chg: [vanity] add vanity domain explorer + fix blurred screenshot + fix languages search filter

This commit is contained in:
terrtia 2024-02-19 15:14:37 +01:00
parent 495ceea73d
commit f07a4b422b
No known key found for this signature in database
GPG key ID: 1E1B1F50D84613D0
14 changed files with 361 additions and 315 deletions

View file

@ -192,6 +192,7 @@ class Crawler(AbstractModule):
# force=force, # force=force,
# general_timeout_in_sec=120) # general_timeout_in_sec=120)
# with_favicon = True,
capture_uuid = self.lacus.enqueue(url=url, capture_uuid = self.lacus.enqueue(url=url,
depth=task.get_depth(), depth=task.get_depth(),
user_agent=task.get_user_agent(), user_agent=task.get_user_agent(),
@ -274,8 +275,9 @@ class Crawler(AbstractModule):
for tag in task.get_tags(): for tag in task.get_tags():
self.domain.add_tag(tag) self.domain.add_tag(tag)
self.original_domain.add_history(epoch, root_item=self.root_item) self.original_domain.add_history(epoch, root_item=self.root_item)
crawlers.update_last_crawled_domain(self.original_domain.get_domain_type(), self.original_domain.id, epoch) # crawlers.update_last_crawled_domain(self.original_domain.get_domain_type(), self.original_domain.id, epoch)
self.domain.update_vanity_cluster()
crawlers.update_last_crawled_domain(self.domain.get_domain_type(), self.domain.id, epoch) crawlers.update_last_crawled_domain(self.domain.get_domain_type(), self.domain.id, epoch)
print('capture:', capture.uuid, 'completed') print('capture:', capture.uuid, 'completed')
print('task: ', task.uuid, 'completed') print('task: ', task.uuid, 'completed')

View file

@ -411,6 +411,10 @@ class Domain(AbstractObject):
r_crawler.sadd(f'language:domains:{self.domain_type}:{language}', self.id) r_crawler.sadd(f'language:domains:{self.domain_type}:{language}', self.id)
r_crawler.sadd(f'domain:language:{self.id}', language) r_crawler.sadd(f'domain:language:{self.id}', language)
def update_vanity_cluster(self):
if self.get_domain_type() == 'onion':
update_vanity_cluster(self.id)
############################################################################ ############################################################################
############################################################################ ############################################################################
@ -644,10 +648,71 @@ def api_search_domains_by_name(name_to_search, domain_types, meta=False, page=1)
################################################################################ ################################################################################
################################################################################ ################################################################################
#### Vanity Explorer ####
# TODO ADD ME IN OBJ CLASS
def get_domain_vanity(domain, len_vanity=4):
return domain[:len_vanity]
def get_vanity_clusters(nb_min=4):
return r_crawler.zrange('vanity:onion:4', nb_min, '+inf', byscore=True, withscores=True)
def get_vanity_domains(vanity, len_vanity=4, meta=False):
if len_vanity == 4:
domains = r_crawler.smembers(f'vanity:{int(len_vanity)}:{vanity}')
else:
domains = []
for domain in r_crawler.smembers(f'vanity:4:{vanity[:4]}'):
dom_vanity = get_domain_vanity(domain, len_vanity=len_vanity)
if vanity == dom_vanity:
domains.append(domain)
if meta:
metas = []
for domain in domains:
metas.append(Domain(domain).get_meta(options={'languages', 'screenshot', 'tags_safe'}))
return metas
else:
return domains
def get_vanity_cluster(vanity, len_vanity=4, nb_min=4):
if len_vanity == 4:
return get_vanity_clusters(nb_min=nb_min)
else:
clusters = {}
for domain in get_vanity_domains(vanity[:4], len_vanity=4):
new_vanity = get_domain_vanity(domain, len_vanity=len_vanity)
if vanity not in clusters:
clusters[new_vanity] = 0
clusters[new_vanity] += 1
to_remove = []
for new_vanity in clusters:
if clusters[new_vanity] < nb_min:
to_remove.append(new_vanity)
for new_vanity in to_remove:
del clusters[new_vanity]
return clusters
def get_vanity_nb_domains(vanity, len_vanity=4):
return r_crawler.scard(f'vanity:{int(len_vanity)}:{vanity}')
# TODO BUILD DICTIONARY
def update_vanity_cluster(domain):
vanity = get_domain_vanity(domain, len_vanity=4)
add = r_crawler.sadd(f'vanity:4:{vanity}', domain)
if add == 1:
r_crawler.zadd('vanity:onion:4', {vanity: 1})
def _rebuild_vanity_clusters():
for vanity in r_crawler.zrange('vanity:onion:4', 0, -1):
r_crawler.delete(f'vanity:4:{vanity}')
r_crawler.delete('vanity:onion:4')
for domain in get_domains_up_by_type('onion'):
update_vanity_cluster(domain)
def cluster_onion_domain_vanity(len_vanity=4): def cluster_onion_domain_vanity(len_vanity=4):
domains = {} domains = {}
occurrences = {} occurrences = {}
for domain in get_domains_up_by_type('web'): for domain in get_domains_up_by_type('onion'):
start = domain[:len_vanity] start = domain[:len_vanity]
if start not in domains: if start not in domains:
domains[start] = [] domains[start] = []
@ -659,8 +724,6 @@ def cluster_onion_domain_vanity(len_vanity=4):
res = dict(sorted(occurrences.items(), key=lambda item: item[1], reverse=True)) res = dict(sorted(occurrences.items(), key=lambda item: item[1], reverse=True))
print(json.dumps(res)) print(json.dumps(res))
################################################################################
################################################################################
if __name__ == '__main__': if __name__ == '__main__':
cluster_onion_domain_vanity(len_vanity=4) _rebuild_vanity_clusters()

View file

@ -576,6 +576,37 @@ def domains_search_date_post():
type=domain_type, down=down, up=up)) type=domain_type, down=down, up=up))
@crawler_splash.route('/domains/explorer/vanity', methods=['GET'])
@login_required
@login_analyst
def domains_explorer_vanity_clusters():
nb_min = request.args.get('min', 0)
if int(nb_min) < 0:
nb_min = 4
vanity_clusters = Domains.get_vanity_clusters(nb_min=nb_min)
return render_template("explorer_vanity_clusters.html", vanity_clusters=vanity_clusters,
length=4)
@crawler_splash.route('/domains/explorer/vanity/explore', methods=['GET'])
@login_required
@login_analyst
def domains_explorer_vanity_explore():
vanity = request.args.get('vanity')
nb_min = request.args.get('min', 0) # TODO SHOW DOMAINS OPTIONS + HARD CODED DOMAINS LIMIT FOR RENDER
length = len(vanity)
if int(nb_min) < 0:
nb_min = 4
vanity_clusters = Domains.get_vanity_cluster(vanity, len_vanity=length+1, nb_min=nb_min)
vanity_domains = Domains.get_vanity_domains(vanity, len_vanity=length, meta=True)
vanities_tree = []
for i in range(4, length):
vanities_tree.append(vanity[:i])
if length == len(vanity):
vanities_tree.append(vanity)
return render_template("explorer_vanity_domains.html", vanity_clusters=vanity_clusters,
bootstrap_label=bootstrap_label, vanity=vanity, vanities_tree=vanities_tree,
vanity_domains=vanity_domains, length=length)
##-- --## ##-- --##

