diff --git a/CHANGELOG.md b/CHANGELOG.md index 7cdf72f..c9dae07 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,7 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - refactor: removed old source code - add: python 3.7 support -- init: `cursor`, `parser` and `writer` module +- init: `cursor`, `packer`, `parser` and `writer` module - 'Twitter' and 'Download' links added on PYPI page ### Changed diff --git a/src/clickgen/packer/__init__.py b/src/clickgen/packer/__init__.py new file mode 100644 index 0000000..f28a7a0 --- /dev/null +++ b/src/clickgen/packer/__init__.py @@ -0,0 +1,7 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +from clickgen.packer.windows import pack_win +from clickgen.packer.x11 import pack_x11 + +__all__ = ["pack_win", "pack_x11"] diff --git a/src/clickgen/packer/__init__.pyi b/src/clickgen/packer/__init__.pyi new file mode 100644 index 0000000..8362c71 --- /dev/null +++ b/src/clickgen/packer/__init__.pyi @@ -0,0 +1,2 @@ +from clickgen.packer.windows import pack_win as pack_win +from clickgen.packer.x11 import pack_x11 as pack_x11 diff --git a/src/clickgen/packer/windows.py b/src/clickgen/packer/windows.py new file mode 100644 index 0000000..381f16d --- /dev/null +++ b/src/clickgen/packer/windows.py @@ -0,0 +1,179 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +"""Generate Windows install and uninstall files. + +.. moduleauthor:: Kaiz Khatri +""" + +from pathlib import Path +from string import Template +from typing import Dict, List, Optional, Set + +FILE_TEMPLATES: Dict[str, Template] = { + "install.inf": Template( + """[Version] +signature="$CHICAGO$" +$comment + +[DefaultInstall] +CopyFiles = Scheme.Cur, Scheme.Txt +AddReg = Scheme.Reg + +[DestinationDirs] +Scheme.Cur = 10,"%CUR_DIR%" +Scheme.Txt = 10,"%CUR_DIR%" + +[Scheme.Reg] +HKCU,"Control Panel\\Cursors\\Schemes","%SCHEME_NAME%",,"%10%\\%CUR_DIR%\\%pointer%,%10%\\%CUR_DIR%\\%help%,%10%\\%CUR_DIR%\\%work%,%10%\\%CUR_DIR%\\%busy%,%10%\\%CUR_DIR%\\%Cross%,%10%\\%CUR_DIR%\\%Text%,%10%\\%CUR_DIR%\\%Hand%,%10%\\%CUR_DIR%\\%Unavailiable%,%10%\\%CUR_DIR%\\%Vert%,%10%\\%CUR_DIR%\\%Horz%,%10%\\%CUR_DIR%\\%Dgn1%,%10%\\%CUR_DIR%\\%Dgn2%,%10%\\%CUR_DIR%\\%move%,%10%\\%CUR_DIR%\\%alternate%,%10%\\%CUR_DIR%\\%link%" + +; -- Installed files + +[Scheme.Cur] +"$Work" +"$Busy" +"$Default" +"$Help" +"$Link" +"$Move" +"$Diagonal_2" +"$Vertical" +"$Horizontal" +"$Diagonal_1" +"$Handwriting" +"$Cross" +"$IBeam" +"$Unavailiable" +"$Alternate" + +[Strings] +CUR_DIR = "Cursors\\$theme_name Cursors" +SCHEME_NAME = "$theme_name Cursors" +pointer = "$Default" +help = "$Help" +work = "$Work" +busy = "$Busy" +cross = "$Cross" +text = "$IBeam" +hand = "$Handwriting" +unavailiable = "$Unavailiable" +vert = "$Vertical" +horz = "$Horizontal" +dgn1 = "$Diagonal_1" +dgn2 = "$Diagonal_2" +move = "$Move" +alternate = "$Alternate" +link = "$Link" +""" + ), + "uninstall.bat": Template( + """@echo off +:: =========================================================== +:: +:: Replace the name of cursor according to the cursor schemes. +:: Credit: https://github.com/smit-sms +:: More Information: https://github.com/ful1e5/apple_cursor/issues/79 +:: +:: =========================================================== + +REG DELETE "HKCU\\Control Panel\\Cursors\\Schemes" /v "$theme_name Cursors" /f + +:: =============================================================================== +:: This enables a popup message box to indicate a user for the operation complete. +:: =============================================================================== +echo x=msgbox("Successfully deleted the cursor!", 0+64, "Cursor") > %tmp%\tmp.vbs +wscript %tmp%\tmp.vbs +del %tmp%\tmp.vbs +""" + ), +} + +REQUIRED_CURSORS: Set[str] = { + "Work", + "Busy", + "Default", + "Help", + "Link", + "Move", + "Diagonal_2", + "Vertical", + "Horizontal", + "Diagonal_1", + "Handwriting", + "Cross", + "IBeam", + "Unavailiable", + "Alternate", +} + + +def pack_win( + dir: Path, + theme_name: str, + comment: str, + author: str, + website_url: Optional[str] = None, +) -> None: + """This packager generates ``install.inf`` files at ``directory``. Also, \ + Cursor extensions is identified by its type (.cur/.ani). + + :param dir: Path where ``.theme`` files save. + :param dir: ``pathlib.Path`` + + :param theme_name: Name of theme. + :param theme_name: ``str`` + + :param comment: Extra information about theme. + :param comment: ``str`` + + :param author: Author name. + :param author: ``str`` + + :param website_url: Website web address.(Useful for **bug reports**) + :param website_url: ``str`` or ``None`` + + :returns: None. + :rtype: ``None`` + + :raise FileNotFoundError: If Windows cursors are not exists on \ + provided directory. + """ + + files: List[Path] = [] + + for ext in ("*.ani", "*.cur"): + for i in sorted(dir.glob(ext)): + if i.stem in REQUIRED_CURSORS: + files.append(i) + + cursors = set(files) + + # Checking cursor files + if not cursors: + raise FileNotFoundError( + f"Windows cursors '*.cur' or '*.ani' not found in '{dir}'" + ) + + if len(cursors) < len(REQUIRED_CURSORS): + # Some cursors are missing + c = set(map(lambda x: x.stem, cursors)) + missing = sorted(REQUIRED_CURSORS - set(c)) + raise FileNotFoundError(f"Windows cursors are missing {missing}") + + if website_url: + comment = f"{comment}\n{website_url}" + + # replace $Default => Default.ani | Default.cur (as file was provided) + cursor_data: Dict[str, str] = {} + for cur in cursors: + cursor_data[cur.stem] = cur.name + + for fname, template in FILE_TEMPLATES.items(): + data: str = template.safe_substitute( + theme_name=theme_name, + comment=comment, + author=author, + **cursor_data, + ) + f = dir / fname + f.write_text(data) diff --git a/src/clickgen/packer/windows.pyi b/src/clickgen/packer/windows.pyi new file mode 100644 index 0000000..57de800 --- /dev/null +++ b/src/clickgen/packer/windows.pyi @@ -0,0 +1,8 @@ +from pathlib import Path +from string import Template +from typing import Dict, Optional, Set + +FILE_TEMPLATES: Dict[str, Template] +REQUIRED_CURSORS: Set[str] + +def pack_win(dir: Path, theme_name: str, comment: str, author: str, website_url: Optional[str] = ...) -> None: ... diff --git a/src/clickgen/packer/x11.py b/src/clickgen/packer/x11.py new file mode 100644 index 0000000..d907b84 --- /dev/null +++ b/src/clickgen/packer/x11.py @@ -0,0 +1,41 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +"""Generate X11 .theme files. + +.. moduleauthor:: Kaiz Khatri +""" + +from pathlib import Path +from string import Template +from typing import Dict + +FILE_TEMPLATES: Dict[str, Template] = { + "cursor.theme": Template('[Icon Theme]\nName=$theme_name\nInherits="$theme_name"'), + "index.theme": Template( + '[Icon Theme]\nName=$theme_name\nComment=$comment\nInherits="hicolor"' + ), +} + + +def pack_x11(dir: Path, theme_name: str, comment: str) -> None: + """This method generates ``cursor.theme`` & ``index.theme`` files at \ + ``directory``. + + :param dir: Path where ``.theme`` files save. + :param dir: ``pathlib.Path`` + + :param theme_name: Name of theme. + :param theme_name: ``str`` + + :param comment: Extra information about theme. + :param comment: ``str`` + + :returns: None. + :rtype: ``None`` + """ + + for fname, template in FILE_TEMPLATES.items(): + data = template.safe_substitute(theme_name=theme_name, comment=comment) + fp: Path = dir / fname + fp.write_text(data) diff --git a/src/clickgen/packer/x11.pyi b/src/clickgen/packer/x11.pyi new file mode 100644 index 0000000..0988a10 --- /dev/null +++ b/src/clickgen/packer/x11.pyi @@ -0,0 +1,7 @@ +from pathlib import Path +from string import Template +from typing import Dict + +FILE_TEMPLATES: Dict[str, Template] + +def pack_x11(dir: Path, theme_name: str, comment: str) -> None: ...