anilife update 2022.10.23(01.)

This commit is contained in:
2022-10-24 00:49:35 +09:00
parent 11a933a4f6
commit 5ff663e288
2 changed files with 438 additions and 296 deletions

View File

@@ -603,6 +603,8 @@ class LogicAniLife(LogicModuleBase):
options.add_argument("start-maximized") options.add_argument("start-maximized")
options.add_argument("--headless") options.add_argument("--headless")
options.add_argument("--no-sandbox") options.add_argument("--no-sandbox")
options.add_argument("window-size=1920x1080")
options.add_argument("disable-gpu")
# options.add_argument('--no-sandbox') # options.add_argument('--no-sandbox')
options.add_argument("--disable-dev-shm-usage") options.add_argument("--disable-dev-shm-usage")
options.add_experimental_option("excludeSwitches", ["enable-automation"]) options.add_experimental_option("excludeSwitches", ["enable-automation"])

View File

@@ -1,368 +1,508 @@
{% extends "base.html" %} {% block content %} {% extends "base.html" %} {% block content %}
<div> <div>
<form id="program_list"> <div id="loader" class="loader">
{{ macros.setting_input_text_and_buttons('code', '작품 Code', <div class="loader-inner">
[['analysis_btn', '분석'], ['go_anilife_btn', 'Go 애니라이프']], desc='예) <div class="loader-line-wrap">
"https://anilife.live/g/l?id=f6e83ec6-bd25-4d6c-9428-c10522687604" 이나 "f6e83ec6-bd25-4d6c-9428-c10522687604"') }} <div class="loader-line"></div>
</form> </div>
<form id="program_auto_form"> <div class="loader-line-wrap">
<div id="episode_list"></div> <div class="loader-line"></div>
</form> </div>
<div class="loader-line-wrap">
<div class="loader-line"></div>
</div>
<div class="loader-line-wrap">
<div class="loader-line"></div>
</div>
<div class="loader-line-wrap">
<div class="loader-line"></div>
</div>
</div>
</div>
<form id="program_list">
{{ macros.setting_input_text_and_buttons('code', '작품 Code',
[['analysis_btn', '분석'], ['go_anilife_btn', 'Go 애니라이프']], desc='예)
"https://anilife.live/g/l?id=f6e83ec6-bd25-4d6c-9428-c10522687604" 이나 "f6e83ec6-bd25-4d6c-9428-c10522687604"')
}}
</form>
<form id="program_auto_form">
<div id="episode_list"></div>
</form>
</div> </div>
<!--전체--> <!--전체-->
<script type="text/javascript"> <script type="text/javascript">
const package_name = "{{arg['package_name'] }}"; const package_name = "{{arg['package_name'] }}";
const sub = "{{arg['sub'] }}"; const sub = "{{arg['sub'] }}";
const anilife_url = "{{arg['anilife_url']}}"; const anilife_url = "{{arg['anilife_url']}}";
let current_data = null; let current_data = null;
const params = new Proxy(new URLSearchParams(window.location.search), { const params = new Proxy(new URLSearchParams(window.location.search), {
get: (searchParams, prop) => searchParams.get(prop), get: (searchParams, prop) => searchParams.get(prop),
}) })
function findGetParameter(parameterName) {
let result = null,
tmp = [];
const items = location.search.substr(1).split("&");
for (let index = 0; index < items.length; index++) {
tmp = items[index].split("=");
if (tmp[0] === parameterName) result = decodeURIComponent(tmp[1]);
}
return result;
}
function findGetParameter(parameterName) { function analyze(wr_id, bo_table) {
let result = null, e.preventDefault();
tmp = []; e.stopPropagation()
const items = location.search.substr(1).split("&"); // e.preventDefault();
for (let index = 0; index < items.length; index++) { const code = document.getElementById("code").value
tmp = items[index].split("="); console.log(code)
if (tmp[0] === parameterName) result = decodeURIComponent(tmp[1]); $.ajax({
} url: '/' + package_name + '/ajax/' + sub + '/analysis',
return result; type: "POST",
} cache: false,
data: {code: code, wr_id: wr_id, bo_table: bo_table},
dataType: "json",
success: function (ret) {
if (ret.ret === 'success' && ret.data != null) {
// {#console.log(ret.code)#}
console.log(ret.data)
make_program(ret.data)
$("#loader").css("display", 'none')
} else {
$.notify('<strong>분석 실패</strong><br>' + ret.log, {type: 'warning'});
}
}
});
}
function analyze(wr_id, bo_table) { function make_program(data) {
// e.preventDefault(); current_data = data;
const code = document.getElementById("code").value // console.log("current_data::", current_data)
console.log(code) str = '';
$.ajax({ tmp = '<div class="form-inline">'
url: '/' + package_name + '/ajax/' + sub + '/analysis', tmp += m_button('check_download_btn', '선택 다운로드 추가', []);
type: "POST", tmp += m_button('all_check_on_btn', '전체 선택', []);
cache: false, tmp += m_button('all_check_off_btn', '전체 해제', []);
data: {code: code, wr_id: wr_id, bo_table: bo_table}, /*
dataType: "json", tmp += '&nbsp;&nbsp;&nbsp;&nbsp;<input id="new_title" name="new_title" class="form-control form-control-sm" value="'+data.title+'">'
success: function (ret) { tmp += '</div>'
if (ret.ret === 'success' && ret.data != null) { tmp += m_button('apply_new_title_btn', '저장폴더명, 파일명 제목 변경', []);
// {#console.log(ret.code)#} tmp += m_button('search_tvdb_btn', 'TVDB', []);
console.log(ret.data) tmp = m_button_group(tmp)
make_program(ret.data) */
} else { str += tmp
$.notify('<strong>분석 실패</strong><br>' + ret.log, {type: 'warning'}); // program
} str += m_hr_black();
} str += m_row_start(0);
}); tmp = ''
} if (data.image != null)
tmp = '<img src="' + data.image + '" class="img-fluid">';
str += m_col(3, tmp)
tmp = ''
tmp += m_row_start(2) + m_col(3, '제목', 'right') + m_col(9, data.title) + m_row_end();
// tmp += m_row_start(2) + m_col(3, '제작사', 'right') + m_col(9, data.des._pub) + m_row_end();
// tmp += m_row_start(2) + m_col(3, '감독', 'right') + m_col(9, data.des._dir) + m_row_end();
//
// tmp += m_row_start(2) + m_col(3, '원작', 'right') + m_col(9, data.des._otit) + m_row_end();
// tmp += m_row_start(2) + m_col(3, '장르', 'right') + m_col(9, data.des._tag) + m_row_end();
// tmp += m_row_start(2) + m_col(3, '분류', 'right') + m_col(9, data.des._classifi) + m_row_end();
// tmp += m_row_start(2) + m_col(3, '공식 방영일', 'right') + m_col(9, data.date+'('+data.day+')') + m_row_end();
// tmp += m_row_start(2) + m_col(3, '에피소드', 'right') + m_col(9, data.des._total_chapter ? data.des._total_chapter : '') + m_row_end();
// tmp += m_row_start(2) + m_col(3, '등급', 'right') + m_col(9, data.des._grade) + m_row_end();
// tmp += m_row_start(2) + m_col(3, '최근 방영일', 'right') + m_col(9, data.des._recent_date ? data.des._recent_date : '') + m_row_end();
// tmp += m_row_start(2) + m_col(3, '줄거리', 'right') + m_col(9, data.ser_description) + m_row_end();
function make_program(data) { tmp += "<div>" + data.des1 + "</div>"
current_data = data; str += m_col(9, tmp)
console.log("current_data::", current_data) str += m_row_end();
str = '';
tmp = '<div class="form-inline">'
tmp += m_button('check_download_btn', '선택 다운로드 추가', []);
tmp += m_button('all_check_on_btn', '전체 선택', []);
tmp += m_button('all_check_off_btn', '전체 해제', []);
/*
tmp += '&nbsp;&nbsp;&nbsp;&nbsp;<input id="new_title" name="new_title" class="form-control form-control-sm" value="'+data.title+'">'
tmp += '</div>'
tmp += m_button('apply_new_title_btn', '저장폴더명, 파일명 제목 변경', []);
tmp += m_button('search_tvdb_btn', 'TVDB', []);
tmp = m_button_group(tmp)
*/
str += tmp
// program
str += m_hr_black();
str += m_row_start(0);
tmp = ''
if (data.image != null)
tmp = '<img src="' + data.image + '" class="img-fluid">';
str += m_col(3, tmp)
tmp = ''
tmp += m_row_start(2) + m_col(3, '제목', 'right') + m_col(9, data.title) + m_row_end();
// tmp += m_row_start(2) + m_col(3, '제작사', 'right') + m_col(9, data.des._pub) + m_row_end();
// tmp += m_row_start(2) + m_col(3, '감독', 'right') + m_col(9, data.des._dir) + m_row_end();
//
// tmp += m_row_start(2) + m_col(3, '원작', 'right') + m_col(9, data.des._otit) + m_row_end();
// tmp += m_row_start(2) + m_col(3, '장르', 'right') + m_col(9, data.des._tag) + m_row_end();
// tmp += m_row_start(2) + m_col(3, '분류', 'right') + m_col(9, data.des._classifi) + m_row_end();
// tmp += m_row_start(2) + m_col(3, '공식 방영일', 'right') + m_col(9, data.date+'('+data.day+')') + m_row_end();
// tmp += m_row_start(2) + m_col(3, '에피소드', 'right') + m_col(9, data.des._total_chapter ? data.des._total_chapter : '') + m_row_end();
// tmp += m_row_start(2) + m_col(3, '등급', 'right') + m_col(9, data.des._grade) + m_row_end();
// tmp += m_row_start(2) + m_col(3, '최근 방영일', 'right') + m_col(9, data.des._recent_date ? data.des._recent_date : '') + m_row_end();
// tmp += m_row_start(2) + m_col(3, '줄거리', 'right') + m_col(9, data.ser_description) + m_row_end();
tmp += "<div>" + data.des1 + "</div>" str += m_hr_black();
str += m_col(9, tmp) for (i in data.episode) {
str += m_row_end(); str += m_row_start();
tmp = '';
if (data.episode[i].thumbnail)
tmp = '<img src="' + data.episode[i].thumbnail + '" class="img-fluid">'
str += m_col(3, tmp)
tmp = '<strong>' + data.episode[i].ep_num + '화. ' + data.episode[i].title + '</strong>';
tmp += '<br>';
tmp += data.episode[i].date + '<br>';
str += m_hr_black(); tmp += '<div class="form-inline">'
for (i in data.episode) { tmp += '<input id="checkbox_' + i + '" name="checkbox_' + i + '" type="checkbox" checked data-toggle="toggle" data-on="선 택" data-off="-" data-onstyle="success" data-offstyle="danger" data-size="small">&nbsp;&nbsp;&nbsp;&nbsp;'
str += m_row_start(); tmp = ''; tmp += m_button('add_queue_btn', '다운로드 추가', [{'key': 'idx', 'value': i}])
if (data.episode[i].thumbnail) tmp += '</div>'
tmp = '<img src="'+ data.episode[i].thumbnail + '" class="img-fluid">' str += m_col(9, tmp)
str += m_col(3, tmp) str += m_row_end();
tmp = '<strong>' + data.episode[i].ep_num + '화. ' + data.episode[i].title+ '</strong>'; if (i != data.length - 1) str += m_hr(0);
tmp += '<br>'; }
tmp += data.episode[i].date + '<br>'; document.getElementById("episode_list").innerHTML = str;
$('input[id^="checkbox_"]').bootstrapToggle()
}
tmp += '<div class="form-inline">' $(function () {
tmp += '<input id="checkbox_'+i+'" name="checkbox_'+i+'" type="checkbox" checked data-toggle="toggle" data-on="선 택" data-off="-" data-onstyle="success" data-offstyle="danger" data-size="small">&nbsp;&nbsp;&nbsp;&nbsp;' console.log(params.wr_id)
tmp += m_button('add_queue_btn', '다운로드 추가', [{'key':'idx', 'value':i}]) console.log(findGetParameter('wr_id'))
tmp += '</div>' console.log(params.code)
str += m_col(9, tmp) if (params.code === '') {
str += m_row_end();
if (i != data.length -1) str += m_hr(0);
}
document.getElementById("episode_list").innerHTML = str;
$('input[id^="checkbox_"]').bootstrapToggle()
}
$(function () { } else {
console.log(params.wr_id) document.getElementById("code").value = params.code
console.log(findGetParameter('wr_id')) document.getElementById("analysis_btn").click();
console.log(params.code) }
if (params.code === '') {
} else { if ("{{arg['anilife_current_code']}}" !== "") {
document.getElementById("code").value = params.code if (params.code === null) {
// {#document.getElementById("analysis_btn").click();#} console.log('params.code === null')
} document.getElementById("code").value = "{{arg['anilife_current_code']}}";
if ( "{{arg['anilife_current_code']}}" !== "") { } else if (params.code === '') {
if (params.code === null) { document.getElementById("code").value = "{{arg['anilife_current_code']}}";
console.log('params.code === null') } else {
document.getElementById("code").value = "{{arg['anilife_current_code']}}";
} else if(params.code === '') { console.log('params code exist')
document.getElementById("code").value = "{{arg['anilife_current_code']}}"; console.log(params.code)
} else { document.getElementById("code").value = params.code
console.log('params code exist') analyze(params.wr_id, params.bo_table)
console.log(params.code) // document.getElementById("analysis_btn").click();
document.getElementById("code").value = params.code // $('#analysis_btn').trigger('click')
}
// 값이 공백이 아니면 분석 버튼 계속 누름
// {#document.getElementById("analysis_btn").click();#}
} else {
analyze(params.wr_id, params.bo_table) }
// document.getElementById("analysis_btn").click();
// $('#analysis_btn').trigger('click')
}
// 값이 공백이 아니면 분석 버튼 계속 누름
// {#document.getElementById("analysis_btn").click();#}
} else {
} })
}) $(document).ready(function () {
$("#loader").css("display", 'none')
// console.log('wr_id::', params.wr_id)
$(document).ready(function(){ });
console.log('wr_id::', params.wr_id) $("#analysis_btn").unbind("click").bind('click', function (e) {
e.preventDefault();
}); e.stopPropagation()
$("#loader").css("display", 'block')
$("#analysis_btn").unbind("click").bind('click', function(e){ const code = document.getElementById("code").value
e.preventDefault(); console.log(code)
e.stopPropagation() $.ajax({
const code = document.getElementById("code").value url: '/' + package_name + '/ajax/' + sub + '/analysis',
console.log(code) type: "POST",
$.ajax({ cache: false,
url: '/' + package_name + '/ajax/' + sub + '/analysis', data: {code: code},
type: "POST", dataType: "json",
cache: false, success: function (ret) {
data: {code:code}, $("#loader").css("display", 'none')
dataType: "json", if (ret.ret === 'success' && ret.data != null) {
success: function (ret) { // {#console.log(ret.code)#}
if (ret.ret === 'success' && ret.data != null) { console.log(ret.data)
// {#console.log(ret.code)#} make_program(ret.data)
console.log(ret.data) } else {
make_program(ret.data) $.notify('<strong>분석 실패</strong><br>' + ret.log, {type: 'warning'});
} else { }
$.notify('<strong>분석 실패</strong><br>' + ret.log, {type: 'warning'}); }
} });
} });
});
});
$("body").on('click', '#go_anilife_btn', function(e){ $("body").on('click', '#go_anilife_btn', function (e) {
e.preventDefault(); e.preventDefault();
window.open("{{arg['anilife_url']}}", "_blank"); window.open("{{arg['anilife_url']}}", "_blank");
}); });
$("body").on('click', '#all_check_on_btn', function(e){ $("body").on('click', '#all_check_on_btn', function (e) {
e.preventDefault(); e.preventDefault();
$('input[id^="checkbox_"]').bootstrapToggle('on') $('input[id^="checkbox_"]').bootstrapToggle('on')
}); });
$("body").on('click', '#all_check_off_btn', function(e){ $("body").on('click', '#all_check_off_btn', function (e) {
e.preventDefault(); e.preventDefault();
$('input[id^="checkbox_"]').bootstrapToggle('off') $('input[id^="checkbox_"]').bootstrapToggle('off')
}); });
$("body").on('click', '#add_queue_btn', function(e){ $("body").on('click', '#add_queue_btn', function (e) {
e.preventDefault(); e.preventDefault();
data = current_data.episode[$(this).data('idx')]; data = current_data.episode[$(this).data('idx')];
console.log('data:::>', data) console.log('data:::>', data)
$.ajax({ $.ajax({
url: '/' + package_name + '/ajax/' + sub + '/add_queue', url: '/' + package_name + '/ajax/' + sub + '/add_queue',
type: "POST", type: "POST",
cache: false, cache: false,
data: {data:JSON.stringify(data)}, data: {data: JSON.stringify(data)},
dataType: "json", dataType: "json",
success: function (data) { success: function (data) {
console.log('#add_queue_btn::data >>', data) console.log('#add_queue_btn::data >>', data)
if (data.ret == 'enqueue_db_append' || data.ret == 'enqueue_db_exist') { if (data.ret == 'enqueue_db_append' || data.ret == 'enqueue_db_exist') {
$.notify('<strong>다운로드 작업을 추가 하였습니다.</strong>', {type: 'success'}); $.notify('<strong>다운로드 작업을 추가 하였습니다.</strong>', {type: 'success'});
} else if (data.ret == 'queue_exist') { } else if (data.ret == 'queue_exist') {
$.notify('<strong>이미 큐에 있습니다. 삭제 후 추가하세요.</strong>', {type: 'warning'}); $.notify('<strong>이미 큐에 있습니다. 삭제 후 추가하세요.</strong>', {type: 'warning'});
} else if (data.ret == 'db_completed') { } else if (data.ret == 'db_completed') {
$.notify('<strong>DB에 완료 기록이 있습니다.</strong>', {type: 'warning'}); $.notify('<strong>DB에 완료 기록이 있습니다.</strong>', {type: 'warning'});
} else { } else {
$.notify('<strong>추가 실패</strong><br>' + ret.log, {type: 'warning'}); $.notify('<strong>추가 실패</strong><br>' + ret.log, {type: 'warning'});
}
} }
}
}); });
}); });
$("body").on('click', '#check_download_btn', function(e){ $("body").on('click', '#check_download_btn', function (e) {
e.preventDefault(); e.preventDefault();
all = $('input[id^="checkbox_"]'); all = $('input[id^="checkbox_"]');
let data = []; let data = [];
let idx; let idx;
for (let i in all) { for (let i in all) {
if (all[i].checked) { if (all[i].checked) {
idx = parseInt(all[i].id.split('_')[1]) idx = parseInt(all[i].id.split('_')[1])
data.push(current_data.episode[idx]); data.push(current_data.episode[idx]);
} }
} }
if (data.length == 0) { if (data.length == 0) {
$.notify('<strong>선택하세요.</strong>', {type: 'warning'}); $.notify('<strong>선택하세요.</strong>', {type: 'warning'});
return; return;
} }
$.ajax({ $.ajax({
url: '/' + package_name + '/ajax/' + sub + '/add_queue_checked_list', url: '/' + package_name + '/ajax/' + sub + '/add_queue_checked_list',
type: "POST", type: "POST",
cache: false, cache: false,
data: {data:JSON.stringify(data)}, data: {data: JSON.stringify(data)},
dataType: "json", dataType: "json",
success: function (data) { success: function (data) {
$.notify('<strong>백그라운드로 작업을 추가합니다.</strong>', {type: 'success'}); $.notify('<strong>백그라운드로 작업을 추가합니다.</strong>', {type: 'success'});
} }
}); });
}); });
</script> </script>
<style> <style>
button.code-button { button.code-button {
min-width: 82px !important; min-width: 82px !important;
} }
.tooltip {
position: relative;
display: block;
}
[data-tooltip-text]:hover { .tooltip {
position: relative; position: relative;
} display: block;
}
[data-tooltip-text]:after { [data-tooltip-text]:hover {
-webkit-transition: bottom 0.3s ease-in-out, opacity 0.3s ease-in-out; position: relative;
-moz-transition: bottom 0.3s ease-in-out, opacity 0.3s ease-in-out; }
transition: bottom 0.3s ease-in-out, opacity 0.3s ease-in-out;
background-color: rgba(0, 0, 0, 0.8); [data-tooltip-text]:after {
-webkit-transition: bottom 0.3s ease-in-out, opacity 0.3s ease-in-out;
-moz-transition: bottom 0.3s ease-in-out, opacity 0.3s ease-in-out;
transition: bottom 0.3s ease-in-out, opacity 0.3s ease-in-out;
-webkit-box-shadow: 0px 0px 3px 1px rgba(50, 50, 50, 0.4); background-color: rgba(0, 0, 0, 0.8);
-moz-box-shadow: 0px 0px 3px 1px rgba(50, 50, 50, 0.4);
box-shadow: 0px 0px 3px 1px rgba(50, 50, 50, 0.4);
-webkit-border-radius: 5px; -webkit-box-shadow: 0px 0px 3px 1px rgba(50, 50, 50, 0.4);
-moz-border-radius: 5px; -moz-box-shadow: 0px 0px 3px 1px rgba(50, 50, 50, 0.4);
border-radius: 5px; box-shadow: 0px 0px 3px 1px rgba(50, 50, 50, 0.4);
color: #ffffff; -webkit-border-radius: 5px;
font-size: 12px; -moz-border-radius: 5px;
margin-bottom: 10px; border-radius: 5px;
padding: 7px 12px;
position: absolute;
width: auto;
min-width: 50px;
max-width: 300px;
word-wrap: break-word;
z-index: 9999; color: #ffffff;
font-size: 12px;
margin-bottom: 10px;
padding: 7px 12px;
position: absolute;
width: auto;
min-width: 50px;
max-width: 300px;
word-wrap: break-word;
opacity: 0; z-index: 9999;
left: -9999px;
top: 90%;
content: attr(data-tooltip-text); opacity: 0;
} left: -9999px;
top: 90%;
[data-tooltip-text]:hover:after { content: attr(data-tooltip-text);
top: 230%; }
left: 0;
opacity: 1;
}
[data-tooltip-text]:hover {
position: relative;
}
[data-tooltip-text]:after { [data-tooltip-text]:hover:after {
-webkit-transition: bottom 0.3s ease-in-out, opacity 0.3s ease-in-out; top: 230%;
-moz-transition: bottom 0.3s ease-in-out, opacity 0.3s ease-in-out; left: 0;
transition: bottom 0.3s ease-in-out, opacity 0.3s ease-in-out; opacity: 1;
}
background-color: rgba(0, 0, 0, 0.8); [data-tooltip-text]:hover {
position: relative;
}
-webkit-box-shadow: 0px 0px 3px 1px rgba(50, 50, 50, 0.4); [data-tooltip-text]:after {
-moz-box-shadow: 0px 0px 3px 1px rgba(50, 50, 50, 0.4); -webkit-transition: bottom 0.3s ease-in-out, opacity 0.3s ease-in-out;
box-shadow: 0px 0px 3px 1px rgba(50, 50, 50, 0.4); -moz-transition: bottom 0.3s ease-in-out, opacity 0.3s ease-in-out;
transition: bottom 0.3s ease-in-out, opacity 0.3s ease-in-out;
-webkit-border-radius: 5px; background-color: rgba(0, 0, 0, 0.8);
-moz-border-radius: 5px;
border-radius: 5px;
color: #ffffff; -webkit-box-shadow: 0px 0px 3px 1px rgba(50, 50, 50, 0.4);
font-size: 12px; -moz-box-shadow: 0px 0px 3px 1px rgba(50, 50, 50, 0.4);
margin-bottom: 10px; box-shadow: 0px 0px 3px 1px rgba(50, 50, 50, 0.4);
padding: 7px 12px;
position: absolute;
width: auto;
min-width: 50px;
max-width: 300px;
word-wrap: break-word;
z-index: 9999; -webkit-border-radius: 5px;
-moz-border-radius: 5px;
border-radius: 5px;
opacity: 0; color: #ffffff;
left: -9999px; font-size: 12px;
top: -210% !important; margin-bottom: 10px;
padding: 7px 12px;
position: absolute;
width: auto;
min-width: 50px;
max-width: 300px;
word-wrap: break-word;
content: attr(data-tooltip-text); z-index: 9999;
}
[data-tooltip-text]:hover:after { opacity: 0;
top: 130%; left: -9999px;
left: 0; top: -210% !important;
opacity: 1;
}
#airing_list { content: attr(data-tooltip-text);
display: none; }
}
.cut-text { [data-tooltip-text]:hover:after {
text-overflow: ellipsis; top: 130%;
overflow: hidden; left: 0;
white-space: nowrap; opacity: 1;
width: 100%; }
}
#screen_movie_list { #airing_list {
margin-top: 10px; display: none;
} }
.cut-text {
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
width: 100%;
}
#screen_movie_list {
margin-top: 10px;
}
.loader {
background: rgb(0, 0, 0, 0.8);
background: radial-gradient(#222, #000);
bottom: 0;
left: 0;
overflow: hidden;
position: fixed;
right: 0;
top: 0;
z-index: 99999;
}
.loader-inner {
bottom: 0;
height: 60px;
left: 0;
margin: auto;
position: absolute;
right: 0;
top: 0;
width: 100px;
}
.loader-line-wrap {
animation: spin 2000ms cubic-bezier(.175, .885, .32, 1.275) infinite;
box-sizing: border-box;
height: 50px;
left: 0;
overflow: hidden;
position: absolute;
top: 0;
transform-origin: 50% 100%;
width: 100px;
}
.loader-line {
border: 4px solid transparent;
border-radius: 100%;
box-sizing: border-box;
height: 100px;
left: 0;
margin: 0 auto;
position: absolute;
right: 0;
top: 0;
width: 100px;
}
.loader-line-wrap:nth-child(1) {
animation-delay: -50ms;
}
.loader-line-wrap:nth-child(2) {
animation-delay: -100ms;
}
.loader-line-wrap:nth-child(3) {
animation-delay: -150ms;
}
.loader-line-wrap:nth-child(4) {
animation-delay: -200ms;
}
.loader-line-wrap:nth-child(5) {
animation-delay: -250ms;
}
.loader-line-wrap:nth-child(1) .loader-line {
border-color: hsl(0, 80%, 60%);
height: 90px;
width: 90px;
top: 7px;
}
.loader-line-wrap:nth-child(2) .loader-line {
border-color: hsl(60, 80%, 60%);
height: 76px;
width: 76px;
top: 14px;
}
.loader-line-wrap:nth-child(3) .loader-line {
border-color: hsl(120, 80%, 60%);
height: 62px;
width: 62px;
top: 21px;
}
.loader-line-wrap:nth-child(4) .loader-line {
border-color: hsl(180, 80%, 60%);
height: 48px;
width: 48px;
top: 28px;
}
.loader-line-wrap:nth-child(5) .loader-line {
border-color: hsl(240, 80%, 60%);
height: 34px;
width: 34px;
top: 35px;
}
@keyframes spin {
0%, 15% {
transform: rotate(0);
}
100% {
transform: rotate(360deg);
}
}
</style> </style>
{% endblock %} {% endblock %}