initial commit
This commit is contained in:
commit
caa37a5021
BIN
__pycache__/app.cpython-39.pyc
Normal file
BIN
__pycache__/app.cpython-39.pyc
Normal file
Binary file not shown.
44
app.py
Normal file
44
app.py
Normal file
@ -0,0 +1,44 @@
|
||||
from flask import Flask, render_template, request, make_response, redirect
|
||||
from numpy import real
|
||||
from freecaptcha import captcha
|
||||
import uuid
|
||||
|
||||
app = Flask(__name__, static_url_path='', static_folder='static',)
|
||||
|
||||
captcha_solutions = {}
|
||||
captcha_solved = []
|
||||
|
||||
@app.route("/captcha", methods=['GET', 'POST'])
|
||||
def login():
|
||||
# This means they just submitted a CAPTCHA
|
||||
# We need to see if they got it right
|
||||
incorrect_captcha = False
|
||||
if request.method == 'POST':
|
||||
captcha_quess = request.form.get('captcha', None)
|
||||
captcha_cookie = request.cookies.get('freecaptcha_cookie')
|
||||
real_answer = captcha_solutions.get(captcha_cookie, None)
|
||||
if real_answer is not None:
|
||||
if int(captcha_quess) == int(real_answer):
|
||||
captcha_solved.append(captcha_cookie)
|
||||
return redirect("/", code=302)
|
||||
else:
|
||||
incorrect_captcha = True
|
||||
|
||||
# Select an image
|
||||
image_path = captcha.random_image()
|
||||
|
||||
# Generate list of rotated versions of image
|
||||
# and save which one is correct
|
||||
answer, options = captcha.captchafy(image_path)
|
||||
|
||||
# Provide the CAPTCHA options to the web page using the CAPTCHA
|
||||
resp = make_response(render_template("index.html", captcha_options=options, incorrect_captcha=incorrect_captcha))
|
||||
|
||||
# Track this user with a cookie and store the correct answer
|
||||
# by linking the cookie with the answer, we can check their answer
|
||||
# later
|
||||
freecaptcha_cookie = str(uuid.uuid4())
|
||||
resp.set_cookie('freecaptcha_cookie', freecaptcha_cookie)
|
||||
captcha_solutions[freecaptcha_cookie] = answer
|
||||
|
||||
return resp
|
0
freecaptcha/__init__.py
Normal file
0
freecaptcha/__init__.py
Normal file
BIN
freecaptcha/__pycache__/__init__.cpython-39.pyc
Normal file
BIN
freecaptcha/__pycache__/__init__.cpython-39.pyc
Normal file
Binary file not shown.
BIN
freecaptcha/__pycache__/captcha.cpython-39.pyc
Normal file
BIN
freecaptcha/__pycache__/captcha.cpython-39.pyc
Normal file
Binary file not shown.
54
freecaptcha/captcha.py
Normal file
54
freecaptcha/captcha.py
Normal file
@ -0,0 +1,54 @@
|
||||
import random
|
||||
import os
|
||||
from PIL import Image
|
||||
import base64
|
||||
from io import BytesIO
|
||||
|
||||
# Angles we'll rotate the original by
|
||||
# when we create n rotations
|
||||
def calculate_angles(n):
|
||||
return list(range(0, 360, 360 // n))
|
||||
|
||||
def rotate_img(img_path, angle):
|
||||
original_img = Image.open(img_path)
|
||||
rotated = original_img.rotate(angle)
|
||||
buffered = BytesIO()
|
||||
rotated.save(buffered, format="PNG")
|
||||
b64_rot = base64.b64encode(buffered.getvalue())
|
||||
return b64_rot.decode("utf-8")
|
||||
|
||||
def captchafy(img_path, n=6):
|
||||
angles = calculate_angles(n)
|
||||
|
||||
rotated_imgs = [
|
||||
{
|
||||
'original': False,
|
||||
'image': rotate_img(img_path, angle)
|
||||
} for angle in angles]
|
||||
|
||||
rotated_imgs[0]['original'] = True
|
||||
|
||||
random.shuffle(rotated_imgs)
|
||||
|
||||
correct_img = None
|
||||
for index, img in enumerate(rotated_imgs):
|
||||
if img['original']:
|
||||
correct_img = index
|
||||
|
||||
return correct_img, [img['image'] for img in rotated_imgs]
|
||||
|
||||
def random_image(dir='images/'):
|
||||
dir_contents = os.listdir(dir)
|
||||
random_image = random.choice(dir_contents)
|
||||
return dir + random_image
|
||||
|
||||
def resize_dir(size=150, dir='images/'):
|
||||
for img_file in os.listdir(dir):
|
||||
img = Image.open(dir + img_file)
|
||||
width, height = img.size
|
||||
print(width, height)
|
||||
if not (width > size or height > size):
|
||||
continue
|
||||
|
||||
img.thumbnail((size, size),Image.ANTIALIAS)
|
||||
img.save(dir + img_file)
|
BIN
images/gnome.png
Normal file
BIN
images/gnome.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 39 KiB |
72
static/freecaptcha.css
Normal file
72
static/freecaptcha.css
Normal file
@ -0,0 +1,72 @@
|
||||
.grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 0fr);
|
||||
}
|
||||
|
||||
div > div {
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
/* HIDE RADIO */
|
||||
[type=radio] {
|
||||
position: absolute;
|
||||
opacity: 0;
|
||||
width: 0;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
/* IMAGE STYLES */
|
||||
[type=radio] + img {
|
||||
cursor: pointer;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
/* CHECKED STYLES */
|
||||
[type=radio]:checked + img {
|
||||
outline: 2px solid black;
|
||||
filter: brightness(120%);
|
||||
}
|
||||
|
||||
.isa_info, .isa_success, .isa_warning, .isa_error {
|
||||
margin: 10px 0px;
|
||||
padding:12px;
|
||||
|
||||
}
|
||||
.isa_info {
|
||||
color: #00529B;
|
||||
background-color: #BDE5F8;
|
||||
}
|
||||
.isa_success {
|
||||
color: #4F8A10;
|
||||
background-color: #DFF2BF;
|
||||
}
|
||||
.isa_warning {
|
||||
color: #9F6000;
|
||||
background-color: #FEEFB3;
|
||||
}
|
||||
.isa_error {
|
||||
color: #D8000C;
|
||||
background-color: #FFD2D2;
|
||||
}
|
||||
.isa_info i, .isa_success i, .isa_warning i, .isa_error i {
|
||||
margin:10px 22px;
|
||||
font-size:2em;
|
||||
vertical-align:middle;
|
||||
}
|
||||
|
||||
#root {
|
||||
width: fit-content;
|
||||
/* To adjust the height as well */
|
||||
height: fit-content;
|
||||
}
|
||||
|
||||
input[type=submit] {
|
||||
background-color: #4CAF50; /* Green */
|
||||
border: none;
|
||||
color: white;
|
||||
padding: 15px 32px;
|
||||
text-align: center;
|
||||
text-decoration: none;
|
||||
display: inline-block;
|
||||
font-size: 16px;
|
||||
}
|
31
templates/index.html
Normal file
31
templates/index.html
Normal file
@ -0,0 +1,31 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link rel="stylesheet" href="freecaptcha.css">
|
||||
<title>Tor Dev</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root">
|
||||
{% if incorrect_captcha %}
|
||||
<div class="isa_error">
|
||||
<i class="fa fa-error"></i>
|
||||
Wrong CAPTCHA, try again!
|
||||
</div>
|
||||
{% endif %}
|
||||
<form method="POST">
|
||||
<div class='grid'>
|
||||
{% for captcha_image in captcha_options %}
|
||||
<label>
|
||||
<input type="radio" name="captcha" value="{{ loop.index0 }}" checked>
|
||||
<img src="data:image/png;base64,{{ captcha_image }}"></img>
|
||||
</label>
|
||||
{% endfor %}
|
||||
</div>
|
||||
<center><input type="submit" value="Submit"></input></center>
|
||||
</form>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
Loading…
Reference in New Issue
Block a user