From afe0a4817fb992dff50d7386946a1a6d12481673 Mon Sep 17 00:00:00 2001 From: Jeremy Daalder Date: Sat, 12 Oct 2024 21:22:37 +1100 Subject: [PATCH] [script.module.bossanova808] 1.0.0 (#2658) --- script.module.bossanova808/LICENSE.txt | 674 ++++++++++++++++++ script.module.bossanova808/README.md | 32 + script.module.bossanova808/addon.xml | 18 + script.module.bossanova808/changelog.txt | 3 + script.module.bossanova808/resources/icon.png | Bin 0 -> 50121 bytes .../resources/lib/bossanova808/constants.py | 26 + .../lib/bossanova808/exception_logger.py | 154 ++++ .../resources/lib/bossanova808/logger.py | 65 ++ .../resources/lib/bossanova808/notify.py | 57 ++ .../resources/lib/bossanova808/utilities.py | 107 +++ 10 files changed, 1136 insertions(+) create mode 100644 script.module.bossanova808/LICENSE.txt create mode 100644 script.module.bossanova808/README.md create mode 100644 script.module.bossanova808/addon.xml create mode 100644 script.module.bossanova808/changelog.txt create mode 100644 script.module.bossanova808/resources/icon.png create mode 100644 script.module.bossanova808/resources/lib/bossanova808/constants.py create mode 100644 script.module.bossanova808/resources/lib/bossanova808/exception_logger.py create mode 100644 script.module.bossanova808/resources/lib/bossanova808/logger.py create mode 100644 script.module.bossanova808/resources/lib/bossanova808/notify.py create mode 100644 script.module.bossanova808/resources/lib/bossanova808/utilities.py diff --git a/script.module.bossanova808/LICENSE.txt b/script.module.bossanova808/LICENSE.txt new file mode 100644 index 000000000..f288702d2 --- /dev/null +++ b/script.module.bossanova808/LICENSE.txt @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/script.module.bossanova808/README.md b/script.module.bossanova808/README.md new file mode 100644 index 000000000..d00e5a03f --- /dev/null +++ b/script.module.bossanova808/README.md @@ -0,0 +1,32 @@ + +Bossanova808 Common Code for Kodi Addons +=================================== + +_script.module.bossanova808_ + +[!["Buy Me A Coffee"](https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png)](https://www.buymeacoffee.com/bossanova808) + + +Common code for all bossanova808 Kodi addons, including: + +**Available from the Kodi Official Repository:** + +* OzWeather +* Unpause Jumpback +* Playback Resumer +* Check Previous Episode +* Caber Toss + + +**Available from the [Bossanova808 Repository](https://github.com/bossanova808/repository.bossanova808):** + +* OzWeather Skin Patcher +* YoctoDisplay + + + + + + + + diff --git a/script.module.bossanova808/addon.xml b/script.module.bossanova808/addon.xml new file mode 100644 index 000000000..d1506a59c --- /dev/null +++ b/script.module.bossanova808/addon.xml @@ -0,0 +1,18 @@ + + + + + + + + Common code needed by bossanova808 addons + all + GPL-3.0-only + https://github.com/bossanova808/script.module.bossanova808 + https://github.com/bossanova808/script.module.bossanova808 + v1.0.0 Initial release + + resources/icon.png + + + diff --git a/script.module.bossanova808/changelog.txt b/script.module.bossanova808/changelog.txt new file mode 100644 index 000000000..1a647a453 --- /dev/null +++ b/script.module.bossanova808/changelog.txt @@ -0,0 +1,3 @@ +v0.0.1 +Alpha pre-release + diff --git a/script.module.bossanova808/resources/icon.png b/script.module.bossanova808/resources/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..232fa3924f741ba634d97745e4977b2d1dc537ee GIT binary patch literal 50121 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 DUxIf3 literal 0 HcmV?d00001 diff --git a/script.module.bossanova808/resources/lib/bossanova808/constants.py b/script.module.bossanova808/resources/lib/bossanova808/constants.py new file mode 100644 index 000000000..b5dd8b504 --- /dev/null +++ b/script.module.bossanova808/resources/lib/bossanova808/constants.py @@ -0,0 +1,26 @@ +# -*- coding: utf-8 -*- + +import sys +import xbmc +import xbmcvfs +import xbmcgui +import xbmcaddon + +""" Just a bunch of very handy Kodi constants """ + +ADDON = xbmcaddon.Addon() +ADDON_NAME = ADDON.getAddonInfo('name') +ADDON_ID = ADDON.getAddonInfo('id') +ADDON_ICON = ADDON.getAddonInfo('icon') +ADDON_AUTHOR = ADDON.getAddonInfo('author') +ADDON_VERSION = ADDON.getAddonInfo('version') +ADDON_ARGUMENTS = f'{sys.argv}' +CWD = ADDON.getAddonInfo('path') +LANGUAGE = ADDON.getLocalizedString +PROFILE = xbmcvfs.translatePath(ADDON.getAddonInfo('profile')) +LOG_PATH = xbmcvfs.translatePath('special://logpath') +KODI_VERSION = xbmc.getInfoLabel('System.BuildVersion') +KODI_VERSION_INT = int(KODI_VERSION.split(".")[0]) +USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36" +HOME_WINDOW = xbmcgui.Window(10000) +WEATHER_WINDOW = xbmcgui.Window(12600) diff --git a/script.module.bossanova808/resources/lib/bossanova808/exception_logger.py b/script.module.bossanova808/resources/lib/bossanova808/exception_logger.py new file mode 100644 index 000000000..e925d6da8 --- /dev/null +++ b/script.module.bossanova808/resources/lib/bossanova808/exception_logger.py @@ -0,0 +1,154 @@ +# coding: utf-8 + +# (c) Roman Miroshnychenko 2020 +# Retrieved from: +# https://github.com/thetvdb/metadata.tvshows.thetvdb.com.v4.python/blob/master/metadata.tvshows.thetvdb.com.v4.python/resources/lib/exception_logger.py +# (Thanks Roman! - Modified by bossanova808 as needed...) +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +"""Exception logger with extended diagnostic info""" + +import inspect +import sys +from contextlib import contextmanager +from platform import uname +from pprint import pformat +from typing import Text, Callable, Generator +import xbmc +from .constants import * +from .logger import Logger + + +def _format_vars(variables): + # type: (dict) -> Text + """ + Format variables dictionary + + :param variables: variables dict + :return: formatted string with sorted ``var = val`` pairs + """ + var_list = [(var, val) for var, val in variables.items() + if not (var.startswith('__') or var.endswith('__'))] + var_list.sort(key=lambda i: i[0]) + lines = [] + for var, val in var_list: + lines.append('{} = {}'.format(var, pformat(val))) + return '\n'.join(lines) + + +def _format_code_context(frame_info): + # type: (tuple) -> Text + context = '' + if frame_info[4] is not None: + for i, line in enumerate(frame_info[4], frame_info[2] - frame_info[5]): + if i == frame_info[2]: + context += '{}:>{}'.format(str(i).rjust(5), line) + else: + context += '{}: {}'.format(str(i).rjust(5), line) + return context + + +FRAME_INFO_TEMPLATE = """File: +{file_path}:{lineno} +-------------------------------------------------------------------------------- +Code context: +{code_context} +-------------------------------------------------------------------------------- +Local variables: +{local_vars} +================================================================================ +""" + + +def _format_frame_info(frame_info): + # type: (tuple) -> Text + return FRAME_INFO_TEMPLATE.format( + file_path=frame_info[1], + lineno=frame_info[2], + code_context=_format_code_context(frame_info), + local_vars=_format_vars(frame_info[0].f_locals) + ) + + +EXCEPTION_TEMPLATE = """ +************************* Unhandled exception detected ************************* +################################################################################ + Diagnostic info +-------------------------------------------------------------------------------- +Exception type : {exc_type} +Exception value : {exc} +System info : {system_info} +Python version : {python_version} +Kodi version : {kodi_version} +sys.argv : {sys_argv} +-------------------------------------------------------------------------------- +sys.path: +{sys_path} +################################################################################ + Stack Trace +================================================================================ +{stack_trace} +*************************** End of diagnostic info ***************************** +""" + + +@contextmanager +def log_exception(logger_func=Logger.error): + # type: (Callable[[Text], None]) -> Generator[None, None, None] + """ + Diagnostic helper context manager + + It controls execution within its context and writes extended + diagnostic info to the Kodi log if an unhandled exception + happens within the context. The info includes the following items: + + - System info + - Python version + - Kodi version + - Module path. + - Stack trace including: + * File path and line number where the exception happened + * Code fragment where the exception has happened. + * Local variables at the moment of the exception. + + After logging the diagnostic info the exception is re-raised. + + Example:: + + with debug_exception(): + # Some risky code + raise RuntimeError('Fatal error!') + + :param logger_func: logger function that accepts a single argument + that is a log message. + """ + try: + yield + except Exception as exc: + stack_trace = '' + for frame_info in inspect.trace(5): + stack_trace += _format_frame_info(frame_info) + message = EXCEPTION_TEMPLATE.format( + exc_type=exc.__class__.__name__, + exc=exc, + system_info=uname(), + python_version=sys.version.replace('\n', ' '), + kodi_version=xbmc.getInfoLabel('System.BuildVersion'), + sys_argv=pformat(sys.argv), + sys_path=pformat(sys.path), + stack_trace=stack_trace + ) + logger_func(message) + raise exc diff --git a/script.module.bossanova808/resources/lib/bossanova808/logger.py b/script.module.bossanova808/resources/lib/bossanova808/logger.py new file mode 100644 index 000000000..df9564792 --- /dev/null +++ b/script.module.bossanova808/resources/lib/bossanova808/logger.py @@ -0,0 +1,65 @@ +# -*- coding: utf-8 -*- + +import xbmc +from .constants import * + + +class Logger: + + @staticmethod + def log(message, level=xbmc.LOGDEBUG): + """ + Log a message to the Kodi log file. + If we're unit testing a module outside Kodi, print to the console instead. + + :param message: the message to log + :param level: the kodi log level to log at, default xbmc.LOGDEBUG + :return: + """ + # + if xbmc.getUserAgent(): + xbmc.log(f'### {ADDON_NAME} {ADDON_VERSION}: {str(message)}', level) + else: + print(str(message)) + + @staticmethod + def info(message): + """ + Log a message to the Kodi log file at INFO level. + + :param message: the message to log + :return: + """ + Logger.log(message, xbmc.LOGINFO) + + @staticmethod + def warning(message): + """ + Log a message to the Kodi log file at WARNING level. + + :param message: the message to log + :return: + """ + Logger.log(message, xbmc.LOGWARNING) + + @staticmethod + def error(message): + """ + Log a message to the Kodi log file at ERROR level. + + :param message: the message to log + :return: + """ + Logger.log(message, xbmc.LOGERROR) + + @staticmethod + def debug(*messages): + """ + Log messages to the Kodi log file at DEBUG level. + + :param messages: the message(s) to log + :return: + """ + for message in messages: + Logger.log(message, xbmc.LOGDEBUG) + diff --git a/script.module.bossanova808/resources/lib/bossanova808/notify.py b/script.module.bossanova808/resources/lib/bossanova808/notify.py new file mode 100644 index 000000000..da5af0693 --- /dev/null +++ b/script.module.bossanova808/resources/lib/bossanova808/notify.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- + +import xbmcgui +from .constants import * + + +class Notify: + + @staticmethod + def kodi_notification(message, duration=5000, icon=xbmcgui.NOTIFICATION_INFO): + """ + Send a custom notification to the user via the Kodi GUI + + :param message: the message to send + :param duration: time to display notification in milliseconds, default 5000 + :param icon: xbmcgui.NOTIFICATION_INFO (default), xbmcgui.NOTIFICATION_WARNING, or xbmcgui.NOTIFICATION_ERROR (or custom icon) + :return: None + """ + dialog = xbmcgui.Dialog() + + dialog.notification(heading=ADDON_NAME, + message=message, + icon=icon, + time=duration) + + @staticmethod + def info(message, duration=5000): + """ + Send an info level notification to the user via the Kodi GUI + + :param message: the message to display + :param duration: the duration to show the message, default 5000ms + :return: + """ + Notify.kodi_notification(message, duration, xbmcgui.NOTIFICATION_INFO) + + @staticmethod + def warning(message, duration=5000): + """ + Send a warning notification to the user via the Kodi GUI + + :param message: the message to display + :param duration: the duration to show the message, default 5000ms + :return: + """ + Notify.kodi_notification(message, duration, xbmcgui.NOTIFICATION_WARNING) + + @staticmethod + def error(message, duration=5000): + """ + Send an error level notification to the user via the Kodi GUI + + :param message: the message to display + :param duration: the duration to show the message, default 5000ms + :return: + """ + Notify.kodi_notification(message, duration, xbmcgui.NOTIFICATION_ERROR) \ No newline at end of file diff --git a/script.module.bossanova808/resources/lib/bossanova808/utilities.py b/script.module.bossanova808/resources/lib/bossanova808/utilities.py new file mode 100644 index 000000000..4d528a85b --- /dev/null +++ b/script.module.bossanova808/resources/lib/bossanova808/utilities.py @@ -0,0 +1,107 @@ +# -*- coding: utf-8 -*- + +import json +from .constants import * +from .logger import Logger + + +def set_property(window, name, value=""): + """ + Set a property on a window. + To clear a property, provide an empty string + + :param window: Required. The Kodi window on which to set the property. + :param name: Required. Name of the property. + :param value: Optional (defaults to ""). Set the property to this value. An empty string clears the property. + """ + if value is None: + window.clearProperty(name) + + value = str(value) + if value: + Logger.debug(f'Setting window property {name} to value {value}') + window.setProperty(name, value) + else: + Logger.debug(f'Clearing window property {name}') + window.clearProperty(name) + + +def get_property(window, name): + """ + Return the value of a window property + + :param window: the Kodi window to get the property value from + :param name: the name of the property to get + :return: the value of the window property + """ + return window.getProperty(name) + + +def get_property_as_bool(window, name): + """ + Return the value of a window property as a boolean + + :param window: the Kodi window to get the property value from + :param name: the name of the property to get + :return: the value of the window property in boolean form + """ + return window.getProperty(name).lower() == "true" + + +def send_kodi_json(human_description, json_string): + """ + Send a JSON command to Kodi, logging the human description, command, and result as returned. + + :param human_description: Required. A human sensible description of what the command is aiming to do/retrieve. + :param json_string: Required. The json command to send. + :return: the json object loaded from the result string + """ + Logger.debug(f'KODI JSON RPC command: {human_description} [{json_string}]') + result = xbmc.executeJSONRPC(json_string) + Logger.debug(f'KODI JSON RPC result: {result}') + return json.loads(result) + + +def get_setting(setting): + """ + Helper function to get string type from settings + + :param setting: The addon setting to return + :return: the setting value + """ + return ADDON.getSetting(setting).strip() + + +def get_setting_as_bool(setting): + """ + Helper function to get bool type from settings + + :param setting: The addon setting to return + :return: the setting value as boolean + """ + return get_setting(setting).lower() == "true" + + +def is_playback_paused(): + """ + Helper function to return Kodi player state. + (Odd this is needed, it should be a testable state on Player really...) + + :return: boolean indicating player paused state + """ + return bool(xbmc.getCondVisibility("Player.Paused")) + + +def footprints(startup=True): + """ + Log the startup/exit of an addon, and key Kodi details that are helpful for debugging + + :param startup: optional, default True. If true, log the startup of an addon, otherwise log the exit. + """ + if startup: + Logger.info(f'Start.') + Logger.info(f'Kodi {KODI_VERSION}') + Logger.info(f'Python {sys.version}') + Logger.info(f'Run {ADDON_ARGUMENTS}') + else: + Logger.info(f'Finish.')