Initial commit

This commit is contained in:
tomeros
2021-03-24 15:11:34 +02:00
commit 7d68b93238
60 changed files with 1847 additions and 0 deletions

View File

@@ -0,0 +1,222 @@
#heading-p {
margin-top: 1.5%;
}
.btn:active {
box-shadow: none;
}
.title-bullet {
width: 100%;
height: 0;
border-top: 1px solid #ddd;
display: block;
margin: 30px 0;
}
.title-bullet span {
width: 70px;
height: 6px;
display: table;
margin-top: -3px;
background: #4b97ed;
}
span {
font-style: inherit;
font-weight: inherit;
}
.form-control-borderless {
border: none;
}
.form-control-borderless:hover, .form-control-borderless:active, .form-control-borderless:focus {
border: none;
outline: none;
box-shadow: none;
}
.btn:not(:disabled):not(.disabled) {
background: rgb(29, 184, 84);
border-style: none;
box-shadow: none;
}
.btn:not(:disabled):not(.disabled) {
background: rgb(29, 184, 84);
border-style: none;
box-shadow: none;
}
.btn:hover {
background-color: white;
}
#long-link {
margin-top: 2%;
}
#credits {
margin-top: 10%;
}
.dh-highlight-text {
text-align: center;
padding: 30px;
}
/**/
/*=================*/
.fa-check:hover {
opacity: 1 !important;
}
.fa-check {
padding: 0 !important;
}
.bullet {
list-style-type: none;
}
.res-home-btn {
padding-top: 1.25rem;
}
.fa {
padding: 20px;
font-size: 30px;
width: 50px;
text-align: center;
text-decoration: none;
margin: 5px 2px;
}
.fa:hover {
opacity: 0.7;
text-decoration: none;
}
.fa-facebook {
background: #3B5998;
color: white;
}
.fa-twitter {
background: #55ACEE;
color: white;
}
.fa-linkedin {
background: #007bb5;
color: white;
}
.fa-reddit {
background: #ff5700;
color: white;
}
.fa {
box-sizing: unset;
}
/*--------------*/
.alert-box {
padding: 15px;
margin-bottom: 20px;
border: 1px solid transparent;
border-radius: 4px;
}
.success {
color: #3c763d;
background-color: #dff0d8;
border-color: #d6e9c6;
display: none;
margin-top: 3%;
}
.c {
width: auto;
padding: 0;
font-size: 17px !important;
}
body {
background: linear-gradient(-45deg, #ee7752, #e73c7e, #23a6d5, #2dd591);
/*background: linear-gradient(-45deg, #06D6A0, #EF476F, #06D6A0, #FFD166);*/
background-size: 400% 400%;
animation: gradient 50s ease infinite;
}
@keyframes gradient {
0% {
background-position: 0% 50%;
}
50% {
background-position: 100% 50%;
}
100% {
background-position: 0% 50%;
}
}
.credits-card {
display: inline-block;
padding: 8px;
opacity: .9;
}
.alert-warning {
display: none;
margin-top: 3%;
}
.card {
border-radius: 17px;
}
.dh-highlight-text {
margin-top: 40px;
}
pre {
margin-bottom: 0;
}
.row {
margin-bottom: 30px;
}
.code-block {
background: #212529;
padding: 10px;
border-radius: 13px;
border: none;
box-shadow: 4px 4px 12px 0 #212529;
}
pre {
color: whitesmoke;
}
#invalid-verification {
display: block !important;
}
#api-card {
margin-top: 0 !important;
}

View File

