fetchers-abstract-graphic-compare
dgtlmoon 2 years ago
parent 0e0bd93234
commit c0fcae0076

@ -642,20 +642,23 @@ def changedetection_app(config=None, datastore_o=None):
enabled_tabs.append('visual-selector') enabled_tabs.append('visual-selector')
enabled_tabs.append('text-filters-and-triggers') enabled_tabs.append('text-filters-and-triggers')
if watch.get('fetch_processor') == 'image':
enabled_tabs.append('visual-selector')
output = render_template("edit.html", output = render_template("edit.html",
uuid=uuid,
watch=watch,
form=form,
enabled_tabs = enabled_tabs,
has_empty_checktime=using_default_check_time,
has_default_notification_urls=True if len(datastore.data['settings']['application']['notification_urls']) else False,
using_global_webdriver_wait=default['webdriver_delay'] is None,
current_base_url=datastore.data['settings']['application']['base_url'], current_base_url=datastore.data['settings']['application']['base_url'],
emailprefix=os.getenv('NOTIFICATION_MAIL_BUTTON_PREFIX', False), emailprefix=os.getenv('NOTIFICATION_MAIL_BUTTON_PREFIX', False),
enabled_tabs = enabled_tabs,
form=form,
has_default_notification_urls=True if len(datastore.data['settings']['application']['notification_urls']) else False,
has_empty_checktime=using_default_check_time,
playwright_enabled=os.getenv('PLAYWRIGHT_DRIVER_URL', False),
settings_application=datastore.data['settings']['application'], settings_application=datastore.data['settings']['application'],
using_global_webdriver_wait=default['webdriver_delay'] is None,
uuid=uuid,
visualselector_data_is_ready=visualselector_data_is_ready, visualselector_data_is_ready=visualselector_data_is_ready,
visualselector_enabled=visualselector_enabled, visualselector_enabled=visualselector_enabled,
playwright_enabled=os.getenv('PLAYWRIGHT_DRIVER_URL', False) watch=watch,
) )
return output return output
@ -809,6 +812,8 @@ def changedetection_app(config=None, datastore_o=None):
previous_version = dates[-2] previous_version = dates[-2]
datastore.set_last_viewed(uuid, time.time())
output = render_template("diff-image.html", output = render_template("diff-image.html",
watch=watch, watch=watch,
extra_stylesheets=extra_stylesheets, extra_stylesheets=extra_stylesheets,
@ -1074,7 +1079,13 @@ def changedetection_app(config=None, datastore_o=None):
new_img = watch.history[watch.newest_history_key] new_img = watch.history[watch.newest_history_key]
prev_img = watch.history[compare_date] prev_img = watch.history[compare_date]
try:
img = image_diff.render_diff(new_img, prev_img) img = image_diff.render_diff(new_img, prev_img)
except ValueError as e:
print ("EXCEPTION: Diff image - got exception {} reverting to raw image without rendering difference".format(str(e)))
with open(new_img, 'rb') as f:
img = f.read()
resp = make_response(img) resp = make_response(img)
resp.headers['Content-Type'] = 'image/jpeg' resp.headers['Content-Type'] = 'image/jpeg'

@ -421,9 +421,9 @@ class base_html_playwright(Fetcher):
# acceptable screenshot quality here # acceptable screenshot quality here
try: try:
# Quality set to 1 because it's not used, just used as a work-around for a bug, no need to change this. # Quality set to 1 because it's not used, just used as a work-around for a bug, no need to change this.
page.screenshot(type='jpeg', clip={'x': 1.0, 'y': 1.0, 'width': 1280, 'height': 1024}, quality=1) #page.screenshot(type='jpeg', clip={'x': 1.0, 'y': 1.0, 'width': 1280, 'height': 1024}, quality=1)
# The actual screenshot # The actual screenshot
self.screenshot = page.screenshot(type='jpeg', full_page=True, quality=int(os.getenv("PLAYWRIGHT_SCREENSHOT_QUALITY", 72))) self.screenshot = page.screenshot(type='jpeg', full_page=True, quality=int(os.getenv("PLAYWRIGHT_SCREENSHOT_QUALITY", 82)))
except Exception as e: except Exception as e:
context.close() context.close()
browser.close() browser.close()

@ -89,8 +89,13 @@ class perform_site_check(fetch_processor):
if 'image' in fetcher.headers['content-type']: if 'image' in fetcher.headers['content-type']:
self.contents = fetcher.raw_content self.contents = fetcher.raw_content
else: else:
# should be element if the filter is set, no?
self.contents = fetcher.screenshot self.contents = fetcher.screenshot
# Used for visual-selector
self.xpath_data = fetcher.xpath_data
self.screenshot = fetcher.screenshot
image = Image.open(io.BytesIO(self.contents)) image = Image.open(io.BytesIO(self.contents))
# @todo different choice? # @todo different choice?

@ -33,8 +33,8 @@ def render_diff(fpath_imageA, fpath_imageB):
# bounding box on both input images to represent where the two # bounding box on both input images to represent where the two
# images differ # images differ
(x, y, w, h) = cv2.boundingRect(c) (x, y, w, h) = cv2.boundingRect(c)
cv2.rectangle(imageA, (x, y), (x + w, y + h), (0, 0, 255), 2) cv2.rectangle(imageA, (x, y), (x + w, y + h), (0, 0, 255), 1)
cv2.rectangle(imageB, (x, y), (x + w, y + h), (0, 0, 255), 2) cv2.rectangle(imageB, (x, y), (x + w, y + h), (0, 0, 255), 1)
#return cv2.imencode('.jpg', imageB)[1].tobytes() #return cv2.imencode('.jpg', imageB)[1].tobytes()
return cv2.imencode('.jpg', imageA)[1].tobytes() return cv2.imencode('.jpg', imageA)[1].tobytes()

@ -0,0 +1,149 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg
version="1.1"
id="Layer_1"
x="0px"
y="0px"
viewBox="0 0 20.745352 20.745251"
xml:space="preserve"
width="20.745352"
height="20.745251"
sodipodi:docname="picture-frame.svg"
inkscape:version="1.1.1 (1:1.1+202109281949+c3084ef5ed)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><sodipodi:namedview
id="namedview31"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
showgrid="false"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
inkscape:zoom="24.215073"
inkscape:cx="11.810825"
inkscape:cy="10.158962"
inkscape:window-width="1920"
inkscape:window-height="1056"
inkscape:window-x="1920"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="g1325" /><defs
id="defs57">
</defs>
<g
id="g22"
transform="translate(-141.68664,-143.32441)">
<g
id="g986"
transform="matrix(0.09174031,0,0,0.09174031,139.41786,139.41786)"><g
id="g1313" /><g
id="g18">
<g
id="g1325"
transform="matrix(1.0989302,0,0,1.0989302,-30.889712,-13.037446)"><g
id="g1413"><rect
x="58.112999"
y="58.112999"
style="fill:#95e1d3"
width="190.77765"
height="190.77299"
id="rect4"
rx="0"
ry="0" /><polygon
style="fill:#eaffd0"
points="117.389,248.887 183.138,135.007 248.887,248.887 "
id="polygon6" /><polygon
style="fill:#eaffd0"
points="100.26,175.887 58.113,248.887 117.389,248.887 129.898,227.221 "
id="polygon8" /><circle
style="fill:#fce38a"
cx="141.82001"
cy="119.433"
r="16.547001"
id="circle10" /><path
style="fill:#414042"
d="M 248.887,50.613 H 58.113 c -4.142,0 -7.5,3.357 -7.5,7.5 v 190.773 c 0,4.118 3.362,7.5 7.5,7.5 h 59.276 131.498 c 4.06,0 7.5,-3.304 7.5,-7.5 V 58.113 c 0,-4.142 -3.358,-7.5 -7.5,-7.5 z m -7.5,15 v 155.283 l -51.754,-89.64 c -2.886,-4.998 -10.11,-4.988 -12.99,0 l -46.745,80.965 -23.143,-40.085 c -2.886,-4.998 -10.11,-4.988 -12.99,0 l -28.151,48.76 V 65.613 Z m -141.127,125.274 20.978,36.335 -7.823,13.549 -0.356,0.616 H 71.103 Z m 30.12,50.5 6.013,-10.415 c 0.001,-0.002 0.002,-0.004 0.003,-0.006 l 46.742,-80.959 52.759,91.38 z"
id="path14" /><path
style="fill:#414042"
d="m 141.82,143.48 c 13.259,0 24.046,-10.787 24.046,-24.047 0,-13.26 -10.787,-24.047 -24.046,-24.047 -13.259,0 -24.046,10.787 -24.046,24.047 0,13.26 10.786,24.047 24.046,24.047 z m 0,-33.093 c 4.988,0 9.046,4.059 9.046,9.047 0,4.988 -4.058,9.047 -9.046,9.047 -4.988,0 -9.046,-4.059 -9.046,-9.047 -0.001,-4.989 4.057,-9.047 9.046,-9.047 z"
id="path16" /></g></g>
</g></g>
</g>
<g
id="g24"
transform="translate(-141.68664,-143.32441)">
</g>
<g
id="g26"
transform="translate(-141.68664,-143.32441)">
</g>
<g
id="g28"
transform="translate(-141.68664,-143.32441)">
</g>
<g
id="g30"
transform="translate(-141.68664,-143.32441)">
</g>
<g
id="g32"
transform="translate(-141.68664,-143.32441)">
</g>
<g
id="g34"
transform="translate(-141.68664,-143.32441)">
</g>
<g
id="g36"
transform="translate(-141.68664,-143.32441)">
</g>
<g
id="g38"
transform="translate(-141.68664,-143.32441)">
</g>
<g
id="g40"
transform="translate(-141.68664,-143.32441)">
</g>
<g
id="g42"
transform="translate(-141.68664,-143.32441)">
</g>
<g
id="g44"
transform="translate(-141.68664,-143.32441)">
</g>
<g
id="g46"
transform="translate(-141.68664,-143.32441)">
</g>
<g
id="g48"
transform="translate(-141.68664,-143.32441)">
</g>
<g
id="g50"
transform="translate(-141.68664,-143.32441)">
</g>
<g
id="g52"
transform="translate(-141.68664,-143.32441)">
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.1 KiB

@ -578,3 +578,15 @@ ul {
display: inline; display: inline;
height: 26px; height: 26px;
vertical-align: middle; } vertical-align: middle; }
#quickwatch-fetch-processor {
color: #fff;
font-size: 80%; }
#quickwatch-fetch-processor ul {
padding: 0px;
list-style-type: none; }
#quickwatch-fetch-processor ul li {
display: inline-block;
margin-right: 1em; }
#quickwatch-fetch-processor ul li label:hover {
cursor: pointer; }

