Skip to content

[fix][cloudkitty]Add code for optimized download rating PDF file #188

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 3, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 8 additions & 3 deletions dingo_command/api/cloudkitty.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from typing import List

from fastapi.responses import FileResponse
from urllib.parse import unquote
from starlette.background import BackgroundTask
from dingo_command.api.model.cloudkitty import CloudKittyRatingSummaryDetail
from dingo_command.services.cloudkitty import CloudKittyService
Expand Down Expand Up @@ -56,7 +57,7 @@ async def download_rating_summary_execl(begin: str = Query(None, description="
)
raise HTTPException(status_code=400, detail="Execl file not found")

@router.post("/cloudkitty/download/ratingSummaryDetail/pdf", summary="下载计费汇总详情PDF", description="下载计费汇总详情PDF")
@router.post("/cloudkitty/download/ratingSummaryDetail/pdf/preprocessing", summary="预处理下载计费汇总详情需要的PDF文件", description="预处理下载计费汇总详情需要的PDF文件")
async def download_rating_summary_detail_pdf(detail: List[CloudKittyRatingSummaryDetail],
language: str = Query(None, description="当前环境语言")):
result_file_pdf_name = "rating_summary_detail_" + format_d8q_timestamp() + ".pdf"
Expand All @@ -66,18 +67,22 @@ async def download_rating_summary_detail_pdf(detail: List[CloudKittyRatingSummar
# 1. 生成PDF文件
try:
cloudkitty_service.download_rating_summary_detail_pdf(result_file_pdf_path, detail, language)
return os.path.basename(result_file_pdf_path)
except Exception as e:
import traceback
traceback.print_exc()
file_utils.cleanup_temp_file(result_file_pdf_path)
raise HTTPException(status_code=400, detail="generate pdf file error")

@router.get("/cloudkitty/download/ratingSummaryDetail/pdf", summary="下载计费汇总详情PDF", description="下载计费汇总详情PDF")
async def download_rating_summary_detail_pdf(filePath: str = Query(None, description="下载PDF文件名称")):
# 文件存在则下载
if os.path.exists(result_file_pdf_path):
result_file_pdf_path = EXCEL_TEMP_DIR + unquote(filePath)
if filePath is not None and os.path.exists(result_file_pdf_path):
return FileResponse(
path=result_file_pdf_path,
media_type="application/octet-stream",
filename=result_file_pdf_name, # 下载时显示的文件名
filename=unquote(filePath), # 下载时显示的文件名
background=BackgroundTask(file_utils.cleanup_temp_file, result_file_pdf_path)
)
raise HTTPException(status_code=400, detail="PDf file not found")
Expand Down
3 changes: 2 additions & 1 deletion dingo_command/api/model/cloudkitty.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ class FlavorObject(BaseModel):

class CloudKittyRatingSummaryDetail(BaseModel):
service: Optional[str] = Field(None, description="服务类型")
tenant_id: Optional[str] = Field(None, description="租户ID")
tenant_id: Optional[str] = Field(None, description="项目ID")
tenant_name: Optional[str] = Field(None, description="项目名称")
end: Optional[str] = Field(None, description="结束时间")
total: Optional[str] = Field(None, description="总计")
flavor: Optional[List[FlavorObject]] = Field(None, description="描述信息")
3 changes: 2 additions & 1 deletion dingo_command/common/cloudkitty_client.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import json
import uuid
from datetime import datetime, timedelta
from oslo_utils import timeutils
from functools import wraps

import requests
Expand Down Expand Up @@ -46,7 +47,7 @@ def _is_token_valid(cls):
print(f"cloudkitty client single instance id: {instance._singleton_instance_uuid}, token[{instance._current_token}]无效,token过期阈值:{cls.TOKEN_EXPIRY_THRESHOLD}")
return False

remaining_time = instance._token_expiry - datetime.utcnow()
remaining_time = instance._token_expiry - timeutils.utcnow()
#print(f"cloudkitty client single instance id: {instance._singleton_instance_uuid}, token[{instance._current_token}]剩余时间:{remaining_time}, token过期阈值:{cls.TOKEN_EXPIRY_THRESHOLD}, 当前token是否有效:{remaining_time > cls.TOKEN_EXPIRY_THRESHOLD}")
return remaining_time > cls.TOKEN_EXPIRY_THRESHOLD

Expand Down
3 changes: 2 additions & 1 deletion dingo_command/common/ironic_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
# self.region_name = region_name
import uuid
from datetime import datetime, timedelta
from oslo_utils import timeutils
from functools import wraps
import requests

Expand Down Expand Up @@ -47,7 +48,7 @@ def _is_token_valid(cls):
print(f"ironic client single instance id: {instance._singleton_instance_uuid}, token[{instance._current_token}]无效,token过期阈值:{cls.TOKEN_EXPIRY_THRESHOLD}")
return False

remaining_time = instance._token_expiry - datetime.utcnow()
remaining_time = instance._token_expiry - timeutils.utcnow()
#print(f"ironic client single instance id: {instance._singleton_instance_uuid}, token[{instance._current_token}]剩余时间:{remaining_time}, token过期阈值:{cls.TOKEN_EXPIRY_THRESHOLD}, 当前token是否有效:{remaining_time > cls.TOKEN_EXPIRY_THRESHOLD}")
return remaining_time > cls.TOKEN_EXPIRY_THRESHOLD

Expand Down
17 changes: 12 additions & 5 deletions dingo_command/services/cloudkitty.py
Original file line number Diff line number Diff line change
Expand Up @@ -166,10 +166,17 @@ def generate_rating_summary_detail_data(self, ratingSummaryDetailList, language)
temp_data = []
# 项目ID
tenant_id = None if ratingSummaryDetailList is None else ratingSummaryDetailList[0].tenant_id
tenant_name = None if ratingSummaryDetailList is None else ratingSummaryDetailList[0].tenant_name
if language is None or language == "EN":
temp_data.append({'Tenant ID': tenant_id})
if tenant_name is None:
temp_data.append({'Tenant ID': tenant_id})
else:
temp_data.append({'Tenant Name': tenant_name})
else:
temp_data.append({'项目ID':tenant_id})
if tenant_name is None:
temp_data.append({'项目ID':tenant_id})
else:
temp_data.append({'项目名称':tenant_name})
# 开始时间
begin_datatime = None if ratingSummaryDetailList is None or ratingSummaryDetailList[0].flavor is None \
or ratingSummaryDetailList[0].flavor is None or ratingSummaryDetailList[0].flavor[0] is None \
Expand Down Expand Up @@ -209,11 +216,11 @@ def generate_rating_summary_detail_data(self, ratingSummaryDetailList, language)
temp_instance_flavor_data.append({'instance':ratingSummaryDetail.total})
if ratingSummaryDetail.flavor is not None:
if language is None or language == "EN":
temp_instance_flavor_data.append({'VM Type': 'Rate'})
temp_instance_flavor_data.append({' VM Type': 'Rate'})
else:
temp_instance_flavor_data.append({'云主机类型': '费率'})
temp_instance_flavor_data.append({' 云主机类型': '费率'})
for flavor in ratingSummaryDetail.flavor:
temp_instance_flavor_data.append({flavor.flavor_name: flavor.rate})
temp_instance_flavor_data.append({" " + flavor.flavor_name: flavor.rate})
else:
temp_non_instance_data.append({ratingSummaryDetail.service:ratingSummaryDetail.total})

Expand Down