From f38b8947a998c1032bb7dfac62a9e2f4b91e4d89 Mon Sep 17 00:00:00 2001 From: MuK IT GmbH Date: Wed, 15 Aug 2018 15:47:10 +0000 Subject: [PATCH] publish muk_autovacuum - 12.0 --- muk_autovacuum/LICENSE | 619 ++++++++++++++++++ muk_autovacuum/__init__.py | 20 + muk_autovacuum/__manifest__.py | 53 ++ muk_autovacuum/data/rules.xml | 33 + muk_autovacuum/doc/changelog.rst | 20 + muk_autovacuum/doc/index.rst | 113 ++++ muk_autovacuum/i18n/de.po | 396 +++++++++++ muk_autovacuum/i18n/muk_autovacuum.pot | 387 +++++++++++ muk_autovacuum/models/__init__.py | 21 + muk_autovacuum/models/ir_autovacuum.py | 87 +++ muk_autovacuum/models/rules.py | 318 +++++++++ muk_autovacuum/security/ir.model.access.csv | 3 + muk_autovacuum/static/description/banner.png | Bin 0 -> 43442 bytes muk_autovacuum/static/description/icon.png | Bin 0 -> 9316 bytes muk_autovacuum/static/description/index.html | 69 ++ 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 | 89 +++ muk_autovacuum/views/rules.xml | 155 +++++ 20 files changed, 2403 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/data/rules.xml 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..9d8a2de --- /dev/null +++ b/muk_autovacuum/__init__.py @@ -0,0 +1,20 @@ +################################################################################### +# +# 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 models diff --git a/muk_autovacuum/__manifest__.py b/muk_autovacuum/__manifest__.py new file mode 100644 index 0000000..5fd0a14 --- /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': '12.0.2.1.4', + 'category': 'Extra Tools', + 'license': 'AGPL-3', + 'author': 'MuK IT', + 'website': 'https://www.mukit.at', + 'live_test_url': 'https://demo.mukit.at/web/login', + 'contributors': [ + 'Mathias Markl ', + ], + 'depends': [ + 'base', + ], + 'data': [ + 'security/ir.model.access.csv', + 'views/rules.xml', + 'data/rules.xml', + ], + 'qweb': [ + 'static/src/xml/*.xml', + ], + 'images': [ + 'static/description/banner.png' + ], + 'external_dependencies': { + 'python': [], + 'bin': [], + }, + 'application': False, + 'installable': True, + 'auto_install': False, +} \ No newline at end of file diff --git a/muk_autovacuum/data/rules.xml b/muk_autovacuum/data/rules.xml new file mode 100644 index 0000000..f6b28ba --- /dev/null +++ b/muk_autovacuum/data/rules.xml @@ -0,0 +1,33 @@ + + + + + + + + Delete Logs after 2 Weeks + + + + time + weeks + 2 + + + + \ 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..b0e796f --- /dev/null +++ b/muk_autovacuum/doc/changelog.rst @@ -0,0 +1,20 @@ +`2.0.0` +------- + +- Added Python Expressions + +`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..7b1ccf3 --- /dev/null +++ b/muk_autovacuum/doc/index.rst @@ -0,0 +1,113 @@ +============== +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 mode and update the +list by clicking on the "Update Apps List" link. Now install the module by +clicking on the install button. + +Another way to install this module is via the package management for Python +(`PyPI `_). + +To install our modules using the package manager make sure +`odoo-autodiscover `_ is installed +correctly. Then open a console and install the module by entering the following +command: + +``pip install --extra-index-url https://nexus.mukit.at/repository/odoo/simple `` + +The module name consists of the Odoo version and the module name, where +underscores are replaced by a dash. + +**Module:** + +``odoo-addon-`` + +**Example:** + +``sudo -H pip3 install --extra-index-url https://nexus.mukit.at/repository/odoo/simple odoo11-addon-muk-utils`` + +Once the installation has been successfully completed, the app is already in the +correct folder. Log on to your Odoo server and go to the Apps menu. Trigger the +debug mode and update the list by clicking on the "Update Apps List" link. Now +install the module by clicking on the install button. + +The biggest advantage of this variant is that you can now also update the app +using the "pip" command. To do this, enter the following command in your console: + +``pip install --upgrade --extra-index-url https://nexus.mukit.at/repository/odoo/simple `` + +When the process is finished, restart your server and update the application in +Odoo. The steps are the same as for the installation only the button has changed +from "Install" to "Upgrade". + +You can also view available Apps directly in our `repository `_ +and find a more detailed installation guide on our `website `_. + +For modules licensed under OPL-1, you will receive access data when you purchase +the module. If the modules were not purchased directly from +`MuK IT `_ please contact our support (support@mukit.at) +with a confirmation of purchase to receive the corresponding access data. + +Upgrade +============ + +To upgrade this module, you need to: + +Download the module and add it to your Odoo addons folder. Restart the server +and log on to your Odoo server. Select the Apps menu and upgrade the module by +clicking on the upgrade button. + +If you installed the module using the "pip" command, you can also update the +module in the same way. Just type the following command into the console: + +``pip install --upgrade --extra-index-url https://nexus.mukit.at/repository/odoo/simple `` + +When the process is finished, restart your server and update the application in +Odoo, just like you would normally. + +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..34d02ee --- /dev/null +++ b/muk_autovacuum/i18n/de.po @@ -0,0 +1,396 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * muk_autovacuum +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 12.0alpha1\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2018-08-15 15:09+0000\n" +"PO-Revision-Date: 2018-08-15 17:44+0200\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.6\n" + +#. module: muk_autovacuum +#: model:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form +msgid "Warning: Warning Exception to use with raise" +msgstr "Warnung: Warnung zur Verwendung mit raise" + +#. module: muk_autovacuum +#: model:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form +msgid "date_format, datetime_format: server date and time formats" +msgstr "date_format, datetime_format: Server Datums- und Zeitformate" + +#. module: muk_autovacuum +#: model:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form +msgid "env: Odoo Environment on which the rule is triggered" +msgstr "env: Odoo Umgebung, auf der die Regel ausgelöst wird" + +#. module: muk_autovacuum +#: model:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form +msgid "logger.info(message): Python logging framework" +msgstr "logger.info(nachricht): Python-Protokollierungs-Framework" + +#. module: muk_autovacuum +#: model:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form +msgid "model: Odoo Model of the record on which the rule is triggered" +msgstr "Modell: Odoo Modell des Datensatzes, auf dem die Regel ausgelöst wird" + +#. module: muk_autovacuum +#: model:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form +msgid "time, datetime, dateutil, timezone: useful Python libraries" +msgstr "time, datetime, dateutil, timezone: nützliche Python-Bibliotheken" + +#. module: muk_autovacuum +#: model:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form +msgid "uid, user: User on which the rule is triggered" +msgstr "uid, user: Benutzer, auf dem die Regel ausgelöst wird" + +#. module: muk_autovacuum +#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__active +msgid "Active" +msgstr "Aktiv" + +#. module: muk_autovacuum +#: model:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_search +msgid "All" +msgstr "Alle" + +#. module: muk_autovacuum +#: model:ir.actions.act_window,name:muk_autovacuum.action_autovacuum_rule +#: model:ir.model,name:muk_autovacuum.model_muk_autovacuum_rules +#: model:ir.ui.menu,name:muk_autovacuum.menu_autovacuum_rules +#: model:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form +#: model:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_search +#: model:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_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__code +msgid "Code" +msgstr "Code" + +#. module: muk_autovacuum +#: selection:muk_autovacuum.rules,state:0 +msgid "Code Based" +msgstr "Codebasiert" + +#. module: muk_autovacuum +#: model:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form +msgid "Code Settings" +msgstr "Code Einstellungen" + +#. module: muk_autovacuum +#: model:ir.model.fields,help:muk_autovacuum.field_muk_autovacuum_rules__code +msgid "Code which will be executed during the clean up." +msgstr "Code, der während der Bereinigung ausgeführt wird." + +#. 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__domain +msgid "Delete all records which match the domain." +msgstr "Löschen Sie alle Datensätze, die mit der Domäne übereinstimmen." + +#. module: muk_autovacuum +#: model:ir.model.fields,help:muk_autovacuum.field_muk_autovacuum_rules__time +msgid "Delete older data than x." +msgstr "Ältere Daten als x löschen." + +#. module: muk_autovacuum +#: model:ir.model.fields,help:muk_autovacuum.field_muk_autovacuum_rules__size +#: model:ir.model.fields,help:muk_autovacuum.field_muk_autovacuum_rules__size_parameter_value +msgid "Delete records with am index greater than x." +msgstr "Datensätze mit einem Index größer als x löschen." + +#. 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.\n" +" Checks for the following fields:\n" +" - starred\n" +" - favorite\n" +" - is_starred\n" +" - is_favorite" +msgstr "" +"Löscht keine markierten Datensätze.\n" +" Überprüft die folgenden Felder:\n" +" - mit Sternen übersät\n" +" - starred\n" +" - favorite\n" +" - is_starred\n" +" - is_favorite" + +#. module: muk_autovacuum +#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__domain +msgid "Domain" +msgstr "Domain" + +#. module: muk_autovacuum +#: selection:muk_autovacuum.rules,state:0 +msgid "Domain Based" +msgstr "Domainenbasiert" + +#. module: muk_autovacuum +#: model:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form +msgid "Domain Settings" +msgstr "Domain-Einstellungen" + +#. module: muk_autovacuum +#: model:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form +msgid "Enter Python code here. Help about Python expression is available in the help tab of this document." +msgstr "Geben Sie Pyhton-Code hier ein. Hife zu Python-Ausdrücken ist in der Hilfe-Registerkarte dieses Dokuments verfügbar." + +#. module: muk_autovacuum +#: selection:muk_autovacuum.rules,size_type:0 +msgid "Fixed Value" +msgstr "Fixpunktwert" + +#. module: muk_autovacuum +#: code:addons/muk_autovacuum/models/ir_autovacuum.py:61 +#: code:addons/muk_autovacuum/models/ir_autovacuum.py:71 +#, python-format +msgid "GC domain: %s" +msgstr "GC Domain: %s" + +#. module: muk_autovacuum +#: code:addons/muk_autovacuum/models/ir_autovacuum.py:68 +#, python-format +msgid "GC domain: [] order: %s limit: %s" +msgstr "GC Domain: [] order: %s limit: %s" + +#. 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 Anhänge aus %s Einträgen" + +#. module: muk_autovacuum +#: model:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_search +msgid "Group By" +msgstr "Gruppieren nach" + +#. module: muk_autovacuum +#: model:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form +msgid "Help" +msgstr "Hilfe" + +#. module: muk_autovacuum +#: model:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form +msgid "Help with Python expressions" +msgstr "Hilfe mit Python-Ausdrücken" + +#. 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 +#: model:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_search +msgid "Model" +msgstr "Modell" + +#. module: muk_autovacuum +#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__model_name +msgid "Model Name" +msgstr "Modellname" + +#. module: muk_autovacuum +#: model:ir.model.fields,help:muk_autovacuum.field_muk_autovacuum_rules__model +msgid "Model on which the rule is applied." +msgstr "Modell, auf das die Regel angewendet wird." + +#. 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__name +msgid "Name" +msgstr "Name" + +#. module: muk_autovacuum +#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__only_inactive +msgid "Only Archived" +msgstr "Nur Archiviert" + +#. 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 "Löschen Sie nur archivierte Sätze." + +#. module: muk_autovacuum +#: model:ir.model.fields,help:muk_autovacuum.field_muk_autovacuum_rules__only_attachments +msgid "Only delete record attachments." +msgstr "Löschen Sie nur Datensatzanhänge." + +#. module: muk_autovacuum +#: model:ir.model.fields,help:muk_autovacuum.field_muk_autovacuum_rules__size_order +msgid "Order by which the index is defined." +msgstr "Reihenfolge, in der der Index definiert ist." + +#. module: muk_autovacuum +#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__protect_starred +msgid "Protect Starred" +msgstr "Schützt Favoriten" + +#. module: muk_autovacuum +#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__state +msgid "Rule Type" +msgstr "Regeltyp" + +#. module: muk_autovacuum +#: code:addons/muk_autovacuum/models/rules.py:318 +#, python-format +msgid "Rule validation has failed!" +msgstr "Die Regelvalidierung ist fehlgeschlagen!" + +#. module: muk_autovacuum +#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__sequence +msgid "Sequence" +msgstr "Reihenfolge" + +#. module: muk_autovacuum +#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__size +#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__size_parameter_value +msgid "Size" +msgstr "Größe" + +#. module: muk_autovacuum +#: selection:muk_autovacuum.rules,state:0 +msgid "Size Based" +msgstr "Größenbasierend" + +#. module: muk_autovacuum +#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__size_order +msgid "Size Order" +msgstr "Größensortierung" + +#. module: muk_autovacuum +#: model:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form +msgid "Size Settings" +msgstr "Größeneinstellungen" + +#. module: muk_autovacuum +#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__size_type +msgid "Size Type" +msgstr "Größe Typ" + +#. module: muk_autovacuum +#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__size_parameter +#: selection:muk_autovacuum.rules,size_type:0 +msgid "System Parameter" +msgstr "Systemparameter" + +#. module: muk_autovacuum +#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__time +msgid "Time" +msgstr "Zeit" + +#. module: muk_autovacuum +#: selection:muk_autovacuum.rules,state:0 +msgid "Time Based" +msgstr "Zeitbasiert" + +#. module: muk_autovacuum +#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__time_field +msgid "Time Field" +msgstr "Zeitfeld" + +#. module: muk_autovacuum +#: model:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form +msgid "Time Settings" +msgstr "Zeiteinstellungen" + +#. module: muk_autovacuum +#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__time_type +msgid "Time Unit" +msgstr "Zeiteinheit" + +#. module: muk_autovacuum +#: model:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form +msgid "Various fields may use Python code or Python expressions. The following variables can be used:" +msgstr "Einige Felder erlauben Python Code oder Python Ausdrücke. Die folgenden Variablen können verwendet werden:" + +#. 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.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form +msgid "e.g. Delete Logs after 30 Days" +msgstr "z.B. Logs nach 30 Tagen löschen" + +#. 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..11c10fd --- /dev/null +++ b/muk_autovacuum/i18n/muk_autovacuum.pot @@ -0,0 +1,387 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * muk_autovacuum +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 12.0alpha1\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2018-08-15 15:09+0000\n" +"PO-Revision-Date: 2018-08-15 15:09+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.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form +msgid "Warning: Warning Exception to use with raise" +msgstr "" + +#. module: muk_autovacuum +#: model:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form +msgid "date_format, datetime_format: server date and time formats" +msgstr "" + +#. module: muk_autovacuum +#: model:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form +msgid "env: Odoo Environment on which the rule is triggered" +msgstr "" + +#. module: muk_autovacuum +#: model:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form +msgid "logger.info(message): Python logging framework" +msgstr "" + +#. module: muk_autovacuum +#: model:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form +msgid "model: Odoo Model of the record on which the rule is triggered" +msgstr "" + +#. module: muk_autovacuum +#: model:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form +msgid "time, datetime, dateutil, timezone: useful Python libraries" +msgstr "" + +#. module: muk_autovacuum +#: model:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form +msgid "uid, user: User on which the rule is triggered" +msgstr "" + +#. module: muk_autovacuum +#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__active +msgid "Active" +msgstr "" + +#. module: muk_autovacuum +#: model:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_search +msgid "All" +msgstr "" + +#. module: muk_autovacuum +#: model:ir.actions.act_window,name:muk_autovacuum.action_autovacuum_rule +#: model:ir.model,name:muk_autovacuum.model_muk_autovacuum_rules +#: model:ir.ui.menu,name:muk_autovacuum.menu_autovacuum_rules +#: model:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form +#: model:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_search +#: model:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_tree +msgid "Auto Vacuum Rules" +msgstr "" + +#. module: muk_autovacuum +#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__code +msgid "Code" +msgstr "" + +#. module: muk_autovacuum +#: selection:muk_autovacuum.rules,state:0 +msgid "Code Based" +msgstr "" + +#. module: muk_autovacuum +#: model:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form +msgid "Code Settings" +msgstr "" + +#. module: muk_autovacuum +#: model:ir.model.fields,help:muk_autovacuum.field_muk_autovacuum_rules__code +msgid "Code which will be executed during the clean up." +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__domain +msgid "Delete all records which match the domain." +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,help:muk_autovacuum.field_muk_autovacuum_rules__size +#: model:ir.model.fields,help:muk_autovacuum.field_muk_autovacuum_rules__size_parameter_value +msgid "Delete records with am index greater 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.\n" +" Checks for the following fields:\n" +" - starred\n" +" - favorite\n" +" - is_starred\n" +" - is_favorite" +msgstr "" + +#. module: muk_autovacuum +#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__domain +msgid "Domain" +msgstr "" + +#. module: muk_autovacuum +#: selection:muk_autovacuum.rules,state:0 +msgid "Domain Based" +msgstr "" + +#. module: muk_autovacuum +#: model:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form +msgid "Domain Settings" +msgstr "" + +#. module: muk_autovacuum +#: model:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form +msgid "Enter Python code here. Help about Python expression is available in the help tab of this document." +msgstr "" + +#. module: muk_autovacuum +#: selection:muk_autovacuum.rules,size_type:0 +msgid "Fixed Value" +msgstr "" + +#. module: muk_autovacuum +#: code:addons/muk_autovacuum/models/ir_autovacuum.py:61 +#: code:addons/muk_autovacuum/models/ir_autovacuum.py:71 +#, python-format +msgid "GC domain: %s" +msgstr "" + +#. module: muk_autovacuum +#: code:addons/muk_autovacuum/models/ir_autovacuum.py:68 +#, python-format +msgid "GC domain: [] order: %s limit: %s" +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 +#: model:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_search +msgid "Group By" +msgstr "" + +#. module: muk_autovacuum +#: model:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form +msgid "Help" +msgstr "" + +#. module: muk_autovacuum +#: model:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form +msgid "Help with Python expressions" +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 +#: model:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_search +msgid "Model" +msgstr "" + +#. module: muk_autovacuum +#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__model_name +msgid "Model Name" +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__name +msgid "Name" +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,help:muk_autovacuum.field_muk_autovacuum_rules__size_order +msgid "Order by which the index is defined." +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__state +msgid "Rule Type" +msgstr "" + +#. module: muk_autovacuum +#: code:addons/muk_autovacuum/models/rules.py:318 +#, python-format +msgid "Rule validation has failed!" +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__size +#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__size_parameter_value +msgid "Size" +msgstr "" + +#. module: muk_autovacuum +#: selection:muk_autovacuum.rules,state:0 +msgid "Size Based" +msgstr "" + +#. module: muk_autovacuum +#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__size_order +msgid "Size Order" +msgstr "" + +#. module: muk_autovacuum +#: model:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form +msgid "Size Settings" +msgstr "" + +#. module: muk_autovacuum +#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__size_type +msgid "Size Type" +msgstr "" + +#. module: muk_autovacuum +#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__size_parameter +#: selection:muk_autovacuum.rules,size_type:0 +msgid "System Parameter" +msgstr "" + +#. module: muk_autovacuum +#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__time +msgid "Time" +msgstr "" + +#. module: muk_autovacuum +#: selection:muk_autovacuum.rules,state:0 +msgid "Time Based" +msgstr "" + +#. module: muk_autovacuum +#: model:ir.model.fields,field_description:muk_autovacuum.field_muk_autovacuum_rules__time_field +msgid "Time Field" +msgstr "" + +#. module: muk_autovacuum +#: model:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form +msgid "Time Settings" +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 +#: model:ir.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form +msgid "Various fields may use Python code or Python expressions. The following variables can be used:" +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.ui.view,arch_db:muk_autovacuum.view_autovacuum_rule_form +msgid "e.g. Delete Logs after 30 Days" +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..9eb3af4 --- /dev/null +++ b/muk_autovacuum/models/ir_autovacuum.py @@ -0,0 +1,87 @@ +################################################################################### +# +# 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, fields +from odoo.tools.safe_eval import safe_eval + +_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: + if rule.state in ['time', 'size', 'domain']: + 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, '<', fields.Datetime.to_string(computed_time))] + if rule.protect_starred: + for field in rule.model.field_id: + if field.name in ['starred', 'favorite', 'is_starred', 'is_favorite']: + domain.append((field.name, '=', 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) + domain = safe_eval(rule.domain, rules._get_eval_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) + elif rule.state == 'code': + safe_eval(rule.code.strip(), rules._get_eval_code_context(rule), mode="exec") + 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..d06928b --- /dev/null +++ b/muk_autovacuum/models/rules.py @@ -0,0 +1,318 @@ +################################################################################### +# +# 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 pytz import timezone + +from odoo import _ +from odoo import models, api, fields +from odoo.exceptions import ValidationError, Warning +from odoo.tools import DEFAULT_SERVER_DATE_FORMAT +from odoo.tools import DEFAULT_SERVER_DATETIME_FORMAT +from odoo.tools.safe_eval import safe_eval, test_python_expr + +_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'), + ('code', 'Code 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)], + 'code': [('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)], + 'code': [('invisible', True)]}) + + time = fields.Integer( + string='Time', + default=1, + states={ + 'time': [('required', True)], + 'size': [('invisible', True)], + 'domain': [('invisible', True)], + 'code': [('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)], + 'code': [('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)], + 'code': [('invisible', True)]}) + + size_parameter_value = fields.Integer( + compute='_compute_size_parameter_value', + string='Size Value', + states={ + 'time': [('invisible', True)], + 'size': [('readonly', True)], + 'domain': [('invisible', True)], + 'code': [('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)], + 'code': [('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)], + 'code': [('invisible', True)]}, + help="Delete records with am index greater than x.") + + domain = fields.Char( + string='Domain', + states={ + 'time': [('invisible', True)], + 'size': [('invisible', True)], + 'domain': [('required', True)], + 'code': [('invisible', True)]}, + help="Delete all records which match the domain.") + + code = fields.Text( + string='Code', + states={ + 'time': [('invisible', True)], + 'size': [('invisible', True)], + 'domain': [('invisible', True)] , + 'code': [('required', True)]}, + help="Code which will be executed during the clean up.") + + protect_starred = fields.Boolean( + string='Protect Starred', + default=True, + states={ + 'time': [('invisible', False)], + 'size': [('invisible', True)], + 'domain': [('invisible', True)], + 'code': [('invisible', True)]}, + help="""Do not delete starred records. + Checks for the following fields: + - starred + - favorite + - is_starred + - is_favorite""") + + only_inactive = fields.Boolean( + string='Only Archived', + default=False, + states={ + 'time': [('invisible', False)], + 'size': [('invisible', True)], + 'domain': [('invisible', True)], + 'code': [('invisible', True)]}, + help="Only delete archived records.") + + only_attachments = fields.Boolean( + string='Only Attachments', + default=False, + states={ + 'time': [('invisible', False)], + 'size': [('invisible', False)], + 'domain': [('invisible', False)], + 'code': [('invisible', True)]}, + help="Only delete record attachments.") + + #---------------------------------------------------------- + # Functions + #---------------------------------------------------------- + + @api.model + def _get_eval_domain_context(self): + return { + 'datetime': datetime, + 'dateutil': dateutil, + 'time': time, + 'uid': self.env.uid, + 'user': self.env.user + } + + @api.model + def _get_eval_code_context(self, rule): + return { + 'env': self.env, + 'model': self.env[rule.model_name], + 'uid': self.env.user.id, + 'user': self.env.user, + 'time': time, + 'datetime': datetime, + 'dateutil': dateutil, + 'timezone': timezone, + 'date_format': DEFAULT_SERVER_DATE_FORMAT, + 'datetime_format': DEFAULT_SERVER_DATETIME_FORMAT, + 'Warning': Warning, + 'logger': logging.getLogger("%s (%s)" % (__name__, rule.name)), + } + + #---------------------------------------------------------- + # 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('code') + def _check_code(self): + for record in self.sudo().filtered('code'): + message = test_python_expr(expr=record.code.strip(), mode="exec") + if message: + raise ValidationError(message) + + @api.constrains( + 'state', 'model', 'domain', 'code', + '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, + 'code': lambda rec: rec.code, + } + 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..488c2ebe8a458ee8c5f7556f11fc8761279c5367 GIT binary patch literal 43442 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

