mirror of
https://github.com/alopexc0de/Simple-Bookmarking-Service.git
synced 2024-12-22 14:22:39 +00:00
Prepare for Telethon Authenticator
This commit is contained in:
parent
4b613cb8d5
commit
68032742ba
17
api/api.py
17
api/api.py
@ -11,7 +11,7 @@ import datetime
|
|||||||
from pprint import pprint
|
from pprint import pprint
|
||||||
from uuid import UUID
|
from uuid import UUID
|
||||||
from bottle import response, abort
|
from bottle import response, abort
|
||||||
from .db import Database
|
from .db import BookmarkDatabase, TelethonDatabase
|
||||||
|
|
||||||
class API:
|
class API:
|
||||||
"""
|
"""
|
||||||
@ -26,7 +26,8 @@ class API:
|
|||||||
Setup some internal variables, such as various constants
|
Setup some internal variables, such as various constants
|
||||||
and the database connection
|
and the database connection
|
||||||
"""
|
"""
|
||||||
self.database = Database('bookmarks.db')
|
self.bookmark_database = BookmarkDatabase('database.db')
|
||||||
|
self.telethon_database = TelethonDatabase('database.db')
|
||||||
self.dt_fmt = "%H:%M:%S on %B %d %Y"
|
self.dt_fmt = "%H:%M:%S on %B %d %Y"
|
||||||
self.response_type = 'application/json'
|
self.response_type = 'application/json'
|
||||||
self.format_date = datetime.datetime.strftime
|
self.format_date = datetime.datetime.strftime
|
||||||
@ -52,7 +53,7 @@ class API:
|
|||||||
the UUID of the saved bookmark
|
the UUID of the saved bookmark
|
||||||
"""
|
"""
|
||||||
response.content_type = self.response_type
|
response.content_type = self.response_type
|
||||||
bookmark = self.database.save_bookmark(uri, title)
|
bookmark = self.bookmark_database.save_bookmark(uri, title)
|
||||||
|
|
||||||
return json.dumps({
|
return json.dumps({
|
||||||
'uuid': bookmark.hex
|
'uuid': bookmark.hex
|
||||||
@ -67,7 +68,7 @@ class API:
|
|||||||
everything about the bookmark
|
everything about the bookmark
|
||||||
"""
|
"""
|
||||||
response.content_type = self.response_type
|
response.content_type = self.response_type
|
||||||
bookmark = self.database.get_bookmark(UUID(bookmark_id))
|
bookmark = self.bookmark_database.get_bookmark(UUID(bookmark_id))
|
||||||
|
|
||||||
if bookmark == None:
|
if bookmark == None:
|
||||||
return abort(404, "Provided bookmark doesn't exist or has been deleted")
|
return abort(404, "Provided bookmark doesn't exist or has been deleted")
|
||||||
@ -82,7 +83,7 @@ class API:
|
|||||||
everything about each bookmark
|
everything about each bookmark
|
||||||
"""
|
"""
|
||||||
response.content_type = self.response_type
|
response.content_type = self.response_type
|
||||||
bookmarks = self.database.get_all_bookmarks()
|
bookmarks = self.bookmark_database.get_all_bookmarks()
|
||||||
|
|
||||||
if len(bookmarks) == 0:
|
if len(bookmarks) == 0:
|
||||||
return abort(404, "There are no bookmarks saved")
|
return abort(404, "There are no bookmarks saved")
|
||||||
@ -109,7 +110,7 @@ class API:
|
|||||||
response.content_type = self.response_type
|
response.content_type = self.response_type
|
||||||
return json.dumps({
|
return json.dumps({
|
||||||
'uuid': bookmark_id,
|
'uuid': bookmark_id,
|
||||||
'bookmark_deleted': self.database.delete_bookmark(UUID(bookmark_id)),
|
'bookmark_deleted': self.bookmark_database.delete_bookmark(UUID(bookmark_id)),
|
||||||
})
|
})
|
||||||
|
|
||||||
def update_bookmark_title(self, bookmark_id, title):
|
def update_bookmark_title(self, bookmark_id, title):
|
||||||
@ -121,7 +122,7 @@ class API:
|
|||||||
everything about the bookmark
|
everything about the bookmark
|
||||||
"""
|
"""
|
||||||
response.content_type = self.response_type
|
response.content_type = self.response_type
|
||||||
bookmark = self.database.update_bookmark_title(UUID(bookmark_id), title)
|
bookmark = self.bookmark_database.update_bookmark_title(UUID(bookmark_id), title)
|
||||||
|
|
||||||
if bookmark == None:
|
if bookmark == None:
|
||||||
return abort(404, "Provided bookmark doesn't exist or has been deleted")
|
return abort(404, "Provided bookmark doesn't exist or has been deleted")
|
||||||
@ -142,7 +143,7 @@ class API:
|
|||||||
"Perhaps you want to delete this bookmark instead?"
|
"Perhaps you want to delete this bookmark instead?"
|
||||||
|
|
||||||
response.content_type = self.response_type
|
response.content_type = self.response_type
|
||||||
bookmark = self.database.update_bookmark_uri(UUID(bookmark_id), uri)
|
bookmark = self.bookmark_database.update_bookmark_uri(UUID(bookmark_id), uri)
|
||||||
|
|
||||||
if bookmark == None:
|
if bookmark == None:
|
||||||
return abort(404, "Provided bookmark doesn't exist or has been deleted")
|
return abort(404, "Provided bookmark doesn't exist or has been deleted")
|
||||||
|
@ -7,3 +7,5 @@
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
from .db import Database
|
from .db import Database
|
||||||
|
from .bookmark_db import BookmarkDatabase
|
||||||
|
from .telethon_db import TelethonDatabase
|
||||||
|
172
api/db/bookmark_db.py
Normal file
172
api/db/bookmark_db.py
Normal file
@ -0,0 +1,172 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# Copyright 2020 - David Todd (c0de@c0defox.es)
|
||||||
|
# Licensed under the MIT License (https://opensource.org/licenses/MIT)
|
||||||
|
|
||||||
|
"""
|
||||||
|
This file contains the database for a simple bookmarking application
|
||||||
|
"""
|
||||||
|
|
||||||
|
import datetime
|
||||||
|
import sqlite3
|
||||||
|
import uuid
|
||||||
|
|
||||||
|
class BookmarkDatabase(Database):
|
||||||
|
"""
|
||||||
|
This class contains various methods for interacting
|
||||||
|
with the database for the bookmarking engine.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, database):
|
||||||
|
"""
|
||||||
|
Sets up the database connection + cursor
|
||||||
|
as well as creates a new table if it doesn't
|
||||||
|
exist in the database that is provided via the
|
||||||
|
instantiation of this class
|
||||||
|
"""
|
||||||
|
super(BookmarkDatabase, self).__init__(database)
|
||||||
|
|
||||||
|
# Automatically create the table if it doesn't
|
||||||
|
# already exist in the selected database
|
||||||
|
self._create_table()
|
||||||
|
|
||||||
|
def _create_table(self):
|
||||||
|
"""
|
||||||
|
Creates a table called `bookmarks`
|
||||||
|
that uses UUID as the primary key.
|
||||||
|
|
||||||
|
The UUID is generated from the `uri`,
|
||||||
|
which will be updated in the case that
|
||||||
|
a bookmark's uri gets updated.
|
||||||
|
|
||||||
|
`title` is a short, human readable/recognizable
|
||||||
|
string.
|
||||||
|
|
||||||
|
`create_date` and `update_date` are the datetimes
|
||||||
|
that the entry was created and updated, respectively.
|
||||||
|
"""
|
||||||
|
query = """
|
||||||
|
CREATE TABLE IF NOT EXISTS bookmarks (
|
||||||
|
bookmark_id GUID PRIMARY KEY,
|
||||||
|
uri TEXT NOT NULL,
|
||||||
|
title TEXT NOT NULL,
|
||||||
|
create_date TIMESTAMP NOT NULL,
|
||||||
|
update_date TIMESTAMP
|
||||||
|
)
|
||||||
|
"""
|
||||||
|
self.cursor.execute(query)
|
||||||
|
self.connection.commit()
|
||||||
|
|
||||||
|
def get_all_bookmarks(self):
|
||||||
|
"""
|
||||||
|
Returns all bookmarks in the database as a list.
|
||||||
|
"""
|
||||||
|
query = "SELECT * FROM bookmarks"
|
||||||
|
self.cursor.execute(query)
|
||||||
|
return self.cursor.fetchall()
|
||||||
|
|
||||||
|
def get_bookmark(self, bookmark_id):
|
||||||
|
"""
|
||||||
|
With the provided `bookmark_id`, the database will be
|
||||||
|
searched for a matching entry, with the row returned
|
||||||
|
if there is a match. If there is no match, None will
|
||||||
|
be returned.
|
||||||
|
|
||||||
|
`bookmark_id` is of type uuid.UUID()
|
||||||
|
"""
|
||||||
|
query = "SELECT * FROM bookmarks WHERE bookmark_id = ?"
|
||||||
|
self.cursor.execute(query, (bookmark_id, ))
|
||||||
|
return self.cursor.fetchone()
|
||||||
|
|
||||||
|
def save_bookmark(self, uri, title):
|
||||||
|
"""
|
||||||
|
Determines if the provided `uri` doesn't already
|
||||||
|
exist in the database adding a new entry if that
|
||||||
|
is the case. If the `uri` is already stored
|
||||||
|
(based on the generated UUID), the existing
|
||||||
|
entry's UUID will be returned instead.
|
||||||
|
"""
|
||||||
|
uri_uuid = uuid.uuid5(uuid.NAMESPACE_URL, uri)
|
||||||
|
|
||||||
|
bookmark_exists = self.get_bookmark(uri_uuid)
|
||||||
|
if bookmark_exists != None:
|
||||||
|
return bookmark_exists[0]
|
||||||
|
|
||||||
|
query = """
|
||||||
|
INSERT INTO bookmarks (
|
||||||
|
bookmark_id, uri, title, create_date
|
||||||
|
) VALUES (?, ?, ?, ?)
|
||||||
|
"""
|
||||||
|
self.cursor.execute(query, (uri_uuid, uri, title, datetime.datetime.now()))
|
||||||
|
self.connection.commit()
|
||||||
|
return uri_uuid
|
||||||
|
|
||||||
|
def delete_bookmark(self, bookmark_id):
|
||||||
|
"""
|
||||||
|
Removes the bookmark entry if it exists
|
||||||
|
|
||||||
|
`bookmark_id` is of type uuid.UUID()
|
||||||
|
|
||||||
|
Returns True upon successful removal.
|
||||||
|
Returns False upon unsuccessful removal.
|
||||||
|
"""
|
||||||
|
if self.get_bookmark(bookmark_id) != None:
|
||||||
|
query = "DELETE FROM bookmarks WHERE bookmark_id = ?"
|
||||||
|
self.cursor.execute(query, (bookmark_id, ))
|
||||||
|
self.connection.commit()
|
||||||
|
|
||||||
|
if self.get_bookmark(bookmark_id) == None:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
def update_bookmark_title(self, bookmark_id, new_title):
|
||||||
|
"""
|
||||||
|
Takes the provided `bookmark_id`, searches the
|
||||||
|
database for the matching record, and if found
|
||||||
|
the title will be replaced with `new_title`.
|
||||||
|
|
||||||
|
`bookmark_id` is of type uuid.UUID()
|
||||||
|
|
||||||
|
Returns None if there is no matching bookmark.
|
||||||
|
"""
|
||||||
|
bookmark = self.get_bookmark(bookmark_id)
|
||||||
|
if bookmark != None:
|
||||||
|
query = """
|
||||||
|
UPDATE bookmarks
|
||||||
|
SET title = ?, update_date = ?
|
||||||
|
WHERE bookmark_id = ?
|
||||||
|
"""
|
||||||
|
self.cursor.execute(query, (new_title, datetime.datetime.now(), bookmark_id, ))
|
||||||
|
self.connection.commit()
|
||||||
|
return self.get_bookmark(bookmark_id)
|
||||||
|
return None
|
||||||
|
|
||||||
|
def update_bookmark_uri(self, bookmark_id, new_uri):
|
||||||
|
"""
|
||||||
|
Takes the provided `bookmark_id`, searches the
|
||||||
|
database for the matching record, and if found
|
||||||
|
the URI will be replaced with `new_uri`.
|
||||||
|
|
||||||
|
`bookmark_id` is of type uuid.UUID()
|
||||||
|
|
||||||
|
A new `bookmark_id` will be generated if the
|
||||||
|
`new_uri` is different than what was previously
|
||||||
|
stored. If the newly generated `bookmark_id` matches
|
||||||
|
an existing entry, this method will return False.
|
||||||
|
You may want to delete the old bookmark in this case.
|
||||||
|
|
||||||
|
Returns None if there is no matching bookmark.
|
||||||
|
"""
|
||||||
|
bookmark = self.get_bookmark(bookmark_id)
|
||||||
|
if bookmark != None:
|
||||||
|
query = """
|
||||||
|
UPDATE bookmarks
|
||||||
|
SET bookmark_id = ?, uri = ?, update_date = ?
|
||||||
|
WHERE bookmark_id = ?
|
||||||
|
"""
|
||||||
|
new_bookmark_id = uuid.uuid5(uuid.NAMESPACE_URL, new_uri)
|
||||||
|
if self.get_bookmark(new_bookmark_id) == None:
|
||||||
|
self.cursor.execute(query, (new_bookmark_id, new_uri, datetime.datetime.now(), bookmark_id, ))
|
||||||
|
self.connection.commit()
|
||||||
|
return self.get_bookmark(new_bookmark_id)
|
||||||
|
return False
|
||||||
|
return None
|
153
api/db/db.py
153
api/db/db.py
@ -9,11 +9,10 @@
|
|||||||
import datetime
|
import datetime
|
||||||
import sqlite3
|
import sqlite3
|
||||||
import uuid
|
import uuid
|
||||||
|
|
||||||
class Database:
|
class Database:
|
||||||
"""
|
"""
|
||||||
This class contains various methods for interacting
|
Base database class that is shared by the bookmark
|
||||||
with the database for the bookmarking engine.
|
engine and the Telethon authenticator
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, database):
|
def __init__(self, database):
|
||||||
@ -36,151 +35,3 @@ class Database:
|
|||||||
self.connection = sqlite3.connect(database, detect_types=detect_types)
|
self.connection = sqlite3.connect(database, detect_types=detect_types)
|
||||||
with self.connection:
|
with self.connection:
|
||||||
self.cursor = self.connection.cursor()
|
self.cursor = self.connection.cursor()
|
||||||
|
|
||||||
# Automatically create the table if it doesn't
|
|
||||||
# already exist in the selected database
|
|
||||||
self._create_table()
|
|
||||||
|
|
||||||
def _create_table(self):
|
|
||||||
"""
|
|
||||||
Creates a table called `bookmarks`
|
|
||||||
that uses UUID as the primary key.
|
|
||||||
|
|
||||||
The UUID is generated from the `uri`,
|
|
||||||
which will be updated in the case that
|
|
||||||
a bookmark's uri gets updated.
|
|
||||||
|
|
||||||
`title` is a short, human readable/recognizable
|
|
||||||
string.
|
|
||||||
|
|
||||||
`create_date` and `update_date` are the datetimes
|
|
||||||
that the entry was create and updated, respectively.
|
|
||||||
"""
|
|
||||||
query = """
|
|
||||||
CREATE TABLE IF NOT EXISTS bookmarks (
|
|
||||||
bookmark_id GUID PRIMARY KEY,
|
|
||||||
uri TEXT NOT NULL,
|
|
||||||
title TEXT NOT NULL,
|
|
||||||
create_date TIMESTAMP NOT NULL,
|
|
||||||
update_date TIMESTAMP
|
|
||||||
)
|
|
||||||
"""
|
|
||||||
self.cursor.execute(query)
|
|
||||||
self.connection.commit()
|
|
||||||
|
|
||||||
def get_all_bookmarks(self):
|
|
||||||
"""
|
|
||||||
Returns all bookmarks in the database as a list.
|
|
||||||
"""
|
|
||||||
query = "SELECT * FROM bookmarks"
|
|
||||||
self.cursor.execute(query)
|
|
||||||
return self.cursor.fetchall()
|
|
||||||
|
|
||||||
def get_bookmark(self, bookmark_id):
|
|
||||||
"""
|
|
||||||
With the provided `bookmark_id`, the database will be
|
|
||||||
searched for a matching entry, with the row returned
|
|
||||||
if there is a match. If there is no match, None will
|
|
||||||
be returned.
|
|
||||||
|
|
||||||
`bookmark_id` is of type uuid.UUID()
|
|
||||||
"""
|
|
||||||
query = "SELECT * FROM bookmarks WHERE bookmark_id = ?"
|
|
||||||
self.cursor.execute(query, (bookmark_id, ))
|
|
||||||
return self.cursor.fetchone()
|
|
||||||
|
|
||||||
def save_bookmark(self, uri, title):
|
|
||||||
"""
|
|
||||||
Determines if the provided `uri` doesn't already
|
|
||||||
exist in the database adding a new entry if that
|
|
||||||
is the case. If the `uri` is already stored
|
|
||||||
(based on the generated UUID), the existing
|
|
||||||
entry's UUID will be returned instead.
|
|
||||||
"""
|
|
||||||
uri_uuid = uuid.uuid5(uuid.NAMESPACE_URL, uri)
|
|
||||||
|
|
||||||
bookmark_exists = self.get_bookmark(uri_uuid)
|
|
||||||
if bookmark_exists != None:
|
|
||||||
return bookmark_exists[0]
|
|
||||||
|
|
||||||
query = """
|
|
||||||
INSERT INTO bookmarks (
|
|
||||||
bookmark_id, uri, title, create_date
|
|
||||||
) VALUES (?, ?, ?, ?)
|
|
||||||
"""
|
|
||||||
self.cursor.execute(query, (uri_uuid, uri, title, datetime.datetime.now()))
|
|
||||||
self.connection.commit()
|
|
||||||
return uri_uuid
|
|
||||||
|
|
||||||
def delete_bookmark(self, bookmark_id):
|
|
||||||
"""
|
|
||||||
Removes the bookmark entry if it exists
|
|
||||||
|
|
||||||
`bookmark_id` is of type uuid.UUID()
|
|
||||||
|
|
||||||
Returns True upon successful removal.
|
|
||||||
Returns False upon unsuccessful removal.
|
|
||||||
"""
|
|
||||||
if self.get_bookmark(bookmark_id) != None:
|
|
||||||
query = "DELETE FROM bookmarks WHERE bookmark_id = ?"
|
|
||||||
self.cursor.execute(query, (bookmark_id, ))
|
|
||||||
self.connection.commit()
|
|
||||||
|
|
||||||
if self.get_bookmark(bookmark_id) == None:
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
def update_bookmark_title(self, bookmark_id, new_title):
|
|
||||||
"""
|
|
||||||
Takes the provided `bookmark_id`, searches the
|
|
||||||
database for the matching record, and if found
|
|
||||||
the title will be replaced with `new_title`.
|
|
||||||
|
|
||||||
`bookmark_id` is of type uuid.UUID()
|
|
||||||
|
|
||||||
Returns None if there is no matching bookmark.
|
|
||||||
"""
|
|
||||||
bookmark = self.get_bookmark(bookmark_id)
|
|
||||||
if bookmark != None:
|
|
||||||
query = """
|
|
||||||
UPDATE bookmarks
|
|
||||||
SET title = ?, update_date = ?
|
|
||||||
WHERE bookmark_id = ?
|
|
||||||
"""
|
|
||||||
self.cursor.execute(query, (new_title, datetime.datetime.now(), bookmark_id, ))
|
|
||||||
self.connection.commit()
|
|
||||||
return self.get_bookmark(bookmark_id)
|
|
||||||
return None
|
|
||||||
|
|
||||||
def update_bookmark_uri(self, bookmark_id, new_uri):
|
|
||||||
"""
|
|
||||||
Takes the provided `bookmark_id`, searches the
|
|
||||||
database for the matching record, and if found
|
|
||||||
the URI will be replaced with `new_uri`.
|
|
||||||
|
|
||||||
`bookmark_id` is of type uuid.UUID()
|
|
||||||
|
|
||||||
A new `bookmark_id` will be generated if the
|
|
||||||
`new_uri` is different than what was previously
|
|
||||||
stored. If the newly generated `bookmark_id` matches
|
|
||||||
an existing entry, this method will return False.
|
|
||||||
You may want to delete the old bookmark in this case.
|
|
||||||
|
|
||||||
Returns None if there is no matching bookmark.
|
|
||||||
"""
|
|
||||||
bookmark = self.get_bookmark(bookmark_id)
|
|
||||||
if bookmark != None:
|
|
||||||
query = """
|
|
||||||
UPDATE bookmarks
|
|
||||||
SET bookmark_id = ?, uri = ?, update_date = ?
|
|
||||||
WHERE bookmark_id = ?
|
|
||||||
"""
|
|
||||||
new_bookmark_id = uuid.uuid5(uuid.NAMESPACE_URL, new_uri)
|
|
||||||
if self.get_bookmark(new_bookmark_id) == None:
|
|
||||||
self.cursor.execute(query, (new_bookmark_id, new_uri, datetime.datetime.now(), bookmark_id, ))
|
|
||||||
self.connection.commit()
|
|
||||||
return self.get_bookmark(new_bookmark_id)
|
|
||||||
return False
|
|
||||||
return None
|
|
||||||
|
|
||||||
|
|
||||||
|
63
api/db/telethon_db.py
Normal file
63
api/db/telethon_db.py
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# Copyright 2020 - David Todd (c0de@c0defox.es)
|
||||||
|
# Licensed under the MIT License (https://opensource.org/licenses/MIT)
|
||||||
|
|
||||||
|
"""
|
||||||
|
This file contains the database for authorizing users
|
||||||
|
of the simple bookmark application
|
||||||
|
"""
|
||||||
|
|
||||||
|
import datetime
|
||||||
|
import sqlite3
|
||||||
|
import uuid
|
||||||
|
|
||||||
|
class TelethonDatabase(Database):
|
||||||
|
"""
|
||||||
|
This class contains various methods for interacting
|
||||||
|
with the database for the Telethon Authenticator
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, database):
|
||||||
|
"""
|
||||||
|
Sets up the database connection + cursor
|
||||||
|
as well as creates a new table if it doesn't
|
||||||
|
exist in the database that is provided via the
|
||||||
|
instantiation of this class
|
||||||
|
"""
|
||||||
|
super(TelethonDatabase, self).__init__(database)
|
||||||
|
|
||||||
|
# Automatically create the table if it doesn't
|
||||||
|
# already exist in the selected database
|
||||||
|
self._create_table()
|
||||||
|
|
||||||
|
def _create_table(self):
|
||||||
|
"""
|
||||||
|
Creates a table called `telethon`
|
||||||
|
that uses UUID as the primary key.
|
||||||
|
|
||||||
|
The UUID is a randomly generated UUID4
|
||||||
|
|
||||||
|
`client_ip` is the IP address that the server
|
||||||
|
recognized when the request was made
|
||||||
|
|
||||||
|
`auth_key` is the key that the user will use when
|
||||||
|
making API requests
|
||||||
|
|
||||||
|
`active` is a boolean value for whether or not to
|
||||||
|
authorize uses of `auth_key`
|
||||||
|
|
||||||
|
`create_date` and `update_date` are the datetimes
|
||||||
|
that the entry was created and updated, respectively.
|
||||||
|
"""
|
||||||
|
query = """
|
||||||
|
CREATE TABLE IF NOT EXISTS telethon (
|
||||||
|
uuid GUID PRIMARY KEY,
|
||||||
|
client_ip TEXT NOT NULL,
|
||||||
|
auth_key TEXT NOT NULL,
|
||||||
|
active BOOLEAN NOT NULL,
|
||||||
|
create_date TIMESTAMP NOT NULL,
|
||||||
|
update_date TIMESTAMP
|
||||||
|
)
|
||||||
|
"""
|
||||||
|
self.cursor.execute(query)
|
||||||
|
self.connection.commit()
|
Loading…
Reference in New Issue
Block a user