@ -804,3 +804,23 @@ ul {
border-radius: 5px; border-radius: 5px;
color: #ff3300; color: #ff3300;
} }
#quickwatch-fetch-processor {
color: #fff;
font-size: 80%;
ul {
padding: 0px;
list-style-type: none;
li {
display: inline-block;
margin-right: 1em;
label {
&:hover {
cursor: pointer;
}
}
}
}
}

@ -28,9 +28,7 @@
{% if 'visual-selector' in enabled_tabs %} {% if 'visual-selector' in enabled_tabs %}
<li class="tab"><a id="visualselector-tab" href="#visualselector">Visual Filter Selector</a></li> <li class="tab"><a id="visualselector-tab" href="#visualselector">Visual Filter Selector</a></li>
{%endif%} {%endif%}
{% if 'text-filters-and-triggers' in enabled_tabs %}
<li class="tab"><a href="#filters-and-triggers">Filters &amp; Triggers</a></li> <li class="tab"><a href="#filters-and-triggers">Filters &amp; Triggers</a></li>
{%endif%}
<li class="tab"><a href="#notifications">Notifications</a></li> <li class="tab"><a href="#notifications">Notifications</a></li>
</ul> </ul>
</div> </div>
@ -158,6 +156,7 @@ User-Agent: wonderbra 1.0") }}
</div> </div>
<div class="tab-pane-inner" id="filters-and-triggers"> <div class="tab-pane-inner" id="filters-and-triggers">
{% if 'text-filters-and-triggers' in enabled_tabs %}
<div class="pure-control-group"> <div class="pure-control-group">
<strong>Pro-tips:</strong><br/> <strong>Pro-tips:</strong><br/>
<ul> <ul>
@ -169,12 +168,14 @@ User-Agent: wonderbra 1.0") }}
</li> </li>
</ul> </ul>
</div> </div>
<fieldset> <fieldset>
<div class="pure-control-group"> <div class="pure-control-group">
{{ render_checkbox_field(form.check_unique_lines) }} {{ render_checkbox_field(form.check_unique_lines) }}
<span class="pure-form-message-inline">Good for websites that just move the content around, and you want to know when NEW content is added, compares new lines against all history for this watch.</span> <span class="pure-form-message-inline">Good for websites that just move the content around, and you want to know when NEW content is added, compares new lines against all history for this watch.</span>
</div> </div>
</fieldset> </fieldset>
{% endif %}
<div class="pure-control-group"> <div class="pure-control-group">
{% set field = render_field(form.css_filter, {% set field = render_field(form.css_filter,
placeholder=".class-name or #some-id, or other CSS selector rule.", placeholder=".class-name or #some-id, or other CSS selector rule.",
@ -201,6 +202,9 @@ User-Agent: wonderbra 1.0") }}
href="https://github.com/dgtlmoon/changedetection.io/wiki/CSS-Selector-help">here for more CSS selector help</a>.<br/> href="https://github.com/dgtlmoon/changedetection.io/wiki/CSS-Selector-help">here for more CSS selector help</a>.<br/>
</span> </span>
</div> </div>
{% if 'text-filters-and-triggers' in enabled_tabs %}
<div class="pure-control-group"> <div class="pure-control-group">
{{ render_field(form.subtractive_selectors, rows=5, placeholder="header {{ render_field(form.subtractive_selectors, rows=5, placeholder="header
footer footer
@ -276,6 +280,8 @@ Unavailable") }}
</span> </span>
</div> </div>
</fieldset> </fieldset>
{% endif %}
</div> </div>
<div class="tab-pane-inner visual-selector-ui" id="visualselector"> <div class="tab-pane-inner visual-selector-ui" id="visualselector">

@ -15,14 +15,18 @@
<div> <div>
{{ render_simple_field(form.url, placeholder="https://...", required=true) }} {{ render_simple_field(form.url, placeholder="https://...", required=true) }}
{{ render_simple_field(form.tag, value=active_tag if active_tag else '', placeholder="watch group") }} {{ render_simple_field(form.tag, value=active_tag if active_tag else '', placeholder="watch group") }}
<span>
{{ render_simple_field(form.watch_submit_button, title="Watch this URL!" ) }}
{{ render_simple_field(form.edit_and_watch_submit_button, title="Edit first then Watch") }}
</span>
{% if webdriver_enabled %} {% if webdriver_enabled %}
<br/> <div id="quickwatch-fetch-processor">
{{ render_field(form.fetch_processor) }} {{ render_field(form.fetch_processor) }}
</div>
{% endif %} {% endif %}
</div> </div>
<div> <div>
{{ render_simple_field(form.watch_submit_button, title="Watch this URL!" ) }}
{{ render_simple_field(form.edit_and_watch_submit_button, title="Edit first then Watch") }}
</div> </div>
</div> </div>
</fieldset> </fieldset>
@ -95,7 +99,7 @@
<a href="{{url_for('form_share_put_watch', uuid=watch.uuid)}}"><img style="height: 1em;display:inline-block;" src="{{url_for('static_content', group='images', filename='spread.svg')}}" /></a> <a href="{{url_for('form_share_put_watch', uuid=watch.uuid)}}"><img style="height: 1em;display:inline-block;" src="{{url_for('static_content', group='images', filename='spread.svg')}}" /></a>
{%if watch.fetch_backend == "html_webdriver" %}<img style="height: 1em; display:inline-block;" src="{{url_for('static_content', group='images', filename='Google-Chrome-icon.png')}}" />{% endif %} {%if watch.fetch_backend == "html_webdriver" %}<img style="height: 1em; display:inline-block;" src="{{url_for('static_content', group='images', filename='Google-Chrome-icon.png')}}" />{% endif %}
{%if watch.fetch_processor == "image" %}<img style="height: 1em; display:inline-block;" src="{{url_for('static_content', group='images', filename='picture-frame.svg')}}" />{% endif %}
{% if watch.last_error is defined and watch.last_error != False %} {% if watch.last_error is defined and watch.last_error != False %}
<div class="fetch-error">{{ watch.last_error }}</div> <div class="fetch-error">{{ watch.last_error }}</div>
{% endif %} {% endif %}

Loading…
Cancel
Save