├── docs ├── .nojekyll ├── objects.inv ├── _static │ ├── file.png │ ├── plus.png │ ├── minus.png │ ├── css │ │ ├── fonts │ │ │ ├── lato-bold.woff │ │ │ ├── lato-bold.woff2 │ │ │ ├── lato-normal.woff │ │ │ ├── lato-normal.woff2 │ │ │ ├── Roboto-Slab-Bold.woff │ │ │ ├── lato-bold-italic.woff │ │ │ ├── Roboto-Slab-Bold.woff2 │ │ │ ├── fontawesome-webfont.eot │ │ │ ├── fontawesome-webfont.ttf │ │ │ ├── lato-bold-italic.woff2 │ │ │ ├── lato-normal-italic.woff │ │ │ ├── Roboto-Slab-Regular.woff │ │ │ ├── Roboto-Slab-Regular.woff2 │ │ │ ├── fontawesome-webfont.woff │ │ │ ├── fontawesome-webfont.woff2 │ │ │ └── lato-normal-italic.woff2 │ │ └── badge_only.css │ ├── documentation_options.js │ ├── js │ │ ├── badge_only.js │ │ ├── html5shiv.min.js │ │ ├── html5shiv-printshiv.min.js │ │ └── theme.js │ ├── pygments.css │ ├── language_data.js │ ├── doctools.js │ ├── underscore.js │ ├── searchtools.js │ └── basic.css ├── _sources │ ├── modules.rst.txt │ ├── README.md.txt │ ├── index.rst.txt │ ├── TikTokPrinter.rst.txt │ ├── TikTokPrinter.client.rst.txt │ ├── TikTokPrinter.tiktok.rst.txt │ ├── TikTokPrinter.types.rst.txt │ ├── TikTokPrinter.client.printer.rst.txt │ └── TikTokPrinter.client.engines.rst.txt ├── .buildinfo ├── search.html ├── README.html ├── modules.html ├── py-modindex.html ├── TikTokPrinter.html ├── searchindex.js └── index.html ├── .github ├── documentation.yml └── FUNDING.yml ├── .gitignore ├── examples ├── fancy │ ├── resources │ │ ├── icons │ │ │ ├── _uwu.png │ │ │ ├── cry1.png │ │ │ ├── cry2.png │ │ │ ├── cry3.png │ │ │ ├── _devil.png │ │ │ ├── _point.png │ │ │ ├── _shoot.png │ │ │ ├── love1.png │ │ │ ├── love10.png │ │ │ ├── love2.png │ │ │ ├── love3.png │ │ │ ├── love4.png │ │ │ ├── love5.png │ │ │ ├── love6.png │ │ │ ├── love7.png │ │ │ ├── love8.png │ │ │ ├── love9.png │ │ │ ├── _shocked.png │ │ │ ├── _wholesome.png │ │ │ ├── embarassed1.png │ │ │ └── embarassed2.png │ │ └── fonts │ │ │ └── fredoka.ttf │ ├── README.md │ ├── client.py │ └── main.py ├── images.py ├── manual.py ├── basic.py ├── README.md └── commands.py ├── main.py └── README.md /docs/.nojekyll: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.github/documentation.yml: -------------------------------------------------------------------------------- 1 | - .sphinx -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | requirements.txt 3 | 4 | private/ -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | custom: [ 'https://www.paypal.me/isaackogan' ] 2 | github: isaackogan 3 | -------------------------------------------------------------------------------- /docs/objects.inv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaackogan/TikTokPrinter/HEAD/docs/objects.inv -------------------------------------------------------------------------------- /docs/_static/file.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaackogan/TikTokPrinter/HEAD/docs/_static/file.png -------------------------------------------------------------------------------- /docs/_static/plus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaackogan/TikTokPrinter/HEAD/docs/_static/plus.png -------------------------------------------------------------------------------- /docs/_static/minus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaackogan/TikTokPrinter/HEAD/docs/_static/minus.png -------------------------------------------------------------------------------- /docs/_sources/modules.rst.txt: -------------------------------------------------------------------------------- 1 | TikTokPrinter 2 | ============= 3 | 4 | .. toctree:: 5 | :maxdepth: 4 6 | 7 | TikTokPrinter 8 | -------------------------------------------------------------------------------- /docs/_static/css/fonts/lato-bold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaackogan/TikTokPrinter/HEAD/docs/_static/css/fonts/lato-bold.woff -------------------------------------------------------------------------------- /docs/_static/css/fonts/lato-bold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaackogan/TikTokPrinter/HEAD/docs/_static/css/fonts/lato-bold.woff2 -------------------------------------------------------------------------------- /docs/_static/css/fonts/lato-normal.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaackogan/TikTokPrinter/HEAD/docs/_static/css/fonts/lato-normal.woff -------------------------------------------------------------------------------- /examples/fancy/resources/icons/_uwu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaackogan/TikTokPrinter/HEAD/examples/fancy/resources/icons/_uwu.png -------------------------------------------------------------------------------- /examples/fancy/resources/icons/cry1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaackogan/TikTokPrinter/HEAD/examples/fancy/resources/icons/cry1.png -------------------------------------------------------------------------------- /examples/fancy/resources/icons/cry2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaackogan/TikTokPrinter/HEAD/examples/fancy/resources/icons/cry2.png -------------------------------------------------------------------------------- /examples/fancy/resources/icons/cry3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaackogan/TikTokPrinter/HEAD/examples/fancy/resources/icons/cry3.png -------------------------------------------------------------------------------- /docs/_static/css/fonts/lato-normal.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaackogan/TikTokPrinter/HEAD/docs/_static/css/fonts/lato-normal.woff2 -------------------------------------------------------------------------------- /examples/fancy/resources/icons/_devil.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaackogan/TikTokPrinter/HEAD/examples/fancy/resources/icons/_devil.png -------------------------------------------------------------------------------- /examples/fancy/resources/icons/_point.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaackogan/TikTokPrinter/HEAD/examples/fancy/resources/icons/_point.png -------------------------------------------------------------------------------- /examples/fancy/resources/icons/_shoot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaackogan/TikTokPrinter/HEAD/examples/fancy/resources/icons/_shoot.png -------------------------------------------------------------------------------- /examples/fancy/resources/icons/love1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaackogan/TikTokPrinter/HEAD/examples/fancy/resources/icons/love1.png -------------------------------------------------------------------------------- /examples/fancy/resources/icons/love10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaackogan/TikTokPrinter/HEAD/examples/fancy/resources/icons/love10.png -------------------------------------------------------------------------------- /examples/fancy/resources/icons/love2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaackogan/TikTokPrinter/HEAD/examples/fancy/resources/icons/love2.png -------------------------------------------------------------------------------- /examples/fancy/resources/icons/love3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaackogan/TikTokPrinter/HEAD/examples/fancy/resources/icons/love3.png -------------------------------------------------------------------------------- /examples/fancy/resources/icons/love4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaackogan/TikTokPrinter/HEAD/examples/fancy/resources/icons/love4.png -------------------------------------------------------------------------------- /examples/fancy/resources/icons/love5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaackogan/TikTokPrinter/HEAD/examples/fancy/resources/icons/love5.png -------------------------------------------------------------------------------- /examples/fancy/resources/icons/love6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaackogan/TikTokPrinter/HEAD/examples/fancy/resources/icons/love6.png -------------------------------------------------------------------------------- /examples/fancy/resources/icons/love7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaackogan/TikTokPrinter/HEAD/examples/fancy/resources/icons/love7.png -------------------------------------------------------------------------------- /examples/fancy/resources/icons/love8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaackogan/TikTokPrinter/HEAD/examples/fancy/resources/icons/love8.png -------------------------------------------------------------------------------- /examples/fancy/resources/icons/love9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaackogan/TikTokPrinter/HEAD/examples/fancy/resources/icons/love9.png -------------------------------------------------------------------------------- /docs/_static/css/fonts/Roboto-Slab-Bold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaackogan/TikTokPrinter/HEAD/docs/_static/css/fonts/Roboto-Slab-Bold.woff -------------------------------------------------------------------------------- /docs/_static/css/fonts/lato-bold-italic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaackogan/TikTokPrinter/HEAD/docs/_static/css/fonts/lato-bold-italic.woff -------------------------------------------------------------------------------- /examples/fancy/resources/fonts/fredoka.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaackogan/TikTokPrinter/HEAD/examples/fancy/resources/fonts/fredoka.ttf -------------------------------------------------------------------------------- /examples/fancy/resources/icons/_shocked.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaackogan/TikTokPrinter/HEAD/examples/fancy/resources/icons/_shocked.png -------------------------------------------------------------------------------- /docs/_static/css/fonts/Roboto-Slab-Bold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaackogan/TikTokPrinter/HEAD/docs/_static/css/fonts/Roboto-Slab-Bold.woff2 -------------------------------------------------------------------------------- /docs/_static/css/fonts/fontawesome-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaackogan/TikTokPrinter/HEAD/docs/_static/css/fonts/fontawesome-webfont.eot -------------------------------------------------------------------------------- /docs/_static/css/fonts/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaackogan/TikTokPrinter/HEAD/docs/_static/css/fonts/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /docs/_static/css/fonts/lato-bold-italic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaackogan/TikTokPrinter/HEAD/docs/_static/css/fonts/lato-bold-italic.woff2 -------------------------------------------------------------------------------- /docs/_static/css/fonts/lato-normal-italic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaackogan/TikTokPrinter/HEAD/docs/_static/css/fonts/lato-normal-italic.woff -------------------------------------------------------------------------------- /examples/fancy/resources/icons/_wholesome.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaackogan/TikTokPrinter/HEAD/examples/fancy/resources/icons/_wholesome.png -------------------------------------------------------------------------------- /examples/fancy/resources/icons/embarassed1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaackogan/TikTokPrinter/HEAD/examples/fancy/resources/icons/embarassed1.png -------------------------------------------------------------------------------- /examples/fancy/resources/icons/embarassed2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaackogan/TikTokPrinter/HEAD/examples/fancy/resources/icons/embarassed2.png -------------------------------------------------------------------------------- /docs/_static/css/fonts/Roboto-Slab-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaackogan/TikTokPrinter/HEAD/docs/_static/css/fonts/Roboto-Slab-Regular.woff -------------------------------------------------------------------------------- /docs/_static/css/fonts/Roboto-Slab-Regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaackogan/TikTokPrinter/HEAD/docs/_static/css/fonts/Roboto-Slab-Regular.woff2 -------------------------------------------------------------------------------- /docs/_static/css/fonts/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaackogan/TikTokPrinter/HEAD/docs/_static/css/fonts/fontawesome-webfont.woff -------------------------------------------------------------------------------- /docs/_static/css/fonts/fontawesome-webfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaackogan/TikTokPrinter/HEAD/docs/_static/css/fonts/fontawesome-webfont.woff2 -------------------------------------------------------------------------------- /docs/_static/css/fonts/lato-normal-italic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaackogan/TikTokPrinter/HEAD/docs/_static/css/fonts/lato-normal-italic.woff2 -------------------------------------------------------------------------------- /docs/.buildinfo: -------------------------------------------------------------------------------- 1 | # Sphinx build info version 1 2 | # This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. 3 | config: bfcb1b5ef82425e544b53fb47be62b35 4 | tags: 645f666f9bcd5a90fca523b33c5a78b7 5 | -------------------------------------------------------------------------------- /docs/_sources/README.md.txt: -------------------------------------------------------------------------------- 1 | ## How To Build 2 | 3 | 1. Complete commands: 4 | 5 | ```shell 6 | **cd .sphinx 7 | 8 | sphinx-apidoc --ext-autodoc --force -o . ../TikTokPrinter 9 | 10 | .\make html 11 | ``` 12 | 13 | 3. Move generated sphinx `/sphinx/_build/html` folder to root, rename to "docs" 14 | 4. Add `.nojekyll` file to new docs folder -------------------------------------------------------------------------------- /docs/_sources/index.rst.txt: -------------------------------------------------------------------------------- 1 | .. MD -> .. mdinclude:: ../README.md 2 | 3 | TikTokPrinter Docs 4 | ================== 5 | 6 | .. toctree:: 7 | :maxdepth: 3 8 | 9 | TikTokPrinter 10 | 11 | View the above tree for detailed documentation on the package. 12 | 13 | .. include:: C:\Users\jeanm\PycharmProjects\TikTokPrinter\README.md 14 | :parser: myst_parser.sphinx_ 15 | -------------------------------------------------------------------------------- /docs/_sources/TikTokPrinter.rst.txt: -------------------------------------------------------------------------------- 1 | TikTokPrinter package 2 | ===================== 3 | 4 | Subpackages 5 | ----------- 6 | 7 | .. toctree:: 8 | :maxdepth: 4 9 | 10 | TikTokPrinter.client 11 | TikTokPrinter.tiktok 12 | TikTokPrinter.types 13 | 14 | Module contents 15 | --------------- 16 | 17 | .. automodule:: TikTokPrinter 18 | :members: 19 | :undoc-members: 20 | :show-inheritance: 21 | -------------------------------------------------------------------------------- /docs/_static/documentation_options.js: -------------------------------------------------------------------------------- 1 | var DOCUMENTATION_OPTIONS = { 2 | URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'), 3 | VERSION: '', 4 | LANGUAGE: 'None', 5 | COLLAPSE_INDEX: false, 6 | BUILDER: 'html', 7 | FILE_SUFFIX: '.html', 8 | LINK_SUFFIX: '.html', 9 | HAS_SOURCE: true, 10 | SOURCELINK_SUFFIX: '.txt', 11 | NAVIGATION_WITH_KEYS: false, 12 | SHOW_SEARCH_SUMMARY: true, 13 | ENABLE_SEARCH_SHORTCUTS: true, 14 | }; -------------------------------------------------------------------------------- /docs/_sources/TikTokPrinter.client.rst.txt: -------------------------------------------------------------------------------- 1 | TikTokPrinter.client package 2 | ============================ 3 | 4 | Subpackages 5 | ----------- 6 | 7 | .. toctree:: 8 | :maxdepth: 4 9 | 10 | TikTokPrinter.client.engines 11 | TikTokPrinter.client.printer 12 | 13 | Submodules 14 | ---------- 15 | 16 | TikTokPrinter.client.client module 17 | ---------------------------------- 18 | 19 | .. automodule:: TikTokPrinter.client.client 20 | :members: 21 | :undoc-members: 22 | :show-inheritance: 23 | 24 | Module contents 25 | --------------- 26 | 27 | .. automodule:: TikTokPrinter.client 28 | :members: 29 | :undoc-members: 30 | :show-inheritance: 31 | -------------------------------------------------------------------------------- /docs/_sources/TikTokPrinter.tiktok.rst.txt: -------------------------------------------------------------------------------- 1 | TikTokPrinter.tiktok package 2 | ============================ 3 | 4 | Submodules 5 | ---------- 6 | 7 | TikTokPrinter.tiktok.http module 8 | -------------------------------- 9 | 10 | .. automodule:: TikTokPrinter.tiktok.http 11 | :members: 12 | :undoc-members: 13 | :show-inheritance: 14 | 15 | TikTokPrinter.tiktok.media module 16 | --------------------------------- 17 | 18 | .. automodule:: TikTokPrinter.tiktok.media 19 | :members: 20 | :undoc-members: 21 | :show-inheritance: 22 | 23 | Module contents 24 | --------------- 25 | 26 | .. automodule:: TikTokPrinter.tiktok 27 | :members: 28 | :undoc-members: 29 | :show-inheritance: 30 | -------------------------------------------------------------------------------- /docs/_sources/TikTokPrinter.types.rst.txt: -------------------------------------------------------------------------------- 1 | TikTokPrinter.types package 2 | =========================== 3 | 4 | Submodules 5 | ---------- 6 | 7 | TikTokPrinter.types.errors module 8 | --------------------------------- 9 | 10 | .. automodule:: TikTokPrinter.types.errors 11 | :members: 12 | :undoc-members: 13 | :show-inheritance: 14 | 15 | TikTokPrinter.types.objects module 16 | ---------------------------------- 17 | 18 | .. automodule:: TikTokPrinter.types.objects 19 | :members: 20 | :undoc-members: 21 | :show-inheritance: 22 | 23 | Module contents 24 | --------------- 25 | 26 | .. automodule:: TikTokPrinter.types 27 | :members: 28 | :undoc-members: 29 | :show-inheritance: 30 | -------------------------------------------------------------------------------- /docs/_sources/TikTokPrinter.client.printer.rst.txt: -------------------------------------------------------------------------------- 1 | TikTokPrinter.client.printer package 2 | ==================================== 3 | 4 | Submodules 5 | ---------- 6 | 7 | TikTokPrinter.client.printer.engine module 8 | ------------------------------------------ 9 | 10 | .. automodule:: TikTokPrinter.client.printer.engine 11 | :members: 12 | :undoc-members: 13 | :show-inheritance: 14 | 15 | TikTokPrinter.client.printer.interface module 16 | --------------------------------------------- 17 | 18 | .. automodule:: TikTokPrinter.client.printer.interface 19 | :members: 20 | :undoc-members: 21 | :show-inheritance: 22 | 23 | Module contents 24 | --------------- 25 | 26 | .. automodule:: TikTokPrinter.client.printer 27 | :members: 28 | :undoc-members: 29 | :show-inheritance: 30 | -------------------------------------------------------------------------------- /docs/_static/js/badge_only.js: -------------------------------------------------------------------------------- 1 | !function(e){var t={};function r(n){if(t[n])return t[n].exports;var o=t[n]={i:n,l:!1,exports:{}};return e[n].call(o.exports,o,o.exports,r),o.l=!0,o.exports}r.m=e,r.c=t,r.d=function(e,t,n){r.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:n})},r.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.t=function(e,t){if(1&t&&(e=r(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(r.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)r.d(n,o,function(t){return e[t]}.bind(null,o));return n},r.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return r.d(t,"a",t),t},r.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},r.p="",r(r.s=4)}({4:function(e,t,r){}}); -------------------------------------------------------------------------------- /docs/_sources/TikTokPrinter.client.engines.rst.txt: -------------------------------------------------------------------------------- 1 | TikTokPrinter.client.engines package 2 | ==================================== 3 | 4 | Submodules 5 | ---------- 6 | 7 | TikTokPrinter.client.engines.console module 8 | ------------------------------------------- 9 | 10 | .. automodule:: TikTokPrinter.client.engines.console 11 | :members: 12 | :undoc-members: 13 | :show-inheritance: 14 | 15 | TikTokPrinter.client.engines.escpos module 16 | ------------------------------------------ 17 | 18 | .. automodule:: TikTokPrinter.client.engines.escpos 19 | :members: 20 | :undoc-members: 21 | :show-inheritance: 22 | 23 | TikTokPrinter.client.engines.sound module 24 | ----------------------------------------- 25 | 26 | .. automodule:: TikTokPrinter.client.engines.sound 27 | :members: 28 | :undoc-members: 29 | :show-inheritance: 30 | 31 | TikTokPrinter.client.engines.voice module 32 | ----------------------------------------- 33 | 34 | .. automodule:: TikTokPrinter.client.engines.voice 35 | :members: 36 | :undoc-members: 37 | :show-inheritance: 38 | 39 | Module contents 40 | --------------- 41 | 42 | .. automodule:: TikTokPrinter.client.engines 43 | :members: 44 | :undoc-members: 45 | :show-inheritance: 46 | -------------------------------------------------------------------------------- /examples/images.py: -------------------------------------------------------------------------------- 1 | from TikTokLive.types.events import GiftEvent 2 | 3 | from TikTokPrinter import TikTokPrinterClient, EscposEngineGenerator, TikTokMedia 4 | from TikTokPrinter.types.objects import PrinterImage 5 | 6 | client: TikTokPrinterClient = TikTokPrinterClient( 7 | unique_id="USERNAME_HERE", 8 | engine=EscposEngineGenerator.create_usb( 9 | auto_find=True, # Automatically find your printer 10 | align="center" 11 | ) 12 | ) 13 | 14 | 15 | @client.on("gift") 16 | async def on_gift(event: GiftEvent): 17 | """ 18 | If you want to send multiple printer commands in one go, the recommended way 19 | to do it is through the queue method. 20 | 21 | This library has support for automatically downloading & printing resources 22 | from the TikTok API. 23 | 24 | """ 25 | 26 | # If currently streaking 27 | if event.gift.streaking: 28 | return 29 | 30 | client.queue( 31 | 32 | PrinterImage( 33 | # Download their avatar and print the image as a circle 34 | await TikTokMedia.user_image(event.user, size=150, circle=True, circle_blur_radius=2) 35 | ), 36 | 37 | PrinterImage( 38 | # Download the gift image and print it 39 | await TikTokMedia.gift_image(event.gift) 40 | ) 41 | ) 42 | 43 | 44 | if __name__ == '__main__': 45 | client.run() 46 | -------------------------------------------------------------------------------- /examples/manual.py: -------------------------------------------------------------------------------- 1 | from TikTokPrinter import TikTokPrinterClient, EscposEngineGenerator, TikTokMedia 2 | 3 | client: TikTokPrinterClient = TikTokPrinterClient( 4 | unique_id="USERNAME_HERE", 5 | engine=EscposEngineGenerator.create_usb( 6 | vendor_id=0x1234, # Manually input a vendor ID 7 | product_id=0x1234, # Manually input a product ID 8 | auto_find=True, # Automatically find your printer if vendor id & product id are invalid 9 | align="center" 10 | ) 11 | ) 12 | 13 | 14 | if __name__ == '__main__': 15 | """ 16 | 17 | [MANUALLY FIND PRINTER] 18 | 19 | Not keen on auto_find? Use the USBDeview, or auto_find, to determine your printer's vendor ID and product ID. 20 | If you include them as parameters in create_usb, TikTokPrinter will first try to connect using them 21 | before automatically finding your printer, so you don't have to pick each time. 22 | 23 | [INVALID ENDPOINT ADDRESS] 24 | 25 | Receiving an Invalid Endpoint error with a USB printer? 26 | 27 | This usually only happens when auto_find is off. Otherwise, the library automatically discovers the endpoints for you! 28 | 29 | Try adding “in_ep = 0x81, out_ep = 0x03" to the create_usb function! 30 | If you are not receiving this error, do not add the additional parameters! 31 | If you continue to receive this error, try doing out_ep = 0x02. 32 | 33 | """ 34 | 35 | client.run() 36 | -------------------------------------------------------------------------------- /examples/basic.py: -------------------------------------------------------------------------------- 1 | from TikTokLive.types.events import ShareEvent, CommentEvent 2 | 3 | from TikTokPrinter import TikTokPrinterClient, EscposEngineGenerator, TikTokMedia 4 | from TikTokPrinter.types.objects import VoiceText, PrinterText, SoundFile, PrinterImage 5 | 6 | client: TikTokPrinterClient = TikTokPrinterClient( 7 | unique_id="USERNAME_HERE", 8 | engine=EscposEngineGenerator.create_usb( 9 | auto_find=True, # Automatically find your printer 10 | align="center" 11 | ) 12 | ) 13 | 14 | @client.on("share") 15 | async def on_share(event: ShareEvent): 16 | """ 17 | You can interface with the library to directly print text! 18 | 19 | """ 20 | 21 | client.text(f"Thank you, @{event.user.uniqueId}, for sharing the LIVE!") 22 | 23 | # client.voice("Do some text to speech ;)") 24 | # client.image(pil_image) 25 | # client.send_message("Send this to the TikTok Live chat as a bot!") 26 | # client.sound("./path/to/sound.mp3") 27 | 28 | 29 | @client.on("comment") 30 | async def on_comment(event: CommentEvent): 31 | """ 32 | If you want to send multiple printer commands in one go, the recommended way 33 | to do it is through the queue method. 34 | 35 | """ 36 | 37 | client.queue( 38 | PrinterText("-" * 20), 39 | 40 | # Speak the comment 41 | VoiceText(event.user.uniqueId + " said " + event.comment), 42 | 43 | # Print the comment to printer 44 | PrinterText(event.user.uniqueId + " -> " + event.comment), 45 | 46 | # Play a sound 47 | SoundFile("enchanted.wav"), 48 | 49 | # Download their avatar and print the image 50 | PrinterImage(await TikTokMedia.user_image(event.user, circle=False)) 51 | 52 | ) 53 | 54 | 55 | if __name__ == '__main__': 56 | client.run() 57 | -------------------------------------------------------------------------------- /main.py: -------------------------------------------------------------------------------- 1 | from TikTokLive.types.events import ShareEvent, CommentEvent 2 | 3 | from TikTokPrinter import TikTokPrinterClient, EscposEngineGenerator, TikTokMedia 4 | from TikTokPrinter.types.objects import VoiceText, PrinterText, SoundFile, PrinterImage 5 | 6 | client: TikTokPrinterClient = TikTokPrinterClient( 7 | unique_id="nothing.aly", 8 | engine=EscposEngineGenerator.create_usb( 9 | vendor_id=0x0416, # Vendor ID goes here 10 | product_id=0x5011, # Product ID goes here 11 | align="center" 12 | ) 13 | ) 14 | 15 | 16 | @client.on("share") 17 | async def on_share(event: ShareEvent): 18 | """ 19 | You can interface with the library to directly print text! 20 | 21 | """ 22 | 23 | client.text(f"Thank you, @{event.user.uniqueId}, for sharing the LIVE!") 24 | 25 | # client.voice("Do some text to speech ;)") 26 | # client.image(pil_image) 27 | # client.send_message("Send this to the TikTok Live chat as a bot!") 28 | # client.sound("./path/to/sound.mp3") 29 | 30 | 31 | @client.on("comment") 32 | async def on_comment(event: CommentEvent): 33 | """ 34 | If you want to send multiple printer commands in one go, the recommended way 35 | to do it is through the queue method. 36 | 37 | """ 38 | 39 | client.queue( 40 | PrinterText("-" * 20), 41 | 42 | # Speak the comment 43 | VoiceText(event.user.uniqueId + " said " + event.comment), 44 | 45 | # Print the comment to printer 46 | PrinterText(event.user.uniqueId + " -> " + event.comment), 47 | 48 | # Play a sound 49 | SoundFile("enchanted.wav"), 50 | 51 | # Download their avatar and print the image 52 | PrinterImage(await TikTokMedia.user_image(event.user, circle=False)) 53 | 54 | ) 55 | 56 | 57 | if __name__ == '__main__': 58 | client.run() 59 | -------------------------------------------------------------------------------- /examples/fancy/README.md: -------------------------------------------------------------------------------- 1 | Fancy Example 2 | ========== 3 | 4 | If you're using this example, it's important that you download 5 | the entire "fancy" folder off of GitHub. 6 | 7 | To make this run, you will need to find your Product ID and Vendor ID and replace the one in the [main.py](main.py) file 8 | with your own. The instructions for this are in the [YouTube tutorial](https://www.youtube.com/watch?v=NeapS5Jn_oo) for this library. 9 | 10 | You will also need to replace the unique_id currently there with **the username** of the TikTok creator you want to print off of. 11 | 12 | After that, you should just be able to run. 13 | 14 | ### Troubleshooting: Invalid Endpoint Address 0x1 15 | 16 | If you receive something like this: 17 | 18 | ```bash 19 | File "C:\Users\tiger\AppData\Local\Programs\Python\Python310\lib\site-packages\usb\core.py", line 986, in write 20 | intf, ep = self._ctx.setup_request(self, endpoint) 21 | File "C:\Users\tiger\AppData\Local\Programs\Python\Python310\lib\site-packages\usb\core.py", line 113, in wrapper 22 | return f(self, *args, **kwargs) 23 | File "C:\Users\tiger\AppData\Local\Programs\Python\Python310\lib\site-packages\usb\core.py", line 228, in setup_request 24 | intf, ep = self.get_interface_and_endpoint(device, endpoint_address) 25 | File "C:\Users\tiger\AppData\Local\Programs\Python\Python310\lib\site-packages\usb\core.py", line 113, in wrapper 26 | return f(self, *args, **kwargs) 27 | File "C:\Users\tiger\AppData\Local\Programs\Python\Python310\lib\site-packages\usb\core.py", line 244, in get_interface_and_endpoint 28 | raise ValueError('Invalid endpoint address ' + hex(endpoint_address)) 29 | ValueError: Invalid endpoint address 0x3 30 | ``` 31 | 32 | Try adding “in_ep = 0x81, out_ep = 0x03" to the create_usb function! If you are not receiving this error, do not add the additional parameters! 33 | If you continue to receive this error, try doing out_ep = 0x02. 34 | 35 | If that still doesn't work, make a ticket & we will handle it together! -------------------------------------------------------------------------------- /examples/README.md: -------------------------------------------------------------------------------- 1 | Examples 2 | ========= 3 | Within this folder are various examples showcasing the TikTokPrinter library. 4 | 5 | If you are looking for a plug & play example, use "fancy." It does pretty much everything 6 | a normal printer stream does, and more. 7 | 8 | If you want to learn how to customize this library yourself, check out the other examples. 9 | 10 | ### Current Examples 11 | 12 | #### Paste & Go (Use right away) 13 | 14 | - [Chat Commands (Ready-2-Go)](commands.py) 15 | - [Fancy Printer (Ready-2-Go)](fancy) 16 | 17 | #### Tutorial (Needs Customization) 18 | 19 | - [Using Images (Tutorial)](images.py) 20 | - [Basic Implementation (Tutorial)](basic.py) 21 | - [Manually VID/PID (Tutorial)](manual.py) 22 | 23 | ### Contributing Examples 24 | 25 | Create a [pull request](https://github.com/isaackogan/TikTok-Live-Connector/pulls) & I will add your example when I have free time! 26 | 27 | ### Troubleshooting: Invalid Endpoint Address 0x1 28 | 29 | If you receive something like this: 30 | 31 | ```bash 32 | File "C:\Users\LovelyClientOfMine\AppData\Local\Programs\Python\Python310\lib\site-packages\usb\core.py", line 986, in write 33 | intf, ep = self._ctx.setup_request(self, endpoint) 34 | File "C:\Users\LovelyClientOfMine\AppData\Local\Programs\Python\Python310\lib\site-packages\usb\core.py", line 113, in wrapper 35 | return f(self, *args, **kwargs) 36 | File "C:\Users\LovelyClientOfMine\AppData\Local\Programs\Python\Python310\lib\site-packages\usb\core.py", line 228, in setup_request 37 | intf, ep = self.get_interface_and_endpoint(device, endpoint_address) 38 | File "C:\Users\LovelyClientOfMine\AppData\Local\Programs\Python\Python310\lib\site-packages\usb\core.py", line 113, in wrapper 39 | return f(self, *args, **kwargs) 40 | File "C:\Users\LovelyClientOfMine\AppData\Local\Programs\Python\Python310\lib\site-packages\usb\core.py", line 244, in get_interface_and_endpoint 41 | raise ValueError('Invalid endpoint address ' + hex(endpoint_address)) 42 | ValueError: Invalid endpoint address 0x3 43 | ``` 44 | 45 | This usually only happens when auto_find is off. Otherwise, the library automatically discovers the endpoints for you! 46 | 47 | If this happens, try adding “in_ep = 0x81, out_ep = 0x03" to the create_usb function! If you are not receiving this error, do not add the additional parameters! 48 | If you continue to receive this error, try doing out_ep = 0x02. 49 | 50 | If that still doesn't work, make a ticket & we will handle it together! 51 | -------------------------------------------------------------------------------- /docs/_static/js/html5shiv.min.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @preserve HTML5 Shiv 3.7.3 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed 3 | */ 4 | !function(a,b){function c(a,b){var c=a.createElement("p"),d=a.getElementsByTagName("head")[0]||a.documentElement;return c.innerHTML="x",d.insertBefore(c.lastChild,d.firstChild)}function d(){var a=t.elements;return"string"==typeof a?a.split(" "):a}function e(a,b){var c=t.elements;"string"!=typeof c&&(c=c.join(" ")),"string"!=typeof a&&(a=a.join(" ")),t.elements=c+" "+a,j(b)}function f(a){var b=s[a[q]];return b||(b={},r++,a[q]=r,s[r]=b),b}function g(a,c,d){if(c||(c=b),l)return c.createElement(a);d||(d=f(c));var e;return e=d.cache[a]?d.cache[a].cloneNode():p.test(a)?(d.cache[a]=d.createElem(a)).cloneNode():d.createElem(a),!e.canHaveChildren||o.test(a)||e.tagUrn?e:d.frag.appendChild(e)}function h(a,c){if(a||(a=b),l)return a.createDocumentFragment();c=c||f(a);for(var e=c.frag.cloneNode(),g=0,h=d(),i=h.length;i>g;g++)e.createElement(h[g]);return e}function i(a,b){b.cache||(b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag()),a.createElement=function(c){return t.shivMethods?g(c,a,b):b.createElem(c)},a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+d().join().replace(/[\w\-:]+/g,function(a){return b.createElem(a),b.frag.createElement(a),'c("'+a+'")'})+");return n}")(t,b.frag)}function j(a){a||(a=b);var d=f(a);return!t.shivCSS||k||d.hasCSS||(d.hasCSS=!!c(a,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),l||i(a,d),a}var k,l,m="3.7.3-pre",n=a.html5||{},o=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,p=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,q="_html5shiv",r=0,s={};!function(){try{var a=b.createElement("a");a.innerHTML="",k="hidden"in a,l=1==a.childNodes.length||function(){b.createElement("a");var a=b.createDocumentFragment();return"undefined"==typeof a.cloneNode||"undefined"==typeof a.createDocumentFragment||"undefined"==typeof a.createElement}()}catch(c){k=!0,l=!0}}();var t={elements:n.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video",version:m,shivCSS:n.shivCSS!==!1,supportsUnknownElements:l,shivMethods:n.shivMethods!==!1,type:"default",shivDocument:j,createElement:g,createDocumentFragment:h,addElements:e};a.html5=t,j(b),"object"==typeof module&&module.exports&&(module.exports=t)}("undefined"!=typeof window?window:this,document); -------------------------------------------------------------------------------- /docs/_static/css/badge_only.css: -------------------------------------------------------------------------------- 1 | .fa:before{-webkit-font-smoothing:antialiased}.clearfix{*zoom:1}.clearfix:after,.clearfix:before{display:table;content:""}.clearfix:after{clear:both}@font-face{font-family:FontAwesome;font-style:normal;font-weight:400;src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix) format("embedded-opentype"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format("woff2"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format("woff"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format("truetype"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#FontAwesome) format("svg")}.fa:before{font-family:FontAwesome;font-style:normal;font-weight:400;line-height:1}.fa:before,a .fa{text-decoration:inherit}.fa:before,a .fa,li .fa{display:inline-block}li .fa-large:before{width:1.875em}ul.fas{list-style-type:none;margin-left:2em;text-indent:-.8em}ul.fas li .fa{width:.8em}ul.fas li .fa-large:before{vertical-align:baseline}.fa-book:before,.icon-book:before{content:"\f02d"}.fa-caret-down:before,.icon-caret-down:before{content:"\f0d7"}.fa-caret-up:before,.icon-caret-up:before{content:"\f0d8"}.fa-caret-left:before,.icon-caret-left:before{content:"\f0d9"}.fa-caret-right:before,.icon-caret-right:before{content:"\f0da"}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60}.rst-versions .rst-current-version:after{clear:both;content:"";display:block}.rst-versions .rst-current-version .fa{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:grey;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:1px solid #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width:768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}} -------------------------------------------------------------------------------- /examples/commands.py: -------------------------------------------------------------------------------- 1 | import functools 2 | from dataclasses import dataclass 3 | from typing import List 4 | 5 | from TikTokLive.types.events import GiftEvent, CommentEvent 6 | 7 | from TikTokPrinter import TikTokPrinterClient, EscposEngineGenerator, TikTokMedia 8 | from TikTokPrinter.types.objects import VoiceText, PrinterText, PrinterImage 9 | 10 | 11 | @dataclass 12 | class Context: 13 | name: str 14 | args: List[str] 15 | event: CommentEvent 16 | 17 | 18 | class TikTokLiveCommandPrinterClient(TikTokPrinterClient): 19 | """ 20 | Command System Client that overrides the main client 21 | """ 22 | 23 | def __init__(self, unique_id: str, command_prefix: str = "/", donation_threshold: int = 0, **options): 24 | options["process_initial_data"] = False 25 | super().__init__(unique_id, **options) 26 | self.command_prefix: str = command_prefix 27 | self.add_listener("comment", functools.partial(self._parse_comments)) 28 | self.add_listener("gift", functools.partial(self._parse_gifts)) 29 | self.donations: dict = dict() 30 | self.donation_threshold: int = donation_threshold 31 | 32 | async def _parse_comments(self, event: CommentEvent): 33 | # Not a command 34 | if not event.comment.startswith(self.command_prefix): 35 | return 36 | 37 | _command: List[str] = event.comment.split(" ") 38 | _name: str = _command[0].replace(self.command_prefix, "", 1) 39 | 40 | self.emit(f"/{_name}", Context(name=_name, args=_command[1:], event=event)) 41 | 42 | async def _parse_gifts(self, event: GiftEvent): 43 | # Check if valid 44 | if not event.user: 45 | return 46 | 47 | # If it's type 1 and the streak is over 48 | if not ((event.gift.gift_type == 1 and event.gift.repeat_end == 1) or event.gift.gift_type != 1): 49 | return 50 | 51 | diamonds: int = event.gift.extended_gift.diamond_count * event.gift.repeatCount 52 | 53 | # Threshold stuff 54 | before = client.donations.get(event.user.uniqueId, 0) 55 | after = diamonds + before 56 | client.donations[event.user.uniqueId] = after 57 | 58 | # If they hit the threshold, let them know 59 | if before < self.donation_threshold <= after: 60 | await self.send_message(f"Congratulations, {event.user.uniqueId}, you just unlocked command access!") 61 | 62 | 63 | client: TikTokLiveCommandPrinterClient = TikTokLiveCommandPrinterClient( 64 | unique_id="jakeandrich", 65 | engine=EscposEngineGenerator.create_usb( 66 | auto_find=True, # Automatically find your printer 67 | align="center" 68 | ), 69 | command_prefix="/" 70 | ) 71 | 72 | 73 | @client.on("/tts") 74 | async def on_tts(context: Context): 75 | message = " ".join(context.args) 76 | 77 | client.queue( 78 | VoiceText(content=message), 79 | PrinterText(f"{context.event.user.uniqueId}", bold=True), 80 | PrinterText(content=f"{client.command_prefix}{context.name} {message}"), 81 | PrinterImage(await TikTokMedia.user_image(context.event.user, circle=False), padding=True) 82 | ) 83 | 84 | 85 | if __name__ == '__main__': 86 | client.run("SESSION_ID_HERE") 87 | -------------------------------------------------------------------------------- /docs/search.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Search — TikTokPrinter documentation 7 | 8 | 9 | 10 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 47 | 48 |
52 | 53 |
54 |
55 |
56 |
    57 |
  • »
  • 58 |
  • Search
  • 59 |
  • 60 |
  • 61 |
