Cizz22 2 months ago
parent 5325679ba7
commit d969059f22

10
Jenkinsfile vendored

@ -61,6 +61,16 @@ pipeline {
"""
}
}
// stage('Watchtower Deployment') {
// steps {
// sh """
// # Push both tags
// docker push ${DOCKER_HUB_USERNAME}/${IMAGE_NAME}:${GIT_COMMIT_HASH}
// docker push ${DOCKER_HUB_USERNAME}/${IMAGE_NAME}:latest
// """
// }
// }
// stage('Deploy') {
// steps {

@ -53,24 +53,60 @@ from .utils import fetch_all_sections, get_google_creds, get_spreatsheed_service
async def get_gantt_performance_chart(*, spreadsheet_id = "1gZXuwA97zU1v4QBv56wKeiqadc6skHUucGKYG8qVFRk"):
creds = get_google_creds()
RANGE_NAME = "'2024 kurva s'!N79:BJ83" # Or just "2024 schedule"
GANTT_DATA_NAME = "2024 schedule"
RANGE_NAME = "'SUMMARY'!I28:AZ32" # Or just "2024 schedule"
GANTT_DATA_NAME = "ACTUAL PROGRESS"
try:
service = get_spreatsheed_service(creds)
sheet = service.spreadsheets()
response = sheet.values().get(spreadsheetId=spreadsheet_id, range=RANGE_NAME).execute()
response = sheet.values().get(
spreadsheetId=spreadsheet_id,
range=RANGE_NAME
).execute()
values = response.get("values", [])
keys = ['day', 'time', 'plan', 'actual', 'gap']
transposed = list(zip(*values))
results = [dict(zip(keys, result)) for result in transposed]
if len(values) < 4:
raise Exception("Spreadsheet format invalid: need 4 rows (DAY, DATE, PLAN, ACTUAL).")
# Extract rows
day_row = values[0][1:]
date_row = values[1][1:]
plan_row = values[3][1:]
actual_row = values[4][1:]
total_days = len(day_row)
# PAD rows so lengths match day count
date_row += [""] * (total_days - len(date_row))
plan_row += [""] * (total_days - len(plan_row))
actual_row += [""] * (total_days - len(actual_row))
results = []
for i in range(total_days):
day = day_row[i]
date = date_row[i]
plan = plan_row[i]
actual = actual_row[i] if actual_row[i] else "0%" # <-- FIX HERE
results.append({
"day": day,
"date": date,
"plan": plan,
"actual": actual
})
except Exception as e:
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=e)
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))
processed_data = process_spreadsheet_data(results)
gantt_data = fetch_all_sections(service=service, spreadsheet_id=spreadsheet_id, sheet_name=GANTT_DATA_NAME)
return processed_data, gantt_data

