-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 9136775
Showing
7 changed files
with
136 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
# WECHAT NOTIFY | ||
|
||
Many scripts today may take a long time to run, such as deep learning tasks. We wonder to check the results immediately after its accomplishment but keeping an eye on the process is not desirable. | ||
|
||
This project is aimed to notify you through WeChat when certain command is completed. | ||
|
||
## requirements | ||
|
||
This package rely on `requests`. | ||
|
||
```bash | ||
pip3 install requests | ||
``` | ||
|
||
### SERVER CHAN | ||
|
||
This project rely on [SERVER CHAN](http://sc.ftqq.com/3.version) to push notifications to WeChat. Please follow the instructions on the website and **set your SCKEY to environment variable** as `SERVER_CHAN_TOKEN`. | ||
|
||
Your command's output and error will be write to file `stdout` and `stderr` regardless of whether notification will be push or not. | ||
|
||
## usage | ||
|
||
```bash | ||
notify [bash command] | ||
``` | ||
|
||
Note that special chars of bash, such as `>`, need to be escaped so that the script can capture the corrent bash command. For example: | ||
|
||
```bash | ||
notify python train.py \> trail.log | ||
``` | ||
|
||
## example | ||
|
||
WECHAT_NOTIFY will push three kinds of notifications. | ||
|
||
* [Success]: inform you [what command, start time, how long the command takes, last three lines of output(if exists)] | ||
<img src='imgs/success.png' height=300> | ||
* [Failed]: inform you [what command, start time, how long the command takes, last three lines of stderr(if exists)] | ||
<img src='imgs/failed.png' height=300> | ||
<!--  --> | ||
* [Keyboard Interrupt]: inform you [what command, start time, 'Keyboard Interrupt'] | ||
<img src='imgs/kayboard.png' height=300> | ||
<!--  --> | ||
|
||
## TODO | ||
|
||
- [ ] unit test | ||
- [ ] Email support | ||
- [ ] test on WeChat Work |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
from setuptools import setup | ||
|
||
setup(name="wechat-notify", | ||
description="notify you on Wechat when certain task is completed", | ||
version="1.0", | ||
author="Tab_version", | ||
author_email="[email protected]", | ||
packages=['wechat_notify'], | ||
install_requires=[ | ||
'requests', | ||
], | ||
entry_points = { | ||
'console_scripts': ['notify=wechat_notify.notify:main'], | ||
}, | ||
include_package_data=True, | ||
) |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
import sys | ||
import os | ||
import subprocess | ||
import requests | ||
import time | ||
|
||
def build_parser(): | ||
if len(sys.argv) == 1: | ||
raise ValueError('please input command') | ||
return sys.argv[1:] | ||
|
||
|
||
def send_request(output, err, process, token, command, start, duration, is_win): | ||
if output is not None: | ||
output = output.decode('utf-8').split('\r\n') if is_win else output.decode('utf-8').split('\n') | ||
with open('stdout', 'w') as f: | ||
f.write('\n'.join(output)) | ||
if err is not None: | ||
err = err.decode('utf-8').split('\r\n') if is_win else err.decode('utf-8').split('\n') | ||
with open('stderr', 'w') as f: | ||
f.write('\n'.join(err)) | ||
temp = None | ||
# import ipdb; ipdb.set_trace() | ||
if process.poll() == 0: | ||
if output is not None: | ||
output = [''] * 3 + output | ||
temp = 'the following are last three lines of stdout:\n' + '\n'.join(output[-3:]) | ||
post_str = r'https://sc.ftqq.com/' + token + '.send?' + f'text=[Scuucess] command: ' + ' '.join(command) + f'&desp=start at {time.ctime(int(start))}\ttake time: {duration}\t' + (temp if temp is not None else '') | ||
requests.post(post_str) | ||
else: | ||
if err is not None: | ||
err = [''] * 3 + err | ||
temp = 'the following are last three lines of stderr:\n' + '\n'.join(err[-3:]) | ||
# import ipdb; ipdb.set_trace() | ||
post_str = r'https://sc.ftqq.com/' + token + '.send?' + f'text=[Failed] command: ' + ' '.join(command) + f'&desp=start at {time.ctime(int(start))}\ttake time: {duration}\terror code: {process.poll()}'+ (temp if temp is not None else '') | ||
print(post_str) | ||
requests.post(post_str) | ||
|
||
|
||
|
||
def init(): | ||
try: | ||
token = os.environ['SERVER_CHAN_TOKEN'] | ||
except KeyError: | ||
print('environment variable `SERVER_CHAN_TOKEN` unfound') | ||
exit(1) | ||
return token | ||
|
||
def main(): | ||
token = init() | ||
start = time.time() | ||
try: | ||
command = build_parser() | ||
process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE) | ||
output, err = process.communicate() | ||
|
||
except KeyboardInterrupt: | ||
print('keyboard') | ||
process.kill() | ||
requests.post(r'https://sc.ftqq.com/' + token + '.send?' + f'text=[Failed] command: ' + ' '.join(command) + f'&desp=start at {time.ctime(int(start))}\nbecause of Keyboard Interrupt') | ||
exit(0) | ||
|
||
duration = time.time() - start | ||
is_win = (sys.platform == 'win32') | ||
send_request(output=output, err=err, duration=duration, is_win=is_win,start=start, token=token, command=command, process=process) | ||
|
||
|
||
|
||
if __name__ == "__main__": | ||
main() |