From 64e5f2d19e73ce4370f69e13ff554ab3cd252eeb Mon Sep 17 00:00:00 2001 From: Mathias Markl Date: Thu, 7 Jun 2018 11:23:37 +0200 Subject: [PATCH] init --- muk_autovacuum/LICENSE | 619 ++++++++++++++++++ muk_autovacuum/__init__.py | 69 ++ muk_autovacuum/__manifest__.py | 53 ++ muk_autovacuum/doc/changelog.rst | 15 + muk_autovacuum/doc/index.rst | 65 ++ muk_autovacuum/i18n/de.po | 173 +++++ muk_autovacuum/i18n/muk_autovacuum.pot | 172 +++++ muk_autovacuum/models/__init__.py | 21 + muk_autovacuum/models/ir_autovacuum.py | 89 +++ muk_autovacuum/models/rules.py | 240 +++++++ muk_autovacuum/security/ir.model.access.csv | 3 + muk_autovacuum/static/description/banner.png | Bin 0 -> 39628 bytes muk_autovacuum/static/description/icon.png | Bin 0 -> 8433 bytes muk_autovacuum/static/description/index.html | 70 ++ muk_autovacuum/static/description/logo.png | Bin 0 -> 38064 bytes .../static/description/screenshot.png | Bin 0 -> 45295 bytes muk_autovacuum/tests/__init__.py | 20 + muk_autovacuum/tests/test_autovacuum.py | 88 +++ muk_autovacuum/views/rules.xml | 134 ++++ 19 files changed, 1831 insertions(+) create mode 100644 muk_autovacuum/LICENSE create mode 100644 muk_autovacuum/__init__.py create mode 100644 muk_autovacuum/__manifest__.py create mode 100644 muk_autovacuum/doc/changelog.rst create mode 100644 muk_autovacuum/doc/index.rst create mode 100644 muk_autovacuum/i18n/de.po create mode 100644 muk_autovacuum/i18n/muk_autovacuum.pot create mode 100644 muk_autovacuum/models/__init__.py create mode 100644 muk_autovacuum/models/ir_autovacuum.py create mode 100644 muk_autovacuum/models/rules.py create mode 100644 muk_autovacuum/security/ir.model.access.csv create mode 100644 muk_autovacuum/static/description/banner.png create mode 100644 muk_autovacuum/static/description/icon.png create mode 100644 muk_autovacuum/static/description/index.html create mode 100644 muk_autovacuum/static/description/logo.png create mode 100644 muk_autovacuum/static/description/screenshot.png create mode 100644 muk_autovacuum/tests/__init__.py create mode 100644 muk_autovacuum/tests/test_autovacuum.py create mode 100644 muk_autovacuum/views/rules.xml diff --git a/muk_autovacuum/LICENSE b/muk_autovacuum/LICENSE new file mode 100644 index 0000000..faf7bf4 --- /dev/null +++ b/muk_autovacuum/LICENSE @@ -0,0 +1,619 @@ + GNU AFFERO GENERAL PUBLIC LICENSE + Version 3, 19 November 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 Affero General Public License is a free, copyleft license for +software and other kinds of works, specifically designed to ensure +cooperation with the community in the case of network server software. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +our General Public Licenses are 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. + + 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. + + Developers that use our General Public Licenses protect your rights +with two steps: (1) assert copyright on the software, and (2) offer +you this License which gives you legal permission to copy, distribute +and/or modify the software. + + A secondary benefit of defending all users' freedom is that +improvements made in alternate versions of the program, if they +receive widespread use, become available for other developers to +incorporate. Many developers of free software are heartened and +encouraged by the resulting cooperation. However, in the case of +software used on network servers, this result may fail to come about. +The GNU General Public License permits making a modified version and +letting the public access it on a server without ever releasing its +source code to the public. + + The GNU Affero General Public License is designed specifically to +ensure that, in such cases, the modified source code becomes available +to the community. It requires the operator of a network server to +provide the source code of the modified version running there to the +users of that server. Therefore, public use of a modified version, on +a publicly accessible server, gives the public access to the source +code of the modified version. + + An older license, called the Affero General Public License and +published by Affero, was designed to accomplish similar goals. This is +a different license, not a version of the Affero GPL, but Affero has +released a new version of the Affero GPL which permits relicensing under +this license. + + 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 Affero 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. Remote Network Interaction; Use with the GNU General Public License. + + Notwithstanding any other provision of this License, if you modify the +Program, your modified version must prominently offer all users +interacting with it remotely through a computer network (if your version +supports such interaction) an opportunity to receive the Corresponding +Source of your version by providing access to the Corresponding Source +from a network server at no charge, through some standard or customary +means of facilitating copying of software. This Corresponding Source +shall include the Corresponding Source for any work covered by version 3 +of the GNU General Public License that is incorporated pursuant to the +following paragraph. + + 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 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 work with which it is combined will remain governed by version +3 of the GNU General Public License. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU Affero 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 Affero 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 Affero 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 Affero 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 \ No newline at end of file diff --git a/muk_autovacuum/__init__.py b/muk_autovacuum/__init__.py new file mode 100644 index 0000000..eaf8b97 --- /dev/null +++ b/muk_autovacuum/__init__.py @@ -0,0 +1,69 @@ +################################################################################### +# +# Copyright (C) 2018 MuK IT GmbH +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero 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 Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +################################################################################### + +from odoo import api, SUPERUSER_ID + +from . import models + +def _get_value(env, model): + model_model = env['ir.model'] + model_fields = env['ir.model.fields'] + model = model_model.search([('model', '=', model)], limit=1) + if model.exists(): + field_domain = [ + ('model_id', '=', model.id), + ('ttype', '=', 'datetime'), + ('name', '=', 'create_date')] + field = model_fields.search(field_domain, limit=1) + return model, field + return None + +def _init_default_rules(cr, registry): + env = api.Environment(cr, SUPERUSER_ID, {}) + rule = env['muk_autovacuum.rules'] + values = _get_value(env, 'mail.message') + if values: + rule.create({ + 'name': "Delete Message Attachments after 6 Months", + 'model': values[0].id, + 'active': False, + 'state': 'time', + 'time_field': values[1].id, + 'time_type': 'months', + 'time': 6, + 'only_attachments': True}) + rule.create({ + 'name': "Delete Messages after 1 Year", + 'model': values[0].id, + 'active': False, + 'state': 'time', + 'time_field': values[1].id, + 'time_type': 'years', + 'time': 1}) + values = _get_value(env, 'ir.logging') + if values: + rule.create({ + 'name': "Delete Logs after 2 Weeks", + 'model': values[0].id, + 'active': False, + 'state': 'time', + 'time_field': values[1].id, + 'time_type': 'weeks', + 'time': 2, + 'protect_starred': False}) \ No newline at end of file diff --git a/muk_autovacuum/__manifest__.py b/muk_autovacuum/__manifest__.py new file mode 100644 index 0000000..c6a180e --- /dev/null +++ b/muk_autovacuum/__manifest__.py @@ -0,0 +1,53 @@ +################################################################################### +# +# Copyright (C) 2018 MuK IT GmbH +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero 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 Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +################################################################################### + +{ + "name": "MuK Autovacuum", + "summary": """Configure automatic garbage collection""", + "version": "11.0.2.0.0", + "category": "Extra Tools", + "license": "AGPL-3", + "website": "https://www.mukit.at", + "live_test_url": "https://demo.mukit.at/web/login", + "author": "MuK IT", + "contributors": [ + "Mathias Markl ", + ], + "depends": [ + "base", + ], + "data": [ + "security/ir.model.access.csv", + "views/rules.xml", + ], + "qweb": [ + "static/src/xml/*.xml", + ], + "images": [ + 'static/description/banner.png' + ], + "external_dependencies": { + "python": [], + "bin": [], + }, + "auto_install": False, + "application": False, + "installable": True, + "post_init_hook": '_init_default_rules', +} \ No newline at end of file diff --git a/muk_autovacuum/doc/changelog.rst b/muk_autovacuum/doc/changelog.rst new file mode 100644 index 0000000..243277c --- /dev/null +++ b/muk_autovacuum/doc/changelog.rst @@ -0,0 +1,15 @@ +`2.0.0` +------- + +- Migrated to Python 3 + +`1.1.0` +------- + +- Add field selector + + +`1.0.0` +------- + +- Init version diff --git a/muk_autovacuum/doc/index.rst b/muk_autovacuum/doc/index.rst new file mode 100644 index 0000000..b4c5cac --- /dev/null +++ b/muk_autovacuum/doc/index.rst @@ -0,0 +1,65 @@ +.. image:: https://img.shields.io/badge/license-AGPL--3-blue.png + :target: https://www.gnu.org/licenses/agpl + :alt: License: AGPL-3 + +.. image:: https://gitlab.mukit.at/base/muk_autovacuum/badges/11.0/pipeline.svg + :target: https://gitlab.mukit.at/base/muk_autovacuum/commits/11.0 + :alt: Pipeline status + +.. image:: https://gitlab.mukit.at/base/muk_autovacuum/badges/11.0/coverage.svg + :target: https://gitlab.mukit.at/base/muk_autovacuum/commits/11.0 + :alt: Coverage report + +============== +MuK Autovacuum +============== + +Allows the administrator to create rules to automatically garbage collect +a certain model. Every rule can have a different time interval additional +constraints. An extra constraint can be for example to only delete inactive +records. + +Installation +============ + +To install this module, you need to: + +Download the module and add it to your Odoo addons folder. Afterward, log on to +your Odoo server and go to the Apps menu. Trigger the debug modus and update the +list by clicking on the "Update Apps List" link. Now install the module by +clicking on the install button. + +Configuration +============= + +To configure this module, you need to: + +#. Go to *Settings* while being in debug mode. +#. Afterwards go to *Technical -> Automation -> Auto Vacuum Rules*. +#. And create a new rule. + +Usage +============= + +This module has no direct visible effect on the system. The garbage collections +happens during the autovacuum cron job. + +Credits +======= + +Contributors +------------ + +* Mathias Markl + +Author & Maintainer +------------------- + +This module is maintained by the `MuK IT GmbH `_. + +MuK IT is an Austrian company specialized in customizing and extending Odoo. +We develop custom solutions for your individual needs to help you focus on +your strength and expertise to grow your business. + +If you want to get in touch please contact us via mail +(sale@mukit.at) or visit our website (https://mukit.at). diff --git a/muk_autovacuum/i18n/de.po b/muk_autovacuum/i18n/de.po new file mode 100644 index 0000000..007e5e1 --- /dev/null +++ b/muk_autovacuum/i18n/de.po @@ -0,0 +1,173 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * muk_autovacuum +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 11.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2018-01-22 19:26+0000\n" +"PO-Revision-Date: 2018-01-22 20:30+0100\n" +"Last-Translator: <>\n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: \n" +"Language: de\n" +"X-Generator: Poedit 2.0.5\n" + +#. module: muk_autovacuum +#: model:ir.actions.act_window,name:muk_autovacuum.action_rule +#: model:ir.model,name:muk_autovacuum.model_muk_autovacuum_rules +#: model:ir.ui.menu,name:muk_autovacuum.menu_rules +#: model:ir.ui.view,arch_db:muk_autovacuum.view_refresh_rule_tree +msgid "Auto Vacuum Rules" +msgstr "Auto Vacuum Regeln" + +#. module: muk_autovacuum +#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules_create_uid +msgid "Created by" +msgstr "Erstellt von" + +#. module: muk_autovacuum +#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules_create_date +msgid "Created on" +msgstr "Erstellt am" + +#. module: muk_autovacuum +#: selection:muk_autovacuum.rules,time_type:0 +msgid "Days" +msgstr "Tage" + +#. module: muk_autovacuum +#: model:ir.model.fields,help:muk_autovacuum.field_muk_autovacuum_rules_time +msgid "Delete older data than x." +msgstr "Lösche ältere Daten als x." + +#. module: muk_autovacuum +#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules_display_name +msgid "Display Name" +msgstr "Anzeigename" + +#. module: muk_autovacuum +#: model:ir.model.fields,help:muk_autovacuum.field_muk_autovacuum_rules_protect_starred +msgid "Do not delete starred records." +msgstr "Einträge mit einem Stern werden nicht gelöscht." + +#. module: muk_autovacuum +#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules_field +msgid "Field" +msgstr "Feld" + +#. module: muk_autovacuum +#: code:addons/muk_autovacuum/models/ir_autovacuum.py:84 +#, python-format +msgid "GC'd %s %s records" +msgstr "GC'd %s %s records" + +#. module: muk_autovacuum +#: code:addons/muk_autovacuum/models/ir_autovacuum.py:80 +#, python-format +msgid "GC'd %s attachments from %s entries" +msgstr "GC'd %s attachments from %s entries" + +#. module: muk_autovacuum +#: selection:muk_autovacuum.rules,time_type:0 +msgid "Hours" +msgstr "Stunden" + +#. module: muk_autovacuum +#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules_id +msgid "ID" +msgstr "ID" + +#. module: muk_autovacuum +#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules___last_update +msgid "Last Modified on" +msgstr "Zuletzt geändert am" + +#. module: muk_autovacuum +#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules_write_uid +msgid "Last Updated by" +msgstr "Zuletzt aktualisiert durch" + +#. module: muk_autovacuum +#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules_write_date +msgid "Last Updated on" +msgstr "Zuletzt aktualisiert am" + +#. module: muk_autovacuum +#: selection:muk_autovacuum.rules,time_type:0 +msgid "Minutes" +msgstr "Minuten" + +#. module: muk_autovacuum +#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules_model +msgid "Model" +msgstr "Modell" + +#. module: muk_autovacuum +#: model:ir.model.fields,help:muk_autovacuum.field_muk_autovacuum_rules_model +msgid "Model on which the rule is applied." +msgstr "Model welches die Regel zuordnet ist." + +#. module: muk_autovacuum +#: selection:muk_autovacuum.rules,time_type:0 +msgid "Months" +msgstr "Monate" + +#. module: muk_autovacuum +#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules_only_inactive +msgid "Only Archived" +msgstr "Nur archivierte Einträge" + +#. module: muk_autovacuum +#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules_only_attachments +msgid "Only Attachments" +msgstr "Nur Anhänge" + +#. module: muk_autovacuum +#: model:ir.model.fields,help:muk_autovacuum.field_muk_autovacuum_rules_only_inactive +msgid "Only delete archived records." +msgstr "Es werden nur archivierte Einträge gelöscht." + +#. module: muk_autovacuum +#: model:ir.model.fields,help:muk_autovacuum.field_muk_autovacuum_rules_only_attachments +msgid "Only delete record attachments." +msgstr "Es werden nur Anhänge gelöscht." + +#. module: muk_autovacuum +#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules_protect_starred +msgid "Protect Starred" +msgstr "Schütze Einträge mit Stern" + +#. module: muk_autovacuum +#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules_sequence +msgid "Sequence" +msgstr "Nummernfolge" + +#. module: muk_autovacuum +#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules_time +msgid "Time" +msgstr "Zeit" + +#. module: muk_autovacuum +#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules_time_type +msgid "Time Unit" +msgstr "Interval" + +#. module: muk_autovacuum +#: selection:muk_autovacuum.rules,time_type:0 +msgid "Weeks" +msgstr "Wochen" + +#. module: muk_autovacuum +#: selection:muk_autovacuum.rules,time_type:0 +msgid "Years" +msgstr "Jahre" + +#. module: muk_autovacuum +#: model:ir.model,name:muk_autovacuum.model_ir_autovacuum +msgid "ir.autovacuum" +msgstr "ir.autovacuum" diff --git a/muk_autovacuum/i18n/muk_autovacuum.pot b/muk_autovacuum/i18n/muk_autovacuum.pot new file mode 100644 index 0000000..c82c766 --- /dev/null +++ b/muk_autovacuum/i18n/muk_autovacuum.pot @@ -0,0 +1,172 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * muk_autovacuum +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 11.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2018-01-22 19:26+0000\n" +"PO-Revision-Date: 2018-01-22 19:26+0000\n" +"Last-Translator: <>\n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: muk_autovacuum +#: model:ir.actions.act_window,name:muk_autovacuum.action_rule +#: model:ir.model,name:muk_autovacuum.model_muk_autovacuum_rules +#: model:ir.ui.menu,name:muk_autovacuum.menu_rules +#: model:ir.ui.view,arch_db:muk_autovacuum.view_refresh_rule_tree +msgid "Auto Vacuum Rules" +msgstr "" + +#. module: muk_autovacuum +#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules_create_uid +msgid "Created by" +msgstr "" + +#. module: muk_autovacuum +#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules_create_date +msgid "Created on" +msgstr "" + +#. module: muk_autovacuum +#: selection:muk_autovacuum.rules,time_type:0 +msgid "Days" +msgstr "" + +#. module: muk_autovacuum +#: model:ir.model.fields,help:muk_autovacuum.field_muk_autovacuum_rules_time +msgid "Delete older data than x." +msgstr "" + +#. module: muk_autovacuum +#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules_display_name +msgid "Display Name" +msgstr "" + +#. module: muk_autovacuum +#: model:ir.model.fields,help:muk_autovacuum.field_muk_autovacuum_rules_protect_starred +msgid "Do not delete starred records." +msgstr "" + +#. module: muk_autovacuum +#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules_field +msgid "Field" +msgstr "" + +#. module: muk_autovacuum +#: code:addons/muk_autovacuum/models/ir_autovacuum.py:84 +#, python-format +msgid "GC'd %s %s records" +msgstr "" + +#. module: muk_autovacuum +#: code:addons/muk_autovacuum/models/ir_autovacuum.py:80 +#, python-format +msgid "GC'd %s attachments from %s entries" +msgstr "" + +#. module: muk_autovacuum +#: selection:muk_autovacuum.rules,time_type:0 +msgid "Hours" +msgstr "" + +#. module: muk_autovacuum +#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules_id +msgid "ID" +msgstr "" + +#. module: muk_autovacuum +#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules___last_update +msgid "Last Modified on" +msgstr "" + +#. module: muk_autovacuum +#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules_write_uid +msgid "Last Updated by" +msgstr "" + +#. module: muk_autovacuum +#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules_write_date +msgid "Last Updated on" +msgstr "" + +#. module: muk_autovacuum +#: selection:muk_autovacuum.rules,time_type:0 +msgid "Minutes" +msgstr "" + +#. module: muk_autovacuum +#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules_model +msgid "Model" +msgstr "" + +#. module: muk_autovacuum +#: model:ir.model.fields,help:muk_autovacuum.field_muk_autovacuum_rules_model +msgid "Model on which the rule is applied." +msgstr "" + +#. module: muk_autovacuum +#: selection:muk_autovacuum.rules,time_type:0 +msgid "Months" +msgstr "" + +#. module: muk_autovacuum +#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules_only_inactive +msgid "Only Archived" +msgstr "" + +#. module: muk_autovacuum +#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules_only_attachments +msgid "Only Attachments" +msgstr "" + +#. module: muk_autovacuum +#: model:ir.model.fields,help:muk_autovacuum.field_muk_autovacuum_rules_only_inactive +msgid "Only delete archived records." +msgstr "" + +#. module: muk_autovacuum +#: model:ir.model.fields,help:muk_autovacuum.field_muk_autovacuum_rules_only_attachments +msgid "Only delete record attachments." +msgstr "" + +#. module: muk_autovacuum +#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules_protect_starred +msgid "Protect Starred" +msgstr "" + +#. module: muk_autovacuum +#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules_sequence +msgid "Sequence" +msgstr "" + +#. module: muk_autovacuum +#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules_time +msgid "Time" +msgstr "" + +#. module: muk_autovacuum +#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules_time_type +msgid "Time Unit" +msgstr "" + +#. module: muk_autovacuum +#: selection:muk_autovacuum.rules,time_type:0 +msgid "Weeks" +msgstr "" + +#. module: muk_autovacuum +#: selection:muk_autovacuum.rules,time_type:0 +msgid "Years" +msgstr "" + +#. module: muk_autovacuum +#: model:ir.model,name:muk_autovacuum.model_ir_autovacuum +msgid "ir.autovacuum" +msgstr "" + diff --git a/muk_autovacuum/models/__init__.py b/muk_autovacuum/models/__init__.py new file mode 100644 index 0000000..81c79ec --- /dev/null +++ b/muk_autovacuum/models/__init__.py @@ -0,0 +1,21 @@ +################################################################################### +# +# Copyright (C) 2018 MuK IT GmbH +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero 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 Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +################################################################################### + +from . import rules +from . import ir_autovacuum \ No newline at end of file diff --git a/muk_autovacuum/models/ir_autovacuum.py b/muk_autovacuum/models/ir_autovacuum.py new file mode 100644 index 0000000..297713f --- /dev/null +++ b/muk_autovacuum/models/ir_autovacuum.py @@ -0,0 +1,89 @@ +################################################################################### +# +# Copyright (C) 2018 MuK IT GmbH +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero 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 Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +################################################################################### + +import time +import logging +import datetime +import dateutil + +from odoo import _ +from odoo import models, api +from odoo.tools.safe_eval import safe_eval +from odoo.tools.misc import DEFAULT_SERVER_DATETIME_FORMAT + +_logger = logging.getLogger(__name__) + +_types = { + 'days': lambda interval: datetime.timedelta(days=interval), + 'years': lambda interval: datetime.timedelta(weeks=interval*52), + 'hours': lambda interval: datetime.timedelta(hours=interval), + 'weeks': lambda interval: datetime.timedelta(weeks=interval), + 'months': lambda interval: datetime.timedelta(days=interval*30), + 'minutes': lambda interval: datetime.timedelta(minutes=interval), +} + +class AutoVacuum(models.AbstractModel): + + _inherit = 'ir.autovacuum' + + @api.model + def power_on(self, *args, **kwargs): + res = super(AutoVacuum, self).power_on(*args, **kwargs) + rules = self.env['muk_autovacuum.rules'].sudo().search([], order='sequence asc') + for rule in rules: + model = self.env[rule.model.model].sudo() + records = self.env[rule.model.model] + if rule.state == 'time': + computed_time = datetime.datetime.utcnow() - _types[rule.time_type](rule.time) + domain = [(rule.time_field.name, '<', computed_time.strftime(DEFAULT_SERVER_DATETIME_FORMAT))] + if rule.protect_starred and "starred" in rule.model.field_id.mapped("name"): + domain.append(('starred', '=', False)) + if rule.only_inactive and "active" in rule.model.field_id.mapped("name"): + domain.append(('active', '=', False)) + _logger.info(_("GC domain: %s"), domain) + records = model.with_context({'active_test': False}).search(domain) + elif rule.state == 'size': + size = rule.size if rule.size_type == 'fixed' else rule.size_parameter_value + count = model.with_context({'active_test': False}).search([], count=True) + if count > size: + limit = count - size + _logger.info(_("GC domain: [] order: %s limit: %s"), rule.size_order, limit) + records = model.with_context({'active_test': False}).search([], order=rule.size_order, limit=limit) + elif rule.state == 'domain': + _logger.info(_("GC domain: %s"), rule.domain) + context = { + 'datetime': datetime, + 'dateutil': dateutil, + 'time': time, + 'uid': self.env.uid, + 'user': self.env.user} + domain = safe_eval(rule.domain, context) + records = model.with_context({'active_test': False}).search(domain) + if rule.only_attachments: + attachments = self.env['ir.attachment'].sudo().search([ + ('res_model', '=', rule.model.model), + ('res_id', 'in', records.mapped('id'))]) + count = len(attachments) + attachments.unlink() + _logger.info(_("GC'd %s attachments from %s entries"), count, rule.model.model) + else: + count = len(records) + records.unlink() + _logger.info(_("GC'd %s %s records"), count, rule.model.model) + return res \ No newline at end of file diff --git a/muk_autovacuum/models/rules.py b/muk_autovacuum/models/rules.py new file mode 100644 index 0000000..2a45cca --- /dev/null +++ b/muk_autovacuum/models/rules.py @@ -0,0 +1,240 @@ +################################################################################### +# +# Copyright (C) 2018 MuK IT GmbH +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero 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 Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +################################################################################### + +import logging + +from odoo import _ +from odoo import models, api, fields +from odoo.exceptions import ValidationError + +_logger = logging.getLogger(__name__) + +class AutoVacuumRules(models.Model): + + _name = 'muk_autovacuum.rules' + _description = "Auto Vacuum Rules" + _order = "sequence asc" + + #---------------------------------------------------------- + # Defaults + #---------------------------------------------------------- + + def _default_sequence(self): + record = self.sudo().search([], order='sequence desc', limit=1) + if record.exists(): + return record.sequence + 1 + else: + return 1 + + #---------------------------------------------------------- + # Database + #---------------------------------------------------------- + + name = fields.Char( + string='Name', + required=True) + + active = fields.Boolean( + string='Active', + default=True) + + state = fields.Selection( + selection=[ + ('time', 'Time Based'), + ('size', 'Size Based'), + ('domain', 'Domain Based')], + string='Rule Type', + default='time', + required=True) + + sequence = fields.Integer( + string='Sequence', + default=_default_sequence, + required=True) + + model = fields.Many2one( + comodel_name='ir.model', + string="Model", + required=True, + ondelete='cascade', + help="Model on which the rule is applied.") + + model_name = fields.Char( + related='model.model', + string="Model Name", + readonly=True, + store=True) + + time_field = fields.Many2one( + comodel_name='ir.model.fields', + domain="[('model_id', '=', model), ('ttype', '=', 'datetime')]", + string='Time Field', + ondelete='cascade', + states={ + 'time': [('required', True)], + 'size': [('invisible', True)], + 'domain': [('invisible', True)]}) + + time_type = fields.Selection( + selection=[ + ('minutes', 'Minutes'), + ('hours', 'Hours'), + ('days', 'Days'), + ('weeks', 'Weeks'), + ('months', 'Months'), + ('years', 'Years')], + string='Time Unit', + default='months', + states={ + 'time': [('required', True)], + 'size': [('invisible', True)], + 'domain': [('invisible', True)]}) + + time = fields.Integer( + string='Time', + default=1, + states={ + 'time': [('required', True)], + 'size': [('invisible', True)], + 'domain': [('invisible', True)]}, + help="Delete older data than x.") + + size_type = fields.Selection( + selection=[ + ('fixed', 'Fixed Value'), + ('parameter', 'System Parameter')], + string='Size Type', + default='fixed', + states={ + 'time': [('invisible', True)], + 'size': [('required', True)], + 'domain': [('invisible', True)]}) + + size_parameter = fields.Many2one( + comodel_name='ir.config_parameter', + string='System Parameter', + ondelete='cascade', + states={ + 'time': [('invisible', True)], + 'size': [('required', True)], + 'domain': [('invisible', True)]}) + + size_parameter_value = fields.Integer( + compute='_compute_size_parameter_value', + string='Size', + states={ + 'time': [('invisible', True)], + 'size': [('readonly', True)], + 'domain': [('invisible', True)]}, + help="Delete records with am index greater than x.") + + size_order = fields.Char( + string='Size Order', + default='create_date desc', + states={ + 'time': [('invisible', True)], + 'size': [('required', True)], + 'domain': [('invisible', True)]}, + help="Order by which the index is defined.") + + size = fields.Integer( + string='Size', + default=200, + states={ + 'time': [('invisible', True)], + 'size': [('required', True)], + 'domain': [('invisible', True)]}, + help="Delete records with am index greater than x.") + + domain = fields.Char( + string='Before Update Domain', + states={ + 'time': [('invisible', True)], + 'size': [('invisible', True)], + 'domain': [('required', True)]}, + help="Delete all records which match the domain.") + + protect_starred = fields.Boolean( + string='Protect Starred', + default=True, + states={ + 'time': [('invisible', False)], + 'size': [('invisible', True)], + 'domain': [('invisible', True)]}, + help="Do not delete starred records.") + + only_inactive = fields.Boolean( + string='Only Archived', + default=False, + states={ + 'time': [('invisible', False)], + 'size': [('invisible', True)], + 'domain': [('invisible', True)]}, + help="Only delete archived records.") + + only_attachments = fields.Boolean( + string='Only Attachments', + default=False, + help="Only delete record attachments.") + + #---------------------------------------------------------- + # View + #---------------------------------------------------------- + + @api.onchange('model') + def _onchange_model(self): + field_domain = [ + ('model_id', '=', self.model.id), + ('ttype', '=', 'datetime'), + ('name', '=', 'create_date')] + record = self.env['ir.model.fields'].sudo().search(field_domain, limit=1) + if record.exists(): + self.time_field = record + else: + return None + + #---------------------------------------------------------- + # Read + #---------------------------------------------------------- + + @api.depends('size_parameter') + def _compute_size_parameter_value(self): + for record in self: + try: + record.size_parameter_value = int(record.size_parameter.value) + except ValueError: + record.size_parameter_value = None + + #---------------------------------------------------------- + # Create, Update, Delete + #---------------------------------------------------------- + + @api.constrains( + 'state', 'model', 'domain', + 'time_field', 'time_type', 'time', + 'size_type', 'size_parameter', 'size_order', 'size') + def validate(self): + validators = { + 'time': lambda rec: rec.time_field and rec.time_type and rec.time, + 'size': lambda rec: rec.size_order and (rec.size_parameter or rec.size), + 'domain': lambda rec: rec.domain, + } + for record in self: + if not validators[record.state](record): + raise ValidationError(_("Rule validation has failed!")) \ No newline at end of file diff --git a/muk_autovacuum/security/ir.model.access.csv b/muk_autovacuum/security/ir.model.access.csv new file mode 100644 index 0000000..a369089 --- /dev/null +++ b/muk_autovacuum/security/ir.model.access.csv @@ -0,0 +1,3 @@ +id,name,model_id/id,group_id/id,perm_read,perm_write,perm_create,perm_unlink + +access_muk_autovacuum_rules_group_cron,muk_autovacuum_rules group_rules,model_muk_autovacuum_rules,base.group_system,1,1,1,1 \ No newline at end of file diff --git a/muk_autovacuum/static/description/banner.png b/muk_autovacuum/static/description/banner.png new file mode 100644 index 0000000000000000000000000000000000000000..7540bae610b5dde675607d62226e2824f1fd2dfc GIT binary patch literal 39628 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 literal 0 HcmV?d00001 diff --git a/muk_autovacuum/static/description/icon.png b/muk_autovacuum/static/description/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..932907c1a600e8c404a63354c18680f4f1174f88 GIT binary patch literal 8433 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 +
+