@@ -0,0 +1,58 @@
function copyToClipboard() {
let copyText = document.getElementById("copy-able");
copyText.select();
copyText.setSelectionRange(0, 99999); /*For mobile devices*/
document.execCommand("copy");
}
$("#copy-btn").click(function () {
$("div.success").fadeIn(300).delay(1500).fadeOut(900);
});
function checkUrl(event) {
let value = document.getElementById('url-input').value;
if (value.length < 5) {
$("div.alert-warning").fadeIn(300).delay(1500).fadeOut(900);
event.preventDefault();
return false;
}
}
function checkEmail(event) {
const re = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
let email = document.getElementById('email_input').value;
let isEmailValid = re.test(String(email).toLowerCase());
if (email.length < 1) {
$("div#cant-be-empty").fadeIn(300).delay(1500).fadeOut(900);
event.preventDefault();
return false;
} else if (isEmailValid === false) {
$("div#invalid-email").fadeIn(300).delay(1500).fadeOut(900);
event.preventDefault();
return false;
}
}
function callGetToken() {
let xhttp = new XMLHttpRequest();
let hostUrl = document.getElementById('host-url').getAttribute('value');
xhttp.onreadystatechange = function () {
if (this.readyState === 4 && this.status === 200) {
document.getElementById("token").innerHTML = this.responseText;
}
};
xhttp.open("GET", `${hostUrl}/api/get_token`, true);
xhttp.send();
}
$('#verification').on('keyup', function () {
var foo = $(this).val().split(" ").join("");
if (foo.length > 0) {
foo = foo.match(new RegExp('.{1,3}', 'g')).join(" ");
}
$(this).val(foo);
});

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

View File

@@ -0,0 +1,28 @@
{% extends "base.html" %}
{% block content %}
<body>
<div>
<div class="row">
<div class="col-md-10 offset-md-1">
<div class="card m-auto" style="max-width:850px">
<div class="card-body">
<h2>🌴 404</h2>
<h4><strong>We could not find this page 🙁</strong><br></h4>
<p></p>
<a href="{{ url_for('index_blueprint.index') }}">
<button class="btn btn-primary" id="go-home" type="button"
style="width: 200px;height: 51px;background-color: rgb(41,41,41);transition: border 0.2s ease;">
Go back HOME
</button>
</a>
</div>
</div>
</div>
</div>
</div>
</body>
{% endblock %}

View File

