mirror of
https://github.com/ArchiveBox/ArchiveBox
synced 2024-11-22 12:13:05 +00:00
add uri salt and fix api url namespaces
This commit is contained in:
parent
fba3995d86
commit
4d0bbfccfc
6 changed files with 55 additions and 22 deletions
|
@ -73,6 +73,10 @@ class ABID(NamedTuple):
|
||||||
rand=suffix[20:26].upper(),
|
rand=suffix[20:26].upper(),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def uri_salt(self) -> str:
|
||||||
|
return DEFAULT_ABID_URI_SALT
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def suffix(self):
|
def suffix(self):
|
||||||
return ''.join((self.ts, self.uri, self.subtype, self.rand))
|
return ''.join((self.ts, self.uri, self.subtype, self.rand))
|
||||||
|
|
|
@ -63,7 +63,7 @@ api = NinjaAPIWithIOCapture(
|
||||||
version='1.0.0',
|
version='1.0.0',
|
||||||
csrf=False,
|
csrf=False,
|
||||||
auth=API_AUTH_METHODS,
|
auth=API_AUTH_METHODS,
|
||||||
urls_namespace="api",
|
urls_namespace="api-1",
|
||||||
docs=Swagger(settings={"persistAuthorization": True}),
|
docs=Swagger(settings={"persistAuthorization": True}),
|
||||||
# docs_decorator=login_required,
|
# docs_decorator=login_required,
|
||||||
# renderer=ORJSONRenderer(),
|
# renderer=ORJSONRenderer(),
|
||||||
|
|
|
@ -33,7 +33,7 @@ class ArchiveResultSchema(Schema):
|
||||||
snapshot_tags: str
|
snapshot_tags: str
|
||||||
|
|
||||||
extractor: str
|
extractor: str
|
||||||
cmd_version: str
|
cmd_version: Optional[str]
|
||||||
cmd: List[str]
|
cmd: List[str]
|
||||||
pwd: str
|
pwd: str
|
||||||
status: str
|
status: str
|
||||||
|
@ -93,16 +93,16 @@ class ArchiveResultFilterSchema(FilterSchema):
|
||||||
created__lt: Optional[datetime] = Field(None, q='updated__lt')
|
created__lt: Optional[datetime] = Field(None, q='updated__lt')
|
||||||
|
|
||||||
|
|
||||||
@router.get("/archiveresults", response=List[ArchiveResultSchema])
|
@router.get("/archiveresults", response=List[ArchiveResultSchema], url_name="get_archiveresult")
|
||||||
@paginate
|
@paginate
|
||||||
def list_archiveresults(request, filters: ArchiveResultFilterSchema = Query(...)):
|
def get_archiveresults(request, filters: ArchiveResultFilterSchema = Query(...)):
|
||||||
"""List all ArchiveResult entries matching these filters."""
|
"""List all ArchiveResult entries matching these filters."""
|
||||||
qs = ArchiveResult.objects.all()
|
qs = ArchiveResult.objects.all()
|
||||||
results = filters.filter(qs)
|
results = filters.filter(qs)
|
||||||
return results
|
return results
|
||||||
|
|
||||||
|
|
||||||
@router.get("/archiveresult/{archiveresult_id}", response=ArchiveResultSchema)
|
@router.get("/archiveresult/{archiveresult_id}", response=ArchiveResultSchema, url_name="get_archiveresult")
|
||||||
def get_archiveresult(request, archiveresult_id: str):
|
def get_archiveresult(request, archiveresult_id: str):
|
||||||
"""Get a specific ArchiveResult by abid, uuid, or pk."""
|
"""Get a specific ArchiveResult by abid, uuid, or pk."""
|
||||||
return ArchiveResult.objects.get(Q(pk__icontains=archiveresult_id) | Q(abid__icontains=archiveresult_id) | Q(uuid__icontains=archiveresult_id))
|
return ArchiveResult.objects.get(Q(pk__icontains=archiveresult_id) | Q(abid__icontains=archiveresult_id) | Q(uuid__icontains=archiveresult_id))
|
||||||
|
@ -211,9 +211,9 @@ class SnapshotFilterSchema(FilterSchema):
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@router.get("/snapshots", response=List[SnapshotSchema])
|
@router.get("/snapshots", response=List[SnapshotSchema], url_name="get_snapshots")
|
||||||
@paginate
|
@paginate
|
||||||
def list_snapshots(request, filters: SnapshotFilterSchema = Query(...), with_archiveresults: bool=True):
|
def get_snapshots(request, filters: SnapshotFilterSchema = Query(...), with_archiveresults: bool=True):
|
||||||
"""List all Snapshot entries matching these filters."""
|
"""List all Snapshot entries matching these filters."""
|
||||||
request.with_archiveresults = with_archiveresults
|
request.with_archiveresults = with_archiveresults
|
||||||
|
|
||||||
|
@ -221,7 +221,7 @@ def list_snapshots(request, filters: SnapshotFilterSchema = Query(...), with_arc
|
||||||
results = filters.filter(qs)
|
results = filters.filter(qs)
|
||||||
return results
|
return results
|
||||||
|
|
||||||
@router.get("/snapshot/{snapshot_id}", response=SnapshotSchema)
|
@router.get("/snapshot/{snapshot_id}", response=SnapshotSchema, url_name="get_snapshot")
|
||||||
def get_snapshot(request, snapshot_id: str, with_archiveresults: bool=True):
|
def get_snapshot(request, snapshot_id: str, with_archiveresults: bool=True):
|
||||||
"""Get a specific Snapshot by abid, uuid, or pk."""
|
"""Get a specific Snapshot by abid, uuid, or pk."""
|
||||||
request.with_archiveresults = with_archiveresults
|
request.with_archiveresults = with_archiveresults
|
||||||
|
@ -286,6 +286,6 @@ class TagSchema(Schema):
|
||||||
def resolve_created_by_id(obj):
|
def resolve_created_by_id(obj):
|
||||||
return str(obj.created_by_id)
|
return str(obj.created_by_id)
|
||||||
|
|
||||||
@router.get("/tags", response=List[TagSchema])
|
@router.get("/tags", response=List[TagSchema], url_name="get_tags")
|
||||||
def list_tags(request):
|
def get_tags(request):
|
||||||
return Tag.objects.all()
|
return Tag.objects.all()
|
||||||
|
|
|
@ -168,28 +168,31 @@ def get_abid_info(self, obj):
|
||||||
return format_html(
|
return format_html(
|
||||||
# URL Hash: <code style="font-size: 10px; user-select: all">{}</code><br/>
|
# URL Hash: <code style="font-size: 10px; user-select: all">{}</code><br/>
|
||||||
'''
|
'''
|
||||||
DB ID: <code style="font-size: 16px; user-select: all; border-radius: 8px; background-color: #fdd; padding: 1px 4px; border: 1px solid #aaa; margin-bottom: 14px;"><b>{}</b></code><br/>
|
DB ID: <code style="font-size: 16px; user-select: all; border-radius: 8px; background-color: #fdd; padding: 1px 4px; border: 1px solid #aaa; margin-bottom: 8px; display: inline-block; vertical-align: top;"><b>{}</b></code><br/>
|
||||||
.id: <code style="font-size: 10px; user-select: all">{}</code> <br/>
|
.id: <code style="font-size: 10px; user-select: all">{}</code> <br/>
|
||||||
.uuid: <code style="font-size: 10px; user-select: all">{}</code> <br/>
|
.uuid: <code style="font-size: 10px; user-select: all">{}</code> <br/>
|
||||||
<br/>
|
<br/>
|
||||||
<div style="opacity: 0.8">
|
<div style="opacity: 0.8">
|
||||||
ABID: <code style="font-size: 16px; user-select: all; border-radius: 8px; background-color: #fdd; padding: 1px 4px; border: 1px solid #aaa; margin-bottom: 14px;"><b>{}</b></code><br/>
|
ABID: <small style="opacity: 0.5">{}_</small><code style="font-size: 16px; user-select: all; border-radius: 8px; background-color: #ddf; padding: 1px 4px; border: 1px solid #aaa; margin-bottom: 8px; display: inline-block; vertical-align: top;"><b>{}</b></code> <a href="{}" style="font-size: 1.5em; font-family: monospace;">/api/v1 GET JSON</a> <a href="{}" style="color: limegreen; font-size: 1.2em; vertical-align: 1px; font-family: monospace;">API DOCS</a><br/>
|
||||||
TS: <code style="font-size: 10px; user-select: all"><b>{}</b></code> ({})<br/>
|
TS: <code style="font-size: 10px; user-select: all"><b>{}</b></code> ({})<br/>
|
||||||
URI: <code style="font-size: 10px; user-select: all"><b>{}</b></code> ({})<br/>
|
URI: <code style="font-size: 10px; user-select: all"><b>{}</b></code> (<span style="display:inline-block; vertical-align: -4px; user-select: all; width: 230px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;">{}</span>)<br/>
|
||||||
SUBTYPE: <code style="font-size: 10px; user-select: all"><b>{}</b></code> ({})
|
SUBTYPE: <code style="font-size: 10px; user-select: all"><b>{}</b></code> ({})
|
||||||
RAND: <code style="font-size: 10px; user-select: all"><b>{}</b></code> ({})<br/><hr/>
|
RAND: <code style="font-size: 10px; user-select: all"><b>{}</b></code> ({})
|
||||||
<small style="opacity: 0.8">as ULID: <code style="font-size: 10px; user-select: all">{}</code></small><br/>
|
SALT: <code style="font-size: 10px; user-select: all"><b style="display:inline-block; user-select: all; width: 50px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;">{}</b></code>
|
||||||
<small style="opacity: 0.8">as UUID: <code style="font-size: 10px; user-select: all">{}</code></small><br/><br/>
|
<br/><hr/>
|
||||||
|
<small style="opacity: 0.8">.ulid: <code style="font-size: 10px; user-select: all">{}</code></small><br/>
|
||||||
|
<small style="opacity: 0.8">.uuid: <code style="font-size: 10px; user-select: all">{}</code></small><br/><br/>
|
||||||
</div>
|
</div>
|
||||||
''',
|
''',
|
||||||
obj.pk,
|
obj.pk,
|
||||||
obj.id,
|
obj.id,
|
||||||
obj.uuid,
|
obj.uuid,
|
||||||
obj.abid,
|
*obj.abid.split('_', 1), obj.api_url, obj.api_docs_url,
|
||||||
obj.ABID.ts, obj.abid_values['ts'].isoformat() if isinstance(obj.abid_values['ts'], datetime) else obj.abid_values['ts'],
|
obj.ABID.ts, obj.abid_values['ts'].isoformat() if isinstance(obj.abid_values['ts'], datetime) else obj.abid_values['ts'],
|
||||||
obj.ABID.uri, str(obj.abid_values['uri']),
|
obj.ABID.uri, str(obj.abid_values['uri']),
|
||||||
obj.ABID.subtype, str(obj.abid_values['subtype']),
|
obj.ABID.subtype, str(obj.abid_values['subtype']),
|
||||||
obj.ABID.rand, str(obj.abid_values['rand'])[-7:],
|
obj.ABID.rand, str(obj.abid_values['rand'])[-7:],
|
||||||
|
obj.ABID.uri_salt,
|
||||||
obj.ABID.ulid,
|
obj.ABID.ulid,
|
||||||
obj.ABID.uuid,
|
obj.ABID.uuid,
|
||||||
)
|
)
|
||||||
|
|
|
@ -14,7 +14,7 @@ from django.db import models
|
||||||
from django.utils.functional import cached_property
|
from django.utils.functional import cached_property
|
||||||
from django.utils.text import slugify
|
from django.utils.text import slugify
|
||||||
from django.core.cache import cache
|
from django.core.cache import cache
|
||||||
from django.urls import reverse
|
from django.urls import reverse, reverse_lazy
|
||||||
from django.db.models import Case, When, Value, IntegerField
|
from django.db.models import Case, When, Value, IntegerField
|
||||||
from django.contrib.auth.models import User # noqa
|
from django.contrib.auth.models import User # noqa
|
||||||
|
|
||||||
|
@ -104,6 +104,15 @@ class Tag(ABIDModel):
|
||||||
else:
|
else:
|
||||||
return super().save(*args, **kwargs)
|
return super().save(*args, **kwargs)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def api_url(self) -> str:
|
||||||
|
# /api/v1/core/snapshot/{uulid}
|
||||||
|
return reverse_lazy('api-1:get_tag', args=[self.abid])
|
||||||
|
|
||||||
|
@property
|
||||||
|
def api_docs_url(self) -> str:
|
||||||
|
return f'/api/v1/docs#/Core%20Models/api_v1_core_get_tag'
|
||||||
|
|
||||||
|
|
||||||
class Snapshot(ABIDModel):
|
class Snapshot(ABIDModel):
|
||||||
abid_prefix = 'snp_'
|
abid_prefix = 'snp_'
|
||||||
|
@ -168,6 +177,15 @@ class Snapshot(ABIDModel):
|
||||||
def icons(self) -> str:
|
def icons(self) -> str:
|
||||||
return snapshot_icons(self)
|
return snapshot_icons(self)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def api_url(self) -> str:
|
||||||
|
# /api/v1/core/snapshot/{uulid}
|
||||||
|
return reverse_lazy('api-1:get_snapshot', args=[self.abid])
|
||||||
|
|
||||||
|
@property
|
||||||
|
def api_docs_url(self) -> str:
|
||||||
|
return f'/api/v1/docs#/Core%20Models/api_v1_core_get_snapshot'
|
||||||
|
|
||||||
@cached_property
|
@cached_property
|
||||||
def extension(self) -> str:
|
def extension(self) -> str:
|
||||||
from ..util import extension
|
from ..util import extension
|
||||||
|
@ -353,6 +371,14 @@ class ArchiveResult(ABIDModel):
|
||||||
def snapshot_dir(self):
|
def snapshot_dir(self):
|
||||||
return Path(self.snapshot.link_dir)
|
return Path(self.snapshot.link_dir)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def api_url(self) -> str:
|
||||||
|
# /api/v1/core/archiveresult/{uulid}
|
||||||
|
return reverse_lazy('api-1:get_archiveresult', args=[self.abid])
|
||||||
|
|
||||||
|
@property
|
||||||
|
def api_docs_url(self) -> str:
|
||||||
|
return f'/api/v1/docs#/Core%20Models/api_v1_core_get_archiveresult'
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def extractor_module(self):
|
def extractor_module(self):
|
||||||
|
|
|
@ -38,7 +38,7 @@ urlpatterns = [
|
||||||
path('accounts/', include('django.contrib.auth.urls')),
|
path('accounts/', include('django.contrib.auth.urls')),
|
||||||
path('admin/', archivebox_admin.urls),
|
path('admin/', archivebox_admin.urls),
|
||||||
|
|
||||||
path("api/", include('api.urls')),
|
path("api/", include('api.urls'), name='api'),
|
||||||
|
|
||||||
path('health/', HealthCheckView.as_view(), name='healthcheck'),
|
path('health/', HealthCheckView.as_view(), name='healthcheck'),
|
||||||
path('error/', lambda *_: 1/0),
|
path('error/', lambda *_: 1/0),
|
||||||
|
|
Loading…
Reference in a new issue