62 |
63 |
64 |
65 |
66 | 67 | 74 | 75 | 76 |
77 | 78 |
79 | 80 |
81 |
82 | 96 |
97 |
98 |
99 |
100 | 105 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | -------------------------------------------------------------------------------- /docs/_static/js/html5shiv-printshiv.min.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @preserve HTML5 Shiv 3.7.3-pre | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed 3 | */ 4 | !function(a,b){function c(a,b){var c=a.createElement("p"),d=a.getElementsByTagName("head")[0]||a.documentElement;return c.innerHTML="x",d.insertBefore(c.lastChild,d.firstChild)}function d(){var a=y.elements;return"string"==typeof a?a.split(" "):a}function e(a,b){var c=y.elements;"string"!=typeof c&&(c=c.join(" ")),"string"!=typeof a&&(a=a.join(" ")),y.elements=c+" "+a,j(b)}function f(a){var b=x[a[v]];return b||(b={},w++,a[v]=w,x[w]=b),b}function g(a,c,d){if(c||(c=b),q)return c.createElement(a);d||(d=f(c));var e;return e=d.cache[a]?d.cache[a].cloneNode():u.test(a)?(d.cache[a]=d.createElem(a)).cloneNode():d.createElem(a),!e.canHaveChildren||t.test(a)||e.tagUrn?e:d.frag.appendChild(e)}function h(a,c){if(a||(a=b),q)return a.createDocumentFragment();c=c||f(a);for(var e=c.frag.cloneNode(),g=0,h=d(),i=h.length;i>g;g++)e.createElement(h[g]);return e}function i(a,b){b.cache||(b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag()),a.createElement=function(c){return y.shivMethods?g(c,a,b):b.createElem(c)},a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+d().join().replace(/[\w\-:]+/g,function(a){return b.createElem(a),b.frag.createElement(a),'c("'+a+'")'})+");return n}")(y,b.frag)}function j(a){a||(a=b);var d=f(a);return!y.shivCSS||p||d.hasCSS||(d.hasCSS=!!c(a,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),q||i(a,d),a}function k(a){for(var b,c=a.getElementsByTagName("*"),e=c.length,f=RegExp("^(?:"+d().join("|")+")$","i"),g=[];e--;)b=c[e],f.test(b.nodeName)&&g.push(b.applyElement(l(b)));return g}function l(a){for(var b,c=a.attributes,d=c.length,e=a.ownerDocument.createElement(A+":"+a.nodeName);d--;)b=c[d],b.specified&&e.setAttribute(b.nodeName,b.nodeValue);return e.style.cssText=a.style.cssText,e}function m(a){for(var b,c=a.split("{"),e=c.length,f=RegExp("(^|[\\s,>+~])("+d().join("|")+")(?=[[\\s,>+~#.:]|$)","gi"),g="$1"+A+"\\:$2";e--;)b=c[e]=c[e].split("}"),b[b.length-1]=b[b.length-1].replace(f,g),c[e]=b.join("}");return c.join("{")}function n(a){for(var b=a.length;b--;)a[b].removeNode()}function o(a){function b(){clearTimeout(g._removeSheetTimer),d&&d.removeNode(!0),d=null}var d,e,g=f(a),h=a.namespaces,i=a.parentWindow;return!B||a.printShived?a:("undefined"==typeof h[A]&&h.add(A),i.attachEvent("onbeforeprint",function(){b();for(var f,g,h,i=a.styleSheets,j=[],l=i.length,n=Array(l);l--;)n[l]=i[l];for(;h=n.pop();)if(!h.disabled&&z.test(h.media)){try{f=h.imports,g=f.length}catch(o){g=0}for(l=0;g>l;l++)n.push(f[l]);try{j.push(h.cssText)}catch(o){}}j=m(j.reverse().join("")),e=k(a),d=c(a,j)}),i.attachEvent("onafterprint",function(){n(e),clearTimeout(g._removeSheetTimer),g._removeSheetTimer=setTimeout(b,500)}),a.printShived=!0,a)}var p,q,r="3.7.3",s=a.html5||{},t=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,u=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,v="_html5shiv",w=0,x={};!function(){try{var a=b.createElement("a");a.innerHTML="",p="hidden"in a,q=1==a.childNodes.length||function(){b.createElement("a");var a=b.createDocumentFragment();return"undefined"==typeof a.cloneNode||"undefined"==typeof a.createDocumentFragment||"undefined"==typeof a.createElement}()}catch(c){p=!0,q=!0}}();var y={elements:s.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video",version:r,shivCSS:s.shivCSS!==!1,supportsUnknownElements:q,shivMethods:s.shivMethods!==!1,type:"default",shivDocument:j,createElement:g,createDocumentFragment:h,addElements:e};a.html5=y,j(b);var z=/^$|\b(?:all|print)\b/,A="html5shiv",B=!q&&function(){var c=b.documentElement;return!("undefined"==typeof b.namespaces||"undefined"==typeof b.parentWindow||"undefined"==typeof c.applyElement||"undefined"==typeof c.removeNode||"undefined"==typeof a.attachEvent)}();y.type+=" print",y.shivPrint=o,o(b),"object"==typeof module&&module.exports&&(module.exports=y)}("undefined"!=typeof window?window:this,document); -------------------------------------------------------------------------------- /examples/fancy/client.py: -------------------------------------------------------------------------------- 1 | import os 2 | import platform 3 | import random 4 | from typing import List 5 | 6 | from PIL import ImageDraw, Image, ImageFont 7 | from TikTokLive.types.events import ConnectEvent 8 | 9 | from TikTokPrinter import TikTokPrinterClient, TikTokMedia 10 | from TikTokPrinter.client.engines.escpos import EscposEngine 11 | 12 | 13 | class AdvancedClient(TikTokPrinterClient): 14 | FREDOKA_LARGE = ImageFont.truetype("./resources/fonts/fredoka.ttf", 38) 15 | FREDOKA_MID = ImageFont.truetype("./resources/fonts/fredoka.ttf", 26) 16 | FREDOKA_SMALL = ImageFont.truetype("./resources/fonts/fredoka.ttf", 16) 17 | 18 | MINI_ICONS: List[str] = [ 19 | "_devil.png", "_point.png", "_shocked.png", "_shoot.png", "_uwu.png", "_wholesome.png", "cry1.png", "cry2.png", "cry3.png", 20 | "embarassed1.png", "embarassed2.png", "love1.png", "love2.png", "love3.png", "love4.png", "love5.png", "love6.png", "love7.png", 21 | "love8.png", "love9.png", "love10.png" 22 | ] 23 | 24 | def __init__(self, unique_id: str, engine: EscposEngine, **options): 25 | super().__init__(unique_id, engine, **options) 26 | self.add_listener("connect", self.on_connect) 27 | 28 | async def on_connect(self, _: ConnectEvent): 29 | print("-------------------") 30 | print(f"Connected to @{self.unique_id}'s TikTok LIVE") 31 | print(f"Python version: {platform.python_version()}") 32 | print(f"Running on: {platform.system()} {platform.release()} ({os.name})") 33 | print("Go for launch! Prepare for madness.") 34 | 35 | @classmethod 36 | def get_cheap_amount(cls, message: str, username: str): 37 | image = Image.new("RGBA", (100, 200), (255, 255, 255)) 38 | draw: ImageDraw = ImageDraw.Draw(image) 39 | 40 | thank_message: str = message 41 | thank_width, thank_height = cls.FREDOKA_SMALL.getsize(thank_message) 42 | thank_start = ((image.width - thank_width) / 2, 18) 43 | draw.text(thank_start, thank_message, (0, 0, 0), font=cls.FREDOKA_LARGE) 44 | 45 | thank_message: str = username 46 | thank_width, thank_height = cls.FREDOKA_SMALL.getsize(thank_message) 47 | thank_start = ((image.width - thank_width) / 2, 50) 48 | draw.text(thank_start, thank_message, (0, 0, 0), font=cls.FREDOKA_LARGE) 49 | 50 | @classmethod 51 | def get_semi_expensive(cls, username: str, gift: str, amount: int): 52 | image = Image.new("RGBA", (400, 200), (255, 255, 255)) 53 | draw: ImageDraw = ImageDraw.Draw(image) 54 | 55 | # Paste heart 56 | heart = TikTokMedia.remove_transparency(Image.open(f"resources/icons/{random.choice(cls.MINI_ICONS)}")) 57 | heart.thumbnail((64, 64)) 58 | 59 | # Thank You 60 | thank_message: str = "Thank You" 61 | thank_width, thank_height = cls.FREDOKA_LARGE.getsize(thank_message) 62 | thank_start = ((image.width - thank_width) / 2, 18) 63 | draw.text(thank_start, thank_message, (0, 0, 0), font=cls.FREDOKA_LARGE) 64 | 65 | # Hearts 66 | image.paste(heart, (int((thank_start[0] - heart.width) / 2), 15)) 67 | image.paste(heart, (int((image.width - heart.width * 1.2)), 15)) 68 | 69 | # Username 70 | username_message: str = f"@{username}" 71 | name_font: ImageFont = cls.FREDOKA_LARGE 72 | n_w, n_h = cls.FREDOKA_LARGE.getsize(username_message) 73 | 74 | # Auto-resize 75 | if n_w > (image.width - 50): 76 | n_w, n_h = cls.FREDOKA_MID.getsize(username_message) 77 | name_font = cls.FREDOKA_MID 78 | 79 | if n_w > (image.width - 50): 80 | n_w, n_h = cls.FREDOKA_SMALL.getsize(username_message) 81 | name_font = cls.FREDOKA_SMALL 82 | 83 | username_start = ((image.width - n_w) / 2, (image.height - n_h) / 2) 84 | draw.text(username_start, username_message, (0, 122, 122), font=name_font) 85 | 86 | # Gift 87 | gift_message: str = f"for sending {amount}x {gift}" 88 | gift_width, gift_height = cls.FREDOKA_MID.getsize(gift_message) 89 | gift_start = ((image.width - gift_width) / 2, 140) 90 | draw.text(gift_start, gift_message, (0, 0, 0), font=cls.FREDOKA_MID) 91 | 92 | image = image.resize((500, 250)) 93 | 94 | return image.convert("L") 95 | -------------------------------------------------------------------------------- /docs/README.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | How To Build — TikTokPrinter documentation 8 | 9 | 10 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 45 | 46 |
50 | 51 |
52 |
53 |
54 | 61 |
62 |
63 |
64 |
65 | 66 |
67 |

How To Build

68 |
    69 |
  1. Complete commands:

  2. 70 |
71 |
**cd .sphinx
 72 | 
 73 | sphinx-apidoc --ext-autodoc --force -o  . ../TikTokPrinter
 74 | 
 75 | .\make html
 76 | 
77 |
78 |
    79 |
  1. Move generated sphinx /sphinx/_build/html folder to root, rename to “docs”

  2. 80 |
  3. Add .nojekyll file to new docs folder

  4. 81 |
82 |
83 | 84 | 85 |
86 |
87 | 101 |
102 |
103 |
104 |
105 | 110 | 111 | 112 | -------------------------------------------------------------------------------- /docs/_static/js/theme.js: -------------------------------------------------------------------------------- 1 | !function(n){var e={};function t(i){if(e[i])return e[i].exports;var o=e[i]={i:i,l:!1,exports:{}};return n[i].call(o.exports,o,o.exports,t),o.l=!0,o.exports}t.m=n,t.c=e,t.d=function(n,e,i){t.o(n,e)||Object.defineProperty(n,e,{enumerable:!0,get:i})},t.r=function(n){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(n,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(n,"__esModule",{value:!0})},t.t=function(n,e){if(1&e&&(n=t(n)),8&e)return n;if(4&e&&"object"==typeof n&&n&&n.__esModule)return n;var i=Object.create(null);if(t.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:n}),2&e&&"string"!=typeof n)for(var o in n)t.d(i,o,function(e){return n[e]}.bind(null,o));return i},t.n=function(n){var e=n&&n.__esModule?function(){return n.default}:function(){return n};return t.d(e,"a",e),e},t.o=function(n,e){return Object.prototype.hasOwnProperty.call(n,e)},t.p="",t(t.s=0)}([function(n,e,t){t(1),n.exports=t(3)},function(n,e,t){(function(){var e="undefined"!=typeof window?window.jQuery:t(2);n.exports.ThemeNav={navBar:null,win:null,winScroll:!1,winResize:!1,linkScroll:!1,winPosition:0,winHeight:null,docHeight:null,isRunning:!1,enable:function(n){var t=this;void 0===n&&(n=!0),t.isRunning||(t.isRunning=!0,e((function(e){t.init(e),t.reset(),t.win.on("hashchange",t.reset),n&&t.win.on("scroll",(function(){t.linkScroll||t.winScroll||(t.winScroll=!0,requestAnimationFrame((function(){t.onScroll()})))})),t.win.on("resize",(function(){t.winResize||(t.winResize=!0,requestAnimationFrame((function(){t.onResize()})))})),t.onResize()})))},enableSticky:function(){this.enable(!0)},init:function(n){n(document);var e=this;this.navBar=n("div.wy-side-scroll:first"),this.win=n(window),n(document).on("click","[data-toggle='wy-nav-top']",(function(){n("[data-toggle='wy-nav-shift']").toggleClass("shift"),n("[data-toggle='rst-versions']").toggleClass("shift")})).on("click",".wy-menu-vertical .current ul li a",(function(){var t=n(this);n("[data-toggle='wy-nav-shift']").removeClass("shift"),n("[data-toggle='rst-versions']").toggleClass("shift"),e.toggleCurrent(t),e.hashChange()})).on("click","[data-toggle='rst-current-version']",(function(){n("[data-toggle='rst-versions']").toggleClass("shift-up")})),n("table.docutils:not(.field-list,.footnote,.citation)").wrap("
"),n("table.docutils.footnote").wrap("
"),n("table.docutils.citation").wrap("
"),n(".wy-menu-vertical ul").not(".simple").siblings("a").each((function(){var t=n(this);expand=n(''),expand.on("click",(function(n){return e.toggleCurrent(t),n.stopPropagation(),!1})),t.prepend(expand)}))},reset:function(){var n=encodeURI(window.location.hash)||"#";try{var e=$(".wy-menu-vertical"),t=e.find('[href="'+n+'"]');if(0===t.length){var i=$('.document [id="'+n.substring(1)+'"]').closest("div.section");0===(t=e.find('[href="#'+i.attr("id")+'"]')).length&&(t=e.find('[href="#"]'))}if(t.length>0){$(".wy-menu-vertical .current").removeClass("current").attr("aria-expanded","false"),t.addClass("current").attr("aria-expanded","true"),t.closest("li.toctree-l1").parent().addClass("current").attr("aria-expanded","true");for(let n=1;n<=10;n++)t.closest("li.toctree-l"+n).addClass("current").attr("aria-expanded","true");t[0].scrollIntoView()}}catch(n){console.log("Error expanding nav for anchor",n)}},onScroll:function(){this.winScroll=!1;var n=this.win.scrollTop(),e=n+this.winHeight,t=this.navBar.scrollTop()+(n-this.winPosition);n<0||e>this.docHeight||(this.navBar.scrollTop(t),this.winPosition=n)},onResize:function(){this.winResize=!1,this.winHeight=this.win.height(),this.docHeight=$(document).height()},hashChange:function(){this.linkScroll=!0,this.win.one("hashchange",(function(){this.linkScroll=!1}))},toggleCurrent:function(n){var e=n.closest("li");e.siblings("li.current").removeClass("current").attr("aria-expanded","false"),e.siblings().find("li.current").removeClass("current").attr("aria-expanded","false");var t=e.find("> ul li");t.length&&(t.removeClass("current").attr("aria-expanded","false"),e.toggleClass("current").attr("aria-expanded",(function(n,e){return"true"==e?"false":"true"})))}},"undefined"!=typeof window&&(window.SphinxRtdTheme={Navigation:n.exports.ThemeNav,StickyNav:n.exports.ThemeNav}),function(){for(var n=0,e=["ms","moz","webkit","o"],t=0;t 50: 40 | return 41 | 42 | client.queue( 43 | PrinterText("-" * 20), 44 | PrinterText(f"@{event.user.uniqueId}", bold=True), 45 | PrinterText("Thank you for the likes!! <3<3") 46 | ) 47 | 48 | 49 | @client.on("join") 50 | async def on_join(event: JoinEvent): 51 | # Check if valid 52 | if not event.user: 53 | return 54 | 55 | # Only do this if the viewer count is less than 20 56 | if client.viewer_count and client.viewer_count > 20: 57 | return 58 | 59 | client.queue( 60 | PrinterText("-" * 20), 61 | PrinterText(f"@{event.user.uniqueId}", bold=True), 62 | PrinterText("Welcome to the LIVE!") 63 | ) 64 | 65 | 66 | @client.on("follow") 67 | async def on_follow(event: FollowEvent): 68 | # Check if valid 69 | if not event.user: 70 | return 71 | 72 | # Only do this if the viewer count is less than 20 73 | if client.viewer_count and client.viewer_count > 20: 74 | return 75 | 76 | client.queue( 77 | PrinterText("-" * 20), 78 | PrinterText(f"@{event.user.uniqueId}", bold=True), 79 | PrinterText("Thank you for the follow!!!") 80 | ) 81 | 82 | 83 | @client.on("gift") 84 | async def on_gift(event: GiftEvent): 85 | # Check if valid 86 | if not event.user: 87 | return 88 | 89 | # If it's type 1 and the streak is over 90 | if not ((event.gift.gift_type == 1 and event.gift.repeat_end == 1) or event.gift.gift_type != 1): 91 | return 92 | 93 | diamonds: int = event.gift.extended_gift.diamond_count * event.gift.repeatCount 94 | 95 | # If less than 5 diamonds (CHEAP) 96 | if diamonds < 5: 97 | client.queue( 98 | PrinterText("-" * 20), 99 | PrinterText(f"Thank you so much!! :D"), 100 | PrinterText(f"@{event.user.uniqueId}", bold=True), 101 | PrinterText(f"For sending {event.gift.repeatCount}x {event.gift.extended_gift.name}") 102 | ) 103 | 104 | return 105 | 106 | # If between 5 & 10 diamonds (SEMI-EXPENSIVE) 107 | if 5 <= diamonds <= 10: 108 | client.queue( 109 | PrinterImage( 110 | # Download the gift image and print it 111 | await TikTokMedia.gift_image(event.gift) 112 | ), 113 | PrinterImage( 114 | # Get a custom special image :) 115 | client.get_semi_expensive(event.user.uniqueId, event.gift.extended_gift.name, event.gift.repeatCount) 116 | ) 117 | ) 118 | 119 | return 120 | 121 | # If diamonds are greater than 10 122 | client.queue( 123 | 124 | PrinterImage( 125 | # Get a custom special image :) 126 | client.get_semi_expensive(event.user.uniqueId, event.gift.giftDetails.giftName, event.gift.repeatCount) 127 | ), 128 | 129 | PrinterImage( 130 | # Download the gift image and print it 131 | await TikTokMedia.gift_image(event.gift) 132 | ), 133 | 134 | PrinterImage( 135 | # Download the user image and print it 136 | await TikTokMedia.user_image(event.user) 137 | ), 138 | 139 | VoiceText( 140 | # Say thanks for the gift 141 | random.choice([ 142 | f"Woah, hotshot! Thanks {event.user.uniqueId} for the {event.gift.repeatCount} {event.gift.giftDetails.giftName}", 143 | f"Woah, thanks {event.user.uniqueId} for the {event.gift.repeatCount} {event.gift.giftDetails.giftName}", 144 | f"You're on fire! Thanks {event.user.uniqueId} for the {event.gift.repeatCount} {event.gift.giftDetails.giftName}", 145 | f"That's freaking insane! Thanks {event.user.uniqueId} for the {event.gift.repeatCount} {event.gift.giftDetails.giftName}", 146 | ]) 147 | ) 148 | ) 149 | 150 | 151 | if __name__ == '__main__': 152 | """ 153 | Receiving an Invalid Endpoint error with a USB printer? 154 | 155 | Try adding “in_ep = 0x81, out_ep = 0x03" to the create_usb function! 156 | If you are not receiving this error, do not add the additional parameters! 157 | If you continue to receive this error, try doing out_ep = 0x02. 158 | 159 | If that still doesn't work, make a ticket & we will handle it together! 160 | 161 | """ 162 | 163 | client.run() 164 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | TikTokPrinter - Thermal Printer Software (Abandoned) 2 | ================== 3 | A Python library to print to thermal printers from TikTokLive. 4 | 5 | [![LinkedIn](https://img.shields.io/badge/LinkedIn-0077B5?style=for-the-badge&logo=linkedin&logoColor=white&style=flat-square)](https://www.linkedin.com/in/isaac-kogan-5a45b9193/ ) 6 | [![HitCount](https://hits.dwyl.com/isaackogan/TikTokPrinter.svg?style=flat)](http://hits.dwyl.com/isaackogan/TikTokLive) 7 | ![Forks](https://img.shields.io/github/forks/isaackogan/TikTokPrinter) 8 | ![Stars](https://img.shields.io/github/stars/isaackogan/TikTokPrinter) 9 | [![Support Server](https://img.shields.io/discord/831349828578574346.svg?color=7289da&logo=discord&style=flat-square&t=3)](https://discord.gg/4Mbw58w5Qx) 10 | 11 | Welcome to the public GitHub information page for the number one best-selling, most customizable & professional-grade tool for thermal printing on TikTok. 12 | 13 | ### **BUY HERE: https://discord.gg/4Mbw58w5Qx** 14 | 15 | Thermal printing is a very recent, very exciting trend on TikTok. It is also a very **complex** one. Not because the topic is difficult in and of itself, but because people want so many different things. 16 | 17 | That's why I developed an all-encompassing, multithreaded thermal printing program that does... everything, including a comprehensive [video tutorial](https://www.youtube.com/watch?v=NeapS5Jn_oo) on how to use it, made by me. 18 | 19 | No subscription unlike many virtual printer services. One-time, life-time purchase. Can be installed in python via pip. Includes access to all future releases/updates to the project. 20 | 21 | ## ❤️ [Get It Now](#purchase-now) ❤️ 22 | 23 | ### YouTube Showcase & Tutorial 24 | 25 | If you want to see just how powerful this library is (and easy to use), we made a video tutorial & showcase 26 | that goes through the basics of how to get started using it. Click the thumbnail below to warp. 27 | 28 | [![YouTube Tutorial & Showcase](https://i.imgur.com/UoIrSwr.png)](https://www.youtube.com/watch?v=NeapS5Jn_oo) 29 | 30 | ### Auto-Select 31 | 32 | Automatically find & use your USB printer. 33 | 34 | ![image](https://user-images.githubusercontent.com/65869106/166118006-7c3ccdff-4dc7-48d6-b581-99f28b5e643f.png) 35 | 36 | ### Purchase Details (Cost, Pricing Logic, etc.) 37 | 38 | The cost is a flat `$25.90 USD`. 39 | 40 | This library is the most advanced, most purchased printer script on the market. Not only does it have an insane number of features, it was made by the person that _created_ 41 | the TikTokLive library. That gives you a benefit of ensuring that it is not only guaranteed to work, but guaranteed to be the best of the best you will possibly find. 42 | 43 | The price is set at what it is because of the ridiculous amount of time spent learning to program, creating the TikTokLive library, figuring out how to print on Windows, MacOS and Linux, creating guides, building the 44 | highly complex script itself, learning all the ways it can go wrong and fixing them, dealing with customer issues and so much more. 45 | 46 | Purchasing this script is an investment that you can make thousands of dollars off of. At this price-point, that's a hell of a deal. You are recommended to have basic Python knowledge to use this library. 47 | 48 | ### [Purchase Now](https://discord.gg/4Mbw58w5Qx) 49 | 50 | To buy this library, create a ticket in the `#tickets` channel in https://discord.gg/4Mbw58w5Qx. 51 | 52 | Type the message "Printer Magic" in the ticket and I will immediately get you started so that you can get to printing as fast as possible! 53 | 54 | ### Printer Library Example 55 | 56 | Here's a sample of what you can do with this library in less than 30 lines of code: 57 | 58 | ![](https://github.com/isaackogan/TikTokLive/raw/master/.github/RESOURCES/printer.gif) 59 | 60 | To show you just how advanced the library is, here we can print a profile picture, play a sound, and do text-to-speech... in just 3 "true" lines of code. This is insane. 61 | 62 | ```py 63 | @client.on("comment") 64 | async def on_comment(event: CommentEvent): 65 | client.queue( 66 | 67 | # Divier Text 68 | PrinterText("-" * 20), 69 | 70 | # Speak the comment 71 | VoiceText(event.user.uniqueId + " said " + event.comment), 72 | 73 | # Print the comment to printer 74 | PrinterText(event.user.uniqueId + " -> " + event.comment), 75 | 76 | # Play a sound 77 | SoundFile("enchanted.wav"), 78 | 79 | # Download their avatar and print the image 80 | PrinterImage(await TikTokMedia.user_image(event.user, circle=False)) 81 | 82 | ) 83 | ``` 84 | 85 | ### Feature List (30+ Features) 86 | 87 | #### Primary Features 88 | 89 | - Ready-to-go script included for non-programmers (basic knowledge still recommended) that has everything you need, already put together 90 | - Automatically find your printer device 91 | - Print ANY Message 92 | - Print Profile Pictures, Gift Images, Custom Images 93 | - CUSTOM Text to Speech (perhaps when someone gifts?) 94 | - Play Sounds (perhaps when someone gifts?) 95 | - Support for ALL Serial, USB, and Network ESC-POS printers 96 | - Automatic setup script 97 | - Support for MacOS, Windows, Linux 98 | - Fully documented API 99 | - Quick-install with PIP 100 | - Access to future releases/updates 101 | - Video Set-Up Tutorial 102 | - Made to be easy to use for newbies 103 | - Access to private discord chat for clients 104 | 105 | ### Additional Features 106 | 107 | - Download and print TikTok user avatars, gifts 108 | - Extremely high level API (There is zero need to touch anything low-level, I've got it covered) 109 | - 100% Asynchronous Programming 110 | - Bold messages 111 | - Left, Right, Center Adjust 112 | - Newline character support 113 | - Print backwards (flip the input!) 114 | - Insert items at the start of the print queue (priority) 115 | - Insert items at the end of the print queue 116 | - Insert items at any index in the print queue 117 | - Custom errors built on top of the API describing what went wrong when it happens 118 | - Errors do not kill the script. Even if a part of a message breaks, the rest still prints! 119 | - Send messages to the TikTok LIVE Chat (chat-bot) 120 | - How-to example on basic usage (using formatting, text-to-speech, sounds, images, etc.) 121 | - How-to example on using gifts 122 | - How-to example on using commands 123 | - How-to example on other features 124 | - Automatically find in_ep and out_ep values 125 | 126 | -------------------------------------------------------------------------------- /docs/modules.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | TikTokPrinter — TikTokPrinter documentation 8 | 9 | 10 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 45 | 46 |
50 | 51 |
52 |
53 |
54 | 61 |
62 |
63 | 105 |
106 | 107 |
108 | 109 |
110 |

© Copyright 2022, Isaac Kogan.

111 |
112 | 113 | Built with Sphinx using a 114 | theme 115 | provided by Read the Docs. 116 | 117 | 118 |
119 |
120 |
121 |
122 |
123 | 128 | 129 | 130 | -------------------------------------------------------------------------------- /docs/py-modindex.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Python Module Index — TikTokPrinter documentation 7 | 8 | 9 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 47 | 48 |
52 | 53 |
54 |
55 |
56 |
    57 |
  • »
  • 58 |
  • Python Module Index
  • 59 |
  • 60 |
  • 61 |
62 |
63 |
64 |
65 |
66 | 67 | 68 |

Python Module Index

69 | 70 |
71 | t 72 |
73 | 74 | 75 | 76 | 78 | 79 | 81 | 84 | 85 | 86 | 89 | 90 | 91 | 94 | 95 | 96 | 99 | 100 | 101 | 104 | 105 | 106 | 109 | 110 | 111 | 114 | 115 | 116 | 119 | 120 | 121 | 124 | 125 | 126 | 129 | 130 | 131 | 134 | 135 | 136 | 139 | 140 | 141 | 144 | 145 | 146 | 149 | 150 | 151 | 154 | 155 | 156 | 159 | 160 | 161 | 164 |
 
77 | t
82 | TikTokPrinter 83 |
    87 | TikTokPrinter.client 88 |
    92 | TikTokPrinter.client.client 93 |
    97 | TikTokPrinter.client.engines 98 |
    102 | TikTokPrinter.client.engines.console 103 |
    107 | TikTokPrinter.client.engines.escpos 108 |
    112 | TikTokPrinter.client.engines.sound 113 |
    117 | TikTokPrinter.client.engines.voice 118 |
    122 | TikTokPrinter.client.printer 123 |
    127 | TikTokPrinter.client.printer.engine 128 |
    132 | TikTokPrinter.client.printer.interface 133 |
    137 | TikTokPrinter.tiktok 138 |
    142 | TikTokPrinter.tiktok.http 143 |
    147 | TikTokPrinter.tiktok.media 148 |
    152 | TikTokPrinter.types 153 |
    157 | TikTokPrinter.types.errors 158 |
    162 | TikTokPrinter.types.objects 163 |
165 | 166 | 167 |
168 |
169 |
170 | 171 |
172 | 173 |
174 |

© Copyright 2022, Isaac Kogan.

175 |
176 | 177 | Built with Sphinx using a 178 | theme 179 | provided by Read the Docs. 180 | 181 | 182 |
183 |
184 |
185 |
186 |
187 | 192 | 193 | 194 | -------------------------------------------------------------------------------- /docs/TikTokPrinter.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | TikTokPrinter package — TikTokPrinter documentation 8 | 9 | 10 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 56 | 57 |
61 | 62 |
63 |
64 |
65 | 72 |
73 |
74 |
75 |
76 | 77 |
78 |

TikTokPrinter package

79 |
80 |

Subpackages

81 | 124 |
125 |
126 |

Module contents

127 |

Copyright (C) Isaac Kogan, Inc - All Rights Reserved 128 | Unauthorized copying of this project, via any medium is strictly prohibited 129 | Proprietary work of Isaac Kogan 130 | Written by Isaac Kogan <isaacikogan@gmail.com>, April 2022

131 |

You are permitted to use this project commercially so long as it was purchased firsthand from Isaac Kogan. 132 | Distributing secondhand copies to others is strictly prohibited & is illegal.

133 |

You can do anything with this project except redistribute it.

134 |
135 |
136 | 137 | 138 |
139 |
140 |
144 | 145 |
146 | 147 |
148 |

© Copyright 2022, Isaac Kogan.

149 |
150 | 151 | Built with Sphinx using a 152 | theme 153 | provided by Read the Docs. 154 | 155 | 156 |
157 |
158 |
159 |
160 |
161 | 166 | 167 | 168 | -------------------------------------------------------------------------------- /docs/searchindex.js: -------------------------------------------------------------------------------- 1 | Search.setIndex({docnames:["README","TikTokPrinter","TikTokPrinter.client","TikTokPrinter.client.engines","TikTokPrinter.client.printer","TikTokPrinter.tiktok","TikTokPrinter.types","index","modules"],envversion:{"sphinx.domains.c":2,"sphinx.domains.changeset":1,"sphinx.domains.citation":1,"sphinx.domains.cpp":5,"sphinx.domains.index":1,"sphinx.domains.javascript":2,"sphinx.domains.math":2,"sphinx.domains.python":3,"sphinx.domains.rst":2,"sphinx.domains.std":2,sphinx:56},filenames:["README.md","TikTokPrinter.rst","TikTokPrinter.client.rst","TikTokPrinter.client.engines.rst","TikTokPrinter.client.printer.rst","TikTokPrinter.tiktok.rst","TikTokPrinter.types.rst","index.rst","modules.rst"],objects:{"":[[1,0,0,"-","TikTokPrinter"]],"TikTokPrinter.client":[[2,0,0,"-","client"],[3,0,0,"-","engines"],[4,0,0,"-","printer"]],"TikTokPrinter.client.client":[[2,1,1,"","TikTokPrinterClient"]],"TikTokPrinter.client.client.TikTokPrinterClient":[[2,2,1,"","image"],[2,2,1,"","queue"],[2,2,1,"","run"],[2,2,1,"","sound"],[2,2,1,"","start"],[2,2,1,"","text"],[2,2,1,"","voice"]],"TikTokPrinter.client.engines":[[3,0,0,"-","console"],[3,0,0,"-","escpos"],[3,0,0,"-","sound"],[3,0,0,"-","voice"]],"TikTokPrinter.client.engines.console":[[3,1,1,"","Console"]],"TikTokPrinter.client.engines.console.Console":[[3,2,1,"","image"],[3,2,1,"","set"],[3,2,1,"","text"]],"TikTokPrinter.client.engines.escpos":[[3,1,1,"","EscposEngine"],[3,1,1,"","EscposEngineGenerator"]],"TikTokPrinter.client.engines.escpos.EscposEngineGenerator":[[3,2,1,"","create_console"],[3,2,1,"","create_network"],[3,2,1,"","create_serial"],[3,2,1,"","create_usb"]],"TikTokPrinter.client.engines.sound":[[3,1,1,"","SoundEngine"]],"TikTokPrinter.client.engines.sound.SoundEngine":[[3,2,1,"","play"]],"TikTokPrinter.client.engines.voice":[[3,1,1,"","VoiceEngine"]],"TikTokPrinter.client.engines.voice.VoiceEngine":[[3,3,1,"","QUEUE_INTERVAL"],[3,2,1,"","speak"],[3,2,1,"","start"],[3,2,1,"","stop"]],"TikTokPrinter.client.printer":[[4,0,0,"-","engine"],[4,0,0,"-","interface"]],"TikTokPrinter.client.printer.engine":[[4,1,1,"","PrinterEngine"]],"TikTokPrinter.client.printer.engine.PrinterEngine":[[4,2,1,"","image"],[4,2,1,"","sound"],[4,2,1,"","text"],[4,2,1,"","voice"]],"TikTokPrinter.client.printer.interface":[[4,1,1,"","PrinterInterface"]],"TikTokPrinter.client.printer.interface.PrinterInterface":[[4,3,1,"","QUEUE_INTERVAL"],[4,2,1,"","image"],[4,2,1,"","queue"],[4,2,1,"","sound"],[4,2,1,"","start"],[4,2,1,"","stop"],[4,2,1,"","text"],[4,2,1,"","voice"]],"TikTokPrinter.tiktok":[[5,0,0,"-","http"],[5,0,0,"-","media"]],"TikTokPrinter.tiktok.http":[[5,1,1,"","GiftImage"],[5,1,1,"","ProfileImage"]],"TikTokPrinter.tiktok.http.GiftImage":[[5,4,1,"","url"]],"TikTokPrinter.tiktok.http.ProfileImage":[[5,3,1,"","DEFAULT_REQUEST_HEADERS"],[5,2,1,"","generate_device_id"],[5,2,1,"","to_bytes"],[5,2,1,"","to_download"],[5,4,1,"","url"]],"TikTokPrinter.tiktok.media":[[5,1,1,"","TikTokMedia"]],"TikTokPrinter.tiktok.media.TikTokMedia":[[5,2,1,"","gift_image"],[5,2,1,"","mask_circle_transparent"],[5,2,1,"","remove_transparency"],[5,2,1,"","user_image"]],"TikTokPrinter.types":[[6,0,0,"-","errors"],[6,0,0,"-","objects"]],"TikTokPrinter.types.errors":[[6,5,1,"","InvalidImageObject"],[6,5,1,"","InvalidPrinterObject"],[6,5,1,"","MissingPrinterDriver"],[6,5,1,"","NoDevicesFound"],[6,5,1,"","SetupMonkeyPatch"]],"TikTokPrinter.types.objects":[[6,1,1,"","CollectionItem"],[6,1,1,"","PrinterCollection"],[6,1,1,"","PrinterImage"],[6,1,1,"","PrinterText"],[6,1,1,"","SoundFile"],[6,1,1,"","VoiceText"]],"TikTokPrinter.types.objects.PrinterCollection":[[6,3,1,"","content"]],"TikTokPrinter.types.objects.PrinterImage":[[6,3,1,"","content"],[6,3,1,"","padding"]],"TikTokPrinter.types.objects.PrinterText":[[6,3,1,"","bold"],[6,3,1,"","content"]],"TikTokPrinter.types.objects.SoundFile":[[6,3,1,"","file_path"]],"TikTokPrinter.types.objects.VoiceText":[[6,3,1,"","content"]],TikTokPrinter:[[2,0,0,"-","client"],[5,0,0,"-","tiktok"],[6,0,0,"-","types"]]},objnames:{"0":["py","module","Python module"],"1":["py","class","Python class"],"2":["py","method","Python method"],"3":["py","attribute","Python attribute"],"4":["py","property","Python property"],"5":["py","exception","Python exception"]},objtypes:{"0":"py:module","1":"py:class","2":"py:method","3":"py:attribute","4":"py:property","5":"py:exception"},terms:{"0":[3,4,5],"0x03":3,"0x81":3,"1":[2,3,5],"10":5,"100":7,"1000":3,"129":[],"20":7,"200":5,"2022":[1,2,3,4,5,6],"255":5,"3":[5,7],"36":5,"4692":5,"5":[4,5],"50":7,"537":5,"60":3,"8":3,"9":5,"9100":3,"9600":3,"97":5,"99":5,"break":7,"byte":5,"class":[2,3,4,5,6],"default":5,"do":[1,2,3,4,5,6,7],"float":[3,4],"int":[2,3,4,5],"long":[1,2,3,4,5,6],"new":[0,5],"public":7,"return":[2,3,4,5],"static":[3,5],"true":[3,5,6,7],A:[2,6,7],At:7,For:3,If:[3,5,7],It:7,No:[6,7],Not:7,One:7,That:[3,7],The:[2,3,4,5,7],There:7,To:[3,6,7],__init__:3,_build:0,abov:7,abstracteventloop:[3,4],accept:5,access:7,action:6,ad:6,add:[0,5,6],address:3,adjust:7,advanc:7,ag:5,agent:5,aliv:5,all:[1,2,3,4,5,6,7],alreadi:7,also:7,amount:7,an:[2,3,4,5,6,7],ani:[1,2,3,4,5,6,7],anyth:[1,2,3,4,5,6,7],api:7,apidoc:0,append:6,applewebkit:5,applic:5,april:[1,2,3,4,5,6],ar:[1,2,3,4,5,6,7],area:5,arg:3,argument:3,around:5,async:[2,4,5,7],asynchron:[2,7],asyncio:[3,4],author:5,auto:3,auto_find:3,autodoc:0,automat:[3,7],avatar:7,await:[3,7],background:5,backward:7,base:[2,3,4,5,6],basic:7,baudrat:3,becaus:7,befor:6,below:7,benefit:7,best:7,between:3,block:2,blur:5,blur_radiu:5,bold:[2,4,6,7],bool:[2,3,4,5,6],bot:7,bui:7,build:7,built:7,bytes:3,c:[1,2,3,4,5,6],cach:5,can:[1,2,3,4,5,6,7],cd:0,center:7,channel:7,charact:7,chat:7,cheap:7,check:6,chrome:5,circl:[5,7],circle_blur_radiu:5,classmethod:[3,5],click:7,client:[1,7,8],code:7,collect:[2,4,6],collectionitem:6,colour:5,com:[1,2,3,4,5,6],command:[0,2,3,4,7],comment:7,commentev:7,commerci:[1,2,3,4,5,6],complet:0,complex:7,comprehens:7,connect:[2,5,6],consecut:[2,4],consol:[1,2],contain:4,content:[7,8],control:[4,5],copi:[1,2,3,4,5,6],copyright:[1,2,3,4,5,6],cor:5,could:6,cover:7,creat:[3,7],create_consol:3,create_network:3,create_seri:3,create_usb:3,crop:5,custom:[3,5,7],custom_head:5,customiz:7,deal:7,def:7,default_request_head:5,deflat:5,describ:7,desir:4,dest:5,detail:[],detect:3,dev:3,develop:7,devfil:3,devic:[3,6],device_id:5,dict:5,differ:7,difficult:7,discord:7,distribut:[1,2,3,4,5,6],divier:7,doc:0,document:7,doe:7,dollar:7,download:[3,5,7],driver:6,dsrdtr:3,dummi:3,easi:7,empti:5,en:[3,5],enchant:7,encod:5,encompass:7,end:7,endpoint:3,engin:[1,2],ensur:7,error:[1,3,7,8],esc:7,escpo:[1,2,4],escposengin:[2,3,4],escposenginegener:3,etc:4,even:7,event:[3,4,7],everyth:[4,7],except:[1,2,3,4,5,6],excit:7,ext:0,extra:3,extrem:7,fals:[2,3,4,6,7],fast:7,fetch:5,figur:7,file:[0,2,3,4,5,6],file_path:[2,3,4,6],find:[3,7],firsthand:[1,2,3,4,5,6],fix:[3,7],flat:7,flip:7,folder:0,follow:3,forc:0,format:[2,3,4,5,7],found:[3,6],from:[1,2,3,4,5,6,7],fulli:7,futur:7,gcp:5,gecko:5,gener:[0,3,5],generate_device_id:5,get:[5,6,7],gg:7,gift:[5,7],gift_imag:5,giftimag:5,github:7,give:7,given:[3,5],gmail:[1,2,3,4,5,6],go:7,goe:7,got:7,grade:7,guarante:7,guid:7,gzip:5,h8m3c6jsf4:7,ha:7,handl:4,happen:7,have:7,header:5,hell:7,here:7,hex:3,high:7,highli:7,host:3,hostnam:3,how:[3,7],html:[0,5],http:[1,3,7,8],i:7,id:[2,3],ignor:3,illeg:[1,2,3,4,5,6],imag:[2,3,4,5,6,7],img_sourc:3,immedi:7,in_ep:3,in_ep_overrid:3,inc:[1,2,3,4,5,6],includ:7,index:[2,4,5,7],inform:[3,7],initi:3,inner:4,input:7,insan:7,insert:[2,4,7],instal:[6,7],intens:5,interact:2,interfac:[1,2],interv:4,invalid:[3,6],invalidimageobject:6,invalidprinterobject:6,invest:7,io:3,isaac:[1,2,3,4,5,6],isaacikogan:[1,2,3,4,5,6],issu:7,item:[6,7],itself:7,jeanm:[2,3,4,5,6],json:5,just:7,keep:5,khtml:5,kill:7,knowledg:7,kogan:[1,2,3,4,5,6],kwarg:3,languag:5,latest:3,learn:7,left:7,less:7,level:7,lib:[2,3,4,5,6],life:7,like:[5,6],line:7,linux:7,list:[2,3,5,6],live:7,look:5,loop:[3,4],loud:4,low:7,m:5,maco:7,made:7,magic:7,main:2,make:[0,2,4,5,7],mani:7,market:7,mask_circle_transpar:5,max:5,me:[5,7],media:[1,8],medium:[1,2,3,4,5,6],messag:[2,3,4,7],method:3,might:3,miss:6,missingprinterdriv:[3,6],mode:5,modul:[7,8],monkei:6,more:[3,6,7],most:7,mostli:3,move:0,mozilla:5,much:7,multipl:[2,4],multithread:7,n:3,necessari:5,need:7,network:[3,7],newbi:7,newlin:7,nicer:5,nkmk:5,nodevicesfound:6,nojekyl:0,non:7,none:[2,3,4,5,6],nonetyp:6,note:5,nt:5,number:7,o:0,object:[1,3,4,5,8],off:7,offset:5,on_com:7,onc:[2,4],one:[3,5,7],onli:7,option:[2,3,5],origin:5,other:[1,2,3,4,5,6,7],out:[4,7],out_ep:3,out_ep_overrid:3,overrid:[2,3,4],packag:[7,8],pad:6,page:7,paramet:[2,3,4,5],pariti:3,part:7,pass:[3,6],patch:6,path:[2,3,4,5,6],peopl:7,perform:[2,4,6],perhap:7,permit:[1,2,3,4,5,6],person:7,pick:5,pictur:[5,7],pil:[2,3,4,5,6],pillow:[5,6],pip:7,plai:[2,3,4,6,7],plain:5,pleas:6,po:7,point:7,port:3,possibl:[3,7],power:7,prevent:6,print:[2,3,4,6,7],printer:[1,2,3,6],printercollect:[4,6],printerengin:4,printerimag:[4,6,7],printerinterfac:4,printertext:[4,6,7],printertwo:[2,3,4,5,6],prioriti:7,privat:7,product:3,product_id:3,profession:7,profil:[5,7],profileimag:5,program:7,programm:7,prohibit:[1,2,3,4,5,6],project:[1,2,3,4,5,6,7],properti:5,proprietari:[1,2,3,4,5,6],protobuf:5,provid:5,proxi:5,purchas:[1,2,3,4,5,6],put:7,py:[2,3,4,5,6],pycharmproject:[2,3,4,5,6],python:[3,5,7],q:5,queue:[2,3,4,6,7],queue_interv:[3,4],quick:7,radiu:5,rais:3,random:5,readi:7,readthedoc:3,receiv:3,recent:7,recommend:7,redistribut:[1,2,3,4,5,6],refer:5,releas:7,remov:5,remove_transpar:5,renam:0,repres:6,request:5,requir:6,reserv:[1,2,3,4,5,6],rest:7,rgba:5,ridicul:7,right:[1,2,3,4,5,6,7],root:0,run:2,runtimeerror:6,s:[3,5,7],safari:5,said:7,sampl:7,scheme:5,scrape:5,script:7,sec:5,secondhand:[1,2,3,4,5,6],see:7,select:3,sell:7,send:[2,4,7],sent:[2,4],serial:[3,7],servic:7,session:2,session_id:2,set:[2,3,4,7],setup:[6,7],setupmonkeypatch:6,show:[3,7],singl:2,site:[2,3,4,5,6],size:5,so:[1,2,3,4,5,6,7],someon:7,song:3,sound:[1,2,4,7],soundengin:[2,3,4],soundfil:[4,6,7],speak:[3,4,6,7],speech:[3,4,6,7],spent:7,sphinx:0,squar:5,start:[2,3,4,7],still:7,stop:[3,4],stopbit:3,str:[2,3,4,5,6],strictli:[1,2,3,4,5,6],string:[3,6],submodul:[1,8],subpackag:[7,8],subscript:7,successfulli:5,support:7,synchron:2,system:6,task:4,text:[2,3,4,6,7],than:[6,7],thei:2,them:7,thermal:3,thi:[1,2,3,4,5,6,7],thing:7,thousand:7,thread:2,through:7,thu:6,thumbnail:[5,7],ticket:7,tiktok:[1,7,8],tiktokl:[2,5,7],tiktoklivecli:2,tiktokmedia:[5,7],tiktokprint:0,tiktokprintercli:2,time:7,timeout:3,to_byt:5,to_download:5,togeth:7,tool:7,top:7,topic:7,touch:7,transform:5,transpar:5,tree:7,trend:7,ttys0:3,tupl:5,turn:5,tutori:[],txt:3,type:[1,2,4,5,7,8],unauthor:[1,2,3,4,5,6],underli:2,union:3,unique_id:2,uniqueid:7,unlik:7,up:7,updat:7,url:5,us:[1,2,3,4,5,6,7],usag:7,usb:[3,6,7],usbdeview:3,usd:7,user:[2,3,4,5,6,7],user_imag:[5,7],util:5,utter:3,valid:5,valu:3,variou:[4,5,6],ve:7,vendor:3,vendor_id:3,venv:[2,3,4,5,6],veri:7,via:[1,2,3,4,5,6,7],video:7,view:7,virtual:7,visit:3,voic:[1,2,4],voiceengin:[2,3,4],voicetext:[4,6,7],wa:[1,2,3,4,5,6,7],wai:7,wait:3,want:[2,7],warp:7,wav:7,we:7,welcom:7,went:7,what:7,when:[2,7],whether:[2,4,5],which:4,why:7,win64:5,window:[5,6,7],without:2,work:[1,2,3,4,5,6,7],written:[1,2,3,4,5,6],wrong:7,www:5,x64:5,xonxoff:3,you:[1,2,3,4,5,6,7],your:[3,4,6,7],zero:7},titles:["How To Build","TikTokPrinter package","TikTokPrinter.client package","TikTokPrinter.client.engines package","TikTokPrinter.client.printer package","TikTokPrinter.tiktok package","TikTokPrinter.types package","TikTokPrinter Docs","TikTokPrinter"],titleterms:{"30":7,To:0,addit:7,auto:7,build:0,client:[2,3,4],consol:3,content:[1,2,3,4,5,6],cost:7,detail:7,doc:7,engin:[3,4],error:6,escpo:3,etc:7,exampl:7,featur:7,how:0,http:5,interfac:4,librari:7,list:7,logic:7,media:5,modul:[1,2,3,4,5,6],now:7,object:6,packag:[1,2,3,4,5,6],price:7,primari:7,printer:[4,7],purchas:7,select:7,showcas:7,softwar:7,sound:3,submodul:[2,3,4,5,6],subpackag:[1,2],thermal:7,tiktok:5,tiktokprint:[1,2,3,4,5,6,7,8],tutori:7,type:6,voic:3,youtub:7}}) -------------------------------------------------------------------------------- /docs/_static/language_data.js: -------------------------------------------------------------------------------- 1 | /* 2 | * language_data.js 3 | * ~~~~~~~~~~~~~~~~ 4 | * 5 | * This script contains the language-specific data used by searchtools.js, 6 | * namely the list of stopwords, stemmer, scorer and splitter. 7 | * 8 | * :copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS. 9 | * :license: BSD, see LICENSE for details. 10 | * 11 | */ 12 | 13 | var stopwords = ["a","and","are","as","at","be","but","by","for","if","in","into","is","it","near","no","not","of","on","or","such","that","the","their","then","there","these","they","this","to","was","will","with"]; 14 | 15 | 16 | /* Non-minified version is copied as a separate JS file, is available */ 17 | 18 | /** 19 | * Porter Stemmer 20 | */ 21 | var Stemmer = function() { 22 | 23 | var step2list = { 24 | ational: 'ate', 25 | tional: 'tion', 26 | enci: 'ence', 27 | anci: 'ance', 28 | izer: 'ize', 29 | bli: 'ble', 30 | alli: 'al', 31 | entli: 'ent', 32 | eli: 'e', 33 | ousli: 'ous', 34 | ization: 'ize', 35 | ation: 'ate', 36 | ator: 'ate', 37 | alism: 'al', 38 | iveness: 'ive', 39 | fulness: 'ful', 40 | ousness: 'ous', 41 | aliti: 'al', 42 | iviti: 'ive', 43 | biliti: 'ble', 44 | logi: 'log' 45 | }; 46 | 47 | var step3list = { 48 | icate: 'ic', 49 | ative: '', 50 | alize: 'al', 51 | iciti: 'ic', 52 | ical: 'ic', 53 | ful: '', 54 | ness: '' 55 | }; 56 | 57 | var c = "[^aeiou]"; // consonant 58 | var v = "[aeiouy]"; // vowel 59 | var C = c + "[^aeiouy]*"; // consonant sequence 60 | var V = v + "[aeiou]*"; // vowel sequence 61 | 62 | var mgr0 = "^(" + C + ")?" + V + C; // [C]VC... is m>0 63 | var meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$"; // [C]VC[V] is m=1 64 | var mgr1 = "^(" + C + ")?" + V + C + V + C; // [C]VCVC... is m>1 65 | var s_v = "^(" + C + ")?" + v; // vowel in stem 66 | 67 | this.stemWord = function (w) { 68 | var stem; 69 | var suffix; 70 | var firstch; 71 | var origword = w; 72 | 73 | if (w.length < 3) 74 | return w; 75 | 76 | var re; 77 | var re2; 78 | var re3; 79 | var re4; 80 | 81 | firstch = w.substr(0,1); 82 | if (firstch == "y") 83 | w = firstch.toUpperCase() + w.substr(1); 84 | 85 | // Step 1a 86 | re = /^(.+?)(ss|i)es$/; 87 | re2 = /^(.+?)([^s])s$/; 88 | 89 | if (re.test(w)) 90 | w = w.replace(re,"$1$2"); 91 | else if (re2.test(w)) 92 | w = w.replace(re2,"$1$2"); 93 | 94 | // Step 1b 95 | re = /^(.+?)eed$/; 96 | re2 = /^(.+?)(ed|ing)$/; 97 | if (re.test(w)) { 98 | var fp = re.exec(w); 99 | re = new RegExp(mgr0); 100 | if (re.test(fp[1])) { 101 | re = /.$/; 102 | w = w.replace(re,""); 103 | } 104 | } 105 | else if (re2.test(w)) { 106 | var fp = re2.exec(w); 107 | stem = fp[1]; 108 | re2 = new RegExp(s_v); 109 | if (re2.test(stem)) { 110 | w = stem; 111 | re2 = /(at|bl|iz)$/; 112 | re3 = new RegExp("([^aeiouylsz])\\1$"); 113 | re4 = new RegExp("^" + C + v + "[^aeiouwxy]$"); 114 | if (re2.test(w)) 115 | w = w + "e"; 116 | else if (re3.test(w)) { 117 | re = /.$/; 118 | w = w.replace(re,""); 119 | } 120 | else if (re4.test(w)) 121 | w = w + "e"; 122 | } 123 | } 124 | 125 | // Step 1c 126 | re = /^(.+?)y$/; 127 | if (re.test(w)) { 128 | var fp = re.exec(w); 129 | stem = fp[1]; 130 | re = new RegExp(s_v); 131 | if (re.test(stem)) 132 | w = stem + "i"; 133 | } 134 | 135 | // Step 2 136 | re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/; 137 | if (re.test(w)) { 138 | var fp = re.exec(w); 139 | stem = fp[1]; 140 | suffix = fp[2]; 141 | re = new RegExp(mgr0); 142 | if (re.test(stem)) 143 | w = stem + step2list[suffix]; 144 | } 145 | 146 | // Step 3 147 | re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/; 148 | if (re.test(w)) { 149 | var fp = re.exec(w); 150 | stem = fp[1]; 151 | suffix = fp[2]; 152 | re = new RegExp(mgr0); 153 | if (re.test(stem)) 154 | w = stem + step3list[suffix]; 155 | } 156 | 157 | // Step 4 158 | re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/; 159 | re2 = /^(.+?)(s|t)(ion)$/; 160 | if (re.test(w)) { 161 | var fp = re.exec(w); 162 | stem = fp[1]; 163 | re = new RegExp(mgr1); 164 | if (re.test(stem)) 165 | w = stem; 166 | } 167 | else if (re2.test(w)) { 168 | var fp = re2.exec(w); 169 | stem = fp[1] + fp[2]; 170 | re2 = new RegExp(mgr1); 171 | if (re2.test(stem)) 172 | w = stem; 173 | } 174 | 175 | // Step 5 176 | re = /^(.+?)e$/; 177 | if (re.test(w)) { 178 | var fp = re.exec(w); 179 | stem = fp[1]; 180 | re = new RegExp(mgr1); 181 | re2 = new RegExp(meq1); 182 | re3 = new RegExp("^" + C + v + "[^aeiouwxy]$"); 183 | if (re.test(stem) || (re2.test(stem) && !(re3.test(stem)))) 184 | w = stem; 185 | } 186 | re = /ll$/; 187 | re2 = new RegExp(mgr1); 188 | if (re.test(w) && re2.test(w)) { 189 | re = /.$/; 190 | w = w.replace(re,""); 191 | } 192 | 193 | // and turn initial Y back to y 194 | if (firstch == "y") 195 | w = firstch.toLowerCase() + w.substr(1); 196 | return w; 197 | } 198 | } 199 | 200 | 201 | 202 | 203 | var splitChars = (function() { 204 | var result = {}; 205 | var singles = [96, 180, 187, 191, 215, 247, 749, 885, 903, 907, 909, 930, 1014, 1648, 206 | 1748, 1809, 2416, 2473, 2481, 2526, 2601, 2609, 2612, 2615, 2653, 2702, 207 | 2706, 2729, 2737, 2740, 2857, 2865, 2868, 2910, 2928, 2948, 2961, 2971, 208 | 2973, 3085, 3089, 3113, 3124, 3213, 3217, 3241, 3252, 3295, 3341, 3345, 209 | 3369, 3506, 3516, 3633, 3715, 3721, 3736, 3744, 3748, 3750, 3756, 3761, 210 | 3781, 3912, 4239, 4347, 4681, 4695, 4697, 4745, 4785, 4799, 4801, 4823, 211 | 4881, 5760, 5901, 5997, 6313, 7405, 8024, 8026, 8028, 8030, 8117, 8125, 212 | 8133, 8181, 8468, 8485, 8487, 8489, 8494, 8527, 11311, 11359, 11687, 11695, 213 | 11703, 11711, 11719, 11727, 11735, 12448, 12539, 43010, 43014, 43019, 43587, 214 | 43696, 43713, 64286, 64297, 64311, 64317, 64319, 64322, 64325, 65141]; 215 | var i, j, start, end; 216 | for (i = 0; i < singles.length; i++) { 217 | result[singles[i]] = true; 218 | } 219 | var ranges = [[0, 47], [58, 64], [91, 94], [123, 169], [171, 177], [182, 184], [706, 709], 220 | [722, 735], [741, 747], [751, 879], [888, 889], [894, 901], [1154, 1161], 221 | [1318, 1328], [1367, 1368], [1370, 1376], [1416, 1487], [1515, 1519], [1523, 1568], 222 | [1611, 1631], [1642, 1645], [1750, 1764], [1767, 1773], [1789, 1790], [1792, 1807], 223 | [1840, 1868], [1958, 1968], [1970, 1983], [2027, 2035], [2038, 2041], [2043, 2047], 224 | [2070, 2073], [2075, 2083], [2085, 2087], [2089, 2307], [2362, 2364], [2366, 2383], 225 | [2385, 2391], [2402, 2405], [2419, 2424], [2432, 2436], [2445, 2446], [2449, 2450], 226 | [2483, 2485], [2490, 2492], [2494, 2509], [2511, 2523], [2530, 2533], [2546, 2547], 227 | [2554, 2564], [2571, 2574], [2577, 2578], [2618, 2648], [2655, 2661], [2672, 2673], 228 | [2677, 2692], [2746, 2748], [2750, 2767], [2769, 2783], [2786, 2789], [2800, 2820], 229 | [2829, 2830], [2833, 2834], [2874, 2876], [2878, 2907], [2914, 2917], [2930, 2946], 230 | [2955, 2957], [2966, 2968], [2976, 2978], [2981, 2983], [2987, 2989], [3002, 3023], 231 | [3025, 3045], [3059, 3076], [3130, 3132], [3134, 3159], [3162, 3167], [3170, 3173], 232 | [3184, 3191], [3199, 3204], [3258, 3260], [3262, 3293], [3298, 3301], [3312, 3332], 233 | [3386, 3388], [3390, 3423], [3426, 3429], [3446, 3449], [3456, 3460], [3479, 3481], 234 | [3518, 3519], [3527, 3584], [3636, 3647], [3655, 3663], [3674, 3712], [3717, 3718], 235 | [3723, 3724], [3726, 3731], [3752, 3753], [3764, 3772], [3774, 3775], [3783, 3791], 236 | [3802, 3803], [3806, 3839], [3841, 3871], [3892, 3903], [3949, 3975], [3980, 4095], 237 | [4139, 4158], [4170, 4175], [4182, 4185], [4190, 4192], [4194, 4196], [4199, 4205], 238 | [4209, 4212], [4226, 4237], [4250, 4255], [4294, 4303], [4349, 4351], [4686, 4687], 239 | [4702, 4703], [4750, 4751], [4790, 4791], [4806, 4807], [4886, 4887], [4955, 4968], 240 | [4989, 4991], [5008, 5023], [5109, 5120], [5741, 5742], [5787, 5791], [5867, 5869], 241 | [5873, 5887], [5906, 5919], [5938, 5951], [5970, 5983], [6001, 6015], [6068, 6102], 242 | [6104, 6107], [6109, 6111], [6122, 6127], [6138, 6159], [6170, 6175], [6264, 6271], 243 | [6315, 6319], [6390, 6399], [6429, 6469], [6510, 6511], [6517, 6527], [6572, 6592], 244 | [6600, 6607], [6619, 6655], [6679, 6687], [6741, 6783], [6794, 6799], [6810, 6822], 245 | [6824, 6916], [6964, 6980], [6988, 6991], [7002, 7042], [7073, 7085], [7098, 7167], 246 | [7204, 7231], [7242, 7244], [7294, 7400], [7410, 7423], [7616, 7679], [7958, 7959], 247 | [7966, 7967], [8006, 8007], [8014, 8015], [8062, 8063], [8127, 8129], [8141, 8143], 248 | [8148, 8149], [8156, 8159], [8173, 8177], [8189, 8303], [8306, 8307], [8314, 8318], 249 | [8330, 8335], [8341, 8449], [8451, 8454], [8456, 8457], [8470, 8472], [8478, 8483], 250 | [8506, 8507], [8512, 8516], [8522, 8525], [8586, 9311], [9372, 9449], [9472, 10101], 251 | [10132, 11263], [11493, 11498], [11503, 11516], [11518, 11519], [11558, 11567], 252 | [11622, 11630], [11632, 11647], [11671, 11679], [11743, 11822], [11824, 12292], 253 | [12296, 12320], [12330, 12336], [12342, 12343], [12349, 12352], [12439, 12444], 254 | [12544, 12548], [12590, 12592], [12687, 12689], [12694, 12703], [12728, 12783], 255 | [12800, 12831], [12842, 12880], [12896, 12927], [12938, 12976], [12992, 13311], 256 | [19894, 19967], [40908, 40959], [42125, 42191], [42238, 42239], [42509, 42511], 257 | [42540, 42559], [42592, 42593], [42607, 42622], [42648, 42655], [42736, 42774], 258 | [42784, 42785], [42889, 42890], [42893, 43002], [43043, 43055], [43062, 43071], 259 | [43124, 43137], [43188, 43215], [43226, 43249], [43256, 43258], [43260, 43263], 260 | [43302, 43311], [43335, 43359], [43389, 43395], [43443, 43470], [43482, 43519], 261 | [43561, 43583], [43596, 43599], [43610, 43615], [43639, 43641], [43643, 43647], 262 | [43698, 43700], [43703, 43704], [43710, 43711], [43715, 43738], [43742, 43967], 263 | [44003, 44015], [44026, 44031], [55204, 55215], [55239, 55242], [55292, 55295], 264 | [57344, 63743], [64046, 64047], [64110, 64111], [64218, 64255], [64263, 64274], 265 | [64280, 64284], [64434, 64466], [64830, 64847], [64912, 64913], [64968, 65007], 266 | [65020, 65135], [65277, 65295], [65306, 65312], [65339, 65344], [65371, 65381], 267 | [65471, 65473], [65480, 65481], [65488, 65489], [65496, 65497]]; 268 | for (i = 0; i < ranges.length; i++) { 269 | start = ranges[i][0]; 270 | end = ranges[i][1]; 271 | for (j = start; j <= end; j++) { 272 | result[j] = true; 273 | } 274 | } 275 | return result; 276 | })(); 277 | 278 | function splitQuery(query) { 279 | var result = []; 280 | var start = -1; 281 | for (var i = 0; i < query.length; i++) { 282 | if (splitChars[query.charCodeAt(i)]) { 283 | if (start !== -1) { 284 | result.push(query.slice(start, i)); 285 | start = -1; 286 | } 287 | } else if (start === -1) { 288 | start = i; 289 | } 290 | } 291 | if (start !== -1) { 292 | result.push(query.slice(start)); 293 | } 294 | return result; 295 | } 296 | 297 | 298 | -------------------------------------------------------------------------------- /docs/_static/doctools.js: -------------------------------------------------------------------------------- 1 | /* 2 | * doctools.js 3 | * ~~~~~~~~~~~ 4 | * 5 | * Sphinx JavaScript utilities for all documentation. 6 | * 7 | * :copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS. 8 | * :license: BSD, see LICENSE for details. 9 | * 10 | */ 11 | 12 | /** 13 | * select a different prefix for underscore 14 | */ 15 | $u = _.noConflict(); 16 | 17 | /** 18 | * make the code below compatible with browsers without 19 | * an installed firebug like debugger 20 | if (!window.console || !console.firebug) { 21 | var names = ["log", "debug", "info", "warn", "error", "assert", "dir", 22 | "dirxml", "group", "groupEnd", "time", "timeEnd", "count", "trace", 23 | "profile", "profileEnd"]; 24 | window.console = {}; 25 | for (var i = 0; i < names.length; ++i) 26 | window.console[names[i]] = function() {}; 27 | } 28 | */ 29 | 30 | /** 31 | * small helper function to urldecode strings 32 | * 33 | * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/decodeURIComponent#Decoding_query_parameters_from_a_URL 34 | */ 35 | jQuery.urldecode = function(x) { 36 | if (!x) { 37 | return x 38 | } 39 | return decodeURIComponent(x.replace(/\+/g, ' ')); 40 | }; 41 | 42 | /** 43 | * small helper function to urlencode strings 44 | */ 45 | jQuery.urlencode = encodeURIComponent; 46 | 47 | /** 48 | * This function returns the parsed url parameters of the 49 | * current request. Multiple values per key are supported, 50 | * it will always return arrays of strings for the value parts. 51 | */ 52 | jQuery.getQueryParameters = function(s) { 53 | if (typeof s === 'undefined') 54 | s = document.location.search; 55 | var parts = s.substr(s.indexOf('?') + 1).split('&'); 56 | var result = {}; 57 | for (var i = 0; i < parts.length; i++) { 58 | var tmp = parts[i].split('=', 2); 59 | var key = jQuery.urldecode(tmp[0]); 60 | var value = jQuery.urldecode(tmp[1]); 61 | if (key in result) 62 | result[key].push(value); 63 | else 64 | result[key] = [value]; 65 | } 66 | return result; 67 | }; 68 | 69 | /** 70 | * highlight a given string on a jquery object by wrapping it in 71 | * span elements with the given class name. 72 | */ 73 | jQuery.fn.highlightText = function(text, className) { 74 | function highlight(node, addItems) { 75 | if (node.nodeType === 3) { 76 | var val = node.nodeValue; 77 | var pos = val.toLowerCase().indexOf(text); 78 | if (pos >= 0 && 79 | !jQuery(node.parentNode).hasClass(className) && 80 | !jQuery(node.parentNode).hasClass("nohighlight")) { 81 | var span; 82 | var isInSVG = jQuery(node).closest("body, svg, foreignObject").is("svg"); 83 | if (isInSVG) { 84 | span = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); 85 | } else { 86 | span = document.createElement("span"); 87 | span.className = className; 88 | } 89 | span.appendChild(document.createTextNode(val.substr(pos, text.length))); 90 | node.parentNode.insertBefore(span, node.parentNode.insertBefore( 91 | document.createTextNode(val.substr(pos + text.length)), 92 | node.nextSibling)); 93 | node.nodeValue = val.substr(0, pos); 94 | if (isInSVG) { 95 | var rect = document.createElementNS("http://www.w3.org/2000/svg", "rect"); 96 | var bbox = node.parentElement.getBBox(); 97 | rect.x.baseVal.value = bbox.x; 98 | rect.y.baseVal.value = bbox.y; 99 | rect.width.baseVal.value = bbox.width; 100 | rect.height.baseVal.value = bbox.height; 101 | rect.setAttribute('class', className); 102 | addItems.push({ 103 | "parent": node.parentNode, 104 | "target": rect}); 105 | } 106 | } 107 | } 108 | else if (!jQuery(node).is("button, select, textarea")) { 109 | jQuery.each(node.childNodes, function() { 110 | highlight(this, addItems); 111 | }); 112 | } 113 | } 114 | var addItems = []; 115 | var result = this.each(function() { 116 | highlight(this, addItems); 117 | }); 118 | for (var i = 0; i < addItems.length; ++i) { 119 | jQuery(addItems[i].parent).before(addItems[i].target); 120 | } 121 | return result; 122 | }; 123 | 124 | /* 125 | * backward compatibility for jQuery.browser 126 | * This will be supported until firefox bug is fixed. 127 | */ 128 | if (!jQuery.browser) { 129 | jQuery.uaMatch = function(ua) { 130 | ua = ua.toLowerCase(); 131 | 132 | var match = /(chrome)[ \/]([\w.]+)/.exec(ua) || 133 | /(webkit)[ \/]([\w.]+)/.exec(ua) || 134 | /(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) || 135 | /(msie) ([\w.]+)/.exec(ua) || 136 | ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) || 137 | []; 138 | 139 | return { 140 | browser: match[ 1 ] || "", 141 | version: match[ 2 ] || "0" 142 | }; 143 | }; 144 | jQuery.browser = {}; 145 | jQuery.browser[jQuery.uaMatch(navigator.userAgent).browser] = true; 146 | } 147 | 148 | /** 149 | * Small JavaScript module for the documentation. 150 | */ 151 | var Documentation = { 152 | 153 | init : function() { 154 | this.fixFirefoxAnchorBug(); 155 | this.highlightSearchWords(); 156 | this.initIndexTable(); 157 | this.initOnKeyListeners(); 158 | }, 159 | 160 | /** 161 | * i18n support 162 | */ 163 | TRANSLATIONS : {}, 164 | PLURAL_EXPR : function(n) { return n === 1 ? 0 : 1; }, 165 | LOCALE : 'unknown', 166 | 167 | // gettext and ngettext don't access this so that the functions 168 | // can safely bound to a different name (_ = Documentation.gettext) 169 | gettext : function(string) { 170 | var translated = Documentation.TRANSLATIONS[string]; 171 | if (typeof translated === 'undefined') 172 | return string; 173 | return (typeof translated === 'string') ? translated : translated[0]; 174 | }, 175 | 176 | ngettext : function(singular, plural, n) { 177 | var translated = Documentation.TRANSLATIONS[singular]; 178 | if (typeof translated === 'undefined') 179 | return (n == 1) ? singular : plural; 180 | return translated[Documentation.PLURALEXPR(n)]; 181 | }, 182 | 183 | addTranslations : function(catalog) { 184 | for (var key in catalog.messages) 185 | this.TRANSLATIONS[key] = catalog.messages[key]; 186 | this.PLURAL_EXPR = new Function('n', 'return +(' + catalog.plural_expr + ')'); 187 | this.LOCALE = catalog.locale; 188 | }, 189 | 190 | /** 191 | * add context elements like header anchor links 192 | */ 193 | addContextElements : function() { 194 | $('div[id] > :header:first').each(function() { 195 | $('\u00B6'). 196 | attr('href', '#' + this.id). 197 | attr('title', _('Permalink to this headline')). 198 | appendTo(this); 199 | }); 200 | $('dt[id]').each(function() { 201 | $('\u00B6'). 202 | attr('href', '#' + this.id). 203 | attr('title', _('Permalink to this definition')). 204 | appendTo(this); 205 | }); 206 | }, 207 | 208 | /** 209 | * workaround a firefox stupidity 210 | * see: https://bugzilla.mozilla.org/show_bug.cgi?id=645075 211 | */ 212 | fixFirefoxAnchorBug : function() { 213 | if (document.location.hash && $.browser.mozilla) 214 | window.setTimeout(function() { 215 | document.location.href += ''; 216 | }, 10); 217 | }, 218 | 219 | /** 220 | * highlight the search words provided in the url in the text 221 | */ 222 | highlightSearchWords : function() { 223 | var params = $.getQueryParameters(); 224 | var terms = (params.highlight) ? params.highlight[0].split(/\s+/) : []; 225 | if (terms.length) { 226 | var body = $('div.body'); 227 | if (!body.length) { 228 | body = $('body'); 229 | } 230 | window.setTimeout(function() { 231 | $.each(terms, function() { 232 | body.highlightText(this.toLowerCase(), 'highlighted'); 233 | }); 234 | }, 10); 235 | $('') 237 | .appendTo($('#searchbox')); 238 | } 239 | }, 240 | 241 | /** 242 | * init the domain index toggle buttons 243 | */ 244 | initIndexTable : function() { 245 | var togglers = $('img.toggler').click(function() { 246 | var src = $(this).attr('src'); 247 | var idnum = $(this).attr('id').substr(7); 248 | $('tr.cg-' + idnum).toggle(); 249 | if (src.substr(-9) === 'minus.png') 250 | $(this).attr('src', src.substr(0, src.length-9) + 'plus.png'); 251 | else 252 | $(this).attr('src', src.substr(0, src.length-8) + 'minus.png'); 253 | }).css('display', ''); 254 | if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) { 255 | togglers.click(); 256 | } 257 | }, 258 | 259 | /** 260 | * helper function to hide the search marks again 261 | */ 262 | hideSearchWords : function() { 263 | $('#searchbox .highlight-link').fadeOut(300); 264 | $('span.highlighted').removeClass('highlighted'); 265 | var url = new URL(window.location); 266 | url.searchParams.delete('highlight'); 267 | window.history.replaceState({}, '', url); 268 | }, 269 | 270 | /** 271 | * helper function to focus on search bar 272 | */ 273 | focusSearchBar : function() { 274 | $('input[name=q]').first().focus(); 275 | }, 276 | 277 | /** 278 | * make the url absolute 279 | */ 280 | makeURL : function(relativeURL) { 281 | return DOCUMENTATION_OPTIONS.URL_ROOT + '/' + relativeURL; 282 | }, 283 | 284 | /** 285 | * get the current relative url 286 | */ 287 | getCurrentURL : function() { 288 | var path = document.location.pathname; 289 | var parts = path.split(/\//); 290 | $.each(DOCUMENTATION_OPTIONS.URL_ROOT.split(/\//), function() { 291 | if (this === '..') 292 | parts.pop(); 293 | }); 294 | var url = parts.join('/'); 295 | return path.substring(url.lastIndexOf('/') + 1, path.length - 1); 296 | }, 297 | 298 | initOnKeyListeners: function() { 299 | // only install a listener if it is really needed 300 | if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS && 301 | !DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) 302 | return; 303 | 304 | $(document).keydown(function(event) { 305 | var activeElementType = document.activeElement.tagName; 306 | // don't navigate when in search box, textarea, dropdown or button 307 | if (activeElementType !== 'TEXTAREA' && activeElementType !== 'INPUT' && activeElementType !== 'SELECT' 308 | && activeElementType !== 'BUTTON') { 309 | if (event.altKey || event.ctrlKey || event.metaKey) 310 | return; 311 | 312 | if (!event.shiftKey) { 313 | switch (event.key) { 314 | case 'ArrowLeft': 315 | if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) 316 | break; 317 | var prevHref = $('link[rel="prev"]').prop('href'); 318 | if (prevHref) { 319 | window.location.href = prevHref; 320 | return false; 321 | } 322 | break; 323 | case 'ArrowRight': 324 | if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) 325 | break; 326 | var nextHref = $('link[rel="next"]').prop('href'); 327 | if (nextHref) { 328 | window.location.href = nextHref; 329 | return false; 330 | } 331 | break; 332 | case 'Escape': 333 | if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) 334 | break; 335 | Documentation.hideSearchWords(); 336 | return false; 337 | } 338 | } 339 | 340 | // some keyboard layouts may need Shift to get / 341 | switch (event.key) { 342 | case '/': 343 | if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) 344 | break; 345 | Documentation.focusSearchBar(); 346 | return false; 347 | } 348 | } 349 | }); 350 | } 351 | }; 352 | 353 | // quick alias for translations 354 | _ = Documentation.gettext; 355 | 356 | $(document).ready(function() { 357 | Documentation.init(); 358 | }); 359 | -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | TikTokPrinter Docs — TikTokPrinter documentation 8 | 9 | 10 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 46 | 47 |
51 | 52 |
53 |
54 |
55 | 62 |
63 |
64 |
65 |
66 | 67 |
68 |

TikTokPrinter Docs

69 | 83 |

View the above tree for detailed documentation on the package.

84 |
85 |

TikTokPrinter - Thermal Printer Software

86 |

A Python library to print to thermal printers from TikTokLive.

87 |

LinkedIn 88 | HitCount 89 | Forks 90 | Stars 91 | Support Server

92 |

Welcome to the public GitHub information page for the number one best-selling, most customizable & professional-grade tool for thermal printing on TikTok.

93 |

Thermal printing is a very recent, very exciting trend on TikTok. It is also a very complex one. Not because the topic is difficult in and of itself, but because people want so many different things.

94 |

That’s why I developed an all-encompassing, multithreaded thermal printing program that does… everything, including a comprehensive video tutorial on how to use it, made by me.

95 |

No subscription unlike many virtual printer services. One-time, life-time purchase. Can be installed in python via pip. Includes access to all future releases/updates to the project.

96 |
97 |

💲💲 Purchase Now 💲💲

98 |
99 |

YouTube Showcase & Tutorial

100 |

If you want to see just how powerful this library is (and easy to use), we made a video tutorial & showcase 101 | that goes through the basics of how to get started using it. Click the thumbnail below to warp.

102 |

YouTube Tutorial & Showcase

103 |
104 |
105 |

Auto-Select

106 |

Automatically find & use your USB printer.

107 |

image

108 |
109 |
110 |

Purchase Details (Cost, Pricing Logic, etc.)

111 |

The cost is a flat $50 USD. That’s insanely cheap.

112 |

This library is the most advanced, most purchased printer script on the market. Not only does it have an insane number of features, it was made by the person that created 113 | the TikTokLive library. That gives you a benefit of ensuring that it is not only guaranteed to work, but guaranteed to be the best of the best you will possibly find.

114 |

The price is set at what it is because of the ridiculous amount of time spent learning to program, creating the TikTokLive library, figuring out how to print on Windows, MacOS and Linux, creating guides, building the 115 | highly complex script itself, learning all the ways it can go wrong and fixing them, dealing with customer issues and so much more.

116 |

Purchasing this script is an investment that you can make thousands of dollars off of. At this price-point, that’s a hell of a deal. You are recommended to have basic Python knowledge to use this library.

117 |
118 |
119 |

Purchase Now

120 |

To buy this library, create a ticket in the #tickets channel in https://discord.gg/H8m3c6jSF4.

121 |

Type the message “Printer Magic” in the ticket and I will immediately get you started so that you can get to printing as fast as possible!

122 |
123 |
124 |

Printer Library Example

125 |

Here’s a sample of what you can do with this library in less than 30 lines of code:

126 |

127 |

To show you just how advanced the library is, here we can print a profile picture, play a sound, and do text-to-speech… in just 3 “true” lines of code. This is insane.

128 |
@client.on("comment")
129 | async def on_comment(event: CommentEvent):
130 |     client.queue(
131 | 
132 |         # Divier Text
133 |         PrinterText("-" * 20),
134 | 
135 |         # Speak the comment
136 |         VoiceText(event.user.uniqueId + " said " + event.comment),
137 | 
138 |         # Print the comment to printer
139 |         PrinterText(event.user.uniqueId + " -> " + event.comment),
140 | 
141 |         # Play a sound
142 |         SoundFile("enchanted.wav"),
143 | 
144 |         # Download their avatar and print the image
145 |         PrinterImage(await TikTokMedia.user_image(event.user, circle=False))
146 | 
147 |     )
148 | 
149 |
150 |
151 |
152 |

Feature List (30+ Features)

153 |
154 |
Primary Features
155 |
    156 |
  • Ready-to-go script included for non-programmers (basic knowledge still recommended) that has everything you need, already put together

  • 157 |
  • Print ANY Message

  • 158 |
  • Print Profile Pictures, Gift Images, Custom Images

  • 159 |
  • CUSTOM Text to Speech (perhaps when someone gifts?)

  • 160 |
  • Play Sounds (perhaps when someone gifts?)

  • 161 |
  • Support for ALL Serial, USB, and Network ESC-POS printers

  • 162 |
  • Automatic setup script

  • 163 |
  • Support for MacOS, Windows, Linux

  • 164 |
  • Fully documented API

  • 165 |
  • Quick-install with PIP

  • 166 |
  • Access to future releases/updates

  • 167 |
  • Video Set-Up Tutorial

  • 168 |
  • Made to be easy to use for newbies

  • 169 |
  • Access to private discord chat for clients

  • 170 |
171 |
172 |
173 |
174 |

Additional Features

175 |
    176 |
  • Download and print TikTok user avatars, gifts

  • 177 |
  • Extremely high level API (There is zero need to touch anything low-level, I’ve got it covered)

  • 178 |
  • 100% Asynchronous Programming

  • 179 |
  • Bold messages

  • 180 |
  • Left, Right, Center Adjust

  • 181 |
  • Newline character support

  • 182 |
  • Print backwards (flip the input!)

  • 183 |
  • Insert items at the start of the print queue (priority)

  • 184 |
  • Insert items at the end of the print queue

  • 185 |
  • Insert items at any index in the print queue

  • 186 |
  • Custom errors built on top of the API describing what went wrong when it happens

  • 187 |
  • Errors do not kill the script. Even if a part of a message breaks, the rest still prints!

  • 188 |
  • Send messages to the TikTok LIVE Chat (chat-bot)

  • 189 |
  • How-to example on basic usage (using formatting, text-to-speech, sounds, images, etc.)

  • 190 |
  • How-to example on using gifts

  • 191 |
  • How-to example on using commands

  • 192 |
  • How-to example on other features

  • 193 |
194 |
195 |
196 |
197 |
198 | 199 | 200 |
201 |
202 |
205 | 206 |
207 | 208 |
209 |

© Copyright 2022, Isaac Kogan.

210 |
211 | 212 | Built with Sphinx using a 213 | theme 214 | provided by Read the Docs. 215 | 216 | 217 |
218 |
219 |
220 |
221 |
222 | 227 | 228 | 229 | -------------------------------------------------------------------------------- /docs/_static/underscore.js: -------------------------------------------------------------------------------- 1 | !function(n,r){"object"==typeof exports&&"undefined"!=typeof module?module.exports=r():"function"==typeof define&&define.amd?define("underscore",r):(n="undefined"!=typeof globalThis?globalThis:n||self,function(){var t=n._,e=n._=r();e.noConflict=function(){return n._=t,e}}())}(this,(function(){ 2 | // Underscore.js 1.13.1 3 | // https://underscorejs.org 4 | // (c) 2009-2021 Jeremy Ashkenas, Julian Gonggrijp, and DocumentCloud and Investigative Reporters & Editors 5 | // Underscore may be freely distributed under the MIT license. 6 | var n="1.13.1",r="object"==typeof self&&self.self===self&&self||"object"==typeof global&&global.global===global&&global||Function("return this")()||{},t=Array.prototype,e=Object.prototype,u="undefined"!=typeof Symbol?Symbol.prototype:null,o=t.push,i=t.slice,a=e.toString,f=e.hasOwnProperty,c="undefined"!=typeof ArrayBuffer,l="undefined"!=typeof DataView,s=Array.isArray,p=Object.keys,v=Object.create,h=c&&ArrayBuffer.isView,y=isNaN,d=isFinite,g=!{toString:null}.propertyIsEnumerable("toString"),b=["valueOf","isPrototypeOf","toString","propertyIsEnumerable","hasOwnProperty","toLocaleString"],m=Math.pow(2,53)-1;function j(n,r){return r=null==r?n.length-1:+r,function(){for(var t=Math.max(arguments.length-r,0),e=Array(t),u=0;u=0&&t<=m}}function J(n){return function(r){return null==r?void 0:r[n]}}var G=J("byteLength"),H=K(G),Q=/\[object ((I|Ui)nt(8|16|32)|Float(32|64)|Uint8Clamped|Big(I|Ui)nt64)Array\]/;var X=c?function(n){return h?h(n)&&!q(n):H(n)&&Q.test(a.call(n))}:C(!1),Y=J("length");function Z(n,r){r=function(n){for(var r={},t=n.length,e=0;e":">",'"':""","'":"'","`":"`"},Cn=Ln($n),Kn=Ln(_n($n)),Jn=tn.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g},Gn=/(.)^/,Hn={"'":"'","\\":"\\","\r":"r","\n":"n","\u2028":"u2028","\u2029":"u2029"},Qn=/\\|'|\r|\n|\u2028|\u2029/g;function Xn(n){return"\\"+Hn[n]}var Yn=/^\s*(\w|\$)+\s*$/;var Zn=0;function nr(n,r,t,e,u){if(!(e instanceof r))return n.apply(t,u);var o=Mn(n.prototype),i=n.apply(o,u);return _(i)?i:o}var rr=j((function(n,r){var t=rr.placeholder,e=function(){for(var u=0,o=r.length,i=Array(o),a=0;a1)ur(a,r-1,t,e),u=e.length;else for(var f=0,c=a.length;f0&&(t=r.apply(this,arguments)),n<=1&&(r=null),t}}var lr=rr(cr,2);function sr(n,r,t){r=qn(r,t);for(var e,u=nn(n),o=0,i=u.length;o0?0:u-1;o>=0&&o0?a=o>=0?o:Math.max(o+f,a):f=o>=0?Math.min(o+1,f):o+f+1;else if(t&&o&&f)return e[o=t(e,u)]===u?o:-1;if(u!=u)return(o=r(i.call(e,a,f),$))>=0?o+a:-1;for(o=n>0?a:f-1;o>=0&&o0?0:i-1;for(u||(e=r[o?o[a]:a],a+=n);a>=0&&a=3;return r(n,Fn(t,u,4),e,o)}}var Ar=wr(1),xr=wr(-1);function Sr(n,r,t){var e=[];return r=qn(r,t),jr(n,(function(n,t,u){r(n,t,u)&&e.push(n)})),e}function Or(n,r,t){r=qn(r,t);for(var e=!er(n)&&nn(n),u=(e||n).length,o=0;o=0}var Br=j((function(n,r,t){var e,u;return D(r)?u=r:(r=Nn(r),e=r.slice(0,-1),r=r[r.length-1]),_r(n,(function(n){var o=u;if(!o){if(e&&e.length&&(n=In(n,e)),null==n)return;o=n[r]}return null==o?o:o.apply(n,t)}))}));function Nr(n,r){return _r(n,Rn(r))}function Ir(n,r,t){var e,u,o=-1/0,i=-1/0;if(null==r||"number"==typeof r&&"object"!=typeof n[0]&&null!=n)for(var a=0,f=(n=er(n)?n:jn(n)).length;ao&&(o=e);else r=qn(r,t),jr(n,(function(n,t,e){((u=r(n,t,e))>i||u===-1/0&&o===-1/0)&&(o=n,i=u)}));return o}function Tr(n,r,t){if(null==r||t)return er(n)||(n=jn(n)),n[Wn(n.length-1)];var e=er(n)?En(n):jn(n),u=Y(e);r=Math.max(Math.min(r,u),0);for(var o=u-1,i=0;i1&&(e=Fn(e,r[1])),r=an(n)):(e=qr,r=ur(r,!1,!1),n=Object(n));for(var u=0,o=r.length;u1&&(t=r[1])):(r=_r(ur(r,!1,!1),String),e=function(n,t){return!Er(r,t)}),Ur(n,e,t)}));function zr(n,r,t){return i.call(n,0,Math.max(0,n.length-(null==r||t?1:r)))}function Lr(n,r,t){return null==n||n.length<1?null==r||t?void 0:[]:null==r||t?n[0]:zr(n,n.length-r)}function $r(n,r,t){return i.call(n,null==r||t?1:r)}var Cr=j((function(n,r){return r=ur(r,!0,!0),Sr(n,(function(n){return!Er(r,n)}))})),Kr=j((function(n,r){return Cr(n,r)}));function Jr(n,r,t,e){A(r)||(e=t,t=r,r=!1),null!=t&&(t=qn(t,e));for(var u=[],o=[],i=0,a=Y(n);ir?(e&&(clearTimeout(e),e=null),a=c,i=n.apply(u,o),e||(u=o=null)):e||!1===t.trailing||(e=setTimeout(f,l)),i};return c.cancel=function(){clearTimeout(e),a=0,e=u=o=null},c},debounce:function(n,r,t){var e,u,o,i,a,f=function(){var c=zn()-u;r>c?e=setTimeout(f,r-c):(e=null,t||(i=n.apply(a,o)),e||(o=a=null))},c=j((function(c){return a=this,o=c,u=zn(),e||(e=setTimeout(f,r),t&&(i=n.apply(a,o))),i}));return c.cancel=function(){clearTimeout(e),e=o=a=null},c},wrap:function(n,r){return rr(r,n)},negate:fr,compose:function(){var n=arguments,r=n.length-1;return function(){for(var t=r,e=n[r].apply(this,arguments);t--;)e=n[t].call(this,e);return e}},after:function(n,r){return function(){if(--n<1)return r.apply(this,arguments)}},before:cr,once:lr,findKey:sr,findIndex:vr,findLastIndex:hr,sortedIndex:yr,indexOf:gr,lastIndexOf:br,find:mr,detect:mr,findWhere:function(n,r){return mr(n,Dn(r))},each:jr,forEach:jr,map:_r,collect:_r,reduce:Ar,foldl:Ar,inject:Ar,reduceRight:xr,foldr:xr,filter:Sr,select:Sr,reject:function(n,r,t){return Sr(n,fr(qn(r)),t)},every:Or,all:Or,some:Mr,any:Mr,contains:Er,includes:Er,include:Er,invoke:Br,pluck:Nr,where:function(n,r){return Sr(n,Dn(r))},max:Ir,min:function(n,r,t){var e,u,o=1/0,i=1/0;if(null==r||"number"==typeof r&&"object"!=typeof n[0]&&null!=n)for(var a=0,f=(n=er(n)?n:jn(n)).length;ae||void 0===t)return 1;if(t= 0) 116 | return; 117 | function pulse() { 118 | var i; 119 | Search._pulse_status = (Search._pulse_status + 1) % 4; 120 | var dotString = ''; 121 | for (i = 0; i < Search._pulse_status; i++) 122 | dotString += '.'; 123 | Search.dots.text(dotString); 124 | if (Search._pulse_status > -1) 125 | window.setTimeout(pulse, 500); 126 | } 127 | pulse(); 128 | }, 129 | 130 | /** 131 | * perform a search for something (or wait until index is loaded) 132 | */ 133 | performSearch : function(query) { 134 | // create the required interface elements 135 | this.out = $('#search-results'); 136 | this.title = $('

' + _('Searching') + '

').appendTo(this.out); 137 | this.dots = $('').appendTo(this.title); 138 | this.status = $('

 

').appendTo(this.out); 139 | this.output = $('