Skip to content

Commit

Permalink
Detect and inform to user if the website is down
Browse files Browse the repository at this point in the history
This will detect and inform to user if website is down.
It detects the status by checking if constant username
which is probably taken forever is available.

Closes manu-chroma#66
  • Loading branch information
seeeturtle authored and manu-chroma committed Jan 10, 2018
1 parent dbfad98 commit c29956f
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 8 deletions.
4 changes: 3 additions & 1 deletion templates/status.html
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,9 @@
})
.then((result) => {
var res = result;
if (!res['possible'])
if (!res['usable'])
$("#" + site)[0].innerHTML = 'Website Down';
else if (!res['possible'])
$("#" + site)[0].innerHTML = 'Impossible';
else if (res['status'] == '404' || res['status'] == '301')
$("#" + site)[0].innerHTML = 'Available';
Expand Down
2 changes: 2 additions & 0 deletions tests/test_username_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ def get_response(app, website, user):
def get_expected_response(website, user, status):
return {
'possible': True,
'usable': True,
'status': status,
'url': username_api.get_profile_url(website, user),
'avatar': username_api.get_avatar(website, user) if status == 200
Expand Down Expand Up @@ -157,5 +158,6 @@ def test_format_checking(self, website, username):
url = username_api.get_profile_url(website, username)
assert {
'possible': False,
'usable': True,
'url': url
} == json_resp
66 changes: 59 additions & 7 deletions username_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,16 @@
from bs4 import BeautifulSoup
from flask import Flask, jsonify
from flask.ext.cors import CORS, cross_origin
from werkzeug.contrib.cache import SimpleCache

app = Flask(__name__)
cors = CORS(app)
app.config['CORS_HEADERS'] = 'Content-Type'

patterns = yaml.load(open('websites.yml'))

cache = SimpleCache()


def get_profile_url(website, username):
return patterns['urls'].get(website, 'https://{w}.com/{u}').format(
Expand Down Expand Up @@ -63,36 +66,58 @@ def get_avatar(website, username):
return result


def get_status_code(website, username):
url = get_profile_url(website, username)

if website in patterns['content_verification']:
res = r.get(url)
phrase = patterns['content_verification'][website].format(u=username)
if bytes(phrase, encoding='utf-8') in res.content:
return 200
else:
return 404

else:
return r.get(url).status_code


def check_username(website, username):
url = get_profile_url(website, username)

usable = check_usable(website)

possible = check_format(website, username)

if not usable:
return {
'url': url,
'possible': possible,
'usable': usable,
}

if not possible:
return {
'url': url,
'possible': possible,
'usable': usable,
}

code = get_status_code(website, username)

if website in patterns['content_verification']:
res = r.get(url)
phrase = patterns['content_verification'][website].format(u=username)
if bytes(phrase, encoding='utf-8') in res.content:
code = 200
else:
code = 404

return {
'status': code,
'url': url,
'avatar': get_avatar(website, username) if code == 200
else None,
'possible': possible,
'usable': usable,
}

elif website == 'facebook':
res = r.get(url)
code = res.status_code

# Using mfacebook for checking username,
# when a username exists but hidden from
# search engines, it gives a login redirect
Expand All @@ -110,6 +135,7 @@ def check_username(website, username):
'avatar': get_avatar(website, username),
'possible': possible,
'profile': profile,
'usable': usable,
}

else:
Expand All @@ -118,9 +144,35 @@ def check_username(website, username):
'url': url,
'avatar': get_avatar(website, username),
'possible': possible,
'usable': usable,
}


def check_usable(website):
"""
Check if the website is usable.
It works by checking if known taken username is shown as available.
The checking will be cached in memory for 10 minutes.
"""

identifier = 'usable_{}'.format(website)

usable = cache.get(identifier)
if usable is not None:
return usable

constant_username = patterns['constant_usernames'][website]

code = get_status_code(website, constant_username)

if code == 404 or code == 301:
usable = False
usable = True
cache.set(identifier, usable, timeout=60*10)

return usable


def check_format(website, username):
"""Check the format of a username depending on the website
"""
Expand Down
14 changes: 14 additions & 0 deletions websites.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,20 @@ content_verification:
gitlab: "Snippets"
opensuse: "About me"
pinterest: "{u}"
constant_usernames:
asciinema: "john"
behance: "seeeturtle"
deviantart: "joshua"
facebook: "gyanlakhwani"
github: "seeeturtle"
gitlab: "andrewda"
instagram: "ElonMusk"
openhub: "seeeturtle"
opensuse: "biscuitsnake"
pinterest: "steve"
soundcloud: "postmalone"
tumblr: "steve"
twitter: "ElonMusk"
username_patterns:
asciinema:
characters: a-zA-Z0-9-
Expand Down

0 comments on commit c29956f

Please sign in to comment.