Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/feature/cafeteria-1' into featur…
Browse files Browse the repository at this point in the history
…e/deploy
  • Loading branch information
Cycrypto committed Jun 5, 2024
2 parents 2abff6a + d135807 commit 7115272
Show file tree
Hide file tree
Showing 3 changed files with 98 additions and 66 deletions.
4 changes: 4 additions & 0 deletions sandol/api_server/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,10 @@ async def wrapper(*args, **kwargs):
tip = Restaurant.by_id("001")
registration_time = get_last_saved_date(file_path)

# 시간대 변환
tip.registration_time = tip.registration_time.astimezone(tz=KST)
registration_time = registration_time.astimezone(tz=KST)

if registration_time < last_wednesday:
must_download = True
else:
Expand Down
105 changes: 57 additions & 48 deletions sandol/crawler/cafeteria.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
"""
Restaurant(class): 산돌이에 입점한 식당의 정보를 담는 클래스를 정의하는 모듈입니다.
get_meals(): s3 버킷에 저장된 data를 json파일로 변환 후 식당의 이름 정보로 식당의 객체를 생성합니다.
"""
import os
import json
import datetime as dt
Expand All @@ -10,31 +14,38 @@


class Restaurant:
"""식당 정보를 담고 메뉴 정보를 추가, 수정, 등록, 삭제하기 위해 사용됩니다.
Restaurant.by_id() 메서드 호출과 동시에 id와 매칭된 식당의 이름으로 객체가 생성됩니다.
메뉴 정보 수정 용 메서드: add_menu, delete_menu, clear_menu
식당 정보 반환 용 메서드: submit
"""
def __init__(self, name, lunch, dinner, location, registration):
self.registration_time = registration
self.opening_time = []
self.name = name
self.lunch = lunch
self.dinner = dinner
self.location = location
self.price_per_person = 0
self.temp_lunch = []
self.temp_dinner = []
self.final_menu = []
self.registration_time = registration # 점주가 식당 메뉴를 등록한 시간(datetime)
self.opening_time = [] # 식당 개점 시간(datetime)
self.name = name # 식당 이름 정보(str)
self.lunch = lunch # 식당 점심 메뉴 정보(list)
self.dinner = dinner # 식당 저녁 메뉴 정보(list)
self.location = location # 식당 위치 정보 - 교내/외(str)
self.price_per_person = 0 # 식당 1인분 가격 정보
self.temp_lunch = [] # 식당 점심 메뉴 수정 용 임시 메뉴 저장 리스트
self.temp_dinner = [] # 식당 저녁 메뉴 수정 용 임시 메뉴 저장 리스트

self.rest_info()

@classmethod
def by_dict(cls, data):
"""
주어진 데이터 딕셔너리로부터 Restaurant 객체를 생성합니다.
get_meals()에서 사용합니다.
"""
registration_time = dt.datetime.fromisoformat(
data["registration_time"])
class_name = f"{data['name']}"
new_class = type(class_name, (Restaurant,), {})

return new_class(data["name"], data["lunch_menu"], data["dinner_menu"], data["location"], registration_time)
return new_class(data["name"], data["lunch_menu"], data["dinner_menu"],
data["location"], registration_time)

@classmethod
def by_id(cls, id_address):
Expand All @@ -56,7 +67,6 @@ def by_id(cls, id_address):
# id 검사
if restaurant_data["identification"] == id_address:
return cls.by_dict(restaurant_data)

else:
raise ValueError(f"해당 식당을 찾을 수 없습니다. ID: '{id_address}'")

Expand Down Expand Up @@ -114,22 +124,18 @@ def add_menu(self, meal_time, menu):
"meal_time should be a string 'lunch' or 'dinner'.")

if meal_time.lower() == "lunch":
if menu in self.temp_lunch:
raise ValueError("해당 메뉴는 이미 메뉴 목록에 존재합니다.")
else:
if menu not in self.temp_lunch:
self.temp_lunch.append(menu)
self.save_temp_menu()
raise ValueError("해당 메뉴는 이미 메뉴 목록에 존재합니다.")

elif meal_time.lower() == "dinner":
if menu in self.temp_dinner:
raise ValueError("해당 메뉴는 이미 메뉴 목록에 존재합니다.")
else:
if meal_time.lower() == "dinner":
if menu not in self.temp_dinner:
self.temp_dinner.append(menu)
self.save_temp_menu()
raise ValueError("해당 메뉴는 이미 메뉴 목록에 존재합니다.")

else:
raise ValueError("meal_time should be 'lunch' or 'dinner'.")

# save temp_menu.json
self.save_temp_menu()
raise ValueError("meal_time should be 'lunch' or 'dinner'.")

