Skip to content

Commit

Permalink
feat: import from opml (#96)
Browse files Browse the repository at this point in the history
  • Loading branch information
versun authored Aug 30, 2024
1 parent 7313e2e commit 2676132
Show file tree
Hide file tree
Showing 5 changed files with 91 additions and 1 deletion.
17 changes: 17 additions & 0 deletions core/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from django.contrib.auth.models import User, Group
from django.utils.html import format_html
from django.utils.translation import gettext_lazy as _
from django.urls import path, reverse

from .models import O_Feed, T_Feed
from .custom_admin_site import core_admin_site
Expand All @@ -19,6 +20,7 @@
)
from .tasks import update_original_feed, update_translated_feed
from utils.modelAdmin_utils import valid_icon
from .views import import_opml


class O_FeedAdmin(admin.ModelAdmin):
Expand All @@ -40,6 +42,21 @@ class O_FeedAdmin(admin.ModelAdmin):
actions = [o_feed_force_update, o_feed_export_as_opml, o_feed_batch_modify]
list_per_page = 20

def get_urls(self):
urls = super().get_urls()
custom_urls = [
path('import_opml/', self.admin_site.admin_view(import_opml), name='core_o_feed_import_opml'),
]
return custom_urls + urls

def changelist_view(self, request, extra_context=None):
extra_context = extra_context or {}
extra_context['import_opml_button'] = format_html(
'<a class="button" href="{}">导入OPML</a>',
reverse('admin:core_o_feed_import_opml')
)
return super().changelist_view(request, extra_context=extra_context)

def save_formset(self, request, form, formset, change):
instances = formset.save(commit=False)
for instance in instances:
Expand Down
1 change: 1 addition & 0 deletions core/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,6 @@
path("category/<str:category>/", views.category, name="category"),
path("json/<str:feed_sid>", views.rss_json, name="json"),
path("json/<str:feed_sid>/", views.rss_json, name="json"),
path('core/o_feed/import_opml/', views.import_opml, name='import_opml'),
re_path(r"(?P<feed_sid>[^/]+)/?$", views.rss, name="rss"),
]
31 changes: 31 additions & 0 deletions core/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,40 @@
from django.views.decorators.cache import cache_page
from django.views.decorators.http import condition
from .models import T_Feed, O_Feed
from django.shortcuts import redirect
from django.contrib import messages
from django.core.files.uploadedfile import InMemoryUploadedFile
from opyml import OPML
from django.utils.translation import gettext_lazy as _

from utils.feed_action import merge_all_atom, check_file_path

def import_opml(request):
if request.method == 'POST':
opml_file = request.FILES.get('opml_file')
if opml_file and isinstance(opml_file, InMemoryUploadedFile):
try:
opml_content = opml_file.read().decode('utf-8')
opml = OPML.from_xml(opml_content)

for outline in opml.body.outlines:
category = outline.text
#category, _ = Category.objects.get_or_create(name=category_name)

for feed in outline.outlines:
O_Feed.objects.create(
name=feed.title or feed.text,
feed_url=feed.xml_url,
category=category
)

messages.success(request, _("OPML file imported successfully."))
except Exception as e:
messages.error(request, _("Error importing OPML file: {}").format(str(e)))
else:
messages.error(request, _("Please upload a valid OPML file."))

return redirect('admin:core_o_feed_changelist')

def get_modified(request, feed_sid):
try:
Expand Down
2 changes: 1 addition & 1 deletion templates/admin/base_site.html
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@
<div id="footer" style="text-align: center;">
<a href="https://rsstranslator.com" title="RSS Translator">RSS Translator</a> ·
<a href="https://afdian.com/a/versun" title="Donate">Donate</a> ·
Version: <span data-version="2024.8.21">2024.8.21</span>
Version: <span data-version="2024.8.30">2024.8.30</span>
<svg id="update-button" class="svg-icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" onclick="checkUpdate()">
<title>Check Updates</title>
<path d="M783.568 328C724.571 241.095 624.953 184 512 184c-181.15 0-328 146.85-328 328h-72c0-220.914 179.086-400 400-400 135.738 0 255.685 67.611 328 170.994V128c0-8.837 7.163-16 16-16h48a8 8 0 0 1 8 8v248c0 17.673-14.327 32-32 32H632a8 8 0 0 1-8-8v-48c0-8.837 7.163-16 16-16h143.568zM240.432 696C299.429 782.905 399.047 840 512 840c181.15 0 328-146.85 328-328h72c0 220.914-179.086 400-400 400-135.738 0-255.685-67.611-328-170.994V896c0 8.837-7.163 16-16 16h-48a8 8 0 0 1-8-8V656c0-17.673 14.327-32 32-32h248a8 8 0 0 1 8 8v48c0 8.837-7.163 16-16 16H240.432z"/>
Expand Down
41 changes: 41 additions & 0 deletions templates/admin/core/o_feed/change_list.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
{% extends "admin/change_list.html" %}
{% load i18n admin_urls %}

{% block object-tools-items %}
{{ block.super }}
<li>
{{ import_opml_button }}
</li>
{% endblock %}

{% block content %}
<div id="import-opml-modal" class="modal" style="display: none;">
<div class="modal-content">
<h2>{% trans "Import OPML" %}</h2>
<form method="post" action="{% url 'admin:core_o_feed_import_opml' %}" enctype="multipart/form-data">
{% csrf_token %}
<input type="file" name="opml_file" accept=".opml,.xml">
<input type="submit" value="{% trans 'Import' %}">
</form>
</div>

</div>
{{ block.super }}
<script>
document.addEventListener('DOMContentLoaded', function() {
var importButton = document.querySelector('a[href="{% url 'admin:core_o_feed_import_opml' %}"]');
var modal = document.getElementById('import-opml-modal');

importButton.addEventListener('click', function(e) {
e.preventDefault();
modal.style.display = 'block';
});

window.onclick = function(event) {
if (event.target == modal) {
modal.style.display = "none";
}
}
});
</script>
{% endblock %}

0 comments on commit 2676132

Please sign in to comment.