View file

@ -56,7 +56,7 @@ def screenshot(filename):
abort(404) abort(404)
filename = filename.replace('/', '') filename = filename.replace('/', '')
s = Screenshot(filename) s = Screenshot(filename)
return send_from_directory(SCREENSHOT_FOLDER, s.get_rel_path(add_extension=True), as_attachment=True) return send_from_directory(SCREENSHOT_FOLDER, s.get_rel_path(add_extension=True), as_attachment=False, mimetype='image')
@objects_item.route("/object/item") @objects_item.route("/object/item")
@login_required @login_required

View file

@ -16,7 +16,7 @@
height: 2px; height: 2px;
background: #eee; background: #eee;
} }
.message_image { .object_image {
max-width: 50%; max-width: 50%;
filter: blur(5px); filter: blur(5px);
} }
@ -66,7 +66,7 @@
{% endif %} {% endif %}
{% if message['images'] %} {% if message['images'] %}
{% for message_image in message['images'] %} {% for message_image in message['images'] %}
<img class="message_image mb-1" src="{{ url_for('objects_image.image', filename=message_image)}}"> <img class="object_image mb-1" src="{{ url_for('objects_image.image', filename=message_image)}}">
{% endfor %} {% endfor %}
{% endif %} {% endif %}
{% if message['files-names'] %} {% if message['files-names'] %}

