webcheck-strings 1.59__tar.gz → 1.601__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {webcheck_strings-1.59 → webcheck_strings-1.601}/PKG-INFO +4 -5
- {webcheck_strings-1.59 → webcheck_strings-1.601}/setup.py +3 -4
- {webcheck_strings-1.59 → webcheck_strings-1.601}/webcheck/__init__.py +23 -17
- {webcheck_strings-1.59 → webcheck_strings-1.601}/webcheck_strings.egg-info/PKG-INFO +4 -5
- {webcheck_strings-1.59 → webcheck_strings-1.601}/LICENSE +0 -0
- {webcheck_strings-1.59 → webcheck_strings-1.601}/setup.cfg +0 -0
- {webcheck_strings-1.59 → webcheck_strings-1.601}/webcheck/__main__.py +0 -0
- {webcheck_strings-1.59 → webcheck_strings-1.601}/webcheck_strings.egg-info/SOURCES.txt +0 -0
- {webcheck_strings-1.59 → webcheck_strings-1.601}/webcheck_strings.egg-info/dependency_links.txt +0 -0
- {webcheck_strings-1.59 → webcheck_strings-1.601}/webcheck_strings.egg-info/entry_points.txt +0 -0
- {webcheck_strings-1.59 → webcheck_strings-1.601}/webcheck_strings.egg-info/top_level.txt +0 -0
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: webcheck_strings
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.601
|
|
4
4
|
Summary: Monitor text strings on websites
|
|
5
5
|
Home-page: http://ssb22.user.srcf.net/setup/webcheck.html
|
|
6
6
|
Author: Silas S. Brown
|
|
7
7
|
Author-email: ssb22@cam.ac.uk
|
|
8
8
|
License: Apache 2
|
|
9
|
-
Platform:
|
|
9
|
+
Platform: any
|
|
10
10
|
Classifier: Programming Language :: Python :: 2
|
|
11
11
|
Classifier: Programming Language :: Python :: 3
|
|
12
12
|
Classifier: License :: OSI Approved :: Apache Software License
|
|
@@ -20,8 +20,7 @@ WebCheck
|
|
|
20
20
|
|
|
21
21
|
From http://ssb22.user.srcf.net/setup/webcheck.html
|
|
22
22
|
|
|
23
|
-
|
|
24
|
-
It is a program to check Web pages for changes to specific phrases of text. I currently use it to:
|
|
23
|
+
WebCheck is a Python program (compatible with both Python 2 and Python 3) to check Web pages for changes to specific phrases (strings) of text. I currently use it to:
|
|
25
24
|
|
|
26
25
|
* check that external links from my website still lead to the information that was there when I added them (I might need to update my links otherwise), and check whether or not I need to warn Lynx users about misguided blocking,
|
|
27
26
|
* check the websites of companies, organisations or governments for changes to a specific rule to which I'd be interested in changes (for example because it applies to myself or someone I know, or because I've commented on it somewhere and my comment might need updating),
|
|
@@ -89,7 +88,7 @@ If the site lists new items but does not support RSS, you can also *extract* ite
|
|
|
89
88
|
|
|
90
89
|
Besides checking `http://`, `https://` and `gemini://` URLs, you can check for:
|
|
91
90
|
|
|
92
|
-
* DNS changes (useful if you’re maintaining a hosts file somewhere due to unreliable DNS or an awkward proxy situation): URLs starting `dns://` will return a list of all current IPs, each enclosed in parentheses. So for example to be alerted if `93.184.
|
|
91
|
+
* DNS changes (useful if you’re maintaining a hosts file somewhere due to unreliable DNS or an awkward proxy situation): URLs starting `dns://` will return a list of all current IPs, each enclosed in parentheses. So for example to be alerted if `93.184.215.14` ceases to be one of the IP addresses of `example.com`, use `dns://example.com (93.184.215.14)`
|
|
93
92
|
* Server reachability: if a server has been unreachable for a long time and you want to be alerted if it ever becomes reachable again, you can place `up://` before the URL (e.g. `up://http://www.example.com`) which will return `yes` or `no` and not report an error if the server is not reachable.
|
|
94
93
|
* Misguided blocking of the Lynx browser. Prepend `blocks-lynx://` to a URL to have Webcheck try to fetch it with a Lynx user agent and return `yes` if it gets an error or timeout only with that agent, or `no` otherwise, so you can, at least in a `noscript` tag, warn your visitors that the server to which you link has accidentally started discriminating against blind and other users of the text-only Lynx browser due to misguided security settings—some “example” security configurations of web servers incorrectly assume Lynx implies automation and block it, and staff have been known to copy such examples without review or without realising what blocking Lynx implies.
|
|
95
94
|
* Items in the HTTP HEAD response: prepend `head://` to a URL. This might be useful for checking `Last-Modified` to see if a large download has changed, like `wget -N` but without needing to keep a copy of the file on the machine where your WebCheck runs.
|
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
from setuptools import setup, find_packages;setup(name='webcheck_strings',version='1.
|
|
1
|
+
from setuptools import setup, find_packages;setup(name='webcheck_strings',version='1.601',entry_points={'console_scripts':['webcheck=webcheck.__init__:main']},license='Apache 2',platforms='any',url='http://ssb22.user.srcf.net/setup/webcheck.html',author='Silas S. Brown',author_email='ssb22@cam.ac.uk',description='Monitor text strings on websites',long_description=r'''WebCheck
|
|
2
2
|
========
|
|
3
3
|
|
|
4
4
|
From http://ssb22.user.srcf.net/setup/webcheck.html
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
It is a program to check Web pages for changes to specific phrases of text. I currently use it to:
|
|
6
|
+
WebCheck is a Python program (compatible with both Python 2 and Python 3) to check Web pages for changes to specific phrases (strings) of text. I currently use it to:
|
|
8
7
|
|
|
9
8
|
* check that external links from my website still lead to the information that was there when I added them (I might need to update my links otherwise), and check whether or not I need to warn Lynx users about misguided blocking,
|
|
10
9
|
* check the websites of companies, organisations or governments for changes to a specific rule to which I'd be interested in changes (for example because it applies to myself or someone I know, or because I've commented on it somewhere and my comment might need updating),
|
|
@@ -72,7 +71,7 @@ If the site lists new items but does not support RSS, you can also *extract* ite
|
|
|
72
71
|
|
|
73
72
|
Besides checking `http://`, `https://` and `gemini://` URLs, you can check for:
|
|
74
73
|
|
|
75
|
-
* DNS changes (useful if you’re maintaining a hosts file somewhere due to unreliable DNS or an awkward proxy situation): URLs starting `dns://` will return a list of all current IPs, each enclosed in parentheses. So for example to be alerted if `93.184.
|
|
74
|
+
* DNS changes (useful if you’re maintaining a hosts file somewhere due to unreliable DNS or an awkward proxy situation): URLs starting `dns://` will return a list of all current IPs, each enclosed in parentheses. So for example to be alerted if `93.184.215.14` ceases to be one of the IP addresses of `example.com`, use `dns://example.com (93.184.215.14)`
|
|
76
75
|
* Server reachability: if a server has been unreachable for a long time and you want to be alerted if it ever becomes reachable again, you can place `up://` before the URL (e.g. `up://http://www.example.com`) which will return `yes` or `no` and not report an error if the server is not reachable.
|
|
77
76
|
* Misguided blocking of the Lynx browser. Prepend `blocks-lynx://` to a URL to have Webcheck try to fetch it with a Lynx user agent and return `yes` if it gets an error or timeout only with that agent, or `no` otherwise, so you can, at least in a `noscript` tag, warn your visitors that the server to which you link has accidentally started discriminating against blind and other users of the text-only Lynx browser due to misguided security settings—some “example” security configurations of web servers incorrectly assume Lynx implies automation and block it, and staff have been known to copy such examples without review or without realising what blocking Lynx implies.
|
|
78
77
|
* Items in the HTTP HEAD response: prepend `head://` to a URL. This might be useful for checking `Last-Modified` to see if a large download has changed, like `wget -N` but without needing to keep a copy of the file on the machine where your WebCheck runs.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env python
|
|
2
2
|
# (compatible with both Python 2 and Python 3)
|
|
3
3
|
|
|
4
|
-
# webcheck.py v1.
|
|
4
|
+
# webcheck.py v1.601 (c) 2014-24 Silas S. Brown.
|
|
5
5
|
# See webcheck.html for description and usage instructions
|
|
6
6
|
|
|
7
7
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
@@ -29,7 +29,6 @@
|
|
|
29
29
|
# and in China: https://gitee.com/ssb22/web-imap-etc
|
|
30
30
|
|
|
31
31
|
max_threads = 10
|
|
32
|
-
delay = 80 # seconds between fetches on same domain-set
|
|
33
32
|
keep_etags = False # if True, will also keep any ETag headers as well as Last-Modified
|
|
34
33
|
verify_SSL_certificates = False # webcheck's non-Webdriver URLs are for monitoring public services and there's not a lot of point in SSL authentication; failures due to server/client certificate misconfigurations are more trouble than they're worth
|
|
35
34
|
|
|
@@ -104,7 +103,7 @@ def read_input():
|
|
|
104
103
|
days = 0 ; extraHeaders = []
|
|
105
104
|
url = mainDomain = None
|
|
106
105
|
lines = read_input_file()
|
|
107
|
-
lastList = None
|
|
106
|
+
lastList = None # refs a list within ret, of [(days,text,elseLogic)]
|
|
108
107
|
while lines:
|
|
109
108
|
line = line_withComment = " ".join(lines.pop().split())
|
|
110
109
|
if " #" in line: line = line[:line.index(" #")].strip()
|
|
@@ -168,7 +167,7 @@ def read_input():
|
|
|
168
167
|
if isElse:
|
|
169
168
|
assert lastList, "else without suitable rule before it"
|
|
170
169
|
lastList[-1] = lastList[-1][:2] + ((url,[(0,text,None)]),) # must be days=0 because don't want to re-check the days count when just retrieved and failed something possibly on same URL ('else:' can be used for simple retrying)
|
|
171
|
-
lastList = lastList[-1][2][1] # so 'else' can be used as 'else if'
|
|
170
|
+
lastList = lastList[-1][2][1] # ref the above list (the one after url), so 'else' can be used as 'else if' and next iteration extends it
|
|
172
171
|
else:
|
|
173
172
|
lastList = ret.setdefault({
|
|
174
173
|
# domains to treat as equivalent for rate reduce
|
|
@@ -237,7 +236,8 @@ def main():
|
|
|
237
236
|
|
|
238
237
|
# 1 job per domain:
|
|
239
238
|
global jobs ; jobs = Queue.Queue()
|
|
240
|
-
for
|
|
239
|
+
for mainDomain,jobItems in read_input().items():
|
|
240
|
+
jobs.put((mainDomain,jobItems))
|
|
241
241
|
|
|
242
242
|
global previous_timestamps
|
|
243
243
|
try: previous_timestamps = pickle.Unpickler(open(".webcheck-last","rb")).load()
|
|
@@ -268,19 +268,24 @@ default_ua = 'Mozilla/5.0 or whatever you like (actually Webcheck)'
|
|
|
268
268
|
# people to hide their tools from webmasters unnecessarily.
|
|
269
269
|
|
|
270
270
|
class Delayer:
|
|
271
|
-
def __init__(self):
|
|
271
|
+
def __init__(self,mainDomain):
|
|
272
|
+
self.last_fetch_finished = 0
|
|
273
|
+
if mainDomain=="stackoverflow.com":
|
|
274
|
+
# (or other Stack Exchange sites)
|
|
275
|
+
self.delay = 80 # seconds between fetches to these sites
|
|
276
|
+
else: self.delay = 3 # (want small if checking many pages and the server doesn't mind, but still non-0)
|
|
272
277
|
def wait(self):
|
|
273
|
-
time.sleep(max(0,self.last_fetch_finished+delay-time.time()))
|
|
278
|
+
time.sleep(max(0,self.last_fetch_finished+self.delay-time.time()))
|
|
274
279
|
if sys.stderr.isatty(): sys.stderr.write('.'),sys.stderr.flush()
|
|
275
280
|
def done(self): self.last_fetch_finished = time.time()
|
|
276
281
|
|
|
277
282
|
def worker_thread(*args):
|
|
278
283
|
opener = [None]
|
|
279
284
|
while True:
|
|
280
|
-
try: job = jobs.get(False)
|
|
285
|
+
try: mainDomain,job = jobs.get(False)
|
|
281
286
|
except: return # no more jobs left
|
|
282
287
|
try:
|
|
283
|
-
delayer = Delayer()
|
|
288
|
+
delayer = Delayer(mainDomain)
|
|
284
289
|
items = sorted(job.items()) # sorted will group http and https together
|
|
285
290
|
items.reverse()
|
|
286
291
|
while items:
|
|
@@ -306,6 +311,7 @@ def worker_thread(*args):
|
|
|
306
311
|
jobs.task_done()
|
|
307
312
|
class CDNBackoff(Exception): pass
|
|
308
313
|
|
|
314
|
+
import threading ; lock = threading.Lock() # webcheck-debug
|
|
309
315
|
def doJob(opener,delayer,url,checklist,extraHeaders):
|
|
310
316
|
failRet = [c[2] for c in checklist if c[2]]
|
|
311
317
|
delayer.wait()
|
|
@@ -413,13 +419,13 @@ def doJob(opener,delayer,url,checklist,extraHeaders):
|
|
|
413
419
|
out=check(t[1:],content,"Source of "+url,"")
|
|
414
420
|
elif not t or t.startswith('#'):
|
|
415
421
|
parseRSS(url,content,t.replace('#','',1).strip())
|
|
416
|
-
out = None
|
|
422
|
+
out = None # (no else: after real RSS, but you can do else: for no extracted items: that goes through check() above)
|
|
417
423
|
else:
|
|
418
424
|
if textContent==None:
|
|
419
425
|
textContent,errmsg=htmlStrings(content)
|
|
420
426
|
out=check(t,textContent,url,errmsg)
|
|
421
|
-
if out:
|
|
422
|
-
if item[2]: toRet.append(item[2])
|
|
427
|
+
if out: # something to alert, unless else:
|
|
428
|
+
if item[2]: toRet.append(item[2]) # else:
|
|
423
429
|
else: sys.stdout.write(out) # don't use 'print' or may have problems with threads
|
|
424
430
|
return toRet
|
|
425
431
|
|
|
@@ -502,7 +508,7 @@ def run_webdriver_inner(actionList,browser):
|
|
|
502
508
|
# wait for "string" to appear in the source
|
|
503
509
|
tries = 30
|
|
504
510
|
while tries and not myFind(a[1:-1],getSrc()):
|
|
505
|
-
time.sleep(
|
|
511
|
+
time.sleep(2) ; tries -= 1
|
|
506
512
|
if not tries:
|
|
507
513
|
try: current_url = browser.current_url
|
|
508
514
|
except: current_url = "(unable to obtain)"
|
|
@@ -586,7 +592,7 @@ def run_webdriver_inner(actionList,browser):
|
|
|
586
592
|
elif re.match("[0-9]+$",a): time.sleep(int(a))
|
|
587
593
|
else: sys.stdout.write("Ignoring webdriver unknown action "+repr(a)+'\n')
|
|
588
594
|
if sys.stderr.isatty(): sys.stderr.write(':'),sys.stderr.flush() # webdriver's '.'
|
|
589
|
-
time.sleep(
|
|
595
|
+
time.sleep(2)
|
|
590
596
|
snippets.append(getSrc())
|
|
591
597
|
return B('\n').join(snippets)
|
|
592
598
|
|
|
@@ -708,7 +714,7 @@ def check(text,content,url,errmsg):
|
|
|
708
714
|
if comment: comment="\n "+paren(comment)
|
|
709
715
|
text = text.strip()
|
|
710
716
|
assert text # or should have gone to parseRSS instead
|
|
711
|
-
if text.startswith('{') and text.endswith('}') and '...' in text: extract(url,content,text[1:-1].split('...'),orig_comment)
|
|
717
|
+
if text.startswith('{') and text.endswith('}') and '...' in text: return extract(url,content,text[1:-1].split('...'),orig_comment)
|
|
712
718
|
elif text.startswith("!"): # 'not', so alert if DOES contain
|
|
713
719
|
if len(text)==1: return # TODO: print error?
|
|
714
720
|
if myFind(text[1:],content):
|
|
@@ -814,8 +820,8 @@ def extract(url,content,startEndMarkers,comment):
|
|
|
814
820
|
c = content[i+len(start):j].decode('utf-8').strip()
|
|
815
821
|
if c: items.append(('Auto-extracted text:','',c,"")) # NB the 'title' field must not be empty (unless we relocate that logic to parseRSS instead of handleRSS)
|
|
816
822
|
i = j+len(end)
|
|
817
|
-
if not items:
|
|
818
|
-
handleRSS(url,items,comment,"extracted")
|
|
823
|
+
if not items: return ("No items were extracted from "+url+" via "+S(start)+"..."+S(end)+" (check that site changes haven't invalidated this extraction rule)")
|
|
824
|
+
else: handleRSS(url,items,comment,"extracted")
|
|
819
825
|
|
|
820
826
|
def myFind(text,content):
|
|
821
827
|
text,content = B(text),B(content)
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: webcheck-strings
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.601
|
|
4
4
|
Summary: Monitor text strings on websites
|
|
5
5
|
Home-page: http://ssb22.user.srcf.net/setup/webcheck.html
|
|
6
6
|
Author: Silas S. Brown
|
|
7
7
|
Author-email: ssb22@cam.ac.uk
|
|
8
8
|
License: Apache 2
|
|
9
|
-
Platform:
|
|
9
|
+
Platform: any
|
|
10
10
|
Classifier: Programming Language :: Python :: 2
|
|
11
11
|
Classifier: Programming Language :: Python :: 3
|
|
12
12
|
Classifier: License :: OSI Approved :: Apache Software License
|
|
@@ -20,8 +20,7 @@ WebCheck
|
|
|
20
20
|
|
|
21
21
|
From http://ssb22.user.srcf.net/setup/webcheck.html
|
|
22
22
|
|
|
23
|
-
|
|
24
|
-
It is a program to check Web pages for changes to specific phrases of text. I currently use it to:
|
|
23
|
+
WebCheck is a Python program (compatible with both Python 2 and Python 3) to check Web pages for changes to specific phrases (strings) of text. I currently use it to:
|
|
25
24
|
|
|
26
25
|
* check that external links from my website still lead to the information that was there when I added them (I might need to update my links otherwise), and check whether or not I need to warn Lynx users about misguided blocking,
|
|
27
26
|
* check the websites of companies, organisations or governments for changes to a specific rule to which I'd be interested in changes (for example because it applies to myself or someone I know, or because I've commented on it somewhere and my comment might need updating),
|
|
@@ -89,7 +88,7 @@ If the site lists new items but does not support RSS, you can also *extract* ite
|
|
|
89
88
|
|
|
90
89
|
Besides checking `http://`, `https://` and `gemini://` URLs, you can check for:
|
|
91
90
|
|
|
92
|
-
* DNS changes (useful if you’re maintaining a hosts file somewhere due to unreliable DNS or an awkward proxy situation): URLs starting `dns://` will return a list of all current IPs, each enclosed in parentheses. So for example to be alerted if `93.184.
|
|
91
|
+
* DNS changes (useful if you’re maintaining a hosts file somewhere due to unreliable DNS or an awkward proxy situation): URLs starting `dns://` will return a list of all current IPs, each enclosed in parentheses. So for example to be alerted if `93.184.215.14` ceases to be one of the IP addresses of `example.com`, use `dns://example.com (93.184.215.14)`
|
|
93
92
|
* Server reachability: if a server has been unreachable for a long time and you want to be alerted if it ever becomes reachable again, you can place `up://` before the URL (e.g. `up://http://www.example.com`) which will return `yes` or `no` and not report an error if the server is not reachable.
|
|
94
93
|
* Misguided blocking of the Lynx browser. Prepend `blocks-lynx://` to a URL to have Webcheck try to fetch it with a Lynx user agent and return `yes` if it gets an error or timeout only with that agent, or `no` otherwise, so you can, at least in a `noscript` tag, warn your visitors that the server to which you link has accidentally started discriminating against blind and other users of the text-only Lynx browser due to misguided security settings—some “example” security configurations of web servers incorrectly assume Lynx implies automation and block it, and staff have been known to copy such examples without review or without realising what blocking Lynx implies.
|
|
95
94
|
* Items in the HTTP HEAD response: prepend `head://` to a URL. This might be useful for checking `Last-Modified` to see if a large download has changed, like `wget -N` but without needing to keep a copy of the file on the machine where your WebCheck runs.
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{webcheck_strings-1.59 → webcheck_strings-1.601}/webcheck_strings.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|