g!r)%gZnS{^tyizB>4`n-K)NFMu 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 literal 0 HcmV?d00001 diff --git a/muk_autovacuum/static/description/index.html b/muk_autovacuum/static/description/index.html new file mode 100644 index 0000000..099721e --- /dev/null +++ b/muk_autovacuum/static/description/index.html @@ -0,0 +1,69 @@ +

+
+

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..e4b23f7 --- /dev/null +++ b/muk_autovacuum/tests/test_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 logging +import datetime + +from odoo.tests import common + +_logger = logging.getLogger(__name__) + +class AutoVacuumTestCase(common.TransactionCase): + + at_install = False + post_install = True + + def setUp(self): + super(AutoVacuumTestCase, self).setUp() + # create test 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) + self.rules = self.env['muk_autovacuum.rules'] + self.rules |= self.rules.create({ + 'name': "Delete Logs after 2 Day", + 'state': 'time', + 'model': model_logs.id, + 'time_field': time_field_logs.id, + 'time_type': 'days', + 'time': 2}) + self.rules |= self.rules.create({ + 'name': "Delete Logs Count > 1", + 'state': 'size', + 'model': model_logs.id, + 'size': 1, + 'size_order': "id desc", + 'size_type': 'fixed'}) + self.rules |= self.rules.create({ + 'name': "Delete Logs with Domain", + 'state': 'domain', + 'model': model_logs.id, + 'domain': "[]"}) + # create test logs + self.logs = self.env['ir.logging'] + time = datetime.datetime.utcnow() + for index in range(0, 10): + self.logs |= self.logs.create({ + 'create_date': time - datetime.timedelta(days=index), + '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 tearDown(self): + super(AutoVacuumTestCase, self).tearDown() + self.logs.unlink() + self.rules.unlink() + + def test_autovacuum(self): + count_before = self.env['ir.logging'].search([], count=True) + self.env['ir.cron'].search([('model_id', '=', 'ir.autovacuum')]).ir_actions_server_id.run() + count_after = self.env['ir.logging'].search([], count=True) + self.assertTrue(count_before > count_after) + \ 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..9ee9cd4 --- /dev/null +++ b/muk_autovacuum/views/rules.xml @@ -0,0 +1,155 @@ + + + + + + + + muk_autovacuum_rules.search + muk_autovacuum.rules + + + + + + + + + + + + + + + + muk_autovacuum_rules.tree + muk_autovacuum.rules + + + + + + + + + + + + + muk_autovacuum_rules.form + muk_autovacuum.rules + +
+ +
+ +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

Help with Python expressions

+

Various fields may use Python code or Python expressions. The following variables can be used:

+
    +
  • uid, user: User on which the rule is triggered
  • +
  • env: Odoo Environment on which the rule is triggered
  • +
  • model: Odoo Model of the record on which the rule is triggered
  • +
  • time, datetime, dateutil, timezone: useful Python libraries
  • +
  • date_format, datetime_format: server date and time formats
  • +
  • logger.info(message): Python logging framework
  • +
  • Warning: Warning Exception to use with raise
  • +
+
+
+
+
+
+
+
+
+ + + Auto Vacuum Rules + muk_autovacuum.rules + tree,form + {'search_default_all': 1} + + + + +
\ No newline at end of file