Skip to content

Commit

Permalink
refactor: tidy codes
Browse files Browse the repository at this point in the history
Signed-off-by: Jack Cherng <jfcherng@gmail.com>
  • Loading branch information
jfcherng committed May 17, 2024
1 parent a39b0f8 commit bc0bec6
Show file tree
Hide file tree
Showing 12 changed files with 76 additions and 2,940 deletions.
3 changes: 2 additions & 1 deletion .gitattributes
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ mkdocs.yml export-ignore
mypy.ini export-ignore
pyproject.toml export-ignore
pyrightconfig.json export-ignore
requirements.txt export-ignore
requirements-* export-ignore
requirements.* export-ignore
scripts/ export-ignore
stubs/ export-ignore
tests/ export-ignore
Expand Down
7 changes: 5 additions & 2 deletions .github/workflows/python.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ jobs:
name: ${{ matrix.python-version }}
runs-on: ${{ matrix.os }}

env:
UV_SYSTEM_PYTHON: 1

strategy:
matrix:
os: ['ubuntu-latest']
Expand All @@ -44,8 +47,8 @@ jobs:
- name: Install dependencies
run: |
python -m pip install -U uv
make install-dev
- name: Do linting
run: |
make UV_INSTALL_FLAGS="--system" \
install ci-check
make ci-check
9 changes: 9 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,18 @@ all:
install:
uv pip install $(UV_INSTALL_FLAGS) -r requirements.txt

.PHONY: install-dev
install-dev:
uv pip install $(UV_INSTALL_FLAGS) -r requirements-dev.txt

.PHONY: pip-compile
pip-compile:
uv pip compile --upgrade requirements.in -o requirements.txt
uv pip compile --upgrade requirements-dev.in -o requirements-dev.txt

.PHONY: update-changelog
update-changelog:
git cliff --output=CHANGELOG.md

.PHONY: ci-check
ci-check:
Expand Down
4 changes: 2 additions & 2 deletions plugin/commands/select_emoji.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import sublime
import sublime_plugin

from ..constants import DB_GENERATOR_REVISION
from ..constants import DB_REVISION
from ..emoji import EmojiDatabase, get_emoji_db


Expand All @@ -31,5 +31,5 @@ def callback(selected: int) -> None:
if selected >= 0:
self.view.run_command("insert", {"characters": db[selected].char})

db = get_emoji_db(DB_GENERATOR_REVISION)
db = get_emoji_db(DB_REVISION)
window.show_quick_panel(emoji_db_to_quick_panel_items(db), callback)
6 changes: 4 additions & 2 deletions plugin/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@

import sublime

assert __package__

PACKAGE_NAME = __package__.partition(".")[0]

DB_FILE_IN_PACKAGE = f"Packages/{PACKAGE_NAME}/data/emoji-test.txt"
DB_FILE_CACHED = Path(sublime.cache_path()) / f"{PACKAGE_NAME}/db.json"
DB_GENERATOR_REVISION = 1
DB_FILE_CACHED = Path(sublime.cache_path()) / f"{PACKAGE_NAME}/db.bin"
DB_REVISION = 2
12 changes: 12 additions & 0 deletions plugin/data_types.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
from __future__ import annotations

import sys
from enum import Enum

if sys.version_info >= (3, 11):
from enum import StrEnum
else:

class StrEnum(str, Enum):
__str__ = str.__str__ # type: ignore
__format__ = str.__format__ # type: ignore
61 changes: 28 additions & 33 deletions plugin/emoji.py
Original file line number Diff line number Diff line change
@@ -1,45 +1,45 @@
from __future__ import annotations

import json
import pickle
import re
from collections.abc import Iterable, Iterator, Sequence
from dataclasses import asdict, dataclass, field
from enum import Enum
from functools import lru_cache
from typing import Any

import sublime

from .constants import DB_FILE_CACHED, DB_FILE_IN_PACKAGE, DB_GENERATOR_REVISION
from .constants import DB_FILE_CACHED, DB_FILE_IN_PACKAGE, DB_REVISION
from .data_types import StrEnum
from .utils import pp_error, pp_info, pp_warning


@lru_cache
def get_emoji_db(generator_revision: int) -> EmojiDatabase:
def _create_db_cache() -> EmojiDatabase:
def get_emoji_db(db_revision: int) -> EmojiDatabase:
def _create_cache() -> EmojiDatabase:
pp_info(f"Create database cache: {DB_FILE_CACHED}")
db_content = sublime.load_resource(DB_FILE_IN_PACKAGE)
db = EmojiDatabase.from_content(db_content)
DB_FILE_CACHED.parent.mkdir(parents=True, exist_ok=True)
DB_FILE_CACHED.write_text(db.to_json(), encoding="utf-8")
DB_FILE_CACHED.write_bytes(db.to_pickle())
return db

