Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cryptography dep #1

Closed
wants to merge 15 commits into from
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
*.egg-info/
__pycache__/
70 changes: 57 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,35 +1,79 @@
# OctoPrint-EmailNotifier
OctoPrint-EmailNotifier
=======================

**UPDATE** *2023-Jun-04*: Remove references to _python2_

- Tested to work on OctoPrint `1.9.0`

**UPDATE** *2020-Sep-30*: Version 0.2.0 updated **with python3 support**

- Tested on OctoPrint `1.4.x`

---

Recieve email notifications when OctoPrint jobs are STARTED, COMPLETED, FAILED or CANCELLED.

* Forked from ericli1018/OctoPrint-EmailNotifier which is forked from anov/OctoPrint-EmailNotifier
Forked from

- `kotl/OctoPrint-EmailNotifier` which is forked from
- `ericli1018/OctoPrint-EmailNotifier` which is forked from
- `anov/OctoPrint-EmailNotifier`

![Settings tab and email screenshot](extras/emailnotifier.png)

## Installation
Installation
------------

Install via the OctoPrint [Plugin Manager](https://github.com/foosel/OctoPrint/wiki/Plugin:-Plugin-Manager) or manually using this [archive URL](https://github.com/kotl/OctoPrint-EmailNotifier/archive/master.zip):
Install via the OctoPrint [Plugin Manager](https://github.com/foosel/OctoPrint/wiki/Plugin:-Plugin-Manager) manually using this [archive URL](https://github.com/idcrook/OctoPrint-EmailNotifier/archive/main.zip):

https://github.com/kotl/OctoPrint-EmailNotifier/archive/master.zip
```
https://github.com/idcrook/OctoPrint-EmailNotifier/archive/main.zip
```

## Configuration
Configuration
-------------

Your outgoing email account password is not stored with OctoPrint's settings. It is retrieved from your system [keyring](https://pypi.python.org/pypi/keyring#what-is-python-keyring-lib). Store your password from a Python prompt on your OctoPrint system using [`yagmail.register`](https://github.com/kootenpv/yagmail#username-and-password):
Your outgoing email account password is not stored with OctoPrint's settings. It is retrieved from your system [keyring](https://pypi.python.org/pypi/keyring#what-is-python-keyring-lib). Store your password from a Python prompt on your OctoPrint system using [`yagmail.register`](https://github.com/kootenpv/yagmail#username-and-password):

$ ~/oprint/bin/python
>>> import yagmail
>>> yagmail.register("SMTP username", "SMTP password")
```
$ ~/oprint/bin/python
>>> import yagmail
>>> import keyring
>>> yagmail.register("SMTP username", "SMTP password")
```

For some accounts, your SMTP username may be your complete `[email protected]` address.

To use yagmail (and thus OctoPrint-EmailNotifier) with Gmail, you may need to [allow less secure apps to access your account](https://support.google.com/accounts/answer/6010255?hl=en).

## Acknowledgements
- Server: `smtp.gmail.com`
- Serverport: `587`
- [X] Use TLS

Troubleshooting
---------------

If on Raspberry Pi, when you try to \[Send a test email\] and you encounter this error:

```
ImportError: libxslt.so.1: cannot open shared object file: No such file or directory
```

Install the system library:

```console
$ sudo apt install libxslt-dev
# on later systems, if that does not work # $ sudo apt install libxslt1-dev
```

Acknowledgements
----------------

Loosely based on [OctoPrint-Pushbullet](https://github.com/OctoPrint/OctoPrint-Pushbullet).
Loosely based on [OctoPrint-Pushbullet](https://github.com/OctoPrint/OctoPrint-Pushbullet).

Uses [yagmail](https://github.com/kootenpv/yagmail) to send email.

## License
License
-------

Licensed under the terms of the [AGPLv3](http://opensource.org/licenses/AGPL-3.0).
10 changes: 5 additions & 5 deletions extras/emailnotifier.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ author: Jim DeVona
license: AGPLv3

# today's date in format YYYY-MM-DD, e.g.
date: 2015-09-23
date: 2020-09-30

homepage: https://github.com/kotl/OctoPrint-EmailNotifier
source: https://github.com/kotl/OctoPrint-EmailNotifier
archive: https://github.com/kotl/OctoPrint-EmailNotifier/archive/master.zip
homepage: https://github.com/idcrook/OctoPrint-EmailNotifier
source: https://github.com/idcrook/OctoPrint-EmailNotifier
archive: https://github.com/idcrook/OctoPrint-EmailNotifier/archive/main.zip

# set this to true if your plugin uses the dependency_links setup parameter to include
# library versions not yet published on PyPi. SHOULD ONLY BE USED IF THERE IS NO OTHER OPTION!
Expand All @@ -31,7 +31,7 @@ featuredimage: /assets/img/plugins/emailnotifier/emailnotifier.png
compatibility:
# list of compatible versions, for example 1.2.0. If left empty no specific version requirement will be assumed
octoprint:
- 1.2.4
- 1.4.0

---

Expand Down
14 changes: 11 additions & 3 deletions octoprint_emailnotifier/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
from email.utils import formatdate

from email.utils import formatdate
from flask.ext.login import current_user
from flask_login import current_user

class EmailNotifierPlugin(octoprint.plugin.EventHandlerPlugin,
octoprint.plugin.SettingsPlugin,
Expand Down Expand Up @@ -160,8 +160,15 @@ def send_notification(self, subject="OctoPrint notification", body=[""], snapsho
snapshot_url = self._settings.global_get(["webcam", "snapshot"])
if snapshot_url:
try:
import urllib
filename, headers = urllib.urlretrieve(snapshot_url, tempfile.gettempdir()+"/snapshot.jpg")
try:
from urllib.parse import urlparse, urlencode
from urllib.request import urlretrieve, urlopen, Request
from urllib.error import HTTPError
except ImportError as e:
from urlparse import urlparse
from urllib import urlencode, urlretrieve
from urllib2 import urlopen, Request, HTTPError
filename, headers = urlretrieve(snapshot_url, tempfile.gettempdir()+"/snapshot.jpg")
except Exception as e:
self._logger.exception("Snapshot error (sending email notification without image): %s" % (str(e)))
else:
Expand All @@ -175,6 +182,7 @@ def send_notification(self, subject="OctoPrint notification", body=[""], snapsho


__plugin_name__ = "Email Notifier"
__plugin_pythoncompat__ = ">=2.7,<4"

def __plugin_load__():
global __plugin_implementation__
Expand Down
83 changes: 75 additions & 8 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,31 +14,52 @@
plugin_name = "OctoPrint-EmailNotifier"

# The plugin's version. Can be overwritten within OctoPrint's internal data via __plugin_version__ in the plugin module
plugin_version = "0.1.1"
plugin_version = "0.2.1"

# The plugin's description. Can be overwritten within OctoPrint's internal data via __plugin_description__ in the plugin
# module
plugin_description = "Recieve email notifications when OctoPrint jobs are complete."
plugin_description = "Receive email notifications when OctoPrint jobs are complete."

# The plugin's author. Can be overwritten within OctoPrint's internal data via __plugin_author__ in the plugin module
plugin_author = "Jim DeVona"
plugin_author = "David Crook"

# The plugin's author's mail address.
plugin_author_email = "[email protected]"
plugin_author_email = "[email protected]"

# The plugin's homepage URL. Can be overwritten within OctoPrint's internal data via __plugin_url__ in the plugin module
plugin_url = "https://github.com/kotl/OctoPrint-EmailNotifier"
plugin_url = "https://github.com/idcrook/OctoPrint-EmailNotifier"

# The plugin's license. Can be overwritten within OctoPrint's internal data via __plugin_license__ in the plugin module
plugin_license = "AGPLv3"

# Any additional requirements besides OctoPrint should be listed here
plugin_requires = ['yagmail', 'keyrings.alt']
plugin_requires = ['yagmail', 'keyring', 'keyrings.alt', 'cryptography==3.3.2']

# Additional package data to install for this plugin. The subfolders "templates", "static" and "translations" will
# already be installed automatically if they exist.
plugin_additional_data = []

# Any additional python packages you need to install with your plugin that are not contains in <plugin_package>.*
plugin_additional_packages = []

# Any python packages within <plugin_package>.* you do NOT want to install with your plugin
plugin_ignored_packages = []

# Additional parameters for the call to setuptools.setup. If your plugin wants to register additional entry points,
# define dependency links or other things like that, this is the place to go. Will be merged recursively with the
# default setup parameters as provided by octoprint_setuptools.create_plugin_setup_parameters using
# octoprint.util.dict_merge.
#
# Example:
# plugin_requires = ["someDependency==dev"]
# additional_setup_parameters = {"dependency_links": ["https://github.com/someUser/someRepo/archive/main.zip#egg=someDependency-dev"]}
additional_setup_parameters = {}

# README/long description file to use for PyPi uploads. Must be the full absolute path. If the filename ends on
# .md and pypandoc is installed a conversion from Markdown to ReStructured Text will be performed utilizing
# setuptools-markdown as additional setup requirement.
plugin_readme_file = "README.md"

########################################################################################################################

from setuptools import setup
Expand All @@ -51,8 +72,9 @@
import sys
sys.exit(-1)

setup(**octoprint_setuptools.create_plugin_setup_parameters(
setup_parameters = octoprint_setuptools.create_plugin_setup_parameters(
identifier=plugin_identifier,
package=plugin_package,
name=plugin_name,
version=plugin_version,
description=plugin_description,
Expand All @@ -61,5 +83,50 @@
url=plugin_url,
license=plugin_license,
requires=plugin_requires,
additional_packages=plugin_additional_packages,
ignored_packages=plugin_ignored_packages,
additional_data=plugin_additional_data
))
)

if len(additional_setup_parameters):
from octoprint.util import dict_merge
setup_parameters = dict_merge(setup_parameters, additional_setup_parameters)

if plugin_readme_file:
import os

here = os.path.abspath(os.path.dirname(__file__))
plugin_readme_file_path = os.path.join(here, plugin_readme_file)

# make sure the file exists
if os.path.isfile(plugin_readme_file_path):
import codecs

try:
with codecs.open(plugin_readme_file_path, "rb", "utf-8") as f:
plugin_readme_file_content = f.read()

except Exception as e:
print("Error reading {} ({}), ignoring long description...".format(plugin_readme_file_path, str(e)))

else:
# file exists, let's see if it's markdown or not
if plugin_readme_file.endswith(".md"):
print("File with long description apparently is in Markdown format, will convert to RST with pypandoc")
try:
import pypandoc
setup_requires = setup_parameters.get("setup_requires", [])
setup_parameters.update(dict(
setup_requires=setup_requires+["setuptools-markdown"],
long_description_markdown_filename=plugin_readme_file
))
except:
print("No pypandoc installed, not using Markdown file as long description")
pass
else:
print("Using long description from {}...".format(plugin_readme_file_path))
setup_parameters.update(dict(
long_description=plugin_readme_file_content
))

setup(**setup_parameters)