View file

@ -41,26 +41,8 @@
</div> </div>
<div class="col-12 col-xl-6"> <div class="col-12 col-xl-6">
<div class="card my-2 border-secondary" > <div class="my-3">
<div class="card-body py-2"> {% include 'objects/image/block_blur_img_slider.html' %}
<div class="row">
<div class="col-md-3 text-center">
<button class="btn btn-primary" onclick="blocks.value=0;pixelate_all();">
<i class="fas fa-eye-slash"></i>
<span class="label-icon">Hide</span>
</button>
</div>
<div class="col-md-6">
<input class="custom-range mt-2" id="blocks" type="range" min="1" max="50" value="3">
</div>
<div class="col-md-3 text-center">
<button class="btn btn-primary" onclick="blocks.value=50;pixelate_all();">
<i class="fas fa-plus-square"></i>
<span class="label-icon">Full resolution</span>
</button>
</div>
</div>
</div>
</div> </div>
</div> </div>
@ -144,85 +126,4 @@ function toggle_sidebar(){
} }
</script> </script>
<script>
// img_url
// ctx
// canevas_id
var dict_canevas_blurr_img = {}
function init_canevas_blurr_img(canevas_id, img_url){
// ctx, turn off image smoothin
dict_canevas_blurr_img[canevas_id] = {}
var canvas_container = document.getElementById(canevas_id);
var ctx = canvas_container.getContext('2d');
ctx.webkitImageSmoothingEnabled = false;
ctx.imageSmoothingEnabled = false;
dict_canevas_blurr_img[canevas_id]["ctx"] = ctx;
// img
dict_canevas_blurr_img[canevas_id]["img"] = new Image();
dict_canevas_blurr_img[canevas_id]["img"].onload = function() {pixelate_img(canevas_id);};
dict_canevas_blurr_img[canevas_id]["img"].addEventListener("error", function() {img_error(canevas_id);});
dict_canevas_blurr_img[canevas_id]["img"].src = img_url;
}
function pixelate_all(){
Object.entries(dict_canevas_blurr_img).forEach(([key, value]) => {
pixelate_img(key);
});
}
function pixelate_img(canevas_id) {
if (typeof canevas_id !== 'undefined') {
var canevas_to_blurr = document.getElementById(canevas_id);
/// use slider value
if( blocks.value == 50 ){
size = 1;
} else {
var size = (blocks.value) * 0.01;
}
canevas_to_blurr.width = dict_canevas_blurr_img[canevas_id]["img"].width;
canevas_to_blurr.height = dict_canevas_blurr_img[canevas_id]["img"].height;
/// cache scaled width and height
w = canevas_to_blurr.width * size;
h = canevas_to_blurr.height * size;
/// draw original image to the scaled size
dict_canevas_blurr_img[canevas_id]["ctx"].drawImage(dict_canevas_blurr_img[canevas_id]["img"], 0, 0, w, h);
/// pixelated
dict_canevas_blurr_img[canevas_id]["ctx"].drawImage(canevas_to_blurr, 0, 0, w, h, 0, 0, canevas_to_blurr.width, canevas_to_blurr.height);
}
}
function img_error(canevas_id) {
dict_canevas_blurr_img[canevas_id]["img"].onerror=null;
dict_canevas_blurr_img[canevas_id]["img"].src="{{ url_for('static', filename='image/AIL.png') }}";
}
blocks.addEventListener('change', pixelate_all, false);
{% for dict_domain in dict_data['list_elem'] %}
{% if dict_domain['is_tags_safe'] %}
{% if dict_domain['screenshot'] %}
var screenshot_url = "{{ url_for('objects_item.screenshot', filename="") }}{{dict_domain['screenshot']}}";
{% else %}
var screenshot_url = "{{ url_for('static', filename='image/AIL.png') }}";
{% endif %}
init_canevas_blurr_img("canvas_{{loop.index0}}", screenshot_url);
{% endif %}
{% endfor %}
</script>
</html> </html>

