Add delete functionality

This commit is contained in:
Scott Wallace 2021-12-28 15:13:45 +00:00
parent fee5801db6
commit 58a94c365d
Signed by: scott
GPG key ID: AA742FDC5AFE2A72
6 changed files with 47 additions and 11 deletions

View file

@ -71,7 +71,7 @@ class Slinky:
"""
shortcode = random_string(length=length)
if self.get(shortcode).url:
if self.get_by_shortcode(shortcode).url:
raise ValueError(f'Shortcode {shortcode} already exists')
dbentry = db.ShortURL(
@ -85,7 +85,7 @@ class Slinky:
return shortcode
def get(self, shortcode: str) -> Shortcode:
def get_by_shortcode(self, shortcode: str) -> Shortcode:
"""
Return a Shortcode object for a given shortcode
@ -130,3 +130,15 @@ class Slinky:
Shortcode: full Shortcode object for the given shortcode
"""
return list(self.session.query(db.ShortURL).all())
def delete_by_shortcode(self, shortcode: str) -> None:
"""
Delete shortcode entry
Args:
shortcode (str): Shortcode of entry to delete
"""
entry = self.session.query(db.ShortURL).filter_by(shortcode=shortcode).first()
self.session.delete(entry)
self.session.commit()

View file

@ -28,7 +28,7 @@
</thead>
<tbody>
<tr>
<td>{{request.host_url}}{{ shortcode }}</td>
<td><a href="{{request.host_url}}{{ shortcode }}">{{request.host_url}}{{ shortcode }}</a></td>
</tr>
</tbody>
</table>

View file

@ -15,6 +15,7 @@
<th scope="col">URL</th>
<th scope="col">Remaining views</th>
<th scope="col">Expiry date</th>
<th scope="col"></th>
</tr>
</thead>
<tbody>
@ -24,6 +25,14 @@
<td><a href="{{shortcode.url}}">{{ shortcode.url }}</a></td>
<td>{{ shortcode.fixed_views if shortcode.fixed_views >= 0 else 'Unlimited' }}</td>
<td>{{ shortcode.expiry if shortcode.expiry != '9999-12-31 23:59:59.999999' else 'None' }}</td>
<td>
<form action="/_/list" method="post">
<input id="delete" type="hidden" name="delete" value="{{ shortcode.shortcode }}" />
<button id="submit" class="btn btn-danger" type="submit">
Delete
</button>
</form>
</td>
</tr>
{% endfor -%}
</tbody>

View file

@ -8,7 +8,7 @@ from datetime import datetime
import yaml
from flask import Blueprint, Response, redirect, render_template
from flask_wtf import FlaskForm
from wtforms import DateTimeLocalField, IntegerField, StringField
from wtforms import DateTimeLocalField, HiddenField, IntegerField, StringField
from wtforms.validators import DataRequired, Length
from slinky import Slinky
@ -19,9 +19,17 @@ with open('config.yaml', encoding='utf-8-sig') as conffile:
cfg = yaml.safe_load(conffile)
class ShortURLForm(FlaskForm): # type: ignore[misc]
class DelForm(FlaskForm): # type: ignore[misc]
"""
Web form definition
Delete form definition
"""
delete = HiddenField('delete')
class AddForm(FlaskForm): # type: ignore[misc]
"""
Add form definition
"""
url = StringField(
@ -69,7 +77,7 @@ def try_path_as_shortcode(path: str) -> Response:
"""
should_redirect = True
slinky = Slinky(cfg['db'])
shortcode = slinky.get(path)
shortcode = slinky.get_by_shortcode(path)
if shortcode.url:
if shortcode.fixed_views == 0:
logging.warning('Shortcode out of views')
@ -97,7 +105,7 @@ def add() -> Response:
shortcode = ''
url = ''
form = ShortURLForm(meta={'csrf': False})
form = AddForm(meta={'csrf': False})
if form.is_submitted():
url = form.url.data.strip()
@ -129,5 +137,10 @@ def lister() -> str:
Returns:
str: shortcode for the URL
"""
form = DelForm(meta={'csrf': False})
slinky = Slinky(cfg['db'])
return render_template('list.html', shortcodes=slinky.get_all())
if form.is_submitted():
slinky.delete_by_shortcode(form.delete.data.strip())
return render_template('list.html', form=form, shortcodes=slinky.get_all())

View file

@ -43,7 +43,9 @@ class TestSlinky(TestCase):
Ensure we can fetch a URL for a known shortcode
"""
self.assertEqual('https://example.com', Slinky(self.test_db).get('egie').url)
self.assertEqual(
'https://example.com', Slinky(self.test_db).get_by_shortcode('egie').url
)
@mock.patch('sqlalchemy.orm.session.Session.add', return_value=None)
@mock.patch('slinky.random_string', return_value='egie')

View file

@ -47,7 +47,7 @@ class TestWeb(TestCase):
@mock.patch('slinky.random_string', return_value='egie')
def test_no_unique_shortcode(self, *_: Any) -> None:
"""
Ensure non-unique shortcodes return a 500 error
Ensure non-unique shortcode generation returns a 500 error
"""
response = web.add()
self.assertEqual(response.status_code, 500)