remove home app

This commit is contained in:
Simon
2024-08-03 21:50:59 +02:00
parent 852dfba8c5
commit 1d07386a06
109 changed files with 0 additions and 8736 deletions

View File

@@ -70,7 +70,6 @@ INSTALLED_APPS = [
"stats", "stats",
"user", "user",
"config", "config",
"home",
] ]
MIDDLEWARE = [ MIDDLEWARE = [

View File

@@ -18,7 +18,6 @@ from django.contrib import admin
from django.urls import include, path from django.urls import include, path
urlpatterns = [ urlpatterns = [
path("", include("home.urls")),
path("api/", include("common.urls")), path("api/", include("common.urls")),
path("api/video/", include("video.urls")), path("api/video/", include("video.urls")),
path("api/channel/", include("channel.urls")), path("api/channel/", include("channel.urls")),

View File

@@ -1,270 +0,0 @@
"""functionality:
- hold all form classes used in the views
"""
import os
from common.src.helper import get_stylesheets
from django import forms
from django.contrib.auth.forms import AuthenticationForm
from django.forms.widgets import PasswordInput, TextInput
class CustomAuthForm(AuthenticationForm):
"""better styled login form"""
username = forms.CharField(
widget=TextInput(
attrs={
"placeholder": "Username",
"autofocus": True,
"autocomplete": True,
}
),
label=False,
)
password = forms.CharField(
widget=PasswordInput(attrs={"placeholder": "Password"}), label=False
)
remember_me = forms.BooleanField(required=False)
class UserSettingsForm(forms.Form):
"""user configurations values"""
STYLESHEET_CHOICES = [("", "-- change stylesheet --")]
STYLESHEET_CHOICES.extend(
[
(stylesheet, os.path.splitext(stylesheet)[0].title())
for stylesheet in get_stylesheets()
]
)
stylesheet = forms.ChoiceField(
widget=forms.Select, choices=STYLESHEET_CHOICES, required=False
)
page_size = forms.IntegerField(required=False)
class ApplicationSettingsForm(forms.Form):
"""handle all application settings"""
AUTOSTART_CHOICES = [
("", "-- change subscription autostart --"),
("0", "disable auto start"),
("1", "enable auto start"),
]
METADATA_CHOICES = [
("", "-- change metadata embed --"),
("0", "don't embed metadata"),
("1", "embed metadata"),
]
THUMBNAIL_CHOICES = [
("", "-- change thumbnail embed --"),
("0", "don't embed thumbnail"),
("1", "embed thumbnail"),
]
RYD_CHOICES = [
("", "-- change ryd integrations"),
("0", "disable ryd integration"),
("1", "enable ryd integration"),
]
SP_CHOICES = [
("", "-- change sponsorblock integrations"),
("0", "disable sponsorblock integration"),
("1", "enable sponsorblock integration"),
]
SNAPSHOT_CHOICES = [
("", "-- change snapshot settings --"),
("0", "disable system snapshots"),
("1", "enable system snapshots"),
]
SUBTITLE_SOURCE_CHOICES = [
("", "-- change subtitle source settings"),
("user", "only download user created"),
("auto", "also download auto generated"),
]
SUBTITLE_INDEX_CHOICES = [
("", "-- change subtitle index settings --"),
("0", "disable subtitle index"),
("1", "enable subtitle index"),
]
COMMENT_SORT_CHOICES = [
("", "-- change comments sort settings --"),
("top", "sort comments by top"),
("new", "sort comments by new"),
]
COOKIE_IMPORT_CHOICES = [
("", "-- change cookie settings"),
("0", "remove cookie"),
("1", "import cookie"),
]
subscriptions_channel_size = forms.IntegerField(
required=False, min_value=1
)
subscriptions_live_channel_size = forms.IntegerField(
required=False, min_value=0
)
subscriptions_shorts_channel_size = forms.IntegerField(
required=False, min_value=0
)
subscriptions_auto_start = forms.ChoiceField(
widget=forms.Select, choices=AUTOSTART_CHOICES, required=False
)
downloads_limit_speed = forms.IntegerField(required=False)
downloads_throttledratelimit = forms.IntegerField(required=False)
downloads_sleep_interval = forms.IntegerField(required=False)
downloads_autodelete_days = forms.IntegerField(required=False)
downloads_format = forms.CharField(required=False)
downloads_format_sort = forms.CharField(required=False)
downloads_extractor_lang = forms.CharField(required=False)
downloads_add_metadata = forms.ChoiceField(
widget=forms.Select, choices=METADATA_CHOICES, required=False
)
downloads_add_thumbnail = forms.ChoiceField(
widget=forms.Select, choices=THUMBNAIL_CHOICES, required=False
)
downloads_subtitle = forms.CharField(required=False)
downloads_subtitle_source = forms.ChoiceField(
widget=forms.Select, choices=SUBTITLE_SOURCE_CHOICES, required=False
)
downloads_subtitle_index = forms.ChoiceField(
widget=forms.Select, choices=SUBTITLE_INDEX_CHOICES, required=False
)
downloads_comment_max = forms.CharField(required=False)
downloads_comment_sort = forms.ChoiceField(
widget=forms.Select, choices=COMMENT_SORT_CHOICES, required=False
)
downloads_cookie_import = forms.ChoiceField(
widget=forms.Select, choices=COOKIE_IMPORT_CHOICES, required=False
)
downloads_integrate_ryd = forms.ChoiceField(
widget=forms.Select, choices=RYD_CHOICES, required=False
)
downloads_integrate_sponsorblock = forms.ChoiceField(
widget=forms.Select, choices=SP_CHOICES, required=False
)
application_enable_snapshot = forms.ChoiceField(
widget=forms.Select, choices=SNAPSHOT_CHOICES, required=False
)
class MultiSearchForm(forms.Form):
"""multi search form for /search/"""
searchInput = forms.CharField(
label="",
widget=forms.TextInput(
attrs={
"autocomplete": "off",
"oninput": "searchMulti(this.value)",
"autofocus": True,
}
),
)
home = forms.CharField(widget=forms.HiddenInput())
channel = forms.CharField(widget=forms.HiddenInput())
playlist = forms.CharField(widget=forms.HiddenInput())
class AddToQueueForm(forms.Form):
"""text area form to add to downloads"""
HELP_TEXT = "Enter at least one video, channel or playlist id/URL here..."
vid_url = forms.CharField(
label=False,
widget=forms.Textarea(
attrs={
"rows": 4,
"placeholder": HELP_TEXT,
}
),
)
class SubscribeToChannelForm(forms.Form):
"""text area form to subscribe to multiple channels"""
subscribe = forms.CharField(
label="Subscribe to channels",
widget=forms.Textarea(
attrs={
"rows": 3,
"placeholder": "Input channel ID, URL or Video of a channel",
}
),
)
class SubscribeToPlaylistForm(forms.Form):
"""text area form to subscribe to multiple playlists"""
subscribe = forms.CharField(
label="Subscribe to playlists",
widget=forms.Textarea(
attrs={
"rows": 3,
"placeholder": "Input playlist IDs or URLs",
}
),
)
class CreatePlaylistForm(forms.Form):
"""text area form to create a single custom playlist"""
create = forms.CharField(
label="Or create custom playlist",
widget=forms.Textarea(
attrs={
"rows": 1,
"placeholder": "Input playlist name",
}
),
)
class ChannelOverwriteForm(forms.Form):
"""custom overwrites for channel settings"""
PLAYLIST_INDEX = [
("", "-- change playlist index --"),
("0", "Disable playlist index"),
("1", "Enable playlist index"),
]
SP_CHOICES = [
("", "-- change sponsorblock integrations"),
("disable", "disable sponsorblock integration"),
("1", "enable sponsorblock integration"),
("0", "unset sponsorblock integration"),
]
download_format = forms.CharField(label=False, required=False)
autodelete_days = forms.IntegerField(label=False, required=False)
index_playlists = forms.ChoiceField(
widget=forms.Select, choices=PLAYLIST_INDEX, required=False
)
integrate_sponsorblock = forms.ChoiceField(
widget=forms.Select, choices=SP_CHOICES, required=False
)
subscriptions_channel_size = forms.IntegerField(
label=False, required=False
)
subscriptions_live_channel_size = forms.IntegerField(
label=False, required=False
)
subscriptions_shorts_channel_size = forms.IntegerField(
label=False, required=False
)

View File

@@ -1,101 +0,0 @@
"""
Functionality:
- handle schedule forms
- implement form validation
"""
from celery.schedules import crontab
from django import forms
from task.src.task_config import TASK_CONFIG
class CrontabValidator:
"""validate crontab"""
@staticmethod
def validate_fields(cron_fields):
"""expect 3 cron fields"""
if not len(cron_fields) == 3:
raise forms.ValidationError("expected three cron schedule fields")
@staticmethod
def validate_minute(minute_field):
"""expect minute int"""
try:
minute_value = int(minute_field)
if not 0 <= minute_value <= 59:
raise forms.ValidationError(
"Invalid value for minutes. Must be between 0 and 59."
)
except ValueError as err:
raise forms.ValidationError(
"Invalid value for minutes. Must be an integer."
) from err
@staticmethod
def validate_cron_tab(minute, hour, day_of_week):
"""check if crontab can be created"""
try:
crontab(minute=minute, hour=hour, day_of_week=day_of_week)
except ValueError as err:
raise forms.ValidationError(f"invalid crontab: {err}") from err
def validate(self, cron_expression):
"""create crontab schedule"""
if cron_expression == "auto":
return
cron_fields = cron_expression.split()
self.validate_fields(cron_fields)
minute, hour, day_of_week = cron_fields
self.validate_minute(minute)
self.validate_cron_tab(minute, hour, day_of_week)
def validate_cron(cron_expression):
"""callable for field"""
CrontabValidator().validate(cron_expression)
class SchedulerSettingsForm(forms.Form):
"""handle scheduler settings"""
update_subscribed = forms.CharField(
required=False, validators=[validate_cron]
)
download_pending = forms.CharField(
required=False, validators=[validate_cron]
)
check_reindex = forms.CharField(required=False, validators=[validate_cron])
check_reindex_days = forms.IntegerField(required=False)
thumbnail_check = forms.CharField(
required=False, validators=[validate_cron]
)
run_backup = forms.CharField(required=False, validators=[validate_cron])
run_backup_rotate = forms.IntegerField(required=False)
class NotificationSettingsForm(forms.Form):
"""add notification URL"""
SUPPORTED_TASKS = [
"update_subscribed",
"extract_download",
"download_pending",
"check_reindex",
]
TASK_LIST = [(i, TASK_CONFIG[i]["title"]) for i in SUPPORTED_TASKS]
TASK_CHOICES = [("", "-- select task --")]
TASK_CHOICES.extend(TASK_LIST)
PLACEHOLDER = "Apprise notification URL"
task = forms.ChoiceField(
widget=forms.Select, choices=TASK_CHOICES, required=False
)
notification_url = forms.CharField(
required=False,
widget=forms.TextInput(attrs={"placeholder": PLACEHOLDER}),
)

View File

@@ -1,19 +0,0 @@
{% extends "home/base.html" %}
{% load static %}
{% block content %}
<div class="boxed-content">
<div class="title-bar">
<h1>About The Tube Archivist</h1>
</div>
<div class="about-section">
<h2>Useful Links</h2>
<p>This project is in active and constant development, take a look at the <a href="https://github.com/tubearchivist/tubearchivist#roadmap" target="_blank">roadmap</a> for a overview.</p>
<p>All functionality is documented in our up-to-date <a href="https://docs.tubearchivist.com" target="_blank">user guide</a>.</p>
<p>All contributions are welcome: Open an <a href="https://github.com/tubearchivist/tubearchivist/issues" target="_blank">issue</a> for any bugs and errors, join us on <a href="https://www.tubearchivist.com/discord" target="_blank">Discord</a> to discuss details. The <a href="https://github.com/tubearchivist/tubearchivist/blob/master/CONTRIBUTING.md" target="_blank">contributing</a> page is a good place to get started.</p>
</div>
<div class="about-section">
<h2>Donate</h2>
<p>Here are <a href="https://github.com/tubearchivist/tubearchivist#donate" target="_blank">some links</a>, if you want to buy the developer a coffee. Thank you for your support!</p>
</div>
</div>
{% endblock content %}

View File

@@ -1,141 +0,0 @@
{% load static %}
{% load auth_extras %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" type="text/css" href="{% static 'css/style.css' %}">
<link rel="apple-touch-icon" sizes="180x180" href="{% static 'favicon/apple-touch-icon.png' %}">
<link rel="icon" type="image/png" sizes="32x32" href="{% static 'favicon/favicon-32x32.png' %}">
<link rel="icon" type="image/png" sizes="16x16" href="{% static 'favicon/favicon-16x16.png' %}">
<link rel="manifest" href="{% static 'favicon/site.webmanifest' %}">
<link rel="mask-icon" href="{% static 'favicon/safari-pinned-tab.svg' %}" color="#01202e">
<link rel="shortcut icon" href="{% static 'favicon/favicon.ico' %}">
<meta name="apple-mobile-web-app-title" content="TubeArchivist">
<meta name="application-name" content="TubeArchivist">
<meta name="msapplication-TileColor" content="#01202e">
<meta name="msapplication-config" content="{% static 'favicon/browserconfig.xml' %}">
<meta name="theme-color" content="#01202e">
{% if title %}
<title>TA | {{ title }}</title>
{% else %}
<title>TubeArchivist</title>
{% endif %}
<link rel="stylesheet" href="{% static 'css/' %}{{ stylesheet }}">
<script type="text/javascript" src="{% static 'script.js' %}"></script>
{% if cast %}
<script type="text/javascript" src="https://www.gstatic.com/cv/js/sender/v1/cast_sender.js?loadCastFramework=1"></script>
<script id="cast-script" type="text/javascript" src="{% static 'cast-videos.js' %}"></script>
{% endif %}
</head>
<body>
<div class="main-content">
<div class="boxed-content">
<a href="{% url 'home' %}">
<div class="top-banner"></div>
</a>
<div class="top-nav">
<div class="nav-items">
<a href="{% url 'home' %}">
<div class="nav-item">home</div>
</a>
<a href="{% url 'channel' %}">
<div class="nav-item">channels</div>
</a>
<a href="{% url 'playlist' %}">
<div class="nav-item">playlists</div>
</a>
{% if request.user|has_group:"admin" or request.user.is_staff %}
<a href="{% url 'downloads' %}">
<div class="nav-item">downloads</div>
</a>
{% endif %}
</div>
<div class="nav-icons">
<a href="{% url 'search' %}">
<img src="{% static 'img/icon-search.svg' %}" alt="search-icon" title="Search">
</a>
<a href="{% url 'settings' %}">
<img src="{% static 'img/icon-gear.svg' %}" alt="gear-icon" title="Settings">
</a>
<form id="logout-form" action="{% url 'logout' %}" method="post" style="display:none;">
{% csrf_token %}
</form>
<a href="#" onclick="document.getElementById('logout-form').submit();">
<img class="alert-hover" src="{% static 'img/icon-exit.svg' %}" alt="exit-icon" title="Logout">
</a>
</div>
</div>
</div>
{% block content %}{% endblock %}
<div class="boxed-content">
<div class="pagination">
{% if pagination %}
{% if pagination.current_page > 1 %}
{% if pagination.params %}
<a class="pagination-item" href="{{ request.path }}?{{ pagination.params }}">First</a>
{% else %}
<a class="pagination-item" href="{{ request.path }}">First</a>
{% endif %}
{% endif %}
{% if pagination.prev_pages %}
{% for page in pagination.prev_pages %}
{% if pagination.params %}
<a class="pagination-item" href="?page={{ page }}&{{ pagination.params }}">{{ page }}</a>
{% else %}
<a class="pagination-item" href="?page={{ page }}">{{ page }}</a>
{% endif %}
{% endfor %}
{% endif %}
{% if pagination.current_page %}
<span>< Page {{ pagination.current_page }}</span>
{% endif %}
{% if pagination.next_pages %}
<span> ></span>
{% for page in pagination.next_pages %}
{% if pagination.params %}
<a class="pagination-item" href="?page={{ page }}&{{ pagination.params }}">{{ page }}</a>
{% else %}
<a class="pagination-item" href="?page={{ page }}">{{ page }}</a>
{% endif %}
{% endfor %}
{% endif %}
{% if pagination.last_page > 0 %}
{% if pagination.params %}
<a class="pagination-item" href="?page={{ pagination.last_page }}&{{ pagination.params }}">
{% if pagination.max_hits %}
Max ({{ pagination.last_page }})
{% else %}
Last ({{ pagination.last_page }})
{% endif %}
</a>
{% else %}
<a class="pagination-item" href="?page={{ pagination.last_page }}">
{% if pagination.max_hits %}
Max ({{ pagination.last_page }})
{% else %}
Last ({{ pagination.last_page }})
{% endif %}
</a>
{% endif %}
{% endif %}
{% endif %}
</div>
</div>
</div>
<div class="footer">
<div class="boxed-content">
<span>© 2021 - <script type="text/javascript">document.write(new Date().getFullYear());</script></span>
<span>TubeArchivist</span>
<span>{{ version }}</span>
{% if ta_update %}
<span class="danger-zone">{{ ta_update.version }} available{% if ta_update.is_breaking %}<span class="danger-zone">Breaking Changes!</span>{% endif %}</span>
<span><a href="https://github.com/tubearchivist/tubearchivist/releases/tag/{{ ta_update.version }}" target="_blank">Release Page</a> | </span>
{% endif %}
<span><a href="{% url 'about' %}">About</a> | <a href="https://github.com/tubearchivist/tubearchivist" target="_blank">GitHub</a> | <a href="https://hub.docker.com/r/bbilly1/tubearchivist" target="_blank">Docker Hub</a> | <a href="https://www.tubearchivist.com/discord" target="_blank">Discord</a> | <a href="https://www.reddit.com/r/TubeArchivist/">Reddit</a></span>
</div>
</div>
</body>
</html>

View File

@@ -1,20 +0,0 @@
{# Base file for all of the settings pages to ensure a common menu #}
{% extends "home/base.html" %}
{% load static %}
{% load auth_extras %}
{% block content %}
<div class="boxed-content">
<div class="info-box-item child-page-nav">
<a href="{% url 'settings' %}"><h3>Dashboard</h3></a>
<a href="{% url 'settings_user' %}"><h3>User</h3></a>
{% if request.user|has_group:"admin" or request.user.is_staff %}
<a href="{% url 'settings_application' %}"><h3>Application</h3></a>
<a href="{% url 'settings_scheduling' %}"><h3>Scheduling</h3></a>
<a href="{% url 'settings_actions' %}"><h3>Actions</h3></a>
{% endif %}
</div>
<div id="notifications" data=""></div>
{% block settings_content %}{% endblock %}
</div>
<script type="text/javascript" src="{% static 'progress.js' %}"></script>
{% endblock content %}

View File

@@ -1,87 +0,0 @@
{% extends "home/base.html" %}
{% load static %}
{% load humanize %}
{% block content %}
{% load auth_extras %}
<div class="boxed-content">
<div class="title-split">
<div class="title-bar">
<h1>Channels</h1>
</div>
{% if request.user|has_group:"admin" or request.user.is_staff %}
<div class="title-split-form">
<img id="animate-icon" onclick="showForm()" src="{% static 'img/icon-add.svg' %}" alt="add-icon" title="Subscribe to Channels">
<div class="show-form">
<form id="hidden-form" action="/channel/" method="post">
{% csrf_token %}
{{ subscribe_form }}
<button type="submit">Subscribe</button>
</form>
</div>
</div>
{% endif %}
</div>
<div id="notifications" data="subscription"></div>
<div class="view-controls">
<div class="toggle">
<span>Show subscribed only:</span>
<div class="toggleBox">
<input id="show_subed_only" onclick="toggleCheckbox(this)" type="checkbox" {% if show_subed_only %}checked{% endif %}>
{% if not show_subed_only %}
<label for="" class="ofbtn">Off</label>
{% else %}
<label for="" class="onbtn">On</label>
{% endif %}
</div>
</div>
<div class="view-icons">
<img src="{% static 'img/icon-gridview.svg' %}" onclick="changeView(this)" data-origin="channel" data-value="grid" alt="grid view">
<img src="{% static 'img/icon-listview.svg' %}" onclick="changeView(this)" data-origin="channel" data-value="list" alt="list view">
</div>
</div>
<h2>Total channels: {{ max_hits }}</h2>
<div class="channel-list {{ view_style }}">
{% if results %}
{% for channel in results %}
<div class="channel-item {{ view_style }}">
<div class="channel-banner {{ view_style }}">
<a href="{% url 'channel_id' channel.channel_id %}">
<img src="{{ channel.channel_banner_url }}" alt="{{ channel.channel_id }}-banner">
</a>
</div>
<div class="info-box info-box-2 {{ view_style }}">
<div class="info-box-item">
<div class="round-img">
<a href="{% url 'channel_id' channel.channel_id %}">
<img src="{{ channel.channel_thumb_url }}" alt="channel-thumb">
</a>
</div>
<div>
<h3><a href="{% url 'channel_id' channel.channel_id %}">{{ channel.channel_name }}</a></h3>
{% if channel.channel_subs >= 1000000 %}
<p>Subscribers: {{ channel.channel_subs|intword }}</p>
{% else %}
<p>Subscribers: {{ channel.channel_subs|intcomma }}</p>
{% endif %}
</div>
</div>
<div class="info-box-item">
<div>
<p>Last refreshed: {{ channel.channel_last_refresh }}</p>
{% if channel.channel_subscribed %}
<button class="unsubscribe" type="button" data-type="channel" data-subscribe="" data-id="{{ channel.channel_id }}" onclick="subscribeStatus(this)" title="Unsubscribe from {{ channel.channel_name }}">Unsubscribe</button>
{% else %}
<button type="button" data-type="channel" data-subscribe="true" data-id="{{ channel.channel_id }}" onclick="subscribeStatus(this)" title="Subscribe to {{ channel.channel_name }}">Subscribe</button>
{% endif %}
</div>
</div>
</div>
</div>
{% endfor %}
{% else %}
<h2>No channels found...</h2>
{% endif %}
</div>
</div>
<script type="text/javascript" src="{% static 'progress.js' %}"></script>
{% endblock content %}

View File

@@ -1,154 +0,0 @@
{% extends "home/base.html" %}
{% block content %}
{% load static %}
{% load humanize %}
{% load auth_extras %}
<div class="boxed-content">
<div class="channel-banner">
<a href="/channel/{{ channel_info.channel_id }}/"><img src="{{ channel_info.channel_banner_url }}" alt="channel_banner"></a>
</div>
<div class="info-box-item child-page-nav">
<a href="{% url 'channel_id' channel_info.channel_id %}"><h3>Videos</h3></a>
{% if has_streams %}
<a href="{% url 'channel_id_live' channel_info.channel_id %}"><h3>Streams</h3></a>
{% endif %}
{% if has_shorts %}
<a href="{% url 'channel_id_shorts' channel_info.channel_id %}"><h3>Shorts</h3></a>
{% endif %}
{% if has_playlists %}
<a href="{% url 'channel_id_playlist' channel_info.channel_id %}"><h3>Playlists</h3></a>
{% endif %}
<a href="{% url 'channel_id_about' channel_info.channel_id %}"><h3>About</h3></a>
{% if has_pending %}
{% if request.user|has_group:"admin" or request.user.is_staff %}
<a href="{% url 'downloads' %}?channel={{ channel_info.channel_id }}"><h3>Downloads</h3></a>
{% endif %}
{% endif %}
</div>
<div id="notifications" data="channel reindex"></div>
<div class="info-box info-box-2">
<div class="info-box-item">
<div class="round-img">
<a href="{% url 'channel_id' channel_info.channel_id %}">
<img src="{{ channel_info.channel_thumb_url }}" alt="channel-thumb">
</a>
</div>
<div>
<h3><a href="{% url 'channel_id' channel_info.channel_id %}">{{ channel_info.channel_name }}</a></h3>
{% if channel_info.channel_subs >= 1000000 %}
<p>Subscribers: {{ channel_info.channel_subs|intword }}</p>
{% else %}
<p>Subscribers: {{ channel_info.channel_subs|intcomma }}</p>
{% endif %}
{% if channel_info.channel_subscribed %}
{% if request.user|has_group:"admin" or request.user.is_staff %}
<button class="unsubscribe" type="button" data-type="channel" data-subscribe="" data-id="{{ channel_info.channel_id }}" onclick="subscribeStatus(this)" title="Unsubscribe from {{ channel_info.channel_name }}">Unsubscribe</button>
{% endif %}
{% else %}
<button type="button" data-type="channel" data-subscribe="true" data-id="{{ channel_info.channel_id }}" onclick="subscribeStatus(this)" title="Subscribe to {{ channel_info.channel_name }}">Subscribe</button>
{% endif %}
</div>
</div>
<div class="info-box-item">
{% if aggs %}
<p>{{ aggs.total_items.value }} videos <span class="space-carrot">|</span> {{ aggs.total_duration.value_str }} playback <span class="space-carrot">|</span> Total size {{ aggs.total_size.value|filesizeformat }}</p>
<div class="button-box">
<button title="Mark all videos from {{ channel_info.channel_name }} as watched" type="button" id="watched-button" data-id="{{ channel_info.channel_id }}" onclick="isWatchedButton(this)">Mark as watched</button>
<button title="Mark all videos from {{ channel_info.channel_name }} as unwatched" type="button" id="unwatched-button" data-id="{{ channel_info.channel_id }}" onclick="isUnwatchedButton(this)">Mark as unwatched</button>
</div>
{% endif %}
</div>
</div>
</div>
<div class="boxed-content {% if view_style == "grid" %}boxed-{{ grid_items }}{% endif %}">
<div class="view-controls three">
<div class="toggle">
<span>Hide watched videos:</span>
<div class="toggleBox">
<input id="hide_watched" onclick="toggleCheckbox(this)" type="checkbox" {% if hide_watched %}checked{% endif %}>
{% if not hide_watched %}
<label for="" class="ofbtn">Off</label>
{% else %}
<label for="" class="onbtn">On</label>
{% endif %}
</div>
</div>
<div class="sort">
<div id="hidden-form">
<span>Sort by:</span>
<select name="sort_by" id="sort" onchange="sortChange(this)">
<option value="published" {% if sort_by == "published" %}selected{% endif %}>date published</option>
<option value="downloaded" {% if sort_by == "downloaded" %}selected{% endif %}>date downloaded</option>
<option value="views" {% if sort_by == "views" %}selected{% endif %}>views</option>
<option value="likes" {% if sort_by == "likes" %}selected{% endif %}>likes</option>
<option value="duration" {% if sort_by == "duration" %}selected{% endif %}>duration</option>
<option value="filesize" {% if sort_by == "filesize" %}selected{% endif %}>file size</option>
</select>
<select name="sort_order" id="sort-order" onchange="sortChange(this)">
<option value="asc" {% if sort_order == "asc" %}selected{% endif %}>asc</option>
<option value="desc" {% if sort_order == "desc" %}selected{% endif %}>desc</option>
</select>
</div>
</div>
<div class="view-icons">
<img src="{% static 'img/icon-sort.svg' %}" alt="sort-icon" onclick="showForm()" id="animate-icon">
{% if view_style == "grid" %}
<div class="grid-count">
{% if grid_items < 7 %}
<img src="{% static 'img/icon-add.svg' %}" onclick="changeGridItems(this)" data-value="{{ grid_items|add:"1"}}" alt="grid plus row">
{% endif %}
{% if grid_items > 3 %}
<img src="{% static 'img/icon-substract.svg' %}" onclick="changeGridItems(this)" data-value="{{ grid_items|add:"-1"}}" alt="grid minus row">
{% endif %}
</div>
{% endif %}
<img src="{% static 'img/icon-gridview.svg' %}" onclick="changeView(this)" data-origin="home" data-value="grid" alt="grid view">
<img src="{% static 'img/icon-listview.svg' %}" onclick="changeView(this)" data-origin="home" data-value="list" alt="list view">
</div>
</div>
</div>
<div id="player" class="player-wrapper"></div>
<div class="boxed-content {% if view_style == "grid" %}boxed-{{ grid_items }}{% endif %}">
<div class="video-list {{ view_style }} {% if view_style == "grid" %}grid-{{ grid_items }}{% endif %}">
{% if results %}
{% for video in results %}
<div class="video-item {{ view_style }}">
<a href="#player" data-id="{{ video.youtube_id }}" onclick="createPlayer(this)">
<div class="video-thumb-wrap {{ view_style }}">
<div class="video-thumb">
<img src="{{ video.vid_thumb_url }}" alt="video-thumb">
{% if video.player.progress %}
<div class="video-progress-bar" id="progress-{{ video.youtube_id }}" style="width: {{video.player.progress}}%;"></div>
{% else %}
<div class="video-progress-bar" id="progress-{{ video.youtube_id }}" style="width: 0%;"></div>
{% endif %}
</div>
<div class="video-play">
<img src="{% static 'img/icon-play.svg' %}" alt="play-icon">
</div>
</div>
</a>
<div class="video-desc {{ view_style }}">
<div class="video-desc-player" id="video-info-{{ video.youtube_id }}">
{% if video.player.watched %}
<img src="{% static 'img/icon-seen.svg' %}" alt="seen-icon" data-id="{{ video.youtube_id }}" data-status="watched" onclick="updateVideoWatchStatus(this)" class="watch-button" title="Mark as unwatched">
{% else %}
<img src="{% static 'img/icon-unseen.svg' %}" alt="unseen-icon" data-id="{{ video.youtube_id }}" data-status="unwatched" onclick="updateVideoWatchStatus(this)" class="watch-button" title="Mark as watched">
{% endif %}
<span>{{ video.published }} | {{ video.player.duration_str }}</span>
</div>
<div>
<a class="video-more" href="{% url 'video' video.youtube_id %}"><h2>{{ video.title }}</h2></a>
</div>
</div>
</div>
{% endfor %}
{% else %}
<h2>No videos found...</h2>
<p>Try going to the <a href="{% url 'downloads' %}">downloads page</a> to start the scan and download tasks.</p>
{% endif %}
</div>
</div>
<script type="text/javascript" src="{% static 'progress.js' %}"></script>
{% endblock content %}

View File

@@ -1,186 +0,0 @@
{% extends "home/base.html" %}
{% block content %}
{% load static %}
{% load humanize %}
{% load auth_extras %}
<div class="boxed-content">
<div class="channel-banner">
<a href="{% url 'channel_id' channel_info.channel_id %}"><img src="{{ channel_info.channel_banner_url }}" alt="channel_banner"></a>
</div>
<div class="info-box-item child-page-nav">
<a href="{% url 'channel_id' channel_info.channel_id %}"><h3>Videos</h3></a>
{% if has_streams %}
<a href="{% url 'channel_id_live' channel_info.channel_id %}"><h3>Streams</h3></a>
{% endif %}
{% if has_shorts %}
<a href="{% url 'channel_id_shorts' channel_info.channel_id %}"><h3>Shorts</h3></a>
{% endif %}
{% if has_playlists %}
<a href="{% url 'channel_id_playlist' channel_info.channel_id %}"><h3>Playlists</h3></a>
{% endif %}
<a href="{% url 'channel_id_about' channel_info.channel_id %}"><h3>About</h3></a>
{% if has_pending %}
{% if request.user|has_group:"admin" or request.user.is_staff %}
<a href="{% url 'downloads' %}?channel={{ channel_info.channel_id }}"><h3>Downloads</h3></a>
{% endif %}
{% endif %}
</div>
<div id="notifications" data="channel reindex"></div>
<div class="info-box info-box-3">
<div class="info-box-item">
<div class="round-img">
<a href="{% url 'channel_id' channel_info.channel_id %}">
<img src="{{ channel_info.channel_thumb_url }}" alt="channel-thumb">
</a>
</div>
<div>
<h3><a href="{% url 'channel_id' channel_info.channel_id %}">{{ channel_info.channel_name }}</a></h3>
{% if channel_info.channel_subs >= 1000000 %}
<p>Subscribers: {{ channel_info.channel_subs|intword }}</p>
{% else %}
<p>Subscribers: {{ channel_info.channel_subs|intcomma }}</p>
{% endif %}
</div>
</div>
<div class="info-box-item">
<div>
<p>Last refreshed: {{ channel_info.channel_last_refresh }}</p>
{% if channel_info.channel_active %}
<p>Youtube: <a href="https://www.youtube.com/channel/{{ channel_info.channel_id }}" target="_blank">Active</a></p>
{% else %}
<p>Youtube: Deactivated</p>
{% endif %}
</div>
</div>
<div class="info-box-item">
<div>
{% if channel_info.channel_views >= 1000000 %}
<p>Channel views: {{ channel_info.channel_views|intword }}</p>
{% elif channel_info.channel_views > 0 %}
<p>Channel views: {{ channel_info.channel_views|intcomma }}</p>
{% endif %}
{% if request.user|has_group:"admin" or request.user.is_staff %}
<div class="button-box">
<button onclick="deleteConfirm()" id="delete-item">Delete Channel</button>
<div class="delete-confirm" id="delete-button">
<span>Delete {{ channel_info.channel_name }} including all videos? </span><button class="danger-button" onclick="deleteChannel(this)" data-id="{{ channel_info.channel_id }}">Delete</button> <button onclick="cancelDelete()">Cancel</button>
</div>
</div>
{% if reindex %}
<p>Reindex scheduled</p>
{% else %}
<div id="reindex-button" class="button-box">
<button data-id="{{ channel_info.channel_id }}" data-type="channel" onclick="reindex(this)" title="Reindex Channel {{ channel_info.channel_name }}">Reindex</button>
<button data-id="{{ channel_info.channel_id }}" data-type="channel" data-extract-videos="true" onclick="reindex(this)" title="Reindex Videos of {{ channel_info.channel_name }}">Reindex Videos</button>
</div>
{% endif %}
{% endif %}
</div>
</div>
</div>
{% if channel_info.channel_description %}
<div class="description-box">
<p id="text-expand" class="description-text">
{{ channel_info.channel_description|linebreaksbr|urlizetrunc:50 }}
</p>
<button onclick="textExpand()" id="text-expand-button">Show more</button>
</div>
{% endif %}
{% if channel_info.channel_tags %}
<div class="description-box">
<div class="video-tag-box">
{% for tag in channel_info.channel_tags %}
<span class="video-tag">{{ tag }}</span>
{% endfor %}
</div>
</div>
{% endif %}
{% if request.user|has_group:"admin" or request.user.is_staff %}
<div id="overwrite-form" class="info-box">
<div class="info-box-item">
<h2>Customize {{ channel_info.channel_name }}</h2>
<form class="overwrite-form" action="/channel/{{ channel_info.channel_id }}/about/" method="POST">
{% csrf_token %}
<div class="overwrite-form-item">
<p>Download format: <span class="settings-current">
{% if channel_info.channel_overwrites.download_format %}
{{ channel_info.channel_overwrites.download_format }}
{% else %}
False
{% endif %}</span><br>
Enter "disable" to disable this override.
</p>
{{ channel_overwrite_form.download_format }}<br>
</div>
<div class="overwrite-form-item">
<p>Auto delete watched videos after x days: <span class="settings-current">
{% if channel_info.channel_overwrites.autodelete_days is not None %}
{{ channel_info.channel_overwrites.autodelete_days }}
{% else %}
False
{% endif %}</span><br>
Enter a negative number to disable this override.
</p>
{{ channel_overwrite_form.autodelete_days }}<br>
</div>
<div class="overwrite-form-item">
<p>Index playlists: <span class="settings-current">
{% if channel_info.channel_overwrites.index_playlists %}
{{ channel_info.channel_overwrites.index_playlists }}
{% else %}
False
{% endif %}</span></p>
{{ channel_overwrite_form.index_playlists }}<br>
</div>
<div class="overwrite-form-item">
<p>Enable <a href="https://sponsor.ajay.app/" target="_blank">SponsorBlock</a>: <span class="settings-current">
{% if channel_info.channel_overwrites.integrate_sponsorblock %}
{{ channel_info.channel_overwrites.integrate_sponsorblock }}
{% elif channel_info.channel_overwrites.integrate_sponsorblock == False %}
Disabled
{% else %}
False
{% endif %}</span></p>
{{ channel_overwrite_form.integrate_sponsorblock }}<br>
</div>
<h3>Page Size Overrides</h3><br>
<p>Disable standard videos, shorts, or streams for this channel by setting their page size to 0 (zero).</p><br>
<p>Disable page size overwrite for channel by setting to negative value.</p><br>
<div class="overwrite-form-item">
<p>YouTube page size: <span class="settings-current">
{% if channel_info.channel_overwrites.subscriptions_channel_size is not None %}
{{ channel_info.channel_overwrites.subscriptions_channel_size }}
{% else %}
False
{% endif %}</span></p>
<i>Videos to scan to find new items for the <b>Rescan subscriptions</b> task, max recommended 50.</i><br>
{{ channel_overwrite_form.subscriptions_channel_size }}<br>
</div>
<div class="overwrite-form-item">
<p>YouTube Live page size: <span class="settings-current">
{% if channel_info.channel_overwrites.subscriptions_live_channel_size is not None %}
{{ channel_info.channel_overwrites.subscriptions_live_channel_size }}
{% else %}
False
{% endif %}</span></p>
<i>Live Videos to scan to find new items for the <b>Rescan subscriptions</b> task, max recommended 50.</i><br>
{{ channel_overwrite_form.subscriptions_live_channel_size }}<br>
</div>
<div class="overwrite-form-item">
<p>YouTube Shorts page size: <span class="settings-current">
{% if channel_info.channel_overwrites.subscriptions_shorts_channel_size is not None %}
{{ channel_info.channel_overwrites.subscriptions_shorts_channel_size }}
{% else %}
False
{% endif %}</span></p>
<i>Shorts Videos to scan to find new items for the <b>Rescan subscriptions</b> task, max recommended 50.</i><br>
{{ channel_overwrite_form.subscriptions_shorts_channel_size }}<br>
</div><br>
<button type="submit">Save Channel Overwrites</button>
</form>
</div>
</div>
{% endif %}
</div>
<script type="text/javascript" src="{% static 'progress.js' %}"></script>
{% endblock content %}

View File

@@ -1,74 +0,0 @@
{% extends "home/base.html" %}
{% block content %}
{% load static %}
{% load humanize %}
{% load auth_extras %}
<div class="boxed-content">
<div class="channel-banner">
<a href="{% url 'channel_id' channel_info.channel_id %}"><img src="{{ channel_info.channel_banner_url }}" alt="channel_banner"></a>
</div>
<div class="info-box-item child-page-nav">
<a href="{% url 'channel_id' channel_info.channel_id %}"><h3>Videos</h3></a>
{% if has_streams %}
<a href="{% url 'channel_id_live' channel_info.channel_id %}"><h3>Streams</h3></a>
{% endif %}
{% if has_shorts %}
<a href="{% url 'channel_id_shorts' channel_info.channel_id %}"><h3>Shorts</h3></a>
{% endif %}
{% if has_playlists %}
<a href="{% url 'channel_id_playlist' channel_info.channel_id %}"><h3>Playlists</h3></a>
{% endif %}
<a href="{% url 'channel_id_about' channel_info.channel_id %}"><h3>About</h3></a>
{% if has_pending %}
{% if request.user|has_group:"admin" or request.user.is_staff %}
<a href="{% url 'downloads' %}?channel={{ channel_info.channel_id }}"><h3>Downloads</h3></a>
{% endif %}
{% endif %}
</div>
<div id="notifications" data="channel reindex"></div>
<div class="view-controls">
<div class="toggle">
<span>Show subscribed only:</span>
<div class="toggleBox">
<input id="show_subed_only" onclick="toggleCheckbox(this)" type="checkbox" {% if show_subed_only %}checked{% endif %}>
{% if not show_subed_only %}
<label for="" class="ofbtn">Off</label>
{% else %}
<label for="" class="onbtn">On</label>
{% endif %}
</div>
</div>
<div class="view-icons">
<img src="{% static 'img/icon-gridview.svg' %}" onclick="changeView(this)" data-origin="playlist" data-value="grid" alt="grid view">
<img src="{% static 'img/icon-listview.svg' %}" onclick="changeView(this)" data-origin="playlist" data-value="list" alt="list view">
</div>
</div>
<div class="playlist-list {{ view_style }}">
{% if results %}
{% for playlist in results %}
<div class="playlist-item {{ view_style }}">
<div class="playlist-thumbnail">
<a href="{% url 'playlist_id' playlist.playlist_id %}">
<img src="{{ playlist.playlist_thumbnail }}" alt="{{ playlist.playlist_id }}-thumbnail">
</a>
</div>
<div class="playlist-desc {{ view_style }}">
<a href="{% url 'playlist_id' playlist.playlist_id %}"><h2>{{ playlist.playlist_name }}</h2></a>
<p>Last refreshed: {{ playlist.playlist_last_refresh }}</p>
{% if request.user|has_group:"admin" or request.user.is_staff %}
{% if playlist.playlist_subscribed %}
<button class="unsubscribe" type="button" data-type="playlist" data-subscribe="" data-id="{{ playlist.playlist_id }}" onclick="subscribeStatus(this)" title="Unsubscribe from {{ playlist.playlist_name }}">Unsubscribe</button>
{% else %}
<button type="button" data-type="playlist" data-subscribe="true" data-id="{{ playlist.playlist_id }}" onclick="subscribeStatus(this)" title="Subscribe to {{ playlist.playlist_name }}">Subscribe</button>
{% endif %}
{% endif %}
</div>
</div>
{% endfor %}
{% else %}
<h2>No playlists found...</h2>
{% endif %}
</div>
</div>
<script type="text/javascript" src="{% static 'progress.js' %}"></script>
{% endblock content %}

View File

@@ -1,122 +0,0 @@
{% extends "home/base.html" %}
{% load static %}
{% block content %}
<div class="boxed-content">
<div class="title-bar">
<h1>Downloads {% if channel_filter_id %} for {{ channel_filter_name }}{% endif %}</h1>
</div>
<div id="notifications" data="download"></div>
<div id="downloadControl"></div>
<div class="info-box info-box-3">
<div class="icon-text">
<img id="rescan-icon" onclick="rescanPending()" src="{% static 'img/icon-rescan.svg' %}" alt="rescan-icon">
<p>Rescan subscriptions</p>
</div>
<div class="icon-text">
<img id="download-icon" onclick="dlPending()" src="{% static 'img/icon-download.svg' %}" alt="download-icon">
<p>Start download</p>
</div>
<div class="icon-text">
<img id="animate-icon" onclick="showForm()" src="{% static 'img/icon-add.svg' %}" alt="add-icon">
<p>Add to download queue</p>
<div class="show-form">
<div id='hidden-form' novalidate>
{% csrf_token %}
{{ add_form }}
<button onclick="addToQueue()">Add to queue</button>
<button onclick="addToQueue(true)">Download now</button>
</div>
</div>
</div>
</div>
<div class="view-controls three">
<div class="toggle">
<span>Show only ignored videos:</span>
<div class="toggleBox">
<input id="show_ignored_only" onclick="toggleCheckbox(this)" type="checkbox" {% if show_ignored_only %}checked{% endif %}>
{% if not show_ignored_only %}
<label for="" class="ofbtn">Off</label>
{% else %}
<label for="" class="onbtn">On</label>
{% endif %}
</div>
</div>
<div class="view-icons">
{% if channel_agg_list|length > 1 %}
<select name="channel_filter" id="channel_filter" onchange="channelFilterDownload(this.value)">
<option value="all" {% if not channel_filter_id %}selected{% endif %}>all</option>
{% for channel in channel_agg_list %}
<option {% if channel_filter_id == channel.id %}selected{% endif %} value="{{ channel.id }}">{{ channel.name }} ({{channel.count}})</option>
{% endfor %}
</select>
{% endif %}
{% if view_style == "grid" %}
<div class="grid-count">
{% if grid_items < 7 %}
<img src="{% static 'img/icon-add.svg' %}" onclick="changeGridItems(this)" data-value="{{ grid_items|add:"1"}}" alt="grid plus row">
{% endif %}
{% if grid_items > 3 %}
<img src="{% static 'img/icon-substract.svg' %}" onclick="changeGridItems(this)" data-value="{{ grid_items|add:"-1"}}" alt="grid minus row">
{% endif %}
</div>
{% endif %}
<img src="{% static 'img/icon-gridview.svg' %}" onclick="changeView(this)" data-origin="downloads" data-value="grid" alt="grid view">
<img src="{% static 'img/icon-listview.svg' %}" onclick="changeView(this)" data-origin="downloads" data-value="list" alt="list view">
</div>
</div>
<h3>Total videos in queue: {{ max_hits }}{% if max_hits == 10000 %}+{% endif %} {% if channel_filter_id %} - from channel <i>{{ channel_filter_name }}</i>{% endif %}</h3>
</div>
<div class="boxed-content {% if view_style == "grid" %}boxed-{{ grid_items }}{% endif %}">
<div class="video-list {{ view_style }} {% if view_style == "grid" %}grid-{{ grid_items }}{% endif %}">
{% if results %}
{% for video in results %}
<div class="video-item {{ view_style }}" id="dl-{{ video.youtube_id }}">
<div class="video-thumb-wrap {{ view_style }}">
<div class="video-thumb">
<img src="{{ video.vid_thumb_url }}" alt="video_thumb">
<div class="video-tags">
{% if show_ignored_only %}
<span>ignored</span>
{% else %}
<span>queued</span>
{% endif %}
<span>{{ video.vid_type }}</span>
{% if video.auto_start %}
<span>auto</span>
{% endif %}
</div>
</div>
</div>
<div class="video-desc {{ view_style }}">
<div>
{% if video.channel_indexed %}
<a href="{% url 'channel_id' video.channel_id %}">{{ video.channel_name }}</a>
{% else %}
<span>{{ video.channel_name }}</span>
{% endif %}
<a href="https://www.youtube.com/watch?v={{ video.youtube_id }}" target="_blank"><h3>{{ video.title }}</h3></a>
</div>
<p>Published: {{ video.published }} | Duration: {{ video.duration }} | {{ video.youtube_id }}</p>
{% if video.message %}
<p class="danger-zone">{{ video.message }}</p>
{% endif %}
<div>
{% if show_ignored_only %}
<button data-id="{{ video.youtube_id }}" onclick="forgetIgnore(this)">Forget</button>
<button data-id="{{ video.youtube_id }}" onclick="addSingle(this)">Add to queue</button>
{% else %}
<button data-id="{{ video.youtube_id }}" onclick="toIgnore(this)">Ignore</button>
<button id="{{ video.youtube_id }}" data-id="{{ video.youtube_id }}" onclick="downloadNow(this)">Download now</button>
{% endif %}
{% if video.message %}
<button class="danger-button" data-id="{{ video.youtube_id }}" onclick="forgetIgnore(this)">Delete</button>
{% endif %}
</div>
</div>
</div>
{% endfor %}
{% endif %}
</div>
</div>
<script type="text/javascript" src="{% static 'progress.js' %}"></script>
{% endblock content %}

View File

@@ -1,137 +0,0 @@
{% extends "home/base.html" %}
{% block content %}
{% load static %}
<div class="boxed-content {% if view_style == "grid" %}boxed-{{ grid_items }}{% endif %}">
{% if continue_vids %}
<div class="title-bar">
<h1>Continue Watching</h1>
</div>
<div class="video-list {{ view_style }} {% if view_style == "grid" %}grid-{{ grid_items }}{% endif %}">
{% for video in continue_vids %}
<div class="video-item {{ view_style }}">
<a href="#player" data-id="{{ video.youtube_id }}" onclick="createPlayer(this)">
<div class="video-thumb-wrap {{ view_style }}">
<div class="video-thumb">
<img src="{{ video.vid_thumb_url }}" alt="video-thumb">
{% if video.player.progress %}
<div class="video-progress-bar" id="progress-{{ video.youtube_id }}" style="width: {{video.player.progress}}%;"></div>
{% else %}
<div class="video-progress-bar" id="progress-{{ video.youtube_id }}" style="width: 0%;"></div>
{% endif %}
</div>
<div class="video-play">
<img src="{% static 'img/icon-play.svg' %}" alt="play-icon">
</div>
</div>
</a>
<div class="video-desc {{ view_style }}">
<div class="video-desc-player" id="video-info-{{ video.youtube_id }}">
{% if video.player.watched %}
<img src="{% static 'img/icon-seen.svg' %}" alt="seen-icon" data-id="{{ video.youtube_id }}" data-status="watched" onclick="updateVideoWatchStatus(this)" class="watch-button" title="Mark as unwatched">
{% else %}
<img src="{% static 'img/icon-unseen.svg' %}" alt="unseen-icon" data-id="{{ video.youtube_id }}" data-status="unwatched" onclick="updateVideoWatchStatus(this)" class="watch-button" title="Mark as watched">
{% endif %}
<span>{{ video.published }} | {{ video.player.duration_str }}</span>
</div>
<div>
<a href="{% url 'channel_id' video.channel.channel_id %}"><h3>{{ video.channel.channel_name }}</h3></a>
<a class="video-more" href="{% url 'video' video.youtube_id %}"><h2>{{ video.title }}</h2></a>
</div>
</div>
</div>
{% endfor %}
</div>
{% endif %}
<div class="title-bar">
<h1>Recent Videos</h1>
</div>
<div class="view-controls three">
<div class="toggle">
<span>Hide watched:</span>
<div class="toggleBox">
<input id="hide_watched" onclick="toggleCheckbox(this)" type="checkbox" {% if hide_watched %}checked{% endif %}>
{% if not hide_watched %}
<label for="" class="ofbtn">Off</label>
{% else %}
<label for="" class="onbtn">On</label>
{% endif %}
</div>
</div>
<div class="sort">
<div id="hidden-form">
<span>Sort by:</span>
<select name="sort_by" id="sort" onchange="sortChange(this)">
<option value="published" {% if sort_by == "published" %}selected{% endif %}>date published</option>
<option value="downloaded" {% if sort_by == "downloaded" %}selected{% endif %}>date downloaded</option>
<option value="views" {% if sort_by == "views" %}selected{% endif %}>views</option>
<option value="likes" {% if sort_by == "likes" %}selected{% endif %}>likes</option>
<option value="duration" {% if sort_by == "duration" %}selected{% endif %}>duration</option>
<option value="filesize" {% if sort_by == "filesize" %}selected{% endif %}>file size</option>
</select>
<select name="sort_order" id="sort-order" onchange="sortChange(this)">
<option value="asc" {% if sort_order == "asc" %}selected{% endif %}>asc</option>
<option value="desc" {% if sort_order == "desc" %}selected{% endif %}>desc</option>
</select>
</div>
</div>
<div class="view-icons">
<img src="{% static 'img/icon-sort.svg' %}" alt="sort-icon" onclick="showForm()" id="animate-icon">
{% if view_style == "grid" %}
<div class="grid-count">
{% if grid_items < 7 %}
<img src="{% static 'img/icon-add.svg' %}" onclick="changeGridItems(this)" data-value="{{ grid_items|add:"1"}}" alt="grid plus row">
{% endif %}
{% if grid_items > 3 %}
<img src="{% static 'img/icon-substract.svg' %}" onclick="changeGridItems(this)" data-value="{{ grid_items|add:"-1"}}" alt="grid minus row">
{% endif %}
</div>
{% endif %}
<img src="{% static 'img/icon-gridview.svg' %}" onclick="changeView(this)" data-origin="home" data-value="grid" alt="grid view">
<img src="{% static 'img/icon-listview.svg' %}" onclick="changeView(this)" data-origin="home" data-value="list" alt="list view">
</div>
</div>
</div>
<div id="player" class="player-wrapper"></div>
<div class="boxed-content {% if view_style == "grid" %}boxed-{{ grid_items }}{% endif %}">
<div class="video-list {{ view_style }} {% if view_style == "grid" %}grid-{{ grid_items }}{% endif %}">
{% if results %}
{% for video in results %}
<div class="video-item {{ view_style }}">
<a href="#player" data-id="{{ video.youtube_id }}" onclick="createPlayer(this)">
<div class="video-thumb-wrap {{ view_style }}">
<div class="video-thumb">
<img src="{{ video.vid_thumb_url }}" alt="video-thumb">
{% if video.player.progress %}
<div class="video-progress-bar" id="progress-{{ video.youtube_id }}" style="width: {{video.player.progress}}%;"></div>
{% else %}
<div class="video-progress-bar" id="progress-{{ video.youtube_id }}" style="width: 0%;"></div>
{% endif %}
</div>
<div class="video-play">
<img src="{% static 'img/icon-play.svg' %}" alt="play-icon">
</div>
</div>
</a>
<div class="video-desc {{ view_style }}">
<div class="video-desc-player" id="video-info-{{ video.youtube_id }}">
{% if video.player.watched %}
<img src="{% static 'img/icon-seen.svg' %}" alt="seen-icon" data-id="{{ video.youtube_id }}" data-status="watched" onclick="updateVideoWatchStatus(this)" class="watch-button" title="Mark as unwatched">
{% else %}
<img src="{% static 'img/icon-unseen.svg' %}" alt="unseen-icon" data-id="{{ video.youtube_id }}" data-status="unwatched" onclick="updateVideoWatchStatus(this)" class="watch-button" title="Mark as watched">
{% endif %}
<span>{{ video.published }} | {{ video.player.duration_str }}</span>
</div>
<div>
<a href="{% url 'channel_id' video.channel.channel_id %}"><h3>{{ video.channel.channel_name }}</h3></a>
<a class="video-more" href="{% url 'video' video.youtube_id %}"><h2>{{ video.title }}</h2></a>
</div>
</div>
</div>
{% endfor %}
{% else %}
<h2>No videos found...</h2>
<p>If you've already added a channel or playlist, try going to the <a href="{% url 'downloads' %}">downloads page</a> to start the scan and download tasks.</p>
{% endif %}
</div>
</div>
{% endblock content %}

View File

@@ -1,47 +0,0 @@
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>TA | Welcome</title>
<link rel="stylesheet" type="text/css" href="{% static 'css/style.css' %}">
<link rel="apple-touch-icon" sizes="180x180" href="{% static 'favicon/apple-touch-icon.png' %}">
<link rel="icon" type="image/png" sizes="32x32" href="{% static 'favicon/favicon-32x32.png' %}">
<link rel="icon" type="image/png" sizes="16x16" href="{% static 'favicon/favicon-16x16.png' %}">
<link rel="manifest" href="{% static 'favicon/site.webmanifest' %}">
<link rel="mask-icon" href="{% static 'favicon/safari-pinned-tab.svg' %}" color="#01202e">
<link rel="shortcut icon" href="{% static 'favicon/favicon.ico' %}">
<meta name="apple-mobile-web-app-title" content="TubeArchivist">
<meta name="application-name" content="TubeArchivist">
<meta name="msapplication-TileColor" content="#01202e">
<meta name="msapplication-config" content="{% static 'favicon/browserconfig.xml' %}">
<meta name="theme-color" content="#01202e">
<link rel="stylesheet" href="{% static 'css/' %}{{ stylesheet }}">
</head>
<body>
<div class="boxed-content login-page">
<img alt="tube-archivist-logo">
<h1>Tube Archivist</h1>
<h2>Your Self Hosted YouTube Media Server</h2>
{% if form_error %}
<p class="danger-zone">Failed to login.</p>
{% endif %}
<form action="/login/" method="POST" name="login">
{% csrf_token %}
{{ form.username }}<br>
{{ form.password }}<br>
<p>Remember me: {{ form.remember_me }}</p>
<input type="hidden" name="next" value="{{ request.GET.next }}" />
<button type="submit">Login</button>
</form>
<p class="login-links"><span><a href="https://github.com/tubearchivist/tubearchivist" target="_blank">Github</a></span> <span><a href="https://github.com/tubearchivist/tubearchivist#donate" target="_blank">Donate</a></span></p>
</div>
<div class="footer-colors">
<div class="col-1"></div>
<div class="col-2"></div>
<div class="col-3"></div>
</div>
</body>
</html>

View File

@@ -1,80 +0,0 @@
{% extends "home/base.html" %}
{% load static %}
{% block content %}
{% load auth_extras %}
<div class="boxed-content">
<div class="title-split">
<div class="title-bar">
<h1>Playlists</h1>
</div>
{% if request.user|has_group:"admin" or request.user.is_staff %}
<div class="title-split-form">
<img id="animate-icon" onclick="showForm();showForm('hidden-form2')" src="{% static 'img/icon-add.svg' %}" alt="add-icon" title="Subscribe to Playlists">
<div class="show-form">
<form id="hidden-form" action="/playlist/" method="post">
{% csrf_token %}
{{ subscribe_form }}
<button type="submit">Subscribe</button>
</form>
<form id="hidden-form2" action="/playlist/" method="post">
{% csrf_token %}
{{ create_form }}
<button type="submit">Create</button>
</form>
</div>
</div>
{% endif %}
</div>
<div id="notifications" data="subscription"></div>
<div class="view-controls">
<div class="toggle">
<span>Show subscribed only:</span>
<div class="toggleBox">
<input id="show_subed_only" onclick="toggleCheckbox(this)" type="checkbox" {% if show_subed_only %}checked{% endif %}>
{% if not show_subed_only %}
<label for="" class="ofbtn">Off</label>
{% else %}
<label for="" class="onbtn">On</label>
{% endif %}
</div>
</div>
<div class="view-icons">
<img src="{% static 'img/icon-gridview.svg' %}" onclick="changeView(this)" data-origin="playlist" data-value="grid" alt="grid view">
<img src="{% static 'img/icon-listview.svg' %}" onclick="changeView(this)" data-origin="playlist" data-value="list" alt="list view">
</div>
</div>
<div class="playlist-list {{ view_style }}">
{% if results %}
{% for playlist in results %}
<div class="playlist-item {{ view_style }}">
<div class="playlist-thumbnail">
<a href="{% url 'playlist_id' playlist.playlist_id %}">
<img src="{{ playlist.playlist_thumbnail }}" alt="{{ playlist.playlist_id }}-thumbnail">
</a>
</div>
<div class="playlist-desc {{ view_style }}">
{% if playlist.playlist_type != "custom" %}
<a href="{% url 'channel_id' playlist.playlist_channel_id %}"><h3>{{ playlist.playlist_channel }}</h3></a>
{% endif %}
<a href="{% url 'playlist_id' playlist.playlist_id %}"><h2>{{ playlist.playlist_name }}</h2></a>
<p>Last refreshed: {{ playlist.playlist_last_refresh }}</p>
{% if playlist.playlist_type != "custom" %}
{% if playlist.playlist_subscribed %}
<button class="unsubscribe" type="button" data-type="playlist" data-subscribe="" data-id="{{ playlist.playlist_id }}" onclick="subscribeStatus(this)" title="Unsubscribe from {{ playlist.playlist_name }}">Unsubscribe</button>
{% else %}
<button type="button" data-type="playlist" data-subscribe="true" data-id="{{ playlist.playlist_id }}" onclick="subscribeStatus(this)" title="Subscribe to {{ playlist.playlist_name }}">Subscribe</button>
{% endif %}
{% endif %}
</div>
</div>
{% endfor %}
{% else %}
<h2>No playlists found...</h2>
{% endif %}
</div>
</div>
<script type="text/javascript" src="{% static 'progress.js' %}"></script>
{% endblock content %}

View File

@@ -1,180 +0,0 @@
{% extends "home/base.html" %}
{% load static %}
{% load humanize %}
{% block content %}
{% load auth_extras %}
<div class="boxed-content">
<div class="title-bar">
<h1>{{ playlist_info.playlist_name }}</h1>
</div>
<div class="info-box info-box-3">
{% if playlist_info.playlist_type != "custom" %}
<div class="info-box-item">
<div class="round-img">
<a href="{% url 'channel_id' channel_info.channel_id %}">
<img src="{{ channel_info.channel_thumb_url }}" alt="channel-thumb">
</a>
</div>
<div>
<h3><a href="{% url 'channel_id' channel_info.channel_id %}">{{ channel_info.channel_name }}</a></h3>
{% if channel_info.channel_subs >= 1000000 %}
<span>Subscribers: {{ channel_info.channel_subs|intword }}</span>
{% else %}
<span>Subscribers: {{ channel_info.channel_subs|intcomma }}</span>
{% endif %}
</div>
</div>
{% endif %}
<div class="info-box-item">
<div>
<p>Last refreshed: {{ playlist_info.playlist_last_refresh }}</p>
{% if playlist_info.playlist_type != "custom" %}
<p>Playlist:
{% if playlist_info.playlist_subscribed %}
{% if request.user|has_group:"admin" or request.user.is_staff %}
<button class="unsubscribe" type="button" data-type="playlist" data-subscribe="" data-id="{{ playlist_info.playlist_id }}" onclick="subscribeStatus(this)" title="Unsubscribe from {{ playlist_info.playlist_name }}">Unsubscribe</button>
{% endif %}
{% else %}
<button type="button" data-type="playlist" data-subscribe="true" data-id="{{ playlist_info.playlist_id }}" onclick="subscribeStatus(this)" title="Subscribe to {{ playlist_info.playlist_name }}">Subscribe</button>
{% endif %}
</p>
{% if playlist_info.playlist_active %}
<p>Youtube: <a href="https://www.youtube.com/playlist?list={{ playlist_info.playlist_id }}" target="_blank">Active</a></p>
{% else %}
<p>Youtube: Deactivated</p>
{% endif %}
{% endif %}
<button onclick="deleteConfirm()" id="delete-item">Delete Playlist</button>
<div class="delete-confirm" id="delete-button">
<span>Delete {{ playlist_info.playlist_name }}?</span>
<button onclick="deletePlaylist(this)" data-action="" data-id="{{ playlist_info.playlist_id }}">Delete metadata</button>
<button onclick="deletePlaylist(this)" data-action="delete-videos" class="danger-button" data-id="{{ playlist_info.playlist_id }}">Delete all</button><br>
<button onclick="cancelDelete()">Cancel</button>
</div>
</div>
</div>
<div class="info-box-item">
<div>
{% if max_hits %}
<p>Total Videos archived: {{ max_hits }}/{{ playlist_info.playlist_entries|length }}</p>
<div id="watched-button" class="button-box">
<button title="Mark all videos from {{ playlist_info.playlist_name }} as watched" type="button" id="watched-button" data-id="{{ playlist_info.playlist_id }}" onclick="isWatchedButton(this)">Mark as watched</button>
<button title="Mark all videos from {{ playlist_info.playlist_name }} as unwatched" type="button" id="unwatched-button" data-id="{{ playlist_info.playlist_id }}" onclick="isUnwatchedButton(this)">Mark as unwatched</button>
</div>
{% endif %}
{% if reindex %}
<p>Reindex scheduled</p>
{% else %}
<div id="reindex-button" class="button-box">
{% if playlist_info.playlist_type != "custom" %}
<button data-id="{{ playlist_info.playlist_id }}" data-type="playlist" onclick="reindex(this)" title="Reindex Playlist {{ playlist_info.playlist_name }}">Reindex</button>
{% endif %}
<button data-id="{{ playlist_info.playlist_id }}" data-type="playlist" data-extract-videos="true" onclick="reindex(this)" title="Reindex Videos of {{ playlist_info.playlist_name }}">Reindex Videos</button>
</div>
{% endif %}
</div>
</div>
</div>
{% if playlist_info.playlist_description %}
<div class="description-box">
<p id="text-expand" class="description-text">
{{ playlist_info.playlist_description|linebreaksbr|urlizetrunc:50 }}
</p>
<button onclick="textExpand()" id="text-expand-button">Show more</button>
</div>
{% endif %}
</div>
<div class="boxed-content {% if view_style == "grid" %}boxed-{{ grid_items }}{% endif %}">
<div class="view-controls">
<div class="toggle">
<span>Hide watched videos:</span>
<div class="toggleBox">
<input id="hide_watched" onclick="toggleCheckbox(this)" type="checkbox" {% if hide_watched %}checked{% endif %}>
{% if not hide_watched %}
<label for="" class="ofbtn">Off</label>
{% else %}
<label for="" class="onbtn">On</label>
{% endif %}
</div>
</div>
<div class="view-icons">
{% if view_style == "grid" %}
<div class="grid-count">
{% if grid_items < 7 %}
<img src="{% static 'img/icon-add.svg' %}" onclick="changeGridItems(this)" data-value="{{ grid_items|add:"1"}}" alt="grid plus row">
{% endif %}
{% if grid_items > 3 %}
<img src="{% static 'img/icon-substract.svg' %}" onclick="changeGridItems(this)" data-value="{{ grid_items|add:"-1"}}" alt="grid minus row">
{% endif %}
</div>
{% endif %}
<img src="{% static 'img/icon-gridview.svg' %}" onclick="changeView(this)" data-origin="home" data-value="grid" alt="grid view">
<img src="{% static 'img/icon-listview.svg' %}" onclick="changeView(this)" data-origin="home" data-value="list" alt="list view">
</div>
</div>
</div>
<div id="player" class="player-wrapper"></div>
<div class="boxed-content {% if view_style == "grid" %}boxed-{{ grid_items }}{% endif %}">
<div class="video-list {{ view_style }} {% if view_style == "grid" %}grid-{{ grid_items }}{% endif %}">
{% if results %}
{% for video in results %}
<div class="video-item {{ view_style }}">
<a href="#player" data-id="{{ video.youtube_id }}" onclick="createPlayer(this)">
<div class="video-thumb-wrap {{ view_style }}">
<div class="video-thumb">
<img src="{{ video.vid_thumb_url }}" alt="video-thumb">
{% if video.player.progress %}
<div class="video-progress-bar" id="progress-{{ video.youtube_id }}" style="width: {{video.player.progress}}%;"></div>
{% else %}
<div class="video-progress-bar" id="progress-{{ video.youtube_id }}" style="width: 0%;"></div>
{% endif %}
</div>
<div class="video-play">
<img src="{% static 'img/icon-play.svg' %}" alt="play-icon">
</div>
</div>
</a>
<div class="video-desc {{ view_style }}">
<div class="video-desc-player" id="video-info-{{ video.youtube_id }}">
{% if video.player.watched %}
<img src="{% static 'img/icon-seen.svg' %}" alt="seen-icon" data-id="{{ video.youtube_id }}" data-status="watched" onclick="updateVideoWatchStatus(this)" class="watch-button" title="Mark as unwatched">
{% else %}
<img src="{% static 'img/icon-unseen.svg' %}" alt="unseen-icon" data-id="{{ video.youtube_id }}" data-status="unwatched" onclick="updateVideoWatchStatus(this)" class="watch-button" title="Mark as watched">
{% endif %}
<span>{{ video.published }} | {{ video.player.duration_str }}</span>
</div>
<div class="video-desc-details">
<div>
{% if playlist_info.playlist_type == "custom" %}
<a href="{% url 'channel_id' video.channel.channel_id %}"><h3>{{ video.channel.channel_name }}</h3></a>
{% endif %}
<a class="video-more" href="{% url 'video' video.youtube_id %}"><h2>{{ video.title }}</h2></a>
</div>
{% if playlist_info.playlist_type == "custom" %}
{% if pagination %}
{% if pagination.last_page > 0 %}
<img id="{{ video.youtube_id }}-button" src="{% static 'img/icon-dot-menu.svg' %}" alt="dot-menu-icon" data-id="{{ video.youtube_id }}" data-context="video" onclick="showCustomPlaylistMenu(this,'{{playlist_info.playlist_id}}',{{pagination.current_page}},{{pagination.last_page}})" class="dot-button" title="More actions">
{% else %}
<img id="{{ video.youtube_id }}-button" src="{% static 'img/icon-dot-menu.svg' %}" alt="dot-menu-icon" data-id="{{ video.youtube_id }}" data-context="video" onclick="showCustomPlaylistMenu(this,'{{playlist_info.playlist_id}}',{{pagination.current_page}},{{pagination.current_page}})" class="dot-button" title="More actions">
{% endif %}
{% else %}
<img id="{{ video.youtube_id }}-button" src="{% static 'img/icon-dot-menu.svg' %}" alt="dot-menu-icon" data-id="{{ video.youtube_id }}" data-context="video" onclick="showCustomPlaylistMenu(this,'{{playlist_info.playlist_id}}',0,0)" class="dot-button" title="More actions">
{% endif %}
{% endif %}
</div>
</div>
</div>
{% endfor %}
{% else %}
<h2>No videos found...</h2>
{% if playlist_info.playlist_type == "custom" %}
<p>Try going to the <a href="{% url 'home' %}">home page</a> to add videos to this playlist.</p>
{% else %}
<p>Try going to the <a href="{% url 'downloads' %}">downloads page</a> to start the scan and download tasks.</p>
{% endif %}
{% endif %}
</div>
</div>
{% endblock content %}

View File

@@ -1,87 +0,0 @@
{% extends "home/base.html" %}
{% block content %}
<div id="player" class="player-wrapper"></div>
<div class="boxed-content {% if all_styles.home == "grid" %}boxed-{{ grid_items }}{% endif %}">
<div class="title-bar">
<h1>Search your Archive</h1>
</div>
<div class="multi-search-box">
{{ search_form }}
</div>
<div id="multi-search-results" style="display: none;">
<div class="multi-search-result">
<h2>Video Results</h2>
<div id="video-results" class="video-list {{ all_styles.home }} {% if all_styles.home == "grid" %}grid-{{ grid_items }}{% endif %}">
<p>No videos found.</p>
</div>
</div>
<div class="multi-search-result">
<h2>Channel Results</h2>
<div id="channel-results" class="channel-list {{ all_styles.channel }}">
<p>No channels found.</p>
</div>
</div>
<div class="multi-search-result">
<h2>Playlist Results</h2>
<div id="playlist-results" class="playlist-list {{ all_styles.playlist }}">
<p>No playlists found.</p>
</div>
</div>
<div class="multi-search-result">
<h2>Fulltext Results</h2>
<div id="fulltext-results" class="video-list list">
<p>No fulltext results found.</p>
</div>
</div>
</div>
<div id="multi-search-results-placeholder" style="display: block;">
<div>
<h2>Example queries</h2>
<ul>
<li><span class="value">music video</span> — basic search</li>
<li><span>video: active:</span><span class="value">no</span> — all videos deleted from YouTube</li>
<li><span>video:</span><span class="value">learn javascript</span><span> channel:</span><span class="value">corey schafer</span><span> active:</span><span class="value">yes</span></li>
<li><span>channel:</span><span class="value">linux</span><span> subscribed:</span><span class="value">yes</span></li>
<li><span>playlist:</span><span class="value">backend engineering</span><span> active:</span><span class="value">yes</span><span> subscribed:</span><span class="value">yes</span></li>
</ul>
</div>
<div>
<h2>Keywords cheatsheet</h2>
<p>For detailed usage check <a href="https://docs.tubearchivist.com/search/" target="_blank">wiki</a>.</p>
<div>
<ul>
<li><span>simple:</span> (implied) — search in video titles, channel names and playlist titles</li>
<li>
<span>video:</span> — search in video titles, tags and category field
<ul>
<li><span>channel:</span> — channel name</li>
<li><span>active:</span><span class="value">yes/no</span> — whether the video is still active on YouTube</li>
</ul>
</li>
<li>
<span>channel:</span> — search in channel name and channel description
<ul>
<li><span>subscribed:</span><span class="value">yes/no</span> — whether you are subscribed to the channel</li>
<li><span>active:</span><span class="value">yes/no</span> — whether the video is still active on YouTube</li>
</ul>
</li>
<li>
<span>playlist:</span> — search in channel name and channel description
<ul>
<li><span>subscribed:</span><span class="value">yes/no</span> — whether you are subscribed to the channel</li>
<li><span>active:</span><span class="value">yes/no</span> — whether the video is still active on YouTube</li>
</ul>
</li>
<li>
<span>full:</span> — search in video subtitles
<ul>
<li><span>lang:</span> — subtitles language (use two-letter ISO country code, same as the one from settings page)</li>
<li><span>source:</span><span class="value">auto/user</span><i>auto</i> to search though auto-generated subtitles only, or <i>user</i> to search through user-uploaded subtitles only</li>
</ul>
</li>
</ul>
</div>
</div>
</div>
</div>
{% endblock content %}

View File

@@ -1,80 +0,0 @@
{% extends "home/base_settings.html" %}
{% load static %}
{% block settings_content %}
<div class="title-bar">
<h1>Your Archive</h1>
</div>
<div class="settings-item">
<h2>Overview</h2>
<div id="activeBox" class="info-box info-box-3">
<p id="loading">Loading...</p>
</div>
</div>
<div class="settings-item">
<h2>Video Type</h2>
<div id="videoTypeBox" class="info-box info-box-3">
<p id="loading">Loading...</p>
</div>
</div>
<div class="settings-item">
<h2>Application</h2>
<div id="secondaryBox" class="info-box info-box-3">
<p id="loading">Loading...</p>
</div>
</div>
<div class="settings-item">
<h2>Watch Progress</h2>
<div id="watchBox" class="info-box info-box-2">
<p id="loading">Loading...</p>
</div>
</div>
<div class="settings-item">
<h2>Download History</h2>
<div id="downHistBox" class="info-box info-box-4">
<p id="loading">Loading...</p>
</div>
</div>
<div class="settings-item">
<h2>Biggest Channels</h2>
<div class="info-box info-box-3">
<div class="info-box-item">
<table class="agg-channel-table">
<thead>
<tr>
<th>Name</th>
<th class="agg-channel-right-align">Videos</th>
</tr>
</thead>
<tbody id="biggestChannelTableVideos"></tbody>
</table>
</div>
<div class="info-box-item">
<table class="agg-channel-table">
<thead>
<tr>
<th>Name</th>
<th class="agg-channel-right-align">Duration</th>
</tr>
</thead>
<tbody id="biggestChannelTableDuration"></tbody>
</table>
</div>
<div class="info-box-item">
<table class="agg-channel-table">
<thead>
<tr>
<th>Name</th>
<th class="agg-channel-right-align">Media Size</th>
</tr>
</thead>
<tbody id="biggestChannelTableMediaSize"></tbody>
</table>
</div>
</div>
</div>
<script type="text/javascript" src="{% static 'stats.js' %}"></script>
{% endblock settings_content %}

View File

@@ -1,66 +0,0 @@
{% extends "home/base_settings.html" %}
{% load static %}
{% block settings_content %}
<div class="title-bar">
<h1>Actions</h1>
</div>
<div class="settings-group">
<h2>Delete download queue</h2>
<p>Delete your pending or previously ignored videos from your download queue.<p>
<button onclick="deleteQueue(this)" id="ignore-button" data-id="ignore" title="Delete all previously ignored videos from the queue">Delete all ignored</button>
<button onclick="deleteQueue(this)" id="pending-button" data-id="pending" title="Delete all pending videos from the queue">Delete all queued</button>
</div>
<div class="settings-group">
<h2>Manual media files import.</h2>
<p>Add files to the <span class="settings-current">cache/import</span> folder. Make sure to follow the instructions in the Github <a href="https://docs.tubearchivist.com/settings/actions/#manual-media-files-import" target="_blank">Wiki</a>.</p>
<div id="manual-import">
<button onclick="manualImport()">Start import</button>
</div>
</div>
<div class="settings-group">
<h2>Embed thumbnails into media file.</h2>
<p>Set extracted youtube thumbnail as cover art of the media file.</p>
<div id="re-embed">
<button onclick="reEmbed()">Start process</button>
</div>
</div>
<div class="settings-group">
<h2>ZIP file index backup</h2>
<p>Export your database to a zip file stored at <span class="settings-current">cache/backup</span>.</p>
<p><i>Zip file backups are very slow for large archives and consistency is not guaranteed, use snapshots instead. Make sure no other tasks are running when creating a Zip file backup.</i></p>
<div id="db-backup">
<button onclick="dbBackup()">Start backup</button>
</div>
</div>
<div class="settings-group">
<h2>Restore from backup</h2>
<p><span class="danger-zone">Danger Zone</span>: This will replace your existing index with the backup.</p>
<p>Restore from available backup files from <span class="settings-current">cache/backup</span>.</p>
{% if available_backups %}
<div class="backup-grid-row">
<span></span>
<span>Timestamp</span>
<span>Source</span>
<span>Filename</span>
</div>
{% for backup in available_backups %}
<div class="backup-grid-row" id="{{ backup.filename }}">
<button onclick="dbRestore(this)" data-id="{{ backup.filename }}">Restore</button>
<span>{{ backup.timestamp }}</span>
<span>{{ backup.reason }}</span>
<span>{{ backup.filename }}</span>
</div>
{% endfor %}
{% else %}
<p>No backups found.</p>
{% endif %}
</div>
<div class="settings-group">
<h2>Rescan filesystem</h2>
<p><span class="danger-zone">Danger Zone</span>: This will delete the metadata of deleted videos from the filesystem.</p>
<p>Rescan your media folder looking for missing videos and clean up index. More infos on the Github <a href="https://docs.tubearchivist.com/settings/actions/#rescan-filesystem" target="_blank">Wiki</a>.</p>
<div id="fs-rescan">
<button onclick="fsRescan()">Rescan filesystem</button>
</div>
</div>
{% endblock settings_content %}

View File

@@ -1,192 +0,0 @@
{% extends "home/base_settings.html" %}
{% load static %}
{% block settings_content %}
<div class="title-bar">
<h1>Application Configurations</h1>
</div>
<form action="{% url 'settings_application' %}" method="POST" name="application-update">
{% csrf_token %}
<div class="settings-group">
<h2 id="subscriptions">Subscriptions</h2>
<p>Disable shorts or streams by setting their page size to 0 (zero).</p>
<div class="settings-item">
<p>YouTube page size: <span class="settings-current">{{ config.subscriptions.channel_size }}</span></p>
<i>Videos to scan to find new items for the <b>Rescan subscriptions</b> task, max recommended 50.</i><br>
{{ app_form.subscriptions_channel_size }}
</div>
<div class="settings-item">
<p>YouTube Live page size: <span class="settings-current">{{ config.subscriptions.live_channel_size }}</span></p>
<i>Live Videos to scan to find new items for the <b>Rescan subscriptions</b> task, max recommended 50.</i><br>
{{ app_form.subscriptions_live_channel_size }}
</div>
<div class="settings-item">
<p>YouTube Shorts page size: <span class="settings-current">{{ config.subscriptions.shorts_channel_size }}</span></p>
<i>Shorts Videos to scan to find new items for the <b>Rescan subscriptions</b> task, max recommended 50.</i><br>
{{ app_form.subscriptions_shorts_channel_size }}
</div>
<div class="settings-item">
<p>Auto start download from your subscriptions: <span class="settings-current">{{ config.subscriptions.auto_start}}</span></p>
<i>Enable this will automatically start and prioritize videos from your subscriptions.</i><br>
{{ app_form.subscriptions_auto_start }}
</div>
</div>
<div class="settings-group">
<h2 id="downloads">Downloads</h2>
<div class="settings-item">
<p>Current download speed limit in KB/s: <span class="settings-current">{{ config.downloads.limit_speed }}</span></p>
<i>Limit download speed. 0 (zero) to deactivate, e.g. 1000 (1MB/s). Speeds are in KB/s. Setting takes effect on new download jobs or application restart.</i><br>
{{ app_form.downloads_limit_speed }}
</div>
<div class="settings-item">
<p>Current throttled rate limit in KB/s: <span class="settings-current">{{ config.downloads.throttledratelimit }}</span></p>
<i>Download will restart if speeds drop below specified amount. 0 (zero) to deactivate, e.g. 100. Speeds are in KB/s.</i><br>
{{ app_form.downloads_throttledratelimit }}
</div>
<div class="settings-item">
<p>Current scraping sleep interval: <span class="settings-current">{{ config.downloads.sleep_interval }}</p>
<i>Seconds to sleep between calls to YouTube. Might be necessary to avoid throttling. Recommended 3.</i><br>
{{ app_form.downloads_sleep_interval }}
</div>
<div class="settings-item">
<p><span class="danger-zone">Danger Zone</span>: Current auto delete watched videos: <span class="settings-current">{{ config.downloads.autodelete_days }}</span></p>
<i>Auto delete watched videos after x days, 0 (zero) to deactivate:</i><br>
{{ app_form.downloads_autodelete_days }}
</div>
</div>
<div class="settings-group">
<h2 id="format">Download Format</h2>
<div class="settings-item">
<p>Limit video and audio quality format for yt-dlp.<br>
Currently: <span class="settings-current">{{ config.downloads.format }}</span>
</p>
<p>Example configurations:</p>
<ul>
<li><span class="settings-current">bestvideo[height<=720]+bestaudio/best[height<=720]</span>: best audio and max video height of 720p.</li>
<li><span class="settings-current">bestvideo[height<=1080]+bestaudio/best[height<=1080]</span>: best audio and max video height of 1080p.</li>
<li><span class="settings-current">bestvideo[height<=1080][vcodec*=avc1]+bestaudio[acodec*=mp4a]/mp4</span>: Max 1080p video height with iOS compatible video and audio codecs.</li>
<li><span class="settings-current">0</span>: deactivate and download the best quality possible as decided by yt-dlp.</li>
</ul>
<i>Make sure your custom format gets merged into a single file. Check out the <a href="https://github.com/yt-dlp/yt-dlp#format-selection" target="_blank">documentation</a> for valid configurations.</i><br>
{{ app_form.downloads_format }}
<br>
</div>
<div class="settings-item">
<p>Force sort order to have precedence over all yt-dlp fields.<br>
Currently: <span class="settings-current">{{ config.downloads.format_sort }}</span>
</p>
<p>Example configurations:</p>
<ul>
<li><span class="settings-current">res,codec:av1</span>: prefer AV1 over all other video codecs.</li>
<li><span class="settings-current">0</span>: deactivate and keep the default as decided by yt-dlp.</li>
</ul>
<i>Not all codecs are supported by all browsers. The default value ensures best compatibility. Check out the <a href="https://github.com/yt-dlp/yt-dlp#sorting-formats" target="_blank">documentation</a> for valid configurations.</i><br>
{{ app_form.downloads_format_sort }}
<br>
</div>
<div class="settings-item">
<p>Prefer translated metadata language: <span class="settings-current">{{ config.downloads.extractor_lang }}</span></p>
<i>This will change the language this video gets indexed as. That will only be available if the uploader provides translations. Add as two letter ISO language code, check the <a href="https://github.com/yt-dlp/yt-dlp#youtube" target="_blank">documentation</a> which languages are available.</i><br>
{{ app_form.downloads_extractor_lang}}
</div>
<div class="settings-item">
<p>Current metadata embed setting: <span class="settings-current">{{ config.downloads.add_metadata }}</span></p>
<i>Metadata is not embedded into the downloaded files by default.</i><br>
{{ app_form.downloads_add_metadata }}
</div>
<div class="settings-item">
<p>Current thumbnail embed setting: <span class="settings-current">{{ config.downloads.add_thumbnail }}</span></p>
<i>Embed thumbnail into the mediafile.</i><br>
{{ app_form.downloads_add_thumbnail }}
</div>
</div>
<div class="settings-group">
<h2 id="format">Subtitles</h2>
<div class="settings-item">
<p>Subtitles download setting: <span class="settings-current">{{ config.downloads.subtitle }}</span><br>
<i>Choose which subtitles to download, add comma separated language codes,<br>
e.g. <span class="settings-current">en, de, zh-Hans</span></i><br>
{{ app_form.downloads_subtitle }}</p>
</div>
<div class="settings-item">
<p>Subtitle source settings: <span class="settings-current">{{ config.downloads.subtitle_source }}</span></p>
<i>Download only user generated, or also less accurate auto generated subtitles.</i><br>
{{ app_form.downloads_subtitle_source }}
</div>
<div class="settings-item">
<p>Index and make subtitles searchable: <span class="settings-current">{{ config.downloads.subtitle_index }}</span></p>
<i>Store subtitle lines in Elasticsearch. Not recommended for low-end hardware.</i><br>
{{ app_form.downloads_subtitle_index }}
</div>
</div>
<div class="settings-group">
<h2 id="comments">Comments</h2>
<div class="settings-item">
<p>Download and index comments: <span class="settings-current">{{ config.downloads.comment_max }}</span><br>
<i>Follow the yt-dlp max_comments documentation, <a href="https://github.com/yt-dlp/yt-dlp#youtube" target="_blank">max-comments,max-parents,max-replies,max-replies-per-thread</a>:</i><br>
<p>Example configurations:</p>
<ul>
<li><span class="settings-current">all,100,all,30</span>: Get 100 max-parents and 30 max-replies-per-thread.</li>
<li><span class="settings-current">1000,all,all,50</span>: Get a total of 1000 comments over all, 50 replies per thread.</li>
</ul>
{{ app_form.downloads_comment_max }}</p>
</div>
<div class="settings-item">
<p>Selected comment sort method: <span class="settings-current">{{ config.downloads.comment_sort }}</span><br>
<i>Select how many comments and threads to download:</i><br>
{{ app_form.downloads_comment_sort }}</p>
</div>
</div>
<div class="settings-group">
<h2 id="format">Cookie</h2>
<div class="settings-item">
<p>Import YouTube cookie: <span class="settings-current">{{ config.downloads.cookie_import }}</span><br></p>
<p>For automatic cookie import use <b>Tube Archivist Companion</b> <a href="https://github.com/tubearchivist/browser-extension" target="_blank">browser extension</a>.</p>
<i>For manual cookie import, place your cookie file named <span class="settings-current">cookies.google.txt</span> in <span class="settings-current">cache/import</span> before enabling. Instructions in the <a href="https://docs.tubearchivist.com/settings/application/#cookie" target="_blank">Wiki.</a></i><br>
{{ app_form.downloads_cookie_import }}<br>
{% if config.downloads.cookie_import %}
<div id="cookieMessage">
<button onclick="handleCookieValidate()" type="button" id="cookieButton">Validate Cookie File</button>
</div>
{% endif %}
</div>
</div>
<div class="settings-group">
<h2 id="integrations">Integrations</h2>
<div class="settings-item">
<p>API token: <button type="button" onclick="textReveal(this)" id="text-reveal-button">Show</button></p>
<div id="text-reveal" class="description-text">
<p>{{ api_token }}</p>
<button class="danger-button" type="button" onclick="resetToken()">Revoke</button>
</div>
</div>
<div class="settings-item">
<p>Integrate with <a href="https://returnyoutubedislike.com/" target="_blank">returnyoutubedislike.com</a> to get dislikes and average ratings back: <span class="settings-current">{{ config.downloads.integrate_ryd }}</span></p>
<i>Before activating that, make sure you have a scraping sleep interval of at least 3 secs set to avoid ratelimiting issues.</i><br>
{{ app_form.downloads_integrate_ryd }}
</div>
<div class="settings-item">
<p>Integrate with <a href="https://sponsor.ajay.app/" target="_blank">SponsorBlock</a> to get sponsored timestamps: <span class="settings-current">{{ config.downloads.integrate_sponsorblock }}</span></p>
<i>Before activating that, make sure you have a scraping sleep interval of at least 3 secs set to avoid ratelimiting issues.</i><br>
{{ app_form.downloads_integrate_sponsorblock }}
</div>
</div>
<div class="settings-group">
<h2 id="snapshots">Snapshots</h2>
<div class="settings-item">
<p>Current system snapshot: <span class="settings-current">{{ config.application.enable_snapshot }}</span></p>
<i>Automatically create daily deduplicated snapshots of the index, stored in Elasticsearch. Read first before activating: <a target="_blank" href="https://docs.tubearchivist.com/settings/application/#snapshots">Wiki</a>.</i><br>
{{ app_form.application_enable_snapshot }}
</div>
<div>
{% if snapshots %}
<p>Create next snapshot: <span class="settings-current">{{ snapshots.next_exec_str }}</span>, snapshots expire after <span class="settings-current">{{ snapshots.expire_after }}</span>. <button onclick="createSnapshot()" id="createButton">Create snapshot now</button></p>
<br>
{% for snapshot in snapshots.snapshots %}
<p><button id="{{ snapshot.id }}" onclick="restoreSnapshot(id)">Restore</button> Snapshot created on: <span class="settings-current">{{ snapshot.start_date }}</span>, took <span class="settings-current">{{ snapshot.duration_s }}s</span> to create. State: <i>{{ snapshot.state }}</i></p>
{% endfor %}
{% endif %}
</div>
</div>
<button type="submit" name="application-settings">Update Application Configurations</button>
</form>
{% endblock settings_content %}

View File

@@ -1,152 +0,0 @@
{% extends "home/base_settings.html" %}
{% load static %}
{% block settings_content %}
<div class="title-bar">
<h1>Scheduler Setup</h1>
<div class="settings-group">
<p>Schedule settings expect a cron like format, where the first value is minute, second is hour and third is day of the week.</p>
<p>Examples:</p>
<ul>
<li><span class="settings-current">0 15 *</span>: Run task every day at 15:00 in the afternoon.</li>
<li><span class="settings-current">30 8 */2</span>: Run task every second day of the week (Sun, Tue, Thu, Sat) at 08:30 in the morning.</li>
<li><span class="settings-current">auto</span>: Sensible default.</li>
</ul>
<p>Note:</p>
<ul>
<li>Avoid an unnecessary frequent schedule to not get blocked by YouTube. For that reason, the scheduler doesn't support schedules that trigger more than once per hour.</li>
</ul>
</div>
</div>
<form action="{% url 'settings_scheduling' %}" method="POST" name="scheduler-update">
{% csrf_token %}
<div class="settings-group">
<h2>Rescan Subscriptions</h2>
<div class="settings-item">
<p>Become a sponsor and join <a href="https://members.tubearchivist.com/" target="_blank">members.tubearchivist.com</a> to get access to <span class="settings-current">real time</span> notifications for new videos uploaded by your favorite channels.</p>
<p>Current rescan schedule: <span class="settings-current">
{% if update_subscribed %}
{{ update_subscribed.crontab.minute }} {{ update_subscribed.crontab.hour }} {{ update_subscribed.crontab.day_of_week }}
<button data-schedule="update_subscribed" onclick="deleteSchedule(this)" class="danger-button">Delete</button>
{% else %}
False
{% endif %}
</span></p>
<p>Periodically rescan your subscriptions:</p>
{% for error in scheduler_form.update_subscribed.errors %}
<p class="danger-zone">{{ error }}</p>
{% endfor %}
{{ scheduler_form.update_subscribed }}
</div>
</div>
<div class="settings-group">
<h2>Start Download</h2>
<div class="settings-item">
<p>Current Download schedule: <span class="settings-current">
{% if download_pending %}
{{ download_pending.crontab.minute }} {{ download_pending.crontab.hour }} {{ download_pending.crontab.day_of_week }}
<button data-schedule="download_pending" onclick="deleteSchedule(this)" class="danger-button">Delete</button>
{% else %}
False
{% endif %}
</span></p>
<p>Automatic video download schedule:</p>
{% for error in scheduler_form.download_pending.errors %}
<p class="danger-zone">{{ error }}</p>
{% endfor %}
{{ scheduler_form.download_pending }}
</div>
</div>
<div class="settings-group">
<h2>Refresh Metadata</h2>
<div class="settings-item">
<p>Current Metadata refresh schedule: <span class="settings-current">
{% if check_reindex %}
{{ check_reindex.crontab.minute }} {{ check_reindex.crontab.hour }} {{ check_reindex.crontab.day_of_week }}
<button data-schedule="check_reindex" onclick="deleteSchedule(this)" class="danger-button">Delete</button>
{% else %}
False
{% endif %}
</span></p>
<p>Daily schedule to refresh metadata from YouTube:</p>
{{ scheduler_form.check_reindex }}
</div>
<div class="settings-item">
<p>Current refresh for metadata older than x days: <span class="settings-current">{{ check_reindex.task_config.days }}</span></p>
<p>Refresh older than x days, recommended 90:</p>
{% for error in scheduler_form.check_reindex.errors %}
<p class="danger-zone">{{ error }}</p>
{% endfor %}
{{ scheduler_form.check_reindex_days }}
</div>
</div>
<div class="settings-group">
<h2>Thumbnail Check</h2>
<div class="settings-item">
<p>Current thumbnail check schedule: <span class="settings-current">
{% if thumbnail_check %}
{{ thumbnail_check.crontab.minute }} {{ thumbnail_check.crontab.hour }} {{ thumbnail_check.crontab.day_of_week }}
<button data-schedule="thumbnail_check" onclick="deleteSchedule(this)" class="danger-button">Delete</button>
{% else %}
False
{% endif %}
</span></p>
<p>Periodically check and cleanup thumbnails:</p>
{% for error in scheduler_form.thumbnail_check.errors %}
<p class="danger-zone">{{ error }}</p>
{% endfor %}
{{ scheduler_form.thumbnail_check }}
</div>
</div>
<div class="settings-group">
<h2>ZIP file index backup</h2>
<div class="settings-item">
<p><i>Zip file backups are very slow for large archives and consistency is not guaranteed, use snapshots instead. Make sure no other tasks are running when creating a Zip file backup.</i></p>
<p>Current index backup schedule: <span class="settings-current">
{% if run_backup %}
{{ run_backup.crontab.minute }} {{ run_backup.crontab.hour }} {{ run_backup.crontab.day_of_week }}
<button data-schedule="run_backup" onclick="deleteSchedule(this)" class="danger-button">Delete</button>
{% else %}
False
{% endif %}
</span></p>
<p>Automatically backup metadata to a zip file:</p>
{% for error in scheduler_form.run_backup.errors %}
<p class="danger-zone">{{ error }}</p>
{% endfor %}
{{ scheduler_form.run_backup }}
</div>
<div class="settings-item">
<p>Current backup files to keep: <span class="settings-current">{{ run_backup.task_config.rotate }}</span></p>
<p>Max auto backups to keep:</p>
{{ scheduler_form.run_backup_rotate }}
</div>
</div>
<div class="settings-group">
<h2>Add Notification URL</h2>
<div class="settings-item">
{% if notifications %}
<p><button type="button" onclick="textReveal(this)" id="text-reveal-button">Show</button> stored notification links</p>
<div id="text-reveal" class="description-text">
{% for task, notifications in notifications.items %}
<h3>{{ notifications.title }}</h3>
{% for url in notifications.urls %}
<p>
<button type="button" class="danger-button" data-url="{{ url }}" data-task="{{ task }}" onclick="deleteNotificationUrl(this)"> Delete</button>
<span> {{ url }}</span>
</p>
{% endfor %}
{% endfor %}
</div>
{% else %}
<p>No notifications stored</p>
{% endif %}
</div>
<div class="settings-item">
<p><i>Send notification on completed tasks with the help of the <a href="https://github.com/caronc/apprise" target="_blank">Apprise</a> library.</i></p>
{{ notification_form.task }}
{{ notification_form.notification_url }}
</div>
</div>
<button type="submit" name="scheduler-settings">Update Scheduler Settings</button>
</form>
{% endblock settings_content %}

View File

@@ -1,37 +0,0 @@
{% extends "home/base_settings.html" %}
{% load static %}
{% block settings_content %}
<div class="title-bar">
<h1>User Configurations</h1>
</div>
<form action="{% url 'settings_user' %}" method="POST" name="user-update">
{% csrf_token %}
<div class="settings-group">
<h2>Stylesheet</h2>
<div class="settings-item">
<p>Current stylesheet: <span class="settings-current">{{ stylesheet }}</span></p>
<i>Select your preferred stylesheet.</i><br>
{{ user_form.stylesheet }}
</div>
</div>
<div class="settings-group">
<h2>Archive View</h2>
<div class="settings-item">
<p>Current page size: <span class="settings-current">{{ page_size }}</span></p>
<i>Result of videos showing in archive page</i><br>
{{ user_form.page_size }}
</div>
</div>
<button type="submit" name="user-settings">Update User Configurations</button>
</form>
{% if request.user.is_superuser %}
<div class="title-bar">
<h1>Users</h1>
</div>
<div class="settings-group">
<h2>User Management</h2>
<p>Access the admin interface for basic user management functionality like adding and deleting users, changing passwords and more.</p>
<a href="/admin/"><button>Admin Interface</button></a>
</div>
{% endif %}
{% endblock settings_content %}

View File

@@ -1,198 +0,0 @@
{% extends "home/base.html" %}
{% block content %}
{% load static %}
{% load humanize %}
{% load auth_extras %}
<div id="player" class="player-wrapper">
<div class="video-main">
<div class="video-modal"><span class="video-modal-text"></span></div>
</div>
</div>
<div class="notifications" id="notifications"></div>
<div class="sponsorblock" id="sponsorblock">
{% if video.sponsorblock.is_enabled %}
{% if video.sponsorblock.segments|length == 0 %}
<h4>This video doesn't have any sponsor segments added. To add a segment go to <u><a href="https://www.youtube.com/watch?v={{ video.youtube_id }}">this video on YouTube</a></u> and add a segment using the <u><a href="https://sponsor.ajay.app/">SponsorBlock</a></u> extension.</h4>
{% elif video.sponsorblock.has_unlocked %}
<h4>This video has unlocked sponsor segments. Go to <u><a href="https://www.youtube.com/watch?v={{ video.youtube_id }}">this video on YouTube</a></u> and vote on the segments using the <u><a href="https://sponsor.ajay.app/">SponsorBlock</a></u> extension.</h4>
{% endif %}
{% endif %}
</div>
<div class="boxed-content">
<div class="title-bar">
{% if cast %}
<google-cast-launcher id="castbutton"></google-cast-launcher>
{% endif %}
<h1 id="video-title">{{ video.title }}</h1>
</div>
<div class="info-box info-box-3">
<div class="info-box-item">
<div class="round-img">
<a href="{% url 'channel_id' video.channel.channel_id %}">
<img src="{{ video.channel.channel_thumb_url }}" alt="channel-thumb">
</a>
</div>
<div>
<h3><a href="{% url 'channel_id' video.channel.channel_id %}">{{ video.channel.channel_name }}</a></h3>
{% if video.channel.channel_subs >= 1000000 %}
<p>Subscribers: {{ video.channel.channel_subs|intword }}</p>
{% else %}
<p>Subscribers: {{ video.channel.channel_subs|intcomma }}</p>
{% endif %}
</div>
</div>
<div class="info-box-item">
<div>
<p>Published: {{ video.published }}</p>
<p>Last refreshed: {{ video.vid_last_refresh }}</p>
<p class="video-info-watched">Watched:
{% if video.player.watched %}
<img src="{% static 'img/icon-seen.svg' %}" alt="seen-icon" data-id="{{ video.youtube_id }}" data-status="watched" onclick="updateVideoWatchStatus(this)" class="watch-button" title="Mark as unwatched">
{% else %}
<img src="{% static 'img/icon-unseen.svg' %}" alt="unseen-icon" data-id="{{ video.youtube_id }}" data-status="unwatched" onclick="updateVideoWatchStatus(this)" class="watch-button" title="Mark as watched">
{% endif %}
</p>
{% if video.active %}
<p>Youtube: <a href="https://www.youtube.com/watch?v={{ video.youtube_id }}" target="_blank">Active</a></p>
{% else %}
<p>Youtube: Deactivated</p>
{% endif %}
</div>
</div>
<div class="info-box-item">
<div>
<p class="thumb-icon"><img src="{% static 'img/icon-eye.svg' %}" alt="views">: {{ video.stats.view_count|intcomma }}</p>
<p class="thumb-icon like"><img src="{% static 'img/icon-thumb.svg' %}" alt="thumbs-up">: {{ video.stats.like_count|intcomma }}</p>
{% if video.stats.dislike_count %}
<p class="thumb-icon"><img class="dislike" src="{% static 'img/icon-thumb.svg' %}" alt="thumbs-down">: {{ video.stats.dislike_count|intcomma }}</p>
{% endif %}
{% if video.stats.average_rating %}
<div class="rating-stars">
{% for star in video.stats.average_rating %}
<img src="/static/img/icon-star-{{ star }}.svg" alt="{{ star }}">
{% endfor %}
</div>
{% endif %}
</div>
</div>
</div>
<div class="info-box info-box-2">
<div class="info-box-item">
<div class="button-box">
{% if reindex %}
<p>Reindex scheduled</p>
{% else %}
{% if request.user|has_group:"admin" or request.user.is_staff %}
<div id="reindex-button" class="button-box">
<button data-id="{{ video.youtube_id }}" data-type="video" onclick="reindex(this)" title="Reindex {{ video.title }}">Reindex</button>
</div>
{% endif %}
{% endif %}
<a download="" href="{{ video.media_url }}"><button id="download-item">Download File</button></a>
{% if request.user|has_group:"admin" or request.user.is_staff %}
<button onclick="deleteConfirm()" id="delete-item">Delete Video</button>
<div class="delete-confirm" id="delete-button">
<span>Are you sure? </span>
<button class="danger-button" onclick="deleteVideo(this)" data-id="{{ video.youtube_id }}" data-redirect = "{{ video.channel.channel_id }}">Delete</button>
<button class="danger-button" onclick="deleteVideo(this)" data-id="{{ video.youtube_id }}" data-ignore data-redirect = "{{ video.channel.channel_id }}">Delete and ignore</button>
<button onclick="cancelDelete()">Cancel</button>
</div>
{% endif %}
<button id="{{ video.youtube_id }}-button" data-id="{{ video.youtube_id }}" data-context="video" onclick="showAddToPlaylistMenu(this)">Add To Playlist</button>
</div>
</div>
<div class="info-box-item">
{% if video.media_size %}
<p>File size: {{ video.media_size|filesizeformat }}</p>
{% endif %}
{% if video.streams %}
{% for stream in video.streams %}
<p>{{ stream.type|title }}: {{ stream.codec }} {{ stream.bitrate|filesizeformat }}/s{% if stream.width %} <span class="space-carrot">|</span> {{ stream.width }}x{{ stream.height}}{% endif %}</p>
{% endfor %}
{% endif %}
</div>
</div>
{% if video.tags %}
<div class="description-box">
<div class="video-tag-box">
{% for tag in video.tags %}
<span class="video-tag">{{ tag }}</span>
{% endfor %}
</div>
</div>
{% endif %}
{% if video.description %}
<div class="description-box">
<p id="text-expand" class="description-text">
{{ video.description|linebreaksbr|urlizetrunc:50 }}
</p>
<button onclick="textExpand()" id="text-expand-button">Show more</button>
</div>
{% endif %}
{% if playlist_nav %}
{% for playlist_item in playlist_nav %}
<div class="playlist-wrap">
<a href="{% url 'playlist_id' playlist_item.playlist_meta.playlist_id %}">
<h3>Playlist [{{ playlist_item.playlist_meta.current_idx|add:"1" }}]: {{ playlist_item.playlist_meta.playlist_name }}</h3>
</a>
<div class="playlist-nav">
<div class="playlist-nav-item">
{% if playlist_item.playlist_previous %}
<a href="{% url 'video' playlist_item.playlist_previous.youtube_id %}">
<img src="{{ playlist_item.playlist_previous.vid_thumb }}" alt="previous thumbnail">
</a>
<div class="playlist-desc">
<p>Previous:</p>
<a href="{% url 'video' playlist_item.playlist_previous.youtube_id %}">
<h3>[{{ playlist_item.playlist_previous.idx|add:"1" }}] {{ playlist_item.playlist_previous.title }}</h3>
</a>
</div>
{% endif %}
</div>
<div class="playlist-nav-item">
{% if playlist_item.playlist_next %}
<div class="playlist-desc">
<p>Next:</p>
<a href="{% url 'video' playlist_item.playlist_next.youtube_id %}">
<h3>[{{ playlist_item.playlist_next.idx|add:"1" }}] {{ playlist_item.playlist_next.title }}</h3>
</a>
</div>
<a href="{% url 'video' playlist_item.playlist_next.youtube_id %}">
<img src="{{ playlist_item.playlist_next.vid_thumb }}" alt="previous thumbnail">
</a>
{% endif %}
</div>
</div>
</div>
{% endfor %}
{% endif %}
<div class="description-box">
<h3>Similar Videos</h3>
<div class="video-list grid grid-3" id="similar-videos">
</div>
<script>getSimilarVideos('{{ video.youtube_id }}')</script>
</div>
{% if video.comment_count == 0 %}
<div class="comments-section">
<span>Video has no comments</span>
</div>
{% elif video.comment_count %}
<div class="comments-section">
<h3>Comments: {{video.comment_count}}</h3>
<div id="comments-list" class="comments-list">
</div>
<script>getComments('{{ video.youtube_id }}')</script>
</div>
{% endif %}
</div>
<script>
var videoData = getVideoData('{{ video.youtube_id }}');
sponsorBlock = videoData.data.sponsorblock;
{% if position %}
var videoProgress = {{ position }}
{% else %}
var videoProgress = getVideoProgress('{{ video.youtube_id }}').position;
{% endif %}
window.onload = insertVideoTag(videoData, videoProgress);
</script>
{% endblock content %}

View File

@@ -1,8 +0,0 @@
from django import template
register = template.Library()
@register.filter(name="has_group")
def has_group(user, group_name):
return user.groups.filter(name=group_name).exists()

View File

@@ -1,107 +0,0 @@
""" all home app urls """
from django.conf import settings
from django.contrib.auth.decorators import login_required
from django.contrib.auth.views import LogoutView
from django.shortcuts import redirect
from django.urls import path
from home import views
if hasattr(settings, "TA_AUTH_PROXY_LOGOUT_URL"):
logout_path = path(
"logout/",
lambda request: redirect(
settings.TA_AUTH_PROXY_LOGOUT_URL, permanent=False
),
name="logout",
)
else:
logout_path = path(
"logout/",
LogoutView.as_view(),
{"next_page": settings.LOGOUT_REDIRECT_URL},
name="logout",
)
urlpatterns = [
path("", login_required(views.HomeView.as_view()), name="home"),
path("login/", views.LoginView.as_view(), name="login"),
logout_path,
path("about/", views.AboutView.as_view(), name="about"),
path(
"downloads/",
login_required(views.DownloadView.as_view()),
name="downloads",
),
path(
"settings/",
login_required(views.SettingsView.as_view()),
name="settings",
),
path(
"settings/user/",
login_required(views.SettingsUserView.as_view()),
name="settings_user",
),
path(
"settings/application/",
login_required(views.SettingsApplicationView.as_view()),
name="settings_application",
),
path(
"settings/scheduling/",
login_required(views.SettingsSchedulingView.as_view()),
name="settings_scheduling",
),
path(
"settings/actions/",
login_required(views.SettingsActionsView.as_view()),
name="settings_actions",
),
path(
"channel/",
login_required(views.ChannelView.as_view()),
name="channel",
),
path(
"channel/<slug:channel_id>/",
login_required(views.ChannelIdView.as_view()),
name="channel_id",
),
path(
"channel/<slug:channel_id>/streams/",
login_required(views.ChannelIdLiveView.as_view()),
name="channel_id_live",
),
path(
"channel/<slug:channel_id>/shorts/",
login_required(views.ChannelIdShortsView.as_view()),
name="channel_id_shorts",
),
path(
"channel/<slug:channel_id>/about/",
login_required(views.ChannelIdAboutView.as_view()),
name="channel_id_about",
),
path(
"channel/<slug:channel_id>/playlist/",
login_required(views.ChannelIdPlaylistView.as_view()),
name="channel_id_playlist",
),
path(
"video/<slug:video_id>/",
login_required(views.VideoView.as_view()),
name="video",
),
path(
"playlist/",
login_required(views.PlaylistView.as_view()),
name="playlist",
),
path(
"playlist/<slug:playlist_id>/",
login_required(views.PlaylistIdView.as_view()),
name="playlist_id",
),
path("search/", login_required(views.SearchView.as_view()), name="search"),
]

File diff suppressed because it is too large Load Diff

View File

@@ -1,3 +0,0 @@
{
"esversion": 6
}

View File

@@ -1,157 +0,0 @@
'use strict';
/* global cast chrome getVideoPlayerVideoId postVideoProgress setProgressBar getVideoPlayer getVideoPlayerWatchStatus watchedThreshold isWatched getVideoData getURL getVideoPlayerCurrentTime */
function initializeCastApi() {
cast.framework.CastContext.getInstance().setOptions({
receiverApplicationId: chrome.cast.media.DEFAULT_MEDIA_RECEIVER_APP_ID, // Use built in receiver app on cast device, see https://developers.google.com/cast/docs/styled_receiver if you want to be able to add a theme, splash screen or watermark. Has a $5 one time fee.
autoJoinPolicy: chrome.cast.AutoJoinPolicy.ORIGIN_SCOPED,
});
let player = new cast.framework.RemotePlayer();
let playerController = new cast.framework.RemotePlayerController(player);
// Add event listerner to check if a connection to a cast device is initiated
playerController.addEventListener(
cast.framework.RemotePlayerEventType.IS_CONNECTED_CHANGED,
function () {
castConnectionChange(player);
}
);
playerController.addEventListener(
cast.framework.RemotePlayerEventType.CURRENT_TIME_CHANGED,
function () {
castVideoProgress(player);
}
);
playerController.addEventListener(
cast.framework.RemotePlayerEventType.IS_PAUSED_CHANGED,
function () {
castVideoPaused(player);
}
);
}
function castConnectionChange(player) {
// If cast connection is initialized start cast
if (player.isConnected) {
// console.log("Cast Connected.");
castStart();
} else if (!player.isConnected) {
// console.log("Cast Disconnected.");
}
}
function castVideoProgress(player) {
let videoId = getVideoPlayerVideoId();
if (player.mediaInfo.contentId.includes(videoId)) {
let currentTime = player.currentTime;
let duration = player.duration;
if (currentTime % 10 <= 1.0 && currentTime !== 0 && duration !== 0) {
// Check progress every 10 seconds or else progress is checked a few times a second
postVideoProgress(videoId, currentTime);
setProgressBar(videoId, currentTime, duration);
if (!getVideoPlayerWatchStatus()) {
// Check if video is already marked as watched
if (watchedThreshold(currentTime, duration)) {
isWatched(videoId);
}
}
}
}
}
function castVideoPaused(player) {
let videoId = getVideoPlayerVideoId();
let currentTime = player.currentTime;
let duration = player.duration;
if (player.mediaInfo != null) {
if (player.mediaInfo.contentId.includes(videoId)) {
if (currentTime !== 0 && duration !== 0) {
postVideoProgress(videoId, currentTime);
}
}
}
}
function castStart() {
let castSession = cast.framework.CastContext.getInstance().getCurrentSession();
// Check if there is already media playing on the cast target to prevent recasting on page reload or switching to another video page
if (!castSession.getMediaSession()) {
let videoId = getVideoPlayerVideoId();
let videoData = getVideoData(videoId);
let contentId = getURL() + videoData.data.media_url;
let contentTitle = videoData.data.title;
let contentImage = getURL() + videoData.data.vid_thumb_url;
let contentType = 'video/mp4'; // Set content type, only videos right now so it is hard coded
let contentCurrentTime = getVideoPlayerCurrentTime(); // Get video's current position
let contentActiveSubtitle = [];
// Check if a subtitle is turned on.
for (let i = 0; i < getVideoPlayer().textTracks.length; i++) {
if (getVideoPlayer().textTracks[i].mode === 'showing') {
contentActiveSubtitle = [i + 1];
}
}
let contentSubtitles = [];
let videoSubtitles = videoData.data.subtitles; // Array of subtitles
if (typeof videoSubtitles !== 'undefined' && videoData.config.downloads.subtitle) {
for (let i = 0; i < videoSubtitles.length; i++) {
let subtitle = new chrome.cast.media.Track(i, chrome.cast.media.TrackType.TEXT);
subtitle.trackContentId = videoSubtitles[i].media_url;
subtitle.trackContentType = 'text/vtt';
subtitle.subtype = chrome.cast.media.TextTrackType.SUBTITLES;
subtitle.name = videoSubtitles[i].name;
subtitle.language = videoSubtitles[i].lang;
subtitle.customData = null;
contentSubtitles.push(subtitle);
}
}
let mediaInfo = new chrome.cast.media.MediaInfo(contentId, contentType); // Create MediaInfo var that contains url and content type
// mediaInfo.streamType = chrome.cast.media.StreamType.BUFFERED; // Set type of stream, BUFFERED, LIVE, OTHER
mediaInfo.metadata = new chrome.cast.media.GenericMediaMetadata(); // Create metadata var and add it to MediaInfo
mediaInfo.metadata.title = contentTitle.replace('&amp;', '&'); // Set the video title
mediaInfo.metadata.images = [new chrome.cast.Image(contentImage)]; // Set the video thumbnail
// mediaInfo.textTrackStyle = new chrome.cast.media.TextTrackStyle();
mediaInfo.tracks = contentSubtitles;
let request = new chrome.cast.media.LoadRequest(mediaInfo); // Create request with the previously set MediaInfo.
// request.queueData = new chrome.cast.media.QueueData(); // See https://developers.google.com/cast/docs/reference/web_sender/chrome.cast.media.QueueData for playlist support.
request.currentTime = shiftCurrentTime(contentCurrentTime); // Set video start position based on the browser video position
request.activeTrackIds = contentActiveSubtitle; // Set active subtitle based on video player
// request.autoplay = false; // Set content to auto play, true by default
castSession.loadMedia(request).then(
function () {
castSuccessful();
},
function (error) {
castFailed(error.code);
}
); // Send request to cast device
}
}
function shiftCurrentTime(contentCurrentTime) {
// Shift media back 3 seconds to prevent missing some of the content
if (contentCurrentTime > 5) {
return contentCurrentTime - 3;
} else {
return 0;
}
}
function castSuccessful() {
// console.log('Cast Successful.');
getVideoPlayer().pause(); // Pause browser video on successful cast
}
function castFailed(errorCode) {
console.log('Error code: ' + errorCode);
}
window['__onGCastApiAvailable'] = function (isAvailable) {
if (isAvailable) {
initializeCastApi();
}
};

View File

@@ -1,14 +0,0 @@
:root {
--main-bg: #00202f;
--highlight-bg: #00293b;
--highlight-error: #990202;
--highlight-error-light: #c44343;
--highlight-bg-transparent: #00293baf;
--main-font: #eeeeee;
--accent-font-dark: #259485;
--accent-font-light: #97d4c8;
--img-filter: invert(50%) sepia(9%) saturate(2940%) hue-rotate(122deg) brightness(94%) contrast(90%);
--img-filter-error: invert(16%) sepia(60%) saturate(3717%) hue-rotate(349deg) brightness(86%) contrast(120%);
--banner: url("../img/banner-tube-archivist-dark.png");
--logo: url("../img/logo-tube-archivist-dark.png");
}

View File

@@ -1,14 +0,0 @@
:root {
--main-bg: #eeeeee;
--highlight-bg: #d9e0d9;
--highlight-error: #990202;
--highlight-error-light: #c44343;
--highlight-bg-transparent: #00293baf;
--main-font: #00202f;
--accent-font-dark: #259485;
--accent-font-light: #35b399;
--img-filter: invert(50%) sepia(9%) saturate(2940%) hue-rotate(122deg) brightness(94%) contrast(90%);
--img-filter-error: invert(16%) sepia(60%) saturate(3717%) hue-rotate(349deg) brightness(86%) contrast(120%);
--banner: url("../img/banner-tube-archivist-light.png");
--logo: url("../img/logo-tube-archivist-light.png");
}

View File

@@ -1,67 +0,0 @@
:root {
--main-bg: #000000;
--highlight-bg: #080808;
--highlight-error: #880000;
--highlight-error-light: #aa0000;
--highlight-bg-transparent: #0c0c0caf;
--main-font: #00aa00;
--accent-font-dark: #007700;
--accent-font-light: #00aa00;
--img-filter: brightness(0) saturate(100%) invert(45%) sepia(100%) saturate(3710%) hue-rotate(96deg) brightness(100%) contrast(102%);
--img-filter-error: invert(16%) sepia(60%) saturate(3717%) hue-rotate(349deg) brightness(86%) contrast(120%);
--banner: url("../img/banner-tube-archivist-dark.png");
--logo: url("../img/logo-tube-archivist-dark.png");
--outline: 1px solid green;
--filter: hue-rotate(310deg);
}
.settings-group {
outline: var(--outline);
}
.info-box-item {
outline: var(--outline);
}
.footer {
outline: var(--outline);
}
.top-banner img {
filter: var(--filter);
}
.icon-text {
outline: var(--outline);
}
.video-item {
outline: var(--outline);
}
.channel-banner {
outline: var(--outline);
}
.description-box {
outline: var(--outline);
}
.video-player {
outline: var(--outline);
}
#notification {
outline: var(--outline);
}
textarea {
background-color: var(--highlight-bg);
outline: var(--outline);
color: var(--main-font);
}
input {
background-color: var(--highlight-bg);
color: var(--main-font);
}

View File

@@ -1,14 +0,0 @@
:root {
--main-bg: #000000;
--highlight-bg: #0c0c0c;
--highlight-error: #220000;
--highlight-error-light: #330000;
--highlight-bg-transparent: #0c0c0caf;
--main-font: #888888;
--accent-font-dark: #555555;
--accent-font-light: #999999;
--img-filter: invert(50%) sepia(9%) saturate(2940%) hue-rotate(122deg) brightness(94%) contrast(90%);
--img-filter-error: invert(16%) sepia(60%) saturate(3717%) hue-rotate(349deg) brightness(86%) contrast(120%);
--banner: url("../img/banner-tube-archivist-dark.png");
--logo: url("../img/logo-tube-archivist-dark.png");
}

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 920 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 747 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1012 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 830 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 891 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 959 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

View File

@@ -1,9 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<browserconfig>
<msapplication>
<tile>
<square150x150logo src="/static/favicon/mstile-150x150.png"/>
<TileColor>#01202e</TileColor>
</tile>
</msapplication>
</browserconfig>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

View File

@@ -1,100 +0,0 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
width="1000.000000pt" height="1000.000000pt" viewBox="0 0 1000.000000 1000.000000"
preserveAspectRatio="xMidYMid meet">
<metadata>
Created by potrace 1.14, written by Peter Selinger 2001-2017
</metadata>
<g transform="translate(0.000000,1000.000000) scale(0.100000,-0.100000)"
fill="#000000" stroke="none">
<path d="M4521 9370 c-4 -3 -7 -31 -6 -63 1 -32 -3 -61 -9 -66 -6 -5 -36 -12
-66 -16 -55 -7 -68 -9 -125 -19 -16 -3 -48 -8 -70 -12 -161 -24 -504 -118
-709 -193 -208 -77 -507 -215 -636 -294 -19 -12 -47 -29 -62 -37 -14 -8 -41
-24 -60 -34 -84 -48 -288 -189 -423 -293 -309 -239 -654 -606 -886 -943 -53
-78 -169 -258 -169 -264 0 -3 -21 -40 -47 -83 -97 -164 -313 -646 -294 -658
14 -8 670 -195 686 -195 8 0 15 9 15 19 0 11 5 23 10 26 6 3 10 13 10 21 0 8
14 44 30 79 17 35 30 67 30 70 0 3 21 48 47 100 l47 95 148 0 c81 0 276 1 433
1 157 0 310 -1 340 -1 l55 0 0 -615 0 -615 415 1 415 0 1 142 c0 78 0 355 1
615 l1 472 46 0 c25 0 322 0 659 0 l612 1 0 32 c1 44 -1 538 -2 660 0 63 -5
97 -12 98 -6 1 -581 1 -1278 0 -698 0 -1268 2 -1268 5 0 7 143 147 241 235 94
85 232 193 329 260 36 24 67 47 68 52 2 4 7 7 12 7 4 0 52 28 106 62 126 79
371 202 510 257 60 23 118 46 129 51 131 56 685 193 713 176 4 -2 7 -34 6 -70
l0 -66 162 0 162 0 0 503 0 502 -155 0 c-85 0 -158 -2 -162 -5z"/>
<path d="M5210 8905 l0 -365 48 -1 c26 0 54 -2 62 -4 8 -1 45 -5 82 -9 72 -6
198 -23 232 -31 12 -3 32 -7 46 -9 284 -48 643 -169 935 -314 527 -262 984
-651 1324 -1127 39 -55 75 -105 81 -112 5 -7 10 -17 10 -23 0 -5 4 -10 9 -10
5 0 14 -12 20 -27 6 -16 24 -48 40 -73 31 -47 61 -101 117 -208 30 -57 32 -65
16 -69 -75 -20 -117 -40 -113 -53 9 -35 83 -285 85 -287 1 -2 18 2 37 8 19 5
41 12 49 14 49 12 856 241 876 249 11 4 10 14 -2 57 -9 29 -17 60 -19 68 -7
32 -53 183 -57 186 -2 2 -22 -2 -43 -9 -93 -31 -88 -33 -126 46 -232 488 -557
933 -950 1303 -285 269 -647 520 -1014 705 -533 268 -1067 412 -1682 455 l-63
4 0 -364z"/>
<path d="M6122 7336 c-4 -6 -14 -31 -23 -56 -17 -47 -238 -630 -288 -760 -16
-41 -61 -160 -100 -265 -40 -104 -76 -199 -80 -210 -10 -23 -54 -138 -104
-275 -20 -52 -41 -108 -48 -125 -7 -16 -13 -32 -13 -35 -1 -3 -7 -18 -13 -35
-6 -16 -55 -145 -108 -285 -53 -140 -102 -271 -110 -290 -8 -19 -48 -125 -89
-235 -41 -110 -90 -240 -109 -290 -19 -49 -76 -200 -127 -335 -133 -356 -151
-402 -166 -437 -8 -17 -14 -34 -14 -37 0 -3 -15 -45 -34 -94 -19 -48 -61 -160
-95 -248 -33 -89 -65 -174 -72 -190 -22 -55 -28 -70 -98 -258 -39 -103 -71
-192 -71 -197 0 -5 182 -8 441 -7 l441 3 114 320 c63 176 126 352 140 390 14
39 46 129 70 200 25 72 50 139 55 150 5 11 22 58 38 105 29 84 89 254 171 480
23 63 47 133 54 155 12 36 70 199 131 365 13 36 60 169 105 295 44 127 85 239
90 250 4 11 62 173 129 360 197 557 186 530 195 504 3 -8 18 -52 35 -99 16
-47 54 -155 84 -240 30 -85 96 -272 146 -415 51 -143 96 -269 100 -280 5 -11
27 -72 49 -135 120 -343 143 -407 152 -422 6 -10 10 -24 10 -33 0 -8 6 -29 14
-47 8 -18 44 -116 80 -218 182 -521 327 -927 336 -942 6 -10 10 -23 10 -29 0
-9 134 -393 176 -502 8 -21 28 -78 45 -128 l31 -90 -49 -56 c-26 -31 -78 -88
-115 -127 -64 -68 -68 -70 -81 -51 -8 11 -28 37 -44 57 l-30 37 -124 -91 c-68
-50 -123 -96 -123 -104 1 -9 281 -404 327 -459 4 -5 62 -84 128 -175 65 -91
124 -166 129 -168 8 -3 73 39 90 58 3 3 42 32 88 64 l82 58 -40 56 -39 56 94
96 c558 566 945 1258 1130 2025 18 77 38 167 44 200 6 33 13 69 15 80 6 33 19
119 21 140 2 11 6 43 9 70 35 253 40 715 11 930 -2 17 -9 75 -15 129 -7 55
-16 109 -20 122 -5 12 -7 24 -5 26 11 11 -85 428 -98 428 -11 0 -680 -190
-685 -195 -2 -1 8 -47 21 -101 14 -55 28 -115 31 -134 3 -19 8 -46 11 -60 10
-53 19 -109 29 -195 4 -33 9 -70 11 -82 8 -53 18 -259 18 -369 -1 -400 -74
-812 -213 -1194 -23 -63 -44 -123 -47 -132 -9 -29 -20 -21 -35 25 -22 62 -198
529 -208 552 -5 11 -69 178 -141 370 -72 193 -187 499 -256 680 -68 182 -164
436 -213 565 -48 129 -93 246 -98 260 -6 14 -27 70 -47 125 -19 55 -40 109
-45 120 -8 18 -191 503 -224 595 -15 42 -95 253 -139 366 l-31 80 -398 0
c-270 0 -401 -3 -406 -10z"/>
<path d="M720 6002 c-47 -160 -68 -237 -64 -243 2 -4 28 -13 56 -19 29 -7 56
-14 59 -16 4 -2 3 -23 -1 -46 -5 -24 -11 -61 -14 -83 -4 -23 -8 -50 -10 -60
-2 -11 -7 -47 -10 -80 -4 -33 -9 -73 -11 -90 -31 -231 -26 -701 11 -955 3 -25
8 -61 10 -80 2 -19 5 -44 8 -55 3 -11 8 -42 12 -70 3 -27 8 -53 10 -56 2 -4 6
-24 10 -45 20 -134 154 -594 209 -719 7 -16 27 -66 45 -110 59 -147 189 -400
297 -579 89 -147 270 -400 359 -502 11 -12 39 -46 64 -75 74 -89 358 -369 465
-459 55 -46 110 -92 121 -102 22 -19 22 -19 107 99 48 65 90 123 94 128 35 42
243 336 242 342 0 5 -38 40 -85 78 -313 258 -611 618 -818 988 -63 114 -176
341 -176 355 0 5 -9 26 -19 48 -54 113 -171 502 -200 669 -6 33 -13 69 -15 80
-8 43 -21 134 -31 210 -19 156 -24 420 -12 605 8 119 13 166 33 295 5 28 7 53
6 58 -2 8 24 3 99 -18 l45 -13 23 82 c12 44 29 106 38 136 30 104 34 95 -54
118 -43 11 -109 29 -148 40 -38 11 -104 30 -145 41 -41 12 -79 23 -85 25 -5 1
-28 8 -50 14 -22 7 -112 33 -200 58 -88 25 -181 52 -207 59 l-48 14 -20 -67z"/>
<path d="M2693 5210 c-48 -11 -119 -56 -148 -95 -112 -146 -57 -352 115 -428
43 -19 68 -20 560 -21 449 -1 521 1 563 15 65 22 114 64 151 129 27 48 31 64
31 130 0 116 -49 200 -149 253 -41 22 -44 22 -566 23 -289 1 -539 -2 -557 -6z"/>
<path d="M6425 5138 c-50 -19 -102 -55 -128 -90 -56 -73 -55 -54 -55 -901 -1
-430 -1 -793 -2 -807 0 -21 -26 1 -169 148 -93 94 -173 172 -178 172 -4 0 -58
-50 -118 -110 l-110 -110 25 -24 c14 -12 202 -204 419 -424 217 -221 397 -402
401 -402 3 0 199 192 435 426 l429 425 -114 114 -115 114 -177 -178 -178 -178
-1 381 c-2 1238 -2 1258 -24 1301 -26 52 -71 98 -126 126 -51 26 -166 35 -214
17z"/>
<path d="M2814 4501 c-2 -2 -4 -415 -4 -918 l0 -913 415 0 415 0 0 28 c4 223
0 1795 -4 1799 -6 7 -816 10 -822 4z"/>
<path d="M3181 2038 c-8 -13 -44 -63 -81 -113 -36 -49 -101 -137 -143 -195
-42 -58 -80 -109 -84 -115 -16 -20 -88 -119 -103 -141 -8 -13 -48 -68 -89
-124 -40 -55 -72 -103 -70 -105 2 -2 60 -44 129 -94 l125 -91 25 32 c62 79 35
81 231 -15 382 -187 717 -298 1149 -382 8 -1 36 -5 61 -9 25 -4 57 -9 70 -11
45 -7 183 -24 264 -32 105 -10 629 -10 725 0 116 13 131 14 195 22 58 7 70 9
125 19 14 3 42 8 63 11 48 7 174 32 252 51 33 8 67 16 76 19 145 33 419 126
599 202 122 52 413 195 418 206 2 4 8 7 12 7 11 0 193 108 273 162 53 36 57
41 45 59 -107 155 -406 558 -415 558 -7 1 -44 -19 -82 -44 -236 -153 -537
-295 -814 -386 -97 -31 -291 -85 -342 -94 -16 -2 -41 -7 -55 -10 -39 -9 -240
-43 -288 -49 -212 -28 -609 -29 -822 -2 -14 2 -52 7 -85 11 -33 4 -69 9 -80
12 -11 2 -33 6 -50 9 -211 34 -520 123 -735 211 -86 36 -291 130 -299 138 -2
3 15 30 38 60 24 31 41 58 39 60 -11 11 -243 178 -252 181 -6 2 -17 -6 -25
-18z"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 6.6 KiB

View File

@@ -1,19 +0,0 @@
{
"name": "TubeArchivist",
"short_name": "TubeArchivist",
"icons": [
{
"src": "/static/favicon/android-chrome-192x192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "/static/favicon/android-chrome-512x512.png",
"sizes": "512x512",
"type": "image/png"
}
],
"theme_color": "#01202e",
"background_color": "#01202e",
"display": "standalone"
}

View File

@@ -1,94 +0,0 @@
Copyright (c) 2015, Kosal Sen, Philatype (<http://philatype.com>),
with Reserved Font Name Sen.
This Font Software is licensed under the SIL Open Font License, Version 1.1.
This license is copied below, and is also available with a FAQ at:
http://scripts.sil.org/OFL
-----------------------------------------------------------
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
-----------------------------------------------------------
PREAMBLE
The goals of the Open Font License (OFL) are to stimulate worldwide
development of collaborative font projects, to support the font creation
efforts of academic and linguistic communities, and to provide a free and
open framework in which fonts may be shared and improved in partnership
with others.
The OFL allows the licensed fonts to be used, studied, modified and
redistributed freely as long as they are not sold by themselves. The
fonts, including any derivative works, can be bundled, embedded,
redistributed and/or sold with any software provided that any reserved
names are not used by derivative works. The fonts and derivatives,
however, cannot be released under any other type of license. The
requirement for fonts to remain under this license does not apply
to any document created using the fonts or their derivatives.
DEFINITIONS
"Font Software" refers to the set of files released by the Copyright
Holder(s) under this license and clearly marked as such. This may
include source files, build scripts and documentation.
"Reserved Font Name" refers to any names specified as such after the
copyright statement(s).
"Original Version" refers to the collection of Font Software components as
distributed by the Copyright Holder(s).
"Modified Version" refers to any derivative made by adding to, deleting,
or substituting -- in part or in whole -- any of the components of the
Original Version, by changing formats or by porting the Font Software to a
new environment.
"Author" refers to any designer, engineer, programmer, technical
writer or other person who contributed to the Font Software.
PERMISSION & CONDITIONS
Permission is hereby granted, free of charge, to any person obtaining
a copy of the Font Software, to use, study, copy, merge, embed, modify,
redistribute, and sell modified and unmodified copies of the Font
Software, subject to the following conditions:
1) Neither the Font Software nor any of its individual components,
in Original or Modified Versions, may be sold by itself.
2) Original or Modified Versions of the Font Software may be bundled,
redistributed and/or sold with any software, provided that each copy
contains the above copyright notice and this license. These can be
included either as stand-alone text files, human-readable headers or
in the appropriate machine-readable metadata fields within text or
binary files as long as those fields can be easily viewed by the user.
3) No Modified Version of the Font Software may use the Reserved Font
Name(s) unless explicit written permission is granted by the corresponding
Copyright Holder. This restriction only applies to the primary font name as
presented to the users.
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
Software shall not be used to promote, endorse or advertise any
Modified Version, except to acknowledge the contribution(s) of the
Copyright Holder(s) and the Author(s) or with their explicit written
permission.
5) The Font Software, modified or unmodified, in part or in whole,
must be distributed entirely under this license, and must not be
distributed under any other license. The requirement for fonts to
remain under this license does not apply to any document created
using the Font Software.
TERMINATION
This license becomes null and void if any of the above conditions are
not met.
DISCLAIMER
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
OTHER DEALINGS IN THE FONT SOFTWARE.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 109 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 56 KiB

View File

@@ -1,13 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 27.5.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1"
id="svg1303" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:svg="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 500 500"
style="enable-background:new 0 0 500 500;" xml:space="preserve">
<sodipodi:namedview bordercolor="#666666" borderopacity="1.0" id="base" inkscape:current-layer="layer1" inkscape:cx="-97.380081" inkscape:cy="261.09215" inkscape:document-units="mm" inkscape:guide-bbox="true" inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:window-height="1017" inkscape:window-maximized="1" inkscape:window-width="1920" inkscape:window-x="-8" inkscape:window-y="-8" inkscape:zoom="0.85859018" pagecolor="#ffffff" showgrid="false" showguides="true" units="px">
<sodipodi:guide id="guide1072" inkscape:locked="false" orientation="1,0" position="-221.87586,143.2945"></sodipodi:guide>
</sodipodi:namedview>
<path d="M431.9,194.4H305.6V68.1c0-30.6-25-55.6-55.6-55.6h0c-30.6,0-55.6,25-55.6,55.6v126.3H68.1c-30.6,0-55.6,25-55.6,55.6v0
c0,30.6,25,55.6,55.6,55.6h126.3v126.3c0,30.6,25,55.6,55.6,55.6h0c30.6,0,55.6-25,55.6-55.6V305.6h126.3c30.6,0,55.6-25,55.6-55.6
v0C487.5,219.4,462.5,194.4,431.9,194.4z"/>
</svg>

Before

Width:  |  Height:  |  Size: 1.6 KiB

View File

@@ -1,14 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 27.5.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1"
id="svg1303" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:svg="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 500 500"
style="enable-background:new 0 0 500 500;" xml:space="preserve">
<g>
<path d="M231.3,382c4.8,5.3,11.6,8.3,18.7,8.3c7.1,0,13.9-3,18.7-8.3l112.1-124.2c6.7-7.4,8.4-18,4.3-27.1
c-4-9.1-13.1-14.9-23-14.9h-52.9V64.9c0-13.9-11.3-25.2-25.2-25.2h-68c-13.9,0-25.2,11.3-25.2,25.2v150.9h-52.9
c-10,0-19,5.9-23,14.9c-4,9.1-2.3,19.7,4.3,27.1L231.3,382z"/>
<path d="M436.1,408.8H63.9c-13.6,0-24.7,11.1-24.7,24.7c0,13.6,11.1,24.7,24.7,24.7h372.2c13.6,0,24.7-11.1,24.7-24.7
C460.8,419.9,449.7,408.8,436.1,408.8z"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<svg viewBox="0 0 500 500" style="enable-background:new 0 0 500 500;" xmlns="http://www.w3.org/2000/svg">
<g style="" transform="matrix(0.9999999999999999, 0, 0, -0.9999999999999999, 0, 497.9000392526395)">
<path d="M 231.3 48 C 236.1 42.7 242.9 39.7 250 39.7 C 257.1 39.7 263.9 42.7 268.7 48 L 380.8 172.2 C 387.5 179.6 389.2 190.2 385.1 199.3 C 381.1 208.4 372 214.2 362.1 214.2 L 309.2 214.2 L 309.2 365.1 C 309.2 379 297.9 390.3 284 390.3 L 216 390.3 C 202.1 390.3 190.8 379 190.8 365.1 L 190.8 214.2 L 137.9 214.2 C 127.9 214.2 118.9 208.3 114.9 199.3 C 110.9 190.2 112.6 179.6 119.2 172.2 L 231.3 48 Z" style=""/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 678 B

View File

@@ -1,7 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<svg viewBox="0 0 500 500" style="enable-background:new 0 0 500 500;" xmlns="http://www.w3.org/2000/svg">
<g style="" transform="matrix(0.9999999999999999, 0, 0, -0.9999999999999999, 0, 497.9000392526395)">
<path d="M231.3,382c4.8,5.3,11.6,8.3,18.7,8.3c7.1,0,13.9-3,18.7-8.3l112.1-124.2c6.7-7.4,8.4-18,4.3-27.1 c-4-9.1-13.1-14.9-23-14.9h-52.9V64.9c0-13.9-11.3-25.2-25.2-25.2h-68c-13.9,0-25.2,11.3-25.2,25.2v150.9h-52.9 c-10,0-19,5.9-23,14.9c-4,9.1-2.3,19.7,4.3,27.1L231.3,382z"/>
<path d="M436.1,408.8H63.9c-13.6,0-24.7,11.1-24.7,24.7c0,13.6,11.1,24.7,24.7,24.7h372.2c13.6,0,24.7-11.1,24.7-24.7 C460.8,419.9,449.7,408.8,436.1,408.8z"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 698 B

View File

@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<svg viewBox="0 0 500 500" style="enable-background:new 0 0 500 500;" xmlns="http://www.w3.org/2000/svg">
<g style="" transform="matrix(0.9999999999999999, 0, 0, -0.9999999999999999, 0, 497.9000392526395)">
<path d="M231.3,382c4.8,5.3,11.6,8.3,18.7,8.3c7.1,0,13.9-3,18.7-8.3l112.1-124.2c6.7-7.4,8.4-18,4.3-27.1 c-4-9.1-13.1-14.9-23-14.9h-52.9V64.9c0-13.9-11.3-25.2-25.2-25.2h-68c-13.9,0-25.2,11.3-25.2,25.2v150.9h-52.9 c-10,0-19,5.9-23,14.9c-4,9.1-2.3,19.7,4.3,27.1L231.3,382z"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 538 B

View File

@@ -1,10 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 27.5.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1"
id="svg1303" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:svg="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 500 500"
style="enable-background:new 0 0 500 500;" xml:space="preserve">
<path d="M473.5,392.9L329.1,250.5l144.3-145.6c21.6-21.6,21.6-57,0-78.6l0,0c-21.6-21.6-57-21.6-78.6,0L250.5,171.9L106.3,26.2
c-21.6-21.6-57-21.6-78.6,0l0,0C6,47.9,6,83.2,27.6,104.9l144.2,145.6L26.4,393.9c-21.6,21.6-21.6,57,0,78.6l0,0
c21.6,21.6,57,21.6,78.6,0l145.4-143.4l144.3,142.4c21.6,21.6,57,21.6,78.6,0l0,0C495.1,449.9,495.1,414.6,473.5,392.9z"/>
</svg>

Before

Width:  |  Height:  |  Size: 1.0 KiB

View File

@@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg width="800px" height="800px" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" fill="#000000" class="bi bi-three-dots-vertical">
<path d="M9.5 13a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0zm0-5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0zm0-5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0z"/>
</svg>

Before

Width:  |  Height:  |  Size: 405 B

View File

@@ -1,14 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 27.5.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1"
id="svg1303" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:svg="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 500 500"
style="enable-background:new 0 0 500 500;" xml:space="preserve">
<g>
<path d="M231.3,382c4.8,5.3,11.6,8.3,18.7,8.3c7.1,0,13.9-3,18.7-8.3l112.1-124.2c6.7-7.4,8.4-18,4.3-27.1
c-4-9.1-13.1-14.9-23-14.9h-52.9V64.9c0-13.9-11.3-25.2-25.2-25.2h-68c-13.9,0-25.2,11.3-25.2,25.2v150.9h-52.9
c-10,0-19,5.9-23,14.9c-4,9.1-2.3,19.7,4.3,27.1L231.3,382z"/>
<path d="M436.1,408.8H63.9c-13.6,0-24.7,11.1-24.7,24.7c0,13.6,11.1,24.7,24.7,24.7h372.2c13.6,0,24.7-11.1,24.7-24.7
C460.8,419.9,449.7,408.8,436.1,408.8z"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -1,19 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 27.5.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1"
id="svg1566" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:svg="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 595.3 595.3"
style="enable-background:new 0 0 595.3 595.3;" xml:space="preserve">
<g>
<path d="M99,295.1c0,105.5,75.4,194.1,177.1,209.1c68.9,10.1,128.8-9.3,179.1-57.3c14.4-13.7,30.2-19,49-11.3
c27.8,11.3,35.3,47.2,14.3,68.5c-43.9,44.6-96.7,72.7-158.4,83.6c-65,11.4-127.4,2.9-185.7-27.8c-85.2-44.9-138.5-115-155.9-210.1
C2.5,261.9,23,182,78.9,112.4C129,50.1,194.6,13.3,274.5,4.6c94.2-10.3,175.3,18.6,243,84.9c13.3,13,16.6,31.3,9.4,47.7
c-7.1,16-23.4,26.2-40.9,25.4c-11.6-0.6-21.3-5.5-29.6-13.7c-28.7-28.3-62.6-47.1-102-56.1c-117-26.9-234.8,53.1-252.9,171.9
C99.9,275.4,98.7,286.2,99,295.1z"/>
<path d="M434.1,339.9c-2.6,0-5.2,0-7.8,0c-69,0-138.1,0-207.1,0c-19.1,0-34.3-10.6-40.8-28.2c-6-16.2-1.2-34.6,12.4-46.4
c8-7,17.5-10.2,28.3-10.2c69,0.1,138.1,0,207.1,0c2.6,0,5.2,0,8.7,0c-2.2-4.7-5.9-7-8.7-10.1c-11.1-12.6-15.3-26.9-9.9-43.1
c5.3-15.8,16.6-25.5,32.9-28.6c14.2-2.7,27.1,1.3,37.3,11.4c28,27.6,55.9,55.3,83.4,83.5c16.1,16.5,16.1,42.2,0.1,58.7
c-27.6,28.3-55.6,56.3-83.9,83.8c-12.7,12.3-28.4,15.4-44.9,8.8c-16.7-6.7-25.9-19.8-27.1-37.7c-0.8-12,3.7-22.7,12.1-31.5
c2.8-3,6.1-5.5,9.2-8.3C435,341.3,434.5,340.6,434.1,339.9z"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.7 KiB

View File

@@ -1,15 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 27.5.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1"
id="svg1303" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:svg="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 500 500"
style="enable-background:new 0 0 500 500;" xml:space="preserve">
<g>
<path d="M249.8,406.5C142.2,401.9,59.2,355.3,3.6,261.9c-4.7-8-4.8-16.2-0.1-24.2c46.6-79.1,115-127.3,205.9-141.1
c113.5-17.1,224.7,36.5,283.5,134.6c1,1.7,1.9,3.5,3,5.2c5.6,8.8,5.4,17.5,0.1,26.5c-29,50.1-69.2,88.2-121,113.9
c-33.4,16.6-68.7,26.2-106,28.5C262.7,405.7,256.4,406.2,249.8,406.5z M139.6,249.7c0,61.4,49.1,110.5,110.6,110.5
c61.2,0,110.3-49.1,110.4-110.2c0.1-61.5-48.9-110.7-110.4-110.7C188.7,139.2,139.6,188.3,139.6,249.7z"/>
<path d="M174.9,249.8c0-42.1,33.2-75.3,75.4-75.2c41.7,0,75,33.3,75,75.2c0,42.1-33.3,75.3-75.5,75.3
C208.1,324.9,174.9,291.6,174.9,249.8z"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.3 KiB

View File

@@ -1,63 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="500"
height="500"
viewBox="0 0 132.29197 132.29167"
version="1.1"
id="svg1303"
inkscape:version="0.92.4 (5da689c313, 2019-01-14)"
sodipodi:docname="Icons_Settings02.svg">
<defs
id="defs1297" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="1.0105705"
inkscape:cx="-25.63665"
inkscape:cy="191.7261"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
showgrid="false"
units="px"
inkscape:window-width="1920"
inkscape:window-height="1017"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1" />
<metadata
id="metadata1300">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Ebene 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(0,-164.70764)">
<path
style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:markers fill stroke"
d="m 57.383938,165.28042 c -4.849506,0 -8.753067,3.9047 -8.753067,8.75416 v 9.09569 a 50.663505,50.95301 0 0 0 -15.06221,8.94072 l -8.089206,-4.6705 c -4.199751,-2.42477 -9.533198,-0.99601 -11.957934,3.20377 l -8.61619,14.92534 c -2.4247365,4.19977 -0.9959782,9.53208 3.2037853,11.95684 l 8.3097237,4.79724 a 50.663505,50.95301 0 0 0 -0.791619,8.56976 50.663505,50.95301 0 0 0 0.811977,8.72482 l -8.0405786,4.64225 c -4.1997499,2.42476 -5.6285156,7.75707 -3.2037853,11.95677 l 8.6161899,14.92541 c 2.424737,4.19978 7.758197,5.62854 11.95794,3.20377 l 7.930877,-4.57893 a 50.663505,50.95301 0 0 0 14.93103,8.81636 v 9.12958 c 0,4.84953 3.903561,8.75306 8.753067,8.75306 h 17.234564 c 4.849471,0 8.753032,-3.90353 8.753032,-8.75306 v -8.90228 a 50.663505,50.95301 0 0 0 15.393578,-8.94415 l 7.757848,4.47942 c 4.19982,2.42477 9.53324,0.99601 11.95796,-3.20377 l 8.61621,-14.92541 c 2.42472,-4.1997 0.99596,-9.53201 -3.20378,-11.95677 l -7.78614,-4.49524 a 50.663505,50.95301 0 0 0 0.84705,-8.87183 50.663505,50.95301 0 0 0 -0.81197,-8.72475 l 8.0405,-4.64225 c 4.19982,-2.42476 5.62859,-7.75707 3.20385,-11.95684 l -8.6162,-14.92534 c -2.42474,-4.19978 -7.75823,-5.62854 -11.95797,-3.20377 l -7.930861,4.57893 a 50.663505,50.95301 0 0 0 -15.510075,-9.02895 v -8.91589 c 0,-4.84946 -3.903561,-8.75416 -8.753032,-8.75416 z m 8.9068,28.59545 A 36.767228,36.977328 0 0 1 103.05797,230.85344 36.767228,36.977328 0 0 1 66.290738,267.83108 36.767228,36.977328 0 0 1 29.5235,230.85344 36.767228,36.977328 0 0 1 66.290738,193.87587 Z"
id="path981"
inkscape:connector-curvature="0" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 3.4 KiB

View File

@@ -1,122 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="2000"
height="2000"
viewBox="0 0 529.16666 529.16735"
version="1.1"
id="svg8"
inkscape:version="0.92.4 (5da689c313, 2019-01-14)"
sodipodi:docname="Gridview.svg">
<defs
id="defs2" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="0.35729063"
inkscape:cx="901.7564"
inkscape:cy="1021.9111"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
showgrid="false"
units="px"
showguides="true"
inkscape:guide-bbox="true"
inkscape:window-width="1920"
inkscape:window-height="1017"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1">
<sodipodi:guide
position="247.25932,291.92959"
orientation="1,0"
id="guide853"
inkscape:locked="false" />
<sodipodi:guide
position="337.22901,167.98535"
orientation="0,1"
id="guide855"
inkscape:locked="false" />
<sodipodi:guide
position="266.76325,305.4565"
orientation="0,1"
id="guide857"
inkscape:locked="false" />
<sodipodi:guide
position="257.79774,279.50371"
orientation="0,1"
id="guide861"
inkscape:locked="false" />
</sodipodi:namedview>
<metadata
id="metadata5">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Ebene 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(0,232.16736)">
<g
id="g873"
transform="matrix(1.3431799,0,0,1.3431799,-84.854433,26.13855)"
style="stroke:none">
<rect
ry="7.445024"
rx="7.445024"
y="-121.39048"
x="79.903137"
height="113.24854"
width="167.35619"
id="rect815"
style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.56300002;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:1.12600005, 0.56300002999999998;stroke-dashoffset:0;stroke-opacity:0.22508042;paint-order:markers fill stroke" />
<rect
ry="7.445024"
rx="7.445024"
y="-121.7837"
x="273.05484"
height="113.24854"
width="167.35619"
id="rect815-4"
style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.56300002;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:1.12600006, 0.56300004000000003;stroke-dashoffset:0;stroke-opacity:0.22508042;paint-order:markers fill stroke" />
<rect
ry="7.445024"
rx="7.445024"
y="17.882772"
x="79.903137"
height="113.24854"
width="167.35619"
id="rect815-2"
style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.56300002;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:1.12600006, 0.56300004000000003;stroke-dashoffset:0;stroke-opacity:0.22508042;paint-order:markers fill stroke" />
<rect
ry="7.445024"
rx="7.445024"
y="17.453594"
x="273.05484"
height="113.24854"
width="167.35619"
id="rect815-7"
style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.56300002;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:1.12600006, 0.56300004000000003;stroke-dashoffset:0;stroke-opacity:0.22508042;paint-order:markers fill stroke" />
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 4.2 KiB

View File

@@ -1,8 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 26.5.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 500 500" style="enable-background:new 0 0 500 500;" xml:space="preserve">
<path d="M499.9,159L499.9,159c0.1-1.7,0.1-3.4,0.1-5.2c0-69.5-58.6-129.7-130.9-129.7c-52.9,0-98.4,34-119,77.4h0
c-20.7-43.4-66.2-77.4-119-77.4C58.6,24.1,0,84.4,0,153.9c0,1.7,0.1,3.4,0.1,5.2h0c0,0-7.4,82.6,84.5,172.7
c41.8,41.9,88.5,81.6,165.4,144.1c76.9-62.5,123.6-102.3,165.4-144.1C507.2,241.6,499.9,159,499.9,159z"/>
</svg>

Before

Width:  |  Height:  |  Size: 684 B

View File

@@ -1,122 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="2000"
height="2000"
viewBox="0 0 529.16666 529.16735"
version="1.1"
id="svg8"
inkscape:version="0.92.4 (5da689c313, 2019-01-14)"
sodipodi:docname="Listview.svg">
<defs
id="defs2" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="0.42053519"
inkscape:cx="851.82064"
inkscape:cy="1105.7974"
inkscape:document-units="mm"
inkscape:current-layer="g873"
showgrid="false"
units="px"
showguides="true"
inkscape:guide-bbox="true"
inkscape:window-width="1920"
inkscape:window-height="1017"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1">
<sodipodi:guide
position="247.25932,291.92959"
orientation="1,0"
id="guide853"
inkscape:locked="false" />
<sodipodi:guide
position="337.22901,167.98535"
orientation="0,1"
id="guide855"
inkscape:locked="false" />
<sodipodi:guide
position="266.76325,305.4565"
orientation="0,1"
id="guide857"
inkscape:locked="false" />
<sodipodi:guide
position="257.79774,279.50371"
orientation="0,1"
id="guide861"
inkscape:locked="false" />
<sodipodi:guide
position="22.413775,336.67894"
orientation="1,0"
id="guide926"
inkscape:locked="false" />
<sodipodi:guide
position="503.71355,217.50031"
orientation="1,0"
id="guide928"
inkscape:locked="false" />
</sodipodi:namedview>
<metadata
id="metadata5">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Ebene 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(0,232.16736)">
<g
id="g873"
transform="matrix(1.3431799,0,0,1.3431799,-84.854433,26.13855)">
<rect
ry="7.445024"
rx="7.445024"
y="-121.34892"
x="79.944702"
height="70.107315"
width="358.24551"
id="rect815"
style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.64810181;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:1.29620369, 0.64810185;stroke-dashoffset:0;stroke-opacity:0.22508042;paint-order:markers fill stroke" />
<rect
ry="7.4450235"
rx="7.4450235"
y="-31.167784"
x="79.861153"
height="70.107315"
width="358.32907"
id="rect815-20"
style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.64817739;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:1.29635485, 0.64817743;stroke-dashoffset:0;stroke-opacity:0.22508042;paint-order:markers fill stroke" />
<rect
ry="7.4450235"
rx="7.4450231"
y="60.024326"
x="79.908524"
height="70.106117"
width="358.28171"
id="rect815-8"
style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.64812905;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:1.29625813, 0.64812907;stroke-dashoffset:0;stroke-opacity:0.22508042;paint-order:markers fill stroke" />
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 4.0 KiB

View File

@@ -1,13 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 27.5.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1"
id="svg1303" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:svg="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 500 500"
style="enable-background:new 0 0 500 500;" xml:space="preserve">
<g>
<path d="M175.5,421.6c-4,0-8,0-12.1,0c-13.9-3.4-21-13-24.1-26.3c-1-4.5-1.5-9-1.5-13.6c0-87.7,0-175.4,0-263.1
c0-5.5,0.6-10.9,2.2-16.2c3.7-12.5,11-21.5,24.5-23.6c9-1.4,17.6,0.7,25.5,5c10.9,5.9,21.6,12.1,32.4,18.2
c66.6,38.2,133.2,76.4,199.8,114.6c7.1,4.1,13.7,8.7,18.8,15.4c8.7,11.5,8.7,25,0,36.5c-5,6.6-11.7,11.3-18.8,15.4
c-74,42.5-148.1,84.9-222.1,127.4C192.2,415.7,184.4,419.8,175.5,421.6z"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<svg viewBox="0 0 500 500" style="enable-background:new 0 0 500 500;" xmlns="http://www.w3.org/2000/svg">
<path d="M 408.514 358.563 L 303.835 255.003 L 408.441 149.115 C 424.1 133.406 424.1 107.662 408.441 91.953 C 392.783 76.245 367.12 76.245 351.463 91.953 L 246.857 197.841 L 142.323 91.881 C 126.665 76.172 101.002 76.172 85.344 91.881 C 69.613 107.662 69.613 133.334 85.272 149.115 L 189.805 255.003 L 84.401 359.291 C 68.743 375 68.743 400.744 84.401 416.453 C 100.06 432.161 125.722 432.161 141.381 416.453 L 246.784 312.165 L 351.39 415.726 C 367.048 431.434 392.711 431.434 408.369 415.726 C 424.172 400.017 424.172 374.345 408.514 358.563 Z" style="" transform="matrix(0.9999999999999999, 0, 0, 0.9999999999999999, 0, 0)"/>
</svg>

Before

Width:  |  Height:  |  Size: 782 B

View File

@@ -1,23 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 27.5.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1"
id="svg1303" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:svg="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 500 500"
style="enable-background:new 0 0 500 500;" xml:space="preserve">
<sodipodi:namedview bordercolor="#666666" borderopacity="1.0" id="base" inkscape:current-layer="layer1" inkscape:cx="125.63373" inkscape:cy="156.7016" inkscape:document-units="mm" inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:window-height="1017" inkscape:window-maximized="1" inkscape:window-width="1920" inkscape:window-x="-8" inkscape:window-y="-8" inkscape:zoom="0.85859018" pagecolor="#ffffff" showgrid="false" units="px">
</sodipodi:namedview>
<g>
<path d="M269,28.7c10.8,1.6,21.6,2.8,32.3,5.3c38.3,9.2,71.9,27.2,100.7,54.1c3.4,3.2,4.7,2.4,6.8-1.1c3.3-5.5,7.1-10.9,10.7-16.2
c4.8-7,11.3-9.7,18.5-7.6c6.8,1.9,11.5,8.2,11.5,16.5c-0.1,26.3,0.3,52.7-0.5,79c-0.4,12.5-0.1,25-0.2,37.6
c-0.1,14-11.1,21.3-23.9,15.6c-35.2-15.7-70.3-31.6-105.5-47.4c-7.7-3.5-11.8-10.1-10.8-16.9c1.1-7.8,6.9-13.2,15.6-14.4
c4-0.6,8-1.2,11.9-1.8c0.9-0.1,2.3,0.2,2.6-1.1c0.3-1.2-1-1.6-1.8-2.2c-12.2-8.9-25.5-15.7-39.8-20.3
c-72.7-23.2-148.9,9.9-181.6,78.9c-4.1,8.7-8.3,17-17.1,22.1c-13.7,8-30.1,6.6-42.2-3.8c-11.3-9.6-15.6-26.6-9.6-40.5
c15.7-36.9,39.4-67.7,71.6-91.8c29.8-22.4,63.2-36.3,100-41.9c4.8-0.7,9.7-1.3,14.5-2C244.8,28.7,256.9,28.7,269,28.7z"/>
<path d="M52.1,361.3c0.6-20,0.8-39,0.8-58c0-14,11.1-21.2,23.9-15.5c25.2,11.2,50.4,22.6,75.6,33.9c10.1,4.5,20.2,9,30.3,13.7
c6.4,2.9,10.5,7.8,10.5,15c0,6.4-3.2,11.2-9,14.2c-3.8,2-8.1,2-12.1,2.8c-2.1,0.4-4.3,0.6-6.4,1c-0.9,0.1-2.3-0.2-2.6,1.1
c-0.3,1.2,1,1.6,1.8,2.2c12.2,8.9,25.5,15.7,39.8,20.3c72.7,23.2,148.9-9.9,181.6-78.9c4.2-8.8,8.5-17.3,17.4-22.4
c13.6-7.7,29.8-6.3,41.8,4c11.3,9.6,15.6,26.6,9.7,40.5c-15.7,36.9-39.4,67.7-71.6,91.8c-29.7,22.3-62.9,36.5-99.6,41.8
c-57.8,8.3-110.9-4-159.1-36.9c-9.3-6.3-17.9-13.5-26.1-21.2c-2.1-2-3.3-2.1-4.9,0.5c-3.4,5.5-7.1,10.8-10.7,16.2
c-5.7,8.5-12.2,11.4-19.9,8.9c-7.3-2.3-11.1-8.6-11.1-18.5C52.1,398.6,52.1,379.4,52.1,361.3z"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.5 KiB

View File

@@ -1,15 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 27.5.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1"
id="svg1303" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:svg="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 500 500"
style="enable-background:new 0 0 500 500;" xml:space="preserve">
<g>
<path d="M492.4,462.2c-1,2.5-1.8,5.1-3,7.6C478,495,448.2,501.9,427.2,484c-1.8-1.5-3.5-3.2-5.2-4.9
c-34.1-34.8-68.3-69.5-102.3-104.4c-3.3-3.4-5.6-3.6-9.5-1c-30.5,20.3-64.1,31.1-100.6,32c-60.1,1.5-110.4-20.8-151.1-65.6
c-28.2-31-45.1-67.8-49.5-109.8C1.6,161.2,23.6,102.8,74.3,56.1c28.7-26.4,62.7-42.4,101-47.9c52.7-7.6,101,4.5,143.9,36.5
c43.7,32.6,70,76.6,78.4,131c7.1,45.8-1.1,89.2-23.7,129.6c-3.7,6.6-3.8,6.6,1.5,11.9c33.3,34,66.6,68,100.1,101.9
c7.6,7.7,14.2,15.9,16.9,26.7C494.1,451.5,493.6,456.9,492.4,462.2z M335.2,205.9c0.5-72.8-58.3-134.2-131.9-134
C132.9,72,72,129.3,72,206c0,74.8,58.1,134.2,131.7,134.2C278.8,340.2,335.8,278.1,335.2,205.9z"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.3 KiB

View File

@@ -1,63 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="500"
height="500"
viewBox="0 0 132.29197 132.29167"
version="1.1"
id="svg1303"
inkscape:version="0.92.4 (5da689c313, 2019-01-14)"
sodipodi:docname="Icons_seen-02.svg">
<defs
id="defs1297" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="1.0316211"
inkscape:cx="67.654116"
inkscape:cy="175.0818"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
showgrid="false"
units="px"
inkscape:window-width="1920"
inkscape:window-height="1017"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1" />
<metadata
id="metadata1300">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Ebene 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(0,-164.70764)">
<path
style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:markers fill stroke"
d="M 9.4628906 4.9277344 C 6.9502624 4.9277344 4.9277344 6.6131716 4.9277344 8.7070312 L 4.9277344 491.29297 C 4.9277344 493.38683 6.9502624 495.07227 9.4628906 495.07227 L 490.53711 495.07227 C 493.04974 495.07227 495.07227 493.38683 495.07227 491.29297 L 495.07227 8.7070312 C 495.07227 6.6131716 493.04974 4.9277344 490.53711 4.9277344 L 9.4628906 4.9277344 z M 53.607422 49.070312 L 446.39258 49.070312 C 448.90521 49.070312 450.92969 50.757703 450.92969 52.851562 L 450.92969 447.14844 C 450.92969 449.2423 448.90521 450.92969 446.39258 450.92969 L 53.607422 450.92969 C 51.094794 450.92969 49.070313 449.2423 49.070312 447.14844 L 49.070312 52.851562 C 49.070312 50.757703 51.094794 49.070312 53.607422 49.070312 z M 394.99414 104.48242 C 392.62745 104.47692 390.27922 105.49181 388.64453 107.46484 L 212.35547 320.24414 L 111.90625 232.94141 C 108.46825 229.95328 103.29681 230.31403 100.30859 233.75195 L 73.150391 264.99805 C 70.162261 268.43605 70.524968 273.60942 73.962891 276.59766 L 212.05469 396.62109 C 214.1632 398.4537 216.92406 399.02085 219.43359 398.39648 C 221.58781 398.24033 223.67676 397.24363 225.16992 395.44141 L 249.54883 366.01758 L 250.8125 364.5625 C 251.04106 364.29953 251.24412 364.0237 251.43359 363.74219 L 433.18555 144.36914 C 436.09166 140.86148 435.60727 135.69713 432.09961 132.79102 L 400.2207 106.37891 C 398.68612 105.10748 396.8349 104.4867 394.99414 104.48242 z "
transform="matrix(0.26458394,0,0,0.26458394,0,164.70749)"
id="rect816" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 3.3 KiB

View File

@@ -1,21 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 27.5.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1"
id="svg1303" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:svg="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 500 500"
style="enable-background:new 0 0 500 500;" xml:space="preserve">
<g>
<path d="M147.7,416.2c-8.7-3.4-11.9-8.1-11.9-17.5c0-53.5,0-107,0-160.5c0-9.3-4.2-15-12.6-16.7c-1.7-0.4-3.4-0.4-5.2-0.4
c-8.3,0-16.6,0-25,0c-7.3,0-12.9-3-16-9.5c-3.1-6.6-2.4-13,2.3-18.8c21.1-26.4,42.1-52.9,63.2-79.4c5.7-7.2,11.4-14.4,17.1-21.6
c3.2-4.1,7-7.4,12.5-7.9c6.6-0.6,11.4,2.3,15.3,7.3c5.7,7.4,11.5,14.9,17.3,22.3c20.5,26.4,40.9,52.8,61.5,79
c7.2,9.2,4.3,19.8-2,24.9c-3.2,2.6-6.8,3.6-10.8,3.6c-8.6,0-17.3,0-25.9,0c-10.6,0.1-16.2,5.6-16.2,16.2
c0,53.1-0.1,106.1,0.1,159.2c0,9.6-3.4,16.3-12.6,19.7C181.9,416.2,164.8,416.2,147.7,416.2z"/>
</g>
<g>
<path d="M369.5,83.8c8.7,3.4,11.9,8.1,11.9,17.5c0,53.5,0,106.9,0,160.4c0,9.3,4.2,15,12.6,16.7c1.7,0.3,3.4,0.4,5.2,0.4
c8.3,0,16.6,0,25,0c7.3,0,12.9,3,16,9.5c3.1,6.6,2.4,13-2.3,18.8c-21.1,26.4-42.1,52.9-63.2,79.3c-5.7,7.2-11.4,14.4-17.1,21.6
c-3.2,4.1-6.9,7.4-12.5,7.9c-6.6,0.6-11.4-2.3-15.3-7.3c-5.7-7.4-11.5-14.8-17.3-22.3c-20.5-26.4-40.8-52.8-61.5-79
c-7.2-9.2-4.3-19.8,2-24.9c3.2-2.6,6.8-3.6,10.8-3.6c8.6,0,17.3,0,25.9,0c10.6-0.1,16.2-5.6,16.2-16.2c0-53,0.1-106.1-0.1-159.1
c0-9.6,3.4-16.3,12.6-19.7C335.4,83.8,352.5,83.8,369.5,83.8z"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.7 KiB

View File

@@ -1,25 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 27.5.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1"
id="svg1303" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:svg="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 500 500"
style="enable-background:new 0 0 500 500;" xml:space="preserve">
<g>
<path d="M492.6,214.8c-2.7,7.3-7.9,12.7-13.8,17.7c-32.6,28.4-65.1,57-97.7,85.5c-2.4,2.1-2.4,4.1-1.8,6.7
c9.9,43.5,19.8,87.1,29.7,130.6c3.8,16.8-4.6,30.8-20.6,34.1c-7.2,1.5-13.7-0.8-19.8-4.4c-37.7-22.5-75.4-45-113-67.7
c-4.2-2.6-7.2-2.5-11.4,0.1c-37.7,22.8-75.6,45.3-113.4,67.9c-17.6,10.5-37.4,1.6-40.9-18.2c-0.7-3.8,0-7.5,0.8-11.2
c9.8-43.4,19.7-86.8,29.6-130.2c0.8-3.7,0.4-5.9-2.6-8.5c-33.2-28.9-66.3-58.1-99.5-87c-4.9-4.3-8.5-9.3-10.9-15.2
c-1-4.4-1.4-8.8,0-13.3c4.9-13.7,14.9-19.5,29.3-20.4c22.5-1.4,44.9-4,67.4-6.1c19-1.7,38-3.6,57-5c6.3-0.5,10.3-2.2,13-8.8
c16.4-39.3,33.3-78.3,50-117.4c2.6-6.2,5.7-12,11.5-15.8c13.6-8.9,31.4-4.1,38.3,11.1c8.8,19.4,17,39.1,25.3,58.7
c9.4,22.1,18.9,44.1,28.2,66.2c1.4,3.3,3.3,4.9,6.9,5.2c15.9,1.3,31.7,2.8,47.6,4.3c23.1,2.1,46.2,4.2,69.2,6.4
c4.2,0.4,8.5,1.1,12.7,1.1c14.3,0.2,23.9,6.8,28.8,20.3C494,206,493.8,210.4,492.6,214.8z M50.8,211.9c-1.9,0.3-2.5,2.7-1.1,3.9
c0.1,0.1,0.2,0.2,0.3,0.3c16.9,14.8,33.7,29.6,50.6,44.4c14.2,12.5,28.5,25,42.7,37.5c8.8,7.7,11.7,17.1,9,28.6
c-8.4,36.3-16.6,72.6-24.8,108.9c-0.9,4.1-2.1,8.1-2.8,12.2c-0.3,2.1,2.1,3.6,3.8,2.4c0.4-0.3,0.8-0.5,1.1-0.8
c34.9-20.8,69.7-41.6,104.5-62.4c3.7-2.2,7.4-4,11.8-4.7c8.6-1.4,15.6,2.2,22.7,6.4c34.1,20.5,68.3,40.9,102.5,61.3
c1.2,0.7,2.6,2.6,4.1,1.3c1.1-1,0-2.7-0.3-4c-9-39.7-17.7-79.5-27-119.1c-3-12.8,0.1-22.8,9.9-31.3c24.3-21.1,48.5-42.4,72.7-63.6
c6.7-5.8,13.3-11.7,20.2-17.8c1.4-1.2,0.7-3.6-1.2-3.8c0,0,0,0,0,0c-17.9-1.6-35.8-3.3-53.7-4.8c-22.6-2-45.2-4.2-67.9-5.9
c-14.2-1.1-22.9-8-28.4-21.2c-15.4-37.2-31.5-74.1-47.3-111.1c-0.5-1.2-0.6-3.2-2.3-3.2s-1.8,2-2.3,3.2c-7.7,18-15.4,36-23.1,54
c-8.6,20.2-17.2,40.4-25.9,60.6c-4,9.2-10.6,15.6-20.7,16.7c-20.2,2.3-40.5,4-60.8,5.8c-19,1.7-38,3.2-57,5.1
C57.2,211,54.2,211.3,50.8,211.9z"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.4 KiB

View File

@@ -1,19 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 27.5.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1"
id="svg1303" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:svg="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 500 500"
style="enable-background:new 0 0 500 500;" xml:space="preserve">
<sodipodi:namedview bordercolor="#666666" borderopacity="1.0" id="base" inkscape:current-layer="layer1" inkscape:cx="61.891881" inkscape:cy="148.25167" inkscape:document-units="mm" inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:window-height="1017" inkscape:window-maximized="1" inkscape:window-width="1920" inkscape:window-x="-8" inkscape:window-y="-8" inkscape:zoom="1.0105705" pagecolor="#ffffff" showgrid="false" units="px">
</sodipodi:namedview>
<g>
<path d="M493.2,207.8c-2.7,7.3-7.9,12.7-13.8,17.7c-32.6,28.4-65.1,57-97.7,85.5c-2.4,2.1-2.4,4.1-1.8,6.7
c9.9,43.5,19.8,87.1,29.7,130.6c3.8,16.8-4.6,30.8-20.6,34.1c-7.2,1.5-13.7-0.8-19.8-4.4c-37.7-22.5-75.4-45-113-67.7
c-4.2-2.6-7.2-2.5-11.4,0.1c-37.7,22.8-75.6,45.3-113.4,67.9c-17.6,10.5-37.4,1.6-40.9-18.2c-0.7-3.8,0-7.5,0.8-11.2
c9.8-43.4,19.7-86.8,29.6-130.2c0.8-3.7,0.4-5.9-2.6-8.5C85.1,281.1,52,252,18.8,223c-4.9-4.3-8.5-9.3-10.9-15.2
c-1-4.4-1.4-8.8,0-13.3c4.9-13.7,14.9-19.5,29.3-20.4c22.5-1.4,44.9-4,67.4-6.1c19-1.7,38-3.6,57-5c6.3-0.5,10.3-2.2,13-8.8
c16.3-39.2,33.2-78.2,49.8-117.2c2.6-6.2,5.7-12,11.5-15.8c13.6-8.9,31.4-4.1,38.3,11.1c8.8,19.4,17,39.1,25.3,58.7
c9.4,22.1,18.9,44.1,28.2,66.2c1.4,3.3,3.3,4.9,6.9,5.2c15.9,1.3,31.7,2.8,47.6,4.3c23.1,2.1,46.2,4.2,69.2,6.4
c4.2,0.4,8.5,1.1,12.7,1.1c14.3,0.2,23.9,6.8,28.8,20.3C494.5,199,494.3,203.4,493.2,207.8z"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.0 KiB

View File

@@ -1,22 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 27.5.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1"
id="svg1303" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:svg="http://www.w3.org/2000/svg" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:cc="http://creativecommons.org/ns#"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 500 500"
style="enable-background:new 0 0 500 500;" xml:space="preserve">
<g>
<path d="M7.5,207.8c2.8,7.3,8,12.6,13.8,17.7C54,253.9,86.4,282.6,119,311c2.4,2.1,2.4,4.1,1.8,6.7c-9.9,43.5-19.8,87.1-29.7,130.6
c-3.9,16.9,4.6,30.9,20.6,34.1c7.2,1.5,13.7-0.7,19.8-4.4c37.7-22.6,75.4-45,112.9-68c1.9-1.3,3.7-1.9,5.4-1.9v0.3
c1.9,0,3.7,0.6,5.8,1.9c37.7,22.8,75.5,45.4,113.4,67.9c17.6,10.5,37.4,1.6,40.9-18.2c0.7-3.8,0-7.5-0.8-11.2
c-9.8-43.4-19.6-86.8-29.6-130.2c-0.9-3.6-0.4-5.9,2.6-8.5c33.3-28.9,66.3-58,99.5-87c4.9-4.3,8.5-9.3,10.9-15.2
c1-4.5,1.4-8.9,0-13.3c-5-13.7-14.9-19.5-29.3-20.4c-22.5-1.4-44.9-4.1-67.4-6.1c-19-1.8-38-3.6-57-5c-6.3-0.5-10.2-2.2-13-8.8
c-16.2-39.2-33.2-78.1-49.8-117.2c-2.6-6.2-5.7-12-11.5-15.8c-4.6-3-9.5-4.5-14.5-4.5v-0.1c-9.8,0-19.2,5.5-23.8,15.6
c-8.8,19.4-16.9,39.1-25.3,58.7c-9.5,22-18.9,44.1-28.2,66.2c-1.4,3.3-3.3,4.9-6.9,5.2c-15.9,1.3-31.7,2.8-47.6,4.3
c-23,2.2-46.1,4.3-69.2,6.4c-4.2,0.4-8.5,1-12.7,1.1C22,174.4,12.4,181,7.5,194.5C6.1,199,6.3,203.4,7.5,207.8z M250,374.9V58.2
c1.6,0.1,1.7,2,2.2,3.2c7.7,18,15.4,36,23.1,54c8.7,20.2,17.3,40.4,25.9,60.6c3.9,9.2,10.6,15.6,20.7,16.7
c20.3,2.3,40.5,4,60.8,5.8c19,1.7,38,3.1,57,5.1l6,0.6c3.3,0.3,4.6,4.3,2.1,6.5c-15.6,13.8-33.6,29.7-48.4,42.7
c-14.2,12.5-28.5,25-42.7,37.5c-8.7,7.7-11.6,17.2-9,28.6c8.4,36.2,16.6,72.6,24.8,108.9c0.9,4,2.1,8,2.8,12.1
c0.3,2.2-2.1,3.7-3.9,2.5c-0.4-0.3-0.7-0.5-1.1-0.7c-34.8-20.8-69.7-41.6-104.5-62.4c-3.7-2.2-7.5-4-11.8-4.7
C252.8,375,251.6,374.9,250,374.9L250,374.9z"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.1 KiB

Some files were not shown because too many files have changed in this diff Show More