From 86d34039a35387e33663f14b30a65cc1165b4fc7 Mon Sep 17 00:00:00 2001 From: morpheus65535 Date: Sat, 11 May 2024 23:22:55 -0400 Subject: [PATCH 01/18] Updated apprise to 1.8.0 --- libs/apprise-1.7.6.dist-info/RECORD | 183 ------------------ libs/apprise-1.7.6.dist-info/REQUESTED | 0 .../INSTALLER | 0 .../LICENSE | 0 .../METADATA | 2 +- libs/apprise-1.8.0.dist-info/RECORD | 183 ++++++++++++++++++ .../REQUESTED | 0 .../WHEEL | 0 .../entry_points.txt | 0 .../top_level.txt | 0 libs/apprise/Apprise.py | 14 +- libs/apprise/__init__.py | 23 +-- ...iseAttachment.py => apprise_attachment.py} | 6 +- ...eAttachment.pyi => apprise_attachment.pyi} | 0 .../{AppriseConfig.py => apprise_config.py} | 4 +- .../{AppriseConfig.pyi => apprise_config.pyi} | 0 libs/apprise/{AppriseAsset.py => asset.py} | 2 +- libs/apprise/{AppriseAsset.pyi => asset.pyi} | 0 libs/apprise/attachment/__init__.py | 5 +- .../attachment/{AttachBase.py => base.py} | 9 +- .../attachment/{AttachBase.pyi => base.pyi} | 0 .../attachment/{AttachFile.py => file.py} | 4 +- .../attachment/{AttachHTTP.py => http.py} | 12 +- libs/apprise/config/__init__.py | 5 +- .../apprise/config/{ConfigBase.py => base.py} | 8 +- .../config/{ConfigBase.pyi => base.pyi} | 0 .../apprise/config/{ConfigFile.py => file.py} | 4 +- .../apprise/config/{ConfigHTTP.py => http.py} | 6 +- .../config/{ConfigMemory.py => memory.py} | 4 +- libs/apprise/conversion.py | 2 +- .../{CustomNotifyPlugin.py => base.py} | 7 +- libs/apprise/decorators/notify.py | 2 +- libs/apprise/i18n/en/LC_MESSAGES/apprise.mo | Bin 3959 -> 3959 bytes libs/apprise/{AppriseLocale.py => locale.py} | 0 libs/apprise/manager.py | 83 ++++---- ...chmentManager.py => manager_attachment.py} | 5 + ...figurationManager.py => manager_config.py} | 5 + ...ificationManager.py => manager_plugins.py} | 6 + libs/apprise/plugins/__init__.py | 8 +- .../{NotifyAppriseAPI.py => apprise_api.py} | 8 +- .../plugins/{NotifyAprs.py => aprs.py} | 6 +- .../plugins/{NotifyBark.py => bark.py} | 6 +- .../plugins/{NotifyBase.py => base.py} | 6 +- .../plugins/{NotifyBase.pyi => base.pyi} | 0 .../plugins/{NotifyBoxcar.py => boxcar.py} | 6 +- .../plugins/{NotifyBulkSMS.py => bulksms.py} | 6 +- .../plugins/{NotifyBulkVS.py => bulkvs.py} | 6 +- .../{NotifyBurstSMS.py => burstsms.py} | 6 +- .../{NotifyChantify.py => chantify.py} | 4 +- .../{NotifyClickSend.py => clicksend.py} | 27 ++- .../plugins/{NotifyForm.py => custom_form.py} | 6 +- .../plugins/{NotifyJSON.py => custom_json.py} | 6 +- .../plugins/{NotifyXML.py => custom_xml.py} | 6 +- .../{NotifyD7Networks.py => d7networks.py} | 4 +- .../plugins/{NotifyDapnet.py => dapnet.py} | 6 +- .../plugins/{NotifyDBus.py => dbus.py} | 4 +- .../{NotifyDingTalk.py => dingtalk.py} | 6 +- .../plugins/{NotifyDiscord.py => discord.py} | 6 +- .../plugins/{NotifyEmail.py => email.py} | 16 +- .../plugins/{NotifyEmby.py => emby.py} | 6 +- .../plugins/{NotifyEnigma2.py => enigma2.py} | 6 +- .../plugins/{NotifyFCM => fcm}/__init__.py | 6 +- .../plugins/{NotifyFCM => fcm}/color.py | 2 +- .../plugins/{NotifyFCM => fcm}/common.py | 0 .../plugins/{NotifyFCM => fcm}/oauth.py | 0 .../plugins/{NotifyFCM => fcm}/priority.py | 0 .../plugins/{NotifyFeishu.py => feishu.py} | 4 +- .../plugins/{NotifyFlock.py => flock.py} | 4 +- .../{NotifyFreeMobile.py => freemobile.py} | 5 +- .../plugins/{NotifyGnome.py => gnome.py} | 4 +- .../{NotifyGoogleChat.py => google_chat.py} | 4 +- .../plugins/{NotifyGotify.py => gotify.py} | 4 +- .../plugins/{NotifyGrowl.py => growl.py} | 6 +- .../plugins/{NotifyGuilded.py => guilded.py} | 5 +- ...tifyHomeAssistant.py => home_assistant.py} | 6 +- .../plugins/{NotifyHttpSMS.py => httpsms.py} | 4 +- .../plugins/{NotifyIFTTT.py => ifttt.py} | 4 +- .../plugins/{NotifyJoin.py => join.py} | 4 +- .../{NotifyKavenegar.py => kavenegar.py} | 4 +- .../plugins/{NotifyKumulos.py => kumulos.py} | 4 +- .../{NotifyLametric.py => lametric.py} | 4 +- .../plugins/{NotifyLine.py => line.py} | 6 +- .../plugins/{NotifyLunaSea.py => lunasea.py} | 6 +- .../plugins/{NotifyMacOSX.py => macosx.py} | 4 +- .../plugins/{NotifyMailgun.py => mailgun.py} | 4 +- .../{NotifyMastodon.py => mastodon.py} | 8 +- .../plugins/{NotifyMatrix.py => matrix.py} | 6 +- .../{NotifyMattermost.py => mattermost.py} | 4 +- .../{NotifyMessageBird.py => messagebird.py} | 4 +- .../plugins/{NotifyMisskey.py => misskey.py} | 4 +- .../plugins/{NotifyMQTT.py => mqtt.py} | 6 +- .../plugins/{NotifyMSG91.py => msg91.py} | 4 +- .../plugins/{NotifyMSTeams.py => msteams.py} | 6 +- .../{NotifyNextcloud.py => nextcloud.py} | 6 +- ...otifyNextcloudTalk.py => nextcloudtalk.py} | 6 +- .../plugins/{NotifyNotica.py => notica.py} | 6 +- .../{NotifyNotifiarr.py => notifiarr.py} | 4 +- .../{NotifyNotifico.py => notifico.py} | 4 +- .../plugins/{NotifyNtfy.py => ntfy.py} | 8 +- .../{NotifyOffice365.py => office365.py} | 6 +- .../{NotifyOneSignal.py => one_signal.py} | 4 +- .../{NotifyOpsgenie.py => opsgenie.py} | 4 +- .../{NotifyPagerDuty.py => pagerduty.py} | 6 +- .../{NotifyPagerTree.py => pagertree.py} | 4 +- ...otifyParsePlatform.py => parseplatform.py} | 4 +- ...tifyPopcornNotify.py => popcorn_notify.py} | 4 +- .../plugins/{NotifyProwl.py => prowl.py} | 4 +- .../{NotifyPushBullet.py => pushbullet.py} | 6 +- .../{NotifyPushDeer.py => pushdeer.py} | 4 +- .../plugins/{NotifyPushed.py => pushed.py} | 6 +- .../plugins/{NotifyPushjet.py => pushjet.py} | 6 +- .../plugins/{NotifyPushMe.py => pushme.py} | 4 +- .../{NotifyPushover.py => pushover.py} | 6 +- .../{NotifyPushSafer.py => pushsafer.py} | 4 +- .../plugins/{NotifyPushy.py => pushy.py} | 4 +- .../plugins/{NotifyReddit.py => reddit.py} | 6 +- .../plugins/{NotifyRevolt.py => revolt.py} | 4 +- .../{NotifyRocketChat.py => rocketchat.py} | 6 +- .../plugins/{NotifyRSyslog.py => rsyslog.py} | 4 +- .../plugins/{NotifyRyver.py => ryver.py} | 4 +- .../{NotifySendGrid.py => sendgrid.py} | 4 +- .../{NotifyServerChan.py => serverchan.py} | 4 +- libs/apprise/plugins/{NotifySES.py => ses.py} | 6 +- .../{NotifySignalAPI.py => signal_api.py} | 6 +- .../{NotifySimplePush.py => simplepush.py} | 6 +- .../plugins/{NotifySinch.py => sinch.py} | 6 +- .../plugins/{NotifySlack.py => slack.py} | 4 +- .../{NotifySMSEagle.py => smseagle.py} | 6 +- .../{NotifySMSManager.py => smsmanager.py} | 4 +- .../plugins/{NotifySMTP2Go.py => smtp2go.py} | 4 +- libs/apprise/plugins/{NotifySNS.py => sns.py} | 6 +- .../{NotifySparkPost.py => sparkpost.py} | 4 +- .../{NotifyStreamlabs.py => streamlabs.py} | 4 +- .../{NotifySynology.py => synology.py} | 6 +- .../plugins/{NotifySyslog.py => syslog.py} | 4 +- ...{NotifyTechulusPush.py => techuluspush.py} | 4 +- .../{NotifyTelegram.py => telegram.py} | 6 +- .../plugins/{NotifyThreema.py => threema.py} | 6 +- .../plugins/{NotifyTwilio.py => twilio.py} | 6 +- .../plugins/{NotifyTwist.py => twist.py} | 6 +- .../plugins/{NotifyTwitter.py => twitter.py} | 8 +- .../plugins/{NotifyVoipms.py => voipms.py} | 4 +- .../plugins/{NotifyVonage.py => vonage.py} | 6 +- .../{NotifyWebexTeams.py => webexteams.py} | 4 +- .../{NotifyWeComBot.py => wecombot.py} | 4 +- .../{NotifyWhatsApp.py => whatsapp.py} | 4 +- .../plugins/{NotifyWindows.py => windows.py} | 4 +- .../plugins/{NotifyXBMC.py => xbmc.py} | 6 +- .../plugins/{NotifyZulip.py => zulip.py} | 4 +- libs/apprise/{URLBase.py => url.py} | 9 +- libs/apprise/{URLBase.pyi => url.pyi} | 0 libs/apprise/utils.py | 13 +- libs/version.txt | 2 +- 153 files changed, 616 insertions(+), 569 deletions(-) delete mode 100644 libs/apprise-1.7.6.dist-info/RECORD delete mode 100644 libs/apprise-1.7.6.dist-info/REQUESTED rename libs/{apprise-1.7.6.dist-info => apprise-1.8.0.dist-info}/INSTALLER (100%) rename libs/{apprise-1.7.6.dist-info => apprise-1.8.0.dist-info}/LICENSE (100%) rename libs/{apprise-1.7.6.dist-info => apprise-1.8.0.dist-info}/METADATA (99%) create mode 100644 libs/apprise-1.8.0.dist-info/RECORD rename libs/{apprise-1.7.4.dist-info => apprise-1.8.0.dist-info}/REQUESTED (100%) rename libs/{apprise-1.7.6.dist-info => apprise-1.8.0.dist-info}/WHEEL (100%) rename libs/{apprise-1.7.6.dist-info => apprise-1.8.0.dist-info}/entry_points.txt (100%) rename libs/{apprise-1.7.6.dist-info => apprise-1.8.0.dist-info}/top_level.txt (100%) rename libs/apprise/{AppriseAttachment.py => apprise_attachment.py} (98%) rename libs/apprise/{AppriseAttachment.pyi => apprise_attachment.pyi} (100%) rename libs/apprise/{AppriseConfig.py => apprise_config.py} (99%) rename libs/apprise/{AppriseConfig.pyi => apprise_config.pyi} (100%) rename libs/apprise/{AppriseAsset.py => asset.py} (99%) rename libs/apprise/{AppriseAsset.pyi => asset.pyi} (100%) rename libs/apprise/attachment/{AttachBase.py => base.py} (98%) rename libs/apprise/attachment/{AttachBase.pyi => base.pyi} (100%) rename libs/apprise/attachment/{AttachFile.py => file.py} (98%) rename libs/apprise/attachment/{AttachHTTP.py => http.py} (98%) rename libs/apprise/config/{ConfigBase.py => base.py} (99%) rename libs/apprise/config/{ConfigBase.pyi => base.pyi} (100%) rename libs/apprise/config/{ConfigFile.py => file.py} (98%) rename libs/apprise/config/{ConfigHTTP.py => http.py} (98%) rename libs/apprise/config/{ConfigMemory.py => memory.py} (97%) rename libs/apprise/decorators/{CustomNotifyPlugin.py => base.py} (98%) rename libs/apprise/{AppriseLocale.py => locale.py} (100%) rename libs/apprise/{AttachmentManager.py => manager_attachment.py} (93%) rename libs/apprise/{ConfigurationManager.py => manager_config.py} (93%) rename libs/apprise/{NotificationManager.py => manager_plugins.py} (92%) rename libs/apprise/plugins/{NotifyAppriseAPI.py => apprise_api.py} (99%) rename libs/apprise/plugins/{NotifyAprs.py => aprs.py} (99%) rename libs/apprise/plugins/{NotifyBark.py => bark.py} (99%) rename libs/apprise/plugins/{NotifyBase.py => base.py} (99%) rename libs/apprise/plugins/{NotifyBase.pyi => base.pyi} (100%) rename libs/apprise/plugins/{NotifyBoxcar.py => boxcar.py} (99%) rename libs/apprise/plugins/{NotifyBulkSMS.py => bulksms.py} (99%) rename libs/apprise/plugins/{NotifyBulkVS.py => bulkvs.py} (99%) rename libs/apprise/plugins/{NotifyBurstSMS.py => burstsms.py} (99%) rename libs/apprise/plugins/{NotifyChantify.py => chantify.py} (98%) rename libs/apprise/plugins/{NotifyClickSend.py => clicksend.py} (94%) rename libs/apprise/plugins/{NotifyForm.py => custom_form.py} (99%) rename libs/apprise/plugins/{NotifyJSON.py => custom_json.py} (99%) rename libs/apprise/plugins/{NotifyXML.py => custom_xml.py} (99%) rename libs/apprise/plugins/{NotifyD7Networks.py => d7networks.py} (99%) rename libs/apprise/plugins/{NotifyDapnet.py => dapnet.py} (99%) rename libs/apprise/plugins/{NotifyDBus.py => dbus.py} (99%) rename libs/apprise/plugins/{NotifyDingTalk.py => dingtalk.py} (99%) rename libs/apprise/plugins/{NotifyDiscord.py => discord.py} (99%) rename libs/apprise/plugins/{NotifyEmail.py => email.py} (98%) rename libs/apprise/plugins/{NotifyEmby.py => emby.py} (99%) rename libs/apprise/plugins/{NotifyEnigma2.py => enigma2.py} (98%) rename libs/apprise/plugins/{NotifyFCM => fcm}/__init__.py (99%) rename libs/apprise/plugins/{NotifyFCM => fcm}/color.py (99%) rename libs/apprise/plugins/{NotifyFCM => fcm}/common.py (100%) rename libs/apprise/plugins/{NotifyFCM => fcm}/oauth.py (100%) rename libs/apprise/plugins/{NotifyFCM => fcm}/priority.py (100%) rename libs/apprise/plugins/{NotifyFeishu.py => feishu.py} (98%) rename libs/apprise/plugins/{NotifyFlock.py => flock.py} (99%) rename libs/apprise/plugins/{NotifyFreeMobile.py => freemobile.py} (98%) rename libs/apprise/plugins/{NotifyGnome.py => gnome.py} (99%) rename libs/apprise/plugins/{NotifyGoogleChat.py => google_chat.py} (99%) rename libs/apprise/plugins/{NotifyGotify.py => gotify.py} (99%) rename libs/apprise/plugins/{NotifyGrowl.py => growl.py} (99%) rename libs/apprise/plugins/{NotifyGuilded.py => guilded.py} (96%) rename libs/apprise/plugins/{NotifyHomeAssistant.py => home_assistant.py} (98%) rename libs/apprise/plugins/{NotifyHttpSMS.py => httpsms.py} (99%) rename libs/apprise/plugins/{NotifyIFTTT.py => ifttt.py} (99%) rename libs/apprise/plugins/{NotifyJoin.py => join.py} (99%) rename libs/apprise/plugins/{NotifyKavenegar.py => kavenegar.py} (99%) rename libs/apprise/plugins/{NotifyKumulos.py => kumulos.py} (99%) rename libs/apprise/plugins/{NotifyLametric.py => lametric.py} (99%) rename libs/apprise/plugins/{NotifyLine.py => line.py} (98%) rename libs/apprise/plugins/{NotifyLunaSea.py => lunasea.py} (99%) rename libs/apprise/plugins/{NotifyMacOSX.py => macosx.py} (99%) rename libs/apprise/plugins/{NotifyMailgun.py => mailgun.py} (99%) rename libs/apprise/plugins/{NotifyMastodon.py => mastodon.py} (99%) rename libs/apprise/plugins/{NotifyMatrix.py => matrix.py} (99%) rename libs/apprise/plugins/{NotifyMattermost.py => mattermost.py} (99%) rename libs/apprise/plugins/{NotifyMessageBird.py => messagebird.py} (99%) rename libs/apprise/plugins/{NotifyMisskey.py => misskey.py} (99%) rename libs/apprise/plugins/{NotifyMQTT.py => mqtt.py} (99%) rename libs/apprise/plugins/{NotifyMSG91.py => msg91.py} (99%) rename libs/apprise/plugins/{NotifyMSTeams.py => msteams.py} (99%) rename libs/apprise/plugins/{NotifyNextcloud.py => nextcloud.py} (99%) rename libs/apprise/plugins/{NotifyNextcloudTalk.py => nextcloudtalk.py} (98%) rename libs/apprise/plugins/{NotifyNotica.py => notica.py} (99%) rename libs/apprise/plugins/{NotifyNotifiarr.py => notifiarr.py} (99%) rename libs/apprise/plugins/{NotifyNotifico.py => notifico.py} (99%) rename libs/apprise/plugins/{NotifyNtfy.py => ntfy.py} (99%) rename libs/apprise/plugins/{NotifyOffice365.py => office365.py} (99%) rename libs/apprise/plugins/{NotifyOneSignal.py => one_signal.py} (99%) rename libs/apprise/plugins/{NotifyOpsgenie.py => opsgenie.py} (99%) rename libs/apprise/plugins/{NotifyPagerDuty.py => pagerduty.py} (99%) rename libs/apprise/plugins/{NotifyPagerTree.py => pagertree.py} (99%) rename libs/apprise/plugins/{NotifyParsePlatform.py => parseplatform.py} (99%) rename libs/apprise/plugins/{NotifyPopcornNotify.py => popcorn_notify.py} (99%) rename libs/apprise/plugins/{NotifyProwl.py => prowl.py} (99%) rename libs/apprise/plugins/{NotifyPushBullet.py => pushbullet.py} (99%) rename libs/apprise/plugins/{NotifyPushDeer.py => pushdeer.py} (98%) rename libs/apprise/plugins/{NotifyPushed.py => pushed.py} (99%) rename libs/apprise/plugins/{NotifyPushjet.py => pushjet.py} (98%) rename libs/apprise/plugins/{NotifyPushMe.py => pushme.py} (98%) rename libs/apprise/plugins/{NotifyPushover.py => pushover.py} (99%) rename libs/apprise/plugins/{NotifyPushSafer.py => pushsafer.py} (99%) rename libs/apprise/plugins/{NotifyPushy.py => pushy.py} (99%) rename libs/apprise/plugins/{NotifyReddit.py => reddit.py} (99%) rename libs/apprise/plugins/{NotifyRevolt.py => revolt.py} (99%) rename libs/apprise/plugins/{NotifyRocketChat.py => rocketchat.py} (99%) rename libs/apprise/plugins/{NotifyRSyslog.py => rsyslog.py} (99%) rename libs/apprise/plugins/{NotifyRyver.py => ryver.py} (99%) rename libs/apprise/plugins/{NotifySendGrid.py => sendgrid.py} (99%) rename libs/apprise/plugins/{NotifyServerChan.py => serverchan.py} (98%) rename libs/apprise/plugins/{NotifySES.py => ses.py} (99%) rename libs/apprise/plugins/{NotifySignalAPI.py => signal_api.py} (99%) rename libs/apprise/plugins/{NotifySimplePush.py => simplepush.py} (98%) rename libs/apprise/plugins/{NotifySinch.py => sinch.py} (99%) rename libs/apprise/plugins/{NotifySlack.py => slack.py} (99%) rename libs/apprise/plugins/{NotifySMSEagle.py => smseagle.py} (99%) rename libs/apprise/plugins/{NotifySMSManager.py => smsmanager.py} (99%) rename libs/apprise/plugins/{NotifySMTP2Go.py => smtp2go.py} (99%) rename libs/apprise/plugins/{NotifySNS.py => sns.py} (99%) rename libs/apprise/plugins/{NotifySparkPost.py => sparkpost.py} (99%) rename libs/apprise/plugins/{NotifyStreamlabs.py => streamlabs.py} (99%) rename libs/apprise/plugins/{NotifySynology.py => synology.py} (98%) rename libs/apprise/plugins/{NotifySyslog.py => syslog.py} (99%) rename libs/apprise/plugins/{NotifyTechulusPush.py => techuluspush.py} (98%) rename libs/apprise/plugins/{NotifyTelegram.py => telegram.py} (99%) rename libs/apprise/plugins/{NotifyThreema.py => threema.py} (99%) rename libs/apprise/plugins/{NotifyTwilio.py => twilio.py} (99%) rename libs/apprise/plugins/{NotifyTwist.py => twist.py} (99%) rename libs/apprise/plugins/{NotifyTwitter.py => twitter.py} (99%) rename libs/apprise/plugins/{NotifyVoipms.py => voipms.py} (99%) rename libs/apprise/plugins/{NotifyVonage.py => vonage.py} (99%) rename libs/apprise/plugins/{NotifyWebexTeams.py => webexteams.py} (99%) rename libs/apprise/plugins/{NotifyWeComBot.py => wecombot.py} (99%) rename libs/apprise/plugins/{NotifyWhatsApp.py => whatsapp.py} (99%) rename libs/apprise/plugins/{NotifyWindows.py => windows.py} (99%) rename libs/apprise/plugins/{NotifyXBMC.py => xbmc.py} (99%) rename libs/apprise/plugins/{NotifyZulip.py => zulip.py} (99%) rename libs/apprise/{URLBase.py => url.py} (99%) rename libs/apprise/{URLBase.pyi => url.pyi} (100%) diff --git a/libs/apprise-1.7.6.dist-info/RECORD b/libs/apprise-1.7.6.dist-info/RECORD deleted file mode 100644 index 250648105..000000000 --- a/libs/apprise-1.7.6.dist-info/RECORD +++ /dev/null @@ -1,183 +0,0 @@ -../../bin/apprise,sha256=ZJ-e4qqxNLtdW_DAvpuPPX5iROIiQd8I6nvg7vtAv-g,233 -apprise-1.7.6.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 -apprise-1.7.6.dist-info/LICENSE,sha256=gt7qKBxRhVcdmXCYVtrWP6DtYjD0DzONet600dkU994,1343 -apprise-1.7.6.dist-info/METADATA,sha256=z_gaX2IdNJqw4T9q7AYQri9jcIs-OTGCo3t2EgEY-mw,44823 -apprise-1.7.6.dist-info/RECORD,, -apprise-1.7.6.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 -apprise-1.7.6.dist-info/WHEEL,sha256=Xo9-1PvkuimrydujYJAjF7pCkriuXBpUPEjma1nZyJ0,92 -apprise-1.7.6.dist-info/entry_points.txt,sha256=71YypBuNdjAKiaLsiMG40HEfLHxkU4Mi7o_S0s0d8wI,45 -apprise-1.7.6.dist-info/top_level.txt,sha256=JrCRn-_rXw5LMKXkIgMSE4E0t1Ks9TYrBH54Pflwjkk,8 -apprise/Apprise.py,sha256=Stm2NhJprWRaMwQfTiIQG_nR1bLpHi_zcdwEcsCpa-A,32865 -apprise/Apprise.pyi,sha256=_4TBKvT-QVj3s6PuTh3YX-BbQMeJTdBGdVpubLMY4_k,2203 -apprise/AppriseAsset.py,sha256=jRW8Y1EcAvjVA9h_mINmsjO4DM3S0aDl6INIFVMcUCs,11647 -apprise/AppriseAsset.pyi,sha256=NYLXXYbScgRkspP27XGpRRM_uliPu1OCdWdZBPPvLng,979 -apprise/AppriseAttachment.py,sha256=vhrktSrp8GLr32aK4KqV6BX83IpI1lxZe-pGo1wiSFM,12540 -apprise/AppriseAttachment.pyi,sha256=R9-0dVqWpeaFrVpcREwPhGy3qHWztG5jEjYIOsbE5dM,1145 -apprise/AppriseConfig.py,sha256=wfuR6Mb3ZLHvjvqWdFp9lVmjjDRWs65unY9qa92RkCg,16909 -apprise/AppriseConfig.pyi,sha256=_mUlCnncqAq8sL01WxQTgZjnb2ic9kZXvtqZmVl-fc8,1568 -apprise/AppriseLocale.py,sha256=4uSr4Nj_rz6ISMMAfRVRk58wZVLKOofJgk2x0_E8NkQ,8994 -apprise/AttachmentManager.py,sha256=EwlnjuKn3fv_pioWcmMCkyDTsO178t6vkEOD8AjAPsw,2053 -apprise/ConfigurationManager.py,sha256=MUmGajxjgnr6FGN7xb3q0nD0VVgdTdvapBBR7CsI-rc,2058 -apprise/NotificationManager.py,sha256=ZJgkiCgcJ7Bz_6bwQ47flrcxvLMbA4Vbw0HG_yTsGdE,2041 -apprise/URLBase.py,sha256=xRP0-blocp9UudYh04Hb3fIEmTZWJaTv_tzjrqaB9fg,29423 -apprise/URLBase.pyi,sha256=WLaRREH7FzZ5x3-qkDkupojWGFC4uFwJ1EDt02lVs8c,520 -apprise/__init__.py,sha256=ArtvoarAMnBcSfXF7L_hzq5CUJ9TUnHopiC7xafCe3c,3368 -apprise/assets/NotifyXML-1.0.xsd,sha256=292qQ_IUl5EWDhPyzm9UTT0C2rVvJkyGar8jiODkJs8,986 -apprise/assets/NotifyXML-1.1.xsd,sha256=bjR3CGG4AEXoJjYkGCbDttKHSkPP1FlIWO02E7G59g4,1758 -apprise/assets/themes/default/apprise-failure-128x128.ico,sha256=Mt0ptfHJaN3Wsv5UCNDn9_3lyEDHxVDv1JdaDEI_xCA,67646 -apprise/assets/themes/default/apprise-failure-128x128.png,sha256=66ps8TDPxVH3g9PlObJqF-0x952CjnqQyN3zvpRcOT8,16135 -apprise/assets/themes/default/apprise-failure-256x256.png,sha256=bQBsKKCsKfR9EqgYOZrcVcVa5y8qG58PN2mEqO5eNRI,41931 -apprise/assets/themes/default/apprise-failure-32x32.png,sha256=vH0pZffIDCvkejpr3fJHGXW__8Yc3R_p0bacX6t6l18,2437 -apprise/assets/themes/default/apprise-failure-72x72.png,sha256=EP5A8DHRDr9srgupFSwOoyQ308bNJ8aL192J_L4K-ec,7600 -apprise/assets/themes/default/apprise-info-128x128.ico,sha256=F5_CirmXueRCRI5Z_Crf6TS6jVIXTJlRD83zw1oJ66g,67646 -apprise/assets/themes/default/apprise-info-128x128.png,sha256=bBqRZAgQey-gkmJrnFhPbzjILSrljE59mRkgj3raMQo,16671 -apprise/assets/themes/default/apprise-info-256x256.png,sha256=B5r_O4d9MHCmSWZwfbqQgZSp-ZetTdiBSwKcMTF1aFA,43331 -apprise/assets/themes/default/apprise-info-32x32.png,sha256=lt3NZ95TzkiCNVNlurrB2fE2nriMa1wftl7nrNXmb6c,2485 -apprise/assets/themes/default/apprise-info-72x72.png,sha256=kDnsZpqNUZGqs9t1ECUup7FOfXUIL-rupnQCYJp9So4,7875 -apprise/assets/themes/default/apprise-logo.png,sha256=85ttALudKkLmiqilJT7mUQLUXRFmM1AK89rnwLm313s,160907 -apprise/assets/themes/default/apprise-success-128x128.ico,sha256=uCopPwdQjxgfohKazHaDzYs9y4oiaOpL048PYC6WRlg,67646 -apprise/assets/themes/default/apprise-success-128x128.png,sha256=nvDuU_QqhGlw6cMtdj7Mv-gPgqCEx-0DaaXn1KBLVYg,17446 -apprise/assets/themes/default/apprise-success-256x256.png,sha256=vXfKuxY3n0eeXHKdb9hTxICxOEn7HjAQ4IZpX0HSLzc,48729 -apprise/assets/themes/default/apprise-success-32x32.png,sha256=Jg9pFJh3YPI-LiPBebyJ7Z4Vt7BRecaE8AsRjQVIkME,2471 -apprise/assets/themes/default/apprise-success-72x72.png,sha256=FQbgvIhqKOhEK0yvrhaSpai0R7hrkTt_-GaC2KUgCCk,7858 -apprise/assets/themes/default/apprise-warning-128x128.ico,sha256=6XaQPOx0oWK_xbhr4Yhb7qNazCWwSs9lk2SYR2MHTrQ,67646 -apprise/assets/themes/default/apprise-warning-128x128.png,sha256=pf5c4Ph7jWH7gf39dJoieSj8TzAsY3TXI-sGISGVIW4,16784 -apprise/assets/themes/default/apprise-warning-256x256.png,sha256=SY-xlaiXaj420iEYKC2_fJxU-yj2SuaQg6xfPNi83bw,43708 -apprise/assets/themes/default/apprise-warning-32x32.png,sha256=97R2ywNvcwczhBoWEIgajVtWjgT8fLs4FCCz4wu0dwc,2472 -apprise/assets/themes/default/apprise-warning-72x72.png,sha256=L8moEInkO_OLxoOcuvN7rmrGZo64iJeH20o-24MQghE,7913 -apprise/attachment/AttachBase.py,sha256=T3WreGrTsqqGplXJO36jm-N14X7ymSc9xt7XdTYuXVE,13656 -apprise/attachment/AttachBase.pyi,sha256=w0XG_QKauiMLJ7eQ4S57IiLIURZHm_Snw7l6-ih9GP8,961 -apprise/attachment/AttachFile.py,sha256=MbHY_av0GeM_AIBKV02Hq7SHiZ9eCr1yTfvDMUgi2I4,4765 -apprise/attachment/AttachHTTP.py,sha256=_CMPp4QGLATfGO2-Nw57sxsQyed9z3ywgoB0vpK3KZk,13779 -apprise/attachment/__init__.py,sha256=xabgXpvV05X-YRuqIt3uGYMXwYNXjHyF6Dwd8HfZCFE,1658 -apprise/cli.py,sha256=h-pWSQPqQficH6J-OEp3MTGydWyt6vMYnDZvHCeAt4Y,20697 -apprise/common.py,sha256=I6wfrndggCL7l7KAl7Cm4uwAX9n0l3SN4-BVvTE0L0M,5593 -apprise/common.pyi,sha256=luF3QRiClDCk8Z23rI6FCGYsVmodOt_JYfYyzGogdNM,447 -apprise/config/ConfigBase.py,sha256=d1efIuQFCJr66WgpudV2DWtxY3-tuZAyMAhHXBzJ8p0,53194 -apprise/config/ConfigBase.pyi,sha256=cngfobwH6v2vxYbQrObDi5Z-t5wcquWF-wR0kBCr3Eg,54 -apprise/config/ConfigFile.py,sha256=u_SDaN3OHMyaAq2X7k_T4_PRKkVsDwleqBz9YIN5lbA,6138 -apprise/config/ConfigHTTP.py,sha256=Iy6Ji8_nX3xDjFgJGLrz4ftrMlMiyKiFGzYGJ7rMSMQ,9457 -apprise/config/ConfigMemory.py,sha256=epEAgNy-eJVWoQaUOvjivMWxXTofy6wAQ-NbCqYmuyE,2829 -apprise/config/__init__.py,sha256=lbsxrUpB1IYM2q7kjYhsXQGgPF-yZXJrKFE361tdIPY,1663 -apprise/conversion.py,sha256=0VZ0eCZfksN-97Vl0TjVjwnCTgus3XTRioceSFnP-gc,6277 -apprise/decorators/CustomNotifyPlugin.py,sha256=i4D-sgOsBWsxO5auWCN2bgXLLPuADaaLlJ1gUKLj2bU,7972 -apprise/decorators/__init__.py,sha256=e_PDAm0kQNzwDPx-NJZLPfLMd2VAABvNZtxx_iDviRM,1487 -apprise/decorators/notify.py,sha256=a2WupErNw1_SMAld7jPC273bskiChMpYy95BOog5A9w,5111 -apprise/emojis.py,sha256=ONF0t8dY9f2XlEkLUG79-ybKVAj2GqbPj2-Be97vAoI,87738 -apprise/i18n/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 -apprise/i18n/en/LC_MESSAGES/apprise.mo,sha256=oUTuHREmLEYN07oqYqRMJ_kU71-o5o37NsF4RXlC5AU,3959 -apprise/logger.py,sha256=131hqhed8cUj9x_mfXDEvwA2YbcYDFAYiWVK1HgxRVY,6921 -apprise/manager.py,sha256=R9w8jxQRNy6Z_XDcobkt4JYbrC4jtj2OwRw9Zrib3CA,26857 -apprise/plugins/NotifyAppriseAPI.py,sha256=ISBE0brD3eQdyw3XrGXd4Uc4kSYvIuI3SSUVCt-bkdo,16654 -apprise/plugins/NotifyAprs.py,sha256=xdL_aIVgb4ggxRFeCdkZAbgHYZ8DWLw9pRpLZQ0rHoE,25523 -apprise/plugins/NotifyBark.py,sha256=bsDvKooRy4k1Gg7tvBjv3DIx7-WZiV_mbTrkTwMtd9Q,15698 -apprise/plugins/NotifyBase.py,sha256=G3xkF_a2BWqNSxsrnOW7NUgHjOqBCYC5zihCifWemo8,30360 -apprise/plugins/NotifyBase.pyi,sha256=aKlZXRYUgG8lz_ZgGkYYJ_GKhuf18youTmMU-FlG7z8,21 -apprise/plugins/NotifyBoxcar.py,sha256=vR00-WggHa1nHYWyb-f5P2V-G4f683fU_-GBlIeJvD0,12867 -apprise/plugins/NotifyBulkSMS.py,sha256=stPWAFCfhBP617zYK9Dgk6pNJBN_WcyJtODzo0jR1QQ,16005 -apprise/plugins/NotifyBulkVS.py,sha256=viLGeyUDiirRRM7CgRqqElHSLYFnMugDtWE6Ytjqfaw,13290 -apprise/plugins/NotifyBurstSMS.py,sha256=cN2kRETKIK5LhwpQEA8C68LKv8KEUPmXYe-nTSegGls,15550 -apprise/plugins/NotifyChantify.py,sha256=GJJOAtSnVoIfKbJF_W1DTu7WsvS_zHdjO4T1XTKT87g,6673 -apprise/plugins/NotifyClickSend.py,sha256=UfOJqsas6WLjQskojuJE7I_-lrb5QrkMiBZv-po_Q9c,11229 -apprise/plugins/NotifyD7Networks.py,sha256=4E6Fh0kQoDlMMwgZJDOXky7c7KrdMMvqprcfm29scWU,15043 -apprise/plugins/NotifyDBus.py,sha256=1eVJHIL3XkFjDePMqfcll35Ie1vxggJ1iBsVFAIaF00,14379 -apprise/plugins/NotifyDapnet.py,sha256=KuXjBU0ZrIYtoDei85NeLZ-IP810T4w5oFXH9sWiSh0,13624 -apprise/plugins/NotifyDingTalk.py,sha256=NJyETgN6QjtRqtxQjfBLFVuFpURyWykRftm6WpQJVbY,12009 -apprise/plugins/NotifyDiscord.py,sha256=M_qmTzB7NNL5_agjYDX38KBN1jRzDBp2EMSNwEF_9Tw,26072 -apprise/plugins/NotifyEmail.py,sha256=Y_ZOrdK6hTUKHLvogKpV5VqD8byzDyDSvwIVmfdsC2g,39789 -apprise/plugins/NotifyEmby.py,sha256=OMVO8XsVl_XCBYNNNQi8ni2lS4voLfU8Puk1xJOAvHs,24039 -apprise/plugins/NotifyEnigma2.py,sha256=Hj0Q9YOeljSwbfiuMKLqXTVX_1g_mjNUGEts7wfrwno,11498 -apprise/plugins/NotifyFCM/__init__.py,sha256=mBFtIgIJuLIFnMB5ndx5Makjs9orVMc2oLoD7LaVT48,21669 -apprise/plugins/NotifyFCM/color.py,sha256=8iqDtadloQh2TMxkFmIFwenHqKp1pHHn1bwyWOzZ6TY,4592 -apprise/plugins/NotifyFCM/common.py,sha256=978uBUoNdtopCtylipGiKQdsQ8FTONxkFBp7uJMZHc8,1718 -apprise/plugins/NotifyFCM/oauth.py,sha256=Vvbd0-rd5BPIjAneG3rILU153JIzfSZ0kaDov6hm96M,11197 -apprise/plugins/NotifyFCM/priority.py,sha256=0WuRW1y1HVnybgjlTeCZPHzt7j8SwWnC7faNcjioAOc,8163 -apprise/plugins/NotifyFeishu.py,sha256=IpcABdLZJ1vcQdZHlmASVbNOiOCIrmgKFhz1hbdskY4,7266 -apprise/plugins/NotifyFlock.py,sha256=0rUIa9nToGsO8BTUgixh8Z_qdVixJeH479UNYjcE4EM,12748 -apprise/plugins/NotifyForm.py,sha256=38nL-2m1cf4gEQFQ4NpvA4j9i5_nNUgelReWFSjyV5U,17905 -apprise/plugins/NotifyFreeMobile.py,sha256=XCkgZLc3KKGlx_9UdeoMJVcHpeQrOml9T93S-DGf4bs,6644 -apprise/plugins/NotifyGnome.py,sha256=8MXTa8gZg1wTgNJfLlmq7_fl3WaYK-SX6VR91u308C4,9059 -apprise/plugins/NotifyGoogleChat.py,sha256=lnoN17m6lZANaXcElDTP8lcuVWjIZEK8C6_iqJNAnw4,12622 -apprise/plugins/NotifyGotify.py,sha256=DNlOIHyuYitO5use9oa_REPm2Fant7y9QSaatrZFNI0,10551 -apprise/plugins/NotifyGrowl.py,sha256=M6ViUz967VhEHtXrE7lbCKF3aB4pIXNEzJLjjGAmvhM,14023 -apprise/plugins/NotifyGuilded.py,sha256=eCMCoFFuE0XNY8HlLM21zoxgBNgqEKQ8dwYj8LihfRU,3641 -apprise/plugins/NotifyHomeAssistant.py,sha256=zqWu7TtdXhTbGNuflC8WfydbHsCLiEBw4uBUcF7YZtw,10739 -apprise/plugins/NotifyHttpSMS.py,sha256=pDEUHCCB18IhOgDcVK3_FFDJdAcrdTIfPzj0jNnZZBo,11136 -apprise/plugins/NotifyIFTTT.py,sha256=oMvTQ0bEu2eJQgw9BwxAwTNOtbZ_ER-zleJvWpWTj7w,13425 -apprise/plugins/NotifyJSON.py,sha256=70ctjmArGzuvM1gHNt1bCiQVWE7Fp9vd2nWhSXwFvw0,13851 -apprise/plugins/NotifyJoin.py,sha256=B8FHp7cblZBkxTgfrka6mNnf6oQVBXVuGISgSau00z0,13581 -apprise/plugins/NotifyKavenegar.py,sha256=F5xTUdebM1lK6yGFbZJQB9Zgw2LTI0angeA-3Nu-89w,12620 -apprise/plugins/NotifyKumulos.py,sha256=eCEW2ZverZqETOLHVWMC4E8Ll6rEhhEWOSD73RD80SM,8214 -apprise/plugins/NotifyLametric.py,sha256=h8vZoX-Ll5NBZRprBlxTO2H9w0lOiMxglGvUgJtK4_8,37534 -apprise/plugins/NotifyLine.py,sha256=OVI0ozMJcq_-dI8dodVX52dzUzgENlAbOik-Kw4l-rI,10676 -apprise/plugins/NotifyLunaSea.py,sha256=woN8XdkwAjhgxAXp7Zj4XsWLybNL80l4W3Dx5BvobZg,14459 -apprise/plugins/NotifyMQTT.py,sha256=cnuG4f3bYYNPhEj9qDX8SLmnxLVT9G1b8J5w6-mQGKY,19545 -apprise/plugins/NotifyMSG91.py,sha256=P7JPyT1xmucnaEeCZPf_6aJfe1gS_STYYwEM7hJ7QBw,12677 -apprise/plugins/NotifyMSTeams.py,sha256=dFH575hoLL3zRddbBKfozlYjxvPJGbj3BKvfJSIkvD0,22976 -apprise/plugins/NotifyMacOSX.py,sha256=y2fGpSZXomFiNwKbWImrXQUMVM4JR4uPCnsWpnxQrFA,8271 -apprise/plugins/NotifyMailgun.py,sha256=FNS_QLOQWMo62yVO-mMZkpiXudUtSdbHOjfSrLC4oIo,25409 -apprise/plugins/NotifyMastodon.py,sha256=2ovjQIOOITHH8lOinC8QCFCJN2QA8foIM2pjdknbblc,35277 -apprise/plugins/NotifyMatrix.py,sha256=I8kdaZUZS-drew0JExBbChQVe7Ib4EwAjQd0xE30XT0,50049 -apprise/plugins/NotifyMattermost.py,sha256=JgEc-wC-43FBMItezDJ62zv1Nc9ROFjDiwD_8bt8rgM,12722 -apprise/plugins/NotifyMessageBird.py,sha256=EUPwhs1PHiPZpluIrLiNKQMUPcdlKnx1sdnllCtN_Ns,12248 -apprise/plugins/NotifyMisskey.py,sha256=zYZkBKv0p3jJpm_HLDBugUgKeGb0qpLoPqy0ffwwxVg,9600 -apprise/plugins/NotifyNextcloud.py,sha256=M3EyvUzBMHbTKU3gxW_7fPA6vmQUF5x8GTMZQ78sWCA,12759 -apprise/plugins/NotifyNextcloudTalk.py,sha256=dLl_g7Knq5PVcadbzDuQsxbGHTZlC4r-pQC8wzYnmAo,11011 -apprise/plugins/NotifyNotica.py,sha256=yHmk8HiNFjzoI4Gewo_nBRrx9liEmhT95k1d10wqhYg,12990 -apprise/plugins/NotifyNotifiarr.py,sha256=ADwLJO9eenfLkNa09tXMGSBTM4c3zTY0SEePvyB8WYA,15857 -apprise/plugins/NotifyNotifico.py,sha256=Qe9jMN_M3GL4XlYIWkAf-w_Hf65g9Hde4bVuytGhUW4,12035 -apprise/plugins/NotifyNtfy.py,sha256=AtJt2zH35mMQTwRDxKia93NPy6-4rtixplP53zIYV2M,27979 -apprise/plugins/NotifyOffice365.py,sha256=8TxsVsdbUghmNj0kceMlmoZzTOKQTgn3priI8JuRuHE,25190 -apprise/plugins/NotifyOneSignal.py,sha256=gsw7ckW7xLiJDRUb7eJHNe_4bvdBXmt6_YsB1u_ghjw,18153 -apprise/plugins/NotifyOpsgenie.py,sha256=zJWpknjoHq35Iv9w88ucR62odaeIN3nrGFPtYnhDdjA,20515 -apprise/plugins/NotifyPagerDuty.py,sha256=lu6oNdygrs6UezYm6xgiQxQDeDz8EVUtfP-xsArRvyw,17874 -apprise/plugins/NotifyPagerTree.py,sha256=mPl6ejdelNlWUWGVs46kZT0VV4uFZoeCdcv4VJ_f_XQ,13849 -apprise/plugins/NotifyParsePlatform.py,sha256=6oFOTpu-HMhesaYXRBvu5oaESYlFrKBNYTHE-ItCBRk,10291 -apprise/plugins/NotifyPopcornNotify.py,sha256=kRstzG0tWBdxSRfn2RN2J7FhvIj2qYWlwUyLxxZCbPc,10587 -apprise/plugins/NotifyProwl.py,sha256=EGOdmiZq8CFbjxTtWWKLQEdYiSvr4czZfE_8aCMEokw,9782 -apprise/plugins/NotifyPushBullet.py,sha256=JVd2GQH-DWmPaKjuGBpsE6DXNCcZEUDH7tA5zbM1qEU,15372 -apprise/plugins/NotifyPushDeer.py,sha256=cG1UFG06PfzbmI1RxtrMqmfaHK_Ojk_W-QMEdtkEuUI,6922 -apprise/plugins/NotifyPushMe.py,sha256=ioRzeXbd2X5miTd3h3m7AwCqkIIfbXNm4PjYk0OOXZ0,7134 -apprise/plugins/NotifyPushSafer.py,sha256=hIcYHwUZapmC-VDvaO_UkDY9RSPTxHgF7m2FL-6JBZw,26756 -apprise/plugins/NotifyPushed.py,sha256=NqLMXD9gvihXLfLUtCcMfz5oUAhPM7sKXECqKgD0v-U,12270 -apprise/plugins/NotifyPushjet.py,sha256=8qWpIqM4dKWjO-BjOrRJXZYtvtJBt_mikdBWRxfibnE,8952 -apprise/plugins/NotifyPushover.py,sha256=MJDquV4zl1cNrGZOC55hLlt6lOb6625WeUcgS5ceCbk,21213 -apprise/plugins/NotifyPushy.py,sha256=mmWcnu905Fvc8ihYXvZ7lVYErGZH5Q-GbBNS20v5r48,12496 -apprise/plugins/NotifyRSyslog.py,sha256=W42LT90X65-pNoU7KdhdX1PBcmsz9RyV376CDa_H3CI,11982 -apprise/plugins/NotifyReddit.py,sha256=E78OSyDQfUalBEcg71sdMsNBOwdj7cVBnELrhrZEAXY,25785 -apprise/plugins/NotifyRevolt.py,sha256=DRA9Xylwl6leVjVFuJcP4L1cG49CIBtnQdxh4BKnAZ4,14500 -apprise/plugins/NotifyRocketChat.py,sha256=Cb_nasX0-G3FoPMYvNk55RJ-tHuXUCTLUn2wTSi4IcI,25738 -apprise/plugins/NotifyRyver.py,sha256=yhHPMLGeJtcHwBKSPPk0OBfp59DgTvXio1R59JhrJu4,11823 -apprise/plugins/NotifySES.py,sha256=wtRmpAZkS5mQma6sdiaPT6U1xcgoj77CB9mNFvSEAw8,33545 -apprise/plugins/NotifySMSEagle.py,sha256=voFNqOewD9OC1eRctD0YdUB_ZSWsb06rjUwBfCcxPYA,24161 -apprise/plugins/NotifySMSManager.py,sha256=DbVc35qLfYkNL7eq43_rPD6k-PELL9apf3S09S6qvDA,14125 -apprise/plugins/NotifySMTP2Go.py,sha256=foQ7aMMmNc5Oree8YwrxZJgMnF6yVMFAfqShm_nLbx0,19711 -apprise/plugins/NotifySNS.py,sha256=ZEBWf0ZJ9w_ftzUikKEvQWJ2fkxrUbrLhPmTRD2DvRQ,24159 -apprise/plugins/NotifySendGrid.py,sha256=IBdYmZcthkvGCz1N_Fs8vDnImtHug6LpuKv1mWT_Cdo,16213 -apprise/plugins/NotifyServerChan.py,sha256=WsrClO9f0xi-KpnLZGTUHV7PxeU3l1D875gvMaZRG_M,5779 -apprise/plugins/NotifySignalAPI.py,sha256=OwJ7qjJ-ZJyS8GS-dBWAtgizHMnGegg76GuwFobyWkw,16733 -apprise/plugins/NotifySimplePush.py,sha256=dUC6O8IGuUIAz5z6_H7A7jdv5Gj1plytNm5QyKnHAYg,10876 -apprise/plugins/NotifySinch.py,sha256=tmHLwQa9lWHEI3EcRfigl4i7JU46A6gKAi_GbY0PrX4,16813 -apprise/plugins/NotifySlack.py,sha256=3VdjruU5FPr3jT_s3axwRJKMcBYXP0lvJnyuKedIlcE,42521 -apprise/plugins/NotifySparkPost.py,sha256=6dRTwnYU50Lvmp6AlwCyePe0TMbVEXaSwNeGkg__EYo,27878 -apprise/plugins/NotifyStreamlabs.py,sha256=lx3N8T2ufUWFYIZ-kU_rOv50YyGWBqLSCKk7xim2_Io,16023 -apprise/plugins/NotifySynology.py,sha256=_jTqfgWeOuSi_I8geMOraHBVFtDkvm9mempzymrmeAo,11105 -apprise/plugins/NotifySyslog.py,sha256=J9Kain2bb-PDNiG5Ydb0q678cYjNE_NjZFqMG9oEXM0,10617 -apprise/plugins/NotifyTechulusPush.py,sha256=m43_Qj1scPcgCRX5Dr2Ul7nxMbaiVxNzm_HRuNmfgoA,7253 -apprise/plugins/NotifyTelegram.py,sha256=XE7PC9LRzcrfE2bpLKyor5lO_7B9LS4Xw1UlUmA4a2A,37187 -apprise/plugins/NotifyThreema.py,sha256=C_C3j0fJWgeF2uB7ceJFXOdC6Lt0TFBInFMs5Xlg04M,11885 -apprise/plugins/NotifyTwilio.py,sha256=WCo8eTI9OF1rtg3ueHHRDXt4Lp45eZ6h3IdTZVf5HM8,15976 -apprise/plugins/NotifyTwist.py,sha256=nZA73CYVe-p0tkVMy5q3vFRyflLM4yjUo9LECvkUwgc,28841 -apprise/plugins/NotifyTwitter.py,sha256=qML0jlBkLZMHrkKRxBpVUnBwAz8MWGYyI3cvwi-hrgM,30152 -apprise/plugins/NotifyVoipms.py,sha256=msy_D32YhP8OP4_Mj_L3OYd4iablqQETN-DvilGZeVQ,12552 -apprise/plugins/NotifyVonage.py,sha256=xmzZgobFaGA_whpQ5fDuG2poUrK9W4T77yP7dusHcSo,13431 -apprise/plugins/NotifyWeComBot.py,sha256=5lkhXDgyJ1edzknemKsO1sJVv7miR9F_7xI40Ag7ICI,8789 -apprise/plugins/NotifyWebexTeams.py,sha256=gbbRlHiPuOvUIZexE5m2QNd1dN_5_x0OdT5m6NSrcso,9164 -apprise/plugins/NotifyWhatsApp.py,sha256=PtzW0ue3d2wZ8Pva_LG29jUcpRRP03TFxO5SME_8Juo,19924 -apprise/plugins/NotifyWindows.py,sha256=QgWJfJF8AE6RWr-L81YYVZNWrnImK9Qr3B991HWanqU,8563 -apprise/plugins/NotifyXBMC.py,sha256=5hDuOTP3Kwtp4NEMaokNjWyEKEkQcN_fSx-cUPJvhaU,12096 -apprise/plugins/NotifyXML.py,sha256=WJnmdvXseuTRgioVMRqpR8a09cDfTpPTfuFlTnT_TfI,16973 -apprise/plugins/NotifyZulip.py,sha256=M8cSL7nZvtBYyTX6045g34tyn2vyybltgD1CoI4Xa7A,13968 -apprise/plugins/__init__.py,sha256=jTfLmW47kZC_Wf5eFFta2NoD2J-7_E7JaPrrVMIECkU,18725 -apprise/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 -apprise/utils.py,sha256=SjRU2tb1UsVnTCTXPUyXVz3WpRbDWwAHH-d3ll38EHY,53185 diff --git a/libs/apprise-1.7.6.dist-info/REQUESTED b/libs/apprise-1.7.6.dist-info/REQUESTED deleted file mode 100644 index e69de29bb..000000000 diff --git a/libs/apprise-1.7.6.dist-info/INSTALLER b/libs/apprise-1.8.0.dist-info/INSTALLER similarity index 100% rename from libs/apprise-1.7.6.dist-info/INSTALLER rename to libs/apprise-1.8.0.dist-info/INSTALLER diff --git a/libs/apprise-1.7.6.dist-info/LICENSE b/libs/apprise-1.8.0.dist-info/LICENSE similarity index 100% rename from libs/apprise-1.7.6.dist-info/LICENSE rename to libs/apprise-1.8.0.dist-info/LICENSE diff --git a/libs/apprise-1.7.6.dist-info/METADATA b/libs/apprise-1.8.0.dist-info/METADATA similarity index 99% rename from libs/apprise-1.7.6.dist-info/METADATA rename to libs/apprise-1.8.0.dist-info/METADATA index ac7cb9aac..c01ef211a 100644 --- a/libs/apprise-1.7.6.dist-info/METADATA +++ b/libs/apprise-1.8.0.dist-info/METADATA @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: apprise -Version: 1.7.6 +Version: 1.8.0 Summary: Push Notifications that work with just about every platform! Home-page: https://github.com/caronc/apprise Author: Chris Caron diff --git a/libs/apprise-1.8.0.dist-info/RECORD b/libs/apprise-1.8.0.dist-info/RECORD new file mode 100644 index 000000000..bcfa733bc --- /dev/null +++ b/libs/apprise-1.8.0.dist-info/RECORD @@ -0,0 +1,183 @@ +../../bin/apprise,sha256=ZJ-e4qqxNLtdW_DAvpuPPX5iROIiQd8I6nvg7vtAv-g,233 +apprise-1.8.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +apprise-1.8.0.dist-info/LICENSE,sha256=gt7qKBxRhVcdmXCYVtrWP6DtYjD0DzONet600dkU994,1343 +apprise-1.8.0.dist-info/METADATA,sha256=if2D6aZrIVQZAe9BKWyqKoKH89ZGnYOTvXGRfqcSf_g,44823 +apprise-1.8.0.dist-info/RECORD,, +apprise-1.8.0.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +apprise-1.8.0.dist-info/WHEEL,sha256=Xo9-1PvkuimrydujYJAjF7pCkriuXBpUPEjma1nZyJ0,92 +apprise-1.8.0.dist-info/entry_points.txt,sha256=71YypBuNdjAKiaLsiMG40HEfLHxkU4Mi7o_S0s0d8wI,45 +apprise-1.8.0.dist-info/top_level.txt,sha256=JrCRn-_rXw5LMKXkIgMSE4E0t1Ks9TYrBH54Pflwjkk,8 +apprise/__init__.py,sha256=nBy2lkwvLxW1QTMEagOZZnM5AQWLM6CRUYt-Gr03X94,3388 +apprise/apprise.py,sha256=JWSqg5pYJOydubQyaIjR9gIPhb2okcrGe2mQ_NhPNS0,32837 +apprise/apprise.pyi,sha256=_4TBKvT-QVj3s6PuTh3YX-BbQMeJTdBGdVpubLMY4_k,2203 +apprise/apprise_attachment.py,sha256=eYVnNWTWQzlzKPDOgMCzGvVtXXDL6noMwtRKwwvyL8Q,12528 +apprise/apprise_attachment.pyi,sha256=R9-0dVqWpeaFrVpcREwPhGy3qHWztG5jEjYIOsbE5dM,1145 +apprise/apprise_config.py,sha256=qlNtd-OkldrY9rE9vT67fVPHINx9fkkbwQinhbBjQ_I,16896 +apprise/apprise_config.pyi,sha256=_mUlCnncqAq8sL01WxQTgZjnb2ic9kZXvtqZmVl-fc8,1568 +apprise/asset.py,sha256=ICXIjCi12Xq8E-WIR4mrVC7KcpPRiJDlKG8cHqoCll0,11643 +apprise/asset.pyi,sha256=NYLXXYbScgRkspP27XGpRRM_uliPu1OCdWdZBPPvLng,979 +apprise/assets/NotifyXML-1.0.xsd,sha256=292qQ_IUl5EWDhPyzm9UTT0C2rVvJkyGar8jiODkJs8,986 +apprise/assets/NotifyXML-1.1.xsd,sha256=bjR3CGG4AEXoJjYkGCbDttKHSkPP1FlIWO02E7G59g4,1758 +apprise/assets/themes/default/apprise-failure-128x128.ico,sha256=Mt0ptfHJaN3Wsv5UCNDn9_3lyEDHxVDv1JdaDEI_xCA,67646 +apprise/assets/themes/default/apprise-failure-128x128.png,sha256=66ps8TDPxVH3g9PlObJqF-0x952CjnqQyN3zvpRcOT8,16135 +apprise/assets/themes/default/apprise-failure-256x256.png,sha256=bQBsKKCsKfR9EqgYOZrcVcVa5y8qG58PN2mEqO5eNRI,41931 +apprise/assets/themes/default/apprise-failure-32x32.png,sha256=vH0pZffIDCvkejpr3fJHGXW__8Yc3R_p0bacX6t6l18,2437 +apprise/assets/themes/default/apprise-failure-72x72.png,sha256=EP5A8DHRDr9srgupFSwOoyQ308bNJ8aL192J_L4K-ec,7600 +apprise/assets/themes/default/apprise-info-128x128.ico,sha256=F5_CirmXueRCRI5Z_Crf6TS6jVIXTJlRD83zw1oJ66g,67646 +apprise/assets/themes/default/apprise-info-128x128.png,sha256=bBqRZAgQey-gkmJrnFhPbzjILSrljE59mRkgj3raMQo,16671 +apprise/assets/themes/default/apprise-info-256x256.png,sha256=B5r_O4d9MHCmSWZwfbqQgZSp-ZetTdiBSwKcMTF1aFA,43331 +apprise/assets/themes/default/apprise-info-32x32.png,sha256=lt3NZ95TzkiCNVNlurrB2fE2nriMa1wftl7nrNXmb6c,2485 +apprise/assets/themes/default/apprise-info-72x72.png,sha256=kDnsZpqNUZGqs9t1ECUup7FOfXUIL-rupnQCYJp9So4,7875 +apprise/assets/themes/default/apprise-logo.png,sha256=85ttALudKkLmiqilJT7mUQLUXRFmM1AK89rnwLm313s,160907 +apprise/assets/themes/default/apprise-success-128x128.ico,sha256=uCopPwdQjxgfohKazHaDzYs9y4oiaOpL048PYC6WRlg,67646 +apprise/assets/themes/default/apprise-success-128x128.png,sha256=nvDuU_QqhGlw6cMtdj7Mv-gPgqCEx-0DaaXn1KBLVYg,17446 +apprise/assets/themes/default/apprise-success-256x256.png,sha256=vXfKuxY3n0eeXHKdb9hTxICxOEn7HjAQ4IZpX0HSLzc,48729 +apprise/assets/themes/default/apprise-success-32x32.png,sha256=Jg9pFJh3YPI-LiPBebyJ7Z4Vt7BRecaE8AsRjQVIkME,2471 +apprise/assets/themes/default/apprise-success-72x72.png,sha256=FQbgvIhqKOhEK0yvrhaSpai0R7hrkTt_-GaC2KUgCCk,7858 +apprise/assets/themes/default/apprise-warning-128x128.ico,sha256=6XaQPOx0oWK_xbhr4Yhb7qNazCWwSs9lk2SYR2MHTrQ,67646 +apprise/assets/themes/default/apprise-warning-128x128.png,sha256=pf5c4Ph7jWH7gf39dJoieSj8TzAsY3TXI-sGISGVIW4,16784 +apprise/assets/themes/default/apprise-warning-256x256.png,sha256=SY-xlaiXaj420iEYKC2_fJxU-yj2SuaQg6xfPNi83bw,43708 +apprise/assets/themes/default/apprise-warning-32x32.png,sha256=97R2ywNvcwczhBoWEIgajVtWjgT8fLs4FCCz4wu0dwc,2472 +apprise/assets/themes/default/apprise-warning-72x72.png,sha256=L8moEInkO_OLxoOcuvN7rmrGZo64iJeH20o-24MQghE,7913 +apprise/attachment/__init__.py,sha256=9jSiGEbLllS-0Vbpgxo4MCpZfIJ-saezWWgQ1PofZ9I,1678 +apprise/attachment/base.py,sha256=phcM6C281j2eoEhtoH5FY0m5s_JvWiEm1AK9z9gyi0w,13692 +apprise/attachment/base.pyi,sha256=w0XG_QKauiMLJ7eQ4S57IiLIURZHm_Snw7l6-ih9GP8,961 +apprise/attachment/file.py,sha256=d9gpsunNIot-6h6w-WQmwWgFiCv7YLqk42zJr4LLqE4,4752 +apprise/attachment/http.py,sha256=C0L9zKmHi60wyzEZN-OJCF7LVoY-MMHYMqhXspFlLdU,13748 +apprise/cli.py,sha256=h-pWSQPqQficH6J-OEp3MTGydWyt6vMYnDZvHCeAt4Y,20697 +apprise/common.py,sha256=I6wfrndggCL7l7KAl7Cm4uwAX9n0l3SN4-BVvTE0L0M,5593 +apprise/common.pyi,sha256=luF3QRiClDCk8Z23rI6FCGYsVmodOt_JYfYyzGogdNM,447 +apprise/config/__init__.py,sha256=oDxdoqG2NEYu_bbpLsLaM3L9WKY3gNn5gjIwb2h3LU4,1679 +apprise/config/base.py,sha256=iWgrBk4-wm_SHtNbe7dCQOYnbkI3oKWP_b60qwjGSoU,53173 +apprise/config/base.pyi,sha256=cngfobwH6v2vxYbQrObDi5Z-t5wcquWF-wR0kBCr3Eg,54 +apprise/config/file.py,sha256=MB_H2X5lJZS-XAOahkMb3IsD2rgVebFjiEF76goITEg,6125 +apprise/config/http.py,sha256=CjQtv_OQJykMxD4ssiwbFI3P8CeQiPdYV_ZIiL_XqMw,9440 +apprise/config/memory.py,sha256=8VICU-WLux8KnW6i9sf9fgmns90J-MfVYI3pvTiyTno,2816 +apprise/conversion.py,sha256=fSn-pTE6-vNt9qVQCKib_NTMhZnCH88FoMt14x6co1M,6273 +apprise/decorators/__init__.py,sha256=e_PDAm0kQNzwDPx-NJZLPfLMd2VAABvNZtxx_iDviRM,1487 +apprise/decorators/base.py,sha256=KnRzhrTOxQxwm4KuJxfCfaYfX0MrFbqWTvXY1XuiNck,8019 +apprise/decorators/notify.py,sha256=FzIa7m-G5KnVVa__rjyn990zt2lqE8sdHW-XY79lbAU,5097 +apprise/emojis.py,sha256=ONF0t8dY9f2XlEkLUG79-ybKVAj2GqbPj2-Be97vAoI,87738 +apprise/i18n/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +apprise/i18n/en/LC_MESSAGES/apprise.mo,sha256=w-KW6RXYYMr14raaIvJzbop8tXU4qrsz50zm8rcCo3U,3959 +apprise/locale.py,sha256=4uSr4Nj_rz6ISMMAfRVRk58wZVLKOofJgk2x0_E8NkQ,8994 +apprise/logger.py,sha256=131hqhed8cUj9x_mfXDEvwA2YbcYDFAYiWVK1HgxRVY,6921 +apprise/manager.py,sha256=_LiMG1Upk6h6GcxOw3GjsPtVT8ZJLhLlQkC_xL_dm6A,27218 +apprise/manager_attachment.py,sha256=EkrcKtKjbxTXXyDaKyiu4XSfDu9wKFSdJD7TOTpyOUc,2200 +apprise/manager_config.py,sha256=sCIOlBTH13bQ1cuhQVpUq2vyKWBArA8YRyPnXIB1iWQ,2205 +apprise/manager_plugins.py,sha256=Xbg5-xr-06zMIDoWviz-zKcbzusHj0iBBMchKPpUOkg,2211 +apprise/plugins/__init__.py,sha256=Hm-vt-Xtxir5mgOdehqlGLhIlc45LA31zjqV42uRnB8,18701 +apprise/plugins/apprise_api.py,sha256=D93eUOlEQ1xPZYdagnEtIxkSuzZ4b9XreuhntQW97F8,16638 +apprise/plugins/aprs.py,sha256=fyzhdsESVwsqHMbfjnlRuGuAqAz2Pk_-MrmiMihs8qY,25506 +apprise/plugins/bark.py,sha256=oSz7Nr7vxnXxqA5dRaO6ze2IljkgEQavUPs-MUUDSX4,15681 +apprise/plugins/base.py,sha256=720L5OyMMLqlM3UdYSNMpA3m0rCudzGP3HwKgu73Ons,30350 +apprise/plugins/base.pyi,sha256=aKlZXRYUgG8lz_ZgGkYYJ_GKhuf18youTmMU-FlG7z8,21 +apprise/plugins/boxcar.py,sha256=8ImhsSsOK9o3eiYp4dZ6fO6p6AeI-jOPWoFJ8qvRAxY,12850 +apprise/plugins/bulksms.py,sha256=XuP8X4dL1wWQU7TkLYWPWRAro7TymnF7PlF2ESe7o0o,15988 +apprise/plugins/bulkvs.py,sha256=sLpiKbHs63Yu0UjMc9erW1VSgLceuu5wvPie5iyl03k,13273 +apprise/plugins/burstsms.py,sha256=7YmuhElVvT-0FIxMFBILHjo6Fir0J4qHTuqj8KfWBaI,15533 +apprise/plugins/chantify.py,sha256=hOvrmhH051Us28_kv0mKkuaJ2BN_8pSsslF8eMCgp-Q,6660 +apprise/plugins/clicksend.py,sha256=kKUJgk9FcTcfXqcIV57uMz0VxBtSQqkpxocRkgn0-3Q,11408 +apprise/plugins/custom_form.py,sha256=fMYwSQyEa_u8IEw5QSylDn-y32FnmymkL5ng-tGxDoc,17888 +apprise/plugins/custom_json.py,sha256=UCXaegE1nD8UrKlFrSKQbxfbcrX1BHUvZwBZY6a_aJc,13834 +apprise/plugins/custom_xml.py,sha256=lrPCRngPz8_oV2A8ZfiIY56BRQc1iv0PN0--2LOlxpA,16956 +apprise/plugins/d7networks.py,sha256=2o_wDgoak_S0sUJJa7HPtu0PPKLVmIOrq1rV9llOnHY,15030 +apprise/plugins/dapnet.py,sha256=fclGE69ggMejgpyvBpJqTwFNF3g2w7qpFySOMcc9vi0,13607 +apprise/plugins/dbus.py,sha256=lvHLmOkJYJAr4TjrigdIgP5bBlQXHrNCDR0k80LNsks,14366 +apprise/plugins/dingtalk.py,sha256=1twAGYUZzjhQepg2zhaR7u8QJuWvM5WymkbPQSUKBck,11992 +apprise/plugins/discord.py,sha256=kdR09bKU80-AosBIrTkMSxoOkAUHMXKwSr1P3H-M_f4,26053 +apprise/plugins/email.py,sha256=pVVWhEpT9Zi7qyUvpI2UxbjxkXYe6FoJj8E0NTw4P98,39912 +apprise/plugins/emby.py,sha256=HWYxlgHE99yAPKii4IE1XQQ-B1HViklWOkefjmq6SW4,24022 +apprise/plugins/enigma2.py,sha256=40Uo0m1JtLUcwRnfqKqdX_8ZR1-SvPfJ5470uijgdfw,11481 +apprise/plugins/fcm/__init__.py,sha256=eTjX-ahPHrPddX0v_Ix77qEr2G4NQ7reClCMzX3Nxwk,21657 +apprise/plugins/fcm/color.py,sha256=rQxVRL_CcRlgnNTQXkjB1Bfs0Xc933zOB1tURSdhi7Y,4585 +apprise/plugins/fcm/common.py,sha256=978uBUoNdtopCtylipGiKQdsQ8FTONxkFBp7uJMZHc8,1718 +apprise/plugins/fcm/oauth.py,sha256=Vvbd0-rd5BPIjAneG3rILU153JIzfSZ0kaDov6hm96M,11197 +apprise/plugins/fcm/priority.py,sha256=0WuRW1y1HVnybgjlTeCZPHzt7j8SwWnC7faNcjioAOc,8163 +apprise/plugins/feishu.py,sha256=buGBg1YlcwHjwUGzUfju4cdYbmEOFl3EHU_NzEBqtlM,7253 +apprise/plugins/flock.py,sha256=_bhH-ub0LbuU7k2p1ZwUPZ-TbC3kpD48GKNtLebUpoM,12735 +apprise/plugins/freemobile.py,sha256=NZf553UWkl1FVEVyWQKJN3ZD6opYSv3I-L6DRaKbiCw,6679 +apprise/plugins/gnome.py,sha256=UYtaiMKxILhTdsxe4aeLaJwjV6Af-8VhjVR3W3CyPPk,9046 +apprise/plugins/google_chat.py,sha256=f7F4gPxwwkmhDBlXMHzYoHRhPX3w8tyD7OimGBjmNxg,12609 +apprise/plugins/gotify.py,sha256=ISzmuQ4-Wd46OlaxGSAZBbWDTq9mHBUYO0R-7tAX_zc,10538 +apprise/plugins/growl.py,sha256=mlpN1QXGlEf2BA3BORnvkyT0oiTsWBev2y5gzpOm9r0,14006 +apprise/plugins/guilded.py,sha256=lhE6gK7laQNYEubD9lBGRemFK-IHis_u2tNekbUoGgM,3707 +apprise/plugins/home_assistant.py,sha256=Wstut0QaQL2dE66kH8MOqMANayhvGOq7CuxVz9O-T60,10722 +apprise/plugins/httpsms.py,sha256=2TtIlAFa4cjXwpMyrjfieCFHgaZl4H_YT6IoPIMDOcg,11123 +apprise/plugins/ifttt.py,sha256=ZHtu7pW9I0aHVEC4DshKi6XZCwqQ0A_XGLyFJujwdKY,13412 +apprise/plugins/join.py,sha256=mRop7thH24kQmvIEvtnh0HT0VyBrUXm2sS-P69c0iFE,13568 +apprise/plugins/kavenegar.py,sha256=1vdms7QBaLcTiLXeQGfprMU5rw9wgImRLtALIb78-ro,12607 +apprise/plugins/kumulos.py,sha256=6M_way1Qi5bELm8Csay86AVtVhzmRyv5hfxGrFvyzN4,8201 +apprise/plugins/lametric.py,sha256=JR0XjdxkEphT4VKvKfElNxpAoOpXZCb-40b2SJQP9XA,37521 +apprise/plugins/line.py,sha256=-xONdu4LFkS3sGgZeEGiPGbBIvBEd20lCbyxKLhQwAg,10659 +apprise/plugins/lunasea.py,sha256=WxJ-RIbFDiS1-5HjCs8XVdNv7nt2EHimsXGCDaK0sC0,14442 +apprise/plugins/macosx.py,sha256=4vIXz1xlsq_xlEyeu_rEvzJQZYcWq7pVmSn5VjF_dCY,8258 +apprise/plugins/mailgun.py,sha256=ad3jzdrbdgwWmOAAu4e_inLEAo-cii4z0OnIJQXoSIA,25396 +apprise/plugins/mastodon.py,sha256=X8CBxnuWORLo9JEOLCJcSafFNVrcEd778R38doyNWUo,35254 +apprise/plugins/matrix.py,sha256=zJPTLFqRT6mofXFVi421_poF0Qm7KaWSgNXTBKq3YoI,50032 +apprise/plugins/mattermost.py,sha256=KfHfqt3LO4XuMsY-qNV-i_OAAamF-35RgjHzxuq2deM,12709 +apprise/plugins/messagebird.py,sha256=3TJ_31Vc1liwQKKKwEiO_rP5e4jP4QkcU_wHyRGtf5Q,12235 +apprise/plugins/misskey.py,sha256=E5UrDrVryb7zV2D_qJCPsCyvpynF4-22JqRVco6PcgM,9587 +apprise/plugins/mqtt.py,sha256=3LcRhT44o2QoSH5rJs23xRbi2vob-po5FAPnnEU_cgs,19528 +apprise/plugins/msg91.py,sha256=V3PwdCS5r-LbVHNNTFZGUHt7GPwQOHnQC0mx8G90wGQ,12664 +apprise/plugins/msteams.py,sha256=4maXBIQFEVfH-IVzZW6t4jirsozmKwF4ySPP5h20cTQ,22964 +apprise/plugins/nextcloud.py,sha256=iYmKGH-xZ4Kj3HvXA_krQody7LRqJKzMRu39Ivk1ve4,12742 +apprise/plugins/nextcloudtalk.py,sha256=TTK8qhy0VPjG0N1yFUBJWTieV-1DqT9Jux9D5PRiYAE,10994 +apprise/plugins/notica.py,sha256=MzryA8x-dSt-oRk9g3dlTTrb1ul7mnbRNajbiwTx1Mc,12973 +apprise/plugins/notifiarr.py,sha256=ZI2mjXwKLWx7SXb6d3S-sk2JmCswJ23UTPj9jVNSN0U,15844 +apprise/plugins/notifico.py,sha256=IKkiXU8HdbRnEWzkQKPFo1g-ZnT8AIwFYer7jF2Yjac,12022 +apprise/plugins/ntfy.py,sha256=jOmPZETJByyNmYSzr-2F3k5jAXFVNldcd3wK-tQRpyE,27956 +apprise/plugins/office365.py,sha256=bCg53GDruS7A3_PQNCjiSERhfub_FHTOVCsRwjgbjXU,25173 +apprise/plugins/one_signal.py,sha256=0ljKuz6Wyn5K8Rxp3BT8aARzHWYff0q2TWA5f-ZLJSA,18140 +apprise/plugins/opsgenie.py,sha256=wWUREzEn8FDQmmVGhmTlN7kxsYlzNj1tK3wA5t8UbCA,20502 +apprise/plugins/pagerduty.py,sha256=1vQ2rfbDUKnM0XdkVMrvTnWIPK7lTxrm-Nslt3LW5Ng,17857 +apprise/plugins/pagertree.py,sha256=uhZL2SxIJr0cguMGhJP_RIJxJZLd86uoAcMhHsBOKm8,13836 +apprise/plugins/parseplatform.py,sha256=G99l6AnHZtaw11y7oBBVVvgdg7lSM8gWFm4tAWhJ8d4,10278 +apprise/plugins/popcorn_notify.py,sha256=ppOqxPrZrOPa-TFicO3Lo_jgwOOPCNEXMgmEo10DAZA,10574 +apprise/plugins/prowl.py,sha256=fYsv6s8xA6OC0yFajgLf3jgL6IwiaOTZaJKisW4eNyw,9769 +apprise/plugins/pushbullet.py,sha256=g-7_Y0N4x-a8YE2gqDqW5OIi74YY7rja_jQ8WVKc4FI,15353 +apprise/plugins/pushdeer.py,sha256=8StOcyK1jlx3pc_CnmFUSqdjfvuv0qa6bf--FHP2_KE,6909 +apprise/plugins/pushed.py,sha256=pm3T7JGExjYeqVWQVN8J8JHkn1XBMfix_sdmr1ItXY8,12253 +apprise/plugins/pushjet.py,sha256=Xk0hzx6l5bNHtGgL0M_znRY5JRPUJf4_PhleCyFbe0I,8935 +apprise/plugins/pushme.py,sha256=EswSmup0uL3QmANeJPDhDYyyeBwSrTnqdjMlfvWFnFA,7121 +apprise/plugins/pushover.py,sha256=I6u9C1SVAEVnsLUySFq5UyHi4cQQtew5za4r86aTK10,21194 +apprise/plugins/pushsafer.py,sha256=aGQ1ibggAWGpcBwpD4oQQYMUcKVcV_xsTlc5_wdjssY,26743 +apprise/plugins/pushy.py,sha256=Ai1tKhcus5IuwvhQgtaj--RMPahgtpleWrBbr_ZQJfM,12483 +apprise/plugins/reddit.py,sha256=z54HpGeJxkyS_LH38nqPa6rqW8mrJqSEGTNOh4Cf-78,25768 +apprise/plugins/revolt.py,sha256=kVrJvTb7mBFXFZd9GIVrX2jVIvaUc5D5via48nOXNSA,14487 +apprise/plugins/rocketchat.py,sha256=oSaFzQ7XjOzjhPIPhdS7r_LGa1IJXV6VK_3xNH9Gq9M,25721 +apprise/plugins/rsyslog.py,sha256=9NTg4sYNbbAzw_MnN51YKxVQpb2o6WZUMyKpRtgoupM,11969 +apprise/plugins/ryver.py,sha256=OM_AG-oiRnNYIua-70Wp8lUpZzIkZ7erIiDE6Fd4Q6s,11810 +apprise/plugins/sendgrid.py,sha256=PGSdbkhERhFSZZN2j7km6mdojdlo7sFxs28lmOeDpgQ,16200 +apprise/plugins/serverchan.py,sha256=fcnuindQTPaKZ5gbS-nAxvL31YqkEF-vi4w8g_h7dKc,5766 +apprise/plugins/ses.py,sha256=CF17VZOEZybwdgqqu00qSoombTP5z0M8P_XxPmyc2f4,33528 +apprise/plugins/signal_api.py,sha256=PeCB_1YJc4lZwDdArTgzHP-Vhe9iwCNIYe4WVW_HgUo,16716 +apprise/plugins/simplepush.py,sha256=bL0WiRUCp39ST9X_0FNAFJJ1BFtd1t5OD_JTRneUGFY,10859 +apprise/plugins/sinch.py,sha256=0-z_cNIWMJu4kdTca-6B3raAIRV-PG1E7fUtbxUDECo,16796 +apprise/plugins/slack.py,sha256=tLbJsr97Ddp8bq1ozSEp1ssLsh913uC0Y24Xm3TN4Bo,42508 +apprise/plugins/smseagle.py,sha256=WbULwfwnUEkPw_z-2cVp2TzrupS7fkPfcQgq779nG8k,24144 +apprise/plugins/smsmanager.py,sha256=aSSZcvpWjKEdDg-XPyD-9fTkaQ0FodvuuO7Hqg7N6Tk,14112 +apprise/plugins/smtp2go.py,sha256=D3C4rWGCJ-oqaZH8JgoMEV_3BYHCCHMd6M7cG0piIvA,19698 +apprise/plugins/sns.py,sha256=dA58nElGwKKnVAr--rh1deIa9BNPbZElK6cb5G1o3g8,24142 +apprise/plugins/sparkpost.py,sha256=ZR4866e1DefqOuuu3z_vBhS8C5YX0sj1G9WEhdWFMEk,27865 +apprise/plugins/streamlabs.py,sha256=Pyrz2xY2rDo8rnTgu4L5t2u1EPrZWVcIP37k8pE2SaE,16010 +apprise/plugins/synology.py,sha256=-g-Cesx8g-nG10shjUAnYtyLpMoGfUNDcTIGfi2UXDE,11088 +apprise/plugins/syslog.py,sha256=sNKh0iSNc3ARuMIO13uwRirMHzW2VxxTRwyZ-0UYL60,10604 +apprise/plugins/techuluspush.py,sha256=HV1m72pRsC3IfVN66zWK9joslDJsKRKYD6_uRfqjnHk,7240 +apprise/plugins/telegram.py,sha256=zsmCUJU-5INyJ-RDUYIHUEXpwnwShOISWc4Xf7Epanw,37168 +apprise/plugins/threema.py,sha256=aWvFfN5Ve0DZCDX7qJVlY8INT_C-AWh-jnYnPTd7Ufs,11868 +apprise/plugins/twilio.py,sha256=0iYa2ug_2_Rbz4N_lGVihtSSxxFaK2f7Sdr9oK_Wg18,15959 +apprise/plugins/twist.py,sha256=hLqabH_STcZiAwRCgFHO7n5qYx7eZgoDw4xT5Zl_y6Q,28824 +apprise/plugins/twitter.py,sha256=ZTHLuZYowQ6qSw9ujsRB5oNp9F9PyutU-iAKAUOkmT8,30129 +apprise/plugins/voipms.py,sha256=NVbrsY7fJG0MbF6eId--0wo9cRC2kehhg8L0sASQs2w,12539 +apprise/plugins/vonage.py,sha256=PRFMdjn0ARqOEhL8kXySz8pi9vsApl2fh9mZyLVySgo,13414 +apprise/plugins/webexteams.py,sha256=DErDmHhvnHfsAyp4L3mF6vSfq0WabL1lbbl-jDUKYTw,9151 +apprise/plugins/wecombot.py,sha256=o5CO0IyHN7wAXhf7es08QiPCmUl8shZCgN_nyJxycVA,8776 +apprise/plugins/whatsapp.py,sha256=9KObQEvUOtOclnudKhNj7qRrJ0uii7dhfxgwzuMHKxY,19911 +apprise/plugins/windows.py,sha256=88bDJQBnuuA0u7_xoTC-1Ppxt4tz39UMZseRY3EX_FE,8550 +apprise/plugins/xbmc.py,sha256=2ssX2AItDUy5FJFDY9r_JI4u7qc0CLGvG-hW0KtgWag,12079 +apprise/plugins/zulip.py,sha256=PJMB8RmV_ddP5waNAQ0Z29cpIut1WFY31DLFeg8-Nao,13955 +apprise/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +apprise/url.py,sha256=QEoqmWzapzXPwBXe85SdJaPWq7B4gcv4QCeJtndN4_E,29455 +apprise/url.pyi,sha256=WLaRREH7FzZ5x3-qkDkupojWGFC4uFwJ1EDt02lVs8c,520 +apprise/utils.py,sha256=Sy0pVslC8FDKh5RY8o6eVB-sPHFxBXFTdbhKSVf4UDM,53461 diff --git a/libs/apprise-1.7.4.dist-info/REQUESTED b/libs/apprise-1.8.0.dist-info/REQUESTED similarity index 100% rename from libs/apprise-1.7.4.dist-info/REQUESTED rename to libs/apprise-1.8.0.dist-info/REQUESTED diff --git a/libs/apprise-1.7.6.dist-info/WHEEL b/libs/apprise-1.8.0.dist-info/WHEEL similarity index 100% rename from libs/apprise-1.7.6.dist-info/WHEEL rename to libs/apprise-1.8.0.dist-info/WHEEL diff --git a/libs/apprise-1.7.6.dist-info/entry_points.txt b/libs/apprise-1.8.0.dist-info/entry_points.txt similarity index 100% rename from libs/apprise-1.7.6.dist-info/entry_points.txt rename to libs/apprise-1.8.0.dist-info/entry_points.txt diff --git a/libs/apprise-1.7.6.dist-info/top_level.txt b/libs/apprise-1.8.0.dist-info/top_level.txt similarity index 100% rename from libs/apprise-1.7.6.dist-info/top_level.txt rename to libs/apprise-1.8.0.dist-info/top_level.txt diff --git a/libs/apprise/Apprise.py b/libs/apprise/Apprise.py index 9a3e8dfc7..05a2ee3cc 100644 --- a/libs/apprise/Apprise.py +++ b/libs/apprise/Apprise.py @@ -33,18 +33,18 @@ from itertools import chain from . import common from .conversion import convert_between from .utils import is_exclusive_match -from .NotificationManager import NotificationManager +from .manager_plugins import NotificationManager from .utils import parse_list from .utils import parse_urls from .utils import cwe312_url from .emojis import apply_emojis from .logger import logger -from .AppriseAsset import AppriseAsset -from .AppriseConfig import AppriseConfig -from .AppriseAttachment import AppriseAttachment -from .AppriseLocale import AppriseLocale -from .config.ConfigBase import ConfigBase -from .plugins.NotifyBase import NotifyBase +from .asset import AppriseAsset +from .apprise_config import AppriseConfig +from .apprise_attachment import AppriseAttachment +from .locale import AppriseLocale +from .config.base import ConfigBase +from .plugins.base import NotifyBase from . import plugins from . import __version__ diff --git a/libs/apprise/__init__.py b/libs/apprise/__init__.py index 81373c75b..457528594 100644 --- a/libs/apprise/__init__.py +++ b/libs/apprise/__init__.py @@ -27,7 +27,7 @@ # POSSIBILITY OF SUCH DAMAGE. __title__ = 'Apprise' -__version__ = '1.7.6' +__version__ = '1.8.0' __author__ = 'Chris Caron' __license__ = 'BSD' __copywrite__ = 'Copyright (C) 2024 Chris Caron ' @@ -49,16 +49,17 @@ from .common import CONTENT_INCLUDE_MODES from .common import ContentLocation from .common import CONTENT_LOCATIONS -from .URLBase import URLBase -from .URLBase import PrivacyMode -from .plugins.NotifyBase import NotifyBase -from .config.ConfigBase import ConfigBase -from .attachment.AttachBase import AttachBase +from .url import URLBase +from .url import PrivacyMode +from .plugins.base import NotifyBase +from .config.base import ConfigBase +from .attachment.base import AttachBase -from .Apprise import Apprise -from .AppriseAsset import AppriseAsset -from .AppriseConfig import AppriseConfig -from .AppriseAttachment import AppriseAttachment +from .apprise import Apprise +from .locale import AppriseLocale +from .asset import AppriseAsset +from .apprise_config import AppriseConfig +from .apprise_attachment import AppriseAttachment from . import decorators @@ -73,7 +74,7 @@ logging.getLogger(__name__).addHandler(logging.NullHandler()) __all__ = [ # Core 'Apprise', 'AppriseAsset', 'AppriseConfig', 'AppriseAttachment', 'URLBase', - 'NotifyBase', 'ConfigBase', 'AttachBase', + 'NotifyBase', 'ConfigBase', 'AttachBase', 'AppriseLocale', # Reference 'NotifyType', 'NotifyImageSize', 'NotifyFormat', 'OverflowMode', diff --git a/libs/apprise/AppriseAttachment.py b/libs/apprise/apprise_attachment.py similarity index 98% rename from libs/apprise/AppriseAttachment.py rename to libs/apprise/apprise_attachment.py index fcfed3af6..3c33f9e73 100644 --- a/libs/apprise/AppriseAttachment.py +++ b/libs/apprise/apprise_attachment.py @@ -27,9 +27,9 @@ # POSSIBILITY OF SUCH DAMAGE. from . import URLBase -from .attachment.AttachBase import AttachBase -from .AppriseAsset import AppriseAsset -from .AttachmentManager import AttachmentManager +from .attachment.base import AttachBase +from .asset import AppriseAsset +from .manager_attachment import AttachmentManager from .logger import logger from .common import ContentLocation from .common import CONTENT_LOCATIONS diff --git a/libs/apprise/AppriseAttachment.pyi b/libs/apprise/apprise_attachment.pyi similarity index 100% rename from libs/apprise/AppriseAttachment.pyi rename to libs/apprise/apprise_attachment.pyi diff --git a/libs/apprise/AppriseConfig.py b/libs/apprise/apprise_config.py similarity index 99% rename from libs/apprise/AppriseConfig.py rename to libs/apprise/apprise_config.py index 7e5a9126f..080f70d30 100644 --- a/libs/apprise/AppriseConfig.py +++ b/libs/apprise/apprise_config.py @@ -28,9 +28,9 @@ from . import ConfigBase from . import CONFIG_FORMATS -from .ConfigurationManager import ConfigurationManager +from .manager_config import ConfigurationManager from . import URLBase -from .AppriseAsset import AppriseAsset +from .asset import AppriseAsset from . import common from .utils import GET_SCHEMA_RE from .utils import parse_list diff --git a/libs/apprise/AppriseConfig.pyi b/libs/apprise/apprise_config.pyi similarity index 100% rename from libs/apprise/AppriseConfig.pyi rename to libs/apprise/apprise_config.pyi diff --git a/libs/apprise/AppriseAsset.py b/libs/apprise/asset.py similarity index 99% rename from libs/apprise/AppriseAsset.py rename to libs/apprise/asset.py index 97a7bccfb..450303d0e 100644 --- a/libs/apprise/AppriseAsset.py +++ b/libs/apprise/asset.py @@ -33,7 +33,7 @@ from os.path import dirname from os.path import isfile from os.path import abspath from .common import NotifyType -from .NotificationManager import NotificationManager +from .manager_plugins import NotificationManager # Grant access to our Notification Manager Singleton diff --git a/libs/apprise/AppriseAsset.pyi b/libs/apprise/asset.pyi similarity index 100% rename from libs/apprise/AppriseAsset.pyi rename to libs/apprise/asset.pyi diff --git a/libs/apprise/attachment/__init__.py b/libs/apprise/attachment/__init__.py index 0a88313d6..c2aef1eec 100644 --- a/libs/apprise/attachment/__init__.py +++ b/libs/apprise/attachment/__init__.py @@ -27,8 +27,8 @@ # POSSIBILITY OF SUCH DAMAGE. # Used for testing -from .AttachBase import AttachBase -from ..AttachmentManager import AttachmentManager +from .base import AttachBase +from ..manager_attachment import AttachmentManager # Initalize our Attachment Manager Singleton A_MGR = AttachmentManager() @@ -36,4 +36,5 @@ A_MGR = AttachmentManager() __all__ = [ # Reference 'AttachBase', + 'AttachmentManager', ] diff --git a/libs/apprise/attachment/AttachBase.py b/libs/apprise/attachment/base.py similarity index 98% rename from libs/apprise/attachment/AttachBase.py rename to libs/apprise/attachment/base.py index 8cb6bd5cb..71e3a4d0d 100644 --- a/libs/apprise/attachment/AttachBase.py +++ b/libs/apprise/attachment/base.py @@ -29,10 +29,10 @@ import os import time import mimetypes -from ..URLBase import URLBase +from ..url import URLBase from ..utils import parse_bool from ..common import ContentLocation -from ..AppriseLocale import gettext_lazy as _ +from ..locale import gettext_lazy as _ class AttachBase(URLBase): @@ -315,7 +315,7 @@ class AttachBase(URLBase): "download() is implimented by the child class.") @staticmethod - def parse_url(url, verify_host=True, mimetype_db=None): + def parse_url(url, verify_host=True, mimetype_db=None, sanitize=True): """Parses the URL and returns it broken apart into a dictionary. This is very specific and customized for Apprise. @@ -333,7 +333,8 @@ class AttachBase(URLBase): successful, otherwise None is returned. """ - results = URLBase.parse_url(url, verify_host=verify_host) + results = URLBase.parse_url( + url, verify_host=verify_host, sanitize=sanitize) if not results: # We're done; we failed to parse our url diff --git a/libs/apprise/attachment/AttachBase.pyi b/libs/apprise/attachment/base.pyi similarity index 100% rename from libs/apprise/attachment/AttachBase.pyi rename to libs/apprise/attachment/base.pyi diff --git a/libs/apprise/attachment/AttachFile.py b/libs/apprise/attachment/file.py similarity index 98% rename from libs/apprise/attachment/AttachFile.py rename to libs/apprise/attachment/file.py index 4c9c8f136..c48a707ae 100644 --- a/libs/apprise/attachment/AttachFile.py +++ b/libs/apprise/attachment/file.py @@ -28,9 +28,9 @@ import re import os -from .AttachBase import AttachBase +from .base import AttachBase from ..common import ContentLocation -from ..AppriseLocale import gettext_lazy as _ +from ..locale import gettext_lazy as _ class AttachFile(AttachBase): diff --git a/libs/apprise/attachment/AttachHTTP.py b/libs/apprise/attachment/http.py similarity index 98% rename from libs/apprise/attachment/AttachHTTP.py rename to libs/apprise/attachment/http.py index 5a3af9467..aa075d671 100644 --- a/libs/apprise/attachment/AttachHTTP.py +++ b/libs/apprise/attachment/http.py @@ -31,10 +31,10 @@ import os import requests import threading from tempfile import NamedTemporaryFile -from .AttachBase import AttachBase +from .base import AttachBase from ..common import ContentLocation -from ..URLBase import PrivacyMode -from ..AppriseLocale import gettext_lazy as _ +from ..url import PrivacyMode +from ..locale import gettext_lazy as _ class AttachHTTP(AttachBase): @@ -296,8 +296,7 @@ class AttachHTTP(AttachBase): """ Tidy memory if open """ - with self._lock: - self.invalidate() + self.invalidate() def url(self, privacy=False, *args, **kwargs): """ @@ -363,8 +362,7 @@ class AttachHTTP(AttachBase): us to re-instantiate this object. """ - results = AttachBase.parse_url(url) - + results = AttachBase.parse_url(url, sanitize=False) if not results: # We're done early as we couldn't load the results return results diff --git a/libs/apprise/config/__init__.py b/libs/apprise/config/__init__.py index efbace687..24957e88e 100644 --- a/libs/apprise/config/__init__.py +++ b/libs/apprise/config/__init__.py @@ -27,8 +27,8 @@ # POSSIBILITY OF SUCH DAMAGE. # Used for testing -from .ConfigBase import ConfigBase -from ..ConfigurationManager import ConfigurationManager +from .base import ConfigBase +from ..manager_config import ConfigurationManager # Initalize our Config Manager Singleton C_MGR = ConfigurationManager() @@ -36,4 +36,5 @@ C_MGR = ConfigurationManager() __all__ = [ # Reference 'ConfigBase', + 'ConfigurationManager', ] diff --git a/libs/apprise/config/ConfigBase.py b/libs/apprise/config/base.py similarity index 99% rename from libs/apprise/config/ConfigBase.py rename to libs/apprise/config/base.py index 32e1bde34..953cee394 100644 --- a/libs/apprise/config/ConfigBase.py +++ b/libs/apprise/config/base.py @@ -33,15 +33,15 @@ import time from .. import plugins from .. import common -from ..AppriseAsset import AppriseAsset -from ..URLBase import URLBase -from ..ConfigurationManager import ConfigurationManager +from ..asset import AppriseAsset +from ..url import URLBase from ..utils import GET_SCHEMA_RE from ..utils import parse_list from ..utils import parse_bool from ..utils import parse_urls from ..utils import cwe312_url -from ..NotificationManager import NotificationManager +from ..manager_config import ConfigurationManager +from ..manager_plugins import NotificationManager # Test whether token is valid or not VALID_TOKEN = re.compile( diff --git a/libs/apprise/config/ConfigBase.pyi b/libs/apprise/config/base.pyi similarity index 100% rename from libs/apprise/config/ConfigBase.pyi rename to libs/apprise/config/base.pyi diff --git a/libs/apprise/config/ConfigFile.py b/libs/apprise/config/file.py similarity index 98% rename from libs/apprise/config/ConfigFile.py rename to libs/apprise/config/file.py index 172d699f8..9f29ca20b 100644 --- a/libs/apprise/config/ConfigFile.py +++ b/libs/apprise/config/file.py @@ -28,10 +28,10 @@ import re import os -from .ConfigBase import ConfigBase +from .base import ConfigBase from ..common import ConfigFormat from ..common import ContentIncludeMode -from ..AppriseLocale import gettext_lazy as _ +from ..locale import gettext_lazy as _ class ConfigFile(ConfigBase): diff --git a/libs/apprise/config/ConfigHTTP.py b/libs/apprise/config/http.py similarity index 98% rename from libs/apprise/config/ConfigHTTP.py rename to libs/apprise/config/http.py index f6faba8d4..2e2ba299b 100644 --- a/libs/apprise/config/ConfigHTTP.py +++ b/libs/apprise/config/http.py @@ -28,11 +28,11 @@ import re import requests -from .ConfigBase import ConfigBase +from .base import ConfigBase from ..common import ConfigFormat from ..common import ContentIncludeMode -from ..URLBase import PrivacyMode -from ..AppriseLocale import gettext_lazy as _ +from ..url import PrivacyMode +from ..locale import gettext_lazy as _ # Support YAML formats # text/yaml diff --git a/libs/apprise/config/ConfigMemory.py b/libs/apprise/config/memory.py similarity index 97% rename from libs/apprise/config/ConfigMemory.py rename to libs/apprise/config/memory.py index 413956dfc..181d76236 100644 --- a/libs/apprise/config/ConfigMemory.py +++ b/libs/apprise/config/memory.py @@ -26,8 +26,8 @@ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. -from .ConfigBase import ConfigBase -from ..AppriseLocale import gettext_lazy as _ +from .base import ConfigBase +from ..locale import gettext_lazy as _ class ConfigMemory(ConfigBase): diff --git a/libs/apprise/conversion.py b/libs/apprise/conversion.py index 4d5632f59..5b6d1a941 100644 --- a/libs/apprise/conversion.py +++ b/libs/apprise/conversion.py @@ -29,7 +29,7 @@ import re from markdown import markdown from .common import NotifyFormat -from .URLBase import URLBase +from .url import URLBase from html.parser import HTMLParser diff --git a/libs/apprise/decorators/CustomNotifyPlugin.py b/libs/apprise/decorators/base.py similarity index 98% rename from libs/apprise/decorators/CustomNotifyPlugin.py rename to libs/apprise/decorators/base.py index eb5f17b78..2661db0aa 100644 --- a/libs/apprise/decorators/CustomNotifyPlugin.py +++ b/libs/apprise/decorators/base.py @@ -27,8 +27,8 @@ # POSSIBILITY OF SUCH DAMAGE.USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. -from ..plugins.NotifyBase import NotifyBase -from ..NotificationManager import NotificationManager +from ..plugins.base import NotifyBase +from ..manager_plugins import NotificationManager from ..utils import URL_DETAILS_RE from ..utils import parse_url from ..utils import url_assembly @@ -55,6 +55,9 @@ class CustomNotifyPlugin(NotifyBase): # should be treated differently. category = 'custom' + # Support Attachments + attachment_support = True + # Define object templates templates = ( '{schema}://', diff --git a/libs/apprise/decorators/notify.py b/libs/apprise/decorators/notify.py index 2dd5f5099..892c3adfe 100644 --- a/libs/apprise/decorators/notify.py +++ b/libs/apprise/decorators/notify.py @@ -26,7 +26,7 @@ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. -from .CustomNotifyPlugin import CustomNotifyPlugin +from .base import CustomNotifyPlugin def notify(on, name=None): diff --git a/libs/apprise/i18n/en/LC_MESSAGES/apprise.mo b/libs/apprise/i18n/en/LC_MESSAGES/apprise.mo index 1d22b89a68a0bcb2532b945c30a51bab4eccad96..f108b538df44a22b2a18b2bb6140e8554b0428c1 100644 GIT binary patch delta 14 Vcmew^_g!v7HaDa3<{WNr762`h1ik((?!_)[A-Za-z0-9]+))$') + # thread safe loading _lock = threading.Lock() @@ -177,7 +180,7 @@ class PluginManager(metaclass=Singleton): # The .py extension is optional as we support loading directories # too module_re = re.compile( - r'^(?P' + self.fname_prefix + r'[a-z0-9]+)(\.py)?$', + r'^(?P(?!base|_)[a-z0-9_]+)(\.py)?$', re.I) t_start = time.time() @@ -188,10 +191,6 @@ class PluginManager(metaclass=Singleton): # keep going continue - elif match.group('name') == f'{self.fname_prefix}Base': - # keep going - continue - # Store our notification/plugin name: module_name = match.group('name') module_pyname = '{}.{}'.format(module_name_prefix, module_name) @@ -216,7 +215,47 @@ class PluginManager(metaclass=Singleton): # logging found in import_module and not needed here continue - if not hasattr(module, module_name): + module_class = None + for m_class in [obj for obj in dir(module) + if self.module_filter_re.match(obj)]: + # Get our plugin + plugin = getattr(module, m_class) + if not hasattr(plugin, 'app_id'): + # Filter out non-notification modules + logger.trace( + "(%s) import failed; no app_id defined in %s", + self.name, m_class, os.path.join(module_path, f)) + continue + + # Add our plugin name to our module map + self._module_map[module_name] = { + 'plugin': set([plugin]), + 'module': module, + 'path': '{}.{}'.format( + module_name_prefix, module_name), + 'native': True, + } + + fn = getattr(plugin, 'schemas', None) + schemas = set([]) if not callable(fn) else fn(plugin) + + # map our schema to our plugin + for schema in schemas: + if schema in self._schema_map: + logger.error( + "{} schema ({}) mismatch detected - {} to {}" + .format(self.name, schema, self._schema_map, + plugin)) + continue + + # Assign plugin + self._schema_map[schema] = plugin + + # Store our class + module_class = m_class + break + + if not module_class: # Not a library we can load as it doesn't follow the simple # rule that the class must bear the same name as the # notification file itself. @@ -226,38 +265,6 @@ class PluginManager(metaclass=Singleton): self.name, module_name, os.path.join(module_path, f)) continue - # Get our plugin - plugin = getattr(module, module_name) - if not hasattr(plugin, 'app_id'): - # Filter out non-notification modules - logger.trace( - "(%s) import failed; no app_id defined in %s", - self.name, module_name, os.path.join(module_path, f)) - continue - - # Add our plugin name to our module map - self._module_map[module_name] = { - 'plugin': set([plugin]), - 'module': module, - 'path': '{}.{}'.format(module_name_prefix, module_name), - 'native': True, - } - - fn = getattr(plugin, 'schemas', None) - schemas = set([]) if not callable(fn) else fn(plugin) - - # map our schema to our plugin - for schema in schemas: - if schema in self._schema_map: - logger.error( - "{} schema ({}) mismatch detected - {} to {}" - .format(self.name, schema, self._schema_map, - plugin)) - continue - - # Assign plugin - self._schema_map[schema] = plugin - logger.trace( '{} {} loaded in {:.6f}s'.format( self.name, module_name, (time.time() - tl_start))) diff --git a/libs/apprise/AttachmentManager.py b/libs/apprise/manager_attachment.py similarity index 93% rename from libs/apprise/AttachmentManager.py rename to libs/apprise/manager_attachment.py index d296a4996..d1288a943 100644 --- a/libs/apprise/AttachmentManager.py +++ b/libs/apprise/manager_attachment.py @@ -26,6 +26,7 @@ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. +import re from os.path import dirname from os.path import abspath from os.path import join @@ -52,3 +53,7 @@ class AttachmentManager(PluginManager): # The module path to scan module_path = join(abspath(dirname(__file__)), _id) + + # For filtering our result set + module_filter_re = re.compile( + r'^(?P' + fname_prefix + r'(?!Base)[A-Za-z0-9]+)$') diff --git a/libs/apprise/ConfigurationManager.py b/libs/apprise/manager_config.py similarity index 93% rename from libs/apprise/ConfigurationManager.py rename to libs/apprise/manager_config.py index 6696895b9..69a6bedb9 100644 --- a/libs/apprise/ConfigurationManager.py +++ b/libs/apprise/manager_config.py @@ -26,6 +26,7 @@ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. +import re from os.path import dirname from os.path import abspath from os.path import join @@ -52,3 +53,7 @@ class ConfigurationManager(PluginManager): # The module path to scan module_path = join(abspath(dirname(__file__)), _id) + + # For filtering our result set + module_filter_re = re.compile( + r'^(?P' + fname_prefix + r'(?!Base)[A-Za-z0-9]+)$') diff --git a/libs/apprise/NotificationManager.py b/libs/apprise/manager_plugins.py similarity index 92% rename from libs/apprise/NotificationManager.py rename to libs/apprise/manager_plugins.py index abbbdd203..74ed370ea 100644 --- a/libs/apprise/NotificationManager.py +++ b/libs/apprise/manager_plugins.py @@ -26,6 +26,7 @@ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. +import re from os.path import dirname from os.path import abspath from os.path import join @@ -52,3 +53,8 @@ class NotificationManager(PluginManager): # The module path to scan module_path = join(abspath(dirname(__file__)), _id) + + # For filtering our result set + module_filter_re = re.compile( + r'^(?P' + fname_prefix + + r'(?!Base|ImageSize|Type)[A-Za-z0-9]+)$') diff --git a/libs/apprise/plugins/__init__.py b/libs/apprise/plugins/__init__.py index 72cb08fbf..bfce14371 100644 --- a/libs/apprise/plugins/__init__.py +++ b/libs/apprise/plugins/__init__.py @@ -30,7 +30,7 @@ import os import copy # Used for testing -from .NotifyBase import NotifyBase +from .base import NotifyBase from ..common import NotifyImageSize from ..common import NOTIFY_IMAGE_SIZES @@ -40,9 +40,9 @@ from ..utils import parse_list from ..utils import cwe312_url from ..utils import GET_SCHEMA_RE from ..logger import logger -from ..AppriseLocale import gettext_lazy as _ -from ..AppriseLocale import LazyTranslation -from ..NotificationManager import NotificationManager +from ..locale import gettext_lazy as _ +from ..locale import LazyTranslation +from ..manager_plugins import NotificationManager # Grant access to our Notification Manager Singleton diff --git a/libs/apprise/plugins/NotifyAppriseAPI.py b/libs/apprise/plugins/apprise_api.py similarity index 99% rename from libs/apprise/plugins/NotifyAppriseAPI.py rename to libs/apprise/plugins/apprise_api.py index 34c34a6d4..fd71236b5 100644 --- a/libs/apprise/plugins/NotifyAppriseAPI.py +++ b/libs/apprise/plugins/apprise_api.py @@ -31,12 +31,12 @@ import requests from json import dumps import base64 -from .NotifyBase import NotifyBase -from ..URLBase import PrivacyMode +from .base import NotifyBase +from ..url import PrivacyMode from ..common import NotifyType from ..utils import parse_list from ..utils import validate_regex -from ..AppriseLocale import gettext_lazy as _ +from ..locale import gettext_lazy as _ class AppriseAPIMethod: @@ -123,7 +123,7 @@ class NotifyAppriseAPI(NotifyBase): 'type': 'string', 'required': True, 'private': True, - 'regex': (r'^[A-Z0-9_-]{1,32}$', 'i'), + 'regex': (r'^[A-Z0-9_-]{1,128}$', 'i'), }, }) diff --git a/libs/apprise/plugins/NotifyAprs.py b/libs/apprise/plugins/aprs.py similarity index 99% rename from libs/apprise/plugins/NotifyAprs.py rename to libs/apprise/plugins/aprs.py index 5d8c3c100..b8adef5aa 100644 --- a/libs/apprise/plugins/NotifyAprs.py +++ b/libs/apprise/plugins/aprs.py @@ -70,9 +70,9 @@ import socket import sys from itertools import chain -from .NotifyBase import NotifyBase -from ..AppriseLocale import gettext_lazy as _ -from ..URLBase import PrivacyMode +from .base import NotifyBase +from ..locale import gettext_lazy as _ +from ..url import PrivacyMode from ..common import NotifyType from ..utils import is_call_sign from ..utils import parse_call_sign diff --git a/libs/apprise/plugins/NotifyBark.py b/libs/apprise/plugins/bark.py similarity index 99% rename from libs/apprise/plugins/NotifyBark.py rename to libs/apprise/plugins/bark.py index 781a1515e..e2f5bbfb4 100644 --- a/libs/apprise/plugins/NotifyBark.py +++ b/libs/apprise/plugins/bark.py @@ -32,13 +32,13 @@ import requests import json -from .NotifyBase import NotifyBase -from ..URLBase import PrivacyMode +from .base import NotifyBase +from ..url import PrivacyMode from ..common import NotifyImageSize from ..common import NotifyType from ..utils import parse_list from ..utils import parse_bool -from ..AppriseLocale import gettext_lazy as _ +from ..locale import gettext_lazy as _ # Sounds generated off of: https://github.com/Finb/Bark/tree/master/Sounds diff --git a/libs/apprise/plugins/NotifyBase.py b/libs/apprise/plugins/base.py similarity index 99% rename from libs/apprise/plugins/NotifyBase.py rename to libs/apprise/plugins/base.py index c29417c60..1abc3410e 100644 --- a/libs/apprise/plugins/NotifyBase.py +++ b/libs/apprise/plugins/base.py @@ -30,7 +30,7 @@ import asyncio import re from functools import partial -from ..URLBase import URLBase +from ..url import URLBase from ..common import NotifyType from ..utils import parse_bool from ..common import NOTIFY_TYPES @@ -38,8 +38,8 @@ from ..common import NotifyFormat from ..common import NOTIFY_FORMATS from ..common import OverflowMode from ..common import OVERFLOW_MODES -from ..AppriseLocale import gettext_lazy as _ -from ..AppriseAttachment import AppriseAttachment +from ..locale import gettext_lazy as _ +from ..apprise_attachment import AppriseAttachment class NotifyBase(URLBase): diff --git a/libs/apprise/plugins/NotifyBase.pyi b/libs/apprise/plugins/base.pyi similarity index 100% rename from libs/apprise/plugins/NotifyBase.pyi rename to libs/apprise/plugins/base.pyi diff --git a/libs/apprise/plugins/NotifyBoxcar.py b/libs/apprise/plugins/boxcar.py similarity index 99% rename from libs/apprise/plugins/NotifyBoxcar.py rename to libs/apprise/plugins/boxcar.py index 808920ed5..851cdd3d8 100644 --- a/libs/apprise/plugins/NotifyBoxcar.py +++ b/libs/apprise/plugins/boxcar.py @@ -35,14 +35,14 @@ from hashlib import sha1 from itertools import chain from urllib.parse import urlparse -from .NotifyBase import NotifyBase -from ..URLBase import PrivacyMode +from .base import NotifyBase +from ..url import PrivacyMode from ..utils import parse_bool from ..utils import parse_list from ..utils import validate_regex from ..common import NotifyType from ..common import NotifyImageSize -from ..AppriseLocale import gettext_lazy as _ +from ..locale import gettext_lazy as _ # Default to sending to all devices if nothing is specified DEFAULT_TAG = '@all' diff --git a/libs/apprise/plugins/NotifyBulkSMS.py b/libs/apprise/plugins/bulksms.py similarity index 99% rename from libs/apprise/plugins/NotifyBulkSMS.py rename to libs/apprise/plugins/bulksms.py index 33664fb00..29c4d7fac 100644 --- a/libs/apprise/plugins/NotifyBulkSMS.py +++ b/libs/apprise/plugins/bulksms.py @@ -36,13 +36,13 @@ import re import requests import json from itertools import chain -from .NotifyBase import NotifyBase -from ..URLBase import PrivacyMode +from .base import NotifyBase +from ..url import PrivacyMode from ..common import NotifyType from ..utils import is_phone_no from ..utils import parse_phone_no from ..utils import parse_bool -from ..AppriseLocale import gettext_lazy as _ +from ..locale import gettext_lazy as _ IS_GROUP_RE = re.compile( diff --git a/libs/apprise/plugins/NotifyBulkVS.py b/libs/apprise/plugins/bulkvs.py similarity index 99% rename from libs/apprise/plugins/NotifyBulkVS.py rename to libs/apprise/plugins/bulkvs.py index e912dff25..53a363008 100644 --- a/libs/apprise/plugins/NotifyBulkVS.py +++ b/libs/apprise/plugins/bulkvs.py @@ -35,13 +35,13 @@ # Messaging/post_messageSend import requests import json -from .NotifyBase import NotifyBase -from ..URLBase import PrivacyMode +from .base import NotifyBase +from ..url import PrivacyMode from ..common import NotifyType from ..utils import is_phone_no from ..utils import parse_phone_no from ..utils import parse_bool -from ..AppriseLocale import gettext_lazy as _ +from ..locale import gettext_lazy as _ class NotifyBulkVS(NotifyBase): diff --git a/libs/apprise/plugins/NotifyBurstSMS.py b/libs/apprise/plugins/burstsms.py similarity index 99% rename from libs/apprise/plugins/NotifyBurstSMS.py rename to libs/apprise/plugins/burstsms.py index 39606abba..eb19df8e4 100644 --- a/libs/apprise/plugins/NotifyBurstSMS.py +++ b/libs/apprise/plugins/burstsms.py @@ -33,14 +33,14 @@ # import requests -from .NotifyBase import NotifyBase -from ..URLBase import PrivacyMode +from .base import NotifyBase +from ..url import PrivacyMode from ..common import NotifyType from ..utils import is_phone_no from ..utils import parse_phone_no from ..utils import parse_bool from ..utils import validate_regex -from ..AppriseLocale import gettext_lazy as _ +from ..locale import gettext_lazy as _ class BurstSMSCountryCode: diff --git a/libs/apprise/plugins/NotifyChantify.py b/libs/apprise/plugins/chantify.py similarity index 98% rename from libs/apprise/plugins/NotifyChantify.py rename to libs/apprise/plugins/chantify.py index d912bd257..d549a59fa 100644 --- a/libs/apprise/plugins/NotifyChantify.py +++ b/libs/apprise/plugins/chantify.py @@ -35,10 +35,10 @@ import requests -from .NotifyBase import NotifyBase +from .base import NotifyBase from ..common import NotifyType from ..utils import validate_regex -from ..AppriseLocale import gettext_lazy as _ +from ..locale import gettext_lazy as _ class NotifyChantify(NotifyBase): diff --git a/libs/apprise/plugins/NotifyClickSend.py b/libs/apprise/plugins/clicksend.py similarity index 94% rename from libs/apprise/plugins/NotifyClickSend.py rename to libs/apprise/plugins/clicksend.py index 5e345fe10..9ade1055e 100644 --- a/libs/apprise/plugins/NotifyClickSend.py +++ b/libs/apprise/plugins/clicksend.py @@ -41,15 +41,14 @@ # import requests from json import dumps -from base64 import b64encode -from .NotifyBase import NotifyBase -from ..URLBase import PrivacyMode +from .base import NotifyBase +from ..url import PrivacyMode from ..common import NotifyType from ..utils import is_phone_no from ..utils import parse_phone_no from ..utils import parse_bool -from ..AppriseLocale import gettext_lazy as _ +from ..locale import gettext_lazy as _ # Extend HTTP Error Messages CLICKSEND_HTTP_ERROR_MAP = { @@ -89,7 +88,7 @@ class NotifyClickSend(NotifyBase): # Define object templates templates = ( - '{schema}://{user}:{password}@{targets}', + '{schema}://{user}:{apikey}@{targets}', ) # Define our template tokens @@ -99,11 +98,12 @@ class NotifyClickSend(NotifyBase): 'type': 'string', 'required': True, }, - 'password': { - 'name': _('Password'), + 'apikey': { + 'name': _('API Key'), 'type': 'string', 'private': True, 'required': True, + 'map_to': 'password', }, 'target_phone': { 'name': _('Target Phone No'), @@ -124,6 +124,9 @@ class NotifyClickSend(NotifyBase): 'to': { 'alias_of': 'targets', }, + 'key': { + 'alias_of': 'apikey', + }, 'batch': { 'name': _('Batch Mode'), 'type': 'bool', @@ -174,9 +177,6 @@ class NotifyClickSend(NotifyBase): headers = { 'User-Agent': self.app_id, 'Content-Type': 'application/json; charset=utf-8', - 'Authorization': 'Basic {}'.format( - b64encode('{}:{}'.format( - self.user, self.password).encode('utf-8'))), } # error tracking (used for function return) @@ -208,6 +208,7 @@ class NotifyClickSend(NotifyBase): r = requests.post( self.notify_url, data=dumps(payload), + auth=(self.user, self.password), headers=headers, verify=self.verify_certificate, timeout=self.request_timeout, @@ -322,6 +323,12 @@ class NotifyClickSend(NotifyBase): results['batch'] = \ parse_bool(results['qsd'].get('batch', False)) + # API Key + if 'key' in results['qsd'] and len(results['qsd']['key']): + # Extract the API Key from an argument + results['password'] = \ + NotifyClickSend.unquote(results['qsd']['key']) + # Support the 'to' variable so that we can support rooms this way too # The 'to' makes it easier to use yaml configuration if 'to' in results['qsd'] and len(results['qsd']['to']): diff --git a/libs/apprise/plugins/NotifyForm.py b/libs/apprise/plugins/custom_form.py similarity index 99% rename from libs/apprise/plugins/NotifyForm.py rename to libs/apprise/plugins/custom_form.py index 9690cd4f5..0f36643f7 100644 --- a/libs/apprise/plugins/NotifyForm.py +++ b/libs/apprise/plugins/custom_form.py @@ -29,11 +29,11 @@ import re import requests -from .NotifyBase import NotifyBase -from ..URLBase import PrivacyMode +from .base import NotifyBase +from ..url import PrivacyMode from ..common import NotifyImageSize from ..common import NotifyType -from ..AppriseLocale import gettext_lazy as _ +from ..locale import gettext_lazy as _ class FORMPayloadField: diff --git a/libs/apprise/plugins/NotifyJSON.py b/libs/apprise/plugins/custom_json.py similarity index 99% rename from libs/apprise/plugins/NotifyJSON.py rename to libs/apprise/plugins/custom_json.py index 182ff77cf..e0d7a6753 100644 --- a/libs/apprise/plugins/NotifyJSON.py +++ b/libs/apprise/plugins/custom_json.py @@ -30,11 +30,11 @@ import requests import base64 from json import dumps -from .NotifyBase import NotifyBase -from ..URLBase import PrivacyMode +from .base import NotifyBase +from ..url import PrivacyMode from ..common import NotifyImageSize from ..common import NotifyType -from ..AppriseLocale import gettext_lazy as _ +from ..locale import gettext_lazy as _ class JSONPayloadField: diff --git a/libs/apprise/plugins/NotifyXML.py b/libs/apprise/plugins/custom_xml.py similarity index 99% rename from libs/apprise/plugins/NotifyXML.py rename to libs/apprise/plugins/custom_xml.py index 21ccb79d3..b7928fceb 100644 --- a/libs/apprise/plugins/NotifyXML.py +++ b/libs/apprise/plugins/custom_xml.py @@ -30,11 +30,11 @@ import re import requests import base64 -from .NotifyBase import NotifyBase -from ..URLBase import PrivacyMode +from .base import NotifyBase +from ..url import PrivacyMode from ..common import NotifyImageSize from ..common import NotifyType -from ..AppriseLocale import gettext_lazy as _ +from ..locale import gettext_lazy as _ class XMLPayloadField: diff --git a/libs/apprise/plugins/NotifyD7Networks.py b/libs/apprise/plugins/d7networks.py similarity index 99% rename from libs/apprise/plugins/NotifyD7Networks.py rename to libs/apprise/plugins/d7networks.py index 906ec2fb9..ad55e2197 100644 --- a/libs/apprise/plugins/NotifyD7Networks.py +++ b/libs/apprise/plugins/d7networks.py @@ -39,13 +39,13 @@ import requests from json import dumps from json import loads -from .NotifyBase import NotifyBase +from .base import NotifyBase from ..common import NotifyType from ..utils import is_phone_no from ..utils import parse_phone_no from ..utils import validate_regex from ..utils import parse_bool -from ..AppriseLocale import gettext_lazy as _ +from ..locale import gettext_lazy as _ # Extend HTTP Error Messages D7NETWORKS_HTTP_ERROR_MAP = { diff --git a/libs/apprise/plugins/NotifyDapnet.py b/libs/apprise/plugins/dapnet.py similarity index 99% rename from libs/apprise/plugins/NotifyDapnet.py rename to libs/apprise/plugins/dapnet.py index ae7199c94..60a18acd4 100644 --- a/libs/apprise/plugins/NotifyDapnet.py +++ b/libs/apprise/plugins/dapnet.py @@ -51,9 +51,9 @@ from json import dumps import requests from requests.auth import HTTPBasicAuth -from .NotifyBase import NotifyBase -from ..AppriseLocale import gettext_lazy as _ -from ..URLBase import PrivacyMode +from .base import NotifyBase +from ..locale import gettext_lazy as _ +from ..url import PrivacyMode from ..common import NotifyType from ..utils import is_call_sign from ..utils import parse_call_sign diff --git a/libs/apprise/plugins/NotifyDBus.py b/libs/apprise/plugins/dbus.py similarity index 99% rename from libs/apprise/plugins/NotifyDBus.py rename to libs/apprise/plugins/dbus.py index 52e119813..f2361fd62 100644 --- a/libs/apprise/plugins/NotifyDBus.py +++ b/libs/apprise/plugins/dbus.py @@ -27,11 +27,11 @@ # POSSIBILITY OF SUCH DAMAGE. import sys -from .NotifyBase import NotifyBase +from .base import NotifyBase from ..common import NotifyImageSize from ..common import NotifyType from ..utils import parse_bool -from ..AppriseLocale import gettext_lazy as _ +from ..locale import gettext_lazy as _ # Default our global support flag NOTIFY_DBUS_SUPPORT_ENABLED = False diff --git a/libs/apprise/plugins/NotifyDingTalk.py b/libs/apprise/plugins/dingtalk.py similarity index 99% rename from libs/apprise/plugins/NotifyDingTalk.py rename to libs/apprise/plugins/dingtalk.py index d4a492fc7..2ca1bc55b 100644 --- a/libs/apprise/plugins/NotifyDingTalk.py +++ b/libs/apprise/plugins/dingtalk.py @@ -34,13 +34,13 @@ import base64 import requests from json import dumps -from .NotifyBase import NotifyBase -from ..URLBase import PrivacyMode +from .base import NotifyBase +from ..url import PrivacyMode from ..common import NotifyFormat from ..common import NotifyType from ..utils import parse_list from ..utils import validate_regex -from ..AppriseLocale import gettext_lazy as _ +from ..locale import gettext_lazy as _ # Register at https://dingtalk.com # - Download their PC based software as it is the only way you can create diff --git a/libs/apprise/plugins/NotifyDiscord.py b/libs/apprise/plugins/discord.py similarity index 99% rename from libs/apprise/plugins/NotifyDiscord.py rename to libs/apprise/plugins/discord.py index 82d764f50..14c6152ba 100644 --- a/libs/apprise/plugins/NotifyDiscord.py +++ b/libs/apprise/plugins/discord.py @@ -50,14 +50,14 @@ from datetime import timedelta from datetime import datetime from datetime import timezone -from .NotifyBase import NotifyBase +from .base import NotifyBase from ..common import NotifyImageSize from ..common import NotifyFormat from ..common import NotifyType from ..utils import parse_bool from ..utils import validate_regex -from ..AppriseLocale import gettext_lazy as _ -from ..attachment.AttachBase import AttachBase +from ..locale import gettext_lazy as _ +from ..attachment.base import AttachBase # Used to detect user/role IDs diff --git a/libs/apprise/plugins/NotifyEmail.py b/libs/apprise/plugins/email.py similarity index 98% rename from libs/apprise/plugins/NotifyEmail.py rename to libs/apprise/plugins/email.py index 80f88bf61..142c93cfb 100644 --- a/libs/apprise/plugins/NotifyEmail.py +++ b/libs/apprise/plugins/email.py @@ -41,12 +41,12 @@ from socket import error as SocketError from datetime import datetime from datetime import timezone -from .NotifyBase import NotifyBase -from ..URLBase import PrivacyMode +from .base import NotifyBase +from ..url import PrivacyMode from ..common import NotifyFormat, NotifyType from ..conversion import convert_between -from ..utils import is_email, parse_emails, is_hostname -from ..AppriseLocale import gettext_lazy as _ +from ..utils import is_ipaddr, is_email, parse_emails, is_hostname +from ..locale import gettext_lazy as _ from ..logger import logger # Globally Default encoding mode set to Quoted Printable. @@ -1053,8 +1053,12 @@ class NotifyEmail(NotifyBase): # Prepare our target lists results['targets'] = [] - if not is_hostname(results['host'], ipv4=False, ipv6=False, - underscore=False): + if is_ipaddr(results['host']): + # Silently move on and do not disrupt any configuration + pass + + elif not is_hostname(results['host'], ipv4=False, ipv6=False, + underscore=False): if is_email(NotifyEmail.unquote(results['host'])): # Don't lose defined email addresses diff --git a/libs/apprise/plugins/NotifyEmby.py b/libs/apprise/plugins/emby.py similarity index 99% rename from libs/apprise/plugins/NotifyEmby.py rename to libs/apprise/plugins/emby.py index ce96553a2..5e4e0b89f 100644 --- a/libs/apprise/plugins/NotifyEmby.py +++ b/libs/apprise/plugins/emby.py @@ -34,12 +34,12 @@ import hashlib from json import dumps from json import loads -from .NotifyBase import NotifyBase -from ..URLBase import PrivacyMode +from .base import NotifyBase +from ..url import PrivacyMode from ..utils import parse_bool from ..common import NotifyType from .. import __version__ as VERSION -from ..AppriseLocale import gettext_lazy as _ +from ..locale import gettext_lazy as _ class NotifyEmby(NotifyBase): diff --git a/libs/apprise/plugins/NotifyEnigma2.py b/libs/apprise/plugins/enigma2.py similarity index 98% rename from libs/apprise/plugins/NotifyEnigma2.py rename to libs/apprise/plugins/enigma2.py index 313149993..8b1fff687 100644 --- a/libs/apprise/plugins/NotifyEnigma2.py +++ b/libs/apprise/plugins/enigma2.py @@ -37,10 +37,10 @@ import requests from json import loads -from .NotifyBase import NotifyBase -from ..URLBase import PrivacyMode +from .base import NotifyBase +from ..url import PrivacyMode from ..common import NotifyType -from ..AppriseLocale import gettext_lazy as _ +from ..locale import gettext_lazy as _ class Enigma2MessageType: diff --git a/libs/apprise/plugins/NotifyFCM/__init__.py b/libs/apprise/plugins/fcm/__init__.py similarity index 99% rename from libs/apprise/plugins/NotifyFCM/__init__.py rename to libs/apprise/plugins/fcm/__init__.py index 54b6c9cc7..9dc0679f1 100644 --- a/libs/apprise/plugins/NotifyFCM/__init__.py +++ b/libs/apprise/plugins/fcm/__init__.py @@ -50,15 +50,15 @@ # You will need this in order to send an apprise messag import requests from json import dumps -from ..NotifyBase import NotifyBase +from ..base import NotifyBase from ...common import NotifyType from ...utils import validate_regex from ...utils import parse_list from ...utils import parse_bool from ...utils import dict_full_update from ...common import NotifyImageSize -from ...AppriseAttachment import AppriseAttachment -from ...AppriseLocale import gettext_lazy as _ +from ...apprise_attachment import AppriseAttachment +from ...locale import gettext_lazy as _ from .common import (FCMMode, FCM_MODES) from .priority import (FCM_PRIORITIES, FCMPriorityManager) from .color import FCMColorManager diff --git a/libs/apprise/plugins/NotifyFCM/color.py b/libs/apprise/plugins/fcm/color.py similarity index 99% rename from libs/apprise/plugins/NotifyFCM/color.py rename to libs/apprise/plugins/fcm/color.py index c7da209a7..20149eedd 100644 --- a/libs/apprise/plugins/NotifyFCM/color.py +++ b/libs/apprise/plugins/fcm/color.py @@ -36,7 +36,7 @@ import re from ...utils import parse_bool from ...common import NotifyType -from ...AppriseAsset import AppriseAsset +from ...asset import AppriseAsset class FCMColorManager: diff --git a/libs/apprise/plugins/NotifyFCM/common.py b/libs/apprise/plugins/fcm/common.py similarity index 100% rename from libs/apprise/plugins/NotifyFCM/common.py rename to libs/apprise/plugins/fcm/common.py diff --git a/libs/apprise/plugins/NotifyFCM/oauth.py b/libs/apprise/plugins/fcm/oauth.py similarity index 100% rename from libs/apprise/plugins/NotifyFCM/oauth.py rename to libs/apprise/plugins/fcm/oauth.py diff --git a/libs/apprise/plugins/NotifyFCM/priority.py b/libs/apprise/plugins/fcm/priority.py similarity index 100% rename from libs/apprise/plugins/NotifyFCM/priority.py rename to libs/apprise/plugins/fcm/priority.py diff --git a/libs/apprise/plugins/NotifyFeishu.py b/libs/apprise/plugins/feishu.py similarity index 98% rename from libs/apprise/plugins/NotifyFeishu.py rename to libs/apprise/plugins/feishu.py index e6988333c..961523bab 100644 --- a/libs/apprise/plugins/NotifyFeishu.py +++ b/libs/apprise/plugins/feishu.py @@ -36,10 +36,10 @@ import requests from json import dumps -from .NotifyBase import NotifyBase +from .base import NotifyBase from ..common import NotifyType from ..utils import validate_regex -from ..AppriseLocale import gettext_lazy as _ +from ..locale import gettext_lazy as _ class NotifyFeishu(NotifyBase): diff --git a/libs/apprise/plugins/NotifyFlock.py b/libs/apprise/plugins/flock.py similarity index 99% rename from libs/apprise/plugins/NotifyFlock.py rename to libs/apprise/plugins/flock.py index f1d12067e..bf2cd131d 100644 --- a/libs/apprise/plugins/NotifyFlock.py +++ b/libs/apprise/plugins/flock.py @@ -44,14 +44,14 @@ import re import requests from json import dumps -from .NotifyBase import NotifyBase +from .base import NotifyBase from ..common import NotifyType from ..common import NotifyFormat from ..common import NotifyImageSize from ..utils import parse_list from ..utils import parse_bool from ..utils import validate_regex -from ..AppriseLocale import gettext_lazy as _ +from ..locale import gettext_lazy as _ # Extend HTTP Error Messages diff --git a/libs/apprise/plugins/NotifyFreeMobile.py b/libs/apprise/plugins/freemobile.py similarity index 98% rename from libs/apprise/plugins/NotifyFreeMobile.py rename to libs/apprise/plugins/freemobile.py index 4aad8db3d..4ff3d4822 100644 --- a/libs/apprise/plugins/NotifyFreeMobile.py +++ b/libs/apprise/plugins/freemobile.py @@ -36,9 +36,9 @@ import requests from json import dumps -from .NotifyBase import NotifyBase +from .base import NotifyBase from ..common import NotifyType -from ..AppriseLocale import gettext_lazy as _ +from ..locale import gettext_lazy as _ class NotifyFreeMobile(NotifyBase): @@ -126,6 +126,7 @@ class NotifyFreeMobile(NotifyBase): # prepare our headers headers = { 'User-Agent': self.app_id, + 'Content-Type': 'application/json', } # Prepare our payload diff --git a/libs/apprise/plugins/NotifyGnome.py b/libs/apprise/plugins/gnome.py similarity index 99% rename from libs/apprise/plugins/NotifyGnome.py rename to libs/apprise/plugins/gnome.py index 67129216d..b64b51304 100644 --- a/libs/apprise/plugins/NotifyGnome.py +++ b/libs/apprise/plugins/gnome.py @@ -26,11 +26,11 @@ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. -from .NotifyBase import NotifyBase +from .base import NotifyBase from ..common import NotifyImageSize from ..common import NotifyType from ..utils import parse_bool -from ..AppriseLocale import gettext_lazy as _ +from ..locale import gettext_lazy as _ # Default our global support flag NOTIFY_GNOME_SUPPORT_ENABLED = False diff --git a/libs/apprise/plugins/NotifyGoogleChat.py b/libs/apprise/plugins/google_chat.py similarity index 99% rename from libs/apprise/plugins/NotifyGoogleChat.py rename to libs/apprise/plugins/google_chat.py index d2a6cc8a8..f30cdae49 100644 --- a/libs/apprise/plugins/NotifyGoogleChat.py +++ b/libs/apprise/plugins/google_chat.py @@ -58,11 +58,11 @@ import re import requests from json import dumps -from .NotifyBase import NotifyBase +from .base import NotifyBase from ..common import NotifyFormat from ..common import NotifyType from ..utils import validate_regex -from ..AppriseLocale import gettext_lazy as _ +from ..locale import gettext_lazy as _ class NotifyGoogleChat(NotifyBase): diff --git a/libs/apprise/plugins/NotifyGotify.py b/libs/apprise/plugins/gotify.py similarity index 99% rename from libs/apprise/plugins/NotifyGotify.py rename to libs/apprise/plugins/gotify.py index 3f4ce132d..bf6c1b281 100644 --- a/libs/apprise/plugins/NotifyGotify.py +++ b/libs/apprise/plugins/gotify.py @@ -34,10 +34,10 @@ import requests from json import dumps -from .NotifyBase import NotifyBase +from .base import NotifyBase from ..common import NotifyType, NotifyFormat from ..utils import validate_regex -from ..AppriseLocale import gettext_lazy as _ +from ..locale import gettext_lazy as _ # Priorities diff --git a/libs/apprise/plugins/NotifyGrowl.py b/libs/apprise/plugins/growl.py similarity index 99% rename from libs/apprise/plugins/NotifyGrowl.py rename to libs/apprise/plugins/growl.py index 0b42e3bec..0b3672188 100644 --- a/libs/apprise/plugins/NotifyGrowl.py +++ b/libs/apprise/plugins/growl.py @@ -26,12 +26,12 @@ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. -from .NotifyBase import NotifyBase -from ..URLBase import PrivacyMode +from .base import NotifyBase +from ..url import PrivacyMode from ..common import NotifyImageSize from ..common import NotifyType from ..utils import parse_bool -from ..AppriseLocale import gettext_lazy as _ +from ..locale import gettext_lazy as _ # Default our global support flag NOTIFY_GROWL_SUPPORT_ENABLED = False diff --git a/libs/apprise/plugins/NotifyGuilded.py b/libs/apprise/plugins/guilded.py similarity index 96% rename from libs/apprise/plugins/NotifyGuilded.py rename to libs/apprise/plugins/guilded.py index 0ea36d9f8..0ee07018e 100644 --- a/libs/apprise/plugins/NotifyGuilded.py +++ b/libs/apprise/plugins/guilded.py @@ -45,10 +45,11 @@ # import re -from .NotifyDiscord import NotifyDiscord +# Import namespace so the class won't conflict with the actual Notify object +from . import discord -class NotifyGuilded(NotifyDiscord): +class NotifyGuilded(discord.NotifyDiscord): """ A wrapper to Guilded Notifications diff --git a/libs/apprise/plugins/NotifyHomeAssistant.py b/libs/apprise/plugins/home_assistant.py similarity index 98% rename from libs/apprise/plugins/NotifyHomeAssistant.py rename to libs/apprise/plugins/home_assistant.py index 0829381b9..b0ffcaa64 100644 --- a/libs/apprise/plugins/NotifyHomeAssistant.py +++ b/libs/apprise/plugins/home_assistant.py @@ -34,11 +34,11 @@ from json import dumps from uuid import uuid4 -from .NotifyBase import NotifyBase -from ..URLBase import PrivacyMode +from .base import NotifyBase +from ..url import PrivacyMode from ..common import NotifyType from ..utils import validate_regex -from ..AppriseLocale import gettext_lazy as _ +from ..locale import gettext_lazy as _ class NotifyHomeAssistant(NotifyBase): diff --git a/libs/apprise/plugins/NotifyHttpSMS.py b/libs/apprise/plugins/httpsms.py similarity index 99% rename from libs/apprise/plugins/NotifyHttpSMS.py rename to libs/apprise/plugins/httpsms.py index 647100949..b36e286d7 100644 --- a/libs/apprise/plugins/NotifyHttpSMS.py +++ b/libs/apprise/plugins/httpsms.py @@ -31,12 +31,12 @@ # https://httpsms.com import requests import json -from .NotifyBase import NotifyBase +from .base import NotifyBase from ..common import NotifyType from ..utils import is_phone_no from ..utils import parse_phone_no from ..utils import validate_regex -from ..AppriseLocale import gettext_lazy as _ +from ..locale import gettext_lazy as _ class NotifyHttpSMS(NotifyBase): diff --git a/libs/apprise/plugins/NotifyIFTTT.py b/libs/apprise/plugins/ifttt.py similarity index 99% rename from libs/apprise/plugins/NotifyIFTTT.py rename to libs/apprise/plugins/ifttt.py index 9174640d0..9d89b1464 100644 --- a/libs/apprise/plugins/NotifyIFTTT.py +++ b/libs/apprise/plugins/ifttt.py @@ -44,11 +44,11 @@ import re import requests from json import dumps -from .NotifyBase import NotifyBase +from .base import NotifyBase from ..common import NotifyType from ..utils import parse_list from ..utils import validate_regex -from ..AppriseLocale import gettext_lazy as _ +from ..locale import gettext_lazy as _ class NotifyIFTTT(NotifyBase): diff --git a/libs/apprise/plugins/NotifyJoin.py b/libs/apprise/plugins/join.py similarity index 99% rename from libs/apprise/plugins/NotifyJoin.py rename to libs/apprise/plugins/join.py index c6b0d91e9..b92bb37a3 100644 --- a/libs/apprise/plugins/NotifyJoin.py +++ b/libs/apprise/plugins/join.py @@ -39,13 +39,13 @@ import re import requests -from .NotifyBase import NotifyBase +from .base import NotifyBase from ..common import NotifyImageSize from ..common import NotifyType from ..utils import parse_list from ..utils import parse_bool from ..utils import validate_regex -from ..AppriseLocale import gettext_lazy as _ +from ..locale import gettext_lazy as _ # Extend HTTP Error Messages JOIN_HTTP_ERROR_MAP = { diff --git a/libs/apprise/plugins/NotifyKavenegar.py b/libs/apprise/plugins/kavenegar.py similarity index 99% rename from libs/apprise/plugins/NotifyKavenegar.py rename to libs/apprise/plugins/kavenegar.py index 2a9c169d7..e4963f409 100644 --- a/libs/apprise/plugins/NotifyKavenegar.py +++ b/libs/apprise/plugins/kavenegar.py @@ -38,12 +38,12 @@ import requests from json import loads -from .NotifyBase import NotifyBase +from .base import NotifyBase from ..common import NotifyType from ..utils import is_phone_no from ..utils import parse_phone_no from ..utils import validate_regex -from ..AppriseLocale import gettext_lazy as _ +from ..locale import gettext_lazy as _ # Extend HTTP Error Messages # Based on https://kavenegar.com/rest.html diff --git a/libs/apprise/plugins/NotifyKumulos.py b/libs/apprise/plugins/kumulos.py similarity index 99% rename from libs/apprise/plugins/NotifyKumulos.py rename to libs/apprise/plugins/kumulos.py index da372e773..504dcc379 100644 --- a/libs/apprise/plugins/NotifyKumulos.py +++ b/libs/apprise/plugins/kumulos.py @@ -39,10 +39,10 @@ import requests from json import dumps -from .NotifyBase import NotifyBase +from .base import NotifyBase from ..common import NotifyType from ..utils import validate_regex -from ..AppriseLocale import gettext_lazy as _ +from ..locale import gettext_lazy as _ # Extend HTTP Error Messages KUMULOS_HTTP_ERROR_MAP = { diff --git a/libs/apprise/plugins/NotifyLametric.py b/libs/apprise/plugins/lametric.py similarity index 99% rename from libs/apprise/plugins/NotifyLametric.py rename to libs/apprise/plugins/lametric.py index 5825d9176..411b9ea21 100644 --- a/libs/apprise/plugins/NotifyLametric.py +++ b/libs/apprise/plugins/lametric.py @@ -90,10 +90,10 @@ import re import requests from json import dumps -from .NotifyBase import NotifyBase +from .base import NotifyBase from ..common import NotifyType from ..utils import validate_regex -from ..AppriseLocale import gettext_lazy as _ +from ..locale import gettext_lazy as _ from ..utils import is_hostname from ..utils import is_ipaddr diff --git a/libs/apprise/plugins/NotifyLine.py b/libs/apprise/plugins/line.py similarity index 98% rename from libs/apprise/plugins/NotifyLine.py rename to libs/apprise/plugins/line.py index 61e4f3703..07a01e769 100644 --- a/libs/apprise/plugins/NotifyLine.py +++ b/libs/apprise/plugins/line.py @@ -33,14 +33,14 @@ import requests import re from json import dumps -from .NotifyBase import NotifyBase -from ..URLBase import PrivacyMode +from .base import NotifyBase +from ..url import PrivacyMode from ..common import NotifyType from ..common import NotifyImageSize from ..utils import validate_regex from ..utils import parse_list from ..utils import parse_bool -from ..AppriseLocale import gettext_lazy as _ +from ..locale import gettext_lazy as _ # Used to break path apart into list of streams diff --git a/libs/apprise/plugins/NotifyLunaSea.py b/libs/apprise/plugins/lunasea.py similarity index 99% rename from libs/apprise/plugins/NotifyLunaSea.py rename to libs/apprise/plugins/lunasea.py index 51d820915..2af519179 100644 --- a/libs/apprise/plugins/NotifyLunaSea.py +++ b/libs/apprise/plugins/lunasea.py @@ -33,15 +33,15 @@ import re import requests from json import dumps -from .NotifyBase import NotifyBase +from .base import NotifyBase from ..common import NotifyType from ..common import NotifyImageSize from ..utils import parse_list from ..utils import is_hostname from ..utils import is_ipaddr from ..utils import parse_bool -from ..AppriseLocale import gettext_lazy as _ -from ..URLBase import PrivacyMode +from ..locale import gettext_lazy as _ +from ..url import PrivacyMode class LunaSeaMode: diff --git a/libs/apprise/plugins/NotifyMacOSX.py b/libs/apprise/plugins/macosx.py similarity index 99% rename from libs/apprise/plugins/NotifyMacOSX.py rename to libs/apprise/plugins/macosx.py index dd53369fe..31b7101bd 100644 --- a/libs/apprise/plugins/NotifyMacOSX.py +++ b/libs/apprise/plugins/macosx.py @@ -30,11 +30,11 @@ import platform import subprocess import os -from .NotifyBase import NotifyBase +from .base import NotifyBase from ..common import NotifyImageSize from ..common import NotifyType from ..utils import parse_bool -from ..AppriseLocale import gettext_lazy as _ +from ..locale import gettext_lazy as _ # Default our global support flag NOTIFY_MACOSX_SUPPORT_ENABLED = False diff --git a/libs/apprise/plugins/NotifyMailgun.py b/libs/apprise/plugins/mailgun.py similarity index 99% rename from libs/apprise/plugins/NotifyMailgun.py rename to libs/apprise/plugins/mailgun.py index 82cf970bf..69ab72dda 100644 --- a/libs/apprise/plugins/NotifyMailgun.py +++ b/libs/apprise/plugins/mailgun.py @@ -56,7 +56,7 @@ # import requests from email.utils import formataddr -from .NotifyBase import NotifyBase +from .base import NotifyBase from ..common import NotifyType from ..common import NotifyFormat from ..utils import parse_emails @@ -64,7 +64,7 @@ from ..utils import parse_bool from ..utils import is_email from ..utils import validate_regex from ..logger import logger -from ..AppriseLocale import gettext_lazy as _ +from ..locale import gettext_lazy as _ # Provide some known codes Mailgun uses and what they translate to: # Based on https://documentation.mailgun.com/en/latest/api-intro.html#errors diff --git a/libs/apprise/plugins/NotifyMastodon.py b/libs/apprise/plugins/mastodon.py similarity index 99% rename from libs/apprise/plugins/NotifyMastodon.py rename to libs/apprise/plugins/mastodon.py index 0d2f27df3..b6e451ad1 100644 --- a/libs/apprise/plugins/NotifyMastodon.py +++ b/libs/apprise/plugins/mastodon.py @@ -33,16 +33,16 @@ from json import dumps, loads from datetime import datetime from datetime import timezone -from .NotifyBase import NotifyBase -from ..URLBase import PrivacyMode +from .base import NotifyBase +from ..url import PrivacyMode from ..common import NotifyImageSize from ..common import NotifyFormat from ..common import NotifyType from ..utils import parse_list from ..utils import parse_bool from ..utils import validate_regex -from ..AppriseLocale import gettext_lazy as _ -from ..attachment.AttachBase import AttachBase +from ..locale import gettext_lazy as _ +from ..attachment.base import AttachBase # Accept: # - @username diff --git a/libs/apprise/plugins/NotifyMatrix.py b/libs/apprise/plugins/matrix.py similarity index 99% rename from libs/apprise/plugins/NotifyMatrix.py rename to libs/apprise/plugins/matrix.py index 594274761..c1401f238 100644 --- a/libs/apprise/plugins/NotifyMatrix.py +++ b/libs/apprise/plugins/matrix.py @@ -37,8 +37,8 @@ from json import dumps from json import loads from time import time -from .NotifyBase import NotifyBase -from ..URLBase import PrivacyMode +from .base import NotifyBase +from ..url import PrivacyMode from ..common import NotifyType from ..common import NotifyImageSize from ..common import NotifyFormat @@ -46,7 +46,7 @@ from ..utils import parse_bool from ..utils import parse_list from ..utils import is_hostname from ..utils import validate_regex -from ..AppriseLocale import gettext_lazy as _ +from ..locale import gettext_lazy as _ # Define default path MATRIX_V1_WEBHOOK_PATH = '/api/v1/matrix/hook' diff --git a/libs/apprise/plugins/NotifyMattermost.py b/libs/apprise/plugins/mattermost.py similarity index 99% rename from libs/apprise/plugins/NotifyMattermost.py rename to libs/apprise/plugins/mattermost.py index dbb5f0dd3..481a9b852 100644 --- a/libs/apprise/plugins/NotifyMattermost.py +++ b/libs/apprise/plugins/mattermost.py @@ -39,13 +39,13 @@ import requests from json import dumps -from .NotifyBase import NotifyBase +from .base import NotifyBase from ..common import NotifyImageSize from ..common import NotifyType from ..utils import parse_bool from ..utils import parse_list from ..utils import validate_regex -from ..AppriseLocale import gettext_lazy as _ +from ..locale import gettext_lazy as _ # Some Reference Locations: # - https://docs.mattermost.com/developer/webhooks-incoming.html diff --git a/libs/apprise/plugins/NotifyMessageBird.py b/libs/apprise/plugins/messagebird.py similarity index 99% rename from libs/apprise/plugins/NotifyMessageBird.py rename to libs/apprise/plugins/messagebird.py index 42d880acd..c496d347e 100644 --- a/libs/apprise/plugins/NotifyMessageBird.py +++ b/libs/apprise/plugins/messagebird.py @@ -34,12 +34,12 @@ import requests -from .NotifyBase import NotifyBase +from .base import NotifyBase from ..common import NotifyType from ..utils import is_phone_no from ..utils import parse_phone_no from ..utils import validate_regex -from ..AppriseLocale import gettext_lazy as _ +from ..locale import gettext_lazy as _ class NotifyMessageBird(NotifyBase): diff --git a/libs/apprise/plugins/NotifyMisskey.py b/libs/apprise/plugins/misskey.py similarity index 99% rename from libs/apprise/plugins/NotifyMisskey.py rename to libs/apprise/plugins/misskey.py index 8965a0f7b..73b8f7c6e 100644 --- a/libs/apprise/plugins/NotifyMisskey.py +++ b/libs/apprise/plugins/misskey.py @@ -47,10 +47,10 @@ import requests from json import dumps -from .NotifyBase import NotifyBase +from .base import NotifyBase from ..common import NotifyType from ..utils import validate_regex -from ..AppriseLocale import gettext_lazy as _ +from ..locale import gettext_lazy as _ class MisskeyVisibility: diff --git a/libs/apprise/plugins/NotifyMQTT.py b/libs/apprise/plugins/mqtt.py similarity index 99% rename from libs/apprise/plugins/NotifyMQTT.py rename to libs/apprise/plugins/mqtt.py index 49380d330..1e09cd147 100644 --- a/libs/apprise/plugins/NotifyMQTT.py +++ b/libs/apprise/plugins/mqtt.py @@ -38,12 +38,12 @@ import re from time import sleep from datetime import datetime from os.path import isfile -from .NotifyBase import NotifyBase -from ..URLBase import PrivacyMode +from .base import NotifyBase +from ..url import PrivacyMode from ..common import NotifyType from ..utils import parse_list from ..utils import parse_bool -from ..AppriseLocale import gettext_lazy as _ +from ..locale import gettext_lazy as _ # Default our global support flag NOTIFY_MQTT_SUPPORT_ENABLED = False diff --git a/libs/apprise/plugins/NotifyMSG91.py b/libs/apprise/plugins/msg91.py similarity index 99% rename from libs/apprise/plugins/NotifyMSG91.py rename to libs/apprise/plugins/msg91.py index a7bd9c473..28a5bf183 100644 --- a/libs/apprise/plugins/NotifyMSG91.py +++ b/libs/apprise/plugins/msg91.py @@ -38,12 +38,12 @@ import re import requests from json import dumps -from .NotifyBase import NotifyBase +from .base import NotifyBase from ..common import NotifyType from ..utils import is_phone_no from ..utils import parse_phone_no, parse_bool from ..utils import validate_regex -from ..AppriseLocale import gettext_lazy as _ +from ..locale import gettext_lazy as _ class MSG91PayloadField: diff --git a/libs/apprise/plugins/NotifyMSTeams.py b/libs/apprise/plugins/msteams.py similarity index 99% rename from libs/apprise/plugins/NotifyMSTeams.py rename to libs/apprise/plugins/msteams.py index 06572c3e6..2e0957f32 100644 --- a/libs/apprise/plugins/NotifyMSTeams.py +++ b/libs/apprise/plugins/msteams.py @@ -81,7 +81,7 @@ import requests import json from json.decoder import JSONDecodeError -from .NotifyBase import NotifyBase +from .base import NotifyBase from ..common import NotifyImageSize from ..common import NotifyType from ..common import NotifyFormat @@ -89,8 +89,8 @@ from ..utils import parse_bool from ..utils import validate_regex from ..utils import apply_template from ..utils import TemplateType -from ..AppriseAttachment import AppriseAttachment -from ..AppriseLocale import gettext_lazy as _ +from ..apprise_attachment import AppriseAttachment +from ..locale import gettext_lazy as _ class NotifyMSTeams(NotifyBase): diff --git a/libs/apprise/plugins/NotifyNextcloud.py b/libs/apprise/plugins/nextcloud.py similarity index 99% rename from libs/apprise/plugins/NotifyNextcloud.py rename to libs/apprise/plugins/nextcloud.py index fd471d9eb..9acfc43d5 100644 --- a/libs/apprise/plugins/NotifyNextcloud.py +++ b/libs/apprise/plugins/nextcloud.py @@ -28,11 +28,11 @@ import requests -from .NotifyBase import NotifyBase -from ..URLBase import PrivacyMode +from .base import NotifyBase +from ..url import PrivacyMode from ..common import NotifyType from ..utils import parse_list -from ..AppriseLocale import gettext_lazy as _ +from ..locale import gettext_lazy as _ class NotifyNextcloud(NotifyBase): diff --git a/libs/apprise/plugins/NotifyNextcloudTalk.py b/libs/apprise/plugins/nextcloudtalk.py similarity index 98% rename from libs/apprise/plugins/NotifyNextcloudTalk.py rename to libs/apprise/plugins/nextcloudtalk.py index 4bfced282..b1b014770 100644 --- a/libs/apprise/plugins/NotifyNextcloudTalk.py +++ b/libs/apprise/plugins/nextcloudtalk.py @@ -29,11 +29,11 @@ import requests from json import dumps -from .NotifyBase import NotifyBase -from ..URLBase import PrivacyMode +from .base import NotifyBase +from ..url import PrivacyMode from ..common import NotifyType from ..utils import parse_list -from ..AppriseLocale import gettext_lazy as _ +from ..locale import gettext_lazy as _ class NotifyNextcloudTalk(NotifyBase): diff --git a/libs/apprise/plugins/NotifyNotica.py b/libs/apprise/plugins/notica.py similarity index 99% rename from libs/apprise/plugins/NotifyNotica.py rename to libs/apprise/plugins/notica.py index 33a94fc96..661fde1d1 100644 --- a/libs/apprise/plugins/NotifyNotica.py +++ b/libs/apprise/plugins/notica.py @@ -43,11 +43,11 @@ import re import requests -from .NotifyBase import NotifyBase -from ..URLBase import PrivacyMode +from .base import NotifyBase +from ..url import PrivacyMode from ..common import NotifyType from ..utils import validate_regex -from ..AppriseLocale import gettext_lazy as _ +from ..locale import gettext_lazy as _ class NoticaMode: diff --git a/libs/apprise/plugins/NotifyNotifiarr.py b/libs/apprise/plugins/notifiarr.py similarity index 99% rename from libs/apprise/plugins/NotifyNotifiarr.py rename to libs/apprise/plugins/notifiarr.py index e195cbd32..cc13e1a56 100644 --- a/libs/apprise/plugins/NotifyNotifiarr.py +++ b/libs/apprise/plugins/notifiarr.py @@ -31,9 +31,9 @@ import requests from json import dumps from itertools import chain -from .NotifyBase import NotifyBase +from .base import NotifyBase from ..common import NotifyType -from ..AppriseLocale import gettext_lazy as _ +from ..locale import gettext_lazy as _ from ..common import NotifyImageSize from ..utils import parse_list, parse_bool from ..utils import validate_regex diff --git a/libs/apprise/plugins/NotifyNotifico.py b/libs/apprise/plugins/notifico.py similarity index 99% rename from libs/apprise/plugins/NotifyNotifico.py rename to libs/apprise/plugins/notifico.py index 27ce29a6e..5cb0d666e 100644 --- a/libs/apprise/plugins/NotifyNotifico.py +++ b/libs/apprise/plugins/notifico.py @@ -44,11 +44,11 @@ import re import requests -from .NotifyBase import NotifyBase +from .base import NotifyBase from ..common import NotifyType from ..utils import parse_bool from ..utils import validate_regex -from ..AppriseLocale import gettext_lazy as _ +from ..locale import gettext_lazy as _ class NotificoFormat: diff --git a/libs/apprise/plugins/NotifyNtfy.py b/libs/apprise/plugins/ntfy.py similarity index 99% rename from libs/apprise/plugins/NotifyNtfy.py rename to libs/apprise/plugins/ntfy.py index 40834eece..805b87260 100644 --- a/libs/apprise/plugins/NotifyNtfy.py +++ b/libs/apprise/plugins/ntfy.py @@ -41,18 +41,18 @@ from json import loads from json import dumps from os.path import basename -from .NotifyBase import NotifyBase +from .base import NotifyBase from ..common import NotifyFormat from ..common import NotifyType from ..common import NotifyImageSize -from ..AppriseLocale import gettext_lazy as _ +from ..locale import gettext_lazy as _ from ..utils import parse_list from ..utils import parse_bool from ..utils import is_hostname from ..utils import is_ipaddr from ..utils import validate_regex -from ..URLBase import PrivacyMode -from ..attachment.AttachBase import AttachBase +from ..url import PrivacyMode +from ..attachment.base import AttachBase class NtfyMode: diff --git a/libs/apprise/plugins/NotifyOffice365.py b/libs/apprise/plugins/office365.py similarity index 99% rename from libs/apprise/plugins/NotifyOffice365.py rename to libs/apprise/plugins/office365.py index 0c62279f9..b04f7a037 100644 --- a/libs/apprise/plugins/NotifyOffice365.py +++ b/libs/apprise/plugins/office365.py @@ -64,14 +64,14 @@ from datetime import datetime from datetime import timedelta from json import loads from json import dumps -from .NotifyBase import NotifyBase -from ..URLBase import PrivacyMode +from .base import NotifyBase +from ..url import PrivacyMode from ..common import NotifyFormat from ..common import NotifyType from ..utils import is_email from ..utils import parse_emails from ..utils import validate_regex -from ..AppriseLocale import gettext_lazy as _ +from ..locale import gettext_lazy as _ class NotifyOffice365(NotifyBase): diff --git a/libs/apprise/plugins/NotifyOneSignal.py b/libs/apprise/plugins/one_signal.py similarity index 99% rename from libs/apprise/plugins/NotifyOneSignal.py rename to libs/apprise/plugins/one_signal.py index eb1e10f7a..76ec212f4 100644 --- a/libs/apprise/plugins/NotifyOneSignal.py +++ b/libs/apprise/plugins/one_signal.py @@ -37,14 +37,14 @@ import requests from json import dumps from itertools import chain -from .NotifyBase import NotifyBase +from .base import NotifyBase from ..common import NotifyType from ..common import NotifyImageSize from ..utils import validate_regex from ..utils import parse_list from ..utils import parse_bool from ..utils import is_email -from ..AppriseLocale import gettext_lazy as _ +from ..locale import gettext_lazy as _ class OneSignalCategory: diff --git a/libs/apprise/plugins/NotifyOpsgenie.py b/libs/apprise/plugins/opsgenie.py similarity index 99% rename from libs/apprise/plugins/NotifyOpsgenie.py rename to libs/apprise/plugins/opsgenie.py index c2dfed232..5327ec803 100644 --- a/libs/apprise/plugins/NotifyOpsgenie.py +++ b/libs/apprise/plugins/opsgenie.py @@ -49,13 +49,13 @@ import requests from json import dumps -from .NotifyBase import NotifyBase +from .base import NotifyBase from ..common import NotifyType from ..utils import validate_regex from ..utils import is_uuid from ..utils import parse_list from ..utils import parse_bool -from ..AppriseLocale import gettext_lazy as _ +from ..locale import gettext_lazy as _ class OpsgenieCategory(NotifyBase): diff --git a/libs/apprise/plugins/NotifyPagerDuty.py b/libs/apprise/plugins/pagerduty.py similarity index 99% rename from libs/apprise/plugins/NotifyPagerDuty.py rename to libs/apprise/plugins/pagerduty.py index 0896b41b1..c9d555527 100644 --- a/libs/apprise/plugins/NotifyPagerDuty.py +++ b/libs/apprise/plugins/pagerduty.py @@ -34,13 +34,13 @@ import requests from json import dumps -from .NotifyBase import NotifyBase -from ..URLBase import PrivacyMode +from .base import NotifyBase +from ..url import PrivacyMode from ..common import NotifyType from ..common import NotifyImageSize from ..utils import validate_regex from ..utils import parse_bool -from ..AppriseLocale import gettext_lazy as _ +from ..locale import gettext_lazy as _ class PagerDutySeverity: diff --git a/libs/apprise/plugins/NotifyPagerTree.py b/libs/apprise/plugins/pagertree.py similarity index 99% rename from libs/apprise/plugins/NotifyPagerTree.py rename to libs/apprise/plugins/pagertree.py index c9290f2f7..8a041a358 100644 --- a/libs/apprise/plugins/NotifyPagerTree.py +++ b/libs/apprise/plugins/pagertree.py @@ -31,11 +31,11 @@ from json import dumps from uuid import uuid4 -from .NotifyBase import NotifyBase +from .base import NotifyBase from ..common import NotifyType from ..utils import parse_list from ..utils import validate_regex -from ..AppriseLocale import gettext_lazy as _ +from ..locale import gettext_lazy as _ # Actions diff --git a/libs/apprise/plugins/NotifyParsePlatform.py b/libs/apprise/plugins/parseplatform.py similarity index 99% rename from libs/apprise/plugins/NotifyParsePlatform.py rename to libs/apprise/plugins/parseplatform.py index 2a182ed31..cd59d0575 100644 --- a/libs/apprise/plugins/NotifyParsePlatform.py +++ b/libs/apprise/plugins/parseplatform.py @@ -30,10 +30,10 @@ import re import requests from json import dumps -from .NotifyBase import NotifyBase +from .base import NotifyBase from ..common import NotifyType from ..utils import validate_regex -from ..AppriseLocale import gettext_lazy as _ +from ..locale import gettext_lazy as _ # Used to break path apart into list of targets TARGET_LIST_DELIM = re.compile(r'[ \t\r\n,\\/]+') diff --git a/libs/apprise/plugins/NotifyPopcornNotify.py b/libs/apprise/plugins/popcorn_notify.py similarity index 99% rename from libs/apprise/plugins/NotifyPopcornNotify.py rename to libs/apprise/plugins/popcorn_notify.py index 0ecd8af68..388aa2199 100644 --- a/libs/apprise/plugins/NotifyPopcornNotify.py +++ b/libs/apprise/plugins/popcorn_notify.py @@ -28,14 +28,14 @@ import requests -from .NotifyBase import NotifyBase +from .base import NotifyBase from ..common import NotifyType from ..utils import is_email from ..utils import is_phone_no from ..utils import parse_list from ..utils import parse_bool from ..utils import validate_regex -from ..AppriseLocale import gettext_lazy as _ +from ..locale import gettext_lazy as _ class NotifyPopcornNotify(NotifyBase): diff --git a/libs/apprise/plugins/NotifyProwl.py b/libs/apprise/plugins/prowl.py similarity index 99% rename from libs/apprise/plugins/NotifyProwl.py rename to libs/apprise/plugins/prowl.py index e5c07bf4e..c174615c0 100644 --- a/libs/apprise/plugins/NotifyProwl.py +++ b/libs/apprise/plugins/prowl.py @@ -28,10 +28,10 @@ import requests -from .NotifyBase import NotifyBase +from .base import NotifyBase from ..common import NotifyType from ..utils import validate_regex -from ..AppriseLocale import gettext_lazy as _ +from ..locale import gettext_lazy as _ # Priorities diff --git a/libs/apprise/plugins/NotifyPushBullet.py b/libs/apprise/plugins/pushbullet.py similarity index 99% rename from libs/apprise/plugins/NotifyPushBullet.py rename to libs/apprise/plugins/pushbullet.py index 5e9c43fbf..8e006db1d 100644 --- a/libs/apprise/plugins/NotifyPushBullet.py +++ b/libs/apprise/plugins/pushbullet.py @@ -30,13 +30,13 @@ import requests from json import dumps from json import loads -from .NotifyBase import NotifyBase +from .base import NotifyBase from ..utils import is_email from ..common import NotifyType from ..utils import parse_list from ..utils import validate_regex -from ..AppriseLocale import gettext_lazy as _ -from ..attachment.AttachBase import AttachBase +from ..locale import gettext_lazy as _ +from ..attachment.base import AttachBase # Flag used as a placeholder to sending to all devices PUSHBULLET_SEND_TO_ALL = 'ALL_DEVICES' diff --git a/libs/apprise/plugins/NotifyPushDeer.py b/libs/apprise/plugins/pushdeer.py similarity index 98% rename from libs/apprise/plugins/NotifyPushDeer.py rename to libs/apprise/plugins/pushdeer.py index 6766dc7ff..fa888b159 100644 --- a/libs/apprise/plugins/NotifyPushDeer.py +++ b/libs/apprise/plugins/pushdeer.py @@ -29,9 +29,9 @@ import requests from ..common import NotifyType -from .NotifyBase import NotifyBase +from .base import NotifyBase from ..utils import validate_regex -from ..AppriseLocale import gettext_lazy as _ +from ..locale import gettext_lazy as _ # Syntax: # schan://{key}/ diff --git a/libs/apprise/plugins/NotifyPushed.py b/libs/apprise/plugins/pushed.py similarity index 99% rename from libs/apprise/plugins/NotifyPushed.py rename to libs/apprise/plugins/pushed.py index a50970f99..1ed83b9e4 100644 --- a/libs/apprise/plugins/NotifyPushed.py +++ b/libs/apprise/plugins/pushed.py @@ -31,12 +31,12 @@ import requests from json import dumps from itertools import chain -from .NotifyBase import NotifyBase -from ..URLBase import PrivacyMode +from .base import NotifyBase +from ..url import PrivacyMode from ..common import NotifyType from ..utils import parse_list from ..utils import validate_regex -from ..AppriseLocale import gettext_lazy as _ +from ..locale import gettext_lazy as _ # Used to detect and parse channels IS_CHANNEL = re.compile(r'^#?(?P[A-Za-z0-9]+)$') diff --git a/libs/apprise/plugins/NotifyPushjet.py b/libs/apprise/plugins/pushjet.py similarity index 98% rename from libs/apprise/plugins/NotifyPushjet.py rename to libs/apprise/plugins/pushjet.py index 253ac6818..f8dcfdf31 100644 --- a/libs/apprise/plugins/NotifyPushjet.py +++ b/libs/apprise/plugins/pushjet.py @@ -29,11 +29,11 @@ import requests from json import dumps -from .NotifyBase import NotifyBase -from ..URLBase import PrivacyMode +from .base import NotifyBase +from ..url import PrivacyMode from ..common import NotifyType from ..utils import validate_regex -from ..AppriseLocale import gettext_lazy as _ +from ..locale import gettext_lazy as _ class NotifyPushjet(NotifyBase): diff --git a/libs/apprise/plugins/NotifyPushMe.py b/libs/apprise/plugins/pushme.py similarity index 98% rename from libs/apprise/plugins/NotifyPushMe.py rename to libs/apprise/plugins/pushme.py index 30889f868..abbed7944 100644 --- a/libs/apprise/plugins/NotifyPushMe.py +++ b/libs/apprise/plugins/pushme.py @@ -28,12 +28,12 @@ import requests -from .NotifyBase import NotifyBase +from .base import NotifyBase from ..common import NotifyType from ..common import NotifyFormat from ..utils import validate_regex from ..utils import parse_bool -from ..AppriseLocale import gettext_lazy as _ +from ..locale import gettext_lazy as _ class NotifyPushMe(NotifyBase): diff --git a/libs/apprise/plugins/NotifyPushover.py b/libs/apprise/plugins/pushover.py similarity index 99% rename from libs/apprise/plugins/NotifyPushover.py rename to libs/apprise/plugins/pushover.py index be6ada289..954e7dd0f 100644 --- a/libs/apprise/plugins/NotifyPushover.py +++ b/libs/apprise/plugins/pushover.py @@ -30,14 +30,14 @@ import re import requests from itertools import chain -from .NotifyBase import NotifyBase +from .base import NotifyBase from ..common import NotifyType from ..common import NotifyFormat from ..conversion import convert_between from ..utils import parse_list from ..utils import validate_regex -from ..AppriseLocale import gettext_lazy as _ -from ..attachment.AttachBase import AttachBase +from ..locale import gettext_lazy as _ +from ..attachment.base import AttachBase # Flag used as a placeholder to sending to all devices PUSHOVER_SEND_TO_ALL = 'ALL_DEVICES' diff --git a/libs/apprise/plugins/NotifyPushSafer.py b/libs/apprise/plugins/pushsafer.py similarity index 99% rename from libs/apprise/plugins/NotifyPushSafer.py rename to libs/apprise/plugins/pushsafer.py index 32cfa82fe..7bdca7a69 100644 --- a/libs/apprise/plugins/NotifyPushSafer.py +++ b/libs/apprise/plugins/pushsafer.py @@ -30,11 +30,11 @@ import base64 import requests from json import loads -from .NotifyBase import NotifyBase +from .base import NotifyBase from ..common import NotifyType from ..utils import parse_list from ..utils import validate_regex -from ..AppriseLocale import gettext_lazy as _ +from ..locale import gettext_lazy as _ class PushSaferSound: diff --git a/libs/apprise/plugins/NotifyPushy.py b/libs/apprise/plugins/pushy.py similarity index 99% rename from libs/apprise/plugins/NotifyPushy.py rename to libs/apprise/plugins/pushy.py index 097017dac..bb2a24ecd 100644 --- a/libs/apprise/plugins/NotifyPushy.py +++ b/libs/apprise/plugins/pushy.py @@ -32,11 +32,11 @@ import requests from itertools import chain from json import dumps, loads -from .NotifyBase import NotifyBase +from .base import NotifyBase from ..common import NotifyType from ..utils import parse_list from ..utils import validate_regex -from ..AppriseLocale import gettext_lazy as _ +from ..locale import gettext_lazy as _ # Used to detect a Device and Topic VALIDATE_DEVICE = re.compile(r'^@(?P[a-z0-9]+)$', re.I) diff --git a/libs/apprise/plugins/NotifyReddit.py b/libs/apprise/plugins/reddit.py similarity index 99% rename from libs/apprise/plugins/NotifyReddit.py rename to libs/apprise/plugins/reddit.py index 022a0a50d..3a60b5e03 100644 --- a/libs/apprise/plugins/NotifyReddit.py +++ b/libs/apprise/plugins/reddit.py @@ -53,14 +53,14 @@ from datetime import timedelta from datetime import datetime from datetime import timezone -from .NotifyBase import NotifyBase -from ..URLBase import PrivacyMode +from .base import NotifyBase +from ..url import PrivacyMode from ..common import NotifyFormat from ..common import NotifyType from ..utils import parse_list from ..utils import parse_bool from ..utils import validate_regex -from ..AppriseLocale import gettext_lazy as _ +from ..locale import gettext_lazy as _ from .. import __title__, __version__ # Extend HTTP Error Messages diff --git a/libs/apprise/plugins/NotifyRevolt.py b/libs/apprise/plugins/revolt.py similarity index 99% rename from libs/apprise/plugins/NotifyRevolt.py rename to libs/apprise/plugins/revolt.py index ae0a43b10..1f518540b 100644 --- a/libs/apprise/plugins/NotifyRevolt.py +++ b/libs/apprise/plugins/revolt.py @@ -42,13 +42,13 @@ from datetime import timedelta from datetime import datetime from datetime import timezone -from .NotifyBase import NotifyBase +from .base import NotifyBase from ..common import NotifyImageSize from ..common import NotifyFormat from ..common import NotifyType from ..utils import validate_regex from ..utils import parse_list -from ..AppriseLocale import gettext_lazy as _ +from ..locale import gettext_lazy as _ class NotifyRevolt(NotifyBase): diff --git a/libs/apprise/plugins/NotifyRocketChat.py b/libs/apprise/plugins/rocketchat.py similarity index 99% rename from libs/apprise/plugins/NotifyRocketChat.py rename to libs/apprise/plugins/rocketchat.py index 9011a5e71..973651e30 100644 --- a/libs/apprise/plugins/NotifyRocketChat.py +++ b/libs/apprise/plugins/rocketchat.py @@ -32,14 +32,14 @@ from json import loads from json import dumps from itertools import chain -from .NotifyBase import NotifyBase -from ..URLBase import PrivacyMode +from .base import NotifyBase +from ..url import PrivacyMode from ..common import NotifyImageSize from ..common import NotifyFormat from ..common import NotifyType from ..utils import parse_list from ..utils import parse_bool -from ..AppriseLocale import gettext_lazy as _ +from ..locale import gettext_lazy as _ IS_CHANNEL = re.compile(r'^#(?P[A-Za-z0-9_-]+)$') IS_USER = re.compile(r'^@(?P[A-Za-z0-9._-]+)$') diff --git a/libs/apprise/plugins/NotifyRSyslog.py b/libs/apprise/plugins/rsyslog.py similarity index 99% rename from libs/apprise/plugins/NotifyRSyslog.py rename to libs/apprise/plugins/rsyslog.py index e39744627..9631c72fd 100644 --- a/libs/apprise/plugins/NotifyRSyslog.py +++ b/libs/apprise/plugins/rsyslog.py @@ -29,10 +29,10 @@ import os import socket -from .NotifyBase import NotifyBase +from .base import NotifyBase from ..common import NotifyType from ..utils import parse_bool -from ..AppriseLocale import gettext_lazy as _ +from ..locale import gettext_lazy as _ class syslog: diff --git a/libs/apprise/plugins/NotifyRyver.py b/libs/apprise/plugins/ryver.py similarity index 99% rename from libs/apprise/plugins/NotifyRyver.py rename to libs/apprise/plugins/ryver.py index 0872f3e52..114dc6a0c 100644 --- a/libs/apprise/plugins/NotifyRyver.py +++ b/libs/apprise/plugins/ryver.py @@ -38,12 +38,12 @@ import re import requests from json import dumps -from .NotifyBase import NotifyBase +from .base import NotifyBase from ..common import NotifyImageSize from ..common import NotifyType from ..utils import parse_bool from ..utils import validate_regex -from ..AppriseLocale import gettext_lazy as _ +from ..locale import gettext_lazy as _ class RyverWebhookMode: diff --git a/libs/apprise/plugins/NotifySendGrid.py b/libs/apprise/plugins/sendgrid.py similarity index 99% rename from libs/apprise/plugins/NotifySendGrid.py rename to libs/apprise/plugins/sendgrid.py index b82e3e60d..d50839f17 100644 --- a/libs/apprise/plugins/NotifySendGrid.py +++ b/libs/apprise/plugins/sendgrid.py @@ -49,13 +49,13 @@ import requests from json import dumps -from .NotifyBase import NotifyBase +from .base import NotifyBase from ..common import NotifyFormat from ..common import NotifyType from ..utils import parse_list from ..utils import is_email from ..utils import validate_regex -from ..AppriseLocale import gettext_lazy as _ +from ..locale import gettext_lazy as _ # Extend HTTP Error Messages SENDGRID_HTTP_ERROR_MAP = { diff --git a/libs/apprise/plugins/NotifyServerChan.py b/libs/apprise/plugins/serverchan.py similarity index 98% rename from libs/apprise/plugins/NotifyServerChan.py rename to libs/apprise/plugins/serverchan.py index cf250cf5b..e3abaa354 100644 --- a/libs/apprise/plugins/NotifyServerChan.py +++ b/libs/apprise/plugins/serverchan.py @@ -30,9 +30,9 @@ import re import requests from ..common import NotifyType -from .NotifyBase import NotifyBase +from .base import NotifyBase from ..utils import validate_regex -from ..AppriseLocale import gettext_lazy as _ +from ..locale import gettext_lazy as _ # Register at https://sct.ftqq.com/ diff --git a/libs/apprise/plugins/NotifySES.py b/libs/apprise/plugins/ses.py similarity index 99% rename from libs/apprise/plugins/NotifySES.py rename to libs/apprise/plugins/ses.py index b580b14d6..5a2c047a7 100644 --- a/libs/apprise/plugins/NotifySES.py +++ b/libs/apprise/plugins/ses.py @@ -95,13 +95,13 @@ from email.utils import formataddr from email.header import Header from urllib.parse import quote -from .NotifyBase import NotifyBase -from ..URLBase import PrivacyMode +from .base import NotifyBase +from ..url import PrivacyMode from ..common import NotifyFormat from ..common import NotifyType from ..utils import parse_emails from ..utils import validate_regex -from ..AppriseLocale import gettext_lazy as _ +from ..locale import gettext_lazy as _ from ..utils import is_email # Our Regin Identifier diff --git a/libs/apprise/plugins/NotifySignalAPI.py b/libs/apprise/plugins/signal_api.py similarity index 99% rename from libs/apprise/plugins/NotifySignalAPI.py rename to libs/apprise/plugins/signal_api.py index b35b4989e..7e557133c 100644 --- a/libs/apprise/plugins/NotifySignalAPI.py +++ b/libs/apprise/plugins/signal_api.py @@ -31,13 +31,13 @@ import requests from json import dumps import base64 -from .NotifyBase import NotifyBase +from .base import NotifyBase from ..common import NotifyType from ..utils import is_phone_no from ..utils import parse_phone_no from ..utils import parse_bool -from ..URLBase import PrivacyMode -from ..AppriseLocale import gettext_lazy as _ +from ..url import PrivacyMode +from ..locale import gettext_lazy as _ GROUP_REGEX = re.compile( diff --git a/libs/apprise/plugins/NotifySimplePush.py b/libs/apprise/plugins/simplepush.py similarity index 98% rename from libs/apprise/plugins/NotifySimplePush.py rename to libs/apprise/plugins/simplepush.py index 3851e1e3c..10b01b0f8 100644 --- a/libs/apprise/plugins/NotifySimplePush.py +++ b/libs/apprise/plugins/simplepush.py @@ -30,11 +30,11 @@ from os import urandom from json import loads import requests -from .NotifyBase import NotifyBase -from ..URLBase import PrivacyMode +from .base import NotifyBase +from ..url import PrivacyMode from ..common import NotifyType from ..utils import validate_regex -from ..AppriseLocale import gettext_lazy as _ +from ..locale import gettext_lazy as _ from base64 import urlsafe_b64encode import hashlib diff --git a/libs/apprise/plugins/NotifySinch.py b/libs/apprise/plugins/sinch.py similarity index 99% rename from libs/apprise/plugins/NotifySinch.py rename to libs/apprise/plugins/sinch.py index 74b3c452a..06bd5b1e7 100644 --- a/libs/apprise/plugins/NotifySinch.py +++ b/libs/apprise/plugins/sinch.py @@ -39,13 +39,13 @@ import requests import json -from .NotifyBase import NotifyBase -from ..URLBase import PrivacyMode +from .base import NotifyBase +from ..url import PrivacyMode from ..common import NotifyType from ..utils import is_phone_no from ..utils import parse_phone_no from ..utils import validate_regex -from ..AppriseLocale import gettext_lazy as _ +from ..locale import gettext_lazy as _ class SinchRegion: diff --git a/libs/apprise/plugins/NotifySlack.py b/libs/apprise/plugins/slack.py similarity index 99% rename from libs/apprise/plugins/NotifySlack.py rename to libs/apprise/plugins/slack.py index b66fe99f4..b929dfb46 100644 --- a/libs/apprise/plugins/NotifySlack.py +++ b/libs/apprise/plugins/slack.py @@ -78,7 +78,7 @@ from json import dumps from json import loads from time import time -from .NotifyBase import NotifyBase +from .base import NotifyBase from ..common import NotifyImageSize from ..common import NotifyType from ..common import NotifyFormat @@ -86,7 +86,7 @@ from ..utils import is_email from ..utils import parse_bool from ..utils import parse_list from ..utils import validate_regex -from ..AppriseLocale import gettext_lazy as _ +from ..locale import gettext_lazy as _ # Extend HTTP Error Messages SLACK_HTTP_ERROR_MAP = { diff --git a/libs/apprise/plugins/NotifySMSEagle.py b/libs/apprise/plugins/smseagle.py similarity index 99% rename from libs/apprise/plugins/NotifySMSEagle.py rename to libs/apprise/plugins/smseagle.py index 33b4af752..8eddca588 100644 --- a/libs/apprise/plugins/NotifySMSEagle.py +++ b/libs/apprise/plugins/smseagle.py @@ -32,14 +32,14 @@ from json import dumps, loads import base64 from itertools import chain -from .NotifyBase import NotifyBase +from .base import NotifyBase from ..common import NotifyType from ..utils import validate_regex from ..utils import is_phone_no from ..utils import parse_phone_no from ..utils import parse_bool -from ..URLBase import PrivacyMode -from ..AppriseLocale import gettext_lazy as _ +from ..url import PrivacyMode +from ..locale import gettext_lazy as _ GROUP_REGEX = re.compile( diff --git a/libs/apprise/plugins/NotifySMSManager.py b/libs/apprise/plugins/smsmanager.py similarity index 99% rename from libs/apprise/plugins/NotifySMSManager.py rename to libs/apprise/plugins/smsmanager.py index efc158b62..1d352daf2 100644 --- a/libs/apprise/plugins/NotifySMSManager.py +++ b/libs/apprise/plugins/smsmanager.py @@ -35,13 +35,13 @@ # 2. Generate an API key in web administration. import requests -from .NotifyBase import NotifyBase +from .base import NotifyBase from ..common import NotifyType from ..utils import is_phone_no from ..utils import parse_phone_no from ..utils import parse_bool from ..utils import validate_regex -from ..AppriseLocale import gettext_lazy as _ +from ..locale import gettext_lazy as _ class SMSManagerGateway(object): diff --git a/libs/apprise/plugins/NotifySMTP2Go.py b/libs/apprise/plugins/smtp2go.py similarity index 99% rename from libs/apprise/plugins/NotifySMTP2Go.py rename to libs/apprise/plugins/smtp2go.py index a34492d05..017da8111 100644 --- a/libs/apprise/plugins/NotifySMTP2Go.py +++ b/libs/apprise/plugins/smtp2go.py @@ -49,14 +49,14 @@ import base64 import requests from json import dumps from email.utils import formataddr -from .NotifyBase import NotifyBase +from .base import NotifyBase from ..common import NotifyType from ..common import NotifyFormat from ..utils import parse_emails from ..utils import parse_bool from ..utils import is_email from ..utils import validate_regex -from ..AppriseLocale import gettext_lazy as _ +from ..locale import gettext_lazy as _ SMTP2GO_HTTP_ERROR_MAP = { 429: 'To many requests.', diff --git a/libs/apprise/plugins/NotifySNS.py b/libs/apprise/plugins/sns.py similarity index 99% rename from libs/apprise/plugins/NotifySNS.py rename to libs/apprise/plugins/sns.py index 5a287e37e..cc6e83076 100644 --- a/libs/apprise/plugins/NotifySNS.py +++ b/libs/apprise/plugins/sns.py @@ -36,13 +36,13 @@ from collections import OrderedDict from xml.etree import ElementTree from itertools import chain -from .NotifyBase import NotifyBase -from ..URLBase import PrivacyMode +from .base import NotifyBase +from ..url import PrivacyMode from ..common import NotifyType from ..utils import is_phone_no from ..utils import parse_list from ..utils import validate_regex -from ..AppriseLocale import gettext_lazy as _ +from ..locale import gettext_lazy as _ # Topic Detection # Summary: 256 Characters max, only alpha/numeric plus underscore (_) and diff --git a/libs/apprise/plugins/NotifySparkPost.py b/libs/apprise/plugins/sparkpost.py similarity index 99% rename from libs/apprise/plugins/NotifySparkPost.py rename to libs/apprise/plugins/sparkpost.py index 255db0709..b873d6b0e 100644 --- a/libs/apprise/plugins/NotifySparkPost.py +++ b/libs/apprise/plugins/sparkpost.py @@ -58,7 +58,7 @@ import requests import base64 from json import loads from json import dumps -from .NotifyBase import NotifyBase +from .base import NotifyBase from ..common import NotifyType from ..common import NotifyFormat from ..utils import is_email @@ -66,7 +66,7 @@ from email.utils import formataddr from ..utils import validate_regex from ..utils import parse_emails from ..utils import parse_bool -from ..AppriseLocale import gettext_lazy as _ +from ..locale import gettext_lazy as _ # Provide some known codes SparkPost uses and what they translate to: # Based on https://www.sparkpost.com/docs/tech-resources/extended-error-codes/ diff --git a/libs/apprise/plugins/NotifyStreamlabs.py b/libs/apprise/plugins/streamlabs.py similarity index 99% rename from libs/apprise/plugins/NotifyStreamlabs.py rename to libs/apprise/plugins/streamlabs.py index d1e4186a6..c534f1ba6 100644 --- a/libs/apprise/plugins/NotifyStreamlabs.py +++ b/libs/apprise/plugins/streamlabs.py @@ -38,10 +38,10 @@ # import requests -from .NotifyBase import NotifyBase +from .base import NotifyBase from ..common import NotifyType from ..utils import validate_regex -from ..AppriseLocale import gettext_lazy as _ +from ..locale import gettext_lazy as _ # calls diff --git a/libs/apprise/plugins/NotifySynology.py b/libs/apprise/plugins/synology.py similarity index 98% rename from libs/apprise/plugins/NotifySynology.py rename to libs/apprise/plugins/synology.py index be58c0643..ed85f80c0 100644 --- a/libs/apprise/plugins/NotifySynology.py +++ b/libs/apprise/plugins/synology.py @@ -29,10 +29,10 @@ import requests from json import dumps -from .NotifyBase import NotifyBase -from ..URLBase import PrivacyMode +from .base import NotifyBase +from ..url import PrivacyMode from ..common import NotifyType -from ..AppriseLocale import gettext_lazy as _ +from ..locale import gettext_lazy as _ # For API Details see: # https://kb.synology.com/en-au/DSM/help/Chat/chat_integration diff --git a/libs/apprise/plugins/NotifySyslog.py b/libs/apprise/plugins/syslog.py similarity index 99% rename from libs/apprise/plugins/NotifySyslog.py rename to libs/apprise/plugins/syslog.py index 5540fc758..935111eea 100644 --- a/libs/apprise/plugins/NotifySyslog.py +++ b/libs/apprise/plugins/syslog.py @@ -28,10 +28,10 @@ import syslog -from .NotifyBase import NotifyBase +from .base import NotifyBase from ..common import NotifyType from ..utils import parse_bool -from ..AppriseLocale import gettext_lazy as _ +from ..locale import gettext_lazy as _ class SyslogFacility: diff --git a/libs/apprise/plugins/NotifyTechulusPush.py b/libs/apprise/plugins/techuluspush.py similarity index 98% rename from libs/apprise/plugins/NotifyTechulusPush.py rename to libs/apprise/plugins/techuluspush.py index 4d0b99348..682bf088e 100644 --- a/libs/apprise/plugins/NotifyTechulusPush.py +++ b/libs/apprise/plugins/techuluspush.py @@ -53,10 +53,10 @@ import requests from json import dumps -from .NotifyBase import NotifyBase +from .base import NotifyBase from ..common import NotifyType from ..utils import validate_regex -from ..AppriseLocale import gettext_lazy as _ +from ..locale import gettext_lazy as _ # Token required as part of the API request # Used to prepare our UUID regex matching diff --git a/libs/apprise/plugins/NotifyTelegram.py b/libs/apprise/plugins/telegram.py similarity index 99% rename from libs/apprise/plugins/NotifyTelegram.py rename to libs/apprise/plugins/telegram.py index cce8af625..6b997f574 100644 --- a/libs/apprise/plugins/NotifyTelegram.py +++ b/libs/apprise/plugins/telegram.py @@ -59,15 +59,15 @@ import os from json import loads from json import dumps -from .NotifyBase import NotifyBase +from .base import NotifyBase from ..common import NotifyType from ..common import NotifyImageSize from ..common import NotifyFormat from ..utils import parse_bool from ..utils import parse_list from ..utils import validate_regex -from ..AppriseLocale import gettext_lazy as _ -from ..attachment.AttachBase import AttachBase +from ..locale import gettext_lazy as _ +from ..attachment.base import AttachBase TELEGRAM_IMAGE_XY = NotifyImageSize.XY_256 diff --git a/libs/apprise/plugins/NotifyThreema.py b/libs/apprise/plugins/threema.py similarity index 99% rename from libs/apprise/plugins/NotifyThreema.py rename to libs/apprise/plugins/threema.py index c2ad82e2e..423c23124 100644 --- a/libs/apprise/plugins/NotifyThreema.py +++ b/libs/apprise/plugins/threema.py @@ -35,14 +35,14 @@ import requests from itertools import chain -from .NotifyBase import NotifyBase +from .base import NotifyBase from ..common import NotifyType from ..utils import is_phone_no from ..utils import validate_regex from ..utils import is_email -from ..URLBase import PrivacyMode +from ..url import PrivacyMode from ..utils import parse_list -from ..AppriseLocale import gettext_lazy as _ +from ..locale import gettext_lazy as _ class ThreemaRecipientTypes: diff --git a/libs/apprise/plugins/NotifyTwilio.py b/libs/apprise/plugins/twilio.py similarity index 99% rename from libs/apprise/plugins/NotifyTwilio.py rename to libs/apprise/plugins/twilio.py index 863b09a94..4205e37f0 100644 --- a/libs/apprise/plugins/NotifyTwilio.py +++ b/libs/apprise/plugins/twilio.py @@ -46,13 +46,13 @@ import requests from json import loads -from .NotifyBase import NotifyBase -from ..URLBase import PrivacyMode +from .base import NotifyBase +from ..url import PrivacyMode from ..common import NotifyType from ..utils import is_phone_no from ..utils import parse_phone_no from ..utils import validate_regex -from ..AppriseLocale import gettext_lazy as _ +from ..locale import gettext_lazy as _ class NotifyTwilio(NotifyBase): diff --git a/libs/apprise/plugins/NotifyTwist.py b/libs/apprise/plugins/twist.py similarity index 99% rename from libs/apprise/plugins/NotifyTwist.py rename to libs/apprise/plugins/twist.py index fa26feb84..62d729f4f 100644 --- a/libs/apprise/plugins/NotifyTwist.py +++ b/libs/apprise/plugins/twist.py @@ -35,13 +35,13 @@ import requests from json import loads from itertools import chain -from .NotifyBase import NotifyBase -from ..URLBase import PrivacyMode +from .base import NotifyBase +from ..url import PrivacyMode from ..common import NotifyFormat from ..common import NotifyType from ..utils import parse_list from ..utils import is_email -from ..AppriseLocale import gettext_lazy as _ +from ..locale import gettext_lazy as _ # A workspace can also be interpreted as a team name too! diff --git a/libs/apprise/plugins/NotifyTwitter.py b/libs/apprise/plugins/twitter.py similarity index 99% rename from libs/apprise/plugins/NotifyTwitter.py rename to libs/apprise/plugins/twitter.py index 7a0813c1f..8000a8151 100644 --- a/libs/apprise/plugins/NotifyTwitter.py +++ b/libs/apprise/plugins/twitter.py @@ -36,14 +36,14 @@ from datetime import timezone from requests_oauthlib import OAuth1 from json import dumps from json import loads -from .NotifyBase import NotifyBase -from ..URLBase import PrivacyMode +from .base import NotifyBase +from ..url import PrivacyMode from ..common import NotifyType from ..utils import parse_list from ..utils import parse_bool from ..utils import validate_regex -from ..AppriseLocale import gettext_lazy as _ -from ..attachment.AttachBase import AttachBase +from ..locale import gettext_lazy as _ +from ..attachment.base import AttachBase IS_USER = re.compile(r'^\s*@?(?P[A-Z0-9_]+)$', re.I) diff --git a/libs/apprise/plugins/NotifyVoipms.py b/libs/apprise/plugins/voipms.py similarity index 99% rename from libs/apprise/plugins/NotifyVoipms.py rename to libs/apprise/plugins/voipms.py index a023589a7..3a4e6d25f 100644 --- a/libs/apprise/plugins/NotifyVoipms.py +++ b/libs/apprise/plugins/voipms.py @@ -37,12 +37,12 @@ import requests from json import loads -from .NotifyBase import NotifyBase +from .base import NotifyBase from ..common import NotifyType from ..utils import is_phone_no from ..utils import is_email from ..utils import parse_phone_no -from ..AppriseLocale import gettext_lazy as _ +from ..locale import gettext_lazy as _ class NotifyVoipms(NotifyBase): diff --git a/libs/apprise/plugins/NotifyVonage.py b/libs/apprise/plugins/vonage.py similarity index 99% rename from libs/apprise/plugins/NotifyVonage.py rename to libs/apprise/plugins/vonage.py index e9b1422ad..441a6ba6b 100644 --- a/libs/apprise/plugins/NotifyVonage.py +++ b/libs/apprise/plugins/vonage.py @@ -33,13 +33,13 @@ # import requests -from .NotifyBase import NotifyBase -from ..URLBase import PrivacyMode +from .base import NotifyBase +from ..url import PrivacyMode from ..common import NotifyType from ..utils import is_phone_no from ..utils import parse_phone_no from ..utils import validate_regex -from ..AppriseLocale import gettext_lazy as _ +from ..locale import gettext_lazy as _ class NotifyVonage(NotifyBase): diff --git a/libs/apprise/plugins/NotifyWebexTeams.py b/libs/apprise/plugins/webexteams.py similarity index 99% rename from libs/apprise/plugins/NotifyWebexTeams.py rename to libs/apprise/plugins/webexteams.py index c91864bad..bd0bdb577 100644 --- a/libs/apprise/plugins/NotifyWebexTeams.py +++ b/libs/apprise/plugins/webexteams.py @@ -63,11 +63,11 @@ import re import requests from json import dumps -from .NotifyBase import NotifyBase +from .base import NotifyBase from ..common import NotifyType from ..common import NotifyFormat from ..utils import validate_regex -from ..AppriseLocale import gettext_lazy as _ +from ..locale import gettext_lazy as _ # Extend HTTP Error Messages # Based on: https://developer.webex.com/docs/api/basics/rate-limiting diff --git a/libs/apprise/plugins/NotifyWeComBot.py b/libs/apprise/plugins/wecombot.py similarity index 99% rename from libs/apprise/plugins/NotifyWeComBot.py rename to libs/apprise/plugins/wecombot.py index 4289b39e9..ab6341718 100644 --- a/libs/apprise/plugins/NotifyWeComBot.py +++ b/libs/apprise/plugins/wecombot.py @@ -59,10 +59,10 @@ import re import requests from json import dumps -from .NotifyBase import NotifyBase +from .base import NotifyBase from ..common import NotifyType from ..utils import validate_regex -from ..AppriseLocale import gettext_lazy as _ +from ..locale import gettext_lazy as _ class NotifyWeComBot(NotifyBase): diff --git a/libs/apprise/plugins/NotifyWhatsApp.py b/libs/apprise/plugins/whatsapp.py similarity index 99% rename from libs/apprise/plugins/NotifyWhatsApp.py rename to libs/apprise/plugins/whatsapp.py index 4ccbcbdaf..7120d736c 100644 --- a/libs/apprise/plugins/NotifyWhatsApp.py +++ b/libs/apprise/plugins/whatsapp.py @@ -44,12 +44,12 @@ import re import requests from json import loads, dumps -from .NotifyBase import NotifyBase +from .base import NotifyBase from ..common import NotifyType from ..utils import is_phone_no from ..utils import parse_phone_no from ..utils import validate_regex -from ..AppriseLocale import gettext_lazy as _ +from ..locale import gettext_lazy as _ class NotifyWhatsApp(NotifyBase): diff --git a/libs/apprise/plugins/NotifyWindows.py b/libs/apprise/plugins/windows.py similarity index 99% rename from libs/apprise/plugins/NotifyWindows.py rename to libs/apprise/plugins/windows.py index 207e0f221..746fcd1dd 100644 --- a/libs/apprise/plugins/NotifyWindows.py +++ b/libs/apprise/plugins/windows.py @@ -28,11 +28,11 @@ from time import sleep -from .NotifyBase import NotifyBase +from .base import NotifyBase from ..common import NotifyImageSize from ..common import NotifyType from ..utils import parse_bool -from ..AppriseLocale import gettext_lazy as _ +from ..locale import gettext_lazy as _ # Default our global support flag NOTIFY_WINDOWS_SUPPORT_ENABLED = False diff --git a/libs/apprise/plugins/NotifyXBMC.py b/libs/apprise/plugins/xbmc.py similarity index 99% rename from libs/apprise/plugins/NotifyXBMC.py rename to libs/apprise/plugins/xbmc.py index 7d4462e41..8006e1005 100644 --- a/libs/apprise/plugins/NotifyXBMC.py +++ b/libs/apprise/plugins/xbmc.py @@ -29,12 +29,12 @@ import requests from json import dumps -from .NotifyBase import NotifyBase -from ..URLBase import PrivacyMode +from .base import NotifyBase +from ..url import PrivacyMode from ..common import NotifyType from ..common import NotifyImageSize from ..utils import parse_bool -from ..AppriseLocale import gettext_lazy as _ +from ..locale import gettext_lazy as _ class NotifyXBMC(NotifyBase): diff --git a/libs/apprise/plugins/NotifyZulip.py b/libs/apprise/plugins/zulip.py similarity index 99% rename from libs/apprise/plugins/NotifyZulip.py rename to libs/apprise/plugins/zulip.py index 54fe2d062..e829e6f6d 100644 --- a/libs/apprise/plugins/NotifyZulip.py +++ b/libs/apprise/plugins/zulip.py @@ -61,13 +61,13 @@ import re import requests -from .NotifyBase import NotifyBase +from .base import NotifyBase from ..common import NotifyType from ..utils import parse_list from ..utils import validate_regex from ..utils import is_email from ..utils import remove_suffix -from ..AppriseLocale import gettext_lazy as _ +from ..locale import gettext_lazy as _ # A Valid Bot Name VALIDATE_BOTNAME = re.compile(r'(?P[A-Z0-9_-]{1,32})', re.I) diff --git a/libs/apprise/URLBase.py b/libs/apprise/url.py similarity index 99% rename from libs/apprise/URLBase.py rename to libs/apprise/url.py index 90ea85c66..39daec867 100644 --- a/libs/apprise/URLBase.py +++ b/libs/apprise/url.py @@ -35,8 +35,8 @@ from xml.sax.saxutils import escape as sax_escape from urllib.parse import unquote as _unquote from urllib.parse import quote as _quote -from .AppriseLocale import gettext_lazy as _ -from .AppriseAsset import AppriseAsset +from .locale import gettext_lazy as _ +from .asset import AppriseAsset from .utils import urlencode from .utils import parse_url from .utils import parse_bool @@ -744,7 +744,7 @@ class URLBase: @staticmethod def parse_url(url, verify_host=True, plus_to_space=False, - strict_port=False): + strict_port=False, sanitize=True): """Parses the URL and returns it broken apart into a dictionary. This is very specific and customized for Apprise. @@ -765,7 +765,8 @@ class URLBase: results = parse_url( url, default_schema='unknown', verify_host=verify_host, - plus_to_space=plus_to_space, strict_port=strict_port) + plus_to_space=plus_to_space, strict_port=strict_port, + sanitize=sanitize) if not results: # We're done; we failed to parse our url diff --git a/libs/apprise/URLBase.pyi b/libs/apprise/url.pyi similarity index 100% rename from libs/apprise/URLBase.pyi rename to libs/apprise/url.pyi diff --git a/libs/apprise/utils.py b/libs/apprise/utils.py index e1881f314..b33ec0749 100644 --- a/libs/apprise/utils.py +++ b/libs/apprise/utils.py @@ -541,7 +541,7 @@ def tidy_path(path): return path -def parse_qsd(qs, simple=False, plus_to_space=False): +def parse_qsd(qs, simple=False, plus_to_space=False, sanitize=True): """ Query String Dictionary Builder @@ -568,6 +568,8 @@ def parse_qsd(qs, simple=False, plus_to_space=False): per normal URL Encoded defininition. Normal URL parsing applies this, but `+` is very actively used character with passwords, api keys, tokens, etc. So Apprise does not do this by default. + + if sanitize is set to False, then kwargs are not placed into lowercase """ # Our return result set: @@ -608,7 +610,7 @@ def parse_qsd(qs, simple=False, plus_to_space=False): # Always Query String Dictionary (qsd) for every entry we have # content is always made lowercase for easy indexing - result['qsd'][key.lower().strip()] = val + result['qsd'][key.lower().strip() if sanitize else key] = val if simple: # move along @@ -636,7 +638,7 @@ def parse_qsd(qs, simple=False, plus_to_space=False): def parse_url(url, default_schema='http', verify_host=True, strict_port=False, - simple=False, plus_to_space=False): + simple=False, plus_to_space=False, sanitize=True): """A function that greatly simplifies the parsing of a url specified by the end user. @@ -691,6 +693,8 @@ def parse_url(url, default_schema='http', verify_host=True, strict_port=False, If the URL can't be parsed then None is returned + If sanitize is set to False, then kwargs are not placed in lowercase + and wrapping whitespace is not removed """ if not isinstance(url, str): @@ -750,7 +754,8 @@ def parse_url(url, default_schema='http', verify_host=True, strict_port=False, # while ensuring that all keys are lowercase if qsdata: result.update(parse_qsd( - qsdata, simple=simple, plus_to_space=plus_to_space)) + qsdata, simple=simple, plus_to_space=plus_to_space, + sanitize=sanitize)) # Now do a proper extraction of data; http:// is just substitued in place # to allow urlparse() to function as expected, we'll swap this back to the diff --git a/libs/version.txt b/libs/version.txt index ccabf65cc..8ac12d74d 100644 --- a/libs/version.txt +++ b/libs/version.txt @@ -2,7 +2,7 @@ alembic==1.13.1 aniso8601==9.0.1 argparse==1.4.0 -apprise==1.7.6 +apprise==1.8.0 apscheduler<=3.10.4 attrs==23.2.0 blinker==1.7.0 From fd0a8c3d3bd1beadb1fed1a58013e386d3f29653 Mon Sep 17 00:00:00 2001 From: morpheus65535 Date: Sun, 12 May 2024 10:11:43 -0400 Subject: [PATCH 02/18] Emergency fix following Apprise 1.8.0 upgrade --- bazarr/app/notifier.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/bazarr/app/notifier.py b/bazarr/app/notifier.py index 931a700a4..f248dfcce 100644 --- a/bazarr/app/notifier.py +++ b/bazarr/app/notifier.py @@ -1,6 +1,6 @@ # coding=utf-8 -import apprise +from apprise import Apprise, AppriseAsset import logging from .database import TableSettingsNotifier, TableEpisodes, TableShows, TableMovies, database, insert, delete, select @@ -8,7 +8,7 @@ from .database import TableSettingsNotifier, TableEpisodes, TableShows, TableMov def update_notifier(): # define apprise object - a = apprise.Apprise() + a = Apprise() # Retrieve all the details results = a.details() @@ -70,9 +70,9 @@ def send_notifications(sonarr_series_id, sonarr_episode_id, message): if not episode: return - asset = apprise.AppriseAsset(async_mode=False) + asset = AppriseAsset(async_mode=False) - apobj = apprise.Apprise(asset=asset) + apobj = Apprise(asset=asset) for provider in providers: if provider.url is not None: @@ -101,9 +101,9 @@ def send_notifications_movie(radarr_id, message): else: movie_year = '' - asset = apprise.AppriseAsset(async_mode=False) + asset = AppriseAsset(async_mode=False) - apobj = apprise.Apprise(asset=asset) + apobj = Apprise(asset=asset) for provider in providers: if provider.url is not None: From b3a5d43a10befd2451711a1abbafe4f5c65f3c76 Mon Sep 17 00:00:00 2001 From: morpheus65535 Date: Sun, 12 May 2024 10:13:21 -0400 Subject: [PATCH 03/18] Fixed issue while saving some odd case ASS embedded subtitles. --- custom_libs/subliminal_patch/core.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/custom_libs/subliminal_patch/core.py b/custom_libs/subliminal_patch/core.py index cb21f4581..1282c2e4b 100644 --- a/custom_libs/subliminal_patch/core.py +++ b/custom_libs/subliminal_patch/core.py @@ -1203,7 +1203,7 @@ def save_subtitles(file_path, subtitles, single=False, directory=None, chmod=Non continue # create subtitle path - if bool(re.search(HI_REGEX, subtitle.text)): + if subtitle.text and bool(re.search(HI_REGEX, subtitle.text)): subtitle.language.hi = True subtitle_path = get_subtitle_path(file_path, None if single else subtitle.language, forced_tag=subtitle.language.forced, From d70a92e9476e61b12a79c5642629ed81c9ad703f Mon Sep 17 00:00:00 2001 From: morpheus65535 Date: Sun, 12 May 2024 23:13:21 -0400 Subject: [PATCH 04/18] Fixed uppercase issue in Apprise module name. --- libs/apprise/apprise.py | 887 +++++++++++++++++++++++++++++++++++++++ libs/apprise/apprise.pyi | 62 +++ 2 files changed, 949 insertions(+) create mode 100644 libs/apprise/apprise.py create mode 100644 libs/apprise/apprise.pyi diff --git a/libs/apprise/apprise.py b/libs/apprise/apprise.py new file mode 100644 index 000000000..05a2ee3cc --- /dev/null +++ b/libs/apprise/apprise.py @@ -0,0 +1,887 @@ +# -*- coding: utf-8 -*- +# BSD 2-Clause License +# +# Apprise - Push Notification Library. +# Copyright (c) 2024, Chris Caron +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. + +import asyncio +import concurrent.futures as cf +import os +from itertools import chain +from . import common +from .conversion import convert_between +from .utils import is_exclusive_match +from .manager_plugins import NotificationManager +from .utils import parse_list +from .utils import parse_urls +from .utils import cwe312_url +from .emojis import apply_emojis +from .logger import logger +from .asset import AppriseAsset +from .apprise_config import AppriseConfig +from .apprise_attachment import AppriseAttachment +from .locale import AppriseLocale +from .config.base import ConfigBase +from .plugins.base import NotifyBase + +from . import plugins +from . import __version__ + +# Grant access to our Notification Manager Singleton +N_MGR = NotificationManager() + + +class Apprise: + """ + Our Notification Manager + + """ + + def __init__(self, servers=None, asset=None, location=None, debug=False): + """ + Loads a set of server urls while applying the Asset() module to each + if specified. + + If no asset is provided, then the default asset is used. + + Optionally specify a global ContentLocation for a more strict means + of handling Attachments. + """ + + # Initialize a server list of URLs + self.servers = list() + + # Assigns an central asset object that will be later passed into each + # notification plugin. Assets contain information such as the local + # directory images can be found in. It can also identify remote + # URL paths that contain the images you want to present to the end + # user. If no asset is specified, then the default one is used. + self.asset = \ + asset if isinstance(asset, AppriseAsset) else AppriseAsset() + + if servers: + self.add(servers) + + # Initialize our locale object + self.locale = AppriseLocale() + + # Set our debug flag + self.debug = debug + + # Store our hosting location for optional strict rule handling + # of Attachments. Setting this to None removes any attachment + # restrictions. + self.location = location + + @staticmethod + def instantiate(url, asset=None, tag=None, suppress_exceptions=True): + """ + Returns the instance of a instantiated plugin based on the provided + Server URL. If the url fails to be parsed, then None is returned. + + The specified url can be either a string (the URL itself) or a + dictionary containing all of the components needed to istantiate + the notification service. If identifying a dictionary, at the bare + minimum, one must specify the schema. + + An example of a url dictionary object might look like: + { + schema: 'mailto', + host: 'google.com', + user: 'myuser', + password: 'mypassword', + } + + Alternatively the string is much easier to specify: + mailto://user:mypassword@google.com + + The dictionary works well for people who are calling details() to + extract the components they need to build the URL manually. + """ + + # Initialize our result set + results = None + + # Prepare our Asset Object + asset = asset if isinstance(asset, AppriseAsset) else AppriseAsset() + + if isinstance(url, str): + # Acquire our url tokens + results = plugins.url_to_dict( + url, secure_logging=asset.secure_logging) + + if results is None: + # Failed to parse the server URL; detailed logging handled + # inside url_to_dict - nothing to report here. + return None + + elif isinstance(url, dict): + # We already have our result set + results = url + + if results.get('schema') not in N_MGR: + # schema is a mandatory dictionary item as it is the only way + # we can index into our loaded plugins + logger.error('Dictionary does not include a "schema" entry.') + logger.trace( + 'Invalid dictionary unpacked as:{}{}'.format( + os.linesep, os.linesep.join( + ['{}="{}"'.format(k, v) + for k, v in results.items()]))) + return None + + logger.trace( + 'Dictionary unpacked as:{}{}'.format( + os.linesep, os.linesep.join( + ['{}="{}"'.format(k, v) for k, v in results.items()]))) + + # Otherwise we handle the invalid input specified + else: + logger.error( + 'An invalid URL type (%s) was specified for instantiation', + type(url)) + return None + + if not N_MGR[results['schema']].enabled: + # + # First Plugin Enable Check (Pre Initialization) + # + + # Plugin has been disabled at a global level + logger.error( + '%s:// is disabled on this system.', results['schema']) + return None + + # Build a list of tags to associate with the newly added notifications + results['tag'] = set(parse_list(tag)) + + # Set our Asset Object + results['asset'] = asset + + if suppress_exceptions: + try: + # Attempt to create an instance of our plugin using the parsed + # URL information + plugin = N_MGR[results['schema']](**results) + + # Create log entry of loaded URL + logger.debug( + 'Loaded {} URL: {}'.format( + N_MGR[results['schema']].service_name, + plugin.url(privacy=asset.secure_logging))) + + except Exception: + # CWE-312 (Secure Logging) Handling + loggable_url = url if not asset.secure_logging \ + else cwe312_url(url) + + # the arguments are invalid or can not be used. + logger.error( + 'Could not load {} URL: {}'.format( + N_MGR[results['schema']].service_name, + loggable_url)) + return None + + else: + # Attempt to create an instance of our plugin using the parsed + # URL information but don't wrap it in a try catch + plugin = N_MGR[results['schema']](**results) + + if not plugin.enabled: + # + # Second Plugin Enable Check (Post Initialization) + # + + # Service/Plugin is disabled (on a more local level). This is a + # case where the plugin was initially enabled but then after the + # __init__() was called under the hood something pre-determined + # that it could no longer be used. + + # The only downside to doing it this way is services are + # initialized prior to returning the details() if 3rd party tools + # are polling what is available. These services that become + # disabled thereafter are shown initially that they can be used. + logger.error( + '%s:// has become disabled on this system.', results['schema']) + return None + + return plugin + + def add(self, servers, asset=None, tag=None): + """ + Adds one or more server URLs into our list. + + You can override the global asset if you wish by including it with the + server(s) that you add. + + The tag allows you to associate 1 or more tag values to the server(s) + being added. tagging a service allows you to exclusively access them + when calling the notify() function. + """ + + # Initialize our return status + return_status = True + + if asset is None: + # prepare default asset + asset = self.asset + + if isinstance(servers, str): + # build our server list + servers = parse_urls(servers) + if len(servers) == 0: + return False + + elif isinstance(servers, dict): + # no problem, we support kwargs, convert it to a list + servers = [servers] + + elif isinstance(servers, (ConfigBase, NotifyBase, AppriseConfig)): + # Go ahead and just add our plugin into our list + self.servers.append(servers) + return True + + elif not isinstance(servers, (tuple, set, list)): + logger.error( + "An invalid notification (type={}) was specified.".format( + type(servers))) + return False + + for _server in servers: + + if isinstance(_server, (ConfigBase, NotifyBase, AppriseConfig)): + # Go ahead and just add our plugin into our list + self.servers.append(_server) + continue + + elif not isinstance(_server, (str, dict)): + logger.error( + "An invalid notification (type={}) was specified.".format( + type(_server))) + return_status = False + continue + + # Instantiate ourselves an object, this function throws or + # returns None if it fails + instance = Apprise.instantiate(_server, asset=asset, tag=tag) + if not isinstance(instance, NotifyBase): + # No logging is required as instantiate() handles failure + # and/or success reasons for us + return_status = False + continue + + # Add our initialized plugin to our server listings + self.servers.append(instance) + + # Return our status + return return_status + + def clear(self): + """ + Empties our server list + + """ + self.servers[:] = [] + + def find(self, tag=common.MATCH_ALL_TAG, match_always=True): + """ + Returns a list of all servers matching against the tag specified. + + """ + + # Build our tag setup + # - top level entries are treated as an 'or' + # - second level (or more) entries are treated as 'and' + # + # examples: + # tag="tagA, tagB" = tagA or tagB + # tag=['tagA', 'tagB'] = tagA or tagB + # tag=[('tagA', 'tagC'), 'tagB'] = (tagA and tagC) or tagB + # tag=[('tagB', 'tagC')] = tagB and tagC + + # A match_always flag allows us to pick up on our 'any' keyword + # and notify these services under all circumstances + match_always = common.MATCH_ALWAYS_TAG if match_always else None + + # Iterate over our loaded plugins + for entry in self.servers: + + if isinstance(entry, (ConfigBase, AppriseConfig)): + # load our servers + servers = entry.servers() + + else: + servers = [entry, ] + + for server in servers: + # Apply our tag matching based on our defined logic + if is_exclusive_match( + logic=tag, data=server.tags, + match_all=common.MATCH_ALL_TAG, + match_always=match_always): + yield server + return + + def notify(self, body, title='', notify_type=common.NotifyType.INFO, + body_format=None, tag=common.MATCH_ALL_TAG, match_always=True, + attach=None, interpret_escapes=None): + """ + Send a notification to all the plugins previously loaded. + + If the body_format specified is NotifyFormat.MARKDOWN, it will + be converted to HTML if the Notification type expects this. + + if the tag is specified (either a string or a set/list/tuple + of strings), then only the notifications flagged with that + tagged value are notified. By default, all added services + are notified (tag=MATCH_ALL_TAG) + + This function returns True if all notifications were successfully + sent, False if even just one of them fails, and None if no + notifications were sent at all as a result of tag filtering and/or + simply having empty configuration files that were read. + + Attach can contain a list of attachment URLs. attach can also be + represented by an AttachBase() (or list of) object(s). This + identifies the products you wish to notify + + Set interpret_escapes to True if you want to pre-escape a string + such as turning a \n into an actual new line, etc. + """ + + try: + # Process arguments and build synchronous and asynchronous calls + # (this step can throw internal errors). + sequential_calls, parallel_calls = self._create_notify_calls( + body, title, + notify_type=notify_type, body_format=body_format, + tag=tag, match_always=match_always, attach=attach, + interpret_escapes=interpret_escapes, + ) + + except TypeError: + # No notifications sent, and there was an internal error. + return False + + if not sequential_calls and not parallel_calls: + # Nothing to send + return None + + sequential_result = Apprise._notify_sequential(*sequential_calls) + parallel_result = Apprise._notify_parallel_threadpool(*parallel_calls) + return sequential_result and parallel_result + + async def async_notify(self, *args, **kwargs): + """ + Send a notification to all the plugins previously loaded, for + asynchronous callers. + + The arguments are identical to those of Apprise.notify(). + + """ + try: + # Process arguments and build synchronous and asynchronous calls + # (this step can throw internal errors). + sequential_calls, parallel_calls = self._create_notify_calls( + *args, **kwargs) + + except TypeError: + # No notifications sent, and there was an internal error. + return False + + if not sequential_calls and not parallel_calls: + # Nothing to send + return None + + sequential_result = Apprise._notify_sequential(*sequential_calls) + parallel_result = \ + await Apprise._notify_parallel_asyncio(*parallel_calls) + return sequential_result and parallel_result + + def _create_notify_calls(self, *args, **kwargs): + """ + Creates notifications for all the plugins loaded. + + Returns a list of (server, notify() kwargs) tuples for plugins with + parallelism disabled and another list for plugins with parallelism + enabled. + """ + + all_calls = list(self._create_notify_gen(*args, **kwargs)) + + # Split into sequential and parallel notify() calls. + sequential, parallel = [], [] + for (server, notify_kwargs) in all_calls: + if server.asset.async_mode: + parallel.append((server, notify_kwargs)) + else: + sequential.append((server, notify_kwargs)) + + return sequential, parallel + + def _create_notify_gen(self, body, title='', + notify_type=common.NotifyType.INFO, + body_format=None, tag=common.MATCH_ALL_TAG, + match_always=True, attach=None, + interpret_escapes=None): + """ + Internal generator function for _create_notify_calls(). + """ + + if len(self) == 0: + # Nothing to notify + msg = "There are no service(s) to notify" + logger.error(msg) + raise TypeError(msg) + + if not (title or body or attach): + msg = "No message content specified to deliver" + logger.error(msg) + raise TypeError(msg) + + try: + if title and isinstance(title, bytes): + title = title.decode(self.asset.encoding) + + if body and isinstance(body, bytes): + body = body.decode(self.asset.encoding) + + except UnicodeDecodeError: + msg = 'The content passed into Apprise was not of encoding ' \ + 'type: {}'.format(self.asset.encoding) + logger.error(msg) + raise TypeError(msg) + + # Tracks conversions + conversion_body_map = dict() + conversion_title_map = dict() + + # Prepare attachments if required + if attach is not None and not isinstance(attach, AppriseAttachment): + attach = AppriseAttachment( + attach, asset=self.asset, location=self.location) + + # Allow Asset default value + body_format = self.asset.body_format \ + if body_format is None else body_format + + # Allow Asset default value + interpret_escapes = self.asset.interpret_escapes \ + if interpret_escapes is None else interpret_escapes + + # Iterate over our loaded plugins + for server in self.find(tag, match_always=match_always): + # If our code reaches here, we either did not define a tag (it + # was set to None), or we did define a tag and the logic above + # determined we need to notify the service it's associated with + + # First we need to generate a key we will use to determine if we + # need to build our data out. Entries without are merged with + # the body at this stage. + key = server.notify_format if server.title_maxlen > 0\ + else f'_{server.notify_format}' + + if server.interpret_emojis: + # alter our key slightly to handle emojis since their value is + # pulled out of the notification + key += "-emojis" + + if key not in conversion_title_map: + + # Prepare our title + conversion_title_map[key] = '' if not title else title + + # Conversion of title only occurs for services where the title + # is blended with the body (title_maxlen <= 0) + if conversion_title_map[key] and server.title_maxlen <= 0: + conversion_title_map[key] = convert_between( + body_format, server.notify_format, + content=conversion_title_map[key]) + + # Our body is always converted no matter what + conversion_body_map[key] = \ + convert_between( + body_format, server.notify_format, content=body) + + if interpret_escapes: + # + # Escape our content + # + + try: + # Added overhead required due to Python 3 Encoding Bug + # identified here: https://bugs.python.org/issue21331 + conversion_body_map[key] = \ + conversion_body_map[key]\ + .encode('ascii', 'backslashreplace')\ + .decode('unicode-escape') + + conversion_title_map[key] = \ + conversion_title_map[key]\ + .encode('ascii', 'backslashreplace')\ + .decode('unicode-escape') + + except AttributeError: + # Must be of string type + msg = 'Failed to escape message body' + logger.error(msg) + raise TypeError(msg) + + if server.interpret_emojis: + # + # Convert our :emoji: definitions + # + + conversion_body_map[key] = \ + apply_emojis(conversion_body_map[key]) + conversion_title_map[key] = \ + apply_emojis(conversion_title_map[key]) + + kwargs = dict( + body=conversion_body_map[key], + title=conversion_title_map[key], + notify_type=notify_type, + attach=attach, + body_format=body_format + ) + yield (server, kwargs) + + @staticmethod + def _notify_sequential(*servers_kwargs): + """ + Process a list of notify() calls sequentially and synchronously. + """ + + success = True + + for (server, kwargs) in servers_kwargs: + try: + # Send notification + result = server.notify(**kwargs) + success = success and result + + except TypeError: + # These are our internally thrown notifications. + success = False + + except Exception: + # A catch all so we don't have to abort early + # just because one of our plugins has a bug in it. + logger.exception("Unhandled Notification Exception") + success = False + + return success + + @staticmethod + def _notify_parallel_threadpool(*servers_kwargs): + """ + Process a list of notify() calls in parallel and synchronously. + """ + + n_calls = len(servers_kwargs) + + # 0-length case + if n_calls == 0: + return True + + # There's no need to use a thread pool for just a single notification + if n_calls == 1: + return Apprise._notify_sequential(servers_kwargs[0]) + + # Create log entry + logger.info( + 'Notifying %d service(s) with threads.', len(servers_kwargs)) + + with cf.ThreadPoolExecutor() as executor: + success = True + futures = [executor.submit(server.notify, **kwargs) + for (server, kwargs) in servers_kwargs] + + for future in cf.as_completed(futures): + try: + result = future.result() + success = success and result + + except TypeError: + # These are our internally thrown notifications. + success = False + + except Exception: + # A catch all so we don't have to abort early + # just because one of our plugins has a bug in it. + logger.exception("Unhandled Notification Exception") + success = False + + return success + + @staticmethod + async def _notify_parallel_asyncio(*servers_kwargs): + """ + Process a list of async_notify() calls in parallel and asynchronously. + """ + + n_calls = len(servers_kwargs) + + # 0-length case + if n_calls == 0: + return True + + # (Unlike with the thread pool, we don't optimize for the single- + # notification case because asyncio can do useful work while waiting + # for that thread to complete) + + # Create log entry + logger.info( + 'Notifying %d service(s) asynchronously.', len(servers_kwargs)) + + async def do_call(server, kwargs): + return await server.async_notify(**kwargs) + + cors = (do_call(server, kwargs) for (server, kwargs) in servers_kwargs) + results = await asyncio.gather(*cors, return_exceptions=True) + + if any(isinstance(status, Exception) + and not isinstance(status, TypeError) for status in results): + # A catch all so we don't have to abort early just because + # one of our plugins has a bug in it. + logger.exception("Unhandled Notification Exception") + return False + + if any(isinstance(status, TypeError) for status in results): + # These are our internally thrown notifications. + return False + + return all(results) + + def details(self, lang=None, show_requirements=False, show_disabled=False): + """ + Returns the details associated with the Apprise object + + """ + + # general object returned + response = { + # Defines the current version of Apprise + 'version': __version__, + # Lists all of the currently supported Notifications + 'schemas': [], + # Includes the configured asset details + 'asset': self.asset.details(), + } + + for plugin in N_MGR.plugins(): + # Iterate over our hashed plugins and dynamically build details on + # their status: + + content = { + 'service_name': getattr(plugin, 'service_name', None), + 'service_url': getattr(plugin, 'service_url', None), + 'setup_url': getattr(plugin, 'setup_url', None), + # Placeholder - populated below + 'details': None, + + # Let upstream service know of the plugins that support + # attachments + 'attachment_support': getattr( + plugin, 'attachment_support', False), + + # Differentiat between what is a custom loaded plugin and + # which is native. + 'category': getattr(plugin, 'category', None) + } + + # Standard protocol(s) should be None or a tuple + enabled = getattr(plugin, 'enabled', True) + if not show_disabled and not enabled: + # Do not show inactive plugins + continue + + elif show_disabled: + # Add current state to response + content['enabled'] = enabled + + # Standard protocol(s) should be None or a tuple + protocols = getattr(plugin, 'protocol', None) + if isinstance(protocols, str): + protocols = (protocols, ) + + # Secure protocol(s) should be None or a tuple + secure_protocols = getattr(plugin, 'secure_protocol', None) + if isinstance(secure_protocols, str): + secure_protocols = (secure_protocols, ) + + # Add our protocol details to our content + content.update({ + 'protocols': protocols, + 'secure_protocols': secure_protocols, + }) + + if not lang: + # Simply return our results + content['details'] = plugins.details(plugin) + if show_requirements: + content['requirements'] = plugins.requirements(plugin) + + else: + # Emulate the specified language when returning our results + with self.locale.lang_at(lang): + content['details'] = plugins.details(plugin) + if show_requirements: + content['requirements'] = plugins.requirements(plugin) + + # Build our response object + response['schemas'].append(content) + + return response + + def urls(self, privacy=False): + """ + Returns all of the loaded URLs defined in this apprise object. + """ + return [x.url(privacy=privacy) for x in self.servers] + + def pop(self, index): + """ + Removes an indexed Notification Service from the stack and returns it. + + The thing is we can never pop AppriseConfig() entries, only what was + loaded within them. So pop needs to carefully iterate over our list + and only track actual entries. + """ + + # Tracking variables + prev_offset = -1 + offset = prev_offset + + for idx, s in enumerate(self.servers): + if isinstance(s, (ConfigBase, AppriseConfig)): + servers = s.servers() + if len(servers) > 0: + # Acquire a new maximum offset to work with + offset = prev_offset + len(servers) + + if offset >= index: + # we can pop an element from our config stack + fn = s.pop if isinstance(s, ConfigBase) \ + else s.server_pop + + return fn(index if prev_offset == -1 + else (index - prev_offset - 1)) + + else: + offset = prev_offset + 1 + if offset == index: + return self.servers.pop(idx) + + # Update our old offset + prev_offset = offset + + # If we reach here, then we indexed out of range + raise IndexError('list index out of range') + + def __getitem__(self, index): + """ + Returns the indexed server entry of a loaded notification server + """ + # Tracking variables + prev_offset = -1 + offset = prev_offset + + for idx, s in enumerate(self.servers): + if isinstance(s, (ConfigBase, AppriseConfig)): + # Get our list of servers associate with our config object + servers = s.servers() + if len(servers) > 0: + # Acquire a new maximum offset to work with + offset = prev_offset + len(servers) + + if offset >= index: + return servers[index if prev_offset == -1 + else (index - prev_offset - 1)] + + else: + offset = prev_offset + 1 + if offset == index: + return self.servers[idx] + + # Update our old offset + prev_offset = offset + + # If we reach here, then we indexed out of range + raise IndexError('list index out of range') + + def __getstate__(self): + """ + Pickle Support dumps() + """ + attributes = { + 'asset': self.asset, + # Prepare our URL list as we need to extract the associated tags + # and asset details associated with it + 'urls': [{ + 'url': server.url(privacy=False), + 'tag': server.tags if server.tags else None, + 'asset': server.asset} for server in self.servers], + 'locale': self.locale, + 'debug': self.debug, + 'location': self.location, + } + + return attributes + + def __setstate__(self, state): + """ + Pickle Support loads() + """ + self.servers = list() + self.asset = state['asset'] + self.locale = state['locale'] + self.location = state['location'] + for entry in state['urls']: + self.add(entry['url'], asset=entry['asset'], tag=entry['tag']) + + def __bool__(self): + """ + Allows the Apprise object to be wrapped in an 'if statement'. + True is returned if at least one service has been loaded. + """ + return len(self) > 0 + + def __iter__(self): + """ + Returns an iterator to each of our servers loaded. This includes those + found inside configuration. + """ + return chain(*[[s] if not isinstance(s, (ConfigBase, AppriseConfig)) + else iter(s.servers()) for s in self.servers]) + + def __len__(self): + """ + Returns the number of servers loaded; this includes those found within + loaded configuration. This funtion nnever actually counts the + Config entry themselves (if they exist), only what they contain. + """ + return sum([1 if not isinstance(s, (ConfigBase, AppriseConfig)) + else len(s.servers()) for s in self.servers]) diff --git a/libs/apprise/apprise.pyi b/libs/apprise/apprise.pyi new file mode 100644 index 000000000..5a34c9c65 --- /dev/null +++ b/libs/apprise/apprise.pyi @@ -0,0 +1,62 @@ +from typing import Any, Dict, List, Iterable, Iterator, Optional + +from . import (AppriseAsset, AppriseAttachment, AppriseConfig, ConfigBase, + NotifyBase, NotifyFormat, NotifyType) +from .common import ContentLocation + +_Server = Union[str, ConfigBase, NotifyBase, AppriseConfig] +_Servers = Union[_Server, Dict[Any, _Server], Iterable[_Server]] +# Can't define this recursively as mypy doesn't support recursive types: +# https://github.com/python/mypy/issues/731 +_Tag = Union[str, Iterable[Union[str, Iterable[str]]]] + +class Apprise: + def __init__( + self, + servers: _Servers = ..., + asset: Optional[AppriseAsset] = ..., + location: Optional[ContentLocation] = ..., + debug: bool = ... + ) -> None: ... + @staticmethod + def instantiate( + url: Union[str, Dict[str, NotifyBase]], + asset: Optional[AppriseAsset] = ..., + tag: Optional[_Tag] = ..., + suppress_exceptions: bool = ... + ) -> NotifyBase: ... + def add( + self, + servers: _Servers = ..., + asset: Optional[AppriseAsset] = ..., + tag: Optional[_Tag] = ... + ) -> bool: ... + def clear(self) -> None: ... + def find(self, tag: str = ...) -> Iterator[Apprise]: ... + def notify( + self, + body: str, + title: str = ..., + notify_type: NotifyType = ..., + body_format: NotifyFormat = ..., + tag: _Tag = ..., + attach: Optional[AppriseAttachment] = ..., + interpret_escapes: Optional[bool] = ... + ) -> bool: ... + async def async_notify( + self, + body: str, + title: str = ..., + notify_type: NotifyType = ..., + body_format: NotifyFormat = ..., + tag: _Tag = ..., + attach: Optional[AppriseAttachment] = ..., + interpret_escapes: Optional[bool] = ... + ) -> bool: ... + def details(self, lang: Optional[str] = ...) -> Dict[str, Any]: ... + def urls(self, privacy: bool = ...) -> Iterable[str]: ... + def pop(self, index: int) -> ConfigBase: ... + def __getitem__(self, index: int) -> ConfigBase: ... + def __bool__(self) -> bool: ... + def __iter__(self) -> Iterator[ConfigBase]: ... + def __len__(self) -> int: ... \ No newline at end of file From 9cb2708909420dbd2d9b0ae637a3bbde410e5176 Mon Sep 17 00:00:00 2001 From: morpheus65535 Date: Sun, 12 May 2024 23:16:01 -0400 Subject: [PATCH 05/18] no log: Delete libs/apprise/Apprise.pyi --- libs/apprise/Apprise.pyi | 62 ---------------------------------------- 1 file changed, 62 deletions(-) delete mode 100644 libs/apprise/Apprise.pyi diff --git a/libs/apprise/Apprise.pyi b/libs/apprise/Apprise.pyi deleted file mode 100644 index 5a34c9c65..000000000 --- a/libs/apprise/Apprise.pyi +++ /dev/null @@ -1,62 +0,0 @@ -from typing import Any, Dict, List, Iterable, Iterator, Optional - -from . import (AppriseAsset, AppriseAttachment, AppriseConfig, ConfigBase, - NotifyBase, NotifyFormat, NotifyType) -from .common import ContentLocation - -_Server = Union[str, ConfigBase, NotifyBase, AppriseConfig] -_Servers = Union[_Server, Dict[Any, _Server], Iterable[_Server]] -# Can't define this recursively as mypy doesn't support recursive types: -# https://github.com/python/mypy/issues/731 -_Tag = Union[str, Iterable[Union[str, Iterable[str]]]] - -class Apprise: - def __init__( - self, - servers: _Servers = ..., - asset: Optional[AppriseAsset] = ..., - location: Optional[ContentLocation] = ..., - debug: bool = ... - ) -> None: ... - @staticmethod - def instantiate( - url: Union[str, Dict[str, NotifyBase]], - asset: Optional[AppriseAsset] = ..., - tag: Optional[_Tag] = ..., - suppress_exceptions: bool = ... - ) -> NotifyBase: ... - def add( - self, - servers: _Servers = ..., - asset: Optional[AppriseAsset] = ..., - tag: Optional[_Tag] = ... - ) -> bool: ... - def clear(self) -> None: ... - def find(self, tag: str = ...) -> Iterator[Apprise]: ... - def notify( - self, - body: str, - title: str = ..., - notify_type: NotifyType = ..., - body_format: NotifyFormat = ..., - tag: _Tag = ..., - attach: Optional[AppriseAttachment] = ..., - interpret_escapes: Optional[bool] = ... - ) -> bool: ... - async def async_notify( - self, - body: str, - title: str = ..., - notify_type: NotifyType = ..., - body_format: NotifyFormat = ..., - tag: _Tag = ..., - attach: Optional[AppriseAttachment] = ..., - interpret_escapes: Optional[bool] = ... - ) -> bool: ... - def details(self, lang: Optional[str] = ...) -> Dict[str, Any]: ... - def urls(self, privacy: bool = ...) -> Iterable[str]: ... - def pop(self, index: int) -> ConfigBase: ... - def __getitem__(self, index: int) -> ConfigBase: ... - def __bool__(self) -> bool: ... - def __iter__(self) -> Iterator[ConfigBase]: ... - def __len__(self) -> int: ... \ No newline at end of file From 811394cec31e144727318820df5ad9506bdfcafd Mon Sep 17 00:00:00 2001 From: morpheus65535 Date: Sun, 12 May 2024 23:16:17 -0400 Subject: [PATCH 06/18] no log: Delete libs/apprise/Apprise.py --- libs/apprise/Apprise.py | 887 ---------------------------------------- 1 file changed, 887 deletions(-) delete mode 100644 libs/apprise/Apprise.py diff --git a/libs/apprise/Apprise.py b/libs/apprise/Apprise.py deleted file mode 100644 index 05a2ee3cc..000000000 --- a/libs/apprise/Apprise.py +++ /dev/null @@ -1,887 +0,0 @@ -# -*- coding: utf-8 -*- -# BSD 2-Clause License -# -# Apprise - Push Notification Library. -# Copyright (c) 2024, Chris Caron -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# -# 1. Redistributions of source code must retain the above copyright notice, -# this list of conditions and the following disclaimer. -# -# 2. Redistributions in binary form must reproduce the above copyright notice, -# this list of conditions and the following disclaimer in the documentation -# and/or other materials provided with the distribution. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. - -import asyncio -import concurrent.futures as cf -import os -from itertools import chain -from . import common -from .conversion import convert_between -from .utils import is_exclusive_match -from .manager_plugins import NotificationManager -from .utils import parse_list -from .utils import parse_urls -from .utils import cwe312_url -from .emojis import apply_emojis -from .logger import logger -from .asset import AppriseAsset -from .apprise_config import AppriseConfig -from .apprise_attachment import AppriseAttachment -from .locale import AppriseLocale -from .config.base import ConfigBase -from .plugins.base import NotifyBase - -from . import plugins -from . import __version__ - -# Grant access to our Notification Manager Singleton -N_MGR = NotificationManager() - - -class Apprise: - """ - Our Notification Manager - - """ - - def __init__(self, servers=None, asset=None, location=None, debug=False): - """ - Loads a set of server urls while applying the Asset() module to each - if specified. - - If no asset is provided, then the default asset is used. - - Optionally specify a global ContentLocation for a more strict means - of handling Attachments. - """ - - # Initialize a server list of URLs - self.servers = list() - - # Assigns an central asset object that will be later passed into each - # notification plugin. Assets contain information such as the local - # directory images can be found in. It can also identify remote - # URL paths that contain the images you want to present to the end - # user. If no asset is specified, then the default one is used. - self.asset = \ - asset if isinstance(asset, AppriseAsset) else AppriseAsset() - - if servers: - self.add(servers) - - # Initialize our locale object - self.locale = AppriseLocale() - - # Set our debug flag - self.debug = debug - - # Store our hosting location for optional strict rule handling - # of Attachments. Setting this to None removes any attachment - # restrictions. - self.location = location - - @staticmethod - def instantiate(url, asset=None, tag=None, suppress_exceptions=True): - """ - Returns the instance of a instantiated plugin based on the provided - Server URL. If the url fails to be parsed, then None is returned. - - The specified url can be either a string (the URL itself) or a - dictionary containing all of the components needed to istantiate - the notification service. If identifying a dictionary, at the bare - minimum, one must specify the schema. - - An example of a url dictionary object might look like: - { - schema: 'mailto', - host: 'google.com', - user: 'myuser', - password: 'mypassword', - } - - Alternatively the string is much easier to specify: - mailto://user:mypassword@google.com - - The dictionary works well for people who are calling details() to - extract the components they need to build the URL manually. - """ - - # Initialize our result set - results = None - - # Prepare our Asset Object - asset = asset if isinstance(asset, AppriseAsset) else AppriseAsset() - - if isinstance(url, str): - # Acquire our url tokens - results = plugins.url_to_dict( - url, secure_logging=asset.secure_logging) - - if results is None: - # Failed to parse the server URL; detailed logging handled - # inside url_to_dict - nothing to report here. - return None - - elif isinstance(url, dict): - # We already have our result set - results = url - - if results.get('schema') not in N_MGR: - # schema is a mandatory dictionary item as it is the only way - # we can index into our loaded plugins - logger.error('Dictionary does not include a "schema" entry.') - logger.trace( - 'Invalid dictionary unpacked as:{}{}'.format( - os.linesep, os.linesep.join( - ['{}="{}"'.format(k, v) - for k, v in results.items()]))) - return None - - logger.trace( - 'Dictionary unpacked as:{}{}'.format( - os.linesep, os.linesep.join( - ['{}="{}"'.format(k, v) for k, v in results.items()]))) - - # Otherwise we handle the invalid input specified - else: - logger.error( - 'An invalid URL type (%s) was specified for instantiation', - type(url)) - return None - - if not N_MGR[results['schema']].enabled: - # - # First Plugin Enable Check (Pre Initialization) - # - - # Plugin has been disabled at a global level - logger.error( - '%s:// is disabled on this system.', results['schema']) - return None - - # Build a list of tags to associate with the newly added notifications - results['tag'] = set(parse_list(tag)) - - # Set our Asset Object - results['asset'] = asset - - if suppress_exceptions: - try: - # Attempt to create an instance of our plugin using the parsed - # URL information - plugin = N_MGR[results['schema']](**results) - - # Create log entry of loaded URL - logger.debug( - 'Loaded {} URL: {}'.format( - N_MGR[results['schema']].service_name, - plugin.url(privacy=asset.secure_logging))) - - except Exception: - # CWE-312 (Secure Logging) Handling - loggable_url = url if not asset.secure_logging \ - else cwe312_url(url) - - # the arguments are invalid or can not be used. - logger.error( - 'Could not load {} URL: {}'.format( - N_MGR[results['schema']].service_name, - loggable_url)) - return None - - else: - # Attempt to create an instance of our plugin using the parsed - # URL information but don't wrap it in a try catch - plugin = N_MGR[results['schema']](**results) - - if not plugin.enabled: - # - # Second Plugin Enable Check (Post Initialization) - # - - # Service/Plugin is disabled (on a more local level). This is a - # case where the plugin was initially enabled but then after the - # __init__() was called under the hood something pre-determined - # that it could no longer be used. - - # The only downside to doing it this way is services are - # initialized prior to returning the details() if 3rd party tools - # are polling what is available. These services that become - # disabled thereafter are shown initially that they can be used. - logger.error( - '%s:// has become disabled on this system.', results['schema']) - return None - - return plugin - - def add(self, servers, asset=None, tag=None): - """ - Adds one or more server URLs into our list. - - You can override the global asset if you wish by including it with the - server(s) that you add. - - The tag allows you to associate 1 or more tag values to the server(s) - being added. tagging a service allows you to exclusively access them - when calling the notify() function. - """ - - # Initialize our return status - return_status = True - - if asset is None: - # prepare default asset - asset = self.asset - - if isinstance(servers, str): - # build our server list - servers = parse_urls(servers) - if len(servers) == 0: - return False - - elif isinstance(servers, dict): - # no problem, we support kwargs, convert it to a list - servers = [servers] - - elif isinstance(servers, (ConfigBase, NotifyBase, AppriseConfig)): - # Go ahead and just add our plugin into our list - self.servers.append(servers) - return True - - elif not isinstance(servers, (tuple, set, list)): - logger.error( - "An invalid notification (type={}) was specified.".format( - type(servers))) - return False - - for _server in servers: - - if isinstance(_server, (ConfigBase, NotifyBase, AppriseConfig)): - # Go ahead and just add our plugin into our list - self.servers.append(_server) - continue - - elif not isinstance(_server, (str, dict)): - logger.error( - "An invalid notification (type={}) was specified.".format( - type(_server))) - return_status = False - continue - - # Instantiate ourselves an object, this function throws or - # returns None if it fails - instance = Apprise.instantiate(_server, asset=asset, tag=tag) - if not isinstance(instance, NotifyBase): - # No logging is required as instantiate() handles failure - # and/or success reasons for us - return_status = False - continue - - # Add our initialized plugin to our server listings - self.servers.append(instance) - - # Return our status - return return_status - - def clear(self): - """ - Empties our server list - - """ - self.servers[:] = [] - - def find(self, tag=common.MATCH_ALL_TAG, match_always=True): - """ - Returns a list of all servers matching against the tag specified. - - """ - - # Build our tag setup - # - top level entries are treated as an 'or' - # - second level (or more) entries are treated as 'and' - # - # examples: - # tag="tagA, tagB" = tagA or tagB - # tag=['tagA', 'tagB'] = tagA or tagB - # tag=[('tagA', 'tagC'), 'tagB'] = (tagA and tagC) or tagB - # tag=[('tagB', 'tagC')] = tagB and tagC - - # A match_always flag allows us to pick up on our 'any' keyword - # and notify these services under all circumstances - match_always = common.MATCH_ALWAYS_TAG if match_always else None - - # Iterate over our loaded plugins - for entry in self.servers: - - if isinstance(entry, (ConfigBase, AppriseConfig)): - # load our servers - servers = entry.servers() - - else: - servers = [entry, ] - - for server in servers: - # Apply our tag matching based on our defined logic - if is_exclusive_match( - logic=tag, data=server.tags, - match_all=common.MATCH_ALL_TAG, - match_always=match_always): - yield server - return - - def notify(self, body, title='', notify_type=common.NotifyType.INFO, - body_format=None, tag=common.MATCH_ALL_TAG, match_always=True, - attach=None, interpret_escapes=None): - """ - Send a notification to all the plugins previously loaded. - - If the body_format specified is NotifyFormat.MARKDOWN, it will - be converted to HTML if the Notification type expects this. - - if the tag is specified (either a string or a set/list/tuple - of strings), then only the notifications flagged with that - tagged value are notified. By default, all added services - are notified (tag=MATCH_ALL_TAG) - - This function returns True if all notifications were successfully - sent, False if even just one of them fails, and None if no - notifications were sent at all as a result of tag filtering and/or - simply having empty configuration files that were read. - - Attach can contain a list of attachment URLs. attach can also be - represented by an AttachBase() (or list of) object(s). This - identifies the products you wish to notify - - Set interpret_escapes to True if you want to pre-escape a string - such as turning a \n into an actual new line, etc. - """ - - try: - # Process arguments and build synchronous and asynchronous calls - # (this step can throw internal errors). - sequential_calls, parallel_calls = self._create_notify_calls( - body, title, - notify_type=notify_type, body_format=body_format, - tag=tag, match_always=match_always, attach=attach, - interpret_escapes=interpret_escapes, - ) - - except TypeError: - # No notifications sent, and there was an internal error. - return False - - if not sequential_calls and not parallel_calls: - # Nothing to send - return None - - sequential_result = Apprise._notify_sequential(*sequential_calls) - parallel_result = Apprise._notify_parallel_threadpool(*parallel_calls) - return sequential_result and parallel_result - - async def async_notify(self, *args, **kwargs): - """ - Send a notification to all the plugins previously loaded, for - asynchronous callers. - - The arguments are identical to those of Apprise.notify(). - - """ - try: - # Process arguments and build synchronous and asynchronous calls - # (this step can throw internal errors). - sequential_calls, parallel_calls = self._create_notify_calls( - *args, **kwargs) - - except TypeError: - # No notifications sent, and there was an internal error. - return False - - if not sequential_calls and not parallel_calls: - # Nothing to send - return None - - sequential_result = Apprise._notify_sequential(*sequential_calls) - parallel_result = \ - await Apprise._notify_parallel_asyncio(*parallel_calls) - return sequential_result and parallel_result - - def _create_notify_calls(self, *args, **kwargs): - """ - Creates notifications for all the plugins loaded. - - Returns a list of (server, notify() kwargs) tuples for plugins with - parallelism disabled and another list for plugins with parallelism - enabled. - """ - - all_calls = list(self._create_notify_gen(*args, **kwargs)) - - # Split into sequential and parallel notify() calls. - sequential, parallel = [], [] - for (server, notify_kwargs) in all_calls: - if server.asset.async_mode: - parallel.append((server, notify_kwargs)) - else: - sequential.append((server, notify_kwargs)) - - return sequential, parallel - - def _create_notify_gen(self, body, title='', - notify_type=common.NotifyType.INFO, - body_format=None, tag=common.MATCH_ALL_TAG, - match_always=True, attach=None, - interpret_escapes=None): - """ - Internal generator function for _create_notify_calls(). - """ - - if len(self) == 0: - # Nothing to notify - msg = "There are no service(s) to notify" - logger.error(msg) - raise TypeError(msg) - - if not (title or body or attach): - msg = "No message content specified to deliver" - logger.error(msg) - raise TypeError(msg) - - try: - if title and isinstance(title, bytes): - title = title.decode(self.asset.encoding) - - if body and isinstance(body, bytes): - body = body.decode(self.asset.encoding) - - except UnicodeDecodeError: - msg = 'The content passed into Apprise was not of encoding ' \ - 'type: {}'.format(self.asset.encoding) - logger.error(msg) - raise TypeError(msg) - - # Tracks conversions - conversion_body_map = dict() - conversion_title_map = dict() - - # Prepare attachments if required - if attach is not None and not isinstance(attach, AppriseAttachment): - attach = AppriseAttachment( - attach, asset=self.asset, location=self.location) - - # Allow Asset default value - body_format = self.asset.body_format \ - if body_format is None else body_format - - # Allow Asset default value - interpret_escapes = self.asset.interpret_escapes \ - if interpret_escapes is None else interpret_escapes - - # Iterate over our loaded plugins - for server in self.find(tag, match_always=match_always): - # If our code reaches here, we either did not define a tag (it - # was set to None), or we did define a tag and the logic above - # determined we need to notify the service it's associated with - - # First we need to generate a key we will use to determine if we - # need to build our data out. Entries without are merged with - # the body at this stage. - key = server.notify_format if server.title_maxlen > 0\ - else f'_{server.notify_format}' - - if server.interpret_emojis: - # alter our key slightly to handle emojis since their value is - # pulled out of the notification - key += "-emojis" - - if key not in conversion_title_map: - - # Prepare our title - conversion_title_map[key] = '' if not title else title - - # Conversion of title only occurs for services where the title - # is blended with the body (title_maxlen <= 0) - if conversion_title_map[key] and server.title_maxlen <= 0: - conversion_title_map[key] = convert_between( - body_format, server.notify_format, - content=conversion_title_map[key]) - - # Our body is always converted no matter what - conversion_body_map[key] = \ - convert_between( - body_format, server.notify_format, content=body) - - if interpret_escapes: - # - # Escape our content - # - - try: - # Added overhead required due to Python 3 Encoding Bug - # identified here: https://bugs.python.org/issue21331 - conversion_body_map[key] = \ - conversion_body_map[key]\ - .encode('ascii', 'backslashreplace')\ - .decode('unicode-escape') - - conversion_title_map[key] = \ - conversion_title_map[key]\ - .encode('ascii', 'backslashreplace')\ - .decode('unicode-escape') - - except AttributeError: - # Must be of string type - msg = 'Failed to escape message body' - logger.error(msg) - raise TypeError(msg) - - if server.interpret_emojis: - # - # Convert our :emoji: definitions - # - - conversion_body_map[key] = \ - apply_emojis(conversion_body_map[key]) - conversion_title_map[key] = \ - apply_emojis(conversion_title_map[key]) - - kwargs = dict( - body=conversion_body_map[key], - title=conversion_title_map[key], - notify_type=notify_type, - attach=attach, - body_format=body_format - ) - yield (server, kwargs) - - @staticmethod - def _notify_sequential(*servers_kwargs): - """ - Process a list of notify() calls sequentially and synchronously. - """ - - success = True - - for (server, kwargs) in servers_kwargs: - try: - # Send notification - result = server.notify(**kwargs) - success = success and result - - except TypeError: - # These are our internally thrown notifications. - success = False - - except Exception: - # A catch all so we don't have to abort early - # just because one of our plugins has a bug in it. - logger.exception("Unhandled Notification Exception") - success = False - - return success - - @staticmethod - def _notify_parallel_threadpool(*servers_kwargs): - """ - Process a list of notify() calls in parallel and synchronously. - """ - - n_calls = len(servers_kwargs) - - # 0-length case - if n_calls == 0: - return True - - # There's no need to use a thread pool for just a single notification - if n_calls == 1: - return Apprise._notify_sequential(servers_kwargs[0]) - - # Create log entry - logger.info( - 'Notifying %d service(s) with threads.', len(servers_kwargs)) - - with cf.ThreadPoolExecutor() as executor: - success = True - futures = [executor.submit(server.notify, **kwargs) - for (server, kwargs) in servers_kwargs] - - for future in cf.as_completed(futures): - try: - result = future.result() - success = success and result - - except TypeError: - # These are our internally thrown notifications. - success = False - - except Exception: - # A catch all so we don't have to abort early - # just because one of our plugins has a bug in it. - logger.exception("Unhandled Notification Exception") - success = False - - return success - - @staticmethod - async def _notify_parallel_asyncio(*servers_kwargs): - """ - Process a list of async_notify() calls in parallel and asynchronously. - """ - - n_calls = len(servers_kwargs) - - # 0-length case - if n_calls == 0: - return True - - # (Unlike with the thread pool, we don't optimize for the single- - # notification case because asyncio can do useful work while waiting - # for that thread to complete) - - # Create log entry - logger.info( - 'Notifying %d service(s) asynchronously.', len(servers_kwargs)) - - async def do_call(server, kwargs): - return await server.async_notify(**kwargs) - - cors = (do_call(server, kwargs) for (server, kwargs) in servers_kwargs) - results = await asyncio.gather(*cors, return_exceptions=True) - - if any(isinstance(status, Exception) - and not isinstance(status, TypeError) for status in results): - # A catch all so we don't have to abort early just because - # one of our plugins has a bug in it. - logger.exception("Unhandled Notification Exception") - return False - - if any(isinstance(status, TypeError) for status in results): - # These are our internally thrown notifications. - return False - - return all(results) - - def details(self, lang=None, show_requirements=False, show_disabled=False): - """ - Returns the details associated with the Apprise object - - """ - - # general object returned - response = { - # Defines the current version of Apprise - 'version': __version__, - # Lists all of the currently supported Notifications - 'schemas': [], - # Includes the configured asset details - 'asset': self.asset.details(), - } - - for plugin in N_MGR.plugins(): - # Iterate over our hashed plugins and dynamically build details on - # their status: - - content = { - 'service_name': getattr(plugin, 'service_name', None), - 'service_url': getattr(plugin, 'service_url', None), - 'setup_url': getattr(plugin, 'setup_url', None), - # Placeholder - populated below - 'details': None, - - # Let upstream service know of the plugins that support - # attachments - 'attachment_support': getattr( - plugin, 'attachment_support', False), - - # Differentiat between what is a custom loaded plugin and - # which is native. - 'category': getattr(plugin, 'category', None) - } - - # Standard protocol(s) should be None or a tuple - enabled = getattr(plugin, 'enabled', True) - if not show_disabled and not enabled: - # Do not show inactive plugins - continue - - elif show_disabled: - # Add current state to response - content['enabled'] = enabled - - # Standard protocol(s) should be None or a tuple - protocols = getattr(plugin, 'protocol', None) - if isinstance(protocols, str): - protocols = (protocols, ) - - # Secure protocol(s) should be None or a tuple - secure_protocols = getattr(plugin, 'secure_protocol', None) - if isinstance(secure_protocols, str): - secure_protocols = (secure_protocols, ) - - # Add our protocol details to our content - content.update({ - 'protocols': protocols, - 'secure_protocols': secure_protocols, - }) - - if not lang: - # Simply return our results - content['details'] = plugins.details(plugin) - if show_requirements: - content['requirements'] = plugins.requirements(plugin) - - else: - # Emulate the specified language when returning our results - with self.locale.lang_at(lang): - content['details'] = plugins.details(plugin) - if show_requirements: - content['requirements'] = plugins.requirements(plugin) - - # Build our response object - response['schemas'].append(content) - - return response - - def urls(self, privacy=False): - """ - Returns all of the loaded URLs defined in this apprise object. - """ - return [x.url(privacy=privacy) for x in self.servers] - - def pop(self, index): - """ - Removes an indexed Notification Service from the stack and returns it. - - The thing is we can never pop AppriseConfig() entries, only what was - loaded within them. So pop needs to carefully iterate over our list - and only track actual entries. - """ - - # Tracking variables - prev_offset = -1 - offset = prev_offset - - for idx, s in enumerate(self.servers): - if isinstance(s, (ConfigBase, AppriseConfig)): - servers = s.servers() - if len(servers) > 0: - # Acquire a new maximum offset to work with - offset = prev_offset + len(servers) - - if offset >= index: - # we can pop an element from our config stack - fn = s.pop if isinstance(s, ConfigBase) \ - else s.server_pop - - return fn(index if prev_offset == -1 - else (index - prev_offset - 1)) - - else: - offset = prev_offset + 1 - if offset == index: - return self.servers.pop(idx) - - # Update our old offset - prev_offset = offset - - # If we reach here, then we indexed out of range - raise IndexError('list index out of range') - - def __getitem__(self, index): - """ - Returns the indexed server entry of a loaded notification server - """ - # Tracking variables - prev_offset = -1 - offset = prev_offset - - for idx, s in enumerate(self.servers): - if isinstance(s, (ConfigBase, AppriseConfig)): - # Get our list of servers associate with our config object - servers = s.servers() - if len(servers) > 0: - # Acquire a new maximum offset to work with - offset = prev_offset + len(servers) - - if offset >= index: - return servers[index if prev_offset == -1 - else (index - prev_offset - 1)] - - else: - offset = prev_offset + 1 - if offset == index: - return self.servers[idx] - - # Update our old offset - prev_offset = offset - - # If we reach here, then we indexed out of range - raise IndexError('list index out of range') - - def __getstate__(self): - """ - Pickle Support dumps() - """ - attributes = { - 'asset': self.asset, - # Prepare our URL list as we need to extract the associated tags - # and asset details associated with it - 'urls': [{ - 'url': server.url(privacy=False), - 'tag': server.tags if server.tags else None, - 'asset': server.asset} for server in self.servers], - 'locale': self.locale, - 'debug': self.debug, - 'location': self.location, - } - - return attributes - - def __setstate__(self, state): - """ - Pickle Support loads() - """ - self.servers = list() - self.asset = state['asset'] - self.locale = state['locale'] - self.location = state['location'] - for entry in state['urls']: - self.add(entry['url'], asset=entry['asset'], tag=entry['tag']) - - def __bool__(self): - """ - Allows the Apprise object to be wrapped in an 'if statement'. - True is returned if at least one service has been loaded. - """ - return len(self) > 0 - - def __iter__(self): - """ - Returns an iterator to each of our servers loaded. This includes those - found inside configuration. - """ - return chain(*[[s] if not isinstance(s, (ConfigBase, AppriseConfig)) - else iter(s.servers()) for s in self.servers]) - - def __len__(self): - """ - Returns the number of servers loaded; this includes those found within - loaded configuration. This funtion nnever actually counts the - Config entry themselves (if they exist), only what they contain. - """ - return sum([1 if not isinstance(s, (ConfigBase, AppriseConfig)) - else len(s.servers()) for s in self.servers]) From d8e58cac836f0615cddbd85b62d2af8498e7df40 Mon Sep 17 00:00:00 2001 From: morpheus65535 Date: Mon, 13 May 2024 22:11:40 -0400 Subject: [PATCH 07/18] no log: fixed empty subtitles being saved --- custom_libs/subliminal_patch/core.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/custom_libs/subliminal_patch/core.py b/custom_libs/subliminal_patch/core.py index 1282c2e4b..872896e9c 100644 --- a/custom_libs/subliminal_patch/core.py +++ b/custom_libs/subliminal_patch/core.py @@ -1193,7 +1193,7 @@ def save_subtitles(file_path, subtitles, single=False, directory=None, chmod=Non must_remove_hi = 'remove_HI' in subtitle.mods # check content - if subtitle.content is None: + if subtitle.content is None or subtitle.text is None: logger.error('Skipping subtitle %r: no content', subtitle) continue From 07534282a24b48efb8bdd98a4c96ddd1114581cb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 13 May 2024 22:24:04 -0400 Subject: [PATCH 08/18] no log: Bump @types/lodash from 4.17.0 to 4.17.1 in /frontend (#2495) Bumps [@types/lodash](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/lodash) from 4.17.0 to 4.17.1. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/lodash) --- updated-dependencies: - dependency-name: "@types/lodash" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- frontend/package-lock.json | 8 ++++---- frontend/package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 42c99c60c..bfc24c17f 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -33,7 +33,7 @@ "@testing-library/react": "^15.0.5", "@testing-library/user-event": "^14.5.2", "@types/jest": "^29.5.12", - "@types/lodash": "^4.17.0", + "@types/lodash": "^4.17.1", "@types/node": "^20.12.6", "@types/react": "^18.2.75", "@types/react-dom": "^18.2.24", @@ -3882,9 +3882,9 @@ "dev": true }, "node_modules/@types/lodash": { - "version": "4.17.0", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.0.tgz", - "integrity": "sha512-t7dhREVv6dbNj0q17X12j7yDG4bD/DHYX7o5/DbDxobP0HnGPgpRz2Ej77aL7TZT3DSw13fqUTj8J4mMnqa7WA==", + "version": "4.17.1", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.1.tgz", + "integrity": "sha512-X+2qazGS3jxLAIz5JDXDzglAF3KpijdhFxlf/V1+hEsOUc+HnWi81L/uv/EvGuV90WY+7mPGFCUDGfQC3Gj95Q==", "dev": true }, "node_modules/@types/node": { diff --git a/frontend/package.json b/frontend/package.json index df5b6918a..eadb26496 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -37,7 +37,7 @@ "@testing-library/react": "^15.0.5", "@testing-library/user-event": "^14.5.2", "@types/jest": "^29.5.12", - "@types/lodash": "^4.17.0", + "@types/lodash": "^4.17.1", "@types/node": "^20.12.6", "@types/react": "^18.2.75", "@types/react-dom": "^18.2.24", From 3e929d8ef90fcb77bba0abeb4662d4d5e2882e6a Mon Sep 17 00:00:00 2001 From: morpheus65535 Date: Thu, 23 May 2024 20:46:07 -0400 Subject: [PATCH 09/18] Fixed upgrade process that was broken since Apprise 1.8.0 update. #2497 --- bazarr/app/check_update.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/bazarr/app/check_update.py b/bazarr/app/check_update.py index 4a8f64868..97617c75b 100644 --- a/bazarr/app/check_update.py +++ b/bazarr/app/check_update.py @@ -229,6 +229,9 @@ def update_cleaner(zipfile, bazarr_dir, config_dir): dir_to_ignore_regex = re.compile(dir_to_ignore_regex_string) file_to_ignore = ['nssm.exe', '7za.exe', 'unins000.exe', 'unins000.dat'] + # prevent deletion of leftover Apprise.py/pyi files after 1.8.0 version that caused issue on case-insensitive + # filesystem. This could be removed in a couple of major versions. + file_to_ignore += ['Apprise.py', 'Apprise.pyi', 'apprise.py', 'apprise.pyi'] logging.debug(f'BAZARR upgrade leftover cleaner will ignore those files: {", ".join(file_to_ignore)}') extension_to_ignore = ['.pyc'] logging.debug( From 5ca733eac0ec43ebd3ca68e867bfd6ef0fb30cc2 Mon Sep 17 00:00:00 2001 From: morpheus65535 Date: Fri, 24 May 2024 13:19:37 -0400 Subject: [PATCH 10/18] Reverted to apprise 1.7.6 to fix an issue with the upgrade process first. 1.8.0 will get back in nightly shortly. #2497 --- .../INSTALLER | 0 .../LICENSE | 0 .../METADATA | 2 +- libs/apprise-1.7.6.dist-info/RECORD | 183 ++++ .../REQUESTED | 0 .../WHEEL | 0 .../entry_points.txt | 0 .../top_level.txt | 0 libs/apprise-1.8.0.dist-info/RECORD | 183 ---- libs/apprise/Apprise.py | 887 ++++++++++++++++++ libs/apprise/Apprise.pyi | 62 ++ libs/apprise/{asset.py => AppriseAsset.py} | 2 +- libs/apprise/{asset.pyi => AppriseAsset.pyi} | 0 ...ise_attachment.py => AppriseAttachment.py} | 6 +- ...e_attachment.pyi => AppriseAttachment.pyi} | 0 .../{apprise_config.py => AppriseConfig.py} | 4 +- .../{apprise_config.pyi => AppriseConfig.pyi} | 0 libs/apprise/{locale.py => AppriseLocale.py} | 0 ...ger_attachment.py => AttachmentManager.py} | 5 - ...ager_config.py => ConfigurationManager.py} | 5 - ...ager_plugins.py => NotificationManager.py} | 6 - libs/apprise/{url.py => URLBase.py} | 9 +- libs/apprise/{url.pyi => URLBase.pyi} | 0 libs/apprise/__init__.py | 23 +- .../attachment/{base.py => AttachBase.py} | 9 +- .../attachment/{base.pyi => AttachBase.pyi} | 0 .../attachment/{file.py => AttachFile.py} | 4 +- .../attachment/{http.py => AttachHTTP.py} | 12 +- libs/apprise/attachment/__init__.py | 5 +- .../apprise/config/{base.py => ConfigBase.py} | 8 +- .../config/{base.pyi => ConfigBase.pyi} | 0 .../apprise/config/{file.py => ConfigFile.py} | 4 +- .../apprise/config/{http.py => ConfigHTTP.py} | 6 +- .../config/{memory.py => ConfigMemory.py} | 4 +- libs/apprise/config/__init__.py | 5 +- libs/apprise/conversion.py | 2 +- .../{base.py => CustomNotifyPlugin.py} | 7 +- libs/apprise/decorators/notify.py | 2 +- libs/apprise/i18n/en/LC_MESSAGES/apprise.mo | Bin 3959 -> 3959 bytes libs/apprise/manager.py | 83 +- .../{apprise_api.py => NotifyAppriseAPI.py} | 8 +- .../plugins/{aprs.py => NotifyAprs.py} | 6 +- .../plugins/{bark.py => NotifyBark.py} | 6 +- .../plugins/{base.py => NotifyBase.py} | 6 +- .../plugins/{base.pyi => NotifyBase.pyi} | 0 .../plugins/{boxcar.py => NotifyBoxcar.py} | 6 +- .../plugins/{bulksms.py => NotifyBulkSMS.py} | 6 +- .../plugins/{bulkvs.py => NotifyBulkVS.py} | 6 +- .../{burstsms.py => NotifyBurstSMS.py} | 6 +- .../{chantify.py => NotifyChantify.py} | 4 +- .../{clicksend.py => NotifyClickSend.py} | 27 +- .../{d7networks.py => NotifyD7Networks.py} | 4 +- .../plugins/{dbus.py => NotifyDBus.py} | 4 +- .../plugins/{dapnet.py => NotifyDapnet.py} | 6 +- .../{dingtalk.py => NotifyDingTalk.py} | 6 +- .../plugins/{discord.py => NotifyDiscord.py} | 6 +- .../plugins/{email.py => NotifyEmail.py} | 16 +- .../plugins/{emby.py => NotifyEmby.py} | 6 +- .../plugins/{enigma2.py => NotifyEnigma2.py} | 6 +- .../plugins/{fcm => NotifyFCM}/__init__.py | 6 +- .../plugins/{fcm => NotifyFCM}/color.py | 2 +- .../plugins/{fcm => NotifyFCM}/common.py | 0 .../plugins/{fcm => NotifyFCM}/oauth.py | 0 .../plugins/{fcm => NotifyFCM}/priority.py | 0 .../plugins/{feishu.py => NotifyFeishu.py} | 4 +- .../plugins/{flock.py => NotifyFlock.py} | 4 +- .../plugins/{custom_form.py => NotifyForm.py} | 6 +- .../{freemobile.py => NotifyFreeMobile.py} | 5 +- .../plugins/{gnome.py => NotifyGnome.py} | 4 +- .../{google_chat.py => NotifyGoogleChat.py} | 4 +- .../plugins/{gotify.py => NotifyGotify.py} | 4 +- .../plugins/{growl.py => NotifyGrowl.py} | 6 +- .../plugins/{guilded.py => NotifyGuilded.py} | 5 +- ...me_assistant.py => NotifyHomeAssistant.py} | 6 +- .../plugins/{httpsms.py => NotifyHttpSMS.py} | 4 +- .../plugins/{ifttt.py => NotifyIFTTT.py} | 4 +- .../plugins/{custom_json.py => NotifyJSON.py} | 6 +- .../plugins/{join.py => NotifyJoin.py} | 4 +- .../{kavenegar.py => NotifyKavenegar.py} | 4 +- .../plugins/{kumulos.py => NotifyKumulos.py} | 4 +- .../{lametric.py => NotifyLametric.py} | 4 +- .../plugins/{line.py => NotifyLine.py} | 6 +- .../plugins/{lunasea.py => NotifyLunaSea.py} | 6 +- .../plugins/{mqtt.py => NotifyMQTT.py} | 6 +- .../plugins/{msg91.py => NotifyMSG91.py} | 4 +- .../plugins/{msteams.py => NotifyMSTeams.py} | 6 +- .../plugins/{macosx.py => NotifyMacOSX.py} | 4 +- .../plugins/{mailgun.py => NotifyMailgun.py} | 4 +- .../{mastodon.py => NotifyMastodon.py} | 8 +- .../plugins/{matrix.py => NotifyMatrix.py} | 6 +- .../{mattermost.py => NotifyMattermost.py} | 4 +- .../{messagebird.py => NotifyMessageBird.py} | 4 +- .../plugins/{misskey.py => NotifyMisskey.py} | 4 +- .../{nextcloud.py => NotifyNextcloud.py} | 6 +- ...extcloudtalk.py => NotifyNextcloudTalk.py} | 6 +- .../plugins/{notica.py => NotifyNotica.py} | 6 +- .../{notifiarr.py => NotifyNotifiarr.py} | 4 +- .../{notifico.py => NotifyNotifico.py} | 4 +- .../plugins/{ntfy.py => NotifyNtfy.py} | 8 +- .../{office365.py => NotifyOffice365.py} | 6 +- .../{one_signal.py => NotifyOneSignal.py} | 4 +- .../{opsgenie.py => NotifyOpsgenie.py} | 4 +- .../{pagerduty.py => NotifyPagerDuty.py} | 6 +- .../{pagertree.py => NotifyPagerTree.py} | 4 +- ...arseplatform.py => NotifyParsePlatform.py} | 4 +- ...pcorn_notify.py => NotifyPopcornNotify.py} | 4 +- .../plugins/{prowl.py => NotifyProwl.py} | 4 +- .../{pushbullet.py => NotifyPushBullet.py} | 6 +- .../{pushdeer.py => NotifyPushDeer.py} | 4 +- .../plugins/{pushme.py => NotifyPushMe.py} | 4 +- .../{pushsafer.py => NotifyPushSafer.py} | 4 +- .../plugins/{pushed.py => NotifyPushed.py} | 6 +- .../plugins/{pushjet.py => NotifyPushjet.py} | 6 +- .../{pushover.py => NotifyPushover.py} | 6 +- .../plugins/{pushy.py => NotifyPushy.py} | 4 +- .../plugins/{rsyslog.py => NotifyRSyslog.py} | 4 +- .../plugins/{reddit.py => NotifyReddit.py} | 6 +- .../plugins/{revolt.py => NotifyRevolt.py} | 4 +- .../{rocketchat.py => NotifyRocketChat.py} | 6 +- .../plugins/{ryver.py => NotifyRyver.py} | 4 +- libs/apprise/plugins/{ses.py => NotifySES.py} | 6 +- .../{smseagle.py => NotifySMSEagle.py} | 6 +- .../{smsmanager.py => NotifySMSManager.py} | 4 +- .../plugins/{smtp2go.py => NotifySMTP2Go.py} | 4 +- libs/apprise/plugins/{sns.py => NotifySNS.py} | 6 +- .../{sendgrid.py => NotifySendGrid.py} | 4 +- .../{serverchan.py => NotifyServerChan.py} | 4 +- .../{signal_api.py => NotifySignalAPI.py} | 6 +- .../{simplepush.py => NotifySimplePush.py} | 6 +- .../plugins/{sinch.py => NotifySinch.py} | 6 +- .../plugins/{slack.py => NotifySlack.py} | 4 +- .../{sparkpost.py => NotifySparkPost.py} | 4 +- .../{streamlabs.py => NotifyStreamlabs.py} | 4 +- .../{synology.py => NotifySynology.py} | 6 +- .../plugins/{syslog.py => NotifySyslog.py} | 4 +- ...{techuluspush.py => NotifyTechulusPush.py} | 4 +- .../{telegram.py => NotifyTelegram.py} | 6 +- .../plugins/{threema.py => NotifyThreema.py} | 6 +- .../plugins/{twilio.py => NotifyTwilio.py} | 6 +- .../plugins/{twist.py => NotifyTwist.py} | 6 +- .../plugins/{twitter.py => NotifyTwitter.py} | 8 +- .../plugins/{voipms.py => NotifyVoipms.py} | 4 +- .../plugins/{vonage.py => NotifyVonage.py} | 6 +- .../{wecombot.py => NotifyWeComBot.py} | 4 +- .../{webexteams.py => NotifyWebexTeams.py} | 4 +- .../{whatsapp.py => NotifyWhatsApp.py} | 4 +- .../plugins/{windows.py => NotifyWindows.py} | 4 +- .../plugins/{xbmc.py => NotifyXBMC.py} | 6 +- .../plugins/{custom_xml.py => NotifyXML.py} | 6 +- .../plugins/{zulip.py => NotifyZulip.py} | 4 +- libs/apprise/plugins/__init__.py | 8 +- libs/apprise/utils.py | 13 +- libs/version.txt | 2 +- 153 files changed, 1511 insertions(+), 609 deletions(-) rename libs/{apprise-1.8.0.dist-info => apprise-1.7.6.dist-info}/INSTALLER (100%) rename libs/{apprise-1.8.0.dist-info => apprise-1.7.6.dist-info}/LICENSE (100%) rename libs/{apprise-1.8.0.dist-info => apprise-1.7.6.dist-info}/METADATA (99%) create mode 100644 libs/apprise-1.7.6.dist-info/RECORD rename libs/{apprise-1.8.0.dist-info => apprise-1.7.6.dist-info}/REQUESTED (100%) rename libs/{apprise-1.8.0.dist-info => apprise-1.7.6.dist-info}/WHEEL (100%) rename libs/{apprise-1.8.0.dist-info => apprise-1.7.6.dist-info}/entry_points.txt (100%) rename libs/{apprise-1.8.0.dist-info => apprise-1.7.6.dist-info}/top_level.txt (100%) delete mode 100644 libs/apprise-1.8.0.dist-info/RECORD create mode 100644 libs/apprise/Apprise.py create mode 100644 libs/apprise/Apprise.pyi rename libs/apprise/{asset.py => AppriseAsset.py} (99%) rename libs/apprise/{asset.pyi => AppriseAsset.pyi} (100%) rename libs/apprise/{apprise_attachment.py => AppriseAttachment.py} (98%) rename libs/apprise/{apprise_attachment.pyi => AppriseAttachment.pyi} (100%) rename libs/apprise/{apprise_config.py => AppriseConfig.py} (99%) rename libs/apprise/{apprise_config.pyi => AppriseConfig.pyi} (100%) rename libs/apprise/{locale.py => AppriseLocale.py} (100%) rename libs/apprise/{manager_attachment.py => AttachmentManager.py} (93%) rename libs/apprise/{manager_config.py => ConfigurationManager.py} (93%) rename libs/apprise/{manager_plugins.py => NotificationManager.py} (92%) rename libs/apprise/{url.py => URLBase.py} (99%) rename libs/apprise/{url.pyi => URLBase.pyi} (100%) rename libs/apprise/attachment/{base.py => AttachBase.py} (98%) rename libs/apprise/attachment/{base.pyi => AttachBase.pyi} (100%) rename libs/apprise/attachment/{file.py => AttachFile.py} (98%) rename libs/apprise/attachment/{http.py => AttachHTTP.py} (98%) rename libs/apprise/config/{base.py => ConfigBase.py} (99%) rename libs/apprise/config/{base.pyi => ConfigBase.pyi} (100%) rename libs/apprise/config/{file.py => ConfigFile.py} (98%) rename libs/apprise/config/{http.py => ConfigHTTP.py} (98%) rename libs/apprise/config/{memory.py => ConfigMemory.py} (97%) rename libs/apprise/decorators/{base.py => CustomNotifyPlugin.py} (98%) rename libs/apprise/plugins/{apprise_api.py => NotifyAppriseAPI.py} (99%) rename libs/apprise/plugins/{aprs.py => NotifyAprs.py} (99%) rename libs/apprise/plugins/{bark.py => NotifyBark.py} (99%) rename libs/apprise/plugins/{base.py => NotifyBase.py} (99%) rename libs/apprise/plugins/{base.pyi => NotifyBase.pyi} (100%) rename libs/apprise/plugins/{boxcar.py => NotifyBoxcar.py} (99%) rename libs/apprise/plugins/{bulksms.py => NotifyBulkSMS.py} (99%) rename libs/apprise/plugins/{bulkvs.py => NotifyBulkVS.py} (99%) rename libs/apprise/plugins/{burstsms.py => NotifyBurstSMS.py} (99%) rename libs/apprise/plugins/{chantify.py => NotifyChantify.py} (98%) rename libs/apprise/plugins/{clicksend.py => NotifyClickSend.py} (94%) rename libs/apprise/plugins/{d7networks.py => NotifyD7Networks.py} (99%) rename libs/apprise/plugins/{dbus.py => NotifyDBus.py} (99%) rename libs/apprise/plugins/{dapnet.py => NotifyDapnet.py} (99%) rename libs/apprise/plugins/{dingtalk.py => NotifyDingTalk.py} (99%) rename libs/apprise/plugins/{discord.py => NotifyDiscord.py} (99%) rename libs/apprise/plugins/{email.py => NotifyEmail.py} (98%) rename libs/apprise/plugins/{emby.py => NotifyEmby.py} (99%) rename libs/apprise/plugins/{enigma2.py => NotifyEnigma2.py} (98%) rename libs/apprise/plugins/{fcm => NotifyFCM}/__init__.py (99%) rename libs/apprise/plugins/{fcm => NotifyFCM}/color.py (99%) rename libs/apprise/plugins/{fcm => NotifyFCM}/common.py (100%) rename libs/apprise/plugins/{fcm => NotifyFCM}/oauth.py (100%) rename libs/apprise/plugins/{fcm => NotifyFCM}/priority.py (100%) rename libs/apprise/plugins/{feishu.py => NotifyFeishu.py} (98%) rename libs/apprise/plugins/{flock.py => NotifyFlock.py} (99%) rename libs/apprise/plugins/{custom_form.py => NotifyForm.py} (99%) rename libs/apprise/plugins/{freemobile.py => NotifyFreeMobile.py} (98%) rename libs/apprise/plugins/{gnome.py => NotifyGnome.py} (99%) rename libs/apprise/plugins/{google_chat.py => NotifyGoogleChat.py} (99%) rename libs/apprise/plugins/{gotify.py => NotifyGotify.py} (99%) rename libs/apprise/plugins/{growl.py => NotifyGrowl.py} (99%) rename libs/apprise/plugins/{guilded.py => NotifyGuilded.py} (96%) rename libs/apprise/plugins/{home_assistant.py => NotifyHomeAssistant.py} (98%) rename libs/apprise/plugins/{httpsms.py => NotifyHttpSMS.py} (99%) rename libs/apprise/plugins/{ifttt.py => NotifyIFTTT.py} (99%) rename libs/apprise/plugins/{custom_json.py => NotifyJSON.py} (99%) rename libs/apprise/plugins/{join.py => NotifyJoin.py} (99%) rename libs/apprise/plugins/{kavenegar.py => NotifyKavenegar.py} (99%) rename libs/apprise/plugins/{kumulos.py => NotifyKumulos.py} (99%) rename libs/apprise/plugins/{lametric.py => NotifyLametric.py} (99%) rename libs/apprise/plugins/{line.py => NotifyLine.py} (98%) rename libs/apprise/plugins/{lunasea.py => NotifyLunaSea.py} (99%) rename libs/apprise/plugins/{mqtt.py => NotifyMQTT.py} (99%) rename libs/apprise/plugins/{msg91.py => NotifyMSG91.py} (99%) rename libs/apprise/plugins/{msteams.py => NotifyMSTeams.py} (99%) rename libs/apprise/plugins/{macosx.py => NotifyMacOSX.py} (99%) rename libs/apprise/plugins/{mailgun.py => NotifyMailgun.py} (99%) rename libs/apprise/plugins/{mastodon.py => NotifyMastodon.py} (99%) rename libs/apprise/plugins/{matrix.py => NotifyMatrix.py} (99%) rename libs/apprise/plugins/{mattermost.py => NotifyMattermost.py} (99%) rename libs/apprise/plugins/{messagebird.py => NotifyMessageBird.py} (99%) rename libs/apprise/plugins/{misskey.py => NotifyMisskey.py} (99%) rename libs/apprise/plugins/{nextcloud.py => NotifyNextcloud.py} (99%) rename libs/apprise/plugins/{nextcloudtalk.py => NotifyNextcloudTalk.py} (98%) rename libs/apprise/plugins/{notica.py => NotifyNotica.py} (99%) rename libs/apprise/plugins/{notifiarr.py => NotifyNotifiarr.py} (99%) rename libs/apprise/plugins/{notifico.py => NotifyNotifico.py} (99%) rename libs/apprise/plugins/{ntfy.py => NotifyNtfy.py} (99%) rename libs/apprise/plugins/{office365.py => NotifyOffice365.py} (99%) rename libs/apprise/plugins/{one_signal.py => NotifyOneSignal.py} (99%) rename libs/apprise/plugins/{opsgenie.py => NotifyOpsgenie.py} (99%) rename libs/apprise/plugins/{pagerduty.py => NotifyPagerDuty.py} (99%) rename libs/apprise/plugins/{pagertree.py => NotifyPagerTree.py} (99%) rename libs/apprise/plugins/{parseplatform.py => NotifyParsePlatform.py} (99%) rename libs/apprise/plugins/{popcorn_notify.py => NotifyPopcornNotify.py} (99%) rename libs/apprise/plugins/{prowl.py => NotifyProwl.py} (99%) rename libs/apprise/plugins/{pushbullet.py => NotifyPushBullet.py} (99%) rename libs/apprise/plugins/{pushdeer.py => NotifyPushDeer.py} (98%) rename libs/apprise/plugins/{pushme.py => NotifyPushMe.py} (98%) rename libs/apprise/plugins/{pushsafer.py => NotifyPushSafer.py} (99%) rename libs/apprise/plugins/{pushed.py => NotifyPushed.py} (99%) rename libs/apprise/plugins/{pushjet.py => NotifyPushjet.py} (98%) rename libs/apprise/plugins/{pushover.py => NotifyPushover.py} (99%) rename libs/apprise/plugins/{pushy.py => NotifyPushy.py} (99%) rename libs/apprise/plugins/{rsyslog.py => NotifyRSyslog.py} (99%) rename libs/apprise/plugins/{reddit.py => NotifyReddit.py} (99%) rename libs/apprise/plugins/{revolt.py => NotifyRevolt.py} (99%) rename libs/apprise/plugins/{rocketchat.py => NotifyRocketChat.py} (99%) rename libs/apprise/plugins/{ryver.py => NotifyRyver.py} (99%) rename libs/apprise/plugins/{ses.py => NotifySES.py} (99%) rename libs/apprise/plugins/{smseagle.py => NotifySMSEagle.py} (99%) rename libs/apprise/plugins/{smsmanager.py => NotifySMSManager.py} (99%) rename libs/apprise/plugins/{smtp2go.py => NotifySMTP2Go.py} (99%) rename libs/apprise/plugins/{sns.py => NotifySNS.py} (99%) rename libs/apprise/plugins/{sendgrid.py => NotifySendGrid.py} (99%) rename libs/apprise/plugins/{serverchan.py => NotifyServerChan.py} (98%) rename libs/apprise/plugins/{signal_api.py => NotifySignalAPI.py} (99%) rename libs/apprise/plugins/{simplepush.py => NotifySimplePush.py} (98%) rename libs/apprise/plugins/{sinch.py => NotifySinch.py} (99%) rename libs/apprise/plugins/{slack.py => NotifySlack.py} (99%) rename libs/apprise/plugins/{sparkpost.py => NotifySparkPost.py} (99%) rename libs/apprise/plugins/{streamlabs.py => NotifyStreamlabs.py} (99%) rename libs/apprise/plugins/{synology.py => NotifySynology.py} (98%) rename libs/apprise/plugins/{syslog.py => NotifySyslog.py} (99%) rename libs/apprise/plugins/{techuluspush.py => NotifyTechulusPush.py} (98%) rename libs/apprise/plugins/{telegram.py => NotifyTelegram.py} (99%) rename libs/apprise/plugins/{threema.py => NotifyThreema.py} (99%) rename libs/apprise/plugins/{twilio.py => NotifyTwilio.py} (99%) rename libs/apprise/plugins/{twist.py => NotifyTwist.py} (99%) rename libs/apprise/plugins/{twitter.py => NotifyTwitter.py} (99%) rename libs/apprise/plugins/{voipms.py => NotifyVoipms.py} (99%) rename libs/apprise/plugins/{vonage.py => NotifyVonage.py} (99%) rename libs/apprise/plugins/{wecombot.py => NotifyWeComBot.py} (99%) rename libs/apprise/plugins/{webexteams.py => NotifyWebexTeams.py} (99%) rename libs/apprise/plugins/{whatsapp.py => NotifyWhatsApp.py} (99%) rename libs/apprise/plugins/{windows.py => NotifyWindows.py} (99%) rename libs/apprise/plugins/{xbmc.py => NotifyXBMC.py} (99%) rename libs/apprise/plugins/{custom_xml.py => NotifyXML.py} (99%) rename libs/apprise/plugins/{zulip.py => NotifyZulip.py} (99%) diff --git a/libs/apprise-1.8.0.dist-info/INSTALLER b/libs/apprise-1.7.6.dist-info/INSTALLER similarity index 100% rename from libs/apprise-1.8.0.dist-info/INSTALLER rename to libs/apprise-1.7.6.dist-info/INSTALLER diff --git a/libs/apprise-1.8.0.dist-info/LICENSE b/libs/apprise-1.7.6.dist-info/LICENSE similarity index 100% rename from libs/apprise-1.8.0.dist-info/LICENSE rename to libs/apprise-1.7.6.dist-info/LICENSE diff --git a/libs/apprise-1.8.0.dist-info/METADATA b/libs/apprise-1.7.6.dist-info/METADATA similarity index 99% rename from libs/apprise-1.8.0.dist-info/METADATA rename to libs/apprise-1.7.6.dist-info/METADATA index c01ef211a..ac7cb9aac 100644 --- a/libs/apprise-1.8.0.dist-info/METADATA +++ b/libs/apprise-1.7.6.dist-info/METADATA @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: apprise -Version: 1.8.0 +Version: 1.7.6 Summary: Push Notifications that work with just about every platform! Home-page: https://github.com/caronc/apprise Author: Chris Caron diff --git a/libs/apprise-1.7.6.dist-info/RECORD b/libs/apprise-1.7.6.dist-info/RECORD new file mode 100644 index 000000000..250648105 --- /dev/null +++ b/libs/apprise-1.7.6.dist-info/RECORD @@ -0,0 +1,183 @@ +../../bin/apprise,sha256=ZJ-e4qqxNLtdW_DAvpuPPX5iROIiQd8I6nvg7vtAv-g,233 +apprise-1.7.6.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +apprise-1.7.6.dist-info/LICENSE,sha256=gt7qKBxRhVcdmXCYVtrWP6DtYjD0DzONet600dkU994,1343 +apprise-1.7.6.dist-info/METADATA,sha256=z_gaX2IdNJqw4T9q7AYQri9jcIs-OTGCo3t2EgEY-mw,44823 +apprise-1.7.6.dist-info/RECORD,, +apprise-1.7.6.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +apprise-1.7.6.dist-info/WHEEL,sha256=Xo9-1PvkuimrydujYJAjF7pCkriuXBpUPEjma1nZyJ0,92 +apprise-1.7.6.dist-info/entry_points.txt,sha256=71YypBuNdjAKiaLsiMG40HEfLHxkU4Mi7o_S0s0d8wI,45 +apprise-1.7.6.dist-info/top_level.txt,sha256=JrCRn-_rXw5LMKXkIgMSE4E0t1Ks9TYrBH54Pflwjkk,8 +apprise/Apprise.py,sha256=Stm2NhJprWRaMwQfTiIQG_nR1bLpHi_zcdwEcsCpa-A,32865 +apprise/Apprise.pyi,sha256=_4TBKvT-QVj3s6PuTh3YX-BbQMeJTdBGdVpubLMY4_k,2203 +apprise/AppriseAsset.py,sha256=jRW8Y1EcAvjVA9h_mINmsjO4DM3S0aDl6INIFVMcUCs,11647 +apprise/AppriseAsset.pyi,sha256=NYLXXYbScgRkspP27XGpRRM_uliPu1OCdWdZBPPvLng,979 +apprise/AppriseAttachment.py,sha256=vhrktSrp8GLr32aK4KqV6BX83IpI1lxZe-pGo1wiSFM,12540 +apprise/AppriseAttachment.pyi,sha256=R9-0dVqWpeaFrVpcREwPhGy3qHWztG5jEjYIOsbE5dM,1145 +apprise/AppriseConfig.py,sha256=wfuR6Mb3ZLHvjvqWdFp9lVmjjDRWs65unY9qa92RkCg,16909 +apprise/AppriseConfig.pyi,sha256=_mUlCnncqAq8sL01WxQTgZjnb2ic9kZXvtqZmVl-fc8,1568 +apprise/AppriseLocale.py,sha256=4uSr4Nj_rz6ISMMAfRVRk58wZVLKOofJgk2x0_E8NkQ,8994 +apprise/AttachmentManager.py,sha256=EwlnjuKn3fv_pioWcmMCkyDTsO178t6vkEOD8AjAPsw,2053 +apprise/ConfigurationManager.py,sha256=MUmGajxjgnr6FGN7xb3q0nD0VVgdTdvapBBR7CsI-rc,2058 +apprise/NotificationManager.py,sha256=ZJgkiCgcJ7Bz_6bwQ47flrcxvLMbA4Vbw0HG_yTsGdE,2041 +apprise/URLBase.py,sha256=xRP0-blocp9UudYh04Hb3fIEmTZWJaTv_tzjrqaB9fg,29423 +apprise/URLBase.pyi,sha256=WLaRREH7FzZ5x3-qkDkupojWGFC4uFwJ1EDt02lVs8c,520 +apprise/__init__.py,sha256=ArtvoarAMnBcSfXF7L_hzq5CUJ9TUnHopiC7xafCe3c,3368 +apprise/assets/NotifyXML-1.0.xsd,sha256=292qQ_IUl5EWDhPyzm9UTT0C2rVvJkyGar8jiODkJs8,986 +apprise/assets/NotifyXML-1.1.xsd,sha256=bjR3CGG4AEXoJjYkGCbDttKHSkPP1FlIWO02E7G59g4,1758 +apprise/assets/themes/default/apprise-failure-128x128.ico,sha256=Mt0ptfHJaN3Wsv5UCNDn9_3lyEDHxVDv1JdaDEI_xCA,67646 +apprise/assets/themes/default/apprise-failure-128x128.png,sha256=66ps8TDPxVH3g9PlObJqF-0x952CjnqQyN3zvpRcOT8,16135 +apprise/assets/themes/default/apprise-failure-256x256.png,sha256=bQBsKKCsKfR9EqgYOZrcVcVa5y8qG58PN2mEqO5eNRI,41931 +apprise/assets/themes/default/apprise-failure-32x32.png,sha256=vH0pZffIDCvkejpr3fJHGXW__8Yc3R_p0bacX6t6l18,2437 +apprise/assets/themes/default/apprise-failure-72x72.png,sha256=EP5A8DHRDr9srgupFSwOoyQ308bNJ8aL192J_L4K-ec,7600 +apprise/assets/themes/default/apprise-info-128x128.ico,sha256=F5_CirmXueRCRI5Z_Crf6TS6jVIXTJlRD83zw1oJ66g,67646 +apprise/assets/themes/default/apprise-info-128x128.png,sha256=bBqRZAgQey-gkmJrnFhPbzjILSrljE59mRkgj3raMQo,16671 +apprise/assets/themes/default/apprise-info-256x256.png,sha256=B5r_O4d9MHCmSWZwfbqQgZSp-ZetTdiBSwKcMTF1aFA,43331 +apprise/assets/themes/default/apprise-info-32x32.png,sha256=lt3NZ95TzkiCNVNlurrB2fE2nriMa1wftl7nrNXmb6c,2485 +apprise/assets/themes/default/apprise-info-72x72.png,sha256=kDnsZpqNUZGqs9t1ECUup7FOfXUIL-rupnQCYJp9So4,7875 +apprise/assets/themes/default/apprise-logo.png,sha256=85ttALudKkLmiqilJT7mUQLUXRFmM1AK89rnwLm313s,160907 +apprise/assets/themes/default/apprise-success-128x128.ico,sha256=uCopPwdQjxgfohKazHaDzYs9y4oiaOpL048PYC6WRlg,67646 +apprise/assets/themes/default/apprise-success-128x128.png,sha256=nvDuU_QqhGlw6cMtdj7Mv-gPgqCEx-0DaaXn1KBLVYg,17446 +apprise/assets/themes/default/apprise-success-256x256.png,sha256=vXfKuxY3n0eeXHKdb9hTxICxOEn7HjAQ4IZpX0HSLzc,48729 +apprise/assets/themes/default/apprise-success-32x32.png,sha256=Jg9pFJh3YPI-LiPBebyJ7Z4Vt7BRecaE8AsRjQVIkME,2471 +apprise/assets/themes/default/apprise-success-72x72.png,sha256=FQbgvIhqKOhEK0yvrhaSpai0R7hrkTt_-GaC2KUgCCk,7858 +apprise/assets/themes/default/apprise-warning-128x128.ico,sha256=6XaQPOx0oWK_xbhr4Yhb7qNazCWwSs9lk2SYR2MHTrQ,67646 +apprise/assets/themes/default/apprise-warning-128x128.png,sha256=pf5c4Ph7jWH7gf39dJoieSj8TzAsY3TXI-sGISGVIW4,16784 +apprise/assets/themes/default/apprise-warning-256x256.png,sha256=SY-xlaiXaj420iEYKC2_fJxU-yj2SuaQg6xfPNi83bw,43708 +apprise/assets/themes/default/apprise-warning-32x32.png,sha256=97R2ywNvcwczhBoWEIgajVtWjgT8fLs4FCCz4wu0dwc,2472 +apprise/assets/themes/default/apprise-warning-72x72.png,sha256=L8moEInkO_OLxoOcuvN7rmrGZo64iJeH20o-24MQghE,7913 +apprise/attachment/AttachBase.py,sha256=T3WreGrTsqqGplXJO36jm-N14X7ymSc9xt7XdTYuXVE,13656 +apprise/attachment/AttachBase.pyi,sha256=w0XG_QKauiMLJ7eQ4S57IiLIURZHm_Snw7l6-ih9GP8,961 +apprise/attachment/AttachFile.py,sha256=MbHY_av0GeM_AIBKV02Hq7SHiZ9eCr1yTfvDMUgi2I4,4765 +apprise/attachment/AttachHTTP.py,sha256=_CMPp4QGLATfGO2-Nw57sxsQyed9z3ywgoB0vpK3KZk,13779 +apprise/attachment/__init__.py,sha256=xabgXpvV05X-YRuqIt3uGYMXwYNXjHyF6Dwd8HfZCFE,1658 +apprise/cli.py,sha256=h-pWSQPqQficH6J-OEp3MTGydWyt6vMYnDZvHCeAt4Y,20697 +apprise/common.py,sha256=I6wfrndggCL7l7KAl7Cm4uwAX9n0l3SN4-BVvTE0L0M,5593 +apprise/common.pyi,sha256=luF3QRiClDCk8Z23rI6FCGYsVmodOt_JYfYyzGogdNM,447 +apprise/config/ConfigBase.py,sha256=d1efIuQFCJr66WgpudV2DWtxY3-tuZAyMAhHXBzJ8p0,53194 +apprise/config/ConfigBase.pyi,sha256=cngfobwH6v2vxYbQrObDi5Z-t5wcquWF-wR0kBCr3Eg,54 +apprise/config/ConfigFile.py,sha256=u_SDaN3OHMyaAq2X7k_T4_PRKkVsDwleqBz9YIN5lbA,6138 +apprise/config/ConfigHTTP.py,sha256=Iy6Ji8_nX3xDjFgJGLrz4ftrMlMiyKiFGzYGJ7rMSMQ,9457 +apprise/config/ConfigMemory.py,sha256=epEAgNy-eJVWoQaUOvjivMWxXTofy6wAQ-NbCqYmuyE,2829 +apprise/config/__init__.py,sha256=lbsxrUpB1IYM2q7kjYhsXQGgPF-yZXJrKFE361tdIPY,1663 +apprise/conversion.py,sha256=0VZ0eCZfksN-97Vl0TjVjwnCTgus3XTRioceSFnP-gc,6277 +apprise/decorators/CustomNotifyPlugin.py,sha256=i4D-sgOsBWsxO5auWCN2bgXLLPuADaaLlJ1gUKLj2bU,7972 +apprise/decorators/__init__.py,sha256=e_PDAm0kQNzwDPx-NJZLPfLMd2VAABvNZtxx_iDviRM,1487 +apprise/decorators/notify.py,sha256=a2WupErNw1_SMAld7jPC273bskiChMpYy95BOog5A9w,5111 +apprise/emojis.py,sha256=ONF0t8dY9f2XlEkLUG79-ybKVAj2GqbPj2-Be97vAoI,87738 +apprise/i18n/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +apprise/i18n/en/LC_MESSAGES/apprise.mo,sha256=oUTuHREmLEYN07oqYqRMJ_kU71-o5o37NsF4RXlC5AU,3959 +apprise/logger.py,sha256=131hqhed8cUj9x_mfXDEvwA2YbcYDFAYiWVK1HgxRVY,6921 +apprise/manager.py,sha256=R9w8jxQRNy6Z_XDcobkt4JYbrC4jtj2OwRw9Zrib3CA,26857 +apprise/plugins/NotifyAppriseAPI.py,sha256=ISBE0brD3eQdyw3XrGXd4Uc4kSYvIuI3SSUVCt-bkdo,16654 +apprise/plugins/NotifyAprs.py,sha256=xdL_aIVgb4ggxRFeCdkZAbgHYZ8DWLw9pRpLZQ0rHoE,25523 +apprise/plugins/NotifyBark.py,sha256=bsDvKooRy4k1Gg7tvBjv3DIx7-WZiV_mbTrkTwMtd9Q,15698 +apprise/plugins/NotifyBase.py,sha256=G3xkF_a2BWqNSxsrnOW7NUgHjOqBCYC5zihCifWemo8,30360 +apprise/plugins/NotifyBase.pyi,sha256=aKlZXRYUgG8lz_ZgGkYYJ_GKhuf18youTmMU-FlG7z8,21 +apprise/plugins/NotifyBoxcar.py,sha256=vR00-WggHa1nHYWyb-f5P2V-G4f683fU_-GBlIeJvD0,12867 +apprise/plugins/NotifyBulkSMS.py,sha256=stPWAFCfhBP617zYK9Dgk6pNJBN_WcyJtODzo0jR1QQ,16005 +apprise/plugins/NotifyBulkVS.py,sha256=viLGeyUDiirRRM7CgRqqElHSLYFnMugDtWE6Ytjqfaw,13290 +apprise/plugins/NotifyBurstSMS.py,sha256=cN2kRETKIK5LhwpQEA8C68LKv8KEUPmXYe-nTSegGls,15550 +apprise/plugins/NotifyChantify.py,sha256=GJJOAtSnVoIfKbJF_W1DTu7WsvS_zHdjO4T1XTKT87g,6673 +apprise/plugins/NotifyClickSend.py,sha256=UfOJqsas6WLjQskojuJE7I_-lrb5QrkMiBZv-po_Q9c,11229 +apprise/plugins/NotifyD7Networks.py,sha256=4E6Fh0kQoDlMMwgZJDOXky7c7KrdMMvqprcfm29scWU,15043 +apprise/plugins/NotifyDBus.py,sha256=1eVJHIL3XkFjDePMqfcll35Ie1vxggJ1iBsVFAIaF00,14379 +apprise/plugins/NotifyDapnet.py,sha256=KuXjBU0ZrIYtoDei85NeLZ-IP810T4w5oFXH9sWiSh0,13624 +apprise/plugins/NotifyDingTalk.py,sha256=NJyETgN6QjtRqtxQjfBLFVuFpURyWykRftm6WpQJVbY,12009 +apprise/plugins/NotifyDiscord.py,sha256=M_qmTzB7NNL5_agjYDX38KBN1jRzDBp2EMSNwEF_9Tw,26072 +apprise/plugins/NotifyEmail.py,sha256=Y_ZOrdK6hTUKHLvogKpV5VqD8byzDyDSvwIVmfdsC2g,39789 +apprise/plugins/NotifyEmby.py,sha256=OMVO8XsVl_XCBYNNNQi8ni2lS4voLfU8Puk1xJOAvHs,24039 +apprise/plugins/NotifyEnigma2.py,sha256=Hj0Q9YOeljSwbfiuMKLqXTVX_1g_mjNUGEts7wfrwno,11498 +apprise/plugins/NotifyFCM/__init__.py,sha256=mBFtIgIJuLIFnMB5ndx5Makjs9orVMc2oLoD7LaVT48,21669 +apprise/plugins/NotifyFCM/color.py,sha256=8iqDtadloQh2TMxkFmIFwenHqKp1pHHn1bwyWOzZ6TY,4592 +apprise/plugins/NotifyFCM/common.py,sha256=978uBUoNdtopCtylipGiKQdsQ8FTONxkFBp7uJMZHc8,1718 +apprise/plugins/NotifyFCM/oauth.py,sha256=Vvbd0-rd5BPIjAneG3rILU153JIzfSZ0kaDov6hm96M,11197 +apprise/plugins/NotifyFCM/priority.py,sha256=0WuRW1y1HVnybgjlTeCZPHzt7j8SwWnC7faNcjioAOc,8163 +apprise/plugins/NotifyFeishu.py,sha256=IpcABdLZJ1vcQdZHlmASVbNOiOCIrmgKFhz1hbdskY4,7266 +apprise/plugins/NotifyFlock.py,sha256=0rUIa9nToGsO8BTUgixh8Z_qdVixJeH479UNYjcE4EM,12748 +apprise/plugins/NotifyForm.py,sha256=38nL-2m1cf4gEQFQ4NpvA4j9i5_nNUgelReWFSjyV5U,17905 +apprise/plugins/NotifyFreeMobile.py,sha256=XCkgZLc3KKGlx_9UdeoMJVcHpeQrOml9T93S-DGf4bs,6644 +apprise/plugins/NotifyGnome.py,sha256=8MXTa8gZg1wTgNJfLlmq7_fl3WaYK-SX6VR91u308C4,9059 +apprise/plugins/NotifyGoogleChat.py,sha256=lnoN17m6lZANaXcElDTP8lcuVWjIZEK8C6_iqJNAnw4,12622 +apprise/plugins/NotifyGotify.py,sha256=DNlOIHyuYitO5use9oa_REPm2Fant7y9QSaatrZFNI0,10551 +apprise/plugins/NotifyGrowl.py,sha256=M6ViUz967VhEHtXrE7lbCKF3aB4pIXNEzJLjjGAmvhM,14023 +apprise/plugins/NotifyGuilded.py,sha256=eCMCoFFuE0XNY8HlLM21zoxgBNgqEKQ8dwYj8LihfRU,3641 +apprise/plugins/NotifyHomeAssistant.py,sha256=zqWu7TtdXhTbGNuflC8WfydbHsCLiEBw4uBUcF7YZtw,10739 +apprise/plugins/NotifyHttpSMS.py,sha256=pDEUHCCB18IhOgDcVK3_FFDJdAcrdTIfPzj0jNnZZBo,11136 +apprise/plugins/NotifyIFTTT.py,sha256=oMvTQ0bEu2eJQgw9BwxAwTNOtbZ_ER-zleJvWpWTj7w,13425 +apprise/plugins/NotifyJSON.py,sha256=70ctjmArGzuvM1gHNt1bCiQVWE7Fp9vd2nWhSXwFvw0,13851 +apprise/plugins/NotifyJoin.py,sha256=B8FHp7cblZBkxTgfrka6mNnf6oQVBXVuGISgSau00z0,13581 +apprise/plugins/NotifyKavenegar.py,sha256=F5xTUdebM1lK6yGFbZJQB9Zgw2LTI0angeA-3Nu-89w,12620 +apprise/plugins/NotifyKumulos.py,sha256=eCEW2ZverZqETOLHVWMC4E8Ll6rEhhEWOSD73RD80SM,8214 +apprise/plugins/NotifyLametric.py,sha256=h8vZoX-Ll5NBZRprBlxTO2H9w0lOiMxglGvUgJtK4_8,37534 +apprise/plugins/NotifyLine.py,sha256=OVI0ozMJcq_-dI8dodVX52dzUzgENlAbOik-Kw4l-rI,10676 +apprise/plugins/NotifyLunaSea.py,sha256=woN8XdkwAjhgxAXp7Zj4XsWLybNL80l4W3Dx5BvobZg,14459 +apprise/plugins/NotifyMQTT.py,sha256=cnuG4f3bYYNPhEj9qDX8SLmnxLVT9G1b8J5w6-mQGKY,19545 +apprise/plugins/NotifyMSG91.py,sha256=P7JPyT1xmucnaEeCZPf_6aJfe1gS_STYYwEM7hJ7QBw,12677 +apprise/plugins/NotifyMSTeams.py,sha256=dFH575hoLL3zRddbBKfozlYjxvPJGbj3BKvfJSIkvD0,22976 +apprise/plugins/NotifyMacOSX.py,sha256=y2fGpSZXomFiNwKbWImrXQUMVM4JR4uPCnsWpnxQrFA,8271 +apprise/plugins/NotifyMailgun.py,sha256=FNS_QLOQWMo62yVO-mMZkpiXudUtSdbHOjfSrLC4oIo,25409 +apprise/plugins/NotifyMastodon.py,sha256=2ovjQIOOITHH8lOinC8QCFCJN2QA8foIM2pjdknbblc,35277 +apprise/plugins/NotifyMatrix.py,sha256=I8kdaZUZS-drew0JExBbChQVe7Ib4EwAjQd0xE30XT0,50049 +apprise/plugins/NotifyMattermost.py,sha256=JgEc-wC-43FBMItezDJ62zv1Nc9ROFjDiwD_8bt8rgM,12722 +apprise/plugins/NotifyMessageBird.py,sha256=EUPwhs1PHiPZpluIrLiNKQMUPcdlKnx1sdnllCtN_Ns,12248 +apprise/plugins/NotifyMisskey.py,sha256=zYZkBKv0p3jJpm_HLDBugUgKeGb0qpLoPqy0ffwwxVg,9600 +apprise/plugins/NotifyNextcloud.py,sha256=M3EyvUzBMHbTKU3gxW_7fPA6vmQUF5x8GTMZQ78sWCA,12759 +apprise/plugins/NotifyNextcloudTalk.py,sha256=dLl_g7Knq5PVcadbzDuQsxbGHTZlC4r-pQC8wzYnmAo,11011 +apprise/plugins/NotifyNotica.py,sha256=yHmk8HiNFjzoI4Gewo_nBRrx9liEmhT95k1d10wqhYg,12990 +apprise/plugins/NotifyNotifiarr.py,sha256=ADwLJO9eenfLkNa09tXMGSBTM4c3zTY0SEePvyB8WYA,15857 +apprise/plugins/NotifyNotifico.py,sha256=Qe9jMN_M3GL4XlYIWkAf-w_Hf65g9Hde4bVuytGhUW4,12035 +apprise/plugins/NotifyNtfy.py,sha256=AtJt2zH35mMQTwRDxKia93NPy6-4rtixplP53zIYV2M,27979 +apprise/plugins/NotifyOffice365.py,sha256=8TxsVsdbUghmNj0kceMlmoZzTOKQTgn3priI8JuRuHE,25190 +apprise/plugins/NotifyOneSignal.py,sha256=gsw7ckW7xLiJDRUb7eJHNe_4bvdBXmt6_YsB1u_ghjw,18153 +apprise/plugins/NotifyOpsgenie.py,sha256=zJWpknjoHq35Iv9w88ucR62odaeIN3nrGFPtYnhDdjA,20515 +apprise/plugins/NotifyPagerDuty.py,sha256=lu6oNdygrs6UezYm6xgiQxQDeDz8EVUtfP-xsArRvyw,17874 +apprise/plugins/NotifyPagerTree.py,sha256=mPl6ejdelNlWUWGVs46kZT0VV4uFZoeCdcv4VJ_f_XQ,13849 +apprise/plugins/NotifyParsePlatform.py,sha256=6oFOTpu-HMhesaYXRBvu5oaESYlFrKBNYTHE-ItCBRk,10291 +apprise/plugins/NotifyPopcornNotify.py,sha256=kRstzG0tWBdxSRfn2RN2J7FhvIj2qYWlwUyLxxZCbPc,10587 +apprise/plugins/NotifyProwl.py,sha256=EGOdmiZq8CFbjxTtWWKLQEdYiSvr4czZfE_8aCMEokw,9782 +apprise/plugins/NotifyPushBullet.py,sha256=JVd2GQH-DWmPaKjuGBpsE6DXNCcZEUDH7tA5zbM1qEU,15372 +apprise/plugins/NotifyPushDeer.py,sha256=cG1UFG06PfzbmI1RxtrMqmfaHK_Ojk_W-QMEdtkEuUI,6922 +apprise/plugins/NotifyPushMe.py,sha256=ioRzeXbd2X5miTd3h3m7AwCqkIIfbXNm4PjYk0OOXZ0,7134 +apprise/plugins/NotifyPushSafer.py,sha256=hIcYHwUZapmC-VDvaO_UkDY9RSPTxHgF7m2FL-6JBZw,26756 +apprise/plugins/NotifyPushed.py,sha256=NqLMXD9gvihXLfLUtCcMfz5oUAhPM7sKXECqKgD0v-U,12270 +apprise/plugins/NotifyPushjet.py,sha256=8qWpIqM4dKWjO-BjOrRJXZYtvtJBt_mikdBWRxfibnE,8952 +apprise/plugins/NotifyPushover.py,sha256=MJDquV4zl1cNrGZOC55hLlt6lOb6625WeUcgS5ceCbk,21213 +apprise/plugins/NotifyPushy.py,sha256=mmWcnu905Fvc8ihYXvZ7lVYErGZH5Q-GbBNS20v5r48,12496 +apprise/plugins/NotifyRSyslog.py,sha256=W42LT90X65-pNoU7KdhdX1PBcmsz9RyV376CDa_H3CI,11982 +apprise/plugins/NotifyReddit.py,sha256=E78OSyDQfUalBEcg71sdMsNBOwdj7cVBnELrhrZEAXY,25785 +apprise/plugins/NotifyRevolt.py,sha256=DRA9Xylwl6leVjVFuJcP4L1cG49CIBtnQdxh4BKnAZ4,14500 +apprise/plugins/NotifyRocketChat.py,sha256=Cb_nasX0-G3FoPMYvNk55RJ-tHuXUCTLUn2wTSi4IcI,25738 +apprise/plugins/NotifyRyver.py,sha256=yhHPMLGeJtcHwBKSPPk0OBfp59DgTvXio1R59JhrJu4,11823 +apprise/plugins/NotifySES.py,sha256=wtRmpAZkS5mQma6sdiaPT6U1xcgoj77CB9mNFvSEAw8,33545 +apprise/plugins/NotifySMSEagle.py,sha256=voFNqOewD9OC1eRctD0YdUB_ZSWsb06rjUwBfCcxPYA,24161 +apprise/plugins/NotifySMSManager.py,sha256=DbVc35qLfYkNL7eq43_rPD6k-PELL9apf3S09S6qvDA,14125 +apprise/plugins/NotifySMTP2Go.py,sha256=foQ7aMMmNc5Oree8YwrxZJgMnF6yVMFAfqShm_nLbx0,19711 +apprise/plugins/NotifySNS.py,sha256=ZEBWf0ZJ9w_ftzUikKEvQWJ2fkxrUbrLhPmTRD2DvRQ,24159 +apprise/plugins/NotifySendGrid.py,sha256=IBdYmZcthkvGCz1N_Fs8vDnImtHug6LpuKv1mWT_Cdo,16213 +apprise/plugins/NotifyServerChan.py,sha256=WsrClO9f0xi-KpnLZGTUHV7PxeU3l1D875gvMaZRG_M,5779 +apprise/plugins/NotifySignalAPI.py,sha256=OwJ7qjJ-ZJyS8GS-dBWAtgizHMnGegg76GuwFobyWkw,16733 +apprise/plugins/NotifySimplePush.py,sha256=dUC6O8IGuUIAz5z6_H7A7jdv5Gj1plytNm5QyKnHAYg,10876 +apprise/plugins/NotifySinch.py,sha256=tmHLwQa9lWHEI3EcRfigl4i7JU46A6gKAi_GbY0PrX4,16813 +apprise/plugins/NotifySlack.py,sha256=3VdjruU5FPr3jT_s3axwRJKMcBYXP0lvJnyuKedIlcE,42521 +apprise/plugins/NotifySparkPost.py,sha256=6dRTwnYU50Lvmp6AlwCyePe0TMbVEXaSwNeGkg__EYo,27878 +apprise/plugins/NotifyStreamlabs.py,sha256=lx3N8T2ufUWFYIZ-kU_rOv50YyGWBqLSCKk7xim2_Io,16023 +apprise/plugins/NotifySynology.py,sha256=_jTqfgWeOuSi_I8geMOraHBVFtDkvm9mempzymrmeAo,11105 +apprise/plugins/NotifySyslog.py,sha256=J9Kain2bb-PDNiG5Ydb0q678cYjNE_NjZFqMG9oEXM0,10617 +apprise/plugins/NotifyTechulusPush.py,sha256=m43_Qj1scPcgCRX5Dr2Ul7nxMbaiVxNzm_HRuNmfgoA,7253 +apprise/plugins/NotifyTelegram.py,sha256=XE7PC9LRzcrfE2bpLKyor5lO_7B9LS4Xw1UlUmA4a2A,37187 +apprise/plugins/NotifyThreema.py,sha256=C_C3j0fJWgeF2uB7ceJFXOdC6Lt0TFBInFMs5Xlg04M,11885 +apprise/plugins/NotifyTwilio.py,sha256=WCo8eTI9OF1rtg3ueHHRDXt4Lp45eZ6h3IdTZVf5HM8,15976 +apprise/plugins/NotifyTwist.py,sha256=nZA73CYVe-p0tkVMy5q3vFRyflLM4yjUo9LECvkUwgc,28841 +apprise/plugins/NotifyTwitter.py,sha256=qML0jlBkLZMHrkKRxBpVUnBwAz8MWGYyI3cvwi-hrgM,30152 +apprise/plugins/NotifyVoipms.py,sha256=msy_D32YhP8OP4_Mj_L3OYd4iablqQETN-DvilGZeVQ,12552 +apprise/plugins/NotifyVonage.py,sha256=xmzZgobFaGA_whpQ5fDuG2poUrK9W4T77yP7dusHcSo,13431 +apprise/plugins/NotifyWeComBot.py,sha256=5lkhXDgyJ1edzknemKsO1sJVv7miR9F_7xI40Ag7ICI,8789 +apprise/plugins/NotifyWebexTeams.py,sha256=gbbRlHiPuOvUIZexE5m2QNd1dN_5_x0OdT5m6NSrcso,9164 +apprise/plugins/NotifyWhatsApp.py,sha256=PtzW0ue3d2wZ8Pva_LG29jUcpRRP03TFxO5SME_8Juo,19924 +apprise/plugins/NotifyWindows.py,sha256=QgWJfJF8AE6RWr-L81YYVZNWrnImK9Qr3B991HWanqU,8563 +apprise/plugins/NotifyXBMC.py,sha256=5hDuOTP3Kwtp4NEMaokNjWyEKEkQcN_fSx-cUPJvhaU,12096 +apprise/plugins/NotifyXML.py,sha256=WJnmdvXseuTRgioVMRqpR8a09cDfTpPTfuFlTnT_TfI,16973 +apprise/plugins/NotifyZulip.py,sha256=M8cSL7nZvtBYyTX6045g34tyn2vyybltgD1CoI4Xa7A,13968 +apprise/plugins/__init__.py,sha256=jTfLmW47kZC_Wf5eFFta2NoD2J-7_E7JaPrrVMIECkU,18725 +apprise/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +apprise/utils.py,sha256=SjRU2tb1UsVnTCTXPUyXVz3WpRbDWwAHH-d3ll38EHY,53185 diff --git a/libs/apprise-1.8.0.dist-info/REQUESTED b/libs/apprise-1.7.6.dist-info/REQUESTED similarity index 100% rename from libs/apprise-1.8.0.dist-info/REQUESTED rename to libs/apprise-1.7.6.dist-info/REQUESTED diff --git a/libs/apprise-1.8.0.dist-info/WHEEL b/libs/apprise-1.7.6.dist-info/WHEEL similarity index 100% rename from libs/apprise-1.8.0.dist-info/WHEEL rename to libs/apprise-1.7.6.dist-info/WHEEL diff --git a/libs/apprise-1.8.0.dist-info/entry_points.txt b/libs/apprise-1.7.6.dist-info/entry_points.txt similarity index 100% rename from libs/apprise-1.8.0.dist-info/entry_points.txt rename to libs/apprise-1.7.6.dist-info/entry_points.txt diff --git a/libs/apprise-1.8.0.dist-info/top_level.txt b/libs/apprise-1.7.6.dist-info/top_level.txt similarity index 100% rename from libs/apprise-1.8.0.dist-info/top_level.txt rename to libs/apprise-1.7.6.dist-info/top_level.txt diff --git a/libs/apprise-1.8.0.dist-info/RECORD b/libs/apprise-1.8.0.dist-info/RECORD deleted file mode 100644 index bcfa733bc..000000000 --- a/libs/apprise-1.8.0.dist-info/RECORD +++ /dev/null @@ -1,183 +0,0 @@ -../../bin/apprise,sha256=ZJ-e4qqxNLtdW_DAvpuPPX5iROIiQd8I6nvg7vtAv-g,233 -apprise-1.8.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 -apprise-1.8.0.dist-info/LICENSE,sha256=gt7qKBxRhVcdmXCYVtrWP6DtYjD0DzONet600dkU994,1343 -apprise-1.8.0.dist-info/METADATA,sha256=if2D6aZrIVQZAe9BKWyqKoKH89ZGnYOTvXGRfqcSf_g,44823 -apprise-1.8.0.dist-info/RECORD,, -apprise-1.8.0.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 -apprise-1.8.0.dist-info/WHEEL,sha256=Xo9-1PvkuimrydujYJAjF7pCkriuXBpUPEjma1nZyJ0,92 -apprise-1.8.0.dist-info/entry_points.txt,sha256=71YypBuNdjAKiaLsiMG40HEfLHxkU4Mi7o_S0s0d8wI,45 -apprise-1.8.0.dist-info/top_level.txt,sha256=JrCRn-_rXw5LMKXkIgMSE4E0t1Ks9TYrBH54Pflwjkk,8 -apprise/__init__.py,sha256=nBy2lkwvLxW1QTMEagOZZnM5AQWLM6CRUYt-Gr03X94,3388 -apprise/apprise.py,sha256=JWSqg5pYJOydubQyaIjR9gIPhb2okcrGe2mQ_NhPNS0,32837 -apprise/apprise.pyi,sha256=_4TBKvT-QVj3s6PuTh3YX-BbQMeJTdBGdVpubLMY4_k,2203 -apprise/apprise_attachment.py,sha256=eYVnNWTWQzlzKPDOgMCzGvVtXXDL6noMwtRKwwvyL8Q,12528 -apprise/apprise_attachment.pyi,sha256=R9-0dVqWpeaFrVpcREwPhGy3qHWztG5jEjYIOsbE5dM,1145 -apprise/apprise_config.py,sha256=qlNtd-OkldrY9rE9vT67fVPHINx9fkkbwQinhbBjQ_I,16896 -apprise/apprise_config.pyi,sha256=_mUlCnncqAq8sL01WxQTgZjnb2ic9kZXvtqZmVl-fc8,1568 -apprise/asset.py,sha256=ICXIjCi12Xq8E-WIR4mrVC7KcpPRiJDlKG8cHqoCll0,11643 -apprise/asset.pyi,sha256=NYLXXYbScgRkspP27XGpRRM_uliPu1OCdWdZBPPvLng,979 -apprise/assets/NotifyXML-1.0.xsd,sha256=292qQ_IUl5EWDhPyzm9UTT0C2rVvJkyGar8jiODkJs8,986 -apprise/assets/NotifyXML-1.1.xsd,sha256=bjR3CGG4AEXoJjYkGCbDttKHSkPP1FlIWO02E7G59g4,1758 -apprise/assets/themes/default/apprise-failure-128x128.ico,sha256=Mt0ptfHJaN3Wsv5UCNDn9_3lyEDHxVDv1JdaDEI_xCA,67646 -apprise/assets/themes/default/apprise-failure-128x128.png,sha256=66ps8TDPxVH3g9PlObJqF-0x952CjnqQyN3zvpRcOT8,16135 -apprise/assets/themes/default/apprise-failure-256x256.png,sha256=bQBsKKCsKfR9EqgYOZrcVcVa5y8qG58PN2mEqO5eNRI,41931 -apprise/assets/themes/default/apprise-failure-32x32.png,sha256=vH0pZffIDCvkejpr3fJHGXW__8Yc3R_p0bacX6t6l18,2437 -apprise/assets/themes/default/apprise-failure-72x72.png,sha256=EP5A8DHRDr9srgupFSwOoyQ308bNJ8aL192J_L4K-ec,7600 -apprise/assets/themes/default/apprise-info-128x128.ico,sha256=F5_CirmXueRCRI5Z_Crf6TS6jVIXTJlRD83zw1oJ66g,67646 -apprise/assets/themes/default/apprise-info-128x128.png,sha256=bBqRZAgQey-gkmJrnFhPbzjILSrljE59mRkgj3raMQo,16671 -apprise/assets/themes/default/apprise-info-256x256.png,sha256=B5r_O4d9MHCmSWZwfbqQgZSp-ZetTdiBSwKcMTF1aFA,43331 -apprise/assets/themes/default/apprise-info-32x32.png,sha256=lt3NZ95TzkiCNVNlurrB2fE2nriMa1wftl7nrNXmb6c,2485 -apprise/assets/themes/default/apprise-info-72x72.png,sha256=kDnsZpqNUZGqs9t1ECUup7FOfXUIL-rupnQCYJp9So4,7875 -apprise/assets/themes/default/apprise-logo.png,sha256=85ttALudKkLmiqilJT7mUQLUXRFmM1AK89rnwLm313s,160907 -apprise/assets/themes/default/apprise-success-128x128.ico,sha256=uCopPwdQjxgfohKazHaDzYs9y4oiaOpL048PYC6WRlg,67646 -apprise/assets/themes/default/apprise-success-128x128.png,sha256=nvDuU_QqhGlw6cMtdj7Mv-gPgqCEx-0DaaXn1KBLVYg,17446 -apprise/assets/themes/default/apprise-success-256x256.png,sha256=vXfKuxY3n0eeXHKdb9hTxICxOEn7HjAQ4IZpX0HSLzc,48729 -apprise/assets/themes/default/apprise-success-32x32.png,sha256=Jg9pFJh3YPI-LiPBebyJ7Z4Vt7BRecaE8AsRjQVIkME,2471 -apprise/assets/themes/default/apprise-success-72x72.png,sha256=FQbgvIhqKOhEK0yvrhaSpai0R7hrkTt_-GaC2KUgCCk,7858 -apprise/assets/themes/default/apprise-warning-128x128.ico,sha256=6XaQPOx0oWK_xbhr4Yhb7qNazCWwSs9lk2SYR2MHTrQ,67646 -apprise/assets/themes/default/apprise-warning-128x128.png,sha256=pf5c4Ph7jWH7gf39dJoieSj8TzAsY3TXI-sGISGVIW4,16784 -apprise/assets/themes/default/apprise-warning-256x256.png,sha256=SY-xlaiXaj420iEYKC2_fJxU-yj2SuaQg6xfPNi83bw,43708 -apprise/assets/themes/default/apprise-warning-32x32.png,sha256=97R2ywNvcwczhBoWEIgajVtWjgT8fLs4FCCz4wu0dwc,2472 -apprise/assets/themes/default/apprise-warning-72x72.png,sha256=L8moEInkO_OLxoOcuvN7rmrGZo64iJeH20o-24MQghE,7913 -apprise/attachment/__init__.py,sha256=9jSiGEbLllS-0Vbpgxo4MCpZfIJ-saezWWgQ1PofZ9I,1678 -apprise/attachment/base.py,sha256=phcM6C281j2eoEhtoH5FY0m5s_JvWiEm1AK9z9gyi0w,13692 -apprise/attachment/base.pyi,sha256=w0XG_QKauiMLJ7eQ4S57IiLIURZHm_Snw7l6-ih9GP8,961 -apprise/attachment/file.py,sha256=d9gpsunNIot-6h6w-WQmwWgFiCv7YLqk42zJr4LLqE4,4752 -apprise/attachment/http.py,sha256=C0L9zKmHi60wyzEZN-OJCF7LVoY-MMHYMqhXspFlLdU,13748 -apprise/cli.py,sha256=h-pWSQPqQficH6J-OEp3MTGydWyt6vMYnDZvHCeAt4Y,20697 -apprise/common.py,sha256=I6wfrndggCL7l7KAl7Cm4uwAX9n0l3SN4-BVvTE0L0M,5593 -apprise/common.pyi,sha256=luF3QRiClDCk8Z23rI6FCGYsVmodOt_JYfYyzGogdNM,447 -apprise/config/__init__.py,sha256=oDxdoqG2NEYu_bbpLsLaM3L9WKY3gNn5gjIwb2h3LU4,1679 -apprise/config/base.py,sha256=iWgrBk4-wm_SHtNbe7dCQOYnbkI3oKWP_b60qwjGSoU,53173 -apprise/config/base.pyi,sha256=cngfobwH6v2vxYbQrObDi5Z-t5wcquWF-wR0kBCr3Eg,54 -apprise/config/file.py,sha256=MB_H2X5lJZS-XAOahkMb3IsD2rgVebFjiEF76goITEg,6125 -apprise/config/http.py,sha256=CjQtv_OQJykMxD4ssiwbFI3P8CeQiPdYV_ZIiL_XqMw,9440 -apprise/config/memory.py,sha256=8VICU-WLux8KnW6i9sf9fgmns90J-MfVYI3pvTiyTno,2816 -apprise/conversion.py,sha256=fSn-pTE6-vNt9qVQCKib_NTMhZnCH88FoMt14x6co1M,6273 -apprise/decorators/__init__.py,sha256=e_PDAm0kQNzwDPx-NJZLPfLMd2VAABvNZtxx_iDviRM,1487 -apprise/decorators/base.py,sha256=KnRzhrTOxQxwm4KuJxfCfaYfX0MrFbqWTvXY1XuiNck,8019 -apprise/decorators/notify.py,sha256=FzIa7m-G5KnVVa__rjyn990zt2lqE8sdHW-XY79lbAU,5097 -apprise/emojis.py,sha256=ONF0t8dY9f2XlEkLUG79-ybKVAj2GqbPj2-Be97vAoI,87738 -apprise/i18n/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 -apprise/i18n/en/LC_MESSAGES/apprise.mo,sha256=w-KW6RXYYMr14raaIvJzbop8tXU4qrsz50zm8rcCo3U,3959 -apprise/locale.py,sha256=4uSr4Nj_rz6ISMMAfRVRk58wZVLKOofJgk2x0_E8NkQ,8994 -apprise/logger.py,sha256=131hqhed8cUj9x_mfXDEvwA2YbcYDFAYiWVK1HgxRVY,6921 -apprise/manager.py,sha256=_LiMG1Upk6h6GcxOw3GjsPtVT8ZJLhLlQkC_xL_dm6A,27218 -apprise/manager_attachment.py,sha256=EkrcKtKjbxTXXyDaKyiu4XSfDu9wKFSdJD7TOTpyOUc,2200 -apprise/manager_config.py,sha256=sCIOlBTH13bQ1cuhQVpUq2vyKWBArA8YRyPnXIB1iWQ,2205 -apprise/manager_plugins.py,sha256=Xbg5-xr-06zMIDoWviz-zKcbzusHj0iBBMchKPpUOkg,2211 -apprise/plugins/__init__.py,sha256=Hm-vt-Xtxir5mgOdehqlGLhIlc45LA31zjqV42uRnB8,18701 -apprise/plugins/apprise_api.py,sha256=D93eUOlEQ1xPZYdagnEtIxkSuzZ4b9XreuhntQW97F8,16638 -apprise/plugins/aprs.py,sha256=fyzhdsESVwsqHMbfjnlRuGuAqAz2Pk_-MrmiMihs8qY,25506 -apprise/plugins/bark.py,sha256=oSz7Nr7vxnXxqA5dRaO6ze2IljkgEQavUPs-MUUDSX4,15681 -apprise/plugins/base.py,sha256=720L5OyMMLqlM3UdYSNMpA3m0rCudzGP3HwKgu73Ons,30350 -apprise/plugins/base.pyi,sha256=aKlZXRYUgG8lz_ZgGkYYJ_GKhuf18youTmMU-FlG7z8,21 -apprise/plugins/boxcar.py,sha256=8ImhsSsOK9o3eiYp4dZ6fO6p6AeI-jOPWoFJ8qvRAxY,12850 -apprise/plugins/bulksms.py,sha256=XuP8X4dL1wWQU7TkLYWPWRAro7TymnF7PlF2ESe7o0o,15988 -apprise/plugins/bulkvs.py,sha256=sLpiKbHs63Yu0UjMc9erW1VSgLceuu5wvPie5iyl03k,13273 -apprise/plugins/burstsms.py,sha256=7YmuhElVvT-0FIxMFBILHjo6Fir0J4qHTuqj8KfWBaI,15533 -apprise/plugins/chantify.py,sha256=hOvrmhH051Us28_kv0mKkuaJ2BN_8pSsslF8eMCgp-Q,6660 -apprise/plugins/clicksend.py,sha256=kKUJgk9FcTcfXqcIV57uMz0VxBtSQqkpxocRkgn0-3Q,11408 -apprise/plugins/custom_form.py,sha256=fMYwSQyEa_u8IEw5QSylDn-y32FnmymkL5ng-tGxDoc,17888 -apprise/plugins/custom_json.py,sha256=UCXaegE1nD8UrKlFrSKQbxfbcrX1BHUvZwBZY6a_aJc,13834 -apprise/plugins/custom_xml.py,sha256=lrPCRngPz8_oV2A8ZfiIY56BRQc1iv0PN0--2LOlxpA,16956 -apprise/plugins/d7networks.py,sha256=2o_wDgoak_S0sUJJa7HPtu0PPKLVmIOrq1rV9llOnHY,15030 -apprise/plugins/dapnet.py,sha256=fclGE69ggMejgpyvBpJqTwFNF3g2w7qpFySOMcc9vi0,13607 -apprise/plugins/dbus.py,sha256=lvHLmOkJYJAr4TjrigdIgP5bBlQXHrNCDR0k80LNsks,14366 -apprise/plugins/dingtalk.py,sha256=1twAGYUZzjhQepg2zhaR7u8QJuWvM5WymkbPQSUKBck,11992 -apprise/plugins/discord.py,sha256=kdR09bKU80-AosBIrTkMSxoOkAUHMXKwSr1P3H-M_f4,26053 -apprise/plugins/email.py,sha256=pVVWhEpT9Zi7qyUvpI2UxbjxkXYe6FoJj8E0NTw4P98,39912 -apprise/plugins/emby.py,sha256=HWYxlgHE99yAPKii4IE1XQQ-B1HViklWOkefjmq6SW4,24022 -apprise/plugins/enigma2.py,sha256=40Uo0m1JtLUcwRnfqKqdX_8ZR1-SvPfJ5470uijgdfw,11481 -apprise/plugins/fcm/__init__.py,sha256=eTjX-ahPHrPddX0v_Ix77qEr2G4NQ7reClCMzX3Nxwk,21657 -apprise/plugins/fcm/color.py,sha256=rQxVRL_CcRlgnNTQXkjB1Bfs0Xc933zOB1tURSdhi7Y,4585 -apprise/plugins/fcm/common.py,sha256=978uBUoNdtopCtylipGiKQdsQ8FTONxkFBp7uJMZHc8,1718 -apprise/plugins/fcm/oauth.py,sha256=Vvbd0-rd5BPIjAneG3rILU153JIzfSZ0kaDov6hm96M,11197 -apprise/plugins/fcm/priority.py,sha256=0WuRW1y1HVnybgjlTeCZPHzt7j8SwWnC7faNcjioAOc,8163 -apprise/plugins/feishu.py,sha256=buGBg1YlcwHjwUGzUfju4cdYbmEOFl3EHU_NzEBqtlM,7253 -apprise/plugins/flock.py,sha256=_bhH-ub0LbuU7k2p1ZwUPZ-TbC3kpD48GKNtLebUpoM,12735 -apprise/plugins/freemobile.py,sha256=NZf553UWkl1FVEVyWQKJN3ZD6opYSv3I-L6DRaKbiCw,6679 -apprise/plugins/gnome.py,sha256=UYtaiMKxILhTdsxe4aeLaJwjV6Af-8VhjVR3W3CyPPk,9046 -apprise/plugins/google_chat.py,sha256=f7F4gPxwwkmhDBlXMHzYoHRhPX3w8tyD7OimGBjmNxg,12609 -apprise/plugins/gotify.py,sha256=ISzmuQ4-Wd46OlaxGSAZBbWDTq9mHBUYO0R-7tAX_zc,10538 -apprise/plugins/growl.py,sha256=mlpN1QXGlEf2BA3BORnvkyT0oiTsWBev2y5gzpOm9r0,14006 -apprise/plugins/guilded.py,sha256=lhE6gK7laQNYEubD9lBGRemFK-IHis_u2tNekbUoGgM,3707 -apprise/plugins/home_assistant.py,sha256=Wstut0QaQL2dE66kH8MOqMANayhvGOq7CuxVz9O-T60,10722 -apprise/plugins/httpsms.py,sha256=2TtIlAFa4cjXwpMyrjfieCFHgaZl4H_YT6IoPIMDOcg,11123 -apprise/plugins/ifttt.py,sha256=ZHtu7pW9I0aHVEC4DshKi6XZCwqQ0A_XGLyFJujwdKY,13412 -apprise/plugins/join.py,sha256=mRop7thH24kQmvIEvtnh0HT0VyBrUXm2sS-P69c0iFE,13568 -apprise/plugins/kavenegar.py,sha256=1vdms7QBaLcTiLXeQGfprMU5rw9wgImRLtALIb78-ro,12607 -apprise/plugins/kumulos.py,sha256=6M_way1Qi5bELm8Csay86AVtVhzmRyv5hfxGrFvyzN4,8201 -apprise/plugins/lametric.py,sha256=JR0XjdxkEphT4VKvKfElNxpAoOpXZCb-40b2SJQP9XA,37521 -apprise/plugins/line.py,sha256=-xONdu4LFkS3sGgZeEGiPGbBIvBEd20lCbyxKLhQwAg,10659 -apprise/plugins/lunasea.py,sha256=WxJ-RIbFDiS1-5HjCs8XVdNv7nt2EHimsXGCDaK0sC0,14442 -apprise/plugins/macosx.py,sha256=4vIXz1xlsq_xlEyeu_rEvzJQZYcWq7pVmSn5VjF_dCY,8258 -apprise/plugins/mailgun.py,sha256=ad3jzdrbdgwWmOAAu4e_inLEAo-cii4z0OnIJQXoSIA,25396 -apprise/plugins/mastodon.py,sha256=X8CBxnuWORLo9JEOLCJcSafFNVrcEd778R38doyNWUo,35254 -apprise/plugins/matrix.py,sha256=zJPTLFqRT6mofXFVi421_poF0Qm7KaWSgNXTBKq3YoI,50032 -apprise/plugins/mattermost.py,sha256=KfHfqt3LO4XuMsY-qNV-i_OAAamF-35RgjHzxuq2deM,12709 -apprise/plugins/messagebird.py,sha256=3TJ_31Vc1liwQKKKwEiO_rP5e4jP4QkcU_wHyRGtf5Q,12235 -apprise/plugins/misskey.py,sha256=E5UrDrVryb7zV2D_qJCPsCyvpynF4-22JqRVco6PcgM,9587 -apprise/plugins/mqtt.py,sha256=3LcRhT44o2QoSH5rJs23xRbi2vob-po5FAPnnEU_cgs,19528 -apprise/plugins/msg91.py,sha256=V3PwdCS5r-LbVHNNTFZGUHt7GPwQOHnQC0mx8G90wGQ,12664 -apprise/plugins/msteams.py,sha256=4maXBIQFEVfH-IVzZW6t4jirsozmKwF4ySPP5h20cTQ,22964 -apprise/plugins/nextcloud.py,sha256=iYmKGH-xZ4Kj3HvXA_krQody7LRqJKzMRu39Ivk1ve4,12742 -apprise/plugins/nextcloudtalk.py,sha256=TTK8qhy0VPjG0N1yFUBJWTieV-1DqT9Jux9D5PRiYAE,10994 -apprise/plugins/notica.py,sha256=MzryA8x-dSt-oRk9g3dlTTrb1ul7mnbRNajbiwTx1Mc,12973 -apprise/plugins/notifiarr.py,sha256=ZI2mjXwKLWx7SXb6d3S-sk2JmCswJ23UTPj9jVNSN0U,15844 -apprise/plugins/notifico.py,sha256=IKkiXU8HdbRnEWzkQKPFo1g-ZnT8AIwFYer7jF2Yjac,12022 -apprise/plugins/ntfy.py,sha256=jOmPZETJByyNmYSzr-2F3k5jAXFVNldcd3wK-tQRpyE,27956 -apprise/plugins/office365.py,sha256=bCg53GDruS7A3_PQNCjiSERhfub_FHTOVCsRwjgbjXU,25173 -apprise/plugins/one_signal.py,sha256=0ljKuz6Wyn5K8Rxp3BT8aARzHWYff0q2TWA5f-ZLJSA,18140 -apprise/plugins/opsgenie.py,sha256=wWUREzEn8FDQmmVGhmTlN7kxsYlzNj1tK3wA5t8UbCA,20502 -apprise/plugins/pagerduty.py,sha256=1vQ2rfbDUKnM0XdkVMrvTnWIPK7lTxrm-Nslt3LW5Ng,17857 -apprise/plugins/pagertree.py,sha256=uhZL2SxIJr0cguMGhJP_RIJxJZLd86uoAcMhHsBOKm8,13836 -apprise/plugins/parseplatform.py,sha256=G99l6AnHZtaw11y7oBBVVvgdg7lSM8gWFm4tAWhJ8d4,10278 -apprise/plugins/popcorn_notify.py,sha256=ppOqxPrZrOPa-TFicO3Lo_jgwOOPCNEXMgmEo10DAZA,10574 -apprise/plugins/prowl.py,sha256=fYsv6s8xA6OC0yFajgLf3jgL6IwiaOTZaJKisW4eNyw,9769 -apprise/plugins/pushbullet.py,sha256=g-7_Y0N4x-a8YE2gqDqW5OIi74YY7rja_jQ8WVKc4FI,15353 -apprise/plugins/pushdeer.py,sha256=8StOcyK1jlx3pc_CnmFUSqdjfvuv0qa6bf--FHP2_KE,6909 -apprise/plugins/pushed.py,sha256=pm3T7JGExjYeqVWQVN8J8JHkn1XBMfix_sdmr1ItXY8,12253 -apprise/plugins/pushjet.py,sha256=Xk0hzx6l5bNHtGgL0M_znRY5JRPUJf4_PhleCyFbe0I,8935 -apprise/plugins/pushme.py,sha256=EswSmup0uL3QmANeJPDhDYyyeBwSrTnqdjMlfvWFnFA,7121 -apprise/plugins/pushover.py,sha256=I6u9C1SVAEVnsLUySFq5UyHi4cQQtew5za4r86aTK10,21194 -apprise/plugins/pushsafer.py,sha256=aGQ1ibggAWGpcBwpD4oQQYMUcKVcV_xsTlc5_wdjssY,26743 -apprise/plugins/pushy.py,sha256=Ai1tKhcus5IuwvhQgtaj--RMPahgtpleWrBbr_ZQJfM,12483 -apprise/plugins/reddit.py,sha256=z54HpGeJxkyS_LH38nqPa6rqW8mrJqSEGTNOh4Cf-78,25768 -apprise/plugins/revolt.py,sha256=kVrJvTb7mBFXFZd9GIVrX2jVIvaUc5D5via48nOXNSA,14487 -apprise/plugins/rocketchat.py,sha256=oSaFzQ7XjOzjhPIPhdS7r_LGa1IJXV6VK_3xNH9Gq9M,25721 -apprise/plugins/rsyslog.py,sha256=9NTg4sYNbbAzw_MnN51YKxVQpb2o6WZUMyKpRtgoupM,11969 -apprise/plugins/ryver.py,sha256=OM_AG-oiRnNYIua-70Wp8lUpZzIkZ7erIiDE6Fd4Q6s,11810 -apprise/plugins/sendgrid.py,sha256=PGSdbkhERhFSZZN2j7km6mdojdlo7sFxs28lmOeDpgQ,16200 -apprise/plugins/serverchan.py,sha256=fcnuindQTPaKZ5gbS-nAxvL31YqkEF-vi4w8g_h7dKc,5766 -apprise/plugins/ses.py,sha256=CF17VZOEZybwdgqqu00qSoombTP5z0M8P_XxPmyc2f4,33528 -apprise/plugins/signal_api.py,sha256=PeCB_1YJc4lZwDdArTgzHP-Vhe9iwCNIYe4WVW_HgUo,16716 -apprise/plugins/simplepush.py,sha256=bL0WiRUCp39ST9X_0FNAFJJ1BFtd1t5OD_JTRneUGFY,10859 -apprise/plugins/sinch.py,sha256=0-z_cNIWMJu4kdTca-6B3raAIRV-PG1E7fUtbxUDECo,16796 -apprise/plugins/slack.py,sha256=tLbJsr97Ddp8bq1ozSEp1ssLsh913uC0Y24Xm3TN4Bo,42508 -apprise/plugins/smseagle.py,sha256=WbULwfwnUEkPw_z-2cVp2TzrupS7fkPfcQgq779nG8k,24144 -apprise/plugins/smsmanager.py,sha256=aSSZcvpWjKEdDg-XPyD-9fTkaQ0FodvuuO7Hqg7N6Tk,14112 -apprise/plugins/smtp2go.py,sha256=D3C4rWGCJ-oqaZH8JgoMEV_3BYHCCHMd6M7cG0piIvA,19698 -apprise/plugins/sns.py,sha256=dA58nElGwKKnVAr--rh1deIa9BNPbZElK6cb5G1o3g8,24142 -apprise/plugins/sparkpost.py,sha256=ZR4866e1DefqOuuu3z_vBhS8C5YX0sj1G9WEhdWFMEk,27865 -apprise/plugins/streamlabs.py,sha256=Pyrz2xY2rDo8rnTgu4L5t2u1EPrZWVcIP37k8pE2SaE,16010 -apprise/plugins/synology.py,sha256=-g-Cesx8g-nG10shjUAnYtyLpMoGfUNDcTIGfi2UXDE,11088 -apprise/plugins/syslog.py,sha256=sNKh0iSNc3ARuMIO13uwRirMHzW2VxxTRwyZ-0UYL60,10604 -apprise/plugins/techuluspush.py,sha256=HV1m72pRsC3IfVN66zWK9joslDJsKRKYD6_uRfqjnHk,7240 -apprise/plugins/telegram.py,sha256=zsmCUJU-5INyJ-RDUYIHUEXpwnwShOISWc4Xf7Epanw,37168 -apprise/plugins/threema.py,sha256=aWvFfN5Ve0DZCDX7qJVlY8INT_C-AWh-jnYnPTd7Ufs,11868 -apprise/plugins/twilio.py,sha256=0iYa2ug_2_Rbz4N_lGVihtSSxxFaK2f7Sdr9oK_Wg18,15959 -apprise/plugins/twist.py,sha256=hLqabH_STcZiAwRCgFHO7n5qYx7eZgoDw4xT5Zl_y6Q,28824 -apprise/plugins/twitter.py,sha256=ZTHLuZYowQ6qSw9ujsRB5oNp9F9PyutU-iAKAUOkmT8,30129 -apprise/plugins/voipms.py,sha256=NVbrsY7fJG0MbF6eId--0wo9cRC2kehhg8L0sASQs2w,12539 -apprise/plugins/vonage.py,sha256=PRFMdjn0ARqOEhL8kXySz8pi9vsApl2fh9mZyLVySgo,13414 -apprise/plugins/webexteams.py,sha256=DErDmHhvnHfsAyp4L3mF6vSfq0WabL1lbbl-jDUKYTw,9151 -apprise/plugins/wecombot.py,sha256=o5CO0IyHN7wAXhf7es08QiPCmUl8shZCgN_nyJxycVA,8776 -apprise/plugins/whatsapp.py,sha256=9KObQEvUOtOclnudKhNj7qRrJ0uii7dhfxgwzuMHKxY,19911 -apprise/plugins/windows.py,sha256=88bDJQBnuuA0u7_xoTC-1Ppxt4tz39UMZseRY3EX_FE,8550 -apprise/plugins/xbmc.py,sha256=2ssX2AItDUy5FJFDY9r_JI4u7qc0CLGvG-hW0KtgWag,12079 -apprise/plugins/zulip.py,sha256=PJMB8RmV_ddP5waNAQ0Z29cpIut1WFY31DLFeg8-Nao,13955 -apprise/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 -apprise/url.py,sha256=QEoqmWzapzXPwBXe85SdJaPWq7B4gcv4QCeJtndN4_E,29455 -apprise/url.pyi,sha256=WLaRREH7FzZ5x3-qkDkupojWGFC4uFwJ1EDt02lVs8c,520 -apprise/utils.py,sha256=Sy0pVslC8FDKh5RY8o6eVB-sPHFxBXFTdbhKSVf4UDM,53461 diff --git a/libs/apprise/Apprise.py b/libs/apprise/Apprise.py new file mode 100644 index 000000000..9a3e8dfc7 --- /dev/null +++ b/libs/apprise/Apprise.py @@ -0,0 +1,887 @@ +# -*- coding: utf-8 -*- +# BSD 2-Clause License +# +# Apprise - Push Notification Library. +# Copyright (c) 2024, Chris Caron +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. + +import asyncio +import concurrent.futures as cf +import os +from itertools import chain +from . import common +from .conversion import convert_between +from .utils import is_exclusive_match +from .NotificationManager import NotificationManager +from .utils import parse_list +from .utils import parse_urls +from .utils import cwe312_url +from .emojis import apply_emojis +from .logger import logger +from .AppriseAsset import AppriseAsset +from .AppriseConfig import AppriseConfig +from .AppriseAttachment import AppriseAttachment +from .AppriseLocale import AppriseLocale +from .config.ConfigBase import ConfigBase +from .plugins.NotifyBase import NotifyBase + +from . import plugins +from . import __version__ + +# Grant access to our Notification Manager Singleton +N_MGR = NotificationManager() + + +class Apprise: + """ + Our Notification Manager + + """ + + def __init__(self, servers=None, asset=None, location=None, debug=False): + """ + Loads a set of server urls while applying the Asset() module to each + if specified. + + If no asset is provided, then the default asset is used. + + Optionally specify a global ContentLocation for a more strict means + of handling Attachments. + """ + + # Initialize a server list of URLs + self.servers = list() + + # Assigns an central asset object that will be later passed into each + # notification plugin. Assets contain information such as the local + # directory images can be found in. It can also identify remote + # URL paths that contain the images you want to present to the end + # user. If no asset is specified, then the default one is used. + self.asset = \ + asset if isinstance(asset, AppriseAsset) else AppriseAsset() + + if servers: + self.add(servers) + + # Initialize our locale object + self.locale = AppriseLocale() + + # Set our debug flag + self.debug = debug + + # Store our hosting location for optional strict rule handling + # of Attachments. Setting this to None removes any attachment + # restrictions. + self.location = location + + @staticmethod + def instantiate(url, asset=None, tag=None, suppress_exceptions=True): + """ + Returns the instance of a instantiated plugin based on the provided + Server URL. If the url fails to be parsed, then None is returned. + + The specified url can be either a string (the URL itself) or a + dictionary containing all of the components needed to istantiate + the notification service. If identifying a dictionary, at the bare + minimum, one must specify the schema. + + An example of a url dictionary object might look like: + { + schema: 'mailto', + host: 'google.com', + user: 'myuser', + password: 'mypassword', + } + + Alternatively the string is much easier to specify: + mailto://user:mypassword@google.com + + The dictionary works well for people who are calling details() to + extract the components they need to build the URL manually. + """ + + # Initialize our result set + results = None + + # Prepare our Asset Object + asset = asset if isinstance(asset, AppriseAsset) else AppriseAsset() + + if isinstance(url, str): + # Acquire our url tokens + results = plugins.url_to_dict( + url, secure_logging=asset.secure_logging) + + if results is None: + # Failed to parse the server URL; detailed logging handled + # inside url_to_dict - nothing to report here. + return None + + elif isinstance(url, dict): + # We already have our result set + results = url + + if results.get('schema') not in N_MGR: + # schema is a mandatory dictionary item as it is the only way + # we can index into our loaded plugins + logger.error('Dictionary does not include a "schema" entry.') + logger.trace( + 'Invalid dictionary unpacked as:{}{}'.format( + os.linesep, os.linesep.join( + ['{}="{}"'.format(k, v) + for k, v in results.items()]))) + return None + + logger.trace( + 'Dictionary unpacked as:{}{}'.format( + os.linesep, os.linesep.join( + ['{}="{}"'.format(k, v) for k, v in results.items()]))) + + # Otherwise we handle the invalid input specified + else: + logger.error( + 'An invalid URL type (%s) was specified for instantiation', + type(url)) + return None + + if not N_MGR[results['schema']].enabled: + # + # First Plugin Enable Check (Pre Initialization) + # + + # Plugin has been disabled at a global level + logger.error( + '%s:// is disabled on this system.', results['schema']) + return None + + # Build a list of tags to associate with the newly added notifications + results['tag'] = set(parse_list(tag)) + + # Set our Asset Object + results['asset'] = asset + + if suppress_exceptions: + try: + # Attempt to create an instance of our plugin using the parsed + # URL information + plugin = N_MGR[results['schema']](**results) + + # Create log entry of loaded URL + logger.debug( + 'Loaded {} URL: {}'.format( + N_MGR[results['schema']].service_name, + plugin.url(privacy=asset.secure_logging))) + + except Exception: + # CWE-312 (Secure Logging) Handling + loggable_url = url if not asset.secure_logging \ + else cwe312_url(url) + + # the arguments are invalid or can not be used. + logger.error( + 'Could not load {} URL: {}'.format( + N_MGR[results['schema']].service_name, + loggable_url)) + return None + + else: + # Attempt to create an instance of our plugin using the parsed + # URL information but don't wrap it in a try catch + plugin = N_MGR[results['schema']](**results) + + if not plugin.enabled: + # + # Second Plugin Enable Check (Post Initialization) + # + + # Service/Plugin is disabled (on a more local level). This is a + # case where the plugin was initially enabled but then after the + # __init__() was called under the hood something pre-determined + # that it could no longer be used. + + # The only downside to doing it this way is services are + # initialized prior to returning the details() if 3rd party tools + # are polling what is available. These services that become + # disabled thereafter are shown initially that they can be used. + logger.error( + '%s:// has become disabled on this system.', results['schema']) + return None + + return plugin + + def add(self, servers, asset=None, tag=None): + """ + Adds one or more server URLs into our list. + + You can override the global asset if you wish by including it with the + server(s) that you add. + + The tag allows you to associate 1 or more tag values to the server(s) + being added. tagging a service allows you to exclusively access them + when calling the notify() function. + """ + + # Initialize our return status + return_status = True + + if asset is None: + # prepare default asset + asset = self.asset + + if isinstance(servers, str): + # build our server list + servers = parse_urls(servers) + if len(servers) == 0: + return False + + elif isinstance(servers, dict): + # no problem, we support kwargs, convert it to a list + servers = [servers] + + elif isinstance(servers, (ConfigBase, NotifyBase, AppriseConfig)): + # Go ahead and just add our plugin into our list + self.servers.append(servers) + return True + + elif not isinstance(servers, (tuple, set, list)): + logger.error( + "An invalid notification (type={}) was specified.".format( + type(servers))) + return False + + for _server in servers: + + if isinstance(_server, (ConfigBase, NotifyBase, AppriseConfig)): + # Go ahead and just add our plugin into our list + self.servers.append(_server) + continue + + elif not isinstance(_server, (str, dict)): + logger.error( + "An invalid notification (type={}) was specified.".format( + type(_server))) + return_status = False + continue + + # Instantiate ourselves an object, this function throws or + # returns None if it fails + instance = Apprise.instantiate(_server, asset=asset, tag=tag) + if not isinstance(instance, NotifyBase): + # No logging is required as instantiate() handles failure + # and/or success reasons for us + return_status = False + continue + + # Add our initialized plugin to our server listings + self.servers.append(instance) + + # Return our status + return return_status + + def clear(self): + """ + Empties our server list + + """ + self.servers[:] = [] + + def find(self, tag=common.MATCH_ALL_TAG, match_always=True): + """ + Returns a list of all servers matching against the tag specified. + + """ + + # Build our tag setup + # - top level entries are treated as an 'or' + # - second level (or more) entries are treated as 'and' + # + # examples: + # tag="tagA, tagB" = tagA or tagB + # tag=['tagA', 'tagB'] = tagA or tagB + # tag=[('tagA', 'tagC'), 'tagB'] = (tagA and tagC) or tagB + # tag=[('tagB', 'tagC')] = tagB and tagC + + # A match_always flag allows us to pick up on our 'any' keyword + # and notify these services under all circumstances + match_always = common.MATCH_ALWAYS_TAG if match_always else None + + # Iterate over our loaded plugins + for entry in self.servers: + + if isinstance(entry, (ConfigBase, AppriseConfig)): + # load our servers + servers = entry.servers() + + else: + servers = [entry, ] + + for server in servers: + # Apply our tag matching based on our defined logic + if is_exclusive_match( + logic=tag, data=server.tags, + match_all=common.MATCH_ALL_TAG, + match_always=match_always): + yield server + return + + def notify(self, body, title='', notify_type=common.NotifyType.INFO, + body_format=None, tag=common.MATCH_ALL_TAG, match_always=True, + attach=None, interpret_escapes=None): + """ + Send a notification to all the plugins previously loaded. + + If the body_format specified is NotifyFormat.MARKDOWN, it will + be converted to HTML if the Notification type expects this. + + if the tag is specified (either a string or a set/list/tuple + of strings), then only the notifications flagged with that + tagged value are notified. By default, all added services + are notified (tag=MATCH_ALL_TAG) + + This function returns True if all notifications were successfully + sent, False if even just one of them fails, and None if no + notifications were sent at all as a result of tag filtering and/or + simply having empty configuration files that were read. + + Attach can contain a list of attachment URLs. attach can also be + represented by an AttachBase() (or list of) object(s). This + identifies the products you wish to notify + + Set interpret_escapes to True if you want to pre-escape a string + such as turning a \n into an actual new line, etc. + """ + + try: + # Process arguments and build synchronous and asynchronous calls + # (this step can throw internal errors). + sequential_calls, parallel_calls = self._create_notify_calls( + body, title, + notify_type=notify_type, body_format=body_format, + tag=tag, match_always=match_always, attach=attach, + interpret_escapes=interpret_escapes, + ) + + except TypeError: + # No notifications sent, and there was an internal error. + return False + + if not sequential_calls and not parallel_calls: + # Nothing to send + return None + + sequential_result = Apprise._notify_sequential(*sequential_calls) + parallel_result = Apprise._notify_parallel_threadpool(*parallel_calls) + return sequential_result and parallel_result + + async def async_notify(self, *args, **kwargs): + """ + Send a notification to all the plugins previously loaded, for + asynchronous callers. + + The arguments are identical to those of Apprise.notify(). + + """ + try: + # Process arguments and build synchronous and asynchronous calls + # (this step can throw internal errors). + sequential_calls, parallel_calls = self._create_notify_calls( + *args, **kwargs) + + except TypeError: + # No notifications sent, and there was an internal error. + return False + + if not sequential_calls and not parallel_calls: + # Nothing to send + return None + + sequential_result = Apprise._notify_sequential(*sequential_calls) + parallel_result = \ + await Apprise._notify_parallel_asyncio(*parallel_calls) + return sequential_result and parallel_result + + def _create_notify_calls(self, *args, **kwargs): + """ + Creates notifications for all the plugins loaded. + + Returns a list of (server, notify() kwargs) tuples for plugins with + parallelism disabled and another list for plugins with parallelism + enabled. + """ + + all_calls = list(self._create_notify_gen(*args, **kwargs)) + + # Split into sequential and parallel notify() calls. + sequential, parallel = [], [] + for (server, notify_kwargs) in all_calls: + if server.asset.async_mode: + parallel.append((server, notify_kwargs)) + else: + sequential.append((server, notify_kwargs)) + + return sequential, parallel + + def _create_notify_gen(self, body, title='', + notify_type=common.NotifyType.INFO, + body_format=None, tag=common.MATCH_ALL_TAG, + match_always=True, attach=None, + interpret_escapes=None): + """ + Internal generator function for _create_notify_calls(). + """ + + if len(self) == 0: + # Nothing to notify + msg = "There are no service(s) to notify" + logger.error(msg) + raise TypeError(msg) + + if not (title or body or attach): + msg = "No message content specified to deliver" + logger.error(msg) + raise TypeError(msg) + + try: + if title and isinstance(title, bytes): + title = title.decode(self.asset.encoding) + + if body and isinstance(body, bytes): + body = body.decode(self.asset.encoding) + + except UnicodeDecodeError: + msg = 'The content passed into Apprise was not of encoding ' \ + 'type: {}'.format(self.asset.encoding) + logger.error(msg) + raise TypeError(msg) + + # Tracks conversions + conversion_body_map = dict() + conversion_title_map = dict() + + # Prepare attachments if required + if attach is not None and not isinstance(attach, AppriseAttachment): + attach = AppriseAttachment( + attach, asset=self.asset, location=self.location) + + # Allow Asset default value + body_format = self.asset.body_format \ + if body_format is None else body_format + + # Allow Asset default value + interpret_escapes = self.asset.interpret_escapes \ + if interpret_escapes is None else interpret_escapes + + # Iterate over our loaded plugins + for server in self.find(tag, match_always=match_always): + # If our code reaches here, we either did not define a tag (it + # was set to None), or we did define a tag and the logic above + # determined we need to notify the service it's associated with + + # First we need to generate a key we will use to determine if we + # need to build our data out. Entries without are merged with + # the body at this stage. + key = server.notify_format if server.title_maxlen > 0\ + else f'_{server.notify_format}' + + if server.interpret_emojis: + # alter our key slightly to handle emojis since their value is + # pulled out of the notification + key += "-emojis" + + if key not in conversion_title_map: + + # Prepare our title + conversion_title_map[key] = '' if not title else title + + # Conversion of title only occurs for services where the title + # is blended with the body (title_maxlen <= 0) + if conversion_title_map[key] and server.title_maxlen <= 0: + conversion_title_map[key] = convert_between( + body_format, server.notify_format, + content=conversion_title_map[key]) + + # Our body is always converted no matter what + conversion_body_map[key] = \ + convert_between( + body_format, server.notify_format, content=body) + + if interpret_escapes: + # + # Escape our content + # + + try: + # Added overhead required due to Python 3 Encoding Bug + # identified here: https://bugs.python.org/issue21331 + conversion_body_map[key] = \ + conversion_body_map[key]\ + .encode('ascii', 'backslashreplace')\ + .decode('unicode-escape') + + conversion_title_map[key] = \ + conversion_title_map[key]\ + .encode('ascii', 'backslashreplace')\ + .decode('unicode-escape') + + except AttributeError: + # Must be of string type + msg = 'Failed to escape message body' + logger.error(msg) + raise TypeError(msg) + + if server.interpret_emojis: + # + # Convert our :emoji: definitions + # + + conversion_body_map[key] = \ + apply_emojis(conversion_body_map[key]) + conversion_title_map[key] = \ + apply_emojis(conversion_title_map[key]) + + kwargs = dict( + body=conversion_body_map[key], + title=conversion_title_map[key], + notify_type=notify_type, + attach=attach, + body_format=body_format + ) + yield (server, kwargs) + + @staticmethod + def _notify_sequential(*servers_kwargs): + """ + Process a list of notify() calls sequentially and synchronously. + """ + + success = True + + for (server, kwargs) in servers_kwargs: + try: + # Send notification + result = server.notify(**kwargs) + success = success and result + + except TypeError: + # These are our internally thrown notifications. + success = False + + except Exception: + # A catch all so we don't have to abort early + # just because one of our plugins has a bug in it. + logger.exception("Unhandled Notification Exception") + success = False + + return success + + @staticmethod + def _notify_parallel_threadpool(*servers_kwargs): + """ + Process a list of notify() calls in parallel and synchronously. + """ + + n_calls = len(servers_kwargs) + + # 0-length case + if n_calls == 0: + return True + + # There's no need to use a thread pool for just a single notification + if n_calls == 1: + return Apprise._notify_sequential(servers_kwargs[0]) + + # Create log entry + logger.info( + 'Notifying %d service(s) with threads.', len(servers_kwargs)) + + with cf.ThreadPoolExecutor() as executor: + success = True + futures = [executor.submit(server.notify, **kwargs) + for (server, kwargs) in servers_kwargs] + + for future in cf.as_completed(futures): + try: + result = future.result() + success = success and result + + except TypeError: + # These are our internally thrown notifications. + success = False + + except Exception: + # A catch all so we don't have to abort early + # just because one of our plugins has a bug in it. + logger.exception("Unhandled Notification Exception") + success = False + + return success + + @staticmethod + async def _notify_parallel_asyncio(*servers_kwargs): + """ + Process a list of async_notify() calls in parallel and asynchronously. + """ + + n_calls = len(servers_kwargs) + + # 0-length case + if n_calls == 0: + return True + + # (Unlike with the thread pool, we don't optimize for the single- + # notification case because asyncio can do useful work while waiting + # for that thread to complete) + + # Create log entry + logger.info( + 'Notifying %d service(s) asynchronously.', len(servers_kwargs)) + + async def do_call(server, kwargs): + return await server.async_notify(**kwargs) + + cors = (do_call(server, kwargs) for (server, kwargs) in servers_kwargs) + results = await asyncio.gather(*cors, return_exceptions=True) + + if any(isinstance(status, Exception) + and not isinstance(status, TypeError) for status in results): + # A catch all so we don't have to abort early just because + # one of our plugins has a bug in it. + logger.exception("Unhandled Notification Exception") + return False + + if any(isinstance(status, TypeError) for status in results): + # These are our internally thrown notifications. + return False + + return all(results) + + def details(self, lang=None, show_requirements=False, show_disabled=False): + """ + Returns the details associated with the Apprise object + + """ + + # general object returned + response = { + # Defines the current version of Apprise + 'version': __version__, + # Lists all of the currently supported Notifications + 'schemas': [], + # Includes the configured asset details + 'asset': self.asset.details(), + } + + for plugin in N_MGR.plugins(): + # Iterate over our hashed plugins and dynamically build details on + # their status: + + content = { + 'service_name': getattr(plugin, 'service_name', None), + 'service_url': getattr(plugin, 'service_url', None), + 'setup_url': getattr(plugin, 'setup_url', None), + # Placeholder - populated below + 'details': None, + + # Let upstream service know of the plugins that support + # attachments + 'attachment_support': getattr( + plugin, 'attachment_support', False), + + # Differentiat between what is a custom loaded plugin and + # which is native. + 'category': getattr(plugin, 'category', None) + } + + # Standard protocol(s) should be None or a tuple + enabled = getattr(plugin, 'enabled', True) + if not show_disabled and not enabled: + # Do not show inactive plugins + continue + + elif show_disabled: + # Add current state to response + content['enabled'] = enabled + + # Standard protocol(s) should be None or a tuple + protocols = getattr(plugin, 'protocol', None) + if isinstance(protocols, str): + protocols = (protocols, ) + + # Secure protocol(s) should be None or a tuple + secure_protocols = getattr(plugin, 'secure_protocol', None) + if isinstance(secure_protocols, str): + secure_protocols = (secure_protocols, ) + + # Add our protocol details to our content + content.update({ + 'protocols': protocols, + 'secure_protocols': secure_protocols, + }) + + if not lang: + # Simply return our results + content['details'] = plugins.details(plugin) + if show_requirements: + content['requirements'] = plugins.requirements(plugin) + + else: + # Emulate the specified language when returning our results + with self.locale.lang_at(lang): + content['details'] = plugins.details(plugin) + if show_requirements: + content['requirements'] = plugins.requirements(plugin) + + # Build our response object + response['schemas'].append(content) + + return response + + def urls(self, privacy=False): + """ + Returns all of the loaded URLs defined in this apprise object. + """ + return [x.url(privacy=privacy) for x in self.servers] + + def pop(self, index): + """ + Removes an indexed Notification Service from the stack and returns it. + + The thing is we can never pop AppriseConfig() entries, only what was + loaded within them. So pop needs to carefully iterate over our list + and only track actual entries. + """ + + # Tracking variables + prev_offset = -1 + offset = prev_offset + + for idx, s in enumerate(self.servers): + if isinstance(s, (ConfigBase, AppriseConfig)): + servers = s.servers() + if len(servers) > 0: + # Acquire a new maximum offset to work with + offset = prev_offset + len(servers) + + if offset >= index: + # we can pop an element from our config stack + fn = s.pop if isinstance(s, ConfigBase) \ + else s.server_pop + + return fn(index if prev_offset == -1 + else (index - prev_offset - 1)) + + else: + offset = prev_offset + 1 + if offset == index: + return self.servers.pop(idx) + + # Update our old offset + prev_offset = offset + + # If we reach here, then we indexed out of range + raise IndexError('list index out of range') + + def __getitem__(self, index): + """ + Returns the indexed server entry of a loaded notification server + """ + # Tracking variables + prev_offset = -1 + offset = prev_offset + + for idx, s in enumerate(self.servers): + if isinstance(s, (ConfigBase, AppriseConfig)): + # Get our list of servers associate with our config object + servers = s.servers() + if len(servers) > 0: + # Acquire a new maximum offset to work with + offset = prev_offset + len(servers) + + if offset >= index: + return servers[index if prev_offset == -1 + else (index - prev_offset - 1)] + + else: + offset = prev_offset + 1 + if offset == index: + return self.servers[idx] + + # Update our old offset + prev_offset = offset + + # If we reach here, then we indexed out of range + raise IndexError('list index out of range') + + def __getstate__(self): + """ + Pickle Support dumps() + """ + attributes = { + 'asset': self.asset, + # Prepare our URL list as we need to extract the associated tags + # and asset details associated with it + 'urls': [{ + 'url': server.url(privacy=False), + 'tag': server.tags if server.tags else None, + 'asset': server.asset} for server in self.servers], + 'locale': self.locale, + 'debug': self.debug, + 'location': self.location, + } + + return attributes + + def __setstate__(self, state): + """ + Pickle Support loads() + """ + self.servers = list() + self.asset = state['asset'] + self.locale = state['locale'] + self.location = state['location'] + for entry in state['urls']: + self.add(entry['url'], asset=entry['asset'], tag=entry['tag']) + + def __bool__(self): + """ + Allows the Apprise object to be wrapped in an 'if statement'. + True is returned if at least one service has been loaded. + """ + return len(self) > 0 + + def __iter__(self): + """ + Returns an iterator to each of our servers loaded. This includes those + found inside configuration. + """ + return chain(*[[s] if not isinstance(s, (ConfigBase, AppriseConfig)) + else iter(s.servers()) for s in self.servers]) + + def __len__(self): + """ + Returns the number of servers loaded; this includes those found within + loaded configuration. This funtion nnever actually counts the + Config entry themselves (if they exist), only what they contain. + """ + return sum([1 if not isinstance(s, (ConfigBase, AppriseConfig)) + else len(s.servers()) for s in self.servers]) diff --git a/libs/apprise/Apprise.pyi b/libs/apprise/Apprise.pyi new file mode 100644 index 000000000..5a34c9c65 --- /dev/null +++ b/libs/apprise/Apprise.pyi @@ -0,0 +1,62 @@ +from typing import Any, Dict, List, Iterable, Iterator, Optional + +from . import (AppriseAsset, AppriseAttachment, AppriseConfig, ConfigBase, + NotifyBase, NotifyFormat, NotifyType) +from .common import ContentLocation + +_Server = Union[str, ConfigBase, NotifyBase, AppriseConfig] +_Servers = Union[_Server, Dict[Any, _Server], Iterable[_Server]] +# Can't define this recursively as mypy doesn't support recursive types: +# https://github.com/python/mypy/issues/731 +_Tag = Union[str, Iterable[Union[str, Iterable[str]]]] + +class Apprise: + def __init__( + self, + servers: _Servers = ..., + asset: Optional[AppriseAsset] = ..., + location: Optional[ContentLocation] = ..., + debug: bool = ... + ) -> None: ... + @staticmethod + def instantiate( + url: Union[str, Dict[str, NotifyBase]], + asset: Optional[AppriseAsset] = ..., + tag: Optional[_Tag] = ..., + suppress_exceptions: bool = ... + ) -> NotifyBase: ... + def add( + self, + servers: _Servers = ..., + asset: Optional[AppriseAsset] = ..., + tag: Optional[_Tag] = ... + ) -> bool: ... + def clear(self) -> None: ... + def find(self, tag: str = ...) -> Iterator[Apprise]: ... + def notify( + self, + body: str, + title: str = ..., + notify_type: NotifyType = ..., + body_format: NotifyFormat = ..., + tag: _Tag = ..., + attach: Optional[AppriseAttachment] = ..., + interpret_escapes: Optional[bool] = ... + ) -> bool: ... + async def async_notify( + self, + body: str, + title: str = ..., + notify_type: NotifyType = ..., + body_format: NotifyFormat = ..., + tag: _Tag = ..., + attach: Optional[AppriseAttachment] = ..., + interpret_escapes: Optional[bool] = ... + ) -> bool: ... + def details(self, lang: Optional[str] = ...) -> Dict[str, Any]: ... + def urls(self, privacy: bool = ...) -> Iterable[str]: ... + def pop(self, index: int) -> ConfigBase: ... + def __getitem__(self, index: int) -> ConfigBase: ... + def __bool__(self) -> bool: ... + def __iter__(self) -> Iterator[ConfigBase]: ... + def __len__(self) -> int: ... \ No newline at end of file diff --git a/libs/apprise/asset.py b/libs/apprise/AppriseAsset.py similarity index 99% rename from libs/apprise/asset.py rename to libs/apprise/AppriseAsset.py index 450303d0e..97a7bccfb 100644 --- a/libs/apprise/asset.py +++ b/libs/apprise/AppriseAsset.py @@ -33,7 +33,7 @@ from os.path import dirname from os.path import isfile from os.path import abspath from .common import NotifyType -from .manager_plugins import NotificationManager +from .NotificationManager import NotificationManager # Grant access to our Notification Manager Singleton diff --git a/libs/apprise/asset.pyi b/libs/apprise/AppriseAsset.pyi similarity index 100% rename from libs/apprise/asset.pyi rename to libs/apprise/AppriseAsset.pyi diff --git a/libs/apprise/apprise_attachment.py b/libs/apprise/AppriseAttachment.py similarity index 98% rename from libs/apprise/apprise_attachment.py rename to libs/apprise/AppriseAttachment.py index 3c33f9e73..fcfed3af6 100644 --- a/libs/apprise/apprise_attachment.py +++ b/libs/apprise/AppriseAttachment.py @@ -27,9 +27,9 @@ # POSSIBILITY OF SUCH DAMAGE. from . import URLBase -from .attachment.base import AttachBase -from .asset import AppriseAsset -from .manager_attachment import AttachmentManager +from .attachment.AttachBase import AttachBase +from .AppriseAsset import AppriseAsset +from .AttachmentManager import AttachmentManager from .logger import logger from .common import ContentLocation from .common import CONTENT_LOCATIONS diff --git a/libs/apprise/apprise_attachment.pyi b/libs/apprise/AppriseAttachment.pyi similarity index 100% rename from libs/apprise/apprise_attachment.pyi rename to libs/apprise/AppriseAttachment.pyi diff --git a/libs/apprise/apprise_config.py b/libs/apprise/AppriseConfig.py similarity index 99% rename from libs/apprise/apprise_config.py rename to libs/apprise/AppriseConfig.py index 080f70d30..7e5a9126f 100644 --- a/libs/apprise/apprise_config.py +++ b/libs/apprise/AppriseConfig.py @@ -28,9 +28,9 @@ from . import ConfigBase from . import CONFIG_FORMATS -from .manager_config import ConfigurationManager +from .ConfigurationManager import ConfigurationManager from . import URLBase -from .asset import AppriseAsset +from .AppriseAsset import AppriseAsset from . import common from .utils import GET_SCHEMA_RE from .utils import parse_list diff --git a/libs/apprise/apprise_config.pyi b/libs/apprise/AppriseConfig.pyi similarity index 100% rename from libs/apprise/apprise_config.pyi rename to libs/apprise/AppriseConfig.pyi diff --git a/libs/apprise/locale.py b/libs/apprise/AppriseLocale.py similarity index 100% rename from libs/apprise/locale.py rename to libs/apprise/AppriseLocale.py diff --git a/libs/apprise/manager_attachment.py b/libs/apprise/AttachmentManager.py similarity index 93% rename from libs/apprise/manager_attachment.py rename to libs/apprise/AttachmentManager.py index d1288a943..d296a4996 100644 --- a/libs/apprise/manager_attachment.py +++ b/libs/apprise/AttachmentManager.py @@ -26,7 +26,6 @@ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. -import re from os.path import dirname from os.path import abspath from os.path import join @@ -53,7 +52,3 @@ class AttachmentManager(PluginManager): # The module path to scan module_path = join(abspath(dirname(__file__)), _id) - - # For filtering our result set - module_filter_re = re.compile( - r'^(?P' + fname_prefix + r'(?!Base)[A-Za-z0-9]+)$') diff --git a/libs/apprise/manager_config.py b/libs/apprise/ConfigurationManager.py similarity index 93% rename from libs/apprise/manager_config.py rename to libs/apprise/ConfigurationManager.py index 69a6bedb9..6696895b9 100644 --- a/libs/apprise/manager_config.py +++ b/libs/apprise/ConfigurationManager.py @@ -26,7 +26,6 @@ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. -import re from os.path import dirname from os.path import abspath from os.path import join @@ -53,7 +52,3 @@ class ConfigurationManager(PluginManager): # The module path to scan module_path = join(abspath(dirname(__file__)), _id) - - # For filtering our result set - module_filter_re = re.compile( - r'^(?P' + fname_prefix + r'(?!Base)[A-Za-z0-9]+)$') diff --git a/libs/apprise/manager_plugins.py b/libs/apprise/NotificationManager.py similarity index 92% rename from libs/apprise/manager_plugins.py rename to libs/apprise/NotificationManager.py index 74ed370ea..abbbdd203 100644 --- a/libs/apprise/manager_plugins.py +++ b/libs/apprise/NotificationManager.py @@ -26,7 +26,6 @@ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. -import re from os.path import dirname from os.path import abspath from os.path import join @@ -53,8 +52,3 @@ class NotificationManager(PluginManager): # The module path to scan module_path = join(abspath(dirname(__file__)), _id) - - # For filtering our result set - module_filter_re = re.compile( - r'^(?P' + fname_prefix + - r'(?!Base|ImageSize|Type)[A-Za-z0-9]+)$') diff --git a/libs/apprise/url.py b/libs/apprise/URLBase.py similarity index 99% rename from libs/apprise/url.py rename to libs/apprise/URLBase.py index 39daec867..90ea85c66 100644 --- a/libs/apprise/url.py +++ b/libs/apprise/URLBase.py @@ -35,8 +35,8 @@ from xml.sax.saxutils import escape as sax_escape from urllib.parse import unquote as _unquote from urllib.parse import quote as _quote -from .locale import gettext_lazy as _ -from .asset import AppriseAsset +from .AppriseLocale import gettext_lazy as _ +from .AppriseAsset import AppriseAsset from .utils import urlencode from .utils import parse_url from .utils import parse_bool @@ -744,7 +744,7 @@ class URLBase: @staticmethod def parse_url(url, verify_host=True, plus_to_space=False, - strict_port=False, sanitize=True): + strict_port=False): """Parses the URL and returns it broken apart into a dictionary. This is very specific and customized for Apprise. @@ -765,8 +765,7 @@ class URLBase: results = parse_url( url, default_schema='unknown', verify_host=verify_host, - plus_to_space=plus_to_space, strict_port=strict_port, - sanitize=sanitize) + plus_to_space=plus_to_space, strict_port=strict_port) if not results: # We're done; we failed to parse our url diff --git a/libs/apprise/url.pyi b/libs/apprise/URLBase.pyi similarity index 100% rename from libs/apprise/url.pyi rename to libs/apprise/URLBase.pyi diff --git a/libs/apprise/__init__.py b/libs/apprise/__init__.py index 457528594..81373c75b 100644 --- a/libs/apprise/__init__.py +++ b/libs/apprise/__init__.py @@ -27,7 +27,7 @@ # POSSIBILITY OF SUCH DAMAGE. __title__ = 'Apprise' -__version__ = '1.8.0' +__version__ = '1.7.6' __author__ = 'Chris Caron' __license__ = 'BSD' __copywrite__ = 'Copyright (C) 2024 Chris Caron ' @@ -49,17 +49,16 @@ from .common import CONTENT_INCLUDE_MODES from .common import ContentLocation from .common import CONTENT_LOCATIONS -from .url import URLBase -from .url import PrivacyMode -from .plugins.base import NotifyBase -from .config.base import ConfigBase -from .attachment.base import AttachBase +from .URLBase import URLBase +from .URLBase import PrivacyMode +from .plugins.NotifyBase import NotifyBase +from .config.ConfigBase import ConfigBase +from .attachment.AttachBase import AttachBase -from .apprise import Apprise -from .locale import AppriseLocale -from .asset import AppriseAsset -from .apprise_config import AppriseConfig -from .apprise_attachment import AppriseAttachment +from .Apprise import Apprise +from .AppriseAsset import AppriseAsset +from .AppriseConfig import AppriseConfig +from .AppriseAttachment import AppriseAttachment from . import decorators @@ -74,7 +73,7 @@ logging.getLogger(__name__).addHandler(logging.NullHandler()) __all__ = [ # Core 'Apprise', 'AppriseAsset', 'AppriseConfig', 'AppriseAttachment', 'URLBase', - 'NotifyBase', 'ConfigBase', 'AttachBase', 'AppriseLocale', + 'NotifyBase', 'ConfigBase', 'AttachBase', # Reference 'NotifyType', 'NotifyImageSize', 'NotifyFormat', 'OverflowMode', diff --git a/libs/apprise/attachment/base.py b/libs/apprise/attachment/AttachBase.py similarity index 98% rename from libs/apprise/attachment/base.py rename to libs/apprise/attachment/AttachBase.py index 71e3a4d0d..8cb6bd5cb 100644 --- a/libs/apprise/attachment/base.py +++ b/libs/apprise/attachment/AttachBase.py @@ -29,10 +29,10 @@ import os import time import mimetypes -from ..url import URLBase +from ..URLBase import URLBase from ..utils import parse_bool from ..common import ContentLocation -from ..locale import gettext_lazy as _ +from ..AppriseLocale import gettext_lazy as _ class AttachBase(URLBase): @@ -315,7 +315,7 @@ class AttachBase(URLBase): "download() is implimented by the child class.") @staticmethod - def parse_url(url, verify_host=True, mimetype_db=None, sanitize=True): + def parse_url(url, verify_host=True, mimetype_db=None): """Parses the URL and returns it broken apart into a dictionary. This is very specific and customized for Apprise. @@ -333,8 +333,7 @@ class AttachBase(URLBase): successful, otherwise None is returned. """ - results = URLBase.parse_url( - url, verify_host=verify_host, sanitize=sanitize) + results = URLBase.parse_url(url, verify_host=verify_host) if not results: # We're done; we failed to parse our url diff --git a/libs/apprise/attachment/base.pyi b/libs/apprise/attachment/AttachBase.pyi similarity index 100% rename from libs/apprise/attachment/base.pyi rename to libs/apprise/attachment/AttachBase.pyi diff --git a/libs/apprise/attachment/file.py b/libs/apprise/attachment/AttachFile.py similarity index 98% rename from libs/apprise/attachment/file.py rename to libs/apprise/attachment/AttachFile.py index c48a707ae..4c9c8f136 100644 --- a/libs/apprise/attachment/file.py +++ b/libs/apprise/attachment/AttachFile.py @@ -28,9 +28,9 @@ import re import os -from .base import AttachBase +from .AttachBase import AttachBase from ..common import ContentLocation -from ..locale import gettext_lazy as _ +from ..AppriseLocale import gettext_lazy as _ class AttachFile(AttachBase): diff --git a/libs/apprise/attachment/http.py b/libs/apprise/attachment/AttachHTTP.py similarity index 98% rename from libs/apprise/attachment/http.py rename to libs/apprise/attachment/AttachHTTP.py index aa075d671..5a3af9467 100644 --- a/libs/apprise/attachment/http.py +++ b/libs/apprise/attachment/AttachHTTP.py @@ -31,10 +31,10 @@ import os import requests import threading from tempfile import NamedTemporaryFile -from .base import AttachBase +from .AttachBase import AttachBase from ..common import ContentLocation -from ..url import PrivacyMode -from ..locale import gettext_lazy as _ +from ..URLBase import PrivacyMode +from ..AppriseLocale import gettext_lazy as _ class AttachHTTP(AttachBase): @@ -296,7 +296,8 @@ class AttachHTTP(AttachBase): """ Tidy memory if open """ - self.invalidate() + with self._lock: + self.invalidate() def url(self, privacy=False, *args, **kwargs): """ @@ -362,7 +363,8 @@ class AttachHTTP(AttachBase): us to re-instantiate this object. """ - results = AttachBase.parse_url(url, sanitize=False) + results = AttachBase.parse_url(url) + if not results: # We're done early as we couldn't load the results return results diff --git a/libs/apprise/attachment/__init__.py b/libs/apprise/attachment/__init__.py index c2aef1eec..0a88313d6 100644 --- a/libs/apprise/attachment/__init__.py +++ b/libs/apprise/attachment/__init__.py @@ -27,8 +27,8 @@ # POSSIBILITY OF SUCH DAMAGE. # Used for testing -from .base import AttachBase -from ..manager_attachment import AttachmentManager +from .AttachBase import AttachBase +from ..AttachmentManager import AttachmentManager # Initalize our Attachment Manager Singleton A_MGR = AttachmentManager() @@ -36,5 +36,4 @@ A_MGR = AttachmentManager() __all__ = [ # Reference 'AttachBase', - 'AttachmentManager', ] diff --git a/libs/apprise/config/base.py b/libs/apprise/config/ConfigBase.py similarity index 99% rename from libs/apprise/config/base.py rename to libs/apprise/config/ConfigBase.py index 953cee394..32e1bde34 100644 --- a/libs/apprise/config/base.py +++ b/libs/apprise/config/ConfigBase.py @@ -33,15 +33,15 @@ import time from .. import plugins from .. import common -from ..asset import AppriseAsset -from ..url import URLBase +from ..AppriseAsset import AppriseAsset +from ..URLBase import URLBase +from ..ConfigurationManager import ConfigurationManager from ..utils import GET_SCHEMA_RE from ..utils import parse_list from ..utils import parse_bool from ..utils import parse_urls from ..utils import cwe312_url -from ..manager_config import ConfigurationManager -from ..manager_plugins import NotificationManager +from ..NotificationManager import NotificationManager # Test whether token is valid or not VALID_TOKEN = re.compile( diff --git a/libs/apprise/config/base.pyi b/libs/apprise/config/ConfigBase.pyi similarity index 100% rename from libs/apprise/config/base.pyi rename to libs/apprise/config/ConfigBase.pyi diff --git a/libs/apprise/config/file.py b/libs/apprise/config/ConfigFile.py similarity index 98% rename from libs/apprise/config/file.py rename to libs/apprise/config/ConfigFile.py index 9f29ca20b..172d699f8 100644 --- a/libs/apprise/config/file.py +++ b/libs/apprise/config/ConfigFile.py @@ -28,10 +28,10 @@ import re import os -from .base import ConfigBase +from .ConfigBase import ConfigBase from ..common import ConfigFormat from ..common import ContentIncludeMode -from ..locale import gettext_lazy as _ +from ..AppriseLocale import gettext_lazy as _ class ConfigFile(ConfigBase): diff --git a/libs/apprise/config/http.py b/libs/apprise/config/ConfigHTTP.py similarity index 98% rename from libs/apprise/config/http.py rename to libs/apprise/config/ConfigHTTP.py index 2e2ba299b..f6faba8d4 100644 --- a/libs/apprise/config/http.py +++ b/libs/apprise/config/ConfigHTTP.py @@ -28,11 +28,11 @@ import re import requests -from .base import ConfigBase +from .ConfigBase import ConfigBase from ..common import ConfigFormat from ..common import ContentIncludeMode -from ..url import PrivacyMode -from ..locale import gettext_lazy as _ +from ..URLBase import PrivacyMode +from ..AppriseLocale import gettext_lazy as _ # Support YAML formats # text/yaml diff --git a/libs/apprise/config/memory.py b/libs/apprise/config/ConfigMemory.py similarity index 97% rename from libs/apprise/config/memory.py rename to libs/apprise/config/ConfigMemory.py index 181d76236..413956dfc 100644 --- a/libs/apprise/config/memory.py +++ b/libs/apprise/config/ConfigMemory.py @@ -26,8 +26,8 @@ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. -from .base import ConfigBase -from ..locale import gettext_lazy as _ +from .ConfigBase import ConfigBase +from ..AppriseLocale import gettext_lazy as _ class ConfigMemory(ConfigBase): diff --git a/libs/apprise/config/__init__.py b/libs/apprise/config/__init__.py index 24957e88e..efbace687 100644 --- a/libs/apprise/config/__init__.py +++ b/libs/apprise/config/__init__.py @@ -27,8 +27,8 @@ # POSSIBILITY OF SUCH DAMAGE. # Used for testing -from .base import ConfigBase -from ..manager_config import ConfigurationManager +from .ConfigBase import ConfigBase +from ..ConfigurationManager import ConfigurationManager # Initalize our Config Manager Singleton C_MGR = ConfigurationManager() @@ -36,5 +36,4 @@ C_MGR = ConfigurationManager() __all__ = [ # Reference 'ConfigBase', - 'ConfigurationManager', ] diff --git a/libs/apprise/conversion.py b/libs/apprise/conversion.py index 5b6d1a941..4d5632f59 100644 --- a/libs/apprise/conversion.py +++ b/libs/apprise/conversion.py @@ -29,7 +29,7 @@ import re from markdown import markdown from .common import NotifyFormat -from .url import URLBase +from .URLBase import URLBase from html.parser import HTMLParser diff --git a/libs/apprise/decorators/base.py b/libs/apprise/decorators/CustomNotifyPlugin.py similarity index 98% rename from libs/apprise/decorators/base.py rename to libs/apprise/decorators/CustomNotifyPlugin.py index 2661db0aa..eb5f17b78 100644 --- a/libs/apprise/decorators/base.py +++ b/libs/apprise/decorators/CustomNotifyPlugin.py @@ -27,8 +27,8 @@ # POSSIBILITY OF SUCH DAMAGE.USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. -from ..plugins.base import NotifyBase -from ..manager_plugins import NotificationManager +from ..plugins.NotifyBase import NotifyBase +from ..NotificationManager import NotificationManager from ..utils import URL_DETAILS_RE from ..utils import parse_url from ..utils import url_assembly @@ -55,9 +55,6 @@ class CustomNotifyPlugin(NotifyBase): # should be treated differently. category = 'custom' - # Support Attachments - attachment_support = True - # Define object templates templates = ( '{schema}://', diff --git a/libs/apprise/decorators/notify.py b/libs/apprise/decorators/notify.py index 892c3adfe..2dd5f5099 100644 --- a/libs/apprise/decorators/notify.py +++ b/libs/apprise/decorators/notify.py @@ -26,7 +26,7 @@ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. -from .base import CustomNotifyPlugin +from .CustomNotifyPlugin import CustomNotifyPlugin def notify(on, name=None): diff --git a/libs/apprise/i18n/en/LC_MESSAGES/apprise.mo b/libs/apprise/i18n/en/LC_MESSAGES/apprise.mo index f108b538df44a22b2a18b2bb6140e8554b0428c1..1d22b89a68a0bcb2532b945c30a51bab4eccad96 100644 GIT binary patch delta 14 Vcmew^_g!v7HaDZu<{WNr762`b1ib(N delta 14 Vcmew^_g!v7HaDa3<{WNr762`h1ik((?!_)[A-Za-z0-9]+))$') - # thread safe loading _lock = threading.Lock() @@ -180,7 +177,7 @@ class PluginManager(metaclass=Singleton): # The .py extension is optional as we support loading directories # too module_re = re.compile( - r'^(?P(?!base|_)[a-z0-9_]+)(\.py)?$', + r'^(?P' + self.fname_prefix + r'[a-z0-9]+)(\.py)?$', re.I) t_start = time.time() @@ -191,6 +188,10 @@ class PluginManager(metaclass=Singleton): # keep going continue + elif match.group('name') == f'{self.fname_prefix}Base': + # keep going + continue + # Store our notification/plugin name: module_name = match.group('name') module_pyname = '{}.{}'.format(module_name_prefix, module_name) @@ -215,47 +216,7 @@ class PluginManager(metaclass=Singleton): # logging found in import_module and not needed here continue - module_class = None - for m_class in [obj for obj in dir(module) - if self.module_filter_re.match(obj)]: - # Get our plugin - plugin = getattr(module, m_class) - if not hasattr(plugin, 'app_id'): - # Filter out non-notification modules - logger.trace( - "(%s) import failed; no app_id defined in %s", - self.name, m_class, os.path.join(module_path, f)) - continue - - # Add our plugin name to our module map - self._module_map[module_name] = { - 'plugin': set([plugin]), - 'module': module, - 'path': '{}.{}'.format( - module_name_prefix, module_name), - 'native': True, - } - - fn = getattr(plugin, 'schemas', None) - schemas = set([]) if not callable(fn) else fn(plugin) - - # map our schema to our plugin - for schema in schemas: - if schema in self._schema_map: - logger.error( - "{} schema ({}) mismatch detected - {} to {}" - .format(self.name, schema, self._schema_map, - plugin)) - continue - - # Assign plugin - self._schema_map[schema] = plugin - - # Store our class - module_class = m_class - break - - if not module_class: + if not hasattr(module, module_name): # Not a library we can load as it doesn't follow the simple # rule that the class must bear the same name as the # notification file itself. @@ -265,6 +226,38 @@ class PluginManager(metaclass=Singleton): self.name, module_name, os.path.join(module_path, f)) continue + # Get our plugin + plugin = getattr(module, module_name) + if not hasattr(plugin, 'app_id'): + # Filter out non-notification modules + logger.trace( + "(%s) import failed; no app_id defined in %s", + self.name, module_name, os.path.join(module_path, f)) + continue + + # Add our plugin name to our module map + self._module_map[module_name] = { + 'plugin': set([plugin]), + 'module': module, + 'path': '{}.{}'.format(module_name_prefix, module_name), + 'native': True, + } + + fn = getattr(plugin, 'schemas', None) + schemas = set([]) if not callable(fn) else fn(plugin) + + # map our schema to our plugin + for schema in schemas: + if schema in self._schema_map: + logger.error( + "{} schema ({}) mismatch detected - {} to {}" + .format(self.name, schema, self._schema_map, + plugin)) + continue + + # Assign plugin + self._schema_map[schema] = plugin + logger.trace( '{} {} loaded in {:.6f}s'.format( self.name, module_name, (time.time() - tl_start))) diff --git a/libs/apprise/plugins/apprise_api.py b/libs/apprise/plugins/NotifyAppriseAPI.py similarity index 99% rename from libs/apprise/plugins/apprise_api.py rename to libs/apprise/plugins/NotifyAppriseAPI.py index fd71236b5..34c34a6d4 100644 --- a/libs/apprise/plugins/apprise_api.py +++ b/libs/apprise/plugins/NotifyAppriseAPI.py @@ -31,12 +31,12 @@ import requests from json import dumps import base64 -from .base import NotifyBase -from ..url import PrivacyMode +from .NotifyBase import NotifyBase +from ..URLBase import PrivacyMode from ..common import NotifyType from ..utils import parse_list from ..utils import validate_regex -from ..locale import gettext_lazy as _ +from ..AppriseLocale import gettext_lazy as _ class AppriseAPIMethod: @@ -123,7 +123,7 @@ class NotifyAppriseAPI(NotifyBase): 'type': 'string', 'required': True, 'private': True, - 'regex': (r'^[A-Z0-9_-]{1,128}$', 'i'), + 'regex': (r'^[A-Z0-9_-]{1,32}$', 'i'), }, }) diff --git a/libs/apprise/plugins/aprs.py b/libs/apprise/plugins/NotifyAprs.py similarity index 99% rename from libs/apprise/plugins/aprs.py rename to libs/apprise/plugins/NotifyAprs.py index b8adef5aa..5d8c3c100 100644 --- a/libs/apprise/plugins/aprs.py +++ b/libs/apprise/plugins/NotifyAprs.py @@ -70,9 +70,9 @@ import socket import sys from itertools import chain -from .base import NotifyBase -from ..locale import gettext_lazy as _ -from ..url import PrivacyMode +from .NotifyBase import NotifyBase +from ..AppriseLocale import gettext_lazy as _ +from ..URLBase import PrivacyMode from ..common import NotifyType from ..utils import is_call_sign from ..utils import parse_call_sign diff --git a/libs/apprise/plugins/bark.py b/libs/apprise/plugins/NotifyBark.py similarity index 99% rename from libs/apprise/plugins/bark.py rename to libs/apprise/plugins/NotifyBark.py index e2f5bbfb4..781a1515e 100644 --- a/libs/apprise/plugins/bark.py +++ b/libs/apprise/plugins/NotifyBark.py @@ -32,13 +32,13 @@ import requests import json -from .base import NotifyBase -from ..url import PrivacyMode +from .NotifyBase import NotifyBase +from ..URLBase import PrivacyMode from ..common import NotifyImageSize from ..common import NotifyType from ..utils import parse_list from ..utils import parse_bool -from ..locale import gettext_lazy as _ +from ..AppriseLocale import gettext_lazy as _ # Sounds generated off of: https://github.com/Finb/Bark/tree/master/Sounds diff --git a/libs/apprise/plugins/base.py b/libs/apprise/plugins/NotifyBase.py similarity index 99% rename from libs/apprise/plugins/base.py rename to libs/apprise/plugins/NotifyBase.py index 1abc3410e..c29417c60 100644 --- a/libs/apprise/plugins/base.py +++ b/libs/apprise/plugins/NotifyBase.py @@ -30,7 +30,7 @@ import asyncio import re from functools import partial -from ..url import URLBase +from ..URLBase import URLBase from ..common import NotifyType from ..utils import parse_bool from ..common import NOTIFY_TYPES @@ -38,8 +38,8 @@ from ..common import NotifyFormat from ..common import NOTIFY_FORMATS from ..common import OverflowMode from ..common import OVERFLOW_MODES -from ..locale import gettext_lazy as _ -from ..apprise_attachment import AppriseAttachment +from ..AppriseLocale import gettext_lazy as _ +from ..AppriseAttachment import AppriseAttachment class NotifyBase(URLBase): diff --git a/libs/apprise/plugins/base.pyi b/libs/apprise/plugins/NotifyBase.pyi similarity index 100% rename from libs/apprise/plugins/base.pyi rename to libs/apprise/plugins/NotifyBase.pyi diff --git a/libs/apprise/plugins/boxcar.py b/libs/apprise/plugins/NotifyBoxcar.py similarity index 99% rename from libs/apprise/plugins/boxcar.py rename to libs/apprise/plugins/NotifyBoxcar.py index 851cdd3d8..808920ed5 100644 --- a/libs/apprise/plugins/boxcar.py +++ b/libs/apprise/plugins/NotifyBoxcar.py @@ -35,14 +35,14 @@ from hashlib import sha1 from itertools import chain from urllib.parse import urlparse -from .base import NotifyBase -from ..url import PrivacyMode +from .NotifyBase import NotifyBase +from ..URLBase import PrivacyMode from ..utils import parse_bool from ..utils import parse_list from ..utils import validate_regex from ..common import NotifyType from ..common import NotifyImageSize -from ..locale import gettext_lazy as _ +from ..AppriseLocale import gettext_lazy as _ # Default to sending to all devices if nothing is specified DEFAULT_TAG = '@all' diff --git a/libs/apprise/plugins/bulksms.py b/libs/apprise/plugins/NotifyBulkSMS.py similarity index 99% rename from libs/apprise/plugins/bulksms.py rename to libs/apprise/plugins/NotifyBulkSMS.py index 29c4d7fac..33664fb00 100644 --- a/libs/apprise/plugins/bulksms.py +++ b/libs/apprise/plugins/NotifyBulkSMS.py @@ -36,13 +36,13 @@ import re import requests import json from itertools import chain -from .base import NotifyBase -from ..url import PrivacyMode +from .NotifyBase import NotifyBase +from ..URLBase import PrivacyMode from ..common import NotifyType from ..utils import is_phone_no from ..utils import parse_phone_no from ..utils import parse_bool -from ..locale import gettext_lazy as _ +from ..AppriseLocale import gettext_lazy as _ IS_GROUP_RE = re.compile( diff --git a/libs/apprise/plugins/bulkvs.py b/libs/apprise/plugins/NotifyBulkVS.py similarity index 99% rename from libs/apprise/plugins/bulkvs.py rename to libs/apprise/plugins/NotifyBulkVS.py index 53a363008..e912dff25 100644 --- a/libs/apprise/plugins/bulkvs.py +++ b/libs/apprise/plugins/NotifyBulkVS.py @@ -35,13 +35,13 @@ # Messaging/post_messageSend import requests import json -from .base import NotifyBase -from ..url import PrivacyMode +from .NotifyBase import NotifyBase +from ..URLBase import PrivacyMode from ..common import NotifyType from ..utils import is_phone_no from ..utils import parse_phone_no from ..utils import parse_bool -from ..locale import gettext_lazy as _ +from ..AppriseLocale import gettext_lazy as _ class NotifyBulkVS(NotifyBase): diff --git a/libs/apprise/plugins/burstsms.py b/libs/apprise/plugins/NotifyBurstSMS.py similarity index 99% rename from libs/apprise/plugins/burstsms.py rename to libs/apprise/plugins/NotifyBurstSMS.py index eb19df8e4..39606abba 100644 --- a/libs/apprise/plugins/burstsms.py +++ b/libs/apprise/plugins/NotifyBurstSMS.py @@ -33,14 +33,14 @@ # import requests -from .base import NotifyBase -from ..url import PrivacyMode +from .NotifyBase import NotifyBase +from ..URLBase import PrivacyMode from ..common import NotifyType from ..utils import is_phone_no from ..utils import parse_phone_no from ..utils import parse_bool from ..utils import validate_regex -from ..locale import gettext_lazy as _ +from ..AppriseLocale import gettext_lazy as _ class BurstSMSCountryCode: diff --git a/libs/apprise/plugins/chantify.py b/libs/apprise/plugins/NotifyChantify.py similarity index 98% rename from libs/apprise/plugins/chantify.py rename to libs/apprise/plugins/NotifyChantify.py index d549a59fa..d912bd257 100644 --- a/libs/apprise/plugins/chantify.py +++ b/libs/apprise/plugins/NotifyChantify.py @@ -35,10 +35,10 @@ import requests -from .base import NotifyBase +from .NotifyBase import NotifyBase from ..common import NotifyType from ..utils import validate_regex -from ..locale import gettext_lazy as _ +from ..AppriseLocale import gettext_lazy as _ class NotifyChantify(NotifyBase): diff --git a/libs/apprise/plugins/clicksend.py b/libs/apprise/plugins/NotifyClickSend.py similarity index 94% rename from libs/apprise/plugins/clicksend.py rename to libs/apprise/plugins/NotifyClickSend.py index 9ade1055e..5e345fe10 100644 --- a/libs/apprise/plugins/clicksend.py +++ b/libs/apprise/plugins/NotifyClickSend.py @@ -41,14 +41,15 @@ # import requests from json import dumps +from base64 import b64encode -from .base import NotifyBase -from ..url import PrivacyMode +from .NotifyBase import NotifyBase +from ..URLBase import PrivacyMode from ..common import NotifyType from ..utils import is_phone_no from ..utils import parse_phone_no from ..utils import parse_bool -from ..locale import gettext_lazy as _ +from ..AppriseLocale import gettext_lazy as _ # Extend HTTP Error Messages CLICKSEND_HTTP_ERROR_MAP = { @@ -88,7 +89,7 @@ class NotifyClickSend(NotifyBase): # Define object templates templates = ( - '{schema}://{user}:{apikey}@{targets}', + '{schema}://{user}:{password}@{targets}', ) # Define our template tokens @@ -98,12 +99,11 @@ class NotifyClickSend(NotifyBase): 'type': 'string', 'required': True, }, - 'apikey': { - 'name': _('API Key'), + 'password': { + 'name': _('Password'), 'type': 'string', 'private': True, 'required': True, - 'map_to': 'password', }, 'target_phone': { 'name': _('Target Phone No'), @@ -124,9 +124,6 @@ class NotifyClickSend(NotifyBase): 'to': { 'alias_of': 'targets', }, - 'key': { - 'alias_of': 'apikey', - }, 'batch': { 'name': _('Batch Mode'), 'type': 'bool', @@ -177,6 +174,9 @@ class NotifyClickSend(NotifyBase): headers = { 'User-Agent': self.app_id, 'Content-Type': 'application/json; charset=utf-8', + 'Authorization': 'Basic {}'.format( + b64encode('{}:{}'.format( + self.user, self.password).encode('utf-8'))), } # error tracking (used for function return) @@ -208,7 +208,6 @@ class NotifyClickSend(NotifyBase): r = requests.post( self.notify_url, data=dumps(payload), - auth=(self.user, self.password), headers=headers, verify=self.verify_certificate, timeout=self.request_timeout, @@ -323,12 +322,6 @@ class NotifyClickSend(NotifyBase): results['batch'] = \ parse_bool(results['qsd'].get('batch', False)) - # API Key - if 'key' in results['qsd'] and len(results['qsd']['key']): - # Extract the API Key from an argument - results['password'] = \ - NotifyClickSend.unquote(results['qsd']['key']) - # Support the 'to' variable so that we can support rooms this way too # The 'to' makes it easier to use yaml configuration if 'to' in results['qsd'] and len(results['qsd']['to']): diff --git a/libs/apprise/plugins/d7networks.py b/libs/apprise/plugins/NotifyD7Networks.py similarity index 99% rename from libs/apprise/plugins/d7networks.py rename to libs/apprise/plugins/NotifyD7Networks.py index ad55e2197..906ec2fb9 100644 --- a/libs/apprise/plugins/d7networks.py +++ b/libs/apprise/plugins/NotifyD7Networks.py @@ -39,13 +39,13 @@ import requests from json import dumps from json import loads -from .base import NotifyBase +from .NotifyBase import NotifyBase from ..common import NotifyType from ..utils import is_phone_no from ..utils import parse_phone_no from ..utils import validate_regex from ..utils import parse_bool -from ..locale import gettext_lazy as _ +from ..AppriseLocale import gettext_lazy as _ # Extend HTTP Error Messages D7NETWORKS_HTTP_ERROR_MAP = { diff --git a/libs/apprise/plugins/dbus.py b/libs/apprise/plugins/NotifyDBus.py similarity index 99% rename from libs/apprise/plugins/dbus.py rename to libs/apprise/plugins/NotifyDBus.py index f2361fd62..52e119813 100644 --- a/libs/apprise/plugins/dbus.py +++ b/libs/apprise/plugins/NotifyDBus.py @@ -27,11 +27,11 @@ # POSSIBILITY OF SUCH DAMAGE. import sys -from .base import NotifyBase +from .NotifyBase import NotifyBase from ..common import NotifyImageSize from ..common import NotifyType from ..utils import parse_bool -from ..locale import gettext_lazy as _ +from ..AppriseLocale import gettext_lazy as _ # Default our global support flag NOTIFY_DBUS_SUPPORT_ENABLED = False diff --git a/libs/apprise/plugins/dapnet.py b/libs/apprise/plugins/NotifyDapnet.py similarity index 99% rename from libs/apprise/plugins/dapnet.py rename to libs/apprise/plugins/NotifyDapnet.py index 60a18acd4..ae7199c94 100644 --- a/libs/apprise/plugins/dapnet.py +++ b/libs/apprise/plugins/NotifyDapnet.py @@ -51,9 +51,9 @@ from json import dumps import requests from requests.auth import HTTPBasicAuth -from .base import NotifyBase -from ..locale import gettext_lazy as _ -from ..url import PrivacyMode +from .NotifyBase import NotifyBase +from ..AppriseLocale import gettext_lazy as _ +from ..URLBase import PrivacyMode from ..common import NotifyType from ..utils import is_call_sign from ..utils import parse_call_sign diff --git a/libs/apprise/plugins/dingtalk.py b/libs/apprise/plugins/NotifyDingTalk.py similarity index 99% rename from libs/apprise/plugins/dingtalk.py rename to libs/apprise/plugins/NotifyDingTalk.py index 2ca1bc55b..d4a492fc7 100644 --- a/libs/apprise/plugins/dingtalk.py +++ b/libs/apprise/plugins/NotifyDingTalk.py @@ -34,13 +34,13 @@ import base64 import requests from json import dumps -from .base import NotifyBase -from ..url import PrivacyMode +from .NotifyBase import NotifyBase +from ..URLBase import PrivacyMode from ..common import NotifyFormat from ..common import NotifyType from ..utils import parse_list from ..utils import validate_regex -from ..locale import gettext_lazy as _ +from ..AppriseLocale import gettext_lazy as _ # Register at https://dingtalk.com # - Download their PC based software as it is the only way you can create diff --git a/libs/apprise/plugins/discord.py b/libs/apprise/plugins/NotifyDiscord.py similarity index 99% rename from libs/apprise/plugins/discord.py rename to libs/apprise/plugins/NotifyDiscord.py index 14c6152ba..82d764f50 100644 --- a/libs/apprise/plugins/discord.py +++ b/libs/apprise/plugins/NotifyDiscord.py @@ -50,14 +50,14 @@ from datetime import timedelta from datetime import datetime from datetime import timezone -from .base import NotifyBase +from .NotifyBase import NotifyBase from ..common import NotifyImageSize from ..common import NotifyFormat from ..common import NotifyType from ..utils import parse_bool from ..utils import validate_regex -from ..locale import gettext_lazy as _ -from ..attachment.base import AttachBase +from ..AppriseLocale import gettext_lazy as _ +from ..attachment.AttachBase import AttachBase # Used to detect user/role IDs diff --git a/libs/apprise/plugins/email.py b/libs/apprise/plugins/NotifyEmail.py similarity index 98% rename from libs/apprise/plugins/email.py rename to libs/apprise/plugins/NotifyEmail.py index 142c93cfb..80f88bf61 100644 --- a/libs/apprise/plugins/email.py +++ b/libs/apprise/plugins/NotifyEmail.py @@ -41,12 +41,12 @@ from socket import error as SocketError from datetime import datetime from datetime import timezone -from .base import NotifyBase -from ..url import PrivacyMode +from .NotifyBase import NotifyBase +from ..URLBase import PrivacyMode from ..common import NotifyFormat, NotifyType from ..conversion import convert_between -from ..utils import is_ipaddr, is_email, parse_emails, is_hostname -from ..locale import gettext_lazy as _ +from ..utils import is_email, parse_emails, is_hostname +from ..AppriseLocale import gettext_lazy as _ from ..logger import logger # Globally Default encoding mode set to Quoted Printable. @@ -1053,12 +1053,8 @@ class NotifyEmail(NotifyBase): # Prepare our target lists results['targets'] = [] - if is_ipaddr(results['host']): - # Silently move on and do not disrupt any configuration - pass - - elif not is_hostname(results['host'], ipv4=False, ipv6=False, - underscore=False): + if not is_hostname(results['host'], ipv4=False, ipv6=False, + underscore=False): if is_email(NotifyEmail.unquote(results['host'])): # Don't lose defined email addresses diff --git a/libs/apprise/plugins/emby.py b/libs/apprise/plugins/NotifyEmby.py similarity index 99% rename from libs/apprise/plugins/emby.py rename to libs/apprise/plugins/NotifyEmby.py index 5e4e0b89f..ce96553a2 100644 --- a/libs/apprise/plugins/emby.py +++ b/libs/apprise/plugins/NotifyEmby.py @@ -34,12 +34,12 @@ import hashlib from json import dumps from json import loads -from .base import NotifyBase -from ..url import PrivacyMode +from .NotifyBase import NotifyBase +from ..URLBase import PrivacyMode from ..utils import parse_bool from ..common import NotifyType from .. import __version__ as VERSION -from ..locale import gettext_lazy as _ +from ..AppriseLocale import gettext_lazy as _ class NotifyEmby(NotifyBase): diff --git a/libs/apprise/plugins/enigma2.py b/libs/apprise/plugins/NotifyEnigma2.py similarity index 98% rename from libs/apprise/plugins/enigma2.py rename to libs/apprise/plugins/NotifyEnigma2.py index 8b1fff687..313149993 100644 --- a/libs/apprise/plugins/enigma2.py +++ b/libs/apprise/plugins/NotifyEnigma2.py @@ -37,10 +37,10 @@ import requests from json import loads -from .base import NotifyBase -from ..url import PrivacyMode +from .NotifyBase import NotifyBase +from ..URLBase import PrivacyMode from ..common import NotifyType -from ..locale import gettext_lazy as _ +from ..AppriseLocale import gettext_lazy as _ class Enigma2MessageType: diff --git a/libs/apprise/plugins/fcm/__init__.py b/libs/apprise/plugins/NotifyFCM/__init__.py similarity index 99% rename from libs/apprise/plugins/fcm/__init__.py rename to libs/apprise/plugins/NotifyFCM/__init__.py index 9dc0679f1..54b6c9cc7 100644 --- a/libs/apprise/plugins/fcm/__init__.py +++ b/libs/apprise/plugins/NotifyFCM/__init__.py @@ -50,15 +50,15 @@ # You will need this in order to send an apprise messag import requests from json import dumps -from ..base import NotifyBase +from ..NotifyBase import NotifyBase from ...common import NotifyType from ...utils import validate_regex from ...utils import parse_list from ...utils import parse_bool from ...utils import dict_full_update from ...common import NotifyImageSize -from ...apprise_attachment import AppriseAttachment -from ...locale import gettext_lazy as _ +from ...AppriseAttachment import AppriseAttachment +from ...AppriseLocale import gettext_lazy as _ from .common import (FCMMode, FCM_MODES) from .priority import (FCM_PRIORITIES, FCMPriorityManager) from .color import FCMColorManager diff --git a/libs/apprise/plugins/fcm/color.py b/libs/apprise/plugins/NotifyFCM/color.py similarity index 99% rename from libs/apprise/plugins/fcm/color.py rename to libs/apprise/plugins/NotifyFCM/color.py index 20149eedd..c7da209a7 100644 --- a/libs/apprise/plugins/fcm/color.py +++ b/libs/apprise/plugins/NotifyFCM/color.py @@ -36,7 +36,7 @@ import re from ...utils import parse_bool from ...common import NotifyType -from ...asset import AppriseAsset +from ...AppriseAsset import AppriseAsset class FCMColorManager: diff --git a/libs/apprise/plugins/fcm/common.py b/libs/apprise/plugins/NotifyFCM/common.py similarity index 100% rename from libs/apprise/plugins/fcm/common.py rename to libs/apprise/plugins/NotifyFCM/common.py diff --git a/libs/apprise/plugins/fcm/oauth.py b/libs/apprise/plugins/NotifyFCM/oauth.py similarity index 100% rename from libs/apprise/plugins/fcm/oauth.py rename to libs/apprise/plugins/NotifyFCM/oauth.py diff --git a/libs/apprise/plugins/fcm/priority.py b/libs/apprise/plugins/NotifyFCM/priority.py similarity index 100% rename from libs/apprise/plugins/fcm/priority.py rename to libs/apprise/plugins/NotifyFCM/priority.py diff --git a/libs/apprise/plugins/feishu.py b/libs/apprise/plugins/NotifyFeishu.py similarity index 98% rename from libs/apprise/plugins/feishu.py rename to libs/apprise/plugins/NotifyFeishu.py index 961523bab..e6988333c 100644 --- a/libs/apprise/plugins/feishu.py +++ b/libs/apprise/plugins/NotifyFeishu.py @@ -36,10 +36,10 @@ import requests from json import dumps -from .base import NotifyBase +from .NotifyBase import NotifyBase from ..common import NotifyType from ..utils import validate_regex -from ..locale import gettext_lazy as _ +from ..AppriseLocale import gettext_lazy as _ class NotifyFeishu(NotifyBase): diff --git a/libs/apprise/plugins/flock.py b/libs/apprise/plugins/NotifyFlock.py similarity index 99% rename from libs/apprise/plugins/flock.py rename to libs/apprise/plugins/NotifyFlock.py index bf2cd131d..f1d12067e 100644 --- a/libs/apprise/plugins/flock.py +++ b/libs/apprise/plugins/NotifyFlock.py @@ -44,14 +44,14 @@ import re import requests from json import dumps -from .base import NotifyBase +from .NotifyBase import NotifyBase from ..common import NotifyType from ..common import NotifyFormat from ..common import NotifyImageSize from ..utils import parse_list from ..utils import parse_bool from ..utils import validate_regex -from ..locale import gettext_lazy as _ +from ..AppriseLocale import gettext_lazy as _ # Extend HTTP Error Messages diff --git a/libs/apprise/plugins/custom_form.py b/libs/apprise/plugins/NotifyForm.py similarity index 99% rename from libs/apprise/plugins/custom_form.py rename to libs/apprise/plugins/NotifyForm.py index 0f36643f7..9690cd4f5 100644 --- a/libs/apprise/plugins/custom_form.py +++ b/libs/apprise/plugins/NotifyForm.py @@ -29,11 +29,11 @@ import re import requests -from .base import NotifyBase -from ..url import PrivacyMode +from .NotifyBase import NotifyBase +from ..URLBase import PrivacyMode from ..common import NotifyImageSize from ..common import NotifyType -from ..locale import gettext_lazy as _ +from ..AppriseLocale import gettext_lazy as _ class FORMPayloadField: diff --git a/libs/apprise/plugins/freemobile.py b/libs/apprise/plugins/NotifyFreeMobile.py similarity index 98% rename from libs/apprise/plugins/freemobile.py rename to libs/apprise/plugins/NotifyFreeMobile.py index 4ff3d4822..4aad8db3d 100644 --- a/libs/apprise/plugins/freemobile.py +++ b/libs/apprise/plugins/NotifyFreeMobile.py @@ -36,9 +36,9 @@ import requests from json import dumps -from .base import NotifyBase +from .NotifyBase import NotifyBase from ..common import NotifyType -from ..locale import gettext_lazy as _ +from ..AppriseLocale import gettext_lazy as _ class NotifyFreeMobile(NotifyBase): @@ -126,7 +126,6 @@ class NotifyFreeMobile(NotifyBase): # prepare our headers headers = { 'User-Agent': self.app_id, - 'Content-Type': 'application/json', } # Prepare our payload diff --git a/libs/apprise/plugins/gnome.py b/libs/apprise/plugins/NotifyGnome.py similarity index 99% rename from libs/apprise/plugins/gnome.py rename to libs/apprise/plugins/NotifyGnome.py index b64b51304..67129216d 100644 --- a/libs/apprise/plugins/gnome.py +++ b/libs/apprise/plugins/NotifyGnome.py @@ -26,11 +26,11 @@ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. -from .base import NotifyBase +from .NotifyBase import NotifyBase from ..common import NotifyImageSize from ..common import NotifyType from ..utils import parse_bool -from ..locale import gettext_lazy as _ +from ..AppriseLocale import gettext_lazy as _ # Default our global support flag NOTIFY_GNOME_SUPPORT_ENABLED = False diff --git a/libs/apprise/plugins/google_chat.py b/libs/apprise/plugins/NotifyGoogleChat.py similarity index 99% rename from libs/apprise/plugins/google_chat.py rename to libs/apprise/plugins/NotifyGoogleChat.py index f30cdae49..d2a6cc8a8 100644 --- a/libs/apprise/plugins/google_chat.py +++ b/libs/apprise/plugins/NotifyGoogleChat.py @@ -58,11 +58,11 @@ import re import requests from json import dumps -from .base import NotifyBase +from .NotifyBase import NotifyBase from ..common import NotifyFormat from ..common import NotifyType from ..utils import validate_regex -from ..locale import gettext_lazy as _ +from ..AppriseLocale import gettext_lazy as _ class NotifyGoogleChat(NotifyBase): diff --git a/libs/apprise/plugins/gotify.py b/libs/apprise/plugins/NotifyGotify.py similarity index 99% rename from libs/apprise/plugins/gotify.py rename to libs/apprise/plugins/NotifyGotify.py index bf6c1b281..3f4ce132d 100644 --- a/libs/apprise/plugins/gotify.py +++ b/libs/apprise/plugins/NotifyGotify.py @@ -34,10 +34,10 @@ import requests from json import dumps -from .base import NotifyBase +from .NotifyBase import NotifyBase from ..common import NotifyType, NotifyFormat from ..utils import validate_regex -from ..locale import gettext_lazy as _ +from ..AppriseLocale import gettext_lazy as _ # Priorities diff --git a/libs/apprise/plugins/growl.py b/libs/apprise/plugins/NotifyGrowl.py similarity index 99% rename from libs/apprise/plugins/growl.py rename to libs/apprise/plugins/NotifyGrowl.py index 0b3672188..0b42e3bec 100644 --- a/libs/apprise/plugins/growl.py +++ b/libs/apprise/plugins/NotifyGrowl.py @@ -26,12 +26,12 @@ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. -from .base import NotifyBase -from ..url import PrivacyMode +from .NotifyBase import NotifyBase +from ..URLBase import PrivacyMode from ..common import NotifyImageSize from ..common import NotifyType from ..utils import parse_bool -from ..locale import gettext_lazy as _ +from ..AppriseLocale import gettext_lazy as _ # Default our global support flag NOTIFY_GROWL_SUPPORT_ENABLED = False diff --git a/libs/apprise/plugins/guilded.py b/libs/apprise/plugins/NotifyGuilded.py similarity index 96% rename from libs/apprise/plugins/guilded.py rename to libs/apprise/plugins/NotifyGuilded.py index 0ee07018e..0ea36d9f8 100644 --- a/libs/apprise/plugins/guilded.py +++ b/libs/apprise/plugins/NotifyGuilded.py @@ -45,11 +45,10 @@ # import re -# Import namespace so the class won't conflict with the actual Notify object -from . import discord +from .NotifyDiscord import NotifyDiscord -class NotifyGuilded(discord.NotifyDiscord): +class NotifyGuilded(NotifyDiscord): """ A wrapper to Guilded Notifications diff --git a/libs/apprise/plugins/home_assistant.py b/libs/apprise/plugins/NotifyHomeAssistant.py similarity index 98% rename from libs/apprise/plugins/home_assistant.py rename to libs/apprise/plugins/NotifyHomeAssistant.py index b0ffcaa64..0829381b9 100644 --- a/libs/apprise/plugins/home_assistant.py +++ b/libs/apprise/plugins/NotifyHomeAssistant.py @@ -34,11 +34,11 @@ from json import dumps from uuid import uuid4 -from .base import NotifyBase -from ..url import PrivacyMode +from .NotifyBase import NotifyBase +from ..URLBase import PrivacyMode from ..common import NotifyType from ..utils import validate_regex -from ..locale import gettext_lazy as _ +from ..AppriseLocale import gettext_lazy as _ class NotifyHomeAssistant(NotifyBase): diff --git a/libs/apprise/plugins/httpsms.py b/libs/apprise/plugins/NotifyHttpSMS.py similarity index 99% rename from libs/apprise/plugins/httpsms.py rename to libs/apprise/plugins/NotifyHttpSMS.py index b36e286d7..647100949 100644 --- a/libs/apprise/plugins/httpsms.py +++ b/libs/apprise/plugins/NotifyHttpSMS.py @@ -31,12 +31,12 @@ # https://httpsms.com import requests import json -from .base import NotifyBase +from .NotifyBase import NotifyBase from ..common import NotifyType from ..utils import is_phone_no from ..utils import parse_phone_no from ..utils import validate_regex -from ..locale import gettext_lazy as _ +from ..AppriseLocale import gettext_lazy as _ class NotifyHttpSMS(NotifyBase): diff --git a/libs/apprise/plugins/ifttt.py b/libs/apprise/plugins/NotifyIFTTT.py similarity index 99% rename from libs/apprise/plugins/ifttt.py rename to libs/apprise/plugins/NotifyIFTTT.py index 9d89b1464..9174640d0 100644 --- a/libs/apprise/plugins/ifttt.py +++ b/libs/apprise/plugins/NotifyIFTTT.py @@ -44,11 +44,11 @@ import re import requests from json import dumps -from .base import NotifyBase +from .NotifyBase import NotifyBase from ..common import NotifyType from ..utils import parse_list from ..utils import validate_regex -from ..locale import gettext_lazy as _ +from ..AppriseLocale import gettext_lazy as _ class NotifyIFTTT(NotifyBase): diff --git a/libs/apprise/plugins/custom_json.py b/libs/apprise/plugins/NotifyJSON.py similarity index 99% rename from libs/apprise/plugins/custom_json.py rename to libs/apprise/plugins/NotifyJSON.py index e0d7a6753..182ff77cf 100644 --- a/libs/apprise/plugins/custom_json.py +++ b/libs/apprise/plugins/NotifyJSON.py @@ -30,11 +30,11 @@ import requests import base64 from json import dumps -from .base import NotifyBase -from ..url import PrivacyMode +from .NotifyBase import NotifyBase +from ..URLBase import PrivacyMode from ..common import NotifyImageSize from ..common import NotifyType -from ..locale import gettext_lazy as _ +from ..AppriseLocale import gettext_lazy as _ class JSONPayloadField: diff --git a/libs/apprise/plugins/join.py b/libs/apprise/plugins/NotifyJoin.py similarity index 99% rename from libs/apprise/plugins/join.py rename to libs/apprise/plugins/NotifyJoin.py index b92bb37a3..c6b0d91e9 100644 --- a/libs/apprise/plugins/join.py +++ b/libs/apprise/plugins/NotifyJoin.py @@ -39,13 +39,13 @@ import re import requests -from .base import NotifyBase +from .NotifyBase import NotifyBase from ..common import NotifyImageSize from ..common import NotifyType from ..utils import parse_list from ..utils import parse_bool from ..utils import validate_regex -from ..locale import gettext_lazy as _ +from ..AppriseLocale import gettext_lazy as _ # Extend HTTP Error Messages JOIN_HTTP_ERROR_MAP = { diff --git a/libs/apprise/plugins/kavenegar.py b/libs/apprise/plugins/NotifyKavenegar.py similarity index 99% rename from libs/apprise/plugins/kavenegar.py rename to libs/apprise/plugins/NotifyKavenegar.py index e4963f409..2a9c169d7 100644 --- a/libs/apprise/plugins/kavenegar.py +++ b/libs/apprise/plugins/NotifyKavenegar.py @@ -38,12 +38,12 @@ import requests from json import loads -from .base import NotifyBase +from .NotifyBase import NotifyBase from ..common import NotifyType from ..utils import is_phone_no from ..utils import parse_phone_no from ..utils import validate_regex -from ..locale import gettext_lazy as _ +from ..AppriseLocale import gettext_lazy as _ # Extend HTTP Error Messages # Based on https://kavenegar.com/rest.html diff --git a/libs/apprise/plugins/kumulos.py b/libs/apprise/plugins/NotifyKumulos.py similarity index 99% rename from libs/apprise/plugins/kumulos.py rename to libs/apprise/plugins/NotifyKumulos.py index 504dcc379..da372e773 100644 --- a/libs/apprise/plugins/kumulos.py +++ b/libs/apprise/plugins/NotifyKumulos.py @@ -39,10 +39,10 @@ import requests from json import dumps -from .base import NotifyBase +from .NotifyBase import NotifyBase from ..common import NotifyType from ..utils import validate_regex -from ..locale import gettext_lazy as _ +from ..AppriseLocale import gettext_lazy as _ # Extend HTTP Error Messages KUMULOS_HTTP_ERROR_MAP = { diff --git a/libs/apprise/plugins/lametric.py b/libs/apprise/plugins/NotifyLametric.py similarity index 99% rename from libs/apprise/plugins/lametric.py rename to libs/apprise/plugins/NotifyLametric.py index 411b9ea21..5825d9176 100644 --- a/libs/apprise/plugins/lametric.py +++ b/libs/apprise/plugins/NotifyLametric.py @@ -90,10 +90,10 @@ import re import requests from json import dumps -from .base import NotifyBase +from .NotifyBase import NotifyBase from ..common import NotifyType from ..utils import validate_regex -from ..locale import gettext_lazy as _ +from ..AppriseLocale import gettext_lazy as _ from ..utils import is_hostname from ..utils import is_ipaddr diff --git a/libs/apprise/plugins/line.py b/libs/apprise/plugins/NotifyLine.py similarity index 98% rename from libs/apprise/plugins/line.py rename to libs/apprise/plugins/NotifyLine.py index 07a01e769..61e4f3703 100644 --- a/libs/apprise/plugins/line.py +++ b/libs/apprise/plugins/NotifyLine.py @@ -33,14 +33,14 @@ import requests import re from json import dumps -from .base import NotifyBase -from ..url import PrivacyMode +from .NotifyBase import NotifyBase +from ..URLBase import PrivacyMode from ..common import NotifyType from ..common import NotifyImageSize from ..utils import validate_regex from ..utils import parse_list from ..utils import parse_bool -from ..locale import gettext_lazy as _ +from ..AppriseLocale import gettext_lazy as _ # Used to break path apart into list of streams diff --git a/libs/apprise/plugins/lunasea.py b/libs/apprise/plugins/NotifyLunaSea.py similarity index 99% rename from libs/apprise/plugins/lunasea.py rename to libs/apprise/plugins/NotifyLunaSea.py index 2af519179..51d820915 100644 --- a/libs/apprise/plugins/lunasea.py +++ b/libs/apprise/plugins/NotifyLunaSea.py @@ -33,15 +33,15 @@ import re import requests from json import dumps -from .base import NotifyBase +from .NotifyBase import NotifyBase from ..common import NotifyType from ..common import NotifyImageSize from ..utils import parse_list from ..utils import is_hostname from ..utils import is_ipaddr from ..utils import parse_bool -from ..locale import gettext_lazy as _ -from ..url import PrivacyMode +from ..AppriseLocale import gettext_lazy as _ +from ..URLBase import PrivacyMode class LunaSeaMode: diff --git a/libs/apprise/plugins/mqtt.py b/libs/apprise/plugins/NotifyMQTT.py similarity index 99% rename from libs/apprise/plugins/mqtt.py rename to libs/apprise/plugins/NotifyMQTT.py index 1e09cd147..49380d330 100644 --- a/libs/apprise/plugins/mqtt.py +++ b/libs/apprise/plugins/NotifyMQTT.py @@ -38,12 +38,12 @@ import re from time import sleep from datetime import datetime from os.path import isfile -from .base import NotifyBase -from ..url import PrivacyMode +from .NotifyBase import NotifyBase +from ..URLBase import PrivacyMode from ..common import NotifyType from ..utils import parse_list from ..utils import parse_bool -from ..locale import gettext_lazy as _ +from ..AppriseLocale import gettext_lazy as _ # Default our global support flag NOTIFY_MQTT_SUPPORT_ENABLED = False diff --git a/libs/apprise/plugins/msg91.py b/libs/apprise/plugins/NotifyMSG91.py similarity index 99% rename from libs/apprise/plugins/msg91.py rename to libs/apprise/plugins/NotifyMSG91.py index 28a5bf183..a7bd9c473 100644 --- a/libs/apprise/plugins/msg91.py +++ b/libs/apprise/plugins/NotifyMSG91.py @@ -38,12 +38,12 @@ import re import requests from json import dumps -from .base import NotifyBase +from .NotifyBase import NotifyBase from ..common import NotifyType from ..utils import is_phone_no from ..utils import parse_phone_no, parse_bool from ..utils import validate_regex -from ..locale import gettext_lazy as _ +from ..AppriseLocale import gettext_lazy as _ class MSG91PayloadField: diff --git a/libs/apprise/plugins/msteams.py b/libs/apprise/plugins/NotifyMSTeams.py similarity index 99% rename from libs/apprise/plugins/msteams.py rename to libs/apprise/plugins/NotifyMSTeams.py index 2e0957f32..06572c3e6 100644 --- a/libs/apprise/plugins/msteams.py +++ b/libs/apprise/plugins/NotifyMSTeams.py @@ -81,7 +81,7 @@ import requests import json from json.decoder import JSONDecodeError -from .base import NotifyBase +from .NotifyBase import NotifyBase from ..common import NotifyImageSize from ..common import NotifyType from ..common import NotifyFormat @@ -89,8 +89,8 @@ from ..utils import parse_bool from ..utils import validate_regex from ..utils import apply_template from ..utils import TemplateType -from ..apprise_attachment import AppriseAttachment -from ..locale import gettext_lazy as _ +from ..AppriseAttachment import AppriseAttachment +from ..AppriseLocale import gettext_lazy as _ class NotifyMSTeams(NotifyBase): diff --git a/libs/apprise/plugins/macosx.py b/libs/apprise/plugins/NotifyMacOSX.py similarity index 99% rename from libs/apprise/plugins/macosx.py rename to libs/apprise/plugins/NotifyMacOSX.py index 31b7101bd..dd53369fe 100644 --- a/libs/apprise/plugins/macosx.py +++ b/libs/apprise/plugins/NotifyMacOSX.py @@ -30,11 +30,11 @@ import platform import subprocess import os -from .base import NotifyBase +from .NotifyBase import NotifyBase from ..common import NotifyImageSize from ..common import NotifyType from ..utils import parse_bool -from ..locale import gettext_lazy as _ +from ..AppriseLocale import gettext_lazy as _ # Default our global support flag NOTIFY_MACOSX_SUPPORT_ENABLED = False diff --git a/libs/apprise/plugins/mailgun.py b/libs/apprise/plugins/NotifyMailgun.py similarity index 99% rename from libs/apprise/plugins/mailgun.py rename to libs/apprise/plugins/NotifyMailgun.py index 69ab72dda..82cf970bf 100644 --- a/libs/apprise/plugins/mailgun.py +++ b/libs/apprise/plugins/NotifyMailgun.py @@ -56,7 +56,7 @@ # import requests from email.utils import formataddr -from .base import NotifyBase +from .NotifyBase import NotifyBase from ..common import NotifyType from ..common import NotifyFormat from ..utils import parse_emails @@ -64,7 +64,7 @@ from ..utils import parse_bool from ..utils import is_email from ..utils import validate_regex from ..logger import logger -from ..locale import gettext_lazy as _ +from ..AppriseLocale import gettext_lazy as _ # Provide some known codes Mailgun uses and what they translate to: # Based on https://documentation.mailgun.com/en/latest/api-intro.html#errors diff --git a/libs/apprise/plugins/mastodon.py b/libs/apprise/plugins/NotifyMastodon.py similarity index 99% rename from libs/apprise/plugins/mastodon.py rename to libs/apprise/plugins/NotifyMastodon.py index b6e451ad1..0d2f27df3 100644 --- a/libs/apprise/plugins/mastodon.py +++ b/libs/apprise/plugins/NotifyMastodon.py @@ -33,16 +33,16 @@ from json import dumps, loads from datetime import datetime from datetime import timezone -from .base import NotifyBase -from ..url import PrivacyMode +from .NotifyBase import NotifyBase +from ..URLBase import PrivacyMode from ..common import NotifyImageSize from ..common import NotifyFormat from ..common import NotifyType from ..utils import parse_list from ..utils import parse_bool from ..utils import validate_regex -from ..locale import gettext_lazy as _ -from ..attachment.base import AttachBase +from ..AppriseLocale import gettext_lazy as _ +from ..attachment.AttachBase import AttachBase # Accept: # - @username diff --git a/libs/apprise/plugins/matrix.py b/libs/apprise/plugins/NotifyMatrix.py similarity index 99% rename from libs/apprise/plugins/matrix.py rename to libs/apprise/plugins/NotifyMatrix.py index c1401f238..594274761 100644 --- a/libs/apprise/plugins/matrix.py +++ b/libs/apprise/plugins/NotifyMatrix.py @@ -37,8 +37,8 @@ from json import dumps from json import loads from time import time -from .base import NotifyBase -from ..url import PrivacyMode +from .NotifyBase import NotifyBase +from ..URLBase import PrivacyMode from ..common import NotifyType from ..common import NotifyImageSize from ..common import NotifyFormat @@ -46,7 +46,7 @@ from ..utils import parse_bool from ..utils import parse_list from ..utils import is_hostname from ..utils import validate_regex -from ..locale import gettext_lazy as _ +from ..AppriseLocale import gettext_lazy as _ # Define default path MATRIX_V1_WEBHOOK_PATH = '/api/v1/matrix/hook' diff --git a/libs/apprise/plugins/mattermost.py b/libs/apprise/plugins/NotifyMattermost.py similarity index 99% rename from libs/apprise/plugins/mattermost.py rename to libs/apprise/plugins/NotifyMattermost.py index 481a9b852..dbb5f0dd3 100644 --- a/libs/apprise/plugins/mattermost.py +++ b/libs/apprise/plugins/NotifyMattermost.py @@ -39,13 +39,13 @@ import requests from json import dumps -from .base import NotifyBase +from .NotifyBase import NotifyBase from ..common import NotifyImageSize from ..common import NotifyType from ..utils import parse_bool from ..utils import parse_list from ..utils import validate_regex -from ..locale import gettext_lazy as _ +from ..AppriseLocale import gettext_lazy as _ # Some Reference Locations: # - https://docs.mattermost.com/developer/webhooks-incoming.html diff --git a/libs/apprise/plugins/messagebird.py b/libs/apprise/plugins/NotifyMessageBird.py similarity index 99% rename from libs/apprise/plugins/messagebird.py rename to libs/apprise/plugins/NotifyMessageBird.py index c496d347e..42d880acd 100644 --- a/libs/apprise/plugins/messagebird.py +++ b/libs/apprise/plugins/NotifyMessageBird.py @@ -34,12 +34,12 @@ import requests -from .base import NotifyBase +from .NotifyBase import NotifyBase from ..common import NotifyType from ..utils import is_phone_no from ..utils import parse_phone_no from ..utils import validate_regex -from ..locale import gettext_lazy as _ +from ..AppriseLocale import gettext_lazy as _ class NotifyMessageBird(NotifyBase): diff --git a/libs/apprise/plugins/misskey.py b/libs/apprise/plugins/NotifyMisskey.py similarity index 99% rename from libs/apprise/plugins/misskey.py rename to libs/apprise/plugins/NotifyMisskey.py index 73b8f7c6e..8965a0f7b 100644 --- a/libs/apprise/plugins/misskey.py +++ b/libs/apprise/plugins/NotifyMisskey.py @@ -47,10 +47,10 @@ import requests from json import dumps -from .base import NotifyBase +from .NotifyBase import NotifyBase from ..common import NotifyType from ..utils import validate_regex -from ..locale import gettext_lazy as _ +from ..AppriseLocale import gettext_lazy as _ class MisskeyVisibility: diff --git a/libs/apprise/plugins/nextcloud.py b/libs/apprise/plugins/NotifyNextcloud.py similarity index 99% rename from libs/apprise/plugins/nextcloud.py rename to libs/apprise/plugins/NotifyNextcloud.py index 9acfc43d5..fd471d9eb 100644 --- a/libs/apprise/plugins/nextcloud.py +++ b/libs/apprise/plugins/NotifyNextcloud.py @@ -28,11 +28,11 @@ import requests -from .base import NotifyBase -from ..url import PrivacyMode +from .NotifyBase import NotifyBase +from ..URLBase import PrivacyMode from ..common import NotifyType from ..utils import parse_list -from ..locale import gettext_lazy as _ +from ..AppriseLocale import gettext_lazy as _ class NotifyNextcloud(NotifyBase): diff --git a/libs/apprise/plugins/nextcloudtalk.py b/libs/apprise/plugins/NotifyNextcloudTalk.py similarity index 98% rename from libs/apprise/plugins/nextcloudtalk.py rename to libs/apprise/plugins/NotifyNextcloudTalk.py index b1b014770..4bfced282 100644 --- a/libs/apprise/plugins/nextcloudtalk.py +++ b/libs/apprise/plugins/NotifyNextcloudTalk.py @@ -29,11 +29,11 @@ import requests from json import dumps -from .base import NotifyBase -from ..url import PrivacyMode +from .NotifyBase import NotifyBase +from ..URLBase import PrivacyMode from ..common import NotifyType from ..utils import parse_list -from ..locale import gettext_lazy as _ +from ..AppriseLocale import gettext_lazy as _ class NotifyNextcloudTalk(NotifyBase): diff --git a/libs/apprise/plugins/notica.py b/libs/apprise/plugins/NotifyNotica.py similarity index 99% rename from libs/apprise/plugins/notica.py rename to libs/apprise/plugins/NotifyNotica.py index 661fde1d1..33a94fc96 100644 --- a/libs/apprise/plugins/notica.py +++ b/libs/apprise/plugins/NotifyNotica.py @@ -43,11 +43,11 @@ import re import requests -from .base import NotifyBase -from ..url import PrivacyMode +from .NotifyBase import NotifyBase +from ..URLBase import PrivacyMode from ..common import NotifyType from ..utils import validate_regex -from ..locale import gettext_lazy as _ +from ..AppriseLocale import gettext_lazy as _ class NoticaMode: diff --git a/libs/apprise/plugins/notifiarr.py b/libs/apprise/plugins/NotifyNotifiarr.py similarity index 99% rename from libs/apprise/plugins/notifiarr.py rename to libs/apprise/plugins/NotifyNotifiarr.py index cc13e1a56..e195cbd32 100644 --- a/libs/apprise/plugins/notifiarr.py +++ b/libs/apprise/plugins/NotifyNotifiarr.py @@ -31,9 +31,9 @@ import requests from json import dumps from itertools import chain -from .base import NotifyBase +from .NotifyBase import NotifyBase from ..common import NotifyType -from ..locale import gettext_lazy as _ +from ..AppriseLocale import gettext_lazy as _ from ..common import NotifyImageSize from ..utils import parse_list, parse_bool from ..utils import validate_regex diff --git a/libs/apprise/plugins/notifico.py b/libs/apprise/plugins/NotifyNotifico.py similarity index 99% rename from libs/apprise/plugins/notifico.py rename to libs/apprise/plugins/NotifyNotifico.py index 5cb0d666e..27ce29a6e 100644 --- a/libs/apprise/plugins/notifico.py +++ b/libs/apprise/plugins/NotifyNotifico.py @@ -44,11 +44,11 @@ import re import requests -from .base import NotifyBase +from .NotifyBase import NotifyBase from ..common import NotifyType from ..utils import parse_bool from ..utils import validate_regex -from ..locale import gettext_lazy as _ +from ..AppriseLocale import gettext_lazy as _ class NotificoFormat: diff --git a/libs/apprise/plugins/ntfy.py b/libs/apprise/plugins/NotifyNtfy.py similarity index 99% rename from libs/apprise/plugins/ntfy.py rename to libs/apprise/plugins/NotifyNtfy.py index 805b87260..40834eece 100644 --- a/libs/apprise/plugins/ntfy.py +++ b/libs/apprise/plugins/NotifyNtfy.py @@ -41,18 +41,18 @@ from json import loads from json import dumps from os.path import basename -from .base import NotifyBase +from .NotifyBase import NotifyBase from ..common import NotifyFormat from ..common import NotifyType from ..common import NotifyImageSize -from ..locale import gettext_lazy as _ +from ..AppriseLocale import gettext_lazy as _ from ..utils import parse_list from ..utils import parse_bool from ..utils import is_hostname from ..utils import is_ipaddr from ..utils import validate_regex -from ..url import PrivacyMode -from ..attachment.base import AttachBase +from ..URLBase import PrivacyMode +from ..attachment.AttachBase import AttachBase class NtfyMode: diff --git a/libs/apprise/plugins/office365.py b/libs/apprise/plugins/NotifyOffice365.py similarity index 99% rename from libs/apprise/plugins/office365.py rename to libs/apprise/plugins/NotifyOffice365.py index b04f7a037..0c62279f9 100644 --- a/libs/apprise/plugins/office365.py +++ b/libs/apprise/plugins/NotifyOffice365.py @@ -64,14 +64,14 @@ from datetime import datetime from datetime import timedelta from json import loads from json import dumps -from .base import NotifyBase -from ..url import PrivacyMode +from .NotifyBase import NotifyBase +from ..URLBase import PrivacyMode from ..common import NotifyFormat from ..common import NotifyType from ..utils import is_email from ..utils import parse_emails from ..utils import validate_regex -from ..locale import gettext_lazy as _ +from ..AppriseLocale import gettext_lazy as _ class NotifyOffice365(NotifyBase): diff --git a/libs/apprise/plugins/one_signal.py b/libs/apprise/plugins/NotifyOneSignal.py similarity index 99% rename from libs/apprise/plugins/one_signal.py rename to libs/apprise/plugins/NotifyOneSignal.py index 76ec212f4..eb1e10f7a 100644 --- a/libs/apprise/plugins/one_signal.py +++ b/libs/apprise/plugins/NotifyOneSignal.py @@ -37,14 +37,14 @@ import requests from json import dumps from itertools import chain -from .base import NotifyBase +from .NotifyBase import NotifyBase from ..common import NotifyType from ..common import NotifyImageSize from ..utils import validate_regex from ..utils import parse_list from ..utils import parse_bool from ..utils import is_email -from ..locale import gettext_lazy as _ +from ..AppriseLocale import gettext_lazy as _ class OneSignalCategory: diff --git a/libs/apprise/plugins/opsgenie.py b/libs/apprise/plugins/NotifyOpsgenie.py similarity index 99% rename from libs/apprise/plugins/opsgenie.py rename to libs/apprise/plugins/NotifyOpsgenie.py index 5327ec803..c2dfed232 100644 --- a/libs/apprise/plugins/opsgenie.py +++ b/libs/apprise/plugins/NotifyOpsgenie.py @@ -49,13 +49,13 @@ import requests from json import dumps -from .base import NotifyBase +from .NotifyBase import NotifyBase from ..common import NotifyType from ..utils import validate_regex from ..utils import is_uuid from ..utils import parse_list from ..utils import parse_bool -from ..locale import gettext_lazy as _ +from ..AppriseLocale import gettext_lazy as _ class OpsgenieCategory(NotifyBase): diff --git a/libs/apprise/plugins/pagerduty.py b/libs/apprise/plugins/NotifyPagerDuty.py similarity index 99% rename from libs/apprise/plugins/pagerduty.py rename to libs/apprise/plugins/NotifyPagerDuty.py index c9d555527..0896b41b1 100644 --- a/libs/apprise/plugins/pagerduty.py +++ b/libs/apprise/plugins/NotifyPagerDuty.py @@ -34,13 +34,13 @@ import requests from json import dumps -from .base import NotifyBase -from ..url import PrivacyMode +from .NotifyBase import NotifyBase +from ..URLBase import PrivacyMode from ..common import NotifyType from ..common import NotifyImageSize from ..utils import validate_regex from ..utils import parse_bool -from ..locale import gettext_lazy as _ +from ..AppriseLocale import gettext_lazy as _ class PagerDutySeverity: diff --git a/libs/apprise/plugins/pagertree.py b/libs/apprise/plugins/NotifyPagerTree.py similarity index 99% rename from libs/apprise/plugins/pagertree.py rename to libs/apprise/plugins/NotifyPagerTree.py index 8a041a358..c9290f2f7 100644 --- a/libs/apprise/plugins/pagertree.py +++ b/libs/apprise/plugins/NotifyPagerTree.py @@ -31,11 +31,11 @@ from json import dumps from uuid import uuid4 -from .base import NotifyBase +from .NotifyBase import NotifyBase from ..common import NotifyType from ..utils import parse_list from ..utils import validate_regex -from ..locale import gettext_lazy as _ +from ..AppriseLocale import gettext_lazy as _ # Actions diff --git a/libs/apprise/plugins/parseplatform.py b/libs/apprise/plugins/NotifyParsePlatform.py similarity index 99% rename from libs/apprise/plugins/parseplatform.py rename to libs/apprise/plugins/NotifyParsePlatform.py index cd59d0575..2a182ed31 100644 --- a/libs/apprise/plugins/parseplatform.py +++ b/libs/apprise/plugins/NotifyParsePlatform.py @@ -30,10 +30,10 @@ import re import requests from json import dumps -from .base import NotifyBase +from .NotifyBase import NotifyBase from ..common import NotifyType from ..utils import validate_regex -from ..locale import gettext_lazy as _ +from ..AppriseLocale import gettext_lazy as _ # Used to break path apart into list of targets TARGET_LIST_DELIM = re.compile(r'[ \t\r\n,\\/]+') diff --git a/libs/apprise/plugins/popcorn_notify.py b/libs/apprise/plugins/NotifyPopcornNotify.py similarity index 99% rename from libs/apprise/plugins/popcorn_notify.py rename to libs/apprise/plugins/NotifyPopcornNotify.py index 388aa2199..0ecd8af68 100644 --- a/libs/apprise/plugins/popcorn_notify.py +++ b/libs/apprise/plugins/NotifyPopcornNotify.py @@ -28,14 +28,14 @@ import requests -from .base import NotifyBase +from .NotifyBase import NotifyBase from ..common import NotifyType from ..utils import is_email from ..utils import is_phone_no from ..utils import parse_list from ..utils import parse_bool from ..utils import validate_regex -from ..locale import gettext_lazy as _ +from ..AppriseLocale import gettext_lazy as _ class NotifyPopcornNotify(NotifyBase): diff --git a/libs/apprise/plugins/prowl.py b/libs/apprise/plugins/NotifyProwl.py similarity index 99% rename from libs/apprise/plugins/prowl.py rename to libs/apprise/plugins/NotifyProwl.py index c174615c0..e5c07bf4e 100644 --- a/libs/apprise/plugins/prowl.py +++ b/libs/apprise/plugins/NotifyProwl.py @@ -28,10 +28,10 @@ import requests -from .base import NotifyBase +from .NotifyBase import NotifyBase from ..common import NotifyType from ..utils import validate_regex -from ..locale import gettext_lazy as _ +from ..AppriseLocale import gettext_lazy as _ # Priorities diff --git a/libs/apprise/plugins/pushbullet.py b/libs/apprise/plugins/NotifyPushBullet.py similarity index 99% rename from libs/apprise/plugins/pushbullet.py rename to libs/apprise/plugins/NotifyPushBullet.py index 8e006db1d..5e9c43fbf 100644 --- a/libs/apprise/plugins/pushbullet.py +++ b/libs/apprise/plugins/NotifyPushBullet.py @@ -30,13 +30,13 @@ import requests from json import dumps from json import loads -from .base import NotifyBase +from .NotifyBase import NotifyBase from ..utils import is_email from ..common import NotifyType from ..utils import parse_list from ..utils import validate_regex -from ..locale import gettext_lazy as _ -from ..attachment.base import AttachBase +from ..AppriseLocale import gettext_lazy as _ +from ..attachment.AttachBase import AttachBase # Flag used as a placeholder to sending to all devices PUSHBULLET_SEND_TO_ALL = 'ALL_DEVICES' diff --git a/libs/apprise/plugins/pushdeer.py b/libs/apprise/plugins/NotifyPushDeer.py similarity index 98% rename from libs/apprise/plugins/pushdeer.py rename to libs/apprise/plugins/NotifyPushDeer.py index fa888b159..6766dc7ff 100644 --- a/libs/apprise/plugins/pushdeer.py +++ b/libs/apprise/plugins/NotifyPushDeer.py @@ -29,9 +29,9 @@ import requests from ..common import NotifyType -from .base import NotifyBase +from .NotifyBase import NotifyBase from ..utils import validate_regex -from ..locale import gettext_lazy as _ +from ..AppriseLocale import gettext_lazy as _ # Syntax: # schan://{key}/ diff --git a/libs/apprise/plugins/pushme.py b/libs/apprise/plugins/NotifyPushMe.py similarity index 98% rename from libs/apprise/plugins/pushme.py rename to libs/apprise/plugins/NotifyPushMe.py index abbed7944..30889f868 100644 --- a/libs/apprise/plugins/pushme.py +++ b/libs/apprise/plugins/NotifyPushMe.py @@ -28,12 +28,12 @@ import requests -from .base import NotifyBase +from .NotifyBase import NotifyBase from ..common import NotifyType from ..common import NotifyFormat from ..utils import validate_regex from ..utils import parse_bool -from ..locale import gettext_lazy as _ +from ..AppriseLocale import gettext_lazy as _ class NotifyPushMe(NotifyBase): diff --git a/libs/apprise/plugins/pushsafer.py b/libs/apprise/plugins/NotifyPushSafer.py similarity index 99% rename from libs/apprise/plugins/pushsafer.py rename to libs/apprise/plugins/NotifyPushSafer.py index 7bdca7a69..32cfa82fe 100644 --- a/libs/apprise/plugins/pushsafer.py +++ b/libs/apprise/plugins/NotifyPushSafer.py @@ -30,11 +30,11 @@ import base64 import requests from json import loads -from .base import NotifyBase +from .NotifyBase import NotifyBase from ..common import NotifyType from ..utils import parse_list from ..utils import validate_regex -from ..locale import gettext_lazy as _ +from ..AppriseLocale import gettext_lazy as _ class PushSaferSound: diff --git a/libs/apprise/plugins/pushed.py b/libs/apprise/plugins/NotifyPushed.py similarity index 99% rename from libs/apprise/plugins/pushed.py rename to libs/apprise/plugins/NotifyPushed.py index 1ed83b9e4..a50970f99 100644 --- a/libs/apprise/plugins/pushed.py +++ b/libs/apprise/plugins/NotifyPushed.py @@ -31,12 +31,12 @@ import requests from json import dumps from itertools import chain -from .base import NotifyBase -from ..url import PrivacyMode +from .NotifyBase import NotifyBase +from ..URLBase import PrivacyMode from ..common import NotifyType from ..utils import parse_list from ..utils import validate_regex -from ..locale import gettext_lazy as _ +from ..AppriseLocale import gettext_lazy as _ # Used to detect and parse channels IS_CHANNEL = re.compile(r'^#?(?P[A-Za-z0-9]+)$') diff --git a/libs/apprise/plugins/pushjet.py b/libs/apprise/plugins/NotifyPushjet.py similarity index 98% rename from libs/apprise/plugins/pushjet.py rename to libs/apprise/plugins/NotifyPushjet.py index f8dcfdf31..253ac6818 100644 --- a/libs/apprise/plugins/pushjet.py +++ b/libs/apprise/plugins/NotifyPushjet.py @@ -29,11 +29,11 @@ import requests from json import dumps -from .base import NotifyBase -from ..url import PrivacyMode +from .NotifyBase import NotifyBase +from ..URLBase import PrivacyMode from ..common import NotifyType from ..utils import validate_regex -from ..locale import gettext_lazy as _ +from ..AppriseLocale import gettext_lazy as _ class NotifyPushjet(NotifyBase): diff --git a/libs/apprise/plugins/pushover.py b/libs/apprise/plugins/NotifyPushover.py similarity index 99% rename from libs/apprise/plugins/pushover.py rename to libs/apprise/plugins/NotifyPushover.py index 954e7dd0f..be6ada289 100644 --- a/libs/apprise/plugins/pushover.py +++ b/libs/apprise/plugins/NotifyPushover.py @@ -30,14 +30,14 @@ import re import requests from itertools import chain -from .base import NotifyBase +from .NotifyBase import NotifyBase from ..common import NotifyType from ..common import NotifyFormat from ..conversion import convert_between from ..utils import parse_list from ..utils import validate_regex -from ..locale import gettext_lazy as _ -from ..attachment.base import AttachBase +from ..AppriseLocale import gettext_lazy as _ +from ..attachment.AttachBase import AttachBase # Flag used as a placeholder to sending to all devices PUSHOVER_SEND_TO_ALL = 'ALL_DEVICES' diff --git a/libs/apprise/plugins/pushy.py b/libs/apprise/plugins/NotifyPushy.py similarity index 99% rename from libs/apprise/plugins/pushy.py rename to libs/apprise/plugins/NotifyPushy.py index bb2a24ecd..097017dac 100644 --- a/libs/apprise/plugins/pushy.py +++ b/libs/apprise/plugins/NotifyPushy.py @@ -32,11 +32,11 @@ import requests from itertools import chain from json import dumps, loads -from .base import NotifyBase +from .NotifyBase import NotifyBase from ..common import NotifyType from ..utils import parse_list from ..utils import validate_regex -from ..locale import gettext_lazy as _ +from ..AppriseLocale import gettext_lazy as _ # Used to detect a Device and Topic VALIDATE_DEVICE = re.compile(r'^@(?P[a-z0-9]+)$', re.I) diff --git a/libs/apprise/plugins/rsyslog.py b/libs/apprise/plugins/NotifyRSyslog.py similarity index 99% rename from libs/apprise/plugins/rsyslog.py rename to libs/apprise/plugins/NotifyRSyslog.py index 9631c72fd..e39744627 100644 --- a/libs/apprise/plugins/rsyslog.py +++ b/libs/apprise/plugins/NotifyRSyslog.py @@ -29,10 +29,10 @@ import os import socket -from .base import NotifyBase +from .NotifyBase import NotifyBase from ..common import NotifyType from ..utils import parse_bool -from ..locale import gettext_lazy as _ +from ..AppriseLocale import gettext_lazy as _ class syslog: diff --git a/libs/apprise/plugins/reddit.py b/libs/apprise/plugins/NotifyReddit.py similarity index 99% rename from libs/apprise/plugins/reddit.py rename to libs/apprise/plugins/NotifyReddit.py index 3a60b5e03..022a0a50d 100644 --- a/libs/apprise/plugins/reddit.py +++ b/libs/apprise/plugins/NotifyReddit.py @@ -53,14 +53,14 @@ from datetime import timedelta from datetime import datetime from datetime import timezone -from .base import NotifyBase -from ..url import PrivacyMode +from .NotifyBase import NotifyBase +from ..URLBase import PrivacyMode from ..common import NotifyFormat from ..common import NotifyType from ..utils import parse_list from ..utils import parse_bool from ..utils import validate_regex -from ..locale import gettext_lazy as _ +from ..AppriseLocale import gettext_lazy as _ from .. import __title__, __version__ # Extend HTTP Error Messages diff --git a/libs/apprise/plugins/revolt.py b/libs/apprise/plugins/NotifyRevolt.py similarity index 99% rename from libs/apprise/plugins/revolt.py rename to libs/apprise/plugins/NotifyRevolt.py index 1f518540b..ae0a43b10 100644 --- a/libs/apprise/plugins/revolt.py +++ b/libs/apprise/plugins/NotifyRevolt.py @@ -42,13 +42,13 @@ from datetime import timedelta from datetime import datetime from datetime import timezone -from .base import NotifyBase +from .NotifyBase import NotifyBase from ..common import NotifyImageSize from ..common import NotifyFormat from ..common import NotifyType from ..utils import validate_regex from ..utils import parse_list -from ..locale import gettext_lazy as _ +from ..AppriseLocale import gettext_lazy as _ class NotifyRevolt(NotifyBase): diff --git a/libs/apprise/plugins/rocketchat.py b/libs/apprise/plugins/NotifyRocketChat.py similarity index 99% rename from libs/apprise/plugins/rocketchat.py rename to libs/apprise/plugins/NotifyRocketChat.py index 973651e30..9011a5e71 100644 --- a/libs/apprise/plugins/rocketchat.py +++ b/libs/apprise/plugins/NotifyRocketChat.py @@ -32,14 +32,14 @@ from json import loads from json import dumps from itertools import chain -from .base import NotifyBase -from ..url import PrivacyMode +from .NotifyBase import NotifyBase +from ..URLBase import PrivacyMode from ..common import NotifyImageSize from ..common import NotifyFormat from ..common import NotifyType from ..utils import parse_list from ..utils import parse_bool -from ..locale import gettext_lazy as _ +from ..AppriseLocale import gettext_lazy as _ IS_CHANNEL = re.compile(r'^#(?P[A-Za-z0-9_-]+)$') IS_USER = re.compile(r'^@(?P[A-Za-z0-9._-]+)$') diff --git a/libs/apprise/plugins/ryver.py b/libs/apprise/plugins/NotifyRyver.py similarity index 99% rename from libs/apprise/plugins/ryver.py rename to libs/apprise/plugins/NotifyRyver.py index 114dc6a0c..0872f3e52 100644 --- a/libs/apprise/plugins/ryver.py +++ b/libs/apprise/plugins/NotifyRyver.py @@ -38,12 +38,12 @@ import re import requests from json import dumps -from .base import NotifyBase +from .NotifyBase import NotifyBase from ..common import NotifyImageSize from ..common import NotifyType from ..utils import parse_bool from ..utils import validate_regex -from ..locale import gettext_lazy as _ +from ..AppriseLocale import gettext_lazy as _ class RyverWebhookMode: diff --git a/libs/apprise/plugins/ses.py b/libs/apprise/plugins/NotifySES.py similarity index 99% rename from libs/apprise/plugins/ses.py rename to libs/apprise/plugins/NotifySES.py index 5a2c047a7..b580b14d6 100644 --- a/libs/apprise/plugins/ses.py +++ b/libs/apprise/plugins/NotifySES.py @@ -95,13 +95,13 @@ from email.utils import formataddr from email.header import Header from urllib.parse import quote -from .base import NotifyBase -from ..url import PrivacyMode +from .NotifyBase import NotifyBase +from ..URLBase import PrivacyMode from ..common import NotifyFormat from ..common import NotifyType from ..utils import parse_emails from ..utils import validate_regex -from ..locale import gettext_lazy as _ +from ..AppriseLocale import gettext_lazy as _ from ..utils import is_email # Our Regin Identifier diff --git a/libs/apprise/plugins/smseagle.py b/libs/apprise/plugins/NotifySMSEagle.py similarity index 99% rename from libs/apprise/plugins/smseagle.py rename to libs/apprise/plugins/NotifySMSEagle.py index 8eddca588..33b4af752 100644 --- a/libs/apprise/plugins/smseagle.py +++ b/libs/apprise/plugins/NotifySMSEagle.py @@ -32,14 +32,14 @@ from json import dumps, loads import base64 from itertools import chain -from .base import NotifyBase +from .NotifyBase import NotifyBase from ..common import NotifyType from ..utils import validate_regex from ..utils import is_phone_no from ..utils import parse_phone_no from ..utils import parse_bool -from ..url import PrivacyMode -from ..locale import gettext_lazy as _ +from ..URLBase import PrivacyMode +from ..AppriseLocale import gettext_lazy as _ GROUP_REGEX = re.compile( diff --git a/libs/apprise/plugins/smsmanager.py b/libs/apprise/plugins/NotifySMSManager.py similarity index 99% rename from libs/apprise/plugins/smsmanager.py rename to libs/apprise/plugins/NotifySMSManager.py index 1d352daf2..efc158b62 100644 --- a/libs/apprise/plugins/smsmanager.py +++ b/libs/apprise/plugins/NotifySMSManager.py @@ -35,13 +35,13 @@ # 2. Generate an API key in web administration. import requests -from .base import NotifyBase +from .NotifyBase import NotifyBase from ..common import NotifyType from ..utils import is_phone_no from ..utils import parse_phone_no from ..utils import parse_bool from ..utils import validate_regex -from ..locale import gettext_lazy as _ +from ..AppriseLocale import gettext_lazy as _ class SMSManagerGateway(object): diff --git a/libs/apprise/plugins/smtp2go.py b/libs/apprise/plugins/NotifySMTP2Go.py similarity index 99% rename from libs/apprise/plugins/smtp2go.py rename to libs/apprise/plugins/NotifySMTP2Go.py index 017da8111..a34492d05 100644 --- a/libs/apprise/plugins/smtp2go.py +++ b/libs/apprise/plugins/NotifySMTP2Go.py @@ -49,14 +49,14 @@ import base64 import requests from json import dumps from email.utils import formataddr -from .base import NotifyBase +from .NotifyBase import NotifyBase from ..common import NotifyType from ..common import NotifyFormat from ..utils import parse_emails from ..utils import parse_bool from ..utils import is_email from ..utils import validate_regex -from ..locale import gettext_lazy as _ +from ..AppriseLocale import gettext_lazy as _ SMTP2GO_HTTP_ERROR_MAP = { 429: 'To many requests.', diff --git a/libs/apprise/plugins/sns.py b/libs/apprise/plugins/NotifySNS.py similarity index 99% rename from libs/apprise/plugins/sns.py rename to libs/apprise/plugins/NotifySNS.py index cc6e83076..5a287e37e 100644 --- a/libs/apprise/plugins/sns.py +++ b/libs/apprise/plugins/NotifySNS.py @@ -36,13 +36,13 @@ from collections import OrderedDict from xml.etree import ElementTree from itertools import chain -from .base import NotifyBase -from ..url import PrivacyMode +from .NotifyBase import NotifyBase +from ..URLBase import PrivacyMode from ..common import NotifyType from ..utils import is_phone_no from ..utils import parse_list from ..utils import validate_regex -from ..locale import gettext_lazy as _ +from ..AppriseLocale import gettext_lazy as _ # Topic Detection # Summary: 256 Characters max, only alpha/numeric plus underscore (_) and diff --git a/libs/apprise/plugins/sendgrid.py b/libs/apprise/plugins/NotifySendGrid.py similarity index 99% rename from libs/apprise/plugins/sendgrid.py rename to libs/apprise/plugins/NotifySendGrid.py index d50839f17..b82e3e60d 100644 --- a/libs/apprise/plugins/sendgrid.py +++ b/libs/apprise/plugins/NotifySendGrid.py @@ -49,13 +49,13 @@ import requests from json import dumps -from .base import NotifyBase +from .NotifyBase import NotifyBase from ..common import NotifyFormat from ..common import NotifyType from ..utils import parse_list from ..utils import is_email from ..utils import validate_regex -from ..locale import gettext_lazy as _ +from ..AppriseLocale import gettext_lazy as _ # Extend HTTP Error Messages SENDGRID_HTTP_ERROR_MAP = { diff --git a/libs/apprise/plugins/serverchan.py b/libs/apprise/plugins/NotifyServerChan.py similarity index 98% rename from libs/apprise/plugins/serverchan.py rename to libs/apprise/plugins/NotifyServerChan.py index e3abaa354..cf250cf5b 100644 --- a/libs/apprise/plugins/serverchan.py +++ b/libs/apprise/plugins/NotifyServerChan.py @@ -30,9 +30,9 @@ import re import requests from ..common import NotifyType -from .base import NotifyBase +from .NotifyBase import NotifyBase from ..utils import validate_regex -from ..locale import gettext_lazy as _ +from ..AppriseLocale import gettext_lazy as _ # Register at https://sct.ftqq.com/ diff --git a/libs/apprise/plugins/signal_api.py b/libs/apprise/plugins/NotifySignalAPI.py similarity index 99% rename from libs/apprise/plugins/signal_api.py rename to libs/apprise/plugins/NotifySignalAPI.py index 7e557133c..b35b4989e 100644 --- a/libs/apprise/plugins/signal_api.py +++ b/libs/apprise/plugins/NotifySignalAPI.py @@ -31,13 +31,13 @@ import requests from json import dumps import base64 -from .base import NotifyBase +from .NotifyBase import NotifyBase from ..common import NotifyType from ..utils import is_phone_no from ..utils import parse_phone_no from ..utils import parse_bool -from ..url import PrivacyMode -from ..locale import gettext_lazy as _ +from ..URLBase import PrivacyMode +from ..AppriseLocale import gettext_lazy as _ GROUP_REGEX = re.compile( diff --git a/libs/apprise/plugins/simplepush.py b/libs/apprise/plugins/NotifySimplePush.py similarity index 98% rename from libs/apprise/plugins/simplepush.py rename to libs/apprise/plugins/NotifySimplePush.py index 10b01b0f8..3851e1e3c 100644 --- a/libs/apprise/plugins/simplepush.py +++ b/libs/apprise/plugins/NotifySimplePush.py @@ -30,11 +30,11 @@ from os import urandom from json import loads import requests -from .base import NotifyBase -from ..url import PrivacyMode +from .NotifyBase import NotifyBase +from ..URLBase import PrivacyMode from ..common import NotifyType from ..utils import validate_regex -from ..locale import gettext_lazy as _ +from ..AppriseLocale import gettext_lazy as _ from base64 import urlsafe_b64encode import hashlib diff --git a/libs/apprise/plugins/sinch.py b/libs/apprise/plugins/NotifySinch.py similarity index 99% rename from libs/apprise/plugins/sinch.py rename to libs/apprise/plugins/NotifySinch.py index 06bd5b1e7..74b3c452a 100644 --- a/libs/apprise/plugins/sinch.py +++ b/libs/apprise/plugins/NotifySinch.py @@ -39,13 +39,13 @@ import requests import json -from .base import NotifyBase -from ..url import PrivacyMode +from .NotifyBase import NotifyBase +from ..URLBase import PrivacyMode from ..common import NotifyType from ..utils import is_phone_no from ..utils import parse_phone_no from ..utils import validate_regex -from ..locale import gettext_lazy as _ +from ..AppriseLocale import gettext_lazy as _ class SinchRegion: diff --git a/libs/apprise/plugins/slack.py b/libs/apprise/plugins/NotifySlack.py similarity index 99% rename from libs/apprise/plugins/slack.py rename to libs/apprise/plugins/NotifySlack.py index b929dfb46..b66fe99f4 100644 --- a/libs/apprise/plugins/slack.py +++ b/libs/apprise/plugins/NotifySlack.py @@ -78,7 +78,7 @@ from json import dumps from json import loads from time import time -from .base import NotifyBase +from .NotifyBase import NotifyBase from ..common import NotifyImageSize from ..common import NotifyType from ..common import NotifyFormat @@ -86,7 +86,7 @@ from ..utils import is_email from ..utils import parse_bool from ..utils import parse_list from ..utils import validate_regex -from ..locale import gettext_lazy as _ +from ..AppriseLocale import gettext_lazy as _ # Extend HTTP Error Messages SLACK_HTTP_ERROR_MAP = { diff --git a/libs/apprise/plugins/sparkpost.py b/libs/apprise/plugins/NotifySparkPost.py similarity index 99% rename from libs/apprise/plugins/sparkpost.py rename to libs/apprise/plugins/NotifySparkPost.py index b873d6b0e..255db0709 100644 --- a/libs/apprise/plugins/sparkpost.py +++ b/libs/apprise/plugins/NotifySparkPost.py @@ -58,7 +58,7 @@ import requests import base64 from json import loads from json import dumps -from .base import NotifyBase +from .NotifyBase import NotifyBase from ..common import NotifyType from ..common import NotifyFormat from ..utils import is_email @@ -66,7 +66,7 @@ from email.utils import formataddr from ..utils import validate_regex from ..utils import parse_emails from ..utils import parse_bool -from ..locale import gettext_lazy as _ +from ..AppriseLocale import gettext_lazy as _ # Provide some known codes SparkPost uses and what they translate to: # Based on https://www.sparkpost.com/docs/tech-resources/extended-error-codes/ diff --git a/libs/apprise/plugins/streamlabs.py b/libs/apprise/plugins/NotifyStreamlabs.py similarity index 99% rename from libs/apprise/plugins/streamlabs.py rename to libs/apprise/plugins/NotifyStreamlabs.py index c534f1ba6..d1e4186a6 100644 --- a/libs/apprise/plugins/streamlabs.py +++ b/libs/apprise/plugins/NotifyStreamlabs.py @@ -38,10 +38,10 @@ # import requests -from .base import NotifyBase +from .NotifyBase import NotifyBase from ..common import NotifyType from ..utils import validate_regex -from ..locale import gettext_lazy as _ +from ..AppriseLocale import gettext_lazy as _ # calls diff --git a/libs/apprise/plugins/synology.py b/libs/apprise/plugins/NotifySynology.py similarity index 98% rename from libs/apprise/plugins/synology.py rename to libs/apprise/plugins/NotifySynology.py index ed85f80c0..be58c0643 100644 --- a/libs/apprise/plugins/synology.py +++ b/libs/apprise/plugins/NotifySynology.py @@ -29,10 +29,10 @@ import requests from json import dumps -from .base import NotifyBase -from ..url import PrivacyMode +from .NotifyBase import NotifyBase +from ..URLBase import PrivacyMode from ..common import NotifyType -from ..locale import gettext_lazy as _ +from ..AppriseLocale import gettext_lazy as _ # For API Details see: # https://kb.synology.com/en-au/DSM/help/Chat/chat_integration diff --git a/libs/apprise/plugins/syslog.py b/libs/apprise/plugins/NotifySyslog.py similarity index 99% rename from libs/apprise/plugins/syslog.py rename to libs/apprise/plugins/NotifySyslog.py index 935111eea..5540fc758 100644 --- a/libs/apprise/plugins/syslog.py +++ b/libs/apprise/plugins/NotifySyslog.py @@ -28,10 +28,10 @@ import syslog -from .base import NotifyBase +from .NotifyBase import NotifyBase from ..common import NotifyType from ..utils import parse_bool -from ..locale import gettext_lazy as _ +from ..AppriseLocale import gettext_lazy as _ class SyslogFacility: diff --git a/libs/apprise/plugins/techuluspush.py b/libs/apprise/plugins/NotifyTechulusPush.py similarity index 98% rename from libs/apprise/plugins/techuluspush.py rename to libs/apprise/plugins/NotifyTechulusPush.py index 682bf088e..4d0b99348 100644 --- a/libs/apprise/plugins/techuluspush.py +++ b/libs/apprise/plugins/NotifyTechulusPush.py @@ -53,10 +53,10 @@ import requests from json import dumps -from .base import NotifyBase +from .NotifyBase import NotifyBase from ..common import NotifyType from ..utils import validate_regex -from ..locale import gettext_lazy as _ +from ..AppriseLocale import gettext_lazy as _ # Token required as part of the API request # Used to prepare our UUID regex matching diff --git a/libs/apprise/plugins/telegram.py b/libs/apprise/plugins/NotifyTelegram.py similarity index 99% rename from libs/apprise/plugins/telegram.py rename to libs/apprise/plugins/NotifyTelegram.py index 6b997f574..cce8af625 100644 --- a/libs/apprise/plugins/telegram.py +++ b/libs/apprise/plugins/NotifyTelegram.py @@ -59,15 +59,15 @@ import os from json import loads from json import dumps -from .base import NotifyBase +from .NotifyBase import NotifyBase from ..common import NotifyType from ..common import NotifyImageSize from ..common import NotifyFormat from ..utils import parse_bool from ..utils import parse_list from ..utils import validate_regex -from ..locale import gettext_lazy as _ -from ..attachment.base import AttachBase +from ..AppriseLocale import gettext_lazy as _ +from ..attachment.AttachBase import AttachBase TELEGRAM_IMAGE_XY = NotifyImageSize.XY_256 diff --git a/libs/apprise/plugins/threema.py b/libs/apprise/plugins/NotifyThreema.py similarity index 99% rename from libs/apprise/plugins/threema.py rename to libs/apprise/plugins/NotifyThreema.py index 423c23124..c2ad82e2e 100644 --- a/libs/apprise/plugins/threema.py +++ b/libs/apprise/plugins/NotifyThreema.py @@ -35,14 +35,14 @@ import requests from itertools import chain -from .base import NotifyBase +from .NotifyBase import NotifyBase from ..common import NotifyType from ..utils import is_phone_no from ..utils import validate_regex from ..utils import is_email -from ..url import PrivacyMode +from ..URLBase import PrivacyMode from ..utils import parse_list -from ..locale import gettext_lazy as _ +from ..AppriseLocale import gettext_lazy as _ class ThreemaRecipientTypes: diff --git a/libs/apprise/plugins/twilio.py b/libs/apprise/plugins/NotifyTwilio.py similarity index 99% rename from libs/apprise/plugins/twilio.py rename to libs/apprise/plugins/NotifyTwilio.py index 4205e37f0..863b09a94 100644 --- a/libs/apprise/plugins/twilio.py +++ b/libs/apprise/plugins/NotifyTwilio.py @@ -46,13 +46,13 @@ import requests from json import loads -from .base import NotifyBase -from ..url import PrivacyMode +from .NotifyBase import NotifyBase +from ..URLBase import PrivacyMode from ..common import NotifyType from ..utils import is_phone_no from ..utils import parse_phone_no from ..utils import validate_regex -from ..locale import gettext_lazy as _ +from ..AppriseLocale import gettext_lazy as _ class NotifyTwilio(NotifyBase): diff --git a/libs/apprise/plugins/twist.py b/libs/apprise/plugins/NotifyTwist.py similarity index 99% rename from libs/apprise/plugins/twist.py rename to libs/apprise/plugins/NotifyTwist.py index 62d729f4f..fa26feb84 100644 --- a/libs/apprise/plugins/twist.py +++ b/libs/apprise/plugins/NotifyTwist.py @@ -35,13 +35,13 @@ import requests from json import loads from itertools import chain -from .base import NotifyBase -from ..url import PrivacyMode +from .NotifyBase import NotifyBase +from ..URLBase import PrivacyMode from ..common import NotifyFormat from ..common import NotifyType from ..utils import parse_list from ..utils import is_email -from ..locale import gettext_lazy as _ +from ..AppriseLocale import gettext_lazy as _ # A workspace can also be interpreted as a team name too! diff --git a/libs/apprise/plugins/twitter.py b/libs/apprise/plugins/NotifyTwitter.py similarity index 99% rename from libs/apprise/plugins/twitter.py rename to libs/apprise/plugins/NotifyTwitter.py index 8000a8151..7a0813c1f 100644 --- a/libs/apprise/plugins/twitter.py +++ b/libs/apprise/plugins/NotifyTwitter.py @@ -36,14 +36,14 @@ from datetime import timezone from requests_oauthlib import OAuth1 from json import dumps from json import loads -from .base import NotifyBase -from ..url import PrivacyMode +from .NotifyBase import NotifyBase +from ..URLBase import PrivacyMode from ..common import NotifyType from ..utils import parse_list from ..utils import parse_bool from ..utils import validate_regex -from ..locale import gettext_lazy as _ -from ..attachment.base import AttachBase +from ..AppriseLocale import gettext_lazy as _ +from ..attachment.AttachBase import AttachBase IS_USER = re.compile(r'^\s*@?(?P[A-Z0-9_]+)$', re.I) diff --git a/libs/apprise/plugins/voipms.py b/libs/apprise/plugins/NotifyVoipms.py similarity index 99% rename from libs/apprise/plugins/voipms.py rename to libs/apprise/plugins/NotifyVoipms.py index 3a4e6d25f..a023589a7 100644 --- a/libs/apprise/plugins/voipms.py +++ b/libs/apprise/plugins/NotifyVoipms.py @@ -37,12 +37,12 @@ import requests from json import loads -from .base import NotifyBase +from .NotifyBase import NotifyBase from ..common import NotifyType from ..utils import is_phone_no from ..utils import is_email from ..utils import parse_phone_no -from ..locale import gettext_lazy as _ +from ..AppriseLocale import gettext_lazy as _ class NotifyVoipms(NotifyBase): diff --git a/libs/apprise/plugins/vonage.py b/libs/apprise/plugins/NotifyVonage.py similarity index 99% rename from libs/apprise/plugins/vonage.py rename to libs/apprise/plugins/NotifyVonage.py index 441a6ba6b..e9b1422ad 100644 --- a/libs/apprise/plugins/vonage.py +++ b/libs/apprise/plugins/NotifyVonage.py @@ -33,13 +33,13 @@ # import requests -from .base import NotifyBase -from ..url import PrivacyMode +from .NotifyBase import NotifyBase +from ..URLBase import PrivacyMode from ..common import NotifyType from ..utils import is_phone_no from ..utils import parse_phone_no from ..utils import validate_regex -from ..locale import gettext_lazy as _ +from ..AppriseLocale import gettext_lazy as _ class NotifyVonage(NotifyBase): diff --git a/libs/apprise/plugins/wecombot.py b/libs/apprise/plugins/NotifyWeComBot.py similarity index 99% rename from libs/apprise/plugins/wecombot.py rename to libs/apprise/plugins/NotifyWeComBot.py index ab6341718..4289b39e9 100644 --- a/libs/apprise/plugins/wecombot.py +++ b/libs/apprise/plugins/NotifyWeComBot.py @@ -59,10 +59,10 @@ import re import requests from json import dumps -from .base import NotifyBase +from .NotifyBase import NotifyBase from ..common import NotifyType from ..utils import validate_regex -from ..locale import gettext_lazy as _ +from ..AppriseLocale import gettext_lazy as _ class NotifyWeComBot(NotifyBase): diff --git a/libs/apprise/plugins/webexteams.py b/libs/apprise/plugins/NotifyWebexTeams.py similarity index 99% rename from libs/apprise/plugins/webexteams.py rename to libs/apprise/plugins/NotifyWebexTeams.py index bd0bdb577..c91864bad 100644 --- a/libs/apprise/plugins/webexteams.py +++ b/libs/apprise/plugins/NotifyWebexTeams.py @@ -63,11 +63,11 @@ import re import requests from json import dumps -from .base import NotifyBase +from .NotifyBase import NotifyBase from ..common import NotifyType from ..common import NotifyFormat from ..utils import validate_regex -from ..locale import gettext_lazy as _ +from ..AppriseLocale import gettext_lazy as _ # Extend HTTP Error Messages # Based on: https://developer.webex.com/docs/api/basics/rate-limiting diff --git a/libs/apprise/plugins/whatsapp.py b/libs/apprise/plugins/NotifyWhatsApp.py similarity index 99% rename from libs/apprise/plugins/whatsapp.py rename to libs/apprise/plugins/NotifyWhatsApp.py index 7120d736c..4ccbcbdaf 100644 --- a/libs/apprise/plugins/whatsapp.py +++ b/libs/apprise/plugins/NotifyWhatsApp.py @@ -44,12 +44,12 @@ import re import requests from json import loads, dumps -from .base import NotifyBase +from .NotifyBase import NotifyBase from ..common import NotifyType from ..utils import is_phone_no from ..utils import parse_phone_no from ..utils import validate_regex -from ..locale import gettext_lazy as _ +from ..AppriseLocale import gettext_lazy as _ class NotifyWhatsApp(NotifyBase): diff --git a/libs/apprise/plugins/windows.py b/libs/apprise/plugins/NotifyWindows.py similarity index 99% rename from libs/apprise/plugins/windows.py rename to libs/apprise/plugins/NotifyWindows.py index 746fcd1dd..207e0f221 100644 --- a/libs/apprise/plugins/windows.py +++ b/libs/apprise/plugins/NotifyWindows.py @@ -28,11 +28,11 @@ from time import sleep -from .base import NotifyBase +from .NotifyBase import NotifyBase from ..common import NotifyImageSize from ..common import NotifyType from ..utils import parse_bool -from ..locale import gettext_lazy as _ +from ..AppriseLocale import gettext_lazy as _ # Default our global support flag NOTIFY_WINDOWS_SUPPORT_ENABLED = False diff --git a/libs/apprise/plugins/xbmc.py b/libs/apprise/plugins/NotifyXBMC.py similarity index 99% rename from libs/apprise/plugins/xbmc.py rename to libs/apprise/plugins/NotifyXBMC.py index 8006e1005..7d4462e41 100644 --- a/libs/apprise/plugins/xbmc.py +++ b/libs/apprise/plugins/NotifyXBMC.py @@ -29,12 +29,12 @@ import requests from json import dumps -from .base import NotifyBase -from ..url import PrivacyMode +from .NotifyBase import NotifyBase +from ..URLBase import PrivacyMode from ..common import NotifyType from ..common import NotifyImageSize from ..utils import parse_bool -from ..locale import gettext_lazy as _ +from ..AppriseLocale import gettext_lazy as _ class NotifyXBMC(NotifyBase): diff --git a/libs/apprise/plugins/custom_xml.py b/libs/apprise/plugins/NotifyXML.py similarity index 99% rename from libs/apprise/plugins/custom_xml.py rename to libs/apprise/plugins/NotifyXML.py index b7928fceb..21ccb79d3 100644 --- a/libs/apprise/plugins/custom_xml.py +++ b/libs/apprise/plugins/NotifyXML.py @@ -30,11 +30,11 @@ import re import requests import base64 -from .base import NotifyBase -from ..url import PrivacyMode +from .NotifyBase import NotifyBase +from ..URLBase import PrivacyMode from ..common import NotifyImageSize from ..common import NotifyType -from ..locale import gettext_lazy as _ +from ..AppriseLocale import gettext_lazy as _ class XMLPayloadField: diff --git a/libs/apprise/plugins/zulip.py b/libs/apprise/plugins/NotifyZulip.py similarity index 99% rename from libs/apprise/plugins/zulip.py rename to libs/apprise/plugins/NotifyZulip.py index e829e6f6d..54fe2d062 100644 --- a/libs/apprise/plugins/zulip.py +++ b/libs/apprise/plugins/NotifyZulip.py @@ -61,13 +61,13 @@ import re import requests -from .base import NotifyBase +from .NotifyBase import NotifyBase from ..common import NotifyType from ..utils import parse_list from ..utils import validate_regex from ..utils import is_email from ..utils import remove_suffix -from ..locale import gettext_lazy as _ +from ..AppriseLocale import gettext_lazy as _ # A Valid Bot Name VALIDATE_BOTNAME = re.compile(r'(?P[A-Z0-9_-]{1,32})', re.I) diff --git a/libs/apprise/plugins/__init__.py b/libs/apprise/plugins/__init__.py index bfce14371..72cb08fbf 100644 --- a/libs/apprise/plugins/__init__.py +++ b/libs/apprise/plugins/__init__.py @@ -30,7 +30,7 @@ import os import copy # Used for testing -from .base import NotifyBase +from .NotifyBase import NotifyBase from ..common import NotifyImageSize from ..common import NOTIFY_IMAGE_SIZES @@ -40,9 +40,9 @@ from ..utils import parse_list from ..utils import cwe312_url from ..utils import GET_SCHEMA_RE from ..logger import logger -from ..locale import gettext_lazy as _ -from ..locale import LazyTranslation -from ..manager_plugins import NotificationManager +from ..AppriseLocale import gettext_lazy as _ +from ..AppriseLocale import LazyTranslation +from ..NotificationManager import NotificationManager # Grant access to our Notification Manager Singleton diff --git a/libs/apprise/utils.py b/libs/apprise/utils.py index b33ec0749..e1881f314 100644 --- a/libs/apprise/utils.py +++ b/libs/apprise/utils.py @@ -541,7 +541,7 @@ def tidy_path(path): return path -def parse_qsd(qs, simple=False, plus_to_space=False, sanitize=True): +def parse_qsd(qs, simple=False, plus_to_space=False): """ Query String Dictionary Builder @@ -568,8 +568,6 @@ def parse_qsd(qs, simple=False, plus_to_space=False, sanitize=True): per normal URL Encoded defininition. Normal URL parsing applies this, but `+` is very actively used character with passwords, api keys, tokens, etc. So Apprise does not do this by default. - - if sanitize is set to False, then kwargs are not placed into lowercase """ # Our return result set: @@ -610,7 +608,7 @@ def parse_qsd(qs, simple=False, plus_to_space=False, sanitize=True): # Always Query String Dictionary (qsd) for every entry we have # content is always made lowercase for easy indexing - result['qsd'][key.lower().strip() if sanitize else key] = val + result['qsd'][key.lower().strip()] = val if simple: # move along @@ -638,7 +636,7 @@ def parse_qsd(qs, simple=False, plus_to_space=False, sanitize=True): def parse_url(url, default_schema='http', verify_host=True, strict_port=False, - simple=False, plus_to_space=False, sanitize=True): + simple=False, plus_to_space=False): """A function that greatly simplifies the parsing of a url specified by the end user. @@ -693,8 +691,6 @@ def parse_url(url, default_schema='http', verify_host=True, strict_port=False, If the URL can't be parsed then None is returned - If sanitize is set to False, then kwargs are not placed in lowercase - and wrapping whitespace is not removed """ if not isinstance(url, str): @@ -754,8 +750,7 @@ def parse_url(url, default_schema='http', verify_host=True, strict_port=False, # while ensuring that all keys are lowercase if qsdata: result.update(parse_qsd( - qsdata, simple=simple, plus_to_space=plus_to_space, - sanitize=sanitize)) + qsdata, simple=simple, plus_to_space=plus_to_space)) # Now do a proper extraction of data; http:// is just substitued in place # to allow urlparse() to function as expected, we'll swap this back to the diff --git a/libs/version.txt b/libs/version.txt index 8ac12d74d..ccabf65cc 100644 --- a/libs/version.txt +++ b/libs/version.txt @@ -2,7 +2,7 @@ alembic==1.13.1 aniso8601==9.0.1 argparse==1.4.0 -apprise==1.8.0 +apprise==1.7.6 apscheduler<=3.10.4 attrs==23.2.0 blinker==1.7.0 From 0abf56191c730309c4fb5d0cbd0f4f666b0adc70 Mon Sep 17 00:00:00 2001 From: morpheus65535 Date: Sat, 25 May 2024 00:18:49 -0400 Subject: [PATCH 11/18] no log: Delete libs/apprise/apprise.py --- libs/apprise/apprise.py | 887 ---------------------------------------- 1 file changed, 887 deletions(-) delete mode 100644 libs/apprise/apprise.py diff --git a/libs/apprise/apprise.py b/libs/apprise/apprise.py deleted file mode 100644 index 05a2ee3cc..000000000 --- a/libs/apprise/apprise.py +++ /dev/null @@ -1,887 +0,0 @@ -# -*- coding: utf-8 -*- -# BSD 2-Clause License -# -# Apprise - Push Notification Library. -# Copyright (c) 2024, Chris Caron -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# -# 1. Redistributions of source code must retain the above copyright notice, -# this list of conditions and the following disclaimer. -# -# 2. Redistributions in binary form must reproduce the above copyright notice, -# this list of conditions and the following disclaimer in the documentation -# and/or other materials provided with the distribution. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. - -import asyncio -import concurrent.futures as cf -import os -from itertools import chain -from . import common -from .conversion import convert_between -from .utils import is_exclusive_match -from .manager_plugins import NotificationManager -from .utils import parse_list -from .utils import parse_urls -from .utils import cwe312_url -from .emojis import apply_emojis -from .logger import logger -from .asset import AppriseAsset -from .apprise_config import AppriseConfig -from .apprise_attachment import AppriseAttachment -from .locale import AppriseLocale -from .config.base import ConfigBase -from .plugins.base import NotifyBase - -from . import plugins -from . import __version__ - -# Grant access to our Notification Manager Singleton -N_MGR = NotificationManager() - - -class Apprise: - """ - Our Notification Manager - - """ - - def __init__(self, servers=None, asset=None, location=None, debug=False): - """ - Loads a set of server urls while applying the Asset() module to each - if specified. - - If no asset is provided, then the default asset is used. - - Optionally specify a global ContentLocation for a more strict means - of handling Attachments. - """ - - # Initialize a server list of URLs - self.servers = list() - - # Assigns an central asset object that will be later passed into each - # notification plugin. Assets contain information such as the local - # directory images can be found in. It can also identify remote - # URL paths that contain the images you want to present to the end - # user. If no asset is specified, then the default one is used. - self.asset = \ - asset if isinstance(asset, AppriseAsset) else AppriseAsset() - - if servers: - self.add(servers) - - # Initialize our locale object - self.locale = AppriseLocale() - - # Set our debug flag - self.debug = debug - - # Store our hosting location for optional strict rule handling - # of Attachments. Setting this to None removes any attachment - # restrictions. - self.location = location - - @staticmethod - def instantiate(url, asset=None, tag=None, suppress_exceptions=True): - """ - Returns the instance of a instantiated plugin based on the provided - Server URL. If the url fails to be parsed, then None is returned. - - The specified url can be either a string (the URL itself) or a - dictionary containing all of the components needed to istantiate - the notification service. If identifying a dictionary, at the bare - minimum, one must specify the schema. - - An example of a url dictionary object might look like: - { - schema: 'mailto', - host: 'google.com', - user: 'myuser', - password: 'mypassword', - } - - Alternatively the string is much easier to specify: - mailto://user:mypassword@google.com - - The dictionary works well for people who are calling details() to - extract the components they need to build the URL manually. - """ - - # Initialize our result set - results = None - - # Prepare our Asset Object - asset = asset if isinstance(asset, AppriseAsset) else AppriseAsset() - - if isinstance(url, str): - # Acquire our url tokens - results = plugins.url_to_dict( - url, secure_logging=asset.secure_logging) - - if results is None: - # Failed to parse the server URL; detailed logging handled - # inside url_to_dict - nothing to report here. - return None - - elif isinstance(url, dict): - # We already have our result set - results = url - - if results.get('schema') not in N_MGR: - # schema is a mandatory dictionary item as it is the only way - # we can index into our loaded plugins - logger.error('Dictionary does not include a "schema" entry.') - logger.trace( - 'Invalid dictionary unpacked as:{}{}'.format( - os.linesep, os.linesep.join( - ['{}="{}"'.format(k, v) - for k, v in results.items()]))) - return None - - logger.trace( - 'Dictionary unpacked as:{}{}'.format( - os.linesep, os.linesep.join( - ['{}="{}"'.format(k, v) for k, v in results.items()]))) - - # Otherwise we handle the invalid input specified - else: - logger.error( - 'An invalid URL type (%s) was specified for instantiation', - type(url)) - return None - - if not N_MGR[results['schema']].enabled: - # - # First Plugin Enable Check (Pre Initialization) - # - - # Plugin has been disabled at a global level - logger.error( - '%s:// is disabled on this system.', results['schema']) - return None - - # Build a list of tags to associate with the newly added notifications - results['tag'] = set(parse_list(tag)) - - # Set our Asset Object - results['asset'] = asset - - if suppress_exceptions: - try: - # Attempt to create an instance of our plugin using the parsed - # URL information - plugin = N_MGR[results['schema']](**results) - - # Create log entry of loaded URL - logger.debug( - 'Loaded {} URL: {}'.format( - N_MGR[results['schema']].service_name, - plugin.url(privacy=asset.secure_logging))) - - except Exception: - # CWE-312 (Secure Logging) Handling - loggable_url = url if not asset.secure_logging \ - else cwe312_url(url) - - # the arguments are invalid or can not be used. - logger.error( - 'Could not load {} URL: {}'.format( - N_MGR[results['schema']].service_name, - loggable_url)) - return None - - else: - # Attempt to create an instance of our plugin using the parsed - # URL information but don't wrap it in a try catch - plugin = N_MGR[results['schema']](**results) - - if not plugin.enabled: - # - # Second Plugin Enable Check (Post Initialization) - # - - # Service/Plugin is disabled (on a more local level). This is a - # case where the plugin was initially enabled but then after the - # __init__() was called under the hood something pre-determined - # that it could no longer be used. - - # The only downside to doing it this way is services are - # initialized prior to returning the details() if 3rd party tools - # are polling what is available. These services that become - # disabled thereafter are shown initially that they can be used. - logger.error( - '%s:// has become disabled on this system.', results['schema']) - return None - - return plugin - - def add(self, servers, asset=None, tag=None): - """ - Adds one or more server URLs into our list. - - You can override the global asset if you wish by including it with the - server(s) that you add. - - The tag allows you to associate 1 or more tag values to the server(s) - being added. tagging a service allows you to exclusively access them - when calling the notify() function. - """ - - # Initialize our return status - return_status = True - - if asset is None: - # prepare default asset - asset = self.asset - - if isinstance(servers, str): - # build our server list - servers = parse_urls(servers) - if len(servers) == 0: - return False - - elif isinstance(servers, dict): - # no problem, we support kwargs, convert it to a list - servers = [servers] - - elif isinstance(servers, (ConfigBase, NotifyBase, AppriseConfig)): - # Go ahead and just add our plugin into our list - self.servers.append(servers) - return True - - elif not isinstance(servers, (tuple, set, list)): - logger.error( - "An invalid notification (type={}) was specified.".format( - type(servers))) - return False - - for _server in servers: - - if isinstance(_server, (ConfigBase, NotifyBase, AppriseConfig)): - # Go ahead and just add our plugin into our list - self.servers.append(_server) - continue - - elif not isinstance(_server, (str, dict)): - logger.error( - "An invalid notification (type={}) was specified.".format( - type(_server))) - return_status = False - continue - - # Instantiate ourselves an object, this function throws or - # returns None if it fails - instance = Apprise.instantiate(_server, asset=asset, tag=tag) - if not isinstance(instance, NotifyBase): - # No logging is required as instantiate() handles failure - # and/or success reasons for us - return_status = False - continue - - # Add our initialized plugin to our server listings - self.servers.append(instance) - - # Return our status - return return_status - - def clear(self): - """ - Empties our server list - - """ - self.servers[:] = [] - - def find(self, tag=common.MATCH_ALL_TAG, match_always=True): - """ - Returns a list of all servers matching against the tag specified. - - """ - - # Build our tag setup - # - top level entries are treated as an 'or' - # - second level (or more) entries are treated as 'and' - # - # examples: - # tag="tagA, tagB" = tagA or tagB - # tag=['tagA', 'tagB'] = tagA or tagB - # tag=[('tagA', 'tagC'), 'tagB'] = (tagA and tagC) or tagB - # tag=[('tagB', 'tagC')] = tagB and tagC - - # A match_always flag allows us to pick up on our 'any' keyword - # and notify these services under all circumstances - match_always = common.MATCH_ALWAYS_TAG if match_always else None - - # Iterate over our loaded plugins - for entry in self.servers: - - if isinstance(entry, (ConfigBase, AppriseConfig)): - # load our servers - servers = entry.servers() - - else: - servers = [entry, ] - - for server in servers: - # Apply our tag matching based on our defined logic - if is_exclusive_match( - logic=tag, data=server.tags, - match_all=common.MATCH_ALL_TAG, - match_always=match_always): - yield server - return - - def notify(self, body, title='', notify_type=common.NotifyType.INFO, - body_format=None, tag=common.MATCH_ALL_TAG, match_always=True, - attach=None, interpret_escapes=None): - """ - Send a notification to all the plugins previously loaded. - - If the body_format specified is NotifyFormat.MARKDOWN, it will - be converted to HTML if the Notification type expects this. - - if the tag is specified (either a string or a set/list/tuple - of strings), then only the notifications flagged with that - tagged value are notified. By default, all added services - are notified (tag=MATCH_ALL_TAG) - - This function returns True if all notifications were successfully - sent, False if even just one of them fails, and None if no - notifications were sent at all as a result of tag filtering and/or - simply having empty configuration files that were read. - - Attach can contain a list of attachment URLs. attach can also be - represented by an AttachBase() (or list of) object(s). This - identifies the products you wish to notify - - Set interpret_escapes to True if you want to pre-escape a string - such as turning a \n into an actual new line, etc. - """ - - try: - # Process arguments and build synchronous and asynchronous calls - # (this step can throw internal errors). - sequential_calls, parallel_calls = self._create_notify_calls( - body, title, - notify_type=notify_type, body_format=body_format, - tag=tag, match_always=match_always, attach=attach, - interpret_escapes=interpret_escapes, - ) - - except TypeError: - # No notifications sent, and there was an internal error. - return False - - if not sequential_calls and not parallel_calls: - # Nothing to send - return None - - sequential_result = Apprise._notify_sequential(*sequential_calls) - parallel_result = Apprise._notify_parallel_threadpool(*parallel_calls) - return sequential_result and parallel_result - - async def async_notify(self, *args, **kwargs): - """ - Send a notification to all the plugins previously loaded, for - asynchronous callers. - - The arguments are identical to those of Apprise.notify(). - - """ - try: - # Process arguments and build synchronous and asynchronous calls - # (this step can throw internal errors). - sequential_calls, parallel_calls = self._create_notify_calls( - *args, **kwargs) - - except TypeError: - # No notifications sent, and there was an internal error. - return False - - if not sequential_calls and not parallel_calls: - # Nothing to send - return None - - sequential_result = Apprise._notify_sequential(*sequential_calls) - parallel_result = \ - await Apprise._notify_parallel_asyncio(*parallel_calls) - return sequential_result and parallel_result - - def _create_notify_calls(self, *args, **kwargs): - """ - Creates notifications for all the plugins loaded. - - Returns a list of (server, notify() kwargs) tuples for plugins with - parallelism disabled and another list for plugins with parallelism - enabled. - """ - - all_calls = list(self._create_notify_gen(*args, **kwargs)) - - # Split into sequential and parallel notify() calls. - sequential, parallel = [], [] - for (server, notify_kwargs) in all_calls: - if server.asset.async_mode: - parallel.append((server, notify_kwargs)) - else: - sequential.append((server, notify_kwargs)) - - return sequential, parallel - - def _create_notify_gen(self, body, title='', - notify_type=common.NotifyType.INFO, - body_format=None, tag=common.MATCH_ALL_TAG, - match_always=True, attach=None, - interpret_escapes=None): - """ - Internal generator function for _create_notify_calls(). - """ - - if len(self) == 0: - # Nothing to notify - msg = "There are no service(s) to notify" - logger.error(msg) - raise TypeError(msg) - - if not (title or body or attach): - msg = "No message content specified to deliver" - logger.error(msg) - raise TypeError(msg) - - try: - if title and isinstance(title, bytes): - title = title.decode(self.asset.encoding) - - if body and isinstance(body, bytes): - body = body.decode(self.asset.encoding) - - except UnicodeDecodeError: - msg = 'The content passed into Apprise was not of encoding ' \ - 'type: {}'.format(self.asset.encoding) - logger.error(msg) - raise TypeError(msg) - - # Tracks conversions - conversion_body_map = dict() - conversion_title_map = dict() - - # Prepare attachments if required - if attach is not None and not isinstance(attach, AppriseAttachment): - attach = AppriseAttachment( - attach, asset=self.asset, location=self.location) - - # Allow Asset default value - body_format = self.asset.body_format \ - if body_format is None else body_format - - # Allow Asset default value - interpret_escapes = self.asset.interpret_escapes \ - if interpret_escapes is None else interpret_escapes - - # Iterate over our loaded plugins - for server in self.find(tag, match_always=match_always): - # If our code reaches here, we either did not define a tag (it - # was set to None), or we did define a tag and the logic above - # determined we need to notify the service it's associated with - - # First we need to generate a key we will use to determine if we - # need to build our data out. Entries without are merged with - # the body at this stage. - key = server.notify_format if server.title_maxlen > 0\ - else f'_{server.notify_format}' - - if server.interpret_emojis: - # alter our key slightly to handle emojis since their value is - # pulled out of the notification - key += "-emojis" - - if key not in conversion_title_map: - - # Prepare our title - conversion_title_map[key] = '' if not title else title - - # Conversion of title only occurs for services where the title - # is blended with the body (title_maxlen <= 0) - if conversion_title_map[key] and server.title_maxlen <= 0: - conversion_title_map[key] = convert_between( - body_format, server.notify_format, - content=conversion_title_map[key]) - - # Our body is always converted no matter what - conversion_body_map[key] = \ - convert_between( - body_format, server.notify_format, content=body) - - if interpret_escapes: - # - # Escape our content - # - - try: - # Added overhead required due to Python 3 Encoding Bug - # identified here: https://bugs.python.org/issue21331 - conversion_body_map[key] = \ - conversion_body_map[key]\ - .encode('ascii', 'backslashreplace')\ - .decode('unicode-escape') - - conversion_title_map[key] = \ - conversion_title_map[key]\ - .encode('ascii', 'backslashreplace')\ - .decode('unicode-escape') - - except AttributeError: - # Must be of string type - msg = 'Failed to escape message body' - logger.error(msg) - raise TypeError(msg) - - if server.interpret_emojis: - # - # Convert our :emoji: definitions - # - - conversion_body_map[key] = \ - apply_emojis(conversion_body_map[key]) - conversion_title_map[key] = \ - apply_emojis(conversion_title_map[key]) - - kwargs = dict( - body=conversion_body_map[key], - title=conversion_title_map[key], - notify_type=notify_type, - attach=attach, - body_format=body_format - ) - yield (server, kwargs) - - @staticmethod - def _notify_sequential(*servers_kwargs): - """ - Process a list of notify() calls sequentially and synchronously. - """ - - success = True - - for (server, kwargs) in servers_kwargs: - try: - # Send notification - result = server.notify(**kwargs) - success = success and result - - except TypeError: - # These are our internally thrown notifications. - success = False - - except Exception: - # A catch all so we don't have to abort early - # just because one of our plugins has a bug in it. - logger.exception("Unhandled Notification Exception") - success = False - - return success - - @staticmethod - def _notify_parallel_threadpool(*servers_kwargs): - """ - Process a list of notify() calls in parallel and synchronously. - """ - - n_calls = len(servers_kwargs) - - # 0-length case - if n_calls == 0: - return True - - # There's no need to use a thread pool for just a single notification - if n_calls == 1: - return Apprise._notify_sequential(servers_kwargs[0]) - - # Create log entry - logger.info( - 'Notifying %d service(s) with threads.', len(servers_kwargs)) - - with cf.ThreadPoolExecutor() as executor: - success = True - futures = [executor.submit(server.notify, **kwargs) - for (server, kwargs) in servers_kwargs] - - for future in cf.as_completed(futures): - try: - result = future.result() - success = success and result - - except TypeError: - # These are our internally thrown notifications. - success = False - - except Exception: - # A catch all so we don't have to abort early - # just because one of our plugins has a bug in it. - logger.exception("Unhandled Notification Exception") - success = False - - return success - - @staticmethod - async def _notify_parallel_asyncio(*servers_kwargs): - """ - Process a list of async_notify() calls in parallel and asynchronously. - """ - - n_calls = len(servers_kwargs) - - # 0-length case - if n_calls == 0: - return True - - # (Unlike with the thread pool, we don't optimize for the single- - # notification case because asyncio can do useful work while waiting - # for that thread to complete) - - # Create log entry - logger.info( - 'Notifying %d service(s) asynchronously.', len(servers_kwargs)) - - async def do_call(server, kwargs): - return await server.async_notify(**kwargs) - - cors = (do_call(server, kwargs) for (server, kwargs) in servers_kwargs) - results = await asyncio.gather(*cors, return_exceptions=True) - - if any(isinstance(status, Exception) - and not isinstance(status, TypeError) for status in results): - # A catch all so we don't have to abort early just because - # one of our plugins has a bug in it. - logger.exception("Unhandled Notification Exception") - return False - - if any(isinstance(status, TypeError) for status in results): - # These are our internally thrown notifications. - return False - - return all(results) - - def details(self, lang=None, show_requirements=False, show_disabled=False): - """ - Returns the details associated with the Apprise object - - """ - - # general object returned - response = { - # Defines the current version of Apprise - 'version': __version__, - # Lists all of the currently supported Notifications - 'schemas': [], - # Includes the configured asset details - 'asset': self.asset.details(), - } - - for plugin in N_MGR.plugins(): - # Iterate over our hashed plugins and dynamically build details on - # their status: - - content = { - 'service_name': getattr(plugin, 'service_name', None), - 'service_url': getattr(plugin, 'service_url', None), - 'setup_url': getattr(plugin, 'setup_url', None), - # Placeholder - populated below - 'details': None, - - # Let upstream service know of the plugins that support - # attachments - 'attachment_support': getattr( - plugin, 'attachment_support', False), - - # Differentiat between what is a custom loaded plugin and - # which is native. - 'category': getattr(plugin, 'category', None) - } - - # Standard protocol(s) should be None or a tuple - enabled = getattr(plugin, 'enabled', True) - if not show_disabled and not enabled: - # Do not show inactive plugins - continue - - elif show_disabled: - # Add current state to response - content['enabled'] = enabled - - # Standard protocol(s) should be None or a tuple - protocols = getattr(plugin, 'protocol', None) - if isinstance(protocols, str): - protocols = (protocols, ) - - # Secure protocol(s) should be None or a tuple - secure_protocols = getattr(plugin, 'secure_protocol', None) - if isinstance(secure_protocols, str): - secure_protocols = (secure_protocols, ) - - # Add our protocol details to our content - content.update({ - 'protocols': protocols, - 'secure_protocols': secure_protocols, - }) - - if not lang: - # Simply return our results - content['details'] = plugins.details(plugin) - if show_requirements: - content['requirements'] = plugins.requirements(plugin) - - else: - # Emulate the specified language when returning our results - with self.locale.lang_at(lang): - content['details'] = plugins.details(plugin) - if show_requirements: - content['requirements'] = plugins.requirements(plugin) - - # Build our response object - response['schemas'].append(content) - - return response - - def urls(self, privacy=False): - """ - Returns all of the loaded URLs defined in this apprise object. - """ - return [x.url(privacy=privacy) for x in self.servers] - - def pop(self, index): - """ - Removes an indexed Notification Service from the stack and returns it. - - The thing is we can never pop AppriseConfig() entries, only what was - loaded within them. So pop needs to carefully iterate over our list - and only track actual entries. - """ - - # Tracking variables - prev_offset = -1 - offset = prev_offset - - for idx, s in enumerate(self.servers): - if isinstance(s, (ConfigBase, AppriseConfig)): - servers = s.servers() - if len(servers) > 0: - # Acquire a new maximum offset to work with - offset = prev_offset + len(servers) - - if offset >= index: - # we can pop an element from our config stack - fn = s.pop if isinstance(s, ConfigBase) \ - else s.server_pop - - return fn(index if prev_offset == -1 - else (index - prev_offset - 1)) - - else: - offset = prev_offset + 1 - if offset == index: - return self.servers.pop(idx) - - # Update our old offset - prev_offset = offset - - # If we reach here, then we indexed out of range - raise IndexError('list index out of range') - - def __getitem__(self, index): - """ - Returns the indexed server entry of a loaded notification server - """ - # Tracking variables - prev_offset = -1 - offset = prev_offset - - for idx, s in enumerate(self.servers): - if isinstance(s, (ConfigBase, AppriseConfig)): - # Get our list of servers associate with our config object - servers = s.servers() - if len(servers) > 0: - # Acquire a new maximum offset to work with - offset = prev_offset + len(servers) - - if offset >= index: - return servers[index if prev_offset == -1 - else (index - prev_offset - 1)] - - else: - offset = prev_offset + 1 - if offset == index: - return self.servers[idx] - - # Update our old offset - prev_offset = offset - - # If we reach here, then we indexed out of range - raise IndexError('list index out of range') - - def __getstate__(self): - """ - Pickle Support dumps() - """ - attributes = { - 'asset': self.asset, - # Prepare our URL list as we need to extract the associated tags - # and asset details associated with it - 'urls': [{ - 'url': server.url(privacy=False), - 'tag': server.tags if server.tags else None, - 'asset': server.asset} for server in self.servers], - 'locale': self.locale, - 'debug': self.debug, - 'location': self.location, - } - - return attributes - - def __setstate__(self, state): - """ - Pickle Support loads() - """ - self.servers = list() - self.asset = state['asset'] - self.locale = state['locale'] - self.location = state['location'] - for entry in state['urls']: - self.add(entry['url'], asset=entry['asset'], tag=entry['tag']) - - def __bool__(self): - """ - Allows the Apprise object to be wrapped in an 'if statement'. - True is returned if at least one service has been loaded. - """ - return len(self) > 0 - - def __iter__(self): - """ - Returns an iterator to each of our servers loaded. This includes those - found inside configuration. - """ - return chain(*[[s] if not isinstance(s, (ConfigBase, AppriseConfig)) - else iter(s.servers()) for s in self.servers]) - - def __len__(self): - """ - Returns the number of servers loaded; this includes those found within - loaded configuration. This funtion nnever actually counts the - Config entry themselves (if they exist), only what they contain. - """ - return sum([1 if not isinstance(s, (ConfigBase, AppriseConfig)) - else len(s.servers()) for s in self.servers]) From ebb0cc16b16363e91100eebf243a657abd2011cf Mon Sep 17 00:00:00 2001 From: morpheus65535 Date: Sat, 25 May 2024 00:19:06 -0400 Subject: [PATCH 12/18] no log: Delete libs/apprise/apprise.pyi --- libs/apprise/apprise.pyi | 62 ---------------------------------------- 1 file changed, 62 deletions(-) delete mode 100644 libs/apprise/apprise.pyi diff --git a/libs/apprise/apprise.pyi b/libs/apprise/apprise.pyi deleted file mode 100644 index 5a34c9c65..000000000 --- a/libs/apprise/apprise.pyi +++ /dev/null @@ -1,62 +0,0 @@ -from typing import Any, Dict, List, Iterable, Iterator, Optional - -from . import (AppriseAsset, AppriseAttachment, AppriseConfig, ConfigBase, - NotifyBase, NotifyFormat, NotifyType) -from .common import ContentLocation - -_Server = Union[str, ConfigBase, NotifyBase, AppriseConfig] -_Servers = Union[_Server, Dict[Any, _Server], Iterable[_Server]] -# Can't define this recursively as mypy doesn't support recursive types: -# https://github.com/python/mypy/issues/731 -_Tag = Union[str, Iterable[Union[str, Iterable[str]]]] - -class Apprise: - def __init__( - self, - servers: _Servers = ..., - asset: Optional[AppriseAsset] = ..., - location: Optional[ContentLocation] = ..., - debug: bool = ... - ) -> None: ... - @staticmethod - def instantiate( - url: Union[str, Dict[str, NotifyBase]], - asset: Optional[AppriseAsset] = ..., - tag: Optional[_Tag] = ..., - suppress_exceptions: bool = ... - ) -> NotifyBase: ... - def add( - self, - servers: _Servers = ..., - asset: Optional[AppriseAsset] = ..., - tag: Optional[_Tag] = ... - ) -> bool: ... - def clear(self) -> None: ... - def find(self, tag: str = ...) -> Iterator[Apprise]: ... - def notify( - self, - body: str, - title: str = ..., - notify_type: NotifyType = ..., - body_format: NotifyFormat = ..., - tag: _Tag = ..., - attach: Optional[AppriseAttachment] = ..., - interpret_escapes: Optional[bool] = ... - ) -> bool: ... - async def async_notify( - self, - body: str, - title: str = ..., - notify_type: NotifyType = ..., - body_format: NotifyFormat = ..., - tag: _Tag = ..., - attach: Optional[AppriseAttachment] = ..., - interpret_escapes: Optional[bool] = ... - ) -> bool: ... - def details(self, lang: Optional[str] = ...) -> Dict[str, Any]: ... - def urls(self, privacy: bool = ...) -> Iterable[str]: ... - def pop(self, index: int) -> ConfigBase: ... - def __getitem__(self, index: int) -> ConfigBase: ... - def __bool__(self) -> bool: ... - def __iter__(self) -> Iterator[ConfigBase]: ... - def __len__(self) -> int: ... \ No newline at end of file From 0e183c428b1509e4cde77c53c4a47a6393c7a54e Mon Sep 17 00:00:00 2001 From: morpheus65535 Date: Mon, 27 May 2024 20:58:29 -0400 Subject: [PATCH 13/18] Fixed subdivx series search process. #2499 --- .../subliminal_patch/providers/subdivx.py | 34 +++++++++++++------ 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/custom_libs/subliminal_patch/providers/subdivx.py b/custom_libs/subliminal_patch/providers/subdivx.py index ae8625f47..a19ae1b5e 100644 --- a/custom_libs/subliminal_patch/providers/subdivx.py +++ b/custom_libs/subliminal_patch/providers/subdivx.py @@ -126,7 +126,7 @@ class SubdivxSubtitlesProvider(Provider): titles = [video.series if episode else video.title] try: - titles.extend(video.alternative_titles) + titles.extend(video.alternative_series if episode else video.alternative_titles) except: pass else: @@ -138,6 +138,7 @@ class SubdivxSubtitlesProvider(Provider): # TODO: cache pack queries (TV SHOW S01). # Too many redundant server calls. for title in titles: + title = _series_sanitizer(title) for query in ( f"{title} S{video.season:02}E{video.episode:02}", f"{title} S{video.season:02}", @@ -297,20 +298,31 @@ def _check_episode(video, title): ) and season_num == video.season series_title = _SERIES_RE.sub("", title).strip() + series_title = _series_sanitizer(series_title) - distance = abs(len(series_title) - len(video.series)) + for video_series_title in [video.series] + video.alternative_series: + video_series_title = _series_sanitizer(video_series_title) + distance = abs(len(series_title) - len(video_series_title)) - series_matched = distance < 4 and ep_matches + series_matched = (distance < 4 or video_series_title in series_title) and ep_matches + + logger.debug( + "Series matched? %s [%s -> %s] [title distance: %d]", + series_matched, + video_series_title, + series_title, + distance, + ) + + if series_matched: + return True + return False - logger.debug( - "Series matched? %s [%s -> %s] [title distance: %d]", - series_matched, - video, - title, - distance, - ) - return series_matched +def _series_sanitizer(title): + title = re.sub(r"\'|\.+", '', title) # remove single quote and dot + title = re.sub(r"\W+", ' ', title) # replace by a space anything other than a letter, digit or underscore + return re.sub(r"([A-Z])\s(?=[A-Z]\b)", '', title).strip() # Marvels Agent of S.H.I.E.L.D def _check_movie(video, title): From 884200441bec801eba56a4ac08328f8227ad3bed Mon Sep 17 00:00:00 2001 From: JayZed Date: Mon, 27 May 2024 21:18:45 -0400 Subject: [PATCH 14/18] Fix for case insensitive filesystem upates This fix was made necessary when a library changed the case of one of its files, but kept the name the same. When the file was updated in place, the case did not change. The solution is to delete the file first before extracting the new one from the zip file with the changed case. --- bazarr/app/check_update.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/bazarr/app/check_update.py b/bazarr/app/check_update.py index 97617c75b..54aeefcce 100644 --- a/bazarr/app/check_update.py +++ b/bazarr/app/check_update.py @@ -165,6 +165,9 @@ def apply_update(): parent_dir = os.path.dirname(file_path) os.makedirs(parent_dir, exist_ok=True) if not os.path.isdir(file_path): + if os.path.exists(file_path): + # remove the file first to handle case-insensitive file systems + os.remove(file_path) with open(file_path, 'wb+') as f: f.write(archive.read(file)) except Exception: From b7e6de71ffe977a5b2fc71d3b61545226af83395 Mon Sep 17 00:00:00 2001 From: Anderson Shindy Oki Date: Fri, 31 May 2024 11:08:29 +0900 Subject: [PATCH 15/18] Fixed bazarr restart traceback exception --- bazarr/utilities/central.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/bazarr/utilities/central.py b/bazarr/utilities/central.py index 009c42e1d..29fe898bc 100644 --- a/bazarr/utilities/central.py +++ b/bazarr/utilities/central.py @@ -3,6 +3,7 @@ # only methods can be specified here that do not cause other moudules to be loaded # for other methods that use settings, etc., use utilities/helper.py +import contextlib import logging import os from pathlib import Path @@ -53,4 +54,8 @@ def restart_bazarr(): except Exception as e: logging.error(f'BAZARR Cannot create restart file: {repr(e)}') logging.info('Bazarr is being restarted...') - raise SystemExit(EXIT_NORMAL) + + # Wrap the SystemExit for a graceful restart. The SystemExit still performs the cleanup but the traceback is omitted + # preventing to throw the exception to the caller but still terminates the Python process with the desired Exit Code + with contextlib.suppress(SystemExit): + raise SystemExit(EXIT_NORMAL) From 77302fad218a3c14c91c3d28074f30e02ffe9b77 Mon Sep 17 00:00:00 2001 From: Alex Meyer Date: Thu, 30 May 2024 22:16:24 -0400 Subject: [PATCH 16/18] Fixed throttled_providers.dat reset --- bazarr/app/get_providers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bazarr/app/get_providers.py b/bazarr/app/get_providers.py index d7a61326f..bc251a4e1 100644 --- a/bazarr/app/get_providers.py +++ b/bazarr/app/get_providers.py @@ -496,7 +496,7 @@ def get_throttled_providers(): except Exception: # set empty content in throttled_providers.dat logging.error("Invalid content in throttled_providers.dat. Resetting") - set_throttled_providers(providers) + set_throttled_providers(str(providers)) finally: return providers From bb8233b599fa0bd8133b092897a4fbcfd736c8cd Mon Sep 17 00:00:00 2001 From: morpheus65535 Date: Thu, 6 Jun 2024 06:17:13 -0400 Subject: [PATCH 17/18] Fixed external subtitles indexing on some platforms where filesystem encoding may be using a different UTF8 normalization form. --- custom_libs/subliminal_patch/core.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/custom_libs/subliminal_patch/core.py b/custom_libs/subliminal_patch/core.py index 872896e9c..c1629496b 100644 --- a/custom_libs/subliminal_patch/core.py +++ b/custom_libs/subliminal_patch/core.py @@ -946,8 +946,8 @@ def _search_external_subtitles(path, languages=None, only_one=False, match_stric lambda m: "" if str(m.group(1)).lower() in FULL_LANGUAGE_LIST else m.group(0), p_root) p_root_lower = p_root_bare.lower() - - filename_matches = p_root_lower == fn_no_ext_lower + # comparing to both unicode normalization forms to prevent broking stuff and improve indexing on some platforms. + filename_matches = fn_no_ext_lower in [p_root_lower, unicodedata.normalize('NFC', p_root_lower)] filename_contains = p_root_lower in fn_no_ext_lower if not filename_matches: From be8f2d6d183e5206f932be1113e0da7db2a2277a Mon Sep 17 00:00:00 2001 From: Anderson Shindy Oki Date: Fri, 7 Jun 2024 12:00:42 +0900 Subject: [PATCH 18/18] Upgraded mantine to v7.x --- frontend/package-lock.json | 747 +++++++----------- frontend/package.json | 14 +- frontend/postcss.config.cjs | 14 + frontend/src/App/Header.module.scss | 9 + frontend/src/App/Header.tsx | 67 +- frontend/src/App/Navbar.module.scss | 56 ++ frontend/src/App/Navbar.tsx | 114 +-- frontend/src/App/ThemeLoader.tsx | 39 + frontend/src/App/ThemeProvider.tsx | 61 ++ frontend/src/App/index.tsx | 18 +- frontend/src/App/theme.tsx | 87 -- frontend/src/Router/index.tsx | 4 +- frontend/src/assets/_bazarr.scss | 40 + frontend/src/assets/_mantine.scss | 61 ++ frontend/src/assets/_variables.module.scss | 18 + frontend/src/assets/action_icon.module.scss | 14 + frontend/src/assets/app_shell.module.scss | 5 + frontend/src/assets/badge.module.scss | 8 + frontend/src/assets/button.module.scss | 12 + frontend/src/components/Search.module.scss | 9 + frontend/src/components/Search.tsx | 80 +- frontend/src/components/StateIcon.tsx | 12 +- frontend/src/components/SubtitleToolsMenu.tsx | 6 +- frontend/src/components/bazarr/AudioList.tsx | 2 +- .../src/components/bazarr/Language.test.tsx | 18 +- frontend/src/components/bazarr/Language.tsx | 2 +- .../src/components/forms/FrameRateForm.tsx | 8 +- .../src/components/forms/ItemEditForm.tsx | 2 +- .../forms/MovieUploadForm.module.scss | 0 .../src/components/forms/MovieUploadForm.tsx | 22 +- .../forms/ProfileEditForm.module.scss | 5 + .../src/components/forms/ProfileEditForm.tsx | 16 +- .../src/components/forms/SeriesUploadForm.tsx | 22 +- .../src/components/forms/SyncSubtitleForm.tsx | 45 +- .../src/components/forms/TimeOffsetForm.tsx | 2 +- frontend/src/components/index.tsx | 2 +- .../src/components/inputs/Action.test.tsx | 8 +- .../src/components/inputs/ChipInput.test.tsx | 10 +- frontend/src/components/inputs/ChipInput.tsx | 50 +- .../components/inputs/DropContent.module.scss | 4 + .../src/components/inputs/DropContent.tsx | 20 +- .../src/components/inputs/FileBrowser.tsx | 27 +- .../src/components/inputs/Selector.test.tsx | 35 +- frontend/src/components/inputs/Selector.tsx | 38 +- .../components/modals/ManualSearchModal.tsx | 24 +- .../components/tables/BaseTable.module.scss | 9 + frontend/src/components/tables/BaseTable.tsx | 61 +- frontend/src/components/tables/GroupTable.tsx | 22 +- .../src/components/tables/PageControl.tsx | 2 +- frontend/src/components/toolbox/Button.tsx | 2 +- .../components/toolbox/Toolbox.module.scss | 9 + .../toolbox/{index.tsx => Toolbox.tsx} | 15 +- frontend/src/constants.ts | 8 - frontend/src/modules/socketio/reducer.ts | 2 +- frontend/src/modules/task/index.ts | 2 +- frontend/src/modules/task/notification.ts | 14 +- frontend/src/pages/Authentication.tsx | 2 +- frontend/src/pages/Blacklist/Movies/table.tsx | 4 +- frontend/src/pages/Blacklist/Series/table.tsx | 4 +- frontend/src/pages/Episodes/index.tsx | 4 +- frontend/src/pages/Episodes/table.tsx | 11 +- frontend/src/pages/History/Movies/index.tsx | 4 +- frontend/src/pages/History/Series/index.tsx | 7 +- .../Statistics/HistoryStats.module.scss | 9 + .../{index.tsx => HistoryStats.tsx} | 41 +- frontend/src/pages/History/history.test.tsx | 2 +- frontend/src/pages/Movies/Details/index.tsx | 8 +- frontend/src/pages/Movies/Details/table.tsx | 11 +- frontend/src/pages/Movies/index.tsx | 4 +- frontend/src/pages/Series/index.tsx | 19 +- frontend/src/pages/Settings/General/index.tsx | 17 +- .../src/pages/Settings/Languages/equals.tsx | 2 +- .../src/pages/Settings/Languages/table.tsx | 5 +- .../Settings/Notifications/components.tsx | 2 +- .../pages/Settings/Providers/components.tsx | 30 +- frontend/src/pages/Settings/Radarr/index.tsx | 2 +- frontend/src/pages/Settings/Sonarr/index.tsx | 2 +- .../src/pages/Settings/Subtitles/index.tsx | 2 +- .../Settings/components/Card.module.scss | 9 + .../src/pages/Settings/components/Card.tsx | 33 +- .../src/pages/Settings/components/Layout.tsx | 2 +- .../pages/Settings/components/LayoutModal.tsx | 2 +- .../src/pages/Settings/components/Message.tsx | 2 +- .../Settings/components/Section.test.tsx | 8 +- .../src/pages/Settings/components/Section.tsx | 2 +- .../pages/Settings/components/collapse.tsx | 2 +- .../pages/Settings/components/forms.test.tsx | 4 +- .../src/pages/Settings/components/forms.tsx | 5 + .../src/pages/Settings/components/index.tsx | 4 +- .../pages/Settings/components/pathMapper.tsx | 2 +- .../src/pages/System/Announcements/table.tsx | 7 +- frontend/src/pages/System/Backups/table.tsx | 7 +- frontend/src/pages/System/Logs/index.tsx | 4 +- frontend/src/pages/System/Releases/index.tsx | 4 +- frontend/src/pages/System/Status/index.tsx | 9 +- frontend/src/pages/System/Status/table.tsx | 7 +- frontend/src/pages/System/Tasks/table.tsx | 7 +- frontend/src/pages/Wanted/Movies/index.tsx | 2 +- frontend/src/pages/Wanted/Series/index.tsx | 6 +- frontend/src/pages/errors/UIError.tsx | 6 +- frontend/src/pages/views/ItemOverview.tsx | 57 +- frontend/src/pages/views/MassEditor.tsx | 10 +- frontend/src/providers.tsx | 2 +- frontend/src/styles/index.ts | 1 - frontend/src/styles/table.ts | 19 - frontend/vite.config.ts | 10 + 106 files changed, 1187 insertions(+), 1241 deletions(-) create mode 100644 frontend/postcss.config.cjs create mode 100644 frontend/src/App/Header.module.scss create mode 100644 frontend/src/App/Navbar.module.scss create mode 100644 frontend/src/App/ThemeLoader.tsx create mode 100644 frontend/src/App/ThemeProvider.tsx delete mode 100644 frontend/src/App/theme.tsx create mode 100644 frontend/src/assets/_bazarr.scss create mode 100644 frontend/src/assets/_mantine.scss create mode 100644 frontend/src/assets/_variables.module.scss create mode 100644 frontend/src/assets/action_icon.module.scss create mode 100644 frontend/src/assets/app_shell.module.scss create mode 100644 frontend/src/assets/badge.module.scss create mode 100644 frontend/src/assets/button.module.scss create mode 100644 frontend/src/components/Search.module.scss create mode 100644 frontend/src/components/forms/MovieUploadForm.module.scss create mode 100644 frontend/src/components/forms/ProfileEditForm.module.scss create mode 100644 frontend/src/components/inputs/DropContent.module.scss create mode 100644 frontend/src/components/tables/BaseTable.module.scss create mode 100644 frontend/src/components/toolbox/Toolbox.module.scss rename frontend/src/components/toolbox/{index.tsx => Toolbox.tsx} (58%) create mode 100644 frontend/src/pages/History/Statistics/HistoryStats.module.scss rename frontend/src/pages/History/Statistics/{index.tsx => HistoryStats.tsx} (79%) create mode 100644 frontend/src/pages/Settings/components/Card.module.scss delete mode 100644 frontend/src/styles/index.ts delete mode 100644 frontend/src/styles/table.ts diff --git a/frontend/package-lock.json b/frontend/package-lock.json index bfc24c17f..f19cbab4d 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -9,12 +9,12 @@ "version": "1.0.0", "license": "GPL-3", "dependencies": { - "@mantine/core": "^6.0.21", - "@mantine/dropzone": "^6.0.21", - "@mantine/form": "^6.0.21", - "@mantine/hooks": "^6.0.21", - "@mantine/modals": "^6.0.21", - "@mantine/notifications": "^6.0.21", + "@mantine/core": "^7.10.1", + "@mantine/dropzone": "^7.10.1", + "@mantine/form": "^7.10.1", + "@mantine/hooks": "^7.10.1", + "@mantine/modals": "^7.10.1", + "@mantine/notifications": "^7.10.1", "axios": "^1.6.8", "react": "^18.2.0", "react-dom": "^18.2.0", @@ -49,6 +49,8 @@ "husky": "^9.0.11", "jsdom": "^24.0.0", "lodash": "^4.17.21", + "postcss-preset-mantine": "^1.14.4", + "postcss-simple-vars": "^7.0.1", "prettier": "^3.2.5", "prettier-plugin-organize-imports": "^3.2.4", "pretty-quick": "^4.0.0", @@ -94,6 +96,7 @@ "version": "7.24.2", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.2.tgz", "integrity": "sha512-y5+tLQyV8pg3fsiln67BVLD1P13Eg4lh5RW9mF0zUuvLrv9uIQ4MCL+CRT+FTsBlBjcIan6PGsLcBN0m3ClUyQ==", + "dev": true, "dependencies": { "@babel/highlight": "^7.24.2", "picocolors": "^1.0.0" @@ -335,6 +338,7 @@ "version": "7.24.3", "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.3.tgz", "integrity": "sha512-viKb0F9f2s0BCS22QSF308z/+1YWKV/76mwt61NBzS5izMzDPwdq1pTrzf+Li3npBWX9KdQbkeCt1jSAM7lZqg==", + "dev": true, "dependencies": { "@babel/types": "^7.24.0" }, @@ -456,6 +460,7 @@ "version": "7.24.1", "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.1.tgz", "integrity": "sha512-2ofRCjnnA9y+wk8b9IAREroeUP02KHp431N2mhKniy2yKIDKpbrHv9eXwm8cBeWQYcJmzv5qKCu65P47eCF7CQ==", + "dev": true, "engines": { "node": ">=6.9.0" } @@ -464,6 +469,7 @@ "version": "7.22.20", "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", + "dev": true, "engines": { "node": ">=6.9.0" } @@ -509,6 +515,7 @@ "version": "7.24.2", "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.2.tgz", "integrity": "sha512-Yac1ao4flkTxTteCDZLEvdxg2fZfz1v8M4QpaGypq/WPDqg3ijHYbDfs+LG5hvzSoqaSZ9/Z9lKSP3CjZjv+pA==", + "dev": true, "dependencies": { "@babel/helper-validator-identifier": "^7.22.20", "chalk": "^2.4.2", @@ -523,6 +530,7 @@ "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, "dependencies": { "color-convert": "^1.9.0" }, @@ -534,6 +542,7 @@ "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -547,6 +556,7 @@ "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, "dependencies": { "color-name": "1.1.3" } @@ -554,12 +564,14 @@ "node_modules/@babel/highlight/node_modules/color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true }, "node_modules/@babel/highlight/node_modules/escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, "engines": { "node": ">=0.8.0" } @@ -568,6 +580,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, "engines": { "node": ">=4" } @@ -576,6 +589,7 @@ "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, "dependencies": { "has-flag": "^3.0.0" }, @@ -2193,6 +2207,7 @@ "version": "7.24.0", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.0.tgz", "integrity": "sha512-+j7a5c253RfKh8iABBhywc8NSfP5LURe7Uh4qpsh6jc+aLJguvmIUBdjSdEMQv2bENrCR5MfRdjGo7vzS/ob7w==", + "dev": true, "dependencies": { "@babel/helper-string-parser": "^7.23.4", "@babel/helper-validator-identifier": "^7.22.20", @@ -2208,120 +2223,6 @@ "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", "dev": true }, - "node_modules/@emotion/babel-plugin": { - "version": "11.11.0", - "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.11.0.tgz", - "integrity": "sha512-m4HEDZleaaCH+XgDDsPF15Ht6wTLsgDTeR3WYj9Q/k76JtWhrJjcP4+/XlG8LGT/Rol9qUfOIztXeA84ATpqPQ==", - "peer": true, - "dependencies": { - "@babel/helper-module-imports": "^7.16.7", - "@babel/runtime": "^7.18.3", - "@emotion/hash": "^0.9.1", - "@emotion/memoize": "^0.8.1", - "@emotion/serialize": "^1.1.2", - "babel-plugin-macros": "^3.1.0", - "convert-source-map": "^1.5.0", - "escape-string-regexp": "^4.0.0", - "find-root": "^1.1.0", - "source-map": "^0.5.7", - "stylis": "4.2.0" - } - }, - "node_modules/@emotion/cache": { - "version": "11.11.0", - "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.11.0.tgz", - "integrity": "sha512-P34z9ssTCBi3e9EI1ZsWpNHcfY1r09ZO0rZbRO2ob3ZQMnFI35jB536qoXbkdesr5EUhYi22anuEJuyxifaqAQ==", - "peer": true, - "dependencies": { - "@emotion/memoize": "^0.8.1", - "@emotion/sheet": "^1.2.2", - "@emotion/utils": "^1.2.1", - "@emotion/weak-memoize": "^0.3.1", - "stylis": "4.2.0" - } - }, - "node_modules/@emotion/hash": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.1.tgz", - "integrity": "sha512-gJB6HLm5rYwSLI6PQa+X1t5CFGrv1J1TWG+sOyMCeKz2ojaj6Fnl/rZEspogG+cvqbt4AE/2eIyD2QfLKTBNlQ==", - "peer": true - }, - "node_modules/@emotion/memoize": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.1.tgz", - "integrity": "sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==", - "peer": true - }, - "node_modules/@emotion/react": { - "version": "11.11.4", - "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.11.4.tgz", - "integrity": "sha512-t8AjMlF0gHpvvxk5mAtCqR4vmxiGHCeJBaQO6gncUSdklELOgtwjerNY2yuJNfwnc6vi16U/+uMF+afIawJ9iw==", - "peer": true, - "dependencies": { - "@babel/runtime": "^7.18.3", - "@emotion/babel-plugin": "^11.11.0", - "@emotion/cache": "^11.11.0", - "@emotion/serialize": "^1.1.3", - "@emotion/use-insertion-effect-with-fallbacks": "^1.0.1", - "@emotion/utils": "^1.2.1", - "@emotion/weak-memoize": "^0.3.1", - "hoist-non-react-statics": "^3.3.1" - }, - "peerDependencies": { - "react": ">=16.8.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@emotion/serialize": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.1.4.tgz", - "integrity": "sha512-RIN04MBT8g+FnDwgvIUi8czvr1LU1alUMI05LekWB5DGyTm8cCBMCRpq3GqaiyEDRptEXOyXnvZ58GZYu4kBxQ==", - "peer": true, - "dependencies": { - "@emotion/hash": "^0.9.1", - "@emotion/memoize": "^0.8.1", - "@emotion/unitless": "^0.8.1", - "@emotion/utils": "^1.2.1", - "csstype": "^3.0.2" - } - }, - "node_modules/@emotion/sheet": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.2.2.tgz", - "integrity": "sha512-0QBtGvaqtWi+nx6doRwDdBIzhNdZrXUppvTM4dtZZWEGTXL/XE/yJxLMGlDT1Gt+UHH5IX1n+jkXyytE/av7OA==", - "peer": true - }, - "node_modules/@emotion/unitless": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.1.tgz", - "integrity": "sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==", - "peer": true - }, - "node_modules/@emotion/use-insertion-effect-with-fallbacks": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.0.1.tgz", - "integrity": "sha512-jT/qyKZ9rzLErtrjGgdkMBn2OP8wl0G3sQlBb3YPryvKHsjvINUhVaPFfP+fpBcOkmrVOVEEHQFJ7nbj2TH2gw==", - "peer": true, - "peerDependencies": { - "react": ">=16.8.0" - } - }, - "node_modules/@emotion/utils": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.2.1.tgz", - "integrity": "sha512-Y2tGf3I+XVnajdItskUCn6LX+VUDmP6lTL4fcqsXAv43dnlbZiuW4MWQW38rW/BVWSE7Q/7+XQocmpnRYILUmg==", - "peer": true - }, - "node_modules/@emotion/weak-memoize": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.3.1.tgz", - "integrity": "sha512-EsBwpc7hBUJWAsNPBmJy4hxWx12v6bshQsldrVmjxJoc3isbxhOrF2IcCpaXxfvq03NwkI7sbsOLXbYuqF/8Ww==", - "peer": true - }, "node_modules/@esbuild/aix-ppc64": { "version": "0.20.2", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz", @@ -2791,13 +2692,13 @@ } }, "node_modules/@floating-ui/react": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/@floating-ui/react/-/react-0.19.2.tgz", - "integrity": "sha512-JyNk4A0Ezirq8FlXECvRtQOX/iBe5Ize0W/pLkrZjfHW9GUV7Xnq6zm6fyZuQzaHHqEnVizmvlA96e1/CkZv+w==", + "version": "0.26.12", + "resolved": "https://registry.npmjs.org/@floating-ui/react/-/react-0.26.12.tgz", + "integrity": "sha512-D09o62HrWdIkstF2kGekIKAC0/N/Dl6wo3CQsnLcOmO3LkW6Ik8uIb3kw8JYkwxNCcg+uJ2bpWUiIijTBep05w==", "dependencies": { - "@floating-ui/react-dom": "^1.3.0", - "aria-hidden": "^1.1.3", - "tabbable": "^6.0.1" + "@floating-ui/react-dom": "^2.0.0", + "@floating-ui/utils": "^0.2.0", + "tabbable": "^6.0.0" }, "peerDependencies": { "react": ">=16.8.0", @@ -2805,11 +2706,11 @@ } }, "node_modules/@floating-ui/react-dom": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-1.3.0.tgz", - "integrity": "sha512-htwHm67Ji5E/pROEAr7f8IKFShuiCKHwUC/UY4vC3I5jiSvGFAYnSYiZO5MlGmads+QqvUkR9ANHEguGrDv72g==", + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.0.8.tgz", + "integrity": "sha512-HOdqOt3R3OGeTKidaLvJKcgg75S6tibQ3Tif4eyd91QnIJWr0NLvoXFpJA/j8HqkFSL68GDca9AuyWEHlhyClw==", "dependencies": { - "@floating-ui/dom": "^1.2.1" + "@floating-ui/dom": "^1.6.1" }, "peerDependencies": { "react": ">=16.8.0", @@ -3034,120 +2935,107 @@ } }, "node_modules/@mantine/core": { - "version": "6.0.21", - "resolved": "https://registry.npmjs.org/@mantine/core/-/core-6.0.21.tgz", - "integrity": "sha512-Kx4RrRfv0I+cOCIcsq/UA2aWcYLyXgW3aluAuW870OdXnbII6qg7RW28D+r9D76SHPxWFKwIKwmcucAG08Divg==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@mantine/core/-/core-7.10.1.tgz", + "integrity": "sha512-l9ypojKN3PjwO1CSLIsqxi7mA25+7w+xc71Q+JuCCREI0tuGwkZsKbIOpuTATIJOjPh8ycLiW7QxX1LYsRTq6w==", + "license": "MIT", "dependencies": { - "@floating-ui/react": "^0.19.1", - "@mantine/styles": "6.0.21", - "@mantine/utils": "6.0.21", - "@radix-ui/react-scroll-area": "1.0.2", - "react-remove-scroll": "^2.5.5", - "react-textarea-autosize": "8.3.4" + "@floating-ui/react": "^0.26.9", + "clsx": "^2.1.1", + "react-number-format": "^5.3.1", + "react-remove-scroll": "^2.5.7", + "react-textarea-autosize": "8.5.3", + "type-fest": "^4.12.0" }, "peerDependencies": { - "@mantine/hooks": "6.0.21", - "react": ">=16.8.0", - "react-dom": ">=16.8.0" + "@mantine/hooks": "7.10.1", + "react": "^18.2.0", + "react-dom": "^18.2.0" + } + }, + "node_modules/@mantine/core/node_modules/type-fest": { + "version": "4.15.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.15.0.tgz", + "integrity": "sha512-tB9lu0pQpX5KJq54g+oHOLumOx+pMep4RaM6liXh2PKmVRFF+/vAtUP0ZaJ0kOySfVNjF6doBWPHhBhISKdlIA==", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/@mantine/dropzone": { - "version": "6.0.21", - "resolved": "https://registry.npmjs.org/@mantine/dropzone/-/dropzone-6.0.21.tgz", - "integrity": "sha512-v63tL4x7R1CvBNnxJVaVPhBVnQcfROQvyOV0xK/v0ZGNAzFxjJoiCRMGdlBjxnEawM0dRhNs/46ItpBgjQIr6g==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@mantine/dropzone/-/dropzone-7.10.1.tgz", + "integrity": "sha512-WzOLwMf8RJtakivPzSYBy3ZLuCtsZEbkJpAXNmM5PdsA8s9MKmY3jYA1MuZis1/NStAGm1d4twofH1KjGCMphg==", + "license": "MIT", "dependencies": { - "@mantine/utils": "6.0.21", - "react-dropzone": "14.2.3" + "react-dropzone-esm": "15.0.1" }, "peerDependencies": { - "@mantine/core": "6.0.21", - "@mantine/hooks": "6.0.21", - "react": ">=16.8.0", - "react-dom": ">=16.8.0" + "@mantine/core": "7.10.1", + "@mantine/hooks": "7.10.1", + "react": "^18.2.0", + "react-dom": "^18.2.0" } }, "node_modules/@mantine/form": { - "version": "6.0.21", - "resolved": "https://registry.npmjs.org/@mantine/form/-/form-6.0.21.tgz", - "integrity": "sha512-d4tlxyZic7MSDnaPx/WliCX1sRFDkUd2nxx4MxxO2T4OSek0YDqTlSBCxeoveu60P+vrQQN5rbbsVsaOJBe4SQ==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@mantine/form/-/form-7.10.1.tgz", + "integrity": "sha512-mZwzg4GEWKEDKEIZu9FmSpGFzYYhFD2YArVOXUM0MMciUqX7yxSCon1PaPJxrV8ldc6FE+JLVI2+G2KVxJ3ZXA==", + "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.3", - "klona": "^2.0.5" + "klona": "^2.0.6" }, "peerDependencies": { - "react": ">=16.8.0" + "react": "^18.2.0" } }, "node_modules/@mantine/hooks": { - "version": "6.0.21", - "resolved": "https://registry.npmjs.org/@mantine/hooks/-/hooks-6.0.21.tgz", - "integrity": "sha512-sYwt5wai25W6VnqHbS5eamey30/HD5dNXaZuaVEAJ2i2bBv8C0cCiczygMDpAFiSYdXoSMRr/SZ2CrrPTzeNew==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@mantine/hooks/-/hooks-7.10.1.tgz", + "integrity": "sha512-0EH9WBWUdtQLGU3Ak+csQ77EtUxI6pPNfwZdRJQWcaA3f8SFOLo9h9CGxiikFExerhvuCeUlaTf3s+TB9Op/rw==", + "license": "MIT", "peerDependencies": { - "react": ">=16.8.0" + "react": "^18.2.0" } }, "node_modules/@mantine/modals": { - "version": "6.0.21", - "resolved": "https://registry.npmjs.org/@mantine/modals/-/modals-6.0.21.tgz", - "integrity": "sha512-Gx2D/ZHMUuYF197JKMWey4K9FeGP9rxYp4lmAEXUrjXiST2fEhLZOdiD75KuOHXd1/sYAU9NcNRo9wXrlF/gUA==", - "dependencies": { - "@mantine/utils": "6.0.21" - }, + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@mantine/modals/-/modals-7.10.1.tgz", + "integrity": "sha512-2riQSNpVV7f0baizlqcggz9hx9/+y6SQTnW3zEkl/RIkuyK9dpeMFUG6M+M8ntwP79b7x9n7Em9PMWxRbgi28A==", + "license": "MIT", "peerDependencies": { - "@mantine/core": "6.0.21", - "@mantine/hooks": "6.0.21", - "react": ">=16.8.0", - "react-dom": ">=16.8.0" + "@mantine/core": "7.10.1", + "@mantine/hooks": "7.10.1", + "react": "^18.2.0", + "react-dom": "^18.2.0" } }, "node_modules/@mantine/notifications": { - "version": "6.0.21", - "resolved": "https://registry.npmjs.org/@mantine/notifications/-/notifications-6.0.21.tgz", - "integrity": "sha512-qsrqxuJHK8b67sf9Pfk+xyhvpf9jMsivW8vchfnJfjv7yz1lLvezjytMFp4fMDoYhjHnDPOEc/YFockK4muhOw==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@mantine/notifications/-/notifications-7.10.1.tgz", + "integrity": "sha512-cx3JR3BJzEzH6t2EF1ysrWVY/rdJk0WbSBQo/qFamJd2sbU+8XAHriI8Cx6hNo7uRGCwd8VGAj7Cf3aWK2VC5A==", + "license": "MIT", "dependencies": { - "@mantine/utils": "6.0.21", - "react-transition-group": "4.4.2" + "@mantine/store": "7.10.1", + "react-transition-group": "4.4.5" }, "peerDependencies": { - "@mantine/core": "6.0.21", - "@mantine/hooks": "6.0.21", - "react": ">=16.8.0", - "react-dom": ">=16.8.0" - } - }, - "node_modules/@mantine/styles": { - "version": "6.0.21", - "resolved": "https://registry.npmjs.org/@mantine/styles/-/styles-6.0.21.tgz", - "integrity": "sha512-PVtL7XHUiD/B5/kZ/QvZOZZQQOj12QcRs3Q6nPoqaoPcOX5+S7bMZLMH0iLtcGq5OODYk0uxlvuJkOZGoPj8Mg==", - "dependencies": { - "clsx": "1.1.1", - "csstype": "3.0.9" - }, - "peerDependencies": { - "@emotion/react": ">=11.9.0", - "react": ">=16.8.0", - "react-dom": ">=16.8.0" - } - }, - "node_modules/@mantine/styles/node_modules/clsx": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.1.1.tgz", - "integrity": "sha512-6/bPho624p3S2pMyvP5kKBPXnI3ufHLObBFCfgx+LkeR5lg2XYy2hqZqUf45ypD8COn2bhgGJSUE+l5dhNBieA==", - "engines": { - "node": ">=6" + "@mantine/core": "7.10.1", + "@mantine/hooks": "7.10.1", + "react": "^18.2.0", + "react-dom": "^18.2.0" } }, - "node_modules/@mantine/styles/node_modules/csstype": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.9.tgz", - "integrity": "sha512-rpw6JPxK6Rfg1zLOYCSwle2GFOOsnjmDYDaBwEcwoOg4qlsIVCN789VkBZDJAGi4T07gI4YSutR43t9Zz4Lzuw==" - }, - "node_modules/@mantine/utils": { - "version": "6.0.21", - "resolved": "https://registry.npmjs.org/@mantine/utils/-/utils-6.0.21.tgz", - "integrity": "sha512-33RVDRop5jiWFao3HKd3Yp7A9mEq4HAJxJPTuYm1NkdqX6aTKOQK7wT8v8itVodBp+sb4cJK6ZVdD1UurK/txQ==", + "node_modules/@mantine/store": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@mantine/store/-/store-7.10.1.tgz", + "integrity": "sha512-KrGBsSoMsfrYeLxPwf5rFv0s2Nl/4wf+AaF/U1SpQrMgPI8vYokPXx52Wp3jCmlo12NCZnCIG+/6YHAdTWH1qQ==", + "license": "MIT", "peerDependencies": { - "react": ">=16.8.0" + "react": "^18.2.0" } }, "node_modules/@nicolo-ribaudo/eslint-scope-5-internals": { @@ -3222,137 +3110,6 @@ "integrity": "sha512-j7P6Rgr3mmtdkeDGTe0E/aYyWEWVtc5yFXtHCRHs28/jptDEWfaVOc5T7cblqy1XKPPfCxJc/8DwQ5YgLOZOVQ==", "dev": true }, - "node_modules/@radix-ui/number": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@radix-ui/number/-/number-1.0.0.tgz", - "integrity": "sha512-Ofwh/1HX69ZfJRiRBMTy7rgjAzHmwe4kW9C9Y99HTRUcYLUuVT0KESFj15rPjRgKJs20GPq8Bm5aEDJ8DuA3vA==", - "dependencies": { - "@babel/runtime": "^7.13.10" - } - }, - "node_modules/@radix-ui/primitive": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.0.0.tgz", - "integrity": "sha512-3e7rn8FDMin4CgeL7Z/49smCA3rFYY3Ha2rUQ7HRWFadS5iCRw08ZgVT1LaNTCNqgvrUiyczLflrVrF0SRQtNA==", - "dependencies": { - "@babel/runtime": "^7.13.10" - } - }, - "node_modules/@radix-ui/react-compose-refs": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.0.0.tgz", - "integrity": "sha512-0KaSv6sx787/hK3eF53iOkiSLwAGlFMx5lotrqD2pTjB18KbybKoEIgkNZTKC60YECDQTKGTRcDBILwZVqVKvA==", - "dependencies": { - "@babel/runtime": "^7.13.10" - }, - "peerDependencies": { - "react": "^16.8 || ^17.0 || ^18.0" - } - }, - "node_modules/@radix-ui/react-context": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.0.0.tgz", - "integrity": "sha512-1pVM9RfOQ+n/N5PJK33kRSKsr1glNxomxONs5c49MliinBY6Yw2Q995qfBUUo0/Mbg05B/sGA0gkgPI7kmSHBg==", - "dependencies": { - "@babel/runtime": "^7.13.10" - }, - "peerDependencies": { - "react": "^16.8 || ^17.0 || ^18.0" - } - }, - "node_modules/@radix-ui/react-direction": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.0.0.tgz", - "integrity": "sha512-2HV05lGUgYcA6xgLQ4BKPDmtL+QbIZYH5fCOTAOOcJ5O0QbWS3i9lKaurLzliYUDhORI2Qr3pyjhJh44lKA3rQ==", - "dependencies": { - "@babel/runtime": "^7.13.10" - }, - "peerDependencies": { - "react": "^16.8 || ^17.0 || ^18.0" - } - }, - "node_modules/@radix-ui/react-presence": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.0.0.tgz", - "integrity": "sha512-A+6XEvN01NfVWiKu38ybawfHsBjWum42MRPnEuqPsBZ4eV7e/7K321B5VgYMPv3Xx5An6o1/l9ZuDBgmcmWK3w==", - "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/react-compose-refs": "1.0.0", - "@radix-ui/react-use-layout-effect": "1.0.0" - }, - "peerDependencies": { - "react": "^16.8 || ^17.0 || ^18.0", - "react-dom": "^16.8 || ^17.0 || ^18.0" - } - }, - "node_modules/@radix-ui/react-primitive": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-1.0.1.tgz", - "integrity": "sha512-fHbmislWVkZaIdeF6GZxF0A/NH/3BjrGIYj+Ae6eTmTCr7EB0RQAAVEiqsXK6p3/JcRqVSBQoceZroj30Jj3XA==", - "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/react-slot": "1.0.1" - }, - "peerDependencies": { - "react": "^16.8 || ^17.0 || ^18.0", - "react-dom": "^16.8 || ^17.0 || ^18.0" - } - }, - "node_modules/@radix-ui/react-scroll-area": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@radix-ui/react-scroll-area/-/react-scroll-area-1.0.2.tgz", - "integrity": "sha512-k8VseTxI26kcKJaX0HPwkvlNBPTs56JRdYzcZ/vzrNUkDlvXBy8sMc7WvCpYzZkHgb+hd72VW9MqkqecGtuNgg==", - "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/number": "1.0.0", - "@radix-ui/primitive": "1.0.0", - "@radix-ui/react-compose-refs": "1.0.0", - "@radix-ui/react-context": "1.0.0", - "@radix-ui/react-direction": "1.0.0", - "@radix-ui/react-presence": "1.0.0", - "@radix-ui/react-primitive": "1.0.1", - "@radix-ui/react-use-callback-ref": "1.0.0", - "@radix-ui/react-use-layout-effect": "1.0.0" - }, - "peerDependencies": { - "react": "^16.8 || ^17.0 || ^18.0", - "react-dom": "^16.8 || ^17.0 || ^18.0" - } - }, - "node_modules/@radix-ui/react-slot": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.0.1.tgz", - "integrity": "sha512-avutXAFL1ehGvAXtPquu0YK5oz6ctS474iM3vNGQIkswrVhdrS52e3uoMQBzZhNRAIE0jBnUyXWNmSjGHhCFcw==", - "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/react-compose-refs": "1.0.0" - }, - "peerDependencies": { - "react": "^16.8 || ^17.0 || ^18.0" - } - }, - "node_modules/@radix-ui/react-use-callback-ref": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.0.0.tgz", - "integrity": "sha512-GZtyzoHz95Rhs6S63D2t/eqvdFCm7I+yHMLVQheKM7nBD8mbZIt+ct1jz4536MDnaOGKIxynJ8eHTkVGVVkoTg==", - "dependencies": { - "@babel/runtime": "^7.13.10" - }, - "peerDependencies": { - "react": "^16.8 || ^17.0 || ^18.0" - } - }, - "node_modules/@radix-ui/react-use-layout-effect": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.0.0.tgz", - "integrity": "sha512-6Tpkq+R6LOlmQb1R5NNETLG0B4YP0wc+klfXafpUCj6JGyaUc8il7/kUZ7m59rGbXGczE9Bs+iz2qloqsZBduQ==", - "dependencies": { - "@babel/runtime": "^7.13.10" - }, - "peerDependencies": { - "react": "^16.8 || ^17.0 || ^18.0" - } - }, "node_modules/@remix-run/router": { "version": "1.15.3", "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.15.3.tgz", @@ -3899,7 +3656,8 @@ "node_modules/@types/parse-json": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz", - "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==" + "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==", + "dev": true }, "node_modules/@types/prop-types": { "version": "15.7.12", @@ -4640,17 +4398,6 @@ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true }, - "node_modules/aria-hidden": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.2.4.tgz", - "integrity": "sha512-y+CcFFwelSXpLZk/7fMB2mUbGtX9lKycf1MWJ7CaTIERyitVlyQx6C+sxcROU2BAJ24OiZyK+8wj2i8AlBoS3A==", - "dependencies": { - "tslib": "^2.0.0" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/aria-query": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", @@ -4848,14 +4595,6 @@ "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" }, - "node_modules/attr-accept": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/attr-accept/-/attr-accept-2.2.2.tgz", - "integrity": "sha512-7prDjvt9HmqiZ0cl5CRjtS84sEyhsHP2coDkaZKRKVfCDo9s7iw7ChVmar78Gu9pC4SoR/28wFu/G5JJhTnqEg==", - "engines": { - "node": ">=4" - } - }, "node_modules/available-typed-arrays": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", @@ -4903,6 +4642,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz", "integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==", + "dev": true, "dependencies": { "@babel/runtime": "^7.12.5", "cosmiconfig": "^7.0.0", @@ -5107,10 +4847,20 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, "engines": { "node": ">=6" } }, + "node_modules/camelcase-css": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", + "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, "node_modules/caniuse-lite": { "version": "1.0.30001607", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001607.tgz", @@ -5229,10 +4979,10 @@ } }, "node_modules/clsx": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.0.tgz", - "integrity": "sha512-m3iNNWpd9rl3jvvcBnu70ylMdrXt8Vlq4HYadnU5fwcOtvkSQWPmj7amUcDT2qYI7risszBjI5AUIUox9D16pg==", - "dev": true, + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "license": "MIT", "engines": { "node": ">=6" } @@ -5286,12 +5036,6 @@ "integrity": "sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==", "dev": true }, - "node_modules/convert-source-map": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", - "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", - "peer": true - }, "node_modules/core-js-compat": { "version": "3.36.1", "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.36.1.tgz", @@ -5309,6 +5053,7 @@ "version": "7.1.0", "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", + "dev": true, "dependencies": { "@types/parse-json": "^4.0.0", "import-fresh": "^3.2.1", @@ -5324,6 +5069,7 @@ "version": "1.10.2", "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "dev": true, "engines": { "node": ">= 6" } @@ -5348,6 +5094,18 @@ "integrity": "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==", "dev": true }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "dev": true, + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/cssstyle": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-4.0.1.tgz", @@ -5779,6 +5537,7 @@ "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, "dependencies": { "is-arrayish": "^0.2.1" } @@ -5992,6 +5751,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, "engines": { "node": ">=10" }, @@ -6606,17 +6366,6 @@ "node": "^10.12.0 || >=12.0.0" } }, - "node_modules/file-selector": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/file-selector/-/file-selector-0.6.0.tgz", - "integrity": "sha512-QlZ5yJC0VxHxQQsQhXvBaC7VRJ2uaxTf+Tfpu4Z/OcVQJVpZO+DGU0rkoVW5ce2SccxugvpBJoMvUs59iILYdw==", - "dependencies": { - "tslib": "^2.4.0" - }, - "engines": { - "node": ">= 12" - } - }, "node_modules/fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", @@ -6629,12 +6378,6 @@ "node": ">=8" } }, - "node_modules/find-root": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", - "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==", - "peer": true - }, "node_modules/find-up": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", @@ -6758,6 +6501,7 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -7035,6 +6779,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, "dependencies": { "function-bind": "^1.1.2" }, @@ -7042,15 +6787,6 @@ "node": ">= 0.4" } }, - "node_modules/hoist-non-react-statics": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", - "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", - "peer": true, - "dependencies": { - "react-is": "^16.7.0" - } - }, "node_modules/html-encoding-sniffer": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-4.0.0.tgz", @@ -7150,6 +6886,7 @@ "version": "3.3.0", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" @@ -7243,7 +6980,8 @@ "node_modules/is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==" + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true }, "node_modules/is-async-function": { "version": "2.0.0", @@ -7316,6 +7054,7 @@ "version": "2.13.1", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", + "dev": true, "dependencies": { "hasown": "^2.0.0" }, @@ -7934,7 +7673,8 @@ "node_modules/json-parse-even-better-errors": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true }, "node_modules/json-schema-traverse": { "version": "0.4.1", @@ -8053,7 +7793,8 @@ "node_modules/lines-and-columns": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true }, "node_modules/local-pkg": { "version": "0.5.0", @@ -8621,6 +8362,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, "dependencies": { "callsites": "^3.0.0" }, @@ -8632,6 +8374,7 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, "dependencies": { "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", @@ -8686,12 +8429,14 @@ "node_modules/path-parse": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true }, "node_modules/path-type": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, "engines": { "node": ">=8" } @@ -8714,7 +8459,8 @@ "node_modules/picocolors": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true }, "node_modules/picomatch": { "version": "2.3.1", @@ -8776,6 +8522,108 @@ "node": "^10 || ^12 || >=14" } }, + "node_modules/postcss-js": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz", + "integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==", + "dev": true, + "dependencies": { + "camelcase-css": "^2.0.1" + }, + "engines": { + "node": "^12 || ^14 || >= 16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": "^8.4.21" + } + }, + "node_modules/postcss-mixins": { + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/postcss-mixins/-/postcss-mixins-9.0.4.tgz", + "integrity": "sha512-XVq5jwQJDRu5M1XGkdpgASqLk37OqkH4JCFDXl/Dn7janOJjCTEKL+36cnRVy7bMtoBzALfO7bV7nTIsFnUWLA==", + "dev": true, + "dependencies": { + "fast-glob": "^3.2.11", + "postcss-js": "^4.0.0", + "postcss-simple-vars": "^7.0.0", + "sugarss": "^4.0.1" + }, + "engines": { + "node": ">=14.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": "^8.2.14" + } + }, + "node_modules/postcss-nested": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.0.1.tgz", + "integrity": "sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ==", + "dev": true, + "dependencies": { + "postcss-selector-parser": "^6.0.11" + }, + "engines": { + "node": ">=12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": "^8.2.14" + } + }, + "node_modules/postcss-preset-mantine": { + "version": "1.14.4", + "resolved": "https://registry.npmjs.org/postcss-preset-mantine/-/postcss-preset-mantine-1.14.4.tgz", + "integrity": "sha512-T1K3MVhU1hA9mJWfqoGvMcK5WKcHpVi4JUX6AYTbESvp78WneB/KFONUi+eXDG9Lpw62W/KNxEYl1ic3Dpm88w==", + "dev": true, + "dependencies": { + "postcss-mixins": "^9.0.4", + "postcss-nested": "^6.0.1" + }, + "peerDependencies": { + "postcss": ">=8.0.0" + } + }, + "node_modules/postcss-selector-parser": { + "version": "6.0.16", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.16.tgz", + "integrity": "sha512-A0RVJrX+IUkVZbW3ClroRWurercFhieevHB38sr2+l9eUClMqome3LmEmnhlNy+5Mr2EYN6B2Kaw9wYdd+VHiw==", + "dev": true, + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-simple-vars": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/postcss-simple-vars/-/postcss-simple-vars-7.0.1.tgz", + "integrity": "sha512-5GLLXaS8qmzHMOjVxqkk1TZPf1jMqesiI7qLhnlyERalG0sMbHIbJqrcnrpmZdKCLglHnRHoEBB61RtGTsj++A==", + "dev": true, + "engines": { + "node": ">=14.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": "^8.2.1" + } + }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -8967,13 +8815,11 @@ "react": "^18.2.0" } }, - "node_modules/react-dropzone": { - "version": "14.2.3", - "resolved": "https://registry.npmjs.org/react-dropzone/-/react-dropzone-14.2.3.tgz", - "integrity": "sha512-O3om8I+PkFKbxCukfIR3QAGftYXDZfOE2N1mr/7qebQJHs7U+/RSL/9xomJNpRg9kM5h9soQSdf0Gc7OHF5Fug==", + "node_modules/react-dropzone-esm": { + "version": "15.0.1", + "resolved": "https://registry.npmjs.org/react-dropzone-esm/-/react-dropzone-esm-15.0.1.tgz", + "integrity": "sha512-RdeGpqwHnoV/IlDFpQji7t7pTtlC2O1i/Br0LWkRZ9hYtLyce814S71h5NolnCZXsIN5wrZId6+8eQj2EBnEzg==", "dependencies": { - "attr-accept": "^2.2.2", - "file-selector": "^0.6.0", "prop-types": "^15.8.1" }, "engines": { @@ -8988,6 +8834,18 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, + "node_modules/react-number-format": { + "version": "5.3.4", + "resolved": "https://registry.npmjs.org/react-number-format/-/react-number-format-5.3.4.tgz", + "integrity": "sha512-2hHN5mbLuCDUx19bv0Q8wet67QqYK6xmtLQeY5xx+h7UXiMmRtaCwqko4mMPoKXLc6xAzwRrutg8XbTRlsfjRg==", + "dependencies": { + "prop-types": "^15.7.2" + }, + "peerDependencies": { + "react": "^0.14 || ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^0.14 || ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0" + } + }, "node_modules/react-query": { "version": "3.39.3", "resolved": "https://registry.npmjs.org/react-query/-/react-query-3.39.3.tgz", @@ -9112,22 +8970,6 @@ "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" } }, - "node_modules/react-smooth/node_modules/react-transition-group": { - "version": "4.4.5", - "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz", - "integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.5.5", - "dom-helpers": "^5.0.1", - "loose-envify": "^1.4.0", - "prop-types": "^15.6.2" - }, - "peerDependencies": { - "react": ">=16.6.0", - "react-dom": ">=16.6.0" - } - }, "node_modules/react-style-singleton": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.1.tgz", @@ -9164,11 +9006,11 @@ } }, "node_modules/react-textarea-autosize": { - "version": "8.3.4", - "resolved": "https://registry.npmjs.org/react-textarea-autosize/-/react-textarea-autosize-8.3.4.tgz", - "integrity": "sha512-CdtmP8Dc19xL8/R6sWvtknD/eCXkQr30dtvC4VmGInhRsfF8X/ihXCq6+9l9qbxmKRiq407/7z5fxE7cVWQNgQ==", + "version": "8.5.3", + "resolved": "https://registry.npmjs.org/react-textarea-autosize/-/react-textarea-autosize-8.5.3.tgz", + "integrity": "sha512-XT1024o2pqCuZSuBt9FwHlaDeNtVrtCXu0Rnz88t1jUGheCLa3PhjE1GH8Ctm2axEtvdCl5SUHYschyQ0L5QHQ==", "dependencies": { - "@babel/runtime": "^7.10.2", + "@babel/runtime": "^7.20.13", "use-composed-ref": "^1.3.0", "use-latest": "^1.2.1" }, @@ -9180,9 +9022,9 @@ } }, "node_modules/react-transition-group": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.2.tgz", - "integrity": "sha512-/RNYfRAMlZwDSr6z4zNKV6xu53/e2BuaBbGhbyYIXTrmgu/bGHzmqOs7mJSJBHy9Ud+ApHx3QjrkKSp1pxvlFg==", + "version": "4.4.5", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz", + "integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==", "dependencies": { "@babel/runtime": "^7.5.5", "dom-helpers": "^5.0.1", @@ -9375,6 +9217,7 @@ "version": "1.22.8", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "dev": true, "dependencies": { "is-core-module": "^2.13.0", "path-parse": "^1.0.7", @@ -9391,6 +9234,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, "engines": { "node": ">=4" } @@ -9701,15 +9545,6 @@ "node": ">=10.0.0" } }, - "node_modules/source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", - "peer": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/source-map-js": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", @@ -9905,11 +9740,21 @@ "integrity": "sha512-WriZw1luRMlmV3LGJaR6QOJjWwgLUTf89OwT2lUOyjX2dJGBwgmIkbcz+7WFZjrZM635JOIR517++e/67CP9dQ==", "dev": true }, - "node_modules/stylis": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz", - "integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==", - "peer": true + "node_modules/sugarss": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/sugarss/-/sugarss-4.0.1.tgz", + "integrity": "sha512-WCjS5NfuVJjkQzK10s8WOBY+hhDxxNt/N6ZaGwxFZ+wN3/lKKFSaaKUNecULcTTvE4urLcKaZFQD8vO0mOZujw==", + "dev": true, + "engines": { + "node": ">=12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": "^8.3.3" + } }, "node_modules/supports-color": { "version": "7.2.0", @@ -9927,6 +9772,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, "engines": { "node": ">= 0.4" }, @@ -9999,6 +9845,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", + "dev": true, "engines": { "node": ">=4" } @@ -10432,6 +10279,12 @@ } } }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true + }, "node_modules/v8-to-istanbul": { "version": "9.2.0", "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.2.0.tgz", diff --git a/frontend/package.json b/frontend/package.json index eadb26496..971065e4d 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -13,12 +13,12 @@ }, "private": true, "dependencies": { - "@mantine/core": "^6.0.21", - "@mantine/dropzone": "^6.0.21", - "@mantine/form": "^6.0.21", - "@mantine/hooks": "^6.0.21", - "@mantine/modals": "^6.0.21", - "@mantine/notifications": "^6.0.21", + "@mantine/core": "^7.10.1", + "@mantine/dropzone": "^7.10.1", + "@mantine/form": "^7.10.1", + "@mantine/hooks": "^7.10.1", + "@mantine/modals": "^7.10.1", + "@mantine/notifications": "^7.10.1", "axios": "^1.6.8", "react": "^18.2.0", "react-dom": "^18.2.0", @@ -53,6 +53,8 @@ "husky": "^9.0.11", "jsdom": "^24.0.0", "lodash": "^4.17.21", + "postcss-preset-mantine": "^1.14.4", + "postcss-simple-vars": "^7.0.1", "prettier": "^3.2.5", "prettier-plugin-organize-imports": "^3.2.4", "pretty-quick": "^4.0.0", diff --git a/frontend/postcss.config.cjs b/frontend/postcss.config.cjs new file mode 100644 index 000000000..e817f567b --- /dev/null +++ b/frontend/postcss.config.cjs @@ -0,0 +1,14 @@ +module.exports = { + plugins: { + "postcss-preset-mantine": {}, + "postcss-simple-vars": { + variables: { + "mantine-breakpoint-xs": "36em", + "mantine-breakpoint-sm": "48em", + "mantine-breakpoint-md": "62em", + "mantine-breakpoint-lg": "75em", + "mantine-breakpoint-xl": "88em", + }, + }, + }, +}; diff --git a/frontend/src/App/Header.module.scss b/frontend/src/App/Header.module.scss new file mode 100644 index 000000000..85b3661a9 --- /dev/null +++ b/frontend/src/App/Header.module.scss @@ -0,0 +1,9 @@ +.header { + @include light { + color: var(--mantine-color-gray-0); + } + + @include dark { + color: var(--mantine-color-dark-0); + } +} diff --git a/frontend/src/App/Header.tsx b/frontend/src/App/Header.tsx index c15071045..6bb47f5b1 100644 --- a/frontend/src/App/Header.tsx +++ b/frontend/src/App/Header.tsx @@ -1,6 +1,5 @@ import { useSystem, useSystemSettings } from "@/apis/hooks"; import { Action, Search } from "@/components"; -import { Layout } from "@/constants"; import { useNavbar } from "@/contexts/Navbar"; import { useIsOnline } from "@/contexts/Online"; import { Environment, useGotoHomepage } from "@/utilities"; @@ -12,27 +11,16 @@ import { import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { Anchor, + AppShell, Avatar, Badge, Burger, Divider, Group, - Header, - MediaQuery, Menu, - createStyles, } from "@mantine/core"; import { FunctionComponent } from "react"; - -const useStyles = createStyles((theme) => { - const headerBackgroundColor = - theme.colorScheme === "light" ? theme.colors.gray[0] : theme.colors.dark[4]; - return { - header: { - backgroundColor: headerBackgroundColor, - }, - }; -}); +import styles from "./Header.module.scss"; const AppHeader: FunctionComponent = () => { const { data: settings } = useSystemSettings(); @@ -47,39 +35,28 @@ const AppHeader: FunctionComponent = () => { const goHome = useGotoHomepage(); - const { classes } = useStyles(); - return ( -
- - - - - - - - - show(!showed)} - size="sm" - > - + + + + + + + show(!showed)} + size="sm" + hiddenFrom="sm" + > Bazarr - + @@ -95,13 +72,13 @@ const AppHeader: FunctionComponent = () => { } + leftSection={} onClick={() => restart()} > Restart } + leftSection={} onClick={() => shutdown()} > Shutdown @@ -114,7 +91,7 @@ const AppHeader: FunctionComponent = () => { -
+ ); }; diff --git a/frontend/src/App/Navbar.module.scss b/frontend/src/App/Navbar.module.scss new file mode 100644 index 000000000..ddb444e4d --- /dev/null +++ b/frontend/src/App/Navbar.module.scss @@ -0,0 +1,56 @@ +.anchor { + border-color: var(--mantine-color-gray-5); + text-decoration: none; + + @include dark { + border-color: var(--mantine-color-dark-5); + } + + &.active { + border-left: 2px solid $color-brand-4; + background-color: var(--mantine-color-gray-1); + + @include dark { + border-left: 2px solid $color-brand-8; + background-color: var(--mantine-color-dark-8); + } + } + + &.hover { + background-color: var(--mantine-color-gray-0); + + @include dark { + background-color: var(--mantine-color-dark-7); + } + } +} + +.badge { + margin-left: auto; + text-decoration: none; + box-shadow: var(--mantine-shadow-xs); +} + +.icon { + width: 1.4rem; + margin-right: var(--mantine-spacing-xs); +} + +.nav { + background-color: var(--mantine-color-gray-2); + + @include dark { + background-color: var(--mantine-color-dark-8); + } +} + +.text { + display: inline-flex; + align-items: center; + width: 100%; + color: var(--mantine-color-gray-8); + + @include dark { + color: var(--mantine-color-gray-5); + } +} diff --git a/frontend/src/App/Navbar.tsx b/frontend/src/App/Navbar.tsx index c626dc257..8254f2fc0 100644 --- a/frontend/src/App/Navbar.tsx +++ b/frontend/src/App/Navbar.tsx @@ -1,5 +1,4 @@ import { Action } from "@/components"; -import { Layout } from "@/constants"; import { useNavbar } from "@/contexts/Navbar"; import { useRouteItems } from "@/Router"; import { CustomRouteObject, Route } from "@/Router/type"; @@ -14,19 +13,19 @@ import { import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { Anchor, + AppShell, Badge, Collapse, - createStyles, Divider, Group, - Navbar as MantineNavbar, Stack, Text, + useComputedColorScheme, useMantineColorScheme, } from "@mantine/core"; import { useHover } from "@mantine/hooks"; import clsx from "clsx"; -import { +import React, { createContext, FunctionComponent, useContext, @@ -35,6 +34,7 @@ import { useState, } from "react"; import { matchPath, NavLink, RouteObject, useLocation } from "react-router-dom"; +import styles from "./Navbar.module.scss"; const Selection = createContext<{ selection: string | null; @@ -97,11 +97,12 @@ function useIsActive(parent: string, route: RouteObject) { } const AppNavbar: FunctionComponent = () => { - const { showed } = useNavbar(); const [selection, select] = useState(null); - const { colorScheme, toggleColorScheme } = useMantineColorScheme(); - const dark = colorScheme === "dark"; + const { toggleColorScheme } = useMantineColorScheme(); + const computedColorScheme = useComputedColorScheme("light"); + + const dark = computedColorScheme === "dark"; const routes = useRouteItems(); @@ -111,23 +112,10 @@ const AppNavbar: FunctionComponent = () => { }, [pathname]); return ( - + ); }; @@ -186,7 +174,7 @@ const RouteItem: FunctionComponent<{ if (children !== undefined) { const elements = ( - + {children.map((child, idx) => ( + { - const borderColor = - theme.colorScheme === "light" ? theme.colors.gray[5] : theme.colors.dark[4]; - - const activeBorderColor = - theme.colorScheme === "light" - ? theme.colors.brand[4] - : theme.colors.brand[8]; - - const activeBackgroundColor = - theme.colorScheme === "light" ? theme.colors.gray[1] : theme.colors.dark[8]; - - const hoverBackgroundColor = - theme.colorScheme === "light" ? theme.colors.gray[0] : theme.colors.dark[7]; - - const textColor = - theme.colorScheme === "light" ? theme.colors.gray[8] : theme.colors.gray[5]; - - return { - text: { - display: "inline-flex", - alignItems: "center", - width: "100%", - color: textColor, - }, - anchor: { - textDecoration: "none", - borderLeft: `2px solid ${borderColor}`, - }, - active: { - backgroundColor: activeBackgroundColor, - borderLeft: `2px solid ${activeBorderColor}`, - boxShadow: theme.shadows.xs, - }, - hover: { - backgroundColor: hoverBackgroundColor, - }, - icon: { width: "1.4rem", marginRight: theme.spacing.xs }, - badge: { - marginLeft: "auto", - textDecoration: "none", - boxShadow: theme.shadows.xs, - color: textColor, - }, - }; -}); - interface NavbarItemProps { name: string; link: string; @@ -308,8 +249,6 @@ const NavbarItem: FunctionComponent = ({ onClick, primary = false, }) => { - const { classes } = useStyles(); - const { show } = useNavbar(); const { ref, hovered } = useHover(); @@ -335,9 +274,9 @@ const NavbarItem: FunctionComponent = ({ }} className={({ isActive }) => clsx( - clsx(classes.anchor, { - [classes.active]: isActive, - [classes.hover]: hovered, + clsx(styles.anchor, { + [styles.active]: isActive, + [styles.hover]: hovered, }), ) } @@ -347,18 +286,19 @@ const NavbarItem: FunctionComponent = ({ inline p="xs" size="sm" - weight={primary ? "bold" : "normal"} - className={classes.text} + fw={primary ? "bold" : "normal"} + className={styles.text} + span > {icon && ( )} {name} - {shouldHideBadge === false && ( - + {!shouldHideBadge && ( + {badge} )} diff --git a/frontend/src/App/ThemeLoader.tsx b/frontend/src/App/ThemeLoader.tsx new file mode 100644 index 000000000..2bc7e4005 --- /dev/null +++ b/frontend/src/App/ThemeLoader.tsx @@ -0,0 +1,39 @@ +import { useCallback, useEffect, useState } from "react"; +import { MantineColorScheme, useMantineColorScheme } from "@mantine/core"; +import { useSystemSettings } from "@/apis/hooks"; + +const ThemeProvider = () => { + const [localScheme, setLocalScheme] = useState( + null, + ); + const { setColorScheme } = useMantineColorScheme(); + + const settings = useSystemSettings(); + + const settingsColorScheme = settings.data?.general + .theme as MantineColorScheme; + + const setScheme = useCallback( + (colorScheme: MantineColorScheme) => { + setColorScheme(colorScheme); + }, + [setColorScheme], + ); + + useEffect(() => { + if (!settingsColorScheme) { + return; + } + + if (localScheme === settingsColorScheme) { + return; + } + + setScheme(settingsColorScheme); + setLocalScheme(settingsColorScheme); + }, [settingsColorScheme, setScheme, localScheme]); + + return <>; +}; + +export default ThemeProvider; diff --git a/frontend/src/App/ThemeProvider.tsx b/frontend/src/App/ThemeProvider.tsx new file mode 100644 index 000000000..d3a39cdb0 --- /dev/null +++ b/frontend/src/App/ThemeProvider.tsx @@ -0,0 +1,61 @@ +import { + ActionIcon, + AppShell, + Badge, + Button, + createTheme, + MantineProvider, +} from "@mantine/core"; +import { FunctionComponent, PropsWithChildren } from "react"; +import ThemeLoader from "@/App/ThemeLoader"; +import "@mantine/core/styles.layer.css"; +import "@mantine/notifications/styles.layer.css"; +import styleVars from "@/assets/_variables.module.scss"; +import buttonClasses from "@/assets/button.module.scss"; +import actionIconClasses from "@/assets/action_icon.module.scss"; +import appShellClasses from "@/assets/app_shell.module.scss"; +import badgeClasses from "@/assets/badge.module.scss"; + +const themeProvider = createTheme({ + fontFamily: "Roboto, open sans, Helvetica Neue, Helvetica, Arial, sans-serif", + colors: { + brand: [ + styleVars.colorBrand0, + styleVars.colorBrand1, + styleVars.colorBrand2, + styleVars.colorBrand3, + styleVars.colorBrand4, + styleVars.colorBrand5, + styleVars.colorBrand6, + styleVars.colorBrand7, + styleVars.colorBrand8, + styleVars.colorBrand9, + ], + }, + primaryColor: "brand", + components: { + ActionIcon: ActionIcon.extend({ + classNames: actionIconClasses, + }), + AppShell: AppShell.extend({ + classNames: appShellClasses, + }), + Badge: Badge.extend({ + classNames: badgeClasses, + }), + Button: Button.extend({ + classNames: buttonClasses, + }), + }, +}); + +const ThemeProvider: FunctionComponent = ({ children }) => { + return ( + + + {children} + + ); +}; + +export default ThemeProvider; diff --git a/frontend/src/App/index.tsx b/frontend/src/App/index.tsx index 4e09a97da..1b27734f4 100644 --- a/frontend/src/App/index.tsx +++ b/frontend/src/App/index.tsx @@ -1,7 +1,6 @@ import AppNavbar from "@/App/Navbar"; import { RouterNames } from "@/Router/RouterNames"; import ErrorBoundary from "@/components/ErrorBoundary"; -import { Layout } from "@/constants"; import NavbarProvider from "@/contexts/Navbar"; import OnlineProvider from "@/contexts/Online"; import { notification } from "@/modules/task"; @@ -13,6 +12,7 @@ import { showNotification } from "@mantine/notifications"; import { FunctionComponent, useEffect, useState } from "react"; import { Outlet, useNavigate } from "react-router-dom"; import AppHeader from "./Header"; +import styleVars from "@/assets/_variables.module.scss"; const App: FunctionComponent = () => { const navigate = useNavigate(); @@ -55,13 +55,19 @@ const App: FunctionComponent = () => { } - navbar={} + navbar={{ + width: styleVars.navBarWidth, + breakpoint: "sm", + collapsed: { mobile: !navbar }, + }} + header={{ height: { base: styleVars.headerHeight } }} padding={0} - fixed > - + + + + + diff --git a/frontend/src/App/theme.tsx b/frontend/src/App/theme.tsx deleted file mode 100644 index 947b4f7a8..000000000 --- a/frontend/src/App/theme.tsx +++ /dev/null @@ -1,87 +0,0 @@ -import { useSystemSettings } from "@/apis/hooks"; -import { - ColorScheme, - ColorSchemeProvider, - createEmotionCache, - MantineProvider, - MantineThemeOverride, -} from "@mantine/core"; -import { useColorScheme } from "@mantine/hooks"; -import { - FunctionComponent, - PropsWithChildren, - useCallback, - useEffect, - useState, -} from "react"; - -const theme: MantineThemeOverride = { - fontFamily: "Roboto, open sans, Helvetica Neue, Helvetica, Arial, sans-serif", - colors: { - brand: [ - "#F8F0FC", - "#F3D9FA", - "#EEBEFA", - "#E599F7", - "#DA77F2", - "#CC5DE8", - "#BE4BDB", - "#AE3EC9", - "#9C36B5", - "#862E9C", - ], - }, - primaryColor: "brand", -}; - -function useAutoColorScheme() { - const settings = useSystemSettings(); - const settingsColorScheme = settings.data?.general.theme; - - let preferredColorScheme: ColorScheme = useColorScheme(); - switch (settingsColorScheme) { - case "light": - preferredColorScheme = "light" as ColorScheme; - break; - case "dark": - preferredColorScheme = "dark" as ColorScheme; - break; - } - - const [colorScheme, setColorScheme] = useState(preferredColorScheme); - - // automatically switch dark/light theme - useEffect(() => { - setColorScheme(preferredColorScheme); - }, [preferredColorScheme]); - - const toggleColorScheme = useCallback((value?: ColorScheme) => { - setColorScheme((scheme) => value || (scheme === "dark" ? "light" : "dark")); - }, []); - - return { colorScheme, setColorScheme, toggleColorScheme }; -} - -const emotionCache = createEmotionCache({ key: "bazarr" }); - -const ThemeProvider: FunctionComponent = ({ children }) => { - const { colorScheme, toggleColorScheme } = useAutoColorScheme(); - - return ( - - - {children} - - - ); -}; - -export default ThemeProvider; diff --git a/frontend/src/Router/index.tsx b/frontend/src/Router/index.tsx index 335cf2d75..efed2edb2 100644 --- a/frontend/src/Router/index.tsx +++ b/frontend/src/Router/index.tsx @@ -53,7 +53,9 @@ import Redirector from "./Redirector"; import { RouterNames } from "./RouterNames"; import { CustomRouteObject } from "./type"; -const HistoryStats = lazy(() => import("@/pages/History/Statistics")); +const HistoryStats = lazy( + () => import("@/pages/History/Statistics/HistoryStats"), +); const SystemStatusView = lazy(() => import("@/pages/System/Status")); function useRoutes(): CustomRouteObject[] { diff --git a/frontend/src/assets/_bazarr.scss b/frontend/src/assets/_bazarr.scss new file mode 100644 index 000000000..6c23aac1a --- /dev/null +++ b/frontend/src/assets/_bazarr.scss @@ -0,0 +1,40 @@ +$color-brand-0: #f8f0fc; +$color-brand-1: #f3d9fa; +$color-brand-2: #eebefa; +$color-brand-3: #e599f7; +$color-brand-4: #da77f2; +$color-brand-5: #cc5de8; +$color-brand-6: #be4bdb; +$color-brand-7: #ae3ec9; +$color-brand-8: #9c36b5; +$color-brand-9: #862e9c; + +$header-height: 64px; + +:global { + .table-long-break { + overflow-wrap: anywhere; + } + + .table-primary { + display: inline-block; + + font-size: var(--mantine-font-size-sm); + + @include smaller-than($mantine-breakpoint-sm) { + min-width: 12rem; + } + } + + .table-no-wrap { + white-space: nowrap; + } + + .table-select { + display: inline-block; + + @include smaller-than($mantine-breakpoint-sm) { + min-width: 10rem; + } + } +} diff --git a/frontend/src/assets/_mantine.scss b/frontend/src/assets/_mantine.scss new file mode 100644 index 000000000..93412c636 --- /dev/null +++ b/frontend/src/assets/_mantine.scss @@ -0,0 +1,61 @@ +@use "sass:math"; + +$mantine-breakpoint-xs: "36em"; +$mantine-breakpoint-sm: "48em"; +$mantine-breakpoint-md: "62em"; +$mantine-breakpoint-lg: "75em"; +$mantine-breakpoint-xl: "88em"; + +@function rem($value) { + @return #{math.div(math.div($value, $value * 0 + 1), 16)}rem; +} + +@mixin light { + [data-mantine-color-scheme="light"] & { + @content; + } +} + +@mixin dark { + [data-mantine-color-scheme="dark"] & { + @content; + } +} + +@mixin hover { + @media (hover: hover) { + &:hover { + @content; + } + } + + @media (hover: none) { + &:active { + @content; + } + } +} + +@mixin smaller-than($breakpoint) { + @media (max-width: $breakpoint) { + @content; + } +} + +@mixin larger-than($breakpoint) { + @media (min-width: $breakpoint) { + @content; + } +} + +@mixin rtl { + [dir="rtl"] & { + @content; + } +} + +@mixin ltr { + [dir="ltr"] & { + @content; + } +} diff --git a/frontend/src/assets/_variables.module.scss b/frontend/src/assets/_variables.module.scss new file mode 100644 index 000000000..262d285b2 --- /dev/null +++ b/frontend/src/assets/_variables.module.scss @@ -0,0 +1,18 @@ +$navbar-width: 200; + +:export { + colorBrand0: $color-brand-0; + colorBrand1: $color-brand-1; + colorBrand2: $color-brand-2; + colorBrand3: $color-brand-3; + colorBrand4: $color-brand-4; + colorBrand5: $color-brand-5; + colorBrand6: $color-brand-6; + colorBrand7: $color-brand-7; + colorBrand8: $color-brand-8; + colorBrand9: $color-brand-9; + + headerHeight: $header-height; + + navBarWidth: $navbar-width; +} diff --git a/frontend/src/assets/action_icon.module.scss b/frontend/src/assets/action_icon.module.scss new file mode 100644 index 000000000..c4bf2eefa --- /dev/null +++ b/frontend/src/assets/action_icon.module.scss @@ -0,0 +1,14 @@ +@layer mantine { + .root { + &[data-variant="light"] { + color: var(--mantine-color-dark-0); + } + + @include light { + &[data-variant="light"] { + background-color: var(--mantine-color-gray-1); + color: var(--mantine-color-dark-2); + } + } + } +} diff --git a/frontend/src/assets/app_shell.module.scss b/frontend/src/assets/app_shell.module.scss new file mode 100644 index 000000000..b027c771a --- /dev/null +++ b/frontend/src/assets/app_shell.module.scss @@ -0,0 +1,5 @@ +.main { + @include dark { + background-color: rgb(26, 27, 30); + } +} diff --git a/frontend/src/assets/badge.module.scss b/frontend/src/assets/badge.module.scss new file mode 100644 index 000000000..830da2927 --- /dev/null +++ b/frontend/src/assets/badge.module.scss @@ -0,0 +1,8 @@ +.root { + background-color: var(--mantine-color-grape-light); + + @include light { + color: var(--mantine-color-dark-filled); + background-color: var(--mantine-color-grape-light); + } +} diff --git a/frontend/src/assets/button.module.scss b/frontend/src/assets/button.module.scss new file mode 100644 index 000000000..4ef306883 --- /dev/null +++ b/frontend/src/assets/button.module.scss @@ -0,0 +1,12 @@ +@layer mantine { + .root { + @include dark { + color: var(--mantine-color-dark-0); + } + + &[data-variant="danger"] { + background-color: var(--mantine-color-red-9); + color: var(--mantine-color-red-0); + } + } +} diff --git a/frontend/src/components/Search.module.scss b/frontend/src/components/Search.module.scss new file mode 100644 index 000000000..2c42098eb --- /dev/null +++ b/frontend/src/components/Search.module.scss @@ -0,0 +1,9 @@ +.result { + @include light { + color: var(--mantine-color-dark-8); + } + + @include dark { + color: var(--mantine-color-gray-1); + } +} diff --git a/frontend/src/components/Search.tsx b/frontend/src/components/Search.tsx index bc4a9f8d3..75341e0a8 100644 --- a/frontend/src/components/Search.tsx +++ b/frontend/src/components/Search.tsx @@ -5,11 +5,12 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { Anchor, Autocomplete, - createStyles, - SelectItemProps, + ComboboxItem, + OptionsFilter, } from "@mantine/core"; -import { forwardRef, FunctionComponent, useMemo, useState } from "react"; +import { FunctionComponent, useMemo, useState } from "react"; import { Link } from "react-router-dom"; +import styles from "./Search.module.scss"; type SearchResultItem = { value: string; @@ -41,36 +42,35 @@ function useSearch(query: string) { ); } -const useStyles = createStyles((theme) => { - return { - result: { - color: - theme.colorScheme === "light" - ? theme.colors.dark[8] - : theme.colors.gray[1], - }, - }; -}); - -type ResultCompProps = SelectItemProps & SearchResultItem; - -const ResultComponent = forwardRef( - ({ link, value }, ref) => { - const styles = useStyles(); +const optionsFilter: OptionsFilter = ({ options, search }) => { + const lowercaseSearch = search.toLowerCase(); + const trimmedSearch = search.trim(); + return (options as ComboboxItem[]).filter((option) => { return ( - - {value} - + option.value.toLowerCase().includes(lowercaseSearch) || + option.value + .normalize("NFD") + .replace(/[\u0300-\u036f]/g, "") + .toLowerCase() + .includes(trimmedSearch) ); - }, -); + }); +}; + +const ResultComponent = ({ name, link }: { name: string; link: string }) => { + return ( + + {name} + + ); +}; const Search: FunctionComponent = () => { const [query, setQuery] = useState(""); @@ -79,22 +79,22 @@ const Search: FunctionComponent = () => { return ( } - itemComponent={ResultComponent} + leftSection={} + renderOption={(input) => ( + a.value === input.option.value)?.link || "/" + } + /> + )} placeholder="Search" size="sm" data={results} value={query} onChange={setQuery} onBlur={() => setQuery("")} - filter={(value, item) => - item.value.toLowerCase().includes(value.toLowerCase().trim()) || - item.value - .normalize("NFD") - .replace(/[\u0300-\u036f]/g, "") - .toLowerCase() - .includes(value.trim()) - } + filter={optionsFilter} > ); }; diff --git a/frontend/src/components/StateIcon.tsx b/frontend/src/components/StateIcon.tsx index f9683f63a..73700a679 100644 --- a/frontend/src/components/StateIcon.tsx +++ b/frontend/src/components/StateIcon.tsx @@ -31,7 +31,7 @@ const StateIcon: FunctionComponent = ({ return ; } else { return ( - + @@ -48,9 +48,9 @@ const StateIcon: FunctionComponent = ({ - - - + + + @@ -59,8 +59,8 @@ const StateIcon: FunctionComponent = ({ ))} - - + + diff --git a/frontend/src/components/SubtitleToolsMenu.tsx b/frontend/src/components/SubtitleToolsMenu.tsx index e36a1e9e1..bdadb5cb4 100644 --- a/frontend/src/components/SubtitleToolsMenu.tsx +++ b/frontend/src/components/SubtitleToolsMenu.tsx @@ -148,7 +148,7 @@ const SubtitleToolsMenu: FunctionComponent = ({ } + leftSection={} onClick={() => { if (tool.modal) { modals.openContextModal(tool.modal, { selections }); @@ -164,7 +164,7 @@ const SubtitleToolsMenu: FunctionComponent = ({ Actions } + leftSection={} onClick={() => { onAction?.("search"); }} @@ -174,7 +174,7 @@ const SubtitleToolsMenu: FunctionComponent = ({ } + leftSection={} onClick={() => { modals.openConfirmModal({ title: "The following subtitles will be deleted", diff --git a/frontend/src/components/bazarr/AudioList.tsx b/frontend/src/components/bazarr/AudioList.tsx index ac9cce743..b73f71331 100644 --- a/frontend/src/components/bazarr/AudioList.tsx +++ b/frontend/src/components/bazarr/AudioList.tsx @@ -13,7 +13,7 @@ const AudioList: FunctionComponent = ({ ...group }) => { return ( - + {audios.map((audio, idx) => ( {audio.name} diff --git a/frontend/src/components/bazarr/Language.test.tsx b/frontend/src/components/bazarr/Language.test.tsx index 9e0e0fab8..e4e3b42b8 100644 --- a/frontend/src/components/bazarr/Language.test.tsx +++ b/frontend/src/components/bazarr/Language.test.tsx @@ -1,4 +1,4 @@ -import { rawRender, screen } from "@/tests"; +import { render, screen } from "@/tests"; import { describe, it } from "vitest"; import { Language } from "."; @@ -9,13 +9,13 @@ describe("Language text", () => { }; it("should show short text", () => { - rawRender(); + render(); expect(screen.getByText(testLanguage.code2)).toBeDefined(); }); it("should show long text", () => { - rawRender(); + render(); expect(screen.getByText(testLanguage.name)).toBeDefined(); }); @@ -23,7 +23,7 @@ describe("Language text", () => { const testLanguageWithHi: Language.Info = { ...testLanguage, hi: true }; it("should show short text with HI", () => { - rawRender(); + render(); const expectedText = `${testLanguageWithHi.code2}:HI`; @@ -31,7 +31,7 @@ describe("Language text", () => { }); it("should show long text with HI", () => { - rawRender(); + render(); const expectedText = `${testLanguageWithHi.name} HI`; @@ -44,7 +44,7 @@ describe("Language text", () => { }; it("should show short text with Forced", () => { - rawRender(); + render(); const expectedText = `${testLanguageWithHi.code2}:Forced`; @@ -52,9 +52,7 @@ describe("Language text", () => { }); it("should show long text with Forced", () => { - rawRender( - , - ); + render(); const expectedText = `${testLanguageWithHi.name} Forced`; @@ -75,7 +73,7 @@ describe("Language list", () => { ]; it("should show all languages", () => { - rawRender(); + render(); elements.forEach((value) => { expect(screen.getByText(value.name)).toBeDefined(); diff --git a/frontend/src/components/bazarr/Language.tsx b/frontend/src/components/bazarr/Language.tsx index e5627c82e..ba1a884e6 100644 --- a/frontend/src/components/bazarr/Language.tsx +++ b/frontend/src/components/bazarr/Language.tsx @@ -49,7 +49,7 @@ type LanguageListProps = { const LanguageList: FunctionComponent = ({ value }) => { return ( - + {value.map((v) => ( {v.name} ))} diff --git a/frontend/src/components/forms/FrameRateForm.tsx b/frontend/src/components/forms/FrameRateForm.tsx index 7e7eca24c..aa1723183 100644 --- a/frontend/src/components/forms/FrameRateForm.tsx +++ b/frontend/src/components/forms/FrameRateForm.tsx @@ -55,15 +55,17 @@ const FrameRateForm: FunctionComponent = ({ selections, onSubmit }) => { })} > - + diff --git a/frontend/src/components/forms/ItemEditForm.tsx b/frontend/src/components/forms/ItemEditForm.tsx index 9f3856d54..64f87fb36 100644 --- a/frontend/src/components/forms/ItemEditForm.tsx +++ b/frontend/src/components/forms/ItemEditForm.tsx @@ -80,7 +80,7 @@ const ItemEditForm: FunctionComponent = ({ label="Languages Profile" > - + diff --git a/frontend/src/components/forms/ProfileEditForm.module.scss b/frontend/src/components/forms/ProfileEditForm.module.scss new file mode 100644 index 000000000..d98b850ff --- /dev/null +++ b/frontend/src/components/forms/ProfileEditForm.module.scss @@ -0,0 +1,5 @@ +.content { + @include smaller-than($mantine-breakpoint-md) { + padding: 0; + } +} diff --git a/frontend/src/components/forms/ProfileEditForm.tsx b/frontend/src/components/forms/ProfileEditForm.tsx index eecacd73e..93f09d8b8 100644 --- a/frontend/src/components/forms/ProfileEditForm.tsx +++ b/frontend/src/components/forms/ProfileEditForm.tsx @@ -1,6 +1,5 @@ import { Action, Selector, SelectorOption, SimpleTable } from "@/components"; import { useModals, withModal } from "@/modules/modals"; -import { useTableStyles } from "@/styles"; import { useArrayAction, useSelectorOptions } from "@/utilities"; import { LOG } from "@/utilities/console"; import FormUtils from "@/utilities/form"; @@ -19,6 +18,7 @@ import { useForm } from "@mantine/form"; import { FunctionComponent, useCallback, useMemo } from "react"; import { Column } from "react-table"; import ChipInput from "../inputs/ChipInput"; +import styles from "./ProfileEditForm.module.scss"; export const anyCutoff = 65535; @@ -162,12 +162,10 @@ const ProfileEditForm: FunctionComponent = ({ [code], ); - const { classes } = useTableStyles(); - return ( { if (value) { @@ -260,13 +258,7 @@ const ProfileEditForm: FunctionComponent = ({ multiple chevronPosition="right" defaultValue={["Languages"]} - styles={(theme) => ({ - content: { - [theme.fn.smallerThan("md")]: { - padding: 0, - }, - }, - })} + className={styles.content} > @@ -275,7 +267,7 @@ const ProfileEditForm: FunctionComponent = ({ columns={columns} data={form.values.items} > - { - return { - wrapper: { - overflowWrap: "anywhere", - }, - }; -}); - const SeriesUploadForm: FunctionComponent = ({ series, files, onComplete, }) => { const modals = useModals(); - const { classes } = useStyles(); const episodes = useEpisodesBySeriesId(series.sonarrSeriesId); const episodeOptions = useSelectorOptions( episodes.data ?? [], @@ -225,8 +214,7 @@ const SeriesUploadForm: FunctionComponent = ({ id: "filename", accessor: "file", Cell: ({ value: { name } }) => { - const { classes } = useTableStyles(); - return {name}; + return {name}; }, }, { @@ -283,11 +271,10 @@ const SeriesUploadForm: FunctionComponent = ({ ), accessor: "language", Cell: ({ row: { original, index }, value }) => { - const { classes } = useTableStyles(); return ( { action.mutate(index, { ...original, language: item }); @@ -301,12 +288,11 @@ const SeriesUploadForm: FunctionComponent = ({ Header: "Episode", accessor: "episode", Cell: ({ value, row }) => { - const { classes } = useTableStyles(); return ( { action.mutate(row.index, { ...row.original, episode: item }); @@ -368,7 +354,7 @@ const SeriesUploadForm: FunctionComponent = ({ modals.closeSelf(); })} > - + diff --git a/frontend/src/components/forms/SyncSubtitleForm.tsx b/frontend/src/components/forms/SyncSubtitleForm.tsx index b5136fc85..c2e4ae9a5 100644 --- a/frontend/src/components/forms/SyncSubtitleForm.tsx +++ b/frontend/src/components/forms/SyncSubtitleForm.tsx @@ -14,10 +14,15 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { Alert, Button, Checkbox, Divider, Stack, Text } from "@mantine/core"; import { useForm } from "@mantine/form"; import { FunctionComponent } from "react"; -import { Selector, SelectorOption } from "../inputs"; +import { GroupedSelector, Selector } from "../inputs"; const TaskName = "Syncing Subtitle"; +interface SelectOptions { + group: string; + items: { value: string; label: string }[]; +} + function useReferencedSubtitles( mediaType: "episode" | "movie", mediaId: number, @@ -37,15 +42,21 @@ function useReferencedSubtitles( const mediaData = mediaType === "episode" ? episodeData : movieData; - const subtitles: { group: string; value: string; label: string }[] = []; + const subtitles: SelectOptions[] = []; if (!mediaData.data) { return []; } else { if (mediaData.data.audio_tracks.length > 0) { + const embeddedAudioGroup: SelectOptions = { + group: "Embedded audio tracks", + items: [], + }; + + subtitles.push(embeddedAudioGroup); + mediaData.data.audio_tracks.forEach((item) => { - subtitles.push({ - group: "Embedded audio tracks", + embeddedAudioGroup.items.push({ value: item.stream, label: `${item.name || item.language} (${item.stream})`, }); @@ -53,9 +64,15 @@ function useReferencedSubtitles( } if (mediaData.data.embedded_subtitles_tracks.length > 0) { + const embeddedSubtitlesTrackGroup: SelectOptions = { + group: "Embedded subtitles tracks", + items: [], + }; + + subtitles.push(embeddedSubtitlesTrackGroup); + mediaData.data.embedded_subtitles_tracks.forEach((item) => { - subtitles.push({ - group: "Embedded subtitles tracks", + embeddedSubtitlesTrackGroup.items.push({ value: item.stream, label: `${item.name || item.language} (${item.stream})`, }); @@ -63,10 +80,16 @@ function useReferencedSubtitles( } if (mediaData.data.external_subtitles_tracks.length > 0) { + const externalSubtitlesFilesGroup: SelectOptions = { + group: "External Subtitles files", + items: [], + }; + + subtitles.push(externalSubtitlesFilesGroup); + mediaData.data.external_subtitles_tracks.forEach((item) => { if (item) { - subtitles.push({ - group: "External Subtitles files", + externalSubtitlesFilesGroup.items.push({ value: item.path, label: item.name, }); @@ -105,7 +128,7 @@ const SyncSubtitleForm: FunctionComponent = ({ const mediaId = selections[0].id; const subtitlesPath = selections[0].path; - const subtitles: SelectorOption[] = useReferencedSubtitles( + const subtitles: SelectOptions[] = useReferencedSubtitles( mediaType, mediaId, subtitlesPath, @@ -145,14 +168,14 @@ const SyncSubtitleForm: FunctionComponent = ({ > {selections.length} subtitles selected - + > = ({ selections, onSubmit }) => { })} > - +