티스토리 뷰
반응형
#style관련 지워도 됨, 다른 그룹웨어 안들어가봐서 되는지 모름ㅎ
0. 실행 시 tray에 등록
-트레이 우클릭 등록, 새로고침, 끝내기
1. selenium으로 gw login
-bs로 로그인 못하겠음
2. driver cookie -> requests.Session에 넘겨 줌
3. Session으로 당일기준 범위 안의 일 별 일정 가져 옴(global day_range = 15)
4. DB로 넣어 줌
- aws dynamo db사용(1. free tier무료 2. 간단 함)
- 넣어주면서 key값으로 중복 검사 함, schedule_day_idx 중복 없었음
5. 없다면 새 일정으로 판단 > 윈도우 알림 줌(카톡으로 줘도 될 듯)
6. timer로 3600초에 한번씩 가져 옴
-thread로 바꿔야 함
import inspect
import json
import os
import platform
import sys
import threading
from datetime import datetime, timedelta
from pprint import pprint
import boto3
import requests
import xmltodict
from PyQt5.QtCore import (
QCoreApplication,
QDateTime,
Qt,
QThread,
pyqtSignal,
pyqtSlot,
)
from PyQt5.QtGui import QColor, QGuiApplication, QIcon, QPalette
from PyQt5.QtWidgets import (
QAbstractItemView,
QAction,
QApplication,
QBoxLayout,
QCalendarWidget,
QCheckBox,
QComboBox,
QDateEdit,
QFrame,
QGridLayout,
QGroupBox,
QHBoxLayout,
QLabel,
QLineEdit,
QMainWindow,
QMenu,
QMessageBox,
QPushButton,
QRadioButton,
QSizePolicy,
QStatusBar,
QStyle,
QSystemTrayIcon,
QTableWidget,
QTableWidgetItem,
QTabWidget,
QTextEdit,
QVBoxLayout,
QWidget,
qApp,
)
from selenium import webdriver
day_range = 15
class Main(QWidget):
def __init__(self):
super(Main, self).__init__()
self.dow = ["월", "화", "수", "목", "금", "토", "일"]
self.insert_cnt = 0
self.data = {
"schedule_day_idx": "",
"schedule_day_type": "",
"schedule_day_pidx": "",
"schedule_day_name": "",
"schedule_day_weekname": "",
"schedule_day_stime": "",
"schedule_day_etime": "",
"schedule_day_date": "",
"schedule_day_gubun": "",
"schedule_day_memo": "",
"schedule_day_cut_memo": "",
"schedule_day_readcheck": "",
}
self.add_data = {
"sm_member_id": "",
"sm_pidx": "",
"sm_gidx": "",
"sm_pcount": "",
"stype": "",
"sm_write_type": "",
"sm_gubun": "P",
"sm_code": "",
"sm_name": "",
"sm_place": "",
"sm_management": "",
"sm_repeat": "",
"sm_sdate": "",
"sm_sadate": "",
"sm_eadate": "",
"sm_stime1": "",
"sm_stime2": "",
"sm_etime1": "",
"sm_etime2": "",
"sm_open": "",
"sm_open_hidden": "",
"sm_open_dept_hidden": "",
"sm_goods": "",
"sm_goods_hidden": "",
"sm_inner": "",
"sm_inner_hidden": "",
"sm_memo": "",
"sm_file": "(binary)",
"sm_file_hidden": "",
"sm_file_filehidden": "",
"sp_date1": "",
"sp_date2": "",
"sm_repeat_gubun": "",
"sp_stime1": "",
"sp_stime2": "",
"sp_etime1": "",
"sp_etime2": "",
}
self.initUI()
self.CheckSchedule()
def initUI(self):
self._translate = QCoreApplication.translate
self.setWindowTitle("GW Schedule Manager")
self.list_schedule_gubun = ["부서", "개인", "회사"]
self.list_schedule_code = ["작업", "회의", "약속", "기타"]
self.list_shour = ["{0:02d}".format(i) for i in range(0, 25)]
self.list_ehour = ["{0:02d}".format(i) for i in range(0, 25)]
self.list_smin = ["{0:02d}".format(i) for i in range(0, 51, 10)]
self.list_emin = ["{0:02d}".format(i) for i in range(0, 51, 10)]
self.icon = QIcon(r"C:\dev\python\Books\crawling2\calendar2.png")
self.tray = QSystemTrayIcon(self)
self.tray.setIcon(self.icon)
self.tray.setVisible(True)
self.date_schedule_dayrange = QDateEdit()
self.date_schedule_dayrange.setCalendarPopup(True)
self.date_schedule_dayrange.setDateTime(QDateTime.currentDateTime())
self.text_schedule_memo = QTextEdit()
self.text_schedule_memo.setHtml(
self._translate(
"Form",
'<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">\n'
'<html><head><meta name="qrichtext" content="1" /><style type="text/css">\n'
"p, li { white-space: pre-wrap; }\n"
"</style></head><body style=\" font-family:'Gulim'; font-size:9pt; font-weight:400; font-style:normal;\">\n"
'<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">1</p>\n'
'<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">2</p>\n'
'<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">3</p></body></html>',
)
)
self.line_schedule_title = QLineEdit("제목: ")
self.line_schedule_title.focusPolicy()
self.line_schedule_joinlist = QLineEdit()
self.line_schedule_joinlist.setEnabled(False)
self.radio_post_gubun = QRadioButton("일정")
self.radio_post_gubun.setChecked(True)
self.combo_schedule_gubun = QComboBox()
self.combo_schedule_gubun.addItems(self.list_schedule_gubun)
self.combo_schedule_code = QComboBox()
self.combo_schedule_code.addItems(self.list_schedule_code)
self.combo_shour = QComboBox()
self.combo_shour.addItems(self.list_shour)
self.combo_shour.setCurrentText("09")
self.combo_smin = QComboBox()
self.combo_smin.addItems(self.list_smin)
self.combo_smin.setCurrentText("00")
self.combo_ehour = QComboBox()
self.combo_ehour.addItems(self.list_ehour)
self.combo_ehour.setCurrentText("18")
self.combo_emin = QComboBox()
self.combo_emin.addItems(self.list_emin)
self.combo_emin.setCurrentText("00")
self.chk_specific = QCheckBox("일정 상세등록")
self.lab_post_gubun = QLabel("등록구분")
self.lab_specific = QLabel("상세등록")
self.lab_schedule_gubun = QLabel("일정구분")
self.lab_schedule_code = QLabel("일정코드")
self.lab_schedule_title = QLabel("일정명")
self.lab_schedule_dayrange = QLabel("기간설정")
self.lab_schedule_timerange = QLabel("시간")
self.lab_schedule_joinlist = QLabel("내부참여자")
self.lab_schedule_memo = QLabel("내용")
self.btn_save = QPushButton("등록", clicked=self.ClickedSaveBtn)
self.btn_cancel = QPushButton("취소", clicked=self.ClickedCancelBtn)
self.btn_joinlist = QPushButton("선택")
self.gbox = QGridLayout()
self.hbox = QHBoxLayout()
self.hbox1 = QHBoxLayout()
self.hbox2 = QHBoxLayout()
self.hbox3 = QHBoxLayout()
self.hbox.addWidget(self.combo_shour)
self.hbox.addWidget(self.combo_smin)
self.hbox.addWidget(self.combo_ehour)
self.hbox.addWidget(self.combo_emin)
self.hbox1.addWidget(self.combo_schedule_code)
self.hbox1.addWidget(self.lab_schedule_code)
self.hbox1.addWidget(self.combo_schedule_gubun)
self.hbox2.addWidget(self.line_schedule_joinlist)
self.hbox2.addWidget(self.btn_joinlist)
self.hbox3.addWidget(self.btn_save)
self.hbox3.addWidget(self.btn_cancel)
self.gbox.addWidget(self.lab_post_gubun, 0, 0, 1, 1)
self.gbox.addWidget(self.radio_post_gubun, 0, 1, 1, 1)
self.gbox.addWidget(self.lab_specific, 1, 0, 1, 1)
self.gbox.addWidget(self.chk_specific, 1, 1, 1, 1)
self.gbox.addWidget(self.lab_schedule_gubun, 2, 0, 1, 1)
self.gbox.addWidget(self.lab_schedule_title, 3, 0, 1, 1)
self.gbox.addWidget(self.line_schedule_title, 3, 1, 1, 1)
self.gbox.addWidget(self.lab_schedule_dayrange, 4, 0, 1, 1)
self.gbox.addWidget(self.date_schedule_dayrange, 4, 1, 1, 1)
self.gbox.addWidget(self.lab_schedule_timerange, 5, 0, 1, 1)
self.gbox.addWidget(self.lab_schedule_joinlist, 6, 0, 1, 1)
self.gbox.addWidget(self.lab_schedule_memo, 7, 0, 1, 1)
self.gbox.addWidget(self.text_schedule_memo, 7, 1, 1, 1)
self.gbox.addLayout(self.hbox, 5, 1, 1, 1)
self.gbox.addLayout(self.hbox1, 2, 1, 1, 1)
self.gbox.addLayout(self.hbox2, 6, 1, 1, 1)
self.gbox.addLayout(self.hbox3, 8, 1, 1, 1)
self.setLayout(self.gbox)
menu = QMenu()
add_action = QAction("Add", self)
refresh_action = QAction("Refresh", self)
exit_action = QAction("Exit", self)
add_action.triggered.connect(self.AddSchedule)
refresh_action.triggered.connect(self.CheckSchedule)
exit_action.triggered.connect(qApp.quit)
menu.addAction(add_action)
menu.addAction(refresh_action)
menu.addAction(exit_action)
self.tray.setContextMenu(menu)
def ClickedSaveBtn(self):
if self.combo_schedule_gubun.currentText() == "부서":
self.add_data["sm_gubun"] = "T"
elif self.combo_schedule_gubun.currentText() == "개인":
self.add_data["sm_gubun"] = "P"
if self.combo_schedule_code.currentText() == "작업":
self.add_data["sm_code"] = "W"
self.add_data["sm_name"] = self.line_schedule_title.text()
self.add_data["sm_repeat"] = "N"
self.add_data["sm_sdate"] = (
self.date_schedule_dayrange.date()
).toString("yyyy-MM-dd")
self.add_data["sm_stime1"] = self.combo_shour.currentText()
self.add_data["sm_stime2"] = self.combo_smin.currentText()
self.add_data["sm_etime1"] = self.combo_ehour.currentText()
self.add_data["sm_etime2"] = self.combo_emin.currentText()
self.add_data["sp_date1"] = (
self.date_schedule_dayrange.date()
).toString("yyyy-MM-dd")
self.add_data["sp_date2"] = (
self.date_schedule_dayrange.date()
).toString("yyyy-MM-dd")
self.add_data["sm_repeat_gubun"] = "A"
self.add_data["sm_open"] = "지사?"
self.add_data["sm_open_dept_hidden"] = "33"
self.add_data["sm_memo"] = self.text_schedule_memo.toPlainText()
self.add_data["sp_stime1"] = self.combo_shour.currentText()
self.add_data["sp_stime2"] = self.combo_smin.currentText()
self.add_data["sp_etime1"] = self.combo_ehour.currentText()
self.add_data["sp_etime2"] = self.combo_emin.currentText()
self.add_data["sm_write_type"] = "S"
driver = self.InitDriver()
driver = self.GWLogin(driver)
cookies = driver.get_cookies()
with requests.Session() as sess:
for cookie in cookies:
sess.cookies.set(cookie["name"], cookie["value"])
sess.post(
"http://gw.{yourdomain}.co.kr/groupware/schedule/schedule_write.php?mode=writeAct",
data=self.add_data,
)
# pprint(self.add_data)
self.tray.showMessage(
"일정 등록", "일정 등록 완료", self.icon, 3000, # Title # Content
)
self.hide()
def SetWidgets(self):
self.line_schedule_title.setText("제목 ")
self.date_schedule_dayrange.setDateTime(QDateTime.currentDateTime())
self.text_schedule_memo.setHtml(
self._translate(
"Form",
'<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">\n'
'<html><head><meta name="qrichtext" content="1" /><style type="text/css">\n'
"p, li { white-space: pre-wrap; }\n"
"</style></head><body style=\" font-family:'Gulim'; font-size:9pt; font-weight:400; font-style:normal;\">\n"
'<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">1:</p>\n'
'<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">2:</p>\n'
'<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">3:</p></body></html>',
)
)
def Notification(self, data):
# 3 title
# 5 stime
# 6 etime
# 7 date
# 9 content
# pprint(data)
if data is not False:
self.tray.showMessage(
data[7]
+ " "
+ self.GetDoW(data[7])
+ " "
+ data[5]
+ "~"
+ data[6]
+ "\r\n"
+ data[3],
data[9],
self.icon,
3000, # Title # Content
)
elif data is False:
self.tray.showMessage(
"일정 조회", "새로운 일정 없음", self.icon, 3000, # Title # Content
)
def InitDB(self):
ddb = boto3.resource(
service_name="dynamodb",
region_name="{your_region}",
aws_access_key_id="{key}",
aws_secret_access_key="{key2}",
)
table = ddb.Table("schedule_data")
return table
def InitDriver(self):
options = webdriver.ChromeOptions()
options.add_argument("headless")
options.add_argument("window-size=1920x1080")
options.add_argument("disable-gpu")
options.add_argument("--no-proxy-server")
if platform.system() == "Windows":
current_folder = os.path.realpath(
os.path.abspath(
os.path.split(inspect.getfile(inspect.currentframe()))[0]
)
)
driver_path = os.path.join(current_folder, "chromedriver.exe")
elif platform.system() == "Linux":
current_folder = os.path.dirname(os.path.realpath(__file__))
driver_path = os.path.join(current_folder, "chromedriver")
driver = webdriver.Chrome(driver_path, options=options)
return driver
def GWLogin(self, driver):
driver.get("http://gw.{yourdomain}.co.kr")
driver.find_element_by_xpath('//*[@id="gw_user_id"]').send_keys("{your_gw_id}")
driver.find_element_by_xpath('//*[@id="gw_user_pw"]').send_keys(
"{your_gw_pw}"
)
driver.find_element_by_xpath('//*[@id="loginBtn"]').click()
return driver
def GetDoW(self, date):
year, month, day = date.split("-")
r = datetime(int(year), int(month), int(day)).weekday()
return self.dow[r]
def InsertSchedule(self, table, data):
try:
reps = table.get_item(Key={"schedule_day_idx": data[0]})
item = reps["Item"]
print("overlap")
except KeyError:
for i, key in enumerate(self.data.keys()):
self.data[key] = data[i]
with table.batch_writer() as batch:
batch.put_item(Item=self.data)
self.Notification(data)
self.insert_cnt += 1
print("not overlap")
def AddSchedule(self):
self.SetWidgets()
self.show()
def ClickedCancelBtn(self):
self.hide()
def CheckSchedule(self):
threading.Timer(3600, self.CheckSchedule).start()
driver = self.InitDriver()
driver = self.GWLogin(driver)
cookies = driver.get_cookies()
table = self.InitDB()
with requests.Session() as sess:
for cookie in cookies:
sess.cookies.set(cookie["name"], cookie["value"])
for r in range(-day_range, day_range):
year, month, day = (
(datetime.now() + timedelta(days=r)).year,
(datetime.now() + timedelta(days=r)).month,
(datetime.now() + timedelta(days=r)).day,
)
html = sess.get(
f"http://gw.{your_domain}.co.kr/chtml/groupware/schedule.php?mode=dayAct&sdate={year}-{month}-{day}&sm_gubun=&sm_gubun_remarks=&my_schedule="
)
dumps = json.loads(json.dumps(xmltodict.parse(html.text)))
try:
datas = list()
for cnt in range(len(dumps["result"]["schedule_daylist"])):
if 12 <= len(dumps["result"]["schedule_daylist"]):
for i, text in enumerate(
dumps["result"]["schedule_daylist"].values()
):
if text is None:
datas.append("")
else:
datas.append(text)
self.InsertSchedule(table, datas)
break
elif 12 > len(dumps["result"]["schedule_daylist"]):
for i, text in enumerate(
dumps["result"]["schedule_daylist"][
cnt
].values()
):
if text is None:
datas.append("")
else:
datas.append(text)
if (i + 1) % 12 == 0:
self.InsertSchedule(table, datas)
datas.clear()
else:
pass
except KeyError:
pass
if self.insert_cnt == 0:
self.tray.showMessage(
"일정 조회", "새로운 일정 없음", self.icon, 3000, # Title # Content
)
self.insert_cnt = 0
driver.quit()
def SetPalette():
darkPalette = QPalette()
darkPalette.setColor(QPalette.WindowText, QColor(180, 180, 180))
darkPalette.setColor(QPalette.Button, QColor(53, 53, 53))
darkPalette.setColor(QPalette.Light, QColor(180, 180, 180))
darkPalette.setColor(QPalette.Midlight, QColor(90, 90, 90))
darkPalette.setColor(QPalette.Dark, QColor(35, 35, 35))
darkPalette.setColor(QPalette.Text, QColor(180, 180, 180))
darkPalette.setColor(QPalette.BrightText, QColor(180, 180, 180))
darkPalette.setColor(QPalette.ButtonText, QColor(180, 180, 180))
darkPalette.setColor(QPalette.Base, QColor(42, 42, 42))
darkPalette.setColor(QPalette.Window, QColor(53, 53, 53))
darkPalette.setColor(QPalette.Shadow, QColor(20, 20, 20))
darkPalette.setColor(QPalette.Highlight, QColor(42, 130, 218))
darkPalette.setColor(QPalette.HighlightedText, QColor(180, 180, 180))
darkPalette.setColor(QPalette.Link, QColor(56, 252, 196))
darkPalette.setColor(QPalette.AlternateBase, QColor(66, 66, 66))
darkPalette.setColor(QPalette.ToolTipBase, QColor(53, 53, 53))
darkPalette.setColor(QPalette.ToolTipText, QColor(180, 180, 180))
darkPalette.setColor(QPalette.LinkVisited, QColor(80, 80, 80))
return darkPalette
if __name__ == "__main__":
app = QApplication(sys.argv)
app.setStyle("Fusion")
app.setPalette(SetPalette())
with open(
r"C:\dev\python\Books\crawling2\resources\style.qss"
) as stylesheet:
app.setStyleSheet(stylesheet.read())
ex = Main()
sys.exit(app.exec_())
'Python > PyQt5' 카테고리의 다른 글
PyQt5 Designer 설치 및 사용방법 (0) | 2020.07.07 |
---|---|
Python PyQt5 DICOM 8bit Pixel Load(PyQt5로 DICOM Pixel 데이터 로드) (0) | 2019.09.30 |
댓글
티스토리 방명록
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
Blog is powered by
Tistory / Designed by
Tistory
Contact: j0n9m1n1@gmail.com
Contact: j0n9m1n1@gmail.com