diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..56fd16c --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,90 @@ +name: package build + +on: + push: + branches: [ main ] + pull_request: + branches: [ main ] + +jobs: + build-linux: + runs-on: ubuntu-latest + strategy: + matrix: + python-version: + - '3.10.14' + - '3.11.9' + - '3.12.4' + + defaults: + run: + shell: bash -e {0} + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + submodules: 'true' + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python-version }} + + #---------------------------------------------- + # ----- install & configure poetry ----- + #---------------------------------------------- + - name: Install Poetry + uses: snok/install-poetry@v1 + with: + virtualenvs-create: true + virtualenvs-in-project: true + installer-parallel: true + + #---------------------------------------------- + # load cached venv if cache exists + #---------------------------------------------- + - name: Load cached venv + id: cached-poetry-dependencies + uses: actions/cache@v3 + with: + path: .venv + key: venv-${{ runner.os }}-${{ steps.setup-python.outputs.python-version }}-${{ hashFiles('**/poetry.lock') }} + #---------------------------------------------- + # install dependencies if cache does not exist + #---------------------------------------------- + - name: Install dependencies + if: steps.cached-poetry-dependencies.outputs.cache-hit != 'true' + run: poetry install --no-interaction --no-root + #---------------------------------------------- + # install your root project, if required + #---------------------------------------------- + - name: Install project + run: poetry install --no-interaction + #---------------------------------------------- + # run test suite + #---------------------------------------------- + - name: Install pytest + run: poetry add --dev pytest coverage + + - name: Run tests + run: | + source .venv/bin/activate + #poetry run pytest + poetry run coverage run -m pytest + poetry run coverage report --fail-under=60 + poetry run coverage xml -o coverage.xml + + - name: Upload coverage report + uses: actions/upload-artifact@v3 + with: + name: coverage-report-${{ github.job }}-${{ github.run_number }} + path: coverage.xml + + - name: Build package + run: | + poetry build + + - name: Verify build + run: | + pip install dist/*.whl diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..727b81d --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,125 @@ +name: Automated Release + +on: + release: + types: [created] + +jobs: + build-and-release: + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + token: ${{ secrets.GITHUB_TOKEN }} + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.10.14' + + - name: Install Poetry + uses: snok/install-poetry@v1 + with: + virtualenvs-create: true + virtualenvs-in-project: true + installer-parallel: true + + #---------------------------------------------- + # load cached venv if cache exists + #---------------------------------------------- + - name: Load cached venv + id: cached-poetry-dependencies + uses: actions/cache@v3 + with: + path: .venv + key: venv-${{ runner.os }}-${{ steps.setup-python.outputs.python-version }}-${{ hashFiles('**/poetry.lock') }} + + #---------------------------------------------- + # install dependencies if cache does not exist + #---------------------------------------------- + - name: Install dependencies + if: steps.cached-poetry-dependencies.outputs.cache-hit != 'true' + run: poetry install --no-interaction --no-root + #---------------------------------------------- + # install your root project, if required + #---------------------------------------------- + - name: Install project + run: poetry install --no-interaction + #---------------------------------------------- + # run test suite + #---------------------------------------------- + - name: Install pytest + run: poetry add --dev pytest coverage + + - name: Run tests + run: | + source .venv/bin/activate + poetry run pytest + + # Configure git for committing version bump + - name: Configure git for committing version bump + run: | + git config --global user.name "github-actions[bot]" + git config --global user.email "github-actions[bot]@users.noreply.github.com" + + # Bump version + - name: Bump version + id: bump_version + run: | + NEW_VERSION=$(poetry version patch | awk '{print $NF}') + echo "New version: $NEW_VERSION" + echo "new_version=$NEW_VERSION" >> $GITHUB_ENV + git add pyproject.toml + git commit -m "Bump version to $NEW_VERSION" + + - name: Push version bump + run: | + git push origin HEAD:main + + # build the package after bumping version + - name: Build package + run: poetry build + + + - name: Delete existing tag (if any) + run: | + git tag -d v${{ env.new_version }} || true + git push origin :refs/tags/v${{ env.new_version }} || true + + - name: Create and push new tag + run: | + git tag -a v${{ env.new_version }} -m "Release v${{ env.new_version }}" + git push origin v${{ env.new_version }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Install GitHub CLI + run: | + sudo apt-get install gh + + - name: Create GitHub release + run: | + gh release create v${{ env.new_version }} --generate-notes + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + + - name: Upload assets to release + run: | + gh release upload v${{ env.new_version }} dist/*.whl dist/*.tar.gz + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + # Delete latest draft release + - name: Delete latest draft release + run: | + latest_release=$(gh release list --draft --limit 1 --json name,url | jq -r '.[0] | select(.name | test("^v[0-9]+\\.[0-9]+\\.[0-9]+(-\\w+)?")) | .url') + if [ -n "$latest_release" ]; then + gh release delete "$latest_release" -y + else + echo "No draft release found to delete." + fi + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/koreader_highlights_2_anki/__main__.py b/koreader_highlights_2_anki/__main__.py index b4583bf..4a687cf 100755 --- a/koreader_highlights_2_anki/__main__.py +++ b/koreader_highlights_2_anki/__main__.py @@ -500,56 +500,6 @@ def parse_lua_highlights_bookmarks(filepath): return metadata -# def parse_lua_highlights(filepath): -# """ -# Parses a Lua file to extract highlighted bookmarks and book metadata. - -# Args: -# filepath (str): Path to the Lua file. - -# Returns: -# dict: Dictionary containing the highlighted bookmarks, book title, and author. -# Returns None if no highlights are found. -# """ -# # Create a Lua runtime environment -# lua = LuaRuntime(unpack_returned_tuples=True) - -# # Load the Lua file content -# with open(filepath, 'r', encoding='utf-8') as file: -# lua_content = file.read() - -# # Evaluate the Lua content -# lua_table = lua.execute(lua_content) - -# # Extract 'bookmarks' and filter for highlighted entries -# bookmarks = lua_table['bookmarks'] -# highlighted_bookmarks = [] -# if bookmarks is None: -# return None - -# for bookmark in bookmarks.values(): -# if bookmark['highlighted']: -# highlighted_bookmarks.append({ -# 'chapter': bookmark['chapter'], -# 'datetime': bookmark['datetime'], -# 'notes': bookmark['notes'], -# }) - -# # Extract book metadata (authors, title) -# metadata = { -# 'title': lua_table['stats']['title'], -# 'authors': lua_table['stats']['authors'], -# 'language': lua_table['stats']['language'], -# 'bookmarks': highlighted_bookmarks -# } - -# # Return None if no highlighted bookmarks found -# if not highlighted_bookmarks: -# return None - -# return metadata - - def main(): """ Main function to scan directory for KOREADER metadata files and create Anki flashcards . diff --git a/pyproject.toml b/pyproject.toml index 6e6a96e..4689695 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -31,8 +31,6 @@ coverage = "^7.5.3" pre-commit = "^3.7.1" poetry-pre-commit-plugin = "^0.1.2" - - [tool.pre_commit] version = "2.3.0" config = ".pre-commit-config.yaml" diff --git a/test_koreader_highlights_2_anki/ressources/Ali Abdaal - Feel-Good Productivity_ How to Do More of What Matters to You.sdr/metadata.epub.lua b/test_koreader_highlights_2_anki/resources/Ali Abdaal - Feel-Good Productivity_ How to Do More of What Matters to You.sdr/metadata.epub.lua similarity index 100% rename from test_koreader_highlights_2_anki/ressources/Ali Abdaal - Feel-Good Productivity_ How to Do More of What Matters to You.sdr/metadata.epub.lua rename to test_koreader_highlights_2_anki/resources/Ali Abdaal - Feel-Good Productivity_ How to Do More of What Matters to You.sdr/metadata.epub.lua diff --git a/test_koreader_highlights_2_anki/ressources/Thinking, Fast and Slow - Daniel Kahneman.sdr/metadata.epub.lua b/test_koreader_highlights_2_anki/resources/Thinking, Fast and Slow - Daniel Kahneman.sdr/metadata.epub.lua similarity index 100% rename from test_koreader_highlights_2_anki/ressources/Thinking, Fast and Slow - Daniel Kahneman.sdr/metadata.epub.lua rename to test_koreader_highlights_2_anki/resources/Thinking, Fast and Slow - Daniel Kahneman.sdr/metadata.epub.lua diff --git a/test_koreader_highlights_2_anki/test_main.py b/test_koreader_highlights_2_anki/test_main.py new file mode 100644 index 0000000..661ec5c --- /dev/null +++ b/test_koreader_highlights_2_anki/test_main.py @@ -0,0 +1,47 @@ +import unittest +import os + +from koreader_highlights_2_anki.__main__ import parse_lua_highlights_annotations + + +ROOT_DIR = os.path.dirname(os.path.abspath(__file__)) + + +class TestParseLuaHighlightsAnnotations(unittest.TestCase): + + def test_parse_lua_highlights_annotations(self): + # Define the path to the Lua file + filepath = os.path.join("Ali Abdaal - Feel-Good Productivity_ How to Do More of What Matters to You.sdr/metadata.epub.lua") + filepath = os.path.join(ROOT_DIR, "resources", filepath) + + # Call the function with the actual Lua file + result = parse_lua_highlights_annotations(filepath) + + # Expected output structure (modify according to your actual expected output) + expected_metadata = { + "title": "Feel-good Productivity : How to Do More of What Matters to You (9781250865052)", + "authors": "Abdaal, Ali", + "language": "en-US", + "entries": [ + {'chapter': 'Introduction', + 'datetime': '2024-08-30 12:31:05', + 'notes': 'when we’re in a positive mood, we tend to consider a broader range ' + 'of actions, be more open to new experiences, and better integrate ' + 'the information we receive', + 'page': 14}, + {'chapter': 'Introduction', + 'datetime': '2024-08-30 12:31:27', + 'notes': 'feeling good boosts our creativity –', + 'page': 15} + ], + } + + self.assertIsNotNone(result) + self.assertEqual(result["title"], expected_metadata["title"]) + self.assertEqual(result["authors"], expected_metadata["authors"]) + self.assertEqual(result["language"], expected_metadata["language"]) + self.assertEqual(result["entries"], expected_metadata["entries"]) + + +if __name__ == '__main__': + unittest.main()