@@ -0,0 +1,68 @@
{% extends "base.html" %}
{% block content %}
<body>
<div>
<div class="row">
<div class="col-md-10 offset-md-1">
<div class="card m-auto" style="max-width:850px">
<div class="card-body">
<h2><strong>The ShortMe API</strong><br></h2>
<p>ShortMe's API will allow you to access ShortMe's URL shortening capabilities over
API.</p>
<h4>What you need to get started</h4>
<ul>
<li>Access token</li>
</ul>
<h4>Shorten your first link!</h4>
<ol>
<li>Generate an <a href="{{ url_for('get_token_blueprint.get_token') }}"> access token</a>.</li>
<li>You'll use the POST method to the <kbd>/api/shorten</kbd> endpoint. Append your
access token as a header in your request. <br>
Here's an example:
<code>&lt;Authorization: Bearer {token}&gt;</code> <br> <br>
Example call: <br>
<kbd>POST</kbd> http://shortme.biz/api/shorten?url=http://www.longurl.com <br> <br>
Example Response:
<div class="code-block">
<pre>{<br> 'short_url': shortme.biz/f3Jds,<br> 'original_url': 'http://www.longurl.com',<br> 'success':True<br>}</pre>
</div>
</li>
</ol>
<br>
<h4>Get total URL clicks</h4>
<p>You can use ShortMe's API to track the total number of clicks your short URL received</p>
<ol>
<li>You'll use the GET method to the <kbd>/api/total_clicks</kbd> endpoint. Access token
is not required.<br>
<br>
Example call: <br>
<kbd>GET</kbd> http://shortme.biz/api/total_clicks?url=shortme.biz/f3Jds <br> <br>
Example Response:
<div class="code-block">
<pre>{<br> 'total': 2,<br> 'short_url': 'shortme.biz/f3Jds',<br> 'original_url': 'http://www.longurl.com',<br> 'success': True <br>}</pre>
</div>
</li>
</ol>
{# <a href="{{ url_for('index_blueprint.index') }}">#}
{# <button class="btn btn-primary" id="try-again-btn" type="button"#}
{# style="width: 200px;height: 51px;background-color: rgb(41,41,41);transition: border 0.2s ease;">#}
{# Try Again#}
{# </button>#}
{# </a>#}
</div>
</div>
</div>
</div>
</div>
</body>
{% endblock %}

View File

@@ -0,0 +1,44 @@
<!DOCTYPE html>
<html lang="eng">
<head>
<meta charset="utf-8">
<title>URL shortner</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css"
integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh"
crossorigin="anonymous">
<link rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<script src="https://code.jquery.com/jquery-3.5.1.js"></script>
<link rel="shortcut icon" href="{{ url_for('static', filename='favicon.ico') }}">
<link rel="stylesheet" href="{{ url_for('static', filename='CSS/styles.css') }}">
</head>
<body>
<div>
<div class="dh-highlight-text">
<div class="container">
<h1 class="clearmargin clearpadding">ShortMe</h1>
<p id="heading-p">ShortMe is a free tool to shorten URLs. Create a short & memorable URL in seconds.</p>
</div>
</div>
</div>
{% block content %}
{% endblock %}
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js"
integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo"
crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js"
integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6"
crossorigin="anonymous"></script>
<script src="https://code.jquery.com/jquery-3.5.1.js"></script>
<script src="{{ url_for('static', filename='../static/JS/main.js') }}"></script>
</body>
</html>

View File

@@ -0,0 +1,39 @@
{% extends "base.html" %}
{% block content %}
<body>
<div>
<div class="row">
<div class="col-md-10 offset-md-1">
<div class="card m-auto" style="max-width:850px">
<div class="card-body">
<h4><strong>Yikes! We could not shorten this URL 🙁</strong><br></h4>
<p>&nbsp;<strong>The URL you entered is not valid.</strong></p>
<ul>
<li class="bullet"><i class="fa fa-check" style="color: rgb(0,128,255);"></i>Make sure
the website is online<br></li>
<li class="bullet"><i class="fa fa-check" style="color: rgb(0,128,255);"></i>Check if
the URL is valid<br></li>
<li class="bullet"><i class="fa fa-check" style="color: rgb(0,128,255);"></i>&nbsp;The
URL may have
been blocked<br></li>
<li class="bullet"><i class="fa fa-check" style="color: rgb(0,128,255);"></i>&nbsp;The
url may have
been reported<br></li>
</ul>
<a href="{{ url_for('index_blueprint.index') }}">
<button class="btn btn-primary" id="try-again-btn" type="button"
style="width: 200px;height: 51px;background-color: rgb(41,41,41);transition: border 0.2s ease;">
Try Again
</button>
</a>
</div>
</div>
</div>
</div>
</div>
</body>
{% endblock %}

View File

@@ -0,0 +1,42 @@
{% extends "base.html" %}
{% block content %}
<body>
<div>
<div class="row">
<div class="col-md-10 offset-md-1">
<div class="card m-auto" style="max-width:850px">
<div class="card-body">
<h1 id="token"></h1>
<h1>Get your free ShortMe's API token</h1>
<p>Please enter your email below to get a verification code</p>
<div class="card">
<form class="card-body d-flex align-items-center" method="POST"
onsubmit="return checkEmail(event)"
action="{{ url_for('send_otp_blueprint.email_validation') }}">
<label for="email_input"></label><input
class="form-control form-control-lg flex-shrink-1 form-control-borderless"
placeholder="example@email.com" id="email_input" name="email"/>
<button class="btn btn-primary" type="submit"
style="width: 200px; height: 51px; background-color: rgb(41, 41, 41); transition: border 0.2s ease;">
Send Code
</button>
<br>
</form>
</div>
<br>
<p>*If you alredy verified your email you will get the API token</p>
<div class="alert-box alert-warning" id="invalid-email">Please enter a valid email address
</div>
<div class="alert-box alert-warning" id="cant-be-empty">This feild cannot be empty</div>
</div>
</div>
</div>
</div>
</div>
</body>
{% endblock %}

View File

@@ -0,0 +1,57 @@
{% extends "base.html" %} {% block content %}
<body>
<div>
<div class="row">
<div class="col-md-10 offset-md-1">
<div class="card m-auto" style="max-width: 850px;">
<div class="card-body">
<form class="d-flex align-items-center" method="POST" onsubmit="return checkUrl(event)"
action="{{ url_for('shorten_url_blueprint.shorten_url') }}">
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24"
fill="none" class="d-none d-sm-block h4 text-body m-0">
<path
d="M13.8284 10.1716C12.2663 8.60948 9.73367 8.60948 8.17157 10.1716L4.17157 14.1716C2.60948 15.7337 2.60948 18.2663 4.17157 19.8284C5.73367 21.3905 8.26633 21.3905 9.82843 19.8284L10.93 18.7269M10.1716 13.8284C11.7337 15.3905 14.2663 15.3905 15.8284 13.8284L19.8284 9.82843C21.3905 8.26633 21.3905 5.73367 19.8284 4.17157C18.2663 2.60948 15.7337 2.60948 14.1716 4.17157L13.072 5.27118"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
></path>
</svg>
<input class="form-control form-control-lg flex-shrink-1 form-control-borderless"
placeholder="Enter the link here" id="url-input" name="original_url"/>
<button class="btn btn-primary" type="submit"
style="width: 200px; height: 51px; background-color: rgb(41, 41, 41); transition: border 0.2s ease;">
Shorten
</button>
</form>
<div class="alert-box alert-warning">This field cannot be empty</div>
</div>
</div>
</div>
</div>
</div>
<div class="text-center" id="">
<div class="">
<p></p>
<h6 class="text-dark font-weight-bold">Check out <a href="{{ url_for('api_doc_blueprint.api_doc') }}">ShortMe's
API</a></h6>
<p></p>
</div>
</div>
<div class="text-center" id="credits">
<div class="card credits-card">
<h6 class="text-dark font-weight-bold"><i class="fa fa-code c"></i> with <i class="fa fa-heart c"></i>
by <a href="https://www.linkedin.com/in/tomer-chaim/">Tomer</a></h6>
<h6 class="text-dark font-weight-bold">Check out my <a
href="https://github.com/acrobaticPanicc/">GitHub</a></h6>
</div>
</div>
</body>
{% endblock %}

View File

@@ -0,0 +1,26 @@
{% extends "base.html" %}
{% block content %}
<div>
<div class="row">
<div class="col-md-10 offset-md-1">
<div class="card m-auto" style="max-width:850px">
<div class="card-body">
<h4><strong>Total URL Clicks</strong><br></h4>
<p id="total-p"> Your URL has been clicked {{ total_clicks }} times so far.<br></p>
<p id="long-link-1"></p>
<a href="{{ url_for('index_blueprint.index') }}">
<button class="btn btn-primary" id="copy-btn" type="button"
style="width: 200px;height: 51px;background-color: rgb(41,41,41);transition: border 0.2s ease;">
Shorten another URL
</button>
</a>
</div>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@@ -0,0 +1,55 @@
{% extends "base.html" %}
{% block content %}
<body>
<div>
<div class="row">
<div class="col-md-10 offset-md-1">
<div class="card m-auto" style="max-width:850px">
<div class="card-body">
<h1 id="token"></h1>
<h1><span></span> Please check your inbox</h1>
<p>We've sent a verification code to your email. Please enter it below and click
verify.</p>
<div class="card">
<form class="card-body d-flex align-items-center" method="POST"
onsubmit="return checkEmail(event)"
action="{{ url_for('verify_code_blueprint.validate_code') }}">
<label for="email_input"></label>
<input maxlength="7"
class="form-control form-control-lg flex-shrink-1 form-control-borderless"
placeholder="000 000" id="verification" name="verification"/>
<button class="btn btn-primary" type="submit"
style="width: 200px; height: 51px; background-color: rgb(41, 41, 41); transition: border 0.2s ease;">
Verify
</button>
<br>
</form>
</div>
{% if is_verified == 'False' %}
<div class="alert-box alert-warning" id="invalid-verification">
Your email already exist in our database but it's not activated.<br>Please check
your
inbox for the verification
code.
</div>
{% endif %}
{% if is_code_valid %}
<div class="alert-box alert-warning" id="invalid-verification">Wrong code, plesee try
again
</div>
{% endif %}
</div>
</div>
</div>
</div>
</div>
</body>
{% endblock %}

View File

@@ -0,0 +1,35 @@
{% extends "base.html" %}
{% block content %}
<body>
<div>
<div class="row">
<div class="col-md-10 offset-md-1">
<div class="card m-auto" style="max-width:850px">
<div class="card-body">
<h1 id="token"></h1>
<h1>Your API token</h1>
<form class="card-body d-flex align-items-center">
<input spellcheck="false" readonly
class="card form-control form-control form-control-lg flex-shrink-1 form-control-borderless"
id="copy-able" type="text" value="{{ auth_token }}"
style="margin-left: 1.4%;margin-right: 1.4%;height: 51px;border-width: 1px;">
<button class="btn btn-primary" onclick="copyToClipboard()" id="copy-btn" type="button"
style="width: 200px;height: 51px;background-color: rgb(41,41,41);transition: border 0.2s ease;">
Copy Token
</button>
</form>
<div class="alert-box success">Token copied to clipboard</div>
<div class="alert-box alert-warning" id="cant-be-empty">This feild cannot be empty</div>
</div>
</div>
</div>
</div>
</div>
</body>
{% endblock %}

View File

@@ -0,0 +1,70 @@
{% extends "base.html" %}
{% block content %}
<body>
<div>
<div class="row">
<div class="col-md-10 offset-md-1">
<div class="card m-auto" style="max-width:850px">
<div class="card-body">
<h4><strong>Your shortened URL</strong><br></h4>
<p>Copy the shortened link to share it.<br></p>
<div class="card">
<form class="card-body d-flex align-items-center">
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24"
fill="none" class="d-none d-sm-block h4 text-body m-0">
<path d="M13.8284 10.1716C12.2663 8.60948 9.73367 8.60948 8.17157 10.1716L4.17157 14.1716C2.60948 15.7337 2.60948 18.2663 4.17157 19.8284C5.73367 21.3905 8.26633 21.3905 9.82843 19.8284L10.93 18.7269M10.1716 13.8284C11.7337 15.3905 14.2663 15.3905 15.8284 13.8284L19.8284 9.82843C21.3905 8.26633 21.3905 5.73367 19.8284 4.17157C18.2663 2.60948 15.7337 2.60948 14.1716 4.17157L13.072 5.27118"
stroke="currentColor" stroke-width="2" stroke-linecap="round"
stroke-linejoin="round"></path>
</svg>
<input class="card form-control form-control form-control-lg flex-shrink-1 form-control-borderless"
id="copy-able" type="text" value="{{ full_short_url }}"
style="margin-left: 1.4%;margin-right: 1.4%;height: 51px;border-width: 1px;">
<button class="btn btn-primary" onclick="copyToClipboard()" id="copy-btn"
type="button"
style="width: 200px;height: 51px;background-color: rgb(41,41,41);transition: border 0.2s ease;">
Copy URL
</button>
</form>
</div>
<div class="alert-box success">URL copied to clipboard</div>
<form action="{{ url_for('total_clicks_blueprint.total_clicks') }}">
<input type="hidden" id="new_url" name="short_url" value="{{ short_url }}">
<p id="long-link">Original URL:&nbsp;<a href="#">{{ original_url }}</a></p>
<p id="long-link-1"><a id="total-clicks-link"
onclick="this.closest('form').submit();return false;" href="">Track</a>
the total clicks of your shortened URL in
real-time</p>
</form>
<div>
<h4><strong>Share your URL</strong><br></h4>
</div>
<div class="social">
<a href="#" class="fa fa-facebook"></a>
<a href="#" class="fa fa-twitter"></a>
<a href="#" class="fa fa-linkedin"></a>
<a href="#" class="fa fa-reddit"></a>
</div>
<div class="res-home-btn">
<a href="{{ url_for('index_blueprint.index') }}">
<button class="btn btn-primary" id="go-home-btn" type="button"
style="width: 200px;height: 51px;background-color: rgb(41,41,41);transition: border 0.2s ease;">
Go back home
</button>
</a>
</div>
</div>
</div>
</div>
</div>
</div>
</body>
{% endblock %}