View file

@ -0,0 +1,94 @@
<!DOCTYPE html>
<html>
<head>
<title>Vanity Explorer - AIL</title>
<link rel="icon" href="{{ url_for('static', filename='image/ail-icon.png') }}">
<!-- Core CSS -->
<link href="{{ url_for('static', filename='css/bootstrap4.min.css') }}" rel="stylesheet">
<link href="{{ url_for('static', filename='css/font-awesome.min.css') }}" rel="stylesheet">
<link href="{{ url_for('static', filename='css/dataTables.bootstrap.min.css') }}" rel="stylesheet">
<!-- JS -->
<script src="{{ url_for('static', filename='js/jquery.js')}}"></script>
<script src="{{ url_for('static', filename='js/popper.min.js')}}"></script>
<script src="{{ url_for('static', filename='js/bootstrap4.min.js') }}"></script>
<script src="{{ url_for('static', filename='js/jquery.dataTables.min.js')}}"></script>
<script src="{{ url_for('static', filename='js/dataTables.bootstrap.min.js')}}"></script>
<style>
.card-columns {
column-count: 4;
}
</style>
</head>
<body>
{% include 'nav_bar.html' %}
<div class="container-fluid">
<div class="row">
{% include 'crawler/menu_sidebar.html' %}
<div class="col-12 col-lg-10" id="core_content">
<h1>Vanity Explorer</h1>
<table id="tableClusters" class="table">
<thead class="bg-dark text-white">
<tr>
<th>Vanity</th>
<th>NB Domains</th>
<th></th>
</tr>
</thead>
<tbody style="font-size: 15px;">
{% for row in vanity_clusters %}
<tr>
<td>
<a href="{{ url_for('crawler_splash.domains_explorer_vanity_explore') }}?vanity={{row[0]}}&length={{ length }}">{{ row[0] }}</a>
</td>
<td>{{ row[1] | int }}</td>
<td>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
</body>
<script>
$(document).ready(function(){
$('#nav_title_domains_explorer').removeClass("text-muted");
$("#nav_vanity_explorer").addClass("active");
$('#tableClusters').DataTable({
"aLengthMenu": [[5, 10, 15, -1], [5, 10, 15, "All"]],
"iDisplayLength": 10,
"order": [[ 1, "desc" ]]
});
});
function toggle_sidebar(){
if($('#nav_menu').is(':visible')){
$('#nav_menu').hide();
$('#side_menu').removeClass('border-right')
$('#side_menu').removeClass('col-lg-2')
$('#core_content').removeClass('col-lg-10')
}else{
$('#nav_menu').show();
$('#side_menu').addClass('border-right')
$('#side_menu').addClass('col-lg-2')
$('#core_content').addClass('col-lg-10')
}
}
</script>
</html>

View file

