diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000..0ad25db4 --- /dev/null +++ b/LICENSE @@ -0,0 +1,661 @@ + 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 + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU 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 . + +Also add information on how to contact you by electronic and paper mail. + + If your software can interact with users remotely through a computer +network, you should also make sure that it provides a way for users to +get its source. For example, if your program is a web application, its +interface could display a "Source" link that leads users to an archive +of the code. There are many ways you could offer source, and different +solutions will be better for different programs; see section 13 for the +specific requirements. + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU AGPL, see +. diff --git a/MAC_build_install.sh b/MAC_build_install.sh new file mode 100644 index 00000000..f7dbd8b2 --- /dev/null +++ b/MAC_build_install.sh @@ -0,0 +1,182 @@ +#!/bin/bash + +# Store the actual path +actual_path=$(pwd) + +# Get the path of LogDoctor-git's folder and move in +docdir="$(dirname $0)" +cd "$docdir" + +# Check CMake availability +if [[ $(which cmake) =~ ^/ ]] +then + $() +else + echo "Error: Cmake not found in PATH, please add it or compilation won't socceed" + exit +fi + +# Check Qt availability +if [[ $(which qmake) =~ ^/ ]] +then + $() +else + echo "Error: Qt-clang not found in PATH, please add it or compilation won't socceed" + exit +fi + +# Check the existence of a previous executable file +if [ -e /Applications/LogDoctor.app ] +then + while true; + do + echo "Warning: the path /Applications/LogDoctor.app already exists" + printf "If you choose to continue, the actual content will be overwritten\nContinue? [y/n] : " + read agree + case "$agree" + in + "y" | "Y" | [yY][eE][sS]) + printf "\n" + break + ;; + *) + exit + ;; + esac + done +fi + +# Start the compilation process +echo "Starting compilation process" + +# Make a build folder +if [ -d build ] +then + rm -r build +fi +mkdir build && cd build + +# Prepare the cmake files +cmake ../logdoctor -DCMAKE_BUILD_TYPE=MinSizeRel +if [[ "$?" != "0" ]] +then + # an error occured during preparation + echo "Error: failed to prepare cmake files" + exit +fi + +# Build the project +cmake --build ./ --target all +if [[ "$?" == "0" ]] +then + # compiled succesfully + chmod 755 ./LogDoctor.app/Contents/MacOS/LogDoctor +else + # an error occured during compilation + echo "Error: failed to compile" + exit +fi + +# Compilation finished +wait +echo "Compilation finished" + +# Start installing LogDoctor +echo "Starting installation process" +cd ../installation_stuff/ + +if [ -e ~/Lybrary/Preferences/LogDoctor ] +then + if [ -e ~/Lybrary/Preferences/LogDoctor/logdoctor.conf ] + then + # A configuration file already exists + while true; + do + echo "Warning: a configuration file already exists" + printf "If you choose 'YES' the current file will be overwritten\nIf you choose 'NO' the current file will be kept\nOverwrite? [y/n] : " + read agree + case "$agree" + in + "y" | "Y" | [yY][eE][sS]) + printf "\n" + cp ./logdoctor.conf ~/Lybrary/Preferences/LogDoctor/ + if [[ "$?" != "0" ]] + then + # an error occured during compilation + echo "Error: failed to copy configuration file" + exit + fi + break + ;; + "n" | "N" | [nN][oO]) + break + ;; + *) + echo "Invalid answer" + ;; + esac + done + fi +else + mkdir -p ~/Lybrary/Preferences/LogDoctor + if [[ "$?" != "0" ]] + then + echo "Error: failed to create directory: ~/Lybrary/Preferences/LogDoctor" + exit + fi + cp ./logdoctor.conf ~/Lybrary/Preferences/LogDoctor/ + if [[ "$?" != "0" ]] + then + echo "Error: failed to copy configuration file" + exit + fi +fi + + +if [ ! -e ~/"Lybrary/Application Support/LogDoctor" ] +then + mkdir -p ~/"Lybrary/Application Support/LogDoctor" + if [[ "$?" != "0" ]] + then + echo "Error: failed to create directory: ~/Lybrary/Application Support/LogDoctor" + exit + fi +fi +if [ ! -e ~/"Lybrary/Application Support/LogDoctor/help" ] +then + rm -r ~/"Lybrary/Application Support/LogDoctor/help" + if [[ "$?" != "0" ]] + then + echo "Error: failed to remove old resources: ~/Lybrary/Application Support/LogDoctor/help" + exit + fi +fi +cp -r ./logdocdata/help ~/"Lybrary/Application Support/LogDoctor/" +if [[ "$?" != "0" ]] +then + echo "Error: failed to copy LogDoctor's data" + exit +fi + + +cp -r ./osx_bundle/* ../build/LogDoctor.app/Contents/ +if [ -e /Applications/LogDoctor.app ] +then + sudo rm -r /Applications/LogDoctor.app + if [[ "$?" != "0" ]] + then + echo "Error: failed to remove old bundle: /Applications/LogDoctor.app" + exit + fi +fi +sudo mv ../build/LogDoctor.app /Applications/ +if [[ "$?" != "0" ]] +then + echo "Error: failed to copy the executable" + exit +fi + + +# Installation finished +echo "Installation finished" +cd "$actual_path" diff --git a/MAC_build_update.sh b/MAC_build_update.sh new file mode 100644 index 00000000..1661c28e --- /dev/null +++ b/MAC_build_update.sh @@ -0,0 +1,109 @@ +#!/bin/bash + +# Store the actual path +actual_path=$(pwd) + +# Get the path of LogDoctor-git's folder and move in +docdir="$(dirname $0)" +cd "$docdir" + +# Check cmake availability +if [[ $(which cmake) =~ ^/ ]] +then + $() +else + echo "Error: Cmake not found in PATH, please add it or compilation won't socceed" + exit +fi + +# Check Qt availability +if [[ $(which qmake) =~ ^/ ]] +then + $() +else + echo "Error: Qt-clang not found in PATH, please add it or compilation won't socceed" + exit +fi + +# Check the existence of a previous executable file +if [ ! -e /Applications/LogDoctor.app ] +then + echo "Warning: no previous installation detected, please run the installation script instead" + exit +fi + +# Start the compilation process +echo "Starting compilation process" + +# Make a build folder +mkdir build && cd build + +# Prepare the cmake files +cmake ../logdoctor -DCMAKE_BUILD_TYPE=MinSizeRel +if [[ "$?" != "0" ]] +then + # an error occured during preparation + echo "Error: failed to prepare cmake files" + exit +fi + +# Build the project +cmake --build ./ --target all +if [[ "$?" == "0" ]] +then + # compiled succesfully + chmod 755 ./LogDoctor.app/Contents/MacOS/LogDoctor +else + # an error occured during compilation + echo "Error: failed to compile" + exit +fi + +# Compilation finished +wait +echo "Compilation finished" + +# Start installing LogDoctor +echo "Starting update process" +cd ../installation_stuff/ + + +if [ ! -e ~/"Lybrary/Application Support/LogDoctor" ] +then + mkdir -p ~/"Lybrary/Application Support/LogDoctor" + if [[ "$?" != "0" ]] + then + echo "Error: failed to create directory: '~/Lybrary/Application Support/LogDoctor'" + exit + fi +fi +if [ ! -e ~/"Lybrary/Application Support/LogDoctor/help" ] +then + rm -r ~/"Lybrary/Application Support/LogDoctor/help" + if [[ "$?" != "0" ]] + then + echo "Error: failed to remove old resources: ~/Lybrary/Application Support/LogDoctor/help" + exit + fi +fi +cp -r ./logdocdata/help ~/"Lybrary/Application Support/LogDoctor" +if [[ "$?" != "0" ]] +then + echo "Error: failed to copy LogDoctor's data" + exit +fi + + +cp ./osx_bundle/* ../build/LogDoctor.app/Contents/ +sudo rm -r /Applications/LogDoctor.app +sudo mv ../build/LogDoctor.app /Applications/ +if [[ "$?" != "0" ]] +then + echo "Error: failed to copy the executable" + exit +fi + + +# Update finished +echo "Update finished" +cd "$actual_path" diff --git a/WIN_build_install_1.bat b/WIN_build_install_1.bat new file mode 100644 index 00000000..bbc95c9e --- /dev/null +++ b/WIN_build_install_1.bat @@ -0,0 +1,95 @@ + +@ECHO off + +ECHO Initializing + +:: Store the actual path +FOR /F "tokens=* USEBACKQ" %%e IN (`cd`) DO SET actual_path=%%e + +:: Get the path of LogDoctor-git's folder and move in +SET logdocdir=%~dp0 +SET logdocdir=%logdocdir:\=/% +IF "%logdocdir:~-1%"=="/" SET logdocdir=%logdocdir:~0,-1% +cd %logdocdir% + + +:: Call the builder +IF NOT EXIST "builder.bat" ( + ECHO: + ECHO Error: builder not found + cd "%actual_path%" + PAUSE + EXIT /B 1 +) + +CALL builder.bat "%actual_path%" +IF ERRORLEVEL 1 ( + ECHO: + ECHO Compilation failed + cd "%actual_path%" + PAUSE + EXIT /B 1 +) + + +:: Start installing LogDoctor +ECHO: +ECHO Starting installation process + +cd ..\installation_stuff\ + +SET data_path=%USERPROFILE%\AppData\Local\LogDoctor +IF NOT EXIST "%data_path%" mkdir "%data_path%" + +IF NOT EXIST "%data_path%\logdoctor.conf" GOTO :step11 + +:loop9 +ECHO: +ECHO Warning: a configuration file already exists +ECHO If you choose 'YES' the current file will be overwritten +ECHO If you choose 'NO' the current file will be kept +SET /P agree=Overwrite? [y/n] : + +IF "%agree%"=="y" ( + GOTO :step10 +) +IF "%agree%"=="Y" ( + GOTO :step10 +) +IF "%agree%"=="n" ( + GOTO :step11 +) +IF "%agree%"=="N" ( + GOTO :step11 +) +ECHO NOT A VALID ANSWER +GOTO :loop9 + +:step10 + +copy /V /Y logdoctor.conf %data_path%\ +IF ERRORLEVEL 1 ( + ECHO: + ECHO Error: failed to copy configuration file + cd "%actual_path%" + PAUSE + EXIT /B 1 +) + +:step11 + +xcopy /E /V /Y logdocdata %data_path%\ +IF ERRORLEVEL 1 ( + ECHO: + ECHO Error: failed to copy LogDoctor's data + cd "%actual_path%" + PAUSE + EXIT /B 1 +) + + +:: End Of Part 1 +ECHO: +ECHO First part is done, please run 'WIN_build_install_2' as Administrator +cd "%actual_path%" +PAUSE diff --git a/WIN_build_install_2.bat b/WIN_build_install_2.bat new file mode 100644 index 00000000..fe3efa0f --- /dev/null +++ b/WIN_build_install_2.bat @@ -0,0 +1,116 @@ + +@ECHO off + +:: Store the actual path +SET actual_path=%1 + +:: Get the path of LogDoctor-git's folder and move in +SET logdocdir=%~dp0 +SET logdocdir=%logdocdir:\=/% +IF "%logdocdir:~-1%"=="/" SET logdocdir=%logdocdir:~0,-1% +cd %logdocdir% + + +:: Check the existence of a previous installation +IF NOT EXIST "C:\Program Files\LogDoctor\LogDoctor.exe" GOTO :step1 + +:loop0 +ECHO: +ECHO Warning: a previous installation already exists +ECHO If you choose to continue, the actual content will be erased +SET /P agree=Continue? [y/n] : + +IF "%agree%"=="y" ( + GOTO :step1 +) +IF "%agree%"=="Y" ( + GOTO :step1 +) +IF "%agree%"=="n" ( + cd "%actual_path%" + EXIT /B 1 +) +IF "%agree%"=="N" ( + cd "%actual_path%" + EXIT /B 1 +) +ECHO NOT A VALID ANSWER +GOTO :loop0 + +:step1 + +SET exec_path=C:\Program Files\LogDoctor + +IF NOT EXIST "%exec_path%" GOTO :step2 + +rmdir /S /Q "%exec_path%" +IF ERRORLEVEL 1 ( + ECHO: + ECHO Error: failed to renew the executable directory + cd "%actual_path%" + PAUSE + EXIT /B 1 +) + +:step2 + +xcopy /E /I /V /Y build\LogDoctor "%exec_path%" +IF ERRORLEVEL 1 ( + ECHO: + ECHO Error: failed to copy the executable + cd "%actual_path%" + PAUSE + EXIT /B 1 +) + + +SET link_path=C:\ProgramData\Microsoft\Windows\Start Menu\Programs\LogDoctor + +IF NOT EXIST "%link_path%" GOTO :step3 + +rmdir /S /Q "%link_path%" +IF ERRORLEVEL 1 ( + ECHO: + ECHO Error: failed to remove old menu entry + cd "%actual_path%" + PAUSE + EXIT /B 1 +) + +:step3 + +mkdir "%link_path%" + +SET link_path=%link_path%\LogDoctor.exe + +IF NOT EXIST "%link_path%" GOTO :step4 + +del "%link_path%" +IF ERRORLEVEL 1 ( + ECHO: + ECHO Error: failed to remove symlink + cd "%actual_path%" + PAUSE + EXIT /B 1 +) + +:step4 + +mklink "%link_path%" "%exec_path%\LogDoctor.exe" + + +copy /V /Y installation_stuff\LogDoctor.svg "%exec_path%\LogDoctor.svg" +IF ERRORLEVEL 1 ( + ECHO: + ECHO Error: failed to copy the icon + cd "%actual_path%" + PAUSE + EXIT /B 1 +) + + +:: Installation finished +ECHO: +ECHO Installation finished +cd "%actual_path%" +PAUSE diff --git a/WIN_build_update_1.bat b/WIN_build_update_1.bat new file mode 100644 index 00000000..b5a45e0e --- /dev/null +++ b/WIN_build_update_1.bat @@ -0,0 +1,68 @@ + +@ECHO off + +ECHO Initializing + +:: Store the actual path +FOR /F "tokens=* USEBACKQ" %%e IN (`cd`) DO SET actual_path=%%e + +:: Get the path of LogDoctor-git's folder and move in +SET logdocdir=%~dp0 +SET logdocdir=%logdocdir:\=/% +IF "%logdocdir:~-1%"=="/" SET logdocdir=%logdocdir:~0,-1% +cd %logdocdir% + + +:: Call the builder +IF NOT EXIST "builder.bat" ( + ECHO: + ECHO Error: builder not found + cd "%actual_path%" + PAUSE + EXIT /B 1 +) + +CALL builder.bat "%actual_path%" +IF ERRORLEVEL 1 ( + ECHO: + ECHO Compilation failed + cd "%actual_path%" + PAUSE + EXIT /B 1 +) + + +:: Start updating LogDoctor +ECHO "Starting update process" +cd ../installation_stuff/ + + +SET data_path=%USERPROFILE%\AppData\Local\LogDoctor +IF EXIST "%data_path%" GOTO :step1 + +mkdir "%data_path%" +IF ERRORLEVEL 1 ( + ECHO Error: failed to create directory: '%data_path%' + cd "%actual_path%" + PAUSE + EXIT /B 1 +) + + +:step1 + +xcopy /E /V /Y logdocdata %data_path%\ +IF ERRORLEVEL 1 ( + ECHO: + ECHO Error: failed to copy LogDoctor's data + cd "%actual_path%" + PAUSE + EXIT /B 1 +) + + +:: End Of Part 1 +ECHO: +ECHO First part is done, please run 'WIN_build_update_2' as Administrator +cd "%actual_path%" +PAUSE diff --git a/WIN_build_update_2.bat b/WIN_build_update_2.bat new file mode 100644 index 00000000..69c5534a --- /dev/null +++ b/WIN_build_update_2.bat @@ -0,0 +1,88 @@ + +@ECHO off + +:: Store the actual path +SET actual_path=%1 + +:: Get the path of LogDoctor-git's folder and move in +SET logdocdir=%~dp0 +SET logdocdir=%logdocdir:\=/% +IF "%logdocdir:~-1%"=="/" SET logdocdir=%logdocdir:~0,-1% +cd %logdocdir% + + +SET exec_path=C:\Program Files\LogDoctor + +IF NOT EXIST "%exec_path%" GOTO :step1 + +rmdir /S /Q "%exec_path%" +IF ERRORLEVEL 1 ( + ECHO: + ECHO Error: failed to renew the executable directory + cd "%actual_path%" + PAUSE + EXIT /B 1 +) + +:step1 + +xcopy /E /I /V /Y build\LogDoctor "%exec_path%" +IF ERRORLEVEL 1 ( + ECHO: + ECHO Error: failed to copy the executable + cd "%actual_path%" + PAUSE + EXIT /B 1 +) + + +SET link_path=C:\ProgramData\Microsoft\Windows\Start Menu\Programs\LogDoctor + +IF NOT EXIST "%link_path%" GOTO :step2 + +rmdir /S /Q "%link_path%" +IF ERRORLEVEL 1 ( + ECHO: + ECHO Error: failed to remove old menu entry + cd "%actual_path%" + PAUSE + EXIT /B 1 +) + +:step2 + +mkdir "%link_path%" + +SET link_path=%link_path%\LogDoctor.exe + +IF NOT EXIST "%link_path%" GOTO :step3 + +del "%link_path%" +IF ERRORLEVEL 1 ( + ECHO: + ECHO Error: failed to remove symlink + cd "%actual_path%" + PAUSE + EXIT /B 1 +) + +:step3 + +mklink "%link_path%" "%exec_path%\LogDoctor.exe" + + +copy /V /Y installation_stuff\LogDoctor.svg "%exec_path%\LogDoctor.svg" +IF ERRORLEVEL 1 ( + ECHO: + ECHO Error: failed to copy the icon + cd "%actual_path%" + PAUSE + EXIT /B 1 +) + + +:: Update finished +ECHO: +ECHO "Update finished" +cd "%actual_path%" +PAUSE diff --git a/build_install.sh b/build_install.sh new file mode 100644 index 00000000..c5fb7687 --- /dev/null +++ b/build_install.sh @@ -0,0 +1,153 @@ +#!/bin/bash + +# Store the actual path +current_path=$(pwd) + +# Get the path of LogDoctor-git's folder and move in +docdir="$(dirname $(realpath $0))" +cd "$docdir" + +# Check cmake availability +which cmake &> /dev/null +if [[ "$?" != "0" ]] +then + echo "$(tput setaf 1)Error:$(tput sgr0) Cmake is not installed" + exit +fi + +# Check the existence of a previous executable file +if [ -e /usr/bin/logdoctor ] +then + echo "$(tput setaf 11)Warning:$(tput sgr0) a previous installation exists, please run the $(tput bold)update$(tput sgr0) script instead" + exit +fi + +# Start the compilation process +echo "$(tput setaf 12)==>$(tput sgr0) $(tput bold)Building$(tput sgr0)" + +# Make a build folder +if [ -e build ] +then + rm -r build + if [[ "$?" != "0" ]] + then + echo "$(tput setaf 1)Error:$(tput sgr0) failed to remove existing build directory" + exit + fi +fi +mkdir build +if [[ "$?" != "0" ]] +then + echo "$(tput setaf 1)Error:$(tput sgr0) failed to create build directory" + exit +fi +cd build + +# Prepare the cmake files +cmake ../logdoctor -DCMAKE_BUILD_TYPE=MinSizeRel +if [[ "$?" != "0" ]] +then + # an error occured during preparation + echo "$(tput setaf 1)Error:$(tput sgr0) failed to prepare build files" + exit +fi + +# Build the project +cmake --build ./ --target all +if [[ "$?" == "0" ]] +then + # compiled succesfully + mv LogDoctor logdoctor +else + # an error occured during compilation + echo "$(tput setaf 1)Error:$(tput sgr0) failed to compile" + exit +fi + +# Compilation finished +wait +echo "$(tput setaf 10)-->$(tput sgr0) Built succesfully" + +# Start installing LogDoctor +echo "$(tput setaf 12)==>$(tput sgr0) $(tput bold)Installing$(tput sgr0)" +cd ../installation_stuff/ + +if [ ! -d ~/.config/LogDoctor ] +then + mkdir -p ~/.config/LogDoctor + if [[ "$?" != "0" ]] + then + echo "$(tput setaf 1)Error:$(tput sgr0) failed to create directory: ~/.config/LogDoctor" + exit + fi +fi +chmod 644 ./logdoctor.conf +install -DC ./logdoctor.conf -t ~/.config/LogDoctor +if [[ "$?" != "0" ]] +then + echo "$(tput setaf 1)Error:$(tput sgr0) failed to copy configuration file" + exit +fi + + +if [ ! -d /usr/share/LogDoctor ] +then + sudo mkdir -p /usr/share/LogDoctor + if [[ "$?" != "0" ]] + then + echo "$(tput setaf 1)Error:$(tput sgr0) failed to create directory: /usr/share/LogDoctor" + exit + fi +fi +chmod 644 ./logdocdata/help/*/* +chmod 444 ./logdocdata/licenses/* +which rsync &> /dev/null +if [[ "$?" == "0" ]] +then + sudo rsync -r --delete ./logdocdata /usr/share/LogDoctor + if [[ "$?" != "0" ]] + then + echo "$(tput setaf 1)Error:$(tput sgr0) failed to copy LogDoctor's data" + exit + fi +else + sudo cp -r ./logdocdata/{help,licenses} /usr/share/LogDoctor + if [[ "$?" != "0" ]] + then + echo "$(tput setaf 1)Error:$(tput sgr0) failed to copy LogDoctor's data" + exit + fi +fi + + +chmod 644 ./LogDoctor.svg +sudo install -DC ./LogDoctor.svg -t /usr/share/LogDoctor +if [[ "$?" != "0" ]] +then + echo "$(tput setaf 1)Error:$(tput sgr0) failed to copy LogDoctor's icon" + exit +fi + + +chmod 644 ./LogDoctor.desktop +sudo install -DC ./LogDoctor.desktop -t /usr/share/applications +if [[ "$?" != "0" ]] +then + echo "$(tput setaf 1)Error:$(tput sgr0) failed to create a menu entry" + exit +fi + + +cd ../build +chmod 755 ./logdoctor +sudo install -DC ./logdoctor -t /usr/bin +if [[ "$?" != "0" ]] +then + echo "$(tput setaf 1)Error:$(tput sgr0) failed to copy the executable" + exit +fi + + +# Installation finished +echo "$(tput setaf 10)-->$(tput sgr0) $(tput bold)Installed succesfully$(tput sgr0)" +cd "$current_path" diff --git a/build_update.sh b/build_update.sh new file mode 100644 index 00000000..dcdabd84 --- /dev/null +++ b/build_update.sh @@ -0,0 +1,136 @@ +#!/bin/bash + +# Store the actual path +current_path=$(pwd) + +# Get the path of LogDoctor-git's folder and move in +docdir="$(dirname $(realpath $0))" +cd "$docdir" + +# Check cmake availability +which cmake &> /dev/null +if [[ "$?" != "0" ]] +then + echo "$(tput setaf 1)Error:$(tput sgr0) Cmake is not installed" + exit +fi + +# Check the existence of a previous executable file +if [ ! -e /usr/bin/logdoctor ] +then + echo "$(tput setaf 11)Warning:$(tput sgr0) no previous installation found, please run the $(tput bold)install$(tput sgr0) script instead" + exit +fi + +# Start the compilation process +echo "$(tput setaf 12)==>$(tput sgr0) $(tput bold)Building$(tput sgr0)" + +# Make a build folder +if [ -e build ] +then + rm -r build + if [[ "$?" != "0" ]] + then + echo "$(tput setaf 1)Error:$(tput sgr0) failed to remove existing build directory" + exit + fi +fi +mkdir build +if [[ "$?" != "0" ]] +then + echo "$(tput setaf 1)Error:$(tput sgr0) failed to create build directory" + exit +fi +cd build + +# Prepare the cmake files +cmake ../logdoctor -DCMAKE_BUILD_TYPE=MinSizeRel +if [[ "$?" != "0" ]] +then + # an error occured during preparation + echo "$(tput setaf 1)Error:$(tput sgr0) failed to prepare build files" + exit +fi + +# Build the project +cmake --build ./ --target all +if [[ "$?" == "0" ]] +then + # compiled succesfully + mv LogDoctor logdoctor +else + # an error occured during compilation + echo "$(tput setaf 1)Error:$(tput sgr0) failed to compile" + exit +fi + +# Compilation finished +wait +echo "$(tput setaf 10)-->$(tput sgr0) Built succesfully" + +# Start updating LogDoctor +echo "$(tput setaf 12)==>$(tput sgr0) $(tput bold)Updating$(tput sgr0)" +cd ../installation_stuff/ + + +if [ ! -d /usr/share/LogDoctor ] +then + sudo mkdir -p /usr/share/LogDoctor + if [[ "$?" != "0" ]] + then + echo "$(tput setaf 1)Error:$(tput sgr0) failed to create directory: /usr/share/LogDoctor" + exit + fi +fi +chmod 644 ./logdocdata/help/*/* +chmod 444 ./logdocdata/licenses/* +which rsync &> /dev/null +if [[ "$?" == "0" ]] +then + sudo rsync -r --delete ./logdocdata /usr/share/LogDoctor + if [[ "$?" != "0" ]] + then + echo "$(tput setaf 1)Error:$(tput sgr0) failed to copy LogDoctor's data" + exit + fi +else + sudo cp -r ./logdocdata/{help,licenses} /usr/share/LogDoctor + if [[ "$?" != "0" ]] + then + echo "$(tput setaf 1)Error:$(tput sgr0) failed to copy LogDoctor's data" + exit + fi +fi + + +chmod 644 ./LogDoctor.svg +sudo install -DC ./LogDoctor.svg -t /usr/share/LogDoctor +if [[ "$?" != "0" ]] +then + echo "$(tput setaf 1)Error:$(tput sgr0) failed to copy LogDoctor's icon" + exit +fi + + +chmod 644 ./LogDoctor.desktop +sudo install -DC ./LogDoctor.desktop -t /usr/share/applications +if [[ "$?" != "0" ]] +then + echo "$(tput setaf 1)Error:$(tput sgr0) failed to create a menu entry" + exit +fi + + +cd ../build +chmod 755 ./logdoctor +sudo install -DC ./logdoctor -t /usr/bin +if [[ "$?" != "0" ]] +then + echo "$(tput setaf 1)Error:$(tput sgr0) failed to copy the executable" + exit +fi + + +# Update finished +echo "$(tput setaf 10)-->$(tput sgr0) $(tput bold)Updated succesfully$(tput sgr0)" +cd "$current_path" diff --git a/builder.bat b/builder.bat new file mode 100644 index 00000000..8152f06c --- /dev/null +++ b/builder.bat @@ -0,0 +1,292 @@ + +@ECHO off + +:: Store the actual path +SET actual_path=%1 + +:: Get Qt base path +SET qt_base_path=C:/Qt +IF EXIST "%qt_base_path%" GOTO :step0 + +SET qt_base_path=C:/Program Files/Qt +IF EXIST "%qt_base_path%" GOTO :step0 + +SET qt_base_path=C:/Program Files (x86)/Qt +IF EXIST "%qt_base_path%" GOTO :step0 + +SET qt_base_path=%USERPROFILE%\Qt +IF EXIST "%qt_base_path%" GOTO :step0 + +SET qt_base_path=NONE + +:step0 + +SET qt_path=%qt_base_path% + +IF "%qt_base_path%" == "NONE" GOTO :step1 + +SET qt_base_path=%qt_base_path:\=/% + +IF "%qt_base_path:~-1%"=="/" SET qt_base_path=%qt_base_path:~0,-1% + + +:: Get Qt version +SET qt_path=%qt_base_path%/5.15.2 +IF EXIST "%qt_path%" GOTO :step1 + +SET qt_path=%qt_base_path%/6.0 +IF EXIST "%qt_path%" GOTO :step1 + +SET qt_path=%qt_base_path%/6.2 +IF EXIST "%qt_path%" GOTO :step1 + +SET qt_path=%qt_base_path%/6.4 +IF EXIST "%qt_path%" GOTO :step1 + +SET qt_path=NONE + + +:step1 + +IF NOT "%qt_path%" == "NONE" GOTO :step2 + +:loop1 +ECHO: +ECHO Qt not found, please insert the path of your Qt installation, including the version +ECHO Ex: C:/your/path/to/Qt/5.15.2 +SET /P qt_path= : +IF NOT EXIST "%qt_path%" ( + ECHO Error: the given path doesn't exist + GOTO :loop1 +) + + +:step2 + +SET qt_path=%qt_path:\=/% + +IF "%qt_path:~-1%"=="/" SET qt_path=%qt_path:~0,-1% + + +:: Get CMake path +SET cmake_path=%qt_base_path%/Tools/CMake_64/bin/cmake.exe +IF EXIST "%cmake_path%" GOTO :step4 + +where /Q cmake +IF ERRORLEVEL 0 ( + FOR /F "tokens=* USEBACKQ" %%e IN (`where cmake`) DO SET cmake_path=%%e + IF EXIST "%cmake_path%" GOTO :step4 +) + +SET cmake_path=C:/Program Files/CMake/bin/cmake.exe +IF EXIST "%cmake_path%" GOTO :step4 + +SET cmake_path=C:/Program Files (x86)/CMake/bin/cmake.exe +IF EXIST "%cmake_path%" GOTO :step4 + +SET cmake_path=C:/CMake/bin/cmake.exe +IF EXIST "%cmake_path%" GOTO :step4 + +SET cmake_path=C:/msys64/usr/bin/cmake.exe +IF EXIST "%cmake_path%" GOTO :step4 + +SET cmake_path=C:/msys64/mingw64/bin/cmake.exe +IF EXIST "%cmake_path%" GOTO :step4 + +:loop3 +ECHO: +ECHO CMake not found, please insert the path of your CMake installation, including the executable +ECHO Ex: C:/your/path/to/cmake.exe +SET /P cmake_path= : +IF EXIST "%cmake_path%" ( + IF NOT "%cmake_path:~-9%" == "cmake.exe" ( + ECHO Error: the given path doesn't point to a cmake executable + GOTO :loop3 + ) +) ELSE ( + ECHO Error: the given path doesn't exist + GOTO :loop3 +) + + +:step4 + +SET cmake_path=%cmake_path:\=/% + +:: Get the C++ compiler path +SET cxx_compiler=%qt_base_path%/Tools/mingw1120_64/bin/g++.exe +IF EXIST "%cxx_compiler%" GOTO :step6 + +SET cxx_compiler=%qt_base_path%/Tools/mingw810_64/bin/g++.exe +IF EXIST "%cxx_compiler%" GOTO :step6 + +where /Q g++ +IF ERRORLEVEL 0 ( + FOR /F "tokens=* USEBACKQ" %%e IN (`where g++`) DO SET cxx_compiler=%%e + IF EXIST "%cxx_compiler%" GOTO :step6 +) + +SET cxx_compiler=C:/msys64/mingw64/bin/g++.exe +IF EXIST "%cxx_compiler%" GOTO :step6 + +:loop5 +ECHO: +ECHO G++ not found, please insert the path of the C++ compiler +ECHO Ex: C:/your/path/to/g++.exe +SET /P cxx_compiler= : +IF EXIST "%cxx_compiler%" ( + IF NOT "%cxx_compiler:~-7%" == "g++.exe" ( + ECHO Error: the given path doesn't point to a g++ executable + GOTO :loop5 + ) +) ELSE ( + ECHO Error: the given path doesn't exist + GOTO :loop5 +) + + +:step6 + +SET cxx_compiler=%cxx_compiler:\=/% + + +SET prefix_path=%qt_path%/mingw112_64 +IF EXIST "%prefix_path%" GOTO :step7 + +SET prefix_path=%qt_path%/mingw81_64 +IF EXIST "%prefix_path%" GOTO :step7 + +ECHO: +ECHO Error: CMAKE_PREFIX_PATH not found +PAUSE +EXIT /B 1 + + +:step7 + +IF "%prefix_path:~-1%"=="/" SET prefix_path=%prefix_path:~0,-1% + + +SET qt_dir=%prefix_path%/lib/cmake/Qt5 +IF EXIST "%qt_dir%" GOTO :step8 + +ECHO: +ECHO Error: QT_DIR not found +PAUSE +EXIT /B 1 + + +:step8 + +IF "%qt_dir:~-1%"=="/" SET qt_dir=%qt_dir:~0,-1% + + +:: Check if JOM is in PATH +where /Q jom +IF ERRORLEVEL 0 ( + FOR /F "tokens=* USEBACKQ" %%e IN (`where jom`) DO SET jom_path=%%e + IF EXIST "%jom_path%" GOTO :step9_a +) + +SET jom_path=%qt_base_path%/Tools/QtCreator/bin/jom +IF EXIST "%jom_path%" SET PATH=%PATH%;%jom_path% + +where /Q jom +IF ERRORLEVEL 0 ( + FOR /F "tokens=* USEBACKQ" %%e IN (`where jom`) DO SET jom_path=%%e + IF EXIST "%jom_path%" GOTO :step9_a +) + +ECHO: +ECHO Error: JOM not found in PATH, please add it or compilation won't succeed +PAUSE +EXIT /B 1 + + +:step9_a + +:: Check if libwinpthread-1.dll is in PATH +where /Q libwinpthread-1.dll +IF ERRORLEVEL 0 ( + FOR /F "tokens=* USEBACKQ" %%e IN (`where libwinpthread-1.dll`) DO SET lib_path=%%e + IF EXIST "%lib_path%" GOTO :step9_b2 +) + +SET lib_path=%qt_base_path%/Tools/mingw1120_64/bin +IF EXIST "%lib_path%" GOTO :step9_b1 + +SET lib_path=%qt_base_path%/Tools/mingw810_64/bin +IF EXIST "%lib_path%" GOTO :step9_b1 + +SET lib_path=C:/msys64/mingw64/bin +IF EXIST "%lib_path%" GOTO :step9_b1 + +:step9_b1 + +SET PATH=%PATH%;%lib_path% + +where /Q libwinpthread-1.dll +IF ERRORLEVEL 0 ( + FOR /F "tokens=* USEBACKQ" %%e IN (`where libwinpthread-1.dll`) DO SET lib_path=%%e + IF EXIST "%lib_path%" GOTO :step9_b2 +) + +ECHO: +ECHO Error: libwinpthread-1.dll not found in PATH, please add it or compilation won't succeed +PAUSE +EXIT /B 1 + +:step9_b2 + + +:: Start the compilation process +ECHO: +ECHO Starting compilation process +ECHO: + +:: Make a build folder +IF EXIST build rmdir /S /Q build + +mkdir build +IF ERRORLEVEL 1 ( + ECHO: + ECHO Error: failed to create directory: 'build' + cd "%actual_path%" + PAUSE + EXIT /B 1 +) +cd build + +:: Prepare build files +"%cmake_path%" "%logdocdir%/logdoctor" "-DCMAKE_BUILD_TYPE:STRING=MinSizeRel" "-DCMAKE_GENERATOR:STRING=NMake Makefiles JOM" "-DCMAKE_MAKE_PROGRAM:STRING=jom" "-DCMAKE_CXX_COMPILER:FILEPATH=%cxx_compiler%" "-DCMAKE_PREFIX_PATH:PATH=%prefix_path%" "-DQT_DIR:PATH=%qt_dir%" +IF ERRORLEVEL 1 ( + ECHO: + ECHO Error: failed to prepare cmake files + cd "%actual_path%" + PAUSE + EXIT /B 1 +) + +:: Build the project +"%cmake_path%" --build ./ --target all +IF ERRORLEVEL 1 ( + ECHO: + ECHO Error: failed to compile + cd "%actual_path%" + PAUSE + EXIT /B 1 +) + +:: Deploy the static libraries +IF EXIST LogDoctor rmdir /S /Q LogDoctor +mkdir LogDoctor +move LogDoctor.exe LogDoctor\ +SET prefix_path=%prefix_path:/=\% +"%prefix_path%\bin\windeployqt.exe" LogDoctor\ +copy /V /Y "%prefix_path%\bin\libstdc++-6.dll" LogDoctor\ +copy /V /Y "%prefix_path%\bin\libwinpthread-1.dll" LogDoctor\ +copy /V /Y "%prefix_path%\bin\libgcc_s_seh-1.dll" LogDoctor\ + +:: Compilation finished +ECHO: +ECHO Compilation finished diff --git a/docs/html/annotated.html b/docs/html/annotated.html new file mode 100644 index 00000000..0bbd5828 --- /dev/null +++ b/docs/html/annotated.html @@ -0,0 +1,134 @@ + + + + + + + +LogDoctor: Class List + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Class List
+
+
+
Here are the classes, structs, unions and interfaces with brief descriptions:
+
[detail level 12]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
 CBodyPartInstance of a part of the body of the snake
 CBWlistExceptionBWlistException
 CCheckSecCheckSec
 CColorSecColorSec
 CCraphelpCraphelp
 CCrapinfoCrapinfo
 CCraplogCraplog
 CBWlistStructure to hold the items of a blacklist/warnlist
 CLogFileStructure which holds informations about a log file
 CLogNameWeb Server specific file names criterions
 CCrapnoteCrapnote
 CCrapupCrapup
 CCrapviewCrapview
 CCrissCrossCrissCross
 CDateTimeExceptionDateTimeException
 CDateTimeOpsDateTimeOps
 CDbQuery
 CDialogBoolDialogBool
 CDialogDiaDialogDia
 CDialogMsgDialogMsg
 CDialogSecDialogSec
 CDonutBreakdownDonutBreakdon
 CFood
 CFormatOpsFormatOps
 CLogsFormatStructure which holds informations about a log format
 CGameSecGameSec
 CGenericExceptionGenericException
 CGZutilsGZUtils
 CHashOpsHashOps
 CIOutilsIOUtils
 CLogFormatExceptionLogFormatException
 CLogOpsLogOps
 CLogParserExceptionLogParserException
 CMainSliceRepresents a slice
 CMainWindowMainWindow
 CRichTextRichText
 CSHA256
 CSnake
 CTile
 CSnakeGameSnake
 CStoreOpsStoreOps
 CStringOpsStringOps
 CStyleSecStyleSec
 CTextBrowserTextBrowser
 CTRTR
 CVecOpsVecOps
 CWebServerExceptionWebServerException
+
+
+ + + + diff --git a/docs/html/bc_s.png b/docs/html/bc_s.png new file mode 100644 index 00000000..224b29aa Binary files /dev/null and b/docs/html/bc_s.png differ diff --git a/docs/html/bc_sd.png b/docs/html/bc_sd.png new file mode 100644 index 00000000..31ca888d Binary files /dev/null and b/docs/html/bc_sd.png differ diff --git a/docs/html/bdwn.png b/docs/html/bdwn.png new file mode 100644 index 00000000..940a0b95 Binary files /dev/null and b/docs/html/bdwn.png differ diff --git a/docs/html/classBWlistException-members.html b/docs/html/classBWlistException-members.html new file mode 100644 index 00000000..60162aa8 --- /dev/null +++ b/docs/html/classBWlistException-members.html @@ -0,0 +1,85 @@ + + + + + + + +LogDoctor: Member List + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
+
BWlistException Member List
+
+
+ +

This is the complete list of members for BWlistException, including all inherited members.

+
+ + + + diff --git a/docs/html/classBWlistException.html b/docs/html/classBWlistException.html new file mode 100644 index 00000000..eddfde1d --- /dev/null +++ b/docs/html/classBWlistException.html @@ -0,0 +1,103 @@ + + + + + + + +LogDoctor: BWlistException Class Reference + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
+ +
BWlistException Class Reference
+
+
+ +

BWlistException. + More...

+ +

#include <exceptions.h>

+
+Inheritance diagram for BWlistException:
+
+
+ +
+

Detailed Description

+

BWlistException.

+

Exception related to a blacklist/warnlist

+

The documentation for this class was generated from the following files:
    +
  • logdoctor/modules/exceptions.h
  • +
  • logdoctor/modules/exceptions.cpp
  • +
+
+ + + + diff --git a/docs/html/classBWlistException.png b/docs/html/classBWlistException.png new file mode 100644 index 00000000..a67e1d43 Binary files /dev/null and b/docs/html/classBWlistException.png differ diff --git a/docs/html/classCheckSec-members.html b/docs/html/classCheckSec-members.html new file mode 100644 index 00000000..0ceb722c --- /dev/null +++ b/docs/html/classCheckSec-members.html @@ -0,0 +1,91 @@ + + + + + + + +LogDoctor: Member List + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
+
CheckSec Member List
+
+
+ +

This is the complete list of members for CheckSec, including all inherited members.

+ + + + + + +
checkCollectionDatabase(const std::string &db_path)CheckSecstatic
checkDatabaseTablesNames(QSqlDatabase &db, const QString &db_name)CheckSecprivatestatic
checkHashesDatabase(const std::string &db_path)CheckSecstatic
newCollectionDatabase(QSqlDatabase &db, const QString &db_name, const std::vector< QString > &ws_names)CheckSecprivatestatic
newHashesDatabase(QSqlDatabase &db, const QString &db_name, const std::vector< QString > &ws_names)CheckSecprivatestatic
+ + + + diff --git a/docs/html/classCheckSec.html b/docs/html/classCheckSec.html new file mode 100644 index 00000000..d0712871 --- /dev/null +++ b/docs/html/classCheckSec.html @@ -0,0 +1,347 @@ + + + + + + + +LogDoctor: CheckSec Class Reference + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
+ +

CheckSec. + More...

+ +

#include <checks.h>

+ + + + + + + + +

+Static Public Member Functions

static bool checkCollectionDatabase (const std::string &db_path)
 Checks the structure's integrity of the Collection database. More...
 
static bool checkHashesDatabase (const std::string &db_path)
 Checks the structure's integrity of the Hashes database. More...
 
+ + + + + + + + + + +

+Static Private Member Functions

static int checkDatabaseTablesNames (QSqlDatabase &db, const QString &db_name)
 Checks the tables' names integrity. More...
 
static bool newCollectionDatabase (QSqlDatabase &db, const QString &db_name, const std::vector< QString > &ws_names)
 Builds a new database for the logs Collection. More...
 
static bool newHashesDatabase (QSqlDatabase &db, const QString &db_name, const std::vector< QString > &ws_names)
 Builds a new database for the used log files' Hashes. More...
 
+

Detailed Description

+

CheckSec.

+

Utilities used to check the databases

+

Member Function Documentation

+ +

◆ checkCollectionDatabase()

+ +
+
+ + + + + +
+ + + + + + + + +
bool CheckSec::checkCollectionDatabase (const std::string & db_path)
+
+static
+
+ +

Checks the structure's integrity of the Collection database.

+
Parameters
+ + +
db_pathThe path of the database, file included
+
+
+
Returns
The result of the check
+
See also
checkDatabaseTablesNames(), newCollectionDatabase(), newHashesDatabase()
+ +
+
+ +

◆ checkDatabaseTablesNames()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
int CheckSec::checkDatabaseTablesNames (QSqlDatabase & db,
const QString & db_name 
)
+
+staticprivate
+
+ +

Checks the tables' names integrity.

+
Parameters
+ + + +
dbDatabase object, already initialized
db_nameDatabase's name, eventually used by the dialogs
+
+
+
Returns
The result of the check: 0 if failed with an error, 1 if all the integrity checks passed, 2 if a rebuild is needed
+
See also
checkCollectionDatabase(), checkHashesDatabase(), newCollectionDatabase(), newHashesDatabase()
+ +
+
+ +

◆ checkHashesDatabase()

+ +
+
+ + + + + +
+ + + + + + + + +
bool CheckSec::checkHashesDatabase (const std::string & db_path)
+
+static
+
+ +

Checks the structure's integrity of the Hashes database.

+
Parameters
+ + +
db_pathThe path of the database, file included
+
+
+
Returns
The result of the check
+
See also
checkDatabaseTablesNames(), newCollectionDatabase(), newHashesDatabase()
+ +
+
+ +

◆ newCollectionDatabase()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
bool CheckSec::newCollectionDatabase (QSqlDatabase & db,
const QString & db_name,
const std::vector< QString > & ws_names 
)
+
+staticprivate
+
+ +

Builds a new database for the logs Collection.

+
Parameters
+ + + +
dbDatabase object, already initialized
db_nameDatabase's name, eventually used by the dialogs
+
+
+
Returns
The result of the operation
+
See also
checkCollectionDatabase(), checkHashesDatabase()
+ +
+
+ +

◆ newHashesDatabase()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
bool CheckSec::newHashesDatabase (QSqlDatabase & db,
const QString & db_name,
const std::vector< QString > & ws_names 
)
+
+staticprivate
+
+ +

Builds a new database for the used log files' Hashes.

+
Parameters
+ + + +
dbDatabase object, already initialized
db_nameDatabase's name, eventually used by the dialogs
+
+
+
Returns
The result of the operation
+
See also
checkCollectionDatabase(), checkHashesDatabase()
+ +
+
+
The documentation for this class was generated from the following files:
    +
  • logdoctor/utilities/checks.h
  • +
  • logdoctor/utilities/checks.cpp
  • +
+
+ + + + diff --git a/docs/html/classColorSec-members.html b/docs/html/classColorSec-members.html new file mode 100644 index 00000000..6d0455aa --- /dev/null +++ b/docs/html/classColorSec-members.html @@ -0,0 +1,88 @@ + + + + + + + +LogDoctor: Member List + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
+
ColorSec Member List
+
+
+ +

This is the complete list of members for ColorSec, including all inherited members.

+ + + +
getColors()ColorSecstatic
getColorSchemes()ColorSecstatic
+ + + + diff --git a/docs/html/classColorSec.html b/docs/html/classColorSec.html new file mode 100644 index 00000000..e72c8132 --- /dev/null +++ b/docs/html/classColorSec.html @@ -0,0 +1,110 @@ + + + + + + + +LogDoctor: ColorSec Class Reference + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
+ +
ColorSec Class Reference
+
+
+ +

ColorSec. + More...

+ +

#include <colors.h>

+ + + + + + + + +

+Static Public Member Functions

+static const std::unordered_map< std::string, QColor > getColors ()
 Provides a map with pre-made colors.
 
+static const std::unordered_map< int, std::unordered_map< std::string, QString > > getColorSchemes ()
 Provides a map with pre-made color-schemes for the TextBrowser.
 
+

Detailed Description

+

ColorSec.

+

Utilities for the colors

+

The documentation for this class was generated from the following files:
    +
  • logdoctor/utilities/colors.h
  • +
  • logdoctor/utilities/colors.cpp
  • +
+
+ + + + diff --git a/docs/html/classCraphelp-members.html b/docs/html/classCraphelp-members.html new file mode 100644 index 00000000..cc66d8cc --- /dev/null +++ b/docs/html/classCraphelp-members.html @@ -0,0 +1,87 @@ + + + + + + + +LogDoctor: Member List + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
+
Craphelp Member List
+
+
+ +

This is the complete list of members for Craphelp, including all inherited members.

+ + +
helpLogsFormat(const std::string &path, const QFont &font, const int &color_scheme_id)Craphelp
+ + + + diff --git a/docs/html/classCraphelp.html b/docs/html/classCraphelp.html new file mode 100644 index 00000000..2aeeae3e --- /dev/null +++ b/docs/html/classCraphelp.html @@ -0,0 +1,156 @@ + + + + + + + +LogDoctor: Craphelp Class Reference + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
+ +
Craphelp Class Reference
+
+
+ +

Craphelp. + More...

+ +

#include <craphelp.h>

+
+Inheritance diagram for Craphelp:
+
+
+ +
+ + + + + +

+Public Member Functions

void helpLogsFormat (const std::string &path, const QFont &font, const int &color_scheme_id)
 Provides help about log formats. More...
 
+

Detailed Description

+

Craphelp.

+

Displays an help window

+

Member Function Documentation

+ +

◆ helpLogsFormat()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void Craphelp::helpLogsFormat (const std::string & path,
const QFont & font,
const int & color_scheme_id 
)
+
+ +

Provides help about log formats.

+
Parameters
+ + + + +
pathThe path of the file resource to be displayed
fontThe font to be used
color_scheme_idThe ID of the color-scheme to be used
+
+
+ +
+
+
The documentation for this class was generated from the following files:
    +
  • logdoctor/modules/craphelp/craphelp.h
  • +
  • logdoctor/modules/craphelp/craphelp.cpp
  • +
+
+ + + + diff --git a/docs/html/classCraphelp.png b/docs/html/classCraphelp.png new file mode 100644 index 00000000..9c754a60 Binary files /dev/null and b/docs/html/classCraphelp.png differ diff --git a/docs/html/classCrapinfo-members.html b/docs/html/classCrapinfo-members.html new file mode 100644 index 00000000..069ae23b --- /dev/null +++ b/docs/html/classCrapinfo-members.html @@ -0,0 +1,87 @@ + + + + + + + +LogDoctor: Member List + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
+
Crapinfo Member List
+
+
+ +

This is the complete list of members for Crapinfo, including all inherited members.

+ + +
Crapinfo(const int &window_theme_id, const QString &version, const QString &exec_path, const QString &conf_path, const QString &logdoc_path, QWidget *parent=nullptr)Crapinfo
+ + + + diff --git a/docs/html/classCrapinfo.html b/docs/html/classCrapinfo.html new file mode 100644 index 00000000..b3237f6a --- /dev/null +++ b/docs/html/classCrapinfo.html @@ -0,0 +1,177 @@ + + + + + + + +LogDoctor: Crapinfo Class Reference + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
+ +
Crapinfo Class Reference
+
+
+ +

Crapinfo. + More...

+ +

#include <crapinfo.h>

+
+Inheritance diagram for Crapinfo:
+
+
+ +
+ + + + + +

+Public Member Functions

 Crapinfo (const int &window_theme_id, const QString &version, const QString &exec_path, const QString &conf_path, const QString &logdoc_path, QWidget *parent=nullptr)
 Class constructor. More...
 
+

Detailed Description

+

Crapinfo.

+

Displays informations

+

Constructor & Destructor Documentation

+ +

◆ Crapinfo()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Crapinfo::Crapinfo (const int & window_theme_id,
const QString & version,
const QString & exec_path,
const QString & conf_path,
const QString & logdoc_path,
QWidget * parent = nullptr 
)
+
+ +

Class constructor.

+
Parameters
+ + + + + + + +
window_theme_idThe ID of the theme in use on the main window
versionThe version of LogDoctor actually running
exec_pathThe path of the executable
conf_pathThe path of the configuration file
logdoc_pathThe path of the additional resources folder
parentThe parent Widget
+
+
+ +
+
+
The documentation for this class was generated from the following files:
    +
  • logdoctor/modules/crapinfo/crapinfo.h
  • +
  • logdoctor/modules/crapinfo/crapinfo.cpp
  • +
+
+ + + + diff --git a/docs/html/classCrapinfo.png b/docs/html/classCrapinfo.png new file mode 100644 index 00000000..beae91d9 Binary files /dev/null and b/docs/html/classCrapinfo.png differ diff --git a/docs/html/classCraplog-members.html b/docs/html/classCraplog-members.html new file mode 100644 index 00000000..c94083d3 --- /dev/null +++ b/docs/html/classCraplog-members.html @@ -0,0 +1,152 @@ + + + + + + + +LogDoctor: Member List + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
+
Craplog Member List
+
+
+ +

This is the complete list of members for Craplog, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
APACHE_IDCraplogprivate
blacklistAdd(const int &web_server_id, const int &log_field_id, const std::string &new_item)Craplog
blacklistMoveDown(const int &web_server_id, const int &log_field_id, const std::string &item)Craplog
blacklistMoveUp(const int &web_server_id, const int &log_field_id, const std::string &item)Craplog
blacklistRemove(const int &web_server_id, const int &log_field_id, const std::string &item)Craplog
changeIisLogsBaseNames(const int &module_id)Craplogprivate
checkStuff()Craplog
clearDataCollection()Craplog
collectPerfData()Craplog
editedDatabase()Craplog
getBlacklist(const int &web_server_id, const int &log_field_id)Craplog
getCurrentLogFormat()Craplog
getCurrentWSID()Craplog
getDialogsLevel()Craplog
getHashesDatabasePath()Craplog
getLogFileItem(const QString &file_name)Craplog
getLogsFormat(const int &web_server_id)Craplog
getLogsFormatSample(const int &web_server_id)Craplog
getLogsFormatString(const int &web_server_id)Craplog
getLogsList(const bool &fresh=false)Craplog
getLogsListSize()Craplog
getLogsPath(const int &web_server)Craplog
getParsedLines()Craplog
getPerfSize()Craplog
getStatsDatabasePath()Craplog
getTotalSize()Craplog
getWarningSize()Craplog
getWarnlist(const int &web_server_id, const int &log_field_id)Craplog
IIS_IDCraplogprivate
isBlacklistUsed(const int &web_server_id, const int &log_field_id)Craplog
isFileNameValid(const std::string &name)Craplog
isParsing()Craplog
isWarnlistUsed(const int &web_server_id, const int &log_field_id)Craplog
isWorking()Craplog
joinLogLines()Craplogprivate
makeChart(const QChart::ChartTheme &theme, const std::unordered_map< std::string, QFont > &fonts, QChartView *size_chart)Craplog
NGINX_IDCraplogprivate
parseLogLines()Craplogprivate
printableSize(const unsigned int &bytes)Craplogprivate
run()Craplog
sanitizeBWitem(const int &log_field_id, const std::string &new_item)Craplogprivate
scanLogsDir()Craplogprivate
setApacheLogFormat(const std::string &format_string)Craplog
setBlacklist(const int &web_server_id, const int &log_field_id, const std::vector< std::string > &new_list)Craplog
setBlacklistUsed(const int &web_server_id, const int &log_field_id, const bool &used)Craplog
setCurrentLogFormat()Craplogprivate
setCurrentWSID(const int &web_server_id)Craplog
setDialogsLevel(const int &new_level)Craplog
setHashesDatabasePath(const std::string &path)Craplog
setIisLogFormat(const std::string &format_string, const int &log_module)Craplog
setLogFileSelected(const QString &file_name)Craplog
setLogsPath(const int &web_server, const std::string &new_path)Craplog
setNginxLogFormat(const std::string &format_string)Craplog
setStatsDatabasePath(const std::string &path)Craplog
setWarningSize(const long &new_size)Craplog
setWarnlist(const int &web_server_id, const int &log_field_id, const std::vector< std::string > &new_list)Craplog
setWarnlistUsed(const int &web_server_id, const int &log_field_id, const bool &used)Craplog
startWorking()Craplogprivate
stopWorking()Craplogprivate
storeLogLines()Craplogprivate
sumBlacklistededSize(const unsigned int &size)Craplog
sumWarningsSize(const unsigned int &size)Craplog
warnlistAdd(const int &web_server_id, const int &log_field_id, const std::string &new_item)Craplog
warnlistMoveDown(const int &web_server_id, const int &log_field_id, const std::string &item)Craplog
warnlistMoveUp(const int &web_server_id, const int &log_field_id, const std::string &item)Craplog
warnlistRemove(const int &web_server_id, const int &log_field_id, const std::string &item)Craplog
+ + + + diff --git a/docs/html/classCraplog.html b/docs/html/classCraplog.html new file mode 100644 index 00000000..a101ddba --- /dev/null +++ b/docs/html/classCraplog.html @@ -0,0 +1,1958 @@ + + + + + + + +LogDoctor: Craplog Class Reference + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
+ +

Craplog. + More...

+ +

#include <craplog.h>

+ + + + + + + + + + + +

+Classes

struct  BWlist
 Structure to hold the items of a blacklist/warnlist. More...
 
struct  LogFile
 Structure which holds informations about a log file. More...
 
struct  LogName
 Web Server specific file names criterions. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

void run ()
 Main work method. More...
 
+const int & getDialogsLevel ()
 Returns the Dialogs level.
 
+void setDialogsLevel (const int &new_level)
 Sets the new Dialogs level.
 
+const std::string & getStatsDatabasePath ()
 Returns the path of the logs Collection database.
 
+const std::string & getHashesDatabasePath ()
 Returns the path of the log files' Hashes database.
 
void setStatsDatabasePath (const std::string &path)
 Sets the new path for the logs Collection database. More...
 
void setHashesDatabasePath (const std::string &path)
 Sets the new path for the log files' Hashes database. More...
 
void setCurrentWSID (const int &web_server_id)
 Sets the currently used Web Server ID. More...
 
const int & getCurrentWSID ()
 Returns the currently used Web Server ID. More...
 
const FormatOps::LogsFormatgetCurrentLogFormat ()
 Returns the currently used LogsFormat. More...
 
const std::string & getLogsPath (const int &web_server)
 Returns the logs' path for the given web Server. More...
 
void setLogsPath (const int &web_server, const std::string &new_path)
 Sets a new path for the given Web Server to search the logs in. More...
 
const bool isFileNameValid (const std::string &name)
 Checks if a file name respects the relative criterions. More...
 
const std::vector< LogFile > & getLogsList (const bool &fresh=false)
 Returns the list of log files. More...
 
const int getLogsListSize ()
 Returns the amount of log files in the list. More...
 
const LogFilegetLogFileItem (const QString &file_name)
 Returns the LogFile instance of the given file. More...
 
const bool setLogFileSelected (const QString &file_name)
 Sets a file in the list as selected. More...
 
const bool setApacheLogFormat (const std::string &format_string)
 Sets the Apache2 LogsFormat from the given format string. More...
 
const bool setNginxLogFormat (const std::string &format_string)
 Sets the Nginx LogsFormat from the given format string. More...
 
const bool setIisLogFormat (const std::string &format_string, const int &log_module)
 Sets the IIS LogsFormat from the given format string. More...
 
const std::string & getLogsFormatString (const int &web_server_id)
 Returns the logs format string for the given Web Server. More...
 
const FormatOps::LogsFormatgetLogsFormat (const int &web_server_id)
 Returns the LogsFormat currently set for the given Web Server. More...
 
const QString getLogsFormatSample (const int &web_server_id)
 Returns a sample log line for the given Web Server using the relative LogsFormat. More...
 
+const long & getWarningSize ()
 Returns the currently set warning size for the log files.
 
+void setWarningSize (const long &new_size)
 Sets the new warning size for the log files.
 
const bool & isBlacklistUsed (const int &web_server_id, const int &log_field_id)
 Returns whether the relative blacklist is set to be used or not. More...
 
const bool & isWarnlistUsed (const int &web_server_id, const int &log_field_id)
 Returns whether the relative warnlist is set to be used or not. More...
 
void setBlacklistUsed (const int &web_server_id, const int &log_field_id, const bool &used)
 Sets the relative blacklist to be used or not. More...
 
void setWarnlistUsed (const int &web_server_id, const int &log_field_id, const bool &used)
 Sets the relative warnlist to be used or not. More...
 
const std::vector< std::string > & getBlacklist (const int &web_server_id, const int &log_field_id)
 Returns the relative items list. More...
 
const std::vector< std::string > & getWarnlist (const int &web_server_id, const int &log_field_id)
 Returns the relative items list. More...
 
void setBlacklist (const int &web_server_id, const int &log_field_id, const std::vector< std::string > &new_list)
 Sets the relative items list. More...
 
void setWarnlist (const int &web_server_id, const int &log_field_id, const std::vector< std::string > &new_list)
 Sets the relative items list. More...
 
void blacklistAdd (const int &web_server_id, const int &log_field_id, const std::string &new_item)
 Adds an item to the relative list. More...
 
void warnlistAdd (const int &web_server_id, const int &log_field_id, const std::string &new_item)
 Adds an item to the relative list. More...
 
void blacklistRemove (const int &web_server_id, const int &log_field_id, const std::string &item)
 Removes an item from the relative list. More...
 
void warnlistRemove (const int &web_server_id, const int &log_field_id, const std::string &item)
 Removes an item from the relative list. More...
 
const int blacklistMoveUp (const int &web_server_id, const int &log_field_id, const std::string &item)
 Moves an item one position up in the relative list. More...
 
const int warnlistMoveUp (const int &web_server_id, const int &log_field_id, const std::string &item)
 Moves an item one position up in the relative list. More...
 
const int blacklistMoveDown (const int &web_server_id, const int &log_field_id, const std::string &item)
 Moves an item one position down in the relative list. More...
 
const int warnlistMoveDown (const int &web_server_id, const int &log_field_id, const std::string &item)
 Moves an item one position down in the relative list. More...
 
+const bool & editedDatabase ()
 Returns whether the database has been edited or not during the process.
 
const bool checkStuff ()
 Various checks to be made before starting a new process. More...
 
+void clearDataCollection ()
 Erases the data collection when a process is done.
 
+const bool & isWorking ()
 Returns whether the process is still running or not.
 
+const bool & isParsing ()
 Returns whether the process is still parsing or not.
 
void collectPerfData ()
 Collects performances data from the sub-modules. More...
 
+void sumWarningsSize (const unsigned int &size)
 Sums the given size to the warnlisted size.
 
+void sumBlacklistededSize (const unsigned int &size)
 Sums the given size to the blacklisted size.
 
+const unsigned int & getPerfSize ()
 Returns the size to be displayed in the main window.
 
+const unsigned int & getTotalSize ()
 Returns the total logs size.
 
+const unsigned int & getParsedLines ()
 Returns the parsed logs lines.
 
void makeChart (const QChart::ChartTheme &theme, const std::unordered_map< std::string, QFont > &fonts, QChartView *size_chart)
 Builds and draws the chart to be displayed in the main window. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Private Member Functions

void startWorking ()
 Sets the working state. More...
 
void stopWorking ()
 Un-sets the working state. More...
 
const QString printableSize (const unsigned int &bytes)
 Returns a printable size to be displayed in the chart, including the suffix. More...
 
void joinLogLines ()
 Reads the selected files and append the resulting lines to the list. More...
 
void parseLogLines ()
 Parses the lines in the list and stores their data in the data collection. More...
 
void storeLogLines ()
 Stores the data collection in the database. More...
 
const std::string sanitizeBWitem (const int &log_field_id, const std::string &new_item)
 Ssnitizes an item removing the unwanted elements. More...
 
void changeIisLogsBaseNames (const int &module_id)
 Changes the name criterions for IIS logs files names depending on the given module. More...
 
+void scanLogsDir ()
 Scans the logs directory to get a list of log files.
 
void setCurrentLogFormat ()
 Uses the current Web Server to set the relative logs format. More...
 
+ + + + + + + + + + +

+Private Attributes

+const unsigned int APACHE_ID = 11
 ID of the Apache2 Web Server.
 
+const unsigned int NGINX_ID = 12
 ID of the Nginx Web Server.
 
+const unsigned int IIS_ID = 13
 ID of the IIS Web Server.
 
+

Detailed Description

+

Craplog.

+

Performs operations related to the logs

+

Member Function Documentation

+ +

◆ blacklistAdd()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void Craplog::blacklistAdd (const int & web_server_id,
const int & log_field_id,
const std::string & new_item 
)
+
+ +

Adds an item to the relative list.

+
Parameters
+ + + + +
web_server_idThe ID of the Web Server
log_field_idThe ID of the log field
new_listThe new items list
+
+
+
See also
BWlist
+ +
+
+ +

◆ blacklistMoveDown()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
const int Craplog::blacklistMoveDown (const int & web_server_id,
const int & log_field_id,
const std::string & item 
)
+
+ +

Moves an item one position down in the relative list.

+
Parameters
+ + + + +
web_server_idThe ID of the Web Server
log_field_idThe ID of the log field
itemThe item to move
+
+
+
See also
BWlist
+ +
+
+ +

◆ blacklistMoveUp()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
const int Craplog::blacklistMoveUp (const int & web_server_id,
const int & log_field_id,
const std::string & item 
)
+
+ +

Moves an item one position up in the relative list.

+
Parameters
+ + + + +
web_server_idThe ID of the Web Server
log_field_idThe ID of the log field
itemThe item to move
+
+
+
See also
BWlist
+ +
+
+ +

◆ blacklistRemove()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void Craplog::blacklistRemove (const int & web_server_id,
const int & log_field_id,
const std::string & item 
)
+
+ +

Removes an item from the relative list.

+
Parameters
+ + + + +
web_server_idThe ID of the Web Server
log_field_idThe ID of the log field
itemThe item to remove from the list
+
+
+
See also
BWlist
+ +
+
+ +

◆ changeIisLogsBaseNames()

+ +
+
+ + + + + +
+ + + + + + + + +
void Craplog::changeIisLogsBaseNames (const int & module_id)
+
+private
+
+ +

Changes the name criterions for IIS logs files names depending on the given module.

+
Parameters
+ + +
module_idThe ID of the module to use to set the criterions
+
+
+
Exceptions
+ + +
GenericException
+
+
+
See also
LogName
+ +
+
+ +

◆ checkStuff()

+ +
+
+ + + + + + + +
const bool Craplog::checkStuff ()
+
+ +

Various checks to be made before starting a new process.

+

Checks the databases, the selected files and their size

Returns
Whether the checks has been successful or not
+
Exceptions
+ + +
GenericException
+
+
+ +
+
+ +

◆ collectPerfData()

+ +
+
+ + + + + + + +
void Craplog::collectPerfData ()
+
+ +

Collects performances data from the sub-modules.

+
See also
LogOps::getParsedSize(), LogOps::getParsedLines()
+ +
+
+ +

◆ getBlacklist()

+ +
+
+ + + + + + + + + + + + + + + + + + +
const std::vector< std::string > & Craplog::getBlacklist (const int & web_server_id,
const int & log_field_id 
)
+
+ +

Returns the relative items list.

+
Parameters
+ + + +
web_server_idThe ID of the Web Server
log_field_idThe ID of the log field
+
+
+
Returns
The list of items in the given blacklist
+
See also
BWlist
+ +
+
+ +

◆ getCurrentLogFormat()

+ +
+
+ + + + + + + +
const FormatOps::LogsFormat & Craplog::getCurrentLogFormat ()
+
+ +

Returns the currently used LogsFormat.

+
Returns
The LogsFormat
+
See also
FormatOps::LogsFormat
+ +
+
+ +

◆ getCurrentWSID()

+ +
+
+ + + + + + + +
const int & Craplog::getCurrentWSID ()
+
+ +

Returns the currently used Web Server ID.

+
Returns
The Web Server ID
+ +
+
+ +

◆ getLogFileItem()

+ +
+
+ + + + + + + + +
const Craplog::LogFile & Craplog::getLogFileItem (const QString & file_name)
+
+ +

Returns the LogFile instance of the given file.

+
Parameters
+ + +
file_nameThe name of the file
+
+
+
Returns
The LogFile instance
+
Exceptions
+ + +
GenericException
+
+
+
See also
LogFile, logs_list
+ +
+
+ +

◆ getLogsFormat()

+ +
+
+ + + + + + + + +
const FormatOps::LogsFormat & Craplog::getLogsFormat (const int & web_server_id)
+
+ +

Returns the LogsFormat currently set for the given Web Server.

+
Parameters
+ + +
web_server_idID of the Web Server
+
+
+
Returns
The LogsFormat instance
+
See also
FormatOps::LogsFormat
+ +
+
+ +

◆ getLogsFormatSample()

+ +
+
+ + + + + + + + +
const QString Craplog::getLogsFormatSample (const int & web_server_id)
+
+ +

Returns a sample log line for the given Web Server using the relative LogsFormat.

+
Parameters
+ + +
web_server_idID of the Web Server
+
+
+
Returns
The sample of a log line
+
Exceptions
+ + +
WebServerException
+
+
+
See also
FormatOps::getApacheLogSample(), FormatOps::getNginxLogSample(), FormatOps::getIisLogSample()
+ +
+
+ +

◆ getLogsFormatString()

+ +
+
+ + + + + + + + +
const std::string & Craplog::getLogsFormatString (const int & web_server_id)
+
+ +

Returns the logs format string for the given Web Server.

+
Parameters
+ + +
web_server_idID of the Web Server
+
+
+
Returns
The format string
+
See also
FormatOps::LogsFormat
+ +
+
+ +

◆ getLogsList()

+ +
+
+ + + + + + + + +
const std::vector< Craplog::LogFile > & Craplog::getLogsList (const bool & fresh = false)
+
+ +

Returns the list of log files.

+
Parameters
+ + +
freshWhether to refresh the list before to return it or not
+
+
+
Returns
The list of log files
+
See also
LogFile, logs_list, scanLogsDir()
+ +
+
+ +

◆ getLogsListSize()

+ +
+
+ + + + + + + +
const int Craplog::getLogsListSize ()
+
+ +

Returns the amount of log files in the list.

+
Returns
The number of files actually in the list
+
See also
logs_list
+ +
+
+ +

◆ getLogsPath()

+ +
+
+ + + + + + + + +
const std::string & Craplog::getLogsPath (const int & web_server)
+
+ +

Returns the logs' path for the given web Server.

+
Parameters
+ + +
web_serverThe ID of the Web Server
+
+
+
Returns
The path of the logs' folder
+ +
+
+ +

◆ getWarnlist()

+ +
+
+ + + + + + + + + + + + + + + + + + +
const std::vector< std::string > & Craplog::getWarnlist (const int & web_server_id,
const int & log_field_id 
)
+
+ +

Returns the relative items list.

+
Parameters
+ + + +
web_server_idThe ID of the Web Server
log_field_idThe ID of the log field
+
+
+
Returns
The list of items in the givenwarnlist
+
See also
BWlist
+ +
+
+ +

◆ isBlacklistUsed()

+ +
+
+ + + + + + + + + + + + + + + + + + +
const bool & Craplog::isBlacklistUsed (const int & web_server_id,
const int & log_field_id 
)
+
+ +

Returns whether the relative blacklist is set to be used or not.

+
Parameters
+ + + +
web_server_idThe ID of the Web Server
log_field_idThe ID of the log field
+
+
+
Returns
Whether the list is used or not
+
See also
BWlist
+ +
+
+ +

◆ isFileNameValid()

+ +
+
+ + + + + + + + +
const bool Craplog::isFileNameValid (const std::string & name)
+
+ +

Checks if a file name respects the relative criterions.

+
Parameters
+ + +
nameThe name of the file
+
+
+
Returns
Wheter it does respect the criterions or not
+
See also
LogName
+ +
+
+ +

◆ isWarnlistUsed()

+ +
+
+ + + + + + + + + + + + + + + + + + +
const bool & Craplog::isWarnlistUsed (const int & web_server_id,
const int & log_field_id 
)
+
+ +

Returns whether the relative warnlist is set to be used or not.

+
Parameters
+ + + +
web_server_idThe ID of the Web Server
log_field_idThe ID of the log field
+
+
+
Returns
Whether the list is used or not
+
See also
BWlist
+ +
+
+ +

◆ joinLogLines()

+ +
+
+ + + + + +
+ + + + + + + +
void Craplog::joinLogLines ()
+
+private
+
+ +

Reads the selected files and append the resulting lines to the list.

+
Exceptions
+ + +
GenericException
+
+
+ +
+
+ +

◆ makeChart()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void Craplog::makeChart (const QChart::ChartTheme & theme,
const std::unordered_map< std::string, QFont > & fonts,
QChartView * size_chart 
)
+
+ +

Builds and draws the chart to be displayed in the main window.

+
Parameters
+ + + + +
themeThe theme to use for the Chart
fontsThe map holding the fonts
size_chartThe widget which will display the chart
+
+
+
See also
DonutBreakdown
+ +
+
+ +

◆ parseLogLines()

+ +
+
+ + + + + +
+ + + + + + + +
void Craplog::parseLogLines ()
+
+private
+
+ +

Parses the lines in the list and stores their data in the data collection.

+
See also
LogOps::parseLines()
+ +
+
+ +

◆ printableSize()

+ +
+
+ + + + + +
+ + + + + + + + +
const QString Craplog::printableSize (const unsigned int & bytes)
+
+private
+
+ +

Returns a printable size to be displayed in the chart, including the suffix.

+
Parameters
+ + +
bytesThe size in bytes
+
+
+
Returns
The string to be displayed
+
See also
makeChart()
+ +
+
+ +

◆ run()

+ +
+
+ + + + + + + +
void Craplog::run ()
+
+ +

Main work method.

+

Manages the operations which need to be done to parse the logs when the START button is pressed

+ +
+
+ +

◆ sanitizeBWitem()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
const std::string Craplog::sanitizeBWitem (const int & log_field_id,
const std::string & new_item 
)
+
+private
+
+ +

Ssnitizes an item removing the unwanted elements.

+

Called when adding a new item to a list

Parameters
+ + + +
log_field_idThe ID of the log field
new_itemThe item to be sanitized
+
+
+
Returns
The sanitized item
+
Exceptions
+ + +
BWlistException,GenericException
+
+
+
See also
BWlist
+ +
+
+ +

◆ setApacheLogFormat()

+ +
+
+ + + + + + + + +
const bool Craplog::setApacheLogFormat (const std::string & format_string)
+
+ +

Sets the Apache2 LogsFormat from the given format string.

+
Parameters
+ + +
format_stringThe logs format string
+
+
+
Returns
Whether the process was successful or not
+
See also
FormatOps, FormatOps::LogsFormat, FormatOps::processApacheFormatString()
+ +
+
+ +

◆ setBlacklist()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void Craplog::setBlacklist (const int & web_server_id,
const int & log_field_id,
const std::vector< std::string > & new_list 
)
+
+ +

Sets the relative items list.

+
Parameters
+ + + + +
web_server_idThe ID of the Web Server
log_field_idThe ID of the log field
new_listThe new items list
+
+
+
See also
BWlist
+ +
+
+ +

◆ setBlacklistUsed()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void Craplog::setBlacklistUsed (const int & web_server_id,
const int & log_field_id,
const bool & used 
)
+
+ +

Sets the relative blacklist to be used or not.

+
Parameters
+ + + + +
web_server_idThe ID of the Web Server
log_field_idThe ID of the log field
usedWhether the list is to be used or not
+
+
+
See also
BWlist
+ +
+
+ +

◆ setCurrentLogFormat()

+ +
+
+ + + + + +
+ + + + + + + +
void Craplog::setCurrentLogFormat ()
+
+private
+
+ +

Uses the current Web Server to set the relative logs format.

+
See also
LogOps::LogsFormat
+ +
+
+ +

◆ setCurrentWSID()

+ +
+
+ + + + + + + + +
void Craplog::setCurrentWSID (const int & web_server_id)
+
+ +

Sets the currently used Web Server ID.

+
Parameters
+ + +
web_server_idThe new currently used Web Server
+
+
+ +
+
+ +

◆ setHashesDatabasePath()

+ +
+
+ + + + + + + + +
void Craplog::setHashesDatabasePath (const std::string & path)
+
+ +

Sets the new path for the log files' Hashes database.

+
Parameters
+ + +
Thenew path of the database file
+
+
+ +
+
+ +

◆ setIisLogFormat()

+ +
+
+ + + + + + + + + + + + + + + + + + +
const bool Craplog::setIisLogFormat (const std::string & format_string,
const int & log_module 
)
+
+ +

Sets the IIS LogsFormat from the given format string.

+
Parameters
+ + + +
format_stringThe logs format string
log_moduleThe IIS logs module to be used to parse the format string
+
+
+
Returns
Whether the process was successful or not
+
See also
FormatOps, FormatOps::LogsFormat, FormatOps::processIisFormatString()
+ +
+
+ +

◆ setLogFileSelected()

+ +
+
+ + + + + + + + +
const bool Craplog::setLogFileSelected (const QString & file_name)
+
+ +

Sets a file in the list as selected.

+
Parameters
+ + +
file_nameThe name of the file
+
+
+
Returns
Wheter the given file name has been found in the list
+
See also
LogFile, logs_list
+ +
+
+ +

◆ setLogsPath()

+ +
+
+ + + + + + + + + + + + + + + + + + +
void Craplog::setLogsPath (const int & web_server,
const std::string & new_path 
)
+
+ +

Sets a new path for the given Web Server to search the logs in.

+
Parameters
+ + + +
web_serverThe ID of the Web Server
new_pathThe new path
+
+
+ +
+
+ +

◆ setNginxLogFormat()

+ +
+
+ + + + + + + + +
const bool Craplog::setNginxLogFormat (const std::string & format_string)
+
+ +

Sets the Nginx LogsFormat from the given format string.

+
Parameters
+ + +
format_stringThe logs format string
+
+
+
Returns
Whether the process was successful or not
+
See also
FormatOps, FormatOps::LogsFormat, FormatOps::processNginxFormatString()
+ +
+
+ +

◆ setStatsDatabasePath()

+ +
+
+ + + + + + + + +
void Craplog::setStatsDatabasePath (const std::string & path)
+
+ +

Sets the new path for the logs Collection database.

+
Parameters
+ + +
Thenew path of the database file
+
+
+ +
+
+ +

◆ setWarnlist()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void Craplog::setWarnlist (const int & web_server_id,
const int & log_field_id,
const std::vector< std::string > & new_list 
)
+
+ +

Sets the relative items list.

+
Parameters
+ + + + +
web_server_idThe ID of the Web Server
log_field_idThe ID of the log field
new_listThe new items list
+
+
+
See also
BWlist
+ +
+
+ +

◆ setWarnlistUsed()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void Craplog::setWarnlistUsed (const int & web_server_id,
const int & log_field_id,
const bool & used 
)
+
+ +

Sets the relative warnlist to be used or not.

+
Parameters
+ + + + +
web_server_idThe ID of the Web Server
log_field_idThe ID of the log field
usedWhether the list is to be used or not
+
+
+
See also
BWlist
+ +
+
+ +

◆ startWorking()

+ +
+
+ + + + + +
+ + + + + + + +
void Craplog::startWorking ()
+
+private
+
+ +

Sets the working state.

+
See also
isWorking()
+ +
+
+ +

◆ stopWorking()

+ +
+
+ + + + + +
+ + + + + + + +
void Craplog::stopWorking ()
+
+private
+
+ +

Un-sets the working state.

+
See also
isWorking()
+ +
+
+ +

◆ storeLogLines()

+ +
+
+ + + + + +
+ + + + + + + +
void Craplog::storeLogLines ()
+
+private
+
+ +

Stores the data collection in the database.

+
See also
StoreOps::storeData()
+ +
+
+ +

◆ warnlistAdd()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void Craplog::warnlistAdd (const int & web_server_id,
const int & log_field_id,
const std::string & new_item 
)
+
+ +

Adds an item to the relative list.

+
Parameters
+ + + + +
web_server_idThe ID of the Web Server
log_field_idThe ID of the log field
new_itemThe new item to add to the list
+
+
+
See also
BWlist
+ +
+
+ +

◆ warnlistMoveDown()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
const int Craplog::warnlistMoveDown (const int & web_server_id,
const int & log_field_id,
const std::string & item 
)
+
+ +

Moves an item one position down in the relative list.

+
Parameters
+ + + + +
web_server_idThe ID of the Web Server
log_field_idThe ID of the log field
itemThe item to move
+
+
+
See also
BWlist
+ +
+
+ +

◆ warnlistMoveUp()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
const int Craplog::warnlistMoveUp (const int & web_server_id,
const int & log_field_id,
const std::string & item 
)
+
+ +

Moves an item one position up in the relative list.

+
Parameters
+ + + + +
web_server_idThe ID of the Web Server
log_field_idThe ID of the log field
itemThe item to move
+
+
+
See also
BWlist
+ +
+
+ +

◆ warnlistRemove()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void Craplog::warnlistRemove (const int & web_server_id,
const int & log_field_id,
const std::string & item 
)
+
+ +

Removes an item from the relative list.

+
Parameters
+ + + + +
web_server_idThe ID of the Web Server
log_field_idThe ID of the log field
itemThe item to remove from the list
+
+
+
See also
BWlist
+ +
+
+
The documentation for this class was generated from the following files:
    +
  • logdoctor/modules/craplog/craplog.h
  • +
  • logdoctor/modules/craplog/craplog.cpp
  • +
+
+ + + + diff --git a/docs/html/classCrapnote-members.html b/docs/html/classCrapnote-members.html new file mode 100644 index 00000000..6faec9e9 --- /dev/null +++ b/docs/html/classCrapnote-members.html @@ -0,0 +1,91 @@ + + + + + + + +LogDoctor: Member List + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
+
Crapnote Member List
+
+
+ +

This is the complete list of members for Crapnote, including all inherited members.

+ + + + + + +
on_button_FontSize_Minus_clicked()Crapnoteprivateslot
on_button_FontSize_Plus_clicked()Crapnoteprivateslot
on_spinBox_FontSize_valueChanged(int arg1)Crapnoteprivateslot
setColorScheme(const int &color_scheme_id)Crapnote
setTextFont(const QFont &font)Crapnote
+ + + + diff --git a/docs/html/classCrapnote.html b/docs/html/classCrapnote.html new file mode 100644 index 00000000..18e57ea2 --- /dev/null +++ b/docs/html/classCrapnote.html @@ -0,0 +1,132 @@ + + + + + + + +LogDoctor: Crapnote Class Reference + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
+ +
Crapnote Class Reference
+
+
+ +

Crapnote. + More...

+ +

#include <crapnote.h>

+
+Inheritance diagram for Crapnote:
+
+
+ +
+ + + + + + + + +

+Public Member Functions

+void setTextFont (const QFont &font)
 Sets the given font.
 
+void setColorScheme (const int &color_scheme_id)
 Sets the given color-scheme.
 
+ + + + + + + + + + +

+Private Slots

+void on_spinBox_FontSize_valueChanged (int arg1)
 Sets the given font size.
 
+void on_button_FontSize_Minus_clicked ()
 Decrease the font size of 1 point.
 
+void on_button_FontSize_Plus_clicked ()
 Increase the font size of 1 point.
 
+

Detailed Description

+

Crapnote.

+

A simple block-note like widget

+

The documentation for this class was generated from the following files:
    +
  • logdoctor/tools/crapnote/crapnote.h
  • +
  • logdoctor/tools/crapnote/crapnote.cpp
  • +
+
+ + + + diff --git a/docs/html/classCrapnote.png b/docs/html/classCrapnote.png new file mode 100644 index 00000000..0f17b9a5 Binary files /dev/null and b/docs/html/classCrapnote.png differ diff --git a/docs/html/classCrapup-members.html b/docs/html/classCrapup-members.html new file mode 100644 index 00000000..8f9e1a00 --- /dev/null +++ b/docs/html/classCrapup-members.html @@ -0,0 +1,93 @@ + + + + + + + +LogDoctor: Member List + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
+
Crapup Member List
+
+
+ +

This is the complete list of members for Crapup, including all inherited members.

+ + + + + + + + +
abortRequest()Crapupsignal
closeEvent(QCloseEvent *event)Crapupprivateslot
Crapup(const int &window_theme_id, const QString &icons_theme, QWidget *parent=nullptr)Crapup
deleteReply()Crapupprivate
requestTimeout()Crapupprivateslot
rotateImg()Crapupprivateslot
versionCheck(const float &current_version)Crapup
+ + + + diff --git a/docs/html/classCrapup.html b/docs/html/classCrapup.html new file mode 100644 index 00000000..1e4ea2e1 --- /dev/null +++ b/docs/html/classCrapup.html @@ -0,0 +1,250 @@ + + + + + + + +LogDoctor: Crapup Class Reference + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
+ +

Crapup. + More...

+ +

#include <crapup.h>

+
+Inheritance diagram for Crapup:
+
+
+ +
+ + + + + +

+Signals

+void abortRequest ()
 Emitted to abort an on-going request.
 
+ + + + + + + +

+Public Member Functions

 Crapup (const int &window_theme_id, const QString &icons_theme, QWidget *parent=nullptr)
 Class constructor. More...
 
void versionCheck (const float &current_version)
 Performs a version check. More...
 
+ + + + + + + + + + +

+Private Slots

+void closeEvent (QCloseEvent *event)
 Override.
 
void requestTimeout ()
 Called when a request's times out. More...
 
+void rotateImg ()
 Rotates the 'checking' image.
 
+ + + + +

+Private Member Functions

+void deleteReply ()
 Deletes the reply in a safe way.
 
+

Detailed Description

+

Constructor & Destructor Documentation

+ +

◆ Crapup()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
Crapup::Crapup (const int & window_theme_id,
const QString & icons_theme,
QWidget * parent = nullptr 
)
+
+ +

Class constructor.

+
Parameters
+ + + + +
window_theme_idThe ID of the window theme
iconstheme The theme of the icons
parentThe parent Widget
+
+
+ +
+
+

Member Function Documentation

+ +

◆ requestTimeout

+ +
+
+ + + + + +
+ + + + + + + +
void Crapup::requestTimeout ()
+
+privateslot
+
+ +

Called when a request's times out.

+
See also
deleteReply(), abortRequest()
+ +
+
+ +

◆ versionCheck()

+ +
+
+ + + + + + + + +
void Crapup::versionCheck (const float & current_version)
+
+ +

Performs a version check.

+
Parameters
+ + +
current_versionThe running version of LogDoctor
+
+
+
Exceptions
+ + +
GenericException
+
+
+ +
+
+
The documentation for this class was generated from the following files:
    +
  • logdoctor/modules/crapup/crapup.h
  • +
  • logdoctor/modules/crapup/crapup.cpp
  • +
+
+ + + + diff --git a/docs/html/classCrapup.png b/docs/html/classCrapup.png new file mode 100644 index 00000000..ce3ab70e Binary files /dev/null and b/docs/html/classCrapup.png differ diff --git a/docs/html/classCrapview-members.html b/docs/html/classCrapview-members.html new file mode 100644 index 00000000..558ba493 --- /dev/null +++ b/docs/html/classCrapview-members.html @@ -0,0 +1,113 @@ + + + + + + + +LogDoctor: Member List + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
+
Crapview Member List
+
+
+ +

This is the complete list of members for Crapview, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
calcGlobals(std::vector< std::tuple< QString, QString > > &recur_list, std::vector< std::tuple< QString, QString > > &traffic_list, std::vector< std::tuple< QString, QString > > &perf_list, std::vector< QString > &work_list, const QString &web_server)Crapview
clearDates()Crapview
drawCount(QTableWidget *table, QtCharts::QChartView *chart, const QChart::ChartTheme &theme, const std::unordered_map< std::string, QFont > &fonts, const QString &web_server, const QString &year, const QString &month, const QString &day, const QString &field)Crapview
drawDay(QtCharts::QChartView *chart, const QChart::ChartTheme &theme, const std::unordered_map< std::string, QFont > &fonts, const QString &web_server, const QString &from_year, const QString &from_month, const QString &from_day, const QString &to_year, const QString &to_month, const QString &to_day, const QString &field, const QString &filter)Crapview
drawRelat(QtCharts::QChartView *chart, const QChart::ChartTheme &theme, const std::unordered_map< std::string, QFont > &fonts, const QString &web_server, const QString &from_year, const QString &from_month, const QString &from_day, const QString &to_year, const QString &to_month, const QString &to_day, const QString &field_1, const QString &filter_1, const QString &field_2, const QString &filter_2)Crapview
drawSpeed(QTableWidget *table, QtCharts::QChartView *chart, const QChart::ChartTheme &theme, const std::unordered_map< std::string, QFont > &fonts, const QString &web_server, const QString &year, const QString &month, const QString &day, const QString &protocol, const QString &method, const QString &uri, const QString &query, const QString &response)Crapview
drawWarn(QTableWidget *table, QtCharts::QChartView *chart, const QChart::ChartTheme &theme, const std::unordered_map< std::string, QFont > &fonts, const QString &web_server, const QString &year, const QString &month, const QString &day, const QString &hour)Crapview
getDays(const QString &web_server, const QString &year, const QString &month)Crapview
getDialogsLevel()Crapview
getFields(const std::string &tab)Crapview
getHours()Crapview
getLogFieldID(const QString &field_str)Crapview
getLogFieldString(const int &field_id)Crapview
getMonthNumber(const QString &month_str)Crapview
getMonths(const QString &web_server, const QString &year)Crapview
getYears(const QString &web_server)Crapview
parseBooleanFilter(const QString &filter_str)Crapview
parseNumericFilter(const QString &filter_str)Crapview
parseTextualFilter(const QString &filter_str)Crapview
printableDate(const int &year, const int &month, const int &day)Crapviewprivate
printableTime(const int &hour, const int &minute, const int &second)Crapviewprivate
printableWarn(const int &value)Crapviewprivate
refreshDates()Crapview
setChartsTheme(const int &new_theme_id)Crapview
setDbPath(const std::string &path)Crapview
setDialogsLevel(const int &new_level)Crapview
updateWarn(QTableWidget *table, const QString &web_server)Crapview
+ + + + diff --git a/docs/html/classCrapview.html b/docs/html/classCrapview.html new file mode 100644 index 00000000..53de8983 --- /dev/null +++ b/docs/html/classCrapview.html @@ -0,0 +1,1294 @@ + + + + + + + +LogDoctor: Crapview Class Reference + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
+ +

Crapview. + More...

+ +

#include <crapview.h>

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

+const int & getDialogsLevel ()
 Returns the Dialogs level.
 
+void setDialogsLevel (const int &new_level)
 Sets the new Dialogs level.
 
+void setChartsTheme (const int &new_theme_id)
 Sets the new charts theme to use.
 
void setDbPath (const std::string &path)
 Sets the new path for the logs Collection database. More...
 
const QString parseBooleanFilter (const QString &filter_str)
 Parses a filter for a database field with boolean type. More...
 
const QString parseNumericFilter (const QString &filter_str)
 Parses a filter for a log field with integer type. More...
 
const QString parseTextualFilter (const QString &filter_str)
 Parses a filter for a log field with text type. More...
 
const QString getLogFieldString (const int &field_id)
 Returns the printable log field corresponding to the given ID. More...
 
const int getLogFieldID (const QString &field_str)
 Returns the log field ID corresponding to the given printable field. More...
 
const int getMonthNumber (const QString &month_str)
 Returns the month number corresponding to the given printable month. More...
 
+void refreshDates ()
 Refreshes the list of the dates which are available in the database.
 
+void clearDates ()
 Erases the list of available dates.
 
const QStringList getYears (const QString &web_server)
 Returns le list of available years, for the given web server. More...
 
const QStringList getMonths (const QString &web_server, const QString &year)
 Returns le list of available months in the given year, for the given web server. More...
 
const QStringList getDays (const QString &web_server, const QString &year, const QString &month)
 Returns le list of available days in the given month and year, for the given web server. More...
 
const QStringList getHours ()
 Returns all the hours of the day. More...
 
const QStringList getFields (const std::string &tab)
 Returns a list of the fields for the given tab. More...
 
void updateWarn (QTableWidget *table, const QString &web_server)
 Updates the database applying the changes which have been made to the table. More...
 
void drawWarn (QTableWidget *table, QtCharts::QChartView *chart, const QChart::ChartTheme &theme, const std::unordered_map< std::string, QFont > &fonts, const QString &web_server, const QString &year, const QString &month, const QString &day, const QString &hour)
 Draws the chart and fills the table for the Warnings stats. More...
 
void drawSpeed (QTableWidget *table, QtCharts::QChartView *chart, const QChart::ChartTheme &theme, const std::unordered_map< std::string, QFont > &fonts, const QString &web_server, const QString &year, const QString &month, const QString &day, const QString &protocol, const QString &method, const QString &uri, const QString &query, const QString &response)
 Draws the chart and fills the table for the Speed stats. More...
 
void drawCount (QTableWidget *table, QtCharts::QChartView *chart, const QChart::ChartTheme &theme, const std::unordered_map< std::string, QFont > &fonts, const QString &web_server, const QString &year, const QString &month, const QString &day, const QString &field)
 Draws the chart and fills the table for the Counts stats. More...
 
void drawDay (QtCharts::QChartView *chart, const QChart::ChartTheme &theme, const std::unordered_map< std::string, QFont > &fonts, const QString &web_server, const QString &from_year, const QString &from_month, const QString &from_day, const QString &to_year, const QString &to_month, const QString &to_day, const QString &field, const QString &filter)
 Draws the chart for the Daytime stats. More...
 
void drawRelat (QtCharts::QChartView *chart, const QChart::ChartTheme &theme, const std::unordered_map< std::string, QFont > &fonts, const QString &web_server, const QString &from_year, const QString &from_month, const QString &from_day, const QString &to_year, const QString &to_month, const QString &to_day, const QString &field_1, const QString &filter_1, const QString &field_2, const QString &filter_2)
 Draws the chart for the Relational stats. More...
 
const bool calcGlobals (std::vector< std::tuple< QString, QString > > &recur_list, std::vector< std::tuple< QString, QString > > &traffic_list, std::vector< std::tuple< QString, QString > > &perf_list, std::vector< QString > &work_list, const QString &web_server)
 Retrieves the data to fill the Globals stats. More...
 
+ + + + + + + + + + +

+Private Member Functions

const QString printableDate (const int &year, const int &month, const int &day)
 Returns a string of the given date in the format YYY-MM-DD. More...
 
const QString printableTime (const int &hour, const int &minute, const int &second)
 Returns a string of the given time in the format HH:MM:SS. More...
 
const QString printableWarn (const int &value)
 Returns a string corresponding to the given value. More...
 
+

Detailed Description

+

Crapview.

+

Performs operations related to the visualization of the statistics

+

Member Function Documentation

+ +

◆ calcGlobals()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
const bool Crapview::calcGlobals (std::vector< std::tuple< QString, QString > > & recur_list,
std::vector< std::tuple< QString, QString > > & traffic_list,
std::vector< std::tuple< QString, QString > > & perf_list,
std::vector< QString > & work_list,
const QString & web_server 
)
+
+ +

Retrieves the data to fill the Globals stats.

+
Parameters
+ + + + + + +
recur_listThe list which will hold the printable recurrencies
traffic_listThe list which will hold the printable traffics
perf_listThe list which will hold the printable performances
work_listThe list which will hold the printable overall work infos
web_serverThe printable Web Server name
+
+
+
Returns
Whether the operation has been successful or not
+ +
+
+ +

◆ drawCount()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void Crapview::drawCount (QTableWidget * table,
QtCharts::QChartView * chart,
const QChart::ChartTheme & theme,
const std::unordered_map< std::string, QFont > & fonts,
const QString & web_server,
const QString & year,
const QString & month,
const QString & day,
const QString & field 
)
+
+ +

Draws the chart and fills the table for the Counts stats.

+
Parameters
+ + + + + + + + + + +
tableThe table widget
chartThe chart widget
themeThe theme to use for the chart
fontsThe map holding the fonts
web_serverThe printable Web Server name
yearThe year
monthThe printable month name
dayThe day
fieldThe printable log field
+
+
+ +
+
+ +

◆ drawDay()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void Crapview::drawDay (QtCharts::QChartView * chart,
const QChart::ChartTheme & theme,
const std::unordered_map< std::string, QFont > & fonts,
const QString & web_server,
const QString & from_year,
const QString & from_month,
const QString & from_day,
const QString & to_year,
const QString & to_month,
const QString & to_day,
const QString & field,
const QString & filter 
)
+
+ +

Draws the chart for the Daytime stats.

+
Parameters
+ + + + + + + + + + + + + +
chartThe chart widget
themeThe theme to use for the chart
fontsThe map holding the fonts
web_serverThe printable Web Server name
yearThe initial year
monthThe initial printable month name
dayThe initial day
yearThe final year
monthThe final printable month name
dayThe finl day
fieldThe printable log field
filterThe give filter string
+
+
+ +
+
+ +

◆ drawRelat()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void Crapview::drawRelat (QtCharts::QChartView * chart,
const QChart::ChartTheme & theme,
const std::unordered_map< std::string, QFont > & fonts,
const QString & web_server,
const QString & from_year,
const QString & from_month,
const QString & from_day,
const QString & to_year,
const QString & to_month,
const QString & to_day,
const QString & field_1,
const QString & filter_1,
const QString & field_2,
const QString & filter_2 
)
+
+ +

Draws the chart for the Relational stats.

+
Parameters
+ + + + + + + + + + + + + + + +
chartThe chart widget
themeThe theme to use for the chart
fontsThe map holding the fonts
web_serverThe printable Web Server name
yearThe initial year
monthThe initial printable month name
dayThe initial day
yearThe final year
monthThe final printable month name
dayThe finl day
field_1The first printable log field
filter_1The give filter string for the first field
field_2The second printable log field
filter_2The give filter string for the second field
+
+
+ +
+
+ +

◆ drawSpeed()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void Crapview::drawSpeed (QTableWidget * table,
QtCharts::QChartView * chart,
const QChart::ChartTheme & theme,
const std::unordered_map< std::string, QFont > & fonts,
const QString & web_server,
const QString & year,
const QString & month,
const QString & day,
const QString & protocol,
const QString & method,
const QString & uri,
const QString & query,
const QString & response 
)
+
+ +

Draws the chart and fills the table for the Speed stats.

+
Parameters
+ + + + + + + + + + + + + + +
tableThe table widget
chartThe chart widget
themeThe theme to use for the chart
fontsThe map holding the fonts
web_serverThe printable Web Server name
yearThe year
monthThe printable month name
dayThe day
protocolThe given filter for the Protocol
methodThe given filter for the Method
uriThe given filter for the URI
queryThe given filter for the Query
responseThe given filter for the Response
+
+
+ +
+
+ +

◆ drawWarn()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void Crapview::drawWarn (QTableWidget * table,
QtCharts::QChartView * chart,
const QChart::ChartTheme & theme,
const std::unordered_map< std::string, QFont > & fonts,
const QString & web_server,
const QString & year,
const QString & month,
const QString & day,
const QString & hour 
)
+
+ +

Draws the chart and fills the table for the Warnings stats.

+
Parameters
+ + + + + + + + + + +
tableThe table widget
chartThe chart widget
themeThe theme to use for the chart
fontsThe map holding the fonts
web_serverThe printable Web Server name
yearThe year
monthThe printable month name
dayThe day
houtThe hour
+
+
+ +
+
+ +

◆ getDays()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
const QStringList Crapview::getDays (const QString & web_server,
const QString & year,
const QString & month 
)
+
+ +

Returns le list of available days in the given month and year, for the given web server.

+
Parameters
+ + + + +
web_serverThe printable Web Server name
yearThe year
monthThe printable month name
+
+
+
Returns
The list of days which are avaliable
+ +
+
+ +

◆ getFields()

+ +
+
+ + + + + + + + +
const QStringList Crapview::getFields (const std::string & tab)
+
+ +

Returns a list of the fields for the given tab.

+
Parameters
+ + +
tabThe stats tab
+
+
+
Returns
The list of fields
+ +
+
+ +

◆ getHours()

+ +
+
+ + + + + + + +
const QStringList Crapview::getHours ()
+
+ +

Returns all the hours of the day.

+
Returns
The list of all the hours
+ +
+
+ +

◆ getLogFieldID()

+ +
+
+ + + + + + + + +
const int Crapview::getLogFieldID (const QString & field_str)
+
+ +

Returns the log field ID corresponding to the given printable field.

+
Parameters
+ + +
field_strThe log field
+
+
+
Returns
The ID of the log field
+ +
+
+ +

◆ getLogFieldString()

+ +
+
+ + + + + + + + +
const QString Crapview::getLogFieldString (const int & field_id)
+
+ +

Returns the printable log field corresponding to the given ID.

+

The field gets translated to be printable before being returned

Parameters
+ + +
field_idThe ID of the log fiels
+
+
+
Returns
The printable field
+ +
+
+ +

◆ getMonthNumber()

+ +
+
+ + + + + + + + +
const int Crapview::getMonthNumber (const QString & month_str)
+
+ +

Returns the month number corresponding to the given printable month.

+
Parameters
+ + +
month_StrThe printable month name
+
+
+
Returns
The month number
+ +
+
+ +

◆ getMonths()

+ +
+
+ + + + + + + + + + + + + + + + + + +
const QStringList Crapview::getMonths (const QString & web_server,
const QString & year 
)
+
+ +

Returns le list of available months in the given year, for the given web server.

+
Parameters
+ + + +
web_serverThe printable Web Server name
yearThe year
+
+
+
Returns
The list of printable month names which are avaliable
+ +
+
+ +

◆ getYears()

+ +
+
+ + + + + + + + +
const QStringList Crapview::getYears (const QString & web_server)
+
+ +

Returns le list of available years, for the given web server.

+
Parameters
+ + +
web_serverThe printable Web Server name
+
+
+
Returns
The list of yearss which are avaliable
+ +
+
+ +

◆ parseBooleanFilter()

+ +
+
+ + + + + + + + +
const QString Crapview::parseBooleanFilter (const QString & filter_str)
+
+ +

Parses a filter for a database field with boolean type.

+
Parameters
+ + +
field_strThe given filter
+
+
+
Returns
The resulting filter to apply at the query
+ +
+
+ +

◆ parseNumericFilter()

+ +
+
+ + + + + + + + +
const QString Crapview::parseNumericFilter (const QString & filter_str)
+
+ +

Parses a filter for a log field with integer type.

+
Parameters
+ + +
field_strThe given filter
+
+
+
Returns
The resulting filter to apply at the query
+ +
+
+ +

◆ parseTextualFilter()

+ +
+
+ + + + + + + + +
const QString Crapview::parseTextualFilter (const QString & filter_str)
+
+ +

Parses a filter for a log field with text type.

+
Parameters
+ + +
field_strThe given filter
+
+
+
Returns
The resulting filter to apply at the query
+ +
+
+ +

◆ printableDate()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
const QString Crapview::printableDate (const int & year,
const int & month,
const int & day 
)
+
+private
+
+ +

Returns a string of the given date in the format YYY-MM-DD.

+
Parameters
+ + + + +
yearThe year
monthThe month
dayThe day
+
+
+
Returns
The printable date
+

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

+
Parameters
+ + + + +
yearThe year
monthThe month
dayThe day
+
+
+
Returns
The printable date
+ +
+
+ +

◆ printableTime()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
const QString Crapview::printableTime (const int & hour,
const int & minute,
const int & second 
)
+
+private
+
+ +

Returns a string of the given time in the format HH:MM:SS.

+
Parameters
+ + + + +
hourThe hour
minutThe minute
secondThe second
+
+
+
Returns
The printable time
+ +
+
+ +

◆ printableWarn()

+ +
+
+ + + + + +
+ + + + + + + + +
const QString Crapview::printableWarn (const int & value)
+
+private
+
+ +

Returns a string corresponding to the given value.

+

Used to convert numeric booleans [0,1] to string [FALSE,TRUE]

Parameters
+ + +
valueThe value to convert
+
+
+
Returns
The corresponding printable string
+ +
+
+ +

◆ setDbPath()

+ +
+
+ + + + + + + + +
void Crapview::setDbPath (const std::string & path)
+
+ +

Sets the new path for the logs Collection database.

+
See also
DbQuery::setDbPath()
+ +
+
+ +

◆ updateWarn()

+ +
+
+ + + + + + + + + + + + + + + + + + +
void Crapview::updateWarn (QTableWidget * table,
const QString & web_server 
)
+
+ +

Updates the database applying the changes which have been made to the table.

+
Parameters
+ + + +
tableThe Warnings stats table
web_serverThe printable Web Server name
+
+
+ +
+
+
The documentation for this class was generated from the following files:
    +
  • logdoctor/modules/crapview/crapview.h
  • +
  • logdoctor/modules/crapview/crapview.cpp
  • +
+
+ + + + diff --git a/docs/html/classCrissCross-members.html b/docs/html/classCrissCross-members.html new file mode 100644 index 00000000..e9086830 --- /dev/null +++ b/docs/html/classCrissCross-members.html @@ -0,0 +1,96 @@ + + + + + + + +LogDoctor: Member List + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
+
CrissCross Member List
+
+
+ +

This is the complete list of members for CrissCross, including all inherited members.

+ + + + + + + + + + + +
AI_makeChoice()CrissCrossprivate
AI_playTurn()CrissCrossprivate
AI_updateWeights()CrissCrossprivate
checkVictory()CrissCrossprivate
draw()CrissCrossprivate
endTurn()CrissCrossprivate
gameDraw()CrissCrossprivate
isPlayerTurn()CrissCrossprivate
nextTurn()CrissCrossprivate
victory()CrissCrossprivate
+ + + + diff --git a/docs/html/classCrissCross.html b/docs/html/classCrissCross.html new file mode 100644 index 00000000..b8bffe30 --- /dev/null +++ b/docs/html/classCrissCross.html @@ -0,0 +1,204 @@ + + + + + + + +LogDoctor: CrissCross Class Reference + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
+ +
CrissCross Class Reference
+
+
+ +

CrissCross. + More...

+ +

#include <game.h>

+
+Inheritance diagram for CrissCross:
+
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Private Member Functions

+void endTurn ()
 Ends the current turn.
 
+void nextTurn ()
 Switches to the next turn.
 
+const bool isPlayerTurn ()
 Checks whether it's the human player turn or not.
 
+const bool checkVictory ()
 Checks whether somebody won or not.
 
+const bool gameDraw ()
 Checks whether the game is draw or not.
 
+void victory ()
 Someone won, process the victory.
 
+void draw ()
 The match is over but nobody won, the game is draw.
 
+void AI_playTurn ()
 Main function for the AI to play its turn.
 
void AI_updateWeights ()
 Updates the weights of the tiles. More...
 
const unsigned int AI_makeChoice ()
 Makes the choice depending on the weights. More...
 
+

Detailed Description

+

CrissCross.

+

Player vs AI criss-cross game

+

Member Function Documentation

+ +

◆ AI_makeChoice()

+ +
+
+ + + + + +
+ + + + + + + +
const unsigned int CrissCross::AI_makeChoice ()
+
+private
+
+ +

Makes the choice depending on the weights.

+
Returns
The tile to select
+
See also
AI_playTurn();
+ +
+
+ +

◆ AI_updateWeights()

+ +
+
+ + + + + +
+ + + + + + + +
void CrissCross::AI_updateWeights ()
+
+private
+
+ +

Updates the weights of the tiles.

+
See also
AI_playTurn();
+ +
+
+
The documentation for this class was generated from the following files:
    +
  • logdoctor/games/crisscross/game.h
  • +
  • logdoctor/games/crisscross/game.cpp
  • +
+
+ + + + diff --git a/docs/html/classCrissCross.png b/docs/html/classCrissCross.png new file mode 100644 index 00000000..f36f39ab Binary files /dev/null and b/docs/html/classCrissCross.png differ diff --git a/docs/html/classDateTimeException-members.html b/docs/html/classDateTimeException-members.html new file mode 100644 index 00000000..57bc8a2e --- /dev/null +++ b/docs/html/classDateTimeException-members.html @@ -0,0 +1,85 @@ + + + + + + + +LogDoctor: Member List + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
+
DateTimeException Member List
+
+
+ +

This is the complete list of members for DateTimeException, including all inherited members.

+
+ + + + diff --git a/docs/html/classDateTimeException.html b/docs/html/classDateTimeException.html new file mode 100644 index 00000000..987000a6 --- /dev/null +++ b/docs/html/classDateTimeException.html @@ -0,0 +1,103 @@ + + + + + + + +LogDoctor: DateTimeException Class Reference + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
+ +
DateTimeException Class Reference
+
+
+ +

DateTimeException. + More...

+ +

#include <exceptions.h>

+
+Inheritance diagram for DateTimeException:
+
+
+ +
+

Detailed Description

+

DateTimeException.

+

Exception related to a date/time

+

The documentation for this class was generated from the following files:
    +
  • logdoctor/modules/exceptions.h
  • +
  • logdoctor/modules/exceptions.cpp
  • +
+
+ + + + diff --git a/docs/html/classDateTimeException.png b/docs/html/classDateTimeException.png new file mode 100644 index 00000000..8fc51ac7 Binary files /dev/null and b/docs/html/classDateTimeException.png differ diff --git a/docs/html/classDateTimeOps-members.html b/docs/html/classDateTimeOps-members.html new file mode 100644 index 00000000..5249d89c --- /dev/null +++ b/docs/html/classDateTimeOps-members.html @@ -0,0 +1,88 @@ + + + + + + + +LogDoctor: Member List + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
+
DateTimeOps Member List
+
+
+ +

This is the complete list of members for DateTimeOps, including all inherited members.

+ + + +
convertMonth(const std::string &month)DateTimeOpsprivatestatic
processDateTime(const std::string &datetime, const std::string &format)DateTimeOpsstatic
+ + + + diff --git a/docs/html/classDateTimeOps.html b/docs/html/classDateTimeOps.html new file mode 100644 index 00000000..216c5da9 --- /dev/null +++ b/docs/html/classDateTimeOps.html @@ -0,0 +1,207 @@ + + + + + + + +LogDoctor: DateTimeOps Class Reference + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
+ +

DateTimeOps. + More...

+ +

#include <datetime.h>

+ + + + + +

+Static Public Member Functions

static const std::vector< std::string > processDateTime (const std::string &datetime, const std::string &format)
 Returns a standardized list of items representing the given date and time. More...
 
+ + + + +

+Static Private Member Functions

static const std::string convertMonth (const std::string &month)
 Converts a month from the short-name to the number. More...
 
+

Detailed Description

+

DateTimeOps.

+

Operations for the dates

+

Member Function Documentation

+ +

◆ convertMonth()

+ +
+
+ + + + + +
+ + + + + + + + +
const std::string DateTimeOps::convertMonth (const std::string & month)
+
+staticprivate
+
+ +

Converts a month from the short-name to the number.

+
Parameters
+ + +
monthThe short-name of the month
+
+
+
Returns
The month number in the calendar
+
Exceptions
+ + +
DateTimeException
+
+
+
See also
processDateTime
+ +
+
+ +

◆ processDateTime()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
const std::vector< std::string > DateTimeOps::processDateTime (const std::string & datetime,
const std::string & format 
)
+
+static
+
+ +

Returns a standardized list of items representing the given date and time.

+
Parameters
+ + + +
datetimeThe given date and time string
formatThe format of the given string
+
+
+
Exceptions
+ + +
DateTimeException
+
+
+
Returns
The list of items
+ +
+
+
The documentation for this class was generated from the following files:
    +
  • logdoctor/modules/craplog/modules/datetime.h
  • +
  • logdoctor/modules/craplog/modules/datetime.cpp
  • +
+
+ + + + diff --git a/docs/html/classDbQuery-members.html b/docs/html/classDbQuery-members.html new file mode 100644 index 00000000..8667b0f5 --- /dev/null +++ b/docs/html/classDbQuery-members.html @@ -0,0 +1,102 @@ + + + + + + + +LogDoctor: Member List + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
+
DbQuery Member List
+
+
+ +

This is the complete list of members for DbQuery, including all inherited members.

+ + + + + + + + + + + + + + + + + +
getDaytimeCounts(std::tuple< bool, std::unordered_map< int, std::unordered_map< int, int > > > &result, const QString &web_server, const QString &from_year_, const QString &from_month_, const QString &from_day_, const QString &to_year_, const QString &to_month_, const QString &to_day_, const QString &log_field_, const QString &field_filter)DbQuery
getDbField(const QString &tr_fld)DbQueryprivate
getGlobalCounts(const QString &web_server, const std::unordered_map< int, std::unordered_map< int, std::vector< int > > > &dates, std::vector< std::unordered_map< QString, int > > &recurs, std::tuple< QString, int > &traf_date, std::unordered_map< int, double > &traf_day, std::unordered_map< int, double > &traf_hour, std::vector< long long > &perf_time, std::vector< long long > &perf_sent, std::vector< long long > &perf_receiv, long &req_count)DbQuery
getItemsCount(std::tuple< bool, std::vector< std::tuple< QString, int > > > &result, const QString &web_server, const QString &year, const QString &month, const QString &day, const QString &log_field)DbQuery
getMinuteGap(const int &minute, const int &gap=10)DbQueryprivate
getMonthDays(const int &year, const int &month)DbQueryprivate
getMonthNumber(const QString &month_str)DbQueryprivate
getMonthsCount(const int &from_year, const int &from_month, const int &to_year, const int &to_month)DbQueryprivate
getRelationalCountsDay(std::tuple< bool, std::vector< std::tuple< long long, int > > > &result, const QString &web_server, const QString &year_, const QString &month_, const QString &day_, const QString &log_field_1_, const QString &field_filter_1, const QString &log_field_2_, const QString &field_filter_2)DbQuery
getRelationalCountsPeriod(std::tuple< bool, std::vector< std::tuple< long long, int > > > &result, const QString &web_server, const QString &from_year_, const QString &from_month_, const QString &from_day_, const QString &to_year_, const QString &to_month_, const QString &to_day_, const QString &log_field_1_, const QString &field_filter_1, const QString &log_field_2_, const QString &field_filter_2)DbQuery
getSpeedData(std::tuple< bool, std::vector< std::tuple< long long, std::vector< QString > > > > &result, const QString &web_server, const QString &year_, const QString &month_, const QString &day_, const QString &protocol_f, const QString &method_f, const QString &uri_f, const QString &query_f, const QString &response_f)DbQuery
getWarnCounts(std::tuple< bool, std::vector< std::vector< std::vector< std::vector< QString > > > > > &result, const QString &web_server, const QString &year_, const QString &month_, const QString &day_, const QString &hour_)DbQuery
refreshDates(std::tuple< bool, std::unordered_map< int, std::unordered_map< int, std::unordered_map< int, std::vector< int > > > > > &result)DbQuery
setDbPath(const std::string &path)DbQuery
setDialogLevel(const int &new_level)DbQuery
updateWarnings(const QString &web_server, const std::vector< std::tuple< int, int > > &updates)DbQuery
+ + + + diff --git a/docs/html/classDbQuery.html b/docs/html/classDbQuery.html new file mode 100644 index 00000000..a2e52f8c --- /dev/null +++ b/docs/html/classDbQuery.html @@ -0,0 +1,1088 @@ + + + + + + + +LogDoctor: DbQuery Class Reference + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

+void setDialogLevel (const int &new_level)
 Returns the Dialogs level.
 
void setDbPath (const std::string &path)
 Sets the path for the logs Collection database. More...
 
void refreshDates (std::tuple< bool, std::unordered_map< int, std::unordered_map< int, std::unordered_map< int, std::vector< int > > > > > &result)
 Refreshes the dates which are available in the database. More...
 
void updateWarnings (const QString &web_server, const std::vector< std::tuple< int, int > > &updates)
 Updates the database applying the changes made in the Warnings statistics table. More...
 
void getWarnCounts (std::tuple< bool, std::vector< std::vector< std::vector< std::vector< QString > > > > > &result, const QString &web_server, const QString &year_, const QString &month_, const QString &day_, const QString &hour_)
 Retrieves the data needed for the Warnings statistics. More...
 
void getSpeedData (std::tuple< bool, std::vector< std::tuple< long long, std::vector< QString > > > > &result, const QString &web_server, const QString &year_, const QString &month_, const QString &day_, const QString &protocol_f, const QString &method_f, const QString &uri_f, const QString &query_f, const QString &response_f)
 Retrieves the data needed for the Speed statistics. More...
 
void getItemsCount (std::tuple< bool, std::vector< std::tuple< QString, int > > > &result, const QString &web_server, const QString &year, const QString &month, const QString &day, const QString &log_field)
 Retrieves the data needed for the Counts statistics. More...
 
void getDaytimeCounts (std::tuple< bool, std::unordered_map< int, std::unordered_map< int, int > > > &result, const QString &web_server, const QString &from_year_, const QString &from_month_, const QString &from_day_, const QString &to_year_, const QString &to_month_, const QString &to_day_, const QString &log_field_, const QString &field_filter)
 Retrieves the data needed for the Daytime statistics. More...
 
void getRelationalCountsDay (std::tuple< bool, std::vector< std::tuple< long long, int > > > &result, const QString &web_server, const QString &year_, const QString &month_, const QString &day_, const QString &log_field_1_, const QString &field_filter_1, const QString &log_field_2_, const QString &field_filter_2)
 Retrieves the data needed for the Relationsl statistics. More...
 
void getRelationalCountsPeriod (std::tuple< bool, std::vector< std::tuple< long long, int > > > &result, const QString &web_server, const QString &from_year_, const QString &from_month_, const QString &from_day_, const QString &to_year_, const QString &to_month_, const QString &to_day_, const QString &log_field_1_, const QString &field_filter_1, const QString &log_field_2_, const QString &field_filter_2)
 Retrieves the data needed for the Relational statistics. More...
 
const bool getGlobalCounts (const QString &web_server, const std::unordered_map< int, std::unordered_map< int, std::vector< int > > > &dates, std::vector< std::unordered_map< QString, int > > &recurs, std::tuple< QString, int > &traf_date, std::unordered_map< int, double > &traf_day, std::unordered_map< int, double > &traf_hour, std::vector< long long > &perf_time, std::vector< long long > &perf_sent, std::vector< long long > &perf_receiv, long &req_count)
 Retrieves the data needed for the Global statistics. More...
 
+ + + + + + + + + + + + + + + + +

+Private Member Functions

const QString getDbField (const QString &tr_fld)
 Returns the database field corresponding to the relative log field. More...
 
const int getMinuteGap (const int &minute, const int &gap=10)
 Returns the minute gap for the given minute with the given gap. More...
 
const int getMonthDays (const int &year, const int &month)
 Returns the number of days for a given month. More...
 
const int getMonthNumber (const QString &month_str)
 Returns the month number in the year. More...
 
const int getMonthsCount (const int &from_year, const int &from_month, const int &to_year, const int &to_month)
 Returns the number of months in a given period. More...
 
+

Member Function Documentation

+ +

◆ getDaytimeCounts()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void DbQuery::getDaytimeCounts (std::tuple< bool, std::unordered_map< int, std::unordered_map< int, int > > > & result,
const QString & web_server,
const QString & from_year_,
const QString & from_month_,
const QString & from_day_,
const QString & to_year_,
const QString & to_month_,
const QString & to_day_,
const QString & log_field_,
const QString & field_filter 
)
+
+ +

Retrieves the data needed for the Daytime statistics.

+
Parameters
+ + + + + + + + + + + +
resultTuple which will hold the result of the operation and the data
web_serverThe ID of the Web Server to use
from_year_The initial year
from_month_The initial month
from_day_The initial day
to_year_The final year
to_month_The final month
to_day_The final day
log_field_The log field to filter
field_filterThe filter to apply
+
+
+ +
+
+ +

◆ getDbField()

+ +
+
+ + + + + +
+ + + + + + + + +
const QString DbQuery::getDbField (const QString & tr_fld)
+
+private
+
+ +

Returns the database field corresponding to the relative log field.

+
Parameters
+ + +
tr_fldThe log field, hendles translated text
+
+
+
Returns
The database field
+ +
+
+ +

◆ getGlobalCounts()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
const bool DbQuery::getGlobalCounts (const QString & web_server,
const std::unordered_map< int, std::unordered_map< int, std::vector< int > > > & dates,
std::vector< std::unordered_map< QString, int > > & recurs,
std::tuple< QString, int > & traf_date,
std::unordered_map< int, double > & traf_day,
std::unordered_map< int, double > & traf_hour,
std::vector< long long > & perf_time,
std::vector< long long > & perf_sent,
std::vector< long long > & perf_receiv,
long & req_count 
)
+
+ +

Retrieves the data needed for the Global statistics.

+
Parameters
+ + + + + + + + + + + +
web_serverThe ID of the Web Server to use
datesThe dates to query
recursWill hold the recurrencies of the items
traf_dateWill hold the most trafficked date and the count
traf_dayWill hold the most trafficked day of the week and the count
traf_hourWill hold the most trafficked hour of the day and the count
perf_timeWill hold the overallo time taken
perf_sentWill hold the overall Bytes sent
perf_receivWill hold the overall Bytes received
req_countWill hold the number of requests examined by the query
+
+
+
Returns
Whether the operation has been successful or not
+ +
+
+ +

◆ getItemsCount()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void DbQuery::getItemsCount (std::tuple< bool, std::vector< std::tuple< QString, int > > > & result,
const QString & web_server,
const QString & year,
const QString & month,
const QString & day,
const QString & log_field 
)
+
+ +

Retrieves the data needed for the Counts statistics.

+
Parameters
+ + + + + + + +
resultTuple which will hold the result of the operation and the data
web_serverThe ID of the Web Server to use
yearThe year
monthThe month
dayThe day
log_fieldThe log field
+
+
+ +
+
+ +

◆ getMinuteGap()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
const int DbQuery::getMinuteGap (const int & minute,
const int & gap = 10 
)
+
+private
+
+ +

Returns the minute gap for the given minute with the given gap.

+
Parameters
+ + + +
minuteThe minute of the hour
gapThe gap used to split the hour
+
+
+
Returns
The gap index
+
Exceptions
+ + +
DateTimeException
+
+
+ +
+
+ +

◆ getMonthDays()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
const int DbQuery::getMonthDays (const int & year,
const int & month 
)
+
+private
+
+ +

Returns the number of days for a given month.

+
Parameters
+ + + +
yearThe year, used to handle leap years
monthThe month
+
+
+
Returns
The number of days
+
Exceptions
+ + +
DateTimeException
+
+
+ +
+
+ +

◆ getMonthNumber()

+ +
+
+ + + + + +
+ + + + + + + + +
const int DbQuery::getMonthNumber (const QString & month_str)
+
+private
+
+ +

Returns the month number in the year.

+
Parameters
+ + +
month_strThe month
+
+
+
Returns
The month number
+ +
+
+ +

◆ getMonthsCount()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
const int DbQuery::getMonthsCount (const int & from_year,
const int & from_month,
const int & to_year,
const int & to_month 
)
+
+private
+
+ +

Returns the number of months in a given period.

+
Parameters
+ + + + + +
from_yearThe initial year
from_monthThe initial month
to_yearThe final Year
to_monthThe final month
+
+
+
Returns
The number of months in the period
+

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

+
Parameters
+ + + + + +
from_yearThe initial year
from_monthThe initial month
to_yearThe final Year
to_monthThe final month
+
+
+
Returns
The number of months in the period
+
Exceptions
+ + +
DateTimeException
+
+
+ +
+
+ +

◆ getRelationalCountsDay()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void DbQuery::getRelationalCountsDay (std::tuple< bool, std::vector< std::tuple< long long, int > > > & result,
const QString & web_server,
const QString & year_,
const QString & month_,
const QString & day_,
const QString & log_field_1_,
const QString & field_filter_1,
const QString & log_field_2_,
const QString & field_filter_2 
)
+
+ +

Retrieves the data needed for the Relationsl statistics.

+

Used when querying a single day

Parameters
+ + + + + + + + + + +
resultTuple which will hold the result of the operation and the data
web_serverThe ID of the Web Server to use
year_The year
month_The month
day_The day
log_field_1_The first log field to filter
field_filter_1The filter to apply to the first field
log_field_2_The second log field to filter
field_filter_2The filter to apply to the second fiend
+
+
+
See also
getRelationalCountsPeriod()
+ +
+
+ +

◆ getRelationalCountsPeriod()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void DbQuery::getRelationalCountsPeriod (std::tuple< bool, std::vector< std::tuple< long long, int > > > & result,
const QString & web_server,
const QString & from_year_,
const QString & from_month_,
const QString & from_day_,
const QString & to_year_,
const QString & to_month_,
const QString & to_day_,
const QString & log_field_1_,
const QString & field_filter_1,
const QString & log_field_2_,
const QString & field_filter_2 
)
+
+ +

Retrieves the data needed for the Relational statistics.

+

Used when querying a period of time

Parameters
+ + + + + + + + + + + + + +
resultTuple which will hold the result of the operation and the data
web_serverThe ID of the Web Server to use
from_year_The initial year
from_month_The initial month
from_day_The initial day
to_year_The final year
to_month_The final month
to_day_The final day
log_field_1_The first log field to filter
field_filter_1The filter to apply to the first field
log_field_2_The second log field to filter
field_filter_2The filter to apply to the second fiend
+
+
+
See also
getRelationalCountsDay()
+ +
+
+ +

◆ getSpeedData()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void DbQuery::getSpeedData (std::tuple< bool, std::vector< std::tuple< long long, std::vector< QString > > > > & result,
const QString & web_server,
const QString & year_,
const QString & month_,
const QString & day_,
const QString & protocol_f,
const QString & method_f,
const QString & uri_f,
const QString & query_f,
const QString & response_f 
)
+
+ +

Retrieves the data needed for the Speed statistics.

+
Parameters
+ + + + + + + + + + + +
resultTuple which will hold the result of the operation and the data
web_serverThe ID of the Web Server to use
year_The year
month_The month
day_The day
protocol_fThe filter for the Protocol field
method_fThe filter for the Method field
uri_fThe filter for the URI field
query_fThe filter for the Query field
response_fThe filter for the Response field
+
+
+ +
+
+ +

◆ getWarnCounts()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void DbQuery::getWarnCounts (std::tuple< bool, std::vector< std::vector< std::vector< std::vector< QString > > > > > & result,
const QString & web_server,
const QString & year_,
const QString & month_,
const QString & day_,
const QString & hour_ 
)
+
+ +

Retrieves the data needed for the Warnings statistics.

+
Parameters
+ + + + + + + +
resultTuple which will hold the result of the operation and the data
web_serverThe ID of the Web Server to use
year_The year
month_The month
day_The day
hour_The hour
+
+
+ +
+
+ +

◆ refreshDates()

+ +
+
+ + + + + + + + +
void DbQuery::refreshDates (std::tuple< bool, std::unordered_map< int, std::unordered_map< int, std::unordered_map< int, std::vector< int > > > > > & result)
+
+ +

Refreshes the dates which are available in the database.

+
Parameters
+ + +
resultTuple which will hold the result of the operation and the data
+
+
+ +
+
+ +

◆ setDbPath()

+ +
+
+ + + + + + + + +
void DbQuery::setDbPath (const std::string & path)
+
+ +

Sets the path for the logs Collection database.

+
See also
Crapview::setDbPath()
+ +
+
+ +

◆ updateWarnings()

+ +
+
+ + + + + + + + + + + + + + + + + + +
void DbQuery::updateWarnings (const QString & web_server,
const std::vector< std::tuple< int, int > > & updates 
)
+
+ +

Updates the database applying the changes made in the Warnings statistics table.

+
Parameters
+ + + +
web_serverThe ID of the Web Server to use
updatesThe list of rowids to update and the corresponding warning values
+
+
+ +
+
+
The documentation for this class was generated from the following files:
    +
  • logdoctor/modules/crapview/modules/query.h
  • +
  • logdoctor/modules/crapview/modules/query.cpp
  • +
+
+ + + + diff --git a/docs/html/classDialogBool-members.html b/docs/html/classDialogBool-members.html new file mode 100644 index 00000000..a1d034e9 --- /dev/null +++ b/docs/html/classDialogBool-members.html @@ -0,0 +1,89 @@ + + + + + + + +LogDoctor: Member List + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
+
DialogBool Member List
+
+
+ +

This is the complete list of members for DialogBool, including all inherited members.

+ + + + +
DialogBool(const QString &title, const QString &text, QWidget *parent=nullptr)DialogBool
on_button_NO_clicked()DialogBoolprivateslot
on_button_YES_clicked()DialogBoolprivateslot
+ + + + diff --git a/docs/html/classDialogBool.html b/docs/html/classDialogBool.html new file mode 100644 index 00000000..07d4675a --- /dev/null +++ b/docs/html/classDialogBool.html @@ -0,0 +1,168 @@ + + + + + + + +LogDoctor: DialogBool Class Reference + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
+ +
DialogBool Class Reference
+
+
+ +

DialogBool. + More...

+ +

#include <dialogbool.h>

+
+Inheritance diagram for DialogBool:
+
+
+ +
+ + + + + +

+Public Member Functions

 DialogBool (const QString &title, const QString &text, QWidget *parent=nullptr)
 Dialog constructor. More...
 
+ + + + + + + +

+Private Slots

+void on_button_NO_clicked ()
 Called when the NO button gets clicked.
 
+void on_button_YES_clicked ()
 Called when the YES button gets clicked.
 
+

Detailed Description

+

DialogBool.

+

YES/NO choice dialog

+

Constructor & Destructor Documentation

+ +

◆ DialogBool()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
DialogBool::DialogBool (const QString & title,
const QString & text,
QWidget * parent = nullptr 
)
+
+ +

Dialog constructor.

+
Parameters
+ + + + +
titleThe title
textThe message
parentThe parent Widget
+
+
+ +
+
+
The documentation for this class was generated from the following files:
    +
  • logdoctor/modules/dialogs/dialogbool.h
  • +
  • logdoctor/modules/dialogs/dialogbool.cpp
  • +
+
+ + + + diff --git a/docs/html/classDialogBool.png b/docs/html/classDialogBool.png new file mode 100644 index 00000000..b5e94b2c Binary files /dev/null and b/docs/html/classDialogBool.png differ diff --git a/docs/html/classDialogDia-members.html b/docs/html/classDialogDia-members.html new file mode 100644 index 00000000..5c4a8596 --- /dev/null +++ b/docs/html/classDialogDia-members.html @@ -0,0 +1,90 @@ + + + + + + + +LogDoctor: Member List + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
+
DialogDia Member List
+
+
+ +

This is the complete list of members for DialogDia, including all inherited members.

+ + + + + +
DialogDia(const QString &title, const QString &text, const bool &ignore=true, const bool &discard=true, const bool &abort=true, QWidget *parent=nullptr)DialogDia
on_button_ABORT_clicked()DialogDiaprivateslot
on_button_DISCARD_clicked()DialogDiaprivateslot
on_button_IGNORE_clicked()DialogDiaprivateslot
+ + + + diff --git a/docs/html/classDialogDia.html b/docs/html/classDialogDia.html new file mode 100644 index 00000000..217dfa15 --- /dev/null +++ b/docs/html/classDialogDia.html @@ -0,0 +1,193 @@ + + + + + + + +LogDoctor: DialogDia Class Reference + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
+ +
DialogDia Class Reference
+
+
+ +

DialogDia. + More...

+ +

#include <dialogdia.h>

+
+Inheritance diagram for DialogDia:
+
+
+ +
+ + + + + +

+Public Member Functions

 DialogDia (const QString &title, const QString &text, const bool &ignore=true, const bool &discard=true, const bool &abort=true, QWidget *parent=nullptr)
 Dialog constructor. More...
 
+ + + + + + + + + + +

+Private Slots

+void on_button_IGNORE_clicked ()
 Called when the IGNORE button gets clicked.
 
+void on_button_DISCARD_clicked ()
 Called when the DISCARD button gets clicked.
 
+void on_button_ABORT_clicked ()
 Called when the ABORT button gets clicked.
 
+

Detailed Description

+

DialogDia.

+

DISCARD/IGNORE/ABORT choice dialog

+

Constructor & Destructor Documentation

+ +

◆ DialogDia()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DialogDia::DialogDia (const QString & title,
const QString & text,
const bool & ignore = true,
const bool & discard = true,
const bool & abort = true,
QWidget * parent = nullptr 
)
+
+ +

Dialog constructor.

+
Parameters
+ + + + + + + +
titleThe title
textThe message
ignoreWhether to show the IGNORE button or not
discardWhether to show the DISCARD button or not
abortWhether to show the ABORT button or not
parentThe parent Widget
+
+
+ +
+
+
The documentation for this class was generated from the following files:
    +
  • logdoctor/modules/dialogs/dialogdia.h
  • +
  • logdoctor/modules/dialogs/dialogdia.cpp
  • +
+
+ + + + diff --git a/docs/html/classDialogDia.png b/docs/html/classDialogDia.png new file mode 100644 index 00000000..9c8d6029 Binary files /dev/null and b/docs/html/classDialogDia.png differ diff --git a/docs/html/classDialogMsg-members.html b/docs/html/classDialogMsg-members.html new file mode 100644 index 00000000..69be2f33 --- /dev/null +++ b/docs/html/classDialogMsg-members.html @@ -0,0 +1,89 @@ + + + + + + + +LogDoctor: Member List + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
+
DialogMsg Member List
+
+
+ +

This is the complete list of members for DialogMsg, including all inherited members.

+ + + + +
DialogMsg(const QString &title, const QString &text, const QString &additional, const int &type, QWidget *parent=nullptr)DialogMsg
on_button_Ok_clicked()DialogMsgprivateslot
on_button_ShowAdditional_clicked()DialogMsgprivateslot
+ + + + diff --git a/docs/html/classDialogMsg.html b/docs/html/classDialogMsg.html new file mode 100644 index 00000000..b944cc6e --- /dev/null +++ b/docs/html/classDialogMsg.html @@ -0,0 +1,181 @@ + + + + + + + +LogDoctor: DialogMsg Class Reference + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
+ +
DialogMsg Class Reference
+
+
+ +

DialogMsg. + More...

+ +

#include <dialogmsg.h>

+
+Inheritance diagram for DialogMsg:
+
+
+ +
+ + + + + +

+Public Member Functions

 DialogMsg (const QString &title, const QString &text, const QString &additional, const int &type, QWidget *parent=nullptr)
 Dialog constructor. More...
 
+ + + + + + + +

+Private Slots

+void on_button_ShowAdditional_clicked ()
 Shows the additional informations.
 
+void on_button_Ok_clicked ()
 Called when the OK button gets clicked.
 
+

Detailed Description

+

DialogMsg.

+

A dialog message to provide informations to the user

+

Constructor & Destructor Documentation

+ +

◆ DialogMsg()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DialogMsg::DialogMsg (const QString & title,
const QString & text,
const QString & additional,
const int & type,
QWidget * parent = nullptr 
)
+
+ +

Dialog constructor.

+
Parameters
+ + + + + +
titleThe title
textThe message
additionalAdditional informations, usually an error message
parentThe parent Widget
+
+
+ +
+
+
The documentation for this class was generated from the following files:
    +
  • logdoctor/modules/dialogs/dialogmsg.h
  • +
  • logdoctor/modules/dialogs/dialogmsg.cpp
  • +
+
+ + + + diff --git a/docs/html/classDialogMsg.png b/docs/html/classDialogMsg.png new file mode 100644 index 00000000..535c68d5 Binary files /dev/null and b/docs/html/classDialogMsg.png differ diff --git a/docs/html/classDialogSec-members.html b/docs/html/classDialogSec-members.html new file mode 100644 index 00000000..ed464312 --- /dev/null +++ b/docs/html/classDialogSec-members.html @@ -0,0 +1,138 @@ + + + + + + + +LogDoctor: Member List + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
+
DialogSec Member List
+
+
+ +

This is the complete list of members for DialogSec, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
choiceDatabaseMissingColumn(const QString &db_name, const QString &table_name, const QString &column_name, QWidget *parent=nullptr)DialogSecstatic
choiceDatabaseMissingTable(const QString &db_name, const QString &table_name, QWidget *parent=nullptr)DialogSecstatic
choiceDatabaseNotFound(const QString &db_name, QWidget *parent=nullptr)DialogSecstatic
choiceDatabaseRenew(const QString &title, const QString &msg, QWidget *parent=nullptr)DialogSecprivatestatic
choiceDatabaseWrongColumn(const QString &db_name, const QString &table_name, const QString &column_name, QWidget *parent=nullptr)DialogSecstatic
choiceDatabaseWrongDataType(const QString &db_name, const QString &table_name, const QString &column_name, const QString &data_type, QWidget *parent=nullptr)DialogSecstatic
choiceDatabaseWrongTable(const QString &db_name, const QString &table_name, QWidget *parent=nullptr)DialogSecstatic
choiceDirNotDir(const QString &path, QWidget *parent=nullptr)DialogSecstatic
choiceFileAlreadyUsed(const QString &msg, QWidget *parent=nullptr)DialogSecstatic
choiceFileNotFile(const QString &path, QWidget *parent=nullptr)DialogSecstatic
choiceFileSizeWarning(const QString &msg, QWidget *parent=nullptr)DialogSecstatic
choiceFileSizeWarning2(const QString &msg, QWidget *parent=nullptr)DialogSecstatic
choiceSelectedFileNotFound(const QString &file, QWidget *parent=nullptr)DialogSecstatic
errConfDirNotWritable(const QString &dir, const QString &err, QWidget *parent=nullptr)DialogSecstatic
errConfFailedWriting(const QString &msg, const QString &err, QWidget *parent=nullptr)DialogSecstatic
errConfFileNotReadable(const QString &file, const QString &err, QWidget *parent=nullptr)DialogSecstatic
errConfFileNotWritable(const QString &file, const QString &err, QWidget *parent=nullptr)DialogSecstatic
errDatabaseFailedBackup(const QString &msg, const QString &err, QWidget *parent=nullptr)DialogSecstatic
errDatabaseFailedCreating(const QString &db_name, QWidget *parent=nullptr)DialogSecstatic
errDatabaseFailedExecuting(const QString &db_name, const QString &statement, const QString &err, QWidget *parent=nullptr)DialogSecstatic
errDatabaseFailedOpening(const QString &db_name, const QString &err, QWidget *parent=nullptr)DialogSecstatic
errDatabaseNotFile(const QString &db_name, QWidget *parent=nullptr)DialogSecstatic
errDatabaseNotReadable(const QString &db_name, QWidget *parent=nullptr)DialogSecstatic
errDatabaseNotWritable(const QString &db_name, QWidget *parent=nullptr)DialogSecstatic
errDirNotExists(const QString &dir, QWidget *parent=nullptr)DialogSecstatic
errDirNotReadable(const QString &dir, const QString &err, QWidget *parent=nullptr)DialogSecstatic
errDirNotWritable(const QString &dir, const QString &err, QWidget *parent=nullptr)DialogSecstatic
errFailedApplyingConfigs(const QString &msg, QWidget *parent=nullptr)DialogSecstatic
errFailedDefiningLogType(const QString &file, QWidget *parent=nullptr)DialogSecstatic
errFailedMakeDir(const QString &msg, const QString &err, QWidget *parent=nullptr)DialogSecstatic
errFailedParsingLogs(const QString &message, QWidget *parent=nullptr)DialogSecstatic
errFailedReadFile(const QString &file, const bool &skipping=false, QWidget *parent=nullptr)DialogSecstatic
errFileNotFound(const QString &file, const bool &report=false, QWidget *parent=nullptr)DialogSecstatic
errGeneric(const QString &message, const bool &report_msg=false, QWidget *parent=nullptr)DialogSecstatic
errHelpFailed(const QString &link, const QString &msg, QWidget *parent=nullptr)DialogSecstatic
errHelpNotFound(const QString &link, QWidget *parent=nullptr)DialogSecstatic
errHelpNotReadable(const QString &link, QWidget *parent=nullptr)DialogSecstatic
errInvalidLogFormatString(const QString &msg, QWidget *parent=nullptr)DialogSecstatic
errLangLocaleInvalid(const QString &locale, QWidget *parent=nullptr)DialogSecstatic
errLangNotAccepted(const QString &locale, QWidget *parent=nullptr)DialogSecstatic
errLogFormatNoFields(QWidget *parent=nullptr)DialogSecstatic
errLogFormatNoSeparators(QWidget *parent=nullptr)DialogSecstatic
errLogFormatNotSet(QWidget *parent=nullptr)DialogSecstatic
errRenaming(const QString &path, const QString &err, QWidget *parent=nullptr)DialogSecstatic
errSqlDriverNotFound(const QString &driver, QWidget *parent=nullptr)DialogSecstatic
msgDatabaseCreated(const QString &db_name, QWidget *parent=nullptr)DialogSecstatic
warnConfFileNotFound(const QString &file, QWidget *parent=nullptr)DialogSecstatic
warnDirNotReadable(QWidget *parent=nullptr)DialogSecstatic
warnDirNotWritable(QWidget *parent=nullptr)DialogSecstatic
warnEmptyFile(const QString &file, QWidget *parent=nullptr)DialogSecstatic
warnFileNotReadable(const QString &file, QWidget *parent=nullptr)DialogSecstatic
warnInvalidItemBW(QWidget *parent=nullptr)DialogSecstatic
+ + + + diff --git a/docs/html/classDialogSec.html b/docs/html/classDialogSec.html new file mode 100644 index 00000000..bf8efdd3 --- /dev/null +++ b/docs/html/classDialogSec.html @@ -0,0 +1,320 @@ + + + + + + + +LogDoctor: DialogSec Class Reference + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
+ +

DialogSec. + More...

+ +

#include <dialogs.h>

+
+Inheritance diagram for DialogSec:
+
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Static Public Member Functions

+static void errGeneric (const QString &message, const bool &report_msg=false, QWidget *parent=nullptr)
 Generic error message.
 
+static void errRenaming (const QString &path, const QString &err, QWidget *parent=nullptr)
 Error while renaming.
 
+static void errLangLocaleInvalid (const QString &locale, QWidget *parent=nullptr)
 Invalid locale found.
 
+static void errLangNotAccepted (const QString &locale, QWidget *parent=nullptr)
 Language not supported.
 
+static void errConfFailedWriting (const QString &msg, const QString &err, QWidget *parent=nullptr)
 Failed to write the configurations on file.
 
+static void warnConfFileNotFound (const QString &file, QWidget *parent=nullptr)
 Configuration file not found.
 
+static void errConfFileNotReadable (const QString &file, const QString &err, QWidget *parent=nullptr)
 Missing read permission for the configuration file.
 
+static void errConfFileNotWritable (const QString &file, const QString &err, QWidget *parent=nullptr)
 Missing write permission for the configuration file.
 
+static void errConfDirNotWritable (const QString &dir, const QString &err, QWidget *parent=nullptr)
 Missing read permission for the configuration file's directory.
 
+static void errFailedApplyingConfigs (const QString &msg, QWidget *parent=nullptr)
 Missing write permission for the configuration file's directory.
 
+static void errHelpFailed (const QString &link, const QString &msg, QWidget *parent=nullptr)
 Help resource is not a file.
 
+static void errHelpNotFound (const QString &link, QWidget *parent=nullptr)
 Help file not found.
 
+static void errHelpNotReadable (const QString &link, QWidget *parent=nullptr)
 Missing read permission for the help file.
 
+static void errSqlDriverNotFound (const QString &driver, QWidget *parent=nullptr)
 SQLite driver not installed or not found.
 
+static const bool choiceDatabaseNotFound (const QString &db_name, QWidget *parent=nullptr)
 Database file not found.
 
+static const bool choiceDatabaseWrongTable (const QString &db_name, const QString &table_name, QWidget *parent=nullptr)
 A database contains an unexpected table.
 
+static const bool choiceDatabaseMissingTable (const QString &db_name, const QString &table_name, QWidget *parent=nullptr)
 A table is missing from the database.
 
+static const bool choiceDatabaseWrongColumn (const QString &db_name, const QString &table_name, const QString &column_name, QWidget *parent=nullptr)
 A database contains a table with an unexpected column.
 
+static const bool choiceDatabaseMissingColumn (const QString &db_name, const QString &table_name, const QString &column_name, QWidget *parent=nullptr)
 A column is missing from table of the database.
 
+static const bool choiceDatabaseWrongDataType (const QString &db_name, const QString &table_name, const QString &column_name, const QString &data_type, QWidget *parent=nullptr)
 A column has an unexpected type parameter.
 
+static void errDatabaseNotFile (const QString &db_name, QWidget *parent=nullptr)
 The entry corresponding to the database path is not a file.
 
+static void errDatabaseNotReadable (const QString &db_name, QWidget *parent=nullptr)
 Missing read permission for a database.
 
+static void errDatabaseNotWritable (const QString &db_name, QWidget *parent=nullptr)
 Missing write permission for a database.
 
+static void msgDatabaseCreated (const QString &db_name, QWidget *parent=nullptr)
 Successfully created a new database.
 
+static void errDatabaseFailedCreating (const QString &db_name, QWidget *parent=nullptr)
 Failed to create a new database.
 
+static void errDatabaseFailedOpening (const QString &db_name, const QString &err, QWidget *parent=nullptr)
 Failed to open a database.
 
+static void errDatabaseFailedExecuting (const QString &db_name, const QString &statement, const QString &err, QWidget *parent=nullptr)
 Failed to execute a statement on a database.
 
+static void errDatabaseFailedBackup (const QString &msg, const QString &err, QWidget *parent=nullptr)
 Failed to backup a database.
 
+static const int choiceSelectedFileNotFound (const QString &file, QWidget *parent=nullptr)
 A log file which has been selected to be used is no more available.
 
+static void warnInvalidItemBW (QWidget *parent=nullptr)
 An item can't be added to a warnlist/blacklist.
 
+static void errFailedDefiningLogType (const QString &file, QWidget *parent=nullptr)
 The log type can't be defined for a file.
 
+static const int choiceFileAlreadyUsed (const QString &msg, QWidget *parent=nullptr)
 A log file has already been used.
 
+static const int choiceFileSizeWarning (const QString &msg, QWidget *parent=nullptr)
 A log file exceeds the warning size.
 
+static const bool choiceFileSizeWarning2 (const QString &msg, QWidget *parent=nullptr)
 A log file exceeds the warning size.
 
+static void errInvalidLogFormatString (const QString &msg, QWidget *parent=nullptr)
 Failed to process a logs format string.
 
+static void errLogFormatNotSet (QWidget *parent=nullptr)
 The logs format has not been set for the web server in use.
 
+static void errLogFormatNoFields (QWidget *parent=nullptr)
 The log format in use has no log fields.
 
+static void errLogFormatNoSeparators (QWidget *parent=nullptr)
 The log format in use has no log separators.
 
+static void errFailedParsingLogs (const QString &message, QWidget *parent=nullptr)
 An error occured while parsing logs.
 
+static void errFileNotFound (const QString &file, const bool &report=false, QWidget *parent=nullptr)
 File not found.
 
+static void warnFileNotReadable (const QString &file, QWidget *parent=nullptr)
 Missing read permission for a file.
 
+static void warnEmptyFile (const QString &file, QWidget *parent=nullptr)
 A file is empty.
 
+static void errFailedReadFile (const QString &file, const bool &skipping=false, QWidget *parent=nullptr)
 An error occured while reading a file.
 
+static void errDirNotExists (const QString &dir, QWidget *parent=nullptr)
 A directory does not extst.
 
+static void errDirNotReadable (const QString &dir, const QString &err, QWidget *parent=nullptr)
 Missing read permission for a directory.
 
+static void errDirNotWritable (const QString &dir, const QString &err, QWidget *parent=nullptr)
 Missing write permission for a directory.
 
+static void warnDirNotReadable (QWidget *parent=nullptr)
 Missing read permission for a directory.
 
+static void warnDirNotWritable (QWidget *parent=nullptr)
 Missing write permission for a directory.
 
+static void errFailedMakeDir (const QString &msg, const QString &err, QWidget *parent=nullptr)
 Failed to create a directory.
 
+static const bool choiceDirNotDir (const QString &path, QWidget *parent=nullptr)
 An entry was supposed to be a directory but it's not.
 
+static const bool choiceFileNotFile (const QString &path, QWidget *parent=nullptr)
 An entry was supposed to be a file but it's not.
 
+ + + + +

+Static Private Member Functions

+static const bool choiceDatabaseRenew (const QString &title, const QString &msg, QWidget *parent=nullptr)
 Asks to renew a database.
 
+

Detailed Description

+

DialogSec.

+

Implements various dialog models

See also
DialogMsg, DialogBool, DialogDia
+

The documentation for this class was generated from the following files:
    +
  • logdoctor/modules/dialogs.h
  • +
  • logdoctor/modules/dialogs.cpp
  • +
+
+ + + + diff --git a/docs/html/classDialogSec.png b/docs/html/classDialogSec.png new file mode 100644 index 00000000..5aa0a78c Binary files /dev/null and b/docs/html/classDialogSec.png differ diff --git a/docs/html/classDonutBreakdown-members.html b/docs/html/classDonutBreakdown-members.html new file mode 100644 index 00000000..0e2f03ba --- /dev/null +++ b/docs/html/classDonutBreakdown-members.html @@ -0,0 +1,89 @@ + + + + + + + +LogDoctor: Member List + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
+
DonutBreakdown Member List
+
+
+ +

This is the complete list of members for DonutBreakdown, including all inherited members.

+ + + + +
addBreakdownSeries(QPieSeries *series, const QColor &color, const QFont &font)DonutBreakdown
recalculateAngles()DonutBreakdownprivate
updateLegendMarkers()DonutBreakdownprivate
+ + + + diff --git a/docs/html/classDonutBreakdown.html b/docs/html/classDonutBreakdown.html new file mode 100644 index 00000000..12f9e5c5 --- /dev/null +++ b/docs/html/classDonutBreakdown.html @@ -0,0 +1,169 @@ + + + + + + + +LogDoctor: DonutBreakdown Class Reference + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
+ +
DonutBreakdown Class Reference
+
+
+ +

DonutBreakdon. + More...

+ +

#include <donuts.h>

+
+Inheritance diagram for DonutBreakdown:
+
+
+ +
+ + + + + +

+Public Member Functions

void addBreakdownSeries (QPieSeries *series, const QColor &color, const QFont &font)
 Adds a slice to the donut. More...
 
+ + + + + + + +

+Private Member Functions

+void recalculateAngles ()
 Recalculates the size of every slice in percentage over the total.
 
+void updateLegendMarkers ()
 Updates the position of the markers to be in the middle of the relative slice.
 
+

Detailed Description

+

DonutBreakdon.

+

Builds the donut chart to be displayed

+

Member Function Documentation

+ +

◆ addBreakdownSeries()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void DonutBreakdown::addBreakdownSeries (QPieSeries * series,
const QColor & color,
const QFont & font 
)
+
+ +

Adds a slice to the donut.

+
Parameters
+ + + + +
seriesThe series to add
colorThe color of the slice
fontThe font to be used
+
+
+
See also
Craplog::makeChart()
+ +
+
+
The documentation for this class was generated from the following files:
    +
  • logdoctor/modules/craplog/modules/donuts.h
  • +
  • logdoctor/modules/craplog/modules/donuts.cpp
  • +
+
+ + + + diff --git a/docs/html/classDonutBreakdown.png b/docs/html/classDonutBreakdown.png new file mode 100644 index 00000000..262e63bf Binary files /dev/null and b/docs/html/classDonutBreakdown.png differ diff --git a/docs/html/classFood-members.html b/docs/html/classFood-members.html new file mode 100644 index 00000000..fd44f97b --- /dev/null +++ b/docs/html/classFood-members.html @@ -0,0 +1,96 @@ + + + + + + + +LogDoctor: Member List + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
+
Food Member List
+
+
+ +

This is the complete list of members for Food, including all inherited members.

+ + + + + + + + + + + +
img_ratFoodprivate
inTile(const unsigned int &x, const unsigned int &y)Food
movableFoodprivate
move(Snake &snake)Food
spawn(Snake &snake, Snake &snake_)Food
update(const unsigned int &new_x, const unsigned int &new_y)Food
xFoodprivate
X()Food
yFoodprivate
Y()Food
+ + + + diff --git a/docs/html/classFood.html b/docs/html/classFood.html new file mode 100644 index 00000000..5c8e7018 --- /dev/null +++ b/docs/html/classFood.html @@ -0,0 +1,158 @@ + + + + + + + +LogDoctor: Food Class Reference + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

+const unsigned int & X ()
 Returns the position on the X-axis.
 
const unsigned int & Y ()
 Returns the position on the Y-axis. More...
 
+const bool inTile (const unsigned int &x, const unsigned int &y)
 Checks whether is there a part of the snake in the given position.
 
+void spawn (Snake &snake, Snake &snake_)
 Spawns the egg/rat in a new position.
 
+void move (Snake &snake)
 Moves the rat.
 
+void update (const unsigned int &new_x, const unsigned int &new_y)
 Updates the position and direction of the entity.
 
+ + + + + + + + + + + + + +

+Private Attributes

+QPixmap img_rat = QPixmap(":/games/games/snake/rat.png")
 Whether the food is a rat or an egg.
 
+bool movable
 The position on the X-axis.
 
+unsigned int x
 The position on the Y-axis.
 
+unsigned int y
 The image which graphically represents the food.
 
+

Member Function Documentation

+ +

◆ Y()

+ +
+
+ + + + + + + +
const unsigned int & Food::Y ()
+
+ +

Returns the position on the Y-axis.

+

Returns the image

+ +
+
+
The documentation for this class was generated from the following files:
    +
  • logdoctor/games/snake/food.h
  • +
  • logdoctor/games/snake/food.cpp
  • +
+
+ + + + diff --git a/docs/html/classFormatOps-members.html b/docs/html/classFormatOps-members.html new file mode 100644 index 00000000..d018f832 --- /dev/null +++ b/docs/html/classFormatOps-members.html @@ -0,0 +1,100 @@ + + + + + + + +LogDoctor: Member List + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
+
FormatOps Member List
+
+
+ +

This is the complete list of members for FormatOps, including all inherited members.

+ + + + + + + + + + + + + + + +
APACHE_ALFFormatOpsprivate
checkIisString(const std::string &string)FormatOpsprivate
countNewLines(const std::string &initial, const std::string &final, const std::vector< std::string > &separators)FormatOpsprivate
findNginxFieldEnd(const std::string &string, const int &start)FormatOpsprivate
getApacheLogSample(const LogsFormat &log_format)FormatOps
getIisLogSample(const LogsFormat &log_format)FormatOps
getNginxLogSample(const LogsFormat &log_format)FormatOps
IIS_ALFFormatOpsprivate
NGINX_ALFFormatOpsprivate
parseApacheEscapes(const std::string &string, const bool &strftime=false)FormatOpsprivate
parseNginxEscapes(const std::string &string)FormatOpsprivate
processApacheFormatString(const std::string &format_string)FormatOps
processIisFormatString(const std::string &format_string, const int &log_module)FormatOps
processNginxFormatString(const std::string &format_string)FormatOps
+ + + + diff --git a/docs/html/classFormatOps.html b/docs/html/classFormatOps.html new file mode 100644 index 00000000..d66f477c --- /dev/null +++ b/docs/html/classFormatOps.html @@ -0,0 +1,622 @@ + + + + + + + +LogDoctor: FormatOps Class Reference + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
+ +

FormatOps. + More...

+ +

#include <formats.h>

+ + + + + +

+Classes

struct  LogsFormat
 Structure which holds informations about a log format. More...
 
+ + + + + + + + + + + + + + + + + + + +

+Public Member Functions

const LogsFormat processApacheFormatString (const std::string &format_string)
 Processes the given string to extrapolate the format for Apache2. More...
 
const LogsFormat processNginxFormatString (const std::string &format_string)
 Processes the given string to extrapolate the format for Nginx. More...
 
const LogsFormat processIisFormatString (const std::string &format_string, const int &log_module)
 Processes the given string to extrapolate the format for the IIS. More...
 
const QString getApacheLogSample (const LogsFormat &log_format)
 Returns a log line sample based on the given format. More...
 
const QString getNginxLogSample (const LogsFormat &log_format)
 Returns a log line sample based on the given format. More...
 
const QString getIisLogSample (const LogsFormat &log_format)
 Returns a log line sample based on the given format. More...
 
+ + + + + + + + + + + + + + + + +

+Private Member Functions

const std::string parseApacheEscapes (const std::string &string, const bool &strftime=false)
 Parses the escapes (backslashes) and returns the resulting string. More...
 
const std::string parseNginxEscapes (const std::string &string)
 Parses the escapes (backslashes) and returns the resulting string. More...
 
const int countNewLines (const std::string &initial, const std::string &final, const std::vector< std::string > &separators)
 Conuts how many new lines are there in the format. More...
 
const size_t findNginxFieldEnd (const std::string &string, const int &start)
 Finds the end of a Nginx log field. More...
 
void checkIisString (const std::string &string)
 Checks whether the format string contains invalid characters or not. More...
 
+ + + + + + + + + + +

+Private Attributes

const std::unordered_map< std::string, std::string > APACHE_ALF
 < Access logs fields formats More...
 
+const std::unordered_map< std::string, std::string > NGINX_ALF
 < Access logs fields formats
 
+const std::unordered_map< std::string, std::string > IIS_ALF
 < Access logs fields formats
 
+

Detailed Description

+

FormatOps.

+

Operations for the logs formats

+

Member Function Documentation

+ +

◆ checkIisString()

+ +
+
+ + + + + +
+ + + + + + + + +
void FormatOps::checkIisString (const std::string & string)
+
+private
+
+ +

Checks whether the format string contains invalid characters or not.

+
Parameters
+ + +
stringThe format string
+
+
+
Exceptions
+ + +
LogFormatException
+
+
+
See also
processIisFormatString
+ +
+
+ +

◆ countNewLines()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
const int FormatOps::countNewLines (const std::string & initial,
const std::string & final,
const std::vector< std::string > & separators 
)
+
+private
+
+ +

Conuts how many new lines are there in the format.

+

Used to join log lines which refer to the same log line

Parameters
+ + + + +
initialThe initial separator
finalThe final separator
separatorsThe separators in the middle
+
+
+
Returns
The number of new lines in a single log line
+
See also
LogsFormat, processApacheFormatString(), processNginxFormatString()
+ +
+
+ +

◆ findNginxFieldEnd()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
const size_t FormatOps::findNginxFieldEnd (const std::string & string,
const int & start 
)
+
+private
+
+ +

Finds the end of a Nginx log field.

+
Parameters
+ + + +
stringThe format string
startThe starting point of the field in the string
+
+
+
Returns
The ending poin of the field in the string
+
See also
processNginxFormatString()
+ +
+
+ +

◆ getApacheLogSample()

+ +
+
+ + + + + + + + +
const QString FormatOps::getApacheLogSample (const LogsFormatlog_format)
+
+ +

Returns a log line sample based on the given format.

+
Parameters
+ + +
log_formatThe logs format to use to build the sample
+
+
+
Returns
The sample line
+
See also
LogsFormat, Craplog::getLogsFormatSample()
+ +
+
+ +

◆ getIisLogSample()

+ +
+
+ + + + + + + + +
const QString FormatOps::getIisLogSample (const LogsFormatlog_format)
+
+ +

Returns a log line sample based on the given format.

+
Parameters
+ + +
log_formatThe logs format to use to build the sample
+
+
+
Returns
The sample line
+
See also
LogsFormat, Craplog::getLogsFormatSample()
+ +
+
+ +

◆ getNginxLogSample()

+ +
+
+ + + + + + + + +
const QString FormatOps::getNginxLogSample (const LogsFormatlog_format)
+
+ +

Returns a log line sample based on the given format.

+
Parameters
+ + +
log_formatThe logs format to use to build the sample
+
+
+
Returns
The sample line
+
See also
LogsFormat, Craplog::getLogsFormatSample()
+ +
+
+ +

◆ parseApacheEscapes()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
const std::string FormatOps::parseApacheEscapes (const std::string & string,
const bool & strftime = false 
)
+
+private
+
+ +

Parses the escapes (backslashes) and returns the resulting string.

+

Used to obtain the same result as on Apache2

Parameters
+ + + +
stringThe string to parse
strftimeWhether to apply the strftime special rule when parsing or not
+
+
+
Returns
The resulting string
+
Exceptions
+ + +
LogFormatException
+
+
+
See also
processApacheFormatString()
+ +
+
+ +

◆ parseNginxEscapes()

+ +
+
+ + + + + +
+ + + + + + + + +
const std::string FormatOps::parseNginxEscapes (const std::string & string)
+
+private
+
+ +

Parses the escapes (backslashes) and returns the resulting string.

+

Used to obtain the same result as on Nginx

Parameters
+ + +
stringThe string to parse
+
+
+
Returns
The resulting string
+
Exceptions
+ + +
LogFormatException
+
+
+
See also
processNginxFormatString()
+ +
+
+ +

◆ processApacheFormatString()

+ +
+
+ + + + + + + + +
const FormatOps::LogsFormat FormatOps::processApacheFormatString (const std::string & format_string)
+
+ +

Processes the given string to extrapolate the format for Apache2.

+
Parameters
+ + +
format_stringThe format string to process
+
+
+
Returns
The logs format
+
Exceptions
+ + +
LogFormatException
+
+
+
See also
LogsFormat
+ +
+
+ +

◆ processIisFormatString()

+ +
+
+ + + + + + + + + + + + + + + + + + +
const FormatOps::LogsFormat FormatOps::processIisFormatString (const std::string & format_string,
const int & log_module 
)
+
+ +

Processes the given string to extrapolate the format for the IIS.

+
Parameters
+ + + +
format_stringThe format string to process
log_moduleThe ID of the log module to use
+
+
+
Returns
The logs format
+
Exceptions
+ + +
LogFormatException
+
+
+
See also
LogsFormat
+ +
+
+ +

◆ processNginxFormatString()

+ +
+
+ + + + + + + + +
const FormatOps::LogsFormat FormatOps::processNginxFormatString (const std::string & format_string)
+
+ +

Processes the given string to extrapolate the format for Nginx.

+
Parameters
+ + +
format_stringThe format string to process
+
+
+
Returns
The logs format
+
Exceptions
+ + +
LogFormatException
+
+
+
See also
LogsFormat
+ +
+
+

Member Data Documentation

+ +

◆ APACHE_ALF

+ +
+
+ + + + + +
+ + + + +
const std::unordered_map<std::string, std::string> FormatOps::APACHE_ALF
+
+private
+
+ +

< Access logs fields formats

+

Composed access logs fields formats

+ +
+
+
The documentation for this class was generated from the following files:
    +
  • logdoctor/modules/craplog/modules/formats.h
  • +
  • logdoctor/modules/craplog/modules/formats.cpp
  • +
+
+ + + + diff --git a/docs/html/classGZutils-members.html b/docs/html/classGZutils-members.html new file mode 100644 index 00000000..0d3ca20a --- /dev/null +++ b/docs/html/classGZutils-members.html @@ -0,0 +1,87 @@ + + + + + + + +LogDoctor: Member List + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
+
GZutils Member List
+
+
+ +

This is the complete list of members for GZutils, including all inherited members.

+ + +
readFile(const std::string &path, std::string &content)GZutilsstatic
+ + + + diff --git a/docs/html/classGZutils.html b/docs/html/classGZutils.html new file mode 100644 index 00000000..fdb98181 --- /dev/null +++ b/docs/html/classGZutils.html @@ -0,0 +1,151 @@ + + + + + + + +LogDoctor: GZutils Class Reference + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
+ +
GZutils Class Reference
+
+
+ +

GZUtils. + More...

+ +

#include <gzip.h>

+ + + + + +

+Static Public Member Functions

static void readFile (const std::string &path, std::string &content)
 Reads a GZipped file. More...
 
+

Detailed Description

+

GZUtils.

+

Utilities to work on GZipped files

+

Member Function Documentation

+ +

◆ readFile()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void GZutils::readFile (const std::string & path,
std::string & content 
)
+
+static
+
+ +

Reads a GZipped file.

+
Parameters
+ + + +
pathThe path of the file
contentWill hold the content of the file
+
+
+ +
+
+
The documentation for this class was generated from the following files:
    +
  • logdoctor/utilities/gzip.h
  • +
  • logdoctor/utilities/gzip.cpp
  • +
+
+ + + + diff --git a/docs/html/classGameSec-members.html b/docs/html/classGameSec-members.html new file mode 100644 index 00000000..e18c6d29 --- /dev/null +++ b/docs/html/classGameSec-members.html @@ -0,0 +1,85 @@ + + + + + + + +LogDoctor: Member List + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
+
GameSec Member List
+
+
+ +

This is the complete list of members for GameSec, including all inherited members.

+
+ + + + diff --git a/docs/html/classGameSec.html b/docs/html/classGameSec.html new file mode 100644 index 00000000..4878928a --- /dev/null +++ b/docs/html/classGameSec.html @@ -0,0 +1,97 @@ + + + + + + + +LogDoctor: GameSec Class Reference + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
+ +
GameSec Class Reference
+
+
+ +

GameSec. + More...

+ +

#include <games.h>

+

Detailed Description

+

GameSec.

+

Utilities for the games

+

The documentation for this class was generated from the following files:
    +
  • logdoctor/games/games.h
  • +
  • logdoctor/games/games.cpp
  • +
+
+ + + + diff --git a/docs/html/classGenericException-members.html b/docs/html/classGenericException-members.html new file mode 100644 index 00000000..2b61543f --- /dev/null +++ b/docs/html/classGenericException-members.html @@ -0,0 +1,85 @@ + + + + + + + +LogDoctor: Member List + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
+
GenericException Member List
+
+
+ +

This is the complete list of members for GenericException, including all inherited members.

+
+ + + + diff --git a/docs/html/classGenericException.html b/docs/html/classGenericException.html new file mode 100644 index 00000000..34860d25 --- /dev/null +++ b/docs/html/classGenericException.html @@ -0,0 +1,103 @@ + + + + + + + +LogDoctor: GenericException Class Reference + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
+ +
GenericException Class Reference
+
+
+ +

GenericException. + More...

+ +

#include <exceptions.h>

+
+Inheritance diagram for GenericException:
+
+
+ +
+

Detailed Description

+

GenericException.

+

Generic exception for general purposes

+

The documentation for this class was generated from the following files:
    +
  • logdoctor/modules/exceptions.h
  • +
  • logdoctor/modules/exceptions.cpp
  • +
+
+ + + + diff --git a/docs/html/classGenericException.png b/docs/html/classGenericException.png new file mode 100644 index 00000000..94312c0a Binary files /dev/null and b/docs/html/classGenericException.png differ diff --git a/docs/html/classHashOps-members.html b/docs/html/classHashOps-members.html new file mode 100644 index 00000000..9695003c --- /dev/null +++ b/docs/html/classHashOps-members.html @@ -0,0 +1,92 @@ + + + + + + + +LogDoctor: Member List + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
+
HashOps Member List
+
+
+ +

This is the complete list of members for HashOps, including all inherited members.

+ + + + + + + +
digestFile(const std::string &file_path)HashOps
hasBeenUsed(const std::string &file_hash, const int &web_server_id)HashOps
insertUsedHash(QSqlQuery &query, const QString &db_name, const std::string &hash, const int &web_server_id)HashOps
insertUsedHashes(const std::string &db_path, const std::vector< std::string > &hashes, const int &web_server_id)HashOps
loadUsedHashesLists(const std::string &db_path)HashOps
setDialogLevel(const int &new_level)HashOps
+ + + + diff --git a/docs/html/classHashOps.html b/docs/html/classHashOps.html new file mode 100644 index 00000000..4ba05385 --- /dev/null +++ b/docs/html/classHashOps.html @@ -0,0 +1,322 @@ + + + + + + + +LogDoctor: HashOps Class Reference + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
+ +
HashOps Class Reference
+
+
+ +

HashOps. + More...

+ +

#include <hash.h>

+ + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

+void setDialogLevel (const int &new_level)
 Sets the new Dialogs level.
 
bool loadUsedHashesLists (const std::string &db_path)
 Retrieves the lists of hashes from the database file. More...
 
std::string digestFile (const std::string &file_path)
 Returns the hash resulting from the content of the given file. More...
 
bool hasBeenUsed (const std::string &file_hash, const int &web_server_id)
 Checks if the given hash equals one which is already in the list. More...
 
bool insertUsedHash (QSqlQuery &query, const QString &db_name, const std::string &hash, const int &web_server_id)
 Inserts a hashe in the corresponding database table. More...
 
bool insertUsedHashes (const std::string &db_path, const std::vector< std::string > &hashes, const int &web_server_id)
 Inserts multiple hashes in the corresponding database table. More...
 
+

Detailed Description

+

HashOps.

+

Operations for the hashes

+

Member Function Documentation

+ +

◆ digestFile()

+ +
+
+ + + + + + + + +
std::string HashOps::digestFile (const std::string & file_path)
+
+ +

Returns the hash resulting from the content of the given file.

+
Parameters
+ + +
file_pathThe path of the file to process
+
+
+
Returns
The sha256 hash
+
Exceptions
+ + +
GenericException
+
+
+
See also
SHA256
+ +
+
+ +

◆ hasBeenUsed()

+ +
+
+ + + + + + + + + + + + + + + + + + +
bool HashOps::hasBeenUsed (const std::string & file_hash,
const int & web_server_id 
)
+
+ +

Checks if the given hash equals one which is already in the list.

+
Parameters
+ + + +
file_hashThe sha256 hash to compare
web_server_idThe ID of the Web Server which generated the file
+
+
+
Returns
Whether the hash is already in the list or not
+
See also
hashes
+ +
+
+ +

◆ insertUsedHash()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool HashOps::insertUsedHash (QSqlQuery & query,
const QString & db_name,
const std::string & hash,
const int & web_server_id 
)
+
+ +

Inserts a hashe in the corresponding database table.

+
Parameters
+ + + + + +
db_queryQuery instance, already initialized
db_nameThe name of the database, eventually used by dialogs
hashThe hash to insert
web_server_idThe ID of the Web Server which generated the file
+
+
+
Returns
Whether the operation has been successful or not
+
See also
insertUsedHashes()
+ +
+
+ +

◆ insertUsedHashes()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
bool HashOps::insertUsedHashes (const std::string & db_path,
const std::vector< std::string > & hashes,
const int & web_server_id 
)
+
+ +

Inserts multiple hashes in the corresponding database table.

+
Parameters
+ + + + +
db_pathThe path of the Hashes database
hashesThe list of hashes to insert
web_server_idThe ID of the Web Server which generated the file
+
+
+
Returns
Whether the operation has been successful or not
+
See also
insertUsedHash()
+ +
+
+ +

◆ loadUsedHashesLists()

+ +
+
+ + + + + + + + +
bool HashOps::loadUsedHashesLists (const std::string & db_path)
+
+ +

Retrieves the lists of hashes from the database file.

+
Parameters
+ + +
db_pathThe path of the log files' Hashes database
+
+
+
Returns
Whether the operation has been successful or not
+
See also
hashes
+ +
+
+
The documentation for this class was generated from the following files:
    +
  • logdoctor/modules/craplog/modules/hash.h
  • +
  • logdoctor/modules/craplog/modules/hash.cpp
  • +
+
+ + + + diff --git a/docs/html/classIOutils-members.html b/docs/html/classIOutils-members.html new file mode 100644 index 00000000..41ef8298 --- /dev/null +++ b/docs/html/classIOutils-members.html @@ -0,0 +1,96 @@ + + + + + + + +LogDoctor: Member List + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
+
IOutils Member List
+
+
+ +

This is the complete list of members for IOutils, including all inherited members.

+ + + + + + + + + + + +
checkDir(const std::string &path, const bool &readable=false, const bool &writable=false)IOutilsstatic
checkFile(const std::string &path, const bool &readable=false, const bool &writable=false)IOutilsstatic
exists(const std::string &path)IOutilsstatic
isDir(const std::string &path)IOutilsstatic
isFile(const std::string &path)IOutilsstatic
makeDir(const std::string &path, std::error_code &err) noexcept(true)IOutilsstatic
randomLines(const std::string &path, std::vector< std::string > &lines, const int &n_lines=16, const bool &strip_lines=true)IOutilsstatic
readFile(const std::string &path, std::string &content)IOutilsstatic
renameAsCopy(const std::string &path, std::error_code &err) noexcept(true)IOutilsstatic
writeOnFile(const std::string &path, const std::string &content)IOutilsstatic
+ + + + diff --git a/docs/html/classIOutils.html b/docs/html/classIOutils.html new file mode 100644 index 00000000..c135ccec --- /dev/null +++ b/docs/html/classIOutils.html @@ -0,0 +1,584 @@ + + + + + + + +LogDoctor: IOutils Class Reference + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
+ +
IOutils Class Reference
+
+
+ +

IOUtils. + More...

+ +

#include <io.h>

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Static Public Member Functions

static const bool exists (const std::string &path)
 Checks the existence of a file/folder. More...
 
static const bool isFile (const std::string &path)
 Checks if a path exists and points to a file. More...
 
static const bool isDir (const std::string &path)
 Checks if a path exists and points to a directory. More...
 
static const bool checkFile (const std::string &path, const bool &readable=false, const bool &writable=false)
 Checks if a path exists, if it points to a file and if the user has read and/or write permissions on it. More...
 
static const bool checkDir (const std::string &path, const bool &readable=false, const bool &writable=false)
 Checks if a path exists, if it points to a folder and if the user has read and/or write permissions on it. More...
 
static const bool makeDir (const std::string &path, std::error_code &err) noexcept(true)
 Creates a directory. More...
 
static const bool renameAsCopy (const std::string &path, std::error_code &err) noexcept(true)
 Renames an entry with a trailing '.copy'. More...
 
static void randomLines (const std::string &path, std::vector< std::string > &lines, const int &n_lines=16, const bool &strip_lines=true)
 Randomly pick lines from a file. More...
 
static void readFile (const std::string &path, std::string &content)
 Reads the content of a file. More...
 
static void writeOnFile (const std::string &path, const std::string &content)
 Writes a string on file. More...
 
+

Detailed Description

+

IOUtils.

+

Utilities to work on files

+

Member Function Documentation

+ +

◆ checkDir()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
const bool IOutils::checkDir (const std::string & path,
const bool & readable = false,
const bool & writable = false 
)
+
+static
+
+ +

Checks if a path exists, if it points to a folder and if the user has read and/or write permissions on it.

+
Parameters
+ + + + +
pathThe path of the entry
readableSet to true to check for readability
writableSet to true to check for writability
+
+
+
Returns
The result of the checks
+ +
+
+ +

◆ checkFile()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
const bool IOutils::checkFile (const std::string & path,
const bool & readable = false,
const bool & writable = false 
)
+
+static
+
+ +

Checks if a path exists, if it points to a file and if the user has read and/or write permissions on it.

+
Parameters
+ + + + +
pathThe path of the entry
readableSet to true to check for readability
writableSet to true to check for writability
+
+
+
Returns
The result of the checks
+ +
+
+ +

◆ exists()

+ +
+
+ + + + + +
+ + + + + + + + +
const bool IOutils::exists (const std::string & path)
+
+static
+
+ +

Checks the existence of a file/folder.

+
Parameters
+ + +
pathThe path of the entry
+
+
+
Returns
The result of the check
+ +
+
+ +

◆ isDir()

+ +
+
+ + + + + +
+ + + + + + + + +
const bool IOutils::isDir (const std::string & path)
+
+static
+
+ +

Checks if a path exists and points to a directory.

+
Parameters
+ + +
pathThe path of the entry
+
+
+
Returns
The result of the checks
+ +
+
+ +

◆ isFile()

+ +
+
+ + + + + +
+ + + + + + + + +
const bool IOutils::isFile (const std::string & path)
+
+static
+
+ +

Checks if a path exists and points to a file.

+
Parameters
+ + +
pathThe path of the entry
+
+
+
Returns
The result of the check
+ +
+
+ +

◆ makeDir()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
const bool IOutils::makeDir (const std::string & path,
std::error_code & err 
)
+
+staticnoexcept
+
+ +

Creates a directory.

+
Parameters
+ + +
pathThe path of the new entry
+
+
+
Returns
Wheter the operation was successful or not
+ +
+
+ +

◆ randomLines()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void IOutils::randomLines (const std::string & path,
std::vector< std::string > & lines,
const int & n_lines = 16,
const bool & strip_lines = true 
)
+
+static
+
+ +

Randomly pick lines from a file.

+
Parameters
+ + + + + +
pathThe path of the entry
linesWill hold the picked lines
n_linesThe number of lines to pick
strip_linesWhether to strip control-characters away from the lines
+
+
+ +
+
+ +

◆ readFile()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void IOutils::readFile (const std::string & path,
std::string & content 
)
+
+static
+
+ +

Reads the content of a file.

+
Parameters
+ + + +
pathThe path of the file to read from
contentWill hold the content of the file
+
+
+ +
+
+ +

◆ renameAsCopy()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
const bool IOutils::renameAsCopy (const std::string & path,
std::error_code & err 
)
+
+staticnoexcept
+
+ +

Renames an entry with a trailing '.copy'.

+
Parameters
+ + + +
pathThe path of the entry to rename
errWill hold the error, if any
+
+
+
Returns
Wheter the operation was successful or not
+ +
+
+ +

◆ writeOnFile()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void IOutils::writeOnFile (const std::string & path,
const std::string & content 
)
+
+static
+
+ +

Writes a string on file.

+
Parameters
+ + + +
pathThe path of the file to write on
contentThe string to write
+
+
+ +
+
+
The documentation for this class was generated from the following files:
    +
  • logdoctor/utilities/io.h
  • +
  • logdoctor/utilities/io.cpp
  • +
+
+ + + + diff --git a/docs/html/classLogFormatException-members.html b/docs/html/classLogFormatException-members.html new file mode 100644 index 00000000..5d90f27c --- /dev/null +++ b/docs/html/classLogFormatException-members.html @@ -0,0 +1,85 @@ + + + + + + + +LogDoctor: Member List + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
+
LogFormatException Member List
+
+
+ +

This is the complete list of members for LogFormatException, including all inherited members.

+
+ + + + diff --git a/docs/html/classLogFormatException.html b/docs/html/classLogFormatException.html new file mode 100644 index 00000000..f1416196 --- /dev/null +++ b/docs/html/classLogFormatException.html @@ -0,0 +1,103 @@ + + + + + + + +LogDoctor: LogFormatException Class Reference + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
+ +
LogFormatException Class Reference
+
+
+ +

LogFormatException. + More...

+ +

#include <exceptions.h>

+
+Inheritance diagram for LogFormatException:
+
+
+ +
+

Detailed Description

+

LogFormatException.

+

Exception related to a Logs Format

+

The documentation for this class was generated from the following files:
    +
  • logdoctor/modules/exceptions.h
  • +
  • logdoctor/modules/exceptions.cpp
  • +
+
+ + + + diff --git a/docs/html/classLogFormatException.png b/docs/html/classLogFormatException.png new file mode 100644 index 00000000..67c7e82a Binary files /dev/null and b/docs/html/classLogFormatException.png differ diff --git a/docs/html/classLogOps-members.html b/docs/html/classLogOps-members.html new file mode 100644 index 00000000..930cd0ef --- /dev/null +++ b/docs/html/classLogOps-members.html @@ -0,0 +1,102 @@ + + + + + + + +LogDoctor: Member List + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
+
LogOps Member List
+
+
+ +

This is the complete list of members for LogOps, including all inherited members.

+ + + + + + + + + + + + + + + + + +
Access enum valueLogOps
cleanLines(std::vector< std::string > &lines)LogOps
deepTypeCheck(const std::string &line, const FormatOps::LogsFormat &format)LogOpsprivate
defineFileType(const std::vector< std::string > &lines, const FormatOps::LogsFormat &format)LogOps
Discarded enum valueLogOps
Failed enum valueLogOps
getParsedLines()LogOps
getParsedSize()LogOps
getTotalSize()LogOps
LogType enum nameLogOps
parsed_linesLogOpsprivate
parsed_sizeLogOpsprivate
parseLine(const std::string &line, const FormatOps::LogsFormat &format)LogOpsprivate
parseLines(std::vector< std::unordered_map< int, std::string > > &data, const std::vector< std::string > &lines, const FormatOps::LogsFormat &format)LogOps
resetPerfData()LogOps
total_sizeLogOpsprivate
+ + + + diff --git a/docs/html/classLogOps.html b/docs/html/classLogOps.html new file mode 100644 index 00000000..8f6169c5 --- /dev/null +++ b/docs/html/classLogOps.html @@ -0,0 +1,536 @@ + + + + + + + +LogDoctor: LogOps Class Reference + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
+ +

LogOps. + More...

+ +

#include <logs.h>

+ + + + + +

+Public Types

enum  LogType { Failed = -1 +, Discarded = 0 +, Access = 1 + }
 Enumerates log file types. More...
 
+ + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

LogType defineFileType (const std::vector< std::string > &lines, const FormatOps::LogsFormat &format)
 Defines the type of a file. More...
 
void cleanLines (std::vector< std::string > &lines)
 Removes commented lines from the given list. More...
 
void parseLines (std::vector< std::unordered_map< int, std::string > > &data, const std::vector< std::string > &lines, const FormatOps::LogsFormat &format)
 Parses log lines to extract data. More...
 
+void resetPerfData ()
 Resets the performances data.
 
const unsigned getTotalSize ()
 Returns the total size of the logs lines. More...
 
const unsigned getParsedSize ()
 Returns the parsed logs size. More...
 
const unsigned getParsedLines ()
 Returns the number of parsed log lines. More...
 
+ + + + + + + +

+Private Member Functions

bool deepTypeCheck (const std::string &line, const FormatOps::LogsFormat &format)
 Parse the given line using the given format. More...
 
const std::unordered_map< int, std::string > parseLine (const std::string &line, const FormatOps::LogsFormat &format)
 Parses a line to extract data. More...
 
+ + + + + + + + + + +

+Private Attributes

unsigned total_size =0
 Total size of the parsed logs. More...
 
unsigned parsed_size =0
 Size of the parsed logs. More...
 
unsigned parsed_lines =0
 Number of parsed logs lines. More...
 
+

Detailed Description

+

LogOps.

+

Operations for the logs

+

Member Enumeration Documentation

+ +

◆ LogType

+ +
+
+ + + + +
enum LogOps::LogType
+
+ +

Enumerates log file types.

+

File types used to decide whether a file should be considered valid or not

See also
defineFileType()
+ + + + +
Enumerator
Failed 

Failed to determine the type.

+
Discarded 

Not a valid file, will be discarded.

+
Access 

Valid access logs file type.

+
+ +
+
+

Member Function Documentation

+ +

◆ cleanLines()

+ +
+
+ + + + + + + + +
void LogOps::cleanLines (std::vector< std::string > & lines)
+
+ +

Removes commented lines from the given list.

+
Parameters
+ + +
linesThe lines to clean
+
+
+ +
+
+ +

◆ deepTypeCheck()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool LogOps::deepTypeCheck (const std::string & line,
const FormatOps::LogsFormatformat 
)
+
+private
+
+ +

Parse the given line using the given format.

+
Parameters
+ + + +
lineThe log line to check
formatThe logs format to use
+
+
+
Returns
Whether the line respects the format or not
+
See also
defineFileType(), FormatOps::LogsFormat
+ +
+
+ +

◆ defineFileType()

+ +
+
+ + + + + + + + + + + + + + + + + + +
LogOps::LogType LogOps::defineFileType (const std::vector< std::string > & lines,
const FormatOps::LogsFormatformat 
)
+
+ +

Defines the type of a file.

+
Parameters
+ + + +
linesA list of (randomly picked) lines from the file to examine
formatThe logs format to use to determine if the file is valid or not
+
+
+
Returns
The resulting file type
+
See also
LogType, deepTypeCheck(), FormatOps::LogsFormat
+ +
+
+ +

◆ getParsedLines()

+ +
+
+ + + + + + + +
const unsigned LogOps::getParsedLines ()
+
+ +

Returns the number of parsed log lines.

+
See also
parsed_lines
+ +
+
+ +

◆ getParsedSize()

+ +
+
+ + + + + + + +
const unsigned LogOps::getParsedSize ()
+
+ +

Returns the parsed logs size.

+
See also
parsed_size
+ +
+
+ +

◆ getTotalSize()

+ +
+
+ + + + + + + +
const unsigned LogOps::getTotalSize ()
+
+ +

Returns the total size of the logs lines.

+
See also
total_size
+ +
+
+ +

◆ parseLine()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
const std::unordered_map< int, std::string > LogOps::parseLine (const std::string & line,
const FormatOps::LogsFormatformat 
)
+
+private
+
+ +

Parses a line to extract data.

+
Parameters
+ + + +
lineThe log line to parse
formatThe logs format to use
+
+
+
Returns
A data collection item
+
Exceptions
+ + +
LogParserException
+
+
+
See also
parseLines(), Craplog::data_collection, FormatOps::LogsFormat
+ +
+
+ +

◆ parseLines()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void LogOps::parseLines (std::vector< std::unordered_map< int, std::string > > & data,
const std::vector< std::string > & lines,
const FormatOps::LogsFormatformat 
)
+
+ +

Parses log lines to extract data.

+
Parameters
+ + + + +
dataThe data collection which will hold the data
linesThe list of lines to parse
formatThe logs format to use
+
+
+
Exceptions
+ + +
LogParserException
+
+
+
See also
parseLine(), Craplog::parseLogLines(), FormatOps::LogsFormat
+ +
+
+

Member Data Documentation

+ +

◆ parsed_lines

+ +
+
+ + + + + +
+ + + + +
unsigned LogOps::parsed_lines =0
+
+private
+
+ +

Number of parsed logs lines.

+
See also
getParsedLines()
+ +
+
+ +

◆ parsed_size

+ +
+
+ + + + + +
+ + + + +
unsigned LogOps::parsed_size =0
+
+private
+
+ +

Size of the parsed logs.

+
See also
getParsedSize()
+ +
+
+ +

◆ total_size

+ +
+
+ + + + + +
+ + + + +
unsigned LogOps::total_size =0
+
+private
+
+ +

Total size of the parsed logs.

+
See also
getTotalSize()
+ +
+
+
The documentation for this class was generated from the following files:
    +
  • logdoctor/modules/craplog/modules/logs.h
  • +
  • logdoctor/modules/craplog/modules/logs.cpp
  • +
+
+ + + + diff --git a/docs/html/classLogParserException-members.html b/docs/html/classLogParserException-members.html new file mode 100644 index 00000000..90135b6e --- /dev/null +++ b/docs/html/classLogParserException-members.html @@ -0,0 +1,85 @@ + + + + + + + +LogDoctor: Member List + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
+
LogParserException Member List
+
+
+ +

This is the complete list of members for LogParserException, including all inherited members.

+
+ + + + diff --git a/docs/html/classLogParserException.html b/docs/html/classLogParserException.html new file mode 100644 index 00000000..358cd6ec --- /dev/null +++ b/docs/html/classLogParserException.html @@ -0,0 +1,103 @@ + + + + + + + +LogDoctor: LogParserException Class Reference + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
+ +
LogParserException Class Reference
+
+
+ +

LogParserException. + More...

+ +

#include <exceptions.h>

+
+Inheritance diagram for LogParserException:
+
+
+ +
+

Detailed Description

+

LogParserException.

+

Exception related to the logs parser

+

The documentation for this class was generated from the following files:
    +
  • logdoctor/modules/exceptions.h
  • +
  • logdoctor/modules/exceptions.cpp
  • +
+
+ + + + diff --git a/docs/html/classLogParserException.png b/docs/html/classLogParserException.png new file mode 100644 index 00000000..0809377c Binary files /dev/null and b/docs/html/classLogParserException.png differ diff --git a/docs/html/classMainSlice-members.html b/docs/html/classMainSlice-members.html new file mode 100644 index 00000000..a7c35e71 --- /dev/null +++ b/docs/html/classMainSlice-members.html @@ -0,0 +1,90 @@ + + + + + + + +LogDoctor: Member List + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
+
MainSlice Member List
+
+
+ +

This is the complete list of members for MainSlice, including all inherited members.

+ + + + + +
breakdownSeries() constMainSlice
name() constMainSlice
setName(QString name)MainSlice
updateLabel()MainSliceslot
+ + + + diff --git a/docs/html/classMainSlice.html b/docs/html/classMainSlice.html new file mode 100644 index 00000000..69878e17 --- /dev/null +++ b/docs/html/classMainSlice.html @@ -0,0 +1,154 @@ + + + + + + + +LogDoctor: MainSlice Class Reference + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
+ +
MainSlice Class Reference
+
+
+ +

Represents a slice. + More...

+ +

#include <donuts.h>

+
+Inheritance diagram for MainSlice:
+
+
+ +
+ + + + + +

+Public Slots

+void updateLabel ()
 Updates the label using the name.
 
+ + + + + + + + + + +

+Public Member Functions

+QPieSeries * breakdownSeries () const
 Returns the series.
 
void setName (QString name)
 Sets the name. More...
 
+QString name () const
 Returns the name.
 
+

Detailed Description

+

Represents a slice.

+

A slice to be added at the donut

+

Member Function Documentation

+ +

◆ setName()

+ +
+
+ + + + + + + + +
void MainSlice::setName (QString name)
+
+ +

Sets the name.

+
Parameters
+ + +
nameThe name to be used
+
+
+ +
+
+
The documentation for this class was generated from the following files:
    +
  • logdoctor/modules/craplog/modules/donuts.h
  • +
  • logdoctor/modules/craplog/modules/donuts.cpp
  • +
+
+ + + + diff --git a/docs/html/classMainSlice.png b/docs/html/classMainSlice.png new file mode 100644 index 00000000..f67e8903 Binary files /dev/null and b/docs/html/classMainSlice.png differ diff --git a/docs/html/classMainWindow-members.html b/docs/html/classMainWindow-members.html new file mode 100644 index 00000000..e8cea435 --- /dev/null +++ b/docs/html/classMainWindow-members.html @@ -0,0 +1,111 @@ + + + + + + + +LogDoctor: Member List + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
+
MainWindow Member List
+
+
+ +

This is the complete list of members for MainWindow, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
backupDatabase()MainWindowprivate
basePath(const std::string &path)MainWindowprivate
checkDataDB()MainWindowprivate
craplogFinished()MainWindowprivate
craplogStarted()MainWindowprivate
defineOSspec()MainWindowprivate
detectIconsTheme()MainWindowprivate
geometryFromString(const std::string &geometry)MainWindowprivate
geometryToString()MainWindowprivate
list2string(const std::vector< std::string > &list, const bool &user_agent=false)MainWindowprivate
makeInitialChecks()MainWindowprivate
menu_actionEnglish_triggered()MainWindowprivateslot
printableSize(const int &bytes)MainWindowprivate
printableSpeed(const int &bytes, const int &secs)MainWindowprivate
printableTime(const int &seconds)MainWindowprivate
readConfigs()MainWindowprivate
refreshStatsDates()MainWindowprivate
resolvePath(const std::string &path)MainWindowprivate
setDbWorkingState(const bool &state)MainWindowprivate
string2list(const std::string &string, const bool &user_agent=false)MainWindowprivate
updateUiFonts()MainWindowprivate
updateUiIcons()MainWindowprivate
updateUiLanguage()MainWindowprivate
updateUiTheme()MainWindowprivate
writeConfigs()MainWindowprivate
+ + + + diff --git a/docs/html/classMainWindow.html b/docs/html/classMainWindow.html new file mode 100644 index 00000000..4c0fbeab --- /dev/null +++ b/docs/html/classMainWindow.html @@ -0,0 +1,411 @@ + + + + + + + +LogDoctor: MainWindow Class Reference + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
+ +
MainWindow Class Reference
+
+
+ +

MainWindow. + More...

+ +

#include <mainwindow.h>

+
+Inheritance diagram for MainWindow:
+
+
+ +
+ + + + +

+Private Slots

void menu_actionEnglish_triggered ()
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Private Member Functions

+void defineOSspec ()
 Defines OS specific stuff.
 
+void readConfigs ()
 Reads the configurations file and apply the resulting configuration.
 
+void writeConfigs ()
 Writes the current configuration on file.
 
const std::string list2string (const std::vector< std::string > &list, const bool &user_agent=false)
 Converts a list of items to a string. More...
 
const std::vector< std::string > string2list (const std::string &string, const bool &user_agent=false)
 Retrieves a list of items from the given string. More...
 
+void updateUiLanguage ()
 Translates the UI to the selected language.
 
const std::string geometryToString ()
 Converts the window's geometry to string. More...
 
void geometryFromString (const std::string &geometry)
 Retrieves the window geometry from the given string. More...
 
+void detectIconsTheme ()
 Auto-detects the icon-set to use depending on the current window theme.
 
+void updateUiIcons ()
 Updates the icons on the window.
 
+void updateUiTheme ()
 Updates the window theme.
 
+void updateUiFonts ()
 Updates the fonts on the window.
 
+const QString printableSize (const int &bytes)
 Printable size, including suffix.
 
+const QString printableTime (const int &seconds)
 Printable time, including suffix(es)
 
+const QString printableSpeed (const int &bytes, const int &secs)
 Printable speed, namely printable size over printable time.
 
+const std::string resolvePath (const std::string &path)
 Resolves the given path and returns the canonical path.
 
+const std::string basePath (const std::string &path)
 Returns the parent folder of the given path.
 
+void makeInitialChecks ()
 Makes the initial integrity checks.
 
+const bool & checkDataDB ()
 Checks the integrity of the logs data collection database.
 
+void backupDatabase ()
 Backs-up the logs data collection database.
 
+void setDbWorkingState (const bool &state)
 Called when a member begins/ends performing operations on the database.
 
+void craplogStarted ()
 The logs parser started working.
 
+void craplogFinished ()
 The logs parser finished working.
 
void refreshStatsDates ()
 Queries the available dates from the db and apply to the tabs. More...
 
+

Detailed Description

+

MainWindow.

+

The parent window

+

Member Function Documentation

+ +

◆ geometryFromString()

+ +
+
+ + + + + +
+ + + + + + + + +
void MainWindow::geometryFromString (const std::string & geometry)
+
+private
+
+ +

Retrieves the window geometry from the given string.

+
See also
readConfigs()
+ +
+
+ +

◆ geometryToString()

+ +
+
+ + + + + +
+ + + + + + + +
const std::string MainWindow::geometryToString ()
+
+private
+
+ +

Converts the window's geometry to string.

+
See also
writeConfigs()
+ +
+
+ +

◆ list2string()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
const std::string MainWindow::list2string (const std::vector< std::string > & list,
const bool & user_agent = false 
)
+
+private
+
+ +

Converts a list of items to a string.

+
Parameters
+ + + +
listThe list to stringify
user_agentsWhether to apply the special rule to parse user-agents lists or not
+
+
+
Returns
The resulting string
+
See also
writeConfigs()
+ +
+
+ +

◆ menu_actionEnglish_triggered

+ +
+
+ + + + + +
+ + + + + + + +
void MainWindow::menu_actionEnglish_triggered ()
+
+privateslot
+
+

MENU //// //////////

+ +
+
+ +

◆ refreshStatsDates()

+ +
+
+ + + + + +
+ + + + + + + +
void MainWindow::refreshStatsDates ()
+
+private
+
+ +

Queries the available dates from the db and apply to the tabs.

+
See also
Crapview::refreshDates()
+ +
+
+ +

◆ string2list()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
const std::vector< std::string > MainWindow::string2list (const std::string & string,
const bool & user_agent = false 
)
+
+private
+
+ +

Retrieves a list of items from the given string.

+
Parameters
+ + + +
listThe list to stringify
user_agentsWhether to apply the special rule to parse user-agents lists or not
+
+
+
Returns
The resulting list
+
See also
readConfigs()
+ +
+
+
The documentation for this class was generated from the following files:
    +
  • logdoctor/mainwindow.h
  • +
  • logdoctor/mainwindow.cpp
  • +
+
+ + + + diff --git a/docs/html/classMainWindow.png b/docs/html/classMainWindow.png new file mode 100644 index 00000000..49ef1450 Binary files /dev/null and b/docs/html/classMainWindow.png differ diff --git a/docs/html/classRichText-members.html b/docs/html/classRichText-members.html new file mode 100644 index 00000000..e68a486d --- /dev/null +++ b/docs/html/classRichText-members.html @@ -0,0 +1,89 @@ + + + + + + + +LogDoctor: Member List + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
+
RichText Member List
+
+
+ +

This is the complete list of members for RichText, including all inherited members.

+ + + + +
enrichLogs(QString &rich_content, const std::string &content, const FormatOps::LogsFormat &logs_format, TextBrowser &TB)RichTextstatic
richLogsDefault(QString &rich_str)RichTextstatic
richLogsFailure(QString &rich_str)RichTextstatic
+ + + + diff --git a/docs/html/classRichText.html b/docs/html/classRichText.html new file mode 100644 index 00000000..106bdd8d --- /dev/null +++ b/docs/html/classRichText.html @@ -0,0 +1,245 @@ + + + + + + + +LogDoctor: RichText Class Reference + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
+ +
RichText Class Reference
+
+
+ +

RichText. + More...

+ +

#include <rtf.h>

+
+Inheritance diagram for RichText:
+
+
+ +
+ + + + + + + + + + + +

+Static Public Member Functions

static void enrichLogs (QString &rich_content, const std::string &content, const FormatOps::LogsFormat &logs_format, TextBrowser &TB)
 Enriches the content of a log file with HTML/CSS code. More...
 
static void richLogsDefault (QString &rich_str)
 Provides the default string. More...
 
static void richLogsFailure (QString &rich_str)
 Provides the failure string. More...
 
+

Detailed Description

+

RichText.

+

Utilities for the TextBrowser

+

Member Function Documentation

+ +

◆ enrichLogs()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void RichText::enrichLogs (QString & rich_content,
const std::string & content,
const FormatOps::LogsFormatlogs_format,
TextBrowserTB 
)
+
+static
+
+ +

Enriches the content of a log file with HTML/CSS code.

+
Parameters
+ + + + + +
rich_contentWill hold the final enriched content
contentThe plain text content from a log file
logs_formatThe logs format to use
TBThe TextBrowser instance
+
+
+ +
+
+ +

◆ richLogsDefault()

+ +
+
+ + + + + +
+ + + + + + + + +
void RichText::richLogsDefault (QString & rich_str)
+
+static
+
+ +

Provides the default string.

+
Parameters
+ + +
rich_strWill hold the string
+
+
+ +
+
+ +

◆ richLogsFailure()

+ +
+
+ + + + + +
+ + + + + + + + +
void RichText::richLogsFailure (QString & rich_str)
+
+static
+
+ +

Provides the failure string.

+
Parameters
+ + +
rich_strWill hold the string
+
+
+ +
+
+
The documentation for this class was generated from the following files:
    +
  • logdoctor/utilities/rtf.h
  • +
  • logdoctor/utilities/rtf.cpp
  • +
+
+ + + + diff --git a/docs/html/classRichText.png b/docs/html/classRichText.png new file mode 100644 index 00000000..72dab49a Binary files /dev/null and b/docs/html/classRichText.png differ diff --git a/docs/html/classSHA256-members.html b/docs/html/classSHA256-members.html new file mode 100644 index 00000000..791b912e --- /dev/null +++ b/docs/html/classSHA256-members.html @@ -0,0 +1,85 @@ + + + + + + + +LogDoctor: Member List + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
+
SHA256 Member List
+
+
+ +

This is the complete list of members for SHA256, including all inherited members.

+
+ + + + diff --git a/docs/html/classSHA256.html b/docs/html/classSHA256.html new file mode 100644 index 00000000..2c2ec185 --- /dev/null +++ b/docs/html/classSHA256.html @@ -0,0 +1,89 @@ + + + + + + + +LogDoctor: SHA256 Class Reference + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
+ +
SHA256 Class Reference
+
+
+
The documentation for this class was generated from the following files:
    +
  • logdoctor/modules/craplog/modules/sha256.h
  • +
  • logdoctor/modules/craplog/modules/sha256.cpp
  • +
+
+ + + + diff --git a/docs/html/classSnake-members.html b/docs/html/classSnake-members.html new file mode 100644 index 00000000..b9214218 --- /dev/null +++ b/docs/html/classSnake-members.html @@ -0,0 +1,91 @@ + + + + + + + +LogDoctor: Member List + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
+
Snake Member List
+
+
+ +

This is the complete list of members for Snake, including all inherited members.

+ + + + + + +
direction()Snake
grow(const bool &is_borning)Snakeprivate
inTile(const unsigned int &x, const unsigned int &y, const bool &avoid_tail=true)Snake
setDirection(const Direction new_direction)Snake
update(QGraphicsScene *field_scene=nullptr, const bool &dry=false, const bool &is_borning=false)Snake
+ + + + diff --git a/docs/html/classSnake.html b/docs/html/classSnake.html new file mode 100644 index 00000000..fbf30db2 --- /dev/null +++ b/docs/html/classSnake.html @@ -0,0 +1,130 @@ + + + + + + + +LogDoctor: Snake Class Reference + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
+
+Inheritance diagram for Snake:
+
+
+ +
+ + + + +

+Classes

struct  Tile
 
+ + + + + + + + + + + + + +

+Public Member Functions

+const bool inTile (const unsigned int &x, const unsigned int &y, const bool &avoid_tail=true)
 Checks whether is there a part of the snake in the given position.
 
+void setDirection (const Direction new_direction)
 Sets the new direction (of the head)
 
+const Direction & direction ()
 Returns the current direction (of the head)
 
+void update (QGraphicsScene *field_scene=nullptr, const bool &dry=false, const bool &is_borning=false)
 Updates the position and direction of the entire snake.
 
+ + + + +

+Private Member Functions

+void grow (const bool &is_borning)
 Increases the length of the body of the snake of 1 part.
 
+
The documentation for this class was generated from the following files:
    +
  • logdoctor/games/snake/snake.h
  • +
  • logdoctor/games/snake/snake.cpp
  • +
+
+ + + + diff --git a/docs/html/classSnake.png b/docs/html/classSnake.png new file mode 100644 index 00000000..97528776 Binary files /dev/null and b/docs/html/classSnake.png differ diff --git a/docs/html/classSnakeGame-members.html b/docs/html/classSnakeGame-members.html new file mode 100644 index 00000000..406e17ad --- /dev/null +++ b/docs/html/classSnakeGame-members.html @@ -0,0 +1,99 @@ + + + + + + + +LogDoctor: Member List + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
+
SnakeGame Member List
+
+
+ +

This is the complete list of members for SnakeGame, including all inherited members.

+ + + + + + + + + + + + + + +
Battle enum valueSnakeGameprivate
checkCollision(Snake &snake, Snake &adv_snake, const bool &is_adv)SnakeGameprivate
Classic enum valueSnakeGameprivate
foodSnakeGameprivate
GameMode enum nameSnakeGameprivate
Hunt enum valueSnakeGameprivate
key_eventsSnakeGameprivate
keyPressEvent(QKeyEvent *event) overrideSnakeGameprivate
MAX_SNAKE_LENGTHSnakeGameprivate
processGameLogic()SnakeGameprivateslot
processNextKeyEvent()SnakeGameprivate
snakeSnakeGameprivate
updateGameScore()SnakeGameprivate
+ + + + diff --git a/docs/html/classSnakeGame.html b/docs/html/classSnakeGame.html new file mode 100644 index 00000000..b1d5bb56 --- /dev/null +++ b/docs/html/classSnakeGame.html @@ -0,0 +1,251 @@ + + + + + + + +LogDoctor: SnakeGame Class Reference + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
+ +

Snake. + More...

+ +

#include <game.h>

+
+Inheritance diagram for SnakeGame:
+
+
+ +
+ + + + + +

+Private Types

enum  GameMode { Classic +, Hunt +, Battle + }
 Enumerates the available game modes. More...
 
+ + + + +

+Private Slots

+void processGameLogic ()
 Processes the logic of the game.
 
+ + + + + + + + + + + + + +

+Private Member Functions

void keyPressEvent (QKeyEvent *event) override
 Stores the valid key events in a queue. More...
 
void processNextKeyEvent ()
 Processes the key events in the queue. More...
 
+void checkCollision (Snake &snake, Snake &adv_snake, const bool &is_adv)
 Checks if a snake will collide with another entity.
 
+void updateGameScore ()
 Increases/Decreases the player's score by one.
 
+ + + + + + + + + + + + + +

+Private Attributes

+std::queue< unsigned short > key_events
 Stores the key events.
 
+const unsigned int MAX_SNAKE_LENGTH = 64
 The maximum length of the snake.
 
+Snake snake
 The snake.
 
+Food food
 Instance of the egg/rat which will be eat by the snake.
 
+

Detailed Description

+

Snake.

+

A reproduction of the timeless classic game

+

Member Enumeration Documentation

+ +

◆ GameMode

+ +
+
+ + + + + +
+ + + + +
enum SnakeGame::GameMode
+
+private
+
+ +

Enumerates the available game modes.

+ + + + +
Enumerator
Classic 

Classic snake game.

+
Hunt 

Game variant in which the food moves too.

+
Battle 

Game variant in which you play against another snake.

+
+ +
+
+

Member Function Documentation

+ +

◆ keyPressEvent()

+ +
+
+ + + + + +
+ + + + + + + + +
void SnakeGame::keyPressEvent (QKeyEvent * event)
+
+overrideprivate
+
+ +

Stores the valid key events in a queue.

+

Valid keys are UP/DOWN/LEFT/RIGHT arrows and W/S/A/D letters

See also
key_events, processNextKeyEvent()
+ +
+
+ +

◆ processNextKeyEvent()

+ +
+
+ + + + + +
+ + + + + + + +
void SnakeGame::processNextKeyEvent ()
+
+private
+
+ +

Processes the key events in the queue.

+
See also
key_events, keyPressEvent()
+ +
+
+
The documentation for this class was generated from the following files:
    +
  • logdoctor/games/snake/game.h
  • +
  • logdoctor/games/snake/game.cpp
  • +
+
+ + + + diff --git a/docs/html/classSnakeGame.png b/docs/html/classSnakeGame.png new file mode 100644 index 00000000..5d5b9e73 Binary files /dev/null and b/docs/html/classSnakeGame.png differ diff --git a/docs/html/classStoreOps-members.html b/docs/html/classStoreOps-members.html new file mode 100644 index 00000000..c87b3cad --- /dev/null +++ b/docs/html/classStoreOps-members.html @@ -0,0 +1,87 @@ + + + + + + + +LogDoctor: Member List + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
+
StoreOps Member List
+
+
+ +

This is the complete list of members for StoreOps, including all inherited members.

+ + +
storeData(QSqlDatabase &db, Craplog &craplog, const std::vector< std::unordered_map< int, std::string > > &data)StoreOpsstatic
+ + + + diff --git a/docs/html/classStoreOps.html b/docs/html/classStoreOps.html new file mode 100644 index 00000000..ebfa74fc --- /dev/null +++ b/docs/html/classStoreOps.html @@ -0,0 +1,165 @@ + + + + + + + +LogDoctor: StoreOps Class Reference + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
+ +
StoreOps Class Reference
+
+
+ +

StoreOps. + More...

+ +

#include <store.h>

+ + + + + +

+Static Public Member Functions

static bool storeData (QSqlDatabase &db, Craplog &craplog, const std::vector< std::unordered_map< int, std::string > > &data)
 Stores the data collection in the logs Collection database. More...
 
+

Detailed Description

+

StoreOps.

+

Operations to store logs data

+

Member Function Documentation

+ +

◆ storeData()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
bool StoreOps::storeData (QSqlDatabase & db,
Craplogcraplog,
const std::vector< std::unordered_map< int, std::string > > & data 
)
+
+static
+
+ +

Stores the data collection in the logs Collection database.

+
Parameters
+ + + + +
dbA database instance, already initizlized
craplogThe Craplog instance
dataThe logs data collection
+
+
+
Returns
Whether the operation has been successful or not
+
Exceptions
+ + +
WebServerException
+
+
+ +
+
+
The documentation for this class was generated from the following files:
    +
  • logdoctor/modules/craplog/modules/store.h
  • +
  • logdoctor/modules/craplog/modules/store.cpp
  • +
+
+ + + + diff --git a/docs/html/classStringOps-members.html b/docs/html/classStringOps-members.html new file mode 100644 index 00000000..3eb3421a --- /dev/null +++ b/docs/html/classStringOps-members.html @@ -0,0 +1,108 @@ + + + + + + + +LogDoctor: Member List + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
+
StringOps Member List
+
+
+ +

This is the complete list of members for StringOps, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + +
contains(const std::string &str, const std::string &flag)StringOpsstatic
count(const std::string &str, const std::string &flag, const bool &consecutives=true)StringOpsstatic
endsWith(const std::string &str, const std::string &flag)StringOpsstatic
findLast(const std::string &str, const std::string &flag)StringOpsstatic
isAlnum(const std::string &str)StringOpsstatic
isAlnum(const unsigned char &chr)StringOpsstatic
isAlphabetic(const std::string &str)StringOpsstatic
isAlphabetic(const unsigned char &chr)StringOpsstatic
isHex(const unsigned char &chr)StringOpsstatic
isIP(const std::string &str)StringOpsstatic
isNumeric(const std::string &str)StringOpsstatic
isNumeric(const unsigned char &chr)StringOpsstatic
lstrip(const std::string &str, const std::string &chars=" \n\t\b\r\v")StringOpsstatic
lstripUntil(const std::string &str, const std::string &chr, const bool &inclusive=true, const bool &consecutives=true)StringOpsstatic
replace(const std::string &str, const std::string &target, const std::string &replace)StringOpsstatic
rstrip(const std::string &str, const std::string &chars=" \n\t\b\r\v")StringOpsstatic
split(std::vector< std::string > &list, const std::string &target_str, const std::string &separator="\n")StringOpsstatic
splitrip(std::vector< std::string > &list, const std::string &target_str, const std::string &separator="\n", const std::string &strip=" \n\t\b\r\v")StringOpsstatic
startsWith(const std::string &str, const std::string &flag)StringOpsstatic
strip(const std::string &str, const std::string &chars=" \n\t\b\r\v")StringOpsstatic
toLower(const std::string &str)StringOpsstatic
toUpper(const std::string &str)StringOpsstatic
+ + + + diff --git a/docs/html/classStringOps.html b/docs/html/classStringOps.html new file mode 100644 index 00000000..26657da1 --- /dev/null +++ b/docs/html/classStringOps.html @@ -0,0 +1,1119 @@ + + + + + + + +LogDoctor: StringOps Class Reference + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
+ +
StringOps Class Reference
+
+
+ +

StringOps. + More...

+ +

#include <strings.h>

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Static Public Member Functions

static const int count (const std::string &str, const std::string &flag, const bool &consecutives=true)
 Count the occurrences of the given sequence in the given string. More...
 
static const bool isNumeric (const std::string &str)
 Checks whether a string only contains numeric characters. More...
 
static const bool isNumeric (const unsigned char &chr)
 Checks whether character is numeric. More...
 
static const bool isAlphabetic (const std::string &str)
 Checks whether a string only contains alphabetic characters. More...
 
static const bool isAlphabetic (const unsigned char &chr)
 Checks whether a character is alphabetic. More...
 
static const bool isAlnum (const std::string &str)
 Checks whether a string only contains alpha-numeric characters. More...
 
static const bool isAlnum (const unsigned char &chr)
 Checks whether a character is alpha-numeric. More...
 
static const bool isHex (const unsigned char &chr)
 Checks whether a string only contains hexadecimal characters. More...
 
static const bool isIP (const std::string &str)
 Checks whether a string could be a valid IPv4/IPv6. More...
 
static const size_t findLast (const std::string &str, const std::string &flag)
 Finds the last occurrence of the given sequence in the given string. More...
 
static const bool startsWith (const std::string &str, const std::string &flag)
 Checks if a string starts with the given sequence. More...
 
static const bool endsWith (const std::string &str, const std::string &flag)
 Checks if a string ends with the given sequence. More...
 
static const bool contains (const std::string &str, const std::string &flag)
 Checks if a string contains the given sequence. More...
 
static std::string strip (const std::string &str, const std::string &chars=" \n\t\b\r\v")
 Strips the given characters from both the left and the right side of a string. More...
 
static std::string lstrip (const std::string &str, const std::string &chars=" \n\t\b\r\v")
 Strips the given characters from the left side of a string. More...
 
static std::string rstrip (const std::string &str, const std::string &chars=" \n\t\b\r\v")
 Strips the given characters from the right side of a string. More...
 
static std::string lstripUntil (const std::string &str, const std::string &chr, const bool &inclusive=true, const bool &consecutives=true)
 Strips everything from a string starting from the left side untill the delimiter is found (a.k.a. cut) More...
 
static void split (std::vector< std::string > &list, const std::string &target_str, const std::string &separator="\n")
 Splits a string using a separator. More...
 
static void splitrip (std::vector< std::string > &list, const std::string &target_str, const std::string &separator="\n", const std::string &strip=" \n\t\b\r\v")
 Splits a string and strips all the splitted items. More...
 
static const std::string replace (const std::string &str, const std::string &target, const std::string &replace)
 Replaces all the occurrences of a sequence with another. More...
 
static const std::string toUpper (const std::string &str)
 Converts a string to upper case. More...
 
static const std::string toLower (const std::string &str)
 Converts a string to lower case. More...
 
+

Detailed Description

+

StringOps.

+

Utilities for the strings

+

Member Function Documentation

+ +

◆ contains()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
const bool StringOps::contains (const std::string & str,
const std::string & flag 
)
+
+static
+
+ +

Checks if a string contains the given sequence.

+
Parameters
+ + + +
strThe target string
flagThe sequence to search for
+
+
+
Returns
The result of the check
+ +
+
+ +

◆ count()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
const int StringOps::count (const std::string & str,
const std::string & flag,
const bool & consecutives = true 
)
+
+static
+
+ +

Count the occurrences of the given sequence in the given string.

+
Parameters
+ + +
strThe target string
+
+
+
Returns
The number of occurrences
+ +
+
+ +

◆ endsWith()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
const bool StringOps::endsWith (const std::string & str,
const std::string & flag 
)
+
+static
+
+ +

Checks if a string ends with the given sequence.

+
Parameters
+ + + +
strThe target string
flagThe sequence to search for
+
+
+
Returns
The result of the check
+ +
+
+ +

◆ findLast()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
const size_t StringOps::findLast (const std::string & str,
const std::string & flag 
)
+
+static
+
+ +

Finds the last occurrence of the given sequence in the given string.

+
Parameters
+ + + +
strThe target string
flagThe sequence to search for
+
+
+
Returns
The position of the last occurrence
+ +
+
+ +

◆ isAlnum() [1/2]

+ +
+
+ + + + + +
+ + + + + + + + +
const bool StringOps::isAlnum (const std::string & str)
+
+static
+
+ +

Checks whether a string only contains alpha-numeric characters.

+
Parameters
+ + +
strThe target string
+
+
+
Returns
The result of the check
+ +
+
+ +

◆ isAlnum() [2/2]

+ +
+
+ + + + + +
+ + + + + + + + +
const bool StringOps::isAlnum (const unsigned char & chr)
+
+static
+
+ +

Checks whether a character is alpha-numeric.

+
Parameters
+ + +
strThe target character
+
+
+
Returns
The result of the check
+
See also
isAlnum
+ +
+
+ +

◆ isAlphabetic() [1/2]

+ +
+
+ + + + + +
+ + + + + + + + +
const bool StringOps::isAlphabetic (const std::string & str)
+
+static
+
+ +

Checks whether a string only contains alphabetic characters.

+
Parameters
+ + +
strThe target string
+
+
+
Returns
The result of the check
+ +
+
+ +

◆ isAlphabetic() [2/2]

+ +
+
+ + + + + +
+ + + + + + + + +
const bool StringOps::isAlphabetic (const unsigned char & chr)
+
+static
+
+ +

Checks whether a character is alphabetic.

+
Parameters
+ + +
strThe target character
+
+
+
Returns
The result of the check
+
See also
isAlphabetic()
+ +
+
+ +

◆ isHex()

+ +
+
+ + + + + +
+ + + + + + + + +
const bool StringOps::isHex (const unsigned char & chr)
+
+static
+
+ +

Checks whether a string only contains hexadecimal characters.

+
Parameters
+ + +
strThe target character
+
+
+
Returns
The result of the check
+ +
+
+ +

◆ isIP()

+ +
+
+ + + + + +
+ + + + + + + + +
const bool StringOps::isIP (const std::string & str)
+
+static
+
+ +

Checks whether a string could be a valid IPv4/IPv6.

+
Parameters
+ + +
strThe target string
+
+
+
Returns
The result of the check
+ +
+
+ +

◆ isNumeric() [1/2]

+ +
+
+ + + + + +
+ + + + + + + + +
const bool StringOps::isNumeric (const std::string & str)
+
+static
+
+ +

Checks whether a string only contains numeric characters.

+
Parameters
+ + +
strThe target string
+
+
+
Returns
The result of the check
+ +
+
+ +

◆ isNumeric() [2/2]

+ +
+
+ + + + + +
+ + + + + + + + +
const bool StringOps::isNumeric (const unsigned char & chr)
+
+static
+
+ +

Checks whether character is numeric.

+
Parameters
+ + +
strThe target character
+
+
+
Returns
The result of the check
+
See also
isNumeric()
+ +
+
+ +

◆ lstrip()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
std::string StringOps::lstrip (const std::string & str,
const std::string & chars = " \n\t\b\r\v" 
)
+
+static
+
+ +

Strips the given characters from the left side of a string.

+
Parameters
+ + + +
strThe target string
charsThe characters to strip away
+
+
+
Returns
The result string
+ +
+
+ +

◆ lstripUntil()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
std::string StringOps::lstripUntil (const std::string & str,
const std::string & chr,
const bool & inclusive = true,
const bool & consecutives = true 
)
+
+static
+
+ +

Strips everything from a string starting from the left side untill the delimiter is found (a.k.a. cut)

+
Parameters
+ + + + + +
strThe target string
chrThe delimiter
inclusiveWhether to also strip the delimiter or not
consecutivesWhether to strip all the occurrences of the delimiter if they're consecutive
+
+
+
Returns
The result string
+ +
+
+ +

◆ replace()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
const std::string StringOps::replace (const std::string & str,
const std::string & target,
const std::string & replace 
)
+
+static
+
+ +

Replaces all the occurrences of a sequence with another.

+
Parameters
+ + + + +
strThe target string
targetThe sequence which will be replaced
replaceThe sequence to be used to replace the target
+
+
+
Returns
The result string
+ +
+
+ +

◆ rstrip()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
std::string StringOps::rstrip (const std::string & str,
const std::string & chars = " \n\t\b\r\v" 
)
+
+static
+
+ +

Strips the given characters from the right side of a string.

+
Parameters
+ + + +
strThe target string
charsThe characters to strip away
+
+
+
Returns
The result string
+ +
+
+ +

◆ split()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
void StringOps::split (std::vector< std::string > & list,
const std::string & target_str,
const std::string & separator = "\n" 
)
+
+static
+
+ +

Splits a string using a separator.

+
Parameters
+ + + + +
listWill hold the splitted content
target_strThe target string
separatorThe sequence to use as separator
+
+
+ +
+
+ +

◆ splitrip()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void StringOps::splitrip (std::vector< std::string > & list,
const std::string & target_str,
const std::string & separator = "\n",
const std::string & strip = " \n\t\b\r\v" 
)
+
+static
+
+ +

Splits a string and strips all the splitted items.

+
Parameters
+ + + + + +
listWill hold the splitted content
target_strThe target string
separatorThe sequence to use as separator
stripThe characters to strip away
+
+
+ +
+
+ +

◆ startsWith()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
const bool StringOps::startsWith (const std::string & str,
const std::string & flag 
)
+
+static
+
+ +

Checks if a string starts with the given sequence.

+
Parameters
+ + + +
strThe target string
flagThe sequence to search for
+
+
+
Returns
The result of the check
+ +
+
+ +

◆ strip()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
std::string StringOps::strip (const std::string & str,
const std::string & chars = " \n\t\b\r\v" 
)
+
+static
+
+ +

Strips the given characters from both the left and the right side of a string.

+
Parameters
+ + + +
strThe target string
charsThe characters to strip away
+
+
+
Returns
The result string
+ +
+
+ +

◆ toLower()

+ +
+
+ + + + + +
+ + + + + + + + +
const std::string StringOps::toLower (const std::string & str)
+
+static
+
+ +

Converts a string to lower case.

+
Parameters
+ + +
strThe target string
+
+
+
Returns
The result string
+ +
+
+ +

◆ toUpper()

+ +
+
+ + + + + +
+ + + + + + + + +
const std::string StringOps::toUpper (const std::string & str)
+
+static
+
+ +

Converts a string to upper case.

+
Parameters
+ + +
strThe target string
+
+
+
Returns
The result string
+ +
+
+
The documentation for this class was generated from the following files:
    +
  • logdoctor/utilities/strings.h
  • +
  • logdoctor/utilities/strings.cpp
  • +
+
+ + + + diff --git a/docs/html/classStyleSec-members.html b/docs/html/classStyleSec-members.html new file mode 100644 index 00000000..9b94dcbe --- /dev/null +++ b/docs/html/classStyleSec-members.html @@ -0,0 +1,88 @@ + + + + + + + +LogDoctor: Member List + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
+
StyleSec Member List
+
+
+ +

This is the complete list of members for StyleSec, including all inherited members.

+ + + +
getStyleSheet(QString &stylesheet, const QString &icons_theme, const int &theme_id)StyleSecstatic
makeStyleSheet(QString &ss, const std::unordered_map< std::string, QString > &style, const QString &theme)StyleSecprivatestatic
+ + + + diff --git a/docs/html/classStyleSec.html b/docs/html/classStyleSec.html new file mode 100644 index 00000000..435ec6dd --- /dev/null +++ b/docs/html/classStyleSec.html @@ -0,0 +1,217 @@ + + + + + + + +LogDoctor: StyleSec Class Reference + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
+ +

StyleSec. + More...

+ +

#include <stylesheets.h>

+ + + + + +

+Static Public Member Functions

static void getStyleSheet (QString &stylesheet, const QString &icons_theme, const int &theme_id)
 Provides the requested stylesheet. More...
 
+ + + + +

+Static Private Member Functions

static void makeStyleSheet (QString &ss, const std::unordered_map< std::string, QString > &style, const QString &theme)
 Builds the final stylesheet upon the generic model. More...
 
+

Detailed Description

+

StyleSec.

+

Utilities for the stylesheets

+

Member Function Documentation

+ +

◆ getStyleSheet()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
void StyleSec::getStyleSheet (QString & stylesheet,
const QString & icons_theme,
const int & theme_id 
)
+
+static
+
+ +

Provides the requested stylesheet.

+
Parameters
+ + + + +
stylesheetWill hold the stylesheet
icons_themeThe theme selected for the Icons
theme_idThe theme selected for the Window
+
+
+ +
+
+ +

◆ makeStyleSheet()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
void StyleSec::makeStyleSheet (QString & ss,
const std::unordered_map< std::string, QString > & style,
const QString & theme 
)
+
+staticprivate
+
+ +

Builds the final stylesheet upon the generic model.

+
Parameters
+ + + + +
ssWill hold the stylesheet
styleThe key-value pairs to be applied at the generic
themeThe theme selected for the Icons
+
+
+ +
+
+
The documentation for this class was generated from the following files:
    +
  • logdoctor/utilities/stylesheets.h
  • +
  • logdoctor/utilities/stylesheets.cpp
  • +
+
+ + + + diff --git a/docs/html/classTR-members.html b/docs/html/classTR-members.html new file mode 100644 index 00000000..0ea2a083 --- /dev/null +++ b/docs/html/classTR-members.html @@ -0,0 +1,85 @@ + + + + + + + +LogDoctor: Member List + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
+
TR Member List
+
+
+ +

This is the complete list of members for TR, including all inherited members.

+
+ + + + diff --git a/docs/html/classTR.html b/docs/html/classTR.html new file mode 100644 index 00000000..a6a4448d --- /dev/null +++ b/docs/html/classTR.html @@ -0,0 +1,103 @@ + + + + + + + +LogDoctor: TR Class Reference + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
+ +
TR Class Reference
+
+
+ +

TR. + More...

+ +

#include <shared.h>

+
+Inheritance diagram for TR:
+
+
+ +
+

Detailed Description

+

TR.

+

Fictitious class for the translations

+

The documentation for this class was generated from the following files:
    +
  • logdoctor/modules/shared.h
  • +
  • logdoctor/modules/shared.cpp
  • +
+
+ + + + diff --git a/docs/html/classTR.png b/docs/html/classTR.png new file mode 100644 index 00000000..528759ec Binary files /dev/null and b/docs/html/classTR.png differ diff --git a/docs/html/classTextBrowser-members.html b/docs/html/classTextBrowser-members.html new file mode 100644 index 00000000..2b4d189a --- /dev/null +++ b/docs/html/classTextBrowser-members.html @@ -0,0 +1,95 @@ + + + + + + + +LogDoctor: Member List + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
+
TextBrowser Member List
+
+
+ +

This is the complete list of members for TextBrowser, including all inherited members.

+ + + + + + + + + + +
getColorScheme()TextBrowser
getColorSchemeID()TextBrowser
getFont()TextBrowser
getFontFamily()TextBrowser
getWideLinesUsage()TextBrowser
makePreview(QString &content)TextBrowser
setColorScheme(const int &color_scheme_id, const std::unordered_map< std::string, QString > &color_scheme)TextBrowser
setFont(const QFont &font)TextBrowser
setWideLinesUsage(const bool &use_wide_lines)TextBrowser
+ + + + diff --git a/docs/html/classTextBrowser.html b/docs/html/classTextBrowser.html new file mode 100644 index 00000000..dd79b716 --- /dev/null +++ b/docs/html/classTextBrowser.html @@ -0,0 +1,164 @@ + + + + + + + +LogDoctor: TextBrowser Class Reference + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
+ +
TextBrowser Class Reference
+
+
+ +

TextBrowser. + More...

+ +

#include <tb.h>

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

+const bool & getWideLinesUsage ()
 Returns whether the wide lines option is set to be used or not.
 
+const int & getColorSchemeID ()
 Returns the ID of the color scheme in use.
 
+const std::unordered_map< std::string, QString > & getColorScheme ()
 Returns the color scheme in use.
 
+const QString & getFontFamily ()
 Returns the family of the font in use.
 
+const QFont & getFont ()
 Returns the font in use.
 
+void setWideLinesUsage (const bool &use_wide_lines)
 Sets whether to use wide lines or not.
 
+void setColorScheme (const int &color_scheme_id, const std::unordered_map< std::string, QString > &color_scheme)
 Stes the given color scheme as the one in use.
 
+void setFont (const QFont &font)
 Sets the given font as the one in use.
 
void makePreview (QString &content)
 Builds the preview which will be shown in the configs tab. More...
 
+

Detailed Description

+

TextBrowser.

+

Perform operations for files visualization

+

Member Function Documentation

+ +

◆ makePreview()

+ +
+
+ + + + + + + + +
void TextBrowser::makePreview (QString & content)
+
+ +

Builds the preview which will be shown in the configs tab.

+
Parameters
+ + +
contentWill hold the preview string
+
+
+ +
+
+
The documentation for this class was generated from the following files:
    +
  • logdoctor/modules/tb.h
  • +
  • logdoctor/modules/tb.cpp
  • +
+
+ + + + diff --git a/docs/html/classVecOps-members.html b/docs/html/classVecOps-members.html new file mode 100644 index 00000000..cc344ae3 --- /dev/null +++ b/docs/html/classVecOps-members.html @@ -0,0 +1,87 @@ + + + + + + + +LogDoctor: Member List + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
+
VecOps< T > Member List
+
+
+ +

This is the complete list of members for VecOps< T >, including all inherited members.

+ + +
contains(const std::vector< T > &list, const T &flag)VecOps< T >static
+ + + + diff --git a/docs/html/classVecOps.html b/docs/html/classVecOps.html new file mode 100644 index 00000000..c0d89cdd --- /dev/null +++ b/docs/html/classVecOps.html @@ -0,0 +1,155 @@ + + + + + + + +LogDoctor: VecOps< T > Class Template Reference + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
+ +
VecOps< T > Class Template Reference
+
+
+ +

VecOps. + More...

+ +

#include <vectors.h>

+ + + + + +

+Static Public Member Functions

static const bool contains (const std::vector< T > &list, const T &flag)
 Checks if a vector contains an element. More...
 
+

Detailed Description

+
template<typename T>
+class VecOps< T >

VecOps.

+

Utilities for the vectors

+

Member Function Documentation

+ +

◆ contains()

+ +
+
+
+template<typename T >
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
const bool VecOps< T >::contains (const std::vector< T > & list,
const T & flag 
)
+
+static
+
+ +

Checks if a vector contains an element.

+
Parameters
+ + + +
listThe target vector
flagThe element to search for
+
+
+
Returns
Whether the list does contain the flag or not
+ +
+
+
The documentation for this class was generated from the following files:
    +
  • logdoctor/utilities/vectors.h
  • +
  • logdoctor/utilities/vectors.cpp
  • +
+
+ + + + diff --git a/docs/html/classWebServerException-members.html b/docs/html/classWebServerException-members.html new file mode 100644 index 00000000..5de27a2a --- /dev/null +++ b/docs/html/classWebServerException-members.html @@ -0,0 +1,85 @@ + + + + + + + +LogDoctor: Member List + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
+
WebServerException Member List
+
+
+ +

This is the complete list of members for WebServerException, including all inherited members.

+
+ + + + diff --git a/docs/html/classWebServerException.html b/docs/html/classWebServerException.html new file mode 100644 index 00000000..39e4af63 --- /dev/null +++ b/docs/html/classWebServerException.html @@ -0,0 +1,103 @@ + + + + + + + +LogDoctor: WebServerException Class Reference + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
+ +
WebServerException Class Reference
+
+
+ +

WebServerException. + More...

+ +

#include <exceptions.h>

+
+Inheritance diagram for WebServerException:
+
+
+ +
+

Detailed Description

+

WebServerException.

+

Exception related to a Web Server

+

The documentation for this class was generated from the following files:
    +
  • logdoctor/modules/exceptions.h
  • +
  • logdoctor/modules/exceptions.cpp
  • +
+
+ + + + diff --git a/docs/html/classWebServerException.png b/docs/html/classWebServerException.png new file mode 100644 index 00000000..214e6aab Binary files /dev/null and b/docs/html/classWebServerException.png differ diff --git a/docs/html/classes.html b/docs/html/classes.html new file mode 100644 index 00000000..c7c1f3c6 --- /dev/null +++ b/docs/html/classes.html @@ -0,0 +1,128 @@ + + + + + + + +LogDoctor: Class Index + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Class Index
+
+ + + + + diff --git a/docs/html/closed.png b/docs/html/closed.png new file mode 100644 index 00000000..98cc2c90 Binary files /dev/null and b/docs/html/closed.png differ diff --git a/docs/html/dir_01fec9b22571a82eb07ead4e65bff8c5.html b/docs/html/dir_01fec9b22571a82eb07ead4e65bff8c5.html new file mode 100644 index 00000000..442c252c --- /dev/null +++ b/docs/html/dir_01fec9b22571a82eb07ead4e65bff8c5.html @@ -0,0 +1,87 @@ + + + + + + + +LogDoctor: logdoctor/modules/dialogs Directory Reference + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ + +
+
+
dialogs Directory Reference
+
+
+
+ + + + diff --git a/docs/html/dir_04e1f2400eed58ce238b4e46b2304549.html b/docs/html/dir_04e1f2400eed58ce238b4e46b2304549.html new file mode 100644 index 00000000..a2cee867 --- /dev/null +++ b/docs/html/dir_04e1f2400eed58ce238b4e46b2304549.html @@ -0,0 +1,87 @@ + + + + + + + +LogDoctor: logdoctor/tools/crapnote Directory Reference + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ + +
+
+
crapnote Directory Reference
+
+
+
+ + + + diff --git a/docs/html/dir_166af4970eb35776782da3373b1769ca.html b/docs/html/dir_166af4970eb35776782da3373b1769ca.html new file mode 100644 index 00000000..c9e45508 --- /dev/null +++ b/docs/html/dir_166af4970eb35776782da3373b1769ca.html @@ -0,0 +1,103 @@ + + + + + + + +LogDoctor: logdoctor/modules Directory Reference + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ + +
+
+
modules Directory Reference
+
+
+ + + + + + + + + + + + + + +

+Directories

directory  craphelp
 
directory  crapinfo
 
directory  craplog
 
directory  crapup
 
directory  crapview
 
directory  dialogs
 
+
+ + + + diff --git a/docs/html/dir_3a0bb91303b349fae8fa9b3a632cefff.html b/docs/html/dir_3a0bb91303b349fae8fa9b3a632cefff.html new file mode 100644 index 00000000..c144c3fc --- /dev/null +++ b/docs/html/dir_3a0bb91303b349fae8fa9b3a632cefff.html @@ -0,0 +1,95 @@ + + + + + + + +LogDoctor: logdoctor/games Directory Reference + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ + +
+
+
games Directory Reference
+
+
+ + + + + + +

+Directories

directory  crisscross
 
directory  snake
 
+
+ + + + diff --git a/docs/html/dir_4216b1c8c447536616ff22cc879c2748.html b/docs/html/dir_4216b1c8c447536616ff22cc879c2748.html new file mode 100644 index 00000000..6eeb06cb --- /dev/null +++ b/docs/html/dir_4216b1c8c447536616ff22cc879c2748.html @@ -0,0 +1,87 @@ + + + + + + + +LogDoctor: logdoctor/games/snake Directory Reference + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ + +
+
+
snake Directory Reference
+
+
+
+ + + + diff --git a/docs/html/dir_64ab1cdb8c5cdc072070fa7afc65bdf3.html b/docs/html/dir_64ab1cdb8c5cdc072070fa7afc65bdf3.html new file mode 100644 index 00000000..ce6300b6 --- /dev/null +++ b/docs/html/dir_64ab1cdb8c5cdc072070fa7afc65bdf3.html @@ -0,0 +1,93 @@ + + + + + + + +LogDoctor: logdoctor/modules/crapview Directory Reference + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ + +
+
+
crapview Directory Reference
+
+
+ + + + +

+Directories

directory  modules
 
+
+ + + + diff --git a/docs/html/dir_7445445f1643ef41aafc7f4f0499cff7.html b/docs/html/dir_7445445f1643ef41aafc7f4f0499cff7.html new file mode 100644 index 00000000..22ffa667 --- /dev/null +++ b/docs/html/dir_7445445f1643ef41aafc7f4f0499cff7.html @@ -0,0 +1,87 @@ + + + + + + + +LogDoctor: logdoctor/modules/craplog/modules Directory Reference + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ + +
+
+
modules Directory Reference
+
+
+
+ + + + diff --git a/docs/html/dir_7cd0ceaf2658a97b0f7fba0138ff1b04.html b/docs/html/dir_7cd0ceaf2658a97b0f7fba0138ff1b04.html new file mode 100644 index 00000000..86849c1d --- /dev/null +++ b/docs/html/dir_7cd0ceaf2658a97b0f7fba0138ff1b04.html @@ -0,0 +1,93 @@ + + + + + + + +LogDoctor: logdoctor/tools Directory Reference + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ + +
+
+
tools Directory Reference
+
+
+ + + + +

+Directories

directory  crapnote
 
+
+ + + + diff --git a/docs/html/dir_89e090ef9a1797a727043bd31c22de25.html b/docs/html/dir_89e090ef9a1797a727043bd31c22de25.html new file mode 100644 index 00000000..32854b8b --- /dev/null +++ b/docs/html/dir_89e090ef9a1797a727043bd31c22de25.html @@ -0,0 +1,87 @@ + + + + + + + +LogDoctor: logdoctor/modules/crapup Directory Reference + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ + +
+
+
crapup Directory Reference
+
+
+
+ + + + diff --git a/docs/html/dir_9435ca5cf080eab6f8746f45b27d7231.html b/docs/html/dir_9435ca5cf080eab6f8746f45b27d7231.html new file mode 100644 index 00000000..9fcd4846 --- /dev/null +++ b/docs/html/dir_9435ca5cf080eab6f8746f45b27d7231.html @@ -0,0 +1,87 @@ + + + + + + + +LogDoctor: logdoctor/games/crisscross Directory Reference + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ + +
+
+
crisscross Directory Reference
+
+
+
+ + + + diff --git a/docs/html/dir_a74e11123a295a4e318d334da8a4cfdc.html b/docs/html/dir_a74e11123a295a4e318d334da8a4cfdc.html new file mode 100644 index 00000000..f511d85d --- /dev/null +++ b/docs/html/dir_a74e11123a295a4e318d334da8a4cfdc.html @@ -0,0 +1,97 @@ + + + + + + + +LogDoctor: logdoctor Directory Reference + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ + +
+
+
logdoctor Directory Reference
+
+
+ + + + + + + + +

+Directories

directory  games
 
directory  modules
 
directory  utilities
 
+
+ + + + diff --git a/docs/html/dir_aefa70d5835bf2f969448f72963649c1.html b/docs/html/dir_aefa70d5835bf2f969448f72963649c1.html new file mode 100644 index 00000000..25f3e7dc --- /dev/null +++ b/docs/html/dir_aefa70d5835bf2f969448f72963649c1.html @@ -0,0 +1,93 @@ + + + + + + + +LogDoctor: logdoctor/modules/craplog Directory Reference + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ + +
+
+
craplog Directory Reference
+
+
+ + + + +

+Directories

directory  modules
 
+
+ + + + diff --git a/docs/html/dir_b7610c71fd3387c1581ad37fc5d3235c.html b/docs/html/dir_b7610c71fd3387c1581ad37fc5d3235c.html new file mode 100644 index 00000000..75b1fdf5 --- /dev/null +++ b/docs/html/dir_b7610c71fd3387c1581ad37fc5d3235c.html @@ -0,0 +1,87 @@ + + + + + + + +LogDoctor: logdoctor/utilities Directory Reference + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ + +
+
+
utilities Directory Reference
+
+
+
+ + + + diff --git a/docs/html/dir_bd0b3fdb9d3141a0d22a74c2c6a59ffc.html b/docs/html/dir_bd0b3fdb9d3141a0d22a74c2c6a59ffc.html new file mode 100644 index 00000000..4d78139e --- /dev/null +++ b/docs/html/dir_bd0b3fdb9d3141a0d22a74c2c6a59ffc.html @@ -0,0 +1,87 @@ + + + + + + + +LogDoctor: logdoctor/modules/crapview/modules Directory Reference + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ + +
+
+
modules Directory Reference
+
+
+
+ + + + diff --git a/docs/html/dir_eed7e567d564c10631ac4772551893e5.html b/docs/html/dir_eed7e567d564c10631ac4772551893e5.html new file mode 100644 index 00000000..3db78cad --- /dev/null +++ b/docs/html/dir_eed7e567d564c10631ac4772551893e5.html @@ -0,0 +1,87 @@ + + + + + + + +LogDoctor: logdoctor/modules/crapinfo Directory Reference + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ + +
+
+
crapinfo Directory Reference
+
+
+
+ + + + diff --git a/docs/html/dir_fc12ceffd2563856433d7c178b8ff976.html b/docs/html/dir_fc12ceffd2563856433d7c178b8ff976.html new file mode 100644 index 00000000..40e05228 --- /dev/null +++ b/docs/html/dir_fc12ceffd2563856433d7c178b8ff976.html @@ -0,0 +1,87 @@ + + + + + + + +LogDoctor: logdoctor/modules/craphelp Directory Reference + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ + +
+
+
craphelp Directory Reference
+
+
+
+ + + + diff --git a/docs/html/doc.png b/docs/html/doc.png new file mode 100644 index 00000000..17edabff Binary files /dev/null and b/docs/html/doc.png differ diff --git a/docs/html/docd.png b/docs/html/docd.png new file mode 100644 index 00000000..d7c94fda Binary files /dev/null and b/docs/html/docd.png differ diff --git a/docs/html/doxygen.css b/docs/html/doxygen.css new file mode 100644 index 00000000..89dee6c4 --- /dev/null +++ b/docs/html/doxygen.css @@ -0,0 +1,1973 @@ +/* The standard CSS for doxygen 1.9.5*/ + +html { +/* page base colors */ +--page-background-color: white; +--page-foreground-color: black; +--page-link-color: #3D578C; +--page-visited-link-color: #4665A2; + +/* index */ +--index-odd-item-bg-color: #F8F9FC; +--index-even-item-bg-color: white; +--index-header-color: black; +--index-separator-color: #A0A0A0; + +/* header */ +--header-background-color: #F9FAFC; +--header-separator-color: #C4CFE5; +--header-gradient-image: url('nav_h.png'); +--group-header-separator-color: #879ECB; +--group-header-color: #354C7B; +--inherit-header-color: gray; + +--footer-foreground-color: #2A3D61; +--footer-logo-width: 104px; +--citation-label-color: #334975; +--glow-color: cyan; + +--title-background-color: white; +--title-separator-color: #5373B4; +--directory-separator-color: #9CAFD4; +--separator-color: #4A6AAA; + +--blockquote-background-color: #F7F8FB; +--blockquote-border-color: #9CAFD4; + +--scrollbar-thumb-color: #9CAFD4; +--scrollbar-background-color: #F9FAFC; + +--icon-background-color: #728DC1; +--icon-foreground-color: white; +--icon-doc-image: url('doc.png'); + +/* brief member declaration list */ +--memdecl-background-color: #F9FAFC; +--memdecl-separator-color: #DEE4F0; +--memdecl-foreground-color: #555; +--memdecl-template-color: #4665A2; + +/* detailed member list */ +--memdef-border-color: #A8B8D9; +--memdef-title-background-color: #E2E8F2; +--memdef-title-gradient-image: url('nav_f.png'); +--memdef-proto-background-color: #DFE5F1; +--memdef-proto-text-color: #253555; +--memdef-proto-text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9); +--memdef-doc-background-color: white; +--memdef-param-name-color: #602020; +--memdef-template-color: #4665A2; + +/* tables */ +--table-cell-border-color: #2D4068; +--table-header-background-color: #374F7F; +--table-header-foreground-color: #FFFFFF; + +/* labels */ +--label-background-color: #728DC1; +--label-left-top-border-color: #5373B4; +--label-right-bottom-border-color: #C4CFE5; +--label-foreground-color: white; + +/** navigation bar/tree/menu */ +--nav-background-color: #F9FAFC; +--nav-foreground-color: #364D7C; +--nav-gradient-image: url('tab_b.png'); +--nav-gradient-hover-image: url('tab_h.png'); +--nav-gradient-active-image: url('tab_a.png'); +--nav-gradient-active-image-parent: url("../tab_a.png"); +--nav-separator-image: url('tab_s.png'); +--nav-breadcrumb-image: url('bc_s.png'); +--nav-breadcrumb-border-color: #C2CDE4; +--nav-splitbar-image: url('splitbar.png'); +--nav-font-size-level1: 13px; +--nav-font-size-level2: 10px; +--nav-font-size-level3: 9px; +--nav-text-normal-color: #283A5D; +--nav-text-hover-color: white; +--nav-text-active-color: white; +--nav-text-normal-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9); +--nav-text-hover-shadow: 0px 1px 1px rgba(0, 0, 0, 1.0); +--nav-text-active-shadow: 0px 1px 1px rgba(0, 0, 0, 1.0); +--nav-menu-button-color: #364D7C; +--nav-menu-background-color: white; +--nav-menu-foreground-color: #555555; +--nav-menu-toggle-color: rgba(255, 255, 255, 0.5); +--nav-arrow-color: #9CAFD4; +--nav-arrow-selected-color: #9CAFD4; + +/* table of contents */ +--toc-background-color: #F4F6FA; +--toc-border-color: #D8DFEE; +--toc-header-color: #4665A2; + +/** search field */ +--search-background-color: white; +--search-foreground-color: #909090; +--search-magnification-image: url('mag.svg'); +--search-magnification-select-image: url('mag_sel.svg'); +--search-active-color: black; +--search-filter-background-color: #F9FAFC; +--search-filter-foreground-color: black; +--search-filter-border-color: #90A5CE; +--search-filter-highlight-text-color: white; +--search-filter-highlight-bg-color: #3D578C; +--search-results-foreground-color: #425E97; +--search-results-background-color: #EEF1F7; +--search-results-border-color: black; +--search-box-shadow: inset 0.5px 0.5px 3px 0px #555; + +/** code fragments */ +--code-keyword-color: #008000; +--code-type-keyword-color: #604020; +--code-flow-keyword-color: #E08000; +--code-comment-color: #800000; +--code-preprocessor-color: #806020; +--code-string-literal-color: #002080; +--code-char-literal-color: #008080; +--code-vhdl-digit-color: #FF00FF; +--code-vhdl-char-color: #000000; +--code-vhdl-keyword-color: #700070; +--code-vhdl-logic-color: #FF0000; +--code-link-color: #4665A2; +--code-external-link-color: #4665A2; +--fragment-foreground-color: black; +--fragment-background-color: #FBFCFD; +--fragment-border-color: #C4CFE5; +--fragment-lineno-border-color: #00FF00; +--fragment-lineno-background-color: #E8E8E8; +--fragment-lineno-foreground-color: black; +--fragment-lineno-link-fg-color: #4665A2; +--fragment-lineno-link-bg-color: #D8D8D8; +--fragment-lineno-link-hover-fg-color: #4665A2; +--fragment-lineno-link-hover-bg-color: #C8C8C8; +--tooltip-foreground-color: black; +--tooltip-background-color: white; +--tooltip-border-color: gray; +--tooltip-doc-color: grey; +--tooltip-declaration-color: #006318; +--tooltip-link-color: #4665A2; +--tooltip-shadow: 1px 1px 7px gray; + +/** font-family */ +--font-family-normal: Roboto,sans-serif; +--font-family-monospace: monospace,fixed; +--font-family-nav: 'Lucida Grande',Geneva,Helvetica,Arial,sans-serif; +--font-family-title: Tahoma,Arial,sans-serif; +--font-family-toc: Verdana,'DejaVu Sans',Geneva,sans-serif; +--font-family-search: Arial,Verdana,sans-serif; +--font-family-icon: Arial,Helvetica; +--font-family-tooltip: Roboto,sans-serif; + +} + +@media (prefers-color-scheme: dark) { + html:not(.dark-mode) { + color-scheme: dark; + +/* page base colors */ +--page-background-color: black; +--page-foreground-color: #C9D1D9; +--page-link-color: #90A5CE; +--page-visited-link-color: #A3B4D7; + +/* index */ +--index-odd-item-bg-color: #0B101A; +--index-even-item-bg-color: black; +--index-header-color: #C4CFE5; +--index-separator-color: #334975; + +/* header */ +--header-background-color: #070B11; +--header-separator-color: #141C2E; +--header-gradient-image: url('nav_hd.png'); +--group-header-separator-color: #283A5D; +--group-header-color: #90A5CE; +--inherit-header-color: #A0A0A0; + +--footer-foreground-color: #5B7AB7; +--footer-logo-width: 60px; +--citation-label-color: #90A5CE; +--glow-color: cyan; + +--title-background-color: #090D16; +--title-separator-color: #354C79; +--directory-separator-color: #283A5D; +--separator-color: #283A5D; + +--blockquote-background-color: #101826; +--blockquote-border-color: #283A5D; + +--scrollbar-thumb-color: #283A5D; +--scrollbar-background-color: #070B11; + +--icon-background-color: #334975; +--icon-foreground-color: #C4CFE5; +--icon-doc-image: url('docd.png'); + +/* brief member declaration list */ +--memdecl-background-color: #0B101A; +--memdecl-separator-color: #2C3F65; +--memdecl-foreground-color: #BBB; +--memdecl-template-color: #7C95C6; + +/* detailed member list */ +--memdef-border-color: #233250; +--memdef-title-background-color: #1B2840; +--memdef-title-gradient-image: url('nav_fd.png'); +--memdef-proto-background-color: #19243A; +--memdef-proto-text-color: #9DB0D4; +--memdef-proto-text-shadow: 0px 1px 1px rgba(0, 0, 0, 0.9); +--memdef-doc-background-color: black; +--memdef-param-name-color: #D28757; +--memdef-template-color: #7C95C6; + +/* tables */ +--table-cell-border-color: #283A5D; +--table-header-background-color: #283A5D; +--table-header-foreground-color: #C4CFE5; + +/* labels */ +--label-background-color: #354C7B; +--label-left-top-border-color: #4665A2; +--label-right-bottom-border-color: #283A5D; +--label-foreground-color: #CCCCCC; + +/** navigation bar/tree/menu */ +--nav-background-color: #101826; +--nav-foreground-color: #364D7C; +--nav-gradient-image: url('tab_bd.png'); +--nav-gradient-hover-image: url('tab_hd.png'); +--nav-gradient-active-image: url('tab_ad.png'); +--nav-gradient-active-image-parent: url("../tab_ad.png"); +--nav-separator-image: url('tab_sd.png'); +--nav-breadcrumb-image: url('bc_sd.png'); +--nav-breadcrumb-border-color: #2A3D61; +--nav-splitbar-image: url('splitbard.png'); +--nav-font-size-level1: 13px; +--nav-font-size-level2: 10px; +--nav-font-size-level3: 9px; +--nav-text-normal-color: #B6C4DF; +--nav-text-hover-color: #DCE2EF; +--nav-text-active-color: #DCE2EF; +--nav-text-normal-shadow: 0px 1px 1px black; +--nav-text-hover-shadow: 0px 1px 1px rgba(0, 0, 0, 1.0); +--nav-text-active-shadow: 0px 1px 1px rgba(0, 0, 0, 1.0); +--nav-menu-button-color: #B6C4DF; +--nav-menu-background-color: #05070C; +--nav-menu-foreground-color: #BBBBBB; +--nav-menu-toggle-color: rgba(255, 255, 255, 0.2); +--nav-arrow-color: #334975; +--nav-arrow-selected-color: #90A5CE; + +/* table of contents */ +--toc-background-color: #151E30; +--toc-border-color: #202E4A; +--toc-header-color: #A3B4D7; + +/** search field */ +--search-background-color: black; +--search-foreground-color: #C5C5C5; +--search-magnification-image: url('mag_d.svg'); +--search-magnification-select-image: url('mag_seld.svg'); +--search-active-color: #C5C5C5; +--search-filter-background-color: #101826; +--search-filter-foreground-color: #90A5CE; +--search-filter-border-color: #7C95C6; +--search-filter-highlight-text-color: #BCC9E2; +--search-filter-highlight-bg-color: #283A5D; +--search-results-background-color: #101826; +--search-results-foreground-color: #90A5CE; +--search-results-border-color: #7C95C6; +--search-box-shadow: inset 0.5px 0.5px 3px 0px #2F436C; + +/** code fragments */ +--code-keyword-color: #CC99CD; +--code-type-keyword-color: #AB99CD; +--code-flow-keyword-color: #E08000; +--code-comment-color: #717790; +--code-preprocessor-color: #65CABE; +--code-string-literal-color: #7EC699; +--code-char-literal-color: #00E0F0; +--code-vhdl-digit-color: #FF00FF; +--code-vhdl-char-color: #000000; +--code-vhdl-keyword-color: #700070; +--code-vhdl-logic-color: #FF0000; +--code-link-color: #79C0FF; +--code-external-link-color: #79C0FF; +--fragment-foreground-color: #C9D1D9; +--fragment-background-color: black; +--fragment-border-color: #30363D; +--fragment-lineno-border-color: #30363D; +--fragment-lineno-background-color: black; +--fragment-lineno-foreground-color: #6E7681; +--fragment-lineno-link-fg-color: #6E7681; +--fragment-lineno-link-bg-color: #303030; +--fragment-lineno-link-hover-fg-color: #8E96A1; +--fragment-lineno-link-hover-bg-color: #505050; +--tooltip-foreground-color: #C9D1D9; +--tooltip-background-color: #202020; +--tooltip-border-color: #C9D1D9; +--tooltip-doc-color: #D9E1E9; +--tooltip-declaration-color: #20C348; +--tooltip-link-color: #79C0FF; +--tooltip-shadow: none; + +/** font-family */ +--font-family-normal: Roboto,sans-serif; +--font-family-monospace: monospace,fixed; +--font-family-nav: 'Lucida Grande',Geneva,Helvetica,Arial,sans-serif; +--font-family-title: Tahoma,Arial,sans-serif; +--font-family-toc: Verdana,'DejaVu Sans',Geneva,sans-serif; +--font-family-search: Arial,Verdana,sans-serif; +--font-family-icon: Arial,Helvetica; +--font-family-tooltip: Roboto,sans-serif; + +}} +body { + background-color: var(--page-background-color); + color: var(--page-foreground-color); + scrollbar-color: var(--scrollbar-thumb-color) var(--scrollbar-background-color); +} + +::-webkit-scrollbar { + background-color: var(--scrollbar-background-color); + height: 10px; + width: 10px; +} +::-webkit-scrollbar-thumb { + background-color: var(--scrollbar-thumb-color); + border-radius: 8px; +} +::-webkit-scrollbar-corner { + background-color: var(--scrollbar-background-color); +} + +body, table, div, p, dl { + font-weight: 400; + font-size: 14px; + font-family: var(--font-family-normal); + line-height: 22px; +} + +/* @group Heading Levels */ + +.title { + font-weight: 400; + font-size: 14px; + font-family: var(--font-family-normal); + line-height: 28px; + font-size: 150%; + font-weight: bold; + margin: 10px 2px; +} + +h1.groupheader { + font-size: 150%; +} + +h2.groupheader { + border-bottom: 1px solid var(--group-header-separator-color); + color: var(--group-header-color); + font-size: 150%; + font-weight: normal; + margin-top: 1.75em; + padding-top: 8px; + padding-bottom: 4px; + width: 100%; +} + +h3.groupheader { + font-size: 100%; +} + +h1, h2, h3, h4, h5, h6 { + -webkit-transition: text-shadow 0.5s linear; + -moz-transition: text-shadow 0.5s linear; + -ms-transition: text-shadow 0.5s linear; + -o-transition: text-shadow 0.5s linear; + transition: text-shadow 0.5s linear; + margin-right: 15px; +} + +h1.glow, h2.glow, h3.glow, h4.glow, h5.glow, h6.glow { + text-shadow: 0 0 15px var(--glow-color); +} + +dt { + font-weight: bold; +} + +p.startli, p.startdd { + margin-top: 2px; +} + +th p.starttd, th p.intertd, th p.endtd { + font-size: 100%; + font-weight: 700; +} + +p.starttd { + margin-top: 0px; +} + +p.endli { + margin-bottom: 0px; +} + +p.enddd { + margin-bottom: 4px; +} + +p.endtd { + margin-bottom: 2px; +} + +p.interli { +} + +p.interdd { +} + +p.intertd { +} + +/* @end */ + +caption { + font-weight: bold; +} + +span.legend { + font-size: 70%; + text-align: center; +} + +h3.version { + font-size: 90%; + text-align: center; +} + +div.navtab { + padding-right: 15px; + text-align: right; + line-height: 110%; +} + +div.navtab table { + border-spacing: 0; +} + +td.navtab { + padding-right: 6px; + padding-left: 6px; +} + +td.navtabHL { + background-image: var(--nav-gradient-active-image); + background-repeat:repeat-x; + padding-right: 6px; + padding-left: 6px; +} + +td.navtabHL a, td.navtabHL a:visited { + color: var(--nav-text-hover-color); + text-shadow: var(--nav-text-hover-shadow); +} + +a.navtab { + font-weight: bold; +} + +div.qindex{ + text-align: center; + width: 100%; + line-height: 140%; + font-size: 130%; + color: var(--index-separator-color); +} + +dt.alphachar{ + font-size: 180%; + font-weight: bold; +} + +.alphachar a{ + color: var(--index-header-color); +} + +.alphachar a:hover, .alphachar a:visited{ + text-decoration: none; +} + +.classindex dl { + padding: 25px; + column-count:1 +} + +.classindex dd { + display:inline-block; + margin-left: 50px; + width: 90%; + line-height: 1.15em; +} + +.classindex dl.even { + background-color: var(--index-even-item-bg-color); +} + +.classindex dl.odd { + background-color: var(--index-odd-item-bg-color); +} + +@media(min-width: 1120px) { + .classindex dl { + column-count:2 + } +} + +@media(min-width: 1320px) { + .classindex dl { + column-count:3 + } +} + + +/* @group Link Styling */ + +a { + color: var(--page-link-color); + font-weight: normal; + text-decoration: none; +} + +.contents a:visited { + color: var(--page-visited-link-color); +} + +a:hover { + text-decoration: underline; +} + +a.el { + font-weight: bold; +} + +a.elRef { +} + +a.code, a.code:visited, a.line, a.line:visited { + color: var(--code-link-color); +} + +a.codeRef, a.codeRef:visited, a.lineRef, a.lineRef:visited { + color: var(--code-external-link-color); +} + +a.code.hl_class { /* style for links to class names in code snippets */ } +a.code.hl_struct { /* style for links to struct names in code snippets */ } +a.code.hl_union { /* style for links to union names in code snippets */ } +a.code.hl_interface { /* style for links to interface names in code snippets */ } +a.code.hl_protocol { /* style for links to protocol names in code snippets */ } +a.code.hl_category { /* style for links to category names in code snippets */ } +a.code.hl_exception { /* style for links to exception names in code snippets */ } +a.code.hl_service { /* style for links to service names in code snippets */ } +a.code.hl_singleton { /* style for links to singleton names in code snippets */ } +a.code.hl_concept { /* style for links to concept names in code snippets */ } +a.code.hl_namespace { /* style for links to namespace names in code snippets */ } +a.code.hl_package { /* style for links to package names in code snippets */ } +a.code.hl_define { /* style for links to macro names in code snippets */ } +a.code.hl_function { /* style for links to function names in code snippets */ } +a.code.hl_variable { /* style for links to variable names in code snippets */ } +a.code.hl_typedef { /* style for links to typedef names in code snippets */ } +a.code.hl_enumvalue { /* style for links to enum value names in code snippets */ } +a.code.hl_enumeration { /* style for links to enumeration names in code snippets */ } +a.code.hl_signal { /* style for links to Qt signal names in code snippets */ } +a.code.hl_slot { /* style for links to Qt slot names in code snippets */ } +a.code.hl_friend { /* style for links to friend names in code snippets */ } +a.code.hl_dcop { /* style for links to KDE3 DCOP names in code snippets */ } +a.code.hl_property { /* style for links to property names in code snippets */ } +a.code.hl_event { /* style for links to event names in code snippets */ } +a.code.hl_sequence { /* style for links to sequence names in code snippets */ } +a.code.hl_dictionary { /* style for links to dictionary names in code snippets */ } + +/* @end */ + +dl.el { + margin-left: -1cm; +} + +ul { + overflow: visible; +} + +#side-nav ul { + overflow: visible; /* reset ul rule for scroll bar in GENERATE_TREEVIEW window */ +} + +#main-nav ul { + overflow: visible; /* reset ul rule for the navigation bar drop down lists */ +} + +.fragment { + text-align: left; + direction: ltr; + overflow-x: auto; /*Fixed: fragment lines overlap floating elements*/ + overflow-y: hidden; +} + +pre.fragment { + border: 1px solid var(--fragment-border-color); + background-color: var(--fragment-background-color); + color: var(--fragment-foreground-color); + padding: 4px 6px; + margin: 4px 8px 4px 2px; + overflow: auto; + word-wrap: break-word; + font-size: 9pt; + line-height: 125%; + font-family: var(--font-family-monospace); + font-size: 105%; +} + +div.fragment { + padding: 0 0 1px 0; /*Fixed: last line underline overlap border*/ + margin: 4px 8px 4px 2px; + color: var(--fragment-foreground-color); + background-color: var(--fragment-background-color); + border: 1px solid var(--fragment-border-color); +} + +div.line { + font-family: var(--font-family-monospace); + font-size: 13px; + min-height: 13px; + line-height: 1.0; + text-wrap: unrestricted; + white-space: -moz-pre-wrap; /* Moz */ + white-space: -pre-wrap; /* Opera 4-6 */ + white-space: -o-pre-wrap; /* Opera 7 */ + white-space: pre-wrap; /* CSS3 */ + word-wrap: break-word; /* IE 5.5+ */ + text-indent: -53px; + padding-left: 53px; + padding-bottom: 0px; + margin: 0px; + -webkit-transition-property: background-color, box-shadow; + -webkit-transition-duration: 0.5s; + -moz-transition-property: background-color, box-shadow; + -moz-transition-duration: 0.5s; + -ms-transition-property: background-color, box-shadow; + -ms-transition-duration: 0.5s; + -o-transition-property: background-color, box-shadow; + -o-transition-duration: 0.5s; + transition-property: background-color, box-shadow; + transition-duration: 0.5s; +} + +div.line:after { + content:"\000A"; + white-space: pre; +} + +div.line.glow { + background-color: var(--glow-color); + box-shadow: 0 0 10px var(--glow-color); +} + + +span.lineno { + padding-right: 4px; + margin-right: 9px; + text-align: right; + border-right: 2px solid var(--fragment-lineno-border-color); + color: var(--fragment-lineno-foreground-color); + background-color: var(--fragment-lineno-background-color); + white-space: pre; +} +span.lineno a, span.lineno a:visited { + color: var(--fragment-lineno-link-fg-color); + background-color: var(--fragment-lineno-link-bg-color); +} + +span.lineno a:hover { + color: var(--fragment-lineno-link-hover-fg-color); + background-color: var(--fragment-lineno-link-hover-bg-color); +} + +.lineno { + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +div.classindex ul { + list-style: none; + padding-left: 0; +} + +div.classindex span.ai { + display: inline-block; +} + +div.groupHeader { + margin-left: 16px; + margin-top: 12px; + font-weight: bold; +} + +div.groupText { + margin-left: 16px; + font-style: italic; +} + +body { + color: var(--page-foreground-color); + margin: 0; +} + +div.contents { + margin-top: 10px; + margin-left: 12px; + margin-right: 8px; +} + +p.formulaDsp { + text-align: center; +} + +img.dark-mode-visible { + display: none; +} +img.light-mode-visible { + display: none; +} + +img.formulaDsp { + +} + +img.formulaInl, img.inline { + vertical-align: middle; +} + +div.center { + text-align: center; + margin-top: 0px; + margin-bottom: 0px; + padding: 0px; +} + +div.center img { + border: 0px; +} + +address.footer { + text-align: right; + padding-right: 12px; +} + +img.footer { + border: 0px; + vertical-align: middle; + width: var(--footer-logo-width); +} + +.compoundTemplParams { + color: var(--memdecl-template-color); + font-size: 80%; + line-height: 120%; +} + +/* @group Code Colorization */ + +span.keyword { + color: var(--code-keyword-color); +} + +span.keywordtype { + color: var(--code-type-keyword-color); +} + +span.keywordflow { + color: var(--code-flow-keyword-color); +} + +span.comment { + color: var(--code-comment-color); +} + +span.preprocessor { + color: var(--code-preprocessor-color); +} + +span.stringliteral { + color: var(--code-string-literal-color); +} + +span.charliteral { + color: var(--code-char-literal-color); +} + +span.vhdldigit { + color: var(--code-vhdl-digit-color); +} + +span.vhdlchar { + color: var(--code-vhdl-char-color); +} + +span.vhdlkeyword { + color: var(--code-vhdl-keyword-color); +} + +span.vhdllogic { + color: var(--code-vhdl-logic-color); +} + +blockquote { + background-color: var(--blockquote-background-color); + border-left: 2px solid var(--blockquote-border-color); + margin: 0 24px 0 4px; + padding: 0 12px 0 16px; +} + +/* @end */ + +td.tiny { + font-size: 75%; +} + +.dirtab { + padding: 4px; + border-collapse: collapse; + border: 1px solid var(--table-cell-border-color); +} + +th.dirtab { + background-color: var(--table-header-background-color); + color: var(--table-header-foreground-color); + font-weight: bold; +} + +hr { + height: 0px; + border: none; + border-top: 1px solid var(--separator-color); +} + +hr.footer { + height: 1px; +} + +/* @group Member Descriptions */ + +table.memberdecls { + border-spacing: 0px; + padding: 0px; +} + +.memberdecls td, .fieldtable tr { + -webkit-transition-property: background-color, box-shadow; + -webkit-transition-duration: 0.5s; + -moz-transition-property: background-color, box-shadow; + -moz-transition-duration: 0.5s; + -ms-transition-property: background-color, box-shadow; + -ms-transition-duration: 0.5s; + -o-transition-property: background-color, box-shadow; + -o-transition-duration: 0.5s; + transition-property: background-color, box-shadow; + transition-duration: 0.5s; +} + +.memberdecls td.glow, .fieldtable tr.glow { + background-color: var(--glow-color); + box-shadow: 0 0 15px var(--glow-color); +} + +.mdescLeft, .mdescRight, +.memItemLeft, .memItemRight, +.memTemplItemLeft, .memTemplItemRight, .memTemplParams { + background-color: var(--memdecl-background-color); + border: none; + margin: 4px; + padding: 1px 0 0 8px; +} + +.mdescLeft, .mdescRight { + padding: 0px 8px 4px 8px; + color: var(--memdecl-foreground-color); +} + +.memSeparator { + border-bottom: 1px solid var(--memdecl-separator-color); + line-height: 1px; + margin: 0px; + padding: 0px; +} + +.memItemLeft, .memTemplItemLeft { + white-space: nowrap; +} + +.memItemRight, .memTemplItemRight { + width: 100%; +} + +.memTemplParams { + color: var(--memdecl-template-color); + white-space: nowrap; + font-size: 80%; +} + +/* @end */ + +/* @group Member Details */ + +/* Styles for detailed member documentation */ + +.memtitle { + padding: 8px; + border-top: 1px solid var(--memdef-border-color); + border-left: 1px solid var(--memdef-border-color); + border-right: 1px solid var(--memdef-border-color); + border-top-right-radius: 4px; + border-top-left-radius: 4px; + margin-bottom: -1px; + background-image: var(--memdef-title-gradient-image); + background-repeat: repeat-x; + background-color: var(--memdef-title-background-color); + line-height: 1.25; + font-weight: 300; + float:left; +} + +.permalink +{ + font-size: 65%; + display: inline-block; + vertical-align: middle; +} + +.memtemplate { + font-size: 80%; + color: var(--memdef-template-color); + font-weight: normal; + margin-left: 9px; +} + +.mempage { + width: 100%; +} + +.memitem { + padding: 0; + margin-bottom: 10px; + margin-right: 5px; + -webkit-transition: box-shadow 0.5s linear; + -moz-transition: box-shadow 0.5s linear; + -ms-transition: box-shadow 0.5s linear; + -o-transition: box-shadow 0.5s linear; + transition: box-shadow 0.5s linear; + display: table !important; + width: 100%; +} + +.memitem.glow { + box-shadow: 0 0 15px var(--glow-color); +} + +.memname { + font-weight: 400; + margin-left: 6px; +} + +.memname td { + vertical-align: bottom; +} + +.memproto, dl.reflist dt { + border-top: 1px solid var(--memdef-border-color); + border-left: 1px solid var(--memdef-border-color); + border-right: 1px solid var(--memdef-border-color); + padding: 6px 0px 6px 0px; + color: var(--memdef-proto-text-color); + font-weight: bold; + text-shadow: var(--memdef-proto-text-shadow); + background-color: var(--memdef-proto-background-color); + box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); + border-top-right-radius: 4px; +} + +.overload { + font-family: var(--font-family-monospace); + font-size: 65%; +} + +.memdoc, dl.reflist dd { + border-bottom: 1px solid var(--memdef-border-color); + border-left: 1px solid var(--memdef-border-color); + border-right: 1px solid var(--memdef-border-color); + padding: 6px 10px 2px 10px; + border-top-width: 0; + background-image:url('nav_g.png'); + background-repeat:repeat-x; + background-color: var(--memdef-doc-background-color); + /* opera specific markup */ + border-bottom-left-radius: 4px; + border-bottom-right-radius: 4px; + box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); + /* firefox specific markup */ + -moz-border-radius-bottomleft: 4px; + -moz-border-radius-bottomright: 4px; + -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px; + /* webkit specific markup */ + -webkit-border-bottom-left-radius: 4px; + -webkit-border-bottom-right-radius: 4px; + -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); +} + +dl.reflist dt { + padding: 5px; +} + +dl.reflist dd { + margin: 0px 0px 10px 0px; + padding: 5px; +} + +.paramkey { + text-align: right; +} + +.paramtype { + white-space: nowrap; +} + +.paramname { + color: var(--memdef-param-name-color); + white-space: nowrap; +} +.paramname em { + font-style: normal; +} +.paramname code { + line-height: 14px; +} + +.params, .retval, .exception, .tparams { + margin-left: 0px; + padding-left: 0px; +} + +.params .paramname, .retval .paramname, .tparams .paramname, .exception .paramname { + font-weight: bold; + vertical-align: top; +} + +.params .paramtype, .tparams .paramtype { + font-style: italic; + vertical-align: top; +} + +.params .paramdir, .tparams .paramdir { + font-family: var(--font-family-monospace); + vertical-align: top; +} + +table.mlabels { + border-spacing: 0px; +} + +td.mlabels-left { + width: 100%; + padding: 0px; +} + +td.mlabels-right { + vertical-align: bottom; + padding: 0px; + white-space: nowrap; +} + +span.mlabels { + margin-left: 8px; +} + +span.mlabel { + background-color: var(--label-background-color); + border-top:1px solid var(--label-left-top-border-color); + border-left:1px solid var(--label-left-top-border-color); + border-right:1px solid var(--label-right-bottom-border-color); + border-bottom:1px solid var(--label-right-bottom-border-color); + text-shadow: none; + color: var(--label-foreground-color); + margin-right: 4px; + padding: 2px 3px; + border-radius: 3px; + font-size: 7pt; + white-space: nowrap; + vertical-align: middle; +} + + + +/* @end */ + +/* these are for tree view inside a (index) page */ + +div.directory { + margin: 10px 0px; + border-top: 1px solid var(--directory-separator-color); + border-bottom: 1px solid var(--directory-separator-color); + width: 100%; +} + +.directory table { + border-collapse:collapse; +} + +.directory td { + margin: 0px; + padding: 0px; + vertical-align: top; +} + +.directory td.entry { + white-space: nowrap; + padding-right: 6px; + padding-top: 3px; +} + +.directory td.entry a { + outline:none; +} + +.directory td.entry a img { + border: none; +} + +.directory td.desc { + width: 100%; + padding-left: 6px; + padding-right: 6px; + padding-top: 3px; + border-left: 1px solid rgba(0,0,0,0.05); +} + +.directory tr.odd { + padding-left: 6px; + background-color: var(--index-odd-item-bg-color); +} + +.directory tr.even { + padding-left: 6px; + background-color: var(--index-even-item-bg-color); +} + +.directory img { + vertical-align: -30%; +} + +.directory .levels { + white-space: nowrap; + width: 100%; + text-align: right; + font-size: 9pt; +} + +.directory .levels span { + cursor: pointer; + padding-left: 2px; + padding-right: 2px; + color: var(--page-link-color); +} + +.arrow { + color: var(--nav-arrow-color); + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + cursor: pointer; + font-size: 80%; + display: inline-block; + width: 16px; + height: 22px; +} + +.icon { + font-family: var(--font-family-icon); + line-height: normal; + font-weight: bold; + font-size: 12px; + height: 14px; + width: 16px; + display: inline-block; + background-color: var(--icon-background-color); + color: var(--icon-foreground-color); + text-align: center; + border-radius: 4px; + margin-left: 2px; + margin-right: 2px; +} + +.icona { + width: 24px; + height: 22px; + display: inline-block; +} + +.iconfopen { + width: 24px; + height: 18px; + margin-bottom: 4px; + background-image:url('folderopen.png'); + background-position: 0px -4px; + background-repeat: repeat-y; + vertical-align:top; + display: inline-block; +} + +.iconfclosed { + width: 24px; + height: 18px; + margin-bottom: 4px; + background-image:url('folderclosed.png'); + background-position: 0px -4px; + background-repeat: repeat-y; + vertical-align:top; + display: inline-block; +} + +.icondoc { + width: 24px; + height: 18px; + margin-bottom: 4px; + background-image:var(--icon-doc-image); + background-position: 0px -4px; + background-repeat: repeat-y; + vertical-align:top; + display: inline-block; +} + +/* @end */ + +div.dynheader { + margin-top: 8px; + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +address { + font-style: normal; + color: var(--footer-foreground-color); +} + +table.doxtable caption { + caption-side: top; +} + +table.doxtable { + border-collapse:collapse; + margin-top: 4px; + margin-bottom: 4px; +} + +table.doxtable td, table.doxtable th { + border: 1px solid var(--table-cell-border-color); + padding: 3px 7px 2px; +} + +table.doxtable th { + background-color: var(--table-header-background-color); + color: var(--table-header-foreground-color); + font-size: 110%; + padding-bottom: 4px; + padding-top: 5px; +} + +table.fieldtable { + margin-bottom: 10px; + border: 1px solid var(--memdef-border-color); + border-spacing: 0px; + border-radius: 4px; + box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.15); +} + +.fieldtable td, .fieldtable th { + padding: 3px 7px 2px; +} + +.fieldtable td.fieldtype, .fieldtable td.fieldname { + white-space: nowrap; + border-right: 1px solid var(--memdef-border-color); + border-bottom: 1px solid var(--memdef-border-color); + vertical-align: top; +} + +.fieldtable td.fieldname { + padding-top: 3px; +} + +.fieldtable td.fielddoc { + border-bottom: 1px solid var(--memdef-border-color); +} + +.fieldtable td.fielddoc p:first-child { + margin-top: 0px; +} + +.fieldtable td.fielddoc p:last-child { + margin-bottom: 2px; +} + +.fieldtable tr:last-child td { + border-bottom: none; +} + +.fieldtable th { + background-image: var(--memdef-title-gradient-image); + background-repeat:repeat-x; + background-color: var(--memdef-title-background-color); + font-size: 90%; + color: var(--memdef-proto-text-color); + padding-bottom: 4px; + padding-top: 5px; + text-align:left; + font-weight: 400; + border-top-left-radius: 4px; + border-top-right-radius: 4px; + border-bottom: 1px solid var(--memdef-border-color); +} + + +.tabsearch { + top: 0px; + left: 10px; + height: 36px; + background-image: var(--nav-gradient-image); + z-index: 101; + overflow: hidden; + font-size: 13px; +} + +.navpath ul +{ + font-size: 11px; + background-image: var(--nav-gradient-image); + background-repeat:repeat-x; + background-position: 0 -5px; + height:30px; + line-height:30px; + color:var(--nav-text-normal-color); + border:solid 1px var(--nav-breadcrumb-border-color); + overflow:hidden; + margin:0px; + padding:0px; +} + +.navpath li +{ + list-style-type:none; + float:left; + padding-left:10px; + padding-right:15px; + background-image:var(--nav-breadcrumb-image); + background-repeat:no-repeat; + background-position:right; + color: var(--nav-foreground-color); +} + +.navpath li.navelem a +{ + height:32px; + display:block; + text-decoration: none; + outline: none; + color: var(--nav-text-normal-color); + font-family: var(--font-family-nav); + text-shadow: var(--nav-text-normal-shadow); + text-decoration: none; +} + +.navpath li.navelem a:hover +{ + color: var(--nav-text-hover-color); + text-shadow: var(--nav-text-hover-shadow); +} + +.navpath li.footer +{ + list-style-type:none; + float:right; + padding-left:10px; + padding-right:15px; + background-image:none; + background-repeat:no-repeat; + background-position:right; + color: var(--footer-foreground-color); + font-size: 8pt; +} + + +div.summary +{ + float: right; + font-size: 8pt; + padding-right: 5px; + width: 50%; + text-align: right; +} + +div.summary a +{ + white-space: nowrap; +} + +table.classindex +{ + margin: 10px; + white-space: nowrap; + margin-left: 3%; + margin-right: 3%; + width: 94%; + border: 0; + border-spacing: 0; + padding: 0; +} + +div.ingroups +{ + font-size: 8pt; + width: 50%; + text-align: left; +} + +div.ingroups a +{ + white-space: nowrap; +} + +div.header +{ + background-image: var(--header-gradient-image); + background-repeat:repeat-x; + background-color: var(--header-background-color); + margin: 0px; + border-bottom: 1px solid var(--header-separator-color); +} + +div.headertitle +{ + padding: 5px 5px 5px 10px; +} + +.PageDocRTL-title div.headertitle { + text-align: right; + direction: rtl; +} + +dl { + padding: 0 0 0 0; +} + +/* dl.note, dl.warning, dl.attention, dl.pre, dl.post, dl.invariant, dl.deprecated, dl.todo, dl.test, dl.bug, dl.examples */ +dl.section { + margin-left: 0px; + padding-left: 0px; +} + +dl.note { + margin-left: -7px; + padding-left: 3px; + border-left: 4px solid; + border-color: #D0C000; +} + +dl.warning, dl.attention { + margin-left: -7px; + padding-left: 3px; + border-left: 4px solid; + border-color: #FF0000; +} + +dl.pre, dl.post, dl.invariant { + margin-left: -7px; + padding-left: 3px; + border-left: 4px solid; + border-color: #00D000; +} + +dl.deprecated { + margin-left: -7px; + padding-left: 3px; + border-left: 4px solid; + border-color: #505050; +} + +dl.todo { + margin-left: -7px; + padding-left: 3px; + border-left: 4px solid; + border-color: #00C0E0; +} + +dl.test { + margin-left: -7px; + padding-left: 3px; + border-left: 4px solid; + border-color: #3030E0; +} + +dl.bug { + margin-left: -7px; + padding-left: 3px; + border-left: 4px solid; + border-color: #C08050; +} + +dl.section dd { + margin-bottom: 6px; +} + + +#projectrow +{ + height: 56px; +} + +#projectlogo +{ + text-align: center; + vertical-align: bottom; + border-collapse: separate; +} + +#projectlogo img +{ + border: 0px none; +} + +#projectalign +{ + vertical-align: middle; + padding-left: 0.5em; +} + +#projectname +{ + font-size: 200%; + font-family: var(--font-family-title); + margin: 0px; + padding: 2px 0px; +} + +#projectbrief +{ + font-size: 90%; + font-family: var(--font-family-title); + margin: 0px; + padding: 0px; +} + +#projectnumber +{ + font-size: 50%; + font-family: 50% var(--font-family-title); + margin: 0px; + padding: 0px; +} + +#titlearea +{ + padding: 0px; + margin: 0px; + width: 100%; + border-bottom: 1px solid var(--title-separator-color); + background-color: var(--title-background-color); +} + +.image +{ + text-align: center; +} + +.dotgraph +{ + text-align: center; +} + +.mscgraph +{ + text-align: center; +} + +.plantumlgraph +{ + text-align: center; +} + +.diagraph +{ + text-align: center; +} + +.caption +{ + font-weight: bold; +} + +dl.citelist { + margin-bottom:50px; +} + +dl.citelist dt { + color:var(--citation-label-color); + float:left; + font-weight:bold; + margin-right:10px; + padding:5px; + text-align:right; + width:52px; +} + +dl.citelist dd { + margin:2px 0 2px 72px; + padding:5px 0; +} + +div.toc { + padding: 14px 25px; + background-color: var(--toc-background-color); + border: 1px solid var(--toc-border-color); + border-radius: 7px 7px 7px 7px; + float: right; + height: auto; + margin: 0 8px 10px 10px; + width: 200px; +} + +div.toc li { + background: url("bdwn.png") no-repeat scroll 0 5px transparent; + font: 10px/1.2 var(--font-family-toc); + margin-top: 5px; + padding-left: 10px; + padding-top: 2px; +} + +div.toc h3 { + font: bold 12px/1.2 var(--font-family-toc); + color: var(--toc-header-color); + border-bottom: 0 none; + margin: 0; +} + +div.toc ul { + list-style: none outside none; + border: medium none; + padding: 0px; +} + +div.toc li.level1 { + margin-left: 0px; +} + +div.toc li.level2 { + margin-left: 15px; +} + +div.toc li.level3 { + margin-left: 30px; +} + +div.toc li.level4 { + margin-left: 45px; +} + +span.emoji { + /* font family used at the site: https://unicode.org/emoji/charts/full-emoji-list.html + * font-family: "Noto Color Emoji", "Apple Color Emoji", "Segoe UI Emoji", Times, Symbola, Aegyptus, Code2000, Code2001, Code2002, Musica, serif, LastResort; + */ +} + +span.obfuscator { + display: none; +} + +.inherit_header { + font-weight: bold; + color: var(--inherit-header-color); + cursor: pointer; + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.inherit_header td { + padding: 6px 0px 2px 5px; +} + +.inherit { + display: none; +} + +tr.heading h2 { + margin-top: 12px; + margin-bottom: 4px; +} + +/* tooltip related style info */ + +.ttc { + position: absolute; + display: none; +} + +#powerTip { + cursor: default; + /*white-space: nowrap;*/ + color: var(--tooltip-foreground-color); + background-color: var(--tooltip-background-color); + border: 1px solid var(--tooltip-border-color); + border-radius: 4px 4px 4px 4px; + box-shadow: var(--tooltip-shadow); + display: none; + font-size: smaller; + max-width: 80%; + opacity: 0.9; + padding: 1ex 1em 1em; + position: absolute; + z-index: 2147483647; +} + +#powerTip div.ttdoc { + color: var(--tooltip-doc-color); + font-style: italic; +} + +#powerTip div.ttname a { + font-weight: bold; +} + +#powerTip a { + color: var(--tooltip-link-color); +} + +#powerTip div.ttname { + font-weight: bold; +} + +#powerTip div.ttdeci { + color: var(--tooltip-declaration-color); +} + +#powerTip div { + margin: 0px; + padding: 0px; + font-size: 12px; + font-family: var(--font-family-tooltip); + line-height: 16px; +} + +#powerTip:before, #powerTip:after { + content: ""; + position: absolute; + margin: 0px; +} + +#powerTip.n:after, #powerTip.n:before, +#powerTip.s:after, #powerTip.s:before, +#powerTip.w:after, #powerTip.w:before, +#powerTip.e:after, #powerTip.e:before, +#powerTip.ne:after, #powerTip.ne:before, +#powerTip.se:after, #powerTip.se:before, +#powerTip.nw:after, #powerTip.nw:before, +#powerTip.sw:after, #powerTip.sw:before { + border: solid transparent; + content: " "; + height: 0; + width: 0; + position: absolute; +} + +#powerTip.n:after, #powerTip.s:after, +#powerTip.w:after, #powerTip.e:after, +#powerTip.nw:after, #powerTip.ne:after, +#powerTip.sw:after, #powerTip.se:after { + border-color: rgba(255, 255, 255, 0); +} + +#powerTip.n:before, #powerTip.s:before, +#powerTip.w:before, #powerTip.e:before, +#powerTip.nw:before, #powerTip.ne:before, +#powerTip.sw:before, #powerTip.se:before { + border-color: rgba(128, 128, 128, 0); +} + +#powerTip.n:after, #powerTip.n:before, +#powerTip.ne:after, #powerTip.ne:before, +#powerTip.nw:after, #powerTip.nw:before { + top: 100%; +} + +#powerTip.n:after, #powerTip.ne:after, #powerTip.nw:after { + border-top-color: var(--tooltip-background-color); + border-width: 10px; + margin: 0px -10px; +} +#powerTip.n:before, #powerTip.ne:before, #powerTip.nw:before { + border-top-color: var(--tooltip-border-color); + border-width: 11px; + margin: 0px -11px; +} +#powerTip.n:after, #powerTip.n:before { + left: 50%; +} + +#powerTip.nw:after, #powerTip.nw:before { + right: 14px; +} + +#powerTip.ne:after, #powerTip.ne:before { + left: 14px; +} + +#powerTip.s:after, #powerTip.s:before, +#powerTip.se:after, #powerTip.se:before, +#powerTip.sw:after, #powerTip.sw:before { + bottom: 100%; +} + +#powerTip.s:after, #powerTip.se:after, #powerTip.sw:after { + border-bottom-color: var(--tooltip-background-color); + border-width: 10px; + margin: 0px -10px; +} + +#powerTip.s:before, #powerTip.se:before, #powerTip.sw:before { + border-bottom-color: var(--tooltip-border-color); + border-width: 11px; + margin: 0px -11px; +} + +#powerTip.s:after, #powerTip.s:before { + left: 50%; +} + +#powerTip.sw:after, #powerTip.sw:before { + right: 14px; +} + +#powerTip.se:after, #powerTip.se:before { + left: 14px; +} + +#powerTip.e:after, #powerTip.e:before { + left: 100%; +} +#powerTip.e:after { + border-left-color: var(--tooltip-border-color); + border-width: 10px; + top: 50%; + margin-top: -10px; +} +#powerTip.e:before { + border-left-color: var(--tooltip-border-color); + border-width: 11px; + top: 50%; + margin-top: -11px; +} + +#powerTip.w:after, #powerTip.w:before { + right: 100%; +} +#powerTip.w:after { + border-right-color: var(--tooltip-border-color); + border-width: 10px; + top: 50%; + margin-top: -10px; +} +#powerTip.w:before { + border-right-color: var(--tooltip-border-color); + border-width: 11px; + top: 50%; + margin-top: -11px; +} + +@media print +{ + #top { display: none; } + #side-nav { display: none; } + #nav-path { display: none; } + body { overflow:visible; } + h1, h2, h3, h4, h5, h6 { page-break-after: avoid; } + .summary { display: none; } + .memitem { page-break-inside: avoid; } + #doc-content + { + margin-left:0 !important; + height:auto !important; + width:auto !important; + overflow:inherit; + display:inline; + } +} + +/* @group Markdown */ + +table.markdownTable { + border-collapse:collapse; + margin-top: 4px; + margin-bottom: 4px; +} + +table.markdownTable td, table.markdownTable th { + border: 1px solid var(--table-cell-border-color); + padding: 3px 7px 2px; +} + +table.markdownTable tr { +} + +th.markdownTableHeadLeft, th.markdownTableHeadRight, th.markdownTableHeadCenter, th.markdownTableHeadNone { + background-color: var(--table-header-background-color); + color: var(--table-header-foreground-color); + font-size: 110%; + padding-bottom: 4px; + padding-top: 5px; +} + +th.markdownTableHeadLeft, td.markdownTableBodyLeft { + text-align: left +} + +th.markdownTableHeadRight, td.markdownTableBodyRight { + text-align: right +} + +th.markdownTableHeadCenter, td.markdownTableBodyCenter { + text-align: center +} + +tt, code, kbd, samp +{ + display: inline-block; +} +/* @end */ + +u { + text-decoration: underline; +} + diff --git a/docs/html/doxygen.svg b/docs/html/doxygen.svg new file mode 100644 index 00000000..d42dad52 --- /dev/null +++ b/docs/html/doxygen.svg @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/html/dynsections.js b/docs/html/dynsections.js new file mode 100644 index 00000000..f579fbf3 --- /dev/null +++ b/docs/html/dynsections.js @@ -0,0 +1,123 @@ +/* + @licstart The following is the entire license notice for the JavaScript code in this file. + + The MIT License (MIT) + + Copyright (C) 1997-2020 by Dimitri van Heesch + + Permission is hereby granted, free of charge, to any person obtaining a copy of this software + and associated documentation files (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, publish, distribute, + sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all copies or + substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + @licend The above is the entire license notice for the JavaScript code in this file + */ +function toggleVisibility(linkObj) +{ + var base = $(linkObj).attr('id'); + var summary = $('#'+base+'-summary'); + var content = $('#'+base+'-content'); + var trigger = $('#'+base+'-trigger'); + var src=$(trigger).attr('src'); + if (content.is(':visible')===true) { + content.hide(); + summary.show(); + $(linkObj).addClass('closed').removeClass('opened'); + $(trigger).attr('src',src.substring(0,src.length-8)+'closed.png'); + } else { + content.show(); + summary.hide(); + $(linkObj).removeClass('closed').addClass('opened'); + $(trigger).attr('src',src.substring(0,src.length-10)+'open.png'); + } + return false; +} + +function updateStripes() +{ + $('table.directory tr'). + removeClass('even').filter(':visible:even').addClass('even'); + $('table.directory tr'). + removeClass('odd').filter(':visible:odd').addClass('odd'); +} + +function toggleLevel(level) +{ + $('table.directory tr').each(function() { + var l = this.id.split('_').length-1; + var i = $('#img'+this.id.substring(3)); + var a = $('#arr'+this.id.substring(3)); + if (l + + + + + + +LogDoctor: Class Members + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Here is a list of all documented class members with links to the class documentation for each member:
+ +

- a -

+
+ + + + diff --git a/docs/html/functions_b.html b/docs/html/functions_b.html new file mode 100644 index 00000000..634493c6 --- /dev/null +++ b/docs/html/functions_b.html @@ -0,0 +1,92 @@ + + + + + + + +LogDoctor: Class Members + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Here is a list of all documented class members with links to the class documentation for each member:
+ +

- b -

+
+ + + + diff --git a/docs/html/functions_c.html b/docs/html/functions_c.html new file mode 100644 index 00000000..e4f18513 --- /dev/null +++ b/docs/html/functions_c.html @@ -0,0 +1,123 @@ + + + + + + + +LogDoctor: Class Members + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Here is a list of all documented class members with links to the class documentation for each member:
+ +

- c -

+
+ + + + diff --git a/docs/html/functions_d.html b/docs/html/functions_d.html new file mode 100644 index 00000000..457b07dd --- /dev/null +++ b/docs/html/functions_d.html @@ -0,0 +1,101 @@ + + + + + + + +LogDoctor: Class Members + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Here is a list of all documented class members with links to the class documentation for each member:
+ +

- d -

+
+ + + + diff --git a/docs/html/functions_e.html b/docs/html/functions_e.html new file mode 100644 index 00000000..4f51374a --- /dev/null +++ b/docs/html/functions_e.html @@ -0,0 +1,122 @@ + + + + + + + +LogDoctor: Class Members + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Here is a list of all documented class members with links to the class documentation for each member:
+ +

- e -

+
+ + + + diff --git a/docs/html/functions_enum.html b/docs/html/functions_enum.html new file mode 100644 index 00000000..59f69e11 --- /dev/null +++ b/docs/html/functions_enum.html @@ -0,0 +1,84 @@ + + + + + + + +LogDoctor: Class Members - Enumerations + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
+ + + + diff --git a/docs/html/functions_eval.html b/docs/html/functions_eval.html new file mode 100644 index 00000000..d60ef05e --- /dev/null +++ b/docs/html/functions_eval.html @@ -0,0 +1,88 @@ + + + + + + + +LogDoctor: Class Members - Enumerator + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
+ + + + diff --git a/docs/html/functions_f.html b/docs/html/functions_f.html new file mode 100644 index 00000000..ab01ba25 --- /dev/null +++ b/docs/html/functions_f.html @@ -0,0 +1,90 @@ + + + + + + + +LogDoctor: Class Members + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Here is a list of all documented class members with links to the class documentation for each member:
+ +

- f -

+
+ + + + diff --git a/docs/html/functions_func.html b/docs/html/functions_func.html new file mode 100644 index 00000000..e9862996 --- /dev/null +++ b/docs/html/functions_func.html @@ -0,0 +1,89 @@ + + + + + + + +LogDoctor: Class Members - Functions + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+  + +

- a -

+
+ + + + diff --git a/docs/html/functions_func_b.html b/docs/html/functions_func_b.html new file mode 100644 index 00000000..c24999db --- /dev/null +++ b/docs/html/functions_func_b.html @@ -0,0 +1,91 @@ + + + + + + + +LogDoctor: Class Members - Functions + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+  + +

- b -

+
+ + + + diff --git a/docs/html/functions_func_c.html b/docs/html/functions_func_c.html new file mode 100644 index 00000000..91b7f7f9 --- /dev/null +++ b/docs/html/functions_func_c.html @@ -0,0 +1,122 @@ + + + + + + + +LogDoctor: Class Members - Functions + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+  + +

- c -

+
+ + + + diff --git a/docs/html/functions_func_d.html b/docs/html/functions_func_d.html new file mode 100644 index 00000000..c0ccdf58 --- /dev/null +++ b/docs/html/functions_func_d.html @@ -0,0 +1,100 @@ + + + + + + + +LogDoctor: Class Members - Functions + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+  + +

- d -

+
+ + + + diff --git a/docs/html/functions_func_e.html b/docs/html/functions_func_e.html new file mode 100644 index 00000000..de6dca22 --- /dev/null +++ b/docs/html/functions_func_e.html @@ -0,0 +1,121 @@ + + + + + + + +LogDoctor: Class Members - Functions + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+  + +

- e -

+
+ + + + diff --git a/docs/html/functions_func_f.html b/docs/html/functions_func_f.html new file mode 100644 index 00000000..e716bb52 --- /dev/null +++ b/docs/html/functions_func_f.html @@ -0,0 +1,86 @@ + + + + + + + +LogDoctor: Class Members - Functions + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+  + +

- f -

+
+ + + + diff --git a/docs/html/functions_func_g.html b/docs/html/functions_func_g.html new file mode 100644 index 00000000..e2ed3922 --- /dev/null +++ b/docs/html/functions_func_g.html @@ -0,0 +1,137 @@ + + + + + + + +LogDoctor: Class Members - Functions + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+  + +

- g -

+
+ + + + diff --git a/docs/html/functions_func_h.html b/docs/html/functions_func_h.html new file mode 100644 index 00000000..fc0d22bf --- /dev/null +++ b/docs/html/functions_func_h.html @@ -0,0 +1,86 @@ + + + + + + + +LogDoctor: Class Members - Functions + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+  + +

- h -

+
+ + + + diff --git a/docs/html/functions_func_i.html b/docs/html/functions_func_i.html new file mode 100644 index 00000000..5fb65b6a --- /dev/null +++ b/docs/html/functions_func_i.html @@ -0,0 +1,100 @@ + + + + + + + +LogDoctor: Class Members - Functions + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+  + +

- i -

+
+ + + + diff --git a/docs/html/functions_func_j.html b/docs/html/functions_func_j.html new file mode 100644 index 00000000..399e3a02 --- /dev/null +++ b/docs/html/functions_func_j.html @@ -0,0 +1,85 @@ + + + + + + + +LogDoctor: Class Members - Functions + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+  + +

- j -

+
+ + + + diff --git a/docs/html/functions_func_k.html b/docs/html/functions_func_k.html new file mode 100644 index 00000000..8f280700 --- /dev/null +++ b/docs/html/functions_func_k.html @@ -0,0 +1,85 @@ + + + + + + + +LogDoctor: Class Members - Functions + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+  + +

- k -

+
+ + + + diff --git a/docs/html/functions_func_l.html b/docs/html/functions_func_l.html new file mode 100644 index 00000000..dfd28d12 --- /dev/null +++ b/docs/html/functions_func_l.html @@ -0,0 +1,88 @@ + + + + + + + +LogDoctor: Class Members - Functions + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+  + +

- l -

+
+ + + + diff --git a/docs/html/functions_func_m.html b/docs/html/functions_func_m.html new file mode 100644 index 00000000..1ea354c4 --- /dev/null +++ b/docs/html/functions_func_m.html @@ -0,0 +1,92 @@ + + + + + + + +LogDoctor: Class Members - Functions + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+  + +

- m -

+
+ + + + diff --git a/docs/html/functions_func_n.html b/docs/html/functions_func_n.html new file mode 100644 index 00000000..b76b20c1 --- /dev/null +++ b/docs/html/functions_func_n.html @@ -0,0 +1,88 @@ + + + + + + + +LogDoctor: Class Members - Functions + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+  + +

- n -

+
+ + + + diff --git a/docs/html/functions_func_o.html b/docs/html/functions_func_o.html new file mode 100644 index 00000000..b1eebe00 --- /dev/null +++ b/docs/html/functions_func_o.html @@ -0,0 +1,94 @@ + + + + + + + +LogDoctor: Class Members - Functions + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+  + +

- o -

+
+ + + + diff --git a/docs/html/functions_func_p.html b/docs/html/functions_func_p.html new file mode 100644 index 00000000..01d1c184 --- /dev/null +++ b/docs/html/functions_func_p.html @@ -0,0 +1,103 @@ + + + + + + + +LogDoctor: Class Members - Functions + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+  + +

- p -

+
+ + + + diff --git a/docs/html/functions_func_r.html b/docs/html/functions_func_r.html new file mode 100644 index 00000000..708ee848 --- /dev/null +++ b/docs/html/functions_func_r.html @@ -0,0 +1,100 @@ + + + + + + + +LogDoctor: Class Members - Functions + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+  + +

- r -

+
+ + + + diff --git a/docs/html/functions_func_s.html b/docs/html/functions_func_s.html new file mode 100644 index 00000000..d49038f4 --- /dev/null +++ b/docs/html/functions_func_s.html @@ -0,0 +1,123 @@ + + + + + + + +LogDoctor: Class Members - Functions + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+  + +

- s -

+
+ + + + diff --git a/docs/html/functions_func_t.html b/docs/html/functions_func_t.html new file mode 100644 index 00000000..1aee62fe --- /dev/null +++ b/docs/html/functions_func_t.html @@ -0,0 +1,86 @@ + + + + + + + +LogDoctor: Class Members - Functions + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+  + +

- t -

+
+ + + + diff --git a/docs/html/functions_func_u.html b/docs/html/functions_func_u.html new file mode 100644 index 00000000..ea618054 --- /dev/null +++ b/docs/html/functions_func_u.html @@ -0,0 +1,94 @@ + + + + + + + +LogDoctor: Class Members - Functions + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+  + +

- u -

+
+ + + + diff --git a/docs/html/functions_func_v.html b/docs/html/functions_func_v.html new file mode 100644 index 00000000..367d3830 --- /dev/null +++ b/docs/html/functions_func_v.html @@ -0,0 +1,86 @@ + + + + + + + +LogDoctor: Class Members - Functions + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+  + +

- v -

+
+ + + + diff --git a/docs/html/functions_func_w.html b/docs/html/functions_func_w.html new file mode 100644 index 00000000..3080b51f --- /dev/null +++ b/docs/html/functions_func_w.html @@ -0,0 +1,96 @@ + + + + + + + +LogDoctor: Class Members - Functions + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+  + +

- w -

+
+ + + + diff --git a/docs/html/functions_func_x.html b/docs/html/functions_func_x.html new file mode 100644 index 00000000..6ca49323 --- /dev/null +++ b/docs/html/functions_func_x.html @@ -0,0 +1,85 @@ + + + + + + + +LogDoctor: Class Members - Functions + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+  + +

- x -

+
+ + + + diff --git a/docs/html/functions_func_y.html b/docs/html/functions_func_y.html new file mode 100644 index 00000000..710fe9dd --- /dev/null +++ b/docs/html/functions_func_y.html @@ -0,0 +1,85 @@ + + + + + + + +LogDoctor: Class Members - Functions + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+  + +

- y -

+
+ + + + diff --git a/docs/html/functions_g.html b/docs/html/functions_g.html new file mode 100644 index 00000000..7609031c --- /dev/null +++ b/docs/html/functions_g.html @@ -0,0 +1,138 @@ + + + + + + + +LogDoctor: Class Members + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Here is a list of all documented class members with links to the class documentation for each member:
+ +

- g -

+
+ + + + diff --git a/docs/html/functions_h.html b/docs/html/functions_h.html new file mode 100644 index 00000000..85c855f8 --- /dev/null +++ b/docs/html/functions_h.html @@ -0,0 +1,88 @@ + + + + + + + +LogDoctor: Class Members + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Here is a list of all documented class members with links to the class documentation for each member:
+ +

- h -

+
+ + + + diff --git a/docs/html/functions_i.html b/docs/html/functions_i.html new file mode 100644 index 00000000..6266c727 --- /dev/null +++ b/docs/html/functions_i.html @@ -0,0 +1,105 @@ + + + + + + + +LogDoctor: Class Members + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Here is a list of all documented class members with links to the class documentation for each member:
+ +

- i -

+
+ + + + diff --git a/docs/html/functions_j.html b/docs/html/functions_j.html new file mode 100644 index 00000000..3c6f119b --- /dev/null +++ b/docs/html/functions_j.html @@ -0,0 +1,85 @@ + + + + + + + +LogDoctor: Class Members + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Here is a list of all documented class members with links to the class documentation for each member:
+ +

- j -

+
+ + + + diff --git a/docs/html/functions_k.html b/docs/html/functions_k.html new file mode 100644 index 00000000..eaa7b642 --- /dev/null +++ b/docs/html/functions_k.html @@ -0,0 +1,86 @@ + + + + + + + +LogDoctor: Class Members + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Here is a list of all documented class members with links to the class documentation for each member:
+ +

- k -

+
+ + + + diff --git a/docs/html/functions_l.html b/docs/html/functions_l.html new file mode 100644 index 00000000..23e53a3b --- /dev/null +++ b/docs/html/functions_l.html @@ -0,0 +1,90 @@ + + + + + + + +LogDoctor: Class Members + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Here is a list of all documented class members with links to the class documentation for each member:
+ +

- l -

+
+ + + + diff --git a/docs/html/functions_m.html b/docs/html/functions_m.html new file mode 100644 index 00000000..225ceede --- /dev/null +++ b/docs/html/functions_m.html @@ -0,0 +1,94 @@ + + + + + + + +LogDoctor: Class Members + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Here is a list of all documented class members with links to the class documentation for each member:
+ +

- m -

+
+ + + + diff --git a/docs/html/functions_n.html b/docs/html/functions_n.html new file mode 100644 index 00000000..0e663239 --- /dev/null +++ b/docs/html/functions_n.html @@ -0,0 +1,91 @@ + + + + + + + +LogDoctor: Class Members + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Here is a list of all documented class members with links to the class documentation for each member:
+ +

- n -

+
+ + + + diff --git a/docs/html/functions_o.html b/docs/html/functions_o.html new file mode 100644 index 00000000..ffc794cc --- /dev/null +++ b/docs/html/functions_o.html @@ -0,0 +1,94 @@ + + + + + + + +LogDoctor: Class Members + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Here is a list of all documented class members with links to the class documentation for each member:
+ +

- o -

+
+ + + + diff --git a/docs/html/functions_p.html b/docs/html/functions_p.html new file mode 100644 index 00000000..727f5277 --- /dev/null +++ b/docs/html/functions_p.html @@ -0,0 +1,107 @@ + + + + + + + +LogDoctor: Class Members + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Here is a list of all documented class members with links to the class documentation for each member:
+ +

- p -

+
+ + + + diff --git a/docs/html/functions_r.html b/docs/html/functions_r.html new file mode 100644 index 00000000..39ca357e --- /dev/null +++ b/docs/html/functions_r.html @@ -0,0 +1,100 @@ + + + + + + + +LogDoctor: Class Members + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Here is a list of all documented class members with links to the class documentation for each member:
+ +

- r -

+
+ + + + diff --git a/docs/html/functions_s.html b/docs/html/functions_s.html new file mode 100644 index 00000000..b8827b65 --- /dev/null +++ b/docs/html/functions_s.html @@ -0,0 +1,129 @@ + + + + + + + +LogDoctor: Class Members + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Here is a list of all documented class members with links to the class documentation for each member:
+ +

- s -

+
+ + + + diff --git a/docs/html/functions_t.html b/docs/html/functions_t.html new file mode 100644 index 00000000..86109faf --- /dev/null +++ b/docs/html/functions_t.html @@ -0,0 +1,87 @@ + + + + + + + +LogDoctor: Class Members + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Here is a list of all documented class members with links to the class documentation for each member:
+ +

- t -

+
+ + + + diff --git a/docs/html/functions_u.html b/docs/html/functions_u.html new file mode 100644 index 00000000..5dab1273 --- /dev/null +++ b/docs/html/functions_u.html @@ -0,0 +1,96 @@ + + + + + + + +LogDoctor: Class Members + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Here is a list of all documented class members with links to the class documentation for each member:
+ +

- u -

+
+ + + + diff --git a/docs/html/functions_v.html b/docs/html/functions_v.html new file mode 100644 index 00000000..9e2af1e8 --- /dev/null +++ b/docs/html/functions_v.html @@ -0,0 +1,86 @@ + + + + + + + +LogDoctor: Class Members + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Here is a list of all documented class members with links to the class documentation for each member:
+ +

- v -

+
+ + + + diff --git a/docs/html/functions_vars.html b/docs/html/functions_vars.html new file mode 100644 index 00000000..b8f655be --- /dev/null +++ b/docs/html/functions_vars.html @@ -0,0 +1,185 @@ + + + + + + + +LogDoctor: Class Members - Variables + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+  + +

- a -

+ + +

- c -

+ + +

- d -

+ + +

- e -

+ + +

- f -

+ + +

- h -

+ + +

- i -

+ + +

- k -

+ + +

- l -

+ + +

- m -

+ + +

- n -

+ + +

- p -

+ + +

- s -

+ + +

- t -

+ + +

- u -

+ + +

- x -

+ + +

- y -

+
+ + + + diff --git a/docs/html/functions_w.html b/docs/html/functions_w.html new file mode 100644 index 00000000..4ce774c7 --- /dev/null +++ b/docs/html/functions_w.html @@ -0,0 +1,96 @@ + + + + + + + +LogDoctor: Class Members + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Here is a list of all documented class members with links to the class documentation for each member:
+ +

- w -

+
+ + + + diff --git a/docs/html/functions_x.html b/docs/html/functions_x.html new file mode 100644 index 00000000..8e927b67 --- /dev/null +++ b/docs/html/functions_x.html @@ -0,0 +1,86 @@ + + + + + + + +LogDoctor: Class Members + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Here is a list of all documented class members with links to the class documentation for each member:
+ +

- x -

+
+ + + + diff --git a/docs/html/functions_y.html b/docs/html/functions_y.html new file mode 100644 index 00000000..0bfa5106 --- /dev/null +++ b/docs/html/functions_y.html @@ -0,0 +1,86 @@ + + + + + + + +LogDoctor: Class Members + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Here is a list of all documented class members with links to the class documentation for each member:
+ +

- y -

+
+ + + + diff --git a/docs/html/hierarchy.html b/docs/html/hierarchy.html new file mode 100644 index 00000000..1fab20d3 --- /dev/null +++ b/docs/html/hierarchy.html @@ -0,0 +1,142 @@ + + + + + + + +LogDoctor: Class Hierarchy + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
Class Hierarchy
+
+
+
This inheritance list is sorted roughly, but not completely, alphabetically:
+
[detail level 12]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
 CBodyPartInstance of a part of the body of the snake
 CCraplog::BWlistStructure to hold the items of a blacklist/warnlist
 CCheckSecCheckSec
 CColorSecColorSec
 CCraplogCraplog
 CCrapviewCrapview
 CDateTimeOpsDateTimeOps
 CDbQuery
 Cstd::exception
 CBWlistExceptionBWlistException
 CDateTimeExceptionDateTimeException
 CGenericExceptionGenericException
 CLogFormatExceptionLogFormatException
 CLogParserExceptionLogParserException
 CWebServerExceptionWebServerException
 CFood
 CFormatOpsFormatOps
 CGameSecGameSec
 CGZutilsGZUtils
 CHashOpsHashOps
 CIOutilsIOUtils
 CCraplog::LogFileStructure which holds informations about a log file
 CCraplog::LogNameWeb Server specific file names criterions
 CLogOpsLogOps
 CFormatOps::LogsFormatStructure which holds informations about a log format
 CQChart
 CDonutBreakdownDonutBreakdon
 CQDialog
 CDialogBoolDialogBool
 CDialogDiaDialogDia
 CDialogMsgDialogMsg
 CQMainWindow
 CMainWindowMainWindow
 CQObject
 CDialogSecDialogSec
 CRichTextRichText
 CTRTR
 CQPieSlice
 CMainSliceRepresents a slice
 CQWidget
 CCraphelpCraphelp
 CCrapinfoCrapinfo
 CCrapnoteCrapnote
 CCrapupCrapup
 CCrissCrossCrissCross
 CSnakeGameSnake
 CSHA256
 CStoreOpsStoreOps
 CStringOpsStringOps
 CStyleSecStyleSec
 CTextBrowserTextBrowser
 CSnake::Tile
 CVecOps< T >VecOps
 Cstd::vector
 CSnake
+
+
+ + + + diff --git a/docs/html/index.html b/docs/html/index.html new file mode 100644 index 00000000..9cb6671b --- /dev/null +++ b/docs/html/index.html @@ -0,0 +1,83 @@ + + + + + + + +LogDoctor: Main Page + + + + + + + + + +
+
+ + + + + + + +
+
LogDoctor 2.00 +
+
Parse Apache2/Nginx/IIS logs and create statistics
+
+
+ + + + + + + +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
LogDoctor Documentation
+
+
+
+ + + + diff --git a/docs/html/jquery.js b/docs/html/jquery.js new file mode 100644 index 00000000..1dffb65b --- /dev/null +++ b/docs/html/jquery.js @@ -0,0 +1,34 @@ +/*! jQuery v3.6.0 | (c) OpenJS Foundation and other contributors | jquery.org/license */ +!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(C,e){"use strict";var t=[],r=Object.getPrototypeOf,s=t.slice,g=t.flat?function(e){return t.flat.call(e)}:function(e){return t.concat.apply([],e)},u=t.push,i=t.indexOf,n={},o=n.toString,v=n.hasOwnProperty,a=v.toString,l=a.call(Object),y={},m=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType&&"function"!=typeof e.item},x=function(e){return null!=e&&e===e.window},E=C.document,c={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||E).createElement("script");if(o.text=e,t)for(r in c)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.6.0",S=function(e,t){return new S.fn.init(e,t)};function p(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!m(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp(F),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+F),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\[\\da-fA-F]{1,6}"+M+"?|\\\\([^\\r\\n\\f])","g"),ne=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(p.childNodes),p.childNodes),t[p.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&y(e,a)&&a.id===i)return n.push(a),n}else{if(u[2])return H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!N[t+" "]&&(!v||!v.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&(U.test(t)||z.test(t))){(f=ee.test(t)&&ye(e.parentNode)||e)===e&&d.scope||((s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=S)),o=(l=h(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+xe(l[o]);c=l.join(",")}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){N(t,!0)}finally{s===S&&e.removeAttribute("id")}}}return g(t.replace($,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[S]=!0,e}function ce(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split("|"),r=n.length;while(r--)b.attrHandle[n[r]]=t}function pe(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function de(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function he(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function ge(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ve(a){return le(function(o){return o=+o,le(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function ye(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}for(e in d=se.support={},i=se.isXML=function(e){var t=e&&e.namespaceURI,n=e&&(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||"HTML")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:p;return r!=C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),p!=C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.scope=ce(function(e){return a.appendChild(e).appendChild(C.createElement("div")),"undefined"!=typeof e.querySelectorAll&&!e.querySelectorAll(":scope fieldset div").length}),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=S,!C.getElementsByName||!C.getElementsByName(S).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(te,ne);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){var t;a.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+S+"-]").length||v.push("~="),(t=C.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||v.push("\\["+M+"*name"+M+"*="+M+"*(?:''|\"\")"),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+S+"+*").length||v.push(".#.+[+~]"),e.querySelectorAll("\\\f"),v.push("[\\r\\n\\f]")}),ce(function(e){e.innerHTML="";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&v.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&v.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),v.push(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",F)}),v=v.length&&new RegExp(v.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),y=t||K.test(a.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},j=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e==C||e.ownerDocument==p&&y(p,e)?-1:t==C||t.ownerDocument==p&&y(p,t)?1:u?P(u,e)-P(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e==C?-1:t==C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?pe(a[r],s[r]):a[r]==p?-1:s[r]==p?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if(T(e),d.matchesSelector&&E&&!N[t+" "]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){N(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=h(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=m[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&m(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=se.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function j(e,n,r){return m(n)?S.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?S.grep(e,function(e){return e===n!==r}):"string"!=typeof n?S.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(S.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||D,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:q.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof S?t[0]:t,S.merge(this,S.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),N.test(r[1])&&S.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(S):S.makeArray(e,this)}).prototype=S.fn,D=S(E);var L=/^(?:parents|prev(?:Until|All))/,H={children:!0,contents:!0,next:!0,prev:!0};function O(e,t){while((e=e[t])&&1!==e.nodeType);return e}S.fn.extend({has:function(e){var t=S(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i;ce=E.createDocumentFragment().appendChild(E.createElement("div")),(fe=E.createElement("input")).setAttribute("type","radio"),fe.setAttribute("checked","checked"),fe.setAttribute("name","t"),ce.appendChild(fe),y.checkClone=ce.cloneNode(!0).cloneNode(!0).lastChild.checked,ce.innerHTML="",y.noCloneChecked=!!ce.cloneNode(!0).lastChild.defaultValue,ce.innerHTML="",y.option=!!ce.lastChild;var ge={thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};function ve(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?S.merge([e],n):n}function ye(e,t){for(var n=0,r=e.length;n",""]);var me=/<|&#?\w+;/;function xe(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d\s*$/g;function je(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&S(e).children("tbody")[0]||e}function De(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function qe(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Le(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(Y.hasData(e)&&(s=Y.get(e).events))for(i in Y.remove(t,"handle events"),s)for(n=0,r=s[i].length;n").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var _t,zt=[],Ut=/(=)\?(?=&|$)|\?\?/;S.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=zt.pop()||S.expando+"_"+wt.guid++;return this[e]=!0,e}}),S.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Ut.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Ut.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Ut,"$1"+r):!1!==e.jsonp&&(e.url+=(Tt.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||S.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?S(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,zt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),y.createHTMLDocument=((_t=E.implementation.createHTMLDocument("").body).innerHTML="
",2===_t.childNodes.length),S.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=N.exec(e))?[t.createElement(i[1])]:(i=xe([e],t,o),o&&o.length&&S(o).remove(),S.merge([],i.childNodes)));var r,i,o},S.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(S.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},S.expr.pseudos.animated=function(t){return S.grep(S.timers,function(e){return t===e.elem}).length},S.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=S.css(e,"position"),c=S(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=S.css(e,"top"),u=S.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),m(t)&&(t=t.call(e,n,S.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):c.css(f)}},S.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){S.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===S.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===S.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=S(e).offset()).top+=S.css(e,"borderTopWidth",!0),i.left+=S.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-S.css(r,"marginTop",!0),left:t.left-i.left-S.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===S.css(e,"position"))e=e.offsetParent;return e||re})}}),S.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;S.fn[t]=function(e){return $(this,function(e,t,n){var r;if(x(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),S.each(["top","left"],function(e,n){S.cssHooks[n]=Fe(y.pixelPosition,function(e,t){if(t)return t=We(e,n),Pe.test(t)?S(e).position()[n]+"px":t})}),S.each({Height:"height",Width:"width"},function(a,s){S.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){S.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return $(this,function(e,t,n){var r;return x(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?S.css(e,t,i):S.style(e,t,n,i)},s,n?e:void 0,n)}})}),S.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){S.fn[t]=function(e){return this.on(t,e)}}),S.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),S.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){S.fn[n]=function(e,t){return 0",options:{classes:{},disabled:!1,create:null},_createWidget:function(t,e){e=y(e||this.defaultElement||this)[0],this.element=y(e),this.uuid=i++,this.eventNamespace="."+this.widgetName+this.uuid,this.bindings=y(),this.hoverable=y(),this.focusable=y(),this.classesElementLookup={},e!==this&&(y.data(e,this.widgetFullName,this),this._on(!0,this.element,{remove:function(t){t.target===e&&this.destroy()}}),this.document=y(e.style?e.ownerDocument:e.document||e),this.window=y(this.document[0].defaultView||this.document[0].parentWindow)),this.options=y.widget.extend({},this.options,this._getCreateOptions(),t),this._create(),this.options.disabled&&this._setOptionDisabled(this.options.disabled),this._trigger("create",null,this._getCreateEventData()),this._init()},_getCreateOptions:function(){return{}},_getCreateEventData:y.noop,_create:y.noop,_init:y.noop,destroy:function(){var i=this;this._destroy(),y.each(this.classesElementLookup,function(t,e){i._removeClass(e,t)}),this.element.off(this.eventNamespace).removeData(this.widgetFullName),this.widget().off(this.eventNamespace).removeAttr("aria-disabled"),this.bindings.off(this.eventNamespace)},_destroy:y.noop,widget:function(){return this.element},option:function(t,e){var i,s,n,o=t;if(0===arguments.length)return y.widget.extend({},this.options);if("string"==typeof t)if(o={},t=(i=t.split(".")).shift(),i.length){for(s=o[t]=y.widget.extend({},this.options[t]),n=0;n
"),i=e.children()[0];return y("body").append(e),t=i.offsetWidth,e.css("overflow","scroll"),t===(i=i.offsetWidth)&&(i=e[0].clientWidth),e.remove(),s=t-i},getScrollInfo:function(t){var e=t.isWindow||t.isDocument?"":t.element.css("overflow-x"),i=t.isWindow||t.isDocument?"":t.element.css("overflow-y"),e="scroll"===e||"auto"===e&&t.widthx(D(s),D(n))?o.important="horizontal":o.important="vertical",p.using.call(this,t,o)}),h.offset(y.extend(l,{using:t}))})},y.ui.position={fit:{left:function(t,e){var i=e.within,s=i.isWindow?i.scrollLeft:i.offset.left,n=i.width,o=t.left-e.collisionPosition.marginLeft,h=s-o,a=o+e.collisionWidth-n-s;e.collisionWidth>n?0n?0=this.options.distance},_mouseDelayMet:function(){return this.mouseDelayMet},_mouseStart:function(){},_mouseDrag:function(){},_mouseStop:function(){},_mouseCapture:function(){return!0}}),y.ui.plugin={add:function(t,e,i){var s,n=y.ui[t].prototype;for(s in i)n.plugins[s]=n.plugins[s]||[],n.plugins[s].push([e,i[s]])},call:function(t,e,i,s){var n,o=t.plugins[e];if(o&&(s||t.element[0].parentNode&&11!==t.element[0].parentNode.nodeType))for(n=0;n").css({overflow:"hidden",position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(),top:this.element.css("top"),left:this.element.css("left")})),this.element=this.element.parent().data("ui-resizable",this.element.resizable("instance")),this.elementIsWrapper=!0,t={marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom"),marginLeft:this.originalElement.css("marginLeft")},this.element.css(t),this.originalElement.css("margin",0),this.originalResizeStyle=this.originalElement.css("resize"),this.originalElement.css("resize","none"),this._proportionallyResizeElements.push(this.originalElement.css({position:"static",zoom:1,display:"block"})),this.originalElement.css(t),this._proportionallyResize()),this._setupHandles(),e.autoHide&&y(this.element).on("mouseenter",function(){e.disabled||(i._removeClass("ui-resizable-autohide"),i._handles.show())}).on("mouseleave",function(){e.disabled||i.resizing||(i._addClass("ui-resizable-autohide"),i._handles.hide())}),this._mouseInit()},_destroy:function(){this._mouseDestroy(),this._addedHandles.remove();function t(t){y(t).removeData("resizable").removeData("ui-resizable").off(".resizable")}var e;return this.elementIsWrapper&&(t(this.element),e=this.element,this.originalElement.css({position:e.css("position"),width:e.outerWidth(),height:e.outerHeight(),top:e.css("top"),left:e.css("left")}).insertAfter(e),e.remove()),this.originalElement.css("resize",this.originalResizeStyle),t(this.originalElement),this},_setOption:function(t,e){switch(this._super(t,e),t){case"handles":this._removeHandles(),this._setupHandles();break;case"aspectRatio":this._aspectRatio=!!e}},_setupHandles:function(){var t,e,i,s,n,o=this.options,h=this;if(this.handles=o.handles||(y(".ui-resizable-handle",this.element).length?{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne",nw:".ui-resizable-nw"}:"e,s,se"),this._handles=y(),this._addedHandles=y(),this.handles.constructor===String)for("all"===this.handles&&(this.handles="n,e,s,w,se,sw,ne,nw"),i=this.handles.split(","),this.handles={},e=0;e"),this._addClass(n,"ui-resizable-handle "+s),n.css({zIndex:o.zIndex}),this.handles[t]=".ui-resizable-"+t,this.element.children(this.handles[t]).length||(this.element.append(n),this._addedHandles=this._addedHandles.add(n));this._renderAxis=function(t){var e,i,s;for(e in t=t||this.element,this.handles)this.handles[e].constructor===String?this.handles[e]=this.element.children(this.handles[e]).first().show():(this.handles[e].jquery||this.handles[e].nodeType)&&(this.handles[e]=y(this.handles[e]),this._on(this.handles[e],{mousedown:h._mouseDown})),this.elementIsWrapper&&this.originalElement[0].nodeName.match(/^(textarea|input|select|button)$/i)&&(i=y(this.handles[e],this.element),s=/sw|ne|nw|se|n|s/.test(e)?i.outerHeight():i.outerWidth(),i=["padding",/ne|nw|n/.test(e)?"Top":/se|sw|s/.test(e)?"Bottom":/^e$/.test(e)?"Right":"Left"].join(""),t.css(i,s),this._proportionallyResize()),this._handles=this._handles.add(this.handles[e])},this._renderAxis(this.element),this._handles=this._handles.add(this.element.find(".ui-resizable-handle")),this._handles.disableSelection(),this._handles.on("mouseover",function(){h.resizing||(this.className&&(n=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i)),h.axis=n&&n[1]?n[1]:"se")}),o.autoHide&&(this._handles.hide(),this._addClass("ui-resizable-autohide"))},_removeHandles:function(){this._addedHandles.remove()},_mouseCapture:function(t){var e,i,s=!1;for(e in this.handles)(i=y(this.handles[e])[0])!==t.target&&!y.contains(i,t.target)||(s=!0);return!this.options.disabled&&s},_mouseStart:function(t){var e,i,s=this.options,n=this.element;return this.resizing=!0,this._renderProxy(),e=this._num(this.helper.css("left")),i=this._num(this.helper.css("top")),s.containment&&(e+=y(s.containment).scrollLeft()||0,i+=y(s.containment).scrollTop()||0),this.offset=this.helper.offset(),this.position={left:e,top:i},this.size=this._helper?{width:this.helper.width(),height:this.helper.height()}:{width:n.width(),height:n.height()},this.originalSize=this._helper?{width:n.outerWidth(),height:n.outerHeight()}:{width:n.width(),height:n.height()},this.sizeDiff={width:n.outerWidth()-n.width(),height:n.outerHeight()-n.height()},this.originalPosition={left:e,top:i},this.originalMousePosition={left:t.pageX,top:t.pageY},this.aspectRatio="number"==typeof s.aspectRatio?s.aspectRatio:this.originalSize.width/this.originalSize.height||1,s=y(".ui-resizable-"+this.axis).css("cursor"),y("body").css("cursor","auto"===s?this.axis+"-resize":s),this._addClass("ui-resizable-resizing"),this._propagate("start",t),!0},_mouseDrag:function(t){var e=this.originalMousePosition,i=this.axis,s=t.pageX-e.left||0,e=t.pageY-e.top||0,i=this._change[i];return this._updatePrevProperties(),i&&(e=i.apply(this,[t,s,e]),this._updateVirtualBoundaries(t.shiftKey),(this._aspectRatio||t.shiftKey)&&(e=this._updateRatio(e,t)),e=this._respectSize(e,t),this._updateCache(e),this._propagate("resize",t),e=this._applyChanges(),!this._helper&&this._proportionallyResizeElements.length&&this._proportionallyResize(),y.isEmptyObject(e)||(this._updatePrevProperties(),this._trigger("resize",t,this.ui()),this._applyChanges())),!1},_mouseStop:function(t){this.resizing=!1;var e,i,s,n=this.options,o=this;return this._helper&&(s=(e=(i=this._proportionallyResizeElements).length&&/textarea/i.test(i[0].nodeName))&&this._hasScroll(i[0],"left")?0:o.sizeDiff.height,i=e?0:o.sizeDiff.width,e={width:o.helper.width()-i,height:o.helper.height()-s},i=parseFloat(o.element.css("left"))+(o.position.left-o.originalPosition.left)||null,s=parseFloat(o.element.css("top"))+(o.position.top-o.originalPosition.top)||null,n.animate||this.element.css(y.extend(e,{top:s,left:i})),o.helper.height(o.size.height),o.helper.width(o.size.width),this._helper&&!n.animate&&this._proportionallyResize()),y("body").css("cursor","auto"),this._removeClass("ui-resizable-resizing"),this._propagate("stop",t),this._helper&&this.helper.remove(),!1},_updatePrevProperties:function(){this.prevPosition={top:this.position.top,left:this.position.left},this.prevSize={width:this.size.width,height:this.size.height}},_applyChanges:function(){var t={};return this.position.top!==this.prevPosition.top&&(t.top=this.position.top+"px"),this.position.left!==this.prevPosition.left&&(t.left=this.position.left+"px"),this.size.width!==this.prevSize.width&&(t.width=this.size.width+"px"),this.size.height!==this.prevSize.height&&(t.height=this.size.height+"px"),this.helper.css(t),t},_updateVirtualBoundaries:function(t){var e,i,s=this.options,n={minWidth:this._isNumber(s.minWidth)?s.minWidth:0,maxWidth:this._isNumber(s.maxWidth)?s.maxWidth:1/0,minHeight:this._isNumber(s.minHeight)?s.minHeight:0,maxHeight:this._isNumber(s.maxHeight)?s.maxHeight:1/0};(this._aspectRatio||t)&&(e=n.minHeight*this.aspectRatio,i=n.minWidth/this.aspectRatio,s=n.maxHeight*this.aspectRatio,t=n.maxWidth/this.aspectRatio,e>n.minWidth&&(n.minWidth=e),i>n.minHeight&&(n.minHeight=i),st.width,h=this._isNumber(t.height)&&e.minHeight&&e.minHeight>t.height,a=this.originalPosition.left+this.originalSize.width,r=this.originalPosition.top+this.originalSize.height,l=/sw|nw|w/.test(i),i=/nw|ne|n/.test(i);return o&&(t.width=e.minWidth),h&&(t.height=e.minHeight),s&&(t.width=e.maxWidth),n&&(t.height=e.maxHeight),o&&l&&(t.left=a-e.minWidth),s&&l&&(t.left=a-e.maxWidth),h&&i&&(t.top=r-e.minHeight),n&&i&&(t.top=r-e.maxHeight),t.width||t.height||t.left||!t.top?t.width||t.height||t.top||!t.left||(t.left=null):t.top=null,t},_getPaddingPlusBorderDimensions:function(t){for(var e=0,i=[],s=[t.css("borderTopWidth"),t.css("borderRightWidth"),t.css("borderBottomWidth"),t.css("borderLeftWidth")],n=[t.css("paddingTop"),t.css("paddingRight"),t.css("paddingBottom"),t.css("paddingLeft")];e<4;e++)i[e]=parseFloat(s[e])||0,i[e]+=parseFloat(n[e])||0;return{height:i[0]+i[2],width:i[1]+i[3]}},_proportionallyResize:function(){if(this._proportionallyResizeElements.length)for(var t,e=0,i=this.helper||this.element;e").css({overflow:"hidden"}),this._addClass(this.helper,this._helper),this.helper.css({width:this.element.outerWidth(),height:this.element.outerHeight(),position:"absolute",left:this.elementOffset.left+"px",top:this.elementOffset.top+"px",zIndex:++e.zIndex}),this.helper.appendTo("body").disableSelection()):this.helper=this.element},_change:{e:function(t,e){return{width:this.originalSize.width+e}},w:function(t,e){var i=this.originalSize;return{left:this.originalPosition.left+e,width:i.width-e}},n:function(t,e,i){var s=this.originalSize;return{top:this.originalPosition.top+i,height:s.height-i}},s:function(t,e,i){return{height:this.originalSize.height+i}},se:function(t,e,i){return y.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[t,e,i]))},sw:function(t,e,i){return y.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[t,e,i]))},ne:function(t,e,i){return y.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[t,e,i]))},nw:function(t,e,i){return y.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[t,e,i]))}},_propagate:function(t,e){y.ui.plugin.call(this,t,[e,this.ui()]),"resize"!==t&&this._trigger(t,e,this.ui())},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition}}}),y.ui.plugin.add("resizable","animate",{stop:function(e){var i=y(this).resizable("instance"),t=i.options,s=i._proportionallyResizeElements,n=s.length&&/textarea/i.test(s[0].nodeName),o=n&&i._hasScroll(s[0],"left")?0:i.sizeDiff.height,h=n?0:i.sizeDiff.width,n={width:i.size.width-h,height:i.size.height-o},h=parseFloat(i.element.css("left"))+(i.position.left-i.originalPosition.left)||null,o=parseFloat(i.element.css("top"))+(i.position.top-i.originalPosition.top)||null;i.element.animate(y.extend(n,o&&h?{top:o,left:h}:{}),{duration:t.animateDuration,easing:t.animateEasing,step:function(){var t={width:parseFloat(i.element.css("width")),height:parseFloat(i.element.css("height")),top:parseFloat(i.element.css("top")),left:parseFloat(i.element.css("left"))};s&&s.length&&y(s[0]).css({width:t.width,height:t.height}),i._updateCache(t),i._propagate("resize",e)}})}}),y.ui.plugin.add("resizable","containment",{start:function(){var i,s,n=y(this).resizable("instance"),t=n.options,e=n.element,o=t.containment,h=o instanceof y?o.get(0):/parent/.test(o)?e.parent().get(0):o;h&&(n.containerElement=y(h),/document/.test(o)||o===document?(n.containerOffset={left:0,top:0},n.containerPosition={left:0,top:0},n.parentData={element:y(document),left:0,top:0,width:y(document).width(),height:y(document).height()||document.body.parentNode.scrollHeight}):(i=y(h),s=[],y(["Top","Right","Left","Bottom"]).each(function(t,e){s[t]=n._num(i.css("padding"+e))}),n.containerOffset=i.offset(),n.containerPosition=i.position(),n.containerSize={height:i.innerHeight()-s[3],width:i.innerWidth()-s[1]},t=n.containerOffset,e=n.containerSize.height,o=n.containerSize.width,o=n._hasScroll(h,"left")?h.scrollWidth:o,e=n._hasScroll(h)?h.scrollHeight:e,n.parentData={element:h,left:t.left,top:t.top,width:o,height:e}))},resize:function(t){var e=y(this).resizable("instance"),i=e.options,s=e.containerOffset,n=e.position,o=e._aspectRatio||t.shiftKey,h={top:0,left:0},a=e.containerElement,t=!0;a[0]!==document&&/static/.test(a.css("position"))&&(h=s),n.left<(e._helper?s.left:0)&&(e.size.width=e.size.width+(e._helper?e.position.left-s.left:e.position.left-h.left),o&&(e.size.height=e.size.width/e.aspectRatio,t=!1),e.position.left=i.helper?s.left:0),n.top<(e._helper?s.top:0)&&(e.size.height=e.size.height+(e._helper?e.position.top-s.top:e.position.top),o&&(e.size.width=e.size.height*e.aspectRatio,t=!1),e.position.top=e._helper?s.top:0),i=e.containerElement.get(0)===e.element.parent().get(0),n=/relative|absolute/.test(e.containerElement.css("position")),i&&n?(e.offset.left=e.parentData.left+e.position.left,e.offset.top=e.parentData.top+e.position.top):(e.offset.left=e.element.offset().left,e.offset.top=e.element.offset().top),n=Math.abs(e.sizeDiff.width+(e._helper?e.offset.left-h.left:e.offset.left-s.left)),s=Math.abs(e.sizeDiff.height+(e._helper?e.offset.top-h.top:e.offset.top-s.top)),n+e.size.width>=e.parentData.width&&(e.size.width=e.parentData.width-n,o&&(e.size.height=e.size.width/e.aspectRatio,t=!1)),s+e.size.height>=e.parentData.height&&(e.size.height=e.parentData.height-s,o&&(e.size.width=e.size.height*e.aspectRatio,t=!1)),t||(e.position.left=e.prevPosition.left,e.position.top=e.prevPosition.top,e.size.width=e.prevSize.width,e.size.height=e.prevSize.height)},stop:function(){var t=y(this).resizable("instance"),e=t.options,i=t.containerOffset,s=t.containerPosition,n=t.containerElement,o=y(t.helper),h=o.offset(),a=o.outerWidth()-t.sizeDiff.width,o=o.outerHeight()-t.sizeDiff.height;t._helper&&!e.animate&&/relative/.test(n.css("position"))&&y(this).css({left:h.left-s.left-i.left,width:a,height:o}),t._helper&&!e.animate&&/static/.test(n.css("position"))&&y(this).css({left:h.left-s.left-i.left,width:a,height:o})}}),y.ui.plugin.add("resizable","alsoResize",{start:function(){var t=y(this).resizable("instance").options;y(t.alsoResize).each(function(){var t=y(this);t.data("ui-resizable-alsoresize",{width:parseFloat(t.width()),height:parseFloat(t.height()),left:parseFloat(t.css("left")),top:parseFloat(t.css("top"))})})},resize:function(t,i){var e=y(this).resizable("instance"),s=e.options,n=e.originalSize,o=e.originalPosition,h={height:e.size.height-n.height||0,width:e.size.width-n.width||0,top:e.position.top-o.top||0,left:e.position.left-o.left||0};y(s.alsoResize).each(function(){var t=y(this),s=y(this).data("ui-resizable-alsoresize"),n={},e=t.parents(i.originalElement[0]).length?["width","height"]:["width","height","top","left"];y.each(e,function(t,e){var i=(s[e]||0)+(h[e]||0);i&&0<=i&&(n[e]=i||null)}),t.css(n)})},stop:function(){y(this).removeData("ui-resizable-alsoresize")}}),y.ui.plugin.add("resizable","ghost",{start:function(){var t=y(this).resizable("instance"),e=t.size;t.ghost=t.originalElement.clone(),t.ghost.css({opacity:.25,display:"block",position:"relative",height:e.height,width:e.width,margin:0,left:0,top:0}),t._addClass(t.ghost,"ui-resizable-ghost"),!1!==y.uiBackCompat&&"string"==typeof t.options.ghost&&t.ghost.addClass(this.options.ghost),t.ghost.appendTo(t.helper)},resize:function(){var t=y(this).resizable("instance");t.ghost&&t.ghost.css({position:"relative",height:t.size.height,width:t.size.width})},stop:function(){var t=y(this).resizable("instance");t.ghost&&t.helper&&t.helper.get(0).removeChild(t.ghost.get(0))}}),y.ui.plugin.add("resizable","grid",{resize:function(){var t,e=y(this).resizable("instance"),i=e.options,s=e.size,n=e.originalSize,o=e.originalPosition,h=e.axis,a="number"==typeof i.grid?[i.grid,i.grid]:i.grid,r=a[0]||1,l=a[1]||1,u=Math.round((s.width-n.width)/r)*r,p=Math.round((s.height-n.height)/l)*l,d=n.width+u,c=n.height+p,f=i.maxWidth&&i.maxWidthd,s=i.minHeight&&i.minHeight>c;i.grid=a,m&&(d+=r),s&&(c+=l),f&&(d-=r),g&&(c-=l),/^(se|s|e)$/.test(h)?(e.size.width=d,e.size.height=c):/^(ne)$/.test(h)?(e.size.width=d,e.size.height=c,e.position.top=o.top-p):/^(sw)$/.test(h)?(e.size.width=d,e.size.height=c,e.position.left=o.left-u):((c-l<=0||d-r<=0)&&(t=e._getPaddingPlusBorderDimensions(this)),0=f[g]?0:Math.min(f[g],n));!a&&1-1){targetElements.on(evt+EVENT_NAMESPACE,function elementToggle(event){$.powerTip.toggle(this,event)})}else{targetElements.on(evt+EVENT_NAMESPACE,function elementOpen(event){$.powerTip.show(this,event)})}});$.each(options.closeEvents,function(idx,evt){if($.inArray(evt,options.openEvents)<0){targetElements.on(evt+EVENT_NAMESPACE,function elementClose(event){$.powerTip.hide(this,!isMouseEvent(event))})}});targetElements.on("keydown"+EVENT_NAMESPACE,function elementKeyDown(event){if(event.keyCode===27){$.powerTip.hide(this,true)}})}return targetElements};$.fn.powerTip.defaults={fadeInTime:200,fadeOutTime:100,followMouse:false,popupId:"powerTip",popupClass:null,intentSensitivity:7,intentPollInterval:100,closeDelay:100,placement:"n",smartPlacement:false,offset:10,mouseOnToPopup:false,manual:false,openEvents:["mouseenter","focus"],closeEvents:["mouseleave","blur"]};$.fn.powerTip.smartPlacementLists={n:["n","ne","nw","s"],e:["e","ne","se","w","nw","sw","n","s","e"],s:["s","se","sw","n"],w:["w","nw","sw","e","ne","se","n","s","w"],nw:["nw","w","sw","n","s","se","nw"],ne:["ne","e","se","n","s","sw","ne"],sw:["sw","w","nw","s","n","ne","sw"],se:["se","e","ne","s","n","nw","se"],"nw-alt":["nw-alt","n","ne-alt","sw-alt","s","se-alt","w","e"],"ne-alt":["ne-alt","n","nw-alt","se-alt","s","sw-alt","e","w"],"sw-alt":["sw-alt","s","se-alt","nw-alt","n","ne-alt","w","e"],"se-alt":["se-alt","s","sw-alt","ne-alt","n","nw-alt","e","w"]};$.powerTip={show:function apiShowTip(element,event){if(isMouseEvent(event)){trackMouse(event);session.previousX=event.pageX;session.previousY=event.pageY;$(element).data(DATA_DISPLAYCONTROLLER).show()}else{$(element).first().data(DATA_DISPLAYCONTROLLER).show(true,true)}return element},reposition:function apiResetPosition(element){$(element).first().data(DATA_DISPLAYCONTROLLER).resetPosition();return element},hide:function apiCloseTip(element,immediate){var displayController;immediate=element?immediate:true;if(element){displayController=$(element).first().data(DATA_DISPLAYCONTROLLER)}else if(session.activeHover){displayController=session.activeHover.data(DATA_DISPLAYCONTROLLER)}if(displayController){displayController.hide(immediate)}return element},toggle:function apiToggle(element,event){if(session.activeHover&&session.activeHover.is(element)){$.powerTip.hide(element,!isMouseEvent(event))}else{$.powerTip.show(element,event)}return element}};$.powerTip.showTip=$.powerTip.show;$.powerTip.closeTip=$.powerTip.hide;function CSSCoordinates(){var me=this;me.top="auto";me.left="auto";me.right="auto";me.bottom="auto";me.set=function(property,value){if($.isNumeric(value)){me[property]=Math.round(value)}}}function DisplayController(element,options,tipController){var hoverTimer=null,myCloseDelay=null;function openTooltip(immediate,forceOpen){cancelTimer();if(!element.data(DATA_HASACTIVEHOVER)){if(!immediate){session.tipOpenImminent=true;hoverTimer=setTimeout(function intentDelay(){hoverTimer=null;checkForIntent()},options.intentPollInterval)}else{if(forceOpen){element.data(DATA_FORCEDOPEN,true)}closeAnyDelayed();tipController.showTip(element)}}else{cancelClose()}}function closeTooltip(disableDelay){if(myCloseDelay){myCloseDelay=session.closeDelayTimeout=clearTimeout(myCloseDelay);session.delayInProgress=false}cancelTimer();session.tipOpenImminent=false;if(element.data(DATA_HASACTIVEHOVER)){element.data(DATA_FORCEDOPEN,false);if(!disableDelay){session.delayInProgress=true;session.closeDelayTimeout=setTimeout(function closeDelay(){session.closeDelayTimeout=null;tipController.hideTip(element);session.delayInProgress=false;myCloseDelay=null},options.closeDelay);myCloseDelay=session.closeDelayTimeout}else{tipController.hideTip(element)}}}function checkForIntent(){var xDifference=Math.abs(session.previousX-session.currentX),yDifference=Math.abs(session.previousY-session.currentY),totalDifference=xDifference+yDifference;if(totalDifference",{id:options.popupId});if($body.length===0){$body=$("body")}$body.append(tipElement);session.tooltips=session.tooltips?session.tooltips.add(tipElement):tipElement}if(options.followMouse){if(!tipElement.data(DATA_HASMOUSEMOVE)){$document.on("mousemove"+EVENT_NAMESPACE,positionTipOnCursor);$window.on("scroll"+EVENT_NAMESPACE,positionTipOnCursor);tipElement.data(DATA_HASMOUSEMOVE,true)}}function beginShowTip(element){element.data(DATA_HASACTIVEHOVER,true);tipElement.queue(function queueTipInit(next){showTip(element);next()})}function showTip(element){var tipContent;if(!element.data(DATA_HASACTIVEHOVER)){return}if(session.isTipOpen){if(!session.isClosing){hideTip(session.activeHover)}tipElement.delay(100).queue(function queueTipAgain(next){showTip(element);next()});return}element.trigger("powerTipPreRender");tipContent=getTooltipContent(element);if(tipContent){tipElement.empty().append(tipContent)}else{return}element.trigger("powerTipRender");session.activeHover=element;session.isTipOpen=true;tipElement.data(DATA_MOUSEONTOTIP,options.mouseOnToPopup);tipElement.addClass(options.popupClass);if(!options.followMouse||element.data(DATA_FORCEDOPEN)){positionTipOnElement(element);session.isFixedTipOpen=true}else{positionTipOnCursor()}if(!element.data(DATA_FORCEDOPEN)&&!options.followMouse){$document.on("click"+EVENT_NAMESPACE,function documentClick(event){var target=event.target;if(target!==element[0]){if(options.mouseOnToPopup){if(target!==tipElement[0]&&!$.contains(tipElement[0],target)){$.powerTip.hide()}}else{$.powerTip.hide()}}})}if(options.mouseOnToPopup&&!options.manual){tipElement.on("mouseenter"+EVENT_NAMESPACE,function tipMouseEnter(){if(session.activeHover){session.activeHover.data(DATA_DISPLAYCONTROLLER).cancel()}});tipElement.on("mouseleave"+EVENT_NAMESPACE,function tipMouseLeave(){if(session.activeHover){session.activeHover.data(DATA_DISPLAYCONTROLLER).hide()}})}tipElement.fadeIn(options.fadeInTime,function fadeInCallback(){if(!session.desyncTimeout){session.desyncTimeout=setInterval(closeDesyncedTip,500)}element.trigger("powerTipOpen")})}function hideTip(element){session.isClosing=true;session.isTipOpen=false;session.desyncTimeout=clearInterval(session.desyncTimeout);element.data(DATA_HASACTIVEHOVER,false);element.data(DATA_FORCEDOPEN,false);$document.off("click"+EVENT_NAMESPACE);tipElement.off(EVENT_NAMESPACE);tipElement.fadeOut(options.fadeOutTime,function fadeOutCallback(){var coords=new CSSCoordinates;session.activeHover=null;session.isClosing=false;session.isFixedTipOpen=false;tipElement.removeClass();coords.set("top",session.currentY+options.offset);coords.set("left",session.currentX+options.offset);tipElement.css(coords);element.trigger("powerTipClose")})}function positionTipOnCursor(){var tipWidth,tipHeight,coords,collisions,collisionCount;if(!session.isFixedTipOpen&&(session.isTipOpen||session.tipOpenImminent&&tipElement.data(DATA_HASMOUSEMOVE))){tipWidth=tipElement.outerWidth();tipHeight=tipElement.outerHeight();coords=new CSSCoordinates;coords.set("top",session.currentY+options.offset);coords.set("left",session.currentX+options.offset);collisions=getViewportCollisions(coords,tipWidth,tipHeight);if(collisions!==Collision.none){collisionCount=countFlags(collisions);if(collisionCount===1){if(collisions===Collision.right){coords.set("left",session.scrollLeft+session.windowWidth-tipWidth)}else if(collisions===Collision.bottom){coords.set("top",session.scrollTop+session.windowHeight-tipHeight)}}else{coords.set("left",session.currentX-tipWidth-options.offset);coords.set("top",session.currentY-tipHeight-options.offset)}}tipElement.css(coords)}}function positionTipOnElement(element){var priorityList,finalPlacement;if(options.smartPlacement||options.followMouse&&element.data(DATA_FORCEDOPEN)){priorityList=$.fn.powerTip.smartPlacementLists[options.placement];$.each(priorityList,function(idx,pos){var collisions=getViewportCollisions(placeTooltip(element,pos),tipElement.outerWidth(),tipElement.outerHeight());finalPlacement=pos;return collisions!==Collision.none})}else{placeTooltip(element,options.placement);finalPlacement=options.placement}tipElement.removeClass("w nw sw e ne se n s w se-alt sw-alt ne-alt nw-alt");tipElement.addClass(finalPlacement)}function placeTooltip(element,placement){var iterationCount=0,tipWidth,tipHeight,coords=new CSSCoordinates;coords.set("top",0);coords.set("left",0);tipElement.css(coords);do{tipWidth=tipElement.outerWidth();tipHeight=tipElement.outerHeight();coords=placementCalculator.compute(element,placement,tipWidth,tipHeight,options.offset);tipElement.css(coords)}while(++iterationCount<=5&&(tipWidth!==tipElement.outerWidth()||tipHeight!==tipElement.outerHeight()));return coords}function closeDesyncedTip(){var isDesynced=false,hasDesyncableCloseEvent=$.grep(["mouseleave","mouseout","blur","focusout"],function(eventType){return $.inArray(eventType,options.closeEvents)!==-1}).length>0;if(session.isTipOpen&&!session.isClosing&&!session.delayInProgress&&hasDesyncableCloseEvent){if(session.activeHover.data(DATA_HASACTIVEHOVER)===false||session.activeHover.is(":disabled")){isDesynced=true}else if(!isMouseOver(session.activeHover)&&!session.activeHover.is(":focus")&&!session.activeHover.data(DATA_FORCEDOPEN)){if(tipElement.data(DATA_MOUSEONTOTIP)){if(!isMouseOver(tipElement)){isDesynced=true}}else{isDesynced=true}}if(isDesynced){hideTip(session.activeHover)}}}this.showTip=beginShowTip;this.hideTip=hideTip;this.resetPosition=positionTipOnElement}function isSvgElement(element){return Boolean(window.SVGElement&&element[0]instanceof SVGElement)}function isMouseEvent(event){return Boolean(event&&$.inArray(event.type,MOUSE_EVENTS)>-1&&typeof event.pageX==="number")}function initTracking(){if(!session.mouseTrackingActive){session.mouseTrackingActive=true;getViewportDimensions();$(getViewportDimensions);$document.on("mousemove"+EVENT_NAMESPACE,trackMouse);$window.on("resize"+EVENT_NAMESPACE,trackResize);$window.on("scroll"+EVENT_NAMESPACE,trackScroll)}}function getViewportDimensions(){session.scrollLeft=$window.scrollLeft();session.scrollTop=$window.scrollTop();session.windowWidth=$window.width();session.windowHeight=$window.height()}function trackResize(){session.windowWidth=$window.width();session.windowHeight=$window.height()}function trackScroll(){var x=$window.scrollLeft(),y=$window.scrollTop();if(x!==session.scrollLeft){session.currentX+=x-session.scrollLeft;session.scrollLeft=x}if(y!==session.scrollTop){session.currentY+=y-session.scrollTop;session.scrollTop=y}}function trackMouse(event){session.currentX=event.pageX;session.currentY=event.pageY}function isMouseOver(element){var elementPosition=element.offset(),elementBox=element[0].getBoundingClientRect(),elementWidth=elementBox.right-elementBox.left,elementHeight=elementBox.bottom-elementBox.top;return session.currentX>=elementPosition.left&&session.currentX<=elementPosition.left+elementWidth&&session.currentY>=elementPosition.top&&session.currentY<=elementPosition.top+elementHeight}function getTooltipContent(element){var tipText=element.data(DATA_POWERTIP),tipObject=element.data(DATA_POWERTIPJQ),tipTarget=element.data(DATA_POWERTIPTARGET),targetElement,content;if(tipText){if($.isFunction(tipText)){tipText=tipText.call(element[0])}content=tipText}else if(tipObject){if($.isFunction(tipObject)){tipObject=tipObject.call(element[0])}if(tipObject.length>0){content=tipObject.clone(true,true)}}else if(tipTarget){targetElement=$("#"+tipTarget);if(targetElement.length>0){content=targetElement.html()}}return content}function getViewportCollisions(coords,elementWidth,elementHeight){var viewportTop=session.scrollTop,viewportLeft=session.scrollLeft,viewportBottom=viewportTop+session.windowHeight,viewportRight=viewportLeft+session.windowWidth,collisions=Collision.none;if(coords.topviewportBottom||Math.abs(coords.bottom-session.windowHeight)>viewportBottom){collisions|=Collision.bottom}if(coords.leftviewportRight){collisions|=Collision.left}if(coords.left+elementWidth>viewportRight||coords.right1)){a.preventDefault();var c=a.originalEvent.changedTouches[0],d=document.createEvent("MouseEvents");d.initMouseEvent(b,!0,!0,window,1,c.screenX,c.screenY,c.clientX,c.clientY,!1,!1,!1,!1,0,null),a.target.dispatchEvent(d)}}if(a.support.touch="ontouchend"in document,a.support.touch){var e,b=a.ui.mouse.prototype,c=b._mouseInit,d=b._mouseDestroy;b._touchStart=function(a){var b=this;!e&&b._mouseCapture(a.originalEvent.changedTouches[0])&&(e=!0,b._touchMoved=!1,f(a,"mouseover"),f(a,"mousemove"),f(a,"mousedown"))},b._touchMove=function(a){e&&(this._touchMoved=!0,f(a,"mousemove"))},b._touchEnd=function(a){e&&(f(a,"mouseup"),f(a,"mouseout"),this._touchMoved||f(a,"click"),e=!1)},b._mouseInit=function(){var b=this;b.element.bind({touchstart:a.proxy(b,"_touchStart"),touchmove:a.proxy(b,"_touchMove"),touchend:a.proxy(b,"_touchEnd")}),c.call(b)},b._mouseDestroy=function(){var b=this;b.element.unbind({touchstart:a.proxy(b,"_touchStart"),touchmove:a.proxy(b,"_touchMove"),touchend:a.proxy(b,"_touchEnd")}),d.call(b)}}}(jQuery);/*! SmartMenus jQuery Plugin - v1.1.0 - September 17, 2017 + * http://www.smartmenus.org/ + * Copyright Vasil Dinkov, Vadikom Web Ltd. http://vadikom.com; Licensed MIT */(function(t){"function"==typeof define&&define.amd?define(["jquery"],t):"object"==typeof module&&"object"==typeof module.exports?module.exports=t(require("jquery")):t(jQuery)})(function($){function initMouseDetection(t){var e=".smartmenus_mouse";if(mouseDetectionEnabled||t)mouseDetectionEnabled&&t&&($(document).off(e),mouseDetectionEnabled=!1);else{var i=!0,s=null,o={mousemove:function(t){var e={x:t.pageX,y:t.pageY,timeStamp:(new Date).getTime()};if(s){var o=Math.abs(s.x-e.x),a=Math.abs(s.y-e.y);if((o>0||a>0)&&2>=o&&2>=a&&300>=e.timeStamp-s.timeStamp&&(mouse=!0,i)){var n=$(t.target).closest("a");n.is("a")&&$.each(menuTrees,function(){return $.contains(this.$root[0],n[0])?(this.itemEnter({currentTarget:n[0]}),!1):void 0}),i=!1}}s=e}};o[touchEvents?"touchstart":"pointerover pointermove pointerout MSPointerOver MSPointerMove MSPointerOut"]=function(t){isTouchEvent(t.originalEvent)&&(mouse=!1)},$(document).on(getEventsNS(o,e)),mouseDetectionEnabled=!0}}function isTouchEvent(t){return!/^(4|mouse)$/.test(t.pointerType)}function getEventsNS(t,e){e||(e="");var i={};for(var s in t)i[s.split(" ").join(e+" ")+e]=t[s];return i}var menuTrees=[],mouse=!1,touchEvents="ontouchstart"in window,mouseDetectionEnabled=!1,requestAnimationFrame=window.requestAnimationFrame||function(t){return setTimeout(t,1e3/60)},cancelAnimationFrame=window.cancelAnimationFrame||function(t){clearTimeout(t)},canAnimate=!!$.fn.animate;return $.SmartMenus=function(t,e){this.$root=$(t),this.opts=e,this.rootId="",this.accessIdPrefix="",this.$subArrow=null,this.activatedItems=[],this.visibleSubMenus=[],this.showTimeout=0,this.hideTimeout=0,this.scrollTimeout=0,this.clickActivated=!1,this.focusActivated=!1,this.zIndexInc=0,this.idInc=0,this.$firstLink=null,this.$firstSub=null,this.disabled=!1,this.$disableOverlay=null,this.$touchScrollingSub=null,this.cssTransforms3d="perspective"in t.style||"webkitPerspective"in t.style,this.wasCollapsible=!1,this.init()},$.extend($.SmartMenus,{hideAll:function(){$.each(menuTrees,function(){this.menuHideAll()})},destroy:function(){for(;menuTrees.length;)menuTrees[0].destroy();initMouseDetection(!0)},prototype:{init:function(t){var e=this;if(!t){menuTrees.push(this),this.rootId=((new Date).getTime()+Math.random()+"").replace(/\D/g,""),this.accessIdPrefix="sm-"+this.rootId+"-",this.$root.hasClass("sm-rtl")&&(this.opts.rightToLeftSubMenus=!0);var i=".smartmenus";this.$root.data("smartmenus",this).attr("data-smartmenus-id",this.rootId).dataSM("level",1).on(getEventsNS({"mouseover focusin":$.proxy(this.rootOver,this),"mouseout focusout":$.proxy(this.rootOut,this),keydown:$.proxy(this.rootKeyDown,this)},i)).on(getEventsNS({mouseenter:$.proxy(this.itemEnter,this),mouseleave:$.proxy(this.itemLeave,this),mousedown:$.proxy(this.itemDown,this),focus:$.proxy(this.itemFocus,this),blur:$.proxy(this.itemBlur,this),click:$.proxy(this.itemClick,this)},i),"a"),i+=this.rootId,this.opts.hideOnClick&&$(document).on(getEventsNS({touchstart:$.proxy(this.docTouchStart,this),touchmove:$.proxy(this.docTouchMove,this),touchend:$.proxy(this.docTouchEnd,this),click:$.proxy(this.docClick,this)},i)),$(window).on(getEventsNS({"resize orientationchange":$.proxy(this.winResize,this)},i)),this.opts.subIndicators&&(this.$subArrow=$("").addClass("sub-arrow"),this.opts.subIndicatorsText&&this.$subArrow.html(this.opts.subIndicatorsText)),initMouseDetection()}if(this.$firstSub=this.$root.find("ul").each(function(){e.menuInit($(this))}).eq(0),this.$firstLink=this.$root.find("a").eq(0),this.opts.markCurrentItem){var s=/(index|default)\.[^#\?\/]*/i,o=/#.*/,a=window.location.href.replace(s,""),n=a.replace(o,"");this.$root.find("a").each(function(){var t=this.href.replace(s,""),i=$(this);(t==a||t==n)&&(i.addClass("current"),e.opts.markCurrentTree&&i.parentsUntil("[data-smartmenus-id]","ul").each(function(){$(this).dataSM("parent-a").addClass("current")}))})}this.wasCollapsible=this.isCollapsible()},destroy:function(t){if(!t){var e=".smartmenus";this.$root.removeData("smartmenus").removeAttr("data-smartmenus-id").removeDataSM("level").off(e),e+=this.rootId,$(document).off(e),$(window).off(e),this.opts.subIndicators&&(this.$subArrow=null)}this.menuHideAll();var i=this;this.$root.find("ul").each(function(){var t=$(this);t.dataSM("scroll-arrows")&&t.dataSM("scroll-arrows").remove(),t.dataSM("shown-before")&&((i.opts.subMenusMinWidth||i.opts.subMenusMaxWidth)&&t.css({width:"",minWidth:"",maxWidth:""}).removeClass("sm-nowrap"),t.dataSM("scroll-arrows")&&t.dataSM("scroll-arrows").remove(),t.css({zIndex:"",top:"",left:"",marginLeft:"",marginTop:"",display:""})),0==(t.attr("id")||"").indexOf(i.accessIdPrefix)&&t.removeAttr("id")}).removeDataSM("in-mega").removeDataSM("shown-before").removeDataSM("scroll-arrows").removeDataSM("parent-a").removeDataSM("level").removeDataSM("beforefirstshowfired").removeAttr("role").removeAttr("aria-hidden").removeAttr("aria-labelledby").removeAttr("aria-expanded"),this.$root.find("a.has-submenu").each(function(){var t=$(this);0==t.attr("id").indexOf(i.accessIdPrefix)&&t.removeAttr("id")}).removeClass("has-submenu").removeDataSM("sub").removeAttr("aria-haspopup").removeAttr("aria-controls").removeAttr("aria-expanded").closest("li").removeDataSM("sub"),this.opts.subIndicators&&this.$root.find("span.sub-arrow").remove(),this.opts.markCurrentItem&&this.$root.find("a.current").removeClass("current"),t||(this.$root=null,this.$firstLink=null,this.$firstSub=null,this.$disableOverlay&&(this.$disableOverlay.remove(),this.$disableOverlay=null),menuTrees.splice($.inArray(this,menuTrees),1))},disable:function(t){if(!this.disabled){if(this.menuHideAll(),!t&&!this.opts.isPopup&&this.$root.is(":visible")){var e=this.$root.offset();this.$disableOverlay=$('
').css({position:"absolute",top:e.top,left:e.left,width:this.$root.outerWidth(),height:this.$root.outerHeight(),zIndex:this.getStartZIndex(!0),opacity:0}).appendTo(document.body)}this.disabled=!0}},docClick:function(t){return this.$touchScrollingSub?(this.$touchScrollingSub=null,void 0):((this.visibleSubMenus.length&&!$.contains(this.$root[0],t.target)||$(t.target).closest("a").length)&&this.menuHideAll(),void 0)},docTouchEnd:function(){if(this.lastTouch){if(!(!this.visibleSubMenus.length||void 0!==this.lastTouch.x2&&this.lastTouch.x1!=this.lastTouch.x2||void 0!==this.lastTouch.y2&&this.lastTouch.y1!=this.lastTouch.y2||this.lastTouch.target&&$.contains(this.$root[0],this.lastTouch.target))){this.hideTimeout&&(clearTimeout(this.hideTimeout),this.hideTimeout=0);var t=this;this.hideTimeout=setTimeout(function(){t.menuHideAll()},350)}this.lastTouch=null}},docTouchMove:function(t){if(this.lastTouch){var e=t.originalEvent.touches[0];this.lastTouch.x2=e.pageX,this.lastTouch.y2=e.pageY}},docTouchStart:function(t){var e=t.originalEvent.touches[0];this.lastTouch={x1:e.pageX,y1:e.pageY,target:e.target}},enable:function(){this.disabled&&(this.$disableOverlay&&(this.$disableOverlay.remove(),this.$disableOverlay=null),this.disabled=!1)},getClosestMenu:function(t){for(var e=$(t).closest("ul");e.dataSM("in-mega");)e=e.parent().closest("ul");return e[0]||null},getHeight:function(t){return this.getOffset(t,!0)},getOffset:function(t,e){var i;"none"==t.css("display")&&(i={position:t[0].style.position,visibility:t[0].style.visibility},t.css({position:"absolute",visibility:"hidden"}).show());var s=t[0].getBoundingClientRect&&t[0].getBoundingClientRect(),o=s&&(e?s.height||s.bottom-s.top:s.width||s.right-s.left);return o||0===o||(o=e?t[0].offsetHeight:t[0].offsetWidth),i&&t.hide().css(i),o},getStartZIndex:function(t){var e=parseInt(this[t?"$root":"$firstSub"].css("z-index"));return!t&&isNaN(e)&&(e=parseInt(this.$root.css("z-index"))),isNaN(e)?1:e},getTouchPoint:function(t){return t.touches&&t.touches[0]||t.changedTouches&&t.changedTouches[0]||t},getViewport:function(t){var e=t?"Height":"Width",i=document.documentElement["client"+e],s=window["inner"+e];return s&&(i=Math.min(i,s)),i},getViewportHeight:function(){return this.getViewport(!0)},getViewportWidth:function(){return this.getViewport()},getWidth:function(t){return this.getOffset(t)},handleEvents:function(){return!this.disabled&&this.isCSSOn()},handleItemEvents:function(t){return this.handleEvents()&&!this.isLinkInMegaMenu(t)},isCollapsible:function(){return"static"==this.$firstSub.css("position")},isCSSOn:function(){return"inline"!=this.$firstLink.css("display")},isFixed:function(){var t="fixed"==this.$root.css("position");return t||this.$root.parentsUntil("body").each(function(){return"fixed"==$(this).css("position")?(t=!0,!1):void 0}),t},isLinkInMegaMenu:function(t){return $(this.getClosestMenu(t[0])).hasClass("mega-menu")},isTouchMode:function(){return!mouse||this.opts.noMouseOver||this.isCollapsible()},itemActivate:function(t,e){var i=t.closest("ul"),s=i.dataSM("level");if(s>1&&(!this.activatedItems[s-2]||this.activatedItems[s-2][0]!=i.dataSM("parent-a")[0])){var o=this;$(i.parentsUntil("[data-smartmenus-id]","ul").get().reverse()).add(i).each(function(){o.itemActivate($(this).dataSM("parent-a"))})}if((!this.isCollapsible()||e)&&this.menuHideSubMenus(this.activatedItems[s-1]&&this.activatedItems[s-1][0]==t[0]?s:s-1),this.activatedItems[s-1]=t,this.$root.triggerHandler("activate.smapi",t[0])!==!1){var a=t.dataSM("sub");a&&(this.isTouchMode()||!this.opts.showOnClick||this.clickActivated)&&this.menuShow(a)}},itemBlur:function(t){var e=$(t.currentTarget);this.handleItemEvents(e)&&this.$root.triggerHandler("blur.smapi",e[0])},itemClick:function(t){var e=$(t.currentTarget);if(this.handleItemEvents(e)){if(this.$touchScrollingSub&&this.$touchScrollingSub[0]==e.closest("ul")[0])return this.$touchScrollingSub=null,t.stopPropagation(),!1;if(this.$root.triggerHandler("click.smapi",e[0])===!1)return!1;var i=$(t.target).is(".sub-arrow"),s=e.dataSM("sub"),o=s?2==s.dataSM("level"):!1,a=this.isCollapsible(),n=/toggle$/.test(this.opts.collapsibleBehavior),r=/link$/.test(this.opts.collapsibleBehavior),h=/^accordion/.test(this.opts.collapsibleBehavior);if(s&&!s.is(":visible")){if((!r||!a||i)&&(this.opts.showOnClick&&o&&(this.clickActivated=!0),this.itemActivate(e,h),s.is(":visible")))return this.focusActivated=!0,!1}else if(a&&(n||i))return this.itemActivate(e,h),this.menuHide(s),n&&(this.focusActivated=!1),!1;return this.opts.showOnClick&&o||e.hasClass("disabled")||this.$root.triggerHandler("select.smapi",e[0])===!1?!1:void 0}},itemDown:function(t){var e=$(t.currentTarget);this.handleItemEvents(e)&&e.dataSM("mousedown",!0)},itemEnter:function(t){var e=$(t.currentTarget);if(this.handleItemEvents(e)){if(!this.isTouchMode()){this.showTimeout&&(clearTimeout(this.showTimeout),this.showTimeout=0);var i=this;this.showTimeout=setTimeout(function(){i.itemActivate(e)},this.opts.showOnClick&&1==e.closest("ul").dataSM("level")?1:this.opts.showTimeout)}this.$root.triggerHandler("mouseenter.smapi",e[0])}},itemFocus:function(t){var e=$(t.currentTarget);this.handleItemEvents(e)&&(!this.focusActivated||this.isTouchMode()&&e.dataSM("mousedown")||this.activatedItems.length&&this.activatedItems[this.activatedItems.length-1][0]==e[0]||this.itemActivate(e,!0),this.$root.triggerHandler("focus.smapi",e[0]))},itemLeave:function(t){var e=$(t.currentTarget);this.handleItemEvents(e)&&(this.isTouchMode()||(e[0].blur(),this.showTimeout&&(clearTimeout(this.showTimeout),this.showTimeout=0)),e.removeDataSM("mousedown"),this.$root.triggerHandler("mouseleave.smapi",e[0]))},menuHide:function(t){if(this.$root.triggerHandler("beforehide.smapi",t[0])!==!1&&(canAnimate&&t.stop(!0,!0),"none"!=t.css("display"))){var e=function(){t.css("z-index","")};this.isCollapsible()?canAnimate&&this.opts.collapsibleHideFunction?this.opts.collapsibleHideFunction.call(this,t,e):t.hide(this.opts.collapsibleHideDuration,e):canAnimate&&this.opts.hideFunction?this.opts.hideFunction.call(this,t,e):t.hide(this.opts.hideDuration,e),t.dataSM("scroll")&&(this.menuScrollStop(t),t.css({"touch-action":"","-ms-touch-action":"","-webkit-transform":"",transform:""}).off(".smartmenus_scroll").removeDataSM("scroll").dataSM("scroll-arrows").hide()),t.dataSM("parent-a").removeClass("highlighted").attr("aria-expanded","false"),t.attr({"aria-expanded":"false","aria-hidden":"true"});var i=t.dataSM("level");this.activatedItems.splice(i-1,1),this.visibleSubMenus.splice($.inArray(t,this.visibleSubMenus),1),this.$root.triggerHandler("hide.smapi",t[0])}},menuHideAll:function(){this.showTimeout&&(clearTimeout(this.showTimeout),this.showTimeout=0);for(var t=this.opts.isPopup?1:0,e=this.visibleSubMenus.length-1;e>=t;e--)this.menuHide(this.visibleSubMenus[e]);this.opts.isPopup&&(canAnimate&&this.$root.stop(!0,!0),this.$root.is(":visible")&&(canAnimate&&this.opts.hideFunction?this.opts.hideFunction.call(this,this.$root):this.$root.hide(this.opts.hideDuration))),this.activatedItems=[],this.visibleSubMenus=[],this.clickActivated=!1,this.focusActivated=!1,this.zIndexInc=0,this.$root.triggerHandler("hideAll.smapi")},menuHideSubMenus:function(t){for(var e=this.activatedItems.length-1;e>=t;e--){var i=this.activatedItems[e].dataSM("sub");i&&this.menuHide(i)}},menuInit:function(t){if(!t.dataSM("in-mega")){t.hasClass("mega-menu")&&t.find("ul").dataSM("in-mega",!0);for(var e=2,i=t[0];(i=i.parentNode.parentNode)!=this.$root[0];)e++;var s=t.prevAll("a").eq(-1);s.length||(s=t.prevAll().find("a").eq(-1)),s.addClass("has-submenu").dataSM("sub",t),t.dataSM("parent-a",s).dataSM("level",e).parent().dataSM("sub",t);var o=s.attr("id")||this.accessIdPrefix+ ++this.idInc,a=t.attr("id")||this.accessIdPrefix+ ++this.idInc;s.attr({id:o,"aria-haspopup":"true","aria-controls":a,"aria-expanded":"false"}),t.attr({id:a,role:"group","aria-hidden":"true","aria-labelledby":o,"aria-expanded":"false"}),this.opts.subIndicators&&s[this.opts.subIndicatorsPos](this.$subArrow.clone())}},menuPosition:function(t){var e,i,s=t.dataSM("parent-a"),o=s.closest("li"),a=o.parent(),n=t.dataSM("level"),r=this.getWidth(t),h=this.getHeight(t),u=s.offset(),l=u.left,c=u.top,d=this.getWidth(s),m=this.getHeight(s),p=$(window),f=p.scrollLeft(),v=p.scrollTop(),b=this.getViewportWidth(),S=this.getViewportHeight(),g=a.parent().is("[data-sm-horizontal-sub]")||2==n&&!a.hasClass("sm-vertical"),M=this.opts.rightToLeftSubMenus&&!o.is("[data-sm-reverse]")||!this.opts.rightToLeftSubMenus&&o.is("[data-sm-reverse]"),w=2==n?this.opts.mainMenuSubOffsetX:this.opts.subMenusSubOffsetX,T=2==n?this.opts.mainMenuSubOffsetY:this.opts.subMenusSubOffsetY;if(g?(e=M?d-r-w:w,i=this.opts.bottomToTopSubMenus?-h-T:m+T):(e=M?w-r:d-w,i=this.opts.bottomToTopSubMenus?m-T-h:T),this.opts.keepInViewport){var y=l+e,I=c+i;if(M&&f>y?e=g?f-y+e:d-w:!M&&y+r>f+b&&(e=g?f+b-r-y+e:w-r),g||(S>h&&I+h>v+S?i+=v+S-h-I:(h>=S||v>I)&&(i+=v-I)),g&&(I+h>v+S+.49||v>I)||!g&&h>S+.49){var x=this;t.dataSM("scroll-arrows")||t.dataSM("scroll-arrows",$([$('')[0],$('')[0]]).on({mouseenter:function(){t.dataSM("scroll").up=$(this).hasClass("scroll-up"),x.menuScroll(t)},mouseleave:function(e){x.menuScrollStop(t),x.menuScrollOut(t,e)},"mousewheel DOMMouseScroll":function(t){t.preventDefault()}}).insertAfter(t));var A=".smartmenus_scroll";if(t.dataSM("scroll",{y:this.cssTransforms3d?0:i-m,step:1,itemH:m,subH:h,arrowDownH:this.getHeight(t.dataSM("scroll-arrows").eq(1))}).on(getEventsNS({mouseover:function(e){x.menuScrollOver(t,e)},mouseout:function(e){x.menuScrollOut(t,e)},"mousewheel DOMMouseScroll":function(e){x.menuScrollMousewheel(t,e)}},A)).dataSM("scroll-arrows").css({top:"auto",left:"0",marginLeft:e+(parseInt(t.css("border-left-width"))||0),width:r-(parseInt(t.css("border-left-width"))||0)-(parseInt(t.css("border-right-width"))||0),zIndex:t.css("z-index")}).eq(g&&this.opts.bottomToTopSubMenus?0:1).show(),this.isFixed()){var C={};C[touchEvents?"touchstart touchmove touchend":"pointerdown pointermove pointerup MSPointerDown MSPointerMove MSPointerUp"]=function(e){x.menuScrollTouch(t,e)},t.css({"touch-action":"none","-ms-touch-action":"none"}).on(getEventsNS(C,A))}}}t.css({top:"auto",left:"0",marginLeft:e,marginTop:i-m})},menuScroll:function(t,e,i){var s,o=t.dataSM("scroll"),a=t.dataSM("scroll-arrows"),n=o.up?o.upEnd:o.downEnd;if(!e&&o.momentum){if(o.momentum*=.92,s=o.momentum,.5>s)return this.menuScrollStop(t),void 0}else s=i||(e||!this.opts.scrollAccelerate?this.opts.scrollStep:Math.floor(o.step));var r=t.dataSM("level");if(this.activatedItems[r-1]&&this.activatedItems[r-1].dataSM("sub")&&this.activatedItems[r-1].dataSM("sub").is(":visible")&&this.menuHideSubMenus(r-1),o.y=o.up&&o.y>=n||!o.up&&n>=o.y?o.y:Math.abs(n-o.y)>s?o.y+(o.up?s:-s):n,t.css(this.cssTransforms3d?{"-webkit-transform":"translate3d(0, "+o.y+"px, 0)",transform:"translate3d(0, "+o.y+"px, 0)"}:{marginTop:o.y}),mouse&&(o.up&&o.y>o.downEnd||!o.up&&o.y0;t.dataSM("scroll-arrows").eq(i?0:1).is(":visible")&&(t.dataSM("scroll").up=i,this.menuScroll(t,!0))}e.preventDefault()},menuScrollOut:function(t,e){mouse&&(/^scroll-(up|down)/.test((e.relatedTarget||"").className)||(t[0]==e.relatedTarget||$.contains(t[0],e.relatedTarget))&&this.getClosestMenu(e.relatedTarget)==t[0]||t.dataSM("scroll-arrows").css("visibility","hidden"))},menuScrollOver:function(t,e){if(mouse&&!/^scroll-(up|down)/.test(e.target.className)&&this.getClosestMenu(e.target)==t[0]){this.menuScrollRefreshData(t);var i=t.dataSM("scroll"),s=$(window).scrollTop()-t.dataSM("parent-a").offset().top-i.itemH;t.dataSM("scroll-arrows").eq(0).css("margin-top",s).end().eq(1).css("margin-top",s+this.getViewportHeight()-i.arrowDownH).end().css("visibility","visible")}},menuScrollRefreshData:function(t){var e=t.dataSM("scroll"),i=$(window).scrollTop()-t.dataSM("parent-a").offset().top-e.itemH;this.cssTransforms3d&&(i=-(parseFloat(t.css("margin-top"))-i)),$.extend(e,{upEnd:i,downEnd:i+this.getViewportHeight()-e.subH})},menuScrollStop:function(t){return this.scrollTimeout?(cancelAnimationFrame(this.scrollTimeout),this.scrollTimeout=0,t.dataSM("scroll").step=1,!0):void 0},menuScrollTouch:function(t,e){if(e=e.originalEvent,isTouchEvent(e)){var i=this.getTouchPoint(e);if(this.getClosestMenu(i.target)==t[0]){var s=t.dataSM("scroll");if(/(start|down)$/i.test(e.type))this.menuScrollStop(t)?(e.preventDefault(),this.$touchScrollingSub=t):this.$touchScrollingSub=null,this.menuScrollRefreshData(t),$.extend(s,{touchStartY:i.pageY,touchStartTime:e.timeStamp});else if(/move$/i.test(e.type)){var o=void 0!==s.touchY?s.touchY:s.touchStartY;if(void 0!==o&&o!=i.pageY){this.$touchScrollingSub=t;var a=i.pageY>o;void 0!==s.up&&s.up!=a&&$.extend(s,{touchStartY:i.pageY,touchStartTime:e.timeStamp}),$.extend(s,{up:a,touchY:i.pageY}),this.menuScroll(t,!0,Math.abs(i.pageY-o))}e.preventDefault()}else void 0!==s.touchY&&((s.momentum=15*Math.pow(Math.abs(i.pageY-s.touchStartY)/(e.timeStamp-s.touchStartTime),2))&&(this.menuScrollStop(t),this.menuScroll(t),e.preventDefault()),delete s.touchY)}}},menuShow:function(t){if((t.dataSM("beforefirstshowfired")||(t.dataSM("beforefirstshowfired",!0),this.$root.triggerHandler("beforefirstshow.smapi",t[0])!==!1))&&this.$root.triggerHandler("beforeshow.smapi",t[0])!==!1&&(t.dataSM("shown-before",!0),canAnimate&&t.stop(!0,!0),!t.is(":visible"))){var e=t.dataSM("parent-a"),i=this.isCollapsible();if((this.opts.keepHighlighted||i)&&e.addClass("highlighted"),i)t.removeClass("sm-nowrap").css({zIndex:"",width:"auto",minWidth:"",maxWidth:"",top:"",left:"",marginLeft:"",marginTop:""});else{if(t.css("z-index",this.zIndexInc=(this.zIndexInc||this.getStartZIndex())+1),(this.opts.subMenusMinWidth||this.opts.subMenusMaxWidth)&&(t.css({width:"auto",minWidth:"",maxWidth:""}).addClass("sm-nowrap"),this.opts.subMenusMinWidth&&t.css("min-width",this.opts.subMenusMinWidth),this.opts.subMenusMaxWidth)){var s=this.getWidth(t);t.css("max-width",this.opts.subMenusMaxWidth),s>this.getWidth(t)&&t.removeClass("sm-nowrap").css("width",this.opts.subMenusMaxWidth)}this.menuPosition(t)}var o=function(){t.css("overflow","")};i?canAnimate&&this.opts.collapsibleShowFunction?this.opts.collapsibleShowFunction.call(this,t,o):t.show(this.opts.collapsibleShowDuration,o):canAnimate&&this.opts.showFunction?this.opts.showFunction.call(this,t,o):t.show(this.opts.showDuration,o),e.attr("aria-expanded","true"),t.attr({"aria-expanded":"true","aria-hidden":"false"}),this.visibleSubMenus.push(t),this.$root.triggerHandler("show.smapi",t[0])}},popupHide:function(t){this.hideTimeout&&(clearTimeout(this.hideTimeout),this.hideTimeout=0);var e=this;this.hideTimeout=setTimeout(function(){e.menuHideAll()},t?1:this.opts.hideTimeout)},popupShow:function(t,e){if(!this.opts.isPopup)return alert('SmartMenus jQuery Error:\n\nIf you want to show this menu via the "popupShow" method, set the isPopup:true option.'),void 0;if(this.hideTimeout&&(clearTimeout(this.hideTimeout),this.hideTimeout=0),this.$root.dataSM("shown-before",!0),canAnimate&&this.$root.stop(!0,!0),!this.$root.is(":visible")){this.$root.css({left:t,top:e});var i=this,s=function(){i.$root.css("overflow","")};canAnimate&&this.opts.showFunction?this.opts.showFunction.call(this,this.$root,s):this.$root.show(this.opts.showDuration,s),this.visibleSubMenus[0]=this.$root}},refresh:function(){this.destroy(!0),this.init(!0)},rootKeyDown:function(t){if(this.handleEvents())switch(t.keyCode){case 27:var e=this.activatedItems[0];if(e){this.menuHideAll(),e[0].focus();var i=e.dataSM("sub");i&&this.menuHide(i)}break;case 32:var s=$(t.target);if(s.is("a")&&this.handleItemEvents(s)){var i=s.dataSM("sub");i&&!i.is(":visible")&&(this.itemClick({currentTarget:t.target}),t.preventDefault())}}},rootOut:function(t){if(this.handleEvents()&&!this.isTouchMode()&&t.target!=this.$root[0]&&(this.hideTimeout&&(clearTimeout(this.hideTimeout),this.hideTimeout=0),!this.opts.showOnClick||!this.opts.hideOnClick)){var e=this;this.hideTimeout=setTimeout(function(){e.menuHideAll()},this.opts.hideTimeout)}},rootOver:function(t){this.handleEvents()&&!this.isTouchMode()&&t.target!=this.$root[0]&&this.hideTimeout&&(clearTimeout(this.hideTimeout),this.hideTimeout=0)},winResize:function(t){if(this.handleEvents()){if(!("onorientationchange"in window)||"orientationchange"==t.type){var e=this.isCollapsible();this.wasCollapsible&&e||(this.activatedItems.length&&this.activatedItems[this.activatedItems.length-1][0].blur(),this.menuHideAll()),this.wasCollapsible=e}}else if(this.$disableOverlay){var i=this.$root.offset();this.$disableOverlay.css({top:i.top,left:i.left,width:this.$root.outerWidth(),height:this.$root.outerHeight()})}}}}),$.fn.dataSM=function(t,e){return e?this.data(t+"_smartmenus",e):this.data(t+"_smartmenus")},$.fn.removeDataSM=function(t){return this.removeData(t+"_smartmenus")},$.fn.smartmenus=function(options){if("string"==typeof options){var args=arguments,method=options;return Array.prototype.shift.call(args),this.each(function(){var t=$(this).data("smartmenus");t&&t[method]&&t[method].apply(t,args)})}return this.each(function(){var dataOpts=$(this).data("sm-options")||null;if(dataOpts)try{dataOpts=eval("("+dataOpts+")")}catch(e){dataOpts=null,alert('ERROR\n\nSmartMenus jQuery init:\nInvalid "data-sm-options" attribute value syntax.')}new $.SmartMenus(this,$.extend({},$.fn.smartmenus.defaults,options,dataOpts))})},$.fn.smartmenus.defaults={isPopup:!1,mainMenuSubOffsetX:0,mainMenuSubOffsetY:0,subMenusSubOffsetX:0,subMenusSubOffsetY:0,subMenusMinWidth:"10em",subMenusMaxWidth:"20em",subIndicators:!0,subIndicatorsPos:"append",subIndicatorsText:"",scrollStep:30,scrollAccelerate:!0,showTimeout:250,hideTimeout:500,showDuration:0,showFunction:null,hideDuration:0,hideFunction:function(t,e){t.fadeOut(200,e)},collapsibleShowDuration:0,collapsibleShowFunction:function(t,e){t.slideDown(200,e)},collapsibleHideDuration:0,collapsibleHideFunction:function(t,e){t.slideUp(200,e)},showOnClick:!1,hideOnClick:!0,noMouseOver:!1,keepInViewport:!0,keepHighlighted:!0,markCurrentItem:!1,markCurrentTree:!0,rightToLeftSubMenus:!1,bottomToTopSubMenus:!1,collapsibleBehavior:"default"},$}); \ No newline at end of file diff --git a/docs/html/menu.js b/docs/html/menu.js new file mode 100644 index 00000000..b0b26936 --- /dev/null +++ b/docs/html/menu.js @@ -0,0 +1,136 @@ +/* + @licstart The following is the entire license notice for the JavaScript code in this file. + + The MIT License (MIT) + + Copyright (C) 1997-2020 by Dimitri van Heesch + + Permission is hereby granted, free of charge, to any person obtaining a copy of this software + and associated documentation files (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, publish, distribute, + sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all copies or + substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + @licend The above is the entire license notice for the JavaScript code in this file + */ +function initMenu(relPath,searchEnabled,serverSide,searchPage,search) { + function makeTree(data,relPath) { + var result=''; + if ('children' in data) { + result+='
    '; + for (var i in data.children) { + var url; + var link; + link = data.children[i].url; + if (link.substring(0,1)=='^') { + url = link.substring(1); + } else { + url = relPath+link; + } + result+='
  • '+ + data.children[i].text+''+ + makeTree(data.children[i],relPath)+'
  • '; + } + result+='
'; + } + return result; + } + var searchBoxHtml; + if (searchEnabled) { + if (serverSide) { + searchBoxHtml='
'+ + '
'+ + '
 '+ + ''+ + '
'+ + '
'+ + '
'+ + '
'; + } else { + searchBoxHtml='
'+ + ''+ + ' '+ + ''+ + ''+ + ''+ + ''+ + ''+ + '
'; + } + } + + $('#main-nav').before('
'+ + ''+ + ''+ + '
'); + $('#main-nav').append(makeTree(menudata,relPath)); + $('#main-nav').children(':first').addClass('sm sm-dox').attr('id','main-menu'); + if (searchBoxHtml) { + $('#main-menu').append('
  • '); + } + var $mainMenuState = $('#main-menu-state'); + var prevWidth = 0; + if ($mainMenuState.length) { + function initResizableIfExists() { + if (typeof initResizable==='function') initResizable(); + } + // animate mobile menu + $mainMenuState.change(function(e) { + var $menu = $('#main-menu'); + var options = { duration: 250, step: initResizableIfExists }; + if (this.checked) { + options['complete'] = function() { $menu.css('display', 'block') }; + $menu.hide().slideDown(options); + } else { + options['complete'] = function() { $menu.css('display', 'none') }; + $menu.show().slideUp(options); + } + }); + // set default menu visibility + function resetState() { + var $menu = $('#main-menu'); + var $mainMenuState = $('#main-menu-state'); + var newWidth = $(window).outerWidth(); + if (newWidth!=prevWidth) { + if ($(window).outerWidth()<768) { + $mainMenuState.prop('checked',false); $menu.hide(); + $('#searchBoxPos1').html(searchBoxHtml); + $('#searchBoxPos2').hide(); + } else { + $menu.show(); + $('#searchBoxPos1').empty(); + $('#searchBoxPos2').html(searchBoxHtml); + $('#searchBoxPos2').show(); + } + if (typeof searchBox!=='undefined') { + searchBox.CloseResultsWindow(); + } + prevWidth = newWidth; + } + } + $(window).ready(function() { resetState(); initResizableIfExists(); }); + $(window).resize(resetState); + } + $('#main-menu').smartmenus(); +} +/* @license-end */ diff --git a/docs/html/menudata.js b/docs/html/menudata.js new file mode 100644 index 00000000..f76b29ea --- /dev/null +++ b/docs/html/menudata.js @@ -0,0 +1,101 @@ +/* + @licstart The following is the entire license notice for the JavaScript code in this file. + + The MIT License (MIT) + + Copyright (C) 1997-2020 by Dimitri van Heesch + + Permission is hereby granted, free of charge, to any person obtaining a copy of this software + and associated documentation files (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, publish, distribute, + sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all copies or + substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + @licend The above is the entire license notice for the JavaScript code in this file +*/ +var menudata={children:[ +{text:"Main Page",url:"index.html"}, +{text:"Classes",url:"annotated.html",children:[ +{text:"Class List",url:"annotated.html"}, +{text:"Class Index",url:"classes.html"}, +{text:"Class Hierarchy",url:"hierarchy.html"}, +{text:"Class Members",url:"functions.html",children:[ +{text:"All",url:"functions.html",children:[ +{text:"a",url:"functions.html#index_a"}, +{text:"b",url:"functions_b.html#index_b"}, +{text:"c",url:"functions_c.html#index_c"}, +{text:"d",url:"functions_d.html#index_d"}, +{text:"e",url:"functions_e.html#index_e"}, +{text:"f",url:"functions_f.html#index_f"}, +{text:"g",url:"functions_g.html#index_g"}, +{text:"h",url:"functions_h.html#index_h"}, +{text:"i",url:"functions_i.html#index_i"}, +{text:"j",url:"functions_j.html#index_j"}, +{text:"k",url:"functions_k.html#index_k"}, +{text:"l",url:"functions_l.html#index_l"}, +{text:"m",url:"functions_m.html#index_m"}, +{text:"n",url:"functions_n.html#index_n"}, +{text:"o",url:"functions_o.html#index_o"}, +{text:"p",url:"functions_p.html#index_p"}, +{text:"r",url:"functions_r.html#index_r"}, +{text:"s",url:"functions_s.html#index_s"}, +{text:"t",url:"functions_t.html#index_t"}, +{text:"u",url:"functions_u.html#index_u"}, +{text:"v",url:"functions_v.html#index_v"}, +{text:"w",url:"functions_w.html#index_w"}, +{text:"x",url:"functions_x.html#index_x"}, +{text:"y",url:"functions_y.html#index_y"}]}, +{text:"Functions",url:"functions_func.html",children:[ +{text:"a",url:"functions_func.html#index_a"}, +{text:"b",url:"functions_func_b.html#index_b"}, +{text:"c",url:"functions_func_c.html#index_c"}, +{text:"d",url:"functions_func_d.html#index_d"}, +{text:"e",url:"functions_func_e.html#index_e"}, +{text:"f",url:"functions_func_f.html#index_f"}, +{text:"g",url:"functions_func_g.html#index_g"}, +{text:"h",url:"functions_func_h.html#index_h"}, +{text:"i",url:"functions_func_i.html#index_i"}, +{text:"j",url:"functions_func_j.html#index_j"}, +{text:"k",url:"functions_func_k.html#index_k"}, +{text:"l",url:"functions_func_l.html#index_l"}, +{text:"m",url:"functions_func_m.html#index_m"}, +{text:"n",url:"functions_func_n.html#index_n"}, +{text:"o",url:"functions_func_o.html#index_o"}, +{text:"p",url:"functions_func_p.html#index_p"}, +{text:"r",url:"functions_func_r.html#index_r"}, +{text:"s",url:"functions_func_s.html#index_s"}, +{text:"t",url:"functions_func_t.html#index_t"}, +{text:"u",url:"functions_func_u.html#index_u"}, +{text:"v",url:"functions_func_v.html#index_v"}, +{text:"w",url:"functions_func_w.html#index_w"}, +{text:"x",url:"functions_func_x.html#index_x"}, +{text:"y",url:"functions_func_y.html#index_y"}]}, +{text:"Variables",url:"functions_vars.html",children:[ +{text:"a",url:"functions_vars.html#index_a"}, +{text:"c",url:"functions_vars.html#index_c"}, +{text:"d",url:"functions_vars.html#index_d"}, +{text:"e",url:"functions_vars.html#index_e"}, +{text:"f",url:"functions_vars.html#index_f"}, +{text:"h",url:"functions_vars.html#index_h"}, +{text:"i",url:"functions_vars.html#index_i"}, +{text:"k",url:"functions_vars.html#index_k"}, +{text:"l",url:"functions_vars.html#index_l"}, +{text:"m",url:"functions_vars.html#index_m"}, +{text:"n",url:"functions_vars.html#index_n"}, +{text:"p",url:"functions_vars.html#index_p"}, +{text:"s",url:"functions_vars.html#index_s"}, +{text:"t",url:"functions_vars.html#index_t"}, +{text:"u",url:"functions_vars.html#index_u"}, +{text:"x",url:"functions_vars.html#index_x"}, +{text:"y",url:"functions_vars.html#index_y"}]}, +{text:"Enumerations",url:"functions_enum.html"}, +{text:"Enumerator",url:"functions_eval.html"}]}]}]} diff --git a/docs/html/nav_f.png b/docs/html/nav_f.png new file mode 100644 index 00000000..72a58a52 Binary files /dev/null and b/docs/html/nav_f.png differ diff --git a/docs/html/nav_fd.png b/docs/html/nav_fd.png new file mode 100644 index 00000000..032fbdd4 Binary files /dev/null and b/docs/html/nav_fd.png differ diff --git a/docs/html/nav_g.png b/docs/html/nav_g.png new file mode 100644 index 00000000..2093a237 Binary files /dev/null and b/docs/html/nav_g.png differ diff --git a/docs/html/nav_h.png b/docs/html/nav_h.png new file mode 100644 index 00000000..33389b10 Binary files /dev/null and b/docs/html/nav_h.png differ diff --git a/docs/html/nav_hd.png b/docs/html/nav_hd.png new file mode 100644 index 00000000..de80f18a Binary files /dev/null and b/docs/html/nav_hd.png differ diff --git a/docs/html/open.png b/docs/html/open.png new file mode 100644 index 00000000..30f75c7e Binary files /dev/null and b/docs/html/open.png differ diff --git a/docs/html/search/all_0.js b/docs/html/search/all_0.js new file mode 100644 index 00000000..b241cfdc --- /dev/null +++ b/docs/html/search/all_0.js @@ -0,0 +1,11 @@ +var searchData= +[ + ['abortrequest_0',['abortRequest',['../classCrapup.html#aab00b3d7f06317c5ff2753821d2b67d7',1,'Crapup']]], + ['access_1',['Access',['../classLogOps.html#aa566f381796a235007d1d27bc0b9e0f3abc99732253f105e139b0be3de2a9cfff',1,'LogOps']]], + ['addbreakdownseries_2',['addBreakdownSeries',['../classDonutBreakdown.html#a161ef5e8ca88f2735a4971d1f66f7a72',1,'DonutBreakdown']]], + ['ai_5fmakechoice_3',['AI_makeChoice',['../classCrissCross.html#ac2a75157a07ba7be4420d3b03f03c532',1,'CrissCross']]], + ['ai_5fplayturn_4',['AI_playTurn',['../classCrissCross.html#aefa21dcac38b6729af095fdc70be9ca9',1,'CrissCross']]], + ['ai_5fupdateweights_5',['AI_updateWeights',['../classCrissCross.html#a8c8798850707c8090bc8bf3d0f313109',1,'CrissCross']]], + ['apache_5falf_6',['APACHE_ALF',['../classFormatOps.html#a1dd258c0c0bb9091e25c2b36c47b5ad1',1,'FormatOps']]], + ['apache_5fid_7',['APACHE_ID',['../classCraplog.html#af5c119035966f19f51e746e6d3980b18',1,'Craplog']]] +]; diff --git a/docs/html/search/all_1.js b/docs/html/search/all_1.js new file mode 100644 index 00000000..5a523ea5 --- /dev/null +++ b/docs/html/search/all_1.js @@ -0,0 +1,14 @@ +var searchData= +[ + ['backupdatabase_0',['backupDatabase',['../classMainWindow.html#a49285e3553fef55101dbf66f37b9e44a',1,'MainWindow']]], + ['basepath_1',['basePath',['../classMainWindow.html#a04f50acafe9fa0c4c5c70b983f1cd804',1,'MainWindow']]], + ['battle_2',['Battle',['../classSnakeGame.html#a146a1430f1f32269ad0ad4df759e6a2ea33f4c7667fa1a7bf17dee0b0cade1f7b',1,'SnakeGame']]], + ['blacklistadd_3',['blacklistAdd',['../classCraplog.html#ae300ab55802ef1138de61adac7a6c6f5',1,'Craplog']]], + ['blacklistmovedown_4',['blacklistMoveDown',['../classCraplog.html#a298eac071b6efee4e15ca85db927de50',1,'Craplog']]], + ['blacklistmoveup_5',['blacklistMoveUp',['../classCraplog.html#abdae45a3f8b8c0e363869bafd72f4559',1,'Craplog']]], + ['blacklistremove_6',['blacklistRemove',['../classCraplog.html#ad762720f210cb068808ae1b6cbc349c9',1,'Craplog']]], + ['bodypart_7',['BodyPart',['../structBodyPart.html',1,'']]], + ['breakdownseries_8',['breakdownSeries',['../classMainSlice.html#af44c7a7a24e34fcd30da0ed8c3412e0d',1,'MainSlice']]], + ['bwlist_9',['BWlist',['../structCraplog_1_1BWlist.html',1,'Craplog']]], + ['bwlistexception_10',['BWlistException',['../classBWlistException.html',1,'']]] +]; diff --git a/docs/html/search/all_10.js b/docs/html/search/all_10.js new file mode 100644 index 00000000..2a29594b --- /dev/null +++ b/docs/html/search/all_10.js @@ -0,0 +1,20 @@ +var searchData= +[ + ['randomlines_0',['randomLines',['../classIOutils.html#a5b47051acc0d9abdc4faa421e31c8f8d',1,'IOutils']]], + ['readconfigs_1',['readConfigs',['../classMainWindow.html#aae306cbf256c5a686cc8d9f2a1dbb18b',1,'MainWindow']]], + ['readfile_2',['readFile',['../classGZutils.html#a72f6960bddea2b816af84e7773d5c6b2',1,'GZutils::readFile()'],['../classIOutils.html#a185c38eff9d9f4432c8138404941915e',1,'IOutils::readFile()']]], + ['recalculateangles_3',['recalculateAngles',['../classDonutBreakdown.html#acd747ee2bbd23ce84eaf9d4db57938e3',1,'DonutBreakdown']]], + ['refreshdates_4',['refreshDates',['../classCrapview.html#ac98b1cbc75604b5145b5cff36e96eb78',1,'Crapview::refreshDates()'],['../classDbQuery.html#af0b44989b67b5735e7ca93a17a250eb3',1,'DbQuery::refreshDates()']]], + ['refreshstatsdates_5',['refreshStatsDates',['../classMainWindow.html#ac8f4c84b43d14b6dcc6cb7b5f75ce343',1,'MainWindow']]], + ['renameascopy_6',['renameAsCopy',['../classIOutils.html#a8fc152ae29702c3760a4f519ceb0b62a',1,'IOutils']]], + ['replace_7',['replace',['../classStringOps.html#a9b073c9a47d2af00d33f1f5b05c167ad',1,'StringOps']]], + ['requesttimeout_8',['requestTimeout',['../classCrapup.html#afe79a787fc0820afbc4573ca7091d880',1,'Crapup']]], + ['resetperfdata_9',['resetPerfData',['../classLogOps.html#a811fb8fd3c84f4980c9044c16909457f',1,'LogOps']]], + ['resolvepath_10',['resolvePath',['../classMainWindow.html#a0ef3bd8e892ddb8a70696c56e35bd79e',1,'MainWindow']]], + ['richlogsdefault_11',['richLogsDefault',['../classRichText.html#a28bf0bdd659cc7b7a58eab9e5cfad495',1,'RichText']]], + ['richlogsfailure_12',['richLogsFailure',['../classRichText.html#a6e5fe6270e6fed0b9e7c42eafc9b4732',1,'RichText']]], + ['richtext_13',['RichText',['../classRichText.html',1,'']]], + ['rotateimg_14',['rotateImg',['../classCrapup.html#a334624ab394fd773b0e6063e7baf7960',1,'Crapup']]], + ['rstrip_15',['rstrip',['../classStringOps.html#a698efee881c6b05439f4fb5016c6c92e',1,'StringOps']]], + ['run_16',['run',['../classCraplog.html#a9c3081cf6cf94b454a87a4d71de3003d',1,'Craplog']]] +]; diff --git a/docs/html/search/all_11.js b/docs/html/search/all_11.js new file mode 100644 index 00000000..bda019b1 --- /dev/null +++ b/docs/html/search/all_11.js @@ -0,0 +1,54 @@ +var searchData= +[ + ['sanitizebwitem_0',['sanitizeBWitem',['../classCraplog.html#aaf61d1fa7538509ba1224469658f676f',1,'Craplog']]], + ['scanlogsdir_1',['scanLogsDir',['../classCraplog.html#aa9ba3931fad5aa0d42afef167f5dc474',1,'Craplog']]], + ['selected_2',['selected',['../structCraplog_1_1LogFile.html#a62bec6c3aaa6d07c80a9c65e609e973a',1,'Craplog::LogFile']]], + ['separators_3',['separators',['../structFormatOps_1_1LogsFormat.html#a9c1f1c8e35a73f5b6a3c3d6678634877',1,'FormatOps::LogsFormat']]], + ['setapachelogformat_4',['setApacheLogFormat',['../classCraplog.html#a7fca53dbd1698b2af7b82b6b9ff49c29',1,'Craplog']]], + ['setblacklist_5',['setBlacklist',['../classCraplog.html#ad64d8cf27ea6667147b73d9ae7a84663',1,'Craplog']]], + ['setblacklistused_6',['setBlacklistUsed',['../classCraplog.html#a17d6ac51e527a3057b7af64b6b3c1ec0',1,'Craplog']]], + ['setchartstheme_7',['setChartsTheme',['../classCrapview.html#a03482b379d82a9252893c2460197c2ca',1,'Crapview']]], + ['setcolorscheme_8',['setColorScheme',['../classCrapnote.html#a5981b895aa2298138e6153b1ff7d0370',1,'Crapnote::setColorScheme()'],['../classTextBrowser.html#a01d85d8805bd131c51da9fb3e1d2e070',1,'TextBrowser::setColorScheme()']]], + ['setcurrentlogformat_9',['setCurrentLogFormat',['../classCraplog.html#a40e768bae158908993b467f9514aaab6',1,'Craplog']]], + ['setcurrentwsid_10',['setCurrentWSID',['../classCraplog.html#a87f4408cbad358dd08951e470a8fa102',1,'Craplog']]], + ['setdbpath_11',['setDbPath',['../classCrapview.html#ac4f0e1215a892983b1c75f268bb1d60d',1,'Crapview::setDbPath()'],['../classDbQuery.html#a1e7cf5357869bc2c19053cb63afd6b67',1,'DbQuery::setDbPath()']]], + ['setdbworkingstate_12',['setDbWorkingState',['../classMainWindow.html#a3a60de6e260f0105b7976bff3307b74d',1,'MainWindow']]], + ['setdialoglevel_13',['setDialogLevel',['../classHashOps.html#a9f10f6c91238d3a4c2d221b2ada54e34',1,'HashOps::setDialogLevel()'],['../classDbQuery.html#a56fc09daba9d591509e916f1f995b297',1,'DbQuery::setDialogLevel()']]], + ['setdialogslevel_14',['setDialogsLevel',['../classCraplog.html#a9e93915c1a94707826f394a0df437b2d',1,'Craplog::setDialogsLevel()'],['../classCrapview.html#a9ac24f2e8a291e94a3db9ff26c0508d0',1,'Crapview::setDialogsLevel()']]], + ['setdirection_15',['setDirection',['../classSnake.html#a85d3b8250d5d26e3f23915c5bc43e372',1,'Snake']]], + ['setfont_16',['setFont',['../classTextBrowser.html#a1d47613908bacf424bb7bed38dac9b46',1,'TextBrowser']]], + ['sethashesdatabasepath_17',['setHashesDatabasePath',['../classCraplog.html#ab5f943a6df16ccd491612b24e7007c5e',1,'Craplog']]], + ['setiislogformat_18',['setIisLogFormat',['../classCraplog.html#a0bcacbeab3a2897b90103535dc6a58ac',1,'Craplog']]], + ['setlogfileselected_19',['setLogFileSelected',['../classCraplog.html#a57b298653b106bfc564b5b5a7d06b86d',1,'Craplog']]], + ['setlogspath_20',['setLogsPath',['../classCraplog.html#af32c0016a3c5924a9c0d0956c59d639e',1,'Craplog']]], + ['setname_21',['setName',['../classMainSlice.html#a96fd7fc82e830b3b49c121e4b2081c44',1,'MainSlice']]], + ['setnginxlogformat_22',['setNginxLogFormat',['../classCraplog.html#a57b18b19ebe66b6095d02627dfc875d9',1,'Craplog']]], + ['setstatsdatabasepath_23',['setStatsDatabasePath',['../classCraplog.html#a3375c00b403ebfad353a55f30fe21445',1,'Craplog']]], + ['settextfont_24',['setTextFont',['../classCrapnote.html#a3c7b98a96114f8efdc06912ee3167e16',1,'Crapnote']]], + ['setwarningsize_25',['setWarningSize',['../classCraplog.html#a5a03769b21e1590412e25b1a73e74278',1,'Craplog']]], + ['setwarnlist_26',['setWarnlist',['../classCraplog.html#aba8c361ed822c1dbd54fe3109a8e9073',1,'Craplog']]], + ['setwarnlistused_27',['setWarnlistUsed',['../classCraplog.html#aed65002c1e6e152f4dc1f8c3fca778ab',1,'Craplog']]], + ['setwidelinesusage_28',['setWideLinesUsage',['../classTextBrowser.html#a4a15c0db1622bcd312d29f1900e4428c',1,'TextBrowser']]], + ['sha256_29',['SHA256',['../classSHA256.html',1,'']]], + ['size_30',['size',['../structCraplog_1_1LogFile.html#a1cfe5d250686bb7cffe896dab11a44bd',1,'Craplog::LogFile']]], + ['snake_31',['snake',['../classSnakeGame.html#a7448c2b54b8bc6e7b3d1d4aee12fbad7',1,'SnakeGame']]], + ['snake_32',['Snake',['../classSnake.html',1,'']]], + ['snakegame_33',['SnakeGame',['../classSnakeGame.html',1,'']]], + ['spawn_34',['spawn',['../classFood.html#a2f588c1963efba7f68871ccba26aed3b',1,'Food']]], + ['split_35',['split',['../classStringOps.html#a09706d05be17cbfec1d6391df8302b7b',1,'StringOps']]], + ['splitrip_36',['splitrip',['../classStringOps.html#aa9d6c42c6a63a2201b514057efc586b0',1,'StringOps']]], + ['starts_37',['starts',['../structCraplog_1_1LogName.html#a6c853d2801446e1a6975e81a7c1bbace',1,'Craplog::LogName']]], + ['startswith_38',['startsWith',['../classStringOps.html#a1ff673b059e5dba907e3f876f5a11f99',1,'StringOps']]], + ['startworking_39',['startWorking',['../classCraplog.html#a5e2e95e07a23be1035b463198ba8b31a',1,'Craplog']]], + ['stopworking_40',['stopWorking',['../classCraplog.html#a7750a46b46ec82a8460640727a109f3c',1,'Craplog']]], + ['storedata_41',['storeData',['../classStoreOps.html#a615741805e57c9c545164370afde925c',1,'StoreOps']]], + ['storeloglines_42',['storeLogLines',['../classCraplog.html#acad55d8b7acb319bee6a44daf4ee366e',1,'Craplog']]], + ['storeops_43',['StoreOps',['../classStoreOps.html',1,'']]], + ['string_44',['string',['../structFormatOps_1_1LogsFormat.html#a2930da1577dfd023523ded0bcc3d8dba',1,'FormatOps::LogsFormat']]], + ['string2list_45',['string2list',['../classMainWindow.html#ad6bb577cde7471e7b8ea6142a1960517',1,'MainWindow']]], + ['stringops_46',['StringOps',['../classStringOps.html',1,'']]], + ['strip_47',['strip',['../classStringOps.html#a55abd7c2bc7448f25438c7578b9f3f44',1,'StringOps']]], + ['stylesec_48',['StyleSec',['../classStyleSec.html',1,'']]], + ['sumblacklistededsize_49',['sumBlacklistededSize',['../classCraplog.html#ae71b63dceaa5d2b7021e9f160377426e',1,'Craplog']]], + ['sumwarningssize_50',['sumWarningsSize',['../classCraplog.html#a248679f392649ddeaf881d66ced4b888',1,'Craplog']]] +]; diff --git a/docs/html/search/all_12.js b/docs/html/search/all_12.js new file mode 100644 index 00000000..0f96f2d0 --- /dev/null +++ b/docs/html/search/all_12.js @@ -0,0 +1,9 @@ +var searchData= +[ + ['textbrowser_0',['TextBrowser',['../classTextBrowser.html',1,'']]], + ['tile_1',['Tile',['../structSnake_1_1Tile.html',1,'Snake']]], + ['tolower_2',['toLower',['../classStringOps.html#ae6b18b8ac8edacbb38a6f07cbfff0e33',1,'StringOps']]], + ['total_5fsize_3',['total_size',['../classLogOps.html#a221aacd573375b78448d16b25fc42bb0',1,'LogOps']]], + ['toupper_4',['toUpper',['../classStringOps.html#a20d3cd1da6fa243c8e4514fad8251f27',1,'StringOps']]], + ['tr_5',['TR',['../classTR.html',1,'']]] +]; diff --git a/docs/html/search/all_13.js b/docs/html/search/all_13.js new file mode 100644 index 00000000..8baf9b7b --- /dev/null +++ b/docs/html/search/all_13.js @@ -0,0 +1,15 @@ +var searchData= +[ + ['update_0',['update',['../classFood.html#a2a120b3f858d6597e87daee875831c33',1,'Food::update()'],['../structBodyPart.html#aeb8163679b076a1346688abea7a17bff',1,'BodyPart::update()'],['../classSnake.html#a4b16000f3ecd8893ccf9dd04b45656be',1,'Snake::update()']]], + ['updategamescore_1',['updateGameScore',['../classSnakeGame.html#a420f3980fab86475ea4788a2e971597b',1,'SnakeGame']]], + ['updatelabel_2',['updateLabel',['../classMainSlice.html#aed2a6013aafca878143a8f05c391c590',1,'MainSlice']]], + ['updatelegendmarkers_3',['updateLegendMarkers',['../classDonutBreakdown.html#a682599f0fd4f13530b7bfe6dc3331578',1,'DonutBreakdown']]], + ['updateuifonts_4',['updateUiFonts',['../classMainWindow.html#a0b27c0bc56c7ffc801a32c90dbd529a6',1,'MainWindow']]], + ['updateuiicons_5',['updateUiIcons',['../classMainWindow.html#ab38da8951aefa2064b1e9d3bddd918ea',1,'MainWindow']]], + ['updateuilanguage_6',['updateUiLanguage',['../classMainWindow.html#a1f84f5977dc0d34a3f65f373be1214cd',1,'MainWindow']]], + ['updateuitheme_7',['updateUiTheme',['../classMainWindow.html#aa38e8aac36ede194803b378725fc123c',1,'MainWindow']]], + ['updatewarn_8',['updateWarn',['../classCrapview.html#a34be04ee1861a56aad782cc6f5e71118',1,'Crapview']]], + ['updatewarnings_9',['updateWarnings',['../classDbQuery.html#a770b22b2026bd95059acbf801e978250',1,'DbQuery']]], + ['used_10',['used',['../structCraplog_1_1BWlist.html#a012ed401cb4203ebdd24b149477a6c24',1,'Craplog::BWlist']]], + ['used_5falready_11',['used_already',['../structCraplog_1_1LogFile.html#a7ba18b36c9f124b05d85a48f381860e8',1,'Craplog::LogFile']]] +]; diff --git a/docs/html/search/all_14.js b/docs/html/search/all_14.js new file mode 100644 index 00000000..9168e5fa --- /dev/null +++ b/docs/html/search/all_14.js @@ -0,0 +1,6 @@ +var searchData= +[ + ['vecops_0',['VecOps',['../classVecOps.html',1,'']]], + ['versioncheck_1',['versionCheck',['../classCrapup.html#a606d41f5156d416335bdb8c0ad4cf8b2',1,'Crapup']]], + ['victory_2',['victory',['../classCrissCross.html#afa0a5b671afad8da3d071c5629c134b3',1,'CrissCross']]] +]; diff --git a/docs/html/search/all_15.js b/docs/html/search/all_15.js new file mode 100644 index 00000000..fe719df3 --- /dev/null +++ b/docs/html/search/all_15.js @@ -0,0 +1,16 @@ +var searchData= +[ + ['warnconffilenotfound_0',['warnConfFileNotFound',['../classDialogSec.html#a3b25c703b036517d3de43596809f1845',1,'DialogSec']]], + ['warndirnotreadable_1',['warnDirNotReadable',['../classDialogSec.html#a57e732827bbb8e58fb863bdd47318b5b',1,'DialogSec']]], + ['warndirnotwritable_2',['warnDirNotWritable',['../classDialogSec.html#ade3c5fd40c2b38b688bfce8a4f2bcd51',1,'DialogSec']]], + ['warnemptyfile_3',['warnEmptyFile',['../classDialogSec.html#a4a80026203e34ff692bc720d65f5c097',1,'DialogSec']]], + ['warnfilenotreadable_4',['warnFileNotReadable',['../classDialogSec.html#a2424ed3e4b1c9a98a0ca979764d004b9',1,'DialogSec']]], + ['warninvaliditembw_5',['warnInvalidItemBW',['../classDialogSec.html#ae9cf747999d28638f8bec00dba752271',1,'DialogSec']]], + ['warnlistadd_6',['warnlistAdd',['../classCraplog.html#a94f8d7c897c3d2ca32bb2e14da04ac5e',1,'Craplog']]], + ['warnlistmovedown_7',['warnlistMoveDown',['../classCraplog.html#a890bc09db02f51a2acb3d598adc198f1',1,'Craplog']]], + ['warnlistmoveup_8',['warnlistMoveUp',['../classCraplog.html#af517e761c3abeba0862ca0e975705c5c',1,'Craplog']]], + ['warnlistremove_9',['warnlistRemove',['../classCraplog.html#a945f190d13245a966b50b0e6d65e4cde',1,'Craplog']]], + ['webserverexception_10',['WebServerException',['../classWebServerException.html',1,'']]], + ['writeconfigs_11',['writeConfigs',['../classMainWindow.html#a77e405bc3eb9a34a2517a45ed7dbabf0',1,'MainWindow']]], + ['writeonfile_12',['writeOnFile',['../classIOutils.html#a4373d388a59e3a61b855892ed37e8757',1,'IOutils']]] +]; diff --git a/docs/html/search/all_16.js b/docs/html/search/all_16.js new file mode 100644 index 00000000..a8025930 --- /dev/null +++ b/docs/html/search/all_16.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['x_0',['x',['../classFood.html#a327d5731323aa500756f0b56a88e6bb5',1,'Food::x()'],['../structBodyPart.html#ad028f53499627e8fed0cc33b9464949b',1,'BodyPart::x()']]], + ['x_1',['X',['../classFood.html#ad31c5ac2518540d64c10143938fe8eb5',1,'Food']]] +]; diff --git a/docs/html/search/all_17.js b/docs/html/search/all_17.js new file mode 100644 index 00000000..4178afb4 --- /dev/null +++ b/docs/html/search/all_17.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['y_0',['y',['../classFood.html#a5dcfa7ef89ddcf8fd089ef99e7d6044f',1,'Food::y()'],['../structBodyPart.html#aa6c8fd72d59c9d20fa1943eac0ca8074',1,'BodyPart::y()']]], + ['y_1',['Y',['../classFood.html#a26a6873b59ce15c8cc7566338e4ee4ab',1,'Food']]] +]; diff --git a/docs/html/search/all_2.js b/docs/html/search/all_2.js new file mode 100644 index 00000000..3337d84a --- /dev/null +++ b/docs/html/search/all_2.js @@ -0,0 +1,49 @@ +var searchData= +[ + ['calcglobals_0',['calcGlobals',['../classCrapview.html#afffae0bf9a5a9a4236e0c6f9b42a153b',1,'Crapview']]], + ['changeiislogsbasenames_1',['changeIisLogsBaseNames',['../classCraplog.html#a5c91338a5331911ccf62a2a52dfeb1ca',1,'Craplog']]], + ['checkcollectiondatabase_2',['checkCollectionDatabase',['../classCheckSec.html#abaeae12b56acc24ef8f600814e3f280f',1,'CheckSec']]], + ['checkcollision_3',['checkCollision',['../classSnakeGame.html#a3bcce74b91e7e46658e44f05bfd319a9',1,'SnakeGame']]], + ['checkdatabasetablesnames_4',['checkDatabaseTablesNames',['../classCheckSec.html#aee7c4ae7ed7b46348be7096d5ca259c6',1,'CheckSec']]], + ['checkdatadb_5',['checkDataDB',['../classMainWindow.html#ac0c8348e66f87495ba105f6bf29ef6fc',1,'MainWindow']]], + ['checkdir_6',['checkDir',['../classIOutils.html#ab5d61de63617601f974e413d57342d10',1,'IOutils']]], + ['checkfile_7',['checkFile',['../classIOutils.html#ab7eef4b2b60686ceeb367155f13f3a99',1,'IOutils']]], + ['checkhashesdatabase_8',['checkHashesDatabase',['../classCheckSec.html#a012e382c91f035ced3c5868ad551a2ec',1,'CheckSec']]], + ['checkiisstring_9',['checkIisString',['../classFormatOps.html#a4d16a895af9986503a05459f014bc6f9',1,'FormatOps']]], + ['checksec_10',['CheckSec',['../classCheckSec.html',1,'']]], + ['checkstuff_11',['checkStuff',['../classCraplog.html#af24d2934e2227cfaf1555c89186f0c2e',1,'Craplog']]], + ['checkvictory_12',['checkVictory',['../classCrissCross.html#a5dccc6edb887b96eef8d4d1d5c00697d',1,'CrissCross']]], + ['choicedatabasemissingcolumn_13',['choiceDatabaseMissingColumn',['../classDialogSec.html#ac02553fc006764aeaec0dd2afd88a371',1,'DialogSec']]], + ['choicedatabasemissingtable_14',['choiceDatabaseMissingTable',['../classDialogSec.html#a0039a7a3cfb2d557687363bde896493c',1,'DialogSec']]], + ['choicedatabasenotfound_15',['choiceDatabaseNotFound',['../classDialogSec.html#a0c1c846547ee78f509e14e55b2b1855a',1,'DialogSec']]], + ['choicedatabaserenew_16',['choiceDatabaseRenew',['../classDialogSec.html#a5168e935cb97524b8491007245b8e024',1,'DialogSec']]], + ['choicedatabasewrongcolumn_17',['choiceDatabaseWrongColumn',['../classDialogSec.html#aa8b173e26906070394067c19b50f690d',1,'DialogSec']]], + ['choicedatabasewrongdatatype_18',['choiceDatabaseWrongDataType',['../classDialogSec.html#acfae1c39345f5d4e07f0626be0c57dc1',1,'DialogSec']]], + ['choicedatabasewrongtable_19',['choiceDatabaseWrongTable',['../classDialogSec.html#a23f40692db7f2c485582d9001fb45d56',1,'DialogSec']]], + ['choicedirnotdir_20',['choiceDirNotDir',['../classDialogSec.html#a489ff3ca5af28ce8baa555ef594f7632',1,'DialogSec']]], + ['choicefilealreadyused_21',['choiceFileAlreadyUsed',['../classDialogSec.html#a4ad145e1a537d7d8a4b9a9e36ab13917',1,'DialogSec']]], + ['choicefilenotfile_22',['choiceFileNotFile',['../classDialogSec.html#a3ab269a5442613eac85ff802b349088a',1,'DialogSec']]], + ['choicefilesizewarning_23',['choiceFileSizeWarning',['../classDialogSec.html#ad15349ac08ff1cee668b68d65b1c5985',1,'DialogSec']]], + ['choicefilesizewarning2_24',['choiceFileSizeWarning2',['../classDialogSec.html#afb8ef0d9047b8818a680d28628a3c363',1,'DialogSec']]], + ['choiceselectedfilenotfound_25',['choiceSelectedFileNotFound',['../classDialogSec.html#aa15af4618bb471f4bb984a6bf1f6fcf3',1,'DialogSec']]], + ['classic_26',['Classic',['../classSnakeGame.html#a146a1430f1f32269ad0ad4df759e6a2ea7fbcdf670873949c8c960b892a303e59',1,'SnakeGame']]], + ['cleanlines_27',['cleanLines',['../classLogOps.html#a0b57c3e3cf3e9e148f6fe340f7606886',1,'LogOps']]], + ['cleardatacollection_28',['clearDataCollection',['../classCraplog.html#a4f4e7518e49879a49bb560ca145ba71c',1,'Craplog']]], + ['cleardates_29',['clearDates',['../classCrapview.html#ae0eb083eea7e2bef76345242da41bf69',1,'Crapview']]], + ['closeevent_30',['closeEvent',['../classCrapup.html#a8640095eb315d653897d01b4e9162119',1,'Crapup']]], + ['collectperfdata_31',['collectPerfData',['../classCraplog.html#a71c27b249a2d7e1a376c5c93d154f903',1,'Craplog']]], + ['colorsec_32',['ColorSec',['../classColorSec.html',1,'']]], + ['contains_33',['contains',['../structCraplog_1_1LogName.html#a64fc39be93c9b1338ace87443ed597f3',1,'Craplog::LogName::contains()'],['../classStringOps.html#a3017639b683ae6b1555a19ac8ba9c7aa',1,'StringOps::contains()'],['../classVecOps.html#a591f42b19a9f4638bae861fc9a4045a0',1,'VecOps::contains()']]], + ['convertmonth_34',['convertMonth',['../classDateTimeOps.html#adb479373277de1df7e77392bffbe9c01',1,'DateTimeOps']]], + ['count_35',['count',['../classStringOps.html#a0ea46e71674e5201b3e3050fc721ee57',1,'StringOps']]], + ['countnewlines_36',['countNewLines',['../classFormatOps.html#aec634128bb1ded97288c43c569591a6a',1,'FormatOps']]], + ['craphelp_37',['Craphelp',['../classCraphelp.html',1,'']]], + ['crapinfo_38',['Crapinfo',['../classCrapinfo.html',1,'Crapinfo'],['../classCrapinfo.html#a5a036ed71eaccc1da462339abc810125',1,'Crapinfo::Crapinfo()']]], + ['craplog_39',['Craplog',['../classCraplog.html',1,'']]], + ['craplogfinished_40',['craplogFinished',['../classMainWindow.html#aa7d69a4e0c951d457dc72113b211758d',1,'MainWindow']]], + ['craplogstarted_41',['craplogStarted',['../classMainWindow.html#a19afbcce0fe0d8b8d12b50409fac0820',1,'MainWindow']]], + ['crapnote_42',['Crapnote',['../classCrapnote.html',1,'']]], + ['crapup_43',['Crapup',['../classCrapup.html#ab004aebc9dd40cc330e522f78f19471c',1,'Crapup::Crapup()'],['../classCrapup.html',1,'Crapup']]], + ['crapview_44',['Crapview',['../classCrapview.html',1,'']]], + ['crisscross_45',['CrissCross',['../classCrissCross.html',1,'']]] +]; diff --git a/docs/html/search/all_3.js b/docs/html/search/all_3.js new file mode 100644 index 00000000..5253067e --- /dev/null +++ b/docs/html/search/all_3.js @@ -0,0 +1,25 @@ +var searchData= +[ + ['datetimeexception_0',['DateTimeException',['../classDateTimeException.html',1,'']]], + ['datetimeops_1',['DateTimeOps',['../classDateTimeOps.html',1,'']]], + ['dbquery_2',['DbQuery',['../classDbQuery.html',1,'']]], + ['deeptypecheck_3',['deepTypeCheck',['../classLogOps.html#a085e70e88d385d30ae1960e55e09fcd6',1,'LogOps']]], + ['definefiletype_4',['defineFileType',['../classLogOps.html#a2dfb583b3262c50d54653368d79af3bb',1,'LogOps']]], + ['defineosspec_5',['defineOSspec',['../classMainWindow.html#a190ea12a49c863423ebc169b1f8c92a2',1,'MainWindow']]], + ['deletereply_6',['deleteReply',['../classCrapup.html#a52cad2625d432f367ca6441ebd35e64b',1,'Crapup']]], + ['detecticonstheme_7',['detectIconsTheme',['../classMainWindow.html#a5684909fae2173eb30b7a77051042d0b',1,'MainWindow']]], + ['dialogbool_8',['DialogBool',['../classDialogBool.html#aed40fd288c983c07b3abb7188655cb95',1,'DialogBool::DialogBool()'],['../classDialogBool.html',1,'DialogBool']]], + ['dialogdia_9',['DialogDia',['../classDialogDia.html',1,'DialogDia'],['../classDialogDia.html#ad0be19eb57e41d754b1dcd514b447891',1,'DialogDia::DialogDia()']]], + ['dialogmsg_10',['DialogMsg',['../classDialogMsg.html',1,'DialogMsg'],['../classDialogMsg.html#a440fa0b48cb5a3a0efdb8005cf44b285',1,'DialogMsg::DialogMsg()']]], + ['dialogsec_11',['DialogSec',['../classDialogSec.html',1,'']]], + ['digestfile_12',['digestFile',['../classHashOps.html#a413cfb68394bc237a19ebd05113dfdc1',1,'HashOps']]], + ['direction_13',['direction',['../structBodyPart.html#ad732b10425a86790821523da2388910b',1,'BodyPart::direction()'],['../classSnake.html#a81efcf9fc2119468d5c7278eaba83f9a',1,'Snake::direction()']]], + ['discarded_14',['Discarded',['../classLogOps.html#aa566f381796a235007d1d27bc0b9e0f3a2655c8b603fcd3f88b92b6114e38955e',1,'LogOps']]], + ['donutbreakdown_15',['DonutBreakdown',['../classDonutBreakdown.html',1,'']]], + ['draw_16',['draw',['../classCrissCross.html#a9f957e38250d4c58f2b232620891cb47',1,'CrissCross']]], + ['drawcount_17',['drawCount',['../classCrapview.html#ad6063317acd5a1861d6c8c49ffa4ff7f',1,'Crapview']]], + ['drawday_18',['drawDay',['../classCrapview.html#a951d380f509b31ce67661084db6779be',1,'Crapview']]], + ['drawrelat_19',['drawRelat',['../classCrapview.html#a22dbc03eaca3f113b42dfb2e6e69d1ba',1,'Crapview']]], + ['drawspeed_20',['drawSpeed',['../classCrapview.html#a7f623bc856d367df467d206722d07f99',1,'Crapview']]], + ['drawwarn_21',['drawWarn',['../classCrapview.html#aa1dbaf577883d7b24854e40427b172f4',1,'Crapview']]] +]; diff --git a/docs/html/search/all_4.js b/docs/html/search/all_4.js new file mode 100644 index 00000000..ae149281 --- /dev/null +++ b/docs/html/search/all_4.js @@ -0,0 +1,41 @@ +var searchData= +[ + ['editeddatabase_0',['editedDatabase',['../classCraplog.html#af7811e4878f27fe0524d87ee65d5a003',1,'Craplog']]], + ['ends_1',['ends',['../structCraplog_1_1LogName.html#a84d26cb4dc6f8efd87b26ad77d048e15',1,'Craplog::LogName']]], + ['endswith_2',['endsWith',['../classStringOps.html#a397c75a4e2713f9ed7a32bf4e7ee64a3',1,'StringOps']]], + ['endturn_3',['endTurn',['../classCrissCross.html#a3d3d3eeb2b7666c4411c89cf153048e0',1,'CrissCross']]], + ['enrichlogs_4',['enrichLogs',['../classRichText.html#a131e4cff5f46ce80e83384c2a236ecc9',1,'RichText']]], + ['errconfdirnotwritable_5',['errConfDirNotWritable',['../classDialogSec.html#a2cfc4ee49a455ec10253c133308e5235',1,'DialogSec']]], + ['errconffailedwriting_6',['errConfFailedWriting',['../classDialogSec.html#a2dcb66d839d8a10574414d45011e1764',1,'DialogSec']]], + ['errconffilenotreadable_7',['errConfFileNotReadable',['../classDialogSec.html#ae2a40f972582a40f5c4533cc7e2b425b',1,'DialogSec']]], + ['errconffilenotwritable_8',['errConfFileNotWritable',['../classDialogSec.html#a7c220883836ee79764e7a55813cc0cc9',1,'DialogSec']]], + ['errdatabasefailedbackup_9',['errDatabaseFailedBackup',['../classDialogSec.html#a20a23916efa18bb1a8dd1e91250f8557',1,'DialogSec']]], + ['errdatabasefailedcreating_10',['errDatabaseFailedCreating',['../classDialogSec.html#a8483bdc26a89628a826e69c454a7a6cf',1,'DialogSec']]], + ['errdatabasefailedexecuting_11',['errDatabaseFailedExecuting',['../classDialogSec.html#a64cfe33e61b020676857f98618aeb944',1,'DialogSec']]], + ['errdatabasefailedopening_12',['errDatabaseFailedOpening',['../classDialogSec.html#adad767386ecd10161f0eabda70d6c5d5',1,'DialogSec']]], + ['errdatabasenotfile_13',['errDatabaseNotFile',['../classDialogSec.html#a587689e07a401f5b51491e017535fd1d',1,'DialogSec']]], + ['errdatabasenotreadable_14',['errDatabaseNotReadable',['../classDialogSec.html#a8b88d0e707f4d0100069208fe6969a74',1,'DialogSec']]], + ['errdatabasenotwritable_15',['errDatabaseNotWritable',['../classDialogSec.html#a6fbd29bf1e96b182b396315cfb49ea49',1,'DialogSec']]], + ['errdirnotexists_16',['errDirNotExists',['../classDialogSec.html#a1624e24d4d7b04b5479970234368db0e',1,'DialogSec']]], + ['errdirnotreadable_17',['errDirNotReadable',['../classDialogSec.html#a89580421a70af819c57f480de24d8e77',1,'DialogSec']]], + ['errdirnotwritable_18',['errDirNotWritable',['../classDialogSec.html#a24cd2a3e54b2969d4f33ba500bd7509b',1,'DialogSec']]], + ['errfailedapplyingconfigs_19',['errFailedApplyingConfigs',['../classDialogSec.html#a636ea87efbab1f9bb75431a48380cd39',1,'DialogSec']]], + ['errfaileddefininglogtype_20',['errFailedDefiningLogType',['../classDialogSec.html#a37b210d2f9a087eaf395a45ff2095ed5',1,'DialogSec']]], + ['errfailedmakedir_21',['errFailedMakeDir',['../classDialogSec.html#af10077a5f3ebbf3683801999d8005f9a',1,'DialogSec']]], + ['errfailedparsinglogs_22',['errFailedParsingLogs',['../classDialogSec.html#a8bdf9d669f24bffd5d996ec18020194b',1,'DialogSec']]], + ['errfailedreadfile_23',['errFailedReadFile',['../classDialogSec.html#a0a5d1f707b891d3f177ecf5ebdc62d41',1,'DialogSec']]], + ['errfilenotfound_24',['errFileNotFound',['../classDialogSec.html#a940492f741a59fa7eb609e5bd12e6c91',1,'DialogSec']]], + ['errgeneric_25',['errGeneric',['../classDialogSec.html#a8315e79b58bd6bb557b5a934d5f4beba',1,'DialogSec']]], + ['errhelpfailed_26',['errHelpFailed',['../classDialogSec.html#abc275ca943e81edb5459da0afbe8c8c3',1,'DialogSec']]], + ['errhelpnotfound_27',['errHelpNotFound',['../classDialogSec.html#a910d3500df728c06173056a4eac0c358',1,'DialogSec']]], + ['errhelpnotreadable_28',['errHelpNotReadable',['../classDialogSec.html#aefdc8e73c551460720d8a58e7e5e18bb',1,'DialogSec']]], + ['errinvalidlogformatstring_29',['errInvalidLogFormatString',['../classDialogSec.html#a3cc898412f2debd5eff058aa8cd88c80',1,'DialogSec']]], + ['errlanglocaleinvalid_30',['errLangLocaleInvalid',['../classDialogSec.html#ab2c944dbd7d2857d6ec7b0eba8b614ae',1,'DialogSec']]], + ['errlangnotaccepted_31',['errLangNotAccepted',['../classDialogSec.html#a38406ffaaed868ab75be5b7e8f35a1c2',1,'DialogSec']]], + ['errlogformatnofields_32',['errLogFormatNoFields',['../classDialogSec.html#a48efa757e87889491d2d723749647c00',1,'DialogSec']]], + ['errlogformatnoseparators_33',['errLogFormatNoSeparators',['../classDialogSec.html#a5cc9c61fd5d5dea50b248366a6bd6e54',1,'DialogSec']]], + ['errlogformatnotset_34',['errLogFormatNotSet',['../classDialogSec.html#af9f19176ce2981bd3397b9d033490cb8',1,'DialogSec']]], + ['errrenaming_35',['errRenaming',['../classDialogSec.html#a93804c66ed89197dceb292926fceb690',1,'DialogSec']]], + ['errsqldrivernotfound_36',['errSqlDriverNotFound',['../classDialogSec.html#a41c7f8f921aff3ecfb876be3d89276b6',1,'DialogSec']]], + ['exists_37',['exists',['../classIOutils.html#a01cb7864b4ed38d8569b4ba093c0ffd9',1,'IOutils']]] +]; diff --git a/docs/html/search/all_5.js b/docs/html/search/all_5.js new file mode 100644 index 00000000..0c10b886 --- /dev/null +++ b/docs/html/search/all_5.js @@ -0,0 +1,11 @@ +var searchData= +[ + ['failed_0',['Failed',['../classLogOps.html#aa566f381796a235007d1d27bc0b9e0f3aefe27e6caeb020826f7fae1ffe85ee6f',1,'LogOps']]], + ['fields_1',['fields',['../structFormatOps_1_1LogsFormat.html#a4d08d99a4450455b10f714e03a3013bd',1,'FormatOps::LogsFormat']]], + ['final_2',['final',['../structFormatOps_1_1LogsFormat.html#a97c81c8d8494c648fb66b05b20a3426f',1,'FormatOps::LogsFormat']]], + ['findlast_3',['findLast',['../classStringOps.html#a4df2ec361e0f4dff2205d452194ca0b3',1,'StringOps']]], + ['findnginxfieldend_4',['findNginxFieldEnd',['../classFormatOps.html#abd7a77e8576787118fb22a540daea795',1,'FormatOps']]], + ['food_5',['Food',['../classFood.html',1,'']]], + ['food_6',['food',['../classSnakeGame.html#a24bb09f513593f8c816b41134f8684c3',1,'SnakeGame']]], + ['formatops_7',['FormatOps',['../classFormatOps.html',1,'']]] +]; diff --git a/docs/html/search/all_6.js b/docs/html/search/all_6.js new file mode 100644 index 00000000..a0582931 --- /dev/null +++ b/docs/html/search/all_6.js @@ -0,0 +1,60 @@ +var searchData= +[ + ['gamedraw_0',['gameDraw',['../classCrissCross.html#afe152a89c9e404e91dfac3f5d492198a',1,'CrissCross']]], + ['gamemode_1',['GameMode',['../classSnakeGame.html#a146a1430f1f32269ad0ad4df759e6a2e',1,'SnakeGame']]], + ['gamesec_2',['GameSec',['../classGameSec.html',1,'']]], + ['genericexception_3',['GenericException',['../classGenericException.html',1,'']]], + ['geometryfromstring_4',['geometryFromString',['../classMainWindow.html#aa4b87391c49c3780e66bd8104908eaf9',1,'MainWindow']]], + ['geometrytostring_5',['geometryToString',['../classMainWindow.html#acc0fd048160dade0598f71b51fefbf5c',1,'MainWindow']]], + ['getapachelogsample_6',['getApacheLogSample',['../classFormatOps.html#a034a9f4fd9baeefaaa8adf07107f0930',1,'FormatOps']]], + ['getblacklist_7',['getBlacklist',['../classCraplog.html#ad6f3d5667cc510154d858d9616cfa88d',1,'Craplog']]], + ['getcolors_8',['getColors',['../classColorSec.html#ad185a26760f960baf931b0bb79c711ff',1,'ColorSec']]], + ['getcolorscheme_9',['getColorScheme',['../classTextBrowser.html#a36ba738ca28c8ca966aa6ca8a290c981',1,'TextBrowser']]], + ['getcolorschemeid_10',['getColorSchemeID',['../classTextBrowser.html#a49e834e37466828519c0e1fc97b20d16',1,'TextBrowser']]], + ['getcolorschemes_11',['getColorSchemes',['../classColorSec.html#a4ad467469ba6b81fd0827f73ac53b6f8',1,'ColorSec']]], + ['getcurrentlogformat_12',['getCurrentLogFormat',['../classCraplog.html#a9d289b49aedb0fbc2ce02bd805a1a65c',1,'Craplog']]], + ['getcurrentwsid_13',['getCurrentWSID',['../classCraplog.html#a9a49a14e50120682a342ea3ba63947a5',1,'Craplog']]], + ['getdays_14',['getDays',['../classCrapview.html#ad03099fd23d33fbd0f7ef5fcc1c67bde',1,'Crapview']]], + ['getdaytimecounts_15',['getDaytimeCounts',['../classDbQuery.html#a31937b71d3088a7cb84a522e85cc86f1',1,'DbQuery']]], + ['getdbfield_16',['getDbField',['../classDbQuery.html#a17b84cf6ad72726387256e5c6288e93c',1,'DbQuery']]], + ['getdialogslevel_17',['getDialogsLevel',['../classCraplog.html#a955b8b094062a6e2ee89cf884dd7b028',1,'Craplog::getDialogsLevel()'],['../classCrapview.html#a9c117a07b9eb26532156e82d7852725b',1,'Crapview::getDialogsLevel()']]], + ['getfields_18',['getFields',['../classCrapview.html#a9b565e2994fc2f5c7379898fb39c7f15',1,'Crapview']]], + ['getfont_19',['getFont',['../classTextBrowser.html#aef0e5e3fb14ca9b48c1d668aebc33b33',1,'TextBrowser']]], + ['getfontfamily_20',['getFontFamily',['../classTextBrowser.html#ab7ad4bfc3ef92bd938e00dc438559c0b',1,'TextBrowser']]], + ['getglobalcounts_21',['getGlobalCounts',['../classDbQuery.html#ae504836c92d55d421d5e34b145b2065b',1,'DbQuery']]], + ['gethashesdatabasepath_22',['getHashesDatabasePath',['../classCraplog.html#a2b66000f63d8ab34e894b90fe3496e43',1,'Craplog']]], + ['gethours_23',['getHours',['../classCrapview.html#ad6eb1887779aaa5f7c2aa95911e832b8',1,'Crapview']]], + ['getiislogsample_24',['getIisLogSample',['../classFormatOps.html#a1fe9ff3f875e96c0866622f1a60f29b5',1,'FormatOps']]], + ['getitemscount_25',['getItemsCount',['../classDbQuery.html#a47744cc993d6a4bada0a8aec992a2c23',1,'DbQuery']]], + ['getlogfieldid_26',['getLogFieldID',['../classCrapview.html#a2907f88ba82158c8c58f54383b4a7c2a',1,'Crapview']]], + ['getlogfieldstring_27',['getLogFieldString',['../classCrapview.html#ab4aa28144e1d1a8f7954e0a3c6d3f9d1',1,'Crapview']]], + ['getlogfileitem_28',['getLogFileItem',['../classCraplog.html#a8fc3affaf8da7695390877c63b5b6051',1,'Craplog']]], + ['getlogsformat_29',['getLogsFormat',['../classCraplog.html#a946a0f980c91d713bd01cca8e822616d',1,'Craplog']]], + ['getlogsformatsample_30',['getLogsFormatSample',['../classCraplog.html#ae772867818dcfac15eba8f94da7f0493',1,'Craplog']]], + ['getlogsformatstring_31',['getLogsFormatString',['../classCraplog.html#a159ff9779d1ff85c8ecc6cb63274d494',1,'Craplog']]], + ['getlogslist_32',['getLogsList',['../classCraplog.html#aa0c1078272a2c9c88e51da32c2cbf269',1,'Craplog']]], + ['getlogslistsize_33',['getLogsListSize',['../classCraplog.html#affcd5025487fb60f89d7a35c3c807454',1,'Craplog']]], + ['getlogspath_34',['getLogsPath',['../classCraplog.html#aefd29a191a45be88d34dcfadab076f6d',1,'Craplog']]], + ['getminutegap_35',['getMinuteGap',['../classDbQuery.html#ae172c2f717f939daa41c5a0681ca76c3',1,'DbQuery']]], + ['getmonthdays_36',['getMonthDays',['../classDbQuery.html#a3dcefca533b85ef4e4f8fc12bd380d3e',1,'DbQuery']]], + ['getmonthnumber_37',['getMonthNumber',['../classCrapview.html#af156af64d1cb47d1c0fe1bacc3745974',1,'Crapview::getMonthNumber()'],['../classDbQuery.html#a3254d6cbe61c890ebc6b9d97367256dd',1,'DbQuery::getMonthNumber()']]], + ['getmonths_38',['getMonths',['../classCrapview.html#aa8518f26e3769580bbd3439e094b221a',1,'Crapview']]], + ['getmonthscount_39',['getMonthsCount',['../classDbQuery.html#a2fd212eaa2c82188ffc469fa5737792b',1,'DbQuery']]], + ['getnginxlogsample_40',['getNginxLogSample',['../classFormatOps.html#a46cc3ff63986ec4437c20ccbd68569c2',1,'FormatOps']]], + ['getparsedlines_41',['getParsedLines',['../classLogOps.html#a239ed1c9dca8cbf31f8e7c3fe52c1be1',1,'LogOps::getParsedLines()'],['../classCraplog.html#ae933a2f390dc08664b2ea07acd0b1c39',1,'Craplog::getParsedLines()']]], + ['getparsedsize_42',['getParsedSize',['../classLogOps.html#a06ce568d05b595728093dd2458608f41',1,'LogOps']]], + ['getperfsize_43',['getPerfSize',['../classCraplog.html#a556449b0a92e4bea1e444faca663abd5',1,'Craplog']]], + ['getrelationalcountsday_44',['getRelationalCountsDay',['../classDbQuery.html#aa1691a2878a4a6821afdaf155251ec0b',1,'DbQuery']]], + ['getrelationalcountsperiod_45',['getRelationalCountsPeriod',['../classDbQuery.html#acae142053967818896367a61e808533c',1,'DbQuery']]], + ['getspeeddata_46',['getSpeedData',['../classDbQuery.html#a3aa22b5075bf5607d986d641668af1ea',1,'DbQuery']]], + ['getstatsdatabasepath_47',['getStatsDatabasePath',['../classCraplog.html#a1f08bdd3ce8f969684cfb2acccb3a8aa',1,'Craplog']]], + ['getstylesheet_48',['getStyleSheet',['../classStyleSec.html#ac0781d686293b84e935bd29fe5283b14',1,'StyleSec']]], + ['gettotalsize_49',['getTotalSize',['../classCraplog.html#a92dd0b6330bdc32c908e688b7eced812',1,'Craplog::getTotalSize()'],['../classLogOps.html#a669727346faca20c48fe8f00e3c906ec',1,'LogOps::getTotalSize()']]], + ['getwarncounts_50',['getWarnCounts',['../classDbQuery.html#a2fc983abeeec05d04a110a29f80c4009',1,'DbQuery']]], + ['getwarningsize_51',['getWarningSize',['../classCraplog.html#af79d254595263448fead944f82db8931',1,'Craplog']]], + ['getwarnlist_52',['getWarnlist',['../classCraplog.html#a53df5cc15fdc79c1708aaf002c2f7719',1,'Craplog']]], + ['getwidelinesusage_53',['getWideLinesUsage',['../classTextBrowser.html#a7a62dfd67e7a58f374951272ac13defd',1,'TextBrowser']]], + ['getyears_54',['getYears',['../classCrapview.html#ab3081c678b102b255fa9f32a8f94e052',1,'Crapview']]], + ['grow_55',['grow',['../classSnake.html#a524fb8b522e917f620cfb401f2badabe',1,'Snake']]], + ['gzutils_56',['GZutils',['../classGZutils.html',1,'']]] +]; diff --git a/docs/html/search/all_7.js b/docs/html/search/all_7.js new file mode 100644 index 00000000..362ffc96 --- /dev/null +++ b/docs/html/search/all_7.js @@ -0,0 +1,8 @@ +var searchData= +[ + ['hasbeenused_0',['hasBeenUsed',['../classHashOps.html#aa9900aa35ed9c3538586c1c1d97f421d',1,'HashOps']]], + ['hash_1',['hash',['../structCraplog_1_1LogFile.html#a549d41730735f5f740bc290e1724f194',1,'Craplog::LogFile']]], + ['hashops_2',['HashOps',['../classHashOps.html',1,'']]], + ['helplogsformat_3',['helpLogsFormat',['../classCraphelp.html#a12d9f2ecffbd122a633ba3dee8267712',1,'Craphelp']]], + ['hunt_4',['Hunt',['../classSnakeGame.html#a146a1430f1f32269ad0ad4df759e6a2ea3bc7db4877c4b58e8b8f5ed74ffc1abb',1,'SnakeGame']]] +]; diff --git a/docs/html/search/all_8.js b/docs/html/search/all_8.js new file mode 100644 index 00000000..b0a1149d --- /dev/null +++ b/docs/html/search/all_8.js @@ -0,0 +1,25 @@ +var searchData= +[ + ['iis_5falf_0',['IIS_ALF',['../classFormatOps.html#aa4afc65bbc4887342cbb36381a26c3ba',1,'FormatOps']]], + ['iis_5fid_1',['IIS_ID',['../classCraplog.html#a6838d80c3522c8c4ed8a6578dd0f1f0b',1,'Craplog']]], + ['image_2',['image',['../structBodyPart.html#a1196ac7004a9559d2f2ef380885f2867',1,'BodyPart']]], + ['img_5frat_3',['img_rat',['../classFood.html#aec2915bdb96ebdf5a7f9d232ee3347b4',1,'Food']]], + ['initial_4',['initial',['../structFormatOps_1_1LogsFormat.html#a60c049b0289c3d9604ab8135da91b56e',1,'FormatOps::LogsFormat']]], + ['insertusedhash_5',['insertUsedHash',['../classHashOps.html#aeaf1ff64dcbec02e16eeec819a477019',1,'HashOps']]], + ['insertusedhashes_6',['insertUsedHashes',['../classHashOps.html#a63840ab6e5657c47179eb8667a25e3e0',1,'HashOps']]], + ['intile_7',['inTile',['../classFood.html#af75b2df758867826e9db4527aaf17d96',1,'Food::inTile()'],['../classSnake.html#a9afd044f5fa48f6d5f84dbff158d8a50',1,'Snake::inTile()']]], + ['ioutils_8',['IOutils',['../classIOutils.html',1,'']]], + ['isalnum_9',['isAlnum',['../classStringOps.html#a97036dc057034511dd3b9dc60e58979c',1,'StringOps::isAlnum(const std::string &str)'],['../classStringOps.html#a8235ab748959ad5967b06b4455c41e32',1,'StringOps::isAlnum(const unsigned char &chr)']]], + ['isalphabetic_10',['isAlphabetic',['../classStringOps.html#a45df33004f631721adb15d9e975ba623',1,'StringOps::isAlphabetic(const unsigned char &chr)'],['../classStringOps.html#aed7c6db4c635d5cae9489b6305af9f2f',1,'StringOps::isAlphabetic(const std::string &str)']]], + ['isblacklistused_11',['isBlacklistUsed',['../classCraplog.html#a17cfa8fd4c173fd5025d50e5f9f63259',1,'Craplog']]], + ['isdir_12',['isDir',['../classIOutils.html#ae205985989cf337fc03cd332971bfa71',1,'IOutils']]], + ['isfile_13',['isFile',['../classIOutils.html#a8bcf274a39f4c2187cca2b7246813c92',1,'IOutils']]], + ['isfilenamevalid_14',['isFileNameValid',['../classCraplog.html#aae25f0828da7cdf9dae0a48cecbc7fab',1,'Craplog']]], + ['ishex_15',['isHex',['../classStringOps.html#a4bd9e3db497099d3427351016be4ef5b',1,'StringOps']]], + ['isip_16',['isIP',['../classStringOps.html#a5c1c8c34501cc06f805a68e7f63938c3',1,'StringOps']]], + ['isnumeric_17',['isNumeric',['../classStringOps.html#a658cd6b0a48b94944851c6e4a71873d8',1,'StringOps::isNumeric(const std::string &str)'],['../classStringOps.html#a3f3446cdde7d3a7f2e26b60f29602589',1,'StringOps::isNumeric(const unsigned char &chr)']]], + ['isparsing_18',['isParsing',['../classCraplog.html#a38bd81dc41a7bcb3f93674fca5e70b7b',1,'Craplog']]], + ['isplayerturn_19',['isPlayerTurn',['../classCrissCross.html#a43322d09dc3752d222ed165fba5b554f',1,'CrissCross']]], + ['iswarnlistused_20',['isWarnlistUsed',['../classCraplog.html#aa26972256a75166113aa3d3b1ce73583',1,'Craplog']]], + ['isworking_21',['isWorking',['../classCraplog.html#a8f4b8fa9f2ef6f990bece47faed0a74a',1,'Craplog']]] +]; diff --git a/docs/html/search/all_9.js b/docs/html/search/all_9.js new file mode 100644 index 00000000..3295de2d --- /dev/null +++ b/docs/html/search/all_9.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['joinloglines_0',['joinLogLines',['../classCraplog.html#aa53d6671a6c1942973afabfb68c1af55',1,'Craplog']]] +]; diff --git a/docs/html/search/all_a.js b/docs/html/search/all_a.js new file mode 100644 index 00000000..2cd04de0 --- /dev/null +++ b/docs/html/search/all_a.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['key_5fevents_0',['key_events',['../classSnakeGame.html#a8be52d5a2a611f246af8631243d88663',1,'SnakeGame']]], + ['keypressevent_1',['keyPressEvent',['../classSnakeGame.html#a407dd2bae84d0f6572b94bb37feb87bc',1,'SnakeGame']]] +]; diff --git a/docs/html/search/all_b.js b/docs/html/search/all_b.js new file mode 100644 index 00000000..8bd228fc --- /dev/null +++ b/docs/html/search/all_b.js @@ -0,0 +1,15 @@ +var searchData= +[ + ['list_0',['list',['../structCraplog_1_1BWlist.html#abd672db987a40c57d9e2e9e5fcdb63d6',1,'Craplog::BWlist']]], + ['list2string_1',['list2string',['../classMainWindow.html#ad027d13d13237554d03d1a89287a08f0',1,'MainWindow']]], + ['loadusedhasheslists_2',['loadUsedHashesLists',['../classHashOps.html#a1184284b059b2094b0fc5cbbd1a2050b',1,'HashOps']]], + ['logfile_3',['LogFile',['../structCraplog_1_1LogFile.html',1,'Craplog']]], + ['logformatexception_4',['LogFormatException',['../classLogFormatException.html',1,'']]], + ['logname_5',['LogName',['../structCraplog_1_1LogName.html',1,'Craplog']]], + ['logops_6',['LogOps',['../classLogOps.html',1,'']]], + ['logparserexception_7',['LogParserException',['../classLogParserException.html',1,'']]], + ['logsformat_8',['LogsFormat',['../structFormatOps_1_1LogsFormat.html',1,'FormatOps']]], + ['logtype_9',['LogType',['../classLogOps.html#aa566f381796a235007d1d27bc0b9e0f3',1,'LogOps']]], + ['lstrip_10',['lstrip',['../classStringOps.html#ad57d5941c836f52cefcb711bff23fb50',1,'StringOps']]], + ['lstripuntil_11',['lstripUntil',['../classStringOps.html#a8a308ab32a62169c5a28ddb6db0b78f6',1,'StringOps']]] +]; diff --git a/docs/html/search/all_c.js b/docs/html/search/all_c.js new file mode 100644 index 00000000..edd2a347 --- /dev/null +++ b/docs/html/search/all_c.js @@ -0,0 +1,15 @@ +var searchData= +[ + ['mainslice_0',['MainSlice',['../classMainSlice.html',1,'']]], + ['mainwindow_1',['MainWindow',['../classMainWindow.html',1,'']]], + ['makechart_2',['makeChart',['../classCraplog.html#a3956db74f727d95f73738d9c19693007',1,'Craplog']]], + ['makedir_3',['makeDir',['../classIOutils.html#ac38e61e00c839dca681d90b5c0397093',1,'IOutils']]], + ['makeinitialchecks_4',['makeInitialChecks',['../classMainWindow.html#ae459fb4a3966975abe641c11c76e2c03',1,'MainWindow']]], + ['makepreview_5',['makePreview',['../classTextBrowser.html#a5b0eb8070202317c6e04534ca417c957',1,'TextBrowser']]], + ['makestylesheet_6',['makeStyleSheet',['../classStyleSec.html#a7deedd8236a76bdb8ba050e1fb797f11',1,'StyleSec']]], + ['max_5fsnake_5flength_7',['MAX_SNAKE_LENGTH',['../classSnakeGame.html#a3c6ebe785fb19d17383ea874819cc887',1,'SnakeGame']]], + ['menu_5factionenglish_5ftriggered_8',['menu_actionEnglish_triggered',['../classMainWindow.html#adffe78de926642168d16bfd8a2522c29',1,'MainWindow']]], + ['movable_9',['movable',['../classFood.html#ab4ab28e75609c4872fc47563909c4c61',1,'Food']]], + ['move_10',['move',['../classFood.html#a7196aa14ad843820518dc9db03252d21',1,'Food']]], + ['msgdatabasecreated_11',['msgDatabaseCreated',['../classDialogSec.html#ae916458257088da13a1a2bc885d5c71d',1,'DialogSec']]] +]; diff --git a/docs/html/search/all_d.js b/docs/html/search/all_d.js new file mode 100644 index 00000000..fb224491 --- /dev/null +++ b/docs/html/search/all_d.js @@ -0,0 +1,10 @@ +var searchData= +[ + ['name_0',['name',['../structCraplog_1_1LogFile.html#afa0840f03ab4786637b3ed63b2dfbbdd',1,'Craplog::LogFile::name()'],['../classMainSlice.html#adda5fecbc9d60f8d6367f187fd4f6c0f',1,'MainSlice::name()']]], + ['new_5flines_1',['new_lines',['../structFormatOps_1_1LogsFormat.html#afcaafb157a17ed598a33d14f157ac244',1,'FormatOps::LogsFormat']]], + ['newcollectiondatabase_2',['newCollectionDatabase',['../classCheckSec.html#a31f0c54f9b229bd616ad49a0bc09e16d',1,'CheckSec']]], + ['newhashesdatabase_3',['newHashesDatabase',['../classCheckSec.html#a56248ef831e3ea55830735ce5d436ba4',1,'CheckSec']]], + ['nextturn_4',['nextTurn',['../classCrissCross.html#acb1ca7cc584c4c2e21e94d88c794c06a',1,'CrissCross']]], + ['nginx_5falf_5',['NGINX_ALF',['../classFormatOps.html#a0489127a5f5a7cca1ae9386a3935fa2d',1,'FormatOps']]], + ['nginx_5fid_6',['NGINX_ID',['../classCraplog.html#a824487f5449d2b52e623a98044613a1b',1,'Craplog']]] +]; diff --git a/docs/html/search/all_e.js b/docs/html/search/all_e.js new file mode 100644 index 00000000..fcefdd0f --- /dev/null +++ b/docs/html/search/all_e.js @@ -0,0 +1,13 @@ +var searchData= +[ + ['on_5fbutton_5fabort_5fclicked_0',['on_button_ABORT_clicked',['../classDialogDia.html#a6fd03d1ce4cb3b6d424ada80b0a5b1f1',1,'DialogDia']]], + ['on_5fbutton_5fdiscard_5fclicked_1',['on_button_DISCARD_clicked',['../classDialogDia.html#a6682425f97963fbf2e2d94af0c766108',1,'DialogDia']]], + ['on_5fbutton_5ffontsize_5fminus_5fclicked_2',['on_button_FontSize_Minus_clicked',['../classCrapnote.html#acdcd9cf3e007d9c60aa2f1449798a0ae',1,'Crapnote']]], + ['on_5fbutton_5ffontsize_5fplus_5fclicked_3',['on_button_FontSize_Plus_clicked',['../classCrapnote.html#a0939b6b9916b5719ea9c55d40659b83b',1,'Crapnote']]], + ['on_5fbutton_5fignore_5fclicked_4',['on_button_IGNORE_clicked',['../classDialogDia.html#a8ba6f60f5f3833c972f3408bcd34c324',1,'DialogDia']]], + ['on_5fbutton_5fno_5fclicked_5',['on_button_NO_clicked',['../classDialogBool.html#a718195dfd76ecefd349333cfd82dc1cc',1,'DialogBool']]], + ['on_5fbutton_5fok_5fclicked_6',['on_button_Ok_clicked',['../classDialogMsg.html#a14ce87023686cac4cf700e0283073058',1,'DialogMsg']]], + ['on_5fbutton_5fshowadditional_5fclicked_7',['on_button_ShowAdditional_clicked',['../classDialogMsg.html#aa273ea069307de059183e8d2b7a2f7ef',1,'DialogMsg']]], + ['on_5fbutton_5fyes_5fclicked_8',['on_button_YES_clicked',['../classDialogBool.html#a14f2fcaac67126b4411bd4a78768809e',1,'DialogBool']]], + ['on_5fspinbox_5ffontsize_5fvaluechanged_9',['on_spinBox_FontSize_valueChanged',['../classCrapnote.html#a3eb5f7525b474fb46c15d383ee9b1d6a',1,'Crapnote']]] +]; diff --git a/docs/html/search/all_f.js b/docs/html/search/all_f.js new file mode 100644 index 00000000..37b27c01 --- /dev/null +++ b/docs/html/search/all_f.js @@ -0,0 +1,26 @@ +var searchData= +[ + ['parseapacheescapes_0',['parseApacheEscapes',['../classFormatOps.html#aea7c5e264f8a40c92cd39916ff75b02b',1,'FormatOps']]], + ['parsebooleanfilter_1',['parseBooleanFilter',['../classCrapview.html#aa7fe41edd00d1754ade13c095ad20b82',1,'Crapview']]], + ['parsed_5flines_2',['parsed_lines',['../classLogOps.html#ae56fab784fb4a7c0c11c631bd52cbdd6',1,'LogOps']]], + ['parsed_5fsize_3',['parsed_size',['../classLogOps.html#afc0aef8fb8975d0c587595ba7b82b617',1,'LogOps']]], + ['parseline_4',['parseLine',['../classLogOps.html#a21da556ce7b7f75cb032c499cd25bfec',1,'LogOps']]], + ['parselines_5',['parseLines',['../classLogOps.html#ad330fe53570a6b1e6edc198e894bcb12',1,'LogOps']]], + ['parseloglines_6',['parseLogLines',['../classCraplog.html#a0b5e942827237a1e61f48b76be89dc0d',1,'Craplog']]], + ['parsenginxescapes_7',['parseNginxEscapes',['../classFormatOps.html#aa8a4f2b2f78807f7156932233d7977fe',1,'FormatOps']]], + ['parsenumericfilter_8',['parseNumericFilter',['../classCrapview.html#ab450412741c7af21dfec42fad5a7f20a',1,'Crapview']]], + ['parsetextualfilter_9',['parseTextualFilter',['../classCrapview.html#ae7693a3fa2b4a402eb123af94a73d809',1,'Crapview']]], + ['path_10',['path',['../structCraplog_1_1LogFile.html#af33e3dd4a226abe93349c085d1b938f5',1,'Craplog::LogFile']]], + ['prev_5fdirection_11',['prev_direction',['../structBodyPart.html#a98303c77db6b5550e20d472075c15bc6',1,'BodyPart']]], + ['printabledate_12',['printableDate',['../classCrapview.html#a3a73f6f5683afaaa17a3065eada4438e',1,'Crapview']]], + ['printablesize_13',['printableSize',['../classMainWindow.html#a05a108ff2e9f3a25e2bfbae1d6ae8578',1,'MainWindow::printableSize()'],['../classCraplog.html#a34dc89787f7e104a84d01ebdeb00b074',1,'Craplog::printableSize()']]], + ['printablespeed_14',['printableSpeed',['../classMainWindow.html#aef96785abecd1b4f0eb7b845b0e64f59',1,'MainWindow']]], + ['printabletime_15',['printableTime',['../classMainWindow.html#ab2a9929d2a80fa4766059ef40904201c',1,'MainWindow::printableTime()'],['../classCrapview.html#af77a399adbd69a9bfd26e42c31e71324',1,'Crapview::printableTime(const int &hour, const int &minute, const int &second)']]], + ['printablewarn_16',['printableWarn',['../classCrapview.html#a2feca301352ca7bd76e199fbcaef932c',1,'Crapview']]], + ['processapacheformatstring_17',['processApacheFormatString',['../classFormatOps.html#a9bc720b012546f34b3f844459089a29d',1,'FormatOps']]], + ['processdatetime_18',['processDateTime',['../classDateTimeOps.html#a3e0808c8c395b0e9ea9240aa065b8967',1,'DateTimeOps']]], + ['processgamelogic_19',['processGameLogic',['../classSnakeGame.html#aeaa13da59d09abc40e25fd769fb96963',1,'SnakeGame']]], + ['processiisformatstring_20',['processIisFormatString',['../classFormatOps.html#afc7446da6389b522922cb94c4319f4ec',1,'FormatOps']]], + ['processnextkeyevent_21',['processNextKeyEvent',['../classSnakeGame.html#a0b0c9d7567a8e352449ddc7b31e09851',1,'SnakeGame']]], + ['processnginxformatstring_22',['processNginxFormatString',['../classFormatOps.html#a9e4c9fb02220492ce2766e830f4fedc6',1,'FormatOps']]] +]; diff --git a/docs/html/search/classes_0.js b/docs/html/search/classes_0.js new file mode 100644 index 00000000..98cb83c2 --- /dev/null +++ b/docs/html/search/classes_0.js @@ -0,0 +1,6 @@ +var searchData= +[ + ['bodypart_0',['BodyPart',['../structBodyPart.html',1,'']]], + ['bwlist_1',['BWlist',['../structCraplog_1_1BWlist.html',1,'Craplog']]], + ['bwlistexception_2',['BWlistException',['../classBWlistException.html',1,'']]] +]; diff --git a/docs/html/search/classes_1.js b/docs/html/search/classes_1.js new file mode 100644 index 00000000..7fd70763 --- /dev/null +++ b/docs/html/search/classes_1.js @@ -0,0 +1,12 @@ +var searchData= +[ + ['checksec_0',['CheckSec',['../classCheckSec.html',1,'']]], + ['colorsec_1',['ColorSec',['../classColorSec.html',1,'']]], + ['craphelp_2',['Craphelp',['../classCraphelp.html',1,'']]], + ['crapinfo_3',['Crapinfo',['../classCrapinfo.html',1,'']]], + ['craplog_4',['Craplog',['../classCraplog.html',1,'']]], + ['crapnote_5',['Crapnote',['../classCrapnote.html',1,'']]], + ['crapup_6',['Crapup',['../classCrapup.html',1,'']]], + ['crapview_7',['Crapview',['../classCrapview.html',1,'']]], + ['crisscross_8',['CrissCross',['../classCrissCross.html',1,'']]] +]; diff --git a/docs/html/search/classes_2.js b/docs/html/search/classes_2.js new file mode 100644 index 00000000..711dbef6 --- /dev/null +++ b/docs/html/search/classes_2.js @@ -0,0 +1,11 @@ +var searchData= +[ + ['datetimeexception_0',['DateTimeException',['../classDateTimeException.html',1,'']]], + ['datetimeops_1',['DateTimeOps',['../classDateTimeOps.html',1,'']]], + ['dbquery_2',['DbQuery',['../classDbQuery.html',1,'']]], + ['dialogbool_3',['DialogBool',['../classDialogBool.html',1,'']]], + ['dialogdia_4',['DialogDia',['../classDialogDia.html',1,'']]], + ['dialogmsg_5',['DialogMsg',['../classDialogMsg.html',1,'']]], + ['dialogsec_6',['DialogSec',['../classDialogSec.html',1,'']]], + ['donutbreakdown_7',['DonutBreakdown',['../classDonutBreakdown.html',1,'']]] +]; diff --git a/docs/html/search/classes_3.js b/docs/html/search/classes_3.js new file mode 100644 index 00000000..9a441b31 --- /dev/null +++ b/docs/html/search/classes_3.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['food_0',['Food',['../classFood.html',1,'']]], + ['formatops_1',['FormatOps',['../classFormatOps.html',1,'']]] +]; diff --git a/docs/html/search/classes_4.js b/docs/html/search/classes_4.js new file mode 100644 index 00000000..4c23f1b0 --- /dev/null +++ b/docs/html/search/classes_4.js @@ -0,0 +1,6 @@ +var searchData= +[ + ['gamesec_0',['GameSec',['../classGameSec.html',1,'']]], + ['genericexception_1',['GenericException',['../classGenericException.html',1,'']]], + ['gzutils_2',['GZutils',['../classGZutils.html',1,'']]] +]; diff --git a/docs/html/search/classes_5.js b/docs/html/search/classes_5.js new file mode 100644 index 00000000..035f4757 --- /dev/null +++ b/docs/html/search/classes_5.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['hashops_0',['HashOps',['../classHashOps.html',1,'']]] +]; diff --git a/docs/html/search/classes_6.js b/docs/html/search/classes_6.js new file mode 100644 index 00000000..1c48d310 --- /dev/null +++ b/docs/html/search/classes_6.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['ioutils_0',['IOutils',['../classIOutils.html',1,'']]] +]; diff --git a/docs/html/search/classes_7.js b/docs/html/search/classes_7.js new file mode 100644 index 00000000..9216fad5 --- /dev/null +++ b/docs/html/search/classes_7.js @@ -0,0 +1,9 @@ +var searchData= +[ + ['logfile_0',['LogFile',['../structCraplog_1_1LogFile.html',1,'Craplog']]], + ['logformatexception_1',['LogFormatException',['../classLogFormatException.html',1,'']]], + ['logname_2',['LogName',['../structCraplog_1_1LogName.html',1,'Craplog']]], + ['logops_3',['LogOps',['../classLogOps.html',1,'']]], + ['logparserexception_4',['LogParserException',['../classLogParserException.html',1,'']]], + ['logsformat_5',['LogsFormat',['../structFormatOps_1_1LogsFormat.html',1,'FormatOps']]] +]; diff --git a/docs/html/search/classes_8.js b/docs/html/search/classes_8.js new file mode 100644 index 00000000..82b5bb68 --- /dev/null +++ b/docs/html/search/classes_8.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['mainslice_0',['MainSlice',['../classMainSlice.html',1,'']]], + ['mainwindow_1',['MainWindow',['../classMainWindow.html',1,'']]] +]; diff --git a/docs/html/search/classes_9.js b/docs/html/search/classes_9.js new file mode 100644 index 00000000..6546caa9 --- /dev/null +++ b/docs/html/search/classes_9.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['richtext_0',['RichText',['../classRichText.html',1,'']]] +]; diff --git a/docs/html/search/classes_a.js b/docs/html/search/classes_a.js new file mode 100644 index 00000000..15f945b0 --- /dev/null +++ b/docs/html/search/classes_a.js @@ -0,0 +1,9 @@ +var searchData= +[ + ['sha256_0',['SHA256',['../classSHA256.html',1,'']]], + ['snake_1',['Snake',['../classSnake.html',1,'']]], + ['snakegame_2',['SnakeGame',['../classSnakeGame.html',1,'']]], + ['storeops_3',['StoreOps',['../classStoreOps.html',1,'']]], + ['stringops_4',['StringOps',['../classStringOps.html',1,'']]], + ['stylesec_5',['StyleSec',['../classStyleSec.html',1,'']]] +]; diff --git a/docs/html/search/classes_b.js b/docs/html/search/classes_b.js new file mode 100644 index 00000000..0c54d9f8 --- /dev/null +++ b/docs/html/search/classes_b.js @@ -0,0 +1,6 @@ +var searchData= +[ + ['textbrowser_0',['TextBrowser',['../classTextBrowser.html',1,'']]], + ['tile_1',['Tile',['../structSnake_1_1Tile.html',1,'Snake']]], + ['tr_2',['TR',['../classTR.html',1,'']]] +]; diff --git a/docs/html/search/classes_c.js b/docs/html/search/classes_c.js new file mode 100644 index 00000000..777fdf68 --- /dev/null +++ b/docs/html/search/classes_c.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['vecops_0',['VecOps',['../classVecOps.html',1,'']]] +]; diff --git a/docs/html/search/classes_d.js b/docs/html/search/classes_d.js new file mode 100644 index 00000000..21b4e79f --- /dev/null +++ b/docs/html/search/classes_d.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['webserverexception_0',['WebServerException',['../classWebServerException.html',1,'']]] +]; diff --git a/docs/html/search/close.svg b/docs/html/search/close.svg new file mode 100644 index 00000000..a933eea1 --- /dev/null +++ b/docs/html/search/close.svg @@ -0,0 +1,31 @@ + + + + + + image/svg+xml + + + + + + + + diff --git a/docs/html/search/enums_0.js b/docs/html/search/enums_0.js new file mode 100644 index 00000000..17ab31c8 --- /dev/null +++ b/docs/html/search/enums_0.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['gamemode_0',['GameMode',['../classSnakeGame.html#a146a1430f1f32269ad0ad4df759e6a2e',1,'SnakeGame']]] +]; diff --git a/docs/html/search/enums_1.js b/docs/html/search/enums_1.js new file mode 100644 index 00000000..b6fba1b1 --- /dev/null +++ b/docs/html/search/enums_1.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['logtype_0',['LogType',['../classLogOps.html#aa566f381796a235007d1d27bc0b9e0f3',1,'LogOps']]] +]; diff --git a/docs/html/search/enumvalues_0.js b/docs/html/search/enumvalues_0.js new file mode 100644 index 00000000..0b29c017 --- /dev/null +++ b/docs/html/search/enumvalues_0.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['access_0',['Access',['../classLogOps.html#aa566f381796a235007d1d27bc0b9e0f3abc99732253f105e139b0be3de2a9cfff',1,'LogOps']]] +]; diff --git a/docs/html/search/enumvalues_1.js b/docs/html/search/enumvalues_1.js new file mode 100644 index 00000000..bf8846d8 --- /dev/null +++ b/docs/html/search/enumvalues_1.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['battle_0',['Battle',['../classSnakeGame.html#a146a1430f1f32269ad0ad4df759e6a2ea33f4c7667fa1a7bf17dee0b0cade1f7b',1,'SnakeGame']]] +]; diff --git a/docs/html/search/enumvalues_2.js b/docs/html/search/enumvalues_2.js new file mode 100644 index 00000000..d8605d68 --- /dev/null +++ b/docs/html/search/enumvalues_2.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['classic_0',['Classic',['../classSnakeGame.html#a146a1430f1f32269ad0ad4df759e6a2ea7fbcdf670873949c8c960b892a303e59',1,'SnakeGame']]] +]; diff --git a/docs/html/search/enumvalues_3.js b/docs/html/search/enumvalues_3.js new file mode 100644 index 00000000..432ad272 --- /dev/null +++ b/docs/html/search/enumvalues_3.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['discarded_0',['Discarded',['../classLogOps.html#aa566f381796a235007d1d27bc0b9e0f3a2655c8b603fcd3f88b92b6114e38955e',1,'LogOps']]] +]; diff --git a/docs/html/search/enumvalues_4.js b/docs/html/search/enumvalues_4.js new file mode 100644 index 00000000..0c858177 --- /dev/null +++ b/docs/html/search/enumvalues_4.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['failed_0',['Failed',['../classLogOps.html#aa566f381796a235007d1d27bc0b9e0f3aefe27e6caeb020826f7fae1ffe85ee6f',1,'LogOps']]] +]; diff --git a/docs/html/search/enumvalues_5.js b/docs/html/search/enumvalues_5.js new file mode 100644 index 00000000..372a1963 --- /dev/null +++ b/docs/html/search/enumvalues_5.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['hunt_0',['Hunt',['../classSnakeGame.html#a146a1430f1f32269ad0ad4df759e6a2ea3bc7db4877c4b58e8b8f5ed74ffc1abb',1,'SnakeGame']]] +]; diff --git a/docs/html/search/functions_0.js b/docs/html/search/functions_0.js new file mode 100644 index 00000000..f06e6cae --- /dev/null +++ b/docs/html/search/functions_0.js @@ -0,0 +1,8 @@ +var searchData= +[ + ['abortrequest_0',['abortRequest',['../classCrapup.html#aab00b3d7f06317c5ff2753821d2b67d7',1,'Crapup']]], + ['addbreakdownseries_1',['addBreakdownSeries',['../classDonutBreakdown.html#a161ef5e8ca88f2735a4971d1f66f7a72',1,'DonutBreakdown']]], + ['ai_5fmakechoice_2',['AI_makeChoice',['../classCrissCross.html#ac2a75157a07ba7be4420d3b03f03c532',1,'CrissCross']]], + ['ai_5fplayturn_3',['AI_playTurn',['../classCrissCross.html#aefa21dcac38b6729af095fdc70be9ca9',1,'CrissCross']]], + ['ai_5fupdateweights_4',['AI_updateWeights',['../classCrissCross.html#a8c8798850707c8090bc8bf3d0f313109',1,'CrissCross']]] +]; diff --git a/docs/html/search/functions_1.js b/docs/html/search/functions_1.js new file mode 100644 index 00000000..07987570 --- /dev/null +++ b/docs/html/search/functions_1.js @@ -0,0 +1,10 @@ +var searchData= +[ + ['backupdatabase_0',['backupDatabase',['../classMainWindow.html#a49285e3553fef55101dbf66f37b9e44a',1,'MainWindow']]], + ['basepath_1',['basePath',['../classMainWindow.html#a04f50acafe9fa0c4c5c70b983f1cd804',1,'MainWindow']]], + ['blacklistadd_2',['blacklistAdd',['../classCraplog.html#ae300ab55802ef1138de61adac7a6c6f5',1,'Craplog']]], + ['blacklistmovedown_3',['blacklistMoveDown',['../classCraplog.html#a298eac071b6efee4e15ca85db927de50',1,'Craplog']]], + ['blacklistmoveup_4',['blacklistMoveUp',['../classCraplog.html#abdae45a3f8b8c0e363869bafd72f4559',1,'Craplog']]], + ['blacklistremove_5',['blacklistRemove',['../classCraplog.html#ad762720f210cb068808ae1b6cbc349c9',1,'Craplog']]], + ['breakdownseries_6',['breakdownSeries',['../classMainSlice.html#af44c7a7a24e34fcd30da0ed8c3412e0d',1,'MainSlice']]] +]; diff --git a/docs/html/search/functions_10.js b/docs/html/search/functions_10.js new file mode 100644 index 00000000..68340346 --- /dev/null +++ b/docs/html/search/functions_10.js @@ -0,0 +1,19 @@ +var searchData= +[ + ['randomlines_0',['randomLines',['../classIOutils.html#a5b47051acc0d9abdc4faa421e31c8f8d',1,'IOutils']]], + ['readconfigs_1',['readConfigs',['../classMainWindow.html#aae306cbf256c5a686cc8d9f2a1dbb18b',1,'MainWindow']]], + ['readfile_2',['readFile',['../classGZutils.html#a72f6960bddea2b816af84e7773d5c6b2',1,'GZutils::readFile()'],['../classIOutils.html#a185c38eff9d9f4432c8138404941915e',1,'IOutils::readFile()']]], + ['recalculateangles_3',['recalculateAngles',['../classDonutBreakdown.html#acd747ee2bbd23ce84eaf9d4db57938e3',1,'DonutBreakdown']]], + ['refreshdates_4',['refreshDates',['../classCrapview.html#ac98b1cbc75604b5145b5cff36e96eb78',1,'Crapview::refreshDates()'],['../classDbQuery.html#af0b44989b67b5735e7ca93a17a250eb3',1,'DbQuery::refreshDates()']]], + ['refreshstatsdates_5',['refreshStatsDates',['../classMainWindow.html#ac8f4c84b43d14b6dcc6cb7b5f75ce343',1,'MainWindow']]], + ['renameascopy_6',['renameAsCopy',['../classIOutils.html#a8fc152ae29702c3760a4f519ceb0b62a',1,'IOutils']]], + ['replace_7',['replace',['../classStringOps.html#a9b073c9a47d2af00d33f1f5b05c167ad',1,'StringOps']]], + ['requesttimeout_8',['requestTimeout',['../classCrapup.html#afe79a787fc0820afbc4573ca7091d880',1,'Crapup']]], + ['resetperfdata_9',['resetPerfData',['../classLogOps.html#a811fb8fd3c84f4980c9044c16909457f',1,'LogOps']]], + ['resolvepath_10',['resolvePath',['../classMainWindow.html#a0ef3bd8e892ddb8a70696c56e35bd79e',1,'MainWindow']]], + ['richlogsdefault_11',['richLogsDefault',['../classRichText.html#a28bf0bdd659cc7b7a58eab9e5cfad495',1,'RichText']]], + ['richlogsfailure_12',['richLogsFailure',['../classRichText.html#a6e5fe6270e6fed0b9e7c42eafc9b4732',1,'RichText']]], + ['rotateimg_13',['rotateImg',['../classCrapup.html#a334624ab394fd773b0e6063e7baf7960',1,'Crapup']]], + ['rstrip_14',['rstrip',['../classStringOps.html#a698efee881c6b05439f4fb5016c6c92e',1,'StringOps']]], + ['run_15',['run',['../classCraplog.html#a9c3081cf6cf94b454a87a4d71de3003d',1,'Craplog']]] +]; diff --git a/docs/html/search/functions_11.js b/docs/html/search/functions_11.js new file mode 100644 index 00000000..29b63957 --- /dev/null +++ b/docs/html/search/functions_11.js @@ -0,0 +1,42 @@ +var searchData= +[ + ['sanitizebwitem_0',['sanitizeBWitem',['../classCraplog.html#aaf61d1fa7538509ba1224469658f676f',1,'Craplog']]], + ['scanlogsdir_1',['scanLogsDir',['../classCraplog.html#aa9ba3931fad5aa0d42afef167f5dc474',1,'Craplog']]], + ['setapachelogformat_2',['setApacheLogFormat',['../classCraplog.html#a7fca53dbd1698b2af7b82b6b9ff49c29',1,'Craplog']]], + ['setblacklist_3',['setBlacklist',['../classCraplog.html#ad64d8cf27ea6667147b73d9ae7a84663',1,'Craplog']]], + ['setblacklistused_4',['setBlacklistUsed',['../classCraplog.html#a17d6ac51e527a3057b7af64b6b3c1ec0',1,'Craplog']]], + ['setchartstheme_5',['setChartsTheme',['../classCrapview.html#a03482b379d82a9252893c2460197c2ca',1,'Crapview']]], + ['setcolorscheme_6',['setColorScheme',['../classTextBrowser.html#a01d85d8805bd131c51da9fb3e1d2e070',1,'TextBrowser::setColorScheme()'],['../classCrapnote.html#a5981b895aa2298138e6153b1ff7d0370',1,'Crapnote::setColorScheme()']]], + ['setcurrentlogformat_7',['setCurrentLogFormat',['../classCraplog.html#a40e768bae158908993b467f9514aaab6',1,'Craplog']]], + ['setcurrentwsid_8',['setCurrentWSID',['../classCraplog.html#a87f4408cbad358dd08951e470a8fa102',1,'Craplog']]], + ['setdbpath_9',['setDbPath',['../classCrapview.html#ac4f0e1215a892983b1c75f268bb1d60d',1,'Crapview::setDbPath()'],['../classDbQuery.html#a1e7cf5357869bc2c19053cb63afd6b67',1,'DbQuery::setDbPath()']]], + ['setdbworkingstate_10',['setDbWorkingState',['../classMainWindow.html#a3a60de6e260f0105b7976bff3307b74d',1,'MainWindow']]], + ['setdialoglevel_11',['setDialogLevel',['../classHashOps.html#a9f10f6c91238d3a4c2d221b2ada54e34',1,'HashOps::setDialogLevel()'],['../classDbQuery.html#a56fc09daba9d591509e916f1f995b297',1,'DbQuery::setDialogLevel()']]], + ['setdialogslevel_12',['setDialogsLevel',['../classCraplog.html#a9e93915c1a94707826f394a0df437b2d',1,'Craplog::setDialogsLevel()'],['../classCrapview.html#a9ac24f2e8a291e94a3db9ff26c0508d0',1,'Crapview::setDialogsLevel()']]], + ['setdirection_13',['setDirection',['../classSnake.html#a85d3b8250d5d26e3f23915c5bc43e372',1,'Snake']]], + ['setfont_14',['setFont',['../classTextBrowser.html#a1d47613908bacf424bb7bed38dac9b46',1,'TextBrowser']]], + ['sethashesdatabasepath_15',['setHashesDatabasePath',['../classCraplog.html#ab5f943a6df16ccd491612b24e7007c5e',1,'Craplog']]], + ['setiislogformat_16',['setIisLogFormat',['../classCraplog.html#a0bcacbeab3a2897b90103535dc6a58ac',1,'Craplog']]], + ['setlogfileselected_17',['setLogFileSelected',['../classCraplog.html#a57b298653b106bfc564b5b5a7d06b86d',1,'Craplog']]], + ['setlogspath_18',['setLogsPath',['../classCraplog.html#af32c0016a3c5924a9c0d0956c59d639e',1,'Craplog']]], + ['setname_19',['setName',['../classMainSlice.html#a96fd7fc82e830b3b49c121e4b2081c44',1,'MainSlice']]], + ['setnginxlogformat_20',['setNginxLogFormat',['../classCraplog.html#a57b18b19ebe66b6095d02627dfc875d9',1,'Craplog']]], + ['setstatsdatabasepath_21',['setStatsDatabasePath',['../classCraplog.html#a3375c00b403ebfad353a55f30fe21445',1,'Craplog']]], + ['settextfont_22',['setTextFont',['../classCrapnote.html#a3c7b98a96114f8efdc06912ee3167e16',1,'Crapnote']]], + ['setwarningsize_23',['setWarningSize',['../classCraplog.html#a5a03769b21e1590412e25b1a73e74278',1,'Craplog']]], + ['setwarnlist_24',['setWarnlist',['../classCraplog.html#aba8c361ed822c1dbd54fe3109a8e9073',1,'Craplog']]], + ['setwarnlistused_25',['setWarnlistUsed',['../classCraplog.html#aed65002c1e6e152f4dc1f8c3fca778ab',1,'Craplog']]], + ['setwidelinesusage_26',['setWideLinesUsage',['../classTextBrowser.html#a4a15c0db1622bcd312d29f1900e4428c',1,'TextBrowser']]], + ['spawn_27',['spawn',['../classFood.html#a2f588c1963efba7f68871ccba26aed3b',1,'Food']]], + ['split_28',['split',['../classStringOps.html#a09706d05be17cbfec1d6391df8302b7b',1,'StringOps']]], + ['splitrip_29',['splitrip',['../classStringOps.html#aa9d6c42c6a63a2201b514057efc586b0',1,'StringOps']]], + ['startswith_30',['startsWith',['../classStringOps.html#a1ff673b059e5dba907e3f876f5a11f99',1,'StringOps']]], + ['startworking_31',['startWorking',['../classCraplog.html#a5e2e95e07a23be1035b463198ba8b31a',1,'Craplog']]], + ['stopworking_32',['stopWorking',['../classCraplog.html#a7750a46b46ec82a8460640727a109f3c',1,'Craplog']]], + ['storedata_33',['storeData',['../classStoreOps.html#a615741805e57c9c545164370afde925c',1,'StoreOps']]], + ['storeloglines_34',['storeLogLines',['../classCraplog.html#acad55d8b7acb319bee6a44daf4ee366e',1,'Craplog']]], + ['string2list_35',['string2list',['../classMainWindow.html#ad6bb577cde7471e7b8ea6142a1960517',1,'MainWindow']]], + ['strip_36',['strip',['../classStringOps.html#a55abd7c2bc7448f25438c7578b9f3f44',1,'StringOps']]], + ['sumblacklistededsize_37',['sumBlacklistededSize',['../classCraplog.html#ae71b63dceaa5d2b7021e9f160377426e',1,'Craplog']]], + ['sumwarningssize_38',['sumWarningsSize',['../classCraplog.html#a248679f392649ddeaf881d66ced4b888',1,'Craplog']]] +]; diff --git a/docs/html/search/functions_12.js b/docs/html/search/functions_12.js new file mode 100644 index 00000000..163f2345 --- /dev/null +++ b/docs/html/search/functions_12.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['tolower_0',['toLower',['../classStringOps.html#ae6b18b8ac8edacbb38a6f07cbfff0e33',1,'StringOps']]], + ['toupper_1',['toUpper',['../classStringOps.html#a20d3cd1da6fa243c8e4514fad8251f27',1,'StringOps']]] +]; diff --git a/docs/html/search/functions_13.js b/docs/html/search/functions_13.js new file mode 100644 index 00000000..5bc5a89d --- /dev/null +++ b/docs/html/search/functions_13.js @@ -0,0 +1,13 @@ +var searchData= +[ + ['update_0',['update',['../classFood.html#a2a120b3f858d6597e87daee875831c33',1,'Food::update()'],['../structBodyPart.html#aeb8163679b076a1346688abea7a17bff',1,'BodyPart::update()'],['../classSnake.html#a4b16000f3ecd8893ccf9dd04b45656be',1,'Snake::update()']]], + ['updategamescore_1',['updateGameScore',['../classSnakeGame.html#a420f3980fab86475ea4788a2e971597b',1,'SnakeGame']]], + ['updatelabel_2',['updateLabel',['../classMainSlice.html#aed2a6013aafca878143a8f05c391c590',1,'MainSlice']]], + ['updatelegendmarkers_3',['updateLegendMarkers',['../classDonutBreakdown.html#a682599f0fd4f13530b7bfe6dc3331578',1,'DonutBreakdown']]], + ['updateuifonts_4',['updateUiFonts',['../classMainWindow.html#a0b27c0bc56c7ffc801a32c90dbd529a6',1,'MainWindow']]], + ['updateuiicons_5',['updateUiIcons',['../classMainWindow.html#ab38da8951aefa2064b1e9d3bddd918ea',1,'MainWindow']]], + ['updateuilanguage_6',['updateUiLanguage',['../classMainWindow.html#a1f84f5977dc0d34a3f65f373be1214cd',1,'MainWindow']]], + ['updateuitheme_7',['updateUiTheme',['../classMainWindow.html#aa38e8aac36ede194803b378725fc123c',1,'MainWindow']]], + ['updatewarn_8',['updateWarn',['../classCrapview.html#a34be04ee1861a56aad782cc6f5e71118',1,'Crapview']]], + ['updatewarnings_9',['updateWarnings',['../classDbQuery.html#a770b22b2026bd95059acbf801e978250',1,'DbQuery']]] +]; diff --git a/docs/html/search/functions_14.js b/docs/html/search/functions_14.js new file mode 100644 index 00000000..a2db7e41 --- /dev/null +++ b/docs/html/search/functions_14.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['versioncheck_0',['versionCheck',['../classCrapup.html#a606d41f5156d416335bdb8c0ad4cf8b2',1,'Crapup']]], + ['victory_1',['victory',['../classCrissCross.html#afa0a5b671afad8da3d071c5629c134b3',1,'CrissCross']]] +]; diff --git a/docs/html/search/functions_15.js b/docs/html/search/functions_15.js new file mode 100644 index 00000000..6ab202ac --- /dev/null +++ b/docs/html/search/functions_15.js @@ -0,0 +1,15 @@ +var searchData= +[ + ['warnconffilenotfound_0',['warnConfFileNotFound',['../classDialogSec.html#a3b25c703b036517d3de43596809f1845',1,'DialogSec']]], + ['warndirnotreadable_1',['warnDirNotReadable',['../classDialogSec.html#a57e732827bbb8e58fb863bdd47318b5b',1,'DialogSec']]], + ['warndirnotwritable_2',['warnDirNotWritable',['../classDialogSec.html#ade3c5fd40c2b38b688bfce8a4f2bcd51',1,'DialogSec']]], + ['warnemptyfile_3',['warnEmptyFile',['../classDialogSec.html#a4a80026203e34ff692bc720d65f5c097',1,'DialogSec']]], + ['warnfilenotreadable_4',['warnFileNotReadable',['../classDialogSec.html#a2424ed3e4b1c9a98a0ca979764d004b9',1,'DialogSec']]], + ['warninvaliditembw_5',['warnInvalidItemBW',['../classDialogSec.html#ae9cf747999d28638f8bec00dba752271',1,'DialogSec']]], + ['warnlistadd_6',['warnlistAdd',['../classCraplog.html#a94f8d7c897c3d2ca32bb2e14da04ac5e',1,'Craplog']]], + ['warnlistmovedown_7',['warnlistMoveDown',['../classCraplog.html#a890bc09db02f51a2acb3d598adc198f1',1,'Craplog']]], + ['warnlistmoveup_8',['warnlistMoveUp',['../classCraplog.html#af517e761c3abeba0862ca0e975705c5c',1,'Craplog']]], + ['warnlistremove_9',['warnlistRemove',['../classCraplog.html#a945f190d13245a966b50b0e6d65e4cde',1,'Craplog']]], + ['writeconfigs_10',['writeConfigs',['../classMainWindow.html#a77e405bc3eb9a34a2517a45ed7dbabf0',1,'MainWindow']]], + ['writeonfile_11',['writeOnFile',['../classIOutils.html#a4373d388a59e3a61b855892ed37e8757',1,'IOutils']]] +]; diff --git a/docs/html/search/functions_16.js b/docs/html/search/functions_16.js new file mode 100644 index 00000000..e6027205 --- /dev/null +++ b/docs/html/search/functions_16.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['x_0',['X',['../classFood.html#ad31c5ac2518540d64c10143938fe8eb5',1,'Food']]] +]; diff --git a/docs/html/search/functions_17.js b/docs/html/search/functions_17.js new file mode 100644 index 00000000..5191f86e --- /dev/null +++ b/docs/html/search/functions_17.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['y_0',['Y',['../classFood.html#a26a6873b59ce15c8cc7566338e4ee4ab',1,'Food']]] +]; diff --git a/docs/html/search/functions_2.js b/docs/html/search/functions_2.js new file mode 100644 index 00000000..a3c38705 --- /dev/null +++ b/docs/html/search/functions_2.js @@ -0,0 +1,41 @@ +var searchData= +[ + ['calcglobals_0',['calcGlobals',['../classCrapview.html#afffae0bf9a5a9a4236e0c6f9b42a153b',1,'Crapview']]], + ['changeiislogsbasenames_1',['changeIisLogsBaseNames',['../classCraplog.html#a5c91338a5331911ccf62a2a52dfeb1ca',1,'Craplog']]], + ['checkcollectiondatabase_2',['checkCollectionDatabase',['../classCheckSec.html#abaeae12b56acc24ef8f600814e3f280f',1,'CheckSec']]], + ['checkcollision_3',['checkCollision',['../classSnakeGame.html#a3bcce74b91e7e46658e44f05bfd319a9',1,'SnakeGame']]], + ['checkdatabasetablesnames_4',['checkDatabaseTablesNames',['../classCheckSec.html#aee7c4ae7ed7b46348be7096d5ca259c6',1,'CheckSec']]], + ['checkdatadb_5',['checkDataDB',['../classMainWindow.html#ac0c8348e66f87495ba105f6bf29ef6fc',1,'MainWindow']]], + ['checkdir_6',['checkDir',['../classIOutils.html#ab5d61de63617601f974e413d57342d10',1,'IOutils']]], + ['checkfile_7',['checkFile',['../classIOutils.html#ab7eef4b2b60686ceeb367155f13f3a99',1,'IOutils']]], + ['checkhashesdatabase_8',['checkHashesDatabase',['../classCheckSec.html#a012e382c91f035ced3c5868ad551a2ec',1,'CheckSec']]], + ['checkiisstring_9',['checkIisString',['../classFormatOps.html#a4d16a895af9986503a05459f014bc6f9',1,'FormatOps']]], + ['checkstuff_10',['checkStuff',['../classCraplog.html#af24d2934e2227cfaf1555c89186f0c2e',1,'Craplog']]], + ['checkvictory_11',['checkVictory',['../classCrissCross.html#a5dccc6edb887b96eef8d4d1d5c00697d',1,'CrissCross']]], + ['choicedatabasemissingcolumn_12',['choiceDatabaseMissingColumn',['../classDialogSec.html#ac02553fc006764aeaec0dd2afd88a371',1,'DialogSec']]], + ['choicedatabasemissingtable_13',['choiceDatabaseMissingTable',['../classDialogSec.html#a0039a7a3cfb2d557687363bde896493c',1,'DialogSec']]], + ['choicedatabasenotfound_14',['choiceDatabaseNotFound',['../classDialogSec.html#a0c1c846547ee78f509e14e55b2b1855a',1,'DialogSec']]], + ['choicedatabaserenew_15',['choiceDatabaseRenew',['../classDialogSec.html#a5168e935cb97524b8491007245b8e024',1,'DialogSec']]], + ['choicedatabasewrongcolumn_16',['choiceDatabaseWrongColumn',['../classDialogSec.html#aa8b173e26906070394067c19b50f690d',1,'DialogSec']]], + ['choicedatabasewrongdatatype_17',['choiceDatabaseWrongDataType',['../classDialogSec.html#acfae1c39345f5d4e07f0626be0c57dc1',1,'DialogSec']]], + ['choicedatabasewrongtable_18',['choiceDatabaseWrongTable',['../classDialogSec.html#a23f40692db7f2c485582d9001fb45d56',1,'DialogSec']]], + ['choicedirnotdir_19',['choiceDirNotDir',['../classDialogSec.html#a489ff3ca5af28ce8baa555ef594f7632',1,'DialogSec']]], + ['choicefilealreadyused_20',['choiceFileAlreadyUsed',['../classDialogSec.html#a4ad145e1a537d7d8a4b9a9e36ab13917',1,'DialogSec']]], + ['choicefilenotfile_21',['choiceFileNotFile',['../classDialogSec.html#a3ab269a5442613eac85ff802b349088a',1,'DialogSec']]], + ['choicefilesizewarning_22',['choiceFileSizeWarning',['../classDialogSec.html#ad15349ac08ff1cee668b68d65b1c5985',1,'DialogSec']]], + ['choicefilesizewarning2_23',['choiceFileSizeWarning2',['../classDialogSec.html#afb8ef0d9047b8818a680d28628a3c363',1,'DialogSec']]], + ['choiceselectedfilenotfound_24',['choiceSelectedFileNotFound',['../classDialogSec.html#aa15af4618bb471f4bb984a6bf1f6fcf3',1,'DialogSec']]], + ['cleanlines_25',['cleanLines',['../classLogOps.html#a0b57c3e3cf3e9e148f6fe340f7606886',1,'LogOps']]], + ['cleardatacollection_26',['clearDataCollection',['../classCraplog.html#a4f4e7518e49879a49bb560ca145ba71c',1,'Craplog']]], + ['cleardates_27',['clearDates',['../classCrapview.html#ae0eb083eea7e2bef76345242da41bf69',1,'Crapview']]], + ['closeevent_28',['closeEvent',['../classCrapup.html#a8640095eb315d653897d01b4e9162119',1,'Crapup']]], + ['collectperfdata_29',['collectPerfData',['../classCraplog.html#a71c27b249a2d7e1a376c5c93d154f903',1,'Craplog']]], + ['contains_30',['contains',['../classStringOps.html#a3017639b683ae6b1555a19ac8ba9c7aa',1,'StringOps::contains()'],['../classVecOps.html#a591f42b19a9f4638bae861fc9a4045a0',1,'VecOps::contains()']]], + ['convertmonth_31',['convertMonth',['../classDateTimeOps.html#adb479373277de1df7e77392bffbe9c01',1,'DateTimeOps']]], + ['count_32',['count',['../classStringOps.html#a0ea46e71674e5201b3e3050fc721ee57',1,'StringOps']]], + ['countnewlines_33',['countNewLines',['../classFormatOps.html#aec634128bb1ded97288c43c569591a6a',1,'FormatOps']]], + ['crapinfo_34',['Crapinfo',['../classCrapinfo.html#a5a036ed71eaccc1da462339abc810125',1,'Crapinfo']]], + ['craplogfinished_35',['craplogFinished',['../classMainWindow.html#aa7d69a4e0c951d457dc72113b211758d',1,'MainWindow']]], + ['craplogstarted_36',['craplogStarted',['../classMainWindow.html#a19afbcce0fe0d8b8d12b50409fac0820',1,'MainWindow']]], + ['crapup_37',['Crapup',['../classCrapup.html#ab004aebc9dd40cc330e522f78f19471c',1,'Crapup']]] +]; diff --git a/docs/html/search/functions_3.js b/docs/html/search/functions_3.js new file mode 100644 index 00000000..0867af8e --- /dev/null +++ b/docs/html/search/functions_3.js @@ -0,0 +1,19 @@ +var searchData= +[ + ['deeptypecheck_0',['deepTypeCheck',['../classLogOps.html#a085e70e88d385d30ae1960e55e09fcd6',1,'LogOps']]], + ['definefiletype_1',['defineFileType',['../classLogOps.html#a2dfb583b3262c50d54653368d79af3bb',1,'LogOps']]], + ['defineosspec_2',['defineOSspec',['../classMainWindow.html#a190ea12a49c863423ebc169b1f8c92a2',1,'MainWindow']]], + ['deletereply_3',['deleteReply',['../classCrapup.html#a52cad2625d432f367ca6441ebd35e64b',1,'Crapup']]], + ['detecticonstheme_4',['detectIconsTheme',['../classMainWindow.html#a5684909fae2173eb30b7a77051042d0b',1,'MainWindow']]], + ['dialogbool_5',['DialogBool',['../classDialogBool.html#aed40fd288c983c07b3abb7188655cb95',1,'DialogBool']]], + ['dialogdia_6',['DialogDia',['../classDialogDia.html#ad0be19eb57e41d754b1dcd514b447891',1,'DialogDia']]], + ['dialogmsg_7',['DialogMsg',['../classDialogMsg.html#a440fa0b48cb5a3a0efdb8005cf44b285',1,'DialogMsg']]], + ['digestfile_8',['digestFile',['../classHashOps.html#a413cfb68394bc237a19ebd05113dfdc1',1,'HashOps']]], + ['direction_9',['direction',['../classSnake.html#a81efcf9fc2119468d5c7278eaba83f9a',1,'Snake']]], + ['draw_10',['draw',['../classCrissCross.html#a9f957e38250d4c58f2b232620891cb47',1,'CrissCross']]], + ['drawcount_11',['drawCount',['../classCrapview.html#ad6063317acd5a1861d6c8c49ffa4ff7f',1,'Crapview']]], + ['drawday_12',['drawDay',['../classCrapview.html#a951d380f509b31ce67661084db6779be',1,'Crapview']]], + ['drawrelat_13',['drawRelat',['../classCrapview.html#a22dbc03eaca3f113b42dfb2e6e69d1ba',1,'Crapview']]], + ['drawspeed_14',['drawSpeed',['../classCrapview.html#a7f623bc856d367df467d206722d07f99',1,'Crapview']]], + ['drawwarn_15',['drawWarn',['../classCrapview.html#aa1dbaf577883d7b24854e40427b172f4',1,'Crapview']]] +]; diff --git a/docs/html/search/functions_4.js b/docs/html/search/functions_4.js new file mode 100644 index 00000000..0abd4b55 --- /dev/null +++ b/docs/html/search/functions_4.js @@ -0,0 +1,40 @@ +var searchData= +[ + ['editeddatabase_0',['editedDatabase',['../classCraplog.html#af7811e4878f27fe0524d87ee65d5a003',1,'Craplog']]], + ['endswith_1',['endsWith',['../classStringOps.html#a397c75a4e2713f9ed7a32bf4e7ee64a3',1,'StringOps']]], + ['endturn_2',['endTurn',['../classCrissCross.html#a3d3d3eeb2b7666c4411c89cf153048e0',1,'CrissCross']]], + ['enrichlogs_3',['enrichLogs',['../classRichText.html#a131e4cff5f46ce80e83384c2a236ecc9',1,'RichText']]], + ['errconfdirnotwritable_4',['errConfDirNotWritable',['../classDialogSec.html#a2cfc4ee49a455ec10253c133308e5235',1,'DialogSec']]], + ['errconffailedwriting_5',['errConfFailedWriting',['../classDialogSec.html#a2dcb66d839d8a10574414d45011e1764',1,'DialogSec']]], + ['errconffilenotreadable_6',['errConfFileNotReadable',['../classDialogSec.html#ae2a40f972582a40f5c4533cc7e2b425b',1,'DialogSec']]], + ['errconffilenotwritable_7',['errConfFileNotWritable',['../classDialogSec.html#a7c220883836ee79764e7a55813cc0cc9',1,'DialogSec']]], + ['errdatabasefailedbackup_8',['errDatabaseFailedBackup',['../classDialogSec.html#a20a23916efa18bb1a8dd1e91250f8557',1,'DialogSec']]], + ['errdatabasefailedcreating_9',['errDatabaseFailedCreating',['../classDialogSec.html#a8483bdc26a89628a826e69c454a7a6cf',1,'DialogSec']]], + ['errdatabasefailedexecuting_10',['errDatabaseFailedExecuting',['../classDialogSec.html#a64cfe33e61b020676857f98618aeb944',1,'DialogSec']]], + ['errdatabasefailedopening_11',['errDatabaseFailedOpening',['../classDialogSec.html#adad767386ecd10161f0eabda70d6c5d5',1,'DialogSec']]], + ['errdatabasenotfile_12',['errDatabaseNotFile',['../classDialogSec.html#a587689e07a401f5b51491e017535fd1d',1,'DialogSec']]], + ['errdatabasenotreadable_13',['errDatabaseNotReadable',['../classDialogSec.html#a8b88d0e707f4d0100069208fe6969a74',1,'DialogSec']]], + ['errdatabasenotwritable_14',['errDatabaseNotWritable',['../classDialogSec.html#a6fbd29bf1e96b182b396315cfb49ea49',1,'DialogSec']]], + ['errdirnotexists_15',['errDirNotExists',['../classDialogSec.html#a1624e24d4d7b04b5479970234368db0e',1,'DialogSec']]], + ['errdirnotreadable_16',['errDirNotReadable',['../classDialogSec.html#a89580421a70af819c57f480de24d8e77',1,'DialogSec']]], + ['errdirnotwritable_17',['errDirNotWritable',['../classDialogSec.html#a24cd2a3e54b2969d4f33ba500bd7509b',1,'DialogSec']]], + ['errfailedapplyingconfigs_18',['errFailedApplyingConfigs',['../classDialogSec.html#a636ea87efbab1f9bb75431a48380cd39',1,'DialogSec']]], + ['errfaileddefininglogtype_19',['errFailedDefiningLogType',['../classDialogSec.html#a37b210d2f9a087eaf395a45ff2095ed5',1,'DialogSec']]], + ['errfailedmakedir_20',['errFailedMakeDir',['../classDialogSec.html#af10077a5f3ebbf3683801999d8005f9a',1,'DialogSec']]], + ['errfailedparsinglogs_21',['errFailedParsingLogs',['../classDialogSec.html#a8bdf9d669f24bffd5d996ec18020194b',1,'DialogSec']]], + ['errfailedreadfile_22',['errFailedReadFile',['../classDialogSec.html#a0a5d1f707b891d3f177ecf5ebdc62d41',1,'DialogSec']]], + ['errfilenotfound_23',['errFileNotFound',['../classDialogSec.html#a940492f741a59fa7eb609e5bd12e6c91',1,'DialogSec']]], + ['errgeneric_24',['errGeneric',['../classDialogSec.html#a8315e79b58bd6bb557b5a934d5f4beba',1,'DialogSec']]], + ['errhelpfailed_25',['errHelpFailed',['../classDialogSec.html#abc275ca943e81edb5459da0afbe8c8c3',1,'DialogSec']]], + ['errhelpnotfound_26',['errHelpNotFound',['../classDialogSec.html#a910d3500df728c06173056a4eac0c358',1,'DialogSec']]], + ['errhelpnotreadable_27',['errHelpNotReadable',['../classDialogSec.html#aefdc8e73c551460720d8a58e7e5e18bb',1,'DialogSec']]], + ['errinvalidlogformatstring_28',['errInvalidLogFormatString',['../classDialogSec.html#a3cc898412f2debd5eff058aa8cd88c80',1,'DialogSec']]], + ['errlanglocaleinvalid_29',['errLangLocaleInvalid',['../classDialogSec.html#ab2c944dbd7d2857d6ec7b0eba8b614ae',1,'DialogSec']]], + ['errlangnotaccepted_30',['errLangNotAccepted',['../classDialogSec.html#a38406ffaaed868ab75be5b7e8f35a1c2',1,'DialogSec']]], + ['errlogformatnofields_31',['errLogFormatNoFields',['../classDialogSec.html#a48efa757e87889491d2d723749647c00',1,'DialogSec']]], + ['errlogformatnoseparators_32',['errLogFormatNoSeparators',['../classDialogSec.html#a5cc9c61fd5d5dea50b248366a6bd6e54',1,'DialogSec']]], + ['errlogformatnotset_33',['errLogFormatNotSet',['../classDialogSec.html#af9f19176ce2981bd3397b9d033490cb8',1,'DialogSec']]], + ['errrenaming_34',['errRenaming',['../classDialogSec.html#a93804c66ed89197dceb292926fceb690',1,'DialogSec']]], + ['errsqldrivernotfound_35',['errSqlDriverNotFound',['../classDialogSec.html#a41c7f8f921aff3ecfb876be3d89276b6',1,'DialogSec']]], + ['exists_36',['exists',['../classIOutils.html#a01cb7864b4ed38d8569b4ba093c0ffd9',1,'IOutils']]] +]; diff --git a/docs/html/search/functions_5.js b/docs/html/search/functions_5.js new file mode 100644 index 00000000..0f98eacd --- /dev/null +++ b/docs/html/search/functions_5.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['findlast_0',['findLast',['../classStringOps.html#a4df2ec361e0f4dff2205d452194ca0b3',1,'StringOps']]], + ['findnginxfieldend_1',['findNginxFieldEnd',['../classFormatOps.html#abd7a77e8576787118fb22a540daea795',1,'FormatOps']]] +]; diff --git a/docs/html/search/functions_6.js b/docs/html/search/functions_6.js new file mode 100644 index 00000000..190f6a56 --- /dev/null +++ b/docs/html/search/functions_6.js @@ -0,0 +1,56 @@ +var searchData= +[ + ['gamedraw_0',['gameDraw',['../classCrissCross.html#afe152a89c9e404e91dfac3f5d492198a',1,'CrissCross']]], + ['geometryfromstring_1',['geometryFromString',['../classMainWindow.html#aa4b87391c49c3780e66bd8104908eaf9',1,'MainWindow']]], + ['geometrytostring_2',['geometryToString',['../classMainWindow.html#acc0fd048160dade0598f71b51fefbf5c',1,'MainWindow']]], + ['getapachelogsample_3',['getApacheLogSample',['../classFormatOps.html#a034a9f4fd9baeefaaa8adf07107f0930',1,'FormatOps']]], + ['getblacklist_4',['getBlacklist',['../classCraplog.html#ad6f3d5667cc510154d858d9616cfa88d',1,'Craplog']]], + ['getcolors_5',['getColors',['../classColorSec.html#ad185a26760f960baf931b0bb79c711ff',1,'ColorSec']]], + ['getcolorscheme_6',['getColorScheme',['../classTextBrowser.html#a36ba738ca28c8ca966aa6ca8a290c981',1,'TextBrowser']]], + ['getcolorschemeid_7',['getColorSchemeID',['../classTextBrowser.html#a49e834e37466828519c0e1fc97b20d16',1,'TextBrowser']]], + ['getcolorschemes_8',['getColorSchemes',['../classColorSec.html#a4ad467469ba6b81fd0827f73ac53b6f8',1,'ColorSec']]], + ['getcurrentlogformat_9',['getCurrentLogFormat',['../classCraplog.html#a9d289b49aedb0fbc2ce02bd805a1a65c',1,'Craplog']]], + ['getcurrentwsid_10',['getCurrentWSID',['../classCraplog.html#a9a49a14e50120682a342ea3ba63947a5',1,'Craplog']]], + ['getdays_11',['getDays',['../classCrapview.html#ad03099fd23d33fbd0f7ef5fcc1c67bde',1,'Crapview']]], + ['getdaytimecounts_12',['getDaytimeCounts',['../classDbQuery.html#a31937b71d3088a7cb84a522e85cc86f1',1,'DbQuery']]], + ['getdbfield_13',['getDbField',['../classDbQuery.html#a17b84cf6ad72726387256e5c6288e93c',1,'DbQuery']]], + ['getdialogslevel_14',['getDialogsLevel',['../classCrapview.html#a9c117a07b9eb26532156e82d7852725b',1,'Crapview::getDialogsLevel()'],['../classCraplog.html#a955b8b094062a6e2ee89cf884dd7b028',1,'Craplog::getDialogsLevel()']]], + ['getfields_15',['getFields',['../classCrapview.html#a9b565e2994fc2f5c7379898fb39c7f15',1,'Crapview']]], + ['getfont_16',['getFont',['../classTextBrowser.html#aef0e5e3fb14ca9b48c1d668aebc33b33',1,'TextBrowser']]], + ['getfontfamily_17',['getFontFamily',['../classTextBrowser.html#ab7ad4bfc3ef92bd938e00dc438559c0b',1,'TextBrowser']]], + ['getglobalcounts_18',['getGlobalCounts',['../classDbQuery.html#ae504836c92d55d421d5e34b145b2065b',1,'DbQuery']]], + ['gethashesdatabasepath_19',['getHashesDatabasePath',['../classCraplog.html#a2b66000f63d8ab34e894b90fe3496e43',1,'Craplog']]], + ['gethours_20',['getHours',['../classCrapview.html#ad6eb1887779aaa5f7c2aa95911e832b8',1,'Crapview']]], + ['getiislogsample_21',['getIisLogSample',['../classFormatOps.html#a1fe9ff3f875e96c0866622f1a60f29b5',1,'FormatOps']]], + ['getitemscount_22',['getItemsCount',['../classDbQuery.html#a47744cc993d6a4bada0a8aec992a2c23',1,'DbQuery']]], + ['getlogfieldid_23',['getLogFieldID',['../classCrapview.html#a2907f88ba82158c8c58f54383b4a7c2a',1,'Crapview']]], + ['getlogfieldstring_24',['getLogFieldString',['../classCrapview.html#ab4aa28144e1d1a8f7954e0a3c6d3f9d1',1,'Crapview']]], + ['getlogfileitem_25',['getLogFileItem',['../classCraplog.html#a8fc3affaf8da7695390877c63b5b6051',1,'Craplog']]], + ['getlogsformat_26',['getLogsFormat',['../classCraplog.html#a946a0f980c91d713bd01cca8e822616d',1,'Craplog']]], + ['getlogsformatsample_27',['getLogsFormatSample',['../classCraplog.html#ae772867818dcfac15eba8f94da7f0493',1,'Craplog']]], + ['getlogsformatstring_28',['getLogsFormatString',['../classCraplog.html#a159ff9779d1ff85c8ecc6cb63274d494',1,'Craplog']]], + ['getlogslist_29',['getLogsList',['../classCraplog.html#aa0c1078272a2c9c88e51da32c2cbf269',1,'Craplog']]], + ['getlogslistsize_30',['getLogsListSize',['../classCraplog.html#affcd5025487fb60f89d7a35c3c807454',1,'Craplog']]], + ['getlogspath_31',['getLogsPath',['../classCraplog.html#aefd29a191a45be88d34dcfadab076f6d',1,'Craplog']]], + ['getminutegap_32',['getMinuteGap',['../classDbQuery.html#ae172c2f717f939daa41c5a0681ca76c3',1,'DbQuery']]], + ['getmonthdays_33',['getMonthDays',['../classDbQuery.html#a3dcefca533b85ef4e4f8fc12bd380d3e',1,'DbQuery']]], + ['getmonthnumber_34',['getMonthNumber',['../classCrapview.html#af156af64d1cb47d1c0fe1bacc3745974',1,'Crapview::getMonthNumber()'],['../classDbQuery.html#a3254d6cbe61c890ebc6b9d97367256dd',1,'DbQuery::getMonthNumber()']]], + ['getmonths_35',['getMonths',['../classCrapview.html#aa8518f26e3769580bbd3439e094b221a',1,'Crapview']]], + ['getmonthscount_36',['getMonthsCount',['../classDbQuery.html#a2fd212eaa2c82188ffc469fa5737792b',1,'DbQuery']]], + ['getnginxlogsample_37',['getNginxLogSample',['../classFormatOps.html#a46cc3ff63986ec4437c20ccbd68569c2',1,'FormatOps']]], + ['getparsedlines_38',['getParsedLines',['../classCraplog.html#ae933a2f390dc08664b2ea07acd0b1c39',1,'Craplog::getParsedLines()'],['../classLogOps.html#a239ed1c9dca8cbf31f8e7c3fe52c1be1',1,'LogOps::getParsedLines()']]], + ['getparsedsize_39',['getParsedSize',['../classLogOps.html#a06ce568d05b595728093dd2458608f41',1,'LogOps']]], + ['getperfsize_40',['getPerfSize',['../classCraplog.html#a556449b0a92e4bea1e444faca663abd5',1,'Craplog']]], + ['getrelationalcountsday_41',['getRelationalCountsDay',['../classDbQuery.html#aa1691a2878a4a6821afdaf155251ec0b',1,'DbQuery']]], + ['getrelationalcountsperiod_42',['getRelationalCountsPeriod',['../classDbQuery.html#acae142053967818896367a61e808533c',1,'DbQuery']]], + ['getspeeddata_43',['getSpeedData',['../classDbQuery.html#a3aa22b5075bf5607d986d641668af1ea',1,'DbQuery']]], + ['getstatsdatabasepath_44',['getStatsDatabasePath',['../classCraplog.html#a1f08bdd3ce8f969684cfb2acccb3a8aa',1,'Craplog']]], + ['getstylesheet_45',['getStyleSheet',['../classStyleSec.html#ac0781d686293b84e935bd29fe5283b14',1,'StyleSec']]], + ['gettotalsize_46',['getTotalSize',['../classCraplog.html#a92dd0b6330bdc32c908e688b7eced812',1,'Craplog::getTotalSize()'],['../classLogOps.html#a669727346faca20c48fe8f00e3c906ec',1,'LogOps::getTotalSize()']]], + ['getwarncounts_47',['getWarnCounts',['../classDbQuery.html#a2fc983abeeec05d04a110a29f80c4009',1,'DbQuery']]], + ['getwarningsize_48',['getWarningSize',['../classCraplog.html#af79d254595263448fead944f82db8931',1,'Craplog']]], + ['getwarnlist_49',['getWarnlist',['../classCraplog.html#a53df5cc15fdc79c1708aaf002c2f7719',1,'Craplog']]], + ['getwidelinesusage_50',['getWideLinesUsage',['../classTextBrowser.html#a7a62dfd67e7a58f374951272ac13defd',1,'TextBrowser']]], + ['getyears_51',['getYears',['../classCrapview.html#ab3081c678b102b255fa9f32a8f94e052',1,'Crapview']]], + ['grow_52',['grow',['../classSnake.html#a524fb8b522e917f620cfb401f2badabe',1,'Snake']]] +]; diff --git a/docs/html/search/functions_7.js b/docs/html/search/functions_7.js new file mode 100644 index 00000000..1cd4a7e4 --- /dev/null +++ b/docs/html/search/functions_7.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['hasbeenused_0',['hasBeenUsed',['../classHashOps.html#aa9900aa35ed9c3538586c1c1d97f421d',1,'HashOps']]], + ['helplogsformat_1',['helpLogsFormat',['../classCraphelp.html#a12d9f2ecffbd122a633ba3dee8267712',1,'Craphelp']]] +]; diff --git a/docs/html/search/functions_8.js b/docs/html/search/functions_8.js new file mode 100644 index 00000000..06c51c32 --- /dev/null +++ b/docs/html/search/functions_8.js @@ -0,0 +1,19 @@ +var searchData= +[ + ['insertusedhash_0',['insertUsedHash',['../classHashOps.html#aeaf1ff64dcbec02e16eeec819a477019',1,'HashOps']]], + ['insertusedhashes_1',['insertUsedHashes',['../classHashOps.html#a63840ab6e5657c47179eb8667a25e3e0',1,'HashOps']]], + ['intile_2',['inTile',['../classFood.html#af75b2df758867826e9db4527aaf17d96',1,'Food::inTile()'],['../classSnake.html#a9afd044f5fa48f6d5f84dbff158d8a50',1,'Snake::inTile()']]], + ['isalnum_3',['isAlnum',['../classStringOps.html#a97036dc057034511dd3b9dc60e58979c',1,'StringOps::isAlnum(const std::string &str)'],['../classStringOps.html#a8235ab748959ad5967b06b4455c41e32',1,'StringOps::isAlnum(const unsigned char &chr)']]], + ['isalphabetic_4',['isAlphabetic',['../classStringOps.html#aed7c6db4c635d5cae9489b6305af9f2f',1,'StringOps::isAlphabetic(const std::string &str)'],['../classStringOps.html#a45df33004f631721adb15d9e975ba623',1,'StringOps::isAlphabetic(const unsigned char &chr)']]], + ['isblacklistused_5',['isBlacklistUsed',['../classCraplog.html#a17cfa8fd4c173fd5025d50e5f9f63259',1,'Craplog']]], + ['isdir_6',['isDir',['../classIOutils.html#ae205985989cf337fc03cd332971bfa71',1,'IOutils']]], + ['isfile_7',['isFile',['../classIOutils.html#a8bcf274a39f4c2187cca2b7246813c92',1,'IOutils']]], + ['isfilenamevalid_8',['isFileNameValid',['../classCraplog.html#aae25f0828da7cdf9dae0a48cecbc7fab',1,'Craplog']]], + ['ishex_9',['isHex',['../classStringOps.html#a4bd9e3db497099d3427351016be4ef5b',1,'StringOps']]], + ['isip_10',['isIP',['../classStringOps.html#a5c1c8c34501cc06f805a68e7f63938c3',1,'StringOps']]], + ['isnumeric_11',['isNumeric',['../classStringOps.html#a658cd6b0a48b94944851c6e4a71873d8',1,'StringOps::isNumeric(const std::string &str)'],['../classStringOps.html#a3f3446cdde7d3a7f2e26b60f29602589',1,'StringOps::isNumeric(const unsigned char &chr)']]], + ['isparsing_12',['isParsing',['../classCraplog.html#a38bd81dc41a7bcb3f93674fca5e70b7b',1,'Craplog']]], + ['isplayerturn_13',['isPlayerTurn',['../classCrissCross.html#a43322d09dc3752d222ed165fba5b554f',1,'CrissCross']]], + ['iswarnlistused_14',['isWarnlistUsed',['../classCraplog.html#aa26972256a75166113aa3d3b1ce73583',1,'Craplog']]], + ['isworking_15',['isWorking',['../classCraplog.html#a8f4b8fa9f2ef6f990bece47faed0a74a',1,'Craplog']]] +]; diff --git a/docs/html/search/functions_9.js b/docs/html/search/functions_9.js new file mode 100644 index 00000000..3295de2d --- /dev/null +++ b/docs/html/search/functions_9.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['joinloglines_0',['joinLogLines',['../classCraplog.html#aa53d6671a6c1942973afabfb68c1af55',1,'Craplog']]] +]; diff --git a/docs/html/search/functions_a.js b/docs/html/search/functions_a.js new file mode 100644 index 00000000..5119c199 --- /dev/null +++ b/docs/html/search/functions_a.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['keypressevent_0',['keyPressEvent',['../classSnakeGame.html#a407dd2bae84d0f6572b94bb37feb87bc',1,'SnakeGame']]] +]; diff --git a/docs/html/search/functions_b.js b/docs/html/search/functions_b.js new file mode 100644 index 00000000..1bb499f6 --- /dev/null +++ b/docs/html/search/functions_b.js @@ -0,0 +1,7 @@ +var searchData= +[ + ['list2string_0',['list2string',['../classMainWindow.html#ad027d13d13237554d03d1a89287a08f0',1,'MainWindow']]], + ['loadusedhasheslists_1',['loadUsedHashesLists',['../classHashOps.html#a1184284b059b2094b0fc5cbbd1a2050b',1,'HashOps']]], + ['lstrip_2',['lstrip',['../classStringOps.html#ad57d5941c836f52cefcb711bff23fb50',1,'StringOps']]], + ['lstripuntil_3',['lstripUntil',['../classStringOps.html#a8a308ab32a62169c5a28ddb6db0b78f6',1,'StringOps']]] +]; diff --git a/docs/html/search/functions_c.js b/docs/html/search/functions_c.js new file mode 100644 index 00000000..583207d2 --- /dev/null +++ b/docs/html/search/functions_c.js @@ -0,0 +1,11 @@ +var searchData= +[ + ['makechart_0',['makeChart',['../classCraplog.html#a3956db74f727d95f73738d9c19693007',1,'Craplog']]], + ['makedir_1',['makeDir',['../classIOutils.html#ac38e61e00c839dca681d90b5c0397093',1,'IOutils']]], + ['makeinitialchecks_2',['makeInitialChecks',['../classMainWindow.html#ae459fb4a3966975abe641c11c76e2c03',1,'MainWindow']]], + ['makepreview_3',['makePreview',['../classTextBrowser.html#a5b0eb8070202317c6e04534ca417c957',1,'TextBrowser']]], + ['makestylesheet_4',['makeStyleSheet',['../classStyleSec.html#a7deedd8236a76bdb8ba050e1fb797f11',1,'StyleSec']]], + ['menu_5factionenglish_5ftriggered_5',['menu_actionEnglish_triggered',['../classMainWindow.html#adffe78de926642168d16bfd8a2522c29',1,'MainWindow']]], + ['move_6',['move',['../classFood.html#a7196aa14ad843820518dc9db03252d21',1,'Food']]], + ['msgdatabasecreated_7',['msgDatabaseCreated',['../classDialogSec.html#ae916458257088da13a1a2bc885d5c71d',1,'DialogSec']]] +]; diff --git a/docs/html/search/functions_d.js b/docs/html/search/functions_d.js new file mode 100644 index 00000000..5c062137 --- /dev/null +++ b/docs/html/search/functions_d.js @@ -0,0 +1,7 @@ +var searchData= +[ + ['name_0',['name',['../classMainSlice.html#adda5fecbc9d60f8d6367f187fd4f6c0f',1,'MainSlice']]], + ['newcollectiondatabase_1',['newCollectionDatabase',['../classCheckSec.html#a31f0c54f9b229bd616ad49a0bc09e16d',1,'CheckSec']]], + ['newhashesdatabase_2',['newHashesDatabase',['../classCheckSec.html#a56248ef831e3ea55830735ce5d436ba4',1,'CheckSec']]], + ['nextturn_3',['nextTurn',['../classCrissCross.html#acb1ca7cc584c4c2e21e94d88c794c06a',1,'CrissCross']]] +]; diff --git a/docs/html/search/functions_e.js b/docs/html/search/functions_e.js new file mode 100644 index 00000000..fcefdd0f --- /dev/null +++ b/docs/html/search/functions_e.js @@ -0,0 +1,13 @@ +var searchData= +[ + ['on_5fbutton_5fabort_5fclicked_0',['on_button_ABORT_clicked',['../classDialogDia.html#a6fd03d1ce4cb3b6d424ada80b0a5b1f1',1,'DialogDia']]], + ['on_5fbutton_5fdiscard_5fclicked_1',['on_button_DISCARD_clicked',['../classDialogDia.html#a6682425f97963fbf2e2d94af0c766108',1,'DialogDia']]], + ['on_5fbutton_5ffontsize_5fminus_5fclicked_2',['on_button_FontSize_Minus_clicked',['../classCrapnote.html#acdcd9cf3e007d9c60aa2f1449798a0ae',1,'Crapnote']]], + ['on_5fbutton_5ffontsize_5fplus_5fclicked_3',['on_button_FontSize_Plus_clicked',['../classCrapnote.html#a0939b6b9916b5719ea9c55d40659b83b',1,'Crapnote']]], + ['on_5fbutton_5fignore_5fclicked_4',['on_button_IGNORE_clicked',['../classDialogDia.html#a8ba6f60f5f3833c972f3408bcd34c324',1,'DialogDia']]], + ['on_5fbutton_5fno_5fclicked_5',['on_button_NO_clicked',['../classDialogBool.html#a718195dfd76ecefd349333cfd82dc1cc',1,'DialogBool']]], + ['on_5fbutton_5fok_5fclicked_6',['on_button_Ok_clicked',['../classDialogMsg.html#a14ce87023686cac4cf700e0283073058',1,'DialogMsg']]], + ['on_5fbutton_5fshowadditional_5fclicked_7',['on_button_ShowAdditional_clicked',['../classDialogMsg.html#aa273ea069307de059183e8d2b7a2f7ef',1,'DialogMsg']]], + ['on_5fbutton_5fyes_5fclicked_8',['on_button_YES_clicked',['../classDialogBool.html#a14f2fcaac67126b4411bd4a78768809e',1,'DialogBool']]], + ['on_5fspinbox_5ffontsize_5fvaluechanged_9',['on_spinBox_FontSize_valueChanged',['../classCrapnote.html#a3eb5f7525b474fb46c15d383ee9b1d6a',1,'Crapnote']]] +]; diff --git a/docs/html/search/functions_f.js b/docs/html/search/functions_f.js new file mode 100644 index 00000000..2bc7060b --- /dev/null +++ b/docs/html/search/functions_f.js @@ -0,0 +1,22 @@ +var searchData= +[ + ['parseapacheescapes_0',['parseApacheEscapes',['../classFormatOps.html#aea7c5e264f8a40c92cd39916ff75b02b',1,'FormatOps']]], + ['parsebooleanfilter_1',['parseBooleanFilter',['../classCrapview.html#aa7fe41edd00d1754ade13c095ad20b82',1,'Crapview']]], + ['parseline_2',['parseLine',['../classLogOps.html#a21da556ce7b7f75cb032c499cd25bfec',1,'LogOps']]], + ['parselines_3',['parseLines',['../classLogOps.html#ad330fe53570a6b1e6edc198e894bcb12',1,'LogOps']]], + ['parseloglines_4',['parseLogLines',['../classCraplog.html#a0b5e942827237a1e61f48b76be89dc0d',1,'Craplog']]], + ['parsenginxescapes_5',['parseNginxEscapes',['../classFormatOps.html#aa8a4f2b2f78807f7156932233d7977fe',1,'FormatOps']]], + ['parsenumericfilter_6',['parseNumericFilter',['../classCrapview.html#ab450412741c7af21dfec42fad5a7f20a',1,'Crapview']]], + ['parsetextualfilter_7',['parseTextualFilter',['../classCrapview.html#ae7693a3fa2b4a402eb123af94a73d809',1,'Crapview']]], + ['printabledate_8',['printableDate',['../classCrapview.html#a3a73f6f5683afaaa17a3065eada4438e',1,'Crapview']]], + ['printablesize_9',['printableSize',['../classCraplog.html#a34dc89787f7e104a84d01ebdeb00b074',1,'Craplog::printableSize()'],['../classMainWindow.html#a05a108ff2e9f3a25e2bfbae1d6ae8578',1,'MainWindow::printableSize(const int &bytes)']]], + ['printablespeed_10',['printableSpeed',['../classMainWindow.html#aef96785abecd1b4f0eb7b845b0e64f59',1,'MainWindow']]], + ['printabletime_11',['printableTime',['../classMainWindow.html#ab2a9929d2a80fa4766059ef40904201c',1,'MainWindow::printableTime()'],['../classCrapview.html#af77a399adbd69a9bfd26e42c31e71324',1,'Crapview::printableTime(const int &hour, const int &minute, const int &second)']]], + ['printablewarn_12',['printableWarn',['../classCrapview.html#a2feca301352ca7bd76e199fbcaef932c',1,'Crapview']]], + ['processapacheformatstring_13',['processApacheFormatString',['../classFormatOps.html#a9bc720b012546f34b3f844459089a29d',1,'FormatOps']]], + ['processdatetime_14',['processDateTime',['../classDateTimeOps.html#a3e0808c8c395b0e9ea9240aa065b8967',1,'DateTimeOps']]], + ['processgamelogic_15',['processGameLogic',['../classSnakeGame.html#aeaa13da59d09abc40e25fd769fb96963',1,'SnakeGame']]], + ['processiisformatstring_16',['processIisFormatString',['../classFormatOps.html#afc7446da6389b522922cb94c4319f4ec',1,'FormatOps']]], + ['processnextkeyevent_17',['processNextKeyEvent',['../classSnakeGame.html#a0b0c9d7567a8e352449ddc7b31e09851',1,'SnakeGame']]], + ['processnginxformatstring_18',['processNginxFormatString',['../classFormatOps.html#a9e4c9fb02220492ce2766e830f4fedc6',1,'FormatOps']]] +]; diff --git a/docs/html/search/mag.svg b/docs/html/search/mag.svg new file mode 100644 index 00000000..9f46b301 --- /dev/null +++ b/docs/html/search/mag.svg @@ -0,0 +1,37 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/docs/html/search/mag_d.svg b/docs/html/search/mag_d.svg new file mode 100644 index 00000000..b9a814c7 --- /dev/null +++ b/docs/html/search/mag_d.svg @@ -0,0 +1,37 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/docs/html/search/mag_sel.svg b/docs/html/search/mag_sel.svg new file mode 100644 index 00000000..03626f64 --- /dev/null +++ b/docs/html/search/mag_sel.svg @@ -0,0 +1,74 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + diff --git a/docs/html/search/mag_seld.svg b/docs/html/search/mag_seld.svg new file mode 100644 index 00000000..6e720dcc --- /dev/null +++ b/docs/html/search/mag_seld.svg @@ -0,0 +1,74 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + diff --git a/docs/html/search/search.css b/docs/html/search/search.css new file mode 100644 index 00000000..19f76f9d --- /dev/null +++ b/docs/html/search/search.css @@ -0,0 +1,291 @@ +/*---------------- Search Box positioning */ + +#main-menu > li:last-child { + /* This
  • object is the parent of the search bar */ + display: flex; + justify-content: center; + align-items: center; + height: 36px; + margin-right: 1em; +} + +/*---------------- Search box styling */ + +.SRPage * { + font-weight: normal; + line-height: normal; +} + +dark-mode-toggle { + margin-left: 5px; + display: flex; + float: right; +} + +#MSearchBox { + display: inline-block; + white-space : nowrap; + background: var(--search-background-color); + border-radius: 0.65em; + box-shadow: var(--search-box-shadow); + z-index: 102; +} + +#MSearchBox .left { + display: inline-block; + vertical-align: middle; + height: 1.4em; +} + +#MSearchSelect { + display: inline-block; + vertical-align: middle; + width: 20px; + height: 19px; + background-image: var(--search-magnification-select-image); + margin: 0 0 0 0.3em; + padding: 0; +} + +#MSearchSelectExt { + display: inline-block; + vertical-align: middle; + width: 10px; + height: 19px; + background-image: var(--search-magnification-image); + margin: 0 0 0 0.5em; + padding: 0; +} + + +#MSearchField { + display: inline-block; + vertical-align: middle; + width: 7.5em; + height: 19px; + margin: 0 0.15em; + padding: 0; + line-height: 1em; + border:none; + color: var(--search-foreground-color); + outline: none; + font-family: var(--font-family-search); + -webkit-border-radius: 0px; + border-radius: 0px; + background: none; +} + +@media(hover: none) { + /* to avoid zooming on iOS */ + #MSearchField { + font-size: 16px; + } +} + +#MSearchBox .right { + display: inline-block; + vertical-align: middle; + width: 1.4em; + height: 1.4em; +} + +#MSearchClose { + display: none; + font-size: inherit; + background : none; + border: none; + margin: 0; + padding: 0; + outline: none; + +} + +#MSearchCloseImg { + padding: 0.3em; + margin: 0; +} + +.MSearchBoxActive #MSearchField { + color: var(--search-active-color); +} + + + +/*---------------- Search filter selection */ + +#MSearchSelectWindow { + display: none; + position: absolute; + left: 0; top: 0; + border: 1px solid var(--search-filter-border-color); + background-color: var(--search-filter-background-color); + z-index: 10001; + padding-top: 4px; + padding-bottom: 4px; + -moz-border-radius: 4px; + -webkit-border-top-left-radius: 4px; + -webkit-border-top-right-radius: 4px; + -webkit-border-bottom-left-radius: 4px; + -webkit-border-bottom-right-radius: 4px; + -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); +} + +.SelectItem { + font: 8pt var(--font-family-search); + padding-left: 2px; + padding-right: 12px; + border: 0px; +} + +span.SelectionMark { + margin-right: 4px; + font-family: var(--font-family-monospace); + outline-style: none; + text-decoration: none; +} + +a.SelectItem { + display: block; + outline-style: none; + color: var(--search-filter-foreground-color); + text-decoration: none; + padding-left: 6px; + padding-right: 12px; +} + +a.SelectItem:focus, +a.SelectItem:active { + color: var(--search-filter-foreground-color); + outline-style: none; + text-decoration: none; +} + +a.SelectItem:hover { + color: var(--search-filter-highlight-text-color); + background-color: var(--search-filter-highlight-bg-color); + outline-style: none; + text-decoration: none; + cursor: pointer; + display: block; +} + +/*---------------- Search results window */ + +iframe#MSearchResults { + /*width: 60ex;*/ + height: 15em; +} + +#MSearchResultsWindow { + display: none; + position: absolute; + left: 0; top: 0; + border: 1px solid var(--search-results-border-color); + background-color: var(--search-results-background-color); + z-index:10000; + width: 300px; + height: 400px; + overflow: auto; +} + +/* ----------------------------------- */ + + +#SRIndex { + clear:both; +} + +.SREntry { + font-size: 10pt; + padding-left: 1ex; +} + +.SRPage .SREntry { + font-size: 8pt; + padding: 1px 5px; +} + +div.SRPage { + margin: 5px 2px; + background-color: var(--search-results-background-color); +} + +.SRChildren { + padding-left: 3ex; padding-bottom: .5em +} + +.SRPage .SRChildren { + display: none; +} + +.SRSymbol { + font-weight: bold; + color: var(--search-results-foreground-color); + font-family: var(--font-family-search); + text-decoration: none; + outline: none; +} + +a.SRScope { + display: block; + color: var(--search-results-foreground-color); + font-family: var(--font-family-search); + font-size: 8pt; + text-decoration: none; + outline: none; +} + +a.SRSymbol:focus, a.SRSymbol:active, +a.SRScope:focus, a.SRScope:active { + text-decoration: underline; +} + +span.SRScope { + padding-left: 4px; + font-family: var(--font-family-search); +} + +.SRPage .SRStatus { + padding: 2px 5px; + font-size: 8pt; + font-style: italic; + font-family: var(--font-family-search); +} + +.SRResult { + display: none; +} + +div.searchresults { + margin-left: 10px; + margin-right: 10px; +} + +/*---------------- External search page results */ + +.pages b { + color: white; + padding: 5px 5px 3px 5px; + background-image: var(--nav-gradient-active-image-parent); + background-repeat: repeat-x; + text-shadow: 0 1px 1px #000000; +} + +.pages { + line-height: 17px; + margin-left: 4px; + text-decoration: none; +} + +.hl { + font-weight: bold; +} + +#searchresults { + margin-bottom: 20px; +} + +.searchpages { + margin-top: 10px; +} + diff --git a/docs/html/search/search.js b/docs/html/search/search.js new file mode 100644 index 00000000..e103a262 --- /dev/null +++ b/docs/html/search/search.js @@ -0,0 +1,816 @@ +/* + @licstart The following is the entire license notice for the JavaScript code in this file. + + The MIT License (MIT) + + Copyright (C) 1997-2020 by Dimitri van Heesch + + Permission is hereby granted, free of charge, to any person obtaining a copy of this software + and associated documentation files (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, publish, distribute, + sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all copies or + substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + @licend The above is the entire license notice for the JavaScript code in this file + */ +function convertToId(search) +{ + var result = ''; + for (i=0;i do a search + { + this.Search(); + } + } + + this.OnSearchSelectKey = function(evt) + { + var e = (evt) ? evt : window.event; // for IE + if (e.keyCode==40 && this.searchIndex0) // Up + { + this.searchIndex--; + this.OnSelectItem(this.searchIndex); + } + else if (e.keyCode==13 || e.keyCode==27) + { + this.OnSelectItem(this.searchIndex); + this.CloseSelectionWindow(); + this.DOMSearchField().focus(); + } + return false; + } + + // --------- Actions + + // Closes the results window. + this.CloseResultsWindow = function() + { + this.DOMPopupSearchResultsWindow().style.display = 'none'; + this.DOMSearchClose().style.display = 'none'; + this.Activate(false); + } + + this.CloseSelectionWindow = function() + { + this.DOMSearchSelectWindow().style.display = 'none'; + } + + // Performs a search. + this.Search = function() + { + this.keyTimeout = 0; + + // strip leading whitespace + var searchValue = this.DOMSearchField().value.replace(/^ +/, ""); + + var code = searchValue.toLowerCase().charCodeAt(0); + var idxChar = searchValue.substr(0, 1).toLowerCase(); + if ( 0xD800 <= code && code <= 0xDBFF && searchValue > 1) // surrogate pair + { + idxChar = searchValue.substr(0, 2); + } + + var jsFile; + + var idx = indexSectionsWithContent[this.searchIndex].indexOf(idxChar); + if (idx!=-1) + { + var hexCode=idx.toString(16); + jsFile = this.resultsPath + indexSectionNames[this.searchIndex] + '_' + hexCode + '.js'; + } + + var loadJS = function(url, impl, loc){ + var scriptTag = document.createElement('script'); + scriptTag.src = url; + scriptTag.onload = impl; + scriptTag.onreadystatechange = impl; + loc.appendChild(scriptTag); + } + + var domPopupSearchResultsWindow = this.DOMPopupSearchResultsWindow(); + var domSearchBox = this.DOMSearchBox(); + var domPopupSearchResults = this.DOMPopupSearchResults(); + var domSearchClose = this.DOMSearchClose(); + var resultsPath = this.resultsPath; + + var handleResults = function() { + document.getElementById("Loading").style.display="none"; + if (typeof searchData !== 'undefined') { + createResults(resultsPath); + document.getElementById("NoMatches").style.display="none"; + } + + searchResults.Search(searchValue); + + if (domPopupSearchResultsWindow.style.display!='block') + { + domSearchClose.style.display = 'inline-block'; + var left = getXPos(domSearchBox) + 150; + var top = getYPos(domSearchBox) + 20; + domPopupSearchResultsWindow.style.display = 'block'; + left -= domPopupSearchResults.offsetWidth; + var maxWidth = document.body.clientWidth; + var maxHeight = document.body.clientHeight; + var width = 300; + if (left<10) left=10; + if (width+left+8>maxWidth) width=maxWidth-left-8; + var height = 400; + if (height+top+8>maxHeight) height=maxHeight-top-8; + domPopupSearchResultsWindow.style.top = top + 'px'; + domPopupSearchResultsWindow.style.left = left + 'px'; + domPopupSearchResultsWindow.style.width = width + 'px'; + domPopupSearchResultsWindow.style.height = height + 'px'; + } + } + + if (jsFile) { + loadJS(jsFile, handleResults, this.DOMPopupSearchResultsWindow()); + } else { + handleResults(); + } + + this.lastSearchValue = searchValue; + } + + // -------- Activation Functions + + // Activates or deactivates the search panel, resetting things to + // their default values if necessary. + this.Activate = function(isActive) + { + if (isActive || // open it + this.DOMPopupSearchResultsWindow().style.display == 'block' + ) + { + this.DOMSearchBox().className = 'MSearchBoxActive'; + this.searchActive = true; + } + else if (!isActive) // directly remove the panel + { + this.DOMSearchBox().className = 'MSearchBoxInactive'; + this.searchActive = false; + this.lastSearchValue = '' + this.lastResultsPage = ''; + this.DOMSearchField().value = ''; + } + } +} + +// ----------------------------------------------------------------------- + +// The class that handles everything on the search results page. +function SearchResults(name) +{ + // The number of matches from the last run of . + this.lastMatchCount = 0; + this.lastKey = 0; + this.repeatOn = false; + + // Toggles the visibility of the passed element ID. + this.FindChildElement = function(id) + { + var parentElement = document.getElementById(id); + var element = parentElement.firstChild; + + while (element && element!=parentElement) + { + if (element.nodeName.toLowerCase() == 'div' && element.className == 'SRChildren') + { + return element; + } + + if (element.nodeName.toLowerCase() == 'div' && element.hasChildNodes()) + { + element = element.firstChild; + } + else if (element.nextSibling) + { + element = element.nextSibling; + } + else + { + do + { + element = element.parentNode; + } + while (element && element!=parentElement && !element.nextSibling); + + if (element && element!=parentElement) + { + element = element.nextSibling; + } + } + } + } + + this.Toggle = function(id) + { + var element = this.FindChildElement(id); + if (element) + { + if (element.style.display == 'block') + { + element.style.display = 'none'; + } + else + { + element.style.display = 'block'; + } + } + } + + // Searches for the passed string. If there is no parameter, + // it takes it from the URL query. + // + // Always returns true, since other documents may try to call it + // and that may or may not be possible. + this.Search = function(search) + { + if (!search) // get search word from URL + { + search = window.location.search; + search = search.substring(1); // Remove the leading '?' + search = unescape(search); + } + + search = search.replace(/^ +/, ""); // strip leading spaces + search = search.replace(/ +$/, ""); // strip trailing spaces + search = search.toLowerCase(); + search = convertToId(search); + + var resultRows = document.getElementsByTagName("div"); + var matches = 0; + + var i = 0; + while (i < resultRows.length) + { + var row = resultRows.item(i); + if (row.className == "SRResult") + { + var rowMatchName = row.id.toLowerCase(); + rowMatchName = rowMatchName.replace(/^sr\d*_/, ''); // strip 'sr123_' + + if (search.length<=rowMatchName.length && + rowMatchName.substr(0, search.length)==search) + { + row.style.display = 'block'; + matches++; + } + else + { + row.style.display = 'none'; + } + } + i++; + } + document.getElementById("Searching").style.display='none'; + if (matches == 0) // no results + { + document.getElementById("NoMatches").style.display='block'; + } + else // at least one result + { + document.getElementById("NoMatches").style.display='none'; + } + this.lastMatchCount = matches; + return true; + } + + // return the first item with index index or higher that is visible + this.NavNext = function(index) + { + var focusItem; + while (1) + { + var focusName = 'Item'+index; + focusItem = document.getElementById(focusName); + if (focusItem && focusItem.parentNode.parentNode.style.display=='block') + { + break; + } + else if (!focusItem) // last element + { + break; + } + focusItem=null; + index++; + } + return focusItem; + } + + this.NavPrev = function(index) + { + var focusItem; + while (1) + { + var focusName = 'Item'+index; + focusItem = document.getElementById(focusName); + if (focusItem && focusItem.parentNode.parentNode.style.display=='block') + { + break; + } + else if (!focusItem) // last element + { + break; + } + focusItem=null; + index--; + } + return focusItem; + } + + this.ProcessKeys = function(e) + { + if (e.type == "keydown") + { + this.repeatOn = false; + this.lastKey = e.keyCode; + } + else if (e.type == "keypress") + { + if (!this.repeatOn) + { + if (this.lastKey) this.repeatOn = true; + return false; // ignore first keypress after keydown + } + } + else if (e.type == "keyup") + { + this.lastKey = 0; + this.repeatOn = false; + } + return this.lastKey!=0; + } + + this.Nav = function(evt,itemIndex) + { + var e = (evt) ? evt : window.event; // for IE + if (e.keyCode==13) return true; + if (!this.ProcessKeys(e)) return false; + + if (this.lastKey==38) // Up + { + var newIndex = itemIndex-1; + var focusItem = this.NavPrev(newIndex); + if (focusItem) + { + var child = this.FindChildElement(focusItem.parentNode.parentNode.id); + if (child && child.style.display == 'block') // children visible + { + var n=0; + var tmpElem; + while (1) // search for last child + { + tmpElem = document.getElementById('Item'+newIndex+'_c'+n); + if (tmpElem) + { + focusItem = tmpElem; + } + else // found it! + { + break; + } + n++; + } + } + } + if (focusItem) + { + focusItem.focus(); + } + else // return focus to search field + { + document.getElementById("MSearchField").focus(); + } + } + else if (this.lastKey==40) // Down + { + var newIndex = itemIndex+1; + var focusItem; + var item = document.getElementById('Item'+itemIndex); + var elem = this.FindChildElement(item.parentNode.parentNode.id); + if (elem && elem.style.display == 'block') // children visible + { + focusItem = document.getElementById('Item'+itemIndex+'_c0'); + } + if (!focusItem) focusItem = this.NavNext(newIndex); + if (focusItem) focusItem.focus(); + } + else if (this.lastKey==39) // Right + { + var item = document.getElementById('Item'+itemIndex); + var elem = this.FindChildElement(item.parentNode.parentNode.id); + if (elem) elem.style.display = 'block'; + } + else if (this.lastKey==37) // Left + { + var item = document.getElementById('Item'+itemIndex); + var elem = this.FindChildElement(item.parentNode.parentNode.id); + if (elem) elem.style.display = 'none'; + } + else if (this.lastKey==27) // Escape + { + searchBox.CloseResultsWindow(); + document.getElementById("MSearchField").focus(); + } + else if (this.lastKey==13) // Enter + { + return true; + } + return false; + } + + this.NavChild = function(evt,itemIndex,childIndex) + { + var e = (evt) ? evt : window.event; // for IE + if (e.keyCode==13) return true; + if (!this.ProcessKeys(e)) return false; + + if (this.lastKey==38) // Up + { + if (childIndex>0) + { + var newIndex = childIndex-1; + document.getElementById('Item'+itemIndex+'_c'+newIndex).focus(); + } + else // already at first child, jump to parent + { + document.getElementById('Item'+itemIndex).focus(); + } + } + else if (this.lastKey==40) // Down + { + var newIndex = childIndex+1; + var elem = document.getElementById('Item'+itemIndex+'_c'+newIndex); + if (!elem) // last child, jump to parent next parent + { + elem = this.NavNext(itemIndex+1); + } + if (elem) + { + elem.focus(); + } + } + else if (this.lastKey==27) // Escape + { + searchBox.CloseResultsWindow(); + document.getElementById("MSearchField").focus(); + } + else if (this.lastKey==13) // Enter + { + return true; + } + return false; + } +} + +function setKeyActions(elem,action) +{ + elem.setAttribute('onkeydown',action); + elem.setAttribute('onkeypress',action); + elem.setAttribute('onkeyup',action); +} + +function setClassAttr(elem,attr) +{ + elem.setAttribute('class',attr); + elem.setAttribute('className',attr); +} + +function createResults(resultsPath) +{ + var results = document.getElementById("SRResults"); + results.innerHTML = ''; + for (var e=0; e + + + + + + +LogDoctor: Member List + + + + + + + + + +
    +
    + + + + + + + +
    +
    LogDoctor 2.00 +
    +
    Parse Apache2/Nginx/IIS logs and create statistics
    +
    +
    + + + + + + + + +
    +
    + + +
    +
    +
    +
    +
    +
    Loading...
    +
    Searching...
    +
    No Matches
    +
    +
    +
    +
    + +
    +
    +
    BodyPart Member List
    +
    +
    + +

    This is the complete list of members for BodyPart, including all inherited members.

    + + + + + + + +
    directionBodyPart
    imageBodyPart
    prev_directionBodyPart
    update(const unsigned int &new_x, const unsigned int &new_y, const Direction &new_direction)BodyPartinline
    xBodyPart
    yBodyPart
    + + + + diff --git a/docs/html/structBodyPart.html b/docs/html/structBodyPart.html new file mode 100644 index 00000000..2af2036c --- /dev/null +++ b/docs/html/structBodyPart.html @@ -0,0 +1,142 @@ + + + + + + + +LogDoctor: BodyPart Struct Reference + + + + + + + + + +
    +
    + + + + + + + +
    +
    LogDoctor 2.00 +
    +
    Parse Apache2/Nginx/IIS logs and create statistics
    +
    +
    + + + + + + + + +
    +
    + + +
    +
    +
    +
    +
    +
    Loading...
    +
    Searching...
    +
    No Matches
    +
    +
    +
    +
    + +
    +
    + +
    BodyPart Struct Reference
    +
    +
    + +

    Instance of a part of the body of the snake. + More...

    + +

    #include <snake.h>

    + + + + + +

    +Public Member Functions

    +void update (const unsigned int &new_x, const unsigned int &new_y, const Direction &new_direction)
     Updates the position and direction of the part.
     
    + + + + + + + + + + + + + + + +

    +Public Attributes

    +unsigned int x
     The position on the X-axis.
     
    +unsigned int y
     The position on the Y-axis.
     
    +Direction direction
     The current direction of the part.
     
    +Direction prev_direction
     The previous direction of the part.
     
    QGraphicsPixmapItem * image
     
    +

    Detailed Description

    +

    Instance of a part of the body of the snake.

    +

    Member Data Documentation

    + +

    ◆ image

    + +
    +
    + + + + +
    QGraphicsPixmapItem* BodyPart::image
    +
    +

    The image which graphically represents the part

    + +
    +
    +
    The documentation for this struct was generated from the following file:
      +
    • logdoctor/games/snake/snake.h
    • +
    +
    + + + + diff --git a/docs/html/structCraplog_1_1BWlist-members.html b/docs/html/structCraplog_1_1BWlist-members.html new file mode 100644 index 00000000..7ccc85d3 --- /dev/null +++ b/docs/html/structCraplog_1_1BWlist-members.html @@ -0,0 +1,92 @@ + + + + + + + +LogDoctor: Member List + + + + + + + + + +
    +
    + + + + + + + +
    +
    LogDoctor 2.00 +
    +
    Parse Apache2/Nginx/IIS logs and create statistics
    +
    +
    + + + + + + + + +
    +
    + + +
    +
    +
    +
    +
    +
    Loading...
    +
    Searching...
    +
    No Matches
    +
    +
    +
    +
    + + +
    +
    +
    Craplog::BWlist Member List
    +
    +
    + +

    This is the complete list of members for Craplog::BWlist, including all inherited members.

    + + + +
    listCraplog::BWlist
    usedCraplog::BWlist
    + + + + diff --git a/docs/html/structCraplog_1_1BWlist.html b/docs/html/structCraplog_1_1BWlist.html new file mode 100644 index 00000000..eddd9948 --- /dev/null +++ b/docs/html/structCraplog_1_1BWlist.html @@ -0,0 +1,112 @@ + + + + + + + +LogDoctor: Craplog::BWlist Struct Reference + + + + + + + + + +
    +
    + + + + + + + +
    +
    LogDoctor 2.00 +
    +
    Parse Apache2/Nginx/IIS logs and create statistics
    +
    +
    + + + + + + + + +
    +
    + + +
    +
    +
    +
    +
    +
    Loading...
    +
    Searching...
    +
    No Matches
    +
    +
    +
    +
    + + +
    +
    + +
    Craplog::BWlist Struct Reference
    +
    +
    + +

    Structure to hold the items of a blacklist/warnlist. + More...

    + +

    #include <craplog.h>

    + + + + + + + + +

    +Public Attributes

    +bool used
     Whether the list is set to be used or not.
     
    +std::vector< std::string > list
     The list of items.
     
    +

    Detailed Description

    +

    Structure to hold the items of a blacklist/warnlist.

    +

    The documentation for this struct was generated from the following file:
      +
    • logdoctor/modules/craplog/craplog.h
    • +
    +
    + + + + diff --git a/docs/html/structCraplog_1_1LogFile-members.html b/docs/html/structCraplog_1_1LogFile-members.html new file mode 100644 index 00000000..aa8f6964 --- /dev/null +++ b/docs/html/structCraplog_1_1LogFile-members.html @@ -0,0 +1,96 @@ + + + + + + + +LogDoctor: Member List + + + + + + + + + +
    +
    + + + + + + + +
    +
    LogDoctor 2.00 +
    +
    Parse Apache2/Nginx/IIS logs and create statistics
    +
    +
    + + + + + + + + +
    +
    + + +
    +
    +
    +
    +
    +
    Loading...
    +
    Searching...
    +
    No Matches
    +
    +
    +
    +
    + + +
    +
    +
    Craplog::LogFile Member List
    +
    + + + + + diff --git a/docs/html/structCraplog_1_1LogFile.html b/docs/html/structCraplog_1_1LogFile.html new file mode 100644 index 00000000..43cd6399 --- /dev/null +++ b/docs/html/structCraplog_1_1LogFile.html @@ -0,0 +1,128 @@ + + + + + + + +LogDoctor: Craplog::LogFile Struct Reference + + + + + + + + + +
    +
    + + + + + + + +
    +
    LogDoctor 2.00 +
    +
    Parse Apache2/Nginx/IIS logs and create statistics
    +
    +
    + + + + + + + + +
    +
    + + +
    +
    +
    +
    +
    +
    Loading...
    +
    Searching...
    +
    No Matches
    +
    +
    +
    +
    + + +
    +
    + +
    Craplog::LogFile Struct Reference
    +
    +
    + +

    Structure which holds informations about a log file. + More...

    + +

    #include <craplog.h>

    + + + + + + + + + + + + + + + + + + + + +

    +Public Attributes

    +bool selected
     Wheter the file has been selected to be use or not.
     
    +bool used_already
     Wheter the file has been used already or not.
     
    +int size
     The size of the file.
     
    +QString name
     The name of the file, to be displayed in the list.
     
    +std::string hash
     The sha256 hash of the content.
     
    +std::string path
     The path of the file, including the file name.
     
    +

    Detailed Description

    +

    Structure which holds informations about a log file.

    +

    The documentation for this struct was generated from the following file:
      +
    • logdoctor/modules/craplog/craplog.h
    • +
    +
    + + + + diff --git a/docs/html/structCraplog_1_1LogName-members.html b/docs/html/structCraplog_1_1LogName-members.html new file mode 100644 index 00000000..0a85de9d --- /dev/null +++ b/docs/html/structCraplog_1_1LogName-members.html @@ -0,0 +1,93 @@ + + + + + + + +LogDoctor: Member List + + + + + + + + + +
    +
    + + + + + + + +
    +
    LogDoctor 2.00 +
    +
    Parse Apache2/Nginx/IIS logs and create statistics
    +
    +
    + + + + + + + + +
    +
    + + +
    +
    +
    +
    +
    +
    Loading...
    +
    Searching...
    +
    No Matches
    +
    +
    +
    +
    + + +
    +
    +
    Craplog::LogName Member List
    +
    +
    + +

    This is the complete list of members for Craplog::LogName, including all inherited members.

    + + + + +
    containsCraplog::LogName
    endsCraplog::LogName
    startsCraplog::LogName
    + + + + diff --git a/docs/html/structCraplog_1_1LogName.html b/docs/html/structCraplog_1_1LogName.html new file mode 100644 index 00000000..8939187e --- /dev/null +++ b/docs/html/structCraplog_1_1LogName.html @@ -0,0 +1,115 @@ + + + + + + + +LogDoctor: Craplog::LogName Struct Reference + + + + + + + + + +
    +
    + + + + + + + +
    +
    LogDoctor 2.00 +
    +
    Parse Apache2/Nginx/IIS logs and create statistics
    +
    +
    + + + + + + + + +
    +
    + + +
    +
    +
    +
    +
    +
    Loading...
    +
    Searching...
    +
    No Matches
    +
    +
    +
    +
    + + +
    +
    + +
    Craplog::LogName Struct Reference
    +
    +
    + +

    Web Server specific file names criterions. + More...

    + + + + + + + + + + + +

    +Public Attributes

    +std::string starts
     What should be initial part of the name.
     
    +std::string contains
     What should be contained in the middle of the name.
     
    +std::string ends
     What should be final part of the name.
     
    +

    Detailed Description

    +

    Web Server specific file names criterions.

    +

    The rules to be used to decide whether a file name is valid or not

    See also
    isFileNameValid()
    +

    The documentation for this struct was generated from the following file:
      +
    • logdoctor/modules/craplog/craplog.h
    • +
    +
    + + + + diff --git a/docs/html/structFormatOps_1_1LogsFormat-members.html b/docs/html/structFormatOps_1_1LogsFormat-members.html new file mode 100644 index 00000000..344b0d6d --- /dev/null +++ b/docs/html/structFormatOps_1_1LogsFormat-members.html @@ -0,0 +1,96 @@ + + + + + + + +LogDoctor: Member List + + + + + + + + + +
    +
    + + + + + + + +
    +
    LogDoctor 2.00 +
    +
    Parse Apache2/Nginx/IIS logs and create statistics
    +
    +
    + + + + + + + + +
    +
    + + +
    +
    +
    +
    +
    +
    Loading...
    +
    Searching...
    +
    No Matches
    +
    +
    +
    +
    + + +
    +
    +
    FormatOps::LogsFormat Member List
    +
    + + + + + diff --git a/docs/html/structFormatOps_1_1LogsFormat.html b/docs/html/structFormatOps_1_1LogsFormat.html new file mode 100644 index 00000000..65f744ee --- /dev/null +++ b/docs/html/structFormatOps_1_1LogsFormat.html @@ -0,0 +1,128 @@ + + + + + + + +LogDoctor: FormatOps::LogsFormat Struct Reference + + + + + + + + + +
    +
    + + + + + + + +
    +
    LogDoctor 2.00 +
    +
    Parse Apache2/Nginx/IIS logs and create statistics
    +
    +
    + + + + + + + + +
    +
    + + +
    +
    +
    +
    +
    +
    Loading...
    +
    Searching...
    +
    No Matches
    +
    +
    +
    +
    + + +
    +
    + +
    FormatOps::LogsFormat Struct Reference
    +
    +
    + +

    Structure which holds informations about a log format. + More...

    + +

    #include <formats.h>

    + + + + + + + + + + + + + + + + + + + + +

    +Public Attributes

    +std::string string
     The logs format string.
     
    +std::string initial
     The initial separator.
     
    +std::string final
     The final separator.
     
    +std::vector< std::string > separators
     The separators in the middle.
     
    +std::vector< std::string > fields
     The fields.
     
    +int new_lines
     The number of new lines.
     
    +

    Detailed Description

    +

    Structure which holds informations about a log format.

    +

    The documentation for this struct was generated from the following file:
      +
    • logdoctor/modules/craplog/modules/formats.h
    • +
    +
    + + + + diff --git a/docs/html/sync_off.png b/docs/html/sync_off.png new file mode 100644 index 00000000..3b443fc6 Binary files /dev/null and b/docs/html/sync_off.png differ diff --git a/docs/html/sync_on.png b/docs/html/sync_on.png new file mode 100644 index 00000000..e08320fb Binary files /dev/null and b/docs/html/sync_on.png differ diff --git a/docs/html/tab_a.png b/docs/html/tab_a.png new file mode 100644 index 00000000..3b725c41 Binary files /dev/null and b/docs/html/tab_a.png differ diff --git a/docs/html/tab_ad.png b/docs/html/tab_ad.png new file mode 100644 index 00000000..e34850ac Binary files /dev/null and b/docs/html/tab_ad.png differ diff --git a/docs/html/tab_b.png b/docs/html/tab_b.png new file mode 100644 index 00000000..e2b4a863 Binary files /dev/null and b/docs/html/tab_b.png differ diff --git a/docs/html/tab_bd.png b/docs/html/tab_bd.png new file mode 100644 index 00000000..91c25249 Binary files /dev/null and b/docs/html/tab_bd.png differ diff --git a/docs/html/tab_h.png b/docs/html/tab_h.png new file mode 100644 index 00000000..fd5cb705 Binary files /dev/null and b/docs/html/tab_h.png differ diff --git a/docs/html/tab_hd.png b/docs/html/tab_hd.png new file mode 100644 index 00000000..2489273d Binary files /dev/null and b/docs/html/tab_hd.png differ diff --git a/docs/html/tab_s.png b/docs/html/tab_s.png new file mode 100644 index 00000000..ab478c95 Binary files /dev/null and b/docs/html/tab_s.png differ diff --git a/docs/html/tab_sd.png b/docs/html/tab_sd.png new file mode 100644 index 00000000..757a565c Binary files /dev/null and b/docs/html/tab_sd.png differ diff --git a/docs/html/tabs.css b/docs/html/tabs.css new file mode 100644 index 00000000..71c8a470 --- /dev/null +++ b/docs/html/tabs.css @@ -0,0 +1 @@ +.sm{position:relative;z-index:9999}.sm,.sm ul,.sm li{display:block;list-style:none;margin:0;padding:0;line-height:normal;direction:ltr;text-align:left;-webkit-tap-highlight-color:rgba(0,0,0,0)}.sm-rtl,.sm-rtl ul,.sm-rtl li{direction:rtl;text-align:right}.sm>li>h1,.sm>li>h2,.sm>li>h3,.sm>li>h4,.sm>li>h5,.sm>li>h6{margin:0;padding:0}.sm ul{display:none}.sm li,.sm a{position:relative}.sm a{display:block}.sm a.disabled{cursor:not-allowed}.sm:after{content:"\00a0";display:block;height:0;font:0/0 serif;clear:both;visibility:hidden;overflow:hidden}.sm,.sm *,.sm *:before,.sm *:after{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.main-menu-btn{position:relative;display:inline-block;width:36px;height:36px;text-indent:36px;margin-left:8px;white-space:nowrap;overflow:hidden;cursor:pointer;-webkit-tap-highlight-color:rgba(0,0,0,0)}.main-menu-btn-icon,.main-menu-btn-icon:before,.main-menu-btn-icon:after{position:absolute;top:50%;left:2px;height:2px;width:24px;background:var(--nav-menu-button-color);-webkit-transition:all .25s;transition:all .25s}.main-menu-btn-icon:before{content:'';top:-7px;left:0}.main-menu-btn-icon:after{content:'';top:7px;left:0}#main-menu-state:checked ~ .main-menu-btn .main-menu-btn-icon{height:0}#main-menu-state:checked ~ .main-menu-btn .main-menu-btn-icon:before{top:0;-webkit-transform:rotate(-45deg);transform:rotate(-45deg)}#main-menu-state:checked ~ .main-menu-btn .main-menu-btn-icon:after{top:0;-webkit-transform:rotate(45deg);transform:rotate(45deg)}#main-menu-state{position:absolute;width:1px;height:1px;margin:-1px;border:0;padding:0;overflow:hidden;clip:rect(1px,1px,1px,1px)}#main-menu-state:not(:checked) ~ #main-menu{display:none}#main-menu-state:checked ~ #main-menu{display:block}@media(min-width:768px){.main-menu-btn{position:absolute;top:-99999px}#main-menu-state:not(:checked) ~ #main-menu{display:block}}.sm-dox{background-image:var(--nav-gradient-image)}.sm-dox a,.sm-dox a:focus,.sm-dox a:hover,.sm-dox a:active{padding:0 12px;padding-right:43px;font-family:var(--font-family-nav);font-size:13px;font-weight:bold;line-height:36px;text-decoration:none;text-shadow:var(--nav-text-normal-shadow);color:var(--nav-text-normal-color);outline:0}.sm-dox a:hover{background-image:var(--nav-gradient-active-image);background-repeat:repeat-x;color:var(--nav-text-hover-color);text-shadow:var(--nav-text-hover-shadow)}.sm-dox a.current{color:#d23600}.sm-dox a.disabled{color:#bbb}.sm-dox a span.sub-arrow{position:absolute;top:50%;margin-top:-14px;left:auto;right:3px;width:28px;height:28px;overflow:hidden;font:bold 12px/28px monospace !important;text-align:center;text-shadow:none;background:var(--nav-menu-toggle-color);-moz-border-radius:5px;-webkit-border-radius:5px;border-radius:5px}.sm-dox a span.sub-arrow:before{display:block;content:'+'}.sm-dox a.highlighted span.sub-arrow:before{display:block;content:'-'}.sm-dox>li:first-child>a,.sm-dox>li:first-child>:not(ul) a{-moz-border-radius:5px 5px 0 0;-webkit-border-radius:5px;border-radius:5px 5px 0 0}.sm-dox>li:last-child>a,.sm-dox>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul{-moz-border-radius:0 0 5px 5px;-webkit-border-radius:0;border-radius:0 0 5px 5px}.sm-dox>li:last-child>a.highlighted,.sm-dox>li:last-child>*:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>*:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a.highlighted{-moz-border-radius:0;-webkit-border-radius:0;border-radius:0}.sm-dox ul{background:var(--nav-menu-background-color)}.sm-dox ul a,.sm-dox ul a:focus,.sm-dox ul a:hover,.sm-dox ul a:active{font-size:12px;border-left:8px solid transparent;line-height:36px;text-shadow:none;background-color:var(--nav-menu-background-color);background-image:none}.sm-dox ul a:hover{background-image:var(--nav-gradient-active-image);background-repeat:repeat-x;color:var(--nav-text-hover-color);text-shadow:0 1px 1px black}.sm-dox ul ul a,.sm-dox ul ul a:hover,.sm-dox ul ul a:focus,.sm-dox ul ul a:active{border-left:16px solid transparent}.sm-dox ul ul ul a,.sm-dox ul ul ul a:hover,.sm-dox ul ul ul a:focus,.sm-dox ul ul ul a:active{border-left:24px solid transparent}.sm-dox ul ul ul ul a,.sm-dox ul ul ul ul a:hover,.sm-dox ul ul ul ul a:focus,.sm-dox ul ul ul ul a:active{border-left:32px solid transparent}.sm-dox ul ul ul ul ul a,.sm-dox ul ul ul ul ul a:hover,.sm-dox ul ul ul ul ul a:focus,.sm-dox ul ul ul ul ul a:active{border-left:40px solid transparent}@media(min-width:768px){.sm-dox ul{position:absolute;width:12em}.sm-dox li{float:left}.sm-dox.sm-rtl li{float:right}.sm-dox ul li,.sm-dox.sm-rtl ul li,.sm-dox.sm-vertical li{float:none}.sm-dox a{white-space:nowrap}.sm-dox ul a,.sm-dox.sm-vertical a{white-space:normal}.sm-dox .sm-nowrap>li>a,.sm-dox .sm-nowrap>li>:not(ul) a{white-space:nowrap}.sm-dox{padding:0 10px;background-image:var(--nav-gradient-image);line-height:36px}.sm-dox a span.sub-arrow{top:50%;margin-top:-2px;right:12px;width:0;height:0;border-width:4px;border-style:solid dashed dashed dashed;border-color:var(--nav-text-normal-color) transparent transparent transparent;background:transparent;-moz-border-radius:0;-webkit-border-radius:0;border-radius:0}.sm-dox a,.sm-dox a:focus,.sm-dox a:active,.sm-dox a:hover,.sm-dox a.highlighted{padding:0 12px;background-image:var(--nav-separator-image);background-repeat:no-repeat;background-position:right;-moz-border-radius:0 !important;-webkit-border-radius:0;border-radius:0 !important}.sm-dox a:hover{background-image:var(--nav-gradient-active-image);background-repeat:repeat-x;color:var(--nav-text-hover-color);text-shadow:var(--nav-text-hover-shadow)}.sm-dox a:hover span.sub-arrow{border-color:var(--nav-text-hover-color) transparent transparent transparent}.sm-dox a.has-submenu{padding-right:24px}.sm-dox li{border-top:0}.sm-dox>li>ul:before,.sm-dox>li>ul:after{content:'';position:absolute;top:-18px;left:30px;width:0;height:0;overflow:hidden;border-width:9px;border-style:dashed dashed solid dashed;border-color:transparent transparent #bbb transparent}.sm-dox>li>ul:after{top:-16px;left:31px;border-width:8px;border-color:transparent transparent var(--nav-menu-background-color) transparent}.sm-dox ul{border:1px solid #bbb;padding:5px 0;background:var(--nav-menu-background-color);-moz-border-radius:5px !important;-webkit-border-radius:5px;border-radius:5px !important;-moz-box-shadow:0 5px 9px rgba(0,0,0,0.2);-webkit-box-shadow:0 5px 9px rgba(0,0,0,0.2);box-shadow:0 5px 9px rgba(0,0,0,0.2)}.sm-dox ul a span.sub-arrow{right:8px;top:50%;margin-top:-5px;border-width:5px;border-color:transparent transparent transparent var(--nav-menu-foreground-color);border-style:dashed dashed dashed solid}.sm-dox ul a,.sm-dox ul a:hover,.sm-dox ul a:focus,.sm-dox ul a:active,.sm-dox ul a.highlighted{color:var(--nav-menu-foreground-color);background-image:none;border:0 !important;color:var(--nav-menu-foreground-color);background-image:none}.sm-dox ul a:hover{background-image:var(--nav-gradient-active-image);background-repeat:repeat-x;color:var(--nav-text-hover-color);text-shadow:var(--nav-text-hover-shadow)}.sm-dox ul a:hover span.sub-arrow{border-color:transparent transparent transparent var(--nav-text-hover-color)}.sm-dox span.scroll-up,.sm-dox span.scroll-down{position:absolute;display:none;visibility:hidden;overflow:hidden;background:var(--nav-menu-background-color);height:36px}.sm-dox span.scroll-up:hover,.sm-dox span.scroll-down:hover{background:#eee}.sm-dox span.scroll-up:hover span.scroll-up-arrow,.sm-dox span.scroll-up:hover span.scroll-down-arrow{border-color:transparent transparent #d23600 transparent}.sm-dox span.scroll-down:hover span.scroll-down-arrow{border-color:#d23600 transparent transparent transparent}.sm-dox span.scroll-up-arrow,.sm-dox span.scroll-down-arrow{position:absolute;top:0;left:50%;margin-left:-6px;width:0;height:0;overflow:hidden;border-width:6px;border-style:dashed dashed solid dashed;border-color:transparent transparent var(--nav-menu-foreground-color) transparent}.sm-dox span.scroll-down-arrow{top:8px;border-style:solid dashed dashed dashed;border-color:var(--nav-menu-foreground-color) transparent transparent transparent}.sm-dox.sm-rtl a.has-submenu{padding-right:12px;padding-left:24px}.sm-dox.sm-rtl a span.sub-arrow{right:auto;left:12px}.sm-dox.sm-rtl.sm-vertical a.has-submenu{padding:10px 20px}.sm-dox.sm-rtl.sm-vertical a span.sub-arrow{right:auto;left:8px;border-style:dashed solid dashed dashed;border-color:transparent #555 transparent transparent}.sm-dox.sm-rtl>li>ul:before{left:auto;right:30px}.sm-dox.sm-rtl>li>ul:after{left:auto;right:31px}.sm-dox.sm-rtl ul a.has-submenu{padding:10px 20px !important}.sm-dox.sm-rtl ul a span.sub-arrow{right:auto;left:8px;border-style:dashed solid dashed dashed;border-color:transparent #555 transparent transparent}.sm-dox.sm-vertical{padding:10px 0;-moz-border-radius:5px;-webkit-border-radius:5px;border-radius:5px}.sm-dox.sm-vertical a{padding:10px 20px}.sm-dox.sm-vertical a:hover,.sm-dox.sm-vertical a:focus,.sm-dox.sm-vertical a:active,.sm-dox.sm-vertical a.highlighted{background:#fff}.sm-dox.sm-vertical a.disabled{background-image:var(--nav-gradient-image)}.sm-dox.sm-vertical a span.sub-arrow{right:8px;top:50%;margin-top:-5px;border-width:5px;border-style:dashed dashed dashed solid;border-color:transparent transparent transparent #555}.sm-dox.sm-vertical>li>ul:before,.sm-dox.sm-vertical>li>ul:after{display:none}.sm-dox.sm-vertical ul a{padding:10px 20px}.sm-dox.sm-vertical ul a:hover,.sm-dox.sm-vertical ul a:focus,.sm-dox.sm-vertical ul a:active,.sm-dox.sm-vertical ul a.highlighted{background:#eee}.sm-dox.sm-vertical ul a.disabled{background:var(--nav-menu-background-color)}} \ No newline at end of file diff --git a/installation_stuff/LogDoctor.desktop b/installation_stuff/LogDoctor.desktop new file mode 100644 index 00000000..39c3b780 --- /dev/null +++ b/installation_stuff/LogDoctor.desktop @@ -0,0 +1,10 @@ +[Desktop Entry] +Type=Application +Name=LogDoctor +GenericName=LogDoctor +Comment=Apache2/Nginx/IIS access logs analyzer to view dynamically generated statistics +Icon=/usr/share/LogDoctor/LogDoctor.svg +Exec=logdoctor +Actions= +Categories=Utility; +Keywords=logdoctor;apache2;nginx;iis;webservers;logs;analyzer;statistics; diff --git a/installation_stuff/LogDoctor.svg b/installation_stuff/LogDoctor.svg new file mode 100644 index 00000000..e03977a4 --- /dev/null +++ b/installation_stuff/LogDoctor.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/installation_stuff/logdocdata/help/en/apache_format.html b/installation_stuff/logdocdata/help/en/apache_format.html new file mode 100644 index 00000000..78cec791 --- /dev/null +++ b/installation_stuff/logdocdata/help/en/apache_format.html @@ -0,0 +1,253 @@ + + + + + LogDoctor - Help + + + + +
    +

    Apache2

    +
    +
    +
    +


    Access logs format string

    +
    +


    Configuration file

    +
    +

    The configuration file should be located at:


    + /etc/apache2/apache2.conf +
    +

    The line to configure access logs is the one starting with "LogFormat" followed by the list of fields codes.

    +
    +
    +
    +

    Common logs formats

    +
    +

    Most commonly used format strings are:

    +
    +
      +
    • Common log format (CLF)

    • + LogFormat "%h %l %u %t \"%r\" %>s %O" common
      +
      +
    • Combined log format (NCSA standard)

    • + LogFormat "%h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-agent}i\"" combined +
    +
    +
    +
    +

    Suggested logs formats

    +
    +

    A suggested format string, to allow using the complete set of functionalities of LogDoctor, is:


    + LogFormat "%{%F %T}t %H %m %U %q %>s %I %O %D \"%{Referer}i\" \"%{Cookie}i\" \"%{User-agent}i\" %{c}h" combined +
    +

    The string above should be preferred, but alternatives can be used as well, like:


    + LogFormat "%{sec}t \"%r\" %q %<s %I %O %D \"%{Referer}i\" \"%{Cookie}i\" \"%{User-agent}i\" %h" combined +
    +
    +
    +

    Note on custom format strings

    +
    +

    If you're using your own custom string, please keep in mind that parsing is not magic. When you define your own string, think about which characters can be there in a field and use separators accordingly to not conflict with the field itself.
    + As an example: an URI (%U) can't contain whitespaces, so it is safe to use a space to separe this field by the previous and next one. Instead, the User-Agent (*%{User-agent}i*) may contain spaces, as well as parenthesis, brackets, dashes, etc, so it's better to pick an appropriate separator (double-quotes are a good choice, since they get escaped while logging).

    +
    +
    +
    +

    Note on control-characters

    +
    +

    Although Apache2 does support some control-characters (aka escape sequences), it is reccomended to not use them inside format strings.
    + In particular, the carriage return will most-likely overwrite previous fields data, making it very difficult to understand where the current field ends (specially for fields like URIs, queries, user-agents, etc) and nearly impossible to retrieve the overwritten data, which will lead in having a wasted database, un-realistic statistics and/or crashes during execution.
    + About the new line character, it has no sense to use it, if not for testing purposes. The same is true for the horizontal tab, for which is better to use a simple whitespace instead.
    + The only control-characters supported by Apache2 are \n, \t and \r. Any other character will be ignored and treated as text.

    +
    +
    +
    +
    +
    +
    +


    Access logs format fields

    +
    +


    Fields considered by LogDoctor

    +
    +

    Only the following fields will be considered, meaning that only these fields' data will be stored and used for the statistics.

    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    CodeInformations
    %%The percent sign character, will result in a single percent sign and treated as normal text (from both Apache and LogDoctor).
    %tTime the request was received, in the format [DD/Mon/YYYY:hh:mm:ss ±TZ]. The last number (TZ) indicates the timezone offset from GMT.
    %{FORMAT}tTime the request was received, in the form given by FORMAT, which should be in an extended strftime format.
    + The following format tokens are supported (by LogDoctor, any other than the following will be discarded, even if valid): +
    + + + + + + + + + + + + + + + + + + + + + + + + +
    FormatDescription
    sectime since epoch, in seconds
    msectime since epoch, in milliseconds
    usectime since epoch, in microseconds
    %bmonth name, abbreviated (same as %h)
    %Bmonth name
    %cdate and time representation
    %dday number, zero padded
    %Ddate, in the form of MM/DD/YY
    %eday number, space padded
    %Fdate, in the form of YYYY/MM/DD
    %hmonth name, abbreviated (same as %b)
    %Hhour, in 24h format, zero padded
    %mmonth number, zero padded
    %Mminute
    %rtime if the day, in 12h format, in the form of HH:MM:SS AM/PM
    %Rtime of the day, in HH:MM format
    %Ssecond
    %TISO 8601 time, in the form of HH:MM:SS
    %xdate representation
    %Xtime representation
    %yyear, last two digits (YY)
    %Yyear
    +
    +
    + Note: time formats sec, msec and usec can't be mixed together or with other formats. +
    %rFirst line of request, equivalent to: %m %U?%q %H.
    %HThe request protocol (HTTP/v, HTTPS/v).
    %mThe request method (GET, POST, HEAD, ...).
    %UThe URI path requested, not including any query string.
    %qQuery string (if any).
    %sHTTP Status code at the beginning of the request (exclude redirections statuses).
    %>sFinal HTTP Status code (in case requests have been internally redirected).
    %IBytes received, including request and headers (you need to enable mod_logio to use this).
    %OBytes sent, including headers (you need to enable mod_logio to use this).
    %TThe time taken to serve the request, in seconds.
    %{UNIT}TThe time taken to serve the request, in a time unit given by UNIT (only available in 2.4.13 and later).
    + Valid units are: +
    + + + + + +
    UnitDescription
    sseconds
    msmilliseconds
    usmicroseconds
    +
    %DThe time taken to serve the request, in milliseconds.
    %hIP Address of the client (remote hostname).
    %{c}hLike %h, but always reports on the hostname of the underlying TCP connection and not any modifications to the remote hostname by modules like mod_remoteip.
    %{VARNAME}iThe contents of VARNAME: header line(s) in the request sent to the server.
    + Supported varnames (by LogDoctor) are: +
    + + + + + +
    VarNameDescription
    Cookiecookie of the request
    Refererreferrer host
    User-agentweb-browser or bot identification string
    +
    +
    +
    +
    +

    Fields discarded by LogDoctor

    +
    +

    Any field than the ones above won't be considered by LogDoctor.
    + When generating a log sample, these fields will appear as 'DISCARDED'.
    + If you aint using logs for any other purpose, please remove unnecessary fields to make the process faster and reduce the possibility of errors.

    +
    +
    +
    +
    +
    +

    References

    +
    + +
    +
    +
    + + diff --git a/installation_stuff/logdocdata/help/en/iis_format.html b/installation_stuff/logdocdata/help/en/iis_format.html new file mode 100644 index 00000000..9e9a887a --- /dev/null +++ b/installation_stuff/logdocdata/help/en/iis_format.html @@ -0,0 +1,184 @@ + + + + + LogDoctor - Help + + + + +
    +

    IIS

    +
    +
    +
    +


    Access logs format string

    +
    +


    Configuration

    +
    +

    The configuration file should be located at:


    + C:\inetpub\logs\LogFiles\<YourSiteName> +
    +

    Access logs can be configured from the IIS Manager.
    + To open the IIS Manager, go to Control panelAdministrative toolsInternet Informations Service (IIS) Manager.
    + Once inside, click on Logging to edit the logs settings.

    +
    +
    +
    +

    Logs format modules

    +
    +

    Available logs formats (supported by LogDoctor) are:

    +
    +
      +
    • IIS
    • +

      Comma-separated values, can't be customized further. The file name is usually something like u_in<DATE>.log

      +
      +
    • NCSA
    • +

      Whitespace-separated values, can't be customized further. The file name is usually something like u_nc<DATE>.log

      +
      +
    • W3C
    • +

      Whitespace-separated values, can be customized by selecting which fields to log. The file name is usually something like u_ex<DATE>.log

      +
    +
    +
    +
    +

    Suggested logs format

    +
    +

    The suggested logs module is the W3C format, which will allow using the complete set of functionalities of LogDoctor.

    +

    The suggested fields to use are the following:


    + date, time, cs-method, cs-uri-stem, cs-uri-query, c-ip, cs-version, cs(User-Agent), cs(Cookie), cs(Referer), sc-status, sc-bytes, cs-bytes, time-taken +
    +
    +
    +

    Logs format strings

    +
    +

    Both the IIS and NCSA modules are standard, and thus LogDoctor doesn't need the format string to be specified.
    + The W3C module can be customized and so a format string must be specified. It can be found insed any log file created using this format module, searching the line starting with #Fields:.

    +
    +
    +
    +
    +
    +
    +


    W3C logs format fields

    +
    +


    Fields considered by LogDoctor

    +
    +

    Only the following fields will be considered, meaning that only these fields' data will be stored and used for the statistics.

    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    CodeInformations
    dateThe date on which the activity occurred (UTC).
    timeThe time at which the activity occurred (UTC).
    cs-versionThe request protocol (HTTP/v, HTTPS/v).
    cs-methodThe request method (GET, POST, HEAD, ...).
    cs-uri-stemThe URI path requested, not including any query string.
    cs-uri-queryQuery string (if any).
    sc-statusHTTP status code.
    cs-bytesThe number of bytes received and processed by the server.
    sc-bytesThe number of bytes sent back by the server.
    time-takenTime taken to serve the request, in milliseconds
    cs(Referer)The site which provided a link to the current site.
    cs(Cookie)The content of the cookie sent or received (if any).
    cs(User-Agent)Web-browser or bot identification string
    c-ipThe IP address of the client that made the request.
    +
    +
    +
    +

    Fields discarded by LogDoctor

    +
    +

    Any field than the ones above won't be considered by LogDoctor.
    + When generating a log sample, these fields will appear as 'DISCARDED'.
    + If you aint using logs for any other purpose, please remove unnecessary fields to make the process faster and reduce the possibility of errors.

    +
    +
    +
    +
    +

    References

    +
    + +
    +
    +
    + + diff --git a/installation_stuff/logdocdata/help/en/nginx_format.html b/installation_stuff/logdocdata/help/en/nginx_format.html new file mode 100644 index 00000000..61da06b2 --- /dev/null +++ b/installation_stuff/logdocdata/help/en/nginx_format.html @@ -0,0 +1,193 @@ + + + + + LogDoctor - Help + + + + +
    +

    Nginx

    +
    +
    +
    +


    Access logs format string

    +
    +


    Configuration file

    +
    +

    The configuration file should be located at:


    + /usr/local/etc/nginx/nginx.conf +
    +

    The line to configure access logs is the one starting with "log_format main" followed by the list of fields codes.

    +
    +
    +
    +

    Default logs formats

    +
    +

    The default logs format string is:

    +
    + log_format main '$remote_addr - $remote_user [$time_local] "$request" $status $bytes_sent "$http_referer" "$http_user_agent"' +
    +
    +
    +

    Suggested logs format

    +
    +

    The suggested format string, to allow using the most of the functionalities of LogDoctor, is:


    + log_format main '$time_iso8601 "$request" $status $request_length $bytes_sent $request_time "$http_referer" "$http_user_agent" $remote_addr' +
    +
    +
    +

    Note the format strings

    +
    +

    When copy-pasting the format string, please remove any identation (if present) and just paste the resulting format string only.

    +
    +
    +
    +

    Note on control-characters

    +
    +

    Although Nginx does support some control-characters (aka escape sequences), it is reccomended to not use them inside format strings.
    + In particular, the carriage return will most-likely overwrite previous fields data, making it very difficult to understand where the current field ends (specially for fields like URIs, queries, user-agents, etc) and nearly impossible to retrieve the overwritten data, which will lead in having a wasted database, un-realistic statistics and/or crashes during execution.
    + About the new line character, it has no sense to use it, if not for testing purposes. The same is true for the horizontal tab, for which is better to use a simple whitespace instead.
    + The only control-characters supported by Nginx are \n, \t and \r. Any other character will be ignored and treated as text.

    +
    +
    +
    +
    +
    +
    +


    Access logs format fields

    +
    +


    Fields considered by LogDoctor

    +
    +

    Only the following fields will be considered, meaning that only these fields' data will be stored and used for the statistics.

    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    CodeInformations
    $time_localDate and time in CLF (NCSA) format.
    $time_iso8601Date and time in ISO 8601 format.
    $msecTime since epoch (in seconds, with a milliseconds resolution) at the time of the log write.
    $requestFirst line of request, equivalent to: $request_method $request_uri $server_protocol.
    $server_protocolThe request protocol (HTTP/v, HTTPS/v).
    $request_methodThe request method (GET, POST, HEAD, ...).
    $request_uriThe requested URI, including the query string (if any).
    $uriThe URI path requested, not including the query string.
    $query_stringQuery string (if any).
    $statusHTTP status code.
    $request_lengthNumber of bytes received (including request line, header, and request body).
    $bytes_sentThe number of bytes sent to a client.
    $request_timeRequest processing time in seconds with a milliseconds resolution: time elapsed between the first bytes were read from the client and the log write after the last bytes were sent to the client.
    $http_refererReferrer hostname.
    $cookie_NAMECookie of the request having the given NAME.
    $http_user_agentWeb-browser or Bot identification string.
    $remote_addrIP Address of the visitor (client).
    $realip_remote_addrOriginal client IP address.
    +
    +
    +
    +

    Fields discarded by LogDoctor

    +
    +

    Any field than the ones above won't be considered by LogDoctor.
    + When generating a log sample, these fields will appear as 'DISCARDED'.
    + If you aint using logs for any other purpose, please remove unnecessary fields to make the process faster and reduce the possibility of errors.

    +
    +
    +
    +
    +

    References

    +
    + +
    +
    +
    + + diff --git a/installation_stuff/logdocdata/licenses/3270_LICENSE.md b/installation_stuff/logdocdata/licenses/3270_LICENSE.md new file mode 100644 index 00000000..3ca71cba --- /dev/null +++ b/installation_stuff/logdocdata/licenses/3270_LICENSE.md @@ -0,0 +1,49 @@ +Copyright (c) 2011-2017, Ricardo Banffy. +Copyright (c) 1993-2011, Paul Mattes. +Copyright (c) 2004-2005, Don Russell. +Copyright (c) 2004, Dick Altenbern. +Copyright (c) 1990, Jeff Sparkes. +Copyright (c) 1989, Georgia Tech Research Corporation (GTRC), Atlanta, GA 30332. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + * Neither the name of Ricardo Banffy, Paul Mattes, Don Russell, + Dick Altenbern, Jeff Sparkes, GTRC nor the names of their contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL RICARDO BANFFY, PAUL MATTES, DON RUSSELL, DICK ALTENBERN, JEFF +SPARKES OR GTRC BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT +OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +The Debian Logo glyph is based on the Debian Open Use Logo and is +Copyright (c) 1999 Software in the Public Interest, Inc., and it is +incorporated here under the terms of the Creative Commons +Attribution-ShareAlike 3.0 Unported License. The logo is released +under the terms of the GNU Lesser General Public License, version 3 or +any later version, or, at your option, of the Creative Commons +Attribution-ShareAlike 3.0 Unported License. + +Ubuntu, the Ubuntu logo and the Circle of Friends symbol are +registered trademarks of Canonical Ltd. + +The Fontforge SFD font description file is optionally licensed under +the SIL Open Font License v1.1 with no Reserved Font Name. This +license is available with a FAQ at http://scripts.sil.org/OFL. diff --git a/installation_stuff/logdocdata/licenses/LogDoctor_LICENSE.md b/installation_stuff/logdocdata/licenses/LogDoctor_LICENSE.md new file mode 100644 index 00000000..0ad25db4 --- /dev/null +++ b/installation_stuff/logdocdata/licenses/LogDoctor_LICENSE.md @@ -0,0 +1,661 @@ + 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 + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU 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 . + +Also add information on how to contact you by electronic and paper mail. + + If your software can interact with users remotely through a computer +network, you should also make sure that it provides a way for users to +get its source. For example, if your program is a web application, its +interface could display a "Source" link that leads users to an archive +of the code. There are many ways you could offer source, and different +solutions will be better for different programs; see section 13 for the +specific requirements. + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU AGPL, see +. diff --git a/installation_stuff/logdocdata/licenses/Metropolis_UNLICENSE.md b/installation_stuff/logdocdata/licenses/Metropolis_UNLICENSE.md new file mode 100644 index 00000000..68a49daa --- /dev/null +++ b/installation_stuff/logdocdata/licenses/Metropolis_UNLICENSE.md @@ -0,0 +1,24 @@ +This is free and unencumbered software released into the public domain. + +Anyone is free to copy, modify, publish, use, compile, sell, or +distribute this software, either in source code form or as a compiled +binary, for any purpose, commercial or non-commercial, and by any +means. + +In jurisdictions that recognize copyright laws, the author or authors +of this software dedicate any and all copyright interest in the +software to the public domain. We make this dedication for the benefit +of the public at large and to the detriment of our heirs and +successors. We intend this dedication to be an overt act of +relinquishment in perpetuity of all present and future rights to this +software under copyright law. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +For more information, please refer to diff --git a/installation_stuff/logdocdata/licenses/sha256_LICENSE.md b/installation_stuff/logdocdata/licenses/sha256_LICENSE.md new file mode 100644 index 00000000..9f47dce7 --- /dev/null +++ b/installation_stuff/logdocdata/licenses/sha256_LICENSE.md @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2021 Jérémy LAMBERT (SystemGlitch) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/installation_stuff/logdoctor.conf b/installation_stuff/logdoctor.conf new file mode 100644 index 00000000..17eb30b2 --- /dev/null +++ b/installation_stuff/logdoctor.conf @@ -0,0 +1,68 @@ +[UI] +Language=en +RememberGeometry=true +Geometry=0,0,800,600,true +WindowTheme=0 +ChartsTheme=0 +MainDialogLevel=1 +DefaultWebServer=11 +DatabaseDataPath= +DatabaseHashesPath= +DatabaseDoBackup=true +DatabaseBackupsNumber=3 + +[TextBrowser] +Font=0 +WideLines=true +ColorScheme=1 + +[Craplog] +CraplogDialogLevel=1 +HideUsedFiles=true +WarningSize=52428801 + +[Apache2] +ApacheLogsPath=/var/log/apache2 +ApacheLogsFormat=%h %l %u %t "%r" %>s %b "%{Referer}i" "%{User-agent}i" +ApacheWarnlistMethod=DELETE HEAD OPTIONS PUT PATCH +ApacheWarnlistMethodUsed=false +ApacheWarnlistURI=/robots.txt /../ /./ /.env /.htaccess /phpmyadmin /wp-admin /wp-content /wp-config.php /config.py /views.py /routes.py /stepu.cgi /cgi-bin +ApacheWarnlistURIUsed=true +ApacheWarnlistClient= +ApacheWarnlistClientUsed=false +ApacheWarnlistUserAgent= +ApacheWarnlistUserAgentUsed=false +ApacheBlacklistClient=::1 +ApacheBlacklistClientUsed=false + +[Nginx] +NginxLogsPath=/var/log/nginx +NginxLogsFormat=$remote_addr - $remote_user [$time_local] "$request" $status $bytes_sent "$http_referer" "$http_user_agent" +NginxWarnlistMethod=DELETE HEAD OPTIONS PUT PATCH +NginxWarnlistMethodUsed=false +NginxWarnlistURI=/robots.txt /../ /./ /.env /.htaccess /phpmyadmin /wp-admin /wp-content /wp-config.php /config.py /views.py /routes.py /stepu.cgi /cgi-bin +NginxWarnlistURIUsed=true +NginxWarnlistClient= +NginxWarnlistClientUsed=false +NginxWarnlistUserAgent= +NginxWarnlistUserAgentUsed=false +NginxBlacklistClient=::1 +NginxBlacklistClientUsed=false + +[IIS] +IisLogsPath=C:/inetpub/logs/LogFiles/ +IisLogsModule=0 +IisLogsFormat=date time s-ip cs-method cs-uri-stem cs-uri-query s-port cs-username c-ip cs(User-Agent) cs(Referer) sc-status sc-substatus sc-win32-status time-taken +IisWarnlistMethod=DELETE HEAD OPTIONS PUT PATCH +IisWarnlistMethodUsed=false +IisWarnlistURI=/robots.txt /../ /./ /.env /.htaccess /phpmyadmin /wp-admin /wp-content /wp-config.php /config.py /views.py /routes.py /stepu.cgi /cgi-bin +IisWarnlistURIUsed=true +IisWarnlistClient= +IisWarnlistClientUsed=false +IisWarnlistUserAgent= +IisWarnlistUserAgentUsed=false +IisBlacklistClient=::1 +IisBlacklistClientUsed=false + +[Crapview] +CrapviewDialogLevel=1 diff --git a/installation_stuff/osx_bundle/Info.plist b/installation_stuff/osx_bundle/Info.plist new file mode 100644 index 00000000..ea3aa3cd --- /dev/null +++ b/installation_stuff/osx_bundle/Info.plist @@ -0,0 +1,30 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + LogDoctor + CFBundleDisplayName + LogDoctor + CFBundleIdentifier + com.logdoctor.LogDoctor + CFBundleShortVersionString + 2.01 + CFBundleVersion + 2.01 + CFBundleExecutable + LogDoctor + CFBundleIconFile + LogDoctor + CFBundlePackageType + APPL + LSApplicationCategoryType + public.app-category.utilities + CSResourcesFileMapped + + + diff --git a/installation_stuff/osx_bundle/Resources/LogDoctor.icns b/installation_stuff/osx_bundle/Resources/LogDoctor.icns new file mode 100644 index 00000000..6675e385 Binary files /dev/null and b/installation_stuff/osx_bundle/Resources/LogDoctor.icns differ diff --git a/installation_stuff/osx_bundle/bin/LogDoctor_uninstall b/installation_stuff/osx_bundle/bin/LogDoctor_uninstall new file mode 100644 index 00000000..e69de29b diff --git a/installation_stuff/osx_bundle/doc/licenses/LogDoctor/LogDoctor_LICENSE.md b/installation_stuff/osx_bundle/doc/licenses/LogDoctor/LogDoctor_LICENSE.md new file mode 100644 index 00000000..0ad25db4 --- /dev/null +++ b/installation_stuff/osx_bundle/doc/licenses/LogDoctor/LogDoctor_LICENSE.md @@ -0,0 +1,661 @@ + 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 + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU 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 . + +Also add information on how to contact you by electronic and paper mail. + + If your software can interact with users remotely through a computer +network, you should also make sure that it provides a way for users to +get its source. For example, if your program is a web application, its +interface could display a "Source" link that leads users to an archive +of the code. There are many ways you could offer source, and different +solutions will be better for different programs; see section 13 for the +specific requirements. + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU AGPL, see +. diff --git a/installation_stuff/osx_bundle/doc/licenses/fonts/3270_LICENSE.md b/installation_stuff/osx_bundle/doc/licenses/fonts/3270_LICENSE.md new file mode 100644 index 00000000..3ca71cba --- /dev/null +++ b/installation_stuff/osx_bundle/doc/licenses/fonts/3270_LICENSE.md @@ -0,0 +1,49 @@ +Copyright (c) 2011-2017, Ricardo Banffy. +Copyright (c) 1993-2011, Paul Mattes. +Copyright (c) 2004-2005, Don Russell. +Copyright (c) 2004, Dick Altenbern. +Copyright (c) 1990, Jeff Sparkes. +Copyright (c) 1989, Georgia Tech Research Corporation (GTRC), Atlanta, GA 30332. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + * Neither the name of Ricardo Banffy, Paul Mattes, Don Russell, + Dick Altenbern, Jeff Sparkes, GTRC nor the names of their contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL RICARDO BANFFY, PAUL MATTES, DON RUSSELL, DICK ALTENBERN, JEFF +SPARKES OR GTRC BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT +OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +The Debian Logo glyph is based on the Debian Open Use Logo and is +Copyright (c) 1999 Software in the Public Interest, Inc., and it is +incorporated here under the terms of the Creative Commons +Attribution-ShareAlike 3.0 Unported License. The logo is released +under the terms of the GNU Lesser General Public License, version 3 or +any later version, or, at your option, of the Creative Commons +Attribution-ShareAlike 3.0 Unported License. + +Ubuntu, the Ubuntu logo and the Circle of Friends symbol are +registered trademarks of Canonical Ltd. + +The Fontforge SFD font description file is optionally licensed under +the SIL Open Font License v1.1 with no Reserved Font Name. This +license is available with a FAQ at http://scripts.sil.org/OFL. diff --git a/installation_stuff/osx_bundle/doc/licenses/fonts/Metropolis_UNLICENSE.md b/installation_stuff/osx_bundle/doc/licenses/fonts/Metropolis_UNLICENSE.md new file mode 100644 index 00000000..68a49daa --- /dev/null +++ b/installation_stuff/osx_bundle/doc/licenses/fonts/Metropolis_UNLICENSE.md @@ -0,0 +1,24 @@ +This is free and unencumbered software released into the public domain. + +Anyone is free to copy, modify, publish, use, compile, sell, or +distribute this software, either in source code form or as a compiled +binary, for any purpose, commercial or non-commercial, and by any +means. + +In jurisdictions that recognize copyright laws, the author or authors +of this software dedicate any and all copyright interest in the +software to the public domain. We make this dedication for the benefit +of the public at large and to the detriment of our heirs and +successors. We intend this dedication to be an overt act of +relinquishment in perpetuity of all present and future rights to this +software under copyright law. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +For more information, please refer to diff --git a/installation_stuff/osx_bundle/doc/licenses/sha256/sha256_LICENSE.md b/installation_stuff/osx_bundle/doc/licenses/sha256/sha256_LICENSE.md new file mode 100644 index 00000000..9f47dce7 --- /dev/null +++ b/installation_stuff/osx_bundle/doc/licenses/sha256/sha256_LICENSE.md @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2021 Jérémy LAMBERT (SystemGlitch) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/logdoctor/CMakeLists.txt b/logdoctor/CMakeLists.txt new file mode 100644 index 00000000..387391c3 --- /dev/null +++ b/logdoctor/CMakeLists.txt @@ -0,0 +1,224 @@ +cmake_minimum_required(VERSION 3.5) + +project(LogDoctor VERSION 2.01 LANGUAGES CXX) + +set(CMAKE_INCLUDE_CURRENT_DIR ON) + +set(CMAKE_AUTOUIC ON) +set(CMAKE_AUTOMOC ON) +set(CMAKE_AUTORCC ON) + +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Widgets Charts LinguistTools Sql Network) +find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets Charts LinguistTools Sql Network) + + +set(TS_FILES + translations/LogDoctor_en.ts + translations/LogDoctor_es.ts + translations/LogDoctor_fr.ts + translations/LogDoctor_it.ts +) + + +set(PROJECT_SOURCES + main.cpp + mainwindow.ui + mainwindow.h + mainwindow.cpp + + utilities/checks.h + utilities/checks.cpp + utilities/colors.h + utilities/colors.cpp + utilities/gzip.h + utilities/gzip.cpp + utilities/io.h + utilities/io.cpp + utilities/rtf.h + utilities/rtf.cpp + utilities/strings.h + utilities/strings.cpp + utilities/stylesheets.h + utilities/stylesheets.cpp + utilities/vectors.h + utilities/vectors.cpp + + modules/shared.h + modules/shared.cpp + + modules/exceptions.h + modules/exceptions.cpp + modules/tb.h + modules/tb.cpp + + modules/dialogs.h + modules/dialogs.cpp + modules/dialogs/dialogmsg.ui + modules/dialogs/dialogmsg.h + modules/dialogs/dialogmsg.cpp + modules/dialogs/dialogbool.ui + modules/dialogs/dialogbool.h + modules/dialogs/dialogbool.cpp + modules/dialogs/dialogdia.ui + modules/dialogs/dialogdia.h + modules/dialogs/dialogdia.cpp + + modules/craplog/craplog.h + modules/craplog/craplog.cpp + modules/craplog/modules/datetime.h + modules/craplog/modules/datetime.cpp + modules/craplog/modules/donuts.h + modules/craplog/modules/donuts.cpp + modules/craplog/modules/formats.h + modules/craplog/modules/formats.cpp + modules/craplog/modules/hash.h + modules/craplog/modules/hash.cpp + modules/craplog/modules/logs.h + modules/craplog/modules/logs.cpp + modules/craplog/modules/sha256.h + modules/craplog/modules/sha256.cpp + modules/craplog/modules/store.h + modules/craplog/modules/store.cpp + + modules/crapview/crapview.h + modules/crapview/crapview.cpp + modules/crapview/modules/query.h + modules/crapview/modules/query.cpp + + modules/craphelp/craphelp.ui + modules/craphelp/craphelp.h + modules/craphelp/craphelp.cpp + + modules/crapup/crapup.ui + modules/crapup/crapup.h + modules/crapup/crapup.cpp + + modules/crapinfo/crapinfo.ui + modules/crapinfo/crapinfo.h + modules/crapinfo/crapinfo.cpp + + tools/crapnote/crapnote.ui + tools/crapnote/crapnote.h + tools/crapnote/crapnote.cpp + + games/games.h + games/games.cpp + + games/crisscross/crisscross.ui + games/crisscross/game.h + games/crisscross/game.cpp + + games/snake/snake.ui + games/snake/game.h + games/snake/game.cpp + games/snake/snake.h + games/snake/snake.cpp + games/snake/food.h + games/snake/food.cpp + + resources/resources.qrc + ${TS_FILES} +) + +if(${QT_VERSION_MAJOR} GREATER_EQUAL 6) + qt_add_executable(LogDoctor + MANUAL_FINALIZATION + ${PROJECT_SOURCES} + ) +# Define target properties for Android with Qt 6 as: +# set_property(TARGET LogDoctor APPEND PROPERTY QT_ANDROID_PACKAGE_SOURCE_DIR +# ${CMAKE_CURRENT_SOURCE_DIR}/android) +# For more information, see https://doc.qt.io/qt-6/qt-add-executable.html#target-creation + + qt_create_translation(QM_FILES ${CMAKE_SOURCE_DIR} ${TS_FILES}) +else() + if(ANDROID) + add_library(LogDoctor SHARED + ${PROJECT_SOURCES} + ) +# Define properties for Android with Qt 5 after find_package() calls as: +# set(ANDROID_PACKAGE_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/android") + else() + add_executable(LogDoctor + ${PROJECT_SOURCES} + ) + endif() + + qt5_create_translation(QM_FILES ${CMAKE_SOURCE_DIR} ${TS_FILES}) +endif() + +if(WIN32) + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-Bstatic -lgcc -lstdc++ -lwinpthread") + target_link_libraries(LogDoctor PRIVATE + -static Qt${QT_VERSION_MAJOR}::Widgets + -static Qt${QT_VERSION_MAJOR}::Charts + -static Qt${QT_VERSION_MAJOR}::Sql + -static Qt${QT_VERSION_MAJOR}::Network) +else() + target_link_libraries(LogDoctor PRIVATE + Qt${QT_VERSION_MAJOR}::Widgets + Qt${QT_VERSION_MAJOR}::Charts + Qt${QT_VERSION_MAJOR}::Sql + Qt${QT_VERSION_MAJOR}::Network) + # Include zlib + find_package(ZLIB REQUIRED) + include_directories(${ZLIB_INCLUDE_DIRS}) + target_link_libraries(LogDoctor PRIVATE ${ZLIB_LIBRARIES}) +endif() + + +if(APPLE) + set_target_properties(LogDoctor PROPERTIES + MACOSX_BUNDLE TRUE + #MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com + MACOSX_BUNDLE_BUNDLE_NAME ${PROJECT_NAME} + MACOSX_BUNDLE_ICON_FILE ${PROJECT_NAME} + MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} + MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} + ) +elseif(WIN32) + set_target_properties(LogDoctor PROPERTIES + WIN32_EXECUTABLE TRUE + ) +endif() + + +if(QT_VERSION_MAJOR EQUAL 6) + qt_finalize_executable(LogDoctor) +endif() + + +# Deb/Flatpak +if(UNIX AND NOT APPLE) + install(TARGETS + LogDoctor + RUNTIME DESTINATION /usr/bin + CONFIGURATIONS Release + PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ + RENAME logdoctor + ) + + install(FILES + ${CMAKE_SOURCE_DIR}/installation_stuff/LogDoctor.desktop + DESTINATION /usr/share/applications + ) + + install(DIRECTORY + DESTINATION /usr/share/LogDoctor + ) + install(FILES + ${CMAKE_SOURCE_DIR}/installation_stuff/LogDoctor.svg + DESTINATION /usr/share/LogDoctor + ) + install(DIRECTORY + ${CMAKE_SOURCE_DIR}/installation_stuff/logdocdata/help + DESTINATION /usr/share/LogDoctor + ) + install(DIRECTORY + ${CMAKE_SOURCE_DIR}/installation_stuff/logdocdata/licenses + DESTINATION /usr/share/LogDoctor + ) +endif() diff --git a/logdoctor/games/crisscross/crisscross.ui b/logdoctor/games/crisscross/crisscross.ui new file mode 100644 index 00000000..7d7f9eba --- /dev/null +++ b/logdoctor/games/crisscross/crisscross.ui @@ -0,0 +1,535 @@ + + + CrissCross + + + + 0 + 0 + 512 + 512 + + + + + 512 + 512 + + + + LogDoctor - CrissCross + + + + :/logo/logo/logdoctor.svg:/logo/logo/logdoctor.svg + + + + + + + 0 + 0 + + + + + 400 + 400 + + + + + 400 + 400 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 8 + + + + + + 0 + 0 + + + + + 120 + 120 + + + + + 120 + 120 + + + + PointingHandCursor + + + + 104 + 104 + + + + + + + + QFrame::Plain + + + Qt::Vertical + + + + + + + + 0 + 0 + + + + + 120 + 120 + + + + + 120 + 120 + + + + PointingHandCursor + + + + 104 + 104 + + + + + + + + QFrame::Plain + + + Qt::Vertical + + + + + + + + 0 + 0 + + + + + 120 + 120 + + + + + 120 + 120 + + + + PointingHandCursor + + + + 104 + 104 + + + + + + + + QFrame::Plain + + + Qt::Horizontal + + + + + + + QFrame::Plain + + + Qt::Horizontal + + + + + + + QFrame::Plain + + + Qt::Horizontal + + + + + + + + 0 + 0 + + + + + 120 + 120 + + + + + 120 + 120 + + + + PointingHandCursor + + + + 104 + 104 + + + + + + + + QFrame::Plain + + + Qt::Vertical + + + + + + + + 0 + 0 + + + + + 120 + 120 + + + + + 120 + 120 + + + + PointingHandCursor + + + + 104 + 104 + + + + + + + + QFrame::Plain + + + Qt::Vertical + + + + + + + + 0 + 0 + + + + + 120 + 120 + + + + + 120 + 120 + + + + PointingHandCursor + + + + 104 + 104 + + + + + + + + QFrame::Plain + + + Qt::Horizontal + + + + + + + QFrame::Plain + + + Qt::Horizontal + + + + + + + QFrame::Plain + + + Qt::Horizontal + + + + + + + + 0 + 0 + + + + + 120 + 120 + + + + + 120 + 120 + + + + PointingHandCursor + + + + 104 + 104 + + + + + + + + QFrame::Plain + + + Qt::Vertical + + + + + + + + 0 + 0 + + + + + 120 + 120 + + + + + 120 + 120 + + + + PointingHandCursor + + + + 104 + 104 + + + + + + + + QFrame::Plain + + + Qt::Vertical + + + + + + + + 0 + 0 + + + + + 120 + 120 + + + + + 120 + 120 + + + + PointingHandCursor + + + + 104 + 104 + + + + + + + + + + + Qt::Horizontal + + + QSizePolicy::MinimumExpanding + + + + 38 + 397 + + + + + + + + Qt::Horizontal + + + QSizePolicy::MinimumExpanding + + + + 4 + 16 + + + + + + + + Qt::Vertical + + + QSizePolicy::MinimumExpanding + + + + 16 + 4 + + + + + + + + Qt::Vertical + + + QSizePolicy::MinimumExpanding + + + + 16 + 4 + + + + + + + + + + + diff --git a/logdoctor/games/crisscross/game.cpp b/logdoctor/games/crisscross/game.cpp new file mode 100644 index 00000000..fa677d44 --- /dev/null +++ b/logdoctor/games/crisscross/game.cpp @@ -0,0 +1,352 @@ + +#include "game.h" +#include "ui_crisscross.h" + +#include "games/games.h" + +#include + + +CrissCross::CrissCross( const int& theme_id, QWidget* parent ) : + QWidget(parent), + ui(new Ui::CrissCross) +{ + this->ui->setupUi(this); + + QString stylesheet = ""; + GameSec::crisscrossStyleSheet( stylesheet, theme_id ); + this->setStyleSheet( stylesheet ); + + // verify that one player is human and the other is not + if ( !(p1_human^p2_human) ) { + throw("Players identities error: "+std::to_string(p1_human)+" - "+std::to_string(p2_human)); + } + + this->victory_sequence.reserve( 3 ); + + this->board_buttons[0] = this->ui->button_NW; + this->board_buttons[1] = this->ui->button_N; + this->board_buttons[2] = this->ui->button_NE; + this->board_buttons[3] = this->ui->button_W; + this->board_buttons[4] = this->ui->button_C; + this->board_buttons[5] = this->ui->button_E; + this->board_buttons[6] = this->ui->button_SW; + this->board_buttons[7] = this->ui->button_S; + this->board_buttons[8] = this->ui->button_SE; + + if ( ! p1_human ) { + // AI starts + this->AI_playTurn(); + } + +} + +CrissCross::~CrissCross() +{ + delete ui; +} + + +///////////////////// +//// BOARD TILES //// +void CrissCross::on_button_NW_clicked() +{ + if ( ! this->ui->button_NW->isFlat() ) { + this->board[0] = this->p_turn; + this->ui->button_NW->setIcon( this->icons[ this->p_turn-1 ] ); + this->ui->button_NW->setFlat( true ); + this->endTurn(); + } +} + +void CrissCross::on_button_N_clicked() +{ + if ( ! this->ui->button_N->isFlat() ) { + this->board[1] = this->p_turn; + this->ui->button_N->setIcon( this->icons[ this->p_turn-1 ] ); + this->ui->button_N->setFlat( true ); + this->endTurn(); + } +} + +void CrissCross::on_button_NE_clicked() +{ + if ( ! this->ui->button_NE->isFlat() ) { + this->board[2] = this->p_turn; + this->ui->button_NE->setIcon( this->icons[ this->p_turn-1 ] ); + this->ui->button_NE->setFlat( true ); + this->endTurn(); + } +} + +void CrissCross::on_button_W_clicked() +{ + if ( ! this->ui->button_W->isFlat() ) { + this->board[3] = this->p_turn; + this->ui->button_W->setIcon( this->icons[ this->p_turn-1 ] ); + this->ui->button_W->setFlat( true ); + this->endTurn(); + } +} + +void CrissCross::on_button_C_clicked() +{ + if ( ! this->ui->button_C->isFlat() ) { + this->board[4] = this->p_turn; + this->ui->button_C->setIcon( this->icons[ this->p_turn-1 ] ); + this->ui->button_C->setFlat( true ); + this->endTurn(); + } +} + +void CrissCross::on_button_E_clicked() +{ + if ( ! this->ui->button_E->isFlat() ) { + this->board[5] = this->p_turn; + this->ui->button_E->setIcon( this->icons[ this->p_turn-1 ] ); + this->ui->button_E->setFlat( true ); + this->endTurn(); + } +} + +void CrissCross::on_button_SW_clicked() +{ + if ( ! this->ui->button_SW->isFlat() ) { + this->board[6] = this->p_turn; + this->ui->button_SW->setIcon( this->icons[ this->p_turn-1 ] ); + this->ui->button_SW->setFlat( true ); + this->endTurn(); + } +} + +void CrissCross::on_button_S_clicked() +{ + if ( ! this->ui->button_S->isFlat() ) { + this->board[7] = this->p_turn; + this->ui->button_S->setIcon( this->icons[ this->p_turn-1 ] ); + this->ui->button_S->setFlat( true ); + this->endTurn(); + } +} + +void CrissCross::on_button_SE_clicked() +{ + if ( ! this->ui->button_SE->isFlat() ) { + this->board[8] = this->p_turn; + this->ui->button_SE->setIcon( this->icons[ this->p_turn-1 ] ); + this->ui->button_SE->setFlat( true ); + this->endTurn(); + } +} + + +////////////////////// +//// TURN RELATED //// +void CrissCross::endTurn() +{ + if ( this->checkVictory() ) { + // a player won! + this->victory(); + } else { + // nobody won yet + if ( this->gameDraw() ) { + // game is draw + this->draw(); + } else { + // change turn and keep playing + this->nextTurn(); + } + } +} + +void CrissCross::nextTurn() +{ + switch ( this->p_turn ) { + case 1: + this->p_turn += 1; + if ( ! this->p2_human ) { + this->AI_playTurn(); + } + break; + case 2: + this->p_turn -= 1; + if ( ! this->p1_human ) { + this->AI_playTurn(); + } + break; + default: + // wrong + throw("Wrong turn: "+std::to_string(this->p_turn)); + break; + } +} + + +const bool CrissCross::checkVictory() +{ + bool result = false; + unsigned int streak; + for ( const auto& sequence : this->sequences ) { + streak = 0; + for ( const auto& index : sequence ) { + if ( this->board[ index ] == this->p_turn ) { + streak ++; + this->victory_sequence.push_back( index ); + } else { + break; + } + } + if ( streak == 3 ) { + // victory + result = true; + break; + } else { + this->victory_sequence.clear(); + } + } + return result; +} + +void CrissCross::victory() +{ + // disable all buttons except the victory sequence ones + bool disable; + for ( unsigned int i=0; i<9; i++ ) { + disable = true; + for ( const auto& j : this->victory_sequence ) { + if ( i == j ) { + disable = false; + break; + } else if ( i < j ) { + break; + } + } + this->board_buttons[ i ]->setFlat( true ); + if ( disable ) { + this->board_buttons[ i ]->setEnabled( false ); + } + } + + // display a dialog + QString message; + if ( (this->p_turn == 1 && this->p1_human) + || (this->p_turn == 2 && this->p2_human) ) { + // user won + message = CrissCross::tr("You beated me!"); + } else { + // AI won + message = CrissCross::tr("This time you lost!"); + } + QMessageBox::about( + this, + CrissCross::tr("Victory"), + message ); +} + + +const bool CrissCross::gameDraw() +{ + bool result = false; + unsigned int empty_tiles = 9; + for ( const auto& tile : this->board ) { + if ( tile > 0 ) { + empty_tiles --; + } + } + if ( empty_tiles == 0 ) { + // no movement left + result = true; + } + return result; +} + +void CrissCross::draw() +{ + // disable all buttons + for ( const auto& button : this->board_buttons ) { + button->setEnabled( false ); + } + + // display a dialog + QMessageBox::about( + this, + CrissCross::tr("Draw"), + CrissCross::tr("Nice match") ); +} + + +//////////// +//// AI //// +void CrissCross::AI_playTurn() +{ + this->AI_updateWeights(); + emit this->board_buttons[ this->AI_makeChoice() ]->clicked(); +} + +void CrissCross::AI_updateWeights() +{ + // reset the weights + for ( int i=0; i<9; i++ ) { + this->board_weights[ i ] = 0; + } + // calculate the new weights + unsigned int win_streak, lose_streak; + std::vector empty_tiles; + for ( const auto& sequence : this->sequences ) { + // reset data + win_streak = lose_streak = 0; + empty_tiles.clear(); + // check the tiles in the sequence + for ( const auto& index : sequence ) { + if ( this->board[ index ] == this->p_turn ) { + win_streak ++; + } else if ( this->board[ index ] > 0 ) { + lose_streak ++; + } else { + empty_tiles.push_back( index ); + } + } + // set the new weight for the empty tiles + const unsigned int new_weight = (win_streak>=lose_streak) + ? (win_streak==2) ? win_streak+2 : win_streak+1 + : lose_streak+1; + for ( const auto& index : empty_tiles ) { + if ( new_weight > this->board_weights[ index ] ) { + this->board_weights[ index ] = new_weight; + } + } + } + +} + +const unsigned int CrissCross::AI_makeChoice() +{ + // get a list of the heaviest tiles + std::vector moves; + unsigned int max_weight = 0; + unsigned int index = 0; + for ( const auto& weight : this->board_weights ) { + if ( weight > max_weight ) { + // heavier weight found + max_weight = weight; + moves.clear(); + moves.push_back( index ); + } else if ( weight == max_weight ) { + // same weight + moves.push_back( index ); + }/* else { + // lighter weight + ; + }*/ + index ++; + } + // decide the movement (or better, randomly pick one) + unsigned int next_move; + if ( max_weight == 0 ) { + // first turn + next_move = rand() % 9; + } else { + next_move = moves[ rand() % moves.size() ]; + } + return next_move; +} diff --git a/logdoctor/games/crisscross/game.h b/logdoctor/games/crisscross/game.h new file mode 100644 index 00000000..54cc691c --- /dev/null +++ b/logdoctor/games/crisscross/game.h @@ -0,0 +1,134 @@ +#ifndef CRISSCROSS_H +#define CRISSCROSS_H + +#include +#include +#include + + +namespace Ui { + class CrissCross; +} + +//! CrissCross +/*! + Player vs AI criss-cross game +*/ +class CrissCross : public QWidget +{ + Q_OBJECT + +public: + CrissCross( const int& theme_id, QWidget* parent=nullptr ); + ~CrissCross(); + + +private slots: + void on_button_NW_clicked(); + + void on_button_N_clicked(); + + void on_button_NE_clicked(); + + void on_button_W_clicked(); + + void on_button_C_clicked(); + + void on_button_E_clicked(); + + void on_button_SW_clicked(); + + void on_button_S_clicked(); + + void on_button_SE_clicked(); + + +private: + Ui::CrissCross *ui; + + // player turn + unsigned int p_turn = 1; + + // players identity + const bool p1_human = rand() %2; + const bool p2_human = (p1_human) ? false : true; + + // victory related + std::vector victory_sequence; + + // game data + unsigned int board[9] = { + 0,0,0, + 0,0,0, + 0,0,0 + }; + + QPushButton* board_buttons[9]; + + const QIcon icons[2] = { + QIcon(":/games/games/crisscross/o.png"), + QIcon(":/games/games/crisscross/x.png") + }; + + const unsigned int sequences[8][3] = { + {0,1,2},{3,4,5},{6,7,8}, // horizontal + {0,3,6},{1,4,7},{2,5,8}, // vertical + {0,4,8},{2,4,6} // diagonal + }; + + // AI data + unsigned int board_weights[9] = { + 1,1,1, + 1,1,1, + 1,1,1 + }; + + + ////////////// + //// GAME //// + + //! Ends the current turn + void endTurn(); + + //! Switches to the next turn + void nextTurn(); + + //! Checks whether it's the human player turn or not + const bool isPlayerTurn(); + + + //! Checks whether somebody won or not + const bool checkVictory(); + + //! Checks whether the game is draw or not + const bool gameDraw(); + + //! Someone won, process the victory + void victory(); + + //! The match is over but nobody won, the game is draw + void draw(); + + + //////////// + //// AI //// + + //! Main function for the AI to play its turn + void AI_playTurn(); + + //! Updates the weights of the tiles + /*! + \see AI_playTurn(); + */ + void AI_updateWeights(); + + //! Makes the choice depending on the weights + /*! + \return The tile to select + \see AI_playTurn(); + */ + const unsigned int AI_makeChoice(); + +}; + +#endif // CRISSCROSS_H diff --git a/logdoctor/games/games.cpp b/logdoctor/games/games.cpp new file mode 100644 index 00000000..329d07be --- /dev/null +++ b/logdoctor/games/games.cpp @@ -0,0 +1,328 @@ + +#include "games.h" + +#include "modules/exceptions.h" + +#include + + +GameSec::GameSec() +{ + +} + + +void GameSec::crisscrossStyleSheet( QString& stylesheet, const int& theme_id ) +{ + std::unordered_map style; + switch ( theme_id ) { + case 0: + break; + case 1: + style = { + {"window_base", + "rgb( 32, 32, 32 )"}, + {"tiles_base_hover", + "rgb( 40, 40, 40 )"}, + {"tiles_border_hover", + "rgb( 64, 64, 64 )"}, + {"lines_base", + "rgb( 192, 192, 192 )"}, + {"lines_border", + "rgb( 16, 16, 16 )"} + }; + break; + case 2: + style = { + {"window_base", + "rgb( 255, 204, 143 )"}, + {"tiles_base_hover", + "rgb( 245, 172, 142 )"}, + {"tiles_border_hover", + "rgb( 255, 140, 141 )"}, + {"lines_base", + "rgb( 195, 80, 81 )"}, + {"lines_border", + "rgb( 255, 204, 143 )"} + }; + break; + case 3: + style = { + {"window_base", + "rgb( 14, 28, 0 )"}, + {"tiles_base_hover", + "rgb( 54, 78, 30 )"}, + {"tiles_border_hover", + "rgb( 94, 118, 70 )"}, + {"lines_base", + "rgb( 193, 175, 129 )"}, + {"lines_border", + "rgb( 14, 28, 0 )"} + }; + break; + case 4: + style = { + {"window_base", + "rgb( 170, 161, 137 )"}, + {"tiles_base_hover", + "rgb( 130, 121, 97 )"}, + {"tiles_border_hover", + "rgb( 140, 131, 107 )"}, + {"lines_base", + "rgb( 60, 51, 27 )"}, + {"lines_border", + "rgb( 170, 161, 137 )"} + }; + break; + default: + throw GenericException( "Unexpected WindowTheme ID: "+std::to_string(theme_id), true ); + break; + } + if ( theme_id != 0 ) { + stylesheet = + "QWidget#CrissCross {" + " background-color: "+style.at("window_base")+";" + "}" + "QPushButton#button_NE," + "QPushButton#button_N," + "QPushButton#button_NW," + "QPushButton#button_E," + "QPushButton#button_C," + "QPushButton#button_W," + "QPushButton#button_SE," + "QPushButton#button_S," + "QPushButton#button_SW {" + " border-radius: 4px;" + " border: 1px solid "+style.at("window_base")+";" + " background-color: "+style.at("window_base")+";" + "}" + "QPushButton#button_NE:hover," + "QPushButton#button_N:hover," + "QPushButton#button_NW:hover," + "QPushButton#button_E:hover," + "QPushButton#button_C:hover," + "QPushButton#button_W:hover," + "QPushButton#button_SE:hover," + "QPushButton#button_S:hover," + "QPushButton#button_SW:hover {" + " border-color: "+style.at("tiles_border_hover")+";" + " background-color: "+style.at("tiles_base_hover")+";" + "}" + "QPushButton#button_NE::flat," + "QPushButton#button_N::flat," + "QPushButton#button_NW::flat," + "QPushButton#button_E::flat," + "QPushButton#button_C::flat," + "QPushButton#button_W::flat," + "QPushButton#button_SE::flat," + "QPushButton#button_S::flat," + "QPushButton#button_SW::flat {" + " border-color: "+style.at("window_base")+";" + " background-color: "+style.at("window_base")+";" + "}" + "QFrame#line_1," + "QFrame#line_2," + "QFrame#line_3," + "QFrame#line_4," + "QFrame#line_5," + "QFrame#line_6," + "QFrame#line_7," + "QFrame#line_8," + "QFrame#line_9," + "QFrame#line_10," + "QFrame#line_11," + "QFrame#line_12 {" + " border: 1px solid "+style.at("lines_border")+";" + " background-color: "+style.at("lines_base")+";" + "}"; + } +} + + +void GameSec::snakeStyleSheet( QString& stylesheet, const int& theme_id ) +{ + std::unordered_map style; + switch ( theme_id ) { + case 0: + break; + case 1: + style = { + {"text", + "rgb( 248, 248, 248 )"}, + {"window_base_primary", + "rgb( 16, 16, 16 )"}, + {"window_base_secondary", + "rgb( 32, 32, 32 )"}, + {"window_border", + "rgb( 128, 128, 128 )"}, + {"gamemode_box_base", + "rgb( 64, 64, 64 )"}, + {"gamemode_box_base_selection", + "rgb( 96, 96, 96 )"}, + {"gamemode_box_border", + "rgb( 82, 82, 82 )"}, + {"play_button_base", + "rgb( 64, 64, 64 )"}, + {"play_button_base_hover", + "rgb( 96, 96, 96 )"}, + {"play_button_border", + "rgb( 82, 82, 82 )"}, + {"play_button_border_hover", + "rgb( 128, 128, 128 )"}, + {"score_frame_base", + "rgb( 64, 64, 64 )"}, + {"score_frame_border", + "rgb( 82, 82, 82 )"}, + {"score_text", + "rgb( 248, 248, 248 )"}, + {"score_base", + "rgb( 0, 0, 0 )"} + }; + break; + case 2: + style = { + {"text", + "rgb( 45, 0, 30 )"}, + {"window_base_primary", + "rgb( 255, 140, 141 )"}, + {"window_base_secondary", + "rgb( 255, 204, 143 )"}, + {"window_border", + "rgb( 195, 80, 81 )"}, + {"gamemode_box_base", + "rgb( 114, 235, 115 )"}, + {"gamemode_box_base_selection", + "rgb( 154, 255, 155 )"}, + {"gamemode_box_border", + "rgb( 245, 172, 142 )"}, + {"play_button_base", + "rgb( 114, 235, 115 )"}, + {"play_button_base_hover", + "rgb( 154, 255, 155 )"}, + {"play_button_border", + "rgb( 245, 172, 142 )"}, + {"play_button_border_hover", + "rgb( 195, 80, 81 )"}, + {"score_frame_base", + "rgb( 245, 172, 142 )"}, + {"score_frame_border", + "rgb( 195, 80, 81 )"}, + {"score_text", + "rgb( 45, 0, 30 )"}, + {"score_base", + "rgb( 255, 210, 221 )"} + }; + break; + case 3: + style = { + {"text", + "rgb( 220, 211, 187 )"}, + {"window_base_primary", + "rgb( 14, 28, 0 )"}, + {"window_base_secondary", + "rgb( 24, 48, 0 )"}, + {"window_border", + "rgb( 163, 145, 99 )"}, + {"gamemode_box_base", + "rgb( 94, 118, 70 )"}, + {"gamemode_box_base_selection", + "rgb( 124, 148, 100 )"}, + {"gamemode_box_border", + "rgb( 163, 145, 99 )"}, + {"play_button_base", + "rgb( 94, 118, 70 )"}, + {"play_button_base_hover", + "rgb( 124, 148, 100 )"}, + {"play_button_border", + "rgb( 163, 145, 99 )"}, + {"play_button_border_hover", + "rgb( 193, 175, 129 )"}, + {"score_frame_base", + "rgb( 54, 78, 30 )"}, + {"score_frame_border", + "rgb( 163, 145, 99 )"}, + {"score_text", + "rgb( 193, 175, 129 )"}, + {"score_base", + "rgb( 14, 28, 0 )"} + }; + break; + case 4: + style = { + {"text", + "rgb( 30, 21, 0 )"}, + {"window_base_primary", + "rgb( 170, 161, 137 )"}, + {"window_base_secondary", + "rgb( 230, 221, 197 )"}, + {"window_border", + "rgb( 80, 71, 47 )"}, + {"gamemode_box_base", + "rgb( 130, 121, 97 )"}, + {"gamemode_box_base_selection", + "rgb( 140, 131, 107 )"}, + {"gamemode_box_border", + "rgb( 90, 81, 57 )"}, + {"play_button_base", + "rgb( 130, 121, 97 )"}, + {"play_button_base_hover", + "rgb( 140, 131, 107 )"}, + {"play_button_border", + "rgb( 90, 81, 57 )"}, + {"play_button_border_hover", + "rgb( 80, 71, 47 )"}, + {"score_frame_base", + "rgb( 210, 201, 177 )"}, + {"score_frame_border", + "rgb( 170, 161, 137 )"}, + {"score_text", + "rgb( 30, 21, 0 )"}, + {"score_base", + "rgb( 230, 221, 197 )"} + }; + break; + default: + throw GenericException( "Unexpected WindowTheme ID: "+std::to_string(theme_id), true ); + break; + } + if ( theme_id != 0 ) { + stylesheet = + "QWidget#SnakeGame {" + " background-color: "+style.at("window_base_primary")+";" + "}" + "QWidget#stackedPage_GameMenu," + "QWidget#stackedPage_GameBoard {" + " border-radius: 4px;" + " border: 1px solid "+style.at("window_border")+";" + " background-color: "+style.at("window_base_secondary")+";" + "}" + "QComboBox {" + " color: "+style.at("text")+";" + " background-color: "+style.at("gamemode_box_base")+";" + " selection-background-color: "+style.at("gamemode_box_base_selection")+";" + "}" + "QComboBox QAbstractItemView {" + " border: 1px solid "+style.at("gamemode_box_border")+";" + " background-color: "+style.at("gamemode_box_base")+";" + "}" + "QPushButton#button_Play {" + " border-radius: 4px;" + " border: 1px solid "+style.at("play_button_border")+";" + " color: "+style.at("text")+";" + " background-color: "+style.at("play_button_base")+";" + "}" + "QPushButton#button_Play:hover {" + " border-color: "+style.at("play_button_border_hover")+";" + " background-color: "+style.at("play_button_base_hover")+";" + "}" + "QFrame#frame_Score {" + " border-radius: 4px;" + " border: 1px solid "+style.at("score_frame_border")+";" + " background-color: "+style.at("score_frame_base")+";" + "}" + "QLCDNumber#lcd_Score {" + " color: "+style.at("score_text")+";" + " background-color: "+style.at("score_base")+";" + "}"; + } +} diff --git a/logdoctor/games/games.h b/logdoctor/games/games.h new file mode 100644 index 00000000..c0d7981a --- /dev/null +++ b/logdoctor/games/games.h @@ -0,0 +1,20 @@ +#ifndef GAMES_H +#define GAMES_H + +#include + + +//! GameSec +/*! + Utilities for the games +*/ +class GameSec +{ +public: + GameSec(); + + static void crisscrossStyleSheet( QString& stylesheet, const int& theme_id ); + static void snakeStyleSheet( QString& stylesheet, const int& theme_id ); +}; + +#endif // GAMES_H diff --git a/logdoctor/games/snake/food.cpp b/logdoctor/games/snake/food.cpp new file mode 100644 index 00000000..f21ccfec --- /dev/null +++ b/logdoctor/games/snake/food.cpp @@ -0,0 +1,217 @@ + +#include "food.h" + + +Food::Food( const bool& can_move ) +{ + this->movable = can_move; + this->image = new QGraphicsPixmapItem( (can_move) ? this->img_rat : this->img_egg ); + this->x = 0; + this->y = 0; +} + + +const unsigned int& Food::X() +{ + return this->x; +} +const unsigned int& Food::Y() +{ + return this->y; +} + + +QGraphicsPixmapItem* Food::getImageItem() +{ + return this->image; +} + + +const bool Food::inTile( const unsigned int& x, const unsigned int& y ) +{ + if ( this->x == x && this->y == y ) { + return true; + } else { + return false; + } +} + + +void Food::update( const unsigned int& new_x, const unsigned int& new_y ) { + this->x = new_x; + this->y = new_y; + this->image->setOffset( 16+(new_x*32), 16+(new_y*32) ); +} + + +void Food::spawn( Snake& snake, Snake& snake_ ) +{ + // pick a new random position + unsigned int x, y; + while (true) { + x = rand() % 16; + y = rand() % 16; + // check it's actually inside the field + if ( x < 16 && y < 16 ) { + // check the tile is empty + if ( x != this->x && y != this->y ) { + if ( !(snake.inTile( x, y, false ) || snake_.inTile( x, y, false )) ) { + break; + } + } + } + } + + // update to new position + this->update( x, y ); + + // randomly rotate the image + int rand_ = rand()%4; + switch (rand_) { + case 1: + this->image->setPixmap( + this->image->pixmap().transformed( + QTransform().rotate( 90.0 ) ) ); + break; + case 2: + this->image->setPixmap( + this->image->pixmap().transformed( + QTransform().rotate( 180.0 ) ) ); + break; + case 3: + this->image->setPixmap( + this->image->pixmap().transformed( + QTransform().rotate( -90.0 ) ) ); + break; + default: + // do not rotate + break; + } +} + + +void Food::move( Snake& snake ) +{ + int move_up = 0, + move_down = 0, + move_left = 0, + move_right = 0; + const unsigned int + snake_x = snake.front().x, + snake_y = snake.front().y; + + + // check the field's limits + if ( this->y == 0 ) { + move_up -= 100; + } else if ( this->y == 15 ) { + move_down -= 100; + } + if ( this->x == 0 ) { + move_left -= 100; + } else if ( this->x == 15 ) { + move_right -= 100; + } + + // check the snake + if ( ! snake.inTile( this->x, this->y-1, false ) ) { + move_up += 100; + } else { + move_up -= 100; + } + if ( ! snake.inTile( this->x, this->y+1, false ) ) { + move_down += 100; + } else { + move_down -= 100; + } + if ( ! snake.inTile( this->x-1, this->y, false ) ) { + move_left += 100; + } else { + move_left -= 100; + } + if ( ! snake.inTile( this->x+1, this->y, false ) ) { + move_right += 100; + } else { + move_right -= 100; + } + + // check the snake position + if ( this->x == snake_x ) { + move_left += 30; + move_right += 30; + if ( this->y < snake_y ) { + move_up += 30; + } else if ( this->y > snake_y ) { + move_down += 30; + } + } else if ( this->x < snake_x ) { + move_left += 30; + if ( this->y < snake_y ) { + move_up += 30; + } else if ( this->y > snake_y ) { + move_down += 30; + } else if ( this->y == snake_y ) { + move_up += 30; + move_down += 30; + } + } else if ( this->x > snake_x ) { + move_right += 30; + if ( this->y < snake_y ) { + move_up += 30; + } else if ( this->y > snake_y ) { + move_down += 30; + } else if ( this->y == snake_y ) { + move_up += 30; + move_down += 30; + } + } + + // decide + int max = -1000; + Direction choice; + if ( move_up > max || (move_up == max && rand()%2) ) { + max = move_up; + choice = Direction::UP; + } + if ( move_down > max || (move_down == max && rand()%2) ) { + max = move_down; + choice = Direction::DOWN; + } + if ( move_left > max || (move_left == max && rand()%2) ) { + max = move_left; + choice = Direction::LEFT; + } + if ( move_right > max || (move_right == max && rand()%2) ) { + choice = Direction::RIGHT; + } + + // apply the move + switch ( choice ) { + case Direction::UP: + this->update( this->x, this->y-1 ); + this->image->setPixmap( + this->img_rat ); + break; + case Direction::DOWN: + this->update( this->x, this->y+1 ); + this->image->setPixmap( + this->img_rat.transformed( + QTransform().rotate( 180.0 ) ) ); + break; + case Direction::LEFT: + this->update( this->x-1, this->y ); + this->image->setPixmap( + this->img_rat.transformed( + QTransform().rotate( -90.0 ) ) ); + break; + case Direction::RIGHT: + this->update( this->x+1, this->y ); + this->image->setPixmap( + this->img_rat.transformed( + QTransform().rotate( 90.0 ) ) ); + break; + default: + // should be unreachable + throw("Unexpected choice direction: "+std::to_string(choice)); + } +} diff --git a/logdoctor/games/snake/food.h b/logdoctor/games/snake/food.h new file mode 100644 index 00000000..353127eb --- /dev/null +++ b/logdoctor/games/snake/food.h @@ -0,0 +1,53 @@ +#ifndef FOOD_H +#define FOOD_H + +#include "snake.h" + +#include + +class Food +{ +public: + Food( const bool& can_move=false ); + + //! Returns the position on the X-axis + const unsigned int& X(); + //! Returns the position on the Y-axis + const unsigned int& Y(); + + //!< Returns the image + QGraphicsPixmapItem* getImageItem(); + + //! Checks whether is there a part of the snake in the given position + const bool inTile( const unsigned int& x, const unsigned int& y ); + + //! Spawns the egg/rat in a new position + void spawn( Snake& snake, Snake& snake_ ); + + //! Moves the rat + void move( Snake& snake ); + + //! Updates the position and direction of the entity + void update( const unsigned int& new_x, const unsigned int& new_y ); + + +private: + + QPixmap img_egg = QPixmap(":/games/games/snake/egg.png"); + + QPixmap img_rat = QPixmap(":/games/games/snake/rat.png"); + + //!< Whether the food is a rat or an egg + bool movable; + + //!< The position on the X-axis + unsigned int x; + + //!< The position on the Y-axis + unsigned int y; + + //!< The image which graphically represents the food + QGraphicsPixmapItem* image; +}; + +#endif // FOOD_H diff --git a/logdoctor/games/snake/game.cpp b/logdoctor/games/snake/game.cpp new file mode 100644 index 00000000..4478b506 --- /dev/null +++ b/logdoctor/games/snake/game.cpp @@ -0,0 +1,417 @@ + +#include "game.h" +#include "ui_snake.h" + +#include "games/games.h" + +#include +#include + + +SnakeGame::SnakeGame( const int& theme_id, const QFont& term_font, QWidget* parent ) : + QWidget(parent), + ui(new Ui::SnakeGame) +{ + this->ui->setupUi(this); + + QString stylesheet = ""; + GameSec::snakeStyleSheet( stylesheet, theme_id ); + this->setStyleSheet( stylesheet ); + + QFont font = QFont( term_font ); + font.setPointSize( 64 ); + this->ui->button_Play->setFont( font ); + font.setPointSize( 12 ); + this->ui->box_GameMode->setFont( font ); + + // create the field + this->field_scene = new QGraphicsScene( this ); + this->field_scene->setSceneRect( 0,0, 544, 544 ); + this->field_scene->setBackgroundBrush( Qt::black ); + // put water limits + this->field_scene->addItem( new QGraphicsPixmapItem( this->img_water ) ); + // add the scene to the view + this->ui->view_Field->setScene( this->field_scene ); +} + +SnakeGame::~SnakeGame() +{ + delete this->ui; + delete this->field_scene; + delete this->game_loop; +} + +void SnakeGame::closeEvent( QCloseEvent* event ) +{ + this->game_loop->stop(); + this->playing = false; +} + + +void SnakeGame::keyPressEvent( QKeyEvent* event ) +{ + // store the key pressed if needed + if ( this->playing ) { + switch ( event->key() ) { + case Qt::Key_Up: + case Qt::Key_W: + if ( this->key_events.empty() ) { // leave me here + this->key_events.push( 0 ); + } else if ( this->key_events.back() != 0 ) { + this->key_events.push( 0 ); + } + break; + case Qt::Key_Down: + case Qt::Key_S: + if ( this->key_events.empty() ) { + this->key_events.push( 1 ); + } else if ( this->key_events.back() != 1 ) { + this->key_events.push( 1 ); + } + break; + case Qt::Key_Left: + case Qt::Key_A: + if ( this->key_events.empty() ) { + this->key_events.push( 2 ); + } else if ( this->key_events.back() != 2 ) { + this->key_events.push( 2 ); + } + break; + case Qt::Key_Right: + case Qt::Key_D: + if ( this->key_events.empty() ) { + this->key_events.push( 3 ); + } else if ( this->key_events.back() != 3 ) { + this->key_events.push( 3 ); + } + break; + } + } +} + + +////////////// +//// MENU //// +void SnakeGame::on_button_Play_clicked() +{ + // set-up the game + this->newSnake(); + bool food_movable = false; + switch ( this->ui->box_GameMode->currentIndex() ) { + case 0: + this->game_mode = GameMode::Classic; + break; + case 1: + this->game_mode = GameMode::Hunt; + food_movable = true; + break; + case 2: + this->game_mode = GameMode::Battle; + this->newSnake_(); + break; + default: + throw("Unexpected GameMode: "+std::to_string(this->ui->box_GameMode->currentIndex())); + break; + } + this->newFood( food_movable ); + + // switch to game board + this->ui->stackedWidget_GameDisplay->setCurrentIndex( 1 ); + // start playing + this->game_loop = new QTimer(this); + connect(this->game_loop, SIGNAL(timeout()), this, SLOT(processGameLogic())); + this->game_loop->start(175); + this->playing = true; +} + + +void SnakeGame::newSnake() +{ + // snake initial position + const unsigned int head_x = (rand()%4)+6; + const unsigned int head_y = (rand()%4)+6; + if ( head_x > 15 || head_y > 15 ) { + // should be unreachable + throw("Unexpected initial position: ("+std::to_string(head_x)+","+std::to_string(head_y)+")"); + } + + // snake initial direction + const int rand_d = rand()%4; + switch ( rand_d ) { + case 0: + this->snake.setDirection( Direction::UP ); + break; + case 1: + this->snake.setDirection( Direction::DOWN ); + break; + case 2: + this->snake.setDirection( Direction::LEFT ); + break; + case 3: + this->snake.setDirection( Direction::RIGHT ); + break; + default: + // should be unreachable + throw("Unexpected initial direction: "+std::to_string(rand_d)); + } + this->key_events.push( rand_d ); + + // build the body with a head + this->snake.push_back( + { head_x, head_y, + this->snake.direction(), this->snake.direction(), + new QGraphicsPixmapItem( this->snake.getHeadImage() ) } + ); + this->field_scene->addItem( this->snake.front().image ); + this->snake.front().update( head_x, head_y, this->snake.direction() ); + // a body part + this->snake.willGrow(); + this->snake.update( this->field_scene, true, true ); + // and a tail + this->snake.willGrow(); + this->snake.update( this->field_scene, true, true ); +} + +void SnakeGame::newSnake_() +{ + // snake initial position + unsigned int head_x, head_y; + head_x = this->snake.front().x; + head_y = this->snake.front().y; + + // snake initial direction + const unsigned int rnd = (rand()%2); + this->snake_.setDirection( this->snake.direction() ); + switch ( this->snake_.direction() ) { + case Direction::UP: + case Direction::DOWN: + if ( rnd ) { + head_x ++; + } else { + head_x --; + } + break; + case Direction::LEFT: + case Direction::RIGHT: + if ( rnd ) { + head_y ++; + } else { + head_y --; + } + break; + default: + // should be unreachable + throw("Unexpected initial direction _: "+std::to_string(this->snake_.direction())); + } + + // build the body with a head + this->snake_.push_back( + { head_x, head_y, + this->snake_.direction(), this->snake_.direction(), + new QGraphicsPixmapItem( this->snake_.getHeadImage() ) } + ); + this->field_scene->addItem( this->snake_.front().image ); + this->snake_.front().update( head_x, head_y, this->snake_.direction() ); + // a body part + this->snake_.willGrow(); + this->snake_.update( this->field_scene, true, true ); + // and a tail + this->snake_.willGrow(); + this->snake_.update( this->field_scene, true, true ); +} + +void SnakeGame::newFood( const bool& movable ) +{ + // put some food on the field for it to eat + this->food = Food( movable ); + this->food.spawn( this->snake, this->snake_ ); + this->field_scene->addItem( this->food.getImageItem() ); +} + + +////////////// +//// GAME //// +void SnakeGame::processGameLogic() +{ + if ( game_over ) { + this->game_loop->stop(); + this->playing = false; + QMessageBox::about( + this, + SnakeGame::tr("Game Over"), + this->game_over_msg ); + } else { + + + if ( !this->key_events.empty() ) { + this->processNextKeyEvent(); + } + if ( this->game_mode == GameMode::Battle ) { + this->snake_.move( this->snake, this->food.X(), this->food.Y() ); + } + // check for a possible collision of the head + this->checkCollision( this->snake, this->snake_, false ); + if ( this->game_mode == GameMode::Battle ) { + this->checkCollision( this->snake_, this->snake, true ); + } + // check for game over + if ( ! this->game_over ) { + // update snake position + this->snake.update( this->field_scene ); + if ( this->game_mode == GameMode::Battle ) { + this->snake_.update( this->field_scene ); + } + if ( this->spawn_food ) { + // updae the score and spawn food in a new position + this->updateGameScore(); + this->food.spawn( this->snake, this->snake_ ); + this->spawn_food = false; + if ( this->game_mode == GameMode::Hunt ) { + this->moving_rate = 6 - ((this->snake.size()/13)+1); + this->moving_countdown = this->moving_rate; + } + } else if ( this->game_mode == GameMode::Hunt ) { + this->moving_countdown --; + if ( this->moving_countdown == 0 ) { + this->moving_countdown = this->moving_rate; + this->food.move( this->snake ); + } + } + } + } +} + + +void SnakeGame::processNextKeyEvent() +{ + // update direction if needed + switch ( this->key_events.front() ) { + case 0: // up + if ( this->snake.direction() != Direction::DOWN ) { + this->snake.setDirection( Direction::UP ); + } + break; + case 1: // down + if ( this->snake.direction() != Direction::UP ) { + this->snake.setDirection( Direction::DOWN ); + } + break; + case 2: // left + if ( this->snake.direction() != Direction::RIGHT ) { + this->snake.setDirection( Direction::LEFT ); + } + break; + case 3: // right + if ( this->snake.direction() != Direction::LEFT ) { + this->snake.setDirection( Direction::RIGHT ); + } + break; + } + this->key_events.pop(); +} + + +void SnakeGame::updateGameScore() +{ + this->game_score += this->score_step; + this->ui->lcd_Score->setDigitCount( std::to_string(this->game_score).size() ); + this->ui->lcd_Score->display( this->game_score ); +} + + +void SnakeGame::checkCollision( Snake& snake, Snake& adv_snake, const bool& is_adv ) +{ + unsigned int x, y, x_, y_; + + x = snake.front().x, + y = snake.front().y; + switch ( snake.direction() ) { + case Direction::UP: + y--; + break; + case Direction::DOWN: + y++; + break; + case Direction::LEFT: + x--; + break; + case Direction::RIGHT: + x++; + break; + default: + // should be unreachable + throw("Unexpected direction: "+std::to_string(snake.direction())); + } + + if ( adv_snake.size() > 0 ) { + x_ = adv_snake.front().x, + y_ = adv_snake.front().y; + switch ( adv_snake.direction() ) { + case Direction::UP: + y_--; + break; + case Direction::DOWN: + y_++; + break; + case Direction::LEFT: + x_--; + break; + case Direction::RIGHT: + x_++; + break; + default: + // should be unreachable + throw("Unexpected direction: "+std::to_string(adv_snake.direction())); + } + } else { + x_ = y_ = 16; + } + + // check the upcoming movement + if ( x > 15 || y > 15 ) { + // collision with the field limits + this->game_over = true; + this->game_over_msg = (is_adv) + ? SnakeGame::tr("Your adversary fell in the water!")+"\n\n"+SnakeGame::tr("YOU WON!") + : SnakeGame::tr("You fell in the water!")+"\n\n"+SnakeGame::tr("YOU LOST!"); + + } else if ( snake.inTile( x, y ) ) { + // collision with another part of the snake + this->game_over = true; + this->game_over_msg = (is_adv) + ? SnakeGame::tr("Your adversary ate itself!")+"\n\n"+SnakeGame::tr("YOU WON!") + : SnakeGame::tr("You ate yourself!")+"\n\n"+SnakeGame::tr("YOU LOST!"); + + } else if ( adv_snake.inTile( x, y ) ) { + // collision with another part of the snake + if ( x_ != x || y_ != y ) { + // not the head + this->game_over = true; + this->game_over_msg = (is_adv) + ? SnakeGame::tr("Your adversary ate you!")+"\n\n"+SnakeGame::tr("YOU WON!") + : SnakeGame::tr("You ate your adversary!")+"\n\n"+SnakeGame::tr("YOU LOST!"); + } else { + this->game_over = true; + this->game_over_msg = SnakeGame::tr("You ate each other!")+"\n\n"+SnakeGame::tr("MATCH IS DRAW!"); + } + + } else if ( this->food.inTile( x, y ) ) { + // will eat + if ( snake.size() < this->MAX_SNAKE_LENGTH ) { + // below max size, will grow + snake.willGrow(); + } else { + // max size reached, increase speed + const int interval = this->game_loop->interval(); + if ( interval > 50 ) { + this->game_loop->setInterval( interval - 5 ); + } + } + if ( is_adv ) { + this->score_step = -1; + } else { + this->score_step = 1; + } + this->spawn_food = true; + } +} diff --git a/logdoctor/games/snake/game.h b/logdoctor/games/snake/game.h new file mode 100644 index 00000000..2ef7af89 --- /dev/null +++ b/logdoctor/games/snake/game.h @@ -0,0 +1,140 @@ +#ifndef SNAKE_GAME_H +#define SNAKE_GAME_H + +#include "snake.h" +#include "food.h" + +#include + +#include +#include +#include + +#include + + +namespace Ui { + class SnakeGame; +} + +//! Snake +/*! + A reproduction of the timeless classic game +*/ +class SnakeGame : public QWidget +{ + Q_OBJECT + +public: + SnakeGame( const int& theme_id, const QFont& term_font, QWidget* parent=nullptr ); + ~SnakeGame(); + + +private slots: + + // Override + void closeEvent( QCloseEvent* event ) override; + + // Starts the game + void on_button_Play_clicked(); + + //! Processes the logic of the game + void processGameLogic(); + + +private: + Ui::SnakeGame *ui; + + //////////////////// + //// KEY EVENTS //// + + //! Stores the valid key events in a queue + /*! + Valid keys are UP/DOWN/LEFT/RIGHT arrows + and W/S/A/D letters + \see key_events, processNextKeyEvent() + */ + void keyPressEvent( QKeyEvent* event ) override; + + //! Stores the key events + std::queue key_events; + + //! Processes the key events in the queue + /*! + \see key_events, keyPressEvent() + */ + void processNextKeyEvent(); + + + ////////////////// + //// GRAPHICS //// + + QGraphicsScene* field_scene; + + QPixmap img_water = QPixmap(":/games/games/snake/water.png"); + + + ////////////// + //// GAME //// + + //! Enumerates the available game modes + enum GameMode { + Classic, //!< Classic snake game + Hunt, //!< Game variant in which the food moves too + Battle //!< Game variant in which you play against another snake + }; + + GameMode game_mode; + + bool playing = false; + + QTimer* game_loop = new QTimer(); + + bool game_over = false; + + QString game_over_msg; + + + /////////////// + //// SNAKE //// + + //! The maximum length of the snake + const unsigned int MAX_SNAKE_LENGTH = 64; + + //! The snake + Snake snake; + void newSnake(); + + // The adversary snake + Snake snake_ = Snake(true); + void newSnake_(); + + //! Checks if a snake will collide with another entity + void checkCollision( Snake& snake, Snake& adv_snake, const bool& is_adv ); + + + ////////////// + //// FOOD //// + + //! Instance of the egg/rat which will be eat by the snake + Food food; + void newFood( const bool& movable ); + + bool spawn_food = false; + + unsigned int moving_countdown = 5; + unsigned int moving_rate = 5; + + + /////////////// + //// SCORE //// + + int game_score = 0; + + //! Increases/Decreases the player's score by one + void updateGameScore(); + int score_step = 1; + +}; + +#endif // SNAKE_GAME_H diff --git a/logdoctor/games/snake/snake.cpp b/logdoctor/games/snake/snake.cpp new file mode 100644 index 00000000..d2d4e526 --- /dev/null +++ b/logdoctor/games/snake/snake.cpp @@ -0,0 +1,1141 @@ + +#include "snake.h" + + +Snake::Snake( const bool& is_adversary ) +{ + this->will_grow = false; + this->adversary = is_adversary; + if ( is_adversary ) { + for ( size_t x=0; x<16; x++ ) { + this->field_map.push_back( std::vector{} ); + std::vector& v = this->field_map.back(); + for ( size_t y=0; y<16; y++ ) { + v.push_back({ Entity::N, 0 }); + } + } + } +} + + +QPixmap& Snake::getHeadImage() +{ + if ( this->adversary ) { + return this->img_snakeHead_; + } else { + return this->img_snakeHead; + } +} + + +const bool Snake::inTile( const unsigned int& x, const unsigned int& y , const bool& avoid_tail ) +{ + bool result = false; + if ( this->size() > 0 ) { + size_t i = 0, + max = this->size()-1; + if ( !avoid_tail ) { + max ++; + } + for ( std::vector::const_iterator bp = this->begin(); bp != this->end(); ++bp ) { + if ( bp->x == x && bp->y == y ) { + result = true; + break; + } + i++; + if ( i >= max ) { + break; + } + } + } + return result; +} + + +void Snake::setDirection( const Direction new_direction ) +{ + this->head_direction = new_direction; +} +const Direction& Snake::direction() +{ + return this->head_direction; +} + +void Snake::willGrow() +{ + this->will_grow = true; +} +void Snake::grow( const bool& is_borning ) +{ + // build from the tail + const BodyPart& tail = this->back(); + unsigned int x = tail.x; + unsigned int y = tail.y; + const Direction d = tail.direction; + const Direction ld = tail.prev_direction; + if ( is_borning ) { + // one tile back + switch ( d ) { + case Direction::UP: + y ++; + break; + case Direction::DOWN: + y --; + break; + case Direction::LEFT: + x ++; + break; + case Direction::RIGHT: + x --; + break; + default: + // should be unreachable + throw("Unexpected direction: "+std::to_string(d)); + } + } + this->push_back( + { x, y, + d, ld, + new QGraphicsPixmapItem( (this->adversary) ? this->img_snakeTail_ : this->img_snakeTail ) } + ); + this->update( nullptr, true ); + this->back().update( x, y, d ); +} + + +void Snake::update( QGraphicsScene* field_scene, const bool& dry , const bool& is_borning ) +{ + // grow if planned + if ( this->will_grow ) { + this->will_grow = false; + this->grow( is_borning ); + field_scene->addItem( this->back().image ); + } + // anyway, update the whole body + size_t i = 0, + max_i = this->size()-1; + unsigned int new_x, prev_x, new_y, prev_y; + Direction new_direction, prev_direction, prev_body_d; + QPixmap& head_img = (this->adversary) ? this->img_snakeHead_ : this->img_snakeHead; + QPixmap& body_img = (this->adversary) ? this->img_snakeBody_ : this->img_snakeBody; + QPixmap& curve_img = (this->adversary) ? this->img_snakeCurve_ : this->img_snakeCurve; + QPixmap& tail_img = (this->adversary) ? this->img_snakeTail_ : this->img_snakeTail; + for ( std::vector::iterator bp = this->begin(); bp != this->end(); ++bp ) { + if ( ! dry ) { + // future position + if ( i == 0 ) { + // head doesn't follow any other part of the body + switch ( this->head_direction ) { + case Direction::UP: + new_y = bp->y - 1; + new_x = bp->x; + break; + case Direction::DOWN: + new_y = bp->y + 1; + new_x = bp->x; + break; + case Direction::LEFT: + new_x = bp->x - 1; + new_y = bp->y; + break; + case Direction::RIGHT: + new_x = bp->x + 1; + new_y = bp->y; + break; + default: + // should be unreachable + throw("Unexpected direction: "+std::to_string(this->head_direction)); + } + new_direction = this->head_direction; + } else { + // follow the previous part of the body + new_x = prev_x; + new_y = prev_y; + new_direction = prev_direction; + } + // store for the next part + prev_x = bp->x; + prev_y = bp->y; + prev_direction = bp->direction; + + // update the body-part position + bp->update( new_x, new_y, new_direction ); + } + + // finally set the image to be shown + switch ( bp->direction ) { + + case Direction::UP: + if ( i == 0 ) { + bp->image->setPixmap( + head_img ); + } else if ( i == max_i ) { + switch ( prev_body_d ) { + case Direction::UP: + bp->image->setPixmap( + tail_img ); + break; + case Direction::LEFT: + bp->image->setPixmap( + tail_img.transformed( + QTransform().rotate( -90.0 ) ) ); + break; + case Direction::RIGHT: + bp->image->setPixmap( + tail_img.transformed( + QTransform().rotate( 90.0 ) ) ); + break; + default: + // should be unreachable + throw("Unexpected direction: "+std::to_string(prev_body_d)); + } + } else { + switch ( prev_body_d ) { + case Direction::UP: + bp->image->setPixmap( + body_img ); + break; + case Direction::LEFT: + bp->image->setPixmap( + curve_img.transformed( + QTransform().rotate( 90.0 ) ) ); + break; + case Direction::RIGHT: + bp->image->setPixmap( + curve_img ); + break; + default: + // should be unreachable + throw("Unexpected direction: "+std::to_string(prev_body_d)); + } + } + break; + + case Direction::DOWN: + if ( i == 0 ) { + bp->image->setPixmap( + head_img.transformed( + QTransform().rotate( 180.0 ) ) ); + } else if ( i == max_i ) { + switch ( prev_body_d ) { + case Direction::DOWN: + bp->image->setPixmap( + tail_img.transformed( + QTransform().rotate( 180.0 ) ) ); + break; + case Direction::LEFT: + bp->image->setPixmap( + tail_img.transformed( + QTransform().rotate( -90.0 ) ) ); + break; + case Direction::RIGHT: + bp->image->setPixmap( + tail_img.transformed( + QTransform().rotate( 90.0 ) ) ); + break; + default: + // should be unreachable + throw("Unexpected direction: "+std::to_string(prev_body_d)); + } + } else { + switch ( prev_body_d ) { + case Direction::DOWN: + bp->image->setPixmap( + body_img ); + break; + case Direction::LEFT: + bp->image->setPixmap( + curve_img.transformed( + QTransform().rotate( 180.0 ) ) ); + break; + case Direction::RIGHT: + bp->image->setPixmap( + curve_img.transformed( + QTransform().rotate( -90.0 ) ) ); + break; + default: + // should be unreachable + throw("Unexpected direction: "+std::to_string(prev_body_d)); + } + } + break; + + case Direction::LEFT: + if ( i == 0 ) { + bp->image->setPixmap( + head_img.transformed( + QTransform().rotate( -90.0 ) ) ); + } else if ( i == max_i ) { + switch ( prev_body_d ) { + case Direction::LEFT: + bp->image->setPixmap( + tail_img.transformed( + QTransform().rotate( -90.0 ) ) ); + break; + case Direction::UP: + bp->image->setPixmap( + tail_img ); + break; + case Direction::DOWN: + bp->image->setPixmap( + tail_img.transformed( + QTransform().rotate( 180.0 ) ) ); + break; + default: + // should be unreachable + throw("Unexpected direction: "+std::to_string(prev_body_d)); + } + } else { + switch ( prev_body_d ) { + case Direction::LEFT: + bp->image->setPixmap( + body_img.transformed( + QTransform().rotate( -90.0 ) ) ); + break; + case Direction::UP: + bp->image->setPixmap( + curve_img.transformed( + QTransform().rotate( -90.0 ) ) ); + break; + case Direction::DOWN: + bp->image->setPixmap( + curve_img ); + break; + default: + // should be unreachable + throw("Unexpected direction: "+std::to_string(prev_body_d)); + } + } + break; + + case Direction::RIGHT: + if ( i == 0 ) { + bp->image->setPixmap( + head_img.transformed( + QTransform().rotate( 90.0 ) ) ); + } else if ( i == max_i ) { + switch ( prev_body_d ) { + case Direction::RIGHT: + bp->image->setPixmap( + tail_img.transformed( + QTransform().rotate( 90.0 ) ) ); + break; + case Direction::UP: + bp->image->setPixmap( + tail_img ); + break; + case Direction::DOWN: + bp->image->setPixmap( + tail_img.transformed( + QTransform().rotate( 180.0 ) ) ); + break; + default: + // should be unreachable + throw("Unexpected direction: "+std::to_string(prev_body_d)); + } + } else { + switch ( prev_body_d ) { + case Direction::RIGHT: + bp->image->setPixmap( + body_img.transformed( + QTransform().rotate( 90.0 ) ) ); + break; + case Direction::UP: + bp->image->setPixmap( + curve_img.transformed( + QTransform().rotate( 180.0 ) ) ); + break; + case Direction::DOWN: + bp->image->setPixmap( + curve_img.transformed( + QTransform().rotate( 90.0 ) ) ); + break; + default: + // should be unreachable + throw("Unexpected direction: "+std::to_string(prev_body_d)); + } + } + break; + + default: + // should be unreachable + throw("Unexpected direction: "+std::to_string(bp->direction)); + } + prev_body_d = bp->direction; + i++; + } +} + + +void Snake::move( Snake& adv_snake, const unsigned int& food_x, const unsigned int& food_y ) +{ + std::vector classes = { + Direction::UP, + Direction::DOWN, + Direction::LEFT, + Direction::RIGHT, + }; + + std::vector> dataset = { + {0,0,0,0,0,0,0}, + {0,0,0,0,0,0,0}, + {0,0,0,0,0,0,0}, + {0,0,0,0,0,0,0} + }; + + std::vector weights = { + -1.0, // blocked way + -0.4, // dead way + 0.003, // dead way steps + 0.1, // food way + 0.4, // aggressive way + 0.01, // same direction + -1.0 // opposite direction + }; + + this->updateFieldMap( adv_snake, food_x, food_y ); + + for ( int i=0; i<4; i++ ) { + this->collectData( dataset.at(i), classes.at(i), adv_snake, food_x, food_y ); + } + + // decide + this->head_direction = this->predictDirection( dataset, weights, classes ); +} + + +const Direction Snake::predictDirection( std::vector>& data, std::vector weights , std::vector classes ) +{ + float results[] = { 1.0, 1.0, 1.0, 1.0 }; + bool keep_current = false; + Direction class_label; + + // process data + for ( int i=0; i<4; i++ ) { + std::vector& d = data.at(i); + float& r = results[i]; + for ( int j=0; j<7; j++ ) { + r += d.at(j) * weights.at(j); + } + } + + // normalize results (not really a need here...) + float min=10.0, max=-10.0; + for ( const float& r : results ) { + if ( r < min ) { + min = r; + } + if ( r > max ) { + max = r; + } + } + if ( max != min ) { + for ( int i=0; i<4; i++ ) { + results[i] = (results[i]-min) / (max-min); + } + } else { + keep_current = true; + for ( int i=0; i<4; i++ ) { + results[i] = 0.0; + } + } + + // choose the best result + if ( keep_current ) { + class_label = this->head_direction; + } else { + max = 0; + for ( int i=0; i<4; i++ ) { + if ( results[i] > max ) { + class_label = classes.at(i); + max = results[i]; + } else if ( results[i] == max ) { + if ( rand()%2 ) { + class_label = classes.at(i); + } + } + } + } + + return class_label; +} + + +void Snake::collectData( std::vector& data, Direction& direction, Snake& adv_snake, const unsigned int& food_x, const unsigned int& food_y ) +{ + unsigned int + blocked_way = 0, + dead_way = 0, + dead_way_steps = 0, + food_way = 0, + aggressive_way = 0, + same_direction = 0, + opposite_direction = 0; + + const unsigned int head_x = this->front().x; + const unsigned int head_y = this->front().y; + + unsigned int x, y; + + // avoid choosing the opposite direction + switch ( direction ) { + + case Direction::UP: + x = head_x; + y = head_y-1; + if ( this->head_direction == Direction::UP ) { + same_direction = 1; + } else if ( this->head_direction == Direction::DOWN ) { + opposite_direction = 1; + } + if ( head_y == 0 ) { + blocked_way = 1; + } + break; + + case Direction::DOWN: + x = head_x; + y = head_y+1; + if ( this->head_direction == Direction::DOWN ) { + same_direction = 1; + } else if ( this->head_direction == Direction::UP ) { + opposite_direction = 1; + } + if ( head_y == 15 ) { + blocked_way = 1; + } + break; + + case Direction::LEFT: + x = head_x-1; + y = head_y; + if ( this->head_direction == Direction::LEFT ) { + same_direction = 1; + } else if ( this->head_direction == Direction::RIGHT ) { + opposite_direction = 1; + } + if ( head_x == 0 ) { + blocked_way = 1; + } + break; + + case Direction::RIGHT: + x = head_x+1; + y = head_y; + if ( this->head_direction == Direction::RIGHT ) { + same_direction = 1; + } else if ( this->head_direction == Direction::LEFT ) { + opposite_direction = 1; + } + if ( head_x == 15 ) { + blocked_way = 1; + } + break; + + default: + // should be unreachable + throw("Unexpected direction: "+std::to_string(this->head_direction)); + } + + + if ( !(blocked_way || opposite_direction) ) { + + // check snakes + switch ( this->field_map.at( x ).at( y ).entity ) { + case Entity::S: + case Entity::A: + blocked_way = 1; + break; + } + + if ( ! blocked_way ) { + + // check for deadhole + dead_way_steps = this->isDeadHole( x, y, direction ); + if ( dead_way_steps > 0 ) { + dead_way = 1; + } + + // check for aggressivity purposes + switch ( direction ) { + + case Direction::UP: + if ( adv_snake.direction() == Direction::LEFT && this->head_direction == Direction::RIGHT ) { + if ( this->inTileAdv( x+2, y+1 ) ) { + aggressive_way = 1; + } + } else if ( adv_snake.direction() == Direction::RIGHT && this->head_direction == Direction::LEFT ) { + if ( this->inTileAdv( x-2, y+1 ) ) { + aggressive_way = 1; + } + } else if ( adv_snake.direction() == this->head_direction ) { + if ( this->inTileAdv( x+2, y ) + || this->inTileAdv( x-2, y ) ) { + if ( !rand()%this->aggressiveness ) { + aggressive_way = 1; + } + } + } + break; + + case Direction::DOWN: + if ( adv_snake.direction() == Direction::LEFT && this->head_direction == Direction::RIGHT ) { + if ( this->inTileAdv( x+2, y-1 ) ) { + aggressive_way = 1; + } + } else if ( adv_snake.direction() == Direction::RIGHT && this->head_direction == Direction::LEFT ) { + if ( this->inTileAdv( x-2, y-1 ) ) { + aggressive_way = 1; + } + } else if ( adv_snake.direction() == this->head_direction ) { + if ( this->inTileAdv( x+2, y ) + || this->inTileAdv( x-2, y ) ) { + if ( !rand()%this->aggressiveness ) { + aggressive_way = 1; + } + } + } + break; + + case Direction::LEFT: + if ( adv_snake.direction() == Direction::UP && this->head_direction == Direction::DOWN ) { + if ( this->inTileAdv( x+1, y+2 ) ) { + aggressive_way = 1; + } + } else if ( adv_snake.direction() == Direction::DOWN && this->head_direction == Direction::UP ) { + if ( this->inTileAdv( x+1, y-2 ) ) { + aggressive_way = 1; + } + } else if ( adv_snake.direction() == this->head_direction ) { + if ( this->inTileAdv( x, y+2 ) + || this->inTileAdv( x, y-2 ) ) { + if ( !rand()%this->aggressiveness ) { + aggressive_way = 1; + } + } + } + break; + + case Direction::RIGHT: + if ( adv_snake.direction() == Direction::UP && this->head_direction == Direction::DOWN ) { + if ( this->inTileAdv( x-1, y+2 ) ) { + aggressive_way = 1; + } + } else if ( adv_snake.direction() == Direction::DOWN && this->head_direction == Direction::UP ) { + if ( this->inTileAdv( x-1, y-2 ) ) { + aggressive_way = 1; + } + } else if ( adv_snake.direction() == this->head_direction ) { + if ( this->inTileAdv( x, y+2 ) + || this->inTileAdv( x, y-2 ) ) { + if ( !rand()%this->aggressiveness ) { + aggressive_way = 1; + } + } + } + break; + + default: + // should be unreachable + throw("Unexpected direction: "+std::to_string(this->head_direction)); + } + } + } + + + if ( !(blocked_way || dead_way) ) { + + // check for food + switch ( direction ) { + + case Direction::UP: + if ( food_y < head_y ) { + if ( ! opposite_direction ) { + food_way = 1; + } + } else if ( food_y == head_y ) { + if ( food_x > head_x && this->head_direction == Direction::LEFT ) { + food_way = 1; + } else if ( food_x < head_x && this->head_direction == Direction::RIGHT ) { + food_way = 1; + } + } + break; + + case Direction::DOWN: + if ( food_y > head_y ) { + if ( ! opposite_direction ) { + food_way = 1; + } + } else if ( food_y == head_y ) { + if ( food_x > head_x && this->head_direction == Direction::LEFT ) { + food_way = 1; + } else if ( food_x < head_x && this->head_direction == Direction::RIGHT ) { + food_way = 1; + } + } + break; + + case Direction::LEFT: + if ( food_x < head_x ) { + if ( ! opposite_direction ) { + food_way = 1; + } + } else if ( food_x == head_x ) { + if ( food_y > head_y && this->head_direction == Direction::UP ) { + food_way = 1; + } else if ( food_y < head_y && this->head_direction == Direction::DOWN ) { + food_way = 1; + } + } + break; + + case Direction::RIGHT: + if ( food_x > head_x ) { + if ( ! opposite_direction ) { + food_way = 1; + } + } else if ( food_x == head_x ) { + if ( food_y > head_y && this->head_direction == Direction::UP ) { + food_way = 1; + } else if ( food_y < head_y && this->head_direction == Direction::DOWN ) { + food_way = 1; + } + } + break; + + default: + // should be unreachable + throw("Unexpected direction: "+std::to_string(this->head_direction)); + } + } + + + // update data + data.at(0) = blocked_way; + data.at(1) = dead_way; + data.at(2) = dead_way_steps; + data.at(3) = food_way; + data.at(4) = aggressive_way; + data.at(5) = same_direction; + data.at(6) = opposite_direction; +} + + +void Snake::updateFieldMap( Snake& adv_snake, const unsigned int& food_x, const unsigned int& food_y ) +{ + // reset to default state + for ( size_t x=0; x<16; x++ ) { + for ( size_t y=0; y<16; y++ ) { + Tile& t = this->field_map.at(x).at(y); + t.entity = Entity::N; + t.s_index = 0; + } + } + // update food position + this->field_map.at(food_x).at(food_y).entity = Entity::F; + // update self + unsigned int i = this->size(); + for ( std::vector::const_iterator bp = this->begin(); bp != this->end(); ++bp ) { + Tile& t = this->field_map.at(bp->x).at(bp->y); + t.entity = Entity::S; + t.s_index = i; + i--; + } + // update adversary + i = adv_snake.size(); + for ( const auto& bp : adv_snake ) { + Tile& t = this->field_map.at(bp.x).at(bp.y); + t.entity = Entity::A; + t.s_index = i; + i--; + } +} + + +const bool Snake::inTileAdv(const unsigned int& x, const unsigned int& y ) +{ + bool result = false; + if ( x < 16 && y < 16 ) { + switch ( this->field_map.at(x).at(y).entity ) { + case Entity::A: + result = true; + break; + } + } + return result; +} + +const bool Snake::inTileMinusSteps(const unsigned int& x, const unsigned int& y, const unsigned int& steps ) +{ + bool result = false; + switch ( this->field_map.at(x).at(y).entity ) { + case Entity::S: + case Entity::A: + if ( this->field_map.at(x).at(y).s_index > steps ) { + result = true; + } + break; + } + return result; +} + + +const std::vector Snake::checkAround( const Direction& direction, const unsigned int& x, const unsigned int& y ) +{ + std::vector around = { + 0, 0, 0, + 0, 0, + 0, 0, 0, + }; + + std::vector x_pattern, y_pattern; + + switch ( direction ) { + case Direction::UP: + x_pattern = { -1, 0, 1, + -1, 1, + -1, 0, 1 }; + y_pattern = { -1, -1, -1, + 0, 0, + 1, 1, 1 }; + break; + case Direction::DOWN: + x_pattern = { 1, 0, -1, + 1, -1, + 1, 0, -1 }; + y_pattern = { 1, 1, 1, + 0, 0, + -1, -1, -1 }; + break; + case Direction::LEFT: + x_pattern = { -1, -1, -1, + 0, 0, + 1, 1, 1 }; + y_pattern = { 1, 0, -1, + 1, -1, + 1, 0, -1 }; + break; + case Direction::RIGHT: + x_pattern = { 1, 1, 1, + 0, 0, + -1, -1, -1 }; + y_pattern = { -1, 0, 1, + -1, 1, + -1, 0, 1 }; + break; + default: + // should be unreachable + throw("Unexpected direction: "+std::to_string(direction)); + } + + unsigned int x_, y_; + for ( int i=0; i<8; i++ ) { + x_ = x; + x_ += x_pattern.at(i); + y_ = y; + y_ += y_pattern.at(i); + if ( x_ > 15 || y_ > 15 ) { + around.at(i) = 1; + } else { + switch ( this->field_map.at( x_ ).at( y_ ).entity ) { + case Entity::S: + case Entity::A: + around.at(i) = 2; + break; + } + } + } + + return around; +} + + +const unsigned int Snake::isDeadHole( const unsigned int& start_x, const unsigned int& start_y, Direction start_direction ) +{ + bool result=false, check=false, check_clockwise=false; + int front_step, front_check, side_check; + unsigned int steps=1, side, front; + Direction direction = start_direction; + + const auto blocked_around = this->checkAround( direction, start_x, start_y ); + if ( (blocked_around.at(3)>0 && blocked_around.at(4)>0) + && (blocked_around.at(3)>1 || blocked_around.at(4)>1) ) { + check = true; + } else if ( (blocked_around.at(3)>0 && blocked_around.at(7)>0) + && (blocked_around.at(3)>1 || blocked_around.at(7)>1) ) { + check = true; + } else if ( (blocked_around.at(4)>0 && blocked_around.at(5)>0) + && (blocked_around.at(4)>1 || blocked_around.at(5)>1) ) { + check = true; + check_clockwise = true; + } else if ( (blocked_around.at(5)>0 && blocked_around.at(7)>0) + && (blocked_around.at(5)>1 || blocked_around.at(7)>1) ) { + check = true; + } else if ( blocked_around.at(0)>0 && blocked_around.at(1)>0 && blocked_around.at(2)>0 ) { + check = true; + } + + + if ( check ) { + + unsigned int aux_side, aux_front; + const unsigned int max_steps = this->size()-1; + std::vector> tried_positions = { + std::make_tuple( start_x, start_y ) + }; + + std::function change_direction; + std::function tried_already; + std::function tile_blocked; + std::function check_deadhole; + + + change_direction = [&](const bool& clockwise) { + switch ( direction ) { + case Direction::UP: + if ( clockwise ) { + direction = Direction::RIGHT; + front_check = +1; + side_check = (check_clockwise) ? +1 : -1; + } else { + direction = Direction::LEFT; + front_check = -1; + side_check = (check_clockwise) ? -1 : +1; + } + break; + case Direction::DOWN: + if ( clockwise ) { + direction = Direction::LEFT; + front_check = -1; + side_check = (check_clockwise) ? -1 : +1; + } else { + direction = Direction::RIGHT; + front_check = +1; + side_check = (check_clockwise) ? +1 : -1; + } + break; + case Direction::LEFT: + if ( clockwise ) { + direction = Direction::UP; + front_check = -1; + side_check = (check_clockwise) ? +1 : -1; + } else { + direction = Direction::DOWN; + front_check = +1; + side_check = (check_clockwise) ? -1 : +1; + } + break; + case Direction::RIGHT: + if ( clockwise ) { + direction = Direction::DOWN; + front_check = +1; + side_check = (check_clockwise) ? -1 : +1; + } else { + direction = Direction::UP; + front_check = -1; + side_check = (check_clockwise) ? +1 : -1; + } + break; + default: + // should be unreachable + throw("Unexpected direction: "+std::to_string(direction)); + } + // swap front/side + front = front ^ side; + side = front ^ side; + front = front ^ side; + front_step = front_check; + }; + + + tried_already = [&](const unsigned int& side_, const unsigned int& front_, const bool& update) { + bool tried = false; + unsigned int x, y; + switch ( direction ) { + case Direction::UP: + case Direction::DOWN: + x = side_; + y = front_; + break; + case Direction::LEFT: + case Direction::RIGHT: + y = side_; + x = front_; + break; + default: + // should be unreachable + throw("Unexpected direction: "+std::to_string(direction)); + } + for ( const auto& position : tried_positions ) { + if ( std::get<0>(position) == x ) { + if ( std::get<1>(position) == y ) { + tried = true; + break; + } + } + } + if ( update ) { + tried_positions.push_back( std::make_tuple( x, y ) ); + } + return tried; + }; + + + tile_blocked = [&](const unsigned int& side_, const unsigned int& front_) { + bool blocked = false; + unsigned int x, y, x_, y_; + switch ( direction ) { + case Direction::UP: + case Direction::DOWN: + x = side_; + y = front_; + x_ = side; + y_ = front; + break; + case Direction::LEFT: + case Direction::RIGHT: + y = side_; + x = front_; + y_ = side; + x_ = front; + break; + default: + // should be unreachable + throw("Unexpected direction: "+std::to_string(direction)); + } + if ( x > 15 || y > 15 ) { + blocked = true; + } else if ( this->inTileMinusSteps( x, y, steps ) ) { + blocked = true; + } else if ( tried_already( side_, front_, false ) ) { + if ( this->field_map.at( x_ ).at( y_ ).entity == Entity::S ) { + blocked = true; + } + } + return blocked; + }; + + + check_deadhole = [&]() { + switch ( start_direction ) { + case Direction::UP: + front = start_y; + side = start_x; + front_check = -1; + side_check = (check_clockwise) ? +1 : -1; + break; + case Direction::DOWN: + front = start_y; + side = start_x; + front_check = +1; + side_check = (check_clockwise) ? -1 : +1; + break; + case Direction::LEFT: + front = start_x; + side = start_y; + front_check = -1; + side_check = (check_clockwise) ? -1 : +1; + break; + case Direction::RIGHT: + front = start_x; + side = start_y; + front_check = +1; + side_check = (check_clockwise) ? +1 : -1; + break; + default: + // should be unreachable + throw("Unexpected direction: "+std::to_string(start_direction)); + } + front_step = front_check; + + while ( true ) { + // check the side + aux_side = side; + aux_side += side_check; + if ( !tile_blocked( aux_side, front ) ) { + // side is free, check for another deadhole + aux_front = front; + aux_front += front_check; + unsigned int aux_front_ = front; + aux_front_ += front_check*(-2); + if ( tile_blocked( side, aux_front ) && tile_blocked( aux_side, aux_front_ ) ) { + // may-be deadhole at side, check the opposite + aux_side = side; + aux_side += (side_check*(-1)); + if ( !tile_blocked( aux_side, front ) ) { + // opposite side free + change_direction( !check_clockwise ); + } else { + // opposite side blocked too + change_direction( check_clockwise ); + } + } else { + // turn at side + change_direction( check_clockwise ); + } + } else { + // side blocked, check front + aux_front = front; + aux_front += front_check; + if ( tile_blocked( side, aux_front ) ) { + // front blocked, check opposite side + aux_side = side; + aux_side += (side_check*(-1)); + if ( !tile_blocked( aux_side, front ) ) { + // opposite side free + change_direction( !check_clockwise ); + } else { + // opposite side blocked too + result = true; + break; + } + } + } + + front += front_step; + + if ( tried_already( side, front, true ) ) { + result = true; + break; + } else { + steps ++; + if ( steps >= max_steps ) { + break; + } + } + } + }; + + + // start checking + bool aux_result=false; + unsigned int aux_steps=0, i=0; + while ( true ) { + check_deadhole(); + if ( !result ) { + steps = 0; + } + i ++; + if ( i == 2 ) { + break; + } + aux_result = result; + result = false; + aux_steps = steps; + steps = 1; + check_clockwise = !check_clockwise; + direction = start_direction; + tried_positions.clear(); + } + + // mean result + result = result | aux_result; + steps = (steps>aux_steps) ? steps : aux_steps; + } + + if ( !result ) { + steps = 0; + } + return steps; +} diff --git a/logdoctor/games/snake/snake.h b/logdoctor/games/snake/snake.h new file mode 100644 index 00000000..051f608e --- /dev/null +++ b/logdoctor/games/snake/snake.h @@ -0,0 +1,125 @@ +#ifndef SNAKE_H +#define SNAKE_H + +#include + +#include +#include +#include + + +//! Enumerates the possible directions +enum Direction { + UP, //!< Up + DOWN, //!< Down + LEFT, //!< Left + RIGHT //!< Right +}; + + +//! Instance of a part of the body of the snake +struct BodyPart { + unsigned int x; //!< The position on the X-axis + unsigned int y; //!< The position on the Y-axis + Direction direction; //!< The current direction of the part + Direction prev_direction; //!< The previous direction of the part + QGraphicsPixmapItem* image; //!< The image which graphically represents the part + //! Updates the position and direction of the part + void update( const unsigned int& new_x, const unsigned int& new_y, const Direction& new_direction ) { + this->x = new_x; + this->y = new_y; + this->image->setOffset( 16+(new_x*32), 16+(new_y*32) ); + this->prev_direction = this->direction; + this->direction = new_direction; + } +}; + + +class Snake : public std::vector +{ +public: + Snake( const bool& is_adversary=false ); + + QPixmap& getHeadImage(); + + //! Checks whether is there a part of the snake in the given position + const bool inTile( const unsigned int& x, const unsigned int& y, const bool& avoid_tail=true ); + + //! Sets the new direction (of the head) + void setDirection( const Direction new_direction ); + + //! Returns the current direction (of the head) + const Direction& direction(); + + //! Updates the position and direction of the entire snake + void update( QGraphicsScene* field_scene=nullptr, const bool& dry=false, const bool& is_borning=false ); + + // Schedules to grow the snake on the next update + void willGrow(); + + // [AI] Chooses a new direction for the snake + void move( Snake& adv_snake, const unsigned int& food_x, const unsigned int& food_y ); + + +private: + + QPixmap img_snakeHead = QPixmap(":/games/games/snake/head.png"); + QPixmap img_snakeTail = QPixmap(":/games/games/snake/tail.png"); + QPixmap img_snakeBody = QPixmap(":/games/games/snake/body_s.png"); + QPixmap img_snakeCurve = QPixmap(":/games/games/snake/body_c.png"); + + QPixmap img_snakeHead_ = QPixmap(":/games/games/snake/head_.png"); + QPixmap img_snakeTail_ = QPixmap(":/games/games/snake/tail_.png"); + QPixmap img_snakeBody_ = QPixmap(":/games/games/snake/body_s_.png"); + QPixmap img_snakeCurve_ = QPixmap(":/games/games/snake/body_c_.png"); + + Direction head_direction; + + bool will_grow; + + //! Increases the length of the body of the snake of 1 part + void grow( const bool& is_borning ); + + bool adversary; + + //// ADVERSARY //// + + const unsigned int aggressiveness = 10 - (rand()%9); + + enum Entity { + N, // none + S, // self + A, // adversary + F, // food + }; + + struct Tile { + Entity entity; + unsigned int s_index; + }; + + std::vector> field_map; + + // [AI] Updates the map of the field + void updateFieldMap( Snake& adv_snake, const unsigned int& food_x, const unsigned int& food_y ); + + // [AI] As inTile(), but works on the field_map and only checks the adersary + const bool inTileAdv( const unsigned int& x, const unsigned int& y ); + + // [AI] Checks whether is there a snake in the tile, without counting as much trailing BodyParts as the number of steps + const bool inTileMinusSteps( const unsigned int& x, const unsigned int& y, const unsigned int& steps ); + + // [AI] Checks which of the surrounding positions are blocked + const std::vector checkAround( const Direction& direction, const unsigned int& x, const unsigned int& y ); + + // [AI] Checks if a direction is a closed path and should be avoided + const unsigned int isDeadHole( const unsigned int& start_x, const unsigned int& start_y, Direction start_direction ); + + // [AI] Collects data about the possible movements + void collectData( std::vector& data, Direction& direction, Snake& adv_snake, const unsigned int& food_x, const unsigned int& food_y ); + + // [AI] Processes the collected data to predict the best movement + const Direction predictDirection( std::vector>& data, std::vector weights, std::vector classes ); +}; + +#endif // SNAKE_H diff --git a/logdoctor/games/snake/snake.ui b/logdoctor/games/snake/snake.ui new file mode 100644 index 00000000..d456f1ad --- /dev/null +++ b/logdoctor/games/snake/snake.ui @@ -0,0 +1,321 @@ + + + SnakeGame + + + + 0 + 0 + 594 + 666 + + + + + 594 + 666 + + + + Qt::StrongFocus + + + LogDoctor - Snake + + + + :/logo/logo/logdoctor.svg + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Qt::Vertical + + + + 529 + 14 + + + + + + + + Qt::Horizontal + + + + 13 + 590 + + + + + + + + Qt::Horizontal + + + + 13 + 590 + + + + + + + + Qt::Vertical + + + + 529 + 14 + + + + + + + + + 564 + 634 + + + + + 564 + 634 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + 0 + + + + + + + Qt::Vertical + + + + 253 + 234 + + + + + + + + + 0 + 0 + + + + + 256 + 128 + + + + + 16777215 + 128 + + + + + 64 + + + + PLAY + + + + + + + Qt::Vertical + + + + 253 + 234 + + + + + + + + Qt::Horizontal + + + + 135 + 125 + + + + + + + + Qt::Horizontal + + + + 135 + 125 + + + + + + + + + 11 + + + + + Classic + + + + + Hunt + + + + + Battle + + + + + + + + + + + + + 544 + 64 + + + + + 544 + 64 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 0 + + + 8 + + + 6 + + + 8 + + + 6 + + + + + + 0 + 0 + + + + 1 + + + 0 + + + + + + + + + + + 544 + 544 + + + + + 544 + 544 + + + + Qt::NoFocus + + + Qt::ScrollBarAlwaysOff + + + Qt::ScrollBarAlwaysOff + + + + + + + + + + + + diff --git a/logdoctor/main.cpp b/logdoctor/main.cpp new file mode 100644 index 00000000..35fb76a9 --- /dev/null +++ b/logdoctor/main.cpp @@ -0,0 +1,15 @@ + +#include "mainwindow.h" + +#include + + +int main(int argc, char *argv[]) +{ + QApplication::setAttribute( Qt::AA_EnableHighDpiScaling ); + QApplication a(argc, argv); + + MainWindow w; + w.show(); + return a.exec(); +} diff --git a/logdoctor/mainwindow.cpp b/logdoctor/mainwindow.cpp new file mode 100644 index 00000000..9ce1a721 --- /dev/null +++ b/logdoctor/mainwindow.cpp @@ -0,0 +1,5252 @@ + +#include "mainwindow.h" +#include "./ui_mainwindow.h" + +#include "utilities/checks.h" +#include "utilities/colors.h" +#include "utilities/gzip.h" +#include "utilities/io.h" +#include "utilities/rtf.h" +#include "utilities/stylesheets.h" + +#include "modules/dialogs.h" +#include "modules/exceptions.h" +#include "modules/shared.h" + +#include + +#include +#include + + +MainWindow::MainWindow(QWidget *parent) + : QMainWindow(parent) + , ui(new Ui::MainWindow) +{ + ////////////////// + //// GRAPHICS //// + this->ui->setupUi(this); + + // initialize the color-schemes map + this->TB_COLOR_SCHEMES = ColorSec::getColorSchemes(); + // initialize the colors map + this->COLORS = ColorSec::getColors(); + + // load the main font + this->main_font_family = QFontDatabase::applicationFontFamilies( + QFontDatabase::addApplicationFont(":/fonts/Metropolis")).at(0); + // load the alternative font + this->alternative_font_family = QFontDatabase::applicationFontFamilies( + QFontDatabase::addApplicationFont(":/fonts/Hack")).at(0); + // load the script font + this->script_font_family = QFontDatabase::applicationFontFamilies( + QFontDatabase::addApplicationFont(":/fonts/3270")).at(0); + // initialize the fonts map + this->FONTS.emplace( "main", QFont( + this->main_font_family, + this->font_size ) ); + this->FONTS.emplace( "main_italic", QFont( + this->main_font_family, + this->font_size, + -1, true ) ); + this->FONTS.emplace( "main_bold", QFont( + this->main_font_family, + this->font_size, + 1 ) ); + this->FONTS.emplace( "main_big", QFont( + this->main_font_family, + this->font_size_big ) ); + this->FONTS.emplace( "main_small", QFont( + this->main_font_family, + this->font_size_small ) ); + this->FONTS.emplace( "alternative", QFont( + this->alternative_font_family, + this->font_size ) ); + this->FONTS.emplace( "script", QFont( + this->script_font_family, + this->font_size ) ); + + // parent fonts + this->ui->mainwidget->setFont( this->FONTS.at( "main_big" ) ); + + // TextBrowser for the LogFiles + this->TB.setColorScheme( 1, this->TB_COLOR_SCHEMES.at( 1 ) ); + this->TB.setFont( this->FONTS.at( "main" ) ); + this->ui->textLogFiles->setFont( this->TB.getFont() ); + + // adjust LogsList headers width + this->ui->listLogFiles->header()->resizeSection(0,200); + this->ui->listLogFiles->header()->resizeSection(1,100); + + // blocknote + this->crapnote->setFont( this->FONTS.at( "main" ) ); + + + ////////////// + //// MENU //// + // languages + connect( this->ui->actionEnglish, &QAction::triggered, this, &MainWindow::menu_actionEnglish_triggered ); + connect( this->ui->actionEspanol, &QAction::triggered, this, &MainWindow::menu_actionEspanol_triggered ); + connect( this->ui->actionFrancais, &QAction::triggered, this, &MainWindow::menu_actionFrancais_triggered ); + connect( this->ui->actionItaliano, &QAction::triggered, this, &MainWindow::menu_actionItaliano_triggered ); + // tools + connect( this->ui->actionBlockNote, &QAction::triggered, this, &MainWindow::menu_actionBlockNote_triggered ); + // utilities + connect( this->ui->actionInfos, &QAction::triggered, this, &MainWindow::menu_actionInfos_triggered ); + connect( this->ui->actionCheckUpdates, &QAction::triggered, this, &MainWindow::menu_actionCheckUpdates_triggered ); + // games + connect( this->ui->actionCrissCross, &QAction::triggered, this, &MainWindow::menu_actionCrissCross_triggered ); + connect( this->ui->actionSnake, &QAction::triggered, this, &MainWindow::menu_actionSnake_triggered ); + + + ///////////////// + //// CONFIGS //// + this->defineOSspec(); + this->readConfigs(); + + + /////////////////// + //// POLISHING //// + // default tabs + this->switchMainTab( 0 ); + this->switchStatsTab( 0 ); + + // language menu + if ( this->language != "en" ) { + this->ui->actionEnglish->setChecked( false ); + if ( language == "es" ) { + this->ui->actionEspanol->setChecked( true ); + } else if ( language == "fr" ) { + this->ui->actionFrancais->setChecked( true ); + } else if ( language == "it" ) { + this->ui->actionItaliano->setChecked( true ); + } + } + + // set the default WS as the current one + switch ( this->default_ws ) { + case 11: + this->ui->button_LogFiles_Apache->setFlat( false ); + this->ui->radio_ConfDefaults_Apache->setChecked( true ); + break; + case 12: + this->ui->button_LogFiles_Nginx->setFlat( false ); + this->ui->radio_ConfDefaults_Nginx->setChecked( true ); + break; + case 13: + this->ui->button_LogFiles_Iis->setFlat( false ); + this->ui->radio_ConfDefaults_Iis->setChecked( true ); + break; + default: + // shouldn't be here + throw WebServerException( "Unexpected WebServer ID: "+std::to_string( this->default_ws ) ); + } + this->craplog.setCurrentWSID( this->default_ws ); + + + // make the Configs initialize + // window + this->ui->checkBox_ConfWindow_Geometry->setChecked( this->remember_window ); + this->ui->box_ConfWindow_Theme->setCurrentIndex( this->window_theme_id ); + this->ui->box_ConfWindow_Icons->setCurrentIndex( this->icons_theme_id ); + // dialogs + this->ui->slider_ConfDialogs_General->setValue( this->dialogs_level ); + this->ui->slider_ConfDialogs_Logs->setValue( this->craplog.getDialogsLevel() ); + this->ui->slider_ConfDialogs_Stats->setValue( this->crapview.getDialogsLevel() ); + // text browser + this->ui->box_ConfTextBrowser_Font->setCurrentText( this->TB.getFontFamily() ); + this->ui->checkBox_ConfTextBrowser_WideLines->setChecked( this->TB.getWideLinesUsage() ); + this->ui->box_ConfTextBrowser_ColorScheme->setCurrentIndex( this->TB.getColorSchemeID() ); + this->refreshTextBrowserPreview(); + // charts + this->ui->box_ConfCharts_Theme->setCurrentIndex( this->charts_theme_id ); + this->refreshChartsPreview(); + // databases + this->ui->inLine_ConfDatabases_Data_Path->setText( QString::fromStdString( this->db_data_path ) ); + this->ui->button_ConfDatabases_Data_Save->setEnabled( false ); + this->ui->inLine_ConfDatabases_Hashes_Path->setText( QString::fromStdString( this->db_hashes_path ) ); + this->ui->button_ConfDatabases_Hashes_Save->setEnabled( false ); + this->ui->spinBox_ConfDatabases_NumBackups->setValue( this->db_backups_number ); + this->ui->checkBox_ConfDatabases_DoBackup->setChecked( this->db_do_backup ); + // logs control + this->ui->checkBox_ConfControl_Usage->setChecked( this->hide_used_files ); + this->ui->spinBox_ConfControl_Size->setValue( this->craplog.getWarningSize() / 1'048'576 ); + if ( this->craplog.getWarningSize() > 0 ) { + this->ui->checkBox_ConfControl_Size->setChecked( true ); + } else { + this->ui->checkBox_ConfControl_Size->setChecked( false ); + } + // apache paths + this->ui->inLine_ConfApache_Path_String->setText( QString::fromStdString(this->craplog.getLogsPath( this->APACHE_ID )) ); + this->ui->button_ConfApache_Path_Save->setEnabled( false ); + // apache formats + this->ui->inLine_ConfApache_Format_String->setText( QString::fromStdString( this->craplog.getLogsFormatString( this->APACHE_ID ) ) ); + this->ui->button_ConfApache_Format_Save->setEnabled( false ); + // apache warnlists + this->on_box_ConfApache_Warnlist_Field_currentTextChanged( this->ui->box_ConfApache_Warnlist_Field->currentText() ); + // apache blacklists + this->on_box_ConfApache_Blacklist_Field_currentTextChanged( this->ui->box_ConfApache_Blacklist_Field->currentText() ); + // nginx paths + this->ui->inLine_ConfNginx_Path_String->setText( QString::fromStdString(this->craplog.getLogsPath( this->NGINX_ID )) ); + this->ui->button_ConfNginx_Path_Save->setEnabled( false ); + // nginx formats + this->ui->inLine_ConfNginx_Format_String->setText( QString::fromStdString( this->craplog.getLogsFormatString( this->NGINX_ID ) ) ); + this->ui->button_ConfNginx_Format_Save->setEnabled( false ); + // nginx warnlists + this->on_box_ConfNginx_Warnlist_Field_currentTextChanged( this->ui->box_ConfNginx_Warnlist_Field->currentText() ); + // nginx blacklists + this->on_box_ConfNginx_Blacklist_Field_currentTextChanged( this->ui->box_ConfNginx_Blacklist_Field->currentText() ); + // iis paths + this->ui->inLine_ConfIis_Path_String->setText( QString::fromStdString(this->craplog.getLogsPath( this->IIS_ID )) ); + this->ui->button_ConfIis_Path_Save->setEnabled( false ); + // iis formats + this->ui->inLine_ConfIis_Format_String->setText( QString::fromStdString( this->craplog.getLogsFormatString( this->IIS_ID ) ) ); + this->ui->button_ConfIis_Format_Save->setEnabled( false ); + // iis warnlists + this->on_box_ConfIis_Warnlist_Field_currentTextChanged( this->ui->box_ConfIis_Warnlist_Field->currentText() ); + // iis blacklists + this->on_box_ConfIis_Blacklist_Field_currentTextChanged( this->ui->box_ConfIis_Blacklist_Field->currentText() ); + + + // blocknote's font and colors + this->crapnote->setTextFont( this->TB.getFont() ); + this->crapnote->setColorScheme( this->TB.getColorSchemeID() ); + + // text browser's default message + { + QString rich_text; + RichText::richLogsDefault( rich_text ); + this->ui->textLogFiles->setText( rich_text ); + this->ui->textLogFiles->setAlignment( Qt::AlignHCenter ); + rich_text.clear(); + } + + + /////////////////// + //// INTERFACE //// + this->updateUiLanguage(); + this->updateUiTheme(); + + + /////////////// + //// START //// + // get a fresh list of LogFiles + this->waiter_timer = new QTimer(this); + connect(this->waiter_timer, SIGNAL(timeout()), this, SLOT(wait_ActiveWindow())); + this->waiter_timer->start(250); +} + +MainWindow::~MainWindow() +{ + delete this->ui; + delete this->waiter_timer; + delete this->craplog_timer; + delete this->crapview_timer; + delete this->craphelp; + delete this->crapnote; + delete this->crapinfo; + delete this->crapup; + delete this->crisscross; + delete this->snake; +} + +void MainWindow::closeEvent( QCloseEvent *event ) +{ + // save actual configurations + this->writeConfigs(); + // backup the database + if ( this->db_do_backup && this->db_edited ) { + this->backupDatabase(); + } + // save splitters sizes => this->ui->splitter_StatsCount->sizes(); +} + + + +//////////////////////// +//// CONFIGURATIONS //// +//////////////////////// +// os definition +void MainWindow::defineOSspec() +{ + switch ( this->OS ) { + case 1: + // unix-like + /*this->configs_path = home_path + "/.config/LogDoctor/logdoctor.conf"; + this->logdoc_path = home_path + "/.local/share/LogDoctor";*/ + this->db_data_path = this->home_path + "/.local/share/LogDoctor"; + this->db_hashes_path = this->home_path + "/.local/share/LogDoctor"; + break; + + case 2: + // windows + /*this->configs_path = home_path + "/AppData/Local/LogDoctor/logdoctor.conf"; + this->logdoc_path = home_path + "/AppData/Local/LogDoctor";*/ + this->db_data_path = this->logdoc_path; + this->db_hashes_path = this->logdoc_path; + break; + + case 3: + // darwin-based + /*this->configs_path = home_path + "/Lybrary/Preferences/LogDoctor/logdoctor.conf"; + this->logdoc_path = home_path + "/Lybrary/Application Support/LogDoctor";*/ + this->db_data_path = this->logdoc_path; + this->db_hashes_path = this->logdoc_path; + break; + + default: + // shouldn't be here + throw GenericException( "Unexpected OS ID: "+std::to_string( this->OS ), true ); + } +} + +void MainWindow::readConfigs() +{ + bool proceed = true; + std::error_code err; + QString err_msg = ""; + // check the file + if ( IOutils::exists( this->configs_path ) ) { + if ( IOutils::checkFile( this->configs_path ) ) { + if ( ! IOutils::checkFile( this->configs_path, true ) ) { + // file not readable, try to assign permissions + std::filesystem::permissions( this->configs_path, + std::filesystem::perms::owner_read, + std::filesystem::perm_options::add, + err ); + if ( err.value() ) { + proceed = false; + QString file = ""; + if ( this->dialogs_level > 0 ) { + file = QString::fromStdString( this->configs_path ); + err_msg = QString::fromStdString( err.message() ); + } + DialogSec::errConfFileNotReadable( file, err_msg ); + } + } + } else { + // the given path doesn't point to a file + proceed = DialogSec::choiceFileNotFile( QString::fromStdString( this->configs_path ) ); + if ( proceed ) { + proceed = IOutils::renameAsCopy( this->configs_path, err ); + if ( ! proceed ) { + QString path = ""; + if ( this->dialogs_level > 0 ) { + path = QString::fromStdString( this->configs_path ); + if ( err.value() ) { + err_msg = QString::fromStdString( err.message() ); + } + } + DialogSec::errRenaming( QString::fromStdString( this->configs_path ), err_msg ); + } + } + } + } else { + // configuration file not found + proceed = false; + QString file = ""; + if ( this->dialogs_level == 2 ) { + file = QString::fromStdString( this->configs_path ); + } + DialogSec::warnConfFileNotFound( file ); + } + + if ( proceed ) { + QString err_msg="", aux_err_msg; + std::vector aux, configs; + try { + // reset the lists when a config file is found + for ( int w=this->APACHE_ID; w<=this->IIS_ID; w++ ) { + for ( const int& f : std::vector({11,12,20,21}) ) { + this->craplog.setWarnlist( w, f, {} ); + } + this->craplog.setBlacklist( w, 20, {} ); + } + std::string content; + IOutils::readFile( this->configs_path, content ); + StringOps::splitrip( configs, content ); + for ( const std::string& line : configs ) { + if ( StringOps::startsWith( line, "[") ) { + // section descriptor + continue; + } + aux.clear(); + StringOps::splitrip( aux, line, "=" ); + if ( aux.size() < 2 ) { + // nothing to do + continue; + } + // if here, a value is present + const std::string& var = aux.at( 0 ), + val = aux.at( 1 ); + + if ( val.size() == 0 ) { + // nothing to do, no value stored + continue; + } + + if ( var == "Language" ) { + if ( val.size() > 2 ) { + // not a valid locale, keep the default + DialogSec::errLangLocaleInvalid( QString::fromStdString( val ) ); + } else { + if ( val == "en" || val == "es" || val == "fr" || val == "it" ) { + this->language = val; + } else { + DialogSec::errLangNotAccepted( QString::fromStdString( val ) ); + } + } + + } else if ( var == "RememberGeometry" ) { + this->remember_window = this->s2b.at( val ); + + } else if ( var == "Geometry" ) { + this->geometryFromString( val ); + + } else if ( var == "WindowTheme" ) { + this->window_theme_id = std::stoi( val ); + + } else if ( var == "ChartsTheme" ) { + this->charts_theme_id = std::stoi( val ); + + } else if ( var == "IconsTheme" ) { + this->icons_theme_id = std::stoi( val ); + + } else if ( var == "MainDialogLevel" ) { + this->dialogs_level = std::stoi( val ); + + } else if ( var == "DefaultWebServer" ) { + this->default_ws = std::stoi( val ); + + } else if ( var == "DatabaseDataPath" ) { + this->db_data_path = this->resolvePath( val ); + + } else if ( var == "DatabaseHashesPath" ) { + this->db_hashes_path = this->resolvePath( val ); + + } else if ( var == "DatabaseDoBackup" ) { + this->db_do_backup = this->s2b.at( val ); + + } else if ( var == "DatabaseBackupsNumber" ) { + this->db_backups_number = std::stoi( val ); + + } else if ( var == "Font" ) { + this->on_box_ConfTextBrowser_Font_currentIndexChanged( std::stoi( val ) ); + + } else if ( var == "WideLines" ) { + this->TB.setWideLinesUsage( this->s2b.at( val ) ); + + } else if ( var == "ColorScheme" ) { + this->on_box_ConfTextBrowser_ColorScheme_currentIndexChanged( std::stoi( val ) ); + + } else if ( var == "CraplogDialogLevel" ) { + this->craplog.setDialogsLevel( std::stoi( val ) ); + + } else if ( var == "HideUsedFiles" ) { + hide_used_files = this->s2b.at( val ); + + } else if ( var == "WarningSize" ) { + this->craplog.setWarningSize( std::stoi( val ) ); + + } else if ( var == "ApacheLogsPath" ) { + this->craplog.setLogsPath( this->APACHE_ID, this->resolvePath( val ) ); + + } else if ( var == "ApacheLogsFormat" ) { + if ( ! this->craplog.setApacheLogFormat( val ) ) { + throw(""); + } + + } else if ( var == "ApacheWarnlistMethod" ) { + aux_err_msg = QString("Apache -> %1 (%2)") + .arg( TR::tr(FIELDS__METHOD.c_str()), MainWindow::tr("warnlist") ); + this->craplog.setWarnlist( this->APACHE_ID, 11, this->string2list( val ) ); + + } else if ( var == "ApacheWarnlistMethodUsed" ) { + this->craplog.setWarnlistUsed( this->APACHE_ID, 11, this->s2b.at( val ) ); + + } else if ( var == "ApacheWarnlistURI" ) { + aux_err_msg = QString("Apache -> %1 (%2)") + .arg( TR::tr(FIELDS__URI.c_str()), MainWindow::tr("warnlist") ); + this->craplog.setWarnlist( this->APACHE_ID, 12, this->string2list( val ) ); + + } else if ( var == "ApacheWarnlistURIUsed" ) { + this->craplog.setWarnlistUsed( this->APACHE_ID, 12, this->s2b.at( val ) ); + + } else if ( var == "ApacheWarnlistClient" ) { + aux_err_msg = QString("Apache -> %1 (%2)") + .arg( TR::tr(FIELDS__CLIENT.c_str()), MainWindow::tr("warnlist") ); + this->craplog.setWarnlist( this->APACHE_ID, 20, this->string2list( val ) ); + + } else if ( var == "ApacheWarnlistClientUsed" ) { + this->craplog.setWarnlistUsed( this->APACHE_ID, 20, this->s2b.at( val ) ); + + } else if ( var == "ApacheWarnlistUserAgent" ) { + aux_err_msg = QString("Apache -> %1 (%2)") + .arg( TR::tr(FIELDS__USER_AGENT.c_str()), MainWindow::tr("warnlist") ); + this->craplog.setWarnlist( this->APACHE_ID, 21, this->string2list( val, true ) ); + + } else if ( var == "ApacheWarnlistUserAgentUsed" ) { + this->craplog.setWarnlistUsed( this->APACHE_ID, 21, this->s2b.at( val ) ); + + } else if ( var == "ApacheBlacklistClient" ) { + aux_err_msg = QString("Apache -> %1 (%2)") + .arg( TR::tr(FIELDS__CLIENT.c_str()), MainWindow::tr("blacklist") ); + this->craplog.setBlacklist( this->APACHE_ID, 20, this->string2list( val ) ); + + } else if ( var == "ApacheBlacklistClientUsed" ) { + this->craplog.setBlacklistUsed( this->APACHE_ID, 20, this->s2b.at( val ) ); + + } else if ( var == "NginxLogsPath" ) { + this->craplog.setLogsPath( this->NGINX_ID, this->resolvePath( val ) ); + + } else if ( var == "NginxLogsFormat" ) { + if ( ! this->craplog.setNginxLogFormat( val ) ) { + throw(""); + } + + } else if ( var == "NginxWarnlistMethod" ) { + aux_err_msg = QString("Nginx -> %1 (%2)") + .arg( TR::tr(FIELDS__METHOD.c_str()), MainWindow::tr("warnlist") ); + this->craplog.setWarnlist( this->NGINX_ID, 11, this->string2list( val ) ); + + } else if ( var == "NginxWarnlistMethodUsed" ) { + this->craplog.setWarnlistUsed( this->NGINX_ID, 11, this->s2b.at( val ) ); + + } else if ( var == "NginxWarnlistURI" ) { + aux_err_msg = QString("Nginx -> %1 (%2)") + .arg( TR::tr(FIELDS__URI.c_str()), MainWindow::tr("warnlist") ); + this->craplog.setWarnlist( this->NGINX_ID, 12, this->string2list( val ) ); + + } else if ( var == "NginxWarnlistURIUsed" ) { + this->craplog.setWarnlistUsed( this->NGINX_ID, 12, this->s2b.at( val ) ); + + } else if ( var == "NginxWarnlistClient" ) { + aux_err_msg = QString("Nginx -> %1 (%2)") + .arg( TR::tr(FIELDS__CLIENT.c_str()), MainWindow::tr("warnlist") ); + this->craplog.setWarnlist( this->NGINX_ID, 20, this->string2list( val ) ); + + } else if ( var == "NginxWarnlistClientUsed" ) { + this->craplog.setWarnlistUsed( this->NGINX_ID, 20, this->s2b.at( val ) ); + + } else if ( var == "NginxWarnlistUserAgent" ) { + aux_err_msg = QString("Nginx -> %1 (%2)") + .arg( TR::tr(FIELDS__USER_AGENT.c_str()), MainWindow::tr("warnlist") ); + this->craplog.setWarnlist( this->NGINX_ID, 21, this->string2list( val, true ) ); + + } else if ( var == "NginxWarnlistUserAgentUsed" ) { + this->craplog.setWarnlistUsed( this->NGINX_ID, 21, this->s2b.at( val ) ); + + } else if ( var == "NginxBlacklistClient" ) { + aux_err_msg = QString("Nginx -> %1 (%2)") + .arg( TR::tr(FIELDS__CLIENT.c_str()), MainWindow::tr("blacklist") ); + this->craplog.setBlacklist( this->NGINX_ID, 20, this->string2list( val ) ); + + } else if ( var == "NginxBlacklistClientUsed" ) { + this->craplog.setBlacklistUsed( this->NGINX_ID, 20, this->s2b.at( val ) ); + + } else if ( var == "IisLogsPath" ) { + this->craplog.setLogsPath( this->IIS_ID, this->resolvePath( val ) ); + + } else if ( var == "IisLogsModule" ) { + if ( val == "1" ) { + this->ui->radio_ConfIis_Format_NCSA->setChecked( true ); + } else if ( val == "2" ) { + this->ui->radio_ConfIis_Format_IIS->setChecked( true ); + } + + } else if ( var == "IisLogsFormat" ) { + int module = 0; + if ( this->ui->radio_ConfIis_Format_NCSA->isChecked() ) { + module = 1; + } else if ( this->ui->radio_ConfIis_Format_IIS->isChecked() ) { + module = 2; + } + if ( ! this->craplog.setIisLogFormat( val, module ) ) { + throw(""); + } + + } else if ( var == "IisWarnlistMethod" ) { + aux_err_msg = QString("IIS -> %1 (%2)") + .arg( TR::tr(FIELDS__METHOD.c_str()), MainWindow::tr("warnlist") ); + this->craplog.setWarnlist( this->IIS_ID, 11, this->string2list( val ) ); + + } else if ( var == "IisWarnlistMethodUsed" ) { + this->craplog.setWarnlistUsed( this->IIS_ID, 11, this->s2b.at( val ) ); + + } else if ( var == "IisWarnlistURI" ) { + aux_err_msg = QString("IIS -> %1 (%2)") + .arg( TR::tr(FIELDS__URI.c_str()), MainWindow::tr("warnlist") ); + this->craplog.setWarnlist( this->IIS_ID, 12, this->string2list( val ) ); + + } else if ( var == "IisWarnlistURIUsed" ) { + this->craplog.setWarnlistUsed( this->IIS_ID, 12, this->s2b.at( val ) ); + + } else if ( var == "IisWarnlistClient" ) { + aux_err_msg = QString("IIS -> %1 (%2)") + .arg( TR::tr(FIELDS__CLIENT.c_str()), MainWindow::tr("warnlist") ); + this->craplog.setWarnlist( this->IIS_ID, 20, this->string2list( val ) ); + + } else if ( var == "IisWarnlistClientUsed" ) { + this->craplog.setWarnlistUsed( this->IIS_ID, 20, this->s2b.at( val ) ); + + } else if ( var == "IisWarnlistUserAgent" ) { + aux_err_msg = QString("IIS -> %1 (%2)") + .arg( TR::tr(FIELDS__USER_AGENT.c_str()), MainWindow::tr("warnlist") ); + this->craplog.setWarnlist( this->IIS_ID, 21, this->string2list( val, true ) ); + + } else if ( var == "IisWarnlistUserAgentUsed" ) { + this->craplog.setWarnlistUsed( this->IIS_ID, 21, this->s2b.at( val ) ); + + } else if ( var == "IisBlacklistClient" ) { + aux_err_msg = QString("IIS -> %1 (%2)") + .arg( TR::tr(FIELDS__CLIENT.c_str()), MainWindow::tr("blacklist") ); + this->craplog.setBlacklist( this->IIS_ID, 20, this->string2list( val ) ); + + } else if ( var == "IisBlacklistClientUsed" ) { + this->craplog.setBlacklistUsed( this->IIS_ID, 20, this->s2b.at( val ) ); + + } else if ( var == "CrapviewDialogLevel" ) { + this->crapview.setDialogsLevel( std::stoi( val ) ); + + }/* else { + // not valid + }*/ + } + + } catch ( const std::ios_base::failure& ) { + // failed reading + proceed = false; + err_msg = DialogSec::tr("An error occured while reading the configuration file"); + } catch ( const LogFormatException& ) { + proceed = false; // message already shown + } catch ( const BWlistException& ) { + proceed = false; + err_msg = QString("%1:\n%2").arg( + DialogSec::tr("One of the lists has an invalid item"), + aux_err_msg ); + } catch (...) { + // something failed + proceed = false; + err_msg = DialogSec::tr("An error occured while parsing configuration file's data"); + } + if ( ! proceed ) { + DialogSec::errFailedApplyingConfigs( err_msg ); + this->closeEvent( new QCloseEvent() ); + } + } +} + +void MainWindow::writeConfigs() +{ + std::error_code err; + bool proceed=true, msg_shown=false; + QString msg="", err_msg=""; + // check the file first + if ( IOutils::exists( this->configs_path ) ) { + if ( IOutils::checkFile( this->configs_path ) ) { + if ( ! IOutils::checkFile( this->configs_path, false, true ) ) { + // file not writable, try to assign permissions + std::filesystem::permissions( this->configs_path, + std::filesystem::perms::owner_write, + std::filesystem::perm_options::add, + err ); + if ( err.value() ) { + proceed = false; + QString file = ""; + if ( this->dialogs_level > 0 ) { + file = QString::fromStdString( this->configs_path ); + err_msg = QString::fromStdString( err.message() ); + } + DialogSec::errConfFileNotWritable( file, err_msg ); + msg_shown = true; + } + } + } else { + // the given path doesn't point to a file + proceed = DialogSec::choiceFileNotFile( QString::fromStdString( this->configs_path ) ); + if ( proceed ) { + proceed = IOutils::renameAsCopy( this->configs_path, err ); + if ( ! proceed ) { + QString path = ""; + if ( this->dialogs_level > 0 ) { + path = QString::fromStdString( this->configs_path ); + if ( err.value() ) { + err_msg = QString::fromStdString( err.message() ); + } + } + DialogSec::errRenaming( path, err_msg ); + msg_shown = true; + } + } + } + } else { + // file does not exists, check if at least the folder exists + const std::string base_path = this->basePath( this->configs_path ); + if ( IOutils::exists( base_path ) ) { + if ( IOutils::isDir( base_path ) ) { + if ( ! IOutils::checkDir( base_path, false, true ) ) { + // directory not writable, try to assign permissions + std::filesystem::permissions( base_path, + std::filesystem::perms::owner_write, + std::filesystem::perm_options::add, + err ); + if ( err.value() ) { + proceed = false; + QString file = ""; + if ( this->dialogs_level > 0 ) { + file = QString::fromStdString( base_path ); + err_msg = QString::fromStdString( err.message() ); + } + DialogSec::errConfDirNotWritable( file, err_msg ); + msg_shown = true; + } + } + } else { + // not a directory + proceed = DialogSec::choiceDirNotDir( QString::fromStdString( base_path ) ); + if ( proceed ) { + proceed = IOutils::renameAsCopy( base_path, err ); + if ( ! proceed ) { + QString path = ""; + if ( this->dialogs_level > 0 ) { + path = QString::fromStdString( base_path ); + err_msg = QString::fromStdString( err.message() ); + } + DialogSec::errRenaming( path, err_msg ); + msg_shown = true; + } else { + // make the new folder + proceed = IOutils::makeDir( base_path, err ); + if ( ! proceed ) { + msg = DialogSec::tr("Failed to create the configuration file's directory"); + if ( this->dialogs_level > 0 ) { + msg += ":\n"+QString::fromStdString( base_path ); + err_msg = QString::fromStdString( err.message() ); + } + } + } + } + } + } else { + // the folder does not exist too + proceed = IOutils::makeDir( base_path, err ); + if ( ! proceed ) { + msg = DialogSec::tr("Failed to create the configuration file's directory"); + if ( this->dialogs_level > 0 ) { + msg += ":\n"+QString::fromStdString( base_path ); + err_msg = QString::fromStdString( err.message() ); + } + } + } + } + if ( !proceed && !msg_shown ) { + DialogSec::errConfFailedWriting( msg, err_msg ); + } + + if ( proceed ) { + //// USER INTERFACE //// + std::string configs = ""; + configs += "\n\n[UI]"; + configs += "\nLanguage=" + this->language; + configs += "\nRememberGeometry=" + this->b2s.at( this->remember_window ); + configs += "\nGeometry=" + this->geometryToString(); + configs += "\nWindowTheme=" + std::to_string( this->window_theme_id ); + configs += "\nChartsTheme=" + std::to_string( this->charts_theme_id ); + configs += "\nIconsTheme=" + std::to_string( this->icons_theme_id ); + configs += "\nMainDialogLevel=" + std::to_string( this->dialogs_level ); + configs += "\nDefaultWebServer=" + std::to_string( this->default_ws ); + configs += "\nDatabaseDataPath=" + this->db_data_path; + configs += "\nDatabaseHashesPath=" + this->db_hashes_path; + configs += "\nDatabaseDoBackup=" + this->b2s.at( this->db_do_backup ); + configs += "\nDatabaseBackupsNumber=" + std::to_string( this->db_backups_number ); + //// TEXT BROWSER //// + configs += "\n\n[TextBrowser]"; + configs += "\nFont=" + std::to_string( this->ui->box_ConfTextBrowser_Font->currentIndex() ); + configs += "\nWideLines=" + this->b2s.at( this->TB.getWideLinesUsage() ); + configs += "\nColorScheme=" + std::to_string( this->TB.getColorSchemeID() ); + //// CRAPLOG //// + configs += "\n\n[Craplog]"; + configs += "\nCraplogDialogLevel=" + std::to_string( this->craplog.getDialogsLevel() ); + configs += "\nHideUsedFiles=" + this->b2s.at( this->hide_used_files ); + configs += "\nWarningSize=" + std::to_string( this->craplog.getWarningSize() ); + //// APACHE2 //// + configs += "\n\n[Apache2]"; + configs += "\nApacheLogsPath=" + this->craplog.getLogsPath( this->APACHE_ID ); + configs += "\nApacheLogsFormat=" + this->craplog.getLogsFormatString( this->APACHE_ID ); + configs += "\nApacheWarnlistMethod=" + this->list2string( this->craplog.getWarnlist( this->APACHE_ID, 11 ) ); + configs += "\nApacheWarnlistMethodUsed=" + this->b2s.at( this->craplog.isWarnlistUsed( this->APACHE_ID, 11 ) ); + configs += "\nApacheWarnlistURI=" + this->list2string( this->craplog.getWarnlist( this->APACHE_ID, 12 ) ); + configs += "\nApacheWarnlistURIUsed=" + this->b2s.at( this->craplog.isWarnlistUsed( this->APACHE_ID, 12 ) ); + configs += "\nApacheWarnlistClient=" + this->list2string( this->craplog.getWarnlist( this->APACHE_ID, 20 ) ); + configs += "\nApacheWarnlistClientUsed=" + this->b2s.at( this->craplog.isWarnlistUsed( this->APACHE_ID, 20 ) ); + configs += "\nApacheWarnlistUserAgent=" + this->list2string( this->craplog.getWarnlist( this->APACHE_ID, 21 ), true ); + configs += "\nApacheWarnlistUserAgentUsed=" + this->b2s.at( this->craplog.isWarnlistUsed( this->APACHE_ID, 21 ) ); + configs += "\nApacheBlacklistClient=" + this->list2string( this->craplog.getBlacklist( this->APACHE_ID, 20 ) ); + configs += "\nApacheBlacklistClientUsed=" + this->b2s.at( this->craplog.isBlacklistUsed( this->APACHE_ID, 20 ) ); + //// NGINX //// + configs += "\n\n[Nginx]"; + configs += "\nNginxLogsPath=" + this->craplog.getLogsPath( this->NGINX_ID ); + configs += "\nNginxLogsFormat=" + this->craplog.getLogsFormatString( this->NGINX_ID ); + configs += "\nNginxWarnlistMethod=" + this->list2string( this->craplog.getWarnlist( this->NGINX_ID, 11 ) ); + configs += "\nNginxWarnlistMethodUsed=" + this->b2s.at( this->craplog.isWarnlistUsed( this->NGINX_ID, 11 ) ); + configs += "\nNginxWarnlistURI=" + this->list2string( this->craplog.getWarnlist( this->NGINX_ID, 12 ) ); + configs += "\nNginxWarnlistURIUsed=" + this->b2s.at( this->craplog.isWarnlistUsed( this->NGINX_ID, 12 ) ); + configs += "\nNginxWarnlistClient=" + this->list2string( this->craplog.getWarnlist( this->NGINX_ID, 20 ) ); + configs += "\nNginxWarnlistClientUsed=" + this->b2s.at( this->craplog.isWarnlistUsed( this->NGINX_ID, 20 ) ); + configs += "\nNginxWarnlistUserAgent=" + this->list2string( this->craplog.getWarnlist( this->NGINX_ID, 21 ), true ); + configs += "\nNginxWarnlistUserAgentUsed=" + this->b2s.at( this->craplog.isWarnlistUsed( this->NGINX_ID, 21 ) ); + configs += "\nNginxBlacklistClient=" + this->list2string( this->craplog.getBlacklist( this->NGINX_ID, 20 ) ); + configs += "\nNginxBlacklistClientUsed=" + this->b2s.at( this->craplog.isBlacklistUsed( this->NGINX_ID, 20 ) ); + //// IIS //// + configs += "\n\n[IIS]"; + configs += "\nIisLogsPath=" + this->craplog.getLogsPath( this->IIS_ID ); + std::string module = "0"; + if ( this->ui->radio_ConfIis_Format_NCSA->isChecked() ) { + module = "1"; + } else if ( this->ui->radio_ConfIis_Format_IIS->isChecked() ) { + module = "2"; + } + configs += "\nIisLogsModule=" + module; + configs += "\nIisLogsFormat=" + this->craplog.getLogsFormatString( this->IIS_ID ); + configs += "\nIisWarnlistMethod=" + this->list2string( this->craplog.getWarnlist( this->IIS_ID, 11 ) ); + configs += "\nIisWarnlistMethodUsed=" + this->b2s.at( this->craplog.isWarnlistUsed( this->IIS_ID, 11 ) ); + configs += "\nIisWarnlistURI=" + this->list2string( this->craplog.getWarnlist( this->IIS_ID, 12 ) ); + configs += "\nIisWarnlistURIUsed=" + this->b2s.at( this->craplog.isWarnlistUsed( this->IIS_ID, 12 ) ); + configs += "\nIisWarnlistClient=" + this->list2string( this->craplog.getWarnlist( this->IIS_ID, 20 ) ); + configs += "\nIisWarnlistClientUsed=" + this->b2s.at( this->craplog.isWarnlistUsed( this->IIS_ID, 20 ) ); + configs += "\nIisWarnlistUserAgent=" + this->list2string( this->craplog.getWarnlist( this->IIS_ID, 21 ), true ); + configs += "\nIisWarnlistUserAgentUsed=" + this->b2s.at( this->craplog.isWarnlistUsed( this->IIS_ID, 21 ) ); + configs += "\nIisBlacklistClient=" + this->list2string( this->craplog.getBlacklist( this->IIS_ID, 20 ) ); + configs += "\nIisBlacklistClientUsed=" + this->b2s.at( this->craplog.isBlacklistUsed( this->IIS_ID, 20 ) ); + //// CRAPVIEW //// + configs += "\n\n[Crapview]"; + configs += "\nCrapviewDialogLevel=" + std::to_string( this->crapview.getDialogsLevel() ); + + // write on file + try { + IOutils::writeOnFile( this->configs_path, configs ); + + } catch ( const std::ios_base::failure&/* err*/ ) { + // failed writing + DialogSec::errGeneric( DialogSec::tr("An error occured while writing the configuration file") ); + } catch (...) { + // something failed + DialogSec::errGeneric( DialogSec::tr("An error occured while preparing the configuration file's data") ); + } + } +} + + +void MainWindow::backupDatabase() +{ + bool proceed = true; + std::error_code err; + QString err_msg = ""; + if ( IOutils::checkFile( this->db_data_path+"/collection.db" ) ) { + // db exists and is a file + const std::string path = this->db_data_path+"/backups"; + if ( std::filesystem::exists( path ) ) { + if ( !std::filesystem::is_directory( path, err ) ) { + // exists but it's not a directory, rename as copy and make a new one + proceed = DialogSec::choiceDirNotDir( QString::fromStdString( path ) ); + if ( proceed ) { + proceed = IOutils::renameAsCopy( path, err ); + if ( ! proceed ) { + QString p = ""; + if ( this->dialogs_level > 0 ) { + p = QString::fromStdString( path ); + if ( err.value() ) { + err_msg = QString::fromStdString( err.message() ); + } + } + DialogSec::errRenaming( p, err_msg ); + } else { + // sucesfully renamed, make the new one + proceed = IOutils::makeDir( path, err ); + if ( ! proceed ) { + QString msg = DialogSec::tr("Failed to create the database backups' directory"); + if ( this->dialogs_level > 0 ) { + msg += ":\n"+QString::fromStdString( path ); + if ( err.value() ) { + err_msg = QString::fromStdString( err.message() ); + } + } + DialogSec::errFailedMakeDir( msg, err_msg ); + } + } + } + } + } else { + // backups directory doesn't exists, make it + proceed = IOutils::makeDir( path, err ); + if ( ! proceed ) { + QString msg = DialogSec::tr("Failed to create the database backups' directory"); + if ( this->dialogs_level > 0 ) { + msg += ":\n"+QString::fromStdString( path ); + if ( err.value() ) { + err_msg = QString::fromStdString( err.message() ); + } + } + DialogSec::errFailedMakeDir( msg, err_msg ); + } + } + + }/* else { + // db doesn't exists or is not a file + }*/ + + if ( proceed ) { + // copy the database to a new file + proceed = std::filesystem::copy_file( + this->db_data_path+"/collection.db", + this->db_data_path+"/backups/collection.db.0", + std::filesystem::copy_options::update_existing, + err ); + if ( ! proceed ) { + // failed to copy + if ( err.value() ) { + err_msg = QString::fromStdString( err.message() ); + } + DialogSec::errDatabaseFailedBackup( DialogSec::tr( "Failed to copy the database file" ), err_msg ); + } else { + // succesfully copied, now rename the already existing copies (up to the choosen number of copies) + std::string path, new_path; + path = this->db_data_path+"/backups/collection.db."+std::to_string(this->db_backups_number); + if ( std::filesystem::exists( path ) ) { + std::ignore = std::filesystem::remove_all( path, err ); + if ( err.value() ) { + err_msg = QString::fromStdString( err.message() ); + proceed = false; + } else { + proceed = ! std::filesystem::exists( path ); + } + if ( ! proceed ) { + DialogSec::errDatabaseFailedBackup( DialogSec::tr( "Failed to update the backups" ), err_msg ); + } + } + if ( proceed ) { + // cascade rename + for ( int n=this->db_backups_number-1; n>=0; n-- ) { + path = this->db_data_path+"/backups/collection.db."+std::to_string( n ); + if ( std::filesystem::exists( path ) ) { + new_path = this->db_data_path+"/backups/collection.db."+std::to_string( n+1 ); + std::filesystem::rename( path, new_path, err ); + if ( err.value() ) { + err_msg = QString::fromStdString( err.message() ); + proceed = false; + } else { + proceed = ! std::filesystem::exists( path ); + } + } + if ( ! proceed ) { + // seems it failed to rename + DialogSec::errDatabaseFailedBackup( DialogSec::tr( "Failed to update the backups" ), err_msg ); + break; + } + } + } + } + } +} + + +const std::string MainWindow::geometryToString() +{ + QRect geometry = this->geometry(); + std::string string = ""; + string += std::to_string( geometry.x() ); + string += ","; + string += std::to_string( geometry.y() ); + string += ","; + string += std::to_string( geometry.width() ); + string += ","; + string += std::to_string( geometry.height() ); + string += ","; + string += this->b2s.at( this->isMaximized() ); + return string; +} +void MainWindow::geometryFromString( const std::string& geometry ) +{ + std::vector aux; + StringOps::splitrip( aux, geometry, "," ); + QRect new_geometry; + new_geometry.setRect( std::stoi(aux.at(0)), std::stoi(aux.at(1)), std::stoi(aux.at(2)), std::stoi(aux.at(3)) ); + this->setGeometry( new_geometry ); + if ( aux.at(4) == "true" ) { + this->showMaximized(); + } +} + + +const std::string MainWindow::list2string( const std::vector& list, const bool& user_agent ) +{ + std::string string; + if ( user_agent ) { + for ( const std::string& str : list ) { + string += StringOps::replace( str, " ", "%@#" ) + " "; + } + } else { + for ( const std::string& str : list ) { + string += str + " "; + } + } + return string; +} +const std::vector MainWindow::string2list( const std::string& string, const bool& user_agent ) +{ + std::vector list, aux; + StringOps::splitrip( aux, string, " " ); + if ( user_agent ) { + for ( const std::string& str : aux ) { + list.push_back( StringOps::replace( str, "%@#", " " ) ); + } + } else { + for ( const std::string& str : aux ) { + list.push_back( str ); + } + } + return list; +} + + +////////////////// +//// GRAPHICS //// +////////////////// +void MainWindow::detectIconsTheme() +{ + switch ( this->window_theme_id ) { + case 0: + // system default, use window color to determine the theme + if ( this->palette().window().color().black() > 127 ) { + this->icons_theme = "light"; + } else { + this->icons_theme = "dark"; + } + break; + case 1: + case 3: + // ash / herb + this->icons_theme = "light"; + break; + case 2: + case 4: + // candy / powder + this->icons_theme = "dark"; + break; + default: + throw GenericException( "Unexpected WindowTheme ID: "+std::to_string(this->window_theme_id), true ); + break; + } +} + + +void MainWindow::updateUiTheme() +{ + // window and fonts + switch ( this->window_theme_id ) { + case 0: + // window first + this->setStyleSheet(""); + // icons last + this->updateUiIcons(); + break; + case 1: case 2: case 3: case 4: + { + // icons first + this->updateUiIcons(); + // window last + QString ss; + StyleSec::getStyleSheet( ss, this->icons_theme, this->window_theme_id ); + this->setStyleSheet( ss ); + break; + } + default: + // wrong + throw GenericException( "Unexpected WindowTheme ID: "+std::to_string(this->window_theme_id), true ); + break; + } + // fonts + this->updateUiFonts(); +} + +void MainWindow::updateUiIcons() +{ + const QString old_icons_theme = this->icons_theme; + switch ( this->icons_theme_id ) { + case 0: + this->detectIconsTheme(); + break; + case 1: + this->icons_theme = "light"; + break; + case 2: + this->icons_theme = "dark"; + break; + default: + throw GenericException( "Unexpected IconSet index: "+std::to_string(this->icons_theme_id), true ); + break; + } + + if ( this->icons_theme != old_icons_theme ) { + // main tabs + const int m_index = this->ui->stacked_Tabs_Pages->currentIndex(); + this->ui->button_Tab_Log->setIcon( + QIcon(QString(":/icons/icons/%1/log_%2.png").arg( + this->icons_theme, + (m_index==0) ? "on" : "off" )) ); + this->ui->button_Tab_View->setIcon( + QIcon(QString(":/icons/icons/%1/view_%2.png").arg( + this->icons_theme, + (m_index==1) ? "on" : "off" )) ); + this->ui->button_Tab_Conf->setIcon( + QIcon(QString(":/icons/icons/%1/conf_%2.png").arg( + this->icons_theme, + (m_index==2) ? "on" : "off" )) ); + // view logs + this->ui->button_LogFiles_ViewFile->setIcon( + QIcon(QString(":/icons/icons/%1/show_file.png").arg(this->icons_theme)) ); + this->ui->button_LogFiles_RefreshList->setIcon( + QIcon(QString(":/icons/icons/%1/refresh.png").arg(this->icons_theme)) ); + // parse logs + this->ui->icon_MakeStats_Size->setPixmap( + QPixmap(QString(":/icons/icons/%1/mk_size.png").arg(this->icons_theme)) ); + this->ui->icon_MakeStats_Lines->setPixmap( + QPixmap(QString(":/icons/icons/%1/mk_lines.png").arg(this->icons_theme)) ); + this->ui->icon_MakeStats_Time->setPixmap( + QPixmap(QString(":/icons/icons/%1/mk_time.png").arg(this->icons_theme)) ); + this->ui->icon_MakeStats_Speed->setPixmap( + QPixmap(QString(":/icons/icons/%1/mk_speed.png").arg(this->icons_theme)) ); + // stats + const int s_index = this->ui->stacked_Stats_Pages->currentIndex(); + // stats warn + this->ui->button_Tab_StatsWarn->setIcon( + QIcon(QString(":/icons/icons/%1/warn_%2.png").arg( + this->icons_theme, + (s_index==0) ? "on" : "off" )) ); + this->ui->button_StatsWarn_Draw->setIcon( + QIcon(QString(":/icons/icons/%1/draw.png").arg(this->icons_theme)) ); + this->ui->button_StatsWarn_Update->setIcon( + QIcon(QString(":/icons/icons/%1/save.png").arg(this->icons_theme)) ); + // stats speed + this->ui->button_Tab_StatsSpeed->setIcon( + QIcon(QString(":/icons/icons/%1/speed_%2.png").arg( + this->icons_theme, + (s_index==1) ? "on" : "off" )) ); + this->ui->button_StatsSpeed_Draw->setIcon( + QIcon(QString(":/icons/icons/%1/draw.png").arg(this->icons_theme)) ); + // stats count + this->ui->button_Tab_StatsCount->setIcon( + QIcon(QString(":/icons/icons/%1/count_%2.png").arg( + this->icons_theme, + (s_index==2) ? "on" : "off" )) ); + // stats daytime + this->ui->button_Tab_StatsDay->setIcon( + QIcon(QString(":/icons/icons/%1/daytime_%2.png").arg( + this->icons_theme, + (s_index==3) ? "on" : "off" )) ); + this->ui->button_StatsDay_Draw->setIcon( + QIcon(QString(":/icons/icons/%1/draw.png").arg(this->icons_theme)) ); + // stats relational + this->ui->button_Tab_StatsRelat->setIcon( + QIcon(QString(":/icons/icons/%1/relational_%2.png").arg( + this->icons_theme, + (s_index==4) ? "on" : "off" )) ); + this->ui->button_StatsRelat_Draw->setIcon( + QIcon(QString(":/icons/icons/%1/draw.png").arg(this->icons_theme)) ); + // stats globals + this->ui->button_Tab_StatsGlob->setIcon( + QIcon(QString(":/icons/icons/%1/global_%2.png").arg( + this->icons_theme, + (s_index==5) ? "on" : "off" )) ); + // configs + this->ui->button_ConfDatabases_Data_Save->setIcon( + QIcon(QString(":/icons/icons/%1/save.png").arg(this->icons_theme)) ); + this->ui->button_ConfDatabases_Hashes_Save->setIcon( + QIcon(QString(":/icons/icons/%1/save.png").arg(this->icons_theme)) ); + this->ui->button_ConfApache_Path_Save->setIcon( + QIcon(QString(":/icons/icons/%1/save.png").arg(this->icons_theme)) ); + this->ui->button_ConfApache_Format_Save->setIcon( + QIcon(QString(":/icons/icons/%1/save.png").arg(this->icons_theme)) ); + this->ui->button_ConfApache_Format_Help->setIcon( + QIcon(QString(":/icons/icons/%1/help.png").arg(this->icons_theme)) ); + this->ui->button_ConfNginx_Path_Save->setIcon( + QIcon(QString(":/icons/icons/%1/save.png").arg(this->icons_theme)) ); + this->ui->button_ConfNginx_Format_Save->setIcon( + QIcon(QString(":/icons/icons/%1/save.png").arg(this->icons_theme)) ); + this->ui->button_ConfNginx_Format_Help->setIcon( + QIcon(QString(":/icons/icons/%1/help.png").arg(this->icons_theme)) ); + this->ui->button_ConfIis_Path_Save->setIcon( + QIcon(QString(":/icons/icons/%1/save.png").arg(this->icons_theme)) ); + this->ui->button_ConfIis_Format_Save->setIcon( + QIcon(QString(":/icons/icons/%1/save.png").arg(this->icons_theme)) ); + this->ui->button_ConfIis_Format_Help->setIcon( + QIcon(QString(":/icons/icons/%1/help.png").arg(this->icons_theme)) ); + } +} + +void MainWindow::updateUiFonts() +{ + const QFont &small_font = this->FONTS.at( "main_small" ); + const QFont &font = this->FONTS.at( "main" ); + const QFont &big_font = this->FONTS.at( "main_big" ); + QFont menu_font = this->FONTS.at( "main_small" ); + menu_font.setPointSizeF( this->font_size_small+1.5 ); + QFont header_font = this->FONTS.at( "main_small" ); + header_font.setPointSizeF( this->font_size_small+2 ); + // menu + this->ui->menuLanguage->setFont( menu_font ); + this->ui->actionEnglish->setFont( menu_font ); + this->ui->actionEspanol->setFont( menu_font ); + this->ui->actionFrancais->setFont( menu_font ); + this->ui->actionItaliano->setFont( menu_font ); + this->ui->menuTools->setFont( menu_font ); + this->ui->actionBlockNote->setFont( menu_font ); + this->ui->menuUtilities->setFont( menu_font ); + this->ui->actionInfos->setFont( menu_font ); + this->ui->actionCheckUpdates->setFont( menu_font ); + this->ui->menuGames->setFont( menu_font ); + this->ui->actionCrissCross->setFont( menu_font ); + this->ui->actionSnake->setFont( menu_font ); + // log files view + this->ui->button_LogFiles_Apache->setFont( font ); + this->ui->button_LogFiles_Nginx->setFont( font ); + this->ui->button_LogFiles_Iis->setFont( font ); + this->ui->checkBox_LogFiles_CheckAll->setFont( small_font ); + this->ui->listLogFiles->setFont( font ); + this->ui->listLogFiles->headerItem()->setFont( 0, header_font ); + this->ui->listLogFiles->headerItem()->setFont( 1, header_font ); + this->ui->textLogFiles->setFont( this->TB.getFont() ); + // log files parse + this->ui->label_MakeStats_Size->setFont( font ); + this->ui->label_MakeStats_Lines->setFont( font ); + this->ui->label_MakeStats_Time->setFont( font ); + this->ui->label_MakeStats_Speed->setFont( font ); + this->ui->button_MakeStats_Start->setFont( big_font ); + // stats warn + this->ui->label_StatsWarn_WebServer->setFont( font ); + this->ui->box_StatsWarn_WebServer->setFont( font ); + this->ui->label_StatsWarn_Year->setFont( font ); + this->ui->box_StatsWarn_Year->setFont( font ); + this->ui->label_StatsWarn_Month->setFont( font ); + this->ui->box_StatsWarn_Month->setFont( font ); + this->ui->label_StatsWarn_Day->setFont( font ); + this->ui->box_StatsWarn_Day->setFont( font ); + this->ui->checkBox_StatsWarn_Hour->setFont( font ); + this->ui->box_StatsWarn_Hour->setFont( font ); + this->ui->table_StatsWarn->setFont( font ); + this->ui->table_StatsWarn->horizontalHeader()->setFont( header_font ); + // stats speed + this->ui->box_StatsSpeed_WebServer->setFont( font ); + this->ui->label_StatsSpeed_Year->setFont( font ); + this->ui->box_StatsSpeed_Year->setFont( font ); + this->ui->label_StatsSpeed_Month->setFont( font ); + this->ui->box_StatsSpeed_Month->setFont( font ); + this->ui->label_StatsSpeed_Day->setFont( font ); + this->ui->box_StatsSpeed_Day->setFont( font ); + this->ui->label_StatsSpeed_Filters->setFont( big_font ); + this->ui->label_StatsSpeed_Protocol->setFont( font ); + this->ui->inLine_StatsSpeed_Protocol->setFont( font ); + this->ui->label_StatsSpeed_Method->setFont( font ); + this->ui->inLine_StatsSpeed_Method->setFont( font ); + this->ui->label_StatsSpeed_Uri->setFont( font ); + this->ui->inLine_StatsSpeed_Uri->setFont( font ); + this->ui->label_StatsSpeed_Query->setFont( font ); + this->ui->inLine_StatsSpeed_Query->setFont( font ); + this->ui->label_StatsSpeed_Response->setFont( font ); + this->ui->inLine_StatsSpeed_Response->setFont( font ); + this->ui->table_StatsSpeed->setFont( font ); + this->ui->table_StatsSpeed->horizontalHeader()->setFont( header_font ); + // stats count + this->ui->box_StatsCount_WebServer->setFont( font ); + this->ui->label_StatsCount_Year->setFont( font ); + this->ui->box_StatsCount_Year->setFont( font ); + this->ui->label_StatsCount_Month->setFont( font ); + this->ui->box_StatsCount_Month->setFont( font ); + this->ui->label_StatsCount_Day->setFont( font ); + this->ui->box_StatsCount_Day->setFont( font ); + this->ui->button_StatsCount_Protocol->setFont( font ); + this->ui->button_StatsCount_Method->setFont( font ); + this->ui->button_StatsCount_Uri->setFont( font ); + this->ui->button_StatsCount_Query->setFont( font ); + this->ui->button_StatsCount_Response->setFont( font ); + this->ui->button_StatsCount_Referrer->setFont( font ); + this->ui->button_StatsCount_Cookie->setFont( font ); + this->ui->button_StatsCount_UserAgent->setFont( font ); + this->ui->button_StatsCount_Client->setFont( font ); + this->ui->table_StatsCount->setFont( font ); + this->ui->table_StatsCount->horizontalHeader()->setFont( header_font ); + // stats day + this->ui->box_StatsDay_WebServer->setFont( font ); + this->ui->label_StatsDay_From->setFont( font ); + this->ui->checkBox_StatsDay_Period->setFont( font ); + this->ui->label_StatsDay_Year->setFont( font ); + this->ui->box_StatsDay_FromYear->setFont( font ); + this->ui->box_StatsDay_ToYear->setFont( font ); + this->ui->label_StatsDay_Month->setFont( font ); + this->ui->box_StatsDay_FromMonth->setFont( font ); + this->ui->box_StatsDay_ToMonth->setFont( font ); + this->ui->label_StatsDay_Day->setFont( font ); + this->ui->box_StatsDay_FromDay->setFont( font ); + this->ui->box_StatsDay_ToDay->setFont( font ); + this->ui->label_StatsDay_LogsField->setFont( font ); + this->ui->box_StatsDay_LogsField->setFont( font ); + this->ui->label_StatsDay_Filter->setFont( font ); + this->ui->inLine_StatsDay_Filter->setFont( font ); + // stats relat + this->ui->box_StatsRelat_WebServer->setFont( font ); + this->ui->label_StatsRelat_From->setFont( font ); + this->ui->label_StatsRelat_To->setFont( font ); + this->ui->box_StatsRelat_FromYear->setFont( font ); + this->ui->box_StatsRelat_ToYear->setFont( font ); + this->ui->box_StatsRelat_FromMonth->setFont( font ); + this->ui->box_StatsRelat_ToMonth->setFont( font ); + this->ui->box_StatsRelat_FromDay->setFont( font ); + this->ui->box_StatsRelat_ToDay->setFont( font ); + this->ui->label_StatsRelat_LogsField_1->setFont( font ); + this->ui->box_StatsRelat_LogsField_1->setFont( font ); + this->ui->label_StatsRelat_Filter_1->setFont( font ); + this->ui->inLine_StatsRelat_Filter_1->setFont( font ); + this->ui->label_StatsRelat_LogsField_2->setFont( font ); + this->ui->box_StatsRelat_LogsField_2->setFont( font ); + this->ui->label_StatsRelat_Filter_2->setFont( font ); + this->ui->inLine_StatsRelat_Filter_2->setFont( font ); + // stats glob + this->ui->button_StatsGlob_Apache->setFont( font ); + this->ui->button_StatsGlob_Nginx->setFont( font ); + this->ui->button_StatsGlob_Iis->setFont( font ); + this->ui->label_StatsGlob_Recur->setFont( big_font ); + this->ui->label_StatsGlob_Recur_Protocol->setFont( font ); + this->ui->label_StatsGlob_Recur_Protocol_String->setFont( font ); + this->ui->label_StatsGlob_Recur_Protocol_Count->setFont( font ); + this->ui->label_StatsGlob_Recur_Method->setFont( font ); + this->ui->label_StatsGlob_Recur_Method_String->setFont( font ); + this->ui->label_StatsGlob_Recur_Method_Count->setFont( font ); + this->ui->label_StatsGlob_Recur_URI->setFont( font ); + this->ui->label_StatsGlob_Recur_URI_String->setFont( font ); + this->ui->label_StatsGlob_Recur_URI_Count->setFont( font ); + this->ui->label_StatsGlob_Recur_UserAgent->setFont( font ); + this->ui->label_StatsGlob_Recur_UserAgent_String->setFont( font ); + this->ui->label_StatsGlob_Recur_UserAgent_Count->setFont( font ); + this->ui->label_StatsGlob_Perf->setFont( big_font ); + this->ui->label_StatsGlob_Perf_Time->setFont( font ); + this->ui->label_StatsGlob_Perf_Time_Mean->setFont( font ); + this->ui->label_StatsGlob_Perf_Time_Max->setFont( font ); + this->ui->label_StatsGlob_Perf_Sent->setFont( font ); + this->ui->label_StatsGlob_Perf_Sent_Mean->setFont( font ); + this->ui->label_StatsGlob_Perf_Sent_Max->setFont( font ); + this->ui->label_StatsGlob_Perf_Received->setFont( font ); + this->ui->label_StatsGlob_Perf_Received_Mean->setFont( font ); + this->ui->label_StatsGlob_Perf_Received_Max->setFont( font ); + this->ui->label_StatsGlob_Traffic->setFont( big_font ); + this->ui->label_StatsGlob_Traffic_Date->setFont( font ); + this->ui->label_StatsGlob_Traffic_Date_String->setFont( font ); + this->ui->label_StatsGlob_Traffic_Date_Count->setFont( font ); + this->ui->label_StatsGlob_Traffic_Day->setFont( font ); + this->ui->label_StatsGlob_Traffic_Day_String->setFont( font ); + this->ui->label_StatsGlob_Traffic_Day_Count->setFont( font ); + this->ui->label_StatsGlob_Traffic_Hour->setFont( font ); + this->ui->label_StatsGlob_Traffic_Hour_String->setFont( font ); + this->ui->label_StatsGlob_Traffic_Hour_Count->setFont( font ); + this->ui->label_StatsGlob_Work->setFont( big_font ); + this->ui->label_StatsGlob_Work_Req->setFont( font ); + this->ui->label_StatsGlob_Work_Req_Count->setFont( font ); + this->ui->label_StatsGlob_Work_Time->setFont( font ); + this->ui->label_StatsGlob_Work_Time_Count->setFont( font ); + this->ui->label_StatsGlob_Work_Sent->setFont( font ); + this->ui->label_StatsGlob_Work_Sent_Count->setFont( font ); + // configs tab + this->ui->ConfTabs->tabBar()->setFont( big_font ); + this->ui->tabs_ConfGeneral->tabBar()->setFont( font ); + this->ui->tabs_ConfLogs->tabBar()->setFont( font ); + this->ui->tabs_ConfApache->tabBar()->setFont( font ); + this->ui->tabs_ConfNginx->tabBar()->setFont( font ); + this->ui->tabs_ConfIis->tabBar()->setFont( font ); + // conf window + this->ui->label_ConfWindow_Geometry->setFont( big_font ); + this->ui->checkBox_ConfWindow_Geometry->setFont( font ); + this->ui->label_ConfWindow_Theme->setFont( big_font ); + this->ui->box_ConfWindow_Theme->setFont( font ); + this->ui->label_ConfWindow_Icons->setFont( big_font ); + this->ui->box_ConfWindow_Icons->setFont( font ); + // conf dialogs + this->ui->label_ConfDialogs_Level->setFont( big_font ); + this->ui->label_ConfDialogs_General->setFont( font ); + this->ui->label_ConfDialogs_Logs->setFont( font ); + this->ui->label_ConfDialogs_Stats->setFont( font ); + this->ui->label_ConfDialogs_Essential->setFont( small_font ); + this->ui->label_ConfDialogs_Normal->setFont( small_font ); + this->ui->label_ConfDialogs_Explanatory->setFont( small_font ); + // conf text-browser + this->ui->label_ConfTextBrowser_Font->setFont( big_font ); + this->ui->box_ConfTextBrowser_Font->setFont( font ); + this->ui->label_ConfTextBrowser_Lines->setFont( big_font ); + this->ui->checkBox_ConfTextBrowser_WideLines->setFont( font ); + this->ui->label_ConfTextBrowser_ColorScheme->setFont( big_font ); + this->ui->box_ConfTextBrowser_ColorScheme->setFont( font ); + this->ui->label_ConfTextBrowser_Preview->setFont( big_font ); + this->ui->textBrowser_ConfTextBrowser_Preview->setFont( this->TB.getFont() ); + // conf charts + this->ui->label_ConfCharts_Theme->setFont( big_font ); + this->ui->box_ConfCharts_Theme->setFont( font ); + this->ui->label_ConfCharts_Preview->setFont( big_font ); + // conf databases + this->ui->label_ConfDatabases_Paths->setFont( big_font ); + this->ui->label_ConfDatabases_Data->setFont( font ); + this->ui->inLine_ConfDatabases_Data_Path->setFont( font ); + this->ui->label_ConfDatabases_Hashes->setFont( font ); + this->ui->inLine_ConfDatabases_Hashes_Path->setFont( font ); + this->ui->label_ConfDatabases_Backups->setFont( big_font ); + this->ui->checkBox_ConfDatabases_DoBackup->setFont( font ); + this->ui->spinBox_ConfDatabases_NumBackups->setFont( font ); + // conf logs default + this->ui->label_ConfDefaults_WebServer->setFont( big_font ); + this->ui->radio_ConfDefaults_Apache->setFont( font ); + this->ui->radio_ConfDefaults_Nginx->setFont( font ); + this->ui->radio_ConfDefaults_Iis->setFont( font ); + // conf logs control + this->ui->label_ConfControl_Usage->setFont( big_font ); + this->ui->checkBox_ConfControl_Usage->setFont( font ); + this->ui->label_ConfControl_Size->setFont( big_font ); + this->ui->checkBox_ConfControl_Size->setFont( font ); + this->ui->spinBox_ConfControl_Size->setFont( font ); + // conf apache + this->ui->label_ConfApache_Path_Path->setFont( font ); + this->ui->inLine_ConfApache_Path_String->setFont( font ); + this->ui->label_ConfApache_Format_String->setFont( font ); + this->ui->inLine_ConfApache_Format_String->setFont( font ); + this->ui->button_ConfApache_Format_Sample->setFont( font ); + this->ui->preview_ConfApache_Format_Sample->setFont( this->TB.getFont() ); + this->ui->box_ConfApache_Warnlist_Field->setFont( font ); + this->ui->checkBox_ConfApache_Warnlist_Used->setFont( font ); + this->ui->inLine_ConfApache_Warnlist_String->setFont( font ); + this->ui->list_ConfApache_Warnlist_List->setFont( font ); + this->ui->box_ConfApache_Blacklist_Field->setFont( font ); + this->ui->checkBox_ConfApache_Blacklist_Used->setFont( font ); + this->ui->inLine_ConfApache_Blacklist_String->setFont( font ); + this->ui->list_ConfApache_Blacklist_List->setFont( font ); + // conf nginx + this->ui->label_ConfNginx_Path_Path->setFont( font ); + this->ui->inLine_ConfNginx_Path_String->setFont( font ); + this->ui->label_ConfNginx_Format_String->setFont( font ); + this->ui->inLine_ConfNginx_Format_String->setFont( font ); + this->ui->button_ConfNginx_Format_Sample->setFont( font ); + this->ui->preview_ConfNginx_Format_Sample->setFont( this->TB.getFont() ); + this->ui->box_ConfNginx_Warnlist_Field->setFont( font ); + this->ui->checkBox_ConfNginx_Warnlist_Used->setFont( font ); + this->ui->inLine_ConfNginx_Warnlist_String->setFont( font ); + this->ui->list_ConfNginx_Warnlist_List->setFont( font ); + this->ui->box_ConfNginx_Blacklist_Field->setFont( font ); + this->ui->checkBox_ConfNginx_Blacklist_Used->setFont( font ); + this->ui->inLine_ConfNginx_Blacklist_String->setFont( font ); + this->ui->list_ConfNginx_Blacklist_List->setFont( font ); + // conf iis + this->ui->label_ConfIis_Path_Path->setFont( font ); + this->ui->inLine_ConfIis_Path_String->setFont( font ); + this->ui->label_ConfIis_Format_String->setFont( font ); + this->ui->inLine_ConfIis_Format_String->setFont( font ); + this->ui->button_ConfIis_Format_Sample->setFont( font ); + this->ui->preview_ConfIis_Format_Sample->setFont( this->TB.getFont() ); + this->ui->box_ConfIis_Warnlist_Field->setFont( font ); + this->ui->checkBox_ConfIis_Warnlist_Used->setFont( font ); + this->ui->inLine_ConfIis_Warnlist_String->setFont( font ); + this->ui->list_ConfIis_Warnlist_List->setFont( font ); + this->ui->box_ConfIis_Blacklist_Field->setFont( font ); + this->ui->checkBox_ConfIis_Blacklist_Used->setFont( font ); + this->ui->inLine_ConfIis_Blacklist_String->setFont( font ); + this->ui->list_ConfIis_Blacklist_List->setFont( font ); +} + + + + +////////////////// +//// LANGUAGE //// +////////////////// +void MainWindow::updateUiLanguage() +{ + // remove the old translator + QCoreApplication::removeTranslator( &this->translator ); + if ( this->translator.load( QString(":/translations/%1").arg(QString::fromStdString( this->language )) ) ) { + // apply the new translator + QCoreApplication::installTranslator( &this->translator ); + this->ui->retranslateUi( this ); + // stats warn table header + { + const QStringList h = { + this->crapview.getLogFieldString(0), + TR::tr( WORDS__DATE.c_str() ), + TR::tr( WORDS__TIME.c_str() ), + this->crapview.getLogFieldString(10), + this->crapview.getLogFieldString(11), + this->crapview.getLogFieldString(12), + this->crapview.getLogFieldString(13), + this->crapview.getLogFieldString(14), + this->crapview.getLogFieldString(18), + this->crapview.getLogFieldString(22), + this->crapview.getLogFieldString(21), + this->crapview.getLogFieldString(20), + this->crapview.getLogFieldString(17), + this->crapview.getLogFieldString(16), + this->crapview.getLogFieldString(15), + "rowid" }; + this->ui->table_StatsWarn->setColumnCount( h.size() ); + this->ui->table_StatsWarn->setHorizontalHeaderLabels( h ); + } + // stats speed table header + { + const QStringList h = { + this->crapview.getLogFieldString(15), + this->crapview.getLogFieldString(12), + this->crapview.getLogFieldString(13), + this->crapview.getLogFieldString(11), + this->crapview.getLogFieldString(10), + this->crapview.getLogFieldString(14), + TR::tr( WORDS__TIME.c_str() ) }; + this->ui->table_StatsSpeed->setColumnCount( h.size() ); + this->ui->table_StatsSpeed->setHorizontalHeaderLabels( h ); + } + // stats count buttons + this->ui->button_StatsCount_Protocol->setText( this->crapview.getLogFieldString( 10 ) ); + this->ui->button_StatsCount_Method->setText( this->crapview.getLogFieldString( 11 ) ); + this->ui->button_StatsCount_Uri->setText( this->crapview.getLogFieldString( 12 ) ); + this->ui->button_StatsCount_Query->setText( this->crapview.getLogFieldString( 13 ) ); + this->ui->button_StatsCount_Response->setText( this->crapview.getLogFieldString( 14 ) ); + this->ui->button_StatsCount_Referrer->setText( this->crapview.getLogFieldString( 18 ) ); + this->ui->button_StatsCount_Cookie->setText( this->crapview.getLogFieldString( 22 ) ); + this->ui->button_StatsCount_UserAgent->setText( this->crapview.getLogFieldString( 21 ) ); + this->ui->button_StatsCount_Client->setText( this->crapview.getLogFieldString( 20 ) ); + // configs warn/black-lists + { + const QStringList wl = { + this->crapview.getLogFieldString( 11 ), + this->crapview.getLogFieldString( 12 ), + this->crapview.getLogFieldString( 21 ), + this->crapview.getLogFieldString( 20 ) }; + const QStringList bl = { + this->crapview.getLogFieldString( 20 ) }; + // set + this->ui->box_ConfApache_Warnlist_Field->clear(); + this->ui->box_ConfApache_Warnlist_Field->addItems( wl ); + this->ui->box_ConfNginx_Warnlist_Field->clear(); + this->ui->box_ConfNginx_Warnlist_Field->addItems( wl ); + this->ui->box_ConfIis_Warnlist_Field->clear(); + this->ui->box_ConfIis_Warnlist_Field->addItems( wl ); + this->ui->box_ConfApache_Blacklist_Field->clear(); + this->ui->box_ConfApache_Blacklist_Field->addItems( bl ); + this->ui->box_ConfNginx_Blacklist_Field->clear(); + this->ui->box_ConfNginx_Blacklist_Field->addItems( bl ); + this->ui->box_ConfIis_Blacklist_Field->clear(); + this->ui->box_ConfIis_Blacklist_Field->addItems( bl ); + } + // renew the dates + this->on_box_StatsWarn_WebServer_currentIndexChanged( this->ui->box_StatsWarn_WebServer->currentIndex() ); + this->on_box_StatsSpeed_WebServer_currentIndexChanged( this->ui->box_StatsSpeed_WebServer->currentIndex() ); + this->on_box_StatsCount_WebServer_currentIndexChanged( this->ui->box_StatsCount_WebServer->currentIndex() ); + this->on_box_StatsDay_WebServer_currentIndexChanged( this->ui->box_StatsDay_WebServer->currentIndex() ); + this->on_box_StatsRelat_WebServer_currentIndexChanged( this->ui->box_StatsRelat_WebServer->currentIndex() ); + } +} + + +////////////////////////// +//// INTEGRITY CHECKS //// +////////////////////////// +void MainWindow::wait_ActiveWindow() +{ + if ( ! this->isActiveWindow() ) { + QCoreApplication::processEvents( QEventLoop::AllEvents, 250 ); + } else { + this->waiter_timer->stop(); + this->makeInitialChecks(); + } +} +void MainWindow::makeInitialChecks() +{ + bool ok = true; + std::error_code err; + QString err_msg = ""; + // check that the sqlite plugin is available + if ( ! QSqlDatabase::drivers().contains("QSQLITE") ) { + // checks failed, abort + DialogSec::errSqlDriverNotFound( "QSQLITE" ); + ok = false; + } + + if ( ok ) { + // check LogDoctor's folders paths + for ( const std::string& path : std::vector({this->basePath(this->configs_path), this->logdoc_path, this->db_data_path, this->db_hashes_path}) ) { + if ( IOutils::exists( path ) ) { + if ( IOutils::isDir( path ) ) { + if ( ! IOutils::checkDir( path, true ) ) { + // directory not readable, try to assign permissions + std::filesystem::permissions( path, + std::filesystem::perms::owner_read, + std::filesystem::perm_options::add, + err ); + if ( err.value() ) { + ok = false; + err_msg = QString::fromStdString( err.message() ); + DialogSec::errDirNotReadable( QString::fromStdString( path ), err_msg ); + } + } + if ( ok ) { + if ( ! IOutils::checkDir( path, false, true ) ) { + // directory not writable, try to assign permissions + std::filesystem::permissions( path, + std::filesystem::perms::owner_write, + std::filesystem::perm_options::add, + err ); + if ( err.value() ) { + ok = false; + err_msg = QString::fromStdString( err.message() ); + DialogSec::errDirNotWritable( QString::fromStdString( path ), err_msg ); + } + } + } + + } else { + // not a directory, rename as copy a make a new one + ok = DialogSec::choiceDirNotDir( QString::fromStdString( path ) ); + if ( ok ) { + ok = IOutils::renameAsCopy( path, err ); + if ( ! ok ) { + QString p = ""; + if ( this->dialogs_level > 0 ) { + p = QString::fromStdString( path ); + if ( err.value() ) { + err_msg = QString::fromStdString( err.message() ); + } + } + DialogSec::errRenaming( p, err_msg ); + } else { + ok = IOutils::makeDir( path, err ); + if ( ! ok ) { + QString msg = DialogSec::tr("Failed to create the directory"); + if ( this->dialogs_level > 0 ) { + msg += ":\n"+QString::fromStdString( path ); + if ( err.value() ) { + err_msg = QString::fromStdString( err.message() ); + } + } + DialogSec::errFailedMakeDir( msg, err_msg ); + } + } + } + } + + } else { + ok = IOutils::makeDir( path, err ); + if ( ! ok ) { + QString msg = DialogSec::tr("Failed to create the directory"); + if ( this->dialogs_level > 0 ) { + msg += ":\n"+QString::fromStdString( path ); + if ( err.value() ) { + err_msg = QString::fromStdString( err.message() ); + } + } + DialogSec::errFailedMakeDir( msg, err_msg ); + } + } + if ( ! ok ) { + break; + } + } + } + + if ( ok ) { + // statistics' database + if ( ! CheckSec::checkCollectionDatabase( this->db_data_path + "/collection.db" ) ) { + // checks failed, abort + ok = false; + } else { + this->crapview.setDbPath( this->db_data_path ); + this->craplog.setStatsDatabasePath( this->db_data_path ); + // used-files' hashes' database + if ( ! CheckSec::checkHashesDatabase( this->db_hashes_path + "/hashes.db" ) ) { + // checks failed, abort + ok = false; + } else { + this->craplog.setHashesDatabasePath( this->db_hashes_path ); + if ( ! this->craplog.hashOps.loadUsedHashesLists( this->db_hashes_path + "/hashes.db" ) ) { + // failed to load the list, abort + ok = false; + } + } + } + } + if ( ! ok ) { + this->close(); + //QCoreApplication::exit(0); + //this->destroy(); + } else { + // get available stats dates + this->refreshStatsDates(); + // get a fresh list of log files + this->on_button_LogFiles_RefreshList_clicked(); + // set the default WS as the current one + switch ( this->craplog.getCurrentWSID() ) { + case 11: + this->ui->box_StatsWarn_WebServer->setCurrentIndex( 0 ); + this->ui->box_StatsCount_WebServer->setCurrentIndex( 0 ); + this->ui->box_StatsSpeed_WebServer->setCurrentIndex( 0 ); + this->ui->box_StatsDay_WebServer->setCurrentIndex( 0 ); + this->ui->box_StatsRelat_WebServer->setCurrentIndex( 0 ); + break; + case 12: + this->ui->box_StatsWarn_WebServer->setCurrentIndex( 1 ); + this->ui->box_StatsCount_WebServer->setCurrentIndex( 1 ); + this->ui->box_StatsSpeed_WebServer->setCurrentIndex( 1 ); + this->ui->box_StatsDay_WebServer->setCurrentIndex( 1 ); + this->ui->box_StatsRelat_WebServer->setCurrentIndex( 1 ); + break; + case 13: + this->ui->box_StatsWarn_WebServer->setCurrentIndex( 2 ); + this->ui->box_StatsCount_WebServer->setCurrentIndex( 2 ); + this->ui->box_StatsSpeed_WebServer->setCurrentIndex( 2 ); + this->ui->box_StatsDay_WebServer->setCurrentIndex( 2 ); + this->ui->box_StatsRelat_WebServer->setCurrentIndex( 2 ); + break; + default: + // shouldn't be here + throw WebServerException( "Unexpected WebServer ID: "+std::to_string( this->default_ws ) ); + } + this->initiating = false; + } +} + + +const bool& MainWindow::checkDataDB() +{ + if ( ! this->initiating ) { // avoid recursions + // check the db + const std::string path = this->db_data_path + "/collection.db"; + bool ok = IOutils::checkFile( path, true ); + if ( ! ok ) { + ok = CheckSec::checkCollectionDatabase( path ); + // update ui stuff + if ( ! ok ) { + // checks failed + this->crapview.clearDates(); + this->ui->box_StatsWarn_Year->clear(); + this->ui->box_StatsSpeed_Year->clear(); + this->ui->box_StatsCount_Year->clear(); + this->ui->box_StatsDay_FromYear->clear(); + if ( this->ui->checkBox_StatsDay_Period->isChecked() ) { + this->ui->box_StatsDay_ToYear->clear(); + } + this->ui->box_StatsRelat_FromYear->clear(); + this->ui->box_StatsRelat_ToYear->clear(); + } + } + if ( ok && !this->db_ok ) { + this->db_ok = ok; + this->initiating = true; + this->refreshStatsDates(); + this->initiating = false; + } else { + this->db_ok = ok; + } + } + return this->db_ok; +} + + +///////////////////// +//// GENERAL USE //// +///////////////////// +const QString MainWindow::wsFromIndex( const int& index ) +{ + switch (index) { + case 0: + return QString("apache"); + case 1: + return QString("nginx"); + case 2: + return QString("iis"); + default: + throw WebServerException( "Unexpected WebServer index: "+std::to_string( index ) ); + } +} + +const std::string MainWindow::resolvePath( const std::string& path ) +{ + std::string p; + try { + p = std::filesystem::canonical( StringOps::strip( path ) ).string(); + } catch (...) { + ; + } + return p; +} +const std::string MainWindow::basePath( const std::string& path ) +{ + const int stop = path.rfind( '/' ); + return path.substr( 0, stop ); +} + +// printable size with suffix and limited decimals +const QString MainWindow::printableSize( const int& bytes ) +{ + std::string size_str, size_sfx=" B"; + float size = (float)bytes; + if (size > 1024) { + size /= 1024; + size_sfx = " KiB"; + if (size > 1024) { + size /= 1024; + size_sfx = " MiB"; + } + } + // cut decimals depending on how big the floor is + size_str = std::to_string( size ); + int cut_index = size_str.find('.')+1; + if ( cut_index == 0 ) { + cut_index = size_str.find(',')+1; + } + int n_decimals = 3; + if ( size >= 100 ) { + n_decimals = 2; + if ( size >= 1000 ) { + n_decimals = 1; + if ( size >= 10000 ) { + n_decimals = 0; + cut_index --; + } + } + } + if ( cut_index >= 1 ) { + cut_index += n_decimals; + if ( cut_index > size_str.size()-1 ) { + cut_index = size_str.size()-1; + } + } + return QString::fromStdString( size_str.substr(0, cut_index ) + size_sfx ); +} + +// printable speed with suffix and limited decimals +const QString MainWindow::printableSpeed( const int& bytes, const int& secs_ ) +{ + std::string speed_str, speed_sfx=" B/s"; + int secs = secs_; + if ( secs == 0 ) { + secs = 1; + } + float speed = (float)bytes / (float)secs; + if (speed > 1024) { + speed /= 1024; + speed_sfx = " KiB/s"; + if (speed > 1024) { + speed /= 1024; + speed_sfx = " MiB/s"; + } + } + // cut decimals depending on how big the floor is + speed_str = std::to_string( speed ); + int cut_index = speed_str.find('.')+1; + if ( cut_index == 0 ) { + cut_index = speed_str.find(',')+1; + } + int n_decimals = 3; + if ( speed >= 100 ) { + n_decimals = 2; + if ( speed >= 1000 ) { + n_decimals = 1; + if ( speed >= 10000 ) { + n_decimals = 0; + cut_index --; + } + } + } + if ( cut_index >= 1 ) { + cut_index += n_decimals; + if ( cut_index > speed_str.size()-1 ) { + cut_index = speed_str.size()-1; + } + } + return QString::fromStdString( speed_str.substr(0, cut_index ) + speed_sfx ); +} + +const QString MainWindow::printableTime( const int& secs_ ) +{ + int secs = secs_; + int mins = secs / 60; + secs = secs - (mins*60); + std::string mins_str = (mins<10) ? "0"+std::to_string(mins) : std::to_string(mins); + std::string secs_str = (secs<10) ? "0"+std::to_string(secs) : std::to_string(secs); + return QString::fromStdString( mins_str +":"+ secs_str ); +} + + +////////////// +//// HELP //// +////////////// +void MainWindow::showHelp( const std::string& file_name ) +{ + const std::string link = "https://github.com/elB4RTO/LogDoctor/tree/main/installation_stuff/logdocdata/help/"; + const std::string path = this->logdoc_path+"/help/"+this->language+"/"+file_name+".html"; + if ( IOutils::exists( path ) ) { + if ( IOutils::isFile( path ) ) { + if ( IOutils::checkFile( path, true ) ) { + // everything ok, delete the old help window and open a new one + delete this->craphelp; + this->craphelp = new Craphelp(); + this->craphelp->helpLogsFormat( + path, + this->TB.getFont(), + this->TB.getColorSchemeID() ); + if ( this->isMaximized() ) { + this->craphelp->showMaximized(); + } else { + this->craphelp->show(); + } + } else { + // resource not readable + DialogSec::errHelpNotReadable( QString::fromStdString( link ) ); + } + } else { + // resource is not a file + DialogSec::errHelpFailed( QString::fromStdString( link ), DialogSec::tr("unrecognized entry") ); + } + } else { + // resource not found + DialogSec::errHelpNotFound( QString::fromStdString( link ) ); + } +} + + + +/*************************************************************** + * MainWindow'S OPERATIONS START FROM HERE + ***************************************************************/ + + +////////////// +//// MENU //// +/// ////////// +// switch language +void MainWindow::menu_actionEnglish_triggered() +{ + this->ui->actionEnglish->setChecked( true ); + this->ui->actionEspanol->setChecked( false ); + this->ui->actionFrancais->setChecked( false ); + this->ui->actionItaliano->setChecked( false ); + this->language = "en"; + this->updateUiLanguage(); +} +void MainWindow::menu_actionEspanol_triggered() +{ + this->ui->actionEnglish->setChecked( false ); + this->ui->actionEspanol->setChecked( true ); + this->ui->actionFrancais->setChecked( false ); + this->ui->actionItaliano->setChecked( false ); + this->language = "es"; + this->updateUiLanguage(); +} +void MainWindow::menu_actionFrancais_triggered() +{ + this->ui->actionEnglish->setChecked( false ); + this->ui->actionEspanol->setChecked( false ); + this->ui->actionFrancais->setChecked( true ); + this->ui->actionItaliano->setChecked( false ); + this->language = "fr"; + this->updateUiLanguage(); +} +void MainWindow::menu_actionItaliano_triggered() +{ + + this->ui->actionEnglish->setChecked( false ); + this->ui->actionEspanol->setChecked( false ); + this->ui->actionFrancais->setChecked( false ); + this->ui->actionItaliano->setChecked( true ); + this->language = "it"; + this->updateUiLanguage(); +} + +// use a tool +void MainWindow::menu_actionBlockNote_triggered() +{ + if ( this->crapnote->isVisible() ) { + this->crapnote->activateWindow(); + + } else { + delete this->crapnote; + this->crapnote = new Crapnote(); + this->crapnote->setTextFont( this->TB.getFont() ); + this->crapnote->setColorScheme( this->TB.getColorSchemeID() ); + this->crapnote->show(); + } +} + +void MainWindow::menu_actionInfos_triggered() +{ + std::string version_ = std::to_string( this->version ); + size_t cut = version_.find('.'); + if ( cut == std::string::npos ) { + cut = version_.find(','); + if ( cut == std::string::npos ) { + cut = version_.size()-3; + } + } + version_ = version_.substr( 0, cut+3 ); + delete this->crapinfo; + this->crapinfo = new Crapinfo( + this->window_theme_id, + QString::fromStdString( version_ ), + QString::fromStdString( this->resolvePath( "./" ) ), + QString::fromStdString( this->configs_path ), + QString::fromStdString( this->logdoc_path ) ); + this->crapinfo->show(); +} + +void MainWindow::menu_actionCheckUpdates_triggered() +{ + if ( this->crapup->isVisible() ) { + this->crapup->activateWindow(); + + } else { + delete this->crapup; + this->crapup = new Crapup( + this->window_theme_id, + this->icons_theme ); + this->crapup->show(); + this->crapup->versionCheck( 1.0 ); + } +} + +// play a game +void MainWindow::menu_actionCrissCross_triggered() +{ + if ( this->crisscross->isVisible() ) { + this->crisscross->activateWindow(); + + } else { + delete this->crisscross; + this->crisscross = new CrissCross( this->window_theme_id ); + this->crisscross->show(); + } +} + +void MainWindow::menu_actionSnake_triggered() +{ + if ( this->snake->isVisible() ) { + this->snake->activateWindow(); + + } else { + delete this->snake; + this->snake = new SnakeGame( this->window_theme_id, this->FONTS.at("script") ); + this->snake->show(); + } +} + + + +////////////// +//// TABS //// +////////////// +void MainWindow::switchMainTab( const int& new_index ) +{ + const int old_index = this->ui->stacked_Tabs_Pages->currentIndex(); + // turn off the old icon + switch ( old_index ) { + case 0: + // make + this->ui->button_Tab_Log->setFlat( true ); + this->ui->button_Tab_Log->setIcon( + QIcon(QString(":/icons/icons/%1/log_off.png").arg(this->icons_theme)) ); + break; + case 1: + // view + this->ui->button_Tab_View->setFlat( true ); + this->ui->button_Tab_View->setIcon( + QIcon(QString(":/icons/icons/%1/view_off.png").arg(this->icons_theme)) ); + break; + case 2: + // config + this->ui->button_Tab_Conf->setFlat( true ); + this->ui->button_Tab_Conf->setIcon( + QIcon(QString(":/icons/icons/%1/conf_off.png").arg(this->icons_theme)) ); + break; + default: + throw("Unexpected Tabs index: "+std::to_string(old_index)); + break; + } + // turn on the new one + switch ( new_index ) { + case 0: + // make + this->ui->button_Tab_Log->setFlat( false ); + this->ui->button_Tab_Log->setIcon( + QIcon(QString(":/icons/icons/%1/log_on.png").arg(this->icons_theme)) ); + break; + case 1: + // view + this->ui->button_Tab_View->setFlat( false ); + this->ui->button_Tab_View->setIcon( + QIcon(QString(":/icons/icons/%1/view_on.png").arg(this->icons_theme)) ); + break; + case 2: + // config + this->ui->button_Tab_Conf->setFlat( false ); + this->ui->button_Tab_Conf->setIcon( + QIcon(QString(":/icons/icons/%1/conf_on.png").arg(this->icons_theme)) ); + break; + default: + throw("Unexpected MainTabs index: "+std::to_string(new_index)); + break; + } + this->ui->stacked_Tabs_Pages->setCurrentIndex( new_index ); +} + + +void MainWindow::on_button_Tab_Log_clicked() +{ + this->switchMainTab( 0 ); +} + +void MainWindow::on_button_Tab_View_clicked() +{ + this->switchMainTab( 1 ); +} + +void MainWindow::on_button_Tab_Conf_clicked() +{ + this->switchMainTab( 2 ); +} + + +//// STATS //// +void MainWindow::switchStatsTab( const int& new_index ) +{ + const int old_index = this->ui->stacked_Stats_Pages->currentIndex(); + // turn off the old icon + switch ( old_index ) { + case 0: + // warning + this->ui->button_Tab_StatsWarn->setFlat( true ); + this->ui->button_Tab_StatsWarn->setIcon( + QIcon(QString(":/icons/icons/%1/warn_off.png").arg(this->icons_theme)) ); + break; + case 1: + // speed + this->ui->button_Tab_StatsSpeed->setFlat( true ); + this->ui->button_Tab_StatsSpeed->setIcon( + QIcon(QString(":/icons/icons/%1/speed_off.png").arg(this->icons_theme)) ); + break; + case 2: + // counts + this->ui->button_Tab_StatsCount->setFlat( true ); + this->ui->button_Tab_StatsCount->setIcon( + QIcon(QString(":/icons/icons/%1/count_off.png").arg(this->icons_theme)) ); + break; + case 3: + // daytime + this->ui->button_Tab_StatsDay->setFlat( true ); + this->ui->button_Tab_StatsDay->setIcon( + QIcon(QString(":/icons/icons/%1/daytime_off.png").arg(this->icons_theme)) ); + break; + case 4: + // relational + this->ui->button_Tab_StatsRelat->setFlat( true ); + this->ui->button_Tab_StatsRelat->setIcon( + QIcon(QString(":/icons/icons/%1/relational_off.png").arg(this->icons_theme)) ); + break; + case 5: + // globals + this->ui->button_Tab_StatsGlob->setFlat( true ); + this->ui->button_Tab_StatsGlob->setIcon( + QIcon(QString(":/icons/icons/%1/global_off.png").arg(this->icons_theme)) ); + break; + default: + throw("Unexpected StatsTabs index: "+std::to_string(old_index)); + break; + } + // turn on the new one + switch ( new_index ) { + case 0: + // warning + this->ui->button_Tab_StatsWarn->setFlat( false ); + this->ui->button_Tab_StatsWarn->setIcon( + QIcon(QString(":/icons/icons/%1/warn_on.png").arg(this->icons_theme)) ); + break; + case 1: + // speed + this->ui->button_Tab_StatsSpeed->setFlat( false ); + this->ui->button_Tab_StatsSpeed->setIcon( + QIcon(QString(":/icons/icons/%1/speed_on.png").arg(this->icons_theme)) ); + break; + case 2: + // counts + this->ui->button_Tab_StatsCount->setFlat( false ); + this->ui->button_Tab_StatsCount->setIcon( + QIcon(QString(":/icons/icons/%1/count_on.png").arg(this->icons_theme)) ); + break; + case 3: + // daytime + this->ui->button_Tab_StatsDay->setFlat( false ); + this->ui->button_Tab_StatsDay->setIcon( + QIcon(QString(":/icons/icons/%1/daytime_on.png").arg(this->icons_theme)) ); + break; + case 4: + // relational + this->ui->button_Tab_StatsRelat->setFlat( false ); + this->ui->button_Tab_StatsRelat->setIcon( + QIcon(QString(":/icons/icons/%1/relational_on.png").arg(this->icons_theme)) ); + break; + case 5: + // globals + this->ui->button_Tab_StatsGlob->setFlat( false ); + this->ui->button_Tab_StatsGlob->setIcon( + QIcon(QString(":/icons/icons/%1/global_on.png").arg(this->icons_theme)) ); + break; + default: + throw("Unexpected StatsTabs index: "+std::to_string(new_index)); + break; + } + this->ui->stacked_Stats_Pages->setCurrentIndex( new_index ); +} + + +void MainWindow::on_button_Tab_StatsWarn_clicked() +{ + this->switchStatsTab( 0 ); +} + +void MainWindow::on_button_Tab_StatsSpeed_clicked() +{ + this->switchStatsTab( 1 ); +} + +void MainWindow::on_button_Tab_StatsCount_clicked() +{ + this->switchStatsTab( 2 ); +} + +void MainWindow::on_button_Tab_StatsDay_clicked() +{ + this->switchStatsTab( 3 ); +} + +void MainWindow::on_button_Tab_StatsRelat_clicked() +{ + this->switchStatsTab( 4 ); +} + +void MainWindow::on_button_Tab_StatsGlob_clicked() +{ + this->switchStatsTab( 5 ); +} + + + +//////////// +//// DB //// +//////////// +void MainWindow::setDbWorkingState( const bool& state ) +{ + this->db_working = state; + if ( ! state ) { + this->checkMakeStats_Makable(); + if ( this->ui->table_StatsWarn->rowCount() > 0 ) { + this->ui->button_StatsWarn_Update->setEnabled( true ); + } + this->checkStatsWarnDrawable(); + this->checkStatsCountDrawable(); + this->checkStatsSpeedDrawable(); + this->checkStatsDayDrawable(); + this->checkStatsRelatDrawable(); + this->ui->button_StatsGlob_Apache->setEnabled( true ); + this->ui->button_StatsGlob_Nginx->setEnabled( true ); + this->ui->button_StatsGlob_Iis->setEnabled( true ); + this->ui->page_Tab_Conf->setEnabled( true ); + } else { + this->ui->button_MakeStats_Start->setEnabled( false ); + this->ui->button_StatsWarn_Update->setEnabled( false ); + this->ui->button_StatsWarn_Draw->setEnabled( false ); + this->ui->scrollArea_StatsCount->setEnabled( false ); + this->ui->button_StatsSpeed_Draw->setEnabled( false ); + this->ui->button_StatsDay_Draw->setEnabled( false ); + this->ui->button_StatsRelat_Draw->setEnabled( false ); + this->ui->button_StatsGlob_Apache->setEnabled( false ); + this->ui->button_StatsGlob_Nginx->setEnabled( false ); + this->ui->button_StatsGlob_Iis->setEnabled( false ); + this->ui->page_Tab_Conf->setEnabled( false ); + } +} + + +////////////// +//// LOGS //// +////////////// +// switch pages +void MainWindow::on_button_Logs_Down_clicked() +{ + this->ui->stacked_Logs_Pages->setCurrentIndex( 1 ); +} + + +void MainWindow::on_button_Logs_Up_clicked() +{ + this->ui->stacked_Logs_Pages->setCurrentIndex( 0 ); +} + + +// check +void MainWindow::checkMakeStats_Makable() +{ + bool state = false; + if ( ! this->db_working ) { + // db is not busy + if ( this->ui->checkBox_LogFiles_CheckAll->checkState() == Qt::CheckState::Checked ) { + // all checked + state = true; + } else if ( this->ui->checkBox_LogFiles_CheckAll->checkState() == Qt::CheckState::PartiallyChecked ) { + // at least one should be checked + QTreeWidgetItemIterator i(this->ui->listLogFiles); + while ( *i ) { + if ( (*i)->checkState(0) == Qt::CheckState::Checked ) { + // an entry is checked + state = true; + break; + } + ++i; + } + } + } + this->ui->button_MakeStats_Start->setEnabled( state ); +} + + +// switch to apache web server +void MainWindow::on_button_LogFiles_Apache_clicked() +{ + if ( this->craplog.getCurrentWSID() != 11 ) { + // flat/unflat + this->ui->button_LogFiles_Apache->setFlat( false ); + this->ui->button_LogFiles_Nginx->setFlat( true ); + this->ui->button_LogFiles_Iis->setFlat( true ); + // set the WebServer + this->craplog.setCurrentWSID( 11 ); + // reset the log files viewer + QString rich_text; + RichText::richLogsDefault( rich_text ); + this->ui->textLogFiles->setText( rich_text ); + this->ui->textLogFiles->setAlignment( Qt::AlignHCenter ); + rich_text.clear(); + // load the list + this->on_button_LogFiles_RefreshList_clicked(); + } +} +// switch to nginx web server +void MainWindow::on_button_LogFiles_Nginx_clicked() +{ + if ( this->craplog.getCurrentWSID() != 12 ) { + // flat/unflat + this->ui->button_LogFiles_Nginx->setFlat( false ); + this->ui->button_LogFiles_Apache->setFlat( true ); + this->ui->button_LogFiles_Iis->setFlat( true ); + // set the WebServer + this->craplog.setCurrentWSID( 12 ); + // reset the log files viewer + QString rich_text; + RichText::richLogsDefault( rich_text ); + this->ui->textLogFiles->setText( rich_text ); + this->ui->textLogFiles->setAlignment( Qt::AlignHCenter ); + rich_text.clear(); + // load the list + this->on_button_LogFiles_RefreshList_clicked(); + } +} +// switch to iis web server +void MainWindow::on_button_LogFiles_Iis_clicked() +{ + if ( this->craplog.getCurrentWSID() != 13 ) { + // flat/unflat + this->ui->button_LogFiles_Iis->setFlat( false ); + this->ui->button_LogFiles_Apache->setFlat( true ); + this->ui->button_LogFiles_Nginx->setFlat( true ); + // set the WebServer + this->craplog.setCurrentWSID( 13 ); + // reset the log files viewer + QString rich_text; + RichText::richLogsDefault( rich_text ); + this->ui->textLogFiles->setText( rich_text ); + this->ui->textLogFiles->setAlignment( Qt::AlignHCenter ); + rich_text.clear(); + // load the list + this->on_button_LogFiles_RefreshList_clicked(); + } +} + +// refresh the log files list +void MainWindow::on_button_LogFiles_RefreshList_clicked() +{ + // clear the current tree + this->ui->listLogFiles->clear(); + this->ui->checkBox_LogFiles_CheckAll->setCheckState( Qt::CheckState::Unchecked ); + // disable elements + this->ui->button_LogFiles_RefreshList->setEnabled( false ); + this->ui->button_LogFiles_ViewFile->setEnabled( false ); + this->ui->button_LogFiles_Apache->setEnabled( false ); + this->ui->button_LogFiles_Nginx->setEnabled( false ); + this->ui->button_LogFiles_Iis->setEnabled( false ); + // start refreshing as thread + this->refreshing_list = true; + delete this->craplog_timer; + this->craplog_timer = new QTimer(this); + this->craplog_timer->setSingleShot( true ); + connect(this->craplog_timer, SIGNAL(timeout()), this, SLOT(refreshLogsList())); + this->craplog_timer->start(250); + // periodically check if thread finished + delete this->waiter_timer; + this->waiter_timer = new QTimer(this); + connect(this->waiter_timer, SIGNAL(timeout()), this, SLOT(check_CraplogLLT_Finished())); + this->waiter_timer->start(250); +} + +void MainWindow::refreshLogsList() +{ + std::string col; + // iterate over elements of list + for ( const Craplog::LogFile& log_file : this->craplog.getLogsList(true) ) { + // new entry for the tree widget + QTreeWidgetItem *item = new QTreeWidgetItem(); + + // preliminary check for file usage display + if ( log_file.used_already ) { + if ( this->hide_used_files ) { + // do not display + delete item; // possible memory leak + continue; + } + // display with red foreground + item->setForeground( 0, this->COLORS.at( "red" ) ); + } + + // preliminary check on file size + col = "grey"; + if ( log_file.size > this->craplog.getWarningSize() ) { + col = "orange"; + } + item->setForeground( 1, this->COLORS.at( col ) ); + + // set the name + item->setText( 0, log_file.name ); + // set the size + item->setText( 1, this->printableSize( log_file.size ) ); + item->setFont( 1, this->FONTS.at("main_italic") ); + // append the item (on top, forced) + item->setCheckState(0, Qt::CheckState::Unchecked ); + this->ui->listLogFiles->addTopLevelItem( item ); + } + if ( this->craplog.getLogsListSize() > 0 ) { + // sort the list alphabetically + this->ui->listLogFiles->sortByColumn(0, Qt::SortOrder::AscendingOrder ); + this->ui->checkBox_LogFiles_CheckAll->setEnabled( true ); + } else { + this->ui->checkBox_LogFiles_CheckAll->setCheckState( Qt::CheckState::Unchecked ); + this->ui->checkBox_LogFiles_CheckAll->setEnabled( false ); + } + refreshing_list = false; +} +void MainWindow::check_CraplogLLT_Finished() +{ + if ( ! this->refreshing_list ) { + this->waiter_timer->stop(); + // back to normal state + this->ui->button_LogFiles_RefreshList->setEnabled( true ); + this->ui->button_LogFiles_ViewFile->setEnabled( true ); + this->ui->button_LogFiles_Apache->setEnabled( true ); + this->ui->button_LogFiles_Nginx->setEnabled( true ); + this->ui->button_LogFiles_Iis->setEnabled( true ); + } +} + + +void MainWindow::on_checkBox_LogFiles_CheckAll_stateChanged(int arg1) +{ + this->checkMakeStats_Makable(); + Qt::CheckState new_state; + if ( arg1 == Qt::CheckState::Checked ) { + // check all + new_state = Qt::CheckState::Checked; + } else if ( arg1 == Qt::CheckState::Unchecked ) { + // un-check all + new_state = Qt::CheckState::Unchecked; + } else { + // do nothing + return; + } + QTreeWidgetItemIterator i( this->ui->listLogFiles ); + while ( *i ) { + (*i)->setCheckState( 0, new_state ); + ++i; + } +} + + +void MainWindow::on_button_LogFiles_ViewFile_clicked() +{ + // display the selected item + if ( this->ui->listLogFiles->selectedItems().size() > 0 ) { + bool proceed = true; + Craplog::LogFile item; + // retrieve the file item + try { + item = this->craplog.getLogFileItem( + this->ui->listLogFiles->selectedItems().takeFirst()->text(0) ); + + } catch ( const GenericException& ) { + // failed to find file + proceed = false; + DialogSec::errFileNotFound( QString::fromStdString( item.path ), true ); + } + + // check the size + if ( proceed ) { + const long warn_size = this->craplog.getWarningSize(); + if ( warn_size >= 0 ) { + if ( item.size > warn_size ) { + // exceeds the warning size + QString size_str, msg = item.name; + if ( this->dialogs_level >= 1 ) { + std::string size_sfx=" B"; + float size = (float)item.size; + if (size > 1024) { + size /= 1024; size_sfx = " KiB"; + if (size > 1024) { + size /= 1024; size_sfx = " MiB"; + } + } + size_str = std::to_string(size).substr(0,std::to_string(size).size()-3).c_str(); + msg += QString("\n\n%1:\n%2%3").arg( DialogSec::tr("Size of the file"), size_str, size_sfx.c_str() ); + if ( this->dialogs_level == 2 ) { + size = (float)warn_size; + if (size > 1024) { + size /= 1024; size_sfx = " KiB"; + if (size > 1024) { + size /= 1024; size_sfx = " MiB"; + } + } + size_str = std::to_string(size).substr(0,std::to_string(size).size()-3).c_str(); + msg += QString("\n\n%1:\n%2%3").arg( DialogSec::tr("Warning size parameter"), size_str, size_sfx.c_str() ); + } + } + // ask the user what to do + proceed = DialogSec::choiceFileSizeWarning2( msg ); + if ( ! proceed ) { + return; + } + } + } + } + + if ( proceed ) { + // get the current log format + FormatOps::LogsFormat format = this->craplog.getCurrentLogFormat(); + // read the content + std::string content; + try { + try { + // try reading as gzip compressed file + GZutils::readFile( item.path, content ); + + } catch ( const GenericException& ) { + // failed closing file pointer + throw; + + } catch (...) { + // failed as gzip, try as text file + if ( content.size() > 0 ) { + content.clear(); + } + IOutils::readFile( item.path, content ); + } + + } catch ( const GenericException& ) { + // failed closing gzip file pointer + proceed = false; + // >> e.what() << // + DialogSec::errGeneric( QString("%1:\n%2").arg( + DialogSec::tr("Failed to read gzipped file"), + item.name) ); + + /*} catch ( const std::ios_base::failure& err ) { + // failed reading as text + proceed = false; + // >> err.what() << // + DialogSec::errFailedReadFile( item.name );*/ + } catch (...) { + // failed somehow + proceed = false; + DialogSec::errFailedReadFile( item.name ); + } + + if ( proceed ) { + // succesfully read, now enriched and display + QString rich_content; + RichText::enrichLogs( + rich_content, content, + format, this->TB ); + this->ui->textLogFiles->setText( rich_content ); + this->ui->textLogFiles->setFont( this->TB.getFont() ); + rich_content.clear(); + } + content.clear(); + } + if ( ! proceed ) { + // failed + QString rich_text; + RichText::richLogsFailure( rich_text ); + this->ui->textLogFiles->setText( rich_text ); + this->ui->textLogFiles->setAlignment( Qt::AlignHCenter ); + rich_text.clear(); + } + } +} + + +void MainWindow::on_listLogFiles_itemDoubleClicked(QTreeWidgetItem *item, int column) +{ + this->on_button_LogFiles_ViewFile_clicked(); +} + + +void MainWindow::on_listLogFiles_itemChanged(QTreeWidgetItem *item, int column) +{ + // control checked + int n_checked = 0; + QTreeWidgetItemIterator i(this->ui->listLogFiles); + while ( *i ) { + if ( (*i)->checkState(0) == Qt::CheckState::Checked ) { + n_checked++; + } + ++i; + } + if ( n_checked == 0 ) { + this->ui->checkBox_LogFiles_CheckAll->setCheckState(Qt::CheckState::Unchecked); + } else if ( n_checked == this->craplog.getLogsListSize() ) { + this->ui->checkBox_LogFiles_CheckAll->setCheckState(Qt::CheckState::Checked); + } else { + this->ui->checkBox_LogFiles_CheckAll->setCheckState(Qt::CheckState::PartiallyChecked); + } +} + + +void MainWindow::on_button_MakeStats_Start_clicked() +{ + if ( ! this->db_working ) { + bool proceed = true; + // check that the format has been set + const FormatOps::LogsFormat& lf = this->craplog.getLogsFormat( this->craplog.getCurrentWSID() ); + if ( lf.string.size() == 0 ) { + // format string not set + proceed = false; + DialogSec::errLogFormatNotSet( nullptr ); + } else if ( lf.fields.size() == 0 ) { + // no field, useless to parse + proceed = false; + DialogSec::errLogFormatNoFields( nullptr ); + } else if ( lf.separators.size() < lf.fields.size()-1 ) { + // missing at least a separator between two (or more) fields + proceed = false; + DialogSec::errLogFormatNoSeparators( nullptr ); + } + + if ( proceed ) { + // take actions on Craplog's start + this->craplogStarted(); + + // feed craplog with the checked files + QTreeWidgetItemIterator i(this->ui->listLogFiles); + while ( *i ) { + if ( (*i)->checkState(0) == Qt::CheckState::Checked ) { + // tell Craplog to set this file as selected + if ( ! this->craplog.setLogFileSelected( (*i)->text(0) ) ) { + // failed to retrieve the file. this shouldn't be, but... + const int choice = DialogSec::choiceSelectedFileNotFound( (*i)->text(0) ); + if ( choice == 0 ) { + // choosed to abort all + proceed = false; + break; + } else if ( choice == 1 ) { + // choosed to discard the file and continue + ; + } else { + // shouldn't be here + throw GenericException( "Unexpeced value returned: "+std::to_string(choice) ); + } + } + } + ++i; + } + + if ( proceed ) { + // check files to be used before to start + proceed = this->craplog.checkStuff(); + } else { + this->craplogFinished(); + } + + if ( proceed ) { + // periodically update perfs + delete this->waiter_timer; + this->waiter_timer = new QTimer(this); + connect(this->waiter_timer, SIGNAL(timeout()), this, SLOT(update_Craplog_PerfData())); + // run craplog as thread + this->waiter_timer_start = std::chrono::system_clock::now(); + delete this->craplog_timer; + this->craplog_timer = new QTimer(this); + this->craplog_timer->setSingleShot( true ); + connect(this->craplog_timer, SIGNAL(timeout()), this, SLOT(runCraplog())); + // start processing + this->waiter_timer->start(250); + this->craplog_timer->start(100); + } else { + this->craplogFinished(); + } + } + } +} +void MainWindow::runCraplog() +{ + this->craplog.run(); +} + +void MainWindow::reset_MakeStats_labels() +{ + // reset to default + this->ui->label_MakeStats_Size->setText( "0 B" ); + this->ui->label_MakeStats_Lines->setText( "0" ); + // time and speed + this->ui->label_MakeStats_Time->setText( "00:00" ); + this->ui->label_MakeStats_Speed->setText( "0 B/s" ); +} + +void MainWindow::update_MakeStats_labels() +{ + // update values + unsigned size; + long secs; + // size and lines + if ( this->craplog.isParsing() ) { + this->craplog.collectPerfData(); + } + size = this->craplog.getTotalSize(); + //size = this->craplog.getParsedSize(); + this->ui->label_MakeStats_Size->setText( this->printableSize( size ) ); + this->ui->label_MakeStats_Lines->setText( QString::fromStdString(std::to_string(this->craplog.getParsedLines())) ); + // time and speed + this->waiter_timer_elapsed = std::chrono::duration_cast( + this->waiter_timer_start - std::chrono::system_clock::now() + ); + size = this->craplog.getPerfSize(); + secs = this->waiter_timer_elapsed.count() / -1000000000; + this->ui->label_MakeStats_Time->setText( this->printableTime( secs )); + this->ui->label_MakeStats_Speed->setText( this->printableSpeed( size, secs )); +} + +void MainWindow::update_Craplog_PerfData() +{ + // craplog is running as thread, update the values meanwhile + this->update_MakeStats_labels(); + // check if Craplog has finished working + if ( ! this->craplog.isWorking() ) { + this->waiter_timer->stop(); + this->craplogFinished(); + } +} + +void MainWindow::craplogStarted() +{ + // reset perfs + this->reset_MakeStats_labels(); + this->craplog.logOps.resetPerfData(); + // disable the LogFiles section + this->ui->stacked_Logs_Pages->setEnabled(false); + // disable things which needs database access + this->setDbWorkingState( true ); + // enable all labels (needed only the first time) + this->ui->icon_MakeStats_Size->setEnabled( false ); + this->ui->label_MakeStats_Size->setEnabled( true ); + this->ui->icon_MakeStats_Lines->setEnabled( false ); + this->ui->label_MakeStats_Lines->setEnabled( true ); + this->ui->icon_MakeStats_Time->setEnabled( false ); + this->ui->label_MakeStats_Time->setEnabled( true ); + this->ui->icon_MakeStats_Speed->setEnabled( false ); + this->ui->label_MakeStats_Speed->setEnabled( true ); +} + +void MainWindow::craplogFinished() +{ + // update the perf data one last time, just in case + this->update_MakeStats_labels(); + this->craplog.makeChart( + this->CHARTS_THEMES.at( this->charts_theme_id ), this->FONTS, + this->ui->chart_MakeStats_Size ); + if ( this->craplog.editedDatabase() ) { + // craplog succeeded + this->db_edited = true; + } + if ( this->craplog.getTotalSize() == 0 ) { + // no data + this->reset_MakeStats_labels(); + } + // clean up temp vars + this->craplog.clearDataCollection(); + this->craplog.logOps.resetPerfData(); + + // refresh the logs list + this->on_button_LogFiles_RefreshList_clicked(); + // enable the LogFiles section + this->ui->stacked_Logs_Pages->setEnabled( true ); + // enable all labels (needed only the first time each session) + this->ui->icon_MakeStats_Size->setEnabled( true ); + this->ui->icon_MakeStats_Lines->setEnabled( true ); + this->ui->icon_MakeStats_Time->setEnabled( true ); + this->ui->icon_MakeStats_Speed->setEnabled( true ); + // enable back + this->setDbWorkingState( false ); + // get a fresh collection of available stats dates + this->refreshStatsDates(); +} + + + +/////////////// +//// STATS //// +/////////////// +// refresh all the dates boxes +void MainWindow::refreshStatsDates() +{ + this->crapview.refreshDates(); + this->on_box_StatsWarn_WebServer_currentIndexChanged( this->ui->box_StatsWarn_WebServer->currentIndex() ); + this->on_box_StatsSpeed_WebServer_currentIndexChanged( this->ui->box_StatsSpeed_WebServer->currentIndex() ); + this->on_box_StatsCount_WebServer_currentIndexChanged( this->ui->box_StatsCount_WebServer->currentIndex() ); + this->on_box_StatsDay_WebServer_currentIndexChanged( this->ui->box_StatsDay_WebServer->currentIndex() ); + this->on_box_StatsRelat_WebServer_currentIndexChanged( this->ui->box_StatsRelat_WebServer->currentIndex() ); +} + + +////////////// +//// WARN //// +void MainWindow::checkStatsWarnDrawable() +{ + if ( ! this->db_working ) { + if ( this->ui->box_StatsWarn_Year->currentIndex() >= 0 + && this->ui->box_StatsWarn_Month->currentIndex() >= 0 + && this->ui->box_StatsWarn_Day->currentIndex() >= 0 ) { + // enable the draw button + this->ui->button_StatsWarn_Draw->setEnabled( true ); + } else { + // disable the draw button + this->ui->button_StatsWarn_Draw->setEnabled( false ); + } + } else { + this->ui->button_StatsRelat_Draw->setEnabled( false ); + } +} + +void MainWindow::on_box_StatsWarn_WebServer_currentIndexChanged(int index) +{ + if ( this->checkDataDB() ) { + this->ui->box_StatsWarn_Year->clear(); + if ( index != -1 ) { + this->ui->box_StatsWarn_Year->addItems( + this->crapview.getYears( this->wsFromIndex( index ) )); + this->ui->box_StatsWarn_Year->setCurrentIndex( 0 ); + } + } + this->checkStatsWarnDrawable(); +} + +void MainWindow::on_box_StatsWarn_Year_currentIndexChanged(int index) +{ + this->ui->box_StatsWarn_Month->clear(); + if ( index != -1 ) { + this->ui->box_StatsWarn_Month->addItems( + this->crapview.getMonths( + this->wsFromIndex( this->ui->box_StatsWarn_WebServer->currentIndex() ), + this->ui->box_StatsWarn_Year->currentText() ) ); + this->ui->box_StatsWarn_Month->setCurrentIndex( 0 ); + } + this->checkStatsWarnDrawable(); +} + +void MainWindow::on_box_StatsWarn_Month_currentIndexChanged(int index) +{ + this->ui->box_StatsWarn_Day->clear(); + if ( index != -1 ) { + this->ui->box_StatsWarn_Day->addItems( + this->crapview.getDays( + this->wsFromIndex( this->ui->box_StatsWarn_WebServer->currentIndex() ), + this->ui->box_StatsWarn_Year->currentText(), + this->ui->box_StatsWarn_Month->currentText() ) ); + this->ui->box_StatsWarn_Day->setCurrentIndex( 0 ); + } + this->checkStatsWarnDrawable(); +} + +void MainWindow::on_box_StatsWarn_Day_currentIndexChanged(int index) +{ + if ( this->ui->checkBox_StatsWarn_Hour->isChecked() ) { + this->ui->box_StatsWarn_Hour->clear(); + if ( index != -1 ) { + this->ui->box_StatsWarn_Hour->addItems( this->crapview.getHours() ); + this->ui->box_StatsWarn_Hour->setCurrentIndex( 0 ); + } + } + this->checkStatsWarnDrawable(); +} + +void MainWindow::on_checkBox_StatsWarn_Hour_stateChanged(int state) +{ + if ( state == Qt::CheckState::Checked ) { + this->ui->box_StatsWarn_Hour->setEnabled( true ); + // add available dates + this->on_box_StatsWarn_Day_currentIndexChanged( 0 ); + } else { + this->ui->box_StatsWarn_Hour->clear(); + this->ui->box_StatsWarn_Hour->setEnabled( false ); + } +} + +void MainWindow::on_box_StatsWarn_Hour_currentIndexChanged(int index) +{ + this->checkStatsWarnDrawable(); +} + +void MainWindow::on_button_StatsWarn_Draw_clicked() +{ + if ( this->checkDataDB() ) { + this->setDbWorkingState( true ); + delete this->crapview_timer; + this->crapview_timer = new QTimer(this); + this->crapview_timer->setSingleShot( true ); + connect(this->crapview_timer, SIGNAL(timeout()), this, SLOT(drawStatsWarn())); + this->crapview_timer->start(250); + } +} +void MainWindow::drawStatsWarn() +{ + this->ui->table_StatsWarn->setRowCount(0); + this->crapview.drawWarn( + this->ui->table_StatsWarn, this->ui->chart_StatsWarn, + this->CHARTS_THEMES.at( this->charts_theme_id ), this->FONTS, + this->wsFromIndex( this->ui->box_StatsWarn_WebServer->currentIndex() ), + this->ui->box_StatsWarn_Year->currentText(), + this->ui->box_StatsWarn_Month->currentText(), + this->ui->box_StatsWarn_Day->currentText(), + (this->ui->checkBox_StatsWarn_Hour->isChecked()) ? this->ui->box_StatsWarn_Hour->currentText() : "" ); + this->setDbWorkingState( false ); +} + + +void MainWindow::on_button_StatsWarn_Update_clicked() +{ + this->crapview.updateWarn( + this->ui->table_StatsWarn, + this->wsFromIndex( this->ui->box_StatsWarn_WebServer->currentIndex() ) ); + this->db_edited = true; +} + + +/////////////// +//// SPEED //// +void MainWindow::checkStatsSpeedDrawable() +{ + if ( ! this->db_working ) { + if ( this->ui->box_StatsSpeed_Year->currentIndex() >= 0 + && this->ui->box_StatsSpeed_Month->currentIndex() >= 0 + && this->ui->box_StatsSpeed_Day->currentIndex() >= 0 ) { + // enable the draw button + this->ui->button_StatsSpeed_Draw->setEnabled( true ); + } else { + // disable the draw button + this->ui->button_StatsSpeed_Draw->setEnabled( false ); + } + } else { + this->ui->button_StatsRelat_Draw->setEnabled( false ); + } +} + +void MainWindow::on_box_StatsSpeed_WebServer_currentIndexChanged(int index) +{ + if ( this->checkDataDB() ) { + this->ui->box_StatsSpeed_Year->clear(); + if ( index != -1 ) { + this->ui->box_StatsSpeed_Year->addItems( + this->crapview.getYears( this->wsFromIndex( index ) ) ); + this->ui->box_StatsSpeed_Year->setCurrentIndex( 0 ); + } + } + this->checkStatsSpeedDrawable(); +} + +void MainWindow::on_box_StatsSpeed_Year_currentIndexChanged(int index) +{ + this->ui->box_StatsSpeed_Month->clear(); + if ( index != -1 ) { + this->ui->box_StatsSpeed_Month->addItems( + this->crapview.getMonths( + this->wsFromIndex( this->ui->box_StatsSpeed_WebServer->currentIndex() ), + this->ui->box_StatsSpeed_Year->currentText() ) ); + this->ui->box_StatsSpeed_Month->setCurrentIndex( 0 ); + } + this->checkStatsSpeedDrawable(); +} + +void MainWindow::on_box_StatsSpeed_Month_currentIndexChanged(int index) +{ + this->ui->box_StatsSpeed_Day->clear(); + if ( index != -1 ) { + this->ui->box_StatsSpeed_Day->addItems( + this->crapview.getDays( + this->wsFromIndex( this->ui->box_StatsSpeed_WebServer->currentIndex() ), + this->ui->box_StatsSpeed_Year->currentText(), + this->ui->box_StatsSpeed_Month->currentText() ) ); + this->ui->box_StatsSpeed_Day->setCurrentIndex( 0 ); + } + this->checkStatsSpeedDrawable(); +} + +void MainWindow::on_box_StatsSpeed_Day_currentIndexChanged(int index) +{ + this->checkStatsSpeedDrawable(); +} + +void MainWindow::on_button_StatsSpeed_Draw_clicked() +{ + if ( this->checkDataDB() ) { + this->setDbWorkingState( true ); + delete this->crapview_timer; + this->crapview_timer = new QTimer(this); + this->crapview_timer->setSingleShot( true ); + connect(this->crapview_timer, SIGNAL(timeout()), this, SLOT(drawStatsSpeed())); + this->crapview_timer->start(250); + } +} +void MainWindow::drawStatsSpeed() +{ + this->ui->table_StatsSpeed->setRowCount(0); + this->crapview.drawSpeed( + this->ui->table_StatsSpeed, + this->ui->chart_SatsSpeed, + this->CHARTS_THEMES.at( this->charts_theme_id ), this->FONTS, + this->wsFromIndex( this->ui->box_StatsSpeed_WebServer->currentIndex() ), + this->ui->box_StatsSpeed_Year->currentText(), + this->ui->box_StatsSpeed_Month->currentText(), + this->ui->box_StatsSpeed_Day->currentText(), + this->crapview.parseTextualFilter( this->ui->inLine_StatsSpeed_Protocol->text() ), + this->crapview.parseTextualFilter( this->ui->inLine_StatsSpeed_Method->text() ), + this->crapview.parseTextualFilter( this->ui->inLine_StatsSpeed_Uri->text() ), + this->crapview.parseTextualFilter( this->ui->inLine_StatsSpeed_Query->text() ), + this->crapview.parseNumericFilter( this->ui->inLine_StatsSpeed_Response->text() ) ); + this->setDbWorkingState( false ); +} + + +/////////////// +//// COUNT //// +void MainWindow::checkStatsCountDrawable() +{ + if ( ! this->db_working ) { + if ( this->ui->box_StatsCount_Year->currentIndex() >= 0 + && this->ui->box_StatsCount_Month->currentIndex() >= 0 + && this->ui->box_StatsCount_Day->currentIndex() >= 0 ) { + // enable the draw button + this->ui->scrollArea_StatsCount->setEnabled( true ); + } else { + // disable the draw button + this->ui->scrollArea_StatsCount->setEnabled( false ); + } + } else { + this->ui->button_StatsRelat_Draw->setEnabled( false ); + } +} + +void MainWindow::on_box_StatsCount_WebServer_currentIndexChanged(int index) +{ + if ( this->checkDataDB() ) { + this->ui->box_StatsCount_Year->clear(); + if ( index != -1 ) { + this->ui->box_StatsCount_Year->addItems( + this->crapview.getYears( this->wsFromIndex( index ) )); + this->ui->box_StatsCount_Year->setCurrentIndex( 0 ); + this->resetStatsCountButtons(); + } + } + this->checkStatsCountDrawable(); +} + +void MainWindow::on_box_StatsCount_Year_currentIndexChanged(int index) +{ + this->ui->box_StatsCount_Month->clear(); + if ( index != -1 ) { + this->ui->box_StatsCount_Month->addItems( + this->crapview.getMonths( + this->wsFromIndex( this->ui->box_StatsCount_WebServer->currentIndex() ), + this->ui->box_StatsCount_Year->currentText() ) ); + this->ui->box_StatsCount_Month->setCurrentIndex( 0 ); + } + this->checkStatsCountDrawable(); +} + +void MainWindow::on_box_StatsCount_Month_currentIndexChanged(int index) +{ + this->ui->box_StatsCount_Day->clear(); + if ( index != -1 ) { + this->ui->box_StatsCount_Day->addItems( + this->crapview.getDays( + this->wsFromIndex( this->ui->box_StatsCount_WebServer->currentIndex() ), + this->ui->box_StatsCount_Year->currentText(), + this->ui->box_StatsCount_Month->currentText() ) ); + this->ui->box_StatsCount_Day->setCurrentIndex( 0 ); + } + this->checkStatsCountDrawable(); +} + +void MainWindow::on_box_StatsCount_Day_currentIndexChanged(int index) +{ + this->checkStatsCountDrawable(); +} + +void MainWindow::resetStatsCountButtons() +{ + if ( ! this->ui->button_StatsCount_Protocol->isFlat() ) { + this->ui->button_StatsCount_Protocol->setFlat( true ); + } + if ( ! this->ui->button_StatsCount_Method->isFlat() ) { + this->ui->button_StatsCount_Method->setFlat( true ); + } + if ( ! this->ui->button_StatsCount_Uri->isFlat() ) { + this->ui->button_StatsCount_Uri->setFlat( true ); + } + if ( ! this->ui->button_StatsCount_Query->isFlat() ) { + this->ui->button_StatsCount_Query->setFlat( true ); + } + if ( ! this->ui->button_StatsCount_Response->isFlat() ) { + this->ui->button_StatsCount_Response->setFlat( true ); + } + if ( ! this->ui->button_StatsCount_Referrer->isFlat() ) { + this->ui->button_StatsCount_Referrer->setFlat( true ); + } + if ( ! this->ui->button_StatsCount_Cookie->isFlat() ) { + this->ui->button_StatsCount_Cookie->setFlat( true ); + } + if ( ! this->ui->button_StatsCount_UserAgent->isFlat() ) { + this->ui->button_StatsCount_UserAgent->setFlat( true ); + } + if ( ! this->ui->button_StatsCount_Client->isFlat() ) { + this->ui->button_StatsCount_Client->setFlat( true ); + } +} + +void MainWindow::startCountDrawing() +{ + this->setDbWorkingState( true ); + delete this->crapview_timer; + this->crapview_timer = new QTimer(this); + this->crapview_timer->setSingleShot( true ); + connect(this->crapview_timer, SIGNAL(timeout()), this, SLOT(drawStatsCount())); + this->crapview_timer->start(250); +} + +void MainWindow::on_button_StatsCount_Protocol_clicked() +{ + if ( this->checkDataDB() ) { + this->resetStatsCountButtons(); + this->ui->button_StatsCount_Protocol->setFlat( false ); + this->count_fld = this->ui->button_StatsCount_Protocol->text(); + startCountDrawing(); + } +} + +void MainWindow::on_button_StatsCount_Method_clicked() +{ + if ( this->checkDataDB() ) { + this->resetStatsCountButtons(); + this->count_fld = this->ui->button_StatsCount_Method->text(); + this->ui->button_StatsCount_Method->setFlat( false ); + startCountDrawing(); + } +} + +void MainWindow::on_button_StatsCount_Uri_clicked() +{ + if ( this->checkDataDB() ) { + this->resetStatsCountButtons(); + this->count_fld = this->ui->button_StatsCount_Uri->text(); + this->ui->button_StatsCount_Uri->setFlat( false ); + startCountDrawing(); + } +} + +void MainWindow::on_button_StatsCount_Query_clicked() +{ + if ( this->checkDataDB() ) { + this->resetStatsCountButtons(); + this->count_fld = this->ui->button_StatsCount_Query->text(); + this->ui->button_StatsCount_Query->setFlat( false ); + startCountDrawing(); + } +} + +void MainWindow::on_button_StatsCount_Response_clicked() +{ + if ( this->checkDataDB() ) { + this->resetStatsCountButtons(); + this->count_fld = this->ui->button_StatsCount_Response->text(); + this->ui->button_StatsCount_Response->setFlat( false ); + startCountDrawing(); + } +} + +void MainWindow::on_button_StatsCount_Referrer_clicked() +{ + if ( this->checkDataDB() ) { + this->resetStatsCountButtons(); + this->count_fld = this->ui->button_StatsCount_Referrer->text(); + this->ui->button_StatsCount_Referrer->setFlat( false ); + startCountDrawing(); + } +} + +void MainWindow::on_button_StatsCount_Cookie_clicked() +{ + if ( this->checkDataDB() ) { + this->resetStatsCountButtons(); + this->count_fld = this->ui->button_StatsCount_Cookie->text(); + this->ui->button_StatsCount_Cookie->setFlat( false ); + startCountDrawing(); + } +} + +void MainWindow::on_button_StatsCount_UserAgent_clicked() +{ + if ( this->checkDataDB() ) { + this->resetStatsCountButtons(); + this->count_fld = this->ui->button_StatsCount_UserAgent->text(); + this->ui->button_StatsCount_UserAgent->setFlat( false ); + startCountDrawing(); + } +} + +void MainWindow::on_button_StatsCount_Client_clicked() +{ + if ( this->checkDataDB() ) { + this->resetStatsCountButtons(); + this->count_fld = this->ui->button_StatsCount_Client->text(); + this->ui->button_StatsCount_Client->setFlat( false ); + startCountDrawing(); + } +} + +void MainWindow::drawStatsCount() +{ + this->ui->table_StatsCount->setRowCount(0); + this->crapview.drawCount( + this->ui->table_StatsCount, this->ui->chart_StatsCount, + this->CHARTS_THEMES.at( this->charts_theme_id ), this->FONTS, + this->wsFromIndex( this->ui->box_StatsCount_WebServer->currentIndex() ), + this->ui->box_StatsCount_Year->currentText(), + this->ui->box_StatsCount_Month->currentText(), + this->ui->box_StatsCount_Day->currentText(), + this->count_fld ); + this->setDbWorkingState( false ); +} + + +///////////// +//// DAY //// +void MainWindow::checkStatsDayDrawable() +{ + if ( ! this->db_working ) { + bool aux = true; + // secondary date (period) + if ( this->ui->checkBox_StatsDay_Period->isChecked() ) { + if ( this->ui->box_StatsDay_ToYear->currentIndex() < 0 + && this->ui->box_StatsDay_ToMonth->currentIndex() < 0 + && this->ui->box_StatsDay_ToDay->currentIndex() < 0 ) { + aux = false; + } else { + int a,b; + a = this->ui->box_StatsDay_ToYear->currentText().toInt(); + b = this->ui->box_StatsDay_FromYear->currentText().toInt(); + if ( a < b ) { + // year 'to' is less than 'from' + aux = false; + } else if ( a == b ) { + a = this->crapview.getMonthNumber( this->ui->box_StatsDay_ToMonth->currentText() ); + b = this->crapview.getMonthNumber( this->ui->box_StatsDay_FromMonth->currentText() ); + if ( a < b ) { + // month 'to' is less than 'from' + aux = false; + } else if ( a == b ) { + a = this->ui->box_StatsDay_ToDay->currentText().toInt(); + b = this->ui->box_StatsDay_FromDay->currentText().toInt(); + if ( a < b ) { + // day 'to' is less than 'from' + aux = false; + } + } + } + } + } + // primary date + if ( this->ui->box_StatsDay_FromYear->currentIndex() < 0 + && this->ui->box_StatsDay_FromMonth->currentIndex() < 0 + && this->ui->box_StatsDay_FromDay->currentIndex() < 0 ) { + aux = false; + } + // check log field validity + if ( this->ui->box_StatsDay_LogsField->currentIndex() < 0 ) { + aux = false; + } + this->ui->button_StatsDay_Draw->setEnabled( aux); + + } else { + // db busy + this->ui->button_StatsRelat_Draw->setEnabled( false ); + } +} + +void MainWindow::on_box_StatsDay_WebServer_currentIndexChanged(int index) +{ + if ( this->checkDataDB() ) { + this->ui->box_StatsDay_LogsField->clear(); + this->ui->box_StatsDay_FromYear->clear(); + this->ui->box_StatsDay_ToYear->clear(); + if ( index != -1 ) { + // refresh fields + this->ui->box_StatsDay_LogsField->addItems( + this->crapview.getFields( "Daytime" )); + this->ui->box_StatsDay_LogsField->setCurrentIndex( 0 ); + // refresh dates + QStringList years = this->crapview.getYears( this->wsFromIndex( index ) ); + this->ui->box_StatsDay_FromYear->addItems( years ); + this->ui->box_StatsDay_FromYear->setCurrentIndex( 0 ); + if ( this->ui->checkBox_StatsDay_Period->isChecked() ) { + this->ui->box_StatsDay_ToYear->addItems( years ); + this->ui->box_StatsDay_ToYear->setCurrentIndex( 0 ); + } + years.clear(); + } + } + this->checkStatsDayDrawable(); +} + + +void MainWindow::on_box_StatsDay_LogsField_currentIndexChanged(int index) +{ + this->ui->inLine_StatsDay_Filter->clear(); + this->checkStatsDayDrawable(); +} + +void MainWindow::on_box_StatsDay_FromYear_currentIndexChanged(int index) +{ + this->ui->box_StatsDay_FromMonth->clear(); + if ( index != -1 ) { + this->ui->box_StatsDay_FromMonth->addItems( + this->crapview.getMonths( + this->wsFromIndex( this->ui->box_StatsDay_WebServer->currentIndex() ), + this->ui->box_StatsDay_FromYear->currentText() ) ); + this->ui->box_StatsDay_FromMonth->setCurrentIndex( 0 ); + } + this->checkStatsDayDrawable(); +} + +void MainWindow::on_box_StatsDay_FromMonth_currentIndexChanged(int index) +{ + this->ui->box_StatsDay_FromDay->clear(); + if ( index != -1 ) { + this->ui->box_StatsDay_FromDay->addItems( + this->crapview.getDays( + this->wsFromIndex( this->ui->box_StatsDay_WebServer->currentIndex() ), + this->ui->box_StatsDay_FromYear->currentText(), + this->ui->box_StatsDay_FromMonth->currentText() ) ); + this->ui->box_StatsDay_FromDay->setCurrentIndex( 0 ); + } + this->checkStatsDayDrawable(); +} + +void MainWindow::on_box_StatsDay_FromDay_currentIndexChanged(int index) +{ + this->checkStatsDayDrawable(); +} + +void MainWindow::on_checkBox_StatsDay_Period_stateChanged(int state) +{ + if ( state == Qt::CheckState::Checked ) { + this->ui->box_StatsDay_ToYear->setEnabled( true ); + this->ui->box_StatsDay_ToMonth->setEnabled( true ); + this->ui->box_StatsDay_ToDay->setEnabled( true ); + // add available dates + this->ui->box_StatsDay_ToYear->addItems( this->crapview.getYears( + this->wsFromIndex( this->ui->box_StatsDay_WebServer->currentIndex() ) ) ); + this->ui->box_StatsDay_ToYear->setCurrentIndex( 0 ); + } else { + this->ui->box_StatsDay_ToYear->clear(); + this->ui->box_StatsDay_ToYear->setEnabled( false ); + this->ui->box_StatsDay_ToMonth->clear(); + this->ui->box_StatsDay_ToMonth->setEnabled( false ); + this->ui->box_StatsDay_ToDay->clear(); + this->ui->box_StatsDay_ToDay->setEnabled( false ); + } +} + +void MainWindow::on_box_StatsDay_ToYear_currentIndexChanged(int index) +{ + this->ui->box_StatsDay_ToMonth->clear(); + if ( index != -1 ) { + this->ui->box_StatsDay_ToMonth->addItems( + this->crapview.getMonths( + this->wsFromIndex( this->ui->box_StatsDay_WebServer->currentIndex() ), + this->ui->box_StatsDay_ToYear->currentText() ) ); + this->ui->box_StatsDay_ToMonth->setCurrentIndex( 0 ); + } + this->checkStatsDayDrawable(); +} + +void MainWindow::on_box_StatsDay_ToMonth_currentIndexChanged(int index) +{ + this->ui->box_StatsDay_ToDay->clear(); + if ( index != -1 ) { + this->ui->box_StatsDay_ToDay->addItems( + this->crapview.getDays( + this->wsFromIndex( this->ui->box_StatsDay_WebServer->currentIndex() ), + this->ui->box_StatsDay_ToYear->currentText(), + this->ui->box_StatsDay_ToMonth->currentText() ) ); + this->ui->box_StatsDay_ToDay->setCurrentIndex( 0 ); + } + this->checkStatsDayDrawable(); +} + +void MainWindow::on_box_StatsDay_ToDay_currentIndexChanged(int index) +{ + this->checkStatsDayDrawable(); +} + + +void MainWindow::on_button_StatsDay_Draw_clicked() +{ + if ( this->checkDataDB() ) { + this->setDbWorkingState( true ); + delete this->crapview_timer; + this->crapview_timer = new QTimer(this); + this->crapview_timer->setSingleShot( true ); + connect(this->crapview_timer, SIGNAL(timeout()), this, SLOT(drawStatsDay())); + this->crapview_timer->start(250); + } +} +void MainWindow::drawStatsDay() +{ + QString filter; + if ( this->ui->box_StatsDay_LogsField->currentIndex() == 0 ) { + filter = this->crapview.parseBooleanFilter( this->ui->inLine_StatsDay_Filter->text() ); + } else if ( this->ui->box_StatsDay_LogsField->currentIndex() == 5 ) { + filter = this->crapview.parseNumericFilter( this->ui->inLine_StatsDay_Filter->text() ); + } else { + filter = this->crapview.parseTextualFilter( this->ui->inLine_StatsDay_Filter->text() ); + } + this->crapview.drawDay( + this->ui->chart_StatsDay, + this->CHARTS_THEMES.at( this->charts_theme_id ), this->FONTS, + this->wsFromIndex( this->ui->box_StatsDay_WebServer->currentIndex() ), + this->ui->box_StatsDay_FromYear->currentText(), + this->ui->box_StatsDay_FromMonth->currentText(), + this->ui->box_StatsDay_FromDay->currentText(), + ( this->ui->checkBox_StatsDay_Period->isChecked() ) ? this->ui->box_StatsDay_ToYear->currentText() : "", + ( this->ui->checkBox_StatsDay_Period->isChecked() ) ? this->ui->box_StatsDay_ToMonth->currentText() : "", + ( this->ui->checkBox_StatsDay_Period->isChecked() ) ? this->ui->box_StatsDay_ToDay->currentText() : "", + this->ui->box_StatsDay_LogsField->currentText(), + filter ); + this->setDbWorkingState( false ); +} + + + +//////////////////// +//// RELATIONAL //// +void MainWindow::checkStatsRelatDrawable() +{ + if ( ! this->db_working ) { + bool aux = true; + if ( this->ui->box_StatsRelat_FromYear->currentIndex() >= 0 + && this->ui->box_StatsRelat_FromMonth->currentIndex() >= 0 + && this->ui->box_StatsRelat_FromDay->currentIndex() >= 0 + && this->ui->box_StatsRelat_ToYear->currentIndex() >= 0 + && this->ui->box_StatsRelat_ToMonth->currentIndex() >= 0 + && this->ui->box_StatsRelat_ToDay->currentIndex() >= 0 ) { + // check period validity + int a,b; + a = this->ui->box_StatsRelat_ToYear->currentText().toInt(); + b = this->ui->box_StatsRelat_FromYear->currentText().toInt(); + if ( a < b ) { + // year 'to' is less than 'from' + aux = false; + } else if ( a == b ) { + a = this->crapview.getMonthNumber( this->ui->box_StatsRelat_ToMonth->currentText() ); + b = this->crapview.getMonthNumber( this->ui->box_StatsRelat_FromMonth->currentText() ); + if ( a < b ) { + // month 'to' is less than 'from' + aux = false; + } else if ( a == b ) { + a = this->ui->box_StatsRelat_ToDay->currentText().toInt(); + b = this->ui->box_StatsRelat_FromDay->currentText().toInt(); + if ( a < b ) { + // day 'to' is less than 'from' + aux = false; + } + } + } + } else { + // disable the draw button + aux = false; + } + // check log field validity + if ( this->ui->box_StatsRelat_LogsField_1->currentIndex() < 0 + || this->ui->box_StatsRelat_LogsField_2->currentIndex() < 0 ) { + aux = false; + } + this->ui->button_StatsRelat_Draw->setEnabled( aux ); + + } else { + // db busy + this->ui->button_StatsRelat_Draw->setEnabled( false ); + } +} + +void MainWindow::on_box_StatsRelat_WebServer_currentIndexChanged(int index) +{ + if ( this->checkDataDB() ) { + this->ui->box_StatsRelat_LogsField_1->clear(); + this->ui->box_StatsRelat_LogsField_2->clear(); + if ( index != -1 ) { + // refresh fields + QStringList fields = this->crapview.getFields( "Relational" ); + this->ui->box_StatsRelat_LogsField_1->addItems( fields ); + this->ui->box_StatsRelat_LogsField_2->addItems( fields ); + this->ui->box_StatsRelat_LogsField_1->setCurrentIndex( 0 ); + this->ui->box_StatsRelat_LogsField_2->setCurrentIndex( 0 ); + // refresh dates + QStringList years = this->crapview.getYears( this->wsFromIndex( index ) ); + // from + this->ui->box_StatsRelat_FromYear->clear(); + this->ui->box_StatsRelat_FromYear->addItems( years ); + this->ui->box_StatsRelat_FromYear->setCurrentIndex( 0 ); + // to + this->ui->box_StatsRelat_ToYear->clear(); + this->ui->box_StatsRelat_ToYear->addItems( years ); + this->ui->box_StatsRelat_ToYear->setCurrentIndex( 0 ); + years.clear(); + } + } + this->checkStatsRelatDrawable(); +} + +void MainWindow::on_box_StatsRelat_LogsField_1_currentIndexChanged(int index) +{ + this->ui->inLine_StatsRelat_Filter_1->clear(); + this->checkStatsRelatDrawable(); +} + +void MainWindow::on_box_StatsRelat_LogsField_2_currentIndexChanged(int index) +{ + this->ui->inLine_StatsRelat_Filter_2->clear(); + this->checkStatsRelatDrawable(); +} + +void MainWindow::on_box_StatsRelat_FromYear_currentIndexChanged(int index) +{ + this->ui->box_StatsRelat_FromMonth->clear(); + if ( index != -1 ) { + this->ui->box_StatsRelat_FromMonth->addItems( + this->crapview.getMonths( + this->wsFromIndex( this->ui->box_StatsRelat_WebServer->currentIndex() ), + this->ui->box_StatsRelat_FromYear->currentText() ) ); + this->ui->box_StatsRelat_FromMonth->setCurrentIndex( 0 ); + } + this->checkStatsRelatDrawable(); +} + +void MainWindow::on_box_StatsRelat_FromMonth_currentIndexChanged(int index) +{ + this->ui->box_StatsRelat_FromDay->clear(); + if ( index != -1 ) { + this->ui->box_StatsRelat_FromDay->addItems( + this->crapview.getDays( + this->wsFromIndex( this->ui->box_StatsRelat_WebServer->currentIndex() ), + this->ui->box_StatsRelat_FromYear->currentText(), + this->ui->box_StatsRelat_FromMonth->currentText() ) ); + this->ui->box_StatsRelat_FromDay->setCurrentIndex( 0 ); + } + this->checkStatsRelatDrawable(); +} + +void MainWindow::on_box_StatsRelat_FromDay_currentIndexChanged(int index) +{ + this->checkStatsRelatDrawable(); +} + +void MainWindow::on_box_StatsRelat_ToYear_currentIndexChanged(int index) +{ + this->ui->box_StatsRelat_ToMonth->clear(); + if ( index != -1 ) { + this->ui->box_StatsRelat_ToMonth->addItems( + this->crapview.getMonths( + this->wsFromIndex( this->ui->box_StatsRelat_WebServer->currentIndex() ), + this->ui->box_StatsRelat_ToYear->currentText() ) ); + this->ui->box_StatsRelat_ToMonth->setCurrentIndex( 0 ); + } + this->checkStatsRelatDrawable(); +} + +void MainWindow::on_box_StatsRelat_ToMonth_currentIndexChanged(int index) +{ + this->ui->box_StatsRelat_ToDay->clear(); + if ( index != -1 ) { + this->ui->box_StatsRelat_ToDay->addItems( + this->crapview.getDays( + this->wsFromIndex( this->ui->box_StatsRelat_WebServer->currentIndex() ), + this->ui->box_StatsRelat_ToYear->currentText(), + this->ui->box_StatsRelat_ToMonth->currentText() ) ); + this->ui->box_StatsRelat_ToDay->setCurrentIndex( 0 ); + } + this->checkStatsRelatDrawable(); +} + +void MainWindow::on_box_StatsRelat_ToDay_currentIndexChanged(int index) +{ + this->checkStatsRelatDrawable(); +} + + +void MainWindow::on_button_StatsRelat_Draw_clicked() +{ + if ( this->checkDataDB() ) { + this->setDbWorkingState( true ); + delete this->crapview_timer; + this->crapview_timer = new QTimer(this); + this->crapview_timer->setSingleShot( true ); + connect(this->crapview_timer, SIGNAL(timeout()), this, SLOT(drawStatsRelat())); + this->crapview_timer->start(250); + } +} +void MainWindow::drawStatsRelat() +{ + int aux; + QString filter1, filter2; + aux = this->ui->box_StatsRelat_LogsField_1->currentIndex(); + if ( aux == 0 ) { + filter1 = this->crapview.parseBooleanFilter( this->ui->inLine_StatsRelat_Filter_1->text() ); + } else if ( aux >= 5 && aux <= 8 ) { + filter1 = this->crapview.parseNumericFilter( this->ui->inLine_StatsRelat_Filter_1->text() ); + } else { + filter1 = this->ui->inLine_StatsRelat_Filter_1->text(); + } + aux = this->ui->box_StatsRelat_LogsField_2->currentIndex(); + if ( aux == 0 ) { + filter2 = this->crapview.parseBooleanFilter( this->ui->inLine_StatsRelat_Filter_2->text() ); + } else if ( aux >= 5 && aux <= 8 ) { + filter2 = this->crapview.parseNumericFilter( this->ui->inLine_StatsRelat_Filter_2->text() ); + } else { + filter2 = this->crapview.parseTextualFilter( this->ui->inLine_StatsRelat_Filter_2->text() ); + } + this->crapview.drawRelat( + this->ui->chart_StatsRelat, + this->CHARTS_THEMES.at( this->charts_theme_id ), this->FONTS, + this->wsFromIndex( this->ui->box_StatsRelat_WebServer->currentIndex() ), + this->ui->box_StatsRelat_FromYear->currentText(), + this->ui->box_StatsRelat_FromMonth->currentText(), + this->ui->box_StatsRelat_FromDay->currentText(), + this->ui->box_StatsRelat_ToYear->currentText(), + this->ui->box_StatsRelat_ToMonth->currentText(), + this->ui->box_StatsRelat_ToDay->currentText(), + this->ui->box_StatsRelat_LogsField_1->currentText(), filter1, + this->ui->box_StatsRelat_LogsField_2->currentText(), filter2 ); + this->setDbWorkingState( false ); +} + + + +//////////////// +//// GLOBAL //// +// +void MainWindow::makeStatsGlobals() +{ + if ( this->checkDataDB() ) { + std::vector> recur_list; + std::vector> traffic_list; + std::vector> perf_list; + std::vector work_list; + + const bool result = this->crapview.calcGlobals( + recur_list, traffic_list, perf_list, work_list, + this->glob_ws ); + + if ( result ) { + this->ui->label_StatsGlob_Recur_Protocol_String->setText( std::get<0>( recur_list.at(0) ) ); + this->ui->label_StatsGlob_Recur_Protocol_Count->setText( std::get<1>( recur_list.at(0) ) ); + this->ui->label_StatsGlob_Recur_Method_String->setText( std::get<0>( recur_list.at(1) ) ); + this->ui->label_StatsGlob_Recur_Method_Count->setText( std::get<1>( recur_list.at(1) ) ); + this->ui->label_StatsGlob_Recur_URI_String->setText( std::get<0>( recur_list.at(2) ) ); + this->ui->label_StatsGlob_Recur_URI_Count->setText( std::get<1>( recur_list.at(2) ) ); + this->ui->label_StatsGlob_Recur_UserAgent_String->setText( std::get<0>( recur_list.at(3) ) ); + this->ui->label_StatsGlob_Recur_UserAgent_Count->setText( std::get<1>( recur_list.at(3) ) ); + + this->ui->label_StatsGlob_Traffic_Date_String->setText( std::get<0>( traffic_list.at(0) ) ); + this->ui->label_StatsGlob_Traffic_Date_Count->setText( std::get<1>( traffic_list.at(0) ) ); + this->ui->label_StatsGlob_Traffic_Day_String->setText( std::get<0>( traffic_list.at(1) ) ); + this->ui->label_StatsGlob_Traffic_Day_Count->setText( std::get<1>( traffic_list.at(1) ) ); + this->ui->label_StatsGlob_Traffic_Hour_String->setText( std::get<0>( traffic_list.at(2) ) ); + this->ui->label_StatsGlob_Traffic_Hour_Count->setText( std::get<1>( traffic_list.at(2) ) ); + + this->ui->label_StatsGlob_Perf_Time_Mean->setText( std::get<0>( perf_list.at(0) ) ); + this->ui->label_StatsGlob_Perf_Time_Max->setText( std::get<1>( perf_list.at(0) ) ); + this->ui->label_StatsGlob_Perf_Sent_Mean->setText( std::get<0>( perf_list.at(1) ) ); + this->ui->label_StatsGlob_Perf_Sent_Max->setText( std::get<1>( perf_list.at(1) ) ); + this->ui->label_StatsGlob_Perf_Received_Mean->setText( std::get<0>( perf_list.at(2) ) ); + this->ui->label_StatsGlob_Perf_Received_Max->setText( std::get<1>( perf_list.at(2) ) ); + + this->ui->label_StatsGlob_Work_Req_Count->setText( work_list.at(0) ); + this->ui->label_StatsGlob_Work_Time_Count->setText( work_list.at(1) ); + this->ui->label_StatsGlob_Work_Sent_Count->setText( work_list.at(2) ); + + if ( this->glob_ws == "apache" ) { + if ( this->ui->button_StatsGlob_Apache->isFlat() ) { + // un-flat + this->ui->button_StatsGlob_Apache->setFlat( false ); + this->ui->button_StatsGlob_Nginx->setFlat( true ); + this->ui->button_StatsGlob_Iis->setFlat( true ); + } + } else if ( this->glob_ws == "nginx" ) { + if ( this->ui->button_StatsGlob_Nginx->isFlat() ) { + // un-flat + this->ui->button_StatsGlob_Nginx->setFlat( false ); + this->ui->button_StatsGlob_Apache->setFlat( true ); + this->ui->button_StatsGlob_Iis->setFlat( true ); + } + } else if ( this->glob_ws == "iis" ) { + if ( this->ui->button_StatsGlob_Iis->isFlat() ) { + // un-flat + this->ui->button_StatsGlob_Iis->setFlat( false ); + this->ui->button_StatsGlob_Apache->setFlat( true ); + this->ui->button_StatsGlob_Nginx->setFlat( true ); + } + } + + } else { + this->resetStatsGlobals(); + } + recur_list.clear(); traffic_list.clear(); + perf_list.clear(); work_list.clear(); + + } else { + this->resetStatsGlobals(); + } + // restore + this->setDbWorkingState( false ); +} + +void MainWindow::resetStatsGlobals() +{ + this->ui->label_StatsGlob_Recur_Protocol_String->setText( "-" ); + this->ui->label_StatsGlob_Recur_Protocol_Count->setText( "0" ); + this->ui->label_StatsGlob_Recur_Method_String->setText( "-" ); + this->ui->label_StatsGlob_Recur_Method_Count->setText( "0" ); + this->ui->label_StatsGlob_Recur_URI_String->setText( "-" ); + this->ui->label_StatsGlob_Recur_URI_Count->setText( "0" ); + this->ui->label_StatsGlob_Recur_UserAgent_String->setText( "-" ); + this->ui->label_StatsGlob_Recur_UserAgent_Count->setText( "0" ); + + this->ui->label_StatsGlob_Traffic_Date_String->setText( "-" ); + this->ui->label_StatsGlob_Traffic_Date_Count->setText( "0" ); + this->ui->label_StatsGlob_Traffic_Day_String->setText( "-" ); + this->ui->label_StatsGlob_Traffic_Day_Count->setText( "0" ); + this->ui->label_StatsGlob_Traffic_Hour_String->setText( "-" ); + this->ui->label_StatsGlob_Traffic_Hour_Count->setText( "0" ); + + this->ui->label_StatsGlob_Perf_Time_Mean->setText( "-" ); + this->ui->label_StatsGlob_Perf_Time_Max->setText( "-" ); + this->ui->label_StatsGlob_Perf_Sent_Mean->setText( "-" ); + this->ui->label_StatsGlob_Perf_Sent_Max->setText( "-" ); + this->ui->label_StatsGlob_Perf_Received_Mean->setText( "-" ); + this->ui->label_StatsGlob_Perf_Received_Max->setText( "-" ); + + this->ui->label_StatsGlob_Work_Req_Count->setText( "-" ); + this->ui->label_StatsGlob_Work_Time_Count->setText( "-" ); + this->ui->label_StatsGlob_Work_Sent_Count->setText( "-" ); + + if ( this->ui->button_StatsGlob_Apache->isChecked() ) { + this->ui->button_StatsGlob_Apache->setChecked( false ); + } else if ( this->ui->button_StatsGlob_Nginx->isChecked() ) { + this->ui->button_StatsGlob_Nginx->setChecked( false ); + } else if ( this->ui->button_StatsGlob_Iis->isChecked() ) { + this->ui->button_StatsGlob_Iis->setChecked( false ); + } +} + + + +void MainWindow::globalsButtonClicked() +{ + this->setDbWorkingState( true ); + delete this->crapview_timer; + this->crapview_timer = new QTimer(this); + this->crapview_timer->setSingleShot( true ); + connect(this->crapview_timer, SIGNAL(timeout()), this, SLOT(makeStatsGlobals())); + this->crapview_timer->start(250); +} + +void MainWindow::on_button_StatsGlob_Apache_clicked() +{ + if ( this->checkDataDB() ) { + this->glob_ws = "apache"; + this->globalsButtonClicked(); + } +} + + +void MainWindow::on_button_StatsGlob_Nginx_clicked() +{ + if ( this->checkDataDB() ) { + this->glob_ws = "nginx"; + this->globalsButtonClicked(); + } +} + + +void MainWindow::on_button_StatsGlob_Iis_clicked() +{ + if ( this->checkDataDB() ) { + this->glob_ws = "iis"; + this->globalsButtonClicked(); + } +} + + + +///////////////////////// +//////// CONFIGS //////// +///////////////////////// + +///////////////// +//// GENERAL //// +///////////////// + +//////////////// +//// WINDOW //// +void MainWindow::on_checkBox_ConfWindow_Geometry_clicked(bool checked) +{ + this->remember_window = checked; +} + +void MainWindow::on_box_ConfWindow_Theme_currentIndexChanged(int index) +{ + this->window_theme_id = index; + this->updateUiTheme(); +} + +void MainWindow::on_box_ConfWindow_Icons_currentIndexChanged(int index) +{ + this->icons_theme_id = index; + this->updateUiIcons(); +} + + +///////////////// +//// DIALOGS //// +void MainWindow::on_slider_ConfDialogs_General_sliderReleased() +{ + this->dialogs_level = this->ui->slider_ConfDialogs_General->value(); +} +void MainWindow::on_slider_ConfDialogs_Logs_sliderReleased() +{ + this->craplog.setDialogsLevel( this->ui->slider_ConfDialogs_Logs->value() ); +} +void MainWindow::on_slider_ConfDialogs_Stats_sliderReleased() +{ + this->crapview.setDialogsLevel( this->ui->slider_ConfDialogs_Stats->value() ); +} + + +////////////////////// +//// TEXT BROWSER //// +void MainWindow::on_box_ConfTextBrowser_Font_currentIndexChanged(int index) +{ + QFont font; + switch ( index ) { + case 0: + font = this->FONTS.at( "main" ); + break; + case 1: + font = this->FONTS.at( "alternative" ); + break; + case 2: + font = this->FONTS.at( "script" ); + break; + default: + throw GenericException( "Unexpected Font index: "+std::to_string(index), true ); + } + this->TB.setFont( font ); + this->crapnote->setTextFont( font ); + this->ui->textBrowser_ConfTextBrowser_Preview->setFont( font ); + this->ui->preview_ConfApache_Format_Sample->setFont( this->TB.getFont() ); + this->ui->preview_ConfNginx_Format_Sample->setFont( this->TB.getFont() ); + this->ui->preview_ConfIis_Format_Sample->setFont( this->TB.getFont() ); +} +void MainWindow::on_checkBox_ConfTextBrowser_WideLines_clicked(bool checked) +{ + this->TB.setWideLinesUsage( checked ); + this->refreshTextBrowserPreview(); +} +void MainWindow::on_box_ConfTextBrowser_ColorScheme_currentIndexChanged(int index) +{ + this->TB.setColorScheme( index, this->TB_COLOR_SCHEMES.at( index ) ); + this->crapnote->setColorScheme( index ); + this->refreshTextBrowserPreview(); +} +void MainWindow::refreshTextBrowserPreview() +{ + QString content = ""; + this->TB.makePreview( content ); + this->ui->textBrowser_ConfTextBrowser_Preview->setText( content ); + this->ui->textBrowser_ConfTextBrowser_Preview->setFont( this->TB.getFont() ); +} + + +//////////////// +//// CHARTS //// +void MainWindow::on_box_ConfCharts_Theme_currentIndexChanged(int index) +{ + this->charts_theme_id = index; + this->refreshChartsPreview(); +} +void MainWindow::refreshChartsPreview() +{ + QColor col = Qt::GlobalColor::darkGreen; + QBarSet *bars_1 = new QBarSet( "" ); + bars_1->setColor( col ); + QBarSet *bars_2 = new QBarSet( "" ); + bars_2->setColor( col ); + QBarSet *bars_3 = new QBarSet( "" ); + bars_3->setColor( col ); + QBarSet *bars_4 = new QBarSet( "" ); + bars_4->setColor( col ); + QBarSet *bars_5 = new QBarSet( "" ); + bars_5->setColor( col ); + QBarSet *bars_6 = new QBarSet( "" ); + bars_6->setColor( col ); + + int aux, max=0; + for ( int i=0; i<24; i++ ) { + aux = rand() %100; *bars_1 << aux; + if ( aux > max ) { max = aux; } + aux = rand() %100; *bars_2 << aux; + if ( aux > max ) { max = aux; } + aux = rand() %100; *bars_3 << aux; + if ( aux > max ) { max = aux; } + aux = rand() %100; *bars_4 << aux; + if ( aux > max ) { max = aux; } + aux = rand() %100; *bars_5 << aux; + if ( aux > max ) { max = aux; } + aux = rand() %100; *bars_6 << aux; + if ( aux > max ) { max = aux; } + } + + QBarSeries *bars = new QBarSeries(); + bars->append( bars_1 ); bars->append( bars_2 ); bars->append( bars_3 ); + bars->append( bars_4 ); bars->append( bars_5 ); bars->append( bars_6 ); + bars->setBarWidth( 1 ); + + QChart *t_chart = new QChart(); + // apply the theme + t_chart->setTheme( this->CHARTS_THEMES.at( this->charts_theme_id ) ); + // add the bars + t_chart->addSeries( bars ); + t_chart->setTitle( "Sample preview" ); + t_chart->setTitleFont( this->FONTS.at("main") ); + t_chart->setAnimationOptions( QChart::SeriesAnimations ); + + QStringList categories; + categories << "00" << "01" << "02" << "03" << "04" << "05" << "06" << "07" << "08" << "09" << "10" << "11" + << "12" << "13" << "14" << "15" << "16" << "17" << "18" << "19" << "20" << "21" << "22" << "23"; + + QBarCategoryAxis *axisX = new QBarCategoryAxis(); + axisX->append( categories ); + axisX->setLabelsFont( this->FONTS.at( "main_small" ) ); + axisX->setTitleText( "Infoes" ); + axisX->setTitleFont( this->FONTS.at("main_small") ); + t_chart->addAxis( axisX, Qt::AlignBottom ); + bars->attachAxis( axisX ); + + QValueAxis *axisY = new QValueAxis(); + axisY->setLabelFormat( "%d" ); + axisY->setRange( 0, max ); + axisY->setLabelsFont( this->FONTS.at( "main_small" ) ); + t_chart->addAxis( axisY, Qt::AlignLeft ); + bars->attachAxis( axisY) ; + + t_chart->legend()->setVisible( false ); + /*t_chart->legend()->setFont( this->FONTS.at("main_small") ); + t_chart->legend()->setAlignment( Qt::AlignBottom );*/ + + this->ui->chart_ConfCharts_Preview->setChart( t_chart ); + this->ui->chart_ConfCharts_Preview->setRenderHint( QPainter::Antialiasing ); +} + + +/////////////////// +//// DATABASES //// +// data collection +void MainWindow::on_inLine_ConfDatabases_Data_Path_textChanged(const QString &arg1) +{ + if ( arg1.size() > 0 ) { + std::string path = this->resolvePath( arg1.toStdString() ); + if ( IOutils::checkDir( path ) ) { + this->ui->icon_ConfDatabases_Data_Wrong->setVisible( false ); + this->ui->button_ConfDatabases_Data_Save->setEnabled( true ); + } else { + this->ui->icon_ConfDatabases_Data_Wrong->setVisible( true ); + this->ui->button_ConfDatabases_Data_Save->setEnabled( false ); + } + } else { + this->ui->icon_ConfDatabases_Data_Wrong->setVisible( true ); + this->ui->button_ConfDatabases_Data_Save->setEnabled( false ); + } +} +void MainWindow::on_inLine_ConfDatabases_Data_Path_returnPressed() +{ + this->on_button_ConfDatabases_Data_Save_clicked(); +} +void MainWindow::on_button_ConfDatabases_Data_Save_clicked() +{ + if ( ! this->ui->icon_ConfDatabases_Data_Wrong->isVisible() ) { + // set the paths + std::string path = this->resolvePath( this->ui->inLine_ConfDatabases_Data_Path->text().toStdString() ); + if ( StringOps::endsWith( path, "/" ) ) { + path = StringOps::rstrip( path, "/" ); + } + if ( ! IOutils::checkDir( path, true ) ) { + DialogSec::warnDirNotReadable( nullptr ); + } + if ( ! IOutils::checkDir( path, false, true ) ) { + DialogSec::warnDirNotWritable( nullptr ); + } + this->db_data_path = path; + this->craplog.setStatsDatabasePath( path ); + this->crapview.setDbPath( path ); + this->ui->inLine_ConfDatabases_Data_Path->setText( QString::fromStdString( path ) ); + } + this->ui->inLine_ConfDatabases_Data_Path->setFocus(); + this->ui->button_ConfDatabases_Data_Save->setEnabled( false ); +} + +// usef files hashes +void MainWindow::on_inLine_ConfDatabases_Hashes_Path_textChanged(const QString &arg1) +{ + if ( arg1.size() > 0 ) { + std::string path = this->resolvePath( arg1.toStdString() ); + if ( IOutils::checkDir( path ) ) { + this->ui->icon_ConfDatabases_Hashes_Wrong->setVisible( false ); + this->ui->button_ConfDatabases_Hashes_Save->setEnabled( true ); + } else { + this->ui->icon_ConfDatabases_Hashes_Wrong->setVisible( true ); + this->ui->button_ConfDatabases_Hashes_Save->setEnabled( false ); + } + } else { + this->ui->icon_ConfDatabases_Hashes_Wrong->setVisible( true ); + this->ui->button_ConfDatabases_Hashes_Save->setEnabled( false ); + } +} +void MainWindow::on_inLine_ConfDatabases_Hashes_Path_returnPressed() +{ + this->on_button_ConfDatabases_Hashes_Save_clicked(); +} +void MainWindow::on_button_ConfDatabases_Hashes_Save_clicked() +{ + if ( ! this->ui->icon_ConfDatabases_Hashes_Wrong->isVisible() ) { + // set the paths + std::string path = this->resolvePath( this->ui->inLine_ConfDatabases_Hashes_Path->text().toStdString() ); + if ( StringOps::endsWith( path, "/" ) ) { + path = StringOps::rstrip( path, "/" ); + } + if ( ! IOutils::checkDir( path, true ) ) { + DialogSec::warnDirNotReadable( nullptr ); + } + if ( ! IOutils::checkDir( path, false, true ) ) { + DialogSec::warnDirNotWritable( nullptr ); + } + this->db_hashes_path = path; + this->craplog.setHashesDatabasePath( path ); + this->ui->inLine_ConfDatabases_Hashes_Path->setText( QString::fromStdString( path ) ); + } + this->ui->inLine_ConfDatabases_Hashes_Path->setFocus(); + this->ui->button_ConfDatabases_Hashes_Save->setEnabled( false ); +} + +// backups +void MainWindow::on_checkBox_ConfDatabases_DoBackup_clicked(bool checked) +{ + this->db_do_backup = checked; + this->ui->spinBox_ConfDatabases_NumBackups->setEnabled( checked ); + if ( checked && this->ui->spinBox_ConfDatabases_NumBackups->value() == 0 ) { + this->ui->spinBox_ConfDatabases_NumBackups->setValue( 1 ); + } +} +void MainWindow::on_spinBox_ConfDatabases_NumBackups_valueChanged(int arg1) +{ + this->db_backups_number = arg1; + if ( arg1 == 1 ) { + this->ui->spinBox_ConfDatabases_NumBackups->setSuffix( " " + MainWindow::tr( "copy" ) ); + } else { + this->ui->spinBox_ConfDatabases_NumBackups->setSuffix( " " + MainWindow::tr( "copies" ) ); + if ( arg1 == 0 ) { + this->ui->checkBox_ConfDatabases_DoBackup->setChecked( false ); + this->on_checkBox_ConfDatabases_DoBackup_clicked( false ); + } + } +} + + +////////////// +//// LOGS //// +////////////// + +////////////////// +//// DEFAULTS //// +void MainWindow::on_radio_ConfDefaults_Apache_toggled(bool checked) +{ + this->default_ws = this->APACHE_ID; +} +void MainWindow::on_radio_ConfDefaults_Nginx_toggled(bool checked) +{ + this->default_ws = this->NGINX_ID; +} +void MainWindow::on_radio_ConfDefaults_Iis_toggled(bool checked) +{ + this->default_ws = this->IIS_ID; +} + +///////////////// +//// CONTROL //// +void MainWindow::on_checkBox_ConfControl_Usage_clicked(bool checked) +{ + this->hide_used_files = checked; +} +void MainWindow::on_checkBox_ConfControl_Size_clicked(bool checked) +{ + if ( ! checked ) { + // disable size warning + this->ui->spinBox_ConfControl_Size->setEnabled( false ); + this->craplog.setWarningSize( 0 ); + } else { + // enable warning + this->ui->spinBox_ConfControl_Size->setEnabled( true ); + this->craplog.setWarningSize( (this->ui->spinBox_ConfControl_Size->value() * 1'048'576) +1 ); + } +} +void MainWindow::on_spinBox_ConfControl_Size_editingFinished() +{ + this->craplog.setWarningSize( (this->ui->spinBox_ConfControl_Size->value() * 1'048'576) +1 ); +} + + +//////////////// +//// APACHE //// +// paths +void MainWindow::on_inLine_ConfApache_Path_String_textChanged(const QString &arg1) +{ + if ( arg1.size() > 0 ) { + std::string path = this->resolvePath( arg1.toStdString() ); + if ( IOutils::checkDir( path ) ) { + this->ui->icon_ConfApache_Path_Wrong->setVisible( false ); + this->ui->button_ConfApache_Path_Save->setEnabled( true ); + } else { + this->ui->icon_ConfApache_Path_Wrong->setVisible( true ); + this->ui->button_ConfApache_Path_Save->setEnabled( false ); + } + } else { + this->ui->icon_ConfApache_Path_Wrong->setVisible( true ); + this->ui->button_ConfApache_Path_Save->setEnabled( false ); + } +} +void MainWindow::on_inLine_ConfApache_Path_String_returnPressed() +{ + this->on_button_ConfApache_Path_Save_clicked(); +} +void MainWindow::on_button_ConfApache_Path_Save_clicked() +{ + if ( ! this->ui->icon_ConfApache_Path_Wrong->isVisible() ) { + // set the paths + std::string path = this->resolvePath( this->ui->inLine_ConfApache_Path_String->text().toStdString() ); + if ( StringOps::endsWith( path, "/" ) ) { + path = StringOps::rstrip( path, "/" ); + } + if ( ! IOutils::checkDir( path, true ) ) { + DialogSec::warnDirNotReadable( nullptr ); + } + this->craplog.setLogsPath( this->APACHE_ID, path ); + this->ui->inLine_ConfApache_Path_String->setText( QString::fromStdString( path ) ); + } + this->ui->button_ConfApache_Path_Save->setEnabled( false ); +} + +// formats +void MainWindow::on_inLine_ConfApache_Format_String_cursorPositionChanged(int arg1, int arg2) +{ + if ( arg2 > 0 ) { + this->ui->button_ConfApache_Format_Save->setEnabled( true ); + } else { + this->ui->button_ConfApache_Format_Save->setEnabled( false ); + } +} +void MainWindow::on_inLine_ConfApache_Format_String_returnPressed() +{ + if ( this->ui->button_ConfApache_Format_Save->isEnabled() ) { + this->on_button_ConfApache_Format_Save_clicked(); + } +} +void MainWindow::on_button_ConfApache_Format_Save_clicked() +{ + const bool success = this->craplog.setApacheLogFormat( + this->ui->inLine_ConfApache_Format_String->text().toStdString() ); + if ( success ) { + this->ui->button_ConfApache_Format_Save->setEnabled( false ); + } +} +void MainWindow::on_button_ConfApache_Format_Sample_clicked() +{ + this->ui->preview_ConfApache_Format_Sample->setText( + this->craplog.getLogsFormatSample( this->APACHE_ID ) ); +} +void MainWindow::on_button_ConfApache_Format_Help_clicked() +{ + this->showHelp( "apache_format" ); +} + +// warnlists +void MainWindow::on_box_ConfApache_Warnlist_Field_currentTextChanged(const QString &arg1) +{ + if ( arg1.size() > 0 ) { + this->ui->inLine_ConfApache_Warnlist_String->clear(); + this->ui->list_ConfApache_Warnlist_List->clear(); + // update the list + const std::vector& list = this->craplog.getWarnlist( + this->APACHE_ID, this->crapview.getLogFieldID( arg1 ) ); + for ( const std::string& item : list ) { + this->ui->list_ConfApache_Warnlist_List->addItem( QString::fromStdString( item ) ); + } + // check/uncheck the usage option + const bool used = this->craplog.isWarnlistUsed( + this->APACHE_ID, + this->crapview.getLogFieldID( this->ui->box_ConfApache_Warnlist_Field->currentText() ) ); + this->ui->checkBox_ConfApache_Warnlist_Used->setChecked( used ); + this->on_checkBox_ConfApache_Warnlist_Used_clicked( used ); + } +} +void MainWindow::on_checkBox_ConfApache_Warnlist_Used_clicked(bool checked) +{ + this->craplog.setWarnlistUsed( + this->APACHE_ID, + this->crapview.getLogFieldID( this->ui->box_ConfApache_Warnlist_Field->currentText() ), + checked ); + if ( checked ) { + this->ui->inLine_ConfApache_Warnlist_String->setEnabled( true ); + this->ui->list_ConfApache_Warnlist_List->setEnabled( true ); + } else { + this->ui->inLine_ConfApache_Warnlist_String->clear(); + this->ui->inLine_ConfApache_Warnlist_String->setEnabled( false ); + this->ui->list_ConfApache_Warnlist_List->clearSelection(); + this->ui->list_ConfApache_Warnlist_List->setEnabled( false ); + } +} + +void MainWindow::on_inLine_ConfApache_Warnlist_String_cursorPositionChanged(int arg1, int arg2) +{ + if ( arg2 > 0 ) { + this->ui->button_ConfApache_Warnlist_Add->setEnabled( true ); + } else { + this->ui->button_ConfApache_Warnlist_Add->setEnabled( false ); + } +} +void MainWindow::on_inLine_ConfApache_Warnlist_String_returnPressed() +{ + this->on_button_ConfApache_Warnlist_Add_clicked(); +} +void MainWindow::on_button_ConfApache_Warnlist_Add_clicked() +{ + const QString& item = this->ui->inLine_ConfApache_Warnlist_String->text(); + if ( this->ui->list_ConfApache_Warnlist_List->findItems( item, Qt::MatchFlag::MatchCaseSensitive ).size() == 0 ) { + // not in the list yet, append + try { + this->craplog.warnlistAdd( + this->APACHE_ID, + this->crapview.getLogFieldID( this->ui->box_ConfApache_Warnlist_Field->currentText() ), + item.toStdString() ); + this->ui->list_ConfApache_Warnlist_List->addItem( item ); + } catch ( const BWlistException& ) { + DialogSec::warnInvalidItemBW(); + return; + } + } + // select the item in the list, in both cases it was already in or it has been just inserted + this->ui->list_ConfApache_Warnlist_List->clearSelection(); + this->ui->list_ConfApache_Warnlist_List->findItems( item, Qt::MatchFlag::MatchCaseSensitive ).at(0)->setSelected( true ); + this->ui->inLine_ConfApache_Warnlist_String->clear(); +} + +void MainWindow::on_list_ConfApache_Warnlist_List_itemSelectionChanged() +{ + if ( this->ui->list_ConfApache_Warnlist_List->selectedItems().size() == 1 ) { + this->ui->button_ConfApache_Warnlist_Remove->setEnabled( true ); + this->ui->button_ConfApache_Warnlist_Up->setEnabled( true ); + this->ui->button_ConfApache_Warnlist_Down->setEnabled( true ); + // polishing + const auto& item = this->ui->list_ConfApache_Warnlist_List->selectedItems().at(0); + const int max = this->ui->list_ConfApache_Warnlist_List->count() -1; + if ( max == 0 ) { + this->ui->button_ConfApache_Warnlist_Up->setEnabled( false ); + this->ui->button_ConfApache_Warnlist_Down->setEnabled( false ); + } else { + for ( int i=0; i<=max; i++ ) { + if ( this->ui->list_ConfApache_Warnlist_List->item(i) == item ) { + if ( i == 0 ) { + this->ui->button_ConfApache_Warnlist_Up->setEnabled( false ); + } else if ( i == max ) { + this->ui->button_ConfApache_Warnlist_Down->setEnabled( false ); + } + } + } + } + } else { + this->ui->button_ConfApache_Warnlist_Remove->setEnabled( false ); + this->ui->button_ConfApache_Warnlist_Up->setEnabled( false ); + this->ui->button_ConfApache_Warnlist_Down->setEnabled( false ); + } +} +void MainWindow::on_button_ConfApache_Warnlist_Remove_clicked() +{ + const auto& item = this->ui->list_ConfApache_Warnlist_List->selectedItems().at(0); + this->craplog.warnlistRemove( + this->APACHE_ID, + this->crapview.getLogFieldID( this->ui->box_ConfApache_Warnlist_Field->currentText() ), + item->text().toStdString() ); + // refresh the list + this->on_box_ConfApache_Warnlist_Field_currentTextChanged( this->ui->box_ConfApache_Warnlist_Field->currentText() ); +} +void MainWindow::on_button_ConfApache_Warnlist_Up_clicked() +{ + const auto& item = this->ui->list_ConfApache_Warnlist_List->selectedItems().at(0); + const int i = this->craplog.warnlistMoveUp( + this->APACHE_ID, + this->crapview.getLogFieldID( this->ui->box_ConfApache_Warnlist_Field->currentText() ), + item->text().toStdString() ); + // refresh the list + this->on_box_ConfApache_Warnlist_Field_currentTextChanged( this->ui->box_ConfApache_Warnlist_Field->currentText() ); + // re-select the item + this->ui->list_ConfApache_Warnlist_List->item( i )->setSelected( true ); + this->ui->list_ConfApache_Warnlist_List->setFocus(); +} +void MainWindow::on_button_ConfApache_Warnlist_Down_clicked() +{ + const auto& item = this->ui->list_ConfApache_Warnlist_List->selectedItems().at(0); + const int i = this->craplog.warnlistMoveDown( + this->APACHE_ID, + this->crapview.getLogFieldID( this->ui->box_ConfApache_Warnlist_Field->currentText() ), + item->text().toStdString() ); + // refresh the list + this->on_box_ConfApache_Warnlist_Field_currentTextChanged( this->ui->box_ConfApache_Warnlist_Field->currentText() ); + // re-select the item + this->ui->list_ConfApache_Warnlist_List->item( i )->setSelected( true ); + this->ui->list_ConfApache_Warnlist_List->setFocus(); +} + + +// blacklist +void MainWindow::on_box_ConfApache_Blacklist_Field_currentTextChanged(const QString &arg1) +{ + if ( arg1.size() > 0 ) { + this->ui->inLine_ConfApache_Blacklist_String->clear(); + this->ui->list_ConfApache_Blacklist_List->clear(); + // update the list + const std::vector& list = this->craplog.getBlacklist( + this->APACHE_ID, this->crapview.getLogFieldID( arg1 ) ); + for ( const std::string& item : list ) { + this->ui->list_ConfApache_Blacklist_List->addItem( QString::fromStdString( item ) ); + } + // check/uncheck the usage option + bool used = this->craplog.isBlacklistUsed( + this->APACHE_ID, + this->crapview.getLogFieldID( this->ui->box_ConfApache_Blacklist_Field->currentText() ) ); + this->ui->checkBox_ConfApache_Blacklist_Used->setChecked( used ); + this->on_checkBox_ConfApache_Blacklist_Used_clicked( used ); + } +} +void MainWindow::on_checkBox_ConfApache_Blacklist_Used_clicked(bool checked) +{ + this->craplog.setBlacklistUsed( + this->APACHE_ID, + this->crapview.getLogFieldID( this->ui->box_ConfApache_Blacklist_Field->currentText() ), + checked ); + if ( checked ) { + this->ui->inLine_ConfApache_Blacklist_String->setEnabled( true ); + this->ui->list_ConfApache_Blacklist_List->setEnabled( true ); + } else { + this->ui->inLine_ConfApache_Blacklist_String->clear(); + this->ui->inLine_ConfApache_Blacklist_String->setEnabled( false ); + this->ui->list_ConfApache_Blacklist_List->clearSelection(); + this->ui->list_ConfApache_Blacklist_List->setEnabled( false ); + } +} + +void MainWindow::on_inLine_ConfApache_Blacklist_String_cursorPositionChanged(int arg1, int arg2) +{ + if ( arg2 > 0 ) { + this->ui->button_ConfApache_Blacklist_Add->setEnabled( true ); + } else { + this->ui->button_ConfApache_Blacklist_Add->setEnabled( false ); + } +} +void MainWindow::on_inLine_ConfApache_Blacklist_String_returnPressed() +{ + this->on_button_ConfApache_Blacklist_Add_clicked(); +} +void MainWindow::on_button_ConfApache_Blacklist_Add_clicked() +{ + const QString& item = this->ui->inLine_ConfApache_Blacklist_String->text(); + if ( this->ui->list_ConfApache_Blacklist_List->findItems( item, Qt::MatchFlag::MatchCaseSensitive ).size() == 0 ) { + // not in the list yet, append + try { + this->craplog.blacklistAdd( + this->APACHE_ID, + this->crapview.getLogFieldID( this->ui->box_ConfApache_Blacklist_Field->currentText() ), + item.toStdString() ); + this->ui->list_ConfApache_Blacklist_List->addItem( item ); + } catch ( const BWlistException& ) { + DialogSec::warnInvalidItemBW(); + return; + } + } + // select the item in the list, in both cases it was already in or it has been just inserted + this->ui->list_ConfApache_Blacklist_List->clearSelection(); + this->ui->list_ConfApache_Blacklist_List->findItems( item, Qt::MatchFlag::MatchCaseSensitive ).at(0)->setSelected( true ); + this->ui->inLine_ConfApache_Blacklist_String->clear(); +} + +void MainWindow::on_list_ConfApache_Blacklist_List_itemSelectionChanged() +{ + if ( this->ui->list_ConfApache_Blacklist_List->selectedItems().size() == 1 ) { + this->ui->button_ConfApache_Blacklist_Remove->setEnabled( true ); + this->ui->button_ConfApache_Blacklist_Up->setEnabled( true ); + this->ui->button_ConfApache_Blacklist_Down->setEnabled( true ); + // polishing + const auto& item = this->ui->list_ConfApache_Blacklist_List->selectedItems().at(0); + const int max = this->ui->list_ConfApache_Blacklist_List->count() -1; + if ( max == 0 ) { + this->ui->button_ConfApache_Blacklist_Up->setEnabled( false ); + this->ui->button_ConfApache_Blacklist_Down->setEnabled( false ); + } else { + for ( int i=0; i<=max; i++ ) { + if ( this->ui->list_ConfApache_Blacklist_List->item(i) == item ) { + if ( i == 0 ) { + this->ui->button_ConfApache_Blacklist_Up->setEnabled( false ); + } else if ( i == max ) { + this->ui->button_ConfApache_Blacklist_Down->setEnabled( false ); + } + } + } + } + } else { + this->ui->button_ConfApache_Blacklist_Remove->setEnabled( false ); + this->ui->button_ConfApache_Blacklist_Up->setEnabled( false ); + this->ui->button_ConfApache_Blacklist_Down->setEnabled( false ); + } +} +void MainWindow::on_button_ConfApache_Blacklist_Remove_clicked() +{ + const auto& item = this->ui->list_ConfApache_Blacklist_List->selectedItems().at(0); + this->craplog.blacklistRemove( + this->APACHE_ID, + this->crapview.getLogFieldID( this->ui->box_ConfApache_Blacklist_Field->currentText() ), + item->text().toStdString() ); + // refresh the list + this->on_box_ConfApache_Blacklist_Field_currentTextChanged( this->ui->box_ConfApache_Blacklist_Field->currentText() ); +} +void MainWindow::on_button_ConfApache_Blacklist_Up_clicked() +{ + const auto& item = this->ui->list_ConfApache_Blacklist_List->selectedItems().at(0); + const int i = this->craplog.blacklistMoveUp( + this->APACHE_ID, + this->crapview.getLogFieldID( this->ui->box_ConfApache_Blacklist_Field->currentText() ), + item->text().toStdString() ); + // refresh the list + this->on_box_ConfApache_Blacklist_Field_currentTextChanged( this->ui->box_ConfApache_Blacklist_Field->currentText() ); + // re-select the item + this->ui->list_ConfApache_Blacklist_List->item( i )->setSelected( true ); + this->ui->list_ConfApache_Blacklist_List->setFocus(); +} +void MainWindow::on_button_ConfApache_Blacklist_Down_clicked() +{ + const auto& item = this->ui->list_ConfApache_Blacklist_List->selectedItems().at(0); + const int i = this->craplog.blacklistMoveDown( + this->APACHE_ID, + this->crapview.getLogFieldID( this->ui->box_ConfApache_Blacklist_Field->currentText() ), + item->text().toStdString() ); + // refresh the list + this->on_box_ConfApache_Blacklist_Field_currentTextChanged( this->ui->box_ConfApache_Blacklist_Field->currentText() ); + // re-select the item + this->ui->list_ConfApache_Blacklist_List->item( i )->setSelected( true ); + this->ui->list_ConfApache_Blacklist_List->setFocus(); +} + + +//////////////// +//// NGINX //// +// paths +void MainWindow::on_inLine_ConfNginx_Path_String_textChanged(const QString &arg1) +{ + if ( arg1.size() > 0 ) { + std::string path = this->resolvePath( arg1.toStdString() ); + if ( IOutils::checkDir( path ) ) { + this->ui->icon_ConfNginx_Path_Wrong->setVisible( false ); + this->ui->button_ConfNginx_Path_Save->setEnabled( true ); + } else { + this->ui->icon_ConfNginx_Path_Wrong->setVisible( true ); + this->ui->button_ConfNginx_Path_Save->setEnabled( false ); + } + } else { + this->ui->icon_ConfNginx_Path_Wrong->setVisible( true ); + this->ui->button_ConfNginx_Path_Save->setEnabled( false ); + } +} +void MainWindow::on_inLine_ConfNginx_Path_String_returnPressed() +{ + this->on_button_ConfNginx_Path_Save_clicked(); +} +void MainWindow::on_button_ConfNginx_Path_Save_clicked() +{ + if ( ! this->ui->icon_ConfNginx_Path_Wrong->isVisible() ) { + // set the paths + std::string path = this->resolvePath( this->ui->inLine_ConfNginx_Path_String->text().toStdString() ); + if ( StringOps::endsWith( path, "/" ) ) { + path = StringOps::rstrip( path, "/" ); + } + if ( ! IOutils::checkDir( path, true ) ) { + DialogSec::warnDirNotReadable( nullptr ); + } + this->craplog.setLogsPath( this->NGINX_ID, path ); + this->ui->inLine_ConfNginx_Path_String->setText( QString::fromStdString( path ) ); + } + this->ui->button_ConfNginx_Path_Save->setEnabled( false ); +} + +// formats +void MainWindow::on_inLine_ConfNginx_Format_String_cursorPositionChanged(int arg1, int arg2) +{ + if ( arg2 > 0 ) { + this->ui->button_ConfNginx_Format_Save->setEnabled( true ); + } else { + this->ui->button_ConfNginx_Format_Save->setEnabled( false ); + } +} +void MainWindow::on_inLine_ConfNginx_Format_String_returnPressed() +{ + if ( this->ui->button_ConfNginx_Format_Save->isEnabled() ) { + this->on_button_ConfNginx_Format_Save_clicked(); + } +} +void MainWindow::on_button_ConfNginx_Format_Save_clicked() +{ + const bool success = this->craplog.setNginxLogFormat( + this->ui->inLine_ConfNginx_Format_String->text().toStdString() ); + if ( success ) { + this->ui->button_ConfNginx_Format_Save->setEnabled( false ); + } +} +void MainWindow::on_button_ConfNginx_Format_Sample_clicked() +{ + this->ui->preview_ConfNginx_Format_Sample->setText( + this->craplog.getLogsFormatSample( this->NGINX_ID ) ); +} +void MainWindow::on_button_ConfNginx_Format_Help_clicked() +{ + this->showHelp( "nginx_format" ); +} + +// warnlists +void MainWindow::on_box_ConfNginx_Warnlist_Field_currentTextChanged(const QString &arg1) +{ + if ( arg1.size() > 0 ) { + this->ui->inLine_ConfNginx_Warnlist_String->clear(); + this->ui->list_ConfNginx_Warnlist_List->clear(); + // update the list + const std::vector& list = this->craplog.getWarnlist( + this->NGINX_ID, this->crapview.getLogFieldID( arg1 ) ); + for ( const std::string& item : list ) { + this->ui->list_ConfNginx_Warnlist_List->addItem( QString::fromStdString( item ) ); + } + // check/uncheck the usage option + const bool used = this->craplog.isWarnlistUsed( + this->NGINX_ID, + this->crapview.getLogFieldID( this->ui->box_ConfNginx_Warnlist_Field->currentText() ) ); + this->ui->checkBox_ConfNginx_Warnlist_Used->setChecked( used ); + this->on_checkBox_ConfNginx_Warnlist_Used_clicked( used ); + } +} +void MainWindow::on_checkBox_ConfNginx_Warnlist_Used_clicked(bool checked) +{ + this->craplog.setWarnlistUsed( + this->NGINX_ID, + this->crapview.getLogFieldID( this->ui->box_ConfNginx_Warnlist_Field->currentText() ), + checked ); + if ( checked ) { + this->ui->inLine_ConfNginx_Warnlist_String->setEnabled( true ); + this->ui->list_ConfNginx_Warnlist_List->setEnabled( true ); + } else { + this->ui->inLine_ConfNginx_Warnlist_String->clear(); + this->ui->inLine_ConfNginx_Warnlist_String->setEnabled( false ); + this->ui->list_ConfNginx_Warnlist_List->clearSelection(); + this->ui->list_ConfNginx_Warnlist_List->setEnabled( false ); + } +} + +void MainWindow::on_inLine_ConfNginx_Warnlist_String_cursorPositionChanged(int arg1, int arg2) +{ + if ( arg2 > 0 ) { + this->ui->button_ConfNginx_Warnlist_Add->setEnabled( true ); + } else { + this->ui->button_ConfNginx_Warnlist_Add->setEnabled( false ); + } +} +void MainWindow::on_inLine_ConfNginx_Warnlist_String_returnPressed() +{ + this->on_button_ConfNginx_Warnlist_Add_clicked(); +} +void MainWindow::on_button_ConfNginx_Warnlist_Add_clicked() +{ + const QString& item = this->ui->inLine_ConfNginx_Warnlist_String->text(); + if ( this->ui->list_ConfNginx_Warnlist_List->findItems( item, Qt::MatchFlag::MatchCaseSensitive ).size() == 0 ) { + // not in the list yet, append + try { + this->craplog.warnlistAdd( + this->NGINX_ID, + this->crapview.getLogFieldID( this->ui->box_ConfNginx_Warnlist_Field->currentText() ), + item.toStdString() ); + this->ui->list_ConfNginx_Warnlist_List->addItem( item ); + } catch ( const BWlistException& ) { + DialogSec::warnInvalidItemBW(); + return; + } + } + // select the item in the list, in both cases it was already in or it has been just inserted + this->ui->list_ConfNginx_Warnlist_List->clearSelection(); + this->ui->list_ConfNginx_Warnlist_List->findItems( item, Qt::MatchFlag::MatchCaseSensitive ).at(0)->setSelected( true ); + this->ui->inLine_ConfNginx_Warnlist_String->clear(); +} + +void MainWindow::on_list_ConfNginx_Warnlist_List_itemSelectionChanged() +{ + if ( this->ui->list_ConfNginx_Warnlist_List->selectedItems().size() == 1 ) { + this->ui->button_ConfNginx_Warnlist_Remove->setEnabled( true ); + this->ui->button_ConfNginx_Warnlist_Up->setEnabled( true ); + this->ui->button_ConfNginx_Warnlist_Down->setEnabled( true ); + // polishing + const auto& item = this->ui->list_ConfNginx_Warnlist_List->selectedItems().at(0); + const int max = this->ui->list_ConfNginx_Warnlist_List->count() -1; + if ( max == 0 ) { + this->ui->button_ConfNginx_Warnlist_Up->setEnabled( false ); + this->ui->button_ConfNginx_Warnlist_Down->setEnabled( false ); + } else { + for ( int i=0; i<=max; i++ ) { + if ( this->ui->list_ConfNginx_Warnlist_List->item(i) == item ) { + if ( i == 0 ) { + this->ui->button_ConfNginx_Warnlist_Up->setEnabled( false ); + } else if ( i == max ) { + this->ui->button_ConfNginx_Warnlist_Down->setEnabled( false ); + } + } + } + } + } else { + this->ui->button_ConfNginx_Warnlist_Remove->setEnabled( false ); + this->ui->button_ConfNginx_Warnlist_Up->setEnabled( false ); + this->ui->button_ConfNginx_Warnlist_Down->setEnabled( false ); + } +} +void MainWindow::on_button_ConfNginx_Warnlist_Remove_clicked() +{ + const auto& item = this->ui->list_ConfNginx_Warnlist_List->selectedItems().at(0); + this->craplog.warnlistRemove( + this->NGINX_ID, + this->crapview.getLogFieldID( this->ui->box_ConfNginx_Warnlist_Field->currentText() ), + item->text().toStdString() ); + // refresh the list + this->on_box_ConfNginx_Warnlist_Field_currentTextChanged( this->ui->box_ConfNginx_Warnlist_Field->currentText() ); +} +void MainWindow::on_button_ConfNginx_Warnlist_Up_clicked() +{ + const auto& item = this->ui->list_ConfNginx_Warnlist_List->selectedItems().at(0); + const int i = this->craplog.warnlistMoveUp( + this->NGINX_ID, + this->crapview.getLogFieldID( this->ui->box_ConfNginx_Warnlist_Field->currentText() ), + item->text().toStdString() ); + // refresh the list + this->on_box_ConfNginx_Warnlist_Field_currentTextChanged( this->ui->box_ConfNginx_Warnlist_Field->currentText() ); + // re-select the item + this->ui->list_ConfNginx_Warnlist_List->item( i )->setSelected( true ); + this->ui->list_ConfNginx_Warnlist_List->setFocus(); +} +void MainWindow::on_button_ConfNginx_Warnlist_Down_clicked() +{ + const auto& item = this->ui->list_ConfNginx_Warnlist_List->selectedItems().at(0); + const int i = this->craplog.warnlistMoveDown( + this->NGINX_ID, + this->crapview.getLogFieldID( this->ui->box_ConfNginx_Warnlist_Field->currentText() ), + item->text().toStdString() ); + // refresh the list + this->on_box_ConfNginx_Warnlist_Field_currentTextChanged( this->ui->box_ConfNginx_Warnlist_Field->currentText() ); + // re-select the item + this->ui->list_ConfNginx_Warnlist_List->item( i )->setSelected( true ); + this->ui->list_ConfNginx_Warnlist_List->setFocus(); +} + + +// blacklist +void MainWindow::on_box_ConfNginx_Blacklist_Field_currentTextChanged(const QString &arg1) +{ + if ( arg1.size() > 0 ) { + this->ui->inLine_ConfNginx_Blacklist_String->clear(); + this->ui->list_ConfNginx_Blacklist_List->clear(); + // update the list + const std::vector& list = this->craplog.getBlacklist( + this->NGINX_ID, this->crapview.getLogFieldID( arg1 ) ); + for ( const std::string& item : list ) { + this->ui->list_ConfNginx_Blacklist_List->addItem( QString::fromStdString( item ) ); + } + // check/uncheck the usage option + bool used = this->craplog.isBlacklistUsed( + this->NGINX_ID, + this->crapview.getLogFieldID( this->ui->box_ConfNginx_Blacklist_Field->currentText() ) ); + this->ui->checkBox_ConfNginx_Blacklist_Used->setChecked( used ); + this->on_checkBox_ConfNginx_Blacklist_Used_clicked( used ); + } +} +void MainWindow::on_checkBox_ConfNginx_Blacklist_Used_clicked(bool checked) +{ + this->craplog.setBlacklistUsed( + this->NGINX_ID, + this->crapview.getLogFieldID( this->ui->box_ConfNginx_Blacklist_Field->currentText() ), + checked ); + if ( checked ) { + this->ui->inLine_ConfNginx_Blacklist_String->setEnabled( true ); + this->ui->list_ConfNginx_Blacklist_List->setEnabled( true ); + } else { + this->ui->inLine_ConfNginx_Blacklist_String->clear(); + this->ui->inLine_ConfNginx_Blacklist_String->setEnabled( false ); + this->ui->list_ConfNginx_Blacklist_List->clearSelection(); + this->ui->list_ConfNginx_Blacklist_List->setEnabled( false ); + } +} + +void MainWindow::on_inLine_ConfNginx_Blacklist_String_cursorPositionChanged(int arg1, int arg2) +{ + if ( arg2 > 0 ) { + this->ui->button_ConfNginx_Blacklist_Add->setEnabled( true ); + } else { + this->ui->button_ConfNginx_Blacklist_Add->setEnabled( false ); + } +} +void MainWindow::on_inLine_ConfNginx_Blacklist_String_returnPressed() +{ + this->on_button_ConfNginx_Blacklist_Add_clicked(); +} +void MainWindow::on_button_ConfNginx_Blacklist_Add_clicked() +{ + const QString& item = this->ui->inLine_ConfNginx_Blacklist_String->text(); + if ( this->ui->list_ConfNginx_Blacklist_List->findItems( item, Qt::MatchFlag::MatchCaseSensitive ).size() == 0 ) { + // not in the list yet, append + try { + this->craplog.blacklistAdd( + this->NGINX_ID, + this->crapview.getLogFieldID( this->ui->box_ConfNginx_Blacklist_Field->currentText() ), + item.toStdString() ); + this->ui->list_ConfNginx_Blacklist_List->addItem( item ); + } catch ( const BWlistException& ) { + DialogSec::warnInvalidItemBW(); + return; + } + } + // select the item in the list, in both cases it was already in or it has been just inserted + this->ui->list_ConfNginx_Blacklist_List->clearSelection(); + this->ui->list_ConfNginx_Blacklist_List->findItems( item, Qt::MatchFlag::MatchCaseSensitive ).at(0)->setSelected( true ); + this->ui->inLine_ConfNginx_Blacklist_String->clear(); +} + +void MainWindow::on_list_ConfNginx_Blacklist_List_itemSelectionChanged() +{ + if ( this->ui->list_ConfNginx_Blacklist_List->selectedItems().size() == 1 ) { + this->ui->button_ConfNginx_Blacklist_Remove->setEnabled( true ); + this->ui->button_ConfNginx_Blacklist_Up->setEnabled( true ); + this->ui->button_ConfNginx_Blacklist_Down->setEnabled( true ); + // polishing + const auto& item = this->ui->list_ConfNginx_Blacklist_List->selectedItems().at(0); + const int max = this->ui->list_ConfNginx_Blacklist_List->count() -1; + if ( max == 0 ) { + this->ui->button_ConfNginx_Blacklist_Up->setEnabled( false ); + this->ui->button_ConfNginx_Blacklist_Down->setEnabled( false ); + } else { + for ( int i=0; i<=max; i++ ) { + if ( this->ui->list_ConfNginx_Blacklist_List->item(i) == item ) { + if ( i == 0 ) { + this->ui->button_ConfNginx_Blacklist_Up->setEnabled( false ); + } else if ( i == max ) { + this->ui->button_ConfNginx_Blacklist_Down->setEnabled( false ); + } + } + } + } + } else { + this->ui->button_ConfNginx_Blacklist_Remove->setEnabled( false ); + this->ui->button_ConfNginx_Blacklist_Up->setEnabled( false ); + this->ui->button_ConfNginx_Blacklist_Down->setEnabled( false ); + } +} +void MainWindow::on_button_ConfNginx_Blacklist_Remove_clicked() +{ + const auto& item = this->ui->list_ConfNginx_Blacklist_List->selectedItems().at(0); + this->craplog.blacklistRemove( + this->NGINX_ID, + this->crapview.getLogFieldID( this->ui->box_ConfNginx_Blacklist_Field->currentText() ), + item->text().toStdString() ); + // refresh the list + this->on_box_ConfNginx_Blacklist_Field_currentTextChanged( this->ui->box_ConfNginx_Blacklist_Field->currentText() ); +} +void MainWindow::on_button_ConfNginx_Blacklist_Up_clicked() +{ + const auto& item = this->ui->list_ConfNginx_Blacklist_List->selectedItems().at(0); + const int i = this->craplog.blacklistMoveUp( + this->NGINX_ID, + this->crapview.getLogFieldID( this->ui->box_ConfNginx_Blacklist_Field->currentText() ), + item->text().toStdString() ); + // refresh the list + this->on_box_ConfNginx_Blacklist_Field_currentTextChanged( this->ui->box_ConfNginx_Blacklist_Field->currentText() ); + // re-select the item + this->ui->list_ConfNginx_Blacklist_List->item( i )->setSelected( true ); + this->ui->list_ConfNginx_Blacklist_List->setFocus(); +} +void MainWindow::on_button_ConfNginx_Blacklist_Down_clicked() +{ + const auto& item = this->ui->list_ConfNginx_Blacklist_List->selectedItems().at(0); + const int i = this->craplog.blacklistMoveDown( + this->NGINX_ID, + this->crapview.getLogFieldID( this->ui->box_ConfNginx_Blacklist_Field->currentText() ), + item->text().toStdString() ); + // refresh the list + this->on_box_ConfNginx_Blacklist_Field_currentTextChanged( this->ui->box_ConfNginx_Blacklist_Field->currentText() ); + // re-select the item + this->ui->list_ConfNginx_Blacklist_List->item( i )->setSelected( true ); + this->ui->list_ConfNginx_Blacklist_List->setFocus(); +} + + +//////////////// +//// IIS //// +// paths +void MainWindow::on_inLine_ConfIis_Path_String_textChanged(const QString &arg1) +{ + if ( arg1.size() > 0 ) { + std::string path = this->resolvePath( arg1.toStdString() ); + if ( IOutils::checkDir( path ) ) { + this->ui->icon_ConfIis_Path_Wrong->setVisible( false ); + this->ui->button_ConfIis_Path_Save->setEnabled( true ); + } else { + this->ui->icon_ConfIis_Path_Wrong->setVisible( true ); + this->ui->button_ConfIis_Path_Save->setEnabled( false ); + } + } else { + this->ui->icon_ConfIis_Path_Wrong->setVisible( true ); + this->ui->button_ConfIis_Path_Save->setEnabled( false ); + } +} +void MainWindow::on_inLine_ConfIis_Path_String_returnPressed() +{ + this->on_button_ConfIis_Path_Save_clicked(); +} +void MainWindow::on_button_ConfIis_Path_Save_clicked() +{ + if ( ! this->ui->icon_ConfIis_Path_Wrong->isVisible() ) { + // set the paths + std::string path = this->resolvePath( this->ui->inLine_ConfIis_Path_String->text().toStdString() ); + if ( StringOps::endsWith( path, "/" ) ) { + path = StringOps::rstrip( path, "/" ); + } + if ( ! IOutils::checkDir( path, true ) ) { + DialogSec::warnDirNotReadable( nullptr ); + } + this->craplog.setLogsPath( this->IIS_ID, path ); + this->ui->inLine_ConfIis_Path_String->setText( QString::fromStdString( path ) ); + } + this->ui->button_ConfIis_Path_Save->setEnabled( false ); +} + +// formats +const int MainWindow::getIisLogsModule() +{ + int module = 0; + if ( this->ui->radio_ConfIis_Format_NCSA->isChecked() ) { + module = 1; + } else if ( this->ui->radio_ConfIis_Format_IIS->isChecked() ) { + module = 2; + } + return module; +} + +void MainWindow::on_radio_ConfIis_Format_W3C_toggled(bool checked) +{ + if ( checked ) { + const bool success = this->craplog.setIisLogFormat( "", 0 ); + if ( success ) { + this->ui->inLine_ConfIis_Format_String->clear(); + this->ui->inLine_ConfIis_Format_String->setEnabled( true ); + this->ui->inLine_ConfIis_Format_String->setFocus(); + } + } +} +void MainWindow::on_radio_ConfIis_Format_NCSA_toggled(bool checked) +{ + if ( checked ) { + const bool success = this->craplog.setIisLogFormat( + "c-ip s-sitename s-computername [date:time] sc-status sc-bytes", + 1 ); + if ( success ) { + this->ui->inLine_ConfIis_Format_String->clear(); + this->ui->inLine_ConfIis_Format_String->setText( QString::fromStdString( this->craplog.getLogsFormatString( this->IIS_ID ) ) ); + this->ui->inLine_ConfIis_Format_String->setEnabled( false ); + this->ui->button_ConfIis_Format_Save->setEnabled( false ); + } + } +} +void MainWindow::on_radio_ConfIis_Format_IIS_toggled(bool checked) +{ + if ( checked ) { + const bool success = this->craplog.setIisLogFormat( + "c-ip, cs-username, date, time, s-sitename, s-computername, s-ip, time-taken, cs-bytes, sc-bytes, sc-status, sc-win32-status, cs-method, cs-uri-stem, cs-uri-query,", + 2 ); + if ( success ) { + this->ui->inLine_ConfIis_Format_String->clear(); + this->ui->inLine_ConfIis_Format_String->setText( QString::fromStdString( this->craplog.getLogsFormatString( this->IIS_ID ) ) ); + this->ui->inLine_ConfIis_Format_String->setEnabled( false ); + this->ui->button_ConfIis_Format_Save->setEnabled( false ); + } + } +} + +void MainWindow::on_inLine_ConfIis_Format_String_cursorPositionChanged(int arg1, int arg2) +{ + if ( arg2 > 0 ) { + this->ui->button_ConfIis_Format_Save->setEnabled( true ); + } else { + this->ui->button_ConfIis_Format_Save->setEnabled( false ); + } +} +void MainWindow::on_inLine_ConfIis_Format_String_returnPressed() +{ + if ( this->ui->button_ConfIis_Format_Save->isEnabled() ) { + this->on_button_ConfIis_Format_Save_clicked(); + } +} +void MainWindow::on_button_ConfIis_Format_Save_clicked() +{ + const bool success = this->craplog.setIisLogFormat( + StringOps::strip( this->ui->inLine_ConfIis_Format_String->text().toStdString() ), + this->getIisLogsModule() ); + if ( success ) { + this->ui->button_ConfIis_Format_Save->setEnabled( false ); + } +} +void MainWindow::on_button_ConfIis_Format_Sample_clicked() +{ + this->ui->preview_ConfIis_Format_Sample->setText( + this->craplog.getLogsFormatSample( this->IIS_ID ) ); +} +void MainWindow::on_button_ConfIis_Format_Help_clicked() +{ + this->showHelp( "iis_format" ); +} + +// warnlists +void MainWindow::on_box_ConfIis_Warnlist_Field_currentTextChanged(const QString &arg1) +{ + if ( arg1.size() > 0 ) { + this->ui->inLine_ConfIis_Warnlist_String->clear(); + this->ui->list_ConfIis_Warnlist_List->clear(); + // update the list + const std::vector& list = this->craplog.getWarnlist( + this->IIS_ID, this->crapview.getLogFieldID( arg1 ) ); + for ( const std::string& item : list ) { + this->ui->list_ConfIis_Warnlist_List->addItem( QString::fromStdString( item ) ); + } + // check/uncheck the usage option + const bool used = this->craplog.isWarnlistUsed( + this->IIS_ID, + this->crapview.getLogFieldID( this->ui->box_ConfIis_Warnlist_Field->currentText() ) ); + this->ui->checkBox_ConfIis_Warnlist_Used->setChecked( used ); + this->on_checkBox_ConfIis_Warnlist_Used_clicked( used ); + } +} +void MainWindow::on_checkBox_ConfIis_Warnlist_Used_clicked(bool checked) +{ + this->craplog.setWarnlistUsed( + this->IIS_ID, + this->crapview.getLogFieldID( this->ui->box_ConfIis_Warnlist_Field->currentText() ), + checked ); + if ( checked ) { + this->ui->inLine_ConfIis_Warnlist_String->setEnabled( true ); + this->ui->list_ConfIis_Warnlist_List->setEnabled( true ); + } else { + this->ui->inLine_ConfIis_Warnlist_String->clear(); + this->ui->inLine_ConfIis_Warnlist_String->setEnabled( false ); + this->ui->list_ConfIis_Warnlist_List->clearSelection(); + this->ui->list_ConfIis_Warnlist_List->setEnabled( false ); + } +} + +void MainWindow::on_inLine_ConfIis_Warnlist_String_cursorPositionChanged(int arg1, int arg2) +{ + if ( arg2 > 0 ) { + this->ui->button_ConfIis_Warnlist_Add->setEnabled( true ); + } else { + this->ui->button_ConfIis_Warnlist_Add->setEnabled( false ); + } +} +void MainWindow::on_inLine_ConfIis_Warnlist_String_returnPressed() +{ + this->on_button_ConfIis_Warnlist_Add_clicked(); +} +void MainWindow::on_button_ConfIis_Warnlist_Add_clicked() +{ + const QString& item = this->ui->inLine_ConfIis_Warnlist_String->text(); + if ( this->ui->list_ConfIis_Warnlist_List->findItems( item, Qt::MatchFlag::MatchCaseSensitive ).size() == 0 ) { + // not in the list yet, append + try { + this->craplog.warnlistAdd( + this->IIS_ID, + this->crapview.getLogFieldID( this->ui->box_ConfIis_Warnlist_Field->currentText() ), + item.toStdString() ); + this->ui->list_ConfIis_Warnlist_List->addItem( item ); + } catch ( const BWlistException& ) { + DialogSec::warnInvalidItemBW(); + return; + } + } + // select the item in the list, in both cases it was already in or it has been just inserted + this->ui->list_ConfIis_Warnlist_List->clearSelection(); + this->ui->list_ConfIis_Warnlist_List->findItems( item, Qt::MatchFlag::MatchCaseSensitive ).at(0)->setSelected( true ); + this->ui->inLine_ConfIis_Warnlist_String->clear(); +} + +void MainWindow::on_list_ConfIis_Warnlist_List_itemSelectionChanged() +{ + if ( this->ui->list_ConfIis_Warnlist_List->selectedItems().size() == 1 ) { + this->ui->button_ConfIis_Warnlist_Remove->setEnabled( true ); + this->ui->button_ConfIis_Warnlist_Up->setEnabled( true ); + this->ui->button_ConfIis_Warnlist_Down->setEnabled( true ); + // polishing + const auto& item = this->ui->list_ConfIis_Warnlist_List->selectedItems().at(0); + const int max = this->ui->list_ConfIis_Warnlist_List->count() -1; + if ( max == 0 ) { + this->ui->button_ConfIis_Warnlist_Up->setEnabled( false ); + this->ui->button_ConfIis_Warnlist_Down->setEnabled( false ); + } else { + for ( int i=0; i<=max; i++ ) { + if ( this->ui->list_ConfIis_Warnlist_List->item(i) == item ) { + if ( i == 0 ) { + this->ui->button_ConfIis_Warnlist_Up->setEnabled( false ); + } else if ( i == max ) { + this->ui->button_ConfIis_Warnlist_Down->setEnabled( false ); + } + } + } + } + } else { + this->ui->button_ConfIis_Warnlist_Remove->setEnabled( false ); + this->ui->button_ConfIis_Warnlist_Up->setEnabled( false ); + this->ui->button_ConfIis_Warnlist_Down->setEnabled( false ); + } +} +void MainWindow::on_button_ConfIis_Warnlist_Remove_clicked() +{ + const auto& item = this->ui->list_ConfIis_Warnlist_List->selectedItems().at(0); + this->craplog.warnlistRemove( + this->IIS_ID, + this->crapview.getLogFieldID( this->ui->box_ConfIis_Warnlist_Field->currentText() ), + item->text().toStdString() ); + // refresh the list + this->on_box_ConfIis_Warnlist_Field_currentTextChanged( this->ui->box_ConfIis_Warnlist_Field->currentText() ); +} +void MainWindow::on_button_ConfIis_Warnlist_Up_clicked() +{ + const auto& item = this->ui->list_ConfIis_Warnlist_List->selectedItems().at(0); + const int i = this->craplog.warnlistMoveUp( + this->IIS_ID, + this->crapview.getLogFieldID( this->ui->box_ConfIis_Warnlist_Field->currentText() ), + item->text().toStdString() ); + // refresh the list + this->on_box_ConfIis_Warnlist_Field_currentTextChanged( this->ui->box_ConfIis_Warnlist_Field->currentText() ); + // re-select the item + this->ui->list_ConfIis_Warnlist_List->item( i )->setSelected( true ); + this->ui->list_ConfIis_Warnlist_List->setFocus(); +} +void MainWindow::on_button_ConfIis_Warnlist_Down_clicked() +{ + const auto& item = this->ui->list_ConfIis_Warnlist_List->selectedItems().at(0); + const int i = this->craplog.warnlistMoveDown( + this->IIS_ID, + this->crapview.getLogFieldID( this->ui->box_ConfIis_Warnlist_Field->currentText() ), + item->text().toStdString() ); + // refresh the list + this->on_box_ConfIis_Warnlist_Field_currentTextChanged( this->ui->box_ConfIis_Warnlist_Field->currentText() ); + // re-select the item + this->ui->list_ConfIis_Warnlist_List->item( i )->setSelected( true ); + this->ui->list_ConfIis_Warnlist_List->setFocus(); +} + + +// blacklist +void MainWindow::on_box_ConfIis_Blacklist_Field_currentTextChanged(const QString &arg1) +{ + if ( arg1.size() > 0 ) { + this->ui->inLine_ConfIis_Blacklist_String->clear(); + this->ui->list_ConfIis_Blacklist_List->clear(); + // update the list + const std::vector& list = this->craplog.getBlacklist( + this->IIS_ID, this->crapview.getLogFieldID( arg1 ) ); + for ( const std::string& item : list ) { + this->ui->list_ConfIis_Blacklist_List->addItem( QString::fromStdString( item ) ); + } + // check/uncheck the usage option + bool used = this->craplog.isBlacklistUsed( + this->IIS_ID, + this->crapview.getLogFieldID( this->ui->box_ConfIis_Blacklist_Field->currentText() ) ); + this->ui->checkBox_ConfIis_Blacklist_Used->setChecked( used ); + this->on_checkBox_ConfIis_Blacklist_Used_clicked( used ); + } +} +void MainWindow::on_checkBox_ConfIis_Blacklist_Used_clicked(bool checked) +{ + this->craplog.setBlacklistUsed( + this->IIS_ID, + this->crapview.getLogFieldID( this->ui->box_ConfIis_Blacklist_Field->currentText() ), + checked ); + if ( checked ) { + this->ui->inLine_ConfIis_Blacklist_String->setEnabled( true ); + this->ui->list_ConfIis_Blacklist_List->setEnabled( true ); + } else { + this->ui->inLine_ConfIis_Blacklist_String->clear(); + this->ui->inLine_ConfIis_Blacklist_String->setEnabled( false ); + this->ui->list_ConfIis_Blacklist_List->clearSelection(); + this->ui->list_ConfIis_Blacklist_List->setEnabled( false ); + } +} + +void MainWindow::on_inLine_ConfIis_Blacklist_String_cursorPositionChanged(int arg1, int arg2) +{ + if ( arg2 > 0 ) { + this->ui->button_ConfIis_Blacklist_Add->setEnabled( true ); + } else { + this->ui->button_ConfIis_Blacklist_Add->setEnabled( false ); + } +} +void MainWindow::on_inLine_ConfIis_Blacklist_String_returnPressed() +{ + this->on_button_ConfIis_Blacklist_Add_clicked(); +} +void MainWindow::on_button_ConfIis_Blacklist_Add_clicked() +{ + const QString& item = this->ui->inLine_ConfIis_Blacklist_String->text(); + if ( this->ui->list_ConfIis_Blacklist_List->findItems( item, Qt::MatchFlag::MatchCaseSensitive ).size() == 0 ) { + // not in the list yet, append + try { + this->craplog.blacklistAdd( + this->IIS_ID, + this->crapview.getLogFieldID( this->ui->box_ConfIis_Blacklist_Field->currentText() ), + item.toStdString() ); + this->ui->list_ConfIis_Blacklist_List->addItem( item ); + } catch ( const BWlistException& ) { + DialogSec::warnInvalidItemBW(); + return; + } + } + // select the item in the list, in both cases it was already in or it has been just inserted + this->ui->list_ConfIis_Blacklist_List->clearSelection(); + this->ui->list_ConfIis_Blacklist_List->findItems( item, Qt::MatchFlag::MatchCaseSensitive ).at(0)->setSelected( true ); + this->ui->inLine_ConfIis_Blacklist_String->clear(); +} + +void MainWindow::on_list_ConfIis_Blacklist_List_itemSelectionChanged() +{ + if ( this->ui->list_ConfIis_Blacklist_List->selectedItems().size() == 1 ) { + this->ui->button_ConfIis_Blacklist_Remove->setEnabled( true ); + this->ui->button_ConfIis_Blacklist_Up->setEnabled( true ); + this->ui->button_ConfIis_Blacklist_Down->setEnabled( true ); + // polishing + const auto& item = this->ui->list_ConfIis_Blacklist_List->selectedItems().at(0); + const int max = this->ui->list_ConfIis_Blacklist_List->count() -1; + if ( max == 0 ) { + this->ui->button_ConfIis_Blacklist_Up->setEnabled( false ); + this->ui->button_ConfIis_Blacklist_Down->setEnabled( false ); + } else { + for ( int i=0; i<=max; i++ ) { + if ( this->ui->list_ConfIis_Blacklist_List->item(i) == item ) { + if ( i == 0 ) { + this->ui->button_ConfIis_Blacklist_Up->setEnabled( false ); + } else if ( i == max ) { + this->ui->button_ConfIis_Blacklist_Down->setEnabled( false ); + } + } + } + } + } else { + this->ui->button_ConfIis_Blacklist_Remove->setEnabled( false ); + this->ui->button_ConfIis_Blacklist_Up->setEnabled( false ); + this->ui->button_ConfIis_Blacklist_Down->setEnabled( false ); + } +} +void MainWindow::on_button_ConfIis_Blacklist_Remove_clicked() +{ + const auto& item = this->ui->list_ConfIis_Blacklist_List->selectedItems().at(0); + this->craplog.blacklistRemove( + this->IIS_ID, + this->crapview.getLogFieldID( this->ui->box_ConfIis_Blacklist_Field->currentText() ), + item->text().toStdString() ); + // refresh the list + this->on_box_ConfIis_Blacklist_Field_currentTextChanged( this->ui->box_ConfIis_Blacklist_Field->currentText() ); +} +void MainWindow::on_button_ConfIis_Blacklist_Up_clicked() +{ + const auto& item = this->ui->list_ConfIis_Blacklist_List->selectedItems().at(0); + const int i = this->craplog.blacklistMoveUp( + this->IIS_ID, + this->crapview.getLogFieldID( this->ui->box_ConfIis_Blacklist_Field->currentText() ), + item->text().toStdString() ); + // refresh the list + this->on_box_ConfIis_Blacklist_Field_currentTextChanged( this->ui->box_ConfIis_Blacklist_Field->currentText() ); + // re-select the item + this->ui->list_ConfIis_Blacklist_List->item( i )->setSelected( true ); + this->ui->list_ConfIis_Blacklist_List->setFocus(); +} +void MainWindow::on_button_ConfIis_Blacklist_Down_clicked() +{ + const auto& item = this->ui->list_ConfIis_Blacklist_List->selectedItems().at(0); + const int i = this->craplog.blacklistMoveDown( + this->IIS_ID, + this->crapview.getLogFieldID( this->ui->box_ConfIis_Blacklist_Field->currentText() ), + item->text().toStdString() ); + // refresh the list + this->on_box_ConfIis_Blacklist_Field_currentTextChanged( this->ui->box_ConfIis_Blacklist_Field->currentText() ); + // re-select the item + this->ui->list_ConfIis_Blacklist_List->item( i )->setSelected( true ); + this->ui->list_ConfIis_Blacklist_List->setFocus(); +} + diff --git a/logdoctor/mainwindow.h b/logdoctor/mainwindow.h new file mode 100644 index 00000000..50a06c96 --- /dev/null +++ b/logdoctor/mainwindow.h @@ -0,0 +1,870 @@ +#ifndef MAINWINDOW_H +#define MAINWINDOW_H + +#include "ui_mainwindow.h" + +#include +#include + +#include +#include +#include +#include +#include + +#include "utilities/strings.h" + +#include "modules/tb.h" + +#include "modules/craplog/craplog.h" +#include "modules/crapview/crapview.h" +#include "modules/craphelp/craphelp.h" +#include "modules/crapup/crapup.h" +#include "modules/crapinfo/crapinfo.h" + +#include "tools/crapnote/crapnote.h" + +#include "games/crisscross/game.h" +#include "games/snake/game.h" + + +QT_BEGIN_NAMESPACE +namespace Ui { class MainWindow; } +QT_END_NAMESPACE + + +//! MainWindow +/*! + The parent window +*/ +class MainWindow : public QMainWindow +{ + Q_OBJECT + +public: + + MainWindow( QWidget* parent=nullptr ); + ~MainWindow(); + + +private slots: + + void closeEvent( QCloseEvent *event ) override; + + + //////////////// + //// CUSTOM //// + + void wait_ActiveWindow(); + + void update_Craplog_PerfData(); + + void check_CraplogLLT_Finished(); + + + ////////////// + //// TABS //// + + void on_button_Tab_Log_clicked(); + + void on_button_Tab_View_clicked(); + + void on_button_Tab_Conf_clicked(); + + //// STATS //// + + void on_button_Tab_StatsWarn_clicked(); + + void on_button_Tab_StatsSpeed_clicked(); + + void on_button_Tab_StatsCount_clicked(); + + void on_button_Tab_StatsDay_clicked(); + + void on_button_Tab_StatsRelat_clicked(); + + void on_button_Tab_StatsGlob_clicked(); + + + ///////////////// + //// CRAPLOG //// + + void on_button_Logs_Down_clicked(); + + void on_button_Logs_Up_clicked(); + + void refreshLogsList(); + + void runCraplog(); + + void on_button_LogFiles_ViewFile_clicked(); + + void on_checkBox_LogFiles_CheckAll_stateChanged(int arg1); + + void on_button_LogFiles_RefreshList_clicked(); + + void on_listLogFiles_itemDoubleClicked(QTreeWidgetItem *item, int column); + + void on_listLogFiles_itemChanged(QTreeWidgetItem *item, int column); + + void on_button_LogFiles_Apache_clicked(); + + void on_button_LogFiles_Nginx_clicked(); + + void on_button_LogFiles_Iis_clicked(); + + void on_button_MakeStats_Start_clicked(); + + + ////////////////// + //// CRAPVIEW //// + + void drawStatsWarn(); + + void drawStatsSpeed(); + + void drawStatsCount(); + + void drawStatsDay(); + + void drawStatsRelat(); + + void makeStatsGlobals(); + + //// WARNINGS //// + + void on_box_StatsWarn_WebServer_currentIndexChanged(int index); + + void on_box_StatsWarn_Year_currentIndexChanged(int index); + + void on_box_StatsWarn_Month_currentIndexChanged(int index); + + void on_box_StatsWarn_Day_currentIndexChanged(int index); + + void on_checkBox_StatsWarn_Hour_stateChanged(int state); + + void on_box_StatsWarn_Hour_currentIndexChanged(int index); + + void on_button_StatsWarn_Draw_clicked(); + + void on_button_StatsWarn_Update_clicked(); + + //// SPEED //// + + void on_box_StatsSpeed_WebServer_currentIndexChanged(int index); + + void on_box_StatsSpeed_Year_currentIndexChanged(int index); + + void on_box_StatsSpeed_Month_currentIndexChanged(int index); + + void on_box_StatsSpeed_Day_currentIndexChanged(int index); + + void on_button_StatsSpeed_Draw_clicked(); + + //// COUNTS //// + + void on_box_StatsCount_WebServer_currentIndexChanged(int index); + + void on_box_StatsCount_Year_currentIndexChanged(int index); + + void on_box_StatsCount_Month_currentIndexChanged(int index); + + void on_box_StatsCount_Day_currentIndexChanged(int index); + + void on_button_StatsCount_Protocol_clicked(); + + void on_button_StatsCount_Method_clicked(); + + void on_button_StatsCount_Uri_clicked(); + + void on_button_StatsCount_Query_clicked(); + + void on_button_StatsCount_Response_clicked(); + + void on_button_StatsCount_Referrer_clicked(); + + void on_button_StatsCount_Cookie_clicked(); + + void on_button_StatsCount_UserAgent_clicked(); + + void on_button_StatsCount_Client_clicked(); + + //// DAY-TIME //// + + void on_box_StatsDay_WebServer_currentIndexChanged(int index); + + void on_box_StatsDay_LogsField_currentIndexChanged(int index); + + void on_box_StatsDay_FromYear_currentIndexChanged(int index); + + void on_box_StatsDay_FromMonth_currentIndexChanged(int index); + + void on_box_StatsDay_FromDay_currentIndexChanged(int index); + + void on_checkBox_StatsDay_Period_stateChanged(int state); + + void on_box_StatsDay_ToYear_currentIndexChanged(int index); + + void on_box_StatsDay_ToMonth_currentIndexChanged(int index); + + void on_box_StatsDay_ToDay_currentIndexChanged(int index); + + void on_button_StatsDay_Draw_clicked(); + + //// RELATIONAL //// + + void on_box_StatsRelat_WebServer_currentIndexChanged(int index); + + void on_box_StatsRelat_LogsField_1_currentIndexChanged(int index); + + void on_box_StatsRelat_LogsField_2_currentIndexChanged(int index); + + void on_box_StatsRelat_FromYear_currentIndexChanged(int index); + + void on_box_StatsRelat_FromMonth_currentIndexChanged(int index); + + void on_box_StatsRelat_FromDay_currentIndexChanged(int index); + + void on_box_StatsRelat_ToYear_currentIndexChanged(int index); + + void on_box_StatsRelat_ToMonth_currentIndexChanged(int index); + + void on_box_StatsRelat_ToDay_currentIndexChanged(int index); + + void on_button_StatsRelat_Draw_clicked(); + + void on_button_StatsGlob_Apache_clicked(); + + void on_button_StatsGlob_Nginx_clicked(); + + void on_button_StatsGlob_Iis_clicked(); + + + ///////////////// + //// CRAPSET //// + + //// WINDOW //// + + void on_checkBox_ConfWindow_Geometry_clicked(bool checked); + + void on_box_ConfWindow_Theme_currentIndexChanged(int index); + + void on_box_ConfWindow_Icons_currentIndexChanged(int index); + + //// DIALOGS //// + + void on_slider_ConfDialogs_General_sliderReleased(); + + void on_slider_ConfDialogs_Logs_sliderReleased(); + + void on_slider_ConfDialogs_Stats_sliderReleased(); + + //// TEXT BROWSER //// + + void on_box_ConfTextBrowser_Font_currentIndexChanged(int index); + + void on_checkBox_ConfTextBrowser_WideLines_clicked(bool checked); + + void on_box_ConfTextBrowser_ColorScheme_currentIndexChanged(int index); + + //// CHARTS //// + + void on_box_ConfCharts_Theme_currentIndexChanged(int index); + + //// DATABASES //// + + void on_inLine_ConfDatabases_Data_Path_textChanged(const QString &arg1); + + void on_inLine_ConfDatabases_Data_Path_returnPressed(); + + void on_button_ConfDatabases_Data_Save_clicked(); + + void on_inLine_ConfDatabases_Hashes_Path_textChanged(const QString &arg1); + + void on_inLine_ConfDatabases_Hashes_Path_returnPressed(); + + void on_button_ConfDatabases_Hashes_Save_clicked(); + + void on_checkBox_ConfDatabases_DoBackup_clicked(bool checked); + + void on_spinBox_ConfDatabases_NumBackups_valueChanged(int arg1); + + //// LOGS DEFAULTS //// + + void on_radio_ConfDefaults_Apache_toggled(bool checked); + + void on_radio_ConfDefaults_Nginx_toggled(bool checked); + + void on_radio_ConfDefaults_Iis_toggled(bool checked); + + //// LOGS CONTROL //// + + void on_checkBox_ConfControl_Usage_clicked(bool checked); + + void on_checkBox_ConfControl_Size_clicked(bool checked); + + void on_spinBox_ConfControl_Size_editingFinished(); + + //// APACHE //// + + void on_inLine_ConfApache_Path_String_textChanged(const QString &arg1); + + void on_inLine_ConfApache_Path_String_returnPressed(); + + void on_button_ConfApache_Path_Save_clicked(); + + void on_inLine_ConfApache_Format_String_cursorPositionChanged(int arg1, int arg2); + + void on_inLine_ConfApache_Format_String_returnPressed(); + + void on_button_ConfApache_Format_Save_clicked(); + + void on_button_ConfApache_Format_Sample_clicked(); + + void on_button_ConfApache_Format_Help_clicked(); + + void on_box_ConfApache_Warnlist_Field_currentTextChanged(const QString &arg1); + + void on_checkBox_ConfApache_Warnlist_Used_clicked(bool checked); + + void on_inLine_ConfApache_Warnlist_String_cursorPositionChanged(int arg1, int arg2); + + void on_inLine_ConfApache_Warnlist_String_returnPressed(); + + void on_button_ConfApache_Warnlist_Add_clicked(); + + void on_list_ConfApache_Warnlist_List_itemSelectionChanged(); + + void on_button_ConfApache_Warnlist_Remove_clicked(); + + void on_button_ConfApache_Warnlist_Up_clicked(); + + void on_button_ConfApache_Warnlist_Down_clicked(); + + void on_box_ConfApache_Blacklist_Field_currentTextChanged(const QString &arg1); + + void on_checkBox_ConfApache_Blacklist_Used_clicked(bool checked); + + void on_inLine_ConfApache_Blacklist_String_cursorPositionChanged(int arg1, int arg2); + + void on_inLine_ConfApache_Blacklist_String_returnPressed(); + + void on_button_ConfApache_Blacklist_Add_clicked(); + + void on_list_ConfApache_Blacklist_List_itemSelectionChanged(); + + void on_button_ConfApache_Blacklist_Remove_clicked(); + + void on_button_ConfApache_Blacklist_Up_clicked(); + + void on_button_ConfApache_Blacklist_Down_clicked(); + + //// NGINX //// + + void on_inLine_ConfNginx_Path_String_textChanged(const QString &arg1); + + void on_inLine_ConfNginx_Path_String_returnPressed(); + + void on_button_ConfNginx_Path_Save_clicked(); + + void on_inLine_ConfNginx_Format_String_cursorPositionChanged(int arg1, int arg2); + + void on_inLine_ConfNginx_Format_String_returnPressed(); + + void on_button_ConfNginx_Format_Save_clicked(); + + void on_button_ConfNginx_Format_Sample_clicked(); + + void on_button_ConfNginx_Format_Help_clicked(); + + void on_box_ConfNginx_Warnlist_Field_currentTextChanged(const QString &arg1); + + void on_checkBox_ConfNginx_Warnlist_Used_clicked(bool checked); + + void on_inLine_ConfNginx_Warnlist_String_cursorPositionChanged(int arg1, int arg2); + + void on_inLine_ConfNginx_Warnlist_String_returnPressed(); + + void on_button_ConfNginx_Warnlist_Add_clicked(); + + void on_list_ConfNginx_Warnlist_List_itemSelectionChanged(); + + void on_button_ConfNginx_Warnlist_Remove_clicked(); + + void on_button_ConfNginx_Warnlist_Up_clicked(); + + void on_button_ConfNginx_Warnlist_Down_clicked(); + + void on_box_ConfNginx_Blacklist_Field_currentTextChanged(const QString &arg1); + + void on_checkBox_ConfNginx_Blacklist_Used_clicked(bool checked); + + void on_inLine_ConfNginx_Blacklist_String_cursorPositionChanged(int arg1, int arg2); + + void on_inLine_ConfNginx_Blacklist_String_returnPressed(); + + void on_button_ConfNginx_Blacklist_Add_clicked(); + + void on_list_ConfNginx_Blacklist_List_itemSelectionChanged(); + + void on_button_ConfNginx_Blacklist_Remove_clicked(); + + void on_button_ConfNginx_Blacklist_Up_clicked(); + + void on_button_ConfNginx_Blacklist_Down_clicked(); + + //// IIS //// + + void on_inLine_ConfIis_Path_String_textChanged(const QString &arg1); + + void on_inLine_ConfIis_Path_String_returnPressed(); + + void on_button_ConfIis_Path_Save_clicked(); + + void on_radio_ConfIis_Format_W3C_toggled(bool checked); + + void on_radio_ConfIis_Format_NCSA_toggled(bool checked); + + void on_radio_ConfIis_Format_IIS_toggled(bool checked); + + void on_inLine_ConfIis_Format_String_cursorPositionChanged(int arg1, int arg2); + + void on_inLine_ConfIis_Format_String_returnPressed(); + + void on_button_ConfIis_Format_Save_clicked(); + + void on_button_ConfIis_Format_Sample_clicked(); + + void on_button_ConfIis_Format_Help_clicked(); + + void on_box_ConfIis_Warnlist_Field_currentTextChanged(const QString &arg1); + + void on_checkBox_ConfIis_Warnlist_Used_clicked(bool checked); + + void on_inLine_ConfIis_Warnlist_String_cursorPositionChanged(int arg1, int arg2); + + void on_inLine_ConfIis_Warnlist_String_returnPressed(); + + void on_button_ConfIis_Warnlist_Add_clicked(); + + void on_list_ConfIis_Warnlist_List_itemSelectionChanged(); + + void on_button_ConfIis_Warnlist_Remove_clicked(); + + void on_button_ConfIis_Warnlist_Up_clicked(); + + void on_button_ConfIis_Warnlist_Down_clicked(); + + void on_box_ConfIis_Blacklist_Field_currentTextChanged(const QString &arg1); + + void on_checkBox_ConfIis_Blacklist_Used_clicked(bool checked); + + void on_inLine_ConfIis_Blacklist_String_cursorPositionChanged(int arg1, int arg2); + + void on_inLine_ConfIis_Blacklist_String_returnPressed(); + + void on_button_ConfIis_Blacklist_Add_clicked(); + + void on_list_ConfIis_Blacklist_List_itemSelectionChanged(); + + void on_button_ConfIis_Blacklist_Remove_clicked(); + + void on_button_ConfIis_Blacklist_Up_clicked(); + + void on_button_ConfIis_Blacklist_Down_clicked(); + + + /////////////// + //// MENU //// + + //// LANGUAGE //// + + void menu_actionEnglish_triggered(); + + void menu_actionEspanol_triggered(); + + void menu_actionFrancais_triggered(); + + void menu_actionItaliano_triggered(); + + //// TOOLS //// + + void menu_actionBlockNote_triggered(); + + //// UTILITIES //// + + void menu_actionInfos_triggered(); + + void menu_actionCheckUpdates_triggered(); + + //// GAMES //// + + void menu_actionCrissCross_triggered(); + + void menu_actionSnake_triggered(); + + +private: + Ui::MainWindow *ui; + + // current version of LogDoctor + const float version = 2.01; + + // web servers ID constants + const unsigned int APACHE_ID=11, NGINX_ID=12, IIS_ID=13; + const QString wsFromIndex( const int& index ); + + + ////////////////////////// + //// OPERATING SYSTEM //// + + const std::string home_path = StringOps::rstrip( QStandardPaths::locate( QStandardPaths::HomeLocation, "", QStandardPaths::LocateDirectory ).toStdString(), "/" ); + + // 1: linux, 2:windows, 3:mac + #if defined( Q_OS_DARWIN ) + // Darwin-based systems: macOS, iOS, watchOS and tvOS. + const unsigned int OS = 3; + const std::string configs_path = this->home_path + "/Lybrary/Preferences/LogDoctor/logdoctor.conf"; + const std::string logdoc_path = this->home_path + "/Lybrary/Application Support/LogDoctor"; + #elif defined( Q_OS_WIN ) + // Microsoft Windows systems + const unsigned int OS = 2; + const std::string configs_path = this->home_path + "/AppData/Local/LogDoctor/logdoctor.conf"; + const std::string logdoc_path = this->home_path + "/AppData/Local/LogDoctor"; + #elif defined( Q_OS_UNIX ) + // Unix-like systems: Linux, BSD and SysV + const unsigned int OS = 1; + const std::string configs_path = this->home_path + "/.config/LogDoctor/logdoctor.conf"; + const std::string logdoc_path = "/usr/share/LogDoctor"; + #else + #error "System not supported" + #endif + + + //! Defines OS specific stuff + void defineOSspec(); + + + //////////////////////// + //// CONFIGURATIONS //// + //////////////////////// + + //! Reads the configurations file and apply the resulting configuration + void readConfigs(); + + //! Writes the current configuration on file + void writeConfigs(); + + //! Converts a list of items to a string + /*! + \param list The list to stringify + \param user_agents Whether to apply the special rule to parse user-agents lists or not + \return The resulting string + \see writeConfigs() + */ + const std::string list2string( const std::vector& list, const bool& user_agent=false ); + + //! Retrieves a list of items from the given string + /*! + \param list The list to stringify + \param user_agents Whether to apply the special rule to parse user-agents lists or not + \return The resulting list + \see readConfigs() + */ + const std::vector string2list( const std::string& string, const bool& user_agent=false ); + + // string to bool and vice versa + const std::unordered_map s2b = { {"true",true}, {"false",false} }; + const std::unordered_map b2s = { {true,"true"}, {false,"false"} }; + + + ////////////////// + //// LANGUAGE //// + + QTranslator translator; + + std::string language = "en"; + + //! Translates the UI to the selected language + void updateUiLanguage(); + + + ///////////////////////// + //// WINDOW GEOMETRY //// + + //! Converts the window's geometry to string + /*! + \see writeConfigs() + */ + const std::string geometryToString(); + + //! Retrieves the window geometry from the given string + /*! + \see readConfigs() + */ + void geometryFromString( const std::string& geometry ); + + + ///////////////// + //// GENERAL //// + + // quantoty of informational dialogs to display + int dialogs_level = 2; // 0: essential, 1: usefull, 2: explanatory + + // default web server + int default_ws = 11; + + + ////////////////// + //// GRAPHICS //// + ////////////////// + + // remember window position and sizes + bool remember_window = true; + + // themes + int window_theme_id = 0; + int charts_theme_id = 0; + int icons_theme_id = 0; + + QString icons_theme; + + //! Auto-detects the icon-set to use depending on the current window theme + void detectIconsTheme(); + + //! Updates the icons on the window + void updateUiIcons(); + + //! Updates the window theme + void updateUiTheme(); + + //! Updates the fonts on the window + void updateUiFonts(); + + const std::vector CHARTS_THEMES = { + QChart::ChartTheme::ChartThemeLight, + QChart::ChartTheme::ChartThemeDark, + QChart::ChartTheme::ChartThemeBrownSand, + QChart::ChartTheme::ChartThemeBlueCerulean + }; + + // color schemes + std::unordered_map> TB_COLOR_SCHEMES; + + // colors + std::unordered_map COLORS; + + // fonts + std::unordered_map FONTS; + + int font_size = 13; + int font_size_big = 16; + int font_size_small = 10; + + // base font families, to build fonts from + QString main_font_family; + QString alternative_font_family; + QString script_font_family; + + + ///////////////////// + //// GENERAL USE //// + ///////////////////// + + //! Printable size, including suffix + const QString printableSize( const int& bytes ); + + //! Printable time, including suffix(es) + const QString printableTime( const int& seconds ); + + //! Printable speed, namely printable size over printable time + const QString printableSpeed( const int& bytes, const int& secs ); + + + //! Resolves the given path and returns the canonical path + const std::string resolvePath( const std::string& path ); + + //! Returns the parent folder of the given path + const std::string basePath( const std::string& path ); + + + //////////////// + //// CHECKS //// + //////////////// + + bool initiating = true; + + bool db_ok = true; + + //! Makes the initial integrity checks + void makeInitialChecks(); + + //! Checks the integrity of the logs data collection database + const bool& checkDataDB(); + + + /////////////////// + //// DATABASES //// + /////////////////// + + bool db_edited = false; + + bool db_do_backup = true; + + unsigned db_backups_number = 3; + + //! Backs-up the logs data collection database + void backupDatabase(); + + std::string db_data_path; + std::string db_hashes_path; + + // actions when working on a db + bool db_working = false; + + //! Called when a member begins/ends performing operations on the database + void setDbWorkingState( const bool& state ); + + + ////////////////// + //// CRAPTABS //// + ////////////////// + + void switchMainTab( const int& new_index ); + + + ///////////////// + //// CRAPLOG //// + ///////////////// + + Craplog craplog; + + QTimer* craplog_timer = new QTimer(); + QTimer* waiter_timer; + + std::chrono::system_clock::time_point waiter_timer_start; + std::chrono::system_clock::duration waiter_timer_elapsed; + + //! The logs parser started working + void craplogStarted(); + + //! The logs parser finished working + void craplogFinished(); + + void checkMakeStats_Makable(); + + + ////////////// + //// LOGS //// + + bool loading_LogsList = false; + + void disableAllButtons_LogFiles_WS(); + void enableAllButtons_LogFiles_WS(); + + bool hide_used_files = false; + bool refreshing_list = false; + + + ////////////////////// + //// TEXT BROWSER //// + + TextBrowser TB; + + + ////////////////////////// + //// LOGS PERFORMANCE //// + + void update_MakeStats_labels(); + + void update_MakeStats_graphs(); + + void reset_MakeStats_labels(); + + + ////////////////// + //// CRAPVIEW //// + ////////////////// + + Crapview crapview; + + QTimer *crapview_timer = new QTimer(); + + // change tab + void switchStatsTab( const int& new_index ); + + //! Queries the available dates from the db and apply to the tabs + /*! + \see Crapview::refreshDates() + */ + void refreshStatsDates(); + + // check if drawing conditions are met + void checkStatsWarnDrawable(); + void checkStatsSpeedDrawable(); + void checkStatsCountDrawable(); + void checkStatsDayDrawable(); + void checkStatsRelatDrawable(); + + // count + QString count_fld; + void startCountDrawing(); + void resetStatsCountButtons(); + + // globals + QString glob_ws; + void globalsButtonClicked(); + void resetStatsGlobals(); + + + ///////////////// + //// CRAPSET //// + ///////////////// + + void refreshTextBrowserPreview(); + + void refreshChartsPreview(); + + const int getIisLogsModule(); + + + ////////////////// + //// CRAPHELP //// + ////////////////// + + Craphelp* craphelp = new Craphelp(); + + void showHelp( const std::string& file_name ); + + + //////////////// + //// CRAPUP //// + //////////////// + + Crapup *crapup = new Crapup(0,""); + + + ////////////////// + //// CRAPNOTE //// + ////////////////// + + Crapnote* crapnote = new Crapnote(); + + + ////////////////// + //// CRAPINFO //// + ////////////////// + + Crapinfo* crapinfo = new Crapinfo(0,"","","",""); + + + /////////////////// + //// CRAPGAMES //// + /////////////////// + + CrissCross* crisscross = new CrissCross( 0 ); + + SnakeGame* snake = new SnakeGame( 0, QFont() ); + +}; +#endif // MAINWINDOW_H diff --git a/logdoctor/mainwindow.ui b/logdoctor/mainwindow.ui new file mode 100644 index 00000000..f4c2f32d --- /dev/null +++ b/logdoctor/mainwindow.ui @@ -0,0 +1,11354 @@ + + + MainWindow + + + + 0 + 0 + 924 + 574 + + + + + 0 + 0 + + + + LogDoctor + + + + :/logo/logo/logdoctor.svg:/logo/logo/logdoctor.svg + + + + + + + + 0 + 0 + + + + + 0 + + + 0 + + + 8 + + + 0 + + + 0 + + + + + + 68 + 0 + + + + + 68 + 16777215 + + + + QFrame::StyledPanel + + + QFrame::Sunken + + + 0 + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 68 + 84 + + + + + 68 + 84 + + + + PointingHandCursor + + + + + + + 48 + 64 + + + + true + + + + + + + + 68 + 84 + + + + + 68 + 84 + + + + PointingHandCursor + + + + + + + 48 + 64 + + + + true + + + + + + + + 68 + 84 + + + + + 68 + 84 + + + + PointingHandCursor + + + + + + + 48 + 64 + + + + true + + + + + + + Qt::Vertical + + + + 20 + 273 + + + + + + + + + + + + 16 + + + + + + + 0 + + + + + + + + 0 + 0 + + + + Qt::NoFocus + + + 0 + + + + + 4 + + + 0 + + + 4 + + + 0 + + + 8 + + + + + + 320 + 48 + + + + QFrame::StyledPanel + + + QFrame::Sunken + + + + 4 + + + 8 + + + 8 + + + 8 + + + 8 + + + + + + 96 + 0 + + + + + 0 + 32 + + + + + 16777215 + 32 + + + + + 13 + + + + PointingHandCursor + + + Parse logs from the Apache2 web server + + + Apache2 + + + true + + + + + + + + 96 + 0 + + + + + 0 + 32 + + + + + 16777215 + 32 + + + + + 13 + + + + PointingHandCursor + + + Parse logs from the Nginx web server + + + Nginx + + + true + + + + + + + + 96 + 0 + + + + + 0 + 32 + + + + + 16777215 + 32 + + + + + 13 + + + + PointingHandCursor + + + Parse logs from the Microsoft IIS web server + + + IIS + + + true + + + + + + + + + + false + + + false + + + + + + QTextEdit::NoWrap + + + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><meta charset="utf-8" /><style type="text/css"> +p, li { white-space: pre-wrap; } +hr { height: 1px; border-width: 0; } +li.unchecked::marker { content: "\2610"; } +li.checked::marker { content: "\2612"; } +</style></head><body style=" font-family:'Noto Sans'; font-size:16pt; font-weight:400; font-style:normal;"> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p></body></html> + + + Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + false + + + + + + + + 0 + 0 + + + + + 10 + + + + PointingHandCursor + + + false + + + Select/deselect all the files + + + All + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 90 + 20 + + + + + + + + + 0 + 0 + + + + + 32 + 36 + + + + + 32 + 36 + + + + PointingHandCursor + + + Inspect a log file + + + + + + + 32 + 32 + + + + + + + + + 0 + 0 + + + + + 320 + 16777215 + + + + + 13 + + + + true + + + QAbstractItemView::SingleSelection + + + QAbstractItemView::SelectRows + + + true + + + true + + + 75 + + + 150 + + + true + + + + Name + + + + 12 + + + + + + Size + + + + 12 + false + + + + + + + + + + 0 + 0 + + + + + 32 + 32 + + + + + 32 + 32 + + + + + 13 + + + + PointingHandCursor + + + Refresh the list + + + + + + + 16 + 16 + + + + true + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 280 + 20 + + + + + + + + + 0 + 32 + + + + + 16777215 + 32 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Qt::Horizontal + + + + 154 + 20 + + + + + + + + + 512 + 32 + + + + + 512 + 32 + + + + PointingHandCursor + + + + + + + :/icons/icons/midtone/down.png:/icons/icons/midtone/down.png + + + + 512 + 32 + + + + true + + + + + + + Qt::Horizontal + + + + 153 + 20 + + + + + + + + + + + + + 4 + + + 4 + + + 0 + + + 4 + + + 0 + + + + + + 0 + 32 + + + + + 16777215 + 32 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Qt::Horizontal + + + + 154 + 20 + + + + + + + + + 512 + 32 + + + + + 512 + 32 + + + + PointingHandCursor + + + + + + + :/icons/icons/midtone/up.png:/icons/icons/midtone/up.png + + + + 512 + 32 + + + + true + + + + + + + Qt::Horizontal + + + + 153 + 20 + + + + + + + + + + + + 0 + 112 + + + + + 16777215 + 112 + + + + + 4 + + + 8 + + + 0 + + + 8 + + + 0 + + + + + Qt::Horizontal + + + + 16 + 98 + + + + + + + + + 96 + 0 + + + + + 128 + 16777215 + + + + Total size of the parsed data + + + + 8 + + + 4 + + + + + false + + + + 64 + 64 + + + + + 32 + + + + Qt::AlignCenter + + + + + + + false + + + + 0 + 0 + + + + + 64 + 32 + + + + + 192 + 128 + + + + + 13 + + + + 0 KiB + + + Qt::AlignCenter + + + + + + + + + + Qt::Horizontal + + + + 16 + 98 + + + + + + + + + 96 + 0 + + + + + 128 + 16777215 + + + + Total number of parsed lines + + + + 8 + + + 4 + + + + + false + + + + 64 + 64 + + + + + 32 + + + + Qt::AlignCenter + + + + + + + false + + + + 0 + 0 + + + + + 64 + 32 + + + + + 192 + 128 + + + + + 13 + + + + 0 + + + Qt::AlignCenter + + + + + + + + + + Qt::Horizontal + + + + 16 + 98 + + + + + + + + false + + + + 0 + 0 + + + + + 128 + 64 + + + + + 192 + 64 + + + + PointingHandCursor + + + Qt::TabFocus + + + Start parsing the selected files + + + START + + + + + + + Qt::Horizontal + + + + 16 + 98 + + + + + + + + + 96 + 0 + + + + + 128 + 16777215 + + + + Time elapsed since the start + + + + 8 + + + 4 + + + + + false + + + + 64 + 64 + + + + + 32 + + + + Qt::AlignCenter + + + + + + + false + + + + 0 + 0 + + + + + 64 + 32 + + + + + 192 + 128 + + + + + 13 + + + + 00:00 + + + Qt::AlignCenter + + + + + + + + + + Qt::Horizontal + + + + 16 + 98 + + + + + + + + + 96 + 0 + + + + + 128 + 16777215 + + + + Average speed, in parsed data size per second + + + QFrame::Raised + + + + 8 + + + 4 + + + + + false + + + + 64 + 64 + + + + + 32 + + + + Qt::AlignCenter + + + + + + + false + + + + 0 + 0 + + + + + 64 + 32 + + + + + 192 + 128 + + + + + 13 + + + + 0 Kib/s + + + Qt::AlignCenter + + + + + + + + + + Qt::Horizontal + + + + 16 + 98 + + + + + + + + + + + + 0 + 128 + + + + Qt::NoFocus + + + false + + + + + + + + + + + + + 8 + + + 0 + + + 8 + + + 0 + + + + + 0 + + + + + 8 + + + 8 + + + 8 + + + 8 + + + + + + 0 + 0 + + + + + + + + 64 + 88 + + + + + 64 + 88 + + + + + 23 + + + + PointingHandCursor + + + Draw the chart + + + + 44 + 44 + + + + + + + + Qt::Vertical + + + + + + + QFrame::StyledPanel + + + QFrame::Sunken + + + + + + + 13 + + + + Web Server + + + + + + + + 100 + 32 + + + + + 16777215 + 32 + + + + + 13 + + + + Select a Web Server + + + QComboBox::AdjustToContents + + + + Apache2 + + + + + Nginx + + + + + IIS + + + + + + + + + + + Qt::Vertical + + + + + + + + 356 + 16777215 + + + + + + + + 13 + + + + Year + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 13 + + + + Month + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 13 + + + + Day + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Qt::Vertical + + + + + + + + 0 + 0 + + + + + 13 + + + + Qt::LeftToRight + + + Hour + + + + + + + + 0 + 0 + + + + + 72 + 32 + + + + + 72 + 32 + + + + + 13 + + + + + + + + + 120 + 32 + + + + + 16777215 + 32 + + + + + 13 + + + + + + + + + 56 + 32 + + + + + 56 + 32 + + + + + 13 + + + + + + + + false + + + + 0 + 0 + + + + + 64 + 32 + + + + + 64 + 32 + + + + + 13 + + + + + + + + + + + Qt::Horizontal + + + + 82 + 20 + + + + + + + + false + + + + 64 + 88 + + + + + 64 + 88 + + + + + 23 + + + + PointingHandCursor + + + Update the database with current Warning States + + + + 44 + 44 + + + + + + + + + + + Qt::Vertical + + + + + 13 + + + + QAbstractItemView::NoEditTriggers + + + false + + + false + + + QAbstractItemView::ScrollPerPixel + + + true + + + 64 + + + 128 + + + true + + + + Warning + + + Log line marked as Warning + + + AlignLeading|AlignVCenter + + + + + Date + + + Date when the request arrived (YYYY-MM-DD) + + + AlignLeading|AlignVCenter + + + + + Time + + + Time when the request arrived (hh:mm:ss) + + + AlignLeading|AlignVCenter + + + + + Protocol + + + Protocol of the request + + + AlignLeading|AlignVCenter + + + + + Method + + + Method of the request + + + AlignLeading|AlignVCenter + + + + + URI + + + URI of the requested page + + + AlignLeading|AlignVCenter + + + + + Query + + + Query carried along with the URI + + + AlignLeading|AlignVCenter + + + + + Response code + + + Response code from the server + + + AlignLeading|AlignVCenter + + + + + Referrer + + + The URL which redirected the Client to the requested page + + + AlignLeading|AlignVCenter + + + + + Cookie + + + Cookie used for the request + + + AlignLeading|AlignVCenter + + + + + User-agent + + + User-agent of the client which made the request + + + AlignLeading|AlignVCenter + + + + + Client + + + IP address of the Client which made the request + + + AlignLeading|AlignVCenter + + + + + Bytes received + + + Size ib Bytes of the request, usually includes header and data + + + AlignLeading|AlignVCenter + + + + + Bytes sent + + + Size in Bytes of the served content, usually includes header and data + + + AlignLeading|AlignVCenter + + + + + Time taken + + + Time taken by the server to serve the content, in milliseconds + + + AlignLeading|AlignVCenter + + + + + rowid + + + + + + AlignLeading|AlignVCenter + + + + + + + + + + + + 8 + + + 18 + + + 8 + + + 8 + + + + + + 0 + 0 + + + + + 321 + 0 + + + + + 0 + 140 + + + + + 8 + + + 0 + + + 8 + + + 8 + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 112 + 32 + + + + + 112 + 32 + + + + + 13 + + + + Select a Web Server + + + QComboBox::AdjustToContents + + + + Apache2 + + + + + Nginx + + + + + IIS + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 0 + 8 + + + + Qt::Horizontal + + + + + + + + + + + 0 + 32 + + + + + 64 + 32 + + + + + 13 + + + + + + + + + 0 + 32 + + + + + 80 + 32 + + + + + 13 + + + + + + + + + 120 + 32 + + + + + 16777215 + 32 + + + + + 13 + + + + + + + + + 13 + + + + Year + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 13 + + + + Month + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 13 + + + + Day + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + + + + Qt::Vertical + + + + + 13 + + + + QAbstractItemView::NoEditTriggers + + + false + + + false + + + true + + + 64 + + + 128 + + + true + + + + Time taken + + + Time taken by the server to serve the content, in milliseconds + + + AlignLeading|AlignVCenter + + + + + URI + + + URI of the requested page + + + AlignLeading|AlignVCenter + + + + + Query + + + Query carried along with the URI + + + AlignLeading|AlignVCenter + + + + + Method + + + Method of the request + + + AlignLeading|AlignVCenter + + + + + Protocol + + + Protocol of the request + + + AlignLeading|AlignVCenter + + + + + Response code + + + Response code from the server + + + AlignLeading|AlignVCenter + + + + + Time + + + Time when the request arrived (hh:mm:ss) + + + AlignLeading|AlignVCenter + + + + + + + + + + + 0 + 0 + + + + + 0 + 328 + + + + + 321 + 16777215 + + + + + + + + 0 + 32 + + + + + 16777215 + 32 + + + + + 13 + + + + Only use lines in which the field is starting with this string + + + + + + + + + + + 0 + 32 + + + + + 16777215 + 32 + + + + + 13 + + + + Only use lines in which the field is starting with this string + + + + + + + + 13 + + + + Protocol of the request + + + Protocol: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + Noto Sans + 13 + + + + Method of the request + + + Method: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 0 + 32 + + + + + 16777215 + 32 + + + + + 13 + + + + Only use lines in which the field is matching this statement. +Use '!', '=','<' or '>' to declare what to use + + + + + + + + + + + 0 + 32 + + + + + 16777215 + 32 + + + + + 13 + + + + Only use lines in which the field is starting with this string + + + + + + + + Noto Sans + 13 + + + + Response code from the server + + + Response: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + Noto Sans + 13 + + + + Query carried along with the URI + + + Query: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 0 + 32 + + + + + 16777215 + 32 + + + + + 13 + + + + Only use lines in which the field is starting with this string + + + + + + + + + + + 13 + + + + URI of the requested page + + + URI: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 0 + 0 + + + + + 0 + 64 + + + + + 16777215 + 64 + + + + + 23 + + + + PointingHandCursor + + + + 44 + 44 + + + + + + + + + 16777215 + 28 + + + + + Noto Sans + 16 + + + + Filters + + + Qt::AlignCenter + + + + + + + + + + + + 8 + + + 18 + + + 8 + + + 8 + + + + + Qt::Vertical + + + + + 13 + + + + QAbstractItemView::NoEditTriggers + + + false + + + false + + + true + + + 64 + + + 128 + + + true + + + false + + + + Count + + + Number of occurrences + + + AlignLeading|AlignVCenter + + + + + Item + + + Value of the field + + + AlignLeading|AlignVCenter + + + + + + + + + + + 0 + 0 + + + + + 321 + 0 + + + + + 321 + 16777215 + + + + + 8 + + + 0 + + + 8 + + + 8 + + + + + QFrame::NoFrame + + + Qt::ScrollBarAlwaysOn + + + Qt::ScrollBarAlwaysOff + + + Qt::AlignHCenter|Qt::AlignTop + + + + + 14 + 0 + 263 + 402 + + + + + 0 + 0 + + + + + + + + 0 + 0 + + + + + 240 + 0 + + + + + 13 + + + + PointingHandCursor + + + Protocol of the request + + + Protocol + + + true + + + + + + + + 0 + 0 + + + + + 240 + 0 + + + + + 13 + + + + PointingHandCursor + + + Method of the request + + + Method + + + true + + + + + + + + 0 + 0 + + + + + 240 + 0 + + + + + 13 + + + + PointingHandCursor + + + URI of the requested page + + + URI + + + true + + + + + + + + 0 + 0 + + + + + 240 + 0 + + + + + 13 + + + + PointingHandCursor + + + Query carried along with the URI + + + Query + + + true + + + + + + + + 0 + 0 + + + + + 240 + 0 + + + + + 13 + + + + PointingHandCursor + + + Response code from the server + + + Response code + + + true + + + + + + + + 0 + 0 + + + + + 240 + 0 + + + + + 13 + + + + PointingHandCursor + + + The URL which redirected the Client to the requested page + + + Referrer + + + true + + + + + + + + 0 + 0 + + + + + 240 + 0 + + + + + 13 + + + + PointingHandCursor + + + Cookie used for the request + + + Cookie + + + true + + + + + + + + 0 + 0 + + + + + 240 + 0 + + + + + 13 + + + + PointingHandCursor + + + User-agent of the client which made the request + + + User-agent + + + true + + + + + + + + 0 + 0 + + + + + 240 + 0 + + + + + 13 + + + + PointingHandCursor + + + IP address of the Client which made the request + + + Client + + + true + + + + + + + + + + + + 112 + 32 + + + + + 112 + 32 + + + + + 13 + + + + Select a Web Server + + + QComboBox::AdjustToContents + + + + Apache2 + + + + + Nginx + + + + + IIS + + + + + + + + + 0 + 8 + + + + Qt::Horizontal + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + 0 + 32 + + + + + 80 + 32 + + + + + 13 + + + + + + + + + 120 + 32 + + + + + 16777215 + 32 + + + + + 13 + + + + + + + + + 13 + + + + Day + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 13 + + + + Year + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 0 + 32 + + + + + 64 + 32 + + + + + 13 + + + + + + + + + 13 + + + + Month + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 298 + 8 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + 8 + + + 8 + + + 8 + + + 8 + + + + + + 0 + 0 + + + + + + + QFrame::StyledPanel + + + QFrame::Sunken + + + + + + + 13 + + + + Month + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 13 + + + + Day + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 13 + + + + From: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + false + + + + 0 + 32 + + + + + 72 + 32 + + + + + 13 + + + + + + + + + 0 + 0 + + + + + 0 + 32 + + + + + 72 + 32 + + + + + 13 + + + + + + + + + 13 + + + + Year + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 0 + 32 + + + + + 56 + 32 + + + + + 13 + + + + + + + + false + + + + 0 + 32 + + + + + 16777215 + 32 + + + + + 13 + + + + + + + + + 13 + + + + To: + + + + + + + false + + + + 0 + 32 + + + + + 56 + 32 + + + + + 13 + + + + + + + + + 120 + 32 + + + + + 16777215 + 32 + + + + + 13 + + + + + + + + + + + + + + + 0 + 32 + + + + + 16777215 + 32 + + + + + 13 + + + + With strings, only the lines in which the field is starting with this string will be used. +With numbers, use '!', '=','<' or '>' to declare what to use + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 298 + 44 + + + + + + + + + 13 + + + + Field: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 0 + 32 + + + + + 160 + 32 + + + + + 13 + + + + Select a log field to view + + + + + + + + 13 + + + + Filter: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + Qt::Vertical + + + + + + + + 100 + 88 + + + + + 100 + 88 + + + + + 23 + + + + PointingHandCursor + + + Draw the chart + + + + 44 + 44 + + + + + + + + Qt::Vertical + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 10 + + + + + + + + + 100 + 32 + + + + + 16777215 + 32 + + + + + 13 + + + + Select a Web Server + + + QComboBox::AdjustToContents + + + + Apache2 + + + + + Nginx + + + + + IIS + + + + + + + + + + + + + + + + 8 + + + 2 + + + 8 + + + 8 + + + + + + 0 + 0 + + + + + 16777215 + 192 + + + + + + + Qt::Vertical + + + + 20 + 4 + + + + + + + + + 100 + 32 + + + + + 16777215 + 32 + + + + + 13 + + + + Select a Web Server + + + QComboBox::AdjustToContents + + + + Apache2 + + + + + Nginx + + + + + IIS + + + + + + + + + 0 + 0 + + + + + 6 + + + + + + 44 + 0 + + + + + 13 + + + + From: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 0 + 0 + + + + + 0 + 32 + + + + + 72 + 32 + + + + + 13 + + + + Year + + + Year + + + + + + + + 120 + 32 + + + + + 16777215 + 32 + + + + + 13 + + + + Month + + + Month + + + + + + + + 0 + 32 + + + + + 60 + 32 + + + + + 13 + + + + Day + + + Day + + + + + + + + 44 + 0 + + + + + 44 + 16777215 + + + + + 13 + + + + To: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 0 + 32 + + + + + 72 + 32 + + + + + 13 + + + + Year + + + Year + + + + + + + + 120 + 32 + + + + + 16777215 + 32 + + + + + 13 + + + + Month + + + Month + + + + + + + + 0 + 32 + + + + + 60 + 32 + + + + + 13 + + + + Day + + + Day + + + + + + + + + + + 100 + 88 + + + + + 100 + 88 + + + + + 23 + + + + PointingHandCursor + + + Draw the chart + + + + 44 + 44 + + + + + + + + QFrame::StyledPanel + + + QFrame::Sunken + + + + + + + 48 + 0 + + + + + 13 + + + + Filter: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 0 + 32 + + + + + 16777215 + 32 + + + + + 13 + + + + With strings, only the lines in which the field is starting with this string will be used. +With numbers, use '!', '=','<' or '>' to declare what to use + + + + + + + + 160 + 32 + + + + + 16777215 + 32 + + + + + 13 + + + + Select a log field to view + + + + + + + + 0 + 32 + + + + + 16777215 + 32 + + + + + 13 + + + + With strings, only the lines in which the field is starting with this string will be used. +With numbers, use '!', '=','<' or '>' to declare what to use + + + + + + + + 160 + 32 + + + + + 16777215 + 32 + + + + + 13 + + + + Select a log field to view + + + + + + + + 44 + 0 + + + + + 13 + + + + Field: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 48 + 0 + + + + + 13 + + + + Filter: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 44 + 0 + + + + + 13 + + + + Field: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + Qt::Vertical + + + + + + + + + + + + + + + + + + 0 + 0 + + + + + 16777215 + 64 + + + + + + + Qt::Horizontal + + + + 234 + 20 + + + + + + + + + 0 + 48 + + + + + 320 + 48 + + + + QFrame::StyledPanel + + + QFrame::Sunken + + + + 8 + + + 8 + + + 8 + + + 8 + + + 8 + + + + + + 96 + 0 + + + + + 0 + 32 + + + + + 16777215 + 32 + + + + + 13 + + + + PointingHandCursor + + + Parse logs from the Apache2 web server + + + Apache2 + + + true + + + + + + + + 96 + 0 + + + + + 0 + 32 + + + + + 16777215 + 32 + + + + + 13 + + + + PointingHandCursor + + + Parse logs from the Nginx web server + + + Nginx + + + true + + + + + + + + 96 + 0 + + + + + 0 + 32 + + + + + 16777215 + 32 + + + + + 13 + + + + PointingHandCursor + + + Parse logs from the Microsoft IIS web server + + + IIS + + + true + + + + + + + + + + Qt::Horizontal + + + + 234 + 20 + + + + + + + + + + + + 0 + 0 + + + + Qt::Horizontal + + + 8 + + + false + + + + Qt::Vertical + + + 8 + + + false + + + + + + + true + + + + + 0 + 0 + 317 + 348 + + + + + + + + + + + 16777215 + 20 + + + + + 10 + + + + 0 + + + Qt::AlignCenter + + + + + + + + 16777215 + 32 + + + + + 13 + + + + Protocol + + + Qt::AlignCenter + + + + + + + + 16777215 + 20 + + + + + 10 + + + + 0 + + + Qt::AlignCenter + + + + + + + + 16777215 + 32 + + + + + 15 + + + + - + + + Qt::AlignCenter + + + + + + + + 16777215 + 32 + + + + + 13 + + + + Method + + + Qt::AlignCenter + + + + + + + + 16777215 + 32 + + + + + 15 + + + + - + + + Qt::AlignCenter + + + + + + + Qt::Vertical + + + + + + + + + + + + + + 16777215 + 32 + + + + + 15 + + + + - + + + Qt::AlignCenter + + + + + + + + 16777215 + 32 + + + + + 13 + + + + URI + + + Qt::AlignCenter + + + + + + + + 16777215 + 20 + + + + + 10 + + + + 0 + + + Qt::AlignCenter + + + + + + + + + + Qt::Horizontal + + + + + + + + + + + 16777215 + 32 + + + + + 13 + + + + User-agent + + + Qt::AlignCenter + + + + + + + + 16777215 + 20 + + + + + 10 + + + + 0 + + + Qt::AlignCenter + + + + + + + + 16777215 + 32 + + + + + 15 + + + + - + + + Qt::AlignCenter + + + + + + + + + + Qt::Horizontal + + + + + + + + + + + + 16777215 + 32 + + + + + 16 + + + + Most recurrent + + + Qt::AlignCenter + + + + + + + + + + + + 16777215 + 32 + + + + + 16 + + + + Most trafficked + + + Qt::AlignCenter + + + + + + + true + + + + + 0 + 0 + 317 + 348 + + + + + + + + + + + 16777215 + 32 + + + + + 13 + + + + Date ever + + + Qt::AlignCenter + + + + + + + + 16777215 + 32 + + + + + 15 + + + + - + + + Qt::AlignCenter + + + + + + + + 16777215 + 20 + + + + + 10 + + + + 0 + + + Qt::AlignCenter + + + + + + + + + + + + + + 16777215 + 32 + + + + + 13 + + + + Day of the week + + + Qt::AlignCenter + + + + + + + + 16777215 + 32 + + + + + 15 + + + + - + + + Qt::AlignCenter + + + + + + + + 16777215 + 20 + + + + + 10 + + + + 0 + + + Qt::AlignCenter + + + + + + + + + + + + + + 16777215 + 32 + + + + + 13 + + + + Hour of the day + + + Qt::AlignCenter + + + + + + + + 16777215 + 32 + + + + + 15 + + + + - + + + Qt::AlignCenter + + + + + + + + 16777215 + 20 + + + + + 10 + + + + 0 + + + Qt::AlignCenter + + + + + + + + + + Qt::Horizontal + + + + + + + Qt::Horizontal + + + + + + + + + + + + + Qt::Vertical + + + 8 + + + false + + + + + + + true + + + + + 0 + 0 + 429 + 276 + + + + + + + Qt::Horizontal + + + + + + + + + + + 16777215 + 32 + + + + + 13 + + + + Time taken + + + Qt::AlignCenter + + + + + + + + 16777215 + 32 + + + + + 15 + + + + - + + + Qt::AlignCenter + + + + + + + + 16777215 + 32 + + + + + 15 + + + + - + + + Qt::AlignCenter + + + + + + + + + + + + + + 16777215 + 32 + + + + + 13 + + + + Bytes sent + + + Qt::AlignCenter + + + + + + + + 16777215 + 32 + + + + + 15 + + + + - + + + Qt::AlignCenter + + + + + + + + 16777215 + 32 + + + + + 15 + + + + - + + + Qt::AlignCenter + + + + + + + + + + + + + + 16777215 + 32 + + + + + 13 + + + + Bytes received + + + Qt::AlignCenter + + + + + + + + 16777215 + 32 + + + + + 15 + + + + - + + + Qt::AlignCenter + + + + + + + + 16777215 + 32 + + + + + 15 + + + + - + + + Qt::AlignCenter + + + + + + + + + + Qt::Horizontal + + + + + + + + + + + + 16777215 + 32 + + + + + 16 + + + + Mean/Max performances + + + Qt::AlignCenter + + + + + + + + + + + true + + + + + 0 + 0 + 429 + 276 + + + + + + + + + + + 16777215 + 32 + + + + + 13 + + + + Bytes sent + + + Qt::AlignCenter + + + + + + + + 16777215 + 32 + + + + + 15 + + + + - + + + Qt::AlignCenter + + + + + + + + + + Qt::Horizontal + + + + + + + + + + + 16777215 + 32 + + + + + 13 + + + + Requests received + + + Qt::AlignCenter + + + + + + + + 16777215 + 32 + + + + + 15 + + + + - + + + Qt::AlignCenter + + + + + + + + + + + + + + 16777215 + 32 + + + + + 13 + + + + Time taken + + + Qt::AlignCenter + + + + + + + + 16777215 + 32 + + + + + 15 + + + + - + + + Qt::AlignCenter + + + + + + + + + + Qt::Horizontal + + + + + + + + + + + + 16777215 + 32 + + + + + 16 + + + + Total work + + + Qt::AlignCenter + + + + + + + + + + + + + + + + + 0 + 34 + + + + + 16777215 + 34 + + + + QFrame::StyledPanel + + + QFrame::Sunken + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 32 + + + + + 16777215 + 32 + + + + + + + + 32 + 32 + + + + true + + + + + + + + 0 + 32 + + + + + 16777215 + 32 + + + + + + + + 32 + 32 + + + + true + + + + + + + + 0 + 32 + + + + + 16777215 + 32 + + + + + + + + 32 + 32 + + + + true + + + + + + + + 0 + 32 + + + + + 16777215 + 32 + + + + + + + + 32 + 32 + + + + true + + + + + + + + 0 + 32 + + + + + 16777215 + 32 + + + + + + + + 32 + 32 + + + + true + + + + + + + + 0 + 32 + + + + + 16777215 + 32 + + + + + + + + 32 + 32 + + + + true + + + + + + + + + + + + 8 + + + 8 + + + 8 + + + 8 + + + + + QTabWidget::West + + + 0 + + + + General + + + General settings + + + + 8 + + + 8 + + + 8 + + + 8 + + + + + + 13 + + + + 0 + + + + Window + + + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 16 + 32 + + + + + + + + + 0 + 0 + + + + + 0 + 32 + + + + + 16777215 + 32 + + + + + 13 + + + + Remember the window's position and size + + + Remember position and size + + + + + + + + 128 + 32 + + + + + 16777215 + 32 + + + + + 16 + + + + Remember window's position and size + + + Geometry + + + + + + + + + + + + + + 128 + 32 + + + + + 16777215 + 32 + + + + + 16 + + + + Theme to use for the window + + + Theme + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 16 + 32 + + + + + + + + + 0 + 0 + + + + + 160 + 32 + + + + + 160 + 32 + + + + + 13 + + + + 10 + + + + None (System) + + + + + Ash + + + + + Candy + + + + + Herb + + + + + Powder + + + + + + + + Qt::Horizontal + + + + 569 + 32 + + + + + + + + + + + + + + + 128 + 32 + + + + + 16777215 + 32 + + + + + 16 + + + + Theme to use for the window + + + Icons + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 16 + 32 + + + + + + + + + 0 + 0 + + + + + 160 + 32 + + + + + 160 + 32 + + + + + 13 + + + + 10 + + + + Auto (Default) + + + + + Light + + + + + Dark + + + + + + + + Qt::Horizontal + + + + 569 + 32 + + + + + + + + + + + Qt::Vertical + + + + 748 + 260 + + + + + + + + + Dialogs + + + + + + + 560 + 0 + + + + + + + + 180 + 32 + + + + + 16777215 + 32 + + + + + 16 + + + + Define the quantity of dialog mesages shown + + + Dialogs level + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 180 + 18 + + + + + + + + + 128 + 24 + + + + + 128 + 32 + + + + + 10 + + + + Reduced quantity of dialog messages shown + + + Essential + + + Qt::AlignBottom|Qt::AlignHCenter + + + + + + + + 164 + 24 + + + + + 164 + 32 + + + + + 10 + + + + Normal quantity of dialog messages shown + + + Normal + + + Qt::AlignBottom|Qt::AlignHCenter + + + + + + + + 128 + 24 + + + + + 128 + 32 + + + + + 10 + + + + Augmented quantity of dialog messages shown + + + Explanatory + + + Qt::AlignBottom|Qt::AlignHCenter + + + + + + + Qt::Horizontal + + + + 98 + 138 + + + + + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 16 + 93 + + + + + + + + + 192 + 32 + + + + + 192 + 32 + + + + + 13 + + + + Dialogs from the main processes + + + General + + + + + + + + 320 + 24 + + + + + 320 + 32 + + + + 2 + + + 2 + + + 2 + + + Qt::Horizontal + + + QSlider::TicksBothSides + + + 1 + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 40 + 93 + + + + + + + + + 192 + 32 + + + + + 192 + 32 + + + + + 13 + + + + Dialogs emitted when parsing logs + + + Logs parser + + + + + + + + 320 + 24 + + + + + 320 + 32 + + + + 2 + + + 2 + + + 2 + + + Qt::Horizontal + + + QSlider::TicksBothSides + + + 1 + + + + + + + + 192 + 32 + + + + + 192 + 32 + + + + + 13 + + + + Dialogs emitted when viewing statistics + + + Statistics viewer + + + + + + + + 320 + 24 + + + + + 320 + 32 + + + + 2 + + + 2 + + + 2 + + + Qt::Horizontal + + + QSlider::TicksAbove + + + 1 + + + + + + + + + + + + + Qt::Vertical + + + + 718 + 271 + + + + + + + + + TextBrowser + + + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 16 + 32 + + + + + + + + + 0 + 0 + + + + + 160 + 32 + + + + + 160 + 32 + + + + + 13 + + + + + Metropolis + + + + + Hack + + + + + 3270 + + + + + + + + Qt::Horizontal + + + + 569 + 32 + + + + + + + + + 128 + 32 + + + + + 16777215 + 32 + + + + + 16 + + + + Font to use for the Text Browser + + + Font + + + + + + + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 16 + 32 + + + + + + + + + 0 + 0 + + + + + 0 + 32 + + + + + 16777215 + 32 + + + + + 13 + + + + Double-spaced lines + + + Use wide lines + + + + + + + + 128 + 32 + + + + + 16777215 + 32 + + + + + 16 + + + + Define the spacing between lines + + + Lines spacing + + + + + + + + + + + + + + 0 + 0 + + + + + 160 + 32 + + + + + 160 + 32 + + + + + 13 + + + + + None + + + + + Breeze + + + + + Monokai + + + + + Radical + + + + + + + + Qt::Horizontal + + + + 566 + 32 + + + + + + + + + 128 + 32 + + + + + 16777215 + 32 + + + + + 16 + + + + Color scheme to use for the Text Browser + + + Color scheme + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 16 + 32 + + + + + + + + + + + + 0 + 32 + + + + + 16777215 + 32 + + + + Qt::Horizontal + + + + + + + + + + + 128 + 32 + + + + + 16777215 + 32 + + + + + 16 + + + + The appearance of the Text Browser with the current settings + + + Preview + + + + + + + + 0 + 64 + + + + false + + + false + + + QTextEdit::NoWrap + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><meta charset="utf-8" /><style type="text/css"> +p, li { white-space: pre-wrap; } +hr { height: 1px; border-width: 0; } +li.unchecked::marker { content: "\2610"; } +li.checked::marker { content: "\2612"; } +</style></head><body style=" font-family:'Noto Sans'; font-size:13pt; font-weight:400; font-style:normal;"> +<p align="center" style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p></body></html> + + + true + + + + + + + + + + + Charts + + + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 16 + 32 + + + + + + + + + 0 + 0 + + + + + 160 + 32 + + + + + 160 + 32 + + + + + 13 + + + + + Default (Light) + + + + + Dark + + + + + Sand + + + + + Cerulean + + + + + + + + Qt::Horizontal + + + + 569 + 32 + + + + + + + + + 128 + 32 + + + + + 16777215 + 32 + + + + + 16 + + + + Theme to use for the Charts + + + Theme + + + + + + + + + + + 0 + 32 + + + + + 16777215 + 32 + + + + Qt::Horizontal + + + + + + + + + + + 128 + 32 + + + + + 16777215 + 32 + + + + + 16 + + + + Preview + + + + + + + + 0 + 256 + + + + + + + + + + + + Databases + + + + + + + + + false + + + + 32 + 32 + + + + + 32 + 32 + + + + + 16 + + + + PointingHandCursor + + + Apply the current path + + + + + + + + 0 + 32 + + + + + 16777215 + 32 + + + + Path where the logs data collection database is located + + + Logs data + + + + + + + true + + + + 32 + 32 + + + + + 32 + 32 + + + + + a Arbei Berry + 16 + + + + The given path doen't exists, or doesn't point to a folder + + + + + + :/icons/icons/err.png + + + true + + + + + + + false + + + + 32 + 32 + + + + + 32 + 32 + + + + + 16 + + + + PointingHandCursor + + + Apply the current path + + + + + + + + 0 + 32 + + + + + 16777215 + 32 + + + + Path where the used files hashes database is located + + + Used files + + + + + + + true + + + + 32 + 32 + + + + + 32 + 32 + + + + + a Arbei Berry + 16 + + + + The given path doen't exists, or doesn't point to a folder + + + + + + :/icons/icons/err.png + + + true + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 8 + + + + + + + + + 0 + 32 + + + + + 16777215 + 32 + + + + Insert the base path only, file name excluded + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 16 + 178 + + + + + + + + + 128 + 32 + + + + + 16777215 + 32 + + + + + 16 + + + + Path for the database files + + + Paths + + + + + + + + 0 + 32 + + + + + 16777215 + 32 + + + + Insert the base path only, file name excluded + + + + + + + + + + + 0 + 32 + + + + + 16777215 + 32 + + + + Qt::Horizontal + + + + + + + + + + + 128 + 32 + + + + + 16777215 + 32 + + + + + 16 + + + + Backup options for the Logs Data database + + + Backups + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 16 + 28 + + + + + + + + A new backup is made when closing LogDoctor after having succesfully edited the database + + + Backup the Logs Data database and keep + + + + + + + + 100 + 32 + + + + + 16777215 + 32 + + + + copies + + + + + + + Qt::Horizontal + + + + 284 + 20 + + + + + + + + + + + Qt::Vertical + + + QSizePolicy::Expanding + + + + 668 + 285 + + + + + + + + + + + + + Logs + + + Logs related settings + + + + 8 + + + 8 + + + 8 + + + 8 + + + + + + 13 + + + + 0 + + + + Defaults + + + + + + + + + + 128 + 32 + + + + + 16777215 + 32 + + + + + 16 + + + + Remember window's position and size + + + Default WebServer + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 16 + 98 + + + + + + + + + 0 + 0 + + + + + + + + 128 + 32 + + + + + 16777215 + 32 + + + + Apache2 + + + true + + + + + + + + 128 + 32 + + + + + 16777215 + 32 + + + + Nginx + + + + + + + + 128 + 32 + + + + + 16777215 + 32 + + + + IIS + + + + + + + + + + + + + Qt::Vertical + + + QSizePolicy::Expanding + + + + 568 + 303 + + + + + + + + + Control + + + Options about the log files usage control + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 758 + 8 + + + + + + + + + 0 + 0 + + + + + 0 + 80 + + + + + 16777215 + 84 + + + + + + + + 0 + 32 + + + + + 16777215 + 32 + + + + + 16 + + + + Remember window's position and size + + + Usage control + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 16 + 32 + + + + + + + + + 0 + 0 + + + + + 0 + 32 + + + + + 16777215 + 32 + + + + + 13 + + + + Remember window's position and size + + + Hide already used files + + + + + + + + + + + 0 + 32 + + + + Qt::Horizontal + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 758 + 13 + + + + + + + + + 0 + 0 + + + + + 0 + 80 + + + + + 16777215 + 84 + + + + + 16 + + + + + + + + 0 + 32 + + + + + 16777215 + 32 + + + + Remember window's position and size + + + Size warnings + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 16 + 32 + + + + + + + + + 0 + 0 + + + + + 0 + 32 + + + + + 16777215 + 32 + + + + + 13 + + + + Remember window's position and size + + + Warn me when using files with a size exceeding: + + + true + + + + + + + + 104 + 32 + + + + + 104 + 32 + + + + + 13 + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + QAbstractSpinBox::PlusMinus + + + MiB + + + 1 + + + 1023 + + + + + + + Qt::Horizontal + + + + 228 + 20 + + + + + + + + + + + Qt::Vertical + + + QSizePolicy::Expanding + + + + 758 + 232 + + + + + + + + + Apache2 + + + Configure Apache2 specific options + + + + + + + 13 + + + + 0 + + + + Paths + + + + + + + 16777215 + 184 + + + + + + + + 0 + 32 + + + + + + + + true + + + + 32 + 32 + + + + + 32 + 32 + + + + + a Arbei Berry + 16 + + + + The given path doen't exists, or doesn't point to a folder + + + + + + :/icons/icons/err.png + + + true + + + + + + + false + + + + 32 + 32 + + + + + 32 + 32 + + + + + 16 + + + + PointingHandCursor + + + Apply the current path + + + + 22 + 22 + + + + + + + + + 0 + 32 + + + + + 16777215 + 32 + + + + Logs folder + + + + + + + + + + Qt::Vertical + + + QSizePolicy::Expanding + + + + 706 + 262 + + + + + + + + + Format + + + + + + + + + + 0 + 32 + + + + + 16777215 + 32 + + + + Logs format string + + + Format string + + + + + + + + 0 + 32 + + + + + 16777215 + 32 + + + + Insert the format string you're using + + + + + + + false + + + + 32 + 32 + + + + + 32 + 32 + + + + + 16 + + + + PointingHandCursor + + + Apply the current string + + + + 22 + 22 + + + + + + + + + 0 + 16 + + + + Qt::Horizontal + + + + + + + + 160 + 32 + + + + + 160 + 32 + + + + Generate a sample log line from the currently saved string, to check if it gets formatted correctly. +Any field not considered by LogDoctor will appear as 'DISCARDED' + + + Generate sample + + + + + + + + 16777215 + 64 + + + + Qt::ScrollBarAlwaysOff + + + Qt::ScrollBarAlwaysOn + + + true + + + + + 0 + 0 + 718 + 54 + + + + + + + + 0 + 36 + + + + + 16777215 + 36 + + + + + 13 + + + + Please check the correctness of this line. +Fields marked as 'DISCARDED' got parsed correctly, but are not considered by LogDoctor + + + + + + + + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 8 + + + + + + + + + + + Qt::Vertical + + + + 728 + 109 + + + + + + + + + 0 + 76 + + + + + 16777215 + 76 + + + + + + + Qt::Horizontal + + + + 536 + 18 + + + + + + + + + 128 + 56 + + + + + 16777215 + 56 + + + + + 20 + + + + PointingHandCursor + + + Open an help window + + + Qt::RightToLeft + + + Help + + + + :/icons/icons/help.png + + + + + 48 + 48 + + + + + + + + + + + + Warnlists + + + + + + + + + + 160 + 32 + + + + + 13 + + + + Select a log field + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 8 + 20 + + + + + + + + Use warnlist for this field + + + + + + + false + + + + 32 + 32 + + + + + 32 + 32 + + + + + 20 + + + + PointingHandCursor + + + Add the current line to the list + + + Qt::RightToLeft + + + + + + + :/icons/icons/add.png + + + + + 32 + 32 + + + + + + + + + 0 + 32 + + + + + 16777215 + 32 + + + + + + + + false + + + + 32 + 32 + + + + + 32 + 32 + + + + + 20 + + + + PointingHandCursor + + + Remove the selected item from the list + + + Qt::RightToLeft + + + + + + + :/icons/icons/rem.png + + + + + 32 + 32 + + + + + + + + QAbstractItemView::NoEditTriggers + + + + + + + false + + + + 32 + 32 + + + + + 32 + 32 + + + + + 20 + + + + PointingHandCursor + + + Move the selected item down + + + Qt::RightToLeft + + + + + + + :/icons/icons/up.png + + + + + 32 + 32 + + + + + + + + false + + + + 32 + 32 + + + + + 32 + 32 + + + + + 20 + + + + PointingHandCursor + + + Move the selected item down + + + Qt::RightToLeft + + + + + + + :/icons/icons/down.png + + + + + 32 + 32 + + + + + + + + Qt::Vertical + + + + 20 + 196 + + + + + + + + + + + + Blacklists + + + + + + + + + + 160 + 32 + + + + + 13 + + + + Select a log field + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 8 + 20 + + + + + + + + Use blacklist for this field + + + + + + + false + + + + 32 + 32 + + + + + 32 + 32 + + + + + 20 + + + + PointingHandCursor + + + Add line + + + Qt::RightToLeft + + + + + + + :/icons/icons/add.png + + + + + 32 + 32 + + + + + + + + + 0 + 32 + + + + + 16777215 + 32 + + + + + + + + false + + + + 32 + 32 + + + + + 32 + 32 + + + + + 20 + + + + PointingHandCursor + + + Remove selection + + + Qt::RightToLeft + + + + + + + :/icons/icons/rem.png + + + + + 32 + 32 + + + + + + + + QAbstractItemView::NoEditTriggers + + + + + + + false + + + + 32 + 32 + + + + + 32 + 32 + + + + + 20 + + + + PointingHandCursor + + + Move the selected item down + + + Qt::RightToLeft + + + + + + + :/icons/icons/up.png + + + + + 32 + 32 + + + + + + + + false + + + + 32 + 32 + + + + + 32 + 32 + + + + + 20 + + + + PointingHandCursor + + + Move the selected item down + + + Qt::RightToLeft + + + + + + + :/icons/icons/down.png + + + + + 32 + 32 + + + + + + + + Qt::Vertical + + + + 20 + 196 + + + + + + + + + + + + + + + + Nginx + + + Configure Nginx specific options + + + + + + + 13 + + + + 0 + + + + Paths + + + + + + + 16777215 + 184 + + + + + + + + 0 + 32 + + + + + + + + true + + + + 32 + 32 + + + + + 32 + 32 + + + + + a Arbei Berry + 16 + + + + The given path doen't exists, or doesn't point to a folder + + + + + + :/icons/icons/err.png + + + true + + + + + + + false + + + + 32 + 32 + + + + + 32 + 32 + + + + + 16 + + + + PointingHandCursor + + + Apply the current path + + + + 22 + 22 + + + + + + + + + 0 + 32 + + + + + 16777215 + 32 + + + + Logs folder + + + + + + + + + + Qt::Vertical + + + QSizePolicy::Expanding + + + + 706 + 262 + + + + + + + + + Format + + + + + + + + + + 0 + 32 + + + + + 16777215 + 32 + + + + Logs format string + + + Format string + + + + + + + + 0 + 32 + + + + + 16777215 + 32 + + + + Insert the format string you're using + + + + + + + false + + + + 32 + 32 + + + + + 32 + 32 + + + + + 16 + + + + PointingHandCursor + + + Apply the current string + + + + 22 + 22 + + + + + + + + + 0 + 16 + + + + Qt::Horizontal + + + + + + + + 160 + 32 + + + + + 160 + 32 + + + + Generate a sample log line from the currently saved string, to check if it gets formatted correctly. +Any field not considered by LogDoctor will appear as 'DISCARDED' + + + Generate sample + + + + + + + + 16777215 + 64 + + + + Qt::ScrollBarAlwaysOff + + + Qt::ScrollBarAlwaysOn + + + true + + + + + 0 + 0 + 62 + 54 + + + + + + + + 0 + 36 + + + + + 16777215 + 36 + + + + + 13 + + + + Please check the correctness of this line. +Fields marked as 'DISCARDED' got parsed correctly, but are not considered by LogDoctor + + + + + + + + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 8 + + + + + + + + + + + Qt::Vertical + + + + 728 + 109 + + + + + + + + + 0 + 76 + + + + + 16777215 + 76 + + + + + + + Qt::Horizontal + + + + 536 + 18 + + + + + + + + + 128 + 56 + + + + + 16777215 + 56 + + + + + 20 + + + + PointingHandCursor + + + Open an help window + + + Qt::RightToLeft + + + Help + + + + :/icons/icons/help.png + + + + + 48 + 48 + + + + + + + + + + + + Warnlists + + + + + + + + + + 160 + 32 + + + + + 13 + + + + Select a log field + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 8 + 20 + + + + + + + + Use warnlist for this field + + + + + + + false + + + + 32 + 32 + + + + + 32 + 32 + + + + + 20 + + + + PointingHandCursor + + + Add line + + + Qt::RightToLeft + + + + + + + :/icons/icons/add.png + + + + + 32 + 32 + + + + + + + + + 0 + 32 + + + + + 16777215 + 32 + + + + + + + + false + + + + 32 + 32 + + + + + 32 + 32 + + + + + 20 + + + + PointingHandCursor + + + Remove selection + + + Qt::RightToLeft + + + + + + + :/icons/icons/rem.png + + + + + 32 + 32 + + + + + + + + QAbstractItemView::NoEditTriggers + + + + + + + false + + + + 32 + 32 + + + + + 32 + 32 + + + + + 20 + + + + PointingHandCursor + + + Move the selected item down + + + Qt::RightToLeft + + + + + + + :/icons/icons/up.png + + + + + 32 + 32 + + + + + + + + false + + + + 32 + 32 + + + + + 32 + 32 + + + + + 20 + + + + PointingHandCursor + + + Move the selected item down + + + Qt::RightToLeft + + + + + + + :/icons/icons/down.png + + + + + 32 + 32 + + + + + + + + Qt::Vertical + + + + 20 + 196 + + + + + + + + + + + + Blacklists + + + + + + + + + + 160 + 32 + + + + + 13 + + + + Select a log field + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 8 + 20 + + + + + + + + Use blacklist for this field + + + + + + + false + + + + 32 + 32 + + + + + 32 + 32 + + + + + 20 + + + + PointingHandCursor + + + Add line + + + Qt::RightToLeft + + + + + + + :/icons/icons/add.png + + + + + 32 + 32 + + + + + + + + + 0 + 32 + + + + + 16777215 + 32 + + + + + + + + false + + + + 32 + 32 + + + + + 32 + 32 + + + + + 20 + + + + PointingHandCursor + + + Remove selection + + + Qt::RightToLeft + + + + + + + :/icons/icons/rem.png + + + + + 32 + 32 + + + + + + + + QAbstractItemView::NoEditTriggers + + + + + + + false + + + + 32 + 32 + + + + + 32 + 32 + + + + + 20 + + + + PointingHandCursor + + + Move the selected item down + + + Qt::RightToLeft + + + + + + + :/icons/icons/up.png + + + + + 32 + 32 + + + + + + + + false + + + + 32 + 32 + + + + + 32 + 32 + + + + + 20 + + + + PointingHandCursor + + + Move the selected item down + + + Qt::RightToLeft + + + + + + + :/icons/icons/down.png + + + + + 32 + 32 + + + + + + + + Qt::Vertical + + + + 20 + 196 + + + + + + + + + + + + + + + + IIS + + + Configure IIS specific options + + + + + + + 13 + + + + 0 + + + + Paths + + + + + + + 16777215 + 184 + + + + + + + + 0 + 32 + + + + + 16777215 + 32 + + + + Logs folder + + + + + + + + 0 + 32 + + + + + + + + true + + + + 32 + 32 + + + + + 32 + 32 + + + + + a Arbei Berry + 16 + + + + The given path doen't exists, or doesn't point to a folder + + + + + + :/icons/icons/err.png + + + true + + + + + + + false + + + + 32 + 32 + + + + + 32 + 32 + + + + + 16 + + + + PointingHandCursor + + + Apply the current path + + + + 22 + 22 + + + + + + + + + + + Qt::Vertical + + + QSizePolicy::Expanding + + + + 706 + 262 + + + + + + + + + Format + + + + + + + + + + 0 + 0 + + + + + 16777215 + 48 + + + + + + + + 88 + 32 + + + + + 88 + 32 + + + + W3C + + + true + + + + + + + + 88 + 32 + + + + + 88 + 32 + + + + NCSA + + + + + + + + 88 + 32 + + + + + 88 + 32 + + + + IIS + + + + + + + + + + + 0 + 32 + + + + + 16777215 + 32 + + + + Logs format string + + + Format string + + + + + + + + 0 + 32 + + + + + 16777215 + 32 + + + + Insert the format string you're using + + + + + + + false + + + + 32 + 32 + + + + + 32 + 32 + + + + + 16 + + + + PointingHandCursor + + + Apply the current string + + + + 22 + 22 + + + + + + + + + 0 + 16 + + + + Qt::Horizontal + + + + + + + + 160 + 32 + + + + + 160 + 32 + + + + Generate a sample log line from the currently saved string, to check if it gets formatted correctly. +Any field not considered by LogDoctor will appear as 'DISCARDED' + + + Generate sample + + + + + + + + 16777215 + 64 + + + + Qt::ScrollBarAlwaysOff + + + Qt::ScrollBarAlwaysOn + + + true + + + + + 0 + 0 + 62 + 54 + + + + + + + + 0 + 36 + + + + + 16777215 + 36 + + + + + 13 + + + + Please check the correctness of this line. +Fields marked as 'DISCARDED' got parsed correctly, but are not considered by LogDoctor + + + + + + + + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 8 + + + + + + + + + + + Qt::Vertical + + + + 725 + 37 + + + + + + + + + 0 + 76 + + + + + 16777215 + 76 + + + + + + + Qt::Horizontal + + + + 536 + 18 + + + + + + + + + 128 + 56 + + + + + 16777215 + 56 + + + + + 20 + + + + PointingHandCursor + + + Open an help window + + + Qt::RightToLeft + + + Help + + + + :/icons/icons/help.png + + + + + 48 + 48 + + + + + + + + + + + + Warnlists + + + + + + + + + + 160 + 32 + + + + + 13 + + + + Select a log field + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 8 + 20 + + + + + + + + Use warnlist for this field + + + + + + + false + + + + 32 + 32 + + + + + 32 + 32 + + + + + 20 + + + + PointingHandCursor + + + Add line + + + Qt::RightToLeft + + + + + + + :/icons/icons/add.png + + + + + 32 + 32 + + + + + + + + + 0 + 32 + + + + + 16777215 + 32 + + + + + + + + false + + + + 32 + 32 + + + + + 32 + 32 + + + + + 20 + + + + PointingHandCursor + + + Remove selection + + + Qt::RightToLeft + + + + + + + :/icons/icons/rem.png + + + + + 32 + 32 + + + + + + + + QAbstractItemView::NoEditTriggers + + + + + + + false + + + + 32 + 32 + + + + + 32 + 32 + + + + + 20 + + + + PointingHandCursor + + + Move the selected item down + + + Qt::RightToLeft + + + + + + + :/icons/icons/up.png + + + + + 32 + 32 + + + + + + + + false + + + + 32 + 32 + + + + + 32 + 32 + + + + + 20 + + + + PointingHandCursor + + + Move the selected item down + + + Qt::RightToLeft + + + + + + + :/icons/icons/down.png + + + + + 32 + 32 + + + + + + + + Qt::Vertical + + + + 20 + 196 + + + + + + + + + + + + Blacklists + + + + + + + + + + 160 + 32 + + + + + 13 + + + + Select a log field + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 8 + 20 + + + + + + + + Use blacklist for this field + + + + + + + false + + + + 32 + 32 + + + + + 32 + 32 + + + + + 20 + + + + PointingHandCursor + + + Add line + + + Qt::RightToLeft + + + + + + + :/icons/icons/add.png + + + + + 32 + 32 + + + + + + + + + 0 + 32 + + + + + 16777215 + 32 + + + + + + + + false + + + + 32 + 32 + + + + + 32 + 32 + + + + + 20 + + + + PointingHandCursor + + + Remove selection + + + Qt::RightToLeft + + + + + + + :/icons/icons/rem.png + + + + + 32 + 32 + + + + + + + + QAbstractItemView::NoEditTriggers + + + + + + + false + + + + 32 + 32 + + + + + 32 + 32 + + + + + 20 + + + + PointingHandCursor + + + Move the selected item down + + + Qt::RightToLeft + + + + + + + :/icons/icons/up.png + + + + + 32 + 32 + + + + + + + + false + + + + 32 + 32 + + + + + 32 + 32 + + + + + 20 + + + + PointingHandCursor + + + Move the selected item down + + + Qt::RightToLeft + + + + + + + :/icons/icons/down.png + + + + + 32 + 32 + + + + + + + + Qt::Vertical + + + + 20 + 196 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + 0 + 924 + 26 + + + + + 11 + + + + + Language + + + + + + + + + + 10 + + + + Utilities + + + + + + + + 10 + + + + Tools + + + + + + + 10 + + + + Games + + + + + + + + + + + + true + + + true + + + + :/flags/flags/en.png:/flags/flags/en.png + + + English + + + English + + + + + true + + + + :/flags/flags/es.png:/flags/flags/es.png + + + Español + + + Español + + + + + true + + + + :/flags/flags/fr.png:/flags/flags/fr.png + + + Francais + + + Francais + + + + + true + + + + :/flags/flags/it.png:/flags/flags/it.png + + + Italiano + + + Italiano + + + + + Check updates + + + Perform a version-check + + + + + Infos + + + + + BlockNote + + + Open a block-note like window to write temporary text + + + + + CrissCross + + + Play CrissCross + + + + + Snake + + + Play Snake + + + + + + QChartView + QGraphicsView +
    QtCharts
    +
    +
    + + + + +
    diff --git a/logdoctor/modules/craphelp/craphelp.cpp b/logdoctor/modules/craphelp/craphelp.cpp new file mode 100644 index 00000000..442eb940 --- /dev/null +++ b/logdoctor/modules/craphelp/craphelp.cpp @@ -0,0 +1,116 @@ + +#include "craphelp.h" +#include "ui_craphelp.h" + +#include "modules/exceptions.h" + +#include "utilities/io.h" + + +Craphelp::Craphelp(QWidget *parent) : + QWidget(parent), + ui(new Ui::Craphelp) +{ + ui->setupUi(this); +} + +Craphelp::~Craphelp() +{ + delete ui; +} + + +const std::unordered_map Craphelp::getColorScheme( const int& scheme_id ) +{ + switch ( scheme_id ) { + case 0: + // none + return { + {"background", ""}, + {"text", ""}, + {"h1", ""}, + {"h3", ""}, + {"code", ""}, + {"link", ""} }; + case 1: + // breeze + return { + {"background", "#ffffff"}, + {"text", "#1f1c1b"}, + {"italic", "#9c9c9b"}, + {"h1", "#006e28"}, + {"h3", "#54b8ff"}, + {"code", "#644a9b"}, + {"link", "#d24f4f"} }; + + case 2: + // monokai + return { + {"background", "#272822"}, + {"text", "#d1d1cb"}, + {"italic", "#c1b864"}, + {"h1", "#a6e22e"}, + {"h3", "#9773db"}, + {"code", "#57adbc"}, + {"link", "#f92672"} }; + + case 3: + // radical + return { + {"background", "#141322"}, + {"text", "#a8c0c2"}, + {"italic", "#fda8bc"}, + {"h1", "#d5358f"}, + {"h3", "#56e8e4"}, + {"code", "#7c9c9e"}, + {"link", "#ff85a1"} }; + + default: + // wrong, shouldn't be here + throw GenericException( "Unexpected ColorScheme ID: "+std::to_string( scheme_id ), true ); // leave un-catched + } +} + + +void Craphelp::helpLogsFormat( const std::string& path, const QFont& font, const int &color_scheme_id ) +{ + std::unordered_map color_scheme = this->getColorScheme( color_scheme_id ); + std::string aux; + IOutils::readFile( path, aux ); + QString content; + if ( color_scheme_id == 0 ) { + // remove the style for the colors + while (true) { + const int start = aux.find( "background-color:" ); + if ( start < 0 || start > aux.size() ) { + break; + } + const int stop = aux.find( ";\n", start ) + 2; + aux = aux.substr( 0, start ) + aux.substr( stop ); + } + while (true) { + const int start = aux.find( "color:" ); + if ( start < 0 || start > aux.size() ) { + break; + } + const int stop = aux.find( ";\n", start ) + 2; + aux = aux.substr( 0, start ) + aux.substr( stop ); + } + content = QString::fromStdString( aux ); + + } else { + // replace with colors + content = QString::fromStdString( aux ) + .replace( "$BG$", color_scheme.at("background") ) + .replace( "$TEXT$", color_scheme.at("text") ) + .replace( "$IT$", color_scheme.at("italic") ) + .replace( "$H1$", color_scheme.at("h1") ) + .replace( "$H3$", color_scheme.at("h3") ) + .replace( "$CODE$", color_scheme.at("code") ) + .replace( "$LINK$", color_scheme.at("link") ); + } + // show the content + this->ui->helpBrowser->setText( content ); + // apply the font + this->ui->helpBrowser->setFont( font ); +} diff --git a/logdoctor/modules/craphelp/craphelp.h b/logdoctor/modules/craphelp/craphelp.h new file mode 100644 index 00000000..97b5d1b1 --- /dev/null +++ b/logdoctor/modules/craphelp/craphelp.h @@ -0,0 +1,39 @@ +#ifndef CRAPHELP_H +#define CRAPHELP_H + +#include + +#include + + +namespace Ui { + class Craphelp; +} + +//! Craphelp +/*! + Displays an help window +*/ +class Craphelp : public QWidget +{ + Q_OBJECT + +public: + explicit Craphelp( QWidget* parent=nullptr ); + ~Craphelp(); + + //! Provides help about log formats + /*! + \param path The path of the file resource to be displayed + \param font The font to be used + \param color_scheme_id The ID of the color-scheme to be used + */ + void helpLogsFormat( const std::string& path, const QFont& font, const int& color_scheme_id ); + +private: + Ui::Craphelp *ui; + + const std::unordered_map getColorScheme( const int& scheme_id ); +}; + +#endif // CRAPHELP_H diff --git a/logdoctor/modules/craphelp/craphelp.ui b/logdoctor/modules/craphelp/craphelp.ui new file mode 100644 index 00000000..bc4ce7b3 --- /dev/null +++ b/logdoctor/modules/craphelp/craphelp.ui @@ -0,0 +1,51 @@ + + + Craphelp + + + + 0 + 0 + 747 + 544 + + + + LogDoctor - Help + + + + :/logo/logo/logdoctor.svg:/logo/logo/logdoctor.svg + + + + + + + + + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><meta charset="utf-8" /><style type="text/css"> +p, li { white-space: pre-wrap; } +hr { height: 1px; border-width: 0; } +</style></head><body style=" font-family:'Noto Sans'; font-size:13pt; font-weight:400; font-style:normal;"> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p></body></html> + + + Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + false + + + + + + + + + + diff --git a/logdoctor/modules/crapinfo/crapinfo.cpp b/logdoctor/modules/crapinfo/crapinfo.cpp new file mode 100644 index 00000000..e76e5711 --- /dev/null +++ b/logdoctor/modules/crapinfo/crapinfo.cpp @@ -0,0 +1,290 @@ + +#include "crapinfo.h" +#include "ui_crapinfo.h" + +#include "modules/exceptions.h" + +#include // leave this for OSX + +#include + + +Crapinfo::Crapinfo( const int& window_theme_id, const QString& version, const QString& exec_path, const QString& conf_path, const QString& logdoc_path, QWidget *parent ) : + QWidget(parent), + ui(new Ui::Crapinfo) +{ + ui->setupUi(this); + QString stylesheet = ""; + this->getStyleSheet( stylesheet, window_theme_id ); + this->setStyleSheet( stylesheet ); + + // fonts + const QString ff = QFontDatabase::applicationFontFamilies( + QFontDatabase::addApplicationFont(":/fonts/Metropolis")).at(0); + const QFont font( ff, 13 ); + const QString ff_s = QFontDatabase::applicationFontFamilies( + QFontDatabase::addApplicationFont(":/fonts/Hack")).at(0); + const QFont font_script( ff_s, 13 ); + + // apply the fonts + this->ui->toolBox_Infos->setFont( font ); + // version + this->ui->label_Verion_Number->setText( QString(version).replace(",",".") ); + this->ui->label_Verion_Number->setFont( font_script ); + // paths + this->ui->inLine_ExecPath->setText( exec_path ); + this->ui->inLine_ExecPath->setCursorPosition( 0 ); + this->ui->inLine_ConfPath->setText( conf_path ); + this->ui->inLine_ConfPath->setCursorPosition( 0 ); + this->ui->inLine_DataPath->setText( logdoc_path ); + this->ui->inLine_DataPath->setCursorPosition( 0 ); + +} + +Crapinfo::~Crapinfo() +{ + delete ui; +} + + +void Crapinfo::getStyleSheet( QString& stylesheet, const int& theme_id ) +{ + std::unordered_map style; + switch ( theme_id ) { + case 0: + break; + case 1: + style = { + {"text", + "rgb( 248, 248, 248 )"}, + {"text_unselected", + "rgb( 192, 192, 192 )"}, + {"window_primary", + "rgb( 32, 32, 32 )"}, + {"window_secondary", + "rgb( 16, 16, 16 )"}, + {"border", + "rgb( 96, 96, 96 )"}, + {"border_hover", + "rgb( 128, 128, 128 )"}, + {"border_unselected", + "rgb( 64, 64, 64 )"}, + {"toolbox_tab_base", + "rgb( 24, 24, 24 )"}, + {"toolbox_tab_base_selected", + "rgb( 48, 48, 48 )"}, + {"scrollbar_base", + "rgb( 96, 96, 96 )"}, + {"scrollbar_handler", + "rgb( 192, 192, 192 )"}, + {"linedit_text", + "rgb( 16, 16, 16 )"}, + {"linedit_base", + "rgb( 216, 216, 216 )"}, + {"linedit_text_selection", + "rgb( 16, 16, 16 )"}, + {"linedit_base_selection", + "rgb( 192, 192, 192 )"}, + {"paths_frame_base", + "rgb( 48, 48, 48 )"}, + {"lines", + "rgb( 192, 192, 192 )"} + }; + break; + case 2: + style = { + {"text", + "rgb( 45, 0, 30 )"}, + {"text_unselected", + "rgb( 115, 30, 70 )"}, + {"window_primary", + "rgb( 255, 140, 141 )"}, + {"window_secondary", + "rgb( 255, 204, 143 )"}, + {"border", + "rgb( 195, 80, 81 )"}, + {"border_hover", + "rgb( 215, 100, 101 )"}, + {"border_unselected", + "rgb( 175, 60, 61 )"}, + {"toolbox_tab_base", + "rgb( 245, 172, 142 )"}, + {"toolbox_tab_base_selected", + "rgb( 245, 130, 131 )"}, + {"scrollbar_base", + "rgb( 145, 100, 130 )"}, + {"scrollbar_handler", + "rgb( 45, 0, 30 )"}, + {"linedit_text", + "rgb( 45, 0, 30 )"}, + {"linedit_base", + "rgb( 113, 154, 225 )"}, + {"linedit_text_selection", + "rgb( 45, 0, 30 )"}, + {"linedit_base_selection", + "rgb( 145, 100, 130 )"}, + {"paths_frame_base", + "rgb( 245, 172, 142 )"}, + {"lines", + "rgb( 195, 80, 81 )"} + }; + break; + case 3: + style = { + {"text", + "rgb( 220, 211, 187 )"}, + {"text_unselected", + "rgb( 163, 145, 99 )"}, + {"window_primary", + "rgb( 34, 58, 10 )"}, + {"window_secondary", + "rgb( 14, 28, 0 )"}, + {"border", + "rgb( 163, 145, 99 )"}, + {"border_hover", + "rgb( 193, 175, 129 )"}, + {"border_unselected", + "rgb( 133, 115, 69 )"}, + {"toolbox_tab_base", + "rgb( 24, 48, 0 )"}, + {"toolbox_tab_base_selected", + "rgb( 54, 78, 30 )"}, + {"scrollbar_base", + "rgb( 94, 118, 70 )"}, + {"scrollbar_handler", + "rgb( 174, 198, 150 )"}, + {"linedit_text", + "rgb( 4, 18, 0 )"}, + {"linedit_base", + "rgb( 193, 175, 129 )"}, + {"linedit_text_selection", + "rgb( 4, 18, 0 )"}, + {"linedit_base_selection", + "rgb( 173, 155, 109 )"}, + {"paths_frame_base", + "rgb( 54, 78, 30 )"}, + {"lines", + "rgb( 124, 148, 100 )"} + }; + break; + case 4: + style = { + {"text", + "rgb( 30, 21, 0 )"}, + {"text_unselected", + "rgb( 60, 51, 27 )"}, + {"window_primary", + "rgb( 170, 161, 137 )"}, + {"window_secondary", + "rgb( 230, 221, 197 )"}, + {"border", + "rgb( 80, 71, 47 )"}, + {"border_hover", + "rgb( 60, 51, 27 )"}, + {"border_unselected", + "rgb( 100, 91, 67 )"}, + {"toolbox_tab_base", + "rgb( 190, 181, 157 )"}, + {"toolbox_tab_base_selected", + "rgb( 150, 141, 117 )"}, + {"scrollbar_base", + "rgb( 100, 91, 67 )"}, + {"scrollbar_handler", + "rgb( 210, 201, 177 )"}, + {"linedit_text", + "rgb( 30, 21, 0 )"}, + {"linedit_base", + "rgb( 210, 201, 177 )"}, + {"linedit_text_selection", + "rgb( 30, 21, 0 )"}, + {"linedit_base_selection", + "rgb( 170, 161, 137 )"}, + {"paths_frame_base", + "rgb( 190, 181, 157 )"}, + {"lines", + "rgb( 60, 51, 27 )"} + }; + break; + default: + throw GenericException( "Unexpected WindowTheme ID: "+std::to_string(theme_id), true ); + break; + } + if ( theme_id != 0 ) { + stylesheet = + "QWidget#Crapinfo {" + " color: "+style.at("text")+";" + " background-color: "+style.at("window_secondary")+";" + "}" + "QFrame {" + " background-color: transparent;" + "}" + "QLabel {" + " color: "+style.at("text")+";" + "}" + "QPushButton:pressed {" + " background-color: "+style.at("window_primary")+";" + "}" + "QWidget#page_LogDoc," + "QWidget#page_Paths," + "QWidget#scrollAreaContents_LogDoc {" + " border: 1px solid "+style.at("border")+";" + " border-top: 0px;" + " border-radius: 4px;" + " border-top-left-radius: 0px;" + " border-top-right-radius: 0px;" + " background-color: "+style.at("window_primary")+";" + "}" + "QToolBox::tab {" + " border: 1px solid "+style.at("border_unselected")+";" + " border-radius: 4px;" + " color: "+style.at("text_unselected")+";" + " background-color: "+style.at("toolbox_tab_base")+";" + "}" + "QToolBox::tab:!selected:hover {" + " border-color: "+style.at("border_hover")+";" + " color: "+style.at("text")+";" + " background-color: "+style.at("toolbox_tab_base")+";" + "}" + "QToolBox::tab:selected {" + " border-color: "+style.at("border")+";" + " border-top: 4px solid "+style.at("border")+";" + " border-bottom: 0px;" + " border-bottom-left-radius: 0px;" + " border-bottom-right-radius: 0px;" + " color: "+style.at("text")+";" + " background-color: "+style.at("toolbox_tab_base_selected")+";" + "}" + "QScrollBar:horizontal {" + " height: 12px;" + " background-color: "+style.at("scrollbar_base")+";" + "}" + "QScrollBar::handle:horizontal {" + " min-width: 16px;" + " margin: 5px 12px 5px 12px;" + " background-color: "+style.at("scrollbar_handler")+";" + "}" + "QScrollBar::handle:horizontal:hover {" + " margin: 4px 12px 4px 12px;" + "}" + "QLineEdit {" + " border-radius: 4px;" + " color: "+style.at("linedit_text")+";" + " selection-color: "+style.at("linedit_text_selection")+";" + " background-color: "+style.at("linedit_base")+";" + " selection-background-color: "+style.at("linedit_base_selection")+";" + "}" + "QWidget#scrollAreaContents_Paths_Executable," + "QWidget#scrollAreaContents_Paths_ConfigFile," + "QWidget#scrollAreaContents_Paths_AppData {" + " border-radius: 4px;" + " background-color: "+style.at("paths_frame_base")+";" + "}" + "QFrame#gline_Version," + "QFrame#gline_StatsCount {" + " border: 1px solid "+style.at("window_secondary")+";" + " margin: 2px 0px 3px 0px;" + " background-color: "+style.at("lines")+";" + "}" + ""; + } +} diff --git a/logdoctor/modules/crapinfo/crapinfo.h b/logdoctor/modules/crapinfo/crapinfo.h new file mode 100644 index 00000000..d3ff4956 --- /dev/null +++ b/logdoctor/modules/crapinfo/crapinfo.h @@ -0,0 +1,39 @@ +#ifndef CRAPINFO_H +#define CRAPINFO_H + +#include + + +namespace Ui { + class Crapinfo; +} + +//! Crapinfo +/*! + Displays informations +*/ +class Crapinfo : public QWidget +{ + Q_OBJECT + +public: + + //! Class constructor + /*! + \param window_theme_id The ID of the theme in use on the main window + \param version The version of LogDoctor actually running + \param exec_path The path of the executable + \param conf_path The path of the configuration file + \param logdoc_path The path of the additional resources folder + \param parent The parent Widget + */ + Crapinfo( const int& window_theme_id, const QString& version, const QString& exec_path, const QString& conf_path, const QString& logdoc_path, QWidget* parent=nullptr ); + ~Crapinfo(); + +private: + Ui::Crapinfo *ui; + + void getStyleSheet( QString& stylesheet, const int& theme_id ); +}; + +#endif // CRAPINFO_H diff --git a/logdoctor/modules/crapinfo/crapinfo.ui b/logdoctor/modules/crapinfo/crapinfo.ui new file mode 100644 index 00000000..41745024 --- /dev/null +++ b/logdoctor/modules/crapinfo/crapinfo.ui @@ -0,0 +1,753 @@ + + + Crapinfo + + + + 0 + 0 + 853 + 597 + + + + LogDoctor - Infos + + + + :/logo/logo/logdoctor.svg:/logo/logo/logdoctor.svg + + + + + + + + + 0 + + + 4 + + + + + 0 + 0 + 835 + 521 + + + + LogDoctor + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + QFrame::NoFrame + + + true + + + + + 0 + 0 + 835 + 521 + + + + + + + Qt::Vertical + + + + 788 + 40 + + + + + + + + + 16777215 + 303 + + + + + + + true + + + + 280 + 280 + + + + + 280 + 280 + + + + + + + + :/logo/logo/logdoctor.svg:/logo/logo/logdoctor.svg + + + + 256 + 256 + + + + true + + + + + + + + 400 + 0 + + + + + + + + 0 + 32 + + + + + 16777215 + 32 + + + + + 16 + + + + Version + + + Qt::AlignCenter + + + + + + + + 0 + 32 + + + + + 16777215 + 32 + + + + + 13 + + + + Currently installed version of the software + + + + + + Qt::AlignHCenter|Qt::AlignTop + + + + + + + Qt::Horizontal + + + + + + + + 0 + 32 + + + + + 16777215 + 32 + + + + + 15 + + + + Repository links + + + Qt::AlignCenter + + + + + + + + 0 + 24 + + + + + 16777215 + 24 + + + + + true + + + + false + + + GitHub + + + https://github.com/elB4RTO/LogDoctor + + + false + + + Qt::AlignCenter + + + true + + + + + + + + 0 + 24 + + + + + 16777215 + 24 + + + + + true + + + + false + + + Disroot + + + https://git.disroot.org/elB4RTO/LogDoctor + + + false + + + Qt::AlignCenter + + + true + + + + + + + + 0 + 24 + + + + + 16777215 + 24 + + + + + true + + + + false + + + GitLab + + + https://gitlab.com/elB4RTO/LogDoctor + + + false + + + Qt::AlignCenter + + + true + + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Qt::Horizontal + + + + 32 + 408 + + + + + + + + Qt::Vertical + + + + 788 + 40 + + + + + + + + + + + + + + 0 + 0 + 835 + 521 + + + + Paths + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + + 0 + 28 + + + + + 16777215 + 28 + + + + + 13 + + + + The path of the executable file + + + Executable + + + + + + + + 0 + 60 + + + + + 16777215 + 60 + + + + true + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + + + 0 + 0 + 815 + 58 + + + + + + + + 0 + 24 + + + + + 16777215 + 24 + + + + false + + + + + + false + + + true + + + + + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 32 + + + + + + + + + 0 + 28 + + + + + 16777215 + 28 + + + + + 13 + + + + The path where the configuration file gets saved and searched in + + + Configuration file + + + + + + + + 0 + 60 + + + + + 16777215 + 60 + + + + true + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + + + 0 + 0 + 815 + 58 + + + + + + + + 0 + 24 + + + + + 16777215 + 24 + + + + false + + + + + + false + + + true + + + + + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 32 + + + + + + + + + 0 + 28 + + + + + 16777215 + 28 + + + + + 13 + + + + The path where the application searches for extra resources + + + Application data + + + + + + + + 0 + 60 + + + + + 16777215 + 60 + + + + true + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + + + 0 + 0 + 815 + 58 + + + + + + + + 0 + 24 + + + + + 16777215 + 24 + + + + false + + + + + + false + + + true + + + + + + + + + + + + + + Qt::Vertical + + + + 20 + 88 + + + + + + + + + + + + + + + diff --git a/logdoctor/modules/craplog/craplog.cpp b/logdoctor/modules/craplog/craplog.cpp new file mode 100644 index 00000000..a476d982 --- /dev/null +++ b/logdoctor/modules/craplog/craplog.cpp @@ -0,0 +1,1167 @@ + +#include "craplog.h" + +#include "utilities/checks.h" +#include "utilities/gzip.h" +#include "utilities/io.h" +#include "utilities/strings.h" + +#include "modules/dialogs.h" +#include "modules/exceptions.h" +#include "modules/shared.h" + +#include "modules/craplog/modules/donuts.h" +#include "modules/craplog/modules/store.h" + +#include +#include + +#include +#include +#include +#include + + +Craplog::Craplog() +{ + //////////////////////// + //// INITIALIZATION //// + //////////////////////// + // blacklists / whitelists + for ( int i=this->APACHE_ID; i<=this->IIS_ID; i++ ) { + this->warnlists.emplace( i, std::unordered_map() ); + this->blacklists.emplace( i, std::unordered_map() ); + // default data + this->warnlists.at( i ).emplace( 11, BWlist{ .used=false, .list={"DELETE","HEAD","OPTIONS","PUT","PATCH"} } ); + this->warnlists.at( i ).emplace( 12, BWlist{ .used=true, .list={"/robots.txt","/../","/./","/.env","/.htaccess","/phpmyadmin","/wp-admin","/wp-content","/wp-config.php","/config.py","/views.py","/routes.py","/setup.cgi","/cgi-bin"} } ); + this->warnlists.at( i ).emplace( 20, BWlist{ .used=false, .list={} } ); + this->warnlists.at( i ).emplace( 21, BWlist{ .used=false, .list={} } ); + this->blacklists.at( i ).emplace( 20, BWlist{ .used=true, .list={} } ); + } + + // default format strings + this->logs_format_strings.emplace( + this->APACHE_ID, "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-agent}i\"" ); + this->logs_format_strings.emplace( + this->NGINX_ID, "$remote_addr - $remote_user [$time_local] \"$request\" $status $bytes_sent \"$http_referer\" \"$http_user_agent\"" ); + this->logs_format_strings.emplace( + this->IIS_ID, "date time s-ip cs-method cs-uri-stem cs-uri-query s-port cs-username c-ip cs(User-Agent) cs(Referer) sc-status sc-substatus sc-win32-status time-taken" ); + + // initialize formats + this->logs_formats.emplace( + this->APACHE_ID, this->formatOps.processApacheFormatString( this->logs_format_strings.at(this->APACHE_ID) ) ); + this->logs_formats.emplace( + this->NGINX_ID, this->formatOps.processNginxFormatString( this->logs_format_strings.at(this->NGINX_ID) ) ); + this->logs_formats.emplace( + this->IIS_ID, this->formatOps.processIisFormatString( this->logs_format_strings.at(this->IIS_ID), 0 ) ); + + this->current_LF = this->logs_formats.at( this->APACHE_ID ); + + // apache2 access/error logs location + this->logs_paths.emplace( this->APACHE_ID, "/var/log/apache2" ); + // nginx access/error logs location + this->logs_paths.emplace( this->NGINX_ID, "/var/log/nginx" ); + // iis access/error logs location + this->logs_paths.emplace( this->IIS_ID, "C:/inetpub/logs/LogFiles" ); + + // apache2 access/error log files' names + this->logs_base_names.emplace( this->APACHE_ID, LogName{ .starts = "access.log.", + .contains = "", + .ends = "" } ); + // nginx access/error log files' names + this->logs_base_names.emplace( this->NGINX_ID, LogName{ .starts = "access.log.", + .contains = "", + .ends = "" }); + // iis access/error log files' names + this->logs_base_names.emplace( this->IIS_ID, LogName{ .starts = "", + .contains = "_ex", + .ends = ".log" }); + +} + + +////////////////// +//// SETTINGS //// +const int& Craplog::getDialogsLevel() +{ + return this->dialogs_level; +} +void Craplog::setDialogsLevel( const int& new_level ) +{ + this->dialogs_level = new_level; + this->hashOps.setDialogLevel( new_level ); +} + +const std::string& Craplog::getStatsDatabasePath() +{ + return this->db_stats_path; +} +const std::string& Craplog::getHashesDatabasePath() +{ + return this->db_hashes_path; +} + +void Craplog::setStatsDatabasePath( const std::string& path ) +{ + this->db_stats_path = path + "/collection.db"; +} +void Craplog::setHashesDatabasePath( const std::string& path ) +{ + this->db_hashes_path = path + "/hashes.db"; +} + +const long& Craplog::getWarningSize() +{ + return this->warning_size; +} + +void Craplog::setWarningSize(const long& new_size ) +{ + this->warning_size = new_size; +} + + +//////////////////// +//// WARN/BLACK //// +const bool& Craplog::isBlacklistUsed( const int& web_server_id, const int& log_field_id ) +{ + return this->blacklists.at( web_server_id ).at( log_field_id ).used; +} +const bool& Craplog::isWarnlistUsed( const int& web_server_id, const int& log_field_id ) +{ + return this->warnlists.at( web_server_id ).at( log_field_id ).used; +} + +void Craplog::setBlacklistUsed( const int& web_server_id, const int& log_field_id, const bool& used ) +{ + this->blacklists.at( web_server_id ).at( log_field_id ).used = used; +} +void Craplog::setWarnlistUsed( const int& web_server_id, const int& log_field_id, const bool& used ) +{ + this->warnlists.at( web_server_id ).at( log_field_id ).used = used; +} + +const std::vector& Craplog::getBlacklist( const int& web_server_id, const int& log_field_id ) +{ + return this->blacklists.at( web_server_id ).at( log_field_id ).list; +} +const std::vector& Craplog::getWarnlist( const int& web_server_id, const int& log_field_id ) +{ + return this->warnlists.at( web_server_id ).at( log_field_id ).list; +} + +void Craplog::setBlacklist( const int& web_server_id, const int& log_field_id, const std::vector& new_list ) +{ + this->blacklists.at( web_server_id ).at( log_field_id ).list.clear(); + for ( const std::string& item : new_list ) { + this->blacklistAdd( web_server_id, log_field_id, item ); + } +} +void Craplog::setWarnlist( const int& web_server_id, const int& log_field_id, const std::vector& new_list ) +{ + this->warnlists.at( web_server_id ).at( log_field_id ).list.clear(); + for ( const std::string& item : new_list ) { + this->warnlistAdd( web_server_id, log_field_id, item ); + } +} + +void Craplog::blacklistAdd( const int& web_server_id, const int& log_field_id, const std::string& new_item ) +{ + this->blacklists.at( web_server_id ).at( log_field_id ).list.push_back( + this->sanitizeBWitem( log_field_id, new_item ) ); +} +void Craplog::warnlistAdd( const int& web_server_id, const int& log_field_id, const std::string& new_item ) +{ + this->warnlists.at( web_server_id ).at( log_field_id ).list.push_back( + this->sanitizeBWitem( log_field_id, new_item ) ); +} + +void Craplog::blacklistRemove( const int& web_server_id, const int& log_field_id, const std::string& item ) +{ + auto& list = this->blacklists.at( web_server_id ).at( log_field_id ).list; + // move the item to the end, then pop it + for ( int i=0; iwarnlists.at( web_server_id ).at( log_field_id ).list; + // move the item to the end, then pop it + for ( int i=0; iblacklists.at( web_server_id ).at( log_field_id ).list; + for ( i=1; iwarnlists.at( web_server_id ).at( log_field_id ).list; + for ( i=1; iblacklists.at( web_server_id ).at( log_field_id ).list; + for ( i=0; iwarnlists.at( web_server_id ).at( log_field_id ).list; + for ( i=0; ilogs_format_strings.at( web_server_id ); +} + +// get the logs format +const FormatOps::LogsFormat& Craplog::getLogsFormat(const int& web_server_id ) +{ + return this->logs_formats.at( web_server_id ); +} + +// set the logs format +const bool Craplog::setApacheLogFormat( const std::string& format_string ) +{ + // apache + bool success = true; + try { + this->logs_formats.at( this->APACHE_ID ) = + this->formatOps.processApacheFormatString( format_string ); + this->logs_format_strings.at( this->APACHE_ID ) = format_string; + } catch ( LogFormatException& e ) { + success = false; + DialogSec::errInvalidLogFormatString( e.what() ); + } catch (...) { + success = false; + DialogSec::errGeneric( DialogSec::tr("An error occured while parsing the format string"), true ); + } + return success; +} +const bool Craplog::setNginxLogFormat( const std::string& format_string ) +{ + // nginx + bool success = true; + try { + this->logs_formats.at( this->NGINX_ID ) = + this->formatOps.processNginxFormatString( format_string ); + this->logs_format_strings.at( this->NGINX_ID ) = format_string; + } catch ( LogFormatException& e ) { + success = false; + DialogSec::errInvalidLogFormatString( e.what() ); + } catch (...) { + success = false; + DialogSec::errGeneric( DialogSec::tr("An error occured while parsing the format string"), true ); + } + return success; +} +const bool Craplog::setIisLogFormat( const std::string& format_string, const int& log_module ) +{ + // iis + bool success = true; + try { + this->logs_formats.at( this->IIS_ID ) = + this->formatOps.processIisFormatString( format_string, log_module ); + this->logs_format_strings.at( this->IIS_ID ) = format_string; + this->changeIisLogsBaseNames( log_module ); + } catch ( LogFormatException& e ) { + success = false; + DialogSec::errInvalidLogFormatString( e.what() ); + } catch (...) { + success = false; + DialogSec::errGeneric( DialogSec::tr("An error occured while parsing the format string"), true ); + } + return success; +} + +const QString Craplog::getLogsFormatSample( const int& web_server_id ) +{ + QString sample; + if ( web_server_id == this->APACHE_ID ) { + sample = this->formatOps.getApacheLogSample( this->logs_formats.at( web_server_id ) ); + } else if ( web_server_id == this->NGINX_ID ) { + sample = this->formatOps.getNginxLogSample( this->logs_formats.at( web_server_id ) ); + } else if ( web_server_id == this->IIS_ID ) { + sample = this->formatOps.getIisLogSample( this->logs_formats.at( web_server_id ) ); + } else { + // unexpected WebServer + throw WebServerException( "Unexpected WebServerID: " + std::to_string( web_server_id ) ); + } + return sample; +} + + +// set the current Web Server +void Craplog::setCurrentWSID( const int& web_server_id ) +{ + this->current_WS = web_server_id; + this->setCurrentLogFormat(); +} + +const int& Craplog::getCurrentWSID() +{ + return this->current_WS; +} + +// set the current access logs format +void Craplog::setCurrentLogFormat() +{ + this->current_LF = this->logs_formats.at( this->current_WS ); +} + +// get the current access logs format +const FormatOps::LogsFormat& Craplog::getCurrentLogFormat() +{ + return this->current_LF; +} + + +/////////////////// +//// LOGS PATH //// +const std::string& Craplog::getLogsPath( const int& web_server ) +{ + return this->logs_paths.at( web_server ); +} +void Craplog::setLogsPath( const int& web_server, const std::string& new_path ) +{ + this->logs_paths.at( web_server ) = new_path; +} + + +/////////////////// +//// LOGS LIST //// +// return the size of the list +const int Craplog::getLogsListSize() { + return this->logs_list.size(); +} + +// return the list. rescan if fresh is true +const std::vector& Craplog::getLogsList( const bool& fresh ) +{ + if ( fresh ) { + this->scanLogsDir(); + } + return this->logs_list; +} + + +// return the path of the file matching the given name +const Craplog::LogFile& Craplog::getLogFileItem( const QString& file_name ) +{ + for ( const Craplog::LogFile& item : this->logs_list ) { + if ( item.name == file_name ) { + return item; + } + } + // should be unreachable + throw GenericException("File item not found"); +} + + +// set a file as selected +const bool Craplog::setLogFileSelected( const QString& file_name ) +{ + bool result = false; + for ( Craplog::LogFile& item : this->logs_list ) { + if ( item.name == file_name ) { + item.selected = true; + result = true; + break; + } + } + return result; +} + + +// scan the logs path to update the log files list +void Craplog::scanLogsDir() +{ + bool successful = true; + this->logs_list.clear(); + std::string &logs_path = this->logs_paths.at( this->current_WS ); + if ( ! IOutils::isDir( logs_path ) ) { + // this directory doesn't exists + if ( IOutils::exists( logs_path ) ) { + DialogSec::errDirNotExists( QString::fromStdString( logs_path ) ); + } + successful = false; + } + if ( successful ) { + int size; + QString name; + std::string path; + // iterate over entries in the logs folder + for ( const auto& dir_entry : std::filesystem::directory_iterator{logs_path}) { + // get the attributes + path = dir_entry.path().string(); + name = QString::fromStdString( dir_entry.path().filename().string() ); + // check if it is actually a file + if ( IOutils::checkFile( path ) ) { + // it's a file, check the readability + if ( ! IOutils::checkFile( path, true ) ) { + // not readable, skip + if ( this->dialogs_level == 2 ) { + DialogSec::warnFileNotReadable( name ); + } + continue; + } + // it's readable, get the size + size = dir_entry.file_size(); + } else { + continue; + } + + std::vector content; + try { + // read 32 random lines + IOutils::randomLines( path, content, 32 ); + + } catch ( GenericException& e ) { + // failed closing gzip file pointer + DialogSec::errGeneric( e.what() ); + continue; + } + + if ( content.size() == 0 ) { + if ( this->dialogs_level == 2 ) { + DialogSec::warnEmptyFile( name ); + } + continue; + } + + LogOps::LogType log_type = this->logOps.defineFileType( + content, this->logs_formats.at( this->current_WS ) ); + content.clear(); + if ( log_type == LogOps::LogType::Failed ) { + // failed to get the log type, do not append + DialogSec::errFailedDefiningLogType( name ); + continue; + } else if ( log_type == LogOps::LogType::Discarded ) { + // skip + continue; + } + + // match only valid files names + if ( ! this->isFileNameValid( name.toStdString() ) ) { + continue; + } + + std::string hash; + try { + hash = this->hashOps.digestFile( path ); + } catch ( GenericException& e ) { + // failed to digest + DialogSec::errGeneric( e.what() ); + continue; + } + + LogFile logfile = { + .selected = false, + .used_already = this->hashOps.hasBeenUsed( hash, this->current_WS ), + .size = size, + .name = name, + .hash = hash, + .path = path + }; + // push in the list + this->logs_list.push_back( logfile ); + } + } +} + + +void Craplog::changeIisLogsBaseNames( const int& module_id ) +{ + switch ( module_id ) { + case 0: // W3C + this->logs_base_names.at( 13 ).contains = "_ex"; break; + case 1: // NCSA + this->logs_base_names.at( 13 ).contains = "_nc"; break; + case 2: // IIS + this->logs_base_names.at( 13 ).contains = "_in"; break; + + default: // shouldn't be reachable + throw GenericException( "Unexpected LogFormatModule ID: "+std::to_string( module_id ), true ); // leave un-catched + } +} +const bool Craplog::isFileNameValid( const std::string& name ) +{ + bool valid = true; + if ( this->logs_base_names.at( this->current_WS ).starts != "" ) { + if ( ! StringOps::startsWith( name, this->logs_base_names.at( this->current_WS ).starts ) ) { + return false; + } + } + if ( this->logs_base_names.at( this->current_WS ).contains != "" ) { + if ( ! StringOps::contains( + name.substr( this->logs_base_names.at( this->current_WS ).starts.size() ), + this->logs_base_names.at( this->current_WS ).contains ) ) { + return false; + } + } + if ( this->logs_base_names.at( this->current_WS ).ends != "" ) { + if ( ! StringOps::endsWith( name, this->logs_base_names.at( this->current_WS ).ends ) + && ! StringOps::endsWith( name, ".gz" ) ) { + return false; + } + } + + switch ( this->current_WS ) { + size_t start, stop; + case 11 | 12: + // further checks for apache / nginx + start = StringOps::findLast( name, ".log." )+5; + if ( start == std::string::npos ) { + valid = false; + break; + } + stop = name.size()-1; + if ( StringOps::endsWith( name, ".gz" ) ) { + stop -= 3; + } + // serach for incremental numbers + for ( int i=start; i<=stop; i++ ) { + if ( ! StringOps::isNumeric( name.at( i ) ) ) { + valid = false; + break; + } + } + break; + + case 13: + // further checks for iis + start = name.find( this->logs_base_names.at( 13 ).contains ) + 3; + if ( start == std::string::npos ) { + valid = false; + break; + } + stop = name.size()-5; // removing the finel '.log' extension + if ( StringOps::endsWith( name, ".gz" ) ) { + stop -= 3; + } + // search for date + std::string date; + for ( int i=start; i<=stop; i++ ) { + if ( ! StringOps::isNumeric( name.at( i ) ) ) { + valid = false; + break; + } + date.push_back( name.at( i ) ); + } + if ( valid ) { + // check if the file has today's date + time_t t; + struct tm *tmp; + char aux_date[7]; + time( &t ); + tmp = localtime( &t ); + // using strftime to display time + strftime( aux_date, 7, "%y%m%d", tmp ); + valid = false; + for ( int i=0; i<6; i++ ) { + if ( date.at(i) != aux_date[i] ) { + // different date, valid + valid = true; + break; + } + } + } + break; + } + return valid; +} + + +/////////////// +//// WORKK //// +void Craplog::startWorking() +{ + this->working = true; + this->parsing = true; + this->proceed = true; + + this->perf_size = 0; + this->total_size = 0; + this->parsed_size = 0; + this->warnlisted_size = 0; + this->blacklisted_size = 0; + this->total_lines = 0; + this->parsed_lines = 0; + + this->data_collection.clear(); + this->logs_lines.clear(); + this->used_files_hashes.clear(); +} +void Craplog::stopWorking() +{ + this->working = false; + this->parsing = false; +} +const bool& Craplog::isWorking() +{ + return this->working; +} +const bool& Craplog::isParsing() +{ + return this->parsing; +} +const bool& Craplog::editedDatabase() +{ + return this->db_edited; +} + +// performances +const unsigned int &Craplog::getPerfSize() +{ + return this->perf_size; +} +/*void Craplog::sumPerfSize( const unsigned& size ) +{ + this->perf_size += size; + this->parsed_size += size; +}*/ +const unsigned int &Craplog::getTotalSize() +{ + return this->total_size; +} +/*const unsigned int &Craplog::getParsedSize() +{ + return this->parsed_size; +}*/ +const unsigned int &Craplog::getParsedLines() +{ + return this->parsed_lines; +} + +void Craplog::sumWarningsSize( const unsigned int& size ) +{ + this->warnlisted_size += size; +} +void Craplog::sumBlacklistededSize( const unsigned int& size ) +{ + this->blacklisted_size += size; +} + +void Craplog::collectPerfData() +{ + this->parsed_size = this->logOps.getParsedSize(); + this->parsed_lines = this->logOps.getParsedLines(); + this->perf_size = this->parsed_size; +} + +void Craplog::clearDataCollection() +{ + this->data_collection.clear(); +} + + +void Craplog::run() +{ + this->startWorking(); + try { + if ( this->proceed ) { + // collect log lines + this->joinLogLines(); + } + if ( this->proceed ) { + // parse the log lines to fill the collection + this->parseLogLines(); + // finished parsing logs + this->parsing = false; + this->total_size = this->logOps.getTotalSize(); + this->parsed_size = this->logOps.getParsedSize(); + this->parsed_lines = this->logOps.getParsedLines(); + this->perf_size = this->parsed_size; + } + // clear log lines data + this->logs_lines.clear(); + + if ( this->proceed ) { + // store the new data + this->storeLogLines(); + } + + if ( this->proceed ) { + // succesfully updated the database + if ( this->parsed_size > 0 ) { + this->db_edited = true; + } + // insert the hashes of the used files + this->hashOps.insertUsedHashes( this->db_hashes_path, this->used_files_hashes, this->current_WS ); + } + this->used_files_hashes.clear(); + + } catch ( GenericException& e ) { + DialogSec::errGeneric( e.what() ); + this->proceed = false; + + } catch ( LogParserException& e ) { + DialogSec::errFailedParsingLogs( e.what() ); + this->proceed = false; + } + + this->stopWorking(); +} + + + +const bool Craplog::checkStuff() +{ + this->proceed = true; + this->log_files_to_use.clear(); + for ( const LogFile& file : this->logs_list ) { + + if ( ! this->proceed ) { break; } + + if ( ! file.selected ) { + // not selected, skip + continue; + } + + // check if the file has been used already + if ( file.used_already ) { + // already used + QString msg = file.name; + if ( this->dialogs_level == 2 ) { + msg += "\n" + QString::fromStdString( file.hash ); + } + const int choice = DialogSec::choiceFileAlreadyUsed( msg ); + if ( choice == 0 ) { + // choosed to abort all + this->proceed = false; + break; + } else if ( choice == 1 ) { + // choosed to discard the file and continue + continue; + } else if ( choice == 2 ) { + // choosed to ignore and use the file anyway + ; + } else { + // shouldn't be here + throw GenericException( "Unexpeced value returned: "+std::to_string(choice) ); + } + } + + // check if the file respects the warning size + if ( this->warning_size >= 0 ) { + if ( file.size > this->warning_size ) { + // exceeds the warning size + QString size_str, msg = file.name; + if ( this->dialogs_level >= 1 ) { + std::string size_sfx=" B"; + float size = (float)file.size; + if (size > 1024) { + size /= 1024; size_sfx = " KiB"; + if (size > 1024) { + size /= 1024; size_sfx = " MiB"; + } + } + size_str = std::to_string(size).substr(0,std::to_string(size).size()-3).c_str(); + msg += QString("\n\n%1:\n%2%3").arg( DialogSec::tr("Size of the file"), size_str, size_sfx.c_str() ); + if ( this->dialogs_level == 2 ) { + size = (float)this->warning_size; + if (size > 1024) { + size /= 1024; size_sfx = " KiB"; + if (size > 1024) { + size /= 1024; size_sfx = " MiB"; + } + } + size_str = std::to_string(size).substr(0,std::to_string(size).size()-3).c_str(); + msg += QString("\n\n%1:\n%2%3").arg( DialogSec::tr("Warning size parameter"), size_str, size_sfx.c_str() ); + } + } + const int choice = DialogSec::choiceFileSizeWarning( msg ); + if ( choice == 0 ) { + // choosed to abort all + this->proceed = false; + break; + } else if ( choice == 1 ) { + // choosed to discard the file and continue + continue; + } else if ( choice == 2 ) { + // choosed to ignore and use the file anyway + ; + } else { + // shouldn't be here + throw GenericException( "Unexpeced value returned: "+std::to_string(choice) ); + } + } + } + + // check if the statistics' database is fune + if ( ! CheckSec::checkCollectionDatabase( this->db_stats_path ) ) { + // checks failed, abort + this->proceed = false; + break; + } + if ( ! CheckSec::checkHashesDatabase( this->db_hashes_path ) ) { + // checks failed, abort + this->proceed = false; + break; + } + + this->log_files_to_use.push_back( file ); + } + + return this->proceed; +} + + +void Craplog::joinLogLines() +{ + std::string aux; + std::vector content; + for ( const LogFile& file : this->log_files_to_use ) { + + if ( ! this->proceed ) { break; } + + // collect lines + try { + // try reading + content.clear(); + aux = ""; + try { + // try as gzip compressed archive first + GZutils::readFile( file.path, aux ); + + } catch ( const GenericException& ) { + // failed closing file pointer + throw; + + } catch (...) { + // fallback on reading as normal file + if ( aux.size() > 0 ) { + aux = ""; + } + IOutils::readFile( file.path, aux ); + } + StringOps::splitrip( content, aux ); + if ( this->current_WS == this->IIS_ID ) { + this->logOps.cleanLines( content ); + } + + // re-catched in run() + } catch ( const GenericException& ) { + // failed closing gzip file pointer + throw GenericException( QString("%1:\n%2").arg( + DialogSec::tr("An error accured while reading the gzipped file"), + QString::fromStdString( file.path ) + ).toStdString() ); + + } catch ( const std::ios_base::failure& ) { + // failed reading as text + throw GenericException( QString("%1:\n%2").arg( + DialogSec::tr("An error accured while reading the file"), + QString::fromStdString( file.path ) + ).toStdString() ); + + } catch (...) { + // failed somehow + throw GenericException( QString("%1:\n%2").arg( + DialogSec::tr("Something failed while handling the file"), + QString::fromStdString( file.path ) + ).toStdString() ); + } + + // append to the relative list + this->logs_lines.insert( this->logs_lines.end(), content.begin(), content.end() ); + this->used_files_hashes.push_back( file.hash ); + this->total_lines += content.size(); + } + aux.clear(); + content.clear(); + this->log_files_to_use.clear(); +} + + +void Craplog::parseLogLines() +{ + if ( this-> proceed && this->logs_lines.size() > 0 ) { + this->logOps.parseLines( + this->data_collection, + this->logs_lines, + this->logs_formats.at( this->current_WS ) ); + } +} + + + +void Craplog::storeLogLines() +{ + QString db_path = QString::fromStdString( this->db_stats_path ); + QString db_name = QString::fromStdString( this->db_stats_path.substr( this->db_stats_path.find_last_of( '/' ) + 1 ) ); + + QSqlDatabase db; + if ( QSqlDatabase::contains("qt_sql_default_connection") ) { + db = QSqlDatabase::database("qt_sql_default_connection"); + } else { + db = QSqlDatabase::addDatabase("QSQLITE"); + } + db.setDatabaseName( db_path ); + + if ( ! db.open() ) { + // error opening database + this->proceed = false; + QString err_msg = ""; + if ( this->dialogs_level == 2 ) { + err_msg = db.lastError().text(); + } + DialogSec::errDatabaseFailedOpening( db_name, err_msg ); + + } else { + + bool successful; + try { + // ACID transaction + if ( ! db.transaction() ) { + // error opening database + this->proceed = false; + QString stmt_msg="", err_msg = ""; + if ( this->dialogs_level > 0 ) { + stmt_msg = "db.transaction()"; + if ( this->dialogs_level == 2 ) { + err_msg = db.lastError().text(); + } + } + DialogSec::errDatabaseFailedExecuting( db_name, stmt_msg, err_msg ); + } + + if ( this->proceed && this->data_collection.size() > 0 ) { + successful = StoreOps::storeData( db, *this, this->data_collection ); + this->proceed = successful; + } + + if ( this->proceed ) { + // commit the transaction + if ( ! db.commit() ) { + // error opening database + this->proceed = false; + QString stmt_msg="", err_msg = ""; + if ( this->dialogs_level > 0 ) { + stmt_msg = "db.commit()"; + if ( this->dialogs_level == 2 ) { + err_msg= db.lastError().text(); + } + } + DialogSec::errDatabaseFailedExecuting( db_name, stmt_msg, err_msg ); + } + } + if ( ! proceed ) { + // rollback + throw (std::exception()); + } + + } catch (...) { + // wrongthing w3nt some.,. + this->proceed = false; + bool err_shown = false; + // rollback the transaction + if ( ! db.rollback() ) { + // error rolling back commits + QString stmt_msg="", err_msg = ""; + if ( this->dialogs_level > 0 ) { + stmt_msg = "db.rollback()"; + if ( this->dialogs_level == 2 ) { + err_msg = db.lastError().text(); + } + } + DialogSec::errDatabaseFailedExecuting( db_name, stmt_msg, err_msg ); + err_shown = true; + } + if ( ! err_shown ) { + // show a message + DialogSec::errGeneric( QString("%1\n\n%2").arg( + DialogSec::tr("An error occured while working on the database"), + DialogSec::tr("Aborting") ) ); + } + } + + db.close(); + } + +} + + +const QString Craplog::printableSize( const unsigned int& bytes ) +{ + std::string size_str, size_sfx=" B"; + float size = (float)bytes; + if (size > 1024) { + size /= 1024; + size_sfx = " KiB"; + if (size > 1024) { + size /= 1024; + size_sfx = " MiB"; + } + } + // cut decimals depending on how big the floor is + size_str = std::to_string( size ); + size_t cut_index = size_str.find('.'); + if ( cut_index == std::string::npos ) { + cut_index = size_str.find(','); + if ( cut_index == std::string::npos ) { + cut_index = 0; + } + } + if ( cut_index != 0 ) { + cut_index ++; + } + short n_decimals = 3; + if ( size >= 100 ) { + n_decimals = 2; + if ( size >= 1000 ) { + n_decimals = 1; + if ( size >= 10000 ) { + n_decimals = 0; + cut_index --; + } + } + } + if ( cut_index > 0 ) { + cut_index += n_decimals; + if ( cut_index > size_str.size()-1 ) { + cut_index = size_str.size()-1; + } + } + return QString::fromStdString( size_str.substr(0, cut_index ) + size_sfx ); +} + + +void Craplog::makeChart( const QChart::ChartTheme& theme, const std::unordered_map& fonts, QChartView* size_chart ) +{ + const QString + size_chart_name = TR::tr("Logs Size Breakdown"), + ignored_slice_name = TR::tr("Ignored"), + parsed_slice_name = TR::tr("Parsed"), + warning_slice_name = TR::tr("Warnings"), + blacklisted_slice_name = TR::tr("Blacklisted"); + + // logs size donut chart + QPieSeries *parsedSize_donut = new QPieSeries(); + parsedSize_donut->setName( this->printableSize( this->parsed_size ) ); + parsedSize_donut->append( + "P@" + parsed_slice_name + "@" + this->printableSize( this->parsed_size-this->warnlisted_size ), + this->parsed_size-this->warnlisted_size ); + parsedSize_donut->append( + "W@" + warning_slice_name + "@" + this->printableSize( this->warnlisted_size ), + this->warnlisted_size ); + parsedSize_donut->append( + "B@" + blacklisted_slice_name + "@" + this->printableSize( this->blacklisted_size ), + this->blacklisted_size ); + + // logs size donut chart + QPieSeries *ignoredSize_donut = new QPieSeries(); + ignoredSize_donut->setName( this->printableSize( this->total_size-this->parsed_size-this->blacklisted_size ) ); + ignoredSize_donut->append( + "I@#" + ignored_slice_name + "@#" + this->printableSize( this->total_size-this->parsed_size-this->blacklisted_size ), + this->total_size-this->parsed_size-this->blacklisted_size ); + ignoredSize_donut->setLabelsVisible( false ); + + DonutBreakdown *sizeBreakdown = new DonutBreakdown(); + sizeBreakdown->setTheme( theme ); + sizeBreakdown->setAnimationOptions( QChart::AllAnimations ); + sizeBreakdown->setTitle( size_chart_name ); + sizeBreakdown->setTitleFont( fonts.at("main") ); + if ( this->proceed && this->total_size > 0 ) { + sizeBreakdown->legend()->setAlignment( Qt::AlignRight ); + sizeBreakdown->addBreakdownSeries( parsedSize_donut, Qt::GlobalColor::darkCyan, fonts.at("main_small") ); + sizeBreakdown->addBreakdownSeries( ignoredSize_donut, Qt::GlobalColor::gray, fonts.at("main_small") ); + } else { + sizeBreakdown->legend()->setVisible( false ); + sizeBreakdown->setTitle(""); + } + sizeBreakdown->legend()->setFont( fonts.at("main") ); + sizeBreakdown->legend()->markers( ignoredSize_donut ).first()->setVisible( false ); + + size_chart->setChart( sizeBreakdown ); + size_chart->setRenderHint( QPainter::Antialiasing ); +} diff --git a/logdoctor/modules/craplog/craplog.h b/logdoctor/modules/craplog/craplog.h new file mode 100644 index 00000000..4e4e8ad5 --- /dev/null +++ b/logdoctor/modules/craplog/craplog.h @@ -0,0 +1,648 @@ +#ifndef CRAPLOG_H +#define CRAPLOG_H + +#include +#include + +#include +#include + +#include "modules/craplog/modules/formats.h" +#include "modules/craplog/modules/hash.h" +#include "modules/craplog/modules/logs.h" + + +//! Craplog +/*! + Performs operations related to the logs +*/ +class Craplog +{ +public: + Craplog(); + + //! Main work method + /*! + Manages the operations which need to be done to parse the logs + when the START button is pressed + */ + void run(); + + + ///////////////// + //// DIALOGS //// + + //! Returns the Dialogs level + const int& getDialogsLevel(); + + //! Sets the new Dialogs level + void setDialogsLevel( const int& new_level ); + + /////////////////// + //// DATABASES //// + + //! Returns the path of the logs Collection database + const std::string& getStatsDatabasePath(); + + //! Returns the path of the log files' Hashes database + const std::string& getHashesDatabasePath(); + + //! Sets the new path for the logs Collection database + /*! + \param The new path of the database file + */ + void setStatsDatabasePath( const std::string& path ); + + //! Sets the new path for the log files' Hashes database + /*! + \param The new path of the database file + */ + void setHashesDatabasePath( const std::string& path ); + + + //////////////////////// + //// CURRENTLY USED //// + + //! Sets the currently used Web Server ID + /*! + \param web_server_id The new currently used Web Server + */ + void setCurrentWSID( const int& web_server_id ); + + //! Returns the currently used Web Server ID + /*! + \return The Web Server ID + */ + const int& getCurrentWSID(); + + //! Returns the currently used LogsFormat + /*! + \return The LogsFormat + \see FormatOps::LogsFormat + */ + const FormatOps::LogsFormat& getCurrentLogFormat(); + + + //////////////////// + //// LOGS PATHS //// + + //! Returns the logs' path for the given web Server + /*! + \param web_server The ID of the Web Server + \return The path of the logs' folder + */ + const std::string& getLogsPath( const int& web_server ); + + //! Sets a new path for the given Web Server to search the logs in + /*! + \param web_server The ID of the Web Server + \param new_path The new path + */ + void setLogsPath( const int& web_server, const std::string& new_path ); + + + /////////////////// + //// LOG FILES //// + + //! Structure which holds informations about a log file + struct LogFile { + bool selected; //!< Wheter the file has been selected to be use or not + bool used_already; //!< Wheter the file has been used already or not + int size; //!< The size of the file + QString name; //!< The name of the file, to be displayed in the list + std::string hash; //!< The sha256 hash of the content + std::string path; //!< The path of the file, including the file name + }; + + //! Checks if a file name respects the relative criterions + /*! + \param name The name of the file + \return Wheter it does respect the criterions or not + \see LogName + */ + const bool isFileNameValid( const std::string& name ); + + + /////////////////// + //// LOGS LIST //// + + //! Returns the list of log files + /*! + \param fresh Whether to refresh the list before to return it or not + \return The list of log files + \see LogFile, logs_list, scanLogsDir() + */ + const std::vector& getLogsList( const bool& fresh=false ); + + //! Returns the amount of log files in the list + /*! + \return The number of files actually in the list + \see logs_list + */ + const int getLogsListSize(); + + //! Returns the LogFile instance of the given file + /*! + \param file_name The name of the file + \return The LogFile instance + \throw GenericException + \see LogFile, logs_list + */ + const LogFile& getLogFileItem( const QString& file_name ); + + /*const std::string& getLogFilePath( const QString& file_name );*/ + + //! Sets a file in the list as selected + /*! + \param file_name The name of the file + \return Wheter the given file name has been found in the list + \see LogFile, logs_list + */ + const bool setLogFileSelected( const QString& file_name ); + + + ////////////////////// + //// LOGS FORMATS //// + + //! Sets the Apache2 LogsFormat from the given format string + /*! + \param format_string The logs format string + \return Whether the process was successful or not + \see FormatOps, FormatOps::LogsFormat, FormatOps::processApacheFormatString() + */ + const bool setApacheLogFormat( const std::string& format_string ); + + //! Sets the Nginx LogsFormat from the given format string + /*! + \param format_string The logs format string + \return Whether the process was successful or not + \see FormatOps, FormatOps::LogsFormat, FormatOps::processNginxFormatString() + */ + const bool setNginxLogFormat( const std::string& format_string ); + + //! Sets the IIS LogsFormat from the given format string + /*! + \param format_string The logs format string + \param log_module The IIS logs module to be used to parse the format string + \return Whether the process was successful or not + \see FormatOps, FormatOps::LogsFormat, FormatOps::processIisFormatString() + */ + const bool setIisLogFormat( const std::string& format_string, const int& log_module ); + + //! Returns the logs format string for the given Web Server + /*! + \param web_server_id ID of the Web Server + \return The format string + \see FormatOps::LogsFormat + */ + const std::string& getLogsFormatString( const int& web_server_id ); + + //! Returns the LogsFormat currently set for the given Web Server + /*! + \param web_server_id ID of the Web Server + \return The LogsFormat instance + \see FormatOps::LogsFormat + */ + const FormatOps::LogsFormat& getLogsFormat( const int& web_server_id ); + + //! Returns a sample log line for the given Web Server using the relative LogsFormat + /*! + \param web_server_id ID of the Web Server + \return The sample of a log line + \throw WebServerException + \see FormatOps::getApacheLogSample(), FormatOps::getNginxLogSample(), FormatOps::getIisLogSample() + */ + const QString getLogsFormatSample( const int& web_server_id ); + + + + ////////////////////// + //// WARNING SIZE //// + + //! Returns the currently set warning size for the log files + const long& getWarningSize(); + + //! Sets the new warning size for the log files + void setWarningSize( const long& new_size ); + + + //////////////////// + //// OPERATIONS //// + + // logs usage control + HashOps hashOps; + + // operations on logs + LogOps logOps; + + ////////////////////////////// + //// BLACKLIST / WARNLIST //// + + //! Structure to hold the items of a blacklist/warnlist + struct BWlist { + bool used; //!< Whether the list is set to be used or not + std::vector list; //!< The list of items + }; + + //! Returns whether the relative blacklist is set to be used or not + /*! + \param web_server_id The ID of the Web Server + \param log_field_id The ID of the log field + \return Whether the list is used or not + \see BWlist + */ + const bool& isBlacklistUsed( const int& web_server_id, const int& log_field_id ); + + //! Returns whether the relative warnlist is set to be used or not + /*! + \param web_server_id The ID of the Web Server + \param log_field_id The ID of the log field + \return Whether the list is used or not + \see BWlist + */ + const bool& isWarnlistUsed( const int& web_server_id, const int& log_field_id ); + + //! Sets the relative blacklist to be used or not + /*! + \param web_server_id The ID of the Web Server + \param log_field_id The ID of the log field + \param used Whether the list is to be used or not + \see BWlist + */ + void setBlacklistUsed( const int& web_server_id, const int& log_field_id, const bool& used ); + + //! Sets the relative warnlist to be used or not + /*! + \param web_server_id The ID of the Web Server + \param log_field_id The ID of the log field + \param used Whether the list is to be used or not + \see BWlist + */ + void setWarnlistUsed( const int& web_server_id, const int& log_field_id, const bool& used ); + + //! Returns the relative items list + /*! + \param web_server_id The ID of the Web Server + \param log_field_id The ID of the log field + \return The list of items in the given blacklist + \see BWlist + */ + const std::vector& getBlacklist( const int& web_server_id, const int& log_field_id ); + + //! Returns the relative items list + /*! + \param web_server_id The ID of the Web Server + \param log_field_id The ID of the log field + \return The list of items in the givenwarnlist + \see BWlist + */ + const std::vector& getWarnlist( const int& web_server_id, const int& log_field_id ); + + //! Sets the relative items list + /*! + \param web_server_id The ID of the Web Server + \param log_field_id The ID of the log field + \param new_list The new items list + \see BWlist + */ + void setBlacklist( const int& web_server_id, const int& log_field_id, const std::vector& new_list ); + + //! Sets the relative items list + /*! + \param web_server_id The ID of the Web Server + \param log_field_id The ID of the log field + \param new_list The new items list + \see BWlist + */ + void setWarnlist( const int& web_server_id, const int& log_field_id, const std::vector& new_list ); + + //! Adds an item to the relative list + /*! + \param web_server_id The ID of the Web Server + \param log_field_id The ID of the log field + \param new_list The new items list + \see BWlist + */ + void blacklistAdd( const int& web_server_id, const int& log_field_id, const std::string& new_item ); + + //! Adds an item to the relative list + /*! + \param web_server_id The ID of the Web Server + \param log_field_id The ID of the log field + \param new_item The new item to add to the list + \see BWlist + */ + void warnlistAdd( const int& web_server_id, const int& log_field_id, const std::string& new_item ); + + //! Removes an item from the relative list + /*! + \param web_server_id The ID of the Web Server + \param log_field_id The ID of the log field + \param item The item to remove from the list + \see BWlist + */ + void blacklistRemove( const int& web_server_id, const int& log_field_id, const std::string& item ); + + //! Removes an item from the relative list + /*! + \param web_server_id The ID of the Web Server + \param log_field_id The ID of the log field + \param item The item to remove from the list + \see BWlist + */ + void warnlistRemove( const int& web_server_id, const int& log_field_id, const std::string& item ); + + //! Moves an item one position up in the relative list + /*! + \param web_server_id The ID of the Web Server + \param log_field_id The ID of the log field + \param item The item to move + \see BWlist + */ + const int blacklistMoveUp( const int& web_server_id, const int& log_field_id, const std::string& item ); + + //! Moves an item one position up in the relative list + /*! + \param web_server_id The ID of the Web Server + \param log_field_id The ID of the log field + \param item The item to move + \see BWlist + */ + const int warnlistMoveUp( const int& web_server_id, const int& log_field_id, const std::string& item ); + + //! Moves an item one position down in the relative list + /*! + \param web_server_id The ID of the Web Server + \param log_field_id The ID of the log field + \param item The item to move + \see BWlist + */ + const int blacklistMoveDown( const int& web_server_id, const int& log_field_id, const std::string& item ); + + //! Moves an item one position down in the relative list + /*! + \param web_server_id The ID of the Web Server + \param log_field_id The ID of the log field + \param item The item to move + \see BWlist + */ + const int warnlistMoveDown( const int& web_server_id, const int& log_field_id, const std::string& item ); + + + ////////////// + //// WORK //// + + //! Returns whether the database has been edited or not during the process + const bool& editedDatabase(); + + //! Various checks to be made before starting a new process + /*! + Checks the databases, the selected files and their size + \return Whether the checks has been successful or not + \throw GenericException + */ + const bool checkStuff(); + + //! Erases the data collection when a process is done + void clearDataCollection(); + + //! Returns whether the process is still running or not + const bool& isWorking(); + + //! Returns whether the process is still parsing or not + const bool& isParsing(); + + + ////////////////////// + //// PERFORMANCES //// + + //! Collects performances data from the sub-modules + /*! + \see LogOps::getParsedSize(), LogOps::getParsedLines() + */ + void collectPerfData(); + + //! Sums the given size to the warnlisted size + void sumWarningsSize( const unsigned int& size ); + + //! Sums the given size to the blacklisted size + void sumBlacklistededSize( const unsigned int& size ); + + /*void sumPerfSize( const unsigned& size );*/ + + //! Returns the size to be displayed in the main window + const unsigned int& getPerfSize(); + + //! Returns the total logs size + const unsigned int& getTotalSize(); + + //! Returns the parsed logs lines + const unsigned int& getParsedLines(); + + /*const unsigned int& getParsedSize();*/ + + //! Builds and draws the chart to be displayed in the main window + /*! + \param theme The theme to use for the Chart + \param fonts The map holding the fonts + \param size_chart The widget which will display the chart + \see DonutBreakdown + */ + void makeChart( const QChart::ChartTheme& theme, const std::unordered_map& fonts, QChartView* size_chart ); + + + +private: + + ///////////////// + //// DIALOGS //// + + // quantity of information to display throught dialogs + int dialogs_level = 2; // 0: essential, 1: usefull, 2: explanatory + + ///////////////////////// + //// WEB SERVERS IDs //// + + const unsigned int APACHE_ID = 11; //!< ID of the Apache2 Web Server + const unsigned int NGINX_ID = 12; //!< ID of the Nginx Web Server + const unsigned int IIS_ID = 13; //!< ID of the IIS Web Server + + + /////////////////// + //// DATABASES //// + + std::string db_stats_path; + std::string db_hashes_path; + + + ////////////// + //// WORK //// + + bool db_edited = false; + bool working = false; + bool parsing = false; + bool proceed = false; + + //! Sets the working state + /*! + \see isWorking() + */ + void startWorking(); + + //! Un-sets the working state + /*! + \see isWorking() + */ + void stopWorking(); + + + ////////////////////// + //// PERFORMANCES //// + + unsigned int total_lines = 0; // total number of logs lines + unsigned int parsed_lines = 0; // number of parsed logs lines + unsigned int perf_size = 0; // final size to show in the main window + unsigned int total_size = 0; // total size of the logs + unsigned int parsed_size = 0; // size of the logs which have been used + unsigned int warnlisted_size = 0; // size of the logs which caused a warning + unsigned int blacklisted_size = 0; // size of the logs which has been blacklisted + + //! Returns a printable size to be displayed in the chart, including the suffix + /*! + \param bytes The size in bytes + \return The string to be displayed + \see makeChart() + */ + const QString printableSize( const unsigned int& bytes ); + + //////////////////// + //// LOGS ITEMS //// + + // collection of logs items, each item results from a log line + /* structure + [ { log_field_id : "data" } ] + + log_field_ids + 99: warning, + 1: year, 2: month, 3: day, 4: hour, 5: minute, 6:second, + 10: request_protocol, 11: request_method, 12: request_uri, 13: request_query, 14: response_code, + 15: time_taken, 16: bytes_sent, 17: bytes_received, 18: referrer, + 20: client, 21: user_agent, 22: cookie + */ + std::vector> data_collection; + + // the selected log files to be parsed during the process + std::vector log_files_to_use; + + // the entire stack of lines which have been read from the log files + std::vector logs_lines; + + //! Reads the selected files and append the resulting lines to the list + /*! + \throw GenericException + */ + void joinLogLines(); + + //! Parses the lines in the list and stores their data in the data collection + /*! + \see LogOps::parseLines() + */ + void parseLogLines(); + + //! Stores the data collection in the database + /*! + \see StoreOps::storeData() + */ + void storeLogLines(); + + // used files + std::vector used_files_hashes; + + + ////////////////////// + //// LOGS CONTROL //// + + // warning size, in Bytes + long warning_size = (1'048'576 * 50) +1; // => 1 MiB * x + + + ////////////////////////////// + //// BLACKLIST / WARNLIST //// + + // { web_server_id : { log_field_id : BWlist } } + std::unordered_map> blacklists; + std::unordered_map> warnlists; + + //! Ssnitizes an item removing the unwanted elements + /*! + Called when adding a new item to a list + \param log_field_id The ID of the log field + \param new_item The item to be sanitized + \return The sanitized item + \throw BWlistException, GenericException + \see BWlist + */ + const std::string sanitizeBWitem( const int& log_field_id, const std::string& new_item ); + + + //////////////////// + //// WEB SERVER //// + + // currently used web server + int current_WS = this->APACHE_ID; + + std::unordered_map logs_paths; + + //! Web Server specific file names criterions + /*! + The rules to be used to decide whether a file name is valid or not + \see isFileNameValid() + */ + struct LogName { + std::string starts; //!< What should be initial part of the name + std::string contains; //!< What should be contained in the middle of the name + std::string ends; //!< What should be final part of the name + }; + + std::unordered_map logs_base_names; + + //! Changes the name criterions for IIS logs files names depending on the given module + /*! + \param module_id The ID of the module to use to set the criterions + \throw GenericException + \see LogName + */ + void changeIisLogsBaseNames( const int& module_id ); + + + /////////////////// + //// LOGS LIST //// + + // list of the log files found in the logs path + std::vector logs_list; + + //! Scans the logs directory to get a list of log files + void scanLogsDir(); + + + ///////////////////// + //// LOGS FORMAT //// + + FormatOps formatOps; + + std::unordered_map logs_format_strings; + + std::unordered_map logs_formats; + + //! Uses the current Web Server to set the relative logs format + /*! + \see LogOps::LogsFormat + */ + void setCurrentLogFormat(); + + // currently used logs format + FormatOps::LogsFormat current_LF; + +}; + +#endif // CRAPLOG_H diff --git a/logdoctor/modules/craplog/modules/datetime.cpp b/logdoctor/modules/craplog/modules/datetime.cpp new file mode 100644 index 00000000..203d32d1 --- /dev/null +++ b/logdoctor/modules/craplog/modules/datetime.cpp @@ -0,0 +1,223 @@ + +#include "datetime.h" + +#include "modules/exceptions.h" +#include "utilities/strings.h" + +#include + +#include + + +DateTimeOps::DateTimeOps() +{ + +} + + +const std::string DateTimeOps::convertMonth( const std::string& month ) +{ + std::string m; + if ( month == "Jan" ) { + m = "1"; + } else if ( month == "Feb" ) { + m = "2"; + } else if ( month == "Mar" ) { + m = "3"; + } else if ( month == "Apr" ) { + m = "4"; + } else if ( month == "May" ) { + m = "5"; + } else if ( month == "Jun" ) { + m = "6"; + } else if ( month == "Jul" ) { + m = "7"; + } else if ( month == "Aug" ) { + m = "8"; + } else if ( month == "Sep" ) { + m = "9"; + } else if ( month == "Oct" ) { + m = "10"; + } else if ( month == "Nov" ) { + m = "11"; + } else if ( month == "Dec" ) { + m = "12"; + } else { + // nope + throw DateTimeException("Unexpected month format: "+month); + } + return m; +} + + + +const std::vector DateTimeOps::processDateTime( const std::string& datetime_, const std::string& format ) +{ + std::string aux, datetime=datetime_; + std::string year="", month="", day="", hour="", minute="", second=""; + + if ( format == "ncsa" ) { + datetime = StringOps::strip( datetime, "[ ]" ); + day = datetime.substr( 0, 2 ); + month = DateTimeOps::convertMonth( datetime.substr( 3, 3 ) ); + year = datetime.substr( 7, 4 ); + hour = datetime.substr( 12, 2 ); + minute = datetime.substr( 15, 2 ); + second = datetime.substr( 18, 2 ); + + } else if ( format == "mcs" ) { + month = DateTimeOps::convertMonth( datetime.substr( 4, 3 ) ); + day = datetime.substr( 8, 2 ); + hour = datetime.substr( 11, 2 ); + minute = datetime.substr( 14, 2 ); + second = datetime.substr( 17, 2 ); + year = datetime.substr( datetime.size()-5 ); + + } else if ( format == "gmt" ) { + int start = datetime.find( ", " ) + 2; + day = datetime.substr( start, 2 ); + start += 3; + month = DateTimeOps::convertMonth( datetime.substr( start, 3 ) ); + start += 4; + year = datetime.substr( start, 4 ); + start += 5; + hour = datetime.substr( start, 2 ); + start += 3; + minute = datetime.substr( start, 2 ); + start += 3; + second = datetime.substr( start, 2 ); + + } else if ( StringOps::startsWith( format, "iso" ) ) { + year = datetime.substr( 0, 4 ); + month = datetime.substr( 5, 2 ); + day = datetime.substr( 8, 2 ); + hour = datetime.substr( 11, 2 ); + minute = datetime.substr( 14, 2 ); + second = datetime.substr( 17, 2 ); + + } else if ( StringOps::startsWith( format, "utc" ) ) { + if ( format == "utc_d" ) { + // date + year = datetime.substr( 0, 4 ); + month = datetime.substr( 5, 2 ); + day = datetime.substr( 8, 2 ); + } else { + // time + hour = datetime.substr( 0, 2 ); + minute = datetime.substr( 3, 2 ); + second = datetime.substr( 6, 2 ); + } + + } else if ( StringOps::startsWith( format, "epoch_" ) ) { + aux = format.substr( 6 ); + // convert to seconds + if ( aux == "us" ) { + // from microseconds + datetime = datetime.substr( 0, datetime.size()-6 ); + } else if ( aux == "ms" ) { + // from milliseconds + datetime = datetime.substr( 0, datetime.size()-3 ); + } else if ( aux == "s.ms" ) { + // from seconds.milliseconds + datetime = std::to_string( std::stoi( datetime ) ); + } + // convert to iso date format + QDateTime e = QDateTime::fromSecsSinceEpoch( std::stoi( datetime ) ); + datetime = e.toString( "yyyy-MM-dd HH:mm:ss" ).toStdString(); + + // parse + year = datetime.substr( 0, 4 ); + month = datetime.substr( 5, 2 ); + day = datetime.substr( 8, 2 ); + hour = datetime.substr( 11, 2 ); + minute = datetime.substr( 14, 2 ); + second = datetime.substr( 17, 2 ); + + } else { + if ( format == "YYYYMMDD" ) { + year = datetime.substr( 0, 4 ); + month = datetime.substr( 5, 2 ); + day = datetime.substr( 8, 2 ); + + } else if ( format == "MMDDYY" ) { + month = datetime.substr( 0, 2 ); + day = datetime.substr( 3, 2 ); + year = "20" + datetime.substr( 6, 2 ); + + } else if ( format == "MDYY" ) { + int aux_; + if ( datetime.at(2) == '/' ) { + month = datetime.substr( 0, 2 ); + aux_ = 3; + } else { + month = "0" + datetime.substr( 0, 1 ); + aux_ = 2; + } + if ( datetime.at(aux_+2) == '/' ) { + day = datetime.substr( aux_, 2 ); + aux_ += 3; + } else { + day = "0" + datetime.substr( aux_, 1 ); + aux_ = +2; + } + year = "20" + datetime.substr( aux_ ); + + } else if ( StringOps::startsWith( format, "year" ) ) { + year = datetime; + if ( format == "year_short" ) { + year = "20" + year; + } + + } else if ( StringOps::startsWith( format, "month" ) ) { + if ( format.size() <= 5 ) { + month = datetime; + } else { + datetime = datetime.substr( 0, 3 ); // may be the full name + month = DateTimeOps::convertMonth( datetime ); + } + + } else if ( format == "day" ) { + day = datetime; + + } else if ( StringOps::startsWith( format, "clock_" ) ) { + aux = format.substr( 6 ); + if ( aux == "24" ) { + hour = datetime.substr( 0, 2 ); + minute = datetime.substr( 3, 2 ); + second = datetime.substr( 6, 2 ); + + } else if ( aux == "12" ) { + hour = datetime.substr( 0, 2 ); + minute = datetime.substr( 3, 2 ); + second = datetime.substr( 6, 2 ); + if ( datetime.substr( 9, 2 ) == "pm" ) { + hour = std::to_string( 12 + std::stoi(hour) ); + } + + } else if ( aux == "short" ) { + hour = datetime.substr( 0, 2 ); + minute = datetime.substr( 3, 2 ); + + } else if ( aux == "meridian" ) { + if ( datetime == "pm" ) { + hour = "PM"; // to mark for final update + } + } + + } else if ( format == "hour" ) { + hour = datetime; + + } else if ( format == "minute" ) { + minute = datetime; + + } else if ( format == "second" ) { + second = datetime; + + } else { + // wronthing went some ... + throw DateTimeException("Unexpected DateTime format: "+datetime_); + } + } + + return std::vector({ year, month, day, hour, minute, second }); +} diff --git a/logdoctor/modules/craplog/modules/datetime.h b/logdoctor/modules/craplog/modules/datetime.h new file mode 100644 index 00000000..f853e55f --- /dev/null +++ b/logdoctor/modules/craplog/modules/datetime.h @@ -0,0 +1,39 @@ +#ifndef DATETIME_H +#define DATETIME_H + +#include +#include + + +//! DateTimeOps +/*! + Operations for the dates +*/ +class DateTimeOps +{ +public: + DateTimeOps(); + + //! Returns a standardized list of items representing the given date and time + /*! + \param datetime The given date and time string + \param format The format of the given string + \throw DateTimeException + \return The list of items + */ + static const std::vector processDateTime( const std::string& datetime, const std::string& format ); + +private: + + //! Converts a month from the short-name to the number + /*! + \param month The short-name of the month + \return The month number in the calendar + \throw DateTimeException + \see processDateTime + */ + static const std::string convertMonth( const std::string& month ); + +}; + +#endif // DATETIME_H diff --git a/logdoctor/modules/craplog/modules/donuts.cpp b/logdoctor/modules/craplog/modules/donuts.cpp new file mode 100644 index 00000000..6c6e5291 --- /dev/null +++ b/logdoctor/modules/craplog/modules/donuts.cpp @@ -0,0 +1,142 @@ + +#include "donuts.h" + +#include "utilities/strings.h" + + +///////////////////////// +//// DONUT BREAKDOWN //// +///////////////////////// +MainSlice::MainSlice( QPieSeries* breakdownSeries, QObject* parent ) + : QPieSlice(parent), + m_breakdownSeries(breakdownSeries) +{ + connect( this, &MainSlice::percentageChanged, this, &MainSlice::updateLabel ); +} + + +QPieSeries *MainSlice::breakdownSeries() const +{ + return this->m_breakdownSeries; +} + +void MainSlice::setName( QString name ) +{ + this->m_name = name; +} + +QString MainSlice::name() const +{ + return this->m_name; +} + + +void MainSlice::updateLabel() +{ + this->setLabel( this->m_name ); + //this->setLabel(QString("%1 %2%").arg(this->m_name).arg(this->percentage() * 100, 0, 'f', 2)); +} + + + +DonutBreakdown::DonutBreakdown( QGraphicsItem* parent, Qt::WindowFlags wFlags ) + : QChart(QChart::ChartTypeCartesian, parent, wFlags) +{ + // create the series for main center pie + this->m_mainSeries = new QPieSeries(); + this->m_mainSeries->setPieSize( 0.7 ); + QChart::addSeries( this->m_mainSeries ); +} + + + +void DonutBreakdown::addBreakdownSeries( QPieSeries* breakdownSeries, const QColor& color, const QFont& font ) +{ + // add breakdown series as a slice to center pie + MainSlice *mainSlice = new MainSlice(breakdownSeries); + mainSlice->setName(breakdownSeries->name()); + mainSlice->setValue(breakdownSeries->sum()); + m_mainSeries->append(mainSlice); + + // customize the slice + mainSlice->setBrush( color ); + mainSlice->setLabelVisible(); + mainSlice->setLabelColor( Qt::white ); + mainSlice->setLabelPosition( QPieSlice::LabelInsideHorizontal ); + mainSlice->setLabelFont( font ); + + // position and customize the breakdown series + breakdownSeries->setPieSize( 0.8 ); + breakdownSeries->setHoleSize( 0.7 ); + breakdownSeries->setLabelsVisible(); + const auto slices = breakdownSeries->slices(); + for (QPieSlice *slice : slices) { + if ( StringOps::startsWith( slice->label().toStdString(), "B" ) ) { + slice->setBrush( Qt::GlobalColor::black ); + } else if ( StringOps::startsWith( slice->label().toStdString(), "W" ) ) { + slice->setBrush( QColor( 255, 140, 0, 255 ) ); + } else if ( StringOps::startsWith( slice->label().toStdString(), "I" ) ) { + slice->setBrush( Qt::GlobalColor::transparent ); + breakdownSeries->setPieSize( 0.0 ); + } else { + slice->setBrush( color.lighter( 150 ) ); + } + slice->setLabelFont( font ); + if ( slice->value() == 0 ) { + slice->setLabelVisible( false ); + } + } + + // add the series to the chart + QChart::addSeries(breakdownSeries); + + // recalculate breakdown donut segments + this->recalculateAngles(); + + // update customize legend markers + this->updateLegendMarkers(); +} + + + +void DonutBreakdown::recalculateAngles() +{ + qreal angle = 0; + const auto slices = m_mainSeries->slices(); + for (QPieSlice *slice : slices) { + QPieSeries *breakdownSeries = qobject_cast(slice)->breakdownSeries(); + breakdownSeries->setPieStartAngle(angle); + angle += slice->percentage() * 360.0; // full pie is 360.0 + breakdownSeries->setPieEndAngle(angle); + } +} + + +void DonutBreakdown::updateLegendMarkers() +{ + // go through all markers + const auto allseries = series(); + for (QAbstractSeries *series : allseries) { + const auto markers = legend()->markers(series); + for (QLegendMarker *marker : markers) { + QPieLegendMarker *pieMarker = qobject_cast(marker); + if (series == m_mainSeries) { + // hide markers from main series + pieMarker->setVisible(false); + } else { + // modify markers from breakdown series + std::string aux = pieMarker->slice()->label().toStdString(); + if ( aux.at( aux.find('@')+1 ) != '#' ) { + pieMarker->setLabel( QString("%1 %2%") + .arg( QString::fromStdString( aux.substr( 0, aux.find('@') ) ) ) + .arg( pieMarker->slice()->percentage() * 100, 0, 'f', 2) ); + pieMarker->setFont( QFont("Arial", 8) ); + pieMarker->slice()->setLabel( QString::fromStdString( aux.substr( aux.find('@')+1 ) ) ); + } else { + pieMarker->setLabel( "" ); + pieMarker->slice()->setLabel( "" ); + } + } + } + } +} diff --git a/logdoctor/modules/craplog/modules/donuts.h b/logdoctor/modules/craplog/modules/donuts.h new file mode 100644 index 00000000..f76f629d --- /dev/null +++ b/logdoctor/modules/craplog/modules/donuts.h @@ -0,0 +1,85 @@ +#ifndef DONUTS_H +#define DONUTS_H + +#include +#include +#include + +#include + + +//! DonutBreakdon +/*! + Builds the donut chart to be displayed +*/ +class DonutBreakdown : public QChart +{ +public: + + DonutBreakdown( QGraphicsItem* parent=nullptr, Qt::WindowFlags wFlags={} ); + + //! Adds a slice to the donut + /*! + \param series The series to add + \param color The color of the slice + \param font The font to be used + \see Craplog::makeChart() + */ + void addBreakdownSeries( QPieSeries* series, const QColor& color, const QFont& font ); + + +private: + + // The main series (a.k.a. the donut) + QPieSeries* m_mainSeries; + + //! Recalculates the size of every slice in percentage over the total + void recalculateAngles(); + + //! Updates the position of the markers to be in the middle of the relative slice + void updateLegendMarkers(); +}; + + + +//! Represents a slice +/*! + A slice to be added at the donut +*/ +class MainSlice : public QPieSlice +{ + Q_OBJECT + +public: + + MainSlice( QPieSeries *breakdownSeries, QObject *parent=0 ); + + //! Returns the series + QPieSeries *breakdownSeries() const; + + //! Sets the name + /*! + \param name The name to be used + */ + void setName( QString name ); + + //! Returns the name + QString name() const; + + +public Q_SLOTS: + + //! Updates the label using the name + void updateLabel(); + + +private: + + // The series of the slice + QPieSeries* m_breakdownSeries; + + // The name of the slice + QString m_name; +}; + +#endif // DONUTS_H diff --git a/logdoctor/modules/craplog/modules/formats.cpp b/logdoctor/modules/craplog/modules/formats.cpp new file mode 100644 index 00000000..8e52fef8 --- /dev/null +++ b/logdoctor/modules/craplog/modules/formats.cpp @@ -0,0 +1,705 @@ + +#include "formats.h" + +#include "modules/exceptions.h" +#include "utilities/strings.h" + + +FormatOps::FormatOps() +{ + +} + + +// count the new lines +const int FormatOps::countNewLines( const std::string& initial, const std::string& final, const std::vector& separators ) +{ + int nl = 0; + nl += StringOps::count( initial, "\n" ); + nl += StringOps::count( final, "\n" ); + for ( const std::string& sep : separators ) { + nl += StringOps::count( sep, "\n" ); + } + return nl; +} + + +// process escapes like apache +const std::string FormatOps::parseApacheEscapes( const std::string& string , const bool& strftime ) +{ + int i = 0, + max = string.size()-1; + std::string str1 = "", + str2 = ""; + char c, cc; + // parse the first time, no control-character added + while (true) { + if ( i >= max ) { + // no need to check the final char + if ( i == max ) { + str1.push_back( string.at( i ) ); + } + break; + } + c = string.at( i ); + cc = string.at( i+1 ); + if ( c == '\\' && (cc == '\\' || cc == '"') ) { + str1.push_back( cc ); + i++; + } else if ( c == '%' && cc == '%' ) { + str1.push_back( c ); + i++; + } else { + str1.push_back( c ); + } + i++; + } + i = 0; + max = str1.size()-1; + // parse the second time, adding control-characters + while (true) { + if ( i >= max ) { + // no need to check the final char + if ( i == max ) { + str2.push_back( str1.at( i ) ); + } + break; + } + c = str1.at( i ); + cc = str1.at( i+1 ); + if ( c == '\\' ) { + // just the ones supported + if ( cc == '\\' || cc == '"' ) { + str2.push_back( cc ); + i++; + } else { + if ( strftime ) { + // when parsing for strftime, any other backslashed characters result in a backslash+character + str2.push_back( c ); + str2.push_back( cc ); + i++; + + } else { + if ( cc == 'n' ) { + str2.push_back( '\n' ); + i++; + } else if ( cc == 'r' ) { + // not supported + throw LogFormatException( "LogDoctor doesn't support the usage of the Carriage Return: '\\r'." ); + } else if ( cc == 't' ) { + str2.push_back( '\t' ); + i++; + } else { + // any other backslashed characters result in a backslash+character + str2.push_back( c ); + str2.push_back( cc ); + i++; + } + } + } + } else if ( c == '%' && strftime ) { + // strftime control-characters + if ( cc == 'n' ) { + str2.push_back( '\n' ); + i++; + } else if ( cc == 't' ) { + str2.push_back( '\t' ); + i++; + } else { + // any other characters result in a percent+character + str2.push_back( c ); + str2.push_back( cc ); + i++; + } + + } else { + str2.push_back( c ); + } + i++; + } + + return str2; +} + +// process escapes like nginx +const std::string FormatOps::parseNginxEscapes( const std::string& string ) +{ + int i = 0, + max = string.size()-1; + char c, cc; + std::string str = ""; + // parse once + while (true) { + if ( i >= max ) { + // no need to check the final char + if ( i == max ) { + str.push_back( string.at( i ) ); + } + break; + } + c = string.at( i ); + cc = string.at( i+1 ); + if ( c == '\\' ) { + // just the ones supported by nginx + if ( cc == '\\' || cc == '\'' || cc == '"' ) { + str.push_back( cc ); + i++; + } else if ( cc == 'n' ) { + str.push_back( '\n' ); + i++; + } else if ( cc == 'r' ) { + // not supported + throw LogFormatException( "LogDoctor doesn't support the usage of the Carriage Return: '\\r'." ); + } else if ( cc == 't' ) { + str.push_back( '\t' ); + i++; + } else { + // not a control-character, resulting in a backslash+character + str.push_back( c ); + str.push_back( cc ); + i++; + } + } else { + str.push_back( c ); + } + i++; + } + + return str; +} + +// find where the field ends +const size_t FormatOps::findNginxFieldEnd( const std::string& string, const int& start ) +{ + size_t stop=start; + const int max=string.size()-1; + if ( start < max ) { // if start equals max there's no need to loop + for ( int i=start; i<=max; i++ ) { + const char& c = string.at( i ); + if ( StringOps::isAlnum( c ) || c == '_' ) { + stop = i; + } else { + break; + } + } + } + return stop; +} + +// check the given format string for unwanted characters +void FormatOps::checkIisString( const std::string& string ) +{ + for ( const char& chr : string ) { + if ( !(StringOps::isAlnum( chr ) || chr == ' ' || chr == '-' || chr == ',' || chr == ':' || chr == '(' || chr == ')' || chr == '[' || chr == ']') ) { + // unwanted character + const std::string c( 1, chr ); + throw LogFormatException( "Unexpected character found: "+c ); + } + } +} + + + +const FormatOps::LogsFormat FormatOps::processApacheFormatString( const std::string& f_str ) +{ + const auto &f_map = this->APACHE_ALF; + const auto &f_map_v = this->APACHE_ALF_V; + + std::string initial="", final=""; + std::vector separators, fields; + // parse the string to convert keyargs in craplog's fields format + int n_fld=0; + size_t start, stop=0, aux, aux_start, aux_stop; + const size_t max=f_str.size()-1; + std::string aux_fld, aux_fld_v, cur_fld, cur_sep; + // find and convert any field + while (true) { + // start after the last found field + start = stop; + cur_sep = ""; + if ( cur_fld == "date_time_ncsa" ) { + // NCAS time format is always enclosed inside brackets + cur_sep += "]"; + } + while (true) { + // loop until a valid field is found (doens't matter if considered or not) + while (true) { + // hunt the next field + aux = f_str.find( '%', stop ); + // check if false positive + if ( aux == max ) { + // invalid, can't end with a single '%' + throw LogFormatException( "Invalid format string: ending with a single '%'." ); + + } else if ( aux != std::string::npos ) { + // apache only escapes a format field using the double percent sign + // backslashes are valid for control-characters only, or get reduced + // single percent-signs are considered invalid + const char c = f_str.at(aux+1); + if ( c == ',' || c == '{' || c == '<' || c == '>' ) { + // in the first case: status code(s) may follow, or may not + // in the second case: a composed format code may follow + // in the third and fourth cases: expressing a status code field + // in any case is considered valid + ; + } else if ( c == '%' ) { + // the percent sign character, will be used as separator, skip + stop = aux + 2; + continue; + } else if ( ! StringOps::isAlnum( c ) ) { + // invalid, there must be a field code, a status code or a percent sign after a '%' + const std::string chr( 1, c ); + throw LogFormatException( "Invalid format: there must be a valid format code, a status code or a percent sign character after a '%'.\nFound: '%"+chr+"'." ); + } + } + break; + } + + if ( aux == std::string::npos ) { + // no more fields, append the last section as final separator + cur_sep += f_str.substr( start ); + n_fld = -1; + break; + } + + // append the current separator + cur_sep += f_str.substr( start, aux-start ); + aux ++; + + char c = f_str.at( aux ); + // remove the per-status directives (if any) + if ( StringOps::isNumeric( c ) + || c == ',' ) { + // per-status, not important for LogDoctor + size_t aux_aux = aux+1; + while (true) { + if ( aux_aux > max ) { + break; + } + c = f_str.at( aux_aux ); + if ( StringOps::isNumeric( c ) + || c == ',' ) { + // skip these chars + aux_aux ++; + continue; + } else { + // stop + aux = aux_aux; + break; + } + } + } + + c = f_str.at( aux ); + // define if normal or composed + if ( c == '{' ) { + // composed + aux_start = aux + 1; + aux = f_str.find( '}', aux_start ); + if ( aux == std::string::npos ) { + // closer bracket not found, resulting in an invalid field + throw LogFormatException( "Invalid format code, no closing bracket found: '%{'." ); + } + aux_stop = aux + 2; + // get the varname(s) + aux_fld = f_str.substr( + aux_start, + aux - aux_start ); + // get the module + aux_fld_v = f_str.at( aux+1 ); + if ( aux_fld_v == "^" ) { + aux_stop += 2; + aux_fld_v = f_str.substr( aux+1, 3 ); + } + if ( f_map_v.find( aux_fld_v ) == f_map_v.end() ) { + // invalid module, abort + throw LogFormatException( "Invalid format code found: '%{...}"+aux_fld_v+"'." ); + } else { + // module is valud + const auto &aux_map = f_map_v.at( aux_fld_v ); + if ( aux_map.size() == 0 ) { + // module not considered and always giving out something, even if invalid varname is passed + fields.push_back( "NONE" ); + separators.push_back( this->parseApacheEscapes( cur_sep ) ); + cur_sep = ""; + + } else if ( aux_fld_v == "p" || aux_fld_v == "P" || aux_fld_v == "T" ) { + // still not considered (except 'T'), but invalid fields get used as text + // field concatenation not allowed, whole content used as varname + if ( aux_map.find( aux_fld ) != aux_map.end() ) { + // valid varname + fields.push_back( aux_map.at( aux_fld ) ); + } else { + // invalid varname, use as text + fields.push_back( "NONE" ); + cur_sep += aux_fld; + } + separators.push_back( this->parseApacheEscapes( cur_sep ) ); + cur_sep = ""; + + } else if ( aux_fld_v == "a" || aux_fld_v == "h" ) { + // client, in any case + fields.push_back( "client" ); + separators.push_back( this->parseApacheEscapes( cur_sep ) ); + cur_sep = ""; + + } else if ( aux_fld_v == "i" ) { + // always giving a result, may the varname be valid or not ('-' if invalid) + // field concatenation not allowed, the entire content is used as varname + if ( aux_map.find( aux_fld ) != aux_map.end() ) { + fields.push_back( aux_map.at( aux_fld ) ); + } else { + fields.push_back( "NONE" ); + } + separators.push_back( this->parseApacheEscapes( cur_sep ) ); + cur_sep = ""; + + } else /*if ( aux_fld_v == "t" )*/ { + // only 't' remaining + size_t aux_aux = aux_fld.find( '%' ); + if ( aux_aux == std::string::npos ) { + // no concatenation, only valid fields used, anything else used as text + // whole content used as varname + if ( aux_map.find( aux_fld ) != aux_map.end() ) { + // valid + fields.push_back( aux_map.at( aux_fld ) ); + separators.push_back( this->parseApacheEscapes( cur_sep, true ) ); + cur_sep = ""; + } else { + // invalid, append to current separator and restart hunting + cur_sep += aux_fld; + } + + } else { + // concatenation allowed, only strftime() value used as fields, everything else treated as text + size_t aux_aux_start, + aux_aux_stop = 0; + std::string aux_aux_fld; + while (true) { + // loop inside the composed field + aux_aux_start = aux_aux_stop; + while (true) { + // hunt the next field + aux_aux = aux_fld.find( '%', aux_aux_stop ); + // check if false positive + if ( aux_aux != std::string::npos ) { + // same escape rules as before, but single percent-signs are considered valid and treated as text + const char c_ = aux_fld.at( aux_aux+1 ); + if ( c_ == '%' || c_ == 'n' || c_ == 't' ) { + // control characters, will be used as separator, skip + aux_aux_stop = aux_aux + 2; + continue; + } + } + break; + } + + if ( aux_aux == std::string::npos ) { + // no more fields, append the last section as separator + cur_sep += aux_fld.substr( aux_aux_start ); + break; + } + + // append the current separator + cur_sep += aux_fld.substr( aux_aux_start, aux_aux-aux_aux_start ); + // and get the possible field + aux_aux_fld = aux_fld.substr( aux_aux, 2 ); + aux_aux_stop = aux_aux+2; + // check if the field is valid + if ( aux_map.find( aux_aux_fld ) != aux_map.end() ) { + // valid, append + cur_fld = aux_map.at( aux_aux_fld ); + fields.push_back( cur_fld ); + // append to separators list + separators.push_back( this->parseApacheEscapes( cur_sep, true ) ); + cur_sep = ""; + + } else { + // invalid, append as separator and keep hunting + cur_sep += aux_aux_fld; + } + } + } + } + // items already appended as needed, next main hunting loop round + start = stop = aux_stop; // re-starting after the previously found module + continue; + } + + } else { + // normal + aux_fld = c; + aux_stop = aux+1; + if ( aux_fld == ">" || aux_fld == "<" ) { + aux_fld += f_str.at( aux+1 ); + aux_stop ++; + } + // check if the module is valid + if ( f_map.find( aux_fld ) != f_map.end() ) { + // valid + cur_fld = f_map.at( aux_fld ); + if ( cur_fld == "date_time_ncsa" ) { + // apache's NCSA time format is always enclosed inside brackets + cur_sep += "["; + } + stop = aux_stop; + break; + } else { + // invalid format field, abort + throw LogFormatException( "Invalid format code found: '%"+aux_fld+"'." ); + } + } + } + // outside hunting loop + + if ( n_fld < 0 ) { + // final reached, stop looping + final = this->parseApacheEscapes( cur_sep ); + break; + + } else if ( n_fld == 0 ) { + // first field found, assign the separator as the initial one + initial = this->parseApacheEscapes( cur_sep ); + + } else { + // append to separators list + separators.push_back( this->parseApacheEscapes( cur_sep ) ); + } + + // append the field + fields.push_back( cur_fld ); + n_fld++; + } + + return FormatOps::LogsFormat{ + .string = f_str, + .initial = initial, + .final = final, + .separators = separators, + .fields = fields, + .new_lines = this->countNewLines( initial, final, separators ) + }; + +} +// sample +const QString FormatOps::getApacheLogSample( const LogsFormat& log_format ) +{ + QString sample = ""; + const std::unordered_map& map = this->APACHE_ALF_SAMPLES; + + // append the initial characters + sample += QString::fromStdString( log_format.initial ); + for ( int i=0; i 0 ) { + sample += map.at( log_format.fields.back() ); + } + // and the final characters + sample += QString::fromStdString( log_format.final ); + return sample; +} + + + +const FormatOps::LogsFormat FormatOps::processNginxFormatString( const std::string& f_str ) +{ + const auto& f_map = this->NGINX_ALF; + + std::string initial="", final=""; + std::vector separators, fields; + // parse the string to convert keyargs in craplog's fields format + bool finished = false; + size_t start, aux, stop=0; + const size_t max=f_str.size()-1; + std::string cur_fld, cur_sep; + // find and convert any field + while (true) { + // start after the last found field + start = stop; + // find the next field + aux = f_str.find( '$', start ); + if ( aux == std::string::npos ) { + // not found, append as final and stop searching + final = this->parseNginxEscapes( f_str.substr( start ) ); + break; + } + aux ++; + // find the end of the current field + stop = this->findNginxFieldEnd( f_str, aux ) + 1; + if ( stop == max ) { + // this is the last field, and ther's no final separator + finished = true; + } + + cur_sep = f_str.substr( start, aux-start-1 ); + cur_fld = f_str.substr( aux, stop-aux ); + + // fixes for varnames + if ( StringOps::startsWith( cur_fld, "cookie_" ) ) { + cur_fld = "cookie_"; + } else if ( StringOps::startsWith( cur_fld, "http_" ) + && cur_fld != "http_user_agent" && cur_fld != "http_referer" ) { + cur_fld = "http_"; + } else if ( StringOps::startsWith( cur_fld, "arg_" ) ) { + cur_fld = "arg_"; + } else if ( StringOps::startsWith( cur_fld, "sent_http_" ) ) { + cur_fld = "sent_http_"; + } else if ( StringOps::startsWith( cur_fld, "upstream_cookie_" ) ) { + cur_fld = "upstream_cookie_"; + } else if ( StringOps::startsWith( cur_fld, "upstream_http_" ) ) { + cur_fld = "upstream_http_"; + } + + // check if the field is valid + if ( f_map.find( cur_fld ) != f_map.end() ) { + // valid, append + if ( start == 0 ) { + initial = this->parseNginxEscapes( cur_sep ); + } else { + separators.push_back( this->parseNginxEscapes( cur_sep ) ); + } + fields.push_back( f_map.at( cur_fld ) ); + if ( finished ) { + // this was the last field + break; + } + } else { + // invalid, abort + throw LogFormatException( "Invalid format code found: '$"+cur_fld+"'." ); + } + } + + return FormatOps::LogsFormat{ + .string = f_str, + .initial = initial, + .final = final, + .separators = separators, + .fields = fields, + .new_lines = this->countNewLines( initial, final, separators ) + }; +} +// sample +const QString FormatOps::getNginxLogSample( const LogsFormat& log_format ) +{ + QString sample = ""; + const std::unordered_map& map = this->NGINX_ALF_SAMPLES; + + // append the initial characters + sample += QString::fromStdString( log_format.initial ); + for ( int i=0; i 0 ) { + sample += map.at( log_format.fields.back() ); + } + // and the final characters + sample += QString::fromStdString( log_format.final ); + return sample; +} + + + +const FormatOps::LogsFormat FormatOps::processIisFormatString( const std::string& f_str, const int& l_mod ) +{ + this->checkIisString( f_str ); + std::string initial="", final=""; + std::vector separators, fields; + switch ( l_mod ) { + case 2: + // IIS logging module + final = ","; + separators = {", ",", ",", ",", ",", ",", ",", ",", ",", ",", ",", ",", ",", ",", "}; + fields = {"client","NONE","date_time_MDYY","date_time_utc_t","NONE","NONE","NONE","time_taken_ms","bytes_received","bytes_sent","response_code","NONE","request_method","request_uri","request_query"}; + break; + case 1: + // NCSA logging module + separators = {" "," "," [","] \"","\" "," "}; + fields = {"client","NONE","NONE","date_time_ncsa","request_full","response_code","bytes_sent"}; + break; + case 0: + // W3C logging module + if ( f_str.size() > 0 ) { + bool finished = false; + size_t start, stop=0; + const size_t max=f_str.size()-1; + std::string cur_fld; + const std::string cur_sep = " "; + const auto &f_map = this->IIS_ALF; + // parse the string to convert keyargs in craplog's fields format + while (true) { + // start after the last found separator + start = stop; + // find the next separator, which is always a single whitespace, in this case + stop = f_str.find( cur_sep, start ); + if ( stop == std::string::npos ) { + // not found, this is the last field + stop = max+1; + finished = true; + } + + // set the current field + cur_fld = f_str.substr( start, stop-start ); + // step over the separator + stop++; + + // check if the module is valid + if ( f_map.find( cur_fld ) != f_map.end() ) { + // valid, append + fields.push_back( f_map.at( cur_fld ) ); + if ( ! finished ) { + separators.push_back( cur_sep ); + } else { + // this was the last field + break; + } + } else { + // invalid, abort + throw LogFormatException( "Invalid format code found: '"+cur_fld+"'." ); + } + } + } + // outside search loop, killing the switch + break; + + default: + // shouldn't be here + throw LogFormatException( "Unexpected LogModule for IIS: "+std::to_string( l_mod ) ); + } + + return FormatOps::LogsFormat{ + .string = f_str, + .initial = initial, + .final = final, + .separators = separators, + .fields = fields, + .new_lines = 0 + }; +} +// sample +const QString FormatOps::getIisLogSample( const LogsFormat& log_format ) +{ + QString sample = ""; + const std::unordered_map& map = this->IIS_ALF_SAMPLES; + + // append the initial characters + sample += QString::fromStdString( log_format.initial ); + for ( int i=0; i 0 ) { + sample += map.at( log_format.fields.back() ); + } + // and the final characters + sample += QString::fromStdString( log_format.final ); + return sample; +} diff --git a/logdoctor/modules/craplog/modules/formats.h b/logdoctor/modules/craplog/modules/formats.h new file mode 100644 index 00000000..1cb16625 --- /dev/null +++ b/logdoctor/modules/craplog/modules/formats.h @@ -0,0 +1,490 @@ +#ifndef FORMATS_H +#define FORMATS_H + +#include + +#include +#include +#include + + +//! FormatOps +/*! + Operations for the logs formats +*/ +class FormatOps +{ +public: + FormatOps(); + + //! Structure which holds informations about a log format + struct LogsFormat { + std::string string; //!< The logs format string + std::string initial; //!< The initial separator + std::string final; //!< The final separator + std::vector separators; //!< The separators in the middle + std::vector fields; //!< The fields + int new_lines; //!< The number of new lines + }; + + + //! Processes the given string to extrapolate the format for Apache2 + /*! + \param format_string The format string to process + \return The logs format + \throw LogFormatException + \see LogsFormat + */ + const LogsFormat processApacheFormatString( const std::string& format_string ); + + //! Processes the given string to extrapolate the format for Nginx + /*! + \param format_string The format string to process + \return The logs format + \throw LogFormatException + \see LogsFormat + */ + const LogsFormat processNginxFormatString( const std::string& format_string ); + + //! Processes the given string to extrapolate the format for the IIS + /*! + \param format_string The format string to process + \param log_module The ID of the log module to use + \return The logs format + \throw LogFormatException + \see LogsFormat + */ + const LogsFormat processIisFormatString( const std::string& format_string, const int& log_module ); + + + ///////////////// + //// SAMPLES //// + + //! Returns a log line sample based on the given format + /*! + \param log_format The logs format to use to build the sample + \return The sample line + \see LogsFormat, Craplog::getLogsFormatSample() + */ + const QString getApacheLogSample( const LogsFormat& log_format ); + + //! Returns a log line sample based on the given format + /*! + \param log_format The logs format to use to build the sample + \return The sample line + \see LogsFormat, Craplog::getLogsFormatSample() + */ + const QString getNginxLogSample( const LogsFormat& log_format ); + + //! Returns a log line sample based on the given format + /*! + \param log_format The logs format to use to build the sample + \return The sample line + \see LogsFormat, Craplog::getLogsFormatSample() + */ + const QString getIisLogSample( const LogsFormat& log_format ); + + +private: + + //! Parses the escapes (backslashes) and returns the resulting string + /*! + Used to obtain the same result as on Apache2 + \param string The string to parse + \param strftime Whether to apply the strftime special rule when parsing or not + \return The resulting string + \throw LogFormatException + \see processApacheFormatString() + */ + const std::string parseApacheEscapes( const std::string& string, const bool& strftime=false ); + + //! Parses the escapes (backslashes) and returns the resulting string + /*! + Used to obtain the same result as on Nginx + \param string The string to parse + \return The resulting string + \throw LogFormatException + \see processNginxFormatString() + */ + const std::string parseNginxEscapes( const std::string& string ); + + //! Conuts how many new lines are there in the format + /*! + Used to join log lines which refer to the same log line + \param initial The initial separator + \param final The final separator + \param separators The separators in the middle + \return The number of new lines in a single log line + \see LogsFormat, processApacheFormatString(), processNginxFormatString() + */ + const int countNewLines( const std::string& initial, const std::string& final, const std::vector& separators ); + + //! Finds the end of a Nginx log field + /*! + \param string The format string + \param start The starting point of the field in the string + \return The ending poin of the field in the string + \see processNginxFormatString() + */ + const size_t findNginxFieldEnd( const std::string& string, const int& start ); + + //! Checks whether the format string contains invalid characters or not + /*! + \param string The format string + \throw LogFormatException + \see processIisFormatString + */ + void checkIisString( const std::string& string ); + + + ///////////////// + //// APACHE2 //// + + //!< Access logs fields formats + const std::unordered_map APACHE_ALF = { + {"h", "client"}, + {"t", "date_time_ncsa"}, + {"r", "request_full"}, + {"H", "request_protocol"}, + {"m", "request_method"}, + {"U", "request_uri"}, + {"q", "request_query"}, + {"s", "response_code"}, + {"s", "response_code"}, + {"O", "bytes_sent"}, + {"I", "bytes_received"}, + {"T", "time_taken_s"}, + {"D", "time_taken_ms"}, + // not in use, will be discarded + {"a", "NONE"}, + {"A", "NONE"}, + {"b", "NONE"}, + {"B", "NONE"}, + {"e", "NONE"}, + {"f", "NONE"}, + {"k", "NONE"}, + {"l", "NONE"}, + {"L", "NONE"}, + {"p", "NONE"}, + {"P", "NONE"}, + {"R", "NONE"}, + {"S", "NONE"}, + {"u", "NONE"}, + {"v", "NONE"}, + {"V", "NONE"}, + {"X", "NONE"} }; + + //!< Composed access logs fields formats + const std::unordered_map> APACHE_ALF_V = { + {"a", { {"c", "client"}}}, + {"h", { {"c", "client"}}}, + {"i", { {"Cookie", "cookie"}, + {"User-agent", "user_agent"}, + {"Referer", "referer"}}}, + {"t", { /* not actually date-time fields but text, used as separators + {"\%n", "NONE"}, // NEW LINE + {"\%t", "NONE"}, // HORIZONTAL TAB + {"\%%", "NONE"},*/ + {"sec", "date_time_epoch_s"}, + {"msec", "date_time_epoch_ms"}, + {"usec", "date_time_epoch_us"}, + {"msec_frac", "NONE"}, + {"usec_frac", "NONE"}, + {"\%a", "NONE"}, + {"\%A", "NONE"}, + {"\%b", "date_time_month_str"}, + {"\%B", "date_time_month_str"}, + {"\%c", "date_time_mcs"}, + {"\%C", "NONE"}, + {"\%d", "date_time_day"}, + {"\%D", "date_time_MMDDYY"}, + {"\%e", "date_time_day"}, + {"\%F", "date_time_YYYYMMDD"}, + {"\%g", "NONE"}, + {"\%G", "NONE"}, + {"\%h", "date_time_month_str"}, + {"\%H", "date_time_hour"}, + {"\%I", "NONE"}, + {"\%j", "NONE"}, + {"\%m", "date_time_month"}, + {"\%M", "date_time_minute"}, + {"\%p", "NONE"}, + {"\%r", "date_time_clock_12"}, + {"\%R", "date_time_clock_short"}, + {"\%S", "date_time_second"}, + {"\%T", "date_time_clock_24"}, + {"\%u", "NONE"}, + {"\%U", "NONE"}, + {"\%V", "NONE"}, + {"\%w", "NONE"}, + {"\%W", "NONE"}, + {"\%x", "date_time_MMDDYY"}, + {"\%X", "date_time_clock_24"}, + {"\%y", "date_time_year_short"}, + {"\%Y", "date_time_year"}, + {"\%z", "NONE"}, + {"\%Z", "NONE"}}}, + {"T", { {"s", "time_taken_s"}, + {"ms", "time_taken_ms"}, + {"us", "time_taken_us"}}}, + // composed not in use + {"C", {}}, + {"e", {}}, + {"L", {}}, + {"n", {}}, + {"o", {}}, + {"p", {{"canonical", "NONE"}, + {"local", "NONE"}, + {"remote", "NONE"}}}, + {"P", {{"pid", "NONE"}, + {"tid", "NONE"}, + {"hextid", "NONE"}}}, + {"^ti", {}}, + {"^to", {}} }; + + // Access logs fields formats samples + const std::unordered_map APACHE_ALF_SAMPLES = { + {"NONE", "DISCARDED"}, + {"date_time_epoch_s", "946771199"}, + {"date_time_epoch_ms", "946771199000"}, + {"date_time_epoch_us", "946771199000000"}, + {"date_time_ncsa", "01/Jan/2000:23:59:59 +0000"}, + {"date_time_mcs", "Sat Jan 01 23:59:59 2000"}, + {"date_time_YYYYMMDD", "2000-01-01"}, + {"date_time_MMDDYY", "01/01/00"}, + {"date_time_year", "2000"}, + {"date_time_year_short", "00"}, + {"date_time_month_str", "January"}, + {"date_time_month", "01"}, + {"date_time_day", "01"}, + {"date_time_clock_12", "11:59:59 pm"}, + {"date_time_clock_24", "23:59:59"}, + {"date_time_clock_short", "23:59"}, + {"date_time_hour", "23"}, + {"date_time_minute", "59"}, + {"date_time_second", "59"}, + {"request_full", "GET /index.php?query=x HTTP/1.1"}, + {"request_protocol", "HTTP/1.1"}, + {"request_method", "GET"}, + {"request_uri", "/index.php"}, + {"request_query", "query=x"}, + {"response_code", "404"}, + {"bytes_sent", "1234"}, + {"bytes_received", "123"}, + {"time_taken_s", "1"}, + {"time_taken_ms", "1000"}, + {"time_taken_us", "1000000"}, + {"referer", "http://www.referrer.site"}, + {"cookie", "aCookie=abc123"}, + {"user_agent", "UserAgent/3.0 (Details stuff) Info/123"}, + {"client", "192.168.1.123"} }; + + + /////////////// + //// NGINX //// + + //!< Access logs fields formats + const std::unordered_map NGINX_ALF = { + {"remote_addr", "client"}, + {"realip_remote_addr", "client"}, + {"time_local", "date_time_ncsa"}, + {"time_iso8601", "date_time_iso"}, + {"date_gmt", "date_time_gmt"}, + {"msec", "date_time_epoch_s.ms"}, + {"request", "request_full"}, + {"server_protocol", "request_protocol"}, + {"request_method", "request_method"}, + {"request_uri", "request_uri_query"}, + {"uri", "request_uri"}, + {"query_string", "request_query"}, + {"status", "response_code"}, + {"bytes_sent", "bytes_sent"}, + {"request_length", "bytes_received"}, + {"request_time", "time_taken_s.ms"}, + {"http_referer", "referer"}, + {"cookie_", "cookie"}, + {"http_user_agent", "user_agent"}, + // not in use, will be discarded + {"ancient_browser", "NONE"}, + {"arg_", "NONE"}, + {"args", "NONE"}, + {"binary_remote_addr", "NONE"}, + {"body_bytes_sent", "NONE"}, + {"connection", "NONE"}, + {"connection_requests", "NONE"}, + {"connections_active", "NONE"}, + {"connections_reading", "NONE"}, + {"connections_waiting", "NONE"}, + {"connections_writing", "NONE"}, + {"content_length", "NONE"}, + {"content_type", "NONE"}, + {"date_local", "NONE"}, + {"document_root", "NONE"}, + {"document_uri", "NONE"}, + {"fastcgi_path_info", "NONE"}, + {"fastcgi_script_name", "NONE"}, + {"geoip_area_code", "NONE"}, + {"geoip_city", "NONE"}, + {"geoip_city_continent_code", "NONE"}, + {"geoip_city_country_code", "NONE"}, + {"geoip_city_country_code3", "NONE"}, + {"geoip_city_country_name", "NONE"}, + {"geoip_country_code", "NONE"}, + {"geoip_country_code3", "NONE"}, + {"geoip_country_name", "NONE"}, + {"geoip_dma_code", "NONE"}, + {"geoip_latitude", "NONE"}, + {"geoip_longitude", "NONE"}, + {"geoip_org", "NONE"}, + {"geoip_postal_code", "NONE"}, + {"geoip_region", "NONE"}, + {"geoip_region_name", "NONE"}, + {"gzip_ratio", "NONE"}, + {"host", "NONE"}, + {"hostname", "NONE"}, + {"http2", "NONE"}, + {"http_", "NONE"}, + {"https", "NONE"}, + {"invalid_referer", "NONE"}, + {"is_args", "NONE"}, + {"limit_rate", "NONE"}, + {"memcached_key", "NONE"}, + {"modern_browser", "NONE"}, + {"msie", "NONE"}, + {"nginx_version", "NONE"}, + {"pid", "NONE"}, + {"pipe", "NONE"}, + {"proxy_add_x_forwarded_for", "NONE"}, + {"proxy_host", "NONE"}, + {"proxy_port", "NONE"}, + {"proxy_protocol_addr", "NONE"}, + {"proxy_protocol_port", "NONE"}, + {"realip_remote_port", "NONE"}, + {"realpath_root", "NONE"}, + {"remote_port", "NONE"}, + {"remote_user", "NONE"}, + {"request_body", "NONE"}, + {"request_body_file", "NONE"}, + {"request_completion", "NONE"}, + {"request_filename", "NONE"}, + {"request_id", "NONE"}, + {"scheme", "NONE"}, + {"secure_link", "NONE"}, + {"secure_link_expires", "NONE"}, + {"sent_http_", "NONE"}, + {"server_addr", "NONE"}, + {"server_name", "NONE"}, + {"server_port", "NONE"}, + {"session_log_binary_id", "NONE"}, + {"session_log_id", "NONE"}, + {"slice_range", "NONE"}, + {"spdy", "NONE"}, + {"spdy_request_priority", "NONE"}, + {"ssl_cipher", "NONE"}, + {"ssl_client_cert", "NONE"}, + {"ssl_client_fingerprint", "NONE"}, + {"ssl_client_i_dn", "NONE"}, + {"ssl_client_raw_cert", "NONE"}, + {"ssl_client_s_dn", "NONE"}, + {"ssl_client_serial", "NONE"}, + {"ssl_client_verify", "NONE"}, + {"ssl_protocol", "NONE"}, + {"ssl_server_name", "NONE"}, + {"ssl_session_id", "NONE"}, + {"ssl_session_reused", "NONE"}, + {"tcpinfo_rtt,", "NONE"}, + {"tcpinfo_rttvar,", "NONE"}, + {"tcpinfo_snd_cwnd,", "NONE"}, + {"tcpinfo_rcv_space", "NONE"}, + {"uid_got", "NONE"}, + {"uid_reset", "NONE"}, + {"uid_set", "NONE"}, + {"upstream_addr", "NONE"}, + {"upstream_cache_status", "NONE"}, + {"upstream_connect_time", "NONE"}, + {"upstream_cookie_", "NONE"}, + {"upstream_header_time", "NONE"}, + {"upstream_http_", "NONE"}, + {"upstream_response_length", "NONE"}, + {"upstream_response_time", "NONE"}, + {"upstream_status", "NONE"} }; + + // Access logs fields formats samples + const std::unordered_map NGINX_ALF_SAMPLES = { + {"NONE", "DISCARDED"}, + {"date_time_epoch_s.ms", "946771199.000"}, + {"date_time_ncsa", "01/Jan/2000:23:59:59 +0000"}, + {"date_time_iso", "2000-01-01T23:59:59+00:00"}, + {"date_time_gmt", "Saturday, 01-Jan-2000 23:59:59 UTC"}, + {"request_full", "GET /index.php?query=x HTTP/1.1"}, + {"request_protocol", "HTTP/1.1"}, + {"request_method", "GET"}, + {"request_uri_query", "/index.php?query=x"}, + {"request_uri", "/index.php"}, + {"request_query", "query=x"}, + {"response_code", "404"}, + {"bytes_sent", "1234"}, + {"bytes_received", "123"}, + {"time_taken_s.ms", "1.000"}, + {"referer", "http://www.referrer.site"}, + {"cookie", "aCookie=abc123"}, + {"user_agent", "UserAgent/3.0 (Details stuff) Info/123"}, + {"client", "192.168.1.123"} }; + + + + ///////////// + //// IIS //// + + //!< Access logs fields formats + const std::unordered_map IIS_ALF = { + {"date", "date_time_utc_d"}, + {"time", "date_time_utc_t"}, + {"cs-version", "request_protocol"}, + {"cs-method", "request_method"}, + {"cs-uri-stem", "request_uri"}, + {"cs-uri-query", "request_query"}, + {"sc-status", "response_code"}, + {"sc-bytes", "bytes_sent"}, + {"cs-bytes", "bytes_received"}, + {"time-taken", "time_taken_ms"}, + {"cs(Referer)", "referer"}, + {"cs(Cookie)", "cookie"}, + {"cs(User-Agent)", "user_agent"}, + {"c-ip", "client"}, + // not in use, will be discarded + {"s-sitename", "NONE"}, + {"s-computername", "NONE"}, + {"s-ip", "NONE"}, + {"s-port", "NONE"}, + {"cs-username", "NONE"}, + {"cs-host", "NONE"}, + {"sc-substatus", "NONE"}, + {"sc-win32-status", "NONE"}, + {"streamid", "NONE"} }; + + // Access logs fields formats samples + const std::unordered_map IIS_ALF_SAMPLES = { + {"NONE", "DISCARDED"}, + {"date_time_ncsa", "01/Jan/2000:23:59:59 +0000"}, + {"date_time_MDYY", "1/1/00"}, + {"date_time_utc_d", "2000-01-01"}, + {"date_time_utc_t", "23:59:59"}, + {"request_full", "GET /index.php?query=x HTTP/1.1"}, + {"request_protocol", "HTTP/1.1"}, + {"request_method", "GET"}, + {"request_uri", "/index.php"}, + {"request_query", "query=x"}, + {"response_code", "404"}, + {"bytes_sent", "1234"}, + {"bytes_received", "123"}, + {"time_taken_ms", "1000"}, + {"referer", "http://www.referrer.site"}, + {"cookie", "aCookie=abc123"}, + {"user_agent", "UserAgent/3.0+(Details+stuff)+Info/123"}, + {"client", "192.168.1.123"} }; + +}; + +#endif // FORMATS_H diff --git a/logdoctor/modules/craplog/modules/hash.cpp b/logdoctor/modules/craplog/modules/hash.cpp new file mode 100644 index 00000000..0a7aaf7f --- /dev/null +++ b/logdoctor/modules/craplog/modules/hash.cpp @@ -0,0 +1,271 @@ + +#include "hash.h" + +#include "utilities/gzip.h" +#include "utilities/io.h" +#include "utilities/vectors.h" + +#include "modules/dialogs.h" +#include "modules/exceptions.h" +#include "modules/craplog/modules/sha256.h" + +#include + + +HashOps::HashOps() +{ + +} + +void HashOps::setDialogLevel( const int& new_level ) +{ + this->dialog_level = new_level; +} + + +// reads the database holding the already used hashes +bool HashOps::loadUsedHashesLists( const std::string& db_path ) +{ + bool successful = true; + const QString db_name = QString::fromStdString( db_path.substr( db_path.find_last_of( '/' ) + 1 ) ); + + QSqlDatabase db; + if ( QSqlDatabase::contains("qt_sql_default_connection") ) { + db = QSqlDatabase::database("qt_sql_default_connection"); + } else { + db = QSqlDatabase::addDatabase("QSQLITE"); + } + db.setDatabaseName( QString::fromStdString( db_path ) ); + + if ( ! db.open() ) { + // error opening database + successful = false; + QString err_msg = ""; + if ( this->dialog_level == 2 ) { + err_msg = db.lastError().text(); + } + DialogSec::errDatabaseFailedOpening( db_name, err_msg ); + + } else { + QSqlQuery query = QSqlQuery( db ); + for ( const auto& [wid,name] : this->ws_names ) { + if ( ! query.exec("SELECT hash FROM "+name+";") ) { + // error querying database + successful = false; + DialogSec::errDatabaseFailedExecuting( db_name, query.lastQuery(), query.lastError().text() ); + break; + } else { + // iterate over results + while ( query.next() ) { + std::string hash = query.value(0).toString().toStdString(); + if ( hash.size() != 64 ) { + // not a valid sha256 hash + continue; + } + this->hashes.at( wid ).push_back( hash ); + } + } + if ( ! successful ) { break; } + } + } + db.close(); + return successful; +} + + +// returns the hash +std::string HashOps::digestFile( const std::string& file_path ) +{ + std::string content; + try { + try { + // try reading as gzip compressed file + GZutils::readFile( file_path, content ); + + } catch ( const GenericException& ) { + // failed closing file pointer + throw; + + } catch (...) { + // failed as gzip, try as text file + if ( content.size() > 0 ) { + content.clear(); + } + IOutils::readFile( file_path, content ); + } + + // re-catched in craplog + } catch ( const GenericException& ) { + // failed closing gzip file pointer + throw GenericException( QString("%1:\n%2").arg( + DialogSec::tr("An error accured while reading the gzipped file"), + QString::fromStdString( file_path ) + ).toStdString() ); + + } catch ( const std::ios_base::failure& ) { + // failed reading as text + throw GenericException( QString("%1:\n%2").arg( + DialogSec::tr("An error accured while reading the file"), + QString::fromStdString( file_path ) + ).toStdString() ); + + } catch (...) { + // failed somehow + throw GenericException( QString("%1:\n%2").arg( + DialogSec::tr("Something failed while handling the file"), + QString::fromStdString( file_path ) + ).toStdString() ); + } + + SHA256 sha; + sha.update( content ); + content.clear(); + uint8_t * digest = sha.digest(); + // return the hex digest + return SHA256::toString(digest); +} + + +// check if the given hash is from a file which has been used already +bool HashOps::hasBeenUsed( const std::string &file_hash, const int& web_server_id) +{ + bool found = false; + for ( const std::string &hash : this->hashes.at( web_server_id ) ) { + if ( file_hash == hash ) { + found = true; + break; + } + } + return found; +} + + +// insert the given hash/es in the relative list +bool HashOps::insertUsedHash( QSqlQuery& query, const QString& db_name, const std::string& hash, const int& web_server_id ) +{ + bool successful = true; + try { + if( ! VecOps::contains( this->hashes.at( web_server_id ), hash ) ) { + this->hashes.at( web_server_id ).push_back( hash ); + // insert tnto the database + QString stmt = QString("INSERT INTO %1 ( hash ) VALUES ( '%2' );") + .arg( this->ws_names.at(web_server_id), QString::fromStdString(hash).replace("'","''") ); + if ( ! query.exec( stmt ) ) { + // error opening database + successful = false; + QString query_msg="", err_msg=""; + if ( this->dialog_level > 0 ) { + query_msg = "query.exec()"; + if ( this->dialog_level == 2 ) { + err_msg = query.lastError().text(); + } + } + DialogSec::errDatabaseFailedExecuting( db_name, query_msg, err_msg ); + } + }/* else { + // hash already stored + }*/ + } catch (...) { + // failed to insert the hash + successful = false; + } + query.finish(); + return successful; +} + + +bool HashOps::insertUsedHashes( const std::string& db_path, const std::vector &hashes, const int& web_server_id ) +{ + bool proceed = true; + + const QString db_name = QString::fromStdString( db_path.substr( db_path.find_last_of( '/' ) + 1 ) ); + QSqlDatabase db; + if ( QSqlDatabase::contains("qt_sql_default_connection") ) { + db = QSqlDatabase::database("qt_sql_default_connection"); + } else { + db = QSqlDatabase::addDatabase("QSQLITE"); + } + db.setDatabaseName( QString::fromStdString( db_path ) ); + + if ( ! db.open() ) { + // error opening database + proceed = false; + QString err_msg = ""; + if ( this->dialog_level == 2 ) { + err_msg = db.lastError().text(); + } + DialogSec::errDatabaseFailedOpening( db_name, err_msg ); + + } else { + QSqlQuery query = QSqlQuery( db ); + if ( ! db.transaction() ) { + // error opening database + proceed = false; + QString stmt_msg="", err_msg = ""; + if ( this->dialog_level > 0 ) { + stmt_msg = "db.transaction()"; + if ( this->dialog_level == 2 ) { + err_msg = db.lastError().text(); + } + } + DialogSec::errDatabaseFailedExecuting( db_name, stmt_msg, err_msg ); + + } else { + + try { + for ( const std::string& hash : hashes ) { + proceed = this->insertUsedHash( query, db_name, hash, web_server_id ); + if ( ! proceed ) { + break; + } + } + query.finish(); + + if ( proceed ) { + // commit the transaction + if ( ! db.commit() ) { + // error opening database + proceed = false; + QString stmt_msg="", err_msg = ""; + if ( this->dialog_level > 0 ) { + stmt_msg = "db.commit()"; + if ( this->dialog_level == 2 ) { + err_msg= db.lastError().text(); + } + } + DialogSec::errDatabaseFailedExecuting( db_name, stmt_msg, err_msg ); + } + } + if ( ! proceed ) { + // rollback + throw (std::exception()); + } + + } catch (...) { + // wrongthing w3nt some.,. + proceed = false; + bool err_shown = false; + // rollback the transaction + if ( ! db.rollback() ) { + // error rolling back commits + QString stmt_msg="", err_msg = ""; + if ( this->dialog_level > 0 ) { + stmt_msg = "db.rollback()"; + if ( this->dialog_level == 2 ) { + err_msg = db.lastError().text(); + } + } + DialogSec::errDatabaseFailedExecuting( db_name, stmt_msg, err_msg ); + err_shown = true; + } + if ( ! err_shown ) { + // show a message + QString msg = DialogSec::tr("An error occured while working on the database\n\nAborting"); + DialogSec::errGeneric( msg ); + } + } + } + } + db.close(); + return proceed; +} diff --git a/logdoctor/modules/craplog/modules/hash.h b/logdoctor/modules/craplog/modules/hash.h new file mode 100644 index 00000000..1335c1a9 --- /dev/null +++ b/logdoctor/modules/craplog/modules/hash.h @@ -0,0 +1,101 @@ +#ifndef HASH_H +#define HASH_H + +#include +#include +#include + +#include +#include +#include +#include + + +//! HashOps +/*! + Operations for the hashes +*/ +class HashOps +{ +public: + HashOps(); + + + //! Sets the new Dialogs level + void setDialogLevel( const int& new_level ); + + //! Retrieves the lists of hashes from the database file + /*! + \param db_path The path of the log files' Hashes database + \return Whether the operation has been successful or not + \see hashes + */ + bool loadUsedHashesLists( const std::string& db_path ); + + //! Returns the hash resulting from the content of the given file + /*! + \param file_path The path of the file to process + \return The sha256 hash + \throw GenericException + \see SHA256 + */ + std::string digestFile( const std::string& file_path ); + + //! Checks if the given hash equals one which is already in the list + /*! + \param file_hash The sha256 hash to compare + \param web_server_id The ID of the Web Server which generated the file + \return Whether the hash is already in the list or not + \see hashes + */ + bool hasBeenUsed( const std::string& file_hash, const int& web_server_id ); + + //! Inserts a hashe in the corresponding database table + /*! + \param db_query Query instance, already initialized + \param db_name The name of the database, eventually used by dialogs + \param hash The hash to insert + \param web_server_id The ID of the Web Server which generated the file + \return Whether the operation has been successful or not + \see insertUsedHashes() + */ + bool insertUsedHash( QSqlQuery& query, const QString& db_name, const std::string& hash, const int& web_server_id ); + + //! Inserts multiple hashes in the corresponding database table + /*! + \param db_path The path of the Hashes database + \param hashes The list of hashes to insert + \param web_server_id The ID of the Web Server which generated the file + \return Whether the operation has been successful or not + \see insertUsedHash() + */ + bool insertUsedHashes( const std::string& db_path, const std::vector& hashes, const int& web_server_id ); + +private: + + // Quantity of information to display throught dialogs + int dialog_level = 2; + + // id constants + const int APACHE_ID = 11; + const int NGINX_ID = 12; + const int IIS_ID = 13; + + // List of Web Servers names + const std::unordered_map ws_names = { + {this->APACHE_ID, "apache"}, + {this->NGINX_ID, "nginx"}, + {this->IIS_ID, "iis"} }; + + + // Lists of used files' hashes + // { web_server_id : { hashes } } + std::unordered_map> hashes = { + {this->APACHE_ID, {}}, + {this->NGINX_ID, {}}, + {this->IIS_ID, {}} + }; + +}; + +#endif // HASH_H diff --git a/logdoctor/modules/craplog/modules/logs.cpp b/logdoctor/modules/craplog/modules/logs.cpp new file mode 100644 index 00000000..e628956f --- /dev/null +++ b/logdoctor/modules/craplog/modules/logs.cpp @@ -0,0 +1,465 @@ + +#include "logs.h" + +#include "modules/exceptions.h" +#include "modules/craplog/modules/datetime.h" + +#include "utilities/strings.h" + + +LogOps::LogOps() +{ + +} + + +LogOps::LogType LogOps::defineFileType( const std::vector& lines, const FormatOps::LogsFormat& format ) +{ + if ( lines.size() == 0 ) { + // empty content + return LogOps::LogType::Failed; + } + + int n_access=0, n_other=0; + LogOps::LogType log_type; + + // real type assignment + log_type = this->LogType::Failed; + for ( const std::string& line : lines ) { + // scan + if ( this->deepTypeCheck( line, format ) ) { + n_access++; + } else { + n_other++; + } + } + + // final decision + if ( n_access > 0 && n_other == 0 ) { + // access logs + log_type = LogOps::LogType::Access; + } else if ( n_other > 0 && n_access == 0 ) { + // other format, maybe error logs + log_type = LogOps::LogType::Discarded; + } else { + // something is wrong with this file, keep the Failed type + } + return log_type; +} + + +bool LogOps::deepTypeCheck( const std::string& line, const FormatOps::LogsFormat& format ) +{ + int n_sep_found=0, n_blank_sep=0, + n_sep = format.separators.size(); + size_t found_at, aux_found_at1=0, aux_found_at2; + std::string sep, aux_sep1, aux_sep2; + // check the initial part + if ( format.initial.size() > 0 ) { + if ( StringOps::startsWith( line, format.initial ) ) { + n_sep_found ++; + } + } else { + n_sep_found ++; + n_blank_sep ++; + } + // check the middle part + for ( int i=0; i 0 ) { + if ( StringOps::endsWith( line, format.final ) ) { + n_sep_found ++; + } + } else { + n_sep_found ++; + n_blank_sep ++; + } + + // add the initial and final seps now + n_sep += 2; + + // the result is considered ture if more then a half of the seps was found + // and more than a half of the found separators was not blank + bool result = false; + if ( n_sep_found >= n_sep-1 + && n_blank_sep <= n_sep_found/2 ) { + result = true; + } + + return result; +} + + +void LogOps::cleanLines( std::vector &lines ) +{ + std::vector aux; + for ( const std::string& line : lines ) { + if ( !StringOps::startsWith( line, "#" ) ) { + // not a commented line + aux.push_back( line ); + } + } + lines = aux; +} + + + +const std::unordered_map LogOps::parseLine( const std::string& line, const FormatOps::LogsFormat& format ) +{ + std::unordered_map data; + std::string sep, fld, fld_str; + bool add_pm=false; + size_t start, stop=0, aux_start, aux_stop, + line_size = line.size()-1; + int i=0, n_sep=format.separators.size()-1; + + // add the initial chars + stop = format.initial.size(); + + while (true) { + // split fields + start = stop; // stop updated at the end of the loop + if ( i <= n_sep ) { + sep = format.separators.at( i ); + stop = line.find( sep, start ); + } else if ( i == n_sep+1 ) { + // final separator + sep = format.final; + if ( sep == "" ) { + stop = line_size+1; + } else { + stop = line.find( sep, start ); + if ( stop == std::string::npos ) { + stop = line_size +1; + } + } + } else { + // no more separators + break; + } + if ( stop == std::string::npos ) { + // separator not found, abort + throw LogParserException( "Separator not found", sep ); + } + + // get the field + fld = format.fields.at( i ); + if ( fld != "NONE" ) { + // only parse the considered fields + fld_str = StringOps::strip( line.substr(start, stop-start), " " ); + + if ( i+1 <= n_sep ) { + // not the last separator, check for mistakes + bool ok = true; + aux_stop = stop; + + if ( sep == " " ) { + // whitespace-separated-values fields + int c = StringOps::count( fld_str, sep ), + n = 0; + if ( fld == "request_full" ) { + n = 2; + } else if ( fld == "date_time_mcs" ) { + n = 4; + } else if ( fld == "date_time_ncsa" ) { + n = 1; + } else if ( fld == "date_time_gmt" ) { + n = 3; + } + if ( n > 0 && c < n ) { + // loop until the correct number of whitespaces is reached + aux_start = stop + 1; + while ( c < n ) { + aux_stop = line.find( sep, aux_start ); + if ( aux_stop == std::string::npos ) { + // not found + ok = false; + break; + } + aux_start = aux_stop + 1; + c++; + } + } + + } else if ( fld == "user_agent" && StringOps::startsWith( sep, "\"" ) ) { + // atm the only support is for escaped quotes + if ( fld_str.back() == '\\' ) { + aux_start = stop + sep.size(); + while (true) { + aux_stop = line.find( sep, aux_start ); + if ( aux_stop == std::string::npos ) { + // not found + break; + } else if ( line.at( aux_stop-1 ) != '\\' ) { + // non-backslashed quotes + break; + } + aux_start = aux_stop + sep.size(); + } + } + } + + // finally update if needed + if ( ok && aux_stop >= stop ) { + stop = aux_stop; + fld_str = StringOps::strip( line.substr(start, stop-start), " " ); + } + } + + // process the field + this->parsed_size += fld_str.size(); + + if ( fld_str != "" ) { + int fld_id = this->field2id.at(fld); + if ( fld_id > 0 ) { + // no need to process, append directly if non-empty + data.emplace( fld_id, fld_str ); + + } else { + // process the field + + // process the date to get year, month, day, hour and minute + if ( StringOps::startsWith( fld, "date_time" ) ) { + const std::vector dt = DateTimeOps::processDateTime( fld_str, fld.substr( 10 ) ); // cut away the "date_time_" part which is useless from now on + if ( dt.at( 0 ) != "" ) { + // year + data.emplace( this->field2id.at("date_time_year"), dt.at( 0 ) ); + } + if ( dt.at( 1 ) != "" ) { + // month + data.emplace( this->field2id.at("date_time_month"), dt.at( 1 ) ); + } + if ( dt.at( 2 ) != "" ) { + // day + data.emplace( this->field2id.at("date_time_day"), dt.at( 2 ) ); + } + if ( dt.at( 3 ) != "" ) { + // hour + if ( dt.at( 3 ) == "PM" ) { + add_pm = true; + } else { + data.emplace( this->field2id.at("date_time_hour"), dt.at( 3 ) ); + } + } + if ( dt.at( 4 ) != "" ) { + // minute + data.emplace( this->field2id.at("date_time_minute"), dt.at( 4 ) ); + } + if ( dt.at( 5 ) != "" ) { + // second + data.emplace( this->field2id.at("date_time_second"), dt.at( 5 ) ); + } + + + // process the request to get the protocol, method, resource and query + } else if ( fld == "request_full" ) { + size_t aux; + std::string aux_fld, protocol="", method="", page="", query=""; + aux_fld = fld_str; + // method + aux = aux_fld.find( ' ' ); + if ( aux != std::string::npos ) { + method = aux_fld.substr( 0, aux ); + aux_fld = StringOps::lstrip( aux_fld.substr( aux ) ); + + // page & query + aux = aux_fld.find( ' ' ); + if ( aux != std::string::npos ) { + std::string aux_str = aux_fld.substr( 0, aux ); + // search for the query + int aux_ = aux_str.find( '?' ); + if ( aux_ != std::string::npos ) { + page = aux_str.substr( 0, aux_ ); + query = aux_str.substr( aux_+1 ); + } else { + // query not found + page = aux_str; + } + aux_fld = StringOps::lstrip( aux_fld.substr( aux ) ); + + // protocol + protocol = aux_fld; + } + } + // append non-empty data + if ( protocol != "" ) { + data.emplace( this->field2id.at("request_protocol"), protocol ); + } + if ( method != "" ) { + data.emplace( this->field2id.at("request_method"), method ); + } + if ( page != "" ) { + data.emplace( this->field2id.at("request_uri"), page ); + } + if ( query != "" ) { + data.emplace( this->field2id.at("request_query"), query ); + } + + + + // process the request to get uri and query + } else if ( fld == "request_uri_query" ) { + // search for the query + std::string page, query; + size_t aux_ = fld_str.find( '?' ); + if ( aux_ != std::string::npos ) { + page = fld_str.substr( 0, aux_ ); + query = fld_str.substr( aux_+1 ); + } else { + // query not found + page = fld_str; + } + if ( page != "" ) { + data.emplace( this->field2id.at("request_uri"), page ); + } + if ( query != "" ) { + data.emplace( this->field2id.at("request_query"), query ); + } + + + + // process the time taken to convert to milliseconds + } else if ( StringOps::startsWith( fld, "time_taken_" ) ) { + float t = std::stof( fld_str ); + fld = fld.substr( 11 ); + if ( fld == "us" ) { + // from microseconds + t /= 1000; + } else if ( fld == "s" || fld == "s.ms" ) { + // from seconds + t *= 1000; + } + data.emplace( this->field2id.at("time_taken"), std::to_string( (int)t ) ); + + + // something went wrong + } else { + // hmmm.. no... + throw LogParserException( "Unexpected LogField", fld ); + } + } + } + } + + + // update the stop for the next start + stop += sep.size(); + i++; + if ( stop > line_size ) { + // this was the final separator + break; + } + } + + if ( add_pm ) { + try { + // add +12 hours for PM + data.at( 4 ) = std::to_string( 12 + std::stoi(data.at( 4 )) ); + } catch (...) { + // no hour data + } + } + + // set the default warning mark ( 0=false ) to default status + data.emplace( 99, "0" ); + + this->total_size += line_size; + this->parsed_lines ++; + + return data; +} + +void LogOps::parseLines( std::vector>& data, const std::vector& lines, const FormatOps::LogsFormat& format ) +{ + data.clear(); + data.shrink_to_fit(); + int nl = format.new_lines; + if ( nl == 0 ) { + data.reserve( lines.size() ); + for ( const std::string& line : lines ) { + data.push_back( this->parseLine( line, format ) ); + } + } else { + data.reserve( parsed_size / (nl+1) ); + parsed_size --; + for ( int i=0; iparseLine( line, format ) ); + } + } + if ( data.size() < data.capacity() ) { + data.shrink_to_fit(); + } +} + + +void LogOps::resetPerfData() +{ + this->total_size = 0; + this->parsed_size = 0; + this->parsed_lines = 0; +} +const unsigned LogOps::getTotalSize() +{ + return this->total_size; +} +const unsigned LogOps::getParsedSize() +{ + return this->parsed_size; +} +const unsigned LogOps::getParsedLines() +{ + return this->parsed_lines; +} diff --git a/logdoctor/modules/craplog/modules/logs.h b/logdoctor/modules/craplog/modules/logs.h new file mode 100644 index 00000000..3454c70f --- /dev/null +++ b/logdoctor/modules/craplog/modules/logs.h @@ -0,0 +1,152 @@ +#ifndef LOGS_H +#define LOGS_H + +#include +#include +#include + +#include "modules/craplog/modules/formats.h" + + +//! LogOps +/*! + Operations for the logs +*/ +class LogOps +{ +public: + LogOps(); + + //! Enumerates log file types + /*! + File types used to decide whether a file should be considered valid or not + \see defineFileType() + */ + enum LogType { + Failed = -1, //!< Failed to determine the type + Discarded = 0, //!< Not a valid file, will be discarded + Access = 1 //!< Valid access logs file type + }; + + //! Defines the type of a file + /*! + \param lines A list of (randomly picked) lines from the file to examine + \param format The logs format to use to determine if the file is valid or not + \return The resulting file type + \see LogType, deepTypeCheck(), FormatOps::LogsFormat + */ + LogType defineFileType( + const std::vector& lines, + const FormatOps::LogsFormat& format ); + + //! Removes commented lines from the given list + /*! + \param lines The lines to clean + */ + void cleanLines( + std::vector& lines ); + + //! Parses log lines to extract data + /*! + \param data The data collection which will hold the data + \param lines The list of lines to parse + \param format The logs format to use + \throw LogParserException + \see parseLine(), Craplog::parseLogLines(), FormatOps::LogsFormat + */ + void parseLines( + std::vector>& data, + const std::vector& lines, + const FormatOps::LogsFormat& format ); + + //! Resets the performances data + void resetPerfData(); + + // share perf data with craplog + const unsigned getTotalSize(); //!< Returns the total size of the logs lines. \see total_size + const unsigned getParsedSize(); //!< Returns the parsed logs size. \see parsed_size + const unsigned getParsedLines(); //!< Returns the number of parsed log lines. \see parsed_lines + +private: + + // Map to convert log fields to field IDs + const std::unordered_map field2id = { + // date-time + {"date_time_year", 1}, + {"date_time_month", 2}, + {"date_time_day", 3}, + {"date_time_hour", 4}, + {"date_time_minute", 5}, + {"date_time_second", 6}, + {"date_time_ncsa", 0}, + {"date_time_iso", 0}, + {"date_time_mcs", 0}, + {"date_time_gmt", 0}, + {"date_time_utc_d", 0}, + {"date_time_utc_t", 0}, + {"date_time_epoch_s", 0}, + {"date_time_epoch_s.ms", 0}, + {"date_time_epoch_ms", 0}, + {"date_time_epoch_us", 0}, + {"date_time_YYYYMMDD", 0}, + {"date_time_MMDDYY", 0}, + {"date_time_MDYY", 0}, + {"date_time_year_short", 0}, + {"date_time_month_str", 0}, + {"date_time_clock_12", 0}, + {"date_time_clock_24", 0}, + {"date_time_clock_short", 0}, + // request + {"request_protocol", 10}, + {"request_method", 11}, + {"request_uri", 12}, + {"request_query", 13}, + {"response_code", 14}, + {"request_full", 0}, + // performance + {"time_taken_ms", 15}, + {"time_taken_us", 0}, + {"time_taken_s.ms", 0}, + {"time_taken_s", 0}, + {"bytes_sent", 16}, + {"bytes_received", 17}, + // referer + {"referer", 18}, + // client data + {"client", 20}, + {"user_agent", 21}, + {"cookie", 22} + }; + + //! Parse the given line using the given format + /*! + \param line The log line to check + \param format The logs format to use + \return Whether the line respects the format or not + \see defineFileType(), FormatOps::LogsFormat + */ + bool deepTypeCheck( + const std::string& line, + const FormatOps::LogsFormat& format ); + + //! Parses a line to extract data + /*! + \param line The log line to parse + \param format The logs format to use + \return A data collection item + \throw LogParserException + \see parseLines(), Craplog::data_collection, FormatOps::LogsFormat + */ + const std::unordered_map parseLine( + const std::string& line, + const FormatOps::LogsFormat& format ); + + // temporary vars + unsigned total_size=0; //!< Total size of the parsed logs. \see getTotalSize() + unsigned parsed_size=0; //!< Size of the parsed logs. \see getParsedSize() + unsigned parsed_lines=0; //!< Number of parsed logs lines. \see getParsedLines() + + +}; + +#endif // LOGS_H diff --git a/logdoctor/modules/craplog/modules/sha256.LICENSE b/logdoctor/modules/craplog/modules/sha256.LICENSE new file mode 100644 index 00000000..9f47dce7 --- /dev/null +++ b/logdoctor/modules/craplog/modules/sha256.LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2021 Jérémy LAMBERT (SystemGlitch) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/logdoctor/modules/craplog/modules/sha256.cpp b/logdoctor/modules/craplog/modules/sha256.cpp new file mode 100644 index 00000000..8c0e56a6 --- /dev/null +++ b/logdoctor/modules/craplog/modules/sha256.cpp @@ -0,0 +1,179 @@ +/* +MIT License + +Copyright (c) 2021 Jérémy LAMBERT (SystemGlitch) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +#include "sha256.h" + +#include +#include +#include + + +SHA256::SHA256(): m_blocklen(0), m_bitlen(0) { + m_state[0] = 0x6a09e667; + m_state[1] = 0xbb67ae85; + m_state[2] = 0x3c6ef372; + m_state[3] = 0xa54ff53a; + m_state[4] = 0x510e527f; + m_state[5] = 0x9b05688c; + m_state[6] = 0x1f83d9ab; + m_state[7] = 0x5be0cd19; +} + +void SHA256::update(const uint8_t * data, size_t length) { + for (size_t i = 0 ; i < length ; i++) { + m_data[m_blocklen++] = data[i]; + if (m_blocklen == 64) { + transform(); + + // End of the block + m_bitlen += 512; + m_blocklen = 0; + } + } +} + +void SHA256::update(const std::string &data) { + update(reinterpret_cast (data.c_str()), data.size()); +} + +uint8_t * SHA256::digest() { + uint8_t * hash = new uint8_t[32]; + + pad(); + revert(hash); + + return hash; +} + +uint32_t SHA256::rotr(uint32_t x, uint32_t n) { + return (x >> n) | (x << (32 - n)); +} + +uint32_t SHA256::choose(uint32_t e, uint32_t f, uint32_t g) { + return (e & f) ^ (~e & g); +} + +uint32_t SHA256::majority(uint32_t a, uint32_t b, uint32_t c) { + return (a & (b | c)) | (b & c); +} + +uint32_t SHA256::sig0(uint32_t x) { + return SHA256::rotr(x, 7) ^ SHA256::rotr(x, 18) ^ (x >> 3); +} + +uint32_t SHA256::sig1(uint32_t x) { + return SHA256::rotr(x, 17) ^ SHA256::rotr(x, 19) ^ (x >> 10); +} + +void SHA256::transform() { + uint32_t maj, xorA, ch, xorE, sum, newA, newE, m[64]; + uint32_t state[8]; + + for (uint8_t i = 0, j = 0; i < 16; i++, j += 4) { // Split data in 32 bit blocks for the 16 first words + m[i] = (m_data[j] << 24) | (m_data[j + 1] << 16) | (m_data[j + 2] << 8) | (m_data[j + 3]); + } + + for (uint8_t k = 16 ; k < 64; k++) { // Remaining 48 blocks + m[k] = SHA256::sig1(m[k - 2]) + m[k - 7] + SHA256::sig0(m[k - 15]) + m[k - 16]; + } + + for(uint8_t i = 0 ; i < 8 ; i++) { + state[i] = m_state[i]; + } + + for (uint8_t i = 0; i < 64; i++) { + maj = SHA256::majority(state[0], state[1], state[2]); + xorA = SHA256::rotr(state[0], 2) ^ SHA256::rotr(state[0], 13) ^ SHA256::rotr(state[0], 22); + + ch = choose(state[4], state[5], state[6]); + + xorE = SHA256::rotr(state[4], 6) ^ SHA256::rotr(state[4], 11) ^ SHA256::rotr(state[4], 25); + + sum = m[i] + K[i] + state[7] + ch + xorE; + newA = xorA + maj + sum; + newE = state[3] + sum; + + state[7] = state[6]; + state[6] = state[5]; + state[5] = state[4]; + state[4] = newE; + state[3] = state[2]; + state[2] = state[1]; + state[1] = state[0]; + state[0] = newA; + } + + for(uint8_t i = 0 ; i < 8 ; i++) { + m_state[i] += state[i]; + } +} + +void SHA256::pad() { + + uint64_t i = m_blocklen; + uint8_t end = m_blocklen < 56 ? 56 : 64; + + m_data[i++] = 0x80; // Append a bit 1 + while (i < end) { + m_data[i++] = 0x00; // Pad with zeros + } + + if(m_blocklen >= 56) { + transform(); + memset(m_data, 0, 56); + } + + // Append to the padding the total message's length in bits and transform. + m_bitlen += m_blocklen * 8; + m_data[63] = m_bitlen; + m_data[62] = m_bitlen >> 8; + m_data[61] = m_bitlen >> 16; + m_data[60] = m_bitlen >> 24; + m_data[59] = m_bitlen >> 32; + m_data[58] = m_bitlen >> 40; + m_data[57] = m_bitlen >> 48; + m_data[56] = m_bitlen >> 56; + transform(); +} + +void SHA256::revert(uint8_t * hash) { + // SHA uses big endian byte ordering + // Revert all bytes + for (uint8_t i = 0 ; i < 4 ; i++) { + for(uint8_t j = 0 ; j < 8 ; j++) { + hash[i + (j * 4)] = (m_state[j] >> (24 - i * 8)) & 0x000000ff; + } + } +} + +std::string SHA256::toString(const uint8_t * digest) { + std::stringstream s; + s << std::setfill('0') << std::hex; + + for(uint8_t i = 0 ; i < 32 ; i++) { + s << std::setw(2) << (unsigned int) digest[i]; + } + + return s.str(); +} diff --git a/logdoctor/modules/craplog/modules/sha256.h b/logdoctor/modules/craplog/modules/sha256.h new file mode 100644 index 00000000..646150c3 --- /dev/null +++ b/logdoctor/modules/craplog/modules/sha256.h @@ -0,0 +1,76 @@ +/* +MIT License + +Copyright (c) 2021 Jérémy LAMBERT (SystemGlitch) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +#ifndef SHA256_H +#define SHA256_H + +#include +#include + +class SHA256 { + +public: + SHA256(); + void update(const uint8_t * data, size_t length); + void update(const std::string &data); + uint8_t * digest(); + + static std::string toString(const uint8_t * digest); + +private: + uint8_t m_data[64]; + uint32_t m_blocklen; + uint64_t m_bitlen; + uint32_t m_state[8]; //A, B, C, D, E, F, G, H + + static constexpr std::array K = { + 0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5, + 0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5, + 0xd807aa98,0x12835b01,0x243185be,0x550c7dc3, + 0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174, + 0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc, + 0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da, + 0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7, + 0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967, + 0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13, + 0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85, + 0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3, + 0xd192e819,0xd6990624,0xf40e3585,0x106aa070, + 0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5, + 0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3, + 0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208, + 0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2 + }; + + static uint32_t rotr(uint32_t x, uint32_t n); + static uint32_t choose(uint32_t e, uint32_t f, uint32_t g); + static uint32_t majority(uint32_t a, uint32_t b, uint32_t c); + static uint32_t sig0(uint32_t x); + static uint32_t sig1(uint32_t x); + void transform(); + void pad(); + void revert(uint8_t * hash); +}; + +#endif // SHA256_H diff --git a/logdoctor/modules/craplog/modules/store.cpp b/logdoctor/modules/craplog/modules/store.cpp new file mode 100644 index 00000000..4927e9b2 --- /dev/null +++ b/logdoctor/modules/craplog/modules/store.cpp @@ -0,0 +1,290 @@ + +#include "store.h" + +#include "modules/dialogs.h" +#include "modules/exceptions.h" + +#include "utilities/strings.h" + +#include + + +StoreOps::StoreOps() +{ + +} + + + +bool StoreOps::storeData( QSqlDatabase& db, Craplog& craplog, const std::vector>& data ) +{ + bool successful = true; + + int wsID = craplog.getCurrentWSID(); + QString db_name; + { + std::string db_path = craplog.getStatsDatabasePath(); + db_name.append( QString::fromStdString( db_path.substr( db_path.find_last_of( '/' ) + 1 ) ) ); + } + + // get blacklist/warnlist items + bool check_bl_cli, + check_wl_cli, check_wl_ua, check_wl_met, check_wl_req; + check_bl_cli = craplog.isBlacklistUsed( wsID, 20 ); + check_wl_met = craplog.isWarnlistUsed( wsID, 11 ); + check_wl_req = craplog.isWarnlistUsed( wsID, 12 ); + check_wl_cli = craplog.isWarnlistUsed( wsID, 20 ); + check_wl_ua = craplog.isWarnlistUsed( wsID, 21 ); + std::vector bl_cli_list, wl_cli_list, wl_ua_list, wl_met_list, wl_req_list; + if ( check_bl_cli ) { + bl_cli_list = craplog.getBlacklist( wsID, 20 ); + } + if ( check_wl_met ) { + wl_met_list = craplog.getWarnlist( wsID, 11 ); + } + if ( check_wl_req ) { + wl_req_list = craplog.getWarnlist( wsID, 12 ); + } + if ( check_wl_cli ) { + wl_cli_list = craplog.getWarnlist( wsID, 20 ); + } + if ( check_wl_ua ) { + wl_ua_list = craplog.getWarnlist( wsID, 21 ); + } + + // prepare the database related studd + QString table; + switch ( wsID ) { + case 11: + table = "apache"; + break; + case 12: + table = "nginx"; + break; + case 13: + table = "iis"; + break; + default: + // wrong WebServerID, but should be unreachable because of the previous operations + throw WebServerException( "Unexpected WebServerID: " + std::to_string(wsID) ); + } + + + int perf_size; + bool skip = false, + warning = false; + QSqlQuery query = QSqlQuery( db ); + // parse every row of data + for ( const std::unordered_map& row : data ) { + // break if failed + if ( ! successful ) { break; } + + // check blacklisted clients + if ( check_bl_cli ) { + if ( row.find( 20 ) != row.end() ) { + // this row do contains this row item, check if they match + const std::string& target = row.at( 20 ); + for ( const auto& item : bl_cli_list ) { + if ( StringOps::startsWith( target, item ) ) { + // match found! skip this line + skip = true; + break; + } + } + } + } + if ( skip ) { + // append every field to ignored size + int blacklisted_size = 0; + for ( const auto& [ id, str ] : row ) { + blacklisted_size += str.size(); + } + craplog.sumBlacklistededSize( blacklisted_size ); + skip = false; + continue; + } + + // check warnlisted clients + if ( check_wl_cli ) { + if ( row.find( 20 ) != row.end() ) { + // this row do contains this row item, check if they match + const std::string& target = row.at( 20 ); + for ( const auto& item : wl_cli_list ) { + if ( StringOps::startsWith( target, item ) ) { + // match found! put a warning on this line + warning = true; + craplog.sumWarningsSize( item.size() ); + break; + } + } + } + } + // check warnlisted user-agents + if ( check_wl_ua && !warning ) { + if ( row.find( 21 ) != row.end() ) { + // this row do contains this row item, check if they match + const std::string& target = row.at( 21 ); + for ( const auto& item : wl_ua_list ) { + if ( StringOps::startsWith( target, item ) ) { + // match found! skip this line + warning = true; + craplog.sumWarningsSize( item.size() ); + break; + } + } + } + } + // check warnlisted methods + if ( check_wl_met && !warning ) { + if ( row.find( 11 ) != row.end() ) { + // this row do contains this row item, check if they match + const std::string& target = row.at( 11 ); + for ( const auto& item : wl_met_list ) { + if ( item == target ) { + // match found! skip this line + warning = true; + craplog.sumWarningsSize( item.size() ); + break; + } + } + } + } + // check warnlisted requests urls + if ( check_wl_req && !warning ) { + if ( row.find( 12 ) != row.end() ) { + // this row do contains this row item, check if they match + const std::string& target = row.at( 12 ); + for ( const auto& item : wl_req_list ) { + if ( StringOps::startsWith( target, item ) ) { + // match found! skip this line + warning = true; + craplog.sumWarningsSize( item.size() ); + break; + } + } + } + } + + + // initialize the SQL statement + QString query_stmt; + query_stmt = "INSERT INTO \""+table+"\" (\"warning\", \"year\", \"month\", \"day\", \"hour\", \"minute\", \"second\", \"protocol\", \"method\", \"uri\", \"query\", \"response\", \"time_taken\", \"bytes_sent\", \"bytes_received\", \"referrer\", \"client\", \"user_agent\", \"cookie\") "\ + "VALUES ("; + + + // complete and execute the statement, binding NULL if not found + perf_size = 0; + + // warning + if ( row.find( 99 ) == row.end() ) { + // no value found in the collection, bind NULL + query_stmt += "0"; + } else { + // value found, bind it + perf_size ++; + if ( ! warning ) { + query_stmt += "0"; + } else { + query_stmt += "1"; + warning = false; + } + } + + // date and time + for ( int i=1; i<7; i++ ) { + query_stmt += ", "; + if ( row.find( i ) == row.end() ) { + // no value found in the collection, bind NULL + query_stmt += "NULL"; + } else { + // value found, bind it + perf_size += row.at( i ).size(); + query_stmt += QString::fromStdString( row.at( i ) ).replace("'","''"); + } + } + + // request + for ( int i=10; i<14; i++ ) { + query_stmt += ", "; + if ( row.find( i ) == row.end() ) { + // no value found in the collection, bind NULL + query_stmt += "NULL"; + } else { + // value found, bind it + perf_size += row.at( i ).size(); + query_stmt += QString("'%1'").arg( QString::fromStdString( row.at( i ) ).replace("'","''") ); + } + } + + for ( int i=14; i<18; i++ ) { + query_stmt += ", "; + if ( row.find( i ) == row.end() ) { + // no value found in the collection, bind NULL + query_stmt += "NULL"; + } else { + // value found, bind it + perf_size += row.at( i ).size(); + query_stmt += QString::fromStdString( row.at( i ) ).replace("'","''"); + } + } + + // client data and referrer + for ( int i : std::vector({18,20,21,22}) ) { + query_stmt += ", "; + if ( row.find( i ) == row.end() ) { + // no value found in the collection, bind NULL + query_stmt += "NULL"; + } else { + // value found, bind it + if ( i == 21 && wsID == 13 ) { + // iis logs the user-agent using '+' instead of ' ' (spaces) + QString str = QString::fromStdString( row.at( i ) ).replace("+"," "); + perf_size += str.size(); + query_stmt += QString("'%1'").arg( str.replace("'","''") ); + } else { + perf_size += row.at( i ).size(); + query_stmt += QString("'%1'").arg( QString::fromStdString( row.at( i ) ).replace("'","''") ); + } + } + } + + + // encode the statement + query_stmt += ");"; + if ( ! query.prepare( query_stmt ) ) { + // error opening database + successful = false; + QString query_msg="", err_msg=""; + if ( craplog.getDialogsLevel() > 0 ) { + query_msg = "query.prepare()"; + if ( craplog.getDialogsLevel() == 2 ) { + err_msg = query.lastError().text(); + } + } + DialogSec::errDatabaseFailedExecuting( db_name, query_msg, err_msg ); + } + + // sum stored data size for the perfs + //craplog.sumPerfSize( perf_size ); + + // finalize this statement + if ( ! query.exec() ) { + // error finalizing step + successful = false; + QString query_msg="", err_msg=""; + if ( craplog.getDialogsLevel() > 0 ) { + query_msg = "query.exec()"; + if ( craplog.getDialogsLevel() == 2 ) { + err_msg = query.lastError().text(); + } + } + DialogSec::errDatabaseFailedExecuting( db_name, query_msg, err_msg ); + break; + } + + // reset the statement to prepare for the next one + query.finish(); + } + + return successful; +} diff --git a/logdoctor/modules/craplog/modules/store.h b/logdoctor/modules/craplog/modules/store.h new file mode 100644 index 00000000..06224fd2 --- /dev/null +++ b/logdoctor/modules/craplog/modules/store.h @@ -0,0 +1,27 @@ +#ifndef STORE_H +#define STORE_H + +#include "modules/craplog/craplog.h" + + +//! StoreOps +/*! + Operations to store logs data +*/ +class StoreOps +{ +public: + StoreOps(); + + //! Stores the data collection in the logs Collection database + /*! + \param db A database instance, already initizlized + \param craplog The Craplog instance + \param data The logs data collection + \return Whether the operation has been successful or not + \throw WebServerException + */ + static bool storeData( QSqlDatabase& db, Craplog& craplog, const std::vector>& data ); +}; + +#endif // STORE_H diff --git a/logdoctor/modules/crapup/crapup.cpp b/logdoctor/modules/crapup/crapup.cpp new file mode 100644 index 00000000..8503f6d1 --- /dev/null +++ b/logdoctor/modules/crapup/crapup.cpp @@ -0,0 +1,343 @@ + +#include "crapup.h" +#include "ui_crapup.h" + +#include "modules/exceptions.h" + +#include +#include + +#include +#include +#include // leave this for OSX + + +Crapup::Crapup( const int& window_theme_id, const QString& icons_theme, QWidget* parent ) : + QWidget(parent), + ui(new Ui::Crapup) +{ + this->ui->setupUi(this); + + QString stylesheet = ""; + this->getStyleSheet( stylesheet, window_theme_id ); + this->setStyleSheet( stylesheet ); + + this->img_checking = QPixmap(":/icons/icons/"+icons_theme+"/checking.png"); + + this->ui->label_Title->setText( Crapup::tr("Checking for updates") ); + this->adjustSize(); +} + +Crapup::~Crapup() +{ + delete this->ui; + if ( this->reply ) { + delete this->reply; + } + if ( this->img_timer ) { + delete this->img_timer; + } + if ( this->request_timer ) { + delete this->request_timer; + } +} + +void Crapup::closeEvent( QCloseEvent* event ) +{ + this->quitting = true; + if ( this->img_timer->isActive() ) { + this->img_timer->stop(); + } + if ( this->request_timer->isActive() ) { + this->request_timer->stop(); + } + if ( this->reply ) { + if ( !this->reply->isFinished() ) { + this->requestTimeout(); + } + } +} + + +void Crapup::versionCheck( const float& v ) +{ + bool successful = false; + float version = -1; + int err = 1; + + this->img_timer = new QTimer(this); + connect(this->img_timer, SIGNAL(timeout()), this, SLOT(rotateImg())); + this->img_timer->start(100); + + QByteArray ua = QByteArray::fromStdString("LogDoctor/"+std::to_string(v)+" (version check)"); + std::string content; + + const std::string links[3] = {"https://raw.githubusercontent.com/elB4RTO/LogDoctor/main/version.txt", + "https://git.disroot.org/elB4RTO/LogDoctor/raw/branch//main/version.txt", + "https://gitlab.com/elB4RTO/LogDoctor/-/raw/main/version.txt"}; + + QNetworkAccessManager networkMgr = QNetworkAccessManager(this); + + + for ( const std::string& URL : links ) { + + // reset the content + content.clear(); + + // reset the reply + this->request_aborted = false; + + // request timeout timer + if ( this->request_timer ) { + delete this->request_timer; + } + this->request_timer = new QTimer(this); + this->request_timer->setSingleShot( true ); + connect(this->request_timer, SIGNAL(timeout()), this, SLOT(requestTimeout())); + + // set the URL and make the request + QNetworkRequest request; + request.setRawHeader( "User-Agent", ua ); + request.setUrl( QUrl( URL.c_str() ) ); + request.setTransferTimeout( this->timeout_msec ); + this->reply = networkMgr.get( request ); + + // reply waiter loop + QEventLoop wait_reply; + connect(this->reply, SIGNAL(readyRead()), &wait_reply, SLOT(quit())); + connect(this, SIGNAL(abortRequest()), &wait_reply, SLOT(quit())); + + // make the request + this->request_timer->start( this->timeout_msec+1000 ); + wait_reply.exec(); + + // request is over, in a way or another + if ( this->quitting ) { + networkMgr.disconnect(); + return; + } + if ( this->request_timer->isActive() ) { + this->request_timer->stop(); + } + if ( !this->reply ) { + err = 2; + continue; + } + + if ( this->reply->error() ) { + continue; + } else { + // connection successful, get the content + content = this->reply->readAll().toStdString(); + // search for the version mark + const std::string version_mark = ".:!¦version¦!:."; + int start = content.find( version_mark ); + if ( start != std::string::npos ) { + // first found + start += version_mark.size(); + const int stop = content.find( version_mark, start ); + if ( stop != std::string::npos ) { + // second found too + try { + // get the version + version = std::stof( content.substr( start, stop-start ) ); + successful = true; + break; + + } catch ( const std::invalid_argument&/*& e*/ ) { + // failed to convert string to float + err = 21; + } + } else { + // second version mark not found + err = 12; + } + } else { + // first version mark not found + err = 11; + } + } + } + if ( this-> reply ) { + this->deleteReply(); + } + networkMgr.disconnect(); + this->img_timer->stop(); + this->ui->label_Image->setVisible( false ); + + if ( !successful && err < 10 ) { + // connection failure + this->ui->label_Title->setText( Crapup::tr("Failed to establish a connection") ); + switch ( err ) { + case 1: + this->ui->label_Message->setText( Crapup::tr( + "Connection error, please try again later" ) ); + break; + case 2: + this->ui->label_Message->setText( Crapup::tr( + "Connection timed out" ) ); + break; + default: + throw GenericException("Unexpected err_code in VersionCheck: "+std::to_string(err)); + break; + } + + } else { + if ( successful ) { + // check the versions + if ( version > v ) { + // new version available + this->ui->label_Title->setText( Crapup::tr("New version available") ); + this->ui->label_Message->setText( Crapup::tr( + "A new version is available!\n" + "Please visit LogDoctor's git repository and follow the instruction about how to update" ) ); + } else if ( version == v ) { + // same version + this->ui->label_Title->setText( Crapup::tr("No update found") ); + this->ui->label_Message->setText( Crapup::tr( + "LogDoctor is up-to-date" ) ); + } else if ( version > 0 ) { + // this version is beyond the current upstream version + this->ui->label_Title->setText( Crapup::tr(":/") ); + this->ui->label_Message->setText( Crapup::tr( + "You're running a version from the future!\n" + "Your version is beyond the current upstream version\n" + "Are you running the original LogDoctor?\n" + "Please visit the LogDoctor's repository and get a fresh version of it" ) ); + } else { + // something went wrong, can't be successful if version is less than 0 + successful = false; + err = 22; + } + } + if ( !successful ) { + // version error + this->ui->label_Title->setText( Crapup::tr("Version check failed") ); + switch ( err ) { + case 11: + this->ui->label_Message->setText( Crapup::tr( + "An error occured while parsing:\n" + "initial version mark not found" ) ); + break; + case 12: + this->ui->label_Message->setText( Crapup::tr( + "An error occured while parsing:\n" + "final version mark not found" ) ); + break; + case 21: + this->ui->label_Message->setText( Crapup::tr( + "An error occured while parsing:\n" + "malformed version" ) ); + break; + case 22: + this->ui->label_Message->setText( Crapup::tr( + "An error occured while comparing:\n" + "malformed upstream version" ) ); + break; + default: + throw GenericException("Unexpected err_code in VersionCheck: "+std::to_string(err)); + break; + } + } + } + this->adjustSize(); +} + + + +void Crapup::requestTimeout() +{ + this->request_aborted = true; + this->deleteReply(); + emit this->abortRequest(); +} + +void Crapup::deleteReply() +{ + if ( !this->reply->isFinished() ) { + this->reply->abort(); + } + if ( this->reply->isOpen() ) { + this->reply->close(); + } + delete this->reply; + this->reply = nullptr; +} + + + +void Crapup::rotateImg() +{ + this->img_orientation += 36.0; + if ( this->img_orientation >= 360.0 ) { + this->img_orientation = 0.0; + } + this->ui->label_Image->setPixmap( + this->img_checking.transformed( + QTransform().rotate( this->img_orientation ) ) ); +} + + +void Crapup::getStyleSheet( QString& stylesheet, const int& theme_id ) +{ + std::unordered_map style; + switch ( theme_id ) { + case 0: + break; + case 1: + style = { + {"text", + "rgb( 248, 248, 248 )"}, + {"window_primary", + "rgb( 16, 16, 16 )"}, + {"window_secondary", + "rgb( 32, 32, 32 )"} + }; + break; + case 2: + style = { + {"text", + "rgb( 45, 0, 30 )"}, + {"window_primary", + "rgb( 255, 204, 143 )"}, + {"window_secondary", + "rgb( 255, 140, 141 )"} + }; + break; + case 3: + style = { + {"text", + "rgb( 220, 211, 187 )"}, + {"window_primary", + "rgb( 14, 28, 0 )"}, + {"window_secondary", + "rgb( 24, 48, 0 )"} + }; + break; + case 4: + style = { + {"text", + "rgb( 30, 21, 0 )"}, + {"window_primary", + "rgb( 230, 221, 197 )"}, + {"window_secondary", + "rgb( 170, 161, 137 )"} + }; + break; + default: + throw GenericException( "Unexpected WindowTheme ID: "+std::to_string(theme_id), true ); + break; + } + if ( theme_id != 0 ) { + stylesheet = + "* {" + " color: "+style.at("text")+";" + "}" + "QWidget#Crapup {" + " background-color: "+style.at("window_primary")+";" + "}" + "QFrame {" + " background-color: "+style.at("window_secondary")+";" + "}"; + } +} diff --git a/logdoctor/modules/crapup/crapup.h b/logdoctor/modules/crapup/crapup.h new file mode 100644 index 00000000..e157a4ad --- /dev/null +++ b/logdoctor/modules/crapup/crapup.h @@ -0,0 +1,88 @@ +#ifndef CRAPUP_H +#define CRAPUP_H + +#include +#include +#include +#include + + +namespace Ui { + class Crapup; +} + + +//! Crapup +/*! + +*/ +class Crapup : public QWidget +{ + Q_OBJECT +public: + + //! Class constructor + /*! + \param window_theme_id The ID of the window theme + \param icons theme The theme of the icons + \param parent The parent Widget + */ + Crapup( const int& window_theme_id, const QString& icons_theme, QWidget* parent=nullptr ); + ~Crapup(); + + + //! Performs a version check + /*! + \param current_version The running version of LogDoctor + \throw GenericException + */ + void versionCheck( const float& current_version ); + + +signals: + + //! Emitted to abort an on-going request + void abortRequest(); + + +private slots: + + //! Override + void closeEvent( QCloseEvent* event ) override; + + //! Called when a request's times out + /*! + \see deleteReply(), abortRequest() + */ + void requestTimeout(); + + //! Rotates the 'checking' image + void rotateImg(); + + +private: + Ui::Crapup *ui; + + QPixmap img_checking; + + float img_orientation = 0.0; + + QTimer* img_timer = nullptr; + + void getStyleSheet( QString& stylesheet, const int& theme_id ); + + bool request_aborted; + + QTimer* request_timer = nullptr; + + const int timeout_msec = 15000; + + QNetworkReply* reply = nullptr; + + //! Deletes the reply in a safe way + void deleteReply(); + + bool quitting = false; +}; + +#endif // CRAPUP_H diff --git a/logdoctor/modules/crapup/crapup.ui b/logdoctor/modules/crapup/crapup.ui new file mode 100644 index 00000000..9bf858a2 --- /dev/null +++ b/logdoctor/modules/crapup/crapup.ui @@ -0,0 +1,227 @@ + + + Crapup + + + + 0 + 0 + 576 + 320 + + + + + 512 + 256 + + + + LogDoctor - Updates + + + + :/logo/logo/logdoctor.svg:/logo/logo/logdoctor.svg + + + + + + Qt::Vertical + + + + 20 + 14 + + + + + + + + Qt::Horizontal + + + + 14 + 20 + + + + + + + + + 512 + 256 + + + + + 768 + 512 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 8 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 64 + + + + + 16777215 + 64 + + + + + 16 + + + + + + + Qt::AlignCenter + + + + + + + + 4 + + + 8 + + + 16 + + + 8 + + + 0 + + + + + + 0 + 64 + + + + + 16777215 + 64 + + + + + + + Qt::AlignCenter + + + + + + + + 0 + 0 + + + + + 0 + 24 + + + + + 13 + + + + + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + true + + + 4 + + + + + + + + + + + + + Qt::Horizontal + + + + 14 + 20 + + + + + + + + Qt::Vertical + + + + 20 + 14 + + + + + + + + + + + diff --git a/logdoctor/modules/crapview/crapview.cpp b/logdoctor/modules/crapview/crapview.cpp new file mode 100644 index 00000000..1260135a --- /dev/null +++ b/logdoctor/modules/crapview/crapview.cpp @@ -0,0 +1,1095 @@ + +#include "crapview.h" + +#include "utilities/strings.h" + +#include + + +Crapview::Crapview() +{ + +} + + +const int& Crapview::getDialogsLevel() +{ + return this->dialogs_level; +} +void Crapview::setDialogsLevel( const int& new_level ) +{ + this->dialogs_level = new_level; +} + + +void Crapview::setDbPath( const std::string& path ) +{ + this->dbQuery.setDbPath( path + "/collection.db" ); +} + + +const QString Crapview::printableDate( const QString& year, const int& month, const QString& day ) +{ + QString date = QString("%1-").arg( year ); + if ( month < 10 ) { + date += QString("0%1-").arg( month ); + } else { + date += QString("%1-").arg( month ); + } + if ( day.size() < 2 ) { + date += QString("0%1").arg( day ); + } else { + date += day; + } + return date; +} + + +const QString Crapview::printableDate( const int& year, const int& month, const int& day ) +{ + QString date; + if ( year < 10 ) { + date += QString("0%1-").arg( year ); + } else { + date += QString("%1-").arg( year ); + } + if ( month < 10 ) { + date += QString("0%1-").arg( month ); + } else { + date += QString("%1-").arg( month ); + } + if ( day < 10 ) { + date += QString("0%1").arg( day ); + } else { + date += QString("%1").arg( day ); + } + return date; +} + + +const QString Crapview::printableTime( const int& hour, const int& minute, const int& second ) +{ + QString time; + if ( hour < 10 ) { + time += QString("0%1:").arg( hour ); + } else { + time += QString("%1:").arg( hour ); + } + if ( minute < 10 ) { + time += QString("0%1:").arg( minute ); + } else { + time += QString("%1:").arg( minute ); + } + if ( second < 10 ) { + time += QString("0%1").arg( second ); + } else { + time += QString("%1").arg( second ); + } + return time; +} + + +const QString Crapview::printableWarn( const int& value ) +{ + if ( value == 0 ) { + return TR::tr( BOOLS__FALSE.c_str() ); + } else { + return TR::tr( BOOLS__TRUE.c_str() ); + } +} + + +const QString Crapview::parseBooleanFilter( const QString& filter_str ) +{ + QString aux = filter_str; + aux = aux.replace( TR::tr(BOOLS__TRUE.c_str()), "1", Qt::CaseSensitivity::CaseInsensitive ); + aux = aux.replace( TR::tr(BOOLS__FALSE.c_str()),"0", Qt::CaseSensitivity::CaseInsensitive ); + return this->parseNumericFilter( aux ); +} + + +const QString Crapview::parseNumericFilter( const QString& filter_str ) +{ + QString final_str = ""; + if ( filter_str.size() > 0 ) { + QString aux_ = this->parseTextualFilter( filter_str ); + if ( aux_ == "NULL" || aux_ == "NOT NULL" ) { + final_str = aux_; + } else { + std::vector f_list; + StringOps::splitrip( f_list, filter_str.toStdString(), " " ); + if ( f_list.size() > 0 ) { + std::string& aux = f_list.at(0); + if ( StringOps::isNumeric( aux ) ) { + // no symbol specified, set '=' as default + final_str += "="; + final_str += QString::fromStdString( aux ); + } else { + if ( StringOps::isNumeric( StringOps::lstrip( aux, "!<=>" ) ) ) { + // symbol/value + final_str += QString::fromStdString( aux ).replace("==","="); + } else if ( StringOps::lstrip( aux, "!<=>" ).size() == 0 ) { + // symbol at first, maybe a value follows + if ( f_list.size() > 1 ) { + final_str += QString::fromStdString( aux ).replace("==","="); + int ck = final_str.size(); + for ( int i=1; i 0 ) { + std::string str = StringOps::strip( filter_str.toUpper().toStdString() ); + if ( str == "NULL" ) { + aux = "NULL"; + } else if ( str == "NOT NULL" || str == "*" ) { + aux = "NOT NULL"; + } + } + return aux; +} + + +void Crapview::refreshDates() +{ + std::tuple>>>> result; + this->dbQuery.refreshDates( result ); + if ( std::get<0>(result) ) { + this->dates = std::get<1>(result); + } +} +void Crapview::clearDates() +{ + this->dates.clear(); +} + +const QString Crapview::getLogFieldString ( const int& field_id ) +{ + return TR::tr( this->dbQuery.FIELDS.at( field_id ).c_str() ); +} + +const int Crapview::getLogFieldID ( const QString& field_str ) +{ + int f=0; + for ( const auto& [id,str] : this->dbQuery.FIELDS ) { + if ( TR::tr(str.c_str()) == field_str ) { + f = id; + break; + } + } + return f; +} + + +const int Crapview::getMonthNumber( const QString& month_str ) +{ + int m=0; + for ( const auto& [num,str] : this->dbQuery.MONTHS ) { + if ( TR::tr(str.c_str()) == month_str ) { + m = num; + break; + } + } + return m; +} + + + +const QStringList Crapview::getYears( const QString& web_server ) +{ + QStringList years; + if ( this->dates.size() > 0 ) { + const int ws = this->WebServer_s2i.value( web_server ); + if ( this->dates.at( ws ).size() > 0 ) { + for ( const auto& [year, data] : this->dates.at( ws ) ) { + years.push_back( QString::fromStdString( std::to_string( year ) ) ); + } + } + } + return years; +} +const QStringList Crapview::getMonths( const QString& web_server, const QString& year ) +{ + QStringList months; + if ( this->dates.size() > 0 ) { + const int ws = this->WebServer_s2i.value( web_server ); + if ( this->dates.at( ws ).size() > 0 ) { + const int y = year.toInt(); + if ( this->dates.at( ws ).at( y ).size() ) { + for ( const auto& [month, data] : this->dates.at( ws ).at( y ) ) { + months.push_back( TR::tr(this->dbQuery.MONTHS.at( month ).c_str()) ); + } + } + } + } + return months; +} +const QStringList Crapview::getDays( const QString& web_server, const QString& year, const QString& month ) +{ + QStringList days; + if ( this->dates.size() > 0 ) { + const int ws = this->WebServer_s2i.value( web_server ); + if ( this->dates.at( ws ).size() > 0 ) { + const int y = year.toInt(); + if ( this->dates.at( ws ).at( y ).size() ) { + const int m = this->getMonthNumber( month ); + if ( this->dates.at( ws ).at( y ).at( m ).size() > 0 ) { + for ( const int day : this->dates.at( ws ).at( y ).at( m ) ) { + days.push_back( QString::fromStdString( std::to_string( day ) ) ); + } + } + } + } + } + return days; +} +const QStringList Crapview::getHours() +{ + return QStringList({"00","01","02","03","04","05","06","07","08","09","10","11","12","13","14","15","16","17","18","19","20","21","22","23"}); +} + +const QStringList Crapview::getFields( const std::string& tab ) +{ + QStringList list; + for ( const auto& field : this->fields.at( tab ) ) { + list.append( TR::tr( field.c_str() ) ); + } + return list; +} + + +//////////////// +//// CHARTS //// +//////////////// +void Crapview::updateWarn( QTableWidget* table , const QString& web_server ) +{ + std::vector> updates; // { (rowid, warn) } + for ( int i=0; irowCount(); i++ ) { + QTableWidgetItem* item = table->item( i, 0 ); + if ( item->checkState() == Qt::CheckState::Checked && item->text() == TR::tr( BOOLS__FALSE.c_str() ) ) { + // remove warning + updates.push_back( std::make_tuple( table->item( i, table->columnCount()-1 )->text().toInt(), 1 ) ); + } else if (item->checkState() == Qt::CheckState::Unchecked && item->text() == TR::tr( BOOLS__TRUE.c_str() ) ) { + // add warning + updates.push_back( std::make_tuple( table->item( i, table->columnCount()-1 )->text().toInt(), 0 ) ); + } + } + this->dbQuery.updateWarnings( web_server, updates ); + updates.clear(); +} + +void Crapview::drawWarn( QTableWidget* table, QtCharts::QChartView* chart, const QChart::ChartTheme& theme, const std::unordered_map& fonts, const QString& web_server, const QString& year, const QString& month, const QString& day, const QString& hour ) +{ + std::tuple>>>> result; + this->dbQuery.getWarnCounts( + result, + web_server, + year, month, day, hour ); + if ( std::get<0>(result) ) { + // get data + // { hour : { 10th_minutes : count } } + std::vector>>> &items = std::get<1>(result); + + // bars + std::vector> sets; + + // build the bars and the table upon data + QString date; + QColor warn_col = QColor( 255, 140, 0, 255 ); + int norm_count, warn_count, sum_count, max_count=0, aux; + if ( hour.size() == 0 ) { + // entire day + for ( int i=0; i<6; i++ ) { + sets.push_back( std::vector() ); + sets.back().push_back( new QBarSet("") ); + sets.back().push_back( new QBarSet("") ); + } + for ( int h=0; h<24; h++ ) { + for ( int m=0; m<6; m++ ) { + const auto& data = items.at( h ).at( m ); + norm_count = warn_count = 0; + for ( const std::vector& line : data ) { + aux = table->rowCount(); + table->insertRow( aux ); + table->setItem( aux, 0, new QTableWidgetItem( this->printableWarn( line.at( 0 ).toInt() ))); + if ( line.at( 0 ).toInt() != 0 ) { + table->item( aux, 0 )->setForeground( warn_col ); + table->item( aux, 0 )->setCheckState( Qt::CheckState::Checked ); + } else { + table->item( aux, 0 )->setCheckState( Qt::CheckState::Unchecked ); + } + table->setItem( aux, 1, new QTableWidgetItem( this->printableDate( line.at( 1 ).toInt(), line.at( 2 ).toInt(), line.at( 3 ).toInt() ))); + table->setItem( aux, 2, new QTableWidgetItem( this->printableTime( line.at( 4 ).toInt(), line.at( 5 ).toInt(), line.at( 6 ).toInt() ))); + for ( int i=7; isetItem( aux, i-4, new QTableWidgetItem( line.at( i ) )); + } + if ( line.at( 0 ) == "0" ) { + norm_count ++; + } else { + warn_count ++; + } + } + sets.at( m ).at( 0 )->append( norm_count ); + sets.at( m ).at( 1 )->append( warn_count ); + sum_count = norm_count + warn_count; + if ( sum_count > max_count ) { + max_count = sum_count; + } + } + } + date = this->printableDate( year, this->getMonthNumber( month ), day ); + } else { + // 1 hour + for ( int i=0; i<10; i++ ) { + sets.push_back( std::vector() ); + sets.back().push_back( new QBarSet("") ); + sets.back().push_back( new QBarSet("") ); + } + for ( int g=0; g<6; g++ ) { + for ( int m=0; m<10; m++ ) { + const auto& data = items.at( g ).at( m ); + norm_count = warn_count = 0; + for ( const std::vector& line : data ) { + aux = table->rowCount(); + table->insertRow( aux ); + table->setItem( aux, 0, new QTableWidgetItem( this->printableWarn( line.at( 0 ).toInt() ))); + if ( line.at( 0 ).toInt() != 0 ) { + table->item( aux, 0 )->setForeground( warn_col ); + table->item( aux, 0 )->setCheckState( Qt::CheckState::Checked ); + } else { + table->item( aux, 0 )->setCheckState( Qt::CheckState::Unchecked ); + } + table->setItem( aux, 1, new QTableWidgetItem( this->printableDate( line.at( 1 ).toInt(), line.at( 2 ).toInt(), line.at( 3 ).toInt() ))); + table->setItem( aux, 2, new QTableWidgetItem( this->printableTime( line.at( 4 ).toInt(), line.at( 5 ).toInt(), line.at( 6 ).toInt() ))); + for ( int i=7; isetItem( aux, i-4, new QTableWidgetItem( line.at( i ) )); + } + if ( line.at( 0 ) == "0" ) { + norm_count ++; + } else { + warn_count ++; + } + } + sets.at( m ).at( 0 )->append( norm_count ); + sets.at( m ).at( 1 )->append( warn_count ); + sum_count = norm_count + warn_count; + if ( sum_count > max_count ) { + max_count = sum_count; + } + } + } + date = this->printableDate( year, this->getMonthNumber( month ), day ) + ", h " + hour; + } + table->verticalHeader()->setVisible( false ); + + // apply the colors and append to the series + QColor cols[] = {QColor(127,127,127), QColor(237,80,61)}; + //QColor cols[] = {QColor(18,175,194), QColor(237,80,61)}; + std::vector b_series; + for ( int i=0; isetColor( cols[ w ] ); + b_series.at( i )->append( b ); + } + } + for ( auto *s : b_series ) { + s->setBarWidth( 1 ); + } + + // set-up the bars chart + QChart *b_chart = new QChart(); + // apply the theme + b_chart->setTheme( theme ); + // append the bars + foreach ( auto& bars, b_series ) { + b_chart->addSeries( bars ); + } + b_chart->setTitle( TR::tr( "Log Lines Marked as Warning" ) ); + b_chart->setTitleFont( fonts.at("main") ); + b_chart->legend()->setVisible( false ); + /*b_chart->legend()->setFont( fonts.at("main_small") ); + b_chart->legend()->setAlignment( Qt::AlignBottom ); + b_chart->setAnimationOptions( QChart::SeriesAnimations );*/ + + // craft the X-axis labels + QStringList categories; + if ( hour.size() == 0 ) { + categories << "00" << "01" << "02" << "03" << "04" << "05" << "06" << "07" << "08" << "09" << "10" << "11" + << "12" << "13" << "14" << "15" << "16" << "17" << "18" << "19" << "20" << "21" << "22" << "23"; + } else { + categories << "00" << "10" << "20" << "30" << "40" << "50"; + } + + // set-up the time-of-day axis (X) + QBarCategoryAxis *axisX = new QBarCategoryAxis(); + axisX->append( categories ); + axisX->setLabelsFont( fonts.at( "main_small" ) ); + axisX->setTitleText( date ); + axisX->setTitleFont( fonts.at("main_small") ); + b_chart->addAxis( axisX, Qt::AlignBottom ); + for ( auto *s : b_series ) { + s->attachAxis( axisX ); + } + + // set-up the count values axis (Y) + QValueAxis *axisY = new QValueAxis(); + axisY->setLabelFormat( "%d" ); + axisY->setTickCount( ( max_count < 8 ) ? max_count : 8 ); + axisY->setRange( 0, max_count ); + axisY->setLabelsFont( fonts.at( "main_small" ) ); + b_chart->addAxis( axisY, Qt::AlignLeft ); + for ( auto *s : b_series ) { + s->attachAxis( axisY ); + } + + // apply the chart to the view + chart->setChart( b_chart ); + chart->setRenderHint( QPainter::Antialiasing ); + + items.clear(); + } +} + + + +void Crapview::drawSpeed( QTableWidget* table, QtCharts::QChartView* chart, const QChart::ChartTheme& theme, const std::unordered_map& fonts, const QString& web_server, const QString& year, const QString& month, const QString& day, const QString& protocol, const QString& method, const QString& uri, const QString& query, const QString& response ) +{ + std::tuple>>> result; + this->dbQuery.getSpeedData( + result, + web_server, + year, month, day, + protocol, method, uri, query, response ); + if ( std::get<0>(result) ) { + // get data + // { hour : { 10th_minutes : count } } + std::vector>> &items = std::get<1>(result); + + // draw the speed chart + QLineSeries *line = new QLineSeries(); + + // build the line upon data + int i=0, max_i=items.size(), max_t=0, aux; + long long time /* xD */, aux_time, t=0, aux_t, count=1; + time = std::get<0>(items.at(0)); + QDateTime dt; + std::vector data; + for ( const auto& item : items ) { + i++; + // append a value to the chart + aux_time = std::get<0>(item); + data = std::get<1>(item); + aux_t = data.at( 0 ).toLongLong(); + // append only if the second is different, else sum + if ( aux_time > time ) { + t = t/count; + if ( t == 0 ) { + t = 1; + } + line->append( time, t ); + if ( t > max_t ) { + max_t = t; + } + time = aux_time; + t = aux_t; + count = 1; + if ( i == max_i ) { + // final + if ( t == 0 ) { + t = 1; + } + line->append( time, t ); + if ( t > max_t ) { + max_t = t; + } + } + } else { + count ++; + t += aux_t; + if ( i == max_i ) { + // final + t = t/count; + if ( t == 0 ) { + t = 1; + } + line->append( aux_time, t ); + if ( t > max_t ) { + max_t = t; + } + } + } + // fill the teble with data + if ( data.at(0).size() > 0 || data.at(1).size() > 0 || data.at(2).size() > 0 || data.at(3).size() > 0 || data.at(4).size() > 0 || data.at(5).size() > 0 ) { + aux = table->rowCount(); + table->insertRow( aux ); + table->setItem( aux, 0, new QTableWidgetItem( data.at(0) )); + table->setItem( aux, 1, new QTableWidgetItem( data.at(1) )); + table->setItem( aux, 2, new QTableWidgetItem( data.at(2) )); + table->setItem( aux, 3, new QTableWidgetItem( data.at(3) )); + table->setItem( aux, 4, new QTableWidgetItem( data.at(4) )); + table->setItem( aux, 5, new QTableWidgetItem( data.at(5) )); + dt = QDateTime::fromMSecsSinceEpoch( aux_time ); + table->setItem( aux, 6, new QTableWidgetItem( dt.time().toString("hh:mm:ss") )); + } + } + table->verticalHeader()->setVisible( false ); + + // fictitious line + QLineSeries *line_ = new QLineSeries(); + + // color the area + QColor col1 = Qt::GlobalColor::red, + col2 = Qt::GlobalColor::green, + col3 = Qt::GlobalColor::blue; + //area->setColor( col ); + QLinearGradient gradient(QPointF(0, 0), QPointF(0, 1)); + gradient.setColorAt(0.3, col1.lighter( 90 ) ); + gradient.setColorAt(0.7, col2.lighter( 90 ) ); + gradient.setColorAt(1.0, col3.lighter( 90 ) ); + gradient.setCoordinateMode(QGradient::ObjectBoundingMode); + + QPen pen = line->pen(); + pen.setBrush( gradient ); + pen.setWidth( 1 ); + line->setPen(pen); + + pen = line_->pen(); + pen.setBrush( gradient ); + pen.setWidth( 1 ); + line_->setPen(pen); + + // build the chart + QChart *l_chart = new QChart(); + l_chart->setTheme( theme ); + l_chart->addSeries( line ); + l_chart->addSeries( line_ ); + l_chart->setTitle( TR::tr( "Time Taken to Serve Requests" ) ); + l_chart->setTitleFont( fonts.at("main") ); + /*l_chart->legend()->setFont( fonts.at( "main_small" ) ); + l_chart->legend()->setAlignment( Qt::AlignBottom );*/ + l_chart->legend()->setVisible( false ); + + // set-up the date-time axis (X) + QDateTimeAxis *axisX = new QDateTimeAxis(); + axisX->setLabelsFont( fonts.at( "main_small" ) ); + axisX->setFormat( "hh:mm" ); + axisX->setTickCount( 25 ); + axisX->setTitleText( this->printableDate( year, this->getMonthNumber(month), day ) ); + axisX->setTitleFont( fonts.at( "main_small" ) ); + l_chart->addAxis( axisX, Qt::AlignBottom ); + line->attachAxis( axisX ); + + // set-up the count values axis (Y) + QValueAxis *axisY = new QValueAxis(); + axisY->setLabelFormat( "%d" ); + axisY->setTickCount( ( max_t < 8 ) ? max_t : 8 ); + if ( max_t == 1 ) { + max_t = 0; + } + axisY->setRange( 0, max_t ); + axisY->setLabelsFont( fonts.at( "main_small" ) ); + l_chart->addAxis( axisY, Qt::AlignLeft ); + line->attachAxis( axisY) ; + + // add the chart to the view + chart->setChart( l_chart ); + chart->setRenderHint(QPainter::Antialiasing); + + items.clear(); + } +} + + + +void Crapview::drawCount( QTableWidget* table, QtCharts::QChartView* chart, const QChart::ChartTheme& theme, const std::unordered_map& fonts, const QString& web_server, const QString& year, const QString& month, const QString& day, const QString& field ) +{ + std::tuple>> result; + this->dbQuery.getItemsCount( + result, + web_server, + year, month, day, + field ); + if ( std::get<0>(result) ) { + // get data + std::vector> &aux_items = std::get<1>(result); + + // make the pie + QPieSeries *pie = new QPieSeries(); + // cut off exdceeding elements for the chart + const int max_items=15; + int aux, count, oth_count=0; + QString item; + for ( int i=0; i( aux_items.at(i) ); + count = std::get<1>( aux_items.at(i) ); + if ( i >= max_items ) { + oth_count += count; + } else { + pie->append( item, count ); + } + aux = table->rowCount(); + table->insertRow( aux ); + table->setItem( aux, 0, new QTableWidgetItem( QString::fromStdString( std::to_string(count) ))); + table->setItem( aux, 1, new QTableWidgetItem( std::get<0>( aux_items.at(i) ) )); + } + table->verticalHeader()->setVisible( false ); + aux_items.clear(); + + if ( oth_count > 0 ) { + pie->append( TR::tr( "Others" ), oth_count ); + QPieSlice *slice = pie->slices().at( pie->count()-1 ); + slice->setBrush( Qt::gray ); + } + pie->setLabelsVisible(); + + QChart *p_chart = new QChart(); + p_chart->setTheme( theme ); + p_chart->addSeries( pie ); + p_chart->setTitle( field ); + p_chart->setTitleFont( fonts.at( "main_big" ) ); + p_chart->legend()->hide(); + + chart->setChart( p_chart ); + chart->setRenderHint( QPainter::Antialiasing ); + } +} + + + +void Crapview::drawDay( QtCharts::QChartView* chart, const QChart::ChartTheme& theme, const std::unordered_map& fonts, const QString& web_server, const QString& from_year, const QString& from_month, const QString& from_day, const QString& to_year, const QString& to_month, const QString& to_day, const QString& field , const QString& filter ) +{ + std::tuple>> result; + this->dbQuery.getDaytimeCounts( + result, + web_server, + from_year, from_month, from_day, + to_year, to_month, to_day, + field, filter ); + if ( std::get<0>(result) ) { + // get data + // { hour : { 10th_minutes : count } } + std::unordered_map> &items = std::get<1>(result); + + // draw the chart + QString date; + QColor col = Qt::GlobalColor::darkGreen; + QBarSet *b_10 = new QBarSet( "" ); + b_10->setColor( col ); + QBarSet *b_20 = new QBarSet( "" ); + b_20->setColor( col ); + QBarSet *b_30 = new QBarSet( "" ); + if ( to_year.size() == 0 || to_month.size() == 0 || to_day.size() == 0 ) { + date = this->printableDate( from_year, this->getMonthNumber(from_month), from_day ); + } else { + date = QString("%1 %2 %3 %4") + .arg( TR::tr( "from" ), + this->printableDate( from_year, this->getMonthNumber(from_month), from_day ), + TR::tr( "to" ), + this->printableDate( to_year, this->getMonthNumber(to_month), to_day ) ); + } + b_30->setColor( col ); + QBarSet *b_40 = new QBarSet( "" ); + b_40->setColor( col ); + QBarSet *b_50 = new QBarSet( "" ); + b_50->setColor( col ); + QBarSet *b_60 = new QBarSet( "" ); + b_60->setColor( col ); + + // build the bars upon data + int count, max_count=0; + for ( int h=0; h<24; h++ ) { + auto& data = items.at( h ); + count = data.at( 0 ); + *b_10 << count; + if ( count > max_count ) { + max_count = count; + } + count = data.at( 10 ); + *b_20 << count; + if ( count > max_count ) { + max_count = count; + } + count = data.at( 20 ); + *b_30 << count; + if ( count > max_count ) { + max_count = count; + } + count = data.at( 30 ); + *b_40 << count; + if ( count > max_count ) { + max_count = count; + } + count = data.at( 40 ); + *b_50 << count; + if ( count > max_count ) { + max_count = count; + } + count = data.at( 50 ); + *b_60 << count; + if ( count > max_count ) { + max_count = count; + } + } + + // apply the bars to the bars serie + QBarSeries *bars = new QBarSeries(); + bars->append( b_10 ); bars->append( b_20 ); bars->append( b_30 ); + bars->append( b_40 ); bars->append( b_50 ); bars->append( b_60 ); + bars->setBarWidth( 1 ); + + // set-up the bars chart + QChart *b_chart = new QChart(); + b_chart->setTheme( theme ); + b_chart->addSeries( bars ); + b_chart->setTitle( QString("%1: %2").arg( TR::tr( "Time of Day Count" ), field ) ); + b_chart->setTitleFont( fonts.at("main") ); + b_chart->legend()->setVisible( false ); + /*b_chart->legend()->setFont( fonts.at("main_small") ); + b_chart->legend()->setAlignment( Qt::AlignBottom ); + b_chart->setAnimationOptions( QChart::SeriesAnimations );*/ + + // craft the X-axis labels + QStringList categories; + categories << "00" << "01" << "02" << "03" << "04" << "05" << "06" << "07" << "08" << "09" << "10" << "11" + << "12" << "13" << "14" << "15" << "16" << "17" << "18" << "19" << "20" << "21" << "22" << "23"; + + // set-up the time-of-day axis (X) + QBarCategoryAxis *axisX = new QBarCategoryAxis(); + axisX->append( categories ); + axisX->setLabelsFont( fonts.at( "main_small" ) ); + axisX->setTitleText( date ); + axisX->setTitleFont( fonts.at("main_small") ); + b_chart->addAxis( axisX, Qt::AlignBottom ); + bars->attachAxis( axisX ); + + // set-up the count values axis (Y) + QValueAxis *axisY = new QValueAxis(); + axisY->setLabelFormat( "%d" ); + axisY->setTickCount( ( max_count < 8 ) ? max_count : 8 ); + axisY->setRange( 0, max_count ); + axisY->setLabelsFont( fonts.at( "main_small" ) ); + b_chart->addAxis( axisY, Qt::AlignLeft ); + bars->attachAxis( axisY) ; + + // apply the chart to the view + chart->setChart( b_chart ); + chart->setRenderHint( QPainter::Antialiasing ); + + items.clear(); + } +} + + + +void Crapview::drawRelat( QtCharts::QChartView* chart, const QChart::ChartTheme& theme, const std::unordered_map& fonts, const QString& web_server, const QString& from_year, const QString& from_month, const QString& from_day, const QString& to_year, const QString& to_month, const QString& to_day, const QString& field_1, const QString& filter_1, const QString& field_2, const QString& filter_2 ) +{ + bool period = true; + std::tuple>> result; + if ( from_year == to_year + && from_month == to_month + && from_day == to_day ) { + period = false; + this->dbQuery.getRelationalCountsDay( + result, + web_server, + from_year, from_month, from_day, + field_1, filter_1, + field_2, filter_2 ); + } else { + this->dbQuery.getRelationalCountsPeriod( + result, + web_server, + from_year, from_month, from_day, + to_year, to_month, to_day, + field_1, filter_1, + field_2, filter_2 ); + } + + if ( std::get<0>(result) ) { + // get data + // { hour : { 10th_minutes : count } } + std::vector> &items = std::get<1>(result); + + // draw the relational chart + QLineSeries *line = new QLineSeries(); + // build the line upon data + int count, max_count=0; + long long time; // xD + for ( const auto& item : items ) { + time = std::get<0>(item); + count = std::get<1>(item); + line->append( time, (double)count ); + if ( count > max_count ) { + max_count = count; + } + } + + // build the area + QString date; + QAreaSeries *area = new QAreaSeries( line ); + if ( ! period ) { + date = this->printableDate( from_year, this->getMonthNumber(from_month), from_day ); + } else { + date = QString("%1 %2 %3 %4") + .arg( TR::tr( "from" ), + this->printableDate( from_year, this->getMonthNumber(from_month), from_day ), + TR::tr( "to" ), + this->printableDate( to_year, this->getMonthNumber(to_month), to_day )); + } + + // color the area + QColor col1 = Qt::GlobalColor::red, + col2 = Qt::GlobalColor::yellow, + col3 = Qt::GlobalColor::magenta; + //area->setColor( col ); + QLinearGradient gradient(QPointF(0, 0), QPointF(0, 1)); + gradient.setColorAt(0.25, col3.lighter( 70 ) ); + gradient.setColorAt(0.5, col1.lighter( 80 ) ); + gradient.setColorAt(1.0, col2.lighter( 90 ) ); + gradient.setCoordinateMode(QGradient::ObjectBoundingMode); + area->setBrush( gradient ); + area->setBorderColor( col1.lighter( 50 ) ); + + // fictitious area, just to have another label + QAreaSeries *area_ = new QAreaSeries( ); + area_->setBrush( gradient ); + area_->setBorderColor( col1.lighter( 50 ) ); + + // build the area + QChart *a_chart = new QChart(); + a_chart->setTheme( theme ); + a_chart->addSeries( area ); + a_chart->addSeries( area_ ); + a_chart->setTitle( QString("%1: %2 -> %3").arg( TR::tr( "Time of Day Count" ), field_1, field_2) ); + a_chart->setTitleFont( fonts.at("main") ); + a_chart->legend()->setVisible( false ); + /*a_chart->legend()->setFont( fonts.at( "main_small" ) ); + a_chart->legend()->setAlignment( Qt::AlignBottom );*/ + + // set-up the date-time axis (X) + QDateTimeAxis *axisX = new QDateTimeAxis(); + axisX->setLabelsFont( fonts.at( "main_small" ) ); + if ( period ) { + //axisX->setLabelsVisible( false ); + axisX->setFormat( "yyyy-MM" ); + int ticks = this->dbQuery.getMonthsCount( from_year, from_month, to_year, to_month ); + if ( ticks == 1 ) { + axisX->setFormat( "yyyy-MM-dd" ); + ticks = to_day.toInt() - from_day.toInt() +2; + } + axisX->setTickCount( ticks+1 ); + } else { + axisX->setFormat( "hh:mm" ); + axisX->setTickCount( 25 ); + } + axisX->setTitleText( date ); + axisX->setTitleFont( fonts.at("main_small") ); + a_chart->addAxis( axisX, Qt::AlignBottom ); + area->attachAxis( axisX ); + + // set-up the count values axis (Y) + QValueAxis *axisY = new QValueAxis(); + axisY->setLabelFormat( "%d" ); + axisY->setTickCount( ( max_count < 8 ) ? max_count : 8 ); + axisY->setRange( 0, max_count ); + axisY->setLabelsFont( fonts.at( "main_small" ) ); + a_chart->addAxis( axisY, Qt::AlignLeft ); + area->attachAxis( axisY) ; + + // add the chart to the view + chart->setChart( a_chart ); + chart->setRenderHint(QPainter::Antialiasing); + + items.clear(); + } +} + + +// calculate global informations +const bool Crapview::calcGlobals( std::vector>& recur_list, std::vector>& traffic_list, std::vector>& perf_list, std::vector& work_list, const QString& web_server ) +{ + bool result = false; + + if ( this->dates.at( this->WebServer_s2i.value( web_server ) ).size() > 0 ) { + + // { { item, count } } // 0:protocol, 1:method, 1:uri, 3:user-agent + std::vector> recurs = { {}, {}, {}, {} }; + // ( date_str, count ) + std::tuple traf_date; + // { day_name : total_count } + std::unordered_map traf_day = { {1,0}, {2,0}, {3,0}, {4,0}, {5,0}, {6,0}, {7,0} }; + // { hour : total_count } + std::unordered_map traf_hour = { + {0,0}, {1,0}, {2,0}, {3,0}, {4,0}, {5,0}, {6,0}, {7,0}, {8,0}, {9,0}, {10,0}, {11,0}, + {12,0}, {13,0}, {14,0}, {15,0}, {16,0}, {17,0}, {18,0}, {19,0}, {20,0}, {21,0}, {22,0}, {23,0} }; + // [ max, total, num ] + std::vector perf_time; + // [ max, total, num ] + std::vector perf_sent; + // [ max, total, num ] + std::vector perf_receiv; + // count + long req_count = 0; + + result = this->dbQuery.getGlobalCounts( + web_server, this->dates.at( this->WebServer_s2i.value( web_server ) ), + recurs, + traf_date, traf_day, traf_hour, + perf_time, perf_sent, perf_receiv, + req_count ); + + if ( result ) { + // compose the results + + // max request elements + for ( int i=0; i<4; i++ ) { + int max=0; + QString max_str=""; + const auto& aux = recurs.at( i ); + for ( const auto& [s,c] : aux ) { + if ( c > max ) { + max = c; + max_str = s; + } + } + recur_list.push_back( std::make_tuple( max_str, QString("%1").arg(max) ) ); + } + + // max date ever + traffic_list.push_back( std::make_tuple( std::get<0>(traf_date), QString("%1").arg( std::get<1>(traf_date) ) ) ); + + // max day of the week + double max=0, max_=0; + for ( const auto& [d,c] : traf_day ) { + if ( c > max ) { + max = c; + max_ = d; + } + } + if ( max_ == 0 ) { + traffic_list.push_back( std::make_tuple( "-", "0" ) ); + } else { + const int f = std::floor(max); + const int d = (max<10) ? (int)(max*100) % 100 : (int)(max*10) % 10; + QString count = QString("%1").arg( f ); + if ( d > 0 ) { + count += QString(".%1").arg( d ); + } + traffic_list.push_back( std::make_tuple( TR::tr(this->dbQuery.DAYS.at(max_).c_str()), count )); + } + + // max hour of the day + max=0, max_=-1; + for ( const auto& [h,c] : traf_hour ) { + if ( c > max ) { + max = c; + max_ = h; + } + } + if ( max_ < 0 ) { + traffic_list.push_back( std::make_tuple( "", "0" ) ); + } else { + const int f = std::floor(max); + const int d = (max<10) ? (int)(max*100) % 100 : (int)(max*10) % 10; + QString count = QString("%1").arg( f ); + if ( d > 0 ) { + count += QString(".%1").arg( d ); + } + QString h = (max_<10) ? QString("0%1").arg(max_) : QString("%1").arg(max_) ; + traffic_list.push_back( std::make_tuple( h, count ) ); + } + + // mean/max time-taken + perf_list.push_back( std::make_tuple( + QString("%1 ms").arg( (perf_time.at(2)>0) ? perf_time.at(1)/perf_time.at(2) : perf_time.at(1) ), + QString("%1 ms").arg( perf_time.at(0) ) )); + perf_list.push_back( std::make_tuple( + QString("%1 B").arg( (perf_sent.at(2)>0) ? perf_sent.at(1)/perf_sent.at(2) : perf_time.at(1) ), + QString("%1 B").arg( perf_sent.at(0) ) )); + perf_list.push_back( std::make_tuple( + QString("%1 B").arg( (perf_receiv.at(2)>0) ? perf_receiv.at(1)/perf_receiv.at(2) : perf_receiv.at(1) ), + QString("%1 B").arg( perf_receiv.at(0) ) )); + + // overall work list + work_list.push_back( QString("%1").arg( req_count ) ); + + float t = (float)perf_time.at(1); + if ( t < 0 ) { + work_list.push_back( "0" ); + } else { + int h=0, m=0, s=0, ms=0; + if ( t > 1000 ) { + ms = (int)t % 1000; + t /= 1000; + } + if ( t > 60 ) { + s = (int)t; + s /= 60; + if ( s > 60 ) { + m = s/60; + s = s%60; + if ( m > 60 ) { + h = m/60; + m = m%60; + } + } + } + work_list.push_back( QString("%1 h %2 m %3.%4 s").arg(h).arg(m).arg(s).arg(ms) ); + } + + float b = (float)perf_sent.at(1); + if ( b < 0 ) { + work_list.push_back( "0" ); + } else { + int f=0, d=0; + QString sfx = "B"; + if ( b > 1024 ) { + b /= 1024; + sfx = "KiB"; + if ( b > 1024 ) { + b /= 1024; + sfx = "MiB"; + if ( b > 1024 ) { + b /= 1024; + sfx = "GiB"; + } + } + } + f = b; + d = (int)( b*1000 ) %1000; + work_list.push_back( QString("%1.%2 %3").arg(f).arg(d).arg(sfx) ); + } + } + + recurs.clear(); + traf_day.clear(); traf_hour.clear(); + perf_time.clear(); perf_sent.clear(); perf_receiv.clear(); + } + + return result; +} diff --git a/logdoctor/modules/crapview/crapview.h b/logdoctor/modules/crapview/crapview.h new file mode 100644 index 00000000..93746c1f --- /dev/null +++ b/logdoctor/modules/crapview/crapview.h @@ -0,0 +1,376 @@ +#ifndef CRAPVIEW_H +#define CRAPVIEW_H + +#include +#include +#include + +#include "modules/crapview/modules/query.h" + +#include + + +//! Crapview +/*! + Performs operations related to the visualization of the statistics +*/ +class Crapview +{ +public: + Crapview(); + + //! Returns the Dialogs level + const int& getDialogsLevel(); + + //! Sets the new Dialogs level + void setDialogsLevel( const int& new_level ); + + + //! Sets the new charts theme to use + void setChartsTheme( const int& new_theme_id ); + + + //! Sets the new path for the logs Collection database + /*! + \see DbQuery::setDbPath() + */ + void setDbPath( const std::string& path ); + + + //! Parses a filter for a database field with boolean type + /*! + \param field_str The given filter + \return The resulting filter to apply at the query + */ + const QString parseBooleanFilter( const QString& filter_str ); + + //! Parses a filter for a log field with integer type + /*! + \param field_str The given filter + \return The resulting filter to apply at the query + */ + const QString parseNumericFilter( const QString& filter_str ); + + //! Parses a filter for a log field with text type + /*! + \param field_str The given filter + \return The resulting filter to apply at the query + */ + const QString parseTextualFilter( const QString& filter_str ); + + + //! Returns the printable log field corresponding to the given ID + /*! + The field gets translated to be printable before being returned + \param field_id The ID of the log fiels + \return The printable field + */ + const QString getLogFieldString ( const int& field_id ); + + //! Returns the log field ID corresponding to the given printable field + /*! + \param field_str The log field + \return The ID of the log field + */ + const int getLogFieldID ( const QString& field_str ); + + + //! Returns the month number corresponding to the given printable month + /*! + \param month_Str The printable month name + \return The month number + */ + const int getMonthNumber( const QString& month_str ); + + + //! Refreshes the list of the dates which are available in the database + void refreshDates(); + + //! Erases the list of available dates + void clearDates(); + + + //! Returns le list of available years, for the given web server + /*! + \param web_server The printable Web Server name + \return The list of yearss which are avaliable + */ + const QStringList getYears( const QString& web_server ); + + //! Returns le list of available months in the given year, for the given web server + /*! + \param web_server The printable Web Server name + \param year The year + \return The list of printable month names which are avaliable + */ + const QStringList getMonths( const QString& web_server, const QString& year ); + + //! Returns le list of available days in the given month and year, for the given web server + /*! + \param web_server The printable Web Server name + \param year The year + \param month The printable month name + \return The list of days which are avaliable + */ + const QStringList getDays( const QString& web_server, const QString& year, const QString& month ); + + //! Returns all the hours of the day + /*! + \return The list of all the hours + */ + const QStringList getHours(); + + + //! Returns a list of the fields for the given tab + /*! + \param tab The stats tab + \return The list of fields + */ + const QStringList getFields( const std::string& tab ); + + + //! Updates the database applying the changes which have been made to the table + /*! + \param table The Warnings stats table + \param web_server The printable Web Server name + */ + void updateWarn( + QTableWidget* table, + const QString& web_server ); + + + //! Draws the chart and fills the table for the Warnings stats + /*! + \param table The table widget + \param chart The chart widget + \param theme The theme to use for the chart + \param fonts The map holding the fonts + \param web_server The printable Web Server name + \param year The year + \param month The printable month name + \param day The day + \param hout The hour + */ + void drawWarn( + QTableWidget* table, QtCharts::QChartView* chart, + const QChart::ChartTheme& theme, + const std::unordered_map& fonts, + const QString& web_server, + const QString& year, const QString& month, const QString& day, const QString& hour ); + + + //! Draws the chart and fills the table for the Speed stats + /*! + \param table The table widget + \param chart The chart widget + \param theme The theme to use for the chart + \param fonts The map holding the fonts + \param web_server The printable Web Server name + \param year The year + \param month The printable month name + \param day The day + \param protocol The given filter for the Protocol + \param method The given filter for the Method + \param uri The given filter for the URI + \param query The given filter for the Query + \param response The given filter for the Response + */ + void drawSpeed( + QTableWidget* table, QtCharts::QChartView* chart, + const QChart::ChartTheme& theme, + const std::unordered_map& fonts, + const QString& web_server, + const QString& year, const QString& month, const QString& day, + const QString& protocol, const QString& method, const QString& uri, const QString& query, const QString& response ); + + + //! Draws the chart and fills the table for the Counts stats + /*! + \param table The table widget + \param chart The chart widget + \param theme The theme to use for the chart + \param fonts The map holding the fonts + \param web_server The printable Web Server name + \param year The year + \param month The printable month name + \param day The day + \param field The printable log field + */ + void drawCount( + QTableWidget* table, QtCharts::QChartView* chart, + const QChart::ChartTheme& theme, + const std::unordered_map& fonts, + const QString& web_server, + const QString& year, const QString& month, const QString& day, + const QString& field ); + + + //! Draws the chart for the Daytime stats + /*! + \param chart The chart widget + \param theme The theme to use for the chart + \param fonts The map holding the fonts + \param web_server The printable Web Server name + \param year The initial year + \param month The initial printable month name + \param day The initial day + \param year The final year + \param month The final printable month name + \param day The finl day + \param field The printable log field + \param filter The give filter string + */ + void drawDay( + QtCharts::QChartView* chart, + const QChart::ChartTheme& theme, + const std::unordered_map& fonts, + const QString& web_server, + const QString& from_year, const QString& from_month, const QString& from_day, + const QString& to_year, const QString& to_month, const QString& to_day, + const QString& field, const QString& filter ); + + + //! Draws the chart for the Relational stats + /*! + \param chart The chart widget + \param theme The theme to use for the chart + \param fonts The map holding the fonts + \param web_server The printable Web Server name + \param year The initial year + \param month The initial printable month name + \param day The initial day + \param year The final year + \param month The final printable month name + \param day The finl day + \param field_1 The first printable log field + \param filter_1 The give filter string for the first field + \param field_2 The second printable log field + \param filter_2 The give filter string for the second field + */ + void drawRelat( + QtCharts::QChartView* chart, + const QChart::ChartTheme& theme, + const std::unordered_map& fonts, + const QString& web_server, + const QString& from_year, const QString& from_month, const QString& from_day, + const QString& to_year, const QString& to_month, const QString& to_day, + const QString& field_1, const QString& filter_1, + const QString& field_2, const QString& filter_2 ); + + + //! Retrieves the data to fill the Globals stats + /*! + \param recur_list The list which will hold the printable recurrencies + \param traffic_list The list which will hold the printable traffics + \param perf_list The list which will hold the printable performances + \param work_list The list which will hold the printable overall work infos + \param web_server The printable Web Server name + \return Whether the operation has been successful or not + */ + const bool calcGlobals( + std::vector>& recur_list, + std::vector>& traffic_list, + std::vector>& perf_list, + std::vector& work_list, + const QString& web_server ); + + +private: + + // quantity of information to display throught dialogs + int dialogs_level = 2; // 0: essential, 1: usefull, 2: explanatory + + // charts theme ID + int charts_theme = 0; + + DbQuery dbQuery; + + // collection of available dates + // { web_server_id : { year : { month_str : [ days ] } } } + std::unordered_map>>> dates; + + // collection of available fields, for tabs which needs them + // { tab : [ fields ] } + const std::unordered_map> fields = { + {"Daytime", { + this->dbQuery.FIELDS.at(0),this->dbQuery.FIELDS.at(10),this->dbQuery.FIELDS.at(11),this->dbQuery.FIELDS.at(12),this->dbQuery.FIELDS.at(13),this->dbQuery.FIELDS.at(14),this->dbQuery.FIELDS.at(18),this->dbQuery.FIELDS.at(22),this->dbQuery.FIELDS.at(21),this->dbQuery.FIELDS.at(20)} }, + {"Relational", { + this->dbQuery.FIELDS.at(0),this->dbQuery.FIELDS.at(10),this->dbQuery.FIELDS.at(11),this->dbQuery.FIELDS.at(12),this->dbQuery.FIELDS.at(13),this->dbQuery.FIELDS.at(14),this->dbQuery.FIELDS.at(15),this->dbQuery.FIELDS.at(16),this->dbQuery.FIELDS.at(17),this->dbQuery.FIELDS.at(18),this->dbQuery.FIELDS.at(22),this->dbQuery.FIELDS.at(21),this->dbQuery.FIELDS.at(20)} } + }; + + + //! Returns a string of the given date in the format YYY-MM-DD + /*! + \overload const QString printableDate(const int& year, const int& month, const int& day) + \param year The year + \param month The month + \param day The day + \return The printable date + */ + const QString printableDate( const QString& year, const int& month, const QString& day ); + + //! Returns a string of the given date in the format YYY-MM-DD + /*! + \param year The year + \param month The month + \param day The day + \return The printable date + */ + const QString printableDate( const int& year, const int& month, const int& day ); + + //! Returns a string of the given time in the format HH:MM:SS + /*! + \param hour The hour + \param minut The minute + \param second The second + \return The printable time + */ + const QString printableTime( const int& hour, const int& minute, const int& second ); + + //! Returns a string corresponding to the given value + /*! + Used to convert numeric booleans [0,1] to string [FALSE,TRUE] + \param value The value to convert + \return The corresponding printable string + */ + const QString printableWarn( const int& value ); + + + // converr Web Servers names to Web Server IDs + const QHash WebServer_s2i = { + {"apache",11}, {"nginx",12}, {"iis",13} }; + + // convert log fields to log fields IDs + const QHash LogFields_s2i = { + {QString::fromStdString(this->dbQuery.FIELDS.at( 0)), 0}, + {QString::fromStdString(this->dbQuery.FIELDS.at(10)), 10}, + {QString::fromStdString(this->dbQuery.FIELDS.at(11)), 11}, + {QString::fromStdString(this->dbQuery.FIELDS.at(12)), 12}, + {QString::fromStdString(this->dbQuery.FIELDS.at(13)), 13}, + {QString::fromStdString(this->dbQuery.FIELDS.at(14)), 14}, + {QString::fromStdString(this->dbQuery.FIELDS.at(15)), 15}, + {QString::fromStdString(this->dbQuery.FIELDS.at(16)), 16}, + {QString::fromStdString(this->dbQuery.FIELDS.at(17)), 17}, + {QString::fromStdString(this->dbQuery.FIELDS.at(18)), 18}, + {QString::fromStdString(this->dbQuery.FIELDS.at(20)), 20}, + {QString::fromStdString(this->dbQuery.FIELDS.at(21)), 21}, + {QString::fromStdString(this->dbQuery.FIELDS.at(22)), 22}}; + + // convert months names to months numbers + const QHash Months_s2i = { + {QString::fromStdString(this->dbQuery.MONTHS.at(1)), 1}, + {QString::fromStdString(this->dbQuery.MONTHS.at(2)), 2}, + {QString::fromStdString(this->dbQuery.MONTHS.at(3)), 3}, + {QString::fromStdString(this->dbQuery.MONTHS.at(4)), 4}, + {QString::fromStdString(this->dbQuery.MONTHS.at(5)), 5}, + {QString::fromStdString(this->dbQuery.MONTHS.at(6)), 6}, + {QString::fromStdString(this->dbQuery.MONTHS.at(7)), 7}, + {QString::fromStdString(this->dbQuery.MONTHS.at(8)), 8}, + {QString::fromStdString(this->dbQuery.MONTHS.at(9)), 9}, + {QString::fromStdString(this->dbQuery.MONTHS.at(10)), 10}, + {QString::fromStdString(this->dbQuery.MONTHS.at(11)), 11}, + {QString::fromStdString(this->dbQuery.MONTHS.at(12)), 12}}; + +}; + +#endif // CRAPVIEW_H diff --git a/logdoctor/modules/crapview/modules/query.cpp b/logdoctor/modules/crapview/modules/query.cpp new file mode 100644 index 00000000..83691ab0 --- /dev/null +++ b/logdoctor/modules/crapview/modules/query.cpp @@ -0,0 +1,2148 @@ + +#include "query.h" + +#include "modules/dialogs.h" +#include "modules/exceptions.h" +#include "utilities/strings.h" + +#include +#include +#include +#include +#include +#include + + +DbQuery::DbQuery() +{ + +} + +void DbQuery::setDialogLevel(const int& new_level ) +{ + this->dialog_level = new_level; +} + +void DbQuery::setDbPath( const std::string& path ) +{ + this->db_path = path; + this->db_name = QString::fromStdString( this->db_path.substr( this->db_path.find_last_of( '/' ) + 1 ) ); +} + + +const int DbQuery::getMinuteGap( const int& minute , const int& gap ) +{ + int m = -1; + if ( minute < 0 || minute >= 60 ) { + // unexpected value + throw DateTimeException( "Unexpected Minute: "+std::to_string( minute ) ); + } + int n = 0; + for ( int g=0; g<60; g+=gap ) { + if ( minute >= g && minute < g+gap ) { + m = gap * n; + break; + } + n++; + } + return m; +} + +const int DbQuery::getMonthDays( const int& year, const int& month ) +{ + int n_days; + switch (month) { + case 1: n_days = 31; break; + case 2: n_days = ( year%4 == 0 ) ? 29 : 28 ; break; + case 3: n_days = 31; break; + case 4: n_days = 30; break; + case 5: n_days = 31; break; + case 6: n_days = 30; break; + case 7: n_days = 31; break; + case 8: n_days = 31; break; + case 9: n_days = 30; break; + case 10: n_days = 31; break; + case 11: n_days = 30; break; + case 12: n_days = 31; break; + default: + // unexpected month + throw DateTimeException( "Unexpected Month: "+std::to_string( month ) ); + } + return n_days; +} + +const int DbQuery::getMonthsCount( const QString& from_year, const QString& from_month, const QString& to_year, const QString& to_month ) +{ + int from_year_, from_month_, to_year_, to_month_; + try { + from_year_ = from_year.toInt(); + from_month_ = this->getMonthNumber( from_month ); + to_year_ = ( to_year.size() == 0 ) ? from_year_ : to_year.toInt() ; + to_month_ = ( to_month.size() == 0 ) ? from_month_ : this->getMonthNumber( to_month ) ; + } catch (...) { + // failed to convert to integers + throw DateTimeException( "Failed to convert Month from string to int" ); // leave un-catched + } + return this->getMonthsCount( from_year_, from_month_, to_year_, to_month_ ); +} + +const int DbQuery::getMonthsCount( const int& from_year, const int& from_month, const int& to_year, const int& to_month ) +{ + int n_months = 0; + if ( from_year == to_year ) { + // same year + if ( from_month == to_month ) { + // same month + n_months = 1; + } else { + // different months + n_months = to_month - from_month + 1; + } + } else { + // different years + n_months += 13 - from_month; // months to the end of the first year + n_months += to_month; // months from the beginning of the last year + n_months += 12 * ( to_year - from_year - 1 ); // 12 months for every middle year (0 if none) + } + return n_months; +} + + +const int DbQuery::getMonthNumber( const QString& month_str ) +{ + int m=0; + for ( const auto& [num,str] : this->MONTHS ) { + if ( TR::tr(str.c_str()) == month_str ) { + m = num; + break; + } + } + return m; +} + + +/*const int DbQuery::getLogFieldID ( const QString& field_str ) +{ + int f=0; + for ( const auto& [id,str] : this->MONTHS ) { + if ( TR::tr(str.c_str()) == field_str ) { + f = id; + break; + } + } + return f; +}*/ + +const QString DbQuery::getDbField( const QString& tr_fld ) +{ + QString f; + for ( const auto& [id,str] : this->FIELDS ) { + if ( TR::tr(str.c_str()) == tr_fld ) { + f = this->LogFields_to_DbFields.at( str ); + break; + } + } + return f; +} + + + +// get a fresh map of available dates +void DbQuery::refreshDates(std::tuple>>>> &result) +{ + bool successful = true; + std::unordered_map>>> dates = { + {11, {}}, {12, {}}, {13, {}} }; + + QSqlDatabase db; + if ( QSqlDatabase::contains("qt_sql_default_connection") ) { + db = QSqlDatabase::database("qt_sql_default_connection"); + } else { + db = QSqlDatabase::addDatabase("QSQLITE"); + } + db.setDatabaseName( QString::fromStdString( this->db_path )); + + if ( ! db.open() ) { + // error opening database + successful = false; + QString err_msg = ""; + if ( this->dialog_level == 2 ) { + err_msg = db.lastError().text(); + } + DialogSec::errDatabaseFailedOpening( this->db_name, err_msg ); + + } else { + // recursively query years, months and days for every WebServer + std::vector> tables = { + std::make_tuple(11,"apache"), + std::make_tuple(12,"nginx"), + std::make_tuple(13,"iis") }; + + QSqlQuery Y_query = QSqlQuery( db ), + M_query = QSqlQuery( db ), + D_query = QSqlQuery( db ); + + for ( const auto& table : tables ) { + if ( ! successful ) { break; } + + int ws = std::get<0>(table); + QString tbl = std::get<1>(table); + + if ( ! Y_query.exec( QString("SELECT DISTINCT \"year\" FROM \"%1\" ORDER BY \"year\" ASC;").arg(tbl) ) ) { + // error querying database + successful = false; + DialogSec::errDatabaseFailedExecuting( this->db_name, Y_query.lastQuery(), Y_query.lastError().text() ); + break; + + } else { + int year, month, day; + while ( Y_query.next() ) { + try { + year = Y_query.value(0).toInt(); + } catch (...) { + // failed to convert to integer + successful = false; + QString err_msg = TR::tr(this->MSG_ERR_PARSING_YMD.c_str()).arg( TR::tr(this->WORD_YEARS.c_str()) ); + if ( this->dialog_level > 0 ) { + err_msg += QString("\n\n%1:\n%2").arg( TR::tr(this->MSG_RESPONSIBLE_VALUE.c_str()), Y_query.value(0).toString() ); + if ( this->dialog_level == 2 ) { + err_msg += QString("\n\n%1:\n%2").arg( TR::tr(this->MSG_TABLE_NAME.c_str()), tbl ); + } + } + DialogSec::errGeneric( err_msg ); + break; + } + // successfully get the year + dates.at( ws ).emplace( year, std::unordered_map>() ); + // query any available month + if ( ! M_query.exec( QString("SELECT DISTINCT \"month\" FROM \"%1\" WHERE \"year\"=%2 ORDER BY \"month\" ASC;").arg(tbl).arg(year) ) ) { + // error querying database + successful = false; + DialogSec::errDatabaseFailedExecuting( this->db_name, M_query.lastQuery(), M_query.lastError().text() ); + break; + + } else { + while ( M_query.next() ) { + try { + month = M_query.value(0).toInt(); + } catch (...) { + // failed to convert to integer + successful = false; + QString err_msg = TR::tr(this->MSG_ERR_PARSING_YMD.c_str()).arg( TR::tr(this->WORD_MONTHS.c_str()) ); + if ( this->dialog_level > 0 ) { + err_msg += QString("\n\n%1:\n%2").arg( TR::tr(this->MSG_RESPONSIBLE_VALUE.c_str()), M_query.value(0).toString() ); + if ( this->dialog_level == 2 ) { + err_msg += QString("\n\n%1:\n%2").arg( TR::tr(this->MSG_TABLE_NAME.c_str()), tbl ); + } + } + DialogSec::errGeneric( err_msg ); + break; + } + // successfully get the month + dates.at( ws ).at( year ).emplace( month, std::vector() ); + // query any available day + if ( ! D_query.exec( QString("SELECT DISTINCT \"day\" FROM \"%1\" WHERE \"year\"=%2 AND \"month\"=%3 ORDER BY \"day\" ASC;").arg(tbl).arg(year).arg(month) ) ) { + // error querying database + successful = false; + DialogSec::errDatabaseFailedExecuting( this->db_name, D_query.lastQuery(), D_query.lastError().text() ); + break; + + } else { + while ( D_query.next() ) { + try { + day = D_query.value(0).toInt(); + } catch (...) { + // failed to convert to integer + successful = false; + QString err_msg = TR::tr(this->MSG_ERR_PARSING_YMD.c_str()).arg( TR::tr(this->WORD_DAYS.c_str()) ); + if ( this->dialog_level > 0 ) { + err_msg += QString("\n\n%1:\n%2").arg( TR::tr(this->MSG_RESPONSIBLE_VALUE.c_str()), D_query.value(0).toString() ); + if ( this->dialog_level == 2 ) { + err_msg += QString("\n\n%1:\n%2").arg( TR::tr(this->MSG_TABLE_NAME.c_str()), tbl ); + } + } + DialogSec::errGeneric( err_msg ); + break; + } + // successfully get the day + dates.at( ws ).at( year ).at( month ).push_back( day ); + } + D_query.finish(); + // break if something went wrong + if ( ! successful ) { break; } + } + } + M_query.finish(); + // break if something went wrong + if ( ! successful ) { break; } + } + } + Y_query.finish(); + // break if something went wrong + if ( ! successful ) { break; } + } + } + } + + if ( ! successful ) { + dates.clear(); + } + if ( db.isOpen() ) { + db.close(); + } + result = std::make_tuple( successful, dates ); +} + + +// update the values for the warnings +void DbQuery::updateWarnings( const QString& web_server, const std::vector>& updates ) +{ + bool successful = true; + + QSqlDatabase db; + if ( QSqlDatabase::contains("qt_sql_default_connection") ) { + db = QSqlDatabase::database("qt_sql_default_connection"); + } else { + db = QSqlDatabase::addDatabase("QSQLITE"); + } + db.setDatabaseName( QString::fromStdString( this->db_path )); + + if ( ! db.open() ) { + // error opening database + QString err_msg = ""; + if ( this->dialog_level == 2 ) { + err_msg = db.lastError().text(); + } + DialogSec::errDatabaseFailedOpening( this->db_name, err_msg ); + + } else { + if ( web_server != "apache" && web_server != "nginx" && web_server != "iis" ) { + // unexpected WebServer + successful = false; + DialogSec::errGeneric( QString("%1:\n%2").arg( TR::tr(this->MSG_ERR_UNX_WS.c_str()), web_server ), true ); + } + + if ( successful ) { + // update the database + QSqlQuery query = QSqlQuery( db ); + + for ( const auto& data : updates ) { + // build the query statement + QString stmt = QString("UPDATE \"%1\" SET warning=%2 WHERE rowid=%3;") + .arg( web_server ) + .arg( std::get<1>(data) ) + .arg( std::get<0>(data) ); + + if ( ! query.exec( stmt.replace("'","''") ) ) { + // error querying database + DialogSec::errDatabaseFailedExecuting( this->db_name, query.lastQuery(), query.lastError().text() ); + break; + } + } + } + } + if ( db.isOpen() ) { + db.close(); + } +} + + +// get daytime values for the warnings +void DbQuery::getWarnCounts( std::tuple>>>> &result, const QString& web_server, const QString& year_, const QString& month_, const QString& day_, const QString& hour_ ) +{ + bool successful = true; + std::vector>>> items; + + QSqlDatabase db; + if ( QSqlDatabase::contains("qt_sql_default_connection") ) { + db = QSqlDatabase::database("qt_sql_default_connection"); + } else { + db = QSqlDatabase::addDatabase("QSQLITE"); + } + db.setDatabaseName( QString::fromStdString( this->db_path )); + + if ( ! db.open() ) { + // error opening database + successful = false; + QString err_msg = ""; + if ( this->dialog_level == 2 ) { + err_msg = db.lastError().text(); + } + DialogSec::errDatabaseFailedOpening( this->db_name, err_msg ); + + } else { + if ( web_server != "apache" && web_server != "nginx" && web_server != "iis" ) { + // unexpected WebServer + successful = false; + DialogSec::errGeneric( QString("%1:\n%2").arg( TR::tr(this->MSG_ERR_UNX_WS.c_str()), web_server ), true ); + } + int year, month, day, hour; + if ( successful ) { + // setup period limits + try { + year = year_.toInt(); + month = this->getMonthNumber( month_ ); + day = day_.toInt(); + if ( hour_.size() > 0 ) { + hour = hour_.toInt(); + } + } catch (...) { + // failed to convert to integers + successful = false; + DialogSec::errGeneric( TR::tr(this->MSG_ERR_PROCESSING_DATES.c_str()), true ); + } + } + if ( successful ) { + // build the query statement + QSqlQuery query = QSqlQuery( db ); + QString stmt = QString("SELECT rowid, * FROM \"%1\" WHERE \"year\"=%2 AND \"month\"=%3 AND \"day\"=%4") + .arg( web_server ) + .arg( year ).arg( month ).arg( day ); + + if ( hour_.size() == 0 ) { + // entire day + for ( int h=0; h<24; h++ ) { + items.push_back( std::vector>>() ); + std::vector>>& aux = items.at( h ); + for ( int m=0; m<60; m+=10 ) { + aux.push_back( std::vector>() ); + } + } + + stmt += " ORDER BY \"hour\",\"minute\",\"second\" ASC;"; + if ( ! query.exec( stmt.replace("'","''") ) ) { + // error querying database + successful = false; + DialogSec::errDatabaseFailedExecuting( this->db_name, query.lastQuery(), query.lastError().text() ); + + } else { + try { + // get query data + while ( query.next() ) { + std::vector aux; + for ( int i=1; i<13; i++ ) { + aux.push_back( query.value( i ).toString() ); + } + for ( int i=19; i>12; i-- ) { + aux.push_back( query.value( i ).toString() ); + } + aux.push_back( query.value( 0 ).toString() ); + // append the line + items.at( query.value(5).toInt() ) + .at( this->getMinuteGap( query.value(6).toInt() )/10 ) + .push_back( aux ); + } + } catch (...) { + // something failed + successful = false; + DialogSec::errGeneric( TR::tr(this->MSG_ERR_PROCESSING.c_str()), true ); + } + } + + } else { + // 1 hour + for ( int g=0; g<6; g++ ) { + items.push_back( std::vector>>() ); + std::vector>>& aux = items.at( g ); + for ( int m=0; m<10; m++ ) { + aux.push_back( std::vector>() ); + } + } + + stmt += QString(" AND \"hour\"=%5 ORDER BY \"minute\",\"second\" ASC;").arg( hour ); + if ( ! query.exec( stmt.replace("'","''") ) ) { + // error querying database + successful = false; + DialogSec::errDatabaseFailedExecuting( this->db_name, query.lastQuery(), query.lastError().text() ); + + } else { + try { + // get query data + while ( query.next() ) { + std::vector aux; + for ( int i=1; i<13; i++ ) { + aux.push_back( query.value( i ).toString() ); + } + for ( int i=19; i>12; i-- ) { + aux.push_back( query.value( i ).toString() ); + } + aux.push_back( query.value( 0 ).toString() ); + // append the line + items.at( this->getMinuteGap( query.value(6).toInt() )/10 ) + .at( query.value(6).toInt()%10 ) + .push_back( aux ); + } + } catch (...) { + // something failed + successful = false; + DialogSec::errGeneric( TR::tr(this->MSG_ERR_PROCESSING.c_str()), true ); + } + } + } + } + } + if ( ! successful ) { + items.clear(); + } + if ( db.isOpen() ) { + db.close(); + } + result = std::make_tuple( successful, items ); +} + + +// get day-time values for the time-taken field +void DbQuery::getSpeedData(std::tuple>>>& result, const QString& web_server, const QString& year_, const QString& month_, const QString& day_, const QString& protocol_f, const QString& method_f, const QString& uri_f, const QString& query_f, const QString& response_f ) +{ + bool successful = true; + std::vector>> data; + + QSqlDatabase db; + if ( QSqlDatabase::contains("qt_sql_default_connection") ) { + db = QSqlDatabase::database("qt_sql_default_connection"); + } else { + db = QSqlDatabase::addDatabase("QSQLITE"); + } + db.setDatabaseName( QString::fromStdString( this->db_path )); + + if ( ! db.open() ) { + // error opening database + successful = false; + QString err_msg = ""; + if ( this->dialog_level == 2 ) { + err_msg = db.lastError().text(); + } + DialogSec::errDatabaseFailedOpening( this->db_name, err_msg ); + + } else { + if ( web_server != "apache" && web_server != "nginx" && web_server != "iis" ) { + // unexpected WebServer + successful = false; + DialogSec::errGeneric( QString("%1:\n%2").arg( TR::tr(this->MSG_ERR_UNX_WS.c_str()), web_server ), true ); + } + int year, month, day; + if ( successful ) { + // setup period limits + try { + year = year_.toInt(); + month = this->getMonthNumber( month_ ); + day = day_.toInt(); + } catch (...) { + // failed to convert to integers + successful = false; + DialogSec::errGeneric( TR::tr(this->MSG_ERR_PROCESSING_DATES.c_str()), true ); + } + } + if ( successful ) { + QDateTime time; + time.setDate( QDate( year, month , day ) ); + // build the query statement + QSqlQuery query = QSqlQuery( db ); + QString stmt; + + // prepare the statement + stmt = QString("SELECT \"hour\",\"minute\",\"second\",\"time_taken\",\"uri\",\"query\",\"method\",\"protocol\",\"response\" FROM \"%1\" WHERE \"year\"=%2 AND \"month\"=%3 AND \"day\"=%4 AND \"time_taken\" IS NOT NULL") + .arg( web_server ) + .arg( year ).arg( month ).arg( day ); + + // apply a filter if present + if ( protocol_f.size() > 0 ) { + if ( protocol_f == "NULL" ) { + // only select NULL values + stmt += QString(" AND \"protocol\" IS NULL"); + } else if ( protocol_f == "NOT NULL" ) { + // only select non-NULL values + stmt += QString(" AND \"protocol\" IS NOT NULL"); + } else { + stmt += QString(" AND \"protocol\" LIKE '%1' || '%'") + .arg( QString(protocol_f).replace("'","''") ); + } + } + if ( method_f.size() > 0 ) { + if ( method_f == "NULL" ) { + // only select NULL values + stmt += QString(" AND \"method\" IS NULL"); + } else if ( method_f == "NOT NULL" ) { + // only select non-NULL values + stmt += QString(" AND \"method\" IS NOT NULL"); + } else { + stmt += QString(" AND \"method\" LIKE '%1' || '%'") + .arg( QString(method_f).replace("'","''") ); + } + } + if ( uri_f.size() > 0 ) { + if ( uri_f == "NULL" ) { + // only select NULL values + stmt += QString(" AND \"uri\" IS NULL"); + } else if ( uri_f == "NOT NULL" ) { + // only select non-NULL values + stmt += QString(" AND \"uri\" IS NOT NULL"); + } else { + stmt += QString(" AND \"uri\" LIKE '%1' || '%'") + .arg( QString(uri_f).replace("'","''") ); + } + } + if ( query_f.size() > 0 ) { + if ( query_f == "NULL" ) { + // only select NULL values + stmt += QString(" AND \"query\" IS NULL"); + } else if ( query_f == "NOT NULL" ) { + // only select non-NULL values + stmt += QString(" AND \"query\" IS NOT NULL"); + } else { + stmt += QString(" AND \"query\" LIKE '%1' || '%'") + .arg( QString(query_f).replace("'","''") ); + } + } + if ( response_f.size() > 0 ) { + // numbers + if ( response_f == "NULL" ) { + // only select NULL values + stmt += QString(" AND \"response\" IS NULL"); + } else if ( response_f == "NOT NULL" ) { + // only select non-NULL values + stmt += QString(" AND \"response\" IS NOT NULL"); + } else { + QString filter; + if ( StringOps::isNumeric( response_f.toStdString() ) ) { + // no operator found, set defult to '=' + filter = QString("=%1").arg( response_f ); + } else { + filter = response_f; + } + stmt += QString(" AND \"response\"%1") + .arg( filter.replace("'","''") ); + } + } + + stmt += QString(" ORDER BY \"hour\",\"minute\",\"second\" ASC;"); + if ( ! query.exec( stmt ) ) { + // error querying database + successful = false; + DialogSec::errDatabaseFailedExecuting( this->db_name, query.lastQuery(), query.lastError().text() ); + + } else { + try { + + if ( query.size() == 0 ) { + // no result found + ; + + } else { + // get query data + int hour=-1, aux_hour, prev_hour=0, h, + minute=0, aux_minute, prev_minute=0, m, + second=0, aux_second, prev_second=0, s; + QString tt, ur, qr, mt, pt, rs; + while ( query.next() ) { + aux_hour = query.value(0).toInt(); + aux_minute = query.value(1).toInt(); + aux_second = query.value(2).toInt(); + + if ( aux_hour == hour && aux_minute == minute && aux_second == second ) { + time.setTime( QTime( hour, minute, second )); + data.push_back( std::make_tuple( + time.toMSecsSinceEpoch(), + std::vector{tt,ur,qr,mt,pt,rs} )); + } else { + if ( aux_hour == hour ) { + h=hour; m=minute; s=second-1; + if ( s < 0 ) { + s=59; m--; + if ( m < 0 ) { + m=59; h--; + if ( h < 0 ) { + h=m=s=0; + } + } + } + // append the second before the last one found, if it is not equal to the prev + if ( prev_hour < h || prev_minute < m || prev_second < s ) { + time.setTime( QTime( h, m, s )); + data.push_back( std::make_tuple( + time.toMSecsSinceEpoch(), + std::vector{"","","","","",""} )); + } + // same hour new minute/second, append the last count + time.setTime( QTime( hour, minute, second )); + data.push_back( std::make_tuple( + time.toMSecsSinceEpoch(), + std::vector{tt,ur,qr,mt,pt,rs} )); + // append the second after the last one found, if it is not equal to the next + h=hour; m=minute; s=second+1; + if ( s > 59 ) { + s=0; m++; + if ( m > 59 ) { + m=0; h++; + if ( h > 23 ) { + h=23;m=59;s=59; + } + } + } + if ( aux_hour > h || aux_minute > m || aux_second > s ) { + time.setTime( QTime( h, m, s )); + data.push_back( std::make_tuple( + time.toMSecsSinceEpoch(), + std::vector{"","","","","",""} )); + } + prev_hour = hour; // update now to avoid getting aux_hour's value + } else { + // minute & second are always different when the hour is different + if ( hour >= 0 ) { + // here only in the first round of the loop + // append the prev as zero + h=hour; m=minute; s=second-1; + if ( s < 0 ) { + s=59; m--; + if ( m < 0 ) { + m=59; h--; + if ( h < 0 ) { + h=m=s=0; + } + } + } + if ( prev_hour < h || prev_minute < m || prev_second < s ) { + time.setTime( QTime( h, m, s )); + data.push_back( std::make_tuple( + time.toMSecsSinceEpoch(), + std::vector{"","","","","",""} )); + } + // apend the last p count if not in the first round of the loop + time.setTime( QTime( hour, minute, second )); + data.push_back( std::make_tuple( + time.toMSecsSinceEpoch(), + std::vector{tt,ur,qr,mt,pt,rs} )); + // append the next as zero + h=hour; m=minute; s=second+1; + if ( s > 59 ) { + s=0; m++; + if ( m > 59 ) { + m=0; h++; + if ( h > 23 ) { + h=23;m=59;s=59; + } + } + } + if ( aux_hour > h || aux_minute > m || aux_second > s ) { + time.setTime( QTime( h, m, s )); + data.push_back( std::make_tuple( + time.toMSecsSinceEpoch(), + std::vector{"","","","","",""} )); + } + } else { + // append the second 0 of the day, if it is not the next found + if ( aux_hour > 0 || aux_minute > 0 || aux_second > 0 ) { + time.setTime( QTime( 0, 0, 0 )); + data.push_back( std::make_tuple( + time.toMSecsSinceEpoch(), + std::vector{"","","","","",""} )); + // append the second before the first found + h=aux_hour; m=aux_minute; s=aux_second-1; + if ( s < 0 ) { + s=59; m--; + if ( m < 0 ) { + m=59; h--; + if ( h < 0 ) { + // abort + h=m=s=0; + } + } + } + if ( h > 0 || m > 0 || s > 0 ) { + time.setTime( QTime( h, m, s )); + data.push_back( std::make_tuple( + time.toMSecsSinceEpoch(), + std::vector{"","","","","",""} )); + } + } + } + prev_hour = hour; + hour = aux_hour; + } + prev_minute = minute; + minute = aux_minute; + prev_second = second; + second = aux_second; + } + tt = query.value(3).toString(); + ur = query.value(4).toString(); + qr = query.value(5).toString(); + mt = query.value(6).toString(); + pt = query.value(7).toString(); + rs = query.value(8).toString(); + } + // last one, append the prev + h=hour; m=minute; s=second-1; + if ( s < 0 ) { + s=59; m--; + if ( m < 0 ) { + m=59; h--; + if ( h < 0 ) { + h=m=s=0; + } + } + } + if ( prev_hour < h || prev_minute < m || prev_second < s ) { + time.setTime( QTime( h, m, s )); + data.push_back( std::make_tuple( + time.toMSecsSinceEpoch(), + std::vector{"","","","","",""} )); + } + // append the last count + time.setTime( QTime( hour, minute, second )); + data.push_back( std::make_tuple( + time.toMSecsSinceEpoch(), + std::vector{tt,ur,qr,mt,pt,rs} )); + // append 1 second after the last + h=hour; m=minute; s=second+1; + if ( s > 59 ) { + s=0; m++; + if ( m > 59 ) { + m=0; h++; + if ( h > 23 ) { + h=23;m=59;s=59; + } + } + } + if ( h > hour || m > minute || s > second ) { + time.setTime( QTime( h, m, s )); + data.push_back( std::make_tuple( + time.toMSecsSinceEpoch(), + std::vector{"","","","","",""} )); + } + // append the real last fictitious count + day ++; + if ( day > this->getMonthDays( year, month ) ) { + day = 1; + month ++; + if ( month > 12 ) { + month = 1; + year ++; + } + } + time.setDate( QDate( year, month , day ) ); + time.setTime( QTime( 0, 0, 0 )); + data.push_back( std::make_tuple( + time.toMSecsSinceEpoch(), + std::vector{"","","","","",""} )); + } + } catch (...) { + // something failed + successful = false; + DialogSec::errGeneric( TR::tr(this->MSG_ERR_PROCESSING.c_str()), true ); + } + } + } + } + + if ( ! successful ) { + data.clear(); + } + if ( db.isOpen() ) { + db.close(); + } + result = std::make_tuple( successful, data ); +} + + + +// get, group and count identical items of a specific field in a date +void DbQuery::getItemsCount( std::tuple>>& result, const QString& web_server, const QString& year, const QString& month, const QString& day, const QString& log_field ) +{ + bool successful = true; + QHash aux_items; + std::vector> items; + + QSqlDatabase db; + if ( QSqlDatabase::contains("qt_sql_default_connection") ) { + db = QSqlDatabase::database("qt_sql_default_connection"); + } else { + db = QSqlDatabase::addDatabase("QSQLITE"); + } + db.setDatabaseName( QString::fromStdString( this->db_path )); + + if ( ! db.open() ) { + // error opening database + successful = false; + QString err_msg = ""; + if ( this->dialog_level == 2 ) { + err_msg = db.lastError().text(); + } + DialogSec::errDatabaseFailedOpening( this->db_name, err_msg ); + + } else { + if ( web_server != "apache" && web_server != "nginx" && web_server != "iis" ) { + // unexpected WebServer + successful = false; + DialogSec::errGeneric( QString("%1:\n%2").arg( TR::tr(this->MSG_ERR_UNX_WS.c_str()), web_server ), true ); + } + if ( successful ) { + // build the query statement + QSqlQuery query = QSqlQuery( db ); + QString stmt = QString("SELECT \"%1\" FROM \"%2\" WHERE \"%3\" IS NOT NULL AND \"year\"=%4 AND \"month\"=%5 AND \"day\"=%6;") + .arg( this->getDbField( log_field ), + web_server, + this->getDbField( log_field ), + year, + QString::fromStdString( std::to_string( this->getMonthNumber( month ) )), + day ); + // quary the database + if ( ! query.exec( stmt.replace("'","''") ) ) { + // error querying database + successful = false; + DialogSec::errDatabaseFailedExecuting( this->db_name, query.lastQuery(), query.lastError().text() ); + + } else { + try { + // get data + QString item; + while ( query.next() ) { + item = query.value(0).toString(); + if ( item.size() > 0 ) { + if ( aux_items.find( item ) == aux_items.end() ) { + // not present yet + aux_items.insert( item, 1 ); + } else { + // already in the list, increase the count + aux_items[ item ] ++; + } + } + } + } catch (...) { + // something failed + successful = false; + DialogSec::errGeneric( TR::tr(this->MSG_ERR_PROCESSING.c_str()), true ); + } + } + } + if ( successful ) { + // sort the list + std::tuple item; + // morph tha HashMap into a Vector of Tuples + foreach ( const QString& v, aux_items.keys() ) { + item = std::make_tuple( v, aux_items.value( v ) ); + items.push_back( item ); + } + // sort the vector + for ( int i=0; i(items.at( i )) > std::get<1>(items.at( j )) ) { + item = items.at( i ); + items.at( i ) = items.at( j ); + items.at( j ) = item; + } + } + } + } + aux_items.clear(); + } + + if ( ! successful ) { + items.clear(); + } + if ( db.isOpen() ) { + db.close(); + } + result = std::make_tuple( successful, items ); +} + + + +// get and count items with a 10 minutes gap for every hour of the day +void DbQuery::getDaytimeCounts( std::tuple>>& result, const QString& web_server, const QString& from_year_, const QString& from_month_, const QString& from_day_, const QString& to_year_, const QString& to_month_, const QString& to_day_, const QString& log_field_, const QString& field_filter ) +{ + bool successful = true; + std::unordered_map> data = { + {0, {{0,0},{10,0},{20,0},{30,0},{40,0},{50,0}}}, {1, {{0,0},{10,0},{20,0},{30,0},{40,0},{50,0}}}, + {2, {{0,0},{10,0},{20,0},{30,0},{40,0},{50,0}}}, {3, {{0,0},{10,0},{20,0},{30,0},{40,0},{50,0}}}, + {4, {{0,0},{10,0},{20,0},{30,0},{40,0},{50,0}}}, {5, {{0,0},{10,0},{20,0},{30,0},{40,0},{50,0}}}, + {6, {{0,0},{10,0},{20,0},{30,0},{40,0},{50,0}}}, {7, {{0,0},{10,0},{20,0},{30,0},{40,0},{50,0}}}, + {8, {{0,0},{10,0},{20,0},{30,0},{40,0},{50,0}}}, {9, {{0,0},{10,0},{20,0},{30,0},{40,0},{50,0}}}, + {10, {{0,0},{10,0},{20,0},{30,0},{40,0},{50,0}}}, {11, {{0,0},{10,0},{20,0},{30,0},{40,0},{50,0}}}, + {12, {{0,0},{10,0},{20,0},{30,0},{40,0},{50,0}}}, {13, {{0,0},{10,0},{20,0},{30,0},{40,0},{50,0}}}, + {14, {{0,0},{10,0},{20,0},{30,0},{40,0},{50,0}}}, {15, {{0,0},{10,0},{20,0},{30,0},{40,0},{50,0}}}, + {16, {{0,0},{10,0},{20,0},{30,0},{40,0},{50,0}}}, {17, {{0,0},{10,0},{20,0},{30,0},{40,0},{50,0}}}, + {18, {{0,0},{10,0},{20,0},{30,0},{40,0},{50,0}}}, {19, {{0,0},{10,0},{20,0},{30,0},{40,0},{50,0}}}, + {20, {{0,0},{10,0},{20,0},{30,0},{40,0},{50,0}}}, {21, {{0,0},{10,0},{20,0},{30,0},{40,0},{50,0}}}, + {22, {{0,0},{10,0},{20,0},{30,0},{40,0},{50,0}}}, {23, {{0,0},{10,0},{20,0},{30,0},{40,0},{50,0}}}, + }; + + QSqlDatabase db; + if ( QSqlDatabase::contains("qt_sql_default_connection") ) { + db = QSqlDatabase::database("qt_sql_default_connection"); + } else { + db = QSqlDatabase::addDatabase("QSQLITE"); + } + db.setDatabaseName( QString::fromStdString( this->db_path )); + + if ( ! db.open() ) { + // error opening database + successful = false; + QString err_msg = ""; + if ( this->dialog_level == 2 ) { + err_msg = db.lastError().text(); + } + DialogSec::errDatabaseFailedOpening( this->db_name, err_msg ); + + } else { + if ( web_server != "apache" && web_server != "nginx" && web_server != "iis" ) { + // unexpected WebServer + successful = false; + DialogSec::errGeneric( QString("%1:\n%2").arg( TR::tr(this->MSG_ERR_UNX_WS.c_str()), web_server ), true ); + } + int from_year, from_month, from_day, + to_year, to_month, to_day; + if ( successful ) { + // setup period limits + try { + from_year = from_year_.toInt(); + from_month = this->getMonthNumber( from_month_ ); + from_day = from_day_.toInt(); + to_year = ( to_year_.size() == 0 ) ? from_year : to_year_.toInt() ; + to_month = ( to_month_.size() == 0 ) ? from_month : this->getMonthNumber( to_month_ ) ; + to_day = ( to_day_.size() == 0 ) ? from_day : to_day_.toInt() ; + } catch (...) { + // failed to convert to integers + successful = false; + DialogSec::errGeneric( TR::tr(this->MSG_ERR_PROCESSING_DATES.c_str()), true ); + } + } + if ( successful ) { + // build the query statement + QSqlQuery query = QSqlQuery( db ); + QString stmt; + QString log_field = this->getDbField( log_field_ ); + + int n_days = 0, + n_months = this->getMonthsCount( from_year, from_month, to_year, to_month ); + + int year = from_year, + month = from_month, + day, hour, minute; + QList days_l; + + if ( n_months == 1 ) { + // 1 month, no need to loop + stmt = QString("SELECT \"day\", \"hour\", \"minute\" FROM \"%1\" WHERE \"year\"=%2 AND \"month\"=%3 AND \"day\">=%4 AND \"day\"<=%5") + .arg( web_server ) + .arg( year ).arg( month ) + .arg( from_day ).arg( to_day ); + + // apply a filter if present + if ( field_filter.size() > 0 ) { + QString filter = field_filter; + if ( filter == "NULL" ) { + // only select NULL values + stmt += QString(" AND \"%1\" IS NULL") + .arg( log_field.replace("'","''") ); + } else if ( filter == "NOT NULL" ) { + // only select non-NULL values + stmt += QString(" AND \"%1\" IS NOT NULL") + .arg( log_field.replace("'","''") ); + } else { + // filter + if ( log_field == "response" + || log_field == "time_taken" + || log_field == "bytes_sent" + || log_field == "bytes_received" ) { + // numbers + if ( StringOps::isNumeric( field_filter.toStdString() ) ) { + // no operator found, set defult to '=' + filter = QString("=%1").arg( field_filter ); + } + stmt += QString(" AND \"%1\"%2") + .arg( log_field.replace("'","''"), + filter.replace("'","''") ); + + } else { + stmt += QString(" AND \"%1\" LIKE '%2' || '%'") + .arg( log_field.replace("'","''"), + filter.replace("'","''") ); + } + } + } + + stmt += ";"; + if ( ! query.exec( stmt ) ) { + // error querying database + successful = false; + DialogSec::errDatabaseFailedExecuting( this->db_name, query.lastQuery(), query.lastError().text() ); + + } else { + try { + // clear the list of found days + days_l.clear(); + // get query data + while ( query.next() ) { + day = query.value(0).toInt(); + hour = query.value(1).toInt(); + minute = query.value(2).toInt(); + // increase the count + data.at( hour ).at( this->getMinuteGap( minute ) ) ++; + // append the day as newly found if not found yet + if ( days_l.indexOf( day ) < 0 ) { + days_l.push_back( day ); + } + } + n_days += days_l.size(); + } catch (...) { + // something failed + successful = false; + DialogSec::errGeneric( TR::tr(this->MSG_ERR_PROCESSING.c_str()), true ); + } + } + + + } else { + for ( int m=1; m<=n_months; m++ ) { + stmt = QString("SELECT \"day\", \"hour\", \"minute\" FROM \"%1\" WHERE \"year\"=%2 AND \"month\"=%3") + .arg( web_server ) + .arg( year ).arg( month ); + if ( m == 1 ) { + // first month, only get the day from the beginning day + stmt += QString(" AND \"day\">=%1").arg( from_day ); + } else if ( m == n_months ) { + // last month, only get the days until the ending day + stmt += QString(" AND \"day\"<=%1").arg( to_day ); + } + + // apply a filter if present + if ( field_filter.size() > 0 ) { + QString filter = field_filter; + if ( filter == "NULL" ) { + // only select NULL values + stmt += QString(" AND \"%1\" IS NULL") + .arg( log_field.replace("'","''") ); + } else if ( filter == "NOT NULL" ) { + // only select non-NULL values + stmt += QString(" AND \"%1\" IS NOT NULL") + .arg( log_field.replace("'","''") ); + } else { + // filter + if ( log_field == "warning" + || log_field == "response" + || log_field == "time_taken" + || log_field == "bytes_sent" + || log_field == "bytes_received" ) { + // numbers + if ( StringOps::isNumeric( field_filter.toStdString() ) ) { + // no operator found, set defult to '=' + filter = QString("=%1").arg( field_filter ); + } + stmt += QString(" AND \"%1\"%2") + .arg( log_field.replace("'","''"), + filter.replace("'","''") ); + + } else { + // only values starting-with + stmt += QString(" AND \"%1\" LIKE '%2' || '%'") + .arg( log_field.replace("'","''"), + filter.replace("'","''") ); + } + } + } + + // quary the database + stmt += ";"; + if ( ! query.exec( stmt ) ) { + // error querying database + successful = false; + DialogSec::errDatabaseFailedExecuting( this->db_name, query.lastQuery(), query.lastError().text() ); + + } else { + try { + // clear the list of found days + days_l.clear(); + // get query data + while ( query.next() ) { + day = query.value(0).toInt(); + hour = query.value(1).toInt(); + minute = query.value(2).toInt(); + // increase the count + data.at( hour ).at( this->getMinuteGap( minute ) ) ++; + // append the day as newly found if not found yet + if ( days_l.indexOf( day ) < 0 ) { + days_l.push_back( day ); + } + } + n_days += days_l.size(); + month ++; + if ( month > 12 ) { + month = 1; + year ++; + } + } catch (...) { + // something failed + successful = false; + DialogSec::errGeneric( TR::tr(this->MSG_ERR_PROCESSING.c_str()), true ); + break; + } + query.finish(); + } + } + } + if ( successful && n_days > 0 ) { + // divide the count by the number of days to get the mean value + for ( const auto& [h,data_] : data ) { + for ( const auto& [m,c] : data_ ) { + data.at( h ).at( m ) /= n_days; + } + } + } + } + } + + + if ( ! successful ) { + data.clear(); + } + if ( db.isOpen() ) { + db.close(); + } + result = std::make_tuple( successful, data ); +} + + + +// get and count how many times a specific item value brought to another +void DbQuery::getRelationalCountsDay(std::tuple>> &result, const QString& web_server, const QString& year_, const QString& month_, const QString& day_, const QString& log_field_1_, const QString& field_filter_1, const QString& log_field_2_, const QString& field_filter_2 ) +{ + bool successful = true; + std::vector> data; + + QSqlDatabase db; + if ( QSqlDatabase::contains("qt_sql_default_connection") ) { + db = QSqlDatabase::database("qt_sql_default_connection"); + } else { + db = QSqlDatabase::addDatabase("QSQLITE"); + } + db.setDatabaseName( QString::fromStdString( this->db_path )); + + if ( ! db.open() ) { + // error opening database + successful = false; + QString err_msg = ""; + if ( this->dialog_level == 2 ) { + err_msg = db.lastError().text(); + } + DialogSec::errDatabaseFailedOpening( this->db_name, err_msg ); + + } else { + if ( web_server != "apache" && web_server != "nginx" && web_server != "iis" ) { + // unexpected WebServer + successful = false; + DialogSec::errGeneric( QString("%1:\n%2").arg( TR::tr(this->MSG_ERR_UNX_WS.c_str()), web_server ), true ); + } + + int year, month, day; + if ( successful ) { + // setup period limits + try { + year = year_.toInt(); + month = this->getMonthNumber( month_ ); + day = day_.toInt(); + } catch (...) { + // failed to convert to integers + successful = false; + DialogSec::errGeneric( TR::tr(this->MSG_ERR_PROCESSING_DATES.c_str()), true ); + } + } + if ( successful ) { + QDateTime time; + time.setDate( QDate( year, month , day ) ); + // build the query statement + QSqlQuery query = QSqlQuery( db ); + QString stmt; + QString log_field_1 = this->getDbField( log_field_1_ ), + log_field_2 = this->getDbField( log_field_2_ ); + + // 1 month, no need to loop + stmt = QString("SELECT \"hour\", \"minute\" FROM \"%1\" WHERE \"year\"=%2 AND \"month\"=%3 AND \"day\"=%4") + .arg( web_server ) + .arg( year ).arg( month ).arg( day ); + + // apply a filter if present + if ( field_filter_1.size() > 0 ) { + QString filter = field_filter_1; + if ( filter == "NULL" ) { + // only select NULL values + stmt += QString(" AND \"%1\" IS NULL") + .arg( log_field_1.replace("'","''") ); + } else if ( filter == "NOT NULL" ) { + // only select non-NULL values + stmt += QString(" AND \"%1\" IS NOT NULL") + .arg( log_field_1.replace("'","''") ); + } else { + // filter + if ( log_field_1 == "warning" + || log_field_1 == "response" + || log_field_1 == "time_taken" + || log_field_1 == "bytes_sent" + || log_field_1 == "bytes_received" ) { + // numbers + if ( StringOps::isNumeric( field_filter_1.toStdString() ) ) { + // no operator found, set defult to '=' + filter = QString("=%1").arg( field_filter_1 ); + } + stmt += QString(" AND \"%1\"%2") + .arg( log_field_1.replace("'","''"), + filter.replace("'","''") ); + + } else { + // only values starting-with + stmt += QString(" AND \"%1\" LIKE '%2' || '%'") + .arg( log_field_1.replace("'","''"), + filter.replace("'","''") ); + } + } + } + // apply a filter if present + if ( field_filter_2.size() > 0 ) { + QString filter = field_filter_2; + if ( filter == "NULL" ) { + // only select NULL values + stmt += QString(" AND \"%1\" IS NULL") + .arg( log_field_2.replace("'","''") ); + } else if ( filter == "NOT NULL" ) { + // only select non-NULL values + stmt += QString(" AND \"%1\" IS NOT NULL") + .arg( log_field_2.replace("'","''") ); + } else { + // filter + if ( log_field_2 == "warning" + || log_field_2 == "response" + || log_field_2 == "time_taken" + || log_field_2 == "bytes_sent" + || log_field_2 == "bytes_received" ) { + // numbers + if ( StringOps::isNumeric( field_filter_2.toStdString() ) ) { + // no operator found, set defult to '=' + filter = QString("=%1").arg( field_filter_2 ); + } + stmt += QString(" AND \"%1\"%2") + .arg( log_field_2.replace("'","''"), + filter.replace("'","''") ); + + } else { + // only values starting-with + stmt += QString(" AND \"%1\" LIKE '%2' || '%'") + .arg( log_field_2.replace("'","''"), + QString(field_filter_2).replace("'","''") ); + } + } + } + + stmt += QString(" ORDER BY \"hour\",\"minute\" ASC;"); + if ( ! query.exec( stmt ) ) { + // error querying database + successful = false; + DialogSec::errDatabaseFailedExecuting( this->db_name, query.lastQuery(), query.lastError().text() ); + + } else { + try { + // get query data + int hour, aux_hour, minute, aux_minute, count; + int gap = 20; + hour = -1; + minute = count = 0; + if ( query.size() == 0 ) { + // no result found, append missing days with 0 value + for ( int h=0; h<24; h++ ) { + for ( int m=0; m<60; m+=gap ) { + time.setTime( QTime( h, m ) ); + data.push_back( std::make_tuple( time.toMSecsSinceEpoch(), 0 ) ); + } + } + + } else { + while ( query.next() ) { + aux_hour = query.value(0).toInt(); + aux_minute = this->getMinuteGap( query.value(1).toInt(), gap ); + if ( aux_hour == hour && aux_minute == minute ) { + count ++; + } else { + if ( aux_hour == hour ) { + // same hour new minute gap, append the last count + time.setTime( QTime( hour, minute ) ); + data.push_back( std::make_tuple( time.toMSecsSinceEpoch(), count ) ); + // and any missing gap + for ( int m=minute+gap; m= 0 ) { + // apend the last minute-gap count if not in the first round of the loop + time.setTime( QTime( hour, minute ) ); + data.push_back( std::make_tuple( time.toMSecsSinceEpoch(), count ) ); + // append any missing gap in the current hour + for ( int m=minute+gap; m<60; m+=gap ) { + time.setTime( QTime( hour, m ) ); + data.push_back( std::make_tuple( time.toMSecsSinceEpoch(), 0 ) ); + } + hour ++; + } else { + // prepare to add missing gaps from 00:00 (+gap will be added to the minute) + hour = 0; + } + // append any missing gap in every hour between the current and the next found (aux) + for ( int h=hour; h this->getMonthDays( year, month ) ) { + day = 1; + month ++; + if ( month > 12 ) { + month = 1; + year ++; + } + } + time.setDate( QDate( year, month , day ) ); + time.setTime( QTime( 0, 0 ) ); + //time.setTime( QTime( 23, 59, 59, 999 ) ); + data.push_back( std::make_tuple( time.toMSecsSinceEpoch(), 0 ) ); + } + } catch (...) { + // something failed + successful = false; + DialogSec::errGeneric( TR::tr(this->MSG_ERR_PROCESSING.c_str()), true ); + } + } + } + } + + if ( ! successful ) { + data.clear(); + } + if ( db.isOpen() ) { + db.close(); + } + result = std::make_tuple( successful, data ); +} + + + +void DbQuery::getRelationalCountsPeriod(std::tuple>> &result, const QString& web_server, const QString& from_year_, const QString& from_month_, const QString& from_day_, const QString& to_year_, const QString& to_month_, const QString& to_day_, const QString& log_field_1_, const QString& field_filter_1, const QString& log_field_2_, const QString& field_filter_2 ) +{ + bool successful = true; + std::vector> data; + + QSqlDatabase db; + if ( QSqlDatabase::contains("qt_sql_default_connection") ) { + db = QSqlDatabase::database("qt_sql_default_connection"); + } else { + db = QSqlDatabase::addDatabase("QSQLITE"); + } + db.setDatabaseName( QString::fromStdString( this->db_path )); + + if ( ! db.open() ) { + // error opening database + successful = false; + QString err_msg = ""; + if ( this->dialog_level == 2 ) { + err_msg = db.lastError().text(); + } + DialogSec::errDatabaseFailedOpening( this->db_name, err_msg ); + + } else { + if ( web_server != "apache" && web_server != "nginx" && web_server != "iis" ) { + // unexpected WebServer + successful = false; + DialogSec::errGeneric( QString("%1:\n%2").arg( TR::tr(this->MSG_ERR_UNX_WS.c_str()), web_server ), true ); + } + int from_year, from_month, from_day, + to_year, to_month, to_day; + if ( successful ) { + // setup period limits + try { + from_year = from_year_.toInt(); + from_month = this->getMonthNumber( from_month_ ); + from_day = from_day_.toInt(); + to_year = ( to_year_.size() == 0 ) ? from_year : to_year_.toInt() ; + to_month = ( to_month_.size() == 0 ) ? from_month : this->getMonthNumber( to_month_ ) ; + to_day = ( to_day_.size() == 0 ) ? from_day : to_day_.toInt() ; + } catch (...) { + // failed to convert to integers + successful = false; + DialogSec::errGeneric( TR::tr(this->MSG_ERR_PROCESSING_DATES.c_str()), true ); + } + } + if ( successful ) { + // build the query statement + QSqlQuery query = QSqlQuery( db ); + QString stmt; + QString log_field_1 = this->getDbField( log_field_1_ ), + log_field_2 = this->getDbField( log_field_2_ ); + + int n_months = this->getMonthsCount( from_year, from_month, to_year, to_month ); + + QDateTime time; + int year = from_year, + month = from_month, + day, aux_day, count; + + if ( n_months == 1 ) { + // 1 month, no need to loop + stmt = QString("SELECT \"day\" FROM \"%1\" WHERE \"year\"=%2 AND \"month\"=%3 AND \"day\">=%4 AND \"day\"<=%5") + .arg( web_server ) + .arg( year ).arg( month ) + .arg( from_day ).arg( to_day ); + + // only select non-NULL values + stmt += QString(" AND \"%1\" IS NOT NULL") + .arg( log_field_1.replace("'","''") ); + // apply a filter if present + if ( field_filter_1.size() > 0 ) { + QString filter = field_filter_1; + if ( log_field_1 == "response" + || log_field_1 == "time_taken" + || log_field_1 == "bytes_sent" + || log_field_1 == "bytes_received" ) { + // numbers + if ( StringOps::isNumeric( field_filter_1.toStdString() ) ) { + // no operator found, set defult to '=' + filter = QString("=%1").arg( field_filter_1 ); + } + stmt += QString(" AND \"%1\"%2") + .arg( log_field_1.replace("'","''"), + filter.replace("'","''") ); + + } else { + stmt += QString(" AND \"%1\" LIKE '%2' || '%'") + .arg( log_field_1.replace("'","''"), + filter.replace("'","''") ); + } + } + // only select non-NULL values + stmt += QString(" AND \"%1\" IS NOT NULL") + .arg( log_field_2.replace("'","''") ); + // apply a filter if present + if ( field_filter_2.size() > 0 ) { + QString filter = field_filter_2; + if ( log_field_2 == "response" + || log_field_2 == "time_taken" + || log_field_2 == "bytes_sent" + || log_field_2 == "bytes_received" ) { + // numbers + if ( StringOps::isNumeric( field_filter_2.toStdString() ) ) { + // no operator found, set defult to '=' + filter = QString("=%1").arg( field_filter_2 ); + } + stmt += QString(" AND \"%1\"%2") + .arg( log_field_2.replace("'","''"), + filter.replace("'","''") ); + + } else { + stmt += QString(" AND \"%1\" LIKE '%2' || '%'") + .arg( log_field_2.replace("'","''"), + QString(field_filter_2).replace("'","''") ); + } + } + + stmt += QString(" ORDER BY \"day\" ASC;"); + if ( ! query.exec( stmt ) ) { + // error querying database + successful = false; + DialogSec::errDatabaseFailedExecuting( this->db_name, query.lastQuery(), query.lastError().text() ); + + } else { + try { + // get query data + day = count = 0; + if ( query.size() == 0 ) { + // no days found, append missing days with 0 value + for ( int d=from_day; d<=to_day; d++ ) { + time.setDate( QDate( year, month , d ) ); + data.push_back( std::make_tuple( time.toMSecsSinceEpoch(), 0 ) ); + } + + } else { + while ( query.next() ) { + aux_day = query.value(0).toInt(); + if ( aux_day == day ) { + count ++; + } else { + if ( day > 0 ) { + // any loop-round except the first + time.setDate( QDate( year, month , day ) ); + data.push_back( std::make_tuple( time.toMSecsSinceEpoch(), count ) ); + for ( int d=day+1; dgetMonthDays( y, m ); + } + for ( ; d!=aux_day; d++ ) { + if ( d > this->getMonthDays( y, m ) ) { + d = 1; + m ++; + if ( m > 12 ) { + m = 1; + y ++; + } + } + time.setDate( QDate( y, m , d ) ); + data.push_back( std::make_tuple( time.toMSecsSinceEpoch(), 0 ) ); + } + } + day = aux_day; + count = 1; + } + } + // append the last count + time.setDate( QDate( year, month , day ) ); + data.push_back( std::make_tuple( time.toMSecsSinceEpoch(), count ) ); + // append any missing day from the last found until 1 day fater the last one + day++; + if ( day > this->getMonthDays( year, month ) ) { + month ++; + if ( month > 12 ) { + month = 1; + year ++; + } + day = this->getMonthDays( year, month ); + } + to_day += 2; + if ( to_day > this->getMonthDays( year, month ) ) { + int m = month + 1, + y = year; + if ( m > 12 ) { + m = 1; + y ++; + } + to_day = this->getMonthDays( y, m ); + } + for ( ; day!=to_day; day++ ) { + if ( day > this->getMonthDays( year, month ) ) { + day = 1; + month ++; + if ( month > 12 ) { + month = 1; + year ++; + } + } + time.setDate( QDate( year, month , day ) ); + data.push_back( std::make_tuple( time.toMSecsSinceEpoch(), 0 ) ); + } + } + } catch (...) { + // something failed + successful = false; + DialogSec::errGeneric( TR::tr(this->MSG_ERR_PROCESSING.c_str()), true ); + } + } + + } else { + for ( int m=1; m<=n_months; m++ ) { + stmt = QString("SELECT \"day\" FROM \"%1\" WHERE \"year\"=%2 AND \"month\"=%3") + .arg( web_server ) + .arg( year ).arg( month ); + + if ( m == 1 ) { + // first month, only get the day from the beginning day + stmt += QString(" AND \"day\">=%1").arg( from_day ); + } else if ( m == n_months ) { + // last month, only get the days until the ending day + stmt += QString(" AND \"day\"<=%1").arg( to_day ); + } + + // only select non-NULL values + stmt += QString(" AND \"%1\" IS NOT NULL") + .arg( log_field_1.replace("'","''") ); + // apply a filter if present + if ( field_filter_1.size() > 0 ) { + QString filter = field_filter_1; + if ( log_field_1 == "response" + || log_field_1 == "time_taken" + || log_field_1 == "bytes_sent" + || log_field_1 == "bytes_received" ) { + // numbers + if ( StringOps::isNumeric( field_filter_1.toStdString() ) ) { + // no operator found, set defult to '=' + filter = QString("=%1").arg( field_filter_1 ); + } + stmt += QString(" AND \"%1\"%2") + .arg( log_field_1.replace("'","''"), + filter.replace("'","''") ); + + } else { + stmt += QString(" AND \"%1\" LIKE '%2' || '%'") + .arg( log_field_1.replace("'","''"), + filter.replace("'","''") ); + } + } + // only select non-NULL values + stmt += QString(" AND \"%1\" IS NOT NULL") + .arg( log_field_2.replace("'","''") ); + // apply a filter if present + if ( field_filter_2.size() > 0 ) { + QString filter = field_filter_2; + if ( log_field_2 == "response" + || log_field_2 == "time_taken" + || log_field_2 == "bytes_sent" + || log_field_2 == "bytes_received" ) { + // numbers + if ( StringOps::isNumeric( field_filter_2.toStdString() ) ) { + // no operator found, set defult to '=' + filter = QString("=%1").arg( field_filter_2 ); + } + stmt += QString(" AND \"%1\"%2") + .arg( log_field_2.replace("'","''"), + filter.replace("'","''") ); + + } else { + stmt += QString(" AND \"%1\" LIKE '%2' || '%'") + .arg( log_field_2.replace("'","''"), + QString(field_filter_2).replace("'","''") ); + } + } + + // quary the database + stmt += " ORDER BY \"day\" ASC;"; + if ( ! query.exec( stmt ) ) { + // error querying database + successful = false; + DialogSec::errDatabaseFailedExecuting( this->db_name, query.lastQuery(), query.lastError().text() ); + + } else { + try { + // get query data + day = count = 0; + if ( query.size() == 0 ) { + // no days found, append missing days with 0 value + int f_d = 1, + t_d = this->getMonthDays( year, month ); + if ( m == 1 ) { + // first month, only get the day from the beginning day + f_d = from_day; + } else if ( m == n_months ) { + // last month, only get the days until the ending day + t_d = to_day; + } + for ( ; f_d<=t_d; f_d++ ) { + time.setDate( QDate( year, month , f_d ) ); + data.push_back( std::make_tuple( time.toMSecsSinceEpoch(), 0 ) ); + } + + } else { + while ( query.next() ) { + aux_day = query.value(0).toInt(); + if ( aux_day == day ) { + count ++; + } else { + if ( day > 0 ) { + // any loop-round except the first + time.setDate( QDate( year, month , day ) ); + data.push_back( std::make_tuple( time.toMSecsSinceEpoch(), count ) ); + for ( int d=day+1; d 0 ) { + time.setDate( QDate( year, month , day ) ); + data.push_back( std::make_tuple( time.toMSecsSinceEpoch(), count ) ); + } + // append any missing day to the end of the month with a zero value + for ( int d=day+1; d<=this->getMonthDays(year,month); d++ ) { + time.setDate( QDate( year, month , d ) ); + data.push_back( std::make_tuple( time.toMSecsSinceEpoch(), 0 ) ); + } + } + // increase the month + month ++; + if ( month > 12 ) { + month = 1; + year ++; + } + } catch (...) { + // something failed + successful = false; + DialogSec::errGeneric( TR::tr(this->MSG_ERR_PROCESSING.c_str()), true ); + break; + } + } + query.finish(); + } + // append the first day of 1 month after the last one as the last one day + day = 1; + month = to_month +1; + if ( month > 12 ) { + month = 1; + year ++; + } + time.setDate( QDate( year, month , day ) ); + data.push_back( std::make_tuple( time.toMSecsSinceEpoch(), 0 ) ); + } + } + } + + if ( ! successful ) { + data.clear(); + } + if ( db.isOpen() ) { + db.close(); + } + result = std::make_tuple( successful, data ); +} + + + +const bool DbQuery::getGlobalCounts( const QString& web_server, const std::unordered_map>>& dates, std::vector>& recurs, std::tuple& traf_date, std::unordered_map& traf_day, std::unordered_map& traf_hour, std::vector& perf_time, std::vector& perf_sent, std::vector& perf_receiv, long& req_count ) +{ + bool successful = true; + + QSqlDatabase db; + if ( QSqlDatabase::contains("qt_sql_default_connection") ) { + db = QSqlDatabase::database("qt_sql_default_connection"); + } else { + db = QSqlDatabase::addDatabase("QSQLITE"); + } + db.setDatabaseName( QString::fromStdString( this->db_path )); + + if ( ! db.open() ) { + // error opening database + successful = false; + QString err_msg = ""; + if ( this->dialog_level == 2 ) { + err_msg = db.lastError().text(); + } + DialogSec::errDatabaseFailedOpening( this->db_name, err_msg ); + + } else { + if ( web_server != "apache" && web_server != "nginx" && web_server != "iis" ) { + // unexpected WebServer + successful = false; + DialogSec::errGeneric( QString("%1:\n%2").arg( TR::tr(this->MSG_ERR_UNX_WS.c_str()), web_server ), true ); + } + } + + if ( successful ) { + QSqlQuery query = QSqlQuery( db ); + int d, h, tt, bs, br, + day, hour, week_day, + day_count, hour_count, + max_date_count=0, + max_tt=0, tot_tt=0, num_tt=0, + max_bs=0, tot_bs=0, num_bs=0, + max_br=0, tot_br=0, num_br=0, + n_days=0; + QString protocol, method, uri, user_agent, max_date_str=""; + std::unordered_map num_day_count = { + {1,0}, {2,0}, {3,0}, {4,0}, {5,0}, {6,0}, {7,0} }; + // get years + for ( const auto& [year, dates_] : dates ) { + // get months of the year + for ( const auto& [month, dates__] : dates_ ) { + + hour=-1; hour_count=0; + day=-1; day_count=0; + + if ( ! query.exec( QString("SELECT \"day\",\"hour\",\"protocol\",\"method\",\"uri\",\"user_agent\",\"time_taken\",\"bytes_sent\",\"bytes_received\" FROM \"%1\" WHERE \"year\"=%2 AND \"month\"=%3 ORDER BY \"day\",\"hour\" ASC;") + .arg( web_server ).arg( year ).arg( month ).replace("'","''") ) ) { + // error querying database + successful = false; + DialogSec::errDatabaseFailedExecuting( this->db_name, query.lastQuery(), query.lastError().text() ); + break; + + } else { + while ( query.next() ) { + try { + // day + if ( query.value(0).isNull() ) { + d = -1; + } else { + d = query.value(0).toInt(); + } + // hour + if ( query.value(1).isNull() ) { + h = -1; + } else { + h = query.value(1).toInt(); + } + // protocol + if ( query.value(2).isNull() ) { + protocol = ""; + } else { + protocol = query.value(2).toString(); + } + // method + if ( query.value(3).isNull() ) { + method = ""; + } else { + method = query.value(3).toString(); + } + // uri + if ( query.value(4).isNull() ) { + uri = ""; + } else { + uri = query.value(4).toString(); + } + // user agent + if ( query.value(5).isNull() ) { + user_agent = ""; + } else { + user_agent = query.value(5).toString(); + } + // time taken + if ( query.value(6).isNull() ) { + tt = -1; + } else { + tt = query.value(6).toInt(); + } + // bytes sent + if ( query.value(7).isNull() ) { + bs = -1; + } else { + bs = query.value(7).toInt(); + } + // bytes received + if ( query.value(8).isNull() ) { + br = -1; + } else { + br = query.value(8).toInt(); + } + } catch (...) { + // failed to convert to integer + successful = false; + QString err_msg = ""; + if ( this->dialog_level == 2 ) { + err_msg = TR::tr(this->MSG_ERR_PROCESSING.c_str()); + } + DialogSec::errGeneric( err_msg ); + break; + } + if ( successful ) { + + // process the day count + if ( d > 0 ) { + if ( day == -1 ) { + day = d; + } + if ( d == day ) { + day_count ++; + } else { + n_days ++; + // sum the day count to the total count + req_count += day_count; + // sum the day count to the relative day of the week count + week_day = QDate(year,month,day).dayOfWeek(); + traf_day.at( week_day ) += day_count; + num_day_count.at( week_day ) ++; + // check the max date count + const QString m_str = (month<10) ? QString("0%1").arg(month) : QString("%1").arg(month) ; + const QString d_str = (day<10) ? QString("0%1").arg(day) : QString("%1").arg(day) ; + if ( day_count > max_date_count ) { + max_date_count = day_count; + max_date_str = QString("%1-%2-%3").arg( year ).arg( m_str, d_str ); + } + day_count = 1; + day = d; + } + } + + // process the hour count + if ( h >= 0 ) { + if ( hour == -1 ) { + hour = h; + } + if ( h == hour ) { + hour_count ++; + } else { + traf_hour.at( hour ) += hour_count; + hour_count = 1; + hour = h; + } + } + + // sum the time taken + if ( tt >= 0 ) { + if ( tt > max_tt ) { + max_tt = tt; + } + tot_tt += tt; + num_tt ++; + } + + // sum the bytes sent + if ( bs >= 0 ) { + if ( bs > max_bs ) { + max_bs = bs; + } + tot_bs += bs; + num_bs ++; + } + + // sum the bytes received + if ( br >= 0 ) { + if ( br > max_br ) { + max_br = br; + } + tot_br += br; + num_br ++; + } + + // process the protocol + if ( protocol.size() > 0 ) { + if ( recurs.at(0).find( protocol ) != recurs.at(0).end() ) { + // sum + recurs.at(0).at( protocol ) ++; + } else { + // new + recurs.at(0).emplace( protocol, 1 ); + } + } + + // process the method + if ( method.size() > 0 ) { + if ( recurs.at(1).find( method ) != recurs.at(1).end() ) { + // sum + recurs.at(1).at( method ) ++; + } else { + // new + recurs.at(1).emplace( method, 1 ); + } + } + + // process the uri + if ( uri.size() > 0 ) { + if ( recurs.at(2).find( uri ) != recurs.at(2).end() ) { + // sum + recurs.at(2).at( uri ) ++; + } else { + // new + recurs.at(2).emplace( uri, 1 ); + } + } + + // process the user-agent + if ( user_agent.size() > 0 ) { + if ( recurs.at(3).find( user_agent ) != recurs.at(3).end() ) { + // sum + recurs.at(3).at( user_agent ) ++; + } else { + // new + recurs.at(3).emplace( user_agent, 1 ); + } + } + } + } + // complete the remaining stats + if ( successful ) { + // append the last hour + if ( hour >= 0 ) { + traf_hour.at( hour ) += hour_count; + } + + // sum the day count to the total count + req_count += day_count; + + // sum the day count to the relative day of the week count + week_day = QDate(year,month,day).dayOfWeek(); + traf_day.at( week_day ) += day_count; + num_day_count.at( week_day ) ++; + + // check the max date count + const QString m_str = (month<10) ? QString("0%1").arg(month) : QString("%1").arg(month) ; + const QString d_str = (day<10) ? QString("0%1").arg(day) : QString("%1").arg(day) ; + if ( day_count > max_date_count ) { + max_date_count = day_count; + max_date_str = QString("%1-%2-%3").arg( year ).arg( m_str, d_str ); + } + } + } + query.finish(); + if ( ! successful ) { break; } + } + if ( ! successful ) { break; } + } + + // final process for some of the values + if ( successful ) { + + // process the hours of the day + for ( int i=0; i<24; i++ ) { + if ( n_days > 0 ) { + traf_hour.at( i ) /= n_days; + } + } + + // process the day of the week + for ( int i=1; i<8; i++ ) { + const int &x = num_day_count.at( i ); + if ( x > 0 ) { + traf_day.at( i ) /= x; + } + } + + // make the max-date tuple + traf_date = std::make_tuple( max_date_str, max_date_count ); + + // time-taken perfs + perf_time = { max_tt, tot_tt, num_tt }; + // bytes-sent perfs + perf_sent = { max_bs, tot_bs, num_bs }; + // bytes-received perfs + perf_receiv = { max_br, tot_br, num_br }; + } + } + + return successful; +} + diff --git a/logdoctor/modules/crapview/modules/query.h b/logdoctor/modules/crapview/modules/query.h new file mode 100644 index 00000000..c2966429 --- /dev/null +++ b/logdoctor/modules/crapview/modules/query.h @@ -0,0 +1,326 @@ +#ifndef QUERY_H +#define QUERY_H + +#include "modules/shared.h" + +#include + +#include +#include + + +class DbQuery +{ +public: + DbQuery(); + + // convert log fields IDs to log fields + const std::unordered_map FIELDS = { + {0, FIELDS__WARNING}, + {10,FIELDS__PROTOCOL}, {11,FIELDS__METHOD}, + {12,FIELDS__URI}, {13,FIELDS__QUERY}, {14,FIELDS__RESPONSE_CODE}, + {15,FIELDS__TIME_TAKEN}, {16,FIELDS__BYTES_SENT}, {17,FIELDS__BYTES_RECEIVED}, + {18,FIELDS__REFERRER}, {22,FIELDS__COOKIE}, + {20,FIELDS__CLIENT}, {21,FIELDS__USER_AGENT} }; + + // convert month numbers to month names + const std::unordered_map MONTHS = { + {1, MONTHS__JANUARY}, {2, MONTHS__FEBRUARY}, {3, MONTHS__MARCH}, + {4, MONTHS__APRIL}, {5, MONTHS__MAY}, {6, MONTHS__JUNE}, + {7, MONTHS__JULY}, {8, MONTHS__AUGUST}, {9, MONTHS__SEPTEMBER}, + {10,MONTHS__OCTOBER}, {11,MONTHS__NOVEMBER}, {12,MONTHS__DECEMBER} }; + + // convert week-day numbers to day names + const std::unordered_map DAYS = { + {1, DAYS__SUNDAY}, {2, DAYS__MONDAY}, {3, DAYS__TUESDAY}, + {4, DAYS__WEDNESDAY}, {5, DAYS__THURSDAY}, {6, DAYS__FRIDAY}, + {7, DAYS__SATURDAY} }; + + + //! Returns the Dialogs level + void setDialogLevel( const int& new_level ); + + + //! Sets the path for the logs Collection database + /*! + \see Crapview::setDbPath() + */ + void setDbPath( const std::string& path ); + + /*const std::string getDbPath( const int web_server );*/ + + //! Returns the number of months in a given period + /*! + \overload const int getMonthsCount(const int& from_year, const int& from_month, const int& to_year, const int& to_month) + \param from_year The initial year + \param from_month The initial month + \param to_year The final Year + \param to_month The final month + \return The number of months in the period + \throw DateTimeException + */ + const int getMonthsCount( + const QString& from_year, + const QString& from_month, + const QString& to_year, + const QString& to_month ); + + + //! Refreshes the dates which are available in the database + /*! + \param result Tuple which will hold the result of the operation and the data + */ + void refreshDates( std::tuple>>>>& result ); + + + //! Updates the database applying the changes made in the Warnings statistics table + /*! + \param web_server The ID of the Web Server to use + \param updates The list of rowids to update and the corresponding warning values + */ + void updateWarnings( + const QString& web_server, + const std::vector>& updates ); + + //! Retrieves the data needed for the Warnings statistics + /*! + \param result Tuple which will hold the result of the operation and the data + \param web_server The ID of the Web Server to use + \param year_ The year + \param month_ The month + \param day_ The day + \param hour_ The hour + */ + void getWarnCounts( + std::tuple>>>>& result, + const QString& web_server, + const QString& year_, + const QString& month_, + const QString& day_, + const QString& hour_ ); + + + //! Retrieves the data needed for the Speed statistics + /*! + \param result Tuple which will hold the result of the operation and the data + \param web_server The ID of the Web Server to use + \param year_ The year + \param month_ The month + \param day_ The day + \param protocol_f The filter for the Protocol field + \param method_f The filter for the Method field + \param uri_f The filter for the URI field + \param query_f The filter for the Query field + \param response_f The filter for the Response field + */ + void getSpeedData( + std::tuple>>>& result, + const QString& web_server, + const QString& year_, + const QString& month_, + const QString& day_, + const QString& protocol_f, + const QString& method_f, + const QString& uri_f, + const QString& query_f, + const QString& response_f ); + + + //! Retrieves the data needed for the Counts statistics + /*! + \param result Tuple which will hold the result of the operation and the data + \param web_server The ID of the Web Server to use + \param year The year + \param month The month + \param day The day + \param log_field The log field + */ + void getItemsCount( + std::tuple>>& result, + const QString& web_server, + const QString& year, + const QString& month, + const QString& day, + const QString& log_field ); + + + //! Retrieves the data needed for the Daytime statistics + /*! + \param result Tuple which will hold the result of the operation and the data + \param web_server The ID of the Web Server to use + \param from_year_ The initial year + \param from_month_ The initial month + \param from_day_ The initial day + \param to_year_ The final year + \param to_month_ The final month + \param to_day_ The final day + \param log_field_ The log field to filter + \param field_filter The filter to apply + */ + void getDaytimeCounts( + std::tuple>>& result, + const QString& web_server, + const QString& from_year_, const QString& from_month_, const QString& from_day_, + const QString& to_year_, const QString& to_month_, const QString& to_day_, + const QString& log_field_, const QString& field_filter ); + + + //! Retrieves the data needed for the Relationsl statistics + /*! + Used when querying a single day + \param result Tuple which will hold the result of the operation and the data + \param web_server The ID of the Web Server to use + \param year_ The year + \param month_ The month + \param day_ The day + \param log_field_1_ The first log field to filter + \param field_filter_1 The filter to apply to the first field + \param log_field_2_ The second log field to filter + \param field_filter_2 The filter to apply to the second fiend + \see getRelationalCountsPeriod() + */ + void getRelationalCountsDay( + std::tuple>>& result, + const QString& web_server, + const QString& year_, const QString& month_, const QString& day_, + const QString& log_field_1_, const QString& field_filter_1, + const QString& log_field_2_, const QString& field_filter_2 ); + + //! Retrieves the data needed for the Relational statistics + /*! + Used when querying a period of time + \param result Tuple which will hold the result of the operation and the data + \param web_server The ID of the Web Server to use + \param from_year_ The initial year + \param from_month_ The initial month + \param from_day_ The initial day + \param to_year_ The final year + \param to_month_ The final month + \param to_day_ The final day + \param log_field_1_ The first log field to filter + \param field_filter_1 The filter to apply to the first field + \param log_field_2_ The second log field to filter + \param field_filter_2 The filter to apply to the second fiend + \see getRelationalCountsDay() + */ + void getRelationalCountsPeriod( + std::tuple>>& result, + const QString& web_server, + const QString& from_year_, const QString& from_month_, const QString& from_day_, + const QString& to_year_, const QString& to_month_, const QString& to_day_, + const QString& log_field_1_, const QString& field_filter_1, + const QString& log_field_2_, const QString& field_filter_2 ); + + + //! Retrieves the data needed for the Global statistics + /*! + \param web_server The ID of the Web Server to use + \param dates The dates to query + \param recurs Will hold the recurrencies of the items + \param traf_date Will hold the most trafficked date and the count + \param traf_day Will hold the most trafficked day of the week and the count + \param traf_hour Will hold the most trafficked hour of the day and the count + \param perf_time Will hold the overallo time taken + \param perf_sent Will hold the overall Bytes sent + \param perf_receiv Will hold the overall Bytes received + \param req_count Will hold the number of requests examined by the query + \return Whether the operation has been successful or not + */ + const bool getGlobalCounts( + const QString& web_server, + const std::unordered_map>>& dates, + std::vector>& recurs, + std::tuple& traf_date, + std::unordered_map& traf_day, + std::unordered_map& traf_hour, + std::vector& perf_time, + std::vector& perf_sent, + std::vector& perf_receiv, + long& req_count ); + +private: + + const std::string MSG_ERR_UNX_WS = TR::tr("Unexpected WebServer").toStdString(); + const std::string MSG_ERR_PROCESSING = TR::tr("An error occured while processing").toStdString(); + const std::string MSG_ERR_PROCESSING_DATES = TR::tr("An error occured while processing dates").toStdString(); + const std::string MSG_ERR_PARSING_YMD = TR::tr("An error occured while parsing %1 from the database").toStdString(); + const std::string WORD_YEARS = TR::tr("Years").toStdString(); + const std::string WORD_MONTHS = TR::tr("Months").toStdString(); + const std::string WORD_DAYS = TR::tr("Days").toStdString(); + const std::string MSG_RESPONSIBLE_VALUE = TR::tr("Value responsible for the error").toStdString(); + const std::string MSG_TABLE_NAME = TR::tr("Database table name").toStdString(); + + // quantity of information to display throught dialogs + int dialog_level = 2; // 0: essential, 1: usefull, 2: explanatory + + std::string db_path; + QString db_name; + + // convert log fields to database fields + const std::unordered_map LogFields_to_DbFields = { + {this->FIELDS.at( 0), "warning"}, + {this->FIELDS.at(10), "protocol"}, + {this->FIELDS.at(11), "method"}, + {this->FIELDS.at(12), "uri"}, + {this->FIELDS.at(13), "query"}, + {this->FIELDS.at(14), "response"}, + {this->FIELDS.at(15), "time_taken"}, + {this->FIELDS.at(16), "bytes_sent"}, + {this->FIELDS.at(17), "bytes_received"}, + {this->FIELDS.at(18), "referrer"}, + {this->FIELDS.at(20), "client"}, + {this->FIELDS.at(21), "user_agent"}, + {this->FIELDS.at(22), "cookie"} + }; + + //! Returns the database field corresponding to the relative log field + /*! + \param tr_fld The log field, hendles translated text + \return The database field + */ + const QString getDbField( const QString& tr_fld ); + + /*const int getLogFieldID ( const QString& field_str );*/ + + + //! Returns the minute gap for the given minute with the given gap + /*! + \param minute The minute of the hour + \param gap The gap used to split the hour + \return The gap index + \throw DateTimeException + */ + const int getMinuteGap( const int& minute, const int& gap=10 ); + + + //! Returns the number of days for a given month + /*! + \param year The year, used to handle leap years + \param month The month + \return The number of days + \throw DateTimeException + */ + const int getMonthDays( const int& year, const int& month ); + + //! Returns the month number in the year + /*! + \param month_str The month + \return The month number + */ + const int getMonthNumber( const QString& month_str ); + + + //! Returns the number of months in a given period + /*! + \param from_year The initial year + \param from_month The initial month + \param to_year The final Year + \param to_month The final month + \return The number of months in the period + */ + const int getMonthsCount( + const int& from_year, const int& from_month, + const int& to_year, const int& to_month ); +}; + +#endif // QUERY_H diff --git a/logdoctor/modules/dialogs.cpp b/logdoctor/modules/dialogs.cpp new file mode 100644 index 00000000..cb09832b --- /dev/null +++ b/logdoctor/modules/dialogs.cpp @@ -0,0 +1,698 @@ + +#include "dialogs.h" + +#include "modules/dialogs/dialogmsg.h" +#include "modules/dialogs/dialogbool.h" +#include "modules/dialogs/dialogdia.h" + + +DialogSec::DialogSec() +{ + +} + + +////////////////// +//// LANGUAGE //// +////////////////// +void DialogSec::errLangLocaleInvalid( const QString& locale, QWidget* parent ) +{ + DialogMsg dialog = DialogMsg( + DialogSec::tr("Invalid locale"), + QString("%1:\n%2\n\n%3").arg( + DialogSec::tr("Unexpected locale format"), + locale, + DialogSec::tr("If you haven't manually edited the configuration file,\nplease report this issue") ), + "", 2, parent ); + std::ignore = dialog.exec(); +} +void DialogSec::errLangNotAccepted( const QString& locale, QWidget* parent ) +{ + DialogMsg dialog = DialogMsg( + DialogSec::tr("Invalid locale"), + QString("%1:\n%2\n\n%3").arg( + DialogSec::tr("The given locale is not an accepted language"), + locale, + DialogSec::tr("If you'd like to have this locale in LogDoctor,\nplease follow the instruction on the repository page") ), + "", 2, parent ); + std::ignore = dialog.exec(); +} + + + +/////////////////////// +//// CONFIGURATION //// +/////////////////////// +void DialogSec::warnConfFileNotFound( const QString& file, QWidget* parent ) +{ + DialogMsg dialog = DialogMsg( + DialogSec::tr("Configuration file not found"), + QString("%1%2\n\n%3").arg( + DialogSec::tr("Unable to retrieve the configuration file"), + (file=="") ? file : ":\n"+file, + DialogSec::tr("Skipping") ), + "", 1, parent ); + std::ignore = dialog.exec(); +} + +void DialogSec::errConfFailedWriting( const QString& msg, const QString& err, QWidget* parent ) +{ + DialogMsg dialog = DialogMsg( + DialogSec::tr("Failed to write the configuration file"), + QString("%1%2\n\n%3").arg( + DialogSec::tr("An error occured while handling the configuration file"), + (msg=="") ? msg : ":\n"+msg, + DialogSec::tr("Current configuration not saved") ), + err, 1, parent ); + std::ignore = dialog.exec(); +} + +void DialogSec::errConfFileNotReadable( const QString& file, const QString& err, QWidget* parent ) +{ + DialogMsg dialog = DialogMsg( + DialogSec::tr("File not readable"), + QString("%1\n\n%2%3").arg( + DialogSec::tr("An error occured while handling the configuration file"), + DialogSec::tr("The file is not readable"), + (file=="") ? file : ":\n"+file ), + err, 2, parent ); + std::ignore = dialog.exec(); +} +void DialogSec::errConfFileNotWritable( const QString& file, const QString& err, QWidget* parent ) +{ + DialogMsg dialog = DialogMsg( + DialogSec::tr("File not writable"), + QString("%1\n\n%2%3").arg( + DialogSec::tr("An error occured while handling the configuration file"), + DialogSec::tr("The file is not writable"), + (file=="") ? file : ":\n"+file ), + err, 2, parent ); + std::ignore = dialog.exec(); +} + + +void DialogSec::errConfDirNotWritable( const QString& dir, const QString& err, QWidget* parent ) +{ + DialogMsg dialog = DialogMsg( + DialogSec::tr("Directory not writable"), + QString("%1\n\n%2%3").arg( + DialogSec::tr("An error occured while handling the configuration file"), + DialogSec::tr("The directory is not writable"), + (dir=="") ? dir : ":\n"+dir ), + err, 2, parent ); + std::ignore = dialog.exec(); +} + + +void DialogSec::errFailedApplyingConfigs( const QString& msg, QWidget* parent ) +{ + DialogMsg dialog = DialogMsg( + DialogSec::tr("Failed applying configuration"), + QString("%1\n%2").arg( + (msg=="") ? msg : QString("%1\n").arg(msg), + DialogSec::tr("Aborting") ), + "", 2, parent ); + std::ignore = dialog.exec(); +} + + + +////////////// +//// HELP //// +////////////// +void DialogSec::errHelpFailed( const QString& link, const QString& msg, QWidget* parent ) +{ + DialogMsg dialog = DialogMsg( + DialogSec::tr("Failed to retrieve the help file"), + QString("%1%2\n\n%3%4").arg( + DialogSec::tr("An error occured while getting the help file"), + (msg=="") ? msg : ":\n"+msg, + DialogSec::tr("Additional resources can be downloaded from the git repo"), + (link=="") ? link : ":\n"+link ), + "", 2, parent ); + std::ignore = dialog.exec(); +} + +void DialogSec::errHelpNotFound( const QString& link, QWidget* parent ) +{ + DialogSec::errHelpFailed( + link, + DialogSec::tr("Unable to retrieve the file").toLower(), + parent ); +} + +void DialogSec::errHelpNotReadable( const QString& link, QWidget* parent ) +{ + DialogSec::errHelpFailed( + link, + DialogSec::tr("The file is not readable").toLower(), + parent ); +} + + + +////////////////////////// +//// WARN/BLACK LISTS //// +////////////////////////// +void DialogSec::warnInvalidItemBW( QWidget* parent ) +{ + DialogMsg dialog = DialogMsg( + DialogSec::tr("Invalid string"), + DialogSec::tr("The given string is invalid and cannot be added to the list\n\nPlease correct it and retry"), + "", 1, parent ); + std::ignore = dialog.exec(); +} + + + +////////////////// +//// DATABASE //// +////////////////// +void DialogSec::errSqlDriverNotFound( const QString& driver, QWidget* parent ) +{ + DialogMsg dialog = DialogMsg( + DialogSec::tr("QSql driver not found"), + QString("%1:\n%2\n\n%3").arg( + DialogSec::tr("Failed to retrieve the driver neede to handle the database"), + driver, + DialogSec::tr("Aborting") ), + "", 2, parent ); + std::ignore = dialog.exec(); +} + +const bool DialogSec::choiceDatabaseNotFound( const QString& db_name, QWidget* parent ) +{ + DialogBool dialog = DialogBool( + DialogSec::tr("File not found"), + QString("%1:\n%2\n\n%3").arg( + DialogSec::tr("Failed to retrieve the database file"), + db_name, + DialogSec::tr("Create a new database?") ), + parent ); + const bool choice = dialog.exec(); + return choice; +} + +const bool DialogSec::choiceDatabaseWrongTable(const QString& db_name, const QString& table_name, QWidget* parent ) +{ + QString msg = QString("%1:\n%2 -> %3").arg( + DialogSec::tr("The database contains an unexpected table"), + db_name, table_name ); + return choiceDatabaseRenew( + DialogSec::tr("Unexpected table"), + msg, + parent ); +} +const bool DialogSec::choiceDatabaseMissingTable( const QString& db_name, const QString& table_name, QWidget* parent ) +{ + QString msg = QString("%1:\n%2 -> %3").arg( + DialogSec::tr("It seems that the database is missing a table"), + db_name, table_name ); + return choiceDatabaseRenew( + DialogSec::tr("Table not found"), + msg, + parent ); +} +const bool DialogSec::choiceDatabaseWrongColumn( const QString& db_name, const QString& table_name, const QString& column_name, QWidget* parent ) +{ + QString msg = QString("%1:\n%2 -> %3 -> %4").arg( + DialogSec::tr("The database contains an unexpected column"), + db_name, table_name, column_name ); + return choiceDatabaseRenew( + DialogSec::tr("Unexpected column"), + msg, + parent ); +} +const bool DialogSec::choiceDatabaseMissingColumn( const QString& db_name, const QString& table_name, const QString& column_name, QWidget* parent ) +{ + QString msg = QString("%1:\n%2 -> %3 -> %4").arg( + DialogSec::tr("It seems that the table is missing a column"), + db_name, table_name, column_name ); + return choiceDatabaseRenew( + DialogSec::tr("Column not found"), + msg, + parent ); +} +const bool DialogSec::choiceDatabaseWrongDataType( const QString& db_name, const QString& table_name, const QString& column_name, const QString& data_type, QWidget* parent ) +{ + QString msg = QString("%1:\n%2 -> %3 -> %4 -> %5").arg( + DialogSec::tr("A column has an unexpected data-type"), + db_name, table_name, column_name, data_type ); + return choiceDatabaseRenew( + DialogSec::tr("Unexpected data-type"), + msg, + parent ); +} +const bool DialogSec::choiceDatabaseRenew( const QString& title, const QString& msg, QWidget* parent ) +{ + DialogBool dialog = DialogBool( + title, + QString("%1\n\n%2").arg( + msg, + DialogSec::tr("This database will renamed with a trailing '.copy' and a new one will be created.\nContinue?") ), + parent ); + const bool choice = dialog.exec(); + return choice; +} +void DialogSec::msgDatabaseCreated( const QString& db_name, QWidget* parent ) +{ + DialogMsg dialog = DialogMsg( + DialogSec::tr("Database created"), + QString("%1:\n%2").arg( + DialogSec::tr("Successfully created a new database"), + db_name ), + "", 0, parent ); + std::ignore = dialog.exec(); +} + +void DialogSec::errDatabaseNotFile( const QString& db_name, QWidget* parent ) +{ + DialogMsg dialog = DialogMsg( + DialogSec::tr("Not a file"), + QString("%1\n\n%2:\n%3\n\n%4").arg( + DialogSec::tr("Failed to retrieve the database file"), + DialogSec::tr("The path was supposed to point to a file, but it doesn't"), + db_name, + DialogSec::tr("Please remove the conflict and retry") ), + "", 2, parent ); + std::ignore = dialog.exec(); +} + +void DialogSec::errDatabaseNotReadable( const QString& db_name, QWidget* parent ) +{ + DialogMsg dialog = DialogMsg( + DialogSec::tr("File not readable"), + QString("%1:\n%2\n\n%3").arg( + DialogSec::tr("The database file is not readable"), + db_name, + DialogSec::tr("Please set the proper permissions and retry\nIf this error persists, please report this issue") ), + "", 2, parent ); + std::ignore = dialog.exec(); +} + +void DialogSec::errDatabaseNotWritable( const QString& db_name, QWidget* parent ) +{ + DialogMsg dialog = DialogMsg( + DialogSec::tr("File not writable"), + QString("%1:\n%2\n\n%3").arg( + DialogSec::tr("The database file is not writable"), + db_name, + DialogSec::tr("Please set the proper permissions and retry\nIf this error persists, please report this issue") ), + "", 2, parent ); + std::ignore = dialog.exec(); +} + +void DialogSec::errDatabaseFailedCreating( const QString& db_name, QWidget* parent ) +{ + DialogMsg dialog = DialogMsg( + DialogSec::tr("Failed creating database"), + QString("%1:\n%2\n\n%3").arg( + DialogSec::tr("An error occured while creating the database"), + db_name, + DialogSec::tr("Aborting") ), + "", 2, parent ); + std::ignore = dialog.exec(); +} + +void DialogSec::errDatabaseFailedOpening( const QString& db_name, const QString& err, QWidget* parent ) +{ + DialogMsg dialog = DialogMsg( + DialogSec::tr("Failed opening database"), + QString("%1:\n%2\n\n%3").arg( + DialogSec::tr("An error occured while opening the database"), + db_name, + DialogSec::tr("Aborting") ), + err, 2, parent ); + std::ignore = dialog.exec(); +} + +void DialogSec::errDatabaseFailedExecuting( const QString& db_name, const QString& statement, const QString& err, QWidget* parent ) +{ + DialogMsg dialog = DialogMsg( + DialogSec::tr("Failed executing on database"), + QString("%1:\n%2%3\n\n%4").arg( + DialogSec::tr("An error occured while executing a statement on the database"), + db_name, + (statement.size()>0) ? "\n"+statement : "", + DialogSec::tr("Aborting") ), + err, 2, parent ); + std::ignore = dialog.exec(); +} + +void DialogSec::errDatabaseFailedBackup( const QString& msg, const QString& err, QWidget* parent ) +{ + DialogMsg dialog = DialogMsg( + DialogSec::tr("Failed to backup database"), + QString("%1\n\n%2").arg( + msg, + DialogSec::tr("Please report this issue") ), + err, 2, parent ); + std::ignore = dialog.exec(); +} + + + +///////////////////// +//// LOGS FORMAT //// +///////////////////// +void DialogSec::errInvalidLogFormatString( const QString& msg, QWidget* parent ) +{ + DialogMsg dialog = DialogMsg( + DialogSec::tr("Invalid log format string"), + DialogSec::tr("Please check that no error is thrown by your WebServer\nIf it gets accepted, please check the presence of a typo here\nIf everything is fine, please report this issue"), + msg, 2, parent ); + std::ignore = dialog.exec(); +} + +void DialogSec::errLogFormatNotSet( QWidget* parent ) +{ + DialogMsg dialog = DialogMsg( + DialogSec::tr("Log format error"), + QString("%1").arg( + DialogSec::tr("The log format has not been set, or is invalid\nPlease add a valid one in the configurations") ), + "", 2, parent ); + std::ignore = dialog.exec(); +} + +void DialogSec::errLogFormatNoFields( QWidget* parent ) +{ + DialogMsg dialog = DialogMsg( + DialogSec::tr("Misconfigured log format"), + QString("%1\n\n%2").arg( + DialogSec::tr("No log field has been set in the current logs format,\nmaking it useless to parse logs"), + DialogSec::tr("Please set up a format which contains at least one field") ), + "", 2, parent ); + std::ignore = dialog.exec(); +} + +void DialogSec::errLogFormatNoSeparators( QWidget* parent ) +{ + DialogMsg dialog = DialogMsg( + DialogSec::tr("Misconfigured log format"), + QString("%1\n\n%2").arg( + DialogSec::tr("A separator is missing between one or more fields,\nmaking it hard to establish net bounds,\nand possibly leading to store incorrect data"), + DialogSec::tr("Please set up a format which contains separators between fields") ), + "", 2, parent ); + std::ignore = dialog.exec(); +} + +void DialogSec::errFailedParsingLogs( const QString& message, QWidget* parent ) +{ + DialogMsg dialog = DialogMsg( + DialogSec::tr("An error occured while parsing logs"), + message, + "", 2, parent ); + std::ignore = dialog.exec(); +} + + + +/////////////////// +//// LOG FILES //// +/////////////////// +void DialogSec::errFailedDefiningLogType( const QString& file, QWidget* parent ) +{ + DialogMsg dialog = DialogMsg( + DialogSec::tr("Failed defining type"), + QString("%1:\n%2").arg( + DialogSec::tr("Failed to determine the log type"), + file ), + "", 2, parent ); + std::ignore = dialog.exec(); +} + + +const int DialogSec::choiceFileAlreadyUsed( const QString& msg, QWidget* parent ) +{ + DialogDia dialog = DialogDia( + DialogSec::tr("File already used"), + QString("%1:\n%2\n\n%3").arg( + DialogSec::tr("The file has probably been used already"), + msg, + DialogSec::tr("Ignore the warning and use it anyway, Discard it and continue, or Abort the entire process?") ), + true, true, true, parent ); + const int choice = dialog.exec(); + return choice; +} + + +const int DialogSec::choiceFileSizeWarning( const QString& msg, QWidget* parent ) +{ + DialogDia dialog = DialogDia( + DialogSec::tr("File exceeds warning size"), + QString("%1:\n%2\n\n%3").arg( + DialogSec::tr("The file's size exceeds the warning size"), + msg, + DialogSec::tr("Ignore the warning and use it anyway, Discard it and continue, or Abort the entire process?") ), + true, true, true, parent ); + const int choice = dialog.exec(); + return choice; +} +const bool DialogSec::choiceFileSizeWarning2( const QString& msg, QWidget* parent ) +{ + DialogBool dialog = DialogBool( + DialogSec::tr("File exceeds warning size"), + QString("%1:\n%2\n\n%3").arg( + DialogSec::tr("The file's size exceeds the warning size"), + msg, + DialogSec::tr("Proceed anyway?") ), + parent ); + const bool choice = dialog.exec(); + return choice; +} + + +void DialogSec::errFailedReadFile( const QString& file , const bool& skipping, QWidget* parent ) +{ + DialogMsg dialog = DialogMsg( + DialogSec::tr("Failed reading"), + QString("%1:\n%2").arg( + DialogSec::tr("An error accured while reading the file"), + file + ((skipping) ? DialogSec::tr("Skipping") : "") ), + "", 2, parent ); + std::ignore = dialog.exec(); +} + +/*void DialogSec::errFailedWriteFile( const QString& file , const bool& skipping, QWidget* parent ) +{ + DialogMsg dialog = DialogMsg( + DialogSec::tr("Failed writing"), + QString("%1:\n%2%3").arg( + DialogSec::tr("An error accured while writing the file"), + file, + (skipping) ? QString("\n\n%1").arg(DialogSec::tr("Skipping")) : "" ), + "", 2, parent ); + std::ignore = dialog.exec(); +}*/ + + +void DialogSec::warnEmptyFile( const QString& file, QWidget* parent ) +{ + DialogMsg dialog = DialogMsg( + DialogSec::tr("File is empty"), + QString("%1:\n%2\n\n%3").arg( + DialogSec::tr("The file is blank"), + file, + DialogSec::tr("Skipping") ), + "", 1, parent ); + std::ignore = dialog.exec(); +} + +void DialogSec::errFileNotFound( const QString& file , const bool& report, QWidget* parent ) +{ + DialogMsg dialog = DialogMsg( + DialogSec::tr("File not found"), + QString("%1:\n%2%3").arg( + DialogSec::tr("Unable to retrieve the file"), + file, + ( report ) ? QString("\n\n%1").arg(DialogSec::tr("Please report this issue")) : "" ), + "", 2, parent ); + std::ignore = dialog.exec(); +} + +void DialogSec::warnFileNotReadable( const QString& file, QWidget* parent ) +{ + DialogMsg dialog = DialogMsg( + DialogSec::tr("File not readable"), + QString("%1:\n%2\n\n%3").arg( + DialogSec::tr("The file is not readable"), + file, + DialogSec::tr("Skipping") ), + "", 1, parent ); + std::ignore = dialog.exec(); +} + + + +const int DialogSec::choiceSelectedFileNotFound( const QString& file, QWidget* parent ) +{ + DialogDia dialog = DialogDia( + DialogSec::tr("File not found"), + QString("%1:\n%2\n\n%3").arg( + DialogSec::tr("Failed to retrieve the selected file"), + file, + DialogSec::tr("Discard it and continue, or Abort all and exit?") ), + false, true, true, parent ); + const int choice = dialog.exec(); + return choice; +} + + + +///////////////////// +//// PERMISSIONS //// +///////////////////// +void DialogSec::errDirNotExists( const QString& dir, QWidget* parent ) +{ + DialogMsg dialog = DialogMsg( + DialogSec::tr("Directory not found"), + QString("%1:\n%2").arg( + DialogSec::tr("The directory does not exists"), + dir ), + "", 2, parent ); + std::ignore = dialog.exec(); +} + +/*const int DialogSec::choiceDirNotExists( const QString& dir, QWidget* parent ) +{ + DialogDia dialog = DialogDia( + DialogSec::tr("Directory not found"), + QString("%1:\n%2\n\n%3").arg( + DialogSec::tr("The directory does not exists"), + dir, + DialogSec::tr("Discard it and continue, or Abort all and exit?") ), + false, true, true, parent ); + const int choice = dialog.exec(); + return choice; +}*/ + + +void DialogSec::errDirNotReadable( const QString& dir, const QString& err, QWidget* parent ) +{ + DialogMsg dialog = DialogMsg( + DialogSec::tr("Directory not readable"), + QString("%1:\n%2\n\n%3").arg( + DialogSec::tr("The directory is not readable"), + dir, + DialogSec::tr("Please set the proper permissions and retry\nIf this error persists, please report this issue") ), + err, 2, parent ); + std::ignore = dialog.exec(); +} +void DialogSec::warnDirNotReadable( QWidget* parent ) +{ + DialogMsg dialog = DialogMsg( + DialogSec::tr("Directory not readable"), + QString("%1\n\n%2").arg( + DialogSec::tr("The directory is not readable"), + DialogSec::tr("Please set the proper permissions before to start") ), + "", 1, parent ); + std::ignore = dialog.exec(); +} + +void DialogSec::errDirNotWritable( const QString& dir, const QString& err, QWidget* parent ) +{ + DialogMsg dialog = DialogMsg( + DialogSec::tr("Directory not writable"), + QString("%1:\n%2\n\n%3").arg( + DialogSec::tr("The directory is not writable"), + dir, + DialogSec::tr("Please set the proper permissions and retry\nIf this error persists, please report this issue") ), + err, 2, parent ); + std::ignore = dialog.exec(); +} +void DialogSec::warnDirNotWritable( QWidget* parent ) +{ + DialogMsg dialog = DialogMsg( + DialogSec::tr("Directory not writable"), + QString("%1\n\n%2").arg( + DialogSec::tr("The directory is not writable"), + DialogSec::tr("Please set the proper permissions before to start") ), + "", 1, parent ); + std::ignore = dialog.exec(); +} + +void DialogSec::errFailedMakeDir( const QString& msg, const QString& err, QWidget* parent ) +{ + DialogMsg dialog = DialogMsg( + DialogSec::tr("Failed creating directory"), + QString("%1\n\n%2").arg( + msg, + DialogSec::tr("Please set the proper permissions and retry\nIf this error persists, please report this issue") ), + err, 2, parent ); + std::ignore = dialog.exec(); +} + + +////////////////// +//// GENERICS //// +////////////////// +const bool DialogSec::choiceDirNotDir( const QString& path, QWidget* parent ) +{ + DialogBool dialog = DialogBool( + DialogSec::tr("Not a folder"), + QString("%1:\n%2\n\n%3").arg( + DialogSec::tr("The path was supposed to point to a folder, but it doesn't"), + path, + DialogSec::tr("The entry will renamed with a trailing '.copy' and a new one will be created.\nContinue?") ), + parent ); + const bool choice = dialog.exec(); + return choice; +} +const bool DialogSec::choiceFileNotFile( const QString& path, QWidget* parent ) +{ + DialogBool dialog = DialogBool( + DialogSec::tr("Not a file"), + QString("%1:\n%2\n\n%3").arg( + DialogSec::tr("The path was supposed to point to a file, but it doesn't"), + path, + DialogSec::tr("The entry will renamed with a trailing '.copy' and a new one will be created.\nContinue?") ), + parent ); + const bool choice = dialog.exec(); + return choice; +} + + + +/*void DialogSec::warnGeneric( const QString& msg, const bool& report_msg, QWidget* parent ) +{ + QString footer = ""; + if ( report_msg ) { + footer += "\n\n" + DialogSec::tr("Please report this issue"); + } + DialogMsg dialog = DialogMsg( + DialogSec::tr("An error occured"), + QString("%1%2").arg( + msg, footer ), + "", 1, parent ); + std::ignore = dialog.exec(); +}*/ + + + +void DialogSec::errGeneric( const QString& msg, const bool& report_msg, QWidget* parent ) +{ + QString footer = ""; + if ( report_msg ) { + footer += "\n\n" + DialogSec::tr("Please report this issue"); + } + DialogMsg dialog = DialogMsg( + DialogSec::tr("An error occured"), + QString("%1%2").arg( + msg, footer ), + "", 2, parent ); + std::ignore = dialog.exec(); +} + + + +void DialogSec::errRenaming( const QString& path, const QString& err, QWidget* parent ) +{ + DialogMsg dialog = DialogMsg( + DialogSec::tr("Failed renaming"), + QString("%1:\n%2\n\n%3").arg( + DialogSec::tr("An error occured while renaming"), + path, + DialogSec::tr("Aborting") ), + err, 2, parent ); + std::ignore = dialog.exec(); +} diff --git a/logdoctor/modules/dialogs.h b/logdoctor/modules/dialogs.h new file mode 100644 index 00000000..61b43815 --- /dev/null +++ b/logdoctor/modules/dialogs.h @@ -0,0 +1,244 @@ +#ifndef DIALOGS_H +#define DIALOGS_H + +#include +#include + + +//! DialogSec +/*! + Implements various dialog models + \see DialogMsg, DialogBool, DialogDia +*/ +class DialogSec : public QObject +{ + Q_OBJECT + +public: + DialogSec(); + + ///////////////// + //// GENERIC //// + + /*static void warnGeneric( const QString& message, const bool& report_msg=false, QWidget* parent=nullptr );*/ + + //! Generic error message + static void errGeneric( const QString& message, const bool& report_msg=false, QWidget* parent=nullptr ); + + //! Error while renaming + static void errRenaming( const QString& path, const QString& err, QWidget* parent=nullptr ); + + + ////////////////// + //// LANGUAGE //// + + //! Invalid locale found + static void errLangLocaleInvalid( const QString& locale, QWidget* parent=nullptr ); + + //! Language not supported + static void errLangNotAccepted( const QString& locale, QWidget* parent=nullptr ); + + + //////////////////////// + //// CONFIGURATIONS //// + + //! Failed to write the configurations on file + static void errConfFailedWriting( const QString& msg, const QString& err, QWidget* parent=nullptr ); + + //! Configuration file not found + static void warnConfFileNotFound( const QString& file, QWidget* parent=nullptr ); + + //! Missing read permission for the configuration file + static void errConfFileNotReadable( const QString& file, const QString& err, QWidget* parent=nullptr ); + + //! Missing write permission for the configuration file + static void errConfFileNotWritable( const QString& file, const QString& err, QWidget* parent=nullptr ); + + //! Missing read permission for the configuration file's directory + static void errConfDirNotWritable( const QString& dir, const QString& err, QWidget* parent=nullptr ); + + //! Missing write permission for the configuration file's directory + static void errFailedApplyingConfigs( const QString& msg, QWidget* parent=nullptr ); + + + ////////////// + //// HELP //// + + //! Help resource is not a file + static void errHelpFailed( const QString& link, const QString& msg, QWidget* parent=nullptr ); + + //! Help file not found + static void errHelpNotFound( const QString& link, QWidget* parent=nullptr ); + + //! Missing read permission for the help file + static void errHelpNotReadable( const QString& link, QWidget* parent=nullptr ); + + + ////////////////// + //// DATABASE //// + + //! SQLite driver not installed or not found + static void errSqlDriverNotFound( const QString& driver, QWidget* parent=nullptr ); + + //! Database file not found + static const bool choiceDatabaseNotFound( const QString& db_name, QWidget* parent=nullptr ); + + //! A database contains an unexpected table + static const bool choiceDatabaseWrongTable( const QString& db_name, const QString& table_name, QWidget* parent=nullptr ); + + //! A table is missing from the database + static const bool choiceDatabaseMissingTable( const QString& db_name, const QString& table_name, QWidget* parent=nullptr ); + + //! A database contains a table with an unexpected column + static const bool choiceDatabaseWrongColumn( const QString& db_name, const QString& table_name, const QString& column_name, QWidget* parent=nullptr ); + + //! A column is missing from table of the database + static const bool choiceDatabaseMissingColumn( const QString& db_name, const QString& table_name, const QString& column_name, QWidget* parent=nullptr ); + + //! A column has an unexpected type parameter + static const bool choiceDatabaseWrongDataType( const QString& db_name, const QString& table_name, const QString& column_name, const QString& data_type, QWidget* parent=nullptr ); + + //! The entry corresponding to the database path is not a file + static void errDatabaseNotFile( const QString& db_name, QWidget* parent=nullptr ); + + //! Missing read permission for a database + static void errDatabaseNotReadable( const QString& db_name, QWidget* parent=nullptr ); + + //! Missing write permission for a database + static void errDatabaseNotWritable( const QString& db_name, QWidget* parent=nullptr ); + + //! Successfully created a new database + static void msgDatabaseCreated( const QString& db_name, QWidget* parent=nullptr ); + + //! Failed to create a new database + static void errDatabaseFailedCreating( const QString& db_name, QWidget* parent=nullptr ); + + //! Failed to open a database + static void errDatabaseFailedOpening( const QString& db_name, const QString& err, QWidget* parent=nullptr ); + + //! Failed to execute a statement on a database + static void errDatabaseFailedExecuting( const QString& db_name, const QString& statement, const QString& err, QWidget* parent=nullptr ); + + //! Failed to backup a database + static void errDatabaseFailedBackup( const QString& msg, const QString& err, QWidget* parent=nullptr ); + + + /////////////////// + //// LOGS-LIST //// + + //! A log file which has been selected to be used is no more available + static const int choiceSelectedFileNotFound( const QString& file, QWidget* parent=nullptr ); + + + //////////////////////////// + //// WARNLIST/BLACKLIST //// + + //! An item can't be added to a warnlist/blacklist + static void warnInvalidItemBW( QWidget* parent=nullptr ); + + + ////////////////// + //// LOG TYPE //// + + //! The log type can't be defined for a file + static void errFailedDefiningLogType( const QString& file, QWidget* parent=nullptr ); + + //////////////////// + //// LOG HASHES //// + + //! A log file has already been used + static const int choiceFileAlreadyUsed( const QString& msg, QWidget* parent=nullptr ); + + /////////////////// + //// LOGS SIZE //// + + //! A log file exceeds the warning size + static const int choiceFileSizeWarning( const QString& msg, QWidget* parent=nullptr ); + + //! A log file exceeds the warning size + static const bool choiceFileSizeWarning2( const QString& msg, QWidget* parent=nullptr ); + + + ///////////////////// + //// LOGS FORMAT //// + + //! Failed to process a logs format string + static void errInvalidLogFormatString( const QString& msg, QWidget* parent=nullptr ); + + //! The logs format has not been set for the web server in use + static void errLogFormatNotSet( QWidget* parent=nullptr ); + + //! The log format in use has no log fields + static void errLogFormatNoFields( QWidget* parent=nullptr ); + + //! The log format in use has no log separators + static void errLogFormatNoSeparators( QWidget* parent=nullptr ); + + + ///////////////////// + //// LOGS PARSER //// + + //! An error occured while parsing logs + static void errFailedParsingLogs( const QString& message, QWidget* parent=nullptr ); + + + /////////////// + //// FILES //// + + //! File not found + static void errFileNotFound( const QString& file, const bool& report=false, QWidget* parent=nullptr ); + + //! Missing read permission for a file + static void warnFileNotReadable( const QString& file, QWidget* parent=nullptr ); + + //! A file is empty + static void warnEmptyFile( const QString& file, QWidget* parent=nullptr ); + + //! An error occured while reading a file + static void errFailedReadFile( const QString& file, const bool& skipping=false, QWidget* parent=nullptr ); + + /*static void errFailedWriteFile( const QString& file, const bool& skipping=false, QWidget* parent=nullptr );*/ + + + ///////////////// + //// FOLDERS //// + + /*static const int choiceDirNotExists( const QString& dir, QWidget* parent=nullptr );*/ + + //! A directory does not extst + static void errDirNotExists( const QString& dir, QWidget* parent=nullptr ); + + //! Missing read permission for a directory + static void errDirNotReadable( const QString& dir, const QString& err, QWidget* parent=nullptr ); + + //! Missing write permission for a directory + static void errDirNotWritable( const QString& dir, const QString& err, QWidget* parent=nullptr ); + + //! Missing read permission for a directory + static void warnDirNotReadable( QWidget* parent=nullptr ); + + //! Missing write permission for a directory + static void warnDirNotWritable( QWidget* parent=nullptr ); + + //! Failed to create a directory + static void errFailedMakeDir( const QString& msg, const QString& err, QWidget* parent=nullptr ); + + ///////////////// + //// CHOICES //// + + //! An entry was supposed to be a directory but it's not + static const bool choiceDirNotDir( const QString& path, QWidget* parent=nullptr ); + + //! An entry was supposed to be a file but it's not + static const bool choiceFileNotFile( const QString& path, QWidget* parent=nullptr ); + + + +private: + + //! Asks to renew a database + static const bool choiceDatabaseRenew( const QString& title, const QString& msg, QWidget* parent=nullptr ); + +}; + +#endif // DIALOGS_H diff --git a/logdoctor/modules/dialogs/dialogbool.cpp b/logdoctor/modules/dialogs/dialogbool.cpp new file mode 100644 index 00000000..c291eda3 --- /dev/null +++ b/logdoctor/modules/dialogs/dialogbool.cpp @@ -0,0 +1,34 @@ + +#include "dialogbool.h" +#include "ui_dialogbool.h" + + +DialogBool::DialogBool( const QString& title, const QString& text, QWidget *parent ) : + QDialog(parent), + ui(new Ui::DialogBool) +{ + ui->setupUi(this); + + // insert the given title and text + this->ui->label_Title->setText( title ); + this->ui->label_Message->setText( text ); + + // adjust the initial size + this->adjustSize(); +} + +DialogBool::~DialogBool() +{ + delete ui; +} + + +void DialogBool::on_button_NO_clicked() +{ + this->done( 0 ); +} + +void DialogBool::on_button_YES_clicked() +{ + this->done( 1 ); +} diff --git a/logdoctor/modules/dialogs/dialogbool.h b/logdoctor/modules/dialogs/dialogbool.h new file mode 100644 index 00000000..2c69b654 --- /dev/null +++ b/logdoctor/modules/dialogs/dialogbool.h @@ -0,0 +1,42 @@ +#ifndef DIALOGBOOL_H +#define DIALOGBOOL_H + +#include + + +namespace Ui { + class DialogBool; +} + +//! DialogBool +/*! + YES/NO choice dialog +*/ +class DialogBool : public QDialog +{ + Q_OBJECT + +public: + + //! Dialog constructor + /*! + \param title The title + \param text The message + \param parent The parent Widget + */ + DialogBool( const QString& title, const QString& text, QWidget *parent=nullptr ); + ~DialogBool(); + +private slots: + + //! Called when the NO button gets clicked + void on_button_NO_clicked(); + + //! Called when the YES button gets clicked + void on_button_YES_clicked(); + +private: + Ui::DialogBool *ui; +}; + +#endif // DIALOGBOOL_H diff --git a/logdoctor/modules/dialogs/dialogbool.ui b/logdoctor/modules/dialogs/dialogbool.ui new file mode 100644 index 00000000..f9388273 --- /dev/null +++ b/logdoctor/modules/dialogs/dialogbool.ui @@ -0,0 +1,210 @@ + + + DialogBool + + + + 0 + 0 + 512 + 256 + + + + + 512 + 192 + + + + + Metropolis + 13 + + + + + :/logo/logo/logdoctor.svg:/logo/logo/logdoctor.svg + + + true + + + + + + + 0 + 0 + + + + + 0 + + + 0 + + + + + + 64 + 64 + + + + + 64 + 64 + + + + :/icons/icons/dialogs/quest.png + + + Qt::AlignCenter + + + + + + + + 0 + 64 + + + + + 16777215 + 64 + + + + + Metropolis + 13 + + + + + + + true + + + 8 + + + + + + + + 0 + 0 + + + + + 0 + 24 + + + + + Metropolis + 13 + + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + true + + + 4 + + + + + + + + + + + 0 + 48 + + + + + 16777215 + 48 + + + + + + + Qt::Horizontal + + + + 333 + 27 + + + + + + + + + 96 + 32 + + + + + 96 + 32 + + + + Yes + + + + + + + + 96 + 32 + + + + + 96 + 32 + + + + No + + + + + + + + + + + + + diff --git a/logdoctor/modules/dialogs/dialogdia.cpp b/logdoctor/modules/dialogs/dialogdia.cpp new file mode 100644 index 00000000..f6c1724b --- /dev/null +++ b/logdoctor/modules/dialogs/dialogdia.cpp @@ -0,0 +1,52 @@ + +#include "dialogdia.h" +#include "ui_dialogdia.h" + + +DialogDia::DialogDia( const QString& title, const QString& text, const bool& ignore, const bool& discard, const bool& abort, QWidget *parent ) : + QDialog(parent), + ui(new Ui::DialogDia) +{ + ui->setupUi(this); + + // (un)set the button if needed + if ( !ignore ) { + this->ui->button_IGNORE->setEnabled( false ); + this->ui->button_IGNORE->setVisible( false ); + } + if ( !discard ) { + this->ui->button_DISCARD->setEnabled( false ); + this->ui->button_DISCARD->setVisible( false ); + } + if ( !abort ) { + this->ui->button_ABORT->setEnabled( false ); + this->ui->button_ABORT->setVisible( false ); + } + + // insert the given title and text + this->ui->label_Title->setText( title ); + this->ui->label_Message->setText( text ); + + // adjust the initial size + this->adjustSize(); +} + +DialogDia::~DialogDia() +{ + delete ui; +} + +void DialogDia::on_button_IGNORE_clicked() +{ + this->done( 2 ); +} + +void DialogDia::on_button_DISCARD_clicked() +{ + this->done( 1 ); +} + +void DialogDia::on_button_ABORT_clicked() +{ + this->done( 0 ); +} diff --git a/logdoctor/modules/dialogs/dialogdia.h b/logdoctor/modules/dialogs/dialogdia.h new file mode 100644 index 00000000..b67e37c5 --- /dev/null +++ b/logdoctor/modules/dialogs/dialogdia.h @@ -0,0 +1,48 @@ +#ifndef DIALOGDIA_H +#define DIALOGDIA_H + +#include + + +namespace Ui { + class DialogDia; +} + +//! DialogDia +/*! + DISCARD/IGNORE/ABORT choice dialog +*/ +class DialogDia : public QDialog +{ + Q_OBJECT + +public: + + //! Dialog constructor + /*! + \param title The title + \param text The message + \param ignore Whether to show the IGNORE button or not + \param discard Whether to show the DISCARD button or not + \param abort Whether to show the ABORT button or not + \param parent The parent Widget + */ + DialogDia( const QString& title, const QString& text, const bool& ignore=true, const bool& discard=true, const bool& abort=true, QWidget *parent=nullptr ); + ~DialogDia(); + +private slots: + + //! Called when the IGNORE button gets clicked + void on_button_IGNORE_clicked(); + + //! Called when the DISCARD button gets clicked + void on_button_DISCARD_clicked(); + + //! Called when the ABORT button gets clicked + void on_button_ABORT_clicked(); + +private: + Ui::DialogDia *ui; +}; + +#endif // DIALOGDIA_H diff --git a/logdoctor/modules/dialogs/dialogdia.ui b/logdoctor/modules/dialogs/dialogdia.ui new file mode 100644 index 00000000..0d9dbe0f --- /dev/null +++ b/logdoctor/modules/dialogs/dialogdia.ui @@ -0,0 +1,229 @@ + + + DialogDia + + + + 0 + 0 + 512 + 256 + + + + + 512 + 192 + + + + + Metropolis + 13 + + + + + :/logo/logo/logdoctor.svg:/logo/logo/logdoctor.svg + + + true + + + + + + + 0 + 0 + + + + + 0 + + + 0 + + + + + + 64 + 64 + + + + + 64 + 64 + + + + :/icons/icons/dialogs/quest.png + + + Qt::AlignCenter + + + + + + + + 0 + 64 + + + + + 16777215 + 64 + + + + + Metropolis + 13 + + + + + + + true + + + 8 + + + + + + + + 0 + 0 + + + + + 0 + 24 + + + + + Metropolis + 13 + + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + true + + + 4 + + + + + + + + + + + 0 + 48 + + + + + 16777215 + 48 + + + + + + + Qt::Horizontal + + + + 333 + 27 + + + + + + + + + 96 + 32 + + + + + 96 + 32 + + + + Ignore + + + + + + + + 96 + 32 + + + + + 96 + 32 + + + + Discard + + + + + + + + 96 + 32 + + + + + 96 + 32 + + + + Abort + + + + + + + + + + + + + diff --git a/logdoctor/modules/dialogs/dialogmsg.cpp b/logdoctor/modules/dialogs/dialogmsg.cpp new file mode 100644 index 00000000..8b106deb --- /dev/null +++ b/logdoctor/modules/dialogs/dialogmsg.cpp @@ -0,0 +1,88 @@ + +#include "dialogmsg.h" +#include "ui_dialogmsg.h" + +#include "modules/exceptions.h" + +#include +#include +#include + + +DialogMsg::DialogMsg(const QString& title, const QString& text, const QString& additional, const int& type, QWidget* parent ) : + QDialog(parent), + ui(new Ui::DialogMsg) +{ + ui->setupUi(this); + + // icon + switch (type) { + case 0: + // info message + this->ui->label_Icon->setPixmap( QPixmap(":/icons/icons/dialogs/info.png") ); + break; + case 1: + // warning message + this->ui->label_Icon->setPixmap( QPixmap(":/icons/icons/dialogs/warn.png") ); + break; + case 2: + // error message + this->ui->label_Icon->setPixmap( QPixmap(":/icons/icons/dialogs/err.png") ); + break; + default: + // shouldn't be here + throw GenericException("Unexpected dialog type: "+ std::to_string(type)); + } + + // insert the given text + this->ui->label_Title->setText( title ); + this->ui->label_Message->setText( text ); + + // additional info, hide by default + this->ui->frame_Additional->setVisible( false ); + if ( additional.size() == 0 ) { + this->ui->button_ShowAdditional->setEnabled( false ); + this->ui->button_ShowAdditional->setVisible( false ); + } else { + this->ui->text_Additional->setText( additional ); + } + + // adjust the initial size + this->adjustSize(); +} + +DialogMsg::~DialogMsg() +{ + delete ui; +} + + +void DialogMsg::on_button_ShowAdditional_clicked() +{ + this->additional_shown = ! this->additional_shown; + // set additional info visibility + this->ui->frame_Additional->setVisible( this->additional_shown ); + // set the icon + QIcon icon; + if ( this->additional_shown ) { + icon = QIcon(":/icons/icons/up.png"); + // resize + this->initial_height = this->height(); + if ( this->additional_height > 0 ) { + this->resize( this->width(), this->additional_height ); + } else { + this->resize( this->width(), this->height()+100 ); + } + } else { + icon = QIcon(":/icons/icons/down.png"); + this->additional_height = this->height(); + this->resize( this->width(), this->initial_height ); + } + this->ui->button_ShowAdditional->setIcon( icon ); +} + + +void DialogMsg::on_button_Ok_clicked() +{ + this->done( 1 ); +} diff --git a/logdoctor/modules/dialogs/dialogmsg.h b/logdoctor/modules/dialogs/dialogmsg.h new file mode 100644 index 00000000..cc2d1cd5 --- /dev/null +++ b/logdoctor/modules/dialogs/dialogmsg.h @@ -0,0 +1,48 @@ +#ifndef DIALOGMSG_H +#define DIALOGMSG_H + +#include + + +namespace Ui { + class DialogMsg; +} + +//! DialogMsg +/*! + A dialog message to provide informations to the user +*/ +class DialogMsg : public QDialog +{ + Q_OBJECT + +public: + + //! Dialog constructor + /*! + \param title The title + \param text The message + \param additional Additional informations, usually an error message + \param parent The parent Widget + */ + DialogMsg( const QString& title, const QString& text, const QString& additional, const int& type, QWidget *parent=nullptr ); + ~DialogMsg(); + +private slots: + + //! Shows the additional informations + void on_button_ShowAdditional_clicked(); + + //! Called when the OK button gets clicked + void on_button_Ok_clicked(); + +private: + Ui::DialogMsg *ui; + + bool additional_shown = false; + + int initial_height = 0; + int additional_height = 0; +}; + +#endif // DIALOGMSG_H diff --git a/logdoctor/modules/dialogs/dialogmsg.ui b/logdoctor/modules/dialogs/dialogmsg.ui new file mode 100644 index 00000000..c3b7d7db --- /dev/null +++ b/logdoctor/modules/dialogs/dialogmsg.ui @@ -0,0 +1,242 @@ + + + DialogMsg + + + + 0 + 0 + 512 + 256 + + + + + 512 + 192 + + + + + Metropolis + 13 + + + + + :/logo/logo/logdoctor.svg:/logo/logo/logdoctor.svg + + + true + + + + + + + 0 + 0 + + + + + 0 + + + 0 + + + + + + 64 + 64 + + + + + 64 + 64 + + + + :/icons/icons/dialogs/info.png + + + Qt::AlignCenter + + + + + + + + 0 + 64 + + + + + 16777215 + 64 + + + + + Metropolis + 13 + + + + + + + true + + + 8 + + + + + + + + 0 + 0 + + + + + 0 + 24 + + + + + Metropolis + 13 + + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + true + + + 4 + + + + + + + + + + + + + + 0 + 24 + + + + + Metropolis + 11 + + + + false + + + + + + + + + + + 0 + 48 + + + + + 16777215 + 48 + + + + + + + + 32 + 32 + + + + + 32 + 32 + + + + + :/icons/icons/down.png:/icons/icons/down.png + + + + 32 + 32 + + + + + + + + Qt::Horizontal + + + + 333 + 27 + + + + + + + + + 96 + 32 + + + + + 96 + 32 + + + + Ok + + + + + + + + + + + + + diff --git a/logdoctor/modules/exceptions.cpp b/logdoctor/modules/exceptions.cpp new file mode 100644 index 00000000..78dc771e --- /dev/null +++ b/logdoctor/modules/exceptions.cpp @@ -0,0 +1,93 @@ + +#include "exceptions.h" + +#include + + +///////////////// +//// GENERIC //// +GenericException::GenericException( const std::string& msg, const bool& to_sys ) +{ + if ( to_sys ) { // when sys, leave un-catched + std::cout << "LogDoctor: Exception: " << msg << std::endl; + std::cerr << "LogDoctor: Exception: " << msg << std::endl; + } else { + this->msg = QString::fromStdString( msg ); + } +} +const QString& GenericException::what() +{ + return msg; +} + + +//////////////////// +//// WEB SERVER //// +WebServerException::WebServerException(const std::string& msg ) // leave un-catched +{ + std::cout << "LogDoctor: WebServerException: " << msg << std::endl; + std::cerr << "LogDoctor: WebServerException: " << msg << std::endl; + /*this->msg = QString::fromStdString( msg );*/ +} +/*const QString& WebServerException::what() +{ + return msg; +}*/ + + +//////////////////// +//// LOG FORMAT //// +LogFormatException::LogFormatException(const std::string& msg ) +{ + std::cout << "LogDoctor: LogFormatException: " << msg << std::endl; + std::cerr << "LogDoctor: LogFormatException: " << msg << std::endl; + this->msg = QString::fromStdString( msg ); +} +const QString& LogFormatException::what() +{ + return msg; +} + + +//////////////////// +//// LOG PARSER //// +LogParserException::LogParserException( const std::string& txt , const std::string& val ) +{ + std::cout << "LogDoctor: LogParserException: " << txt << ": '" << val << "'" << std::endl; + std::cerr << "LogDoctor: LogParserException: " << txt << ": '" << val << "'" << std::endl; + this->msg = QString("%1:\n'%2'").arg( + QString::fromStdString( txt ), + QString::fromStdString( val ) ); +} +const QString& LogParserException::what() +{ + return msg; +} + + +/////////////////// +//// DATE-TIME //// +DateTimeException::DateTimeException(const std::string& msg ) // leave un-catched +{ + std::cout << "LogDoctor: DateTimeException: " << msg << std::endl; + std::cerr << "LogDoctor: DateTimeException: " << msg << std::endl; + /*this->msg = QString::fromStdString( msg );*/ +} +/*const QString& DateTimeException::what() +{ + return msg; +}*/ + + +////////////////////////// +//// BLACK/WARN LISTS //// +BWlistException::BWlistException( const std::string& msg ) +{ + std::cout << "LogDoctor: BWlistException: " << msg << std::endl; + std::cerr << "LogDoctor: BWlistException: " << msg << std::endl; + /*this->msg = QString::fromStdString( msg );*/ +} +/*const QString& DateTimeException::what() +{ + return msg; +}*/ diff --git a/logdoctor/modules/exceptions.h b/logdoctor/modules/exceptions.h new file mode 100644 index 00000000..d0ee465e --- /dev/null +++ b/logdoctor/modules/exceptions.h @@ -0,0 +1,92 @@ +#ifndef EXCEPTIONS_H +#define EXCEPTIONS_H + +#include + +#include + + +//! GenericException +/*! + Generic exception for general purposes +*/ +class GenericException : public std::exception { +public: + GenericException( const std::string& msg , const bool& to_sys=false ); + const QString& what(); + +private: + QString msg; +}; + + +//! WebServerException +/*! + Exception related to a Web Server +*/ +class WebServerException : public std::exception { +public: + WebServerException( const std::string& msg ); + /*const QString& what(); + +private: + QString msg;*/ +}; + + +//! LogFormatException +/*! + Exception related to a Logs Format +*/ +class LogFormatException : public std::exception { +public: + LogFormatException( const std::string& msg ); + const QString& what(); + +private: + QString msg; +}; + + +//! LogParserException +/*! + Exception related to the logs parser +*/ +class LogParserException : public std::exception { +public: + LogParserException( const std::string& txt, const std::string& val ); + const QString& what(); + +private: + QString msg; +}; + + +//! DateTimeException +/*! + Exception related to a date/time +*/ +class DateTimeException : public std::exception { +public: + DateTimeException( const std::string& msg ); + /*const QString& what(); + +private: + QString msg;*/ +}; + + +//! BWlistException +/*! + Exception related to a blacklist/warnlist +*/ +class BWlistException : public std::exception { +public: + BWlistException( const std::string& msg ); + /*const QString& what(); + +private: + QString msg;*/ +}; + +#endif // EXCEPTIONS_H diff --git a/logdoctor/modules/shared.cpp b/logdoctor/modules/shared.cpp new file mode 100644 index 00000000..45adad95 --- /dev/null +++ b/logdoctor/modules/shared.cpp @@ -0,0 +1,9 @@ + +#include "shared.h" + + +TR::TR(QObject *parent) + : QObject{parent} +{ + +} diff --git a/logdoctor/modules/shared.h b/logdoctor/modules/shared.h new file mode 100644 index 00000000..494d6657 --- /dev/null +++ b/logdoctor/modules/shared.h @@ -0,0 +1,61 @@ +#ifndef TR_H +#define TR_H + +#include + + +//! TR +/*! + Fictitious class for the translations +*/ +class TR : public QObject +{ + Q_OBJECT +public: + explicit TR( QObject* parent=nullptr ); +}; + + +const std::string BOOLS__FALSE = TR::tr("FALSE").toStdString(); +const std::string BOOLS__TRUE = TR::tr("TRUE").toStdString(); + +const std::string WORDS__DATE = TR::tr("Date").toStdString(); +const std::string WORDS__TIME = TR::tr("Time").toStdString(); + +const std::string FIELDS__WARNING = TR::tr("Warning").toStdString(); +const std::string FIELDS__PROTOCOL = TR::tr("Protocol").toStdString(); +const std::string FIELDS__METHOD = TR::tr("Method").toStdString(); +const std::string FIELDS__URI = TR::tr("URI").toStdString(); +const std::string FIELDS__QUERY = TR::tr("Query").toStdString(); +const std::string FIELDS__RESPONSE_CODE = TR::tr("Response code").toStdString(); +const std::string FIELDS__TIME_TAKEN = TR::tr("Time taken").toStdString(); +const std::string FIELDS__BYTES_SENT = TR::tr("Bytes sent").toStdString(); +const std::string FIELDS__BYTES_RECEIVED = TR::tr("Bytes received").toStdString(); +const std::string FIELDS__REFERRER = TR::tr("Referrer").toStdString(); +const std::string FIELDS__COOKIE = TR::tr("Cookie").toStdString(); +const std::string FIELDS__CLIENT = TR::tr("Client").toStdString(); +const std::string FIELDS__USER_AGENT = TR::tr("User-agent").toStdString(); + +const std::string MONTHS__JANUARY = TR::tr("January").toStdString(); +const std::string MONTHS__FEBRUARY = TR::tr("February").toStdString(); +const std::string MONTHS__MARCH = TR::tr("March").toStdString(); +const std::string MONTHS__APRIL = TR::tr("April").toStdString(); +const std::string MONTHS__MAY = TR::tr("May").toStdString(); +const std::string MONTHS__JUNE = TR::tr("June").toStdString(); +const std::string MONTHS__JULY = TR::tr("July").toStdString(); +const std::string MONTHS__AUGUST = TR::tr("August").toStdString(); +const std::string MONTHS__SEPTEMBER = TR::tr("September").toStdString(); +const std::string MONTHS__OCTOBER = TR::tr("October").toStdString(); +const std::string MONTHS__NOVEMBER = TR::tr("November").toStdString(); +const std::string MONTHS__DECEMBER = TR::tr("December").toStdString(); + +const std::string DAYS__SUNDAY = TR::tr("Sunday").toStdString(); +const std::string DAYS__MONDAY = TR::tr("Monday").toStdString(); +const std::string DAYS__TUESDAY = TR::tr("Tuesday").toStdString(); +const std::string DAYS__WEDNESDAY = TR::tr("Wednesday").toStdString(); +const std::string DAYS__THURSDAY = TR::tr("Thursday").toStdString(); +const std::string DAYS__FRIDAY = TR::tr("Friday").toStdString(); +const std::string DAYS__SATURDAY = TR::tr("Saturday").toStdString(); + + +#endif // TR_H diff --git a/logdoctor/modules/tb.cpp b/logdoctor/modules/tb.cpp new file mode 100644 index 00000000..2edd840a --- /dev/null +++ b/logdoctor/modules/tb.cpp @@ -0,0 +1,174 @@ + +#include "tb.h" + + +TextBrowser::TextBrowser() +{ + +} + + +// getters +const bool& TextBrowser::getWideLinesUsage() +{ + return this->wide_lines; +} + +const int& TextBrowser::getColorSchemeID() +{ + return this->color_scheme_id; +} + +const std::unordered_map& TextBrowser::getColorScheme() +{ + return this->color_scheme; +} + +/*const int& TextBrowser::getFontSize() +{ + return this->font_size; +}*/ + +const QString& TextBrowser::getFontFamily() +{ + return this->font_family; +} + +const QFont& TextBrowser::getFont() +{ + return this->font; +} + + +// setters +void TextBrowser::setWideLinesUsage( const bool& use_wide_lines ) +{ + this->wide_lines = use_wide_lines; +} + +void TextBrowser::setColorScheme( const int& color_scheme_id, const std::unordered_map& color_scheme ) +{ + this->color_scheme_id = color_scheme_id; + this->color_scheme = color_scheme; +} + +/*void TextBrowser::setFontSize( const int& font_size ) +{ + this->font_size = font_size; +} + +void TextBrowser::setFontFamily( const QString& font_family ) +{ + this->font_family = font_family; +}*/ + +void TextBrowser::setFont( const QFont& font ) +{ + this->font = font; + this->font_family = font.family(); +} + + +// preview +void TextBrowser::makePreview( QString& content ) +{ + content += QString("color_scheme_id > 0 ) { + content += QString(" style=\"background:%1; color:%2\"") + .arg( this->color_scheme.at("background"), + this->color_scheme.at("text") ); + } + content += ">"; + if ( wide_lines ) { + content += "
    "; + } + for ( int i=0; i<32; i++ ) { + content += "

    "; + + content += ""; + if ( this->color_scheme_id > 0 ) { + content += QString("").arg( this->color_scheme.at("time") ); + } + content += "2000-01-01 23:59:59"; + if ( this->color_scheme_id > 0 ) { + content += ""; + } + content += ""; + + content += " "; + if ( this->color_scheme_id > 0 ) { + content += QString("").arg( this->color_scheme.at("req") ); + } + content += "HTTP/1.1 GET /index.php query=x"; + if ( this->color_scheme_id > 0 ) { + content += ""; + } + content += ""; + + content += " "; + if ( this->color_scheme_id > 0 ) { + content += QString("").arg( this->color_scheme.at("res") ); + } + content += "404"; + if ( this->color_scheme_id > 0 ) { + content += ""; + } + content += ""; + + content += " "; + if ( this->color_scheme_id > 0 ) { + content += QString("").arg( this->color_scheme.at("x") ); + } + content += "123 1234 1000"; + if ( this->color_scheme_id > 0 ) { + content += ""; + } + content += ""; + + content += " \""; + if ( this->color_scheme_id > 0 ) { + content += QString("").arg( this->color_scheme.at("x") ); + } + content += "http://www.referrer.site"; + if ( this->color_scheme_id > 0 ) { + content += ""; + } + content += "\""; + + content += " \""; + if ( this->color_scheme_id > 0 ) { + content += QString("").arg( this->color_scheme.at("x") ); + } + content += "aCookie=abc123"; + if ( this->color_scheme_id > 0 ) { + content += ""; + } + content += "\""; + + content += " \""; + if ( this->color_scheme_id > 0 ) { + content += QString("").arg( this->color_scheme.at("ua") ); + } + content += "UserAgent/3.0 (Details stuff) Info/123"; + if ( this->color_scheme_id > 0 ) { + content += ""; + } + content += "\""; + + content += " "; + if ( this->color_scheme_id > 0 ) { + content += QString("").arg( this->color_scheme.at("ip") ); + } + content += "192.168.1.123"; + if ( this->color_scheme_id > 0 ) { + content += ""; + } + content += ""; + + content += "

    "; + if ( this->wide_lines ) { + content += "
    "; + } + } + content += ""; +} diff --git a/logdoctor/modules/tb.h b/logdoctor/modules/tb.h new file mode 100644 index 00000000..4bc62a4b --- /dev/null +++ b/logdoctor/modules/tb.h @@ -0,0 +1,77 @@ +#ifndef LOGFILESTB_H +#define LOGFILESTB_H + +#include + +#include +#include + + +//! TextBrowser +/*! + Perform operations for files visualization +*/ +class TextBrowser +{ +public: + TextBrowser(); + + + ///////////////// + //// GETTERS //// + + //! Returns whether the wide lines option is set to be used or not + const bool& getWideLinesUsage(); + + //! Returns the ID of the color scheme in use + const int& getColorSchemeID(); + + //! Returns the color scheme in use + const std::unordered_map& getColorScheme(); + + /*const int& getFontSize();*/ + + //! Returns the family of the font in use + const QString& getFontFamily(); + + //! Returns the font in use + const QFont& getFont(); + + + ///////////////// + //// SETTERS //// + + //! Sets whether to use wide lines or not + void setWideLinesUsage( const bool& use_wide_lines ); + + //! Stes the given color scheme as the one in use + void setColorScheme( const int& color_scheme_id, const std::unordered_map& color_scheme ); + + /*void setFontSize( const int& font_size ); + void setFontFamily( const QString& font_family );*/ + + //! Sets the given font as the one in use + void setFont( const QFont& font ); + + + ///////////////// + //// PREVIEW //// + + //! Builds the preview which will be shown in the configs tab + /*! + \param content Will hold the preview string + */ + void makePreview( QString& content ); + + +private: + + bool wide_lines = false; + int color_scheme_id = 1; + std::unordered_map color_scheme; + /*int font_size = 13;*/ + QString font_family; + QFont font; +}; + +#endif // LOGFILESTB_H diff --git a/logdoctor/resources/flags/en.png b/logdoctor/resources/flags/en.png new file mode 100644 index 00000000..3352c866 Binary files /dev/null and b/logdoctor/resources/flags/en.png differ diff --git a/logdoctor/resources/flags/es.png b/logdoctor/resources/flags/es.png new file mode 100644 index 00000000..cb1c2a78 Binary files /dev/null and b/logdoctor/resources/flags/es.png differ diff --git a/logdoctor/resources/flags/fr.png b/logdoctor/resources/flags/fr.png new file mode 100644 index 00000000..c65915a7 Binary files /dev/null and b/logdoctor/resources/flags/fr.png differ diff --git a/logdoctor/resources/flags/it.png b/logdoctor/resources/flags/it.png new file mode 100644 index 00000000..0d13d3a6 Binary files /dev/null and b/logdoctor/resources/flags/it.png differ diff --git a/logdoctor/resources/fonts/3270.ttf b/logdoctor/resources/fonts/3270.ttf new file mode 100644 index 00000000..3fa73e78 Binary files /dev/null and b/logdoctor/resources/fonts/3270.ttf differ diff --git a/logdoctor/resources/fonts/3270_LICENSE.md b/logdoctor/resources/fonts/3270_LICENSE.md new file mode 100644 index 00000000..3ca71cba --- /dev/null +++ b/logdoctor/resources/fonts/3270_LICENSE.md @@ -0,0 +1,49 @@ +Copyright (c) 2011-2017, Ricardo Banffy. +Copyright (c) 1993-2011, Paul Mattes. +Copyright (c) 2004-2005, Don Russell. +Copyright (c) 2004, Dick Altenbern. +Copyright (c) 1990, Jeff Sparkes. +Copyright (c) 1989, Georgia Tech Research Corporation (GTRC), Atlanta, GA 30332. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + * Neither the name of Ricardo Banffy, Paul Mattes, Don Russell, + Dick Altenbern, Jeff Sparkes, GTRC nor the names of their contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL RICARDO BANFFY, PAUL MATTES, DON RUSSELL, DICK ALTENBERN, JEFF +SPARKES OR GTRC BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT +OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +The Debian Logo glyph is based on the Debian Open Use Logo and is +Copyright (c) 1999 Software in the Public Interest, Inc., and it is +incorporated here under the terms of the Creative Commons +Attribution-ShareAlike 3.0 Unported License. The logo is released +under the terms of the GNU Lesser General Public License, version 3 or +any later version, or, at your option, of the Creative Commons +Attribution-ShareAlike 3.0 Unported License. + +Ubuntu, the Ubuntu logo and the Circle of Friends symbol are +registered trademarks of Canonical Ltd. + +The Fontforge SFD font description file is optionally licensed under +the SIL Open Font License v1.1 with no Reserved Font Name. This +license is available with a FAQ at http://scripts.sil.org/OFL. diff --git a/logdoctor/resources/fonts/Hack.ttf b/logdoctor/resources/fonts/Hack.ttf new file mode 100644 index 00000000..92a90cb0 Binary files /dev/null and b/logdoctor/resources/fonts/Hack.ttf differ diff --git a/logdoctor/resources/fonts/Metropolis.ttf b/logdoctor/resources/fonts/Metropolis.ttf new file mode 100644 index 00000000..72cef2e8 Binary files /dev/null and b/logdoctor/resources/fonts/Metropolis.ttf differ diff --git a/logdoctor/resources/fonts/Metropolis_UNLICENSE.md b/logdoctor/resources/fonts/Metropolis_UNLICENSE.md new file mode 100644 index 00000000..68a49daa --- /dev/null +++ b/logdoctor/resources/fonts/Metropolis_UNLICENSE.md @@ -0,0 +1,24 @@ +This is free and unencumbered software released into the public domain. + +Anyone is free to copy, modify, publish, use, compile, sell, or +distribute this software, either in source code form or as a compiled +binary, for any purpose, commercial or non-commercial, and by any +means. + +In jurisdictions that recognize copyright laws, the author or authors +of this software dedicate any and all copyright interest in the +software to the public domain. We make this dedication for the benefit +of the public at large and to the detriment of our heirs and +successors. We intend this dedication to be an overt act of +relinquishment in perpetuity of all present and future rights to this +software under copyright law. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +For more information, please refer to diff --git a/logdoctor/resources/games/crisscross/o.png b/logdoctor/resources/games/crisscross/o.png new file mode 100644 index 00000000..64b1d8e7 Binary files /dev/null and b/logdoctor/resources/games/crisscross/o.png differ diff --git a/logdoctor/resources/games/crisscross/x.png b/logdoctor/resources/games/crisscross/x.png new file mode 100644 index 00000000..2310a611 Binary files /dev/null and b/logdoctor/resources/games/crisscross/x.png differ diff --git a/logdoctor/resources/games/snake/body_c.png b/logdoctor/resources/games/snake/body_c.png new file mode 100644 index 00000000..bc519acf Binary files /dev/null and b/logdoctor/resources/games/snake/body_c.png differ diff --git a/logdoctor/resources/games/snake/body_c_.png b/logdoctor/resources/games/snake/body_c_.png new file mode 100644 index 00000000..ffc59262 Binary files /dev/null and b/logdoctor/resources/games/snake/body_c_.png differ diff --git a/logdoctor/resources/games/snake/body_s.png b/logdoctor/resources/games/snake/body_s.png new file mode 100644 index 00000000..339f4c65 Binary files /dev/null and b/logdoctor/resources/games/snake/body_s.png differ diff --git a/logdoctor/resources/games/snake/body_s_.png b/logdoctor/resources/games/snake/body_s_.png new file mode 100644 index 00000000..9968f81e Binary files /dev/null and b/logdoctor/resources/games/snake/body_s_.png differ diff --git a/logdoctor/resources/games/snake/egg.png b/logdoctor/resources/games/snake/egg.png new file mode 100644 index 00000000..5586117a Binary files /dev/null and b/logdoctor/resources/games/snake/egg.png differ diff --git a/logdoctor/resources/games/snake/head.png b/logdoctor/resources/games/snake/head.png new file mode 100644 index 00000000..80feb8c8 Binary files /dev/null and b/logdoctor/resources/games/snake/head.png differ diff --git a/logdoctor/resources/games/snake/head_.png b/logdoctor/resources/games/snake/head_.png new file mode 100644 index 00000000..edbeb9a9 Binary files /dev/null and b/logdoctor/resources/games/snake/head_.png differ diff --git a/logdoctor/resources/games/snake/rat.png b/logdoctor/resources/games/snake/rat.png new file mode 100644 index 00000000..e9ec7bf2 Binary files /dev/null and b/logdoctor/resources/games/snake/rat.png differ diff --git a/logdoctor/resources/games/snake/tail.png b/logdoctor/resources/games/snake/tail.png new file mode 100644 index 00000000..bec64c2e Binary files /dev/null and b/logdoctor/resources/games/snake/tail.png differ diff --git a/logdoctor/resources/games/snake/tail_.png b/logdoctor/resources/games/snake/tail_.png new file mode 100644 index 00000000..ddc8eb30 Binary files /dev/null and b/logdoctor/resources/games/snake/tail_.png differ diff --git a/logdoctor/resources/games/snake/water.png b/logdoctor/resources/games/snake/water.png new file mode 100644 index 00000000..5bd891f8 Binary files /dev/null and b/logdoctor/resources/games/snake/water.png differ diff --git a/logdoctor/resources/icons/add.png b/logdoctor/resources/icons/add.png new file mode 100644 index 00000000..0c6bd0e5 Binary files /dev/null and b/logdoctor/resources/icons/add.png differ diff --git a/logdoctor/resources/icons/dark/checkbox_checked.png b/logdoctor/resources/icons/dark/checkbox_checked.png new file mode 100644 index 00000000..56de7208 Binary files /dev/null and b/logdoctor/resources/icons/dark/checkbox_checked.png differ diff --git a/logdoctor/resources/icons/dark/checkbox_semichecked.png b/logdoctor/resources/icons/dark/checkbox_semichecked.png new file mode 100644 index 00000000..fd53258b Binary files /dev/null and b/logdoctor/resources/icons/dark/checkbox_semichecked.png differ diff --git a/logdoctor/resources/icons/dark/checkbox_unchecked.png b/logdoctor/resources/icons/dark/checkbox_unchecked.png new file mode 100644 index 00000000..1f982f3f Binary files /dev/null and b/logdoctor/resources/icons/dark/checkbox_unchecked.png differ diff --git a/logdoctor/resources/icons/dark/checking.png b/logdoctor/resources/icons/dark/checking.png new file mode 100644 index 00000000..acf7c4f6 Binary files /dev/null and b/logdoctor/resources/icons/dark/checking.png differ diff --git a/logdoctor/resources/icons/dark/conf_off.png b/logdoctor/resources/icons/dark/conf_off.png new file mode 100644 index 00000000..9516e380 Binary files /dev/null and b/logdoctor/resources/icons/dark/conf_off.png differ diff --git a/logdoctor/resources/icons/dark/conf_on.png b/logdoctor/resources/icons/dark/conf_on.png new file mode 100644 index 00000000..77bd1f9e Binary files /dev/null and b/logdoctor/resources/icons/dark/conf_on.png differ diff --git a/logdoctor/resources/icons/dark/count_off.png b/logdoctor/resources/icons/dark/count_off.png new file mode 100644 index 00000000..951e390f Binary files /dev/null and b/logdoctor/resources/icons/dark/count_off.png differ diff --git a/logdoctor/resources/icons/dark/count_on.png b/logdoctor/resources/icons/dark/count_on.png new file mode 100644 index 00000000..486da288 Binary files /dev/null and b/logdoctor/resources/icons/dark/count_on.png differ diff --git a/logdoctor/resources/icons/dark/daytime_off.png b/logdoctor/resources/icons/dark/daytime_off.png new file mode 100644 index 00000000..16c9c88c Binary files /dev/null and b/logdoctor/resources/icons/dark/daytime_off.png differ diff --git a/logdoctor/resources/icons/dark/daytime_on.png b/logdoctor/resources/icons/dark/daytime_on.png new file mode 100644 index 00000000..d5be0550 Binary files /dev/null and b/logdoctor/resources/icons/dark/daytime_on.png differ diff --git a/logdoctor/resources/icons/dark/down.png b/logdoctor/resources/icons/dark/down.png new file mode 100644 index 00000000..5b307488 Binary files /dev/null and b/logdoctor/resources/icons/dark/down.png differ diff --git a/logdoctor/resources/icons/dark/draw.png b/logdoctor/resources/icons/dark/draw.png new file mode 100644 index 00000000..9746285e Binary files /dev/null and b/logdoctor/resources/icons/dark/draw.png differ diff --git a/logdoctor/resources/icons/dark/global_off.png b/logdoctor/resources/icons/dark/global_off.png new file mode 100644 index 00000000..dca10df3 Binary files /dev/null and b/logdoctor/resources/icons/dark/global_off.png differ diff --git a/logdoctor/resources/icons/dark/global_on.png b/logdoctor/resources/icons/dark/global_on.png new file mode 100644 index 00000000..b22e7eba Binary files /dev/null and b/logdoctor/resources/icons/dark/global_on.png differ diff --git a/logdoctor/resources/icons/dark/help.png b/logdoctor/resources/icons/dark/help.png new file mode 100644 index 00000000..7666644b Binary files /dev/null and b/logdoctor/resources/icons/dark/help.png differ diff --git a/logdoctor/resources/icons/dark/log_off.png b/logdoctor/resources/icons/dark/log_off.png new file mode 100644 index 00000000..d14352e5 Binary files /dev/null and b/logdoctor/resources/icons/dark/log_off.png differ diff --git a/logdoctor/resources/icons/dark/log_on.png b/logdoctor/resources/icons/dark/log_on.png new file mode 100644 index 00000000..7e02b974 Binary files /dev/null and b/logdoctor/resources/icons/dark/log_on.png differ diff --git a/logdoctor/resources/icons/dark/mk_lines.png b/logdoctor/resources/icons/dark/mk_lines.png new file mode 100644 index 00000000..4f0aec5a Binary files /dev/null and b/logdoctor/resources/icons/dark/mk_lines.png differ diff --git a/logdoctor/resources/icons/dark/mk_size.png b/logdoctor/resources/icons/dark/mk_size.png new file mode 100644 index 00000000..9e6e4d18 Binary files /dev/null and b/logdoctor/resources/icons/dark/mk_size.png differ diff --git a/logdoctor/resources/icons/dark/mk_speed.png b/logdoctor/resources/icons/dark/mk_speed.png new file mode 100644 index 00000000..4f7044a3 Binary files /dev/null and b/logdoctor/resources/icons/dark/mk_speed.png differ diff --git a/logdoctor/resources/icons/dark/mk_time.png b/logdoctor/resources/icons/dark/mk_time.png new file mode 100644 index 00000000..02802f30 Binary files /dev/null and b/logdoctor/resources/icons/dark/mk_time.png differ diff --git a/logdoctor/resources/icons/dark/radiobutton_checked.png b/logdoctor/resources/icons/dark/radiobutton_checked.png new file mode 100644 index 00000000..31ec6420 Binary files /dev/null and b/logdoctor/resources/icons/dark/radiobutton_checked.png differ diff --git a/logdoctor/resources/icons/dark/radiobutton_unchecked.png b/logdoctor/resources/icons/dark/radiobutton_unchecked.png new file mode 100644 index 00000000..74271a56 Binary files /dev/null and b/logdoctor/resources/icons/dark/radiobutton_unchecked.png differ diff --git a/logdoctor/resources/icons/dark/refresh.png b/logdoctor/resources/icons/dark/refresh.png new file mode 100644 index 00000000..354198e0 Binary files /dev/null and b/logdoctor/resources/icons/dark/refresh.png differ diff --git a/logdoctor/resources/icons/dark/relational_off.png b/logdoctor/resources/icons/dark/relational_off.png new file mode 100644 index 00000000..a13fd2a8 Binary files /dev/null and b/logdoctor/resources/icons/dark/relational_off.png differ diff --git a/logdoctor/resources/icons/dark/relational_on.png b/logdoctor/resources/icons/dark/relational_on.png new file mode 100644 index 00000000..eecdd71e Binary files /dev/null and b/logdoctor/resources/icons/dark/relational_on.png differ diff --git a/logdoctor/resources/icons/dark/save.png b/logdoctor/resources/icons/dark/save.png new file mode 100644 index 00000000..a4accee5 Binary files /dev/null and b/logdoctor/resources/icons/dark/save.png differ diff --git a/logdoctor/resources/icons/dark/show_file.png b/logdoctor/resources/icons/dark/show_file.png new file mode 100644 index 00000000..712c2901 Binary files /dev/null and b/logdoctor/resources/icons/dark/show_file.png differ diff --git a/logdoctor/resources/icons/dark/speed_off.png b/logdoctor/resources/icons/dark/speed_off.png new file mode 100644 index 00000000..090a2146 Binary files /dev/null and b/logdoctor/resources/icons/dark/speed_off.png differ diff --git a/logdoctor/resources/icons/dark/speed_on.png b/logdoctor/resources/icons/dark/speed_on.png new file mode 100644 index 00000000..def0fea3 Binary files /dev/null and b/logdoctor/resources/icons/dark/speed_on.png differ diff --git a/logdoctor/resources/icons/dark/spinbox_add.png b/logdoctor/resources/icons/dark/spinbox_add.png new file mode 100644 index 00000000..212c6fab Binary files /dev/null and b/logdoctor/resources/icons/dark/spinbox_add.png differ diff --git a/logdoctor/resources/icons/dark/spinbox_sub.png b/logdoctor/resources/icons/dark/spinbox_sub.png new file mode 100644 index 00000000..9d3dc92d Binary files /dev/null and b/logdoctor/resources/icons/dark/spinbox_sub.png differ diff --git a/logdoctor/resources/icons/dark/up.png b/logdoctor/resources/icons/dark/up.png new file mode 100644 index 00000000..6f1471e6 Binary files /dev/null and b/logdoctor/resources/icons/dark/up.png differ diff --git a/logdoctor/resources/icons/dark/view_off.png b/logdoctor/resources/icons/dark/view_off.png new file mode 100644 index 00000000..bbaad265 Binary files /dev/null and b/logdoctor/resources/icons/dark/view_off.png differ diff --git a/logdoctor/resources/icons/dark/view_on.png b/logdoctor/resources/icons/dark/view_on.png new file mode 100644 index 00000000..af8354a0 Binary files /dev/null and b/logdoctor/resources/icons/dark/view_on.png differ diff --git a/logdoctor/resources/icons/dark/warn_off.png b/logdoctor/resources/icons/dark/warn_off.png new file mode 100644 index 00000000..424566a2 Binary files /dev/null and b/logdoctor/resources/icons/dark/warn_off.png differ diff --git a/logdoctor/resources/icons/dark/warn_on.png b/logdoctor/resources/icons/dark/warn_on.png new file mode 100644 index 00000000..c5f8dd52 Binary files /dev/null and b/logdoctor/resources/icons/dark/warn_on.png differ diff --git a/logdoctor/resources/icons/dialogs/err.png b/logdoctor/resources/icons/dialogs/err.png new file mode 100644 index 00000000..0eb209ac Binary files /dev/null and b/logdoctor/resources/icons/dialogs/err.png differ diff --git a/logdoctor/resources/icons/dialogs/info.png b/logdoctor/resources/icons/dialogs/info.png new file mode 100644 index 00000000..f5342d87 Binary files /dev/null and b/logdoctor/resources/icons/dialogs/info.png differ diff --git a/logdoctor/resources/icons/dialogs/quest.png b/logdoctor/resources/icons/dialogs/quest.png new file mode 100644 index 00000000..b176b570 Binary files /dev/null and b/logdoctor/resources/icons/dialogs/quest.png differ diff --git a/logdoctor/resources/icons/dialogs/warn.png b/logdoctor/resources/icons/dialogs/warn.png new file mode 100644 index 00000000..407c80b1 Binary files /dev/null and b/logdoctor/resources/icons/dialogs/warn.png differ diff --git a/logdoctor/resources/icons/down.png b/logdoctor/resources/icons/down.png new file mode 100644 index 00000000..a0247c8f Binary files /dev/null and b/logdoctor/resources/icons/down.png differ diff --git a/logdoctor/resources/icons/err.png b/logdoctor/resources/icons/err.png new file mode 100644 index 00000000..cd650cd3 Binary files /dev/null and b/logdoctor/resources/icons/err.png differ diff --git a/logdoctor/resources/icons/light/checkbox_checked.png b/logdoctor/resources/icons/light/checkbox_checked.png new file mode 100644 index 00000000..244aabc3 Binary files /dev/null and b/logdoctor/resources/icons/light/checkbox_checked.png differ diff --git a/logdoctor/resources/icons/light/checkbox_semichecked.png b/logdoctor/resources/icons/light/checkbox_semichecked.png new file mode 100644 index 00000000..adefd3fa Binary files /dev/null and b/logdoctor/resources/icons/light/checkbox_semichecked.png differ diff --git a/logdoctor/resources/icons/light/checkbox_unchecked.png b/logdoctor/resources/icons/light/checkbox_unchecked.png new file mode 100644 index 00000000..ff4faf0f Binary files /dev/null and b/logdoctor/resources/icons/light/checkbox_unchecked.png differ diff --git a/logdoctor/resources/icons/light/checking.png b/logdoctor/resources/icons/light/checking.png new file mode 100644 index 00000000..e0e0f4b0 Binary files /dev/null and b/logdoctor/resources/icons/light/checking.png differ diff --git a/logdoctor/resources/icons/light/conf_off.png b/logdoctor/resources/icons/light/conf_off.png new file mode 100644 index 00000000..7c9b4a63 Binary files /dev/null and b/logdoctor/resources/icons/light/conf_off.png differ diff --git a/logdoctor/resources/icons/light/conf_on.png b/logdoctor/resources/icons/light/conf_on.png new file mode 100644 index 00000000..92967698 Binary files /dev/null and b/logdoctor/resources/icons/light/conf_on.png differ diff --git a/logdoctor/resources/icons/light/count_off.png b/logdoctor/resources/icons/light/count_off.png new file mode 100644 index 00000000..96814966 Binary files /dev/null and b/logdoctor/resources/icons/light/count_off.png differ diff --git a/logdoctor/resources/icons/light/count_on.png b/logdoctor/resources/icons/light/count_on.png new file mode 100644 index 00000000..90f30b39 Binary files /dev/null and b/logdoctor/resources/icons/light/count_on.png differ diff --git a/logdoctor/resources/icons/light/daytime_off.png b/logdoctor/resources/icons/light/daytime_off.png new file mode 100644 index 00000000..4249829f Binary files /dev/null and b/logdoctor/resources/icons/light/daytime_off.png differ diff --git a/logdoctor/resources/icons/light/daytime_on.png b/logdoctor/resources/icons/light/daytime_on.png new file mode 100644 index 00000000..abf0b99d Binary files /dev/null and b/logdoctor/resources/icons/light/daytime_on.png differ diff --git a/logdoctor/resources/icons/light/down.png b/logdoctor/resources/icons/light/down.png new file mode 100644 index 00000000..cd9c65f8 Binary files /dev/null and b/logdoctor/resources/icons/light/down.png differ diff --git a/logdoctor/resources/icons/light/draw.png b/logdoctor/resources/icons/light/draw.png new file mode 100644 index 00000000..fa156f08 Binary files /dev/null and b/logdoctor/resources/icons/light/draw.png differ diff --git a/logdoctor/resources/icons/light/global_off.png b/logdoctor/resources/icons/light/global_off.png new file mode 100644 index 00000000..6789686a Binary files /dev/null and b/logdoctor/resources/icons/light/global_off.png differ diff --git a/logdoctor/resources/icons/light/global_on.png b/logdoctor/resources/icons/light/global_on.png new file mode 100644 index 00000000..9d110a96 Binary files /dev/null and b/logdoctor/resources/icons/light/global_on.png differ diff --git a/logdoctor/resources/icons/light/help.png b/logdoctor/resources/icons/light/help.png new file mode 100644 index 00000000..c44d85b6 Binary files /dev/null and b/logdoctor/resources/icons/light/help.png differ diff --git a/logdoctor/resources/icons/light/log_off.png b/logdoctor/resources/icons/light/log_off.png new file mode 100644 index 00000000..c0772417 Binary files /dev/null and b/logdoctor/resources/icons/light/log_off.png differ diff --git a/logdoctor/resources/icons/light/log_on.png b/logdoctor/resources/icons/light/log_on.png new file mode 100644 index 00000000..e5b22b02 Binary files /dev/null and b/logdoctor/resources/icons/light/log_on.png differ diff --git a/logdoctor/resources/icons/light/mk_lines.png b/logdoctor/resources/icons/light/mk_lines.png new file mode 100644 index 00000000..96449982 Binary files /dev/null and b/logdoctor/resources/icons/light/mk_lines.png differ diff --git a/logdoctor/resources/icons/light/mk_size.png b/logdoctor/resources/icons/light/mk_size.png new file mode 100644 index 00000000..37b87f92 Binary files /dev/null and b/logdoctor/resources/icons/light/mk_size.png differ diff --git a/logdoctor/resources/icons/light/mk_speed.png b/logdoctor/resources/icons/light/mk_speed.png new file mode 100644 index 00000000..898ccf0e Binary files /dev/null and b/logdoctor/resources/icons/light/mk_speed.png differ diff --git a/logdoctor/resources/icons/light/mk_time.png b/logdoctor/resources/icons/light/mk_time.png new file mode 100644 index 00000000..91bc7792 Binary files /dev/null and b/logdoctor/resources/icons/light/mk_time.png differ diff --git a/logdoctor/resources/icons/light/radiobutton_checked.png b/logdoctor/resources/icons/light/radiobutton_checked.png new file mode 100644 index 00000000..bf84b78a Binary files /dev/null and b/logdoctor/resources/icons/light/radiobutton_checked.png differ diff --git a/logdoctor/resources/icons/light/radiobutton_unchecked.png b/logdoctor/resources/icons/light/radiobutton_unchecked.png new file mode 100644 index 00000000..2f55cd11 Binary files /dev/null and b/logdoctor/resources/icons/light/radiobutton_unchecked.png differ diff --git a/logdoctor/resources/icons/light/refresh.png b/logdoctor/resources/icons/light/refresh.png new file mode 100644 index 00000000..dd33da99 Binary files /dev/null and b/logdoctor/resources/icons/light/refresh.png differ diff --git a/logdoctor/resources/icons/light/relational_off.png b/logdoctor/resources/icons/light/relational_off.png new file mode 100644 index 00000000..91aad88f Binary files /dev/null and b/logdoctor/resources/icons/light/relational_off.png differ diff --git a/logdoctor/resources/icons/light/relational_on.png b/logdoctor/resources/icons/light/relational_on.png new file mode 100644 index 00000000..18873fda Binary files /dev/null and b/logdoctor/resources/icons/light/relational_on.png differ diff --git a/logdoctor/resources/icons/light/save.png b/logdoctor/resources/icons/light/save.png new file mode 100644 index 00000000..ded3a4cd Binary files /dev/null and b/logdoctor/resources/icons/light/save.png differ diff --git a/logdoctor/resources/icons/light/show_file.png b/logdoctor/resources/icons/light/show_file.png new file mode 100644 index 00000000..b4883541 Binary files /dev/null and b/logdoctor/resources/icons/light/show_file.png differ diff --git a/logdoctor/resources/icons/light/speed_off.png b/logdoctor/resources/icons/light/speed_off.png new file mode 100644 index 00000000..43dde23b Binary files /dev/null and b/logdoctor/resources/icons/light/speed_off.png differ diff --git a/logdoctor/resources/icons/light/speed_on.png b/logdoctor/resources/icons/light/speed_on.png new file mode 100644 index 00000000..0f77de0c Binary files /dev/null and b/logdoctor/resources/icons/light/speed_on.png differ diff --git a/logdoctor/resources/icons/light/spinbox_add.png b/logdoctor/resources/icons/light/spinbox_add.png new file mode 100644 index 00000000..7f1625d0 Binary files /dev/null and b/logdoctor/resources/icons/light/spinbox_add.png differ diff --git a/logdoctor/resources/icons/light/spinbox_sub.png b/logdoctor/resources/icons/light/spinbox_sub.png new file mode 100644 index 00000000..20bb06c8 Binary files /dev/null and b/logdoctor/resources/icons/light/spinbox_sub.png differ diff --git a/logdoctor/resources/icons/light/up.png b/logdoctor/resources/icons/light/up.png new file mode 100644 index 00000000..342a799f Binary files /dev/null and b/logdoctor/resources/icons/light/up.png differ diff --git a/logdoctor/resources/icons/light/view_off.png b/logdoctor/resources/icons/light/view_off.png new file mode 100644 index 00000000..efab51ec Binary files /dev/null and b/logdoctor/resources/icons/light/view_off.png differ diff --git a/logdoctor/resources/icons/light/view_on.png b/logdoctor/resources/icons/light/view_on.png new file mode 100644 index 00000000..999fde30 Binary files /dev/null and b/logdoctor/resources/icons/light/view_on.png differ diff --git a/logdoctor/resources/icons/light/warn_off.png b/logdoctor/resources/icons/light/warn_off.png new file mode 100644 index 00000000..678844da Binary files /dev/null and b/logdoctor/resources/icons/light/warn_off.png differ diff --git a/logdoctor/resources/icons/light/warn_on.png b/logdoctor/resources/icons/light/warn_on.png new file mode 100644 index 00000000..aaedefe6 Binary files /dev/null and b/logdoctor/resources/icons/light/warn_on.png differ diff --git a/logdoctor/resources/icons/midtone/down.png b/logdoctor/resources/icons/midtone/down.png new file mode 100644 index 00000000..35d82410 Binary files /dev/null and b/logdoctor/resources/icons/midtone/down.png differ diff --git a/logdoctor/resources/icons/midtone/save.png b/logdoctor/resources/icons/midtone/save.png new file mode 100644 index 00000000..7b0d3e1e Binary files /dev/null and b/logdoctor/resources/icons/midtone/save.png differ diff --git a/logdoctor/resources/icons/midtone/spinbox_add.png b/logdoctor/resources/icons/midtone/spinbox_add.png new file mode 100644 index 00000000..7a841d7d Binary files /dev/null and b/logdoctor/resources/icons/midtone/spinbox_add.png differ diff --git a/logdoctor/resources/icons/midtone/spinbox_sub.png b/logdoctor/resources/icons/midtone/spinbox_sub.png new file mode 100644 index 00000000..8dabb948 Binary files /dev/null and b/logdoctor/resources/icons/midtone/spinbox_sub.png differ diff --git a/logdoctor/resources/icons/midtone/up.png b/logdoctor/resources/icons/midtone/up.png new file mode 100644 index 00000000..0dd682bd Binary files /dev/null and b/logdoctor/resources/icons/midtone/up.png differ diff --git a/logdoctor/resources/icons/rem.png b/logdoctor/resources/icons/rem.png new file mode 100644 index 00000000..8b4dc190 Binary files /dev/null and b/logdoctor/resources/icons/rem.png differ diff --git a/logdoctor/resources/icons/up.png b/logdoctor/resources/icons/up.png new file mode 100644 index 00000000..5e4d7487 Binary files /dev/null and b/logdoctor/resources/icons/up.png differ diff --git a/logdoctor/resources/logo/logdoctor.svg b/logdoctor/resources/logo/logdoctor.svg new file mode 100644 index 00000000..e03977a4 --- /dev/null +++ b/logdoctor/resources/logo/logdoctor.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/logdoctor/resources/resources.qrc b/logdoctor/resources/resources.qrc new file mode 100644 index 00000000..f57be509 --- /dev/null +++ b/logdoctor/resources/resources.qrc @@ -0,0 +1,127 @@ + + + logo/logdoctor.svg + + + translations/LogDoctor_en.qm + translations/LogDoctor_es.qm + translations/LogDoctor_fr.qm + translations/LogDoctor_it.qm + + + fonts/3270.ttf + fonts/Hack.ttf + fonts/Metropolis.ttf + + + icons/add.png + icons/rem.png + icons/down.png + icons/up.png + icons/err.png + icons/dialogs/err.png + icons/dialogs/info.png + icons/dialogs/quest.png + icons/dialogs/warn.png + icons/light/checkbox_checked.png + icons/light/checkbox_semichecked.png + icons/light/checkbox_unchecked.png + icons/light/checking.png + icons/light/conf_off.png + icons/light/conf_on.png + icons/light/count_off.png + icons/light/count_on.png + icons/light/daytime_off.png + icons/light/daytime_on.png + icons/light/down.png + icons/light/draw.png + icons/light/global_off.png + icons/light/global_on.png + icons/light/help.png + icons/light/log_off.png + icons/light/log_on.png + icons/light/mk_lines.png + icons/light/mk_size.png + icons/light/mk_speed.png + icons/light/mk_time.png + icons/light/radiobutton_checked.png + icons/light/radiobutton_unchecked.png + icons/light/refresh.png + icons/light/relational_off.png + icons/light/relational_on.png + icons/light/save.png + icons/light/show_file.png + icons/light/speed_off.png + icons/light/speed_on.png + icons/light/spinbox_add.png + icons/light/spinbox_sub.png + icons/light/up.png + icons/light/view_off.png + icons/light/view_on.png + icons/light/warn_off.png + icons/light/warn_on.png + icons/dark/checkbox_checked.png + icons/dark/checkbox_semichecked.png + icons/dark/checkbox_unchecked.png + icons/dark/checking.png + icons/dark/conf_off.png + icons/dark/conf_on.png + icons/dark/count_off.png + icons/dark/count_on.png + icons/dark/daytime_off.png + icons/dark/daytime_on.png + icons/dark/down.png + icons/dark/draw.png + icons/dark/global_off.png + icons/dark/global_on.png + icons/dark/help.png + icons/dark/log_off.png + icons/dark/log_on.png + icons/dark/mk_lines.png + icons/dark/mk_size.png + icons/dark/mk_speed.png + icons/dark/mk_time.png + icons/dark/radiobutton_checked.png + icons/dark/radiobutton_unchecked.png + icons/dark/refresh.png + icons/dark/relational_off.png + icons/dark/relational_on.png + icons/dark/save.png + icons/dark/show_file.png + icons/dark/speed_off.png + icons/dark/speed_on.png + icons/dark/spinbox_add.png + icons/dark/spinbox_sub.png + icons/dark/up.png + icons/dark/view_off.png + icons/dark/view_on.png + icons/dark/warn_off.png + icons/dark/warn_on.png + icons/midtone/down.png + icons/midtone/up.png + icons/midtone/save.png + icons/midtone/spinbox_add.png + icons/midtone/spinbox_sub.png + + + flags/en.png + flags/es.png + flags/fr.png + flags/it.png + + + games/crisscross/o.png + games/crisscross/x.png + games/snake/body_c.png + games/snake/body_c_.png + games/snake/body_s.png + games/snake/body_s_.png + games/snake/egg.png + games/snake/head.png + games/snake/head_.png + games/snake/rat.png + games/snake/tail.png + games/snake/tail_.png + games/snake/water.png + + diff --git a/logdoctor/resources/translations/LogDoctor_en.qm b/logdoctor/resources/translations/LogDoctor_en.qm new file mode 100644 index 00000000..d9193f19 Binary files /dev/null and b/logdoctor/resources/translations/LogDoctor_en.qm differ diff --git a/logdoctor/resources/translations/LogDoctor_es.qm b/logdoctor/resources/translations/LogDoctor_es.qm new file mode 100644 index 00000000..ad8c2442 Binary files /dev/null and b/logdoctor/resources/translations/LogDoctor_es.qm differ diff --git a/logdoctor/resources/translations/LogDoctor_fr.qm b/logdoctor/resources/translations/LogDoctor_fr.qm new file mode 100644 index 00000000..3d10142a Binary files /dev/null and b/logdoctor/resources/translations/LogDoctor_fr.qm differ diff --git a/logdoctor/resources/translations/LogDoctor_it.qm b/logdoctor/resources/translations/LogDoctor_it.qm new file mode 100644 index 00000000..d26200f5 Binary files /dev/null and b/logdoctor/resources/translations/LogDoctor_it.qm differ diff --git a/logdoctor/tools/crapnote/crapnote.cpp b/logdoctor/tools/crapnote/crapnote.cpp new file mode 100644 index 00000000..ffd567a2 --- /dev/null +++ b/logdoctor/tools/crapnote/crapnote.cpp @@ -0,0 +1,77 @@ + +#include "crapnote.h" +#include "ui_crapnote.h" + +#include "modules/exceptions.h" + + +Crapnote::Crapnote(QWidget *parent) : + QWidget(parent), + ui(new Ui::Crapnote) +{ + ui->setupUi(this); +} + +Crapnote::~Crapnote() +{ + delete ui; +} + + +void Crapnote::setTextFont( const QFont& font ) +{ + QFont f = QFont( font ); + f.setPointSize( this->font_size ); + this->ui->textEdit->setFont( f ); +} + +void Crapnote::setColorScheme( const int& color_scheme_id ) +{ + QColor b, t; + // update the colors palette + switch ( color_scheme_id ) { + case 0: + this->ui->textEdit->setPalette( QPalette() ); + break; + case 1: + // breeze + b = QColor(255,198,102); + t = QColor(31,28,27); + this->ui->textEdit->setPalette( QPalette(t,b,b,b,b,t,b) ); + break; + case 2: + // monokai + b = QColor(166,226,46); + t = QColor(39,40,34); + this->ui->textEdit->setPalette( QPalette(t,b,b,b,b,t,b) ); + break; + case 3: + // radical + b = QColor(20,19,34); + t = QColor(213,53,143); + this->ui->textEdit->setPalette( QPalette(t,b,b,b,b,t,b) ); + break; + default: + // wrong + throw GenericException( "Unexpected ColorScheme ID for Crapnote: "+std::to_string( color_scheme_id ), true ); // leave un-catched + } +} + + +void Crapnote::on_spinBox_FontSize_valueChanged(int arg1) +{ + this->font_size = arg1; + this->setTextFont( this->ui->textEdit->font() ); +} + + +void Crapnote::on_button_FontSize_Minus_clicked() +{ + this->ui->spinBox_FontSize->setValue( this->font_size-1 ); +} + + +void Crapnote::on_button_FontSize_Plus_clicked() +{ + this->ui->spinBox_FontSize->setValue( this->font_size+1 ); +} diff --git a/logdoctor/tools/crapnote/crapnote.h b/logdoctor/tools/crapnote/crapnote.h new file mode 100644 index 00000000..a566bec1 --- /dev/null +++ b/logdoctor/tools/crapnote/crapnote.h @@ -0,0 +1,48 @@ +#ifndef CRAPNOTE_H +#define CRAPNOTE_H + +#include + + +namespace Ui { +class Crapnote; +} + +//! Crapnote +/*! + A simple block-note like widget +*/ +class Crapnote : public QWidget +{ + Q_OBJECT + +public: + explicit Crapnote( QWidget* parent=nullptr ); + ~Crapnote(); + + //! Sets the given font + void setTextFont( const QFont& font ); + + //! Sets the given color-scheme + void setColorScheme( const int& color_scheme_id ); + + +private slots: + + //! Sets the given font size + void on_spinBox_FontSize_valueChanged(int arg1); + + //! Decrease the font size of 1 point + void on_button_FontSize_Minus_clicked(); + + //! Increase the font size of 1 point + void on_button_FontSize_Plus_clicked(); + + +private: + Ui::Crapnote *ui; + + int font_size = 17; +}; + +#endif // CRAPNOTE_H diff --git a/logdoctor/tools/crapnote/crapnote.ui b/logdoctor/tools/crapnote/crapnote.ui new file mode 100644 index 00000000..5875102a --- /dev/null +++ b/logdoctor/tools/crapnote/crapnote.ui @@ -0,0 +1,189 @@ + + + Crapnote + + + + 0 + 0 + 600 + 600 + + + + LogDoctor - BlockNote + + + + :/logo/logo/logdoctor.svg:/logo/logo/logdoctor.svg + + + + + + + + + + + + Qt::Horizontal + + + + 203 + 20 + + + + + + + + + 32 + 32 + + + + + 32 + 32 + + + + + 16 + + + + Reduce the font size + + + + + + true + + + + + + + + 64 + 32 + + + + + 64 + 32 + + + + Font size + + + true + + + Qt::AlignCenter + + + QAbstractSpinBox::NoButtons + + + 1 + + + 17 + + + + + + + + 32 + 32 + + + + + 32 + 32 + + + + + 16 + + + + Increase the font size + + + + + + true + + + + + + + Qt::Horizontal + + + + 203 + 20 + + + + + + + + + + + + 16 + + + 8 + + + 16 + + + 16 + + + + + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><meta charset="utf-8" /><style type="text/css"> +p, li { white-space: pre-wrap; } +hr { height: 1px; border-width: 0; } +</style></head><body style=" font-family:'Noto Sans'; font-size:13pt; font-weight:400; font-style:normal;"> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p></body></html> + + + + + + + + + + + + + diff --git a/logdoctor/translations/LogDoctor_en.ts b/logdoctor/translations/LogDoctor_en.ts new file mode 100644 index 00000000..10eabfc8 --- /dev/null +++ b/logdoctor/translations/LogDoctor_en.ts @@ -0,0 +1,1746 @@ + + + + + Crapinfo + + Version + Version + + + Repository links + Repository links + + + Paths + Paths + + + Currently installed version of the software + Currently installed version of the software + + + The path of the executable file + The path of the executable file + + + Executable + Executable + + + The path where the configuration file gets saved and searched in + The path where the configuration file gets saved and searched in + + + Configuration file + Configuration file + + + The path where the application searches for extra resources + The path where the application searches for extra resources + + + Application data + Application data + + + + Crapnote + + Reduce the font size + Reduce the font size + + + Font size + Font size + + + Increase the font size + Increase the font size + + + + Crapup + + Checking for updates + Checking for updates + + + Failed to establish a connection + Failed to establish a connection + + + Connection error, please try again later + Connection error, please try again later + + + Connection timed out + Connection timed out + + + New version available + New version available + + + No update found + No update found + + + LogDoctor is up-to-date + No update found + + + :/ + :/ + + + You're running a version from the future! +Your version is beyond the current upstream version +Are you running the original LogDoctor? +Please visit the LogDoctor's repository and get a fresh version of it + You're running a version from the future! +Your version is beyond the current upstream version +Are you running the original LogDoctor? +Please visit the LogDoctor's repository and get a fresh version of it + + + Version check failed + Version check failed + + + An error occured while parsing: +initial version mark not found + An error occured while parsing: +initial version mark not found + + + An error occured while parsing: +final version mark not found + An error occured while parsing: +final version mark not found + + + An error occured while parsing: +malformed version + An error occured while parsing: +malformed version + + + An error occured while comparing: +malformed upstream version + An error occured while comparing: +malformed upstream version + + + A new version is available! +Please visit LogDoctor's git repository and follow the instruction about how to update + A new version is available! +Please visit LogDoctor's git repository and follow the instruction about how to update + + + + CrissCross + + You beated me! + You beated me! + + + This time you lost! + This time you lost! + + + Victory + Victory + + + Draw + Draw + + + Nice match + Nice match + + + + DialogBool + + Yes + Yes + + + No + No + + + + DialogDia + + Ignore + Ignore + + + Discard + Discard + + + Abort + Abort + + + + DialogMsg + + Ok + Ok + + + + DialogSec + + An error occured while reading the configuration file + An error occured while reading the configuration file + + + An error occured while parsing configuration file's data + An error occured while parsing configuration file's data + + + Failed to create the configuration file's directory + Failed to create the configuration file's directory + + + An error occured while writing the configuration file + An error occured while writing the configuration file + + + An error occured while preparing the configuration file's data + An error occured while preparing the configuration file's data + + + Failed to create the database backups' directory + Failed to create the database backups' directory + + + Failed to copy the database file + Failed to copy the database file + + + Failed to update the backups + Failed to update the backups + + + unrecognized entry + unrecognized entry + + + Failed to read gzipped file + Failed to read gzipped file + + + Discard it and continue, or Abort all and exit? + Discard it and continue, or Abort all and exit? + + + Create a new database? + Create a new database? + + + This database will renamed with a trailing '.copy' and a new one will be created. +Continue? + This database will renamed with a trailing '.copy' and a new one will be created. +Continue? + + + The entry will renamed with a trailing '.copy' and a new one will be created. +Continue? + The entry will renamed with a trailing '.copy' and a new one will be created. +Continue? + + + An error occured + An error occured + + + Failed renaming + Failed renaming + + + Invalid locale + Invalid locale + + + Configuration file not found + Configuration file not found + + + Failed to retrieve the help file + Failed to retrieve the help file + + + Not a file + Not a file + + + File not found + File not found + + + File not readable + File not readable + + + File not writable + File not writable + + + File is empty + File is empty + + + Failed reading + Failed reading + + + Not a folder + Not a folder + + + Directory not found + Directory not found + + + Directory not readable + Directory not readable + + + Directory not writable + Directory not writable + + + Failed creating directory + Failed creating directory + + + QSql driver not found + QSql driver not found + + + Database created + Database created + + + Failed creating database + Failed creating database + + + Failed opening database + Failed opening database + + + Failed executing on database + Failed executing on database + + + Unexpected table + Unexpected table + + + Table not found + Table not found + + + Unexpected column + Unexpected column + + + Column not found + Column not found + + + Unexpected data-type + Unexpected data-type + + + Failed to backup database + Failed to backup database + + + Failed defining type + Failed defining type + + + Log format error + Log format error + + + Misconfigured log format + Misconfigured log format + + + Invalid log format string + Invalid log format string + + + File already used + File already used + + + File exceeds warning size + File exceeds warning size + + + An error occured while renaming + An error occured while renaming + + + Unexpected locale format + Unexpected locale format + + + The given locale is not an accepted language + The given locale is not an accepted language + + + An error occured while handling the configuration file + An error occured while handling the configuration file + + + Unable to retrieve the configuration file + Unable to retrieve the configuration file + + + Current configuration not saved + Current configuration not saved + + + An error occured while getting the help file + An error occured while getting the help file + + + The path was supposed to point to a file, but it doesn't + The path was supposed to point to a file, but it doesn't + + + Unable to retrieve the file + Unable to retrieve the file + + + The file is not readable + The file is not readable + + + The file is not writable + The file is not writable + + + The file is blank + The file is blank + + + An error accured while reading the file + An error accured while reading the file + + + The path was supposed to point to a folder, but it doesn't + The path was supposed to point to a folder, but it doesn't + + + The directory does not exists + The directory does not exists + + + The directory is not readable + The directory is not readable + + + The directory is not writable + The directory is not writable + + + Failed to retrieve the driver neede to handle the database + Failed to retrieve the driver neede to handle the database + + + Failed to retrieve the database file + Failed to retrieve the database file + + + The database file is not readable + The database file is not readable + + + The database file is not writable + The database file is not writable + + + Successfully created a new database + Successfully created a new database + + + An error occured while creating the database + An error occured while creating the database + + + An error occured while opening the database + An error occured while opening the database + + + An error occured while executing a statement on the database + An error occured while executing a statement on the database + + + The database contains an unexpected table + The database contains an unexpected table + + + It seems that the database is missing a table + It seems that the database is missing a table + + + It seems that the table is missing a column + It seems that the table is missing a column + + + The database contains an unexpected column + The database contains an unexpected column + + + A column has an unexpected data-type + A column has an unexpected data-type + + + Failed to retrieve the selected file + Failed to retrieve the selected file + + + The file has probably been used already + The file has probably been used already + + + The file's size exceeds the warning size + The file's size exceeds the warning size + + + Failed to determine the log type + Failed to determine the log type + + + The log format has not been set, or is invalid +Please add a valid one in the configurations + The log format has not been set, or is invalid +Please add a valid one in the configurations + + + No log field has been set in the current logs format, +making it useless to parse logs + No log field has been set in the current logs format, +making it useless to parse logs + + + A separator is missing between one or more fields, +making it hard to establish net bounds, +and possibly leading to store incorrect data + A separator is missing between one or more fields, +making it hard to establish net bounds, +and possibly leading to store incorrect data + + + Please report this issue + Please report this issue + + + Please remove the conflict and retry + Please remove the conflict and retry + + + Please set the proper permissions before to start + Please set the proper permissions before to start + + + Please set the proper permissions and retry +If this error persists, please report this issue + Please set the proper permissions and retry +If this error persists, please report this issue + + + If you haven't manually edited the configuration file, +please report this issue + If you haven't manually edited the configuration file, +please report this issue + + + Please set up a format which contains at least one field + Please set up a format which contains at least one field + + + Please set up a format which contains separators between fields + Please set up a format which contains separators between fields + + + Skipping + Skipping + + + Aborting + Aborting + + + Additional resources can be downloaded from the git repo + Additional resources can be downloaded from the git repo + + + An error occured while parsing the format string + An error occured while parsing the format string + + + Size of the file + Size of the file + + + Warning size parameter + Warning size parameter + + + An error accured while reading the gzipped file + An error accured while reading the gzipped file + + + Something failed while handling the file + Something failed while handling the file + + + An error occured while working on the database + An error occured while working on the database + + + An error occured while working on the database + +Aborting + An error occured while working on the database + +Aborting + + + One of the lists has an invalid item + One of the lists has an invalid item + + + Failed to write the configuration file + Failed to write the configuration file + + + Failed applying configuration + Failed applying configuration + + + Invalid string + Invalid string + + + The given string is invalid and cannot be added to the list + +Please correct it and retry + The given string is invalid and cannot be added to the list + +Please correct it and retry + + + Please check that no error is thrown by your WebServer +If it gets accepted, please check the presence of a typo here +If everything is fine, please report this issue + Please check that no error is thrown by your WebServer +If it gets accepted, please check the presence of a typo here +If everything is fine, please report this issue + + + An error occured while parsing logs + An error occured while parsing logs + + + Ignore the warning and use it anyway, Discard it and continue, or Abort the entire process? + Ignore the warning and use it anyway, Discard it and continue, or Abort the entire process? + + + Proceed anyway? + Proceed anyway? + + + If you'd like to have this locale in LogDoctor, +please follow the instruction on the repository page + If you'd like to have this locale in LogDoctor, +please follow the instruction on the repository page + + + Failed to create the directory + Failed to create the directory + + + + MainWindow + + Parse logs from the Apache2 web server + Parse logs from the Apache2 web server + + + Parse logs from the Nginx web server + Parse logs from the Nginx web server + + + Parse logs from the Microsoft IIS web server + Parse logs from the Microsoft IIS web server + + + All + All + + + Inspect a log file + Inspect a log file + + + Name + Name + + + Size + Size + + + Refresh the list + Refresh the list + + + Total size of the parsed data + Total size of the parsed data + + + Total number of parsed lines + Total number of parsed lines + + + Start parsing the selected files + Start parsing the selected files + + + START + START + + + Time elapsed since the start + Time elapsed since the start + + + Average speed, in parsed data size per second + Average speed, in parsed data size per second + + + Draw the chart + Draw the chart + + + Web Server + Web Server + + + Select a Web Server + Select a Web Server + + + Year + Year + + + Month + Month + + + Day + Day + + + Hour + Hour + + + Update the database with current Warning States + Update the database with current Warning States + + + Log line marked as Warning + Log line marked as Warning + + + Date when the request arrived (YYYY-MM-DD) + Date when the request arrived (YYYY-MM-DD) + + + Time when the request arrived (hh:mm:ss) + Time when the request arrived (hh:mm:ss) + + + Protocol of the request + Protocol of the request + + + Method of the request + Method of the request + + + URI of the requested page + URI of the requested page + + + Response code from the server + Response code from the server + + + IP address of the Client which made the request + IP address of the Client which made the request + + + Size ib Bytes of the request, usually includes header and data + Size ib Bytes of the request, usually includes header and data + + + Size in Bytes of the served content, usually includes header and data + Size in Bytes of the served content, usually includes header and data + + + Protocol: + Protocol: + + + Method: + Method: + + + Response: + Response: + + + Query: + Query: + + + URI: + URI: + + + Filters + Filters + + + Query carried along with the URI + Query carried along with the URI + + + Cookie used for the request + Referrer for the request + + + User-agent of the client which made the request + User-agent of the client which made the request + + + Count + Count + + + Number of occurrences + Number of occurrences + + + Item + Item + + + Value of the field + Value of the field + + + From: + From: + + + To: + To: + + + Field: + Field: + + + Select a log field to view + Select a log field to view + + + Filter: + Filter: + + + Protocol + Protocol + + + Method + Method + + + URI + URI + + + User-agent + User-agent + + + Most recurrent + Most recurrent + + + Date ever + Date ever + + + Day of the week + Day of the week + + + Hour of the day + Hour of the day + + + Most trafficked + Most trafficked + + + Time taken + Time taken + + + Bytes sent + Bytes sent + + + Bytes received + Bytes received + + + Mean/Max performances + Mean/Max performances + + + Requests received + Requests received + + + Total work + Total work + + + General + General + + + General settings + General settings + + + Window + Window + + + Remember window's position and size + Remember window's position and size + + + Geometry + Geometry + + + Theme to use for the window + Theme to use for the window + + + Theme + Theme + + + None (System) + None (System) + + + Dark + Dark + + + Dialogs + Dialogs + + + Dialogs level + Dialogs level + + + Reduced quantity of dialog messages shown + Reduced quantity of dialog messages shown + + + Essential + Essential + + + Normal quantity of dialog messages shown + Normal quantity of dialog messages shown + + + Normal + Normal + + + Explanatory + Explanatory + + + Logs parser + Logs parser + + + Statistics viewer + Statistics viewer + + + TextBrowser + TextBrowser + + + Font to use for the Text Browser + Font to use for the Text Browser + + + Font + Font + + + Double-spaced lines + Double-spaced lines + + + Use wide lines + Use wide lines + + + Define the spacing between lines + Define the spacing between lines + + + Lines spacing + Lines spacing + + + None + None + + + Color scheme to use for the Text Browser + Color scheme to use for the Text Browser + + + Color scheme + Color scheme + + + The appearance of the Text Browser with the current settings + The appearance of the Text Browser with the current settings + + + Preview + Preview + + + Charts + Charts + + + Default (Light) + Default (Light) + + + Sand + Sand + + + Cerulean + Cerulean + + + Theme to use for the Charts + Theme to use for the Charts + + + Databases + Databases + + + Apply the current path + Apply the current path + + + Path where the logs data collection database is located + Path where the logs data collection database is located + + + Logs data + Logs data + + + The given path doen't exists, or doesn't point to a folder + The given path doen't exists, or doesn't point to a folder + + + Path where the used files hashes database is located + Path where the used files hashes database is located + + + Used files + Used files + + + Insert the base path only, file name excluded + Insert the base path only, file name excluded + + + Path for the database files + Path for the database files + + + Paths + Paths + + + Backup options for the Logs Data database + Backup options for the Logs Data database + + + Backups + Backups + + + A new backup is made when closing LogDoctor after having succesfully edited the database + A new backup is made when closing LogDoctor after having succesfully edited the database + + + Backup the Logs Data database and keep + Backup the Logs Data database and keep + + + Logs + Logs + + + Logs related settings + Logs related settings + + + Defaults + Defaults + + + Default WebServer + Default WebServer + + + Control + Control + + + Options about the log files usage control + Options about the log files usage control + + + Usage control + Usage control + + + Hide already used files + Hide already used files + + + Size warnings + Size warnings + + + Warn me when using files with a size exceeding: + Warn me when using files with a size exceeding: + + + Apache2 + Apache2 + + + Configure Apache2 specific options + Configure Apache2 specific options + + + Logs folder + Logs folder + + + Logs format string + Logs format string + + + Format string + Format string + + + Insert the format string you're using + Insert the format string you're using + + + Apply the current string + Apply the current string + + + Generate sample + Generate sample + + + Please check the correctness of this line. +Fields marked as 'DISCARDED' got parsed correctly, but are not considered by LogDoctor + Please check the correctness of this line. +Fields marked as 'DISCARDED' got parsed correctly, but are not considered by LogDoctor + + + Open an help window + Open an help window + + + Help + Help + + + Warnlists + Warnlists + + + Select a log field + Select a log field + + + Use warnlist for this field + Use warnlist for this field + + + Add the current line to the list + Add the current line to the list + + + Remove the selected item from the list + Remove the selected item from the list + + + Move the selected item down + Move the selected item down + + + Blacklists + Blacklists + + + Use blacklist for this field + Use blacklist for this field + + + Add line + Add line + + + Remove selection + Remove selection + + + Nginx + Nginx + + + Configure Nginx specific options + Configure Nginx specific options + + + IIS + IIS + + + Configure IIS specific options + Configure IIS specific options + + + Language + Language + + + Utilities + Utilities + + + Tools + Tools + + + Check updates + Check updates + + + Perform a version-check + Perform a version-check + + + Infos + Infos + + + BlockNote + BlockNote + + + Open a block-note like window to write temporary text + Open a block-note like window to write temporary text + + + copy + copy + + + copies + copies + + + Time taken by the server to serve the content, in milliseconds + Time taken by the server to serve the content, in milliseconds + + + Only use lines in which the field is starting with this string + Only use lines in which the field is starting with this string + + + Only use lines in which the field is matching this statement. +Use '!', '=','<' or '>' to declare what to use + Only use lines in which the field is matching this statement. +Use '!', '=','<' or '>' to declare what to use + + + With strings, only the lines in which the field is starting with this string will be used. +With numbers, use '!', '=','<' or '>' to declare what to use + With strings, only the lines in which the field is starting with this string will be used. +With numbers, use '!', '=','<' or '>' to declare what to use + + + The URL which redirected the Client to the requested page + The URL which redirected the Client to the requested page + + + Remember the window's position and size + Remember the window's position and size + + + Remember position and size + Remember position and size + + + Define the quantity of dialog mesages shown + Define the quantity of dialog mesages shown + + + Augmented quantity of dialog messages shown + Augmented quantity of dialog messages shown + + + Dialogs from the main processes + Dialogs from the main processes + + + Dialogs emitted when parsing logs + Dialogs emitted when parsing logs + + + Dialogs emitted when viewing statistics + Dialogs emitted when viewing statistics + + + Format + Format + + + Select/deselect all the files + Select/deselect all the files + + + Candy + Candy + + + Herb + Herb + + + Powder + Powder + + + warnlist + warnlist + + + blacklist + blacklist + + + Ash + Ash + + + Games + Games + + + CrissCross + CrissCross + + + Play CrissCross + Play CrissCross + + + Snake + Snake + + + Play Snake + Play Snake + + + Auto (Default) + Auto (Default) + + + Light + Light + + + Generate a sample log line from the currently saved string, to check if it gets formatted correctly. +Any field not considered by LogDoctor will appear as 'DISCARDED' + Generate a sample log line from the currently saved string, to check if it gets formatted correctly. +Any field not considered by LogDoctor will appear as 'DISCARDED' + + + Icons + Icons + + + + RichText + + Select a file from the list + Select a file from the list + + + to inspect its content + to inspect its content + + + Failed to read + Failed to read + + + + SnakeGame + + Game Over + Game Over + + + Your adversary fell in the water! + Your adversary fell in the water! + + + You fell in the water! + You fell in the water! + + + YOU LOST! + YOU LOST! + + + You ate yourself! + You ate yourself! + + + You ate your adversary! + You ate your adversary! + + + You ate each other! + You ate each other! + + + MATCH IS DRAW! + MATCH IS DRAW! + + + Your adversary ate itself! + Your adversary ate itself! + + + Your adversary ate you! + Your adversary ate you! + + + PLAY + PLAY + + + Classic + Classic + + + Hunt + Hunt + + + Battle + Battle + + + YOU WON! + YOU WON! + + + + TR + + Logs Size Breakdown + Logs Size Breakdown + + + Ignored + Ignored + + + Parsed + Parsed + + + Warnings + Warnings + + + Blacklisted + Blacklisted + + + FALSE + FALSE + + + TRUE + TRUE + + + Log Lines Marked as Warning + Log Lines Marked as Warning + + + Time Taken to Serve Requests + Time Taken to Serve Requests + + + Others + Others + + + Time of Day Count + Time of Day Count + + + from + from + + + to + to + + + Unexpected WebServer + Unexpected WebServer + + + An error occured while processing + An error occured while processing + + + An error occured while processing dates + An error occured while processing dates + + + An error occured while parsing %1 from the database + An error occured while parsing %1 from the database + + + Years + Years + + + Months + Months + + + Days + Days + + + Value responsible for the error + Value responsible for the error + + + Database table name + Database table name + + + Date + Date + + + Time + Time + + + Warning + Warning + + + Protocol + Protocol + + + Method + Method + + + URI + URI + + + Query + Query + + + Response code + Response code + + + Time taken + Time taken + + + Bytes sent + Bytes sent + + + Bytes received + Bytes received + + + Referrer + Referrer + + + Cookie + Cookie + + + Client + Client + + + User-agent + User-agent + + + January + January + + + February + February + + + March + March + + + April + April + + + May + May + + + June + June + + + July + July + + + August + August + + + September + September + + + October + October + + + November + November + + + December + December + + + Sunday + Sunday + + + Monday + Monday + + + Tuesday + Tuesday + + + Wednesday + Wednesday + + + Thursday + Thursday + + + Friday + Friday + + + Saturday + Saturday + + + diff --git a/logdoctor/translations/LogDoctor_es.ts b/logdoctor/translations/LogDoctor_es.ts new file mode 100644 index 00000000..13d25cd6 --- /dev/null +++ b/logdoctor/translations/LogDoctor_es.ts @@ -0,0 +1,2396 @@ + + + + + Crapinfo + + + Version + Versión + + + + Currently installed version of the software + Versión del software actualmente instalada + + + + Repository links + Links del repositorio + + + + Paths + Rutas + + + + The path of the executable file + El camino del ejecutable + + + + The path where the configuration file gets saved and searched in + La ruta donde se guarda y busca el archivo de configuración + + + + The path where the application searches for extra resources + La ruta donde la aplicación busca recursos extra + + + + Executable + Ejecutable + + + + Configuration file + Archivo de configuración + + + + Application data + Datos de la aplicación + + + + Crapnote + + + Reduce the font size + Reducir el tamaño de font + + + + Font size + tamaño de font + + + + Increase the font size + Aumentar el tamaño de font + + + + Crapup + + + Checking for updates + Comprobando para actualizaciones + + + + Failed to establish a connection + Error al establecer una conexión + + + + Connection error, please try again later + Error de conexión, inténtalo de nuevo más tarde + + + + Connection timed out + Tiempo de conexión agotado + + + + New version available + Nueva versión disponible + + + + A new version is available! +Please visit LogDoctor's git repository and follow the instruction about how to update + ¡Una nueva versión es disponible! +Visite el repositorio git de LogDoctor y siga las instrucciones sobre cómo actualizar + + + + No update found + Ninguna actualización encontrada + + + + LogDoctor is up-to-date + LogDoctor está actualizado + + + + :/ + :/ + + + + You're running a version from the future! +Your version is beyond the current upstream version +Are you running the original LogDoctor? +Please visit the LogDoctor's repository and get a fresh version of it + ¡Estás ejecutando una versión del futuro! +Tu versión es mayor de la versión online +¿Estás ejecutando el LogDoctor original? +Visita el repositorio de LogDoctor y descargalo una otra vez + + + + Version check failed + Comprobación de la versión fallida + + + + An error occured while parsing: +initial version mark not found + Ocurrió un error al analizar: +marcador inicial no encontrado + + + + An error occured while parsing: +final version mark not found + Ocurrió un error al analizar: +marcador final no encontrado + + + + An error occured while parsing: +malformed version + Ocurrió un error al analizar: +versión mal formada + + + + An error occured while comparing: +malformed upstream version + Ocurrió un error al comparar: +versión online mal formada + + + + CrissCross + + + You beated me! + ¡Me ganaste! + + + + This time you lost! + ¡Esta vez perdiste! + + + + Victory + Victoria + + + + Draw + Empate + + + + Nice match + Bien jugada + + + + DialogBool + + + Yes + + + + + No + No + + + + DialogDia + + + Ignore + Ignorar + + + + Discard + Descartar + + + + Abort + Anular + + + + DialogMsg + + + Ok + Ok + + + + DialogSec + + + An error occured while reading the configuration file + Error durante la lectura del archivo de configuración + + + + One of the lists has an invalid item + Una de las listas tiene un elemento no válido + + + + An error occured while parsing configuration file's data + Error durante el análisis del archivo de configuración + + + + + Failed to create the configuration file's directory + Error al crear la carpeta del archivo de configuración + + + + An error occured while writing the configuration file + Error al escribir el archivo de configuración + + + + An error occured while preparing the configuration file's data + Error al preparar los datos de los archivos de configuración + + + + + Failed to create the database backups' directory + Error al crear el directorio de copias de seguridad del database + + + + Failed to copy the database file + Error al copiar el archivo del database + + + + + Failed to update the backups + Error al actualizar las copias de seguridad + + + + + Failed to create the directory + Error al crear la carpeta + + + + unrecognized entry + entrada no reconocida + + + + Failed to read gzipped file + Lectura del archivo gzip no conseguida + + + + Discard it and continue, or Abort all and exit? + ¿Descartarlo y continuar, o Anular todo y salir? + + + + Create a new database? + Crear un nuevo database? + + + + This database will renamed with a trailing '.copy' and a new one will be created. +Continue? + Este database se renombrará con el final '.copia' y se creará uno nuevo. +¿Continuar? + + + + + Ignore the warning and use it anyway, Discard it and continue, or Abort the entire process? + ¿Ignorar la advertencia y usarlo igualmente, Descartarlo y continuar o Anular todo el proceso? + + + + Proceed anyway? + ¿Procede de todas maneras? + + + + + The entry will renamed with a trailing '.copy' and a new one will be created. +Continue? + La entrada se renombrará con el final '.copia' y se creará una nueva. +¿Continuar? + + + + An error occured + Ocurrió un error + + + + Failed renaming + Renombramiento fallido + + + + + Invalid locale + Idioma no válido + + + + Configuration file not found + Archivo de configuración no encontrado + + + + Failed to retrieve the help file + Error al recuperar el archivo de ayuda + + + + + Not a file + No es un archivo + + + + + + File not found + Archivo no encontrado + + + + + + File not readable + Archivo no legible + + + + + File not writable + Archivo no escribible + + + + File is empty + El archivo está vacío + + + + Failed reading + Lectura fallida + + + + Not a folder + No es una carpeta + + + + Directory not found + Carpeta no encontrada + + + + + Directory not readable + Carpeta no legible + + + + + + Directory not writable + Carpeta no escribible + + + + Failed creating directory + Creación de la carpeta fallida + + + + QSql driver not found + Driver QSql no encontrado + + + + Database created + Database creado + + + + Failed creating database + Error al crear el database + + + + Failed opening database + Error al abrir el database + + + + Failed executing on database + Error al ejecutar en el database + + + + Unexpected table + Tabla inesperada + + + + If you'd like to have this locale in LogDoctor, +please follow the instruction on the repository page + Si deseas tener este idioma en LogDoctor, +por favor sigue las instrucciones en la página del repositorio + + + + Table not found + Tabla no encontrada + + + + Unexpected column + Columna inesperada + + + + Column not found + Columna no encontrada + + + + Unexpected data-type + Tipo de datos inesperado + + + + Failed to backup database + Error al respaldar el database + + + + Please check that no error is thrown by your WebServer +If it gets accepted, please check the presence of a typo here +If everything is fine, please report this issue + Verifique que su servidor web no arroje ningún error +Si la acepta, verifique la presencia de un error tipográfico aquí +Si todo está bien, por favor notifica este problema + + + + An error occured while parsing logs + Error durante el análisis de los registros + + + + Failed defining type + Error al definir el tipo + + + + Log format error + Error de formato de registro + + + + + Misconfigured log format + Formato de registro mal configurado + + + + Invalid log format string + Cadena de formato de registro no válida + + + + File already used + Archivo ya usado + + + + + File exceeds warning size + El archivo excede el tamaño de advertencia + + + + An error occured while renaming + Error al renombrar + + + + Unexpected locale format + Formato de idioma inesperado + + + + The given locale is not an accepted language + El idioma dado no está entre los aceptados + + + + + + + An error occured while handling the configuration file + Error al manejar el archivo de configuración + + + + Unable to retrieve the configuration file + Falla en el recuperar el archivo de configuración + + + + Current configuration not saved + Configuración actual no guardada + + + + Failed to write the configuration file + Error al escribir el archivo de configuración + + + + Failed applying configuration + Error al aplicar la configuración + + + + An error occured while getting the help file + Error al obtener el archivo de ayuda + + + + Invalid string + Cadena inválida + + + + The given string is invalid and cannot be added to the list + +Please correct it and retry + La cadena dada no es válida y no se puede agregar a la lista + +Corrígela y vuelve a intentarlo + + + + + The path was supposed to point to a file, but it doesn't + La ruta debería apuntar a un archivo, pero no lo hace + + + + + Unable to retrieve the file + Falla en el recuperar el archivo + + + + + + The file is not readable + El archivo no es legible + + + + The file is not writable + El archivo no es escribible + + + + The file is blank + El archivo está vacío + + + + + + An error accured while reading the file + Error en la lectura del archivo + + + + The path was supposed to point to a folder, but it doesn't + La ruta debería apuntar a una carpeta, pero no lo hace + + + + The directory does not exists + La carpeta no existe + + + + + The directory is not readable + La carpeta no es legible + + + + + + The directory is not writable + La carpeta no es escribible + + + + Failed to retrieve the driver neede to handle the database + Error en el recuperar el driver necesario para manejar el database + + + + + Failed to retrieve the database file + Error en el recuperar el archivo del database + + + + The database file is not readable + El archivo de database no es legible + + + + The database file is not writable + El archivo de database no es escribible + + + + Successfully created a new database + Database creado con buen éxito + + + + An error occured while creating the database + Error al crear el database + + + + An error occured while opening the database + Error al abrir el database + + + + An error occured while executing a statement on the database + Error al ejecutar una declaración en el database + + + + The database contains an unexpected table + El database contiene una tabla inesperada + + + + It seems that the database is missing a table + Parece que a el database le falta una tabla + + + + It seems that the table is missing a column + Parece que a la tabla le falta una columna + + + + The database contains an unexpected column + El database contiene una columna inesperada + + + + A column has an unexpected data-type + Una columna tiene un tipo de datos inesperado + + + + Failed to retrieve the selected file + Error al recuperar el archivo seleccionado + + + + The file has probably been used already + El archivo probablemente ya se ha utilizado + + + + + The file's size exceeds the warning size + El tamaño del archivo excede el de la advertencia + + + + Failed to determine the log type + Falla al determinar el tipo de registro + + + + The log format has not been set, or is invalid +Please add a valid one in the configurations + El formato de registro no se ha establecido, o es invalido +Por favor añade uno valido en la configuración + + + + No log field has been set in the current logs format, +making it useless to parse logs + No se ha establecido ningún campo de registro en el formato actual, +por lo tanto es inútil analizar algunos archivos + + + + A separator is missing between one or more fields, +making it hard to establish net bounds, +and possibly leading to store incorrect data + Falta un separador entre uno o más campos, +esto dificulta establecer límites netos, +y puede llevar a almacenar datos incorrectos + + + + + + Please report this issue + Por favor notifica este problema + + + + Please remove the conflict and retry + Elimina el conflicto y vuelve a intentarlo + + + + + Please set the proper permissions before to start + Establezca los permisos adecuados antes de comenzar + + + + + + + + Please set the proper permissions and retry +If this error persists, please report this issue + Establezca los permisos adecuados y vuelva a intentarlo +Si el error persiste, por favor notifica este problema + + + + If you haven't manually edited the configuration file, +please report this issue + Si no has editado manualmente el archivo de configuración, +por favor notifica este problema + + + + Please set up a format which contains at least one field + Configure un formato que contenga al menos un campo + + + + Please set up a format which contains separators between fields + Configura un formato que contenga un separador entre cada campo + + + + + + + Skipping + Saltado + + + + + + + + + + Aborting + Anulado + + + + Additional resources can be downloaded from the git repo + Se pueden descargar recursos adicionales desde el repositorio + + + + + + An error occured while parsing the format string + Error al analizar la cadena de formato + + + + + Size of the file + Tamaño del archivo + + + + + Warning size parameter + Parámetro de advertencia del tamaño + + + + + An error accured while reading the gzipped file + Error en la lectura del archivo gzip + + + + + Something failed while handling the file + Algo falló al manejar el archivo + + + + An error occured while working on the database + Error durante el trabajo en el database + + + + An error occured while working on the database + +Aborting + Error durante el trabajo en el database + +Anulado + + + + MainWindow + + + + Parse logs from the Apache2 web server + Analizar los registros del servidor web Apache2 + + + + + Parse logs from the Nginx web server + Analizar los registros del servidor web Nginx + + + + + Parse logs from the Microsoft IIS web server + Analizar los registros del servidor web Microsoft IIS + + + + All + Todos + + + + Inspect a log file + Inspeccionar un archivo de registro + + + + Name + Nombre + + + + Size + Tamaño + + + + Refresh the list + Actualizar la lista + + + + Total size of the parsed data + Tamaño total de los datos analizados + + + + Total number of parsed lines + Número total de líneas analizadas + + + + Start parsing the selected files + Comenzar a analizar los archivos seleccionados + + + + START + START + + + + Time elapsed since the start + Tiempo transcurrido desde el inicio + + + + Average speed, in parsed data size per second + Velocidad media, en tamaño de datos analizados por segundo + + + + + + Draw the chart + Dibujar el gráfico + + + + Web Server + Web Server + + + + + + + + Select a Web Server + Seleccione un Web Server + + + + + + + + + + + Year + Año + + + + + + + + + + + Month + Mes + + + + + + + + + + + Day + Día + + + + Hour + Hora + + + + Update the database with current Warning States + Actualice el database con los estados de advertencia actuales + + + + Log line marked as Warning + Línea de registro marcada como Advertencia + + + + Date when the request arrived (YYYY-MM-DD) + Fecha en que llegó la solicitud (AAAA-MM-DD) + + + + + Time when the request arrived (hh:mm:ss) + Hora en que llegó la solicitud (hh:mm:ss) + + + + + + + Protocol of the request + Protocolo de la solicitud + + + + + + + Method of the request + Método de la solicitud + + + + + + + URI of the requested page + URL de la página solicitada + + + + + + + Response code from the server + Código de respuesta del servidor + + + + + IP address of the Client which made the request + Dirección IP del cliente que realizó la solicitud + + + + Size ib Bytes of the request, usually includes header and data + Tamaño en Bytes de la solicitud, generalmente incluye el header y los datos + + + + Size in Bytes of the served content, usually includes header and data + Tamaño en Bytes del contenido servido, generalmente incluye el header y los datos + + + + Protocol: + Protocolo: + + + + Method: + Método: + + + + Response: + Respuesta: + + + + Query: + Query: + + + + URI: + URI: + + + + Filters + Filtros + + + + + + + Query carried along with the URI + Query llevada junto con el URI + + + + + Cookie used for the request + Cookie utilizado para la solicitud + + + + + User-agent of the client which made the request + User-agent del cliente que realizó la solicitud + + + + Count + Cálculo + + + + + The URL which redirected the Client to the requested page + La URL que redirigió al Cliente a la página solicitada + + + + Number of occurrences + Numero de incidentes + + + + Item + Artículo + + + + Value of the field + Valor del campo + + + + + From: + De: + + + + + To: + A: + + + + + + Field: + Campo: + + + + + + Select a log field to view + Seleccione un campo de registro para ver + + + + + + Filter: + Filtro: + + + + Protocol + Protocolo + + + + Method + Método + + + + URI + URI + + + + User-agent + User-agent + + + + Most recurrent + Más recurrente + + + + Date ever + Fecha de la historia + + + + Day of the week + Día de la semana + + + + Hour of the day + Hora del día + + + + Most trafficked + Más traficado + + + + Select/deselect all the files + Seleccione/deseleccione todos los archivios + + + + + Time taken + Tiempo tomado + + + + + Bytes sent + Bytes enviados + + + + Bytes received + Bytes recibidos + + + + Mean/Max performances + Desempeño medio/máximo + + + + Requests received + Solicitudes recibidas + + + + Total work + Trabajo total + + + + + General + General + + + + General settings + Configuración general + + + + Window + Ventana + + + + + + + + + Remember window's position and size + Recuerda la posición y el tamaño de la ventana + + + + Geometry + Apariencia + + + + + Theme to use for the window + Tema a usar para la ventana + + + + + Theme + Tema + + + + None (System) + Ninguno (Sistema) + + + + + Dark + Oscuro + + + + Dialogs + Diálogos + + + + Candy + Dulce + + + + Herb + Hierba + + + + Powder + Polvo + + + + Auto (Default) + Auto (Predeterminado) + + + + Light + Claro + + + + Dialogs level + Nivel de diálogo + + + + Reduced quantity of dialog messages shown + Cantidad reducida de mensajes de diálogo mostrados + + + + Essential + Básico + + + + Normal quantity of dialog messages shown + Cantidad normal de mensajes de diálogo mostrados + + + + Normal + Normal + + + + Explanatory + Explicativo + + + + Logs parser + Analizador de registros + + + + Statistics viewer + Visor de estadísticas + + + + TextBrowser + TextBrowser + + + + Font to use for the Text Browser + Font a usar para el Text Browser + + + + Font + Font + + + + Double-spaced lines + Líneas a doble espacio + + + + Use wide lines + Usa líneas anchas + + + + Define the spacing between lines + Definir el espaciado entre líneas + + + + Lines spacing + Espaciado de líneas + + + + None + Ninguno + + + + Color scheme to use for the Text Browser + Combinación de colores a utilizar para el Text Browser + + + + Color scheme + Esquema de colores + + + + The appearance of the Text Browser with the current settings + La apariencia del Text Browser con la configuración actual + + + + + Preview + Preestreno + + + + Charts + Gráficos + + + + Default (Light) + Predeterminado (Claro) + + + + Sand + Arena + + + + Cerulean + Azul claro + + + + Theme to use for the Charts + Tema a usar para los Gráficos + + + + Databases + Databases + + + + + + + + Apply the current path + Aplicar la ruta actual + + + + Path where the logs data collection database is located + Ruta donde se encuentra el database de recopilación de datos de registros + + + + Logs data + Datos de registros + + + + + + + + The given path doen't exists, or doesn't point to a folder + La ruta dada no existe o no apunta a una carpeta + + + + Path where the used files hashes database is located + Ruta donde se encuentra el database de hash de los archivos usados + + + + Used files + Archivos usados + + + + + Insert the base path only, file name excluded + Inserte solo la ruta base, nombre de archivo excluido + + + + Path for the database files + Ruta de los archivos de el database + + + + + + + Paths + Rutas + + + + Backup options for the Logs Data database + Opciones de copia de seguridad para el database de datos de registros + + + + Backups + Copias de seguridad + + + + A new backup is made when closing LogDoctor after having succesfully edited the database + Se realiza una nueva copia de seguridad al cerrar LogDoctor después de haber editado correctamente el database + + + + Backup the Logs Data database and keep + Haga una copia de seguridad de el database de datos y conserve + + + + Logs + Registros + + + + Logs related settings + Configuración relacionada con los registros + + + + Defaults + Predeterminados + + + + Default WebServer + Servidor Web predeterminado + + + + Control + Controlar + + + + Options about the log files usage control + Opciones sobre el control de uso de archivos de registro + + + + Usage control + Control de uso + + + + Hide already used files + Ocultar archivos ya usados + + + + Size warnings + Advertencias de tamaño + + + + Warn me when using files with a size exceeding: + Avisarme cuando use archivos con un tamaño superior a: + + + + + + Generate a sample log line from the currently saved string, to check if it gets formatted correctly. +Any field not considered by LogDoctor will appear as 'DISCARDED' + Genere una línea de registro de muestra a partir de la cadena guardada actualmente, para verificar si se formatea correctamente. +Cualquier campo no considerado por LogDoctor aparecerá como 'DISCARDED' + + + + CrissCross + CrissCross + + + + Play CrissCross + Jugar a CrissCross + + + + Snake + Snake + + + + Play Snake + Jugar a Snake + + + + + + + + + + + Apache2 + Apache2 + + + + + Time taken by the server to serve the content, in milliseconds + Tiempo que tarda el servidor en servir el contenido, en milisegundos + + + + + + + Only use lines in which the field is starting with this string + Use solo líneas en las que el campo comience con esta cadena + + + + Only use lines in which the field is matching this statement. +Use '!', '=','<' or '>' to declare what to use + Solo use líneas en las que el campo coincida con esta declaración. +Use '!', '=', '<' o '>' para declarar qué usar + + + + + + With strings, only the lines in which the field is starting with this string will be used. +With numbers, use '!', '=','<' or '>' to declare what to use + Con cadenas, solo se utilizarán las líneas en las que el campo comienza con esta cadena. +Con números, use '!', '=', '<' o '>' para declarar qué usar + + + + Remember the window's position and size + Recuerda la posición y el tamaño de la ventana + + + + Remember position and size + Recuerda posición y tamaño + + + + Ash + Ceniza + + + + Icons + Iconos + + + + Define the quantity of dialog mesages shown + Definir la cantidad de mensajes de diálogo que se muestran + + + + Augmented quantity of dialog messages shown + Cantidad aumentada de mensajes de diálogo mostrados + + + + Dialogs from the main processes + Diálogos de los principales procesos + + + + Dialogs emitted when parsing logs + Diálogos emitidos al analizar registros + + + + Dialogs emitted when viewing statistics + Diálogos emitidos al visualizar estadísticas + + + + Configure Apache2 specific options + Configurar opciones específicas de Apache2 + + + + + + Logs folder + Carpeta de registros + + + + + + Logs format string + Cadena de formato de registros + + + + + + Format string + Cadena de formato + + + + + + Insert the format string you're using + Inserta la cadena de formato que estás usando + + + + + + Apply the current string + Aplicar la cadena actual + + + + + + Generate sample + Generar muestra + + + + + + Please check the correctness of this line. +Fields marked as 'DISCARDED' got parsed correctly, but are not considered by LogDoctor + Por favor, compruebe la exactitud de esta línea. +Los campos marcados como 'DISCARDED' se analizaron correctamente, pero LogDoctor no los tiene en cuenta + + + + + + Open an help window + Abrir una ventana de ayuda + + + + + + Help + Ayuda + + + + + + Warnlists + Warnlists + + + + + + + + + Select a log field + Seleccione un campo de registro + + + + + + Use warnlist for this field + Usar Lista de Advertencia para este campo + + + + Add the current line to the list + Agregar la línea actual a la lista + + + + Remove the selected item from the list + Eliminar el elemento seleccionado de la lista + + + + + + + + + + + + + + + Move the selected item down + Mover el elemento seleccionado hacia abajo + + + + + + Blacklists + Blacklists + + + + + + Use blacklist for this field + Usar Lista Negra para este campo + + + + + + + + Add line + Añadir línea + + + + + + + + Remove selection + Eliminar selección + + + + + + + + + + + Nginx + Nginx + + + + Configure Nginx specific options + Configurar opciones específicas de Nginx + + + + + + + + + + + IIS + IIS + + + + + + Format + Formato + + + + Configure IIS specific options + Configurar opciones específicas de IIS + + + + Language + Langue + + + + Utilities + Utilidades + + + + Tools + Instrumentos + + + + Games + Juegos + + + + Check updates + Revisa actualizaciones + + + + Perform a version-check + Realizar una verificación de versión + + + + Infos + Información + + + + BlockNote + Bloc de Notas + + + + Open a block-note like window to write temporary text + Abra una ventana similar a una nota de bloque para escribir texto temporal + + + + + + + + + + + + + + + warnlist + warnlists + + + + + + blacklist + blacklist + + + + copy + copia + + + + copies + copias + + + + RichText + + + Select a file from the list + Seleccione un archivo de la lista + + + + to inspect its content + para inspeccionar su contenido + + + + Failed to read + Fracaso en la lectura + + + + SnakeGame + + + Game Over + Game Over + + + + Your adversary fell in the water! + ¡Tu adversario cayó en el agua! + + + + + + YOU WON! + ¡GANASTE! + + + + You fell in the water! + ¡Te caíste en la agua! + + + + + + YOU LOST! + ¡PERDISTE! + + + + Your adversary ate itself! + ¡Tu adversario se comió a sí mismo! + + + + Your adversary ate you! + ¡Tu adversario te comió! + + + + You ate yourself! + ¡Te comiste a ti mismo! + + + + You ate your adversary! + ¡Comiste a tu adversario! + + + + You ate each other! + ¡Se comieron el uno al otro! + + + + MATCH IS DRAW! + ¡CORBATA! + + + + PLAY + JUGAR + + + + Classic + Clásico + + + + Hunt + Caza + + + + Battle + Batalla + + + + TR + + + Logs Size Breakdown + Desglose del Tamaño de los Registros + + + + Ignored + Ignorado + + + + Parsed + Analizado + + + + Warnings + Advertencias + + + + Blacklisted + Excluido + + + + FALSE + FALSO + + + + TRUE + VERDADERO + + + + Log Lines Marked as Warning + Líneas Marcadas como Advertencia + + + + Time Taken to Serve Requests + Tiempo Necesario para Atender las Solicitudes + + + + Others + Otros + + + + + Time of Day Count + Recuento de la Hora del Día + + + + + from + de + + + + + to + a + + + + Unexpected WebServer + WebServer inesperdado + + + + An error occured while processing + Ocurrió un error durante el procesamiento + + + + An error occured while processing dates + Ocurrió un error al procesar las fechas + + + + An error occured while parsing %1 from the database + Ocurrió un error al procesar los %1 en la base de datos + + + + Years + Años + + + + Months + Meses + + + + Days + Días + + + + Value responsible for the error + Valor responsable del error + + + + Database table name + Nombre de la tabla de la base de datos + + + + Date + Fecha + + + + Time + Tiempo + + + + Warning + Advertencia + + + + Protocol + Protocolo + + + + Method + Método + + + + URI + URI + + + + Query + Query + + + + Response code + Código de respuesta + + + + Time taken + Tiempo tomado + + + + Bytes sent + Bytes enviados + + + + Bytes received + Bytes recibidos + + + + Referrer + Referente + + + + Cookie + Cookie + + + + Client + Cliente + + + + User-agent + User-agent + + + + January + Enero + + + + February + Febrero + + + + March + Marzo + + + + April + Abril + + + + May + Mayo + + + + June + Junio + + + + July + Julio + + + + August + Agosto + + + + September + Septiembre + + + + October + Octubre + + + + November + Noviembre + + + + December + Diciembre + + + + Sunday + Domingo + + + + Monday + Lunes + + + + Tuesday + Martes + + + + Wednesday + Miércoles + + + + Thursday + Jueves + + + + Friday + Viernes + + + + Saturday + Sábado + + + diff --git a/logdoctor/translations/LogDoctor_fr.ts b/logdoctor/translations/LogDoctor_fr.ts new file mode 100644 index 00000000..67455713 --- /dev/null +++ b/logdoctor/translations/LogDoctor_fr.ts @@ -0,0 +1,2396 @@ + + + + + Crapinfo + + + Version + Version + + + + Currently installed version of the software + Version actuallement installée + + + + Repository links + Links de référentiel + + + + Paths + Chemins + + + + The path of the executable file + Le chemin de l'exécutable + + + + The path where the configuration file gets saved and searched in + Le chemin où le fichier de configuration est enregistré et recherché dans + + + + The path where the application searches for extra resources + Le chemin où l'application recherche des ressources supplémentaires + + + + Executable + Exécutable + + + + Configuration file + Fichier de configuration + + + + Application data + Ressources d'application + + + + Crapnote + + + Reduce the font size + Réduire la taille de la font + + + + Font size + taille de la font + + + + Increase the font size + Augmenter la taille de la font + + + + Crapup + + + Checking for updates + Vérification des mises à jour + + + + Failed to establish a connection + Échec de l'établissement d'une connexion + + + + Connection error, please try again later + Erreur de connexion, veuillez réessayer plus tard + + + + Connection timed out + La connexion a expiré + + + + New version available + Nouvelle version disponible + + + + A new version is available! +Please visit LogDoctor's git repository and follow the instruction about how to update + Une nouvelle version est disponible! +Veuillez visiter le référentiel git de LogDoctor et suivez les instructions sur la façon de mettre à jour + + + + No update found + Aucune mise à jour trouvée + + + + LogDoctor is up-to-date + LogDoctor est à jour + + + + :/ + :/ + + + + You're running a version from the future! +Your version is beyond the current upstream version +Are you running the original LogDoctor? +Please visit the LogDoctor's repository and get a fresh version of it + Vous utilisez une version du futur! +Votre version est au-delà de la version amont actuelle +Utilisez-vous le LogDoctor d'origine? +Veuillez visiter le référentiel de LogDoctor et en obtenir une nouvelle version + + + + Version check failed + La vérification de la version a échoué + + + + An error occured while parsing: +initial version mark not found + Une erreur s'est produite lors de l'analyse: +marqueur initial pas trouvé + + + + An error occured while parsing: +final version mark not found + Une erreur s'est produite lors de l'analyse: +marqueur final pas trouvé + + + + An error occured while parsing: +malformed version + Une erreur s'est produite lors de l'analyse: +version malformée + + + + An error occured while comparing: +malformed upstream version + Une erreur s'est produite lors de la comparaison: +version online malformée + + + + CrissCross + + + You beated me! + Tu m'as battu! + + + + This time you lost! + Cette fois, vous avez perdu! + + + + Victory + Victoire + + + + Draw + Nul + + + + Nice match + Bon match + + + + DialogBool + + + Yes + Oui + + + + No + Non + + + + DialogDia + + + Ignore + Ignorer + + + + Discard + Jeter + + + + Abort + Abandonner + + + + DialogMsg + + + Ok + Ok + + + + DialogSec + + + An error occured while reading the configuration file + Une erreur s'est produite lors de la lecture du fichier de configuration + + + + One of the lists has an invalid item + L'une des listes contient un élément non valide + + + + An error occured while parsing configuration file's data + Une erreur s'est produite lors de l'analyse des données du fichier de configuration + + + + + Failed to create the configuration file's directory + Échec de la création du répertoire du fichier de configuration + + + + An error occured while writing the configuration file + Une erreur s'est produite lors de l'écriture du fichier de configuration + + + + An error occured while preparing the configuration file's data + Une erreur s'est produite lors de la préparation des données des fichiers de configuration + + + + + Failed to create the database backups' directory + Echec de la création du répertoire des sauvegardes de le database + + + + Failed to copy the database file + Impossible de copier le fichier de database + + + + + Failed to update the backups + Échec de la mise à jour des sauvegardes + + + + + Failed to create the directory + Échec de la création du répertoire + + + + unrecognized entry + entrée non reconnue + + + + Failed to read gzipped file + Impossible de lire le fichier gzippé + + + + Discard it and continue, or Abort all and exit? + Jetez-le et continuez, ou tout Abandonner et quitter? + + + + Create a new database? + Créer un nouveau database? + + + + This database will renamed with a trailing '.copy' and a new one will be created. +Continue? + Cette database sera renommée avec un '.copy' à la fin et une nouvelle sera créée. +Continuer? + + + + + Ignore the warning and use it anyway, Discard it and continue, or Abort the entire process? + Ignorer l'avertissement et l'utiliser quand même, Jeter el et continuer, ou Abandonner tout le processus? + + + + Proceed anyway? + Continuer malgré tout? + + + + + The entry will renamed with a trailing '.copy' and a new one will be created. +Continue? + L'entrée sera renommée avec un « .copy » à la fin et une nouvelle sera créée. +Continuer? + + + + An error occured + Une erreur s'est produite + + + + Failed renaming + Échec du changement de nom + + + + + Invalid locale + Paramètres régionaux non valides + + + + Configuration file not found + Fichier de configuration introuvable + + + + Failed to retrieve the help file + Échec de la récupération du fichier d'aide + + + + + Not a file + Pas un fichier + + + + + + File not found + Fichier introuvable + + + + + + File not readable + Fichier illisible + + + + + File not writable + Fichier non inscriptible + + + + File is empty + Le fichier est vide + + + + Failed reading + Échec de la lecture + + + + Not a folder + Pas un dossier + + + + Directory not found + Dossier introuvable + + + + + Directory not readable + Dossier illisible + + + + + + Directory not writable + Dossier non inscriptible + + + + Failed creating directory + Échec de la création du dossier + + + + QSql driver not found + Driver QSql introuvable + + + + Database created + Database créée + + + + Failed creating database + Échec de la création de le database + + + + Failed opening database + Échec de l'ouverture de le database + + + + Failed executing on database + Échec de l'exécution sur le database + + + + Unexpected table + Tableau inattendu + + + + If you'd like to have this locale in LogDoctor, +please follow the instruction on the repository page + Si vous souhaitez avoir cette locale dans LogDoctor, +veuillez suivre les instructions sur la page du référentiel + + + + Table not found + Tableau introuvable + + + + Unexpected column + Colonne inattendue + + + + Column not found + Colonne introuvable + + + + Unexpected data-type + Type de données inattendu + + + + Failed to backup database + Échec de la sauvegarde de le database + + + + Please check that no error is thrown by your WebServer +If it gets accepted, please check the presence of a typo here +If everything is fine, please report this issue + Veuillez vérifier qu'aucune erreur n'est renvoyée par votre WebServer +S'il est accepté, veuillez vérifier la présence d'une faute de frappe ici +Si tout va bien, signaler ce problème s'il vous plaît + + + + An error occured while parsing logs + Une erreur s'est produite lors de l'analyse de les journaux + + + + Failed defining type + Échec de la définition du type + + + + Log format error + Erreur de format de journal + + + + + Misconfigured log format + Format de journal mal configuré + + + + Invalid log format string + Chaîne de format de journal non valide + + + + File already used + Fichier déjà utilisé + + + + + File exceeds warning size + Le fichier dépasse la taille d'avertissement + + + + An error occured while renaming + Une erreur s'est produite lors du changement de nom + + + + Unexpected locale format + Format de paramètres régionaux inattendu + + + + The given locale is not an accepted language + La locale donnée n'est pas une langue acceptée + + + + + + + An error occured while handling the configuration file + Une erreur s'est produite lors de la gestion du fichier de configuration + + + + Unable to retrieve the configuration file + Impossible de récupérer le fichier de configuration + + + + Current configuration not saved + Configuration actuelle non enregistrée + + + + Failed to write the configuration file + Échec de l'écriture du fichier de configuration + + + + Failed applying configuration + Échec lors de l'application de la configuration + + + + An error occured while getting the help file + Une erreur s'est produite lors de l'obtention du fichier d'aide + + + + Invalid string + Chaîne invalide + + + + The given string is invalid and cannot be added to the list + +Please correct it and retry + La chaîne donnée n'est pas valide et ne peut pas être ajoutée à la liste + +Veuillez le corriger et réessayer + + + + + The path was supposed to point to a file, but it doesn't + Le chemin était censé pointer vers un fichier, mais ce n'est pas le cas + + + + + Unable to retrieve the file + Impossible de récupérer le fichier + + + + + + The file is not readable + Le fichier n'est pas lisible + + + + The file is not writable + Le fichier n'est pas accessible en écriture + + + + The file is blank + Le fichier est vide + + + + + + An error accured while reading the file + Une erreur s'est produite lors de la lecture du fichier + + + + The path was supposed to point to a folder, but it doesn't + Le chemin était censé pointer vers un dossier, mais ce n'est pas le cas + + + + The directory does not exists + Le dossier n'existe pas + + + + + The directory is not readable + Le dossier n'est pas lisible + + + + + + The directory is not writable + Le dossier n'est pas accessible en écriture + + + + Failed to retrieve the driver neede to handle the database + Impossible de récupérer le driver nécessaire pour gérer la base de données + + + + + Failed to retrieve the database file + Impossible de récupérer le fichier de database + + + + The database file is not readable + Le fichier de database n'est pas lisible + + + + The database file is not writable + Le fichier de database n'est pas accessible en écriture + + + + Successfully created a new database + Création réussie d'un nouveau database + + + + An error occured while creating the database + Une erreur s'est produite lors de la création de le database + + + + An error occured while opening the database + Une erreur s'est produite lors de l'ouverture de le database + + + + An error occured while executing a statement on the database + Une erreur s'est produite lors de l'exécution d'une instruction sur le database + + + + The database contains an unexpected table + Le databaase contient une table inattendue + + + + It seems that the database is missing a table + Il semble qu'il manque une table dans le database + + + + It seems that the table is missing a column + Il semble qu'il manque une colonne au tableau + + + + The database contains an unexpected column + Le database contient une colonne inattendue + + + + A column has an unexpected data-type + Une colonne a un type de données inattendu + + + + Failed to retrieve the selected file + Impossible de récupérer le fichier sélectionné + + + + The file has probably been used already + Le fichier a probablement déjà été utilisé + + + + + The file's size exceeds the warning size + La taille du fichier dépasse la taille d'avertissement + + + + Failed to determine the log type + Impossible de déterminer le type de journal + + + + The log format has not been set, or is invalid +Please add a valid one in the configurations + Le format du journal n'a pas été défini ou n'est pas valide +Veuillez en ajouter un valide dans les configurations + + + + No log field has been set in the current logs format, +making it useless to parse logs + Aucun champ de journal n'a été défini dans le format actuel des journaux, +rendant inutile l'analyse des journaux + + + + A separator is missing between one or more fields, +making it hard to establish net bounds, +and possibly leading to store incorrect data + Un séparateur manque entre un ou plusieurs champs, +ce qui rend difficile l'établissement de limites nettes, +et pouvant conduire à stocker des données incorrectes + + + + + + Please report this issue + S'il vous plaît signaler ce problème + + + + Please remove the conflict and retry + Veuillez supprimer le conflit et réessayer + + + + + Please set the proper permissions before to start + Veuillez définir les autorisations appropriées avant de commencer + + + + + + + + Please set the proper permissions and retry +If this error persists, please report this issue + Veuillez définir les autorisations appropriées et réessayer +Si cette erreur persiste, veuillez signaler ce problème + + + + If you haven't manually edited the configuration file, +please report this issue + Si vous n'avez pas modifié manuellement le fichier de configuration, +merci de signaler ce problème + + + + Please set up a format which contains at least one field + Veuillez configurer un format qui contient au moins un champ + + + + Please set up a format which contains separators between fields + Veuillez configurer un format qui contient des séparateurs entre les champs + + + + + + + Skipping + Saut + + + + + + + + + + Aborting + Abandon + + + + Additional resources can be downloaded from the git repo + Des ressources supplémentaires peuvent être téléchargées à partir du dépôt git + + + + + + An error occured while parsing the format string + Une erreur s'est produite lors de l'analyse de la chaîne de format + + + + + Size of the file + Taille du fichier + + + + + Warning size parameter + Paramètre de taille d'avertissement + + + + + An error accured while reading the gzipped file + Une erreur s'est produite lors de la lecture du fichier gzippé + + + + + Something failed while handling the file + Quelque chose a échoué lors du traitement du fichier + + + + An error occured while working on the database + Une erreur s'est produite lors du travail sur le database + + + + An error occured while working on the database + +Aborting + Une erreur s'est produite lors du travail sur le database + +Abandon + + + + MainWindow + + + + Parse logs from the Apache2 web server + Analyser les journaux du serveur web Apache2 + + + + + Parse logs from the Nginx web server + Analyser les journaux du serveur web Nginx + + + + + Parse logs from the Microsoft IIS web server + Analyser les journaux du serveur web Microsoft IIS + + + + All + Tout + + + + Inspect a log file + Inspecter un fichier journal + + + + Name + Nom + + + + Size + Taille + + + + Refresh the list + Rafraîchir la liste + + + + Total size of the parsed data + Taille totale des données analysées + + + + Total number of parsed lines + Nombre total de lignes analysées + + + + Start parsing the selected files + Commencer à analyser les fichiers sélectionnés + + + + START + START + + + + Time elapsed since the start + Temps écoulé depuis le début + + + + Average speed, in parsed data size per second + Vitesse moyenne, en taille de données analysées par seconde + + + + + + Draw the chart + Dessinez le graphique + + + + Web Server + Web Server + + + + + + + + Select a Web Server + Sélectionnez un Web Server + + + + + + + + + + + Year + An + + + + + + + + + + + Month + Mois + + + + + + + + + + + Day + Jour + + + + Hour + Heure + + + + Update the database with current Warning States + Mettre à jour le database avec les états d'avertissement actuels + + + + Log line marked as Warning + Ligne de journal marquée comme Avertissement + + + + Date when the request arrived (YYYY-MM-DD) + Date d'arrivée de la demande (AAAA-MM-JJ) + + + + + Time when the request arrived (hh:mm:ss) + Heure d'arrivée de la demande (hh:mm:ss) + + + + + + + Protocol of the request + Protocole de la demande + + + + + + + Method of the request + Méthode de la demande + + + + + + + URI of the requested page + URL de la page demandée + + + + + + + Response code from the server + Code de résponse du serveur + + + + + IP address of the Client which made the request + Addresse IP du client qui a fait la demande + + + + Size ib Bytes of the request, usually includes header and data + Taille en Octets de la demande, comprend généralement header et données + + + + Size in Bytes of the served content, usually includes header and data + Taille en Octets du contenu servi, comprend généralement header et données + + + + Protocol: + Protocole: + + + + Method: + Méthode: + + + + Response: + Réponse: + + + + Query: + Query: + + + + URI: + URI: + + + + Filters + Filtres + + + + + + + Query carried along with the URI + Query transportée avec l'URI + + + + + Cookie used for the request + Cookie utilisé pour la requête + + + + + User-agent of the client which made the request + User-agent du client qui a fait la demande + + + + Count + Compter + + + + + The URL which redirected the Client to the requested page + L'URL qui a redirigé le Client vers la page demandée + + + + Number of occurrences + Nombre d'occurrences + + + + Item + Article + + + + Value of the field + Valeur du champ + + + + + From: + De: + + + + + To: + À: + + + + + + Field: + Champ: + + + + + + Select a log field to view + Sélectionnez un champ de journal à afficher + + + + + + Filter: + Filtre: + + + + Protocol + Protocole + + + + Method + Méthode + + + + URI + URI + + + + User-agent + User-agent + + + + Most recurrent + Le plus récurrent + + + + Date ever + Date de tous les temps + + + + Day of the week + Jour de la semaine + + + + Hour of the day + Heure du jour + + + + Most trafficked + Plus trafiqué + + + + Select/deselect all the files + Sélectionnez/désélectionnez tous les fichiers + + + + + Time taken + Temps pris + + + + + Bytes sent + Octets envoyés + + + + Bytes received + Octets reçus + + + + Mean/Max performances + Performances moyennes/maxi + + + + Requests received + Demandes reçues + + + + Total work + Travail total + + + + + General + Général + + + + General settings + Réglages généraux + + + + Window + Fenêtre + + + + + + + + + Remember window's position and size + Se souvenir de la position et de la taille de la fenêtre + + + + Geometry + Apparence + + + + + Theme to use for the window + Thème à utiliser pour la fenêtre + + + + + Theme + Thème + + + + None (System) + Aucun (Système) + + + + + Dark + Sombre + + + + Dialogs + Dialogues + + + + Candy + Bonbon + + + + Herb + Herbe + + + + Powder + Poudre + + + + Auto (Default) + Auto (Défaut) + + + + Light + Clair + + + + Dialogs level + Niveau dialogue + + + + Reduced quantity of dialog messages shown + Quantité réduite de messages de dialogue affichés + + + + Essential + Essentiel + + + + Normal quantity of dialog messages shown + Quantité normale de messages de dialogue affichés + + + + Normal + Normal + + + + Explanatory + Explicatif + + + + Logs parser + Analyseur de journaux + + + + Statistics viewer + Visualiseur de statistiques + + + + TextBrowser + TextBrowser + + + + Font to use for the Text Browser + Font à utiliser pour le Text Browser + + + + Font + Font + + + + Double-spaced lines + Lignes à double interligne + + + + Use wide lines + Utilisez des lignes larges + + + + Define the spacing between lines + Définir l'espacement entre les lignes + + + + Lines spacing + Interligne + + + + None + Aucun + + + + Color scheme to use for the Text Browser + Jeu de couleurs à utiliser pour le Text Browser + + + + Color scheme + Schéma de couleur + + + + The appearance of the Text Browser with the current settings + L'apparence du Text Browser avec les paramètres actuels + + + + + Preview + Aperçu + + + + Charts + Graphiques + + + + Default (Light) + Par défaut (lDégager) + + + + Sand + Sable + + + + Cerulean + Azuré + + + + Theme to use for the Charts + Thème à utiliser pour les Graphiques + + + + Databases + Databases + + + + + + + + Apply the current path + Appliquer le chemin actuel + + + + Path where the logs data collection database is located + Chemin où se trouve le database de collecte de données de journaux + + + + Logs data + Données de journaux + + + + + + + + The given path doen't exists, or doesn't point to a folder + Le chemin donné n'existe pas ou ne pointe pas vers un dossier + + + + Path where the used files hashes database is located + Chemin où se trouve le database de hachage des fichiers utilisés + + + + Used files + Archivos usados + + + + + Insert the base path only, file name excluded + Insérez le chemin de base uniquement, nom de fichier exclu + + + + Path for the database files + Chemin des fichiers de laìe database + + + + + + + Paths + Chemins + + + + Backup options for the Logs Data database + Options de sauvegarde pour le database de données de journaux + + + + Backups + Sauvegardes + + + + A new backup is made when closing LogDoctor after having succesfully edited the database + Une nouvelle sauvegarde est effectuée à la fermeture de LogDoctor après avoir édité avec succès le database + + + + Backup the Logs Data database and keep + Sauvegardez le database de données de journaux et conservez + + + + Logs + Journaux + + + + Logs related settings + Paramètres liés aux journaux + + + + Defaults + Défaut + + + + Default WebServer + Serveur Web par défaut + + + + Control + Control + + + + Options about the log files usage control + Options concernant le contrôle de l'utilisation des fichiers journaux + + + + Usage control + Contrôle de l'utilisation + + + + Hide already used files + Masquer les fichiers déjà utilisés + + + + Size warnings + Avertissements de taille + + + + Warn me when using files with a size exceeding: + M'avertir lors de l'utilisation de fichiers dont la taille dépasse : + + + + + + Generate a sample log line from the currently saved string, to check if it gets formatted correctly. +Any field not considered by LogDoctor will appear as 'DISCARDED' + Générez un exemple de ligne de journal à partir de la chaîne actuellement enregistrée, pour vérifier si elle est correctement formatée. +Tout champ non pris en compte par LogDoctor apparaîtra comme 'DISCARDED' + + + + CrissCross + CrissCross + + + + Play CrissCross + Jouer au CrissCross + + + + Snake + Snake + + + + Play Snake + Jouer au Snake + + + + + + + + + + + Apache2 + Apache2 + + + + + Time taken by the server to serve the content, in milliseconds + Temps mis par le serveur pour servir le contenu, en millisecondes + + + + + + + Only use lines in which the field is starting with this string + Utilisez uniquement les lignes dans lesquelles le champ commence par cette chaîne + + + + Only use lines in which the field is matching this statement. +Use '!', '=','<' or '>' to declare what to use + Utilisez uniquement les lignes dans lesquelles le champ correspond à cette instruction. +Utilisez '!', '=', '<' ou '>' pour déclarer quoi utiliser + + + + + + With strings, only the lines in which the field is starting with this string will be used. +With numbers, use '!', '=','<' or '>' to declare what to use + Avec les chaînes, seules les lignes dans lesquelles le champ commence par cette chaîne seront utilisées. +Avec des nombres, utilisez '!', '=', '<' ou '>' pour déclarer ce qu'il faut utiliser + + + + Remember the window's position and size + Rappelez-vous la position et la taille de la fenêtre + + + + Remember position and size + Rappelez-vous la position et la taille + + + + Ash + Cendre + + + + Icons + Icônes + + + + Define the quantity of dialog mesages shown + Définir la quantité de messages de dialogue affichés + + + + Augmented quantity of dialog messages shown + Quantité augmentée de messages de dialogue affichés + + + + Dialogs from the main processes + Dialogues des principaux processus + + + + Dialogs emitted when parsing logs + Boîtes de dialogue émises lors de l'analyse des journaux + + + + Dialogs emitted when viewing statistics + Dialogues émis lors de la consultation des statistiques + + + + Configure Apache2 specific options + Configurer les options spécifiques à Apache2 + + + + + + Logs folder + Dossier journaux + + + + + + Logs format string + Chaîne de format des journaux + + + + + + Format string + Chaîne de format + + + + + + Insert the format string you're using + Insérez la chaîne de format que vous utilisez + + + + + + Apply the current string + Appliquer la chaîne actuelle + + + + + + Generate sample + Générer un échantillon + + + + + + Please check the correctness of this line. +Fields marked as 'DISCARDED' got parsed correctly, but are not considered by LogDoctor + Veuillez vérifier l'exactitude de cette ligne. +Les champs marqués comme 'DISCARDED' ont été analysés correctement, mais ne sont pas pris en compte par LogDoctor + + + + + + Open an help window + Ouvrir une fenêtre d'aide + + + + + + Help + Aider + + + + + + Warnlists + Warnlists + + + + + + + + + Select a log field + Sélectionnez un champ de journal + + + + + + Use warnlist for this field + Utiliser la Liste d'Avertissement pour ce champ + + + + Add the current line to the list + Ajouter la ligne actuelle à la liste + + + + Remove the selected item from the list + Supprimer l'élément sélectionné de la liste + + + + + + + + + + + + + + + Move the selected item down + Déplacer l'élément sélectionné vers le bas + + + + + + Blacklists + Blacklists + + + + + + Use blacklist for this field + Utiliser la Liste Noire pour ce champ + + + + + + + + Add line + Ajouter une ligne + + + + + + + + Remove selection + Supprimer la sélection + + + + + + + + + + + Nginx + Nginx + + + + Configure Nginx specific options + Configurer les options spécifiques à Nginx + + + + + + + + + + + IIS + IIS + + + + + + Format + Format + + + + Configure IIS specific options + Configurer les options spécifiques à IIS + + + + Language + Langue + + + + Utilities + Utilitaires + + + + Tools + Outils + + + + Games + Jeux + + + + Check updates + Vérifier les mises à jour + + + + Perform a version-check + Effectuer une vérification de version + + + + Infos + Infos + + + + BlockNote + Bloc Notes + + + + Open a block-note like window to write temporary text + Ouvrir une fenêtre de type bloc-note pour écrire un texte temporaire + + + + + + + + + + + + + + + warnlist + warnlist + + + + + + blacklist + blacklist + + + + copy + copie + + + + copies + copies + + + + RichText + + + Select a file from the list + Sélectionnez un fichier dans la liste + + + + to inspect its content + pour inspecter son contenu + + + + Failed to read + Echec en lecture + + + + SnakeGame + + + Game Over + Game Over + + + + Your adversary fell in the water! + Votre adversaire est tombé dans l'eau! + + + + + + YOU WON! + TU AS GAGNÉ! + + + + You fell in the water! + Tu es tombé dans l'eau! + + + + + + YOU LOST! + TU AS PERDU! + + + + Your adversary ate itself! + Votre adversaire s'est mangé! + + + + Your adversary ate you! + Votre adversaire vous a mangé! + + + + You ate yourself! + Vous vous êtes mangé! + + + + You ate your adversary! + Vous avez mangé votre adversaire! + + + + You ate each other! + Vous vous êtes mangés réciproquement! + + + + MATCH IS DRAW! + CRAVATE! + + + + PLAY + JOUER + + + + Classic + Classique + + + + Hunt + Chasse + + + + Battle + Bataille + + + + TR + + + Logs Size Breakdown + Répartition de la Taille des Journaux + + + + Ignored + Ignoré + + + + Parsed + analysé + + + + Warnings + Avertissements + + + + Blacklisted + Exclu + + + + FALSE + FAUX + + + + TRUE + VRAI + + + + Log Lines Marked as Warning + Lignes Marquées comme Avertissement + + + + Time Taken to Serve Requests + Temps Pris pour Traiter les Demandes + + + + Others + Autres + + + + + Time of Day Count + Compter les Heures de la Journée + + + + + from + de + + + + + to + à + + + + Unexpected WebServer + WebServer inattendu + + + + An error occured while processing + Une erreur s'est produite lors du traitement + + + + An error occured while processing dates + Une erreur s'est produite lors du traitement des dates + + + + An error occured while parsing %1 from the database + Erreur lors du traitement de '%1' dans la database + + + + Years + Ans + + + + Months + Mois + + + + Days + Journées + + + + Value responsible for the error + Valeur responsable de l'erreur + + + + Database table name + Nom de la table de la base de données + + + + Date + Date + + + + Time + Temps + + + + Warning + Avertissement + + + + Protocol + Protocole + + + + Method + Méthode + + + + URI + URI + + + + Query + Query + + + + Response code + Code de réponse + + + + Time taken + Temps pris + + + + Bytes sent + Octets envoyés + + + + Bytes received + Octets reçus + + + + Referrer + Référent + + + + Cookie + Cookie + + + + Client + Client + + + + User-agent + User-agent + + + + January + Janvier + + + + February + Février + + + + March + Mars + + + + April + Avril + + + + May + Peut + + + + June + Juin + + + + July + Juillet + + + + August + Août + + + + September + Septembre + + + + October + Octobre + + + + November + Novembre + + + + December + Décembre + + + + Sunday + Dimanche + + + + Monday + Lundi + + + + Tuesday + Mardi + + + + Wednesday + Mercredi + + + + Thursday + Jeudi + + + + Friday + Vendredi + + + + Saturday + Samedi + + + diff --git a/logdoctor/translations/LogDoctor_it.ts b/logdoctor/translations/LogDoctor_it.ts new file mode 100644 index 00000000..5a1553a1 --- /dev/null +++ b/logdoctor/translations/LogDoctor_it.ts @@ -0,0 +1,1747 @@ + + + + + Crapinfo + + Version + Versione + + + Repository links + Links del repository + + + Currently installed version of the software + Versione del software attualmente installata + + + Paths + Percorsi + + + The path of the executable file + Il percorso del file eseguibile + + + Executable + Eseguibile + + + The path where the configuration file gets saved and searched in + Il percorso in cui il file di configurazione viene salvato e cercato + + + Configuration file + File di configurazione + + + The path where the application searches for extra resources + Il percorso in cui l'applicazione cerca le risorse extra + + + Application data + Risorse applicazione + + + + Crapnote + + Reduce the font size + Riduci la dimensione dei caratteri + + + Font size + Dimensione dei caratteri + + + Increase the font size + Aumenta la dimensione dei caratteri + + + + Crapup + + Checking for updates + Controllo degli aggiornamenti + + + Failed to establish a connection + Fallimento nello stabilire una connessione + + + Connection error, please try again later + Errore di connessione, per favore riprova più tardi + + + Connection timed out + Connessione scaduta + + + New version available + Nuova versione disponibile + + + No update found + Nessun aggiornamento disponibile + + + LogDoctor is up-to-date + LogDoctor è aggiornato + + + :/ + :/ + + + You're running a version from the future! +Your version is beyond the current upstream version +Are you running the original LogDoctor? +Please visit the LogDoctor's repository and get a fresh version of it + Stai usando una versione proveniente dal futuro! +La tua versione è maggiore di quella online +Sei sicuro di avere la versione originale di LogDoctor? +È consigliato visitare il repository di LogDoctor e scaricalo di nuovo + + + Version check failed + Controllo della versione fallito + + + An error occured while parsing: +initial version mark not found + È avvenuto un errore durante l'analisi: +marcatore iniziale non trovato + + + An error occured while parsing: +final version mark not found + È avvenuto un errore durante l'analisi: +marcatore finale non trovato + + + An error occured while parsing: +malformed version + È avvenuto un errore durante l'analisi: +versione malformata + + + An error occured while comparing: +malformed upstream version + È avvenuto un errore durante la comparazione: +versione upstream malformata + + + A new version is available! +Please visit LogDoctor's git repository and follow the instruction about how to update + È disponibile una nuova versione! +Visita il repository di LogDoctor e segui le istruzioni su come aggiornare + + + + CrissCross + + You beated me! + Mi hai battuto! + + + This time you lost! + Stavolta hai perso! + + + Victory + Vittoria + + + Draw + Pareggio + + + Nice match + Bella partita + + + + DialogBool + + Yes + + + + No + No + + + + DialogDia + + Ignore + Ignora + + + Discard + Scarta + + + Abort + Annulla + + + + DialogMsg + + Ok + Ok + + + + DialogSec + + An error occured while reading the configuration file + Errore durante la lettura del file di configurazione + + + An error occured while parsing configuration file's data + Errore durante l'analisi del file di configurazione + + + Failed to create the configuration file's directory + Creazione della cartella del file di configurazione non riuscita + + + An error occured while writing the configuration file + Errore durante la scrittura del file di configurazione + + + An error occured while preparing the configuration file's data + Errore durante la preparazione dei dati per il file di configurazione + + + Failed to create the database backups' directory + Creazione della cartella per i backups del database non riuscita + + + Failed to copy the database file + Fallimento nel copiare il database + + + Failed to update the backups + Fallimento nell'aggiornare i backups + + + unrecognized entry + input non riconosciuto + + + Failed to read gzipped file + Lettura del file gzip non riuscita + + + Discard it and continue, or Abort all and exit? + Scartarlo e continuare, o Annullare tutto e terminare? + + + Create a new database? + Creare un nuovo database? + + + This database will renamed with a trailing '.copy' and a new one will be created. +Continue? + L'attuale database verrà rinominato con estensione '.copy' e ne verrà creato uno nuovo. +Continuare? + + + The entry will renamed with a trailing '.copy' and a new one will be created. +Continue? + La risorsa attuale verrà rinominata con estensione '.copy' e ne verrà creata una nuova. +Continuare? + + + An error occured + È avvenuto un errore + + + Failed renaming + Rinominazione fallita + + + Invalid locale + Lingua non valida + + + Configuration file not found + File di configurazione non trovato + + + Failed to retrieve the help file + Fallimento nel reperire il file di aiuto + + + Not a file + Non è un file + + + File not found + File non trovato + + + File not readable + File non leggibile + + + File not writable + File non scrivibile + + + File is empty + Il file è vuoto + + + Failed reading + Lettura fallita + + + Not a folder + Non è una cartella + + + Directory not found + Cartella non trovata + + + Directory not readable + Cartella non leggibile + + + Directory not writable + Cartella non scrivibile + + + Failed creating directory + Creazione cartella fallita + + + QSql driver not found + Driver QSql non trovato + + + Database created + Database creato + + + Failed creating database + Creazione database fallita + + + Failed opening database + Apertura database fallita + + + Failed executing on database + Esecuzione sul database fallita + + + Unexpected table + Tabella inaspettata + + + Table not found + Tabella non trovata + + + Unexpected column + Colonna inaspettata + + + Column not found + Colonna non trovata + + + Unexpected data-type + Tipo di dato inaspettato + + + Failed to backup database + Backup del database fallito + + + Failed defining type + Fallimento nella definizione del tipo + + + Log format error + Errore del formato di log + + + Misconfigured log format + Formato di log malconfigurato + + + Invalid log format string + Stringa del formato di log non valida + + + File already used + File già usato + + + File exceeds warning size + Dimensione del file eccessiva + + + An error occured while renaming + Errore nel rinominare + + + Unexpected locale format + Formato della lingua inaspettato + + + The given locale is not an accepted language + La lingua fornita non è tra quelle accettate + + + An error occured while handling the configuration file + Errore nel maneggiare il file di confgurazione + + + Unable to retrieve the configuration file + Fallimento nel reperire il file di configurazione + + + Current configuration not saved + Configurazione attuale non salvata + + + An error occured while getting the help file + Errore nel recuperare il file di aiuto + + + The path was supposed to point to a file, but it doesn't + Il percorso dovrebbe puntare ad un file, ma non è così + + + Unable to retrieve the file + Fallimeno nel recuperare il file + + + The file is not readable + Il file non è leggibile + + + The file is not writable + Il ile non è scrivibile + + + The file is blank + Il file è vuoto + + + An error accured while reading the file + Errore nella lettura del file + + + The path was supposed to point to a folder, but it doesn't + Il percorso dovrebbe puntare ad una cartella, ma non è così + + + The directory does not exists + La cartella non esiste + + + The directory is not readable + La cartella non è leggibile + + + The directory is not writable + La cartella non è scrivibile + + + Failed to retrieve the driver neede to handle the database + Fallimento nel reperire il driver necessario per maneggiare il database + + + Failed to retrieve the database file + Fallimento nel reperire il database + + + The database file is not readable + Il database non è leggibile + + + The database file is not writable + Il database non è scrivibile + + + Successfully created a new database + Database creato con successo + + + An error occured while creating the database + Errore nella creazione del database + + + An error occured while opening the database + Errore nell'apertura del database + + + An error occured while executing a statement on the database + Errore nell'eseguire un comando sul database + + + The database contains an unexpected table + Il database contiene una tabella inaspettata + + + It seems that the database is missing a table + Sembra che al database manchi una tabella + + + It seems that the table is missing a column + Sembra che alla tabella manchi una colonna + + + The database contains an unexpected column + Il database contiene una colonna inaspettata + + + A column has an unexpected data-type + Una colonna ha un tipo di dato inaspettato + + + Failed to retrieve the selected file + Fallimento nel recuperare il file selezionato + + + The file has probably been used already + Probabilmente il file è già stato usato + + + The file's size exceeds the warning size + La dimensione del file eccede quella di sicurezza + + + Failed to determine the log type + Fallimento nel determinare il tipo di log + + + The log format has not been set, or is invalid +Please add a valid one in the configurations + Il formato di log non è stato impostato, o è errato. +Per favore aggiungine uno valido nelle impostazioni + + + No log field has been set in the current logs format, +making it useless to parse logs + Nessun campo di log è stato impostato nel formato di log corrente, +rendendo inutile analizzare dei file + + + A separator is missing between one or more fields, +making it hard to establish net bounds, +and possibly leading to store incorrect data + Manca un separatore tra uno o più campi di log, +ciò rende difficile stabilire dei confini netti +e può portare ad avere dati incorretti + + + Please report this issue + Per favore segnala questo problema + + + Please remove the conflict and retry + Per favore rimuovi il conflitto e riprova + + + Please set the proper permissions before to start + Per favore imposta i dovuti permessi prima di cominciare + + + Please set the proper permissions and retry +If this error persists, please report this issue + Imposta i dovuti permessi e riprova +Se l'errore persiste, per favore segnala questo problema + + + If you haven't manually edited the configuration file, +please report this issue + Se non hai modificato manualmente il file di configurazione, +per favore segnala questo problema + + + Please set up a format which contains at least one field + Per favore imposta un formato che contenga almeno un campo + + + Please set up a format which contains separators between fields + Per favore imposta un formato che contenga un separatore tra ogni campo + + + Skipping + Saltato + + + Aborting + Annullato + + + Additional resources can be downloaded from the git repo + Le risorse extra possono essere scaricate dal repository + + + An error occured while parsing the format string + Errore durante l'analisi della stringa + + + Size of the file + Dimensione del file + + + Warning size parameter + Dimensione di sicurezza + + + An error accured while reading the gzipped file + Errore durante la lettura del file gzip + + + Something failed while handling the file + Qualcosa è andato storto nel maneggiare il file + + + An error occured while working on the database + Errore durante il lavoro sul database + + + An error occured while working on the database + +Aborting + Errore durante il lavoro sul database + +Annullato + + + One of the lists has an invalid item + Una delle liste contiene un elemento non valido + + + Failed to write the configuration file + Scrittura del file di configurazione non riuscita + + + Failed applying configuration + Fallimento nell'applicare la configurazione + + + Invalid string + Stringa non valida + + + The given string is invalid and cannot be added to the list + +Please correct it and retry + La stringa fornita non è valida e non può essere aggiunta alla lista + +Correggila e poi riprova + + + Please check that no error is thrown by your WebServer +If it gets accepted, please check the presence of a typo here +If everything is fine, please report this issue + Controlla che il tuo web server non dia errori +Se la accetta, controlla la presenza di un errore nel riportarla qui +Se tutto è corretto, per favore segnala questo errore + + + An error occured while parsing logs + Errore durante l'analisi dei log + + + Ignore the warning and use it anyway, Discard it and continue, or Abort the entire process? + Ignorare l'avvertimento e usarlo comunque, Scartarlo e continuare, o Annullare l'intero processo? + + + Proceed anyway? + Continuare comunque? + + + If you'd like to have this locale in LogDoctor, +please follow the instruction on the repository page + Se desideri avere questa lingua in LogDoctor, +per favore segui le istruzioni nella pagina del repository + + + Failed to create the directory + Creazione della cartella non riuscita + + + + MainWindow + + Parse logs from the Apache2 web server + Esamina i log del web server Apache2 + + + Parse logs from the Nginx web server + Esamina i log del web server Nginx + + + Parse logs from the Microsoft IIS web server + Esamina i log del web server Microsoft IIS + + + All + Tutti + + + Inspect a log file + Ispeziona un file di log + + + Name + Nome + + + Size + Dimensione + + + Refresh the list + Ricarica la lista + + + Total size of the parsed data + Dimensione totale analizzata + + + Total number of parsed lines + Numero di linee analizzate + + + Start parsing the selected files + Inizia l'analisi dei file selezionati + + + START + START + + + Time elapsed since the start + Tempo trascorso + + + Average speed, in parsed data size per second + Velocità media, in dimensione analizzata per secondo + + + Draw the chart + Crea il grafico + + + Web Server + Web Server + + + Select a Web Server + Seleziona un Web Server + + + Year + Anno + + + Month + Mese + + + Day + Giorno + + + Hour + Ora + + + Update the database with current Warning States + Aggiorna il database con gli Avvertimenti correnti + + + Log line marked as Warning + Linee di log marcate come Avvertimento + + + Date when the request arrived (YYYY-MM-DD) + Data di ricezione della richiesta (AAAA-MM-GG) + + + Time when the request arrived (hh:mm:ss) + Ora di ricezione della richiesta (oo:mm:ss) + + + Protocol of the request + Protocollo della richiesta + + + Method of the request + Metodo della richiesta + + + URI of the requested page + URI della pagina richiesta + + + Response code from the server + Codice di risposta dal server + + + IP address of the Client which made the request + Indirizzo IP del Cliente che ha effettuato la richiesta + + + Size ib Bytes of the request, usually includes header and data + Dimensione in Bytes della richiesta, solitamente include sia header che dati + + + Size in Bytes of the served content, usually includes header and data + Dimensione in Bytes del contenuto servito, solitamente include si aheader che dati + + + Protocol: + Protocollo: + + + Method: + Metodo: + + + Response: + Status code: + + + Query: + Query: + + + URI: + URI: + + + Filters + Filtri + + + Query carried along with the URI + Query congiunta alla pagina richiesta + + + Cookie used for the request + Cookie usato per la richiesta + + + User-agent of the client which made the request + User-agent del cliente che ha effettuato la richiesta + + + Count + Conteggio + + + Number of occurrences + Numero di ricorrenze + + + Item + Oggetto + + + Value of the field + Valore del campo + + + From: + Da: + + + To: + A: + + + Field: + Campo: + + + Select a log field to view + Seleziona un campo da visualizzare + + + Filter: + Filtro: + + + Protocol + Protocollo + + + Method + Metodo + + + URI + URI + + + User-agent + User-agent + + + Most recurrent + Più ricorrenti + + + Date ever + Data di sempre + + + Day of the week + Giorno della settimana + + + Hour of the day + Ora del giorno + + + Most trafficked + Più trafficati + + + Time taken + Tempo impiegato + + + Bytes sent + Bytes inviati + + + Bytes received + Bytes ricevuti + + + Mean/Max performances + Performance media/massima + + + Requests received + Richieste ricevute + + + Total work + Lavoro totale + + + General + Generale + + + General settings + Impostazioni generali + + + Window + Finestra + + + Remember window's position and size + Ricorda posizione e dimensione della finestra + + + Geometry + Forma + + + Theme to use for the window + Tema da usare per la finestra + + + Theme + Tema + + + None (System) + Nessuno (Sistema) + + + Dark + Scuro + + + Dialogs + Dialoghi + + + Dialogs level + Livello di dialogo + + + Reduced quantity of dialog messages shown + Quantità ridotta di finestre di dialogo + + + Essential + Essenziale + + + Normal quantity of dialog messages shown + Quantità normale di finestre di dialogo + + + Normal + Normale + + + Explanatory + Esplicativo + + + Logs parser + Analisi dei log + + + Statistics viewer + Visualizzazione statistiche + + + TextBrowser + TextBrowser + + + + Font to use for the Text Browser + Font da usare per il TextBrowser + + + Font + Font + + + Double-spaced lines + Doppio spazio tra le linee + + + Use wide lines + Usa linee larghe + + + Define the spacing between lines + Definisci lo spazio tra le linee + + + Lines spacing + Spazio tra le linee + + + None + Nessuno + + + Color scheme to use for the Text Browser + Schema di colori da usare per il TextBrowser + + + Color scheme + Schema di colori + + + The appearance of the Text Browser with the current settings + L'aspetto del TextBrowser con i settaggi attuali + + + Preview + Anteprima + + + Charts + Grafici + + + Default (Light) + Predefinito (Chiaro) + + + Sand + Sabbia + + + Cerulean + Ceruleo + + + Theme to use for the Charts + Tema da usare per i Grafici + + + Databases + Databases + + + Apply the current path + Applica il percorso corrente + + + Path where the logs data collection database is located + Percorso in cui è localizzato il database per i dati di log + + + Logs data + Dati di log + + + The given path doen't exists, or doesn't point to a folder + Il percorso fornito non esiste, o non punta ad una cartella + + + Path where the used files hashes database is located + Percorso in cui è localizzato il database per gli hash dei file usati + + + Used files + Files usati + + + Insert the base path only, file name excluded + Inserisci solo il percorso di base, senza il nome del file + + + Path for the database files + Percorso per i databases + + + Paths + Percorsi + + + Backup options for the Logs Data database + Opzioni di backup per il database dei Dati di Log + + + Backups + Backups + + + A new backup is made when closing LogDoctor after having succesfully edited the database + Viene effettuato un nuovo backup ogni volta che chiudi LogDoctor e sono state fatte modifiche al database + + + Backup the Logs Data database and keep + Fai un Backup del database e mantieni + + + Logs + Logs + + + Logs related settings + Impostazioni relative ai logs + + + Defaults + Predefiniti + + + Default WebServer + WebServer predefinito + + + Control + Controllo + + + Options about the log files usage control + Opzioni riguardo l'uso dei files di log + + + Usage control + Controllo dell'utilizzo + + + Hide already used files + Nascondi i files già usati + + + Size warnings + Avvertimenti sulla dimensione + + + Warn me when using files with a size exceeding: + Avvertimi prima di utilizzare un file di dimensioni superiori a: + + + Apache2 + Apache2 + + + Configure Apache2 specific options + Configura le opzioni specifiche per Apache2 + + + Logs folder + Cartella dei logs + + + Logs format string + Stringa di formato dei logs + + + Format string + Stringa di formato + + + Insert the format string you're using + Inserisci la stringa di formato che utilizzi + + + Apply the current string + Applica la stringa corrente + + + Generate sample + Genera esempio + + + Please check the correctness of this line. +Fields marked as 'DISCARDED' got parsed correctly, but are not considered by LogDoctor + Per favore controlla la correttezza di questa linea. +I campi marcati come 'DISCARDED' sono stati applicati correttamente, ma non vengono considerati da LogDoctor + + + Open an help window + Apri una finestra di aiuto + + + Help + Aiuto + + + Warnlists + Warnlists + + + Select a log field + Seleziona un campo di log + + + Use warnlist for this field + Usa la lista per questo campo + + + Add the current line to the list + Aggiungi la linea corrente alla lista + + + Remove the selected item from the list + Rimuovi l'elemento selezionato dalla lista + + + Move the selected item down + Sposta in basso l'elemento selezionato + + + Blacklists + Blacklists + + + Use blacklist for this field + Usa la lista per questo campo + + + Add line + Aggiungi linea + + + Remove selection + Rimuovi selezione + + + Nginx + Nginx + + + Configure Nginx specific options + Configura le opzioni specifiche per Nginx + + + IIS + IIS + + + Configure IIS specific options + Configura le opzioni specifiche per IIS + + + Language + Lingua + + + Utilities + Utilità + + + Tools + Attrezzi + + + Check updates + Controlla aggiornamenti + + + Perform a version-check + Effettua un controllo della versione + + + Infos + Informazioni + + + BlockNote + BloccoNote + + + Open a block-note like window to write temporary text + Apri una finestra in stile blocco note per scrivere del testo temporaneo + + + copy + copia + + + copies + copie + + + Time taken by the server to serve the content, in milliseconds + Tempo impiegato dal server per servire i contenuti, in millisecondi + + + Only use lines in which the field is starting with this string + Usa solo le linee in cui il campo comincia con questa stringa + + + Only use lines in which the field is matching this statement. +Use '!', '=','<' or '>' to declare what to use + Usa solo le linee in cui il campo combacia con questo criterio. +Usa '!', '=','<' or '>' per dichiarare cosa usare + + + With strings, only the lines in which the field is starting with this string will be used. +With numbers, use '!', '=','<' or '>' to declare what to use + Per le stringhe, solo le linee in cui il campo comincia con questa stringa verranno usate. +Per i numeri, usa '!', '=','<' or '>' per dichiarare cosa usare + + + The URL which redirected the Client to the requested page + L'URL da cui è stato redirezionato il Cliente verso la pagina richiesta + + + Remember the window's position and size + Ricorda la posizione e le dimensioni della finestra + + + Remember position and size + Ricorda posizione e dimensioni + + + Define the quantity of dialog mesages shown + Definisci la quantità di finestre di dialogo visualizzate + + + Augmented quantity of dialog messages shown + Quantità aumentata di finestre di dialogo + + + Dialogs from the main processes + Dialoghi derivanti dai processi principali + + + Dialogs emitted when parsing logs + Dialoghi emessi durante l'analisi dei log + + + Dialogs emitted when viewing statistics + Dialoghi emessi durante la visualizzazione delle satistiche + + + Format + Formato + + + Select/deselect all the files + Seleziona/deseleziona tutti i files + + + Candy + Caramella + + + Herb + Erba + + + Powder + Polvere + + + warnlist + warnlist + + + blacklist + blacklist + + + Ash + Cenere + + + Games + Giochi + + + CrissCross + Tris + + + Play CrissCross + Gioca a Tris + + + Snake + Snake + + + Play Snake + Gioca a Snake + + + Auto (Default) + Auto (Default) + + + Light + Chiaro + + + Generate a sample log line from the currently saved string, to check if it gets formatted correctly. +Any field not considered by LogDoctor will appear as 'DISCARDED' + Genera una linea di log dalla stringa salvata, come esempio per controllare che sia stata applicata correttamente. +I campi non considerati da LogDocrot appariranno come 'DISCARDED' + + + Icons + Icone + + + + RichText + + Select a file from the list + Seleziona un file dalla lista + + + to inspect its content + per ispezionarne il contenuto + + + Failed to read + Lettura fallita + + + + SnakeGame + + Game Over + Game Over + + + Your adversary fell in the water! + Il tuo avversario è caduto nell'acqua! + + + You fell in the water! + Sei caduto nell'acqua! + + + YOU LOST! + HAI PERSO! + + + You ate yourself! + Ti sei mangiato da solo! + + + You ate your adversary! + Hai mangiato il tuo avversario! + + + You ate each other! + Vi siete mangiati a vicenda! + + + MATCH IS DRAW! + PAREGGIO! + + + Your adversary ate itself! + Il tuo avversario si è mangiato da solo! + + + Your adversary ate you! + Il tuo avversario ti ha mangiato! + + + PLAY + GIOCA + + + Classic + Classico + + + Hunt + Caccia + + + Battle + Battaglia + + + YOU WON! + HAI VINTO! + + + + TR + + Logs Size Breakdown + Ripartizione Dimensioni Logs + + + Ignored + Ignorati + + + Parsed + Analizzati + + + Warnings + Avvertimenti + + + Blacklisted + Esclusi + + + FALSE + FALSO + + + TRUE + VERO + + + Log Lines Marked as Warning + Linee di Log Marcate come Avvertimento + + + Time Taken to Serve Requests + Tempo Impiegato per Servire le Richieste + + + Others + Altri + + + Time of Day Count + Conteggio dei Momenti del Giorno + + + from + da + + + to + a + + + Unexpected WebServer + WebServer inaspettato + + + An error occured while processing + È avvenuto un errore nel processare + + + An error occured while processing dates + È avvenuto un errore nel processare le date + + + An error occured while parsing %1 from the database + È avvenuto un errore nel processare '%1' dal database + + + Years + Anni + + + Months + Mesi + + + Days + Giorni + + + Value responsible for the error + Valore responsabile per l'errore + + + Database table name + Nome della tabella del database + + + Date + Data + + + Time + Ora + + + Warning + Attenzione + + + Protocol + Protocollo + + + Method + Metodo + + + URI + URI + + + Query + Query + + + Response code + Status code + + + Time taken + Tempo impiegato + + + Bytes sent + Bytes inviati + + + Bytes received + Bytes ricevuti + + + Referrer + Referente + + + Cookie + Cookie + + + Client + Visitatore + + + User-agent + User-agent + + + January + Gennaio + + + February + Febbraio + + + March + Marzo + + + April + Aprile + + + May + Maggio + + + June + Giugno + + + July + Luglio + + + August + Agosto + + + September + Settembre + + + October + Ottobre + + + November + Novembre + + + December + Dicembre + + + Sunday + Domenica + + + Monday + Lunedì + + + Tuesday + Martedì + + + Wednesday + Mercoledì + + + Thursday + Giovedì + + + Friday + Venerdì + + + Saturday + Sabato + + + diff --git a/logdoctor/utilities/checks.cpp b/logdoctor/utilities/checks.cpp new file mode 100644 index 00000000..d40e9fd1 --- /dev/null +++ b/logdoctor/utilities/checks.cpp @@ -0,0 +1,502 @@ + +#include "checks.h" + +#include "modules/dialogs.h" + +#include "utilities/io.h" + +#include +#include +#include + +#include + + +CheckSec::CheckSec() +{ + +} + +int CheckSec::checkDatabaseTablesNames( QSqlDatabase& db, const QString& db_name ) +{ + bool make_new=false, ok=true; + QSqlQuery query = QSqlQuery( db ); + if ( ! query.exec("SELECT name FROM sqlite_schema WHERE type = 'table';") ) { + // error querying database + ok = false; + DialogSec::errDatabaseFailedExecuting( db_name, query.lastQuery(), query.lastError().text() ); + } else { + std::unordered_map tables_checks = { + {"apache", false}, + {"nginx", false}, + {"iis", false} }; + while ( query.next() ) { + QString table_name = query.value(0).toString(); + if ( tables_checks.find( table_name ) == tables_checks.end() ) { + // unexpected table name + if ( DialogSec::choiceDatabaseWrongTable( db_name, table_name ) ) { + // agreed to renew + make_new = true; + } else { + // refused to renew + ok = false; + } + break; + + } else { + // table found + tables_checks.at( table_name ) = true; + } + } + if ( ok && !make_new ) { + for ( const auto& [ tbl, res ] : tables_checks ) { + if ( ! res ) { + // a table has not been found + if ( DialogSec::choiceDatabaseMissingTable( db_name, tbl ) ) { + // agreed to renew + make_new = true; + } else { + // refused to renew + ok = false; + } + break; + } + } + } + tables_checks.clear(); + } + query.finish(); + if ( ok ) { + if ( make_new ) { + return 2; + } else { + return 1; + } + } else { + return 0; + } +} + +bool CheckSec::newCollectionDatabase( QSqlDatabase& db, const QString& db_name, const std::vector& ws_names ) +{ + bool successful = true; + // create the database + if ( ! db.open() ) { + // error opening database + successful = false; + DialogSec::errDatabaseFailedOpening( db_name, db.lastError().text() ); + + } else { + // succesfully creted database file, now create the tables + QSqlQuery query; + for ( const QString& ws_name : ws_names ) { + if ( ! successful ) { break; } + // compose the statement with the table name for the access logs + query.prepare( "\ + CREATE TABLE \""+ws_name+"\" (\ + \"warning\" BOOLEAN,\ + \"year\" SMALLINT,\ + \"month\" TINYINT,\ + \"day\" TINYINT,\ + \"hour\" TINYINT,\ + \"minute\" TINYINT,\ + \"second\" TINYINT,\ + \"protocol\" TEXT,\ + \"method\" TEXT,\ + \"uri\" TEXT,\ + \"query\" TEXT,\ + \"response\" SMALLINT,\ + \"time_taken\" INTEGER,\ + \"bytes_sent\" INTEGER,\ + \"bytes_received\" INTEGER,\ + \"client\" TEXT,\ + \"user_agent\" TEXT,\ + \"cookie\" TEXT,\ + \"referrer\" TEXT\ + );"); + if ( ! query.exec() ) { + // error creating table + successful = false; + DialogSec::errDatabaseFailedExecuting( + QString( db_name ), + QString("CREATE TABLE \"%1\" (...)").arg( ws_name ), + QString( query.lastError().text() ) ); + + } + query.finish(); + } + + // inform about creation + if ( successful ) { + DialogSec::msgDatabaseCreated( db_name ); + } else { + DialogSec::errDatabaseFailedCreating( db_name ); + } + } + return successful; +} + +bool CheckSec::checkCollectionDatabase( const std::string& db_path ) +{ + bool make_new=false, ok=true; + std::error_code err; + QString err_msg = ""; + const QString db_name = QString::fromStdString( db_path.substr( db_path.find_last_of( '/' ) + 1 ) ); + const std::vector ws_names = { "apache", "nginx", "iis" }; + + QSqlDatabase db; + if ( QSqlDatabase::contains("qt_sql_default_connection") ) { + db = QSqlDatabase::database("qt_sql_default_connection"); + } else { + db = QSqlDatabase::addDatabase("QSQLITE"); + } + db.setDatabaseName( QString::fromStdString( db_path ) ); + + // check the existence + if ( IOutils::exists( db_path ) ) { + // database file exists + if ( ! IOutils::isFile( db_path ) ) { + // path doesn't point to a file + DialogSec::errDatabaseNotFile( QString(db_name) ); + ok = false; + } else if ( ! IOutils::checkFile( db_path, true ) ) { + // database not readable, abort + DialogSec::errDatabaseNotReadable( QString(db_name) ); + ok = false; + } else if ( ! IOutils::checkFile( db_path, false, true ) ) { + // database not writable, abort + DialogSec::errDatabaseNotWritable( QString(db_name) ); + ok = false; + + } else { + // database file has read and write permissions, now try to open + if ( ! db.open() ) { + // error opening database + ok = false; + DialogSec::errDatabaseFailedOpening( db_name, db.lastError().text() ); + + } else { + // database successfully opened, now check the tables + int check = CheckSec::checkDatabaseTablesNames( db, db_name ); + if ( check == 0 ) { + ok = false; + } else if ( check == 2 ) { + make_new = true; + } + QSqlQuery query = QSqlQuery( db ); + if ( ok && !make_new ) { + + // check every WebServer table, both access and error + for ( const QString& table : ws_names ) { + + if ( !ok || make_new ) { break; } + // column's name:type associations + std::unordered_map> + data_types = { + {"warning", { "BOOLEAN", false} }, + {"year", { "SMALLINT", false} }, + {"month", { "TINYINT", false} }, + {"day", { "TINYINT", false} }, + {"hour", { "TINYINT", false} }, + {"minute", { "TINYINT", false} }, + {"second", { "TINYINT", false} }, + {"protocol", { "TEXT", false} }, + {"method", { "TEXT", false} }, + {"uri", { "TEXT", false} }, + {"query", { "TEXT", false} }, + {"response", { "SMALLINT", false} }, + {"time_taken", { "INTEGER", false} }, + {"bytes_sent", { "INTEGER", false} }, + {"bytes_received", { "INTEGER", false} }, + {"client", { "TEXT", false} }, + {"user_agent", { "TEXT", false} }, + {"cookie", { "TEXT", false} }, + {"referrer", { "TEXT", false} } + }; + + // query table's columns' infoes for access logs + if ( ! query.exec( "SELECT name, type FROM pragma_table_info('"+table+"') AS tbinfo;" ) ) { + // error opening database + ok = false; + DialogSec::errDatabaseFailedExecuting( db_name, query.lastQuery(), query.lastError().text() ); + } + // iterate over results + while ( query.next() ) { + QString col_name = query.value(0).toString(), + col_type = query.value(1).toString(); + if ( data_types.find( col_name ) == data_types.end() ) { + // unexpected column + if ( DialogSec::choiceDatabaseWrongColumn( db_name, table, col_name ) ) { + // agreed to renew + make_new = true; + } else { + // refused to renew + ok = false; + } + break; + + } else { + // column found, check the data-type + QString data_type = std::get<0>(data_types.at( col_name ) ); + if ( col_type == data_type ) { + // same data-type + data_types.at( col_name ) = std::tuple( data_type, true ); + } else { + // different data-type, ask to renew + if ( DialogSec::choiceDatabaseWrongDataType( db_name, table, col_name, col_type ) ) { + // agreed to renew + make_new = true; + } else { + // refused to renew + ok = false; + } + break; + } + } + } + if ( ok && !make_new ) { + for ( const auto& [ col, tup ] : data_types ) { + if ( ! std::get<1>( tup ) ) { + // a table has not been found + if ( DialogSec::choiceDatabaseMissingColumn( db_name, table, col ) ) { + // agreed to renew + make_new = true; + } else { + // refused to renew + ok = false; + } + break; + } + } + } + + query.finish(); + if ( !ok || make_new ) { break; } + } + } + } + } + + } else { + // database does not exist, yet, ask to create a new one + if ( DialogSec::choiceDatabaseNotFound( QString(db_name) ) ) { + // choosed to create it + make_new = true; + + } else { + // refused to create it, abort + ok = false; + } + } + + if ( ok && make_new ) { + // rename the current db file as a 'copy' + if ( IOutils::exists( db_path ) ) { + // a database already exists, try rename it + if ( ! IOutils::renameAsCopy( db_path, err ) ) { + // failed to rename + ok = false; + if ( err.value() ) { + err_msg = QString::fromStdString( err.message() ); + } + DialogSec::errRenaming( QString::fromStdString(db_path), err_msg ); + }/* else { + // renamed successfully, make new one + }*/ + } + if ( ok ) { + ok = CheckSec::newCollectionDatabase( db, db_name, ws_names ); + } + } + + db.close(); + return ok; +} + + + +bool CheckSec::newHashesDatabase( QSqlDatabase& db, const QString& db_name, const std::vector& ws_names ) +{ + bool successful = true; + // create the database + if ( ! db.open() ) { + // error opening database + successful = false; + DialogSec::errDatabaseFailedOpening( db_name, db.lastError().text() ); + + } else { + // succesfully creted database file, now create the tables + QSqlQuery query; + for ( const QString& ws_name : ws_names ) { + if ( ! successful ) { break; } + // compose the statement with the table name for the access logs + query.prepare( "\ + CREATE TABLE \""+ws_name+"\" (\ + \"hash\" TEXT\ + );"); + if ( ! query.exec() ) { + // error creating table + successful = false; + DialogSec::errDatabaseFailedExecuting( + QString( db_name ), + QString("CREATE TABLE \"%1\" (...)").arg( ws_name ), + QString( query.lastError().text() ) ); + + } + query.finish(); + } + + // inform about creation + if ( successful ) { + DialogSec::msgDatabaseCreated( db_name ); + } else { + DialogSec::errDatabaseFailedCreating( db_name ); + } + } + return successful; +} + +bool CheckSec::checkHashesDatabase( const std::string& db_path ) +{ + bool make_new=false, ok=true; + std::error_code err; + QString err_msg = ""; + const QString db_name = QString::fromStdString( db_path.substr( db_path.find_last_of( '/' ) + 1 ) ); + const std::vector ws_names = { "apache", "nginx", "iis" }; + + QSqlDatabase db; + if ( QSqlDatabase::contains("qt_sql_default_connection") ) { + db = QSqlDatabase::database("qt_sql_default_connection"); + } else { + db = QSqlDatabase::addDatabase("QSQLITE"); + } + db.setDatabaseName( QString::fromStdString( db_path ) ); + + // check the existence + if ( IOutils::exists( db_path ) ) { + // database file exists + if ( ! IOutils::isFile( db_path ) ) { + // path doesn't point to a file + DialogSec::errDatabaseNotFile( QString(db_name) ); + ok = false; + } else if ( ! IOutils::checkFile( db_path, true ) ) { + // database not readable, abort + DialogSec::errDatabaseNotReadable( QString(db_name) ); + ok = false; + } else if ( ! IOutils::checkFile( db_path, false, true ) ) { + // database not writable, abort + DialogSec::errDatabaseNotWritable( QString(db_name) ); + ok = false; + + } else { + // database file has read and write permissions, now try to open + if ( ! db.open() ) { + // error opening database + ok = false; + DialogSec::errDatabaseFailedOpening( db_name, db.lastError().text() ); + + } else { + // database successfully opened, now check the tables + int check = CheckSec::checkDatabaseTablesNames( db, db_name ); + if ( check == 0 ) { + ok = false; + } else if ( check == 2 ) { + make_new = true; + } + QSqlQuery query = QSqlQuery( db ); + if ( ok && !make_new ) { + + // check every WebServer table, both access and error + for ( const QString& table : ws_names ) { + + if ( !ok || make_new ) { break; } + // column's name:type associations + bool name_ok = false, + type_ok = false; + + // query table's columns' infoes for access logs + if ( ! query.exec( "SELECT name, type FROM pragma_table_info('"+table+"') AS tbinfo;" ) ) { + // error opening database + ok = false; + DialogSec::errDatabaseFailedExecuting( db_name, query.lastQuery(), query.lastError().text() ); + } + // iterate over results + while ( query.next() ) { + QString col_name = query.value(0).toString(), + col_type = query.value(1).toString(); + if ( col_name != "hash" ) { + // unexpected column + if ( DialogSec::choiceDatabaseWrongColumn( db_name, table, col_name ) ) { + // agreed to renew + make_new = true; + } else { + // refused to renew + ok = false; + } + break; + + } else { + // column found, check the data-type + name_ok = true; + if ( col_type == "TEXT" ) { + // same data-type + type_ok = true; + } else { + // different data-type, ask to renew + if ( DialogSec::choiceDatabaseWrongDataType( db_name, table, col_name, col_type ) ) { + // agreed to renew + make_new = true; + } else { + // refused to renew + ok = false; + } + break; + } + } + } + if ( ok && !make_new ) { + if ( !name_ok || !type_ok ) { + ok = false; + } + } + query.finish(); + } + } + } + } + + } else { + // database does not exist, yet, ask to create a new one + if ( DialogSec::choiceDatabaseNotFound( QString(db_name) ) ) { + // choosed to create it + make_new = true; + + } else { + // refused to create it, abort + ok = false; + } + } + + if ( ok && make_new ) { + // rename the current db file as a 'copy' + if ( IOutils::exists( db_path ) ) { + // a database already exists, try rename it + if ( ! IOutils::renameAsCopy( db_path, err ) ) { + // failed to rename + ok = false; + if ( err.value() ) { + err_msg = QString::fromStdString( err.message() ); + } + DialogSec::errRenaming( QString::fromStdString(db_path), err_msg ); + }/* else { + // renamed successfully, make new one + }*/ + } + if ( ok ) { + ok = CheckSec::newHashesDatabase( db, db_name, ws_names ); + } + } + + db.close(); + return ok; +} diff --git a/logdoctor/utilities/checks.h b/logdoctor/utilities/checks.h new file mode 100644 index 00000000..623ca31f --- /dev/null +++ b/logdoctor/utilities/checks.h @@ -0,0 +1,68 @@ +#ifndef CHECKS_H +#define CHECKS_H + +#include +#include + +#include +#include + + +//! CheckSec +/*! + Utilities used to check the databases +*/ +class CheckSec +{ + +public: + CheckSec(); + + //! Checks the structure's integrity of the Collection database + /*! + \param db_path The path of the database, file included + \return The result of the check + \see checkDatabaseTablesNames(), newCollectionDatabase(), newHashesDatabase() + */ + static bool checkCollectionDatabase( const std::string& db_path ); + + //! Checks the structure's integrity of the Hashes database + /*! + \param db_path The path of the database, file included + \return The result of the check + \see checkDatabaseTablesNames(), newCollectionDatabase(), newHashesDatabase() + */ + static bool checkHashesDatabase( const std::string& db_path ); + + +private: + + //! Checks the tables' names integrity + /*! + \param db Database object, already initialized + \param db_name Database's name, eventually used by the dialogs + \return The result of the check: 0 if failed with an error, 1 if all the integrity checks passed, 2 if a rebuild is needed + \see checkCollectionDatabase(), checkHashesDatabase(), newCollectionDatabase(), newHashesDatabase() + */ + static int checkDatabaseTablesNames( QSqlDatabase& db, const QString& db_name ); + + //! Builds a new database for the logs Collection + /*! + \param db Database object, already initialized + \param db_name Database's name, eventually used by the dialogs + \return The result of the operation + \see checkCollectionDatabase(), checkHashesDatabase() + */ + static bool newCollectionDatabase( QSqlDatabase& db, const QString& db_name, const std::vector& ws_names ); + + //! Builds a new database for the used log files' Hashes + /*! + \param db Database object, already initialized + \param db_name Database's name, eventually used by the dialogs + \return The result of the operation + \see checkCollectionDatabase(), checkHashesDatabase() + */ + static bool newHashesDatabase( QSqlDatabase& db, const QString& db_name, const std::vector& ws_names ); +}; + +#endif // CHECKS_H diff --git a/logdoctor/utilities/colors.cpp b/logdoctor/utilities/colors.cpp new file mode 100644 index 00000000..823717d7 --- /dev/null +++ b/logdoctor/utilities/colors.cpp @@ -0,0 +1,73 @@ + +#include "colors.h" + + +ColorSec::ColorSec() +{ + +} + +const std::unordered_map ColorSec::getColors() +{ + const std::unordered_map colors = { + // greyscale + {"black", QColor( 0, 0, 0, 255 )}, + {"dark_grey", QColor( 63, 63, 63, 255 )}, + {"grey", QColor( 127, 127, 127, 255 )}, + {"light_grey", QColor( 191, 191, 191, 255 )}, + {"white", QColor( 255, 255, 255, 255 )}, + // spectrum + {"red", QColor( 255, 44, 0, 255 )}, + {"orange", QColor( 255, 140, 0, 255 )}, + {"yellow", QColor( 255, 200, 0, 255 )}, + }; + return colors; +} + + +const std::unordered_map> ColorSec::getColorSchemes() +{ + const std::unordered_map> scheme = { + // none + {0,{{"background",""}, + {"text",""}, + {"x",""}, + {"ip",""}, + {"pt",""}, + {"time",""}, + {"ua",""}, + {"req",""}, + {"res",""} }}, + // breeze + {1,{{"background","#ffffff"}, + {"text","#9c9c9b"}, + {"x","#1f1c1b"}, + {"ip","#644a9b"}, + {"pt","#d5bc79"}, + {"time","#d685d6"}, + {"ua","#006e28"}, + {"req","#54b8ff"}, + {"res","#d24f4f"} }}, + // monokai + {2,{{"background","#272822"}, + {"text","#706c5a"}, + {"x","#a6a6a0"}, + {"ip","#57adbc"}, + {"pt","#c1b864"}, + {"time","#9773db"}, + {"ua","#a6e22e"}, + {"req","#d1d1cb"}, + {"res","#f92672"} }}, + // radical + {3,{{"background","#141322"}, + {"text","#749295"}, + {"x","#7c9c9e"}, + {"ip","#fda8bc"}, + {"pt","#ff85a1"}, + {"time","#a8c0c2"}, + {"ua","#42a784"}, + {"req","#d5358f"}, + {"res","#56e8e4"} }} + }; + return scheme; +} diff --git a/logdoctor/utilities/colors.h b/logdoctor/utilities/colors.h new file mode 100644 index 00000000..7ad89063 --- /dev/null +++ b/logdoctor/utilities/colors.h @@ -0,0 +1,28 @@ +#ifndef COLORS_H +#define COLORS_H + +#include +#include +#include + +#include +#include + + +//! ColorSec +/*! + Utilities for the colors +*/ +class ColorSec +{ +public: + ColorSec(); + + //! Provides a map with pre-made colors + static const std::unordered_map getColors(); + + //! Provides a map with pre-made color-schemes for the TextBrowser + static const std::unordered_map> getColorSchemes(); +}; + +#endif // COLORS_H diff --git a/logdoctor/utilities/gzip.cpp b/logdoctor/utilities/gzip.cpp new file mode 100644 index 00000000..b273ac63 --- /dev/null +++ b/logdoctor/utilities/gzip.cpp @@ -0,0 +1,124 @@ + +#include "gzip.h" + +#include "modules/exceptions.h" + +#include +#include +#if defined( Q_OS_WIN ) + #include +#else + #include +#endif + + +// avoid corruption of the data on Windows/MS-DOS systems +#if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(__CYGWIN__) + #include + #include + #define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY) +#else + #define SET_BINARY_MODE(file) +#endif + +// buffer size +#define CHUNK 16384 + + +GZutils::GZutils() +{ + +} + + +void GZutils::readFile( const std::string& path, std::string& content ) +{ + bool successful = true; + + int ret; + unsigned have; + z_stream strm; + unsigned char in[CHUNK]; + unsigned char out[CHUNK]; + + // allocate inflate state + strm.zalloc = Z_NULL; + strm.zfree = Z_NULL; + strm.opaque = Z_NULL; + strm.avail_in = 0; + strm.next_in = Z_NULL; + ret = inflateInit2( &strm, 15|32 ); + if ( ret != Z_OK ) { + successful = false; + } + + if ( successful ) { + FILE *file = fopen ( path.c_str(), "rb" ); + /*FILE *dest = fopen ( out_path.c_str(), "wb" );*/ + if ( file == NULL ) { + // unable to open the file + //throw("cannot read"); + return; + } + // decompress until deflate stream ends or end of file is reached + do { + strm.avail_in = fread( in, 1, CHUNK, file ); + if ( ferror( file ) ) { + // error reading + (void)inflateEnd( &strm ); + /*successful = false;*/ + break; + } + if ( strm.avail_in == 0 ) { + // no more data to read + break; + } + strm.next_in = in; + // run inflate() on input until output buffer is not full + do { + strm.avail_out = CHUNK; + strm.next_out = out; + ret = inflate( &strm, Z_NO_FLUSH ); + switch (ret) { + case Z_NEED_DICT: + ret = Z_DATA_ERROR; // fall through + case Z_STREAM_ERROR: // <- state not clobbered + case Z_DATA_ERROR: + case Z_MEM_ERROR: + (void)inflateEnd( &strm ); + successful = false; + break; + } + have = CHUNK - strm.avail_out; + /*if ( fwrite(out, 1, have, dest) != have || ferror( dest ) ) { + (void)inflateEnd( &strm ); + successful = false; + break; + }*/ + for ( int i=0; i + + +//! GZUtils +/*! + Utilities to work on GZipped files +*/ +class GZutils +{ +public: + GZutils(); + + //! Reads a GZipped file + /*! + \param path The path of the file + \param content Will hold the content of the file + */ + static void readFile( const std::string& path, std::string& content ); +}; + +#endif // GZIP_H diff --git a/logdoctor/utilities/io.cpp b/logdoctor/utilities/io.cpp new file mode 100644 index 00000000..d9000ea3 --- /dev/null +++ b/logdoctor/utilities/io.cpp @@ -0,0 +1,307 @@ + +#include "io.h" + +#include "modules/exceptions.h" + +#include "utilities/gzip.h" +#include "utilities/strings.h" +#include "utilities/vectors.h" + +#include + + +IOutils::IOutils() +{ + +} + +// test the existence of a file/folder +const bool IOutils::exists( const std::string& path ) +{ + if ( path.size() > 0 ) { + return std::filesystem::exists( path ); + } else { + return false; + } +} + +// tests if a path exists and points to a file +const bool IOutils::isFile( const std::string& path ) +{ + bool result = false; + if ( std::filesystem::exists( path )) { + result = std::filesystem::is_regular_file( path ); + } + return result; +} +// returns whether a file is readable/writable +const bool IOutils::checkFile( const std::string& path, const bool& readable, const bool& writable ) +{ + bool result = false; + if ( IOutils::isFile( path ) ) { + result = true; + // check the needed permissions + const auto perms = std::filesystem::status( path ).permissions(); + if ( readable ) { + if ( (perms & std::filesystem::perms::owner_read) == std::filesystem::perms::none ) { + result = false; + } + } + if ( writable ) { + if ( (perms & std::filesystem::perms::owner_write) == std::filesystem::perms::none ) { + result = false; + } + } + } + return result; +} + +// test if a path exists and points to a folder +const bool IOutils::isDir( const std::string& path ) +{ + bool result = false; + if ( std::filesystem::exists( path )) { + result = std::filesystem::is_directory( path ); + } + return result; +} +// returns whether a folder is readable/writable +const bool IOutils::checkDir( const std::string& path, const bool& readable, const bool& writable ) +{ + bool result = false; + if ( IOutils::isDir( path ) ) { + result = true; + // check the needed permissions + const auto perms = std::filesystem::status( path ).permissions(); + if ( readable ) { + if ( (perms & std::filesystem::perms::owner_read) == std::filesystem::perms::none ) { + result = false; + } + } + if ( writable ) { + if ( (perms & std::filesystem::perms::owner_write) == std::filesystem::perms::none ) { + result = false; + } + } + } + return result; +} + + +// create a directory +const bool IOutils::makeDir( const std::string& path, std::error_code& err ) noexcept(true) +{ + bool result = true; + try { + result = std::filesystem::create_directories( path, err ); + if ( err.value() ) { + result = false; + } + } catch (...) { + result = false; + } + return result; +} + + +// rename an entry with a trailing '.copy' +const bool IOutils::renameAsCopy( const std::string& path, std::error_code& err ) noexcept(true) +{ + bool result = true; + try { + std::string new_path = path; + // loop until a valid name is found + while (true) { + new_path += ".copy"; + if ( ! IOutils::exists( new_path ) ) { + // available name found + break; + } + } + std::filesystem::rename( path, new_path, err ); + if ( err.value() ) { + result = false; + } + } catch (...) { + result = false; + } + return result; +} + + + +void IOutils::randomLines(const std::string& path, std::vector& lines, const int& n_lines, const bool& strip_lines ) +{ + // read rhe first N lines only + std::ifstream file; + std::string line; + std::vector aux_lines; + try { + // pick random lines + std::string aux; + try { + // try reading a gzipped file + GZutils::readFile( path, aux ); + + } catch ( const GenericException& ) { + // failed closing file pointer + throw; + + } catch (...) { + // fallback in reading as text file + if ( aux.size() > 0 ) { + aux.clear(); + } + IOutils::readFile( path, aux ); + } + StringOps::split( aux_lines, aux ); + aux.clear(); + int max = aux_lines.size(); + if ( max > 0 ) { + if ( max <= n_lines ) { + lines = aux_lines; + } else { + time_t nTime; + srand((unsigned) time(&nTime)); + int index; + std::vector picked_indexes; + for( int i=0 ; i::contains( picked_indexes, index ) ) { + continue; + } + break; + } + line = aux_lines.at( index ); + if ( strip_lines ) { + line = StringOps::strip( line ); + } + if ( line.size() == 0 || StringOps::startsWith( line, "#" ) ) { // leave the "#" check for IIS logs + i--; + continue; + } + lines.push_back( line ); + } + // add the first and last lines, to double check for file integrity + for ( const int& index : std::vector({0,max-1}) ) { + if ( ! VecOps::contains( picked_indexes, index ) ) { + line = aux_lines.at( index ); + if ( strip_lines ) { + line = StringOps::strip( line ); + } + if ( line.size() == 0 || StringOps::startsWith( line, "#" ) ) { + continue; + } + lines.push_back( line ); + } + } + } + } + aux_lines.clear(); + + // re-catched in craplog + } catch ( const GenericException& ) { + // failed closing gzip file pointer + lines.clear(); aux_lines.clear(); + if ( file.is_open() ) { + file.close(); + } + throw GenericException( "An error accured while reading the gzipped file" ); + + } catch ( const std::ios_base::failure& ) { + // failed reading + lines.clear(); aux_lines.clear(); + if ( file.is_open() ) { + file.close(); + } + throw GenericException( "An error accured while reading the file" ); + + } catch (...) { + lines.clear(); aux_lines.clear(); + if ( file.is_open() ) { + file.close(); + } + throw GenericException( "Something failed while handling the file" ); + } + if ( file.is_open() ) { + file.close(); + } + aux_lines.clear(); +} + + +void IOutils::readFile( const std::string& path , std::string& content ) +{ + // read the whole file + std::ifstream file; + try { + /*constexpr std::size_t read_size = std::size_t(4096);*/ + file = std::ifstream(path); + if ( ! file.is_open() ) { + throw std::ios_base::failure( "file is not open" ); + } + if ( ! file.good() ) { + throw std::ios_base::failure( "file is not good" ); + } + // add bit exceptions + file.exceptions(std::ifstream::failbit); + file.exceptions(std::ios_base::badbit); + // read the whole file + content = std::string( + (std::istreambuf_iterator( file )), + std::istreambuf_iterator() ); + + } catch ( const std::ios_base::failure& ) { + // failed reading + if ( file.is_open() ) { + file.close(); + } + throw; + } catch (...) { + if ( file.is_open() ) { + file.close(); + } + throw std::exception(); // already catched + } + + if ( file.is_open() ) { + file.close(); + } +} + + +void IOutils::writeOnFile( const std::string& path, const std::string& content ) +{ + std::ofstream file; + try { + file.open( path ); + if ( ! file.is_open() ) { + throw std::ios_base::failure( "file is not open" ); + } + if ( ! file.good() ) { + throw std::ios_base::failure( "file is not good" ); + } + // add bit exceptions + file.exceptions(std::ifstream::failbit); + file.exceptions(std::ios_base::badbit); + // write the content + file << content << std::endl; + + } catch ( const std::ios_base::failure& ) { + // failed writing + if ( file.is_open() ) { + file.close(); + } + throw; + } catch (...) { + if ( file.is_open() ) { + file.close(); + } + throw std::exception(); // already catched + } + + if ( file.is_open() ) { + file.close(); + } +} diff --git a/logdoctor/utilities/io.h b/logdoctor/utilities/io.h new file mode 100644 index 00000000..c1345734 --- /dev/null +++ b/logdoctor/utilities/io.h @@ -0,0 +1,96 @@ +#ifndef IO_H +#define IO_H + +#include +#include +#include + + +//! IOUtils +/*! + Utilities to work on files +*/ +class IOutils +{ +public: + IOutils(); + + //! Checks the existence of a file/folder + /*! + \param path The path of the entry + \return The result of the check + */ + static const bool exists( const std::string& path ); + + //! Checks if a path exists and points to a file + /*! + \param path The path of the entry + \return The result of the check + */ + static const bool isFile( const std::string& path ); + + //! Checks if a path exists and points to a directory + /*! + \param path The path of the entry + \return The result of the checks + */ + static const bool isDir( const std::string& path ); + + //! Checks if a path exists, if it points to a file and if the user has read and/or write permissions on it + /*! + \param path The path of the entry + \param readable Set to true to check for readability + \param writable Set to true to check for writability + \return The result of the checks + */ + static const bool checkFile( const std::string& path, const bool& readable=false, const bool& writable=false ); + + //! Checks if a path exists, if it points to a folder and if the user has read and/or write permissions on it + /*! + \param path The path of the entry + \param readable Set to true to check for readability + \param writable Set to true to check for writability + \return The result of the checks + */ + static const bool checkDir( const std::string& path, const bool& readable=false, const bool& writable=false ); + + //! Creates a directory + /*! + \param path The path of the new entry + \return Wheter the operation was successful or not + */ + static const bool makeDir( const std::string& path, std::error_code& err ) noexcept(true); + + //! Renames an entry with a trailing '.copy' + /*! + \param path The path of the entry to rename + \param err Will hold the error, if any + \return Wheter the operation was successful or not + */ + static const bool renameAsCopy( const std::string& path, std::error_code& err ) noexcept(true); + + //! Randomly pick lines from a file + /*! + \param path The path of the entry + \param lines Will hold the picked lines + \param n_lines The number of lines to pick + \param strip_lines Whether to strip control-characters away from the lines + */ + static void randomLines( const std::string& path, std::vector& lines, const int& n_lines=16, const bool& strip_lines=true ); + + //! Reads the content of a file + /*! + \param path The path of the file to read from + \param content Will hold the content of the file + */ + static void readFile( const std::string& path, std::string& content ); + + //! Writes a string on file + /*! + \param path The path of the file to write on + \param content The string to write + */ + static void writeOnFile( const std::string& path, const std::string& content ); +}; + +#endif // IO_H diff --git a/logdoctor/utilities/rtf.cpp b/logdoctor/utilities/rtf.cpp new file mode 100644 index 00000000..41a56b8d --- /dev/null +++ b/logdoctor/utilities/rtf.cpp @@ -0,0 +1,228 @@ + +#include "rtf.h" + +#include "utilities/strings.h" + + +RichText::RichText() +{ + +} + + +void RichText::enrichLogs( QString &rich_content, const std::string& content, const FormatOps::LogsFormat& logs_format, TextBrowser& TB ) +{ + const std::unordered_map& colors = TB.getColorScheme(); + int color_scheme = TB.getColorSchemeID(); + bool wide_lines = TB.getWideLinesUsage(); + // enrich the text + rich_content.clear(); + rich_content.reserve( content.size() ); + rich_content += QString(" 0 ) { + rich_content += " style=\"background:" + colors.at("background") + "; color:" + colors.at("text") + "\""; + } + rich_content += ">"; + if ( wide_lines == true ) { + rich_content += "
    "; + } + QString rich_line="", class_name=""; + std::string sep, fld, fld_str, aux_sep2; + bool missing=false; + size_t start, stop, i, aux_start, aux_stop, + line_size, sep_size; + const size_t n_sep = logs_format.separators.size()-1; + std::vector lines; + StringOps::splitrip( lines, content ); + for ( const std::string& line : lines ) { + // check if the line is commented, usually from IIS logs + if ( StringOps::startsWith( line, "#" ) && !StringOps::startsWith( logs_format.initial, "#" ) ) { + rich_line = QString("

    %1

    ").arg( QString::fromStdString( line ) ); + if ( wide_lines == true ) { + rich_line += "
    "; + } + rich_content.push_back( rich_line ); + continue; + } + i = 0; + line_size = line.size()-1; + rich_line = "

    "; + // add the initial chars + stop = logs_format.initial.size(); + rich_line += QString::fromStdString( logs_format.initial ); + while (true) { + // color fields + start = stop; // stop updated at the end of this loop + if ( i <= n_sep ) { + sep = logs_format.separators.at( i ); + stop = line.find( sep, start ); + } else if ( i == n_sep+1 ) { + // final separator + sep = logs_format.final; + if ( sep.size() == 0 ) { + stop = line_size+1; + } else { + stop = line.find( sep, start ); + if ( stop == std::string::npos ) { + stop = line_size +1; + } + } + } else { + // no more separators + break; + } + if ( stop == std::string::npos ) { + // separator not found, skip to the next one + i++; + stop = start; + continue; + } + + // get fields + fld = logs_format.fields.at( i ); + fld_str = line.substr(start, stop-start); + + if ( i+1 <= n_sep ) { + // not the last separator, check for mistakes + bool ok = true; + aux_stop = stop; + + if ( sep == " " ) { + // whitespace-separated-values fields + int c = StringOps::count( fld_str, sep ), + n = 0; + if ( fld == "request_full" ) { + n = 2; + } else if ( fld == "date_time_mcs" ) { + n = 4; + } else if ( fld == "date_time_ncsa" ) { + n = 1; + } else if ( fld == "date_time_gmt" ) { + n = 3; + } + if ( n > 0 && c < n ) { + // loop until the correct number of whitespaces is reached + aux_start = stop + 1; + while ( c < n ) { + aux_stop = line.find( sep, aux_start ); + if ( aux_stop == std::string::npos ) { + // not found + ok = false; + break; + } + aux_start = aux_stop + 1; + c++; + } + } + + } else if ( fld == "user_agent" && StringOps::startsWith( sep, "\"" ) ) { + // atm the only support is for escaped quotes + if ( fld_str.back() == '\\' ) { + aux_start = stop + sep.size(); + while (true) { + aux_stop = line.find( sep, aux_start ); + if ( aux_stop == std::string::npos ) { + // not found + break; + } else if ( line.at( aux_stop-1 ) != '\\' ) { + // non-backslashed quotes + break; + } + aux_start = aux_stop + sep.size(); + } + } + } + + // finally update if needed + if ( ok == true && aux_stop >= stop ) { + stop = aux_stop; + fld_str = StringOps::strip( line.substr(start, stop-start), " " ); + } + } + + sep_size = sep.size(); // do not remove, holdss the corretc size to increase stop + // color the fields + if ( StringOps::startsWith( fld, "date_time" ) ) { + if ( StringOps::startsWith( fld_str, "[" ) ) { + fld_str = fld_str.substr( 1, fld_str.size()-1 ); + rich_line += "["; + if ( StringOps::endsWith( fld_str, "]" ) ) { + fld_str = fld_str.substr( 0, fld_str.size()-1 ); + sep = "]" + sep; + } + } + } + rich_line += ""; + class_name = ""; + if ( color_scheme > 0 ) { + class_name += ""; + } + // add the class name as span + rich_line += class_name; + rich_line += QString::fromStdString( fld_str ); + if ( color_scheme > 0 ) { + rich_line += ""; + } + rich_line += ""; + // update the stop for the next start + if ( missing == true ) { + stop = aux_stop; + } else { + stop += sep_size; + i++; + } + if ( stop > line_size ) { + // this was the final separator + rich_line += QString::fromStdString( logs_format.final ); + break; + } + if ( missing == true ) { + missing = false; + rich_line += QString::fromStdString( aux_sep2 ); + } else { + rich_line += QString::fromStdString( sep ); + } + } + rich_line += "

    "; + if ( wide_lines == true ) { + rich_line += "
    "; + } + rich_content.push_back( rich_line ); + } + lines.clear(); + rich_content.push_back(""); +} + + + +void RichText::richLogsDefault( QString& rich_str ) +{ + rich_str.clear(); + rich_str += QString("








    %1

    %2

    ") + .arg( RichText::tr("Select a file from the list"), + RichText::tr("to inspect its content") ); +} + + +void RichText::richLogsFailure( QString &rich_str ) +{ + rich_str.clear(); + rich_str += QString("








    %1

    ") + .arg( RichText::tr("Failed to read") ); +} diff --git a/logdoctor/utilities/rtf.h b/logdoctor/utilities/rtf.h new file mode 100644 index 00000000..6278d38d --- /dev/null +++ b/logdoctor/utilities/rtf.h @@ -0,0 +1,49 @@ +#ifndef RTF_H +#define RTF_H + +#include +#include + +#include "modules/tb.h" +#include "modules/craplog/modules/formats.h" + + +//! RichText +/*! + Utilities for the TextBrowser +*/ + +class RichText : public QObject +{ + Q_OBJECT + +public: + RichText(); + + //! Enriches the content of a log file with HTML/CSS code + /*! + \param rich_content Will hold the final enriched content + \param content The plain text content from a log file + \param logs_format The logs format to use + \param TB The TextBrowser instance + */ + static void enrichLogs( + QString& rich_content, + const std::string& content, + const FormatOps::LogsFormat& logs_format, + TextBrowser& TB ); + + //! Provides the default string + /*! + \param rich_str Will hold the string + */ + static void richLogsDefault( QString& rich_str ); + + //! Provides the failure string + /*! + \param rich_str Will hold the string + */ + static void richLogsFailure( QString& rich_str ); +}; + +#endif // RTF_H diff --git a/logdoctor/utilities/strings.cpp b/logdoctor/utilities/strings.cpp new file mode 100644 index 00000000..3f302756 --- /dev/null +++ b/logdoctor/utilities/strings.cpp @@ -0,0 +1,389 @@ + +#include "strings.h" + + +StringOps::StringOps() +{ + +} + + +const int StringOps::count(const std::string& str, const std::string& flag, const bool& consecutives ) +{ + size_t start=0, aux_start=0, count=0; + while (true) { + start = str.find( flag, start ); + if ( start != std::string::npos ) { + if ( consecutives == true + && start == aux_start ) { + start += flag.size(); + aux_start = start; + continue; + } + count ++; + start += flag.size(); + aux_start = start; + } else { + break; + } + } + return count; +} + + +const bool StringOps::isNumeric( const std::string& str ) +{ + bool result = false; + if ( str.size() > 0 ) { + result = true; + for ( const unsigned char& chr : str ) { + if ( ! StringOps::isNumeric( chr ) ) { + result = false; + break; + } + } + } + return result; +} +const bool StringOps::isNumeric(const unsigned char& chr ) +{ + if ( chr > 47 && chr < 58 ) { + return true; + } else { + return false; + } +} + + +const bool StringOps::isAlphabetic( const std::string& str ) +{ + bool result = false; + if ( str.size() > 0 ) { + result = true; + for ( const unsigned char& chr : str ) { + if ( ! StringOps::isAlphabetic( chr ) ) { + result = false; + break; + } + } + } + return result; +} +const bool StringOps::isAlphabetic(const unsigned char& chr ) +{ + if ( (chr > 64 && chr < 91) + || (chr > 96 && chr < 123) ) { + return true; + } else { + return false; + } +} + + +const bool StringOps::isAlnum( const std::string& str ) +{ + bool result = false; + if ( str.size() > 0 ) { + result = true; + for ( const unsigned char& chr : str ) { + if ( ! StringOps::isAlnum( chr ) ) { + result = false; + break; + } + } + } + return result; +} +const bool StringOps::isAlnum(const unsigned char& chr ) +{ + if ( !StringOps::isNumeric( chr ) + && !StringOps::isAlphabetic( chr ) ) { + return false; + } else { + return true; + } +} + + +const bool StringOps::isHex( const unsigned char& chr ) +{ + if ( (chr > 47 && chr < 58) + || (chr > 64 && chr < 71) + || (chr > 96 && chr < 103) ) { + return true; + } else { + return false; + } +} + + +const bool StringOps::isIP( const std::string& str ) +{ + bool result = false; + if ( str.size() > 0 ) { + result = true; + for ( const unsigned char& chr : str ) { + if ( chr == '.' || chr == ':' ) { + continue; + } else if ( ! StringOps::isHex( chr ) ) { + result = false; + break; + } + } + } + return result; +} + + +const size_t StringOps::findLast( const std::string& str, const std::string& flag ) +{ + int n=0; + size_t index, aux=0; + const size_t f_size=flag.size(); + do { + index = (n>0) ? aux : -f_size; + aux = str.find( flag, index+f_size ); + n++; + + } while ( aux != std::string::npos ); + + if ( index == -f_size ) { + index = std::string::npos; + } + + return index; +} + + +const bool StringOps::startsWith( const std::string& str, const std::string& flag ) +{ + bool result = false; + if ( flag.size() == 0 ) { + result = true; + } else if ( flag.size() <= str.size() ) { + result = true; + for ( int i=0; i= 0 ) { + found = false; + char str_index = str.at( i ); + for ( const char& chr : chars ) { + if ( str_index == chr ) { + found = true; + break; + } + } + if ( ! found ) { + break; + } + i--; + } + std::string stripped = ""; + if ( i >= 0 ) { + stripped = str.substr( 0, str.size() - (str.size() - i) + 1 ); + } + return stripped; +} + + +std::string StringOps::lstripUntil( const std::string& str, const std::string& chr, const bool& inclusive, const bool& consecutives ) +{ + size_t start, aux_start, aux; + const size_t max_size = str.size(); + std::string stripped = ""; + if ( max_size > 0 ) { + start = str.find( chr ); + if ( inclusive == true ) { + start += chr.size(); + } + if ( consecutives == true + && start != std::string::npos ) { + aux_start = start; + while (true) { + aux = str.find( chr, aux_start ); + if ( aux == std::string::npos ) { + break; + } else if ( aux != aux_start ) { + break; + } + if ( inclusive == true ) { + aux += chr.size(); + } + aux_start = aux; + } + if ( aux_start < max_size ) { + stripped = str.substr( aux_start ); + } + } else { + if ( start == std::string::npos ) { + stripped = str; + } else if ( start < max_size ) { + stripped = str.substr( start ); + } + } + } + return stripped; +} + + + +void StringOps::split( std::vector& list, const std::string& target_str, const std::string& separator ) +{ + std::string slice; + size_t start=0, stop; + if ( target_str.size() > 0 ) { + while (true) { + stop = target_str.find( separator, start ); + if ( stop == std::string::npos ) { + slice = target_str.substr( start ); + if ( slice.size() > 0 ) { + list.push_back( slice ); + } + break; + } else { + slice = target_str.substr( start, stop-start ); + if ( slice.size() > 0 ) { + list.push_back( slice ); + } + start = stop+separator.size(); + } + } + } +} + + +void StringOps::splitrip( std::vector& list, const std::string& target_str, const std::string& separator, const std::string& strip ) +{ + std::vector aux; + const std::string str_ = StringOps::strip( target_str, strip ); + StringOps::split( aux, str_, separator ); + for ( const std::string& str : aux ) { + const std::string str_aux = StringOps::strip( str, strip ); + if ( str_aux.size() == 0 ) { + continue; + } + list.push_back( str_aux ); + } + aux.clear(); +} + + +const std::string StringOps::replace( const std::string& str, const std::string& target, const std::string& replace ) +{ + size_t start=0, stop; + const size_t size = target.size(); + std::string string = ""; + if ( str.size() > 0 ) { + if ( size == 0 ) { + // target is empty, nothing to replace + string = str; + } else { + while ( true ) { + stop = str.find( target, start ); + if ( stop == std::string::npos ) { + string += str.substr( start ); + break; + } else { + string += str.substr( start, stop-start ); + string += replace; + start = stop+size; + } + } + } + } + return string; +} + + +const std::string StringOps::toUpper( const std::string& str ) +{ + std::string up = ""; + for ( const unsigned char& ch : str ) { + up.push_back( (char)std::toupper( ch ) ); + } + return up; +} + +const std::string StringOps::toLower( const std::string& str ) +{ + std::string low = ""; + for ( const unsigned char& ch : str ) { + low.push_back( (char)std::tolower( ch ) ); + } + return low; +} diff --git a/logdoctor/utilities/strings.h b/logdoctor/utilities/strings.h new file mode 100644 index 00000000..4c180543 --- /dev/null +++ b/logdoctor/utilities/strings.h @@ -0,0 +1,192 @@ +#ifndef STRINGS_H +#define STRINGS_H + +#include +#include + + +//! StringOps +/*! + Utilities for the strings +*/ +class StringOps +{ +public: + StringOps(); + + + //! Count the occurrences of the given sequence in the given string + /*! + \param str The target string + \return The number of occurrences + */ + static const int count( const std::string& str, const std::string& flag, const bool& consecutives=true ); + + //! Checks whether a string only contains numeric characters + /*! + \param str The target string + \return The result of the check + */ + static const bool isNumeric( const std::string& str ); + + //! Checks whether character is numeric + /*! + \param str The target character + \return The result of the check + \see isNumeric() + */ + static const bool isNumeric( const unsigned char& chr ); + + //! Checks whether a string only contains alphabetic characters + /*! + \param str The target string + \return The result of the check + */ + static const bool isAlphabetic( const std::string& str ); + + //! Checks whether a character is alphabetic + /*! + \param str The target character + \return The result of the check + \see isAlphabetic() + */ + static const bool isAlphabetic( const unsigned char& chr ); + + //! Checks whether a string only contains alpha-numeric characters + /*! + \param str The target string + \return The result of the check + */ + static const bool isAlnum( const std::string& str ); + + //! Checks whether a character is alpha-numeric + /*! + \param str The target character + \return The result of the check + \see isAlnum + */ + static const bool isAlnum( const unsigned char& chr ); + + //! Checks whether a string only contains hexadecimal characters + /*! + \param str The target character + \return The result of the check + */ + static const bool isHex( const unsigned char& chr ); + + //! Checks whether a string could be a valid IPv4/IPv6 + /*! + \param str The target string + \return The result of the check + */ + static const bool isIP( const std::string& str ); + + //! Finds the last occurrence of the given sequence in the given string + /*! + \param str The target string + \param flag The sequence to search for + \return The position of the last occurrence + */ + static const size_t findLast( const std::string& str, const std::string& flag ); + + //! Checks if a string starts with the given sequence + /*! + \param str The target string + \param flag The sequence to search for + \return The result of the check + */ + static const bool startsWith( const std::string& str, const std::string& flag ); + + //! Checks if a string ends with the given sequence + /*! + \param str The target string + \param flag The sequence to search for + \return The result of the check + */ + static const bool endsWith( const std::string& str, const std::string& flag ); + + //! Checks if a string contains the given sequence + /*! + \param str The target string + \param flag The sequence to search for + \return The result of the check + */ + static const bool contains( const std::string& str, const std::string& flag ); + + //! Strips the given characters from both the left and the right side of a string + /*! + \param str The target string + \param chars The characters to strip away + \return The result string + */ + static std::string strip( const std::string& str, const std::string& chars=" \n\t\b\r\v" ); + + //! Strips the given characters from the left side of a string + /*! + \param str The target string + \param chars The characters to strip away + \return The result string + */ + static std::string lstrip( const std::string& str, const std::string& chars=" \n\t\b\r\v" ); + + //! Strips the given characters from the right side of a string + /*! + \param str The target string + \param chars The characters to strip away + \return The result string + */ + static std::string rstrip( const std::string& str, const std::string& chars=" \n\t\b\r\v" ); + + //! Strips everything from a string starting from the left side untill the delimiter is found (a.k.a. cut) + /*! + \param str The target string + \param chr The delimiter + \param inclusive Whether to also strip the delimiter or not + \param consecutives Whether to strip all the occurrences of the delimiter if they're consecutive + \return The result string + */ + static std::string lstripUntil( const std::string& str, const std::string& chr, const bool& inclusive=true, const bool& consecutives=true ); + + //! Splits a string using a separator + /*! + \param list Will hold the splitted content + \param target_str The target string + \param separator The sequence to use as separator + */ + static void split( std::vector& list, const std::string& target_str, const std::string& separator="\n" ); + + //! Splits a string and strips all the splitted items + /*! + \param list Will hold the splitted content + \param target_str The target string + \param separator The sequence to use as separator + \param strip The characters to strip away + */ + static void splitrip( std::vector& list, const std::string& target_str, const std::string& separator="\n", const std::string& strip=" \n\t\b\r\v" ); + + //! Replaces all the occurrences of a sequence with another + /*! + \param str The target string + \param target The sequence which will be replaced + \param replace The sequence to be used to replace the target + \return The result string + */ + static const std::string replace( const std::string& str, const std::string& target, const std::string& replace ); + + //! Converts a string to upper case + /*! + \param str The target string + \return The result string + */ + static const std::string toUpper( const std::string& str ); + + //! Converts a string to lower case + /*! + \param str The target string + \return The result string + */ + static const std::string toLower( const std::string& str ); + +}; + +#endif // STRINGS_H diff --git a/logdoctor/utilities/stylesheets.cpp b/logdoctor/utilities/stylesheets.cpp new file mode 100644 index 00000000..0ad3b928 --- /dev/null +++ b/logdoctor/utilities/stylesheets.cpp @@ -0,0 +1,1522 @@ + +#include "stylesheets.h" + +#include "modules/exceptions.h" + + +StyleSec::StyleSec() +{ + +} + + +void StyleSec::getStyleSheet( QString& stylesheet, const QString& icons_theme, const int& theme_id ) +{ + std::unordered_map style_map; + switch ( theme_id ) { + case 1: + style_map = { + {"text_primary", + "rgb( 248, 248, 248 )"}, + {"text_secondary", + "rgb( 144, 144, 144 )"}, + {"text_disabled", + "rgb( 128, 128, 128 )"}, + {"tooltips_base", + "rgb( 4, 4, 4 )"}, + {"tooltips_text", + "rgb( 248, 248, 248 )"}, + {"tooltips_border", + "rgb( 144, 144, 144 )"}, + {"menu_text", + "rgb( 144, 144, 144 )"}, + {"menu_base", + "rgb( 32, 32, 32 )"}, + {"menu_base_hover", + "rgb( 64, 64, 64 )"}, + {"menu_base_dropdown_selection", + "rgb( 192, 192, 192 )"}, + {"window_base_primary", + "rgb( 32, 32, 32 )"}, + {"window_base_secondary", + "rgb( 16, 16, 16 )"}, + {"window_base_tertiary", + "rgb( 64, 64, 64 )"}, + {"border_primary", + "rgb( 96, 96, 96 )"}, + {"border_secondary", + "rgb( 128, 128, 128 )"}, + {"border_tertiary", + "rgb( 128, 128, 128 )"}, + {"buttons_base", + "rgb( 64, 64, 64 )"}, + {"buttons_base_hover", + "rgb( 82, 82, 82 )"}, + {"buttons_base_disabled", + "rgb( 40, 40, 40 )"}, + {"logs_switch_buttons_base_hover", + "rgb( 24, 24, 24 )"}, + {"stats_switch_buttons_frame_base", + "rgb( 16, 16, 16 )"}, + {"stats_switch_buttons_frame_border", + "rgb( 32, 32, 32 )"}, + {"stats_switch_buttons_base", + "rgb( 64, 64, 64 )"}, + {"stats_switch_buttons_base_hover", + "rgb( 24, 24, 24 )"}, + {"stats_switch_buttons_base_border_hover", + "rgb( 48, 48, 48 )"}, + {"globals_frames_base", + "rgb( 16, 16, 16 )"}, + {"globals_frames_border", + "rgb( 128, 128, 128 )"}, + {"globals_frames_lines", + "rgb( 192, 192, 192 )"}, + {"boxes_base_primary", + "rgb( 64, 64, 64 )"}, + {"boxes_base_secondary", + "rgb( 96, 96, 96 )"}, + {"boxes_base_tertiary", + "rgb( 128, 128, 128 )"}, + {"boxes_border_focus", + "rgb( 192, 192, 192 )"}, + {"boxes_base_disabled", + "rgb( 40, 40, 40 )"}, + {"boxes_base_off", + "rgb( 48, 48, 48 )"}, + {"linedit_text", + "rgb( 16, 16, 16 )"}, + {"linedit_base", + "rgb( 216, 216, 216 )"}, + {"linedit_base_focus", + "rgb( 248, 248, 248 )"}, + {"linedit_base_selection", + "rgb( 192, 192, 192 )"}, + {"linedit_base_disabled", + "rgb( 96, 96, 96 )"}, + {"tables_header", + "rgb( 64, 64, 64 )"}, + {"tables_base", + "rgb( 32, 32, 32 )"}, + {"tables_text_selection", + "rgb( 248, 248, 248 )"}, + {"tables_base_selection", + "rgb( 64, 64, 64 )"}, + {"tables_border", + "rgb( 96, 96, 96 )"}, + {"tables_base_disabled", + "rgb( 96, 96, 96 )"}, + {"tables_text_disabled", + "rgb( 128, 128, 128 )"}, + {"tables_border_disabled", + "rgb( 64, 64, 64 )"}, + {"charts_contour", + "rgb( 32, 32, 32 )"}, + {"textbrowser_text", + "rgb( 192, 192, 192 )"}, + {"textbrowser_base", + "rgb( 32, 32, 32 )"}, + {"textbrowser_text_selection", + "rgb( 248, 248, 248 )"}, + {"textbrowser_base_selection", + "rgb( 64, 64, 64 )"}, + {"scrollbar_base", + "rgb( 96, 96, 96 )"}, + {"scrollbar_handler", + "rgb( 192, 192, 192 )"}, + {"slider_handler", + "rgb( 48, 48, 48 )"}, + {"slider_bar_active", + "rgb( 128, 128, 128 )"}, + {"slider_bar_inactive", + "rgb( 82, 82, 82 )"}, + {"slider_bar_active_border", + "rgb( 144, 144, 144 )"}, + {"slider_handler_border", + "rgb( 192, 192, 192 )"}, + {"slider_handler_border_hover", + "rgb( 248, 248, 248 )"}, + {"outer-tabs_base", + "rgb( 16, 16, 16 )"}, + {"inner-tabs_base", + "rgb( 32, 32, 32 )"}, + {"sub-tabs_base", + "rgb( 48, 48, 48 )"}, + {"outer-tabs_tab_text_selected", + "rgb( 248, 248, 248 )"}, + {"outer-tabs_tab_text_unselected", + "rgb( 128, 128, 128 )"}, + {"outer-tabs_tab_text_hover", + "rgb( 192, 192, 192 )"}, + {"outer-tabs_tab_border", + "rgb( 96, 96, 96 )"}, + {"outer-tabs_tab_border_unselected", + "rgb( 48, 48, 48 )"}, + {"inner-tabs_tab_base", + "rgb( 32, 32, 32 )"}, + {"inner-tabs_tab_base_unselected", + "rgb( 24, 24, 24 )"}, + {"inner-tabs_pane_base", + "rgb( 32, 32, 32 )"}, + {"inner-tabs_border", + "rgb( 96, 96, 96 )"}, + {"inner-tabs_lines", + "rgb( 192, 192, 192 )"}, + {"sub-tabs_tab_base", + "rgb( 48, 48, 48 )"}, + {"sub-tabs_tab_base_unselected", + "rgb( 40, 40, 40 )"}, + {"sub-tabs_pane_base", + "rgb( 48, 48, 48 )"}, + {"sub-tabs_border", + "rgb( 96, 96, 96 )"}, + {"sub-tabs_tab_border_unselected", + "rgb( 64, 64, 64 )"} + }; + break; + case 2: + style_map = { + {"text_primary", + "rgb( 45, 0, 30 )"}, + {"text_secondary", + "rgb( 115, 30, 70 )"}, + {"text_disabled", + "rgb( 255, 204, 143 )"}, + {"tooltips_base", + "rgb( 45, 0, 30 )"}, + {"tooltips_text", + "rgb( 255, 204, 143 )"}, + {"tooltips_border", + "rgb( 145, 100, 130 )"}, + {"menu_text", + "rgb( 45, 0, 30 )"}, + {"menu_base", + "rgb( 205, 154, 93 )"}, + {"menu_base_hover", + "rgb( 165, 114, 63 )"}, + {"menu_base_dropdown_selection", + "rgb( 145, 100, 130 )"}, + {"window_base_primary", + "rgb( 255, 204, 143 )"}, + {"window_base_secondary", + "rgb( 255, 140, 141 )"}, + {"window_base_tertiary", + "rgb( 245, 172, 142 )"}, + {"border_primary", + "rgb( 195, 80, 81 )"}, + {"border_secondary", + "rgb( 195, 80, 81 )"}, + {"border_tertiary", + "rgb( 255, 204, 143 )"}, + {"buttons_base", + "rgb( 114, 235, 115 )"}, + {"buttons_base_hover", + "rgb( 154, 255, 155 )"}, + {"buttons_base_disabled", + "rgb( 195, 80, 81 )"}, + {"logs_switch_buttons_base_hover", + "rgb( 245, 172, 142 )"}, + {"stats_switch_buttons_frame_base", + "rgb( 245, 172, 142 )"}, + {"stats_switch_buttons_frame_border", + "rgb( 255, 204, 143 )"}, + {"stats_switch_buttons_base", + "rgb( 255, 140, 141 )"}, + {"stats_switch_buttons_base_hover", + "rgb( 245, 172, 142 )"}, + {"stats_switch_buttons_base_border_hover", + "rgb( 255, 204, 143 )"}, + {"globals_frames_base", + "rgb( 255, 210, 221 )"}, + {"globals_frames_border", + "rgb( 195, 80, 81 )"}, + {"globals_frames_lines", + "rgb( 145, 100, 130 )"}, + {"boxes_base_primary", + "rgb( 164, 255, 165 )"}, + {"boxes_base_secondary", + "rgb( 114, 235, 115 )"}, + {"boxes_base_tertiary", + "rgb( 154, 245, 155 )"}, + {"boxes_border_focus", + "rgb( 195, 80, 81 )"}, + {"boxes_base_disabled", + "rgb( 195, 80, 81 )"}, + {"boxes_base_off", + "rgb( 195, 80, 81 )"}, + {"linedit_text", + "rgb( 45, 0, 30 )"}, + {"linedit_base", + "rgb( 113, 154, 225 )"}, + {"linedit_base_focus", + "rgb( 143, 184, 255 )"}, + {"linedit_base_selection", + "rgb( 145, 100, 130 )"}, + {"linedit_base_disabled", + "rgb( 195, 80, 81 )"}, + {"tables_header", + "rgb( 195, 140, 141 )"}, + {"tables_base", + "rgb( 255, 210, 221 )"}, + {"tables_text_selection", + "rgb( 45, 0, 30 )"}, + {"tables_base_selection", + "rgb( 145, 100, 130 )"}, + {"tables_border", + "rgb( 195, 80, 81 )"}, + {"tables_base_disabled", + "rgb( 195, 80, 81 )"}, + {"tables_text_disabled", + "rgb( 195, 140, 141 )"}, + {"tables_border_disabled", + "rgb( 165, 114, 63 )"}, + {"charts_contour", + "rgb( 113, 154, 225 )"}, + {"textbrowser_text", + "rgb( 45, 0, 30 )"}, + {"textbrowser_base", + "rgb( 255, 210, 221 )"}, + {"textbrowser_text_selection", + "rgb( 255, 204, 143 )"}, + {"textbrowser_base_selection", + "rgb( 145, 100, 130 )"}, + {"scrollbar_base", + "rgb( 145, 100, 130 )"}, + {"scrollbar_handler", + "rgb( 45, 0, 30 )"}, + {"slider_handler", + "rgb( 113, 154, 225 )"}, + {"slider_bar_active", + "rgb( 114, 235, 115 )"}, + {"slider_bar_inactive", + "rgb( 165, 114, 63 )"}, + {"slider_bar_active_border", + "rgb( 154, 245, 155 )"}, + {"slider_handler_border", + "rgb( 195, 140, 141 )"}, + {"slider_handler_border_hover", + "rgb( 255, 210, 221 )"}, + {"outer-tabs_base", + "rgb( 255, 140, 141 )"}, + {"inner-tabs_base", + "rgb( 255, 204, 143 )"}, + {"sub-tabs_base", + "rgb( 255, 140, 141 )"}, + {"outer-tabs_tab_text_selected", + "rgb( 45, 0, 30 )"}, + {"outer-tabs_tab_text_unselected", + "rgb( 115, 30, 70 )"}, + {"outer-tabs_tab_text_hover", + "rgb( 45, 0, 30 )"}, + {"outer-tabs_tab_border", + "rgb( 255, 204, 143 )"}, + {"outer-tabs_tab_border_unselected", + "rgb( 165, 114, 63 )"}, + {"inner-tabs_tab_base", + "rgb( 255, 204, 143 )"}, + {"inner-tabs_tab_base_unselected", + "rgb( 245, 172, 142 )"}, + {"inner-tabs_pane_base", + "rgb( 255, 204, 143 )"}, + {"inner-tabs_border", + "rgb( 195, 80, 81 )"}, + {"inner-tabs_lines", + "rgb( 195, 80, 81 )"}, + {"sub-tabs_tab_base", + "rgb( 255, 140, 141 )"}, + {"sub-tabs_tab_base_unselected", + "rgb( 245, 172, 142 )"}, + {"sub-tabs_pane_base", + "rgb( 255, 140, 141 )"}, + {"sub-tabs_border", + "rgb( 195, 80, 81 )"}, + {"sub-tabs_tab_border_unselected", + "rgb( 165, 114, 63 )"} + }; + break; + case 3: + style_map = { + {"text_primary", + "rgb( 220, 211, 187 )"}, + {"text_secondary", + "rgb( 193, 175, 129 )"}, + {"text_disabled", + "rgb( 163, 145, 99 )"}, + {"tooltips_base", + "rgb( 193, 175, 129 )"}, + {"tooltips_text", + "rgb( 14, 28, 0 )"}, + {"tooltips_border", + "rgb( 163, 145, 99 )"}, + {"menu_text", + "rgb( 163, 145, 99 )"}, + {"menu_base", + "rgb( 24, 48, 0 )"}, + {"menu_base_hover", + "rgb( 54, 78, 30 )"}, + {"menu_base_dropdown_selection", + "rgb( 74, 98, 50 )"}, + {"window_base_primary", + "rgb( 24, 48, 0 )"}, + {"window_base_secondary", + "rgb( 14, 28, 0 )"}, + {"window_base_tertiary", + "rgb( 54, 78, 30 )"}, + {"border_primary", + "rgb( 163, 145, 99 )"}, + {"border_secondary", + "rgb( 193, 175, 129 )"}, + {"border_tertiary", + "rgb( 193, 175, 129 )"}, + {"buttons_base", + "rgb( 94, 118, 70 )"}, + {"buttons_base_hover", + "rgb( 124, 148, 100 )"}, + {"buttons_base_disabled", + "rgb( 54, 78, 30 )"}, + {"logs_switch_buttons_base_hover", + "rgb( 24, 38, 0 )"}, + {"stats_switch_buttons_frame_base", + "rgb( 14, 28, 0 )"}, + {"stats_switch_buttons_frame_border", + "rgb( 24, 48, 0 )"}, + {"stats_switch_buttons_base", + "rgb( 54, 78, 30 )"}, + {"stats_switch_buttons_base_hover", + "rgb( 24, 48, 0 )"}, + {"stats_switch_buttons_base_border_hover", + "rgb( 94, 118, 70 )"}, + {"globals_frames_base", + "rgb( 4, 18, 0 )"}, + {"globals_frames_border", + "rgb( 128, 128, 128 )"}, + {"globals_frames_lines", + "rgb( 124, 148, 100 )"}, + {"boxes_base_primary", + "rgb( 94, 118, 70 )"}, + {"boxes_base_secondary", + "rgb( 104, 128, 80 )"}, + {"boxes_base_tertiary", + "rgb( 124, 148, 100 )"}, + {"boxes_border_focus", + "rgb( 193, 175, 129 )"}, + {"boxes_base_disabled", + "rgb( 54, 78, 30 )"}, + {"boxes_base_off", + "rgb( 74, 98, 50 )"}, + {"linedit_text", + "rgb( 4, 18, 0 )"}, + {"linedit_base", + "rgb( 193, 175, 129 )"}, + {"linedit_base_focus", + "rgb( 223, 215, 159 )"}, + {"linedit_base_selection", + "rgb( 173, 155, 109 )"}, + {"linedit_base_disabled", + "rgb( 54, 78, 30 )"}, + {"tables_header", + "rgb( 63, 65, 19 )"}, + {"tables_base", + "rgb( 33, 35, 0 )"}, + {"tables_text_selection", + "rgb( 33, 35, 0 )"}, + {"tables_base_selection", + "rgb( 133, 135, 89 )"}, + {"tables_border", + "rgb( 133, 135, 89 )"}, + {"tables_base_disabled", + "rgb( 54, 78, 30 )"}, + {"tables_text_disabled", + "rgb( 163, 145, 99 )"}, + {"tables_border_disabled", + "rgb( 83, 85, 39 )"}, + {"charts_contour", + "rgb( 94, 118, 70 )"}, + {"textbrowser_text", + "rgb( 193, 175, 129 )"}, + {"textbrowser_base", + "rgb( 33, 35, 0 )"}, + {"textbrowser_text_selection", + "rgb( 223, 205, 159 )"}, + {"textbrowser_base_selection", + "rgb( 133, 135, 89 )"}, + {"scrollbar_base", + "rgb( 94, 118, 70 )"}, + {"scrollbar_handler", + "rgb( 174, 198, 150 )"}, + {"slider_handler", + "rgb( 94, 118, 70 )"}, + {"slider_bar_active", + "rgb( 163, 145, 99 )"}, + {"slider_bar_inactive", + "rgb( 113, 95, 49 )"}, + {"slider_bar_active_border", + "rgb( 183, 165, 119 )"}, + {"slider_handler_border", + "rgb( 163, 145, 99 )"}, + {"slider_handler_border_hover", + "rgb( 193, 175, 129 )"}, + {"outer-tabs_base", + "rgb( 14, 28, 0 )"}, + {"inner-tabs_base", + "rgb( 24, 48, 0 )"}, + {"sub-tabs_base", + "rgb( 34, 58, 10 )"}, + {"outer-tabs_tab_text_selected", + "rgb( 220, 211, 187 )"}, + {"outer-tabs_tab_text_unselected", + "rgb( 163, 145, 99 )"}, + {"outer-tabs_tab_text_hover", + "rgb( 193, 175, 129 )"}, + {"outer-tabs_tab_border", + "rgb( 220, 211, 187 )"}, + {"outer-tabs_tab_border_unselected", + "rgb( 163, 145, 99 )"}, + {"inner-tabs_tab_base", + "rgb( 24, 48, 0 )"}, + {"inner-tabs_tab_base_unselected", + "rgb( 14, 28, 0 )"}, + {"inner-tabs_pane_base", + "rgb( 24, 48, 0 )"}, + {"inner-tabs_border", + "rgb( 220, 211, 187 )"}, + {"inner-tabs_lines", + "rgb( 124, 148, 100 )"}, + {"sub-tabs_tab_base", + "rgb( 34, 58, 10 )"}, + {"sub-tabs_tab_base_unselected", + "rgb( 24, 48, 0 )"}, + {"sub-tabs_pane_base", + "rgb( 34, 58, 10 )"}, + {"sub-tabs_border", + "rgb( 220, 211, 187 )"}, + {"sub-tabs_tab_border_unselected", + "rgb( 163, 145, 99 )"} + }; + break; + case 4: + style_map = { + {"text_primary", + "rgb( 30, 21, 0 )"}, + {"text_secondary", + "rgb( 40, 31, 7 )"}, + {"text_disabled", + "rgb( 60, 51, 27 )"}, + {"tooltips_base", + "rgb( 40, 31, 7 )"}, + {"tooltips_text", + "rgb( 170, 161, 137 )"}, + {"tooltips_border", + "rgb( 210, 201, 177 )"}, + {"menu_text", + "rgb( 40, 31, 7 )"}, + {"menu_base", + "rgb( 210, 201, 177 )"}, + {"menu_base_hover", + "rgb( 170, 161, 137 )"}, + {"menu_base_dropdown_selection", + "rgb( 70, 61, 37 )"}, + {"window_base_primary", + "rgb( 230, 221, 197 )"}, + {"window_base_secondary", + "rgb( 170, 161, 137 )"}, + {"window_base_tertiary", + "rgb( 210, 201, 177 )"}, + {"border_primary", + "rgb( 80, 71, 47 )"}, + {"border_secondary", + "rgb( 100, 91, 67 )"}, + {"border_tertiary", + "rgb( 100, 91, 67 )"}, + {"buttons_base", + "rgb( 130, 121, 97 )"}, + {"buttons_base_hover", + "rgb( 140, 131, 107 )"}, + {"buttons_base_disabled", + "rgb( 160, 151, 127 )"}, + {"logs_switch_buttons_base_hover", + "rgb( 160, 151, 127 )"}, + {"stats_switch_buttons_frame_base", + "rgb( 170, 161, 137 )"}, + {"stats_switch_buttons_frame_border", + "rgb( 230, 221, 197 )"}, + {"stats_switch_buttons_base", + "rgb( 200, 191, 167 )"}, + {"stats_switch_buttons_base_hover", + "rgb( 180, 171, 147 )"}, + {"stats_switch_buttons_base_border_hover", + "rgb( 220, 211, 187 )"}, + {"globals_frames_base", + "rgb( 210, 201, 177 )"}, + {"globals_frames_border", + "rgb( 80, 71, 47 )"}, + {"globals_frames_lines", + "rgb( 60, 51, 27 )"}, + {"boxes_base_primary", + "rgb( 130, 121, 97 )"}, + {"boxes_base_secondary", + "rgb( 140, 131, 107 )"}, + {"boxes_base_tertiary", + "rgb( 130, 121, 97 )"}, + {"boxes_border_focus", + "rgb( 80, 71, 47 )"}, + {"boxes_base_disabled", + "rgb( 160, 151, 127 )"}, + {"boxes_base_off", + "rgb( 150, 141, 117 )"}, + {"linedit_text", + "rgb( 30, 21, 0 )"}, + {"linedit_base", + "rgb( 210, 201, 177 )"}, + {"linedit_base_focus", + "rgb( 230, 221, 197 )"}, + {"linedit_base_selection", + "rgb( 170, 161, 137 )"}, + {"linedit_base_disabled", + "rgb( 160, 151, 127 )"}, + {"tables_header", + "rgb( 130, 121, 97 )"}, + {"tables_base", + "rgb( 210, 201, 177 )"}, + {"tables_text_selection", + "rgb( 230, 221, 197 )"}, + {"tables_base_selection", + "rgb( 60, 51, 27 )"}, + {"tables_border", + "rgb( 80, 71, 47 )"}, + {"tables_base_disabled", + "rgb( 160, 151, 127 )"}, + {"tables_text_disabled", + "rgb( 130, 121, 97 )"}, + {"tables_border_disabled", + "rgb( 130, 121, 97 )"}, + {"charts_contour", + "rgb( 40, 31, 7 )"}, + {"textbrowser_text", + "rgb( 30, 21, 0 )"}, + {"textbrowser_base", + "rgb( 210, 201, 177 )"}, + {"textbrowser_text_selection", + "rgb( 230, 221, 197 )"}, + {"textbrowser_base_selection", + "rgb( 80, 71, 47 )"}, + {"scrollbar_base", + "rgb( 100, 91, 67 )"}, + {"scrollbar_handler", + "rgb( 210, 201, 177 )"}, + {"slider_handler", + "rgb( 100, 91, 67 )"}, + {"slider_bar_active", + "rgb( 120, 111, 87 )"}, + {"slider_bar_inactive", + "rgb( 40, 31, 7 )"}, + {"slider_bar_active_border", + "rgb( 150, 141, 117 )"}, + {"slider_handler_border", + "rgb( 220, 211, 187 )"}, + {"slider_handler_border_hover", + "rgb( 250, 241, 217 )"}, + {"outer-tabs_base", + "rgb( 170, 161, 137 )"}, + {"inner-tabs_base", + "rgb( 180, 171, 147 )"}, + {"sub-tabs_base", + "rgb( 190, 181, 157 )"}, + {"outer-tabs_tab_text_selected", + "rgb( 30, 21, 0 )"}, + {"outer-tabs_tab_text_unselected", + "rgb( 90, 81, 57 )"}, + {"outer-tabs_tab_text_hover", + "rgb( 50, 41, 17 )"}, + {"outer-tabs_tab_border", + "rgb( 80, 71, 47 )"}, + {"outer-tabs_tab_border_unselected", + "rgb( 100, 91, 67 )"}, + {"inner-tabs_tab_base", + "rgb( 180, 171, 147 )"}, + {"inner-tabs_tab_base_unselected", + "rgb( 170, 161, 137 )"}, + {"inner-tabs_pane_base", + "rgb( 180, 171, 147 )"}, + {"inner-tabs_border", + "rgb( 80, 71, 47 )"}, + {"inner-tabs_lines", + "rgb( 60, 51, 27 )"}, + {"sub-tabs_tab_base", + "rgb( 190, 181, 157 )"}, + {"sub-tabs_tab_base_unselected", + "rgb( 180, 171, 147 )"}, + {"sub-tabs_pane_base", + "rgb( 190, 181, 157 )"}, + {"sub-tabs_border", + "rgb( 80, 71, 47 )"}, + {"sub-tabs_tab_border_unselected", + "rgb( 100, 91, 67 )"} + }; + break; + default: + throw GenericException( "Unexpected WindowTheme ID: "+std::to_string(theme_id), true ); + break; + } + StyleSec::makeStyleSheet( stylesheet, style_map, icons_theme ); +} + + + +void StyleSec::makeStyleSheet( QString& ss, const std::unordered_map &style, const QString& theme ) +{ + ss= //////////////// + //// SHARED //// + "* {" + " color: "+style.at("text_primary")+";" + "}" + // frames + "QFrame," + "QWidget {" + " background-color: transparent;" + "}" + // tab widgets + "QTabWidget {" + " border: 0px;" + "}" + "QTabWidget::tab-bar {" + " alignment: left;" + "}" + "QTabBar {" + " background-color: transparent;" + "}" + "QTabBar::tab {" + " background-color: transparent;" + "}" + // tooltips + "QToolTip {" + " border: 1px solid "+style.at("tooltips_border")+";" + " color: "+style.at("tooltips_text")+";" + " background-color: "+style.at("tooltips_base")+";" + "}" + // check boxes + "QCheckBox::indicator {" + " width: 13px;" + " height: 13px;" + "}" + "QCheckBox::indicator:unchecked {" + " image: url(:/icons/icons/"+theme+"/checkbox_unchecked.png);" + "}" + "QCheckBox::indicator:indeterminate {" + " image: url(:/icons/icons/"+theme+"/checkbox_semichecked.png);" + "}" + "QCheckBox::indicator:checked {" + " image: url(:/icons/icons/"+theme+"/checkbox_checked.png);" + "}" + // radio buttons + "QRadioButton::indicator {" + " width: 13px;" + " height : 13px;" + "}" + "QRadioButton::indicator:unchecked {" + " image: url(:/icons/icons/"+theme+"/radiobutton_unchecked.png);" + "}" + "QRadioButton::indicator:checked {" + " image: url(:/icons/icons/"+theme+"/radiobutton_checked.png);" + "}" + // line edits + "QLineEdit {" + " color: "+style.at("linedit_text")+";" + " selection-color: "+style.at("linedit_text")+";" + " background-color: "+style.at("linedit_base")+";" + " selection-background-color: "+style.at("linedit_base_selection")+";" + "}" + "QLineEdit::focus {" + " background-color: "+style.at("linedit_base_focus")+";" + "}" + "QLineEdit:disabled {" + " background-color: "+style.at("linedit_base_disabled")+";" + "}" + // combo boxes + "QComboBox {" + " background-color: "+style.at("boxes_base_primary")+";" + " selection-background-color: "+style.at("boxes_base_secondary")+";" + "}" + "QComboBox::disabled {" + " background-color: "+style.at("boxes_base_disabled")+";" + "}" + "QComboBox QAbstractItemView {" + " border: 1px solid "+style.at("boxes_base_tertiary")+";" + " background-color: "+style.at("boxes_base_primary")+";" + "}" + // spin boxes + "QSpinBox {" + " border: 1px solid "+style.at("boxes_base_secondary")+";" + " border-radius: 4px;" + " background-color: "+style.at("boxes_base_primary")+";" + " selection-background-color: "+style.at("boxes_base_secondary")+";" + "}" + "QSpinBox::focus {" + " border-color: "+style.at("boxes_border_focus")+";" + "}" + "QSpinBox::disabled {" + " border-color: "+style.at("boxes_base_off")+";" + " color: "+style.at("text_disabled")+";" + " background-color: "+style.at("boxes_base_disabled")+";" + "}" + "QSpinBox::up-button," + "QSpinBox::down-button {" + " padding: 2px;" + " border-left: 1px solid "+style.at("boxes_border_focus")+";" + " background-color: "+style.at("boxes_base_secondary")+";" + "}" + "QSpinBox::up-button:hover," + "QSpinBox::down-button:hover {" + " background-color: "+style.at("boxes_base_tertiary")+";" + "}" + "QSpinBox::up-button:off," + "QSpinBox::down-button:off {" + " background-color: "+style.at("boxes_base_off")+";" + "}" + "QSpinBox::up-button:disabled," + "QSpinBox::down-button:disabled {" + " border-left-color: "+style.at("boxes_base_primary")+";" + " background-color: "+style.at("boxes_base_disabled")+";" + "}" + "QSpinBox::up-arrow {" + " width: 7px;" + " height: 7px;" + " padding: 2px;" + " image: url(:/icons/icons/"+theme+"/spinbox_add.png);" + "}" + "QSpinBox::up-arrow:off," + "QSpinBox::up-arrow:disabled {" + " image: url(:/icons/icons/midtone/spinbox_add.png);" + "}" + "QSpinBox::down-arrow {" + " width: 7px;" + " height: 7px;" + " padding: 2px;" + " image: url(:/icons/icons/"+theme+"/spinbox_sub.png);" + "}" + "QSpinBox::down-arrow:off," + "QSpinBox::down-arrow:disabled {" + " image: url(:/icons/icons/midtone/spinbox_sub.png);" + "}" + // scroll bars + "QScrollBar:horizontal {" + " height: 12px;" + " background-color: "+style.at("scrollbar_base")+";" + "}" + "QScrollBar::handle:horizontal {" + " min-width: 16px;" + " margin: 5px 12px 5px 12px;" + " background-color: "+style.at("scrollbar_handler")+";" + "}" + "QScrollBar::handle:horizontal:hover {" + " margin: 4px 12px 4px 12px;" + "}" + "QScrollBar:vertical {" + " width: 12px;" + " background-color: "+style.at("scrollbar_base")+";" + "}" + "QScrollBar::handle:vertical {" + " min-height: 16px;" + " margin: 12px 5px 12px 5px;" + " background-color: "+style.at("scrollbar_handler")+";" + "}" + "QScrollBar::handle:vertical:hover {" + " margin:12px 4px 12px 4px;" + "}" + // slider + "QSlider::groove:horizontal {" + " height: 2px;" + " border: 1px solid "+style.at("slider_bar_active_border")+";" + " background-color: "+style.at("slider_bar_active")+";" + "}" + "QSlider::add-page:horizontal {" + " border: 0px;" + " background-color: "+style.at("slider_bar_inactive")+";" + "}" + "QSlider::sub-page:horizontal {" + " border: 1px solid "+style.at("slider_bar_active_border")+";" + " background-color: "+style.at("slider_bar_active")+";" + "}" + "QSlider::handle:horizontal {" + " width: 12px;" + " margin: -5px 0px;" + " border: 1px solid "+style.at("slider_handler_border")+";" + " border-radius: 4px;" + " background-color: "+style.at("slider_handler")+";" + "}" + "QSlider::handle:hover:horizontal {" + " border: 1px solid "+style.at("slider_handler_border_hover")+";" + "}" + // charts + "QGraphicsView {" + " border-radius: 4px;" + " background-color: "+style.at("charts_contour")+";" + "}" + // tables, trees and headers + "QTreeWidget," + "QListWidget," + "QTableWidget {" + " background-color: "+style.at("tables_base")+";" + " selection-color: "+style.at("tables_text_selection")+";" + " selection-background-color: "+style.at("tables_base_selection")+";" + "}" + "QTreeWidget QScrollBar::handle:vertical," + "QTableWidget QScrollBar::handle:vertical {" + " padding: 12px;" + "}" + "QHeaderView {" + " background-color: "+style.at("tables_header")+";" + "}" + // text browser + "QTextBrowser {" + " color: "+style.at("textbrowser_text")+";" + " background-color: "+style.at("textbrowser_base")+";" + " selection-color: "+style.at("textbrowser_text_selection")+";" + " selection-background-color: "+style.at("textbrowser_base_selection")+";" + "}" + "QTextBrowser QScrollBar::handle:vertical {" + " padding: 12px;" + "}" + ////////////// + //// MENU //// + "QMenuBar {" + " color: "+style.at("menu_text")+";" + " background-color: "+style.at("menu_base")+";" + "}" + "QMenuBar::item:selected {" + " color: "+style.at("menu_text")+";" + " background-color: "+style.at("menu_base_hover")+";" + " border-radius: 4px;" + "}" + "QMenuBar::item:pressed {" + " color: "+style.at("menu_base")+";" + " background-color: "+style.at("menu_text")+";" + " border-radius: 0px;" + " border-top-left-radius: 4px;" + " border-top-right-radius: 4px;" + "}" + // menu dropdown + "QMenu {" + " color: "+style.at("menu_base")+";" + " background-color: "+style.at("menu_text")+";" + "}" + "QMenu::item:selected {" + " background-color: "+style.at("menu_base_dropdown_selection")+";" + "}" + ////////////// + //// MAIN //// + // window + "QWidget#mainwidget {" + " background-color: "+style.at("window_base_primary")+";" + "}" + // tabs buttons + "QFrame#frame_Tabs_Buttons {" + " background-color: "+style.at("window_base_primary")+";" + "}" + "QPushButton#button_Tab_Log," + "QPushButton#button_Tab_View," + "QPushButton#button_Tab_Conf {" + " border-top-left-radius: 8px;" + " border-bottom-left-radius: 8px;" + " background-color: "+style.at("window_base_secondary")+";" + "}" + "QPushButton#button_Tab_Log::flat," + "QPushButton#button_Tab_View::flat," + "QPushButton#button_Tab_Conf::flat {" + " background-color: "+style.at("window_base_primary")+";" + "}" + "QPushButton#button_Tab_Log::flat:hover," + "QPushButton#button_Tab_View::flat:hover," + "QPushButton#button_Tab_Conf::flat:hover {" + " background-color: "+style.at("window_base_tertiary")+";" + "}" + // tabs pages + "QStackedWidget#stacked_Tabs_Pages {" + " background-color: "+style.at("window_base_secondary")+";" + "}" + ////////////// + //// LOGS //// + // switcher buttons + "QFrame#frame_Logs_Down {" + " background-color: "+style.at("window_base_secondary")+";" + "}" + "QPushButton#button_Logs_Down:hover {" + " border-radius: 16px;" + " background-color: "+style.at("logs_switch_buttons_base_hover")+";" + " icon: url(:/icons/icons/"+theme+"/down.png);" + "}" + "QFrame#frame_Logs_Up {" + " background-color: "+style.at("window_base_secondary")+";" + "}" + "QPushButton#button_Logs_Up::flat:hover {" + " border-radius: 16px;" + " background-color: "+style.at("logs_switch_buttons_base_hover")+";" + " icon: url(:/icons/icons/"+theme+"/up.png);" + "}" + // web servers buttons + "QPushButton#button_LogFiles_Apache," + "QPushButton#button_LogFiles_Nginx," + "QPushButton#button_LogFiles_Iis {" + " border-radius: 4px;" + " background-color: "+style.at("buttons_base")+";" + "}" + "QPushButton#button_LogFiles_Apache::flat," + "QPushButton#button_LogFiles_Nginx::flat," + "QPushButton#button_LogFiles_Iis::flat {" + " border: 1px solid "+style.at("buttons_base")+";" + " color: "+style.at("text_secondary")+";" + " background-color: "+style.at("window_base_secondary")+";" + "}" + "QPushButton#button_LogFiles_Apache::flat:hover," + "QPushButton#button_LogFiles_Nginx::flat:hover," + "QPushButton#button_LogFiles_Iis::flat:hover {" + " border: 1px solid "+style.at("border_secondary")+";" + " color: "+style.at("text_primary")+";" + "}" + "QPushButton#button_LogFiles_Apache::disabled," + "QPushButton#button_LogFiles_Nginx::disabled," + "QPushButton#button_LogFiles_Iis::disabled {" + " color: "+style.at("text_disabled")+";" + " background-color: "+style.at("buttons_base_disabled")+";" + "}" + // logs list + "QTreeWidget#listLogFiles::indicator {" + " width: 13px;" + " height: 13px;" + " margin-left: -4px;" + " margin-right: 4px;" + "}" + "QTreeWidget#listLogFiles::indicator:unchecked {" + " image: url(:/icons/icons/"+theme+"/checkbox_unchecked.png);" + "}" + "QTreeWidget#listLogFiles::indicator:checked {" + " image: url(:/icons/icons/"+theme+"/checkbox_checked.png);" + "}" + // view file button + "QPushButton#button_LogFiles_ViewFile {" + " border-radius: 4px;" + " background-color: "+style.at("buttons_base")+";" + "}" + "QPushButton#button_LogFiles_ViewFile:hover {" + " border: 1px solid "+style.at("border_primary")+";" + "}" + "QPushButton#button_LogFiles_ViewFile::disabled {" + " background-color: "+style.at("buttons_base_disabled")+";" + "}" + // refresh button + "QPushButton#button_LogFiles_RefreshList {" + " border: 1px solid "+style.at("buttons_base_disabled")+";" + " border-radius: 16px;" + " background-color: transparent;" + "}" + "QPushButton#button_LogFiles_RefreshList:hover {" + " border: 1px solid "+style.at("border_primary")+";" + "}" + // parse logs button + "QPushButton#button_MakeStats_Start {" + " border-radius: 4px;" + " background-color: "+style.at("buttons_base")+";" + "}" + "QPushButton#button_MakeStats_Start:hover {" + " border: 1px solid "+style.at("border_primary")+";" + " background-color: "+style.at("buttons_base_hover")+";" + "}" + "QPushButton#button_MakeStats_Start::disabled {" + " color: "+style.at("text_disabled")+";" + " background-color: "+style.at("buttons_base_disabled")+";" + "}" + /////////////// + //// STATS //// + // statistics tabs buttons + "QFrame#frame_Stats_Buttons {" + " border: 2px solid "+style.at("stats_switch_buttons_frame_border")+";" + " border-bottom-left-radius: 4px;" + " border-bottom-right-radius: 4px;" + " background-color: "+style.at("stats_switch_buttons_frame_base")+";" + "}" + "QPushButton#button_Tab_StatsWarn," + "QPushButton#button_Tab_StatsSpeed," + "QPushButton#button_Tab_StatsCount," + "QPushButton#button_Tab_StatsDay," + "QPushButton#button_Tab_StatsRelat," + "QPushButton#button_Tab_StatsGlob {" + " border-radius: 4px;" + " background-color: "+style.at("stats_switch_buttons_base")+";" + "}" + "QPushButton#button_Tab_StatsWarn::flat," + "QPushButton#button_Tab_StatsSpeed::flat," + "QPushButton#button_Tab_StatsCount::flat," + "QPushButton#button_Tab_StatsDay::flat," + "QPushButton#button_Tab_StatsRelat::flat," + "QPushButton#button_Tab_StatsGlob::flat {" + " background-color: transparent;" + "}" + "QPushButton#button_Tab_StatsWarn::flat:hover," + "QPushButton#button_Tab_StatsSpeed::flat:hover," + "QPushButton#button_Tab_StatsCount::flat:hover," + "QPushButton#button_Tab_StatsDay::flat:hover," + "QPushButton#button_Tab_StatsRelat::flat:hover," + "QPushButton#button_Tab_StatsGlob::flat:hover {" + " border: 1px solid "+style.at("stats_switch_buttons_base_border_hover")+";" + " background-color: "+style.at("stats_switch_buttons_base_hover")+";" + "}" + // draw buttons + "QPushButton#button_StatsWarn_Update," + "QPushButton#button_StatsWarn_Draw," + "QPushButton#button_StatsSpeed_Draw," + "QPushButton#button_StatsCount_Draw," + "QPushButton#button_StatsDay_Draw," + "QPushButton#button_StatsRelat_Draw," + "QPushButton#button_StatsGlob_Draw {" + " border-radius: 4px;" + " background-color: "+style.at("buttons_base")+";" + "}" + "QPushButton#button_StatsWarn_Update:hover," + "QPushButton#button_StatsWarn_Draw:hover," + "QPushButton#button_StatsSpeed_Draw:hover," + "QPushButton#button_StatsCount_Draw:hover," + "QPushButton#button_StatsDay_Draw:hover," + "QPushButton#button_StatsRelat_Draw:hover," + "QPushButton#button_StatsGlob_Draw:hover {" + " border: 1px solid "+style.at("border_secondary")+";" + " background-color: "+style.at("buttons_base_hover")+";" + "}" + "QPushButton#button_StatsWarn_Update::disabled {" + " border: 1px solid "+style.at("buttons_base")+";" + " background-color: "+style.at("buttons_base_disabled")+";" + " icon: url(:/icons/icons/midtone/save.png);" + "}" + // stats warn + "QTableWidget#table_StatsWarn::indicator {" + " width: 13px;" + " height: 13px;" + "}" + "QTableWidget#table_StatsWarn::indicator:unchecked {" + " image: url(:/icons/icons/"+theme+"/checkbox_unchecked.png);" + "}" + "QTableWidget#table_StatsWarn::indicator:checked {" + " image: url(:/icons/icons/"+theme+"/checkbox_checked.png);" + "}" + "QTableWidget#table_StatsWarn QScrollBar::handle:vertical {" + " padding: 12px;" + "}" + // stats count + "QScrollArea#scrollArea_StatsCount {" + " background-color: "+style.at("window_base_secondary")+";" + "}" + "QWidget#scrollAreaContent_StatsCount {" + " background-color: transparent;" + "}" + "QPushButton#button_StatsCount_Protocol," + "QPushButton#button_StatsCount_Method," + "QPushButton#button_StatsCount_Uri," + "QPushButton#button_StatsCount_Query," + "QPushButton#button_StatsCount_Response," + "QPushButton#button_StatsCount_Referrer," + "QPushButton#button_StatsCount_Cookie," + "QPushButton#button_StatsCount_UserAgent," + "QPushButton#button_StatsCount_Client {" + " border-radius: 4px;" + " background-color: "+style.at("border_primary")+";" + "}" + "QPushButton#button_StatsCount_Protocol::flat," + "QPushButton#button_StatsCount_Method::flat," + "QPushButton#button_StatsCount_Uri::flat," + "QPushButton#button_StatsCount_Query::flat," + "QPushButton#button_StatsCount_Response::flat," + "QPushButton#button_StatsCount_Referrer::flat," + "QPushButton#button_StatsCount_Cookie::flat," + "QPushButton#button_StatsCount_UserAgent::flat," + "QPushButton#button_StatsCount_Client::flat {" + " border: 1px solid "+style.at("buttons_base")+";" + " background-color: "+style.at("buttons_base_disabled")+";" + "}" + "QPushButton#button_StatsCount_Protocol::flat:hover," + "QPushButton#button_StatsCount_Method::flat:hover," + "QPushButton#button_StatsCount_Uri::flat:hover," + "QPushButton#button_StatsCount_Query::flat:hover," + "QPushButton#button_StatsCount_Response::flat:hover," + "QPushButton#button_StatsCount_Referrer::flat:hover," + "QPushButton#button_StatsCount_Cookie::flat:hover," + "QPushButton#button_StatsCount_UserAgent::flat:hover," + "QPushButton#button_StatsCount_Client::flat:hover {" + " border: 1px solid "+style.at("border_primary")+";" + " background-color: "+style.at("buttons_base")+";" + "}" + // stats globals + "QFrame#frame_StatsGlob_WebServers {" + " border-radius: 4px;" + " border: 1px solid "+style.at("buttons_base")+";" + "}" + "QPushButton#button_StatsGlob_Apache," + "QPushButton#button_StatsGlob_Nginx," + "QPushButton#button_StatsGlob_Iis {" + " border-radius: 4px;" + " background-color: "+style.at("buttons_base")+";" + "}" + "QPushButton#button_StatsGlob_Apache::flat," + "QPushButton#button_StatsGlob_Nginx::flat," + "QPushButton#button_StatsGlob_Iis::flat {" + " border: 1px solid "+style.at("buttons_base")+";" + " color: "+style.at("text_secondary")+";" + " background-color: "+style.at("window_base_secondary")+";" + "}" + "QPushButton#button_StatsGlob_Apache::flat:hover," + "QPushButton#button_StatsGlob_Nginx::flat:hover," + "QPushButton#button_StatsGlob_Iis::flat:hover {" + " border: 1px solid "+style.at("border_secondary")+";" + " color: "+style.at("text_primary")+";" + "}" + "QPushButton#button_StatsGlob_Apache::disabled," + "QPushButton#button_StatsGlob_Nginx::disabled," + "QPushButton#button_StatsGlob_Iis::disabled {" + " color: "+style.at("text_disabled")+";" + " background-color: "+style.at("buttons_base_disabled")+";" + "}" + "QScrollArea#scrollArea_StatsGlob_Recur," + "QScrollArea#scrollArea_StatsGlob_Perf," + "QScrollArea#scrollArea_StatsGlob_Traffic," + "QScrollArea#scrollArea_StatsGlob_Work {" + " border: 1px solid "+style.at("globals_frames_border")+";" + " background-color: "+style.at("globals_frames_base")+";" + "}" + // styled frames + "QFrame#frame_StatsWarn_Logs," + "QFrame#frame_StatsDay_Date," + "QFrame#frame_StatsRelat_Field {" + " border: 1px solid "+style.at("border_tertiary")+";" + "}" + // lines separators + "QFrame#gline_StatsWarn_1," + "QFrame#gline_StatsWarn_2," + "QFrame#gline_StatsWarn_3," + "QFrame#gline_StatsDay_1," + "QFrame#gline_StatsDay_2," + "QFrame#gline_StatsRelat_1," + "QFrame#gline_StatsGlob_Recur_1," + "QFrame#gline_StatsGlob_Recur_2," + "QFrame#gline_StatsGlob_Recur_3," + "QFrame#gline_StatsGlob_Perf_1," + "QFrame#gline_StatsGlob_Perf_2," + "QFrame#gline_StatsGlob_Traffic_1," + "QFrame#gline_StatsGlob_Traffic_2," + "QFrame#gline_StatsGlob_Work_1," + "QFrame#gline_StatsGlob_Work_2 {" + " border: 1px solid "+style.at("globals_frames_base")+";" + " background-color: "+style.at("globals_frames_lines")+";" + "}" + "QFrame#gline_StatsSpeed_1," + "QFrame#gline_StatsCount_1 {" + " border: 1px solid "+style.at("globals_frames_base")+";" + " margin: 2px 0px 3px 0px;" + " background-color: "+style.at("globals_frames_lines")+";" + "}" + ///////////////// + //// CONFIGS //// + // outer tabs + "QTabWidget#ConfTabs QTabBar::tab {" + " margin-bottom: 4px;" + " padding: 8px 6px;" + " border: 1px solid "+style.at("outer-tabs_tab_border")+";" + " border-left: 4px solid "+style.at("outer-tabs_tab_border")+";" + " border-right: 0px;" + " border-top-left-radius: 4px;" + " border-bottom-left-radius: 4px;" + "}" + "QTabWidget#ConfTabs QTabBar::tab:selected {" + " color: "+style.at("outer-tabs_tab_text_selected")+";" + "}" + "QTabWidget#ConfTabs QTabBar::tab:!selected {" + " border-color: "+style.at("outer-tabs_tab_border_unselected")+";" + " border-left: 1px solid "+style.at("outer-tabs_tab_border_unselected")+";" + " color: "+style.at("outer-tabs_tab_text_unselected")+";" + "}" + "QTabWidget#ConfTabs QTabBar::tab:!selected:hover {" + " border-color: "+style.at("outer-tabs_tab_border")+";" + " color: "+style.at("outer-tabs_tab_text_hover")+";" + "}" + // inner tabs + "QTabWidget#tabs_ConfGeneral QTabBar::tab," + "QTabWidget#tabs_ConfLogs QTabBar::tab {" + " margin: 0px;" + " margin-right: 4px;" + " padding: 6px 8px;" + " border: 1px solid "+style.at("inner-tabs_border")+";" + " border-bottom: 0px;" + " border-top-left-radius: 4px;" + " border-bottom-left-radius: 0px;" + " border-top-right-radius: 4px;" + " background-color: "+style.at("inner-tabs_tab_base")+";" + "}" + "QTabWidget#tabs_ConfGeneral QTabBar::tab:!selected," + "QTabWidget#tabs_ConfLogs QTabBar::tab:!selected {" + " background-color: "+style.at("inner-tabs_tab_base_unselected")+";" + "}" + "QTabWidget#tabs_ConfGeneral::pane," + "QTabWidget#tabs_ConfLogs::pane {" + " border: 1px solid "+style.at("inner-tabs_border")+";" + " border-top-right-radius: 4px;" + " border-bottom-left-radius: 4px;" + " border-bottom-right-radius: 4px;" + " background-color: "+style.at("inner-tabs_pane_base")+";" + "}" + // sub tabs + "QTabWidget#tabs_ConfApache QTabBar," + "QTabWidget#tabs_ConfNginx QTabBar," + "QTabWidget#tabs_ConfIis QTabBar {" + " border: 0px;" + "}" + "QTabWidget#tabs_ConfApache QTabBar::tab," + "QTabWidget#tabs_ConfNginx QTabBar::tab," + "QTabWidget#tabs_ConfIis QTabBar::tab {" + " background-color: "+style.at("sub-tabs_tab_base")+";" + "}" + "QTabWidget#tabs_ConfApache QTabBar::tab:!selected," + "QTabWidget#tabs_ConfNginx QTabBar::tab:!selected," + "QTabWidget#tabs_ConfIis QTabBar::tab:!selected {" + " border: 1px solid "+style.at("sub-tabs_tab_border_unselected")+";" + " background-color: "+style.at("sub-tabs_tab_base_unselected")+";" + "}" + "QTabWidget#tabs_ConfApache::pane," + "QTabWidget#tabs_ConfNginx::pane," + "QTabWidget#tabs_ConfIis::pane {" + " border: 1px solid "+style.at("sub-tabs_border")+";" + " background-color: "+style.at("sub-tabs_pane_base")+";" + "}" + // panes + "QWidget#confGeneral," + "QWidget#confLogs {" + " border: 1px solid "+style.at("outer-tabs_tab_border")+";" + " border-top-right-radius: 4px;" + " border-bottom-left-radius: 4px;" + " border-bottom-right-radius: 4px;" + " background-color: "+style.at("outer-tabs_base")+";" + "}" + "QWidget#tab_confWindow," + "QWidget#tab_confTextBrowser," + "QWidget#tab_confCharts," + "QWidget#tab_confDatabases," + "QWidget#tab_confLogs_Default," + "QWidget#tab_confLogs_Control," + "QWidget#tab_confLogs_Apache," + "QWidget#tab_confLogs_Nginx," + "QWidget#tab_confLogs_Iis {" + " border: 0px;" + " background-color: "+style.at("inner-tabs_base")+";" + "}" + "QWidget#tab_confApache_Paths," + "QWidget#tab_confApache_Formats," + "QWidget#tab_confApache_Warnlists," + "QWidget#tab_confApache_Blacklists," + "QWidget#tab_confNginx_Paths," + "QWidget#tab_confNginx_Formats," + "QWidget#tab_confNginx_Warnlists," + "QWidget#tab_confNginx_Blacklists," + "QWidget#tab_confIis_Paths," + "QWidget#tab_confIis_Formats," + "QWidget#tab_confIis_Warnlists," + "QWidget#tab_confIis_Blacklists {" + " background-color: "+style.at("sub-tabs_base")+";" + "}" + // line separators + "QFrame#gline_ConfTextBrowser {" + " border: 2px solid "+style.at("inner-tabs_base")+";" + " margin: 13px 0px 14px 0px;" + " background-color: "+style.at("inner-tabs_lines")+";" + "}" + // save buttons + "QPushButton#button_ConfDatabases_Data_Save," + "QPushButton#button_ConfDatabases_Hashes_Save," + "QPushButton#button_ConfApache_Path_Save," + "QPushButton#button_ConfApache_Format_Save," + "QPushButton#button_ConfNginx_Path_Save," + "QPushButton#button_ConfNginx_Format_Save," + "QPushButton#button_ConfIis_Path_Save," + "QPushButton#button_ConfIis_Format_Save {" + " border: 1px solid "+style.at("border_primary")+";" + " border-radius: 4px;" + " background-color: "+style.at("buttons_base")+";" + "}" + "QPushButton#button_ConfDatabases_Data_Save:hover," + "QPushButton#button_ConfDatabases_Hashes_Save:hover," + "QPushButton#button_ConfApache_Path_Save:hover," + "QPushButton#button_ConfApache_Format_Save:hover," + "QPushButton#button_ConfNginx_Path_Save:hover," + "QPushButton#button_ConfNginx_Format_Save:hover," + "QPushButton#button_ConfIis_Path_Save:hover," + "QPushButton#button_ConfIis_Format_Save:hover {" + " border-color: "+style.at("border_secondary")+";" + " background-color: "+style.at("buttons_base_hover")+";" + "}" + "QPushButton#button_ConfDatabases_Data_Save::disabled," + "QPushButton#button_ConfDatabases_Hashes_Save::disabled," + "QPushButton#button_ConfApache_Path_Save::disabled," + "QPushButton#button_ConfApache_Path_Save::disabled," + "QPushButton#button_ConfNginx_Path_Save::disabled," + "QPushButton#button_ConfNginx_Format_Save::disabled," + "QPushButton#button_ConfIis_Path_Save::disabled," + "QPushButton#button_ConfIis_Format_Save::disabled {" + " border-color: "+style.at("buttons_base")+";" + " background-color: "+style.at("buttons_base_disabled")+";" + " icon: url(:/icons/icons/midtone/save.png);" + "}" + // sample buttons + "QPushButton#button_ConfApache_Format_Sample," + "QPushButton#button_ConfNginx_Format_Sample," + "QPushButton#button_ConfIis_Format_Sample {" + " border: 1px solid "+style.at("border_primary")+";" + " border-radius: 4px;" + " background-color: "+style.at("buttons_base")+";" + "}" + "QPushButton#button_ConfApache_Format_Sample:hover," + "QPushButton#button_ConfNginx_Format_Sample:hover," + "QPushButton#button_ConfIis_Format_Sample:hover {" + " border-color: "+style.at("border_secondary")+";" + " background-color: "+style.at("buttons_base_hover")+";" + "}" + // sample previews + "QWidget#scrollAreaContent_ConfApache_Format_Sample," + "QWidget#scrollAreaContent_ConfNginx_Format_Sample," + "QWidget#scrollAreaContent_ConfIis_Format_Sample {" + " border: 1px solid "+style.at("border_primary")+";" + " background-color: "+style.at("textbrowser_base")+";" + "}" + // help buttons + "QPushButton#button_ConfApache_Format_Help," + "QPushButton#button_ConfNginx_Format_Help," + "QPushButton#button_ConfIis_Format_Help {" + " border: 1px solid "+style.at("border_primary")+";" + " border-radius: 4px;" + " background-color: "+style.at("buttons_base")+";" + "}" + "QPushButton#button_ConfApache_Format_Help:hover," + "QPushButton#button_ConfNginx_Format_Help:hover," + "QPushButton#button_ConfIis_Format_Help:hover {" + " border-color: "+style.at("border_secondary")+";" + " background-color: "+style.at("buttons_base_hover")+";" + "}" + // warnlists / blacklists + "QListWidget#list_ConfApache_Warnlist_List," + "QListWidget#list_ConfApache_Blacklist_List," + "QListWidget#list_ConfNginx_Warnlist_List," + "QListWidget#list_ConfNginx_Blacklist_List," + "QListWidget#list_ConfIis_Warnlist_List," + "QListWidget#list_ConfIis_Blacklist_List {" + " padding: 4px;" + " border: 1px solid "+style.at("tables_border")+";" + "}" + "QListWidget#list_ConfApache_Warnlist_List::disabled," + "QListWidget#list_ConfApache_Blacklist_List::disabled," + "QListWidget#list_ConfNginx_Warnlist_List::disabled," + "QListWidget#list_ConfNginx_Blacklist_List::disabled," + "QListWidget#list_ConfIis_Warnlist_List::disabled," + "QListWidget#list_ConfIis_Blacklist_List::disabled {" + " border: 1px solid "+style.at("tables_border_disabled")+";" + " color: "+style.at("tables_text_disabled")+";" + " background-color: "+style.at("tables_base_disabled")+";" + "}" + "QListWidget#list_ConfApache_Warnlist_List::item," + "QListWidget#list_ConfApache_Blacklist_List::item," + "QListWidget#list_ConfNginx_Warnlist_List::item," + "QListWidget#list_ConfNginx_Blacklist_List::item," + "QListWidget#list_ConfIis_Warnlist_List::item," + "QListWidget#list_ConfIis_Blacklist_List::item {" + " padding: 4px;" + "}" + // lists buttons + "QPushButton#button_ConfApache_Warnlist_Add," + "QPushButton#button_ConfApache_Warnlist_Remove," + "QPushButton#button_ConfApache_Warnlist_Up," + "QPushButton#button_ConfApache_Warnlist_Down," + "QPushButton#button_ConfApache_Blacklist_Add," + "QPushButton#button_ConfApache_Blacklist_Remove," + "QPushButton#button_ConfApache_Blacklist_Up," + "QPushButton#button_ConfApache_Blacklist_Down," + "QPushButton#button_ConfNginx_Warnlist_Add," + "QPushButton#button_ConfNginx_Warnlist_Remove," + "QPushButton#button_ConfNginx_Warnlist_Up," + "QPushButton#button_ConfNginx_Warnlist_Down," + "QPushButton#button_ConfNginx_Blacklist_Add," + "QPushButton#button_ConfNginx_Blacklist_Remove," + "QPushButton#button_ConfNginx_Blacklist_Up," + "QPushButton#button_ConfNginx_Blacklist_Down," + "QPushButton#button_ConfIis_Warnlist_Add," + "QPushButton#button_ConfIis_Warnlist_Remove," + "QPushButton#button_ConfIis_Warnlist_Up," + "QPushButton#button_ConfIis_Warnlist_Down," + "QPushButton#button_ConfIis_Blacklist_Add," + "QPushButton#button_ConfIis_Blacklist_Remove," + "QPushButton#button_ConfIis_Blacklist_Up," + "QPushButton#button_ConfIis_Blacklist_Down {" + " border: 1px solid "+style.at("border_primary")+";" + " border-radius: 4px;" + " background-color: "+style.at("buttons_base")+";" + "}" + "QPushButton#button_ConfApache_Warnlist_Add:hover," + "QPushButton#button_ConfApache_Warnlist_Remove:hover," + "QPushButton#button_ConfApache_Warnlist_Up:hover," + "QPushButton#button_ConfApache_Warnlist_Down:hover," + "QPushButton#button_ConfApache_Blacklist_Add:hover," + "QPushButton#button_ConfApache_Blacklist_Remove:hover," + "QPushButton#button_ConfApache_Blacklist_Up:hover," + "QPushButton#button_ConfApache_Blacklist_Down:hover," + "QPushButton#button_ConfNginx_Warnlist_Add:hover," + "QPushButton#button_ConfNginx_Warnlist_Remove:hover," + "QPushButton#button_ConfNginx_Warnlist_Up:hover," + "QPushButton#button_ConfNginx_Warnlist_Down:hover," + "QPushButton#button_ConfNginx_Blacklist_Add:hover," + "QPushButton#button_ConfNginx_Blacklist_Remove:hover," + "QPushButton#button_ConfNginx_Blacklist_Up:hover," + "QPushButton#button_ConfNginx_Blacklist_Down:hover," + "QPushButton#button_ConfIis_Warnlist_Add:hover," + "QPushButton#button_ConfIis_Warnlist_Remove:hover," + "QPushButton#button_ConfIis_Warnlist_Up:hover," + "QPushButton#button_ConfIis_Warnlist_Down:hover," + "QPushButton#button_ConfIis_Blacklist_Add:hover," + "QPushButton#button_ConfIis_Blacklist_Remove:hover," + "QPushButton#button_ConfIis_Blacklist_Up:hover," + "QPushButton#button_ConfIis_Blacklist_Down:hover {" + " border-color: "+style.at("border_secondary")+";" + " background-color: "+style.at("buttons_base_hover")+";" + "}" + "QPushButton#button_ConfApache_Warnlist_Add::disabled," + "QPushButton#button_ConfApache_Blacklist_Add::disabled," + "QPushButton#button_ConfNginx_Warnlist_Add::disabled," + "QPushButton#button_ConfNginx_Blacklist_Add::disabled," + "QPushButton#button_ConfIis_Warnlist_Add::disabled," + "QPushButton#button_ConfIis_Blacklist_Add::disabled {" + " border-color: "+style.at("buttons_base")+";" + " background-color: "+style.at("buttons_base_disabled")+";" + " icon: url(:/icons/icons/add.png), #fff;" + "}" + "QPushButton#button_ConfApache_Warnlist_Remove::disabled," + "QPushButton#button_ConfApache_Blacklist_Remove::disabled," + "QPushButton#button_ConfNginx_Warnlist_Remove::disabled," + "QPushButton#button_ConfNginx_Blacklist_Remove::disabled," + "QPushButton#button_ConfIis_Warnlist_Remove::disabled," + "QPushButton#button_ConfIis_Blacklist_Remove::disabled {" + " border-color: "+style.at("buttons_base")+";" + " background-color: "+style.at("buttons_base_disabled")+";" + " icon: url(:/icons/icons/rem.png), #fff;" + "}" + "QPushButton#button_ConfApache_Warnlist_Up::disabled," + "QPushButton#button_ConfApache_Blacklist_Up::disabled," + "QPushButton#button_ConfNginx_Warnlist_Up::disabled," + "QPushButton#button_ConfNginx_Blacklist_Up::disabled," + "QPushButton#button_ConfIis_Warnlist_Up::disabled," + "QPushButton#button_ConfIis_Blacklist_Up::disabled {" + " border-color: "+style.at("buttons_base")+";" + " background-color: "+style.at("buttons_base_disabled")+";" + " icon: url(:/icons/icons/up.png), #fff;" + "}" + "QPushButton#button_ConfApache_Warnlist_Down::disabled," + "QPushButton#button_ConfApache_Blacklist_Down::disabled," + "QPushButton#button_ConfNginx_Warnlist_Down::disabled," + "QPushButton#button_ConfNginx_Blacklist_Down::disabled," + "QPushButton#button_ConfIis_Warnlist_Down::disabled," + "QPushButton#button_ConfIis_Blacklist_Down::disabled {" + " border-color: "+style.at("buttons_base")+";" + " background-color: "+style.at("buttons_base_disabled")+";" + " icon: url(:/icons/icons/down.png), #fff;" + "}"; +} diff --git a/logdoctor/utilities/stylesheets.h b/logdoctor/utilities/stylesheets.h new file mode 100644 index 00000000..ca760b58 --- /dev/null +++ b/logdoctor/utilities/stylesheets.h @@ -0,0 +1,37 @@ +#ifndef STYLESHEETS_H +#define STYLESHEETS_H + +#include + +#include + + +//! StyleSec +/*! + Utilities for the stylesheets +*/ +class StyleSec +{ +public: + StyleSec(); + + //! Provides the requested stylesheet + /*! + \param stylesheet Will hold the stylesheet + \param icons_theme The theme selected for the Icons + \param theme_id The theme selected for the Window + */ + static void getStyleSheet( QString& stylesheet, const QString& icons_theme, const int& theme_id ); + +private: + + //! Builds the final stylesheet upon the generic model + /*! + \param ss Will hold the stylesheet + \param style The key-value pairs to be applied at the generic + \param theme The theme selected for the Icons + */ + static void makeStyleSheet( QString& ss, const std::unordered_map &style, const QString& theme ); +}; + +#endif // STYLESHEETS_H diff --git a/logdoctor/utilities/vectors.cpp b/logdoctor/utilities/vectors.cpp new file mode 100644 index 00000000..47b6e516 --- /dev/null +++ b/logdoctor/utilities/vectors.cpp @@ -0,0 +1,27 @@ + +#include "vectors.h" + + +template +VecOps::VecOps() +{ + +} + + +template +const bool VecOps::contains(const std::vector& list, const T& flag ) +{ + bool result = false; + for ( const T& item : list ) { + if ( item == flag ) { + result = true; + break; + } + } + return result; +} + + +template class VecOps; +template class VecOps; diff --git a/logdoctor/utilities/vectors.h b/logdoctor/utilities/vectors.h new file mode 100644 index 00000000..0218046b --- /dev/null +++ b/logdoctor/utilities/vectors.h @@ -0,0 +1,27 @@ +#ifndef VECOPS_H +#define VECOPS_H + +#include +#include + + +//! VecOps +/*! + Utilities for the vectors +*/ +template +class VecOps +{ +public: + VecOps(); + + //! Checks if a vector contains an element + /*! + \param list The target vector + \param flag The element to search for + \return Whether the list does contain the flag or not + */ + static const bool contains( const std::vector& list, const T& flag ); +}; + +#endif // VECOPS_H diff --git a/version.txt b/version.txt new file mode 100644 index 00000000..d1442284 --- /dev/null +++ b/version.txt @@ -0,0 +1 @@ +.:!¦version¦!:.2.01.:!¦version¦!:.