MuK Auto Vacuum

+

Configure automatic garbage collection

+

MuK IT GmbH - + www.mukit.at

+
+ +
+
+ + +
+
+
+

Overview

+

Allows the administrator to create rules to + automatically garbage collect a certain model. Every rule can have a + different time interval additional constraints. An extra constraint + can be for example to only delete inactive records.

+
+
+
+ +
+

Demo

+
+
+
User:
+
+
+
apps
+
+
+
Password:
+
+
+
demo
+
+
+ +
+ +
+

Help and Support

+
Feel free to + contact us, if you need any help with your Odoo integration or + addiontal features.
+ + +
\ No newline at end of file diff --git a/muk_autovacuum/static/description/logo.png b/muk_autovacuum/static/description/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..9427ce33ea36c2ec961356d01d612bae02d48ce2 GIT binary patch literal 38064 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 literal 0 HcmV?d00001 diff --git a/muk_autovacuum/static/description/screenshot.png b/muk_autovacuum/static/description/screenshot.png new file mode 100644 index 0000000000000000000000000000000000000000..ef9395f888729198fc5bfb08c78a44384dc3c795 GIT binary patch literal 45295 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. +# +################################################################################### + +from . import test_autovacuum \ No newline at end of file diff --git a/muk_autovacuum/tests/test_autovacuum.py b/muk_autovacuum/tests/test_autovacuum.py new file mode 100644 index 0000000..e71bf6f --- /dev/null +++ b/muk_autovacuum/tests/test_autovacuum.py @@ -0,0 +1,88 @@ +################################################################################### +# +# Copyright (C) 2018 MuK IT GmbH +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero 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 Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +################################################################################### + +import logging +import datetime + +from odoo.tests import common +from odoo.tools.misc import DEFAULT_SERVER_DATETIME_FORMAT + +_logger = logging.getLogger(__name__) + +class AutoVacuumTestCase(common.TransactionCase): + + at_install = False + post_install = True + + def _setUpData(self): + model_logs = self.env['ir.logging'] + time = datetime.datetime.utcnow() - datetime.timedelta(days=60) + for index in range(0, 3): + model_logs.create({ + 'create_date': time.strftime(DEFAULT_SERVER_DATETIME_FORMAT), + 'create_uid': self.env.user.id, + 'name': "Test %s" % index, + 'type': 'server', + 'dbname': self.env.cr.dbname, + 'level': "INFO", + 'message': "TEST", + 'path': "PATH", + 'func': "TEST", + 'line': 1}) + + def _setUpRules(self): + model_rule = self.env['muk_autovacuum.rules'] + model_model = self.env['ir.model'] + model_fields = self.env['ir.model.fields'] + model_logs = model_model.search([('model', '=', 'ir.logging')], limit=1) + time_field_domain = [ + ('model_id', '=', model_logs.id), + ('ttype', '=', 'datetime'), + ('name', '=', 'create_date')] + time_field_logs = model_fields.search(time_field_domain, limit=1) + model_rule.create({ + 'name': "Delete Logs after 1 Minute", + 'state': 'time', + 'model': model_logs.id, + 'time_field': time_field_logs.id, + 'time_type': 'minutes', + 'time': 1}) + model_rule.create({ + 'name': "Delete Logs Count > 1", + 'state': 'size', + 'model': model_logs.id, + 'size': 1, + 'size_order': "id desc", + 'size_type': 'fixed'}) + model_rule.create({ + 'name': "Delete Logs with Domain", + 'state': 'domain', + 'model': model_logs.id, + 'domain': "[]"}) + + def setUp(self): + super(AutoVacuumTestCase, self).setUp() + self._setUpData() + self._setUpRules() + + def tearDown(self): + super(AutoVacuumTestCase, self).tearDown() + + def test_autovacuum(self): + self.env['ir.cron'].search([('model_id', '=', 'ir.autovacuum')]).ir_actions_server_id.run() \ No newline at end of file diff --git a/muk_autovacuum/views/rules.xml b/muk_autovacuum/views/rules.xml new file mode 100644 index 0000000..161c181 --- /dev/null +++ b/muk_autovacuum/views/rules.xml @@ -0,0 +1,134 @@ + + + + + + + + muk_autovacuum_rules.search + muk_autovacuum.rules + + + + + + + + + + + + + + + + + muk_autovacuum_rules.tree + muk_autovacuum.rules + + + + + + + + + + + + + muk_autovacuum_rules.form + muk_autovacuum.rules + +
+ +
+ +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+ + + Auto Vacuum Rules + muk_autovacuum.rules + tree,form + {'search_default_all': 1} + + + + +
\ No newline at end of file