def delete_menu(self, meal_time, menu):
"""
Expand All @@ -143,20 +149,16 @@ def delete_menu(self, meal_time, menu):
if meal_time.lower() == "lunch":
if menu in self.temp_lunch:
self.temp_lunch.remove(menu)
else:
raise ValueError("해당 메뉴는 등록되지 않은 메뉴입니다.")
self.save_temp_menu()
raise ValueError("해당 메뉴는 등록되지 않은 메뉴입니다.")

elif meal_time.lower() == "dinner":
if meal_time.lower() == "dinner":
if menu in self.temp_dinner:
self.temp_dinner.remove(menu)
else:
raise ValueError("해당 메뉴는 등록되지 않은 메뉴입니다.")

else:
raise ValueError("meal_time should be 'lunch' or 'dinner'.")
self.save_temp_menu()
raise ValueError("해당 메뉴는 등록되지 않은 메뉴입니다.")

# save temp_menu.json
self.save_temp_menu()
raise ValueError("meal_time should be 'lunch' or 'dinner'.")

def clear_menu(self):
"""
Expand Down Expand Up @@ -206,15 +208,14 @@ def submit_update_menu(self, menu_type):
"""
if menu_type == "lunch" and self.temp_lunch:
return self.temp_lunch
elif menu_type == "dinner" and self.temp_dinner:
if menu_type == "dinner" and self.temp_dinner:
return self.temp_dinner

def submit(self):
"""
temp_menu.json 파일의 "lunch", "dinner" 데이터에 변화가 생길 때
원본 test.json 파일에 덮어씀, 동시에 self.temp_menu 초기화.
"""
# TODO(Seokyoung_Hong): S3용으로 수정 필요
filename = os.path.join('/tmp', 'test.json')

# read and write
Expand All @@ -223,17 +224,22 @@ def submit(self):
data = json.load(file)
except json.decoder.JSONDecodeError:
data = []
except FileNotFoundError:
raise FileNotFoundError(f"{filename} 파일을 찾을 수 없습니다.")
except FileNotFoundError as e:
raise FileNotFoundError(f"{filename} 파일을 찾을 수 없습니다.") from e

restaurant_found = False
for restaurant_data in data:
if restaurant_data["name"] == self.name: # 식당 검색
restaurant_data["lunch_menu"] = self.submit_update_menu("lunch") # 점심 메뉴 변경 사항 존재 시 submit
restaurant_data["dinner_menu"] = self.submit_update_menu("dinner") # 저녁 메뉴 변경 사항 존재 시 submit
restaurant_data["registration_time"] = dt.datetime.now().isoformat() # registration time update
restaurant_data["opening_time"] = self.opening_time # opining time update
restaurant_data["price_per_person"] = self.price_per_person # 가격 update
if restaurant_data["name"] == self.name: # 식당 검색
restaurant_data["lunch_menu"] = self.submit_update_menu(
"lunch") # 점심 메뉴 변경 사항 존재 시 submit
restaurant_data["dinner_menu"] = self.submit_update_menu(
"dinner") # 저녁 메뉴 변경 사항 존재 시 submit
restaurant_data["registration_time"] = dt.datetime.now(
).isoformat() # registration time update
# opining time update
restaurant_data["opening_time"] = self.opening_time
# 가격 update
restaurant_data["price_per_person"] = self.price_per_person
restaurant_found = True
break

Expand Down Expand Up @@ -265,6 +271,11 @@ def __str__(self):


async def get_meals() -> list:
"""
bucket에서 서비스중인 식당 목록을 불러옴
각 식당의 identification 코드를 조회하여 인증
인증된 식당일 경우 식당의 이름으로 Restaurant 객체 반환
"""
download_path = '/tmp/test.json' # 임시 경로에 파일 다운로드

download_file_from_s3(BUCKET_NAME, FILE_KEY, download_path)
Expand All @@ -278,9 +289,7 @@ async def get_meals() -> list:


if __name__ == "__main__":
# rests = get_meals()
# print(rests)
identification = "001" # 001: TIP 가가식당
rest = Restaurant.by_id(identification)
ID = "001" # 001: TIP 가가식당
rest = Restaurant.by_id(ID)

print(rest)
55 changes: 37 additions & 18 deletions sandol/crawler/ibookcrawler.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,22 @@
import datetime as dt
import pandas as pd
""" ibookdownloader.py에서 다운로드 한 data.xlsx 파일을 사용가능한 정보로 가공하는 모듈이다.
현재 한국공학대학교 TIP, E동 식당의 주간 식당메뉴 정보를 가공, 반환한다.
"""

import json
import os
import math
import datetime as dt
import pandas as pd

from crawler.settings import KST
from bucket.common import download_file_from_s3, BUCKET_NAME, FILE_KEY, upload_file_to_s3


class BookTranslator:
"""
ibookDownloader.py에서 다운로드한 'data.xlsx'을 토대로
TIP, E동 식당의 식당 정보를 포함한 객체를 반환한다.
"""
def __init__(self):
self.identification = ""
self.name = ""
Expand Down Expand Up @@ -51,7 +59,7 @@ def tip_save_menu(self, weekday):
"""
self.tip_lunch_menu = list(self.df.iloc[6:12, weekday]) # data.xlsx file 내 1열 8행~13행
for menu in self.tip_lunch_menu:
if menu == '*복수메뉴*':
if menu == '*복수메뉴*': # *복수메뉴* 글자 제거
self.tip_lunch_menu.remove(menu)