@ -0,0 +1,137 @@
<!DOCTYPE html>
<html>
<head>
<title>Vanity Explorer - AIL</title>
<link rel="icon" href="{{ url_for('static', filename='image/ail-icon.png') }}">
<!-- Core CSS -->
<link href="{{ url_for('static', filename='css/bootstrap4.min.css') }}" rel="stylesheet">
<link href="{{ url_for('static', filename='css/font-awesome.min.css') }}" rel="stylesheet">
<link href="{{ url_for('static', filename='css/dataTables.bootstrap.min.css') }}" rel="stylesheet">
<!-- JS -->
<script src="{{ url_for('static', filename='js/jquery.js')}}"></script>
<script src="{{ url_for('static', filename='js/popper.min.js')}}"></script>
<script src="{{ url_for('static', filename='js/bootstrap4.min.js') }}"></script>
<script src="{{ url_for('static', filename='js/jquery.dataTables.min.js')}}"></script>
<script src="{{ url_for('static', filename='js/dataTables.bootstrap.min.js')}}"></script>
<style>
.card-columns {
column-count: 4;
}
</style>
</head>
<body>
{% include 'nav_bar.html' %}
<div class="container-fluid">
<div class="row">
{% include 'crawler/menu_sidebar.html' %}
<div class="col-12 col-lg-10" id="core_content">
<h1>Vanity Explorer: </h1>
<div class="row">
<div class="col-12 col-lg-6">
<div class="my-2">
{% if vanities_tree | length > 1 %}
<i class="fas fa-arrow-right"></i>
{% for vanity in vanities_tree[:-1] %}
<btn class="btn btn-primary disabled">{{ vanity }}</btn> <i class="fas fa-arrow-right"></i>
{% endfor %}
<btn class="btn btn-primary disabled">{{ vanities_tree[-1] }}</btn>
{% else %}
<i class="fas fa-arrow-right"></i>
{% for vanity in vanities_tree %}
<btn class="btn btn-primary disabled">{{ vanity }}</btn>
{% endfor %}
{% endif %}
</div>
<div><b>Vanity Length:</b> {{ length }}</div>
</div>
<div class="col-12 col-xl-6">
<table id="tableClusters" class="table">
<thead class="bg-dark text-white">
<tr>
<th>Length+1 Vanities</th>
<th>NB Domains</th>
<th></th>
</tr>
</thead>
<tbody style="font-size: 15px;">
{% for row in vanity_clusters %}
<tr>
<td>
<a href="{{ url_for('crawler_splash.domains_explorer_vanity_explore') }}?vanity={{row}}&length={{ length + 1 }}">{{ row }}</a>
</td>
<td>{{ vanity_clusters[row] }}</td>
<td>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
{% if vanity_domains %}
<div class="my-3">
{% include 'objects/image/block_blur_img_slider.html' %}
</div>
<div class="card">
<div class="card-header bg-dark text-white" style="background-color:#d9edf7;font-size: 15px">
<h4>{{ vanity }} <span class="badge badge-primary">{{ vanity_domains | length }}</span></h4>
</div>
<div class="card-body">
{% with l_dict_domains=vanity_domains, bootstrap_label=bootstrap_label %}
{% include 'domains/card_img_domain.html' %}
{% endwith %}
</div>
</div>
{% endif %}
</div>
</div>
</div>
</body>
<script>
$(document).ready(function(){
$('#nav_title_domains_explorer').removeClass("text-muted");
$("#nav_vanity_explorer").addClass("active");
$('#tableClusters').DataTable({
"aLengthMenu": [[5, 10, 15, -1], [5, 10, 15, "All"]],
"iDisplayLength": 10,
"order": [[ 1, "desc" ]]
});
});
function toggle_sidebar(){
if($('#nav_menu').is(':visible')){
$('#nav_menu').hide();
$('#side_menu').removeClass('border-right')
$('#side_menu').removeClass('col-lg-2')
$('#core_content').removeClass('col-lg-10')
}else{
$('#nav_menu').show();
$('#side_menu').addClass('border-right')
$('#side_menu').addClass('col-lg-2')
$('#core_content').addClass('col-lg-10')
}
}
</script>
</html>

