From 376fe5605a8d8baee908594dbfb03d5adc69ac8a Mon Sep 17 00:00:00 2001 From: vidplace7 Date: Sat, 11 Jan 2025 10:58:00 -0500 Subject: [PATCH] Add org.meshtastic.meshtasticd --- .github/workflows/ci.yaml | 39 ++ .gitignore | 5 + .gitmodules | 3 + LICENSE | 675 ++++++++++++++++++++++++ meshtasticd-wrapper.sh | 26 + org.meshtastic.meshtasticd.desktop | 8 + org.meshtastic.meshtasticd.metainfo.xml | 29 + org.meshtastic.meshtasticd.svg | 16 + org.meshtastic.meshtasticd.yaml | 185 +++++++ patches/stdcppfs.patch | 12 + python3-modules.json | 192 +++++++ requirements.txt | 6 + shared-modules | 1 + static/Screenshot_1.png | Bin 0 -> 49093 bytes 14 files changed, 1197 insertions(+) create mode 100644 .github/workflows/ci.yaml create mode 100644 .gitignore create mode 100644 .gitmodules create mode 100644 LICENSE create mode 100755 meshtasticd-wrapper.sh create mode 100644 org.meshtastic.meshtasticd.desktop create mode 100644 org.meshtastic.meshtasticd.metainfo.xml create mode 100644 org.meshtastic.meshtasticd.svg create mode 100644 org.meshtastic.meshtasticd.yaml create mode 100644 patches/stdcppfs.patch create mode 100644 python3-modules.json create mode 100644 requirements.txt create mode 160000 shared-modules create mode 100644 static/Screenshot_1.png diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml new file mode 100644 index 0000000000..9074488cab --- /dev/null +++ b/.github/workflows/ci.yaml @@ -0,0 +1,39 @@ +name: CI + +on: + push: + branches: [meshtasticd] + pull_request: + +jobs: + flatpak-amd64: + runs-on: ubuntu-24.04 + container: + image: ghcr.io/flathub-infra/flatpak-github-actions:freedesktop-24.08 + options: --privileged + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive + - uses: flathub-infra/flatpak-github-actions/flatpak-builder@master + with: + bundle: meshtasticd.flatpak + manifest-path: org.meshtastic.meshtasticd.yaml + arch: x86_64 + cache-key: flatpak-builder-${{ github.sha }} + + flatpak-arm64: + runs-on: ubuntu-24.04-arm + container: + image: ghcr.io/flathub-infra/flatpak-github-actions:freedesktop-24.08 + options: --privileged + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive + - uses: flathub-infra/flatpak-github-actions/flatpak-builder@master + with: + bundle: meshtasticd.flatpak + manifest-path: org.meshtastic.meshtasticd.yaml + arch: aarch64 + cache-key: flatpak-builder-${{ github.sha }} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000..51f1f3ebd7 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +.vscode/settings.json + +.flatpak +.flatpak-builder +build diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000000..1e7a990914 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "shared-modules"] + path = shared-modules + url = https://github.com/flathub/shared-modules.git diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000000..10926e87f1 --- /dev/null +++ b/LICENSE @@ -0,0 +1,675 @@ + 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/meshtasticd-wrapper.sh b/meshtasticd-wrapper.sh new file mode 100755 index 0000000000..8bb90530e3 --- /dev/null +++ b/meshtasticd-wrapper.sh @@ -0,0 +1,26 @@ +#!/usr/bin/env bash + +CONF_DIR="$XDG_CONFIG_HOME/meshtasticd" + +# Ensure conf directories exist +mkdir -p "$CONF_DIR/config.d" +mkdir -p "$CONF_DIR/available.d" + +# Always copy available.d config files +cp -R /app/share/meshtasticd/available.d/* "$CONF_DIR/available.d/" + +# Copy default config if it doesn't exist +if [ ! -f "$CONF_DIR/config.yaml" ]; then + echo "Copying default config to $CONF_DIR/config.yaml" + cp /app/share/meshtasticd/config-dist.yaml $CONF_DIR/config.yaml + sed -i 's|/usr/share/meshtasticd|/app/share/meshtasticd|g' $CONF_DIR/config.yaml + sed -i "s|/etc/meshtasticd|$CONF_DIR|g" $CONF_DIR/config.yaml +fi + +# Copy default UI config if it doesn't exist +if [ ! -f "$CONF_DIR/config.d/MUI.yaml" ]; then + echo "Copying default UI config to $CONF_DIR/config.d/MUI.yaml" + cp /app/share/meshtasticd/available.d/MUI/X11_480x480.yaml $CONF_DIR/config.d/MUI.yaml +fi + +exec meshtasticd "--fsdir=$XDG_DATA_HOME" "--config=$XDG_CONFIG_HOME/meshtasticd/config.yaml" "$@" diff --git a/org.meshtastic.meshtasticd.desktop b/org.meshtastic.meshtasticd.desktop new file mode 100644 index 0000000000..35810d29ca --- /dev/null +++ b/org.meshtastic.meshtasticd.desktop @@ -0,0 +1,8 @@ +[Desktop Entry] +Name=Meshtastic +Comment=Meshtastic App +Exec=meshtasticd-wrapper.sh +Icon=org.meshtastic.meshtasticd +Terminal=true +Type=Application +Categories=Utility; \ No newline at end of file diff --git a/org.meshtastic.meshtasticd.metainfo.xml b/org.meshtastic.meshtasticd.metainfo.xml new file mode 100644 index 0000000000..ed8fed04e6 --- /dev/null +++ b/org.meshtastic.meshtasticd.metainfo.xml @@ -0,0 +1,29 @@ + + + org.meshtastic.meshtasticd + + Meshtastic + An open source, off-grid, decentralized, mesh network built to run on affordable, low-power devices + + CC-BY-4.0 + GPL-3.0-or-later + + + pointing + keyboard + touch + + + +

