Skip to content

Instantly share code, notes, and snippets.

@watagashi0619
Created April 23, 2021 15:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save watagashi0619/1267849cda831adc17032b545f69ad31 to your computer and use it in GitHub Desktop.
Save watagashi0619/1267849cda831adc17032b545f69ad31 to your computer and use it in GitHub Desktop.
AWS上で動かしている kulasisのお知らせとかpandaの課題とかをslackにpostするやつ
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