diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
new file mode 100644
index 0000000..46b480c
--- /dev/null
+++ b/.github/workflows/release.yml
@@ -0,0 +1,40 @@
+name: PikaOS Package Release
+
+on:
+ workflow_dispatch
+
+jobs:
+ build:
+ runs-on: self-hosted
+ container:
+ image: ubuntu:22.10
+ volumes:
+ - /proc:/proc
+ options: --privileged -it
+
+ steps:
+ - uses: actions/checkout@v3
+
+ - name: Install needed packages
+ run: apt update && apt install software-properties-common sudo git bc gpg gpg-agent bison build-essential ccache cpio fakeroot flex git kmod libelf-dev libncurses5-dev libssl-dev lz4 qtbase5-dev rsync schedtool wget zstd tar reprepro dpkg-sig devscripts -y
+
+ - name: Import GPG key
+ id: import_gpg
+ uses: crazy-max/ghaction-import-gpg@v5
+ with:
+ gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }}
+ passphrase: ${{ secrets.PASSPHRASE }}
+
+ - name: Install SSH key
+ uses: shimataro/ssh-key-action@v2
+ with:
+ key: ${{ secrets.SSH_KEY }}
+ name: id_rsa
+ known_hosts: ${{ secrets.KNOWN_HOSTS }}
+ if_key_exists: replace
+
+ - name: Build Package
+ run: ./main.sh
+
+ - name: Release Package
+ run: ./release.sh
diff --git a/archive/.cz.toml b/archive/.cz.toml
deleted file mode 100644
index 8b9c8ca..0000000
--- a/archive/.cz.toml
+++ /dev/null
@@ -1,7 +0,0 @@
-[tool.commitizen]
-name = "cz_conventional_commits"
-version = "1.5.2"
-tag_format = "$version"
-version_files = [
- 'repolib/__version__.py:__version__'
-]
\ No newline at end of file
diff --git a/archive/.readthedocs.yml b/archive/.readthedocs.yml
deleted file mode 100644
index 07db85f..0000000
--- a/archive/.readthedocs.yml
+++ /dev/null
@@ -1,20 +0,0 @@
-# .readthedocs.yml
-# Read the Docs configuration file
-# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
-
-# Required
-version: 2
-
-# Build documentation in the docs/ directory with Sphinx
-sphinx:
- configuration: docs/conf.py
-
-# Build documentation with MkDocs
-#mkdocs:
-# configuration: mkdocs.yml
-
-# Optionally build your docs in additional formats such as PDF
-formats:
- - pdf
- - epub
- - htmlzip
diff --git a/archive/.travis.yml b/archive/.travis.yml
deleted file mode 100644
index e098634..0000000
--- a/archive/.travis.yml
+++ /dev/null
@@ -1,13 +0,0 @@
-dist: bionic
-addons:
- apt:
- packages:
- - libdbus-1-dev
-
-language: python
-python: "3.8"
-
-install:
- - pip install -r requirements.txt
-scripts:
- - pytest --pylint
diff --git a/archive/LICENSE b/archive/LICENSE
deleted file mode 100644
index 01a7a80..0000000
--- a/archive/LICENSE
+++ /dev/null
@@ -1,675 +0,0 @@
-### 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 .
\ No newline at end of file
diff --git a/archive/LICENSE.LESSER b/archive/LICENSE.LESSER
deleted file mode 100644
index 13fc077..0000000
--- a/archive/LICENSE.LESSER
+++ /dev/null
@@ -1,157 +0,0 @@
-### GNU LESSER 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.
-
-This version of the GNU Lesser General Public License incorporates the
-terms and conditions of version 3 of the GNU General Public License,
-supplemented by the additional permissions listed below.
-
-#### 0. Additional Definitions.
-
-As used herein, "this License" refers to version 3 of the GNU Lesser
-General Public License, and the "GNU GPL" refers to version 3 of the
-GNU General Public License.
-
-"The Library" refers to a covered work governed by this License, other
-than an Application or a Combined Work as defined below.
-
-An "Application" is any work that makes use of an interface provided
-by the Library, but which is not otherwise based on the Library.
-Defining a subclass of a class defined by the Library is deemed a mode
-of using an interface provided by the Library.
-
-A "Combined Work" is a work produced by combining or linking an
-Application with the Library. The particular version of the Library
-with which the Combined Work was made is also called the "Linked
-Version".
-
-The "Minimal Corresponding Source" for a Combined Work means the
-Corresponding Source for the Combined Work, excluding any source code
-for portions of the Combined Work that, considered in isolation, are
-based on the Application, and not on the Linked Version.
-
-The "Corresponding Application Code" for a Combined Work means the
-object code and/or source code for the Application, including any data
-and utility programs needed for reproducing the Combined Work from the
-Application, but excluding the System Libraries of the Combined Work.
-
-#### 1. Exception to Section 3 of the GNU GPL.
-
-You may convey a covered work under sections 3 and 4 of this License
-without being bound by section 3 of the GNU GPL.
-
-#### 2. Conveying Modified Versions.
-
-If you modify a copy of the Library, and, in your modifications, a
-facility refers to a function or data to be supplied by an Application
-that uses the facility (other than as an argument passed when the
-facility is invoked), then you may convey a copy of the modified
-version:
-
-- a) under this License, provided that you make a good faith effort
- to ensure that, in the event an Application does not supply the
- function or data, the facility still operates, and performs
- whatever part of its purpose remains meaningful, or
-- b) under the GNU GPL, with none of the additional permissions of
- this License applicable to that copy.
-
-#### 3. Object Code Incorporating Material from Library Header Files.
-
-The object code form of an Application may incorporate material from a
-header file that is part of the Library. You may convey such object
-code under terms of your choice, provided that, if the incorporated
-material is not limited to numerical parameters, data structure
-layouts and accessors, or small macros, inline functions and templates
-(ten or fewer lines in length), you do both of the following:
-
-- a) Give prominent notice with each copy of the object code that
- the Library is used in it and that the Library and its use are
- covered by this License.
-- b) Accompany the object code with a copy of the GNU GPL and this
- license document.
-
-#### 4. Combined Works.
-
-You may convey a Combined Work under terms of your choice that, taken
-together, effectively do not restrict modification of the portions of
-the Library contained in the Combined Work and reverse engineering for
-debugging such modifications, if you also do each of the following:
-
-- a) Give prominent notice with each copy of the Combined Work that
- the Library is used in it and that the Library and its use are
- covered by this License.
-- b) Accompany the Combined Work with a copy of the GNU GPL and this
- license document.
-- c) For a Combined Work that displays copyright notices during
- execution, include the copyright notice for the Library among
- these notices, as well as a reference directing the user to the
- copies of the GNU GPL and this license document.
-- d) Do one of the following:
- - 0) Convey the Minimal Corresponding Source under the terms of
- this License, and the Corresponding Application Code in a form
- suitable for, and under terms that permit, the user to
- recombine or relink the Application with a modified version of
- the Linked Version to produce a modified Combined Work, in the
- manner specified by section 6 of the GNU GPL for conveying
- Corresponding Source.
- - 1) Use a suitable shared library mechanism for linking with
- the Library. A suitable mechanism is one that (a) uses at run
- time a copy of the Library already present on the user's
- computer system, and (b) will operate properly with a modified
- version of the Library that is interface-compatible with the
- Linked Version.
-- e) Provide Installation Information, but only if you would
- otherwise be required to provide such information under section 6
- of the GNU GPL, and only to the extent that such information is
- necessary to install and execute a modified version of the
- Combined Work produced by recombining or relinking the Application
- with a modified version of the Linked Version. (If you use option
- 4d0, the Installation Information must accompany the Minimal
- Corresponding Source and Corresponding Application Code. If you
- use option 4d1, you must provide the Installation Information in
- the manner specified by section 6 of the GNU GPL for conveying
- Corresponding Source.)
-
-#### 5. Combined Libraries.
-
-You may place library facilities that are a work based on the Library
-side by side in a single library together with other library
-facilities that are not Applications and are not covered by this
-License, and convey such a combined library under terms of your
-choice, if you do both of the following:
-
-- a) Accompany the combined library with a copy of the same work
- based on the Library, uncombined with any other library
- facilities, conveyed under the terms of this License.
-- b) Give prominent notice with the combined library that part of it
- is a work based on the Library, and explaining where to find the
- accompanying uncombined form of the same work.
-
-#### 6. Revised Versions of the GNU Lesser General Public License.
-
-The Free Software Foundation may publish revised and/or new versions
-of the GNU Lesser 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 Library
-as you received it specifies that a certain numbered version of the
-GNU Lesser General Public License "or any later version" applies to
-it, you have the option of following the terms and conditions either
-of that published version or of any later version published by the
-Free Software Foundation. If the Library as you received it does not
-specify a version number of the GNU Lesser General Public License, you
-may choose any version of the GNU Lesser General Public License ever
-published by the Free Software Foundation.
-
-If the Library as you received it specifies that a proxy can decide
-whether future versions of the GNU Lesser General Public License shall
-apply, that proxy's public statement of acceptance of any version is
-permanent authorization for you to choose that version for the
-Library.
\ No newline at end of file
diff --git a/archive/README.rst b/archive/README.rst
deleted file mode 100644
index be9b897..0000000
--- a/archive/README.rst
+++ /dev/null
@@ -1,167 +0,0 @@
-=======
-RepoLib
-=======
-
-RepoLib is a Python library and CLI tool-set for managing your software
-system software repositories. It's currently set up to handle APT repositories
-on Debian-based linux distributions.
-
-RepoLib is intended to operate on DEB822-format sources. It aims to provide
-feature parity with software-properties for most commonly used functions.
-
-Documentation
-=============
-
-Documentation is available online at `Read The Docs `_.
-
-
-Basic CLI Usage
----------------
-
-RepoLib includes a CLI program for managing software repositories,
-:code:`apt-manage`
-.
-
-Usage is divided into subcommands for most tasks. Currently implemented commands
-are:
-
- apt-manage add # Adds repositories to the system
- apt-manage list # Lists configuration details of repositories
-
-Additional information is available with the built-in help:
-
- apt-manage --help
-
-
-Add
-^^^
-
-Apt-manage allows entering a URL for a repository, a complete debian line, or a
-Launchpad PPA shortcut (e.g. "ppa:user/repo"). It also adds signing keys for PPA
-style repositories automatically.
-
-
-List
-^^^^
-
-With no options, it outputs a list of the currently configured repositories on
-the system (all those found in
-:code:`/etc/apt/sources.list.d/`
-. With a configured repository as an argument, it outputs the configuration
-details of the specified repository.
-
-Remove
-^^^^^^
-
-Accepts one repository as an argument. Removes the specified repository.
-
-NOTE: The system repository (/etc/at/sources.list.d/system.sources) cannot be
-removed.
-
-Source
-^^^^^^
-
-Allows enabling or disabling source code for the given repository.
-
-Modify
-^^^^^^
-
-Allows changing configuration details of a given repository
-
-Installation
-============
-
-From System Package Manager
----------------------------
-
-If your operating system packages repolib, you can install it by running::
-
- sudo apt install python3-repolib
-
-
-Uninstall
-^^^^^^^^^
-
-To uninstall, simply do::
-
- sudo apt remove python3-repolib
-
-
-From PyPI
----------
-
-Repolib is available on PyPI. You can install it for your current user with::
-
- pip3 install repolib
-
-Alternatively, you can install it system-wide using::
-
- sudo pip3 install repolib
-
-Uninstall
-^^^^^^^^^
-
-To uninstall, simply do::
-
- sudo pip3 uninstall repolib
-
-From Git
---------
-
-First, clone the git repository onto your local system::
-
- git clone https://github.com/isantop/repolib
- cd repolib
-
-Debian
-------
-
-On debian based distributions, you can build a .deb package locally and install
-it onto your system. You will need the following build-dependencies:
-
- * debhelper (>=11)
- * dh-python
- * python3-all
- * python3-setuptools
-
-You can use this command to install these all in one go::
-
- sudo apt install debhelper dh-python python3-all python3-setuptools
-
-Then build and install the package::
-
- debuild -us -uc
- cd ..
- sudo dpkg -i python3-repolib_*.deb
-
-Uninstall
-^^^^^^^^^
-
-To uninstall, simply do::
-
- sudo apt remove python3-repolib
-
-setuptools setup.py
--------------------
-
-You can build and install the package using python3-setuptools. First, install
-the dependencies::
-
- sudo apt install python3-all python3-setuptools
-
-Then build and install the package::
-
- sudo python3 ./setup.py install
-
-Uninstall
-^^^^^^^^^
-
-You can uninstall RepoLib by removing the following files/directories:
-
- * /usr/local/lib/python3.7/dist-packages/repolib/
- * /usr/local/lib/python3.7/dist-packages/repolib-\*.egg-info
- * /usr/local/bin/apt-manage
-
-This command will remove all of these for you::
-
- sudo rm -r /usr/local/lib/python3.7/dist-packages/repolib* /usr/local/bin/apt-manage
diff --git a/archive/SECURITY.md b/archive/SECURITY.md
deleted file mode 100644
index d8f441d..0000000
--- a/archive/SECURITY.md
+++ /dev/null
@@ -1,18 +0,0 @@
-# Security Policy
-
-## Supported Versions
-
-The following versions of RepoLib currently receive updates for security:
-
-| Version | Supported |
-| ------- | ------------------------ |
-| 1.1.x | :heavy_check_mark:
-| 1.0.x | :heavy_exclamation_mark: |
-
-Please note that only the current supported patch version of each release
-is supported.
-
-## Reporting a Vulnerability
-
-When Filing an issue for a potential security vulnerability, please be sure
-to include a `[SECURITY]` tag in the issue title.
diff --git a/archive/TESTING.md b/archive/TESTING.md
deleted file mode 100644
index 8979356..0000000
--- a/archive/TESTING.md
+++ /dev/null
@@ -1,276 +0,0 @@
-## Testing
-
-The following components of RepoLib should be tested with each revision:
-
-### CLI - apt-manage command
-
-The `apt-manage` command should be tested every single revision to ensure that
-it is working correctly. This will also generally test that changes to the
-underlying library have not affected anything.
-
-#### Adding repositories
-
-Adding repositories should be tested.
-
-1. Test Adding PPAs
-
-```
-sudo apt-manage -b add ppa:system76/proposed
-```
-Verify that the information output and the resulting deb lines (at the end of
-the output) appear correct for the given PPA.
-
-```
-sudo apt-manage add -s ppa:system76/proposed
-```
-Verify that the `deb-src` is included in the `Types` field, then remove the
-repository: `sudo apt-manage remove ppa-system76-proposed`
-
-```
-sudo apt-manage add -d ppa:system76/proposed
-```
-Verify that the `Enabled` field is set to `no`, then remove the
-repository: `sudo apt-manage remove ppa-system76-proposed`
-
-```
-sudo apt-manage add ppa:system76/proposed
-```
-Verify that the command asks for verification before completing and displays
-information about the PPA (similar to `add-apt-repository`). Verify that the
-command fetches the signing key and adds it to the system. Verify that the
-the correct `.list` file is added to `/etc/apt/sources.list.d`, then remove the
-repository: `sudo apt-manage remove ppa-system76-proposed`
-
-
-2. Test adding deb repositories
-
-```
-sudo apt-manage add --format list deb http://example.com/ubuntu focal main
-```
-Verify that the added repository matches the given input, and that there is a
-commented-out `deb-src` repository with it. Ensure that the added repository
-file ends in `.list` and that the contents match legacy Deb format.
-
-Remove the repository with `sudo apt-manage remove
-
-3. Test adding URLs
-
-```
-sudo apt-manage add --format list http://example.com/ubuntu
-```
-Verify that the repository is correctly expanded to include the `deb` at the
-beginning, and the correct `{RELEASE} main` suites and components, where
-{RELEASE} matches the current version codename. Verify that a matching `deb-src`
-entry is added as well in the command output.
-
-4. Test adding Pop Development repositories
-
-```
-sudo apt-manage add popdev:master
-```
-
-Verify that the repository details are correct, that the `Signed-by` field
-points to `/etc/apt/keyrings/popdev-archive-keyring.gpg`, that the key file
-exists at that path. Then, delete the repostiory:
-```
-sudo apt-manage remove popdev-master
-```
-
-#### Test Listing Details
-
-1. Test that all repos are listed
-
-```
-apt-manage list
-```
-Verify that all configured repositories added to `/etc/apt/sources.list.d` are
-printed in the command output.
-
-2. Test that details for all repositories are listed
-
-```
-apt-manage list -a
-```
-
-Verify that the specific configuration for each repository listed in step 1 is
-presented in the output.
-
-3. Test that details for a specific repository are listed
-
-```
-apt-manage list system
-```
-
-Verify that the detailed configuration for only the specified repository is
-listed in the output.
-
-
-#### Removing repositories
-
-1. Test cancelling removal
-
-```
-sudo apt-manage remove example-com-ubuntu
-sudo apt-manage remove example-com-ubuntu
-sudo apt-manage remove example-com-ubuntu
-```
-
-On the first run, enter 'n' and press enter. Verify that the source is not
-removed using `apt-manage list`.
-
-On the second run, simply press enter. Verify that the source is not removed by
-using `apt-manage list`.
-
-On the third run, enter 'v' and press enter. Verify that the source is not removed by
-using `apt-manage list`.
-
-2. Test removing sources
-
-```
-sudo apt-manage remove example-com-ubuntu
-```
-
-Enter 'y'. Verify that the source is removed using `apt-manage list`.
-
-3. Verify protection of system sources
-
-```
-sudo apt-manage remove system
-```
-
-Verify that the command returns an error and that no action is taken (even if a
-system.sources file does not exist) using `apt-manage list`
-
-
-#### Modifying a repository
-
-##### Setup
-
-Add a testing repository:
-
-```
-sudo apt-manage add popdev:master
-apt-manage list popdev-master
-```
-Verify that the details are correct in the output.
-
-1. Change Repository Name
-
-```
-sudo apt-manage modify popdev-master --name 'Testing Repo'
-apt-manage list popdev-master
-```
-
-Verify that the name was updated in the final output to match the given input
-`Testing Repo`
-
-2. Disable Repository
-
-```
-sudo apt-manage modify popdev-master --disable
-apt-manage list popdev-master
-```
-Ensure that the repository is now listed as `Enabled: no`.
-
-3. Add/Remove URI
-
-```
-sudo apt-manage modify popdev-master --add-uri http://example.com/
-apt-manage list popdev-master
-```
-Ensure that the `http://example.com` URI was added to the source.
-
-```
-sudo apt-manage modify popdev-master --remove-uri http://example.com
-apt-manage list popdev-master
-```
-Ensure that the `http://example.com` URI was removed.
-
-4. Add/Remove Suite
-
-```
-sudo apt-manage modify popdev-master --add-suite xenial
-apt-manage list popdev-master
-```
-Ensure that the suite `xenial` was added to the source.
-
-```
-sudo apt-manage modify popdev-master --remove-suite xenial
-apt-manage list popdev-master
-```
-
-Ensure that the suite `xenial` was removed from the source.
-
-5. Add/Remove Components
-
-```
-sudo apt-manage modify popdev-master --add-component 'universe multiverse'
-apt-manage list popdev-master
-```
-Ensure that the components `universe` and `multiverse` were added to the source.
-
-```
-sudo apt-manage modify popdev-master --remove-component 'main multiverse'
-apt-manage list popdev-master
-```
-Ensure that the components `main` and `multiverse` were removed from the source.
-
-
-#### Enabling/Disabling Source Code
-
-##### Setup
-
-Add a testing repository:
-
-```
-apt-manage list popdev-master
-```
-Verify that the details are correct in the output and that `Types:` is just
-`deb`.
-
-1. Enable source code for one repo
-
-```
-sudo apt-manage modify --source-enable popdev-master
-apt-manage list popdev-master
-```
-Verify that the `Types:` is now `deb deb-src`.
-
-2. Disable source code for one repo
-
-```
-sudo apt-manage modify --source-disable popdev-master
-apt-manage list popdev-master
-```
-Verify that the `Types:` is now just `deb`.
-
-Finally, remove the testing repository:
-```
-sudo apt-manage remove popdev-master
-```
-
-### Installation/upgrading (packaging tests)
-
-_This section is to test the installation behavior of the Debian package,
-and doesn't need to be run for changes to repolib itself._
-
-**Confirm add-apt-repository is installed when software-properties-common is not installed:**
-
-- [ ] Make sure `software-properties-common` is not installed.
-- [ ] Remove `python3-repolib` with `sudo dpkg -r --force-all python3-repolib`.
-- [ ] Ensure `/usr/bin/add-apt-repository` doesn't exist (if it does, remove it.)
-- [ ] Install `python3-repolib` (can be done with `sudo apt install -f`).
-- [ ] Ensure `/usr/bin/add-apt-repository` exists and is a link to `/usr/lib/repolib/add-apt-repository`.
-
-**Confirm add-apt-repository is not installed when software-properties-common is installed:**
-
-- [ ] Remove `python3-repolib` with `sudo dpkg -r --force-all python3-repolib`.
-- [ ] Ensure `/usr/bin/add-apt-repository` doesn't exist (if it does, remove it.)
-- [ ] Install `software-properties-common`, confirm `/usr/bin/add-apt-repository` now exists and is not a link.
- - Can be done with `apt download software-properties-common python3-software-properties`
- followed by `dpkg -i` on the downloaded files.
-- [ ] Install `python3-repolib` again, confirm `/usr/bin/add-apt-repository` still isn't a link.
-
-**Confirm add-apt-repository is installed when software-properties-common is removed:**
-
-- [ ] Remove `software-properties-common` and confirm that `/usr/bin/add-apt-repository` still exists and is now a link.
diff --git a/archive/apt-manage-spec.rst b/archive/apt-manage-spec.rst
deleted file mode 100644
index d8d31ea..0000000
--- a/archive/apt-manage-spec.rst
+++ /dev/null
@@ -1,172 +0,0 @@
-===================
-Spec for apt-manage
-===================
-
-apt-manage is the CLI interface to manage software sources using RepoLib. It is
-written in Python and shipped with RepoLib
-
-Commands
-========
-
-There are several commands provided by apt-manage::
-
- add
- remove
- modify
- list
- source
-
-add
----
-
-The add command is used for adding new software sources to the system. It
-requires root. It has the following options::
-
- --disable, -d
- --source-code, -s
- --expand, -e
-
---disable
-^^^^^^^^^
-
-The --disable option (short form -d) will add the source and disable it
-immediately
-
---source-code
-^^^^^^^^^^^^^
-
-The --source-code option (short form -s) will enable source code for the
-new source as well as binary packages.
-
---expand
-^^^^^^^^
-
-The --expand options (short form -e) will show expanded details about the source
-prior to adding it.
-
-remove
-------
-
-The remove command will remove the selected source. It has no options. Note that
-the system sources cannot be removed. This requires root.
-
-modify
-------
-
-The modify command will allow making modifications to the specified repository.
-It requires providing a repository to modify. It requires root. It accepts the
-following options::
-
- --enable, -e
- --disable, -d
- --add-suite
- --remove-suite
- --add-component
- --remove-component
- --add-uri
- --remove-uri
- --add-option
- --remove-option
-
---enable
-^^^^^^^^
-
-The enable option (short form -e) sets the source to be enabled.
-
---disable
-^^^^^^^^^
-
-The disable option (short form -d) sets the source to be disabled.
-
---add-suite
-^^^^^^^^^^^
-
-The --add-suite option attempts to add the specified suite or suites to the
-source. If a given suite is already added to the source, it is ignored. Note
-that legacy deb sources cannot have multiple suites.
-
---remove-suite
-^^^^^^^^^^^^^^
-
-The --remove-suite option attempts to remove the specified suite or suites from
-the source. If a given suite is not added to the source, it is ignored. The last
-configured suite on a source cannot be removed.
-
---add-component
-^^^^^^^^^^^^^^^
-
-The --add-component option attempts to add the specified component or components
-to the source. If a given component is already added to the source, it is
-ignored.
-
---remove-component
-^^^^^^^^^^^^^^^^^^
-
-The --remove-component option attempts to remove the specified component or
-components from the source. If a given component is not added to the source, it
-is ignored. The last configured component on a source cannot be removed.
-
---add-uri
-^^^^^^^^^
-
-The --add-uri option attempts to add the specified URI or URIs to the source. If
-a given URI is already added to the source, it is ignored. Note that legacy deb
-sources cannot have multiple URIs.
-
---remove-uri
-^^^^^^^^^^^^
-
-The --remove-uri option attempts to remove the specified URI or URIs from the
-source. If a given URI is not added to the source, it is ignored. The last
-configured URI on a source cannot be removed.
-
---add-option
-^^^^^^^^^^^^
-The --add-option option attempts to add the given option or options as well as
-values to the source. If a given option is already added to the source, it is
-ignored.
-
---remove-option
-^^^^^^^^^^^^^^^
-
-The --remove-option option attempts to remove the given option or options from
-the source. If a given option isn't added to the source, it is ignored.
-
-list
-----
-
-The list command lists available software sources as well as details about
-sources. With no further options, it lists all configured sources. With a
-configured source, it lists details about the specified source. It has the
-following option::
-
- --verbose, -v
- --legacy, -l
-
---verbose
-^^^^^^^^^
-
-The --verbose option (short form -v) lists all details for all configured
-software sources. It has no effect if a specific source is provided.
-
-source
-------
-
-The source command allows enabling or disabling source code in configured
-sources. If a configured source is provided, this command will affect that
-source. If no sources are provided, this command will affect all sources on the
-system. Without options, it will list the status for source code packages. It
-also accepts the following options, which require root::
-
- --enable, -e
- --disable, -d
-
---enable
-^^^^^^^^
-
-The --enable option (short form -e) will enable source code packages.
-
---disable
-^^^^^^^^^
-
-The --disable option (short form -d) will disable source code packages
\ No newline at end of file
diff --git a/archive/bin/add-apt-repository b/archive/bin/add-apt-repository
deleted file mode 100755
index 5c2f26c..0000000
--- a/archive/bin/add-apt-repository
+++ /dev/null
@@ -1,194 +0,0 @@
-#!/usr/bin/python3
-
-"""
-Copyright (c) 2019-2020, Ian Santopietro
-All rights reserved.
-
-This file is part of RepoLib.
-
-RepoLib is free software: you can redistribute it and/or modify
-it under the terms of the GNU Lesser General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-RepoLib 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 Lesser General Public License for more details.
-
-You should have received a copy of the GNU Lesser General Public License
-along with RepoLib. If not, see .
-"""
-#pylint: disable=invalid-name
-# Pylint will complain about our module name not being snake_case, however this
-# is a command rather than a python module, and thus this is correct anyway.
-
-import argparse
-import os
-import subprocess
-
-import repolib
-
-system_codename = repolib.util.DISTRO_CODENAME
-
-system_components = [
- 'main',
- 'universe',
- 'multiverse',
- 'restricted'
-]
-
-system_suites = [
- system_codename,
- f'{system_codename}-updates',
- f'{system_codename}-security',
- f'{system_codename}-backports',
- f'{system_codename}-proposed',
- 'updates',
- 'security',
- 'backports',
- 'proposed',
-]
-
-def get_args():
- parser = argparse.ArgumentParser(
- prog='add-apt-repository',
- description=(
- 'add-apt-repository is a script for adding apt sources.list entries.'
- '\nThis command has been deprecated in favor of `apt-manage`. See '
- '`apt-manage --help` for more information.'
- )
- )
-
- parser.add_argument(
- 'sourceline',
- metavar=''
- )
-
- group = parser.add_mutually_exclusive_group()
-
- group.add_argument(
- '-m',
- '--massive-debug',
- dest='debug',
- action='store_true',
- help='Print a lot of debug information to the command line'
- )
-
- group.add_argument(
- '-r',
- '--remove',
- action='store_true',
- help='remove repository from sources.list.d directory'
- )
-
- group.add_argument(
- '-s',
- '--enable-source',
- dest='source',
- action='store_true',
- help='Allow downloading of source packages from the repository'
- )
-
- parser.add_argument(
- '-y',
- '--yes',
- action='store_true',
- help='Assum yes to all queries'
- )
-
- parser.add_argument(
- '-n',
- '--no-update',
- dest='noupdate',
- action='store_true',
- help='Do not update package cache after adding'
- )
-
- parser.add_argument(
- '-u',
- '--update',
- action='store_true',
- help='Update package cache after adding (legacy option)'
- )
-
- parser.add_argument(
- '-k',
- '--keyserver',
- metavar='KEYSERVER',
- help='Legacy option, unused.'
- )
-
- return parser
-
-parser = get_args()
-args = parser.parse_args()
-
-command = ['apt-manage']
-
-if args.debug:
- command.append('-bb')
-
-sourceline = args.sourceline
-run = True
-remove = False
-
-if sourceline in system_components:
- command.append('modify')
- command.append('system')
- if not args.remove:
- command.append('--add-component')
- else:
- command.append('--remove-component')
-
-elif sourceline in system_suites:
- command.append('modify')
- command.append('system')
- if not args.remove:
- command.append('--add-suite')
- else:
- command.append('--remove-suite')
-
-else:
-
- if args.source:
- command.append('source')
-
- elif args.remove:
- remove = True
- command.append('remove')
-
- else:
- command.append('add')
- if not args.yes:
- command.append('--expand')
-
-if not remove:
- command.append(sourceline)
-else:
- sources = repolib.get_all_sources()
- comp_source = repolib.DebLine(sourceline)
- for source in sources:
- if comp_source.uris[0] in source.uris:
- name = str(source.filename.name)
- name = name.replace(".list", "")
- name = name.replace(".sources", "")
- command.append(name)
-
-run = True
-
-if os.geteuid() != 0:
- print('Error: must run as root')
- run = False
-
-if run:
- subprocess.run(command)
-
- if not args.noupdate:
- subprocess.run(['apt', 'update'])
-
-print('NOTE: add-apt-repository is deprecated in Pop!_OS. Use this instead:')
-print_command = command.copy()
-if '--expand' in print_command:
- print_command.remove('--expand')
-print(' '.join(print_command))
diff --git a/archive/bin/apt-manage b/archive/bin/apt-manage
deleted file mode 100755
index 77ae812..0000000
--- a/archive/bin/apt-manage
+++ /dev/null
@@ -1,85 +0,0 @@
-#!/usr/bin/python3
-
-"""
-Copyright (c) 2019-2020, Ian Santopietro
-All rights reserved.
-
-This file is part of RepoLib.
-
-RepoLib is free software: you can redistribute it and/or modify
-it under the terms of the GNU Lesser General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-RepoLib 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 Lesser General Public License for more details.
-
-You should have received a copy of the GNU Lesser General Public License
-along with RepoLib. If not, see .
-"""
-#pylint: disable=invalid-name
-# Pylint will complain about our module name not being snake_case, however this
-# is a command rather than a python module, and thus this is correct anyway.
-
-import argparse
-import logging
-import os
-import sys
-
-import repolib
-from repolib import command
-
-SOURCES_DIR = '/etc/apt/sources.list.d'
-
-def main(options=None):
- """ Main function for apt-manage."""
- # Set up Argument Parsing.
- parser = repolib.command.parser
-
- # Parse options
- args = parser.parse_args()
- if options:
- args = parser.parse_args(options)
-
- if not args.debug:
- args.debug = 0
-
- if args.debug > 2:
- args.debug = 2
-
- verbosity = {
- 0 : logging.WARN,
- 1 : logging.INFO,
- 2 : logging.DEBUG
- }
-
- log = logging.getLogger('apt-manage')
- handler = logging.StreamHandler()
- formatter = logging.Formatter('%(name)s: %(levelname)s: %(message)s')
- handler.setFormatter(formatter)
- log.addHandler(handler)
- log.setLevel(verbosity[args.debug])
- log.debug('Logging set up!')
- repolib.set_logging_level(args.debug)
-
- if not args.action:
- args = parser.parse_args(sys.argv[1:] + ['list'])
-
- log.debug('Arguments passed: %s', str(args))
- log.debug('Got command: %s', args.action)
-
- subcommand = args.action.capitalize()
-
- command = getattr(repolib.command, subcommand)(log, args, parser)
- result = command.run()
- if not result:
- sys.exit(1)
-
-if __name__ == '__main__':
- try:
- main()
- except KeyboardInterrupt:
- print('')
- sys.exit(130)
diff --git a/archive/data/bash-completion/apt-manage b/archive/data/bash-completion/apt-manage
deleted file mode 100755
index f881bc4..0000000
--- a/archive/data/bash-completion/apt-manage
+++ /dev/null
@@ -1,42 +0,0 @@
-# Debian apt-manage completion
-
-_apt_manage()
-{
- local cur prev words cword package
- _init_completion -n ':=' || return
-
- local special i
- i=0
- for (( i=0; i < ${#words[@]}-1; i++ )); do
- if [[ ${words[i]} == @(add|list|modify|remove|key) ]]; then
- special=${words[i]}
- fi
- done
-
- if [[ -n $special ]]; then
- case $special in
- list|modify|remove|key)
- COMPREPLY=( $( compgen -W '$(apt-manage list -n)' -- "$cur" ) )
- return
- ;;
- *)
- ;;
- esac
- fi
-
-
- if [[ "$cur" == -* ]]; then
- return
- # COMPREPLY=( $(compgen -W '
- # --help --disable --source-code --expand
- # --verbose --legacy --no-names
- # --enable --disable --name --add-suite --remove-suite
- # --add-component --remove-component --add-uri --remove-uri
- # ' -- "$cur") )
- else
- COMPREPLY=( $(compgen -W 'add list modify remove key' \
- -- "$cur") )
- fi
-
-} &&
-complete -F _apt_manage apt-manage
diff --git a/archive/data/org.pop_os.repolib.conf b/archive/data/org.pop_os.repolib.conf
deleted file mode 100644
index cadef8b..0000000
--- a/archive/data/org.pop_os.repolib.conf
+++ /dev/null
@@ -1,20 +0,0 @@
-
-
-
- system
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/archive/data/org.pop_os.repolib.policy b/archive/data/org.pop_os.repolib.policy
deleted file mode 100644
index 7a6caef..0000000
--- a/archive/data/org.pop_os.repolib.policy
+++ /dev/null
@@ -1,20 +0,0 @@
-
-
-
-
- Repoman
- https://github.com/pop-os/repolib
- x-system-software-sources
-
-
- Modifies a Debian Repository in the system software sources.
- Authentication is required to change software sources.
-
- auth_admin_keep
- auth_admin_keep
- auth_admin_keep
-
-
-
\ No newline at end of file
diff --git a/archive/data/org.pop_os.repolib.service b/archive/data/org.pop_os.repolib.service
deleted file mode 100644
index 2f354e3..0000000
--- a/archive/data/org.pop_os.repolib.service
+++ /dev/null
@@ -1,4 +0,0 @@
-[D-BUS Service]
-Name=org.pop_os.repolib
-Exec=/usr/bin/python3 /usr/lib/repolib/service.py
-User=root
diff --git a/archive/data/service.py b/archive/data/service.py
deleted file mode 100755
index b8d79dd..0000000
--- a/archive/data/service.py
+++ /dev/null
@@ -1,316 +0,0 @@
-#!/usr/bin/python3
-'''
- Copyright 2020 Ian Santopietro (ian@system76.com)
-
- This file is part of Repolib.
-
- Repolib 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.
-
- Repolib 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 Repolib. If not, see .
-'''
-#pylint: skip-file
-
-import shutil
-import subprocess
-
-import gi
-from gi.repository import GObject, GLib
-
-from pathlib import Path
-import dbus
-import dbus.service
-import dbus.mainloop.glib
-import time
-
-import repolib
-
-class RepolibException(dbus.DBusException):
- _dbus_error_name = 'org.pop_os.repolib.RepolibException'
-
-class PermissionDeniedByPolicy(dbus.DBusException):
- _dbus_error_name = 'org.pop_os.repolib.PermissionDeniedByPolicy'
-
-class AptException(Exception):
- pass
-
-class Repo(dbus.service.Object):
- def __init__(self, conn=None, object_path=None, bus_name=None):
- dbus.service.Object.__init__(self, conn, object_path, bus_name)
-
- # These are used by PolKit to check privileges
- self.dbus_info = None
- self.polkit = None
- self.enforce_polkit = True
-
- try:
- self.system_repo = repolib.SystemSource()
- except:
- self.system_repo = None
-
- self.source = None
- self.sources_dir = Path('/etc/apt/sources.list.d')
- self.keys_dir = Path('/etc/apt/trusted.gpg.d')
-
- @dbus.service.method(
- "org.pop_os.repolib.Interface",
- in_signature='as', out_signature='',
- sender_keyword='sender', connection_keyword='conn'
- )
- def add_apt_signing_key(self, cmd, sender=None, conn=None):
- self._check_polkit_privilege(
- sender, conn, 'org.pop_os.repolib.modifysources'
- )
- print(cmd)
- key_path = str(cmd.pop(-1))
- with open(key_path, mode='wb') as keyfile:
- try:
- subprocess.run(cmd, check=True, stdout=keyfile)
- except subprocess.CalledProcessError as e:
- raise e
-
- @dbus.service.method(
- "org.pop_os.repolib.Interface",
- in_signature='ss', out_signature='',
- sender_keyword='sender', connection_keyword='conn'
- )
- def install_signing_key(self, src, dest, sender=None, conn=None):
- self._check_polkit_privilege(
- sender, conn, 'org.pop_os.repolib.modifysources'
- )
- shutil.copy2(src, dest)
-
- @dbus.service.method(
- "org.pop_os.repolib.Interface",
- in_signature='s', out_signature='',
- sender_keyword='sender', connection_keyword='conn'
- )
- def delete_signing_key(self, src, sender=None, conn=None):
- self._check_polkit_privilege(
- sender, conn, 'org.pop_os.repolib.modifysources'
- )
- key_path = Path(src)
- key_path.unlink()
-
- @dbus.service.method(
- "org.pop_os.repolib.Interface",
- in_signature='s', out_signature='',
- sender_keyword='sender', connection_keyword='conn'
- )
- def delete_prefs_file(self, src, sender=None, conn=None):
- self._check_polkit_privilege(
- sender, conn, 'org.pop_os.repolib.modifysources'
- )
- prefs_path = Path(src)
- prefs_path.unlink()
-
- @dbus.service.method(
- "org.pop_os.repolib.Interface",
- in_signature='ss', out_signature='',
- sender_keyword='sender', connection_keyword='conn'
- )
- def output_prefs_to_disk(self, path, contents, sender=None, conn=None):
- self._check_polkit_privilege(
- sender, conn, 'org.pop_os.repolib.modifysources'
- )
- full_path = Path(path)
- with open(full_path, mode='w') as output_file:
- output_file.write(contents)
-
- @dbus.service.method(
- "org.pop_os.repolib.Interface",
- in_signature='ss', out_signature='',
- sender_keyword='sender', connection_keyword='conn'
- )
- def output_file_to_disk(self, filename, source, sender=None, conn=None):
- self._check_polkit_privilege(
- sender, conn, 'org.pop_os.repolib.modifysources'
- )
- full_path = self.sources_dir / filename
- with open(full_path, mode='w') as output_file:
- output_file.write(source)
-
- @dbus.service.method(
- "org.pop_os.repolib.Interface",
- in_signature='ss', out_signature='',
- sender_keyword='sender', connection_keyword='conn'
- )
- def backup_alt_file(self, alt_file, save_file, sender=None, conn=None):
- self._check_polkit_privilege(
- sender, conn, 'org.pop_os.repolib.modifysources'
- )
- alt_path = self.sources_dir / alt_file
- save_path = self.sources_dir / save_file
- if alt_path.exists():
- alt_path.rename(save_path)
-
- @dbus.service.method(
- "org.pop_os.repolib.Interface",
- in_signature='s', out_signature='',
- sender_keyword='sender', connection_keyword='conn'
- )
- def delete_source_file(self, filename, sender=None, conn=None):
- self._check_polkit_privilege(
- sender, conn, 'org.pop_os.repolib.modifysources'
- )
- source_file = self.sources_dir / filename
- source_file.unlink()
-
- @dbus.service.method(
- "org.pop_os.repolib.Interface",
- in_signature='', out_signature='',
- sender_keyword='sender', connection_keyword='conn'
- )
- def exit(self, sender=None, conn=None):
- mainloop.quit()
-
- @dbus.service.method(
- "org.pop_os.repolib.Interface",
- in_signature='b', out_signature='b',
- sender_keyword='sender', connection_keyword='conn'
- )
- def set_system_source_code_enabled(self, enabled, sender=None, conn=None):
- """ Enable or disable source code in the system source.
-
- Arguments:
- enabled (bool): The new state to set, True = Enabled.
- """
- self._check_polkit_privilege(
- sender, conn, 'org.pop_os.repolib.modifysources'
- )
- if self.system_repo:
- self.system_repo.load_from_file()
- new_types = [repolib.util.AptSourceType.BINARY]
- if enabled:
- new_types.append(repolib.util.AptSourceType.SOURCE)
- self.system_repo.types = new_types
- self.system_repo.save_to_disk()
- return enabled
- return False
-
- @dbus.service.method(
- "org.pop_os.repolib.Interface",
- in_signature='sb', out_signature='b',
- sender_keyword='sender', connection_keyword='conn'
- )
- def set_system_comp_enabled(self, comp, enable, sender=None, conn=None):
- """ Enable or disable a component in the system source.
-
- Arguments:
- comp (str): the component to set
- enable (bool): The new state to set, True = Enabled.
- """
- self._check_polkit_privilege(
- sender, conn, 'org.pop_os.repolib.modifysources'
- )
- if self.system_repo:
- self.system_repo.load_from_file()
- self.system_repo.set_component_enabled(component=comp, enabled=enable)
- self.system_repo.save_to_disk()
- return True
- return False
-
- @dbus.service.method(
- "org.pop_os.repolib.Interface",
- in_signature='sb', out_signature='b',
- sender_keyword='sender', connection_keyword='conn'
- )
- def set_system_suite_enabled(self, suite, enable, sender=None, conn=None):
- """ Enable or disable a suite in the system source.
-
- Arguments:
- suite (str): the suite to set
- enable (bool): The new state to set, True = Enabled.
- """
- self._check_polkit_privilege(
- sender, conn, 'org.pop_os.repolib.modifysources'
- )
- if self.system_repo:
- self.system_repo.load_from_file()
- self.system_repo.set_suite_enabled(suite=suite, enabled=enable)
- self.system_repo.save_to_disk()
- return True
- return False
-
- @classmethod
- def _log_in_file(klass, filename, string):
- date = time.asctime(time.localtime())
- ff = open(filename, "a")
- ff.write("%s : %s\n" %(date,str(string)))
- ff.close()
-
- @classmethod
- def _strip_source_line(self, source):
- source = source.replace("#", "# ")
- source = source.replace("[", "")
- source = source.replace("]", "")
- source = source.replace("'", "")
- source = source.replace(" ", " ")
- return source
-
- def _check_polkit_privilege(self, sender, conn, privilege):
- # from jockey
- '''Verify that sender has a given PolicyKit privilege.
- sender is the sender's (private) D-BUS name, such as ":1:42"
- (sender_keyword in @dbus.service.methods). conn is
- the dbus.Connection object (connection_keyword in
- @dbus.service.methods). privilege is the PolicyKit privilege string.
- This method returns if the caller is privileged, and otherwise throws a
- PermissionDeniedByPolicy exception.
- '''
- if sender is None and conn is None:
- # called locally, not through D-BUS
- return
- if not self.enforce_polkit:
- # that happens for testing purposes when running on the session
- # bus, and it does not make sense to restrict operations here
- return
-
- # get peer PID
- if self.dbus_info is None:
- self.dbus_info = dbus.Interface(conn.get_object('org.freedesktop.DBus',
- '/org/freedesktop/DBus/Bus', False), 'org.freedesktop.DBus')
- pid = self.dbus_info.GetConnectionUnixProcessID(sender)
-
- # query PolicyKit
- if self.polkit is None:
- self.polkit = dbus.Interface(dbus.SystemBus().get_object(
- 'org.freedesktop.PolicyKit1',
- '/org/freedesktop/PolicyKit1/Authority', False),
- 'org.freedesktop.PolicyKit1.Authority')
- try:
- # we don't need is_challenge return here, since we call with AllowUserInteraction
- (is_auth, _, details) = self.polkit.CheckAuthorization(
- ('unix-process', {'pid': dbus.UInt32(pid, variant_level=1),
- 'start-time': dbus.UInt64(0, variant_level=1)}),
- privilege, {'': ''}, dbus.UInt32(1), '', timeout=600)
- except dbus.DBusException as e:
- if e._dbus_error_name == 'org.freedesktop.DBus.Error.ServiceUnknown':
- # polkitd timed out, connect again
- self.polkit = None
- return self._check_polkit_privilege(sender, conn, privilege)
- else:
- raise
-
- if not is_auth:
- Repo._log_in_file('/tmp/repolib.log','_check_polkit_privilege: sender %s on connection %s pid %i is not authorized for %s: %s' %
- (sender, conn, pid, privilege, str(details)))
- raise PermissionDeniedByPolicy(privilege)
-
-if __name__ == '__main__':
- dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
-
- bus = dbus.SystemBus()
- name = dbus.service.BusName("org.pop_os.repolib", bus)
- object = Repo(bus, '/Repo')
-
- mainloop = GLib.MainLoop()
- mainloop.run()
\ No newline at end of file
diff --git a/archive/data/zsh-completion/_apt-manage b/archive/data/zsh-completion/_apt-manage
deleted file mode 100644
index 7ccf75b..0000000
--- a/archive/data/zsh-completion/_apt-manage
+++ /dev/null
@@ -1,70 +0,0 @@
-#compdef apt-manage
-typeset -A opt_args
-
-typeset -A opt_args
-
-_arguments -C \
- '1:cmd:->cmds' \
- '2:sources:->source_lists' \
- '*:: :->args' \
-&& ret=0
-
-case "$state" in
- (cmds)
- local commands; commands=(
- 'add'
- 'list'
- 'modify'
- 'remove'
- 'key'
- )
- _describe -t commands 'command' commands && ret=0
- ;;
- (source_lists)
- local sources
- sources=( $(apt-manage list -n))
- _describe -t sources 'source' sources && ret=0
- ;;
- (args)
- local arguments
- arguments=(
- # Main command
- '--help'
- # Add subcommand
- '--disable'
- '--source-code'
- '--terse'
- '--name'
- '--identifier'
- '--format'
- '--skip-keys'
- # Key Ssbcommand
- '--path'
- '--url'
- '--ascii'
- '--fingerprint'
- '--keyserver'
- '--remove'
- # List subcommand
- '--legacy'
- '--verbose'
- '--all'
- '--file-names'
- # Modify subcommand
- '--enable'
- '--source-enable'
- '--source-disable'
- '--add-uri'
- '--add-suite'
- '--add-component'
- '--remove-uri'
- '--remove-suite'
- '--remove-component'
- # Remove subcommand
- '--assume-yes'
- )
- _describe -t arguments 'argument' arguments && ret=0
- ;;
-esac
-
-return 1
\ No newline at end of file
diff --git a/archive/debian/changelog b/archive/debian/changelog
deleted file mode 100644
index 980b413..0000000
--- a/archive/debian/changelog
+++ /dev/null
@@ -1,11 +0,0 @@
-repolib (2.2.0~99pika2) kinetic; urgency=medium
-
- * Remove stupid post scripts
-
- -- Ward Nakchbandi Fri, 09 Oct 2022 21:38:00 +0300
-
-repolib (2.2.0~99pika1) kinetic; urgency=medium
-
- * Initial Creation
-
- -- Ward Nakchbandi Fri, 09 Oct 2022 21:38:00 +0300
diff --git a/archive/docs/Makefile b/archive/docs/Makefile
deleted file mode 100644
index 298ea9e..0000000
--- a/archive/docs/Makefile
+++ /dev/null
@@ -1,19 +0,0 @@
-# Minimal makefile for Sphinx documentation
-#
-
-# You can set these variables from the command line.
-SPHINXOPTS =
-SPHINXBUILD = sphinx-build
-SOURCEDIR = .
-BUILDDIR = _build
-
-# Put it first so that "make" without argument is like "make help".
-help:
- @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
-
-.PHONY: help Makefile
-
-# Catch-all target: route all unknown targets to Sphinx using the new
-# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
-%: Makefile
- @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
\ No newline at end of file
diff --git a/archive/docs/aptmanage/add.rst b/archive/docs/aptmanage/add.rst
deleted file mode 100644
index d2e2121..0000000
--- a/archive/docs/aptmanage/add.rst
+++ /dev/null
@@ -1,71 +0,0 @@
-==============
-Adding Sources
-==============
-
-The ``add`` subcommand is used to add new repositories to the software sources.
-You can specify a deb-line to configure into the system or a ``ppa:`` shortcut
-to add the new source directly::
-
- $ sudo apt-manage add deb http://apt.pop-os.org/ubuntu disco main
- $ sudo apt-manage add ppa:system76/pop
-
-If an internet connection is available, ``apt-manage`` will additionally attempt
-to install the signing key for any ``ppa:`` shortcuts added.
-
-
-Options for adding sources
-==========================
-
-Various options control adding sources to the system.
-
-
-Source Code, Details, Disabling Sources
----------------------------------------
-
-To enable source code for the added repository, use the ``--source-code`` flag::
-
- $ apt-manage add --source-code ppa:system76/pop
-
-The new source can be disabled upon adding it using the ``--disable`` flag::
-
- $ apt-manage add --disable ppa:system76/pop
-
-Details for the PPA are printed for review prior to adding the source by default.
-This will print the generated configuration for the source as well as any
-available details fetched for the source (typically only available for PPA
-sources). To suppress this output, include ``--terse``.
-
-
-Source File Format
-------------------
-
-The format which RepoLib saves the repository on disk in depends on the type of
-repository being added, but regardless the ``--format`` flag can be used to
-force either legacy ``.list`` format or modern ``.sources`` format::
-
- apt-manage add popdev:master --format=list
- apt-manage add ppa:system76/pop --format=sources
-
-
-Names and Identifiers
----------------------
-
-Names for PPA sources are automatically detected from Launchpad if an internet
-connection is available. Otherwise they are automatically generated based on the
-source type and details. Optionally, a name can be specified when the source is
-added::
-
- $ apt-manage add ppa:system76/pop --name "PPA for Pop_OS Software"
-
-System-identifiers determine how the source is subsequently located within RepoLib and
-on the system. It matches the filename for the source's configuration file. It
-is automatically generated based on the source type, or can be specified
-manually upon creation using the ``--identifier`` flag::
-
- $ apt-manage add ppa:system76/pop --identifier pop-ppa
-
-.. note::
- Even though ``apt-manage`` allows modifcation or management of DEB822-format
- sources, it does not currently support adding them to the system directly.
- DEB822 sources can be manually added or added using third-party tools, and
- ``apt-manage`` will correctly operate on them subsequently.
diff --git a/archive/docs/aptmanage/aptmanage.rst b/archive/docs/aptmanage/aptmanage.rst
deleted file mode 100644
index 2e80cc4..0000000
--- a/archive/docs/aptmanage/aptmanage.rst
+++ /dev/null
@@ -1,28 +0,0 @@
-==========
-Apt Manage
-==========
-
-``apt-manage`` is a command line tool for managing your local software sources
-using RepoLib. Run ``apt-manage`` standalone to get a listing of all of the
-software repositories currently configured::
-
- $ apt-manage
- Configured sources:
- system
- pop-os-apps
- ppa-system76-pop
-
-
-``apt-manage`` operates on both DEB822-formated sources (located in the
-``/etc/apt/sources.list.d/*.sources`` files) as well as using traditional
-one-line format sources (in ``/etc/apt/sources.list.d/*.list`` files).
-
-.. toctree::
- :maxdepth 1
- :caption: apt-manage Documentation
-
- add
- list
- modify
- remove
- key
diff --git a/archive/docs/aptmanage/key.rst b/archive/docs/aptmanage/key.rst
deleted file mode 100644
index 88fe9a6..0000000
--- a/archive/docs/aptmanage/key.rst
+++ /dev/null
@@ -1,78 +0,0 @@
-=====================
-Managing Signing Keys
-=====================
-
-Signing keys are an important part of repository security and are generally
-required to be used in repositories for all recent versions of APT. As previous
-methods of handling Apt keys have been deprecated, Apt Manage provides easy
-tools to use for managing signing keys for repositories in the ``key``
-subcommand.
-
-Most of the tools in the ``key`` subcommand are centered around adding a signing
-key to a repository::
-
- apt-manage key repo-id --fingerprint 63C46DF0140D738961429F4E204DD8AEC33A7AFF
-
-Apt Manage supports adding keys from a variety of sources:
-
-
-Existing Keyring Files, --name, --path
-======================================
-
-``--name`` sets the :ref:`signed_by` value of the existing repository to the
-name of a file within the system key configuration directory::
-
- apt-manage key popdev-master --name popdev
-
-``--path`` sets the :ref:`signed_by` value of the existing repository to the
-path of a file on disk::
-
- apt-manage key popdev-master --path /etc/apt/keyrings/popdev-archive-keyring.gpg
-
-
-Keyring Files Stored on the Internet, --url
-===========================================
-
-``--url`` will download a key file from the internet and install it into the
-system, then set the repository to use that key::
-
- apt-manage key popdev-master --url https://example.com/sigining-key.asc
-
-
-Keys Stored on a Public Keyserver
-=================================
-
-``--fingerprint`` will fetch the specified fingerprint from a public keyserver.
-By default, keys will be fetched from ``keyserver.ubuntu.com``, but any SKS
-keyserver can be specified using the ``--keyserver=`` argument::
-
- apt-manage key ppa-system76-pop \
- --fingerprint=E6AC16572ED1AD6F96C7EBE01E5F8BBC5BEB10AE
-
- apt-manage key popdev-master \
- --fingerprint=63C46DF0140D738961429F4E204DD8AEC33A7AFF \
- --keyserver=https://keyserver.example.com/
-
-
-Adding ASCII-Armored Keys Directly, --ascii
-===========================================
-
-``--ascii`` Will take plain ascii data from the command line and add it to a new
-keyring file, then set the repository to use that key::
-
- apt-manage key popdev-master --ascii "$(/tmp/popdev-key.asc)"
-
-
-Removing Keys
-=============
-
-Generally, manually removing keys is not necessary because removing a source
-automatically removes the key (if it is the only source using that key). However,
-If there is a need to remove a key manually (e.g. the signing key has changed
-and must be re-added), then removal is supported::
-
- apt-manage key popdev-master --remove
-
-This will remove the key from the repository configuration and if no other
-sources are using a particular key, it will also remove the keyring file from
-disk.
diff --git a/archive/docs/aptmanage/list.rst b/archive/docs/aptmanage/list.rst
deleted file mode 100644
index 7eacea9..0000000
--- a/archive/docs/aptmanage/list.rst
+++ /dev/null
@@ -1,79 +0,0 @@
-=============================
-Listing Configuration Details
-=============================
-
-To get a list of all of the sources configured on the system, use the ``list``
-subcommand::
-
- $ apt-manage list
- Configured sources:
- system - Pop_OS System Sources
- pop-os-apps - Pop_OS Applications
- ppa-system76-pop - Pop!_OS PPA
-
-The sources are listed with the system source (if detected/configured) first,
-followed by all DEB822-format sources detected first, then by all one-line
-format sources. The system-identifier (used to identify sources in the system)
-is listed at the beginning of the line, and the name of the source is listed
-after.
-
-Details of an individual source can be printed by specifying a source's
-system-identifier::
-
- $ apt-manage list ppa-system76-pop
- Details for source ppa-system76-pop:
- Name: Pop!_OS PPA
- Enabled: yes
- Types: deb deb-src
- URIs: http://apt.pop-os.org/release
- Suites: focal
- Components: main
-
-
-Listing all details of all sources at once
-==========================================
-
-Details about all sources can be listed at once using the ``--verbose`` flag::
-
- $ apt-manage list --verbose
- Configured sources:
- system - Pop_OS System Sources
- Name: Pop_OS System Sources
- Enabled: yes
- Types: deb deb-src
- URIs: http://us.archive.ubuntu.com/ubuntu/
- Suites: focal focal-security focal-updates focal-backports
- Components: main restricted universe multiverse
-
- pop-os-apps - Pop_OS Applications
- Name: Pop_OS Applications
- Enabled: yes
- Types: deb
- URIs: http://apt.pop-os.org/proprietary
- Suites: focal
- Components: main
-
- ppa-system76-pop - Pop!_OS PPA
- Name: Pop!_OS PPA
- Enabled: yes
- Types: deb deb-src
- URIs: http://apt.pop-os.org/release
- Suites: focal
- Components: main
-
-Note
-^^^^
-
-Passing the ``--verbose`` flag only applies to listing all sources. It has no
-effect if a source is specified using the system-identifier; in that case, only
-the specified source is printed. Additionally, if there are sources files which
-contain errors, the ``--verbose`` flag will print details about them, including
-the contents of the files and the stack trace of the exception which caused the
-error.
-
-
-Legacy sources.list entries
-===========================
-
-The contents of the system ``sources.list`` file can be appended to the end of
-the output using the ``--legacy`` flag.
\ No newline at end of file
diff --git a/archive/docs/aptmanage/modify.rst b/archive/docs/aptmanage/modify.rst
deleted file mode 100644
index 98a6929..0000000
--- a/archive/docs/aptmanage/modify.rst
+++ /dev/null
@@ -1,82 +0,0 @@
-=================
-Modifying Sources
-=================
-
-Modifications can be made to various configured sources using the ``modify``
-subcommand.
-
-Enabling/Disabling Sources: --enable | --disable
-================================================
-
-Sources can be disabled, which prevents software/updates from being installed
-from the source but keeps it present in the system configuration for later use
-or records for later. To disable a source, use ``--disable``::
-
- $ apt-manage modify ppa-system76-pop --disable
-
-To re-enable a source after it's been disabled, use ``--enable``::
-
- $ apt-manage modify ppa-system76-pop --enable
-
-
-Changing names of sources: --name
-=================================
-
-RepoLib allows setting up human-readable names for use in GUIs or other
-user-facing contexts. To set or change a name of a source, use ``--name``::
-
- $ apt-manage modify ppa-system76-pop --name "Pop_OS PPA"
-
-
-Suites: --add-suite | --remove-suite
-====================================
-
-Suites for sources can be added or removed from the configuration. In one-line
-sources, these are added with multiple lines, since each one-line source can
-have only one suite each. DEB822 sources can have multiple suites.
-
-To add a suite, use ``--add-suite``::
-
- $ apt-manage modify ppa-system76-pop --add-suite groovy
-
-Use ``--remove-suite`` to remove a suite::
-
- $ apt-manage modify ppa-system76-pop --remove-suite focal
-
-
-Components: --add-component | --remove-component
-================================================
-
-Both types of source format can have multiple components for each source. Note
-that all components for one-line format sources will share all of a source's
-components.
-
-Components are managed similarly to suites::
-
- $ apt-manage modify system --add-component universe
- $ apt-manage modify system --remove-component restricted
-
-
-URIs: --add-uri | --remove-uri
-==============================
-
-DEB822 sources may contain an arbitrary number of URIs. One-line sources require
-an additional line for each individual URI added. All suites on a source are all
-applied to all of the URIs equally.
-
-URIs are managed similarly to both suites and components::
-
- $ apt-manage modify system --add-uri http://apt.pop-os.org/ubuntu
- $ apt-manage modify system --remove-uri http://us.archive.ubuntu.com/ubuntu
-
-
-Notes
-^^^^^
-
-Multiple modifications may be applied on a single ``apt-manage modify`` calls::
-
- $ apt-manage modify system --name "Pop_OS 20.10 System Sources" \
- --add-suite groovy \
- --remove-suite focal focal-proposed \
- --add-uri http://apt.pop-os.org/ubuntu \
- --remove-uri http://us.archive.ubuntu.com/ubuntu
diff --git a/archive/docs/aptmanage/remove.rst b/archive/docs/aptmanage/remove.rst
deleted file mode 100644
index dfe1f03..0000000
--- a/archive/docs/aptmanage/remove.rst
+++ /dev/null
@@ -1,9 +0,0 @@
-================
-Removing Sources
-================
-
-To remove a source from the system configuration, use the ``remove``
-subcommand::
-
- $ apt-manage remove ppa-system76-pop
-
\ No newline at end of file
diff --git a/archive/docs/conf.py b/archive/docs/conf.py
deleted file mode 100644
index ee962e6..0000000
--- a/archive/docs/conf.py
+++ /dev/null
@@ -1,177 +0,0 @@
-# -*- coding: utf-8 -*-
-#
-# Configuration file for the Sphinx documentation builder.
-#
-# This file does only contain a selection of the most common options. For a
-# full list see the documentation:
-# http://www.sphinx-doc.org/en/master/config
-#pylint: skip-file
-
-# -- Path setup --------------------------------------------------------------
-
-# If extensions (or modules to document with autodoc) are in another directory,
-# add these directories to sys.path here. If the directory is relative to the
-# documentation root, use os.path.abspath to make it absolute, like shown here.
-#
-# import os
-# import sys
-# sys.path.insert(0, os.path.abspath('.'))
-
-import sphinx_rtd_theme
-
-
-# -- Project information -----------------------------------------------------
-
-project = 'RepoLib'
-copyright = '2019-2020, Ian Santopietro'
-author = 'Ian Santopietro'
-
-# The short X.Y version
-version = '0.0.8'
-# The full version, including alpha/beta/rc tags
-release = ''
-
-
-# -- General configuration ---------------------------------------------------
-
-# If your documentation needs a minimal Sphinx version, state it here.
-#
-# needs_sphinx = '1.0'
-
-# Add any Sphinx extension module names here, as strings. They can be
-# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
-# ones.
-extensions = [
-]
-
-# Add any paths that contain templates here, relative to this directory.
-templates_path = ['_templates']
-
-# The suffix(es) of source filenames.
-# You can specify multiple suffix as a list of string:
-#
-# source_suffix = ['.rst', '.md']
-source_suffix = '.rst'
-
-# The master toctree document.
-master_doc = 'index'
-
-# The language for content autogenerated by Sphinx. Refer to documentation
-# for a list of supported languages.
-#
-# This is also used if you do content translation via gettext catalogs.
-# Usually you set "language" from the command line for these cases.
-language = None
-
-# List of patterns, relative to source directory, that match files and
-# directories to ignore when looking for source files.
-# This pattern also affects html_static_path and html_extra_path.
-exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
-
-# The name of the Pygments (syntax highlighting) style to use.
-pygments_style = None
-
-
-# -- Options for HTML output -------------------------------------------------
-
-# The theme to use for HTML and HTML Help pages. See the documentation for
-# a list of builtin themes.
-#
-html_theme = 'sphinx_rtd_theme'
-html_theme_path = [sphinx_rtd_theme.get_html_theme_path()]
-
-# Theme options are theme-specific and customize the look and feel of a theme
-# further. For a list of options available for each theme, see the
-# documentation.
-#
-# html_theme_options = {}
-
-# Add any paths that contain custom static files (such as style sheets) here,
-# relative to this directory. They are copied after the builtin static files,
-# so a file named "default.css" will overwrite the builtin "default.css".
-html_static_path = ['_static']
-
-# Custom sidebar templates, must be a dictionary that maps document names
-# to template names.
-#
-# The default sidebars (for documents that don't match any pattern) are
-# defined by theme itself. Builtin themes are using these templates by
-# default: ``['localtoc.html', 'relations.html', 'sourcelink.html',
-# 'searchbox.html']``.
-#
-# html_sidebars = {}
-
-
-# -- Options for HTMLHelp output ---------------------------------------------
-
-# Output file base name for HTML help builder.
-htmlhelp_basename = 'RepoLibdoc'
-
-
-# -- Options for LaTeX output ------------------------------------------------
-
-latex_elements = {
- # The paper size ('letterpaper' or 'a4paper').
- #
- # 'papersize': 'letterpaper',
-
- # The font size ('10pt', '11pt' or '12pt').
- #
- # 'pointsize': '10pt',
-
- # Additional stuff for the LaTeX preamble.
- #
- # 'preamble': '',
-
- # Latex figure (float) alignment
- #
- # 'figure_align': 'htbp',
-}
-
-# Grouping the document tree into LaTeX files. List of tuples
-# (source start file, target name, title,
-# author, documentclass [howto, manual, or own class]).
-latex_documents = [
- (master_doc, 'RepoLib.tex', 'RepoLib Documentation',
- 'Ian Santopietro', 'manual'),
-]
-
-
-# -- Options for manual page output ------------------------------------------
-
-# One entry per manual page. List of tuples
-# (source start file, name, description, authors, manual section).
-man_pages = [
- (master_doc, 'repolib', 'RepoLib Documentation',
- [author], 1)
-]
-
-
-# -- Options for Texinfo output ----------------------------------------------
-
-# Grouping the document tree into Texinfo files. List of tuples
-# (source start file, target name, title, author,
-# dir menu entry, description, category)
-texinfo_documents = [
- (master_doc, 'RepoLib', 'RepoLib Documentation',
- author, 'RepoLib', 'One line description of project.',
- 'Miscellaneous'),
-]
-
-
-# -- Options for Epub output -------------------------------------------------
-
-# Bibliographic Dublin Core info.
-epub_title = project
-
-# The unique identifier of the text. This can be a ISBN number
-# or the project homepage.
-#
-# epub_identifier = ''
-
-# A unique identification for the text.
-#
-# epub_uid = ''
-
-# A list of files that should not be packed into the epub file.
-epub_exclude_files = ['search.html']
diff --git a/archive/docs/deb822-format.rst b/archive/docs/deb822-format.rst
deleted file mode 100644
index b01e815..0000000
--- a/archive/docs/deb822-format.rst
+++ /dev/null
@@ -1,276 +0,0 @@
-.. _deb822-explanation:
-
-=======================================
-Explanation of the DEB822 Source Format
-=======================================
-
-The sources described in ``/etc/apt/sources.list.d/`` on a Debian-based OS are
-designed to support any number of different active and inactive sources, as well
-as a large variety of source media and transport protocols. The files describe
-one or more sources each and contain multiline stanzas defining one or more
-sources per stanza, with the most preferred source listed first. Information
-about available packages and versions from each source is fetched using the
-``apt update`` command, or with an equivalent command from a different frontend.
-
-
-.. _sources-list-d:
-
-sources.list.d
-==============
-
-APT source information is stored locally within the ``/etc/apt/sources.list.d``
-directory. In this directory are one or more files describing one or more
-sources each. For :ref:`deb822-format` sources, each file needs to have the .sources
-extension. The filenames may only contain letters, digits, underscore, hyphen,
-and period characters. Files with other characters in their filenames will cause
-APT to print a notice that it has ignore that file (unless the file matches a
-pattern in the ``Dir::Ignore-Files-Silently`` configuration list, which will
-force APT to silently ignore the file.
-
-
-.. _one-line-format:
-
-One-Line-Style Format
-=====================
-
-In order to understand some of the decisions behind using the :ref:`deb822-format`
-sources, it is helpful to understand the older :ref:`one-line-format`.
-
-:ref:`one-line-format` sources occupy one line in a file ending in ``.list``.
-The line begins with a type (i.e. ``deb`` or ``deb-src`` followed by options and
-arguments for this type. Individual entries cannot be continued onto multiple
-lines (hence the "one-line" portion of this format's name). Empty lines in
-``.list`` files are ignored, and a ``#`` character anywhere on the line signifies
-that the remainder of that line is a comment. Consequently an entry can be
-disabled by commenting out that entire line (prefixing it with a ``#``). If
-options are provided, they are space-separated and all together are enclosed
-within square brackets ( ``[]`` ). Options allowing multiple values should
-separate each value with a comma ( ``,`` ) and each option name is separated
-from its values by an equals sign ( ``=`` ).
-
-This is the traditional format and is supported by all current APT versions.
-It has the advantage of being relatively compact for single-sources and
-relatively easy for humans to parse.
-
-
-.. _one-line-disadvantages:
-
-Disadvantages
--------------
-
-Problems with the :ref:`one-line-format` begin when parsing entries via machine.
-Traditional, optionless entries are relatively simple to parse, as each
-different portion of the entry is separated with a space. With options, however,
-this is no longer the case. The presence of options causes there to be no, 1, or
-multiple segments of configuration between the type declaration and the URI.
-Additionally, APT sources support a variety of URI schemas, with the capability
-for extensions to add additional schemas on certain configurations. Thus,
-supporting modern, optioned :ref:`one-line-format` source entries requires use
-of either regular expressions or multi-level parsing in order to adequately
-parse the entry. Further compounding this support is the fact that
-:ref:`one-line-format` entries can have one or more components, preventing
-parsing of sources backwards from the end towards the front.
-
-Consider the following examples::
-
- deb [] http://example.com.ubuntu disco main restricted multiverse universe
- deb [ arch=amd64 ] http://example.com/ubuntu disco main nonfree
- deb [lang=en_US] http://example.com/ubuntu disco main restricted universe multiverse
- deb [ arch=amd64,armel lang=en_US,en_CA ] http://example.com/ubuntu disco main
-
-Each of these entries are syntactically valid source entries, each cleanly
-splits into eight segments when splitting on spaces. Depending on which entry
-being parsed, the URI portion of the entry may be in index 2, 4, or 5 while
-options (where present) may be in index 1, 2, or 3. If we want to work backwards,
-then the URI is in either index -3, -4, or -6. The only segments guaranteed to
-be present at any given index is the type. The situation is even more
-complicated when considering that entries may have at a minimum 3 elements, and
-at a maximum 12 or more elements.
-
-In addition to parsing difficulty, :ref:`one-line-format` entries may only
-specify a single suite and URI per entry, meaning that having two active mirrors
-for a given source requires doubling the number of entries configured. You must
-also create an extra set of duplicated entries for each suite you want to
-configure. This can make tracking down duplicated entries difficult for users
-and leads to longer-than-necessary configuration.
-
-
-.. _deb822-format:
-
-Deb822-style Format
-===================
-
-This format addresses the file-length, duplication, and machine-parsability
-issues present in the :ref:`one-line-format`. Each source is configured in a
-single stanza of configuration, with lines explicitly describing their
-function for the source. They also allow for lists of values for most options,
-meaning that mirrors or multiple suites can be defined within a single source. A
-``#`` character at the beginning of a line marks the entire line as a comment.
-Entries can again be disabled by commenting out each line within the stanza;
-however, as a convenience this format also brings an ``Enabled:`` field which,
-when set to ``no`` disables the entry as well. Removing this field or setting it
-to ``yes`` re-enables it. Options have the same format as every other field,
-thus a stanza may be parsed by checking the beginning of each line for a fixed
-substring, and if the line doesn't match a known substring, it can be assumed
-the line is an option and the line can be ignored. Unknown options are ignored
-by all versions of APT. This has the unintentional side effect of adding
-extensibility to the source; by selecting a carefully namespaced field name,
-third-party applications and libraries can add their own fields to sources
-without causing breakage by APT. This can include comments, version information,
-and (as is the case with :ref:`repolib-module`, pretty, human-readable names.
-
-From the ``sources.list(5)`` manual page:
-
- This is a new format supported by apt itself since version 1.1. Previous
- versions ignore such files with a notice message as described earlier. It is
- intended to make this format gradually the default format, deprecating the
- previously described one-line-style format, as it is easier to create,
- extend and modify for humans and machines alike especially if a lot of
- sources and/or options are involved.
-
-.. _deb822-technical:
-
-===================================
-DEB822 Source Format Specifications
-===================================
-
-Following is a description of each field in the deb822 source format.
-
-
-.. _deb822-field-enabled:
-
-Enabled:
-========
-
-Enabled: (value: "yes" or "no", required: No, default: "yes")
- Tells APT whether the source is enabled or not. Disabled sources are not
- queried for package lists, effectively removing them from the system
- sources while still allowing reference or re-enabling at any time.
-
-.. _deb822-field-types:
-
-Types:
-======
-
-Types: (value: "deb" or "deb-src", required: Yes)
- Defines which types of packages to look for from a given source; either
- binary: ``deb`` or source code: ``deb-src``. The ``deb`` type references a
- typical two-level Debian archive providing packages containing pre-compiled
- binary data intended for execution on user machines. The ``deb-src`` type
- references a Debian distribution's source code in the same form as the ``deb``
- type. A ``deb-src`` line is required to fetch source pacakge indices.
-
-
-.. _deb822-field-uris:
-
-URIs:
-=====
-
-URIs: (value: string(s), required: Yes)
- The URI must specify the base of the Debian distribution archive, from which
- APT finds the information it needs. There must be a URI component present in
- order for the source to be valid; multipls URIs can be configured
- simultaneously by adding a space-separated list of URIs.
-
- A list of the current built-in URI Schemas supported by APT is available at
- the `Debian sources.list manpage `_.
-
-
-.. _deb822-field-suites:
-
-Suites:
-=======
-
-Suites: (value: strings(s), required: Yes)
- The Suite can specify an exact path in relation to the URI(s) provided, in
- which case the :ref:`deb822-field-components` **must** be omitted and suite
- **must** end with a slash ( ``/`` ). Alternatively, it may take the form of
- a distribution version (e.g. a version codename like ``disco`` or ``artful``
- ). If the suite does not specify a path, at least one
- :ref:`deb822-field-component` **must** be present.
-
-
-.. _deb822-field-components:
-
-Components:
-===========
-
-Components: (value: string(s), required: see :ref:`deb822-field-suites`)
- Components specify different sections of one distribution version present in
- a Suite. If :ref:`deb822-field-suites` specifies an exact path, then no
- Components may be specified. Otherwise, a component **must** be present.
-
-
-.. _deb822-options:
-
-Options
-=======
-
-Sources may specify a number of options. These options and their values will
-generally narrow a set of software to be available from the source or in some
-other way control what software is downloaded from it. An exhaustive list of
-options can be found at the
-`Debian sources.list manpage `_.
-
-
-.. _deb822-fields-repolib:
-
-RepoLib-Specific Deb822 Fields
-==============================
-
-RepoLib presently defines a single internal-use fields which it adds to deb822
-sources that it modifies.
-
-X-Repolib-Name:
----------------
-
-X-Repolib-Name: (value: string, required: no, default: filename)
- This field defines a formatted name for the source which is suitable for
- inclusion within a graphical UI or other interface which presents source
- information to an end-user. As a :ref:`repolib-module` specific field, this
- is silently ignored by APT and other tools operating with deb822 sources and
- is only intended to be utilized by :ref:`repolib-module` itself.
-
-
-.. _deb822-examples:
-
-========
-Examples
-========
-
-The following specifies a binary and source-code source fetching from the
-primary Ubuntu archive with multiple suites for updates as well as several components::
-
- Enabled: yes
- Types: deb deb-src
- URIs: http://archive.ubuntu.com/ubuntu
- Suites: disco disco-updates disco-security disco-backports
- Components: main universe multiverse restricted
-
-This is a source for fetching Google's Chrome browser, which specifies a CPU
-architecture option and a RepoLib Name::
-
- X-Repolib-Name: Google Chrome
- Enabled: yes
- URIs: http://dl.google.com/linux/chrome/deb
- Suites: stable
- Components: main
- Architectures: amd64
-
-This specifies a source for downloading packages for System76's Pop!_OS::
-
- X-Repolib-Name: Pop!_OS PPA
- Enabled: yes
- Types: deb
- URIs: http://ppa.launchpad.net/system76/pop/ubuntu
- Suites: disco
- Components: main
-
-Following is a PPA source which has been disabled::
-
- X-Repolib-Name: ZNC Stable
- Enabled: no
- Types: deb
- URIs: http://ppa.launchpad.net/teward/znc/ubuntu
- Suites: disco
- Components: main
diff --git a/archive/docs/index.rst b/archive/docs/index.rst
deleted file mode 100644
index 264d01e..0000000
--- a/archive/docs/index.rst
+++ /dev/null
@@ -1,182 +0,0 @@
-.. RepoLib documentation master file, created by
- sphinx-quickstart on Wed May 1 13:49:01 2019.
- You can adapt this file completely to your liking, but it should at least
- contain the root `toctree` directive.
-
-===================================
-Welcome to RepoLib's documentation!
-===================================
-
-RepoLib is a Python library and CLI tool-set for managing your software
-system software repositories. It's currently set up to handle APT repositories
-on Debian-based linux distributions.
-
-RepoLib is intended to operate on DEB822-format sources as well as legacy
-one-line format sources. It aims to provide feature parity with
-software-properties for most commonly used functions. It also allows for
-simple, automated conversion from legacy "one-line" style source to newer
-DEB822 format sources. These sources will eventually deprecate the older
-one-line sources and are much easier to parse for both human and machine. For a
-detailed explanation of the DEB822 Source format, see :ref:`deb822-explanation`.
-
-RepoLib provides much faster access to a subset of ``SoftwareProperties``
-features than ``SoftwareProperties`` itself does. Its scope is somewhat more
-limited because of this, but the performance improvements gained are substantial.
-``SoftwareProperties`` also does not yet feature support for managing DEB822
-format sources, and instead only manages one-line sources.
-
-RepoLib is available under the GNU LGPL.
-
-.. contents:: Table of Contents
- :local:
-
-.. toctree::
- :maxdepth: 4
- :caption: Developer Documentation
-
- library/developer
-
-.. toctree::
- :maxdepth: 1
- :caption: RepoLib Documentation
-
- deb822-format
-
-.. toctree::
- :maxdepth: 1
- :caption: apt-manage Documentation
-
- aptmanage/aptmanage
-
-============
-Installation
-============
-
-There are a variety of ways to install RepoLib
-
-From System Package Manager
-^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-If your operating system packages repolib, you can install it by running::
-
- sudo apt install python3-repolib
-
-
-Uninstall
-"""""""""
-
-To uninstall, simply do::
-
- sudo apt remove python3-repolib
-
-
-From PyPI
-^^^^^^^^^
-
-Repolib is available on PyPI. You can install it for your current user with::
-
- pip3 install repolib
-
-Alternatively, you can install it system-wide using::
-
- sudo pip3 install repolib
-
-Uninstall
-"""""""""
-
-To uninstall, simply do::
-
- sudo pip3 uninstall repolib
-
-From Git
-^^^^^^^^
-
-First, clone the git repository onto your local system::
-
- git clone https://github.com/isantop/repolib
- cd repolib
-
-Debian
-^^^^^^
-
-On debian based distributions, you can build a .deb package locally and install
-it onto your system. You will need the following build-dependencies:
-
- * debhelper (>= 11)
- * dh-python
- * lsb-release
- * python3-all
- * python3-dbus
- * python3-debian
- * python3-setuptools
- * python3-distutils
- * python3-pytest
- * python3-gnupg
-
-You can use this command to install these all in one go::
-
- sudo apt install debhelper dh-python python3-all python3-setuptools python3-gnupg
-
-Then build and install the package::
-
- debuild -us -uc
- cd ..
- sudo dpkg -i python3-repolib_*.deb
-
-Uninstall
-"""""""""
-
-To uninstall, simply do::
-
- sudo apt remove python3-repolib
-
-setuptools setup.py
-^^^^^^^^^^^^^^^^^^^
-
-You can build and install the package using python3-setuptools. First, install
-the dependencies::
-
- sudo apt install python3-all python3-setuptools
-
-Then build and install the package::
-
- sudo python3 ./setup.py install
-
-Uninstall
-"""""""""
-
-You can uninstall RepoLib by removing the following files/directories:
-
- * /usr/local/lib/python3.7/dist-packages/repolib/
- * /usr/local/lib/python3.7/dist-packages/repolib-\*.egg-info
- * /usr/local/bin/apt-manage
-
-This command will remove all of these for you::
-
- sudo rm -r /usr/local/lib/python3.7/dist-packages/repolib* /usr/local/bin/apt-manage
-
-
-|
-|
-|
-|
-|
-
-Copyright © 2019-2022, Ian Santopietro
-All rights reserved.
-
-This file is part of RepoLib.
-
-RepoLib is free software: you can redistribute it and/or modify
-it under the terms of the GNU Lesser General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-RepoLib 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 Lesser General Public License for more details.
-
-You should have received a copy of the GNU Lesser General Public License
-along with RepoLib. If not, see .
-
diff --git a/archive/docs/installation.rst b/archive/docs/installation.rst
deleted file mode 100644
index a8279d1..0000000
--- a/archive/docs/installation.rst
+++ /dev/null
@@ -1,106 +0,0 @@
-============
-Installation
-============
-
-There are a variety of ways to install RepoLib
-
-From System Package Manager
-^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-If your operating system packages repolib, you can install it by running::
-
- sudo apt install python3-repolib
-
-
-Uninstall
-"""""""""
-
-To uninstall, simply do::
-
- sudo apt remove python3-repolib
-
-
-From PyPI
-^^^^^^^^^
-
-Repolib is available on PyPI. You can install it for your current user with::
-
- pip3 install repolib
-
-Alternatively, you can install it system-wide using::
-
- sudo pip3 install repolib
-
-Uninstall
-"""""""""
-
-To uninstall, simply do::
-
- sudo pip3 uninstall repolib
-
-From Git
-^^^^^^^^
-
-First, clone the git repository onto your local system::
-
- git clone https://github.com/isantop/repolib
- cd repolib
-
-Debian
-^^^^^^
-
-On debian based distributions, you can build a .deb package locally and install
-it onto your system. You will need the following build-dependencies:
-
- * debhelper (>= 11)
- * dh-python
- * lsb-release
- * python3-all
- * python3-dbus
- * python3-debian
- * python3-setuptools
- * python3-distutils
- * python3-pytest
- * python3-gnupg
-
-You can use this command to install these all in one go::
-
- sudo apt install debhelper dh-python python3-all python3-setuptools python3-gnupg
-
-Then build and install the package::
-
- debuild -us -uc
- cd ..
- sudo dpkg -i python3-repolib_*.deb
-
-Uninstall
-"""""""""
-
-To uninstall, simply do::
-
- sudo apt remove python3-repolib
-
-setuptools setup.py
-^^^^^^^^^^^^^^^^^^^
-
-You can build and install the package using python3-setuptools. First, install
-the dependencies::
-
- sudo apt install python3-all python3-setuptools
-
-Then build and install the package::
-
- sudo python3 ./setup.py install
-
-Uninstall
-"""""""""
-
-You can uninstall RepoLib by removing the following files/directories:
-
- * /usr/local/lib/python3.7/dist-packages/repolib/
- * /usr/local/lib/python3.7/dist-packages/repolib-\*.egg-info
- * /usr/local/bin/apt-manage
-
-This command will remove all of these for you::
-
- sudo rm -r /usr/local/lib/python3.7/dist-packages/repolib* /usr/local/bin/apt-manage
diff --git a/archive/docs/library/developer.rst b/archive/docs/library/developer.rst
deleted file mode 100644
index b7ba6b7..0000000
--- a/archive/docs/library/developer.rst
+++ /dev/null
@@ -1,335 +0,0 @@
-.. _repolib_module:
-
-=======
-RepoLib
-=======
-
-The :ref:`repolib-module` module simplifies working with APT sources, especially
-those stored in the DEB822 format. It translates these sources into Python
-Objects for easy reading, parsing, and manipulation of them within Python
-programs. The program takes a user-defined sources filename and reads the
-contents, parsing it into a Python object which can then be iterated upon and
-which uses native data types where practicable. The :ref:`repolib-module` module
-also allows easy creation of new DEB822-style sources from user-supplied data.
-
-.. toctree::
- :maxdepth: 1
- :caption: RepoLib
-
- source/source
- ppa-module
- enums
-
-==================
-``repolib`` Module
-==================
-
-The ``repolib`` Module is the main module for the package. It allows interfacing
-with the various Classes, Subclasses, and Functions provided by RepoLib.
-
-Module-level Attributes
-=======================
-
-There are a couple of module-level attributes and functions provided directly in
-the module.
-
-.. _module-version
-
-``VERSION``
------------
-
-repolib.VERSION
- Provides the current version of the library.
-
-.. _module_log_file_path
-
-``LOG_FILE_PATH``
------------------
-
-repolib.LOG_FILE_PATH
- Stores the current path to the log file
-
-.. _module_log_level
-
-repolib.LOG_LEVEL
- Stores the current logging level. Note: Change this level using the
- :ref:`module_set_logging_level` function.
-
-.. _module_dirs
-
-Configuration directories
-=========================
-
-repolib.KEYS_DIR
-repolib.SOURCES_DIR
- Stores the current :obj:`Pathlib.Path` pointing at the signing key and
- sources directories, respectively. Used for building path names and reading
- configuration.
-
-.. _module_distro_codename:
-
-DISTRO_CODENAME
-===============
-
-repolib.DISTRO_CODENAME
- The current CODENAME field from LSB. If LSB is not available, it will
- default to ``linux``.
-
-
-.. _module_clean_chars
-
-CLEAN_CHARS
-===========
-
-repolib.CLEAN_CHARS
- A ``dict`` which maps invalid characters for the :ref:`ident` attributes
- which cannot be used and their replacements. These limitations are based on
- invalid characters in unix-compatible filenames.
-
-.. _module_sources
-
-sources
-=======
-
-repolib.sources
- A :obj:`dict` storing all current sources configured on the system. To save
- resources, this list is only loaded/parsed when
- :ref:`module_load_all_sources` is called, since many simple operations don't
- need the full list of currently-configured sources.
-
-.. _module_files
-
-files
-=====
-
-repolib.files
- A :obj:`dict` containing any source file objects present in the configured
- sources dir (See :ref:`module_dirs`). This list is empty until
- :ref:`module_load_all_sources` is called, since many simple operations don't
- need the full list of currently-installed config files.
-
-.. _module_keys
-
-keys
-====
-
-repolib.keys
- A :obj`dict` containing any installed repository signing keys on the system.
- This list is empty until :ref:`module_load_all_sources` is called, since
- many simple operations don'tneed the full list of
- currently-installed keys.
-
-.. _module_compare_sources
-
-compare_sources()
------------------
-
-repolib.compare_sources(source1, source2, excl_keys:list) -> bool
- Compares two sources based on arbitrary criteria.
-
- This looks at a given list of keys, and if the given keys between the two
- given sources are identical, returns True.
-
- Returns: :obj:`bool`
- `True` if the sources are identical, otherwise `False`.
-
-source1, source2
-^^^^^^^^^^^^^^^^
-The two source objects to compare.
-
-excl_keys
-^^^^^^^^^
-:obj:`list` A list of DEB822key names to ignore when comparing. Even if these
-items don't match, this function still returns true if all other keys match.
-
-.. _module_combine_sources
-
-combine_sources()
------------------
-
-repolib.combine_sources(source1, source2) -> None
- Copies all of the data in `source2` and adds it to `source1`.
-
- This avoids duplicating data and ensures that all of both sources' data are
- present in the unified source
-
-source1
-^^^^^^^
-The source into which both sources should be merged
-
-source2
-^^^^^^^
-The source from which to copy to `source1`
-
-
-.. _module_url_validator
-
-url_validator()
----------------
-
-repolib.url_validator(url: str) -> bool
- Validates a given URL and attempts to see if it's a valid Debian respository
- URL. Returns `True` if the URL appears to be valid and `False` if not.
-
-url
-^^^
-:obj:`str`The url to validate
-
-
-.. _module_validate_debline
-
-validate_debline()
-==================
-
-repolib.util.validate_debline(line: str) -> bool
- Validate if the provided debline ``line`` is valid or not.
-
- Returns ``True`` if ``line`` is valid, otherwise ``False``.
-
-line
-^^^^
-:obj:`str` The line to validate
-
-
-.. _module_strip_hashes
-
-strip_hashes()
---------------
-
-repolib.strip_hashes(line: str) -> str
- Strips leading hash (`#`) characters from a line and returns the result.
-
-line
-^^^^
-:obj:`str` The line to strip
-
-.. _module_load_all_sources
-
-load_all_sources()
-------------------
-
-repolib.load_all_sources() -> None
-
- Loads all sources from the current system configuration.
-
-
-.. _module-set_testing
-
-set_testing()
--------------
-
-repolib.set_testing(testing: bool = True) -> None
- Enables or disables testing mode in Repolib
-
- When in testing mode, repolib will operate within a temporary directory
- rather tan on your live system configuration. This can be used for testing
- out changes to the program without worry about changes to the system config.
- It's also used for unit testing.
-
-
-testing
-^^^^^^^
-:obj:`bool` - Wether testing mode should be enabled (`True`) or not (`False`)
-
-
-Example
-=======
-
-The following code as a Python program that creates in ``example.sources`` file
-in `/etc/apt/sources.list.d` with some sample data, then modifies the suites
-used by the source and prints it to the console, before finally saving the new,
-modified source to disk::
-
- import repolib
- source = repolib.Source()
- file = repolib.SourceFile(name='example')
-
- source.ident = 'example-source'
- source.name = 'Example Source'
- source.types = [repolib.SourceType.BINARY]
- source.uris = ['http://example.com/software']
- source.suites = ['focal']
- source.components = ['main']
- file.add_source(source)
-
- print(source.ui)
-
- file.save()
-
-When run with the appropriate arguments, it prints the contents of the source to
-console and then saves a new ``example.sources`` file::
-
- $
- example-source:
- Name: Example Source
- Enabled: yes
- Types: deb
- URIs: http://example.com/software
- Suites: focal
- Components: main
-
- $ ls -la /etc/apt/sources.list.d/example.sources
- -rw-r--r-- 1 root root 159 May 1 15:21 /etc/apt/sources.list.d/example.sources
-
-Below is a walkthrough of this example.
-
-Creating Source and File Objects
---------------------------------
-
-The first step in using :ref:`repolib_module` is creating :ref:`source_object`
-and :ref:`file_object`::
-
- source = repolib.Source()
- file = repolib.SourceFile(name='example')
-
-The :ref:`source_object` will hold all of the information for the source to be
-created. The :ref:`file_object` represents the output file on disk, and allows
-for advanced usage like multiple sources per file.
-
-Adding and Manipulating Data
-----------------------------
-
-The :ref:`source_object` contains attributes which describe the connfiguration
-aspects of the source required to fetch and install software. Generally, these
-attributes are lists of strings which describe different aspects of the source.
-They can be set or retrieved like any other attributes::
-
- source.uris = ['http://example.com/software']
- source.suites = ['focal']
-
-This will add a ``focal`` suite to our source and add a URI from which to
-download package lists.
-
-:ref:`source_object` also presents a dict-like interface for setting and getting
-configuration data. Key names are case-insensitive and their order within the
-object are preserved.
-
-Adding the Source to the File
------------------------------
-
-Before the :ref:`source_object` can be saved, it needs to be added to a
-:ref:`file_object`::
-
- file.add_source(source)
-
-This will add `source` to the `file`'s lists of sources, as well as setting the
-`source`'s file attribute to `file`.
-
-Saving Data to Disk
--------------------
-
-Once a source has the correct data and has been added to a file object, it can
-be saved into the system configuration using :ref:`file-save`::
-
- file.save()
-
-When called, this writes the sources stored in the file to disk. This does not
-destroy the object, so that it may be further manipulated by the program.
-
-.. note::
- While data within the source or file objects can be manipulated after
- calling :ref:`file-save`, any subsequent changes will not be automatically
- written to disk as well. The :ref:`file-save` method must be called to
- commit changes to disk.
-
-.. _source_object:
diff --git a/archive/docs/library/enums.rst b/archive/docs/library/enums.rst
deleted file mode 100644
index b83031a..0000000
--- a/archive/docs/library/enums.rst
+++ /dev/null
@@ -1,45 +0,0 @@
-.. _repolib-enums:
-
-=============
-RepoLib Enums
-=============
-
-RepoLib uses a variety of Enums to help ensure that data values are consistent
-when they need to be set to specific string values for compatibility.
-
-.. _enum_sourceformat
-
-SourceFormat
-============
-
-repolib.SourceFormat()
- Encodes the two formats of source files, either ``.list`` for legacy format
- files or ``.sources`` for DEB822-formatted files.
-
- * ``DEFAULT`` - DEB822 formatting (value: ``"sources"``)
- * ``LEGACY`` - Legacy, one-line formatting (value: ``"list"``)
-
-
-.. _enum_sourcetype
-
-SourceType
-==========
-
-repolib.SourceType()
- Encodes the type of packages the repository provides (binary or source code).
-
- * ``BINARY`` - Binary package source type (value: ``"deb"``)
- * ``SOURCECODE`` - Source code package type (value : ``"deb-src"``)
-
-
-.. _enum_aptsourceenabled:
-
-AptSourceEnabled
-================
-
-repolib.AptSourceEnabled()
- Used to encode whether the source is enabled or not.
-
- * ``TRUE`` - The source should be enabled (value: ``"yes"``).
- * ``FALSE`` - The source should not be enabled (value: ``"no"``).
-
\ No newline at end of file
diff --git a/archive/docs/library/source/exceptions.rst b/archive/docs/library/source/exceptions.rst
deleted file mode 100644
index bf5ddce..0000000
--- a/archive/docs/library/source/exceptions.rst
+++ /dev/null
@@ -1,50 +0,0 @@
-.. _exceptions
-
-==========
-Exceptions
-==========
-
-RepoLib throws various forms of exceptions to halt execution of code when
-incorrect input is detected or deviations from expected norms are encountered.
-
-.. _exc_repoerror
-
-RepoError()
------------
-
-Repolib.RepoError()
- This is base exception thrown by RepoLib. All other exceptions are
- subclasses of this exception type.
-
-.. _exc_sourceerror
-
-SourceError()
--------------
-
-Repolib.Source.SourceError()
- Raised when errors result from processing within the :obj:`source_object` or
- one of it's subclasses.
-
-.. _exc_debparseerror
-
-DebParseError()
----------------
-
-Repolib.parsedeb.DebParseError()
- Raised due to problems parsing legacy Debian one-line repository lines.
-
-.. _exc_sourcefileerror
-
-SourceFileError()
------------------
-
-Repolib.file.SourceFileError()
- Raised due to errors handling :ref:`file_object` objects.
-
-.. _exc_keyfileerror
-
-KeyFileError()
---------------
-
-Repolib.key.KeyFileError()
- Raised due to errors loading/finding key files or :ref:`key_object` objects.
diff --git a/archive/docs/library/source/file.rst b/archive/docs/library/source/file.rst
deleted file mode 100644
index c4f6f9f..0000000
--- a/archive/docs/library/source/file.rst
+++ /dev/null
@@ -1,172 +0,0 @@
-.. _file_object:
-
-===========
-File object
-===========
-
-SourceFile objects are the interface between the OS storage and the repolib
-:ref:`source_object` items. Files contain sources and comments and allow for
-loading sources from and saving them to disk. They also assign idents to sources
-in a way that ensures each source has a unique ident.
-
-Attributes
-==========
-
-File objects contain the following attributes:
-
-.. _file-name
-
-name
-----
-
-SourceFile.name
- The name of the file on disk. This does not include the file extension, as
- that is stored in :ref:`file-format`.
-
-.. _file-path
-
-path
-----
-
-SourceFile.path
- A ``Pathlib.Path`` object representing this file's actual path on disk. Note
- that the file may not actually exist on disk yet.
-
-.. _file-format
-
-format
-------
-
-SourceFile.format
- The format this file should be saved in. Saved as a :ref:`enum_sourceformat`.
-
-.. _file-contents
-
-contents
---------
-
-SourceFile.contents
- A :obj:`list` containing, in order, every comment line and source in this
- file.
-
-.. _file-sources
-
-sources
--------
-
-SourceFile.sources
- A :obj:`list` containing, in order, only the sources in this file.
-
-
-Methods
-=======
-
-.. _file-add_source
-
-add_source()
-------------
-
-SourceFile.add_source(source) -> None
- Adds a given source to the file. This correctly appends the source to both
- the :ref:`file-contents` and :ref:`file-sources` lists, and sets the
- :ref:`source-file` attribute of the source to this file.
-
-source
-^^^^^^
-The source to add to the file.
-
-.. _file-remove_source
-
-remove_source()
----------------
-
-SourceFile.remove_source(ident: str) -> None
- Removes the source with a specified ident from this file.
-
-ident
-^^^^^
-The ident of the source to remove from the file.
-
-.. _file-get_source_by_ident
-
-get_source_by_ident()
----------------------
-
-SourceFile.get_source_by_ident(ident: str) -> :obj:`Source`
- Finds a source within this file given a specified ident and returns the
- :ref:`source_object` matching that ident. If the file does not contain a
- Source matching the given ident, raises a :ref:`exc_sourcefileerror`.
-
-ident
-^^^^^
-The ident to look up.
-
-.. _file-reset_path
-
-SourceFile.reset_path() -> None
- Attempts to detect the full path to the file given the :ref:`file-name`
- attribute for this file. If the ``name.sources`` exists on disk, the path
- will be set to that, otherwise if the ``name.list`` exists, it will be set
- to that instead. Failing both, the path will fallback to ``name.sources`` as
- a default.
-
-.. _file-load
-
-load()
-------
-
-SourceFile.load() -> None
- Loads the file specified by :ref:`path` from disk, creating sources and
- comments and appending them in order to the :ref:`file-contents` and
- :ref:`file-sources` lists as appropriate.
-
-.. _file-save
-
-save()
-------
-
-SourceFile.save() -> None
- Saves the file and any sources currently configured to disk. This method
- must be called to commit changes to disk. If the file currently contains no
- sources, then the file will instead be deleted.
-
-
-Output
-======
-
-There are four attributes which contain the output of the files stored as
-strings and which are ready for full output in the specified format.
-
-.. _file-deb822
-
-deb822
-------
-
-SourceFile.deb822
- Outputs the entire file as DEB822-formatted sources
-
-.. _file-legacy
-
-legacy
-------
-
-SourceFile.legacy
- Outputs the entire file as one-line legacy-formatted deb lines
-
-.. _file-ui
-
-ui
---
-
-SourceFile.ui
- Outputs the file in a format for output through a UI (e.g. for preview or
- external parsing.)
-
-.. _file-output
-
-output
-------
-
-SourceFile.output
- Outputs the entire file in the format matching that configured in
- :ref:`file-format`.
diff --git a/archive/docs/library/source/key.rst b/archive/docs/library/source/key.rst
deleted file mode 100644
index 684f71a..0000000
--- a/archive/docs/library/source/key.rst
+++ /dev/null
@@ -1,121 +0,0 @@
-.. _key_object:
-
-==========
-Key object
-==========
-
-The SourceKey object is the representation for signing keys used to validate
-software packages downloaded from repositories.
-
-
-Attributes
-==========
-
-.. _key-path
-
-path
-----
-
-SourceKey.path
- A :obj:`Pathlib.Path` object pointing to this key's file location on disk.
-
-.. _key-gpg
-
-gpg
----
-
-SourceKey.gpg
- A :obj:`gnupg.GPG` object used for importing and manipulating GPG data.
-
-.. _key-data
-
-data
-----
-
-SourceKey.data
- The binary data stored in this key, used to verify package signatures.
-
-
-Methods
-=======
-
-.. _key-reset_path
-
-reset_path()
-------------
-
-SourceKey.reset_path(name:str='', path:str='', suffix:str='archive-keyring') -> None
- (Re)sets the path object for this key to the key file specified. If a ``name``
- is given, then the file is expected to be located within the system default
- signing key directory ``/etc/apt/keyrings``. If a ``path`` is spefified,
- then it is assumed to be the full path to the keyring file on disk.
-
-name
-^^^^
-The name of a keyring file located within the system signing key directory, less
-any suffix or file extensions.
-
-path
-^^^^
-The absolute path to a keyring file located at any readable location on disk.
-
-suffix
-^^^^^^
-A suffix to append to the file name before the file extension. (Default:
-``'archive-keyring'``)
-
-.. _key-setup_gpg
-
-setup_gpg()
------------
-
-SourceKey.setup_gpg() -> None
- Sets up the :ref:`key-gpg` object for this key and loads key data from disk
- (if present).
-
-.. _key-save_gpg
-
-save_gpg()
-----------
-
-SourceKey.save_gpg() -> None
- Saves the GPG key data to disk.
-
-.. _key-delete_key
-
-delete_key()
-------------
-
-SourceKey.delete_key() -> None
- Deletes the key file from disk.
-
-.. _key-load_key_data
-
-load_key_data()
----------------
-
-SourceKey.load_key_data(raw=|ascii=|url=|fingerprint=) -> None
- Fetches and loads a key from some remote source. Keys can be loaded from one
- of:
- * Raw internal data (:obj:`bytes`)
- * ASCII-armored keys (:obj:`str`)
- * Internet URL download (:obj:`str`)
- * Public GPG Keyserver Fingerprint (:obj:`str`)
-
-raw=data (:obj:`bytes`)
-^^^^^^^^^^^^^^^^^^^^^^^
-Load a key from raw binary data. This is ideal when importing a key which has
-already been loaded from a binary data file or stream.
-
-ascii=armor (:obj:`str`)
-^^^^^^^^^^^^^^^^^^^^^^^^
-Load a key from an ASCII-Armored string.
-
-url=url (:obj:`str`)
-^^^^^^^^^^^^^^^^^^^^
-Download a key over an HTTPS connection. Note that keys should only be downloaded
-from secure sources.
-
-fingerprint=fingerprint (:obj:`str`)
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-Fetch the key specified by ``fingerprint`` from a public keyserver.
diff --git a/archive/docs/library/source/shortcuts.rst b/archive/docs/library/source/shortcuts.rst
deleted file mode 100644
index 9ba697c..0000000
--- a/archive/docs/library/source/shortcuts.rst
+++ /dev/null
@@ -1,56 +0,0 @@
-.. _shortcuts
-
-====================
-Repository Shortcuts
-====================
-
-Repolib supports adding repositories via abbreviated shortcuts (such as
-``ppa:system76/pop`` or ``popdev:master``) where the format of the shortcut is
-given in the form of a prefix, and the data required to expand the shortcut into
-a full repository is provided, with a colon character separating the two parts.
-These function as subclasses of the :ref:`source_object` with specialized
-functionality. Currently there is support for Launchpad PPAs and Pop_OS
-Development branches automatically.
-
-
-Launchpad PPAs
-==============
-
-repolib.PPASource()
- RepoLib has built-in support for adding Launchpad PPA shortcuts, similarly to
- ``add-apt-repository``. Launchpad shortcuts take the general form::
-
- ppa:owner-name/ppa-name
-
- If an internet connection is available, RepoLib can automatically fetch the
- repository signing key as well as metadata like the description, human-readable
- name, etc.
-
-
-Pop_OS Development Branches
-===========================
-
-repolib.PopdevSource()
- RepoLib can automatically add Pop_OS development branches for testing unstable
- pre-release software before it is ready for general use. Development branch
- shortcuts take the form::
-
- popdev:branch-name
-
- If an internet connection is available, then RepoLib will also add the signing
- key for the branch (if it is not already added).
-
-
-
-Adding Shortcut Repositories
-============================
-
-Shortcuts are generally added similarly to loading a different source from data,
-the main difference being that in the call to :ref:`load_from_data` the only
-element in the ``data`` list should be a string of the shortcut::
-
- ppa_source = repolib.PPASource()
- ppa_source.load_from_data(['ppa:system76/pop'])
-
- popdev_source = repolib.PopdevSource()
- popdev_source.load_from_data(['popdev:master'])
\ No newline at end of file
diff --git a/archive/docs/library/source/source.rst b/archive/docs/library/source/source.rst
deleted file mode 100644
index bf6b3fe..0000000
--- a/archive/docs/library/source/source.rst
+++ /dev/null
@@ -1,281 +0,0 @@
-.. _source_object:
-
-=============
-Source object
-=============
-
-The Source object is the base class for all of the sources used within RepoLib.
-The Source class itself is a subclass of the deb822() class from the Python
-Debian module, which provides a dict-like interface for setting data as well as
-several methods for dumping data to files and other helpful functions.
-
-.. toctree::
- :maxdepth: 2
- :caption: Source
-
- deb
- legacy-deb
- ppa-object
- system
-
-class repolib.Source (file=None)
- Create a new :ref:`source_object`.
-
-
- The Source object has the following attributes:
-
- * :ref:`ident` - The system-identifier to use for this source.
- * :ref:`name` - The human-readable name of the source. (default: '')
- * :ref:`enabled` - Whether the source is enabled or not at creation.
- (default: True)
- * :ref:`types` - A list of the types that the source should use.
- (default: [])
- * :ref:`uris` - A list of URIs from which to fetch software or check for
- updates. (default: [])
- * :ref:`suites` - Suites in which to narrow available software. (default:
- [])
- * :ref:`components` - Components of the source repository to enable.
- (default: [])
- * :ref:`signed_by` - The path to the signing key for this source
- * :ref:`file` - The :ref:`file_object` for this source
- * :ref:`key` - The :ref:`key_object` for this source.
- * :ref:`twin_source`: - This source should be saved with both binary and
- source code types enabled.
-
-The following decribe how each of these are used.
-
-.. _ident:
-
-ident
------
-
-The ``ident`` is the system-identifier for this source. This determines the
-filename the source will use on-disk as well as the way to specify a source to
-load.
-
-.. _name:
-
-name
-----
-
-This is a human-readable and nicely-formatted name to help a user recognize
-what this source is. Any unicode character is allowed in this field. If a
-source is opened which doesn't have a name field, the filename will be used.
-
-:ref:`name` is a string value, set to ``''`` by default. If there is no name in
-a loaded source, it will be set to the same as the filename (minus the
-extension).
-
-This field maps to the ``X-Repolib-Name:`` field in the .sources file, which
-is ignored by Apt and other standards-compliant sources parsers.
-
-.. _enabled:
-
-enabled
--------
-
-Apt sources can be disbaled without removing them entirely from the system. A
-disabled source is excluded from updates and new software installs, but it can
-be easily re-enabled at any time. It defaults to ``True``.
-
-This field maps to the ``Enabled:`` field in the .sources file. This is optional
-per the DEB822 standard, however if set to anything other than ``no``, the
-source is considered enabled.
-
-.. _types:
-
-types
------
-
-Debian archives may contain either binary packages or source code packages, and
-this value specifies which of those Apt should look for in the source. ``deb``
-is used to look for binary packages, while ``deb-src`` looks for source code
-packages. RepoLib stores this value as a list of :ref:`aptsourcetype-enum`s, and
-defaults to ``[AptSourceType.BINARY]``.
-
-This field maps to the ``Types:`` field in the sources file.
-
-.. _uris:
-
-uris
-----
-
-A list of string values describing the URIs from which to fetch package lists
-and software for updates and installs. The currently recognized URI types are:
-
- * file
- * cdrom
- * http
- * ftp
- * copy
- * rsh
- * ssh
-
-DEB822 sources may directly contain an arbitrary number of URIs. Legacy sources
-may also have multiple URIs; however, these require writing a new deb line for
-each URI as the one-line format only allows a single URI per source.
-
-.. note::
- Although these are the currently-recognized official URI types, Apt can be
- extended with additional URI schemes through extension packages. Thus it is
- **not** recommended to parse URIs by type and instead rely on user input
- being correct and to throw exceptions when that isn't the case.
-
-.. _suites:
-
-suites
-------
-
-The Suite, also known as the **distribution** specifies a subdirectory of the
-main archive root in which to look for software. This is typically used to
-differentiate versions for the same OS, e.g. ``disco`` or ``cosmic`` for Ubuntu,
-or ``squeeze`` and ``unstable`` for Debian.
-
-DEB822 Sources allow specifying an arbitrary number of suites. One-line sources
-also support multiple suites, but require an additional repo line for each as
-the one-line format only allows a single suite for each source.
-
-This value maps to the ``Suites:`` field in the sources file.
-
-.. _components:
-
-components
-----------
-
-This value is a list of strings describing the enabled distro components to
-download software from. Common values include ``main``, ``restricted``,
-``nonfree``, etc.
-
-.. _signed_by
-
-signed_by
----------
-The path to the keyring containing the signing key used to verify packages
-downloaded from this repository. This should generally match the
-:ref:`key-path` attribute for this source's :ref:`key` object.
-
-.. _source-file
-
-file
-----
-The :ref:`file_object` for the file which contains this source.
-
-.. _key
-
-key
----
-The :ref:`key_object` for this source.
-
-=======
-Methods
-=======
-
-
-.. _get_description
-
-Source.get_description() -> str
- Returns a :obj:`str` containing a UI-compatible description of the source.
-
-.. _reset_values:
-
-reset_values()
--------------
-
-Source.reset_values()
- Initializes the Source's attributes with default data in-order. This is
- recommended to ensure that the fields in the underlying deb822 Dict are
- in order and correctly capitalized.
-
-.. _load_from_data
-
-load_from_data()
-----------------
-
-Source.load_from_data(data: list) -> None
- Loads configuration information from a list of data, rather than using
- manual entry. The data can either be a list of strings with DEB822 data, or
- a single-element list containing a one-line legacy line.
-
-data
-^^^^
-The data load load into the source. If this contains a legacy-format one-line
-repository, it must be a single-element list. Otherwise, it should contain a
-list of strings, each being a line from a DEB822 configuration.
-
-.. _generate_default_ident
-
-generate_default_ident()
-------------------------
-
-Source.generate_default_ident(prefix: str = '') -> str
- Generates a suitable default ident, optionally with a prefix, and sets it.
- The generated ident is also returned for processing convenience.
-
-prefix
-^^^^^^
-The prefix to prepend to the ident.
-
-.. _generate_default_name
-
-generate_default_name()
-_______________________
-
-Source.generate_default_name() ->
- Generates a default name for the source and sets it. The generated name is
- also returned for convenience.
-
-.. _load_key
-
-load_key()
-__________
-
-Source.load_key(ignore_errors: bool = True) -> None
- Finds the signing key for this source spefified in :ref:`signed_by` and
- loads a :ref:`key_object` for it.
-
-ignore_errors
-^^^^^^^^^^^^^
-If `False`, raise a :ref:`exc_sourceerror` if the key can't be loaded or doesn't
-exist.
-
-.. _source_save
-
-save()
-------
-
-Source.save()
- Proxy method for the :ref:`file-save` method for this source's
- :ref:`file_object`.
-
-Output Properties
-=================
-
-There are three output properties which contain the current source data for
-output in a variety of formats.
-
-.. _source_deb822
-
-deb822
-------
-
-Source.deb822
- A representation of the source data as a DEB822-formatted string
-
-.. _source_legacy
-
-legacy
-------
-
-Source.legacy
- A one-line formatted string of the source. It :ref:`twin_source` is ``True``,
- then there will additionally be a ``deb-src`` line following the primary
- line.
-
-.. _source_ui
-
-ui
---
-
-Source.ui
- A representation of the source with certain key names translated to better
- represent their use in a UI for display to a user.
diff --git a/archive/repolib/__init__.py b/archive/repolib/__init__.py
deleted file mode 100644
index 4b4b7e5..0000000
--- a/archive/repolib/__init__.py
+++ /dev/null
@@ -1,144 +0,0 @@
-#!/usr/bin/python3
-
-"""
-Copyright (c) 2019-2022, Ian Santopietro
-All rights reserved.
-
-This file is part of RepoLib.
-
-RepoLib is free software: you can redistribute it and/or modify
-it under the terms of the GNU Lesser General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-RepoLib 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 Lesser General Public License for more details.
-
-You should have received a copy of the GNU Lesser General Public License
-along with RepoLib. If not, see .
-"""
-
-import logging
-import logging.handlers as handlers
-
-from pathlib import Path
-
-from . import __version__
-
-VERSION = __version__.__version__
-
-from .file import SourceFile, SourceFileError
-from .source import Source, SourceError
-from .shortcuts import PPASource, PopdevSource, shortcut_prefixes
-from .key import SourceKey, KeyFileError
-from . import util
-from . import system
-
-LOG_FILE_PATH = '/var/log/repolib.log'
-LOG_LEVEL = logging.WARNING
-KEYS_DIR = util.KEYS_DIR
-SOURCES_DIR = util.SOURCES_DIR
-TESTING = util.TESTING
-KEYSERVER_QUERY_URL = util.KEYSERVER_QUERY_URL
-DISTRO_CODENAME = util.DISTRO_CODENAME
-PRETTY_PRINT = util.PRETTY_PRINT
-CLEAN_CHARS = util.CLEAN_CHARS
-
-try:
- from systemd.journal import JournalHandler
- systemd_support = True
-except ImportError:
- systemd_support = False
-
-## Setup logging
-stream_fmt = logging.Formatter(
- '%(name)-21s: %(levelname)-8s %(message)s'
-)
-file_fmt = logging.Formatter(
- '%(asctime)s - %(name)-21s: %(levelname)-8s %(message)s'
-)
-log = logging.getLogger(__name__)
-
-console_log = logging.StreamHandler()
-console_log.setFormatter(stream_fmt)
-console_log.setLevel(LOG_LEVEL)
-
-# file_log = handlers.RotatingFileHandler(
-# LOG_FILE_PATH, maxBytes=(1048576*5), backupCount=5
-# )
-# file_log.setFormatter(file_fmt)
-# file_log.setLevel(LOG_LEVEL)
-
-log.addHandler(console_log)
-# log.addHandler(file_log)
-
-log_level_map:dict = {
- 0: logging.WARNING,
- 1: logging.INFO,
- 2: logging.DEBUG
-}
-
-if systemd_support:
- journald_log = JournalHandler() # type: ignore (this is handled by the wrapping if)
- journald_log.setLevel(logging.INFO)
- journald_log.setFormatter(stream_fmt)
- log.addHandler(journald_log)
-
-log.setLevel(logging.DEBUG)
-
-def set_testing(testing:bool = True) -> None:
- """Puts Repolib into testing mode"""
- global KEYS_DIR
- global SOURCES_DIR
-
- util.set_testing(testing=testing)
- KEYS_DIR = util.KEYS_DIR
- SOURCES_DIR = util.SOURCES_DIR
-
-
-def set_logging_level(level:int) -> None:
- """Set the logging level for this current repolib
-
- Accepts an integer between 0 and 2, with 0 being the default loglevel of
- logging.WARNING, 1 being logging.INFO, and 2 being logging.DEBUG.
-
- Values greater than 2 are clamped to 2. Values less than 0 are clamped to 0.
-
- Note: This only affects console output. Log file output remains
- at logging.INFO
-
- Arguments:
- level(int): A logging level from 0-2
- """
- if level > 2:
- level = 2
- if level < 0:
- level = 0
- LOG_LEVEL = log_level_map[level]
- console_log.setLevel(LOG_LEVEL)
-
-RepoError = util.RepoError
-SourceFormat = util.SourceFormat
-SourceType = util.SourceType
-AptSourceEnabled = util.AptSourceEnabled
-
-scrub_filename = util.scrub_filename
-url_validator = util.url_validator
-prettyprint_enable = util.prettyprint_enable
-validate_debline = util.validate_debline
-strip_hashes = util.strip_hashes
-compare_sources = util.compare_sources
-combine_sources = util.combine_sources
-sources = util.sources
-files = util.files
-keys = util.keys
-errors = util.errors
-
-valid_keys = util.valid_keys
-options_inmap = util.options_inmap
-options_outmap = util.options_outmap
-true_values = util.true_values
-
-load_all_sources = system.load_all_sources
diff --git a/archive/repolib/__version__.py b/archive/repolib/__version__.py
deleted file mode 100644
index f28f7ec..0000000
--- a/archive/repolib/__version__.py
+++ /dev/null
@@ -1,22 +0,0 @@
-#!/usr/bin/python3
-
-"""
-Copyright (c) 2019-2022, Ian Santopietro
-All rights reserved.
-
-This file is part of RepoLib.
-
-RepoLib is free software: you can redistribute it and/or modify
-it under the terms of the GNU Lesser General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-RepoLib 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 Lesser General Public License for more details.
-
-You should have received a copy of the GNU Lesser General Public License
-along with RepoLib. If not, see .
-"""
-__version__ = "2.1.1"
diff --git a/archive/repolib/command/__init__.py b/archive/repolib/command/__init__.py
deleted file mode 100644
index 86f8e6c..0000000
--- a/archive/repolib/command/__init__.py
+++ /dev/null
@@ -1,30 +0,0 @@
-#!/usr/bin/python3
-
-"""
-Copyright (c) 2022, Ian Santopietro
-All rights reserved.
-
-This file is part of RepoLib.
-
-RepoLib is free software: you can redistribute it and/or modify
-it under the terms of the GNU Lesser General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-RepoLib 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 Lesser General Public License for more details.
-
-You should have received a copy of the GNU Lesser General Public License
-along with RepoLib. If not, see .
-"""
-
-from .argparser import get_argparser
-from .add import Add
-from .list import List
-from .remove import Remove
-from .modify import Modify
-from .key import Key
-
-parser = get_argparser()
diff --git a/archive/repolib/command/add.py b/archive/repolib/command/add.py
deleted file mode 100644
index 5ba3f14..0000000
--- a/archive/repolib/command/add.py
+++ /dev/null
@@ -1,267 +0,0 @@
-#!/usr/bin/python3
-
-"""
-Copyright (c) 2022, Ian Santopietro
-All rights reserved.
-
-This file is part of RepoLib.
-
-RepoLib is free software: you can redistribute it and/or modify
-it under the terms of the GNU Lesser General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-RepoLib 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 Lesser General Public License for more details.
-
-You should have received a copy of the GNU Lesser General Public License
-along with RepoLib. If not, see .
-"""
-
-from httplib2.error import ServerNotFoundError
-from urllib.error import URLError
-
-from .. import util
-from ..source import Source, SourceError
-from ..file import SourceFile, SourceFileError
-from ..shortcuts import ppa, popdev, shortcut_prefixes
-from .command import Command, RepolibCommandError
-
-class Add(Command):
- """Add subcommand
-
- Adds a new source into the system. Requests root, if not present.
-
- Options:
- --disable, d
- --source-code, -s
- --terse, -t
- --name, -n
- --identifier, -i
- --format, -f
- --skip-keys, -k
- """
-
- @classmethod
- def init_options(cls, subparsers):
- """ Sets up the argument parser for this command.
-
- Returns: argparse.subparser
- The subparser for this command
- """
-
- sub = subparsers.add_parser(
- 'add',
- help='Add a new repository to the system'
- )
-
- sub.add_argument(
- 'deb_line',
- nargs='*',
- default=['822styledeb'],
- help='The deb line of the repository to add'
- )
- sub.add_argument(
- '-d',
- '--disable',
- action='store_true',
- help='Add the repository and then set it to disabled.'
- )
- sub.add_argument(
- '-s',
- '--source-code',
- action='store_true',
- help='Also enable source code packages for the repository.'
- )
- sub.add_argument(
- '-t',
- '--terse',
- action='store_true',
- help='Do not display expanded info about a repository before adding it.'
- )
- sub.add_argument(
- '-n',
- '--name',
- default='',
- help='A name to set for the new repo'
- )
- sub.add_argument(
- '-i',
- '--identifier',
- default='',
- help='The filename to use for the new source'
- )
- sub.add_argument(
- '-f',
- '--format',
- default='sources',
- help='The source format to save as, `sources` or `list`'
- )
- sub.add_argument(
- '-k',
- '--skip-keys',
- action='store_true',
- help='Skip adding signing keys (not recommended!)'
- )
-
- return sub
-
- def finalize_options(self, args):
- super().finalize_options(args)
- self.deb_line = ' '.join(args.deb_line)
- self.terse = args.terse
- self.source_code = args.source_code
- self.disable = args.disable
- self.log.debug(args)
-
- try:
- name = args.name.split()
- except AttributeError:
- name = args.name
-
- try:
- ident = args.identifier.split()
- except AttributeError:
- ident = args.identifier
-
- self.name = ' '.join(name)
- pre_ident:str = '-'.join(ident)
- self.ident = util.scrub_filename(pre_ident)
- self.skip_keys = args.skip_keys
- self.format = args.format.lower()
-
- def run(self) -> bool:
- """Run the command, return `True` if successful; otherwise `False`"""
- if self.deb_line == '822styledeb':
- self.parser.print_usage()
- self.log.error('A repository is required')
- return False
-
- repo_is_url = self.deb_line.startswith('http')
- repo_is_nospaced = len(self.deb_line.split()) == 1
-
- if repo_is_url and repo_is_nospaced:
- self.deb_line = f'deb {self.deb_line} {util.DISTRO_CODENAME} main'
-
- print('Fetching repository information...')
-
- self.log.debug('Adding line %s', self.deb_line)
-
- new_source: Source = Source()
-
- for prefix in shortcut_prefixes:
- self.log.debug('Trying prefix %s', prefix)
- if self.deb_line.startswith(prefix):
- self.log.debug('Line is prefix: %s', prefix)
- new_source = shortcut_prefixes[prefix]()
- if not new_source.validator(self.deb_line):
- self.log.error(
- 'The shortcut "%s" is malformed',
- self.deb_line
- )
-
- # Try and get a suggested correction for common errors
- try:
- if self.deb_line[len(prefix)] != ':':
- fixed_debline: str = self.deb_line.replace(
- self.deb_line[len(prefix)],
- ":",
- 1
- )
- print(f'Did you mean "{fixed_debline}"?')
- except IndexError:
- pass
- return False
-
- try:
- new_source.load_from_data([self.deb_line])
- except (URLError, ServerNotFoundError) as err:
- import traceback
- self.log.debug(
- 'Exception info: %s \n %s \n %s',
- type(err),
- ''.join(traceback.format_exception(err)),
- err.args
- )
- self.log.error(
- 'System is offline. A connection is required to add '
- 'PPA and Popdev sources.'
- )
- return False
- except Exception as err:
- import traceback
- self.log.debug(
- 'Exception info: %s \n %s \n %s',
- type(err),
- err.__traceback__,
- err
- )
- self.log.error('An error ocurred: %s', err)
- return False
- break
-
-
- if not new_source:
- self.log.error(
- f'Could not parse line "{self.deb_line}". Double-check the '
- 'spelling.'
- )
- valid_shortcuts: str = ''
- for shortcut in shortcut_prefixes:
- if shortcut.startswith('deb'):
- continue
- valid_shortcuts += f'{shortcut}, '
- valid_shortcuts = valid_shortcuts.strip(', ')
- print(f'Supported repository shortcuts:\n {valid_shortcuts}')
- return False
-
- new_source.twin_source = True
- new_source.sourcecode_enabled = self.source_code
-
- if self.name:
- new_source.name = self.name
- if self.ident:
- new_source.ident = self.ident
- if self.disable:
- new_source.enabled = False
-
- if not new_source.ident:
- new_source.ident = new_source.generate_default_ident()
-
- new_file = SourceFile(name=new_source.ident)
- new_file.format = new_source.default_format
- if self.format:
- self.log.info('Setting new source format to %s', self.format)
- for format in util.SourceFormat:
- if self.format == format.value:
- new_file.format = format
- self.log.debug('New source format set to %s', format.value)
-
- new_file.add_source(new_source)
- new_source.file = new_file
- self.log.debug('File format: %s', new_file.format)
- self.log.debug('File path: %s', new_file.path)
-
- self.log.debug('Sources in file %s:\n%s', new_file.path, new_file.sources)
-
- if not self.terse:
- print(
- 'Adding the following source: \n',
- new_source.get_description(),
- '\n\n',
- new_source.ui
- )
- try:
- input(
- 'Press ENTER to continue adding this source or Ctrl+C '
- 'to cancel'
- )
- except KeyboardInterrupt:
- # Handled here to avoid printing the exception to console
- exit(0)
-
- new_file.save()
- util.dbus_quit()
- return True
diff --git a/archive/repolib/command/argparser.py b/archive/repolib/command/argparser.py
deleted file mode 100644
index 182ccd7..0000000
--- a/archive/repolib/command/argparser.py
+++ /dev/null
@@ -1,65 +0,0 @@
-#!/usr/bin/python3
-
-"""
-Copyright (c) 2020, Ian Santopietro
-All rights reserved.
-
-This file is part of RepoLib.
-
-RepoLib is free software: you can redistribute it and/or modify
-it under the terms of the GNU Lesser General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-RepoLib 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 Lesser General Public License for more details.
-
-You should have received a copy of the GNU Lesser General Public License
-along with RepoLib. If not, see .
-
-Module for getting an argparser. Used by apt-manage
-"""
-
-import argparse
-import inspect
-
-from repolib import command as cmd
-
-from .. import __version__
-
-def get_argparser():
- """ Get an argument parser with our arguments.
-
- Returns:
- An argparse.ArgumentParser.
- """
- parser = argparse.ArgumentParser(
- prog='apt-manage',
- description='Manage software sources and repositories',
- epilog='apt-manage version: {}'.format(__version__.__version__)
- )
-
- parser.add_argument(
- '-b',
- '--debug',
- action='count',
- help=argparse.SUPPRESS
- )
-
- subparsers = parser.add_subparsers(
- help='...',
- dest='action',
- metavar='COMMAND'
- )
-
- subcommands = []
- for i in inspect.getmembers(cmd, inspect.isclass):
- obj = getattr(cmd, i[0])
- subcommands.append(obj)
-
- for i in subcommands:
- i.init_options(subparsers)
-
- return parser
diff --git a/archive/repolib/command/command.py b/archive/repolib/command/command.py
deleted file mode 100644
index b4afa41..0000000
--- a/archive/repolib/command/command.py
+++ /dev/null
@@ -1,77 +0,0 @@
-"""
-Copyright (c) 2020, Ian Santopietro
-All rights reserved.
-
-This file is part of RepoLib.
-
-RepoLib is free software: you can redistribute it and/or modify
-it under the terms of the GNU Lesser General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-RepoLib 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 Lesser General Public License for more details.
-
-You should have received a copy of the GNU Lesser General Public License
-along with RepoLib. If not, see .
-
-Command line application helper class.
-"""
-
-from ..util import SOURCES_DIR
-
-class RepolibCommandError(Exception):
- """ Exceptions generated by Repolib CLIs."""
-
- def __init__(self, *args, code=1, **kwargs):
- """Exception from a CLI
-
- Arguments:
- code (:obj:`int`, optional, default=1): Exception error code.
- """
- super().__init__(*args, **kwargs)
- self.code = code
-
-class Command:
- # pylint: disable=no-self-use,too-few-public-methods
- # This is a base class for other things to inherit and give other programs
- # a standardized interface for interacting with commands.
- """ CLI helper class for developing command line applications."""
-
- def __init__(self, log, args, parser):
- self.log = log
- self.parser = parser
- self.sources_dir = SOURCES_DIR
- self.finalize_options(args)
-
- def finalize_options(self, args):
- """ Base options parsing class.
-
- Use this class in commands to set up the final options parsing and set
- instance variables for later use.
- """
- self.verbose = False
- self.debug = False
- if args.debug:
- if args.debug > 1:
- self.verbose = True
- if args.debug != 0:
- self.log.info('Debug mode set, not-saving any changes.')
- self.debug = True
-
- def run(self):
- """ The initial base for running the command.
-
- This needs to have a standardized format, argument list, and return
- either True or False depending on whether the command was successful or
- not.
-
- Returns:
- True if the command succeeded, otherwise False.
- """
-
- # Since this is just the base, it should always return True (because
- # you shouldn't fail at doing nothing).
- return True
diff --git a/archive/repolib/command/key.py b/archive/repolib/command/key.py
deleted file mode 100644
index f73c5b2..0000000
--- a/archive/repolib/command/key.py
+++ /dev/null
@@ -1,325 +0,0 @@
-#!/usr/bin/python3
-
-"""
-Copyright (c) 2022, Ian Santopietro
-All rights reserved.
-
-This file is part of RepoLib.
-
-RepoLib is free software: you can redistribute it and/or modify
-it under the terms of the GNU Lesser General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-RepoLib 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 Lesser General Public License for more details.
-
-You should have received a copy of the GNU Lesser General Public License
-along with RepoLib. If not, see .
-"""
-
-from pathlib import Path
-
-from ..key import SourceKey
-from .. import system, util
-
-from .command import Command
-
-KEYS_PATH = Path(util.KEYS_DIR)
-
-class Key(Command):
- """Key subcommand.
-
- Manages signing keys for repositories, allowing adding, removal, and
- fetching of remote keys.
-
- Options:
- --name, -n
- --path, -p
- --url, -u
- --ascii, -a
- --fingerprint, -f
- --keyserver, -s
- --remove, -r
- """
-
- @classmethod
- def init_options(cls, subparsers) -> None:
- """Sets up this command's options parser"""
-
- sub = subparsers.add_parser(
- 'key',
- help='Manage repository signing keys',
- epilog=(
- 'Note that no verification of key validity is performed when '
- 'managing key using apt-mange. Ensure that keys are valid to '
- 'avoid errors with updates.'
- )
- )
-
- sub.add_argument(
- 'repository',
- default=['x-repolib-none'],
- help='Which repository to manage keys for.'
- )
-
- sub_group = sub.add_mutually_exclusive_group(
- required=True
- )
-
- sub_group.add_argument(
- '-n',
- '--name',
- help='The name of an existing key file to set.'
- )
-
- sub_group.add_argument(
- '-p',
- '--path',
- help='Sets a path on disk to a signing key.'
- )
-
- sub_group.add_argument(
- '-u',
- '--url',
- help='Download a key over HTTPS'
- )
-
- sub_group.add_argument(
- '-a',
- '--ascii',
- help='Add an ascii-armored key'
- )
-
- sub_group.add_argument(
- '-f',
- '--fingerprint',
- help=(
- 'Fetch a key via fingerprint from a keyserver. Use --keyserver '
- 'to specify the URL to the keyserver.'
- )
- )
-
- sub_group.add_argument(
- '-r',
- '--remove',
- action='store_true',
- help=(
- 'Remove a signing key from the repo. If no other sources use '
- 'this key, its file will be deleted.'
- )
- )
-
- sub.add_argument(
- '-s',
- '--keyserver',
- help=(
- 'The keyserver from which to fetch the given fingerprint. '
- '(Default: keyserver.ubuntu.com)'
- )
- )
-
- def finalize_options(self, args):
- super().finalize_options(args)
- self.repo = args.repository
- self.keyserver = args.keyserver
-
- self.actions:dict = {}
- self.system_source = False
-
- for act in [
- 'name',
- 'path',
- 'url',
- 'ascii',
- 'fingerprint',
- 'remove',
- ]:
- self.actions[act] = getattr(args, act)
-
- system.load_all_sources()
-
- def run(self):
- """Run the command"""
- self.log.info('Modifying signing key settings for %s', self.repo)
-
- if not self.repo:
- self.log.error('No repository provided')
- return False
-
- try:
- self.source = util.sources[self.repo]
- if self.repo == 'system':
- self.system_source = True
- except KeyError:
- self.log.error(
- 'The repository %s was not found. Check the spelling',
- self.repo
- )
- return False
-
- self.log.debug('Actions to take:\n%s', self.actions)
- self.log.debug('Source before:\n%s', self.source)
-
- rets = []
- for action in self.actions:
- if self.actions[action]:
- self.log.debug('Running action: %s - (%s)', action, self.actions[action])
- ret = getattr(self, action)(self.actions[action])
- rets.append(ret)
-
- self.log.debug('Results: %s', rets)
- self.log.debug('Source after: \n%s', self.source)
-
- if True in rets:
- self.source.file.save()
- return True
- else:
- self.log.warning('No valid changes specified, no actions taken.')
- return False
-
- def name(self, value:str) -> bool:
- """Sets the key file to a name in the key file directory"""
- if not value:
- return False
-
- key_path = None
-
- for ext in ['.gpg', '.asc']:
- if value.endswith(ext):
- path = KEYS_PATH / value
- if path.exists():
- key_path = path
- break
- else:
- if 'archive-keyring' not in value:
- value += '-archive-keyring'
- path = KEYS_PATH / f'{value}{ext}'
- if path.exists():
- key_path = path
- break
-
- if not key_path:
- self.log.error('The key file %s could not be found', value)
- return False
-
- return self.path(str(key_path))
-
- def path(self, value:str) -> bool:
- """Sets the key file to the given path"""
- if not value:
- return False
-
- key_path = Path(value)
-
- if not key_path.exists():
- self.log.error(
- 'The path %s does not exist', value
- )
- return False
-
- self.source.signed_by = str(key_path)
- self.source.load_key()
- return True
-
- def url(self, value:str) -> bool:
- """Downloads a key to use from a provided URL."""
- if not value:
- return False
-
- if not value.startswith('https:'):
- response = 'n'
- self.log.warning(
- 'The key is not being downloaded over an encrypted connection, '
- 'and may be tampered with in-transit. Only add keys that you '
- 'trust, from sources which you trust.'
- )
- response = input('Do you want to continue? (y/N): ')
- if response not in util.true_values:
- return False
-
- key = SourceKey(name=self.source.ident)
- key.load_key_data(url=value)
- self.source.key = key
- self.source.signed_by = str(key.path)
- self.source.load_key()
- return True
-
- def ascii(self, value:str) -> bool:
- """Loads the key from provided ASCII-armored data"""
- if not value:
- return False
-
- response = 'n'
- print('Only add signing keys from data you trust.')
- response = input('Do you want to continue? (y/N): ')
-
- if response not in util.true_values:
- return False
-
- key = SourceKey(name=self.source.ident)
- key.load_key_data(ascii=value)
- self.source.key = key
- self.source.signed_by = str(key.path)
- self.source.load_key()
- return True
-
- def fingerprint(self, value:str) -> bool:
- """Downloads the key with the given fingerprint from a keyserver"""
- if not value:
- return False
-
- key = SourceKey(name=self.source.ident)
-
- if self.keyserver:
- key.load_key_data(fingerprint=value, keyserver=self.keyserver)
- else:
- key.load_key_data(fingerprint=value)
-
- self.source.key = key
- self.source.signed_by = str(key.path)
- self.source.load_key()
- return True
-
- def remove(self, value:str) -> bool:
- """Removes the key from the source"""
-
- if not self.source.key:
- self.log.error(
- 'The source %s does not have a key configured.',
- self.repo
- )
- return False
-
- response = 'n'
- print(
- 'If you remove the key, there may no longer be any verification '
- 'of software packages from this repository, including for future '
- 'updates. This may cause errors with your updates.'
- )
- response = input('Do you want to continue? (y/N): ')
- if response not in util.true_values:
- return False
-
- old_key = self.source.key
- self.source.key = None
- self.source.signed_by = ''
-
- for source in util.sources.values():
- if source.key == old_key:
- self.log.info(
- 'Key file %s in use with another key, not deleting',
- old_key.path
- )
- return True
-
- response = 'n'
- print('No other sources were found which use this key.')
- response = input('Do you want to remove it? (Y/n): ')
- if response in util.true_values:
- old_key.delete_key()
-
- return True
-
diff --git a/archive/repolib/command/list.py b/archive/repolib/command/list.py
deleted file mode 100644
index aad121b..0000000
--- a/archive/repolib/command/list.py
+++ /dev/null
@@ -1,216 +0,0 @@
-#!/usr/bin/python3
-
-"""
-Copyright (c) 2022, Ian Santopietro
-All rights reserved.
-
-This file is part of RepoLib.
-
-RepoLib is free software: you can redistribute it and/or modify
-it under the terms of the GNU Lesser General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-RepoLib 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 Lesser General Public License for more details.
-
-You should have received a copy of the GNU Lesser General Public License
-along with RepoLib. If not, see .
-"""
-
-import argparse
-import textwrap
-import traceback
-
-from ..file import SourceFile, SourceFileError
-from ..source import Source, SourceError
-from .. import RepoError, util, system
-
-from .command import Command, RepolibCommandError
-
-class List(Command):
- """List subcommand
-
- Lists information about currently-configured sources on the system.
-
- Options:
- --legacy, -l
- --verbose, -v
- --all, -a
- --no-names, -n
- --file-names, -f
- --no-indentation
- """
-
- @classmethod
- def init_options(cls, subparsers):
- """Sets up ths argument parser for this command.
-
- Returns: argparse.subparser:
- This command's subparser
- """
-
- sub = subparsers.add_parser(
- 'list',
- help=(
- 'List information for configured repostiories. If a repository '
- 'name is provided, details about that repository are printed.'
- )
- )
-
- sub.add_argument(
- 'repository',
- nargs='*',
- default=['x-repolib-all-sources'],
- help='The repository for which to list configuration'
- )
- sub.add_argument(
- '-v',
- '--verbose',
- action='store_true',
- help='Show additional information, if available.'
- )
- sub.add_argument(
- '-a',
- '--all',
- action='store_true',
- help='Display full configuration for all configured repositories.'
- )
- sub.add_argument(
- '-l',
- '--legacy',
- action='store_true',
- help='Include repositories configured in legacy sources.list file.'
- )
- sub.add_argument(
- '-n',
- '--no-names',
- action='store_true',
- dest='skip_names',
- help=argparse.SUPPRESS
- )
- sub.add_argument(
- '-f',
- '--file-names',
- action='store_true',
- dest='print_files',
- help="Don't print names of files"
- )
- sub.add_argument(
- '--no-indentation',
- action='store_true',
- dest='no_indent',
- help=argparse.SUPPRESS
- )
-
- def finalize_options(self, args):
- super().finalize_options(args)
- self.repo = ' '.join(args.repository)
- self.verbose = args.verbose
- self.all = args.all
- self.legacy = args.legacy
- self.skip_names = args.skip_names
- self.print_files = args.print_files
- self.no_indent = args.no_indent
-
- def list_legacy(self, indent) -> None:
- """List the contents of the sources.list file.
-
- Arguments:
- list_file(Path): The sources.list file to try and parse.
- indent(str): An indentation to append to the output
- """
- try:
- sources_list_file = util.SOURCES_DIR.parent / 'sources.list'
- except FileNotFoundError:
- sources_list_file = None
-
- print('Legacy source.list sources:')
- if sources_list_file:
- with open(sources_list_file, mode='r') as file:
- for line in file:
- if 'cdrom' in line:
- line = ''
-
- try:
- source = Source()
- source.load_from_data([line])
- print(textwrap.indent(source.ui, indent))
- except SourceError:
- pass
-
- def list_all(self):
- """List all sources presently configured in the system
-
- This may include the configuration data for each source as well
- """
-
- indent = ' '
- if self.no_indent:
- indent = ''
-
- if self.print_files:
- print('Configured source files:')
-
- for file in util.files:
- print(f'{file.path.name}:')
-
- for source in file.sources:
- print(textwrap.indent(source.ui, indent))
-
- if self.legacy:
- self.list_legacy(indent)
-
- else:
- print('Configured Sources:')
- for source in util.sources:
- output = util.sources[source]
- print(textwrap.indent(output.ui, indent))
-
- if self.legacy:
- self.list_legacy(indent)
-
- if util.errors:
- print('\n\nThe following files contain formatting errors:')
- for err in util.errors:
- print(err)
- if self.verbose or self.debug:
- print('\nDetails about failing files:')
- for err in util.errors:
- print(f'{err}: {util.errors[err].args[0]}')
-
- return True
-
- def run(self):
- """Run the command"""
- system.load_all_sources()
- self.log.debug("Current sources: %s", util.sources)
- ret = False
-
- if self.all:
- return self.list_all()
-
- if self.repo == 'x-repolib-all-sources' and not self.all:
- if not self.skip_names:
- print('Configured Sources:')
- for source in util.sources:
- line = source
- if not self.skip_names:
- line += f' - {util.sources[source].name}'
- print(line)
-
- return True
-
- else:
- try:
- output = util.sources[self.repo]
- print(f'Details for source {output.ui}')
- return True
- except KeyError:
- self.log.error(
- "Couldn't find the source file for %s, check the spelling",
- self.repo
- )
- return False
diff --git a/archive/repolib/command/modify.py b/archive/repolib/command/modify.py
deleted file mode 100644
index 2738684..0000000
--- a/archive/repolib/command/modify.py
+++ /dev/null
@@ -1,502 +0,0 @@
-#!/usr/bin/python3
-
-"""
-Copyright (c) 2022, Ian Santopietro
-All rights reserved.
-
-This file is part of RepoLib.
-
-RepoLib is free software: you can redistribute it and/or modify
-it under the terms of the GNU Lesser General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-RepoLib 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 Lesser General Public License for more details.
-
-You should have received a copy of the GNU Lesser General Public License
-along with RepoLib. If not, see .
-"""
-
-from argparse import SUPPRESS
-
-from .command import Command, RepolibCommandError
-from .. import util, system
-
-class Modify(Command):
- """Modify Subcommand
-
- Makes modifications to the specified repository
-
- Options:
- --enable, -e
- --disable, -d
- --default-mirror
- --name
- --add-suite
- --remove-suite
- --add-component
- --remove-component
- --add-uri
- --remove-uri
-
- Hidden Options
- --add-option
- --remove-option
- --default-mirror
- """
-
- @classmethod
- def init_options(cls, subparsers):
- """ Sets up this command's options parser"""
-
- sub = subparsers.add_parser(
- 'modify',
- help='Change a configured repository.'
- )
- sub.add_argument(
- 'repository',
- nargs='*',
- default=['system'],
- help='The repository to modify. Default is the system repository.'
- )
-
- modify_enable = sub.add_mutually_exclusive_group(
- required=False
- )
- modify_enable.add_argument(
- '-e',
- '--enable',
- action='store_true',
- help='Enable the repository, if disabled.'
- )
- modify_enable.add_argument(
- '-d',
- '--disable',
- action='store_true',
- help=(
- 'Disable the repository, if enabled. The system repository cannot '
- 'be disabled.'
- )
- )
-
- modify_source = sub.add_mutually_exclusive_group(
- required=False
- )
-
- modify_source.add_argument(
- '--source-enable',
- action='store_true',
- help='Enable source code for the repository, if disabled.'
- )
- modify_source.add_argument(
- '--source-disable',
- action='store_true',
- help='Disable source code for the repository, if enabled.'
- )
-
- sub.add_argument(
- '--default-mirror',
- help=SUPPRESS
- #help='Sets the default mirror for the system source.'
- )
-
- # Name
- sub.add_argument(
- '-n',
- '--name',
- help='Set the repository name to NAME'
- )
-
- # Suites
- sub.add_argument(
- '--add-suite',
- metavar='SUITE[,SUITE]',
- help=(
- 'Add the specified suite(s) to the repository. Multiple '
- 'repositories should be separated with commas. NOTE: Legacy deb '
- 'repositories may only contain one suite.'
- )
- )
- sub.add_argument(
- '--remove-suite',
- metavar='SUITE[,SUITE]',
- help=(
- 'Remove the specified suite(s) from the repository. Multiple '
- 'repositories should be separated with commas. NOTE: The last '
- 'suite in a repository cannot be removed.'
- )
- )
-
- # Components
- sub.add_argument(
- '--add-component',
- metavar='COMPONENT[,COMPONENT]',
- help=(
- 'Add the specified component(s) to the repository. Multiple '
- 'repositories should be separated with commas.'
- )
- )
- sub.add_argument(
- '--remove-component',
- metavar='COMPONENT[,COMPONENT]',
- help=(
- 'Remove the specified component(s) from the repository. Multiple '
- 'repositories should be separated with commas. NOTE: The last '
- 'component in a repository cannot be removed.'
- )
- )
-
- # URIs
- sub.add_argument(
- '--add-uri',
- metavar='URI[,URI]',
- help=(
- 'Add the specified URI(s) to the repository. Multiple '
- 'repositories should be separated with commas. NOTE: Legacy deb '
- 'repositories may only contain one uri.'
- )
- )
- sub.add_argument(
- '--remove-uri',
- metavar='URI[,URI]',
- help=(
- 'Remove the specified URI(s) from the repository. Multiple '
- 'repositories should be separated with commas. NOTE: The last '
- 'uri in a repository cannot be removed.'
- )
- )
-
- # Options
- sub.add_argument(
- '--add-option',
- metavar='OPTION=VALUE[,OPTION=VALUE]',
- help=SUPPRESS
- )
- sub.add_argument(
- '--remove-option',
- metavar='OPTION=VALUE[,OPTION=VALUE]',
- help=SUPPRESS
- )
-
- def finalize_options(self, args):
- super().finalize_options(args)
- self.count = 0
- self.repo = ' '.join(args.repository)
- self.enable = args.enable
- self.disable = args.disable
- self.source_enable = args.source_enable
- self.source_disable = args.source_disable
-
- self.actions:dict = {}
-
- self.actions['endisable'] = None
- for i in ['enable', 'disable']:
- if getattr(args, i):
- self.actions['endisable'] = i
-
- self.actions['source_endisable'] = None
- for i in ['source_enable', 'source_disable']:
- if getattr(args, i):
- self.actions['source_endisable'] = i
-
- for arg in [
- 'default_mirror',
- 'name',
- 'add_uri',
- 'add_suite',
- 'add_component',
- 'remove_uri',
- 'remove_suite',
- 'remove_component',
- ]:
- self.actions[arg] = getattr(args, arg)
-
- system.load_all_sources()
-
- def run(self):
- """Run the command"""
- self.log.info('Modifying repository %s', self.repo)
-
- self.system_source = False
- try:
- self.source = util.sources[self.repo]
- except KeyError:
- self.log.error(
- 'The source %s could not be found. Check the spelling',
- self.repo
- )
- return False
-
- if self.source.ident == 'system':
- self.system_source = True
-
- self.log.debug('Actions to take:\n%s', self.actions)
- self.log.debug('Source before:\n%s', self.source)
-
- rets = []
- for action in self.actions:
- ret = getattr(self, action)(self.actions[action])
- rets.append(ret)
-
- self.log.debug('Results: %s', rets)
- self.log.debug('Source after: \n%s', self.source)
-
- if True in rets:
- self.source.file.save()
- return True
- else:
- self.log.warning('No valid changes specified, no actions taken.')
- return False
-
- def default_mirror(self, value:str) -> bool:
- """Checks if this is the system source, then set the default mirror"""
- if not value:
- return False
-
- if self.system_source:
- self.source['X-Repolib-Default-Mirror'] = value
- return True
- return False
-
- def name(self, value:str) -> bool:
- """Sets the source name"""
- if not value:
- return False
-
- self.log.info('Setting name for %s to %s', self.repo, value)
- self.source.name = value
- return True
-
- def endisable(self, value:str) -> bool:
- """Enable or disable the source"""
- if not value:
- return False
-
- self.log.info('%sing source %s', value[:-1], self.repo)
- if value == 'disable':
- self.source.enabled = False
- return True
-
- self.source.enabled = True
- return True
-
- def source_endisable(self, value:str) -> bool:
- """Enable/disable source code for the repo"""
- if not value:
- return False
-
- self.log.info('%sing source code for source %s', value[7:-1], self.repo)
- if value == 'source_disable':
- self.source.sourcecode_enabled = False
- return True
-
- self.source.sourcecode_enabled = True
- return True
-
- def add_uri(self, values:str) -> bool:
- """Adds URIs to the source, if not already present."""
- if not values:
- return False
-
- self.log.info('Adding URIs: %s', values)
- uris = self.source.uris
-
- for uri in values.split():
- if not util.url_validator(uri):
- raise RepolibCommandError(
- f'Cannot add URI {uri} to {self.repo}. The URI is '
- 'malformed'
- )
-
- if uri not in uris:
- uris.append(uri)
- self.log.debug('Added URI %s', uri)
-
- else:
- self.log.warning(
- 'The URI %s was already present in %s',
- uri,
- self.repo
- )
-
- if uris != self.source.uris:
- self.source.uris = uris
- return True
- return False
-
- def remove_uri(self, values:str) -> bool:
- """Remove URIs from the soruce, if they are added."""
- if not values:
- return False
-
- self.log.info('Removing URIs %s from source %s', values, self.repo)
- uris = self.source.uris
- self.log.debug('Starting uris: %s', uris)
-
- for uri in values.split():
- try:
- uris.remove(uri)
- self.log.debug('Removed URI %s', uri)
-
- except ValueError:
- self.log.warning(
- 'The URI %s was not present in %s',
- uri,
- self.repo
- )
-
- if len(uris) == 0:
- self.log.error(
- 'Cannot remove the last URI from %s. If you meant to delete the source, try REMOVE instead.',
- self.repo
- )
- return False
-
- if uris != self.source.uris:
- self.source.uris = uris
- return True
-
- return False
-
- def add_suite(self, values:str) -> bool:
- """Adds a suite to the source"""
- if not values:
- return False
-
- self.log.info('Adding suites: %s', values)
- suites = self.source.suites
-
- for suite in values.split():
- if suite not in suites:
- suites.append(suite)
- self.log.debug('Added suite %s', suite)
-
- else:
- self.log.warning(
- 'The suite %s was already present in %s',
- suite,
- self.repo
- )
-
- if suites != self.source.suites:
- self.source.suites = suites
- return True
- return False
-
- def remove_suite(self, values:str) -> bool:
- """Remove a suite from the source"""
- if not values:
- return False
-
- self.log.info('Removing suites %s from source %s', values, self.repo)
- suites = self.source.suites
- self.log.debug('Starting suites: %s', suites)
-
- for suite in values.split():
- try:
- suites.remove(suite)
- self.log.debug('Removed suite %s', suite)
-
- except ValueError:
- self.log.warning(
- 'The suite %s was not present in %s',
- suite,
- self.repo
- )
-
- if len(suites) == 0:
- self.log.error(
- 'Cannot remove the last suite from %s. If you meant to delete the source, try REMOVE instead.',
- self.repo
- )
- return False
-
- if suites != self.source.suites:
- self.source.suites = suites
- return True
-
- return False
-
- def add_component(self, values:str) -> bool:
- """Adds components to the source"""
- if not values:
- return False
-
- self.log.info('Adding components: %s', values)
- components = self.source.components
-
- for component in values.split():
- if component not in components:
- components.append(component)
- self.log.debug('Added component %s', component)
-
- else:
- self.log.warning(
- 'The component %s was already present in %s',
- component,
- self.repo
- )
-
- if len(components) > 1:
- if self.source.file.format == util.SourceFormat.LEGACY:
- self.log.warning(
- 'Adding multiple components to a legacy source is not '
- 'supported. Consider converting the source to DEB822 format.'
- )
-
- if components != self.source.components:
- self.source.components = components
- return True
- return False
-
- def remove_component(self, values:str) -> bool:
- """Removes components from the source"""
- if not values:
- return False
-
- self.log.info('Removing components %s from source %s', values, self.repo)
- components = self.source.components
- self.log.debug('Starting components: %s', components)
-
- for component in values.split():
- try:
- components.remove(component)
- self.log.debug('Removed component %s', component)
-
- except ValueError:
- self.log.warning(
- 'The component %s was not present in %s',
- component,
- self.repo
- )
-
- if len(components) == 0:
- self.log.error(
- 'Cannot remove the last component from %s. If you meant to delete the source, try REMOVE instead.',
- self.repo
- )
- return False
-
- if components != self.source.components:
- self.source.components = components
- return True
-
- return False
-
- def add_option(self, values) -> bool:
- """TODO: Support options"""
- raise NotImplementedError(
- 'Options have not been implemented in this version of repolib yet. '
- f'Please edit the file {self.source.file.path} manually.'
- )
-
-
- def remove_option(self, values) -> bool:
- """TODO: Support options"""
- raise NotImplementedError(
- 'Options have not been implemented in this version of repolib yet. '
- f'Please edit the file {self.source.file.path} manually.'
- )
diff --git a/archive/repolib/command/remove.py b/archive/repolib/command/remove.py
deleted file mode 100644
index 851be03..0000000
--- a/archive/repolib/command/remove.py
+++ /dev/null
@@ -1,128 +0,0 @@
-#!/usr/bin/python3
-
-"""
-Copyright (c) 2022, Ian Santopietro
-All rights reserved.
-
-This file is part of RepoLib.
-
-RepoLib is free software: you can redistribute it and/or modify
-it under the terms of the GNU Lesser General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-RepoLib 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 Lesser General Public License for more details.
-
-You should have received a copy of the GNU Lesser General Public License
-along with RepoLib. If not, see .
-"""
-
-from .. import util, system
-from .command import Command
-
-class Remove(Command):
- """Remove subcommand
-
- Removes configured sources from the system
-
- Options:
- --assume-yes, -y
- """
-
- @classmethod
- def init_options(cls, subparsers):
- """Sets up the argument parser for this command
-
- Returns: argparse.subparser
- This command's subparser
- """
-
- sub = subparsers.add_parser(
- 'remove',
- help='Remove a configured repository'
- )
-
- sub.add_argument(
- 'repository',
- help='The identifier of the repository to remove. See LIST'
- )
- sub.add_argument(
- '-y',
- '--assume-yes',
- action='store_true',
- help='Remove without prompting for confirmation'
- )
-
- def finalize_options(self, args):
- super().finalize_options(args)
- system.load_all_sources()
- self.source_name = args.repository
- self.assume_yes = args.assume_yes
- self.source = None
-
- def run(self):
- """Run the command"""
-
- self.log.info('Looking up %s for removal', self.source_name)
-
- if self.source_name == 'system':
- self.log.error('You cannot remove the system sources')
- return False
-
- if self.source_name not in util.sources:
- self.log.error(
- 'Source %s was not found. Double-check the spelling',
- self.source_name
- )
- source_list:list = []
- for source in util.sources:
- source_list.append(source)
- suggested_source:str = self.source_name.replace(':', '-')
- suggested_source = suggested_source.translate(util.CLEAN_CHARS)
- if not suggested_source in source_list:
- return False
-
- response:str = input(f'Did you mean "{suggested_source}"? (Y/n) ')
- if not response:
- response = 'y'
- if response not in util.true_values:
- return False
- self.source_name = suggested_source
-
- self.source = util.sources[self.source_name]
- self.key = self.source.key
- self.file = self.source.file
-
- print(f'This will remove the source {self.source_name}')
- print(self.source.ui)
- response:str = 'n'
- if self.assume_yes:
- response = 'y'
- else:
- response = input('Are you sure you want to do this? (y/N) ')
-
- if response in util.true_values:
- self.file.remove_source(self.source_name)
- self.file.save()
-
- system.load_all_sources()
- for source in util.sources.values():
- self.log.debug('Checking key for %s', source.ident)
- try:
- if source.key.path == self.key.path:
- self.log.info('Source key in use with another source')
- return True
- except AttributeError:
- pass
-
- self.log.info('No other sources found using key, deleting key')
- if self.key:
- self.key.delete_key()
- return True
-
- else:
- print('Canceled.')
- return False
diff --git a/archive/repolib/file.py b/archive/repolib/file.py
deleted file mode 100644
index 5541a56..0000000
--- a/archive/repolib/file.py
+++ /dev/null
@@ -1,544 +0,0 @@
-#!/usr/bin/python3
-
-"""
-Copyright (c) 2022, Ian Santopietro
-All rights reserved.
-
-This file is part of RepoLib.
-
-RepoLib is free software: you can redistribute it and/or modify
-it under the terms of the GNU Lesser General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-RepoLib 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 Lesser General Public License for more details.
-
-You should have received a copy of the GNU Lesser General Public License
-along with RepoLib. If not, see .
-"""
-import logging
-
-from pathlib import Path
-
-import dbus
-
-from .source import Source, SourceError
-from . import util
-
-FILE_COMMENT = "## Added/managed by repolib ##"
-
-class SourceFileError(util.RepoError):
- """ Exception from a source file."""
-
- def __init__(self, *args, code:int = 1, **kwargs):
- """Exception with a source file
-
- Arguments:
- :code int, optional, default=1: Exception error code.
- """
- super().__init__(*args, **kwargs)
- self.code: int = code
-
-class SourceFile:
- """ A Source File on disk
-
- Attributes:
- path(Pathlib.Path): the path for this file on disk
- name(str): The name for this source (filename less the extension)
- format(SourceFormat): The format used by this source file
- contents(list): A list containing all of this file's contents
- """
-
- def __init__(self, name:str='') -> None:
- """Initialize a source file
-
- Arguments:
- name(str): The filename within the sources directory to load
- """
- self.log = logging.getLogger(__name__)
- self.name:str = ''
- self.path:Path = Path()
- self.alt_path:Path = Path()
- self.format:util.SourceFormat = util.SourceFormat.DEFAULT
- self.contents:list = []
- self.sources:list = []
-
- self.contents.append(FILE_COMMENT)
- self.contents.append('#')
-
- if name:
- self.name = name
- self.reset_path()
-
- if self.path.exists():
- self.contents = []
- self.load()
-
- def __str__(self):
- return self.output
-
- def __repr__(self):
- return f'SourceFile(name={self.name})'
-
- def add_source(self, source:Source) -> None:
- """Adds a source to the file
-
- Arguments:
- source(Source): The source to add
- """
- if source not in self.sources:
- self.contents.append(source)
- self.sources.append(source)
- source.file = self
-
- def remove_source(self, ident:str) -> None:
- """Removes a source from the file
-
- Arguments:
- ident(str): The ident of the source to remove
- """
- source = self.get_source_by_ident(ident)
- self.contents.remove(source)
- self.sources.remove(source)
- self.save()
-
- ## Remove sources prefs files/pin-priority
- prefs_path = source.prefs
- try:
- if prefs_path.exists() and prefs_path.name:
- prefs_path.unlink()
-
- except AttributeError:
- # No prefs path
- pass
-
- except PermissionError:
- bus = dbus.SystemBus()
- privileged_object = bus.get_object('org.pop_os.repolib', '/Repo')
- privileged_object.delete_prefs_file(str(prefs_path))
-
- def get_source_by_ident(self, ident: str) -> Source:
- """Find a source within this file by its ident
-
- Arguments:
- ident(str): The ident to search for
-
- Returns: Source
- The located source
- """
- self.log.debug(f'Looking up ident {ident} in {self.name}')
- for source in self.sources:
- if source.ident == ident:
- self.log.debug(f'{ident} found')
- return source
- raise SourceFileError(
- f'The file {self.path} does not contain the source {ident}'
- )
-
- def reset_path(self) -> None:
- """Attempt to detect the correct path for this File.
-
- We default to DEB822 .sources format files, but if that file doesn't
- exist, fallback to legacy .list format. If this also doesn't exist, we
- swap back to DEB822 format, as this is likely a new file."""
- self.log.debug('Resetting path')
-
- default_path = util.SOURCES_DIR / f'{self.name}.sources'
- legacy_path = util.SOURCES_DIR / f'{self.name}.list'
-
- if default_path.exists():
- self.path = default_path
- self.alt_path = legacy_path
- self.format = util.SourceFormat.DEFAULT
-
- elif legacy_path.exists():
- self.path = legacy_path
- self.alt_path = default_path
- self.format = util.SourceFormat.LEGACY
-
- else:
- self.path = default_path
- self.alt_path = legacy_path
-
- return
-
- def find_unique_ident(self, source1:Source, source2:Source) -> bool:
- """Takes two sources with identical idents, and finds a new, unique
- idents for them.
-
- The rules for this are mildly complicated, and vary depending on the
- situation:
-
- * (DEB822) If the sources are identical other than some portion of
- data, then the two will be combined into a single source.
- * (legacy) If the two sources are identical other than source type
- (common with legacy-format PPAs with source code) then the second
- source will be dropped until export.
- * (legacy) If the sources differ by URIs, Components, or Suites, then
- the differing data will be appended to the sources' idents.
- * (Either) If no other rules can be determined, then the sources will
- have a number appended to them
-
- Arguments:
- source1(Source): The original source with the ident
- source2(Source): The new colliding source with the ident
-
- Returns: bool
- `True` if the two sources were successfully deduped, `False` if the
- second source should be discarded.
- """
- ident_src1:str = source1.ident
- ident_src2:str = source2.ident
-
- self.log.debug(f'Idents {ident_src1} and {ident_src2} conflict')
-
- if self.format == util.SourceFormat.DEFAULT:
- util.combine_sources(source1, source2)
- ident_src2 = ''
-
- else:
- excl_keys = [
- 'X-Repolib-Name',
- 'X-Repolib-ID',
- 'X-Repolib-Comment',
- 'Enabled',
- 'Types'
- ]
- if len(source1.types) == 1 and len(source2.types) == 1:
- if util.compare_sources(source1, source2, excl_keys):
- util.combine_sources(source1, source2)
- source1.types = [
- util.SourceType.BINARY, util.SourceType.SOURCECODE
- ]
- source1.twin_source = True
- source1.sourcecode_enabled = source2.enabled
- ident_src2 = ''
- diffs = util.find_differences_sources(source1, source2, excl_keys)
- if diffs:
- for key in diffs:
- raw_diffs:tuple = diffs[key]
- diff1_list = raw_diffs[0].strip().split()
- diff2_list = raw_diffs[1].strip().split()
- for i in diff1_list:
- if i not in diff2_list:
- ident_src1 += f'-{i}'
- break
- for i in diff2_list:
- if i not in diff1_list:
- ident_src2 += f'-{i}'
- break
- if ident_src1 != ident_src2:
- break
- if ident_src2 and ident_src1 != ident_src2:
- source1.ident = ident_src1
- source2.ident = ident_src2
- return True
-
- elif ident_src2 and ident_src1 == ident_src2:
- for source in self.sources:
- src_index = self.sources.index(source)
- source.ident = f'{self.name}-{src_index}'
- return True
-
- elif not ident_src2:
- return False
-
- return True
-
-
- def load(self) -> None:
- """Loads the sources from the file on disk"""
- self.log.debug(f'Loading source file {self.path}')
- self.contents = []
- self.sources = []
-
- if not self.name:
- raise SourceFileError('You must provide a filename to load.')
-
- if not self.path.exists():
- raise SourceFileError(f'The file {self.path} does not exist.')
-
- with open(self.path, 'r') as source_file:
- srcfile_data = source_file.readlines()
-
- item:int = 0
- raw822:list = []
- parsing_deb822:bool = False
- source_name:str = ''
- commented:bool = False
- idents:dict = {}
-
- # Main file parsing loop
- for line in srcfile_data:
- comment_found:str = ''
- name_line:bool = 'X-Repolib-Name' in line
-
- if not parsing_deb822:
- commented = line.startswith('#')
-
- # Find commented out lines
- if commented:
- # Exclude disabled legacy deblines
- valid_legacy = util.validate_debline(line.strip())
- if not valid_legacy and not name_line:
- # Found a standard comment
- self.contents.append(line.strip())
-
- elif valid_legacy:
- if self.format != util.SourceFormat.LEGACY:
- raise SourceFileError(
- f'File {self.path.name} is an updated file, but '
- 'contains legacy-format sources. This is not '
- 'allowed. Please fix the file manually.'
- )
- new_source = Source()
- new_source.load_from_data([line])
- if source_name:
- new_source.name = source_name
- if not new_source.ident:
- new_source.ident = self.name
- to_add:bool = True
- if new_source.ident in idents:
- old_source = idents[new_source.ident]
- idents.pop(old_source.ident)
- to_add = self.find_unique_ident(old_source, new_source)
- idents[old_source.ident] = old_source
- idents[new_source.ident] = new_source
- if to_add:
- new_source.file = self
- self.contents.append(new_source)
- self.sources.append(new_source)
-
- elif name_line:
- source_name = ':'.join(line.split(':')[1:])
- source_name = source_name.strip()
-
- # Active legacy line
- elif not commented:
- if util.validate_debline(line.strip()):
- if self.format != util.SourceFormat.LEGACY:
- raise SourceFileError(
- f'File {self.path.name} is an updated file, but '
- 'contains legacy-format sources. This is not '
- 'allowed. Please fix the file manually.'
- )
- new_source = Source()
- new_source.load_from_data([line])
- if source_name:
- new_source.name = source_name
- if not new_source.ident:
- new_source.ident = self.name
- to_add:bool = True
- if new_source.ident in idents:
- old_source = idents[new_source.ident]
- idents.pop(old_source.ident)
- to_add = self.find_unique_ident(old_source, new_source)
- idents[old_source.ident] = old_source
- idents[new_source.ident] = new_source
- if to_add:
- new_source.file = self
- self.contents.append(new_source)
- self.sources.append(new_source)
-
- # Empty lines are treated as comments
- if line.strip() == '':
- self.contents.append('')
-
- # Find 822 sources
- # Valid sources can begin with any key:
- for key in util.valid_keys:
- if line.startswith(key):
- if self.format == util.SourceFormat.LEGACY:
- raise SourceFileError(
- f'File {self.path.name} is a DEB822-format file, but '
- 'contains legacy sources. This is not allowed. '
- 'Please fix the file manually.'
- )
- parsing_deb822 = True
- raw822.append(line.strip())
-
- item += 1
-
- elif parsing_deb822:
- # Deb822 sources are terminated with an empty line
- if line.strip() == '':
- parsing_deb822 = False
- new_source = Source()
- new_source.load_from_data(raw822)
- new_source.file = self
- if source_name:
- new_source.name = source_name
- if not new_source.ident:
- new_source.ident = self.name
- if new_source.ident in idents:
- old_source = idents[new_source.ident]
- idents.pop(old_source.ident)
- self.find_unique_ident(old_source, new_source)
- idents[old_source.ident] = old_source
- idents[new_source.ident] = new_source
- new_source.file = self
- self.contents.append(new_source)
- self.sources.append(new_source)
- raw822 = []
- item += 1
- self.contents.append('')
- else:
- raw822.append(line.strip())
-
- if raw822:
- parsing_deb822 = False
- new_source = Source()
- new_source.load_from_data(raw822)
- new_source.file = self
- if source_name:
- new_source.name = source_name
- if not new_source.ident:
- new_source.ident = self.name
- if new_source.ident in idents:
- old_source = idents[new_source.ident]
- idents.pop(old_source.ident)
- self.find_unique_ident(old_source, new_source)
- idents[old_source.ident] = old_source
- idents[new_source.ident] = new_source
- new_source.file = self
- self.contents.append(new_source)
- self.sources.append(new_source)
- raw822 = []
- item += 1
- self.contents.append('')
-
- for source in self.sources:
- if not source.has_required_parts:
- raise SourceFileError(
- f'The file {self.path.name} is malformed and contains '
- 'errors. Maybe it has some extra new-lines?'
- )
-
- self.log.debug('File %s loaded', self.path)
-
- def save(self) -> None:
- """Saves the source file to disk using the current format"""
- self.log.debug(f'Saving source file to {self.path}')
-
- for source in self.sources:
- self.log.debug('New Source %s: \n%s', source.ident, source)
-
- save_path = util.SOURCES_DIR / f'{self.name}.save'
-
- for source in self.sources:
- if source.key:
- source.key.save_gpg()
- source.tasks_save()
-
- if not self.name or not self.format:
- raise SourceFileError('There was not a complete filename to save')
-
- if not util.SOURCES_DIR.exists():
- try:
- util.SOURCES_DIR.mkdir(parents=True)
- except PermissionError:
- self.log.error(
- 'Source destination path does not exist and cannot be created '
- 'Failures expected now.'
- )
-
- if len(self.sources) > 0:
- self.log.debug('Saving, Main path %s; Alt path: %s', self.path, self.alt_path)
- try:
- with open(self.path, mode='w') as output_file:
- output_file.write(self.output)
- if self.alt_path.exists():
- self.alt_path.rename(save_path)
-
- except PermissionError:
- bus = dbus.SystemBus()
- privileged_object = bus.get_object('org.pop_os.repolib', '/Repo')
- privileged_object.output_file_to_disk(self.path.name, self.output)
- self.log.debug('File %s saved', self.path)
- else:
- try:
- self.path.unlink(missing_ok=True)
- self.alt_path.unlink(missing_ok=True)
- save_path.unlink(missing_ok=True)
- except PermissionError:
- bus = dbus.SystemBus()
- privileged_object = bus.get_object('org.pop_os.repolib', '/Repo')
- privileged_object.delete_source_file(self.path.name)
- self.log.debug('File %s removed', self.path)
-
-
- ## Attribute properties
- @property
- def format(self) -> util.SourceFormat: # type: ignore (We don't use str.format)
- """The format of the file on disk"""
- return self._format
-
- @format.setter
- def format(self, format:util.SourceFormat) -> None: # type: ignore (We don't use str.format)
- """The path needs to be updated when the format changes"""
- alt_format:util.SourceFormat = util.SourceFormat.LEGACY
- self._format = format
- self.path = util.SOURCES_DIR / f'{self.name}.{self._format.value}'
- for format_ in util.SourceFormat:
- if format != format_:
- alt_format = format_
- self.alt_path = util.SOURCES_DIR / f'{self.name}.{alt_format.value}'
-
- ## Output properties
- @property
- def legacy(self) -> str:
- """Outputs the file in the output_legacy format"""
- legacy_output:str = ''
- for item in self.contents:
- try:
- legacy_output += item.legacy
- except AttributeError:
- legacy_output += item
- legacy_output += '\n'
- return legacy_output
-
- @property
- def deb822(self) -> str:
- """Outputs the file in the output_822 format"""
- deb822_output:str = ''
- for item in self.contents:
- try:
- deb822_output += item.deb822
- except AttributeError:
- deb822_output += item
- deb822_output += '\n'
- return deb822_output
-
-
- @property
- def ui(self) -> str:
- """Outputs the file in the output_ui format"""
- ui_output:str = ''
- for item in self.contents:
- try:
- ui_output += item.ui
- except AttributeError:
- pass # Skip file comments in UI mode
- ui_output += '\n'
- return ui_output
-
-
- @property
- def output(self) -> str:
- """Outputs the file in the output format"""
- default_output:str = ''
- for item in self.contents:
- try:
- if self.format == util.SourceFormat.DEFAULT:
- default_output += item.deb822
- elif self.format == util.SourceFormat.LEGACY:
- default_output += item.legacy
- default_output += '\n'
- except AttributeError:
- default_output += item
- default_output += '\n'
- return default_output
-
diff --git a/archive/repolib/key.py b/archive/repolib/key.py
deleted file mode 100644
index 766881b..0000000
--- a/archive/repolib/key.py
+++ /dev/null
@@ -1,204 +0,0 @@
-#!/usr/bin/python3
-
-"""
-Copyright (c) 2022, Ian Santopietro
-All rights reserved.
-
-This file is part of RepoLib.
-
-RepoLib is free software: you can redistribute it and/or modify
-it under the terms of the GNU Lesser General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-RepoLib 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 Lesser General Public License for more details.
-
-You should have received a copy of the GNU Lesser General Public License
-along with RepoLib. If not, see .
-"""
-
-import logging
-import shutil
-
-import dbus
-import gnupg
-from pathlib import Path
-from urllib import request
-
-from . import util
-
-SKS_KEYSERVER = 'https://keyserver.ubuntu.com/'
-SKS_KEYLOOKUP_PATH = 'pks/lookup?op=get&options=mr&exact=on&search=0x'
-
-class KeyFileError(util.RepoError):
- """ Exceptions related to apt key files."""
-
- def __init__(self, *args, code=1, **kwargs):
- """Exceptions related to apt key files.
-
- Arguments:
- code (:obj:`int`, optional, default=1): Exception error code.
- """
- super().__init__(*args, **kwargs)
- self.code = code
-
-class SourceKey:
- """A signing key for an apt source."""
-
- def __init__(self, name:str = '') -> None:
- self.log = logging.getLogger(__name__)
- self.tmp_path = Path()
- self.path = Path()
- self.gpg = gnupg.GPG()
- self.data = b''
-
- if name:
- self.reset_path(name=name)
- self.setup_gpg()
-
- def reset_path(self, name: str = '', path:str = '', suffix: str = 'archive-keyring') -> None:
- """Set the path for this key
-
- Arguments:
- suffix(str): The suffix to append to the end of the name to get the
- file name (default: 'archive-keyring')
- name(str): The name of the source
- path(str): The entire path to the key
- """
- self.log.info('Setting path')
- if not name and not path:
- raise KeyFileError('A name is required to set the path for this key')
-
- if name:
- file_name = f'{name}-{suffix}.gpg'
- self.tmp_path = util.TEMP_DIR / file_name
- self.path = util.KEYS_DIR / file_name
- elif path:
- self.path = Path(path)
- self.tmp_path = util.TEMP_DIR / self.path.name
-
- self.setup_gpg()
-
- self.log.debug('Key Path: %s', self.path)
- self.log.debug('Temp Path: %s', self.tmp_path)
-
- def setup_gpg(self) -> None:
- """Set up the GPG object for this key."""
- self.log.info('Setting up GPG')
- self.log.debug('Copying %s to %s', self.path, self.tmp_path)
- try:
- shutil.copy2(self.path, self.tmp_path)
-
- except FileNotFoundError:
- pass
-
- self.gpg = gnupg.GPG(keyring=str(self.tmp_path))
- self.log.debug('GPG Setup: %s', self.gpg.keyring)
-
- def save_gpg(self) -> None:
- """Saves the key to disk."""
- self.log.info('Saving key file %s from %s', self.path, self.tmp_path)
- self.log.debug('Key contents: %s', self.gpg.list_keys())
- self.log.debug('Temp key exists? %s', self.tmp_path.exists())
- if not util.KEYS_DIR.exists():
- try:
- util.KEYS_DIR.mkdir(parents=True)
- except PermissionError:
- self.log.error(
- 'Key destination path does not exist and cannot be created '
- 'Failures expected now.'
- )
- try:
- shutil.copy(self.tmp_path, self.path)
-
- except PermissionError:
- bus = dbus.SystemBus()
- privileged_object = bus.get_object('org.pop_os.repolib', '/Repo')
- privileged_object.install_signing_key(
- str(self.tmp_path),
- str(self.path)
- )
-
- def delete_key(self) -> None:
- """Deletes the key file from disk."""
- try:
- self.tmp_path.unlink()
- self.path.unlink()
-
- except PermissionError:
- bus = dbus.SystemBus()
- privileged_object = bus.get_object('org.pop_os.repolib', '/Repo')
- privileged_object.delete_signing_key(str(self.path))
-
- except FileNotFoundError:
- pass
-
- def load_key_data(self, **kwargs) -> None:
- """Loads the key data from disk into the object for processing.
-
- Each of the keyword options specifies one place to look to import key
- data. Once one is successfully imported, the method returns, so passing
- multiple won't import multiple keys.
-
- Keyword Arguments:
- raw(bytes): Raw data to import to the keyring
- ascii(str): ASCII-armored key data to import directly
- url(str): A URL to download key data from
- fingerprint(str): A key fingerprint to download from `keyserver`
- keyserver(str): A keyserver to download from.
- keypath(str): The path on the keyserver from which to download.
-
- NOTE: The keyserver and keypath args only affect the operation of the
- `fingerprint` keyword.
- """
-
- if self.path.exists():
- with open(self.path, mode='rb') as keyfile:
- self.data = keyfile.read()
- return
-
- self.tmp_path.touch()
-
- if 'raw' in kwargs:
- self.data = kwargs['raw']
- self.gpg.import_keys(self.data)
- return
-
- if 'ascii' in kwargs:
- self.gpg.import_keys(kwargs['ascii'])
- if self.tmp_path.exists():
- with open(self.tmp_path, mode='rb') as keyfile:
- self.data = keyfile.read()
- return
-
- if 'url' in kwargs:
- req = request.Request(kwargs['url'])
- with request.urlopen(req) as response:
- self.data = response.read().decode('UTF-8')
- self.gpg.import_keys(self.data)
- return
-
- if 'fingerprint' in kwargs:
- if not 'keyserver' in kwargs:
- kwargs['keyserver'] = SKS_KEYSERVER
-
- if not 'keypath' in kwargs:
- kwargs['keypath'] = SKS_KEYLOOKUP_PATH
-
- key_url = kwargs['keyserver'] + kwargs['keypath'] + kwargs['fingerprint']
- req = request.Request(key_url)
- with request.urlopen(req) as response:
- self.data = response.read().decode('UTF-8')
- self.gpg.import_keys(self.data)
- return
-
- raise TypeError(
- f'load_key_data() got an unexpected keyword argument "{kwargs.keys()}',
- ' Expected keyword arguments are: [raw, ascii, url, fingerprint]'
- )
-
-
-
diff --git a/archive/repolib/parsedeb.py b/archive/repolib/parsedeb.py
deleted file mode 100644
index 1e0d992..0000000
--- a/archive/repolib/parsedeb.py
+++ /dev/null
@@ -1,371 +0,0 @@
-#!/usr/bin/python3
-
-"""
-Copyright (c) 2022, Ian Santopietro
-All rights reserved.
-
-This file is part of RepoLib.
-
-RepoLib is free software: you can redistribute it and/or modify
-it under the terms of the GNU Lesser General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-RepoLib 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 Lesser General Public License for more details.
-
-You should have received a copy of the GNU Lesser General Public License
-along with RepoLib. If not, see .
-"""
-
-import logging
-
-from . import util
-
-log = logging.getLogger(__name__)
-
-class DebParseError(util.RepoError):
- """ Exceptions related to parsing deb lines."""
-
- def __init__(self, *args, code=1, **kwargs):
- """Exceptions related to parsing deb lines.
-
- Arguments:
- code (:obj:`int`, optional, default=1): Exception error code.
- """
- super().__init__(*args, **kwargs)
- self.code = code
-
-def debsplit(line:str) -> list:
- """ Improved string.split() with support for things like [] options.
-
- Adapted from python-apt
-
- Arguments:
- line(str): The line to split up.
- """
- line = line.strip()
- line_list = line.split()
- for i in line_list:
- if util.url_validator(i):
- line_list[line_list.index(i)] = decode_brackets(i)
- line = ' '.join(line_list)
- pieces:list = []
- tmp:str = ""
- # we are inside a [..] block
- p_found = False
- for char in line:
- if char == '[':
- p_found = True
- tmp += char
- elif char == ']':
- p_found = False
- tmp += char
- elif char.isspace() and not p_found:
- pieces.append(tmp)
- tmp = ''
- continue
- else:
- tmp += char
- # append last piece
- if len(tmp) > 0:
- pieces.append(tmp)
- return pieces
-
-def encode_brackets(word:str) -> str:
- """ Encodes any [ and ] brackets into URL-safe form
-
- Technically we should never be recieving these, and there are other things
- which should technically be encoded as well. However, square brackets
- actively break the URL parsing, and must be strictly avoided.
-
- Arguments:
- word (str): the string to encode brackets in.
-
- Returns:
- `str`: the encoded string.
- """
- word = word.replace('[', '%5B')
- word = word.replace(']', '%5D')
- return word
-
-def decode_brackets(word:str) -> str:
- """ Un-encodes [ and ] from the input
-
- Since our downstream libraries should also be encoding these correctly, it
- is better to retain these as the user entered, as that ensures they can
- recognize it properly.
-
- Arguments:
- word (str): The string to decode.
-
- Returns:
- `str`: the decoded string.
- """
- word = word.replace('%5B', '[')
- word = word.replace('%5D', ']')
- return word
-
-def parse_name_ident(tail:str) -> tuple:
- """ Find a Repolib name within the given comment string.
-
- The name should be headed with "X-Repolib-Name:" and is not space terminated.
- The ident should be headed with "X-Repolib-ID:" and is space terminated.
-
- Either field ends at the end of a line, or at a subsequent definition of a
- different field, or at a subsequent ' #' substring. Additionally, the ident
- field ends with a subsequent space.
-
- Arguments:
- tail (str): The comment to search within.
-
- Returns: tuple(name, ident, comment):
- name (str): The detected name, or None
- ident (str): The detected ident, or None
- comment (str): The string with the name and ident removed
- """
- tail = util.strip_hashes(tail)
-
- # Used for sanity checking later
- has_name = 'X-Repolib-Name' in tail
- log.debug('Line name found: %s', has_name)
- has_ident = 'X-Repolib-ID' in tail
- log.debug('Line ident found: %s', has_ident)
-
- parts: list = tail.split()
- name_found = False
- ident_found = False
- name:str = ''
- ident:str = ''
- comment:str = ''
- for item in parts:
- log.debug("Checking line item: %s", item)
- item_is_name = item.strip('#').strip().startswith('X-Repolib-Name')
- item_is_ident = item.strip('#').strip().startswith('X-Repolib-ID')
-
- if '#' in item and not item_is_name and not item_is_ident:
- name_found = False
- ident_found = False
-
- elif item_is_name:
- name_found = True
- ident_found = False
- continue
-
- elif item_is_ident:
- name_found = False
- ident_found = True
- continue
-
- if name_found and not item_is_name:
- name += f'{item} '
- continue
-
- elif ident_found and not item_is_ident:
- ident += f'{item}'
- ident_found = False
- continue
-
- elif not name_found and not ident_found:
- c = item.strip('#')
- comment += f'{c} '
-
- name = name.strip()
- ident = ident.strip()
- comment = comment.strip()
-
- if not name:
- if ident:
- name = ident
-
- # Final sanity checking
- if has_name and not name:
- raise DebParseError(
- f'Could not parse repository name from comment {comment}. Make sure '
- 'you have a space between the colon and the Name'
- )
- if has_ident and not ident:
- raise DebParseError(
- f'Could not parse repository ident from comment {comment}. Make sure '
- 'you have a space between the colon and the Ident'
- )
-
- return name, ident, comment
-
-
-class ParseDeb:
- """ Parsing for source entries.
-
- Contains parsing helpers for one-line format sources.
- """
-
- def __init__(self, debug:bool = False) -> None:
- """
- Arguments:
- debug (bool): In debug mode, the structured data is always returned
- at the end, instead of checking for sanity (default: `False`)
- """
- self.debug = debug
- self.last_line: str = ''
- self.last_line_valid: bool = False
- self.curr_line: str = ''
- self.curr_line_valid: bool = False
-
- def parse_options(self, opt:str) -> dict:
- """ Parses a string of options into a dictionary that repolib can use.
-
- Arguments:
- opt(str): The string with options returned from the line parser.
-
- Returns:
- `dict`: The dictionary of options with key:val pairs (may be {})
- """
- opt = opt.strip()
- opt = opt[1:-1].strip() # Remove enclosing brackets
- options = opt.split()
-
- parsed_options:dict = {}
-
- for opt in options:
- pre_key, values = opt.split('=')
- values = values.split(',')
- value:str = ' '.join(values)
- try:
- key:str = util.options_inmap[pre_key]
- except KeyError:
- raise DebParseError(
- f'Could not parse line {self.curr_line}: option {opt} is '
- 'not a valid debian repository option or is unsupported.'
- )
- parsed_options[key] = value
-
- return parsed_options
-
-
- def parse_line(self, line:str) -> dict:
- """ Parse a deb line into its individual parts.
-
- Adapted from python-apt
-
- Arguments:
- line (str): The line input to parse
-
- Returns:
- (dict): a dict containing the requisite data.
- """
- self.last_line = self.curr_line
- self.last_line_valid = self.curr_line_valid
- self.curr_line = line.strip()
- parts:list = []
-
- line_is_comment = self.curr_line == '#'
- line_is_empty = self.curr_line == ''
- if line_is_comment or line_is_empty:
- raise DebParseError(f'Current line "{self.curr_line}" is empty')
-
- line_parsed: dict = {}
- line_parsed['enabled'] = True
- line_parsed['name'] = ''
- line_parsed['ident'] = ''
- line_parsed['comments'] = []
- line_parsed['repo_type'] = ''
- line_parsed['uri'] = ''
- line_parsed['suite'] = ''
- line_parsed['components'] = []
- line_parsed['options'] = {}
-
- if line.startswith('#'):
- line_parsed['enabled'] = False
- line = util.strip_hashes(line)
- parts = line.split()
- if not parts[0] in ('deb', 'deb-src'):
- raise DebParseError(f'Current line "{self.curr_line}" is invalid')
-
- comments_index = line.find('#')
- if comments_index > 0:
- raw_comments:str = line[comments_index + 1:].strip()
- (
- line_parsed['name'],
- line_parsed['ident'],
- comments
- ) = parse_name_ident(raw_comments)
- line_parsed['comments'].append(comments)
- line = line[:comments_index]
-
- parts = debsplit(line)
- if len(parts) < 3: # We need at least a type, a URL, and a component
- raise DebParseError(
- f'The line "{self.curr_line}" does not have enough pieces to be'
- 'valid'
- )
- # Determine the type of the repo
- repo_type:str = parts.pop(0)
- if repo_type in ['deb', 'deb-src']:
- line_parsed['repo_type'] = util.SourceType(repo_type)
- else:
- raise DebParseError(f'The line "{self.curr_line}" is of invalid type.')
-
- # Determine the properties of our repo line
- uri_index:int = 0
- is_cdrom: bool = False
- ## The URI index is the vital piece of information we need to parse the
- ## deb line, as it's position determines what other components are
- ## present and where they are. This determines the location of the URI
- ## regardless of where it's at.
- for part in parts:
- if part.startswith('['):
- if 'cdrom' in part:
- is_cdrom = True
- uri_index = parts.index(part)
- else:
- uri_index = 1
-
- if is_cdrom:
- # This could maybe change if the parser now differentiates between
- # CDROM URIs and option lists
- raise DebParseError('Repolib cannot currently accept CDROM Sources')
-
- if uri_index != 0:
- line_parsed['options'] = self.parse_options(parts.pop(0))
-
- if len(line_parsed) < 2: # Should have at minimum a URI and a suite/path
- raise DebParseError(
- f'The line "{self.curr_line}" does not have enough pieces to be'
- 'valid'
- )
-
- line_uri = parts.pop(0)
- if util.url_validator(line_uri):
- line_parsed['uri'] = line_uri
-
- else:
- raise DebParseError(
- f'The line "{self.curr_line}" has invalid URI: {line_uri}'
- )
-
- line_parsed['suite'] = parts.pop(0)
-
- line_components:list = []
- for comp in parts:
- line_parsed['components'].append(comp)
-
-
- has_type = line_parsed['repo_type']
- has_uri = line_parsed['uri']
- has_suite = line_parsed['suite']
-
- if has_type and has_uri and has_suite:
- # if we have these three minimum components, we can proceed and the
- # line is valid. Otherwise, error out.
- return line_parsed.copy()
-
- if self.debug:
- return line_parsed.copy()
-
- raise DebParseError(
- f'The line {self.curr_line} could not be parsed due to an '
- 'unknown error (Probably missing the repo type, URI, or a '
- 'suite/path).'
- )
diff --git a/archive/repolib/shortcuts/__init__.py b/archive/repolib/shortcuts/__init__.py
deleted file mode 100644
index 43c1503..0000000
--- a/archive/repolib/shortcuts/__init__.py
+++ /dev/null
@@ -1,32 +0,0 @@
-#!/usr/bin/python3
-
-"""
-Copyright (c) 2022, Ian Santopietro
-All rights reserved.
-
-This file is part of RepoLib.
-
-RepoLib is free software: you can redistribute it and/or modify
-it under the terms of the GNU Lesser General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-RepoLib 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 Lesser General Public License for more details.
-
-You should have received a copy of the GNU Lesser General Public License
-along with RepoLib. If not, see .
-"""
-
-from .popdev import PopdevSource
-from .ppa import PPASource
-from ..source import Source
-
-shortcut_prefixes = {
- 'deb': Source,
- 'deb-src': Source,
- ppa.prefix: ppa.PPASource,
- popdev.prefix: popdev.PopdevSource
-}
\ No newline at end of file
diff --git a/archive/repolib/shortcuts/popdev.py b/archive/repolib/shortcuts/popdev.py
deleted file mode 100644
index f4efc6e..0000000
--- a/archive/repolib/shortcuts/popdev.py
+++ /dev/null
@@ -1,171 +0,0 @@
-#!/usr/bin/python3
-
-"""
-Copyright (c) 2022, Ian Santopietro
-All rights reserved.
-
-This file is part of RepoLib.
-
-RepoLib is free software: you can redistribute it and/or modify
-it under the terms of the GNU Lesser General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-RepoLib 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 Lesser General Public License for more details.
-
-You should have received a copy of the GNU Lesser General Public License
-along with RepoLib. If not, see .
-"""
-
-import logging
-from pathlib import Path
-
-import dbus
-
-from repolib.key import SourceKey
-
-from ..source import Source, SourceError
-from ..file import SourceFile
-from .. import util
-
-BASE_FORMAT = util.SourceFormat.DEFAULT
-BASE_URL = 'http://apt.pop-os.org/staging'
-BASE_COMPS = 'main'
-BASE_KEYURL = 'https://raw.githubusercontent.com/pop-os/pop/master/scripts/.iso.asc'
-
-DEFAULT_FORMAT = util.SourceFormat.DEFAULT
-
-prefix = 'popdev'
-delineator = ':'
-
-class PopdevSource(Source):
- """ PopDev Source shortcut
-
- These are given in the format popdev:branchname.
-
- Arguments:
- shortcut (str): The ppa: shortcut to process
- """
- prefs_dir = Path('/etc/apt/preferences.d')
- default_format = BASE_FORMAT
-
- @staticmethod
- def validator(shortcut:str) -> bool:
- """Determine whether a PPA shortcut is valid.
-
- Arguments:
- shortcut(str): The shortcut to validate
-
- Returns: bool
- `True` if the PPA is valid, otherwise False
- """
- if '/' in shortcut:
- return False
-
- shortcut_split = shortcut.split(':')
- try:
- if not shortcut_split[1]:
- return False
- except IndexError:
- return False
-
- if shortcut.startswith(f'{prefix}:'):
- shortlist = shortcut.split(':')
- if len(shortlist) > 0:
- return True
-
- return False
-
- def __init__(self, *args, line='', fetch_data=True, **kwargs):
- if line:
- if not line.startswith('ppa:'):
- raise SourceError(f'The PPA shortcut {line} is malformed')
- super().__init__(args, kwargs)
- self.log = logging.getLogger(__name__)
- self.line = line
- self.twin_source:bool = True
- self.prefs_path = None
- self.branch_name:str = ''
- self.branch_url:str = ''
- if line:
- self.load_from_shortcut(line)
-
- def tasks_save(self, *args, **kwargs) -> None:
- super().tasks_save(*args, **kwargs)
- self.log.info('Saving prefs file for %s', self.ident)
- prefs_contents = 'Package: *\n'
- prefs_contents += f'Pin: release o=pop-os-staging-{self.branch_url}\n'
- prefs_contents += 'Pin-Priority: 1002\n'
-
- self.log.debug('%s prefs for pin priority:\n%s', self.ident, prefs_contents)
-
- try:
- with open(self.prefs, mode='w') as prefs_file:
- prefs_file.write(prefs_contents)
- except PermissionError:
- bus = dbus.SystemBus()
- privileged_object = bus.get_object('org.pop_os.repolib', '/Repo')
- privileged_object.output_prefs_to_disk(str(self.prefs), prefs_contents)
-
- self.log.debug('Pin priority saved for %s', self.ident)
-
-
- def get_description(self) -> str:
- return f'Pop Development Staging branch'
-
-
- def load_from_data(self, data: list) -> None:
- self.log.debug('Loading line %s', data[0])
- self.load_from_shortcut(shortcut=data[0])
-
- def load_from_shortcut(self, shortcut:str='', meta:bool=True, get_key:bool=True) -> None:
- """Translates the shortcut line into a full repo.
-
- Arguments:
- shortcut(str): The shortcut to load, if one hasn't been loaded yet.
- """
- self.reset_values()
- if shortcut:
- self.line = shortcut
-
- if not self.line:
- raise SourceError('No PPA shortcut provided')
-
- if not self.validator(self.line):
- raise SourceError(f'The line {self.line} is malformed')
-
- self.log.debug('Loading shortcut %s', self.line)
-
- self.info_parts = shortcut.split(delineator)
- self.branch_url = ':'.join(self.info_parts[1:])
- self.branch_name = util.scrub_filename(name=self.branch_url)
- self.log.debug('Popdev branch name: %s', self.branch_name)
-
- self.ident = f'{prefix}-{self.branch_name}'
- if f'{self.ident}.{BASE_FORMAT.value}' not in util.files:
- new_file = SourceFile(name=self.ident)
- new_file.format = BASE_FORMAT
- self.file = new_file
- util.files[str(self.file.path)] = self.file
- else:
- self.file = util.files[str(self.file.path)]
-
- self.file.add_source(self)
-
- self.name = f'Pop Development Branch {self.branch_name}'
- self.uris = [f'{BASE_URL}/{self.branch_url}']
- self.suites = [util.DISTRO_CODENAME]
- self.components = [BASE_COMPS]
-
- key = SourceKey(name='popdev')
- key.load_key_data(url=BASE_KEYURL)
- self.key = key
- self.signed_by = str(self.key.path)
-
- self.prefs_path = self.prefs_dir / f'pop-os-staging-{self.branch_name}'
- self.prefs = self.prefs_path
-
- self.enabled = True
diff --git a/archive/repolib/shortcuts/ppa.py b/archive/repolib/shortcuts/ppa.py
deleted file mode 100644
index 624ac4e..0000000
--- a/archive/repolib/shortcuts/ppa.py
+++ /dev/null
@@ -1,274 +0,0 @@
-#!/usr/bin/python3
-
-"""
-Copyright (c) 2022, Ian Santopietro
-All rights reserved.
-
-This file is part of RepoLib.
-
-RepoLib is free software: you can redistribute it and/or modify
-it under the terms of the GNU Lesser General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-RepoLib 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 Lesser General Public License for more details.
-
-You should have received a copy of the GNU Lesser General Public License
-along with RepoLib. If not, see .
-"""
-
-import logging
-
-from repolib.key import SourceKey
-
-from ..source import Source, SourceError
-from ..file import SourceFile
-from .. import util
-
-try:
- from launchpadlib.launchpad import Launchpad
- from lazr.restfulclient.errors import BadRequest, NotFound, Unauthorized
-except ImportError:
- raise SourceError(
- 'Missing optional dependency "launchpadlib". Try `sudo apt install '
- 'python3-launchpadlib` to install it.'
- )
-
-BASE_FORMAT = util.SourceFormat.LEGACY
-BASE_URL = 'http://ppa.launchpad.net'
-BASE_DIST = 'ubuntu'
-BASE_COMPS = 'main'
-
-DEFAULT_FORMAT = util.SourceFormat.LEGACY
-
-prefix = 'ppa'
-delineator = ':'
-
-class PPASource(Source):
- """ PPA Source shortcut
-
- These are given in the format ppa:owner/name. Much of this code is adapted
- from SoftwareProperties.
-
- Arguments:
- shortcut (str): The ppa: shortcut to process
- fetch_data (bool): Whether to try and fetch metadata from Launchpad.
- """
-
- default_format = BASE_FORMAT
-
- @staticmethod
- def validator(shortcut:str) -> bool:
- """Determine whether a PPA shortcut is valid.
-
- Arguments:
- shortcut(str): The shortcut to validate
-
- Returns: bool
- `True` if the PPA is valid, otherwise False
- """
-
- if shortcut.startswith(f'{prefix}:'):
- shortlist = shortcut.split('/')
- if len(shortlist) > 1:
- return True
- return False
-
- def __init__(self, *args, line='', fetch_data=True, **kwargs):
- if line:
- if not line.startswith('ppa:'):
- raise SourceError(f'The PPA shortcut {line} is malformed')
- super().__init__(args, kwargs)
- self.log = logging.getLogger(__name__)
- self.line = line
- self.ppa = None
- self.twin_source = True
- self._displayname = ''
- self._description = ''
- if line:
- self.load_from_shortcut(self.line)
-
- def get_description(self) -> str:
- output:str = ''
- output += self.displayname
- output += '\n\n'
- output += self.description
- return output
-
- def load_from_data(self, data: list) -> None:
- self.load_from_shortcut(shortcut=data[0])
-
- def load_from_shortcut(self, shortcut:str='', meta:bool=True, key:bool=True) -> None:
- """Translates the shortcut line into a full repo.
-
- Arguments:
- shortcut(str): The shortcut to load, if one hasn't been loaded yet.
- meta(bool): Whether to fetch repo metadata from Launchpad
- key(bool): Whether to fetch and install a signing key
- """
- self.reset_values()
- if shortcut:
- self.line = shortcut
-
- if not self.line:
- raise SourceError('No PPA shortcut provided')
-
- if not self.validator(self.line):
- raise SourceError(f'The line {self.line} is malformed')
-
- line = self.line.replace(prefix + delineator, '')
- self.info_parts = line.split('/')
- ppa_owner = self.info_parts[0]
- ppa_name = self.info_parts[1]
-
- self.ident = f'{prefix}-{ppa_owner}-{ppa_name}'
- if f'{self.ident}.{BASE_FORMAT.value}' not in util.files:
- new_file = SourceFile(name=self.ident)
- new_file.format = BASE_FORMAT
- self.file = new_file
- util.files[str(self.file.path)] = self.file
- else:
- self.file = util.files[str(self.file.path)]
-
- self.file.add_source(self)
-
- self.name = self.ident
- self.uris = [f'{BASE_URL}/{ppa_owner}/{ppa_name}/{BASE_DIST}']
- self.suites = [util.DISTRO_CODENAME]
- self.components = [BASE_COMPS]
-
- if meta or key:
- self.ppa = get_info_from_lp(ppa_owner, ppa_name)
- self.displayname = self.ppa.displayname
- self.description = self.ppa.description
-
- if self.ppa and meta:
- self.name = self.ppa.displayname
-
- if self.ppa and key:
- repo_key = SourceKey(name=self.ident)
- if str(repo_key.path) not in util.keys:
- repo_key.load_key_data(fingerprint=self.ppa.fingerprint)
- util.keys[str(repo_key.path)] = repo_key
- self.key:SourceKey = repo_key
- else:
- self.key = util.keys[repo_key.path]
- self.signed_by = str(self.key.path)
-
- self.enabled = True
-
- @property
- def displayname(self) -> str:
- """The name of the PPA provided by launchpad"""
- if self._displayname:
- return self._displayname
- if self.ppa:
- self._displayname = self.ppa.displayname
- return self._displayname
-
- @displayname.setter
- def displayname(self, displayname) -> None:
- """Cache this for use without hitting LP"""
- self._displayname = displayname
-
- @property
- def description(self) -> str:
- """The description of the PPA provided by Launchpad"""
- if self._description:
- return self._description
- if self.ppa:
- self._description = self.ppa.description
- return self._description
-
- @description.setter
- def description(self, desc) -> None:
- """Cache this for use without hitting LP"""
- self._description = desc
-
-class PPA:
- """ An object to fetch data from PPAs.
-
- Portions of this class were adapted from Software Properties
- """
-
- def __init__(self, teamname, ppaname):
- self.teamname = teamname
- self.ppaname = ppaname
- self._lap = None
- self._lpteam = None
- self._lpppa = None
- self._signing_key_data = None
- self._fingerprint = None
-
- @property
- def lap(self):
- """ The Launchpad Object."""
- if not self._lap:
- self._lap = Launchpad.login_anonymously(
- f'{self.__module__}.{self.__class__.__name__}',
- service_root='production',
- version='devel'
- )
- return self._lap
-
- @property
- def lpteam(self):
- """ The Launchpad object for the PPA's owner."""
- if not self._lpteam:
- try:
- self._lpteam = self.lap.people(self.teamname) # type: ignore (This won't actually be unbound because of the property)
- except NotFound as err:
- msg = f'User/Team "{self.teamname}" not found'
- raise SourceError(msg) from err
- except Unauthorized as err:
- msg = f'Invalid user/team name "{self.teamname}"'
- raise SourceError(msg) from err
- return self._lpteam
-
- @property
- def lpppa(self):
- """ The Launchpad object for the PPA."""
- if not self._lpppa:
- try:
- self._lpppa = self.lpteam.getPPAByName(name=self.ppaname)
- except NotFound as err:
- msg = f'PPA "{self.teamname}/{self.ppaname}"" not found'
- raise SourceError(msg) from err
- except BadRequest as err:
- msg = f'Invalid PPA name "{self.ppaname}"'
- raise SourceError(msg) from err
- return self._lpppa
-
- @property
- def description(self) -> str:
- """str: The description of the PPA."""
- return self.lpppa.description or ''
-
- @property
- def displayname(self) -> str:
- """ str: the fancy name of the PPA."""
- return self.lpppa.displayname or ''
-
- @property
- def fingerprint(self):
- """ str: the fingerprint of the signing key."""
- if not self._fingerprint:
- self._fingerprint = self.lpppa.signing_key_fingerprint
- return self._fingerprint
-
-
-def get_info_from_lp(owner_name, ppa):
- """ Attempt to get information on a PPA from launchpad over the internet.
-
- Arguments:
- owner_name (str): The Launchpad user owning the PPA.
- ppa (str): The name of the PPA
-
- Returns:
- json: The PPA information as a JSON object.
- """
- ppa = PPA(owner_name, ppa)
- return ppa
diff --git a/archive/repolib/source.py b/archive/repolib/source.py
deleted file mode 100644
index 889221b..0000000
--- a/archive/repolib/source.py
+++ /dev/null
@@ -1,920 +0,0 @@
-#!/usr/bin/python3
-
-"""
-Copyright (c) 2022, Ian Santopietro
-All rights reserved.
-
-This file is part of RepoLib.
-
-RepoLib is free software: you can redistribute it and/or modify
-it under the terms of the GNU Lesser General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-RepoLib 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 Lesser General Public License for more details.
-
-You should have received a copy of the GNU Lesser General Public License
-along with RepoLib. If not, see .
-"""
-
-import logging
-from pathlib import Path
-
-from debian import deb822
-
-from .parsedeb import ParseDeb
-from .key import SourceKey
-from . import util
-
-DEFAULT_FORMAT = util.SourceFormat.LEGACY
-
-class SourceError(util.RepoError):
- """ Exception from a source object."""
-
- def __init__(self, *args, code=1, **kwargs):
- """Exception with a source object
-
- Arguments:
- code (:obj:`int`, optional, default=1): Exception error code.
- """
- super().__init__(*args, **kwargs)
- self.code = code
-
-class Source(deb822.Deb822):
- """A DEB822 object representing a single software source.
-
- Attributes:
- ident(str): The unique id for this source
- name(str): The user-readable name for this source
- enabled(bool): Whether or not the source is enabled
- types([SourceType]): A list of repository types for this source
- uris([str]): A list of possible URIs for this source
- suites([str]): A list of enabled suites for this source
- components([str]): A list of enabled components for this source
- comments(str): Comments for this source
- signed_by(Path): The path to this source's key file
- file(SourceFile): The file this source belongs to
- key(SourceKey): The key which signs this source
- """
-
- default_format = DEFAULT_FORMAT
-
- @staticmethod
- def validator(shortcut:str) -> bool:
- """Determine whether a deb line is valid.
-
- Arguments:
- shortcut(str): The shortcut to validate
-
- Returns: bool
- `True` if the PPA is valid, otherwise False
- """
- shortcut_list:list = shortcut.split()
-
- if not shortcut.startswith('deb'):
- return False
-
- if not len(shortcut_list) > 3:
- return False
-
- if not util.validate_debline:
- return False
-
- if len(shortcut_list) == 3 and '/' not in shortcut_list[-1]:
- return False
-
- return True
-
- def __init__(self, *args, file=None, **kwargs) -> None:
- """Initialize this source object"""
- self.log = logging.getLogger(__name__)
- super().__init__(*args, **kwargs)
- self.reset_values()
- self.file = file
- self.twin_source = False
- self.twin_enabled = False
-
- def __repr__(self):
- """type: () -> str"""
- # Append comments to the item
- # if self.options:
-
- if self.comments:
- self['Comments'] = '# '
- self['Comments'] += ' # '.join(self.comments)
-
- rep:str = '{%s}' % ', '.join(['%r: %r' % (k, v) for k, v in self.items()])
-
- rep:str = '{'
- for key in self:
- rep += f"{util.PRETTY_PRINT}'{key}': '{self[key]}', "
-
- rep = rep[:-2]
- rep += f"{util.PRETTY_PRINT.replace(' ', '')}"
- rep += '}'
-
- if self.comments:
- self.pop('Comments')
-
- return rep
-
- def __bool__(self) -> bool:
- has_uri:bool = len(self.uris) > 0
- has_suite:bool = len(self.suites) > 0
- has_component:bool = len(self.components) > 0
-
- if has_uri and has_suite and has_component:
- return True
- return False
-
-
- def get_description(self) -> str:
- """Get a UI-compatible description for a source.
-
- Returns: (str)
- The formatted description.
- """
- return self.name
-
- def reset_values(self) -> None:
- """Reset the default values for all attributes"""
- self.log.info('Resetting source info')
- self.ident = ''
- self.name = ''
- self.enabled = True
- self.types = [util.SourceType.BINARY]
- self.uris = []
- self.suites = []
- self.components = []
- self.comments = []
- self.signed_by = None
- self.architectures = ''
- self.languages = ''
- self.targets = ''
- self.pdiffs = ''
- self.by_hash = ''
- self.allow_insecure = ''
- self.allow_weak = ''
- self.allow_downgrade_to_insecure = ''
- self.trusted = ''
- self.signed_by = ''
- self.check_valid_until = ''
- self.valid_until_min = ''
- self.valid_until_max = ''
- self.prefs = ''
- self._update_legacy_options()
- self.file = None
- self.key = None
-
- def load_from_data(self, data:list) -> None:
- """Loads source information from the provided data
-
- Should correctly load either a lecagy Deb line (optionally with
- preceeding comment) or a DEB822 source.
-
- Arguments:
- data(list): the data to load into the source.
- """
- self.log.info('Loading source from data')
- self.reset_values()
-
- if util.validate_debline(data[0]): # Legacy Source
- if len(data) > 1:
- raise SourceError(
- f'The source is a legacy source but contains {len(data)} entries. '
- 'It may only contain one entry.'
- )
- deb_parser = ParseDeb()
- parsed_debline = deb_parser.parse_line(data[0])
- self.ident = parsed_debline['ident']
- self.name = parsed_debline['name']
- self.enabled = parsed_debline['enabled']
- self.types = [parsed_debline['repo_type']]
- self.uris = [parsed_debline['uri']]
- self.suites = [parsed_debline['suite']]
- self.components = parsed_debline['components']
- for key in parsed_debline['options']:
- self[key] = parsed_debline['options'][key]
- self._update_legacy_options()
- for comment in parsed_debline['comments']:
- self.comments.append(comment)
- if self.comments == ['']:
- self.comments = []
-
- if not self.name:
- self.name = self.generate_default_name()
-
- if self.signed_by:
- self.load_key()
- return
-
- # DEB822 Source
- super().__init__(sequence=data)
- if self.signed_by:
- self.load_key()
- return
-
- @property
- def sourcecode_enabled(self) -> bool:
- """`True` if this source also provides source code, otherwise `False`"""
- if util.SourceType.SOURCECODE in self.types:
- return True
- return False
-
- @sourcecode_enabled.setter
- def sourcecode_enabled(self, enabled) -> None:
- """Accept a variety of input values"""
- types = [util.SourceType.BINARY]
- if enabled in util.true_values:
- types.append(util.SourceType.SOURCECODE)
- self.types = types
-
-
- def generate_default_ident(self, prefix='') -> str:
- """Generates a suitable ID for the source
-
- Returns: str
- A sane default-id
- """
- ident:str = ''
- if len(self.uris) > 0:
- uri:str = self.uris[0].replace('/', ' ')
- uri_list:list = uri.split()
- uri_str:str = '-'.join(uri_list[1:])
- branch_name:str = util.scrub_filename(uri_str)
- ident = f'{prefix}{branch_name}'
- ident += f'-{self.types[0].ident()}'
- try:
- if not self['X-Repolib-ID']:
- self['X-Repolib-ID'] = ident
- except KeyError:
- self['X-Repolib-ID'] = ident
- return ident
-
- def generate_default_name(self) -> str:
- """Generate a default name based on the ident
-
- Returns: str
- A name based on the ident
- """
- name:str = self.ident
- try:
- name = self['X-Repolib-Name']
- except KeyError:
- self['X-Repolib-Name'] = self.ident
- return self['X-Repolib-Name']
-
- if not name:
- self['X-Repolib-Name'] = self.ident
-
- return self['X-Repolib-Name']
-
- def load_key(self, ignore_errors:bool = True) -> None:
- """Finds and loads the signing key from the system
-
- Arguments:
- ignore_errors(bool): If `False`, throw a SourceError exception if
- the key can't be found/doesn't exist (Default: `True`)
- """
- self.log.info('Finding key for source %s', self.ident)
- if not self.signed_by:
- if ignore_errors:
- self.log.warning('No key configured for source %s', self.ident)
- else:
- raise SourceError('No key configured for source {self.ident}')
-
- if self.signed_by not in util.keys:
- new_key = SourceKey()
- new_key.reset_path(path=self.signed_by)
- self.key = new_key
- util.keys[str(new_key.path)] = new_key
- else:
- self.key = util.keys[self.signed_by]
-
- def save(self) -> None:
- """Proxy method to save the source"""
- if not self.file == None:
- self.file.save()
-
- def output_legacy(self) -> str:
- """Outputs a legacy representation of this source
-
- Note: this is expected to fail if there is more than one type, URI, or
- Suite; the one-line format does not support having multiple of these
- properties.
-
- Returns: str
- The source output formatted as Legacy
- """
- return self.legacy
-
- def output_822(self) -> str:
- """Outputs a DEB822 representation of this source
-
- Returns: str
- The source output formatted as Deb822
- """
- return self.deb822
-
- def output_ui(self) -> str:
- """Outputs a string representation of this source for use in UIs
-
- Returns: str
- The source output string
- """
- return self.ui
-
- def prop_append(self, prop:list, item:str) -> None:
- """Appends an item to a list property of this source.
- NOTE: List properties are `types`, `uris`, `suites`, and `components`.
-
- Arguments:
- prop(list): The property on which to append the item.
- item(str): The item to append to the propery
- """
- _list = prop
- _list.append(item)
- prop = _list
-
- def tasks_save(self, *args, **kwargs) -> None:
- """Extra tasks to perform when saving a source"""
- return
-
- ## Properties are stored/retrieved from the underlying Deb822 dict
- @property
- def has_required_parts(self) -> bool:
- """(RO) True if all required attributes are set, otherwise false."""
- required_parts = ['uris', 'suites', 'ident']
-
- for attr in required_parts:
- if len(getattr(self, attr)) < 1:
- return False
-
- return True
-
-
- @property
- def ident(self) -> str:
- """The ident for this source within the file"""
- try:
- return self['X-Repolib-ID']
- except KeyError:
- return ''
-
-
- @ident.setter
- def ident(self, ident: str) -> None:
- ident = util.scrub_filename(ident)
- self['X-Repolib-ID'] = ident
-
-
- @property
- def name(self) -> str:
- """The human-friendly name for this source"""
- try:
- _name = self['X-Repolib-Name']
- except KeyError:
- _name = ''
-
- if not _name:
- self.generate_default_name()
- return self['X-Repolib-Name']
-
- @name.setter
- def name(self, name: str) -> None:
- self['X-Repolib-Name'] = name
-
-
- @property
- def enabled(self) -> util.AptSourceEnabled:
- """Whether or not the source is enabled/active"""
- try:
- enabled = self['Enabled'] in util.true_values
- except KeyError:
- return util.AptSourceEnabled.FALSE
-
- if enabled and self.has_required_parts:
- return util.AptSourceEnabled.TRUE
- return util.AptSourceEnabled.FALSE
-
- @enabled.setter
- def enabled(self, enabled) -> None:
- """For convenience, accept a wide varietry of input value types"""
- self['Enabled'] = 'no'
- if enabled in util.true_values:
- self['Enabled'] = 'yes'
-
-
- @property
- def types(self) -> list:
- """The list of source types for this source"""
- _types:list = []
- try:
- for sourcetype in self['types'].split():
- _types.append(util.SourceType(sourcetype))
- except KeyError:
- pass
- return _types
-
- @types.setter
- def types(self, types: list) -> None:
- """Turn this list into a string of values for storage"""
- self['Types'] = ''
- _types:list = []
- for sourcetype in types:
- if sourcetype not in _types:
- _types.append(sourcetype)
- for sourcetype in _types:
- self['Types'] += f'{sourcetype.value} '
- self['Types'] = self['Types'].strip()
-
-
- @property
- def uris(self) -> list:
- """The list of URIs for this source"""
- try:
- return self['URIs'].split()
- except KeyError:
- return []
-
- @uris.setter
- def uris(self, uris: list) -> None:
- self['URIs'] = ' '.join(uris).strip()
-
-
- @property
- def suites(self) -> list:
- """The list of URIs for this source"""
- try:
- return self['Suites'].split()
- except KeyError:
- return []
-
- @suites.setter
- def suites(self, suites: list) -> None:
- self['Suites'] = ' '.join(suites).strip()
-
-
- @property
- def components(self) -> list:
- """The list of URIs for this source"""
- try:
- return self['Components'].split()
- except KeyError:
- return []
-
- @components.setter
- def components(self, components: list) -> None:
- self['Components'] = ' '.join(components).strip()
-
-
- @property
- def options(self) -> dict:
- """The options for this source"""
- return self._options
-
- @options.setter
- def options(self, options:dict) -> None:
- if 'Signed-By' in options:
- self.signed_by = options['Signed-By']
- if self.signed_by:
- options.pop('Signed-By')
- self._options = options
-
- @property
- def prefs(self):
- """The path to any apt preferences files for this source."""
- try:
- prefs = self['X-Repolib-Prefs']
- except KeyError:
- prefs = ''
-
- if prefs:
- return Path(prefs)
- return Path()
-
- @prefs.setter
- def prefs(self, prefs):
- """Accept a str or a Path-like object"""
- try:
- del self['X-Repolib-Prefs']
- except KeyError:
- pass
-
- if prefs:
- prefs_str = str(prefs)
- self['X-Repolib-Prefs'] = prefs_str
-
-
- ## Option properties
-
- @property
- def architectures (self) -> str:
- """architectures option"""
- try:
- return self['Architectures']
- except KeyError:
- return ''
-
- @architectures.setter
- def architectures(self, data) -> None:
- try:
- self.pop('Architectures')
- except KeyError:
- pass
-
- if data:
- self['Architectures'] = data
- self._update_legacy_options()
-
-
- @property
- def languages (self) -> str:
- """languages option"""
- try:
- return self['Languages']
- except KeyError:
- return ''
-
- @languages.setter
- def languages(self, data) -> None:
- try:
- self.pop('Languages')
- except KeyError:
- pass
-
- if data:
- self['Languages'] = data
- self._update_legacy_options()
-
-
- @property
- def targets (self) -> str:
- """targets option"""
- try:
- return self['Targets']
- except KeyError:
- return ''
-
- @targets.setter
- def targets(self, data) -> None:
- try:
- self.pop('Targets')
- except KeyError:
- pass
-
- if data:
- self['Targets'] = data
- self._update_legacy_options()
-
-
- @property
- def pdiffs (self) -> str:
- """pdiffs option"""
- try:
- return self['Pdiffs']
- except KeyError:
- return ''
-
- @pdiffs.setter
- def pdiffs(self, data) -> None:
- try:
- self.pop('Pdiffs')
- except KeyError:
- pass
-
- if data:
- self['Pdiffs'] = data
- self._update_legacy_options()
-
-
- @property
- def by_hash (self) -> str:
- """by_hash option"""
- try:
- return self['By-Hash']
- except KeyError:
- return ''
-
- @by_hash.setter
- def by_hash(self, data) -> None:
- try:
- self.pop('By-Hash')
- except KeyError:
- pass
-
- if data:
- self['By-Hash'] = data
- self._update_legacy_options()
-
-
- @property
- def allow_insecure (self) -> str:
- """allow_insecure option"""
- try:
- return self['Allow-Insecure']
- except KeyError:
- return ''
-
- @allow_insecure.setter
- def allow_insecure(self, data) -> None:
- try:
- self.pop('Allow-Insecure')
- except KeyError:
- pass
-
- if data:
- self['Allow-Insecure'] = data
- self._update_legacy_options()
-
-
- @property
- def allow_weak (self) -> str:
- """allow_weak option"""
- try:
- return self['Allow-Weak']
- except KeyError:
- return ''
-
- @allow_weak.setter
- def allow_weak(self, data) -> None:
- try:
- self.pop('Allow-Weak')
- except KeyError:
- pass
-
- if data:
- self['Allow-Weak'] = data
- self._update_legacy_options()
-
-
- @property
- def allow_downgrade_to_insecure (self) -> str:
- """allow_downgrade_to_insecure option"""
- try:
- return self['Allow-Downgrade-To-Insecure']
- except KeyError:
- return ''
-
- @allow_downgrade_to_insecure.setter
- def allow_downgrade_to_insecure(self, data) -> None:
- try:
- self.pop('Allow-Downgrade-To-Insecure')
- except KeyError:
- pass
-
- if data:
- self['Allow-Downgrade-To-Insecure'] = data
- self._update_legacy_options()
-
-
- @property
- def trusted (self) -> str:
- """trusted option"""
- try:
- return self['Trusted']
- except KeyError:
- return ''
-
- @trusted.setter
- def trusted(self, data) -> None:
- try:
- self.pop('Trusted')
- except KeyError:
- pass
-
- if data:
- self['Trusted'] = data
- self._update_legacy_options()
-
-
- @property
- def signed_by (self) -> str:
- """signed_by option"""
- try:
- return self['Signed-By']
- except KeyError:
- return ''
-
- @signed_by.setter
- def signed_by(self, data) -> None:
- try:
- self.pop('Signed-By')
- except KeyError:
- pass
-
- if data:
- self['Signed-By'] = data
- self._update_legacy_options()
-
-
- @property
- def check_valid_until (self) -> str:
- """check_valid_until option"""
- try:
- return self['Check-Valid-Until']
- except KeyError:
- return ''
-
- @check_valid_until.setter
- def check_valid_until(self, data) -> None:
- try:
- self.pop('Check-Valid-Until')
- except KeyError:
- pass
-
- if data:
- self['Check-Valid-Until'] = data
- self._update_legacy_options()
-
-
- @property
- def valid_until_min (self) -> str:
- """valid_until_min option"""
- try:
- return self['Valid-Until-Min']
- except KeyError:
- return ''
-
- @valid_until_min.setter
- def valid_until_min(self, data) -> None:
- try:
- self.pop('Valid-Until-Min')
- except KeyError:
- pass
-
- if data:
- self['Valid-Until-Min'] = data
- self._update_legacy_options()
-
-
- @property
- def valid_until_max (self) -> str:
- """valid_until_max option"""
- try:
- return self['Valid-Until-Max']
- except KeyError:
- return ''
-
- @valid_until_max.setter
- def valid_until_max(self, data) -> None:
- try:
- self.pop('Valid-Until-Max')
- except KeyError:
- pass
-
- if data:
- self['Valid-Until-Max'] = data
- self._update_legacy_options()
-
- @property
- def default_mirror(self) -> str:
- """The default mirror/URI for the source"""
- try:
- return self['X-Repolib-Default-Mirror']
- except KeyError:
- return ''
-
- @default_mirror.setter
- def default_mirror(self, mirror) -> None:
- if mirror:
- self['X-Repolib-Default-Mirror'] = mirror
- else:
- self['X-Repolib-Default-Mirror'] = ''
-
-
- ## Output Properties
- @property
- def deb822(self) -> str:
- """The DEB822 representation of this source"""
- self._update_legacy_options()
- # comments get handled separately because they're a list, and list
- # properties don't support .append()
- if self.comments:
- self['X-Repolib-Comments'] = '# '
- self['X-Repolib-Comments'] += ' # '.join(self.comments)
- _deb822 = self.dump()
- if self.comments:
- self.pop('X-Repolib-Comments')
- if _deb822:
- return _deb822
- return ''
-
- @property
- def ui(self) -> str:
- """The UI-friendly representation of this source"""
- self._update_legacy_options()
- _ui_list:list = self.deb822.split('\n')
- ui_output: str = f'{self.ident}:\n'
- for line in _ui_list:
- key = line.split(':')[0]
- if key not in util.output_skip_keys:
- if line:
- ui_output += f'{line}\n'
- for key in util.keys_map:
- ui_output = ui_output.replace(key, util.keys_map[key])
- return ui_output
-
- @property
- def legacy(self) -> str:
- """The legacy/one-line format representation of this source"""
- self._update_legacy_options()
-
- if str(self.prefs) != '.':
- raise SourceError(
- 'Apt Preferences files can only be used with DEB822-format sources.'
- )
-
- sourcecode = self.sourcecode_enabled
- if len(self.types) > 1:
- self.twin_source = True
- self.types = [util.SourceType.BINARY]
- sourcecode = True
-
- legacy = ''
-
- legacy += self._generate_legacy_output()
- if self.twin_source:
- legacy += '\n'
- legacy += self._generate_legacy_output(sourcecode=True, enabled=sourcecode)
-
- return legacy
-
- def _generate_legacy_output(self, sourcecode=False, enabled=True) -> str:
- """Generate a string of the current source in legacy format"""
- legacy = ''
-
- if len(self.types) > 1:
- self.twin_source = True
- self.types = [util.SourceType.BINARY]
- for attr in ['types', 'uris', 'suites']:
- if len(getattr(self, attr)) > 1:
- msg = f'The source has too many {attr}.'
- msg += f'Legacy-format sources support one {attr[:-1]} only.'
- raise SourceError(msg)
-
- if not self.enabled.get_bool() and not sourcecode:
- legacy += '# '
-
- if sourcecode and not enabled:
- legacy += '# '
-
- if sourcecode:
- legacy += 'deb-src '
- else:
- legacy += self.types[0].value
- legacy += ' '
-
- options_string = self._legacy_options()
- if options_string:
- legacy += '['
- legacy += options_string
- legacy = legacy.strip()
- legacy += '] '
-
- legacy += f'{self.uris[0]} '
- legacy += f'{self.suites[0]} '
-
- for component in self.components:
- legacy += f'{component} '
-
- legacy += f' ## X-Repolib-Name: {self.name}'
- legacy += f' # X-Repolib-ID: {self.ident}'
- if self.comments:
- for comment in self.comments:
- legacy += f' # {comment}'
-
- return legacy
-
- def _legacy_options(self) -> str:
- """Turn the current options into a oneline-style string
-
- Returns: str
- The one-line-format options string
- """
- options_str = ''
- for key in self.options:
- if self.options[key] != '':
- options_str += f'{key}={self.options[key].replace(" ", ",")} '
- return options_str
-
- def _update_legacy_options(self) -> None:
- """Updates the current set of legacy options"""
- self.options = {
- 'arch': self.architectures,
- 'lang': self.languages,
- 'target': self.targets,
- 'pdiffs': self.pdiffs,
- 'by-hash': self.by_hash,
- 'allow-insecure': self.allow_insecure,
- 'allow-weak': self.allow_weak,
- 'allow-downgrade-to-insecure': self.allow_downgrade_to_insecure,
- 'trusted': self.trusted,
- 'signed-by': self.signed_by,
- 'check-valid-until': self.check_valid_until,
- 'valid-until-min': self.valid_until_min,
- 'valid-until-max': self.valid_until_max,
- }
\ No newline at end of file
diff --git a/archive/repolib/system.py b/archive/repolib/system.py
deleted file mode 100644
index b22ef09..0000000
--- a/archive/repolib/system.py
+++ /dev/null
@@ -1,73 +0,0 @@
-#!/usr/bin/python3
-
-"""
-Copyright (c) 2022, Ian Santopietro
-All rights reserved.
-
-This file is part of RepoLib.
-
-RepoLib is free software: you can redistribute it and/or modify
-it under the terms of the GNU Lesser General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-RepoLib 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 Lesser General Public License for more details.
-
-You should have received a copy of the GNU Lesser General Public License
-along with RepoLib. If not, see .
-"""
-
-import logging
-
-from pathlib import Path
-
-from . import util
-from .file import SourceFile
-from .source import Source
-from .shortcuts import popdev, ppa
-
-
-log = logging.getLogger(__name__)
-
-def load_all_sources() -> None:
- """Loads all of the sources present on the system."""
- log.info('Loading all sources')
-
- util.sources.clear()
- util.files.clear()
- util.keys.clear()
- util.errors.clear()
-
- sources_path = Path(util.SOURCES_DIR)
- sources_files = sources_path.glob('*.sources')
- legacy_files = sources_path.glob('*.list')
-
- for file in sources_files:
- try:
- sourcefile = SourceFile(name=file.stem)
- log.debug('Loading %s', file)
- sourcefile.load()
- if file.name not in util.files:
- util.files[file.name] = sourcefile
-
- except Exception as err:
- util.errors[file.name] = err
-
- for file in legacy_files:
- try:
- sourcefile = SourceFile(name=file.stem)
- sourcefile.load()
- util.files[file.name] = sourcefile
- except Exception as err:
- util.errors[file.name] = err
-
- for f in util.files:
- file = util.files[f]
- for source in file.sources:
- if source.ident in util.sources:
- source.ident = f'{file.name}-{source.ident}'
- source.file.save()
- util.sources[source.ident] = source
diff --git a/archive/repolib/unittest/__init__.py b/archive/repolib/unittest/__init__.py
deleted file mode 100644
index e69de29..0000000
diff --git a/archive/repolib/unittest/test_key.py b/archive/repolib/unittest/test_key.py
deleted file mode 100644
index 977324b..0000000
--- a/archive/repolib/unittest/test_key.py
+++ /dev/null
@@ -1,142 +0,0 @@
-#!/usr/bin/python3
-
-"""
-Copyright (c) 2022, Ian Santopietro
-All rights reserved.
-
-This file is part of RepoLib.
-
-RepoLib is free software: you can redistribute it and/or modify
-it under the terms of the GNU Lesser General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-RepoLib 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 Lesser General Public License for more details.
-
-You should have received a copy of the GNU Lesser General Public License
-along with RepoLib. If not, see .
-"""
-
-import unittest
-
-from ..key import SourceKey
-from .. import util, system
-from .. import set_testing
-
-# System76 Signing PubKey, for test import
-KEY_DATA = (
- '-----BEGIN PGP PUBLIC KEY BLOCK-----\n\nmQINBFlL+3MBEADdNM9Xy2t3EtKU1i3R1o'
- '1OCgJqLiDm8OZZq47InYID8oAPKRjd\n0UDVJTrvfsB4oJH97VRi2hGv2xmc19OaFE/NsQBZW/'
- '7/3ypLr8eyaNgvscsmG/WN\ncM1cbMZtwd1b0JOr3bNTzp6WKRI3jo9uRw7duM8FwPjKm76Lbo'
- 'DQbAR+4Szm3O8x\n/om8Gs1MRPUkY2dVz5KzednFLHwy7qnUXR3WRB5K1L9EBZkFDDNqnyViUI'
- 'rE4bTm\nBC9mTg/Xfw/QXUFYz3t/YTYduAU0o1q2yei+8tVAJKh7H9t3PrQ95l3RUUcaAvba\n'
- 'A9zlCrI8fonpxu7eSpkqzT4uCkfxdLVwittl1DumKTEkSXDQ5txY21igbSZZQwBA\nZf9MnFhJ'
- 'fPsEIq2YHRc1FBcQxiAIpnGizv7FgYY5FxmZQ7592dMQOZ00h+lDSQug\nNMxloHCogaXR038u'
- 'IKGTQnQEVcT46FtTRkLMSvbigy+RVSchdu9MEBBPgD3vSv53\nNEobXsLiZ9hF6Hk7XI2WxP5j'
- '1zWTPmzxvf9NDOWz2Sw9Z+ilf252LXoxZQaMngp8\nXL32uvw7q+mjB6F1W/qpe3b32uu7eGNr'
- 'DWJ5veE808hpXXj803TllmRUfMGUrtY9\nk7uUTQQWtrJ5uZ0QmsTk1oJHCPIUjjuiNtQfq28+'
- 'bfg8FEJ/F1N1mB0IvwARAQAB\ntCxQb3AgT1MgKElTTyBTaWduaW5nIEtleSkgPGluZm9Ac3lz'
- 'dGVtNzYuY29tPokC\nNwQTAQIAIgUCWUv7cwIbAwYLCQgHAwIGFQgCCQoLBBYCAwECHgECF4AA'
- 'CgkQIE3Y\nrsM6ev8kXw/4p/8fOH8wM59ZoU0t1+fv3O8dYaDdTVTVIEno9snrsx5A5tbMu59r'
- '\nHoBaxGenv/PB0l8yANhRX+HVmU/l0Sj0lTlEkYzgH/IT2Ne60s1ETgI7DlgSuYyP\nH8wq61'
- '85+2DyE2+R/XcXGq0I++QUq1Y6rS+B4KIyYcgpJotcVNFaZiwuJZE31uLg\nkVMZrm1oObHear'
- '7P2JQTbgsENMZDJEhQBCGKVdnAfVdKUeUrd07syr0cDe3kwY9o\ncNc00bhIh23cLTJE2omok9'
- 'yCsXoeFJlPMyZw8WvEa5oaYWzP4Yw7nF8/27JTzZ70\nDjK2D2xoTkr0cP87LtZulS6FC3lxLu'
- 'Z6hSaxsqoBH8Dd1uyYVEzLDsIRMtSHsXk+\n3kLrr1p7/7/vjGShlYkbLtP4jWnlHc6vSxIzm/'
- 'MQmQMCfjeo3QH7GGw88mYtXngQ\n/Zna6wz0oL6pGM/4t90SCxTxRqCnoxMxzkcpt9n42bj79g'
- 'rESOMH4wm3ExfuPk7I\nDtY+SqzIq0QvoPbC3XJLusWVgwUsRF2FpTTRTHEiWEMjWDKDVEyT4K'
- '1k1k3f/gi2\n6LdtXwqDwzUvJJU5HYwVFywt+0jt5F0ZlTlPizz3iHw4gMLOielRShl+gZrU2U'
- '0O\naj1Hyts9LymEKMUvRQGwMqCZcXo6sGjs59tTsfeGX16PTOyBri8eoLkCDQRZS/tz\nARAA'
- 'pD9IWm4zS1AuBcOTuvh1E/ciKHGIUtW3JftD9ah8loEeckakgG5Xn9he1X6J\nyxPULpsptcCC'
- 'cKXlw853ZQK9PLQJX6moWLH+qf2Zo3UAn/YEsWk+KsHoxPXHNUds\nu/j6UKkqEk8c7H92hUo8'
- 'aWghO3p4HDVJ9KmGtueQ3jOv8Qun7Eh9cIo0A59cKmMv\njKUiYHLIJw8bkveQ8rVPul1ZHn56'
- 'ORiBi58vm3tzjI4UWHQMjiKxXT6H5eG/f5K6\nuaK8lljh6n6jhdnQCpBcdtSIbhE/6YRv2+Ig'
- 'L+BRssvprBtx4/sBwKjNNqzWPeGy\nUDHMiF88ETYqZ8DfukQ/e5XuaxjU41g/F8cw8BeVTBMv'
- 'eb1YTyOoWcWvTL+hoBfS\nqYc/lvDHmmJ7/IgeMvUE6KoByP4ub5wX52mJTqgMC4GMhA04BC60'
- 'B+NfVAXLh2pa\nTRJAHoWTDswOxbR6q9zPEFGZzV04B9Y96EavwMpT5IzG2fOPBwvdT0EDnt+v'
- 'Q/iB\nc9O7CvkRTROAV+RoNCLY2XU8yNc/XxuI66PCE4Q96jW4uDzHvi6sPW/glsfRi2NT\nRW'
- 'CO15KMVf0aypXeBpSbHIXIYGdXRQRpw980IW6PrElPpqZ5/DGbkXei5CuruF2R\nmltuu3MqYQ'
- 'jcUvP9T7s0e5GAFgQFrR/8q29nVULq8IF4vzUAEQEAAYkCHwQYAQIA\nCQUCWUv7cwIbDAAKCR'
- 'AgTdiuwzp6/wTGD/9Co4gEmTTOW++FneMMJo5K4WqeWVRg\ng1q5+yoVqgWq3k6lLsEC5kxR30'
- '5BAAcvXo9XPKdo62ySYmhIFOpIz/TkeTUxDZaw\nsLtcBxXUME2L5j/1od1V9lxecUvLAgA11o'
- '5Kb8TMKn5ZcmGhadtTLslWQcYsKqhw\nLaYQRlcxLDHYT8DXFkHgDhUMMbpt07dU5v5lIjgtGN'
- 'HRhdS7/lCmSWOBtYapwpAH\nGYSmahN0zO36VHzOB5uwFue0tSoQiBEvLrCV/8ZtT2S5NkXaSm'
- 'isz6B5Vr6DRtWI\nOamW5pMbSL8WQNQ99Kik05ctERjv2NgxI4JQo/a4KKthRrT4JlixXmrfJD'
- 'uPyDPp\nRuTu1Elo6snoqWKQNf1sEPKvcv7EviNxBOhbTKivWrJXMnbOme7+UlNLcq7VAFp3\n'
- 'x5hxk/ap0WqH/hs7+8jMBC8nS402MoM7EyLS0++kbOuEL/Prf3+JxFRqIu5Df77J\n+bUmTtKI'
- 'CV43ikiVWmnP5OuJj2JPSOTR+rLxAQYpyHmo7HKXE63FbH1FVLgsT88+\nEW6VtI01I7EYmKQX'
- 'EqQo52yfeHKDrQjGNVBWMKcXj0SVU+QQ1Ue/4yLwA+74VD2d\nfOyJI22NfTI+3SMAsMQ8L+WV'
- 'QI+58bu7+iEqoEfHCXikE8BtTbJAN4Oob1lrjfOe\n5utH/lMP9suRWw==\n=NL3f\n-----EN'
- 'D PGP PUBLIC KEY BLOCK-----\n'
-)
-
-class KeyTestCase(unittest.TestCase):
- def setUp(self):
- set_testing()
- self.key_data = KEY_DATA
- self.keys_dir = util.KEYS_DIR
- self.key_id = '204DD8AEC33A7AFF'
- self.key_uids = ['Pop OS (ISO Signing Key) ']
- self.key_length = '4096'
- self.key_date = '1498151795'
-
- def test_import_ascii(self):
- key = SourceKey(name='popdev')
- key.load_key_data(ascii=self.key_data)
- key_dict = key.gpg.list_keys()[0]
- key_path = self.keys_dir / 'popdev-archive-keyring.gpg'
-
- self.assertEqual(key.path, key_path)
- self.assertEqual(len(key.gpg.list_keys()), 1)
- self.assertEqual(key_dict['keyid'], self.key_id)
- self.assertEqual(key_dict['uids'], self.key_uids)
- self.assertEqual(key_dict['length'], self.key_length)
- self.assertEqual(key_dict['date'], self.key_date)
-
- def test_key_save_load(self):
- print(self.keys_dir)
- key_path = self.keys_dir / 'popdev-archive-keyring.gpg'
- if key_path.exists():
- key_path.unlink()
-
- self.assertFalse(key_path.exists())
- key_save = SourceKey(name='popdev')
- key_save.load_key_data(ascii=self.key_data)
- key_save.save_gpg()
-
- self.assertTrue(key_save.path.exists())
-
- key_load = SourceKey()
- key_load.reset_path(name='popdev')
- key_dict = key_load.gpg.list_keys()[0]
-
- self.assertEqual(key_load.path, key_path)
- self.assertEqual(len(key_load.gpg.list_keys()), 1)
- self.assertEqual(key_dict['keyid'], self.key_id)
- self.assertEqual(key_dict['uids'], self.key_uids)
- self.assertEqual(key_dict['length'], self.key_length)
- self.assertEqual(key_dict['date'], self.key_date)
-
- def test_delete_key(self):
- key_path = self.keys_dir / 'popdev-archive-keyring.gpg'
- if key_path.exists():
- key_path.unlink()
-
- self.assertFalse(key_path.exists())
-
- self.assertFalse(key_path.exists())
- key_save = SourceKey(name='popdev')
- key_save.load_key_data(ascii=self.key_data)
-
- key_save.save_gpg()
-
- self.assertTrue(key_save.path.exists())
-
- key_load = SourceKey()
- key_load.reset_path(name='popdev')
- key_load.delete_key()
-
- self.assertFalse(key_load.path.exists())
diff --git a/archive/repolib/unittest/test_parsedeb.py b/archive/repolib/unittest/test_parsedeb.py
deleted file mode 100644
index 0a975a0..0000000
--- a/archive/repolib/unittest/test_parsedeb.py
+++ /dev/null
@@ -1,188 +0,0 @@
-#!/usr/bin/python3
-
-"""
-Copyright (c) 2019-2022, Ian Santopietro
-All rights reserved.
-
-This file is part of RepoLib.
-
-RepoLib is free software: you can redistribute it and/or modify
-it under the terms of the GNU Lesser General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-RepoLib 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 Lesser General Public License for more details.
-
-You should have received a copy of the GNU Lesser General Public License
-along with RepoLib. If not, see .
-
-This is a library for parsing deb lines into deb822-format data.
-"""
-
-import unittest
-
-from ..source import Source
-from .. import util
-
-class DebTestCase(unittest.TestCase):
- def test_normal_source(self):
- source = Source()
- source.load_from_data([
- 'deb http://example.com/ suite main'
- ])
- source.generate_default_ident()
- self.assertEqual(source.types, [util.SourceType.BINARY])
- self.assertTrue(source.enabled.get_bool())
- self.assertEqual(source.uris, ['http://example.com/'])
- self.assertEqual(source.suites, ['suite'])
- self.assertEqual(source.components, ['main'])
- self.assertEqual(source.ident, 'example-com-binary')
-
- def test_source_with_multiple_components(self):
- source = Source()
- source.load_from_data([
- 'deb http://example.com/ suite main nonfree'
- ])
- source.generate_default_ident()
- self.assertEqual(source.suites, ['suite'])
- self.assertEqual(source.components, ['main', 'nonfree'])
-
- def test_source_with_option(self):
- source = Source()
- source.load_from_data([
- 'deb [ arch=amd64 ] http://example.com/ suite main'
- ])
- source.generate_default_ident()
- self.assertEqual(source.uris, ['http://example.com/'])
- self.assertEqual(source.architectures, 'amd64')
-
- def test_source_uri_with_brackets(self):
- source = Source()
- source.load_from_data([
- 'deb http://example.com/[release]/ubuntu suite main'
- ])
- source.generate_default_ident()
- self.assertEqual(source.uris, ['http://example.com/[release]/ubuntu'])
-
- def test_source_options_with_colons(self):
- source = Source()
- source.load_from_data([
- 'deb [ arch=arm:2 ] http://example.com/ suite main'
- ])
- source.generate_default_ident()
- self.assertEqual(source.uris, ['http://example.com/'])
- self.assertEqual(source.architectures, 'arm:2')
-
- def test_source_with_multiple_option_values(self):
- source = Source()
- source.load_from_data([
- 'deb [ arch=armel,amd64 ] http://example.com/ suite main'
- ])
- source.generate_default_ident()
- self.assertEqual(source.uris, ['http://example.com/'])
- self.assertEqual(source.architectures, 'armel amd64')
-
- def test_source_with_multiple_options(self):
- source = Source()
- source.load_from_data([
- 'deb [ arch=amd64 lang=en_US ] http://example.com/ suite main'
- ])
- source.generate_default_ident()
- self.assertEqual(source.uris, ['http://example.com/'])
- self.assertEqual(source.architectures, 'amd64')
- self.assertEqual(source.languages, 'en_US')
-
- def test_source_with_multiple_options_with_multiple_values(self):
- source = Source()
- source.load_from_data([
- 'deb [ arch=amd64,armel lang=en_US,en_CA ] '
- 'http://example.com/ suite main'
- ])
- source.generate_default_ident()
- self.assertEqual(source.uris, ['http://example.com/'])
- self.assertEqual(source.architectures, 'amd64 armel')
- self.assertEqual(source.languages, 'en_US en_CA')
-
- def test_source_uri_with_brackets_and_options(self):
- source = Source()
- source.load_from_data([
- 'deb [ arch=amd64 lang=en_US,en_CA ] '
- 'http://example][.com/[release]/ubuntu suite main'
- ])
- source.generate_default_ident()
- self.assertEqual(source.uris, ['http://example][.com/[release]/ubuntu'])
- self.assertEqual(source.architectures, 'amd64')
- self.assertEqual(source.languages, 'en_US en_CA')
-
- def test_source_uri_with_brackets_and_options_with_colons(self):
- source = Source()
- source.load_from_data([
- 'deb [ arch=amd64,arm:2 lang=en_US,en_CA ] '
- 'http://example][.com/[release]/ubuntu suite main'
- ])
- source.generate_default_ident()
- self.assertEqual(source.uris, ['http://example][.com/[release]/ubuntu'])
- self.assertEqual(source.architectures, 'amd64 arm:2')
- self.assertEqual(source.languages, 'en_US en_CA')
-
- def test_worst_case_sourcenario(self):
- source = Source()
- source.load_from_data([
- 'deb [ arch=amd64,arm:2,arm][ lang=en_US,en_CA ] '
- 'http://example][.com/[release:good]/ubuntu suite main restricted '
- 'nonfree not-a-component'
- ])
- source.generate_default_ident()
- self.assertEqual(source.uris, ['http://example][.com/[release:good]/ubuntu'])
- self.assertEqual(source.suites, ['suite'])
- self.assertEqual(source.components, [
- 'main', 'restricted', 'nonfree', 'not-a-component'
- ])
- source.generate_default_ident()
- self.assertEqual(source.architectures, 'amd64 arm:2 arm][')
- self.assertEqual(source.languages, 'en_US en_CA')
-
- def test_source_code_source(self):
- source = Source()
- source.load_from_data([
- 'deb-src http://example.com/ suite main'
- ])
- source.generate_default_ident()
- self.assertEqual(source.types, [util.SourceType.SOURCECODE])
-
- def test_disabled_source(self):
- source = Source()
- source.load_from_data([
- '# deb http://example.com/ suite main'
- ])
- source.generate_default_ident()
- self.assertFalse(source.enabled.get_bool())
-
- def test_disabled_source_without_space(self):
- source = Source()
- source.load_from_data([
- '#deb http://example.com/ suite main'
- ])
- source.generate_default_ident()
- self.assertFalse(source.enabled.get_bool())
-
- def test_source_with_trailing_comment(self):
- source = Source()
- source.load_from_data([
- 'deb http://example.com/ suite main # This is a comment'
- ])
- source.generate_default_ident()
- self.assertEqual(source.suites, ['suite'])
- self.assertEqual(source.components, ['main'])
-
- def test_disabled_source_with_trailing_comment(self):
- source = Source()
- source.load_from_data([
- '# deb http://example.com/ suite main # This is a comment'
- ])
- source.generate_default_ident()
- self.assertEqual(source.suites, ['suite'])
- self.assertEqual(source.components, ['main'])
diff --git a/archive/repolib/unittest/test_popdev.py b/archive/repolib/unittest/test_popdev.py
deleted file mode 100644
index 8207b09..0000000
--- a/archive/repolib/unittest/test_popdev.py
+++ /dev/null
@@ -1,43 +0,0 @@
-#!/usr/bin/python3
-
-"""
-Copyright (c) 2022, Ian Santopietro
-All rights reserved.
-
-This file is part of RepoLib.
-
-RepoLib is free software: you can redistribute it and/or modify
-it under the terms of the GNU Lesser General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-RepoLib 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 Lesser General Public License for more details.
-
-You should have received a copy of the GNU Lesser General Public License
-along with RepoLib. If not, see .
-"""
-
-import unittest
-
-from ..shortcuts import popdev
-from .. import util
-
-class PopdevTestCase(unittest.TestCase):
-
- def test_ppa(self):
- source = popdev.PopdevSource()
-
- # Verification data
- uris_test = ['http://apt.pop-os.org/staging/master']
- signed_test = '/usr/share/keyrings/popdev-archive-keyring.gpg'
- source.load_from_shortcut(shortcut='popdev:master')
-
- self.assertEqual(source.uris, uris_test)
- self.assertEqual(source.ident, 'popdev-master')
- self.assertEqual(source.suites, [util.DISTRO_CODENAME])
- self.assertEqual(source.components, ['main'])
- self.assertEqual(source.types, [util.SourceType.BINARY])
- self.assertTrue(source.signed_by.endswith(signed_test))
\ No newline at end of file
diff --git a/archive/repolib/unittest/test_ppa.py b/archive/repolib/unittest/test_ppa.py
deleted file mode 100644
index 9b346cf..0000000
--- a/archive/repolib/unittest/test_ppa.py
+++ /dev/null
@@ -1,42 +0,0 @@
-#!/usr/bin/python3
-
-"""
-Copyright (c) 2022, Ian Santopietro
-All rights reserved.
-
-This file is part of RepoLib.
-
-RepoLib is free software: you can redistribute it and/or modify
-it under the terms of the GNU Lesser General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-RepoLib 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 Lesser General Public License for more details.
-
-You should have received a copy of the GNU Lesser General Public License
-along with RepoLib. If not, see .
-"""
-
-import unittest
-
-from ..shortcuts import ppa
-from .. import util
-
-class PPATestCase(unittest.TestCase):
-
- def test_ppa(self):
- source = ppa.PPASource()
-
- # Verification data
- uris_test = ['http://ppa.launchpad.net/system76/pop/ubuntu']
- signed_test = '/usr/share/keyrings/ppa-system76-pop-archive-keyring.gpg'
- source.load_from_shortcut(shortcut='ppa:system76/pop', meta=False, key=False)
-
- self.assertEqual(source.uris, uris_test)
- self.assertEqual(source.ident, 'ppa-system76-pop')
- self.assertEqual(source.suites, [util.DISTRO_CODENAME])
- self.assertEqual(source.components, ['main'])
- self.assertEqual(source.types, [util.SourceType.BINARY])
diff --git a/archive/repolib/unittest/test_source.py b/archive/repolib/unittest/test_source.py
deleted file mode 100644
index ae7f38e..0000000
--- a/archive/repolib/unittest/test_source.py
+++ /dev/null
@@ -1,245 +0,0 @@
-#!/usr/bin/python3
-
-"""
-Copyright (c) 2022, Ian Santopietro
-All rights reserved.
-
-This file is part of RepoLib.
-
-RepoLib is free software: you can redistribute it and/or modify
-it under the terms of the GNU Lesser General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-RepoLib 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 Lesser General Public License for more details.
-
-You should have received a copy of the GNU Lesser General Public License
-along with RepoLib. If not, see .
-"""
-
-import unittest
-
-from .. import file, util, source
-
-class SourceTestCase(unittest.TestCase):
- def setUp(self):
- util.set_testing()
- self.source = source.Source()
- self.source.ident = 'test'
- self.source.name = 'Test Source'
- self.source.enabled = True
- self.source.types = [util.SourceType.BINARY, util.SourceType.SOURCECODE]
- self.source.uris = ['http://example.com/ubuntu', 'http://example.com/mirror']
- self.source.suites = ['suite', 'suite-updates']
- self.source.components = ['main', 'contrib', 'nonfree']
- self.source.architectures = 'amd64 armel'
- self.source.languages = 'en_US en_CA'
- self.file = file.SourceFile(name=self.source.ident)
- self.file.add_source(self.source)
- self.source.file = self.file
-
- self.source_legacy = source.Source()
- self.source_legacy.ident = 'test-legacy'
- self.source_legacy.name = 'Test Legacy Source'
- self.source_legacy.enabled = True
- self.source_legacy.types = [util.SourceType.BINARY]
- self.source_legacy.uris = ['http://example.com/ubuntu']
- self.source_legacy.suites = ['suite']
- self.source_legacy.components = ['main', 'contrib', 'nonfree']
- self.source_legacy.architectures = 'amd64 armel'
- self.source_legacy.languages = 'en_US en_CA'
- self.source_legacy.file = file.SourceFile(name=self.source_legacy.ident)
- self.source_legacy.file.format = util.SourceFormat.LEGACY
-
-
- def test_default_source_data(self):
- self.assertEqual(self.source.name, 'Test Source')
- self.assertTrue(self.source.enabled.get_bool())
- self.assertEqual(
- self.source.types,
- [util.SourceType.BINARY, util.SourceType.SOURCECODE]
- )
- self.assertTrue(self.source.sourcecode_enabled)
- self.assertEqual(
- self.source.uris,
- ['http://example.com/ubuntu', 'http://example.com/mirror']
- )
- self.assertEqual(
- self.source.suites,
- ['suite', 'suite-updates']
- )
- self.assertEqual(
- self.source.components,
- ['main', 'contrib', 'nonfree']
- )
- self.assertEqual(self.source.architectures, 'amd64 armel')
- self.assertEqual(self.source.languages, 'en_US en_CA')
- self.assertEqual(self.source.file.path.name, 'test.sources')
-
- def test_output_822(self):
- source_string = (
- 'X-Repolib-ID: test\n'
- 'X-Repolib-Name: Test Source\n'
- 'Enabled: yes\n'
- 'Types: deb deb-src\n'
- 'URIs: http://example.com/ubuntu http://example.com/mirror\n'
- 'Suites: suite suite-updates\n'
- 'Components: main contrib nonfree\n'
- 'Architectures: amd64 armel\n'
- 'Languages: en_US en_CA\n'
- )
- legacy_source_string = (
- 'X-Repolib-ID: test-legacy\n'
- 'X-Repolib-Name: Test Legacy Source\n'
- 'Enabled: yes\n'
- 'Types: deb\n'
- 'URIs: http://example.com/ubuntu\n'
- 'Suites: suite\n'
- 'Components: main contrib nonfree\n'
- 'Architectures: amd64 armel\n'
- 'Languages: en_US en_CA\n'
- )
- self.assertEqual(self.source.deb822, source_string)
- self.assertEqual(self.source_legacy.deb822, legacy_source_string)
-
- def test_output_ui(self):
- source_string = (
- 'test:\n'
- 'Name: Test Source\n'
- 'Enabled: yes\n'
- 'Types: deb deb-src\n'
- 'URIs: http://example.com/ubuntu http://example.com/mirror\n'
- 'Suites: suite suite-updates\n'
- 'Components: main contrib nonfree\n'
- 'Architectures: amd64 armel\n'
- 'Languages: en_US en_CA\n'
- ''
- )
- legacy_source_string = (
- 'test-legacy:\n'
- 'Name: Test Legacy Source\n'
- 'Enabled: yes\n'
- 'Types: deb\n'
- 'URIs: http://example.com/ubuntu\n'
- 'Suites: suite\n'
- 'Components: main contrib nonfree\n'
- 'Architectures: amd64 armel\n'
- 'Languages: en_US en_CA\n'
- )
- self.assertEqual(self.source.ui, source_string)
- self.assertEqual(self.source_legacy.ui, legacy_source_string)
-
- def test_output_legacy(self):
- source_string = (
- 'deb [arch=amd64,armel lang=en_US,en_CA] http://example.com/ubuntu suite main contrib nonfree ## X-Repolib-Name: Test Legacy Source # X-Repolib-ID: test-legacy'
- )
- self.assertEqual(self.source_legacy.legacy, source_string)
-
- def test_enabled(self):
- self.source.enabled = False
- self.assertFalse(self.source.enabled.get_bool())
-
- def test_sourcecode_enabled(self):
- self.source.sourcecode_enabled = False
- self.assertEqual(self.source.types, [util.SourceType.BINARY])
-
- def test_dict_access(self):
- self.assertEqual(self.source['X-Repolib-ID'], 'test')
- self.assertEqual(self.source['X-Repolib-Name'], 'Test Source')
- self.assertEqual(self.source['Enabled'], 'yes')
- self.assertEqual(self.source['Enabled'], 'yes')
- self.assertEqual(self.source['Types'], 'deb deb-src')
- self.assertEqual(self.source['URIs'], 'http://example.com/ubuntu http://example.com/mirror')
- self.assertEqual(self.source['Suites'], 'suite suite-updates')
- self.assertEqual(self.source['Components'], 'main contrib nonfree')
- self.assertEqual(self.source['Architectures'], 'amd64 armel')
- self.assertEqual(self.source['Languages'], 'en_US en_CA')
-
- def test_load(self):
- load_source = source.Source()
- load_source.load_from_data([
- 'X-Repolib-ID: load-test',
- 'X-Repolib-Name: Test Source Loading',
- 'Enabled: yes',
- 'Types: deb',
- 'URIs: http://example.com/ubuntu http://example.com/mirror',
- 'Suites: suite suite-updates',
- 'Components: main contrib nonfree',
- 'Architectures: amd64 armel',
- 'Languages: en_US en_CA',
- ])
-
- self.assertEqual(load_source.ident, 'load-test')
- self.assertEqual(load_source.name, 'Test Source Loading')
- self.assertTrue(load_source.enabled.get_bool())
- self.assertEqual(
- load_source.types,
- [util.SourceType.BINARY]
- )
- self.assertEqual(
- load_source.uris,
- ['http://example.com/ubuntu', 'http://example.com/mirror']
- )
- self.assertEqual(
- load_source.suites,
- ['suite', 'suite-updates']
- )
- self.assertEqual(
- load_source.components,
- ['main', 'contrib', 'nonfree']
- )
- self.assertEqual(load_source.architectures, 'amd64 armel')
- self.assertEqual(load_source.languages, 'en_US en_CA')
-
- load_legacy_source = source.Source()
- load_legacy_source.load_from_data(
- ['deb [arch=amd64,armel lang=en_US,en_CA] http://example.com/ubuntu suite main contrib nonfree ## X-Repolib-Name: Test Legacy Source Loading # X-Repolib-ID: test-load-legacy']
- )
-
- self.assertEqual(load_legacy_source.ident, 'test-load-legacy')
- self.assertEqual(load_legacy_source.name, 'Test Legacy Source Loading')
- self.assertTrue(load_legacy_source.enabled.get_bool())
- self.assertEqual(
- load_legacy_source.types,
- [util.SourceType.BINARY]
- )
- self.assertEqual(
- load_legacy_source.uris,
- ['http://example.com/ubuntu']
- )
- self.assertEqual(
- load_legacy_source.suites,
- ['suite']
- )
- self.assertEqual(
- load_legacy_source.components,
- ['main', 'contrib', 'nonfree']
- )
- self.assertEqual(load_legacy_source.architectures, 'amd64 armel')
- self.assertEqual(load_legacy_source.languages, 'en_US en_CA')
-
- def test_save_load(self):
- self.source.file.save()
- load_source_file = file.SourceFile(name='test')
- load_source_file.load()
- self.assertGreater(len(load_source_file.sources), 0)
- self.assertGreater(
- len(load_source_file.contents), len(load_source_file.sources)
- )
- load_source = load_source_file.sources[0]
-
- self.assertEqual(load_source.ident, self.source.ident)
- self.assertEqual(load_source.name, self.source.name)
- self.assertEqual(load_source.enabled, self.source.enabled)
- self.assertEqual(load_source.types, self.source.types)
- self.assertEqual(load_source.sourcecode_enabled, self.source.sourcecode_enabled)
- self.assertEqual(load_source.uris, self.source.uris)
- self.assertEqual(load_source.suites, self.source.suites)
- self.assertEqual(load_source.components, self.source.components)
- self.assertEqual(load_source.architectures, self.source.architectures)
- self.assertEqual(load_source.languages, self.source.languages)
- self.assertEqual(load_source.file.name, self.source.file.name)
-
\ No newline at end of file
diff --git a/archive/repolib/util.py b/archive/repolib/util.py
deleted file mode 100644
index cb303a9..0000000
--- a/archive/repolib/util.py
+++ /dev/null
@@ -1,455 +0,0 @@
-#!/usr/bin/python3
-
-"""
-Copyright (c) 2019-2022, Ian Santopietro
-All rights reserved.
-
-This file is part of RepoLib.
-
-RepoLib is free software: you can redistribute it and/or modify
-it under the terms of the GNU Lesser General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-RepoLib 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 Lesser General Public License for more details.
-
-You should have received a copy of the GNU Lesser General Public License
-along with RepoLib. If not, see .
-"""
-
-import atexit
-import logging
-import re
-import tempfile
-
-from enum import Enum
-from pathlib import Path
-from urllib.parse import urlparse
-from urllib import request, error
-
-import dbus
-
-SOURCES_DIR = Path('/etc/apt/sources.list.d')
-KEYS_DIR = Path('/etc/apt/keyrings/')
-TESTING = False
-KEYSERVER_QUERY_URL = 'http://keyserver.ubuntu.com/pks/lookup?op=get&search=0x'
-
-log = logging.getLogger(__name__)
-
-class RepoError(Exception):
- """ Exception from this module."""
-
- def __init__(self, *args, code=1, **kwargs):
- """Exception with a source object
-
- Arguments:
- code (:obj:`int`, optional, default=1): Exception error code.
- """
- super().__init__(*args, **kwargs)
- self.code = code
-
-try:
- import distro
- DISTRO_CODENAME = distro.codename()
-except ImportError:
- DISTRO_CODENAME = 'linux'
-
-class SourceFormat(Enum):
- """Enum of SourceFile Formats"""
- DEFAULT = "sources"
- LEGACY = "list"
-
-class SourceType(Enum):
- """Enum of repository types"""
- BINARY = 'deb'
- SOURCECODE = 'deb-src'
-
- def ident(self) -> str:
- """Used for getting a version of the format for idents"""
- ident = f'{self.value}'
- ident = ident.replace('deb-src', 'source')
- ident = ident.replace('deb', 'binary')
- return ident
-
-class AptSourceEnabled(Enum):
- """ Helper Enum to translate between bool data and the Deb822 format. """
- TRUE = 'yes'
- FALSE = 'no'
-
- def get_bool(self):
- """ Return a bool based on the value. """
- # pylint: disable=comparison-with-callable
- # This doesnt seem to actually be a callable in this case.
- if self.value == "yes":
- return True
-
- return False
-
-valid_keys = [
- 'X-Repolib-Name:',
- 'X-Repolib-ID:',
- 'X-Repolib-Default-Mirror:',
- 'X-Repolib-Comment',
- 'X-Repolib-Prefs',
- 'Enabled:',
- 'Types:',
- 'URIs:',
- 'Suites:',
- 'Components:',
- 'Architectures:',
- 'Languages:',
- 'Targets:',
- 'PDiffs:',
- 'By-Hash:',
- 'Allow-Insecure:',
- 'Allow-Weak:',
- 'Allow-Downgrade-To-Insecure:',
- 'Trusted:',
- 'Signed-By:',
- 'Check-Valid-Until:',
- 'Valid-Until-Min:',
- 'Valid-Until-Max:',
-]
-
-output_skip_keys = [
- 'X-Repolib-Prefs',
- 'X-Repolib-ID',
-]
-
-options_inmap = {
- 'arch': 'Architectures',
- 'lang': 'Languages',
- 'target': 'Targets',
- 'pdiffs': 'PDiffs',
- 'by-hash': 'By-Hash',
- 'allow-insecure': 'Allow-Insecure',
- 'allow-weak': 'Allow-Weak',
- 'allow-downgrade-to-insecure': 'Allow-Downgrade-To-Insecure',
- 'trusted': 'Trusted',
- 'signed-by': 'Signed-By',
- 'check-valid-until': 'Check-Valid-Until',
- 'valid-until-min': 'Valid-Until-Min',
- 'valid-until-max': 'Valid-Until-Max'
-}
-
-options_outmap = {
- 'Architectures': 'arch',
- 'Languages': 'lang',
- 'Targets': 'target',
- 'PDiffs': 'pdiffs',
- 'By-Hash': 'by-hash',
- 'Allow-Insecure': 'allow-insecure',
- 'Allow-Weak': 'allow-weak',
- 'Allow-Downgrade-To-Insecure': 'allow-downgrade-to-insecure',
- 'Trusted': 'trusted',
- 'Signed-By': 'signed-by',
- 'Check-Valid-Until': 'check-valid-until',
- 'Valid-Until-Min': 'valid-until-min',
- 'Valid-Until-Max': 'valid-until-max'
-}
-
-true_values = [
- True,
- 'True',
- 'true',
- 'Yes',
- 'yes',
- 'YES',
- 'y',
- 'Y',
- AptSourceEnabled.TRUE,
- 1
-]
-
-keys_map = {
- 'X-Repolib-Name: ': 'Name: ',
- 'X-Repolib-ID: ': 'Ident: ',
- 'X-Repolib-Comments: ': 'Comments: ',
- 'X-Repolib-Default-Mirror: ': 'Default Mirror: ',
-}
-
-PRETTY_PRINT = '\n '
-
-_KEYS_TEMPDIR = tempfile.TemporaryDirectory()
-TEMP_DIR = Path(_KEYS_TEMPDIR.name)
-
-options_re = re.compile(r'[^@.+]\[([^[]+.+)\]\ ')
-uri_re = re.compile(r'\w+:(\/?\/?)[^\s]+')
-
-CLEAN_CHARS = {
- 33: None,
- 64: 45,
- 35: 45,
- 36: 45,
- 37: 45,
- 94: 45,
- 38: 45,
- 42: 45,
- 41: None,
- 40: None,
- 43: 45,
- 61: 45,
- 91: None,
- 92: None,
- 93: None,
- 123: None,
- 125: None,
- 124: 95,
- 63: None,
- 47: 95,
- 46: 45,
- 60: 95,
- 62: 95,
- 44: 95,
- 96: None,
- 126: None,
- 32: 95,
- 58: None,
- 59: None,
-}
-
-sources:dict = {}
-files:dict = {}
-keys:dict = {}
-errors:dict = {}
-
-
-def scrub_filename(name: str = '') -> str:
- """ Clean up a string intended for a filename.
-
- Arguments:
- name (str): The prospective name to scrub.
-
- Returns: str
- The cleaned-up name.
- """
- return name.translate(CLEAN_CHARS)
-
-def set_testing(testing:bool=True) -> None:
- """Sets Repolib in testing mode where changes will not be saved.
-
- Arguments:
- testing(bool): Whether testing mode should be enabled or disabled
- (Defaul: True)
- """
- global KEYS_DIR
- global SOURCES_DIR
-
- testing_tempdir = tempfile.TemporaryDirectory()
-
- if not testing:
- KEYS_DIR = '/usr/share/keyrings'
- SOURCES_DIR = '/etc/apt/sources.list.d'
- return
-
- testing_root = Path(testing_tempdir.name)
- KEYS_DIR = testing_root / 'usr' / 'share' / 'keyrings'
- SOURCES_DIR = testing_root / 'etc' / 'apt' / 'sources.list.d'
-
-
-def _cleanup_temsps() -> None:
- """Clean up our tempdir"""
- _KEYS_TEMPDIR.cleanup()
- # _TESTING_TEMPDIR.cleanup()
-
-atexit.register(_cleanup_temsps)
-
-def dbus_quit():
- bus = dbus.SystemBus()
- privileged_object = bus.get_object('org.pop_os.repolib', '/Repo')
- privileged_object.exit()
-
-def compare_sources(source1, source2, excl_keys:list) -> bool:
- """Compare two sources based on arbitrary criteria.
-
- This looks at a given list of keys, and if the given keys between the two
- given sources are identical, returns True.
-
- Arguments:
- source1, source2(Source): The two sources to compare
- excl_keys([str]): Any keys to exclude from the comparison
-
- Returns: bool
- `True` if the sources are identical, otherwise `False`.
- """
- for key in source1:
- if key in excl_keys:
- continue
- if key in source2:
- if source1[key] != source2[key]:
- return False
- else:
- continue
- else:
- return False
- for key in source2:
- if key in excl_keys:
- continue
- if key in source1:
- if source1[key] != source2[key]:
- return False
- else:
- continue
- else:
- return False
- return True
-
-def find_differences_sources(source1, source2, excl_keys:list) -> dict:
- """Find key-value pairs which differ between two sources.
-
- Arguments:
- source1, source2(Source): The two sources to compare
- excl_keys([str]): Any keys to exclude from the comparison
-
- Returns: dict{'key': ('source1[key]','source2[key]')}
- The dictionary of different keys, with the key values from each source.
- """
- differing_keys:dict = {}
-
- for key in source1:
- if key in excl_keys:
- continue
- if key in source2:
- if source1[key] == source2[key]:
- continue
- differing_keys[key] = (source1[key], source2[key])
- differing_keys[key] = (source1[key], '')
- for key in source2:
- if key in excl_keys:
- continue
- if key in source1:
- if source1[key] == source2[key]:
- continue
- differing_keys[key] = ('', source2[key])
-
- return differing_keys
-
-def combine_sources(source1, source2) -> None:
- """Combine the data in two sources into one.
-
- Arguments:
- source1(Source): The source to be merged into
- source2(Source): The source to merge from
- """
- for key in source1:
- if key in ('X-Repolib-Name', 'X-Repolib-ID', 'Enabled', 'Types'):
- continue
- if key in source2:
- source1[key] += f' {source2[key]}'
- for key in source2:
- if key in ('X-Repolib-Name', 'X-Repolib-ID', 'Enabled', 'Types'):
- continue
- if key in source1:
- source1[key] += f' {source2[key]}'
-
- # Need to deduplicate the list
- for key in source1:
- vals = source1[key].strip().split()
- newvals = []
- for val in vals:
- if val not in newvals:
- newvals.append(val)
- source1[key] = ' '.join(newvals)
- for key in source2:
- vals = source2[key].strip().split()
- newvals = []
- for val in vals:
- if val not in newvals:
- newvals.append(val)
- source2[key] = ' '.join(newvals)
-
-
-def prettyprint_enable(enabled: bool = True) -> None:
- """Easy helper to enable/disable pretty-printing for object reprs.
-
- Can also be used as an easy way to reset to defaults.
-
- Arguments:
- enabled(bool): Whether or not Pretty Printing should be enabled
- """
- global PRETTY_PRINT
- if enabled:
- PRETTY_PRINT = '\n '
- else:
- PRETTY_PRINT = ''
-
-def url_validator(url):
- """ Validate a url and tell if it's good or not.
-
- Arguments:
- url (str): The URL to validate.
-
- Returns:
- `True` if `url` is not malformed, otherwise `False`.
- """
- try:
- # pylint: disable=no-else-return,bare-except
- # A) We want to return false if the URL doesn't contain those parts
- # B) We need this to not throw any exceptions, regardless what they are
- result = urlparse(url)
- if not result.scheme:
- return False
- if result.scheme == 'x-repolib-name':
- return False
- if result.netloc:
- # We need at least a scheme and a netlocation/hostname or...
- return all([result.scheme, result.netloc])
- elif result.path:
- # ...a scheme and a path (this allows file:/// URIs which are valid)
- return all([result.scheme, result.path])
- return False
- except:
- return False
-
-def validate_debline(valid):
- """ Basic checks to see if a given debline is valid or not.
-
- Arguments:
- valid (str): The line to validate.
-
- Returns:
- True if the line is valid, False otherwise.
- """
- comment:bool = False
- if valid.startswith('#'):
- comment = True
- valid = valid.replace('#', '')
- valid = valid.strip()
-
- if valid.startswith("deb"):
- words = valid.split()
- for word in words:
- if url_validator(word):
- return True
-
- elif valid.startswith("ppa:"):
- if "/" in valid:
- return True
-
- else:
- if valid.endswith('.flatpakrepo'):
- return False
- if len(valid.split()) == 1 and not comment:
- return url_validator(valid)
- return False
-
-def strip_hashes(line:str) -> str:
- """ Strips the leading #'s from the given line.
-
- Arguments:
- line (str): The line to strip.
-
- Returns:
- (str): The input line without any leading/trailing hashes or
- leading/trailing whitespace.
- """
- while True:
- line = line.strip('#')
- line = line.strip()
- if not line.startswith('#'):
- break
-
- return line
diff --git a/archive/requirements.txt b/archive/requirements.txt
deleted file mode 100644
index 204fdde..0000000
--- a/archive/requirements.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-dbus-python
-distro
-pytest-pylint
-python-debian
\ No newline at end of file
diff --git a/archive/setup.py b/archive/setup.py
deleted file mode 100755
index 9a78ce1..0000000
--- a/archive/setup.py
+++ /dev/null
@@ -1,198 +0,0 @@
-#!/usr/bin/python3
-
-"""
-Copyright (c) 2019-2020, Ian Santopietro
-All rights reserved.
-
-This file is part of RepoLib.
-
-RepoLib is free software: you can redistribute it and/or modify
-it under the terms of the GNU Lesser General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-RepoLib 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 Lesser General Public License for more details.
-
-You should have received a copy of the GNU Lesser General Public License
-along with RepoLib. If not, see .
-"""
-#pylint: skip-file
-# We don't need to check these in setup
-
-import os
-import subprocess
-from setuptools import setup, find_packages, Command
-
-def get_version():
- """ Get the program version. """
- #pylint: disable=exec-used
- # Just getting the version.
- version = {}
- with open(os.path.join('repolib', '__version__.py')) as fp:
- exec(fp.read(), version)
- return version['__version__']
-
-with open("README.rst", "r") as fh:
- long_description = fh.read()
-
-classifiers = [
- 'Environment :: Console',
- 'Intended Audience :: System Administrators',
- 'Intended Audience :: End Users/Desktop',
- 'Intended Audience :: Developers',
- 'License :: OSI Approved :: GNU Lesser General Public License v3 (LGPLv3)',
- 'Natural Language :: English',
- 'Operating System :: POSIX :: Linux',
- 'Programming Language :: Python :: 3',
- 'Topic :: Software Development :: Libraries :: Python Modules',
- 'Topic :: System'
-]
-
-class Release(Command):
- """ Generate a release and push it to git."""
- description = "Generate a release and push it to git."
-
- user_options = [
- ('dry-run', None, 'Skip the actual release and do a dry run instead.'),
- ('skip-deb', None, 'Skip doing a debian update for this release.'),
- ('skip-git', None, 'Skip committing to git at the end.'),
- ('prerelease=', None, 'Release a pre-release version (alpha,beta,rc)'),
- ('increment=', None, 'Manually specify the desired increment (MAJOR, MINOR, PATCH)')
- ]
-
- def initialize_options(self):
- self.dry_run = False
- self.skip_deb = False
- self.skip_git = False
- self.prerelease = None
- self.increment = None
-
- def finalize_options(self):
- pass
-
- def run(self):
- cz_command = ['cz', 'bump', '--yes']
- ch_command = ['dch']
- git_command = ['git', 'add', '.']
-
- def capture_version(sp_complete):
- output = sp_complete.stdout.decode('UTF-8').split('\n')
- print('\n'.join(output))
- for line in output:
- if 'tag to create' in line:
- version_line = line
-
- try:
- return version_line.split()[-1].replace('v', '')
- except UnboundLocalError:
- stderr = sp_complete.stderr.decode('UTF-8')
- print("WARNING: Couldn't get updated version! Using current.")
- print(stderr)
- return get_version()
-
- if self.dry_run:
- print('Dry run: Not making actual changes')
- cz_command.append('--dry-run')
-
- if self.prerelease:
- if self.prerelease.lower() not in ['alpha', 'beta', 'rc']:
- raise Exception(
- f'{self.prerelease} is not a valid prerelease type. Please '
- 'use one of "alpha", "beta", or "rc".'
- )
- cz_command.append('--prerelease')
- cz_command.append(self.prerelease.lower())
-
- if self.increment:
- if self.increment.upper() not in ['MAJOR', 'MINOR', 'PATCH']:
- raise Exception(
- f'{self.increment} is not a valid increments. Please use '
- 'one of MAJOR, MINOR, or PATCH.'
- )
- cz_command.append('--increment')
- cz_command.append(self.increment.upper())
-
- # We need to get the new version from CZ, as the file hasn't been
- # updated yet.
- version_command = cz_command.copy()
- version_command.append('--dry-run')
- version_complete = subprocess.run(version_command, capture_output=True)
-
- version = capture_version(version_complete)
- print(f'Old Version: {get_version()}')
- print(f'New version: {version}')
-
- ch_command.append(f'-v{version}')
- if not self.skip_deb:
- print(ch_command)
- if not self.dry_run:
- subprocess.run(ch_command)
- subprocess.run(['dch', '-r', '""'])
-
- if not self.skip_git:
- print(git_command)
- if not self.dry_run:
- subprocess.run(git_command)
-
- print(' '.join(cz_command))
- if not self.dry_run:
- subprocess.run(cz_command)
-
-class Test(Command):
- """ Run pyflakes and pytest"""
- description = 'Run pyflakes, pytest, and pylint'
-
- user_options = [
- ('run-flakes', None, 'Run pyflakes'),
- ('skip-test', None, 'Skip running pytest'),
- ('skip-lint', None, 'Skip running pylint')
- ]
-
- def initialize_options(self):
- self.run_flakes = True
- self.skip_test = False
- self.skip_lint = False
-
- def finalize_options(self):
- pass
-
- def run(self):
- pytest_command = ['pytest-3']
- flakes_command = ['pyflakes3', 'repolib']
- lint_command = ['pylint', 'repolib']
-
- if not self.skip_test:
- subprocess.run(pytest_command)
-
- if not self.run_flakes:
- subprocess.run(flakes_command)
-
- if not self.skip_lint:
- subprocess.run(lint_command)
-
-setup(
- name='repolib',
- version=get_version(),
- author='Ian Santopietro',
- author_email='ian@system76.com',
- url='https://github.com/pop-os/repolib',
- description='Easily manage software sources',
- download_url='https://github.com/pop-os/repolib/releases',
- long_description=long_description,
- tests_require=['pytest'],
- license='LGPLv3',
- packages=['repolib', 'repolib/command', 'repolib/shortcuts', 'repolib/unittest'],
- cmdclass={'release': Release, 'test': Test},
- scripts=['bin/apt-manage'],
- data_files=[
- ('share/bash-completion/completions', ['data/bash-completion/apt-manage']),
- ('share/zsh/vendor-completions', ['data/zsh-completion/_apt-manage']),
- ('/usr/share/dbus-1/system-services', ['data/org.pop_os.repolib.service']),
- ('/usr/share/polkit-1/actions', ['data/org.pop_os.repolib.policy']),
- ('/etc/dbus-1/system.d/', ['data/org.pop_os.repolib.conf']),
- ('/usr/lib/repolib', ['data/service.py', 'bin/add-apt-repository'])
- ]
-)
diff --git a/archive/debian/README.source b/debian/README.source
similarity index 100%
rename from archive/debian/README.source
rename to debian/README.source
diff --git a/debian/changelog b/debian/changelog
new file mode 100644
index 0000000..390e307
--- /dev/null
+++ b/debian/changelog
@@ -0,0 +1,5 @@
+repolib (2.2.0~99pika4) kinetic; urgency=medium
+
+ * Initial Creation
+
+ -- Ward Nakchbandi Fri, 09 Oct 2022 21:38:00 +0300
diff --git a/archive/debian/compat b/debian/compat
similarity index 100%
rename from archive/debian/compat
rename to debian/compat
diff --git a/archive/debian/control b/debian/control
similarity index 100%
rename from archive/debian/control
rename to debian/control
diff --git a/archive/debian/copyright b/debian/copyright
similarity index 100%
rename from archive/debian/copyright
rename to debian/copyright
diff --git a/archive/debian/rules b/debian/rules
similarity index 100%
rename from archive/debian/rules
rename to debian/rules
diff --git a/archive/debian/source/format b/debian/source/format
similarity index 100%
rename from archive/debian/source/format
rename to debian/source/format
diff --git a/archive/debian/source/options b/debian/source/options
similarity index 100%
rename from archive/debian/source/options
rename to debian/source/options
diff --git a/archive/debian/triggers b/debian/triggers
similarity index 100%
rename from archive/debian/triggers
rename to debian/triggers
diff --git a/main.sh b/main.sh
new file mode 100755
index 0000000..90c535f
--- /dev/null
+++ b/main.sh
@@ -0,0 +1,21 @@
+# Add dependent repositories
+wget -q -O - https://ppa.pika-os.com/key.gpg | sudo apt-key add -
+add-apt-repository https://ppa.pika-os.com
+add-apt-repository ppa:pikaos/pika
+add-apt-repository ppa:kubuntu-ppa/backports
+# Clone Upstream
+git clone https://github.com/pop-os/repolib
+rm -rvf ./repolib/debian
+cp -rvf ./debian ./repolib
+cd ./repolib
+
+# Get build deps
+apt-get build-dep ./ -y
+
+# Build package
+dpkg-buildpackage
+
+# Move the debs to output
+cd ../
+mkdir -p ./output
+mv ./*.deb ./output/
diff --git a/release.sh b/release.sh
new file mode 100755
index 0000000..ce9e316
--- /dev/null
+++ b/release.sh
@@ -0,0 +1,11 @@
+# Sign the packages
+dpkg-sig --sign builder ./output/*.deb
+
+# Pull down existing ppa repo db files etc
+rsync -azP --exclude '*.deb' ferreo@direct.pika-os.com:/srv/www/pikappa/ ./output/repo
+
+# Add the new package to the repo
+reprepro -V --basedir ./output/repo/ includedeb kinetic ./output/*.deb
+
+# Push the updated ppa repo to the server
+rsync -azP ./output/repo/ ferreo@direct.pika-os.com:/srv/www/pikappa/