Created
April 23, 2021 15:20
-
-
Save watagashi0619/1267849cda831adc17032b545f69ad31 to your computer and use it in GitHub Desktop.
AWS上で動かしている kulasisのお知らせとかpandaの課題とかをslackにpostするやつ
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
import datetime | |
import json | |
import os | |
import re | |
import time | |
import requests | |
import yaml | |
from selenium import webdriver | |
from selenium.webdriver.chrome.options import Options | |
from selenium.webdriver.common.by import By | |
from selenium.webdriver.support import expected_conditions as EC | |
from selenium.webdriver.support.ui import WebDriverWait | |
class Chrome: | |
def headless_lambda(self): | |
options = webdriver.ChromeOptions() | |
options.binary_location = "/opt/headless/python/bin/headless-chromium" | |
options.add_argument("--headless") | |
options.add_argument("--no-sandbox") | |
options.add_argument("--single-process") | |
options.add_argument("--disable-gpu") | |
options.add_argument("--window-size=1280x1696") | |
options.add_argument("--disable-application-cache") | |
options.add_argument("--disable-infobars") | |
options.add_argument("--hide-scrollbars") | |
options.add_argument("--enable-logging") | |
options.add_argument("--log-level=0") | |
options.add_argument("--ignore-certificate-errors") | |
options.add_argument("--homedir=/tmp") | |
options.add_argument("--disable-dev-shm-usage") | |
options.add_experimental_option( | |
"prefs", | |
{ | |
"download.default_directory": "/tmp", | |
"plugins.always_open_pdf_externally": True, | |
}, | |
) | |
driver = webdriver.Chrome( | |
executable_path="/opt/headless/python/bin/chromedriver", | |
chrome_options=options, | |
) | |
return driver | |
def lambda_handler(event, context): | |
with open("config.yaml") as yamlfile: | |
config = yaml.load(yamlfile, Loader=yaml.SafeLoader) | |
ECS_ACCOUNT = {"ecs-id": config["ecs-id"], "password": config["password"]} | |
# CHANNEL_ID_KULASIS = config["channel_id_test"] | |
CHANNEL_ID_KULASIS = config["channel_id_kulasis"] | |
CHANNEL_ID_PANDA = config["channel_id_panda"] | |
HISTORY_API_URL = config["history_api_url"] | |
POST_API_URL = config["post_api_url"] | |
UPLOAD_API_URL = config["upload_api_url"] | |
TOKEN = config["bot_token"] | |
JST = datetime.timezone(datetime.timedelta(hours=+9), "JST") | |
dt_now = datetime.datetime.now(JST) | |
chrome = Chrome() | |
driver = chrome.headless_lambda() | |
##### KULASIS | |
login_url = "https://www.k.kyoto-u.ac.jp/student/la/top" | |
driver.get(login_url) | |
driver.find_element_by_id("username").send_keys(ECS_ACCOUNT["ecs-id"]) | |
driver.find_element_by_id("password").send_keys(ECS_ACCOUNT["password"]) | |
driver.find_element_by_name("_eventId_proceed").click() | |
# 重複確認 | |
payload = {"token": TOKEN, "channel": CHANNEL_ID_KULASIS} | |
response = requests.get(HISTORY_API_URL, params=payload) | |
json_data = response.json() | |
history_link_list = [] | |
divide_time = (dt_now - datetime.timedelta(hours=24)).timestamp() | |
print("-----slack履歴確認開始-----") | |
for item in json_data["messages"]: | |
if "bot_id" in item and float(item["ts"]) > divide_time: | |
if "subtype" in item and item["subtype"] == "bot_message": | |
try: | |
print( | |
item["attachments"][0]["fallback"], | |
item["attachments"][0]["title_link"], | |
) | |
history_link_list.append(item["attachments"][0]["title_link"]) | |
except: | |
print("*****") | |
print("-----slack履歴確認終了-----") | |
new_list = [] # 履歴にないものを格納(ログ用) | |
# 全学生向け共通掲示板Information | |
print("-----全学生向け共通掲示板Information-----") | |
today = ( | |
str(dt_now.year) | |
+ "/" | |
+ "{:02d}".format(dt_now.month) | |
+ "/" | |
+ "{:02d}".format(dt_now.day) | |
) | |
information_details_link = [] # 掲示板情報のリンク | |
info_table = driver.find_element_by_class_name( | |
"panel-info" | |
).find_elements_by_tag_name("tr") | |
for item in info_table: | |
if today in item.text: | |
information_details_link.append( | |
item.find_element_by_tag_name("a").get_attribute("href") | |
) | |
for link in information_details_link: | |
driver.get(link) | |
title = driver.find_element_by_class_name("panel-heading").text | |
table_item = driver.find_element_by_class_name( | |
"table" | |
).find_elements_by_tag_name("tr") | |
classification = table_item[1].find_elements_by_tag_name("td")[1].text | |
title = "[" + classification + "] " + title | |
text = table_item[3].find_elements_by_tag_name("td")[0].text | |
if not link in history_link_list: # 掲示板情報のリンクが履歴になければpost | |
new_list += [title] | |
if not table_item[4].find_elements_by_tag_name("td")[0].text == "": | |
attachment_file = ( | |
table_item[4] | |
.find_elements_by_tag_name("td")[0] | |
.find_element_by_tag_name("a") | |
.get_attribute("href") | |
) | |
data = { | |
"token": TOKEN, | |
"channel": CHANNEL_ID_KULASIS, | |
"username": u"全学生向け共通掲示板 Information", | |
"attachments": json.dumps( | |
[ | |
{ | |
"fallback": title, | |
"title": title, | |
"title_link": link, | |
"color": "#36c5f0", | |
"fields": [ | |
{ | |
"value": text, | |
} | |
], | |
"actions": [ | |
{ | |
"type": "button", | |
"text": "添付ファイルを表示", | |
"url": attachment_file, | |
} | |
], | |
"ts": datetime.datetime.now(JST).timestamp(), | |
} | |
] | |
), | |
"icon_emoji": u":books:", | |
} | |
else: | |
data = { | |
"token": TOKEN, | |
"channel": CHANNEL_ID_KULASIS, | |
"username": u"全学生向け共通掲示板 Information", | |
"attachments": json.dumps( | |
[ | |
{ | |
"fallback": title, | |
"title": title, | |
"title_link": link, | |
"color": "#36c5f0", | |
"fields": [ | |
{ | |
"value": text, | |
} | |
], | |
"ts": dt_now.timestamp(), | |
} | |
] | |
), | |
"icon_emoji": u":books:", | |
} | |
requests.post(POST_API_URL, data=data) | |
if new_list == []: | |
print("新しいお知らせはありません。") | |
else: | |
for item in new_list: | |
print(item) | |
new_list = [] | |
# 工学部掲示板 | |
driver.command_executor._commands["send_command"] = ( | |
"POST", | |
"/session/$sessionId/chromium/send_command", | |
) | |
params = { | |
"cmd": "Page.setDownloadBehavior", | |
"params": {"behavior": "allow", "downloadPath": "/tmp"}, | |
} | |
driver.execute("send_command", params=params) | |
print("-----工学部掲示板-----") | |
today = ( | |
str(dt_now.year) + "/" + str(dt_now.month) + "/" + "{:02d}".format(dt_now.day) | |
) | |
notice_t = "https://www.k.kyoto-u.ac.jp/student/u/t/notice/general" | |
driver.get(notice_t) | |
report_details_link = [] | |
table = driver.find_element_by_class_name( | |
"no_scroll_list" | |
).find_elements_by_tag_name("tr") | |
for item in table[2:-2]: | |
if ( | |
"情報学/コース/全" in item.find_elements_by_tag_name("td")[1].text | |
or "情報学/コース/2,3" in item.find_elements_by_tag_name("td")[1].text | |
or "情報学/コース/3" in item.find_elements_by_tag_name("td")[1].text | |
or "全/コース/全" in item.find_elements_by_tag_name("td")[1].text | |
or "全/コース/2,3" in item.find_elements_by_tag_name("td")[1].text | |
or "全/コース/3" in item.find_elements_by_tag_name("td")[1].text | |
) and ( | |
today in item.find_elements_by_tag_name("td")[3].text | |
): # 自分たちに関係のあるものだけを抽出 | |
report_details_link.append( | |
item.find_element_by_tag_name("a").get_attribute("href") | |
) | |
for link in report_details_link: | |
driver.get(link) | |
table_item = driver.find_element_by_class_name( | |
"relaxed_table" | |
).find_elements_by_tag_name("tr") | |
title = table_item[2].find_elements_by_tag_name("td")[1].text | |
text = table_item[4].find_elements_by_tag_name("td")[1].text | |
target = "" # このへんいらなさそう... | |
if ( | |
"数理工学コース" | |
in table_item[3] | |
.find_elements_by_tag_name("td")[1] | |
.find_element_by_tag_name("span") | |
.get_attribute("data-tooltip") | |
and "計算機科学コース" | |
in table_item[3] | |
.find_elements_by_tag_name("td")[1] | |
.find_element_by_tag_name("span") | |
.get_attribute("data-tooltip") | |
) or ( | |
"指定なし" | |
in table_item[3] | |
.find_elements_by_tag_name("td")[1] | |
.find_element_by_tag_name("span") | |
.get_attribute("data-tooltip") | |
): | |
target = "対象:計算機科学コース/数理工学コース" | |
elif "数理工学コース" in table_item[3].find_elements_by_tag_name("td")[ | |
1 | |
].find_element_by_tag_name("span").get_attribute("data-tooltip"): | |
target = "対象:数理工学コース" | |
elif "計算機科学コース" in table_item[3].find_elements_by_tag_name("td")[ | |
1 | |
].find_element_by_tag_name("span").get_attribute("data-tooltip"): | |
target = "対象:計算機科学コース" | |
if not link in history_link_list: | |
new_list += [title] | |
if "ファイルを表示" in driver.find_element_by_class_name("relaxed_table").text: | |
attachment_file = ( | |
table_item[5] | |
.find_elements_by_tag_name("td")[1] | |
.find_element_by_tag_name("a") | |
.get_attribute("href") | |
) | |
data = { | |
"token": TOKEN, | |
"channel": CHANNEL_ID_KULASIS, | |
"username": u"工学部教務・厚生情報", | |
"attachments": json.dumps( | |
[ | |
{ | |
"fallback": title, | |
"title": title, | |
"title_link": link, | |
"color": "#2eb886", | |
"fields": [ | |
{ | |
"value": text, | |
} | |
], | |
"actions": [ | |
{ | |
"type": "button", | |
"text": "ファイルを表示", | |
"url": attachment_file, | |
} | |
], | |
"footer": target, | |
"ts": dt_now.timestamp(), | |
} | |
] | |
), | |
"icon_emoji": u":books:", | |
} | |
requests.post(POST_API_URL, data=data) | |
try: # pdfは展開してもらう(失敗することがある?気がするのでtry) | |
driver.get(attachment_file) | |
time.sleep(3) | |
for file_in_tmp in os.listdir("/tmp/"): | |
base, ext = os.path.splitext(file_in_tmp) | |
if ext == ".pdf": | |
files = {"file": open("/tmp/{}".format(file_in_tmp), "rb")} | |
param = { | |
"token": TOKEN, | |
"channels": CHANNEL_ID_KULASIS, | |
"username": u"工学部教務・厚生情報", | |
} | |
requests.post( | |
url=UPLOAD_API_URL, | |
params=param, | |
files=files, | |
) | |
os.remove("/tmp/{}".format(file_in_tmp)) | |
except Exception as e: | |
print("ERROR has occured:", e.args) | |
else: | |
data = { | |
"token": TOKEN, | |
"channel": CHANNEL_ID_KULASIS, | |
"username": u"工学部教務・厚生情報", | |
"attachments": json.dumps( | |
[ | |
{ | |
"fallback": title, | |
"title": title, | |
"title_link": link, | |
"color": "#2eb886", | |
"fields": [ | |
{ | |
"value": text, | |
} | |
], | |
"footer": target, | |
"ts": dt_now.timestamp(), | |
} | |
] | |
), | |
"icon_emoji": u":books:", | |
} | |
requests.post( | |
url=UPLOAD_API_URL, | |
params=param, | |
files=files, | |
) | |
if new_list == []: | |
print("新しいお知らせはありません。") | |
else: | |
for item in new_list: | |
print(item) | |
##### PANDA | |
payload = {"token": TOKEN, "channel": CHANNEL_ID_PANDA} | |
response = requests.get(HISTORY_API_URL, params=payload) | |
json_data = response.json() | |
kadai_history = [] | |
for item in json_data["messages"]: | |
if "subtype" in item and item["subtype"] == "bot_message": | |
kadai_history.append( | |
(item["attachments"][0]["footer"], item["attachments"][0]["ts"]) | |
) | |
login_url = "https://cas.ecs.kyoto-u.ac.jp/cas/login?service=https%3A%2F%2Fpanda.ecs.kyoto-u.ac.jp%2Fsakai-login-tool%2Fcontainer" | |
driver.get(login_url) | |
driver.find_element_by_id("username").send_keys(ECS_ACCOUNT["ecs-id"]) | |
driver.find_element_by_id("password").send_keys(ECS_ACCOUNT["password"]) | |
driver.find_element_by_name("submit").click() | |
tab_info = {} | |
for elementCollection in driver.find_elements_by_css_selector(".fav-sites-entry"): | |
lecture_id = elementCollection.find_element_by_css_selector("a").get_attribute( | |
"data-site-id" | |
) | |
lecture_name = ( | |
elementCollection.find_element_by_css_selector("div") | |
.find_element_by_css_selector("a") | |
.get_attribute("title") | |
) | |
lecture_link = ( | |
elementCollection.find_element_by_css_selector("div") | |
.find_element_by_css_selector("a") | |
.get_attribute("href") | |
) | |
tab_info[lecture_id] = { | |
"lectureName": lecture_name, | |
"lectureLink": lecture_link, | |
} | |
my_json = "https://panda.ecs.kyoto-u.ac.jp/direct/assignment/my.json" | |
driver.get(my_json) | |
json_text = driver.find_element_by_css_selector("pre").get_attribute("innerText") | |
json_response = json.loads(json_text) | |
for item in json_response["assignment_collection"]: | |
lecture_name = tab_info[item["context"]]["lectureName"] | |
lecture_link = tab_info[item["context"]]["lectureLink"] | |
title = item["title"] | |
dueDate = datetime.datetime.fromtimestamp( | |
item["dueTime"]["epochSecond"], JST | |
).strftime("%Y/%m/%d %H:%M") | |
time_last_modified = item["timeLastModified"]["epochSecond"] | |
fallback_text = lecture_name + "(締切:" + dueDate + ")" | |
instructions = re.sub(r"<.+?>", "", item["instructions"]) | |
kadai_id = item["id"] | |
if (kadai_id, time_last_modified) in kadai_history: | |
continue | |
data = { | |
"token": TOKEN, | |
"username": u"PandA課題", | |
"channel": CHANNEL_ID_PANDA, | |
"icon_emoji": u":panda_face:", | |
"attachments": json.dumps( | |
[ | |
{ | |
"fallback": fallback_text, | |
"title": title, | |
"title_link": lecture_link, | |
"fields": [ | |
{ | |
"title": "講義名", | |
"value": lecture_name, | |
}, | |
{ | |
"title": "締め切り", | |
"value": dueDate, | |
}, | |
{ | |
"title": "課題内容", | |
"value": instructions, | |
}, | |
], | |
"footer": item["id"], | |
"ts": time_last_modified, | |
} | |
] | |
), | |
} | |
requests.post(POST_API_URL, data=data) | |
driver.quit() | |
return True |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment