diff --git a/slinky/__init__.py b/slinky/__init__.py
index cd019c8..f524612 100644
--- a/slinky/__init__.py
+++ b/slinky/__init__.py
@@ -46,8 +46,8 @@ class Slinky:
Class for Slinky
"""
- def __init__(self, url: str) -> None:
- self.db = db.ShortcodeDB(url) # pylint: disable=invalid-name
+ def __init__(self, db_url: str) -> None:
+ self.db = db.ShortcodeDB(db_url) # pylint: disable=invalid-name
self.session = self.db.session()
def add(
@@ -118,3 +118,15 @@ class Slinky:
{db.ShortURL.fixed_views: db.ShortURL.fixed_views - 1}
)
self.session.commit()
+
+ def get_all(self) -> list[Shortcode]:
+ """
+ Return a Shortcode object for a given shortcode
+
+ Args:
+ shortcode (str): the shortcode to look up
+
+ Returns:
+ Shortcode: full Shortcode object for the given shortcode
+ """
+ return list(self.session.query(db.ShortURL).all())
diff --git a/slinky/templates/add.html b/slinky/templates/add.html
index 9a943da..61d40c8 100644
--- a/slinky/templates/add.html
+++ b/slinky/templates/add.html
@@ -1,4 +1,4 @@
-{% include '_head.html' %}
+{% include '_head.html' -%}
@@ -9,7 +9,7 @@
-{% include '_tail.html' %}
+{% include '_tail.html' -%}
diff --git a/slinky/templates/list.html b/slinky/templates/list.html
new file mode 100644
index 0000000..8c5cd90
--- /dev/null
+++ b/slinky/templates/list.html
@@ -0,0 +1,35 @@
+{% include '_head.html' -%}
+
+
+
+
+
Add a shortcode
+
+
+
+ {% if shortcodes -%}
+
+
+
+ Shortcode |
+ URL |
+ Remaining views |
+ Expiry date |
+
+
+
+ {% for shortcode in shortcodes -%}
+
+ {{ shortcode.shortcode }} |
+ {{ shortcode.url }} |
+ {{ shortcode.fixed_views if shortcode.fixed_views >= 0 else 'Unlimited' }} |
+ {{ shortcode.expiry if shortcode.expiry != '9999-12-31 23:59:59.999999' else 'None' }} |
+
+ {% endfor -%}
+
+
+ {% endif -%}
+
+
+
+{% include '_tail.html' -%}
diff --git a/slinky/web.py b/slinky/web.py
index b87d61b..66503af 100644
--- a/slinky/web.py
+++ b/slinky/web.py
@@ -65,7 +65,7 @@ def try_path_as_shortcode(path: str) -> Response:
Try the initial path as a shortcode, redirect if found
Returns:
- Optional[Response]: redirect if found, otherwise continue on
+ Response: redirect if found, otherwise 404
"""
should_redirect = True
slinky = Slinky(cfg['db'])
@@ -87,12 +87,12 @@ def try_path_as_shortcode(path: str) -> Response:
@slinky_webapp.route('/_/add', methods=['GET', 'POST'])
-def add() -> str:
+def add() -> Response:
"""
Create and add a new shorturl
Returns:
- str: shortcode for the URL
+ str: HTTP response
"""
shortcode = ''
url = ''
@@ -107,11 +107,27 @@ def add() -> str:
if url:
slinky = Slinky(cfg['db'])
- while True:
+ for attempts in range(50):
try:
shortcode = slinky.add(url, length, fixed_views, expiry)
break
except ValueError:
- logging.warning('Shortcode already exists. Retrying.')
+ logging.warning(
+ 'Shortcode already exists. Retrying (%d/50).', attempts
+ )
+ else:
+ return Response('Could not create a unique shortcode', 500)
return render_template('add.html', form=form, shortcode=shortcode)
+
+
+@slinky_webapp.route('/_/list', methods=['GET', 'POST'])
+def lister() -> str:
+ """
+ Create and add a new shorturl
+
+ Returns:
+ str: shortcode for the URL
+ """
+ slinky = Slinky(cfg['db'])
+ return render_template('list.html', shortcodes=slinky.get_all())
diff --git a/templates/_head.html b/templates/_head.html
index e15f33f..23ce692 100644
--- a/templates/_head.html
+++ b/templates/_head.html
@@ -89,6 +89,9 @@
Add
+
+ List
+
diff --git a/tests/test_slinky.py b/tests/test_slinky.py
index 1e40b24..033571e 100644
--- a/tests/test_slinky.py
+++ b/tests/test_slinky.py
@@ -56,3 +56,15 @@ class TestSlinky(TestCase):
Slinky(self.test_db).add,
'https://www.example.com',
)
+
+ def test_get_all(self) -> None:
+ """
+ Ensure multiple results are returned and that they return all fields
+ """
+ shortcodes = Slinky(self.test_db).get_all()
+
+ self.assertGreater(len(shortcodes), 1)
+ assert hasattr(shortcodes[0], 'shortcode')
+ assert hasattr(shortcodes[0], 'url')
+ assert hasattr(shortcodes[0], 'fixed_views')
+ assert hasattr(shortcodes[0], 'expiry')
diff --git a/tests/test_web.py b/tests/test_web.py
index 4484d82..3f47f19 100644
--- a/tests/test_web.py
+++ b/tests/test_web.py
@@ -6,6 +6,7 @@ from unittest import TestCase, mock
from slinky import web
+
@mock.patch.dict('slinky.web.cfg', {'db': 'sqlite:///tests/test.db'})
class TestWeb(TestCase):
"""
@@ -33,3 +34,20 @@ class TestWeb(TestCase):
"""
response = web.try_path_as_shortcode('egif')
self.assertEqual(response.status_code, 404)
+
+ @mock.patch(
+ 'slinky.web.ShortURLForm',
+ return_value=mock.Mock(
+ shortcode=mock.Mock(data=''),
+ url=mock.Mock(data='https://example.com'),
+ fixed_views=mock.Mock(data=0),
+ expiry=mock.Mock(data='1970-01-01 00:00:00.000000'),
+ ),
+ )
+ @mock.patch('slinky.random_string', return_value='egie')
+ def test_no_unique_shortcode(self, *_: Any) -> None:
+ """
+ Ensure non-unique shortcodes return a 500 error
+ """
+ response = web.add()
+ self.assertEqual(response.status_code, 500)