Skip to content

Commit

Permalink
Hidden links (#10)
Browse files Browse the repository at this point in the history
* added hide_preview field

* added to form

* basic functionality
  • Loading branch information
angusgoody authored Mar 1, 2025
1 parent 561d056 commit b581f63
Show file tree
Hide file tree
Showing 7 changed files with 81 additions and 2 deletions.
13 changes: 13 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,17 @@

A simple url shortener service.

## Getting Started

Migrate the database:

```bash
python manage.py migrate
```

Run the server:

```bash
python manage.py runserver
```

11 changes: 10 additions & 1 deletion poo/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,20 @@

# Shared utility functions for the poo package

def shorten(new_url: str) -> str:
def shorten(new_url: str, hide_preview: bool = False) -> str:
"""
Takes a URL and returns a shortened version of it.
"""

if hide_preview:
# Generate a unique short code since the URL does not exist
short_code = generate_short_code()

# Save the URL to the database
URL.objects.create(original_url=new_url, short_code=short_code, hide_preview=True)

return short_code

# Check if the URL already exists in the database
existing_url = URL.objects.filter(original_url=new_url).first()
if existing_url:
Expand Down
18 changes: 18 additions & 0 deletions shortener/migrations/0003_url_hide_preview.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Generated by Django 5.1.3 on 2025-03-01 17:38

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('shortener', '0002_url_clicks_url_last_accessed'),
]

operations = [
migrations.AddField(
model_name='url',
name='hide_preview',
field=models.BooleanField(default=False),
),
]
1 change: 1 addition & 0 deletions shortener/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ class URL(models.Model):
original_url = models.URLField() # Original URL
short_code = models.CharField(max_length=10, unique=True) # Short code for the URL
created_at = models.DateTimeField(auto_now_add=True) # Creation timestamp
hide_preview = models.BooleanField(default=False) # Require click before redirecting

last_accessed = models.DateTimeField(null=True, blank=True) # Last accessed timestamp
clicks = models.PositiveIntegerField(default=0) # Number of times the URL was accessed
Expand Down
12 changes: 11 additions & 1 deletion shortener/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from .utils import generate_short_code
from django.http import HttpRequest, HttpResponse


def shorten_url(request: HttpRequest) -> HttpResponse:
if request.method == 'POST':
# Retrieve the original URL from POST data
Expand All @@ -14,15 +15,19 @@ def shorten_url(request: HttpRequest) -> HttpResponse:
if not original_url:
return render(request, 'shortener/index.html', {'error': 'URL is required'})

# Get the hide_preview value from the POST data
hide_preview = request.POST.get('hide_preview', False)

# Shorten the URL
short_code = shorten(original_url)
short_code = shorten(original_url, hide_preview)

# Redirect to the view that displays the shortened URL
return redirect('shortened', short_code=short_code)

# Render the form if the request method is not POST
return render(request, 'shortener/index.html')


def shortened_url(request: HttpRequest, short_code: str) -> HttpResponse:
"""View to display the shortened URL."""

Expand All @@ -31,11 +36,16 @@ def shortened_url(request: HttpRequest, short_code: str) -> HttpResponse:

return render(request, 'shortener/shortened.html', {'short_url': request.build_absolute_uri(f"/{short_code}")})


def redirect_url(request: HttpRequest, short_code: str) -> HttpResponse:
url = get_object_or_404(URL, short_code=short_code)

# Update the access information
url.record_access()

# If hide_preview is enabled, display the forward page
if url.hide_preview:
return render(request, 'shortener/forward.html', {'original_url': url.original_url})

# Redirect to the original URL
return redirect(url.original_url)
22 changes: 22 additions & 0 deletions templates/shortener/forward.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{% extends "shortener/../_base.html" %}

{% block content %}
<div class="container mx-auto mt-12">
<!-- Include the header -->
{% include "shortener/../_header.html" %}

<div class="max-w-lg mx-auto text-center">
<p>If not automatically redirected, click the link below ...</p>

<a href="{{ original_url }}" class="mt-5 bg-emerald-700 hover:bg-emerald-800 text-white font-semibold transition duration-300 rounded-lg py-2 px-2.5 inline-flex items-center justify-center">
Visit
</a>
</div>
</div>
<script>
// Wait for the page to load and redirect to the original URL
document.addEventListener('DOMContentLoaded', function () {
window.location.href = "{{ original_url }}";
});
</script>
{% endblock content %}
6 changes: 6 additions & 0 deletions templates/shortener/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,12 @@
required
>
</div>

<!-- Hide preview checkbox -->
<div class="flex items-center mb-4">
<input id="hide_preview" name="hide_preview" type="checkbox" value="True" class="w-4 h-4 text-emerald-600 bg-gray-100 border-gray-300 rounded-sm focus:ring-emerald-500">
<label for="hide_preview" class="ms-2 text-sm font-medium text-gray-900">Hide preview <small>(Prevents apps providing a preview of the site (BETA)</small></label>
</div>

<!-- Submit Button -->
<button
Expand Down

0 comments on commit b581f63

Please sign in to comment.