-
Notifications
You must be signed in to change notification settings - Fork 198
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #260 from 1simransaini/simran_branch
Added Url-Shortener project under Node-JS-Projects
- Loading branch information
Showing
13 changed files
with
405 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
<h1 align='center'><b>💥 URL-Shortner 💥</b></h1> | ||
|
||
<!-- -------------------------------------------------------------------------------------------------------------- --> | ||
|
||
<h3 align='center'>Tech Stack Used 🎮</h3> | ||
<!-- enlist all the technologies used to create this project from them (Remove comment using 'ctrl+z' or 'command+z') --> | ||
|
||
<div align='center'> | ||
<img src="https://img.shields.io/badge/html5-%23E34F26.svg?style=for-the-badge&logo=html5&logoColor=white" alt="HTML5"/> | ||
<img src="https://img.shields.io/badge/css3-%231572B6.svg?style=for-the-badge&logo=css3&logoColor=white" alt="CSS3"/> | ||
<img src="https://img.shields.io/badge/javascript-%23323330.svg?style=for-the-badge&logo=javascript&logoColor=%23F7DF1E" alt="JavaScript"/> | ||
<img src="https://img.shields.io/badge/node.js-6DA55F?style=for-the-badge&logo=node.js&logoColor=white" alt="Node.js"/> | ||
<img src="https://img.shields.io/badge/express.js-%23404d59.svg?style=for-the-badge&logo=express&logoColor=%2361DAFB" alt="Express.js"/> | ||
<img src="https://img.shields.io/badge/MongoDB-%234ea94b.svg?style=for-the-badge&logo=mongodb&logoColor=white" alt="MongoDB"/> | ||
</div> | ||
|
||
|
||
|
||
![Line](https://github.com/Avdhesh-Varshney/WebMasterLog/assets/114330097/4b78510f-a941-45f8-a9d5-80ed0705e847) | ||
|
||
<!-- -------------------------------------------------------------------------------------------------------------- --> | ||
|
||
## :zap: Description 📃 | ||
|
||
<div> | ||
<!-- <p>Add Description of the project</p> --> | ||
<p>A simple Node.js URL shortener using ExpressJS and MongoDB. The primary aim of a URL shortener is to convert long URLs into shorter, more manageable links. The shortened URL redirects users to the original, longer URL when accessed.</p> | ||
</div> | ||
|
||
|
||
<!-- -------------------------------------------------------------------------------------------------------------- --> | ||
|
||
## :zap: How to run it? 🕹️ | ||
|
||
<!-- Add steps how to run this project --> | ||
Follow these steps to set up the project locally: | ||
|
||
### Clone the Repository | ||
|
||
First, clone the repository to your local machine: | ||
|
||
```bash | ||
git clone https://github.com/1simransaini/Url-Shortener.git | ||
``` | ||
Navigate to the project directory and install the required dependencies: | ||
```bash | ||
cd Url-Shortener | ||
npm install | ||
``` | ||
Create a .env file in the root of the project directory and add the following environment variables: | ||
```bash | ||
PORT=3000 | ||
MONGO_URL=yours | ||
``` | ||
Run the program as | ||
```bash | ||
node src/server.js | ||
``` | ||
<!-- -------------------------------------------------------------------------------------------------------------- --> | ||
|
||
## :zap: Screenshots 📸 | ||
<!-- add the screenshot of the project (Mandatory) --> | ||
![1](https://github.com/Avdhesh-Varshney/WebMasterLog/assets/91106038/26624ca0-5639-4fe4-9c7f-f0ec4241406a) | ||
|
||
![Line](https://github.com/Avdhesh-Varshney/WebMasterLog/assets/114330097/4b78510f-a941-45f8-a9d5-80ed0705e847) | ||
|
||
<!-- -------------------------------------------------------------------------------------------------------------- --> | ||
|
||
<h4 align='center'>Developed By <b><i>Simran Saini</i></b> 👩</h4> | ||
<p align='center'> | ||
<a href='https://www.linkedin.com/in/1simransaini/'> | ||
<img src='https://img.shields.io/badge/linkedin-%230077B5.svg?style=for-the-badge&logo=linkedin&logoColor=white' /> | ||
</a> | ||
<a href='https://github.com/1simransaini'> | ||
<img src='https://img.shields.io/badge/github-%23121011.svg?style=for-the-badge&logo=github&logoColor=white' /> | ||
</a> | ||
</p> | ||
|
||
<h4 align='center'>Happy Coding 👩</h4> | ||
|
||
<h3 align="center">Show some ❤️ by 🌟 this repository!</h3> | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
{ | ||
"name": "urlshortner", | ||
"version": "1.0.0", | ||
"description": "", | ||
"main": "index.js", | ||
"scripts": { | ||
"dev": "nodemon src/server.js", | ||
"start": "nodemon src/server.js" | ||
}, | ||
"author": "Simran Saini", | ||
"license": "ISC", | ||
"dependencies": { | ||
"body-parser": "^1.20.2", | ||
"dotenv": "^16.3.1", | ||
"express": "^4.18.2", | ||
"mongoose": "^7.5.1" | ||
} | ||
} |
106 changes: 106 additions & 0 deletions
106
Node-JS-Projects/Advanced/Url-Shortener/public/css/styles.css
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
body { | ||
font-family: 'Arial', sans-serif; | ||
background-color: #e0e0e0; /* background color */ | ||
margin: 0; | ||
padding: 0; | ||
line-height: 1.6; | ||
} | ||
|
||
.container { | ||
max-width: 600px; | ||
margin: 50px auto; | ||
background-color: #ffffff; /* background color */ | ||
padding: 20px; | ||
border-radius: 5px; | ||
box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.1); | ||
} | ||
|
||
header { | ||
text-align: center; | ||
margin-bottom: 20px; | ||
background-color: #007BFF; /* Added background color */ | ||
padding: 10px; | ||
border-radius: 5px 5px 0 0; | ||
} | ||
|
||
header h1 { | ||
color: #ffffff; /* text color */ | ||
margin: 0; | ||
font-size: 2em; | ||
} | ||
|
||
header p { | ||
color: #dddddd; /* text color */ | ||
font-size: 1em; | ||
} | ||
|
||
input[type="url"] { | ||
width: 100%; | ||
padding: 10px; | ||
margin-bottom: 10px; | ||
border: 1px solid #ddd; | ||
border-radius: 5px; | ||
box-sizing: border-box; | ||
transition: border-color 0.3s; | ||
} | ||
|
||
input[type="url"]:focus { | ||
border-color: #007BFF; | ||
outline: none; | ||
} | ||
|
||
button { | ||
width: 100%; | ||
padding: 10px; | ||
background-color: #28a745; /* background color */ | ||
color: #fff; | ||
border: none; | ||
border-radius: 5px; | ||
cursor: pointer; | ||
transition: background-color 0.3s, transform 0.3s; | ||
} | ||
|
||
button:hover { | ||
background-color: #218838; /* hover background color */ | ||
transform: scale(1.05); | ||
} | ||
|
||
button:active { | ||
background-color: #1e7e34; /* active background color */ | ||
} | ||
|
||
#result { | ||
margin-top: 20px; | ||
text-align: center; | ||
font-size: 18px; | ||
color: #28a745; /* text color */ | ||
} | ||
|
||
#result a { | ||
color: #155724; /* link color */ | ||
text-decoration: none; | ||
transition: color 0.3s; | ||
} | ||
|
||
#result a:hover { | ||
color: #0c3d12; /* hover link color */ | ||
} | ||
|
||
@media (max-width: 600px) { | ||
.container { | ||
margin: 20px; | ||
padding: 15px; | ||
} | ||
|
||
header h1 { | ||
font-size: 1.5em; | ||
} | ||
|
||
header p { | ||
font-size: 0.9em; | ||
} | ||
|
||
button { | ||
padding: 12px; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
|
||
<head> | ||
<meta charset="UTF-8"> | ||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | ||
<title>URL SHORTENER</title> | ||
<link rel="stylesheet" href="css/styles.css"> | ||
</head> | ||
|
||
<body> | ||
<div class="container"> | ||
<header> | ||
<h1>URL SHORTENER</h1> | ||
<p>Shorten your lengthy URLs in a snap!!</p> | ||
</header> | ||
<main> | ||
<input type="url" id="originalUrl" placeholder="Enter your long URL here"> | ||
<button id="shortenBtn">Shorten</button> | ||
<div id="result"></div> | ||
</main> | ||
<script src="js/main.js"></script> | ||
</div> | ||
</body> | ||
|
||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
document.getElementById('shortenBtn').addEventListener('click', async () => { | ||
const originalUrl = document.getElementById('originalUrl').value; | ||
if (!originalUrl || !isValidUrl(originalUrl)) { | ||
alert('Please enter a valid URL'); | ||
return; | ||
} | ||
try { | ||
const response = await fetch('/shorten', { | ||
method: 'POST', | ||
headers: { | ||
'Content-Type': 'application/json' | ||
}, | ||
body: JSON.stringify({ originalUrl }) | ||
}); | ||
const data = await response.json(); | ||
document.getElementById('result').textContent = `Shortened URL : ${window.location.href}${data.shortUrl}`; | ||
} catch (err) { | ||
console.error('Error shortening the URL : ', err); | ||
alert('Error shortening the URL , PLEASE TRY AGAIN'); | ||
} | ||
|
||
}); | ||
function isValidUrl(string) { | ||
try { | ||
new URL(string); | ||
return true; | ||
} catch (_) { | ||
return false; | ||
} | ||
} |
Binary file not shown.
54 changes: 54 additions & 0 deletions
54
Node-JS-Projects/Advanced/Url-Shortener/src/controllers/urlController.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
// src/controllers/urlController.js | ||
const Url = require('../models/urlModel'); | ||
const UrlShortener = require('../utils/urlShortener'); | ||
|
||
class UrlController { | ||
static async shortenUrl(req, res) { | ||
try { | ||
const { originalUrl } = req.body; | ||
if (!originalUrl || typeof originalUrl !== 'string') { | ||
return res.status(400).json({ message: "A valid URL is required" }); | ||
} | ||
|
||
// Check if the URL is already shortened | ||
const url = await Url.findOne({ originalUrl }); | ||
if (url) { | ||
return res.json(url); | ||
} | ||
|
||
// Generate a short URL | ||
const shortUrl = UrlShortener.generateShortUrl(); | ||
|
||
// Save to the database | ||
const newUrl = new Url({ originalUrl, shortUrl }); | ||
await newUrl.save(); | ||
res.json(newUrl); | ||
} catch (err) { | ||
res.status(500).json({ message: 'Server error: ' + err.message }); | ||
} | ||
} | ||
|
||
static async redirectToOriginalUrl(req, res) { | ||
try { | ||
const { shortUrl } = req.params; | ||
if (!shortUrl || typeof shortUrl !== 'string') { | ||
return res.status(400).send('Invalid short URL'); | ||
} | ||
|
||
const url = await Url.findOne({ shortUrl }); | ||
if (!url) { | ||
return res.status(404).send('URL NOT FOUND'); | ||
} | ||
|
||
// Increase the count | ||
url.clicks += 1; | ||
await url.save(); | ||
res.redirect(url.originalUrl); | ||
} catch (err) { | ||
console.error(err); | ||
res.status(500).send('Server Error'); | ||
} | ||
} | ||
} | ||
|
||
module.exports = UrlController; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
const mongoose = require('mongoose'); | ||
//requing the .env file | ||
require('dotenv').config(); | ||
const connectDB = async () => { | ||
try { | ||
await mongoose.connect(process.env.MONGO_URL, { | ||
useNewUrlParser: true, | ||
useUnifiedTopology: true | ||
}); | ||
console.log("Connected to MONGODB ...") | ||
} catch (err) { | ||
console.error('Error connecting to database : ', err); | ||
} | ||
} | ||
|
||
module.exports = connectDB; |
22 changes: 22 additions & 0 deletions
22
Node-JS-Projects/Advanced/Url-Shortener/src/models/urlModel.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
const mongoose = require('mongoose'); | ||
const urlSchema = new mongoose.Schema({ | ||
originalUrl: { | ||
type: String, | ||
required: true | ||
}, | ||
shortUrl: { | ||
type: String, | ||
required: true, | ||
unique: true | ||
}, | ||
clicks: { | ||
type: Number, | ||
default: 0 | ||
}, | ||
createdAt: { | ||
type: Date, | ||
default: Date.now | ||
} | ||
}); | ||
const Url = mongoose.model('Url', urlSchema); | ||
module.exports = Url; |
19 changes: 19 additions & 0 deletions
19
Node-JS-Projects/Advanced/Url-Shortener/src/routes/urlRoutes.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
// src/routes/urlRoutes.js | ||
const express = require('express'); | ||
const rateLimit = require('express-rate-limit'); | ||
const urlController = require('../controllers/urlController'); | ||
|
||
const router = express.Router(); | ||
|
||
// Define rate limit rule | ||
const limiter = rateLimit({ | ||
windowMs: 15 * 60 * 1000, // 15 minutes | ||
max: 100, // limit each IP to 100 requests per windowMs | ||
message: "Too many requests from this IP, please try again later." | ||
}); | ||
|
||
// Apply the rate limiting middleware to relevant routes | ||
router.post('/shorten', limiter, urlController.shortenUrl); | ||
router.get('/:shortUrl', limiter, urlController.redirectToOriginalUrl); | ||
|
||
module.exports = router; |
Oops, something went wrong.