Skip to content

Commit

Permalink
Merge pull request #145 from pawelmalak/feature
Browse files Browse the repository at this point in the history
Version 1.7.4
  • Loading branch information
pawelmalak authored Nov 8, 2021
2 parents 88694c7 + 4f2ba0a commit 08afaec
Show file tree
Hide file tree
Showing 65 changed files with 1,536 additions and 1,114 deletions.
File renamed without changes.
166 changes: 166 additions & 0 deletions .dev/bookmarks_importer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
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)
9 changes: 9 additions & 0 deletions .dev/getMdi.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// Script to get all icon names from materialdesignicons.com
const getMdi = () => {
const icons = document.querySelectorAll('#icons div span');
const names = [...icons].map((icon) => icon.textContent.replace('mdi-', ''));
const output = names.map((name) => ({ name }));
output.pop();
const json = JSON.stringify(output);
console.log(json);
};
2 changes: 1 addition & 1 deletion .env
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
PORT=5005
NODE_ENV=development
VERSION=1.7.3
VERSION=1.7.4
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
node_modules
data
public
!client/public
build.sh
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
### v1.7.4 (2021-11-08)
- Added option to set custom greetings and date ([#103](https://github.com/pawelmalak/flame/issues/103))
- Fallback to web search if local search has zero results ([#129](https://github.com/pawelmalak/flame/issues/129))
- Added iOS "Add to homescreen" icon ([#131](https://github.com/pawelmalak/flame/issues/131))
- Added experimental script to import bookmarks ([#141](https://github.com/pawelmalak/flame/issues/141))
- Added 3 new themes

### v1.7.3 (2021-10-28)
- Fixed bug with custom CSS not updating

Expand Down
10 changes: 7 additions & 3 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
FROM node:14-alpine

RUN apk update && apk add --no-cache nano curl
FROM node:14 as builder

WORKDIR /app

Expand All @@ -18,6 +16,12 @@ RUN mkdir -p ./public ./data \
&& mv ./client/build/* ./public \
&& rm -rf ./client

FROM node:14-alpine

COPY --from=builder /app /app

WORKDIR /app

EXPOSE 5005

ENV NODE_ENV=production
Expand Down
20 changes: 11 additions & 9 deletions Dockerfile.multiarch
Original file line number Diff line number Diff line change
@@ -1,27 +1,29 @@
FROM node:14-alpine

RUN apk update && apk add --no-cache nano curl
FROM node:14 as builder

WORKDIR /app

COPY package*.json ./

RUN apk --no-cache --virtual build-dependencies add python make g++ \
&& npm install --production
RUN npm install --production

COPY . .
COPY . .

RUN mkdir -p ./public ./data \
&& cd ./client \
&& npm install --production \
&& npm run build \
&& cd .. \
&& mv ./client/build/* ./public \
&& rm -rf ./client \
&& apk del build-dependencies
&& rm -rf ./client

FROM node:14-alpine

COPY --from=builder /app /app

WORKDIR /app

EXPOSE 5005

ENV NODE_ENV=production

CMD ["node", "server.js"]
CMD ["node", "server.js"]
Loading

0 comments on commit 08afaec

Please sign in to comment.