bookmarks_importer.py script added
This commit is contained in:
parent
2485f4ff33
commit
567af1c66e
2 changed files with 184 additions and 1 deletions
167
.dev/bookmarks_importer.py
Executable file
167
.dev/bookmarks_importer.py
Executable file
|
@ -0,0 +1,167 @@
|
|||
import sqlite3
|
||||
from bs4 import BeautifulSoup
|
||||
from PIL import Image, UnidentifiedImageError
|
||||
from io import BytesIO
|
||||
import re
|
||||
import base64
|
||||
from datetime import datetime, timezone
|
||||
import os
|
||||
import argparse
|
||||
|
||||
|
||||
"""
|
||||
Imports html bookmarks file into Flame.
|
||||
Tested only on Firefox html exports so far.
|
||||
|
||||
Usage:
|
||||
python3 bookmarks_importer.py --bookmarks <path to bookmarks file> --data <path to flame data dir>
|
||||
|
||||
"""
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('--bookmarks', type=str, required=True)
|
||||
parser.add_argument('--data', type=str, required=True)
|
||||
args = parser.parse_args()
|
||||
|
||||
bookmarks_path = args.bookmarks
|
||||
data_path = args.data
|
||||
created = datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3] + datetime.now().astimezone().strftime(" %z")
|
||||
updated = created
|
||||
if data_path[-1] != '/':
|
||||
data_path = data_path + '/'
|
||||
|
||||
|
||||
|
||||
|
||||
def Base64toPNG(codec, name):
|
||||
|
||||
"""
|
||||
Convert base64 encoded image to png file
|
||||
Reference: https://github.com/python-pillow/Pillow/issues/3400#issuecomment-428104239
|
||||
|
||||
Parameters:
|
||||
codec (str): icon in html bookmark format.e.g. 'data:image/png;base64,<image encoding>'
|
||||
name (str): name for export file
|
||||
|
||||
Returns:
|
||||
icon_name(str): name of png output E.g. 1636473849374--mybookmark.png
|
||||
None: if image not produced successfully
|
||||
|
||||
"""
|
||||
|
||||
try:
|
||||
unix_t = str(int(datetime.now(tz=timezone.utc).timestamp() * 1000))
|
||||
icon_name = unix_t + '--' + re.sub(r'\W+', '', name).lower() + '.png'
|
||||
image_path = data_path + 'uploads/' + icon_name
|
||||
if os.path.exists(image_path):
|
||||
return image_path
|
||||
base64_data = re.sub('^data:image/.+;base64,', '', codec)
|
||||
byte_data = base64.b64decode(base64_data)
|
||||
image_data = BytesIO(byte_data)
|
||||
img = Image.open(image_data)
|
||||
img.save(image_path, "PNG")
|
||||
return icon_name
|
||||
except UnidentifiedImageError:
|
||||
return None
|
||||
|
||||
|
||||
|
||||
|
||||
def FlameBookmarkParser(bookmarks_path):
|
||||
|
||||
"""
|
||||
Parses HTML bookmarks file
|
||||
Reference: https://stackoverflow.com/questions/68621107/extracting-bookmarks-and-folder-hierarchy-from-google-chrome-with-beautifulsoup
|
||||
|
||||
Parameters:
|
||||
bookmarks_path (str): path to bookmarks.html
|
||||
|
||||
Returns:
|
||||
None
|
||||
|
||||
"""
|
||||
|
||||
soup = BeautifulSoup()
|
||||
with open(bookmarks_path) as f:
|
||||
soup = BeautifulSoup(f.read(), 'lxml')
|
||||
|
||||
dt = soup.find_all('dt')
|
||||
folder_name =''
|
||||
for i in dt:
|
||||
n = i.find_next()
|
||||
if n.name == 'h3':
|
||||
folder_name = n.text
|
||||
continue
|
||||
else:
|
||||
url = n.get("href")
|
||||
website_name = n.text
|
||||
icon = n.get("icon")
|
||||
if icon != None:
|
||||
icon_name = Base64toPNG(icon, website_name)
|
||||
cat_id = AddFlameCategory(folder_name)
|
||||
AddFlameBookmark(website_name, url, cat_id, icon_name)
|
||||
|
||||
|
||||
|
||||
|
||||
def AddFlameCategory(cat_name):
|
||||
"""
|
||||
Parses HTML bookmarks file
|
||||
|
||||
Parameters:
|
||||
cat_name (str): category name
|
||||
|
||||
Returns:
|
||||
cat_id (int): primary key id of cat_name
|
||||
|
||||
"""
|
||||
|
||||
|
||||
|
||||
con = sqlite3.connect(data_path + 'db.sqlite')
|
||||
cur = con.cursor()
|
||||
count_sql = ("SELECT count(*) FROM categories WHERE name = ?;")
|
||||
cur.execute(count_sql, [cat_name])
|
||||
count = int(cur.fetchall()[0][0])
|
||||
if count > 0:
|
||||
getid_sql = ("SELECT id FROM categories WHERE name = ?;")
|
||||
cur.execute(getid_sql, [cat_name])
|
||||
cat_id = int(cur.fetchall()[0][0])
|
||||
return cat_id
|
||||
|
||||
is_pinned = 1
|
||||
|
||||
insert_sql = "INSERT OR IGNORE INTO categories(name, isPinned, createdAt, updatedAt) VALUES (?, ?, ?, ?);"
|
||||
cur.execute(insert_sql, (cat_name, is_pinned, created, updated))
|
||||
con.commit()
|
||||
|
||||
getid_sql = ("SELECT id FROM categories WHERE name = ?;")
|
||||
cur.execute(getid_sql, [cat_name])
|
||||
cat_id = int(cur.fetchall()[0][0])
|
||||
return cat_id
|
||||
|
||||
|
||||
|
||||
|
||||
def AddFlameBookmark(website_name, url, cat_id, icon_name):
|
||||
con = sqlite3.connect(data_path + 'db.sqlite')
|
||||
cur = con.cursor()
|
||||
if icon_name == None:
|
||||
insert_sql = "INSERT OR IGNORE INTO bookmarks(name, url, categoryId, createdAt, updatedAt) VALUES (?, ?, ?, ?, ?);"
|
||||
cur.execute(insert_sql, (website_name, url, cat_id, created, updated))
|
||||
con.commit()
|
||||
else:
|
||||
insert_sql = "INSERT OR IGNORE INTO bookmarks(name, url, categoryId, icon, createdAt, updatedAt) VALUES (?, ?, ?, ?, ?, ?);"
|
||||
cur.execute(insert_sql, (website_name, url, cat_id, icon_name, created, updated))
|
||||
con.commit()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
FlameBookmarkParser(bookmarks_path)
|
||||
|
18
README.md
18
README.md
|
@ -106,6 +106,7 @@ Follow instructions from wiki: [Installation without Docker](https://github.com/
|
|||
- Bookmarks
|
||||
- Create, update, delete and organize bookmarks and categories using GUI
|
||||
- Pin your favourite categories to the homescreen
|
||||
- Import html bookmarks (experimental)
|
||||
|
||||
![Homescreen screenshot](./.github/_bookmarks.png)
|
||||
|
||||
|
@ -120,6 +121,21 @@ Follow instructions from wiki: [Installation without Docker](https://github.com/
|
|||
|
||||
## Usage
|
||||
|
||||
### Import HTML Bookmarks (Experimental)
|
||||
- Requirements
|
||||
- Python3
|
||||
- pip packages: Pillow, beautifulsoup4
|
||||
- Backup your db.sqlite before running script!
|
||||
- Known Issues:
|
||||
- generated icons are sometimes incorrect
|
||||
```shell
|
||||
|
||||
pip3 install Pillow, beautifulsoup4
|
||||
|
||||
cd flame/.dev
|
||||
python3 bookmarks_importer.py --bookmarks <path to bookmarks.html> --data <path to flame data folder>
|
||||
```
|
||||
|
||||
### Search bar
|
||||
|
||||
#### Searching
|
||||
|
@ -202,4 +218,4 @@ metadata:
|
|||
|
||||
### Custom CSS and themes
|
||||
|
||||
See project wiki for [Custom CSS](https://github.com/pawelmalak/flame/wiki/Custom-CSS) and [Custom theme with CSS](https://github.com/pawelmalak/flame/wiki/Custom-theme-with-CSS).
|
||||
See project wiki for [Custom CSS](https://github.com/pawelmalak/flame/wiki/Custom-CSS) and [Custom theme with CSS](https://github.com/pawelmalak/flame/wiki/Custom-theme-with-CSS).
|
||||
|
|
Loading…
Reference in a new issue