diff --git a/.github/workflows/publish_to_pypi.yml b/.github/workflows/publish_to_pypi.yml new file mode 100644 index 0000000..447c78c --- /dev/null +++ b/.github/workflows/publish_to_pypi.yml @@ -0,0 +1,29 @@ +name: Publish to PyPI + +on: + release: + types: + - created + +jobs: + publish: + name: Publish Package + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v2 + + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: "3.11.4" + + - name: Build and publish package + env: + TWINE_USERNAME: ${{ secrets.PYPI_API_USERNAME }} + TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }} + run: | + python3 -m pip install build twine + python3 -m build + python3 -m twine upload dist/* diff --git a/.gitignore b/.gitignore index 97fd905..0c33f58 100644 --- a/.gitignore +++ b/.gitignore @@ -6,9 +6,12 @@ __pycache__/ # C extensions *.so -# Pycharm +# Pycharm .idea +# Docs +docs/book + # Distribution / packaging .Python build/ @@ -139,4 +142,4 @@ dmypy.json .pyre/ # Test is under development -*out.py \ No newline at end of file +*out.py diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..9de2a16 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,15 @@ +repos: + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v2.3.0 + hooks: + - id: check-yaml + - id: end-of-file-fixer + - id: trailing-whitespace + - repo: https://github.com/psf/black + rev: 23.3.0 + hooks: + - id: black + - repo: https://github.com/charliermarsh/ruff-pre-commit + rev: v0.0.272 + hooks: + - id: ruff diff --git a/GUI_script.py b/GUI_script.py deleted file mode 100644 index fcd21c9..0000000 --- a/GUI_script.py +++ /dev/null @@ -1,154 +0,0 @@ -import tkinter as tk -from Simulator import Type -import customtkinter -from tkinter import filedialog -import tkinter - - -customtkinter.set_appearance_mode("Dark") # Modes: "System" (standard), "Dark", "Light" - - -class App(customtkinter.CTk): - - WIDTH = 780 - HEIGHT = 520 - - def __init__(self): - super().__init__() - self.resizable(0, 0) - self.title("Autotype") - self.geometry(f"{App.WIDTH}x{App.HEIGHT}") - - self.protocol("WM_DELETE_WINDOW", self.on_closing) - - # ============ created two frames ============ - - # configured grid layout (2x1) - self.grid_columnconfigure(1, weight=1) - self.grid_rowconfigure(0, weight=1) - - self.frame_left = customtkinter.CTkFrame( - master=self, width=180, corner_radius=0 - ) - self.frame_left.grid(row=0, column=0, sticky="nswe") - - self.frame_right = customtkinter.CTkFrame(master=self) - self.frame_right.grid(row=0, column=1, sticky="nswe", padx=20, pady=20) - - # ============ frame_left ============ - - # configure grid layout (1x11) - self.frame_left.grid_rowconfigure( - 0, minsize=10 - ) # empty row with minsize as spacing - self.frame_left.grid_rowconfigure(2, minsize=10) # empty row with minsize as spacing - self.frame_left.grid_rowconfigure( - 5, weight=1 - ) # empty row as spacing - self.frame_left.grid_rowconfigure( - 8, minsize=20 - ) # empty row with minsize as spacing - self.frame_left.grid_rowconfigure( - 11, minsize=10 - ) # empty row with minsize as spacing - - self.delay = customtkinter.CTkEntry( - master=self.frame_left, width=140, placeholder_text="Enter time delay" - ) - self.delay.grid(row=1, column=0, pady=10, padx=20) - - self.key_delay = customtkinter.CTkEntry( - master=self.frame_left, width=140, placeholder_text="Character delay time" - ) - self.key_delay.grid(row=3, column=0, pady=10, padx=20) - - self.line_delay = customtkinter.CTkEntry( - master=self.frame_left, width=140, placeholder_text="Next Line delay" - ) - self.line_delay.grid(row=5, column=0, pady=10, padx=20) - - self.button_2 = customtkinter.CTkButton( - master=self.frame_left, - text="Start Typing", - fg_color=("gray75", "gray30"), # <- custom tuple-color - command=self.start_typing, - hover=True, - ) - self.button_2.grid(row=6, column=0, pady=10, padx=20) - - self.label = customtkinter.CTkLabel(master=self.frame_left, text="") - self.label.place(relx=0.5, rely=0.3, anchor=tkinter.CENTER) - - self.switch_1 = customtkinter.CTkSwitch( - master=self.frame_left, text="Dark Mode", command=self.change_mode - ) - self.switch_1.grid(row=10, column=0, pady=10, padx=20, sticky="w") - - # ============ frame_right ============ - - self.code = customtkinter.CTkTextbox( - master=self.frame_right, width=520, height=400 - ) - self.code.grid(row=8, column=0, columnspan=2, pady=20, padx=20, sticky="we") - - self.label_2 = customtkinter.CTkLabel( - master=self.frame_right, - text="Enter Your Code", - text_font=("Roboto Medium", -16), - ) # font name and size in px - self.label_2.grid(row=8, column=0, columnspan=2, pady=20, padx=20, sticky="we") - self.label_2.place(relx=0.38, rely=0.92) - - - def open_file(self): - filePath = filedialog.askopenfile() - return filePath.name - - def start_typing(self): - # Get the delay time, key delay time, line delay time, and code from the GUI inputs - delay = self.delay.get() - key_delay = self.key_delay.get() - line_delay = self.line_delay.get() - code = self.code.textbox.get("1.0", tk.END) - - # Check if key_delay and line_delay are provided - if not key_delay: - key_delay = 0 # Set a default value (e.g., 0 seconds) if not provided - else: - key_delay = float(key_delay) - - if not line_delay: - line_delay = 0 # Set a default value (e.g., 0 seconds) if not provided - else: - line_delay = float(line_delay) - - # Continue with the logic based on code and delay as before - if not code.strip() and delay: - Type(path=self.open_file(), delay=int(delay), code=None, key_delay=key_delay, line_delay=line_delay) - self.label.configure(text="Done Writing Script") - elif not code.strip() and not delay: - Type(path=self.open_file(), delay=3, code=None, key_delay=key_delay, line_delay=line_delay) - self.label.configure(text="Done Writing Script") - elif code.strip() and delay: - Type(path=None, delay=int(delay), code=code, key_delay=key_delay, line_delay=line_delay) - self.label.configure(text="Done Writing Script") - else: - Type(path=None, delay=3, code=code, key_delay=key_delay, line_delay=line_delay) - self.label.configure(text="Done Writing Script") - - def change_mode(self): - if self.switch_1.get() == 1: - customtkinter.set_appearance_mode("dark") - else: - customtkinter.set_appearance_mode("light") - - def on_closing(self, event=0): - self.destroy() - - def start(self): - self.mainloop() - - -if __name__ == "__main__": - app = App() - app.start() diff --git a/LICENSE b/LICENSE index 0e259d4..230107a 100644 --- a/LICENSE +++ b/LICENSE @@ -1,121 +1,21 @@ -Creative Commons Legal Code - -CC0 1.0 Universal - - CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE - LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN - ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS - INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES - REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS - PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM - THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED - HEREUNDER. - -Statement of Purpose - -The laws of most jurisdictions throughout the world automatically confer -exclusive Copyright and Related Rights (defined below) upon the creator -and subsequent owner(s) (each and all, an "owner") of an original work of -authorship and/or a database (each, a "Work"). - -Certain owners wish to permanently relinquish those rights to a Work for -the purpose of contributing to a commons of creative, cultural and -scientific works ("Commons") that the public can reliably and without fear -of later claims of infringement build upon, modify, incorporate in other -works, reuse and redistribute as freely as possible in any form whatsoever -and for any purposes, including without limitation commercial purposes. -These owners may contribute to the Commons to promote the ideal of a free -culture and the further production of creative, cultural and scientific -works, or to gain reputation or greater distribution for their Work in -part through the use and efforts of others. - -For these and/or other purposes and motivations, and without any -expectation of additional consideration or compensation, the person -associating CC0 with a Work (the "Affirmer"), to the extent that he or she -is an owner of Copyright and Related Rights in the Work, voluntarily -elects to apply CC0 to the Work and publicly distribute the Work under its -terms, with knowledge of his or her Copyright and Related Rights in the -Work and the meaning and intended legal effect of CC0 on those rights. - -1. Copyright and Related Rights. A Work made available under CC0 may be -protected by copyright and related or neighboring rights ("Copyright and -Related Rights"). Copyright and Related Rights include, but are not -limited to, the following: - - i. the right to reproduce, adapt, distribute, perform, display, - communicate, and translate a Work; - ii. moral rights retained by the original author(s) and/or performer(s); -iii. publicity and privacy rights pertaining to a person's image or - likeness depicted in a Work; - iv. rights protecting against unfair competition in regards to a Work, - subject to the limitations in paragraph 4(a), below; - v. rights protecting the extraction, dissemination, use and reuse of data - in a Work; - vi. database rights (such as those arising under Directive 96/9/EC of the - European Parliament and of the Council of 11 March 1996 on the legal - protection of databases, and under any national implementation - thereof, including any amended or successor version of such - directive); and -vii. other similar, equivalent or corresponding rights throughout the - world based on applicable law or treaty, and any national - implementations thereof. - -2. Waiver. To the greatest extent permitted by, but not in contravention -of, applicable law, Affirmer hereby overtly, fully, permanently, -irrevocably and unconditionally waives, abandons, and surrenders all of -Affirmer's Copyright and Related Rights and associated claims and causes -of action, whether now known or unknown (including existing as well as -future claims and causes of action), in the Work (i) in all territories -worldwide, (ii) for the maximum duration provided by applicable law or -treaty (including future time extensions), (iii) in any current or future -medium and for any number of copies, and (iv) for any purpose whatsoever, -including without limitation commercial, advertising or promotional -purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each -member of the public at large and to the detriment of Affirmer's heirs and -successors, fully intending that such Waiver shall not be subject to -revocation, rescission, cancellation, termination, or any other legal or -equitable action to disrupt the quiet enjoyment of the Work by the public -as contemplated by Affirmer's express Statement of Purpose. - -3. Public License Fallback. Should any part of the Waiver for any reason -be judged legally invalid or ineffective under applicable law, then the -Waiver shall be preserved to the maximum extent permitted taking into -account Affirmer's express Statement of Purpose. In addition, to the -extent the Waiver is so judged Affirmer hereby grants to each affected -person a royalty-free, non transferable, non sublicensable, non exclusive, -irrevocable and unconditional license to exercise Affirmer's Copyright and -Related Rights in the Work (i) in all territories worldwide, (ii) for the -maximum duration provided by applicable law or treaty (including future -time extensions), (iii) in any current or future medium and for any number -of copies, and (iv) for any purpose whatsoever, including without -limitation commercial, advertising or promotional purposes (the -"License"). The License shall be deemed effective as of the date CC0 was -applied by Affirmer to the Work. Should any part of the License for any -reason be judged legally invalid or ineffective under applicable law, such -partial invalidity or ineffectiveness shall not invalidate the remainder -of the License, and in such case Affirmer hereby affirms that he or she -will not (i) exercise any of his or her remaining Copyright and Related -Rights in the Work or (ii) assert any associated claims and causes of -action with respect to the Work, in either case contrary to Affirmer's -express Statement of Purpose. - -4. Limitations and Disclaimers. - - a. No trademark or patent rights held by Affirmer are waived, abandoned, - surrendered, licensed or otherwise affected by this document. - b. Affirmer offers the Work as-is and makes no representations or - warranties of any kind concerning the Work, express, implied, - statutory or otherwise, including without limitation warranties of - title, merchantability, fitness for a particular purpose, non - infringement, or the absence of latent or other defects, accuracy, or - the present or absence of errors, whether or not discoverable, all to - the greatest extent permissible under applicable law. - c. Affirmer disclaims responsibility for clearing rights of other persons - that may apply to the Work or any use thereof, including without - limitation any person's Copyright and Related Rights in the Work. - Further, Affirmer disclaims responsibility for obtaining any necessary - consents, permissions or other rights required for any use of the - Work. - d. Affirmer understands and acknowledges that Creative Commons is not a - party to this document and has no duty or obligation with respect to - this CC0 or use of the Work. +The MIT License (MIT) + +Copyright (c) 2023 Tushar Gupta + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/Pipfile b/Pipfile deleted file mode 100644 index 6a68122..0000000 --- a/Pipfile +++ /dev/null @@ -1,25 +0,0 @@ -[[source]] -url = "https://pypi.org/simple" -verify_ssl = true -name = "pypi" - -[packages] -click = "==8.1.3" -colorama = "==0.4.5" -customtkinter = "==4.6.3" -darkdetect = "==0.7.1" -importlib-metadata = "==5.0.0" -pillow = "==9.1.1" -pynput = "==1.7.3" -python-xlib = "==0.30" -six = "==1.16.0" -tk = "==0.1.0" -typer = "==0.4.2" -typing-extensions = "==4.4.0" -zipp = "==3.10.0" - -[dev-packages] - -[requires] -python_version = "3.9" -python_full_version = "3.9.0" diff --git a/Pipfile.lock b/Pipfile.lock deleted file mode 100644 index dd03666..0000000 --- a/Pipfile.lock +++ /dev/null @@ -1,163 +0,0 @@ -{ - "_meta": { - "hash": { - "sha256": "3973f462c66875bb3373b6b575b8ca8d02a6c3baac1b5da3aac86b8c7347de52" - }, - "pipfile-spec": 6, - "requires": { - "python_full_version": "3.10.9", - "python_version": "3.10" - }, - "sources": [ - { - "name": "pypi", - "url": "https://pypi.org/simple", - "verify_ssl": true - } - ] - }, - "default": { - "click": { - "hashes": [ - "sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e", - "sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48" - ], - "index": "pypi", - "version": "==8.1.3" - }, - "colorama": { - "hashes": [ - "sha256:854bf444933e37f5824ae7bfc1e98d5bce2ebe4160d46b5edf346a89358e99da", - "sha256:e6c6b4334fc50988a639d9b98aa429a0b57da6e17b9a44f0451f930b6967b7a4" - ], - "index": "pypi", - "version": "==0.4.5" - }, - "customtkinter": { - "hashes": [ - "sha256:479ecdcfa91cd54d03be7c302612fcb3719df8928657bab5ea4a0a9e255e7099", - "sha256:d475da11aeaf4edd83499ceffb9437614d47b2a3c5d41531d115a3ff942d7838" - ], - "index": "pypi", - "version": "==4.6.3" - }, - "darkdetect": { - "hashes": [ - "sha256:3efe69f8ecd5f1b7f4fbb0d1d93f656b0e493c45cc49222380ffe2a529cbc866", - "sha256:47be3cf5134432ddb616bbffc927237718407914993c82809983e7ccebf49013" - ], - "index": "pypi", - "version": "==0.7.1" - }, - "importlib-metadata": { - "hashes": [ - "sha256:da31db32b304314d044d3c12c79bd59e307889b287ad12ff387b3500835fc2ab", - "sha256:ddb0e35065e8938f867ed4928d0ae5bf2a53b7773871bfe6bcc7e4fcdc7dea43" - ], - "index": "pypi", - "version": "==5.0.0" - }, - "pillow": { - "hashes": [ - "sha256:088df396b047477dd1bbc7de6e22f58400dae2f21310d9e2ec2933b2ef7dfa4f", - "sha256:09e67ef6e430f90caa093528bd758b0616f8165e57ed8d8ce014ae32df6a831d", - "sha256:0b4d5ad2cd3a1f0d1df882d926b37dbb2ab6c823ae21d041b46910c8f8cd844b", - "sha256:0b525a356680022b0af53385944026d3486fc8c013638cf9900eb87c866afb4c", - "sha256:1d4331aeb12f6b3791911a6da82de72257a99ad99726ed6b63f481c0184b6fb9", - "sha256:20d514c989fa28e73a5adbddd7a171afa5824710d0ab06d4e1234195d2a2e546", - "sha256:2b291cab8a888658d72b575a03e340509b6b050b62db1f5539dd5cd18fd50578", - "sha256:3f6c1716c473ebd1649663bf3b42702d0d53e27af8b64642be0dd3598c761fb1", - "sha256:42dfefbef90eb67c10c45a73a9bc1599d4dac920f7dfcbf4ec6b80cb620757fe", - "sha256:488f3383cf5159907d48d32957ac6f9ea85ccdcc296c14eca1a4e396ecc32098", - "sha256:4d45dbe4b21a9679c3e8b3f7f4f42a45a7d3ddff8a4a16109dff0e1da30a35b2", - "sha256:53c27bd452e0f1bc4bfed07ceb235663a1df7c74df08e37fd6b03eb89454946a", - "sha256:55e74faf8359ddda43fee01bffbc5bd99d96ea508d8a08c527099e84eb708f45", - "sha256:59789a7d06c742e9d13b883d5e3569188c16acb02eeed2510fd3bfdbc1bd1530", - "sha256:5b650dbbc0969a4e226d98a0b440c2f07a850896aed9266b6fedc0f7e7834108", - "sha256:66daa16952d5bf0c9d5389c5e9df562922a59bd16d77e2a276e575d32e38afd1", - "sha256:6e760cf01259a1c0a50f3c845f9cad1af30577fd8b670339b1659c6d0e7a41dd", - "sha256:7502539939b53d7565f3d11d87c78e7ec900d3c72945d4ee0e2f250d598309a0", - "sha256:769a7f131a2f43752455cc72f9f7a093c3ff3856bf976c5fb53a59d0ccc704f6", - "sha256:7c150dbbb4a94ea4825d1e5f2c5501af7141ea95825fadd7829f9b11c97aaf6c", - "sha256:8844217cdf66eabe39567118f229e275f0727e9195635a15e0e4b9227458daaf", - "sha256:8a66fe50386162df2da701b3722781cbe90ce043e7d53c1fd6bd801bca6b48d4", - "sha256:9370d6744d379f2de5d7fa95cdbd3a4d92f0b0ef29609b4b1687f16bc197063d", - "sha256:937a54e5694684f74dcbf6e24cc453bfc5b33940216ddd8f4cd8f0f79167f765", - "sha256:9c857532c719fb30fafabd2371ce9b7031812ff3889d75273827633bca0c4602", - "sha256:a4165205a13b16a29e1ac57efeee6be2dfd5b5408122d59ef2145bc3239fa340", - "sha256:b3fe2ff1e1715d4475d7e2c3e8dabd7c025f4410f79513b4ff2de3d51ce0fa9c", - "sha256:b6617221ff08fbd3b7a811950b5c3f9367f6e941b86259843eab77c8e3d2b56b", - "sha256:b761727ed7d593e49671d1827044b942dd2f4caae6e51bab144d4accf8244a84", - "sha256:baf3be0b9446a4083cc0c5bb9f9c964034be5374b5bc09757be89f5d2fa247b8", - "sha256:c17770a62a71718a74b7548098a74cd6880be16bcfff5f937f900ead90ca8e92", - "sha256:c67db410508b9de9c4694c57ed754b65a460e4812126e87f5052ecf23a011a54", - "sha256:d78ca526a559fb84faaaf84da2dd4addef5edb109db8b81677c0bb1aad342601", - "sha256:e9ed59d1b6ee837f4515b9584f3d26cf0388b742a11ecdae0d9237a94505d03a", - "sha256:f054b020c4d7e9786ae0404278ea318768eb123403b18453e28e47cdb7a0a4bf", - "sha256:f372d0f08eff1475ef426344efe42493f71f377ec52237bf153c5713de987251", - "sha256:f3f6a6034140e9e17e9abc175fc7a266a6e63652028e157750bd98e804a8ed9a", - "sha256:ffde4c6fabb52891d81606411cbfaf77756e3b561b566efd270b3ed3791fde4e" - ], - "index": "pypi", - "version": "==9.1.1" - }, - "pynput": { - "hashes": [ - "sha256:4e50b1a0ab86847e87e58f6d1993688b9a44f9f4c88d4712315ea8eb552ef828", - "sha256:6626e8ea9ca482bb5628a7169e1193824e382c4ad3053e40f4f24f41ee7b41c9", - "sha256:fea5777454f896bd79d35393088cd29a089f3b2da166f0848a922b1d5a807d4f" - ], - "index": "pypi", - "version": "==1.7.3" - }, - "python-xlib": { - "hashes": [ - "sha256:74131418faf9e7b83178c71d9d80297fbbd678abe99ae9258f5a20cd027acb5f", - "sha256:c4c92cd47e07588b2cbc7d52de18407b2902c3812d7cdec39cd2177b060828e2" - ], - "index": "pypi", - "version": "==0.30" - }, - "six": { - "hashes": [ - "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", - "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254" - ], - "index": "pypi", - "version": "==1.16.0" - }, - "tk": { - "hashes": [ - "sha256:60bc8923d5d35f67f5c6bd93d4f0c49d2048114ec077768f959aef36d4ed97f8", - "sha256:703a69ff0d5ba2bd2f7440582ad10160e4a6561595d33457dc6caa79b9bf4930" - ], - "index": "pypi", - "version": "==0.1.0" - }, - "typer": { - "hashes": [ - "sha256:023bae00d1baf358a6cc7cea45851639360bb716de687b42b0a4641cd99173f1", - "sha256:b8261c6c0152dd73478b5ba96ba677e5d6948c715c310f7c91079f311f62ec03" - ], - "index": "pypi", - "version": "==0.4.2" - }, - "typing-extensions": { - "hashes": [ - "sha256:1511434bb92bf8dd198c12b1cc812e800d4181cfcb867674e0f8279cc93087aa", - "sha256:16fa4864408f655d35ec496218b85f79b3437c829e93320c7c9215ccfd92489e" - ], - "index": "pypi", - "version": "==4.4.0" - }, - "zipp": { - "hashes": [ - "sha256:4fcb6f278987a6605757302a6e40e896257570d11c51628968ccb2a47e80c6c1", - "sha256:7a7262fd930bd3e36c50b9a64897aec3fafff3dfdeec9623ae22b40e93f99bb8" - ], - "index": "pypi", - "version": "==3.10.0" - } - }, - "develop": {} -} diff --git a/README.md b/README.md index acb894d..064cdc2 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,10 @@ # Autotype 🖊 +
+
+
# Pre-requisites
+
+# Dev-Setup
+```bash
+git clone https://github.com/tushar5526/Autotype
-- You can simply type your code in the textbox , enter the time delay and click the `Start Typing` button.The script will then type your code for you.
-
+python3 -m venv venv
-- If your code is in a file , then leave the textbox blank , enter the time delay and click `Start Typing` button.A file exploror prompt will open asking you to select the file.Simply select your file and Done! Autotype will type your code for you.
-
+source venv/bin/activate
-- There are two themes in the GUI Script: Dark and Light. By clicking the toggle in the bottom left corner of the window, you can switch between the two.
-
+pip3 install -r requirements-dev.txt
-### Run it as follows if you are not familiar with CLI apps.
-Put the text inside `code` in `Simulator/simulate_keyboard.py` as follows
+pre-commit
+
+pip3 install .
```
-Line 13
-code = """
- #include