Skip to content

Commit eb4ecd4

Browse files
committed
add site status
1 parent eca6ef0 commit eb4ecd4

File tree

4 files changed

+92
-22
lines changed

4 files changed

+92
-22
lines changed

build.py

+68-15
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import geoip2.database
1616
import urllib.request
1717
import whois
18+
import check
1819

1920
from xml.etree import ElementTree
2021

@@ -121,17 +122,24 @@ def sites(limit=None) -> [[str, str, str]]:
121122
def build_isps_data(limit=None):
122123
isps = collections.defaultdict(lambda: [])
123124

124-
for site, classification, _, _ in sites(limit=limit):
125+
for site, classification, _, page_string in sites(limit=limit):
125126
isp = site_isp(site)
126127
if isp is None:
127128
continue
128129

129130
rank = site_rank(site)
130131

132+
hate_site_response = HateSiteLoader(domain=site).load()
133+
is_site_up = isinstance(
134+
HateSiteResponseAnalyzer(response=hate_site_response, page_string=page_string).analyze(),
135+
HateSiteResponseSiteUp
136+
)
137+
print(f"site up: {is_site_up}")
138+
131139
if classification != 'splc':
132140
classification = None
133141

134-
isps[isp].append([mask_site(site), rank_to_color(rank), classification])
142+
isps[isp].append([mask_site(site), is_site_up, classification])
135143

136144
return sorted(isps.items(), key=lambda x: len(x[1]), reverse=True)
137145

@@ -143,23 +151,68 @@ def mask_site(site: str) -> str:
143151
return f"{site[0]}{asterisks}.{domain}"
144152

145153

146-
def rank_to_color(rank: typing.Optional[int]) -> str:
147-
if rank and rank < 10_000:
148-
return '#fff600'
149-
elif rank and rank < 100_000:
150-
return '#d7d45d'
151-
elif rank and rank < 1_000_000:
152-
return '#c9c77f'
153-
elif rank and rank < 10_000_000:
154-
return '#bcbc9d'
155-
else:
156-
return '#b3b3b3'
157-
158-
159154
def todays_date() -> str:
160155
return datetime.datetime.now().strftime("%B %d, %Y")
161156

162157

158+
CHROME_USER_AGENT = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.75 Safari/537.36'
159+
REQUEST_HEADERS = {'User-Agent': CHROME_USER_AGENT}
160+
161+
162+
class HateSiteErrorResponse(typing.NamedTuple):
163+
reason: str
164+
status_code: typing.Optional[int]
165+
166+
167+
class HateSiteResponse(typing.NamedTuple):
168+
body: bytes
169+
status_code: int
170+
171+
172+
class HateSiteLoader(typing.NamedTuple):
173+
domain: str
174+
175+
def load(self) -> typing.Union[HateSiteResponse, HateSiteErrorResponse]:
176+
url = 'http://' + self.domain
177+
request = urllib.request.Request(url, headers=REQUEST_HEADERS)
178+
try:
179+
response = urllib.request.urlopen(request)
180+
except urllib.error.HTTPError as error:
181+
return HateSiteErrorResponse(reason=str(error.reason), status_code=error.code)
182+
except urllib.error.URLError as error:
183+
return HateSiteErrorResponse(reason=str(error.reason), status_code=None)
184+
return HateSiteResponse(body=response.read(), status_code=response.status)
185+
186+
187+
class HateSiteResponseSiteUp:
188+
pass
189+
190+
191+
class HateSiteResponsePageStringNotFound:
192+
pass
193+
194+
195+
class HateSiteReponseSiteDown(typing.NamedTuple):
196+
status_code: typing.Optional[int]
197+
reason: str
198+
199+
200+
class HateSiteResponseAnalyzer(typing.NamedTuple):
201+
response: typing.Union[HateSiteResponse, HateSiteErrorResponse]
202+
page_string: str
203+
204+
def analyze(self) -> typing.Union[HateSiteResponseSiteUp, HateSiteResponsePageStringNotFound, HateSiteReponseSiteDown]:
205+
if isinstance(self.response, HateSiteResponse):
206+
if self.page_string.encode() in self.response.body:
207+
return HateSiteResponseSiteUp()
208+
else:
209+
return HateSiteResponsePageStringNotFound()
210+
elif self.response.status_code:
211+
return HateSiteResponseSiteDown(status_code=self.response.status_code, reason=self.response.reason)
212+
else:
213+
return HateSiteResponseSiteDown(status_code=None, reason=self.response.reason)
214+
215+
163216
def render(limit=None):
164217
env = jinja2.Environment(
165218
loader=jinja2.FileSystemLoader('templates'),

hate-sites.csv

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
Site,Classification,Reason
2-
americanidentitymovement.com,splc,
1+
Site,Classification,Reason,Page string
2+
americanidentitymovement.com,splc,,

templates/base.html.j2

+8-1
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,6 @@
9797
9898
a {
9999
color: var(--color-complement-1);
100-
text-decoration: none;
101100
}
102101
103102
.p-1 {
@@ -141,6 +140,14 @@
141140
overflow: hidden;
142141
text-overflow: ellipsis;
143142
}
143+
144+
.site-up {
145+
color: var(--color-secondary-2-1);
146+
}
147+
148+
.not-available {
149+
color: var(--color-primary-1);
150+
}
144151
</style>
145152
</head>
146153
<body class="bg-dark white p-1">

templates/index.html.j2

+14-4
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,31 @@
33
{% block content %}
44
{% for asn, sites in isps_data %}
55
<div class="pure-u-1">
6-
<h2 class="truncate">{{ asn.name }}</h2>{# fixme asn number #}
6+
<h2 class="truncate m-y-0-3">{{ asn.name }}</h2>
7+
{# <div><a href="{{ asn.number }}">asn</a></div> #}
78
</div>
89

910
<div class="pure-g">
10-
{% for site_name, site_color, site_classification in sites %}
11+
{% for site_name, is_site_up, site_classification in sites %}
1112
<div class="pure-u-1 pure-u-sm-1-2 pure-u-md-1-4 pure-u-lg-1-5">
1213
<div class="bg-less-dark p-1 m-br-1">
1314
<h3 class="truncate m-t-0">{{ site_name }}</h3>
14-
{# <div class="truncate">status: UP</div> #}{# fime #}
15+
16+
<div class="truncate">
17+
site status:
18+
{% if is_site_up %}
19+
<span class="site-up">up</span>
20+
{% else %}
21+
<span class="not-available">n/a</span>
22+
{% endif %}
23+
</div>{# fime #}
24+
1525
<div class="truncate">
1626
type:
1727
{% if site_classification %}
1828
<a href="faqs.html#classify" class="dark-grey">{{ site_classification }}</a>
1929
{% else %}
20-
N/A
30+
<span class="not-available">n/a</span>
2131
{% endif %}
2232
</div>
2333
</div>

0 commit comments

Comments
 (0)