@ -22,53 +22,81 @@ def process_spreadsheet_data(rows):
processed_data = []
for row in rows:
processed_row = convert_spreadsheet_data(row)
processed_data.append(processed_row)
processed_data.append(processed_row) if processed_row else None
return processed_data
def convert_spreadsheet_data(data):
from datetime import datetime
from datetime import datetime
def convert_spreadsheet_data(data, default_year=None):
"""
Convert spreadsheet row into structured data.
Expected keys: day, date, plan, actual
"""
# Skip header or invalid rows
if not data.get("day") or not data["day"].isdigit():
return None
result = {}
# Convert day to integer
result['day'] = int(data['day'])
# Convert time to a datetime object
from datetime import datetime
# Assuming Indonesian format with month names
# Replace Indonesian month names with English if needed
month_mapping = {
'Januari': 'January', 'Februari': 'February', 'Maret': 'March',
'April': 'April', 'Mei': 'May', 'Juni': 'June',
'Juli': 'July', 'Agustus': 'August', 'September': 'September',
'Oktober': 'October', 'November': 'November', 'Desember': 'December'
}
# Convert day
result["day"] = int(data["day"])
# Determine default year
if default_year is None:
default_year = datetime.now().year
date_str = data.get("date", "").strip()
# ---------- DATE HANDLING ----------
# Accept formats like: "Nov 20", "Dec 3", "Jan 1"
parsed_date = None
time_str = data['time']
for indo, eng in month_mapping.items():
time_str = time_str.replace(indo, eng)
# Format: "Sabtu, Juli 13, 2024" -> "Saturday, July 13, 2024"
# Removing the day of week to simplify parsing
time_str = time_str.split(', ', 1)[1] # Remove "Sabtu, "
result['time'] = datetime.strptime(time_str, '%B %d, %Y')
# Convert percentage strings to floats
# Handling format like "0,12%" -> 0.12
for key in ['plan', 'actual', 'gap']:
# Replace comma with dot (European to US decimal notation)
value = data[key].replace(',', '.')
# Remove percentage sign
value = value.rstrip('%')
# Convert to float
result[key] = float(value) / 100 # Divide by 100 to get the actual decimal value
if date_str:
try:
parsed_date = datetime.strptime(f"{date_str} {default_year}", "%b %d %Y")
except ValueError:
try:
parsed_date = datetime.strptime(f"{date_str} {default_year}", "%B %d %Y")
except:
parsed_date = None
# YEAR ROLLOVER (Dec → Jan next year)
if parsed_date and parsed_date.month == 1 and "Dec" in data.get("date", ""):
parsed_date = parsed_date.replace(year=default_year + 1)
result["date"] = parsed_date
# ---------- PERCENT HANDLING ----------
def parse_percent(value):
if not value:
return 0.0
v = value.strip().replace(",", ".").replace("%", "")
try:
return float(v) / 100.0
except:
return 0.0
result["plan"] = parse_percent(data.get("plan", "0"))
result["actual"] = parse_percent(data.get("actual", "0"))
# Gap calculation
result["gap"] = result["actual"] - result["plan"]
return result
def fetch_all_sections(service, spreadsheet_id, sheet_name):
# Fetch a wide range including columns AL
result = service.spreadsheets().values().get(
spreadsheetId=spreadsheet_id,
range=f"{sheet_name}!A18:1000" # start from row 19, adjust Z if needed
range=f"{sheet_name}!A5:M5000"
).execute()
values = result.get("values", [])
if not values:
raise ValueError("No data found in sheet")
@ -78,50 +106,92 @@ def fetch_all_sections(service, spreadsheet_id, sheet_name):
current_subsystem = None
for i, row in enumerate(values):
row = [c.strip() for c in row] # clean whitespace
for row in values:
# Pad missing columns to avoid index errors
row += [""] * (13 - len(row))
# Skip completely empty rows
if all(c == "" for c in row):
continue
colA, colB, colC, colD, colE, colF, colG, colH, colI, colJ, colK, colL, colM = row
# Detect section headers (usually in col A, all caps)
if row[0]:
# skip unwanted section title
if row[0] == "U4 PLANNED OUTAGE 2024":
continue
current_section = row[0]
# Detect a SECTION — bold blue rows in Column C
if colC and not colD and not colE:
current_section = colC.strip()
current_subsystem = None
header = None
continue
# Detect subsystem (non-all-caps in col A)
if row[1]:
current_subsystem = row[1]
# Detect a SUBSYSTEM — indented header in Column D
if colD and not colE:
current_subsystem = colD.strip()
continue
# Otherwise, treat as task row (must have header defined)
if row[2]:
task = row[2]
pic = row[3]
start_date = row[4]
finish_date = row[5]
duration = row[6]
plan = row[7]
actual = row[8]
gap = row[9]
# Detect a TASK — Column E populated
if colE:
task = colE.strip()
pic = colF.strip()
start_date = indo_formatted_date(colG.strip())
finish_date = indo_formatted_date(colH.strip())
duration = colI.strip()
plan = colK.strip()
actual = colL.strip()
gap = colM.strip()
data.append({
"system": current_section,
"section": current_section,
"subsystem": current_subsystem,
"task": task,
"PIC": pic,
"start_date": start_date,
"end_date": finish_date,
"duration": duration,
"duration": int(duration),
"plan": plan,
"actual": actual,
"gap": gap
})
return data
return data
def indo_formatted_date(date_str, base_year=2025):
"""
Convert short date like 'Nov 20', '30-Dec', 'Jan 1'
into: 'Rabu, November 20, 2025'
If month is January, year becomes 2026.
"""
# Month mappings
eng_to_indo_month = {
"Jan": "Januari", "Feb": "Februari", "Mar": "Maret", "Apr": "April",
"May": "Mei", "Jun": "Juni", "Jul": "Juli", "Aug": "Agustus",
"Sep": "September", "Oct": "Oktober", "Nov": "November", "Dec": "Desember"
}
indo_days = {
0: "Senin",
1: "Selasa",
2: "Rabu",
3: "Kamis",
4: "Jumat",
5: "Sabtu",
6: "Minggu"
}
# Normalize formats ("30-Dec" → "Dec 30")
if "-" in date_str:
d, m = date_str.split("-")
date_str = f"{m} {d}"
# Parse using English abbreviation
try:
dt = datetime.strptime(f"{date_str} {base_year}", "%b %d %Y")
except:
return None
# Handle year rollover (Jan -> next year)
if dt.month == 1:
dt = dt.replace(year=base_year + 1)
# Convert to Indonesian components
day_name = indo_days[dt.weekday()]
month_name = eng_to_indo_month[dt.strftime("%b")]
return f"{day_name}, {month_name} {dt.day}, {dt.year}"
Loading…
Cancel
Save