self.tip_dinner_menu = list(self.df.iloc[13:19, weekday]) # data.xlsx file 내 1열 15행~20행
Expand All @@ -70,15 +78,21 @@ def e_save_menu(self, weekday):
self.e_dinner_menu = list(self.df.iloc[30:37, weekday]) # data.xlsx file 내 1열 32행~38행

def save_tip_info(self):
self.save_menu("TIP") # restaurant = "TIP" -> tip_save_menu()
"""
TIP식당의 식당정보 저장 메서드
"""
self.save_menu("TIP") # restaurant = "TIP" -> tip_save_menu()
self.identification = "001"
self.name = "TIP 가가식당"
self.opening_time = "오전 11시-2시 / 오후 5시-6:50"
self.location = "TIP 지하 1층"
self.price_per_person = 6000

def save_e_info(self):
self.save_menu("E") # restaurant = "E" -> e_save_menu()
"""
E동 식당의 식당정보 저장 메서드
"""
self.save_menu("E") # restaurant = "E" -> e_save_menu()
self.identification = "002"
self.name = "E동 레스토랑"
self.opening_time = "오전 11:30-13:50 / 오후 4:50-18:40"
Expand All @@ -105,9 +119,6 @@ def submit_tip_info(self):
"price_per_person": self.price_per_person
}

current_dir = os.path.dirname(__file__)
filename = os.path.join(current_dir, 'test.json')

# S3에서 파일 다운로드
download_path = '/tmp/test.json'
try:
Expand Down Expand Up @@ -135,7 +146,8 @@ def submit_tip_info(self):
for restaurant in data:
for key, value in restaurant.items():
if isinstance(value, list):
restaurant[key] = [item for item in value if not (isinstance(item, float) and math.isnan(item))]
restaurant[key] = [item for item in value if not (isinstance(item, float)
and math.isnan(item))]

# 임시 파일에 데이터 저장
with open(download_path, 'w', encoding='utf-8') as file:
Expand Down Expand Up @@ -165,17 +177,18 @@ def submit_e_info(self):
"price_per_person": self.price_per_person
}

current_dir = os.path.dirname(__file__)
filename = os.path.join(current_dir, 'test.json')

# read and write
# S3에서 파일 다운로드
download_path = '/tmp/test.json'
try:
with open(filename, 'r', encoding='utf-8') as file:
download_file_from_s3(BUCKET_NAME, FILE_KEY, download_path)
with open(download_path, 'r', encoding='utf-8') as file:
data = json.load(file)
if not isinstance(data, list):
data = []
except FileNotFoundError:
data = []
except json.decoder.JSONDecodeError:
data = []
except FileNotFoundError:
raise FileNotFoundError(f"{filename} 파일을 찾을 수 없습니다.")

restaurant_found = False
for restaurant_data in data:
Expand All @@ -191,11 +204,17 @@ def submit_e_info(self):
for restaurant in data:
for key, value in restaurant.items():
if isinstance(value, list):
restaurant[key] = [item for item in value if not (isinstance(item, float) and math.isnan(item))]
restaurant[key] = [item for item in value if not (isinstance(item, float)
and math.isnan(item))]

with open(filename, 'w', encoding='utf-8') as file:
# 임시 파일에 데이터 저장
with open(download_path, 'w', encoding='utf-8') as file:
json.dump(data, file, ensure_ascii=False, indent=4)

# S3에 업로드
upload_file_to_s3(download_path, BUCKET_NAME, FILE_KEY)
print(f"File {FILE_KEY} uploaded to S3 bucket {BUCKET_NAME}")


if __name__ == "__main__":
ibook = BookTranslator()
Expand Down

0 comments on commit 7115272

Please sign in to comment.