View file

@ -62,6 +62,12 @@
<span>Web Domain</span> <span>Web Domain</span>
</a> </a>
</li> </li>
<li class="nav-item">
<a class="nav-link" href="{{url_for('crawler_splash.domains_explorer_vanity_clusters')}}" id="nav_vanity_explorer">
<i class="fas fa-dumbbell"></i>
<span>Vanity Explorer</span>
</a>
</li>
</ul> </ul>
<h5 class="d-flex text-muted w-100" id="nav_title_cookiejar"> <h5 class="d-flex text-muted w-100" id="nav_title_cookiejar">

View file

@ -23,8 +23,8 @@
</label> </label>
</div> </div>
<div class="custom-control custom-switch"> <div class="custom-control custom-switch">
<input class="custom-control-input" type="checkbox" name="domain_regular_switch" value="True" id="domain_regular_switch" {%if not domains_types%}checked{%elif 'regular' in domains_types%}checked{%endif%}> <input class="custom-control-input" type="checkbox" name="domain_web_switch" value="True" id="domain_web_switch" {%if not domains_types%}checked{%elif 'web' in domains_types%}checked{%endif%}>
<label class="custom-control-label" for="domain_regular_switch"> <label class="custom-control-label" for="domain_web_switch">
<span class="badge badge-warning"><i class="fab fa-html5"></i> Web Domains</span> <span class="badge badge-warning"><i class="fab fa-html5"></i> Web Domains</span>
</label> </label>
</div> </div>
@ -54,7 +54,7 @@
}); });
function searchLanguages() { function searchLanguages() {
var all_domain_types = ['onion', 'regular'] // TODO: load from flask var all_domain_types = ['onion', 'web'] // TODO: load from flask
var l_domains_types = []; var l_domains_types = [];
var data = llanguages.getValue(); var data = llanguages.getValue();

View file

@ -1,3 +1,11 @@
<style>
.object_image {
max-height: 400px;
max-width: 100%;
filter: blur(5px);
}
</style>
{% for dict_domain in l_dict_domains %} {% for dict_domain in l_dict_domains %}
{% if loop.index0 % 4 == 0 %} {% if loop.index0 % 4 == 0 %}
<div class="card-deck mt-3"> <div class="card-deck mt-3">
@ -6,7 +14,7 @@
<div class="card {% if dict_domain["status"] %}border-success{% else %}border-danger{% endif %}"> <div class="card {% if dict_domain["status"] %}border-success{% else %}border-danger{% endif %}">
<div class="text-center"> <div class="text-center">
{% if dict_domain["is_tags_safe"] %} {% if dict_domain["is_tags_safe"] %}
<canvas id="canvas_{{loop.index0}}" style="max-height: 400px; max-width: 100%;"></canvas> <img class="object_image mb-1" src="{{ url_for('objects_item.screenshot', filename="") }}{{dict_domain['screenshot']}}">
{% else %} {% else %}
<span class="my-2 fa-stack fa-8x"> <span class="my-2 fa-stack fa-8x">
<i class="fas fa-stack-1x fa-image"></i> <i class="fas fa-stack-1x fa-image"></i>

View file

@ -38,27 +38,9 @@
</div> </div>
<div class="col-12 col-xl-6"> <div class="col-12 col-xl-6">
<div class="card my-2 border-secondary" > <div class="my-3">
<div class="card-body py-2"> {% include 'objects/image/block_blur_img_slider.html' %}
<div class="row"> </div>
<div class="col-md-3 text-center">
<button class="btn btn-primary" onclick="blocks.value=0;pixelate_all();">
<i class="fas fa-eye-slash"></i>
<span class="label-icon">Hide</span>
</button>
</div>
<div class="col-md-6">
<input class="custom-range mt-2" id="blocks" type="range" min="1" max="50" value="5">
</div>
<div class="col-md-3 text-center">
<button class="btn btn-primary" onclick="blocks.value=50;pixelate_all();">
<i class="fas fa-plus-square"></i>
<span class="label-icon">Full resolution</span>
</button>
</div>
</div>
</div>
</div>
</div> </div>
</div> </div>
@ -109,84 +91,4 @@ function toggle_sidebar(){
} }
</script> </script>
<script>
// img_url
// ctx
// canevas_id
var dict_canevas_blurr_img = {}
function init_canevas_blurr_img(canevas_id, img_url){
// ctx, turn off image smoothin
dict_canevas_blurr_img[canevas_id] = {}
var canvas_container = document.getElementById(canevas_id);
var ctx = canvas_container.getContext('2d');
ctx.webkitImageSmoothingEnabled = false;
ctx.imageSmoothingEnabled = false;
dict_canevas_blurr_img[canevas_id]["ctx"] = ctx;
// img
dict_canevas_blurr_img[canevas_id]["img"] = new Image();
dict_canevas_blurr_img[canevas_id]["img"].onload = function() {pixelate_img(canevas_id);};
dict_canevas_blurr_img[canevas_id]["img"].addEventListener("error", function() {img_error(canevas_id);});
dict_canevas_blurr_img[canevas_id]["img"].src = img_url;
}
function pixelate_all(){
Object.entries(dict_canevas_blurr_img).forEach(([key, value]) => {
pixelate_img(key);
});
}
function pixelate_img(canevas_id) {
if (typeof canevas_id !== 'undefined') {
var canevas_to_blurr = document.getElementById(canevas_id);
/// use slider value
if( blocks.value == 50 ){
size = 1;
} else {
var size = (blocks.value) * 0.01;
}
canevas_to_blurr.width = dict_canevas_blurr_img[canevas_id]["img"].width;
canevas_to_blurr.height = dict_canevas_blurr_img[canevas_id]["img"].height;
/// cache scaled width and height
w = canevas_to_blurr.width * size;
h = canevas_to_blurr.height * size;
/// draw original image to the scaled size
dict_canevas_blurr_img[canevas_id]["ctx"].drawImage(dict_canevas_blurr_img[canevas_id]["img"], 0, 0, w, h);
/// pixelated
dict_canevas_blurr_img[canevas_id]["ctx"].drawImage(canevas_to_blurr, 0, 0, w, h, 0, 0, canevas_to_blurr.width, canevas_to_blurr.height);
}
}
function img_error(canevas_id) {
dict_canevas_blurr_img[canevas_id]["img"].onerror=null;
dict_canevas_blurr_img[canevas_id]["img"].src="{{ url_for('static', filename='image/AIL.png') }}";
}
blocks.addEventListener('change', pixelate_all, false);
{% for dict_domain in l_dict_domains['list_elem'] %}
{% if 'screenshot' in dict_domain %}
{% if dict_domain['is_tags_safe'] %}
var screenshot_url = "{{ url_for('objects_item.screenshot', filename="") }}{{dict_domain['screenshot']}}";
{% else %}
var screenshot_url = "{{ url_for('static', filename='image/AIL.png') }}";
{% endif %}
init_canevas_blurr_img("canvas_{{loop.index0}}", screenshot_url);
{% endif %}
{% endfor %}
</script>
</html> </html>

View file

@ -37,26 +37,8 @@
{% endwith %} {% endwith %}
</div> </div>
<div class="col-12 col-xl-6"> <div class="col-12 col-xl-6">
<div class="card my-2 border-secondary" > <div class="my-3">
<div class="card-body py-2"> {% include 'objects/image/block_blur_img_slider.html' %}
<div class="row">
<div class="col-md-3 text-center">
<button class="btn btn-primary" onclick="blocks.value=0;pixelate_all();">
<i class="fas fa-eye-slash"></i>
<span class="label-icon">Hide</span>
</button>
</div>
<div class="col-md-6">
<input class="custom-range mt-2" id="blocks" type="range" min="1" max="50" value="5">
</div>
<div class="col-md-3 text-center">
<button class="btn btn-primary" onclick="blocks.value=50;pixelate_all();">
<i class="fas fa-plus-square"></i>
<span class="label-icon">Full resolution</span>
</button>
</div>
</div>
</div>
</div> </div>
</div> </div>
</div> </div>
@ -104,84 +86,4 @@ function toggle_sidebar(){
} }
</script> </script>
<script>
// img_url
// ctx
// canevas_id
var dict_canevas_blurr_img = {}
function init_canevas_blurr_img(canevas_id, img_url){
// ctx, turn off image smoothin
dict_canevas_blurr_img[canevas_id] = {}
var canvas_container = document.getElementById(canevas_id);
var ctx = canvas_container.getContext('2d');
ctx.webkitImageSmoothingEnabled = false;
ctx.imageSmoothingEnabled = false;
dict_canevas_blurr_img[canevas_id]["ctx"] = ctx;
// img
dict_canevas_blurr_img[canevas_id]["img"] = new Image();
dict_canevas_blurr_img[canevas_id]["img"].onload = function() {pixelate_img(canevas_id);};
dict_canevas_blurr_img[canevas_id]["img"].addEventListener("error", function() {img_error(canevas_id);});
dict_canevas_blurr_img[canevas_id]["img"].src = img_url;
}
function pixelate_all(){
Object.entries(dict_canevas_blurr_img).forEach(([key, value]) => {
pixelate_img(key);
});
}
function pixelate_img(canevas_id) {
if (typeof canevas_id !== 'undefined') {
var canevas_to_blurr = document.getElementById(canevas_id);
/// use slider value
if( blocks.value == 50 ){
size = 1;
} else {
var size = (blocks.value) * 0.01;
}
canevas_to_blurr.width = dict_canevas_blurr_img[canevas_id]["img"].width;
canevas_to_blurr.height = dict_canevas_blurr_img[canevas_id]["img"].height;
/// cache scaled width and height
w = canevas_to_blurr.width * size;
h = canevas_to_blurr.height * size;
/// draw original image to the scaled size
dict_canevas_blurr_img[canevas_id]["ctx"].drawImage(dict_canevas_blurr_img[canevas_id]["img"], 0, 0, w, h);
/// pixelated
dict_canevas_blurr_img[canevas_id]["ctx"].drawImage(canevas_to_blurr, 0, 0, w, h, 0, 0, canevas_to_blurr.width, canevas_to_blurr.height);
}
}
function img_error(canevas_id) {
dict_canevas_blurr_img[canevas_id]["img"].onerror=null;
dict_canevas_blurr_img[canevas_id]["img"].src="{{ url_for('static', filename='image/AIL.png') }}";
}
blocks.addEventListener('change', pixelate_all, false);
{% for dict_domain in l_dict_domains['list_elem'] %}
{% if dict_domain['is_tags_safe'] %}
{% if dict_domain['screenshot'] %}
var screenshot_url = "{{ url_for('objects_item.screenshot', filename="") }}{{dict_domain['screenshot']}}";
{% else %}
var screenshot_url = "{{ url_for('static', filename='image/AIL.png') }}";
{% endif %}
init_canevas_blurr_img("canvas_{{loop.index0}}", screenshot_url);
{% endif %}
{% endfor %}
</script>
</html> </html>

View file

@ -26,7 +26,7 @@
function blur_images(){ function blur_images(){
let blurValue = blur_slider.val(); let blurValue = blur_slider.val();
blurValue = 15 - blurValue; blurValue = 15 - blurValue;
let images = document.getElementsByClassName('message_image'); let images = document.getElementsByClassName('object_image');
for(i = 0; i < images.length; i++) { for(i = 0; i < images.length; i++) {
images[i].style.filter = "blur(" + blurValue + "px)"; images[i].style.filter = "blur(" + blurValue + "px)";
} }