Skip to content

Commit 714324b

Browse files
committed
REFACTOR :: slack block util 반영과 region alias 추가
1 parent 35dd9f5 commit 714324b

3 files changed

Lines changed: 138 additions & 2 deletions

File tree

monitor_v2/ec2/report.py

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,39 @@
3030
KST = timezone(timedelta(hours=9))
3131

3232
REGION_ALIAS = {
33-
'ap-northeast-2': '서울',
33+
# 아시아 태평양
3434
'ap-northeast-1': '도쿄',
35+
'ap-northeast-2': '서울',
36+
'ap-northeast-3': '오사카',
37+
'ap-southeast-1': '싱가포르',
38+
'ap-southeast-2': '시드니',
39+
'ap-southeast-3': '자카르타',
40+
'ap-southeast-4': '멜버른',
41+
'ap-south-1': '뭄바이',
42+
'ap-south-2': '하이데라바드',
43+
'ap-east-1': '홍콩',
44+
# 미주
3545
'us-east-1': '버지니아',
46+
'us-east-2': '오하이오',
47+
'us-west-1': '캘리포니아',
3648
'us-west-2': '오레곤',
49+
'ca-central-1': '캐나다',
50+
'ca-west-1': '캘거리',
51+
'sa-east-1': '상파울루',
52+
# 유럽
3753
'eu-west-1': '아일랜드',
54+
'eu-west-2': '런던',
55+
'eu-west-3': '파리',
3856
'eu-central-1': '프랑크푸르트',
39-
'ap-southeast-1': '싱가포르',
57+
'eu-central-2': '취리히',
58+
'eu-north-1': '스톡홀름',
59+
'eu-south-1': '밀라노',
60+
'eu-south-2': '스페인',
61+
# 중동 · 아프리카
62+
'me-south-1': '바레인',
63+
'me-central-1': 'UAE',
64+
'af-south-1': '케이프타운',
65+
'il-central-1': '텔아비브',
4066
}
4167

4268

monitor_v2/utils/__init__.py

Whitespace-only changes.

monitor_v2/utils/blocks.py

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
"""
2+
monitor_v2/utils/blocks.py
3+
4+
cost/report.py 와 ec2/report.py 가 공통으로 사용하는
5+
Block Kit 헬퍼, 계산/포맷 헬퍼, 공유 상수를 모아둔 모듈.
6+
"""
7+
8+
from slack_sdk.models.blocks import (
9+
HeaderBlock, SectionBlock, DividerBlock, ContextBlock,
10+
)
11+
from slack_sdk.models.blocks.basic_components import MarkdownTextObject, PlainTextObject
12+
13+
# ---------------------------------------------------------------------------
14+
# 공유 상수
15+
# ---------------------------------------------------------------------------
16+
17+
SEP = "─" * 60
18+
19+
EC2_SERVICES = {
20+
'Amazon Elastic Compute Cloud - Compute',
21+
'Amazon EC2',
22+
'EC2 - Other',
23+
}
24+
25+
_MD_BLOCK_MAX = 2800 # Slack 3000자 제한에서 여유분 확보
26+
27+
28+
# ---------------------------------------------------------------------------
29+
# Block Kit 헬퍼
30+
# ---------------------------------------------------------------------------
31+
32+
def header(text: str) -> HeaderBlock:
33+
"""굵고 큰 헤더. plain_text 전용, 150자 제한."""
34+
return HeaderBlock(text=PlainTextObject(text=text[:150]))
35+
36+
37+
def section(text: str) -> SectionBlock:
38+
"""mrkdwn 텍스트 섹션. 소제목 및 본문용."""
39+
return SectionBlock(text=MarkdownTextObject(text=text))
40+
41+
42+
def divider() -> DividerBlock:
43+
"""섹션 간 구분선."""
44+
return DividerBlock()
45+
46+
47+
def context(text: str) -> ContextBlock:
48+
"""보조 설명용 작은 mrkdwn 텍스트."""
49+
return ContextBlock(elements=[MarkdownTextObject(text=text)])
50+
51+
52+
def md_block(text: str) -> dict:
53+
"""Slack 신규 markdown 블록 — Markdown 테이블 렌더링 지원."""
54+
return {"type": "markdown", "text": text}
55+
56+
57+
def md_table_blocks(headers: list, rows: list) -> list:
58+
"""
59+
Markdown 테이블을 _MD_BLOCK_MAX 한도에 맞게 분할해 md_block 리스트로 반환.
60+
분할 시 각 블록마다 헤더 행을 반복 포함한다.
61+
62+
Args:
63+
headers: 열 헤더 리스트
64+
rows: 2차원 리스트 (각 행 = 헤더 길이와 동일한 셀 목록)
65+
"""
66+
header_text = (
67+
"| " + " | ".join(str(h) for h in headers) + " |\n"
68+
+ "| " + " | ".join(["---"] * len(headers)) + " |\n"
69+
)
70+
chunks, current, cur_len = [], [], len(header_text)
71+
for row in rows:
72+
line = "| " + " | ".join(str(c) for c in row) + " |"
73+
cost = len(line) + 1
74+
if current and cur_len + cost > _MD_BLOCK_MAX:
75+
chunks.append(current)
76+
current, cur_len = [], len(header_text)
77+
current.append(line)
78+
cur_len += cost
79+
if current:
80+
chunks.append(current)
81+
return [md_block(header_text + "\n".join(c)) for c in chunks] if chunks \
82+
else [md_block(header_text.rstrip())]
83+
84+
85+
def table_section(title: str, headers: list, rows: list) -> list:
86+
"""소제목 section + 전체 행 Markdown 테이블 블록 리스트."""
87+
return [section(title), *md_table_blocks(headers, rows)]
88+
89+
90+
# ---------------------------------------------------------------------------
91+
# 공통 계산 / 포맷 헬퍼
92+
# ---------------------------------------------------------------------------
93+
94+
def calc_change(today: float, compare: float) -> tuple:
95+
"""(delta, pct|None). compare=0이면 pct=None."""
96+
delta = today - compare
97+
pct = (delta / compare * 100.0) if compare else None
98+
return delta, pct
99+
100+
101+
def fmt_change(delta: float, pct) -> str:
102+
"""+$13.45 (+12.2%) 형식 문자열."""
103+
sign = '+' if delta >= 0 else ''
104+
d_str = f"{sign}${abs(delta):,.2f}" if delta >= 0 else f"-${abs(delta):,.2f}"
105+
if pct is None:
106+
suffix = '(신규)' if delta > 0 else '(중단)' if delta < 0 else ''
107+
else:
108+
s = '+' if pct >= 0 else ''
109+
suffix = f"({s}{pct:.1f}%)"
110+
return f"{d_str} {suffix}".strip()

0 commit comments

Comments
 (0)