Создайте свою собственную библиотеку ссылок
Мне нравится читать много статей на самые разные темы. Как это принято среди технических специалистов, я хочу узнать о большем количестве вещей, чем у меня есть время. В результате мне нужно где-то сохранять статьи, чтобы вернуться и прочитать их, когда у меня будет время.
Утром я обычно просматриваю Hacker News, свой Medium Daily Digest, свою ленту в Twitter и, возможно, некоторые информационные бюллетени Substack. Я прочитаю некоторые статьи и добавлю в закладки много статей, чтобы прочитать их позже. Раньше я использовал закладки браузера, но это быстро вышло из-под контроля.
Мое самое последнее решение состояло в том, чтобы использовать расширение браузера Obsidian Clipper, которое сохраняет статьи в ежедневную заметку в моем хранилище Obsidian Vault. Это хорошо работает, так как я могу пометить их темой и найти их позже. Моя проблема с этим заключается в том, что трудно увидеть сводку статей и отличить прочитанное от непрочитанного. Это то, что побудило меня реализовать свое решение.
В этой статье предполагается, что читатель немного знаком с Python, AWS и SQL, и будет объяснено, как сохранять закладки URL в вашей базе данных с помощью букмарклета. В частности, реализация использует Flask, AWS Elastic Beanstalk и MySQL.
Первый шаг — развертывание приложения Flask на Beanstalk. Документация AWS довольно хороша, если у вас ее еще нет. Имейте в виду, однако, что установка Elastic Beanstalk CLI может быть немного сложной в зависимости от того, какой тип машины вы используете.
Когда у вас есть работающее приложение и вы изменили основные маршруты и шаблоны в соответствии со своими потребностями, вам нужно настроить базу данных. Первый шаг здесь — перейти на панель инструментов Elastic Beanstalk и найти среду, в которой работает ваше приложение Flask. На боковой панели щелкните Конфигурация. Прокрутите вниз, где написано «База данных».
Чтобы убедиться, что вы (скорее всего) остаетесь в рамках уровня бесплатного пользования AWS-RDS, выберите MySQL на db.t2.micro
инстансе с низкой доступностью. На следующем шаге вам понадобится конечная точка базы данных, имя пользователя и пароль. Так что обратите внимание на это. Кроме того, пока вы здесь, вы должны зайти в группу безопасности и разрешить входящий трафик с вашего IP, чтобы вы могли подключаться к базе данных при локальном запуске сервера.
Теперь мы создадим базу данных и таблицу, которая будет использоваться для хранения ваших закладок. Вам нужно будет установить MySQL на свой локальный компьютер. Для меня это было сделано с.
brew install mysql-client export PATH=”/usr/local/opt/mysql-client/bin:$PATH” brew install mysql
Как только это будет сделано, вы можете подключиться к своей конечной точке и создать базу данных и таблицу. После первой команды вам будет предложено ввести пароль.
mysql -h <YOUR-ENDPOINT> -u <USERNAME> -p CREATE DATABASE MyDB; USE MyDB; CREATE TABLE bookmarks (id INT NOT NULL PRIMARY KEY, url VARCHAR(64), category VARCHAR(40), is_read BOOL, created_date DATETIME);
Теперь мы готовы начать работу в IDE!
Самое первое, что нужно сделать здесь, это последний шаг в настройке вашей базы данных. В том же каталоге, что и application.py, и каталог .elasticbeanstalk
создайте новый каталог с именем .ebextensions
. Чтобы MySQL работал на вашем экземпляре эластичных вычислений, создайте новый файл с именем 01_packages.config
и добавьте следующее:
packages: yum: python3-devel: [] mariadb-devel: []
Хорошо, теперь мы можем начать использовать Python. Активируйте виртуальную среду и
pip install flask-mysqldb
В application.py
вам понадобится что-то вроде этого:
from flask_mysqldb import MySQL # Create Flask Application application = Flask(__name__) application.secret_key = dotenv_values(‘.env’)[‘APP_SECRET’] # initialize the db application.config['MYSQL_HOST'] = dotenv_values('.env')['DB_ENDPOINT'] application.config['MYSQL_USER'] = dotenv_values('.env')['DB_USERNAME'] application.config['MYSQL_PASSWORD'] = dotenv_values('.env')['DB_PASSWORD'] application.config['MYSQL_DB'] = 'MyDB' db = MySQL(application) import source.routes
Мне нравится держать routes.py
в чистоте, насколько это возможно, поэтому давайте начнем с bookmarks.py, где мы определим класс Bookmark
и некоторые функции для управления вашими закладками.
Класс Bookmark
принимает URL-адрес и категорию при инициализации, назначает текущую дату и время для created_date
и предполагает, что вы еще не читали статью. В настоящее время я не использую метод категорий. Я планирую поиграть с некоторыми моделями машинного обучения, чтобы увидеть, насколько хорошо они могут помечать или классифицировать статьи, которые я им подаю.
Класс Bookmark
также имеет метод для вставки объекта в базу данных. Когда вы просматриваете закладки на своем сайте, там будет флажок.
Если вы установите флажок и отправите форму, функция update_read_bookmarks()
обновит базу данных.
Функция get_all_unread_bookmarks()
извлекает данные, которые мы хотим отобразить в bookmarks.html.
from application import db import datetime class Bookmark(): def __init__(self, url, category) -> None: self.url = url self.category = category self.created_date = datetime.datetime.now() self.is_read = False def insert(self): query = f"""INSERT INTO bookmarks (url, category, created_date, is_read) VALUES ('{self.url}', '{self.category}', '{self.created_date}', {self.is_read});""" cursor = db.connection.cursor() cursor.execute(query) db.connection.commit() cursor.close() def update_read_bookmarks(bookmarks_to_update): query = f"""UPDATE bookmarks SET is_read = TRUE WHERE id IN ({bookmarks_to_update});""" cursor = db.connection.cursor() cursor.execute(query) db.connection.commit() cursor.close() def get_all_unread_bookmarks(): query = """SELECT * FROM bookmarks WHERE is_read = False ORDER BY created_date DESC;""" cursor = db.connection.cursor() cursor.execute(query) db.connection.commit() bookmarks = cursor.fetchall() cursor.close() return bookmarks
Хорошо, теперь все готово для создания маршрутов и запуска!
В routes.py
у вас будет что-то вроде того, что показано ниже. Маршрут закладки — это то, что используется в букмарклете, поэтому он ищет суффикс, который выглядит так: ?url=<URL TO BOOKMARK>
. Когда вы используете букмарклет для добавления URL-адреса в закладки, он приведет вас к маршруту /bookmark/show
, на который вы можете сослаться из index.html.
Все, что он делает, — это запрашивает базу данных о непрочитанных закладках и отображает их в таблице. Маршрут /update_bookmarks
— это действие, связанное с формой в bookmarks.html, и оно будет искать поля, которые были проверены, чтобы база данных обновлялась должным образом.
from application import db from source.bookmarks import Bookmark, get_all_unread_bookmarks, update_read_bookmarks @application.route("/bookmark", methods=["GET", "POST"]) def bookmark(): print(request.args) if token := request.args.get("token"): print("Found the token") if token == dotenv_values(".env")["BOOKMARK_TOKEN"]: if url := request.args.get("url"): bookmark = Bookmark(url=url, category="self") bookmark.insert() return redirect(url) else: print("The token was wrong") return welcome() else: print("Didnt find the token") return welcome() return bookmark_show() @application.route("/bookmark/show", methods=["GET", "POST"]) @login_required def bookmark_show(): bookmarks = get_all_unread_bookmarks() return render_template("bookmarks.html", data=bookmarks) @application.route("/update_bookmarks", methods=["GET", "POST"]) @login_required def update_bookmarks(): new_read_bookmarks = [str(bookmark) for bookmark in request.form] bookmarks_for_query = ",".join(new_read_bookmarks) update_read_bookmarks(bookmarks_for_query) bookmarks = get_all_unread_bookmarks() return render_template("bookmarks.html", data=bookmarks)
Я использую Flask-Login, чтобы убедиться, что я единственный, кто может взаимодействовать с базой данных. На данный момент я единственный, кто может даже просматривать закладки, но со временем я открою это, чтобы другие люди могли видеть мою «библиотеку ссылок».
Честно говоря, мне очень не хватает документации и руководств по использованию Flask-Login с MySQL, поэтому я собираюсь написать еще одну статью о том, как использовать Flask-Login с зашифрованными паролями в базе данных MySQL.
Чтобы убедиться, что я единственный, кто может добавить закладку, у меня есть токен в качестве переменной среды. У меня есть этот токен в запросе, который приходит из букмарклета; если они не совпадают, закладка не добавляется.
Последним шагом будет создание bookmarks.html. Я могу быть слишком утилитарным для своего же блага, но моя выглядит примерно так:
<html> <body> <form action="/update_bookmarks" method="post"> <input type="submit"> <table border="1"> <tr border="1"> <th>URL</th> <th>Category</th> <th>Created Date</th> <th>Read</th> </tr> {% for item in data %} <br> <tr border="1"> <td border="1"> <a href="{{item[1]}}"> {{item[1]}} </a> </td> <td border="1">{{item[2]}}</td> <td border="1">{{item[4]}}</td> {% if item[3] %} <td><input type="checkbox" name="{{ item[0] }}" checked /> </td> {% else %} <td><input type="checkbox" name="{{ item[0] }}" /> </td> {% endif %} </tr> {% endfor %} </table> </form> </body> </html>
Последнее, что вам понадобится, это букмарклет, а именно:
javascript:location.href=’http://127.0.0.1:5000/bookmark?url='+location.href+'&token=<TOKEN>';
После того, как вы закончите тестирование, используйте свой домен вместо локального хоста, и все будет готово!
У меня большие планы на это приложение, поэтому, если вам интересно, подпишитесь на меня, чтобы вскоре прочитать о следующих шагах, или свяжитесь со мной в LinkedIn!
- Дайте приложению номер телефона, чтобы я мог добавлять закладки с помощью текстового сообщения.
- Используйте машинное обучение и обработку естественного языка для извлечения ключевых слов и классификации статей.
- Добавить поиск, фильтрацию, пагинацию и т.д.