You've already forked hotpocket
BTHLABS-66: Prepping for public release: Take four
Apple gonna Apple... ;)
This commit is contained in:
@@ -27,7 +27,7 @@ COPY --chown=$APP_USER_UID:$APP_USER_GID packages/common/ /srv/packages/common/
|
||||
COPY --chown=$APP_USER_UID:$APP_USER_GID packages/soa/ /srv/packages/soa/
|
||||
|
||||
RUN poetry install --only main,deployment && \
|
||||
minify -i --css-precision 0 --js-precision 0 --js-version 2022 hotpocket_backend/apps/ui/static/ui/css/hotpocket-backend*.css hotpocket_backend/apps/ui/static/ui/js/hotpocket*.js && \
|
||||
minify -i --css-precision 0 --js-precision 0 --js-version 2022 hotpocket_backend/apps/ui/static/ui/css/hotpocket-backend*.css hotpocket_backend/apps/ui/static/ui/js/hotpocket-backend*.js && \
|
||||
./manage.py collectstatic --settings hotpocket_backend.settings.deployment.build --noinput && \
|
||||
find hotpocket_backend/static/ -name "*.map*" -delete && \
|
||||
rm -f hotpocket_backend/settings/deployment/build.py && \
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
from .access_token import AccessToken # noqa: F401
|
||||
from .account import AccountAdmin # noqa: F401
|
||||
from .auth_key import AuthKey # noqa: F401
|
||||
|
||||
@@ -2,16 +2,41 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from django.contrib import admin
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from hotpocket_backend.apps.accounts.models import AccessToken
|
||||
|
||||
|
||||
class AccessTokenAdmin(admin.ModelAdmin):
|
||||
list_display = ('pk', 'account_uuid', 'origin', 'created_at', 'is_active')
|
||||
list_display = (
|
||||
'pk', 'account_uuid', 'origin', 'created_at', 'render_is_active',
|
||||
)
|
||||
search_fields = ('pk', 'account_uuid', 'key', 'origin')
|
||||
readonly_fields = (
|
||||
'pk',
|
||||
'account_uuid',
|
||||
'key',
|
||||
'origin',
|
||||
'meta',
|
||||
'created_at',
|
||||
'deleted_at',
|
||||
)
|
||||
ordering = ['-created_at']
|
||||
|
||||
def has_change_permission(self, request, obj=None):
|
||||
return False
|
||||
|
||||
def has_delete_permission(self, request, obj=None):
|
||||
return request.user.is_superuser
|
||||
|
||||
@admin.display(
|
||||
description=_('Is Active?'), boolean=True, ordering='-deleted_at',
|
||||
)
|
||||
def render_is_active(self, obj: AccessToken | None = None) -> bool | None:
|
||||
if obj is None:
|
||||
return None
|
||||
|
||||
return obj.is_active
|
||||
|
||||
|
||||
admin.site.register(AccessToken, AccessTokenAdmin)
|
||||
|
||||
@@ -3,15 +3,26 @@ from __future__ import annotations
|
||||
|
||||
from django.contrib import admin
|
||||
from django.contrib.auth.admin import UserAdmin
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from hotpocket_backend.apps.accounts.models import Account
|
||||
|
||||
|
||||
class AccountAdmin(UserAdmin):
|
||||
list_display = (*UserAdmin.list_display, 'is_active')
|
||||
list_display = (*UserAdmin.list_display, 'render_is_active')
|
||||
ordering = ['username']
|
||||
|
||||
def has_delete_permission(self, request, obj=None):
|
||||
return request.user.is_superuser
|
||||
|
||||
@admin.display(
|
||||
description=_('Is Active?'), boolean=True, ordering='-is_active',
|
||||
)
|
||||
def render_is_active(self, obj: Account | None = None) -> bool | None:
|
||||
if obj is None:
|
||||
return None
|
||||
|
||||
return obj.is_active
|
||||
|
||||
|
||||
admin.site.register(Account, AccountAdmin)
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import annotations
|
||||
|
||||
from django.contrib import admin
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from hotpocket_backend.apps.accounts.models import AuthKey
|
||||
|
||||
|
||||
class AuthKeyAdmin(admin.ModelAdmin):
|
||||
list_display = (
|
||||
'pk', 'account_uuid', 'key', 'created_at', 'consumed_at', 'render_is_active',
|
||||
)
|
||||
search_fields = ('pk', 'account_uuid', 'key')
|
||||
readonly_fields = (
|
||||
'pk',
|
||||
'account_uuid',
|
||||
'key',
|
||||
'consumed_at',
|
||||
'created_at',
|
||||
'deleted_at',
|
||||
)
|
||||
ordering = ['-created_at']
|
||||
|
||||
def has_change_permission(self, request, obj=None):
|
||||
return False
|
||||
|
||||
def has_delete_permission(self, request, obj=None):
|
||||
return request.user.is_superuser
|
||||
|
||||
@admin.display(
|
||||
description=_('Is Active?'), boolean=True, ordering='-deleted_at',
|
||||
)
|
||||
def render_is_active(self, obj: AuthKey | None = None) -> bool | None:
|
||||
if obj is None:
|
||||
return None
|
||||
|
||||
return obj.is_active
|
||||
|
||||
|
||||
admin.site.register(AuthKey, AuthKeyAdmin)
|
||||
@@ -1 +1,2 @@
|
||||
from . import association # noqa: F401
|
||||
from . import save # noqa: F401
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import annotations
|
||||
|
||||
from django.contrib import admin
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from hotpocket_backend.apps.saves.models import Association
|
||||
|
||||
|
||||
class AssociationAdmin(admin.ModelAdmin):
|
||||
list_display = (
|
||||
'pk', 'account_uuid', 'target', 'created_at', 'render_is_active',
|
||||
)
|
||||
search_fields = ('pk', 'account_uuid')
|
||||
fields = (
|
||||
'pk',
|
||||
'account_uuid',
|
||||
'archived_at',
|
||||
'starred_at',
|
||||
'target_meta',
|
||||
'target_title',
|
||||
'target_description',
|
||||
'created_at',
|
||||
'deleted_at',
|
||||
)
|
||||
readonly_fields = (
|
||||
'pk',
|
||||
'account_uuid',
|
||||
'target_meta',
|
||||
'target',
|
||||
'archived_at',
|
||||
'starred_at',
|
||||
'created_at',
|
||||
'deleted_at',
|
||||
)
|
||||
ordering = ['-created_at']
|
||||
|
||||
def has_delete_permission(self, request, obj=None):
|
||||
return request.user.is_superuser
|
||||
|
||||
@admin.display(
|
||||
description=_('Is Active?'), boolean=True, ordering='-deleted_at',
|
||||
)
|
||||
def render_is_active(self, obj: Association | None = None) -> bool | None:
|
||||
if obj is None:
|
||||
return None
|
||||
|
||||
return obj.is_active
|
||||
|
||||
|
||||
admin.site.register(Association, AssociationAdmin)
|
||||
@@ -11,6 +11,26 @@ class SaveAdmin(admin.ModelAdmin):
|
||||
list_display = (
|
||||
'pk', 'key', 'account_uuid', 'created_at', 'render_is_active',
|
||||
)
|
||||
search_fields = ('pk', 'account_uuid', 'url')
|
||||
fields = (
|
||||
'pk',
|
||||
'account_uuid',
|
||||
'key',
|
||||
'url',
|
||||
'title',
|
||||
'description',
|
||||
'last_processed_at',
|
||||
'is_netloc_banned',
|
||||
'created_at',
|
||||
'deleted_at',
|
||||
)
|
||||
readonly_fields = (
|
||||
'pk',
|
||||
'account_uuid',
|
||||
'key',
|
||||
'created_at',
|
||||
'deleted_at',
|
||||
)
|
||||
ordering = ['-created_at']
|
||||
|
||||
def has_delete_permission(self, request, obj=None):
|
||||
|
||||
@@ -45,7 +45,6 @@
|
||||
return null;
|
||||
}
|
||||
onLoad = (event) => {
|
||||
console.log('HotPocketApp.onLoad()', event);
|
||||
for (let pluginSpec of this.plugins) {
|
||||
if (pluginSpec[1].onLoad) {
|
||||
pluginSpec[1].onLoad(event);
|
||||
|
||||
@@ -130,6 +130,56 @@
|
||||
{% translate 'Log out' %}
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item px-3 d-flex justify-content-center">
|
||||
{% spaceless %}
|
||||
<a
|
||||
class="btn btn-outline-info btn-sm"
|
||||
href="https://apps.apple.com/pl/app/hotpocket-by-bthlabs/id6752321380"
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
title="{% translate 'Safari and Share extension for iOS and macOS' %}"
|
||||
>
|
||||
<i class="bi bi-apple"></i>
|
||||
</a>
|
||||
<a
|
||||
class="btn btn-outline-info btn-sm ms-1"
|
||||
href="https://chromewebstore.google.com/detail/save-to-hotpocket/mkmoejhhgnadmijpgkkioicjmikkkjbd"
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
title="{% translate 'Chrome extension' %}"
|
||||
>
|
||||
<i class="bi bi-browser-chrome"></i>
|
||||
</a>
|
||||
<a
|
||||
class="btn btn-outline-info btn-sm ms-1"
|
||||
href="https://addons.mozilla.org/en-GB/firefox/addon/save-to-hotpocket/"
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
title="{% translate 'Firefox extension' %}"
|
||||
>
|
||||
<i class="bi bi-browser-firefox"></i>
|
||||
</a>
|
||||
<a
|
||||
class="btn btn-outline-info btn-sm ms-1"
|
||||
data-bs-toggle="modal"
|
||||
data-bs-target="#modalPWA"
|
||||
href="#"
|
||||
title="{% translate 'Android PWA' %}"
|
||||
>
|
||||
<i class="bi bi-android2"></i>
|
||||
</a>
|
||||
<div class="vr my-1 ms-1 opacity-75"></div>
|
||||
<a
|
||||
class="btn btn-outline-info btn-sm ms-1"
|
||||
href="https://git.bthlabs.pl/tomekwojcik/hotpocket"
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
title="{% translate 'Source code repository' %}"
|
||||
>
|
||||
<i class="bi bi-git"></i>
|
||||
</a>
|
||||
{% endspaceless %}
|
||||
</li>
|
||||
{% else %}
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="{% url 'ui.accounts.login' %}">
|
||||
@@ -142,6 +192,38 @@
|
||||
{% include "ui/ui/partials/uname.html" %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% if not request.user.is_anonymous %}
|
||||
<div class="modal modal-fade" id="modalPWA" tabindex="-1">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h1 class="modal-title fs-5" id="modalPWALabel">
|
||||
{% translate 'HotPocket on Android and others' %}
|
||||
</h1>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p class="mb-1">
|
||||
{% blocktranslate %}
|
||||
HotPocket doesn't natively support Android and other systems. However, it's a Progressive Web Application. You can install it from your browser and it'll register itself as share target.
|
||||
{% endblocktranslate %}
|
||||
</p>
|
||||
<p class="mb-0">
|
||||
{% blocktranslate %}
|
||||
This is currently supported on Android and Windows 11 (when installed using Edge).
|
||||
{% endblocktranslate %}
|
||||
</p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-primary" data-bs-dismiss="modal">
|
||||
{% translate 'Cool' %}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
{% block scripts %}
|
||||
|
||||
@@ -27,9 +27,6 @@ def page_not_found(request: HttpRequest,
|
||||
exception: Exception,
|
||||
template_name: str = ERROR_404_TEMPLATE_NAME,
|
||||
) -> HttpResponseNotFound:
|
||||
if exception:
|
||||
LOGGER.error('Exception: %s', exception, exc_info=exception)
|
||||
|
||||
return HttpResponseNotFound(render_to_string(
|
||||
'ui/errors/page_not_found.html',
|
||||
context={},
|
||||
|
||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user