+ Meshtastic® is a project that enables you to use inexpensive LoRa radios as a long range off-grid communication platform in areas without existing or reliable communications infrastructure. This project is 100% community driven and open source! +

+
+ + org.meshtastic.meshtasticd.desktop + + + https://raw.githubusercontent.com/meshtastic/flathub-submissions/refs/heads/meshtasticd/static/Screenshot_1.png + + +
\ No newline at end of file diff --git a/org.meshtastic.meshtasticd.svg b/org.meshtastic.meshtasticd.svg new file mode 100644 index 0000000000..e6863f6a65 --- /dev/null +++ b/org.meshtastic.meshtasticd.svg @@ -0,0 +1,16 @@ + + + +Created with Fabric.js 4.6.0 + + + + + + + + + + + + \ No newline at end of file diff --git a/org.meshtastic.meshtasticd.yaml b/org.meshtastic.meshtasticd.yaml new file mode 100644 index 0000000000..27c2d1587c --- /dev/null +++ b/org.meshtastic.meshtasticd.yaml @@ -0,0 +1,185 @@ +id: org.meshtastic.meshtasticd +runtime: org.freedesktop.Platform +runtime-version: '24.08' +sdk: org.freedesktop.Sdk +command: meshtasticd-wrapper.sh +modules: + - name: meshtasticd-wrapper + buildsystem: simple + build-commands: + - install -Dm755 meshtasticd-wrapper.sh /app/bin/meshtasticd-wrapper.sh + - install -Dm644 -t /app/share/icons/hicolor/scalable/apps/ org.meshtastic.meshtasticd.svg + - install -Dm644 -t /app/share/applications org.meshtastic.meshtasticd.desktop + - install -Dm644 -t /app/share/metainfo org.meshtastic.meshtasticd.metainfo.xml + sources: + - type: file + path: meshtasticd-wrapper.sh + - type: file + path: org.meshtastic.meshtasticd.desktop + - type: file + path: org.meshtastic.meshtasticd.svg + - type: file + path: org.meshtastic.meshtasticd.metainfo.xml + - name: meshtasticd + buildsystem: simple + build-options: + # build-args: + # # PlatformIO requires internet access at build-time to download pkgs + # - --share=network + env: + PLATFORMIO_BUILD_FLAGS: -L/app/lib + PLATFORMIO_LIBDEPS_DIR: pio/libdeps + PLATFORMIO_PACKAGES_DIR: pio/packages + PLATFORMIO_CORE_DIR: pio/core + build-commands: + - pwd + - ls -lah pio + - mv pio/libdeps/native pio/libdeps/native-tft + # - mv pio/core/platforms/native pio/core/platforms/native-tft + - platformio run -e native-tft + - install -Dm755 .pio/build/native-tft/program /app/bin/meshtasticd + # Install the default config files and directories + - install -d /app/share/meshtasticd + - install -d /app/share/meshtasticd/config.d + - install -d /app/share/meshtasticd/available.d + - cp -R bin/config.d/* /app/share/meshtasticd/available.d + - install -m644 bin/config-dist.yaml /app/share/meshtasticd/config-dist.yaml + sources: + - type: git + url: https://github.com/meshtastic/firmware.git + # tag: v2.5.21.447533a + # commit: 447533aae5b82398e8dcd648745a4ff1a3c0a8ac + branch: '2.6' + - type: patch + paths: + - patches/stdcppfs.patch + - type: archive + url: https://github.com/meshtastic/firmware/releases/download/v2.5.21.447533a/platformio-deps-native-2.5.21.447533a.zip + sha256: 3cf3d3511f49885e08dbceebc440f3ef8dd96c508691cc079f40f3694b49f764 + strip-components: 0 + dest: pio + modules: + - python3-modules.json + - shared-modules/libusb/libusb.json + - name: yaml-cpp + buildsystem: cmake-ninja + config-opts: + - -DBUILD_SHARED_LIBS=ON + - -DYAML_BUILD_SHARED_LIBS=ON + - -DYAML_CPP_BUILD_TOOLS=OFF + - -DYAML_CPP_BUILD_TESTS=OFF + - -DYAML_CPP_BUILD_CONTRIB=OFF + sources: + - type: archive + url: https://github.com/jbeder/yaml-cpp/archive/refs/tags/0.8.0.tar.gz + sha256: fbe74bbdcee21d656715688706da3c8becfd946d92cd44705cc6098bb23b3a16 + - name: libgpiod + buildsystem: autotools + sources: + - type: archive + url: https://git.kernel.org/pub/scm/libs/libgpiod/libgpiod.git/snapshot/libgpiod-2.2.tar.gz + sha256: ae35329db7027c740e90c883baf27c26311f0614e6a7b115771b28188b992aec + - name: i2c-tools + buildsystem: simple + build-commands: + - make PREFIX=${FLATPAK_DEST} install + sources: + - type: archive + url: https://git.kernel.org/pub/scm/utils/i2c-tools/i2c-tools.git/snapshot/i2c-tools-4.4.tar.gz + sha256: af01d0fbe78e109a2db7137c7e9bfda3f3fb236c3177744c0f2695d1056cde71 + - name: libevdev + buildsystem: meson + config-opts: + - -Dtests=disabled + - -Ddocumentation=disabled + sources: + - type: archive + url: https://www.freedesktop.org/software/libevdev/libevdev-1.13.3.tar.xz + sha256: abf1aace86208eebdd5d3550ffded4c8d73bb405b796d51c389c9d0604cbcfbf + x-checker-data: + type: anitya + project-id: 20540 + stable-only: true + url-template: https://www.freedesktop.org/software/libevdev/libevdev-$version.tar.xz + cleanup: + - /bin + - /include + - /lib/pkgconfig + - /share/man + - name: libinput + buildsystem: meson + config-opts: + - --libexec=lib + - -Dlibwacom=false + - -Ddebug-gui=false + - -Dtests=false + - -Ddocumentation=false + - -Dzshcompletiondir=no + sources: + - type: archive + url: https://gitlab.freedesktop.org/libinput/libinput/-/archive/1.27.0/libinput-1.27.0.tar.gz + sha256: b11b900bf88ef68fe688c107226bb453ef26faf461ae2dcf9690b00009d660a6 + x-checker-data: + type: anitya + project-id: 5781 + stable-only: true + url-template: https://gitlab.freedesktop.org/libinput/libinput/-/archive/$version/libinput-$version.tar.gz + cleanup: + - /bin + - /etc + - /lib/libinput + - /lib/udev + - /share + - /include + - /lib/pkgconfig + modules: + - name: mtdev + buildsystem: autotools + config-opts: + - --disable-static + sources: + - type: archive + url: https://bitmath.org/code/mtdev/mtdev-1.1.7.tar.bz2 + sha256: a107adad2101fecac54ac7f9f0e0a0dd155d954193da55c2340c97f2ff1d814e + x-checker-data: + type: anitya + project-id: 8868 + stable-only: true + url-template: https://bitmath.org/code/mtdev/mtdev-$version.tar.bz2 + # Upstream uses an outdated version of the config.guess/config.sub script, + # so we override it here to fix aarch64 builds. + - type: shell + commands: + - cp -p /usr/share/automake-*/config.{sub,guess} config-aux/ + cleanup: + - /bin + - /include + - /lib/*.la + - /lib/pkgconfig + - name: xkbcommon + buildsystem: meson + config-opts: + - --buildtype=release + - -Ddefault_library=static + - -Denable-docs=false + - -Denable-tools=false + - -Denable-bash-completion=false + - -Dx-locale-root=/usr/share/X11/locale + cleanup: + - /bin + - /libexec + sources: + - type: archive + url: https://xkbcommon.org/download/libxkbcommon-1.6.0.tar.xz + sha256: 0edc14eccdd391514458bc5f5a4b99863ed2d651e4dd761a90abf4f46ef99c2b + +finish-args: + # Allow the app to talk to the X server + - --socket=x11 + # Required for CH341 USB radio + - --device=all + # Needs to talk to the network: + - --share=network + # Persist the meshtasticd configs + - --filesystem=xdg-config + - --filesystem=xdg-data diff --git a/patches/stdcppfs.patch b/patches/stdcppfs.patch new file mode 100644 index 0000000000..030e01bab7 --- /dev/null +++ b/patches/stdcppfs.patch @@ -0,0 +1,12 @@ +diff --git a/arch/portduino/portduino.ini b/arch/portduino/portduino.ini +index aa1150e9..26377345 100644 +--- a/arch/portduino/portduino.ini ++++ b/arch/portduino/portduino.ini +@@ -35,7 +35,6 @@ build_flags = + -DRADIOLIB_EEPROM_UNSUPPORTED + -DPORTDUINO_LINUX_HARDWARE + -lpthread +- -lstdc++fs + -lbluetooth + -lgpiod + -lyaml-cpp \ No newline at end of file diff --git a/python3-modules.json b/python3-modules.json new file mode 100644 index 0000000000..11fc7b2d01 --- /dev/null +++ b/python3-modules.json @@ -0,0 +1,192 @@ +{ + "name": "python3-modules", + "buildsystem": "simple", + "build-commands": [], + "modules": [ + { + "name": "python3-typing_extensions", + "buildsystem": "simple", + "build-commands": [ + "pip3 install --verbose --exists-action=i --no-index --find-links=\"file://${PWD}\" --prefix=${FLATPAK_DEST} \"typing_extensions\" --no-build-isolation" + ], + "sources": [ + { + "type": "file", + "url": "https://files.pythonhosted.org/packages/26/9f/ad63fc0248c5379346306f8668cda6e2e2e9c95e01216d2b8ffd9ff037d0/typing_extensions-4.12.2-py3-none-any.whl", + "sha256": "04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d" + } + ] + }, + { + "name": "python3-platformio", + "buildsystem": "simple", + "build-commands": [ + "pip3 install --verbose --exists-action=i --no-index --find-links=\"file://${PWD}\" --prefix=${FLATPAK_DEST} \"platformio\" --no-build-isolation" + ], + "sources": [ + { + "type": "file", + "url": "https://files.pythonhosted.org/packages/cf/6f/6abff7fe6813e6f94129a50c8c70bf70fb33ed2515b1037e703cef6d7a7e/ajsonrpc-1.2.0-py3-none-any.whl", + "sha256": "0fa2c1cf8e619d18ffee96043822032d6520eda65d3b712f9540a3a63e9cac25" + }, + { + "type": "file", + "url": "https://files.pythonhosted.org/packages/46/eb/e7f063ad1fec6b3178a3cd82d1a3c4de82cccf283fc42746168188e1cdd5/anyio-4.8.0-py3-none-any.whl", + "sha256": "b5011f270ab5eb0abf13385f851315585cc37ef330dd88e27ec3d34d651fd47a" + }, + { + "type": "file", + "url": "https://files.pythonhosted.org/packages/7e/0a/a5260c758ff813acc6967344339aa7ba15f815575f4d49141685c4345d39/bottle-0.13.2-py2.py3-none-any.whl", + "sha256": "27569ab8d1332fbba3e400b3baab2227ab4efb4882ff147af05a7c00ed73409c" + }, + { + "type": "file", + "url": "https://files.pythonhosted.org/packages/a5/32/8f6669fc4798494966bf446c8c4a162e0b5d893dff088afddf76414f70e1/certifi-2024.12.14-py3-none-any.whl", + "sha256": "1275f7a45be9464efc1173084eaa30f866fe2e47d389406136d332ed4967ec56" + }, + { + "type": "file", + "url": "https://files.pythonhosted.org/packages/16/b0/572805e227f01586461c80e0fd25d65a2115599cc9dad142fee4b747c357/charset_normalizer-3.4.1.tar.gz", + "sha256": "44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3" + }, + { + "type": "file", + "url": "https://files.pythonhosted.org/packages/7e/d4/7ebdbd03970677812aac39c869717059dbb71a4cfc033ca6e5221787892c/click-8.1.8-py3-none-any.whl", + "sha256": "63c132bbbed01578a06712a2d1f497bb62d9c1c0d329b7903a866228027263b2" + }, + { + "type": "file", + "url": "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", + "sha256": "4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6" + }, + { + "type": "file", + "url": "https://files.pythonhosted.org/packages/95/04/ff642e65ad6b90db43e668d70ffb6736436c7ce41fcc549f4e9472234127/h11-0.14.0-py3-none-any.whl", + "sha256": "e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761" + }, + { + "type": "file", + "url": "https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl", + "sha256": "946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3" + }, + { + "type": "file", + "url": "https://files.pythonhosted.org/packages/76/26/b347619b719d4c048e038929769f8f6b28c6d930149b40d950bbdde31d48/marshmallow-3.25.0-py3-none-any.whl", + "sha256": "50894cd57c6b097a6c6ed2bf216af47d10146990a54db52d03e32edb0448c905" + }, + { + "type": "file", + "url": "https://files.pythonhosted.org/packages/88/ef/eb23f262cca3c0c4eb7ab1933c3b1f03d021f2c48f54763065b6f0e321be/packaging-24.2-py3-none-any.whl", + "sha256": "09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759" + }, + { + "type": "file", + "url": "https://files.pythonhosted.org/packages/32/a0/4b1d18da2668a37b28beff3ecdc934940516302565c31a4cd4e17661a285/platformio-6.1.16.tar.gz", + "sha256": "79387b45ca7df9c0c51cae82b3b0a40ba78d11d87cea385db47e1033d781e959" + }, + { + "type": "file", + "url": "https://files.pythonhosted.org/packages/f8/64/711030d9fe9ccaf6ee3ab1bcf4801c6bb3d0e585af18824a50b016b4f39c/pyelftools-0.31-py3-none-any.whl", + "sha256": "f52de7b3c7e8c64c8abc04a79a1cf37ac5fb0b8a49809827130b858944840607" + }, + { + "type": "file", + "url": "https://files.pythonhosted.org/packages/07/bc/587a445451b253b285629263eb51c2d8e9bcea4fc97826266d186f96f558/pyserial-3.5-py2.py3-none-any.whl", + "sha256": "c4451db6ba391ca6ca299fb3ec7bae67a5c55dde170964c7a14ceefec02f2cf0" + }, + { + "type": "file", + "url": "https://files.pythonhosted.org/packages/f9/9b/335f9764261e915ed497fcdeb11df5dfd6f7bf257d4a6a2a686d80da4d54/requests-2.32.3-py3-none-any.whl", + "sha256": "70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6" + }, + { + "type": "file", + "url": "https://files.pythonhosted.org/packages/6a/23/8146aad7d88f4fcb3a6218f41a60f6c2d4e3a72de72da1825dc7c8f7877c/semantic_version-2.10.0-py2.py3-none-any.whl", + "sha256": "de78a3b8e0feda74cabc54aab2da702113e33ac9d9eb9d2389bcf1f58b7d9177" + }, + { + "type": "file", + "url": "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", + "sha256": "2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2" + }, + { + "type": "file", + "url": "https://files.pythonhosted.org/packages/60/f0/04547f776c8845be46df4bdd1f11159c088bd39e916f35d7da1b9f6eb3ef/starlette-0.39.2-py3-none-any.whl", + "sha256": "134dd6deb655a9775991d352312d53f1879775e5cc8a481f966e83416a2c3f71" + }, + { + "type": "file", + "url": "https://files.pythonhosted.org/packages/40/44/4a5f08c96eb108af5cb50b41f76142f0afa346dfa99d5296fe7202a11854/tabulate-0.9.0-py3-none-any.whl", + "sha256": "024ca478df22e9340661486f85298cff5f6dcdba14f3813e8830015b9ed1948f" + }, + { + "type": "file", + "url": "https://files.pythonhosted.org/packages/c8/19/4ec628951a74043532ca2cf5d97b7b14863931476d117c471e8e2b1eb39f/urllib3-2.3.0-py3-none-any.whl", + "sha256": "1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df" + }, + { + "type": "file", + "url": "https://files.pythonhosted.org/packages/f5/8e/cdc7d6263db313030e4c257dd5ba3909ebc4e4fb53ad62d5f09b1a2f5458/uvicorn-0.30.6-py3-none-any.whl", + "sha256": "65fd46fe3fda5bdc1b03b94eb634923ff18cd35b2f084813ea79d1f103f711b5" + }, + { + "type": "file", + "url": "https://files.pythonhosted.org/packages/78/58/e860788190eba3bcce367f74d29c4675466ce8dddfba85f7827588416f01/wsproto-1.2.0-py3-none-any.whl", + "sha256": "b9acddd652b585d75b20477888c56642fdade28bdfd3579aa24a4d2c037dd736" + } + ] + }, + { + "name": "python3-protobuf", + "buildsystem": "simple", + "build-commands": [ + "pip3 install --verbose --exists-action=i --no-index --find-links=\"file://${PWD}\" --prefix=${FLATPAK_DEST} \"protobuf\" --no-build-isolation" + ], + "sources": [ + { + "type": "file", + "url": "https://files.pythonhosted.org/packages/f7/d1/e0a911544ca9993e0f17ce6d3cc0932752356c1b0a834397f28e63479344/protobuf-5.29.3.tar.gz", + "sha256": "5da0f41edaf117bde316404bad1a486cb4ededf8e4a54891296f648e8e076620" + } + ] + }, + { + "name": "python3-grpcio", + "buildsystem": "simple", + "build-commands": [ + "pip3 install --verbose --exists-action=i --no-index --find-links=\"file://${PWD}\" --prefix=${FLATPAK_DEST} \"grpcio\" --no-build-isolation" + ], + "sources": [ + { + "type": "file", + "url": "https://files.pythonhosted.org/packages/e4/87/06a145284cbe86c91ca517fe6b57be5efbb733c0d6374b407f0992054d18/grpcio-1.69.0.tar.gz", + "sha256": "936fa44241b5379c5afc344e1260d467bee495747eaf478de825bab2791da6f5" + } + ] + }, + { + "name": "python3-grpcio-tools", + "buildsystem": "simple", + "build-commands": [ + "pip3 install --verbose --exists-action=i --no-index --find-links=\"file://${PWD}\" --prefix=${FLATPAK_DEST} \"grpcio-tools\" --no-build-isolation" + ], + "sources": [ + { + "type": "file", + "url": "https://files.pythonhosted.org/packages/e4/87/06a145284cbe86c91ca517fe6b57be5efbb733c0d6374b407f0992054d18/grpcio-1.69.0.tar.gz", + "sha256": "936fa44241b5379c5afc344e1260d467bee495747eaf478de825bab2791da6f5" + }, + { + "type": "file", + "url": "https://files.pythonhosted.org/packages/64/ec/1c25136ca1697eaa09a02effe3e74959fd9fb6aba9960d7340dd6341c5ce/grpcio_tools-1.69.0.tar.gz", + "sha256": "3e1a98f4d9decb84979e1ddd3deb09c0a33a84b6e3c0776d5bde4097e3ab66dd" + }, + { + "type": "file", + "url": "https://files.pythonhosted.org/packages/f7/d1/e0a911544ca9993e0f17ce6d3cc0932752356c1b0a834397f28e63479344/protobuf-5.29.3.tar.gz", + "sha256": "5da0f41edaf117bde316404bad1a486cb4ededf8e4a54891296f648e8e076620" + } + ] + } + ] +} \ No newline at end of file diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000000..508f24c345 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,6 @@ +# For flatpak_pip_generator +typing_extensions +platformio +protobuf +grpcio +grpcio-tools diff --git a/shared-modules b/shared-modules new file mode 160000 index 0000000000..802d804161 --- /dev/null +++ b/shared-modules @@ -0,0 +1 @@ +Subproject commit 802d80416180436ff9929ce2a2e098203ace078e diff --git a/static/Screenshot_1.png b/static/Screenshot_1.png new file mode 100644 index 0000000000000000000000000000000000000000..7de4f043edab6f76f5212311cd89ffac54eb253f GIT binary patch literal 49093 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