Support keword
This commit is contained in:
139
core/templates/admin/create_full_site_task.html
Normal file
139
core/templates/admin/create_full_site_task.html
Normal file
@@ -0,0 +1,139 @@
|
||||
{% extends "admin/base_site.html" %}
|
||||
{% load i18n admin_urls static admin_modify %}
|
||||
|
||||
{% block title %}{{ title }} | {{ site_title|default:_('Django site admin') }}{% endblock %}
|
||||
|
||||
{% block breadcrumbs %}
|
||||
<div class="breadcrumbs">
|
||||
<a href="{% url 'admin:index' %}">{% trans 'Home' %}</a>
|
||||
› <a href="{% url 'admin:core_crawltask_changelist' %}">爬取任务</a>
|
||||
› {{ title }}
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<h1>{{ title }}</h1>
|
||||
|
||||
<div class="help" style="background: #fff3cd; border: 1px solid #ffeaa7; padding: 15px; margin-bottom: 20px; border-radius: 5px;">
|
||||
<strong>注意:</strong>全站爬取会爬取整个网站的所有文章,可能需要很长时间。建议在非高峰时段进行。
|
||||
</div>
|
||||
|
||||
<form method="post" id="full-site-task-form">
|
||||
{% csrf_token %}
|
||||
|
||||
<fieldset class="module aligned">
|
||||
<h2>基本信息</h2>
|
||||
<div class="form-row">
|
||||
<div>
|
||||
<label for="id_name" class="required">任务名称:</label>
|
||||
<input type="text" name="name" id="id_name" required maxlength="200" style="width: 300px;">
|
||||
<p class="help">为这个全站爬取任务起一个容易识别的名称</p>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
<fieldset class="module aligned">
|
||||
<h2>目标网站</h2>
|
||||
<div class="form-row">
|
||||
<div>
|
||||
<label>选择要爬取的网站:</label>
|
||||
<div style="max-height: 200px; overflow-y: auto; border: 1px solid #ddd; padding: 10px; margin-top: 5px;">
|
||||
<label style="display: block; margin: 5px 0;">
|
||||
<input type="checkbox" id="select_all" onchange="toggleAllWebsites()">
|
||||
<strong>全选/取消全选</strong>
|
||||
</label>
|
||||
<hr style="margin: 10px 0;">
|
||||
{% for website in websites %}
|
||||
<label style="display: block; margin: 3px 0;">
|
||||
<input type="checkbox" name="websites" value="{{ website.name }}" class="website-checkbox">
|
||||
{{ website.name }}
|
||||
</label>
|
||||
{% endfor %}
|
||||
</div>
|
||||
<p class="help">不选择任何网站将爬取所有支持的网站</p>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
<fieldset class="module aligned">
|
||||
<h2>爬取设置</h2>
|
||||
<div class="form-row">
|
||||
<div>
|
||||
<label for="id_max_pages">最大爬取页数:</label>
|
||||
<input type="number" name="max_pages" id="id_max_pages" value="500" min="1" max="5000" style="width: 100px;">
|
||||
<p class="help">每个网站最多爬取的页数 (1-5000)</p>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
<div class="submit-row">
|
||||
<input type="submit" value="创建任务" class="default" name="_save">
|
||||
<a href="{% url 'admin:core_crawltask_changelist' %}" class="button cancel-link">取消</a>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<script>
|
||||
function toggleAllWebsites() {
|
||||
const selectAll = document.getElementById('select_all');
|
||||
const checkboxes = document.querySelectorAll('.website-checkbox');
|
||||
|
||||
checkboxes.forEach(checkbox => {
|
||||
checkbox.checked = selectAll.checked;
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.form-row {
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.form-row label {
|
||||
display: block;
|
||||
font-weight: bold;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.form-row input[type="text"],
|
||||
.form-row input[type="number"] {
|
||||
padding: 5px;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.form-row .help {
|
||||
color: #666;
|
||||
font-size: 12px;
|
||||
margin-top: 3px;
|
||||
}
|
||||
|
||||
.submit-row {
|
||||
margin-top: 20px;
|
||||
padding-top: 20px;
|
||||
border-top: 1px solid #ddd;
|
||||
}
|
||||
|
||||
.submit-row input[type="submit"] {
|
||||
background: #417690;
|
||||
color: white;
|
||||
padding: 10px 20px;
|
||||
border: none;
|
||||
border-radius: 3px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.submit-row .cancel-link {
|
||||
margin-left: 10px;
|
||||
padding: 10px 20px;
|
||||
background: #f8f8f8;
|
||||
color: #333;
|
||||
text-decoration: none;
|
||||
border-radius: 3px;
|
||||
border: 1px solid #ddd;
|
||||
}
|
||||
|
||||
.submit-row .cancel-link:hover {
|
||||
background: #e8e8e8;
|
||||
}
|
||||
</style>
|
||||
{% endblock %}
|
||||
164
core/templates/admin/create_historical_task.html
Normal file
164
core/templates/admin/create_historical_task.html
Normal file
@@ -0,0 +1,164 @@
|
||||
{% extends "admin/base_site.html" %}
|
||||
{% load i18n admin_urls static admin_modify %}
|
||||
|
||||
{% block title %}{{ title }} | {{ site_title|default:_('Django site admin') }}{% endblock %}
|
||||
|
||||
{% block breadcrumbs %}
|
||||
<div class="breadcrumbs">
|
||||
<a href="{% url 'admin:index' %}">{% trans 'Home' %}</a>
|
||||
› <a href="{% url 'admin:core_crawltask_changelist' %}">爬取任务</a>
|
||||
› {{ title }}
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<h1>{{ title }}</h1>
|
||||
|
||||
<form method="post" id="historical-task-form">
|
||||
{% csrf_token %}
|
||||
|
||||
<fieldset class="module aligned">
|
||||
<h2>基本信息</h2>
|
||||
<div class="form-row">
|
||||
<div>
|
||||
<label for="id_name" class="required">任务名称:</label>
|
||||
<input type="text" name="name" id="id_name" required maxlength="200" style="width: 300px;">
|
||||
<p class="help">为这个历史文章爬取任务起一个容易识别的名称</p>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
<fieldset class="module aligned">
|
||||
<h2>目标网站</h2>
|
||||
<div class="form-row">
|
||||
<div>
|
||||
<label>选择要爬取的网站:</label>
|
||||
<div style="max-height: 200px; overflow-y: auto; border: 1px solid #ddd; padding: 10px; margin-top: 5px;">
|
||||
<label style="display: block; margin: 5px 0;">
|
||||
<input type="checkbox" id="select_all" onchange="toggleAllWebsites()">
|
||||
<strong>全选/取消全选</strong>
|
||||
</label>
|
||||
<hr style="margin: 10px 0;">
|
||||
{% for website in websites %}
|
||||
<label style="display: block; margin: 3px 0;">
|
||||
<input type="checkbox" name="websites" value="{{ website.name }}" class="website-checkbox">
|
||||
{{ website.name }}
|
||||
</label>
|
||||
{% endfor %}
|
||||
</div>
|
||||
<p class="help">不选择任何网站将爬取所有支持的网站</p>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
<fieldset class="module aligned">
|
||||
<h2>时间范围</h2>
|
||||
<div class="form-row">
|
||||
<div>
|
||||
<label for="id_start_date" class="required">开始日期:</label>
|
||||
<input type="date" name="start_date" id="id_start_date" required>
|
||||
<p class="help">历史文章的开始日期</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-row">
|
||||
<div>
|
||||
<label for="id_end_date" class="required">结束日期:</label>
|
||||
<input type="date" name="end_date" id="id_end_date" required>
|
||||
<p class="help">历史文章的结束日期</p>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
<fieldset class="module aligned">
|
||||
<h2>爬取设置</h2>
|
||||
<div class="form-row">
|
||||
<div>
|
||||
<label for="id_max_articles">每个网站最大文章数:</label>
|
||||
<input type="number" name="max_articles" id="id_max_articles" value="50" min="1" max="500" style="width: 100px;">
|
||||
<p class="help">每个网站最多爬取的文章数量 (1-500)</p>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
<div class="submit-row">
|
||||
<input type="submit" value="创建任务" class="default" name="_save">
|
||||
<a href="{% url 'admin:core_crawltask_changelist' %}" class="button cancel-link">取消</a>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<script>
|
||||
function toggleAllWebsites() {
|
||||
const selectAll = document.getElementById('select_all');
|
||||
const checkboxes = document.querySelectorAll('.website-checkbox');
|
||||
|
||||
checkboxes.forEach(checkbox => {
|
||||
checkbox.checked = selectAll.checked;
|
||||
});
|
||||
}
|
||||
|
||||
// 设置默认日期
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
const today = new Date();
|
||||
const oneMonthAgo = new Date(today.getFullYear(), today.getMonth() - 1, today.getDate());
|
||||
|
||||
document.getElementById('id_end_date').value = today.toISOString().split('T')[0];
|
||||
document.getElementById('id_start_date').value = oneMonthAgo.toISOString().split('T')[0];
|
||||
});
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.form-row {
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.form-row label {
|
||||
display: block;
|
||||
font-weight: bold;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.form-row input[type="text"],
|
||||
.form-row input[type="number"],
|
||||
.form-row input[type="date"] {
|
||||
padding: 5px;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.form-row .help {
|
||||
color: #666;
|
||||
font-size: 12px;
|
||||
margin-top: 3px;
|
||||
}
|
||||
|
||||
.submit-row {
|
||||
margin-top: 20px;
|
||||
padding-top: 20px;
|
||||
border-top: 1px solid #ddd;
|
||||
}
|
||||
|
||||
.submit-row input[type="submit"] {
|
||||
background: #417690;
|
||||
color: white;
|
||||
padding: 10px 20px;
|
||||
border: none;
|
||||
border-radius: 3px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.submit-row .cancel-link {
|
||||
margin-left: 10px;
|
||||
padding: 10px 20px;
|
||||
background: #f8f8f8;
|
||||
color: #333;
|
||||
text-decoration: none;
|
||||
border-radius: 3px;
|
||||
border: 1px solid #ddd;
|
||||
}
|
||||
|
||||
.submit-row .cancel-link:hover {
|
||||
background: #e8e8e8;
|
||||
}
|
||||
</style>
|
||||
{% endblock %}
|
||||
180
core/templates/admin/create_keyword_task.html
Normal file
180
core/templates/admin/create_keyword_task.html
Normal file
@@ -0,0 +1,180 @@
|
||||
{% extends "admin/base_site.html" %}
|
||||
{% load i18n admin_urls static admin_modify %}
|
||||
|
||||
{% block title %}{{ title }} | {{ site_title|default:_('Django site admin') }}{% endblock %}
|
||||
|
||||
{% block breadcrumbs %}
|
||||
<div class="breadcrumbs">
|
||||
<a href="{% url 'admin:index' %}">{% trans 'Home' %}</a>
|
||||
› <a href="{% url 'admin:core_crawltask_changelist' %}">爬取任务</a>
|
||||
› {{ title }}
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<h1>{{ title }}</h1>
|
||||
|
||||
<form method="post" id="keyword-task-form">
|
||||
{% csrf_token %}
|
||||
|
||||
<fieldset class="module aligned">
|
||||
<h2>基本信息</h2>
|
||||
<div class="form-row">
|
||||
<div>
|
||||
<label for="id_name" class="required">任务名称:</label>
|
||||
<input type="text" name="name" id="id_name" required maxlength="200" style="width: 300px;">
|
||||
<p class="help">为这个爬取任务起一个容易识别的名称</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-row">
|
||||
<div>
|
||||
<label for="id_keyword" class="required">搜索关键词:</label>
|
||||
<input type="text" name="keyword" id="id_keyword" required maxlength="200" style="width: 300px;">
|
||||
<p class="help">输入要搜索的关键词,例如:人工智能、两会、政策等</p>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
<fieldset class="module aligned">
|
||||
<h2>目标网站</h2>
|
||||
<div class="form-row">
|
||||
<div>
|
||||
<label>选择要爬取的网站:</label>
|
||||
<div style="max-height: 200px; overflow-y: auto; border: 1px solid #ddd; padding: 10px; margin-top: 5px;">
|
||||
<label style="display: block; margin: 5px 0;">
|
||||
<input type="checkbox" id="select_all" onchange="toggleAllWebsites()">
|
||||
<strong>全选/取消全选</strong>
|
||||
</label>
|
||||
<hr style="margin: 10px 0;">
|
||||
{% for website in websites %}
|
||||
<label style="display: block; margin: 3px 0;">
|
||||
<input type="checkbox" name="websites" value="{{ website.name }}" class="website-checkbox">
|
||||
{{ website.name }}
|
||||
</label>
|
||||
{% endfor %}
|
||||
</div>
|
||||
<p class="help">不选择任何网站将爬取所有支持的网站</p>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
<fieldset class="module aligned">
|
||||
<h2>时间范围 (可选)</h2>
|
||||
<div class="form-row">
|
||||
<div>
|
||||
<label for="id_start_date">开始日期:</label>
|
||||
<input type="date" name="start_date" id="id_start_date">
|
||||
<p class="help">留空则搜索所有时间</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-row">
|
||||
<div>
|
||||
<label for="id_end_date">结束日期:</label>
|
||||
<input type="date" name="end_date" id="id_end_date">
|
||||
<p class="help">留空则搜索到当前时间</p>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
<fieldset class="module aligned">
|
||||
<h2>爬取设置</h2>
|
||||
<div class="form-row">
|
||||
<div>
|
||||
<label for="id_max_pages">最大搜索页数:</label>
|
||||
<input type="number" name="max_pages" id="id_max_pages" value="10" min="1" max="100" style="width: 100px;">
|
||||
<p class="help">每个网站最多搜索的页数 (1-100)</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-row">
|
||||
<div>
|
||||
<label for="id_max_articles">最大文章数量:</label>
|
||||
<input type="number" name="max_articles" id="id_max_articles" value="100" min="1" max="1000" style="width: 100px;">
|
||||
<p class="help">总共最多爬取的文章数量 (1-1000)</p>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
<div class="submit-row">
|
||||
<input type="submit" value="创建任务" class="default" name="_save">
|
||||
<a href="{% url 'admin:core_crawltask_changelist' %}" class="button cancel-link">取消</a>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<script>
|
||||
function toggleAllWebsites() {
|
||||
const selectAll = document.getElementById('select_all');
|
||||
const checkboxes = document.querySelectorAll('.website-checkbox');
|
||||
|
||||
checkboxes.forEach(checkbox => {
|
||||
checkbox.checked = selectAll.checked;
|
||||
});
|
||||
}
|
||||
|
||||
// 设置默认日期
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
const today = new Date();
|
||||
const oneMonthAgo = new Date(today.getFullYear(), today.getMonth() - 1, today.getDate());
|
||||
|
||||
document.getElementById('id_end_date').value = today.toISOString().split('T')[0];
|
||||
document.getElementById('id_start_date').value = oneMonthAgo.toISOString().split('T')[0];
|
||||
});
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.form-row {
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.form-row label {
|
||||
display: block;
|
||||
font-weight: bold;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.form-row input[type="text"],
|
||||
.form-row input[type="number"],
|
||||
.form-row input[type="date"] {
|
||||
padding: 5px;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.form-row .help {
|
||||
color: #666;
|
||||
font-size: 12px;
|
||||
margin-top: 3px;
|
||||
}
|
||||
|
||||
.submit-row {
|
||||
margin-top: 20px;
|
||||
padding-top: 20px;
|
||||
border-top: 1px solid #ddd;
|
||||
}
|
||||
|
||||
.submit-row input[type="submit"] {
|
||||
background: #417690;
|
||||
color: white;
|
||||
padding: 10px 20px;
|
||||
border: none;
|
||||
border-radius: 3px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.submit-row .cancel-link {
|
||||
margin-left: 10px;
|
||||
padding: 10px 20px;
|
||||
background: #f8f8f8;
|
||||
color: #333;
|
||||
text-decoration: none;
|
||||
border-radius: 3px;
|
||||
border: 1px solid #ddd;
|
||||
}
|
||||
|
||||
.submit-row .cancel-link:hover {
|
||||
background: #e8e8e8;
|
||||
}
|
||||
</style>
|
||||
{% endblock %}
|
||||
172
core/templates/admin/index.html
Normal file
172
core/templates/admin/index.html
Normal file
@@ -0,0 +1,172 @@
|
||||
{% extends "admin/base_site.html" %}
|
||||
{% load i18n static %}
|
||||
|
||||
{% block extrastyle %}{{ block.super }}<link rel="stylesheet" type="text/css" href="{% static "admin/css/dashboard.css" %}">{% endblock %}
|
||||
|
||||
{% block coltype %}colMS{% endblock %}
|
||||
|
||||
{% block bodyclass %}{{ block.super }} dashboard{% endblock %}
|
||||
|
||||
{% block breadcrumbs %}{% endblock %}
|
||||
|
||||
{% block nav-sidebar %}{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div id="content-main">
|
||||
|
||||
{% if app_list %}
|
||||
{% for app in app_list %}
|
||||
<div class="app-{{ app.app_label }} module">
|
||||
<table>
|
||||
<caption>
|
||||
<a href="{{ app.app_url }}" class="section" title="{% blocktranslate with name=app.name %}Models in the {{ name }} application{% endblocktranslate %}">{{ app.name }}</a>
|
||||
</caption>
|
||||
{% for model in app.models %}
|
||||
<tr class="model-{{ model.object_name|lower }}">
|
||||
{% if model.admin_url %}
|
||||
<th scope="row"><a href="{{ model.admin_url }}"{% if model.add_url %} class="addlink"{% endif %}>{{ model.name }}</a></th>
|
||||
{% else %}
|
||||
<th scope="row">{{ model.name }}</th>
|
||||
{% endif %}
|
||||
|
||||
{% if model.add_url %}
|
||||
<td><a href="{{ model.add_url }}" class="addlink">{% translate 'Add' %}</a></td>
|
||||
{% else %}
|
||||
<td> </td>
|
||||
{% endif %}
|
||||
|
||||
{% if model.admin_url %}
|
||||
{% if model.view_only %}
|
||||
<td><a href="{{ model.admin_url }}" class="viewlink">{% translate 'View' %}</a></td>
|
||||
{% else %}
|
||||
<td><a href="{{ model.admin_url }}" class="changelink">{% translate 'Change' %}</a></td>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
<td> </td>
|
||||
{% endif %}
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<p>{% translate "You don't have permission to view or edit anything." %}</p>
|
||||
{% endif %}
|
||||
|
||||
<!-- 自定义快速操作区域 -->
|
||||
<div class="module" style="margin-top: 20px;">
|
||||
<h2>快速创建爬取任务</h2>
|
||||
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); gap: 15px; margin-top: 15px;">
|
||||
<div style="border: 1px solid #ddd; padding: 15px; border-radius: 5px; text-align: center;">
|
||||
<h3 style="margin-top: 0; color: #417690;">关键词搜索</h3>
|
||||
<p style="color: #666; font-size: 14px;">根据关键词搜索并爬取相关文章</p>
|
||||
<a href="{% url 'admin:create_keyword_task' %}" class="button" style="background: #417690; color: white; padding: 8px 16px; text-decoration: none; border-radius: 3px; display: inline-block;">
|
||||
创建任务
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div style="border: 1px solid #ddd; padding: 15px; border-radius: 5px; text-align: center;">
|
||||
<h3 style="margin-top: 0; color: #28a745;">历史文章</h3>
|
||||
<p style="color: #666; font-size: 14px;">爬取指定日期范围的历史文章</p>
|
||||
<a href="{% url 'admin:create_historical_task' %}" class="button" style="background: #28a745; color: white; padding: 8px 16px; text-decoration: none; border-radius: 3px; display: inline-block;">
|
||||
创建任务
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div style="border: 1px solid #ddd; padding: 15px; border-radius: 5px; text-align: center;">
|
||||
<h3 style="margin-top: 0; color: #dc3545;">全站爬取</h3>
|
||||
<p style="color: #666; font-size: 14px;">爬取整个网站的所有文章</p>
|
||||
<a href="{% url 'admin:create_full_site_task' %}" class="button" style="background: #dc3545; color: white; padding: 8px 16px; text-decoration: none; border-radius: 3px; display: inline-block;">
|
||||
创建任务
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 最近任务状态 -->
|
||||
<div class="module" style="margin-top: 20px;">
|
||||
<h2>最近任务状态</h2>
|
||||
<div style="margin-top: 15px;">
|
||||
{% load core_extras %}
|
||||
{% get_recent_tasks as recent_tasks %}
|
||||
{% if recent_tasks %}
|
||||
<table style="width: 100%;">
|
||||
<thead>
|
||||
<tr style="background: #f8f9fa;">
|
||||
<th style="padding: 8px; text-align: left;">任务名称</th>
|
||||
<th style="padding: 8px; text-align: left;">类型</th>
|
||||
<th style="padding: 8px; text-align: left;">状态</th>
|
||||
<th style="padding: 8px; text-align: left;">进度</th>
|
||||
<th style="padding: 8px; text-align: left;">创建时间</th>
|
||||
<th style="padding: 8px; text-align: left;">操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for task in recent_tasks %}
|
||||
<tr>
|
||||
<td style="padding: 8px;">{{ task.name }}</td>
|
||||
<td style="padding: 8px;">{{ task.get_task_type_display }}</td>
|
||||
<td style="padding: 8px;">
|
||||
<span style="color: {% if task.status == 'completed' %}green{% elif task.status == 'failed' %}red{% elif task.status == 'running' %}blue{% else %}gray{% endif %};">
|
||||
{{ task.get_status_display }}
|
||||
</span>
|
||||
</td>
|
||||
<td style="padding: 8px;">
|
||||
{% if task.status == 'running' %}
|
||||
<div style="width: 100px; background-color: #f0f0f0; border-radius: 3px; overflow: hidden;">
|
||||
<div style="width: {{ task.progress }}%; background-color: #4CAF50; height: 16px; text-align: center; line-height: 16px; color: white; font-size: 12px;">
|
||||
{{ task.progress }}%
|
||||
</div>
|
||||
</div>
|
||||
{% else %}
|
||||
-
|
||||
{% endif %}
|
||||
</td>
|
||||
<td style="padding: 8px;">{{ task.created_at|date:"m-d H:i" }}</td>
|
||||
<td style="padding: 8px;">
|
||||
<a href="{% url 'admin:core_crawltask_change' task.id %}" style="color: #417690; text-decoration: none;">查看</a>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
{% else %}
|
||||
<p style="color: #666; text-align: center; padding: 20px;">暂无任务</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block sidebar %}
|
||||
<div id="content-related">
|
||||
<div class="module" id="recent-actions-module">
|
||||
<h2>{% translate 'Recent actions' %}</h2>
|
||||
<h3>{% translate 'My actions' %}</h3>
|
||||
{% load log %}
|
||||
{% get_admin_log 10 as admin_log for_user user %}
|
||||
{% if not admin_log %}
|
||||
<p>{% translate 'None available' %}</p>
|
||||
{% else %}
|
||||
<ul class="actionlist">
|
||||
{% for entry in admin_log %}
|
||||
<li class="{% if entry.is_addition %}addlink{% endif %}{% if entry.is_change %}changelink{% endif %}{% if entry.is_deletion %}deletelink{% endif %}">
|
||||
{% if entry.is_deletion or not entry.get_admin_url %}
|
||||
{{ entry.object_repr }}
|
||||
{% else %}
|
||||
<a href="{{ entry.get_admin_url }}">{{ entry.object_repr }}</a>
|
||||
{% endif %}
|
||||
<br>
|
||||
{% if entry.content_type %}
|
||||
<span class="mini quiet">{% filter capfirst %}{{ entry.content_type.name }}{% endfilter %}</span>
|
||||
{% else %}
|
||||
<span class="mini quiet">{% translate 'Unknown content' %}</span>
|
||||
{% endif %}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
184
core/templates/admin/task_results.html
Normal file
184
core/templates/admin/task_results.html
Normal file
@@ -0,0 +1,184 @@
|
||||
{% extends "admin/base_site.html" %}
|
||||
{% load i18n admin_urls static admin_modify %}
|
||||
|
||||
{% block title %}{{ title }} | {{ site_title|default:_('Django site admin') }}{% endblock %}
|
||||
|
||||
{% block breadcrumbs %}
|
||||
<div class="breadcrumbs">
|
||||
<a href="{% url 'admin:index' %}">{% trans 'Home' %}</a>
|
||||
› <a href="{% url 'admin:core_crawltask_changelist' %}">爬取任务</a>
|
||||
› {{ title }}
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<h1>{{ title }}</h1>
|
||||
|
||||
<div class="results-summary" style="background: #f8f9fa; border: 1px solid #dee2e6; padding: 20px; margin-bottom: 20px; border-radius: 5px;">
|
||||
<h2>任务概览</h2>
|
||||
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 15px;">
|
||||
<div>
|
||||
<strong>任务名称:</strong><br>
|
||||
{{ task.name }}
|
||||
</div>
|
||||
<div>
|
||||
<strong>任务类型:</strong><br>
|
||||
{{ task.get_task_type_display }}
|
||||
</div>
|
||||
<div>
|
||||
<strong>状态:</strong><br>
|
||||
<span style="color: {% if task.status == 'completed' %}green{% elif task.status == 'failed' %}red{% elif task.status == 'running' %}blue{% else %}gray{% endif %};">
|
||||
{{ task.get_status_display }}
|
||||
</span>
|
||||
</div>
|
||||
<div>
|
||||
<strong>创建时间:</strong><br>
|
||||
{{ task.created_at|date:"Y-m-d H:i:s" }}
|
||||
</div>
|
||||
{% if task.started_at %}
|
||||
<div>
|
||||
<strong>开始时间:</strong><br>
|
||||
{{ task.started_at|date:"Y-m-d H:i:s" }}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if task.completed_at %}
|
||||
<div>
|
||||
<strong>完成时间:</strong><br>
|
||||
{{ task.completed_at|date:"Y-m-d H:i:s" }}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if task.get_duration %}
|
||||
<div>
|
||||
<strong>执行时长:</strong><br>
|
||||
{{ task.duration_display }}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="results-stats" style="background: #fff; border: 1px solid #dee2e6; padding: 20px; margin-bottom: 20px; border-radius: 5px;">
|
||||
<h2>统计信息</h2>
|
||||
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 15px;">
|
||||
<div style="text-align: center; padding: 15px; background: #e3f2fd; border-radius: 5px;">
|
||||
<div style="font-size: 24px; font-weight: bold; color: #1976d2;">{{ task.total_articles }}</div>
|
||||
<div>总文章数</div>
|
||||
</div>
|
||||
<div style="text-align: center; padding: 15px; background: #e8f5e8; border-radius: 5px;">
|
||||
<div style="font-size: 24px; font-weight: bold; color: #388e3c;">{{ task.success_count }}</div>
|
||||
<div>成功数</div>
|
||||
</div>
|
||||
<div style="text-align: center; padding: 15px; background: #ffebee; border-radius: 5px;">
|
||||
<div style="font-size: 24px; font-weight: bold; color: #d32f2f;">{{ task.failed_count }}</div>
|
||||
<div>失败数</div>
|
||||
</div>
|
||||
{% if task.total_articles > 0 %}
|
||||
<div style="text-align: center; padding: 15px; background: #fff3e0; border-radius: 5px;">
|
||||
<div style="font-size: 24px; font-weight: bold; color: #f57c00;">
|
||||
{% widthratio task.success_count task.total_articles 100 %}%
|
||||
</div>
|
||||
<div>成功率</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% if task.keyword %}
|
||||
<div class="task-config" style="background: #fff; border: 1px solid #dee2e6; padding: 20px; margin-bottom: 20px; border-radius: 5px;">
|
||||
<h2>任务配置</h2>
|
||||
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 15px;">
|
||||
<div>
|
||||
<strong>搜索关键词:</strong><br>
|
||||
{{ task.keyword }}
|
||||
</div>
|
||||
<div>
|
||||
<strong>目标网站:</strong><br>
|
||||
{{ task.get_websites_display }}
|
||||
</div>
|
||||
{% if task.start_date %}
|
||||
<div>
|
||||
<strong>开始日期:</strong><br>
|
||||
{{ task.start_date }}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if task.end_date %}
|
||||
<div>
|
||||
<strong>结束日期:</strong><br>
|
||||
{{ task.end_date }}
|
||||
</div>
|
||||
{% endif %}
|
||||
<div>
|
||||
<strong>最大页数:</strong><br>
|
||||
{{ task.max_pages }}
|
||||
</div>
|
||||
<div>
|
||||
<strong>最大文章数:</strong><br>
|
||||
{{ task.max_articles }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if task.current_website or task.current_action %}
|
||||
<div class="current-status" style="background: #fff; border: 1px solid #dee2e6; padding: 20px; margin-bottom: 20px; border-radius: 5px;">
|
||||
<h2>当前状态</h2>
|
||||
{% if task.current_website %}
|
||||
<div>
|
||||
<strong>当前网站:</strong> {{ task.current_website }}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if task.current_action %}
|
||||
<div>
|
||||
<strong>当前操作:</strong> {{ task.current_action }}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if task.status == 'running' %}
|
||||
<div style="margin-top: 10px;">
|
||||
<div style="width: 100%; background-color: #f0f0f0; border-radius: 10px; overflow: hidden;">
|
||||
<div style="width: {{ task.progress }}%; background-color: #4CAF50; height: 20px; text-align: center; line-height: 20px; color: white;">
|
||||
{{ task.progress }}%
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if task.error_message %}
|
||||
<div class="error-info" style="background: #ffebee; border: 1px solid #f44336; padding: 20px; margin-bottom: 20px; border-radius: 5px;">
|
||||
<h2 style="color: #d32f2f;">错误信息</h2>
|
||||
<pre style="white-space: pre-wrap; word-wrap: break-word;">{{ task.error_message }}</pre>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if task.result_details %}
|
||||
<div class="detailed-results" style="background: #fff; border: 1px solid #dee2e6; padding: 20px; margin-bottom: 20px; border-radius: 5px;">
|
||||
<h2>详细结果</h2>
|
||||
{% for website, result in task.result_details.items %}
|
||||
<div style="margin-bottom: 15px; padding: 10px; background: #f8f9fa; border-radius: 3px;">
|
||||
<strong>{{ website }}:</strong>
|
||||
<ul style="margin: 5px 0; padding-left: 20px;">
|
||||
<li>找到链接: {{ result.found_urls }}</li>
|
||||
<li>已处理: {{ result.processed }}</li>
|
||||
<li>成功: {{ result.success }}</li>
|
||||
<li>失败: {{ result.failed }}</li>
|
||||
{% if result.error %}
|
||||
<li style="color: red;">错误: {{ result.error }}</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<div class="actions" style="text-align: center; margin-top: 30px;">
|
||||
<a href="{% url 'admin:core_crawltask_changelist' %}" class="button" style="padding: 10px 20px; background: #417690; color: white; text-decoration: none; border-radius: 3px; margin-right: 10px;">
|
||||
返回任务列表
|
||||
</a>
|
||||
{% if task.status == 'completed' %}
|
||||
<a href="{% url 'admin:core_article_changelist' %}" class="button" style="padding: 10px 20px; background: #28a745; color: white; text-decoration: none; border-radius: 3px;">
|
||||
查看文章
|
||||
</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
Reference in New Issue
Block a user