def _load_db_cache() -> EmojiDatabase | None:
def _load_cache() -> EmojiDatabase | None:
try:
db_dict: dict[str, Any] = json.loads(DB_FILE_CACHED.read_bytes())
db_dict: dict[str, Any] = pickle.loads(DB_FILE_CACHED.read_bytes())
db = EmojiDatabase.from_dict(db_dict)
if db.generator_revision == generator_revision:
if db.db_revision == db_revision:
pp_info(f"Load database cache: {DB_FILE_CACHED}")
return db
pp_warning("Mismatched database cache revision...")
except Exception as e:
pp_error(f"Failed to load database cache: {e}")
return None

return _load_db_cache() or _create_db_cache()
return _load_cache() or _create_cache()


class EmojiStatus(str, Enum):
class EmojiStatus(StrEnum):
COMPONENT = "component"
FULLY_QUALIFIED = "fully-qualified"
MINIMALLY_QUALIFIED = "minimally-qualified"
Expand Down Expand Up @@ -118,21 +118,21 @@ def str_to_code_points(s: str) -> list[str]:

@dataclass
class EmojiDatabase:
db_revision: int = 0
date: str = ""
version: str = ""
emojis: list = field(default_factory=list)
generator_revision: int = 0
emojis: list[Emoji] = field(default_factory=list)

_re_version = re.compile(r"^#\s*Version:\s*(?P<version>.*)$")
_RE_VERSION = re.compile(r"^#\s*Version:\s*(?P<version>.*)$")
"""Matches `# Version: 15.1`."""
_re_date = re.compile(r"^#\s*Date:\s*(?P<date>.*)$")
_RE_DATE = re.compile(r"^#\s*Date:\s*(?P<date>.*)$")
"""Matches `# Date: 2023-06-05, 21:39:54 GMT`."""

def __getitem__(self, index: int) -> Emoji:
return self.emojis[index]

def __hash__(self) -> int:
return hash((self.date, self.version, self.generator_revision))
return hash((self.db_revision, self.date, self.version))

def __iter__(self) -> Iterator[Emoji]:
return iter(self.emojis)
Expand All @@ -144,9 +144,9 @@ def __str__(self) -> str:
"""Returns a string like "emoji-test.txt"."""
data = "\n".join(map(str, self.emojis))
return f"""
# DB Revision: {self.db_revision}
# Date: {self.date}
# Version: {self.version}
# Generator Version: {self.generator_revision}
{data}
# EOF
"""
Expand All @@ -158,34 +158,29 @@ def from_content(cls, content: str) -> EmojiDatabase:
@classmethod
def from_dict(cls, db: dict[str, Any]) -> EmojiDatabase:
return cls(
db_revision=db.get("db_revision", DB_REVISION),
date=db.get("date", ""),
version=db.get("version", ""),
emojis=list(map(Emoji.from_dict, db.get("emojis", []))),
generator_revision=db.get("generator_revision", 0),
)

@classmethod
def from_lines(cls, lines: Iterable[str]) -> EmojiDatabase:
collection = cls()
collection = cls(db_revision=DB_REVISION)
for line in lines:
if e := Emoji.from_line(line):
collection.emojis.append(e)
if emoji := Emoji.from_line(line):
collection.emojis.append(emoji)
continue
if m := cls._re_version.fullmatch(line):
if m := cls._RE_VERSION.fullmatch(line):
collection.version = m.group("version").strip()
continue
if m := cls._re_date.fullmatch(line):
if m := cls._RE_DATE.fullmatch(line):
collection.date = m.group("date").strip()
continue
return collection

def to_json(self, *, pretty: bool = False) -> str:
if pretty:
kwargs: dict[str, Any] = {"indent": "\t"}
else:
kwargs = {"separators": (",", ":")}
return json.dumps(
dict(asdict(self), generator_revision=DB_GENERATOR_REVISION),
ensure_ascii=False,
**kwargs,
)
def to_dict(self) -> dict[str, Any]:
return asdict(self)

def to_pickle(self) -> bytes:
return pickle.dumps(self.to_dict(), protocol=pickle.HIGHEST_PROTOCOL)
Loading

0 comments on commit bc0bec6

Please sign in to comment.