migrated all pawprint work

This commit is contained in:
buenosairesam
2025-12-31 08:34:18 -03:00
parent fc63e9010c
commit 680969ca42
63 changed files with 4687 additions and 5 deletions

View File

@@ -0,0 +1,135 @@
"""
Ticket models with self-parsing from Jira objects.
"""
from pydantic import BaseModel
from typing import Optional, List
from datetime import datetime
class Attachment(BaseModel):
id: str
filename: str
mimetype: str
size: int # bytes
url: str
content_base64: Optional[str] = None # populated when include_attachments=true
@classmethod
def from_jira(cls, att) -> "Attachment":
return cls(
id=att.id,
filename=att.filename,
mimetype=att.mimeType,
size=att.size,
url=att.content,
)
class Ticket(BaseModel):
key: str
summary: str
description: Optional[str] = None
status: str
status_category: Optional[str] = None
issue_type: str
priority: Optional[str] = None
project: str
assignee: Optional[str] = None
reporter: Optional[str] = None
labels: List[str] = []
created: Optional[datetime] = None
updated: Optional[datetime] = None
url: str
parent_key: Optional[str] = None # For subtasks
@classmethod
def from_jira(cls, issue, base_url: str) -> "Ticket":
f = issue.fields
status_cat = None
if hasattr(f.status, "statusCategory"):
status_cat = f.status.statusCategory.name
# Get parent key for subtasks
parent = None
if hasattr(f, "parent") and f.parent:
parent = f.parent.key
return cls(
key=issue.key,
summary=f.summary or "",
description=f.description,
status=f.status.name,
status_category=status_cat,
issue_type=f.issuetype.name,
priority=f.priority.name if f.priority else None,
project=f.project.key,
assignee=f.assignee.displayName if f.assignee else None,
reporter=f.reporter.displayName if f.reporter else None,
labels=f.labels or [],
created=cls._parse_dt(f.created),
updated=cls._parse_dt(f.updated),
url=f"{base_url}/browse/{issue.key}",
parent_key=parent,
)
@staticmethod
def _parse_dt(val: Optional[str]) -> Optional[datetime]:
if not val:
return None
try:
return datetime.fromisoformat(val.replace("Z", "+00:00"))
except ValueError:
return None
class TicketDetail(Ticket):
comments: List[dict] = []
linked_issues: List[str] = []
subtasks: List[str] = []
attachments: List[Attachment] = []
@classmethod
def from_jira(cls, issue, base_url: str) -> "TicketDetail":
base = Ticket.from_jira(issue, base_url)
f = issue.fields
comments = []
if hasattr(f, "comment") and f.comment:
for c in f.comment.comments:
comments.append({
"author": c.author.displayName if hasattr(c, "author") else None,
"body": c.body,
"created": c.created,
})
linked = []
if hasattr(f, "issuelinks") and f.issuelinks:
for link in f.issuelinks:
if hasattr(link, "outwardIssue"):
linked.append(link.outwardIssue.key)
if hasattr(link, "inwardIssue"):
linked.append(link.inwardIssue.key)
subtasks = []
if hasattr(f, "subtasks") and f.subtasks:
subtasks = [st.key for st in f.subtasks]
attachments = []
if hasattr(f, "attachment") and f.attachment:
attachments = [Attachment.from_jira(a) for a in f.attachment]
return cls(
**base.model_dump(),
comments=comments,
linked_issues=linked,
subtasks=subtasks,
attachments=attachments,
)
class TicketList(BaseModel):
tickets: List[Ticket]
total: int
page: int
page_size: int