forked from jsk-ros-pkg/jsk_robot
-
Notifications
You must be signed in to change notification settings - Fork 3
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
[jsk_unitree_startup] Send Unitree-launch-email #24
Open
tkmtnt7000
wants to merge
19
commits into
k-okada:unitree
Choose a base branch
from
tkmtnt7000:PR-email-when-launching
base: unitree
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 13 commits
Commits
Show all changes
19 commits
Select commit
Hold shift + click to select a range
6984d62
[jsk_unitree_startup] Send Unitree-launch-email
tkmtnt7000 e103e6d
[jsk_unitree_startup] Show weather and single comment
tkmtnt7000 6e655eb
Fix for unitree internal environment
tkmtnt7000 05fa77d
Add sevice file for launch-email
tkmtnt7000 bdd220d
not use rospy
cd96718
add horoscope to email
MiyabiTane d2c3bcf
fix bug
MiyabiTane f57b932
Merge pull request #1 from MiyabiTane/add_emoji_unitree_email
tkmtnt7000 e4df359
[jsk_unitree_startup] Add python3-bs4 to package.xml
tkmtnt7000 3d707e0
[jsk_unitree_startup] Display robot name in mail subject
tkmtnt7000 11f1712
fix bug
MiyabiTane 0267836
誕生日の指定
MiyabiTane 6c1d600
Merge pull request #2 from MiyabiTane/add_emoji_unitree_email
tkmtnt7000 a2e1652
[jsk_unitree_startup] Use email_topic.py to send email
tkmtnt7000 5ae31f2
Merge branch 'unitree' into PR-email-when-launching
tkmtnt7000 de51c2b
Merge branch 'PR-email-when-launching' of github.com:tkmtnt7000/jsk_r…
tkmtnt7000 52ce98e
[jsk_unitree_startup] Use unitree's autostart process to send email
tkmtnt7000 2a7469a
[jsk_unitree_startup] Fix format
tkmtnt7000 2ee9f4b
[jsk_unitree_startup] Change file name launch-email.py -> launch_emai…
tkmtnt7000 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
274 changes: 274 additions & 0 deletions
274
jsk_unitree_robot/jsk_unitree_startup/scripts/launch-email.py
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,274 @@ | ||
#!/usr/bin/env python3 | ||
# -*- coding: utf-8 -*- | ||
|
||
from bs4 import BeautifulSoup | ||
import datetime | ||
import json | ||
import random | ||
import socket | ||
import subprocess | ||
import emoji | ||
import sys | ||
import argparse | ||
import re | ||
if sys.version_info.major == 2: | ||
import urllib2 | ||
else: | ||
from urllib import request | ||
|
||
|
||
class RobotLaunchEmail: | ||
""" | ||
Send email when robot launched with tips. | ||
""" | ||
def __init__(self): | ||
# Character code differences between python versions | ||
# See https://stackoverflow.com/questions/54153986/handling-encode-when-converting-from-python2-to-python3 #NOQA | ||
if sys.version_info.major == 2: | ||
reload(sys) | ||
sys.setdefaultencoding('utf-8') | ||
api_key_file = '/var/lib/robot/openweathermap_api_key.txt' | ||
with open(api_key_file, 'r') as f: | ||
self.appid = f.read().split('\n')[0] | ||
self.constellation = "sagittarius" | ||
self.constellation_jpn = "いて" | ||
|
||
def get_tips(self): | ||
""" | ||
Get tips from zatsuneta random article. | ||
|
||
Returns: | ||
---------- | ||
title : str | ||
article title | ||
contents : str | ||
article contents (heading) | ||
detail_url :str | ||
URL of the article written about the details | ||
""" | ||
url = 'https://zatsuneta.com/category/random.html' | ||
if sys.version_info.major == 2: | ||
response = urllib2.urlopen(url) | ||
else: | ||
response = request.urlopen(url) | ||
soup = BeautifulSoup(response, 'html5lib') | ||
topstories = soup.find('div', class_="article") | ||
title = topstories.find('a')['title'] | ||
detail_url = topstories.find('a')['href'] | ||
contents = topstories.find('p').text | ||
response.close() | ||
|
||
return title, contents, detail_url | ||
|
||
# Partly copied from https://github.com/knorth55/jsk_robot/blob/b2999b0cece82d7b1d46320a1e7c84e4fc078bd2/jsk_fetch_robot/jsk_fetch_startup/scripts/time_signal.py #NOQA | ||
def get_weather_forecast(self, lang='en'): | ||
url = 'http://api.openweathermap.org/data/2.5/weather?q=tokyo&lang={}&units=metric&appid={}'.format(lang, self.appid) # NOQA | ||
if sys.version_info.major == 2: | ||
resp = json.loads(urllib2.urlopen(url).read()) | ||
else: | ||
resp = json.loads(request.urlopen(url).read()) | ||
weather = resp['weather'][0]['description'] | ||
|
||
forecast_text = "" | ||
if lang == 'ja': | ||
forecast_text = "今日の天気は" + weather + "です。" | ||
else: | ||
forecast_text = " The weather is " + weather + " now." | ||
|
||
# It feels like the robot is expressing its will based on the weather. | ||
if "晴" in weather: | ||
forecast_tuple = ( | ||
'日差しに気をつけて。', | ||
'お散歩しよう!', | ||
) | ||
elif "雨" in weather: | ||
forecast_tuple = ( | ||
'部屋の中で遊ぼう!', | ||
'傘忘れていない?', | ||
) | ||
elif "雲" or "曇" or "くもり" in weather: | ||
forecast_tuple = ( | ||
'晴れたらいいな', | ||
) | ||
elif "雪" in weather: | ||
forecast_tuple = ( | ||
'雪合戦しよう!', | ||
'寒さに気をつけて', | ||
) | ||
else: | ||
forecast_tuple = (' ') | ||
forecast_text += random.choice(forecast_tuple) | ||
|
||
return forecast_text | ||
|
||
def add_emoji(self, mode): | ||
""" | ||
0: 普通, 1: 喜び, 2: 安心, 3: 悪巧み, 4: 驚き, 5: 悲しみ, 6: 怒り, 7: 照れ, | ||
8: 恐怖, 9: 好き, 10: ウインク・おふざけ, 11: 退屈, 12: 混乱 | ||
ref: https://www.webfx.com/tools/emoji-cheat-sheet/ | ||
""" | ||
dic = {0: ":neutral_face:", 1: ":smile:", 2: ":relieved:", 3: ":smirk:" , | ||
4: ":astonished:", 5: ":cry:", 6: ":angry:", 7: ":flushed:", | ||
8: ":scream:", 9: ":heart_eyes:", 10: ":wink:", 11: ":sleepy:", 12: ":sweat:"} | ||
|
||
return emoji.emojize(dic[mode], language='alias') | ||
|
||
def set_constellation(self): | ||
parser = argparse.ArgumentParser() | ||
parser.add_argument("--month", default="12") | ||
parser.add_argument("--days", default="14") | ||
args = parser.parse_args() | ||
|
||
birthday_num = int(args.month) * 100 + int(args.days) | ||
if 1221 < birthday_num <= 1231 or 101 <= birthday_num <= 119: | ||
self.constellation = "capricorn" | ||
self.constellation_jpn = "やぎ" | ||
elif 119 < birthday_num <= 131 or 201 <= birthday_num <= 218: | ||
self.constellation = "aquarius" | ||
self.constellation_jpn = "みずがめ" | ||
elif 218 < birthday_num <= 229 or 301 <= birthday_num <= 320: | ||
self.constellation = "pisces" | ||
self.constellation_jpn = "うお" | ||
elif 320 < birthday_num <= 331 or 401 <= birthday_num <= 419: | ||
self.constellation = "aries" | ||
self.constellation_jpn = "おひつじ" | ||
elif 419 < birthday_num <= 430 or 501 <= birthday_num <= 520: | ||
self.constellation = "taurus" | ||
self.constellation_jpn = "おうし" | ||
elif 520 < birthday_num <= 531 or 601 <= birthday_num <= 621: | ||
self.constellation = "gemini" | ||
self.constellation_jpn = "ふたご" | ||
elif 621 < birthday_num <= 630 or 701 <= birthday_num <= 722: | ||
self.constellation = "cancer" | ||
self.constellation_jpn = "かに" | ||
elif 722 < birthday_num <= 731 or 801 <= birthday_num <= 822: | ||
self.constellation = "leo" | ||
self.constellation_jpn = "しし" | ||
elif 822 < birthday_num <= 831 or 901 <= birthday_num <= 922: | ||
self.constellation = "virgo" | ||
self.constellation_jpn = "おとめ" | ||
elif 922 < birthday_num <= 930 or 1001 <= birthday_num <= 1023: | ||
self.constellation = "libra" | ||
self.constellation_jpn = "てんびん" | ||
elif 1023 < birthday_num <= 1031 or 1101 <= birthday_num <= 1121: | ||
self.constellation = "scorpio" | ||
self.constellation_jpn = "さそり" | ||
elif 1121 < birthday_num <= 1130 or 1201 <= birthday_num <= 1221: | ||
self.constellation = "sagittarius" | ||
self.constellation_jpn = "いて" | ||
else: | ||
print("Inappropriate birthday. Set default constellation: sagittarius") | ||
|
||
def get_fortune(self): | ||
""" | ||
Get tips from horoscope | ||
Return: | ||
message : str | ||
""" | ||
def add_comment_rank(rank): | ||
if rank == 1: | ||
message = "すごい、1位だ" + self.add_emoji(4) | ||
elif rank <= 3: | ||
message = str(rank) + "位!いい感じ" + self.add_emoji(1) | ||
elif rank == 12: | ||
message = "最下位..." + self.add_emoji(5) + "ラッキーアイテムをチェックしなきゃ!!" | ||
else: | ||
message = str(rank) + "位かぁ。そこそこかな" + self.add_emoji(0) | ||
return " " + message | ||
|
||
def add_comment_love(point): | ||
if point >= 9: | ||
message = "出会いを求めてお散歩しちゃおっかな" + self.add_emoji(9) | ||
elif point >= 6: | ||
message = "気になってるあの子に会えちゃうかも" + self.add_emoji(7) | ||
elif point <= 3: | ||
message = "こんなの信じないぞ" + self.add_emoji(6) | ||
else: | ||
message = "平凡な一日になりそう..." + self.add_emoji(11) | ||
return " " + message | ||
|
||
def add_comment_money(point): | ||
if point >= 9: | ||
message = "今日はお買い物しちゃおうかな" + self.add_emoji(10) | ||
elif point <= 3: | ||
message = "お金のつかい過ぎには気をつけよう..." + self.add_emoji(8) | ||
else: | ||
message = "今日は何事もなさそうかな" + self.add_emoji(2) | ||
return " " + message | ||
|
||
def add_comment_business(point): | ||
if point >= 7: | ||
message = "研究頑張ったら良いことあるかも" + self.add_emoji(1) | ||
elif point >= 4: | ||
message = "いいのか悪いのか分からないなぁ" + self.add_emoji(12) | ||
else: | ||
message = "今日は研究さぼっちゃおうかな〜" + self.add_emoji(3) | ||
return " " + message | ||
|
||
url = 'https://fortune.yahoo.co.jp/12astro/'+ self.constellation | ||
if sys.version_info.major == 2: | ||
response = urllib2.urlopen(url) | ||
else: | ||
response = request.urlopen(url) | ||
soup = BeautifulSoup(response, "html.parser") | ||
fortune = soup.find('div', id="jumpdtl").find_all('td') | ||
f_contents = soup.find('div', class_="yftn12a-md48").find_all('dd')[0].contents[0] | ||
try: | ||
rank = re.sub(r"\D", "", fortune[-5].contents[0].contents[0]) + "位" | ||
except: | ||
rank = re.sub(r"\D", "", fortune[-5].contents[0].attrs['alt']) + "位" | ||
point_overall = fortune[-4].contents[0].attrs['alt'] | ||
point_love = fortune[-3].contents[0].attrs['alt'] | ||
point_money = fortune[-2].contents[0].attrs['alt'] | ||
point_business = fortune[-1].contents[0].attrs['alt'] | ||
rank_int = int(re.sub(r"\D", "", rank)) | ||
point_love_int = int(re.sub(r"\D", "", point_love)[2:]) | ||
point_money_int = int(re.sub(r"\D", "", point_money)[2:]) | ||
point_business_int = int(re.sub(r"\D", "", point_business)[2:]) | ||
message = "今日の星座占い:" | ||
message += self.constellation_jpn + "座の運勢は【" + rank + "】" + add_comment_rank(rank_int) + "\n" | ||
message += f_contents + "\n" | ||
message += "だって!\n" | ||
message += "\n" | ||
message += "総合運: " + point_overall + "\n" | ||
message += "恋愛運: " + point_love + add_comment_love(point_love_int) + "\n" | ||
message += "金運: " + point_money + add_comment_money(point_money_int) + "\n" | ||
message += "仕事運: " + point_business + add_comment_business(point_business_int) + "\n" | ||
response.close() | ||
|
||
return message | ||
|
||
def send_mail(self): | ||
""" | ||
Send mail with mailutils | ||
""" | ||
sender_address = "[email protected]" | ||
receiver_address = "[email protected]" | ||
current_time = datetime.datetime.now() | ||
mail_title = "{} が起動しました".format(socket.gethostname()) | ||
message = "" | ||
message += "おはよう。" | ||
message += "{}時{}分です。\\n".format( | ||
current_time.hour, current_time.minute) | ||
message += "{} \\n".format(self.get_weather_forecast(lang="ja")) | ||
message += "\\n" | ||
|
||
contents_title, contents, detail_url = self.get_tips() | ||
message += "今日の豆知識 \\n" | ||
message += "{}: {} \\n".format(contents_title, contents) | ||
message += "詳細: {} \\n".format(detail_url) | ||
message += "\\n" | ||
|
||
message += self.get_fortune() | ||
message += "\\n" | ||
|
||
# echo -e option is necessary in raspberry pi | ||
cmd = "echo -e '{}'".format(message) | ||
cmd += " | /usr/bin/mail -s '{}' -r {} {}".format( | ||
mail_title, sender_address, receiver_address) | ||
exit_code = subprocess.call(cmd, shell=True) | ||
|
||
if __name__ == '__main__': | ||
RobotLaunchEmail = RobotLaunchEmail() | ||
RobotLaunchEmail.set_constellation() | ||
RobotLaunchEmail.send_mail() |
19 changes: 19 additions & 0 deletions
19
jsk_unitree_robot/jsk_unitree_startup/scripts/launch-email.service
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,19 @@ | ||
[Unit] | ||
Description=Unitree launched email Service | ||
Requires=dhcpcd.service | ||
Requires=networking.service | ||
Requires=dnsmasq.service | ||
|
||
|
||
[Service] | ||
Type=simple | ||
ExecStart=/home/pi/jsk_catkin_ws/src/jsk_robot/jsk_unitree_robot/jsk_unitree_startup/scripts/launch-email.py | ||
RestartSec=10s | ||
Restart=on-failure | ||
# KillMode=control-group | ||
# KillSignal=SIGTERM | ||
User=pi | ||
Group=pi | ||
|
||
[Install] | ||
WantedBy=multi-user.target |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@a-ichikura
こんな感じで適当な言葉を追加してあるので,思いついたら色々と追加していただけると嬉しいです.