FossilRepo

fossilrepo / fossil / models.py
Blame History Raw 84 lines
1
from pathlib import Path
2
3
from django.db import models
4
5
from core.models import ActiveManager, Tracking
6
7
8
class FossilRepository(Tracking):
9
"""Links a Project to its on-disk .fossil SQLite file."""
10
11
project = models.OneToOneField("projects.Project", on_delete=models.CASCADE, related_name="fossil_repo")
12
filename = models.CharField(max_length=255, unique=True, help_text="Filename relative to FOSSIL_DATA_DIR")
13
file_size_bytes = models.BigIntegerField(default=0)
14
fossil_project_code = models.CharField(max_length=40, blank=True, default="")
15
last_checkin_at = models.DateTimeField(null=True, blank=True)
16
checkin_count = models.PositiveIntegerField(default=0)
17
18
# Remote sync
19
remote_url = models.URLField(blank=True, default="", help_text="Upstream remote URL for sync")
20
last_sync_at = models.DateTimeField(null=True, blank=True)
21
upstream_artifacts_available = models.PositiveIntegerField(default=0, help_text="New artifacts available from upstream")
22
23
# S3 tracking
24
s3_key = models.CharField(max_length=500, blank=True, default="")
25
s3_last_replicated_at = models.DateTimeField(null=True, blank=True)
26
27
objects = ActiveManager()
28
all_objects = models.Manager()
29
30
class Meta:
31
ordering = ["filename"]
32
verbose_name = "Fossil Repository"
33
verbose_name_plural = "Fossil Repositories"
34
35
def __str__(self):
36
return self.filename
37
38
@property
39
def full_path(self) -> Path:
40
from constance import config
41
42
return Path(config.FOSSIL_DATA_DIR) / self.filename
43
44
@property
45
def exists_on_disk(self) -> bool:
46
return self.full_path.exists()
47
48
49
class FossilSnapshot(Tracking):
50
"""Binary snapshot of a .fossil file stored via Django's file storage."""
51
52
repository = models.ForeignKey(FossilRepository, on_delete=models.CASCADE, related_name="snapshots")
53
file = models.FileField(upload_to="fossil_snapshots/%Y/%m/")
54
file_size_bytes = models.BigIntegerField(default=0)
55
fossil_hash = models.CharField(max_length=64, blank=True, default="", help_text="SHA-256 of the .fossil file")
56
note = models.CharField(max_length=200, blank=True, default="")
57
58
objects = ActiveManager()
59
all_objects = models.Manager()
60
61
class Meta:
62
ordering = ["-created_at"]
63
get_latest_by = "created_at"
64
65
def __str__(self):
66
return f"{self.repository.filename} @ {self.created_at:%Y-%m-%d %H:%M}" if self.created_at else self.repository.filename
67
68
69
# Import related models so they're discoverable by Django
70
from fossil.agent_claims import TicketClaim # noqa: E402, F401
71
from fossil.api_tokens import APIToken # noqa: E402, F401
72
from fossil.branch_protection import BranchProtection # noqa: E402, F401
73
from fossil.ci import StatusCheck # noqa: E402, F401
74
from fossil.code_reviews import CodeReview, ReviewComment # noqa: E402, F401
75
from fossil.forum import ForumPost # noqa: E402, F401
76
from fossil.notifications import Notification, NotificationPreference, ProjectWatch # noqa: E402, F401
77
from fossil.releases import Release, ReleaseAsset # noqa: E402, F401
78
from fossil.sync_models import GitMirror, SSHKey, SyncLog # noqa: E402, F401
79
from fossil.ticket_fields import TicketFieldDefinition # noqa: E402, F401
80
from fossil.ticket_reports import TicketReport # noqa: E402, F401
81
from fossil.user_keys import UserSSHKey # noqa: E402, F401
82
from fossil.webhooks import Webhook, WebhookDelivery # noqa: E402, F401
83
from fossil.workspaces import AgentWorkspace # noqa: E402, F401
84

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button