From 6409aa91ff1bb269bc07db18f7121e35e9591d1d Mon Sep 17 00:00:00 2001 From: QWQAQ Date: Tue, 24 Aug 2021 11:16:07 +0800 Subject: [PATCH 001/349] Initial commit --- .gitignore | 15 ++ LICENSE | 674 +++++++++++++++++++++++++++++++++++++++++++++++++++++ README.md | 1 + 3 files changed, 690 insertions(+) create mode 100644 .gitignore create mode 100644 LICENSE create mode 100644 README.md diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..66fd13c90 --- /dev/null +++ b/.gitignore @@ -0,0 +1,15 @@ +# Binaries for programs and plugins +*.exe +*.exe~ +*.dll +*.so +*.dylib + +# Test binary, built with `go test -c` +*.test + +# Output of the go coverage tool, specifically when used with LiteIDE +*.out + +# Dependency directories (remove the comment below to include it) +# vendor/ diff --git a/LICENSE b/LICENSE new file mode 100644 index 000000000..f288702d2 --- /dev/null +++ b/LICENSE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/README.md b/README.md new file mode 100644 index 000000000..dcd625210 --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +# Artalk-API-Go \ No newline at end of file From 6960d5a4fa45e33a5fdc2fa83aecfb2b8b591a35 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Tue, 24 Aug 2021 13:27:00 +0800 Subject: [PATCH 002/349] =?UTF-8?q?=F0=9F=9A=A7=20Start=20the=20project.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 3 + artalk-go.example.yaml | 59 ++++ cli/cmd/root.go | 129 +++++++++ cli/cmd/serve.go | 26 ++ cli/main.go | 7 + config/config.go | 50 ++++ go.mod | 13 + go.sum | 633 +++++++++++++++++++++++++++++++++++++++++ http/http.go | 5 + 9 files changed, 925 insertions(+) create mode 100644 artalk-go.example.yaml create mode 100644 cli/cmd/root.go create mode 100644 cli/cmd/serve.go create mode 100644 cli/main.go create mode 100644 config/config.go create mode 100644 go.mod create mode 100644 go.sum create mode 100644 http/http.go diff --git a/.gitignore b/.gitignore index 66fd13c90..1b11232c8 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,6 @@ # Dependency directories (remove the comment below to include it) # vendor/ + +/config.yaml +/artalk-go.yaml \ No newline at end of file diff --git a/artalk-go.example.yaml b/artalk-go.example.yaml new file mode 100644 index 000000000..02ae377ed --- /dev/null +++ b/artalk-go.example.yaml @@ -0,0 +1,59 @@ +# 网站名 +site_name: 'XXX 的博客' + +# HTTP Server 监听地址 +http_addr: ':23366' + +# 数据文件 +db_file: '' + +# 日志 +log: + on: true # 总开关 + filepath: '' # 日志文件路径 + +# 支持跨域访问的域名 +allow_origin: + - http://localhost:8080 # 或 '*' 跨域无限制 + +# 管理员账户 +admin_users: + - + nick: 'admin' + email: 'admin@example.com' + password: '' + badge_name: '管理员' + badge_color: '#FF6C00' + +# 评论审核 +moderation: + pending_default: false # 发表新评论默认为 “待审状态” + +# 验证码 +captcha: + on: true # 总开关 + # ↓↓ 在 {timeout} 秒内,若再次评论超过 {limit} 次则需要验证码 + timeout: 2400 # 超时:重置评论次数统计(单位:秒) + limit: 3 # 激活验证码的评论次数(设置为 0 总是需要验证码) + +# 邮件通知 +email: + on: true # 总开关 + admin_addr: 'example@example.com' # 管理员邮箱地址(文章收到评论时通知) + sender_type: 'smtp' # 发送方式(ali_dm or smtp) + mail_title: '您在 [站名] 收到了新的回复' + mail_title_to_admin: '您的文章收到了新的回复' + mail_tpl_name: 'default.html' # 邮件模板文件(/email-tpl 目录下存放) + smtp: + host: 'smtp.qq.com' + port: 465 + smtp_auth: true + username: 'example@qq.com' + password: '' + smtp_secure: 'ssl' + from_addr: 'example@qq.com' # 发件人邮箱 + from_name: '站名' # 发件人显示的名称 + ali_dm: # https://help.aliyun.com/document_detail/29414.html + access_key_id: '' # 阿里云颁发给用户的访问服务所用的密钥 ID + access_key_secret: '' # 用于加密的密钥 + account_name: 'example@example.com' # 管理控制台中配置的发信地址 diff --git a/cli/cmd/root.go b/cli/cmd/root.go new file mode 100644 index 000000000..4fd5f84d6 --- /dev/null +++ b/cli/cmd/root.go @@ -0,0 +1,129 @@ +package cmd + +import ( + "fmt" + "os" + + "github.com/ArtalkJS/Artalk-API-Go/config" + "github.com/rifflock/lfshook" + "github.com/sirupsen/logrus" + "github.com/spf13/cobra" + "github.com/spf13/viper" + prefixed "github.com/x-cray/logrus-prefixed-formatter" +) + +var Banner = ` + ________ ________ _________ ________ ___ ___ __ +|\ __ \|\ __ \|\___ ___\\ __ \|\ \ |\ \|\ \ +\ \ \|\ \ \ \|\ \|___ \ \_\ \ \|\ \ \ \ \ \ \/ /|_ + \ \ __ \ \ _ _\ \ \ \ \ \ __ \ \ \ \ \ ___ \ + \ \ \ \ \ \ \\ \| \ \ \ \ \ \ \ \ \ \____\ \ \\ \ \ + \ \__\ \__\ \__\\ _\ \ \__\ \ \__\ \__\ \_______\ \__\\ \__\ + \|__|\|__|\|__|\|__| \|__| \|__|\|__|\|_______|\|__| \|__| + +Artalk: A Fast, Slight & Funny Comment System. +More detail on https://github.com/ArtalkJS/Artalk +(c) 2021 artalk.js.org` + +var cfgFile string + +var rootCmd = &cobra.Command{ + Use: "artalk-go", + Short: "Artalk: A Fast, Slight & Funny Comment System", + Long: Banner, + Run: func(cmd *cobra.Command, args []string) { + fmt.Println(Banner) + fmt.Println() + fmt.Println("NOTE: add `-h` flag to show help about any command.") + }, +} + +func Execute() { + cobra.CheckErr(rootCmd.Execute()) +} + +func init() { + cobra.OnInitialize(initConfig) + cobra.OnInitialize(initLog) + cobra.OnInitialize(initDB) + + rootCmd.SetVersionTemplate("Artalk-GO {{printf \"version %s\" .Version}}\n") + rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "配置文件路径 (defaults are './artalk-go.conf.yaml', './config.yaml')") +} + +func initConfig() { + config.Init(cfgFile) +} + +func initLog() { + // 初始化日志 + stdFormatter := &prefixed.TextFormatter{ + DisableTimestamp: true, + ForceFormatting: true, + ForceColors: true, + DisableColors: false, + } // 命令行输出格式 + fileFormatter := &prefixed.TextFormatter{ + FullTimestamp: true, + TimestampFormat: "2006-01-02.15:04:05.000000", + ForceFormatting: true, + ForceColors: false, + DisableColors: true, + } // 文件输出格式 + + // logrus.SetLevel(logrus.DebugLevel) + logrus.SetFormatter(stdFormatter) + logrus.SetOutput(os.Stdout) + + // 文件保存 + pathMap := lfshook.PathMap{ + logrus.InfoLevel: config.Instance.LogFile, + logrus.DebugLevel: config.Instance.LogFile, + logrus.ErrorLevel: config.Instance.LogFile, + } + logrus.AddHook(lfshook.NewHook( + pathMap, + fileFormatter, + )) +} + +func initDB() { +} + +//// 捷径函数 //// + +func flag(cmd *cobra.Command, name string, defaultVal interface{}, usage string) { + f := cmd.PersistentFlags() + switch y := defaultVal.(type) { + case bool: + f.Bool(name, y, usage) + case int: + f.Int(name, y, usage) + case string: + f.String(name, y, usage) + } + viper.SetDefault(name, defaultVal) +} + +func flagP(cmd *cobra.Command, name, shorthand string, defaultVal interface{}, usage string) { + f := cmd.PersistentFlags() + switch y := defaultVal.(type) { + case bool: + f.BoolP(name, shorthand, y, usage) + case int: + f.IntP(name, shorthand, y, usage) + case string: + f.StringP(name, shorthand, y, usage) + } + viper.SetDefault(name, defaultVal) +} + +func flagV(cmd *cobra.Command, name string, defaultVal interface{}, usage string) { + flag(cmd, name, defaultVal, usage) + viper.BindPFlag(name, cmd.PersistentFlags().Lookup(name)) +} + +func flagPV(cmd *cobra.Command, name, shorthand string, defaultVal interface{}, usage string) { + flagP(cmd, name, shorthand, defaultVal, usage) + viper.BindPFlag(name, cmd.PersistentFlags().Lookup(name)) +} diff --git a/cli/cmd/serve.go b/cli/cmd/serve.go new file mode 100644 index 000000000..cc8a306de --- /dev/null +++ b/cli/cmd/serve.go @@ -0,0 +1,26 @@ +package cmd + +import ( + "fmt" + + "github.com/ArtalkJS/Artalk-API-Go/http" + "github.com/spf13/cobra" +) + +var serveCmd = &cobra.Command{ + Use: "serve", + Version: rootCmd.Version, + Aliases: []string{"server"}, + Short: "启动服务器", + Long: rootCmd.Long, + Run: func(cmd *cobra.Command, args []string) { + fmt.Println(Banner) + fmt.Println("----------------------") + http.Run() + }, + Args: cobra.NoArgs, +} + +func init() { + rootCmd.AddCommand(serveCmd) +} diff --git a/cli/main.go b/cli/main.go new file mode 100644 index 000000000..521d9d7a0 --- /dev/null +++ b/cli/main.go @@ -0,0 +1,7 @@ +package main + +import "github.com/ArtalkJS/Artalk-API-Go/cli/cmd" + +func main() { + cmd.Execute() +} diff --git a/config/config.go b/config/config.go new file mode 100644 index 000000000..b9211b5cf --- /dev/null +++ b/config/config.go @@ -0,0 +1,50 @@ +package config + +import ( + "fmt" + "strings" + + "github.com/sirupsen/logrus" + "github.com/spf13/viper" +) + +// Instance 配置实例 +var Instance *Config + +// Config 配置 +// @link https://godoc.org/github.com/mitchellh/mapstructure +type Config struct { + SiteName string `mapstructure:"site_name"` // 网站名 + HttpAddr string `mapstructure:"http_addr"` // HTTP Server 监听地址 + + DbFile string `mapstructure:"db_file"` // 数据文件 + LogFile string `mapstructure:"log_file"` // 日志文件 +} + +// Init 初始化配置 +func Init(cfgFile string) { + viper.SetConfigType("yaml") + + if cfgFile != "" { + // Use config file from the flag. + viper.SetConfigFile(cfgFile) + } else { + // Find config file in path. + viper.AddConfigPath(".") + viper.SetConfigName("artalk-go.yaml") + } + + viper.SetEnvPrefix("ATG") + viper.AutomaticEnv() + viper.SetEnvKeyReplacer(strings.NewReplacer(".", "_")) + + if err := viper.ReadInConfig(); err == nil { + fmt.Println("Using config file:", viper.ConfigFileUsed()) + } + + Instance = &Config{} + err := viper.Unmarshal(&Instance) + if err != nil { + logrus.Errorf("unable to decode into struct, %v", err) + } +} diff --git a/go.mod b/go.mod new file mode 100644 index 000000000..f955bb317 --- /dev/null +++ b/go.mod @@ -0,0 +1,13 @@ +module github.com/ArtalkJS/Artalk-API-Go + +go 1.16 + +require ( + github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect + github.com/onsi/gomega v1.16.0 // indirect + github.com/rifflock/lfshook v0.0.0-20180920164130-b9218ef580f5 + github.com/sirupsen/logrus v1.8.1 + github.com/spf13/cobra v1.2.1 + github.com/spf13/viper v1.8.1 + github.com/x-cray/logrus-prefixed-formatter v0.5.2 +) diff --git a/go.sum b/go.sum new file mode 100644 index 000000000..bf1caef61 --- /dev/null +++ b/go.sum @@ -0,0 +1,633 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= +cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= +cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= +cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= +cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= +cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= +cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= +cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= +cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= +cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= +cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= +cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= +cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= +cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= +cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= +cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg= +cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8= +cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0= +cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= +cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= +cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= +cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= +cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= +cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= +cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= +cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= +cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= +cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= +cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= +cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= +cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= +cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= +cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= +cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= +cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= +cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= +dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= +github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= +github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= +github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= +github.com/bketelsen/crypt v0.0.4/go.mod h1:aI6NrJ0pMGgvZKL1iVgXLnfIFJtfV+bKCoqOes/6LfM= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= +github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= +github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= +github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= +github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= +github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= +github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= +github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= +github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= +github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= +github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= +github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= +github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= +github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= +github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= +github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= +github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= +github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= +github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= +github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= +github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= +github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= +github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= +github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/magiconair/properties v1.8.5 h1:b6kJs+EmPFMYGkow9GiUyCyOvIwYetYJ3fSaWak/Gls= +github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= +github.com/mattn/go-colorable v0.0.9 h1:UVL0vNpWh04HeJXV0KLcaT7r06gOH2l4OW6ddYRUIY4= +github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/mattn/go-isatty v0.0.3 h1:ns/ykhmWi7G9O+8a448SecJU3nSMBXJfqQkl0upE1jI= +github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d h1:5PJl274Y63IEHC+7izoQE9x6ikvDFZS2mDVS3drnohI= +github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= +github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= +github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= +github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= +github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= +github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= +github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.4.1 h1:CpVNEelQCZBooIPDn+AR3NpivK/TIKU8bDxdASFVQag= +github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= +github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= +github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc= +github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= +github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= +github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +github.com/onsi/gomega v1.16.0 h1:6gjqkI8iiRHMvdccRJM8rVKjCWk6ZIm6FTm3ddIe4/c= +github.com/onsi/gomega v1.16.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= +github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/pelletier/go-toml v1.9.3 h1:zeC5b1GviRUyKYd6OJPvBU/mcVDVoL1OhT17FCt5dSQ= +github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/rifflock/lfshook v0.0.0-20180920164130-b9218ef580f5 h1:mZHayPoR0lNmnHyvtYjDeq0zlVHn9K/ZXoy17ylucdo= +github.com/rifflock/lfshook v0.0.0-20180920164130-b9218ef580f5/go.mod h1:GEXHk5HgEKCvEIIrSpFI3ozzG5xOKA2DVlEX/gGnewM= +github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= +github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= +github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= +github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= +github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s= +github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= +github.com/spf13/afero v1.6.0 h1:xoax2sJ2DT8S8xA2paPFjDCScCNeWsg75VG0DLRreiY= +github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= +github.com/spf13/cast v1.3.1 h1:nFm6S0SMdyzrzcmThSipiEubIDy8WEXKNZ0UOgiRpng= +github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cobra v1.2.1 h1:+KmjbUw1hriSNMF55oPrkZcb27aECyrj8V2ytv7kWDw= +github.com/spf13/cobra v1.2.1/go.mod h1:ExllRjgxM/piMAM+3tAZvg8fsklGAf3tPfi+i8t68Nk= +github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= +github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/viper v1.8.1 h1:Kq1fyeebqsBfbjZj4EL7gj2IO0mMaiyjYUWcUsl2O44= +github.com/spf13/viper v1.8.1/go.mod h1:o0Pch8wJ9BVSWGQMbra6iw0oQ5oktSIBaujf1rJH9Ns= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s= +github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= +github.com/x-cray/logrus-prefixed-formatter v0.5.2 h1:00txxvfBM9muc0jiLIEAkAcIMJzfthRT6usrui8uGmg= +github.com/x-cray/logrus-prefixed-formatter v0.5.2/go.mod h1:2duySbKsL6M18s5GU7VPsoEPHyzalCE06qoARUCeBBE= +github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs= +go.etcd.io/etcd/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= +go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ= +go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= +go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= +go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= +go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= +go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= +go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= +golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= +golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= +golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= +golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= +golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= +golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= +golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= +golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= +golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= +golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.0.0-20210428140749-89ef3d95e781 h1:DzZ89McO9/gWPsQXS/FVKAlG02ZjaQ6AlZRBimEYOd0= +golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007 h1:gG67DSER+11cZvqIMb8S8bt0vZtiN6xWYARwirrOSfE= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= +golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= +golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= +golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= +google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= +google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= +google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= +google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= +google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= +google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= +google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= +google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= +google.golang.org/api v0.44.0/go.mod h1:EBOGZqzyhtvMDoxwS97ctnh0zUmYY6CxqXsc1AvkYD8= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= +google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= +google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= +google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= +google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= +google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= +google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= +google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= +google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= +google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= +google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/ini.v1 v1.62.0 h1:duBzk771uxoUuOlyRLkHsygud9+5lrlGjdFBb4mSKDU= +gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= +honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= +rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= +rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= diff --git a/http/http.go b/http/http.go new file mode 100644 index 000000000..5e3a0a074 --- /dev/null +++ b/http/http.go @@ -0,0 +1,5 @@ +package http + +func Run() { + +} From 170ea5a524daeccc2fa575389d9411c267cf4ae5 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Tue, 24 Aug 2021 20:38:31 +0800 Subject: [PATCH 003/349] Complete the basic model & config. --- .gitignore | 5 +-- .vscode/launch.json | 7 ++++ .vscode/settings.json | 9 +++++ artalk-go.example.yaml | 20 ++++++----- cli/cmd/root.go | 38 +++++++++++++-------- config/config.go | 75 +++++++++++++++++++++++++++++++++++++++--- config/config_test.go | 8 +++++ email-tpl/.gitignore | 3 ++ email-tpl/default.html | 7 ++++ go.mod | 10 ++++++ go.sum | 39 ++++++++++++++++++---- lib/db.go | 14 ++++++++ model/comment.go | 26 +++++++++++++++ model/page.go | 9 +++++ model/user.go | 23 +++++++++++++ 15 files changed, 257 insertions(+), 36 deletions(-) create mode 100644 .vscode/launch.json create mode 100644 .vscode/settings.json create mode 100644 config/config_test.go create mode 100644 email-tpl/.gitignore create mode 100644 email-tpl/default.html create mode 100644 lib/db.go create mode 100644 model/comment.go create mode 100644 model/page.go create mode 100644 model/user.go diff --git a/.gitignore b/.gitignore index 1b11232c8..6f60a2546 100644 --- a/.gitignore +++ b/.gitignore @@ -14,5 +14,6 @@ # Dependency directories (remove the comment below to include it) # vendor/ -/config.yaml -/artalk-go.yaml \ No newline at end of file +/artalk-go.yaml + +/local diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 000000000..f980ab98c --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,7 @@ +{ + // 使用 IntelliSense 了解相关属性。 + // 悬停以查看现有属性的描述。 + // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [] +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 000000000..088284993 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,9 @@ +{ + "cSpell.words": [ + "artalk", + "gorm", + "lfshook", + "smpt", + "sqlite" + ] +} \ No newline at end of file diff --git a/artalk-go.example.yaml b/artalk-go.example.yaml index 02ae377ed..922353cea 100644 --- a/artalk-go.example.yaml +++ b/artalk-go.example.yaml @@ -5,40 +5,42 @@ site_name: 'XXX 的博客' http_addr: ':23366' # 数据文件 -db_file: '' +db: + type: 'sqlite' # 支持 mysql 和 sqlite + dsn: './local/artalk-go.db' # 日志 log: - on: true # 总开关 - filepath: '' # 日志文件路径 + enabled: true # 总开关 + filename: './local/artalk-go.log' # 日志文件路径 -# 支持跨域访问的域名 +# 允许跨域访问的域名 allow_origin: - http://localhost:8080 # 或 '*' 跨域无限制 # 管理员账户 admin_users: - - nick: 'admin' + name: 'admin' email: 'admin@example.com' password: '' badge_name: '管理员' badge_color: '#FF6C00' # 评论审核 -moderation: +moderator: pending_default: false # 发表新评论默认为 “待审状态” # 验证码 captcha: - on: true # 总开关 + enabled: true # 总开关 # ↓↓ 在 {timeout} 秒内,若再次评论超过 {limit} 次则需要验证码 timeout: 2400 # 超时:重置评论次数统计(单位:秒) - limit: 3 # 激活验证码的评论次数(设置为 0 总是需要验证码) + comment_limit: 3 # 激活验证码的评论次数(设置为 0 总是需要验证码) # 邮件通知 email: - on: true # 总开关 + enabled: true # 总开关 admin_addr: 'example@example.com' # 管理员邮箱地址(文章收到评论时通知) sender_type: 'smtp' # 发送方式(ali_dm or smtp) mail_title: '您在 [站名] 收到了新的回复' diff --git a/cli/cmd/root.go b/cli/cmd/root.go index 4fd5f84d6..487283d5a 100644 --- a/cli/cmd/root.go +++ b/cli/cmd/root.go @@ -21,7 +21,7 @@ var Banner = ` \ \__\ \__\ \__\\ _\ \ \__\ \ \__\ \__\ \_______\ \__\\ \__\ \|__|\|__|\|__|\|__| \|__| \|__|\|__|\|_______|\|__| \|__| -Artalk: A Fast, Slight & Funny Comment System. +Artalk: A Fast, Slight & Delightful Comment System. More detail on https://github.com/ArtalkJS/Artalk (c) 2021 artalk.js.org` @@ -29,7 +29,7 @@ var cfgFile string var rootCmd = &cobra.Command{ Use: "artalk-go", - Short: "Artalk: A Fast, Slight & Funny Comment System", + Short: "Artalk: A Fast, Slight & Delightful Comment System", Long: Banner, Run: func(cmd *cobra.Command, args []string) { fmt.Println(Banner) @@ -51,40 +51,50 @@ func init() { rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "配置文件路径 (defaults are './artalk-go.conf.yaml', './config.yaml')") } +// 初始化配置 func initConfig() { config.Init(cfgFile) } +// 初始化日志 func initLog() { - // 初始化日志 + if !config.Instance.Log.Enabled { + return + } + + // 命令行输出格式 stdFormatter := &prefixed.TextFormatter{ DisableTimestamp: true, ForceFormatting: true, ForceColors: true, DisableColors: false, - } // 命令行输出格式 + } + + // 文件输出格式 fileFormatter := &prefixed.TextFormatter{ FullTimestamp: true, TimestampFormat: "2006-01-02.15:04:05.000000", ForceFormatting: true, ForceColors: false, DisableColors: true, - } // 文件输出格式 + } // logrus.SetLevel(logrus.DebugLevel) logrus.SetFormatter(stdFormatter) logrus.SetOutput(os.Stdout) - // 文件保存 - pathMap := lfshook.PathMap{ - logrus.InfoLevel: config.Instance.LogFile, - logrus.DebugLevel: config.Instance.LogFile, - logrus.ErrorLevel: config.Instance.LogFile, + if config.Instance.Log.Filename != "" { + // 文件保存 + pathMap := lfshook.PathMap{ + logrus.InfoLevel: config.Instance.Log.Filename, + logrus.DebugLevel: config.Instance.Log.Filename, + logrus.ErrorLevel: config.Instance.Log.Filename, + } + logrus.AddHook(lfshook.NewHook( + pathMap, + fileFormatter, + )) } - logrus.AddHook(lfshook.NewHook( - pathMap, - fileFormatter, - )) } func initDB() { diff --git a/config/config.go b/config/config.go index b9211b5cf..ab4e67f5d 100644 --- a/config/config.go +++ b/config/config.go @@ -4,6 +4,7 @@ import ( "fmt" "strings" + "github.com/ArtalkJS/Artalk-API-Go/model" "github.com/sirupsen/logrus" "github.com/spf13/viper" ) @@ -14,13 +15,79 @@ var Instance *Config // Config 配置 // @link https://godoc.org/github.com/mitchellh/mapstructure type Config struct { - SiteName string `mapstructure:"site_name"` // 网站名 - HttpAddr string `mapstructure:"http_addr"` // HTTP Server 监听地址 + SiteName string `mapstructure:"site_name"` // 网站名 + HttpAddr string `mapstructure:"http_addr"` // HTTP Server 监听地址 + DB DBConf `mapstructure:"db"` // 数据文件 + Log LogConf `mapstructure:"log"` // 日志文件 + AllowOrigin []string `mapstructure:"allow_origin"` // 允许跨域访问的域名 + AdminUsers []model.User `mapstructure:"admin_users"` + Moderator ModeratorConf `mapstructure:"moderator"` + Captcha CaptchaConf `mapstructure:"captcha"` + Email EmailConf `mapstructure:"email"` +} + +type DBConf struct { + Type DBType `mapstructure:"type"` + Dsn string `mapstructure:"dsn"` +} + +type LogConf struct { + Enabled bool `mapstructure:"enabled"` + Filename string `mapstructure:"filename"` +} - DbFile string `mapstructure:"db_file"` // 数据文件 - LogFile string `mapstructure:"log_file"` // 日志文件 +type ModeratorConf struct { + PendingDefault bool `mapstructure:"pending_default"` } +type CaptchaConf struct { + Enabled bool `mapstructure:"enabled"` + Timeout uint `mapstructure:"timeout"` + CommentLimit uint `mapstructure:"comment_limit"` +} + +type EmailConf struct { + Enabled bool `mapstructure:"enabled"` + AdminAddr string `mapstructure:"admin_addr"` + SenderType EmailSenderType `mapstructure:"sender_type"` + MailTitle string `mapstructure:"mail_title"` + MailTitleToAdmin string `mapstructure:"mail_title_to_admin"` + MailTplName string `mapstructure:"mail_tpl_name"` + SMTP SMTPConf `mapstructure:"smtp"` + AliDM AliDMConf `mapstructure:"ali_dm"` +} + +type SMTPConf struct { + Host string `mapstructure:"host"` + Port uint `mapstructure:"port"` + SMTPAuth bool `mapstructure:"smtp_auth"` + Username string `mapstructure:"username"` + Password string `mapstructure:"password"` + SMTPSecure string `mapstructure:"smtp_secure"` + FromAddr string `mapstructure:"from_addr"` + FromName string `mapstructure:"from_name"` +} + +type AliDMConf struct { + AccessKeyId string `mapstructure:"access_key_id"` + AccessKeySecret string `mapstructure:"access_key_secret"` + AccountName string `mapstructure:"account_name"` +} + +type DBType string + +const ( + MySql DBType = "mysql" + Sqlite DBType = "sqlite" +) + +type EmailSenderType string + +const ( + SMTP EmailSenderType = "smpt" + AliDM EmailSenderType = "ali_dm" +) + // Init 初始化配置 func Init(cfgFile string) { viper.SetConfigType("yaml") diff --git a/config/config_test.go b/config/config_test.go new file mode 100644 index 000000000..6914b2321 --- /dev/null +++ b/config/config_test.go @@ -0,0 +1,8 @@ +package config + +import "testing" + +func TestInit(t *testing.T) { + Init("../artalk-go.example.yaml") + t.Log(Instance) +} diff --git a/email-tpl/.gitignore b/email-tpl/.gitignore new file mode 100644 index 000000000..b9f7c8625 --- /dev/null +++ b/email-tpl/.gitignore @@ -0,0 +1,3 @@ +* +!.gitignore +!default.html \ No newline at end of file diff --git a/email-tpl/default.html b/email-tpl/default.html new file mode 100644 index 000000000..93a644aee --- /dev/null +++ b/email-tpl/default.html @@ -0,0 +1,7 @@ +

Hi, {{comment.nick}}:

+

+您在 {{conf.site_name}} 收到了回复: +

{{reply.content_html}}
+

+

传送门 >

+

Powered By Artalk

diff --git a/go.mod b/go.mod index f955bb317..fce4bc9fa 100644 --- a/go.mod +++ b/go.mod @@ -3,11 +3,21 @@ module github.com/ArtalkJS/Artalk-API-Go go 1.16 require ( + github.com/fsnotify/fsnotify v1.5.0 // indirect + github.com/mattn/go-colorable v0.1.8 // indirect + github.com/mattn/go-isatty v0.0.13 // indirect github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect github.com/onsi/gomega v1.16.0 // indirect github.com/rifflock/lfshook v0.0.0-20180920164130-b9218ef580f5 github.com/sirupsen/logrus v1.8.1 + github.com/spf13/cast v1.4.1 // indirect github.com/spf13/cobra v1.2.1 github.com/spf13/viper v1.8.1 github.com/x-cray/logrus-prefixed-formatter v0.5.2 + golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 // indirect + golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf // indirect + golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b // indirect + golang.org/x/text v0.3.7 // indirect + gorm.io/driver/sqlite v1.1.4 + gorm.io/gorm v1.21.13 ) diff --git a/go.sum b/go.sum index bf1caef61..8b9042230 100644 --- a/go.sum +++ b/go.sum @@ -68,8 +68,9 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.m github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/fsnotify/fsnotify v1.5.0 h1:NO5hkcB+srp1x6QmwvNZLeaOgbM8cmBTN32THzjvu2k= +github.com/fsnotify/fsnotify v1.5.0/go.mod h1:BX0DCEr5pT4jm2CnQdVP1lFV521fcCNcyEeNp4DQQDk= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= @@ -167,6 +168,11 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= +github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= +github.com/jinzhu/now v1.1.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= +github.com/jinzhu/now v1.1.2 h1:eVKgfIdy9b6zbWBMgFpfDPoAMifwSZagU9HmEU6zgiI= +github.com/jinzhu/now v1.1.2/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= @@ -182,10 +188,15 @@ github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/magiconair/properties v1.8.5 h1:b6kJs+EmPFMYGkow9GiUyCyOvIwYetYJ3fSaWak/Gls= github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= -github.com/mattn/go-colorable v0.0.9 h1:UVL0vNpWh04HeJXV0KLcaT7r06gOH2l4OW6ddYRUIY4= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= -github.com/mattn/go-isatty v0.0.3 h1:ns/ykhmWi7G9O+8a448SecJU3nSMBXJfqQkl0upE1jI= +github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ0s8= +github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-isatty v0.0.13 h1:qdl+GuBjcsKKDco5BsxPJlId98mSWNKqYA+Co0SC1yA= +github.com/mattn/go-isatty v0.0.13/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-sqlite3 v1.14.5 h1:1IdxlwTNazvbKJQSxoJ5/9ECbEeaTTyeU7sEAZ5KKTQ= +github.com/mattn/go-sqlite3 v1.14.5/go.mod h1:WVKg1VTActs4Qso6iwGbiFih2UIHo0ENGwNd0Lj+XmI= github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d h1:5PJl274Y63IEHC+7izoQE9x6ikvDFZS2mDVS3drnohI= github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= @@ -237,8 +248,9 @@ github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIK github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/spf13/afero v1.6.0 h1:xoax2sJ2DT8S8xA2paPFjDCScCNeWsg75VG0DLRreiY= github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= -github.com/spf13/cast v1.3.1 h1:nFm6S0SMdyzrzcmThSipiEubIDy8WEXKNZ0UOgiRpng= github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cast v1.4.1 h1:s0hze+J0196ZfEMTs80N7UlFt0BDuQ7Q+JDnHiMWKdA= +github.com/spf13/cast v1.4.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cobra v1.2.1 h1:+KmjbUw1hriSNMF55oPrkZcb27aECyrj8V2ytv7kWDw= github.com/spf13/cobra v1.2.1/go.mod h1:ExllRjgxM/piMAM+3tAZvg8fsklGAf3tPfi+i8t68Nk= github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= @@ -283,8 +295,9 @@ golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 h1:HWj/xjIHfjYU5nVXpTM0s39J9CbLn7Cc5a7IC5rwsMQ= +golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -403,6 +416,7 @@ golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -429,9 +443,14 @@ golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210510120138-977fb7262007 h1:gG67DSER+11cZvqIMb8S8bt0vZtiN6xWYARwirrOSfE= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf h1:2ucpDCmfkl8Bd/FsLtiD653Wf96cW37s+iGx93zsu4k= +golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b h1:9zKuko04nR4gjZ4+DNjHqRlAJqbJETHwiNKDqTfOjfE= +golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -439,8 +458,9 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -621,6 +641,11 @@ gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gorm.io/driver/sqlite v1.1.4 h1:PDzwYE+sI6De2+mxAneV9Xs11+ZyKV6oxD3wDGkaNvM= +gorm.io/driver/sqlite v1.1.4/go.mod h1:mJCeTFr7+crvS+TRnWc5Z3UvwxUN1BGBLMrf5LA9DYw= +gorm.io/gorm v1.20.7/go.mod h1:0HFTzE/SqkGTzK6TlDPPQbAYCluiVvhzoA1+aVyzenw= +gorm.io/gorm v1.21.13 h1:JU5A4yVemRjdMndJ0oZU7VX+Nr2ICE3C60U5bgR6mHE= +gorm.io/gorm v1.21.13/go.mod h1:F+OptMscr0P2F2qU97WT1WimdH9GaQPoDW7AYd5i2Y0= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/lib/db.go b/lib/db.go new file mode 100644 index 000000000..74548104f --- /dev/null +++ b/lib/db.go @@ -0,0 +1,14 @@ +package lib + +import ( + "github.com/ArtalkJS/Artalk-API-Go/config" + "gorm.io/driver/sqlite" + "gorm.io/gorm" +) + +var DB *gorm.DB + +func OpenDb(dbFile string) (err error) { + DB, err = gorm.Open(sqlite.Open(config.Instance.DB.Dsn), &gorm.Config{}) + return +} diff --git a/model/comment.go b/model/comment.go new file mode 100644 index 000000000..9161f266e --- /dev/null +++ b/model/comment.go @@ -0,0 +1,26 @@ +package model + +import "gorm.io/gorm" + +type CommentType string + +const ( + CommentCollapsed CommentType = "collapsed" + CommentPending CommentType = "pengding" + CommentDeleted CommentType = "deleted" +) + +type Comment struct { + gorm.Model + Content string + + UserID uint + PageID uint + User User `gorm:"foreignKey:UserID"` + Page Page `gorm:"foreignKey:PageID"` + + Rid uint + UA string + IP string + Type CommentType +} diff --git a/model/page.go b/model/page.go new file mode 100644 index 000000000..a2ffd2cce --- /dev/null +++ b/model/page.go @@ -0,0 +1,9 @@ +package model + +import "gorm.io/gorm" + +type Page struct { + gorm.Model + Name string + Link string +} diff --git a/model/user.go b/model/user.go new file mode 100644 index 000000000..c11c72b5f --- /dev/null +++ b/model/user.go @@ -0,0 +1,23 @@ +package model + +import "gorm.io/gorm" + +type UserType string + +const ( + UserBanned UserType = "banned" + UserAdmin UserType = "admin" +) + +type User struct { + gorm.Model + Name string `mapstructure:"name"` + Email string `mapstructure:"email"` + Link string `mapstructure:"link"` + Password string `mapstructure:"password"` + BadgeName string `mapstructure:"badge_name"` + BadgeColor string `mapstructure:"badge_color"` + LastIP string + LastUA string + Type UserType +} From 77d418fa99144f616e9d6dfb1b504145b5aff3df Mon Sep 17 00:00:00 2001 From: qwqcode Date: Wed, 25 Aug 2021 23:48:52 +0800 Subject: [PATCH 004/349] Basic route, captcha, jwt, makefile. Signed-off-by: qwqcode --- .gitignore | 7 ++- .goreleaser.yml | 32 +++++++++++ artalk-go.example.yaml | 6 ++ cli/main.go | 7 --- {cli/cmd => cmd}/root.go | 8 ++- {cli/cmd => cmd}/serve.go | 2 +- config/config.go | 24 ++++---- config/config_test.go | 5 +- frontend/index.html | 12 ++++ go.mod | 17 +++++- go.sum | 63 ++++++++++++++++++--- http/api_admin.go | 20 +++++++ http/api_captcha.go | 42 ++++++++++++++ http/api_main.go | 78 ++++++++++++++++++++++++++ http/http.go | 66 ++++++++++++++++++++++ http/pkged.go | 12 ++++ http/route.go | 56 +++++++++++++++++++ http/utils.go | 112 ++++++++++++++++++++++++++++++++++++++ lib/db.go | 31 ++++++++++- lib/gorm-logger.go | 61 +++++++++++++++++++++ lib/utils.go | 25 +++++++++ main.go | 7 +++ makefile | 24 ++++++++ model/page.go | 14 ++++- model/user.go | 4 ++ 25 files changed, 699 insertions(+), 36 deletions(-) create mode 100644 .goreleaser.yml delete mode 100644 cli/main.go rename {cli/cmd => cmd}/root.go (94%) rename {cli/cmd => cmd}/serve.go (93%) create mode 100644 frontend/index.html create mode 100644 http/api_admin.go create mode 100644 http/api_captcha.go create mode 100644 http/api_main.go create mode 100644 http/pkged.go create mode 100644 http/route.go create mode 100644 http/utils.go create mode 100644 lib/gorm-logger.go create mode 100644 lib/utils.go create mode 100644 main.go create mode 100644 makefile diff --git a/.gitignore b/.gitignore index 6f60a2546..8551dde21 100644 --- a/.gitignore +++ b/.gitignore @@ -14,6 +14,9 @@ # Dependency directories (remove the comment below to include it) # vendor/ -/artalk-go.yaml +artalk-go.yaml -/local +local/ +bin/ + +dist/ diff --git a/.goreleaser.yml b/.goreleaser.yml new file mode 100644 index 000000000..5dbd55950 --- /dev/null +++ b/.goreleaser.yml @@ -0,0 +1,32 @@ +# This is an example .goreleaser.yml file with some sane defaults. +# Make sure to check the documentation at http://goreleaser.com +before: + hooks: + # You may remove this if you don't use go modules. + - go mod tidy + # you may remove this if you don't need go generate + - go generate ./... +builds: + - env: + - CGO_ENABLED=0 + goos: + - linux + - windows + - darwin +archives: + - replacements: + darwin: Darwin + linux: Linux + windows: Windows + 386: i386 + amd64: x86_64 +checksum: + name_template: 'checksums.txt' +snapshot: + name_template: "{{ incpatch .Version }}-next" +changelog: + sort: asc + filters: + exclude: + - '^docs:' + - '^test:' diff --git a/artalk-go.example.yaml b/artalk-go.example.yaml index 922353cea..ead781c20 100644 --- a/artalk-go.example.yaml +++ b/artalk-go.example.yaml @@ -4,6 +4,9 @@ site_name: 'XXX 的博客' # HTTP Server 监听地址 http_addr: ':23366' +# 加密密钥 +app_key: 'QXJ0YWxrLmpz' + # 数据文件 db: type: 'sqlite' # 支持 mysql 和 sqlite @@ -27,6 +30,9 @@ admin_users: badge_name: '管理员' badge_color: '#FF6C00' +# 登录超时 (单位:秒) +login_timeout: 259200 + # 评论审核 moderator: pending_default: false # 发表新评论默认为 “待审状态” diff --git a/cli/main.go b/cli/main.go deleted file mode 100644 index 521d9d7a0..000000000 --- a/cli/main.go +++ /dev/null @@ -1,7 +0,0 @@ -package main - -import "github.com/ArtalkJS/Artalk-API-Go/cli/cmd" - -func main() { - cmd.Execute() -} diff --git a/cli/cmd/root.go b/cmd/root.go similarity index 94% rename from cli/cmd/root.go rename to cmd/root.go index 487283d5a..704d0db42 100644 --- a/cli/cmd/root.go +++ b/cmd/root.go @@ -5,6 +5,7 @@ import ( "os" "github.com/ArtalkJS/Artalk-API-Go/config" + "github.com/ArtalkJS/Artalk-API-Go/lib" "github.com/rifflock/lfshook" "github.com/sirupsen/logrus" "github.com/spf13/cobra" @@ -22,7 +23,7 @@ var Banner = ` \|__|\|__|\|__|\|__| \|__| \|__|\|__|\|_______|\|__| \|__| Artalk: A Fast, Slight & Delightful Comment System. -More detail on https://github.com/ArtalkJS/Artalk +More details on https://github.com/ArtalkJS/Artalk (c) 2021 artalk.js.org` var cfgFile string @@ -98,6 +99,11 @@ func initLog() { } func initDB() { + err := lib.OpenDB() + if err != nil { + logrus.Error("数据库初始化发生错误 ", err) + os.Exit(1) + } } //// 捷径函数 //// diff --git a/cli/cmd/serve.go b/cmd/serve.go similarity index 93% rename from cli/cmd/serve.go rename to cmd/serve.go index cc8a306de..8c41d3be1 100644 --- a/cli/cmd/serve.go +++ b/cmd/serve.go @@ -11,7 +11,7 @@ var serveCmd = &cobra.Command{ Use: "serve", Version: rootCmd.Version, Aliases: []string{"server"}, - Short: "启动服务器", + Short: "启动 HTTP 服务", Long: rootCmd.Long, Run: func(cmd *cobra.Command, args []string) { fmt.Println(Banner) diff --git a/config/config.go b/config/config.go index ab4e67f5d..5f8d549a4 100644 --- a/config/config.go +++ b/config/config.go @@ -15,15 +15,17 @@ var Instance *Config // Config 配置 // @link https://godoc.org/github.com/mitchellh/mapstructure type Config struct { - SiteName string `mapstructure:"site_name"` // 网站名 - HttpAddr string `mapstructure:"http_addr"` // HTTP Server 监听地址 - DB DBConf `mapstructure:"db"` // 数据文件 - Log LogConf `mapstructure:"log"` // 日志文件 - AllowOrigin []string `mapstructure:"allow_origin"` // 允许跨域访问的域名 - AdminUsers []model.User `mapstructure:"admin_users"` - Moderator ModeratorConf `mapstructure:"moderator"` - Captcha CaptchaConf `mapstructure:"captcha"` - Email EmailConf `mapstructure:"email"` + SiteName string `mapstructure:"site_name"` // 网站名 + AppKey string `mapstructure:"app_key"` // 加密密钥 + HttpAddr string `mapstructure:"http_addr"` // HTTP Server 监听地址 + DB DBConf `mapstructure:"db"` // 数据文件 + Log LogConf `mapstructure:"log"` // 日志文件 + AllowOrigin []string `mapstructure:"allow_origin"` // 允许跨域访问的域名 + AdminUsers []model.User `mapstructure:"admin_users"` + LoginTimeout int `mapstructure:"login_timeout"` + Moderator ModeratorConf `mapstructure:"moderator"` + Captcha CaptchaConf `mapstructure:"captcha"` + Email EmailConf `mapstructure:"email"` } type DBConf struct { @@ -77,8 +79,8 @@ type AliDMConf struct { type DBType string const ( - MySql DBType = "mysql" - Sqlite DBType = "sqlite" + TypeMySql DBType = "mysql" + TypeSqlite DBType = "sqlite" ) type EmailSenderType string diff --git a/config/config_test.go b/config/config_test.go index 6914b2321..39dc52b02 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -1,8 +1,11 @@ package config -import "testing" +import ( + "testing" +) func TestInit(t *testing.T) { Init("../artalk-go.example.yaml") + t.Log(Instance) } diff --git a/frontend/index.html b/frontend/index.html new file mode 100644 index 000000000..d7f935c12 --- /dev/null +++ b/frontend/index.html @@ -0,0 +1,12 @@ + + + + + + + Document + + +

Hello World!

+ + \ No newline at end of file diff --git a/go.mod b/go.mod index fce4bc9fa..efbc5e5fb 100644 --- a/go.mod +++ b/go.mod @@ -3,10 +3,19 @@ module github.com/ArtalkJS/Artalk-API-Go go 1.16 require ( - github.com/fsnotify/fsnotify v1.5.0 // indirect - github.com/mattn/go-colorable v0.1.8 // indirect + github.com/dchest/captcha v0.0.0-20200903113550-03f5f0333e1f // indirect + github.com/fsnotify/fsnotify v1.5.1 // indirect + github.com/golang-jwt/jwt v3.2.2+incompatible + github.com/kr/text v0.2.0 // indirect + github.com/labstack/echo/v4 v4.5.0 + github.com/markbates/pkger v0.17.1 github.com/mattn/go-isatty v0.0.13 // indirect + github.com/mattn/go-sqlite3 v1.14.8 // indirect github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect + github.com/mitchellh/mapstructure v1.4.1 + github.com/mojocn/base64Captcha v1.3.5 // indirect + github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect + github.com/onrik/logrus v0.9.0 github.com/onsi/gomega v1.16.0 // indirect github.com/rifflock/lfshook v0.0.0-20180920164130-b9218ef580f5 github.com/sirupsen/logrus v1.8.1 @@ -15,9 +24,13 @@ require ( github.com/spf13/viper v1.8.1 github.com/x-cray/logrus-prefixed-formatter v0.5.2 golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 // indirect + golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d // indirect + golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d // indirect golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf // indirect golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b // indirect golang.org/x/text v0.3.7 // indirect + gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f // indirect + gorm.io/driver/mysql v1.1.2 gorm.io/driver/sqlite v1.1.4 gorm.io/gorm v1.21.13 ) diff --git a/go.sum b/go.sum index 8b9042230..b1378a7ea 100644 --- a/go.sum +++ b/go.sum @@ -56,9 +56,12 @@ github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnht github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dchest/captcha v0.0.0-20200903113550-03f5f0333e1f h1:q/DpyjJjZs94bziQ7YkBmIlpqbVP7yw179rnzoNVX1M= +github.com/dchest/captcha v0.0.0-20200903113550-03f5f0333e1f/go.mod h1:QGrK8vMWWHQYQ3QU9bw9Y9OPNfxccGzfb41qjvVeXtY= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= @@ -69,15 +72,23 @@ github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7 github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/fsnotify/fsnotify v1.5.0 h1:NO5hkcB+srp1x6QmwvNZLeaOgbM8cmBTN32THzjvu2k= -github.com/fsnotify/fsnotify v1.5.0/go.mod h1:BX0DCEr5pT4jm2CnQdVP1lFV521fcCNcyEeNp4DQQDk= +github.com/fsnotify/fsnotify v1.5.1 h1:mZcQUHVQUQWoPXXtuf9yuEXKudkV2sx1E06UadKWpgI= +github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE= +github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= +github.com/gobuffalo/here v0.6.0 h1:hYrd0a6gDmWxBM4TnrGw8mQg24iSVoIkHEk7FodQcBI= +github.com/gobuffalo/here v0.6.0/go.mod h1:wAG085dHOYqUpf+Ap+WOdrPTp5IYcDAs/x7PLa8Y5fM= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY= +github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= +github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g= +github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -181,22 +192,32 @@ github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfV github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= -github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/labstack/echo/v4 v4.5.0 h1:JXk6H5PAw9I3GwizqUHhYyS4f45iyGebR/c1xNCeOCY= +github.com/labstack/echo/v4 v4.5.0/go.mod h1:czIriw4a0C1dFun+ObrXp7ok03xON0N1awStJ6ArI7Y= +github.com/labstack/gommon v0.3.0 h1:JEeO0bvc78PKdyHxloTKiF8BD5iGrH8T6MSeGvSgob0= +github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k= github.com/magiconair/properties v1.8.5 h1:b6kJs+EmPFMYGkow9GiUyCyOvIwYetYJ3fSaWak/Gls= github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= +github.com/markbates/pkger v0.17.1 h1:/MKEtWqtc0mZvu9OinB9UzVN9iYCwLWuyUv4Bw+PCno= +github.com/markbates/pkger v0.17.1/go.mod h1:0JoVlrol20BSywW79rN3kdFFsE5xYM+rSCQDXbLhiuI= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ0s8= github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.13 h1:qdl+GuBjcsKKDco5BsxPJlId98mSWNKqYA+Co0SC1yA= github.com/mattn/go-isatty v0.0.13/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= -github.com/mattn/go-sqlite3 v1.14.5 h1:1IdxlwTNazvbKJQSxoJ5/9ECbEeaTTyeU7sEAZ5KKTQ= github.com/mattn/go-sqlite3 v1.14.5/go.mod h1:WVKg1VTActs4Qso6iwGbiFih2UIHo0ENGwNd0Lj+XmI= +github.com/mattn/go-sqlite3 v1.14.8 h1:gDp86IdQsN/xWjIEmr9MF6o9mpksUgh0fu+9ByFxzIU= +github.com/mattn/go-sqlite3 v1.14.8/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d h1:5PJl274Y63IEHC+7izoQE9x6ikvDFZS2mDVS3drnohI= github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= @@ -212,9 +233,17 @@ github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RR github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/mojocn/base64Captcha v1.2.2 h1:NTFnThPVrb3tR66JO/N8/ZHsyFrNc7ho+xRpxBUEIlo= +github.com/mojocn/base64Captcha v1.2.2/go.mod h1:wAQCKEc5bDujxKRmbT6/vTnTt5CjStQ8bRfPWUuz/iY= +github.com/mojocn/base64Captcha v1.3.5 h1:Qeilr7Ta6eDtG4S+tQuZ5+hO+QHbiGAJdi4PfoagaA0= +github.com/mojocn/base64Captcha v1.3.5/go.mod h1:/tTTXn4WTpX9CfrmipqRytCpJ27Uw3G6I7NcP2WwcmY= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= +github.com/onrik/logrus v0.9.0 h1:oT7VstCUxWBoX7fswYK61fi9bzRBSpROq5CR2b7wxQo= +github.com/onrik/logrus v0.9.0/go.mod h1:qfe9NeZVAJfIxviw3cYkZo3kvBtLoPRJriAO8zl7qTk= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc= @@ -269,6 +298,11 @@ github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5Cc github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= +github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= +github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= +github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= +github.com/valyala/fasttemplate v1.2.1 h1:TVEnxayobAdVkhQfrfes2IzOB6o+z4roRkPF52WA1u4= +github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= github.com/x-cray/logrus-prefixed-formatter v0.5.2 h1:00txxvfBM9muc0jiLIEAkAcIMJzfthRT6usrui8uGmg= github.com/x-cray/logrus-prefixed-formatter v0.5.2/go.mod h1:2duySbKsL6M18s5GU7VPsoEPHyzalCE06qoARUCeBBE= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -296,6 +330,7 @@ golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 h1:HWj/xjIHfjYU5nVXpTM0s39J9CbLn7Cc5a7IC5rwsMQ= golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -309,7 +344,11 @@ golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= +golang.org/x/image v0.0.0-20190501045829-6d32002ffd75/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= +golang.org/x/image v0.0.0-20190802002840-cff245a6509b h1:+qEpEAPhDZ1o0x3tHzZTQDArnOixOzGD9HUJfcg0mb4= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d h1:RNPAfi2nHY7C2srAV8A49jpsYr0ADedCk1wq6fTMTvs= +golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -371,8 +410,9 @@ golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.0.0-20210428140749-89ef3d95e781 h1:DzZ89McO9/gWPsQXS/FVKAlG02ZjaQ6AlZRBimEYOd0= golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= +golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d h1:LO7XpTYMwTqxjLcGWPijK3vRXg1aWdlNOVOHRq45d7c= +golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -401,6 +441,7 @@ golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -408,6 +449,7 @@ golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -464,6 +506,8 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20201208040808-7e3f01d25324 h1:Hir2P/De0WpUhtrKGGjvSb2YxUgyZ7EFOSLIcSSpiwE= +golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= @@ -623,8 +667,9 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/ini.v1 v1.62.0 h1:duBzk771uxoUuOlyRLkHsygud9+5lrlGjdFBb4mSKDU= @@ -634,6 +679,7 @@ gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWD gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= @@ -641,9 +687,12 @@ gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gorm.io/driver/mysql v1.1.2 h1:OofcyE2lga734MxwcCW9uB4mWNXMr50uaGRVwQL2B0M= +gorm.io/driver/mysql v1.1.2/go.mod h1:4P/X9vSc3WTrhTLZ259cpFd6xKNYiSSdSZngkSBGIMM= gorm.io/driver/sqlite v1.1.4 h1:PDzwYE+sI6De2+mxAneV9Xs11+ZyKV6oxD3wDGkaNvM= gorm.io/driver/sqlite v1.1.4/go.mod h1:mJCeTFr7+crvS+TRnWc5Z3UvwxUN1BGBLMrf5LA9DYw= gorm.io/gorm v1.20.7/go.mod h1:0HFTzE/SqkGTzK6TlDPPQbAYCluiVvhzoA1+aVyzenw= +gorm.io/gorm v1.21.12/go.mod h1:F+OptMscr0P2F2qU97WT1WimdH9GaQPoDW7AYd5i2Y0= gorm.io/gorm v1.21.13 h1:JU5A4yVemRjdMndJ0oZU7VX+Nr2ICE3C60U5bgR6mHE= gorm.io/gorm v1.21.13/go.mod h1:F+OptMscr0P2F2qU97WT1WimdH9GaQPoDW7AYd5i2Y0= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/http/api_admin.go b/http/api_admin.go new file mode 100644 index 000000000..880ff427d --- /dev/null +++ b/http/api_admin.go @@ -0,0 +1,20 @@ +package http + +import ( + "github.com/labstack/echo/v4" +) + +func ActionAdminLogin(c echo.Context) error { + return nil +} + +func ActionAdminEdit(c echo.Context) error { + // user := c.Get("user").(*jwt.Token) + // claims := user.Claims.(*jwtCustomClaims) + // name := claims.Name + return nil +} + +func ActionAdminDel(c echo.Context) error { + return nil +} diff --git a/http/api_captcha.go b/http/api_captcha.go new file mode 100644 index 000000000..838d39ba6 --- /dev/null +++ b/http/api_captcha.go @@ -0,0 +1,42 @@ +package http + +import ( + "bytes" + "encoding/base64" + "time" + + "github.com/dchest/captcha" + "github.com/labstack/echo/v4" +) + +var caGlobalStore = captcha.NewMemoryStore(100, 10*time.Minute) // TODO: 用 redis 或其他kv数据库来存更多值 + +func ActionCaptchaRefresh(c echo.Context) error { + ip := c.RealIP() + + return RespData(c, Map{ + "img_data": GetBase64Image(ip, 150, 40), + }) +} + +func ActionCaptchaCheck(c echo.Context) error { + ip := c.RealIP() + value := c.QueryParam("value") + + captcha.SetCustomStore(caGlobalStore) + if captcha.VerifyString(ip, value) { + return RespSuccess(c) + } else { + return RespError(c, "验证码错误") + } +} + +func GetBase64Image(id string, width, height int) string { + png := bytes.NewBuffer([]byte{}) + d := captcha.RandomDigits(6) + captcha.SetCustomStore(caGlobalStore) + caGlobalStore.Set(id, d) + captcha.NewImage(id, d, width, height).WriteTo(png) + base64Code := "data:image/png;base64," + base64.StdEncoding.EncodeToString(png.Bytes()) + return base64Code +} diff --git a/http/api_main.go b/http/api_main.go new file mode 100644 index 000000000..dc430adb3 --- /dev/null +++ b/http/api_main.go @@ -0,0 +1,78 @@ +package http + +import ( + "github.com/ArtalkJS/Artalk-API-Go/config" + "github.com/ArtalkJS/Artalk-API-Go/lib" + "github.com/ArtalkJS/Artalk-API-Go/model" + "github.com/labstack/echo/v4" + "github.com/mitchellh/mapstructure" + "github.com/sirupsen/logrus" +) + +type ParamsAdd struct { + Name string `mapstructure:"name"` + Content string `mapstructure:"content"` + Email string `mapstructure:"email"` + Link string `mapstructure:"link"` + Rid uint `mapstructure:"rid"` + PageKey string `mapstructure:"page_key"` + Token string `mapstructure:"token"` +} + +func ActionAdd(c echo.Context) error { + var p ParamsAdd + mapstructure.Decode(c.QueryParams(), &p) + + ip := c.RealIP() + ua := c.Request().UserAgent() + + // find user + user := FindUser(p.Name, p.Email) + if user.IsEmpty() { + user = NewUser(p.Name, p.Email, p.Link) // save a new user + } + + user.Link = p.Link + user.LastIP = ip + user.LastUA = ua + UpdateUser(&user) + + // find page + page := FindPage(p.PageKey) + if page.IsEmpty() { + page = NewPage(p.PageKey) + } + + // check if the user is allowed to comment + if isAllowed, err := CheckIfAllowed(c, user, page); !isAllowed { + return err + } + + comment := model.Comment{ + Content: p.Content, + Rid: p.Rid, + UserID: user.ID, + PageID: page.ID, + IP: ip, + UA: ua, + } + + if config.Instance.Moderator.PendingDefault { + comment.Type = model.CommentPending + } + + err := lib.DB.Create(&comment).Error + if err != nil { + logrus.Error("Save Comment error: ", err) + } + + return nil +} + +func ActionGet(c echo.Context) error { + return nil +} + +func ActionUser(c echo.Context) error { + return nil +} diff --git a/http/http.go b/http/http.go index 5e3a0a074..7e38a12a8 100644 --- a/http/http.go +++ b/http/http.go @@ -1,5 +1,71 @@ package http +import ( + "net/http" + + "github.com/ArtalkJS/Artalk-API-Go/config" + "github.com/labstack/echo/v4" + "github.com/labstack/echo/v4/middleware" + echolog "github.com/onrik/logrus/echo" + "github.com/sirupsen/logrus" +) + +type Map = map[string]interface{} + func Run() { + e := echo.New() + e.HideBanner = true + + e.Use(middleware.CORSWithConfig(middleware.CORSConfig{ + AllowOrigins: config.Instance.AllowOrigin, + })) + e.Logger = echolog.NewLogger(logrus.StandardLogger(), "") + e.Use(echolog.Middleware(echolog.DefaultConfig)) + + InitRoute(e) + + e.Logger.Fatal(e.Start(config.Instance.HttpAddr)) +} + +// JSONResult JSON 响应数据结构 +type JSONResult struct { + Success bool `json:"success"` // 是否成功 + Msg string `json:"msg,omitempty"` // 消息 + Data interface{} `json:"data,omitempty"` // 数据 + Extra interface{} `json:"extra,omitempty"` // 数据 +} + +// RespJSON is normal json result +func RespJSON(c echo.Context, msg string, data interface{}, success bool) error { + return c.JSON(http.StatusOK, &JSONResult{ + Success: success, + Msg: msg, + Data: data, + }) +} + +// RespData is just response data +func RespData(c echo.Context, data interface{}) error { + return c.JSON(http.StatusOK, &JSONResult{ + Success: true, + Data: data, + }) +} + +// RespSuccess is just response success +func RespSuccess(c echo.Context) error { + return c.JSON(http.StatusOK, &JSONResult{ + Success: true, + }) +} +// RespError is just response error +func RespError(c echo.Context, msg string, details ...string) error { + return c.JSON(http.StatusOK, &JSONResult{ + Success: false, + Msg: msg, + Extra: Map{ + "errDetails": details, + }, + }) } diff --git a/http/pkged.go b/http/pkged.go new file mode 100644 index 000000000..8a8e6dba6 --- /dev/null +++ b/http/pkged.go @@ -0,0 +1,12 @@ +// Code generated by pkger; DO NOT EDIT. + +// +build !skippkger + +package http + +import ( + "github.com/markbates/pkger" + "github.com/markbates/pkger/pkging/mem" +) + +var _ = pkger.Apply(mem.UnmarshalEmbed([]byte(`1f8b08000000000000ffec594b73db3812fe2b295c230b2425d992aaf6e028b1e28c93d5d88e35f67a6a0a04411216087000508fa4f2dfb7005222453dac642e73e04122bafb03886737f8f57740792814187e0711d571e6b7b148e0a5d488cd3edd1585b3cbc9f5d95818d07b2ac1108c86cfcf5f1591eaf999a45852fefc3c15727697224c9e9fb72bb5c075920aa92748c76078c25b5ae00b4a08188204510e5ae0bdc06008400bdc231911bdfff591787ef64d61abad365912d002b7421ca876a4d79f91c63118fe0fb4c19f2d70a7112360a865460ae19620253818022ef41bca95468c91e08d9fe937688e28433e236f287fe36794056f30c2b1e9ca585c51469469d70caf1d09d37a3e4356fbeafc409c04a6ce7b92da0a7e1652d35f7fa589022d8045924aa2140c19d2a4aa88bed1d4ca5c23ca89848c2a5d28c8d296e42ad5625380286f3117304d63224b39a81a03854a81e06d31f07a3d77b0a380946b22396290040b2403f533301852c2820a98319a6a8a773565fd90a27294304e5005bd0149c4834c53b6c7a4325f33521a92a0570aa65e45c2dd8a509d0d1523774bf27ae75b72cff52a72ed959a55267dd97306db124c6774095a20401af94811a8fe6635110692ceed3a128e454079542942a4b85b954dadf3ee9686722457550d56f3aa189365557c31a7a422a724a98acbc474904829a41959c890e94f9898853aed2c9c84133ca4d149d058ebf424602202c2b691a1e242d370b5296c9b23e167618898803191a46e638847672f0b0d5f16b5c1c748c5140b99c218b32326fb43ea586dfb4b915476071c4749bbf15f83298c383f01a625167cfe1a4c8b19e1c740663b9d30000b3ba16b16b7e7a59463c1552cc99c18470e139129a225aa6d8d17cabfc519a43c64046b2af85e33178b6d3d43bed208cf20c1b180f3ee712b4c681030b240f53db3014622490487eb107004820513f2388489e838c0783a916c631214512c38a212a652a4446a5aef4a82e4cc479a2898cea2faaad48c7b0e481db1f1ca094a8fbfc9fce76eee550c24894f82939009d99982bd38a503b1d33fad398cc4995d0db3bf0ed8a9425ad79c481265fa1b445cd19a9e6a1c13c6623b215a665867f539145cd29959609929bbbbb6cd29618c684aa479b71649cdd7481a864ce01964a18a85986d5b159559aa082f9aaf19d3d0ed401412290e1a76673437e21d8f56e8852fd13ec3cb02314de482201d139920be0f94169166c730a7697d73aacc178a6a0123a149dd87cd115b2186ece133ee9dc85408b61f1322a53549d2e26656412ccfb044ab62eece524942ba24c15928a4d90c7987c4dab78baa6713a5fbb221a42d640497707d83c30939628228d30213a90f60948aa12632a11cb13a84136d83a5fd8b32ad0e01bc8306187bf888314578b6cf4c038eea7ab552a54bc8b8422189090a8a39aa0117940762b1d36133d25ddd524345702609f4694065c67626d462b4445c99f5da6bcd38c522c89b380ae0fb5aa00981b2d833229d456dca21e5b43d77ab9a154a587b9ecfb64cdad4ecd7a2b1528498a14c91ba9689a8f0c955adc23149505d6b6ec766ee4c242d1e104bdc316f8eb5f51ae6012b3b7db332c8a755d11c1ac4a2aa0aa759550c13ad84dd9f1b5524c832259226846fe9a916a82a73a2b54478ebfd42d9ab6655950ac6aa72bd8a2436b833ba3d124579c448c868146ff542ad14468c41b2243877163ba672fb1d32414922aab4bd671fc4a8950ab6bbae89d279f83e7414eca722153054f9938ae25b27af96988ff4fc017d1a95457bba6db9f8ce49a8752ce601938c699a22bb4a56f177263409ec05b2886e9ce8fc7f7dbfdef21eeb65da52161ddbe8d643daa78348614a0b8b394fa914f643d6c89934756c1016caae0b6881341fa979c0903252c8c562db524496e9a600d58a6b64be6c64c6753ef8a20403e26751452e7ba545623f49772cc544efe8d5ca74b3d8f1e59d59694979644d2b8e8b47d97cb133400be4ae08f90b49f3a8912bca93b825e71769a3cd075438a1b204331dbae7db72df8a6657811698131e0809f7c50e1c231c23cf390d950ab6723b4eef15b47d18af712a6efd457b0c9cc93959730f4770f12c088f2376998223e057466c766ec095f9254429141d6a6e5f1c7e15974ab15cbd022c23f021541188f7994d98cd5df93eeb81a87a105a0dae0741b518fb2ace86da3f5be09e28bde1e578c658aeda9072b9eab3084c2787dfc14f30999f11e56bd6f057a8d3b1f82c829fabf5fc1c897622025bfb8148452d4be9b6dd73f0e3c78f1608f3819e40f80e612805d78407064e796829e08068642e00c3ef80e744ed06d5028a7e2360e8b44062fcc8d073bb17dd7ed7ed0dace62feb6786c0733cf7cce99f79bd7bd71b7afda1d36b5ff4bb9ee3f5de3afda1637c06557f0566c6f2c9337e71f81d9845bad45a523f339fba43f7bc05469220f3e97d6fdbfe0e6ec4e23dd22417dd5eafe75d386ecf69818f348a4b4bc71938e717dee0470bdc20a52f31264aed6da3ef0e06dea07fdedbdf44e7bc68626a7ceede16bcdec579cfb9f0baee915e98b1ddd16fc400ec14ae15376201868e5dbb98c886856f58f886856f58f886856f58f886856f58f886856f58f886856f58f886856f58f886856f58f886856f58f886856f58f88685fff7b2f085e333a398453f47c79694fc8f9c515acf4c8aa489c49b36cb2af6853f41f643ca03b26cdb4bc451debf825b33ff5ebfbbe6febb9dfe31d2ff62e8b9ed81dbf5fae7173ba47f88983accfa77bc57587fcf71ba838b8b81e3fd33d6bfd31d7406bfcefabb9d8bbed377fa9d5f66fdbd7ef71ff1fe968eaf93ffe5cef00f50fb255b5f52f0f92e2b18f8627db629f82ab19ea36b873727cbcbb3dd1cf7d38f7bf5506e4e3e988cae3edc3b5fbe4e1fde5d5d8f63c79f2ede8e5e962218bbea7abc8cfd040fae9387ecfaa5fbdb641cb3c7e9ef6f47f432ba1e5df6fde983f378f7ee058daf56d87b7026779f1e1e3e3ceaff8eaeeb18117cbc5ddc4c1f96c1947993bb4f8f370f0fef6ebe7e99fb7fbc8b8331a3fef82bbd1e7f99fbfc96f9fcf7c1f58c5d4da60fb327ef2b9d44c2b4154dc62e0bc61f223fb9d24ff70e0d12c682cebb39e6bf6fd7e541faf4f1564ca6b72c48d8cbd39ddb41d35b078d16119af6d260cc627fe47e7bf4aed4d3bdb3bc79b92cdff1f1360dc64b3699ddce1f3b0ffa69da7326a38183feb8554ff7dddf26a381789a5ecd2691e83f268319b9effe66ea5dbf5f8acf2fbdeba7e952f9ab777ff89d4fea69f4a17fe3452b83bdf13ecd9f3ecede8e5e1673f4f156fbefbbff01aff8dcfcd892265fd7e4eb9a7c5d93af6bf2754dbeaec9d735f9ba265fd7e4eb9a7c5d93af6bf2754dbeaec9d735f9ba265fd7e4eb9a7c5d93af6bf275ff5e02ffc7ff010000ffff010000ffffff1a750f27490000`))) diff --git a/http/route.go b/http/route.go new file mode 100644 index 000000000..0dc5ce1a3 --- /dev/null +++ b/http/route.go @@ -0,0 +1,56 @@ +package http + +import ( + "net/http" + + "github.com/ArtalkJS/Artalk-API-Go/config" + "github.com/ArtalkJS/Artalk-API-Go/model" + "github.com/golang-jwt/jwt" + "github.com/labstack/echo/v4" + "github.com/labstack/echo/v4/middleware" + "github.com/markbates/pkger" + "github.com/sirupsen/logrus" +) + +func InitRoute(e *echo.Echo) { + f, err := pkger.Open("/frontend") + if err != nil { + logrus.Fatal(err) + return + } + + fileServer := http.FileServer(f) + e.GET("/*", echo.WrapHandler(fileServer)) + + // api + api := e.Group("/api") + + api.GET("/add", ActionAdd) + api.GET("/get", ActionAdd) + api.GET("/user", ActionUser) + api.GET("/login-admin", ActionAdminLogin) + + // api/captcha + ca := api.Group("/captcha") + ca.GET("/refresh", ActionCaptchaRefresh) + ca.GET("/check", ActionCaptchaCheck) + + // api/admin + admin := api.Group("/admin") + admin.GET("/edit", ActionAdminEdit) + admin.GET("/del", ActionAdminDel) + + admin.Use(middleware.JWTWithConfig(middleware.JWTConfig{ + Claims: &jwtCustomClaims{}, + SigningKey: []byte(config.Instance.AppKey), + })) +} + +// jwtCustomClaims are custom claims extending default ones. +// See https://github.com/golang-jwt/jwt for more examples +type jwtCustomClaims struct { + UserName string `json:"name"` + UserEmail string `json:"email"` + UserType model.UserType `json:"type"` + jwt.StandardClaims +} diff --git a/http/utils.go b/http/utils.go new file mode 100644 index 000000000..e9025adc1 --- /dev/null +++ b/http/utils.go @@ -0,0 +1,112 @@ +package http + +import ( + "time" + + "github.com/ArtalkJS/Artalk-API-Go/config" + "github.com/ArtalkJS/Artalk-API-Go/lib" + "github.com/ArtalkJS/Artalk-API-Go/model" + "github.com/golang-jwt/jwt" + "github.com/labstack/echo/v4" + "github.com/sirupsen/logrus" +) + +func LoginUser(user model.User) string { + // Set custom claims + claims := &jwtCustomClaims{ + UserName: user.Name, + UserEmail: user.Email, + UserType: user.Type, + StandardClaims: jwt.StandardClaims{ + ExpiresAt: time.Now().Add(time.Second * time.Duration(config.Instance.LoginTimeout)).Unix(), // 过期时间 + }, + } + + // Create token with claims + token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims) + + // Generate encoded token and send it as response. + t, err := token.SignedString([]byte(config.Instance.AppKey)) + if err != nil { + return "" + } + + return t +} + +func CheckIsAdmin(c echo.Context) bool { + jwt := c.Get("user").(*jwt.Token) + claims := jwt.Claims.(*jwtCustomClaims) + name := claims.UserName + email := claims.UserEmail + + if claims.UserType != model.UserAdmin { + return false + } + + // check user from database + user := FindUser(name, email) + if user.IsEmpty() { + return false + } + + return user.Type == model.UserAdmin +} + +func CheckIfAllowed(c echo.Context, user model.User, page model.Page) (bool, error) { + return false, nil +} + +func FindUser(name string, email string) model.User { + var user model.User + lib.DB.Where(&model.User{Name: name, Email: email}).First(&user) + return user +} + +func NewUser(name string, email string, link string) model.User { + user := model.User{ + Name: name, + Email: email, + Link: link, + } + + err := lib.DB.Create(&user).Error + if err != nil { + logrus.Error("Save User error: ", err) + } + + return user +} + +func UpdateUser(user *model.User) { + err := lib.DB.Save(user).Error + if err != nil { + logrus.Error("Update User error: ", err) + } +} + +func FindPage(key string) model.Page { + var page model.Page + lib.DB.Where(&model.Page{Key: key}).First(&page) + return page +} + +func NewPage(key string) model.Page { + page := model.Page{ + Key: key, + } + + err := lib.DB.Create(&page).Error + if err != nil { + logrus.Error("Save Page error: ", err) + } + + return page +} + +func UpdatePage(page *model.Page) { + err := lib.DB.Save(page).Error + if err != nil { + logrus.Error("Update Page error: ", err) + } +} diff --git a/lib/db.go b/lib/db.go index 74548104f..819e56826 100644 --- a/lib/db.go +++ b/lib/db.go @@ -1,14 +1,41 @@ package lib import ( + "path/filepath" + "github.com/ArtalkJS/Artalk-API-Go/config" + "gorm.io/driver/mysql" "gorm.io/driver/sqlite" "gorm.io/gorm" ) var DB *gorm.DB -func OpenDb(dbFile string) (err error) { - DB, err = gorm.Open(sqlite.Open(config.Instance.DB.Dsn), &gorm.Config{}) +var gormConfig = &gorm.Config{ + Logger: NewGormLogger(), +} + +func OpenDB() (err error) { + switch config.Instance.DB.Type { + case config.TypeMySql: + err = OpenMySqlDb() + case config.TypeSqlite: + err = OpenSqliteDb() + } + return +} + +func OpenMySqlDb() (err error) { + DB, err = gorm.Open(mysql.Open(config.Instance.DB.Dsn), gormConfig) + return +} + +func OpenSqliteDb() (err error) { + filename := config.Instance.DB.Dsn + if err := EnsureDir(filepath.Dir(filename)); err != nil { + return err + } + + DB, err = gorm.Open(sqlite.Open(filename), gormConfig) return } diff --git a/lib/gorm-logger.go b/lib/gorm-logger.go new file mode 100644 index 000000000..b8ea2dce3 --- /dev/null +++ b/lib/gorm-logger.go @@ -0,0 +1,61 @@ +package lib + +import ( + "context" + "errors" + "time" + + log "github.com/sirupsen/logrus" + "gorm.io/gorm" + gormlogger "gorm.io/gorm/logger" + "gorm.io/gorm/utils" +) + +type gLogger struct { + SlowThreshold time.Duration + SourceField string + SkipErrRecordNotFound bool +} + +func NewGormLogger() *gLogger { + return &gLogger{ + SkipErrRecordNotFound: true, + } +} + +func (l *gLogger) LogMode(gormlogger.LogLevel) gormlogger.Interface { + return l +} + +func (l *gLogger) Info(ctx context.Context, s string, args ...interface{}) { + log.WithContext(ctx).Infof(s, args) +} + +func (l *gLogger) Warn(ctx context.Context, s string, args ...interface{}) { + log.WithContext(ctx).Warnf(s, args) +} + +func (l *gLogger) Error(ctx context.Context, s string, args ...interface{}) { + log.WithContext(ctx).Errorf(s, args) +} + +func (l *gLogger) Trace(ctx context.Context, begin time.Time, fc func() (string, int64), err error) { + elapsed := time.Since(begin) + sql, _ := fc() + fields := log.Fields{} + if l.SourceField != "" { + fields[l.SourceField] = utils.FileWithLineNum() + } + if err != nil && !(errors.Is(err, gorm.ErrRecordNotFound) && l.SkipErrRecordNotFound) { + fields[log.ErrorKey] = err + log.WithContext(ctx).WithFields(fields).Errorf("%s [%s]", sql, elapsed) + return + } + + if l.SlowThreshold != 0 && elapsed > l.SlowThreshold { + log.WithContext(ctx).WithFields(fields).Warnf("%s [%s]", sql, elapsed) + return + } + + log.WithContext(ctx).WithFields(fields).Debugf("%s [%s]", sql, elapsed) +} diff --git a/lib/utils.go b/lib/utils.go new file mode 100644 index 000000000..9405379ad --- /dev/null +++ b/lib/utils.go @@ -0,0 +1,25 @@ +package lib + +import ( + "errors" + "os" +) + +func EnsureDir(dirName string) error { + err := os.Mkdir(dirName, os.ModeDir) + if err == nil { + return nil + } + if os.IsExist(err) { + // check that the existing path is a directory + info, err := os.Stat(dirName) + if err != nil { + return err + } + if !info.IsDir() { + return errors.New("path exists but is not a directory") + } + return nil + } + return err +} diff --git a/main.go b/main.go new file mode 100644 index 000000000..98e0717d3 --- /dev/null +++ b/main.go @@ -0,0 +1,7 @@ +package main + +import "github.com/ArtalkJS/Artalk-API-Go/cmd" + +func main() { + cmd.Execute() +} diff --git a/makefile b/makefile new file mode 100644 index 000000000..09a6d5e63 --- /dev/null +++ b/makefile @@ -0,0 +1,24 @@ +ifndef VERSION + VERSION := $(shell git describe --tags --abbrev=0) +endif + +COMMIT_HASH :=$(shell git rev-parse --short HEAD) +DEV_VERSION := dev-${COMMIT_HASH} + +all: install update build + +install: + go mod tidy + go install github.com/markbates/pkger/cmd/pkger + +update: + pkger -include /frontend -o http + +build: update + go build -ldflags "-X github.com/ArtalkJS/Artalk-API-Go.Version=${VERSION}" -o bin/artalk-go github.com/ArtalkJS/Artalk-API-Go + +run: update build + ./bin/artalk-go + +test: update + go test -cover github.com/ArtalkJS/Artalk-API-Go/... diff --git a/model/page.go b/model/page.go index a2ffd2cce..f7bc2d48a 100644 --- a/model/page.go +++ b/model/page.go @@ -2,8 +2,18 @@ package model import "gorm.io/gorm" +type PageType string + +const ( + PageClosed PageType = "closed" +) + type Page struct { gorm.Model - Name string - Link string + Key string + Type PageType +} + +func (p Page) IsEmpty() bool { + return p.ID == 0 } diff --git a/model/user.go b/model/user.go index c11c72b5f..76e99d177 100644 --- a/model/user.go +++ b/model/user.go @@ -21,3 +21,7 @@ type User struct { LastUA string Type UserType } + +func (u User) IsEmpty() bool { + return u.ID == 0 +} From 4389dba2859e9c2c7d96f00c785abba855acb3e8 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Thu, 26 Aug 2021 00:26:44 +0800 Subject: [PATCH 005/349] Rename Artalk-API-Go to ArtalkGo --- README.md | 6 +++++- cmd/root.go | 4 ++-- cmd/serve.go | 2 +- config/config.go | 2 +- docs/artalk-go.png | Bin 0 -> 88142 bytes go.mod | 2 +- http/api_main.go | 6 +++--- http/http.go | 2 +- http/route.go | 4 ++-- http/utils.go | 6 +++--- lib/db.go | 2 +- main.go | 2 +- makefile | 4 ++-- 13 files changed, 23 insertions(+), 19 deletions(-) create mode 100644 docs/artalk-go.png diff --git a/README.md b/README.md index dcd625210..16b229d54 100644 --- a/README.md +++ b/README.md @@ -1 +1,5 @@ -# Artalk-API-Go \ No newline at end of file +# ArtalkGo + +

+Artalk +

\ No newline at end of file diff --git a/cmd/root.go b/cmd/root.go index 704d0db42..00ef7b4ef 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -4,8 +4,8 @@ import ( "fmt" "os" - "github.com/ArtalkJS/Artalk-API-Go/config" - "github.com/ArtalkJS/Artalk-API-Go/lib" + "github.com/ArtalkJS/ArtalkGo/config" + "github.com/ArtalkJS/ArtalkGo/lib" "github.com/rifflock/lfshook" "github.com/sirupsen/logrus" "github.com/spf13/cobra" diff --git a/cmd/serve.go b/cmd/serve.go index 8c41d3be1..fdb3e4550 100644 --- a/cmd/serve.go +++ b/cmd/serve.go @@ -3,7 +3,7 @@ package cmd import ( "fmt" - "github.com/ArtalkJS/Artalk-API-Go/http" + "github.com/ArtalkJS/ArtalkGo/http" "github.com/spf13/cobra" ) diff --git a/config/config.go b/config/config.go index 5f8d549a4..4ed002311 100644 --- a/config/config.go +++ b/config/config.go @@ -4,7 +4,7 @@ import ( "fmt" "strings" - "github.com/ArtalkJS/Artalk-API-Go/model" + "github.com/ArtalkJS/ArtalkGo/model" "github.com/sirupsen/logrus" "github.com/spf13/viper" ) diff --git a/docs/artalk-go.png b/docs/artalk-go.png new file mode 100644 index 0000000000000000000000000000000000000000..895b00c449d70ba269468f3785947f6df02c14f6 GIT binary patch literal 88142 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 Ub&K6}MISw?cKmSSLGx?>5B0vJNB{r; literal 0 HcmV?d00001 diff --git a/go.mod b/go.mod index efbc5e5fb..5a2cb4cb5 100644 --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -module github.com/ArtalkJS/Artalk-API-Go +module github.com/ArtalkJS/ArtalkGo go 1.16 diff --git a/http/api_main.go b/http/api_main.go index dc430adb3..91cabb893 100644 --- a/http/api_main.go +++ b/http/api_main.go @@ -1,9 +1,9 @@ package http import ( - "github.com/ArtalkJS/Artalk-API-Go/config" - "github.com/ArtalkJS/Artalk-API-Go/lib" - "github.com/ArtalkJS/Artalk-API-Go/model" + "github.com/ArtalkJS/ArtalkGo/config" + "github.com/ArtalkJS/ArtalkGo/lib" + "github.com/ArtalkJS/ArtalkGo/model" "github.com/labstack/echo/v4" "github.com/mitchellh/mapstructure" "github.com/sirupsen/logrus" diff --git a/http/http.go b/http/http.go index 7e38a12a8..a47987169 100644 --- a/http/http.go +++ b/http/http.go @@ -3,7 +3,7 @@ package http import ( "net/http" - "github.com/ArtalkJS/Artalk-API-Go/config" + "github.com/ArtalkJS/ArtalkGo/config" "github.com/labstack/echo/v4" "github.com/labstack/echo/v4/middleware" echolog "github.com/onrik/logrus/echo" diff --git a/http/route.go b/http/route.go index 0dc5ce1a3..a80b17c37 100644 --- a/http/route.go +++ b/http/route.go @@ -3,8 +3,8 @@ package http import ( "net/http" - "github.com/ArtalkJS/Artalk-API-Go/config" - "github.com/ArtalkJS/Artalk-API-Go/model" + "github.com/ArtalkJS/ArtalkGo/config" + "github.com/ArtalkJS/ArtalkGo/model" "github.com/golang-jwt/jwt" "github.com/labstack/echo/v4" "github.com/labstack/echo/v4/middleware" diff --git a/http/utils.go b/http/utils.go index e9025adc1..bc8f52573 100644 --- a/http/utils.go +++ b/http/utils.go @@ -3,9 +3,9 @@ package http import ( "time" - "github.com/ArtalkJS/Artalk-API-Go/config" - "github.com/ArtalkJS/Artalk-API-Go/lib" - "github.com/ArtalkJS/Artalk-API-Go/model" + "github.com/ArtalkJS/ArtalkGo/config" + "github.com/ArtalkJS/ArtalkGo/lib" + "github.com/ArtalkJS/ArtalkGo/model" "github.com/golang-jwt/jwt" "github.com/labstack/echo/v4" "github.com/sirupsen/logrus" diff --git a/lib/db.go b/lib/db.go index 819e56826..62df7c1e6 100644 --- a/lib/db.go +++ b/lib/db.go @@ -3,7 +3,7 @@ package lib import ( "path/filepath" - "github.com/ArtalkJS/Artalk-API-Go/config" + "github.com/ArtalkJS/ArtalkGo/config" "gorm.io/driver/mysql" "gorm.io/driver/sqlite" "gorm.io/gorm" diff --git a/main.go b/main.go index 98e0717d3..ba304802d 100644 --- a/main.go +++ b/main.go @@ -1,6 +1,6 @@ package main -import "github.com/ArtalkJS/Artalk-API-Go/cmd" +import "github.com/ArtalkJS/ArtalkGo/cmd" func main() { cmd.Execute() diff --git a/makefile b/makefile index 09a6d5e63..9338e024a 100644 --- a/makefile +++ b/makefile @@ -15,10 +15,10 @@ update: pkger -include /frontend -o http build: update - go build -ldflags "-X github.com/ArtalkJS/Artalk-API-Go.Version=${VERSION}" -o bin/artalk-go github.com/ArtalkJS/Artalk-API-Go + go build -ldflags "-X github.com/ArtalkJS/ArtalkGo.Version=${VERSION}" -o bin/artalk-go github.com/ArtalkJS/ArtalkGo run: update build ./bin/artalk-go test: update - go test -cover github.com/ArtalkJS/Artalk-API-Go/... + go test -cover github.com/ArtalkJS/ArtalkGo/... From 3e9869c190a10754258e4ef3151be91f60264112 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Thu, 26 Aug 2021 17:04:33 +0800 Subject: [PATCH 006/349] Complete comment basic add & get function. --- .gitignore | 3 +- ...k-go.example.yaml => artalk-go.example.yml | 0 cmd/root.go | 6 +- config/config.go | 34 +++--- config/config_test.go | 2 +- http/api_admin.go | 20 +++- http/api_captcha.go | 4 + http/api_main.go | 73 +------------ http/api_main_add.go | 102 ++++++++++++++++++ http/api_main_get.go | 92 ++++++++++++++++ http/http.go | 9 +- http/route.go | 4 +- http/utils.go | 76 ++++++++++++- lib/utils.go | 8 ++ model/comment.go | 91 ++++++++++++++-- model/page.go | 18 +++- model/user.go | 18 ++-- 17 files changed, 447 insertions(+), 113 deletions(-) rename artalk-go.example.yaml => artalk-go.example.yml (100%) create mode 100644 http/api_main_add.go create mode 100644 http/api_main_get.go diff --git a/.gitignore b/.gitignore index 8551dde21..88f478baf 100644 --- a/.gitignore +++ b/.gitignore @@ -14,7 +14,8 @@ # Dependency directories (remove the comment below to include it) # vendor/ -artalk-go.yaml +artalk-go.yml +config.yml local/ bin/ diff --git a/artalk-go.example.yaml b/artalk-go.example.yml similarity index 100% rename from artalk-go.example.yaml rename to artalk-go.example.yml diff --git a/cmd/root.go b/cmd/root.go index 00ef7b4ef..d1218f88d 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -6,6 +6,7 @@ import ( "github.com/ArtalkJS/ArtalkGo/config" "github.com/ArtalkJS/ArtalkGo/lib" + "github.com/ArtalkJS/ArtalkGo/model" "github.com/rifflock/lfshook" "github.com/sirupsen/logrus" "github.com/spf13/cobra" @@ -49,7 +50,7 @@ func init() { cobra.OnInitialize(initDB) rootCmd.SetVersionTemplate("Artalk-GO {{printf \"version %s\" .Version}}\n") - rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "配置文件路径 (defaults are './artalk-go.conf.yaml', './config.yaml')") + rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "配置文件路径 (defaults are './artalk-go.yml')") } // 初始化配置 @@ -104,6 +105,9 @@ func initDB() { logrus.Error("数据库初始化发生错误 ", err) os.Exit(1) } + + // Migrate the schema + lib.DB.AutoMigrate(&model.Comment{}, &model.Page{}, &model.User{}) } //// 捷径函数 //// diff --git a/config/config.go b/config/config.go index 4ed002311..6bd238d03 100644 --- a/config/config.go +++ b/config/config.go @@ -4,7 +4,6 @@ import ( "fmt" "strings" - "github.com/ArtalkJS/ArtalkGo/model" "github.com/sirupsen/logrus" "github.com/spf13/viper" ) @@ -15,17 +14,17 @@ var Instance *Config // Config 配置 // @link https://godoc.org/github.com/mitchellh/mapstructure type Config struct { - SiteName string `mapstructure:"site_name"` // 网站名 - AppKey string `mapstructure:"app_key"` // 加密密钥 - HttpAddr string `mapstructure:"http_addr"` // HTTP Server 监听地址 - DB DBConf `mapstructure:"db"` // 数据文件 - Log LogConf `mapstructure:"log"` // 日志文件 - AllowOrigin []string `mapstructure:"allow_origin"` // 允许跨域访问的域名 - AdminUsers []model.User `mapstructure:"admin_users"` - LoginTimeout int `mapstructure:"login_timeout"` - Moderator ModeratorConf `mapstructure:"moderator"` - Captcha CaptchaConf `mapstructure:"captcha"` - Email EmailConf `mapstructure:"email"` + SiteName string `mapstructure:"site_name"` // 网站名 + AppKey string `mapstructure:"app_key"` // 加密密钥 + HttpAddr string `mapstructure:"http_addr"` // HTTP Server 监听地址 + DB DBConf `mapstructure:"db"` // 数据文件 + Log LogConf `mapstructure:"log"` // 日志文件 + AllowOrigin []string `mapstructure:"allow_origin"` // 允许跨域访问的域名 + AdminUsers []AdminUserConf `mapstructure:"admin_users"` + LoginTimeout int `mapstructure:"login_timeout"` + Moderator ModeratorConf `mapstructure:"moderator"` + Captcha CaptchaConf `mapstructure:"captcha"` + Email EmailConf `mapstructure:"email"` } type DBConf struct { @@ -38,6 +37,15 @@ type LogConf struct { Filename string `mapstructure:"filename"` } +type AdminUserConf struct { + Name string `mapstructure:"name"` + Email string `mapstructure:"email"` + Link string `mapstructure:"link"` + Password string `mapstructure:"password"` + BadgeName string `mapstructure:"badge_name"` + BadgeColor string `mapstructure:"badge_color"` +} + type ModeratorConf struct { PendingDefault bool `mapstructure:"pending_default"` } @@ -100,7 +108,7 @@ func Init(cfgFile string) { } else { // Find config file in path. viper.AddConfigPath(".") - viper.SetConfigName("artalk-go.yaml") + viper.SetConfigName("artalk-go.yml") } viper.SetEnvPrefix("ATG") diff --git a/config/config_test.go b/config/config_test.go index 39dc52b02..5b6c31a0b 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -5,7 +5,7 @@ import ( ) func TestInit(t *testing.T) { - Init("../artalk-go.example.yaml") + Init("../artalk-go.example.yml") t.Log(Instance) } diff --git a/http/api_admin.go b/http/api_admin.go index 880ff427d..64f1bb817 100644 --- a/http/api_admin.go +++ b/http/api_admin.go @@ -1,11 +1,27 @@ package http import ( + "github.com/ArtalkJS/ArtalkGo/lib" + "github.com/ArtalkJS/ArtalkGo/model" "github.com/labstack/echo/v4" ) -func ActionAdminLogin(c echo.Context) error { - return nil +func ActionLogin(c echo.Context) error { + username := c.QueryParam("username") + password := c.QueryParam("password") + if username == "" || password == "" { + return RespError(c, "Incomplete parameters.") + } + + var user model.User + lib.DB.Where("name = ? OR email = ?", username, username).First(user) + if user.IsEmpty() || user.Password != password { + return RespError(c, "验证失败") + } + + return RespData(c, Map{ + "token": LoginGetUserToken(user), + }) } func ActionAdminEdit(c echo.Context) error { diff --git a/http/api_captcha.go b/http/api_captcha.go index 838d39ba6..f723f8fc2 100644 --- a/http/api_captcha.go +++ b/http/api_captcha.go @@ -23,6 +23,10 @@ func ActionCaptchaCheck(c echo.Context) error { ip := c.RealIP() value := c.QueryParam("value") + if value == "" { + return RespError(c, "param `value` is required.") + } + captcha.SetCustomStore(caGlobalStore) if captcha.VerifyString(ip, value) { return RespSuccess(c) diff --git a/http/api_main.go b/http/api_main.go index 91cabb893..7c4eeb5d9 100644 --- a/http/api_main.go +++ b/http/api_main.go @@ -1,77 +1,6 @@ package http -import ( - "github.com/ArtalkJS/ArtalkGo/config" - "github.com/ArtalkJS/ArtalkGo/lib" - "github.com/ArtalkJS/ArtalkGo/model" - "github.com/labstack/echo/v4" - "github.com/mitchellh/mapstructure" - "github.com/sirupsen/logrus" -) - -type ParamsAdd struct { - Name string `mapstructure:"name"` - Content string `mapstructure:"content"` - Email string `mapstructure:"email"` - Link string `mapstructure:"link"` - Rid uint `mapstructure:"rid"` - PageKey string `mapstructure:"page_key"` - Token string `mapstructure:"token"` -} - -func ActionAdd(c echo.Context) error { - var p ParamsAdd - mapstructure.Decode(c.QueryParams(), &p) - - ip := c.RealIP() - ua := c.Request().UserAgent() - - // find user - user := FindUser(p.Name, p.Email) - if user.IsEmpty() { - user = NewUser(p.Name, p.Email, p.Link) // save a new user - } - - user.Link = p.Link - user.LastIP = ip - user.LastUA = ua - UpdateUser(&user) - - // find page - page := FindPage(p.PageKey) - if page.IsEmpty() { - page = NewPage(p.PageKey) - } - - // check if the user is allowed to comment - if isAllowed, err := CheckIfAllowed(c, user, page); !isAllowed { - return err - } - - comment := model.Comment{ - Content: p.Content, - Rid: p.Rid, - UserID: user.ID, - PageID: page.ID, - IP: ip, - UA: ua, - } - - if config.Instance.Moderator.PendingDefault { - comment.Type = model.CommentPending - } - - err := lib.DB.Create(&comment).Error - if err != nil { - logrus.Error("Save Comment error: ", err) - } - - return nil -} - -func ActionGet(c echo.Context) error { - return nil -} +import "github.com/labstack/echo/v4" func ActionUser(c echo.Context) error { return nil diff --git a/http/api_main_add.go b/http/api_main_add.go new file mode 100644 index 000000000..fe95dc5cb --- /dev/null +++ b/http/api_main_add.go @@ -0,0 +1,102 @@ +package http + +import ( + "github.com/ArtalkJS/ArtalkGo/config" + "github.com/ArtalkJS/ArtalkGo/lib" + "github.com/ArtalkJS/ArtalkGo/model" + "github.com/labstack/echo/v4" + "github.com/sirupsen/logrus" +) + +type ParamsAdd struct { + Name string `mapstructure:"name" param:"required"` + Email string `mapstructure:"email" param:"required"` + Link string `mapstructure:"link"` + Content string `mapstructure:"content" param:"required"` + Rid uint `mapstructure:"rid"` + PageKey string `mapstructure:"page_key" param:"required"` + Token string `mapstructure:"token"` +} + +type ResponseAdd struct { + Comment model.CookedComment `json:"comment"` +} + +func ActionAdd(c echo.Context) error { + var p ParamsAdd + if isOK, resp := ParamsDecode(c, ParamsAdd{}, &p); !isOK { + return resp + } + + if !ValidateEmail(p.Email) { + return RespError(c, "Invalid email.") + } + if p.Link != "" && !ValidateURL(p.Link) { + return RespError(c, "Invalid link.") + } + + ip := c.RealIP() + ua := c.Request().UserAgent() + + // find user + user := FindUser(p.Name, p.Email) + if user.IsEmpty() { + user = NewUser(p.Name, p.Email, p.Link) // save a new user + } + user.Link = p.Link + user.LastIP = ip + user.LastUA = ua + UpdateUser(&user) + + // find page + page := FindPage(p.PageKey) + if page.IsEmpty() { + page = NewPage(p.PageKey) + } + + // check if the user is allowed to comment + if isAllowed, resp := CheckIfAllowed(c, user, page); !isAllowed { + return resp + } + + if user.ID == 0 || page.Key == "" { + logrus.Error("Cannot get real user and page.") + return RespError(c, "评论失败") + } + + // check reply comment + if p.Rid != 0 { + parentComment := FindComment(p.Rid) + if parentComment.IsEmpty() { + return RespError(c, "找不到父评论") + } + if parentComment.PageKey != p.PageKey { + return RespError(c, "与父评论的 pageKey 不一致") + } + } + + comment := model.Comment{ + Content: p.Content, + Rid: p.Rid, + UserID: user.ID, + PageKey: page.Key, + IP: ip, + UA: ua, + } + + // default comment type + if config.Instance.Moderator.PendingDefault { + comment.Type = model.CommentPending + } + + // save to database + err := lib.DB.Create(&comment).Error + if err != nil { + logrus.Error("Save Comment error: ", err) + return RespError(c, "评论失败") + } + + return RespData(c, ResponseAdd{ + Comment: comment.ToCooked(), + }) +} diff --git a/http/api_main_get.go b/http/api_main_get.go new file mode 100644 index 000000000..b3fcc123c --- /dev/null +++ b/http/api_main_get.go @@ -0,0 +1,92 @@ +package http + +import ( + "github.com/ArtalkJS/ArtalkGo/lib" + "github.com/ArtalkJS/ArtalkGo/model" + "github.com/labstack/echo/v4" + "gorm.io/gorm" +) + +type ParamsGet struct { + PageKey string `mapstructure:"page_key" param:"required"` + Limit int `mapstructure:"limit"` + Offset int `mapstructure:"offset"` + // TODO: FlatMode string `mapstructure:"flat_mode"` +} + +type ResponseGet struct { + Comments []model.CookedComment `json:"comments"` + Total int64 `json:"total"` + TotalParents int64 `json:"total_parents"` + Page model.CookedPage `json:"page"` +} + +func ActionGet(c echo.Context) error { + var p ParamsGet + if isOK, resp := ParamsDecode(c, ParamsGet{}, &p); !isOK { + return resp + } + + // find page + page := FindPage(p.PageKey) + + // find comments + var comments []model.Comment + lib.DB.Where("page_key = ?", p.PageKey).Scopes(Paginate(p.Offset, p.Limit), FilterAllowedComment(c, p)).Order("created_at DESC").Find(&comments) + + cookedComments := []model.CookedComment{} + for _, c := range comments { + cookedComments = append(cookedComments, c.ToCooked()) + } + + // find children comments + for _, c := range comments { // TODO: Read more children, pagination for children comment + children := c.FetchChildren(func(db *gorm.DB) *gorm.DB { return db.Where("type != ?", model.CommentPending) }) + for _, c := range children { + cookedComments = append(cookedComments, c.ToCooked()) + } + } + + // count comments + total := CountComments(p.PageKey, func(db *gorm.DB) *gorm.DB { + return db.Where("page_key = ?", p.PageKey) + }) + totalParents := CountComments(p.PageKey, func(db *gorm.DB) *gorm.DB { + return db.Where("page_key = ? AND rid = 0", p.PageKey) + }) + + return RespData(c, ResponseGet{ + Comments: cookedComments, + Total: total, + TotalParents: totalParents, + Page: page.ToCooked(), + }) +} + +func Paginate(offset int, limit int) func(db *gorm.DB) *gorm.DB { + if offset < 0 { + offset = 0 + } + + if limit > 100 { + limit = 100 + } else if limit <= 0 { + limit = 15 + } + + return func(db *gorm.DB) *gorm.DB { + return db.Offset(offset).Limit(limit) + } +} + +func FilterAllowedComment(c echo.Context, p ParamsGet) func(db *gorm.DB) *gorm.DB { + return func(db *gorm.DB) *gorm.DB { + return db.Where("rid = 0 AND type != ?", model.CommentPending) + } +} + +func CountComments(pageKey string, filter func(db *gorm.DB) *gorm.DB) int64 { + var count int64 + lib.DB.Model(&model.Comment{}).Scopes(filter).Count(&count) + return count +} diff --git a/http/http.go b/http/http.go index a47987169..efa73b6b3 100644 --- a/http/http.go +++ b/http/http.go @@ -61,11 +61,14 @@ func RespSuccess(c echo.Context) error { // RespError is just response error func RespError(c echo.Context, msg string, details ...string) error { + extraMap := Map{} + if details != nil { + extraMap["errDetails"] = details + } + return c.JSON(http.StatusOK, &JSONResult{ Success: false, Msg: msg, - Extra: Map{ - "errDetails": details, - }, + Extra: extraMap, }) } diff --git a/http/route.go b/http/route.go index a80b17c37..753b7dcac 100644 --- a/http/route.go +++ b/http/route.go @@ -26,9 +26,9 @@ func InitRoute(e *echo.Echo) { api := e.Group("/api") api.GET("/add", ActionAdd) - api.GET("/get", ActionAdd) + api.GET("/get", ActionGet) api.GET("/user", ActionUser) - api.GET("/login-admin", ActionAdminLogin) + api.GET("/login", ActionLogin) // api/captcha ca := api.Group("/captcha") diff --git a/http/utils.go b/http/utils.go index bc8f52573..c5477370c 100644 --- a/http/utils.go +++ b/http/utils.go @@ -1,6 +1,11 @@ package http import ( + "net/mail" + "net/url" + "reflect" + "strconv" + "strings" "time" "github.com/ArtalkJS/ArtalkGo/config" @@ -8,10 +13,11 @@ import ( "github.com/ArtalkJS/ArtalkGo/model" "github.com/golang-jwt/jwt" "github.com/labstack/echo/v4" + "github.com/mitchellh/mapstructure" "github.com/sirupsen/logrus" ) -func LoginUser(user model.User) string { +func LoginGetUserToken(user model.User) string { // Set custom claims claims := &jwtCustomClaims{ UserName: user.Name, @@ -34,6 +40,56 @@ func LoginUser(user model.User) string { return t } +func ParamsDecode(c echo.Context, paramsStruct interface{}, destParams interface{}) (isContinue bool, resp error) { + refVal := reflect.ValueOf(paramsStruct) + for i := 0; i < refVal.Type().NumField(); i++ { + field := refVal.Type().Field(i) + //fieldName := field.Name + paramTagM := field.Tag.Get("mapstructure") + paramTagP := field.Tag.Get("param") + //fmt.Println(field, paramTagM, paramTagP) + + if paramTagM != "" && paramTagP == "required" { + if strings.TrimSpace(c.QueryParam(paramTagM)) == "" { + return false, RespError(c, "Param `"+paramTagM+"` is required.") + } + } + } + + // get the first + params := make(map[string]interface{}) + for k, p := range c.QueryParams() { + params[k] = p[0] + } + + // convet type + for i := 0; i < refVal.Type().NumField(); i++ { + field := refVal.Type().Field(i) + paramName := field.Tag.Get("mapstructure") + + if field.Type.Kind() == reflect.Int { + u64, _ := strconv.ParseInt(c.QueryParam(paramName), 10, 32) + params[paramName] = int(u64) + } + + if field.Type.Kind() == reflect.Uint { + u64, _ := strconv.ParseUint(c.QueryParam(paramName), 10, 32) + params[paramName] = uint(u64) + } + + if field.Type.Kind() == reflect.Array { + params[paramName] = c.QueryParams()[paramName] + } + } + + err := mapstructure.Decode(params, destParams) + if err != nil { + logrus.Error("Params decode error: ", err) + return false, RespError(c, "Params decode error.") + } + return true, nil +} + func CheckIsAdmin(c echo.Context) bool { jwt := c.Get("user").(*jwt.Token) claims := jwt.Claims.(*jwtCustomClaims) @@ -54,7 +110,13 @@ func CheckIsAdmin(c echo.Context) bool { } func CheckIfAllowed(c echo.Context, user model.User, page model.Page) (bool, error) { - return false, nil + return true, nil +} + +func FindComment(id uint) model.Comment { + var comment model.Comment + lib.DB.First(&comment, id) + return comment } func FindUser(name string, email string) model.User { @@ -110,3 +172,13 @@ func UpdatePage(page *model.Page) { logrus.Error("Update Page error: ", err) } } + +func ValidateEmail(email string) bool { + _, err := mail.ParseAddress(email) + return err == nil +} + +func ValidateURL(urlStr string) bool { + _, err := url.ParseRequestURI(urlStr) + return err == nil +} diff --git a/lib/utils.go b/lib/utils.go index 9405379ad..90de7a29a 100644 --- a/lib/utils.go +++ b/lib/utils.go @@ -1,6 +1,8 @@ package lib import ( + "crypto/md5" + "encoding/hex" "errors" "os" ) @@ -23,3 +25,9 @@ func EnsureDir(dirName string) error { } return err } + +func GetMD5Hash(text string) string { + hasher := md5.New() + hasher.Write([]byte(text)) + return hex.EncodeToString(hasher.Sum(nil)) +} diff --git a/model/comment.go b/model/comment.go index 9161f266e..d9838676e 100644 --- a/model/comment.go +++ b/model/comment.go @@ -1,6 +1,9 @@ package model -import "gorm.io/gorm" +import ( + "github.com/ArtalkJS/ArtalkGo/lib" + "gorm.io/gorm" +) type CommentType string @@ -14,13 +17,89 @@ type Comment struct { gorm.Model Content string - UserID uint - PageID uint - User User `gorm:"foreignKey:UserID"` - Page Page `gorm:"foreignKey:PageID"` + UserID uint `gorm:"index"` + PageKey string `gorm:"index"` + User User `gorm:"foreignKey:UserID;references:ID"` + Page Page `gorm:"foreignKey:PageKey;references:Key"` - Rid uint + Rid uint `gorm:"index"` UA string IP string Type CommentType } + +func (c Comment) IsEmpty() bool { + return c.ID == 0 +} + +func (c *Comment) FetchUser() User { + if !c.User.IsEmpty() { + return c.User + } + + // TODO: 先从 Redis 查询 + var user User + lib.DB.First(&user, c.UserID) + + c.User = user + return user +} + +func (c *Comment) FetchPage() Page { + if !c.Page.IsEmpty() { + return c.Page + } + + var page Page + lib.DB.Where(&Page{Key: c.PageKey}).First(&page) + + c.Page = page + return page +} + +func (c Comment) FetchChildren(filter func(db *gorm.DB) *gorm.DB) []Comment { + children := []Comment{} + fetchChildrenOnce(&children, c, filter) // TODO: children 数量限制 + return children +} + +func fetchChildrenOnce(src *[]Comment, parentComment Comment, filter func(db *gorm.DB) *gorm.DB) { + children := []Comment{} + lib.DB.Scopes(filter).Where("rid = ?", parentComment.ID).Order("created_at ASC").Find(&children) + + for _, child := range children { + *src = append(*src, child) + fetchChildrenOnce(src, child, filter) // loop + } +} + +type CookedComment struct { + ID uint `json:"id"` + Content string `json:"content"` + Nick string `json:"nick"` + EmailEncrypted string `json:"email_encrypted"` + Link string `json:"link"` + UA string `json:"ua"` + Date string `json:"date"` + IsCollapsed bool `json:"is_collapsed"` + IsPending bool `json:"is_pending"` + Rid uint `json:"rid"` +} + +func (c Comment) ToCooked() CookedComment { + user := c.FetchUser() + //page := c.FetchPage() + + return CookedComment{ + ID: c.ID, + Content: c.Content, + Nick: user.Name, + EmailEncrypted: lib.GetMD5Hash(user.Email), + Link: user.Link, + UA: c.UA, + Date: c.CreatedAt.Local().String(), + IsCollapsed: c.Type == CommentCollapsed, + IsPending: c.Type == CommentPending, + Rid: c.Rid, + } +} diff --git a/model/page.go b/model/page.go index f7bc2d48a..fe874ef40 100644 --- a/model/page.go +++ b/model/page.go @@ -5,15 +5,29 @@ import "gorm.io/gorm" type PageType string const ( - PageClosed PageType = "closed" + PageCommentClosed PageType = "comment_closed" ) type Page struct { gorm.Model - Key string + Key string `gorm:"uniqueIndex"` Type PageType } func (p Page) IsEmpty() bool { return p.ID == 0 } + +type CookedPage struct { + ID uint `json:"id"` + IsCommentClosed bool `json:"is_comment_closed"` + PageKey string `json:"page_key"` +} + +func (p Page) ToCooked() CookedPage { + return CookedPage{ + ID: p.ID, + IsCommentClosed: p.Type == PageCommentClosed, + PageKey: p.Key, + } +} diff --git a/model/user.go b/model/user.go index 76e99d177..7eff2329f 100644 --- a/model/user.go +++ b/model/user.go @@ -1,6 +1,8 @@ package model -import "gorm.io/gorm" +import ( + "gorm.io/gorm" +) type UserType string @@ -11,15 +13,15 @@ const ( type User struct { gorm.Model - Name string `mapstructure:"name"` - Email string `mapstructure:"email"` - Link string `mapstructure:"link"` - Password string `mapstructure:"password"` - BadgeName string `mapstructure:"badge_name"` - BadgeColor string `mapstructure:"badge_color"` + Name string `gorm:"index"` + Email string `gorm:"index"` + Link string + Password string + BadgeName string + BadgeColor string LastIP string LastUA string - Type UserType + Type UserType `gorm:"index"` } func (u User) IsEmpty() bool { From 7ffeb2ff0bddc6be04195702c2c2fe4db513c9f6 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Thu, 26 Aug 2021 23:02:03 +0800 Subject: [PATCH 007/349] Complete permission checker (ActionLimit) and captcha. --- .vscode/launch.json | 10 +- artalk-go.example.yml | 10 +- cmd/root.go | 13 + config/config.go | 10 +- config/config_test.go | 11 - go.mod | 6 +- go.sum | 332 ++++++++++++++++++++++++- http/a_http.go | 93 +++++++ http/api_captcha.go | 60 +++-- http/api_main_add.go | 4 +- http/{api_admin.go => api_manager.go} | 11 +- http/permission.go | 171 +++++++++++++ http/{http.go => resp.go} | 60 +++-- http/route.go | 56 ----- http/utils.go | 19 -- lib/cache.go | 22 ++ lib/{gorm-logger.go => gorm_logger.go} | 0 17 files changed, 735 insertions(+), 153 deletions(-) delete mode 100644 config/config_test.go create mode 100644 http/a_http.go rename http/{api_admin.go => api_manager.go} (78%) create mode 100644 http/permission.go rename http/{http.go => resp.go} (57%) delete mode 100644 http/route.go create mode 100644 lib/cache.go rename lib/{gorm-logger.go => gorm_logger.go} (100%) diff --git a/.vscode/launch.json b/.vscode/launch.json index f980ab98c..61b381cac 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -3,5 +3,13 @@ // 悬停以查看现有属性的描述。 // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387 "version": "0.2.0", - "configurations": [] + "configurations": [ + { + "name": "Launch Package", + "type": "go", + "request": "launch", + "mode": "auto", + "program": "${fileDirname}" + } + ] } \ No newline at end of file diff --git a/artalk-go.example.yml b/artalk-go.example.yml index ead781c20..8b24bea5d 100644 --- a/artalk-go.example.yml +++ b/artalk-go.example.yml @@ -7,6 +7,9 @@ http_addr: ':23366' # 加密密钥 app_key: 'QXJ0YWxrLmpz' +# 调试模式 +debug: false + # 数据文件 db: type: 'sqlite' # 支持 mysql 和 sqlite @@ -40,9 +43,10 @@ moderator: # 验证码 captcha: enabled: true # 总开关 - # ↓↓ 在 {timeout} 秒内,若再次评论超过 {limit} 次则需要验证码 - timeout: 2400 # 超时:重置评论次数统计(单位:秒) - comment_limit: 3 # 激活验证码的评论次数(设置为 0 总是需要验证码) + always: false # 总是需要验证码 + # ↓ 在 {comment_timeout} 秒内,操作次数超过 {comment_limit} 次激活验证码 + action_timeout: 60 + action_limit: 3 # 邮件通知 email: diff --git a/cmd/root.go b/cmd/root.go index d1218f88d..e7b205ba2 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -48,6 +48,7 @@ func init() { cobra.OnInitialize(initConfig) cobra.OnInitialize(initLog) cobra.OnInitialize(initDB) + cobra.OnInitialize(initCache) rootCmd.SetVersionTemplate("Artalk-GO {{printf \"version %s\" .Version}}\n") rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "配置文件路径 (defaults are './artalk-go.yml')") @@ -85,6 +86,10 @@ func initLog() { logrus.SetFormatter(stdFormatter) logrus.SetOutput(os.Stdout) + if config.Instance.Debug { + logrus.SetLevel(logrus.DebugLevel) + } + if config.Instance.Log.Filename != "" { // 文件保存 pathMap := lfshook.PathMap{ @@ -110,6 +115,14 @@ func initDB() { lib.DB.AutoMigrate(&model.Comment{}, &model.Page{}, &model.User{}) } +func initCache() { + err := lib.OpenCache() + if err != nil { + logrus.Error("缓存初始化发生错误 ", err) + os.Exit(1) + } +} + //// 捷径函数 //// func flag(cmd *cobra.Command, name string, defaultVal interface{}, usage string) { diff --git a/config/config.go b/config/config.go index 6bd238d03..53e3ffb24 100644 --- a/config/config.go +++ b/config/config.go @@ -16,6 +16,7 @@ var Instance *Config type Config struct { SiteName string `mapstructure:"site_name"` // 网站名 AppKey string `mapstructure:"app_key"` // 加密密钥 + Debug bool `mapstructure:"debug"` // 调试模式 HttpAddr string `mapstructure:"http_addr"` // HTTP Server 监听地址 DB DBConf `mapstructure:"db"` // 数据文件 Log LogConf `mapstructure:"log"` // 日志文件 @@ -51,9 +52,10 @@ type ModeratorConf struct { } type CaptchaConf struct { - Enabled bool `mapstructure:"enabled"` - Timeout uint `mapstructure:"timeout"` - CommentLimit uint `mapstructure:"comment_limit"` + Enabled bool `mapstructure:"enabled"` + Always bool `mapstructure:"always"` + ActionTimeout int `mapstructure:"action_timeout"` + ActionLimit int `mapstructure:"action_limit"` } type EmailConf struct { @@ -69,7 +71,7 @@ type EmailConf struct { type SMTPConf struct { Host string `mapstructure:"host"` - Port uint `mapstructure:"port"` + Port int `mapstructure:"port"` SMTPAuth bool `mapstructure:"smtp_auth"` Username string `mapstructure:"username"` Password string `mapstructure:"password"` diff --git a/config/config_test.go b/config/config_test.go deleted file mode 100644 index 5b6c31a0b..000000000 --- a/config/config_test.go +++ /dev/null @@ -1,11 +0,0 @@ -package config - -import ( - "testing" -) - -func TestInit(t *testing.T) { - Init("../artalk-go.example.yml") - - t.Log(Instance) -} diff --git a/go.mod b/go.mod index 5a2cb4cb5..670c5d60c 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,8 @@ module github.com/ArtalkJS/ArtalkGo go 1.16 require ( - github.com/dchest/captcha v0.0.0-20200903113550-03f5f0333e1f // indirect + github.com/allegro/bigcache/v3 v3.0.0 + github.com/eko/gocache/v2 v2.1.0 github.com/fsnotify/fsnotify v1.5.1 // indirect github.com/golang-jwt/jwt v3.2.2+incompatible github.com/kr/text v0.2.0 // indirect @@ -13,7 +14,6 @@ require ( github.com/mattn/go-sqlite3 v1.14.8 // indirect github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect github.com/mitchellh/mapstructure v1.4.1 - github.com/mojocn/base64Captcha v1.3.5 // indirect github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect github.com/onrik/logrus v0.9.0 github.com/onsi/gomega v1.16.0 // indirect @@ -22,9 +22,9 @@ require ( github.com/spf13/cast v1.4.1 // indirect github.com/spf13/cobra v1.2.1 github.com/spf13/viper v1.8.1 + github.com/steambap/captcha v1.4.1 github.com/x-cray/logrus-prefixed-formatter v0.5.2 golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 // indirect - golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d // indirect golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d // indirect golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf // indirect golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b // indirect diff --git a/go.sum b/go.sum index b1378a7ea..55b432a2d 100644 --- a/go.sum +++ b/go.sum @@ -37,31 +37,99 @@ cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohl cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= +github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= +github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= +github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= +github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= +github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= +github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= +github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= +github.com/XiaoMi/pegasus-go-client v0.0.0-20210427083443-f3b6b08bc4c2 h1:pami0oPhVosjOu/qRHepRmdjD6hGILF7DBr+qQZeP10= +github.com/XiaoMi/pegasus-go-client v0.0.0-20210427083443-f3b6b08bc4c2/go.mod h1:jNIx5ykW1MroBuaTja9+VpglmaJOUzezumfhLlER3oY= +github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= +github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= +github.com/allegro/bigcache/v2 v2.2.5 h1:mRc8r6GQjuJsmSKQNPsR5jQVXc8IJ1xsW5YXUYMLfqI= +github.com/allegro/bigcache/v2 v2.2.5/go.mod h1:FppZsIO+IZk7gCuj5FiIDHGygD9xvWQcqg1uIPMb6tY= +github.com/allegro/bigcache/v3 v3.0.0 h1:5Hxq+GTy8gHEeQccCZZDCfZRTydUfErdUf0iVDcMAFg= +github.com/allegro/bigcache/v3 v3.0.0/go.mod h1:t5TAJn1B9qvf/VlJrSM1r6NlFAYoFDubYUsCuIO9nUQ= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= +github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= +github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= +github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= +github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= +github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= +github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= +github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/bketelsen/crypt v0.0.4/go.mod h1:aI6NrJ0pMGgvZKL1iVgXLnfIFJtfV+bKCoqOes/6LfM= +github.com/bradfitz/gomemcache v0.0.0-20190913173617-a41fca850d0b h1:L/QXpzIa3pOvUGt1D1lA5KjYhPBAN/3iWdP7xeFS9F0= +github.com/bradfitz/gomemcache v0.0.0-20190913173617-a41fca850d0b/go.mod h1:H0wQNHz2YrLsuXOZozoeDmnHXkNCRmMW0gwFWDfEZDA= +github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= +github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4= +github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= +github.com/cenkalti/backoff/v4 v4.1.0 h1:c8LkOFQTzuO0WBM/ae5HdGQuZPfPxp7lqBRwQRm4fSc= +github.com/cenkalti/backoff/v4 v4.1.0/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= +github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= +github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= +github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= +github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= +github.com/coocood/freecache v1.1.1 h1:uukNF7QKCZEdZ9gAV7WQzvh0SbjwdMF6m3x3rxEkaPc= +github.com/coocood/freecache v1.1.1/go.mod h1:OKrEjkGVoxZhyWAJoeFi5BMLUJm2Tit0kpGkIr7NGYY= +github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= +github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= +github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/davecgh/go-spew v0.0.0-20151105211317-5215b55f46b2/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/dchest/captcha v0.0.0-20200903113550-03f5f0333e1f h1:q/DpyjJjZs94bziQ7YkBmIlpqbVP7yw179rnzoNVX1M= -github.com/dchest/captcha v0.0.0-20200903113550-03f5f0333e1f/go.mod h1:QGrK8vMWWHQYQ3QU9bw9Y9OPNfxccGzfb41qjvVeXtY= +github.com/dgraph-io/ristretto v0.0.3 h1:jh22xisGBjrEVnRZ1DVTpBVQm0Xndu8sMl0CWDzSIBI= +github.com/dgraph-io/ristretto v0.0.3/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= +github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= +github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= +github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= +github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM= +github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= +github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= +github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= +github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= +github.com/eko/gocache/v2 v2.1.0 h1:ljFKAAa5hHsrsSaBvyx0g9a/A9lZSUrf4jBjErQd7gc= +github.com/eko/gocache/v2 v2.1.0/go.mod h1:u+EpYjCVsOpeqvDLzinOVLjLxwHJjO+NT4LS2+8XnCU= +github.com/elazarl/goproxy v0.0.0-20170405201442-c4fc26588b6e/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= +github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= +github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= @@ -69,27 +137,54 @@ github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5y github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= +github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw= +github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= +github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4= +github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsnotify/fsnotify v1.5.1 h1:mZcQUHVQUQWoPXXtuf9yuEXKudkV2sx1E06UadKWpgI= github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU= +github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o= +github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= +github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= +github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= +github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= +github.com/go-openapi/jsonpointer v0.0.0-20160704185906-46af16f9f7b1/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0= +github.com/go-openapi/jsonreference v0.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg= +github.com/go-openapi/spec v0.0.0-20160808142527-6aced65f8501/go.mod h1:J8+jY1nAiCcj+friV/PDoE1/3eeccG9LYBs0tYvLOWc= +github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I= +github.com/go-redis/redis/v8 v8.9.0 h1:FTTbB7WqlXfVNdVv0SsxA+oVi0bAwit6bMe3IUucq2o= +github.com/go-redis/redis/v8 v8.9.0/go.mod h1:ik7vb7+gm8Izylxu6kf6wG26/t2VljgCfSQ1DM4O1uU= +github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE= github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/gobuffalo/here v0.6.0 h1:hYrd0a6gDmWxBM4TnrGw8mQg24iSVoIkHEk7FodQcBI= github.com/gobuffalo/here v0.6.0/go.mod h1:wAG085dHOYqUpf+Ap+WOdrPTp5IYcDAs/x7PLa8Y5fM= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= +github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY= github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g= github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -100,7 +195,9 @@ github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= +github.com/golang/mock v1.5.0 h1:jlYHihg//f7RRwuPfptm04yp4s7O6Kw8EZiVYIGcH0g= github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= +github.com/golang/protobuf v0.0.0-20161109072736-4bd1920723d7/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -117,7 +214,9 @@ github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= +github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= @@ -130,7 +229,9 @@ github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/gofuzz v0.0.0-20161122191042-44d81051d367/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= @@ -147,14 +248,26 @@ github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLe github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= +github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= +github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= +github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= +github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= +github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE= github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= +github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= @@ -165,6 +278,7 @@ github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerX github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= @@ -175,23 +289,40 @@ github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0m github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= github.com/jinzhu/now v1.1.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= github.com/jinzhu/now v1.1.2 h1:eVKgfIdy9b6zbWBMgFpfDPoAMifwSZagU9HmEU6zgiI= github.com/jinzhu/now v1.1.2/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= +github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= +github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= +github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= +github.com/json-iterator/go v0.0.0-20180612202835-f2b4162afba3/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= +github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= +github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= @@ -201,8 +332,12 @@ github.com/labstack/echo/v4 v4.5.0 h1:JXk6H5PAw9I3GwizqUHhYyS4f45iyGebR/c1xNCeOC github.com/labstack/echo/v4 v4.5.0/go.mod h1:czIriw4a0C1dFun+ObrXp7ok03xON0N1awStJ6ArI7Y= github.com/labstack/gommon v0.3.0 h1:JEeO0bvc78PKdyHxloTKiF8BD5iGrH8T6MSeGvSgob0= github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k= +github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= +github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= +github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= github.com/magiconair/properties v1.8.5 h1:b6kJs+EmPFMYGkow9GiUyCyOvIwYetYJ3fSaWak/Gls= github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= +github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/markbates/pkger v0.17.1 h1:/MKEtWqtc0mZvu9OinB9UzVN9iYCwLWuyUv4Bw+PCno= github.com/markbates/pkger v0.17.1/go.mod h1:0JoVlrol20BSywW79rN3kdFFsE5xYM+rSCQDXbLhiuI= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= @@ -210,14 +345,18 @@ github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVc github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ0s8= github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.13 h1:qdl+GuBjcsKKDco5BsxPJlId98mSWNKqYA+Co0SC1yA= github.com/mattn/go-isatty v0.0.13/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-sqlite3 v1.14.5/go.mod h1:WVKg1VTActs4Qso6iwGbiFih2UIHo0ENGwNd0Lj+XmI= github.com/mattn/go-sqlite3 v1.14.8 h1:gDp86IdQsN/xWjIEmr9MF6o9mpksUgh0fu+9ByFxzIU= github.com/mattn/go-sqlite3 v1.14.8/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= +github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= +github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d h1:5PJl274Y63IEHC+7izoQE9x6ikvDFZS2mDVS3drnohI= github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= @@ -231,64 +370,151 @@ github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh github.com/mitchellh/mapstructure v1.4.1 h1:CpVNEelQCZBooIPDn+AR3NpivK/TIKU8bDxdASFVQag= github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180320133207-05fbef0ca5da/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/mojocn/base64Captcha v1.2.2 h1:NTFnThPVrb3tR66JO/N8/ZHsyFrNc7ho+xRpxBUEIlo= -github.com/mojocn/base64Captcha v1.2.2/go.mod h1:wAQCKEc5bDujxKRmbT6/vTnTt5CjStQ8bRfPWUuz/iY= -github.com/mojocn/base64Captcha v1.3.5 h1:Qeilr7Ta6eDtG4S+tQuZ5+hO+QHbiGAJdi4PfoagaA0= -github.com/mojocn/base64Captcha v1.3.5/go.mod h1:/tTTXn4WTpX9CfrmipqRytCpJ27Uw3G6I7NcP2WwcmY= +github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= +github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= +github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg= +github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU= +github.com/nats-io/nats-server/v2 v2.1.2/go.mod h1:Afk+wRZqkMQs/p45uXdrVLuab3gwv3Z8C4HTBu8GD/k= +github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w= +github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= +github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= +github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= +github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= +github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= +github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= github.com/onrik/logrus v0.9.0 h1:oT7VstCUxWBoX7fswYK61fi9bzRBSpROq5CR2b7wxQo= github.com/onrik/logrus v0.9.0/go.mod h1:qfe9NeZVAJfIxviw3cYkZo3kvBtLoPRJriAO8zl7qTk= +github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= +github.com/onsi/ginkgo v1.15.0/go.mod h1:hF8qUzuuC8DJGygJH3726JnCZX4MYbRB8yFfISqnKUg= github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc= github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= +github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +github.com/onsi/gomega v1.10.5/go.mod h1:gza4q3jKQJijlu05nKWRCW/GavJumGt8aNRxWg7mt48= github.com/onsi/gomega v1.16.0 h1:6gjqkI8iiRHMvdccRJM8rVKjCWk6ZIm6FTm3ddIe4/c= github.com/onsi/gomega v1.16.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= +github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= +github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis= +github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74= +github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxSfWAKL3wpBW7V8scJMt8N8gnaMCS9E/cA= +github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= +github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= +github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= +github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc= +github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ= +github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= +github.com/pegasus-kv/thrift v0.13.0 h1:4ESwaNoHImfbHa9RUGJiJZ4hrxorihZHk5aarYwY8d4= +github.com/pegasus-kv/thrift v0.13.0/go.mod h1:Gl9NT/WHG6ABm6NsrbfE8LiJN0sAyneCrvB4qN4NPqQ= github.com/pelletier/go-toml v1.9.3 h1:zeC5b1GviRUyKYd6OJPvBU/mcVDVoL1OhT17FCt5dSQ= github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= +github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= +github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= +github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= +github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA= github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= +github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= +github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= +github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= +github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= +github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= +github.com/prometheus/client_golang v1.10.0 h1:/o0BDeWzLWXNZ+4q5gXltUvaMpJqckTa+jTNoB+z4cg= +github.com/prometheus/client_golang v1.10.0/go.mod h1:WJM3cc3yu7XKBKa/I8WeZm+V3eltZnBwfENSU7mdogU= +github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M= +github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= +github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= +github.com/prometheus/common v0.18.0 h1:WCVKW7aL6LEe1uryfI9dnEc2ZqNB1Fn0ok930v0iL1Y= +github.com/prometheus/common v0.18.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= +github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= +github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= +github.com/prometheus/procfs v0.6.0 h1:mxy4L2jP6qMonqmq+aTtOx1ifVWUgG/TAmntgbh3xv4= +github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= +github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/rifflock/lfshook v0.0.0-20180920164130-b9218ef580f5 h1:mZHayPoR0lNmnHyvtYjDeq0zlVHn9K/ZXoy17ylucdo= github.com/rifflock/lfshook v0.0.0-20180920164130-b9218ef580f5/go.mod h1:GEXHk5HgEKCvEIIrSpFI3ozzG5xOKA2DVlEX/gGnewM= +github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= +github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= +github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= +github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= +github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= +github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.6.0 h1:xoax2sJ2DT8S8xA2paPFjDCScCNeWsg75VG0DLRreiY= github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cast v1.4.1 h1:s0hze+J0196ZfEMTs80N7UlFt0BDuQ7Q+JDnHiMWKdA= github.com/spf13/cast v1.4.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v1.2.1 h1:+KmjbUw1hriSNMF55oPrkZcb27aECyrj8V2ytv7kWDw= github.com/spf13/cobra v1.2.1/go.mod h1:ExllRjgxM/piMAM+3tAZvg8fsklGAf3tPfi+i8t68Nk= github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= +github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.8.1 h1:Kq1fyeebqsBfbjZj4EL7gj2IO0mMaiyjYUWcUsl2O44= github.com/spf13/viper v1.8.1/go.mod h1:o0Pch8wJ9BVSWGQMbra6iw0oQ5oktSIBaujf1rJH9Ns= +github.com/steambap/captcha v1.4.1 h1:OmMdxLCWCqJvsFaFYwRpvMckIuvI6s8s1LsBrBw97P0= +github.com/steambap/captcha v1.4.1/go.mod h1:oC9T7IfEgnrhzjDz5Djf1H7GPffCzRMbsQfFkJmhlnk= +github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= +github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= +github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v0.0.0-20151208002404-e3a8ff8ce365/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= @@ -298,21 +524,30 @@ github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5Cc github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= +github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= +github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= github.com/valyala/fasttemplate v1.2.1 h1:TVEnxayobAdVkhQfrfes2IzOB6o+z4roRkPF52WA1u4= github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= +github.com/vmihailenco/msgpack v4.0.4+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk= github.com/x-cray/logrus-prefixed-formatter v0.5.2 h1:00txxvfBM9muc0jiLIEAkAcIMJzfthRT6usrui8uGmg= github.com/x-cray/logrus-prefixed-formatter v0.5.2/go.mod h1:2duySbKsL6M18s5GU7VPsoEPHyzalCE06qoARUCeBBE= +github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= +go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs= go.etcd.io/etcd/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ= +go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= +go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= @@ -320,13 +555,30 @@ go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= +go.opentelemetry.io/otel v0.20.0 h1:eaP0Fqu7SXHwvjiqDq83zImeehOHX8doTvU9AwXON8g= +go.opentelemetry.io/otel v0.20.0/go.mod h1:Y3ugLH2oa81t5QO+Lty+zXf8zC9L26ax4Nzoxm/dooo= +go.opentelemetry.io/otel/metric v0.20.0 h1:4kzhXFP+btKm4jwxpjIqjs41A7MakRFUS86bqLHTIw8= +go.opentelemetry.io/otel/metric v0.20.0/go.mod h1:598I5tYlH1vzBjn+BTuhzTCSb/9debfNp6R3s7Pr1eU= +go.opentelemetry.io/otel/oteltest v0.20.0 h1:HiITxCawalo5vQzdHfKeZurV8x7ljcqAgiWzF6Vaeaw= +go.opentelemetry.io/otel/oteltest v0.20.0/go.mod h1:L7bgKf9ZB7qCwT9Up7i9/pn0PWIa9FqQ2IQ8LoxiGnw= +go.opentelemetry.io/otel/trace v0.20.0 h1:1DL6EXUdcg95gukhuRRvLDO/4X5THh/5dIV52lqtnbw= +go.opentelemetry.io/otel/trace v0.20.0/go.mod h1:6GjCW8zgDjwGHGa6GkyeB8+/5vjT16gUEi0Nf1iBdgw= +go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= +go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= +go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= +go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= +golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= @@ -344,8 +596,6 @@ golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= -golang.org/x/image v0.0.0-20190501045829-6d32002ffd75/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= -golang.org/x/image v0.0.0-20190802002840-cff245a6509b h1:+qEpEAPhDZ1o0x3tHzZTQDArnOixOzGD9HUJfcg0mb4= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d h1:RNPAfi2nHY7C2srAV8A49jpsYr0ADedCk1wq6fTMTvs= golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM= @@ -372,21 +622,29 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191105084925-a882066a44e0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -405,6 +663,7 @@ golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81R golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= @@ -436,27 +695,37 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -470,6 +739,8 @@ golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -478,8 +749,10 @@ golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210309074719-68d13333faf2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -493,6 +766,7 @@ golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b h1:9zKuko04nR4gjZ4+DNjHqRlAJqbJETHwiNKDqTfOjfE= golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -503,12 +777,17 @@ golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20201208040808-7e3f01d25324 h1:Hir2P/De0WpUhtrKGGjvSb2YxUgyZ7EFOSLIcSSpiwE= golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181011042414-1f849cf54d09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= @@ -524,6 +803,8 @@ golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgw golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= @@ -532,6 +813,7 @@ golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= @@ -563,7 +845,9 @@ golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= @@ -587,6 +871,7 @@ google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBz google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= google.golang.org/api v0.44.0/go.mod h1:EBOGZqzyhtvMDoxwS97ctnh0zUmYY6CxqXsc1AvkYD8= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= @@ -598,6 +883,7 @@ google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRn google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= @@ -634,10 +920,15 @@ google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= @@ -665,20 +956,35 @@ google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpAD google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= +gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/ini.v1 v1.62.0 h1:duBzk771uxoUuOlyRLkHsygud9+5lrlGjdFBb4mSKDU= gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8= +gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= +gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/tomb.v2 v2.0.0-20161208151619-d5d1b5820637 h1:yiW+nvdHb9LVqSHQBXfZCieqV4fzYhNBql77zY0ykqs= +gopkg.in/tomb.v2 v2.0.0-20161208151619-d5d1b5820637/go.mod h1:BHsqpu/nsuzkT5BpiH1EMZPLyqSMM8JbIavyFACoFNk= +gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= +gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= @@ -695,6 +1001,7 @@ gorm.io/gorm v1.20.7/go.mod h1:0HFTzE/SqkGTzK6TlDPPQbAYCluiVvhzoA1+aVyzenw= gorm.io/gorm v1.21.12/go.mod h1:F+OptMscr0P2F2qU97WT1WimdH9GaQPoDW7AYd5i2Y0= gorm.io/gorm v1.21.13 h1:JU5A4yVemRjdMndJ0oZU7VX+Nr2ICE3C60U5bgR6mHE= gorm.io/gorm v1.21.13/go.mod h1:F+OptMscr0P2F2qU97WT1WimdH9GaQPoDW7AYd5i2Y0= +honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= @@ -702,6 +1009,15 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +k8s.io/apimachinery v0.0.0-20191123233150-4c4803ed55e3 h1:FErmbNIJruD5GT2oVEjtPn5Ar5+rcWJsC8/PPUkR0s4= +k8s.io/apimachinery v0.0.0-20191123233150-4c4803ed55e3/go.mod h1:b9qmWdKlLuU9EBh+06BtLcSf/Mu89rWL33naRxs1uZg= +k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= +k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= +k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I= +k8s.io/kube-openapi v0.0.0-20191107075043-30be4d16710a/go.mod h1:1TqjTSzOxsLGIKfj0lK8EeCP7K1iUG65v09OM0/WG5E= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= +sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI= +sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= +sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU= diff --git a/http/a_http.go b/http/a_http.go new file mode 100644 index 000000000..de83cbd88 --- /dev/null +++ b/http/a_http.go @@ -0,0 +1,93 @@ +package http + +import ( + "net/http" + "strings" + + "github.com/ArtalkJS/ArtalkGo/config" + "github.com/labstack/echo/v4" + "github.com/labstack/echo/v4/middleware" + "github.com/markbates/pkger" + echolog "github.com/onrik/logrus/echo" + "github.com/sirupsen/logrus" +) + +type Map = map[string]interface{} + +func Run() { + e := echo.New() + e.HideBanner = true + + e.Use(middleware.CORSWithConfig(middleware.CORSConfig{ + AllowOrigins: config.Instance.AllowOrigin, + })) + + // Logger + e.Logger = echolog.NewLogger(logrus.StandardLogger(), "") + logConf := echolog.DefaultConfig + logConf.Fields = []string{"ip", "latency", "status", "referer", "user_agent"} // "headers" + e.Use(echolog.Middleware(logConf)) + + // Action Limit + ActionPermissionConf := ActionPermissionConf{ + Skipper: func(c echo.Context) bool { + // 不启用操作限制的 path + skipPath := []string{ + "/api/captcha/", + } + + for _, p := range skipPath { + if strings.HasPrefix(c.Request().URL.Path, p) { + return true + } + } + + return false + }, + } + e.Use(ActionPermission(ActionPermissionConf)) + + CommonJwtConfig = middleware.JWTConfig{ + Claims: &jwtCustomClaims{}, + ContextKey: "user", + SigningMethod: "HS256", + TokenLookup: "header:X-Auth-Token,query:token", + SigningKey: []byte(config.Instance.AppKey), + } + + // Route + InitRoute(e) + + e.Logger.Fatal(e.Start(config.Instance.HttpAddr)) +} + +func InitRoute(e *echo.Echo) { + f, err := pkger.Open("/frontend") + if err != nil { + logrus.Fatal(err) + return + } + + fileServer := http.FileServer(f) + e.GET("/*", echo.WrapHandler(fileServer)) + + // api + api := e.Group("/api") + + api.GET("/add", ActionAdd) + api.GET("/get", ActionGet) + api.GET("/user", ActionUser) + api.GET("/login", ActionLogin) + + // api/captcha + ca := api.Group("/captcha") + ca.GET("/get", ActionCaptchaGet) + ca.GET("/check", ActionCaptchaCheck) + + // api/manager + manager := api.Group("/manager") + manager.GET("/edit", ActionManagerEdit) + manager.GET("/del", ActionManagerDel) + + manager.Use(middleware.JWTWithConfig(CommonJwtConfig)) +} diff --git a/http/api_captcha.go b/http/api_captcha.go index f723f8fc2..ac337c986 100644 --- a/http/api_captcha.go +++ b/http/api_captcha.go @@ -3,44 +3,68 @@ package http import ( "bytes" "encoding/base64" + "strings" "time" - "github.com/dchest/captcha" + "github.com/ArtalkJS/ArtalkGo/lib" + "github.com/eko/gocache/v2/store" "github.com/labstack/echo/v4" + "github.com/steambap/captcha" ) -var caGlobalStore = captcha.NewMemoryStore(100, 10*time.Minute) // TODO: 用 redis 或其他kv数据库来存更多值 - -func ActionCaptchaRefresh(c echo.Context) error { +func ActionCaptchaGet(c echo.Context) error { ip := c.RealIP() return RespData(c, Map{ - "img_data": GetBase64Image(ip, 150, 40), + "img_data": GetNewCaptchaImageBase64(ip), }) } func ActionCaptchaCheck(c echo.Context) error { ip := c.RealIP() - value := c.QueryParam("value") - if value == "" { + inputVal := c.QueryParam("value") + if inputVal == "" { return RespError(c, "param `value` is required.") } - captcha.SetCustomStore(caGlobalStore) - if captcha.VerifyString(ip, value) { + if strings.ToLower(inputVal) == GetCaptchaRealCode(ip) { + // 验证码正确 + ResetActionRecord(c) // 重置操作记录 + DisposeCaptcha(ip) // 销毁验证码 + return RespSuccess(c) } else { - return RespError(c, "验证码错误") + // 验证码错误 + RecordAction(c) // 记录操作 + + return RespError(c, "验证码错误", Map{ + "img_data": GetNewCaptchaImageBase64(ip), + }) + } +} + +func GetCaptchaRealCode(ip string) string { + realVal := "" + if val, err := lib.CACHE.Get(permCtx, "captcha:"+ip); err == nil { + realVal = string(val.([]byte)) } + return strings.ToLower(realVal) +} + +func GetNewCaptchaImageBase64(ip string) string { + // generate a image + pngBuffer := bytes.NewBuffer([]byte{}) + data, _ := captcha.New(150, 40) + data.WriteImage(pngBuffer) + base64 := "data:image/png;base64," + base64.StdEncoding.EncodeToString(pngBuffer.Bytes()) + + // save real code + lib.CACHE.Set(permCtx, "captcha:"+ip, []byte(data.Text), &store.Options{Expiration: 5 * time.Minute}) // 5分钟失效 + + return base64 } -func GetBase64Image(id string, width, height int) string { - png := bytes.NewBuffer([]byte{}) - d := captcha.RandomDigits(6) - captcha.SetCustomStore(caGlobalStore) - caGlobalStore.Set(id, d) - captcha.NewImage(id, d, width, height).WriteTo(png) - base64Code := "data:image/png;base64," + base64.StdEncoding.EncodeToString(png.Bytes()) - return base64Code +func DisposeCaptcha(ip string) { + lib.CACHE.Delete(permCtx, "captcha:"+ip) } diff --git a/http/api_main_add.go b/http/api_main_add.go index fe95dc5cb..5b504c416 100644 --- a/http/api_main_add.go +++ b/http/api_main_add.go @@ -15,7 +15,6 @@ type ParamsAdd struct { Content string `mapstructure:"content" param:"required"` Rid uint `mapstructure:"rid"` PageKey string `mapstructure:"page_key" param:"required"` - Token string `mapstructure:"token"` } type ResponseAdd struct { @@ -38,6 +37,9 @@ func ActionAdd(c echo.Context) error { ip := c.RealIP() ua := c.Request().UserAgent() + // record action for limiting action + RecordAction(c) + // find user user := FindUser(p.Name, p.Email) if user.IsEmpty() { diff --git a/http/api_admin.go b/http/api_manager.go similarity index 78% rename from http/api_admin.go rename to http/api_manager.go index 64f1bb817..da122856e 100644 --- a/http/api_admin.go +++ b/http/api_manager.go @@ -7,14 +7,17 @@ import ( ) func ActionLogin(c echo.Context) error { - username := c.QueryParam("username") + username := c.QueryParam("user") password := c.QueryParam("password") if username == "" || password == "" { return RespError(c, "Incomplete parameters.") } + // record action for limiting action + RecordAction(c) + var user model.User - lib.DB.Where("name = ? OR email = ?", username, username).First(user) + lib.DB.Where("name = ? OR email = ?", username, username).First(&user) if user.IsEmpty() || user.Password != password { return RespError(c, "验证失败") } @@ -24,13 +27,13 @@ func ActionLogin(c echo.Context) error { }) } -func ActionAdminEdit(c echo.Context) error { +func ActionManagerEdit(c echo.Context) error { // user := c.Get("user").(*jwt.Token) // claims := user.Claims.(*jwtCustomClaims) // name := claims.Name return nil } -func ActionAdminDel(c echo.Context) error { +func ActionManagerDel(c echo.Context) error { return nil } diff --git a/http/permission.go b/http/permission.go new file mode 100644 index 000000000..687a9c993 --- /dev/null +++ b/http/permission.go @@ -0,0 +1,171 @@ +package http + +import ( + "context" + "fmt" + "strconv" + "time" + + "github.com/ArtalkJS/ArtalkGo/config" + "github.com/ArtalkJS/ArtalkGo/lib" + "github.com/ArtalkJS/ArtalkGo/model" + "github.com/golang-jwt/jwt" + "github.com/labstack/echo/v4" + "github.com/labstack/echo/v4/middleware" + "github.com/sirupsen/logrus" +) + +var permCtx = context.Background() +var CommonJwtConfig middleware.JWTConfig + +// jwtCustomClaims are custom claims extending default ones. +// See https://github.com/golang-jwt/jwt for more examples +type jwtCustomClaims struct { + UserName string `json:"name"` + UserEmail string `json:"email"` + UserType model.UserType `json:"type"` + jwt.StandardClaims +} + +type Skipper func(echo.Context) bool +type ActionPermissionConf struct { + Skipper Skipper +} + +// 操作限制 中间件 +func ActionPermission(conf ActionPermissionConf) echo.MiddlewareFunc { + return func(next echo.HandlerFunc) echo.HandlerFunc { + return func(c echo.Context) error { + if conf.Skipper(c) { + return next(c) + } + + if !CheckIsAdmin(c) && IsActionOverLimit(c) { + if config.Instance.Debug { + logrus.Debug("[操作限制] 次数: ", getActionCount(c), ", 最后时间:", getActionLastTime(c)) + } + return RespError(c, "需要验证码", Map{ + "need_captcha": true, + "img_data": GetNewCaptchaImageBase64(c.RealIP()), + }) + } else { + return next(c) + } + } + } +} + +// 操作是否超过限制 +func IsActionOverLimit(c echo.Context) bool { + if config.Instance.Captcha.Always { // 总是需要验证码 + return true + } + + if time.Since(getActionLastTime(c)).Seconds() <= float64(config.Instance.Captcha.ActionTimeout) { // 在时间内 + if getActionCount(c) >= config.Instance.Captcha.ActionLimit { // 操作次数超过 + RecordAction(c) // 记录操作 + return true + } + } else { // 不在时间内,超时 + ResetActionRecord(c) // 重置操作记录 + } + + return false +} + +// 记录操作 +func RecordAction(c echo.Context) { + updateActionLastTime(c) // 更新最后操作时间 + addActionCount(c) // 操作次数 +1 +} + +// 重置操作记录 +func ResetActionRecord(c echo.Context) { + ip := c.RealIP() + + lib.CACHE.Delete(permCtx, "action-time:"+ip) + lib.CACHE.Delete(permCtx, "action-count:"+ip) +} + +// 修改最后操作时间 +func updateActionLastTime(c echo.Context) { + curtTime := fmt.Sprintf("%v", time.Now().Unix()) + lib.CACHE.Set(permCtx, "action-time:"+c.RealIP(), []byte(curtTime), nil) +} + +// 获取最后操作时间 +func getActionLastTime(c echo.Context) time.Time { + var timestamp int64 + if val, err := lib.CACHE.Get(permCtx, "action-time:"+c.RealIP()); err == nil { + timestamp, _ = strconv.ParseInt(string(val.([]byte)), 10, 64) + } + tm := time.Unix(timestamp, 0) + return tm +} + +// 获取操作次数 +func getActionCount(c echo.Context) int { + count := 0 + if val, err := lib.CACHE.Get(permCtx, "action-count:"+c.RealIP()); err == nil { + count, _ = strconv.Atoi(string(val.([]byte))) + } + + return count +} + +// 修改操作次数 +func setActionCount(c echo.Context, num int) { + lib.CACHE.Set(permCtx, "action-count:"+c.RealIP(), []byte(fmt.Sprintf("%d", num)), nil) +} + +// 操作次数 +1 +func addActionCount(c echo.Context) { + setActionCount(c, getActionCount(c)+1) +} + +func CheckIsAdmin(c echo.Context) bool { + isAdmin := false + token := c.Param("token") + if token == "" { + token = c.Request().Header.Get("X-Auth-Token") + } + if token != "" { + jwt, err := jwt.Parse(token, func(t *jwt.Token) (interface{}, error) { + if t.Method.Alg() != CommonJwtConfig.SigningMethod { + return nil, fmt.Errorf("unexpected jwt signing method=%v", t.Header["alg"]) + } + + return []byte(config.Instance.AppKey), nil // 密钥 + }) + + if err == nil { + isAdmin = CheckIsAdminByJwt(jwt) + } + } + return isAdmin +} + +func CheckIsAdminByJwt(jwt *jwt.Token) bool { + claims := jwt.Claims.(*jwtCustomClaims) + name := claims.UserName + email := claims.UserEmail + + if claims.UserType != model.UserAdmin { + return false + } + + // check user from database + user := FindUser(name, email) + if user.IsEmpty() { + return false + } + + return user.Type == model.UserAdmin +} + +// 中间件会创建一个 user context,通过中间件获取到的 jwt 判断 +func CheckIsAdminByJwtMiddleware(c echo.Context) bool { + jwt := c.Get("user").(*jwt.Token) + + return CheckIsAdminByJwt(jwt) +} diff --git a/http/http.go b/http/resp.go similarity index 57% rename from http/http.go rename to http/resp.go index efa73b6b3..f1ace9cb0 100644 --- a/http/http.go +++ b/http/resp.go @@ -2,31 +2,12 @@ package http import ( "net/http" + "strconv" - "github.com/ArtalkJS/ArtalkGo/config" "github.com/labstack/echo/v4" - "github.com/labstack/echo/v4/middleware" - echolog "github.com/onrik/logrus/echo" "github.com/sirupsen/logrus" ) -type Map = map[string]interface{} - -func Run() { - e := echo.New() - e.HideBanner = true - - e.Use(middleware.CORSWithConfig(middleware.CORSConfig{ - AllowOrigins: config.Instance.AllowOrigin, - })) - e.Logger = echolog.NewLogger(logrus.StandardLogger(), "") - e.Use(echolog.Middleware(echolog.DefaultConfig)) - - InitRoute(e) - - e.Logger.Fatal(e.Start(config.Instance.HttpAddr)) -} - // JSONResult JSON 响应数据结构 type JSONResult struct { Success bool `json:"success"` // 是否成功 @@ -60,15 +41,44 @@ func RespSuccess(c echo.Context) error { } // RespError is just response error -func RespError(c echo.Context, msg string, details ...string) error { - extraMap := Map{} - if details != nil { - extraMap["errDetails"] = details +func RespError(c echo.Context, msg string, data ...interface{}) error { + // log + req := c.Request() + path := req.URL.Path + if path == "" { + path = "/" } + LogWithHttpInfo(c).Errorf("[响应] %s %s ==> %s", req.Method, path, strconv.Quote(msg)) return c.JSON(http.StatusOK, &JSONResult{ Success: false, Msg: msg, - Extra: extraMap, + Data: data, }) } + +func LogWithHttpInfo(c echo.Context) *logrus.Entry { + fields := logrus.Fields{} + + req := c.Request() + res := c.Response() + + path := req.URL.Path + if path == "" { + path = "/" + } + + id := req.Header.Get(echo.HeaderXRequestID) + if id == "" { + id = res.Header().Get(echo.HeaderXRequestID) + } + fields["id"] = id + fields["ip"] = c.RealIP() + fields["host"] = req.Host + fields["referer"] = req.Referer() + fields["user_agent"] = req.UserAgent() + fields["status"] = res.Status + //fields["headers"] = req.Header + + return logrus.WithFields(fields) +} diff --git a/http/route.go b/http/route.go deleted file mode 100644 index 753b7dcac..000000000 --- a/http/route.go +++ /dev/null @@ -1,56 +0,0 @@ -package http - -import ( - "net/http" - - "github.com/ArtalkJS/ArtalkGo/config" - "github.com/ArtalkJS/ArtalkGo/model" - "github.com/golang-jwt/jwt" - "github.com/labstack/echo/v4" - "github.com/labstack/echo/v4/middleware" - "github.com/markbates/pkger" - "github.com/sirupsen/logrus" -) - -func InitRoute(e *echo.Echo) { - f, err := pkger.Open("/frontend") - if err != nil { - logrus.Fatal(err) - return - } - - fileServer := http.FileServer(f) - e.GET("/*", echo.WrapHandler(fileServer)) - - // api - api := e.Group("/api") - - api.GET("/add", ActionAdd) - api.GET("/get", ActionGet) - api.GET("/user", ActionUser) - api.GET("/login", ActionLogin) - - // api/captcha - ca := api.Group("/captcha") - ca.GET("/refresh", ActionCaptchaRefresh) - ca.GET("/check", ActionCaptchaCheck) - - // api/admin - admin := api.Group("/admin") - admin.GET("/edit", ActionAdminEdit) - admin.GET("/del", ActionAdminDel) - - admin.Use(middleware.JWTWithConfig(middleware.JWTConfig{ - Claims: &jwtCustomClaims{}, - SigningKey: []byte(config.Instance.AppKey), - })) -} - -// jwtCustomClaims are custom claims extending default ones. -// See https://github.com/golang-jwt/jwt for more examples -type jwtCustomClaims struct { - UserName string `json:"name"` - UserEmail string `json:"email"` - UserType model.UserType `json:"type"` - jwt.StandardClaims -} diff --git a/http/utils.go b/http/utils.go index c5477370c..e18bc1c28 100644 --- a/http/utils.go +++ b/http/utils.go @@ -90,25 +90,6 @@ func ParamsDecode(c echo.Context, paramsStruct interface{}, destParams interface return true, nil } -func CheckIsAdmin(c echo.Context) bool { - jwt := c.Get("user").(*jwt.Token) - claims := jwt.Claims.(*jwtCustomClaims) - name := claims.UserName - email := claims.UserEmail - - if claims.UserType != model.UserAdmin { - return false - } - - // check user from database - user := FindUser(name, email) - if user.IsEmpty() { - return false - } - - return user.Type == model.UserAdmin -} - func CheckIfAllowed(c echo.Context, user model.User, page model.Page) (bool, error) { return true, nil } diff --git a/lib/cache.go b/lib/cache.go new file mode 100644 index 000000000..6f950a10f --- /dev/null +++ b/lib/cache.go @@ -0,0 +1,22 @@ +package lib + +import ( + "time" + + "github.com/allegro/bigcache/v3" + "github.com/eko/gocache/v2/cache" + "github.com/eko/gocache/v2/store" +) + +var CACHE *cache.Cache + +func OpenCache() (err error) { + bigcacheClient, err := bigcache.NewBigCache(bigcache.DefaultConfig(30 * time.Minute)) // TODO 过期时间是一样的,只有 Redis 才能设置单个 key 的 + if err != nil { + return err + } + + bigcacheStore := store.NewBigcache(bigcacheClient, nil) // No options provided (as second argument) + CACHE = cache.New(bigcacheStore) + return +} diff --git a/lib/gorm-logger.go b/lib/gorm_logger.go similarity index 100% rename from lib/gorm-logger.go rename to lib/gorm_logger.go From e55d31656b036732d2c2758e22040ab671069110 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Fri, 27 Aug 2021 00:16:49 +0800 Subject: [PATCH 008/349] Complete 3 ways to send email: smtp, ali_dm, sendmail. --- .vscode/settings.json | 2 + artalk-go.example.yml | 9 ++- config/config.go | 15 +++-- go.mod | 3 + go.sum | 6 ++ lib/email_sender.go | 125 ++++++++++++++++++++++++++++++++++++++++++ lib/gorm_logger.go | 6 +- 7 files changed, 150 insertions(+), 16 deletions(-) create mode 100644 lib/email_sender.go diff --git a/.vscode/settings.json b/.vscode/settings.json index 088284993..e3f6b4fe4 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,8 +1,10 @@ { "cSpell.words": [ "artalk", + "gomail", "gorm", "lfshook", + "sendmail", "smpt", "sqlite" ] diff --git a/artalk-go.example.yml b/artalk-go.example.yml index 8b24bea5d..eb06c80e0 100644 --- a/artalk-go.example.yml +++ b/artalk-go.example.yml @@ -52,20 +52,19 @@ captcha: email: enabled: true # 总开关 admin_addr: 'example@example.com' # 管理员邮箱地址(文章收到评论时通知) - sender_type: 'smtp' # 发送方式(ali_dm or smtp) + sender_type: 'smtp' # 发送方式(ali_dm, smtp, sendmail) mail_title: '您在 [站名] 收到了新的回复' mail_title_to_admin: '您的文章收到了新的回复' mail_tpl_name: 'default.html' # 邮件模板文件(/email-tpl 目录下存放) smtp: host: 'smtp.qq.com' - port: 465 - smtp_auth: true + port: 587 username: 'example@qq.com' password: '' - smtp_secure: 'ssl' from_addr: 'example@qq.com' # 发件人邮箱 from_name: '站名' # 发件人显示的名称 - ali_dm: # https://help.aliyun.com/document_detail/29414.html + ali_dm: # https://help.aliyun.com/document_detail/29444.html access_key_id: '' # 阿里云颁发给用户的访问服务所用的密钥 ID access_key_secret: '' # 用于加密的密钥 account_name: 'example@example.com' # 管理控制台中配置的发信地址 + from_alias: '' # 发信人昵称 diff --git a/config/config.go b/config/config.go index 53e3ffb24..003921155 100644 --- a/config/config.go +++ b/config/config.go @@ -70,20 +70,19 @@ type EmailConf struct { } type SMTPConf struct { - Host string `mapstructure:"host"` - Port int `mapstructure:"port"` - SMTPAuth bool `mapstructure:"smtp_auth"` - Username string `mapstructure:"username"` - Password string `mapstructure:"password"` - SMTPSecure string `mapstructure:"smtp_secure"` - FromAddr string `mapstructure:"from_addr"` - FromName string `mapstructure:"from_name"` + Host string `mapstructure:"host"` + Port int `mapstructure:"port"` + Username string `mapstructure:"username"` + Password string `mapstructure:"password"` + FromAddr string `mapstructure:"from_addr"` + FromName string `mapstructure:"from_name"` } type AliDMConf struct { AccessKeyId string `mapstructure:"access_key_id"` AccessKeySecret string `mapstructure:"access_key_secret"` AccountName string `mapstructure:"account_name"` + FromAlias string `mapstructure:"from_alias"` } type DBType string diff --git a/go.mod b/go.mod index 670c5d60c..b4aef9401 100644 --- a/go.mod +++ b/go.mod @@ -17,6 +17,7 @@ require ( github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect github.com/onrik/logrus v0.9.0 github.com/onsi/gomega v1.16.0 // indirect + github.com/qwqcode/go-aliyun-email v0.0.0-20180120030821-cb6e7b1382bf github.com/rifflock/lfshook v0.0.0-20180920164130-b9218ef580f5 github.com/sirupsen/logrus v1.8.1 github.com/spf13/cast v1.4.1 // indirect @@ -29,7 +30,9 @@ require ( golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf // indirect golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b // indirect golang.org/x/text v0.3.7 // indirect + gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f // indirect + gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df gorm.io/driver/mysql v1.1.2 gorm.io/driver/sqlite v1.1.4 gorm.io/gorm v1.21.13 diff --git a/go.sum b/go.sum index 55b432a2d..e358350d6 100644 --- a/go.sum +++ b/go.sum @@ -468,6 +468,8 @@ github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+Gx github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.6.0 h1:mxy4L2jP6qMonqmq+aTtOx1ifVWUgG/TAmntgbh3xv4= github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= +github.com/qwqcode/go-aliyun-email v0.0.0-20180120030821-cb6e7b1382bf h1:FH9O7I17HCdVYbK1IMxTGgD3bVuTzyO45bR94iE+T/U= +github.com/qwqcode/go-aliyun-email v0.0.0-20180120030821-cb6e7b1382bf/go.mod h1:5N3D7E1/M3G95YK4jPjcPRf/A7XBis0ni4VMmcVnnRY= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/rifflock/lfshook v0.0.0-20180920164130-b9218ef580f5 h1:mZHayPoR0lNmnHyvtYjDeq0zlVHn9K/ZXoy17ylucdo= github.com/rifflock/lfshook v0.0.0-20180920164130-b9218ef580f5/go.mod h1:GEXHk5HgEKCvEIIrSpFI3ozzG5xOKA2DVlEX/gGnewM= @@ -959,6 +961,8 @@ google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp0 google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= +gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc h1:2gGKlE2+asNV9m7xrywl36YYNnBG5ZQ0r/BOOxqPpmk= +gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc/go.mod h1:m7x9LTH6d71AHyAX77c9yqWCCa3UKHcVEj9y7hAtKDk= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -968,6 +972,8 @@ gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qS gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= +gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df h1:n7WqCuqOuCbNr617RXOY0AWRXxgwEyPp2z+p0+hgMuE= +gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df/go.mod h1:LRQQ+SO6ZHR7tOkpBDuZnXENFzX8qRjMDMyPD6BRkCw= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/ini.v1 v1.62.0 h1:duBzk771uxoUuOlyRLkHsygud9+5lrlGjdFBb4mSKDU= gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= diff --git a/lib/email_sender.go b/lib/email_sender.go new file mode 100644 index 000000000..cfd9cc665 --- /dev/null +++ b/lib/email_sender.go @@ -0,0 +1,125 @@ +package lib + +import ( + "bytes" + "io/ioutil" + "os/exec" + + "github.com/ArtalkJS/ArtalkGo/config" + ali_dm "github.com/qwqcode/go-aliyun-email" + "github.com/sirupsen/logrus" + "gopkg.in/gomail.v2" +) + +type Email struct { + FromAddr string + FromName string + ToAddr string + Subject string + Body string +} + +func SendEmailBySMTP(email Email) bool { + smtp := config.Instance.Email.SMTP + + m := GenerateEmailMessage(email) + d := gomail.NewDialer(smtp.Host, smtp.Port, smtp.Username, smtp.Password) + + // 发送邮件 + if err := d.DialAndSend(m); err != nil { + logrus.Error("[EMAIL] SMTP 邮件发送失败 ", err) + return false + } + return true +} + +func SendEmailByAliDM(email Email) bool { + client := ali_dm.NewClient( + config.Instance.Email.AliDM.AccessKeyId, + config.Instance.Email.AliDM.AccessKeySecret, + config.Instance.Email.AliDM.AccountName, + config.Instance.Email.AliDM.FromAlias, + ali_dm.RegionCNHangZhou, + ) + req := &ali_dm.SingleRequest{ + ReplyToAddress: true, + AddressType: 1, + ToAddress: email.ToAddr, + Subject: email.Subject, + HtmlBody: email.Body, + } + + resp, err := client.SingleRequest(req) + if err != nil { + logrus.Error("[EMAIL] ali_dm 邮件发送失败 ", err) + return false + } + + if config.Instance.Debug { + logrus.Debug(resp) + } + + return true +} + +func SendEmailByUsingSystemCMD(email Email) bool { + LogTag := "[EMAIL] sendmail" + msg := GenerateEmailMineTxt(email) + + // 调用系统 sendmail + sendmail := exec.Command("/usr/sbin/sendmail", "-t", "-oi") + stdin, err := sendmail.StdinPipe() + if err != nil { + logrus.Error(LogTag, err) + return false + } + + stdout, err := sendmail.StdoutPipe() + if err != nil { + logrus.Error(LogTag, err) + return false + } + + sendmail.Start() + stdin.Write([]byte(msg)) + stdin.Close() + sentBytes, _ := ioutil.ReadAll(stdout) + if err := sendmail.Wait(); err != nil { + logrus.Error(LogTag, err) + if exitError, ok := err.(*exec.ExitError); ok { + logrus.Error(LogTag, "Exit code is %d", exitError.ExitCode()) + } + return false + } + + if config.Instance.Debug { + logrus.Debug(string(sentBytes)) + } + + return true +} + +func GenerateEmailMessage(email Email) *gomail.Message { + m := gomail.NewMessage() + + // 发送人 + m.SetHeader("From", m.FormatAddress(email.FromAddr, email.FromName)) + // 接收人 + m.SetHeader("To", email.ToAddr) + // 抄送人 + //m.SetAddressHeader("Cc", "dan@example.com", "Dan") + // 主题 + m.SetHeader("Subject", email.Subject) + // 内容 + m.SetBody("text/html", email.Body) + // 附件 + //m.Attach("./file.png") + + return m +} + +func GenerateEmailMineTxt(email Email) string { + emailBuffer := bytes.NewBuffer([]byte{}) + GenerateEmailMessage(email).WriteTo(emailBuffer) + return string(emailBuffer.Bytes()[:]) +} diff --git a/lib/gorm_logger.go b/lib/gorm_logger.go index b8ea2dce3..99e18d2b3 100644 --- a/lib/gorm_logger.go +++ b/lib/gorm_logger.go @@ -28,15 +28,15 @@ func (l *gLogger) LogMode(gormlogger.LogLevel) gormlogger.Interface { } func (l *gLogger) Info(ctx context.Context, s string, args ...interface{}) { - log.WithContext(ctx).Infof(s, args) + log.WithContext(ctx).Infof(s, args...) } func (l *gLogger) Warn(ctx context.Context, s string, args ...interface{}) { - log.WithContext(ctx).Warnf(s, args) + log.WithContext(ctx).Warnf(s, args...) } func (l *gLogger) Error(ctx context.Context, s string, args ...interface{}) { - log.WithContext(ctx).Errorf(s, args) + log.WithContext(ctx).Errorf(s, args...) } func (l *gLogger) Trace(ctx context.Context, begin time.Time, fc func() (string, int64), err error) { From 225d6029fc8d0da7284d359a39d4c41ac67b5b24 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Fri, 27 Aug 2021 00:36:58 +0800 Subject: [PATCH 009/349] Update README.md --- README.md | 24 +++++++++++++++++++++--- artalk-go.example.yml | 2 +- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 16b229d54..7936998b0 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,23 @@ -# ArtalkGo -

Artalk -

\ No newline at end of file +

+ +# ArtalkGo + +> ArtalkGo: the Artalk golang version. + +- 跨平台 +- 轻松部署 +- 可视化图形界面 +- 命令行管理 +- 多站点支持 +- 用户鉴权机制 +- 全局验证码操作限制 +- 规范化 API + +## 支持 + +- 跨平台:支持 Linux, Win, Darwin +- 数据存储:支持 SQLite, MySQL... +- 高效缓存:支持 Redis, Memory... +- 邮件发送:支持 SMTP, 阿里云邮件, 系统调用 sendmail 等发送邮件 diff --git a/artalk-go.example.yml b/artalk-go.example.yml index eb06c80e0..dc0974ef2 100644 --- a/artalk-go.example.yml +++ b/artalk-go.example.yml @@ -52,7 +52,7 @@ captcha: email: enabled: true # 总开关 admin_addr: 'example@example.com' # 管理员邮箱地址(文章收到评论时通知) - sender_type: 'smtp' # 发送方式(ali_dm, smtp, sendmail) + sender_type: 'smtp' # 发送方式 [ali_dm, smtp, sendmail] mail_title: '您在 [站名] 收到了新的回复' mail_title_to_admin: '您的文章收到了新的回复' mail_tpl_name: 'default.html' # 邮件模板文件(/email-tpl 目录下存放) From d8eac4825beebcccf623b043e5294f0102a7e449 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Fri, 27 Aug 2021 00:48:06 +0800 Subject: [PATCH 010/349] CommentAdd action check the admin user. --- README.md | 3 +++ http/api_main_add.go | 17 +++++++++++++---- http/permission.go | 4 ++-- model/user.go | 4 ++++ 4 files changed, 22 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 7936998b0..613968cbf 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,9 @@ - 可视化图形界面 - 命令行管理 - 多站点支持 +- 评论获取分页 +- 邮件异步队列发送 +- 邮件多模板自定义 - 用户鉴权机制 - 全局验证码操作限制 - 规范化 API diff --git a/http/api_main_add.go b/http/api_main_add.go index 5b504c416..cbda0714a 100644 --- a/http/api_main_add.go +++ b/http/api_main_add.go @@ -45,10 +45,13 @@ func ActionAdd(c echo.Context) error { if user.IsEmpty() { user = NewUser(p.Name, p.Email, p.Link) // save a new user } - user.Link = p.Link - user.LastIP = ip - user.LastUA = ua - UpdateUser(&user) + + // admin user check + if !user.IsEmpty() && user.IsAdmin() { + if !CheckIsAdminReq(c) { + return RespError(c, "需要验证管理员身份", Map{"need_password": true}) + } + } // find page page := FindPage(p.PageKey) @@ -98,6 +101,12 @@ func ActionAdd(c echo.Context) error { return RespError(c, "评论失败") } + // update user + user.Link = p.Link + user.LastIP = ip + user.LastUA = ua + UpdateUser(&user) + return RespData(c, ResponseAdd{ Comment: comment.ToCooked(), }) diff --git a/http/permission.go b/http/permission.go index 687a9c993..73cad15ab 100644 --- a/http/permission.go +++ b/http/permission.go @@ -40,7 +40,7 @@ func ActionPermission(conf ActionPermissionConf) echo.MiddlewareFunc { return next(c) } - if !CheckIsAdmin(c) && IsActionOverLimit(c) { + if !CheckIsAdminReq(c) && IsActionOverLimit(c) { if config.Instance.Debug { logrus.Debug("[操作限制] 次数: ", getActionCount(c), ", 最后时间:", getActionLastTime(c)) } @@ -123,7 +123,7 @@ func addActionCount(c echo.Context) { setActionCount(c, getActionCount(c)+1) } -func CheckIsAdmin(c echo.Context) bool { +func CheckIsAdminReq(c echo.Context) bool { isAdmin := false token := c.Param("token") if token == "" { diff --git a/model/user.go b/model/user.go index 7eff2329f..729290c97 100644 --- a/model/user.go +++ b/model/user.go @@ -27,3 +27,7 @@ type User struct { func (u User) IsEmpty() bool { return u.ID == 0 } + +func (u User) IsAdmin() bool { + return u.Type == UserAdmin +} From f9412bf098dbf5701248e2c345c4f6c0f4e4c0da Mon Sep 17 00:00:00 2001 From: qwqcode Date: Fri, 27 Aug 2021 01:12:39 +0800 Subject: [PATCH 011/349] Add more sql database supports. --- README.md | 2 +- artalk-go.example.yml | 2 +- config/config.go | 6 ++- go.mod | 2 + go.sum | 105 ++++++++++++++++++++++++++++++++++++++++++ lib/db.go | 26 +++++++++-- 6 files changed, 134 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 613968cbf..fc62d1d94 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,6 @@ ## 支持 - 跨平台:支持 Linux, Win, Darwin -- 数据存储:支持 SQLite, MySQL... +- 数据存储:支持 SQLite, MySQL, PostgreSQL, SQL Server... - 高效缓存:支持 Redis, Memory... - 邮件发送:支持 SMTP, 阿里云邮件, 系统调用 sendmail 等发送邮件 diff --git a/artalk-go.example.yml b/artalk-go.example.yml index dc0974ef2..3a04f31c8 100644 --- a/artalk-go.example.yml +++ b/artalk-go.example.yml @@ -12,7 +12,7 @@ debug: false # 数据文件 db: - type: 'sqlite' # 支持 mysql 和 sqlite + type: 'sqlite' # 支持 mysql, sqlite, pgsql, sqlserver dsn: './local/artalk-go.db' # 日志 diff --git a/config/config.go b/config/config.go index 003921155..4e716ae1c 100644 --- a/config/config.go +++ b/config/config.go @@ -88,8 +88,10 @@ type AliDMConf struct { type DBType string const ( - TypeMySql DBType = "mysql" - TypeSqlite DBType = "sqlite" + TypeMySql DBType = "mysql" + TypeSQLite DBType = "sqlite" + TypePostgreSQL DBType = "pgsql" + TypeSqlServer DBType = "sqlserver" ) type EmailSenderType string diff --git a/go.mod b/go.mod index b4aef9401..04fe07fa6 100644 --- a/go.mod +++ b/go.mod @@ -34,6 +34,8 @@ require ( gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f // indirect gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df gorm.io/driver/mysql v1.1.2 + gorm.io/driver/postgres v1.1.0 gorm.io/driver/sqlite v1.1.4 + gorm.io/driver/sqlserver v1.0.8 gorm.io/gorm v1.21.13 ) diff --git a/go.sum b/go.sum index e358350d6..a82570441 100644 --- a/go.sum +++ b/go.sum @@ -41,6 +41,8 @@ github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= +github.com/Masterminds/semver/v3 v3.1.1 h1:hLg3sBzpNErnxhQtUy/mmLR2I9foDujNK030IGemrRc= +github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= @@ -96,6 +98,8 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I= +github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= github.com/coocood/freecache v1.1.1 h1:uukNF7QKCZEdZ9gAV7WQzvh0SbjwdMF6m3x3rxEkaPc= @@ -103,6 +107,8 @@ github.com/coocood/freecache v1.1.1/go.mod h1:OKrEjkGVoxZhyWAJoeFi5BMLUJm2Tit0kp github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= @@ -113,6 +119,8 @@ github.com/davecgh/go-spew v0.0.0-20151105211317-5215b55f46b2/go.mod h1:J7Y8YcW2 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/denisenkom/go-mssqldb v0.10.0 h1:QykgLZBorFE95+gO3u9esLd0BmbvpWp0/waNNZfHBM8= +github.com/denisenkom/go-mssqldb v0.10.0/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU= github.com/dgraph-io/ristretto v0.0.3 h1:jh22xisGBjrEVnRZ1DVTpBVQm0Xndu8sMl0CWDzSIBI= github.com/dgraph-io/ristretto v0.0.3/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= @@ -173,6 +181,8 @@ github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg78 github.com/gobuffalo/here v0.6.0 h1:hYrd0a6gDmWxBM4TnrGw8mQg24iSVoIkHEk7FodQcBI= github.com/gobuffalo/here v0.6.0/go.mod h1:wAG085dHOYqUpf+Ap+WOdrPTp5IYcDAs/x7PLa8Y5fM= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/gofrs/uuid v3.2.0+incompatible h1:y12jRkkFxsd7GpqdSZ+/KCs/fJbqpEXSGd4+jfEaewE= +github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= @@ -181,6 +191,8 @@ github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d/go.mod h1:SlYgWuQ5 github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY= github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= +github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe h1:lXe2qZdvpiX5WZkZR4hgp4KJVfY3nMkvmwbVkpv1rVY= +github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g= github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= @@ -295,6 +307,58 @@ github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1: github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= +github.com/jackc/chunkreader v1.0.0 h1:4s39bBR8ByfqH+DKm8rQA3E1LHZWB9XWcrz8fqaZbe0= +github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo= +github.com/jackc/chunkreader/v2 v2.0.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk= +github.com/jackc/chunkreader/v2 v2.0.1 h1:i+RDz65UE+mmpjTfyz0MoVTnzeYxroil2G82ki7MGG8= +github.com/jackc/chunkreader/v2 v2.0.1/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk= +github.com/jackc/pgconn v0.0.0-20190420214824-7e0022ef6ba3/go.mod h1:jkELnwuX+w9qN5YIfX0fl88Ehu4XC3keFuOJJk9pcnA= +github.com/jackc/pgconn v0.0.0-20190824142844-760dd75542eb/go.mod h1:lLjNuW/+OfW9/pnVKPazfWOgNfH2aPem8YQ7ilXGvJE= +github.com/jackc/pgconn v0.0.0-20190831204454-2fabfa3c18b7/go.mod h1:ZJKsE/KZfsUgOEh9hBm+xYTstcNHg7UPMVJqRfQxq4s= +github.com/jackc/pgconn v1.4.0/go.mod h1:Y2O3ZDF0q4mMacyWV3AstPJpeHXWGEetiFttmq5lahk= +github.com/jackc/pgconn v1.5.0/go.mod h1:QeD3lBfpTFe8WUnPZWN5KY/mB8FGMIYRdd8P8Jr0fAI= +github.com/jackc/pgconn v1.5.1-0.20200601181101-fa742c524853/go.mod h1:QeD3lBfpTFe8WUnPZWN5KY/mB8FGMIYRdd8P8Jr0fAI= +github.com/jackc/pgconn v1.8.1 h1:ySBX7Q87vOMqKU2bbmKbUvtYhauDFclYbNDYIE1/h6s= +github.com/jackc/pgconn v1.8.1/go.mod h1:JV6m6b6jhjdmzchES0drzCcYcAHS1OPD5xu3OZ/lE2g= +github.com/jackc/pgio v1.0.0 h1:g12B9UwVnzGhueNavwioyEEpAmqMe1E/BN9ES+8ovkE= +github.com/jackc/pgio v1.0.0/go.mod h1:oP+2QK2wFfUWgr+gxjoBH9KGBb31Eio69xUb0w5bYf8= +github.com/jackc/pgmock v0.0.0-20190831213851-13a1b77aafa2 h1:JVX6jT/XfzNqIjye4717ITLaNwV9mWbJx0dLCpcRzdA= +github.com/jackc/pgmock v0.0.0-20190831213851-13a1b77aafa2/go.mod h1:fGZlG77KXmcq05nJLRkk0+p82V8B8Dw8KN2/V9c/OAE= +github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= +github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= +github.com/jackc/pgproto3 v1.1.0 h1:FYYE4yRw+AgI8wXIinMlNjBbp/UitDJwfj5LqqewP1A= +github.com/jackc/pgproto3 v1.1.0/go.mod h1:eR5FA3leWg7p9aeAqi37XOTgTIbkABlvcPB3E5rlc78= +github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190420180111-c116219b62db/go.mod h1:bhq50y+xrl9n5mRYyCBFKkpRVTLYJVWeCc+mEAI3yXA= +github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190609003834-432c2951c711/go.mod h1:uH0AWtUmuShn0bcesswc4aBTWGvw0cAxIJp+6OB//Wg= +github.com/jackc/pgproto3/v2 v2.0.0-rc3/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM= +github.com/jackc/pgproto3/v2 v2.0.0-rc3.0.20190831210041-4c03ce451f29/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM= +github.com/jackc/pgproto3/v2 v2.0.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= +github.com/jackc/pgproto3/v2 v2.0.6 h1:b1105ZGEMFe7aCvrT1Cca3VoVb4ZFMaFJLJcg/3zD+8= +github.com/jackc/pgproto3/v2 v2.0.6/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= +github.com/jackc/pgservicefile v0.0.0-20200307190119-3430c5407db8/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E= +github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b h1:C8S2+VttkHFdOOCXJe+YGfa4vHYwlt4Zx+IVXQ97jYg= +github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E= +github.com/jackc/pgtype v0.0.0-20190421001408-4ed0de4755e0/go.mod h1:hdSHsc1V01CGwFsrv11mJRHWJ6aifDLfdV3aVjFF0zg= +github.com/jackc/pgtype v0.0.0-20190824184912-ab885b375b90/go.mod h1:KcahbBH1nCMSo2DXpzsoWOAfFkdEtEJpPbVLq8eE+mc= +github.com/jackc/pgtype v0.0.0-20190828014616-a8802b16cc59/go.mod h1:MWlu30kVJrUS8lot6TQqcg7mtthZ9T0EoIBFiJcmcyw= +github.com/jackc/pgtype v1.2.0/go.mod h1:5m2OfMh1wTK7x+Fk952IDmI4nw3nPrvtQdM0ZT4WpC0= +github.com/jackc/pgtype v1.3.1-0.20200510190516-8cd94a14c75a/go.mod h1:vaogEUkALtxZMCH411K+tKzNpwzCKU+AnPzBKZ+I+Po= +github.com/jackc/pgtype v1.3.1-0.20200606141011-f6355165a91c/go.mod h1:cvk9Bgu/VzJ9/lxTO5R5sf80p0DiucVtN7ZxvaC4GmQ= +github.com/jackc/pgtype v1.7.0 h1:6f4kVsW01QftE38ufBYxKciO6gyioXSC0ABIRLcZrGs= +github.com/jackc/pgtype v1.7.0/go.mod h1:ZnHF+rMePVqDKaOfJVI4Q8IVvAQMryDlDkZnKOI75BE= +github.com/jackc/pgx/v4 v4.0.0-20190420224344-cc3461e65d96/go.mod h1:mdxmSJJuR08CZQyj1PVQBHy9XOp5p8/SHH6a0psbY9Y= +github.com/jackc/pgx/v4 v4.0.0-20190421002000-1b8f0016e912/go.mod h1:no/Y67Jkk/9WuGR0JG/JseM9irFbnEPbuWV2EELPNuM= +github.com/jackc/pgx/v4 v4.0.0-pre1.0.20190824185557-6972a5742186/go.mod h1:X+GQnOEnf1dqHGpw7JmHqHc1NxDoalibchSk9/RWuDc= +github.com/jackc/pgx/v4 v4.5.0/go.mod h1:EpAKPLdnTorwmPUUsqrPxy5fphV18j9q3wrfRXgo+kA= +github.com/jackc/pgx/v4 v4.6.1-0.20200510190926-94ba730bb1e9/go.mod h1:t3/cdRQl6fOLDxqtlyhe9UWgfIi9R8+8v8GKV5TRA/o= +github.com/jackc/pgx/v4 v4.6.1-0.20200606145419-4e5062306904/go.mod h1:ZDaNWkt9sW1JMiNn0kdYBaLelIhw7Pg4qd+Vk6tw7Hg= +github.com/jackc/pgx/v4 v4.11.0 h1:J86tSWd3Y7nKjwT/43xZBvpi04keQWx8gNC2YkdJhZI= +github.com/jackc/pgx/v4 v4.11.0/go.mod h1:i62xJgdrtVDsnL3U8ekyrQXEwGNTRoG7/8r+CIdYfcc= +github.com/jackc/puddle v0.0.0-20190413234325-e4ced69a3a2b/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= +github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= +github.com/jackc/puddle v1.1.0/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= +github.com/jackc/puddle v1.1.1/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= +github.com/jackc/puddle v1.1.3/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= github.com/jinzhu/now v1.1.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= @@ -320,11 +384,13 @@ github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQL github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= @@ -332,6 +398,11 @@ github.com/labstack/echo/v4 v4.5.0 h1:JXk6H5PAw9I3GwizqUHhYyS4f45iyGebR/c1xNCeOC github.com/labstack/echo/v4 v4.5.0/go.mod h1:czIriw4a0C1dFun+ObrXp7ok03xON0N1awStJ6ArI7Y= github.com/labstack/gommon v0.3.0 h1:JEeO0bvc78PKdyHxloTKiF8BD5iGrH8T6MSeGvSgob0= github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k= +github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/lib/pq v1.3.0 h1:/qkRGz8zljWiDcFvgpwUpwIAPu3r07TDvs3Rws+o/pU= +github.com/lib/pq v1.3.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= @@ -341,11 +412,15 @@ github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN github.com/markbates/pkger v0.17.1 h1:/MKEtWqtc0mZvu9OinB9UzVN9iYCwLWuyUv4Bw+PCno= github.com/markbates/pkger v0.17.1/go.mod h1:0JoVlrol20BSywW79rN3kdFFsE5xYM+rSCQDXbLhiuI= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= +github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ0s8= github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= @@ -434,6 +509,7 @@ github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0 github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA= github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= @@ -476,12 +552,20 @@ github.com/rifflock/lfshook v0.0.0-20180920164130-b9218ef580f5/go.mod h1:GEXHk5H github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= +github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU= +github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= +github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= +github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4= +github.com/shopspring/decimal v0.0.0-20200227202807-02e2044944cc h1:jUIKcSPO9MoMJBbEoyE/RJoE8vz7Mb8AjvifMMwSyvY= +github.com/shopspring/decimal v0.0.0-20200227202807-02e2044944cc/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= @@ -516,6 +600,7 @@ github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3 github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= github.com/stretchr/testify v0.0.0-20151208002404-e3a8ff8ce365/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= @@ -543,6 +628,7 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs= @@ -566,23 +652,31 @@ go.opentelemetry.io/otel/oteltest v0.20.0/go.mod h1:L7bgKf9ZB7qCwT9Up7i9/pn0PWIa go.opentelemetry.io/otel/trace v0.20.0 h1:1DL6EXUdcg95gukhuRRvLDO/4X5THh/5dIV52lqtnbw= go.opentelemetry.io/otel/trace v0.20.0/go.mod h1:6GjCW8zgDjwGHGa6GkyeB8+/5vjT16gUEi0Nf1iBdgw= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= +go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= +go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= +go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 h1:HWj/xjIHfjYU5nVXpTM0s39J9CbLn7Cc5a7IC5rwsMQ= @@ -709,6 +803,7 @@ golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -797,12 +892,14 @@ golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3 golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190425163242-31fd60d6bfdc/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190823170909-c4a336ef6a2f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= @@ -844,6 +941,8 @@ golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -974,6 +1073,7 @@ gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMy gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df h1:n7WqCuqOuCbNr617RXOY0AWRXxgwEyPp2z+p0+hgMuE= gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df/go.mod h1:LRQQ+SO6ZHR7tOkpBDuZnXENFzX8qRjMDMyPD6BRkCw= +gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/ini.v1 v1.62.0 h1:duBzk771uxoUuOlyRLkHsygud9+5lrlGjdFBb4mSKDU= gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= @@ -1001,9 +1101,14 @@ gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gorm.io/driver/mysql v1.1.2 h1:OofcyE2lga734MxwcCW9uB4mWNXMr50uaGRVwQL2B0M= gorm.io/driver/mysql v1.1.2/go.mod h1:4P/X9vSc3WTrhTLZ259cpFd6xKNYiSSdSZngkSBGIMM= +gorm.io/driver/postgres v1.1.0 h1:afBljg7PtJ5lA6YUWluV2+xovIPhS+YiInuL3kUjrbk= +gorm.io/driver/postgres v1.1.0/go.mod h1:hXQIwafeRjJvUm+OMxcFWyswJ/vevcpPLlGocwAwuqw= gorm.io/driver/sqlite v1.1.4 h1:PDzwYE+sI6De2+mxAneV9Xs11+ZyKV6oxD3wDGkaNvM= gorm.io/driver/sqlite v1.1.4/go.mod h1:mJCeTFr7+crvS+TRnWc5Z3UvwxUN1BGBLMrf5LA9DYw= +gorm.io/driver/sqlserver v1.0.8 h1:h/A+30Y2ChvEPmd6d+A/2ZDlNek/MlHb0YhqNoMkRbw= +gorm.io/driver/sqlserver v1.0.8/go.mod h1:WHXpEvhU8VqBD4Rb2TflB1el5hTUiw0F7ynv4923djo= gorm.io/gorm v1.20.7/go.mod h1:0HFTzE/SqkGTzK6TlDPPQbAYCluiVvhzoA1+aVyzenw= +gorm.io/gorm v1.21.9/go.mod h1:F+OptMscr0P2F2qU97WT1WimdH9GaQPoDW7AYd5i2Y0= gorm.io/gorm v1.21.12/go.mod h1:F+OptMscr0P2F2qU97WT1WimdH9GaQPoDW7AYd5i2Y0= gorm.io/gorm v1.21.13 h1:JU5A4yVemRjdMndJ0oZU7VX+Nr2ICE3C60U5bgR6mHE= gorm.io/gorm v1.21.13/go.mod h1:F+OptMscr0P2F2qU97WT1WimdH9GaQPoDW7AYd5i2Y0= diff --git a/lib/db.go b/lib/db.go index 62df7c1e6..19e24c21d 100644 --- a/lib/db.go +++ b/lib/db.go @@ -5,7 +5,9 @@ import ( "github.com/ArtalkJS/ArtalkGo/config" "gorm.io/driver/mysql" + "gorm.io/driver/postgres" "gorm.io/driver/sqlite" + "gorm.io/driver/sqlserver" "gorm.io/gorm" ) @@ -18,19 +20,23 @@ var gormConfig = &gorm.Config{ func OpenDB() (err error) { switch config.Instance.DB.Type { case config.TypeMySql: - err = OpenMySqlDb() - case config.TypeSqlite: - err = OpenSqliteDb() + err = OpenMySql() + case config.TypeSQLite: + err = OpenSQLite() + case config.TypePostgreSQL: + err = OpenPostgreSQL() + case config.TypeSqlServer: + err = OpenSqlServer() } return } -func OpenMySqlDb() (err error) { +func OpenMySql() (err error) { DB, err = gorm.Open(mysql.Open(config.Instance.DB.Dsn), gormConfig) return } -func OpenSqliteDb() (err error) { +func OpenSQLite() (err error) { filename := config.Instance.DB.Dsn if err := EnsureDir(filepath.Dir(filename)); err != nil { return err @@ -39,3 +45,13 @@ func OpenSqliteDb() (err error) { DB, err = gorm.Open(sqlite.Open(filename), gormConfig) return } + +func OpenPostgreSQL() (err error) { + DB, err = gorm.Open(postgres.Open(config.Instance.DB.Dsn), &gorm.Config{}) + return +} + +func OpenSqlServer() (err error) { + DB, err = gorm.Open(sqlserver.Open(config.Instance.DB.Dsn), &gorm.Config{}) + return +} From 2daf3d81807d89472bc1e479f7426f6508462be7 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Fri, 27 Aug 2021 10:35:39 +0800 Subject: [PATCH 012/349] Complete email tpl render. --- artalk-go.example.yml | 17 +++-- cmd/root.go | 2 + config/config.go | 51 +++++++++++---- email-tpl/.gitignore | 3 - email-tpl/default.html | 10 +-- go.mod | 3 + go.sum | 12 ++++ http/a_http.go | 5 +- http/api_main_add.go | 10 ++- http/api_manager.go | 4 ++ http/pkged.go | 12 ---- lib/email/email.go | 42 +++++++++++++ lib/email/queue.go | 28 +++++++++ lib/{email_sender.go => email/sender.go} | 18 +++--- lib/email/tpl.go | 80 ++++++++++++++++++++++++ lib/utils.go | 58 +++++++++++++++++ makefile | 2 +- model/comment.go | 41 ++++++++++++ pkged/main.go | 1 + pkged/pkged.go | 12 ++++ 20 files changed, 356 insertions(+), 55 deletions(-) delete mode 100644 email-tpl/.gitignore delete mode 100644 http/pkged.go create mode 100644 lib/email/email.go create mode 100644 lib/email/queue.go rename lib/{email_sender.go => email/sender.go} (86%) create mode 100644 lib/email/tpl.go create mode 100644 pkged/main.go create mode 100644 pkged/pkged.go diff --git a/artalk-go.example.yml b/artalk-go.example.yml index 3a04f31c8..1125cea74 100644 --- a/artalk-go.example.yml +++ b/artalk-go.example.yml @@ -1,11 +1,11 @@ # 网站名 -site_name: 'XXX 的博客' +site_name: 'ArtalkServer' # HTTP Server 监听地址 http_addr: ':23366' # 加密密钥 -app_key: 'QXJ0YWxrLmpz' +app_key: '' # 调试模式 debug: false @@ -52,19 +52,18 @@ captcha: email: enabled: true # 总开关 admin_addr: 'example@example.com' # 管理员邮箱地址(文章收到评论时通知) - sender_type: 'smtp' # 发送方式 [ali_dm, smtp, sendmail] - mail_title: '您在 [站名] 收到了新的回复' - mail_title_to_admin: '您的文章收到了新的回复' - mail_tpl_name: 'default.html' # 邮件模板文件(/email-tpl 目录下存放) + send_type: 'smtp' # 发送方式 [ali_dm, smtp, sendmail] + send_name: 'ArtalkGo' # 发信人昵称 + mail_subject: '您在 Artalk 收到了新的回复' + mail_subject_to_admin: '您的文章收到了新的回复' + mail_tpl: 'default' # 邮件模板文件 smtp: host: 'smtp.qq.com' port: 587 username: 'example@qq.com' password: '' - from_addr: 'example@qq.com' # 发件人邮箱 - from_name: '站名' # 发件人显示的名称 ali_dm: # https://help.aliyun.com/document_detail/29444.html access_key_id: '' # 阿里云颁发给用户的访问服务所用的密钥 ID access_key_secret: '' # 用于加密的密钥 account_name: 'example@example.com' # 管理控制台中配置的发信地址 - from_alias: '' # 发信人昵称 + from_alias: 'ArtalkGo' # 发信人昵称 diff --git a/cmd/root.go b/cmd/root.go index e7b205ba2..d6d0fce22 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -6,6 +6,7 @@ import ( "github.com/ArtalkJS/ArtalkGo/config" "github.com/ArtalkJS/ArtalkGo/lib" + "github.com/ArtalkJS/ArtalkGo/lib/email" "github.com/ArtalkJS/ArtalkGo/model" "github.com/rifflock/lfshook" "github.com/sirupsen/logrus" @@ -49,6 +50,7 @@ func init() { cobra.OnInitialize(initLog) cobra.OnInitialize(initDB) cobra.OnInitialize(initCache) + cobra.OnInitialize(email.InitQueue) rootCmd.SetVersionTemplate("Artalk-GO {{printf \"version %s\" .Version}}\n") rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "配置文件路径 (defaults are './artalk-go.yml')") diff --git a/config/config.go b/config/config.go index 4e716ae1c..790dac6d8 100644 --- a/config/config.go +++ b/config/config.go @@ -1,9 +1,11 @@ package config import ( + "encoding/json" "fmt" "strings" + "github.com/jeremywohl/flatten" "github.com/sirupsen/logrus" "github.com/spf13/viper" ) @@ -11,6 +13,8 @@ import ( // Instance 配置实例 var Instance *Config +var Flat map[string]interface{} + // Config 配置 // @link https://godoc.org/github.com/mitchellh/mapstructure type Config struct { @@ -59,14 +63,15 @@ type CaptchaConf struct { } type EmailConf struct { - Enabled bool `mapstructure:"enabled"` - AdminAddr string `mapstructure:"admin_addr"` - SenderType EmailSenderType `mapstructure:"sender_type"` - MailTitle string `mapstructure:"mail_title"` - MailTitleToAdmin string `mapstructure:"mail_title_to_admin"` - MailTplName string `mapstructure:"mail_tpl_name"` - SMTP SMTPConf `mapstructure:"smtp"` - AliDM AliDMConf `mapstructure:"ali_dm"` + Enabled bool `mapstructure:"enabled"` // 总开关 + AdminAddr string `mapstructure:"admin_addr"` // 管理员邮箱 + SendType EmailSenderType `mapstructure:"send_type"` // 发送方式 + SendName string `mapstructure:"send_name"` // 发件人名 + MailSubject string `mapstructure:"mail_subject"` // 邮件标题 + MailSubjectToAdmin string `mapstructure:"mail_subject_to_admin"` // 邮件标题 (发送给管理员用) + MailTpl string `mapstructure:"mail_tpl"` // 邮件模板 + SMTP SMTPConf `mapstructure:"smtp"` // SMTP 配置 + AliDM AliDMConf `mapstructure:"ali_dm"` // 阿里云邮件配置 } type SMTPConf struct { @@ -74,8 +79,7 @@ type SMTPConf struct { Port int `mapstructure:"port"` Username string `mapstructure:"username"` Password string `mapstructure:"password"` - FromAddr string `mapstructure:"from_addr"` - FromName string `mapstructure:"from_name"` + From string `mapstructure:"from"` } type AliDMConf struct { @@ -97,8 +101,9 @@ const ( type EmailSenderType string const ( - SMTP EmailSenderType = "smpt" - AliDM EmailSenderType = "ali_dm" + TypeSMTP EmailSenderType = "smpt" + TypeAliDM EmailSenderType = "ali_dm" + TypeSendmail EmailSenderType = "sendmail" ) // Init 初始化配置 @@ -127,4 +132,26 @@ func Init(cfgFile string) { if err != nil { logrus.Errorf("unable to decode into struct, %v", err) } + + Flat = StructToFlatDotMap(&Instance) + + if strings.TrimSpace(Instance.AppKey) == "" { + logrus.Fatal("请检查配置文件,并设置一个 app_key") + } +} + +func StructToMap(s interface{}) map[string]interface{} { + b, _ := json.Marshal(s) + var m map[string]interface{} + _ = json.Unmarshal(b, &m) + return m +} + +func StructToFlatDotMap(s interface{}) map[string]interface{} { + m := StructToMap(s) + mainFlat, err := flatten.Flatten(m, "", flatten.DotStyle) + if err != nil { + return map[string]interface{}{} + } + return mainFlat } diff --git a/email-tpl/.gitignore b/email-tpl/.gitignore deleted file mode 100644 index b9f7c8625..000000000 --- a/email-tpl/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -* -!.gitignore -!default.html \ No newline at end of file diff --git a/email-tpl/default.html b/email-tpl/default.html index 93a644aee..f7ac26324 100644 --- a/email-tpl/default.html +++ b/email-tpl/default.html @@ -1,7 +1,7 @@ -

Hi, {{comment.nick}}:

+

Hi, {{to.nick}}:

-您在 {{conf.site_name}} 收到了回复: -

{{reply.content_html}}
+您在 {{site_name}} 收到了回复: +
@{{from.nick}}:
{{from.content}}

-

传送门 >

-

Powered By Artalk

+

传送门  >>

+

Powered By ArtalkGo

diff --git a/go.mod b/go.mod index 04fe07fa6..deac7a187 100644 --- a/go.mod +++ b/go.mod @@ -7,12 +7,14 @@ require ( github.com/eko/gocache/v2 v2.1.0 github.com/fsnotify/fsnotify v1.5.1 // indirect github.com/golang-jwt/jwt v3.2.2+incompatible + github.com/jeremywohl/flatten v1.0.1 // indirect github.com/kr/text v0.2.0 // indirect github.com/labstack/echo/v4 v4.5.0 github.com/markbates/pkger v0.17.1 github.com/mattn/go-isatty v0.0.13 // indirect github.com/mattn/go-sqlite3 v1.14.8 // indirect github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect + github.com/microcosm-cc/bluemonday v1.0.15 // indirect github.com/mitchellh/mapstructure v1.4.1 github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect github.com/onrik/logrus v0.9.0 @@ -25,6 +27,7 @@ require ( github.com/spf13/viper v1.8.1 github.com/steambap/captcha v1.4.1 github.com/x-cray/logrus-prefixed-formatter v0.5.2 + github.com/yuin/goldmark v1.4.0 // indirect golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 // indirect golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d // indirect golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf // indirect diff --git a/go.sum b/go.sum index a82570441..a39824aa3 100644 --- a/go.sum +++ b/go.sum @@ -69,9 +69,12 @@ github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hC github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= +github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= +github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk= +github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= @@ -269,6 +272,8 @@ github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsC github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= +github.com/gorilla/css v1.0.0 h1:BQqNyPTi50JCFMTw/b67hByjMVXZRwGha6wxVGkeihY= +github.com/gorilla/css v1.0.0/go.mod h1:Dn721qIggHpt4+EFCcTLTU/vk5ySda2ReITrtgBl60c= github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= @@ -359,6 +364,8 @@ github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0f github.com/jackc/puddle v1.1.0/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jackc/puddle v1.1.1/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jackc/puddle v1.1.3/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= +github.com/jeremywohl/flatten v1.0.1 h1:LrsxmB3hfwJuE+ptGOijix1PIfOoKLJ3Uee/mzbgtrs= +github.com/jeremywohl/flatten v1.0.1/go.mod h1:4AmD/VxjWcI5SRB0n6szE2A6s2fsNHDLO0nAlMHgfLQ= github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= github.com/jinzhu/now v1.1.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= @@ -434,6 +441,8 @@ github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0j github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d h1:5PJl274Y63IEHC+7izoQE9x6ikvDFZS2mDVS3drnohI= github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= +github.com/microcosm-cc/bluemonday v1.0.15 h1:J4uN+qPng9rvkBZBoBb8YGR+ijuklIMpSOZZLjYpbeY= +github.com/microcosm-cc/bluemonday v1.0.15/go.mod h1:ZLvAzeakRwrGnzQEvstVzVt3ZpqOF2+sdFr0Om+ce30= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= @@ -628,6 +637,8 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.0 h1:OtISOGfH6sOWa1/qXqqAiOIAO6Z5J3AEAE18WAq6BiQ= +github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= @@ -766,6 +777,7 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= +golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d h1:LO7XpTYMwTqxjLcGWPijK3vRXg1aWdlNOVOHRq45d7c= golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= diff --git a/http/a_http.go b/http/a_http.go index de83cbd88..b52ec55e6 100644 --- a/http/a_http.go +++ b/http/a_http.go @@ -85,9 +85,8 @@ func InitRoute(e *echo.Echo) { ca.GET("/check", ActionCaptchaCheck) // api/manager - manager := api.Group("/manager") + manager := api.Group("/manager", middleware.JWTWithConfig(CommonJwtConfig)) // use jwt manager.GET("/edit", ActionManagerEdit) manager.GET("/del", ActionManagerDel) - - manager.Use(middleware.JWTWithConfig(CommonJwtConfig)) + manager.GET("/send-mail", ActionManagerSendMail) } diff --git a/http/api_main_add.go b/http/api_main_add.go index cbda0714a..f71b49daf 100644 --- a/http/api_main_add.go +++ b/http/api_main_add.go @@ -3,6 +3,7 @@ package http import ( "github.com/ArtalkJS/ArtalkGo/config" "github.com/ArtalkJS/ArtalkGo/lib" + "github.com/ArtalkJS/ArtalkGo/lib/email" "github.com/ArtalkJS/ArtalkGo/model" "github.com/labstack/echo/v4" "github.com/sirupsen/logrus" @@ -70,8 +71,9 @@ func ActionAdd(c echo.Context) error { } // check reply comment + var parentComment model.Comment if p.Rid != 0 { - parentComment := FindComment(p.Rid) + parentComment = FindComment(p.Rid) if parentComment.IsEmpty() { return RespError(c, "找不到父评论") } @@ -107,6 +109,12 @@ func ActionAdd(c echo.Context) error { user.LastUA = ua UpdateUser(&user) + // send email + if comment.Rid != 0 { + email.Send(comment.ToCookedForEmail(), parentComment.ToCookedForEmail()) + } + email.SendToAdmin(comment.ToCookedForEmail()) + return RespData(c, ResponseAdd{ Comment: comment.ToCooked(), }) diff --git a/http/api_manager.go b/http/api_manager.go index da122856e..43f3629a9 100644 --- a/http/api_manager.go +++ b/http/api_manager.go @@ -37,3 +37,7 @@ func ActionManagerEdit(c echo.Context) error { func ActionManagerDel(c echo.Context) error { return nil } + +func ActionManagerSendMail(c echo.Context) error { + return RespSuccess(c) +} diff --git a/http/pkged.go b/http/pkged.go deleted file mode 100644 index 8a8e6dba6..000000000 --- a/http/pkged.go +++ /dev/null @@ -1,12 +0,0 @@ -// Code generated by pkger; DO NOT EDIT. - -// +build !skippkger - -package http - -import ( - "github.com/markbates/pkger" - "github.com/markbates/pkger/pkging/mem" -) - -var _ = pkger.Apply(mem.UnmarshalEmbed([]byte(`1f8b08000000000000ffec594b73db3812fe2b295c230b2425d992aaf6e028b1e28c93d5d88e35f67a6a0a04411216087000508fa4f2dfb7005222453dac642e73e04122bafb03886737f8f57740792814187e0711d571e6b7b148e0a5d488cd3edd1585b3cbc9f5d95818d07b2ac1108c86cfcf5f1591eaf999a45852fefc3c15727697224c9e9fb72bb5c075920aa92748c76078c25b5ae00b4a08188204510e5ae0bdc06008400bdc231911bdfff591787ef64d61abad365912d002b7421ca876a4d79f91c63118fe0fb4c19f2d70a7112360a865460ae19620253818022ef41bca95468c91e08d9fe937688e28433e236f287fe36794056f30c2b1e9ca585c51469469d70caf1d09d37a3e4356fbeafc409c04a6ce7b92da0a7e1652d35f7fa589022d8045924aa2140c19d2a4aa88bed1d4ca5c23ca89848c2a5d28c8d296e42ad5625380286f3117304d63224b39a81a03854a81e06d31f07a3d77b0a380946b22396290040b2403f533301852c2820a98319a6a8a773565fd90a27294304e5005bd0149c4834c53b6c7a4325f33521a92a0570aa65e45c2dd8a509d0d1523774bf27ae75b72cff52a72ed959a55267dd97306db124c6774095a20401af94811a8fe6635110692ceed3a128e454079542942a4b85b954dadf3ee9686722457550d56f3aa189365557c31a7a422a724a98acbc474904829a41959c890e94f9898853aed2c9c84133ca4d149d058ebf424602202c2b691a1e242d370b5296c9b23e167618898803191a46e638847672f0b0d5f16b5c1c748c5140b99c218b32326fb43ea586dfb4b915476071c4749bbf15f83298c383f01a625167cfe1a4c8b19e1c740663b9d30000b3ba16b16b7e7a59463c1552cc99c18470e139129a225aa6d8d17cabfc519a43c64046b2af85e33178b6d3d43bed208cf20c1b180f3ee712b4c681030b240f53db3014622490487eb107004820513f2388489e838c0783a916c631214512c38a212a652a4446a5aef4a82e4cc479a2898cea2faaad48c7b0e481db1f1ca094a8fbfc9fce76eee550c24894f82939009d99982bd38a503b1d33fad398cc4995d0db3bf0ed8a9425ad79c481265fa1b445cd19a9e6a1c13c6623b215a665867f539145cd29959609929bbbbb6cd29618c684aa479b71649cdd7481a864ce01964a18a85986d5b159559aa082f9aaf19d3d0ed401412290e1a76673437e21d8f56e8852fd13ec3cb02314de482201d139920be0f94169166c730a7697d73aacc178a6a0123a149dd87cd115b2186ece133ee9dc85408b61f1322a53549d2e26656412ccfb044ab62eece524942ba24c15928a4d90c7987c4dab78baa6713a5fbb221a42d640497707d83c30939628228d30213a90f60948aa12632a11cb13a84136d83a5fd8b32ad0e01bc8306187bf888314578b6cf4c038eea7ab552a54bc8b8422189090a8a39aa0117940762b1d36133d25ddd524345702609f4694065c67626d462b4445c99f5da6bcd38c522c89b380ae0fb5aa00981b2d833229d456dca21e5b43d77ab9a154a587b9ecfb64cdad4ecd7a2b1528498a14c91ba9689a8f0c955adc23149505d6b6ec766ee4c242d1e104bdc316f8eb5f51ae6012b3b7db332c8a755d11c1ac4a2aa0aa759550c13ad84dd9f1b5524c832259226846fe9a916a82a73a2b54478ebfd42d9ab6655950ac6aa72bd8a2436b833ba3d124579c448c868146ff542ad14468c41b2243877163ba672fb1d32414922aab4bd671fc4a8950ab6bbae89d279f83e7414eca722153054f9938ae25b27af96988ff4fc017d1a95457bba6db9f8ce49a8752ce601938c699a22bb4a56f177263409ec05b2886e9ce8fc7f7dbfdef21eeb65da52161ddbe8d643daa78348614a0b8b394fa914f643d6c89934756c1016caae0b6881341fa979c0903252c8c562db524496e9a600d58a6b64be6c64c6753ef8a20403e26751452e7ba545623f49772cc544efe8d5ca74b3d8f1e59d59694979644d2b8e8b47d97cb133400be4ae08f90b49f3a8912bca93b825e71769a3cd075438a1b204331dbae7db72df8a6657811698131e0809f7c50e1c231c23cf390d950ab6723b4eef15b47d18af712a6efd457b0c9cc93959730f4770f12c088f2376998223e057466c766ec095f9254429141d6a6e5f1c7e15974ab15cbd022c23f021541188f7994d98cd5df93eeb81a87a105a0dae0741b518fb2ace86da3f5be09e28bde1e578c658aeda9072b9eab3084c2787dfc14f30999f11e56bd6f057a8d3b1f82c829fabf5fc1c897622025bfb8148452d4be9b6dd73f0e3c78f1608f3819e40f80e612805d78407064e796829e08068642e00c3ef80e744ed06d5028a7e2360e8b44062fcc8d073bb17dd7ed7ed0dace62feb6786c0733cf7cce99f79bd7bd71b7afda1d36b5ff4bb9ee3f5de3afda1637c06557f0566c6f2c9337e71f81d9845bad45a523f339fba43f7bc05469220f3e97d6fdbfe0e6ec4e23dd22417dd5eafe75d386ecf69818f348a4b4bc71938e717dee0470bdc20a52f31264aed6da3ef0e06dea07fdedbdf44e7bc68626a7ceede16bcdec579cfb9f0baee915e98b1ddd16fc400ec14ae15376201868e5dbb98c886856f58f886856f58f886856f58f886856f58f886856f58f886856f58f886856f58f886856f58f886856f58f886856f58f88685fff7b2f085e333a398453f47c79694fc8f9c515acf4c8aa489c49b36cb2af6853f41f643ca03b26cdb4bc451debf825b33ff5ebfbbe6febb9dfe31d2ff62e8b9ed81dbf5fae7173ba47f88983accfa77bc57587fcf71ba838b8b81e3fd33d6bfd31d7406bfcefabb9d8bbed377fa9d5f66fdbd7ef71ff1fe968eaf93ffe5cef00f50fb255b5f52f0f92e2b18f8627db629f82ab19ea36b873727cbcbb3dd1cf7d38f7bf5506e4e3e988cae3edc3b5fbe4e1fde5d5d8f63c79f2ede8e5e962218bbea7abc8cfd040fae9387ecfaa5fbdb641cb3c7e9ef6f47f432ba1e5df6fde983f378f7ee058daf56d87b7026779f1e1e3e3ceaff8eaeeb18117cbc5ddc4c1f96c1947993bb4f8f370f0fef6ebe7e99fb7fbc8b8331a3fef82bbd1e7f99fbfc96f9fcf7c1f58c5d4da60fb327ef2b9d44c2b4154dc62e0bc61f223fb9d24ff70e0d12c682cebb39e6bf6fd7e541faf4f1564ca6b72c48d8cbd39ddb41d35b078d16119af6d260cc627fe47e7bf4aed4d3bdb3bc79b92cdff1f1360dc64b3699ddce1f3b0ffa69da7326a38183feb8554ff7dddf26a381789a5ecd2691e83f268319b9effe66ea5dbf5f8acf2fbdeba7e952f9ab777ff89d4fea69f4a17fe3452b83bdf13ecd9f3ecede8e5e1673f4f156fbefbbff01aff8dcfcd892265fd7e4eb9a7c5d93af6bf2754dbeaec9d735f9ba265fd7e4eb9a7c5d93af6bf2754dbeaec9d735f9ba265fd7e4eb9a7c5d93af6bf275ff5e02ffc7ff010000ffff010000ffffff1a750f27490000`))) diff --git a/lib/email/email.go b/lib/email/email.go new file mode 100644 index 000000000..368b61c0f --- /dev/null +++ b/lib/email/email.go @@ -0,0 +1,42 @@ +package email + +import ( + "github.com/ArtalkJS/ArtalkGo/config" + "github.com/ArtalkJS/ArtalkGo/model" +) + +func Send(from model.CookedCommentForEmail, to model.CookedCommentForEmail) { + go func() { + subject := RenderConfig(config.Instance.Email.MailSubject) + body := RenderEmailTpl(from, to) + + AddToQueue(Email{ + FromAddr: from.Email, + FromName: config.Instance.Email.SendName, + ToAddr: to.Email, + Subject: subject, + Body: body, + }) + }() +} + +func SendToAdmin(from model.CookedCommentForEmail) { + if config.Instance.Email.AdminAddr == "" { + return + } + + go func() { + subject := RenderConfig(config.Instance.Email.MailSubjectToAdmin) + body := RenderEmailTpl(from, model.CookedCommentForEmail{ + Nick: "Admin", + }) + + AddToQueue(Email{ + FromAddr: from.Email, + FromName: config.Instance.Email.SendName, + ToAddr: config.Instance.Email.AdminAddr, + Subject: subject, + Body: body, + }) + }() +} diff --git a/lib/email/queue.go b/lib/email/queue.go new file mode 100644 index 000000000..a281fdea5 --- /dev/null +++ b/lib/email/queue.go @@ -0,0 +1,28 @@ +package email + +import ( + "github.com/ArtalkJS/ArtalkGo/config" +) + +var emailCh = make(chan Email) // make(chan Email, 5) + +func InitQueue() { + go func() { + for email := range emailCh { + switch config.Instance.Email.SendType { + case config.TypeSMTP: + SendBySMTP(email) + case config.TypeAliDM: + SendByAliDM(email) + case config.TypeSendmail: + SendByUsingSystemCMD(email) + } + } + }() +} + +func AddToQueue(email Email) { + go func() { + emailCh <- email + }() +} diff --git a/lib/email_sender.go b/lib/email/sender.go similarity index 86% rename from lib/email_sender.go rename to lib/email/sender.go index cfd9cc665..05c3feb65 100644 --- a/lib/email_sender.go +++ b/lib/email/sender.go @@ -1,4 +1,4 @@ -package lib +package email import ( "bytes" @@ -19,10 +19,10 @@ type Email struct { Body string } -func SendEmailBySMTP(email Email) bool { +func SendBySMTP(email Email) bool { smtp := config.Instance.Email.SMTP - m := GenerateEmailMessage(email) + m := GetCookedEmail(email) d := gomail.NewDialer(smtp.Host, smtp.Port, smtp.Username, smtp.Password) // 发送邮件 @@ -33,7 +33,7 @@ func SendEmailBySMTP(email Email) bool { return true } -func SendEmailByAliDM(email Email) bool { +func SendByAliDM(email Email) bool { client := ali_dm.NewClient( config.Instance.Email.AliDM.AccessKeyId, config.Instance.Email.AliDM.AccessKeySecret, @@ -62,9 +62,9 @@ func SendEmailByAliDM(email Email) bool { return true } -func SendEmailByUsingSystemCMD(email Email) bool { +func SendByUsingSystemCMD(email Email) bool { LogTag := "[EMAIL] sendmail" - msg := GenerateEmailMineTxt(email) + msg := GetEmailMineTxt(email) // 调用系统 sendmail sendmail := exec.Command("/usr/sbin/sendmail", "-t", "-oi") @@ -99,7 +99,7 @@ func SendEmailByUsingSystemCMD(email Email) bool { return true } -func GenerateEmailMessage(email Email) *gomail.Message { +func GetCookedEmail(email Email) *gomail.Message { m := gomail.NewMessage() // 发送人 @@ -118,8 +118,8 @@ func GenerateEmailMessage(email Email) *gomail.Message { return m } -func GenerateEmailMineTxt(email Email) string { +func GetEmailMineTxt(email Email) string { emailBuffer := bytes.NewBuffer([]byte{}) - GenerateEmailMessage(email).WriteTo(emailBuffer) + GetCookedEmail(email).WriteTo(emailBuffer) return string(emailBuffer.Bytes()[:]) } diff --git a/lib/email/tpl.go b/lib/email/tpl.go new file mode 100644 index 000000000..dd1167a8f --- /dev/null +++ b/lib/email/tpl.go @@ -0,0 +1,80 @@ +package email + +import ( + "bytes" + "fmt" + "html" + "io/ioutil" + "os" + "strings" + + "github.com/ArtalkJS/ArtalkGo/config" + "github.com/ArtalkJS/ArtalkGo/lib" + "github.com/ArtalkJS/ArtalkGo/model" + "github.com/markbates/pkger" +) + +func RenderEmailTpl(from model.CookedCommentForEmail, to model.CookedCommentForEmail) string { + tplName := config.Instance.Email.MailTpl + tpl := "" + if _, err := os.Stat(tplName); os.IsExist(err) { + tpl = GetExternalEmailTpl(tplName) + } else { + tpl = GetInternalEmailTpl(tplName) + } + + getValue := func(k string, v interface{}) string { + val := fmt.Sprintf("%v", v) + if k != "content" { + val = html.EscapeString(val) + } + return val + } + + flatFrom := lib.StructToFlatDotMap(&from) + flatTo := lib.StructToFlatDotMap(&to) + for k, v := range flatFrom { + tpl = strings.ReplaceAll(tpl, fmt.Sprintf("{{from.%s}}", k), getValue(k, v)) + } + for k, v := range flatTo { + tpl = strings.ReplaceAll(tpl, fmt.Sprintf("{{to.%s}}", k), getValue(k, v)) + } + + tpl = RenderConfig(tpl) + tpl = strings.ReplaceAll(tpl, "{{reply_link}}", lib.AddQueryToURL(from.Link, map[string]string{"artalk_comment": fmt.Sprintf("%d", from.ID)})) + + return tpl +} + +func RenderConfig(str string) string { + for k, v := range config.Flat { + str = strings.ReplaceAll(str, fmt.Sprintf("{{config.%s}}", k), fmt.Sprintf("%v", v)) + } + str = strings.ReplaceAll(str, "{{site_name}}", config.Instance.SiteName) + return str +} + +func GetExternalEmailTpl(filename string) string { + buf, err := ioutil.ReadFile(filename) + if err != nil { + return "" + } + + return string(buf) +} + +func GetInternalEmailTpl(tplName string) string { + filename := fmt.Sprintf("/email-tpl/%s.html", tplName) + f, err := pkger.Open(filename) + if err != nil { + return "" + } + + buf := new(bytes.Buffer) + if _, err := buf.ReadFrom(f); err != nil { + return "" + } + contents := buf.String() + + return contents +} diff --git a/lib/utils.go b/lib/utils.go index 90de7a29a..6dd4b3cb7 100644 --- a/lib/utils.go +++ b/lib/utils.go @@ -1,10 +1,19 @@ package lib import ( + "bytes" "crypto/md5" "encoding/hex" + "encoding/json" "errors" + "net/url" "os" + + "github.com/jeremywohl/flatten" + "github.com/yuin/goldmark" + "github.com/yuin/goldmark/extension" + "github.com/yuin/goldmark/parser" + "github.com/yuin/goldmark/renderer/html" ) func EnsureDir(dirName string) error { @@ -31,3 +40,52 @@ func GetMD5Hash(text string) string { hasher.Write([]byte(text)) return hex.EncodeToString(hasher.Sum(nil)) } + +func StructToMap(s interface{}) map[string]interface{} { + b, _ := json.Marshal(s) + var m map[string]interface{} + _ = json.Unmarshal(b, &m) + return m +} + +func StructToFlatDotMap(s interface{}) map[string]interface{} { + m := StructToMap(s) + mainFlat, err := flatten.Flatten(m, "", flatten.DotStyle) + if err != nil { + return map[string]interface{}{} + } + return mainFlat +} + +func Marked(markdownStr string) (string, error) { + // https://github.com/yuin/goldmark#security + md := goldmark.New( + goldmark.WithExtensions(extension.GFM), + goldmark.WithParserOptions( + parser.WithAutoHeadingID(), + ), + goldmark.WithRendererOptions( + html.WithHardWraps(), + html.WithXHTML(), + ), + ) + + var buf bytes.Buffer + if err := md.Convert([]byte(markdownStr), &buf); err != nil { + return "", err + } + + return buf.String(), nil +} + +func AddQueryToURL(urlStr string, queryMap map[string]string) string { + u, _ := url.Parse(urlStr) + + q, _ := url.ParseQuery(u.RawQuery) + for k, v := range queryMap { + q.Add(k, v) + } + + u.RawQuery = q.Encode() + return u.String() +} diff --git a/makefile b/makefile index 9338e024a..d1def5de0 100644 --- a/makefile +++ b/makefile @@ -12,7 +12,7 @@ install: go install github.com/markbates/pkger/cmd/pkger update: - pkger -include /frontend -o http + pkger -include /frontend -include /email-tpl -o pkged build: update go build -ldflags "-X github.com/ArtalkJS/ArtalkGo.Version=${VERSION}" -o bin/artalk-go github.com/ArtalkJS/ArtalkGo diff --git a/model/comment.go b/model/comment.go index d9838676e..7cc282e03 100644 --- a/model/comment.go +++ b/model/comment.go @@ -103,3 +103,44 @@ func (c Comment) ToCooked() CookedComment { Rid: c.Rid, } } + +type CookedCommentForEmail struct { + ID uint `json:"id"` + ContentRaw string `json:"content_raw"` + Content string `json:"content"` + Nick string `json:"nick"` + Email string `json:"email"` + EmailEncrypted string `json:"email_encrypted"` + Link string `json:"link"` + UA string `json:"ua"` + Datetime string `json:"datetime"` + Date string `json:"date"` + Time string `json:"time"` + IsCollapsed bool `json:"is_collapsed"` + IsPending bool `json:"is_pending"` + Rid uint `json:"rid"` + PageKey string `json:"page_key"` +} + +func (c Comment) ToCookedForEmail() CookedCommentForEmail { + user := c.FetchUser() + content, _ := lib.Marked(c.Content) + + return CookedCommentForEmail{ + ID: c.ID, + ContentRaw: c.Content, + Content: content, + Nick: user.Name, + Email: user.Email, + EmailEncrypted: lib.GetMD5Hash(user.Email), + Link: user.Link, + UA: c.UA, + Datetime: c.CreatedAt.Local().Format("2006-01-02 15:04:05"), + Date: c.CreatedAt.Local().Format("2006-01-02"), + Time: c.CreatedAt.Local().Format("15:04:05"), + IsCollapsed: c.Type == CommentCollapsed, + IsPending: c.Type == CommentPending, + Rid: c.Rid, + PageKey: c.PageKey, + } +} diff --git a/pkged/main.go b/pkged/main.go new file mode 100644 index 000000000..dee467340 --- /dev/null +++ b/pkged/main.go @@ -0,0 +1 @@ +package pkged diff --git a/pkged/pkged.go b/pkged/pkged.go new file mode 100644 index 000000000..a633f569e --- /dev/null +++ b/pkged/pkged.go @@ -0,0 +1,12 @@ +// Code generated by pkger; DO NOT EDIT. + +// +build !skippkger + +package pkged + +import ( + "github.com/markbates/pkger" + "github.com/markbates/pkger/pkging/mem" +) + +var _ = pkger.Apply(mem.UnmarshalEmbed([]byte(`1f8b08000000000000ffec5b6b53e33c96fe2b53feda801c272197aafd00e125a45f68689a269065ea2d59966d25b264243917bafabf6fc97612c7b9999da9dd995d7d00fb9cf348d65d3aca797e5984f95c5add5f56405498b8678847e0422848275f7fe42f7daeed5744585d6bd87d7b5b694fac411473a11ea00aadeee11c4eac6f30c256d78a2061d68975c591d5b5ac13eb098a002bab6bf5ba6f6f3f2516f2ed0dc74810f6f616f0b73757bf2cb339c3736c9d588f9cabedc2dc418542abfb9fd699f5f713eb8782145b5d25129c0b8f184aceacae25b5f4370fc7987998a145f76f878a0e2871ad13abcfaf09c552e7afab701670fd95ac0152edc13c50e469f8158e53ac9bf84417d95d282cad130bf12816584ae053a87051117c90b828d38f5951fcc80a87385390302c002552e50a3c4fdfc422567cf50260f6c14c40240eb158cb5ed1e849b81630da143da7d9ac75b614803085058314606f0685273f03033ec1d42b802925b122685bb34eef13b8ae2508235840af4002322f5184ee30c9c45514af0d91d75c0b3a5d41428d82506c0d19c2da86e434cf37e466cd29c8a54f2a5a68f479d3ee6c4a209e90b97562795041174a0ce43b2d89c013649af6238e5cac8b8c19e21e6141e11540c96a4559a73e6f6c6808836251d420392d8a219e17c5b19e4f0539c651519c47baa058082e740df13c9e425d489f425d303fd23d7774da1c8370e693e0182a542a3e86c9a6d24148c43d4c37412f04f23b02621c4099c8d3809f224a3053007a51bad255c1128f7e1aafbbef13f0ada63c88169f2d8dc03125082ac23f954a786e45b8d6501e7c022d13f93934e071c50422461591124bb9d52690521c080e5c122088420ca6f5a300f09ee0a4d4e12ee682b5408cc54482f7043245681922a0e713f501021ee128cb6cf9b28944984d205504b8104db8ef8369a30c90311418cce7219421983a9b660f3322319bf00804fc3492f29d963b772764bd16a3f853700f231241faa934ef09168b7c672ca60ac4424e884e22f4a1e063cacb83074f380878de1b0ed8d1806504f7303a8888b012041dfe8e545c94bee34bc615f117ab974d735a078f4890fd9fb68f98578d53150774f72b1854c74b04596574cc79f5a2c482a7879b6ae87c3faf06ce0f0c9b60f94e4fb3cd16448b6c23de00b889ef43ca4188cbbd16700a59703a9e29309ea99d36bd932332ddfeacb6025f60ac16f1ce6c574620a054e949e000469f89f7e694b6a89bf8bb9bb604d1b9c82a1800d9d630dd89f312b16313d9035624c252c1a8b46ee8f14910173108113d604affa054c7203114b2dca63b50221d3ac7607a2eb00a30251067d36330c527981d02e9235a850aa4b00a454b713b3e4a18e24c86024f31742906114f245602967a660cd1040114266c2230f4b0d8da4532441c20ced87e4b61cf50f359eaf7edc74a15a91dcbf51243f86e7d0ca5f4b7f6d395550fc5fadee24b2ca604e1fde9b7e7dfd232dfda788b9682e7021951e4e3402e402a6feb503b26ec234c00613ec5687ba6e566c6679b7a0a5da9209a008c42be55c2b21544c4f3289ec1f22ab802063c8a38034b07f8000471cac561c8d6b9b00cd00b3f8f3631110c08e20c12a1d795180b45ca4589a098b8506109e249509e1825e38e25bf8c58755d04e3c35fd2ff33efed28467732dfca4d29a6b7abb4edf484dc6327122ab5d86394ef94285cdfb6aa58f0c4cb17e5bf968bf25f78ae30d3875d0962777bf78c82447d00c82429e9894221a6344c9b458904a9a4dc929c0932d1dd2c12998eb14df3f2d83d9902150ae22bedcb8180e752194c2956040b5d47c5a3523163c123ac429c48901de1ff5a6f3eb9e1d309f61cb1aaa4d4af30296fc4db2953cf14040770d94cc0f378cbefde46ad46aa4b949ba00956675c0460360301d7a561383896c50e57f97df6ae0fc5badd21258b849de20896878920be4f399a00eacb90f3c9a6551291c412b37c2c948cb15fab03e863c1f71ab4f3b3cb88b6ce01b99ebb02ee328c67902a2c6618aa108ba87cc0cd40717ed5b1659892b8bc9e488561e4c21820182b14963f9ab85c12a57d0385cbe78229a40b4861ba9aea132816db87e825c68752291cc5f9456301313f45022ef2963d8d05f6c91c7ba73e177ad267c5e5673cc64c618ab5f3b238231c7095f5f31e13804a09e226d9d7f681f4b8908700c519740c035c18043038f8c11536a0dcad98ad121061c078764db00f9e7975c71115be9c035912b9079b7f0914382052a537787ba17aaf83c1ea8cbd0f96d6f5102061249d307c7982e6c5f3235f1f12d3252d5d3ee66079078d227cc004f41283b0507b30b13bf17c678f51ca10282c22b21c2c050889608081cfd956ce9925822a04e9a82fdb1956e91d62fa2f4894dc07d82ad6ca0042071d30c6104d769989c760592f17b2e0a732097d1ca6c7e95dc019611e9f6d1558b7d1b66eaef44a8877a0e76a730eee33026d4896b3ef284a6f1731445b1db289ce6f1bb60007bf2512b6a72212a34460e0128f8884ee4e9d63628111d99d8b129049bd3aeeb4268ca49b9dfec84100db97c38c782adcb290483bf9f96aca038acf0af69583bcbe92d79ae5855755fc8c8823f9172ee124ca0f1415d13cce674f15b85a5ed95440afeae0617f9a8fd24fa48ab09430c01257adcc2ae572747e26c9d11e59a759fe7e5205ac1d4eddc89f802f3dd12a700a83aa25093023557b8e4471d5eee262b9cc1dc7c6020611ac08aedeef5255ee8e2916cbdbfffde8d545db7e88c0a9b79e298ef7ef063c173e95a2708cd89f2461e962942a88bf3c2e54c41fedf1fc3a104b2448acb888dd2af809e33306205b7c06bebc73fc4c9ad5d5639e289e046744bbcddaa339cbae85964ac2c8d9b456d430a8b04f180a014dcf76638826a5448a476e49b580d12a6b11e99358f92a7a531d73a90291ef811b96ccb5dfa997584cf319969982e5feb416018294ba104de49681c244e2b296f220d8ca1344241050f12dbd4421cea76d419b2892fe4e1e4219e60f003d8a45dd598a48a00d21fd713b15fcd4630a55eaeceb0728b840e9d96ff95c5d37152410438ad51a0b3c01672b2120feeabdb0a2c100e7772099691ca73e7326c4e9ddce0a0d5d5214b51b07e90602c54951f42325797a3e5eafb71ccf632c4884d9869e280e8b32c36a79b65f2faa32dd648aaa98535a94cb49f205231f46ebb591b080629f9220dc28855c483d66009e6394b9af5ba6f539759fa9e8dfecc5c885f4368baeb054d90de1be33737a054c38f065f6243cefba495bea0108631241141286c502c493201d8ceb8df9204ae2f4b89315403b18f903b82458bfa698f43d3ff044247591f4034409552486697fa78af7842beca53f38e4977b2cddbd96ee44e135fdb7ecf00d655ec595ae70badfd201281121b925bfb3d1af325a7d4c9f68963b999613a141e9cd249769bf676f49f64b449cb5449c795c14e7f27ab31238c0f378f502e4822938d772b68facdf004aafbd969287dd2428c8eb3a281ea58ef99625ef962dbd5ce8e2e7336dfd8b8c5482b0f42024170ce58f75f6f988b44eaccc4d80ee4c90ecfe2453ac979e0d39fb99466bb3eae50ec2fa0d24caaf9d6fcaed54d4a3d93ab1a698795c805d6e310a210aa1635743c59c2e6a75bb79049d3ef46a5515b78c413a044ec4142fa3c60ee0c289e71f466cc7781d001fa9b11ed11e93fa2ff7130e00cb17054771b1e0f3c511e0fa8a601f2abf29d865960b996f21bbac7b7ce2bdd0a2e3bb1754f27f8fe25237f8ef27d613966a156bc9124a33d52ad03253dd714f17b2fbcbaa167c7a07095b0683ee8c64edf33bee95d46f6f013f8bb8979a9ff3a37cd7aa9dd5ceaddfbf7f9f587e56cac3c1b35d90de729faa986a28617e1a4feb6105f589a6fbcb625964ec1a766249f281adae7d62457a05e83ab546abd16ed49a9d54f357ba42742dc7766aa776fbd4693dd9adae53ef36db67edba5d3fefd4bfd8edaead673b917f79bac259ddf58ad6fd65e9e6bd58decb4aab5b3b3fb17a02a7a7e0a734ef5fd62d9f5d418533b153ab359db653ab9d58372408d786baddb1cf5bb5ceef13eb164a75811096726716cd76a7d5b05b8dd6ae2c5a76c7ceb318eac572670eb54eaddd6a38f5466777166d5d0a5db51fe4036b40da824bc52d9f595d3bedb7100b13d26c429a4d48b309693621cd26a4d984349b906613d26c429a4d48b309693621cd26a4d984349b906613d26c429a4d48b309693621cd26a4d984349b906613d26c429a4d48b309693621cd26a4d984349b906613d26c429a4d48b309693621cd26a4d984349b906613d26c429affed439af3354c176112540e7f2dc437ffce82f896558aa1d05bf72abf759af46315a3a6b5f30b13aaced2c3cec110ea0de4328aba71de58c65137eaeddd01d4cda75aad5bab771b8db37aad63dbf5e65600b50fa9dc1f415d77fe1d22a8ab14e2700075e3bc7138843a0d6f2ec751af3bdedd132abd0e815e873d6783288f7ace9b7f33ecb918c49ca14b932a8b4e5ecfb9ff17d37073c2ace6a4f57073f1e5477f220737aaf5ea74943b7c4ebc5e3381c36fc27fb1cf1f7a9dd94360ffa97157df4514bc8f29fb3308705d8d5da719ddb26fb1d77ff6dde85a8d5e6a9dc13dfca992e140deff380f93a1cb92e1648cbfb4239d47ff31f6c8e5877743e5e8c926afd1f5183adec2ad3f27a32b3e1e455fa3d76844eeeb97e1a8ff18bb113abf7bba9ce1dec5e2eee6b271ef8ca62efbae9043cf474f7c7e9feabe4e51f44811a9c9d17064df8fbfcd70eff2c375e6f1a87731bebbba68dc39a3e8dea98528f26297d46cb77e717ef7f43cc357923c30d542d1f3ccbd9924af4e27f1facf8977dde15ebf26fd17bb7deb3cc6deb8f1ad379e4dd1957ece670fe37938e8878bd1f0b53358a5a7bedba709acd73a83421d477dfa81faf3103fc5b11bcd6337faa95ea3f9f4d5912dd4bf9e8cfa34197d701bdd04c1dd58974911b7fe75327a1928145d4fe0cbf3c7fdf85aebc7ae339fa2312fd429affb982f747ae474241c7e0f061f17b3fbab6fd168acecd14b68df0e1fe9abd359bcbe3cc6aed33877a34e327a52eaf5e52b83c386f2fa9dd9fd78304337416b402e6dad1fbd7cef0c6887b8fdeb042e065f9ab78be0fcb577793ec27cd01b31ef4ab66f9d3fbe14c7c7cf7ea73e7af94a47bdcb1efe717989d863e8f665fbb6aec70eff0feb1f5cfd7dc199c2cc3bbcdeaf509f66cc349f6a4ed76977ede659abdd706c677bc1ffc71833b566b3e9b4ec5ad3debdd63aff230bbed36c9d37ed96d3d8b3e23b86326328338632632833863263283386326328338632632833d5c824863263283386326328330594a1cc6c9a0d65c650660c65c650660c65a60032941943993194194399319419439931941943993194194399319419439931941943993194194399319419439931941943993194194399f93f1babbf0a5cfe673266969902c23c3caf409729e09601d44ebb1259c6e93aadae533bebd41a4efbbcf5cf26cb38b6dde8b45a1ddbf95f0d9eaed55b6dbb6db7ebffede069a76de832ffe253b0385b0a5c99def51f4ff6b79fc3e7cbeb413fb4dde1ec4b6f3c4fb92283fe3c7423d41944cfc960dcf8f3a11fd2d7e1f72f3d72110c7a176d77f86cbffeb81cc3fef50239cff6c38fafcfcf7fbcaafbdea08ce1decde3ec76f83cf786d479f8f1f5f5f6f9f9f2f6e7b7a9fb72197a7d4adcfe4f32e87f9bbaec91baec7b6730a1d70fc3e7c9c8f9491e02aef30a1efa35eaf5ff08525ece934dbc8852af7e3945ecfb665ae6c5a39b47fe307ca45e44c7a31fb53a1c3edab0370be0b0197b7d1ababddac7ab732d474ff6fc767cb1fec6cd63ecf5e7f461f2387dad3fabd1b0693ff43a367c7994a3a7c69f0fbd0e1f0daf270f016fbf469d097e6afca9d30daee6fc6edc1c8c8673e92e2e5fdcfa5739eafdd1be758285c6de3a5fa7a39bc997de783685378fcabd6a1ce58e64f3091b3e82e123183e82e123183e82e123183e82e123183e82e123183e82e123183e82e1236428c347d8341b3e82e123183e82e123183e420164f808868f60f808868f60f808868f60f808868f60f808868f60f808868f60f808868f60f808868f60f808868f60f808868f60f808868ff0af1f0cfdfbbf000000ffff010000ffff8a2b8505d3bb0000`))) From 9fab4c1aaa903ca7d50e3ccb3c41a68c40771e43 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Fri, 27 Aug 2021 11:20:26 +0800 Subject: [PATCH 013/349] Modify ActionGet method from GET to POST. --- artalk-go.example.yml | 6 ++--- config/config.go | 1 - http/a_http.go | 2 +- http/api_main_add.go | 1 + http/utils.go | 63 ++++++++++++++++++++++++------------------- lib/email/email.go | 7 +++++ lib/email/sender.go | 2 +- 7 files changed, 49 insertions(+), 33 deletions(-) diff --git a/artalk-go.example.yml b/artalk-go.example.yml index 1125cea74..b8da2d009 100644 --- a/artalk-go.example.yml +++ b/artalk-go.example.yml @@ -51,11 +51,11 @@ captcha: # 邮件通知 email: enabled: true # 总开关 - admin_addr: 'example@example.com' # 管理员邮箱地址(文章收到评论时通知) send_type: 'smtp' # 发送方式 [ali_dm, smtp, sendmail] send_name: 'ArtalkGo' # 发信人昵称 mail_subject: '您在 Artalk 收到了新的回复' - mail_subject_to_admin: '您的文章收到了新的回复' + admin_addr: 'example@example.com' # 管理员邮箱地址(文章收到评论时通知) + mail_subject_to_admin: '您的文章有新的回复' mail_tpl: 'default' # 邮件模板文件 smtp: host: 'smtp.qq.com' @@ -66,4 +66,4 @@ email: access_key_id: '' # 阿里云颁发给用户的访问服务所用的密钥 ID access_key_secret: '' # 用于加密的密钥 account_name: 'example@example.com' # 管理控制台中配置的发信地址 - from_alias: 'ArtalkGo' # 发信人昵称 + diff --git a/config/config.go b/config/config.go index 790dac6d8..32d1379c9 100644 --- a/config/config.go +++ b/config/config.go @@ -86,7 +86,6 @@ type AliDMConf struct { AccessKeyId string `mapstructure:"access_key_id"` AccessKeySecret string `mapstructure:"access_key_secret"` AccountName string `mapstructure:"account_name"` - FromAlias string `mapstructure:"from_alias"` } type DBType string diff --git a/http/a_http.go b/http/a_http.go index b52ec55e6..dd8873539 100644 --- a/http/a_http.go +++ b/http/a_http.go @@ -74,7 +74,7 @@ func InitRoute(e *echo.Echo) { // api api := e.Group("/api") - api.GET("/add", ActionAdd) + api.POST("/add", ActionAdd) api.GET("/get", ActionGet) api.GET("/user", ActionUser) api.GET("/login", ActionLogin) diff --git a/http/api_main_add.go b/http/api_main_add.go index f71b49daf..3234a6ed5 100644 --- a/http/api_main_add.go +++ b/http/api_main_add.go @@ -16,6 +16,7 @@ type ParamsAdd struct { Content string `mapstructure:"content" param:"required"` Rid uint `mapstructure:"rid"` PageKey string `mapstructure:"page_key" param:"required"` + Token string `mapstructure:"token"` } type ResponseAdd struct { diff --git a/http/utils.go b/http/utils.go index e18bc1c28..e1b5f1cac 100644 --- a/http/utils.go +++ b/http/utils.go @@ -41,45 +41,54 @@ func LoginGetUserToken(user model.User) string { } func ParamsDecode(c echo.Context, paramsStruct interface{}, destParams interface{}) (isContinue bool, resp error) { + params := make(map[string]interface{}) + refVal := reflect.ValueOf(paramsStruct) for i := 0; i < refVal.Type().NumField(); i++ { field := refVal.Type().Field(i) //fieldName := field.Name - paramTagM := field.Tag.Get("mapstructure") + paramName := field.Tag.Get("mapstructure") paramTagP := field.Tag.Get("param") - //fmt.Println(field, paramTagM, paramTagP) - - if paramTagM != "" && paramTagP == "required" { - if strings.TrimSpace(c.QueryParam(paramTagM)) == "" { - return false, RespError(c, "Param `"+paramTagM+"` is required.") + paramMethod := strings.ToUpper(field.Tag.Get("method")) + + // get param value + paramVal := func() string { + if paramMethod == "" { + if c.Request().Method == "GET" { + return c.QueryParam(paramName) + } else if c.Request().Method == "POST" { + return c.FormValue(paramName) + } } - } - } - - // get the first - params := make(map[string]interface{}) - for k, p := range c.QueryParams() { - params[k] = p[0] - } - // convet type - for i := 0; i < refVal.Type().NumField(); i++ { - field := refVal.Type().Field(i) - paramName := field.Tag.Get("mapstructure") + if paramMethod == "GET" { + return c.QueryParam(paramName) + } else if paramMethod == "POST" { + return c.FormValue(paramName) + } + return "" + }() - if field.Type.Kind() == reflect.Int { - u64, _ := strconv.ParseInt(c.QueryParam(paramName), 10, 32) - params[paramName] = int(u64) + // check required param + if paramName != "" && paramTagP == "required" { + if strings.TrimSpace(paramVal) == "" { + return false, RespError(c, "Param `"+paramName+"` is required.") + } } - if field.Type.Kind() == reflect.Uint { - u64, _ := strconv.ParseUint(c.QueryParam(paramName), 10, 32) + // convert type + if field.Type.Kind() == reflect.String { + params[paramName] = paramVal + } else if field.Type.Kind() == reflect.Int { + u64, _ := strconv.ParseInt(paramVal, 10, 32) + params[paramName] = int(u64) + } else if field.Type.Kind() == reflect.Uint { + u64, _ := strconv.ParseUint(paramVal, 10, 32) params[paramName] = uint(u64) } - - if field.Type.Kind() == reflect.Array { - params[paramName] = c.QueryParams()[paramName] - } + // } else if field.Type.Kind() == reflect.Array { + // params[paramName] = c.QueryParams()[paramName] + // } } err := mapstructure.Decode(params, destParams) diff --git a/lib/email/email.go b/lib/email/email.go index 368b61c0f..ab8c5d4d9 100644 --- a/lib/email/email.go +++ b/lib/email/email.go @@ -6,6 +6,10 @@ import ( ) func Send(from model.CookedCommentForEmail, to model.CookedCommentForEmail) { + if !config.Instance.Email.Enabled { + return + } + go func() { subject := RenderConfig(config.Instance.Email.MailSubject) body := RenderEmailTpl(from, to) @@ -21,6 +25,9 @@ func Send(from model.CookedCommentForEmail, to model.CookedCommentForEmail) { } func SendToAdmin(from model.CookedCommentForEmail) { + if !config.Instance.Email.Enabled { + return + } if config.Instance.Email.AdminAddr == "" { return } diff --git a/lib/email/sender.go b/lib/email/sender.go index 05c3feb65..32c5ba106 100644 --- a/lib/email/sender.go +++ b/lib/email/sender.go @@ -38,7 +38,7 @@ func SendByAliDM(email Email) bool { config.Instance.Email.AliDM.AccessKeyId, config.Instance.Email.AliDM.AccessKeySecret, config.Instance.Email.AliDM.AccountName, - config.Instance.Email.AliDM.FromAlias, + config.Instance.Email.SendName, ali_dm.RegionCNHangZhou, ) req := &ali_dm.SingleRequest{ From 10ba5c7623d66a3f966684f605c6288b324bb682 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Wed, 8 Sep 2021 20:03:10 +0800 Subject: [PATCH 014/349] Update login method. Signed-off-by: qwqcode --- README.md | 5 +++++ http/a_http.go | 1 + http/api_manager.go | 19 +++++++++++++++---- http/permission.go | 3 +++ 4 files changed, 24 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index fc62d1d94..3e320d0b9 100644 --- a/README.md +++ b/README.md @@ -10,10 +10,15 @@ - 轻松部署 - 可视化图形界面 - 命令行管理 +- 数据导出导入 +- 数据备份同步 - 多站点支持 - 评论获取分页 +- 评论点赞投票 +- 通知中心管理 - 邮件异步队列发送 - 邮件多模板自定义 +- 博客邮件订阅 - 用户鉴权机制 - 全局验证码操作限制 - 规范化 API diff --git a/http/a_http.go b/http/a_http.go index dd8873539..4b40a5589 100644 --- a/http/a_http.go +++ b/http/a_http.go @@ -78,6 +78,7 @@ func InitRoute(e *echo.Echo) { api.GET("/get", ActionGet) api.GET("/user", ActionUser) api.GET("/login", ActionLogin) + api.POST("/login", ActionLogin) // api/captcha ca := api.Group("/captcha") diff --git a/http/api_manager.go b/http/api_manager.go index 43f3629a9..acb4fd425 100644 --- a/http/api_manager.go +++ b/http/api_manager.go @@ -7,9 +7,20 @@ import ( ) func ActionLogin(c echo.Context) error { - username := c.QueryParam("user") - password := c.QueryParam("password") - if username == "" || password == "" { + name := c.FormValue("name") + email := c.FormValue("email") + password := c.FormValue("password") + if name == "" { + name = c.QueryParam("name") + } + if email == "" { + email = c.QueryParam("email") + } + if password == "" { + password = c.QueryParam("password") + } + + if name == "" || email == "" || password == "" { return RespError(c, "Incomplete parameters.") } @@ -17,7 +28,7 @@ func ActionLogin(c echo.Context) error { RecordAction(c) var user model.User - lib.DB.Where("name = ? OR email = ?", username, username).First(&user) + lib.DB.Where("name = ? AND email = ?", name, email).First(&user) // name = ? OR email = ? if user.IsEmpty() || user.Password != password { return RespError(c, "验证失败") } diff --git a/http/permission.go b/http/permission.go index 73cad15ab..cd3ed7ded 100644 --- a/http/permission.go +++ b/http/permission.go @@ -126,6 +126,9 @@ func addActionCount(c echo.Context) { func CheckIsAdminReq(c echo.Context) bool { isAdmin := false token := c.Param("token") + if token == "" { + token = c.FormValue("token") + } if token == "" { token = c.Request().Header.Get("X-Auth-Token") } From c506bf566ab10d00ae47821a97ada51ba3139e6f Mon Sep 17 00:00:00 2001 From: qwqcode Date: Sun, 12 Sep 2021 15:29:10 +0800 Subject: [PATCH 015/349] Modify the admin user check logic. --- cmd/root.go | 2 +- http/api_main_add.go | 25 +++++++++---------------- http/utils.go | 20 +++++++++++++++++--- model/page.go | 1 + 4 files changed, 28 insertions(+), 20 deletions(-) diff --git a/cmd/root.go b/cmd/root.go index d6d0fce22..22d4f7877 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -114,7 +114,7 @@ func initDB() { } // Migrate the schema - lib.DB.AutoMigrate(&model.Comment{}, &model.Page{}, &model.User{}) + lib.DB.AutoMigrate(&model.Page{}, &model.User{}, &model.Comment{}) // 注意表的创建顺序 } func initCache() { diff --git a/http/api_main_add.go b/http/api_main_add.go index 3234a6ed5..55a07f293 100644 --- a/http/api_main_add.go +++ b/http/api_main_add.go @@ -42,19 +42,6 @@ func ActionAdd(c echo.Context) error { // record action for limiting action RecordAction(c) - // find user - user := FindUser(p.Name, p.Email) - if user.IsEmpty() { - user = NewUser(p.Name, p.Email, p.Link) // save a new user - } - - // admin user check - if !user.IsEmpty() && user.IsAdmin() { - if !CheckIsAdminReq(c) { - return RespError(c, "需要验证管理员身份", Map{"need_password": true}) - } - } - // find page page := FindPage(p.PageKey) if page.IsEmpty() { @@ -62,10 +49,16 @@ func ActionAdd(c echo.Context) error { } // check if the user is allowed to comment - if isAllowed, resp := CheckIfAllowed(c, user, page); !isAllowed { + if isAllowed, resp := CheckIfAllowed(c, p.Name, p.Email, page); !isAllowed { return resp } + // find user + user := FindUser(p.Name, p.Email) + if user.IsEmpty() { + user = NewUser(p.Name, p.Email, p.Link) // save a new user + } + if user.ID == 0 || page.Key == "" { logrus.Error("Cannot get real user and page.") return RespError(c, "评论失败") @@ -112,9 +105,9 @@ func ActionAdd(c echo.Context) error { // send email if comment.Rid != 0 { - email.Send(comment.ToCookedForEmail(), parentComment.ToCookedForEmail()) + email.Send(comment.ToCookedForEmail(), parentComment.ToCookedForEmail()) // 发送邮件给回复者 } - email.SendToAdmin(comment.ToCookedForEmail()) + email.SendToAdmin(comment.ToCookedForEmail()) // 发送邮件给管理员 return RespData(c, ResponseAdd{ Comment: comment.ToCooked(), diff --git a/http/utils.go b/http/utils.go index e1b5f1cac..1bcc8e1a1 100644 --- a/http/utils.go +++ b/http/utils.go @@ -99,7 +99,14 @@ func ParamsDecode(c echo.Context, paramsStruct interface{}, destParams interface return true, nil } -func CheckIfAllowed(c echo.Context, user model.User, page model.Page) (bool, error) { +func CheckIfAllowed(c echo.Context, name string, email string, page model.Page) (bool, error) { + // 如果用户是管理员,或者当前页只能管理员评论 + if IsAdminUser(name, email) || page.Type == model.PageOnlyAdmin { + if !CheckIsAdminReq(c) { + return false, RespError(c, "需要验证管理员身份", Map{"need_password": true}) + } + } + return true, nil } @@ -109,12 +116,19 @@ func FindComment(id uint) model.Comment { return comment } +// 查找用户(返回:精确查找,模糊查找) func FindUser(name string, email string) model.User { - var user model.User - lib.DB.Where(&model.User{Name: name, Email: email}).First(&user) + var user model.User // 注:user 查找是 AND + lib.DB.Where("name = ? AND email = ?", name, email).First(&user) return user } +func IsAdminUser(name string, email string) bool { + var user model.User // 注:user 查找是 OR + lib.DB.Where("(name = ? OR email = ?) AND type = ?", name, email, model.UserAdmin).First(&user) + return !user.IsEmpty() +} + func NewUser(name string, email string, link string) model.User { user := model.User{ Name: name, diff --git a/model/page.go b/model/page.go index fe874ef40..e67ab35d7 100644 --- a/model/page.go +++ b/model/page.go @@ -6,6 +6,7 @@ type PageType string const ( PageCommentClosed PageType = "comment_closed" + PageOnlyAdmin PageType = "only_admin" ) type Page struct { From 737beefad26696b8191800adb9f1b54928d100ff Mon Sep 17 00:00:00 2001 From: qwqcode Date: Tue, 14 Sep 2021 14:06:56 +0800 Subject: [PATCH 016/349] Modify http routes. --- cmd/root.go | 2 +- http/a_http.go | 4 ++-- http/resp.go | 9 +++++++-- http/utils.go | 2 +- 4 files changed, 11 insertions(+), 6 deletions(-) diff --git a/cmd/root.go b/cmd/root.go index 22d4f7877..4ecbd63b5 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -114,7 +114,7 @@ func initDB() { } // Migrate the schema - lib.DB.AutoMigrate(&model.Page{}, &model.User{}, &model.Comment{}) // 注意表的创建顺序 + lib.DB.AutoMigrate(&model.Page{}, &model.User{}, &model.Comment{}) // 注意表的创建顺序,因为有关联字段 } func initCache() { diff --git a/http/a_http.go b/http/a_http.go index 4b40a5589..2176c29c2 100644 --- a/http/a_http.go +++ b/http/a_http.go @@ -75,14 +75,14 @@ func InitRoute(e *echo.Echo) { api := e.Group("/api") api.POST("/add", ActionAdd) - api.GET("/get", ActionGet) + api.POST("/get", ActionGet) api.GET("/user", ActionUser) api.GET("/login", ActionLogin) api.POST("/login", ActionLogin) // api/captcha ca := api.Group("/captcha") - ca.GET("/get", ActionCaptchaGet) + ca.GET("/refresh", ActionCaptchaGet) ca.GET("/check", ActionCaptchaCheck) // api/manager diff --git a/http/resp.go b/http/resp.go index f1ace9cb0..af5038aaa 100644 --- a/http/resp.go +++ b/http/resp.go @@ -41,7 +41,7 @@ func RespSuccess(c echo.Context) error { } // RespError is just response error -func RespError(c echo.Context, msg string, data ...interface{}) error { +func RespError(c echo.Context, msg string, data ...Map) error { // log req := c.Request() path := req.URL.Path @@ -50,10 +50,15 @@ func RespError(c echo.Context, msg string, data ...interface{}) error { } LogWithHttpInfo(c).Errorf("[响应] %s %s ==> %s", req.Method, path, strconv.Quote(msg)) + respData := Map{} + if len(data) > 0 { + respData = data[0] + } + return c.JSON(http.StatusOK, &JSONResult{ Success: false, Msg: msg, - Data: data, + Data: respData, }) } diff --git a/http/utils.go b/http/utils.go index 1bcc8e1a1..72c67ed92 100644 --- a/http/utils.go +++ b/http/utils.go @@ -103,7 +103,7 @@ func CheckIfAllowed(c echo.Context, name string, email string, page model.Page) // 如果用户是管理员,或者当前页只能管理员评论 if IsAdminUser(name, email) || page.Type == model.PageOnlyAdmin { if !CheckIsAdminReq(c) { - return false, RespError(c, "需要验证管理员身份", Map{"need_password": true}) + return false, RespError(c, "需要验证管理员身份", Map{"need_login": true}) } } From 0f0e9846c2e6029074c235462e29cc9976cdb375 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Wed, 15 Sep 2021 16:26:41 +0800 Subject: [PATCH 017/349] Add user-get api. --- http/a_http.go | 2 +- http/api_main.go | 6 ---- http/api_main_add.go | 3 ++ http/api_user.go | 49 ++++++++++++++++++++++++++++++ http/permission.go | 71 +++++++++++++++++++++++++++++++------------- http/utils.go | 4 +-- lib/utils.go | 10 +++++++ model/comment.go | 8 +++++ model/user.go | 24 +++++++++++++++ 9 files changed, 148 insertions(+), 29 deletions(-) create mode 100644 http/api_user.go diff --git a/http/a_http.go b/http/a_http.go index 2176c29c2..d421d4952 100644 --- a/http/a_http.go +++ b/http/a_http.go @@ -76,7 +76,7 @@ func InitRoute(e *echo.Echo) { api.POST("/add", ActionAdd) api.POST("/get", ActionGet) - api.GET("/user", ActionUser) + api.POST("/user-get", ActionUserGet) api.GET("/login", ActionLogin) api.POST("/login", ActionLogin) diff --git a/http/api_main.go b/http/api_main.go index 7c4eeb5d9..d02cfda64 100644 --- a/http/api_main.go +++ b/http/api_main.go @@ -1,7 +1 @@ package http - -import "github.com/labstack/echo/v4" - -func ActionUser(c echo.Context) error { - return nil -} diff --git a/http/api_main_add.go b/http/api_main_add.go index 55a07f293..8cab338bd 100644 --- a/http/api_main_add.go +++ b/http/api_main_add.go @@ -74,6 +74,9 @@ func ActionAdd(c echo.Context) error { if parentComment.PageKey != p.PageKey { return RespError(c, "与父评论的 pageKey 不一致") } + if !parentComment.IsAllowReply() { + return RespError(c, "不允许回复该评论") + } } comment := model.Comment{ diff --git a/http/api_user.go b/http/api_user.go new file mode 100644 index 000000000..4edca9940 --- /dev/null +++ b/http/api_user.go @@ -0,0 +1,49 @@ +package http + +import ( + "github.com/ArtalkJS/ArtalkGo/lib" + "github.com/ArtalkJS/ArtalkGo/model" + "github.com/labstack/echo/v4" +) + +type ParamsUserGet struct { + Name string `mapstructure:"name"` + Email string `mapstructure:"email"` +} + +type ResponseUserGet struct { + IsAdmin bool `json:"is_admin"` +} + +func ActionUserGet(c echo.Context) error { + var p ParamsUserGet + if isOK, resp := ParamsDecode(c, ParamsUserGet{}, &p); !isOK { + return resp + } + + if p.Name == "" && p.Email == "" { + return RespError(c, "Please input name or email.") + } + + var user model.User // 注:user 查找是 AND + lib.DB.Where("name = ? AND email = ?", p.Name, p.Email).First(&user) + + isLogin := false + tUser := GetUserByReqToken(c) + if !tUser.IsEmpty() && tUser.Name == p.Name && tUser.Email == p.Email { + isLogin = true + user = tUser + } + + if user.IsEmpty() { + return RespData(c, Map{ + "user": nil, + "is_login": false, + }) + } + + return RespData(c, Map{ + "user": user.ToCooked(), + "is_login": isLogin, + }) +} diff --git a/http/permission.go b/http/permission.go index cd3ed7ded..70c55acd2 100644 --- a/http/permission.go +++ b/http/permission.go @@ -2,6 +2,7 @@ package http import ( "context" + "encoding/json" "fmt" "strconv" "time" @@ -123,47 +124,70 @@ func addActionCount(c echo.Context) { setActionCount(c, getActionCount(c)+1) } -func CheckIsAdminReq(c echo.Context) bool { - isAdmin := false - token := c.Param("token") +func GetJwtInstanceByReq(c echo.Context) *jwt.Token { + token := c.QueryParam("token") if token == "" { token = c.FormValue("token") } if token == "" { token = c.Request().Header.Get("X-Auth-Token") } - if token != "" { - jwt, err := jwt.Parse(token, func(t *jwt.Token) (interface{}, error) { - if t.Method.Alg() != CommonJwtConfig.SigningMethod { - return nil, fmt.Errorf("unexpected jwt signing method=%v", t.Header["alg"]) - } - - return []byte(config.Instance.AppKey), nil // 密钥 - }) + if token == "" { + return nil + } - if err == nil { - isAdmin = CheckIsAdminByJwt(jwt) + jwt, err := jwt.Parse(token, func(t *jwt.Token) (interface{}, error) { + if t.Method.Alg() != CommonJwtConfig.SigningMethod { + return nil, fmt.Errorf("unexpected jwt signing method=%v", t.Header["alg"]) } + + return []byte(config.Instance.AppKey), nil // 密钥 + }) + if err != nil { + return nil } - return isAdmin + + return jwt } func CheckIsAdminByJwt(jwt *jwt.Token) bool { - claims := jwt.Claims.(*jwtCustomClaims) + user := GetUserByJwt(jwt) + if user.IsEmpty() { + return false + } + + return user.Type == model.UserAdmin +} + +func CheckIsAdminReq(c echo.Context) bool { + jwt := GetJwtInstanceByReq(c) + if jwt == nil { + return false + } + + return CheckIsAdminByJwt(jwt) +} + +func GetUserByJwt(jwt *jwt.Token) model.User { + if jwt == nil { + return model.User{} + } + + claims := jwtCustomClaims{} + tmp, _ := json.Marshal(jwt.Claims) + _ = json.Unmarshal(tmp, &claims) + name := claims.UserName email := claims.UserEmail if claims.UserType != model.UserAdmin { - return false + return model.User{} } // check user from database user := FindUser(name, email) - if user.IsEmpty() { - return false - } - return user.Type == model.UserAdmin + return user } // 中间件会创建一个 user context,通过中间件获取到的 jwt 判断 @@ -172,3 +196,10 @@ func CheckIsAdminByJwtMiddleware(c echo.Context) bool { return CheckIsAdminByJwt(jwt) } + +func GetUserByReqToken(c echo.Context) model.User { + jwt := GetJwtInstanceByReq(c) + user := GetUserByJwt(jwt) + + return user +} diff --git a/http/utils.go b/http/utils.go index 72c67ed92..ed016d17c 100644 --- a/http/utils.go +++ b/http/utils.go @@ -124,8 +124,8 @@ func FindUser(name string, email string) model.User { } func IsAdminUser(name string, email string) bool { - var user model.User // 注:user 查找是 OR - lib.DB.Where("(name = ? OR email = ?) AND type = ?", name, email, model.UserAdmin).First(&user) + var user model.User // 还是用 AND 吧,OR 太混乱了 + lib.DB.Where("(name = ? AND email = ?) AND type = ?", name, email, model.UserAdmin).First(&user) return !user.IsEmpty() } diff --git a/lib/utils.go b/lib/utils.go index 6dd4b3cb7..fc693cbca 100644 --- a/lib/utils.go +++ b/lib/utils.go @@ -89,3 +89,13 @@ func AddQueryToURL(urlStr string, queryMap map[string]string) string { u.RawQuery = q.Encode() return u.String() } + +// ContainsStr returns true if an str is present in a iteratee. +func ContainsStr(s []string, v string) bool { + for _, vv := range s { + if vv == v { + return true + } + } + return false +} diff --git a/model/comment.go b/model/comment.go index 7cc282e03..2ae18e13e 100644 --- a/model/comment.go +++ b/model/comment.go @@ -32,6 +32,10 @@ func (c Comment) IsEmpty() bool { return c.ID == 0 } +func (c Comment) IsAllowReply() bool { + return c.Type != CommentCollapsed && c.Type != CommentPending && c.Type != CommentDeleted +} + func (c *Comment) FetchUser() User { if !c.User.IsEmpty() { return c.User @@ -83,6 +87,7 @@ type CookedComment struct { Date string `json:"date"` IsCollapsed bool `json:"is_collapsed"` IsPending bool `json:"is_pending"` + IsAllowReply bool `json:"is_allow_reply"` Rid uint `json:"rid"` } @@ -100,6 +105,7 @@ func (c Comment) ToCooked() CookedComment { Date: c.CreatedAt.Local().String(), IsCollapsed: c.Type == CommentCollapsed, IsPending: c.Type == CommentPending, + IsAllowReply: c.IsAllowReply(), Rid: c.Rid, } } @@ -118,6 +124,7 @@ type CookedCommentForEmail struct { Time string `json:"time"` IsCollapsed bool `json:"is_collapsed"` IsPending bool `json:"is_pending"` + IsAllowReply bool `json:"is_allow_reply"` Rid uint `json:"rid"` PageKey string `json:"page_key"` } @@ -140,6 +147,7 @@ func (c Comment) ToCookedForEmail() CookedCommentForEmail { Time: c.CreatedAt.Local().Format("15:04:05"), IsCollapsed: c.Type == CommentCollapsed, IsPending: c.Type == CommentPending, + IsAllowReply: c.IsAllowReply(), Rid: c.Rid, PageKey: c.PageKey, } diff --git a/model/user.go b/model/user.go index 729290c97..0c0728669 100644 --- a/model/user.go +++ b/model/user.go @@ -31,3 +31,27 @@ func (u User) IsEmpty() bool { func (u User) IsAdmin() bool { return u.Type == UserAdmin } + +type CookedUser struct { + ID uint `json:"id"` + Name string `json:"name"` + Email string `json:"email"` + Link string `json:"link"` + BadgeName string `json:"badge_name"` + BadgeColor string `json:"badge_color"` + IsAdmin bool `json:"is_admin"` + Type UserType `json:"type"` +} + +func (u User) ToCooked() CookedUser { + return CookedUser{ + ID: u.ID, + Name: u.Name, + Email: u.Email, + Link: u.Link, + BadgeName: u.BadgeName, + BadgeColor: u.BadgeColor, + IsAdmin: u.IsAdmin(), + Type: u.Type, + } +} From 5374e2f621e6ee0757dbdea4b16bc70219b9d6df Mon Sep 17 00:00:00 2001 From: qwqcode Date: Wed, 15 Sep 2021 21:12:52 +0800 Subject: [PATCH 018/349] Add manager edit-page & edit-comment actions. --- http/a_http.go | 3 +- http/api_login.go | 39 ++++++++++++++ http/api_main_add.go | 13 ++--- http/api_man_edit_comment.go | 101 +++++++++++++++++++++++++++++++++++ http/api_man_edit_page.go | 37 +++++++++++++ http/api_manager.go | 57 +++++++------------- http/permission.go | 7 --- http/utils.go | 47 +++++++++++++--- model/page.go | 22 ++++---- 9 files changed, 252 insertions(+), 74 deletions(-) create mode 100644 http/api_login.go create mode 100644 http/api_man_edit_comment.go create mode 100644 http/api_man_edit_page.go diff --git a/http/a_http.go b/http/a_http.go index d421d4952..40c4c00df 100644 --- a/http/a_http.go +++ b/http/a_http.go @@ -87,7 +87,8 @@ func InitRoute(e *echo.Echo) { // api/manager manager := api.Group("/manager", middleware.JWTWithConfig(CommonJwtConfig)) // use jwt - manager.GET("/edit", ActionManagerEdit) + manager.GET("/edit-page", ActionManagerEditPage) + manager.GET("/edit-comment", ActionManagerEditComment) manager.GET("/del", ActionManagerDel) manager.GET("/send-mail", ActionManagerSendMail) } diff --git a/http/api_login.go b/http/api_login.go new file mode 100644 index 000000000..e1dba195d --- /dev/null +++ b/http/api_login.go @@ -0,0 +1,39 @@ +package http + +import ( + "github.com/ArtalkJS/ArtalkGo/lib" + "github.com/ArtalkJS/ArtalkGo/model" + "github.com/labstack/echo/v4" +) + +func ActionLogin(c echo.Context) error { + name := c.FormValue("name") + email := c.FormValue("email") + password := c.FormValue("password") + if name == "" { + name = c.QueryParam("name") + } + if email == "" { + email = c.QueryParam("email") + } + if password == "" { + password = c.QueryParam("password") + } + + if name == "" || email == "" || password == "" { + return RespError(c, "Incomplete parameters.") + } + + // record action for limiting action + RecordAction(c) + + var user model.User + lib.DB.Where("name = ? AND email = ?", name, email).First(&user) // name = ? OR email = ? + if user.IsEmpty() || user.Password != password { + return RespError(c, "验证失败") + } + + return RespData(c, Map{ + "token": LoginGetUserToken(user), + }) +} diff --git a/http/api_main_add.go b/http/api_main_add.go index 8cab338bd..b1f42e34d 100644 --- a/http/api_main_add.go +++ b/http/api_main_add.go @@ -43,10 +43,7 @@ func ActionAdd(c echo.Context) error { RecordAction(c) // find page - page := FindPage(p.PageKey) - if page.IsEmpty() { - page = NewPage(p.PageKey) - } + page := FindCreatePage(p.PageKey) // check if the user is allowed to comment if isAllowed, resp := CheckIfAllowed(c, p.Name, p.Email, page); !isAllowed { @@ -54,13 +51,9 @@ func ActionAdd(c echo.Context) error { } // find user - user := FindUser(p.Name, p.Email) - if user.IsEmpty() { - user = NewUser(p.Name, p.Email, p.Link) // save a new user - } - + user := FindCreateUser(p.Name, p.Email) if user.ID == 0 || page.Key == "" { - logrus.Error("Cannot get real user and page.") + logrus.Error("Cannot get user or page.") return RespError(c, "评论失败") } diff --git a/http/api_man_edit_comment.go b/http/api_man_edit_comment.go new file mode 100644 index 000000000..1088f5eba --- /dev/null +++ b/http/api_man_edit_comment.go @@ -0,0 +1,101 @@ +package http + +import ( + "encoding/json" + "strconv" + + "github.com/ArtalkJS/ArtalkGo/model" + "github.com/labstack/echo/v4" +) + +type ParamsEditComment struct { + ID string `mapstructure:"id" param:"required"` + Content string `mapstructure:"content"` + PageKey string `mapstructure:"page_key"` + Name string `mapstructure:"name"` + Email string `mapstructure:"email"` + Link string `mapstructure:"link"` + Rid string `mapstructure:"rid"` + UA string `mapstructure:"ua"` + IP string `mapstructure:"ip"` + Type string `mapstructure:"type"` +} + +func ActionManagerEditComment(c echo.Context) error { + if isOK, resp := AdminOnly(c); !isOK { + return resp + } + + var p ParamsEditComment + if isOK, resp := ParamsDecode(c, ParamsEditComment{}, &p); !isOK { + return resp + } + + id, err := strconv.Atoi(p.ID) + if err != nil { + return RespError(c, "invalid id.") + } + + comment := FindComment(uint(id)) + if comment.IsEmpty() { + return RespError(c, "comment not found.") + } + + // content + if p.Content != "" { + comment.Content = p.Content + } + + // rid + if p.Rid != "" { + if rid, err := strconv.Atoi(p.Rid); err == nil { + comment.Rid = uint(rid) + } + } + + // user + if p.Name != "" && p.Email != "" { + user := FindCreateUser(p.Name, p.Email) + if user.ID != comment.UserID { + comment.UserID = user.ID + } + } + if p.Link != "" { + comment.User.Link = p.Link + UpdateUser(&comment.User) + } + + // pageKey + if p.PageKey != "" { + if p.PageKey != comment.PageKey { + FindCreatePage(p.PageKey) + comment.PageKey = p.PageKey + } + } + + // ua + if p.UA != "" { + comment.UA = p.UA + } + + // ip + if p.IP != "" { + comment.IP = p.IP + } + + // type + if p.Type != "" { + tmp, _ := json.Marshal(Map{"Type": p.Type}) + var tmpComment model.Comment + json.Unmarshal(tmp, &tmpComment) + if comment.Type != tmpComment.Type { + comment.Type = tmpComment.Type + } + } + + if err := UpdateComment(&comment); err != nil { + return RespError(c, "comment save error.") + } + + return RespSuccess(c) +} diff --git a/http/api_man_edit_page.go b/http/api_man_edit_page.go new file mode 100644 index 000000000..9b981abb0 --- /dev/null +++ b/http/api_man_edit_page.go @@ -0,0 +1,37 @@ +package http + +import "github.com/labstack/echo/v4" + +type ParamsEditPage struct { + Key string `mapstructure:"key" param:"required"` + OnlyAdmin string `mapstructure:"only_admin"` +} + +func ActionManagerEditPage(c echo.Context) error { + if isOK, resp := AdminOnly(c); !isOK { + return resp + } + + var p ParamsEditPage + if isOK, resp := ParamsDecode(c, ParamsEditPage{}, &p); !isOK { + return resp + } + + page := FindPage(p.Key) + if page.IsEmpty() { + return RespError(c, "page not found.") + } + + switch p.OnlyAdmin { + case "1": + page.AdminOnly = true + case "0": + page.AdminOnly = false + } + + if err := UpdatePage(&page); err != nil { + return RespError(c, "page save error.") + } + + return RespSuccess(c) +} diff --git a/http/api_manager.go b/http/api_manager.go index acb4fd425..67ebceadf 100644 --- a/http/api_manager.go +++ b/http/api_manager.go @@ -1,54 +1,37 @@ package http import ( - "github.com/ArtalkJS/ArtalkGo/lib" - "github.com/ArtalkJS/ArtalkGo/model" + "github.com/golang-jwt/jwt" "github.com/labstack/echo/v4" ) -func ActionLogin(c echo.Context) error { - name := c.FormValue("name") - email := c.FormValue("email") - password := c.FormValue("password") - if name == "" { - name = c.QueryParam("name") - } - if email == "" { - email = c.QueryParam("email") - } - if password == "" { - password = c.QueryParam("password") - } - - if name == "" || email == "" || password == "" { - return RespError(c, "Incomplete parameters.") +func ActionManagerDel(c echo.Context) error { + if isOK, resp := AdminOnly(c); !isOK { + return resp } - // record action for limiting action - RecordAction(c) + return nil +} - var user model.User - lib.DB.Where("name = ? AND email = ?", name, email).First(&user) // name = ? OR email = ? - if user.IsEmpty() || user.Password != password { - return RespError(c, "验证失败") +func ActionManagerSendMail(c echo.Context) error { + if isOK, resp := AdminOnly(c); !isOK { + return resp } - return RespData(c, Map{ - "token": LoginGetUserToken(user), - }) + return RespSuccess(c) } -func ActionManagerEdit(c echo.Context) error { - // user := c.Get("user").(*jwt.Token) - // claims := user.Claims.(*jwtCustomClaims) - // name := claims.Name - return nil -} +func AdminOnly(c echo.Context) (isOK bool, resp error) { + if !CheckIsAdminInJwtMiddleware(c) { + return false, RespError(c, "需要验证管理员身份", Map{"need_login": true}) + } -func ActionManagerDel(c echo.Context) error { - return nil + return true, nil } -func ActionManagerSendMail(c echo.Context) error { - return RespSuccess(c) +// 中间件会创建一个 user context,通过中间件获取到的 jwt 判断 +func CheckIsAdminInJwtMiddleware(c echo.Context) bool { + jwt := c.Get("user").(*jwt.Token) + + return CheckIsAdminByJwt(jwt) } diff --git a/http/permission.go b/http/permission.go index 70c55acd2..005498306 100644 --- a/http/permission.go +++ b/http/permission.go @@ -190,13 +190,6 @@ func GetUserByJwt(jwt *jwt.Token) model.User { return user } -// 中间件会创建一个 user context,通过中间件获取到的 jwt 判断 -func CheckIsAdminByJwtMiddleware(c echo.Context) bool { - jwt := c.Get("user").(*jwt.Token) - - return CheckIsAdminByJwt(jwt) -} - func GetUserByReqToken(c echo.Context) model.User { jwt := GetJwtInstanceByReq(c) user := GetUserByJwt(jwt) diff --git a/http/utils.go b/http/utils.go index ed016d17c..2755da0e7 100644 --- a/http/utils.go +++ b/http/utils.go @@ -15,6 +15,7 @@ import ( "github.com/labstack/echo/v4" "github.com/mitchellh/mapstructure" "github.com/sirupsen/logrus" + "gorm.io/gorm/clause" ) func LoginGetUserToken(user model.User) string { @@ -101,7 +102,7 @@ func ParamsDecode(c echo.Context, paramsStruct interface{}, destParams interface func CheckIfAllowed(c echo.Context, name string, email string, page model.Page) (bool, error) { // 如果用户是管理员,或者当前页只能管理员评论 - if IsAdminUser(name, email) || page.Type == model.PageOnlyAdmin { + if IsAdminUser(name, email) || page.AdminOnly { if !CheckIsAdminReq(c) { return false, RespError(c, "需要验证管理员身份", Map{"need_login": true}) } @@ -112,11 +113,11 @@ func CheckIfAllowed(c echo.Context, name string, email string, page model.Page) func FindComment(id uint) model.Comment { var comment model.Comment - lib.DB.First(&comment, id) + lib.DB.Preload(clause.Associations).First(&comment, id) return comment } -// 查找用户(返回:精确查找,模糊查找) +// 查找用户(返回:精确查找 AND) func FindUser(name string, email string) model.User { var user model.User // 注:user 查找是 AND lib.DB.Where("name = ? AND email = ?", name, email).First(&user) @@ -129,11 +130,34 @@ func IsAdminUser(name string, email string) bool { return !user.IsEmpty() } -func NewUser(name string, email string, link string) model.User { +func UpdateComment(comment *model.Comment) error { + err := lib.DB.Save(comment).Error + if err != nil { + logrus.Error("Update Comment error: ", err) + } + return err +} + +func FindCreatePage(pageKey string) model.Page { + page := FindPage(pageKey) + if page.IsEmpty() { + page = NewPage(pageKey) + } + return page +} + +func FindCreateUser(name string, email string) model.User { + user := FindUser(name, email) + if user.IsEmpty() { + user = NewUser(name, email) // save a new user + } + return user +} + +func NewUser(name string, email string) model.User { user := model.User{ Name: name, Email: email, - Link: link, } err := lib.DB.Create(&user).Error @@ -144,11 +168,13 @@ func NewUser(name string, email string, link string) model.User { return user } -func UpdateUser(user *model.User) { +func UpdateUser(user *model.User) error { err := lib.DB.Save(user).Error if err != nil { logrus.Error("Update User error: ", err) } + + return err } func FindPage(key string) model.Page { @@ -157,6 +183,12 @@ func FindPage(key string) model.Page { return page } +func FindPageByID(id uint) model.Page { + var page model.Page + lib.DB.Where("id = ?", id).First(&page) + return page +} + func NewPage(key string) model.Page { page := model.Page{ Key: key, @@ -170,11 +202,12 @@ func NewPage(key string) model.Page { return page } -func UpdatePage(page *model.Page) { +func UpdatePage(page *model.Page) error { err := lib.DB.Save(page).Error if err != nil { logrus.Error("Update Page error: ", err) } + return err } func ValidateEmail(email string) bool { diff --git a/model/page.go b/model/page.go index e67ab35d7..5de851b49 100644 --- a/model/page.go +++ b/model/page.go @@ -4,15 +4,13 @@ import "gorm.io/gorm" type PageType string -const ( - PageCommentClosed PageType = "comment_closed" - PageOnlyAdmin PageType = "only_admin" -) +const () type Page struct { gorm.Model - Key string `gorm:"uniqueIndex"` - Type PageType + Key string `gorm:"uniqueIndex"` + AdminOnly bool + Type PageType } func (p Page) IsEmpty() bool { @@ -20,15 +18,15 @@ func (p Page) IsEmpty() bool { } type CookedPage struct { - ID uint `json:"id"` - IsCommentClosed bool `json:"is_comment_closed"` - PageKey string `json:"page_key"` + ID uint `json:"id"` + AdminOnly bool `json:"admin_only"` + PageKey string `json:"page_key"` } func (p Page) ToCooked() CookedPage { return CookedPage{ - ID: p.ID, - IsCommentClosed: p.Type == PageCommentClosed, - PageKey: p.Key, + ID: p.ID, + AdminOnly: p.AdminOnly, + PageKey: p.Key, } } From 8a21a4cad542cf90ad6657eee99feac0359839a9 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Wed, 15 Sep 2021 21:55:08 +0800 Subject: [PATCH 019/349] Fix some bugs. --- http/a_http.go | 6 +++--- http/api_man_edit_comment.go | 10 ++++++---- http/api_man_edit_page.go | 4 +++- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/http/a_http.go b/http/a_http.go index 40c4c00df..4d58ecf43 100644 --- a/http/a_http.go +++ b/http/a_http.go @@ -51,7 +51,7 @@ func Run() { Claims: &jwtCustomClaims{}, ContextKey: "user", SigningMethod: "HS256", - TokenLookup: "header:X-Auth-Token,query:token", + TokenLookup: "header:X-Auth-Token,query:token,form:token", SigningKey: []byte(config.Instance.AppKey), } @@ -87,8 +87,8 @@ func InitRoute(e *echo.Echo) { // api/manager manager := api.Group("/manager", middleware.JWTWithConfig(CommonJwtConfig)) // use jwt - manager.GET("/edit-page", ActionManagerEditPage) - manager.GET("/edit-comment", ActionManagerEditComment) + manager.POST("/edit-page", ActionManagerEditPage) + manager.POST("/edit-comment", ActionManagerEditComment) manager.GET("/del", ActionManagerDel) manager.GET("/send-mail", ActionManagerSendMail) } diff --git a/http/api_man_edit_comment.go b/http/api_man_edit_comment.go index 1088f5eba..4e053693a 100644 --- a/http/api_man_edit_comment.go +++ b/http/api_man_edit_comment.go @@ -12,7 +12,7 @@ type ParamsEditComment struct { ID string `mapstructure:"id" param:"required"` Content string `mapstructure:"content"` PageKey string `mapstructure:"page_key"` - Name string `mapstructure:"name"` + Nick string `mapstructure:"nick"` Email string `mapstructure:"email"` Link string `mapstructure:"link"` Rid string `mapstructure:"rid"` @@ -54,8 +54,8 @@ func ActionManagerEditComment(c echo.Context) error { } // user - if p.Name != "" && p.Email != "" { - user := FindCreateUser(p.Name, p.Email) + if p.Nick != "" && p.Email != "" { + user := FindCreateUser(p.Nick, p.Email) if user.ID != comment.UserID { comment.UserID = user.ID } @@ -97,5 +97,7 @@ func ActionManagerEditComment(c echo.Context) error { return RespError(c, "comment save error.") } - return RespSuccess(c) + return RespData(c, Map{ + "comment": comment.ToCooked(), + }) } diff --git a/http/api_man_edit_page.go b/http/api_man_edit_page.go index 9b981abb0..847534c4c 100644 --- a/http/api_man_edit_page.go +++ b/http/api_man_edit_page.go @@ -33,5 +33,7 @@ func ActionManagerEditPage(c echo.Context) error { return RespError(c, "page save error.") } - return RespSuccess(c) + return RespData(c, Map{ + "page": page.ToCooked(), + }) } From ca08478389d6abe7c1def5c8a87d450a90c5dd07 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Wed, 15 Sep 2021 21:59:26 +0800 Subject: [PATCH 020/349] Add manager comment del action. --- http/a_http.go | 1 + http/api_man_del_comment.go | 38 +++++++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+) create mode 100644 http/api_man_del_comment.go diff --git a/http/a_http.go b/http/a_http.go index 4d58ecf43..c729a3d97 100644 --- a/http/a_http.go +++ b/http/a_http.go @@ -89,6 +89,7 @@ func InitRoute(e *echo.Echo) { manager := api.Group("/manager", middleware.JWTWithConfig(CommonJwtConfig)) // use jwt manager.POST("/edit-page", ActionManagerEditPage) manager.POST("/edit-comment", ActionManagerEditComment) + manager.POST("/del-comment", ActionManagerDel) manager.GET("/del", ActionManagerDel) manager.GET("/send-mail", ActionManagerSendMail) } diff --git a/http/api_man_del_comment.go b/http/api_man_del_comment.go new file mode 100644 index 000000000..bca28f95a --- /dev/null +++ b/http/api_man_del_comment.go @@ -0,0 +1,38 @@ +package http + +import ( + "strconv" + + "github.com/ArtalkJS/ArtalkGo/lib" + "github.com/labstack/echo/v4" +) + +type ParamsDelComment struct { + ID string `mapstructure:"id" param:"required"` +} + +func ActionManagerDelComment(c echo.Context) error { + if isOK, resp := AdminOnly(c); !isOK { + return resp + } + + var p ParamsEditComment + if isOK, resp := ParamsDecode(c, ParamsEditComment{}, &p); !isOK { + return resp + } + + id, err := strconv.Atoi(p.ID) + if err != nil { + return RespError(c, "invalid id.") + } + + comment := FindComment(uint(id)) + if comment.IsEmpty() { + return RespError(c, "comment not found.") + } + + if err := lib.DB.Delete("id = ?", comment.ID).Error; err != nil { + return RespError(c, "comment delete error.") + } + return RespSuccess(c) +} From 90fd84722b4a6e3b621f71613d5246eec9061bd7 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Thu, 16 Sep 2021 14:45:18 +0800 Subject: [PATCH 021/349] Remove comment field & collapsed comment. --- http/a_http.go | 3 +-- http/api_main_add.go | 16 ++++++------ http/api_main_get.go | 4 +-- http/api_man_del_comment.go | 18 +++++++++++++- http/api_man_edit_comment.go | 47 +++++++++++++++++++++--------------- http/api_manager.go | 8 ------ model/comment.go | 26 +++++++++----------- 7 files changed, 68 insertions(+), 54 deletions(-) diff --git a/http/a_http.go b/http/a_http.go index c729a3d97..28fa72de4 100644 --- a/http/a_http.go +++ b/http/a_http.go @@ -89,7 +89,6 @@ func InitRoute(e *echo.Echo) { manager := api.Group("/manager", middleware.JWTWithConfig(CommonJwtConfig)) // use jwt manager.POST("/edit-page", ActionManagerEditPage) manager.POST("/edit-comment", ActionManagerEditComment) - manager.POST("/del-comment", ActionManagerDel) - manager.GET("/del", ActionManagerDel) + manager.POST("/del-comment", ActionManagerDelComment) manager.GET("/send-mail", ActionManagerSendMail) } diff --git a/http/api_main_add.go b/http/api_main_add.go index b1f42e34d..22e35d4c4 100644 --- a/http/api_main_add.go +++ b/http/api_main_add.go @@ -73,17 +73,19 @@ func ActionAdd(c echo.Context) error { } comment := model.Comment{ - Content: p.Content, - Rid: p.Rid, - UserID: user.ID, - PageKey: page.Key, - IP: ip, - UA: ua, + Content: p.Content, + Rid: p.Rid, + UserID: user.ID, + PageKey: page.Key, + IP: ip, + UA: ua, + IsPending: false, + IsCollapsed: false, } // default comment type if config.Instance.Moderator.PendingDefault { - comment.Type = model.CommentPending + comment.IsPending = true } // save to database diff --git a/http/api_main_get.go b/http/api_main_get.go index b3fcc123c..d3322be33 100644 --- a/http/api_main_get.go +++ b/http/api_main_get.go @@ -41,7 +41,7 @@ func ActionGet(c echo.Context) error { // find children comments for _, c := range comments { // TODO: Read more children, pagination for children comment - children := c.FetchChildren(func(db *gorm.DB) *gorm.DB { return db.Where("type != ?", model.CommentPending) }) + children := c.FetchChildren(func(db *gorm.DB) *gorm.DB { return db.Where("is_pending = 0") }) for _, c := range children { cookedComments = append(cookedComments, c.ToCooked()) } @@ -81,7 +81,7 @@ func Paginate(offset int, limit int) func(db *gorm.DB) *gorm.DB { func FilterAllowedComment(c echo.Context, p ParamsGet) func(db *gorm.DB) *gorm.DB { return func(db *gorm.DB) *gorm.DB { - return db.Where("rid = 0 AND type != ?", model.CommentPending) + return db.Where("rid = 0 AND is_pending = 0") } } diff --git a/http/api_man_del_comment.go b/http/api_man_del_comment.go index bca28f95a..3d9c62260 100644 --- a/http/api_man_del_comment.go +++ b/http/api_man_del_comment.go @@ -4,7 +4,9 @@ import ( "strconv" "github.com/ArtalkJS/ArtalkGo/lib" + "github.com/ArtalkJS/ArtalkGo/model" "github.com/labstack/echo/v4" + "gorm.io/gorm" ) type ParamsDelComment struct { @@ -31,8 +33,22 @@ func ActionManagerDelComment(c echo.Context) error { return RespError(c, "comment not found.") } - if err := lib.DB.Delete("id = ?", comment.ID).Error; err != nil { + if err := lib.DB.Model(&model.Comment{}).Delete("id = ?", comment.ID).Error; err != nil { return RespError(c, "comment delete error.") } + + // 删除子评论 + hasErr := false + children := comment.FetchChildren(func(db *gorm.DB) *gorm.DB { return db }) + for _, c := range children { + err := lib.DB.Delete(&c) + if err != nil { + hasErr = true + } + } + if hasErr { + return RespError(c, "children comment delete error.") + } + return RespSuccess(c) } diff --git a/http/api_man_edit_comment.go b/http/api_man_edit_comment.go index 4e053693a..e040288bd 100644 --- a/http/api_man_edit_comment.go +++ b/http/api_man_edit_comment.go @@ -1,24 +1,23 @@ package http import ( - "encoding/json" "strconv" - "github.com/ArtalkJS/ArtalkGo/model" "github.com/labstack/echo/v4" ) type ParamsEditComment struct { - ID string `mapstructure:"id" param:"required"` - Content string `mapstructure:"content"` - PageKey string `mapstructure:"page_key"` - Nick string `mapstructure:"nick"` - Email string `mapstructure:"email"` - Link string `mapstructure:"link"` - Rid string `mapstructure:"rid"` - UA string `mapstructure:"ua"` - IP string `mapstructure:"ip"` - Type string `mapstructure:"type"` + ID string `mapstructure:"id" param:"required"` + Content string `mapstructure:"content"` + PageKey string `mapstructure:"page_key"` + Nick string `mapstructure:"nick"` + Email string `mapstructure:"email"` + Link string `mapstructure:"link"` + Rid string `mapstructure:"rid"` + UA string `mapstructure:"ua"` + IP string `mapstructure:"ip"` + IsCollapsed string `mapstructure:"is_collapsed"` + IsPending string `mapstructure:"is_pending"` } func ActionManagerEditComment(c echo.Context) error { @@ -83,13 +82,23 @@ func ActionManagerEditComment(c echo.Context) error { comment.IP = p.IP } - // type - if p.Type != "" { - tmp, _ := json.Marshal(Map{"Type": p.Type}) - var tmpComment model.Comment - json.Unmarshal(tmp, &tmpComment) - if comment.Type != tmpComment.Type { - comment.Type = tmpComment.Type + // is_collapsed + if p.IsCollapsed != "" { + switch p.IsCollapsed { + case "1": + comment.IsCollapsed = true + case "0": + comment.IsCollapsed = false + } + } + + // is_pending + if p.IsPending != "" { + switch p.IsPending { + case "1": + comment.IsPending = true + case "0": + comment.IsPending = false } } diff --git a/http/api_manager.go b/http/api_manager.go index 67ebceadf..b3d27808f 100644 --- a/http/api_manager.go +++ b/http/api_manager.go @@ -5,14 +5,6 @@ import ( "github.com/labstack/echo/v4" ) -func ActionManagerDel(c echo.Context) error { - if isOK, resp := AdminOnly(c); !isOK { - return resp - } - - return nil -} - func ActionManagerSendMail(c echo.Context) error { if isOK, resp := AdminOnly(c); !isOK { return resp diff --git a/model/comment.go b/model/comment.go index 2ae18e13e..96d5c9891 100644 --- a/model/comment.go +++ b/model/comment.go @@ -7,12 +7,6 @@ import ( type CommentType string -const ( - CommentCollapsed CommentType = "collapsed" - CommentPending CommentType = "pengding" - CommentDeleted CommentType = "deleted" -) - type Comment struct { gorm.Model Content string @@ -22,10 +16,12 @@ type Comment struct { User User `gorm:"foreignKey:UserID;references:ID"` Page Page `gorm:"foreignKey:PageKey;references:Key"` - Rid uint `gorm:"index"` - UA string - IP string - Type CommentType + Rid uint `gorm:"index"` + UA string + IP string + + IsCollapsed bool + IsPending bool } func (c Comment) IsEmpty() bool { @@ -33,7 +29,7 @@ func (c Comment) IsEmpty() bool { } func (c Comment) IsAllowReply() bool { - return c.Type != CommentCollapsed && c.Type != CommentPending && c.Type != CommentDeleted + return !c.IsCollapsed && !c.IsPending } func (c *Comment) FetchUser() User { @@ -103,8 +99,8 @@ func (c Comment) ToCooked() CookedComment { Link: user.Link, UA: c.UA, Date: c.CreatedAt.Local().String(), - IsCollapsed: c.Type == CommentCollapsed, - IsPending: c.Type == CommentPending, + IsCollapsed: c.IsCollapsed, + IsPending: c.IsPending, IsAllowReply: c.IsAllowReply(), Rid: c.Rid, } @@ -145,8 +141,8 @@ func (c Comment) ToCookedForEmail() CookedCommentForEmail { Datetime: c.CreatedAt.Local().Format("2006-01-02 15:04:05"), Date: c.CreatedAt.Local().Format("2006-01-02"), Time: c.CreatedAt.Local().Format("15:04:05"), - IsCollapsed: c.Type == CommentCollapsed, - IsPending: c.Type == CommentPending, + IsCollapsed: c.IsCollapsed, + IsPending: c.IsPending, IsAllowReply: c.IsAllowReply(), Rid: c.Rid, PageKey: c.PageKey, From 4514764abad8042a69065d2b0e6c4f06ef077038 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Thu, 16 Sep 2021 22:26:10 +0800 Subject: [PATCH 022/349] Notification Center. --- http/api_main_get.go | 90 ++++++++++++++++++++++++++++++++++++-------- 1 file changed, 74 insertions(+), 16 deletions(-) diff --git a/http/api_main_get.go b/http/api_main_get.go index d3322be33..087141386 100644 --- a/http/api_main_get.go +++ b/http/api_main_get.go @@ -11,6 +11,10 @@ type ParamsGet struct { PageKey string `mapstructure:"page_key" param:"required"` Limit int `mapstructure:"limit"` Offset int `mapstructure:"offset"` + + Name string `mapstructure:"name"` + Email string `mapstructure:"email"` + Type string `mapstructure:"type"` // TODO: FlatMode string `mapstructure:"flat_mode"` } @@ -31,29 +35,27 @@ func ActionGet(c echo.Context) error { page := FindPage(p.PageKey) // find comments + + // comment parents var comments []model.Comment - lib.DB.Where("page_key = ?", p.PageKey).Scopes(Paginate(p.Offset, p.Limit), FilterAllowedComment(c, p)).Order("created_at DESC").Find(&comments) + GetParentCommentQuery(c, p).Find(&comments) cookedComments := []model.CookedComment{} for _, c := range comments { cookedComments = append(cookedComments, c.ToCooked()) } - // find children comments - for _, c := range comments { // TODO: Read more children, pagination for children comment - children := c.FetchChildren(func(db *gorm.DB) *gorm.DB { return db.Where("is_pending = 0") }) - for _, c := range children { - cookedComments = append(cookedComments, c.ToCooked()) + // comment children + for _, parent := range comments { // TODO: Read more children, pagination for children comment + children := parent.FetchChildren(AllowedComment(c, p)) + for _, child := range children { + cookedComments = append(cookedComments, child.ToCooked()) } } // count comments - total := CountComments(p.PageKey, func(db *gorm.DB) *gorm.DB { - return db.Where("page_key = ?", p.PageKey) - }) - totalParents := CountComments(p.PageKey, func(db *gorm.DB) *gorm.DB { - return db.Where("page_key = ? AND rid = 0", p.PageKey) - }) + total := CountComments(GetCommentQuery(c, p)) + totalParents := CountComments(GetParentCommentQuery(c, p)) return RespData(c, ResponseGet{ Comments: cookedComments, @@ -63,6 +65,19 @@ func ActionGet(c echo.Context) error { }) } +func GetCommentQuery(c echo.Context, p ParamsGet) *gorm.DB { + return lib.DB.Scopes(CommonQuery(c, p), Paginate(p.Offset, p.Limit), NotificationCenter(c, p)) +} +func GetParentCommentQuery(c echo.Context, p ParamsGet) *gorm.DB { + return GetCommentQuery(c, p).Scopes(ParentComment()) +} + +func CommonQuery(c echo.Context, p ParamsGet) func(db *gorm.DB) *gorm.DB { + return func(db *gorm.DB) *gorm.DB { + return db.Model(&model.Comment{}).Where("page_key = ?", p.PageKey).Order("created_at DESC") + } +} + func Paginate(offset int, limit int) func(db *gorm.DB) *gorm.DB { if offset < 0 { offset = 0 @@ -79,14 +94,57 @@ func Paginate(offset int, limit int) func(db *gorm.DB) *gorm.DB { } } -func FilterAllowedComment(c echo.Context, p ParamsGet) func(db *gorm.DB) *gorm.DB { +func AllowedComment(c echo.Context, p ParamsGet) func(db *gorm.DB) *gorm.DB { + return func(db *gorm.DB) *gorm.DB { + return db.Where("is_pending = 0") + } +} + +func ParentComment() func(db *gorm.DB) *gorm.DB { return func(db *gorm.DB) *gorm.DB { - return db.Where("rid = 0 AND is_pending = 0") + return db.Where("rid = 0") + } +} + +func NotificationCenter(c echo.Context, p ParamsGet) func(db *gorm.DB) *gorm.DB { + return func(db *gorm.DB) *gorm.DB { + if p.Name == "" || p.Email == "" { + return db.Scopes(AllowedComment(c, p)) // 不是通知中心 + } + if p.Type == "" { + p.Type = "mentions" + } + + user := FindUser(p.Name, p.Email) + + myCommentIDs := []int{} + if p.Type == "all" || p.Type == "mentions" { + var myComments []model.Comment + lib.DB.Where("user_id = ?", user.ID).Find(&myComments) + for _, comment := range myComments { + myCommentIDs = append(myCommentIDs, int(comment.ID)) + } + } + + if p.Type == "all" { + db = db.Where("rid IN (?) OR user_id = ?", myCommentIDs, user.ID) + } + if p.Type == "mentions" { + db = db.Where("rid IN (?) AND user_id != ?", myCommentIDs, user.ID) + } + if p.Type == "mine" { + db = db.Where("user_id = ?", user.ID) + } + if p.Type == "pending" { + db = db.Where("user_id = ? AND is_pending = 1", user.ID) + } + + return db } } -func CountComments(pageKey string, filter func(db *gorm.DB) *gorm.DB) int64 { +func CountComments(db *gorm.DB) int64 { var count int64 - lib.DB.Model(&model.Comment{}).Scopes(filter).Count(&count) + db.Count(&count) return count } From f7d1a417178789c1138d936916bfe73de855d952 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Fri, 17 Sep 2021 22:35:46 +0800 Subject: [PATCH 023/349] Comment List FlatMode & Message center. --- http/a_http.go | 3 +- http/api_main_get.go | 142 ++++++++++++++++++++++++++----------------- http/permission.go | 4 +- model/comment.go | 4 ++ 4 files changed, 96 insertions(+), 57 deletions(-) diff --git a/http/a_http.go b/http/a_http.go index 28fa72de4..9934f7af6 100644 --- a/http/a_http.go +++ b/http/a_http.go @@ -51,7 +51,8 @@ func Run() { Claims: &jwtCustomClaims{}, ContextKey: "user", SigningMethod: "HS256", - TokenLookup: "header:X-Auth-Token,query:token,form:token", + TokenLookup: "header:Authorization,query:token,form:token", + AuthScheme: "Bearer", SigningKey: []byte(config.Instance.AppKey), } diff --git a/http/api_main_get.go b/http/api_main_get.go index 087141386..68035d2f5 100644 --- a/http/api_main_get.go +++ b/http/api_main_get.go @@ -12,9 +12,11 @@ type ParamsGet struct { Limit int `mapstructure:"limit"` Offset int `mapstructure:"offset"` + // Message Center Name string `mapstructure:"name"` Email string `mapstructure:"email"` Type string `mapstructure:"type"` + // TODO: FlatMode string `mapstructure:"flat_mode"` } @@ -30,32 +32,68 @@ func ActionGet(c echo.Context) error { if isOK, resp := ParamsDecode(c, ParamsGet{}, &p); !isOK { return resp } + isMsgCenter := IsMsgCenter(p) // find page page := FindPage(p.PageKey) - // find comments - // comment parents var comments []model.Comment - GetParentCommentQuery(c, p).Find(&comments) + query := GetCommentQuery(c, p).Scopes(Paginate(p.Offset, p.Limit)) cookedComments := []model.CookedComment{} - for _, c := range comments { - cookedComments = append(cookedComments, c.ToCooked()) - } - // comment children - for _, parent := range comments { // TODO: Read more children, pagination for children comment - children := parent.FetchChildren(AllowedComment(c, p)) - for _, child := range children { - cookedComments = append(cookedComments, child.ToCooked()) + if !isMsgCenter { + query = query.Scopes(ParentComment()) + query.Find(&comments) + + for _, c := range comments { + cookedComments = append(cookedComments, c.ToCooked()) + } + + // comment children + for _, parent := range comments { // TODO: Read more children, pagination for children comment + children := parent.FetchChildren(AllowedComment()) + for _, child := range children { + cookedComments = append(cookedComments, child.ToCooked()) + } + } + } else { + // flat mode + query.Find(&comments) + + for _, c := range comments { + cookedComments = append(cookedComments, c.ToCooked()) + } + + containsComment := func(cid uint) bool { + for _, c := range cookedComments { + if c.ID == cid { + return true + } + } + return false + } + + // find linked comments + for _, c := range comments { + if c.Rid == 0 || containsComment(c.Rid) { + continue + } + + rComment := FindComment(c.Rid) // 查找被回复的评论 + if rComment.IsEmpty() { + continue + } + rCooked := rComment.ToCooked() + rCooked.Visible = false // 设置为不可见 + cookedComments = append(cookedComments, rCooked) } } // count comments total := CountComments(GetCommentQuery(c, p)) - totalParents := CountComments(GetParentCommentQuery(c, p)) + totalParents := CountComments(GetCommentQuery(c, p).Scopes(ParentComment())) return RespData(c, ResponseGet{ Comments: cookedComments, @@ -66,55 +104,21 @@ func ActionGet(c echo.Context) error { } func GetCommentQuery(c echo.Context, p ParamsGet) *gorm.DB { - return lib.DB.Scopes(CommonQuery(c, p), Paginate(p.Offset, p.Limit), NotificationCenter(c, p)) -} -func GetParentCommentQuery(c echo.Context, p ParamsGet) *gorm.DB { - return GetCommentQuery(c, p).Scopes(ParentComment()) -} - -func CommonQuery(c echo.Context, p ParamsGet) func(db *gorm.DB) *gorm.DB { - return func(db *gorm.DB) *gorm.DB { - return db.Model(&model.Comment{}).Where("page_key = ?", p.PageKey).Order("created_at DESC") - } -} - -func Paginate(offset int, limit int) func(db *gorm.DB) *gorm.DB { - if offset < 0 { - offset = 0 - } - - if limit > 100 { - limit = 100 - } else if limit <= 0 { - limit = 15 - } - - return func(db *gorm.DB) *gorm.DB { - return db.Offset(offset).Limit(limit) - } -} - -func AllowedComment(c echo.Context, p ParamsGet) func(db *gorm.DB) *gorm.DB { - return func(db *gorm.DB) *gorm.DB { - return db.Where("is_pending = 0") + query := lib.DB.Model(&model.Comment{}).Where("page_key = ?", p.PageKey).Order("created_at DESC") + if IsMsgCenter(p) { + query = query.Scopes(MsgCenter(c, p)) + } else { + query = query.Scopes(AllowedComment()) } + return query } -func ParentComment() func(db *gorm.DB) *gorm.DB { - return func(db *gorm.DB) *gorm.DB { - return db.Where("rid = 0") - } +func IsMsgCenter(p ParamsGet) bool { + return p.Name != "" && p.Email != "" } -func NotificationCenter(c echo.Context, p ParamsGet) func(db *gorm.DB) *gorm.DB { +func MsgCenter(c echo.Context, p ParamsGet) func(db *gorm.DB) *gorm.DB { return func(db *gorm.DB) *gorm.DB { - if p.Name == "" || p.Email == "" { - return db.Scopes(AllowedComment(c, p)) // 不是通知中心 - } - if p.Type == "" { - p.Type = "mentions" - } - user := FindUser(p.Name, p.Email) myCommentIDs := []int{} @@ -148,3 +152,31 @@ func CountComments(db *gorm.DB) int64 { db.Count(&count) return count } + +func Paginate(offset int, limit int) func(db *gorm.DB) *gorm.DB { + if offset < 0 { + offset = 0 + } + + if limit > 100 { + limit = 100 + } else if limit <= 0 { + limit = 15 + } + + return func(db *gorm.DB) *gorm.DB { + return db.Offset(offset).Limit(limit) + } +} + +func AllowedComment() func(db *gorm.DB) *gorm.DB { + return func(db *gorm.DB) *gorm.DB { + return db.Where("is_pending = 0") + } +} + +func ParentComment() func(db *gorm.DB) *gorm.DB { + return func(db *gorm.DB) *gorm.DB { + return db.Where("rid = 0") + } +} diff --git a/http/permission.go b/http/permission.go index 005498306..a01c13110 100644 --- a/http/permission.go +++ b/http/permission.go @@ -5,6 +5,7 @@ import ( "encoding/json" "fmt" "strconv" + "strings" "time" "github.com/ArtalkJS/ArtalkGo/config" @@ -130,7 +131,8 @@ func GetJwtInstanceByReq(c echo.Context) *jwt.Token { token = c.FormValue("token") } if token == "" { - token = c.Request().Header.Get("X-Auth-Token") + token = c.Request().Header.Get("Authorization") + token = strings.TrimPrefix(token, "Bearer ") } if token == "" { return nil diff --git a/model/comment.go b/model/comment.go index 96d5c9891..a133d88d6 100644 --- a/model/comment.go +++ b/model/comment.go @@ -85,6 +85,8 @@ type CookedComment struct { IsPending bool `json:"is_pending"` IsAllowReply bool `json:"is_allow_reply"` Rid uint `json:"rid"` + PageKey string `json:"page_key"` + Visible bool `json:"visible"` } func (c Comment) ToCooked() CookedComment { @@ -103,6 +105,8 @@ func (c Comment) ToCooked() CookedComment { IsPending: c.IsPending, IsAllowReply: c.IsAllowReply(), Rid: c.Rid, + PageKey: c.PageKey, + Visible: true, } } From 05bc345523036e267de0f0d17c8d1b1ce2d13a41 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Sat, 18 Sep 2021 14:57:34 +0800 Subject: [PATCH 024/349] Comment pending type support. --- http/a_http.go | 1 + http/api_main_get.go | 10 +++++++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/http/a_http.go b/http/a_http.go index 9934f7af6..5f5ed7ec8 100644 --- a/http/a_http.go +++ b/http/a_http.go @@ -34,6 +34,7 @@ func Run() { // 不启用操作限制的 path skipPath := []string{ "/api/captcha/", + "/api/get", // 获取评论不做限制 } for _, p := range skipPath { diff --git a/http/api_main_get.go b/http/api_main_get.go index 68035d2f5..ef6b65240 100644 --- a/http/api_main_get.go +++ b/http/api_main_get.go @@ -53,7 +53,7 @@ func ActionGet(c echo.Context) error { // comment children for _, parent := range comments { // TODO: Read more children, pagination for children comment - children := parent.FetchChildren(AllowedComment()) + children := parent.FetchChildren(AllowedComment(c)) for _, child := range children { cookedComments = append(cookedComments, child.ToCooked()) } @@ -108,7 +108,7 @@ func GetCommentQuery(c echo.Context, p ParamsGet) *gorm.DB { if IsMsgCenter(p) { query = query.Scopes(MsgCenter(c, p)) } else { - query = query.Scopes(AllowedComment()) + query = query.Scopes(AllowedComment(c)) } return query } @@ -169,8 +169,12 @@ func Paginate(offset int, limit int) func(db *gorm.DB) *gorm.DB { } } -func AllowedComment() func(db *gorm.DB) *gorm.DB { +func AllowedComment(c echo.Context) func(db *gorm.DB) *gorm.DB { return func(db *gorm.DB) *gorm.DB { + if CheckIsAdminReq(c) { + return db // 管理员显示全部 + } + return db.Where("is_pending = 0") } } From 230b501e23a68f1145c5e34cfe107f2e2daea4d2 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Sat, 18 Sep 2021 15:18:59 +0800 Subject: [PATCH 025/349] Modify output date format. --- model/comment.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/model/comment.go b/model/comment.go index a133d88d6..67a06b6a9 100644 --- a/model/comment.go +++ b/model/comment.go @@ -100,7 +100,7 @@ func (c Comment) ToCooked() CookedComment { EmailEncrypted: lib.GetMD5Hash(user.Email), Link: user.Link, UA: c.UA, - Date: c.CreatedAt.Local().String(), + Date: c.CreatedAt.Local().Format("2006-01-02 15:04:05"), IsCollapsed: c.IsCollapsed, IsPending: c.IsPending, IsAllowReply: c.IsAllowReply(), From c124b0abc16e29b4865e1ff8757a41431b036ac0 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Mon, 27 Sep 2021 13:54:38 +0800 Subject: [PATCH 026/349] Fix emailsend & Add page details & site isolation. --- artalk-go.example.yml | 2 +- config/config.go | 2 +- go.mod | 1 + go.sum | 5 +++ http/a_http.go | 3 +- http/api_login.go | 29 +++++++--------- http/api_main_add.go | 25 +++++++++----- http/api_man_edit_comment.go | 2 +- http/api_man_edit_page.go | 17 ++++++++-- http/api_man_page_fetch.go | 31 +++++++++++++++++ http/api_man_send_mail.go | 27 +++++++++++++++ http/api_manager.go | 8 ----- http/permission.go | 10 +++--- http/utils.go | 18 +++++----- lib/email/email.go | 51 ++++++++++++++++++++-------- lib/utils.go | 5 +++ model/comment.go | 2 ++ model/page.go | 66 ++++++++++++++++++++++++++++++++---- model/site.go | 32 +++++++++++++++++ model/user.go | 36 ++++++++------------ 20 files changed, 276 insertions(+), 96 deletions(-) create mode 100644 http/api_man_page_fetch.go create mode 100644 http/api_man_send_mail.go create mode 100644 model/site.go diff --git a/artalk-go.example.yml b/artalk-go.example.yml index b8da2d009..e8f32a303 100644 --- a/artalk-go.example.yml +++ b/artalk-go.example.yml @@ -53,8 +53,8 @@ email: enabled: true # 总开关 send_type: 'smtp' # 发送方式 [ali_dm, smtp, sendmail] send_name: 'ArtalkGo' # 发信人昵称 + send_addr: 'example@qq.com' # 发信人地址 mail_subject: '您在 Artalk 收到了新的回复' - admin_addr: 'example@example.com' # 管理员邮箱地址(文章收到评论时通知) mail_subject_to_admin: '您的文章有新的回复' mail_tpl: 'default' # 邮件模板文件 smtp: diff --git a/config/config.go b/config/config.go index 32d1379c9..946e529c7 100644 --- a/config/config.go +++ b/config/config.go @@ -64,9 +64,9 @@ type CaptchaConf struct { type EmailConf struct { Enabled bool `mapstructure:"enabled"` // 总开关 - AdminAddr string `mapstructure:"admin_addr"` // 管理员邮箱 SendType EmailSenderType `mapstructure:"send_type"` // 发送方式 SendName string `mapstructure:"send_name"` // 发件人名 + SendAddr string `mapstructure:"send_addr"` // 发件人地址 MailSubject string `mapstructure:"mail_subject"` // 邮件标题 MailSubjectToAdmin string `mapstructure:"mail_subject_to_admin"` // 邮件标题 (发送给管理员用) MailTpl string `mapstructure:"mail_tpl"` // 邮件模板 diff --git a/go.mod b/go.mod index deac7a187..290e976ef 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,7 @@ module github.com/ArtalkJS/ArtalkGo go 1.16 require ( + github.com/PuerkitoBio/goquery v1.7.1 // indirect github.com/allegro/bigcache/v3 v3.0.0 github.com/eko/gocache/v2 v2.1.0 github.com/fsnotify/fsnotify v1.5.1 // indirect diff --git a/go.sum b/go.sum index a39824aa3..79a9779c4 100644 --- a/go.sum +++ b/go.sum @@ -45,6 +45,8 @@ github.com/Masterminds/semver/v3 v3.1.1 h1:hLg3sBzpNErnxhQtUy/mmLR2I9foDujNK030I github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= +github.com/PuerkitoBio/goquery v1.7.1 h1:oE+T06D+1T7LNrn91B4aERsRIeCLJ/oPSa6xB9FPnz4= +github.com/PuerkitoBio/goquery v1.7.1/go.mod h1:XY0pP4kfraEmmV1O7Uf6XyjoslwsneBbgeDjLYuN8xY= github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= @@ -62,6 +64,8 @@ github.com/allegro/bigcache/v2 v2.2.5 h1:mRc8r6GQjuJsmSKQNPsR5jQVXc8IJ1xsW5YXUYM github.com/allegro/bigcache/v2 v2.2.5/go.mod h1:FppZsIO+IZk7gCuj5FiIDHGygD9xvWQcqg1uIPMb6tY= github.com/allegro/bigcache/v3 v3.0.0 h1:5Hxq+GTy8gHEeQccCZZDCfZRTydUfErdUf0iVDcMAFg= github.com/allegro/bigcache/v3 v3.0.0/go.mod h1:t5TAJn1B9qvf/VlJrSM1r6NlFAYoFDubYUsCuIO9nUQ= +github.com/andybalholm/cascadia v1.2.0 h1:vuRCkM5Ozh/BfmsaTm26kbjm0mIOM3yS5Ek/F5h18aE= +github.com/andybalholm/cascadia v1.2.0/go.mod h1:YCyR8vOZT9aZ1CHEd8ap0gMVm2aFgxBp0T0eFw1RUQY= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= @@ -730,6 +734,7 @@ golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= diff --git a/http/a_http.go b/http/a_http.go index 5f5ed7ec8..1f1770499 100644 --- a/http/a_http.go +++ b/http/a_http.go @@ -92,5 +92,6 @@ func InitRoute(e *echo.Echo) { manager.POST("/edit-page", ActionManagerEditPage) manager.POST("/edit-comment", ActionManagerEditComment) manager.POST("/del-comment", ActionManagerDelComment) - manager.GET("/send-mail", ActionManagerSendMail) + manager.POST("/page-fetch", ActionManagerPageFetch) + manager.POST("/send-mail", ActionManagerSendMail) } diff --git a/http/api_login.go b/http/api_login.go index e1dba195d..5f6620926 100644 --- a/http/api_login.go +++ b/http/api_login.go @@ -6,30 +6,25 @@ import ( "github.com/labstack/echo/v4" ) -func ActionLogin(c echo.Context) error { - name := c.FormValue("name") - email := c.FormValue("email") - password := c.FormValue("password") - if name == "" { - name = c.QueryParam("name") - } - if email == "" { - email = c.QueryParam("email") - } - if password == "" { - password = c.QueryParam("password") - } +type ParamsLogin struct { + Name string `mapstructure:"name" param:"required"` + Email string `mapstructure:"email" param:"required"` + Password string `mapstructure:"password" param:"required"` + Site string `mapstructure:"site"` +} - if name == "" || email == "" || password == "" { - return RespError(c, "Incomplete parameters.") +func ActionLogin(c echo.Context) error { + var p ParamsLogin + if isOK, resp := ParamsDecode(c, ParamsLogin{}, &p); !isOK { + return resp } // record action for limiting action RecordAction(c) var user model.User - lib.DB.Where("name = ? AND email = ?", name, email).First(&user) // name = ? OR email = ? - if user.IsEmpty() || user.Password != password { + lib.DB.Where("name = ? AND email = ? AND site = ?", p.Name, p.Email).First(&user) // name = ? OR email = ? + if user.IsEmpty() || user.Password != p.Password { return RespError(c, "验证失败") } diff --git a/http/api_main_add.go b/http/api_main_add.go index 22e35d4c4..7421a38ad 100644 --- a/http/api_main_add.go +++ b/http/api_main_add.go @@ -10,13 +10,15 @@ import ( ) type ParamsAdd struct { - Name string `mapstructure:"name" param:"required"` - Email string `mapstructure:"email" param:"required"` - Link string `mapstructure:"link"` - Content string `mapstructure:"content" param:"required"` - Rid uint `mapstructure:"rid"` - PageKey string `mapstructure:"page_key" param:"required"` - Token string `mapstructure:"token"` + Name string `mapstructure:"name" param:"required"` + Email string `mapstructure:"email" param:"required"` + Link string `mapstructure:"link"` + Content string `mapstructure:"content" param:"required"` + Rid uint `mapstructure:"rid"` + PageKey string `mapstructure:"page_key" param:"required"` + PageUrl string `mapstructure:"page_url"` + PageTitle string `mapstructure:"page_title"` + Token string `mapstructure:"token"` } type ResponseAdd struct { @@ -43,7 +45,7 @@ func ActionAdd(c echo.Context) error { RecordAction(c) // find page - page := FindCreatePage(p.PageKey) + page := FindCreatePage(p.PageKey, p.PageUrl, p.PageTitle) // check if the user is allowed to comment if isAllowed, resp := CheckIfAllowed(c, p.Name, p.Email, page); !isAllowed { @@ -107,6 +109,13 @@ func ActionAdd(c echo.Context) error { } email.SendToAdmin(comment.ToCookedForEmail()) // 发送邮件给管理员 + // fetch page url data + if page.Url != "" && page.Title == "" { + go func() { + page.FetchURL() + }() + } + return RespData(c, ResponseAdd{ Comment: comment.ToCooked(), }) diff --git a/http/api_man_edit_comment.go b/http/api_man_edit_comment.go index e040288bd..30966359f 100644 --- a/http/api_man_edit_comment.go +++ b/http/api_man_edit_comment.go @@ -67,7 +67,7 @@ func ActionManagerEditComment(c echo.Context) error { // pageKey if p.PageKey != "" { if p.PageKey != comment.PageKey { - FindCreatePage(p.PageKey) + FindCreatePage(p.PageKey, "", "") comment.PageKey = p.PageKey } } diff --git a/http/api_man_edit_page.go b/http/api_man_edit_page.go index 847534c4c..81a345a8b 100644 --- a/http/api_man_edit_page.go +++ b/http/api_man_edit_page.go @@ -4,7 +4,9 @@ import "github.com/labstack/echo/v4" type ParamsEditPage struct { Key string `mapstructure:"key" param:"required"` - OnlyAdmin string `mapstructure:"only_admin"` + Url string `mapstructure:"url"` + Title string `mapstructure:"title"` + AdminOnly string `mapstructure:"admin_only"` } func ActionManagerEditPage(c echo.Context) error { @@ -22,7 +24,18 @@ func ActionManagerEditPage(c echo.Context) error { return RespError(c, "page not found.") } - switch p.OnlyAdmin { + // url + if p.Url != "" { + page.Url = p.Url + } + + // title + if p.Title != "" { + page.Title = p.Title + } + + // only_admin + switch p.AdminOnly { case "1": page.AdminOnly = true case "0": diff --git a/http/api_man_page_fetch.go b/http/api_man_page_fetch.go new file mode 100644 index 000000000..dbcd5577b --- /dev/null +++ b/http/api_man_page_fetch.go @@ -0,0 +1,31 @@ +package http + +import "github.com/labstack/echo/v4" + +type ParamsPageFetch struct { + Key string `mapstructure:"key" param:"required"` +} + +func ActionManagerPageFetch(c echo.Context) error { + if isOK, resp := AdminOnly(c); !isOK { + return resp + } + + var p ParamsPageFetch + if isOK, resp := ParamsDecode(c, ParamsPageFetch{}, &p); !isOK { + return resp + } + + page := FindPage(p.Key) + if page.IsEmpty() { + return RespError(c, "page not found.") + } + + if err := page.FetchURL(); err != nil { + return RespError(c, "page fetch error: "+err.Error()) + } + + return RespData(c, Map{ + "page": page.ToCooked(), + }) +} diff --git a/http/api_man_send_mail.go b/http/api_man_send_mail.go new file mode 100644 index 000000000..02ecdc73a --- /dev/null +++ b/http/api_man_send_mail.go @@ -0,0 +1,27 @@ +package http + +import ( + "github.com/ArtalkJS/ArtalkGo/lib/email" + "github.com/labstack/echo/v4" +) + +type ParamsSendMail struct { + Subject string `mapstructure:"subject" param:"required"` + Body string `mapstructure:"body" param:"required"` + ToAddr string `mapstructure:"to_addr" param:"required"` +} + +func ActionManagerSendMail(c echo.Context) error { + if isOK, resp := AdminOnly(c); !isOK { + return resp + } + + var p ParamsSendMail + if isOK, resp := ParamsDecode(c, ParamsSendMail{}, &p); !isOK { + return resp + } + + email.SendTo(p.Subject, p.Body, p.ToAddr) + + return RespSuccess(c) +} diff --git a/http/api_manager.go b/http/api_manager.go index b3d27808f..cef0325f5 100644 --- a/http/api_manager.go +++ b/http/api_manager.go @@ -5,14 +5,6 @@ import ( "github.com/labstack/echo/v4" ) -func ActionManagerSendMail(c echo.Context) error { - if isOK, resp := AdminOnly(c); !isOK { - return resp - } - - return RespSuccess(c) -} - func AdminOnly(c echo.Context) (isOK bool, resp error) { if !CheckIsAdminInJwtMiddleware(c) { return false, RespError(c, "需要验证管理员身份", Map{"need_login": true}) diff --git a/http/permission.go b/http/permission.go index a01c13110..effbe654b 100644 --- a/http/permission.go +++ b/http/permission.go @@ -23,9 +23,9 @@ var CommonJwtConfig middleware.JWTConfig // jwtCustomClaims are custom claims extending default ones. // See https://github.com/golang-jwt/jwt for more examples type jwtCustomClaims struct { - UserName string `json:"name"` - UserEmail string `json:"email"` - UserType model.UserType `json:"type"` + UserName string `json:"name"` + UserEmail string `json:"email"` + UserIsAdmin bool `json:"is_admin"` jwt.StandardClaims } @@ -158,7 +158,7 @@ func CheckIsAdminByJwt(jwt *jwt.Token) bool { return false } - return user.Type == model.UserAdmin + return user.IsAdmin } func CheckIsAdminReq(c echo.Context) bool { @@ -182,7 +182,7 @@ func GetUserByJwt(jwt *jwt.Token) model.User { name := claims.UserName email := claims.UserEmail - if claims.UserType != model.UserAdmin { + if !claims.UserIsAdmin { return model.User{} } diff --git a/http/utils.go b/http/utils.go index 2755da0e7..d143729ad 100644 --- a/http/utils.go +++ b/http/utils.go @@ -21,9 +21,9 @@ import ( func LoginGetUserToken(user model.User) string { // Set custom claims claims := &jwtCustomClaims{ - UserName: user.Name, - UserEmail: user.Email, - UserType: user.Type, + UserName: user.Name, + UserEmail: user.Email, + UserIsAdmin: user.IsAdmin, StandardClaims: jwt.StandardClaims{ ExpiresAt: time.Now().Add(time.Second * time.Duration(config.Instance.LoginTimeout)).Unix(), // 过期时间 }, @@ -126,7 +126,7 @@ func FindUser(name string, email string) model.User { func IsAdminUser(name string, email string) bool { var user model.User // 还是用 AND 吧,OR 太混乱了 - lib.DB.Where("(name = ? AND email = ?) AND type = ?", name, email, model.UserAdmin).First(&user) + lib.DB.Where("(name = ? AND email = ?) AND is_admin = 1", name, email).First(&user) return !user.IsEmpty() } @@ -138,10 +138,10 @@ func UpdateComment(comment *model.Comment) error { return err } -func FindCreatePage(pageKey string) model.Page { +func FindCreatePage(pageKey string, pageUrl string, pageTitle string) model.Page { page := FindPage(pageKey) if page.IsEmpty() { - page = NewPage(pageKey) + page = NewPage(pageKey, pageUrl, pageTitle) } return page } @@ -189,9 +189,11 @@ func FindPageByID(id uint) model.Page { return page } -func NewPage(key string) model.Page { +func NewPage(key string, pageUrl string, pageTitle string) model.Page { page := model.Page{ - Key: key, + Key: key, + Url: pageUrl, + Title: pageTitle, } err := lib.DB.Create(&page).Error diff --git a/lib/email/email.go b/lib/email/email.go index ab8c5d4d9..9c37a9c56 100644 --- a/lib/email/email.go +++ b/lib/email/email.go @@ -2,9 +2,20 @@ package email import ( "github.com/ArtalkJS/ArtalkGo/config" + "github.com/ArtalkJS/ArtalkGo/lib" "github.com/ArtalkJS/ArtalkGo/model" ) +func SendTo(subject string, body string, toAddr string) { + AddToQueue(Email{ + FromAddr: config.Instance.Email.SendAddr, + FromName: config.Instance.Email.SendName, + ToAddr: toAddr, + Subject: subject, + Body: body, + }) +} + func Send(from model.CookedCommentForEmail, to model.CookedCommentForEmail) { if !config.Instance.Email.Enabled { return @@ -15,7 +26,7 @@ func Send(from model.CookedCommentForEmail, to model.CookedCommentForEmail) { body := RenderEmailTpl(from, to) AddToQueue(Email{ - FromAddr: from.Email, + FromAddr: config.Instance.Email.SendAddr, FromName: config.Instance.Email.SendName, ToAddr: to.Email, Subject: subject, @@ -28,22 +39,32 @@ func SendToAdmin(from model.CookedCommentForEmail) { if !config.Instance.Email.Enabled { return } - if config.Instance.Email.AdminAddr == "" { + + // 查询所有 admin + var admins []model.User + lib.DB.Where(&model.User{IsAdmin: true}).Find(&admins) + + if len(admins) == 0 { return } - go func() { - subject := RenderConfig(config.Instance.Email.MailSubjectToAdmin) - body := RenderEmailTpl(from, model.CookedCommentForEmail{ - Nick: "Admin", - }) + // 发邮件给每个 admin + for _, admin := range admins { + email := admin.Email - AddToQueue(Email{ - FromAddr: from.Email, - FromName: config.Instance.Email.SendName, - ToAddr: config.Instance.Email.AdminAddr, - Subject: subject, - Body: body, - }) - }() + go func() { + subject := RenderConfig(config.Instance.Email.MailSubjectToAdmin) + body := RenderEmailTpl(from, model.CookedCommentForEmail{ + Nick: "Admin", + }) + + AddToQueue(Email{ + FromAddr: config.Instance.Email.SendAddr, + FromName: config.Instance.Email.SendName, + ToAddr: email, + Subject: subject, + Body: body, + }) + }() + } } diff --git a/lib/utils.go b/lib/utils.go index fc693cbca..101c52ec4 100644 --- a/lib/utils.go +++ b/lib/utils.go @@ -99,3 +99,8 @@ func ContainsStr(s []string, v string) bool { } return false } + +func IsUrlValid(urlStr string) bool { + _, err := url.ParseRequestURI(urlStr) + return err != nil +} diff --git a/model/comment.go b/model/comment.go index 67a06b6a9..f82ffc824 100644 --- a/model/comment.go +++ b/model/comment.go @@ -13,8 +13,10 @@ type Comment struct { UserID uint `gorm:"index"` PageKey string `gorm:"index"` + SiteID uint `gorm:"index"` User User `gorm:"foreignKey:UserID;references:ID"` Page Page `gorm:"foreignKey:PageKey;references:Key"` + Site Site `gorm:"foreignKey:SiteID;references:ID"` Rid uint `gorm:"index"` UA string diff --git a/model/page.go b/model/page.go index 5de851b49..fc2315cdf 100644 --- a/model/page.go +++ b/model/page.go @@ -1,16 +1,24 @@ package model -import "gorm.io/gorm" +import ( + "errors" + "net/http" -type PageType string - -const () + "github.com/ArtalkJS/ArtalkGo/lib" + "github.com/PuerkitoBio/goquery" + "github.com/sirupsen/logrus" + "gorm.io/gorm" +) type Page struct { gorm.Model Key string `gorm:"uniqueIndex"` + Title string + Url string AdminOnly bool - Type PageType + + SiteID uint `gorm:"index"` + Site Site `gorm:"foreignKey:SiteID;references:ID"` } func (p Page) IsEmpty() bool { @@ -20,13 +28,57 @@ func (p Page) IsEmpty() bool { type CookedPage struct { ID uint `json:"id"` AdminOnly bool `json:"admin_only"` - PageKey string `json:"page_key"` + Key string `json:"key"` + URL string `json:"url"` + Title string `json:"title"` + SiteID uint `json:"site_id"` } func (p Page) ToCooked() CookedPage { return CookedPage{ ID: p.ID, AdminOnly: p.AdminOnly, - PageKey: p.Key, + Key: p.Key, + URL: p.Url, + Title: p.Title, + SiteID: p.SiteID, + } +} + +func (p *Page) FetchURL() error { + if !lib.IsUrlValid(p.Url) { + return errors.New("URL is invalid") + } + + // Request the HTML page. + res, err := http.Get(p.Url) + if err != nil { + logrus.Error(err) + return err + } + defer res.Body.Close() + if res.StatusCode != 200 { + logrus.Error("status code error: %d %s", res.StatusCode, res.Status) + return errors.New("status code error") } + + // Load the HTML document + doc, err := goquery.NewDocumentFromReader(res.Body) + if err != nil { + logrus.Error(err) + return err + } + + // 读取页面 title 并保存 + title := doc.Find("title").Text() + if title != "" { + p.Title = title + } + + if err := lib.DB.Save(p).Error; err != nil { + logrus.Error("FetchURL 保存失败") + return err + } + + return nil } diff --git a/model/site.go b/model/site.go new file mode 100644 index 000000000..80f38b6d0 --- /dev/null +++ b/model/site.go @@ -0,0 +1,32 @@ +package model + +import ( + "gorm.io/gorm" +) + +type Site struct { + gorm.Model + Name string + Url string + UserID uint +} + +func (s Site) IsEmpty() bool { + return s.ID == 0 +} + +type CookedSite struct { + ID uint `json:"id"` + Name string `json:"name"` + Url string `json:"url"` + UserID uint `json:"user_id"` +} + +func (s Site) ToCooked() CookedSite { + return CookedSite{ + ID: s.ID, + Name: s.Name, + Url: s.Url, + UserID: s.UserID, + } +} diff --git a/model/user.go b/model/user.go index 0c0728669..2c23bacbd 100644 --- a/model/user.go +++ b/model/user.go @@ -4,13 +4,6 @@ import ( "gorm.io/gorm" ) -type UserType string - -const ( - UserBanned UserType = "banned" - UserAdmin UserType = "admin" -) - type User struct { gorm.Model Name string `gorm:"index"` @@ -21,26 +14,25 @@ type User struct { BadgeColor string LastIP string LastUA string - Type UserType `gorm:"index"` + IsAdmin bool + + SiteID uint `gorm:"index"` + Site Site `gorm:"foreignKey:SiteID;references:ID"` } func (u User) IsEmpty() bool { return u.ID == 0 } -func (u User) IsAdmin() bool { - return u.Type == UserAdmin -} - type CookedUser struct { - ID uint `json:"id"` - Name string `json:"name"` - Email string `json:"email"` - Link string `json:"link"` - BadgeName string `json:"badge_name"` - BadgeColor string `json:"badge_color"` - IsAdmin bool `json:"is_admin"` - Type UserType `json:"type"` + ID uint `json:"id"` + Name string `json:"name"` + Email string `json:"email"` + Link string `json:"link"` + BadgeName string `json:"badge_name"` + BadgeColor string `json:"badge_color"` + IsAdmin bool `json:"is_admin"` + SiteID uint `json:"site_id"` } func (u User) ToCooked() CookedUser { @@ -51,7 +43,7 @@ func (u User) ToCooked() CookedUser { Link: u.Link, BadgeName: u.BadgeName, BadgeColor: u.BadgeColor, - IsAdmin: u.IsAdmin(), - Type: u.Type, + IsAdmin: u.IsAdmin, + SiteID: u.SiteID, } } From 0a25166bbd9643e8d746695242e6b6ab323bebc3 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Mon, 27 Sep 2021 15:32:04 +0800 Subject: [PATCH 027/349] Complete Site Isolation & Sync config AdminUsers with database. --- artalk-go.example.yml | 1 + cmd/root.go | 55 ++++++++- config/config.go | 1 + http/api_main_add.go | 37 ++++--- http/api_main_get.go | 27 +++-- http/api_man_del_comment.go | 15 ++- http/api_man_edit_comment.go | 24 +++- http/api_man_edit_page.go | 22 +++- http/api_man_page_fetch.go | 17 ++- http/api_user.go | 19 +++- http/{api_login.go => api_user_login.go} | 16 ++- http/permission.go | 16 +-- http/utils.go | 135 ++++------------------- lib/utils.go | 11 ++ model/query.go | 116 +++++++++++++++++++ model/user.go | 3 + 16 files changed, 350 insertions(+), 165 deletions(-) rename http/{api_login.go => api_user_login.go} (70%) create mode 100644 model/query.go diff --git a/artalk-go.example.yml b/artalk-go.example.yml index e8f32a303..fa015c5b2 100644 --- a/artalk-go.example.yml +++ b/artalk-go.example.yml @@ -32,6 +32,7 @@ admin_users: password: '' badge_name: '管理员' badge_color: '#FF6C00' + site_id: 0 # 登录超时 (单位:秒) login_timeout: 259200 diff --git a/cmd/root.go b/cmd/root.go index 4ecbd63b5..a2e409cfd 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -114,7 +114,60 @@ func initDB() { } // Migrate the schema - lib.DB.AutoMigrate(&model.Page{}, &model.User{}, &model.Comment{}) // 注意表的创建顺序,因为有关联字段 + lib.DB.AutoMigrate(&model.Site{}, &model.Page{}, &model.User{}, &model.Comment{}) // 注意表的创建顺序,因为有关联字段 + + syncConfWithDB() +} + +// 同步配置文件与数据库 +func syncConfWithDB() { + // 导入配置文件的管理员用户 + for _, admin := range config.Instance.AdminUsers { + user := model.FindUser(admin.Name, admin.Email, admin.SiteID) + if user.IsEmpty() { + // create + user = model.User{ + Name: admin.Name, + Email: admin.Email, + Link: admin.Link, + Password: admin.Password, + BadgeName: admin.BadgeName, + BadgeColor: admin.BadgeColor, + SiteID: admin.SiteID, + IsAdmin: true, + IsInConf: true, + } + lib.DB.Create(&user) + } else { + // update + user.Link = admin.Link + user.Password = admin.Password + user.BadgeName = admin.BadgeName + user.BadgeColor = admin.BadgeColor + user.SiteID = admin.SiteID + user.IsAdmin = true + user.IsInConf = true + lib.DB.Save(&user) + } + } + + // 清理配置文件中不存在的用户 + var dbAdminUsers []model.User + lib.DB.Where(&model.User{IsInConf: true}).Find(&dbAdminUsers) + for _, dbU := range dbAdminUsers { + isUserExist := func() bool { + for _, confU := range config.Instance.AdminUsers { + if confU.Name == dbU.Name && confU.Email == dbU.Email { + return true + } + } + return false + } + + if !isUserExist() { + lib.DB.Delete(&dbU) + } + } } func initCache() { diff --git a/config/config.go b/config/config.go index 946e529c7..d3d74f187 100644 --- a/config/config.go +++ b/config/config.go @@ -49,6 +49,7 @@ type AdminUserConf struct { Password string `mapstructure:"password"` BadgeName string `mapstructure:"badge_name"` BadgeColor string `mapstructure:"badge_color"` + SiteID uint `mapstructure:"site_id"` } type ModeratorConf struct { diff --git a/http/api_main_add.go b/http/api_main_add.go index 7421a38ad..e65aa5846 100644 --- a/http/api_main_add.go +++ b/http/api_main_add.go @@ -10,15 +10,19 @@ import ( ) type ParamsAdd struct { - Name string `mapstructure:"name" param:"required"` - Email string `mapstructure:"email" param:"required"` - Link string `mapstructure:"link"` - Content string `mapstructure:"content" param:"required"` - Rid uint `mapstructure:"rid"` + Name string `mapstructure:"name" param:"required"` + Email string `mapstructure:"email" param:"required"` + Link string `mapstructure:"link"` + Content string `mapstructure:"content" param:"required"` + Rid uint `mapstructure:"rid"` + PageKey string `mapstructure:"page_key" param:"required"` PageUrl string `mapstructure:"page_url"` PageTitle string `mapstructure:"page_title"` - Token string `mapstructure:"token"` + + Token string `mapstructure:"token"` + Site string `mapstructure:"site"` + SiteID uint } type ResponseAdd struct { @@ -31,10 +35,10 @@ func ActionAdd(c echo.Context) error { return resp } - if !ValidateEmail(p.Email) { + if !lib.ValidateEmail(p.Email) { return RespError(c, "Invalid email.") } - if p.Link != "" && !ValidateURL(p.Link) { + if p.Link != "" && !lib.ValidateURL(p.Link) { return RespError(c, "Invalid link.") } @@ -44,16 +48,22 @@ func ActionAdd(c echo.Context) error { // record action for limiting action RecordAction(c) + // find site + p.SiteID = HandleSiteParam(p.Site) + if isOK, resp := CheckSite(c, p.SiteID); !isOK { + return resp + } + // find page - page := FindCreatePage(p.PageKey, p.PageUrl, p.PageTitle) + page := model.FindCreatePage(p.PageKey, p.PageUrl, p.PageTitle, p.SiteID) // check if the user is allowed to comment - if isAllowed, resp := CheckIfAllowed(c, p.Name, p.Email, page); !isAllowed { + if isAllowed, resp := CheckIfAllowed(c, p.Name, p.Email, page, p.SiteID); !isAllowed { return resp } // find user - user := FindCreateUser(p.Name, p.Email) + user := model.FindCreateUser(p.Name, p.Email, p.SiteID) if user.ID == 0 || page.Key == "" { logrus.Error("Cannot get user or page.") return RespError(c, "评论失败") @@ -62,7 +72,7 @@ func ActionAdd(c echo.Context) error { // check reply comment var parentComment model.Comment if p.Rid != 0 { - parentComment = FindComment(p.Rid) + parentComment = model.FindComment(p.Rid, p.SiteID) if parentComment.IsEmpty() { return RespError(c, "找不到父评论") } @@ -83,6 +93,7 @@ func ActionAdd(c echo.Context) error { UA: ua, IsPending: false, IsCollapsed: false, + SiteID: p.SiteID, } // default comment type @@ -101,7 +112,7 @@ func ActionAdd(c echo.Context) error { user.Link = p.Link user.LastIP = ip user.LastUA = ua - UpdateUser(&user) + model.UpdateUser(&user) // send email if comment.Rid != 0 { diff --git a/http/api_main_get.go b/http/api_main_get.go index ef6b65240..ba8b032f1 100644 --- a/http/api_main_get.go +++ b/http/api_main_get.go @@ -17,7 +17,8 @@ type ParamsGet struct { Email string `mapstructure:"email"` Type string `mapstructure:"type"` - // TODO: FlatMode string `mapstructure:"flat_mode"` + Site string `mapstructure:"site"` + SiteID uint } type ResponseGet struct { @@ -34,13 +35,19 @@ func ActionGet(c echo.Context) error { } isMsgCenter := IsMsgCenter(p) + // find site + p.SiteID = HandleSiteParam(p.Site) + if isOK, resp := CheckSite(c, p.SiteID); !isOK { + return resp + } + // find page - page := FindPage(p.PageKey) + page := model.FindPage(p.PageKey, p.SiteID) // comment parents var comments []model.Comment - query := GetCommentQuery(c, p).Scopes(Paginate(p.Offset, p.Limit)) + query := GetCommentQuery(c, p, p.SiteID).Scopes(Paginate(p.Offset, p.Limit)) cookedComments := []model.CookedComment{} if !isMsgCenter { @@ -81,7 +88,7 @@ func ActionGet(c echo.Context) error { continue } - rComment := FindComment(c.Rid) // 查找被回复的评论 + rComment := model.FindComment(c.Rid, p.SiteID) // 查找被回复的评论 if rComment.IsEmpty() { continue } @@ -92,8 +99,8 @@ func ActionGet(c echo.Context) error { } // count comments - total := CountComments(GetCommentQuery(c, p)) - totalParents := CountComments(GetCommentQuery(c, p).Scopes(ParentComment())) + total := CountComments(GetCommentQuery(c, p, p.SiteID)) + totalParents := CountComments(GetCommentQuery(c, p, p.SiteID).Scopes(ParentComment())) return RespData(c, ResponseGet{ Comments: cookedComments, @@ -103,10 +110,10 @@ func ActionGet(c echo.Context) error { }) } -func GetCommentQuery(c echo.Context, p ParamsGet) *gorm.DB { +func GetCommentQuery(c echo.Context, p ParamsGet, siteID uint) *gorm.DB { query := lib.DB.Model(&model.Comment{}).Where("page_key = ?", p.PageKey).Order("created_at DESC") if IsMsgCenter(p) { - query = query.Scopes(MsgCenter(c, p)) + query = query.Scopes(MsgCenter(c, p, siteID)) } else { query = query.Scopes(AllowedComment(c)) } @@ -117,9 +124,9 @@ func IsMsgCenter(p ParamsGet) bool { return p.Name != "" && p.Email != "" } -func MsgCenter(c echo.Context, p ParamsGet) func(db *gorm.DB) *gorm.DB { +func MsgCenter(c echo.Context, p ParamsGet, siteID uint) func(db *gorm.DB) *gorm.DB { return func(db *gorm.DB) *gorm.DB { - user := FindUser(p.Name, p.Email) + user := model.FindUser(p.Name, p.Email, siteID) myCommentIDs := []int{} if p.Type == "all" || p.Type == "mentions" { diff --git a/http/api_man_del_comment.go b/http/api_man_del_comment.go index 3d9c62260..69107bf7d 100644 --- a/http/api_man_del_comment.go +++ b/http/api_man_del_comment.go @@ -11,6 +11,9 @@ import ( type ParamsDelComment struct { ID string `mapstructure:"id" param:"required"` + + Site string `mapstructure:"id"` + SiteID uint } func ActionManagerDelComment(c echo.Context) error { @@ -18,8 +21,8 @@ func ActionManagerDelComment(c echo.Context) error { return resp } - var p ParamsEditComment - if isOK, resp := ParamsDecode(c, ParamsEditComment{}, &p); !isOK { + var p ParamsDelComment + if isOK, resp := ParamsDecode(c, ParamsDelComment{}, &p); !isOK { return resp } @@ -28,7 +31,13 @@ func ActionManagerDelComment(c echo.Context) error { return RespError(c, "invalid id.") } - comment := FindComment(uint(id)) + // find site + p.SiteID = HandleSiteParam(p.Site) + if isOK, resp := CheckSite(c, p.SiteID); !isOK { + return resp + } + + comment := model.FindComment(uint(id), p.SiteID) if comment.IsEmpty() { return RespError(c, "comment not found.") } diff --git a/http/api_man_edit_comment.go b/http/api_man_edit_comment.go index 30966359f..7228a828b 100644 --- a/http/api_man_edit_comment.go +++ b/http/api_man_edit_comment.go @@ -3,11 +3,17 @@ package http import ( "strconv" + "github.com/ArtalkJS/ArtalkGo/model" "github.com/labstack/echo/v4" ) type ParamsEditComment struct { - ID string `mapstructure:"id" param:"required"` + // 查询值 + ID string `mapstructure:"id" param:"required"` + Site string `mapstructure:"site"` + SiteID uint + + // 可修改 Content string `mapstructure:"content"` PageKey string `mapstructure:"page_key"` Nick string `mapstructure:"nick"` @@ -35,7 +41,13 @@ func ActionManagerEditComment(c echo.Context) error { return RespError(c, "invalid id.") } - comment := FindComment(uint(id)) + // find site + p.SiteID = HandleSiteParam(p.Site) + if isOK, resp := CheckSite(c, p.SiteID); !isOK { + return resp + } + + comment := model.FindComment(uint(id), p.SiteID) if comment.IsEmpty() { return RespError(c, "comment not found.") } @@ -54,20 +66,20 @@ func ActionManagerEditComment(c echo.Context) error { // user if p.Nick != "" && p.Email != "" { - user := FindCreateUser(p.Nick, p.Email) + user := model.FindCreateUser(p.Nick, p.Email, p.SiteID) if user.ID != comment.UserID { comment.UserID = user.ID } } if p.Link != "" { comment.User.Link = p.Link - UpdateUser(&comment.User) + model.UpdateUser(&comment.User) } // pageKey if p.PageKey != "" { if p.PageKey != comment.PageKey { - FindCreatePage(p.PageKey, "", "") + model.FindCreatePage(p.PageKey, "", "", p.SiteID) comment.PageKey = p.PageKey } } @@ -102,7 +114,7 @@ func ActionManagerEditComment(c echo.Context) error { } } - if err := UpdateComment(&comment); err != nil { + if err := model.UpdateComment(&comment); err != nil { return RespError(c, "comment save error.") } diff --git a/http/api_man_edit_page.go b/http/api_man_edit_page.go index 81a345a8b..d427cc8ee 100644 --- a/http/api_man_edit_page.go +++ b/http/api_man_edit_page.go @@ -1,9 +1,17 @@ package http -import "github.com/labstack/echo/v4" +import ( + "github.com/ArtalkJS/ArtalkGo/model" + "github.com/labstack/echo/v4" +) type ParamsEditPage struct { - Key string `mapstructure:"key" param:"required"` + // 查询值 + Key string `mapstructure:"key" param:"required"` + Site string `mapstructure:"site"` + SiteID uint + + // 修改值 Url string `mapstructure:"url"` Title string `mapstructure:"title"` AdminOnly string `mapstructure:"admin_only"` @@ -19,7 +27,13 @@ func ActionManagerEditPage(c echo.Context) error { return resp } - page := FindPage(p.Key) + // find site + p.SiteID = HandleSiteParam(p.Site) + if isOK, resp := CheckSite(c, p.SiteID); !isOK { + return resp + } + + page := model.FindPage(p.Key, p.SiteID) if page.IsEmpty() { return RespError(c, "page not found.") } @@ -42,7 +56,7 @@ func ActionManagerEditPage(c echo.Context) error { page.AdminOnly = false } - if err := UpdatePage(&page); err != nil { + if err := model.UpdatePage(&page); err != nil { return RespError(c, "page save error.") } diff --git a/http/api_man_page_fetch.go b/http/api_man_page_fetch.go index dbcd5577b..5fd0dc27e 100644 --- a/http/api_man_page_fetch.go +++ b/http/api_man_page_fetch.go @@ -1,9 +1,14 @@ package http -import "github.com/labstack/echo/v4" +import ( + "github.com/ArtalkJS/ArtalkGo/model" + "github.com/labstack/echo/v4" +) type ParamsPageFetch struct { - Key string `mapstructure:"key" param:"required"` + Key string `mapstructure:"key" param:"required"` + Site string `mapstructure:"site"` + SiteID uint } func ActionManagerPageFetch(c echo.Context) error { @@ -16,7 +21,13 @@ func ActionManagerPageFetch(c echo.Context) error { return resp } - page := FindPage(p.Key) + // find site + p.SiteID = HandleSiteParam(p.Site) + if isOK, resp := CheckSite(c, p.SiteID); !isOK { + return resp + } + + page := model.FindPage(p.Key, p.SiteID) if page.IsEmpty() { return RespError(c, "page not found.") } diff --git a/http/api_user.go b/http/api_user.go index 4edca9940..ed78061de 100644 --- a/http/api_user.go +++ b/http/api_user.go @@ -7,8 +7,11 @@ import ( ) type ParamsUserGet struct { - Name string `mapstructure:"name"` - Email string `mapstructure:"email"` + Name string `mapstructure:"name" param:"required"` + Email string `mapstructure:"email" param:"required"` + + Site string `mapstructure:"site"` + SiteID uint } type ResponseUserGet struct { @@ -21,12 +24,18 @@ func ActionUserGet(c echo.Context) error { return resp } - if p.Name == "" && p.Email == "" { - return RespError(c, "Please input name or email.") + // find site + p.SiteID = HandleSiteParam(p.Site) + if isOK, resp := CheckSite(c, p.SiteID); !isOK { + return resp } var user model.User // 注:user 查找是 AND - lib.DB.Where("name = ? AND email = ?", p.Name, p.Email).First(&user) + lib.DB.Where(&model.User{ + Name: p.Name, + Email: p.Email, + SiteID: p.SiteID, + }).First(&user) isLogin := false tUser := GetUserByReqToken(c) diff --git a/http/api_login.go b/http/api_user_login.go similarity index 70% rename from http/api_login.go rename to http/api_user_login.go index 5f6620926..0c4c1097a 100644 --- a/http/api_login.go +++ b/http/api_user_login.go @@ -10,7 +10,9 @@ type ParamsLogin struct { Name string `mapstructure:"name" param:"required"` Email string `mapstructure:"email" param:"required"` Password string `mapstructure:"password" param:"required"` - Site string `mapstructure:"site"` + + Site string `mapstructure:"site"` + SiteID uint } func ActionLogin(c echo.Context) error { @@ -22,8 +24,18 @@ func ActionLogin(c echo.Context) error { // record action for limiting action RecordAction(c) + // find site + p.SiteID = HandleSiteParam(p.Site) + if isOK, resp := CheckSite(c, p.SiteID); !isOK { + return resp + } + var user model.User - lib.DB.Where("name = ? AND email = ? AND site = ?", p.Name, p.Email).First(&user) // name = ? OR email = ? + lib.DB.Where(&model.User{ + Name: p.Name, + Email: p.Email, + SiteID: p.SiteID, + }).First(&user) // name = ? OR email = ? if user.IsEmpty() || user.Password != p.Password { return RespError(c, "验证失败") } diff --git a/http/permission.go b/http/permission.go index effbe654b..1f12a3e00 100644 --- a/http/permission.go +++ b/http/permission.go @@ -23,9 +23,10 @@ var CommonJwtConfig middleware.JWTConfig // jwtCustomClaims are custom claims extending default ones. // See https://github.com/golang-jwt/jwt for more examples type jwtCustomClaims struct { - UserName string `json:"name"` - UserEmail string `json:"email"` - UserIsAdmin bool `json:"is_admin"` + Name string `json:"name"` + Email string `json:"email"` + Site uint `json:"site"` + IsAdmin bool `json:"is_admin"` jwt.StandardClaims } @@ -179,15 +180,16 @@ func GetUserByJwt(jwt *jwt.Token) model.User { tmp, _ := json.Marshal(jwt.Claims) _ = json.Unmarshal(tmp, &claims) - name := claims.UserName - email := claims.UserEmail + name := claims.Name + email := claims.Email + site := claims.Site - if !claims.UserIsAdmin { + if !claims.IsAdmin { return model.User{} } // check user from database - user := FindUser(name, email) + user := model.FindUser(name, email, site) return user } diff --git a/http/utils.go b/http/utils.go index d143729ad..cf43bba10 100644 --- a/http/utils.go +++ b/http/utils.go @@ -1,29 +1,26 @@ package http import ( - "net/mail" - "net/url" "reflect" "strconv" "strings" "time" "github.com/ArtalkJS/ArtalkGo/config" - "github.com/ArtalkJS/ArtalkGo/lib" "github.com/ArtalkJS/ArtalkGo/model" "github.com/golang-jwt/jwt" "github.com/labstack/echo/v4" "github.com/mitchellh/mapstructure" "github.com/sirupsen/logrus" - "gorm.io/gorm/clause" ) func LoginGetUserToken(user model.User) string { // Set custom claims claims := &jwtCustomClaims{ - UserName: user.Name, - UserEmail: user.Email, - UserIsAdmin: user.IsAdmin, + Name: user.Name, + Email: user.Email, + Site: user.SiteID, + IsAdmin: user.IsAdmin, StandardClaims: jwt.StandardClaims{ ExpiresAt: time.Now().Add(time.Second * time.Duration(config.Instance.LoginTimeout)).Unix(), // 过期时间 }, @@ -52,6 +49,10 @@ func ParamsDecode(c echo.Context, paramsStruct interface{}, destParams interface paramTagP := field.Tag.Get("param") paramMethod := strings.ToUpper(field.Tag.Get("method")) + if paramName == "" { + continue + } + // get param value paramVal := func() string { if paramMethod == "" { @@ -100,9 +101,9 @@ func ParamsDecode(c echo.Context, paramsStruct interface{}, destParams interface return true, nil } -func CheckIfAllowed(c echo.Context, name string, email string, page model.Page) (bool, error) { +func CheckIfAllowed(c echo.Context, name string, email string, page model.Page, siteID uint) (bool, error) { // 如果用户是管理员,或者当前页只能管理员评论 - if IsAdminUser(name, email) || page.AdminOnly { + if model.IsAdminUser(name, email, siteID) || page.AdminOnly { if !CheckIsAdminReq(c) { return false, RespError(c, "需要验证管理员身份", Map{"need_login": true}) } @@ -111,113 +112,25 @@ func CheckIfAllowed(c echo.Context, name string, email string, page model.Page) return true, nil } -func FindComment(id uint) model.Comment { - var comment model.Comment - lib.DB.Preload(clause.Associations).First(&comment, id) - return comment -} - -// 查找用户(返回:精确查找 AND) -func FindUser(name string, email string) model.User { - var user model.User // 注:user 查找是 AND - lib.DB.Where("name = ? AND email = ?", name, email).First(&user) - return user -} - -func IsAdminUser(name string, email string) bool { - var user model.User // 还是用 AND 吧,OR 太混乱了 - lib.DB.Where("(name = ? AND email = ?) AND is_admin = 1", name, email).First(&user) - return !user.IsEmpty() -} - -func UpdateComment(comment *model.Comment) error { - err := lib.DB.Save(comment).Error - if err != nil { - logrus.Error("Update Comment error: ", err) - } - return err -} - -func FindCreatePage(pageKey string, pageUrl string, pageTitle string) model.Page { - page := FindPage(pageKey) - if page.IsEmpty() { - page = NewPage(pageKey, pageUrl, pageTitle) - } - return page -} - -func FindCreateUser(name string, email string) model.User { - user := FindUser(name, email) - if user.IsEmpty() { - user = NewUser(name, email) // save a new user - } - return user -} - -func NewUser(name string, email string) model.User { - user := model.User{ - Name: name, - Email: email, - } - - err := lib.DB.Create(&user).Error - if err != nil { - logrus.Error("Save User error: ", err) - } - - return user -} - -func UpdateUser(user *model.User) error { - err := lib.DB.Save(user).Error - if err != nil { - logrus.Error("Update User error: ", err) +func CheckSite(c echo.Context, siteID uint) (bool, error) { + if siteID == 0 { + return true, nil } - return err -} - -func FindPage(key string) model.Page { - var page model.Page - lib.DB.Where(&model.Page{Key: key}).First(&page) - return page -} - -func FindPageByID(id uint) model.Page { - var page model.Page - lib.DB.Where("id = ?", id).First(&page) - return page -} - -func NewPage(key string, pageUrl string, pageTitle string) model.Page { - page := model.Page{ - Key: key, - Url: pageUrl, - Title: pageTitle, + site := model.FindSite(siteID) + if site.IsEmpty() { + return false, RespError(c, "site not found.") } - err := lib.DB.Create(&page).Error - if err != nil { - logrus.Error("Save Page error: ", err) - } - - return page + return true, nil } -func UpdatePage(page *model.Page) error { - err := lib.DB.Save(page).Error - if err != nil { - logrus.Error("Update Page error: ", err) +func HandleSiteParam(str string) uint { + site := 0 + if str != "" { + if v, err := strconv.Atoi(str); err == nil { + site = v + } } - return err -} - -func ValidateEmail(email string) bool { - _, err := mail.ParseAddress(email) - return err == nil -} - -func ValidateURL(urlStr string) bool { - _, err := url.ParseRequestURI(urlStr) - return err == nil + return uint(site) } diff --git a/lib/utils.go b/lib/utils.go index 101c52ec4..0e72cbe75 100644 --- a/lib/utils.go +++ b/lib/utils.go @@ -6,6 +6,7 @@ import ( "encoding/hex" "encoding/json" "errors" + "net/mail" "net/url" "os" @@ -104,3 +105,13 @@ func IsUrlValid(urlStr string) bool { _, err := url.ParseRequestURI(urlStr) return err != nil } + +func ValidateEmail(email string) bool { + _, err := mail.ParseAddress(email) + return err == nil +} + +func ValidateURL(urlStr string) bool { + _, err := url.ParseRequestURI(urlStr) + return err == nil +} diff --git a/model/query.go b/model/query.go new file mode 100644 index 000000000..fe529a847 --- /dev/null +++ b/model/query.go @@ -0,0 +1,116 @@ +package model + +import ( + "github.com/ArtalkJS/ArtalkGo/lib" + "github.com/sirupsen/logrus" + "gorm.io/gorm/clause" +) + +func FindComment(id uint, siteID uint) Comment { + var comment Comment + lib.DB.Preload(clause.Associations).Where("id = ? AND site_id = ?", id, siteID).First(&comment) + return comment +} + +// 查找用户(返回:精确查找 AND) +func FindUser(name string, email string, siteID uint) User { + var user User + lib.DB.Where(&User{Name: name, Email: email, SiteID: siteID}).First(&user) + return user +} + +func IsAdminUser(name string, email string, siteID uint) bool { + var user User + lib.DB.Where(&User{Name: name, Email: email, IsAdmin: true, SiteID: siteID}).First(&user) + return !user.IsEmpty() +} + +func UpdateComment(comment *Comment) error { + err := lib.DB.Save(comment).Error + if err != nil { + logrus.Error("Update Comment error: ", err) + } + return err +} + +func FindSite(id uint) Site { + var site Site + lib.DB.Where("id = ?", id).First(&site) + return site +} + +func FindCreatePage(pageKey string, pageUrl string, pageTitle string, siteID uint) Page { + page := FindPage(pageKey, siteID) + if page.IsEmpty() { + page = NewPage(pageKey, pageUrl, pageTitle, siteID) + } + return page +} + +func FindCreateUser(name string, email string, siteID uint) User { + user := FindUser(name, email, siteID) + if user.IsEmpty() { + user = NewUser(name, email, siteID) // save a new user + } + return user +} + +func NewUser(name string, email string, siteID uint) User { + user := User{ + Name: name, + Email: email, + SiteID: siteID, + } + + err := lib.DB.Create(&user).Error + if err != nil { + logrus.Error("Save User error: ", err) + } + + return user +} + +func UpdateUser(user *User) error { + err := lib.DB.Save(user).Error + if err != nil { + logrus.Error("Update User error: ", err) + } + + return err +} + +func FindPage(key string, siteID uint) Page { + var page Page + lib.DB.Where(&Page{Key: key, SiteID: siteID}).First(&page) + return page +} + +func FindPageByID(id uint, siteID uint) Page { + var page Page + lib.DB.Where("id = ? AND site_id = ?", id, siteID).First(&page) + return page +} + +func NewPage(key string, pageUrl string, pageTitle string, siteID uint) Page { + page := Page{ + Key: key, + Url: pageUrl, + Title: pageTitle, + SiteID: siteID, + } + + err := lib.DB.Create(&page).Error + if err != nil { + logrus.Error("Save Page error: ", err) + } + + return page +} + +func UpdatePage(page *Page) error { + err := lib.DB.Save(page).Error + if err != nil { + logrus.Error("Update Page error: ", err) + } + return err +} diff --git a/model/user.go b/model/user.go index 2c23bacbd..0e901b030 100644 --- a/model/user.go +++ b/model/user.go @@ -18,6 +18,9 @@ type User struct { SiteID uint `gorm:"index"` Site Site `gorm:"foreignKey:SiteID;references:ID"` + + // 配置文件中添加的 + IsInConf bool } func (u User) IsEmpty() bool { From 38e98915b73a239a185f29f40d466a59bf03aa79 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Mon, 27 Sep 2021 17:10:05 +0800 Subject: [PATCH 028/349] Remove site isolation of user model. --- artalk-go.example.yml | 1 - cmd/root.go | 4 +--- config/config.go | 1 - http/api_main_add.go | 5 ++--- http/api_main_get.go | 5 ++--- http/api_man_del_comment.go | 3 +-- http/api_man_edit_comment.go | 5 ++--- http/api_man_edit_page.go | 3 +-- http/api_man_page_fetch.go | 3 +-- http/api_user.go | 14 ++------------ http/api_user_login.go | 14 ++------------ http/permission.go | 4 +--- http/utils.go | 23 +++++++---------------- model/query.go | 25 ++++++++++++------------- model/site.go | 19 ++++++++----------- model/user.go | 5 ----- 16 files changed, 42 insertions(+), 92 deletions(-) diff --git a/artalk-go.example.yml b/artalk-go.example.yml index fa015c5b2..e8f32a303 100644 --- a/artalk-go.example.yml +++ b/artalk-go.example.yml @@ -32,7 +32,6 @@ admin_users: password: '' badge_name: '管理员' badge_color: '#FF6C00' - site_id: 0 # 登录超时 (单位:秒) login_timeout: 259200 diff --git a/cmd/root.go b/cmd/root.go index a2e409cfd..974c0784b 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -123,7 +123,7 @@ func initDB() { func syncConfWithDB() { // 导入配置文件的管理员用户 for _, admin := range config.Instance.AdminUsers { - user := model.FindUser(admin.Name, admin.Email, admin.SiteID) + user := model.FindUser(admin.Name, admin.Email) if user.IsEmpty() { // create user = model.User{ @@ -133,7 +133,6 @@ func syncConfWithDB() { Password: admin.Password, BadgeName: admin.BadgeName, BadgeColor: admin.BadgeColor, - SiteID: admin.SiteID, IsAdmin: true, IsInConf: true, } @@ -144,7 +143,6 @@ func syncConfWithDB() { user.Password = admin.Password user.BadgeName = admin.BadgeName user.BadgeColor = admin.BadgeColor - user.SiteID = admin.SiteID user.IsAdmin = true user.IsInConf = true lib.DB.Save(&user) diff --git a/config/config.go b/config/config.go index d3d74f187..946e529c7 100644 --- a/config/config.go +++ b/config/config.go @@ -49,7 +49,6 @@ type AdminUserConf struct { Password string `mapstructure:"password"` BadgeName string `mapstructure:"badge_name"` BadgeColor string `mapstructure:"badge_color"` - SiteID uint `mapstructure:"site_id"` } type ModeratorConf struct { diff --git a/http/api_main_add.go b/http/api_main_add.go index e65aa5846..2d5789282 100644 --- a/http/api_main_add.go +++ b/http/api_main_add.go @@ -49,8 +49,7 @@ func ActionAdd(c echo.Context) error { RecordAction(c) // find site - p.SiteID = HandleSiteParam(p.Site) - if isOK, resp := CheckSite(c, p.SiteID); !isOK { + if isOK, resp := CheckSite(c, p.Site, &p.SiteID); !isOK { return resp } @@ -63,7 +62,7 @@ func ActionAdd(c echo.Context) error { } // find user - user := model.FindCreateUser(p.Name, p.Email, p.SiteID) + user := model.FindCreateUser(p.Name, p.Email) if user.ID == 0 || page.Key == "" { logrus.Error("Cannot get user or page.") return RespError(c, "评论失败") diff --git a/http/api_main_get.go b/http/api_main_get.go index ba8b032f1..cd7d87fa5 100644 --- a/http/api_main_get.go +++ b/http/api_main_get.go @@ -36,8 +36,7 @@ func ActionGet(c echo.Context) error { isMsgCenter := IsMsgCenter(p) // find site - p.SiteID = HandleSiteParam(p.Site) - if isOK, resp := CheckSite(c, p.SiteID); !isOK { + if isOK, resp := CheckSite(c, p.Site, &p.SiteID); !isOK { return resp } @@ -126,7 +125,7 @@ func IsMsgCenter(p ParamsGet) bool { func MsgCenter(c echo.Context, p ParamsGet, siteID uint) func(db *gorm.DB) *gorm.DB { return func(db *gorm.DB) *gorm.DB { - user := model.FindUser(p.Name, p.Email, siteID) + user := model.FindUser(p.Name, p.Email) myCommentIDs := []int{} if p.Type == "all" || p.Type == "mentions" { diff --git a/http/api_man_del_comment.go b/http/api_man_del_comment.go index 69107bf7d..f5786b78c 100644 --- a/http/api_man_del_comment.go +++ b/http/api_man_del_comment.go @@ -32,8 +32,7 @@ func ActionManagerDelComment(c echo.Context) error { } // find site - p.SiteID = HandleSiteParam(p.Site) - if isOK, resp := CheckSite(c, p.SiteID); !isOK { + if isOK, resp := CheckSite(c, p.Site, &p.SiteID); !isOK { return resp } diff --git a/http/api_man_edit_comment.go b/http/api_man_edit_comment.go index 7228a828b..d58e489da 100644 --- a/http/api_man_edit_comment.go +++ b/http/api_man_edit_comment.go @@ -42,8 +42,7 @@ func ActionManagerEditComment(c echo.Context) error { } // find site - p.SiteID = HandleSiteParam(p.Site) - if isOK, resp := CheckSite(c, p.SiteID); !isOK { + if isOK, resp := CheckSite(c, p.Site, &p.SiteID); !isOK { return resp } @@ -66,7 +65,7 @@ func ActionManagerEditComment(c echo.Context) error { // user if p.Nick != "" && p.Email != "" { - user := model.FindCreateUser(p.Nick, p.Email, p.SiteID) + user := model.FindCreateUser(p.Nick, p.Email) if user.ID != comment.UserID { comment.UserID = user.ID } diff --git a/http/api_man_edit_page.go b/http/api_man_edit_page.go index d427cc8ee..90baa8f9b 100644 --- a/http/api_man_edit_page.go +++ b/http/api_man_edit_page.go @@ -28,8 +28,7 @@ func ActionManagerEditPage(c echo.Context) error { } // find site - p.SiteID = HandleSiteParam(p.Site) - if isOK, resp := CheckSite(c, p.SiteID); !isOK { + if isOK, resp := CheckSite(c, p.Site, &p.SiteID); !isOK { return resp } diff --git a/http/api_man_page_fetch.go b/http/api_man_page_fetch.go index 5fd0dc27e..2807b87ad 100644 --- a/http/api_man_page_fetch.go +++ b/http/api_man_page_fetch.go @@ -22,8 +22,7 @@ func ActionManagerPageFetch(c echo.Context) error { } // find site - p.SiteID = HandleSiteParam(p.Site) - if isOK, resp := CheckSite(c, p.SiteID); !isOK { + if isOK, resp := CheckSite(c, p.Site, &p.SiteID); !isOK { return resp } diff --git a/http/api_user.go b/http/api_user.go index ed78061de..74b5be964 100644 --- a/http/api_user.go +++ b/http/api_user.go @@ -9,9 +9,6 @@ import ( type ParamsUserGet struct { Name string `mapstructure:"name" param:"required"` Email string `mapstructure:"email" param:"required"` - - Site string `mapstructure:"site"` - SiteID uint } type ResponseUserGet struct { @@ -24,17 +21,10 @@ func ActionUserGet(c echo.Context) error { return resp } - // find site - p.SiteID = HandleSiteParam(p.Site) - if isOK, resp := CheckSite(c, p.SiteID); !isOK { - return resp - } - var user model.User // 注:user 查找是 AND lib.DB.Where(&model.User{ - Name: p.Name, - Email: p.Email, - SiteID: p.SiteID, + Name: p.Name, + Email: p.Email, }).First(&user) isLogin := false diff --git a/http/api_user_login.go b/http/api_user_login.go index 0c4c1097a..23c9e576f 100644 --- a/http/api_user_login.go +++ b/http/api_user_login.go @@ -10,9 +10,6 @@ type ParamsLogin struct { Name string `mapstructure:"name" param:"required"` Email string `mapstructure:"email" param:"required"` Password string `mapstructure:"password" param:"required"` - - Site string `mapstructure:"site"` - SiteID uint } func ActionLogin(c echo.Context) error { @@ -24,17 +21,10 @@ func ActionLogin(c echo.Context) error { // record action for limiting action RecordAction(c) - // find site - p.SiteID = HandleSiteParam(p.Site) - if isOK, resp := CheckSite(c, p.SiteID); !isOK { - return resp - } - var user model.User lib.DB.Where(&model.User{ - Name: p.Name, - Email: p.Email, - SiteID: p.SiteID, + Name: p.Name, + Email: p.Email, }).First(&user) // name = ? OR email = ? if user.IsEmpty() || user.Password != p.Password { return RespError(c, "验证失败") diff --git a/http/permission.go b/http/permission.go index 1f12a3e00..50e92c141 100644 --- a/http/permission.go +++ b/http/permission.go @@ -25,7 +25,6 @@ var CommonJwtConfig middleware.JWTConfig type jwtCustomClaims struct { Name string `json:"name"` Email string `json:"email"` - Site uint `json:"site"` IsAdmin bool `json:"is_admin"` jwt.StandardClaims } @@ -182,14 +181,13 @@ func GetUserByJwt(jwt *jwt.Token) model.User { name := claims.Name email := claims.Email - site := claims.Site if !claims.IsAdmin { return model.User{} } // check user from database - user := model.FindUser(name, email, site) + user := model.FindUser(name, email) return user } diff --git a/http/utils.go b/http/utils.go index cf43bba10..862da8f14 100644 --- a/http/utils.go +++ b/http/utils.go @@ -19,7 +19,6 @@ func LoginGetUserToken(user model.User) string { claims := &jwtCustomClaims{ Name: user.Name, Email: user.Email, - Site: user.SiteID, IsAdmin: user.IsAdmin, StandardClaims: jwt.StandardClaims{ ExpiresAt: time.Now().Add(time.Second * time.Duration(config.Instance.LoginTimeout)).Unix(), // 过期时间 @@ -103,7 +102,7 @@ func ParamsDecode(c echo.Context, paramsStruct interface{}, destParams interface func CheckIfAllowed(c echo.Context, name string, email string, page model.Page, siteID uint) (bool, error) { // 如果用户是管理员,或者当前页只能管理员评论 - if model.IsAdminUser(name, email, siteID) || page.AdminOnly { + if model.IsAdminUser(name, email) || page.AdminOnly { if !CheckIsAdminReq(c) { return false, RespError(c, "需要验证管理员身份", Map{"need_login": true}) } @@ -112,25 +111,17 @@ func CheckIfAllowed(c echo.Context, name string, email string, page model.Page, return true, nil } -func CheckSite(c echo.Context, siteID uint) (bool, error) { - if siteID == 0 { +func CheckSite(c echo.Context, siteName string, destID *uint) (bool, error) { + if siteName == "" { return true, nil } - site := model.FindSite(siteID) + site := model.FindSite(siteName) if site.IsEmpty() { - return false, RespError(c, "site not found.") + return false, RespError(c, "Site not found") } - return true, nil -} + *destID = site.ID -func HandleSiteParam(str string) uint { - site := 0 - if str != "" { - if v, err := strconv.Atoi(str); err == nil { - site = v - } - } - return uint(site) + return true, nil } diff --git a/model/query.go b/model/query.go index fe529a847..b9b3b966a 100644 --- a/model/query.go +++ b/model/query.go @@ -13,15 +13,15 @@ func FindComment(id uint, siteID uint) Comment { } // 查找用户(返回:精确查找 AND) -func FindUser(name string, email string, siteID uint) User { +func FindUser(name string, email string) User { var user User - lib.DB.Where(&User{Name: name, Email: email, SiteID: siteID}).First(&user) + lib.DB.Where(&User{Name: name, Email: email}).First(&user) return user } -func IsAdminUser(name string, email string, siteID uint) bool { +func IsAdminUser(name string, email string) bool { var user User - lib.DB.Where(&User{Name: name, Email: email, IsAdmin: true, SiteID: siteID}).First(&user) + lib.DB.Where(&User{Name: name, Email: email, IsAdmin: true}).First(&user) return !user.IsEmpty() } @@ -33,9 +33,9 @@ func UpdateComment(comment *Comment) error { return err } -func FindSite(id uint) Site { +func FindSite(name string) Site { var site Site - lib.DB.Where("id = ?", id).First(&site) + lib.DB.Where(&Site{Name: name}).First(&site) return site } @@ -47,19 +47,18 @@ func FindCreatePage(pageKey string, pageUrl string, pageTitle string, siteID uin return page } -func FindCreateUser(name string, email string, siteID uint) User { - user := FindUser(name, email, siteID) +func FindCreateUser(name string, email string) User { + user := FindUser(name, email) if user.IsEmpty() { - user = NewUser(name, email, siteID) // save a new user + user = NewUser(name, email) // save a new user } return user } -func NewUser(name string, email string, siteID uint) User { +func NewUser(name string, email string) User { user := User{ - Name: name, - Email: email, - SiteID: siteID, + Name: name, + Email: email, } err := lib.DB.Create(&user).Error diff --git a/model/site.go b/model/site.go index 80f38b6d0..183ce5bd2 100644 --- a/model/site.go +++ b/model/site.go @@ -6,9 +6,8 @@ import ( type Site struct { gorm.Model - Name string - Url string - UserID uint + Name string `gorm:"uniqueIndex"` + Url string } func (s Site) IsEmpty() bool { @@ -16,17 +15,15 @@ func (s Site) IsEmpty() bool { } type CookedSite struct { - ID uint `json:"id"` - Name string `json:"name"` - Url string `json:"url"` - UserID uint `json:"user_id"` + ID uint `json:"id"` + Name string `json:"name"` + Url string `json:"url"` } func (s Site) ToCooked() CookedSite { return CookedSite{ - ID: s.ID, - Name: s.Name, - Url: s.Url, - UserID: s.UserID, + ID: s.ID, + Name: s.Name, + Url: s.Url, } } diff --git a/model/user.go b/model/user.go index 0e901b030..9dbf4c947 100644 --- a/model/user.go +++ b/model/user.go @@ -16,9 +16,6 @@ type User struct { LastUA string IsAdmin bool - SiteID uint `gorm:"index"` - Site Site `gorm:"foreignKey:SiteID;references:ID"` - // 配置文件中添加的 IsInConf bool } @@ -35,7 +32,6 @@ type CookedUser struct { BadgeName string `json:"badge_name"` BadgeColor string `json:"badge_color"` IsAdmin bool `json:"is_admin"` - SiteID uint `json:"site_id"` } func (u User) ToCooked() CookedUser { @@ -47,6 +43,5 @@ func (u User) ToCooked() CookedUser { BadgeName: u.BadgeName, BadgeColor: u.BadgeColor, IsAdmin: u.IsAdmin, - SiteID: u.SiteID, } } From bc2b672b9b2de034b9a3d6de28a7a010e8b1aa18 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Mon, 27 Sep 2021 18:49:09 +0800 Subject: [PATCH 029/349] Rename param site to site_name & rename manager to admin. --- http/a_http.go | 14 +++++----- http/{api_manager.go => api_admin.go} | 0 ...el_comment.go => api_admin_del_comment.go} | 10 +++---- ...t_comment.go => api_admin_edit_comment.go} | 14 +++++----- ...an_edit_page.go => api_admin_edit_page.go} | 12 ++++---- ..._page_fetch.go => api_admin_page_fetch.go} | 12 ++++---- ...an_send_mail.go => api_admin_send_mail.go} | 2 +- http/api_main_add.go | 16 +++++------ http/api_main_get.go | 10 +++---- http/{api_user.go => api_user_get.go} | 0 http/utils.go | 2 +- model/comment.go | 16 +++++++---- model/page.go | 8 +++--- model/query.go | 28 +++++++++---------- 14 files changed, 74 insertions(+), 70 deletions(-) rename http/{api_manager.go => api_admin.go} (100%) rename http/{api_man_del_comment.go => api_admin_del_comment.go} (82%) rename http/{api_man_edit_comment.go => api_admin_edit_comment.go} (86%) rename http/{api_man_edit_page.go => api_admin_edit_page.go} (77%) rename http/{api_man_page_fetch.go => api_admin_page_fetch.go} (67%) rename http/{api_man_send_mail.go => api_admin_send_mail.go} (91%) rename http/{api_user.go => api_user_get.go} (100%) diff --git a/http/a_http.go b/http/a_http.go index 1f1770499..99917db04 100644 --- a/http/a_http.go +++ b/http/a_http.go @@ -87,11 +87,11 @@ func InitRoute(e *echo.Echo) { ca.GET("/refresh", ActionCaptchaGet) ca.GET("/check", ActionCaptchaCheck) - // api/manager - manager := api.Group("/manager", middleware.JWTWithConfig(CommonJwtConfig)) // use jwt - manager.POST("/edit-page", ActionManagerEditPage) - manager.POST("/edit-comment", ActionManagerEditComment) - manager.POST("/del-comment", ActionManagerDelComment) - manager.POST("/page-fetch", ActionManagerPageFetch) - manager.POST("/send-mail", ActionManagerSendMail) + // api/admin + admin := api.Group("/admin", middleware.JWTWithConfig(CommonJwtConfig)) // use jwt + admin.POST("/edit-page", ActionAdminEditPage) + admin.POST("/edit-comment", ActionAdminEditComment) + admin.POST("/del-comment", ActionAdminDelComment) + admin.POST("/page-fetch", ActionAdminPageFetch) + admin.POST("/send-mail", ActionAdminSendMail) } diff --git a/http/api_manager.go b/http/api_admin.go similarity index 100% rename from http/api_manager.go rename to http/api_admin.go diff --git a/http/api_man_del_comment.go b/http/api_admin_del_comment.go similarity index 82% rename from http/api_man_del_comment.go rename to http/api_admin_del_comment.go index f5786b78c..8f1a584fc 100644 --- a/http/api_man_del_comment.go +++ b/http/api_admin_del_comment.go @@ -12,11 +12,11 @@ import ( type ParamsDelComment struct { ID string `mapstructure:"id" param:"required"` - Site string `mapstructure:"id"` - SiteID uint + SiteName string `mapstructure:"site_name"` + SiteID uint } -func ActionManagerDelComment(c echo.Context) error { +func ActionAdminDelComment(c echo.Context) error { if isOK, resp := AdminOnly(c); !isOK { return resp } @@ -32,11 +32,11 @@ func ActionManagerDelComment(c echo.Context) error { } // find site - if isOK, resp := CheckSite(c, p.Site, &p.SiteID); !isOK { + if isOK, resp := CheckSite(c, p.SiteName, &p.SiteID); !isOK { return resp } - comment := model.FindComment(uint(id), p.SiteID) + comment := model.FindComment(uint(id), p.SiteName) if comment.IsEmpty() { return RespError(c, "comment not found.") } diff --git a/http/api_man_edit_comment.go b/http/api_admin_edit_comment.go similarity index 86% rename from http/api_man_edit_comment.go rename to http/api_admin_edit_comment.go index d58e489da..a4130eb78 100644 --- a/http/api_man_edit_comment.go +++ b/http/api_admin_edit_comment.go @@ -9,9 +9,9 @@ import ( type ParamsEditComment struct { // 查询值 - ID string `mapstructure:"id" param:"required"` - Site string `mapstructure:"site"` - SiteID uint + ID string `mapstructure:"id" param:"required"` + SiteName string `mapstructure:"site_name"` + SiteID uint // 可修改 Content string `mapstructure:"content"` @@ -26,7 +26,7 @@ type ParamsEditComment struct { IsPending string `mapstructure:"is_pending"` } -func ActionManagerEditComment(c echo.Context) error { +func ActionAdminEditComment(c echo.Context) error { if isOK, resp := AdminOnly(c); !isOK { return resp } @@ -42,11 +42,11 @@ func ActionManagerEditComment(c echo.Context) error { } // find site - if isOK, resp := CheckSite(c, p.Site, &p.SiteID); !isOK { + if isOK, resp := CheckSite(c, p.SiteName, &p.SiteID); !isOK { return resp } - comment := model.FindComment(uint(id), p.SiteID) + comment := model.FindComment(uint(id), p.SiteName) if comment.IsEmpty() { return RespError(c, "comment not found.") } @@ -78,7 +78,7 @@ func ActionManagerEditComment(c echo.Context) error { // pageKey if p.PageKey != "" { if p.PageKey != comment.PageKey { - model.FindCreatePage(p.PageKey, "", "", p.SiteID) + model.FindCreatePage(p.PageKey, "", "", p.SiteName) comment.PageKey = p.PageKey } } diff --git a/http/api_man_edit_page.go b/http/api_admin_edit_page.go similarity index 77% rename from http/api_man_edit_page.go rename to http/api_admin_edit_page.go index 90baa8f9b..d6a83d717 100644 --- a/http/api_man_edit_page.go +++ b/http/api_admin_edit_page.go @@ -7,9 +7,9 @@ import ( type ParamsEditPage struct { // 查询值 - Key string `mapstructure:"key" param:"required"` - Site string `mapstructure:"site"` - SiteID uint + Key string `mapstructure:"key" param:"required"` + SiteName string `mapstructure:"site_name"` + SiteID uint // 修改值 Url string `mapstructure:"url"` @@ -17,7 +17,7 @@ type ParamsEditPage struct { AdminOnly string `mapstructure:"admin_only"` } -func ActionManagerEditPage(c echo.Context) error { +func ActionAdminEditPage(c echo.Context) error { if isOK, resp := AdminOnly(c); !isOK { return resp } @@ -28,11 +28,11 @@ func ActionManagerEditPage(c echo.Context) error { } // find site - if isOK, resp := CheckSite(c, p.Site, &p.SiteID); !isOK { + if isOK, resp := CheckSite(c, p.SiteName, &p.SiteID); !isOK { return resp } - page := model.FindPage(p.Key, p.SiteID) + page := model.FindPage(p.Key, p.SiteName) if page.IsEmpty() { return RespError(c, "page not found.") } diff --git a/http/api_man_page_fetch.go b/http/api_admin_page_fetch.go similarity index 67% rename from http/api_man_page_fetch.go rename to http/api_admin_page_fetch.go index 2807b87ad..32a27f764 100644 --- a/http/api_man_page_fetch.go +++ b/http/api_admin_page_fetch.go @@ -6,12 +6,12 @@ import ( ) type ParamsPageFetch struct { - Key string `mapstructure:"key" param:"required"` - Site string `mapstructure:"site"` - SiteID uint + Key string `mapstructure:"key" param:"required"` + SiteName string `mapstructure:"site_name"` + SiteID uint } -func ActionManagerPageFetch(c echo.Context) error { +func ActionAdminPageFetch(c echo.Context) error { if isOK, resp := AdminOnly(c); !isOK { return resp } @@ -22,11 +22,11 @@ func ActionManagerPageFetch(c echo.Context) error { } // find site - if isOK, resp := CheckSite(c, p.Site, &p.SiteID); !isOK { + if isOK, resp := CheckSite(c, p.SiteName, &p.SiteID); !isOK { return resp } - page := model.FindPage(p.Key, p.SiteID) + page := model.FindPage(p.Key, p.SiteName) if page.IsEmpty() { return RespError(c, "page not found.") } diff --git a/http/api_man_send_mail.go b/http/api_admin_send_mail.go similarity index 91% rename from http/api_man_send_mail.go rename to http/api_admin_send_mail.go index 02ecdc73a..3711392ad 100644 --- a/http/api_man_send_mail.go +++ b/http/api_admin_send_mail.go @@ -11,7 +11,7 @@ type ParamsSendMail struct { ToAddr string `mapstructure:"to_addr" param:"required"` } -func ActionManagerSendMail(c echo.Context) error { +func ActionAdminSendMail(c echo.Context) error { if isOK, resp := AdminOnly(c); !isOK { return resp } diff --git a/http/api_main_add.go b/http/api_main_add.go index 2d5789282..c2dd47119 100644 --- a/http/api_main_add.go +++ b/http/api_main_add.go @@ -20,9 +20,9 @@ type ParamsAdd struct { PageUrl string `mapstructure:"page_url"` PageTitle string `mapstructure:"page_title"` - Token string `mapstructure:"token"` - Site string `mapstructure:"site"` - SiteID uint + Token string `mapstructure:"token"` + SiteName string `mapstructure:"site_name"` + SiteID uint } type ResponseAdd struct { @@ -49,15 +49,15 @@ func ActionAdd(c echo.Context) error { RecordAction(c) // find site - if isOK, resp := CheckSite(c, p.Site, &p.SiteID); !isOK { + if isOK, resp := CheckSite(c, p.SiteName, &p.SiteID); !isOK { return resp } // find page - page := model.FindCreatePage(p.PageKey, p.PageUrl, p.PageTitle, p.SiteID) + page := model.FindCreatePage(p.PageKey, p.PageUrl, p.PageTitle, p.SiteName) // check if the user is allowed to comment - if isAllowed, resp := CheckIfAllowed(c, p.Name, p.Email, page, p.SiteID); !isAllowed { + if isAllowed, resp := CheckIfAllowed(c, p.Name, p.Email, page); !isAllowed { return resp } @@ -71,7 +71,7 @@ func ActionAdd(c echo.Context) error { // check reply comment var parentComment model.Comment if p.Rid != 0 { - parentComment = model.FindComment(p.Rid, p.SiteID) + parentComment = model.FindComment(p.Rid, p.SiteName) if parentComment.IsEmpty() { return RespError(c, "找不到父评论") } @@ -92,7 +92,7 @@ func ActionAdd(c echo.Context) error { UA: ua, IsPending: false, IsCollapsed: false, - SiteID: p.SiteID, + SiteName: p.SiteName, } // default comment type diff --git a/http/api_main_get.go b/http/api_main_get.go index cd7d87fa5..8a82689b6 100644 --- a/http/api_main_get.go +++ b/http/api_main_get.go @@ -17,8 +17,8 @@ type ParamsGet struct { Email string `mapstructure:"email"` Type string `mapstructure:"type"` - Site string `mapstructure:"site"` - SiteID uint + SiteName string `mapstructure:"site_name"` + SiteID uint } type ResponseGet struct { @@ -36,12 +36,12 @@ func ActionGet(c echo.Context) error { isMsgCenter := IsMsgCenter(p) // find site - if isOK, resp := CheckSite(c, p.Site, &p.SiteID); !isOK { + if isOK, resp := CheckSite(c, p.SiteName, &p.SiteID); !isOK { return resp } // find page - page := model.FindPage(p.PageKey, p.SiteID) + page := model.FindPage(p.PageKey, p.SiteName) // comment parents var comments []model.Comment @@ -87,7 +87,7 @@ func ActionGet(c echo.Context) error { continue } - rComment := model.FindComment(c.Rid, p.SiteID) // 查找被回复的评论 + rComment := model.FindComment(c.Rid, p.SiteName) // 查找被回复的评论 if rComment.IsEmpty() { continue } diff --git a/http/api_user.go b/http/api_user_get.go similarity index 100% rename from http/api_user.go rename to http/api_user_get.go diff --git a/http/utils.go b/http/utils.go index 862da8f14..fba206d24 100644 --- a/http/utils.go +++ b/http/utils.go @@ -100,7 +100,7 @@ func ParamsDecode(c echo.Context, paramsStruct interface{}, destParams interface return true, nil } -func CheckIfAllowed(c echo.Context, name string, email string, page model.Page, siteID uint) (bool, error) { +func CheckIfAllowed(c echo.Context, name string, email string, page model.Page) (bool, error) { // 如果用户是管理员,或者当前页只能管理员评论 if model.IsAdminUser(name, email) || page.AdminOnly { if !CheckIsAdminReq(c) { diff --git a/model/comment.go b/model/comment.go index f82ffc824..fa77a1afd 100644 --- a/model/comment.go +++ b/model/comment.go @@ -11,12 +11,12 @@ type Comment struct { gorm.Model Content string - UserID uint `gorm:"index"` - PageKey string `gorm:"index"` - SiteID uint `gorm:"index"` - User User `gorm:"foreignKey:UserID;references:ID"` - Page Page `gorm:"foreignKey:PageKey;references:Key"` - Site Site `gorm:"foreignKey:SiteID;references:ID"` + UserID uint `gorm:"index"` + PageKey string `gorm:"index"` + SiteName string `gorm:"index"` + User User `gorm:"foreignKey:UserID;references:ID"` + Page Page `gorm:"foreignKey:PageKey;references:Key"` + Site Site `gorm:"foreignKey:SiteName;references:Name"` Rid uint `gorm:"index"` UA string @@ -89,6 +89,7 @@ type CookedComment struct { Rid uint `json:"rid"` PageKey string `json:"page_key"` Visible bool `json:"visible"` + SiteName string `json:"site_name"` } func (c Comment) ToCooked() CookedComment { @@ -109,6 +110,7 @@ func (c Comment) ToCooked() CookedComment { Rid: c.Rid, PageKey: c.PageKey, Visible: true, + SiteName: c.SiteName, } } @@ -129,6 +131,7 @@ type CookedCommentForEmail struct { IsAllowReply bool `json:"is_allow_reply"` Rid uint `json:"rid"` PageKey string `json:"page_key"` + SiteName string `json:"site_name"` } func (c Comment) ToCookedForEmail() CookedCommentForEmail { @@ -152,5 +155,6 @@ func (c Comment) ToCookedForEmail() CookedCommentForEmail { IsAllowReply: c.IsAllowReply(), Rid: c.Rid, PageKey: c.PageKey, + SiteName: c.SiteName, } } diff --git a/model/page.go b/model/page.go index fc2315cdf..05cbc4086 100644 --- a/model/page.go +++ b/model/page.go @@ -17,8 +17,8 @@ type Page struct { Url string AdminOnly bool - SiteID uint `gorm:"index"` - Site Site `gorm:"foreignKey:SiteID;references:ID"` + SiteName string `gorm:"index"` + Site Site `gorm:"foreignKey:SiteName;references:Name"` } func (p Page) IsEmpty() bool { @@ -31,7 +31,7 @@ type CookedPage struct { Key string `json:"key"` URL string `json:"url"` Title string `json:"title"` - SiteID uint `json:"site_id"` + SiteName string `json:"site_name"` } func (p Page) ToCooked() CookedPage { @@ -41,7 +41,7 @@ func (p Page) ToCooked() CookedPage { Key: p.Key, URL: p.Url, Title: p.Title, - SiteID: p.SiteID, + SiteName: p.SiteName, } } diff --git a/model/query.go b/model/query.go index b9b3b966a..ae2669e30 100644 --- a/model/query.go +++ b/model/query.go @@ -6,9 +6,9 @@ import ( "gorm.io/gorm/clause" ) -func FindComment(id uint, siteID uint) Comment { +func FindComment(id uint, siteName string) Comment { var comment Comment - lib.DB.Preload(clause.Associations).Where("id = ? AND site_id = ?", id, siteID).First(&comment) + lib.DB.Preload(clause.Associations).Where("id = ? AND site_name = ?", id, siteName).First(&comment) return comment } @@ -39,10 +39,10 @@ func FindSite(name string) Site { return site } -func FindCreatePage(pageKey string, pageUrl string, pageTitle string, siteID uint) Page { - page := FindPage(pageKey, siteID) +func FindCreatePage(pageKey string, pageUrl string, pageTitle string, siteName string) Page { + page := FindPage(pageKey, siteName) if page.IsEmpty() { - page = NewPage(pageKey, pageUrl, pageTitle, siteID) + page = NewPage(pageKey, pageUrl, pageTitle, siteName) } return page } @@ -78,24 +78,24 @@ func UpdateUser(user *User) error { return err } -func FindPage(key string, siteID uint) Page { +func FindPage(key string, siteName string) Page { var page Page - lib.DB.Where(&Page{Key: key, SiteID: siteID}).First(&page) + lib.DB.Where(&Page{Key: key, SiteName: siteName}).First(&page) return page } -func FindPageByID(id uint, siteID uint) Page { +func FindPageByID(id uint, siteName string) Page { var page Page - lib.DB.Where("id = ? AND site_id = ?", id, siteID).First(&page) + lib.DB.Where("id = ? AND site_name = ?", id, siteName).First(&page) return page } -func NewPage(key string, pageUrl string, pageTitle string, siteID uint) Page { +func NewPage(key string, pageUrl string, pageTitle string, siteName string) Page { page := Page{ - Key: key, - Url: pageUrl, - Title: pageTitle, - SiteID: siteID, + Key: key, + Url: pageUrl, + Title: pageTitle, + SiteName: siteName, } err := lib.DB.Create(&page).Error From 7af6628d3880ed7f11e2b7ca6683a90c52e866f6 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Tue, 28 Sep 2021 19:15:10 +0800 Subject: [PATCH 030/349] Cross origin action control & rename some apis. --- http/a_http.go | 9 ++- ...el_comment.go => api_admin_comment_del.go} | 8 +-- ...t_comment.go => api_admin_comment_edit.go} | 8 +-- http/api_admin_page_del.go | 51 +++++++++++++++ ...in_edit_page.go => api_admin_page_edit.go} | 8 +-- http/api_admin_page_fetch.go | 6 +- http/api_admin_send_mail.go | 6 +- http/api_admin_site_add.go | 37 +++++++++++ http/api_admin_site_del.go | 53 +++++++++++++++ http/api_admin_site_edit.go | 64 +++++++++++++++++++ http/api_main_add.go | 2 +- http/api_user_get.go | 23 +++---- http/utils.go | 56 +++++++++++++++- model/query.go | 6 ++ 14 files changed, 301 insertions(+), 36 deletions(-) rename http/{api_admin_del_comment.go => api_admin_comment_del.go} (86%) rename http/{api_admin_edit_comment.go => api_admin_comment_edit.go} (92%) create mode 100644 http/api_admin_page_del.go rename http/{api_admin_edit_page.go => api_admin_page_edit.go} (84%) create mode 100644 http/api_admin_site_add.go create mode 100644 http/api_admin_site_del.go create mode 100644 http/api_admin_site_edit.go diff --git a/http/a_http.go b/http/a_http.go index 99917db04..684cf6a8e 100644 --- a/http/a_http.go +++ b/http/a_http.go @@ -89,9 +89,12 @@ func InitRoute(e *echo.Echo) { // api/admin admin := api.Group("/admin", middleware.JWTWithConfig(CommonJwtConfig)) // use jwt - admin.POST("/edit-page", ActionAdminEditPage) - admin.POST("/edit-comment", ActionAdminEditComment) - admin.POST("/del-comment", ActionAdminDelComment) + admin.POST("/page-edit", ActionAdminPageEdit) + admin.POST("/page-del", ActionAdminPageDel) + admin.POST("/comment-edit", ActionAdminCommentEdit) + admin.POST("/comment-del", ActionAdminCommentDel) admin.POST("/page-fetch", ActionAdminPageFetch) admin.POST("/send-mail", ActionAdminSendMail) + admin.POST("/site-add", ActionAdminSiteAdd) + admin.POST("/site-del", ActionAdminSiteDel) } diff --git a/http/api_admin_del_comment.go b/http/api_admin_comment_del.go similarity index 86% rename from http/api_admin_del_comment.go rename to http/api_admin_comment_del.go index 8f1a584fc..df4cbf6d6 100644 --- a/http/api_admin_del_comment.go +++ b/http/api_admin_comment_del.go @@ -9,20 +9,20 @@ import ( "gorm.io/gorm" ) -type ParamsDelComment struct { +type ParamsCommentDel struct { ID string `mapstructure:"id" param:"required"` SiteName string `mapstructure:"site_name"` SiteID uint } -func ActionAdminDelComment(c echo.Context) error { +func ActionAdminCommentDel(c echo.Context) error { if isOK, resp := AdminOnly(c); !isOK { return resp } - var p ParamsDelComment - if isOK, resp := ParamsDecode(c, ParamsDelComment{}, &p); !isOK { + var p ParamsCommentDel + if isOK, resp := ParamsDecode(c, ParamsCommentDel{}, &p); !isOK { return resp } diff --git a/http/api_admin_edit_comment.go b/http/api_admin_comment_edit.go similarity index 92% rename from http/api_admin_edit_comment.go rename to http/api_admin_comment_edit.go index a4130eb78..fcba9d07e 100644 --- a/http/api_admin_edit_comment.go +++ b/http/api_admin_comment_edit.go @@ -7,7 +7,7 @@ import ( "github.com/labstack/echo/v4" ) -type ParamsEditComment struct { +type ParamsCommentEdit struct { // 查询值 ID string `mapstructure:"id" param:"required"` SiteName string `mapstructure:"site_name"` @@ -26,13 +26,13 @@ type ParamsEditComment struct { IsPending string `mapstructure:"is_pending"` } -func ActionAdminEditComment(c echo.Context) error { +func ActionAdminCommentEdit(c echo.Context) error { if isOK, resp := AdminOnly(c); !isOK { return resp } - var p ParamsEditComment - if isOK, resp := ParamsDecode(c, ParamsEditComment{}, &p); !isOK { + var p ParamsCommentEdit + if isOK, resp := ParamsDecode(c, ParamsCommentEdit{}, &p); !isOK { return resp } diff --git a/http/api_admin_page_del.go b/http/api_admin_page_del.go new file mode 100644 index 000000000..676796062 --- /dev/null +++ b/http/api_admin_page_del.go @@ -0,0 +1,51 @@ +package http + +import ( + "github.com/ArtalkJS/ArtalkGo/lib" + "github.com/ArtalkJS/ArtalkGo/model" + "github.com/labstack/echo/v4" +) + +type ParamsAdminPageDel struct { + Key string `mapstructure:"key" param:"required"` + SiteName string `mapstructure:"site_name"` + SiteID uint +} + +func ActionAdminPageDel(c echo.Context) error { + if isOK, resp := AdminOnly(c); !isOK { + return resp + } + + var p ParamsAdminPageDel + if isOK, resp := ParamsDecode(c, ParamsAdminPageDel{}, &p); !isOK { + return resp + } + + // find site + if isOK, resp := CheckSite(c, p.SiteName, &p.SiteID); !isOK { + return resp + } + + page := model.FindPage(p.Key, p.SiteName) + if page.IsEmpty() { + return RespError(c, "page not found.") + } + + err := lib.DB.Delete(&page).Error + if err != nil { + return RespError(c, "page 删除失败") + } + + // 删除所有相关内容 + var comments []model.Comment + lib.DB.Where(&model.Comment{PageKey: p.Key, SiteName: p.SiteName}).Find(&comments) + + tx := lib.DB.Begin() + for _, c := range comments { + tx.Delete(&c) + } + tx.Commit() + + return RespSuccess(c) +} diff --git a/http/api_admin_edit_page.go b/http/api_admin_page_edit.go similarity index 84% rename from http/api_admin_edit_page.go rename to http/api_admin_page_edit.go index d6a83d717..9e4692548 100644 --- a/http/api_admin_edit_page.go +++ b/http/api_admin_page_edit.go @@ -5,7 +5,7 @@ import ( "github.com/labstack/echo/v4" ) -type ParamsEditPage struct { +type ParamsAdminPageEdit struct { // 查询值 Key string `mapstructure:"key" param:"required"` SiteName string `mapstructure:"site_name"` @@ -17,13 +17,13 @@ type ParamsEditPage struct { AdminOnly string `mapstructure:"admin_only"` } -func ActionAdminEditPage(c echo.Context) error { +func ActionAdminPageEdit(c echo.Context) error { if isOK, resp := AdminOnly(c); !isOK { return resp } - var p ParamsEditPage - if isOK, resp := ParamsDecode(c, ParamsEditPage{}, &p); !isOK { + var p ParamsAdminPageEdit + if isOK, resp := ParamsDecode(c, ParamsAdminPageEdit{}, &p); !isOK { return resp } diff --git a/http/api_admin_page_fetch.go b/http/api_admin_page_fetch.go index 32a27f764..a1619936b 100644 --- a/http/api_admin_page_fetch.go +++ b/http/api_admin_page_fetch.go @@ -5,7 +5,7 @@ import ( "github.com/labstack/echo/v4" ) -type ParamsPageFetch struct { +type ParamsAdminPageFetch struct { Key string `mapstructure:"key" param:"required"` SiteName string `mapstructure:"site_name"` SiteID uint @@ -16,8 +16,8 @@ func ActionAdminPageFetch(c echo.Context) error { return resp } - var p ParamsPageFetch - if isOK, resp := ParamsDecode(c, ParamsPageFetch{}, &p); !isOK { + var p ParamsAdminPageFetch + if isOK, resp := ParamsDecode(c, ParamsAdminPageFetch{}, &p); !isOK { return resp } diff --git a/http/api_admin_send_mail.go b/http/api_admin_send_mail.go index 3711392ad..52861a5c3 100644 --- a/http/api_admin_send_mail.go +++ b/http/api_admin_send_mail.go @@ -5,7 +5,7 @@ import ( "github.com/labstack/echo/v4" ) -type ParamsSendMail struct { +type ParamsAdminSendMail struct { Subject string `mapstructure:"subject" param:"required"` Body string `mapstructure:"body" param:"required"` ToAddr string `mapstructure:"to_addr" param:"required"` @@ -16,8 +16,8 @@ func ActionAdminSendMail(c echo.Context) error { return resp } - var p ParamsSendMail - if isOK, resp := ParamsDecode(c, ParamsSendMail{}, &p); !isOK { + var p ParamsAdminSendMail + if isOK, resp := ParamsDecode(c, ParamsAdminSendMail{}, &p); !isOK { return resp } diff --git a/http/api_admin_site_add.go b/http/api_admin_site_add.go new file mode 100644 index 000000000..668b36eb9 --- /dev/null +++ b/http/api_admin_site_add.go @@ -0,0 +1,37 @@ +package http + +import ( + "github.com/ArtalkJS/ArtalkGo/lib" + "github.com/ArtalkJS/ArtalkGo/model" + "github.com/labstack/echo/v4" +) + +type ParamsAdminSiteAdd struct { + Name string `mapstructure:"name" param:"required"` + Url string `mapstructure:"url" param:"required"` +} + +func ActionAdminSiteAdd(c echo.Context) error { + if isOK, resp := AdminOnly(c); !isOK { + return resp + } + + var p ParamsAdminSiteAdd + if isOK, resp := ParamsDecode(c, ParamsAdminSiteAdd{}, &p); !isOK { + return resp + } + + if !model.FindSite(p.Name).IsEmpty() { + return RespError(c, "site 已存在") + } + + site := model.Site{} + site.Name = p.Name + site.Url = p.Url + err := lib.DB.Create(&site).Error + if err != nil { + return RespError(c, "site 创建失败") + } + + return RespSuccess(c) +} diff --git a/http/api_admin_site_del.go b/http/api_admin_site_del.go new file mode 100644 index 000000000..c10bc74a9 --- /dev/null +++ b/http/api_admin_site_del.go @@ -0,0 +1,53 @@ +package http + +import ( + "github.com/ArtalkJS/ArtalkGo/lib" + "github.com/ArtalkJS/ArtalkGo/model" + "github.com/labstack/echo/v4" +) + +type ParamsAdminSiteDel struct { + ID uint `mapstructure:"id" param:"required"` + DelContent bool `mapstructure:"del_content"` +} + +func ActionAdminSiteDel(c echo.Context) error { + if isOK, resp := AdminOnly(c); !isOK { + return resp + } + + var p ParamsAdminSiteDel + if isOK, resp := ParamsDecode(c, ParamsAdminSiteDel{}, &p); !isOK { + return resp + } + + site := model.FindSiteByID(p.ID) + if site.IsEmpty() { + return RespError(c, "site 不存在") + } + + err := lib.DB.Delete(&site).Error + if err != nil { + return RespError(c, "site 删除失败") + } + + // 删除所有相关内容 + if p.DelContent { + var comments []model.Comment + lib.DB.Where(&model.Comment{SiteName: site.Name}).Find(&comments) + + var pages []model.Page + lib.DB.Where(&model.Page{SiteName: site.Name}).Find(&pages) + + tx := lib.DB.Begin() + for _, c := range comments { + tx.Delete(&c) + } + for _, p := range pages { + tx.Delete(&p) + } + tx.Commit() + } + + return RespSuccess(c) +} diff --git a/http/api_admin_site_edit.go b/http/api_admin_site_edit.go new file mode 100644 index 000000000..c12a0a620 --- /dev/null +++ b/http/api_admin_site_edit.go @@ -0,0 +1,64 @@ +package http + +import ( + "github.com/ArtalkJS/ArtalkGo/lib" + "github.com/ArtalkJS/ArtalkGo/model" + "github.com/labstack/echo/v4" +) + +type ParamsAdminSiteEdit struct { + ID uint `mapstructure:"id" param:"required"` + Name string `mapstructure:"name"` + Url string `mapstructure:"url"` +} + +func ActionAdminSiteEdit(c echo.Context) error { + if isOK, resp := AdminOnly(c); !isOK { + return resp + } + + var p ParamsAdminSiteEdit + if isOK, resp := ParamsDecode(c, ParamsAdminSiteEdit{}, &p); !isOK { + return resp + } + + site := model.FindSiteByID(p.ID) + if site.IsEmpty() { + return RespError(c, "site 不存在") + } + + modifyName := (p.Name != "" && p.Name != site.Name) + if modifyName && !model.FindSite(p.Name).IsEmpty() { + return RespError(c, "site 已存在,请换个名称") + } + + site.Name = p.Name + site.Url = p.Url + + err := lib.DB.Save(&site).Error + if err != nil { + return RespError(c, "site 保存失败") + } + + // 同步变更 site_name + if modifyName { + var comments []model.Comment + lib.DB.Where(&model.Comment{SiteName: p.Name}).Find(&comments) + + var pages []model.Page + lib.DB.Where(&model.Page{SiteName: p.Name}).Find(&pages) + + tx := lib.DB.Begin() + for _, c := range comments { + c.SiteName = site.Name + tx.Save(&c) + } + for _, p := range pages { + p.SiteName = site.Name + tx.Save(&p) + } + tx.Commit() + } + + return RespSuccess(c) +} diff --git a/http/api_main_add.go b/http/api_main_add.go index c2dd47119..c73470303 100644 --- a/http/api_main_add.go +++ b/http/api_main_add.go @@ -57,7 +57,7 @@ func ActionAdd(c echo.Context) error { page := model.FindCreatePage(p.PageKey, p.PageUrl, p.PageTitle, p.SiteName) // check if the user is allowed to comment - if isAllowed, resp := CheckIfAllowed(c, p.Name, p.Email, page); !isAllowed { + if isAllowed, resp := CheckIfAllowed(c, p.Name, p.Email, page, p.SiteName); !isAllowed { return resp } diff --git a/http/api_user_get.go b/http/api_user_get.go index 74b5be964..b0dc91452 100644 --- a/http/api_user_get.go +++ b/http/api_user_get.go @@ -7,8 +7,8 @@ import ( ) type ParamsUserGet struct { - Name string `mapstructure:"name" param:"required"` - Email string `mapstructure:"email" param:"required"` + Name string `mapstructure:"name"` + Email string `mapstructure:"email"` } type ResponseUserGet struct { @@ -21,12 +21,20 @@ func ActionUserGet(c echo.Context) error { return resp } - var user model.User // 注:user 查找是 AND + var user model.User lib.DB.Where(&model.User{ - Name: p.Name, + Name: p.Name, // 注:user 查找是 AND Email: p.Email, }).First(&user) + if user.IsEmpty() || user.Name != p.Name || user.Email != p.Email { + return RespData(c, Map{ + "user": nil, + "is_login": false, + }) + } + + // loginned user check isLogin := false tUser := GetUserByReqToken(c) if !tUser.IsEmpty() && tUser.Name == p.Name && tUser.Email == p.Email { @@ -34,13 +42,6 @@ func ActionUserGet(c echo.Context) error { user = tUser } - if user.IsEmpty() { - return RespData(c, Map{ - "user": nil, - "is_login": false, - }) - } - return RespData(c, Map{ "user": user.ToCooked(), "is_login": isLogin, diff --git a/http/utils.go b/http/utils.go index fba206d24..593165134 100644 --- a/http/utils.go +++ b/http/utils.go @@ -1,6 +1,7 @@ package http import ( + "net/url" "reflect" "strconv" "strings" @@ -86,6 +87,8 @@ func ParamsDecode(c echo.Context, paramsStruct interface{}, destParams interface } else if field.Type.Kind() == reflect.Uint { u64, _ := strconv.ParseUint(paramVal, 10, 32) params[paramName] = uint(u64) + } else if field.Type.Kind() == reflect.Bool { + params[paramName] = (paramVal == "1") } // } else if field.Type.Kind() == reflect.Array { // params[paramName] = c.QueryParams()[paramName] @@ -100,9 +103,11 @@ func ParamsDecode(c echo.Context, paramsStruct interface{}, destParams interface return true, nil } -func CheckIfAllowed(c echo.Context, name string, email string, page model.Page) (bool, error) { +func CheckIfAllowed(c echo.Context, name string, email string, page model.Page, siteName string) (bool, error) { + isAdminUser := model.IsAdminUser(name, email) + // 如果用户是管理员,或者当前页只能管理员评论 - if model.IsAdminUser(name, email) || page.AdminOnly { + if isAdminUser || page.AdminOnly { if !CheckIsAdminReq(c) { return false, RespError(c, "需要验证管理员身份", Map{"need_login": true}) } @@ -111,6 +116,46 @@ func CheckIfAllowed(c echo.Context, name string, email string, page model.Page) return true, nil } +func CheckReferer(c echo.Context, siteName string) (bool, error) { + isAdminReq := CheckIsAdminReq(c) + if isAdminReq || siteName == "" { + return true, nil + } + + // 请求 Referer 合法性判断 + site := model.FindSite(siteName) + allowUrls := strings.Split(site.Url, ",") + referer := c.Request().Referer() + if referer == "" { + return true, nil + } + + pr, err := url.Parse(referer) + if err != nil { + return true, nil + } + + allow := false + for _, u := range allowUrls { + u = strings.TrimSpace(u) + if u == "" { + continue + } + pu, err := url.Parse(u) + if err != nil { + continue + } + if pu.Hostname() == pr.Hostname() { + allow = true + } + } + if !allow { + return false, RespError(c, "非法请求:Referer 不被允许") + } + + return true, nil +} + func CheckSite(c echo.Context, siteName string, destID *uint) (bool, error) { if siteName == "" { return true, nil @@ -118,7 +163,12 @@ func CheckSite(c echo.Context, siteName string, destID *uint) (bool, error) { site := model.FindSite(siteName) if site.IsEmpty() { - return false, RespError(c, "Site not found") + return false, RespError(c, "Site 未找到") + } + + // 检测 Referer 合法性 + if isOK, resp := CheckReferer(c, siteName); !isOK { + return false, resp } *destID = site.ID diff --git a/model/query.go b/model/query.go index ae2669e30..a9ccb15b2 100644 --- a/model/query.go +++ b/model/query.go @@ -39,6 +39,12 @@ func FindSite(name string) Site { return site } +func FindSiteByID(id uint) Site { + var site Site + lib.DB.First(&site, id) + return site +} + func FindCreatePage(pageKey string, pageUrl string, pageTitle string, siteName string) Page { page := FindPage(pageKey, siteName) if page.IsEmpty() { From 59439d81b520988897dc9adcafecd51e3956869f Mon Sep 17 00:00:00 2001 From: qwqcode Date: Tue, 28 Sep 2021 19:31:55 +0800 Subject: [PATCH 031/349] Replace struct query by string query: bcz when querying with struct, GORM will only query with non-zero fields. --- README.md | 1 + cmd/root.go | 2 +- http/api_admin_page_del.go | 2 +- http/api_admin_site_del.go | 4 ++-- http/api_admin_site_edit.go | 4 ++-- http/api_main_get.go | 2 +- http/api_user_get.go | 5 +---- http/api_user_login.go | 5 +---- http/utils.go | 4 ++++ lib/email/email.go | 2 +- model/comment.go | 2 +- model/query.go | 8 ++++---- 12 files changed, 20 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index 3e320d0b9..beab46723 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,7 @@ - 邮件多模板自定义 - 博客邮件订阅 - 用户鉴权机制 +- 防止非法跨域请求 - 全局验证码操作限制 - 规范化 API diff --git a/cmd/root.go b/cmd/root.go index 974c0784b..2ce8ae3b0 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -151,7 +151,7 @@ func syncConfWithDB() { // 清理配置文件中不存在的用户 var dbAdminUsers []model.User - lib.DB.Where(&model.User{IsInConf: true}).Find(&dbAdminUsers) + lib.DB.Where("is_in_conf = 1").Find(&dbAdminUsers) for _, dbU := range dbAdminUsers { isUserExist := func() bool { for _, confU := range config.Instance.AdminUsers { diff --git a/http/api_admin_page_del.go b/http/api_admin_page_del.go index 676796062..40db001c0 100644 --- a/http/api_admin_page_del.go +++ b/http/api_admin_page_del.go @@ -39,7 +39,7 @@ func ActionAdminPageDel(c echo.Context) error { // 删除所有相关内容 var comments []model.Comment - lib.DB.Where(&model.Comment{PageKey: p.Key, SiteName: p.SiteName}).Find(&comments) + lib.DB.Where("page_key = ? AND site_name = ?", p.Key, p.SiteName).Find(&comments) tx := lib.DB.Begin() for _, c := range comments { diff --git a/http/api_admin_site_del.go b/http/api_admin_site_del.go index c10bc74a9..e8fa158a9 100644 --- a/http/api_admin_site_del.go +++ b/http/api_admin_site_del.go @@ -34,10 +34,10 @@ func ActionAdminSiteDel(c echo.Context) error { // 删除所有相关内容 if p.DelContent { var comments []model.Comment - lib.DB.Where(&model.Comment{SiteName: site.Name}).Find(&comments) + lib.DB.Where("site_name = ?", site.Name).Find(&comments) var pages []model.Page - lib.DB.Where(&model.Page{SiteName: site.Name}).Find(&pages) + lib.DB.Where("site_name = ?", site.Name).Find(&pages) tx := lib.DB.Begin() for _, c := range comments { diff --git a/http/api_admin_site_edit.go b/http/api_admin_site_edit.go index c12a0a620..eb3aa1d5b 100644 --- a/http/api_admin_site_edit.go +++ b/http/api_admin_site_edit.go @@ -43,10 +43,10 @@ func ActionAdminSiteEdit(c echo.Context) error { // 同步变更 site_name if modifyName { var comments []model.Comment - lib.DB.Where(&model.Comment{SiteName: p.Name}).Find(&comments) + lib.DB.Where("site_name = ?", p.Name).Find(&comments) var pages []model.Page - lib.DB.Where(&model.Page{SiteName: p.Name}).Find(&pages) + lib.DB.Where("site_name = ?", p.Name).Find(&pages) tx := lib.DB.Begin() for _, c := range comments { diff --git a/http/api_main_get.go b/http/api_main_get.go index 8a82689b6..6abc746c4 100644 --- a/http/api_main_get.go +++ b/http/api_main_get.go @@ -110,7 +110,7 @@ func ActionGet(c echo.Context) error { } func GetCommentQuery(c echo.Context, p ParamsGet, siteID uint) *gorm.DB { - query := lib.DB.Model(&model.Comment{}).Where("page_key = ?", p.PageKey).Order("created_at DESC") + query := lib.DB.Model(&model.Comment{}).Where("page_key = ? AND site_name = ?", p.PageKey, p.SiteName).Order("created_at DESC") if IsMsgCenter(p) { query = query.Scopes(MsgCenter(c, p, siteID)) } else { diff --git a/http/api_user_get.go b/http/api_user_get.go index b0dc91452..4f80c0c60 100644 --- a/http/api_user_get.go +++ b/http/api_user_get.go @@ -22,10 +22,7 @@ func ActionUserGet(c echo.Context) error { } var user model.User - lib.DB.Where(&model.User{ - Name: p.Name, // 注:user 查找是 AND - Email: p.Email, - }).First(&user) + lib.DB.Where("name = ? AND email = ?", p.Name, p.Email).First(&user) if user.IsEmpty() || user.Name != p.Name || user.Email != p.Email { return RespData(c, Map{ diff --git a/http/api_user_login.go b/http/api_user_login.go index 23c9e576f..8f5d14c21 100644 --- a/http/api_user_login.go +++ b/http/api_user_login.go @@ -22,10 +22,7 @@ func ActionLogin(c echo.Context) error { RecordAction(c) var user model.User - lib.DB.Where(&model.User{ - Name: p.Name, - Email: p.Email, - }).First(&user) // name = ? OR email = ? + lib.DB.Where("name = ? AND email = ?", p.Name, p.Email).First(&user) // name = ? OR email = ? if user.IsEmpty() || user.Password != p.Password { return RespError(c, "验证失败") } diff --git a/http/utils.go b/http/utils.go index 593165134..b63dbd67f 100644 --- a/http/utils.go +++ b/http/utils.go @@ -124,6 +124,10 @@ func CheckReferer(c echo.Context, siteName string) (bool, error) { // 请求 Referer 合法性判断 site := model.FindSite(siteName) + if strings.TrimSpace(site.Url) == "" { + return true, nil // 若 url 字段为空,则取消控制 + } + allowUrls := strings.Split(site.Url, ",") referer := c.Request().Referer() if referer == "" { diff --git a/lib/email/email.go b/lib/email/email.go index 9c37a9c56..28d8a439b 100644 --- a/lib/email/email.go +++ b/lib/email/email.go @@ -42,7 +42,7 @@ func SendToAdmin(from model.CookedCommentForEmail) { // 查询所有 admin var admins []model.User - lib.DB.Where(&model.User{IsAdmin: true}).Find(&admins) + lib.DB.Where("is_admin = 1").Find(&admins) if len(admins) == 0 { return diff --git a/model/comment.go b/model/comment.go index fa77a1afd..f2c0a3219 100644 --- a/model/comment.go +++ b/model/comment.go @@ -53,7 +53,7 @@ func (c *Comment) FetchPage() Page { } var page Page - lib.DB.Where(&Page{Key: c.PageKey}).First(&page) + lib.DB.Where("page_key = ?", c.PageKey).First(&page) c.Page = page return page diff --git a/model/query.go b/model/query.go index a9ccb15b2..d5b0c6edd 100644 --- a/model/query.go +++ b/model/query.go @@ -15,13 +15,13 @@ func FindComment(id uint, siteName string) Comment { // 查找用户(返回:精确查找 AND) func FindUser(name string, email string) User { var user User - lib.DB.Where(&User{Name: name, Email: email}).First(&user) + lib.DB.Where("name = ? AND email = ?", name, email).First(&user) return user } func IsAdminUser(name string, email string) bool { var user User - lib.DB.Where(&User{Name: name, Email: email, IsAdmin: true}).First(&user) + lib.DB.Where("name = ? AND email = ? AND is_admin = 1", name, email).First(&user) return !user.IsEmpty() } @@ -35,7 +35,7 @@ func UpdateComment(comment *Comment) error { func FindSite(name string) Site { var site Site - lib.DB.Where(&Site{Name: name}).First(&site) + lib.DB.Where("name = ?", name).First(&site) return site } @@ -86,7 +86,7 @@ func UpdateUser(user *User) error { func FindPage(key string, siteName string) Page { var page Page - lib.DB.Where(&Page{Key: key, SiteName: siteName}).First(&page) + lib.DB.Where("key = ? AND site_name = ?", key, siteName).First(&page) return page } From ad5bf0e5e66f198484d931a508b6a95909944e48 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Fri, 8 Oct 2021 20:20:42 +0800 Subject: [PATCH 032/349] Api for Sidebar Admin panel. --- http/a_http.go | 13 +++++++-- http/api_admin_page_get.go | 40 ++++++++++++++++++++++++++ http/api_admin_site_get.go | 33 +++++++++++++++++++++ http/api_main_get.go | 59 +++++++++++++++++++++++++------------- 4 files changed, 122 insertions(+), 23 deletions(-) create mode 100644 http/api_admin_page_get.go create mode 100644 http/api_admin_site_get.go diff --git a/http/a_http.go b/http/a_http.go index 684cf6a8e..3153b7d63 100644 --- a/http/a_http.go +++ b/http/a_http.go @@ -89,12 +89,19 @@ func InitRoute(e *echo.Echo) { // api/admin admin := api.Group("/admin", middleware.JWTWithConfig(CommonJwtConfig)) // use jwt - admin.POST("/page-edit", ActionAdminPageEdit) - admin.POST("/page-del", ActionAdminPageDel) + admin.POST("/comment-edit", ActionAdminCommentEdit) admin.POST("/comment-del", ActionAdminCommentDel) + + admin.POST("/page-get", ActionAdminPageGet) + admin.POST("/page-edit", ActionAdminPageEdit) + admin.POST("/page-del", ActionAdminPageDel) admin.POST("/page-fetch", ActionAdminPageFetch) - admin.POST("/send-mail", ActionAdminSendMail) + + admin.POST("/site-get", ActionAdminSiteGet) admin.POST("/site-add", ActionAdminSiteAdd) + admin.POST("/site-edit", ActionAdminSiteEdit) admin.POST("/site-del", ActionAdminSiteDel) + + admin.POST("/send-mail", ActionAdminSendMail) } diff --git a/http/api_admin_page_get.go b/http/api_admin_page_get.go new file mode 100644 index 000000000..2577f5897 --- /dev/null +++ b/http/api_admin_page_get.go @@ -0,0 +1,40 @@ +package http + +import ( + "github.com/ArtalkJS/ArtalkGo/lib" + "github.com/ArtalkJS/ArtalkGo/model" + "github.com/labstack/echo/v4" +) + +type ParamsAdminPageGet struct { + SiteName string `mapstructure:"site_name"` + SiteID uint +} + +func ActionAdminPageGet(c echo.Context) error { + if isOK, resp := AdminOnly(c); !isOK { + return resp + } + + var p ParamsAdminPageFetch + if isOK, resp := ParamsDecode(c, ParamsAdminPageFetch{}, &p); !isOK { + return resp + } + + // find site + if isOK, resp := CheckSite(c, p.SiteName, &p.SiteID); !isOK { + return resp + } + + var pages []model.Page + lib.DB.Model(&model.Page{}).Find(&pages) + + var cookedPages []model.CookedPage + for _, p := range pages { + cookedPages = append(cookedPages, p.ToCooked()) + } + + return RespData(c, Map{ + "pages": cookedPages, + }) +} diff --git a/http/api_admin_site_get.go b/http/api_admin_site_get.go new file mode 100644 index 000000000..f238b7f35 --- /dev/null +++ b/http/api_admin_site_get.go @@ -0,0 +1,33 @@ +package http + +import ( + "github.com/ArtalkJS/ArtalkGo/lib" + "github.com/ArtalkJS/ArtalkGo/model" + "github.com/labstack/echo/v4" +) + +type ParamsAdminSiteGet struct { +} + +func ActionAdminSiteGet(c echo.Context) error { + if isOK, resp := AdminOnly(c); !isOK { + return resp + } + + var p ParamsAdminSiteGet + if isOK, resp := ParamsDecode(c, ParamsAdminSiteGet{}, &p); !isOK { + return resp + } + + var sites []model.Site + lib.DB.Model(&model.Site{}).Find(&sites) + + var cookedSites []model.CookedSite + for _, s := range sites { + cookedSites = append(cookedSites, s.ToCooked()) + } + + return RespData(c, Map{ + "sites": cookedSites, + }) +} diff --git a/http/api_main_get.go b/http/api_main_get.go index 6abc746c4..2628dabaf 100644 --- a/http/api_main_get.go +++ b/http/api_main_get.go @@ -1,6 +1,8 @@ package http import ( + "strings" + "github.com/ArtalkJS/ArtalkGo/lib" "github.com/ArtalkJS/ArtalkGo/model" "github.com/labstack/echo/v4" @@ -110,46 +112,63 @@ func ActionGet(c echo.Context) error { } func GetCommentQuery(c echo.Context, p ParamsGet, siteID uint) *gorm.DB { - query := lib.DB.Model(&model.Comment{}).Where("page_key = ? AND site_name = ?", p.PageKey, p.SiteName).Order("created_at DESC") + query := lib.DB.Model(&model.Comment{}).Order("created_at DESC") + if IsMsgCenter(p) { - query = query.Scopes(MsgCenter(c, p, siteID)) - } else { - query = query.Scopes(AllowedComment(c)) + return query.Scopes(MsgCenter(c, p, siteID)) } - return query + + return query.Where("page_key = ? AND site_name = ?", p.PageKey, p.SiteName).Scopes(AllowedComment(c)) } func IsMsgCenter(p ParamsGet) bool { - return p.Name != "" && p.Email != "" + return p.Name != "" && p.Email != "" && p.Type != "" } +// TODO: 重构 MsgCenter func MsgCenter(c echo.Context, p ParamsGet, siteID uint) func(db *gorm.DB) *gorm.DB { return func(db *gorm.DB) *gorm.DB { user := model.FindUser(p.Name, p.Email) - myCommentIDs := []int{} - if p.Type == "all" || p.Type == "mentions" { + // 站点隔离 + isAdminReq := CheckIsAdminReq(c) + if !isAdminReq || (isAdminReq && p.SiteName != "") { + db = db.Where("site_name = ?", p.SiteName) + } + + // admin_only 检测 + if strings.HasPrefix(p.Type, "admin_") && !CheckIsAdminReq(c) { + db = db.Where("id = 0") + return db + } + + // 获取我的 commentIDs + getMyCommentIDs := func() []int { + myCommentIDs := []int{} var myComments []model.Comment lib.DB.Where("user_id = ?", user.ID).Find(&myComments) for _, comment := range myComments { myCommentIDs = append(myCommentIDs, int(comment.ID)) } + return myCommentIDs } - if p.Type == "all" { - db = db.Where("rid IN (?) OR user_id = ?", myCommentIDs, user.ID) - } - if p.Type == "mentions" { - db = db.Where("rid IN (?) AND user_id != ?", myCommentIDs, user.ID) - } - if p.Type == "mine" { - db = db.Where("user_id = ?", user.ID) - } - if p.Type == "pending" { - db = db.Where("user_id = ? AND is_pending = 1", user.ID) + switch p.Type { + case "all": + return db.Where("rid IN (?) OR user_id = ?", getMyCommentIDs(), user.ID) + case "mentions": + return db.Where("rid IN (?) AND user_id != ?", getMyCommentIDs(), user.ID) + case "mine": + return db.Where("user_id = ?", user.ID) + case "pending": + return db.Where("user_id = ? AND is_pending = 1", user.ID) + case "admin_all": + return db + case "admin_pending": + return db.Where("is_pending = 1") } - return db + return db.Where("id = 0") } } From 45fec00545e1e1a0da6b90e93c5914a4094738dc Mon Sep 17 00:00:00 2001 From: qwqcode Date: Sat, 9 Oct 2021 15:03:19 +0800 Subject: [PATCH 033/349] Fix a wrong of type. --- http/api_admin_page_get.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/http/api_admin_page_get.go b/http/api_admin_page_get.go index 2577f5897..9c372ffbc 100644 --- a/http/api_admin_page_get.go +++ b/http/api_admin_page_get.go @@ -16,8 +16,8 @@ func ActionAdminPageGet(c echo.Context) error { return resp } - var p ParamsAdminPageFetch - if isOK, resp := ParamsDecode(c, ParamsAdminPageFetch{}, &p); !isOK { + var p ParamsAdminPageGet + if isOK, resp := ParamsDecode(c, ParamsAdminPageGet{}, &p); !isOK { return resp } From 4cb361fd51539e5ebdcd98e42da2e4f7533262ea Mon Sep 17 00:00:00 2001 From: qwqcode Date: Sat, 9 Oct 2021 18:23:51 +0800 Subject: [PATCH 034/349] Admin importer api. --- http/a_http.go | 3 ++ http/api_admin_comment_del.go | 8 +-- http/api_admin_comment_edit.go | 6 +-- http/api_admin_importer.go | 95 ++++++++++++++++++++++++++++++++++ http/api_admin_page_del.go | 2 +- http/api_admin_page_edit.go | 4 +- http/api_admin_page_fetch.go | 2 +- http/api_admin_setting.go | 32 ++++++++++++ http/api_captcha.go | 2 +- http/api_main_add.go | 6 +-- http/utils.go | 4 +- 11 files changed, 147 insertions(+), 17 deletions(-) create mode 100644 http/api_admin_importer.go create mode 100644 http/api_admin_setting.go diff --git a/http/a_http.go b/http/a_http.go index 3153b7d63..3495224b3 100644 --- a/http/a_http.go +++ b/http/a_http.go @@ -102,6 +102,9 @@ func InitRoute(e *echo.Echo) { admin.POST("/site-add", ActionAdminSiteAdd) admin.POST("/site-edit", ActionAdminSiteEdit) admin.POST("/site-del", ActionAdminSiteDel) + admin.POST("/setting-get", ActionAdminSettingGet) + admin.POST("/setting-save", ActionAdminSettingSave) + admin.POST("/importer", ActionAdminImporter) admin.POST("/send-mail", ActionAdminSendMail) } diff --git a/http/api_admin_comment_del.go b/http/api_admin_comment_del.go index df4cbf6d6..00ae3ffba 100644 --- a/http/api_admin_comment_del.go +++ b/http/api_admin_comment_del.go @@ -28,7 +28,7 @@ func ActionAdminCommentDel(c echo.Context) error { id, err := strconv.Atoi(p.ID) if err != nil { - return RespError(c, "invalid id.") + return RespError(c, "invalid id") } // find site @@ -38,11 +38,11 @@ func ActionAdminCommentDel(c echo.Context) error { comment := model.FindComment(uint(id), p.SiteName) if comment.IsEmpty() { - return RespError(c, "comment not found.") + return RespError(c, "comment not found") } if err := lib.DB.Model(&model.Comment{}).Delete("id = ?", comment.ID).Error; err != nil { - return RespError(c, "comment delete error.") + return RespError(c, "comment delete error") } // 删除子评论 @@ -55,7 +55,7 @@ func ActionAdminCommentDel(c echo.Context) error { } } if hasErr { - return RespError(c, "children comment delete error.") + return RespError(c, "children comment delete error") } return RespSuccess(c) diff --git a/http/api_admin_comment_edit.go b/http/api_admin_comment_edit.go index fcba9d07e..1fb11d464 100644 --- a/http/api_admin_comment_edit.go +++ b/http/api_admin_comment_edit.go @@ -38,7 +38,7 @@ func ActionAdminCommentEdit(c echo.Context) error { id, err := strconv.Atoi(p.ID) if err != nil { - return RespError(c, "invalid id.") + return RespError(c, "invalid id") } // find site @@ -48,7 +48,7 @@ func ActionAdminCommentEdit(c echo.Context) error { comment := model.FindComment(uint(id), p.SiteName) if comment.IsEmpty() { - return RespError(c, "comment not found.") + return RespError(c, "comment not found") } // content @@ -114,7 +114,7 @@ func ActionAdminCommentEdit(c echo.Context) error { } if err := model.UpdateComment(&comment); err != nil { - return RespError(c, "comment save error.") + return RespError(c, "comment save error") } return RespData(c, Map{ diff --git a/http/api_admin_importer.go b/http/api_admin_importer.go new file mode 100644 index 000000000..2a50c904e --- /dev/null +++ b/http/api_admin_importer.go @@ -0,0 +1,95 @@ +package http + +import ( + "encoding/json" + "fmt" + "strings" + + "github.com/ArtalkJS/ArtalkGo/lib" + "github.com/ArtalkJS/ArtalkGo/model" + "github.com/labstack/echo/v4" + "github.com/sirupsen/logrus" +) + +type ArtalkV1_Comment struct { + ID uint `json:"id"` + Content string `json:"content"` + Nick string `json:"nick"` + Email string `json:"email"` + Link string `json:"link"` + UA string `json:"ua"` + PageKey string `json:"page_key"` + Rid uint `json:"rid"` + IP string `json:"ip"` + Date string `json:"date"` + IsPending bool `json:"is_pending"` + IsCollapsed bool `json:"is_collapsed"` +} + +type ParamsAdminImporter struct { + Type string `mapstructure:"type" param:"required"` + Data string `mapstructure:"data" param:"required"` + SiteName string `mapstructure:"site_name"` + SiteID uint +} + +func ActionAdminImporter(c echo.Context) error { + if isOK, resp := AdminOnly(c); !isOK { + return resp + } + + var p ParamsAdminImporter + if isOK, resp := ParamsDecode(c, ParamsAdminImporter{}, &p); !isOK { + return resp + } + + // find site + if isOK, resp := CheckSite(c, p.SiteName, &p.SiteID); !isOK { + return resp + } + + switch p.Type { + case "artalk_v1": + var comments []ArtalkV1_Comment + err := json.Unmarshal([]byte(p.Data), &comments) + if err != nil { + return RespError(c, "json unmarshal err:"+err.Error()) + } + + errs := []string{} + for _, c := range comments { + page := model.FindCreatePage(c.PageKey, "", "", p.SiteName) + user := model.FindCreateUser(c.Nick, c.Email) + + user.Link = c.Link + user.LastIP = c.IP + user.LastUA = c.UA + model.UpdateUser(&user) + + nComment := model.Comment{ + Content: c.Content, + Rid: c.Rid, + UserID: user.ID, + PageKey: page.Key, + IP: c.IP, + UA: c.UA, + IsPending: c.IsPending, + IsCollapsed: c.IsCollapsed, + SiteName: p.SiteName, + } + + err := lib.DB.Create(&nComment).Error + if err != nil { + logrus.Error("Save Comment error: ", err) + errs = append(errs, fmt.Sprintf("%d: %s", c.ID, err.Error())) + } + } + + if len(errs) != 0 { + return RespError(c, "导入发生错误:"+strings.Join(errs, "\n")) + } + return RespSuccess(c) + } + + return RespError(c, "invalid type") +} diff --git a/http/api_admin_page_del.go b/http/api_admin_page_del.go index 40db001c0..e04a228f2 100644 --- a/http/api_admin_page_del.go +++ b/http/api_admin_page_del.go @@ -29,7 +29,7 @@ func ActionAdminPageDel(c echo.Context) error { page := model.FindPage(p.Key, p.SiteName) if page.IsEmpty() { - return RespError(c, "page not found.") + return RespError(c, "page not found") } err := lib.DB.Delete(&page).Error diff --git a/http/api_admin_page_edit.go b/http/api_admin_page_edit.go index 9e4692548..d8595c878 100644 --- a/http/api_admin_page_edit.go +++ b/http/api_admin_page_edit.go @@ -34,7 +34,7 @@ func ActionAdminPageEdit(c echo.Context) error { page := model.FindPage(p.Key, p.SiteName) if page.IsEmpty() { - return RespError(c, "page not found.") + return RespError(c, "page not found") } // url @@ -56,7 +56,7 @@ func ActionAdminPageEdit(c echo.Context) error { } if err := model.UpdatePage(&page); err != nil { - return RespError(c, "page save error.") + return RespError(c, "page save error") } return RespData(c, Map{ diff --git a/http/api_admin_page_fetch.go b/http/api_admin_page_fetch.go index a1619936b..b8569af72 100644 --- a/http/api_admin_page_fetch.go +++ b/http/api_admin_page_fetch.go @@ -28,7 +28,7 @@ func ActionAdminPageFetch(c echo.Context) error { page := model.FindPage(p.Key, p.SiteName) if page.IsEmpty() { - return RespError(c, "page not found.") + return RespError(c, "page not found") } if err := page.FetchURL(); err != nil { diff --git a/http/api_admin_setting.go b/http/api_admin_setting.go new file mode 100644 index 000000000..74e350c33 --- /dev/null +++ b/http/api_admin_setting.go @@ -0,0 +1,32 @@ +package http + +import ( + "github.com/labstack/echo/v4" +) + +func ActionAdminSettingGet(c echo.Context) error { + if isOK, resp := AdminOnly(c); !isOK { + return resp + } + + return RespSuccess(c) +} + +type ParamsAdminSettingSave struct { + ID uint `mapstructure:"id" param:"required"` + Name string `mapstructure:"name"` + Url string `mapstructure:"url"` +} + +func ActionAdminSettingSave(c echo.Context) error { + if isOK, resp := AdminOnly(c); !isOK { + return resp + } + + var p ParamsAdminSettingSave + if isOK, resp := ParamsDecode(c, ParamsAdminSettingSave{}, &p); !isOK { + return resp + } + + return RespSuccess(c) +} diff --git a/http/api_captcha.go b/http/api_captcha.go index ac337c986..40cdaf325 100644 --- a/http/api_captcha.go +++ b/http/api_captcha.go @@ -25,7 +25,7 @@ func ActionCaptchaCheck(c echo.Context) error { inputVal := c.QueryParam("value") if inputVal == "" { - return RespError(c, "param `value` is required.") + return RespError(c, "param `value` is required") } if strings.ToLower(inputVal) == GetCaptchaRealCode(ip) { diff --git a/http/api_main_add.go b/http/api_main_add.go index c73470303..37dfd36a1 100644 --- a/http/api_main_add.go +++ b/http/api_main_add.go @@ -36,10 +36,10 @@ func ActionAdd(c echo.Context) error { } if !lib.ValidateEmail(p.Email) { - return RespError(c, "Invalid email.") + return RespError(c, "Invalid email") } if p.Link != "" && !lib.ValidateURL(p.Link) { - return RespError(c, "Invalid link.") + return RespError(c, "Invalid link") } ip := c.RealIP() @@ -64,7 +64,7 @@ func ActionAdd(c echo.Context) error { // find user user := model.FindCreateUser(p.Name, p.Email) if user.ID == 0 || page.Key == "" { - logrus.Error("Cannot get user or page.") + logrus.Error("Cannot get user or page") return RespError(c, "评论失败") } diff --git a/http/utils.go b/http/utils.go index b63dbd67f..796abfc63 100644 --- a/http/utils.go +++ b/http/utils.go @@ -74,7 +74,7 @@ func ParamsDecode(c echo.Context, paramsStruct interface{}, destParams interface // check required param if paramName != "" && paramTagP == "required" { if strings.TrimSpace(paramVal) == "" { - return false, RespError(c, "Param `"+paramName+"` is required.") + return false, RespError(c, "Param `"+paramName+"` is required") } } @@ -98,7 +98,7 @@ func ParamsDecode(c echo.Context, paramsStruct interface{}, destParams interface err := mapstructure.Decode(params, destParams) if err != nil { logrus.Error("Params decode error: ", err) - return false, RespError(c, "Params decode error.") + return false, RespError(c, "Params decode error") } return true, nil } From c99861fc30b90f50849fc07d89978c8d1dbfd0a5 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Sat, 9 Oct 2021 23:07:35 +0800 Subject: [PATCH 035/349] Improve some details, Soft Delete is not used in some places to prevent content duplication. --- cmd/root.go | 2 +- http/api_admin_importer.go | 10 ++++++++++ http/api_admin_page_del.go | 2 +- http/api_admin_page_get.go | 2 +- http/api_admin_site_add.go | 8 ++++++-- http/api_admin_site_del.go | 4 ++-- http/api_admin_site_edit.go | 22 +++++++++++++++++++--- http/utils.go | 4 ++-- lib/utils.go | 11 +++++++++++ model/query.go | 1 + model/site.go | 27 ++++++++++++++++++++------- 11 files changed, 74 insertions(+), 19 deletions(-) diff --git a/cmd/root.go b/cmd/root.go index 2ce8ae3b0..bfd719315 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -163,7 +163,7 @@ func syncConfWithDB() { } if !isUserExist() { - lib.DB.Delete(&dbU) + lib.DB.Unscoped().Delete(&dbU) } } } diff --git a/http/api_admin_importer.go b/http/api_admin_importer.go index 2a50c904e..3362e7a51 100644 --- a/http/api_admin_importer.go +++ b/http/api_admin_importer.go @@ -43,6 +43,16 @@ func ActionAdminImporter(c echo.Context) error { return resp } + // check create site + if model.FindSite(p.SiteName).IsEmpty() { + site := model.Site{} + site.Name = p.SiteName + err := lib.DB.Create(&site).Error + if err != nil { + return RespError(c, "站点创建失败") + } + } + // find site if isOK, resp := CheckSite(c, p.SiteName, &p.SiteID); !isOK { return resp diff --git a/http/api_admin_page_del.go b/http/api_admin_page_del.go index e04a228f2..af8d373c3 100644 --- a/http/api_admin_page_del.go +++ b/http/api_admin_page_del.go @@ -32,7 +32,7 @@ func ActionAdminPageDel(c echo.Context) error { return RespError(c, "page not found") } - err := lib.DB.Delete(&page).Error + err := lib.DB.Unscoped().Delete(&page).Error if err != nil { return RespError(c, "page 删除失败") } diff --git a/http/api_admin_page_get.go b/http/api_admin_page_get.go index 9c372ffbc..2e6c09635 100644 --- a/http/api_admin_page_get.go +++ b/http/api_admin_page_get.go @@ -27,7 +27,7 @@ func ActionAdminPageGet(c echo.Context) error { } var pages []model.Page - lib.DB.Model(&model.Page{}).Find(&pages) + lib.DB.Model(&model.Page{}).Where("site_name = ?", p.SiteName).Find(&pages) var cookedPages []model.CookedPage for _, p := range pages { diff --git a/http/api_admin_site_add.go b/http/api_admin_site_add.go index 668b36eb9..b46c926d2 100644 --- a/http/api_admin_site_add.go +++ b/http/api_admin_site_add.go @@ -8,7 +8,7 @@ import ( type ParamsAdminSiteAdd struct { Name string `mapstructure:"name" param:"required"` - Url string `mapstructure:"url" param:"required"` + Urls string `mapstructure:"urls"` } func ActionAdminSiteAdd(c echo.Context) error { @@ -21,13 +21,17 @@ func ActionAdminSiteAdd(c echo.Context) error { return resp } + if p.Urls != "" && !lib.ValidateURL(p.Urls) { + return RespError(c, "Invalid url") + } + if !model.FindSite(p.Name).IsEmpty() { return RespError(c, "site 已存在") } site := model.Site{} site.Name = p.Name - site.Url = p.Url + site.Urls = p.Urls err := lib.DB.Create(&site).Error if err != nil { return RespError(c, "site 创建失败") diff --git a/http/api_admin_site_del.go b/http/api_admin_site_del.go index e8fa158a9..81b5077a2 100644 --- a/http/api_admin_site_del.go +++ b/http/api_admin_site_del.go @@ -26,7 +26,7 @@ func ActionAdminSiteDel(c echo.Context) error { return RespError(c, "site 不存在") } - err := lib.DB.Delete(&site).Error + err := lib.DB.Unscoped().Delete(&site).Error if err != nil { return RespError(c, "site 删除失败") } @@ -44,7 +44,7 @@ func ActionAdminSiteDel(c echo.Context) error { tx.Delete(&c) } for _, p := range pages { - tx.Delete(&p) + tx.Unscoped().Delete(&p) } tx.Commit() } diff --git a/http/api_admin_site_edit.go b/http/api_admin_site_edit.go index eb3aa1d5b..8736b4d12 100644 --- a/http/api_admin_site_edit.go +++ b/http/api_admin_site_edit.go @@ -1,6 +1,8 @@ package http import ( + "strings" + "github.com/ArtalkJS/ArtalkGo/lib" "github.com/ArtalkJS/ArtalkGo/model" "github.com/labstack/echo/v4" @@ -9,7 +11,7 @@ import ( type ParamsAdminSiteEdit struct { ID uint `mapstructure:"id" param:"required"` Name string `mapstructure:"name"` - Url string `mapstructure:"url"` + Urls string `mapstructure:"urls"` } func ActionAdminSiteEdit(c echo.Context) error { @@ -27,13 +29,25 @@ func ActionAdminSiteEdit(c echo.Context) error { return RespError(c, "site 不存在") } + if strings.TrimSpace(p.Name) == "" { + return RespError(c, "site 名称不能为空白字符") + } + modifyName := (p.Name != "" && p.Name != site.Name) if modifyName && !model.FindSite(p.Name).IsEmpty() { return RespError(c, "site 已存在,请换个名称") } site.Name = p.Name - site.Url = p.Url + site.Urls = p.Urls + + if p.Urls != "" { + for _, url := range site.ToCooked().Urls { + if !lib.ValidateURL(url) { + return RespError(c, "Invalid url exist") + } + } + } err := lib.DB.Save(&site).Error if err != nil { @@ -60,5 +74,7 @@ func ActionAdminSiteEdit(c echo.Context) error { tx.Commit() } - return RespSuccess(c) + return RespData(c, Map{ + "site": site.ToCooked(), + }) } diff --git a/http/utils.go b/http/utils.go index 796abfc63..c5b587412 100644 --- a/http/utils.go +++ b/http/utils.go @@ -124,11 +124,11 @@ func CheckReferer(c echo.Context, siteName string) (bool, error) { // 请求 Referer 合法性判断 site := model.FindSite(siteName) - if strings.TrimSpace(site.Url) == "" { + if strings.TrimSpace(site.Urls) == "" { return true, nil // 若 url 字段为空,则取消控制 } - allowUrls := strings.Split(site.Url, ",") + allowUrls := site.ToCooked().Urls referer := c.Request().Referer() if referer == "" { return true, nil diff --git a/lib/utils.go b/lib/utils.go index 0e72cbe75..075a67efc 100644 --- a/lib/utils.go +++ b/lib/utils.go @@ -9,6 +9,7 @@ import ( "net/mail" "net/url" "os" + "strings" "github.com/jeremywohl/flatten" "github.com/yuin/goldmark" @@ -101,6 +102,16 @@ func ContainsStr(s []string, v string) bool { return false } +func RemoveBlankStrings(s []string) []string { + var r []string + for _, str := range s { + if strings.TrimSpace(str) != "" { + r = append(r, str) + } + } + return r +} + func IsUrlValid(urlStr string) bool { _, err := url.ParseRequestURI(urlStr) return err != nil diff --git a/model/query.go b/model/query.go index d5b0c6edd..36ad1e0a1 100644 --- a/model/query.go +++ b/model/query.go @@ -86,6 +86,7 @@ func UpdateUser(user *User) error { func FindPage(key string, siteName string) Page { var page Page + // TODO: default site_name not null lib.DB.Where("key = ? AND site_name = ?", key, siteName).First(&page) return page } diff --git a/model/site.go b/model/site.go index 183ce5bd2..c7733bc14 100644 --- a/model/site.go +++ b/model/site.go @@ -1,13 +1,16 @@ package model import ( + "strings" + + "github.com/ArtalkJS/ArtalkGo/lib" "gorm.io/gorm" ) type Site struct { gorm.Model Name string `gorm:"uniqueIndex"` - Url string + Urls string } func (s Site) IsEmpty() bool { @@ -15,15 +18,25 @@ func (s Site) IsEmpty() bool { } type CookedSite struct { - ID uint `json:"id"` - Name string `json:"name"` - Url string `json:"url"` + ID uint `json:"id"` + Name string `json:"name"` + Urls []string `json:"urls"` + UrlsRaw string `json:"urls_raw"` + FirstUrl string `json:"first_url"` } func (s Site) ToCooked() CookedSite { + splitUrls := lib.RemoveBlankStrings(strings.Split(s.Urls, ",")) + firstUrl := "" + if len(splitUrls) > 0 { + firstUrl = splitUrls[0] + } + return CookedSite{ - ID: s.ID, - Name: s.Name, - Url: s.Url, + ID: s.ID, + Name: s.Name, + Urls: splitUrls, + UrlsRaw: s.Urls, + FirstUrl: firstUrl, } } From 0e53f8b50d42f12ee042bcd082e5b8dcdefb4939 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Sun, 10 Oct 2021 00:04:33 +0800 Subject: [PATCH 036/349] New logic to get default site isoluted content. --- artalk-go.example.yml | 3 ++ cmd/_utils.go | 44 +++++++++++++++++++++++ cmd/root.go | 66 +++++++++++----------------------- config/config.go | 5 +-- http/api_admin_comment_del.go | 2 +- http/api_admin_comment_edit.go | 2 +- http/api_admin_importer.go | 2 +- http/api_admin_page_del.go | 2 +- http/api_admin_page_edit.go | 2 +- http/api_admin_page_fetch.go | 2 +- http/api_admin_page_get.go | 2 +- http/api_admin_site_edit.go | 39 ++++++++++---------- http/api_main_add.go | 2 +- http/api_main_get.go | 2 +- http/utils.go | 23 +++++++----- model/query.go | 26 ++++++++++++-- 16 files changed, 137 insertions(+), 87 deletions(-) create mode 100644 cmd/_utils.go diff --git a/artalk-go.example.yml b/artalk-go.example.yml index e8f32a303..f73dd9e40 100644 --- a/artalk-go.example.yml +++ b/artalk-go.example.yml @@ -24,6 +24,9 @@ log: allow_origin: - http://localhost:8080 # 或 '*' 跨域无限制 +# 默认站点名 +site_default: '默认站点' + # 管理员账户 admin_users: - diff --git a/cmd/_utils.go b/cmd/_utils.go new file mode 100644 index 000000000..56ecb97cc --- /dev/null +++ b/cmd/_utils.go @@ -0,0 +1,44 @@ +package cmd + +import ( + "github.com/spf13/cobra" + "github.com/spf13/viper" +) + +//// 捷径函数 //// + +func flag(cmd *cobra.Command, name string, defaultVal interface{}, usage string) { + f := cmd.PersistentFlags() + switch y := defaultVal.(type) { + case bool: + f.Bool(name, y, usage) + case int: + f.Int(name, y, usage) + case string: + f.String(name, y, usage) + } + viper.SetDefault(name, defaultVal) +} + +func flagP(cmd *cobra.Command, name, shorthand string, defaultVal interface{}, usage string) { + f := cmd.PersistentFlags() + switch y := defaultVal.(type) { + case bool: + f.BoolP(name, shorthand, y, usage) + case int: + f.IntP(name, shorthand, y, usage) + case string: + f.StringP(name, shorthand, y, usage) + } + viper.SetDefault(name, defaultVal) +} + +func flagV(cmd *cobra.Command, name string, defaultVal interface{}, usage string) { + flag(cmd, name, defaultVal, usage) + viper.BindPFlag(name, cmd.PersistentFlags().Lookup(name)) +} + +func flagPV(cmd *cobra.Command, name, shorthand string, defaultVal interface{}, usage string) { + flagP(cmd, name, shorthand, defaultVal, usage) + viper.BindPFlag(name, cmd.PersistentFlags().Lookup(name)) +} diff --git a/cmd/root.go b/cmd/root.go index bfd719315..ee0def797 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -3,6 +3,7 @@ package cmd import ( "fmt" "os" + "strings" "github.com/ArtalkJS/ArtalkGo/config" "github.com/ArtalkJS/ArtalkGo/lib" @@ -11,7 +12,6 @@ import ( "github.com/rifflock/lfshook" "github.com/sirupsen/logrus" "github.com/spf13/cobra" - "github.com/spf13/viper" prefixed "github.com/x-cray/logrus-prefixed-formatter" ) @@ -49,19 +49,25 @@ func init() { cobra.OnInitialize(initConfig) cobra.OnInitialize(initLog) cobra.OnInitialize(initDB) + cobra.OnInitialize(syncConfWithDB) cobra.OnInitialize(initCache) - cobra.OnInitialize(email.InitQueue) + cobra.OnInitialize(email.InitQueue) // 初始化邮件队列 rootCmd.SetVersionTemplate("Artalk-GO {{printf \"version %s\" .Version}}\n") rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "配置文件路径 (defaults are './artalk-go.yml')") } -// 初始化配置 +// 1. 初始化配置 func initConfig() { config.Init(cfgFile) + + // 检查 app_key 是否设置 + if strings.TrimSpace(config.Instance.AppKey) == "" { + logrus.Fatal("请检查配置文件,并设置一个 app_key (任意字符串) 用于数据加密") + } } -// 初始化日志 +// 2. 初始化日志 func initLog() { if !config.Instance.Log.Enabled { return @@ -106,6 +112,7 @@ func initLog() { } } +// 3. 初始化数据库 func initDB() { err := lib.OpenDB() if err != nil { @@ -115,12 +122,18 @@ func initDB() { // Migrate the schema lib.DB.AutoMigrate(&model.Site{}, &model.Page{}, &model.User{}, &model.Comment{}) // 注意表的创建顺序,因为有关联字段 - - syncConfWithDB() } -// 同步配置文件与数据库 +// 4. 同步配置文件与数据库 func syncConfWithDB() { + // 初始化默认站点 + siteDefault := strings.TrimSpace(config.Instance.SiteDefault) + if siteDefault == "" { + logrus.Error("请设置 SiteDefault 默认站点,不能为空") + os.Exit(1) + } + model.FindCreateSite(siteDefault) + // 导入配置文件的管理员用户 for _, admin := range config.Instance.AdminUsers { user := model.FindUser(admin.Name, admin.Email) @@ -168,6 +181,7 @@ func syncConfWithDB() { } } +// 5. 初始化缓存 func initCache() { err := lib.OpenCache() if err != nil { @@ -175,41 +189,3 @@ func initCache() { os.Exit(1) } } - -//// 捷径函数 //// - -func flag(cmd *cobra.Command, name string, defaultVal interface{}, usage string) { - f := cmd.PersistentFlags() - switch y := defaultVal.(type) { - case bool: - f.Bool(name, y, usage) - case int: - f.Int(name, y, usage) - case string: - f.String(name, y, usage) - } - viper.SetDefault(name, defaultVal) -} - -func flagP(cmd *cobra.Command, name, shorthand string, defaultVal interface{}, usage string) { - f := cmd.PersistentFlags() - switch y := defaultVal.(type) { - case bool: - f.BoolP(name, shorthand, y, usage) - case int: - f.IntP(name, shorthand, y, usage) - case string: - f.StringP(name, shorthand, y, usage) - } - viper.SetDefault(name, defaultVal) -} - -func flagV(cmd *cobra.Command, name string, defaultVal interface{}, usage string) { - flag(cmd, name, defaultVal, usage) - viper.BindPFlag(name, cmd.PersistentFlags().Lookup(name)) -} - -func flagPV(cmd *cobra.Command, name, shorthand string, defaultVal interface{}, usage string) { - flagP(cmd, name, shorthand, defaultVal, usage) - viper.BindPFlag(name, cmd.PersistentFlags().Lookup(name)) -} diff --git a/config/config.go b/config/config.go index 946e529c7..f7b54cf8d 100644 --- a/config/config.go +++ b/config/config.go @@ -25,6 +25,7 @@ type Config struct { DB DBConf `mapstructure:"db"` // 数据文件 Log LogConf `mapstructure:"log"` // 日志文件 AllowOrigin []string `mapstructure:"allow_origin"` // 允许跨域访问的域名 + SiteDefault string `mapstructure:"site_default"` // 默认站点名(当请求无指定 site_name 时使用) AdminUsers []AdminUserConf `mapstructure:"admin_users"` LoginTimeout int `mapstructure:"login_timeout"` Moderator ModeratorConf `mapstructure:"moderator"` @@ -133,10 +134,6 @@ func Init(cfgFile string) { } Flat = StructToFlatDotMap(&Instance) - - if strings.TrimSpace(Instance.AppKey) == "" { - logrus.Fatal("请检查配置文件,并设置一个 app_key") - } } func StructToMap(s interface{}) map[string]interface{} { diff --git a/http/api_admin_comment_del.go b/http/api_admin_comment_del.go index 00ae3ffba..c39012c6e 100644 --- a/http/api_admin_comment_del.go +++ b/http/api_admin_comment_del.go @@ -32,7 +32,7 @@ func ActionAdminCommentDel(c echo.Context) error { } // find site - if isOK, resp := CheckSite(c, p.SiteName, &p.SiteID); !isOK { + if isOK, resp := CheckSite(c, &p.SiteName, &p.SiteID); !isOK { return resp } diff --git a/http/api_admin_comment_edit.go b/http/api_admin_comment_edit.go index 1fb11d464..ea2448f3e 100644 --- a/http/api_admin_comment_edit.go +++ b/http/api_admin_comment_edit.go @@ -42,7 +42,7 @@ func ActionAdminCommentEdit(c echo.Context) error { } // find site - if isOK, resp := CheckSite(c, p.SiteName, &p.SiteID); !isOK { + if isOK, resp := CheckSite(c, &p.SiteName, &p.SiteID); !isOK { return resp } diff --git a/http/api_admin_importer.go b/http/api_admin_importer.go index 3362e7a51..d60204a62 100644 --- a/http/api_admin_importer.go +++ b/http/api_admin_importer.go @@ -54,7 +54,7 @@ func ActionAdminImporter(c echo.Context) error { } // find site - if isOK, resp := CheckSite(c, p.SiteName, &p.SiteID); !isOK { + if isOK, resp := CheckSite(c, &p.SiteName, &p.SiteID); !isOK { return resp } diff --git a/http/api_admin_page_del.go b/http/api_admin_page_del.go index af8d373c3..3705465f7 100644 --- a/http/api_admin_page_del.go +++ b/http/api_admin_page_del.go @@ -23,7 +23,7 @@ func ActionAdminPageDel(c echo.Context) error { } // find site - if isOK, resp := CheckSite(c, p.SiteName, &p.SiteID); !isOK { + if isOK, resp := CheckSite(c, &p.SiteName, &p.SiteID); !isOK { return resp } diff --git a/http/api_admin_page_edit.go b/http/api_admin_page_edit.go index d8595c878..c1c9ce1b2 100644 --- a/http/api_admin_page_edit.go +++ b/http/api_admin_page_edit.go @@ -28,7 +28,7 @@ func ActionAdminPageEdit(c echo.Context) error { } // find site - if isOK, resp := CheckSite(c, p.SiteName, &p.SiteID); !isOK { + if isOK, resp := CheckSite(c, &p.SiteName, &p.SiteID); !isOK { return resp } diff --git a/http/api_admin_page_fetch.go b/http/api_admin_page_fetch.go index b8569af72..d1c5d3076 100644 --- a/http/api_admin_page_fetch.go +++ b/http/api_admin_page_fetch.go @@ -22,7 +22,7 @@ func ActionAdminPageFetch(c echo.Context) error { } // find site - if isOK, resp := CheckSite(c, p.SiteName, &p.SiteID); !isOK { + if isOK, resp := CheckSite(c, &p.SiteName, &p.SiteID); !isOK { return resp } diff --git a/http/api_admin_page_get.go b/http/api_admin_page_get.go index 2e6c09635..946a56150 100644 --- a/http/api_admin_page_get.go +++ b/http/api_admin_page_get.go @@ -22,7 +22,7 @@ func ActionAdminPageGet(c echo.Context) error { } // find site - if isOK, resp := CheckSite(c, p.SiteName, &p.SiteID); !isOK { + if isOK, resp := CheckSite(c, &p.SiteName, &p.SiteID); !isOK { return resp } diff --git a/http/api_admin_site_edit.go b/http/api_admin_site_edit.go index 8736b4d12..f72e9d432 100644 --- a/http/api_admin_site_edit.go +++ b/http/api_admin_site_edit.go @@ -33,14 +33,13 @@ func ActionAdminSiteEdit(c echo.Context) error { return RespError(c, "site 名称不能为空白字符") } - modifyName := (p.Name != "" && p.Name != site.Name) + // 重命名合法性检测 + modifyName := p.Name != site.Name if modifyName && !model.FindSite(p.Name).IsEmpty() { return RespError(c, "site 已存在,请换个名称") } - site.Name = p.Name - site.Urls = p.Urls - + // urls 合法性检测 if p.Urls != "" { for _, url := range site.ToCooked().Urls { if !lib.ValidateURL(url) { @@ -49,29 +48,31 @@ func ActionAdminSiteEdit(c echo.Context) error { } } - err := lib.DB.Save(&site).Error - if err != nil { - return RespError(c, "site 保存失败") - } - // 同步变更 site_name if modifyName { var comments []model.Comment - lib.DB.Where("site_name = ?", p.Name).Find(&comments) + lib.DB.Where("site_name = ?", site.Name).Find(&comments) var pages []model.Page - lib.DB.Where("site_name = ?", p.Name).Find(&pages) + lib.DB.Where("site_name = ?", site.Name).Find(&pages) - tx := lib.DB.Begin() - for _, c := range comments { - c.SiteName = site.Name - tx.Save(&c) + for _, comment := range comments { + comment.SiteName = p.Name + lib.DB.Save(&comment) } - for _, p := range pages { - p.SiteName = site.Name - tx.Save(&p) + for _, page := range pages { + page.SiteName = p.Name + lib.DB.Save(&page) } - tx.Commit() + } + + // 修改 site + site.Name = p.Name + site.Urls = p.Urls + + err := lib.DB.Save(&site).Error + if err != nil { + return RespError(c, "site 保存失败") } return RespData(c, Map{ diff --git a/http/api_main_add.go b/http/api_main_add.go index 37dfd36a1..e1bd7293f 100644 --- a/http/api_main_add.go +++ b/http/api_main_add.go @@ -49,7 +49,7 @@ func ActionAdd(c echo.Context) error { RecordAction(c) // find site - if isOK, resp := CheckSite(c, p.SiteName, &p.SiteID); !isOK { + if isOK, resp := CheckSite(c, &p.SiteName, &p.SiteID); !isOK { return resp } diff --git a/http/api_main_get.go b/http/api_main_get.go index 2628dabaf..e540313ea 100644 --- a/http/api_main_get.go +++ b/http/api_main_get.go @@ -38,7 +38,7 @@ func ActionGet(c echo.Context) error { isMsgCenter := IsMsgCenter(p) // find site - if isOK, resp := CheckSite(c, p.SiteName, &p.SiteID); !isOK { + if isOK, resp := CheckSite(c, &p.SiteName, &p.SiteID); !isOK { return resp } diff --git a/http/utils.go b/http/utils.go index c5b587412..763888cc2 100644 --- a/http/utils.go +++ b/http/utils.go @@ -116,14 +116,13 @@ func CheckIfAllowed(c echo.Context, name string, email string, page model.Page, return true, nil } -func CheckReferer(c echo.Context, siteName string) (bool, error) { +func CheckReferer(c echo.Context, site model.Site) (bool, error) { isAdminReq := CheckIsAdminReq(c) - if isAdminReq || siteName == "" { + if isAdminReq || site.IsEmpty() { return true, nil } // 请求 Referer 合法性判断 - site := model.FindSite(siteName) if strings.TrimSpace(site.Urls) == "" { return true, nil // 若 url 字段为空,则取消控制 } @@ -160,22 +159,30 @@ func CheckReferer(c echo.Context, siteName string) (bool, error) { return true, nil } -func CheckSite(c echo.Context, siteName string, destID *uint) (bool, error) { - if siteName == "" { +func CheckSite(c echo.Context, siteName *string, destID *uint) (bool, error) { + if *siteName == "" { + // 传入值为空,使用默认 site + siteDefault := strings.TrimSpace(config.Instance.SiteDefault) + if siteDefault != "" { + // 没有则创建 + model.FindCreateSite(siteDefault) + } + *siteName = siteDefault // 更新原 name + return true, nil } - site := model.FindSite(siteName) + site := model.FindSite(*siteName) if site.IsEmpty() { return false, RespError(c, "Site 未找到") } // 检测 Referer 合法性 - if isOK, resp := CheckReferer(c, siteName); !isOK { + if isOK, resp := CheckReferer(c, site); !isOK { return false, resp } - *destID = site.ID + *destID = site.ID // 更新源 id return true, nil } diff --git a/model/query.go b/model/query.go index 36ad1e0a1..96d506903 100644 --- a/model/query.go +++ b/model/query.go @@ -45,6 +45,28 @@ func FindSiteByID(id uint) Site { return site } +func FindCreateSite(siteName string) Site { + site := FindSite(siteName) + if site.IsEmpty() { + site = NewSite(siteName, "") + } + return site +} + +func NewSite(name string, urls string) Site { + site := Site{ + Name: name, + Urls: urls, + } + + err := lib.DB.Create(&site).Error + if err != nil { + logrus.Error("Create Site error: ", err) + } + + return site +} + func FindCreatePage(pageKey string, pageUrl string, pageTitle string, siteName string) Page { page := FindPage(pageKey, siteName) if page.IsEmpty() { @@ -69,7 +91,7 @@ func NewUser(name string, email string) User { err := lib.DB.Create(&user).Error if err != nil { - logrus.Error("Save User error: ", err) + logrus.Error("Create User error: ", err) } return user @@ -107,7 +129,7 @@ func NewPage(key string, pageUrl string, pageTitle string, siteName string) Page err := lib.DB.Create(&page).Error if err != nil { - logrus.Error("Save Page error: ", err) + logrus.Error("Create Page error: ", err) } return page From 37d4084013857c083b07d6de8f1076afad0e5e57 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Sun, 10 Oct 2021 14:55:36 +0800 Subject: [PATCH 037/349] Remove Page model field & fix lots of bugs. --- go.mod | 1 + go.sum | 5 ++ http/api_admin_comment_del.go | 3 +- http/api_admin_comment_edit.go | 58 ++++------------ http/api_admin_importer.go | 119 ++++++++++++++++++++++----------- http/api_admin_page_del.go | 2 +- http/api_admin_page_edit.go | 46 ++++++++----- http/api_admin_page_fetch.go | 2 +- http/api_admin_page_get.go | 9 ++- http/api_admin_site_add.go | 4 ++ http/api_admin_site_edit.go | 5 +- http/api_main_add.go | 7 +- http/api_main_get.go | 71 +++++++++++++------- http/utils.go | 51 ++++++++++---- lib/constants.go | 6 ++ lib/utils.go | 5 -- model/comment.go | 10 +-- model/page.go | 23 +++++-- model/query.go | 14 ++-- 19 files changed, 273 insertions(+), 168 deletions(-) create mode 100644 lib/constants.go diff --git a/go.mod b/go.mod index 290e976ef..d5a1da047 100644 --- a/go.mod +++ b/go.mod @@ -5,6 +5,7 @@ go 1.16 require ( github.com/PuerkitoBio/goquery v1.7.1 // indirect github.com/allegro/bigcache/v3 v3.0.0 + github.com/araddon/dateparse v0.0.0-20210429162001-6b43995a97de // indirect github.com/eko/gocache/v2 v2.1.0 github.com/fsnotify/fsnotify v1.5.1 // indirect github.com/golang-jwt/jwt v3.2.2+incompatible diff --git a/go.sum b/go.sum index 79a9779c4..72d304ec3 100644 --- a/go.sum +++ b/go.sum @@ -69,6 +69,8 @@ github.com/andybalholm/cascadia v1.2.0/go.mod h1:YCyR8vOZT9aZ1CHEd8ap0gMVm2aFgxB github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= +github.com/araddon/dateparse v0.0.0-20210429162001-6b43995a97de h1:FxWPpzIjnTlhPwqqXc4/vE0f7GvRjuAsbW+HOIe8KnA= +github.com/araddon/dateparse v0.0.0-20210429162001-6b43995a97de/go.mod h1:DCaWoUhZrYW9p1lxo/cm8EmUOOzAPSEZNGF2DK1dJgw= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= @@ -438,6 +440,7 @@ github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Ky github.com/mattn/go-isatty v0.0.13 h1:qdl+GuBjcsKKDco5BsxPJlId98mSWNKqYA+Co0SC1yA= github.com/mattn/go-isatty v0.0.13/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= +github.com/mattn/go-runewidth v0.0.10/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk= github.com/mattn/go-sqlite3 v1.14.5/go.mod h1:WVKg1VTActs4Qso6iwGbiFih2UIHo0ENGwNd0Lj+XmI= github.com/mattn/go-sqlite3 v1.14.8 h1:gDp86IdQsN/xWjIEmr9MF6o9mpksUgh0fu+9ByFxzIU= github.com/mattn/go-sqlite3 v1.14.8/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= @@ -562,6 +565,7 @@ github.com/qwqcode/go-aliyun-email v0.0.0-20180120030821-cb6e7b1382bf/go.mod h1: github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/rifflock/lfshook v0.0.0-20180920164130-b9218ef580f5 h1:mZHayPoR0lNmnHyvtYjDeq0zlVHn9K/ZXoy17ylucdo= github.com/rifflock/lfshook v0.0.0-20180920164130-b9218ef580f5/go.mod h1:GEXHk5HgEKCvEIIrSpFI3ozzG5xOKA2DVlEX/gGnewM= +github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= @@ -572,6 +576,7 @@ github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQD github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= +github.com/scylladb/termtables v0.0.0-20191203121021-c4c0b6d42ff4/go.mod h1:C1a7PQSMz9NShzorzCiG2fk9+xuCgLkPeCvMHYR2OWg= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4= github.com/shopspring/decimal v0.0.0-20200227202807-02e2044944cc h1:jUIKcSPO9MoMJBbEoyE/RJoE8vz7Mb8AjvifMMwSyvY= diff --git a/http/api_admin_comment_del.go b/http/api_admin_comment_del.go index c39012c6e..751e74162 100644 --- a/http/api_admin_comment_del.go +++ b/http/api_admin_comment_del.go @@ -14,6 +14,7 @@ type ParamsCommentDel struct { SiteName string `mapstructure:"site_name"` SiteID uint + SiteAll bool } func ActionAdminCommentDel(c echo.Context) error { @@ -32,7 +33,7 @@ func ActionAdminCommentDel(c echo.Context) error { } // find site - if isOK, resp := CheckSite(c, &p.SiteName, &p.SiteID); !isOK { + if isOK, resp := CheckSite(c, &p.SiteName, &p.SiteID, &p.SiteAll); !isOK { return resp } diff --git a/http/api_admin_comment_edit.go b/http/api_admin_comment_edit.go index ea2448f3e..7a9ccce1a 100644 --- a/http/api_admin_comment_edit.go +++ b/http/api_admin_comment_edit.go @@ -9,7 +9,7 @@ import ( type ParamsCommentEdit struct { // 查询值 - ID string `mapstructure:"id" param:"required"` + ID uint `mapstructure:"id" param:"required"` SiteName string `mapstructure:"site_name"` SiteID uint @@ -22,8 +22,8 @@ type ParamsCommentEdit struct { Rid string `mapstructure:"rid"` UA string `mapstructure:"ua"` IP string `mapstructure:"ip"` - IsCollapsed string `mapstructure:"is_collapsed"` - IsPending string `mapstructure:"is_pending"` + IsCollapsed bool `mapstructure:"is_collapsed"` + IsPending bool `mapstructure:"is_pending"` } func ActionAdminCommentEdit(c echo.Context) error { @@ -36,17 +36,12 @@ func ActionAdminCommentEdit(c echo.Context) error { return resp } - id, err := strconv.Atoi(p.ID) - if err != nil { - return RespError(c, "invalid id") - } - // find site - if isOK, resp := CheckSite(c, &p.SiteName, &p.SiteID); !isOK { + if isOK, resp := CheckSite(c, &p.SiteName, &p.SiteID, nil); !isOK { return resp } - comment := model.FindComment(uint(id), p.SiteName) + comment := model.FindComment(p.ID, p.SiteName) if comment.IsEmpty() { return RespError(c, "comment not found") } @@ -70,48 +65,21 @@ func ActionAdminCommentEdit(c echo.Context) error { comment.UserID = user.ID } } - if p.Link != "" { + if p.Link != "" && p.Link != comment.User.Link { comment.User.Link = p.Link model.UpdateUser(&comment.User) } // pageKey - if p.PageKey != "" { - if p.PageKey != comment.PageKey { - model.FindCreatePage(p.PageKey, "", "", p.SiteName) - comment.PageKey = p.PageKey - } - } - - // ua - if p.UA != "" { - comment.UA = p.UA - } - - // ip - if p.IP != "" { - comment.IP = p.IP - } - - // is_collapsed - if p.IsCollapsed != "" { - switch p.IsCollapsed { - case "1": - comment.IsCollapsed = true - case "0": - comment.IsCollapsed = false - } + if p.PageKey != "" && p.PageKey != comment.PageKey { + model.FindCreatePage(p.PageKey, "", p.SiteName) + comment.PageKey = p.PageKey } - // is_pending - if p.IsPending != "" { - switch p.IsPending { - case "1": - comment.IsPending = true - case "0": - comment.IsPending = false - } - } + comment.UA = p.UA + comment.IP = p.IP + comment.IsCollapsed = p.IsCollapsed + comment.IsPending = p.IsPending if err := model.UpdateComment(&comment); err != nil { return RespError(c, "comment save error") diff --git a/http/api_admin_importer.go b/http/api_admin_importer.go index d60204a62..bf7c018f9 100644 --- a/http/api_admin_importer.go +++ b/http/api_admin_importer.go @@ -7,25 +7,11 @@ import ( "github.com/ArtalkJS/ArtalkGo/lib" "github.com/ArtalkJS/ArtalkGo/model" + "github.com/araddon/dateparse" "github.com/labstack/echo/v4" "github.com/sirupsen/logrus" ) -type ArtalkV1_Comment struct { - ID uint `json:"id"` - Content string `json:"content"` - Nick string `json:"nick"` - Email string `json:"email"` - Link string `json:"link"` - UA string `json:"ua"` - PageKey string `json:"page_key"` - Rid uint `json:"rid"` - IP string `json:"ip"` - Date string `json:"date"` - IsPending bool `json:"is_pending"` - IsCollapsed bool `json:"is_collapsed"` -} - type ParamsAdminImporter struct { Type string `mapstructure:"type" param:"required"` Data string `mapstructure:"data" param:"required"` @@ -54,52 +40,107 @@ func ActionAdminImporter(c echo.Context) error { } // find site - if isOK, resp := CheckSite(c, &p.SiteName, &p.SiteID); !isOK { + if isOK, resp := CheckSite(c, &p.SiteName, &p.SiteID, nil); !isOK { return resp } + // 数据导入注意事项: + // 1. 记得恢复创建/更新时间 + // 2. 因为是数据追加模式,ID 会发生变动,需更新 rid + + errs := []string{} + dbResultLog := func(name string, err error) { + if err != nil { + logrus.Error("Save Comment error: ", err) + errs = append(errs, fmt.Sprintf("%s: %s", name, err.Error())) + } + } + + idChanges := map[uint]uint{} // comment_id: old => new + switch p.Type { + // Artalk v1 数据源 case "artalk_v1": - var comments []ArtalkV1_Comment - err := json.Unmarshal([]byte(p.Data), &comments) + // 解析数据源 + var v1Comments []ArtalkV1_Comment + err := json.Unmarshal([]byte(p.Data), &v1Comments) if err != nil { return RespError(c, "json unmarshal err:"+err.Error()) } - errs := []string{} - for _, c := range comments { - page := model.FindCreatePage(c.PageKey, "", "", p.SiteName) - user := model.FindCreateUser(c.Nick, c.Email) + for _, oc := range v1Comments { + if strings.TrimSpace(oc.Content) == "" { + continue + } + + // 创建 page 和 user + page := model.FindCreatePage(oc.PageKey, "", p.SiteName) + user := model.FindCreateUser(oc.Nick, oc.Email) - user.Link = c.Link - user.LastIP = c.IP - user.LastUA = c.UA + user.Link = oc.Link + user.LastIP = oc.IP + user.LastUA = oc.UA model.UpdateUser(&user) + // 创建新 comment 实例 nComment := model.Comment{ - Content: c.Content, - Rid: c.Rid, + Content: oc.Content, + Rid: oc.Rid, UserID: user.ID, PageKey: page.Key, - IP: c.IP, - UA: c.UA, - IsPending: c.IsPending, - IsCollapsed: c.IsCollapsed, + IP: oc.IP, + UA: oc.UA, + IsPending: oc.IsPending, + IsCollapsed: oc.IsCollapsed, SiteName: p.SiteName, } + // 日期恢复 + t, _ := dateparse.ParseAny(oc.Date) + nComment.CreatedAt = t + nComment.UpdatedAt = t + + // 保存到数据库 err := lib.DB.Create(&nComment).Error - if err != nil { - logrus.Error("Save Comment error: ", err) - errs = append(errs, fmt.Sprintf("%d: %s", c.ID, err.Error())) - } + dbResultLog(fmt.Sprintf("保存 old_id:%d new_id:%d", oc.ID, nComment.ID), err) + + idChanges[oc.ID] = nComment.ID } - if len(errs) != 0 { - return RespError(c, "导入发生错误:"+strings.Join(errs, "\n")) + // reply id 重建 + for _, oc := range v1Comments { + if oc.Rid != 0 { + if _, isExist := idChanges[oc.ID]; !isExist { + continue + } + + nComment := model.FindComment(idChanges[oc.ID], p.SiteName) + nComment.Rid = idChanges[oc.Rid] + err := lib.DB.Save(&nComment).Error + dbResultLog(fmt.Sprintf("rid 更新 new_id:%d new_rid:%d", nComment.ID, idChanges[oc.Rid]), err) + } } - return RespSuccess(c) + default: + return RespError(c, "invalid type") } - return RespError(c, "invalid type") + if len(errs) != 0 { + return RespError(c, "导入发生错误:"+strings.Join(errs, "\n")) + } + return RespSuccess(c) +} + +type ArtalkV1_Comment struct { + ID uint `json:"id"` + Content string `json:"content"` + Nick string `json:"nick"` + Email string `json:"email"` + Link string `json:"link"` + UA string `json:"ua"` + PageKey string `json:"page_key"` + Rid uint `json:"rid"` + IP string `json:"ip"` + Date string `json:"date"` + IsPending bool `json:"is_pending"` + IsCollapsed bool `json:"is_collapsed"` } diff --git a/http/api_admin_page_del.go b/http/api_admin_page_del.go index 3705465f7..63b5ef028 100644 --- a/http/api_admin_page_del.go +++ b/http/api_admin_page_del.go @@ -23,7 +23,7 @@ func ActionAdminPageDel(c echo.Context) error { } // find site - if isOK, resp := CheckSite(c, &p.SiteName, &p.SiteID); !isOK { + if isOK, resp := CheckSite(c, &p.SiteName, &p.SiteID, nil); !isOK { return resp } diff --git a/http/api_admin_page_edit.go b/http/api_admin_page_edit.go index c1c9ce1b2..aa236a493 100644 --- a/http/api_admin_page_edit.go +++ b/http/api_admin_page_edit.go @@ -1,20 +1,23 @@ package http import ( + "strings" + + "github.com/ArtalkJS/ArtalkGo/lib" "github.com/ArtalkJS/ArtalkGo/model" "github.com/labstack/echo/v4" ) type ParamsAdminPageEdit struct { // 查询值 - Key string `mapstructure:"key" param:"required"` + ID uint `mapstructure:"id" param:"required"` SiteName string `mapstructure:"site_name"` SiteID uint // 修改值 - Url string `mapstructure:"url"` + Key string `mapstructure:"key"` Title string `mapstructure:"title"` - AdminOnly string `mapstructure:"admin_only"` + AdminOnly bool `mapstructure:"admin_only"` } func ActionAdminPageEdit(c echo.Context) error { @@ -27,32 +30,39 @@ func ActionAdminPageEdit(c echo.Context) error { return resp } + if strings.TrimSpace(p.Key) == "" { + return RespError(c, "page key 不能为空白字符") + } + // find site - if isOK, resp := CheckSite(c, &p.SiteName, &p.SiteID); !isOK { + if isOK, resp := CheckSite(c, &p.SiteName, &p.SiteID, nil); !isOK { return resp } - page := model.FindPage(p.Key, p.SiteName) + page := model.FindPageByID(p.ID, p.SiteName) if page.IsEmpty() { return RespError(c, "page not found") } - // url - if p.Url != "" { - page.Url = p.Url + // 重命名合法性检测 + modifyKey := p.Key != page.Key + if modifyKey && !model.FindPage(p.Key, p.SiteName).IsEmpty() { + return RespError(c, "page 已存在,请换个 key") } - // title - if p.Title != "" { - page.Title = p.Title - } + page.Title = p.Title + page.AdminOnly = p.AdminOnly + if modifyKey { + // 相关性数据修改 + var comments []model.Comment + lib.DB.Where("page_key = ?", page.Key).Find(&comments) + + for _, comment := range comments { + comment.PageKey = p.Key + lib.DB.Save(&comment) + } - // only_admin - switch p.AdminOnly { - case "1": - page.AdminOnly = true - case "0": - page.AdminOnly = false + page.Key = p.Key } if err := model.UpdatePage(&page); err != nil { diff --git a/http/api_admin_page_fetch.go b/http/api_admin_page_fetch.go index d1c5d3076..d384b6b5e 100644 --- a/http/api_admin_page_fetch.go +++ b/http/api_admin_page_fetch.go @@ -22,7 +22,7 @@ func ActionAdminPageFetch(c echo.Context) error { } // find site - if isOK, resp := CheckSite(c, &p.SiteName, &p.SiteID); !isOK { + if isOK, resp := CheckSite(c, &p.SiteName, &p.SiteID, nil); !isOK { return resp } diff --git a/http/api_admin_page_get.go b/http/api_admin_page_get.go index 946a56150..e8ecfc3d2 100644 --- a/http/api_admin_page_get.go +++ b/http/api_admin_page_get.go @@ -9,6 +9,7 @@ import ( type ParamsAdminPageGet struct { SiteName string `mapstructure:"site_name"` SiteID uint + SiteAll bool } func ActionAdminPageGet(c echo.Context) error { @@ -22,12 +23,16 @@ func ActionAdminPageGet(c echo.Context) error { } // find site - if isOK, resp := CheckSite(c, &p.SiteName, &p.SiteID); !isOK { + if isOK, resp := CheckSite(c, &p.SiteName, &p.SiteID, &p.SiteAll); !isOK { return resp } var pages []model.Page - lib.DB.Model(&model.Page{}).Where("site_name = ?", p.SiteName).Find(&pages) + query := lib.DB.Model(&model.Page{}) + if !p.SiteAll { // 不是查的所有站点 + query = query.Where("site_name = ?", p.SiteName) + } + query.Find(&pages) var cookedPages []model.CookedPage for _, p := range pages { diff --git a/http/api_admin_site_add.go b/http/api_admin_site_add.go index b46c926d2..a763fa2f6 100644 --- a/http/api_admin_site_add.go +++ b/http/api_admin_site_add.go @@ -25,6 +25,10 @@ func ActionAdminSiteAdd(c echo.Context) error { return RespError(c, "Invalid url") } + if p.Name == lib.ATK_SITE_ALL { + return RespError(c, "禁止使用保留关键字作为名称") + } + if !model.FindSite(p.Name).IsEmpty() { return RespError(c, "site 已存在") } diff --git a/http/api_admin_site_edit.go b/http/api_admin_site_edit.go index f72e9d432..49fa9a655 100644 --- a/http/api_admin_site_edit.go +++ b/http/api_admin_site_edit.go @@ -9,7 +9,10 @@ import ( ) type ParamsAdminSiteEdit struct { - ID uint `mapstructure:"id" param:"required"` + // 查询值 + ID uint `mapstructure:"id" param:"required"` + + // 修改值 Name string `mapstructure:"name"` Urls string `mapstructure:"urls"` } diff --git a/http/api_main_add.go b/http/api_main_add.go index e1bd7293f..252fb8bb6 100644 --- a/http/api_main_add.go +++ b/http/api_main_add.go @@ -17,7 +17,6 @@ type ParamsAdd struct { Rid uint `mapstructure:"rid"` PageKey string `mapstructure:"page_key" param:"required"` - PageUrl string `mapstructure:"page_url"` PageTitle string `mapstructure:"page_title"` Token string `mapstructure:"token"` @@ -49,12 +48,12 @@ func ActionAdd(c echo.Context) error { RecordAction(c) // find site - if isOK, resp := CheckSite(c, &p.SiteName, &p.SiteID); !isOK { + if isOK, resp := CheckSite(c, &p.SiteName, &p.SiteID, nil); !isOK { return resp } // find page - page := model.FindCreatePage(p.PageKey, p.PageUrl, p.PageTitle, p.SiteName) + page := model.FindCreatePage(p.PageKey, p.PageTitle, p.SiteName) // check if the user is allowed to comment if isAllowed, resp := CheckIfAllowed(c, p.Name, p.Email, page, p.SiteName); !isAllowed { @@ -120,7 +119,7 @@ func ActionAdd(c echo.Context) error { email.SendToAdmin(comment.ToCookedForEmail()) // 发送邮件给管理员 // fetch page url data - if page.Url != "" && page.Title == "" { + if page.ToCooked().URL != "" && page.Title == "" { go func() { page.FetchURL() }() diff --git a/http/api_main_get.go b/http/api_main_get.go index e540313ea..dd19b4372 100644 --- a/http/api_main_get.go +++ b/http/api_main_get.go @@ -21,6 +21,7 @@ type ParamsGet struct { SiteName string `mapstructure:"site_name"` SiteID uint + SiteAll bool } type ResponseGet struct { @@ -30,6 +31,17 @@ type ResponseGet struct { Page model.CookedPage `json:"page"` } +// 获取评论查询实例 +func GetCommentQuery(c echo.Context, p ParamsGet, siteID uint) *gorm.DB { + query := lib.DB.Model(&model.Comment{}).Order("created_at DESC") + + if IsMsgCenter(p) { + return query.Scopes(MsgCenter(c, p, siteID), SiteIsolation(c, p)) + } + + return query.Where("page_key = ?", p.PageKey).Scopes(SiteIsolation(c, p), AllowedComment(c, p)) +} + func ActionGet(c echo.Context) error { var p ParamsGet if isOK, resp := ParamsDecode(c, ParamsGet{}, &p); !isOK { @@ -38,12 +50,15 @@ func ActionGet(c echo.Context) error { isMsgCenter := IsMsgCenter(p) // find site - if isOK, resp := CheckSite(c, &p.SiteName, &p.SiteID); !isOK { + if isOK, resp := CheckSite(c, &p.SiteName, &p.SiteID, &p.SiteAll); !isOK { return resp } // find page - page := model.FindPage(p.PageKey, p.SiteName) + var page model.Page + if !p.SiteAll { + page = model.FindPage(p.PageKey, p.SiteName) + } // comment parents var comments []model.Comment @@ -61,7 +76,7 @@ func ActionGet(c echo.Context) error { // comment children for _, parent := range comments { // TODO: Read more children, pagination for children comment - children := parent.FetchChildren(AllowedComment(c)) + children := parent.FetchChildren(SiteIsolation(c, p), AllowedComment(c, p)) for _, child := range children { cookedComments = append(cookedComments, child.ToCooked()) } @@ -84,12 +99,12 @@ func ActionGet(c echo.Context) error { } // find linked comments - for _, c := range comments { - if c.Rid == 0 || containsComment(c.Rid) { + for _, comment := range comments { + if comment.Rid == 0 || containsComment(comment.Rid) { continue } - rComment := model.FindComment(c.Rid, p.SiteName) // 查找被回复的评论 + rComment := model.FindCommentScopes(comment.Rid, SiteIsolation(c, p)) // 查找被回复的评论 if rComment.IsEmpty() { continue } @@ -111,16 +126,7 @@ func ActionGet(c echo.Context) error { }) } -func GetCommentQuery(c echo.Context, p ParamsGet, siteID uint) *gorm.DB { - query := lib.DB.Model(&model.Comment{}).Order("created_at DESC") - - if IsMsgCenter(p) { - return query.Scopes(MsgCenter(c, p, siteID)) - } - - return query.Where("page_key = ? AND site_name = ?", p.PageKey, p.SiteName).Scopes(AllowedComment(c)) -} - +// 请求是否为 通知中心数据 func IsMsgCenter(p ParamsGet) bool { return p.Name != "" && p.Email != "" && p.Type != "" } @@ -129,15 +135,10 @@ func IsMsgCenter(p ParamsGet) bool { func MsgCenter(c echo.Context, p ParamsGet, siteID uint) func(db *gorm.DB) *gorm.DB { return func(db *gorm.DB) *gorm.DB { user := model.FindUser(p.Name, p.Email) - - // 站点隔离 isAdminReq := CheckIsAdminReq(c) - if !isAdminReq || (isAdminReq && p.SiteName != "") { - db = db.Where("site_name = ?", p.SiteName) - } // admin_only 检测 - if strings.HasPrefix(p.Type, "admin_") && !CheckIsAdminReq(c) { + if strings.HasPrefix(p.Type, "admin_") && !isAdminReq { db = db.Where("id = 0") return db } @@ -172,12 +173,14 @@ func MsgCenter(c echo.Context, p ParamsGet, siteID uint) func(db *gorm.DB) *gorm } } +// 评论计数 func CountComments(db *gorm.DB) int64 { var count int64 db.Count(&count) return count } +// 分页 func Paginate(offset int, limit int) func(db *gorm.DB) *gorm.DB { if offset < 0 { offset = 0 @@ -194,13 +197,33 @@ func Paginate(offset int, limit int) func(db *gorm.DB) *gorm.DB { } } -func AllowedComment(c echo.Context) func(db *gorm.DB) *gorm.DB { +// 允许的评论 +func AllowedComment(c echo.Context, p ParamsGet) func(db *gorm.DB) *gorm.DB { return func(db *gorm.DB) *gorm.DB { if CheckIsAdminReq(c) { return db // 管理员显示全部 } - return db.Where("is_pending = 0") + // 显示个人全部评论 + if p.Name != "" && p.Email != "" { + user := model.FindUser(p.Name, p.Email) + if !user.IsEmpty() { + return db.Where("is_pending = 0 OR (is_pending = 1 AND user_id = ?)", user.ID) + } + } + + return db.Where("is_pending = 0") // 不允许待审评论 + } +} + +// 站点隔离 +func SiteIsolation(c echo.Context, p ParamsGet) func(db *gorm.DB) *gorm.DB { + return func(db *gorm.DB) *gorm.DB { + if CheckIsAdminReq(c) && p.SiteAll { + return db // 仅管理员支持取消站点隔离 + } + + return db.Where("site_name = ?", p.SiteName) } } diff --git a/http/utils.go b/http/utils.go index 763888cc2..d8e9c79ac 100644 --- a/http/utils.go +++ b/http/utils.go @@ -1,6 +1,7 @@ package http import ( + "fmt" "net/url" "reflect" "strconv" @@ -8,6 +9,7 @@ import ( "time" "github.com/ArtalkJS/ArtalkGo/config" + "github.com/ArtalkJS/ArtalkGo/lib" "github.com/ArtalkJS/ArtalkGo/model" "github.com/golang-jwt/jwt" "github.com/labstack/echo/v4" @@ -72,23 +74,34 @@ func ParamsDecode(c echo.Context, paramsStruct interface{}, destParams interface }() // check required param - if paramName != "" && paramTagP == "required" { + requiredField := paramName != "" && paramTagP == "required" + if requiredField { if strings.TrimSpace(paramVal) == "" { return false, RespError(c, "Param `"+paramName+"` is required") } } + typeString := field.Type.Kind() == reflect.String + typeInt := field.Type.Kind() == reflect.Int + typeUint := field.Type.Kind() == reflect.Uint + typeBool := field.Type.Kind() == reflect.Bool + // convert type - if field.Type.Kind() == reflect.String { + if typeString { params[paramName] = paramVal - } else if field.Type.Kind() == reflect.Int { - u64, _ := strconv.ParseInt(paramVal, 10, 32) - params[paramName] = int(u64) - } else if field.Type.Kind() == reflect.Uint { - u64, _ := strconv.ParseUint(paramVal, 10, 32) - params[paramName] = uint(u64) - } else if field.Type.Kind() == reflect.Bool { + } else if typeBool { params[paramName] = (paramVal == "1") + } else if typeInt || typeUint { + u64, err := strconv.ParseInt(paramVal, 10, 32) + if requiredField && (err != nil || u64 == 0) { + return false, RespError(c, "Param `"+paramName+"` is required") + } + + if typeUint { + params[paramName] = uint(u64) + } else { + params[paramName] = int(u64) + } } // } else if field.Type.Kind() == reflect.Array { // params[paramName] = c.QueryParams()[paramName] @@ -159,7 +172,21 @@ func CheckReferer(c echo.Context, site model.Site) (bool, error) { return true, nil } -func CheckSite(c echo.Context, siteName *string, destID *uint) (bool, error) { +func CheckSite(c echo.Context, siteName *string, destID *uint, destSiteAll *bool) (bool, error) { + // 启用源 SiteAll + if destSiteAll != nil { + // 传入站点名参数 == "__ATK_SITE_ALL" 时取消站点隔离 + if *siteName == lib.ATK_SITE_ALL { + if !CheckIsAdminReq(c) { + return false, RespError(c, "仅管理员查询允许取消站点隔离") + } + *destSiteAll = true + return true, nil + } else { + *destSiteAll = false + } + } + if *siteName == "" { // 传入值为空,使用默认 site siteDefault := strings.TrimSpace(config.Instance.SiteDefault) @@ -167,14 +194,14 @@ func CheckSite(c echo.Context, siteName *string, destID *uint) (bool, error) { // 没有则创建 model.FindCreateSite(siteDefault) } - *siteName = siteDefault // 更新原 name + *siteName = siteDefault // 更新源 name return true, nil } site := model.FindSite(*siteName) if site.IsEmpty() { - return false, RespError(c, "Site 未找到") + return false, RespError(c, fmt.Sprintf("未找到站点:`%s`,请控制台创建站点", *siteName)) } // 检测 Referer 合法性 diff --git a/lib/constants.go b/lib/constants.go new file mode 100644 index 000000000..0efd83373 --- /dev/null +++ b/lib/constants.go @@ -0,0 +1,6 @@ +package lib + +// Artalk 保留关键字 + +// 所有站点 +const ATK_SITE_ALL = "__ATK_SITE_ALL" diff --git a/lib/utils.go b/lib/utils.go index 075a67efc..26ab10000 100644 --- a/lib/utils.go +++ b/lib/utils.go @@ -112,11 +112,6 @@ func RemoveBlankStrings(s []string) []string { return r } -func IsUrlValid(urlStr string) bool { - _, err := url.ParseRequestURI(urlStr) - return err != nil -} - func ValidateEmail(email string) bool { _, err := mail.ParseAddress(email) return err == nil diff --git a/model/comment.go b/model/comment.go index f2c0a3219..509bb2ba4 100644 --- a/model/comment.go +++ b/model/comment.go @@ -59,19 +59,19 @@ func (c *Comment) FetchPage() Page { return page } -func (c Comment) FetchChildren(filter func(db *gorm.DB) *gorm.DB) []Comment { +func (c Comment) FetchChildren(filters ...func(db *gorm.DB) *gorm.DB) []Comment { children := []Comment{} - fetchChildrenOnce(&children, c, filter) // TODO: children 数量限制 + fetchChildrenOnce(&children, c, filters...) // TODO: children 数量限制 return children } -func fetchChildrenOnce(src *[]Comment, parentComment Comment, filter func(db *gorm.DB) *gorm.DB) { +func fetchChildrenOnce(src *[]Comment, parentComment Comment, filters ...func(db *gorm.DB) *gorm.DB) { children := []Comment{} - lib.DB.Scopes(filter).Where("rid = ?", parentComment.ID).Order("created_at ASC").Find(&children) + lib.DB.Scopes(filters...).Where("rid = ?", parentComment.ID).Order("created_at ASC").Find(&children) for _, child := range children { *src = append(*src, child) - fetchChildrenOnce(src, child, filter) // loop + fetchChildrenOnce(src, child, filters...) // loop } } diff --git a/model/page.go b/model/page.go index 05cbc4086..b394308eb 100644 --- a/model/page.go +++ b/model/page.go @@ -2,6 +2,7 @@ package model import ( "errors" + "fmt" "net/http" "github.com/ArtalkJS/ArtalkGo/lib" @@ -12,9 +13,8 @@ import ( type Page struct { gorm.Model - Key string `gorm:"uniqueIndex"` + Key string `gorm:"uniqueIndex"` // 页面 Key(一般为不含 hash/query 的完整 url) Title string - Url string AdminOnly bool SiteName string `gorm:"index"` @@ -35,30 +35,41 @@ type CookedPage struct { } func (p Page) ToCooked() CookedPage { + url := "" + if lib.ValidateURL(p.Key) { + url = p.Key + } + return CookedPage{ ID: p.ID, AdminOnly: p.AdminOnly, Key: p.Key, - URL: p.Url, + URL: url, Title: p.Title, SiteName: p.SiteName, } } func (p *Page) FetchURL() error { - if !lib.IsUrlValid(p.Url) { + cookedPage := p.ToCooked() + url := cookedPage.URL + + if url == "" { + return errors.New("URL is null") + } + if !lib.ValidateURL(url) { return errors.New("URL is invalid") } // Request the HTML page. - res, err := http.Get(p.Url) + res, err := http.Get(url) if err != nil { logrus.Error(err) return err } defer res.Body.Close() if res.StatusCode != 200 { - logrus.Error("status code error: %d %s", res.StatusCode, res.Status) + logrus.Error(fmt.Sprintf("status code error: %d '%s' '%s'", res.StatusCode, res.Status, url)) return errors.New("status code error") } diff --git a/model/query.go b/model/query.go index 96d506903..0ef3561c1 100644 --- a/model/query.go +++ b/model/query.go @@ -3,6 +3,7 @@ package model import ( "github.com/ArtalkJS/ArtalkGo/lib" "github.com/sirupsen/logrus" + "gorm.io/gorm" "gorm.io/gorm/clause" ) @@ -12,6 +13,12 @@ func FindComment(id uint, siteName string) Comment { return comment } +func FindCommentScopes(id uint, filters ...func(db *gorm.DB) *gorm.DB) Comment { + var comment Comment + lib.DB.Preload(clause.Associations).Where("id = ?", id).Scopes(filters...).First(&comment) + return comment +} + // 查找用户(返回:精确查找 AND) func FindUser(name string, email string) User { var user User @@ -67,10 +74,10 @@ func NewSite(name string, urls string) Site { return site } -func FindCreatePage(pageKey string, pageUrl string, pageTitle string, siteName string) Page { +func FindCreatePage(pageKey string, pageTitle string, siteName string) Page { page := FindPage(pageKey, siteName) if page.IsEmpty() { - page = NewPage(pageKey, pageUrl, pageTitle, siteName) + page = NewPage(pageKey, pageTitle, siteName) } return page } @@ -119,10 +126,9 @@ func FindPageByID(id uint, siteName string) Page { return page } -func NewPage(key string, pageUrl string, pageTitle string, siteName string) Page { +func NewPage(key string, pageTitle string, siteName string) Page { page := Page{ Key: key, - Url: pageUrl, Title: pageTitle, SiteName: siteName, } From 772288dbaf484df5af19f51b018401f9d89a2370 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Sun, 10 Oct 2021 15:07:24 +0800 Subject: [PATCH 038/349] Add timezone config item. --- artalk-go.example.yml | 3 +++ cmd/root.go | 10 ++++++++++ config/config.go | 1 + http/api_admin_importer.go | 6 +++++- 4 files changed, 19 insertions(+), 1 deletion(-) diff --git a/artalk-go.example.yml b/artalk-go.example.yml index f73dd9e40..5f12be5bd 100644 --- a/artalk-go.example.yml +++ b/artalk-go.example.yml @@ -10,6 +10,9 @@ app_key: '' # 调试模式 debug: false +# 时区 +timezone: 'Asia/Shanghai' + # 数据文件 db: type: 'sqlite' # 支持 mysql, sqlite, pgsql, sqlserver diff --git a/cmd/root.go b/cmd/root.go index ee0def797..1d9a272a8 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -4,6 +4,7 @@ import ( "fmt" "os" "strings" + "time" "github.com/ArtalkJS/ArtalkGo/config" "github.com/ArtalkJS/ArtalkGo/lib" @@ -61,9 +62,18 @@ func init() { func initConfig() { config.Init(cfgFile) + // 设置时区 + if strings.TrimSpace(config.Instance.TimeZone) == "" { + logrus.Fatal("请检查配置文件,并设置 timezone") + os.Exit(1) + } + denverLoc, _ := time.LoadLocation(config.Instance.TimeZone) + time.Local = denverLoc + // 检查 app_key 是否设置 if strings.TrimSpace(config.Instance.AppKey) == "" { logrus.Fatal("请检查配置文件,并设置一个 app_key (任意字符串) 用于数据加密") + os.Exit(1) } } diff --git a/config/config.go b/config/config.go index f7b54cf8d..9c14d76d7 100644 --- a/config/config.go +++ b/config/config.go @@ -21,6 +21,7 @@ type Config struct { SiteName string `mapstructure:"site_name"` // 网站名 AppKey string `mapstructure:"app_key"` // 加密密钥 Debug bool `mapstructure:"debug"` // 调试模式 + TimeZone string `mapstructure:"timezone"` // 时区 HttpAddr string `mapstructure:"http_addr"` // HTTP Server 监听地址 DB DBConf `mapstructure:"db"` // 数据文件 Log LogConf `mapstructure:"log"` // 日志文件 diff --git a/http/api_admin_importer.go b/http/api_admin_importer.go index bf7c018f9..aaf4e9e7e 100644 --- a/http/api_admin_importer.go +++ b/http/api_admin_importer.go @@ -4,7 +4,9 @@ import ( "encoding/json" "fmt" "strings" + "time" + "github.com/ArtalkJS/ArtalkGo/config" "github.com/ArtalkJS/ArtalkGo/lib" "github.com/ArtalkJS/ArtalkGo/model" "github.com/araddon/dateparse" @@ -96,7 +98,9 @@ func ActionAdminImporter(c echo.Context) error { } // 日期恢复 - t, _ := dateparse.ParseAny(oc.Date) + denverLoc, _ := time.LoadLocation(config.Instance.TimeZone) // 时区 + time.Local = denverLoc + t, _ := dateparse.ParseIn(oc.Date, denverLoc) nComment.CreatedAt = t nComment.UpdatedAt = t From 91d965f61c6d5947520eea5d098f3065b3f255fb Mon Sep 17 00:00:00 2001 From: qwqcode Date: Sun, 10 Oct 2021 15:47:49 +0800 Subject: [PATCH 039/349] Request param Parser support convert string to bool. --- http/utils.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/http/utils.go b/http/utils.go index d8e9c79ac..bf82895c6 100644 --- a/http/utils.go +++ b/http/utils.go @@ -90,7 +90,7 @@ func ParamsDecode(c echo.Context, paramsStruct interface{}, destParams interface if typeString { params[paramName] = paramVal } else if typeBool { - params[paramName] = (paramVal == "1") + params[paramName] = (paramVal == "1" || paramVal == "true") } else if typeInt || typeUint { u64, err := strconv.ParseInt(paramVal, 10, 32) if requiredField && (err != nil || u64 == 0) { From 92f3d7e22e10864ddc8da1a25f0f0968b5294a63 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Sun, 10 Oct 2021 19:26:54 +0800 Subject: [PATCH 040/349] Anti spam: support akismet. --- .vscode/settings.json | 1 + artalk-go.example.yml | 1 + config/config.go | 3 +- http/api_main_add.go | 7 ++++ lib/anti_spam.go | 81 +++++++++++++++++++++++++++++++++++++++++++ model/comment.go | 54 +++++++++++++++++++++++++++++ model/query.go | 6 ++++ 7 files changed, 152 insertions(+), 1 deletion(-) create mode 100644 lib/anti_spam.go diff --git a/.vscode/settings.json b/.vscode/settings.json index e3f6b4fe4..0c4f18531 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,5 +1,6 @@ { "cSpell.words": [ + "akismet", "artalk", "gomail", "gorm", diff --git a/artalk-go.example.yml b/artalk-go.example.yml index 5f12be5bd..612308f4e 100644 --- a/artalk-go.example.yml +++ b/artalk-go.example.yml @@ -45,6 +45,7 @@ login_timeout: 259200 # 评论审核 moderator: pending_default: false # 发表新评论默认为 “待审状态” + akismet_key: '' # 启用 akismet.com 反垃圾 # 验证码 captcha: diff --git a/config/config.go b/config/config.go index 9c14d76d7..61ced83a2 100644 --- a/config/config.go +++ b/config/config.go @@ -54,7 +54,8 @@ type AdminUserConf struct { } type ModeratorConf struct { - PendingDefault bool `mapstructure:"pending_default"` + PendingDefault bool `mapstructure:"pending_default"` + AkismetKey string `mapstructure:"akismet_key"` } type CaptchaConf struct { diff --git a/http/api_main_add.go b/http/api_main_add.go index 252fb8bb6..9719e520a 100644 --- a/http/api_main_add.go +++ b/http/api_main_add.go @@ -125,6 +125,13 @@ func ActionAdd(c echo.Context) error { }() } + // 垃圾评论检测 + if !CheckIsAdminReq(c) { + go func() { + comment.AntiSpamCheck(c) + }() + } + return RespData(c, ResponseAdd{ Comment: comment.ToCooked(), }) diff --git a/lib/anti_spam.go b/lib/anti_spam.go new file mode 100644 index 000000000..8880e7dec --- /dev/null +++ b/lib/anti_spam.go @@ -0,0 +1,81 @@ +package lib + +import ( + "errors" + "fmt" + "io/ioutil" + "net/http" + "net/url" + "reflect" + "strings" + + "github.com/ArtalkJS/ArtalkGo/config" + "github.com/sirupsen/logrus" +) + +type AkismetParams struct { + Blog string `name:"blog"` // required + UserIP string `name:"user_ip"` // required + UserAgent string `name:"user_agent"` // required + + CommentType string `name:"comment_type"` + CommentAuthor string `name:"comment_author"` + CommentAuthorEmail string `name:"comment_author_email"` + CommentAuthorURL string `name:"comment_author_url"` + CommentContent string `name:"comment_content"` + + UserRole string `name:"user_role"` + Referrer string `name:"referrer"` + Permalink string `name:"permalink"` + BlogLang string `name:"blog_lang"` + BlogCharset string `name:"blog_charset"` +} + +// @link https://akismet.com/development/api/#comment-check +func AntiSpamCheck_Akismet(params *AkismetParams, key string) (bool, error) { + form := url.Values{} + + v := reflect.ValueOf(*params) + t := v.Type() + for i := 0; i < v.Type().NumField(); i++ { + if v.Field(i).String() != "" { + form.Add(t.Field(i).Tag.Get("name"), v.Field(i).String()) + } + } + + client := &http.Client{} + + reqBody := strings.NewReader(form.Encode()) + api := fmt.Sprintf("https://%s.rest.akismet.com/1.1/comment-check", key) + req, err := http.NewRequest("POST", api, reqBody) + if err != nil { + return true, err + } + + req.Header.Add("Content-Type", "application/x-www-form-urlencoded") + + resp, err := client.Do(req) + if err != nil { + return true, err + } + + defer resp.Body.Close() + respBody, err := ioutil.ReadAll(resp.Body) + if err != nil { + return true, err + } + + respStr := string(respBody) + + if config.Instance.Debug { + logrus.Info("akismet 垃圾检测响应 ", respStr) + } + + if respStr == "true" { + return false, nil // 不是垃圾评论 + } else if respStr == "false" { + return true, nil + } + + return true, errors.New(respStr) +} diff --git a/model/comment.go b/model/comment.go index 509bb2ba4..c8c8e244d 100644 --- a/model/comment.go +++ b/model/comment.go @@ -1,7 +1,14 @@ package model import ( + "fmt" + "net/url" + "strings" + + "github.com/ArtalkJS/ArtalkGo/config" "github.com/ArtalkJS/ArtalkGo/lib" + "github.com/labstack/echo/v4" + "github.com/sirupsen/logrus" "gorm.io/gorm" ) @@ -158,3 +165,50 @@ func (c Comment) ToCookedForEmail() CookedCommentForEmail { SiteName: c.SiteName, } } + +func (c *Comment) AntiSpamCheck(echoCtx echo.Context) { + setPending := func() { + if c.IsPending { + return + } + + // 改为待审状态 + c.IsPending = true + lib.DB.Save(c) + } + + siteURL := "" + if c.SiteName != "" { + site := FindSite(c.SiteName) + siteURL = site.ToCooked().FirstUrl + } + if siteURL == "" { // 从 referer 中提取网站 + if pr, err := url.Parse(echoCtx.Request().Referer()); err == nil && pr.Scheme != "" && pr.Host != "" { + siteURL = fmt.Sprintf("%s://%s", pr.Scheme, pr.Host) + } + } + + user := FindUserByID(c.UserID) + + // akismet + akismetKey := strings.TrimSpace(config.Instance.Moderator.AkismetKey) + if akismetKey != "" { + isOK, err := lib.AntiSpamCheck_Akismet(&lib.AkismetParams{ + Blog: siteURL, + UserIP: echoCtx.RealIP(), + UserAgent: echoCtx.Request().UserAgent(), + CommentType: "comment", + CommentAuthor: user.Name, + CommentAuthorEmail: user.Email, + CommentContent: c.Content, + }, akismetKey) + if err != nil { + logrus.Error("akismet 垃圾检测错误 ", err) + } + if !isOK { + setPending() + } + } + + // TODO:关键字过滤 +} diff --git a/model/query.go b/model/query.go index 0ef3561c1..9179729e0 100644 --- a/model/query.go +++ b/model/query.go @@ -26,6 +26,12 @@ func FindUser(name string, email string) User { return user } +func FindUserByID(id uint) User { + var user User + lib.DB.First(&user, id) + return user +} + func IsAdminUser(name string, email string) bool { var user User lib.DB.Where("name = ? AND email = ? AND is_admin = 1", name, email).First(&user) From 2512a22073720967570861a04593d097d61bc4a7 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Sun, 10 Oct 2021 20:20:11 +0800 Subject: [PATCH 041/349] Update README todos. --- README.md | 81 ++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 65 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index beab46723..ef93dabd1 100644 --- a/README.md +++ b/README.md @@ -6,25 +6,74 @@ > ArtalkGo: the Artalk golang version. +## Features + +- 高效 - 跨平台 - 轻松部署 -- 可视化图形界面 -- 命令行管理 -- 数据导出导入 -- 数据备份同步 - 多站点支持 -- 评论获取分页 -- 评论点赞投票 -- 通知中心管理 -- 邮件异步队列发送 -- 邮件多模板自定义 -- 博客邮件订阅 -- 用户鉴权机制 -- 防止非法跨域请求 -- 全局验证码操作限制 -- 规范化 API - -## 支持 +- 多数据库类型支持 + +## TODOs + +- [ ] 命令行管理 +- [x] 多站点支持 +- [x] 多数据库支持 +- [x] 评论获取分页 +- [ ] 评论点赞投票 +- [ ] 实时浏览量统计 +- [x] 评论分页加载 +- [x] 数据 +- [x] 通知中心 + - [x] 提及 + - [x] 全部 + - [x] 我的 + - [x] 待审 +- [x] 管理员控制台 + - [x] 评论 (增/删/改) + - [x] 页面 (增/删/改) + - [x] 站点 (增/删/改) + - [ ] 配置 (GUI) + - [ ] 数据分页 +- [x] 数据导入 + - [x] Artalk v1 (PHP) + - [ ] WordPress + - [ ] Typecho +- [ ] 数据导出 +- [ ] 数据备份同步 +- [x] 邮件异步队列发送 +- [ ] 邮件队列持久化 +- [x] 邮件多种发送方式 + - [x] SMTP + - [x] 阿里云邮件 + - [x] 系统调用 sendmail +- [x] 邮件多模板自定义 +- [ ] 用户已阅标记 +- [x] 反垃圾 + - [x] Akismet + - [ ] 阿里云服务 + - [ ] 腾讯云服务 + - [ ] 关键字 / 正则表达式过滤 +- [ ] 评论通知 WebHook + - [ ] Telegram Bot + - [ ] 自定义 HTTP 回调 +- [ ] 博客邮件订阅 +- [x] 用户鉴权机制 +- [x] 跨域非法请求阻止 +- [x] 全局验证码操作次数限制 +- [x] JWT 登陆状态验证 +- [x] 时区自定义 +- [ ] 评论置顶 / 精华 +- [ ] AT 提及 (@) +- [ ] 评论提及 (#) +- [ ] 表情包统一管理 + - [ ] 导入表情包 + - [ ] 表情包图片地址控制 +- [ ] 图片上传 / 管理 +- [ ] 评论标签分类系统 +- [ ] 规范化 API + +## Supports - 跨平台:支持 Linux, Win, Darwin - 数据存储:支持 SQLite, MySQL, PostgreSQL, SQL Server... From 6c6ca70bd0a0e9497eeeee406a513eb09af9a548 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Sun, 10 Oct 2021 20:28:01 +0800 Subject: [PATCH 042/349] Add more todos. --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index ef93dabd1..4216aee8b 100644 --- a/README.md +++ b/README.md @@ -71,7 +71,12 @@ - [ ] 表情包图片地址控制 - [ ] 图片上传 / 管理 - [ ] 评论标签分类系统 +- [ ] 主题样式更换 - [ ] 规范化 API +- [ ] 扩展中心 +- [ ] 开放用户注册 +- [ ] 接入第三方登录 +- [ ] 在线升级 ## Supports From dd3dab429408aca7813efda218e237f409a2cd95 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Mon, 11 Oct 2021 13:58:05 +0800 Subject: [PATCH 043/349] Fix open assets not found bug. --- README.md | 2 ++ http/a_http.go | 4 ++-- lib/email/tpl.go | 6 ++++-- lib/utils.go | 21 +++------------------ makefile | 2 +- pkged/main.go | 9 +++++++++ 6 files changed, 21 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index 4216aee8b..5e4b8881a 100644 --- a/README.md +++ b/README.md @@ -70,12 +70,14 @@ - [ ] 导入表情包 - [ ] 表情包图片地址控制 - [ ] 图片上传 / 管理 +- [ ] 附件上传 / 管理 - [ ] 评论标签分类系统 - [ ] 主题样式更换 - [ ] 规范化 API - [ ] 扩展中心 - [ ] 开放用户注册 - [ ] 接入第三方登录 +- [ ] 国际化 (i18n) - [ ] 在线升级 ## Supports diff --git a/http/a_http.go b/http/a_http.go index 3495224b3..d660f0d71 100644 --- a/http/a_http.go +++ b/http/a_http.go @@ -5,9 +5,9 @@ import ( "strings" "github.com/ArtalkJS/ArtalkGo/config" + "github.com/ArtalkJS/ArtalkGo/pkged" "github.com/labstack/echo/v4" "github.com/labstack/echo/v4/middleware" - "github.com/markbates/pkger" echolog "github.com/onrik/logrus/echo" "github.com/sirupsen/logrus" ) @@ -64,7 +64,7 @@ func Run() { } func InitRoute(e *echo.Echo) { - f, err := pkger.Open("/frontend") + f, err := pkged.Open("/frontend") if err != nil { logrus.Fatal(err) return diff --git a/lib/email/tpl.go b/lib/email/tpl.go index dd1167a8f..f8e62b6f6 100644 --- a/lib/email/tpl.go +++ b/lib/email/tpl.go @@ -11,7 +11,7 @@ import ( "github.com/ArtalkJS/ArtalkGo/config" "github.com/ArtalkJS/ArtalkGo/lib" "github.com/ArtalkJS/ArtalkGo/model" - "github.com/markbates/pkger" + "github.com/ArtalkJS/ArtalkGo/pkged" ) func RenderEmailTpl(from model.CookedCommentForEmail, to model.CookedCommentForEmail) string { @@ -41,6 +41,8 @@ func RenderEmailTpl(from model.CookedCommentForEmail, to model.CookedCommentForE } tpl = RenderConfig(tpl) + + // TODO: not from.link tpl = strings.ReplaceAll(tpl, "{{reply_link}}", lib.AddQueryToURL(from.Link, map[string]string{"artalk_comment": fmt.Sprintf("%d", from.ID)})) return tpl @@ -65,7 +67,7 @@ func GetExternalEmailTpl(filename string) string { func GetInternalEmailTpl(tplName string) string { filename := fmt.Sprintf("/email-tpl/%s.html", tplName) - f, err := pkger.Open(filename) + f, err := pkged.Open(filename) if err != nil { return "" } diff --git a/lib/utils.go b/lib/utils.go index 26ab10000..ad78e70cd 100644 --- a/lib/utils.go +++ b/lib/utils.go @@ -5,7 +5,6 @@ import ( "crypto/md5" "encoding/hex" "encoding/json" - "errors" "net/mail" "net/url" "os" @@ -18,23 +17,9 @@ import ( "github.com/yuin/goldmark/renderer/html" ) -func EnsureDir(dirName string) error { - err := os.Mkdir(dirName, os.ModeDir) - if err == nil { - return nil - } - if os.IsExist(err) { - // check that the existing path is a directory - info, err := os.Stat(dirName) - if err != nil { - return err - } - if !info.IsDir() { - return errors.New("path exists but is not a directory") - } - return nil - } - return err +// EnsureDir ensures that a target directory exists (like `mkdir -p`), +func EnsureDir(dir string) error { + return os.MkdirAll(dir, 0700) } func GetMD5Hash(text string) string { diff --git a/makefile b/makefile index d1def5de0..aa88e6fa4 100644 --- a/makefile +++ b/makefile @@ -2,7 +2,7 @@ ifndef VERSION VERSION := $(shell git describe --tags --abbrev=0) endif -COMMIT_HASH :=$(shell git rev-parse --short HEAD) +COMMIT_HASH := $(shell git rev-parse --short HEAD) DEV_VERSION := dev-${COMMIT_HASH} all: install update build diff --git a/pkged/main.go b/pkged/main.go index dee467340..4c55289eb 100644 --- a/pkged/main.go +++ b/pkged/main.go @@ -1 +1,10 @@ package pkged + +import ( + "github.com/markbates/pkger" + "github.com/markbates/pkger/pkging" +) + +func Open(p string) (pkging.File, error) { + return pkger.Open(p) +} From 5995bc1c5b99bba7f673816e3074840e79c6f84f Mon Sep 17 00:00:00 2001 From: qwqcode Date: Mon, 11 Oct 2021 16:58:43 +0800 Subject: [PATCH 044/349] Allow any request method at path '/'. --- http/a_http.go | 2 +- http/api_admin_page_edit.go | 2 +- http/api_admin_page_fetch.go | 11 ++--------- model/query.go | 4 ++-- 4 files changed, 6 insertions(+), 13 deletions(-) diff --git a/http/a_http.go b/http/a_http.go index d660f0d71..0871cdb3a 100644 --- a/http/a_http.go +++ b/http/a_http.go @@ -71,7 +71,7 @@ func InitRoute(e *echo.Echo) { } fileServer := http.FileServer(f) - e.GET("/*", echo.WrapHandler(fileServer)) + e.Any("/*", echo.WrapHandler(fileServer)) // api api := e.Group("/api") diff --git a/http/api_admin_page_edit.go b/http/api_admin_page_edit.go index aa236a493..125fbfd6b 100644 --- a/http/api_admin_page_edit.go +++ b/http/api_admin_page_edit.go @@ -39,7 +39,7 @@ func ActionAdminPageEdit(c echo.Context) error { return resp } - page := model.FindPageByID(p.ID, p.SiteName) + page := model.FindPageByID(p.ID) if page.IsEmpty() { return RespError(c, "page not found") } diff --git a/http/api_admin_page_fetch.go b/http/api_admin_page_fetch.go index d384b6b5e..894af6bca 100644 --- a/http/api_admin_page_fetch.go +++ b/http/api_admin_page_fetch.go @@ -6,9 +6,7 @@ import ( ) type ParamsAdminPageFetch struct { - Key string `mapstructure:"key" param:"required"` - SiteName string `mapstructure:"site_name"` - SiteID uint + ID uint `mapstructure:"id" param:"required"` } func ActionAdminPageFetch(c echo.Context) error { @@ -21,12 +19,7 @@ func ActionAdminPageFetch(c echo.Context) error { return resp } - // find site - if isOK, resp := CheckSite(c, &p.SiteName, &p.SiteID, nil); !isOK { - return resp - } - - page := model.FindPage(p.Key, p.SiteName) + page := model.FindPageByID(p.ID) if page.IsEmpty() { return RespError(c, "page not found") } diff --git a/model/query.go b/model/query.go index 9179729e0..07f6b397a 100644 --- a/model/query.go +++ b/model/query.go @@ -126,9 +126,9 @@ func FindPage(key string, siteName string) Page { return page } -func FindPageByID(id uint, siteName string) Page { +func FindPageByID(id uint) Page { var page Page - lib.DB.Where("id = ? AND site_name = ?", id, siteName).First(&page) + lib.DB.Where("id = ?", id).First(&page) return page } From 33c8bbe9b188969ebba97ee0080ab315c9b1643d Mon Sep 17 00:00:00 2001 From: qwqcode Date: Mon, 11 Oct 2021 23:28:40 +0800 Subject: [PATCH 045/349] Add model Notify & msg read / unread. --- README.md | 2 +- artalk-go.example.yml | 3 -- cmd/root.go | 14 +++--- config/config.go | 1 - http/a_http.go | 1 + http/api_admin_comment_del.go | 24 ++++++++- http/api_admin_importer.go | 20 +++++--- http/api_admin_page_del.go | 4 +- http/api_admin_send_mail.go | 2 +- http/api_admin_site_del.go | 5 +- http/api_main_add.go | 66 +++++++++++++++++-------- http/api_main_mark_read.go | 44 +++++++++++++++++ http/api_user_get.go | 24 ++++++--- lib/email/email.go | 74 +++++++++++++++------------- lib/email/queue.go | 14 ++++-- lib/email/{tpl.go => render.go} | 12 ++--- lib/email/sender.go | 12 +++-- model/comment.go | 53 ++++++++++++++------ model/notify.go | 87 +++++++++++++++++++++++++++++++++ model/query.go | 44 ++++++++++++++++- 20 files changed, 384 insertions(+), 122 deletions(-) create mode 100644 http/api_main_mark_read.go rename lib/email/{tpl.go => render.go} (78%) create mode 100644 model/notify.go diff --git a/README.md b/README.md index 5e4b8881a..58171b1f2 100644 --- a/README.md +++ b/README.md @@ -48,7 +48,7 @@ - [x] 阿里云邮件 - [x] 系统调用 sendmail - [x] 邮件多模板自定义 -- [ ] 用户已阅标记 +- [x] 用户已读标记 - [x] 反垃圾 - [x] Akismet - [ ] 阿里云服务 diff --git a/artalk-go.example.yml b/artalk-go.example.yml index 612308f4e..b4820cb74 100644 --- a/artalk-go.example.yml +++ b/artalk-go.example.yml @@ -1,6 +1,3 @@ -# 网站名 -site_name: 'ArtalkServer' - # HTTP Server 监听地址 http_addr: ':23366' diff --git a/cmd/root.go b/cmd/root.go index 1d9a272a8..9210c3c63 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -62,6 +62,12 @@ func init() { func initConfig() { config.Init(cfgFile) + // 检查 app_key 是否设置 + if strings.TrimSpace(config.Instance.AppKey) == "" { + logrus.Fatal("请检查配置文件,并设置一个 app_key (任意字符串) 用于数据加密") + os.Exit(1) + } + // 设置时区 if strings.TrimSpace(config.Instance.TimeZone) == "" { logrus.Fatal("请检查配置文件,并设置 timezone") @@ -69,12 +75,6 @@ func initConfig() { } denverLoc, _ := time.LoadLocation(config.Instance.TimeZone) time.Local = denverLoc - - // 检查 app_key 是否设置 - if strings.TrimSpace(config.Instance.AppKey) == "" { - logrus.Fatal("请检查配置文件,并设置一个 app_key (任意字符串) 用于数据加密") - os.Exit(1) - } } // 2. 初始化日志 @@ -131,7 +131,7 @@ func initDB() { } // Migrate the schema - lib.DB.AutoMigrate(&model.Site{}, &model.Page{}, &model.User{}, &model.Comment{}) // 注意表的创建顺序,因为有关联字段 + lib.DB.AutoMigrate(&model.Site{}, &model.Page{}, &model.User{}, &model.Comment{}, &model.Notify{}) // 注意表的创建顺序,因为有关联字段 } // 4. 同步配置文件与数据库 diff --git a/config/config.go b/config/config.go index 61ced83a2..7518eff7f 100644 --- a/config/config.go +++ b/config/config.go @@ -18,7 +18,6 @@ var Flat map[string]interface{} // Config 配置 // @link https://godoc.org/github.com/mitchellh/mapstructure type Config struct { - SiteName string `mapstructure:"site_name"` // 网站名 AppKey string `mapstructure:"app_key"` // 加密密钥 Debug bool `mapstructure:"debug"` // 调试模式 TimeZone string `mapstructure:"timezone"` // 时区 diff --git a/http/a_http.go b/http/a_http.go index 0871cdb3a..a8cff943b 100644 --- a/http/a_http.go +++ b/http/a_http.go @@ -81,6 +81,7 @@ func InitRoute(e *echo.Echo) { api.POST("/user-get", ActionUserGet) api.GET("/login", ActionLogin) api.POST("/login", ActionLogin) + api.POST("/mark-read", ActionMarkRead) // api/captcha ca := api.Group("/captcha") diff --git a/http/api_admin_comment_del.go b/http/api_admin_comment_del.go index 751e74162..ca02fdf23 100644 --- a/http/api_admin_comment_del.go +++ b/http/api_admin_comment_del.go @@ -42,7 +42,7 @@ func ActionAdminCommentDel(c echo.Context) error { return RespError(c, "comment not found") } - if err := lib.DB.Model(&model.Comment{}).Delete("id = ?", comment.ID).Error; err != nil { + if err := DelComment(&comment); err != nil { return RespError(c, "comment delete error") } @@ -50,7 +50,7 @@ func ActionAdminCommentDel(c echo.Context) error { hasErr := false children := comment.FetchChildren(func(db *gorm.DB) *gorm.DB { return db }) for _, c := range children { - err := lib.DB.Delete(&c) + err := DelComment(&c) if err != nil { hasErr = true } @@ -61,3 +61,23 @@ func ActionAdminCommentDel(c echo.Context) error { return RespSuccess(c) } + +func DelComment(comment *model.Comment) error { + // 清除 notify + var notifications []model.Notify + lib.DB.Where("comment_id = ?", comment.ID).Find(¬ifications) + + for _, n := range notifications { + if err := lib.DB.Delete(n).Error; err != nil { + return err + } + } + + // 删除 comment + err := lib.DB.Delete(comment).Error + if err != nil { + return err + } + + return nil +} diff --git a/http/api_admin_importer.go b/http/api_admin_importer.go index aaf4e9e7e..e687ac149 100644 --- a/http/api_admin_importer.go +++ b/http/api_admin_importer.go @@ -86,15 +86,19 @@ func ActionAdminImporter(c echo.Context) error { // 创建新 comment 实例 nComment := model.Comment{ - Content: oc.Content, - Rid: oc.Rid, - UserID: user.ID, - PageKey: page.Key, - IP: oc.IP, - UA: oc.UA, - IsPending: oc.IsPending, + Content: oc.Content, + + PageKey: page.Key, + SiteName: p.SiteName, + + UserID: user.ID, + UA: oc.UA, + IP: oc.IP, + + Rid: oc.Rid, + IsCollapsed: oc.IsCollapsed, - SiteName: p.SiteName, + IsPending: oc.IsPending, } // 日期恢复 diff --git a/http/api_admin_page_del.go b/http/api_admin_page_del.go index 63b5ef028..ef743d8e9 100644 --- a/http/api_admin_page_del.go +++ b/http/api_admin_page_del.go @@ -41,11 +41,9 @@ func ActionAdminPageDel(c echo.Context) error { var comments []model.Comment lib.DB.Where("page_key = ? AND site_name = ?", p.Key, p.SiteName).Find(&comments) - tx := lib.DB.Begin() for _, c := range comments { - tx.Delete(&c) + DelComment(&c) } - tx.Commit() return RespSuccess(c) } diff --git a/http/api_admin_send_mail.go b/http/api_admin_send_mail.go index 52861a5c3..53e95bd63 100644 --- a/http/api_admin_send_mail.go +++ b/http/api_admin_send_mail.go @@ -21,7 +21,7 @@ func ActionAdminSendMail(c echo.Context) error { return resp } - email.SendTo(p.Subject, p.Body, p.ToAddr) + email.AsyncSendTo(p.Subject, p.Body, p.ToAddr) return RespSuccess(c) } diff --git a/http/api_admin_site_del.go b/http/api_admin_site_del.go index 81b5077a2..949feb017 100644 --- a/http/api_admin_site_del.go +++ b/http/api_admin_site_del.go @@ -39,10 +39,11 @@ func ActionAdminSiteDel(c echo.Context) error { var pages []model.Page lib.DB.Where("site_name = ?", site.Name).Find(&pages) - tx := lib.DB.Begin() for _, c := range comments { - tx.Delete(&c) + DelComment(&c) } + + tx := lib.DB.Begin() for _, p := range pages { tx.Unscoped().Delete(&p) } diff --git a/http/api_main_add.go b/http/api_main_add.go index 9719e520a..039a53ff4 100644 --- a/http/api_main_add.go +++ b/http/api_main_add.go @@ -83,15 +83,18 @@ func ActionAdd(c echo.Context) error { } comment := model.Comment{ - Content: p.Content, - Rid: p.Rid, - UserID: user.ID, - PageKey: page.Key, - IP: ip, - UA: ua, + Content: p.Content, + PageKey: page.Key, + SiteName: p.SiteName, + + UserID: user.ID, + IP: ip, + UA: ua, + + Rid: p.Rid, + IsPending: false, IsCollapsed: false, - SiteName: p.SiteName, } // default comment type @@ -112,27 +115,50 @@ func ActionAdd(c echo.Context) error { user.LastUA = ua model.UpdateUser(&user) - // send email - if comment.Rid != 0 { - email.Send(comment.ToCookedForEmail(), parentComment.ToCookedForEmail()) // 发送邮件给回复者 - } - email.SendToAdmin(comment.ToCookedForEmail()) // 发送邮件给管理员 - - // fetch page url data + // update page if page.ToCooked().URL != "" && page.Title == "" { go func() { page.FetchURL() }() } - // 垃圾评论检测 - if !CheckIsAdminReq(c) { - go func() { - comment.AntiSpamCheck(c) - }() - } + // 异步执行 + go func() { + // 垃圾检测 + if !CheckIsAdminReq(c) { + comment.SpamCheck(c) + } + + // 邮件通知发送 + AsyncSendEmail(&comment, &parentComment) + }() return RespData(c, ResponseAdd{ Comment: comment.ToCooked(), }) } + +// 异步邮件发送 +func AsyncSendEmail(comment *model.Comment, parentComment *model.Comment) { + if !config.Instance.Email.Enabled { + return + } + + if !parentComment.IsEmpty() && !comment.IsPending { + notify := model.FindCreateNotify(parentComment.UserID, comment.ID) + email.AsyncSend(¬ify) + } + + // 邮件通知管理员 + var admins []model.User + lib.DB.Where("is_admin = 1").Find(&admins) + + if len(admins) == 0 { + return + } + + for _, admin := range admins { + notify := model.FindCreateNotify(parentComment.UserID, comment.ID) + email.AsyncSendToAdmin(¬ify, &admin) // 发送邮件给管理员 + } +} diff --git a/http/api_main_mark_read.go b/http/api_main_mark_read.go new file mode 100644 index 000000000..0e0f2a68e --- /dev/null +++ b/http/api_main_mark_read.go @@ -0,0 +1,44 @@ +package http + +import ( + "github.com/ArtalkJS/ArtalkGo/model" + "github.com/labstack/echo/v4" +) + +type ParamsMarkRead struct { + NotifyKey string `mapstructure:"notify_key"` + + SiteName string `mapstructure:"site_name"` + SiteID uint + SiteAll bool +} + +func ActionMarkRead(c echo.Context) error { + var p ParamsMarkRead + if isOK, resp := ParamsDecode(c, ParamsMarkRead{}, &p); !isOK { + return resp + } + + // find site + if isOK, resp := CheckSite(c, &p.SiteName, &p.SiteID, &p.SiteAll); !isOK { + return resp + } + + // find notify + notify := model.FindNotifyByKey(p.NotifyKey) + if notify.IsEmpty() { + return RespError(c, "notify key is wrong") + } + + if notify.IsRead { + return RespSuccess(c) + } + + // update notify + err := notify.SetRead() + if err != nil { + return RespError(c, "notify save error") + } + + return RespSuccess(c) +} diff --git a/http/api_user_get.go b/http/api_user_get.go index 4f80c0c60..1b742638f 100644 --- a/http/api_user_get.go +++ b/http/api_user_get.go @@ -11,10 +11,6 @@ type ParamsUserGet struct { Email string `mapstructure:"email"` } -type ResponseUserGet struct { - IsAdmin bool `json:"is_admin"` -} - func ActionUserGet(c echo.Context) error { var p ParamsUserGet if isOK, resp := ParamsDecode(c, ParamsUserGet{}, &p); !isOK { @@ -26,8 +22,10 @@ func ActionUserGet(c echo.Context) error { if user.IsEmpty() || user.Name != p.Name || user.Email != p.Email { return RespData(c, Map{ - "user": nil, - "is_login": false, + "user": nil, + "is_login": false, + "unread_msg": 0, + "unread_comments": []int{}, }) } @@ -39,8 +37,18 @@ func ActionUserGet(c echo.Context) error { user = tUser } + // unread_msg + var notifications []model.Notify + lib.DB.Where("user_id = ?", user.ID).Find(¬ifications) + unreadComments := []uint{} + for _, notify := range notifications { + unreadComments = append(unreadComments, notify.CommentID) + } + return RespData(c, Map{ - "user": user.ToCooked(), - "is_login": isLogin, + "user": user.ToCooked(), + "is_login": isLogin, + "unread_msg": 0, + "unread_comments": unreadComments, }) } diff --git a/lib/email/email.go b/lib/email/email.go index 28d8a439b..872b8ec97 100644 --- a/lib/email/email.go +++ b/lib/email/email.go @@ -2,11 +2,14 @@ package email import ( "github.com/ArtalkJS/ArtalkGo/config" - "github.com/ArtalkJS/ArtalkGo/lib" "github.com/ArtalkJS/ArtalkGo/model" ) -func SendTo(subject string, body string, toAddr string) { +func AsyncSendTo(subject string, body string, toAddr string) { + if !config.Instance.Email.Enabled { + return + } + AddToQueue(Email{ FromAddr: config.Instance.Email.SendAddr, FromName: config.Instance.Email.SendName, @@ -16,55 +19,58 @@ func SendTo(subject string, body string, toAddr string) { }) } -func Send(from model.CookedCommentForEmail, to model.CookedCommentForEmail) { +func AsyncSend(notify *model.Notify) { if !config.Instance.Email.Enabled { return } + notify.SetInitial() + + comment := notify.Comment + parentComment := notify.GetParentComment() + + from := comment.ToCookedForEmail() + to := parentComment.ToCookedForEmail() + go func() { - subject := RenderConfig(config.Instance.Email.MailSubject) - body := RenderEmailTpl(from, to) + subject := RenderConfig(config.Instance.Email.MailSubject, notify, from, to) + body := RenderEmailTpl(notify, from, to) AddToQueue(Email{ - FromAddr: config.Instance.Email.SendAddr, - FromName: config.Instance.Email.SendName, - ToAddr: to.Email, - Subject: subject, - Body: body, + FromAddr: config.Instance.Email.SendAddr, + FromName: config.Instance.Email.SendName, + ToAddr: to.Email, + Subject: subject, + Body: body, + LinkedNotify: notify, }) }() } -func SendToAdmin(from model.CookedCommentForEmail) { +func AsyncSendToAdmin(notify *model.Notify, admin *model.User) { if !config.Instance.Email.Enabled { return } - // 查询所有 admin - var admins []model.User - lib.DB.Where("is_admin = 1").Find(&admins) + notify.SetInitial() - if len(admins) == 0 { - return + comment := notify.Comment + from := comment.ToCookedForEmail() + to := model.CookedCommentForEmail{ + Nick: admin.Name, + Email: admin.Email, } - // 发邮件给每个 admin - for _, admin := range admins { - email := admin.Email - - go func() { - subject := RenderConfig(config.Instance.Email.MailSubjectToAdmin) - body := RenderEmailTpl(from, model.CookedCommentForEmail{ - Nick: "Admin", - }) + go func() { + subject := RenderConfig(config.Instance.Email.MailSubjectToAdmin, notify, from, to) + body := RenderEmailTpl(notify, from, to) - AddToQueue(Email{ - FromAddr: config.Instance.Email.SendAddr, - FromName: config.Instance.Email.SendName, - ToAddr: email, - Subject: subject, - Body: body, - }) - }() - } + AddToQueue(Email{ + FromAddr: config.Instance.Email.SendAddr, + FromName: config.Instance.Email.SendName, + ToAddr: admin.Email, + Subject: subject, + Body: body, + }) + }() } diff --git a/lib/email/queue.go b/lib/email/queue.go index a281fdea5..ca9f0b384 100644 --- a/lib/email/queue.go +++ b/lib/email/queue.go @@ -9,13 +9,21 @@ var emailCh = make(chan Email) // make(chan Email, 5) func InitQueue() { go func() { for email := range emailCh { + result := false switch config.Instance.Email.SendType { case config.TypeSMTP: - SendBySMTP(email) + result = SendBySMTP(email) case config.TypeAliDM: - SendByAliDM(email) + result = SendByAliDM(email) case config.TypeSendmail: - SendByUsingSystemCMD(email) + result = SendByUsingSystemCMD(email) + } + + if result { // 发送成功 + if email.LinkedNotify != nil { + // 标记关联评论邮件发送状态 + email.LinkedNotify.SetEmailed() + } } } }() diff --git a/lib/email/tpl.go b/lib/email/render.go similarity index 78% rename from lib/email/tpl.go rename to lib/email/render.go index f8e62b6f6..219e75f71 100644 --- a/lib/email/tpl.go +++ b/lib/email/render.go @@ -14,7 +14,7 @@ import ( "github.com/ArtalkJS/ArtalkGo/pkged" ) -func RenderEmailTpl(from model.CookedCommentForEmail, to model.CookedCommentForEmail) string { +func RenderEmailTpl(notify *model.Notify, from model.CookedCommentForEmail, to model.CookedCommentForEmail) string { tplName := config.Instance.Email.MailTpl tpl := "" if _, err := os.Stat(tplName); os.IsExist(err) { @@ -40,19 +40,17 @@ func RenderEmailTpl(from model.CookedCommentForEmail, to model.CookedCommentForE tpl = strings.ReplaceAll(tpl, fmt.Sprintf("{{to.%s}}", k), getValue(k, v)) } - tpl = RenderConfig(tpl) - - // TODO: not from.link - tpl = strings.ReplaceAll(tpl, "{{reply_link}}", lib.AddQueryToURL(from.Link, map[string]string{"artalk_comment": fmt.Sprintf("%d", from.ID)})) + tpl = RenderConfig(tpl, notify, from, to) + tpl = strings.ReplaceAll(tpl, "{{reply_link}}", notify.GetReadLink()) return tpl } -func RenderConfig(str string) string { +func RenderConfig(str string, notify *model.Notify, from, to model.CookedCommentForEmail) string { for k, v := range config.Flat { str = strings.ReplaceAll(str, fmt.Sprintf("{{config.%s}}", k), fmt.Sprintf("%v", v)) } - str = strings.ReplaceAll(str, "{{site_name}}", config.Instance.SiteName) + str = strings.ReplaceAll(str, "{{site_name}}", from.SiteName) return str } diff --git a/lib/email/sender.go b/lib/email/sender.go index 32c5ba106..c4b6508ac 100644 --- a/lib/email/sender.go +++ b/lib/email/sender.go @@ -6,17 +6,19 @@ import ( "os/exec" "github.com/ArtalkJS/ArtalkGo/config" + "github.com/ArtalkJS/ArtalkGo/model" ali_dm "github.com/qwqcode/go-aliyun-email" "github.com/sirupsen/logrus" "gopkg.in/gomail.v2" ) type Email struct { - FromAddr string - FromName string - ToAddr string - Subject string - Body string + FromAddr string + FromName string + ToAddr string + Subject string + Body string + LinkedNotify *model.Notify } func SendBySMTP(email Email) bool { diff --git a/model/comment.go b/model/comment.go index c8c8e244d..41f51afa5 100644 --- a/model/comment.go +++ b/model/comment.go @@ -12,25 +12,26 @@ import ( "gorm.io/gorm" ) -type CommentType string - type Comment struct { gorm.Model + Content string - UserID uint `gorm:"index"` PageKey string `gorm:"index"` SiteName string `gorm:"index"` - User User `gorm:"foreignKey:UserID;references:ID"` - Page Page `gorm:"foreignKey:PageKey;references:Key"` - Site Site `gorm:"foreignKey:SiteName;references:Name"` - Rid uint `gorm:"index"` - UA string - IP string + UserID uint `gorm:"index"` + UA string + IP string + + Rid uint `gorm:"index"` // 父评论 ID + + IsCollapsed bool // 折叠 + IsPending bool // 待审 - IsCollapsed bool - IsPending bool + User User `gorm:"foreignKey:UserID;references:ID"` + Page Page `gorm:"foreignKey:PageKey;references:Key"` + Site Site `gorm:"foreignKey:SiteName;references:Name"` } func (c Comment) IsEmpty() bool { @@ -66,6 +67,18 @@ func (c *Comment) FetchPage() Page { return page } +func (c *Comment) FetchSite() Site { + if !c.Site.IsEmpty() { + return c.Site + } + + var site Site + lib.DB.Where("name = ?", c.SiteName).First(&site) + + c.Site = site + return site +} + func (c Comment) FetchChildren(filters ...func(db *gorm.DB) *gorm.DB) []Comment { children := []Comment{} fetchChildrenOnce(&children, c, filters...) // TODO: children 数量限制 @@ -94,12 +107,14 @@ type CookedComment struct { IsPending bool `json:"is_pending"` IsAllowReply bool `json:"is_allow_reply"` Rid uint `json:"rid"` - PageKey string `json:"page_key"` + BadgeName string `json:"badge_name"` + BadgeColor string `json:"badge_color"` Visible bool `json:"visible"` + PageKey string `json:"page_key"` SiteName string `json:"site_name"` } -func (c Comment) ToCooked() CookedComment { +func (c *Comment) ToCooked() CookedComment { user := c.FetchUser() //page := c.FetchPage() @@ -115,8 +130,10 @@ func (c Comment) ToCooked() CookedComment { IsPending: c.IsPending, IsAllowReply: c.IsAllowReply(), Rid: c.Rid, - PageKey: c.PageKey, + BadgeName: user.BadgeName, + BadgeColor: user.BadgeColor, Visible: true, + PageKey: c.PageKey, SiteName: c.SiteName, } } @@ -137,11 +154,13 @@ type CookedCommentForEmail struct { IsPending bool `json:"is_pending"` IsAllowReply bool `json:"is_allow_reply"` Rid uint `json:"rid"` + BadgeName string `json:"badge_name"` + BadgeColor string `json:"badge_color"` PageKey string `json:"page_key"` SiteName string `json:"site_name"` } -func (c Comment) ToCookedForEmail() CookedCommentForEmail { +func (c *Comment) ToCookedForEmail() CookedCommentForEmail { user := c.FetchUser() content, _ := lib.Marked(c.Content) @@ -161,12 +180,14 @@ func (c Comment) ToCookedForEmail() CookedCommentForEmail { IsPending: c.IsPending, IsAllowReply: c.IsAllowReply(), Rid: c.Rid, + BadgeName: user.BadgeName, + BadgeColor: user.BadgeColor, PageKey: c.PageKey, SiteName: c.SiteName, } } -func (c *Comment) AntiSpamCheck(echoCtx echo.Context) { +func (c *Comment) SpamCheck(echoCtx echo.Context) { setPending := func() { if c.IsPending { return diff --git a/model/notify.go b/model/notify.go new file mode 100644 index 000000000..324984484 --- /dev/null +++ b/model/notify.go @@ -0,0 +1,87 @@ +package model + +import ( + "fmt" + "time" + + "github.com/ArtalkJS/ArtalkGo/lib" + "gorm.io/gorm" +) + +type Notify struct { + gorm.Model + + UserID uint `gorm:"index"` // 通知对象 + CommentID uint `gorm:"index"` // 待查看的评论 + + IsRead bool + ReadAt time.Time + IsEmailed bool + EmailAt time.Time + + Key string `gorm:"index"` + + Comment Comment `gorm:"foreignKey:CommentID;references:ID"` +} + +func (n Notify) IsEmpty() bool { + return n.ID == 0 +} + +func (n *Notify) FetchComment() Comment { + if !n.Comment.IsEmpty() { + return n.Comment + } + + var comment Comment + lib.DB.First(&comment, n.CommentID) + + n.Comment = comment + return comment +} + +func (n *Notify) GetParentComment() Comment { + comment := n.FetchComment() + if comment.Rid == 0 { + return Comment{} + } + + pComment := FindComment(comment.Rid, comment.SiteName) + return pComment +} + +// 操作时的验证密钥(判断是否本人操作) +func (n *Notify) GenerateKey() { + n.Key = lib.GetMD5Hash(fmt.Sprintf("%v %v %v", n.UserID, n.CommentID, time.Now().Unix())) +} + +func (n *Notify) GetReadLink() string { + c := n.FetchComment() + + if !lib.ValidateURL(c.PageKey) { + return "" + } + + return lib.AddQueryToURL(c.PageKey, map[string]string{ + "atk_comment": fmt.Sprintf("%d", c.ID), + "atk_notify_key": n.Key, + }) +} + +func (n *Notify) SetInitial() error { + n.IsRead = false + n.IsEmailed = false + return lib.DB.Save(n).Error +} + +func (n *Notify) SetRead() error { + n.IsRead = true + n.ReadAt = time.Now() + return lib.DB.Save(n).Error +} + +func (n *Notify) SetEmailed() error { + n.IsEmailed = true + n.EmailAt = time.Now() + return lib.DB.Save(n).Error +} diff --git a/model/query.go b/model/query.go index 07f6b397a..2c56ff43a 100644 --- a/model/query.go +++ b/model/query.go @@ -58,6 +58,24 @@ func FindSiteByID(id uint) Site { return site } +func FindNotify(userID uint, commentID uint) Notify { + var notify Notify + lib.DB.Where("user_id = ? AND comment_id = ?", userID, commentID).First(¬ify) + return notify +} + +func FindNotifyByKey(key string) Notify { + var notify Notify + lib.DB.Where("key = ?", key).First(¬ify) + return notify +} + +func FindNotifyByID(id uint) Notify { + var notify Notify + lib.DB.First(¬ify, id) + return notify +} + func FindCreateSite(siteName string) Site { site := FindSite(siteName) if site.IsEmpty() { @@ -96,6 +114,14 @@ func FindCreateUser(name string, email string) User { return user } +func FindCreateNotify(userID uint, lookCommentID uint) Notify { + notify := FindNotify(userID, lookCommentID) + if notify.IsEmpty() { + notify = NewNotify(userID, lookCommentID) + } + return notify +} + func NewUser(name string, email string) User { user := User{ Name: name, @@ -121,7 +147,6 @@ func UpdateUser(user *User) error { func FindPage(key string, siteName string) Page { var page Page - // TODO: default site_name not null lib.DB.Where("key = ? AND site_name = ?", key, siteName).First(&page) return page } @@ -154,3 +179,20 @@ func UpdatePage(page *Page) error { } return err } + +func NewNotify(userID uint, commentID uint) Notify { + notify := Notify{ + UserID: userID, + CommentID: commentID, + IsRead: false, + IsEmailed: false, + } + notify.GenerateKey() + + err := lib.DB.Create(¬ify).Error + if err != nil { + logrus.Error("Create Notify error: ", err) + } + + return notify +} From 714d5122fb3b26fdc28fcb8413fa15888738ee78 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Tue, 12 Oct 2021 00:01:53 +0800 Subject: [PATCH 046/349] Fix email notify mark and render bug. --- go.mod | 9 ++++----- go.sum | 7 ------- http/api_main_add.go | 4 +++- lib/email/email.go | 15 ++++++++------- lib/email/render.go | 2 +- pkged/pkged.go | 2 +- 6 files changed, 17 insertions(+), 22 deletions(-) diff --git a/go.mod b/go.mod index d5a1da047..c6f7c3d05 100644 --- a/go.mod +++ b/go.mod @@ -3,20 +3,19 @@ module github.com/ArtalkJS/ArtalkGo go 1.16 require ( - github.com/PuerkitoBio/goquery v1.7.1 // indirect + github.com/PuerkitoBio/goquery v1.7.1 github.com/allegro/bigcache/v3 v3.0.0 - github.com/araddon/dateparse v0.0.0-20210429162001-6b43995a97de // indirect + github.com/araddon/dateparse v0.0.0-20210429162001-6b43995a97de github.com/eko/gocache/v2 v2.1.0 github.com/fsnotify/fsnotify v1.5.1 // indirect github.com/golang-jwt/jwt v3.2.2+incompatible - github.com/jeremywohl/flatten v1.0.1 // indirect + github.com/jeremywohl/flatten v1.0.1 github.com/kr/text v0.2.0 // indirect github.com/labstack/echo/v4 v4.5.0 github.com/markbates/pkger v0.17.1 github.com/mattn/go-isatty v0.0.13 // indirect github.com/mattn/go-sqlite3 v1.14.8 // indirect github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect - github.com/microcosm-cc/bluemonday v1.0.15 // indirect github.com/mitchellh/mapstructure v1.4.1 github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect github.com/onrik/logrus v0.9.0 @@ -29,7 +28,7 @@ require ( github.com/spf13/viper v1.8.1 github.com/steambap/captcha v1.4.1 github.com/x-cray/logrus-prefixed-formatter v0.5.2 - github.com/yuin/goldmark v1.4.0 // indirect + github.com/yuin/goldmark v1.4.0 golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 // indirect golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d // indirect golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf // indirect diff --git a/go.sum b/go.sum index 72d304ec3..306d6aeb2 100644 --- a/go.sum +++ b/go.sum @@ -75,12 +75,9 @@ github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hC github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= -github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= -github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk= -github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= @@ -278,8 +275,6 @@ github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsC github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= -github.com/gorilla/css v1.0.0 h1:BQqNyPTi50JCFMTw/b67hByjMVXZRwGha6wxVGkeihY= -github.com/gorilla/css v1.0.0/go.mod h1:Dn721qIggHpt4+EFCcTLTU/vk5ySda2ReITrtgBl60c= github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= @@ -448,8 +443,6 @@ github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0j github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d h1:5PJl274Y63IEHC+7izoQE9x6ikvDFZS2mDVS3drnohI= github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= -github.com/microcosm-cc/bluemonday v1.0.15 h1:J4uN+qPng9rvkBZBoBb8YGR+ijuklIMpSOZZLjYpbeY= -github.com/microcosm-cc/bluemonday v1.0.15/go.mod h1:ZLvAzeakRwrGnzQEvstVzVt3ZpqOF2+sdFr0Om+ce30= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= diff --git a/http/api_main_add.go b/http/api_main_add.go index 039a53ff4..9a36c9153 100644 --- a/http/api_main_add.go +++ b/http/api_main_add.go @@ -146,6 +146,7 @@ func AsyncSendEmail(comment *model.Comment, parentComment *model.Comment) { if !parentComment.IsEmpty() && !comment.IsPending { notify := model.FindCreateNotify(parentComment.UserID, comment.ID) + notify.Comment = *comment email.AsyncSend(¬ify) } @@ -158,7 +159,8 @@ func AsyncSendEmail(comment *model.Comment, parentComment *model.Comment) { } for _, admin := range admins { - notify := model.FindCreateNotify(parentComment.UserID, comment.ID) + notify := model.FindCreateNotify(admin.ID, comment.ID) + notify.Comment = *comment email.AsyncSendToAdmin(¬ify, &admin) // 发送邮件给管理员 } } diff --git a/lib/email/email.go b/lib/email/email.go index 872b8ec97..d66e4e07a 100644 --- a/lib/email/email.go +++ b/lib/email/email.go @@ -26,7 +26,7 @@ func AsyncSend(notify *model.Notify) { notify.SetInitial() - comment := notify.Comment + comment := notify.FetchComment() parentComment := notify.GetParentComment() from := comment.ToCookedForEmail() @@ -54,7 +54,7 @@ func AsyncSendToAdmin(notify *model.Notify, admin *model.User) { notify.SetInitial() - comment := notify.Comment + comment := notify.FetchComment() from := comment.ToCookedForEmail() to := model.CookedCommentForEmail{ Nick: admin.Name, @@ -66,11 +66,12 @@ func AsyncSendToAdmin(notify *model.Notify, admin *model.User) { body := RenderEmailTpl(notify, from, to) AddToQueue(Email{ - FromAddr: config.Instance.Email.SendAddr, - FromName: config.Instance.Email.SendName, - ToAddr: admin.Email, - Subject: subject, - Body: body, + FromAddr: config.Instance.Email.SendAddr, + FromName: config.Instance.Email.SendName, + ToAddr: admin.Email, + Subject: subject, + Body: body, + LinkedNotify: notify, }) }() } diff --git a/lib/email/render.go b/lib/email/render.go index 219e75f71..bf006380d 100644 --- a/lib/email/render.go +++ b/lib/email/render.go @@ -46,7 +46,7 @@ func RenderEmailTpl(notify *model.Notify, from model.CookedCommentForEmail, to m return tpl } -func RenderConfig(str string, notify *model.Notify, from, to model.CookedCommentForEmail) string { +func RenderConfig(str string, notify *model.Notify, from model.CookedCommentForEmail, to model.CookedCommentForEmail) string { for k, v := range config.Flat { str = strings.ReplaceAll(str, fmt.Sprintf("{{config.%s}}", k), fmt.Sprintf("%v", v)) } diff --git a/pkged/pkged.go b/pkged/pkged.go index a633f569e..cf8a47831 100644 --- a/pkged/pkged.go +++ b/pkged/pkged.go @@ -9,4 +9,4 @@ import ( "github.com/markbates/pkger/pkging/mem" ) -var _ = pkger.Apply(mem.UnmarshalEmbed([]byte(`1f8b08000000000000ffec5b6b53e33c96fe2b53feda801c272197aafd00e125a45f68689a269065ea2d59966d25b264243917bafabf6fc97612c7b9999da9dd995d7d00fb9cf348d65d3aca797e5984f95c5add5f56405498b8678847e0422848275f7fe42f7daeed5744585d6bd87d7b5b694fac411473a11ea00aadeee11c4eac6f30c256d78a2061d68975c591d5b5ac13eb098a002bab6bf5ba6f6f3f2516f2ed0dc74810f6f616f0b73757bf2cb339c3736c9d588f9cabedc2dc418542abfb9fd699f5f713eb8782145b5d25129c0b8f184aceacae25b5f4370fc7987998a145f76f878a0e2871ad13abcfaf09c552e7afab701670fd95ac0152edc13c50e469f8158e53ac9bf84417d95d282cad130bf12816584ae053a87051117c90b828d38f5951fcc80a87385390302c002552e50a3c4fdfc422567cf50260f6c14c40240eb158cb5ed1e849b81630da143da7d9ac75b614803085058314606f0685273f03033ec1d42b802925b122685bb34eef13b8ae2508235840af4002322f5184ee30c9c45514af0d91d75c0b3a5d41428d82506c0d19c2da86e434cf37e466cd29c8a54f2a5a68f479d3ee6c4a209e90b97562795041174a0ce43b2d89c013649af6238e5cac8b8c19e21e6141e11540c96a4559a73e6f6c6808836251d420392d8a219e17c5b19e4f0539c651519c47baa058082e740df13c9e425d489f425d303fd23d7774da1c8370e693e0182a542a3e86c9a6d24148c43d4c37412f04f23b02621c4099c8d3809f224a3053007a51bad255c1128f7e1aafbbef13f0ada63c88169f2d8dc03125082ac23f954a786e45b8d6501e7c022d13f93934e071c50422461591124bb9d52690521c080e5c122088420ca6f5a300f09ee0a4d4e12ee682b5408cc54482f7043245681922a0e713f501021ee128cb6cf9b28944984d205504b8104db8ef8369a30c90311418cce7219421983a9b660f3322319bf00804fc3492f29d963b772764bd16a3f853700f231241faa934ef09168b7c672ca60ac4424e884e22f4a1e063cacb83074f380878de1b0ed8d1806504f7303a8888b012041dfe8e545c94bee34bc615f117ab974d735a078f4890fd9fb68f98578d53150774f72b1854c74b04596574cc79f5a2c482a7879b6ae87c3faf06ce0f0c9b60f94e4fb3cd16448b6c23de00b889ef43ca4188cbbd16700a59703a9e29309ea99d36bd932332ddfeacb6025f60ac16f1ce6c574620a054e949e000469f89f7e694b6a89bf8bb9bb604d1b9c82a1800d9d630dd89f312b16313d9035624c252c1a8b46ee8f14910173108113d604affa054c7203114b2dca63b50221d3ac7607a2eb00a30251067d36330c527981d02e9235a850aa4b00a454b713b3e4a18e24c86024f31742906114f245602967a660cd1040114266c2230f4b0d8da4532441c20ced87e4b61cf50f359eaf7edc74a15a91dcbf51243f86e7d0ca5f4b7f6d395550fc5fadee24b2ca604e1fde9b7e7dfd232dfda788b9682e7021951e4e3402e402a6feb503b26ec234c00613ec5687ba6e566c6679b7a0a5da9209a008c42be55c2b21544c4f3289ec1f22ab802063c8a38034b07f8000471cac561c8d6b9b00cd00b3f8f3631110c08e20c12a1d795180b45ca4589a098b8506109e249509e1825e38e25bf8c58755d04e3c35fd2ff33efed28467732dfca4d29a6b7abb4edf484dc6327122ab5d86394ef94285cdfb6aa58f0c4cb17e5bf968bf25f78ae30d3875d0962777bf78c82447d00c82429e9894221a6344c9b458904a9a4dc929c0932d1dd2c12998eb14df3f2d83d9902150ae22bedcb8180e752194c2956040b5d47c5a3523163c123ac429c48901de1ff5a6f3eb9e1d309f61cb1aaa4d4af30296fc4db2953cf14040770d94cc0f378cbefde46ad46aa4b949ba00956675c0460360301d7a561383896c50e57f97df6ae0fc5badd21258b849de20896878920be4f399a00eacb90f3c9a6551291c412b37c2c948cb15fab03e863c1f71ab4f3b3cb88b6ce01b99ebb02ee328c67902a2c6618aa108ba87cc0cd40717ed5b1659892b8bc9e488561e4c21820182b14963f9ab85c12a57d0385cbe78229a40b4861ba9aea132816db87e825c68752291cc5f9456301313f45022ef2963d8d05f6c91c7ba73e177ad267c5e5673cc64c618ab5f3b238231c7095f5f31e13804a09e226d9d7f681f4b8908700c519740c035c18043038f8c11536a0dcad98ad121061c078764db00f9e7975c71115be9c035912b9079b7f0914382052a537787ba17aaf83c1ea8cbd0f96d6f5102061249d307c7982e6c5f3235f1f12d3252d5d3ee66079078d227cc004f41283b0507b30b13bf17c678f51ca10282c22b21c2c050889608081cfd956ce9925822a04e9a82fdb1956e91d62fa2f4894dc07d82ad6ca0042071d30c6104d769989c760592f17b2e0a732097d1ca6c7e95dc019611e9f6d1558b7d1b66eaef44a8877a0e76a730eee33026d4896b3ef284a6f1731445b1db289ce6f1bb60007bf2512b6a72212a34460e0128f8884ee4e9d63628111d99d8b129049bd3aeeb4268ca49b9dfec84100db97c38c782adcb290483bf9f96aca038acf0af69583bcbe92d79ae5855755fc8c8823f9172ee124ca0f1415d13cce674f15b85a5ed95440afeae0617f9a8fd24fa48ab09430c01257adcc2ae572747e26c9d11e59a759fe7e5205ac1d4eddc89f802f3dd12a700a83aa25093023557b8e4471d5eee262b9cc1dc7c6020611ac08aedeef5255ee8e2916cbdbfffde8d545db7e88c0a9b79e298ef7ef063c173e95a2708cd89f2461e962942a88bf3c2e54c41fedf1fc3a104b2448acb888dd2af809e33306205b7c06bebc73fc4c9ad5d5639e289e046744bbcddaa339cbae85964ac2c8d9b456d430a8b04f180a014dcf76638826a5448a476e49b580d12a6b11e99358f92a7a531d73a90291ef811b96ccb5dfa997584cf319969982e5feb416018294ba104de49681c244e2b296f220d8ca1344241050f12dbd4421cea76d419b2892fe4e1e4219e60f003d8a45dd598a48a00d21fd713b15fcd4630a55eaeceb0728b840e9d96ff95c5d37152410438ad51a0b3c01672b2120feeabdb0a2c100e7772099691ca73e7326c4e9ddce0a0d5d5214b51b07e90602c54951f42325797a3e5eafb71ccf632c4884d9869e280e8b32c36a79b65f2faa32dd648aaa98535a94cb49f205231f46ebb591b080629f9220dc28855c483d66009e6394b9af5ba6f539759fa9e8dfecc5c885f4368baeb054d90de1be33737a054c38f065f6243cefba495bea0108631241141286c502c493201d8ceb8df9204ae2f4b89315403b18f903b82458bfa698f43d3ff044247591f4034409552486697fa78af7842beca53f38e4977b2cddbd96ee44e135fdb7ecf00d655ec595ae70badfd201281121b925bfb3d1af325a7d4c9f68963b999613a141e9cd249769bf676f49f64b449cb5449c795c14e7f27ab31238c0f378f502e4822938d772b68facdf004aafbd969287dd2428c8eb3a281ea58ef99625ef962dbd5ce8e2e7336dfd8b8c5482b0f42024170ce58f75f6f988b44eaccc4d80ee4c90ecfe2453ac979e0d39fb99466bb3eae50ec2fa0d24caaf9d6fcaed54d4a3d93ab1a698795c805d6e310a210aa1635743c59c2e6a75bb79049d3ef46a5515b78c413a044ec4142fa3c60ee0c289e71f466cc7781d001fa9b11ed11e93fa2ff7130e00cb17054771b1e0f3c511e0fa8a601f2abf29d865960b996f21bbac7b7ce2bdd0a2e3bb1754f27f8fe25237f8ef27d613966a156bc9124a33d52ad03253dd714f17b2fbcbaa167c7a07095b0683ee8c64edf33bee95d46f6f013f8bb8979a9ff3a37cd7aa9dd5ceaddfbf7f9f587e56cac3c1b35d90de729faa986a28617e1a4feb6105f589a6fbcb625964ec1a766249f281adae7d62457a05e83ab546abd16ed49a9d54f357ba42742dc7766aa776fbd4693dd9adae53ef36db67edba5d3fefd4bfd8edaead673b917f79bac259ddf58ad6fd65e9e6bd58decb4aab5b3b3fb17a02a7a7e0a734ef5fd62d9f5d418533b153ab359db653ab9d58372408d786baddb1cf5bb5ceef13eb164a75811096726716cd76a7d5b05b8dd6ae2c5a76c7ceb318eac572670eb54eaddd6a38f5466777166d5d0a5db51fe4036b40da824bc52d9f595d3bedb7100b13d26c429a4d48b309693621cd26a4d984349b906613d26c429a4d48b309693621cd26a4d984349b906613d26c429a4d48b309693621cd26a4d984349b906613d26c429a4d48b309693621cd26a4d984349b906613d26c429a4d48b309693621cd26a4d984349b906613d26c429affed439af3354c176112540e7f2dc437ffce82f896558aa1d05bf72abf759af46315a3a6b5f30b13aaced2c3cec110ea0de4328aba71de58c65137eaeddd01d4cda75aad5bab771b8db37aad63dbf5e65600b50fa9dc1f415d77fe1d22a8ab14e2700075e3bc7138843a0d6f2ec751af3bdedd132abd0e815e873d6783288f7ace9b7f33ecb918c49ca14b932a8b4e5ecfb9ff17d37073c2ace6a4f57073f1e5477f220737aaf5ea74943b7c4ebc5e3381c36fc27fb1cf1f7a9dd94360ffa97157df4514bc8f29fb3308705d8d5da719ddb26fb1d77ff6dde85a8d5e6a9dc13dfca992e140deff380f93a1cb92e1648cbfb4239d47ff31f6c8e5877743e5e8c926afd1f5183adec2ad3f27a32b3e1e455fa3d76844eeeb97e1a8ff18bb113abf7bba9ce1dec5e2eee6b271ef8ca62efbae9043cf474f7c7e9feabe4e51f44811a9c9d17064df8fbfcd70eff2c375e6f1a87731bebbba68dc39a3e8dea98528f26297d46cb77e717ef7f43cc357923c30d542d1f3ccbd9924af4e27f1facf8977dde15ebf26fd17bb7deb3cc6deb8f1ad379e4dd1957ece670fe37938e8878bd1f0b53358a5a7bedba709acd73a83421d477dfa81faf3103fc5b11bcd6337faa95ea3f9f4d5912dd4bf9e8cfa34197d701bdd04c1dd58974911b7fe75327a1928145d4fe0cbf3c7fdf85aebc7ae339fa2312fd429affb982f747ae474241c7e0f061f17b3fbab6fd168acecd14b68df0e1fe9abd359bcbe3cc6aed33877a34e327a52eaf5e52b83c386f2fa9dd9fd78304337416b402e6dad1fbd7cef0c6887b8fdeb042e065f9ab78be0fcb577793ec27cd01b31ef4ab66f9d3fbe14c7c7cf7ea73e7af94a47bdcb1efe717989d863e8f665fbb6aec70eff0feb1f5cfd7dc199c2cc3bbcdeaf509f66cc349f6a4ed76977ede659abdd706c677bc1ffc71833b566b3e9b4ec5ad3debdd63aff230bbed36c9d37ed96d3d8b3e23b86326328338632632833863263283386326328338632632833d5c824863263283386326328330594a1cc6c9a0d65c650660c65c650660c65a60032941943993194194399319419439931941943993194194399319419439931941943993194194399319419439931941943993194194399f93f1babbf0a5cfe673266969902c23c3caf409729e09601d44ebb1259c6e93aadae533bebd41a4efbbcf5cf26cb38b6dde8b45a1ddbf95f0d9eaed55b6dbb6db7ebffede069a76de832ffe253b0385b0a5c99def51f4ff6b79fc3e7cbeb413fb4dde1ec4b6f3c4fb92283fe3c7423d41944cfc960dcf8f3a11fd2d7e1f72f3d72110c7a176d77f86cbffeb81cc3fef50239cff6c38fafcfcf7fbcaafbdea08ce1decde3ec76f83cf786d479f8f1f5f5f6f9f9f2f6e7b7a9fb72197a7d4adcfe4f32e87f9bbaec91baec7b6730a1d70fc3e7c9c8f9491e02aef30a1efa35eaf5ff08525ece934dbc8852af7e3945ecfb665ae6c5a39b47fe307ca45e44c7a31fb53a1c3edab0370be0b0197b7d1ababddac7ab732d474ff6fc767cb1fec6cd63ecf5e7f461f2387dad3fabd1b0693ff43a367c7994a3a7c69f0fbd0e1f0daf270f016fbf469d097e6afca9d30daee6fc6edc1c8c8673e92e2e5fdcfa5739eafdd1be758285c6de3a5fa7a39bc997de783685378fcabd6a1ce58e64f3091b3e82e123183e82e123183e82e123183e82e123183e82e123183e82e123183e82e1236428c347d8341b3e82e123183e82e123183e420164f808868f60f808868f60f808868f60f808868f60f808868f60f808868f60f808868f60f808868f60f808868f60f808868f60f808868ff0af1f0cfdfbbf000000ffff010000ffff8a2b8505d3bb0000`))) +var _ = pkger.Apply(mem.UnmarshalEmbed([]byte(`1f8b08000000000000ffec7d5b6fdb38d7ee5f79a1db3aa165f90cec8b26691c679a4393364efc625050122dd1a24895a47cc820ff7d83946ccb960f0af6ec0fdf05316824aef590e2996bd1ebc1fc63613a61c2eaff63055886a97beeb1187ce51292e8f6397f1930a5bfc2dcea5be085913446028c188f9e13e8a11c74f6f57178366056cd1ac609e3f211cad0ea1f2fb566ddc318597d2b86985a35eb8a7956dfb26ad64fc80324d5e77e09c4054089c7310501032ea6c5fc4f8cc96ab5ba83d20badfe7fad73ebef9af52c2141565ff214e589270405a356df122af51f1f2588fa887acbfe7f8eb501788c4e7060d5ac01bbc60409f509d59cf380a90f659da1a5c78b897d05bf4289c6bae904ab5abb4b898455b33c16271c090126044a541404ef3829a6c9fbbc987c27d8d5692a21a688038285cc0568a1dff832916cfd0260f6c12ce1e124447c93f68b4a5fc04d0279db49bfd16ad9bd9200602a11a79000e4cf21f7c52e8c109c48ec6d24610c0ba975760ea99f4a4cf6a844ea4a82368ad86f6d122a5f21e5350b8962034408edad54a3d5de4ab7ec4621bdf349490afdb468d57bdba94d5d63e8b11d284822bcb06a960f2574a14040fc213b49e0733cd3e3826217a9f620ea311fd3a0f00aa0a07631ad72b79b5b124c215f16259e981593215a149353b5440ae904c5c5e4225615459c33aeda8416c90caa4a4e0854159bc46abe9d5c06a720ab057714154a999cc2644be31404a018ea69761418331f9d0425518076daf798221e61c92e300301fb93223d1c05c02b86ec0e83040550a4e22c60671ec1884a00fd586f9a55b0d8279fc6abd9f2097869e48ea2f9676bc35142b00725669fcac57db7225c49080b3e8116a9f81c1ab0a462069e781591020951ea1348080ab83a2c030f7a210233e72400fc4951ba33e090fa4b1792909118785078d0c77007c1a1ef330a7c285102f9ee8c7111e3b40312c42301fea4904a4c76211cfa132cdf41c0621467b559bd6c233d44234824062ef4223699805973172012c811582c422842306b6cab7d44b14034623108d8592cc41fb23b3bf642369bb5977c0aee230fc7907c2a8fde01f293b9982be04b116195852bbbe47dc676671f8ad40e920f6703ece9c05d04f39177141123c9b177fc3b4232bef39d89a04ce2c972fdb2add66df0b100d9df59f7847add395571400dbf844175bcf020ad8c4e18ab5e9584336d5c5543e7c64935706efd6c83c51f72961907205e6686c316c04d2713481808d1eea8058c401a9c4de7124ce772af4e591e1e9e953fabb460c21192cb646fb16b25e050486db91cc128b3fc6049ba47dd74b2bf6b7720aa14510503202d4dd3bd383fe57b4ea10360896324248c77f60d353fb1c77802428f1c51e97f50c85310bdf3f29328aea7ce29985a0bb4024c728fd1d929986411a2c740caa4acd0000dab50358ddbf3d129f4220f78614a238ea08f78e978c81049e031ba376fa6291c067231d73ee561ac90b1dcb30faf3098ed9727508849e9a05c6bd51c730e565f203ec31e3a9cbfbcb0569a45e9442d6a0afe15a458e2f723a50021fd92753d451cc5cb390b89f662656988307d0f5380e98420afbcc4723565f36d3981ae90d08b00f242566ac1ae16c4d8f7099ac3dded6f0d0c581c330a569ef71188c708e3c721258b7217a0767c166f636218608f5188b9da5012c425dead4a0c79e4428984f629f851e59ebd7e1751704793e35f527f3337f32406ac7cd3d3c81895ba602f4e489f95ea272555279f1e0de8ee4efbb51e0b28e5f28052fc215822a7ac950967a99fefefbf57fbfb6fb490882ac35b80c42d1fc47190ca7700a9c03b722cbd101112ea8e963cf564ba3b368c721ca989c353a167edb67ae502443320438e2752fba801cb53bb604290c488ab364a16ef5433e12c463244a900993bf17b738ee58a4f673860ad55c9a95e61ba7ba697736a5f1b044770d9da428ba474e55046ade7be8ba59b7a1192e78c07603e070153b5a1283855c41ee77fbb59dee4704766ea4d353e012d4fbc3ff33fcaac57c30d095ea6f46ccfed05c79309615e04c844848c45db5a81799a0844f329b8a34c26b603e004717650515ecd99d22b5932b99cb91cee534ce79048c4e708ca10f178d744cf40497eb95452cc70b2bb310a8960ecc2047830915eb8fbd1d465024be5dd48b46bd9cc20594202f5b1a06c68c4cb6ec00a3381424a1427f9556d01b138f3385ce63d7b967034c10be49f4d18577bcd6e7597a9bef326beda0d8fa8ca26e2b67abd5955029d2a6d9fadb68dd01e2aaf8601a1dcdd95b681655f785bbf5a03ec9c25884a4490f25a97e7980126d13115805272eca6d9201d02a9e5248e018afbdd290c706110c0e0e807d7d88030b762b192430f01cab20ba643f0cc9d3f8da8f0e51c48d3d8cdc6f90490a3000b99dd6d1e822a5b07066be7ea104cb7f51820a558cf18b69ac9ace838b08d77a00f20bdd92fc0eac70f2f464754401d081ee2f20026f69b0734891bf993c601a510219088c778358d0a101cc3008109a3a56f669a18ca10e86d64574f915cafae7d7200656679969532d17f82548a4380525bd60a1036bc23ca047ad13e35f629dc958b65f1b4a3024e50a8bdb77dc094ea9f4db6e4aa57cbb2855487112ab54d6bb6d6f32125508a74b5924fa294a19040af3484dbe8fccaaa0438fa2d9ed2030d11c84b39022ef6314fc9fedc3926e1c8c3fb4b911c52a10ea8bdda94626d6fa88f1c05d04325ccb12fc39206c708f0fcf8642c20e8bca05fdfb26c7e875292d54951153fc7fc44f9859b5ce1e5a66445344bf2a553052e57f77e15d0eb36f86832cb67e92772c54808182081aa36669d73353b3f93e5e4886cf2ac7e34ac029e608254277f02bebaf5a8022730a85a9300515c75e4709c541d2ec6577bdc696cc26110c38ae0eae32e64e5e19821beb22e0fa3d7b7b587211ce99b9f4c707a7cb7e079e253390a26c9e12c29d59b9116e0c9caf4a8883f39e2f99d32121ec789643c71abe023cae61440bafc0c7c7571fd993cebfbeb3c531205e7daf8564ee5797605b912628acf67765142a144134cbd10106d274ea117ed64922c7677444b18af8be6b1b2ea767fcfd816274cc880e767e09626bbd4d92b1788cff21596a982d5f9b449020f12e2422f12250581a940bb52c282a054268871c0a16425b9f042942fdb82547933ea73211461fe00d027883b8d55d2e3de56424774e8c4443badb9c9a72dbc8217aaadc5d5737d755948810412243758e073385f27023c59bf17763418a0dc01cb54d344df96648944df136e7c9fa544906c89bc242d2627b1144c1bd76b11457265f06f7647a14f8ba228618414d3bb59f2959fcf87cd26876940d084e020dcfaaa580a35f8002d90975d059454b9b5b931de9090d96def2183555ff763965df0600630cbbb2eea0a3501608263e8859822be044914e8c9b039188fa204d2e6465601e512e40fe0e260f3aa31fa3d373862acdd1df500714a244ea0ee7e2df89332897cfdab517ead4af5e9b1b2e50baffacf6a9cb6847913d7b28275ad64f9e5947a15f1ba486537acce0b954eb902e99b5f26f4a0646f6976119164ed4d324f88a03cbd3912380ad02259bf00b1a412aad1cb77ebcd1bf0f4b5e22ae523370d0ae9f5d02ad749bbd2254ddef925b958aaeae7d37bf3e399901c536d6e8825f5f2c7a6f87cb659352b33c6a13be738bb28ca049b05be9506ab608cbc79b919be7903a99cd8eded745727d59cb56ad60c519f71b0cf5df542e885b051af864a1859da4ebd7502ad1f6a8ba88a5b85b71d03a77c86560186477061e44f8e23cab18547c0275aac66b44f85fa975be34780bbbef8495cc2d9627902b8f1c20fa17267fc909ab3f4e04029573cdbd7f7690f78a607a145f7f32068c70b3d89d3cee8df35eb2712721db64b534232d13a663713dd315f55b2ff8f552da6f90e62ba0a2dae1c343d6077ccaf0005013b8f99af73bce47677dfb2cfedb6f5f1f151b32659638e8773f7b398c633991005c574a223bc7d24a1323ffaff58348bcbdec06a96c0efc8eaf7da352b563b49bf61373bcd6ed36eda5af25bef347dab516fd86776fdccb67fd6ebfd7aafdf6a9d779c66a7deadf7ec2ff56ebfaef60d2c7efbaa6bb25e527b63ff1feb0acdacbeddee743a8d86a3fb1da974b7d3a959f704d3c8ea3b356b4899d56fb76dbb6ed7ac5fd8b7fa2df536506fdd7acd7af25531f59af508fddf5ec07ed7adfe7feb35fddfdf35ebabb66913e4a92f3eab87dd769c6eb761aba6dd0b2d719cb6ed349bf647cdba3b8c6fadf0ebf67dd4accb4fe22f3097e19e3c8d5ea7e774ea9d559e66dd719ca6ddee7dd4ace7f5505c10a6ec53d5dc0b126543d4ac2bcdb5f662956280a87e7ed7d171faf547feaafae56f3d6f42c44d90ffa13698207f13e46f82fc4d90bf09f23741fe26c8df04f99b207f13e46f82fc0f2b4d90bf09f23741fe26c8df04f99b207f13e46f82fc4d90bf09f23741fe26c8ff20d004f99b207f13e46f82fc4d90bf09f23741fe26c8df04f99b207f13e46f82fc4d90bf09f23741fe26c8df04f99b207f13e46f82fc4d90ffc747be15aa9a4641e5e0eb42c4ff471666ba6a790239a27253de268ffed8b1e20b3c02e5a9c294c8736d991c25156c2157bc8266c759110b9a8d7a054641cb69d876a35162144c20112728058e6377bb6b4a819d530a3abd6ed7eefecb94824dc87fcfeef6ec4eb75199529037b032a560833f4429d8434368f79abd96bda614e85158710abaffa39c02e0331d84b6452cd8ccc55c5b260f6cf8019bf8ff6c62e7e1fff984d88eff2f86f267e89dfd208bd1df6c17660739b4d6d7db89f578f3f5cbf32012c31bd9f107ddd48dc9143a76ef613a9f7957cdbf94fe3285977f1e46de9fcb8b0e72ee137ff03271e36b397eb57bc307f84ba6a3a178786e87e9c8a5e9289aa22fdd3860ddf180348637f775345a90c7e75bfc36bae763e776e68f5ad103be8fdfe2311ec7c38e37b88ec603928edfd9e2eee6a239bc1acebd9ba0338e7ba97f69bfc3d7843c4cbf3595ec2dee2dc78397e5f7d1828ce98ff69d73d11cdedccfdc0189869777f3bbabe07d1cbf75dcd1f572dc20e9f7d7a79977c516f7af17cd87e5f0cb8f1bd919d3db99fbdc4ae1e89e4f5eebedc7c1edf2fb7bab831ae3a5dba8a76f8d5eea0f5e52ffc6ee3d5ef622f8faf6e5b2d01f8f836f01bcb925e3691d23472ec7af1702bdf4041cb55479b8d0e608bedecfddc175eb2126a9abdaf86c6377d09bc277397f1b3d4570d4a20fd3a739bafcbad4756cdccebcf88978d85ebe8d9e12fff5ae7da7e5aa8dbde503deb471d5170fd3db39babc78771b8b647cf9757a77f5b579d718c70fce1341373fe478f032759ddbd01f90993b4d52b7d1220f0d3bf4623f71b15d779dafedbbe9c51c5d093cbc795272e25fd5f16be356bc8d5a7c38ed44b3bfae92607893907610dcc62dec395f3bb7b15f7f588ea97f25badf1bdfbe3c5ef6e68f01eb7a57ad1faee3132f7e8986df6e5bc36fd74b7f702d60dd9fe598ff63fd3f1e6213cea844d43f7e6cad519fa3c2d57beae06ad4fb2da7df70ce9b3dbbd969385de75fa3c2759c56d36efe6be796edb49bddbab33a23da2da7de6bb5bbf543e7d60e7eddbe43e7d611fcc173ab9cc76936dbed96a1c2192a9ca1c2192a9ca1c2192a9ca1c2192a9ca1c215d5860a67a870860a67a870860a771466a870860ab74f63a870860a67a870860a67a870860a67a870860a771861a870860a67a870860a67a870860a67a870860a67a870860a67a870860a67a870860a67a870860a67a870860a67a870860a67a870ff3b882ceb48fe7f9309b72a1460eaa345051a5c01b7621434bacda324b83297a0d5ec39f5cebf4882735a4dbbf5ff8b4cd0727a4ebdd1edb4ab9309b206562713acf19f201334db76abb5f9ffeae85130243843823bb67714977981017779fded67fdfed7e8e5e27a3808ebee68fee572ba60fec016c3c1227463af378c5fd2e1b4f9d7e320246fa31f5f2ef1d76078f9b5eb8e5eea6fcf175338b85e7a8d97fae3f3edcbcbb737f97039dcc530ffe669fe7df4b2f047a4f1f87cfbf6fde5e5e2fbaffb99fb7a11fa0382ddc12f3c1cdccf5cfa445cfaa3378cc8f5e3e8251a377ee1c780a9b282c7814dfcc1b740b3ef7ed6b11f13e23b17338ffed8ce4bfd647cf3c41e474fc48fc974fc6c3b70f4548797f3008e5a893f20a17b69bfbf35aec5f8677df17dfa75f38d9ba7c41f2cc863f4347b735ee478d4aa3f5ef6eaf0f5498c7f36ff7abcecb1f1e83a7a0c58f72dee45e867f32f956f78b56077d3d6703c5a087779f1ea3ab7627cf9adfbbd112c15f67be37636be8934930ede3c49f7aa79920596ad4564a83d87da60a83d86da63a83d86da63a83d86da63a83d86da63a83d86da63a83d879586da63a83d86da63a83d86da63a83d86da63a83d86da63a83d86da63a83d078186da63a83d86da63a83d86da63a83d86da63a83d86da63a83d86da63a83d86da63a83d86da63a83d86da63a83d86da63a83d86daf3f1f1f17f010000ffff010000ffff8806ce659ac80000`))) From 4a9484a544abcd45123142617196de530d79e07b Mon Sep 17 00:00:00 2001 From: qwqcode Date: Tue, 12 Oct 2021 14:38:44 +0800 Subject: [PATCH 047/349] Unread message mark. --- artalk-go.example.yml | 2 +- http/api_main_get.go | 24 +++++++++++++++++++++--- http/api_user_get.go | 25 ++++++++++--------------- model/notify.go | 20 ++++++++++++++++++++ model/query.go | 16 ++++++++++++++++ 5 files changed, 68 insertions(+), 19 deletions(-) diff --git a/artalk-go.example.yml b/artalk-go.example.yml index b4820cb74..475e9f8e5 100644 --- a/artalk-go.example.yml +++ b/artalk-go.example.yml @@ -33,7 +33,7 @@ admin_users: name: 'admin' email: 'admin@example.com' password: '' - badge_name: '管理员' + badge_name: 'Verified' badge_color: '#FF6C00' # 登录超时 (单位:秒) diff --git a/http/api_main_get.go b/http/api_main_get.go index dd19b4372..eb613ec0b 100644 --- a/http/api_main_get.go +++ b/http/api_main_get.go @@ -15,9 +15,10 @@ type ParamsGet struct { Offset int `mapstructure:"offset"` // Message Center + Type string `mapstructure:"type"` Name string `mapstructure:"name"` Email string `mapstructure:"email"` - Type string `mapstructure:"type"` + User *model.User SiteName string `mapstructure:"site_name"` SiteID uint @@ -29,6 +30,8 @@ type ResponseGet struct { Total int64 `json:"total"` TotalParents int64 `json:"total_parents"` Page model.CookedPage `json:"page"` + Unread []model.CookedNotify `json:"unread"` + UnreadCount int `json:"unread_count"` } // 获取评论查询实例 @@ -60,6 +63,13 @@ func ActionGet(c echo.Context) error { page = model.FindPage(p.PageKey, p.SiteName) } + // find user + var user model.User + if p.Name != "" && p.Email != "" { + user = model.FindUser(p.Name, p.Email) + p.User = &user + } + // comment parents var comments []model.Comment @@ -118,23 +128,31 @@ func ActionGet(c echo.Context) error { total := CountComments(GetCommentQuery(c, p, p.SiteID)) totalParents := CountComments(GetCommentQuery(c, p, p.SiteID).Scopes(ParentComment())) + // unread notifies + var unreadNotifies = []model.CookedNotify{} + if p.User != nil { + unreadNotifies = model.FindUnreadNotifies(p.User.ID) + } + return RespData(c, ResponseGet{ Comments: cookedComments, Total: total, TotalParents: totalParents, Page: page.ToCooked(), + Unread: unreadNotifies, + UnreadCount: len(unreadNotifies), }) } // 请求是否为 通知中心数据 func IsMsgCenter(p ParamsGet) bool { - return p.Name != "" && p.Email != "" && p.Type != "" + return p.Type != "" && p.User != nil && !p.User.IsEmpty() } // TODO: 重构 MsgCenter func MsgCenter(c echo.Context, p ParamsGet, siteID uint) func(db *gorm.DB) *gorm.DB { return func(db *gorm.DB) *gorm.DB { - user := model.FindUser(p.Name, p.Email) + user := p.User isAdminReq := CheckIsAdminReq(c) // admin_only 检测 diff --git a/http/api_user_get.go b/http/api_user_get.go index 1b742638f..021460376 100644 --- a/http/api_user_get.go +++ b/http/api_user_get.go @@ -22,10 +22,10 @@ func ActionUserGet(c echo.Context) error { if user.IsEmpty() || user.Name != p.Name || user.Email != p.Email { return RespData(c, Map{ - "user": nil, - "is_login": false, - "unread_msg": 0, - "unread_comments": []int{}, + "user": nil, + "is_login": false, + "unread": []interface{}{}, + "unread_count": 0, }) } @@ -37,18 +37,13 @@ func ActionUserGet(c echo.Context) error { user = tUser } - // unread_msg - var notifications []model.Notify - lib.DB.Where("user_id = ?", user.ID).Find(¬ifications) - unreadComments := []uint{} - for _, notify := range notifications { - unreadComments = append(unreadComments, notify.CommentID) - } + // unread notifies + unreadNotifies := model.FindUnreadNotifies(user.ID) return RespData(c, Map{ - "user": user.ToCooked(), - "is_login": isLogin, - "unread_msg": 0, - "unread_comments": unreadComments, + "user": user.ToCooked(), + "is_login": isLogin, + "unread": unreadNotifies, + "unread_count": len(unreadNotifies), }) } diff --git a/model/notify.go b/model/notify.go index 324984484..7bcb047e7 100644 --- a/model/notify.go +++ b/model/notify.go @@ -85,3 +85,23 @@ func (n *Notify) SetEmailed() error { n.EmailAt = time.Now() return lib.DB.Save(n).Error } + +type CookedNotify struct { + ID uint `json:"id"` + UserID uint `json:"user_id"` + CommentID uint `json:"comment_id"` + IsRead bool `json:"is_read"` + IsEmailed bool `json:"is_emailed"` + ReadLink string `json:"read_link"` +} + +func (n *Notify) ToCooked() CookedNotify { + return CookedNotify{ + ID: n.ID, + UserID: n.UserID, + CommentID: n.CommentID, + IsRead: n.IsRead, + IsEmailed: n.IsEmailed, + ReadLink: n.GetReadLink(), + } +} diff --git a/model/query.go b/model/query.go index 2c56ff43a..958cdd565 100644 --- a/model/query.go +++ b/model/query.go @@ -196,3 +196,19 @@ func NewNotify(userID uint, commentID uint) Notify { return notify } + +func FindUnreadNotifies(userID uint) []CookedNotify { + if userID == 0 { + return []CookedNotify{} + } + + var notifies []Notify + lib.DB.Where("user_id = ? AND is_read = 0", userID).Find(¬ifies) + + cookedNotifies := []CookedNotify{} + for _, n := range notifies { + cookedNotifies = append(cookedNotifies, n.ToCooked()) + } + + return cookedNotifies +} From 12a624555baa34810cfe036ae5b55552600e7ceb Mon Sep 17 00:00:00 2001 From: qwqcode Date: Wed, 13 Oct 2021 18:40:14 +0800 Subject: [PATCH 048/349] Mark all as read. --- http/api_admin_site_add.go | 15 ++++++++++++--- http/api_main_add.go | 1 + http/api_main_get.go | 9 ++++++++- http/api_main_mark_read.go | 18 ++++++++++++++++++ model/query.go | 20 ++++++++++++++++++++ 5 files changed, 59 insertions(+), 4 deletions(-) diff --git a/http/api_admin_site_add.go b/http/api_admin_site_add.go index a763fa2f6..13e9b96a5 100644 --- a/http/api_admin_site_add.go +++ b/http/api_admin_site_add.go @@ -1,6 +1,8 @@ package http import ( + "strings" + "github.com/ArtalkJS/ArtalkGo/lib" "github.com/ArtalkJS/ArtalkGo/model" "github.com/labstack/echo/v4" @@ -21,8 +23,13 @@ func ActionAdminSiteAdd(c echo.Context) error { return resp } - if p.Urls != "" && !lib.ValidateURL(p.Urls) { - return RespError(c, "Invalid url") + if p.Urls != "" { + urls := strings.Split(p.Urls, ",") + for _, url := range urls { + if !lib.ValidateURL(url) { + return RespError(c, "Invalid url exist") + } + } } if p.Name == lib.ATK_SITE_ALL { @@ -41,5 +48,7 @@ func ActionAdminSiteAdd(c echo.Context) error { return RespError(c, "site 创建失败") } - return RespSuccess(c) + return RespData(c, Map{ + "site": site.ToCooked(), + }) } diff --git a/http/api_main_add.go b/http/api_main_add.go index 9a36c9153..db39a50c6 100644 --- a/http/api_main_add.go +++ b/http/api_main_add.go @@ -144,6 +144,7 @@ func AsyncSendEmail(comment *model.Comment, parentComment *model.Comment) { return } + // TODO 管理员自己评论问题,重复发送,管理员太吵了(别人回复别人都会发提醒) if !parentComment.IsEmpty() && !comment.IsPending { notify := model.FindCreateNotify(parentComment.UserID, comment.ID) notify.Comment = *comment diff --git a/http/api_main_get.go b/http/api_main_get.go index eb613ec0b..f56a6c007 100644 --- a/http/api_main_get.go +++ b/http/api_main_get.go @@ -1,6 +1,7 @@ package http import ( + "fmt" "strings" "github.com/ArtalkJS/ArtalkGo/lib" @@ -50,7 +51,6 @@ func ActionGet(c echo.Context) error { if isOK, resp := ParamsDecode(c, ParamsGet{}, &p); !isOK { return resp } - isMsgCenter := IsMsgCenter(p) // find site if isOK, resp := CheckSite(c, &p.SiteName, &p.SiteID, &p.SiteAll); !isOK { @@ -70,6 +70,8 @@ func ActionGet(c echo.Context) error { p.User = &user } + isMsgCenter := IsMsgCenter(p) + // comment parents var comments []model.Comment @@ -128,6 +130,11 @@ func ActionGet(c echo.Context) error { total := CountComments(GetCommentQuery(c, p, p.SiteID)) totalParents := CountComments(GetCommentQuery(c, p, p.SiteID).Scopes(ParentComment())) + if isMsgCenter { + // mark all as read + fmt.Println(model.NotifyMarkAllAsRead(p.Name, p.Email)) + } + // unread notifies var unreadNotifies = []model.CookedNotify{} if p.User != nil { diff --git a/http/api_main_mark_read.go b/http/api_main_mark_read.go index 0e0f2a68e..1603d3766 100644 --- a/http/api_main_mark_read.go +++ b/http/api_main_mark_read.go @@ -8,6 +8,10 @@ import ( type ParamsMarkRead struct { NotifyKey string `mapstructure:"notify_key"` + Name string `mapstructure:"name"` + Email string `mapstructure:"email"` + AllRead bool `mapstructure:"all_read"` + SiteName string `mapstructure:"site_name"` SiteID uint SiteAll bool @@ -24,6 +28,20 @@ func ActionMarkRead(c echo.Context) error { return resp } + // all read + if p.AllRead { + if p.Name == "" || p.Email == "" { + return RespError(c, "need username and email") + } + + err := model.NotifyMarkAllAsRead(p.Name, p.Email) + if err != nil { + return RespError(c, err.Error()) + } + + return RespSuccess(c) + } + // find notify notify := model.FindNotifyByKey(p.NotifyKey) if notify.IsEmpty() { diff --git a/model/query.go b/model/query.go index 958cdd565..4be1dffc3 100644 --- a/model/query.go +++ b/model/query.go @@ -1,6 +1,8 @@ package model import ( + "errors" + "github.com/ArtalkJS/ArtalkGo/lib" "github.com/sirupsen/logrus" "gorm.io/gorm" @@ -212,3 +214,21 @@ func FindUnreadNotifies(userID uint) []CookedNotify { return cookedNotifies } + +func NotifyMarkAllAsRead(name string, email string) error { + user := FindUser(name, email) + if user.IsEmpty() { + return errors.New("user not found") + } + + // find all + var notifies []Notify + lib.DB.Where("user_id = ?", user.ID).Find(¬ifies) + + // mark as read + for _, n := range notifies { + n.SetRead() + } + + return nil +} From 4ae5a3fd029b8df1a4e2ef90a4eb465a889fe870 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Wed, 13 Oct 2021 19:49:37 +0800 Subject: [PATCH 049/349] Reduce query to improve performance. --- http/api_captcha.go | 6 ++--- http/api_main_get.go | 10 +++----- http/api_main_mark_read.go | 20 ++++++++++++++- http/api_user_get.go | 3 +-- http/permission.go | 36 ++++++++------------------- lib/cache.go | 3 +++ model/comment.go | 2 +- model/query.go | 51 ++++++++++++++++++++++++-------------- 8 files changed, 73 insertions(+), 58 deletions(-) diff --git a/http/api_captcha.go b/http/api_captcha.go index 40cdaf325..30447188e 100644 --- a/http/api_captcha.go +++ b/http/api_captcha.go @@ -46,7 +46,7 @@ func ActionCaptchaCheck(c echo.Context) error { func GetCaptchaRealCode(ip string) string { realVal := "" - if val, err := lib.CACHE.Get(permCtx, "captcha:"+ip); err == nil { + if val, err := lib.CACHE.Get(lib.Ctx, "captcha:"+ip); err == nil { realVal = string(val.([]byte)) } return strings.ToLower(realVal) @@ -60,11 +60,11 @@ func GetNewCaptchaImageBase64(ip string) string { base64 := "data:image/png;base64," + base64.StdEncoding.EncodeToString(pngBuffer.Bytes()) // save real code - lib.CACHE.Set(permCtx, "captcha:"+ip, []byte(data.Text), &store.Options{Expiration: 5 * time.Minute}) // 5分钟失效 + lib.CACHE.Set(lib.Ctx, "captcha:"+ip, []byte(data.Text), &store.Options{Expiration: 5 * time.Minute}) // 5分钟失效 return base64 } func DisposeCaptcha(ip string) { - lib.CACHE.Delete(permCtx, "captcha:"+ip) + lib.CACHE.Delete(lib.Ctx, "captcha:"+ip) } diff --git a/http/api_main_get.go b/http/api_main_get.go index f56a6c007..0b2c01995 100644 --- a/http/api_main_get.go +++ b/http/api_main_get.go @@ -1,7 +1,6 @@ package http import ( - "fmt" "strings" "github.com/ArtalkJS/ArtalkGo/lib" @@ -67,7 +66,7 @@ func ActionGet(c echo.Context) error { var user model.User if p.Name != "" && p.Email != "" { user = model.FindUser(p.Name, p.Email) - p.User = &user + p.User = &user // init params user field } isMsgCenter := IsMsgCenter(p) @@ -132,7 +131,7 @@ func ActionGet(c echo.Context) error { if isMsgCenter { // mark all as read - fmt.Println(model.NotifyMarkAllAsRead(p.Name, p.Email)) + NotifyMarkAllAsRead(p.User.ID) } // unread notifies @@ -231,9 +230,8 @@ func AllowedComment(c echo.Context, p ParamsGet) func(db *gorm.DB) *gorm.DB { // 显示个人全部评论 if p.Name != "" && p.Email != "" { - user := model.FindUser(p.Name, p.Email) - if !user.IsEmpty() { - return db.Where("is_pending = 0 OR (is_pending = 1 AND user_id = ?)", user.ID) + if !p.User.IsEmpty() { + return db.Where("is_pending = 0 OR (is_pending = 1 AND user_id = ?)", p.User.ID) } } diff --git a/http/api_main_mark_read.go b/http/api_main_mark_read.go index 1603d3766..c9c6ec817 100644 --- a/http/api_main_mark_read.go +++ b/http/api_main_mark_read.go @@ -1,6 +1,10 @@ package http import ( + "errors" + "time" + + "github.com/ArtalkJS/ArtalkGo/lib" "github.com/ArtalkJS/ArtalkGo/model" "github.com/labstack/echo/v4" ) @@ -34,7 +38,8 @@ func ActionMarkRead(c echo.Context) error { return RespError(c, "need username and email") } - err := model.NotifyMarkAllAsRead(p.Name, p.Email) + user := model.FindUser(p.Name, p.Email) + err := NotifyMarkAllAsRead(user.ID) if err != nil { return RespError(c, err.Error()) } @@ -60,3 +65,16 @@ func ActionMarkRead(c echo.Context) error { return RespSuccess(c) } + +func NotifyMarkAllAsRead(userID uint) error { + if userID == 0 { + return errors.New("user not found") + } + + lib.DB.Model(&model.Notify{}).Where("user_id = ?", userID).Updates(&model.Notify{ + IsRead: true, + ReadAt: time.Now(), + }) + + return nil +} diff --git a/http/api_user_get.go b/http/api_user_get.go index 021460376..2fe5d0726 100644 --- a/http/api_user_get.go +++ b/http/api_user_get.go @@ -32,9 +32,8 @@ func ActionUserGet(c echo.Context) error { // loginned user check isLogin := false tUser := GetUserByReqToken(c) - if !tUser.IsEmpty() && tUser.Name == p.Name && tUser.Email == p.Email { + if tUser.Name == p.Name && tUser.Email == p.Email { isLogin = true - user = tUser } // unread notifies diff --git a/http/permission.go b/http/permission.go index 50e92c141..7ed1296b6 100644 --- a/http/permission.go +++ b/http/permission.go @@ -1,7 +1,6 @@ package http import ( - "context" "encoding/json" "fmt" "strconv" @@ -10,14 +9,12 @@ import ( "github.com/ArtalkJS/ArtalkGo/config" "github.com/ArtalkJS/ArtalkGo/lib" - "github.com/ArtalkJS/ArtalkGo/model" "github.com/golang-jwt/jwt" "github.com/labstack/echo/v4" "github.com/labstack/echo/v4/middleware" "github.com/sirupsen/logrus" ) -var permCtx = context.Background() var CommonJwtConfig middleware.JWTConfig // jwtCustomClaims are custom claims extending default ones. @@ -85,20 +82,20 @@ func RecordAction(c echo.Context) { func ResetActionRecord(c echo.Context) { ip := c.RealIP() - lib.CACHE.Delete(permCtx, "action-time:"+ip) - lib.CACHE.Delete(permCtx, "action-count:"+ip) + lib.CACHE.Delete(lib.Ctx, "action-time:"+ip) + lib.CACHE.Delete(lib.Ctx, "action-count:"+ip) } // 修改最后操作时间 func updateActionLastTime(c echo.Context) { curtTime := fmt.Sprintf("%v", time.Now().Unix()) - lib.CACHE.Set(permCtx, "action-time:"+c.RealIP(), []byte(curtTime), nil) + lib.CACHE.Set(lib.Ctx, "action-time:"+c.RealIP(), []byte(curtTime), nil) } // 获取最后操作时间 func getActionLastTime(c echo.Context) time.Time { var timestamp int64 - if val, err := lib.CACHE.Get(permCtx, "action-time:"+c.RealIP()); err == nil { + if val, err := lib.CACHE.Get(lib.Ctx, "action-time:"+c.RealIP()); err == nil { timestamp, _ = strconv.ParseInt(string(val.([]byte)), 10, 64) } tm := time.Unix(timestamp, 0) @@ -108,7 +105,7 @@ func getActionLastTime(c echo.Context) time.Time { // 获取操作次数 func getActionCount(c echo.Context) int { count := 0 - if val, err := lib.CACHE.Get(permCtx, "action-count:"+c.RealIP()); err == nil { + if val, err := lib.CACHE.Get(lib.Ctx, "action-count:"+c.RealIP()); err == nil { count, _ = strconv.Atoi(string(val.([]byte))) } @@ -117,7 +114,7 @@ func getActionCount(c echo.Context) int { // 修改操作次数 func setActionCount(c echo.Context, num int) { - lib.CACHE.Set(permCtx, "action-count:"+c.RealIP(), []byte(fmt.Sprintf("%d", num)), nil) + lib.CACHE.Set(lib.Ctx, "action-count:"+c.RealIP(), []byte(fmt.Sprintf("%d", num)), nil) } // 操作次数 +1 @@ -154,9 +151,6 @@ func GetJwtInstanceByReq(c echo.Context) *jwt.Token { func CheckIsAdminByJwt(jwt *jwt.Token) bool { user := GetUserByJwt(jwt) - if user.IsEmpty() { - return false - } return user.IsAdmin } @@ -170,29 +164,19 @@ func CheckIsAdminReq(c echo.Context) bool { return CheckIsAdminByJwt(jwt) } -func GetUserByJwt(jwt *jwt.Token) model.User { +func GetUserByJwt(jwt *jwt.Token) jwtCustomClaims { if jwt == nil { - return model.User{} + return jwtCustomClaims{} } claims := jwtCustomClaims{} tmp, _ := json.Marshal(jwt.Claims) _ = json.Unmarshal(tmp, &claims) - name := claims.Name - email := claims.Email - - if !claims.IsAdmin { - return model.User{} - } - - // check user from database - user := model.FindUser(name, email) - - return user + return claims } -func GetUserByReqToken(c echo.Context) model.User { +func GetUserByReqToken(c echo.Context) jwtCustomClaims { jwt := GetJwtInstanceByReq(c) user := GetUserByJwt(jwt) diff --git a/lib/cache.go b/lib/cache.go index 6f950a10f..d4759a799 100644 --- a/lib/cache.go +++ b/lib/cache.go @@ -1,6 +1,7 @@ package lib import ( + "context" "time" "github.com/allegro/bigcache/v3" @@ -10,6 +11,8 @@ import ( var CACHE *cache.Cache +var Ctx = context.Background() + func OpenCache() (err error) { bigcacheClient, err := bigcache.NewBigCache(bigcache.DefaultConfig(30 * time.Minute)) // TODO 过期时间是一样的,只有 Redis 才能设置单个 key 的 if err != nil { diff --git a/model/comment.go b/model/comment.go index 41f51afa5..3b224d0aa 100644 --- a/model/comment.go +++ b/model/comment.go @@ -209,7 +209,7 @@ func (c *Comment) SpamCheck(echoCtx echo.Context) { } } - user := FindUserByID(c.UserID) + user := c.FetchUser() // akismet akismetKey := strings.TrimSpace(config.Instance.Moderator.AkismetKey) diff --git a/model/query.go b/model/query.go index 4be1dffc3..8527077e4 100644 --- a/model/query.go +++ b/model/query.go @@ -1,9 +1,10 @@ package model import ( - "errors" + "encoding/json" "github.com/ArtalkJS/ArtalkGo/lib" + "github.com/eko/gocache/v2/store" "github.com/sirupsen/logrus" "gorm.io/gorm" "gorm.io/gorm/clause" @@ -24,6 +25,7 @@ func FindCommentScopes(id uint, filters ...func(db *gorm.DB) *gorm.DB) Comment { // 查找用户(返回:精确查找 AND) func FindUser(name string, email string) User { var user User + lib.DB.Where("name = ? AND email = ?", name, email).First(&user) return user } @@ -34,6 +36,35 @@ func FindUserByID(id uint) User { return user } +func FindCache(name string, destStruct interface{}) error { + entry, err := lib.CACHE.Get(lib.Ctx, name) + if err != nil { + return err + } + + str := entry.([]byte) + err = json.Unmarshal(str, destStruct) + if err != nil { + return err + } + + return nil +} + +func StoreCache(name string, srcStruct interface{}) error { + str, err := json.Marshal(srcStruct) + if err != nil { + return err + } + + err = lib.CACHE.Set(lib.Ctx, name, []byte(str), &store.Options{}) + if err != nil { + return err + } + + return nil +} + func IsAdminUser(name string, email string) bool { var user User lib.DB.Where("name = ? AND email = ? AND is_admin = 1", name, email).First(&user) @@ -214,21 +245,3 @@ func FindUnreadNotifies(userID uint) []CookedNotify { return cookedNotifies } - -func NotifyMarkAllAsRead(name string, email string) error { - user := FindUser(name, email) - if user.IsEmpty() { - return errors.New("user not found") - } - - // find all - var notifies []Notify - lib.DB.Where("user_id = ?", user.ID).Find(¬ifies) - - // mark as read - for _, n := range notifies { - n.SetRead() - } - - return nil -} From 47726d614f72f3287f6d7d37c1e2bfd91e3272bb Mon Sep 17 00:00:00 2001 From: qwqcode Date: Wed, 13 Oct 2021 21:50:34 +0800 Subject: [PATCH 050/349] Comments get with sites. --- http/api_admin_page_get.go | 1 + http/api_admin_site_get.go | 10 +++++++--- http/api_main_get.go | 18 ++++++++++++++++++ 3 files changed, 26 insertions(+), 3 deletions(-) diff --git a/http/api_admin_page_get.go b/http/api_admin_page_get.go index e8ecfc3d2..71a3702e5 100644 --- a/http/api_admin_page_get.go +++ b/http/api_admin_page_get.go @@ -41,5 +41,6 @@ func ActionAdminPageGet(c echo.Context) error { return RespData(c, Map{ "pages": cookedPages, + "sites": GetAllCookedSites(), }) } diff --git a/http/api_admin_site_get.go b/http/api_admin_site_get.go index f238b7f35..df5547de1 100644 --- a/http/api_admin_site_get.go +++ b/http/api_admin_site_get.go @@ -19,6 +19,12 @@ func ActionAdminSiteGet(c echo.Context) error { return resp } + return RespData(c, Map{ + "sites": GetAllCookedSites(), + }) +} + +func GetAllCookedSites() []model.CookedSite { var sites []model.Site lib.DB.Model(&model.Site{}).Find(&sites) @@ -27,7 +33,5 @@ func ActionAdminSiteGet(c echo.Context) error { cookedSites = append(cookedSites, s.ToCooked()) } - return RespData(c, Map{ - "sites": cookedSites, - }) + return cookedSites } diff --git a/http/api_main_get.go b/http/api_main_get.go index 0b2c01995..e9b1d9298 100644 --- a/http/api_main_get.go +++ b/http/api_main_get.go @@ -23,6 +23,10 @@ type ParamsGet struct { SiteName string `mapstructure:"site_name"` SiteID uint SiteAll bool + + WithSites bool `mapstructure:"with_sites"` + + IsAdminReq bool } type ResponseGet struct { @@ -32,6 +36,7 @@ type ResponseGet struct { Page model.CookedPage `json:"page"` Unread []model.CookedNotify `json:"unread"` UnreadCount int `json:"unread_count"` + Sites []model.CookedSite `json:"sites,omitempty"` } // 获取评论查询实例 @@ -69,6 +74,12 @@ func ActionGet(c echo.Context) error { p.User = &user // init params user field } + // check if admin + if CheckIsAdminReq(c) { + p.IsAdminReq = true + } + + // check if msg center isMsgCenter := IsMsgCenter(p) // comment parents @@ -134,6 +145,12 @@ func ActionGet(c echo.Context) error { NotifyMarkAllAsRead(p.User.ID) } + // with sites for admin + sites := []model.CookedSite{} + if p.IsAdminReq && p.WithSites { + sites = GetAllCookedSites() + } + // unread notifies var unreadNotifies = []model.CookedNotify{} if p.User != nil { @@ -147,6 +164,7 @@ func ActionGet(c echo.Context) error { Page: page.ToCooked(), Unread: unreadNotifies, UnreadCount: len(unreadNotifies), + Sites: sites, }) } From 7a83824e0dacf06ca4251ceb33ae5a113de18759 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Wed, 13 Oct 2021 23:10:28 +0800 Subject: [PATCH 051/349] Fix mail notification logic. --- http/api_main_add.go | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/http/api_main_add.go b/http/api_main_add.go index db39a50c6..1c5c40ed1 100644 --- a/http/api_main_add.go +++ b/http/api_main_add.go @@ -95,6 +95,9 @@ func ActionAdd(c echo.Context) error { IsPending: false, IsCollapsed: false, + + User: user, + Page: page, } // default comment type @@ -144,7 +147,12 @@ func AsyncSendEmail(comment *model.Comment, parentComment *model.Comment) { return } - // TODO 管理员自己评论问题,重复发送,管理员太吵了(别人回复别人都会发提醒) + // 自己回复自己,不提醒 + if comment.UserID == parentComment.UserID { + return + } + + // 邮件回复对方 if !parentComment.IsEmpty() && !comment.IsPending { notify := model.FindCreateNotify(parentComment.UserID, comment.ID) notify.Comment = *comment @@ -155,13 +163,11 @@ func AsyncSendEmail(comment *model.Comment, parentComment *model.Comment) { var admins []model.User lib.DB.Where("is_admin = 1").Find(&admins) - if len(admins) == 0 { - return - } - - for _, admin := range admins { - notify := model.FindCreateNotify(admin.ID, comment.ID) - notify.Comment = *comment - email.AsyncSendToAdmin(¬ify, &admin) // 发送邮件给管理员 + if parentComment.IsEmpty() && len(admins) > 0 { + for _, admin := range admins { + notify := model.FindCreateNotify(admin.ID, comment.ID) + notify.Comment = *comment + email.AsyncSendToAdmin(¬ify, &admin) // 发送邮件给管理员 + } } } From 48c60b84d31377f66a8884e306c1e22223bdc910 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Thu, 14 Oct 2021 13:24:39 +0800 Subject: [PATCH 052/349] User name and email not case sensitive. --- cmd/root.go | 7 +++++-- http/api_main_add.go | 33 ++++++++++++++++++++------------- http/api_user_get.go | 6 ++---- http/api_user_login.go | 4 +--- model/query.go | 5 +++-- 5 files changed, 31 insertions(+), 24 deletions(-) diff --git a/cmd/root.go b/cmd/root.go index 9210c3c63..dd057ca41 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -162,6 +162,8 @@ func syncConfWithDB() { lib.DB.Create(&user) } else { // update + user.Name = admin.Name + user.Email = admin.Email user.Link = admin.Link user.Password = admin.Password user.BadgeName = admin.BadgeName @@ -174,11 +176,12 @@ func syncConfWithDB() { // 清理配置文件中不存在的用户 var dbAdminUsers []model.User - lib.DB.Where("is_in_conf = 1").Find(&dbAdminUsers) + lib.DB.Model(&model.User{}).Where("is_in_conf = 1").Find(&dbAdminUsers) for _, dbU := range dbAdminUsers { isUserExist := func() bool { for _, confU := range config.Instance.AdminUsers { - if confU.Name == dbU.Name && confU.Email == dbU.Email { + // 忽略大小写比较 + if strings.EqualFold(confU.Name, dbU.Name) && strings.EqualFold(confU.Email, dbU.Email) { return true } } diff --git a/http/api_main_add.go b/http/api_main_add.go index 1c5c40ed1..6e82b6a61 100644 --- a/http/api_main_add.go +++ b/http/api_main_add.go @@ -60,13 +60,6 @@ func ActionAdd(c echo.Context) error { return resp } - // find user - user := model.FindCreateUser(p.Name, p.Email) - if user.ID == 0 || page.Key == "" { - logrus.Error("Cannot get user or page") - return RespError(c, "评论失败") - } - // check reply comment var parentComment model.Comment if p.Rid != 0 { @@ -82,6 +75,21 @@ func ActionAdd(c echo.Context) error { } } + // find user + user := model.FindCreateUser(p.Name, p.Email) + if user.ID == 0 || page.Key == "" { + logrus.Error("Cannot get user or page") + return RespError(c, "评论失败") + } + + // update user + user.Link = p.Link + user.LastIP = ip + user.LastUA = ua + user.Name = p.Name // for 若用户修改用户名大小写 + user.Email = p.Email + model.UpdateUser(&user) + comment := model.Comment{ Content: p.Content, PageKey: page.Key, @@ -112,12 +120,6 @@ func ActionAdd(c echo.Context) error { return RespError(c, "评论失败") } - // update user - user.Link = p.Link - user.LastIP = ip - user.LastUA = ua - model.UpdateUser(&user) - // update page if page.ToCooked().URL != "" && page.Title == "" { go func() { @@ -164,7 +166,12 @@ func AsyncSendEmail(comment *model.Comment, parentComment *model.Comment) { lib.DB.Where("is_admin = 1").Find(&admins) if parentComment.IsEmpty() && len(admins) > 0 { + // TODO: 增加用户的站点隔离,指定管理员分配网站 for _, admin := range admins { + if comment.UserID == admin.ID { // 管理员自己回复自己,不提醒 + continue + } + notify := model.FindCreateNotify(admin.ID, comment.ID) notify.Comment = *comment email.AsyncSendToAdmin(¬ify, &admin) // 发送邮件给管理员 diff --git a/http/api_user_get.go b/http/api_user_get.go index 2fe5d0726..000e2d78c 100644 --- a/http/api_user_get.go +++ b/http/api_user_get.go @@ -1,7 +1,6 @@ package http import ( - "github.com/ArtalkJS/ArtalkGo/lib" "github.com/ArtalkJS/ArtalkGo/model" "github.com/labstack/echo/v4" ) @@ -17,10 +16,9 @@ func ActionUserGet(c echo.Context) error { return resp } - var user model.User - lib.DB.Where("name = ? AND email = ?", p.Name, p.Email).First(&user) + user := model.FindUser(p.Name, p.Email) - if user.IsEmpty() || user.Name != p.Name || user.Email != p.Email { + if user.IsEmpty() { return RespData(c, Map{ "user": nil, "is_login": false, diff --git a/http/api_user_login.go b/http/api_user_login.go index 8f5d14c21..fdd7caa28 100644 --- a/http/api_user_login.go +++ b/http/api_user_login.go @@ -1,7 +1,6 @@ package http import ( - "github.com/ArtalkJS/ArtalkGo/lib" "github.com/ArtalkJS/ArtalkGo/model" "github.com/labstack/echo/v4" ) @@ -21,8 +20,7 @@ func ActionLogin(c echo.Context) error { // record action for limiting action RecordAction(c) - var user model.User - lib.DB.Where("name = ? AND email = ?", p.Name, p.Email).First(&user) // name = ? OR email = ? + user := model.FindUser(p.Name, p.Email) // name = ? OR email = ? if user.IsEmpty() || user.Password != p.Password { return RespError(c, "验证失败") } diff --git a/model/query.go b/model/query.go index 8527077e4..4f24d3775 100644 --- a/model/query.go +++ b/model/query.go @@ -26,7 +26,8 @@ func FindCommentScopes(id uint, filters ...func(db *gorm.DB) *gorm.DB) Comment { func FindUser(name string, email string) User { var user User - lib.DB.Where("name = ? AND email = ?", name, email).First(&user) + // 不区分大小写 + lib.DB.Where("LOWER(name) = LOWER(?) AND LOWER(email) = LOWER(?)", name, email).First(&user) return user } @@ -67,7 +68,7 @@ func StoreCache(name string, srcStruct interface{}) error { func IsAdminUser(name string, email string) bool { var user User - lib.DB.Where("name = ? AND email = ? AND is_admin = 1", name, email).First(&user) + lib.DB.Where("LOWER(name) = LOWER(?) AND LOWER(email) = LOWER(?) AND is_admin = 1", name, email).First(&user) return !user.IsEmpty() } From bb05d683edba057ed1a858a14c5de6be38fc09d6 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Thu, 14 Oct 2021 13:47:20 +0800 Subject: [PATCH 053/349] Fix msg center empty user bug. --- http/api_main_get.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/http/api_main_get.go b/http/api_main_get.go index e9b1d9298..2a69c28f1 100644 --- a/http/api_main_get.go +++ b/http/api_main_get.go @@ -170,13 +170,18 @@ func ActionGet(c echo.Context) error { // 请求是否为 通知中心数据 func IsMsgCenter(p ParamsGet) bool { - return p.Type != "" && p.User != nil && !p.User.IsEmpty() + return p.Type != "" && p.Name != "" && p.Email != "" } // TODO: 重构 MsgCenter func MsgCenter(c echo.Context, p ParamsGet, siteID uint) func(db *gorm.DB) *gorm.DB { return func(db *gorm.DB) *gorm.DB { user := p.User + + if user == nil || user.IsEmpty() { // user not found + return db.Where("id = 0") + } + isAdminReq := CheckIsAdminReq(c) // admin_only 检测 From 0e3b1efb5375124b47dc213fe927db4cb90ea2a4 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Fri, 15 Oct 2021 15:53:17 +0800 Subject: [PATCH 054/349] Vote for comment or page. --- cmd/root.go | 2 +- http/a_http.go | 2 + http/api_admin_comment_del.go | 17 +++-- http/api_admin_page_del.go | 25 +++++-- http/api_admin_site_del.go | 11 +-- http/api_admin_vote_sync.go | 55 +++++++++++++++ http/api_main_vote.go | 124 ++++++++++++++++++++++++++++++++++ model/comment.go | 7 ++ model/page.go | 7 ++ model/query.go | 6 ++ model/vote.go | 35 ++++++++++ 11 files changed, 270 insertions(+), 21 deletions(-) create mode 100644 http/api_admin_vote_sync.go create mode 100644 http/api_main_vote.go create mode 100644 model/vote.go diff --git a/cmd/root.go b/cmd/root.go index dd057ca41..aa315777f 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -131,7 +131,7 @@ func initDB() { } // Migrate the schema - lib.DB.AutoMigrate(&model.Site{}, &model.Page{}, &model.User{}, &model.Comment{}, &model.Notify{}) // 注意表的创建顺序,因为有关联字段 + lib.DB.AutoMigrate(&model.Site{}, &model.Page{}, &model.User{}, &model.Comment{}, &model.Notify{}, &model.Vote{}) // 注意表的创建顺序,因为有关联字段 } // 4. 同步配置文件与数据库 diff --git a/http/a_http.go b/http/a_http.go index a8cff943b..33c25b68a 100644 --- a/http/a_http.go +++ b/http/a_http.go @@ -82,6 +82,7 @@ func InitRoute(e *echo.Echo) { api.GET("/login", ActionLogin) api.POST("/login", ActionLogin) api.POST("/mark-read", ActionMarkRead) + api.POST("/vote", ActionVote) // api/captcha ca := api.Group("/captcha") @@ -106,6 +107,7 @@ func InitRoute(e *echo.Echo) { admin.POST("/setting-get", ActionAdminSettingGet) admin.POST("/setting-save", ActionAdminSettingSave) admin.POST("/importer", ActionAdminImporter) + admin.POST("/vote-sync", ActionAdminVoteSync) admin.POST("/send-mail", ActionAdminSendMail) } diff --git a/http/api_admin_comment_del.go b/http/api_admin_comment_del.go index ca02fdf23..422715d7d 100644 --- a/http/api_admin_comment_del.go +++ b/http/api_admin_comment_del.go @@ -64,13 +64,18 @@ func ActionAdminCommentDel(c echo.Context) error { func DelComment(comment *model.Comment) error { // 清除 notify - var notifications []model.Notify - lib.DB.Where("comment_id = ?", comment.ID).Find(¬ifications) + if err := lib.DB.Model(&model.Notify{}).Unscoped().Delete("comment_id = ?", comment.ID).Error; err != nil { + return err + } - for _, n := range notifications { - if err := lib.DB.Delete(n).Error; err != nil { - return err - } + // 清除 vote + if err := lib.DB.Model(&model.Vote{}).Unscoped().Delete( + "target_id = ? AND (type = ? OR type = ?)", + comment.ID, + string(model.VoteTypeCommentUp), + string(model.VoteTypeCommentDown), + ).Error; err != nil { + return err } // 删除 comment diff --git a/http/api_admin_page_del.go b/http/api_admin_page_del.go index ef743d8e9..1c182f226 100644 --- a/http/api_admin_page_del.go +++ b/http/api_admin_page_del.go @@ -32,18 +32,35 @@ func ActionAdminPageDel(c echo.Context) error { return RespError(c, "page not found") } - err := lib.DB.Unscoped().Delete(&page).Error + err := DelPage(&page) if err != nil { - return RespError(c, "page 删除失败") + return RespError(c, "Page 删除失败") + } + + return RespSuccess(c) +} + +func DelPage(page *model.Page) error { + err := lib.DB.Unscoped().Delete(page).Error + if err != nil { + return err } // 删除所有相关内容 var comments []model.Comment - lib.DB.Where("page_key = ? AND site_name = ?", p.Key, p.SiteName).Find(&comments) + lib.DB.Where("page_key = ? AND site_name = ?", page.Key, page.SiteName).Find(&comments) for _, c := range comments { DelComment(&c) } - return RespSuccess(c) + // 删除 vote + lib.DB.Model(&model.Vote{}).Unscoped().Delete( + "target_id = ? AND (type = ? OR type = ?)", + page.ID, + string(model.VoteTypePageUp), + string(model.VoteTypePageDown), + ) + + return nil } diff --git a/http/api_admin_site_del.go b/http/api_admin_site_del.go index 949feb017..c351491fd 100644 --- a/http/api_admin_site_del.go +++ b/http/api_admin_site_del.go @@ -33,21 +33,12 @@ func ActionAdminSiteDel(c echo.Context) error { // 删除所有相关内容 if p.DelContent { - var comments []model.Comment - lib.DB.Where("site_name = ?", site.Name).Find(&comments) - var pages []model.Page lib.DB.Where("site_name = ?", site.Name).Find(&pages) - for _, c := range comments { - DelComment(&c) - } - - tx := lib.DB.Begin() for _, p := range pages { - tx.Unscoped().Delete(&p) + DelPage(&p) } - tx.Commit() } return RespSuccess(c) diff --git a/http/api_admin_vote_sync.go b/http/api_admin_vote_sync.go new file mode 100644 index 000000000..ca508a638 --- /dev/null +++ b/http/api_admin_vote_sync.go @@ -0,0 +1,55 @@ +package http + +import ( + "github.com/ArtalkJS/ArtalkGo/lib" + "github.com/ArtalkJS/ArtalkGo/model" + "github.com/labstack/echo/v4" +) + +type ParamsAdminVoteSync struct { +} + +func ActionAdminVoteSync(c echo.Context) error { + if isOK, resp := AdminOnly(c); !isOK { + return resp + } + + var p ParamsAdminVoteSync + if isOK, resp := ParamsDecode(c, ParamsAdminVoteSync{}, &p); !isOK { + return resp + } + + VoteSync() + + return RespSuccess(c) +} + +func VoteSync() { + var comments []model.Comment + lib.DB.Find(&comments) + + for _, c := range comments { + voteUp := GetVoteNum(c.ID, string(model.VoteTypeCommentUp)) + voteDown := GetVoteNum(c.ID, string(model.VoteTypeCommentDown)) + c.VoteUp = int(voteUp) + c.VoteDown = int(voteDown) + lib.DB.Save(&c) + } + + var pages []model.Page + lib.DB.Find(&pages) + + for _, p := range pages { + voteUp := GetVoteNum(p.ID, string(model.VoteTypePageUp)) + voteDown := GetVoteNum(p.ID, string(model.VoteTypePageDown)) + p.VoteUp = voteUp + p.VoteDown = voteDown + lib.DB.Save(&p) + } +} + +func GetVoteNum(targetID uint, voteType string) int { + var num int64 + lib.DB.Model(&model.Vote{}).Where("target_id = ? AND type = ?", targetID, voteType).Count(&num) + return int(num) +} diff --git a/http/api_main_vote.go b/http/api_main_vote.go new file mode 100644 index 000000000..89ac3b48e --- /dev/null +++ b/http/api_main_vote.go @@ -0,0 +1,124 @@ +package http + +import ( + "strings" + + "github.com/ArtalkJS/ArtalkGo/lib" + "github.com/ArtalkJS/ArtalkGo/model" + "github.com/labstack/echo/v4" +) + +type ParamsVote struct { + TargetID uint `mapstructure:"target_id" param:"required"` + Type string `mapstructure:"type"` + + Name string `mapstructure:"name"` + Email string `mapstructure:"email"` + + SiteName string `mapstructure:"site_name"` + SiteID uint + SiteAll bool +} + +func ActionVote(c echo.Context) error { + var p ParamsVote + if isOK, resp := ParamsDecode(c, ParamsVote{}, &p); !isOK { + return resp + } + + // find site + if isOK, resp := CheckSite(c, &p.SiteName, &p.SiteID, &p.SiteAll); !isOK { + return resp + } + + ip := c.RealIP() + + // check type + isVoteComment := strings.HasPrefix(p.Type, "comment_") + isVotePage := strings.HasPrefix(p.Type, "page_") + isUp := strings.HasSuffix(p.Type, "_up") + isDown := strings.HasSuffix(p.Type, "_down") + + if !isUp && !isDown { + return RespError(c, "unknown type") + } + + var comment model.Comment + var page model.Page + + switch { + case isVoteComment: + comment = model.FindComment(p.TargetID, p.SiteName) + if comment.IsEmpty() { + return RespError(c, "comment not found") + } + case isVotePage: + page = model.FindPageByID(p.TargetID) + if page.IsEmpty() { + return RespError(c, "page not found") + } + default: + return RespError(c, "unknown type") + } + + // sync target model field value + sync := func(voteNum int) { + switch { + case isVoteComment: + if isUp { + comment.VoteUp = voteNum + } else { + comment.VoteDown = voteNum + } + lib.DB.Save(&comment) + case isVotePage: + if isUp { + page.VoteUp = voteNum + } else { + page.VoteDown = voteNum + } + lib.DB.Save(&page) + } + } + + // un-vote + var avaliableVote model.Vote + lib.DB.Where("target_id = ? AND type = ? AND ip = ?", p.TargetID, p.Type, ip).Find(&avaliableVote) + if !avaliableVote.IsEmpty() { + lib.DB.Unscoped().Delete(&avaliableVote) + + voteNum := GetVoteNum(p.TargetID, p.Type) + sync(voteNum) + + return RespData(c, Map{ + "vote_num": voteNum, + }) + } + + // find user + var user model.User + if p.Name != "" && p.Email != "" { + user = model.FindCreateUser(p.Name, p.Email) + } + + // create new vote record + vote := model.Vote{ + TargetID: p.TargetID, + Type: model.VoteType(p.Type), + UserID: user.ID, + UA: c.Request().UserAgent(), + IP: ip, + } + err := lib.DB.Create(&vote).Error + if err != nil { + return RespError(c, "vote create error") + } + + // sync + voteNum := GetVoteNum(p.TargetID, p.Type) + sync(voteNum) + + return RespData(c, Map{ + "vote_num": voteNum, + }) +} diff --git a/model/comment.go b/model/comment.go index 3b224d0aa..a946c7858 100644 --- a/model/comment.go +++ b/model/comment.go @@ -32,6 +32,9 @@ type Comment struct { User User `gorm:"foreignKey:UserID;references:ID"` Page Page `gorm:"foreignKey:PageKey;references:Key"` Site Site `gorm:"foreignKey:SiteName;references:Name"` + + VoteUp int + VoteDown int } func (c Comment) IsEmpty() bool { @@ -110,6 +113,8 @@ type CookedComment struct { BadgeName string `json:"badge_name"` BadgeColor string `json:"badge_color"` Visible bool `json:"visible"` + VoteUp int `json:"vote_up"` + VoteDown int `json:"vote_down"` PageKey string `json:"page_key"` SiteName string `json:"site_name"` } @@ -133,6 +138,8 @@ func (c *Comment) ToCooked() CookedComment { BadgeName: user.BadgeName, BadgeColor: user.BadgeColor, Visible: true, + VoteUp: c.VoteUp, + VoteDown: c.VoteDown, PageKey: c.PageKey, SiteName: c.SiteName, } diff --git a/model/page.go b/model/page.go index b394308eb..996f0ed5a 100644 --- a/model/page.go +++ b/model/page.go @@ -19,6 +19,9 @@ type Page struct { SiteName string `gorm:"index"` Site Site `gorm:"foreignKey:SiteName;references:Name"` + + VoteUp int + VoteDown int } func (p Page) IsEmpty() bool { @@ -32,6 +35,8 @@ type CookedPage struct { URL string `json:"url"` Title string `json:"title"` SiteName string `json:"site_name"` + VoteUp int `json:"vote_up"` + VoteDown int `json:"vote_down"` } func (p Page) ToCooked() CookedPage { @@ -47,6 +52,8 @@ func (p Page) ToCooked() CookedPage { URL: url, Title: p.Title, SiteName: p.SiteName, + VoteUp: p.VoteUp, + VoteDown: p.VoteDown, } } diff --git a/model/query.go b/model/query.go index 4f24d3775..938092a2f 100644 --- a/model/query.go +++ b/model/query.go @@ -16,6 +16,12 @@ func FindComment(id uint, siteName string) Comment { return comment } +func FindCommentBy(id uint) Comment { + var comment Comment + lib.DB.Preload(clause.Associations).Where("id = ?", id).First(&comment) + return comment +} + func FindCommentScopes(id uint, filters ...func(db *gorm.DB) *gorm.DB) Comment { var comment Comment lib.DB.Preload(clause.Associations).Where("id = ?", id).Scopes(filters...).First(&comment) diff --git a/model/vote.go b/model/vote.go new file mode 100644 index 000000000..d4d5c1acf --- /dev/null +++ b/model/vote.go @@ -0,0 +1,35 @@ +package model + +import ( + "strings" + + "gorm.io/gorm" +) + +type VoteType string + +const ( + VoteTypeCommentUp VoteType = "comment_up" + VoteTypeCommentDown VoteType = "comment_down" + VoteTypePageUp VoteType = "page_up" + VoteTypePageDown VoteType = "page_down" +) + +type Vote struct { + gorm.Model + + TargetID uint `gorm:"index"` // 投票对象 + Type VoteType `gorm:"index"` + + UserID uint `gorm:"index"` // 投票者 + UA string + IP string +} + +func (v *Vote) IsEmpty() bool { + return v.ID == 0 +} + +func (v *Vote) IsUp() bool { + return strings.HasSuffix(string(v.Type), "_up") +} From 727dcfcf28afd364f4186148b42258beb3129340 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Mon, 18 Oct 2021 21:05:04 +0800 Subject: [PATCH 055/349] Add site model field . --- README.md | 2 +- artalk-go.example.yml | 5 +++-- model/site.go | 2 ++ 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 58171b1f2..73b122f51 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ - [x] 多站点支持 - [x] 多数据库支持 - [x] 评论获取分页 -- [ ] 评论点赞投票 +- [x] 评论点赞投票 - [ ] 实时浏览量统计 - [x] 评论分页加载 - [x] 数据 diff --git a/artalk-go.example.yml b/artalk-go.example.yml index 475e9f8e5..b5abbe96c 100644 --- a/artalk-go.example.yml +++ b/artalk-go.example.yml @@ -22,7 +22,8 @@ log: # 允许跨域访问的域名 allow_origin: - - http://localhost:8080 # 或 '*' 跨域无限制 + - '*' # '*' 跨域无限制 +# - 'http://localhost:8080' # 默认站点名 site_default: '默认站点' @@ -55,7 +56,7 @@ captcha: # 邮件通知 email: enabled: true # 总开关 - send_type: 'smtp' # 发送方式 [ali_dm, smtp, sendmail] + send_type: 'smtp' # 发送方式 [smtp, ali_dm, sendmail] send_name: 'ArtalkGo' # 发信人昵称 send_addr: 'example@qq.com' # 发信人地址 mail_subject: '您在 Artalk 收到了新的回复' diff --git a/model/site.go b/model/site.go index c7733bc14..f5886d841 100644 --- a/model/site.go +++ b/model/site.go @@ -11,6 +11,8 @@ type Site struct { gorm.Model Name string `gorm:"uniqueIndex"` Urls string + + Users string // 分配给指定 UserIDs } func (s Site) IsEmpty() bool { From 7da6b44aaba0760144108ba55d62cb42e248aee4 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Tue, 19 Oct 2021 11:22:25 +0800 Subject: [PATCH 056/349] Fix wrong delete using. --- http/api_admin_comment_del.go | 6 +++--- http/api_admin_page_del.go | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/http/api_admin_comment_del.go b/http/api_admin_comment_del.go index 422715d7d..a1cbf7598 100644 --- a/http/api_admin_comment_del.go +++ b/http/api_admin_comment_del.go @@ -64,17 +64,17 @@ func ActionAdminCommentDel(c echo.Context) error { func DelComment(comment *model.Comment) error { // 清除 notify - if err := lib.DB.Model(&model.Notify{}).Unscoped().Delete("comment_id = ?", comment.ID).Error; err != nil { + if err := lib.DB.Unscoped().Where("comment_id = ?", comment.ID).Delete(&model.Notify{}).Error; err != nil { return err } // 清除 vote - if err := lib.DB.Model(&model.Vote{}).Unscoped().Delete( + if err := lib.DB.Unscoped().Where( "target_id = ? AND (type = ? OR type = ?)", comment.ID, string(model.VoteTypeCommentUp), string(model.VoteTypeCommentDown), - ).Error; err != nil { + ).Delete(&model.Vote{}).Error; err != nil { return err } diff --git a/http/api_admin_page_del.go b/http/api_admin_page_del.go index 1c182f226..ec0da7cca 100644 --- a/http/api_admin_page_del.go +++ b/http/api_admin_page_del.go @@ -55,12 +55,12 @@ func DelPage(page *model.Page) error { } // 删除 vote - lib.DB.Model(&model.Vote{}).Unscoped().Delete( + lib.DB.Unscoped().Where( "target_id = ? AND (type = ? OR type = ?)", page.ID, string(model.VoteTypePageUp), string(model.VoteTypePageDown), - ) + ).Delete(&model.Vote{}) return nil } From 75ff7631bd7665e479aec11b3d3db2ff257438ac Mon Sep 17 00:00:00 2001 From: QWQAQ Date: Wed, 20 Oct 2021 00:51:40 +0800 Subject: [PATCH 057/349] Update README.md --- README.md | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 73b122f51..0bba862b3 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,17 @@ # ArtalkGo -> ArtalkGo: the Artalk golang version. +> ArtalkGo: Golang backend of Artalk. + +## QuickStart + +1. 前往 Release 页下载已编译二进制文件 +2. 编辑 `artalk-go.yml` 配置程序 +3. 执行 `./artalk-go serve` 运行程序 +4. 反代设定的端口到 80 并套上 CDN (Nginx) +5. 持久化运行 artalk-go (tmux, sysctl) + +(目前部署较为繁琐,将推出 docker 镜像,更新待续...) ## Features From d89e7088b7e790f1efdb36fd6eb85aed820883a9 Mon Sep 17 00:00:00 2001 From: fossabot Date: Tue, 19 Oct 2021 19:45:20 -0700 Subject: [PATCH 058/349] Add license scan report and status Signed off by: fossabot --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index 0bba862b3..268ed1fe1 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,8 @@

# ArtalkGo +[![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2FArtalkJS%2FArtalkGo.svg?type=shield)](https://app.fossa.com/projects/git%2Bgithub.com%2FArtalkJS%2FArtalkGo?ref=badge_shield) + > ArtalkGo: Golang backend of Artalk. @@ -96,3 +98,7 @@ - 数据存储:支持 SQLite, MySQL, PostgreSQL, SQL Server... - 高效缓存:支持 Redis, Memory... - 邮件发送:支持 SMTP, 阿里云邮件, 系统调用 sendmail 等发送邮件 + + +## License +[![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2FArtalkJS%2FArtalkGo.svg?type=large)](https://app.fossa.com/projects/git%2Bgithub.com%2FArtalkJS%2FArtalkGo?ref=badge_large) \ No newline at end of file From 00fe2552231512ed16888552c1b2eadfdd07be0d Mon Sep 17 00:00:00 2001 From: Otstar Lin Date: Wed, 20 Oct 2021 03:07:19 +0000 Subject: [PATCH 059/349] Add Dockerfile and docker-componse.yml example --- Dockerfile | 19 +++++++++++++++++++ docker-compose.yml | 13 +++++++++++++ 2 files changed, 32 insertions(+) create mode 100644 Dockerfile create mode 100644 docker-compose.yml diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 000000000..f72b308e7 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,19 @@ +FROM golang:alpine as builder + +ENV ARTALK_VERSION v2.0 + +RUN apk --no-cache add make git gcc musl-dev +WORKDIR /app +COPY . . +RUN go mod tidy \ + && go install github.com/markbates/pkger/cmd/pkger \ + && pkger -include /frontend -include /email-tpl -o pkged \ + && go build -ldflags "-X github.com/ArtalkJS/ArtalkGo.Version=${ARTALK_VERSION}" -o bin/artalk-go github.com/ArtalkJS/ArtalkGo + +FROM alpine + +COPY --from=builder /app/bin/artalk-go /artalk-go +COPY --from=builder /app/email-tpl /email-tpl +COPY --from=builder /app/frontend /frontend + +CMD ["/artalk-go", "serve"] \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 000000000..b97d10242 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,13 @@ +version: "3.5" +services: + artalk: + container_name: artalk + build: + context: . + ports: + - "23366:23366" + volumes: + - ./email-tpl:/email-tpl + - ./frontend:/frontend + - ./artalk-go.example.yml:/artalk-go.yml + - ./local:/local \ No newline at end of file From 972355a45a3b17758b4bde1c4ceaf46841ccdeac Mon Sep 17 00:00:00 2001 From: qwqcode Date: Wed, 20 Oct 2021 12:58:06 +0800 Subject: [PATCH 060/349] Update dockerfile. --- Dockerfile | 12 +++++++----- README.md | 13 +++++++++---- docker-compose.yml | 2 +- 3 files changed, 17 insertions(+), 10 deletions(-) diff --git a/Dockerfile b/Dockerfile index f72b308e7..4191536a7 100644 --- a/Dockerfile +++ b/Dockerfile @@ -3,7 +3,7 @@ FROM golang:alpine as builder ENV ARTALK_VERSION v2.0 RUN apk --no-cache add make git gcc musl-dev -WORKDIR /app +WORKDIR /source COPY . . RUN go mod tidy \ && go install github.com/markbates/pkger/cmd/pkger \ @@ -12,8 +12,10 @@ RUN go mod tidy \ FROM alpine -COPY --from=builder /app/bin/artalk-go /artalk-go -COPY --from=builder /app/email-tpl /email-tpl -COPY --from=builder /app/frontend /frontend +COPY --from=builder /source/bin/artalk-go /artalk-go -CMD ["/artalk-go", "serve"] \ No newline at end of file +VOLUME ["/conf.yml", "/local"] + +ENTRYPOINT ["/artalk-go", "serve"] + +CMD ["--config", "/conf.yml"] \ No newline at end of file diff --git a/README.md b/README.md index 268ed1fe1..d40e3bcef 100644 --- a/README.md +++ b/README.md @@ -3,8 +3,6 @@

# ArtalkGo -[![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2FArtalkJS%2FArtalkGo.svg?type=shield)](https://app.fossa.com/projects/git%2Bgithub.com%2FArtalkJS%2FArtalkGo?ref=badge_shield) - > ArtalkGo: Golang backend of Artalk. @@ -16,7 +14,12 @@ 4. 反代设定的端口到 80 并套上 CDN (Nginx) 5. 持久化运行 artalk-go (tmux, sysctl) -(目前部署较为繁琐,将推出 docker 镜像,更新待续...) +## Docker + +```sh +docker pull artalk/artalk-go +docker run -d --name artalk-go -p 23366:23366 -v :/conf.yml -v :/local artalk/artalk-go +``` ## Features @@ -99,6 +102,8 @@ - 高效缓存:支持 Redis, Memory... - 邮件发送:支持 SMTP, 阿里云邮件, 系统调用 sendmail 等发送邮件 - ## License + +[![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2FArtalkJS%2FArtalkGo.svg?type=shield)](https://app.fossa.com/projects/git%2Bgithub.com%2FArtalkJS%2FArtalkGo?ref=badge_shield) + [![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2FArtalkJS%2FArtalkGo.svg?type=large)](https://app.fossa.com/projects/git%2Bgithub.com%2FArtalkJS%2FArtalkGo?ref=badge_large) \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index b97d10242..446072e0a 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -9,5 +9,5 @@ services: volumes: - ./email-tpl:/email-tpl - ./frontend:/frontend - - ./artalk-go.example.yml:/artalk-go.yml + - ./artalk-go.yml:/artalk-go.yml - ./local:/local \ No newline at end of file From 7cebb701ad473bd89557864fdf98584b9590b44e Mon Sep 17 00:00:00 2001 From: qwqcode Date: Wed, 20 Oct 2021 21:11:45 +0800 Subject: [PATCH 061/349] Add SSL config & docker build script. --- .gitignore | 1 + Dockerfile | 64 +++++++++++++++++++++----- README.md | 90 ++++++++++++++++++++++++++++--------- artalk-go.example.yml | 17 +++++-- cmd/serve.go | 3 ++ cmd/{_utils.go => utils.go} | 0 config/config.go | 10 ++++- docker-compose.yml | 2 +- frontend/index.html | 12 ++--- http/a_http.go | 9 +++- lib/version.go | 7 +++ makefile | 12 ++++- scripts/docker-build.sh | 20 +++++++++ 13 files changed, 199 insertions(+), 48 deletions(-) rename cmd/{_utils.go => utils.go} (100%) create mode 100644 lib/version.go create mode 100755 scripts/docker-build.sh diff --git a/.gitignore b/.gitignore index 88f478baf..d9d6440e5 100644 --- a/.gitignore +++ b/.gitignore @@ -19,5 +19,6 @@ config.yml local/ bin/ +data/ dist/ diff --git a/Dockerfile b/Dockerfile index 4191536a7..f9b440f43 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,21 +1,61 @@ -FROM golang:alpine as builder +### build ArtalkGo +FROM golang:1.17.2-alpine3.13 as builder -ENV ARTALK_VERSION v2.0 - -RUN apk --no-cache add make git gcc musl-dev WORKDIR /source -COPY . . -RUN go mod tidy \ + +# install tools +RUN set -ex \ + && apk upgrade \ + && apk add make git gcc musl-dev yarn + +# 1. build frontend +RUN git clone https://github.com/ArtalkJS/Artalk.git Artalk + +RUN set -ex \ + && cd ./Artalk \ + && yarn install --network-timeout 1000000 \ + && yarn build + +# 2. build backend +COPY . ./ArtalkGo + +# copy frontend dist folder +RUN cp -r ./Artalk/dist ./ArtalkGo/frontend + +RUN set -ex \ + && cd ./ArtalkGo \ + && export VERSION=$(git describe --tags --abbrev=0) \ + && export COMMIT_SHA=$(git rev-parse --short HEAD) \ + && go mod tidy \ && go install github.com/markbates/pkger/cmd/pkger \ && pkger -include /frontend -include /email-tpl -o pkged \ - && go build -ldflags "-X github.com/ArtalkJS/ArtalkGo.Version=${ARTALK_VERSION}" -o bin/artalk-go github.com/ArtalkJS/ArtalkGo + && go build -ldflags "-X github.com/ArtalkJS/ArtalkGo/lib.Version=${VERSION} \ + -X github.com/ArtalkJS/ArtalkGo/lib.LastCommit=${COMMIT_SHA}" \ + -o bin/artalk-go \ + github.com/ArtalkJS/ArtalkGo + +### build final image +FROM alpine:3.13 + +# we set the timezone `Asia/Shanghai` by default, you can be modified +# by `docker build --build-arg="TZ=Other_Timezone ..."` +ARG TZ="Asia/Shanghai" + +ENV TZ ${TZ} + +COPY --from=builder /source/ArtalkGo/bin/artalk-go /artalk-go -FROM alpine +RUN apk upgrade \ + && apk add bash tzdata \ + && ln -s /artalk-go /usr/bin/artalk-go \ + && ln -sf /usr/share/zoneinfo/${TZ} /etc/localtime \ + && echo ${TZ} > /etc/timezone -COPY --from=builder /source/bin/artalk-go /artalk-go +VOLUME ["/conf.yml", "/data"] -VOLUME ["/conf.yml", "/local"] +ENTRYPOINT ["/artalk-go"] -ENTRYPOINT ["/artalk-go", "serve"] +# expose ArtalkGo default port +EXPOSE 23366 -CMD ["--config", "/conf.yml"] \ No newline at end of file +CMD ["serve", "--config", "/conf.yml", "--host", "0.0.0.0", "--port", "23366"] diff --git a/README.md b/README.md index d40e3bcef..78fecc59f 100644 --- a/README.md +++ b/README.md @@ -6,28 +6,81 @@ > ArtalkGo: Golang backend of Artalk. -## QuickStart +- 高效 +- 跨平台 +- 轻松部署 +- 多站点支持 +- 多数据库类型支持 -1. 前往 Release 页下载已编译二进制文件 -2. 编辑 `artalk-go.yml` 配置程序 -3. 执行 `./artalk-go serve` 运行程序 -4. 反代设定的端口到 80 并套上 CDN (Nginx) -5. 持久化运行 artalk-go (tmux, sysctl) +# 部署方针 -## Docker +## 普通方式 + +1. 前往 [Release](https://github.com/ArtalkJS/ArtalkGo/releases) 下载已编译二进制文件 +2. 编辑配置文件 + ```sh + $ curl -L https://raw.githubusercontent.com/ArtalkJS/ArtalkGo/main/artalk-go.example.yml > artalk-go.yml + $ vim artalk-go.yml + ``` +3. 运行程序 `./artalk-go serve` +4. 反代设定的端口到 80 并套上 CDN (Nginx, Apache) +5. 持久化运作 artalk-go 程序 (tmux, sysctl) + +## Docker(推荐) ```sh -docker pull artalk/artalk-go -docker run -d --name artalk-go -p 23366:23366 -v :/conf.yml -v :/local artalk/artalk-go +# 为 ArtalkGo 创建一个目录 +$ mkdir ArtalkGo +$ cd ArtalkGo + +# 下载配置文件模版 +$ curl -L https://raw.githubusercontent.com/ArtalkJS/ArtalkGo/main/artalk-go.example.yml > conf.yml + +# 编译配置文件 +$ vim conf.yml + +# 拉取 docker 镜像 +$ docker pull artalk/artalk-go + +# 新建 docker 容器 +$ docker run -d \ + --name artalk-go \ + -p 23366:23366 \ + -v $(pwd)/conf.yml:/conf.yml \ + -v $(pwd)/data:/data \ + artalk/artalk-go ``` -## Features +- 默认监听 `localhost:23366` +- 配置文件 `./conf.yml` +- 数据目录 `./data/` -- 高效 -- 跨平台 -- 轻松部署 -- 多站点支持 -- 多数据库类型支持 +# 编译 + +## 编译二进制文件 + +```sh +$ make all +``` + +编译后二进制文件将输出到 `bin/` 目录下 + +## Docker 镜像制作 + +```sh +## 制作镜像 +$ make docker-docker + +# 发布镜像 +$ make docker-push +``` + +## Supports + +- 跨平台:支持 Linux, Win, Darwin +- 数据存储:支持 SQLite, MySQL, PostgreSQL, SQL Server... +- 高效缓存:支持 Redis, Memory... +- 邮件发送:支持 SMTP, 阿里云邮件, 系统调用 sendmail 等发送邮件 ## TODOs @@ -95,13 +148,6 @@ docker run -d --name artalk-go -p 23366:23366 -v :/conf.yml -v < - [ ] 国际化 (i18n) - [ ] 在线升级 -## Supports - -- 跨平台:支持 Linux, Win, Darwin -- 数据存储:支持 SQLite, MySQL, PostgreSQL, SQL Server... -- 高效缓存:支持 Redis, Memory... -- 邮件发送:支持 SMTP, 阿里云邮件, 系统调用 sendmail 等发送邮件 - ## License [![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2FArtalkJS%2FArtalkGo.svg?type=shield)](https://app.fossa.com/projects/git%2Bgithub.com%2FArtalkJS%2FArtalkGo?ref=badge_shield) diff --git a/artalk-go.example.yml b/artalk-go.example.yml index b5abbe96c..27b3c70a6 100644 --- a/artalk-go.example.yml +++ b/artalk-go.example.yml @@ -1,5 +1,8 @@ -# HTTP Server 监听地址 -http_addr: ':23366' +# HTTP Server +host: '0.0.0.0' + +# 端口 +port: 23366 # 加密密钥 app_key: '' @@ -13,18 +16,24 @@ timezone: 'Asia/Shanghai' # 数据文件 db: type: 'sqlite' # 支持 mysql, sqlite, pgsql, sqlserver - dsn: './local/artalk-go.db' + dsn: './data/artalk-go.db' # 日志 log: enabled: true # 总开关 - filename: './local/artalk-go.log' # 日志文件路径 + filename: './data/artalk-go.log' # 日志文件路径 # 允许跨域访问的域名 allow_origin: - '*' # '*' 跨域无限制 # - 'http://localhost:8080' +# SSL +ssl: + enabled: false + cert_path: '' + key_path: '' + # 默认站点名 site_default: '默认站点' diff --git a/cmd/serve.go b/cmd/serve.go index fdb3e4550..fbfc830a8 100644 --- a/cmd/serve.go +++ b/cmd/serve.go @@ -23,4 +23,7 @@ var serveCmd = &cobra.Command{ func init() { rootCmd.AddCommand(serveCmd) + + flagPV(serveCmd, "host", "", "0.0.0.0", "监听 IP") + flagPV(serveCmd, "port", "", 23366, "监听端口") } diff --git a/cmd/_utils.go b/cmd/utils.go similarity index 100% rename from cmd/_utils.go rename to cmd/utils.go diff --git a/config/config.go b/config/config.go index 7518eff7f..586e7632c 100644 --- a/config/config.go +++ b/config/config.go @@ -21,10 +21,12 @@ type Config struct { AppKey string `mapstructure:"app_key"` // 加密密钥 Debug bool `mapstructure:"debug"` // 调试模式 TimeZone string `mapstructure:"timezone"` // 时区 - HttpAddr string `mapstructure:"http_addr"` // HTTP Server 监听地址 + Host string `mapstructure:"host"` // HTTP Server 监听 IP + Port int `mapstructure:"port"` // HTTP Server 监听 Port DB DBConf `mapstructure:"db"` // 数据文件 Log LogConf `mapstructure:"log"` // 日志文件 AllowOrigin []string `mapstructure:"allow_origin"` // 允许跨域访问的域名 + SSL SSLConf `mapstructure:"site_default"` // SSL SiteDefault string `mapstructure:"site_default"` // 默认站点名(当请求无指定 site_name 时使用) AdminUsers []AdminUserConf `mapstructure:"admin_users"` LoginTimeout int `mapstructure:"login_timeout"` @@ -43,6 +45,12 @@ type LogConf struct { Filename string `mapstructure:"filename"` } +type SSLConf struct { + Enabled bool `mapstructure:"enabled"` + CertPath string `mapstructure:"cert_path"` + KeyPath string `mapstructure:"key_path"` +} + type AdminUserConf struct { Name string `mapstructure:"name"` Email string `mapstructure:"email"` diff --git a/docker-compose.yml b/docker-compose.yml index 446072e0a..63887c28b 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -10,4 +10,4 @@ services: - ./email-tpl:/email-tpl - ./frontend:/frontend - ./artalk-go.yml:/artalk-go.yml - - ./local:/local \ No newline at end of file + - ./data:/data \ No newline at end of file diff --git a/frontend/index.html b/frontend/index.html index d7f935c12..78e890b51 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -1,12 +1,12 @@ - + - - - Document + Welcome to ArtalkGo! - -

Hello World!

+ +

Welcome to ArtalkGo!

+

For online documentation and support please refer to artalk.js.org.

+

Thank you for using ArtalkGo.

\ No newline at end of file diff --git a/http/a_http.go b/http/a_http.go index 33c25b68a..99b1c5645 100644 --- a/http/a_http.go +++ b/http/a_http.go @@ -1,6 +1,7 @@ package http import ( + "fmt" "net/http" "strings" @@ -60,7 +61,13 @@ func Run() { // Route InitRoute(e) - e.Logger.Fatal(e.Start(config.Instance.HttpAddr)) + listenAddr := fmt.Sprintf("%s:%d", config.Instance.Host, config.Instance.Port) + + if config.Instance.SSL.Enabled { + e.Logger.Fatal(e.StartTLS(listenAddr, config.Instance.SSL.CertPath, config.Instance.SSL.KeyPath)) + } else { + e.Logger.Fatal(e.Start(listenAddr)) + } } func InitRoute(e *echo.Echo) { diff --git a/lib/version.go b/lib/version.go new file mode 100644 index 000000000..e221c1b9f --- /dev/null +++ b/lib/version.go @@ -0,0 +1,7 @@ +package lib + +// 版本信息 +var ( + Version string + LastCommit string +) diff --git a/makefile b/makefile index aa88e6fa4..4f02f9b49 100644 --- a/makefile +++ b/makefile @@ -15,10 +15,20 @@ update: pkger -include /frontend -include /email-tpl -o pkged build: update - go build -ldflags "-X github.com/ArtalkJS/ArtalkGo.Version=${VERSION}" -o bin/artalk-go github.com/ArtalkJS/ArtalkGo + go build \ + -ldflags "-X github.com/ArtalkJS/ArtalkGo/lib.Version=${VERSION} \ + -X github.com/ArtalkJS/ArtalkGo/lib.LastCommit=${COMMIT_SHA}" \ + -o bin/artalk-go \ + github.com/ArtalkJS/ArtalkGo run: update build ./bin/artalk-go test: update go test -cover github.com/ArtalkJS/ArtalkGo/... + +docker-build: + ./scripts/docker-build.sh + +docker-push: + ./scripts/docker-build.sh --push diff --git a/scripts/docker-build.sh b/scripts/docker-build.sh new file mode 100755 index 000000000..09844b980 --- /dev/null +++ b/scripts/docker-build.sh @@ -0,0 +1,20 @@ +#!/bin/bash + +set -e + +IMAGE_NAME="artalk-go" +REPO_NAME="artalk/artalk-go" + +VERSION=$(git describe --tags --abbrev=0) + +if [[ $* == *--push* ]] +then + # tag and push image + for tag in {${VERSION},latest}; do + docker image tag ${IMAGE_NAME} ${REPO_NAME}:${tag} + docker push ${REPO_NAME}:${tag} + done +else + # build + docker image build -t ${IMAGE_NAME} . +fi From 10c09a92fa2791a86adba733d67ca85827956d89 Mon Sep 17 00:00:00 2001 From: QWQAQ Date: Wed, 20 Oct 2021 22:49:18 +0800 Subject: [PATCH 062/349] Update README.md --- README.md | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 78fecc59f..772ae2459 100644 --- a/README.md +++ b/README.md @@ -45,15 +45,20 @@ $ docker pull artalk/artalk-go # 新建 docker 容器 $ docker run -d \ --name artalk-go \ - -p 23366:23366 \ + -p 0.0.0.0:8080:23366 \ -v $(pwd)/conf.yml:/conf.yml \ -v $(pwd)/data:/data \ artalk/artalk-go ``` -- 默认监听 `localhost:23366` -- 配置文件 `./conf.yml` -- 数据目录 `./data/` +- 前端访问地址 `http://localhost:8080/api` + + ```js + new Artalk({ server: "http://localhost:8080/api" }) + ``` + +- 配置文件路径 `./conf.yml` +- 数据文件目录 `./data/` # 编译 @@ -152,4 +157,4 @@ $ make docker-push [![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2FArtalkJS%2FArtalkGo.svg?type=shield)](https://app.fossa.com/projects/git%2Bgithub.com%2FArtalkJS%2FArtalkGo?ref=badge_shield) -[![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2FArtalkJS%2FArtalkGo.svg?type=large)](https://app.fossa.com/projects/git%2Bgithub.com%2FArtalkJS%2FArtalkGo?ref=badge_large) \ No newline at end of file +[![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2FArtalkJS%2FArtalkGo.svg?type=large)](https://app.fossa.com/projects/git%2Bgithub.com%2FArtalkJS%2FArtalkGo?ref=badge_large) From ec51c719c33bf9eb8a64ab6462f0962f36b795a5 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Wed, 20 Oct 2021 22:50:09 +0800 Subject: [PATCH 063/349] Format yml config file. --- artalk-go.example.yml | 59 +++++++++++++++++++++---------------------- 1 file changed, 29 insertions(+), 30 deletions(-) diff --git a/artalk-go.example.yml b/artalk-go.example.yml index 27b3c70a6..8306b677d 100644 --- a/artalk-go.example.yml +++ b/artalk-go.example.yml @@ -1,50 +1,49 @@ # HTTP Server -host: '0.0.0.0' +host: "0.0.0.0" # 端口 port: 23366 # 加密密钥 -app_key: '' +app_key: "" # 调试模式 debug: false # 时区 -timezone: 'Asia/Shanghai' +timezone: "Asia/Shanghai" # 数据文件 db: - type: 'sqlite' # 支持 mysql, sqlite, pgsql, sqlserver - dsn: './data/artalk-go.db' + type: "sqlite" # 支持 mysql, sqlite, pgsql, sqlserver + dsn: "./data/artalk-go.db" # 日志 log: enabled: true # 总开关 - filename: './data/artalk-go.log' # 日志文件路径 + filename: "./data/artalk-go.log" # 日志文件路径 # 允许跨域访问的域名 allow_origin: - - '*' # '*' 跨域无限制 + - "*" # '*' 跨域无限制 # - 'http://localhost:8080' # SSL ssl: enabled: false - cert_path: '' - key_path: '' + cert_path: "" + key_path: "" # 默认站点名 -site_default: '默认站点' +site_default: "默认站点" # 管理员账户 admin_users: - - - name: 'admin' - email: 'admin@example.com' - password: '' - badge_name: 'Verified' - badge_color: '#FF6C00' + - name: "admin" + email: "admin@example.com" + password: "" + badge_name: "Verified" + badge_color: "#FF6C00" # 登录超时 (单位:秒) login_timeout: 259200 @@ -52,7 +51,7 @@ login_timeout: 259200 # 评论审核 moderator: pending_default: false # 发表新评论默认为 “待审状态” - akismet_key: '' # 启用 akismet.com 反垃圾 + akismet_key: "" # 启用 akismet.com 反垃圾 # 验证码 captcha: @@ -65,19 +64,19 @@ captcha: # 邮件通知 email: enabled: true # 总开关 - send_type: 'smtp' # 发送方式 [smtp, ali_dm, sendmail] - send_name: 'ArtalkGo' # 发信人昵称 - send_addr: 'example@qq.com' # 发信人地址 - mail_subject: '您在 Artalk 收到了新的回复' - mail_subject_to_admin: '您的文章有新的回复' - mail_tpl: 'default' # 邮件模板文件 + send_type: "smtp" # 发送方式 [smtp, ali_dm, sendmail] + send_name: "ArtalkGo" # 发信人昵称 + send_addr: "example@qq.com" # 发信人地址 + mail_subject: "您在 Artalk 收到了新的回复" + mail_subject_to_admin: "您的文章有新的回复" + mail_tpl: "default" # 邮件模板文件 smtp: - host: 'smtp.qq.com' + host: "smtp.qq.com" port: 587 - username: 'example@qq.com' - password: '' + username: "example@qq.com" + password: "" ali_dm: # https://help.aliyun.com/document_detail/29444.html - access_key_id: '' # 阿里云颁发给用户的访问服务所用的密钥 ID - access_key_secret: '' # 用于加密的密钥 - account_name: 'example@example.com' # 管理控制台中配置的发信地址 - + access_key_id: "" # 阿里云颁发给用户的访问服务所用的密钥 ID + access_key_secret: "" # 用于加密的密钥 + account_name: "example@example.com" # 管理控制台中配置的发信地址 + From 312b38758106bc8485ef735311a01b1853002f56 Mon Sep 17 00:00:00 2001 From: Otstar Lin Date: Wed, 20 Oct 2021 16:11:39 +0000 Subject: [PATCH 064/349] Fix a typo. --- .vscode/launch.json | 3 ++- config/config.go | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index 61b381cac..a5e93ef13 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -9,7 +9,8 @@ "type": "go", "request": "launch", "mode": "auto", - "program": "${fileDirname}" + "program": "${fileDirname}", + "args": ["server"] } ] } \ No newline at end of file diff --git a/config/config.go b/config/config.go index 586e7632c..fe35066f5 100644 --- a/config/config.go +++ b/config/config.go @@ -110,7 +110,7 @@ const ( type EmailSenderType string const ( - TypeSMTP EmailSenderType = "smpt" + TypeSMTP EmailSenderType = "smtp" TypeAliDM EmailSenderType = "ali_dm" TypeSendmail EmailSenderType = "sendmail" ) From 53f37fa68a3a829c5bbe6dd5c773bc0acb649e75 Mon Sep 17 00:00:00 2001 From: Otstar Lin Date: Thu, 21 Oct 2021 03:08:42 +0000 Subject: [PATCH 065/349] Fix check email template. --- lib/email/render.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/email/render.go b/lib/email/render.go index bf006380d..fa673aa33 100644 --- a/lib/email/render.go +++ b/lib/email/render.go @@ -2,6 +2,7 @@ package email import ( "bytes" + "errors" "fmt" "html" "io/ioutil" @@ -17,10 +18,10 @@ import ( func RenderEmailTpl(notify *model.Notify, from model.CookedCommentForEmail, to model.CookedCommentForEmail) string { tplName := config.Instance.Email.MailTpl tpl := "" - if _, err := os.Stat(tplName); os.IsExist(err) { - tpl = GetExternalEmailTpl(tplName) - } else { + if _, err := os.Stat(tplName); errors.Is(err, os.ErrNotExist) { tpl = GetInternalEmailTpl(tplName) + } else { + tpl = GetExternalEmailTpl(tplName) } getValue := func(k string, v interface{}) string { From 63f7a734ea1fbd2b2a3ff90ce3a34249314258d8 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Thu, 21 Oct 2021 20:44:55 +0800 Subject: [PATCH 066/349] Improve Email Sender & Fix important security issues. --- .vscode/settings.json | 2 +- artalk-go.example.yml | 10 +- config/config.go | 124 ++++++++++-------------- email-tpl/default.html | 20 ++-- http/api_main_add.go | 35 ++++--- lib/anti_spam.go | 2 +- lib/email/email.go | 46 +++++---- lib/email/render.go | 208 +++++++++++++++++++++++++---------------- lib/email/sender.go | 2 +- model/comment.go | 79 ++++++++-------- model/notify.go | 3 +- model/query.go | 2 +- pkged/pkged.go | 2 +- 13 files changed, 288 insertions(+), 247 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 0c4f18531..c96d70f54 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -5,8 +5,8 @@ "gomail", "gorm", "lfshook", + "pgsql", "sendmail", - "smpt", "sqlite" ] } \ No newline at end of file diff --git a/artalk-go.example.yml b/artalk-go.example.yml index 8306b677d..37ad33824 100644 --- a/artalk-go.example.yml +++ b/artalk-go.example.yml @@ -42,7 +42,7 @@ admin_users: - name: "admin" email: "admin@example.com" password: "" - badge_name: "Verified" + badge_name: "管理员" badge_color: "#FF6C00" # 登录超时 (单位:秒) @@ -63,12 +63,12 @@ captcha: # 邮件通知 email: - enabled: true # 总开关 + enabled: false # 总开关 send_type: "smtp" # 发送方式 [smtp, ali_dm, sendmail] - send_name: "ArtalkGo" # 发信人昵称 + send_name: '{{reply_nick}}' # 发信人昵称 send_addr: "example@qq.com" # 发信人地址 - mail_subject: "您在 Artalk 收到了新的回复" - mail_subject_to_admin: "您的文章有新的回复" + mail_subject: "[{{site_name}}] 您收到了来自 @{{reply_nick}} 的回复" + mail_subject_to_admin: '[{{site_name}}] 您的文章 "{{page_title}}" 有新回复' mail_tpl: "default" # 邮件模板文件 smtp: host: "smtp.qq.com" diff --git a/config/config.go b/config/config.go index fe35066f5..9daaac9e5 100644 --- a/config/config.go +++ b/config/config.go @@ -1,11 +1,9 @@ package config import ( - "encoding/json" "fmt" "strings" - "github.com/jeremywohl/flatten" "github.com/sirupsen/logrus" "github.com/spf13/viper" ) @@ -13,89 +11,87 @@ import ( // Instance 配置实例 var Instance *Config -var Flat map[string]interface{} - // Config 配置 // @link https://godoc.org/github.com/mitchellh/mapstructure type Config struct { - AppKey string `mapstructure:"app_key"` // 加密密钥 - Debug bool `mapstructure:"debug"` // 调试模式 - TimeZone string `mapstructure:"timezone"` // 时区 - Host string `mapstructure:"host"` // HTTP Server 监听 IP - Port int `mapstructure:"port"` // HTTP Server 监听 Port - DB DBConf `mapstructure:"db"` // 数据文件 - Log LogConf `mapstructure:"log"` // 日志文件 - AllowOrigin []string `mapstructure:"allow_origin"` // 允许跨域访问的域名 - SSL SSLConf `mapstructure:"site_default"` // SSL - SiteDefault string `mapstructure:"site_default"` // 默认站点名(当请求无指定 site_name 时使用) - AdminUsers []AdminUserConf `mapstructure:"admin_users"` - LoginTimeout int `mapstructure:"login_timeout"` - Moderator ModeratorConf `mapstructure:"moderator"` - Captcha CaptchaConf `mapstructure:"captcha"` - Email EmailConf `mapstructure:"email"` + AppKey string `mapstructure:"app_key" json:"app_key"` // 加密密钥 + Debug bool `mapstructure:"debug" json:"debug"` // 调试模式 + TimeZone string `mapstructure:"timezone" json:"timezone"` // 时区 + Host string `mapstructure:"host" json:"host"` // HTTP Server 监听 IP + Port int `mapstructure:"port" json:"port"` // HTTP Server 监听 Port + DB DBConf `mapstructure:"db" json:"db"` // 数据文件 + Log LogConf `mapstructure:"log" json:"log"` // 日志文件 + AllowOrigin []string `mapstructure:"allow_origin" json:"allow_origin"` // 允许跨域访问的域名 + SSL SSLConf `mapstructure:"ssl" json:"ssl"` // SSL + SiteDefault string `mapstructure:"site_default" json:"site_default"` // 默认站点名(当请求无指定 site_name 时使用) + AdminUsers []AdminUserConf `mapstructure:"admin_users" json:"admin_users"` + LoginTimeout int `mapstructure:"login_timeout" json:"login_timeout"` + Moderator ModeratorConf `mapstructure:"moderator" json:"moderator"` + Captcha CaptchaConf `mapstructure:"captcha" json:"captcha"` + Email EmailConf `mapstructure:"email" json:"email"` } type DBConf struct { - Type DBType `mapstructure:"type"` - Dsn string `mapstructure:"dsn"` + Type DBType `mapstructure:"type" json:"type"` + Dsn string `mapstructure:"dsn" json:"dsn"` } type LogConf struct { - Enabled bool `mapstructure:"enabled"` - Filename string `mapstructure:"filename"` + Enabled bool `mapstructure:"enabled" json:"enabled"` + Filename string `mapstructure:"filename" json:"filename"` } type SSLConf struct { - Enabled bool `mapstructure:"enabled"` - CertPath string `mapstructure:"cert_path"` - KeyPath string `mapstructure:"key_path"` + Enabled bool `mapstructure:"enabled" json:"enabled"` + CertPath string `mapstructure:"cert_path" json:"cert_path"` + KeyPath string `mapstructure:"key_path" json:"key_path"` } type AdminUserConf struct { - Name string `mapstructure:"name"` - Email string `mapstructure:"email"` - Link string `mapstructure:"link"` - Password string `mapstructure:"password"` - BadgeName string `mapstructure:"badge_name"` - BadgeColor string `mapstructure:"badge_color"` + Name string `mapstructure:"name" json:"name"` + Email string `mapstructure:"email" json:"email"` + Link string `mapstructure:"link" json:"link"` + Password string `mapstructure:"password" json:"password"` + BadgeName string `mapstructure:"badge_name" json:"badge_name"` + BadgeColor string `mapstructure:"badge_color" json:"badge_color"` } type ModeratorConf struct { - PendingDefault bool `mapstructure:"pending_default"` - AkismetKey string `mapstructure:"akismet_key"` + PendingDefault bool `mapstructure:"pending_default" json:"pending_default"` + AkismetKey string `mapstructure:"akismet_key" json:"akismet_key"` } type CaptchaConf struct { - Enabled bool `mapstructure:"enabled"` - Always bool `mapstructure:"always"` - ActionTimeout int `mapstructure:"action_timeout"` - ActionLimit int `mapstructure:"action_limit"` + Enabled bool `mapstructure:"enabled" json:"enabled"` + Always bool `mapstructure:"always" json:"always"` + ActionTimeout int `mapstructure:"action_timeout" json:"action_timeout"` + ActionLimit int `mapstructure:"action_limit" json:"action_limit"` } type EmailConf struct { - Enabled bool `mapstructure:"enabled"` // 总开关 - SendType EmailSenderType `mapstructure:"send_type"` // 发送方式 - SendName string `mapstructure:"send_name"` // 发件人名 - SendAddr string `mapstructure:"send_addr"` // 发件人地址 - MailSubject string `mapstructure:"mail_subject"` // 邮件标题 - MailSubjectToAdmin string `mapstructure:"mail_subject_to_admin"` // 邮件标题 (发送给管理员用) - MailTpl string `mapstructure:"mail_tpl"` // 邮件模板 - SMTP SMTPConf `mapstructure:"smtp"` // SMTP 配置 - AliDM AliDMConf `mapstructure:"ali_dm"` // 阿里云邮件配置 + Enabled bool `mapstructure:"enabled" json:"enabled"` // 总开关 + SendType EmailSenderType `mapstructure:"send_type" json:"send_type"` // 发送方式 + SendName string `mapstructure:"send_name" json:"send_name"` // 发件人名 + SendAddr string `mapstructure:"send_addr" json:"send_addr"` // 发件人地址 + MailSubject string `mapstructure:"mail_subject" json:"mail_subject"` // 邮件标题 + MailSubjectToAdmin string `mapstructure:"mail_subject_to_admin" json:"mail_subject_to_admin"` // 邮件标题 (发送给管理员用) + MailTpl string `mapstructure:"mail_tpl" json:"mail_tpl"` // 邮件模板 + SMTP SMTPConf `mapstructure:"smtp" json:"smtp"` // SMTP 配置 + AliDM AliDMConf `mapstructure:"ali_dm" json:"ali_dm"` // 阿里云邮件配置 } type SMTPConf struct { - Host string `mapstructure:"host"` - Port int `mapstructure:"port"` - Username string `mapstructure:"username"` - Password string `mapstructure:"password"` - From string `mapstructure:"from"` + Host string `mapstructure:"host" json:"host"` + Port int `mapstructure:"port" json:"port"` + Username string `mapstructure:"username" json:"username"` + Password string `mapstructure:"password" json:"password"` + From string `mapstructure:"from" json:"from"` } type AliDMConf struct { - AccessKeyId string `mapstructure:"access_key_id"` - AccessKeySecret string `mapstructure:"access_key_secret"` - AccountName string `mapstructure:"account_name"` + AccessKeyId string `mapstructure:"access_key_id" json:"access_key_id"` + AccessKeySecret string `mapstructure:"access_key_secret" json:"access_key_secret"` + AccountName string `mapstructure:"account_name" json:"account_name"` } type DBType string @@ -141,22 +137,4 @@ func Init(cfgFile string) { if err != nil { logrus.Errorf("unable to decode into struct, %v", err) } - - Flat = StructToFlatDotMap(&Instance) -} - -func StructToMap(s interface{}) map[string]interface{} { - b, _ := json.Marshal(s) - var m map[string]interface{} - _ = json.Unmarshal(b, &m) - return m -} - -func StructToFlatDotMap(s interface{}) map[string]interface{} { - m := StructToMap(s) - mainFlat, err := flatten.Flatten(m, "", flatten.DotStyle) - if err != nil { - return map[string]interface{}{} - } - return mainFlat } diff --git a/email-tpl/default.html b/email-tpl/default.html index f7ac26324..bfc81e6cc 100644 --- a/email-tpl/default.html +++ b/email-tpl/default.html @@ -1,7 +1,13 @@ -

Hi, {{to.nick}}:

-

-您在 {{site_name}} 收到了回复: -

@{{from.nick}}:
{{from.content}}
-

-

传送门  >>

-

Powered By ArtalkGo

+ +
+

Hi, {{nick}}:

+

+ 您在 “{{page_title}}” 收到了回复: +

+
+
@{{reply_nick}}:
+
{{reply_content}}
+
+

传送门  »

+

-- {{site_name}}
Powered By ArtalkGo

+
\ No newline at end of file diff --git a/http/api_main_add.go b/http/api_main_add.go index 6e82b6a61..4bd745b17 100644 --- a/http/api_main_add.go +++ b/http/api_main_add.go @@ -120,22 +120,20 @@ func ActionAdd(c echo.Context) error { return RespError(c, "评论失败") } - // update page - if page.ToCooked().URL != "" && page.Title == "" { - go func() { - page.FetchURL() - }() - } - // 异步执行 go func() { + // update page + if page.ToCooked().URL != "" && page.Title == "" { + page.FetchURL() + } + // 垃圾检测 if !CheckIsAdminReq(c) { comment.SpamCheck(c) } // 邮件通知发送 - AsyncSendEmail(&comment, &parentComment) + EmailSend(&comment, &parentComment) }() return RespData(c, ResponseAdd{ @@ -143,8 +141,8 @@ func ActionAdd(c echo.Context) error { }) } -// 异步邮件发送 -func AsyncSendEmail(comment *model.Comment, parentComment *model.Comment) { +// 邮件发送 (from comment to parentComment) +func EmailSend(comment *model.Comment, parentComment *model.Comment) { if !config.Instance.Email.Enabled { return } @@ -165,10 +163,25 @@ func AsyncSendEmail(comment *model.Comment, parentComment *model.Comment) { var admins []model.User lib.DB.Where("is_admin = 1").Find(&admins) + isAdmin := func(userID uint) bool { + for _, admin := range admins { + if admin.ID == userID { + return true + } + } + return false + } + if parentComment.IsEmpty() && len(admins) > 0 { // TODO: 增加用户的站点隔离,指定管理员分配网站 for _, admin := range admins { - if comment.UserID == admin.ID { // 管理员自己回复自己,不提醒 + // 管理员自己回复自己,不提醒 + if comment.UserID == admin.ID { + continue + } + + // 管理员评论不回复给其他管理员 + if isAdmin(comment.UserID) { continue } diff --git a/lib/anti_spam.go b/lib/anti_spam.go index 8880e7dec..21a36d681 100644 --- a/lib/anti_spam.go +++ b/lib/anti_spam.go @@ -32,7 +32,7 @@ type AkismetParams struct { } // @link https://akismet.com/development/api/#comment-check -func AntiSpamCheck_Akismet(params *AkismetParams, key string) (bool, error) { +func SpamCheck_Akismet(params *AkismetParams, key string) (bool, error) { form := url.Values{} v := reflect.ValueOf(*params) diff --git a/lib/email/email.go b/lib/email/email.go index d66e4e07a..8fff45d52 100644 --- a/lib/email/email.go +++ b/lib/email/email.go @@ -32,19 +32,18 @@ func AsyncSend(notify *model.Notify) { from := comment.ToCookedForEmail() to := parentComment.ToCookedForEmail() - go func() { - subject := RenderConfig(config.Instance.Email.MailSubject, notify, from, to) - body := RenderEmailTpl(notify, from, to) + fromName := RenderCommon(config.Instance.Email.SendName, notify, from, to) + subject := RenderCommon(config.Instance.Email.MailSubject, notify, from, to) + body := RenderEmailTpl(notify, from, to) - AddToQueue(Email{ - FromAddr: config.Instance.Email.SendAddr, - FromName: config.Instance.Email.SendName, - ToAddr: to.Email, - Subject: subject, - Body: body, - LinkedNotify: notify, - }) - }() + AddToQueue(Email{ + FromAddr: config.Instance.Email.SendAddr, + FromName: fromName, + ToAddr: to.Email, + Subject: subject, + Body: body, + LinkedNotify: notify, + }) } func AsyncSendToAdmin(notify *model.Notify, admin *model.User) { @@ -61,17 +60,16 @@ func AsyncSendToAdmin(notify *model.Notify, admin *model.User) { Email: admin.Email, } - go func() { - subject := RenderConfig(config.Instance.Email.MailSubjectToAdmin, notify, from, to) - body := RenderEmailTpl(notify, from, to) + fromName := RenderCommon(config.Instance.Email.SendName, notify, from, to) + subject := RenderCommon(config.Instance.Email.MailSubjectToAdmin, notify, from, to) + body := RenderEmailTpl(notify, from, to) - AddToQueue(Email{ - FromAddr: config.Instance.Email.SendAddr, - FromName: config.Instance.Email.SendName, - ToAddr: admin.Email, - Subject: subject, - Body: body, - LinkedNotify: notify, - }) - }() + AddToQueue(Email{ + FromAddr: config.Instance.Email.SendAddr, + FromName: fromName, + ToAddr: admin.Email, + Subject: subject, + Body: body, + LinkedNotify: notify, + }) } diff --git a/lib/email/render.go b/lib/email/render.go index fa673aa33..d9fa75ce5 100644 --- a/lib/email/render.go +++ b/lib/email/render.go @@ -1,81 +1,127 @@ -package email - -import ( - "bytes" - "errors" - "fmt" - "html" - "io/ioutil" - "os" - "strings" - - "github.com/ArtalkJS/ArtalkGo/config" - "github.com/ArtalkJS/ArtalkGo/lib" - "github.com/ArtalkJS/ArtalkGo/model" - "github.com/ArtalkJS/ArtalkGo/pkged" -) - -func RenderEmailTpl(notify *model.Notify, from model.CookedCommentForEmail, to model.CookedCommentForEmail) string { - tplName := config.Instance.Email.MailTpl - tpl := "" - if _, err := os.Stat(tplName); errors.Is(err, os.ErrNotExist) { - tpl = GetInternalEmailTpl(tplName) - } else { - tpl = GetExternalEmailTpl(tplName) - } - - getValue := func(k string, v interface{}) string { - val := fmt.Sprintf("%v", v) - if k != "content" { - val = html.EscapeString(val) - } - return val - } - - flatFrom := lib.StructToFlatDotMap(&from) - flatTo := lib.StructToFlatDotMap(&to) - for k, v := range flatFrom { - tpl = strings.ReplaceAll(tpl, fmt.Sprintf("{{from.%s}}", k), getValue(k, v)) - } - for k, v := range flatTo { - tpl = strings.ReplaceAll(tpl, fmt.Sprintf("{{to.%s}}", k), getValue(k, v)) - } - - tpl = RenderConfig(tpl, notify, from, to) - tpl = strings.ReplaceAll(tpl, "{{reply_link}}", notify.GetReadLink()) - - return tpl -} - -func RenderConfig(str string, notify *model.Notify, from model.CookedCommentForEmail, to model.CookedCommentForEmail) string { - for k, v := range config.Flat { - str = strings.ReplaceAll(str, fmt.Sprintf("{{config.%s}}", k), fmt.Sprintf("%v", v)) - } - str = strings.ReplaceAll(str, "{{site_name}}", from.SiteName) - return str -} - -func GetExternalEmailTpl(filename string) string { - buf, err := ioutil.ReadFile(filename) - if err != nil { - return "" - } - - return string(buf) -} - -func GetInternalEmailTpl(tplName string) string { - filename := fmt.Sprintf("/email-tpl/%s.html", tplName) - f, err := pkged.Open(filename) - if err != nil { - return "" - } - - buf := new(bytes.Buffer) - if _, err := buf.ReadFrom(f); err != nil { - return "" - } - contents := buf.String() - - return contents -} +package email + +import ( + "bytes" + "errors" + "fmt" + "html" + "io/ioutil" + "os" + "regexp" + "strings" + + "github.com/ArtalkJS/ArtalkGo/config" + "github.com/ArtalkJS/ArtalkGo/lib" + "github.com/ArtalkJS/ArtalkGo/model" + "github.com/ArtalkJS/ArtalkGo/pkged" +) + +func RenderEmailTpl(notify *model.Notify, from model.CookedCommentForEmail, to model.CookedCommentForEmail) string { + tplName := config.Instance.Email.MailTpl + tpl := "" + if _, err := os.Stat(tplName); errors.Is(err, os.ErrNotExist) { + tpl = GetInternalEmailTpl(tplName) + } else { + tpl = GetExternalEmailTpl(tplName) + } + + tpl = RenderCommon(tpl, notify, from, to) + + return tpl +} + +type CommonFields struct { + From model.CookedCommentForEmail `json:"from"` + To model.CookedCommentForEmail `json:"to"` + Comment model.CookedCommentForEmail `json:"comment"` + ParentComment model.CookedCommentForEmail `json:"parent_comment"` + + Nick string `json:"nick"` + Content string `json:"content"` + ReplyNick string `json:"reply_nick"` + ReplyContent string `json:"reply_content"` + + PageTitle string `json:"page_title"` + PageURL string `json:"page_url"` + SiteName string `json:"site_name"` + SiteURL string `json:"site_url"` + + LinkToReply string `json:"link_to_reply"` +} + +func RenderCommon(str string, notify *model.Notify, from model.CookedCommentForEmail, to model.CookedCommentForEmail) string { + cf := CommonFields{ + From: from, + To: to, + Comment: from, + ParentComment: to, + + Nick: to.Nick, + Content: to.Content, + ReplyNick: from.Nick, + ReplyContent: from.Content, + PageTitle: from.Page.Title, + PageURL: from.Page.URL, + SiteName: from.SiteName, + SiteURL: from.Site.FirstUrl, + + LinkToReply: notify.GetReadLink(), + } + + flat := lib.StructToFlatDotMap(&cf) + + return ReplaceAllMustache(str, flat) +} + +// 获取内建模版 +func GetInternalEmailTpl(tplName string) string { + filename := fmt.Sprintf("/email-tpl/%s.html", tplName) + f, err := pkged.Open(filename) + if err != nil { + return "" + } + + buf := new(bytes.Buffer) + if _, err := buf.ReadFrom(f); err != nil { + return "" + } + contents := buf.String() + + return contents +} + +// 获取外置模版 +func GetExternalEmailTpl(filename string) string { + buf, err := ioutil.ReadFile(filename) + if err != nil { + return "" + } + + return string(buf) +} + +// 替换 {{ key }} 为 val +func ReplaceAllMustache(data string, dict map[string]interface{}) string { + r := regexp.MustCompile(`{{\s*(\S+)\s*}}`) + return r.ReplaceAllStringFunc(data, func(m string) string { + key := r.FindStringSubmatch(m)[1] + if val, isExist := dict[key]; isExist { + return GetPurifiedValue(key, val) + } + + return m + }) +} + +// 净化文本,防止 XSS +func GetPurifiedValue(k string, v interface{}) string { + val := fmt.Sprintf("%v", v) + + // 去除标签数据,防止数据泄漏 + if k == "reply_content" || strings.HasSuffix(k, ".content") { // 排除 model.CookedComment.content + return val + } + + val = html.EscapeString(val) + return val +} diff --git a/lib/email/sender.go b/lib/email/sender.go index c4b6508ac..3fd8c6b68 100644 --- a/lib/email/sender.go +++ b/lib/email/sender.go @@ -40,7 +40,7 @@ func SendByAliDM(email Email) bool { config.Instance.Email.AliDM.AccessKeyId, config.Instance.Email.AliDM.AccessKeySecret, config.Instance.Email.AliDM.AccountName, - config.Instance.Email.SendName, + email.FromName, ali_dm.RegionCNHangZhou, ) req := &ali_dm.SingleRequest{ diff --git a/model/comment.go b/model/comment.go index a946c7858..d4a30cea8 100644 --- a/model/comment.go +++ b/model/comment.go @@ -146,51 +146,52 @@ func (c *Comment) ToCooked() CookedComment { } type CookedCommentForEmail struct { - ID uint `json:"id"` - ContentRaw string `json:"content_raw"` - Content string `json:"content"` - Nick string `json:"nick"` - Email string `json:"email"` - EmailEncrypted string `json:"email_encrypted"` - Link string `json:"link"` - UA string `json:"ua"` - Datetime string `json:"datetime"` - Date string `json:"date"` - Time string `json:"time"` - IsCollapsed bool `json:"is_collapsed"` - IsPending bool `json:"is_pending"` - IsAllowReply bool `json:"is_allow_reply"` - Rid uint `json:"rid"` - BadgeName string `json:"badge_name"` - BadgeColor string `json:"badge_color"` - PageKey string `json:"page_key"` - SiteName string `json:"site_name"` + CookedComment + Content string `json:"content"` + ContentRaw string `json:"content_raw"` + Nick string `json:"nick"` + Email string `json:"email"` + Datetime string `json:"datetime"` + Date string `json:"date"` + Time string `json:"time"` + PageKey string `json:"page_key"` + PageTitle string `json:"page_title"` + Page CookedPage `json:"page"` + SiteName string `json:"site_name"` + Site CookedSite `json:"site"` } func (c *Comment) ToCookedForEmail() CookedCommentForEmail { user := c.FetchUser() + page := c.FetchPage() + site := c.FetchSite() content, _ := lib.Marked(c.Content) return CookedCommentForEmail{ - ID: c.ID, - ContentRaw: c.Content, - Content: content, - Nick: user.Name, - Email: user.Email, - EmailEncrypted: lib.GetMD5Hash(user.Email), - Link: user.Link, - UA: c.UA, - Datetime: c.CreatedAt.Local().Format("2006-01-02 15:04:05"), - Date: c.CreatedAt.Local().Format("2006-01-02"), - Time: c.CreatedAt.Local().Format("15:04:05"), - IsCollapsed: c.IsCollapsed, - IsPending: c.IsPending, - IsAllowReply: c.IsAllowReply(), - Rid: c.Rid, - BadgeName: user.BadgeName, - BadgeColor: user.BadgeColor, - PageKey: c.PageKey, - SiteName: c.SiteName, + Content: content, + ContentRaw: c.Content, + Nick: user.Name, + Email: user.Email, + Datetime: c.CreatedAt.Local().Format("2006-01-02 15:04:05"), + Date: c.CreatedAt.Local().Format("2006-01-02"), + Time: c.CreatedAt.Local().Format("15:04:05"), + PageKey: c.PageKey, + PageTitle: page.Title, + Page: page.ToCooked(), + SiteName: c.SiteName, + Site: site.ToCooked(), + CookedComment: CookedComment{ + ID: c.ID, + EmailEncrypted: lib.GetMD5Hash(user.Email), + Link: user.Link, + UA: c.UA, + IsCollapsed: c.IsCollapsed, + IsPending: c.IsPending, + IsAllowReply: c.IsAllowReply(), + Rid: c.Rid, + BadgeName: user.BadgeName, + BadgeColor: user.BadgeColor, + }, } } @@ -221,7 +222,7 @@ func (c *Comment) SpamCheck(echoCtx echo.Context) { // akismet akismetKey := strings.TrimSpace(config.Instance.Moderator.AkismetKey) if akismetKey != "" { - isOK, err := lib.AntiSpamCheck_Akismet(&lib.AkismetParams{ + isOK, err := lib.SpamCheck_Akismet(&lib.AkismetParams{ Blog: siteURL, UserIP: echoCtx.RealIP(), UserAgent: echoCtx.Request().UserAgent(), diff --git a/model/notify.go b/model/notify.go index 7bcb047e7..c7251d4e2 100644 --- a/model/notify.go +++ b/model/notify.go @@ -33,8 +33,7 @@ func (n *Notify) FetchComment() Comment { return n.Comment } - var comment Comment - lib.DB.First(&comment, n.CommentID) + comment := FindCommentByID(n.CommentID) n.Comment = comment return comment diff --git a/model/query.go b/model/query.go index 938092a2f..5b04ce402 100644 --- a/model/query.go +++ b/model/query.go @@ -16,7 +16,7 @@ func FindComment(id uint, siteName string) Comment { return comment } -func FindCommentBy(id uint) Comment { +func FindCommentByID(id uint) Comment { var comment Comment lib.DB.Preload(clause.Associations).Where("id = ?", id).First(&comment) return comment diff --git a/pkged/pkged.go b/pkged/pkged.go index cf8a47831..7db58c71d 100644 --- a/pkged/pkged.go +++ b/pkged/pkged.go @@ -9,4 +9,4 @@ import ( "github.com/markbates/pkger/pkging/mem" ) -var _ = pkger.Apply(mem.UnmarshalEmbed([]byte(`1f8b08000000000000ffec7d5b6fdb38d7ee5f79a1db3aa165f90cec8b26691c679a4393364efc625050122dd1a24895a47cc820ff7d83946ccb960f0af6ec0fdf05316824aef590e2996bd1ebc1fc63613a61c2eaff63055886a97beeb1187ce51292e8f6397f1930a5bfc2dcea5be085913446028c188f9e13e8a11c74f6f57178366056cd1ac609e3f211cad0ea1f2fb566ddc318597d2b86985a35eb8a7956dfb26ad64fc80324d5e77e09c4054089c7310501032ea6c5fc4f8cc96ab5ba83d20badfe7fad73ebef9af52c2141565ff214e589270405a356df122af51f1f2588fa887acbfe7f8eb501788c4e7060d5ac01bbc60409f509d59cf380a90f659da1a5c78b897d05bf4289c6bae904ab5abb4b898455b33c16271c090126044a541404ef3829a6c9fbbc987c27d8d5692a21a688038285cc0568a1dff832916cfd0260f6c12ce1e124447c93f68b4a5fc04d0279db49bfd16ad9bd9200602a11a79000e4cf21f7c52e8c109c48ec6d24610c0ba975760ea99f4a4cf6a844ea4a82368ad86f6d122a5f21e5350b8962034408edad54a3d5de4ab7ec4621bdf349490afdb468d57bdba94d5d63e8b11d284822bcb06a960f2574a14040fc213b49e0733cd3e3826217a9f620ea311fd3a0f00aa0a07631ad72b79b5b124c215f16259e981593215a149353b5440ae904c5c5e4225615459c33aeda8416c90caa4a4e0854159bc46abe9d5c06a720ab057714154a999cc2644be31404a018ea69761418331f9d0425518076daf798221e61c92e300301fb93223d1c05c02b86ec0e83040550a4e22c60671ec1884a00fd586f9a55b0d8279fc6abd9f2097869e48ea2f9676bc35142b00725669fcac57db7225c49080b3e8116a9f81c1ab0a462069e781591020951ea1348080ab83a2c030f7a210233e72400fc4951ba33e090fa4b1792909118785078d0c77007c1a1ef330a7c285102f9ee8c7111e3b40312c42301fea4904a4c76211cfa132cdf41c0621467b559bd6c233d44234824062ef4223699805973172012c811582c422842306b6cab7d44b14034623108d8592cc41fb23b3bf642369bb5977c0aee230fc7907c2a8fde01f293b9982be04b116195852bbbe47dc676671f8ad40e920f6703ece9c05d04f39177141123c9b177fc3b4232bef39d89a04ce2c972fdb2add66df0b100d9df59f7847add395571400dbf844175bcf020ad8c4e18ab5e9584336d5c5543e7c64935706efd6c83c51f72961907205e6686c316c04d2713481808d1eea8058c401a9c4de7124ce772af4e591e1e9e953fabb460c21192cb646fb16b25e050486db91cc128b3fc6049ba47dd74b2bf6b7720aa14510503202d4dd3bd383fe57b4ea10360896324248c77f60d353fb1c77802428f1c51e97f50c85310bdf3f29328aea7ce29985a0bb4024c728fd1d929986411a2c740caa4acd0000dab50358ddbf3d129f4220f78614a238ea08f78e978c81049e031ba376fa6291c067231d73ee561ac90b1dcb30faf3098ed9727508849e9a05c6bd51c730e565f203ec31e3a9cbfbcb0569a45e9442d6a0afe15a458e2f723a50021fd92753d451cc5cb390b89f662656988307d0f5380e98420afbcc4723565f36d3981ae90d08b00f242566ac1ae16c4d8f7099ac3dded6f0d0c581c330a569ef71188c708e3c721258b7217a0767c166f636218608f5188b9da5012c425dead4a0c79e4428984f629f851e59ebd7e1751704793e35f527f3337f32406ac7cd3d3c81895ba602f4e489f95ea272555279f1e0de8ee4efbb51e0b28e5f28052fc215822a7ac950967a99fefefbf57fbfb6fb490882ac35b80c42d1fc47190ca7700a9c03b722cbd101112ea8e963cf564ba3b368c721ca989c353a167edb67ae502443320438e2752fba801cb53bb604290c488ab364a16ef5433e12c463244a900993bf17b738ee58a4f673860ad55c9a95e61ba7ba697736a5f1b044770d9da428ba474e55046ade7be8ba59b7a1192e78c07603e070153b5a1283855c41ee77fbb59dee4704766ea4d353e012d4fbc3ff33fcaac57c30d095ea6f46ccfed05c79309615e04c844848c45db5a81799a0844f329b8a34c26b603e004717650515ecd99d22b5932b99cb91cee534ce79048c4e708ca10f178d744cf40497eb95452cc70b2bb310a8960ecc2047830915eb8fbd1d465024be5dd48b46bd9cc20594202f5b1a06c68c4cb6ec00a3381424a1427f9556d01b138f3385ce63d7b967034c10be49f4d18577bcd6e7597a9bef326beda0d8fa8ca26e2b67abd5955029d2a6d9fadb68dd01e2aaf8601a1dcdd95b681655f785bbf5a03ec9c25884a4490f25a97e7980126d13115805272eca6d9201d02a9e5248e018afbdd290c706110c0e0e807d7d88030b762b192430f01cab20ba643f0cc9d3f8da8f0e51c48d3d8cdc6f90490a3000b99dd6d1e822a5b07066be7ea104cb7f51820a558cf18b69ac9ace838b08d77a00f20bdd92fc0eac70f2f464754401d081ee2f20026f69b0734891bf993c601a510219088c778358d0a101cc3008109a3a56f669a18ca10e86d64574f915cafae7d7200656679969532d17f82548a4380525bd60a1036bc23ca047ad13e35f629dc958b65f1b4a3024e50a8bdb77dc094ea9f4db6e4aa57cbb2855487112ab54d6bb6d6f32125508a74b5924fa294a19040af3484dbe8fccaaa0438fa2d9ed2030d11c84b39022ef6314fc9fedc3926e1c8c3fb4b911c52a10ea8bdda94626d6fa88f1c05d04325ccb12fc39206c708f0fcf8642c20e8bca05fdfb26c7e875292d54951153fc7fc44f9859b5ce1e5a66445344bf2a553052e57f77e15d0eb36f86832cb67e92772c54808182081aa36669d73353b3f93e5e4886cf2ac7e34ac029e608254277f02bebaf5a8022730a85a9300515c75e4709c541d2ec6577bdc696cc26110c38ae0eae32e64e5e19821beb22e0fa3d7b7b587211ce99b9f4c707a7cb7e079e253390a26c9e12c29d59b9116e0c9caf4a8883f39e2f99d32121ec789643c71abe023cae61440bafc0c7c7571fd993cebfbeb3c531205e7daf8564ee5797605b912628acf67765142a144134cbd10106d274ea117ed64922c7677444b18af8be6b1b2ea767fcfd816274cc880e767e09626bbd4d92b1788cff21596a982d5f9b449020f12e2422f12250581a940bb52c282a054268871c0a16425b9f042942fdb82547933ea73211461fe00d027883b8d55d2e3de56424774e8c4443badb9c9a72dbc8217aaadc5d5737d755948810412243758e073385f27023c59bf17763418a0dc01cb54d344df96648944df136e7c9fa544906c89bc242d2627b1144c1bd76b11457265f06f7647a14f8ba228618414d3bb59f2959fcf87cd26876940d084e020dcfaaa580a35f8002d90975d059454b9b5b931de9090d96def2183555ff763965df0600630cbbb2eea0a3501608263e8859822be044914e8c9b039188fa204d2e6465601e512e40fe0e260f3aa31fa3d373862acdd1df500714a244ea0ee7e2df89332897cfdab517ead4af5e9b1b2e50baffacf6a9cb6847913d7b28275ad64f9e5947a15f1ba486537acce0b954eb902e99b5f26f4a0646f6976119164ed4d324f88a03cbd3912380ad02259bf00b1a412aad1cb77ebcd1bf0f4b5e22ae523370d0ae9f5d02ad749bbd2254ddef925b958aaeae7d37bf3e399901c536d6e8825f5f2c7a6f87cb659352b33c6a13be738bb28ca049b05be9506ab608cbc79b919be7903a99cd8eded745727d59cb56ad60c519f71b0cf5df542e885b051af864a1859da4ebd7502ad1f6a8ba88a5b85b71d03a77c86560186477061e44f8e23cab18547c0275aac66b44f85fa975be34780bbbef8495cc2d9627902b8f1c20fa17267fc909ab3f4e04029573cdbd7f7690f78a607a145f7f32068c70b3d89d3cee8df35eb2712721db64b534232d13a663713dd315f55b2ff8f552da6f90e62ba0a2dae1c343d6077ccaf0005013b8f99af73bce47677dfb2cfedb6f5f1f151b32659638e8773f7b398c633991005c574a223bc7d24a1323ffaff58348bcbdec06a96c0efc8eaf7da352b563b49bf61373bcd6ed36eda5af25bef347dab516fd86776fdccb67fd6ebfd7aafdf6a9d779c66a7deadf7ec2ff56ebfaef60d2c7efbaa6bb25e527b63ff1feb0acdacbeddee743a8d86a3fb1da974b7d3a959f704d3c8ea3b356b4899d56fb76dbb6ed7ac5fd8b7fa2df536506fdd7acd7af25531f59af508fddf5ec07ed7adfe7feb35fddfdf35ebabb66913e4a92f3eab87dd769c6eb761aba6dd0b2d719cb6ed349bf647cdba3b8c6fadf0ebf67dd4accb4fe22f3097e19e3c8d5ea7e774ea9d559e66dd719ca6ddee7dd4ace7f5505c10a6ec53d5dc0b126543d4ac2bcdb5f662956280a87e7ed7d171faf547feaafae56f3d6f42c44d90ffa13698207f13e46f82fc4d90bf09f23741fe26c8df04f99b207f13e46f82fc0f2b4d90bf09f23741fe26c8df04f99b207f13e46f82fc4d90bf09f23741fe26c8ff20d004f99b207f13e46f82fc4d90bf09f23741fe26c8df04f99b207f13e46f82fc4d90bf09f23741fe26c8df04f99b207f13e46f82fc4d90ffc747be15aa9a4641e5e0eb42c4ff471666ba6a790239a27253de268ffed8b1e20b3c02e5a9c294c8736d991c25156c2157bc8266c759110b9a8d7a054641cb69d876a35162144c20112728058e6377bb6b4a819d530a3abd6ed7eefecb94824dc87fcfeef6ec4eb75199529037b032a560833f4429d8434368f79abd96bda614e85158710abaffa39c02e0331d84b6452cd8ccc55c5b260f6cf8019bf8ff6c62e7e1fff984d88eff2f86f267e89dfd208bd1df6c17660739b4d6d7db89f578f3f5cbf32012c31bd9f107ddd48dc9143a76ef613a9f7957cdbf94fe3285977f1e46de9fcb8b0e72ee137ff03271e36b397eb57bc307f84ba6a3a178786e87e9c8a5e9289aa22fdd3860ddf180348637f775345a90c7e75bfc36bae763e776e68f5ad103be8fdfe2311ec7c38e37b88ec603928edfd9e2eee6a239bc1acebd9ba0338e7ba97f69bfc3d7843c4cbf3595ec2dee2dc78397e5f7d1828ce98ff69d73d11cdedccfdc0189869777f3bbabe07d1cbf75dcd1f572dc20e9f7d7a79977c516f7af17cd87e5f0cb8f1bd919d3db99fbdc4ae1e89e4f5eebedc7c1edf2fb7bab831ae3a5dba8a76f8d5eea0f5e52ffc6ee3d5ef622f8faf6e5b2d01f8f836f01bcb925e3691d23472ec7af1702bdf4041cb55479b8d0e608bedecfddc175eb2126a9abdaf86c6377d09bc277397f1b3d4570d4a20fd3a739bafcbad4756cdccebcf88978d85ebe8d9e12fff5ae7da7e5aa8dbde503deb471d5170fd3db39babc78771b8b647cf9757a77f5b579d718c70fce1341373fe478f032759ddbd01f90993b4d52b7d1220f0d3bf4623f71b15d779dafedbbe9c51c5d093cbc795272e25fd5f16be356bc8d5a7c38ed44b3bfae92607893907610dcc62dec395f3bb7b15f7f588ea97f25badf1bdfbe3c5ef6e68f01eb7a57ad1faee3132f7e8986df6e5bc36fd74b7f702d60dd9fe598ff63fd3f1e6213cea844d43f7e6cad519fa3c2d57beae06ad4fb2da7df70ce9b3dbbd969385de75fa3c2759c56d36efe6be796edb49bddbab33a23da2da7de6bb5bbf543e7d60e7eddbe43e7d611fcc173ab9cc76936dbed96a1c2192a9ca1c2192a9ca1c2192a9ca1c2192a9ca1c215d5860a67a870860a67a870860a771466a870860ab74f63a870860a67a870860a67a870860a67a870860a771861a870860a67a870860a67a870860a67a870860a67a870860a67a870860a67a870860a67a870860a67a870860a67a870860a67a870ff3b882ceb48fe7f9309b72a1460eaa345051a5c01b7621434bacda324b83297a0d5ec39f5cebf4882735a4dbbf5ff8b4cd0727a4ebdd1edb4ab9309b206562713acf19f201334db76abb5f9ffeae85130243843823bb67714977981017779fded67fdfed7e8e5e27a3808ebee68fee572ba60fec016c3c1227463af378c5fd2e1b4f9d7e320246fa31f5f2ef1d76078f9b5eb8e5eea6fcf175338b85e7a8d97fae3f3edcbcbb737f97039dcc530ffe669fe7df4b2f047a4f1f87cfbf6fde5e5e2fbaffb99fb7a11fa0382ddc12f3c1cdccf5cfa445cfaa3378cc8f5e3e8251a377ee1c780a9b282c7814dfcc1b740b3ef7ed6b11f13e23b17338ffed8ce4bfd647cf3c41e474fc48fc974fc6c3b70f4548797f3008e5a893f20a17b69bfbf35aec5f8677df17dfa75f38d9ba7c41f2cc863f4347b735ee478d4aa3f5ef6eaf0f5498c7f36ff7abcecb1f1e83a7a0c58f72dee45e867f32f956f78b56077d3d6703c5a087779f1ea3ab7627cf9adfbbd112c15f67be37636be8934930ede3c49f7aa79920596ad4564a83d87da60a83d86da63a83d86da63a83d86da63a83d86da63a83d86da63a83d879586da63a83d86da63a83d86da63a83d86da63a83d86da63a83d86da63a83d078186da63a83d86da63a83d86da63a83d86da63a83d86da63a83d86da63a83d86da63a83d86da63a83d86da63a83d86da63a83d86daf3f1f1f17f010000ffff010000ffff8806ce659ac80000`))) +var _ = pkger.Apply(mem.UnmarshalEmbed([]byte(`1f8b08000000000000ffec7d596fe3b816e65fb9d06b259125799381fb90a5e3385d592a49c5b12f1a0d8aa224da5c5424e5258dfaef034ab22def0ea6319807a2109be4f9b86fe7d0e743fd636116716975feb162ac922cb8809cda97420132be7f2d035daee53758581dcb7ee724a348da7d2ec6af2980a8049d5f3ef7cebbdc3ab37a34e5423d0395589dc3a59e598f8022ab635180997566dd7068752cebcc7a0322464a57f75322216d944281991d733bc0ac9aff8573755aab1e808289d5f99f7561fd7566bd2a4090d551224365e40501c999d5b1a48efd27442962216270def9cfa13ed890b308c7d699d5e5b79820a9abd0ddb988b9aea8188c3cf5703134d4f01b94e6d8208bb06e753057485a6716e43415484a3b2240a16a42fc89d36a9c7c4eabd14f82833cce14c00c099b60a9ca0434cb43629e2abe0cd8a0a8b088409c2648ace26155184ab08a20b81e0ddd46c3f1b7126ccc14120c101b85532042b9092304a70ac3554a424125b6cc2e000b3385c90e91cc0245d04a40c3c62aa2f35562b05e89543b2013e0acc5dc46732dde70dc4a7ca34a452ae3346bd4fcf5d8aaad1440be01b5d3319e5967560814088044b6fc4536a27628f0249f174403a4fb8318e4216671256803c99c6a5ce76ed6d7523003625e4d8172528d2668568d8ef416a9c45344abd119d50d454270a1fb8466e904e8464604e8864554afb7a3dbe01864b1e10ea212a5d26398626b1c83d888827c991d04521ea2a3a0741ca38dfe3d67488cb1e25798db31ff95a17c3a2a800f0cf803b653140399c9f3989f438211533608697e689e82c521f9325eaf962fc0b766ee205a7cb53502a50443a030ff522e110627c2750ae1f117d032935f43db3c3d318348e1894889a4dc1a1340088a85be2c63086082ec89771460ffca50b631e18085f3009084136a4320210831d8400810869cd9215028056273c504880bd6b25324c6d2fe9501a630d984081046587dda31a78816ad5904d69110b131200adb0180631e45f6a4be09902910c89ecd1220137be2ae8b43c4b0446ccca91df3732ae52fb2b93a76425687354cbf040f11c414902fe5c94f80f266aee68ac55c8eb1ce22b45ef239e19bab0f8df509524ea76bef18c04d040f113c88a048090c0fd72315171bf544927185a3f932b02ecefb106269179f93f611f172704ec5d97afa15884fc74b08d8c9e894f3d39b920a9e2b57a7a14be5e43470a9fdac83e52f725e2807369d178ac31a20c8a208106e276873d6624e008bcf4753658fa66aa74c6b1e104fb6abd5523b1208a979bab3d8a5d01640aa5c733980d16af9de92f2110db268f7d06e407429f2148c0dd8d632dd890b33b1e316da03569822a900dd3837f4fac4908bd44e203920caff8054c720f9c92b8ea244be748ec1f45e6027c094809c4d8ec1141f237608a455ca133a90c34e685a8edb51e908c031b46192b1b140204462eb7a2810690c39db99b790542e03359be636e57eac5454ed38871718cc77a7a740ca68eba25c4af51af3f6365f2231c110edcfbfbdb11692d9d68d5a9554ec2bc0b0c29f074ab1a50ab7b4eb111288cea73c21b915abb6a608b3cf24b3318b0882db5bac14333e5d4f2720900ac0b18d60c2b77ab029b5290e4382a660f3f85b02634e2967f6c2f23e00819c707118b2a5516e02f489cfe93a86821843ce0016fa4049915078b329148871001492b94d210e0a779cf59b888a399a1eae497f1666e6518cbdb04d8f2329da1a829d38a942bed53ea598bef9f2d900c1e6b25fcab1044acdf708e52f8215f2b6a52a153c0bcbf3fdefc5f9fe379a29c4b4e22ded34d8be88699ca94f1b308937d2b182092224c9075a890caa6c736e381378ac178ec864be6ad7c50b13603cb1552270a4721b35e6656c134c08521809dd47c5e9463353c1295209caa45d98137fafeeb152f0e50c7bb4b55372ea20c836eff4ed9cb9ad6dc70770c5de42b374ebc9611bb55cfb01564106c7485d7011dbd3a91d73dd1a86e26345ec30fed7bb05a3fd03598857cdf802747be1fd9afed26abd9e6e40f03c63e73b5e2f048e22c2e1d826914c381faf4b2516592a112b97e086308d1ccf0611127caf607b371742b8a5c994e93c10609760340544213145402548d04d15bd00a5e5e3d2966082d3cd83512a046800521b8254c164b3d22ce0122b6ddd28b4a9d94c00990302f26b41ebd0486c9b010b4c04a45288a6e5536d05313b8702cccb913d4f058af00c85e71117faacd96cee3ccbdfbc49a84fc303a26d15715dbc3cac4e021d2b6d97aeb68ec82d54711ac64ed4e6a9b40edcb685d7e58b3dc02f788a98420469ab757e81b9cd153a24b281520207593149fb407a3bc94380ea79770c6307208e417cb0c22536263c38b15825004436e3c503d33e7861ce1f479c50730964190d8a793e021428c652156f9bfba05ad701f1d2b8da07cbfb7a0890319caf18be58c9bc6a38f09575905f40f9613fb3173f7e408a0e886c7d214024d41e0c0deb7b2469300e23778f50cac4564850bc58461508a6204676c4d9569d85840295d8f931b22967482d77d7ae741ba842f3dc16aa34ff883325f701b6fab214d8890b0f085300c7bbc4386460335dceabb71d932042496ebded02662cffd9642d5d8fea76da4ce9cb086df52d97acede77d425b0bb2c54e3e8ad28a420ae0d614aea3cb27ab2dc0c1ba44c6f67444229809640738c42223bb7397985420887797a20460525f503ba519c3b9bea12b390860fb4a98e250255b124c912dcaeb93f398a08b8a7cf9cab2fa1d4aa72c6e8a53f1532c8e945f79c995b054254f44f3b4dc3aa7c0d5e2ddef04f4b20f218a26e52afd422e8aa4043192e8d4ce2c732e56e757b21c9d91559ec58f86a780234c901ee42fc017af1ea7c009884f6d498c183e75e6304d4f9d2e2e1667dc716c2a404cc189e0d3e75daa93a76382c442bbdc8f5ebed6ee870894bffc1409c7e7770d5e46be94a3a292eccf92b1fc30ca1370b4503d4ec41f9df1f24d19492870aab8488353f063c6a7cc066cfe15f8e2e1fa2b7996efd765a6741c5fe4cab7362a2f8a27c8452266f862e25453185028c20c2636c9f5c41180e38d4c8ad36023690ee8b26841b556b7f97bc67a72caa58a457907ae498a479d9de9128949b9c30a51bcb89f56511b02420200c7724b404026d1662ae171bc55a64d712c80e25be91226a8dcb695546dcde8ea122093f2cb062141c273175128e05a24f7e8c823516eb4962a5faee155acd05c5b5c7c2f9f2e2b313b0504a915d60e05982e23318e96e1ca890662541a60856894e6af254524cddf0957b6cf5c2140d692609a55a3115592e7caf5328921b550f857a7a3cc6f8b6a52ca09a9c637b3943bbf5c0fab430eb398a088e03859ab55cea59e7c1bcd102c9e02b644a5b6b952de9054c56bef3e85357feec7bc78e0c1dcc6bc1cba715bea0500524c014c3043626ea7e3385f0cab8bf1204aa25cdd281aa04d82f2cb0e70bc0ae6983c5c2a1c14e7e68efeb26946144e413efc79c2af8c2b14e6bf1a95cfaa2cbf3d16ba7c25987f2ce6692db1ece232ada25debb4f2714a07255d16a9f586c57da1e399d0a0fce597cb7c528a50563c44a4457fd3c21222a88cafae048162344b97015bce99027af6cad37a15b261feacb8888528c8e24a7c39b5da74ca4de92d4939f85be972ae9b5f2eefd58f675209cc727543ce192cbf56c597abcd3ab30a651c0453818b87a22261b5c1d7e2f6c219a3ec5ea986af4276a622a7b91e6fe751bd66ad336b8258c885bdcb5c85098009706ba7a1524ee68e576b1c41e75ffa883815b7706f3b04cec4042d1c0c0fe09271181d466cfb161e001fe9b15ed12193faafd4c60f00376df1a3b854f0d9fc08706585ef4395c6f83eb1e0d9de89d2a67871aeef92eeb14cf742abe6e75ed086157a14971ba37f9d596f48aaa5db2ecb082992963ebb45d2030f75233bff58a7f9343f00cc16aec5273b4d77f9030f4f80da31bfa03ccc73bc977a77c7722e9ca6f5fbf7ef332b2a3a73d89dbb53f8349eab9468286651eee11d2205b4fad1f9c762855ff60a766649fc89ac8edf3cb3a83e493aae536fd5db75a7eee4297fe7274dc7726bae73eed4ce1de7ad56ebd4fc4ea371d1f2eaad5abbe63bdf6aed4e4d9f1b58fe1deaa12946499f8d9d7fac1b34b13a4eb3d56ab96e3d1f77a4e3ed56ebcc7a24988dad8e7766f518b73acda6e3d49c33eb270ead4e4387ba3ad4ae9d592fa12ea676663d83f06f18f3bf6b56e77fb5b3fcdf5f67d665aed3a608ea1a5ff597d3f4bc76db7574d71e659ee2794dc7abd79ddf67d6c37e7c63815ff6eff79975fd45fc15162ad991c7f55bbed7aab51679ea35cff3ea4ed3ff7d66bd2ea7e28a70ad9feaee5e91713145f59a96dce656ac167411cbbfbfe7de7179f04719d4e3f257be6e12248c93ffbe3e18277fe3e46f9cfc8d93bf71f2374efec6c9df38f91b277fe3e46f9cfcf70b8d93bf71f2374efec6c9df38f91b277fe3e46f9cfc8d93bf71f2374efec6c97f2fd038f91b277fe3e46f9cfc8d93bf71f2374efec6c9df38f91b277fe3e46f9cfc8d93bf71f2374efec6c9df38f91b277fe3e46f9cfc8d93ffefdfe551a85b3a8e4f76beae78fcff2edc4c173d4f81404cadca5be5c92b3b547c8547a02d55901175916b260749056bc825afc06f2d880575b7b69351e03a6f8edff1fc4ead7dd1aa35dd9ad36eb95b8c820810798452e0794ebbbda4143825a5a0e5b7db4efb5fa314d4db4ed36bba0bf77dbfe934da5ebbe9eea314e4f87a7b49115874701fa5e0007e1fa560070da1e9d7fd86b3a214e85958700adaff4f39057690bb8aaef10a564b31d8431d58b10356deffc5b22e9dffcbe5b0eefd5f75e42fd01ba741e1a1bf3a2cccf9b16fa72f0f13eb7a341b838f410cbd9746d0fde9f7d85532ecbea40185cddecdfb145d5f4e9fe6bd6fd7f832ee5d5fb6e1f5d5677847e4f0ad8683feed7ce892ec7b7f4686ec47b377f3c714dec5ad21f5b3f0daf9041f2979c297b3477655d765bc76c7b277a75a012523e0397eab3507cfd7fef439e6baecf8f9ee72d50eea24908669801d39ec0f6b4ff872fe70579453b625ff6bf03f796338e7bda73f2fd99d6ac1ee2d1bbefb35f0f122871f8e5fe7d761ef09fc5459bf279f5e9b49d60f58d61f8fd0b7365dd45b6d43f7250df1aa8f037a3b026e380fbcf76c78c347437a4f0774889fbcd5383dbce5e354b4cf1d4e02f643419734876f7cf694a7dd4f207d2170d197d1e3145d5f7d06ee2c1d5e5f8e1e6e2eeb0fee903eb9cb3ed702efb2f9f0164ed18dc48bb6e57f371bf345d7ea8b1fde86459ef1550b79f70476678d0fb7910e5ce5476fbcfddd7d49c351fdcf6579d797ed6197b8cf4cb5207d9f0677241ab87e1676dfb3f0cef19faf7d5ddf72fed7f2dfcca6bdbbc71aeacfc8f3ebbd1a7cdc33d0afab01f56b61d7574fa39ea3d7c3be75d21bd5db83d72b0ee93b7d7ebd6f21779606544561d78fcab6f8d16b2f0ebb3aff7bedf9f53e1ad0591250892bf58ec1c7e334e8de369e28c9822ec986af0e0ebafe087caae9a0ff3206fd067bc297ba2df1c3e86a8a6ed42870671338e271eff372fa74f34887238507fd4731f4ee2761bf317ec297a321d573b29cbbf9a0ff92861f0fcddecd8fbcfd03eacf87ddf7b95e9bba6ce8fa12f47f54cbac0d3f92daf7fe0b19b8fe7cf0f192066ebd19503f1bbea9e578855d7ffa342ac704f7be35becfe3e6e0faaa3944bc773dcc06ec71fad4feb3f57ced27cfa3e904deec1cffb2ae5b09fa61f684afe6a01ff270adafd079747f361e2a75434a18b85b9b13f5fdf5727d5ebcc734ecbe47e1c7bd8c3e6ab877f7a2d729096f6af8c3bd97837e43f4aa7bc6f565e0f59abdeb87e9c34dfc39a48356d87daf87d7ce78d87f9c407a5b037d3f7ba28d49407fb67aa3c6b28e80de2abd6f8bbece30c49793e7d1ec13766fb34a5f69e0366adf3f1e53447feab6bb45db1b3f022f2490be8f7b7fdc377a7fdccec3eead049f5bf9abf3ef0efaf7e3c74fbd67c2c9f3b59f63f371f6ae9260546f7ff72ebf5d8fa6937c9fc4fffdaff57fa97e45823385587858e15aa2be46e2acf9e78ef3e6d63a0dafe37a1775dfa9b75cafedfd6b24ce96d7a83bf57f4de372bc66bd5df316da4db3e1d5fc46b35ddba7716de097fddba7711dc0efd5b8b6f378f57ab3d930244e43e234244e43e234244e43e234244e43e23424ceaad890380d89d390380d89d390380fc20c89d3903877490c89d390380d89d390380d89d390380d89d39038f7230c89d390380d89d390380d89d390380d89d390380d89d390380d89d390380d89d390380d89d390380d89d390380d89d390380d89f3ff0f12d6d293ffdfe4702e0ab5310bd1ec04026705b76014786df7287db3f6e6d43b75bfe3352e1a2db7d56ab6fdf6bf48dff41a75a7f1efd1375b5ea351f397ff2354d36bb7dda6bff77f84aab71cb7d15a522b971ddc4bdfdc8fff0299a0de741a8dd5ff0895cf82a16f1afae6fe93a3bac957dccde7ebdb3fde6a8f3ffbef57b7bd6e520bfad36fd7a3190fbb8e7c8e791b74df93e18a2ba6861f2f49affbc8071ff79fc38f1f7e8fbcff7cc1b57a6fc5e72b78936f8d8f617f360a5c87f4ee5e264b1e552d9cf4dea693b04b6a41f767ce895ad4f1dcbd9f0cefc6151ee90b41773fd4a03f4b876ebdd9eb3e9280bd10385af1199fbbf1fc998424e83e4e82fecf38ecb6e31f1ff7b5417f269eef1ea7837ebdc2737c9c045d7ffe842f470f37c364407f784ff3deb717b7ddfeeee5d86fba6de0a6c255bd697403af17076e43827e83f4ba2f9381f7ae86fd46ade4e2c5837e63dcbb7b74e0ddd504b21f31eccec8e0e391f4eeeec990becff3fedfcc925e37990ffb03bf47935a7877f5f984db9341d9d6ef34fdfc4efdf970defbb695f6399d0cdeead906cff5db7b3749022a63d4f79d5e773881f8ca812ec986f3ab2bc85e92a0abee82f98a7b36a0fe18bdd5ff7cbef6cbf93dce432b4e0364c845fbfa60c845865c64c845865c64c845865c64c845865c64c845865c64c845fb85865c64c845865c64c845865c64c845865c64c845865c64c845865c64c8457b81865c64c845865c64c845865c64c845865c64c845865c64c845865c64c845865c64c845865c64c845865c64c845865c64c845865cf4fbf7efff030000ffff010000ffff50a73adfd6cb0000`))) From 12888632647847f845b581ed6a511f4dcf4cf944 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Thu, 21 Oct 2021 21:44:45 +0800 Subject: [PATCH 067/349] Github action to dockerhub. --- .github/workflows/dockerhub.yml | 65 +++++++++++++++++++++++++++++++++ Dockerfile | 7 +++- 2 files changed, 70 insertions(+), 2 deletions(-) create mode 100644 .github/workflows/dockerhub.yml diff --git a/.github/workflows/dockerhub.yml b/.github/workflows/dockerhub.yml new file mode 100644 index 000000000..9d7decffc --- /dev/null +++ b/.github/workflows/dockerhub.yml @@ -0,0 +1,65 @@ +name: CI to Docker Hub + +on: + push: + branches: + - "master" + tags: + - "v*" + pull_request: + branches: + - "master" + +jobs: + docker: + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@master + + - name: Login to DockerHub + uses: docker/login-action@v1 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + + - name: Set up Docker Buildx + id: buildx + uses: docker/setup-buildx-action@master + + # https://github.com/docker/metadata-action + - name: Docker meta + id: meta + uses: docker/metadata-action@v3 + with: + images: | + ${{ secrets.DOCKERHUB_USERNAME }}/artalk-go + tags: | + type=ref,event=branch + type=ref,event=pr + type=semver,pattern={{version}} + type=semver,pattern={{major}}.{{minor}} + type=sha + + # https://github.com/docker/setup-qemu-action + - name: Set up QEMU + id: qemu + uses: docker/setup-qemu-action@v1 + with: + platforms: all + + # build docker image + - name: Build and push + id: docker_build + uses: docker/build-push-action@v2 + with: + builder: ${{ steps.buildx.outputs.name }} + context: ./ + platforms: linux/amd64,linux/arm64,linux/arm/v7 + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + + - name: Image digest + run: echo ${{ steps.docker_build.outputs.digest }} diff --git a/Dockerfile b/Dockerfile index f9b440f43..b234261d8 100644 --- a/Dockerfile +++ b/Dockerfile @@ -8,8 +8,11 @@ RUN set -ex \ && apk upgrade \ && apk add make git gcc musl-dev yarn -# 1. build frontend -RUN git clone https://github.com/ArtalkJS/Artalk.git Artalk +# 1. build frontend (using latest tag) +RUN git clone https://github.com/ArtalkJS/Artalk.git Artalk \ + && cd Artalk \ + && git fetch --tags \ + && git checkout $(git describe --tags --abbrev=0) RUN set -ex \ && cd ./Artalk \ From dce93b36792d6f331c21aa18bda3bc94ca007c7c Mon Sep 17 00:00:00 2001 From: qwqcode Date: Thu, 21 Oct 2021 23:06:11 +0800 Subject: [PATCH 068/349] Update GitHub actions & add some badges. --- .github/workflows/dockerhub.yml | 26 +++++++++++++++++++++----- README.md | 19 +++++++++++-------- 2 files changed, 32 insertions(+), 13 deletions(-) diff --git a/.github/workflows/dockerhub.yml b/.github/workflows/dockerhub.yml index 9d7decffc..d38a5355b 100644 --- a/.github/workflows/dockerhub.yml +++ b/.github/workflows/dockerhub.yml @@ -28,6 +28,7 @@ jobs: id: buildx uses: docker/setup-buildx-action@master + # Docker tag 值生成 # https://github.com/docker/metadata-action - name: Docker meta id: meta @@ -42,24 +43,39 @@ jobs: type=semver,pattern={{major}}.{{minor}} type=sha + # 编译多平台 # https://github.com/docker/setup-qemu-action - - name: Set up QEMU - id: qemu - uses: docker/setup-qemu-action@v1 + # - name: Set up QEMU + # id: qemu + # uses: docker/setup-qemu-action@v1 + # with: + # platforms: all + + # 缓存 Docker + - name: Cache Docker layers + uses: actions/cache@v2 with: - platforms: all + path: /tmp/.buildx-cache + key: ${{ runner.os }}-buildx-${{ github.sha }} + restore-keys: | + ${{ runner.os }}-buildx- # build docker image + # https://github.com/docker/build-push-action - name: Build and push id: docker_build uses: docker/build-push-action@v2 with: builder: ${{ steps.buildx.outputs.name }} context: ./ - platforms: linux/amd64,linux/arm64,linux/arm/v7 + file: ./Dockerfile + # platforms: linux/amd64,linux/arm64,linux/arm/v7 push: true tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} + # 缓存 + cache-from: type=local,src=/tmp/.buildx-cache + cache-to: type=local,dest=/tmp/.buildx-cache - name: Image digest run: echo ${{ steps.docker_build.outputs.digest }} diff --git a/README.md b/README.md index 772ae2459..88341109f 100644 --- a/README.md +++ b/README.md @@ -6,15 +6,20 @@ > ArtalkGo: Golang backend of Artalk. +[![GitHub issues](https://img.shields.io/github/issues/ArtalkJS/ArtalkGo)](https://github.com/ArtalkJS/ArtalkGo/issues) +[![](https://img.shields.io/github/issues-pr/ArtalkJS/ArtalkGo)](https://github.com/ArtalkJS/ArtalkGo/pulls) +[![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2FArtalkJS%2FArtalkGo.svg?type=shield)](https://app.fossa.com/projects/git%2Bgithub.com%2FArtalkJS%2FArtalkGo?ref=badge_shield) +[![CI to Docker Hub](https://github.com/ArtalkJS/ArtalkGo/actions/workflows/dockerhub.yml/badge.svg)](https://github.com/ArtalkJS/ArtalkGo/actions/workflows/dockerhub.yml) + - 高效 - 跨平台 - 轻松部署 - 多站点支持 - 多数据库类型支持 -# 部署方针 +## 部署方针 -## 普通方式 +### 普通方式 1. 前往 [Release](https://github.com/ArtalkJS/ArtalkGo/releases) 下载已编译二进制文件 2. 编辑配置文件 @@ -26,7 +31,7 @@ 4. 反代设定的端口到 80 并套上 CDN (Nginx, Apache) 5. 持久化运作 artalk-go 程序 (tmux, sysctl) -## Docker(推荐) +### Docker(推荐) ```sh # 为 ArtalkGo 创建一个目录 @@ -60,9 +65,9 @@ $ docker run -d \ - 配置文件路径 `./conf.yml` - 数据文件目录 `./data/` -# 编译 +## 编译 -## 编译二进制文件 +### 编译二进制文件 ```sh $ make all @@ -70,7 +75,7 @@ $ make all 编译后二进制文件将输出到 `bin/` 目录下 -## Docker 镜像制作 +### Docker 镜像制作 ```sh ## 制作镜像 @@ -155,6 +160,4 @@ $ make docker-push ## License -[![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2FArtalkJS%2FArtalkGo.svg?type=shield)](https://app.fossa.com/projects/git%2Bgithub.com%2FArtalkJS%2FArtalkGo?ref=badge_shield) - [![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2FArtalkJS%2FArtalkGo.svg?type=large)](https://app.fossa.com/projects/git%2Bgithub.com%2FArtalkJS%2FArtalkGo?ref=badge_large) From edce679f884cb6bfbbd932165698c965b3af87f9 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Thu, 21 Oct 2021 23:33:18 +0800 Subject: [PATCH 069/349] Modify config allow_origin to allow_origins Signed-off-by: qwqcode --- .github/workflows/dockerhub.yml | 11 ++--------- artalk-go.example.yml | 2 +- config/config.go | 20 ++++++++++---------- http/a_http.go | 2 +- 4 files changed, 14 insertions(+), 21 deletions(-) diff --git a/.github/workflows/dockerhub.yml b/.github/workflows/dockerhub.yml index d38a5355b..90bbe1102 100644 --- a/.github/workflows/dockerhub.yml +++ b/.github/workflows/dockerhub.yml @@ -1,14 +1,7 @@ name: CI to Docker Hub -on: - push: - branches: - - "master" - tags: - - "v*" - pull_request: - branches: - - "master" +on: [push, pull_request] + jobs: docker: diff --git a/artalk-go.example.yml b/artalk-go.example.yml index 37ad33824..50663ea70 100644 --- a/artalk-go.example.yml +++ b/artalk-go.example.yml @@ -24,7 +24,7 @@ log: filename: "./data/artalk-go.log" # 日志文件路径 # 允许跨域访问的域名 -allow_origin: +allow_origins: - "*" # '*' 跨域无限制 # - 'http://localhost:8080' diff --git a/config/config.go b/config/config.go index 9daaac9e5..bcc4bd651 100644 --- a/config/config.go +++ b/config/config.go @@ -14,16 +14,16 @@ var Instance *Config // Config 配置 // @link https://godoc.org/github.com/mitchellh/mapstructure type Config struct { - AppKey string `mapstructure:"app_key" json:"app_key"` // 加密密钥 - Debug bool `mapstructure:"debug" json:"debug"` // 调试模式 - TimeZone string `mapstructure:"timezone" json:"timezone"` // 时区 - Host string `mapstructure:"host" json:"host"` // HTTP Server 监听 IP - Port int `mapstructure:"port" json:"port"` // HTTP Server 监听 Port - DB DBConf `mapstructure:"db" json:"db"` // 数据文件 - Log LogConf `mapstructure:"log" json:"log"` // 日志文件 - AllowOrigin []string `mapstructure:"allow_origin" json:"allow_origin"` // 允许跨域访问的域名 - SSL SSLConf `mapstructure:"ssl" json:"ssl"` // SSL - SiteDefault string `mapstructure:"site_default" json:"site_default"` // 默认站点名(当请求无指定 site_name 时使用) + AppKey string `mapstructure:"app_key" json:"app_key"` // 加密密钥 + Debug bool `mapstructure:"debug" json:"debug"` // 调试模式 + TimeZone string `mapstructure:"timezone" json:"timezone"` // 时区 + Host string `mapstructure:"host" json:"host"` // HTTP Server 监听 IP + Port int `mapstructure:"port" json:"port"` // HTTP Server 监听 Port + DB DBConf `mapstructure:"db" json:"db"` // 数据文件 + Log LogConf `mapstructure:"log" json:"log"` // 日志文件 + AllowOrigins []string `mapstructure:"allow_origins" json:"allow_origins"` // 允许跨域访问的域名 + SSL SSLConf `mapstructure:"ssl" json:"ssl"` // SSL + SiteDefault string `mapstructure:"site_default" json:"site_default"` // 默认站点名(当请求无指定 site_name 时使用) AdminUsers []AdminUserConf `mapstructure:"admin_users" json:"admin_users"` LoginTimeout int `mapstructure:"login_timeout" json:"login_timeout"` Moderator ModeratorConf `mapstructure:"moderator" json:"moderator"` diff --git a/http/a_http.go b/http/a_http.go index 99b1c5645..2b3627238 100644 --- a/http/a_http.go +++ b/http/a_http.go @@ -20,7 +20,7 @@ func Run() { e.HideBanner = true e.Use(middleware.CORSWithConfig(middleware.CORSConfig{ - AllowOrigins: config.Instance.AllowOrigin, + AllowOrigins: config.Instance.AllowOrigins, })) // Logger From 3b2c34d6fe8dc8a2cbcf658e3126f2d7d290efc7 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Thu, 21 Oct 2021 23:47:07 +0800 Subject: [PATCH 070/349] Fix empty version issue. --- Dockerfile | 1 + 1 file changed, 1 insertion(+) diff --git a/Dockerfile b/Dockerfile index b234261d8..153d1b862 100644 --- a/Dockerfile +++ b/Dockerfile @@ -27,6 +27,7 @@ RUN cp -r ./Artalk/dist ./ArtalkGo/frontend RUN set -ex \ && cd ./ArtalkGo \ + && git fetch --tags \ && export VERSION=$(git describe --tags --abbrev=0) \ && export COMMIT_SHA=$(git rev-parse --short HEAD) \ && go mod tidy \ From 3155e28fe37753bf4564050e68f9df228fdedab8 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Fri, 22 Oct 2021 15:39:26 +0800 Subject: [PATCH 071/349] feat: Add goreleaser with golang-cross. Signed-off-by: qwqcode --- .github/workflows/dockerhub.yml | 13 ++- .github/workflows/release.yml | 47 +++++++++++ .gitignore | 1 + .goreleaser.yml | 144 ++++++++++++++++++++++++++++---- .vscode/settings.json | 2 + Dockerfile | 28 +++---- README.md | 13 ++- lib/version.go | 2 +- makefile | 71 ++++++++++++++-- pkged/pkged.go | 12 --- 10 files changed, 276 insertions(+), 57 deletions(-) create mode 100644 .github/workflows/release.yml delete mode 100644 pkged/pkged.go diff --git a/.github/workflows/dockerhub.yml b/.github/workflows/dockerhub.yml index 90bbe1102..3c3f7ee34 100644 --- a/.github/workflows/dockerhub.yml +++ b/.github/workflows/dockerhub.yml @@ -1,7 +1,14 @@ name: CI to Docker Hub -on: [push, pull_request] - +on: + push: + branches: + - "master" + tags: + - "v*" + pull_request: + branches: + - "master" jobs: docker: @@ -10,6 +17,8 @@ jobs: steps: - name: Checkout uses: actions/checkout@master + - run: | + git fetch --prune --unshallow --tags -f - name: Login to DockerHub uses: docker/login-action@v1 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 000000000..5b5c3d6ef --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,47 @@ +name: Release Build + +on: + push: + tags: + - v* + +jobs: + release: + runs-on: ubuntu-latest + steps: + - name: checkout code + uses: actions/checkout@v2 + - run: git fetch --prune --unshallow --tags -f + + - name: setup go + uses: actions/setup-go@v2 + with: + go-version: '^1.16.6' + + # docker `golang-cross` image cache + - run: mkdir -p ~/image-cache + - name: docker image cache + id: image-cache + uses: actions/cache@v1 + with: + path: ~/image-cache + # Adjust key to meet your cache time requirements e.g. + # ${{ hashFiles(*) }} can be useful here to invalidate + # cache on file changes + key: image-cache-golang-cross + + - if: steps.image-cache.outputs.cache-hit != 'true' + run: | + docker pull troian/golang-cross + docker save -o ~/image-cache/golang-cross.tar troian/golang-cross + + - if: steps.image-cache.outputs.cache-hit == 'true' + run: docker load -i ~/image-cache/golang-cross.tar + + # build + - name: setup release environment + run: |- + echo 'GITHUB_TOKEN=${{secrets.GORELEASER_ACCESS_TOKEN}}' > .release-env + + - name: build and release publish + run: make release diff --git a/.gitignore b/.gitignore index d9d6440e5..3da070771 100644 --- a/.gitignore +++ b/.gitignore @@ -22,3 +22,4 @@ bin/ data/ dist/ +pkged/pkged.go diff --git a/.goreleaser.yml b/.goreleaser.yml index 5dbd55950..ad64d7c80 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -1,32 +1,146 @@ -# This is an example .goreleaser.yml file with some sane defaults. -# Make sure to check the documentation at http://goreleaser.com +# Goreleaser Config +# +# https://goreleaser.com/quick-start/ +# https://goreleaser.com/customization/ +# https://goreleaser.com/customization/templates/ +# https://goreleaser.com/customization/fury/ +# https://goreleaser.com/customization/announce/telegram/ + +project_name: artalk-go + +env: + - GO111MODULE=on + - CGO_ENABLED=1 + before: hooks: - # You may remove this if you don't use go modules. - - go mod tidy - # you may remove this if you don't need go generate - - go generate ./... + # install dependencies + - make install + - make update + +# build multi-platform builds: - - env: - - CGO_ENABLED=0 + ## Amd 64 + + # Linux (amd_64) + - id: linux-amd64 goos: - linux + goarch: + - amd64 + env: + - CC=gcc + - CXX=g++ + binary: "{{.ProjectName}}" + main: ./main.go + ldflags: &common_ldflags | + -X github.com/ArtalkJS/ArtalkGo/lib.Version={{.Version}} + -X github.com/ArtalkJS/ArtalkGo/lib.CommitHash={{ .ShortCommit }} + -s -w + + # Windows (amd_64) + - id: windows-amd64 + goos: - windows + goarch: + - amd64 + env: + - CC=x86_64-w64-mingw32-gcc + - CXX=x86_64-w64-mingw32-g++ + binary: "{{.ProjectName}}" + main: ./main.go + ldflags: *common_ldflags + + # Darwin (amd_64) + - id: darwin-amd64 + goos: + - darwin + goarch: + - amd64 + env: + - CC=o64-clang + - CXX=o64-clang++ + binary: "{{.ProjectName}}" + main: ./main.go + ldflags: *common_ldflags + + ## Arm + + # Linux (arm_v7) + - id: linux-armhf + goos: + - linux + goarch: + - arm + goarm: + - 7 + env: + - CC=arm-linux-gnueabihf-gcc + - CXX=arm-linux-gnueabihf-g++ + binary: "{{.ProjectName}}" + main: ./main.go + ldflags: *common_ldflags + + # Linux (arm_64) + - id: linux-arm64 + goos: + - linux + goarch: + - arm64 + env: + - CC=aarch64-linux-gnu-gcc + binary: "{{.ProjectName}}" + main: ./main.go + ldflags: *common_ldflags + + # Darwin (arm_64) + - id: darwin-arm64 + goos: - darwin + goarch: + - arm64 + env: + - CC=oa64-clang + binary: "{{.ProjectName}}" + main: ./main.go + ldflags: *common_ldflags + archives: - - replacements: - darwin: Darwin - linux: Linux - windows: Windows - 386: i386 - amd64: x86_64 + - id: artalk-go + builds: + - linux-amd64 + - darwin-amd64 + - windows-amd64 + - linux-armhf + - linux-arm64 + - darwin-arm64 + name_template: "{{.ProjectName}}_v{{.Version}}_{{.Os}}_{{.Arch}}{{.Arm}}" + format: tar.gz + format_overrides: + - goos: windows + format: zip + wrap_in_directory: true + files: + - README* + - LICENSE* + checksum: name_template: 'checksums.txt' + snapshot: - name_template: "{{ incpatch .Version }}-next" + name_template: "{{.Version}}-SNAPSHOT-{{.ShortCommit}}" + +# changelog changelog: sort: asc filters: exclude: - '^docs:' - '^test:' + +release: + github: + owner: ArtalkJS + name: ArtalkGo + prerelease: auto + draft: true diff --git a/.vscode/settings.json b/.vscode/settings.json index c96d70f54..231288f65 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -3,7 +3,9 @@ "akismet", "artalk", "gomail", + "Goreleaser", "gorm", + "ldflags", "lfshook", "pgsql", "sendmail", diff --git a/Dockerfile b/Dockerfile index 153d1b862..8be02f6d5 100644 --- a/Dockerfile +++ b/Dockerfile @@ -9,34 +9,28 @@ RUN set -ex \ && apk add make git gcc musl-dev yarn # 1. build frontend (using latest tag) -RUN git clone https://github.com/ArtalkJS/Artalk.git Artalk \ - && cd Artalk \ - && git fetch --tags \ - && git checkout $(git describe --tags --abbrev=0) +# RUN git clone https://github.com/ArtalkJS/Artalk.git Artalk \ +# && cd Artalk \ +# && git fetch --tags \ +# && git checkout $(git describe --tags --abbrev=0) -RUN set -ex \ - && cd ./Artalk \ - && yarn install --network-timeout 1000000 \ - && yarn build +# RUN set -ex \ +# && cd ./Artalk \ +# && yarn install --network-timeout 1000000 \ +# && yarn build # 2. build backend COPY . ./ArtalkGo # copy frontend dist folder -RUN cp -r ./Artalk/dist ./ArtalkGo/frontend +# RUN cp -r ./Artalk/dist ./ArtalkGo/frontend RUN set -ex \ && cd ./ArtalkGo \ - && git fetch --tags \ + && git fetch --tags -f \ && export VERSION=$(git describe --tags --abbrev=0) \ && export COMMIT_SHA=$(git rev-parse --short HEAD) \ - && go mod tidy \ - && go install github.com/markbates/pkger/cmd/pkger \ - && pkger -include /frontend -include /email-tpl -o pkged \ - && go build -ldflags "-X github.com/ArtalkJS/ArtalkGo/lib.Version=${VERSION} \ - -X github.com/ArtalkJS/ArtalkGo/lib.LastCommit=${COMMIT_SHA}" \ - -o bin/artalk-go \ - github.com/ArtalkJS/ArtalkGo + && make all ### build final image FROM alpine:3.13 diff --git a/README.md b/README.md index 88341109f..476286930 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,7 @@ 4. 反代设定的端口到 80 并套上 CDN (Nginx, Apache) 5. 持久化运作 artalk-go 程序 (tmux, sysctl) -### Docker(推荐) +### Docker 容器(推荐) ```sh # 为 ArtalkGo 创建一个目录 @@ -65,6 +65,17 @@ $ docker run -d \ - 配置文件路径 `./conf.yml` - 数据文件目录 `./data/` +### Docker 升级 + +```sh +# 暂停并删除正在运行的容器,然后从 DockerHub 拉取最新镜像 +docker stop artalk-go \ + && docker rm artalk-go \ + && docker pull artalk/artalk-go +``` + +之后,重新执行上面创建 Docker 容器步骤即可。 + ## 编译 ### 编译二进制文件 diff --git a/lib/version.go b/lib/version.go index e221c1b9f..60d9bf9fe 100644 --- a/lib/version.go +++ b/lib/version.go @@ -3,5 +3,5 @@ package lib // 版本信息 var ( Version string - LastCommit string + CommitHash string ) diff --git a/makefile b/makefile index 4f02f9b49..4d268e169 100644 --- a/makefile +++ b/makefile @@ -1,34 +1,87 @@ -ifndef VERSION - VERSION := $(shell git describe --tags --abbrev=0) -endif - -COMMIT_HASH := $(shell git rev-parse --short HEAD) -DEV_VERSION := dev-${COMMIT_HASH} +PACKAGE_NAME := github.com/ArtalkJS/ArtalkGo +VERSION ?= $(shell git describe --tags --abbrev=0) +COMMIT_HASH := $(shell git rev-parse --short HEAD) +DEV_VERSION := dev-${COMMIT_HASH} +GO_VERSION ?= 1.16.6 all: install update build +.PHONY: install install: go mod tidy go install github.com/markbates/pkger/cmd/pkger +.PHONY: update update: pkger -include /frontend -include /email-tpl -o pkged +.PHONY: build build: update go build \ - -ldflags "-X github.com/ArtalkJS/ArtalkGo/lib.Version=${VERSION} \ - -X github.com/ArtalkJS/ArtalkGo/lib.LastCommit=${COMMIT_SHA}" \ + -ldflags "-s -w -X github.com/ArtalkJS/ArtalkGo/lib.Version=${VERSION} \ + -X github.com/ArtalkJS/ArtalkGo/lib.CommitHash=${COMMIT_HASH}" \ -o bin/artalk-go \ github.com/ArtalkJS/ArtalkGo +.PHONY: run run: update build - ./bin/artalk-go + ./bin/artalk-go serve $(ARGS) + +.PHONY: dev +dev: + @if [ ! -f "pkged/pkged.go" ]; then \ + make install; \ + make update; \ + fi + @go build \ + -ldflags "-s -w -X github.com/ArtalkJS/ArtalkGo/lib.Version=${VERSION} \ + -X github.com/ArtalkJS/ArtalkGo/lib.CommitHash=${COMMIT_HASH}" \ + -o bin/artalk-go \ + github.com/ArtalkJS/ArtalkGo + ./bin/artalk-go $(ARGS) +.PHONY: test test: update go test -cover github.com/ArtalkJS/ArtalkGo/... +.PHONY: docker-build docker-build: ./scripts/docker-build.sh +.PHONY: docker-push docker-push: ./scripts/docker-build.sh --push + +.PHONY: release-dry-run +release-dry-run: + @docker run \ + --rm \ + --privileged \ + -e CGO_ENABLED=1 \ + -v /var/run/docker.sock:/var/run/docker.sock \ + -v `pwd`:/go/src/$(PACKAGE_NAME) \ + -v `pwd`/sysroot:/sysroot \ + -w /go/src/$(PACKAGE_NAME) \ + troian/golang-cross:v${GO_VERSION} \ + --rm-dist --skip-validate --skip-publish + +.PHONY: release +# https://hub.docker.com/r/troian/golang-cross +# https://goreleaser.com/cmd/goreleaser_release/ +# --skip-validate 参数跳过 git checks (由于 pkger 和 .release-env 文件生成) +release: + @if [ ! -f ".release-env" ]; then \ + echo "\033[91m.release-env is required for release\033[0m";\ + exit 1;\ + fi + docker run \ + --rm \ + --privileged \ + -e CGO_ENABLED=1 \ + --env-file .release-env \ + -v /var/run/docker.sock:/var/run/docker.sock \ + -v `pwd`:/go/src/$(PACKAGE_NAME) \ + -v `pwd`/sysroot:/sysroot \ + -w /go/src/$(PACKAGE_NAME) \ + troian/golang-cross:v${GO_VERSION} \ + release --rm-dist --skip-validate diff --git a/pkged/pkged.go b/pkged/pkged.go deleted file mode 100644 index 7db58c71d..000000000 --- a/pkged/pkged.go +++ /dev/null @@ -1,12 +0,0 @@ -// Code generated by pkger; DO NOT EDIT. - -// +build !skippkger - -package pkged - -import ( - "github.com/markbates/pkger" - "github.com/markbates/pkger/pkging/mem" -) - -var _ = pkger.Apply(mem.UnmarshalEmbed([]byte(`1f8b08000000000000ffec7d596fe3b816e65fb9d06b259125799381fb90a5e3385d592a49c5b12f1a0d8aa224da5c5424e5258dfaef034ab22def0ea6319807a2109be4f9b86fe7d0e743fd636116716975feb162ac922cb8809cda97420132be7f2d035daee53758581dcb7ee724a348da7d2ec6af2980a8049d5f3ef7cebbdc3ab37a34e5423d0395589dc3a59e598f8022ab635180997566dd7068752cebcc7a0322464a57f75322216d944281991d733bc0ac9aff8573755aab1e808289d5f99f7561fd7566bd2a4090d551224365e40501c999d5b1a48efd27442962216270def9cfa13ed890b308c7d699d5e5b79820a9abd0ddb988b9aea8188c3cf5703134d4f01b94e6d8208bb06e753057485a6716e43415484a3b2240a16a42fc89d36a9c7c4eabd14f82833cce14c00c099b60a9ca0434cb43629e2abe0cd8a0a8b088409c2648ace26155184ab08a20b81e0ddd46c3f1b7126ccc14120c101b85532042b9092304a70ac3554a424125b6cc2e000b3385c90e91cc0245d04a40c3c62aa2f35562b05e89543b2013e0acc5dc46732dde70dc4a7ca34a452ae3346bd4fcf5d8aaad1440be01b5d3319e5967560814088044b6fc4536a27628f0249f174403a4fb8318e4216671256803c99c6a5ce76ed6d7523003625e4d8172528d2668568d8ef416a9c45344abd119d50d454270a1fb8466e904e8464604e8864554afb7a3dbe01864b1e10ea212a5d26398626b1c83d888827c991d04521ea2a3a0741ca38dfe3d67488cb1e25798db31ff95a17c3a2a800f0cf803b653140399c9f3989f438211533608697e689e82c521f9325eaf962fc0b766ee205a7cb53502a50443a030ff522e110627c2750ae1f117d032935f43db3c3d318348e1894889a4dc1a1340088a85be2c63086082ec89771460ffca50b631e18085f3009084136a4320210831d8400810869cd9215028056273c504880bd6b25324c6d2fe9501a630d984081046587dda31a78816ad5904d69110b131200adb0180631e45f6a4be09902910c89ecd1220137be2ae8b43c4b0446ccca91df3732ae52fb2b93a76425687354cbf040f11c414902fe5c94f80f266aee68ac55c8eb1ce22b45ef239e19bab0f8df509524ea76bef18c04d040f113c88a048090c0fd72315171bf544927185a3f932b02ecefb106269179f93f611f172704ec5d97afa15884fc74b08d8c9e894f3d39b920a9e2b57a7a14be5e43470a9fdac83e52f725e2807369d178ac31a20c8a208106e276873d6624e008bcf4753658fa66aa74c6b1e104fb6abd5523b1208a979bab3d8a5d01640aa5c733980d16af9de92f2110db268f7d06e407429f2148c0dd8d632dd890b33b1e316da03569822a900dd3837f4fac4908bd44e203920caff8054c720f9c92b8ea244be748ec1f45e6027c094809c4d8ec1141f237608a455ca133a90c34e685a8edb51e908c031b46192b1b140204462eb7a2810690c39db99b790542e03359be636e57eac5454ed38871718cc77a7a740ca68eba25c4af51af3f6365f2231c110edcfbfbdb11692d9d68d5a9554ec2bc0b0c29f074ab1a50ab7b4eb111288cea73c21b915abb6a608b3cf24b3318b0882db5bac14333e5d4f2720900ac0b18d60c2b77ab029b5290e4382a660f3f85b02634e2967f6c2f23e00819c707118b2a5516e02f489cfe93a86821843ce0016fa4049915078b329148871001492b94d210e0a779cf59b888a399a1eae497f1666e6518cbdb04d8f2329da1a829d38a942bed53ea598bef9f2d900c1e6b25fcab1044acdf708e52f8215f2b6a52a153c0bcbf3fdefc5f9fe379a29c4b4e22ded34d8be88699ca94f1b308937d2b182092224c9075a890caa6c736e381378ac178ec864be6ad7c50b13603cb1552270a4721b35e6656c134c08521809dd47c5e9463353c1295209caa45d98137fafeeb152f0e50c7bb4b55372ea20c836eff4ed9cb9ad6dc70770c5de42b374ebc9611bb55cfb01564106c7485d7011dbd3a91d73dd1a86e26345ec30fed7bb05a3fd03598857cdf802747be1fd9afed26abd9e6e40f03c63e73b5e2f048e22c2e1d826914c381faf4b2516592a112b97e086308d1ccf0611127caf607b371742b8a5c994e93c10609760340544213145402548d04d15bd00a5e5e3d2966082d3cd83512a046800521b8254c164b3d22ce0122b6ddd28b4a9d94c00990302f26b41ebd0486c9b010b4c04a45288a6e5536d05313b8702cccb913d4f058af00c85e71117faacd96cee3ccbdfbc49a84fc303a26d15715dbc3cac4e021d2b6d97aeb68ec82d54711ac64ed4e6a9b40edcb685d7e58b3dc02f788a98420469ab757e81b9cd153a24b281520207593149fb407a3bc94380ea79770c6307208e417cb0c22536263c38b15825004436e3c503d33e7861ce1f479c50730964190d8a793e021428c652156f9bfba05ad701f1d2b8da07cbfb7a0890319caf18be58c9bc6a38f09575905f40f9613fb3173f7e408a0e886c7d214024d41e0c0deb7b2469300e23778f50cac4564850bc58461508a6204676c4d9569d85840295d8f931b22967482d77d7ae741ba842f3dc16aa34ff883325f701b6fab214d8890b0f085300c7bbc4386460335dceabb71d932042496ebded02662cffd9642d5d8fea76da4ce9cb086df52d97acede77d425b0bb2c54e3e8ad28a420ae0d614aea3cb27ab2dc0c1ba44c6f67444229809640738c42223bb7397985420887797a20460525f503ba519c3b9bea12b390860fb4a98e250255b124c912dcaeb93f398a08b8a7cf9cab2fa1d4aa72c6e8a53f1532c8e945f79c995b054254f44f3b4dc3aa7c0d5e2ddef04f4b20f218a26e52afd422e8aa4043192e8d4ce2c732e56e757b21c9d91559ec58f86a780234c901ee42fc017af1ea7c009884f6d498c183e75e6304d4f9d2e2e1667dc716c2a404cc189e0d3e75daa93a76382c442bbdc8f5ebed6ee870894bffc1409c7e7770d5e46be94a3a292eccf92b1fc30ca1370b4503d4ec41f9df1f24d19492870aab8488353f063c6a7cc066cfe15f8e2e1fa2b7996efd765a6741c5fe4cab7362a2f8a27c8452266f862e25453185028c20c2636c9f5c41180e38d4c8ad36023690ee8b26841b556b7f97bc67a72caa58a457907ae498a479d9de9128949b9c30a51bcb89f56511b02420200c7724b404026d1662ae171bc55a64d712c80e25be91226a8dcb695546dcde8ea122093f2cb062141c273175128e05a24f7e8c823516eb4962a5faee155acd05c5b5c7c2f9f2e2b313b0504a915d60e05982e23318e96e1ca890662541a60856894e6af254524cddf0957b6cf5c2140d692609a55a3115592e7caf5328921b550f857a7a3cc6f8b6a52ca09a9c637b3943bbf5c0fab430eb398a088e03859ab55cea59e7c1bcd102c9e02b644a5b6b952de9054c56bef3e85357feec7bc78e0c1dcc6bc1cba715bea0500524c014c3043626ea7e3385f0cab8bf1204aa25cdd281aa04d82f2cb0e70bc0ae6983c5c2a1c14e7e68efeb26946144e413efc79c2af8c2b14e6bf1a95cfaa2cbf3d16ba7c25987f2ce6692db1ece232ada25debb4f2714a07255d16a9f586c57da1e399d0a0fce597cb7c528a50563c44a4457fd3c21222a88cafae048162344b97015bce99027af6cad37a15b261feacb8888528c8e24a7c39b5da74ca4de92d4939f85be972ae9b5f2eefd58f675209cc727543ce192cbf56c597abcd3ab30a651c0453818b87a22261b5c1d7e2f6c219a3ec5ea986af4276a622a7b91e6fe751bd66ad336b8258c885bdcb5c85098009706ba7a1524ee68e576b1c41e75ffa883815b7706f3b04cec4042d1c0c0fe09271181d466cfb161e001fe9b15ed12193faafd4c60f00376df1a3b854f0d9fc08706585ef4395c6f83eb1e0d9de89d2a67871aeef92eeb14cf742abe6e75ed086157a14971ba37f9d596f48aaa5db2ecb082992963ebb45d2030f75233bff58a7f9343f00cc16aec5273b4d77f9030f4f80da31bfa03ccc73bc977a77c7722e9ca6f5fbf7ef332b2a3a73d89dbb53f8349eab9468286651eee11d2205b4fad1f9c762855ff60a766649fc89ac8edf3cb3a83e493aae536fd5db75a7eee4297fe7274dc7726bae73eed4ce1de7ad56ebd4fc4ea371d1f2eaad5abbe63bdf6aed4e4d9f1b58fe1deaa12946499f8d9d7fac1b34b13a4eb3d56ab96e3d1f77a4e3ed56ebcc7a24988dad8e7766f518b73acda6e3d49c33eb270ead4e4387ba3ad4ae9d592fa12ea676663d83f06f18f3bf6b56e77fb5b3fcdf5f67d665aed3a608ea1a5ff597d3f4bc76db7574d71e659ee2794dc7abd79ddf67d6c37e7c63815ff6eff79975fd45fc15162ad991c7f55bbed7aab51679ea35cff3ea4ed3ff7d66bd2ea7e28a70ad9feaee5e91713145f59a96dce656ac167411cbbfbfe7de7179f04719d4e3f257be6e12248c93ffbe3e18277fe3e46f9cfc8d93bf71f2374efec6c9df38f91b277fe3e46f9cfcf70b8d93bf71f2374efec6c9df38f91b277fe3e46f9cfc8d93bf71f2374efec6c97f2fd038f91b277fe3e46f9cfc8d93bf71f2374efec6c9df38f91b277fe3e46f9cfc8d93bf71f2374efec6c9df38f91b277fe3e46f9cfc8d93ffefdfe551a85b3a8e4f76beae78fcff2edc4c173d4f81404cadca5be5c92b3b547c8547a02d55901175916b260749056bc825afc06f2d880575b7b69351e03a6f8edff1fc4ead7dd1aa35dd9ad36eb95b8c820810798452e0794ebbbda4143825a5a0e5b7db4efb5fa314d4db4ed36bba0bf77dbfe934da5ebbe9eea314e4f87a7b49115874701fa5e0007e1fa560070da1e9d7fd86b3a214e85958700adaff4f39057690bb8aaef10a564b31d8431d58b10356deffc5b22e9dffcbe5b0eefd5f75e42fd01ba741e1a1bf3a2cccf9b16fa72f0f13eb7a341b838f410cbd9746d0fde9f7d85532ecbea40185cddecdfb145d5f4e9fe6bd6fd7f832ee5d5fb6e1f5d5677847e4f0ad8683feed7ce892ec7b7f4686ec47b377f3c714dec5ad21f5b3f0daf9041f2979c297b3477655d765bc76c7b277a75a012523e0397eab3507cfd7fef439e6baecf8f9ee72d50eea24908669801d39ec0f6b4ff872fe70579453b625ff6bf03f796338e7bda73f2fd99d6ac1ee2d1bbefb35f0f122871f8e5fe7d761ef09fc5459bf279f5e9b49d60f58d61f8fd0b7365dd45b6d43f7250df1aa8f037a3b026e380fbcf76c78c347437a4f0774889fbcd5383dbce5e354b4cf1d4e02f643419734876f7cf694a7dd4f207d2170d197d1e3145d5f7d06ee2c1d5e5f8e1e6e2eeb0fee903eb9cb3ed702efb2f9f0164ed18dc48bb6e57f371bf345d7ea8b1fde86459ef1550b79f70476678d0fb7910e5ce5476fbcfddd7d49c351fdcf6579d797ed6197b8cf4cb5207d9f0677241ab87e1676dfb3f0cef19faf7d5ddf72fed7f2dfcca6bdbbc71aeacfc8f3ebbd1a7cdc33d0afab01f56b61d7574fa39ea3d7c3be75d21bd5db83d72b0ee93b7d7ebd6f21779606544561d78fcab6f8d16b2f0ebb3aff7bedf9f53e1ad0591250892bf58ec1c7e334e8de369e28c9822ec986af0e0ebafe087caae9a0ff3206fd067bc297ba2df1c3e86a8a6ed42870671338e271eff372fa74f34887238507fd4731f4ee2761bf317ec297a321d573b29cbbf9a0ff92861f0fcddecd8fbcfd03eacf87ddf7b95e9bba6ce8fa12f47f54cbac0d3f92daf7fe0b19b8fe7cf0f192066ebd19503f1bbea9e578855d7ffa342ac704f7be35becfe3e6e0faaa3944bc773dcc06ec71fad4feb3f57ced27cfa3e904deec1cffb2ae5b09fa61f684afe6a01ff270adafd079747f361e2a75434a18b85b9b13f5fdf5727d5ebcc734ecbe47e1c7bd8c3e6ab877f7a2d729096f6af8c3bd97837e43f4aa7bc6f565e0f59abdeb87e9c34dfc39a48356d87daf87d7ce78d87f9c407a5b037d3f7ba28d49407fb67aa3c6b28e80de2abd6f8bbece30c49793e7d1ec13766fb34a5f69e0366adf3f1e53447feab6bb45db1b3f022f2490be8f7b7fdc377a7fdccec3eead049f5bf9abf3ef0efaf7e3c74fbd67c2c9f3b59f63f371f6ae9260546f7ff72ebf5d8fa6937c9fc4fffdaff57fa97e45823385587858e15aa2be46e2acf9e78ef3e6d63a0dafe37a1775dfa9b75cafedfd6b24ce96d7a83bf57f4de372bc66bd5df316da4db3e1d5fc46b35ddba7716de097fddba7711dc0efd5b8b6f378f57ab3d930244e43e234244e43e234244e43e234244e43e23424ceaad890380d89d390380d89d390380fc20c89d3903877490c89d390380d89d390380d89d390380d89d39038f7230c89d390380d89d390380d89d390380d89d390380d89d390380d89d390380d89d390380d89d390380d89d390380d89d390380d89f3ff0f12d6d293ffdfe4702e0ab5310bd1ec04026705b76014786df7287db3f6e6d43b75bfe3352e1a2db7d56ab6fdf6bf48dff41a75a7f1efd1375b5ea351f397ff2354d36bb7dda6bff77f84aab71cb7d15a522b971ddc4bdfdc8fff0299a0de741a8dd5ff0895cf82a16f1afae6fe93a3bac957dccde7ebdb3fde6a8f3ffbef57b7bd6e520bfad36fd7a3190fbb8e7c8e791b74df93e18a2ba6861f2f49affbc8071ff79fc38f1f7e8fbcff7cc1b57a6fc5e72b78936f8d8f617f360a5c87f4ee5e264b1e552d9cf4dea693b04b6a41f767ce895ad4f1dcbd9f0cefc6151ee90b41773fd4a03f4b876ebdd9eb3e9280bd10385af1199fbbf1fc998424e83e4e82fecf38ecb6e31f1ff7b5417f269eef1ea7837ebdc2737c9c045d7ffe842f470f37c364407f784ff3deb717b7ddfeeee5d86fba6de0a6c255bd697403af17076e43827e83f4ba2f9381f7ae86fd46ade4e2c5837e63dcbb7b74e0ddd504b21f31eccec8e0e391f4eeeec990becff3fedfcc925e37990ffb03bf47935a7877f5f984db9341d9d6ef34fdfc4efdf970defbb695f6399d0cdeead906cff5db7b3749022a63d4f79d5e773881f8ca812ec986f3ab2bc85e92a0abee82f98a7b36a0fe18bdd5ff7cbef6cbf93dce432b4e0364c845fbfa60c845865c64c845865c64c845865c64c845865c64c845865c64c845fb85865c64c845865c64c845865c64c845865c64c845865c64c845865c64c8457b81865c64c845865c64c845865c64c845865c64c845865c64c845865c64c845865c64c845865c64c845865c64c845865c64c845865cf4fbf7efff030000ffff010000ffff50a73adfd6cb0000`))) From c10316cbc6308a61c09ba49f6cf13966b98de711 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Fri, 22 Oct 2021 19:18:50 +0800 Subject: [PATCH 072/349] fix: github actions image cache Signed-off-by: qwqcode --- .github/workflows/release.yml | 23 ++++++++++++---------- .gitignore | 2 +- .goreleaser.yml | 1 + README.md | 36 ++++++++++++++++++----------------- http/a_http.go | 10 ++++++++++ 5 files changed, 44 insertions(+), 28 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 5b5c3d6ef..9cf7cea50 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -8,6 +8,7 @@ on: jobs: release: runs-on: ubuntu-latest + steps: - name: checkout code uses: actions/checkout@v2 @@ -19,28 +20,30 @@ jobs: go-version: '^1.16.6' # docker `golang-cross` image cache - - run: mkdir -p ~/image-cache + # `cache-go-cross-v1-16-6` + - run: mkdir -p ~/docker-cache - name: docker image cache - id: image-cache - uses: actions/cache@v1 + id: cache-go-cross-v1-16-6 + uses: actions/cache@v2 with: - path: ~/image-cache + path: ~/docker-cache # Adjust key to meet your cache time requirements e.g. # ${{ hashFiles(*) }} can be useful here to invalidate # cache on file changes - key: image-cache-golang-cross + key: cache-go-cross-v1-16-6 - - if: steps.image-cache.outputs.cache-hit != 'true' + - if: steps.cache-go-cross-v1-16-6.outputs.cache-hit != 'true' run: | - docker pull troian/golang-cross - docker save -o ~/image-cache/golang-cross.tar troian/golang-cross + docker pull troian/golang-cross:v1.16.6 + docker save -o ~/docker-cache/golang-cross.tar troian/golang-cross:v1.16.6 - - if: steps.image-cache.outputs.cache-hit == 'true' - run: docker load -i ~/image-cache/golang-cross.tar + - if: steps.cache-go-cross-v1-16-6.outputs.cache-hit == 'true' + run: docker load -i ~/docker-cache/golang-cross.tar # build - name: setup release environment run: |- + cp artalk-go.example.yml artalk-go.yml echo 'GITHUB_TOKEN=${{secrets.GORELEASER_ACCESS_TOKEN}}' > .release-env - name: build and release publish diff --git a/.gitignore b/.gitignore index 3da070771..1dd172710 100644 --- a/.gitignore +++ b/.gitignore @@ -16,10 +16,10 @@ artalk-go.yml config.yml +.release-env local/ bin/ data/ - dist/ pkged/pkged.go diff --git a/.goreleaser.yml b/.goreleaser.yml index ad64d7c80..fc546885d 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -123,6 +123,7 @@ archives: files: - README* - LICENSE* + - artalk-go.yml checksum: name_template: 'checksums.txt' diff --git a/README.md b/README.md index 476286930..8f3061504 100644 --- a/README.md +++ b/README.md @@ -17,19 +17,28 @@ - 多站点支持 - 多数据库类型支持 +## Supports + +- 跨平台:支持 Linux, Win, Darwin +- 数据存储:支持 SQLite, MySQL, PostgreSQL, SQL Server +- 邮件发送:支持 SMTP, 阿里云邮件, 系统调用 sendmail 等发送邮件 +- 高效缓存:支持 Redis, Memory cache + ## 部署方针 ### 普通方式 1. 前往 [Release](https://github.com/ArtalkJS/ArtalkGo/releases) 下载已编译二进制文件 -2. 编辑配置文件 - ```sh - $ curl -L https://raw.githubusercontent.com/ArtalkJS/ArtalkGo/main/artalk-go.example.yml > artalk-go.yml - $ vim artalk-go.yml - ``` -3. 运行程序 `./artalk-go serve` -4. 反代设定的端口到 80 并套上 CDN (Nginx, Apache) -5. 持久化运作 artalk-go 程序 (tmux, sysctl) +2. 解压程序 `tar -zxvf artalk-go.tar.gz` +3. 编辑配置 `vim artalk-go.yml` +4. 运行程序 `./artalk-go serve` +5. 反代设定的端口到 80 并套上 CDN (Nginx, Apache) +6. 持久化运作 artalk-go 程序 (tmux, sysctl) +7. 前端配置 + + ```js + new Artalk({ server: "http://your_domain:端口号/api" }) + ``` ### Docker 容器(推荐) @@ -56,10 +65,10 @@ $ docker run -d \ artalk/artalk-go ``` -- 前端访问地址 `http://localhost:8080/api` +- 前端配置地址 `http://your_domain:8080/api` ```js - new Artalk({ server: "http://localhost:8080/api" }) + new Artalk({ server: "http://your_domain:8080/api" }) ``` - 配置文件路径 `./conf.yml` @@ -96,13 +105,6 @@ $ make docker-docker $ make docker-push ``` -## Supports - -- 跨平台:支持 Linux, Win, Darwin -- 数据存储:支持 SQLite, MySQL, PostgreSQL, SQL Server... -- 高效缓存:支持 Redis, Memory... -- 邮件发送:支持 SMTP, 阿里云邮件, 系统调用 sendmail 等发送邮件 - ## TODOs - [ ] 命令行管理 diff --git a/http/a_http.go b/http/a_http.go index 2b3627238..f2a2b6d5b 100644 --- a/http/a_http.go +++ b/http/a_http.go @@ -6,6 +6,7 @@ import ( "strings" "github.com/ArtalkJS/ArtalkGo/config" + "github.com/ArtalkJS/ArtalkGo/lib" "github.com/ArtalkJS/ArtalkGo/pkged" "github.com/labstack/echo/v4" "github.com/labstack/echo/v4/middleware" @@ -117,4 +118,13 @@ func InitRoute(e *echo.Echo) { admin.POST("/vote-sync", ActionAdminVoteSync) admin.POST("/send-mail", ActionAdminSendMail) + + // version + api.Any("/version", func(c echo.Context) error { + return c.JSON(200, Map{ + "app": "artalk-go", + "version": lib.Version, + "commit_hash": lib.CommitHash, + }) + }) } From 93d07d9b69cb3bcad704c5ec3e9bcb533149600c Mon Sep 17 00:00:00 2001 From: qwqcode Date: Sat, 23 Oct 2021 07:54:32 +0800 Subject: [PATCH 073/349] feat: Add robots.txt. Signed-off-by: qwqcode --- frontend/robots.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 frontend/robots.txt diff --git a/frontend/robots.txt b/frontend/robots.txt new file mode 100644 index 000000000..3f6899136 --- /dev/null +++ b/frontend/robots.txt @@ -0,0 +1,2 @@ +User-agent: * +Disallow: / From 9a34bcb02386892b8ab0a012b8ec616c9a7df6f9 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Mon, 25 Oct 2021 23:48:07 +0800 Subject: [PATCH 074/349] feat: Typecho Impoter. --- .github/workflows/dockerhub.yml | 10 +- artalk-go.example.yml | 1 - cmd/import.go | 43 +++++ cmd/root.go | 8 +- config/config.go | 10 +- http/api_admin_importer.go | 23 ++- lib/db.go | 64 ++++--- lib/importer/importer.go | 214 +++++++++++++++++++++ lib/importer/typecho.go | 322 ++++++++++++++++++++++++++++++++ lib/importer/wordpress.go | 15 ++ 10 files changed, 660 insertions(+), 50 deletions(-) create mode 100644 cmd/import.go create mode 100644 lib/importer/importer.go create mode 100644 lib/importer/typecho.go create mode 100644 lib/importer/wordpress.go diff --git a/.github/workflows/dockerhub.yml b/.github/workflows/dockerhub.yml index 3c3f7ee34..3a9d6af3f 100644 --- a/.github/workflows/dockerhub.yml +++ b/.github/workflows/dockerhub.yml @@ -2,13 +2,13 @@ name: CI to Docker Hub on: push: - branches: - - "master" + # branches: + # - "master" tags: - "v*" - pull_request: - branches: - - "master" + # pull_request: + # branches: + # - "master" jobs: docker: diff --git a/artalk-go.example.yml b/artalk-go.example.yml index 50663ea70..2cd89a17f 100644 --- a/artalk-go.example.yml +++ b/artalk-go.example.yml @@ -79,4 +79,3 @@ email: access_key_id: "" # 阿里云颁发给用户的访问服务所用的密钥 ID access_key_secret: "" # 用于加密的密钥 account_name: "example@example.com" # 管理控制台中配置的发信地址 - diff --git a/cmd/import.go b/cmd/import.go new file mode 100644 index 000000000..1484b7275 --- /dev/null +++ b/cmd/import.go @@ -0,0 +1,43 @@ +package cmd + +import ( + "strings" + + "github.com/ArtalkJS/ArtalkGo/lib/importer" + "github.com/sirupsen/logrus" + "github.com/spf13/cobra" +) + +var importCmd = &cobra.Command{ + Use: "import", + Version: rootCmd.Version, + Aliases: []string{}, + Short: "数据导入", + Long: rootCmd.Long, + Run: func(cmd *cobra.Command, args []string) { + dataType, _ := cmd.Flags().GetString("type") + if strings.TrimSpace(dataType) == "" { + logrus.Fatal("请指定参数 `--type`,帮助文档加 `-h`") + } + + isSupport := false + for _, t := range importer.GetSupportTypes() { + if strings.EqualFold(t, dataType) { + isSupport = true + } + } + + if !isSupport { + logrus.Fatal("不支持该数据类型") + } + + importer.RunByName(dataType, args) + }, +} + +func init() { + rootCmd.AddCommand(importCmd) + + flagPV(importCmd, "type", "", "", "数据类型 ["+strings.Join(importer.GetSupportTypes(), ",")+"]") + flagPV(importCmd, "port", "", 23366, "监听端口") +} diff --git a/cmd/root.go b/cmd/root.go index aa315777f..24faf080a 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -14,6 +14,7 @@ import ( "github.com/sirupsen/logrus" "github.com/spf13/cobra" prefixed "github.com/x-cray/logrus-prefixed-formatter" + "gorm.io/gorm" ) var Banner = ` @@ -65,13 +66,11 @@ func initConfig() { // 检查 app_key 是否设置 if strings.TrimSpace(config.Instance.AppKey) == "" { logrus.Fatal("请检查配置文件,并设置一个 app_key (任意字符串) 用于数据加密") - os.Exit(1) } // 设置时区 if strings.TrimSpace(config.Instance.TimeZone) == "" { logrus.Fatal("请检查配置文件,并设置 timezone") - os.Exit(1) } denverLoc, _ := time.LoadLocation(config.Instance.TimeZone) time.Local = denverLoc @@ -124,12 +123,15 @@ func initLog() { // 3. 初始化数据库 func initDB() { - err := lib.OpenDB() + var db *gorm.DB + db, err := lib.OpenDB(config.DBType(config.Instance.DB.Type), config.Instance.DB.Dsn) if err != nil { logrus.Error("数据库初始化发生错误 ", err) os.Exit(1) } + lib.DB = db + // Migrate the schema lib.DB.AutoMigrate(&model.Site{}, &model.Page{}, &model.User{}, &model.Comment{}, &model.Notify{}, &model.Vote{}) // 注意表的创建顺序,因为有关联字段 } diff --git a/config/config.go b/config/config.go index bcc4bd651..0642be9c2 100644 --- a/config/config.go +++ b/config/config.go @@ -24,11 +24,11 @@ type Config struct { AllowOrigins []string `mapstructure:"allow_origins" json:"allow_origins"` // 允许跨域访问的域名 SSL SSLConf `mapstructure:"ssl" json:"ssl"` // SSL SiteDefault string `mapstructure:"site_default" json:"site_default"` // 默认站点名(当请求无指定 site_name 时使用) - AdminUsers []AdminUserConf `mapstructure:"admin_users" json:"admin_users"` - LoginTimeout int `mapstructure:"login_timeout" json:"login_timeout"` - Moderator ModeratorConf `mapstructure:"moderator" json:"moderator"` - Captcha CaptchaConf `mapstructure:"captcha" json:"captcha"` - Email EmailConf `mapstructure:"email" json:"email"` + AdminUsers []AdminUserConf `mapstructure:"admin_users" json:"admin_users"` // 管理员账户 + LoginTimeout int `mapstructure:"login_timeout" json:"login_timeout"` // 登陆超时 + Moderator ModeratorConf `mapstructure:"moderator" json:"moderator"` // 评论审查 + Captcha CaptchaConf `mapstructure:"captcha" json:"captcha"` // 验证码 + Email EmailConf `mapstructure:"email" json:"email"` // 邮箱提醒 } type DBConf struct { diff --git a/http/api_admin_importer.go b/http/api_admin_importer.go index e687ac149..8b86249f0 100644 --- a/http/api_admin_importer.go +++ b/http/api_admin_importer.go @@ -79,9 +79,9 @@ func ActionAdminImporter(c echo.Context) error { page := model.FindCreatePage(oc.PageKey, "", p.SiteName) user := model.FindCreateUser(oc.Nick, oc.Email) - user.Link = oc.Link - user.LastIP = oc.IP - user.LastUA = oc.UA + if oc.Link != "" { + user.Link = oc.Link + } model.UpdateUser(&user) // 创建新 comment 实例 @@ -116,16 +116,15 @@ func ActionAdminImporter(c echo.Context) error { } // reply id 重建 - for _, oc := range v1Comments { - if oc.Rid != 0 { - if _, isExist := idChanges[oc.ID]; !isExist { - continue - } - - nComment := model.FindComment(idChanges[oc.ID], p.SiteName) - nComment.Rid = idChanges[oc.Rid] + for _, newId := range idChanges { + nComment := model.FindComment(newId, p.SiteName) + if nComment.Rid == 0 { + continue + } + if newId, isExist := idChanges[nComment.Rid]; isExist { + nComment.Rid = newId err := lib.DB.Save(&nComment).Error - dbResultLog(fmt.Sprintf("rid 更新 new_id:%d new_rid:%d", nComment.ID, idChanges[oc.Rid]), err) + dbResultLog(fmt.Sprintf("rid 更新 new_id:%d new_rid:%d", nComment.ID, newId), err) } } default: diff --git a/lib/db.go b/lib/db.go index 19e24c21d..d08edd413 100644 --- a/lib/db.go +++ b/lib/db.go @@ -1,7 +1,10 @@ package lib import ( + "errors" + "fmt" "path/filepath" + "strconv" "github.com/ArtalkJS/ArtalkGo/config" "gorm.io/driver/mysql" @@ -17,41 +20,54 @@ var gormConfig = &gorm.Config{ Logger: NewGormLogger(), } -func OpenDB() (err error) { - switch config.Instance.DB.Type { - case config.TypeMySql: - err = OpenMySql() +func OpenDB(dbType config.DBType, dsn string) (*gorm.DB, error) { + switch dbType { case config.TypeSQLite: - err = OpenSQLite() + return OpenSQLite(dsn) + case config.TypeMySql: + return OpenMySql(dsn) case config.TypePostgreSQL: - err = OpenPostgreSQL() + return OpenPostgreSQL(dsn) case config.TypeSqlServer: - err = OpenSqlServer() + return OpenSqlServer(dsn) } - return -} - -func OpenMySql() (err error) { - DB, err = gorm.Open(mysql.Open(config.Instance.DB.Dsn), gormConfig) - return + return nil, errors.New(`不支持的数据库类型 "` + string(dbType) + `"`) } -func OpenSQLite() (err error) { - filename := config.Instance.DB.Dsn +func OpenSQLite(filename string) (*gorm.DB, error) { if err := EnsureDir(filepath.Dir(filename)); err != nil { - return err + return nil, err } - DB, err = gorm.Open(sqlite.Open(filename), gormConfig) - return + return gorm.Open(sqlite.Open(filename), gormConfig) +} + +func OpenMySql(dsn string) (*gorm.DB, error) { + return gorm.Open(mysql.Open(dsn), gormConfig) +} + +func OpenPostgreSQL(dsn string) (*gorm.DB, error) { + return gorm.Open(postgres.Open(dsn), &gorm.Config{}) } -func OpenPostgreSQL() (err error) { - DB, err = gorm.Open(postgres.Open(config.Instance.DB.Dsn), &gorm.Config{}) - return +func OpenSqlServer(dsn string) (*gorm.DB, error) { + return gorm.Open(sqlserver.Open(dsn), &gorm.Config{}) } -func OpenSqlServer() (err error) { - DB, err = gorm.Open(sqlserver.Open(config.Instance.DB.Dsn), &gorm.Config{}) - return +func GetDsn(dbType config.DBType, host string, portStr string, dbName string, user string, password string) (string, error) { + port, err := strconv.Atoi(portStr) + if err != nil { + return "", errors.New("port 值有误") + } + + switch dbType { + case config.TypeMySql: + return fmt.Sprintf("%s:%s@tcp(%s:%d)/%s", user, password, host, port, dbName), nil + case config.TypePostgreSQL: + return fmt.Sprintf("host=%s port=%d user=%s password=%s dbname=%s", host, port, user, password, dbName), nil + case config.TypeSqlServer: + return fmt.Sprintf("sqlserver://%s:%s@%s:%d?database=%s", user, password, host, port, dbName), nil + } + + return "", errors.New(`不支持的数据库类型 "` + string(dbType) + `"`) } diff --git a/lib/importer/importer.go b/lib/importer/importer.go new file mode 100644 index 000000000..96a85d6f6 --- /dev/null +++ b/lib/importer/importer.go @@ -0,0 +1,214 @@ +package importer + +import ( + "fmt" + "reflect" + "strconv" + "strings" + "time" + + "github.com/ArtalkJS/ArtalkGo/config" + "github.com/ArtalkJS/ArtalkGo/lib" + "github.com/ArtalkJS/ArtalkGo/model" + "github.com/araddon/dateparse" + "github.com/sirupsen/logrus" + "gorm.io/gorm" +) + +type Map = map[string]interface{} + +type Importer struct { + Name string + Desc string + Run func(basic BasicParams, payload []string) +} + +var Supports = []interface{}{ + TypechoImporter, + WordPressImporter, +} + +func GetSupportTypes() []string { + types := []string{} + for _, i := range Supports { + r := reflect.ValueOf(i) + f := reflect.Indirect(r).FieldByName("Name") + types = append(types, f.String()) + } + + return types +} + +func RunByName(dataType string, payload []string) { + basic := GetBasicParamsFrom(payload) + for _, i := range Supports { + r := reflect.ValueOf(i) + name := reflect.Indirect(r).FieldByName("Name").String() + desc := reflect.Indirect(r).FieldByName("Desc").String() + if strings.EqualFold(name, dataType) { + fmt.Print("\n* * *\n\n") + fmt.Print(" [数据导入] " + name + "\n\n") + logrus.Info(desc) + fmt.Print("\n* * *\n\n") + + t1 := time.Now() + r.MethodByName("Run").Call([]reflect.Value{ + reflect.ValueOf(basic), + reflect.ValueOf(payload), + }) + elapsed := time.Since(t1) + fmt.Print("\n") + logrus.Info("导出执行结束,耗时: ", elapsed) + } + } +} + +type _getParamsTo struct { + To func(variables map[string]*string) +} + +func GetParamsFrom(payload []string) _getParamsTo { + a := _getParamsTo{} + a.To = func(variables map[string]*string) { + for _, pVal := range payload { + for fromName, toVar := range variables { + if !strings.HasPrefix(pVal, fromName+":") { + continue + } + + *toVar = strings.TrimPrefix(pVal, fromName+":") + break + } + } + } + return a +} + +type BasicParams struct { + TargetSiteName string `json:"target_site_name"` + TargetSiteUrl string `json:"target_site_url"` +} + +func GetBasicParamsFrom(payload []string) BasicParams { + basic := BasicParams{} + GetParamsFrom(payload).To(map[string]*string{ + "target_site_name": &basic.TargetSiteName, + "target_site_url": &basic.TargetSiteUrl, + }) + + if basic.TargetSiteName == "" { + logrus.Fatal("参数 `target_site_name:<站点名称>` 不能为空") + } + if basic.TargetSiteUrl == "" { + logrus.Fatal("参数 `target_site_url:<站点根目录 URL>` 不能为空") + } + if !lib.ValidateURL(basic.TargetSiteUrl) { + logrus.Fatal("参数 `target_site_url:<站点根目录 URL>` 必须为 URL 格式") + } + + return basic +} + +func DbReady(payload []string) *gorm.DB { + var host, port, dbName, user, password, dbType, dbFile string + GetParamsFrom(payload).To(map[string]*string{ + "host": &host, + "port": &port, + "db_name": &dbName, + "user": &user, + "password": &password, + "db_type": &dbType, + "db_file": &dbFile, + }) + + if dbType == "" { + dbType = string(config.TypeMySql) + } + + // sqlite + if strings.EqualFold(dbType, string(config.TypeSQLite)) { + if dbFile == "" { + logrus.Fatal("SQLite 数据库:请传递参数 `db_file` 指定数据文件路径") + } + + db, err := lib.OpenSQLite(dbFile) + if err != nil { + logrus.Fatal("SQLite 打开失败 ", err) + } + return db + } + + dsn, err := lib.GetDsn(config.DBType(dbType), host, port, dbName, user, password) + if err != nil { + logrus.Fatal("数据库连接 DSN 生成错误 ", err) + } + + db, err := lib.OpenDB(config.DBType(dbType), dsn) + if err != nil { + logrus.Fatal("数据库连接失败 ", err) + } + return db +} + +// 站点准备 +func SiteReady(basic BasicParams) model.Site { + site := model.FindSite(basic.TargetSiteName) + if site.IsEmpty() { + // 创建新站点 + site = model.Site{} + site.Name = basic.TargetSiteName + site.Urls = basic.TargetSiteUrl + err := lib.DB.Create(&site).Error + if err != nil { + logrus.Fatal("站点创建失败") + } + } else { + sic := site.ToCooked() + + // 加 URL + urlExist := false + for _, url := range sic.Urls { + if url == site.Urls { + urlExist = true + break + } + } + + if !urlExist { + urls := []string{} + urls = append(urls, basic.TargetSiteUrl) // prepend + urls = append(urls, sic.Urls...) + site.Urls = strings.Join(urls, ",") + err := lib.DB.Save(&site).Error + if err != nil { + logrus.Fatal("站点数据更新失败") + } + } + } + + return site +} + +func ParseVersion(s string) int64 { + strList := strings.Split(s, ".") + format := fmt.Sprintf("%%s%%0%ds", len(strList)) + v := "" + for _, value := range strList { + v = fmt.Sprintf(format, v, value) + } + var result int64 + var err error + if result, err = strconv.ParseInt(v, 10, 64); err != nil { + logrus.Error("ugh: parseVersion(%s): error=%s", s, err) + return 0 + } + return result +} + +func ParseDate(s string) time.Time { + denverLoc, _ := time.LoadLocation(config.Instance.TimeZone) // 时区 + time.Local = denverLoc + t, _ := dateparse.ParseIn(s, denverLoc) + + return t +} diff --git a/lib/importer/typecho.go b/lib/importer/typecho.go new file mode 100644 index 000000000..521304132 --- /dev/null +++ b/lib/importer/typecho.go @@ -0,0 +1,322 @@ +package importer + +import ( + "fmt" + "regexp" + "strings" + + "github.com/ArtalkJS/ArtalkGo/lib" + "github.com/ArtalkJS/ArtalkGo/model" + "github.com/sirupsen/logrus" +) + +const ( + // 已测试可用版本 + TypechoTestedVerMain = "1.1" + TypechoTestedVerSub = "17.10.30" +) + +var TypechoImporter = &_TypechoImporter{ + Importer: Importer{ + Name: "Typecho", + Desc: fmt.Sprintf("测试兼容:Typecho %s/%s", TypechoTestedVerMain, TypechoTestedVerSub), + }, +} + +type _TypechoImporter struct { + Importer + TargetSite model.Site + + Basic BasicParams + SrcVersion string + SrcSiteName string + SrcSiteURL string + Comments []TypechoComment + Options []TypechoOption + Contents []TypechoContent + Metas []TypechoMeta + Relationships []TypechoRelationship + + DbPrefix string + + RewriteRulePost string + RewriteRulePage string +} + +// Typecho 升级相关的代码 @see https://github.com/typecho/typecho/blob/64b8e686885d8ab4c7f0cdc3d6dc2d99fa48537c/var/Utils/Upgrade.php +// 路由 @see https://github.com/typecho/typecho/blob/530312443142577509df88ce88cf3274fac9b8c4/var/Widget/Options/Permalink.php#L319 +func (imp *_TypechoImporter) Run(basic BasicParams, payload []string) { + // Ready + imp.Basic = basic + typechoDB := DbReady(payload) + imp.TargetSite = SiteReady(basic) + + GetParamsFrom(payload).To(map[string]*string{ + "prefix": &imp.DbPrefix, + "rewrite_rule_post": &imp.RewriteRulePost, + "rewrite_rule_page": &imp.RewriteRulePage, + }) + + if imp.DbPrefix == "" { + imp.DbPrefix = "typecho_" + } + + // Load Options + typechoDB.Raw(fmt.Sprintf("SELECT * FROM %soptions", imp.DbPrefix)).Scan(&imp.Options) + + for _, opt := range imp.Options { + switch opt.Name { + case "generator": + imp.SrcVersion = opt.Value + case "title": + imp.SrcSiteName = opt.Value + case "siteUrl": + imp.SrcSiteURL = opt.Value + } + } + + fmt.Printf("- 源版本:%#v\n", imp.SrcVersion) + fmt.Printf("- 源站点名:%#v\n", imp.SrcSiteName) + fmt.Printf("- 源站点URL:%#v\n", imp.SrcSiteURL) + + imp.CheckVersion() + + // load Metas + typechoDB.Raw(fmt.Sprintf("SELECT * FROM %smetas", imp.DbPrefix)).Scan(&imp.Metas) + + // load Relationships + typechoDB.Raw(fmt.Sprintf("SELECT * FROM %srelationships", imp.DbPrefix)).Scan(&imp.Relationships) + + // 重写规则 + imp.CheckRewriteRule() + + // 开始导入评论 + fmt.Println() + + var contents []TypechoContent + typechoDB.Raw(fmt.Sprintf("SELECT * FROM %scontents ORDER BY created ASC", imp.DbPrefix)).Scan(&contents) + if len(contents) > 0 { + fmt.Printf("[第一篇文章]\n\n"+ + " %#v\n\n", contents[0]) + } + imp.Contents = contents + + var comments []TypechoComment + typechoDB.Raw(fmt.Sprintf("SELECT * FROM %scomments ORDER BY created ASC", imp.DbPrefix)).Scan(&comments) + if len(contents) > 0 { + fmt.Printf("[第一条评论]\n\n"+ + " %#v\n\n", comments[0]) + } + imp.Comments = comments + + // Import Data + imp.ImportComments() +} + +// 导入评论 +func (imp *_TypechoImporter) ImportComments() { + articles := imp.Contents + comments := imp.Comments + + fmt.Print("====================================\n\n") + logrus.Info(fmt.Sprintf("[开始导入] 共 %d 个页面,%d 条评论", len(articles), len(comments))) + fmt.Print("\n") + + siteName := imp.Basic.TargetSiteName + + idChanges := map[uint]uint{} // comment_id: old => new + + // 遍历导入文章的评论 + for _, art := range articles { + // 创建页面 + pageKey := imp.GetNewPageKey(art) + page := model.FindCreatePage(pageKey, art.Title, imp.Basic.TargetSiteName) + + // 查询评论 + commentTotal := 0 + for _, co := range comments { + if co.Cid != art.Cid { + continue + } + + // 创建 user + user := model.FindCreateUser(co.Author, co.Mail) + + if co.Url != "" { + user.Link = co.Url + } + model.UpdateUser(&user) + + // 创建新 comment 实例 + nComment := model.Comment{ + Content: co.Text, + + PageKey: page.Key, + SiteName: siteName, + + UserID: user.ID, + UA: co.Agent, + IP: co.Ip, + + Rid: uint(co.Parent), + + IsCollapsed: false, + IsPending: co.Status != "approved", + } + + // 日期恢复 + createdVal := fmt.Sprintf("%v", co.Created) + nComment.CreatedAt = ParseDate(createdVal) + nComment.UpdatedAt = ParseDate(createdVal) + + // 保存到数据库 + err := lib.DB.Create(&nComment).Error + if err != nil { + logrus.Error(fmt.Sprintf("评论源 ID:%d 保存失败", co.Coid)) + continue + } + + idChanges[uint(co.Coid)] = nComment.ID + commentTotal++ + } + + fmt.Printf("+ [%-3d] 条评论 <- [%5d] %-30s | %#v\n", commentTotal, art.Cid, art.Slug, art.Title) + } + + // reply id 重建 + for _, newId := range idChanges { + nComment := model.FindComment(newId, siteName) + if nComment.Rid == 0 { + continue + } + if newId, isExist := idChanges[nComment.Rid]; isExist { + nComment.Rid = newId + err := lib.DB.Save(&nComment).Error + if err != nil { + logrus.Error(fmt.Sprintf("[rid 更新] new_id:%d new_rid:%d", nComment.ID, newId), err) + } + } + } + + fmt.Print("\n") + logrus.Info("RID 重构完毕") +} + +func (imp *_TypechoImporter) GetNewPageKey(content TypechoContent) string { + // TODO: page/post 重写规则 + + baseUrl := imp.Basic.TargetSiteUrl + baseUrl = strings.TrimSuffix(baseUrl, "/") + "/" + return baseUrl + content.Slug + ".html" +} + +// 版本国旧检测 +func (imp *_TypechoImporter) CheckVersion() { + r := regexp.MustCompile(`Typecho[\s]*(.+)\/(.+)`) + group := r.FindStringSubmatch(imp.SrcVersion) + if len(group) < 2 { + logrus.Warn(`无法确认您的 Typecho 版本号:"` + fmt.Sprintf("%#v", imp.SrcVersion) + `"`) + return + } + + verMain := ParseVersion(group[1]) + verSub := ParseVersion(group[2]) + + if verMain < ParseVersion(TypechoTestedVerMain) || + verSub < ParseVersion(TypechoTestedVerSub) { + fmt.Print("\n") + logrus.Warn(fmt.Sprintf("Typecho 当前版本 \"%s\" 旧于 \"Typecho %s/%s\"", + imp.SrcVersion, TypechoTestedVerMain, TypechoTestedVerSub)) + logrus.Warn("不确定导入是否能够成功导入,您可以选择升级 Typecho: http://docs.typecho.org/upgrade") + } +} + +func (imp *_TypechoImporter) GetOptionRoutingTable() string { + for _, opt := range imp.Options { + if opt.Name == "routingTable" { + return opt.Value + } + } + + return "" +} + +// 重写路径获取 +func (imp *_TypechoImporter) CheckRewriteRule() { + if imp.RewriteRulePost == "" { + + } else { + logrus.Info("[重写规则] 自定义 “文章” 规则:", fmt.Sprintf("%#v", imp.RewriteRulePost)) + } + + if imp.RewriteRulePage == "" { + + } else { + logrus.Info("[重写规则] 自定义 “独立页面” 规则:", fmt.Sprintf("%#v", imp.RewriteRulePage)) + } +} + +type TypechoComment struct { + Coid int `gorm:"column:coid"` // comment_id + Cid int `gorm:"column:cid"` // content_id + Created int `gorm:"column:created"` + Author string `gorm:"column:author"` + AuthorId int `gorm:"column:authorId"` + OwnerId int `gorm:"column:ownerId"` + Mail string `gorm:"column:mail"` + Url string `gorm:"column:url"` + Ip string `gorm:"column:ip"` + Agent string `gorm:"column:agent"` + Text string `gorm:"column:text"` + Type string `gorm:"column:type"` + Status string `gorm:"column:status"` + Parent int `gorm:"column:parent"` + Stars int `gorm:"column:stars"` + Notify int `gorm:"column:notify"` + Likes int `gorm:"column:likes"` + Dislikes int `gorm:"column:dislikes"` +} + +type TypechoContent struct { + Cid int `gorm:"column:cid"` + Title string `gorm:"column:title"` + Slug string `gorm:"column:slug"` + Created int `gorm:"column:created"` + Modified int `gorm:"column:modified"` + Text string `gorm:"column:text"` + Order int `gorm:"column:order"` + AuthorId int `gorm:"column:authorId"` + Template string `gorm:"column:template"` + Type string `gorm:"column:type"` + Status string `gorm:"column:status"` + Password string `gorm:"column:password"` + CommentsNum int `gorm:"column:commentsNum"` + AllowComment string `gorm:"column:allowComment"` + AllowPing string `gorm:"column:allowPing"` + AllowFeed string `gorm:"column:allowFeed"` + Parent int `gorm:"column:parent"` + Views int `gorm:"column:views"` + ViewsNum int `gorm:"column:viewsNum"` + LikesNum int `gorm:"column:likesNum"` + WordCount int `gorm:"column:wordCount"` + Likes int `gorm:"column:likes"` +} + +type TypechoOption struct { + Name string `gorm:"column:name"` + User int `gorm:"column:user"` + Value string `gorm:"column:value"` +} + +type TypechoRelationship struct { + Cid int `gorm:"column:cid"` // content_id + Mid int `gorm:"column:mid"` // meta_id +} + +type TypechoMeta struct { + Mid int `gorm:"column:mid"` + Name string `gorm:"column:name"` + Slug string `gorm:"column:slug"` + Type string `gorm:"column:type"` + Description string `gorm:"column:description"` +} diff --git a/lib/importer/wordpress.go b/lib/importer/wordpress.go new file mode 100644 index 000000000..f74e665a3 --- /dev/null +++ b/lib/importer/wordpress.go @@ -0,0 +1,15 @@ +package importer + +var WordPressImporter = &_TypechoImporter{ + Importer: Importer{ + Name: "WordPress", + Desc: "", + }, +} + +type _WordPressImporter struct { + Importer +} + +func (i _WordPressImporter) Run(basic BasicParams, payload []string) { +} From d9e4245bee3cb76712da156f9c5327da71c74cde Mon Sep 17 00:00:00 2001 From: qwqcode Date: Tue, 26 Oct 2021 17:27:46 +0800 Subject: [PATCH 075/349] feat: Typecho Impoter PageKey builder. Signed-off-by: qwqcode --- .vscode/settings.json | 1 + cmd/import.go | 44 +++--- cmd/root.go | 25 ++-- cmd/serve.go | 7 +- config/config.go | 3 +- go.mod | 2 + go.sum | 9 ++ lib/email/render.go | 2 +- lib/importer/importer.go | 129 ++++++++++++---- lib/importer/typecho.go | 305 +++++++++++++++++++++++++++++++------- lib/importer/wordpress.go | 9 +- 11 files changed, 401 insertions(+), 135 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 231288f65..2e66c975a 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -7,6 +7,7 @@ "gorm", "ldflags", "lfshook", + "Metas", "pgsql", "sendmail", "sqlite" diff --git a/cmd/import.go b/cmd/import.go index 1484b7275..76ce0538a 100644 --- a/cmd/import.go +++ b/cmd/import.go @@ -1,43 +1,33 @@ package cmd import ( - "strings" - "github.com/ArtalkJS/ArtalkGo/lib/importer" - "github.com/sirupsen/logrus" "github.com/spf13/cobra" ) var importCmd = &cobra.Command{ Use: "import", - Version: rootCmd.Version, Aliases: []string{}, - Short: "数据导入", - Long: rootCmd.Long, - Run: func(cmd *cobra.Command, args []string) { - dataType, _ := cmd.Flags().GetString("type") - if strings.TrimSpace(dataType) == "" { - logrus.Fatal("请指定参数 `--type`,帮助文档加 `-h`") - } - - isSupport := false - for _, t := range importer.GetSupportTypes() { - if strings.EqualFold(t, dataType) { - isSupport = true - } - } - - if !isSupport { - logrus.Fatal("不支持该数据类型") - } - - importer.RunByName(dataType, args) - }, + Short: "数据搬家 - 导入", + Long: "\n# 数据搬家 - 导入\n\n 从其他评论系统迁移数据到 ArtalkGo\n" + ` +- 例如:artalk-go import typecho [参数] +- 文档:https://artalk.js.org/guide/transfer.html +`, } func init() { rootCmd.AddCommand(importCmd) - flagPV(importCmd, "type", "", "", "数据类型 ["+strings.Join(importer.GetSupportTypes(), ",")+"]") - flagPV(importCmd, "port", "", 23366, "监听端口") + for _, item := range importer.Supports { + imp := importer.GetImporterInfo(item) + subCmd := &cobra.Command{ + Use: imp.Name + " [参数]", + Short: imp.Desc, + Run: func(cmd *cobra.Command, args []string) { + importer.RunByName(imp.Name, args) + }, + } + + importCmd.AddCommand(subCmd) + } } diff --git a/cmd/root.go b/cmd/root.go index 24faf080a..82b8d689d 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -1,7 +1,6 @@ package cmd import ( - "fmt" "os" "strings" "time" @@ -17,6 +16,8 @@ import ( "gorm.io/gorm" ) +var Version = lib.Version + `/` + lib.CommitHash + var Banner = ` ________ ________ _________ ________ ___ ___ __ |\ __ \|\ __ \|\___ ___\\ __ \|\ \ |\ \|\ \ @@ -26,20 +27,24 @@ var Banner = ` \ \__\ \__\ \__\\ _\ \ \__\ \ \__\ \__\ \_______\ \__\\ \__\ \|__|\|__|\|__|\|__| \|__| \|__|\|__|\|_______|\|__| \|__| -Artalk: A Fast, Slight & Delightful Comment System. -More details on https://github.com/ArtalkJS/Artalk -(c) 2021 artalk.js.org` +Artalk (` + Version + `) + + -> A Selfhosted Comment System. + -> https://artalk.js.org +` var cfgFile string var rootCmd = &cobra.Command{ - Use: "artalk-go", - Short: "Artalk: A Fast, Slight & Delightful Comment System", - Long: Banner, + Use: "artalk-go", + Short: "Artalk: A Fast, Slight & Delightful Comment System", + Long: Banner, + Version: Version, Run: func(cmd *cobra.Command, args []string) { - fmt.Println(Banner) - fmt.Println() - fmt.Println("NOTE: add `-h` flag to show help about any command.") + // fmt.Println(Banner) + // fmt.Println() + // fmt.Println("NOTE: add `-h` flag to show help about any command.") + serveCmd.Run(cmd, args) }, } diff --git a/cmd/serve.go b/cmd/serve.go index fbfc830a8..bc5773a33 100644 --- a/cmd/serve.go +++ b/cmd/serve.go @@ -9,13 +9,12 @@ import ( var serveCmd = &cobra.Command{ Use: "serve", - Version: rootCmd.Version, Aliases: []string{"server"}, - Short: "启动 HTTP 服务", - Long: rootCmd.Long, + Short: "HTTP 服务", + Long: Banner, Run: func(cmd *cobra.Command, args []string) { fmt.Println(Banner) - fmt.Println("----------------------") + fmt.Print("-------------------------------\n\n") http.Run() }, Args: cobra.NoArgs, diff --git a/config/config.go b/config/config.go index 0642be9c2..9c66ec1df 100644 --- a/config/config.go +++ b/config/config.go @@ -129,7 +129,8 @@ func Init(cfgFile string) { viper.SetEnvKeyReplacer(strings.NewReplacer(".", "_")) if err := viper.ReadInConfig(); err == nil { - fmt.Println("Using config file:", viper.ConfigFileUsed()) + fmt.Print("\n") + fmt.Println("- Using ArtalkGo config file:", viper.ConfigFileUsed()) } Instance = &Config{} diff --git a/go.mod b/go.mod index c6f7c3d05..5ed4d04ea 100644 --- a/go.mod +++ b/go.mod @@ -7,8 +7,10 @@ require ( github.com/allegro/bigcache/v3 v3.0.0 github.com/araddon/dateparse v0.0.0-20210429162001-6b43995a97de github.com/eko/gocache/v2 v2.1.0 + github.com/elliotchance/phpserialize v1.3.1 github.com/fsnotify/fsnotify v1.5.1 // indirect github.com/golang-jwt/jwt v3.2.2+incompatible + github.com/jedib0t/go-pretty/v6 v6.2.4 github.com/jeremywohl/flatten v1.0.1 github.com/kr/text v0.2.0 // indirect github.com/labstack/echo/v4 v4.5.0 diff --git a/go.sum b/go.sum index 306d6aeb2..3a6249e56 100644 --- a/go.sum +++ b/go.sum @@ -142,6 +142,8 @@ github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaB github.com/eko/gocache/v2 v2.1.0 h1:ljFKAAa5hHsrsSaBvyx0g9a/A9lZSUrf4jBjErQd7gc= github.com/eko/gocache/v2 v2.1.0/go.mod h1:u+EpYjCVsOpeqvDLzinOVLjLxwHJjO+NT4LS2+8XnCU= github.com/elazarl/goproxy v0.0.0-20170405201442-c4fc26588b6e/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= +github.com/elliotchance/phpserialize v1.3.1 h1:bA32YZF9/WmxJgIFmrweMK03Y74vPAMmRyKTLFs67/Q= +github.com/elliotchance/phpserialize v1.3.1/go.mod h1:gt7XX9+ETUcLXbtTKEuyrqW3lcLUAeS/AnGZ2e49TZs= github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= @@ -161,6 +163,7 @@ github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMo github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsnotify/fsnotify v1.5.1 h1:mZcQUHVQUQWoPXXtuf9yuEXKudkV2sx1E06UadKWpgI= github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU= +github.com/fzipp/gocyclo v0.3.1/go.mod h1:DJHO6AUmbdqj2ET4Z9iArSuwWgYDRryYt2wASxc7x3E= github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= @@ -365,6 +368,8 @@ github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0f github.com/jackc/puddle v1.1.0/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jackc/puddle v1.1.1/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jackc/puddle v1.1.3/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= +github.com/jedib0t/go-pretty/v6 v6.2.4 h1:wdaj2KHD2W+mz8JgJ/Q6L/T5dB7kyqEFI16eLq7GEmk= +github.com/jedib0t/go-pretty/v6 v6.2.4/go.mod h1:+nE9fyyHGil+PuISTCrp7avEdo6bqoMwqZnuiK2r2a0= github.com/jeremywohl/flatten v1.0.1 h1:LrsxmB3hfwJuE+ptGOijix1PIfOoKLJ3Uee/mzbgtrs= github.com/jeremywohl/flatten v1.0.1/go.mod h1:4AmD/VxjWcI5SRB0n6szE2A6s2fsNHDLO0nAlMHgfLQ= github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= @@ -435,6 +440,8 @@ github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Ky github.com/mattn/go-isatty v0.0.13 h1:qdl+GuBjcsKKDco5BsxPJlId98mSWNKqYA+Co0SC1yA= github.com/mattn/go-isatty v0.0.13/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= +github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= +github.com/mattn/go-runewidth v0.0.10 h1:CoZ3S2P7pvtP45xOtBw+/mDL2z0RKI576gSkzRRpdGg= github.com/mattn/go-runewidth v0.0.10/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk= github.com/mattn/go-sqlite3 v1.14.5/go.mod h1:WVKg1VTActs4Qso6iwGbiFih2UIHo0ENGwNd0Lj+XmI= github.com/mattn/go-sqlite3 v1.14.8 h1:gDp86IdQsN/xWjIEmr9MF6o9mpksUgh0fu+9ByFxzIU= @@ -558,6 +565,7 @@ github.com/qwqcode/go-aliyun-email v0.0.0-20180120030821-cb6e7b1382bf/go.mod h1: github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/rifflock/lfshook v0.0.0-20180920164130-b9218ef580f5 h1:mZHayPoR0lNmnHyvtYjDeq0zlVHn9K/ZXoy17ylucdo= github.com/rifflock/lfshook v0.0.0-20180920164130-b9218ef580f5/go.mod h1:GEXHk5HgEKCvEIIrSpFI3ozzG5xOKA2DVlEX/gGnewM= +github.com/rivo/uniseg v0.1.0 h1:+2KBaVoUmb9XzDsrx/Ct0W/EYOSFf/nWTauy++DprtY= github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= @@ -807,6 +815,7 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180816055513-1c9583448a9c/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= diff --git a/lib/email/render.go b/lib/email/render.go index d9fa75ce5..83a3c4121 100644 --- a/lib/email/render.go +++ b/lib/email/render.go @@ -102,7 +102,7 @@ func GetExternalEmailTpl(filename string) string { // 替换 {{ key }} 为 val func ReplaceAllMustache(data string, dict map[string]interface{}) string { - r := regexp.MustCompile(`{{\s*(\S+)\s*}}`) + r := regexp.MustCompile(`{{\s*(.*?)\s*}}`) return r.ReplaceAllStringFunc(data, func(m string) string { key := r.FindStringSubmatch(m)[1] if val, isExist := dict[key]; isExist { diff --git a/lib/importer/importer.go b/lib/importer/importer.go index 96a85d6f6..af202c77f 100644 --- a/lib/importer/importer.go +++ b/lib/importer/importer.go @@ -1,7 +1,11 @@ package importer import ( + "bufio" + "encoding/json" "fmt" + "log" + "os" "reflect" "strconv" "strings" @@ -11,56 +15,74 @@ import ( "github.com/ArtalkJS/ArtalkGo/lib" "github.com/ArtalkJS/ArtalkGo/model" "github.com/araddon/dateparse" + "github.com/jedib0t/go-pretty/v6/table" "github.com/sirupsen/logrus" "gorm.io/gorm" ) type Map = map[string]interface{} -type Importer struct { - Name string - Desc string - Run func(basic BasicParams, payload []string) -} - var Supports = []interface{}{ TypechoImporter, WordPressImporter, } -func GetSupportTypes() []string { - types := []string{} +func RunByName(dataType string, payload []string) { + basic := GetBasicParamsFrom(payload) for _, i := range Supports { r := reflect.ValueOf(i) - f := reflect.Indirect(r).FieldByName("Name") - types = append(types, f.String()) + name := reflect.Indirect(r).FieldByName("Name").String() + desc := reflect.Indirect(r).FieldByName("Desc").String() + note := reflect.Indirect(r).FieldByName("Note").String() + if !strings.EqualFold(name, dataType) { + continue + } + + fmt.Print("\n") + PrintTable([]table.Row{ + {"数据搬家 - 导入"}, + {strings.ToUpper(name)}, + {desc}, + {note}, + }) + fmt.Print("\n") + + t1 := time.Now() + r.MethodByName("Run").Call([]reflect.Value{ + reflect.ValueOf(basic), + reflect.ValueOf(payload), + }) + elapsed := time.Since(t1) + fmt.Print("\n") + logrus.Info("导入执行结束,耗时: ", elapsed) + return } - return types + logrus.Fatal("不支持该数据类型导入") } -func RunByName(dataType string, payload []string) { - basic := GetBasicParamsFrom(payload) +type ImporterInfo struct { + Name string + Desc string + Note string +} + +func GetImporterInfo(instance interface{}) ImporterInfo { + var info ImporterInfo + j, _ := json.Marshal(instance) + json.Unmarshal(j, &info) + return info +} + +func GetSupportNames() []string { + types := []string{} for _, i := range Supports { r := reflect.ValueOf(i) - name := reflect.Indirect(r).FieldByName("Name").String() - desc := reflect.Indirect(r).FieldByName("Desc").String() - if strings.EqualFold(name, dataType) { - fmt.Print("\n* * *\n\n") - fmt.Print(" [数据导入] " + name + "\n\n") - logrus.Info(desc) - fmt.Print("\n* * *\n\n") - - t1 := time.Now() - r.MethodByName("Run").Call([]reflect.Value{ - reflect.ValueOf(basic), - reflect.ValueOf(payload), - }) - elapsed := time.Since(t1) - fmt.Print("\n") - logrus.Info("导出执行结束,耗时: ", elapsed) - } + f := reflect.Indirect(r).FieldByName("Name") + types = append(types, f.String()) } + + return types } type _getParamsTo struct { @@ -97,10 +119,10 @@ func GetBasicParamsFrom(payload []string) BasicParams { }) if basic.TargetSiteName == "" { - logrus.Fatal("参数 `target_site_name:<站点名称>` 不能为空") + logrus.Fatal("请附带参数 `target_site_name:<站点名称>`") } if basic.TargetSiteUrl == "" { - logrus.Fatal("参数 `target_site_url:<站点根目录 URL>` 不能为空") + logrus.Fatal("请附带参数 `target_site_url:<站点根目录 URL>`") } if !lib.ValidateURL(basic.TargetSiteUrl) { logrus.Fatal("参数 `target_site_url:<站点根目录 URL>` 必须为 URL 格式") @@ -147,6 +169,9 @@ func DbReady(payload []string) *gorm.DB { if err != nil { logrus.Fatal("数据库连接失败 ", err) } + + logrus.Info("数据库连接成功") + return db } @@ -212,3 +237,43 @@ func ParseDate(s string) time.Time { return t } + +func PrintTable(rows []table.Row) { + t := table.NewWriter() + t.SetOutputMirror(os.Stdout) + + for _, r := range rows { + t.AppendRow(r) + } + + tStyle := table.StyleLight + tStyle.Options.SeparateRows = true + t.SetStyle(tStyle) + + t.Render() +} + +func Confirm(s string) bool { + r := bufio.NewReader(os.Stdin) + + for { + fmt.Printf("%s [y/n]: ", s) + + res, err := r.ReadString('\n') + if err != nil { + log.Fatal(err) + } + + // Empty input (i.e. "\n") + if len(res) < 2 { + continue + } + + resp := strings.ToLower(strings.TrimSpace(res)) + if resp == "y" || resp == "yes" { + return true + } else if resp == "n" || resp == "no" { + return false + } + } +} diff --git a/lib/importer/typecho.go b/lib/importer/typecho.go index 521304132..138b7bb52 100644 --- a/lib/importer/typecho.go +++ b/lib/importer/typecho.go @@ -1,30 +1,38 @@ package importer import ( + "errors" "fmt" + "os" "regexp" "strings" "github.com/ArtalkJS/ArtalkGo/lib" "github.com/ArtalkJS/ArtalkGo/model" + "github.com/elliotchance/phpserialize" + "github.com/jedib0t/go-pretty/v6/table" + "github.com/mitchellh/mapstructure" "github.com/sirupsen/logrus" ) const ( // 已测试可用版本 - TypechoTestedVerMain = "1.1" - TypechoTestedVerSub = "17.10.30" + TypechoTestedVerMain = "1.1" + TypechoTestedVerSub = "17.10.30" + TypechoRewritePostDefault = "/archives/{cid}/" + TypechoRewritePageDefault = "/{slug}.html" ) var TypechoImporter = &_TypechoImporter{ - Importer: Importer{ - Name: "Typecho", - Desc: fmt.Sprintf("测试兼容:Typecho %s/%s", TypechoTestedVerMain, TypechoTestedVerSub), + ImporterInfo: ImporterInfo{ + Name: "typecho", + Desc: "从 Typecho 导入数据", + Note: fmt.Sprintf("测试兼容:Typecho %s/%s", TypechoTestedVerMain, TypechoTestedVerSub), }, } type _TypechoImporter struct { - Importer + ImporterInfo TargetSite model.Site Basic BasicParams @@ -39,22 +47,24 @@ type _TypechoImporter struct { DbPrefix string - RewriteRulePost string - RewriteRulePage string + RewritePost string + RewritePage string + + OptionRoutingTable map[string]TypechoRoute } // Typecho 升级相关的代码 @see https://github.com/typecho/typecho/blob/64b8e686885d8ab4c7f0cdc3d6dc2d99fa48537c/var/Utils/Upgrade.php // 路由 @see https://github.com/typecho/typecho/blob/530312443142577509df88ce88cf3274fac9b8c4/var/Widget/Options/Permalink.php#L319 +// DB @see https://github.com/typecho/typecho/blob/6558fd5e030a950335d53038f82728b06ad6c32d/install/Mysql.sql func (imp *_TypechoImporter) Run(basic BasicParams, payload []string) { // Ready imp.Basic = basic typechoDB := DbReady(payload) - imp.TargetSite = SiteReady(basic) GetParamsFrom(payload).To(map[string]*string{ - "prefix": &imp.DbPrefix, - "rewrite_rule_post": &imp.RewriteRulePost, - "rewrite_rule_page": &imp.RewriteRulePage, + "prefix": &imp.DbPrefix, + "rewrite_post": &imp.RewritePost, + "rewrite_page": &imp.RewritePage, }) if imp.DbPrefix == "" { @@ -75,67 +85,102 @@ func (imp *_TypechoImporter) Run(basic BasicParams, payload []string) { } } - fmt.Printf("- 源版本:%#v\n", imp.SrcVersion) - fmt.Printf("- 源站点名:%#v\n", imp.SrcSiteName) - fmt.Printf("- 源站点URL:%#v\n", imp.SrcSiteURL) + // 检查数据源版本号 + imp.VersionCheck() - imp.CheckVersion() + // 重写规则 + imp.RewriteRuleReady() // load Metas typechoDB.Raw(fmt.Sprintf("SELECT * FROM %smetas", imp.DbPrefix)).Scan(&imp.Metas) + logrus.Info(fmt.Sprintf("从数据表 `%smetas` 获取 %d 条记录", imp.DbPrefix, len(imp.Metas))) // load Relationships typechoDB.Raw(fmt.Sprintf("SELECT * FROM %srelationships", imp.DbPrefix)).Scan(&imp.Relationships) + logrus.Info(fmt.Sprintf("从数据表 `%srelationships` 获取 %d 条记录", imp.DbPrefix, len(imp.Relationships))) - // 重写规则 - imp.CheckRewriteRule() + // 获取 contents + typechoDB.Raw(fmt.Sprintf("SELECT * FROM %scontents ORDER BY created ASC", imp.DbPrefix)).Scan(&imp.Contents) + logrus.Info(fmt.Sprintf("从数据表 `%scontents` 获取 %d 条记录", imp.DbPrefix, len(imp.Contents))) - // 开始导入评论 - fmt.Println() + // 获取 comments + typechoDB.Raw(fmt.Sprintf("SELECT * FROM %scomments ORDER BY created ASC", imp.DbPrefix)).Scan(&imp.Comments) + logrus.Info(fmt.Sprintf("从数据表 `%scomments` 获取 %d 条记录", imp.DbPrefix, len(imp.Comments))) - var contents []TypechoContent - typechoDB.Raw(fmt.Sprintf("SELECT * FROM %scontents ORDER BY created ASC", imp.DbPrefix)).Scan(&contents) - if len(contents) > 0 { - fmt.Printf("[第一篇文章]\n\n"+ - " %#v\n\n", contents[0]) + // 导入前参数汇总 + fmt.Print("\n") + + fmt.Print("# 请过目:\n\n") + + // 显示第一条数据 + for _, c := range imp.Contents { + if c.Type == "post" { + fmt.Printf("[第一篇文章]\n\n"+ + " %#v\n\n", imp.Contents[0]) + fmt.Printf(" -> 生成 PageKey: %#v\n\n", imp.GetNewPageKey(c)) + break + } } - imp.Contents = contents - var comments []TypechoComment - typechoDB.Raw(fmt.Sprintf("SELECT * FROM %scomments ORDER BY created ASC", imp.DbPrefix)).Scan(&comments) - if len(contents) > 0 { + if len(imp.Comments) > 0 { fmt.Printf("[第一条评论]\n\n"+ - " %#v\n\n", comments[0]) + " %#v\n\n", imp.Comments[0]) + } + + PrintTable([]table.Row{ + {"[基本信息]", "读取数据", "导入目标"}, + {"站点名称", fmt.Sprintf("%#v", imp.SrcSiteName), fmt.Sprintf("%#v", imp.Basic.TargetSiteName)}, + {"BaseURL", fmt.Sprintf("%#v", imp.SrcSiteURL), fmt.Sprintf("%#v", imp.Basic.TargetSiteUrl)}, + {"版本号", fmt.Sprintf("%v", imp.SrcVersion), fmt.Sprintf("ArtalkGo %v", lib.Version+"/"+lib.CommitHash+"")}, + {"数量统计", fmt.Sprintf("评论: %d", len(imp.Comments)), fmt.Sprintf("页面: %d", len(imp.Contents))}, + }) + + PrintTable([]table.Row{ + {"[重写规则]", "用于生成 pageKey (评论页面唯一标识)"}, + {"文章页面", fmt.Sprintf("%#v", imp.RewritePost)}, + {"独立页面", fmt.Sprintf("%#v", imp.RewritePage)}, + }) + + fmt.Print("\n") + + // 确认开始 + if !Confirm("确认开始导入吗?") { + os.Exit(0) } - imp.Comments = comments - // Import Data + // 准备导入评论 + fmt.Println() + + // 准备新的 site + imp.TargetSite = SiteReady(basic) + + // 开始执行导入 imp.ImportComments() } // 导入评论 func (imp *_TypechoImporter) ImportComments() { - articles := imp.Contents + contents := imp.Contents comments := imp.Comments - fmt.Print("====================================\n\n") - logrus.Info(fmt.Sprintf("[开始导入] 共 %d 个页面,%d 条评论", len(articles), len(comments))) + fmt.Print("\n====================================\n\n") + logrus.Info(fmt.Sprintf("[开始导入] 共 %d 个页面,%d 条评论", len(contents), len(comments))) fmt.Print("\n") siteName := imp.Basic.TargetSiteName idChanges := map[uint]uint{} // comment_id: old => new - // 遍历导入文章的评论 - for _, art := range articles { + // 遍历 Contents + for _, c := range contents { // 创建页面 - pageKey := imp.GetNewPageKey(art) - page := model.FindCreatePage(pageKey, art.Title, imp.Basic.TargetSiteName) + pageKey := imp.GetNewPageKey(c) + page := model.FindCreatePage(pageKey, c.Title, imp.Basic.TargetSiteName) // 查询评论 commentTotal := 0 for _, co := range comments { - if co.Cid != art.Cid { + if co.Cid != c.Cid { continue } @@ -180,7 +225,7 @@ func (imp *_TypechoImporter) ImportComments() { commentTotal++ } - fmt.Printf("+ [%-3d] 条评论 <- [%5d] %-30s | %#v\n", commentTotal, art.Cid, art.Slug, art.Title) + fmt.Printf("+ [%-3d] 条评论 <- [%5d] %-30s | %#v\n", commentTotal, c.Cid, c.Slug, c.Title) } // reply id 重建 @@ -202,16 +247,50 @@ func (imp *_TypechoImporter) ImportComments() { logrus.Info("RID 重构完毕") } +// 获取新的 PageKey (根据重写规则) func (imp *_TypechoImporter) GetNewPageKey(content TypechoContent) string { - // TODO: page/post 重写规则 + date := ParseDate(fmt.Sprintf("%v", content.Created)) + + // 替换内容制作 + replaces := map[string]string{ + "cid": fmt.Sprintf("%v", content.Cid), + "slug": content.Slug, + "category": imp.GetContentCategory(content.Cid), + "year": fmt.Sprintf("%v", date.Local().Year()), + "month": fmt.Sprintf("%v", date.Local().Month()), + "day": fmt.Sprintf("%v", date.Local().Day()), + } baseUrl := imp.Basic.TargetSiteUrl - baseUrl = strings.TrimSuffix(baseUrl, "/") + "/" - return baseUrl + content.Slug + ".html" + baseUrl = strings.TrimSuffix(baseUrl, "/") + + rewriteRule := imp.RewritePost + if strings.HasPrefix(content.Type, "post") { + rewriteRule = imp.RewritePost + } else if strings.HasPrefix(content.Type, "page") { + rewriteRule = imp.RewritePage + } + + rewriteRule = "/" + strings.TrimPrefix(rewriteRule, "/") + return baseUrl + imp.ReplaceAll(rewriteRule, replaces) } -// 版本国旧检测 -func (imp *_TypechoImporter) CheckVersion() { +// 替换字符串 +func (imp *_TypechoImporter) ReplaceAll(data string, dict map[string]string) string { + r := regexp.MustCompile(`(\[|\{)\s*(.*?)\s*(\]|\})`) // 同时支持 {} 和 [] + return r.ReplaceAllStringFunc(data, func(m string) string { + key := r.FindStringSubmatch(m)[2] + if val, isExist := dict[key]; isExist { + return val + } else { + logrus.Error(fmt.Sprintf("[重写规则] \"%s\" 变量无效", key)) + } + return m + }) +} + +// 版本过旧检测 +func (imp *_TypechoImporter) VersionCheck() { r := regexp.MustCompile(`Typecho[\s]*(.+)\/(.+)`) group := r.FindStringSubmatch(imp.SrcVersion) if len(group) < 2 { @@ -231,31 +310,141 @@ func (imp *_TypechoImporter) CheckVersion() { } } -func (imp *_TypechoImporter) GetOptionRoutingTable() string { +// TypechoRoute 路由 +type TypechoRoute struct { + URL string `json:"url"` + Format string `json:"format"` + Params string `json:"params"` + Regx string `json:"regx"` + Action string `json:"action"` + Widget string `json:"widget"` +} + +// 获取 typecho_options 表里面的 name:routingTable option,解析 option.value。 +// option.value 数据为 PHP 序列化后的结果。 +// @see https://www.php.net/manual/en/function.serialize.php +// @see https://www.php.net/manual/en/function.unserialize.php +func (imp *_TypechoImporter) GetOptionRoutingTable() (map[string]TypechoRoute, error) { + // 仅获取一次 + if imp.OptionRoutingTable != nil { + return imp.OptionRoutingTable, nil + } + + dataStr := "" for _, opt := range imp.Options { if opt.Name == "routingTable" { - return opt.Value + dataStr = opt.Value + break } } - return "" + if dataStr == "" { + return map[string]TypechoRoute{}, errors.New("`routingTable` Not Found in Options") + } + + // Unmarshal + var data map[interface{}]interface{} + err := phpserialize.Unmarshal([]byte(dataStr), &data) + if err != nil { + return map[string]TypechoRoute{}, err + } + + // interface{} to struct + routingTable := map[string]TypechoRoute{} + for k, v := range data { + var r TypechoRoute + mapstructure.Decode(v, &r) + routingTable[fmt.Sprintf("%v", k)] = r + } + + imp.OptionRoutingTable = routingTable // 就不再反复获取了 + + return routingTable, nil +} + +// 获取一个 Route +func (imp *_TypechoImporter) GetOptionRoute(name string) (TypechoRoute, error) { + routingTable, err := imp.GetOptionRoutingTable() + if err != nil { + return TypechoRoute{}, err + } + + for n, route := range routingTable { + if n == name { + return route, nil + } + } + + return TypechoRoute{}, errors.New(`Route Name "` + name + `" Not Found`) } // 重写路径获取 -func (imp *_TypechoImporter) CheckRewriteRule() { - if imp.RewriteRulePost == "" { +func (imp *_TypechoImporter) RewriteRuleReady() { + check := func(nameText string, routeName string, field *string, defaultVal string) { + if *field == "" { + // 从数据库获取 + route, err := imp.GetOptionRoute(routeName) + if err != nil || route.URL == "" { + if err != nil { + logrus.Error(err) + } + + *field = defaultVal + logrus.Error("[重写规则] \"" + nameText + "\" 无法从数据库读取,将使用默认值 \"" + imp.RewritePost + "\"") + return + } - } else { - logrus.Info("[重写规则] 自定义 “文章” 规则:", fmt.Sprintf("%#v", imp.RewriteRulePost)) + *field = route.URL + logrus.Info("重写规则 \"" + nameText + "\" 读取成功") + } else { + logrus.Info("[重写规则] 自定义 \""+nameText+"\" 规则:", fmt.Sprintf("%#v", *field)) + } + } + + check("文章页", "post", &imp.RewritePost, TypechoRewritePostDefault) + check("独立页面", "page", &imp.RewritePage, TypechoRewritePageDefault) +} + +// 获取 Content 的 Metas +func (imp *_TypechoImporter) GetContentMetas(cid int) []TypechoMeta { + metaIds := []int{} + for _, rela := range imp.Relationships { + if rela.Cid == cid { + metaIds = append(metaIds, rela.Mid) + } + } + + metas := []TypechoMeta{} + for _, m := range imp.Metas { + isNeed := false + for _, id := range metaIds { + if id == m.Mid { + isNeed = true + break + } + } + + if isNeed { + metas = append(metas, m) + } } - if imp.RewriteRulePage == "" { + return metas +} - } else { - logrus.Info("[重写规则] 自定义 “独立页面” 规则:", fmt.Sprintf("%#v", imp.RewriteRulePage)) +// 获取 Content 的分类 +func (imp *_TypechoImporter) GetContentCategory(cid int) string { + metas := imp.GetContentMetas(cid) + for _, m := range metas { + if m.Type == "category" { + return m.Slug + } } + + return "" } +// Typecho 评论数据表 type TypechoComment struct { Coid int `gorm:"column:coid"` // comment_id Cid int `gorm:"column:cid"` // content_id @@ -277,6 +466,7 @@ type TypechoComment struct { Dislikes int `gorm:"column:dislikes"` } +// Typecho 内容数据表 (Type: post, page) type TypechoContent struct { Cid int `gorm:"column:cid"` Title string `gorm:"column:title"` @@ -302,17 +492,20 @@ type TypechoContent struct { Likes int `gorm:"column:likes"` } +// Typecho 配置数据表 type TypechoOption struct { Name string `gorm:"column:name"` User int `gorm:"column:user"` Value string `gorm:"column:value"` } +// Typecho 关联表 (Content => Metas) type TypechoRelationship struct { Cid int `gorm:"column:cid"` // content_id Mid int `gorm:"column:mid"` // meta_id } +// Typecho 附加字段数据表 type TypechoMeta struct { Mid int `gorm:"column:mid"` Name string `gorm:"column:name"` diff --git a/lib/importer/wordpress.go b/lib/importer/wordpress.go index f74e665a3..8ffbdf1c3 100644 --- a/lib/importer/wordpress.go +++ b/lib/importer/wordpress.go @@ -1,14 +1,15 @@ package importer var WordPressImporter = &_TypechoImporter{ - Importer: Importer{ - Name: "WordPress", - Desc: "", + ImporterInfo: ImporterInfo{ + Name: "wordpress", + Desc: "从 WordPress 导入数据", + Note: "", }, } type _WordPressImporter struct { - Importer + ImporterInfo } func (i _WordPressImporter) Run(basic BasicParams, payload []string) { From 6a372bacdcde6bc73418b7ca8ba5c4e5002045f4 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Tue, 26 Oct 2021 19:10:56 +0800 Subject: [PATCH 076/349] feat: Typecho Impoter add some hint. Signed-off-by: qwqcode --- lib/importer/importer.go | 31 +++++++++++++++++++++++--- lib/importer/typecho.go | 48 ++++++++++++++++++++++++++++------------ 2 files changed, 62 insertions(+), 17 deletions(-) diff --git a/lib/importer/importer.go b/lib/importer/importer.go index af202c77f..b7564c602 100644 --- a/lib/importer/importer.go +++ b/lib/importer/importer.go @@ -7,9 +7,11 @@ import ( "log" "os" "reflect" + "regexp" "strconv" "strings" "time" + "unicode/utf8" "github.com/ArtalkJS/ArtalkGo/config" "github.com/ArtalkJS/ArtalkGo/lib" @@ -47,14 +49,14 @@ func RunByName(dataType string, payload []string) { }) fmt.Print("\n") - t1 := time.Now() + //t1 := time.Now() r.MethodByName("Run").Call([]reflect.Value{ reflect.ValueOf(basic), reflect.ValueOf(payload), }) - elapsed := time.Since(t1) + //elapsed := time.Since(t1) fmt.Print("\n") - logrus.Info("导入执行结束,耗时: ", elapsed) + logrus.Info("导入执行结束") //,耗时: ", elapsed) return } @@ -106,6 +108,17 @@ func GetParamsFrom(payload []string) _getParamsTo { return a } +func GetArrayParamsFrom(payload []string, key string) []string { + arr := []string{} + for _, pVal := range payload { + if strings.HasPrefix(pVal, key+":") { + arr = append(arr, strings.TrimPrefix(pVal, key+":")) + } + } + + return arr +} + type BasicParams struct { TargetSiteName string `json:"target_site_name"` TargetSiteUrl string `json:"target_site_url"` @@ -277,3 +290,15 @@ func Confirm(s string) bool { } } } + +func HideJsonLongText(key string, text string) string { + r := regexp.MustCompile(key + `:"(.+?)"`) + sm := r.FindStringSubmatch(text) + postText := "" + if len(sm) > 0 { + postText = sm[1] + } + + text = r.ReplaceAllString(text, fmt.Sprintf(key+": ", utf8.RuneCountInString(postText))) + return text +} diff --git a/lib/importer/typecho.go b/lib/importer/typecho.go index 138b7bb52..4ffe21285 100644 --- a/lib/importer/typecho.go +++ b/lib/importer/typecho.go @@ -72,7 +72,9 @@ func (imp *_TypechoImporter) Run(basic BasicParams, payload []string) { } // Load Options - typechoDB.Raw(fmt.Sprintf("SELECT * FROM %soptions", imp.DbPrefix)).Scan(&imp.Options) + tbOptions := imp.DbPrefix + "options" + typechoDB.Raw("SELECT * FROM " + tbOptions).Scan(&imp.Options) + logrus.Info(fmt.Sprintf("从数据表 `%s` 获取 %d 条记录", tbOptions, len(imp.Options))) for _, opt := range imp.Options { switch opt.Name { @@ -92,20 +94,24 @@ func (imp *_TypechoImporter) Run(basic BasicParams, payload []string) { imp.RewriteRuleReady() // load Metas - typechoDB.Raw(fmt.Sprintf("SELECT * FROM %smetas", imp.DbPrefix)).Scan(&imp.Metas) - logrus.Info(fmt.Sprintf("从数据表 `%smetas` 获取 %d 条记录", imp.DbPrefix, len(imp.Metas))) + tbMetas := imp.DbPrefix + "metas" + typechoDB.Raw("SELECT * FROM " + tbMetas).Scan(&imp.Metas) + logrus.Info(fmt.Sprintf("从数据表 `%s` 获取 %d 条记录", tbMetas, len(imp.Metas))) // load Relationships - typechoDB.Raw(fmt.Sprintf("SELECT * FROM %srelationships", imp.DbPrefix)).Scan(&imp.Relationships) - logrus.Info(fmt.Sprintf("从数据表 `%srelationships` 获取 %d 条记录", imp.DbPrefix, len(imp.Relationships))) + tbRelationships := imp.DbPrefix + "relationships" + typechoDB.Raw("SELECT * FROM " + tbRelationships).Scan(&imp.Relationships) + logrus.Info(fmt.Sprintf("从数据表 `%s` 获取 %d 条记录", tbRelationships, len(imp.Relationships))) // 获取 contents - typechoDB.Raw(fmt.Sprintf("SELECT * FROM %scontents ORDER BY created ASC", imp.DbPrefix)).Scan(&imp.Contents) - logrus.Info(fmt.Sprintf("从数据表 `%scontents` 获取 %d 条记录", imp.DbPrefix, len(imp.Contents))) + tbContents := imp.DbPrefix + "contents" + typechoDB.Raw(fmt.Sprintf("SELECT * FROM %s ORDER BY created ASC", tbContents)).Scan(&imp.Contents) + logrus.Info(fmt.Sprintf("从数据表 `%s` 获取 %d 条记录", tbContents, len(imp.Contents))) // 获取 comments - typechoDB.Raw(fmt.Sprintf("SELECT * FROM %scomments ORDER BY created ASC", imp.DbPrefix)).Scan(&imp.Comments) - logrus.Info(fmt.Sprintf("从数据表 `%scomments` 获取 %d 条记录", imp.DbPrefix, len(imp.Comments))) + tbComments := imp.DbPrefix + "comments" + typechoDB.Raw(fmt.Sprintf("SELECT * FROM %s ORDER BY created ASC", tbComments)).Scan(&imp.Comments) + logrus.Info(fmt.Sprintf("从数据表 `%s` 获取 %d 条记录", tbComments, len(imp.Comments))) // 导入前参数汇总 fmt.Print("\n") @@ -113,11 +119,23 @@ func (imp *_TypechoImporter) Run(basic BasicParams, payload []string) { fmt.Print("# 请过目:\n\n") // 显示第一条数据 + pageKeyEgPost := "" + pageKeyEgPage := "" for _, c := range imp.Contents { if c.Type == "post" { - fmt.Printf("[第一篇文章]\n\n"+ + firstPost := fmt.Sprintf("[第一篇文章]\n\n"+ " %#v\n\n", imp.Contents[0]) - fmt.Printf(" -> 生成 PageKey: %#v\n\n", imp.GetNewPageKey(c)) + + fmt.Print(HideJsonLongText("Text", firstPost)) + pageKeyEgPost = imp.GetNewPageKey(c) + fmt.Printf(" -> 生成 PageKey: %#v\n\n", pageKeyEgPost) + break + } + } + + for _, c := range imp.Contents { + if c.Type == "page" { + pageKeyEgPage = imp.GetNewPageKey(c) break } } @@ -136,11 +154,13 @@ func (imp *_TypechoImporter) Run(basic BasicParams, payload []string) { }) PrintTable([]table.Row{ - {"[重写规则]", "用于生成 pageKey (评论页面唯一标识)"}, - {"文章页面", fmt.Sprintf("%#v", imp.RewritePost)}, - {"独立页面", fmt.Sprintf("%#v", imp.RewritePage)}, + {"[重写规则]", "用于生成 pageKey (评论页面唯一标识)", "生成示例"}, + {"文章页面", fmt.Sprintf("%#v", imp.RewritePost), pageKeyEgPost}, + {"独立页面", fmt.Sprintf("%#v", imp.RewritePage), pageKeyEgPage}, }) + fmt.Print("\n") + fmt.Println("若以上内容不符合预期,请向我们反馈:https://artalk.js.org/guide/transfer.html") fmt.Print("\n") // 确认开始 From fa2c7605e2818cec20e7e67e61f85b454a7ec23a Mon Sep 17 00:00:00 2001 From: qwqcode Date: Tue, 26 Oct 2021 20:37:21 +0800 Subject: [PATCH 077/349] fix: Typecho Importer some bugs. Signed-off-by: qwqcode --- lib/importer/importer.go | 10 ++++++---- lib/importer/typecho.go | 42 +++++++++++++++++++++++++++++++++------ lib/importer/wordpress.go | 2 +- 3 files changed, 43 insertions(+), 11 deletions(-) diff --git a/lib/importer/importer.go b/lib/importer/importer.go index b7564c602..30e58ea84 100644 --- a/lib/importer/importer.go +++ b/lib/importer/importer.go @@ -124,13 +124,17 @@ type BasicParams struct { TargetSiteUrl string `json:"target_site_url"` } -func GetBasicParamsFrom(payload []string) BasicParams { +func GetBasicParamsFrom(payload []string) *BasicParams { basic := BasicParams{} GetParamsFrom(payload).To(map[string]*string{ "target_site_name": &basic.TargetSiteName, "target_site_url": &basic.TargetSiteUrl, }) + return &basic +} + +func RequiredBasicTargetSite(basic *BasicParams) { if basic.TargetSiteName == "" { logrus.Fatal("请附带参数 `target_site_name:<站点名称>`") } @@ -140,8 +144,6 @@ func GetBasicParamsFrom(payload []string) BasicParams { if !lib.ValidateURL(basic.TargetSiteUrl) { logrus.Fatal("参数 `target_site_url:<站点根目录 URL>` 必须为 URL 格式") } - - return basic } func DbReady(payload []string) *gorm.DB { @@ -189,7 +191,7 @@ func DbReady(payload []string) *gorm.DB { } // 站点准备 -func SiteReady(basic BasicParams) model.Site { +func SiteReady(basic *BasicParams) model.Site { site := model.FindSite(basic.TargetSiteName) if site.IsEmpty() { // 创建新站点 diff --git a/lib/importer/typecho.go b/lib/importer/typecho.go index 4ffe21285..898335ccf 100644 --- a/lib/importer/typecho.go +++ b/lib/importer/typecho.go @@ -35,7 +35,7 @@ type _TypechoImporter struct { ImporterInfo TargetSite model.Site - Basic BasicParams + Basic *BasicParams SrcVersion string SrcSiteName string SrcSiteURL string @@ -56,7 +56,7 @@ type _TypechoImporter struct { // Typecho 升级相关的代码 @see https://github.com/typecho/typecho/blob/64b8e686885d8ab4c7f0cdc3d6dc2d99fa48537c/var/Utils/Upgrade.php // 路由 @see https://github.com/typecho/typecho/blob/530312443142577509df88ce88cf3274fac9b8c4/var/Widget/Options/Permalink.php#L319 // DB @see https://github.com/typecho/typecho/blob/6558fd5e030a950335d53038f82728b06ad6c32d/install/Mysql.sql -func (imp *_TypechoImporter) Run(basic BasicParams, payload []string) { +func (imp *_TypechoImporter) Run(basic *BasicParams, payload []string) { // Ready imp.Basic = basic typechoDB := DbReady(payload) @@ -87,6 +87,15 @@ func (imp *_TypechoImporter) Run(basic BasicParams, payload []string) { } } + // 若未指定 target site 则使用数据库数据 + if basic.TargetSiteName == "" && imp.SrcSiteName != "" { + basic.TargetSiteName = imp.SrcSiteName + } + if basic.TargetSiteUrl == "" && imp.SrcSiteURL != "" && lib.ValidateURL(imp.SrcSiteURL) { + basic.TargetSiteUrl = imp.SrcSiteURL + } + RequiredBasicTargetSite(basic) + // 检查数据源版本号 imp.VersionCheck() @@ -292,15 +301,16 @@ func (imp *_TypechoImporter) GetNewPageKey(content TypechoContent) string { } rewriteRule = "/" + strings.TrimPrefix(rewriteRule, "/") - return baseUrl + imp.ReplaceAll(rewriteRule, replaces) + return baseUrl + imp.ReplaceAllBracketed(rewriteRule, replaces) } // 替换字符串 -func (imp *_TypechoImporter) ReplaceAll(data string, dict map[string]string) string { +// @note 特别注意:replaces 的 key 外侧无 “[]” 或 “{}” +func (imp *_TypechoImporter) ReplaceAllBracketed(data string, replaces map[string]string) string { r := regexp.MustCompile(`(\[|\{)\s*(.*?)\s*(\]|\})`) // 同时支持 {} 和 [] return r.ReplaceAllStringFunc(data, func(m string) string { key := r.FindStringSubmatch(m)[2] - if val, isExist := dict[key]; isExist { + if val, isExist := replaces[key]; isExist { return val } else { logrus.Error(fmt.Sprintf("[重写规则] \"%s\" 变量无效", key)) @@ -414,7 +424,27 @@ func (imp *_TypechoImporter) RewriteRuleReady() { return } - *field = route.URL + readRule := route.URL + + // 将 [year:digital:4] 变为 [year] + r := regexp.MustCompile(`\[(([a-zA-Z0-9]+):?(.*?))\]`) + subMatches := r.FindAllStringSubmatch(readRule, -1) + replaces := map[string]string{} + for _, m := range subMatches { + if len(m) < 1 { + continue + } + + // 0 => [year:digital:4] + // 1 => year:digital:4 + // 2 => year + // 3 => digital:4 + replaces[m[1]] = "[" + m[2] + "]" + } + readRule = imp.ReplaceAllBracketed(readRule, replaces) // replaces keys 无括号 + + // 保存从数据库读取到的 rule + *field = readRule logrus.Info("重写规则 \"" + nameText + "\" 读取成功") } else { logrus.Info("[重写规则] 自定义 \""+nameText+"\" 规则:", fmt.Sprintf("%#v", *field)) diff --git a/lib/importer/wordpress.go b/lib/importer/wordpress.go index 8ffbdf1c3..e59412a83 100644 --- a/lib/importer/wordpress.go +++ b/lib/importer/wordpress.go @@ -12,5 +12,5 @@ type _WordPressImporter struct { ImporterInfo } -func (i _WordPressImporter) Run(basic BasicParams, payload []string) { +func (i _WordPressImporter) Run(basic *BasicParams, payload []string) { } From bce0598ebe5001efab91a14df0006aa2d2c53536 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Tue, 26 Oct 2021 22:56:21 +0800 Subject: [PATCH 078/349] feat(importer): import from valine. Signed-off-by: qwqcode --- lib/importer/example.go | 16 ++++ lib/importer/importer.go | 24 +++-- lib/importer/valine.go | 194 ++++++++++++++++++++++++++++++++++++++ lib/importer/wordpress.go | 4 +- lib/utils.go | 7 ++ 5 files changed, 233 insertions(+), 12 deletions(-) create mode 100644 lib/importer/example.go create mode 100644 lib/importer/valine.go diff --git a/lib/importer/example.go b/lib/importer/example.go new file mode 100644 index 000000000..733d9618e --- /dev/null +++ b/lib/importer/example.go @@ -0,0 +1,16 @@ +package importer + +var ExampleImporter = &_ExampleImporter{ + ImporterInfo: ImporterInfo{ + Name: "example", + Desc: "从 Example 导入数据", + Note: "", + }, +} + +type _ExampleImporter struct { + ImporterInfo +} + +func (imp *_ExampleImporter) Run(basic *BasicParams, payload []string) { +} diff --git a/lib/importer/importer.go b/lib/importer/importer.go index 30e58ea84..780436e92 100644 --- a/lib/importer/importer.go +++ b/lib/importer/importer.go @@ -27,6 +27,7 @@ type Map = map[string]interface{} var Supports = []interface{}{ TypechoImporter, WordPressImporter, + ValineImporter, } func RunByName(dataType string, payload []string) { @@ -41,12 +42,15 @@ func RunByName(dataType string, payload []string) { } fmt.Print("\n") - PrintTable([]table.Row{ + tableData := []table.Row{ {"数据搬家 - 导入"}, {strings.ToUpper(name)}, {desc}, - {note}, - }) + } + if note != "" { + tableData = append(tableData, table.Row{note}) + } + PrintTable(tableData) fmt.Print("\n") //t1 := time.Now() @@ -120,15 +124,15 @@ func GetArrayParamsFrom(payload []string, key string) []string { } type BasicParams struct { - TargetSiteName string `json:"target_site_name"` - TargetSiteUrl string `json:"target_site_url"` + TargetSiteName string + TargetSiteUrl string } func GetBasicParamsFrom(payload []string) *BasicParams { basic := BasicParams{} GetParamsFrom(payload).To(map[string]*string{ - "target_site_name": &basic.TargetSiteName, - "target_site_url": &basic.TargetSiteUrl, + "ts_name": &basic.TargetSiteName, + "ts_url": &basic.TargetSiteUrl, }) return &basic @@ -136,13 +140,13 @@ func GetBasicParamsFrom(payload []string) *BasicParams { func RequiredBasicTargetSite(basic *BasicParams) { if basic.TargetSiteName == "" { - logrus.Fatal("请附带参数 `target_site_name:<站点名称>`") + logrus.Fatal("请附带参数 `ts_name:<目标站点名称>`") } if basic.TargetSiteUrl == "" { - logrus.Fatal("请附带参数 `target_site_url:<站点根目录 URL>`") + logrus.Fatal("请附带参数 `ts_url:<目标站点根目录 URL>`") } if !lib.ValidateURL(basic.TargetSiteUrl) { - logrus.Fatal("参数 `target_site_url:<站点根目录 URL>` 必须为 URL 格式") + logrus.Fatal("参数 `ts_url:<目标站点根目录 URL>` 必须为 URL 格式") } } diff --git a/lib/importer/valine.go b/lib/importer/valine.go new file mode 100644 index 000000000..8bc215f23 --- /dev/null +++ b/lib/importer/valine.go @@ -0,0 +1,194 @@ +package importer + +import ( + "encoding/json" + "errors" + "fmt" + "io/ioutil" + "os" + "strings" + + "github.com/ArtalkJS/ArtalkGo/lib" + "github.com/ArtalkJS/ArtalkGo/model" + "github.com/jedib0t/go-pretty/v6/table" + "github.com/sirupsen/logrus" +) + +var ValineImporter = &_ValineImporter{ + ImporterInfo: ImporterInfo{ + Name: "valine", + Desc: "从 Valine 导入数据", + Note: "", + }, +} + +type _ValineImporter struct { + ImporterInfo + TargetSite model.Site +} + +func (imp *_ValineImporter) Run(basic *BasicParams, payload []string) { + RequiredBasicTargetSite(basic) + + imp.TargetSite = SiteReady(basic) + + // 读取文件 + var jsonFile string + GetParamsFrom(payload).To(map[string]*string{ + "json_file": &jsonFile, + }) + + if jsonFile == "" { + logrus.Fatal("请附带参数 `json_file:`") + } + if _, err := os.Stat(jsonFile); errors.Is(err, os.ErrNotExist) { + logrus.Fatal("文件不存在,请检查参数 `json_file` 传入路径是否正确") + } + + buf, err := ioutil.ReadFile(jsonFile) + if err != nil { + logrus.Fatal("json 文件打开失败:", err) + } + jsonStr := string(buf) + + // 解析 JSON + comments, err := ParseValineCommentJSON(jsonStr) + if err != nil { + logrus.Fatal("json 解析失败:", err) + } + + // 汇总 + fmt.Print("# 请过目:\n\n") + + // 第一条评论 + if len(comments) > 0 { + fmt.Printf("[第一条评论]\n\n"+ + " %#v\n\n", comments[0]) + } + + PrintTable([]table.Row{ + {"目标站点名", basic.TargetSiteName}, + {"目标站点 URL", basic.TargetSiteUrl}, + {"评论数量", len(comments)}, + }) + + fmt.Print("\n") + + // 确认开始 + if !Confirm("确认开始导入吗?") { + os.Exit(0) + } + + // 准备导入评论 + fmt.Print("\n") + + ImportValineComments(basic, comments) +} + +func ParseValineCommentJSON(jsonStr string) ([]ValineComment, error) { + var list []ValineComment + err := json.Unmarshal([]byte(jsonStr), &list) + if err != nil { + return []ValineComment{}, err + } + + return list, nil +} + +func ImportValineComments(basic *BasicParams, comments []ValineComment) { + siteName := basic.TargetSiteName + + // 查找父评论 + idDict := map[string]int{} + id := 1 + + idChanges := map[uint]uint{} + + for _, c := range comments { + idDict[c.ObjectId] = id + id++ + } + + for _, c := range comments { + // PageKey + tSiteUrl := basic.TargetSiteUrl + tSiteUrl = strings.TrimSuffix(tSiteUrl, "/") + "/" + pageKey := tSiteUrl + strings.TrimPrefix(lib.GetUrlWithoutDomain(c.Url), "/") + + // 创建 user + user := model.FindCreateUser(c.Nick, c.Mail) + page := model.FindCreatePage(pageKey, "", siteName) + + if c.Link != "" { + user.Link = c.Link + } + model.UpdateUser(&user) + + // 创建新 comment 实例 + nComment := model.Comment{ + Content: c.Comment, + + PageKey: page.Key, + SiteName: basic.TargetSiteName, + + UserID: user.ID, + UA: c.UA, + IP: c.IP, + + Rid: uint(idDict[c.Rid]), + + IsCollapsed: false, + IsPending: false, + } + + // 日期恢复 + createdVal := fmt.Sprintf("%v", c.CreatedAt) + updatedVal := fmt.Sprintf("%v", c.UpdatedAt) + nComment.CreatedAt = ParseDate(createdVal) + nComment.UpdatedAt = ParseDate(updatedVal) + + // 保存到数据库 + err := lib.DB.Create(&nComment).Error + if err != nil { + logrus.Error(fmt.Sprintf("评论源 ID:%s 保存失败", c.ObjectId)) + continue + } + + idChanges[uint(idDict[c.ObjectId])] = nComment.ID + } + + // reply id 重建 + for _, newId := range idChanges { + nComment := model.FindComment(newId, siteName) + if nComment.Rid == 0 { + continue + } + if newId, isExist := idChanges[nComment.Rid]; isExist { + nComment.Rid = newId + err := lib.DB.Save(&nComment).Error + if err != nil { + logrus.Error(fmt.Sprintf("[rid 更新] new_id:%d new_rid:%d", nComment.ID, newId), err) + } + } + } + + fmt.Print("\n") + logrus.Info("RID 重构完毕") +} + +type ValineComment struct { + ObjectId string `json:"objectId"` + Nick string `json:"nick"` + IP string `json:"ip"` + Mail string `json:"mail"` + MailMd5 string `json:"mailMd5"` + IsSpam string `json:"isSpam"` + UA string `json:"ua"` + Link string `json:"link"` + Pid string `json:"pid"` + Rid string `json:"rid"` + Comment string `json:"comment"` + Url string `json:"url"` + CreatedAt string `json:"createdAt"` + UpdatedAt string `json:"updatedAt"` +} diff --git a/lib/importer/wordpress.go b/lib/importer/wordpress.go index e59412a83..c55de148a 100644 --- a/lib/importer/wordpress.go +++ b/lib/importer/wordpress.go @@ -1,6 +1,6 @@ package importer -var WordPressImporter = &_TypechoImporter{ +var WordPressImporter = &_WordPressImporter{ ImporterInfo: ImporterInfo{ Name: "wordpress", Desc: "从 WordPress 导入数据", @@ -12,5 +12,5 @@ type _WordPressImporter struct { ImporterInfo } -func (i _WordPressImporter) Run(basic *BasicParams, payload []string) { +func (imp *_WordPressImporter) Run(basic *BasicParams, payload []string) { } diff --git a/lib/utils.go b/lib/utils.go index ad78e70cd..68c776855 100644 --- a/lib/utils.go +++ b/lib/utils.go @@ -8,6 +8,7 @@ import ( "net/mail" "net/url" "os" + "regexp" "strings" "github.com/jeremywohl/flatten" @@ -77,6 +78,12 @@ func AddQueryToURL(urlStr string, queryMap map[string]string) string { return u.String() } +// "https://artalk.js.org/guide/describe.html" => "guide/describe.html" +func GetUrlWithoutDomain(urlStr string) string { + r := regexp.MustCompile(`^http[s]?:\/\/.+?\/+`) + return r.ReplaceAllString(urlStr, "") +} + // ContainsStr returns true if an str is present in a iteratee. func ContainsStr(s []string, v string) bool { for _, vv := range s { From 7dc0ea9d19dae7d1048ff18f53842eafb3313756 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Tue, 26 Oct 2021 23:18:37 +0800 Subject: [PATCH 079/349] chore: Merge some code. Signed-off-by: qwqcode --- .goreleaser.yml | 1 + http/api_admin_comment_del.go | 2 +- http/api_admin_comment_edit.go | 4 +-- http/api_admin_importer.go | 9 ++----- http/api_main_add.go | 4 +-- http/api_main_vote.go | 4 +-- lib/importer/importer.go | 17 ++++++++++++ lib/importer/typecho.go | 25 +++--------------- lib/importer/valine.go | 48 ++++++++++++---------------------- model/notify.go | 4 +-- model/query.go | 15 ++++------- 11 files changed, 55 insertions(+), 78 deletions(-) diff --git a/.goreleaser.yml b/.goreleaser.yml index fc546885d..d09a5305e 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -138,6 +138,7 @@ changelog: exclude: - '^docs:' - '^test:' + - '^chore:' release: github: diff --git a/http/api_admin_comment_del.go b/http/api_admin_comment_del.go index a1cbf7598..13476da4c 100644 --- a/http/api_admin_comment_del.go +++ b/http/api_admin_comment_del.go @@ -37,7 +37,7 @@ func ActionAdminCommentDel(c echo.Context) error { return resp } - comment := model.FindComment(uint(id), p.SiteName) + comment := model.FindComment(uint(id)) if comment.IsEmpty() { return RespError(c, "comment not found") } diff --git a/http/api_admin_comment_edit.go b/http/api_admin_comment_edit.go index 7a9ccce1a..21e25adfb 100644 --- a/http/api_admin_comment_edit.go +++ b/http/api_admin_comment_edit.go @@ -41,7 +41,7 @@ func ActionAdminCommentEdit(c echo.Context) error { return resp } - comment := model.FindComment(p.ID, p.SiteName) + comment := model.FindComment(p.ID) if comment.IsEmpty() { return RespError(c, "comment not found") } @@ -60,7 +60,7 @@ func ActionAdminCommentEdit(c echo.Context) error { // user if p.Nick != "" && p.Email != "" { - user := model.FindCreateUser(p.Nick, p.Email) + user := model.FindCreateUser(p.Nick, p.Email, p.Link) if user.ID != comment.UserID { comment.UserID = user.ID } diff --git a/http/api_admin_importer.go b/http/api_admin_importer.go index 8b86249f0..a53374190 100644 --- a/http/api_admin_importer.go +++ b/http/api_admin_importer.go @@ -77,12 +77,7 @@ func ActionAdminImporter(c echo.Context) error { // 创建 page 和 user page := model.FindCreatePage(oc.PageKey, "", p.SiteName) - user := model.FindCreateUser(oc.Nick, oc.Email) - - if oc.Link != "" { - user.Link = oc.Link - } - model.UpdateUser(&user) + user := model.FindCreateUser(oc.Nick, oc.Email, oc.Link) // 创建新 comment 实例 nComment := model.Comment{ @@ -117,7 +112,7 @@ func ActionAdminImporter(c echo.Context) error { // reply id 重建 for _, newId := range idChanges { - nComment := model.FindComment(newId, p.SiteName) + nComment := model.FindComment(newId) if nComment.Rid == 0 { continue } diff --git a/http/api_main_add.go b/http/api_main_add.go index 4bd745b17..b3c24646d 100644 --- a/http/api_main_add.go +++ b/http/api_main_add.go @@ -63,7 +63,7 @@ func ActionAdd(c echo.Context) error { // check reply comment var parentComment model.Comment if p.Rid != 0 { - parentComment = model.FindComment(p.Rid, p.SiteName) + parentComment = model.FindComment(p.Rid) if parentComment.IsEmpty() { return RespError(c, "找不到父评论") } @@ -76,7 +76,7 @@ func ActionAdd(c echo.Context) error { } // find user - user := model.FindCreateUser(p.Name, p.Email) + user := model.FindCreateUser(p.Name, p.Email, p.Link) if user.ID == 0 || page.Key == "" { logrus.Error("Cannot get user or page") return RespError(c, "评论失败") diff --git a/http/api_main_vote.go b/http/api_main_vote.go index 89ac3b48e..27eb190ff 100644 --- a/http/api_main_vote.go +++ b/http/api_main_vote.go @@ -48,7 +48,7 @@ func ActionVote(c echo.Context) error { switch { case isVoteComment: - comment = model.FindComment(p.TargetID, p.SiteName) + comment = model.FindComment(p.TargetID) if comment.IsEmpty() { return RespError(c, "comment not found") } @@ -98,7 +98,7 @@ func ActionVote(c echo.Context) error { // find user var user model.User if p.Name != "" && p.Email != "" { - user = model.FindCreateUser(p.Name, p.Email) + user = model.FindCreateUser(p.Name, p.Email, "") } // create new vote record diff --git a/lib/importer/importer.go b/lib/importer/importer.go index 780436e92..ae5cf0a5b 100644 --- a/lib/importer/importer.go +++ b/lib/importer/importer.go @@ -308,3 +308,20 @@ func HideJsonLongText(key string, text string) string { text = r.ReplaceAllString(text, fmt.Sprintf(key+": ", utf8.RuneCountInString(postText))) return text } + +// 传入 ID 变更表 (原始ID => 数据库已存在记录的ID) rid 将根据此替换 +func RebuildRid(idChanges map[uint]uint) { + for _, newId := range idChanges { + nComment := model.FindComment(newId) + if nComment.Rid == 0 { + continue + } + if newId, isExist := idChanges[nComment.Rid]; isExist { + nComment.Rid = newId + err := lib.DB.Save(&nComment).Error + if err != nil { + logrus.Error(fmt.Sprintf("[rid 更新] new_id:%d new_rid:%d", nComment.ID, newId), err) + } + } + } +} diff --git a/lib/importer/typecho.go b/lib/importer/typecho.go index 898335ccf..dc0859476 100644 --- a/lib/importer/typecho.go +++ b/lib/importer/typecho.go @@ -200,13 +200,13 @@ func (imp *_TypechoImporter) ImportComments() { idChanges := map[uint]uint{} // comment_id: old => new - // 遍历 Contents + // 导入页面 for _, c := range contents { // 创建页面 pageKey := imp.GetNewPageKey(c) page := model.FindCreatePage(pageKey, c.Title, imp.Basic.TargetSiteName) - // 查询评论 + // 导入评论 commentTotal := 0 for _, co := range comments { if co.Cid != c.Cid { @@ -214,12 +214,7 @@ func (imp *_TypechoImporter) ImportComments() { } // 创建 user - user := model.FindCreateUser(co.Author, co.Mail) - - if co.Url != "" { - user.Link = co.Url - } - model.UpdateUser(&user) + user := model.FindCreateUser(co.Author, co.Mail, co.Url) // 创建新 comment 实例 nComment := model.Comment{ @@ -258,19 +253,7 @@ func (imp *_TypechoImporter) ImportComments() { } // reply id 重建 - for _, newId := range idChanges { - nComment := model.FindComment(newId, siteName) - if nComment.Rid == 0 { - continue - } - if newId, isExist := idChanges[nComment.Rid]; isExist { - nComment.Rid = newId - err := lib.DB.Save(&nComment).Error - if err != nil { - logrus.Error(fmt.Sprintf("[rid 更新] new_id:%d new_rid:%d", nComment.ID, newId), err) - } - } - } + RebuildRid(idChanges) fmt.Print("\n") logrus.Info("RID 重构完毕") diff --git a/lib/importer/valine.go b/lib/importer/valine.go index 8bc215f23..211edeae8 100644 --- a/lib/importer/valine.go +++ b/lib/importer/valine.go @@ -95,34 +95,32 @@ func ParseValineCommentJSON(jsonStr string) ([]ValineComment, error) { return list, nil } +// PageKey (c.Url 不确定是否为完整 URL 还是一个 path) +func GetValineNewPageKey(baseUrl string, c ValineComment) string { + baseUrl = strings.TrimSuffix(baseUrl, "/") + "/" + return baseUrl + strings.TrimPrefix(lib.GetUrlWithoutDomain(c.Url), "/") +} + func ImportValineComments(basic *BasicParams, comments []ValineComment) { siteName := basic.TargetSiteName - // 查找父评论 - idDict := map[string]int{} - id := 1 - - idChanges := map[uint]uint{} + idMap := map[string]int{} // ID映射 object_id => id + idChanges := map[uint]uint{} // 变更 ID original_id => new_db_id + id := 1 for _, c := range comments { - idDict[c.ObjectId] = id + idMap[c.ObjectId] = id id++ } for _, c := range comments { - // PageKey - tSiteUrl := basic.TargetSiteUrl - tSiteUrl = strings.TrimSuffix(tSiteUrl, "/") + "/" - pageKey := tSiteUrl + strings.TrimPrefix(lib.GetUrlWithoutDomain(c.Url), "/") // 创建 user - user := model.FindCreateUser(c.Nick, c.Mail) - page := model.FindCreatePage(pageKey, "", siteName) + user := model.FindCreateUser(c.Nick, c.Mail, c.Link) - if c.Link != "" { - user.Link = c.Link - } - model.UpdateUser(&user) + // 创建 page + pageKey := GetValineNewPageKey(basic.TargetSiteUrl, c) + page := model.FindCreatePage(pageKey, "", siteName) // 创建新 comment 实例 nComment := model.Comment{ @@ -135,7 +133,7 @@ func ImportValineComments(basic *BasicParams, comments []ValineComment) { UA: c.UA, IP: c.IP, - Rid: uint(idDict[c.Rid]), + Rid: uint(idMap[c.Rid]), IsCollapsed: false, IsPending: false, @@ -154,23 +152,11 @@ func ImportValineComments(basic *BasicParams, comments []ValineComment) { continue } - idChanges[uint(idDict[c.ObjectId])] = nComment.ID + idChanges[uint(idMap[c.ObjectId])] = nComment.ID } // reply id 重建 - for _, newId := range idChanges { - nComment := model.FindComment(newId, siteName) - if nComment.Rid == 0 { - continue - } - if newId, isExist := idChanges[nComment.Rid]; isExist { - nComment.Rid = newId - err := lib.DB.Save(&nComment).Error - if err != nil { - logrus.Error(fmt.Sprintf("[rid 更新] new_id:%d new_rid:%d", nComment.ID, newId), err) - } - } - } + RebuildRid(idChanges) fmt.Print("\n") logrus.Info("RID 重构完毕") diff --git a/model/notify.go b/model/notify.go index c7251d4e2..ee729abce 100644 --- a/model/notify.go +++ b/model/notify.go @@ -33,7 +33,7 @@ func (n *Notify) FetchComment() Comment { return n.Comment } - comment := FindCommentByID(n.CommentID) + comment := FindComment(n.CommentID) n.Comment = comment return comment @@ -45,7 +45,7 @@ func (n *Notify) GetParentComment() Comment { return Comment{} } - pComment := FindComment(comment.Rid, comment.SiteName) + pComment := FindComment(comment.Rid) return pComment } diff --git a/model/query.go b/model/query.go index 5b04ce402..8d3302e9b 100644 --- a/model/query.go +++ b/model/query.go @@ -10,13 +10,7 @@ import ( "gorm.io/gorm/clause" ) -func FindComment(id uint, siteName string) Comment { - var comment Comment - lib.DB.Preload(clause.Associations).Where("id = ? AND site_name = ?", id, siteName).First(&comment) - return comment -} - -func FindCommentByID(id uint) Comment { +func FindComment(id uint) Comment { var comment Comment lib.DB.Preload(clause.Associations).Where("id = ?", id).First(&comment) return comment @@ -146,10 +140,10 @@ func FindCreatePage(pageKey string, pageTitle string, siteName string) Page { return page } -func FindCreateUser(name string, email string) User { +func FindCreateUser(name string, email string, link string) User { user := FindUser(name, email) if user.IsEmpty() { - user = NewUser(name, email) // save a new user + user = NewUser(name, email, link) // save a new user } return user } @@ -162,10 +156,11 @@ func FindCreateNotify(userID uint, lookCommentID uint) Notify { return notify } -func NewUser(name string, email string) User { +func NewUser(name string, email string, link string) User { user := User{ Name: name, Email: email, + Link: link, } err := lib.DB.Create(&user).Error From c1ed9fdd928f76132d01a241d10525415e18088a Mon Sep 17 00:00:00 2001 From: qwqcode Date: Tue, 26 Oct 2021 23:52:20 +0800 Subject: [PATCH 080/349] feat(importer): import from Twikoo. Signed-off-by: qwqcode --- lib/importer/importer.go | 24 +++++++++++ lib/importer/twikoo.go | 88 ++++++++++++++++++++++++++++++++++++++++ lib/importer/valine.go | 28 +++---------- 3 files changed, 118 insertions(+), 22 deletions(-) create mode 100644 lib/importer/twikoo.go diff --git a/lib/importer/importer.go b/lib/importer/importer.go index ae5cf0a5b..88334f73b 100644 --- a/lib/importer/importer.go +++ b/lib/importer/importer.go @@ -3,7 +3,9 @@ package importer import ( "bufio" "encoding/json" + "errors" "fmt" + "io/ioutil" "log" "os" "reflect" @@ -28,6 +30,7 @@ var Supports = []interface{}{ TypechoImporter, WordPressImporter, ValineImporter, + TwikooImporter, } func RunByName(dataType string, payload []string) { @@ -233,6 +236,27 @@ func SiteReady(basic *BasicParams) model.Site { return site } +func JsonFileReady(payload []string) string { + var jsonFile string + GetParamsFrom(payload).To(map[string]*string{ + "json_file": &jsonFile, + }) + + if jsonFile == "" { + logrus.Fatal("请附带参数 `json_file:`") + } + if _, err := os.Stat(jsonFile); errors.Is(err, os.ErrNotExist) { + logrus.Fatal("文件不存在,请检查参数 `json_file` 传入路径是否正确") + } + + buf, err := ioutil.ReadFile(jsonFile) + if err != nil { + logrus.Fatal("json 文件打开失败:", err) + } + + return string(buf) +} + func ParseVersion(s string) int64 { strList := strings.Split(s, ".") format := fmt.Sprintf("%%s%%0%ds", len(strList)) diff --git a/lib/importer/twikoo.go b/lib/importer/twikoo.go new file mode 100644 index 000000000..b67678283 --- /dev/null +++ b/lib/importer/twikoo.go @@ -0,0 +1,88 @@ +package importer + +import ( + "encoding/json" + + "github.com/ArtalkJS/ArtalkGo/model" + "github.com/sirupsen/logrus" +) + +var TwikooImporter = &_TwikooImporter{ + ImporterInfo: ImporterInfo{ + Name: "twikoo", + Desc: "从 Twikoo 导入数据", + Note: "", + }, +} + +type _TwikooImporter struct { + ImporterInfo + TargetSite model.Site +} + +func (imp *_TwikooImporter) Run(basic *BasicParams, payload []string) { + RequiredBasicTargetSite(basic) + + // 读取文件 + jsonStr := JsonFileReady(payload) + + // 解析 JSON + tComments, err := ParseTwikooCommentJSON(jsonStr) + if err != nil { + logrus.Fatal("json 解析失败:", err) + } + + // twikoo 转 valine + // @see https://github.com/imaegoo/twikoo/blob/c528c94105449c6b10c63bded6f813ceaee4bf74/src/vercel/api/index.js#L1155 + // rid 对应 _id @see https://github.com/imaegoo/twikoo/blob/c528c94105449c6b10c63bded6f813ceaee4bf74/src/vercel/api/index.js#L343 + vComments := []ValineComment{} + for _, tc := range tComments { + vComments = append(vComments, ValineComment{ + ObjectId: tc.ID, + Nick: tc.Nick, + IP: tc.IP, + Mail: tc.Mail, + MailMd5: tc.MailMd5, + IsSpam: tc.IsSpam, + UA: tc.UA, + Link: tc.Link, + Pid: tc.Pid, + Rid: tc.Rid, + Comment: tc.Comment, + Url: tc.Url, + CreatedAt: tc.Created, + UpdatedAt: tc.Updated, + }) + } + + ImportValine(basic, payload, vComments) +} + +func ParseTwikooCommentJSON(jsonStr string) ([]TwikooComment, error) { + var list []TwikooComment + err := json.Unmarshal([]byte(jsonStr), &list) + if err != nil { + return []TwikooComment{}, err + } + return list, nil +} + +type TwikooComment struct { + ID string `json:"_id"` + Uid string `json:"uid"` + Nick string `json:"nick"` + Mail string `json:"mail"` + MailMd5 string `json:"mailMd5"` + Link string `json:"link"` + UA string `json:"ua"` + IP string `json:"ip"` + Master string `json:"master"` + Url string `json:"url"` + Href string `json:"href"` + Comment string `json:"comment"` + Pid string `json:"pid"` + Rid string `json:"rid"` + IsSpam string `json:"isSpam"` + Created string `json:"created"` + Updated string `json:"updated"` +} diff --git a/lib/importer/valine.go b/lib/importer/valine.go index 211edeae8..aba383d72 100644 --- a/lib/importer/valine.go +++ b/lib/importer/valine.go @@ -2,9 +2,7 @@ package importer import ( "encoding/json" - "errors" "fmt" - "io/ioutil" "os" "strings" @@ -24,32 +22,13 @@ var ValineImporter = &_ValineImporter{ type _ValineImporter struct { ImporterInfo - TargetSite model.Site } func (imp *_ValineImporter) Run(basic *BasicParams, payload []string) { RequiredBasicTargetSite(basic) - imp.TargetSite = SiteReady(basic) - // 读取文件 - var jsonFile string - GetParamsFrom(payload).To(map[string]*string{ - "json_file": &jsonFile, - }) - - if jsonFile == "" { - logrus.Fatal("请附带参数 `json_file:`") - } - if _, err := os.Stat(jsonFile); errors.Is(err, os.ErrNotExist) { - logrus.Fatal("文件不存在,请检查参数 `json_file` 传入路径是否正确") - } - - buf, err := ioutil.ReadFile(jsonFile) - if err != nil { - logrus.Fatal("json 文件打开失败:", err) - } - jsonStr := string(buf) + jsonStr := JsonFileReady(payload) // 解析 JSON comments, err := ParseValineCommentJSON(jsonStr) @@ -57,6 +36,10 @@ func (imp *_ValineImporter) Run(basic *BasicParams, payload []string) { logrus.Fatal("json 解析失败:", err) } + ImportValine(basic, payload, comments) +} + +func ImportValine(basic *BasicParams, payload []string, comments []ValineComment) { // 汇总 fmt.Print("# 请过目:\n\n") @@ -82,6 +65,7 @@ func (imp *_ValineImporter) Run(basic *BasicParams, payload []string) { // 准备导入评论 fmt.Print("\n") + SiteReady(basic) ImportValineComments(basic, comments) } From 229ade32c31a72aacb898808165f02c5ba6cd7fd Mon Sep 17 00:00:00 2001 From: qwqcode Date: Wed, 27 Oct 2021 08:49:57 +0800 Subject: [PATCH 081/349] fix(importer): json decode by universal type. Signed-off-by: qwqcode --- lib/importer/twikoo.go | 3 ++- lib/importer/valine.go | 2 +- lib/utils.go | 21 +++++++++++++++++++++ 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/lib/importer/twikoo.go b/lib/importer/twikoo.go index b67678283..4c055a030 100644 --- a/lib/importer/twikoo.go +++ b/lib/importer/twikoo.go @@ -3,6 +3,7 @@ package importer import ( "encoding/json" + "github.com/ArtalkJS/ArtalkGo/lib" "github.com/ArtalkJS/ArtalkGo/model" "github.com/sirupsen/logrus" ) @@ -60,7 +61,7 @@ func (imp *_TwikooImporter) Run(basic *BasicParams, payload []string) { func ParseTwikooCommentJSON(jsonStr string) ([]TwikooComment, error) { var list []TwikooComment - err := json.Unmarshal([]byte(jsonStr), &list) + err := json.Unmarshal([]byte(lib.JsonArrItemAnyWrapInStr(jsonStr)), &list) if err != nil { return []TwikooComment{}, err } diff --git a/lib/importer/valine.go b/lib/importer/valine.go index aba383d72..15b469b16 100644 --- a/lib/importer/valine.go +++ b/lib/importer/valine.go @@ -71,7 +71,7 @@ func ImportValine(basic *BasicParams, payload []string, comments []ValineComment func ParseValineCommentJSON(jsonStr string) ([]ValineComment, error) { var list []ValineComment - err := json.Unmarshal([]byte(jsonStr), &list) + err := json.Unmarshal([]byte(lib.JsonArrItemAnyWrapInStr(jsonStr)), &list) if err != nil { return []ValineComment{}, err } diff --git a/lib/utils.go b/lib/utils.go index 68c776855..3d630013f 100644 --- a/lib/utils.go +++ b/lib/utils.go @@ -5,6 +5,7 @@ import ( "crypto/md5" "encoding/hex" "encoding/json" + "fmt" "net/mail" "net/url" "os" @@ -104,6 +105,26 @@ func RemoveBlankStrings(s []string) []string { return r } +func JsonArrItemAnyWrapInStr(jsonStr string) string { + var raw []map[string]interface{} + json.Unmarshal([]byte(jsonStr), &raw) + var dest []interface{} + for _, item := range raw { + dest = append(dest, JsonAnyWrapInStr(item)) + } + j, _ := json.Marshal(dest) + return string(j) +} + +// {"test":233} => {"test": "233"}, {"test": ["233"]} => {"test": "[\"233\"]"} +func JsonAnyWrapInStr(item map[string]interface{}) map[string]string { + dest := map[string]string{} + for k, v := range item { + dest[k] = fmt.Sprintf("%v", v) + } + return dest +} + func ValidateEmail(email string) bool { _, err := mail.ParseAddress(email) return err == nil From cabc3a96d8ca6e7bcfbbde18d25c9bd9f62ff61b Mon Sep 17 00:00:00 2001 From: qwqcode Date: Wed, 27 Oct 2021 15:33:44 +0800 Subject: [PATCH 082/349] feat(artrans): Export and Import Artrans type data. Signed-off-by: qwqcode --- .gitignore | 2 + .vscode/settings.json | 2 + cmd/export.go | 68 ++++++++++++++ cmd/import.go | 31 ++++++- config/config.go | 5 +- go.mod | 10 +- go.sum | 29 ++++-- lib/importer/artrans.go | 132 ++++++++++++++++++++++++++ lib/importer/importer.go | 193 +++++++++++++++++++++++++++------------ lib/importer/twikoo.go | 60 +++++------- lib/importer/typecho.go | 14 +-- lib/importer/valine.go | 147 ++++++----------------------- lib/utils.go | 33 ++++++- model/artran.go | 40 ++++++++ model/comment.go | 33 ++++++- model/query.go | 8 ++ 16 files changed, 559 insertions(+), 248 deletions(-) create mode 100644 cmd/export.go create mode 100644 lib/importer/artrans.go create mode 100644 model/artran.go diff --git a/.gitignore b/.gitignore index 1dd172710..e006b8639 100644 --- a/.gitignore +++ b/.gitignore @@ -14,6 +14,8 @@ # Dependency directories (remove the comment below to include it) # vendor/ +.history + artalk-go.yml config.yml .release-env diff --git a/.vscode/settings.json b/.vscode/settings.json index 2e66c975a..dc936142c 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -2,6 +2,8 @@ "cSpell.words": [ "akismet", "artalk", + "artran", + "Artrans", "gomail", "Goreleaser", "gorm", diff --git a/cmd/export.go b/cmd/export.go new file mode 100644 index 000000000..acdf4ee43 --- /dev/null +++ b/cmd/export.go @@ -0,0 +1,68 @@ +package cmd + +import ( + "encoding/json" + "fmt" + "os" + "path/filepath" + + "github.com/ArtalkJS/ArtalkGo/lib" + "github.com/ArtalkJS/ArtalkGo/model" + "github.com/sirupsen/logrus" + "github.com/spf13/cobra" +) + +var exportCmd = &cobra.Command{ + Use: "export", + Aliases: []string{}, + Short: "数据搬家 - 迁出", + Long: "\n# 数据搬家 - 迁出\n\n 将所有数据从 ArtalkGo 导出,用作备份,或迁移至其他地方\n 打包所有数据并导出成 “ArtalkGo 数据行囊 (Artrans)”,为数据搬家做准备\n" + ` +- 重新导入 ArtalkGo,可执行: artalk-go import <数据行囊文件路径> +- 文档:https://artalk.js.org/guide/transfer.html +`, + Run: func(cmd *cobra.Command, args []string) { + comments := []model.Comment{} + lib.DB.Find(&comments) + + artrans := []model.Artran{} + for _, c := range comments { + ct := c.ToArtran() + artrans = append(artrans, ct) + } + + jsonByte, err := json.Marshal(artrans) + if err != nil { + logrus.Fatal(err) + } + jsonStr := string(jsonByte) + + outputFile := cmd.Flag("output").Value.String() + if outputFile == "" { + // write to stdout + fmt.Println(jsonStr) + } else { + // mkdir -p + if err := lib.EnsureDir(filepath.Dir(outputFile)); err != nil { + logrus.Fatal(err) + } + + // touch + f, err := os.Create(outputFile) + if err != nil { + logrus.Fatal(err) + } + + // > + _, err2 := f.WriteString(jsonStr) + if err2 != nil { + logrus.Fatal(err2) + } + } + }, +} + +func init() { + rootCmd.AddCommand(exportCmd) + + flagP(exportCmd, "output", "o", "", "Write to file instead of stdout") +} diff --git a/cmd/import.go b/cmd/import.go index 76ce0538a..d47a2e4ee 100644 --- a/cmd/import.go +++ b/cmd/import.go @@ -1,18 +1,43 @@ package cmd import ( + "errors" + "io/ioutil" + "os" + "github.com/ArtalkJS/ArtalkGo/lib/importer" + "github.com/sirupsen/logrus" "github.com/spf13/cobra" ) var importCmd = &cobra.Command{ - Use: "import", + Use: "import <数据行囊文件路径>", Aliases: []string{}, - Short: "数据搬家 - 导入", - Long: "\n# 数据搬家 - 导入\n\n 从其他评论系统迁移数据到 ArtalkGo\n" + ` + Short: "数据搬家 - 迁入", + Long: "\n# 数据搬家 - 迁入\n\n 从其他评论系统迁移数据到 ArtalkGo\n" + ` - 例如:artalk-go import typecho [参数] - 文档:https://artalk.js.org/guide/transfer.html `, + Run: func(cmd *cobra.Command, args []string) { + parcelFile := args[0] + if _, err := os.Stat(parcelFile); errors.Is(err, os.ErrNotExist) { + logrus.Fatal("`数据行囊` 文件不存在,请检查路径是否正确") + } + + buf, err := ioutil.ReadFile(parcelFile) + if err != nil { + logrus.Fatal("数据行囊文件打开失败:", err) + } + + content := string(buf) + basic := importer.GetBasicParamsFrom(args[1:]) + basic.UrlResolver = false // 默认关闭 URL 解析器:因为 pageKey 是完整,且站点隔离开 + importer.ImportArtransByStr(basic, content) + + logrus.Info("导入结束") + }, + Args: cobra.MinimumNArgs(1), + ArgAliases: importer.GetSupportNames(), } func init() { diff --git a/config/config.go b/config/config.go index 9c66ec1df..65726f3e8 100644 --- a/config/config.go +++ b/config/config.go @@ -1,7 +1,6 @@ package config import ( - "fmt" "strings" "github.com/sirupsen/logrus" @@ -129,8 +128,8 @@ func Init(cfgFile string) { viper.SetEnvKeyReplacer(strings.NewReplacer(".", "_")) if err := viper.ReadInConfig(); err == nil { - fmt.Print("\n") - fmt.Println("- Using ArtalkGo config file:", viper.ConfigFileUsed()) + // fmt.Print("\n") + // fmt.Println("- Using ArtalkGo config file:", viper.ConfigFileUsed()) } Instance = &Config{} diff --git a/go.mod b/go.mod index 5ed4d04ea..73fe6bb64 100644 --- a/go.mod +++ b/go.mod @@ -6,6 +6,7 @@ require ( github.com/PuerkitoBio/goquery v1.7.1 github.com/allegro/bigcache/v3 v3.0.0 github.com/araddon/dateparse v0.0.0-20210429162001-6b43995a97de + github.com/cheggaaa/pb/v3 v3.0.8 github.com/eko/gocache/v2 v2.1.0 github.com/elliotchance/phpserialize v1.3.1 github.com/fsnotify/fsnotify v1.5.1 // indirect @@ -15,7 +16,8 @@ require ( github.com/kr/text v0.2.0 // indirect github.com/labstack/echo/v4 v4.5.0 github.com/markbates/pkger v0.17.1 - github.com/mattn/go-isatty v0.0.13 // indirect + github.com/mattn/go-isatty v0.0.14 // indirect + github.com/mattn/go-runewidth v0.0.13 // indirect github.com/mattn/go-sqlite3 v1.14.8 // indirect github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect github.com/mitchellh/mapstructure v1.4.1 @@ -31,10 +33,10 @@ require ( github.com/steambap/captcha v1.4.1 github.com/x-cray/logrus-prefixed-formatter v0.5.2 github.com/yuin/goldmark v1.4.0 - golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 // indirect + golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 // indirect golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d // indirect - golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf // indirect - golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b // indirect + golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359 // indirect + golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect golang.org/x/text v0.3.7 // indirect gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f // indirect diff --git a/go.sum b/go.sum index 3a6249e56..b5232eff9 100644 --- a/go.sum +++ b/go.sum @@ -51,6 +51,8 @@ github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbt github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= +github.com/VividCortex/ewma v1.1.1 h1:MnEK4VOv6n0RSY4vtRe3h11qjxL3+t0B8yOL8iMXdcM= +github.com/VividCortex/ewma v1.1.1/go.mod h1:2Tkkvm3sRDVXaiyucHiACn4cqf7DpdyLvmxzcbUokwA= github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= github.com/XiaoMi/pegasus-go-client v0.0.0-20210427083443-f3b6b08bc4c2 h1:pami0oPhVosjOu/qRHepRmdjD6hGILF7DBr+qQZeP10= github.com/XiaoMi/pegasus-go-client v0.0.0-20210427083443-f3b6b08bc4c2/go.mod h1:jNIx5ykW1MroBuaTja9+VpglmaJOUzezumfhLlER3oY= @@ -96,6 +98,8 @@ github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cheggaaa/pb/v3 v3.0.8 h1:bC8oemdChbke2FHIIGy9mn4DPJ2caZYQnfbRqwmdCoA= +github.com/cheggaaa/pb/v3 v3.0.8/go.mod h1:UICbiLec/XO6Hw6k+BHEtHeQFzzBH4i2/qk/ow1EJTA= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= @@ -155,6 +159,8 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.m github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= +github.com/fatih/color v1.10.0 h1:s36xzo75JdqLaaWoiEHk767eHiwo0598uUxyfiPkDsg= +github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM= github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw= github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4= @@ -437,12 +443,14 @@ github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hd github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= -github.com/mattn/go-isatty v0.0.13 h1:qdl+GuBjcsKKDco5BsxPJlId98mSWNKqYA+Co0SC1yA= -github.com/mattn/go-isatty v0.0.13/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= +github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= -github.com/mattn/go-runewidth v0.0.10 h1:CoZ3S2P7pvtP45xOtBw+/mDL2z0RKI576gSkzRRpdGg= github.com/mattn/go-runewidth v0.0.10/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk= +github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk= +github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU= +github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mattn/go-sqlite3 v1.14.5/go.mod h1:WVKg1VTActs4Qso6iwGbiFih2UIHo0ENGwNd0Lj+XmI= github.com/mattn/go-sqlite3 v1.14.8 h1:gDp86IdQsN/xWjIEmr9MF6o9mpksUgh0fu+9ByFxzIU= github.com/mattn/go-sqlite3 v1.14.8/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= @@ -565,8 +573,9 @@ github.com/qwqcode/go-aliyun-email v0.0.0-20180120030821-cb6e7b1382bf/go.mod h1: github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/rifflock/lfshook v0.0.0-20180920164130-b9218ef580f5 h1:mZHayPoR0lNmnHyvtYjDeq0zlVHn9K/ZXoy17ylucdo= github.com/rifflock/lfshook v0.0.0-20180920164130-b9218ef580f5/go.mod h1:GEXHk5HgEKCvEIIrSpFI3ozzG5xOKA2DVlEX/gGnewM= -github.com/rivo/uniseg v0.1.0 h1:+2KBaVoUmb9XzDsrx/Ct0W/EYOSFf/nWTauy++DprtY= github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= +github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= @@ -700,8 +709,8 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= -golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 h1:HWj/xjIHfjYU5nVXpTM0s39J9CbLn7Cc5a7IC5rwsMQ= -golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 h1:7I4JAnoQBe7ZtJcBaYHi5UtiO8tQHbUSXxL+pnGRANg= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -882,11 +891,11 @@ golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf h1:2ucpDCmfkl8Bd/FsLtiD653Wf96cW37s+iGx93zsu4k= -golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359 h1:2B5p2L5IfGiD7+b9BOoRMC6DgObAVZV+Fsp050NqXik= +golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b h1:9zKuko04nR4gjZ4+DNjHqRlAJqbJETHwiNKDqTfOjfE= -golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= diff --git a/lib/importer/artrans.go b/lib/importer/artrans.go new file mode 100644 index 000000000..5ae9312c1 --- /dev/null +++ b/lib/importer/artrans.go @@ -0,0 +1,132 @@ +package importer + +import ( + "fmt" + "os" + + "github.com/ArtalkJS/ArtalkGo/lib" + "github.com/ArtalkJS/ArtalkGo/model" + "github.com/cheggaaa/pb/v3" + "github.com/jedib0t/go-pretty/v6/table" + "github.com/sirupsen/logrus" +) + +func ImportArtransByStr(basic *BasicParams, str string) { + // 解析内容 + comments := []model.Artran{} + JsonDecodeFAS(str, &comments) + + ImportArtrans(basic, comments) +} + +func ImportArtrans(basic *BasicParams, comments []model.Artran) { + // 汇总 + fmt.Print("# 请过目:\n\n") + + // 第一条评论 + PrintEncodeData("第一条评论", comments[0]) + + showTSiteName := basic.TargetSiteName + showTSiteUrl := basic.TargetSiteUrl + if showTSiteName == "" { + showTSiteName = "未指定" + } + if showTSiteUrl == "" { + showTSiteUrl = "未指定" + } + + PrintTable([]table.Row{ + {"目标站点名", showTSiteName}, + {"目标站点 URL", showTSiteUrl}, + {"评论数量", len(comments)}, + }) + + fmt.Print("\n") + + // 确认开始 + if !Confirm("确认开始导入吗?") { + os.Exit(0) + } + + // 准备导入评论 + fmt.Print("\n") + + // 执行导入 + idMap := map[string]int{} // ID 映射表 object_id => id + idChanges := map[uint]uint{} // ID 变更表 original_id => new_db_id + + // 生成 ID 映射表 + id := 1 + for _, c := range comments { + idMap[c.ID] = id + id++ + } + + // 进度条 + bar := pb.StartNew(len(comments)) + + // 遍历导入 comments + for _, c := range comments { + // 准备 site + site := SiteReady(c.SiteName, c.SiteUrls) + + // 准备 user + user := model.FindCreateUser(c.Nick, c.Email, c.Link) + if c.Password != "" { + user.Password = c.Password + } + if c.BadgeName != "" { + user.BadgeName = c.BadgeName + } + if c.BadgeColor != "" { + user.BadgeColor = c.BadgeColor + } + model.UpdateUser(&user) + + // 准备 page + nPageKey := c.PageKey + if basic.UrlResolver { // 使用 URL 解析器 + nPageKey = UrlResolverGetPageKey(basic.TargetSiteUrl, c.PageKey) + } + + page := model.FindCreatePage(nPageKey, c.PageTitle, c.SiteName) + page.AdminOnly = c.PageAdminOnly == lib.ToString(true) + model.UpdatePage(&page) + + // 创建新 comment 实例 + nComment := model.Comment{ + Rid: uint(idMap[c.Rid]), + + Content: c.Content, + + UA: c.UA, + IP: c.IP, + + IsCollapsed: c.IsCollapsed == lib.ToString(true), + IsPending: c.IsPending == lib.ToString(true), + + UserID: user.ID, + PageKey: page.Key, + SiteName: site.Name, + } + + // 日期恢复 + nComment.CreatedAt = ParseDate(c.CreatedAt) + nComment.UpdatedAt = ParseDate(c.UpdatedAt) + + // 保存到数据库 + err := lib.DB.Create(&nComment).Error + if err != nil { + logrus.Error(fmt.Sprintf("评论源 ID:%s 保存失败", c.ID)) + continue + } + + idChanges[uint(idMap[c.ID])] = nComment.ID + + bar.Increment() + } + bar.Finish() + + // reply id 重建 + RebuildRid(idChanges) +} diff --git a/lib/importer/importer.go b/lib/importer/importer.go index 88334f73b..3cd29a587 100644 --- a/lib/importer/importer.go +++ b/lib/importer/importer.go @@ -7,7 +7,9 @@ import ( "fmt" "io/ioutil" "log" + "net/url" "os" + "path/filepath" "reflect" "regexp" "strconv" @@ -94,68 +96,46 @@ func GetSupportNames() []string { return types } -type _getParamsTo struct { - To func(variables map[string]*string) -} - -func GetParamsFrom(payload []string) _getParamsTo { - a := _getParamsTo{} - a.To = func(variables map[string]*string) { - for _, pVal := range payload { - for fromName, toVar := range variables { - if !strings.HasPrefix(pVal, fromName+":") { - continue - } - - *toVar = strings.TrimPrefix(pVal, fromName+":") - break - } - } - } - return a -} - -func GetArrayParamsFrom(payload []string, key string) []string { - arr := []string{} - for _, pVal := range payload { - if strings.HasPrefix(pVal, key+":") { - arr = append(arr, strings.TrimPrefix(pVal, key+":")) - } - } - - return arr -} - type BasicParams struct { TargetSiteName string TargetSiteUrl string + + UrlResolver bool } func GetBasicParamsFrom(payload []string) *BasicParams { basic := BasicParams{} - GetParamsFrom(payload).To(map[string]*string{ - "ts_name": &basic.TargetSiteName, - "ts_url": &basic.TargetSiteUrl, + + basic.UrlResolver = true // 默认开启 + + GetParamsFrom(payload).To(map[string]interface{}{ + "t_name": &basic.TargetSiteName, + "t_url": &basic.TargetSiteUrl, + "t_url_resolver": &basic.UrlResolver, }) + if !basic.UrlResolver { + logrus.Warn("目标站点 URL 解析器已关闭") + } + return &basic } func RequiredBasicTargetSite(basic *BasicParams) { if basic.TargetSiteName == "" { - logrus.Fatal("请附带参数 `ts_name:<目标站点名称>`") + logrus.Fatal("请附带参数 `t_name:<目标站点名称>`") } if basic.TargetSiteUrl == "" { - logrus.Fatal("请附带参数 `ts_url:<目标站点根目录 URL>`") + logrus.Fatal("请附带参数 `t_url:<目标站点根目录 URL>`") } if !lib.ValidateURL(basic.TargetSiteUrl) { - logrus.Fatal("参数 `ts_url:<目标站点根目录 URL>` 必须为 URL 格式") + logrus.Fatal("参数 `t_url:<目标站点根目录 URL>` 必须为 URL 格式") } } func DbReady(payload []string) *gorm.DB { var host, port, dbName, user, password, dbType, dbFile string - GetParamsFrom(payload).To(map[string]*string{ + GetParamsFrom(payload).To(map[string]interface{}{ "host": &host, "port": &port, "db_name": &dbName, @@ -198,34 +178,43 @@ func DbReady(payload []string) *gorm.DB { } // 站点准备 -func SiteReady(basic *BasicParams) model.Site { - site := model.FindSite(basic.TargetSiteName) +func SiteReady(tSiteName string, tSiteUrls string) model.Site { + site := model.FindSite(tSiteName) if site.IsEmpty() { // 创建新站点 site = model.Site{} - site.Name = basic.TargetSiteName - site.Urls = basic.TargetSiteUrl + site.Name = tSiteName + site.Urls = tSiteUrls err := lib.DB.Create(&site).Error if err != nil { logrus.Fatal("站点创建失败") } } else { - sic := site.ToCooked() + // 追加 URL + siteCooked := site.ToCooked() - // 加 URL - urlExist := false - for _, url := range sic.Urls { - if url == site.Urls { - urlExist = true - break + urlExist := func(tUrl string) bool { + for _, u := range siteCooked.Urls { + if u == tUrl { + return true + } + } + return false + } + + tUrlsSpit := strings.Split(tSiteUrls, ",") + + rUrls := []string{} + for _, u := range tUrlsSpit { + if !urlExist(u) { + rUrls = append(rUrls, u) // prepend 不存在的站点 } } - if !urlExist { - urls := []string{} - urls = append(urls, basic.TargetSiteUrl) // prepend - urls = append(urls, sic.Urls...) - site.Urls = strings.Join(urls, ",") + if len(rUrls) > 0 { + // 保存 + rUrls = append(rUrls, siteCooked.Urls...) + site.Urls = strings.Join(rUrls, ",") err := lib.DB.Save(&site).Error if err != nil { logrus.Fatal("站点数据更新失败") @@ -238,7 +227,7 @@ func SiteReady(basic *BasicParams) model.Site { func JsonFileReady(payload []string) string { var jsonFile string - GetParamsFrom(payload).To(map[string]*string{ + GetParamsFrom(payload).To(map[string]interface{}{ "json_file": &jsonFile, }) @@ -257,6 +246,34 @@ func JsonFileReady(payload []string) string { return string(buf) } +// PageKey (commentUrlVal 不确定是否为完整 URL 还是一个 path) +func UrlResolverGetPageKey(baseUrl string, commentUrlVal string) string { + baseUrl = strings.TrimSuffix(baseUrl, "/") + "/" + path := strings.TrimPrefix(lib.GetUrlWithoutDomain(commentUrlVal), "/") + + // 解决拼接路径中的相对地址,例如:https://atk.xxx/abc/../artalk => https://atk.xxx/artalk + u, err := url.ParseRequestURI(baseUrl + path) + if err != nil { + logrus.Error("GetNewPageKey Error: ", err) + return commentUrlVal + } + + pathIsDir := strings.HasSuffix(u.Path, "/") // path 以 / 结尾 + abs, absErr := filepath.Abs(u.Path) // 相对路径转绝对路径 + if absErr != nil { + return u.String() + } + + if pathIsDir { + u.Path = abs + "/" // 加上 "/" + // 这是一个 patch: 因为 filepath.Abs() 结果无论是 目录还是文件,都会去掉 / + } else { + u.Path = abs + } + + return u.String() +} + func ParseVersion(s string) int64 { strList := strings.Split(s, ".") format := fmt.Sprintf("%%s%%0%ds", len(strList)) @@ -281,6 +298,50 @@ func ParseDate(s string) time.Time { return t } +type _getParamsTo struct { + To func(variables map[string]interface{}) +} + +func GetParamsFrom(payload []string) _getParamsTo { + a := _getParamsTo{} + a.To = func(variables map[string]interface{}) { + for _, pVal := range payload { + for fromName, toVar := range variables { + if !strings.HasPrefix(pVal, fromName+":") { + continue + } + + valStr := strings.TrimPrefix(pVal, fromName+":") + + switch toVar.(type) { + case *string: + *toVar.(*string) = valStr + case *bool: + *toVar.(*bool) = strings.EqualFold(valStr, "true") + case *int: + num, err := strconv.Atoi(valStr) + if err != nil { + *toVar.(*int) = num + } + } + break + } + } + } + return a +} + +func GetArrayParamsFrom(payload []string, key string) []string { + arr := []string{} + for _, pVal := range payload { + if strings.HasPrefix(pVal, key+":") { + arr = append(arr, strings.TrimPrefix(pVal, key+":")) + } + } + + return arr +} + func PrintTable(rows []table.Row) { t := table.NewWriter() t.SetOutputMirror(os.Stdout) @@ -296,6 +357,14 @@ func PrintTable(rows []table.Row) { t.Render() } +func PrintEncodeData(dataType string, val interface{}) { + fmt.Print(SprintEncodeData(dataType, val)) +} + +func SprintEncodeData(dataType string, val interface{}) string { + return fmt.Sprintf("[%s]\n\n %#v\n\n", dataType, val) +} + func Confirm(s string) bool { r := bufio.NewReader(os.Stdin) @@ -321,6 +390,15 @@ func Confirm(s string) bool { } } +// Json Decode (FAS: Fields All String Type) +// 解析 json 为字段全部是 string 类型的 struct +func JsonDecodeFAS(str string, fasStructure interface{}) { + err := json.Unmarshal([]byte(lib.JsonObjInArrAnyStr(str)), fasStructure) // lib.ToString() + if err != nil { + logrus.Fatal("JSON 解析失败 ", err) + } +} + func HideJsonLongText(key string, text string) string { r := regexp.MustCompile(key + `:"(.+?)"`) sm := r.FindStringSubmatch(text) @@ -348,4 +426,7 @@ func RebuildRid(idChanges map[uint]uint) { } } } + + fmt.Print("\n") + logrus.Info("RID 重构完毕") } diff --git a/lib/importer/twikoo.go b/lib/importer/twikoo.go index 4c055a030..5b43d6175 100644 --- a/lib/importer/twikoo.go +++ b/lib/importer/twikoo.go @@ -1,11 +1,8 @@ package importer import ( - "encoding/json" - "github.com/ArtalkJS/ArtalkGo/lib" "github.com/ArtalkJS/ArtalkGo/model" - "github.com/sirupsen/logrus" ) var TwikooImporter = &_TwikooImporter{ @@ -27,48 +24,39 @@ func (imp *_TwikooImporter) Run(basic *BasicParams, payload []string) { // 读取文件 jsonStr := JsonFileReady(payload) - // 解析 JSON - tComments, err := ParseTwikooCommentJSON(jsonStr) - if err != nil { - logrus.Fatal("json 解析失败:", err) - } + // 解析 Twikoo JSON + var tComments []TwikooCommentFAS + JsonDecodeFAS(jsonStr, &tComments) - // twikoo 转 valine + // twikoo 转 ArtalkTransferParcel // @see https://github.com/imaegoo/twikoo/blob/c528c94105449c6b10c63bded6f813ceaee4bf74/src/vercel/api/index.js#L1155 // rid 对应 _id @see https://github.com/imaegoo/twikoo/blob/c528c94105449c6b10c63bded6f813ceaee4bf74/src/vercel/api/index.js#L343 - vComments := []ValineComment{} + tp := []model.Artran{} for _, tc := range tComments { - vComments = append(vComments, ValineComment{ - ObjectId: tc.ID, - Nick: tc.Nick, - IP: tc.IP, - Mail: tc.Mail, - MailMd5: tc.MailMd5, - IsSpam: tc.IsSpam, - UA: tc.UA, - Link: tc.Link, - Pid: tc.Pid, - Rid: tc.Rid, - Comment: tc.Comment, - Url: tc.Url, - CreatedAt: tc.Created, - UpdatedAt: tc.Updated, + tp = append(tp, model.Artran{ + ID: tc.ID, + Rid: tc.Rid, + Content: tc.Comment, + UA: tc.UA, + IP: tc.IP, + IsCollapsed: lib.ToString(false), + IsPending: lib.ToString(tc.IsSpam == "true"), + CreatedAt: tc.Created, + UpdatedAt: tc.Updated, + Nick: tc.Nick, + Email: tc.Mail, + Link: tc.Link, + PageKey: tc.Url, + SiteName: basic.TargetSiteName, + SiteUrls: basic.TargetSiteUrl, }) } - ImportValine(basic, payload, vComments) -} - -func ParseTwikooCommentJSON(jsonStr string) ([]TwikooComment, error) { - var list []TwikooComment - err := json.Unmarshal([]byte(lib.JsonArrItemAnyWrapInStr(jsonStr)), &list) - if err != nil { - return []TwikooComment{}, err - } - return list, nil + ImportArtrans(basic, tp) } -type TwikooComment struct { +// TwikooCommentFAS (Fields All String type) +type TwikooCommentFAS struct { ID string `json:"_id"` Uid string `json:"uid"` Nick string `json:"nick"` diff --git a/lib/importer/typecho.go b/lib/importer/typecho.go index dc0859476..d4479ba10 100644 --- a/lib/importer/typecho.go +++ b/lib/importer/typecho.go @@ -61,7 +61,7 @@ func (imp *_TypechoImporter) Run(basic *BasicParams, payload []string) { imp.Basic = basic typechoDB := DbReady(payload) - GetParamsFrom(payload).To(map[string]*string{ + GetParamsFrom(payload).To(map[string]interface{}{ "prefix": &imp.DbPrefix, "rewrite_post": &imp.RewritePost, "rewrite_page": &imp.RewritePage, @@ -132,9 +132,7 @@ func (imp *_TypechoImporter) Run(basic *BasicParams, payload []string) { pageKeyEgPage := "" for _, c := range imp.Contents { if c.Type == "post" { - firstPost := fmt.Sprintf("[第一篇文章]\n\n"+ - " %#v\n\n", imp.Contents[0]) - + firstPost := SprintEncodeData("第一篇文章", imp.Contents[0]) fmt.Print(HideJsonLongText("Text", firstPost)) pageKeyEgPost = imp.GetNewPageKey(c) fmt.Printf(" -> 生成 PageKey: %#v\n\n", pageKeyEgPost) @@ -150,8 +148,7 @@ func (imp *_TypechoImporter) Run(basic *BasicParams, payload []string) { } if len(imp.Comments) > 0 { - fmt.Printf("[第一条评论]\n\n"+ - " %#v\n\n", imp.Comments[0]) + PrintEncodeData("第一条评论", imp.Comments[0]) } PrintTable([]table.Row{ @@ -181,7 +178,7 @@ func (imp *_TypechoImporter) Run(basic *BasicParams, payload []string) { fmt.Println() // 准备新的 site - imp.TargetSite = SiteReady(basic) + imp.TargetSite = SiteReady(basic.TargetSiteName, basic.TargetSiteUrl) // 开始执行导入 imp.ImportComments() @@ -254,9 +251,6 @@ func (imp *_TypechoImporter) ImportComments() { // reply id 重建 RebuildRid(idChanges) - - fmt.Print("\n") - logrus.Info("RID 重构完毕") } // 获取新的 PageKey (根据重写规则) diff --git a/lib/importer/valine.go b/lib/importer/valine.go index 15b469b16..afe5aa709 100644 --- a/lib/importer/valine.go +++ b/lib/importer/valine.go @@ -1,15 +1,8 @@ package importer import ( - "encoding/json" - "fmt" - "os" - "strings" - "github.com/ArtalkJS/ArtalkGo/lib" "github.com/ArtalkJS/ArtalkGo/model" - "github.com/jedib0t/go-pretty/v6/table" - "github.com/sirupsen/logrus" ) var ValineImporter = &_ValineImporter{ @@ -30,123 +23,37 @@ func (imp *_ValineImporter) Run(basic *BasicParams, payload []string) { // 读取文件 jsonStr := JsonFileReady(payload) - // 解析 JSON - comments, err := ParseValineCommentJSON(jsonStr) - if err != nil { - logrus.Fatal("json 解析失败:", err) - } - - ImportValine(basic, payload, comments) -} - -func ImportValine(basic *BasicParams, payload []string, comments []ValineComment) { - // 汇总 - fmt.Print("# 请过目:\n\n") - - // 第一条评论 - if len(comments) > 0 { - fmt.Printf("[第一条评论]\n\n"+ - " %#v\n\n", comments[0]) - } - - PrintTable([]table.Row{ - {"目标站点名", basic.TargetSiteName}, - {"目标站点 URL", basic.TargetSiteUrl}, - {"评论数量", len(comments)}, - }) - - fmt.Print("\n") - - // 确认开始 - if !Confirm("确认开始导入吗?") { - os.Exit(0) - } - - // 准备导入评论 - fmt.Print("\n") - - SiteReady(basic) - ImportValineComments(basic, comments) -} - -func ParseValineCommentJSON(jsonStr string) ([]ValineComment, error) { - var list []ValineComment - err := json.Unmarshal([]byte(lib.JsonArrItemAnyWrapInStr(jsonStr)), &list) - if err != nil { - return []ValineComment{}, err - } - - return list, nil -} - -// PageKey (c.Url 不确定是否为完整 URL 还是一个 path) -func GetValineNewPageKey(baseUrl string, c ValineComment) string { - baseUrl = strings.TrimSuffix(baseUrl, "/") + "/" - return baseUrl + strings.TrimPrefix(lib.GetUrlWithoutDomain(c.Url), "/") -} - -func ImportValineComments(basic *BasicParams, comments []ValineComment) { - siteName := basic.TargetSiteName - - idMap := map[string]int{} // ID映射 object_id => id - idChanges := map[uint]uint{} // 变更 ID original_id => new_db_id - - id := 1 - for _, c := range comments { - idMap[c.ObjectId] = id - id++ - } - - for _, c := range comments { - - // 创建 user - user := model.FindCreateUser(c.Nick, c.Mail, c.Link) - - // 创建 page - pageKey := GetValineNewPageKey(basic.TargetSiteUrl, c) - page := model.FindCreatePage(pageKey, "", siteName) - - // 创建新 comment 实例 - nComment := model.Comment{ - Content: c.Comment, - - PageKey: page.Key, - SiteName: basic.TargetSiteName, - - UserID: user.ID, - UA: c.UA, - IP: c.IP, - - Rid: uint(idMap[c.Rid]), - - IsCollapsed: false, - IsPending: false, - } - - // 日期恢复 - createdVal := fmt.Sprintf("%v", c.CreatedAt) - updatedVal := fmt.Sprintf("%v", c.UpdatedAt) - nComment.CreatedAt = ParseDate(createdVal) - nComment.UpdatedAt = ParseDate(updatedVal) - - // 保存到数据库 - err := lib.DB.Create(&nComment).Error - if err != nil { - logrus.Error(fmt.Sprintf("评论源 ID:%s 保存失败", c.ObjectId)) - continue - } - - idChanges[uint(idMap[c.ObjectId])] = nComment.ID + // 解析 Valine JSON + var vComments []ValineCommentFAS + JsonDecodeFAS(jsonStr, &vComments) + + // Valine 数据格式转 Artrans + tp := []model.Artran{} + for _, vc := range vComments { + tp = append(tp, model.Artran{ + ID: vc.ObjectId, + Rid: vc.Rid, + Content: vc.Comment, + UA: vc.UA, + IP: vc.IP, + IsCollapsed: lib.ToString(false), + IsPending: lib.ToString(vc.IsSpam == "true"), + CreatedAt: vc.CreatedAt, + UpdatedAt: vc.UpdatedAt, + Nick: vc.Nick, + Email: vc.Mail, + Link: vc.Link, + PageKey: vc.Url, + SiteName: basic.TargetSiteName, + SiteUrls: basic.TargetSiteUrl, + }) } - // reply id 重建 - RebuildRid(idChanges) - - fmt.Print("\n") - logrus.Info("RID 重构完毕") + ImportArtrans(basic, tp) } -type ValineComment struct { +// ValineCommentFAS (FieldAllStr) +type ValineCommentFAS struct { ObjectId string `json:"objectId"` Nick string `json:"nick"` IP string `json:"ip"` diff --git a/lib/utils.go b/lib/utils.go index 3d630013f..cb1773d6f 100644 --- a/lib/utils.go +++ b/lib/utils.go @@ -105,26 +105,47 @@ func RemoveBlankStrings(s []string) []string { return r } -func JsonArrItemAnyWrapInStr(jsonStr string) string { +//#region JSON Any To String (for Transfer) +//****************************************** + +// 任何类型转 String +// (bool) true => (string) "true" +// (int) 0 => (string) "0" +func ToString(val interface{}) string { + return fmt.Sprintf("%v", val) +} + +// 将 JSON "数组中的"对象的 Values 全部转成 String 类型 +// @note Array style is not the same as JSON Array, it uses the ToString() function. +// [{"a":233}, {"b":true}, {"c":"233"}] +// => [{"a":"233"}, {"b":"true"}, {"c":"233"}] +// @relevant ToString() +func JsonObjInArrAnyStr(jsonStr string) string { var raw []map[string]interface{} json.Unmarshal([]byte(jsonStr), &raw) var dest []interface{} for _, item := range raw { - dest = append(dest, JsonAnyWrapInStr(item)) + dest = append(dest, JsonObjAnyStr(item)) } j, _ := json.Marshal(dest) return string(j) } -// {"test":233} => {"test": "233"}, {"test": ["233"]} => {"test": "[\"233\"]"} -func JsonAnyWrapInStr(item map[string]interface{}) map[string]string { +// 将 JSON 对象的 Values 全部转成 String 类型 +// {"test":233} => {"test": "233"}, {"test": true} => {"test": "true"} +func JsonObjAnyStr(item map[string]interface{}) map[string]string { dest := map[string]string{} for k, v := range item { - dest[k] = fmt.Sprintf("%v", v) + dest[k] = ToString(v) } return dest } +//#endregion + +//#region Validators +//****************************************** + func ValidateEmail(email string) bool { _, err := mail.ParseAddress(email) return err == nil @@ -134,3 +155,5 @@ func ValidateURL(urlStr string) bool { _, err := url.ParseRequestURI(urlStr) return err == nil } + +//#endregion diff --git a/model/artran.go b/model/artran.go new file mode 100644 index 000000000..7ea1f7a22 --- /dev/null +++ b/model/artran.go @@ -0,0 +1,40 @@ +package model + +// 数据行囊 (n 个 Artran 组成一个 Artrans) +// Fields All String type (FAS) +type Artran struct { + ID string `json:"id"` + Rid string `json:"rid"` + + Content string `json:"content"` + + UA string `json:"ua"` + IP string `json:"ip"` + IsCollapsed string `json:"is_collapsed"` // bool => string "true" or "false" + IsPending string `json:"is_pending"` // bool + + // vote + VoteUp string `json:"vote_up"` + VoteDown string `json:"vote_down"` + + // date + CreatedAt string `json:"created_at"` + UpdatedAt string `json:"updated_at"` + + // user + Nick string `json:"nick"` + Email string `json:"email"` + Link string `json:"link"` + Password string `json:"password"` + BadgeName string `json:"badge_name"` + BadgeColor string `json:"badge_color"` + + // page + PageKey string `json:"page_key"` + PageTitle string `json:"page_title"` + PageAdminOnly string `json:"page_admin_only"` // bool + + // site + SiteName string `json:"site_name"` + SiteUrls string `json:"site_urls"` +} diff --git a/model/comment.go b/model/comment.go index d4a30cea8..8db6d900b 100644 --- a/model/comment.go +++ b/model/comment.go @@ -64,7 +64,7 @@ func (c *Comment) FetchPage() Page { } var page Page - lib.DB.Where("page_key = ?", c.PageKey).First(&page) + lib.DB.Where("key = ?", c.PageKey).First(&page) c.Page = page return page @@ -241,3 +241,34 @@ func (c *Comment) SpamCheck(echoCtx echo.Context) { // TODO:关键字过滤 } + +func (c *Comment) ToArtran() Artran { + user := c.FetchUser() + page := c.FetchPage() + site := c.FetchSite() + + return Artran{ + ID: lib.ToString(c.ID), + Rid: lib.ToString(c.Rid), + Content: c.Content, + UA: c.UA, + IP: c.IP, + IsCollapsed: lib.ToString(c.IsCollapsed), + IsPending: lib.ToString(c.IsPending), + VoteUp: lib.ToString(c.VoteUp), + VoteDown: lib.ToString(c.VoteDown), + CreatedAt: c.CreatedAt.String(), + UpdatedAt: c.UpdatedAt.String(), + Nick: user.Name, + Email: user.Email, + Link: user.Link, + Password: user.Password, + BadgeName: user.BadgeName, + BadgeColor: user.BadgeColor, + PageKey: page.Key, + PageTitle: page.Title, + PageAdminOnly: lib.ToString(page.AdminOnly), + SiteName: site.Name, + SiteUrls: site.Urls, + } +} diff --git a/model/query.go b/model/query.go index 8d3302e9b..db09dd8b5 100644 --- a/model/query.go +++ b/model/query.go @@ -132,6 +132,14 @@ func NewSite(name string, urls string) Site { return site } +func UpdateSite(site *Site) error { + err := lib.DB.Save(site).Error + if err != nil { + logrus.Error("Update Site error: ", err) + } + return err +} + func FindCreatePage(pageKey string, pageTitle string, siteName string) Page { page := FindPage(pageKey, siteName) if page.IsEmpty() { From 364a251041bbf5fb977924ef5173e7a9b09c5ac4 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Wed, 27 Oct 2021 17:05:02 +0800 Subject: [PATCH 083/349] feat(artrans): Import from Artalk v1 (PHP). Signed-off-by: qwqcode --- http/a_http.go | 2 +- lib/importer/artalk_v1.go | 65 +++++++++++++++++++++++++++++++++++++++ lib/importer/importer.go | 22 +++++++------ 3 files changed, 79 insertions(+), 10 deletions(-) create mode 100644 lib/importer/artalk_v1.go diff --git a/http/a_http.go b/http/a_http.go index f2a2b6d5b..93d744557 100644 --- a/http/a_http.go +++ b/http/a_http.go @@ -115,7 +115,7 @@ func InitRoute(e *echo.Echo) { admin.POST("/setting-get", ActionAdminSettingGet) admin.POST("/setting-save", ActionAdminSettingSave) admin.POST("/importer", ActionAdminImporter) - admin.POST("/vote-sync", ActionAdminVoteSync) + // admin.POST("/vote-sync", ActionAdminVoteSync) // 数据导入功能未关注 vote 部分,暂时注释 admin.POST("/send-mail", ActionAdminSendMail) diff --git a/lib/importer/artalk_v1.go b/lib/importer/artalk_v1.go new file mode 100644 index 000000000..cc8585a7f --- /dev/null +++ b/lib/importer/artalk_v1.go @@ -0,0 +1,65 @@ +package importer + +import ( + "github.com/ArtalkJS/ArtalkGo/model" +) + +var ArtalkV1Importer = &_ArtalkV1Importer{ + ImporterInfo: ImporterInfo{ + Name: "artalk_v1", + Desc: "从 Artalk v1 (PHP) 导入数据", + Note: "", + }, +} + +type _ArtalkV1Importer struct { + ImporterInfo +} + +func (imp *_ArtalkV1Importer) Run(basic *BasicParams, payload []string) { + RequiredBasicTargetSite(basic) + + // 读取文件 + jsonStr := JsonFileReady(payload) + + var aComments []ArtalkV1AFS + JsonDecodeFAS(jsonStr, &aComments) + + tp := []model.Artran{} + for _, tc := range aComments { + tp = append(tp, model.Artran{ + ID: tc.ID, + Rid: tc.Rid, + Content: tc.Content, + UA: tc.UA, + IP: tc.IP, + IsCollapsed: tc.IsCollapsed, + IsPending: tc.IsPending, + CreatedAt: tc.Date, + UpdatedAt: tc.Date, + Nick: tc.Nick, + Email: tc.Email, + Link: tc.Link, + PageKey: tc.PageKey, + SiteName: basic.TargetSiteName, + SiteUrls: basic.TargetSiteUrl, + }) + } + + ImportArtrans(basic, tp) +} + +type ArtalkV1AFS struct { + ID string `json:"id"` + Content string `json:"content"` + Nick string `json:"nick"` + Email string `json:"email"` + Link string `json:"link"` + UA string `json:"ua"` + PageKey string `json:"page_key"` + Rid string `json:"rid"` + IP string `json:"ip"` + Date string `json:"date"` + IsPending string `json:"is_pending"` + IsCollapsed string `json:"is_collapsed"` +} diff --git a/lib/importer/importer.go b/lib/importer/importer.go index 3cd29a587..d44ddcd56 100644 --- a/lib/importer/importer.go +++ b/lib/importer/importer.go @@ -33,6 +33,7 @@ var Supports = []interface{}{ WordPressImporter, ValineImporter, TwikooImporter, + ArtalkV1Importer, } func RunByName(dataType string, payload []string) { @@ -258,18 +259,21 @@ func UrlResolverGetPageKey(baseUrl string, commentUrlVal string) string { return commentUrlVal } - pathIsDir := strings.HasSuffix(u.Path, "/") // path 以 / 结尾 - abs, absErr := filepath.Abs(u.Path) // 相对路径转绝对路径 + // pathIsDir := strings.HasSuffix(u.Path, "/") // path 以 / 结尾 + abs, absErr := filepath.Abs(u.Path) // 相对路径转绝对路径 if absErr != nil { return u.String() } - if pathIsDir { - u.Path = abs + "/" // 加上 "/" - // 这是一个 patch: 因为 filepath.Abs() 结果无论是 目录还是文件,都会去掉 / - } else { - u.Path = abs - } + // TODO 会导致 "http://aaa.com", "/" => "http://aaa.com//" 暂时搁置 + // if pathIsDir { + // u.Path = abs + "/" // 加上 "/" + // // 这是一个 patch: 因为 filepath.Abs() 结果无论是 目录还是文件,都会去掉 / + // } else { + // u.Path = abs + // } + + u.Path = abs return u.String() } @@ -313,7 +317,7 @@ func GetParamsFrom(payload []string) _getParamsTo { valStr := strings.TrimPrefix(pVal, fromName+":") - switch toVar.(type) { + switch reflect.ValueOf(toVar).Interface().(type) { case *string: *toVar.(*string) = valStr case *bool: From fbce496de47767f9c018908bfda781d5d8cbcc9a Mon Sep 17 00:00:00 2001 From: qwqcode Date: Thu, 28 Oct 2021 07:47:45 +0800 Subject: [PATCH 084/349] feat(artrans): Run on frontend client. Signed-off-by: qwqcode --- .vscode/settings.json | 3 +- cmd/export.go | 15 +-- cmd/import.go | 17 ++- cmd/root.go | 11 ++ http/a_http.go | 2 +- http/api_admin_artransfer.go | 45 +++++++ http/api_admin_importer.go | 148 ---------------------- lib/{importer => artransfer}/artalk_v1.go | 18 ++- lib/{importer => artransfer}/artrans.go | 53 ++++++-- lib/{importer => artransfer}/example.go | 2 +- lib/artransfer/exporter.go | 27 ++++ lib/{importer => artransfer}/importer.go | 135 +++++++------------- lib/artransfer/output.go | 122 ++++++++++++++++++ lib/{importer => artransfer}/twikoo.go | 14 +- lib/{importer => artransfer}/typecho.go | 76 ++++++----- lib/{importer => artransfer}/valine.go | 14 +- lib/{importer => artransfer}/wordpress.go | 2 +- model/page.go | 2 +- 18 files changed, 393 insertions(+), 313 deletions(-) create mode 100644 http/api_admin_artransfer.go delete mode 100644 http/api_admin_importer.go rename lib/{importer => artransfer}/artalk_v1.go (83%) rename lib/{importer => artransfer}/artrans.go (73%) rename lib/{importer => artransfer}/example.go (93%) create mode 100644 lib/artransfer/exporter.go rename lib/{importer => artransfer}/importer.go (74%) create mode 100644 lib/artransfer/output.go rename lib/{importer => artransfer}/twikoo.go (90%) rename lib/{importer => artransfer}/typecho.go (86%) rename lib/{importer => artransfer}/valine.go (89%) rename lib/{importer => artransfer}/wordpress.go (93%) diff --git a/.vscode/settings.json b/.vscode/settings.json index dc936142c..b66a11ab6 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -3,7 +3,8 @@ "akismet", "artalk", "artran", - "Artrans", + "artrans", + "artransfer", "gomail", "Goreleaser", "gorm", diff --git a/cmd/export.go b/cmd/export.go index acdf4ee43..af5a9f902 100644 --- a/cmd/export.go +++ b/cmd/export.go @@ -1,13 +1,12 @@ package cmd import ( - "encoding/json" "fmt" "os" "path/filepath" "github.com/ArtalkJS/ArtalkGo/lib" - "github.com/ArtalkJS/ArtalkGo/model" + "github.com/ArtalkJS/ArtalkGo/lib/artransfer" "github.com/sirupsen/logrus" "github.com/spf13/cobra" ) @@ -21,20 +20,10 @@ var exportCmd = &cobra.Command{ - 文档:https://artalk.js.org/guide/transfer.html `, Run: func(cmd *cobra.Command, args []string) { - comments := []model.Comment{} - lib.DB.Find(&comments) - - artrans := []model.Artran{} - for _, c := range comments { - ct := c.ToArtran() - artrans = append(artrans, ct) - } - - jsonByte, err := json.Marshal(artrans) + jsonStr, err := artransfer.ExportArtransString() if err != nil { logrus.Fatal(err) } - jsonStr := string(jsonByte) outputFile := cmd.Flag("output").Value.String() if outputFile == "" { diff --git a/cmd/import.go b/cmd/import.go index d47a2e4ee..4bcd677ce 100644 --- a/cmd/import.go +++ b/cmd/import.go @@ -5,7 +5,7 @@ import ( "io/ioutil" "os" - "github.com/ArtalkJS/ArtalkGo/lib/importer" + "github.com/ArtalkJS/ArtalkGo/lib/artransfer" "github.com/sirupsen/logrus" "github.com/spf13/cobra" ) @@ -30,29 +30,32 @@ var importCmd = &cobra.Command{ } content := string(buf) - basic := importer.GetBasicParamsFrom(args[1:]) + basic := artransfer.GetBasicParamsFrom(args[1:]) basic.UrlResolver = false // 默认关闭 URL 解析器:因为 pageKey 是完整,且站点隔离开 - importer.ImportArtransByStr(basic, content) + artransfer.ImportArtransByStr(basic, content) logrus.Info("导入结束") }, Args: cobra.MinimumNArgs(1), - ArgAliases: importer.GetSupportNames(), + ArgAliases: artransfer.GetSupportNames(), } func init() { rootCmd.AddCommand(importCmd) - for _, item := range importer.Supports { - imp := importer.GetImporterInfo(item) + for _, item := range artransfer.Supports { + imp := artransfer.GetImporterInfo(item) subCmd := &cobra.Command{ Use: imp.Name + " [参数]", Short: imp.Desc, Run: func(cmd *cobra.Command, args []string) { - importer.RunByName(imp.Name, args) + artransfer.Assumeyes, _ = cmd.Flags().GetBool("assumeyes") + artransfer.RunByName(imp.Name, args) }, } importCmd.AddCommand(subCmd) } + + flagPV(importCmd, "assumeyes", "y", false, "Automatically answer yes for all questions.") } diff --git a/cmd/root.go b/cmd/root.go index 82b8d689d..a25a27b15 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -1,6 +1,7 @@ package cmd import ( + "fmt" "os" "strings" "time" @@ -62,6 +63,16 @@ func init() { rootCmd.SetVersionTemplate("Artalk-GO {{printf \"version %s\" .Version}}\n") rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "配置文件路径 (defaults are './artalk-go.yml')") + + versionCmd := &cobra.Command{ + Use: "version", + Short: "输出 ArtalkGo 版本信息", + Version: Version, + Run: func(cmd *cobra.Command, args []string) { + fmt.Println("ArtalkGo (" + lib.Version + "/" + lib.CommitHash + ")") + }, + } + rootCmd.AddCommand(versionCmd) } // 1. 初始化配置 diff --git a/http/a_http.go b/http/a_http.go index 93d744557..5786e408b 100644 --- a/http/a_http.go +++ b/http/a_http.go @@ -114,7 +114,7 @@ func InitRoute(e *echo.Echo) { admin.POST("/site-del", ActionAdminSiteDel) admin.POST("/setting-get", ActionAdminSettingGet) admin.POST("/setting-save", ActionAdminSettingSave) - admin.POST("/importer", ActionAdminImporter) + admin.POST("/artransfer", ActionAdminArtransfer) // admin.POST("/vote-sync", ActionAdminVoteSync) // 数据导入功能未关注 vote 部分,暂时注释 admin.POST("/send-mail", ActionAdminSendMail) diff --git a/http/api_admin_artransfer.go b/http/api_admin_artransfer.go new file mode 100644 index 000000000..076f1d6b6 --- /dev/null +++ b/http/api_admin_artransfer.go @@ -0,0 +1,45 @@ +package http + +import ( + "encoding/json" + "net/http" + + "github.com/ArtalkJS/ArtalkGo/lib/artransfer" + "github.com/labstack/echo/v4" +) + +type ParamsAdminArtransfer struct { + Type string `mapstructure:"type" param:"required"` + Payload string `mapstructure:"payload"` +} + +func ActionAdminArtransfer(c echo.Context) error { + if isOK, resp := AdminOnly(c); !isOK { + return resp + } + + var p ParamsAdminArtransfer + if isOK, resp := ParamsDecode(c, ParamsAdminArtransfer{}, &p); !isOK { + return resp + } + + var payload []string + err := json.Unmarshal([]byte(p.Payload), &payload) + if err != nil { + return RespError(c, "payload 解析错误", Map{ + "error": err, + }) + } + + c.Response().Header().Set(echo.HeaderContentType, echo.MIMETextPlainCharsetUTF8) + c.Response().WriteHeader(http.StatusOK) + + artransfer.Assumeyes = true + artransfer.HttpOutput = func(continueRun bool, text string) { + c.Response().Write([]byte(text)) + c.Response().Flush() + } + artransfer.RunByName(p.Type, payload) + + return nil +} diff --git a/http/api_admin_importer.go b/http/api_admin_importer.go deleted file mode 100644 index a53374190..000000000 --- a/http/api_admin_importer.go +++ /dev/null @@ -1,148 +0,0 @@ -package http - -import ( - "encoding/json" - "fmt" - "strings" - "time" - - "github.com/ArtalkJS/ArtalkGo/config" - "github.com/ArtalkJS/ArtalkGo/lib" - "github.com/ArtalkJS/ArtalkGo/model" - "github.com/araddon/dateparse" - "github.com/labstack/echo/v4" - "github.com/sirupsen/logrus" -) - -type ParamsAdminImporter struct { - Type string `mapstructure:"type" param:"required"` - Data string `mapstructure:"data" param:"required"` - SiteName string `mapstructure:"site_name"` - SiteID uint -} - -func ActionAdminImporter(c echo.Context) error { - if isOK, resp := AdminOnly(c); !isOK { - return resp - } - - var p ParamsAdminImporter - if isOK, resp := ParamsDecode(c, ParamsAdminImporter{}, &p); !isOK { - return resp - } - - // check create site - if model.FindSite(p.SiteName).IsEmpty() { - site := model.Site{} - site.Name = p.SiteName - err := lib.DB.Create(&site).Error - if err != nil { - return RespError(c, "站点创建失败") - } - } - - // find site - if isOK, resp := CheckSite(c, &p.SiteName, &p.SiteID, nil); !isOK { - return resp - } - - // 数据导入注意事项: - // 1. 记得恢复创建/更新时间 - // 2. 因为是数据追加模式,ID 会发生变动,需更新 rid - - errs := []string{} - dbResultLog := func(name string, err error) { - if err != nil { - logrus.Error("Save Comment error: ", err) - errs = append(errs, fmt.Sprintf("%s: %s", name, err.Error())) - } - } - - idChanges := map[uint]uint{} // comment_id: old => new - - switch p.Type { - // Artalk v1 数据源 - case "artalk_v1": - // 解析数据源 - var v1Comments []ArtalkV1_Comment - err := json.Unmarshal([]byte(p.Data), &v1Comments) - if err != nil { - return RespError(c, "json unmarshal err:"+err.Error()) - } - - for _, oc := range v1Comments { - if strings.TrimSpace(oc.Content) == "" { - continue - } - - // 创建 page 和 user - page := model.FindCreatePage(oc.PageKey, "", p.SiteName) - user := model.FindCreateUser(oc.Nick, oc.Email, oc.Link) - - // 创建新 comment 实例 - nComment := model.Comment{ - Content: oc.Content, - - PageKey: page.Key, - SiteName: p.SiteName, - - UserID: user.ID, - UA: oc.UA, - IP: oc.IP, - - Rid: oc.Rid, - - IsCollapsed: oc.IsCollapsed, - IsPending: oc.IsPending, - } - - // 日期恢复 - denverLoc, _ := time.LoadLocation(config.Instance.TimeZone) // 时区 - time.Local = denverLoc - t, _ := dateparse.ParseIn(oc.Date, denverLoc) - nComment.CreatedAt = t - nComment.UpdatedAt = t - - // 保存到数据库 - err := lib.DB.Create(&nComment).Error - dbResultLog(fmt.Sprintf("保存 old_id:%d new_id:%d", oc.ID, nComment.ID), err) - - idChanges[oc.ID] = nComment.ID - } - - // reply id 重建 - for _, newId := range idChanges { - nComment := model.FindComment(newId) - if nComment.Rid == 0 { - continue - } - if newId, isExist := idChanges[nComment.Rid]; isExist { - nComment.Rid = newId - err := lib.DB.Save(&nComment).Error - dbResultLog(fmt.Sprintf("rid 更新 new_id:%d new_rid:%d", nComment.ID, newId), err) - } - } - default: - return RespError(c, "invalid type") - } - - if len(errs) != 0 { - return RespError(c, "导入发生错误:"+strings.Join(errs, "\n")) - } - return RespSuccess(c) -} - -type ArtalkV1_Comment struct { - ID uint `json:"id"` - Content string `json:"content"` - Nick string `json:"nick"` - Email string `json:"email"` - Link string `json:"link"` - UA string `json:"ua"` - PageKey string `json:"page_key"` - Rid uint `json:"rid"` - IP string `json:"ip"` - Date string `json:"date"` - IsPending bool `json:"is_pending"` - IsCollapsed bool `json:"is_collapsed"` -} diff --git a/lib/importer/artalk_v1.go b/lib/artransfer/artalk_v1.go similarity index 83% rename from lib/importer/artalk_v1.go rename to lib/artransfer/artalk_v1.go index cc8585a7f..ed255933c 100644 --- a/lib/importer/artalk_v1.go +++ b/lib/artransfer/artalk_v1.go @@ -1,4 +1,4 @@ -package importer +package artransfer import ( "github.com/ArtalkJS/ArtalkGo/model" @@ -17,12 +17,20 @@ type _ArtalkV1Importer struct { } func (imp *_ArtalkV1Importer) Run(basic *BasicParams, payload []string) { - RequiredBasicTargetSite(basic) + err := RequiredBasicTargetSite(basic) + if err != nil { + logFatal(err) + return + } // 读取文件 - jsonStr := JsonFileReady(payload) + jsonStr, jErr := JsonFileReady(payload) + if jErr != nil { + logFatal(jErr) + return + } - var aComments []ArtalkV1AFS + var aComments []ArtalkV1CommentAFS JsonDecodeFAS(jsonStr, &aComments) tp := []model.Artran{} @@ -49,7 +57,7 @@ func (imp *_ArtalkV1Importer) Run(basic *BasicParams, payload []string) { ImportArtrans(basic, tp) } -type ArtalkV1AFS struct { +type ArtalkV1CommentAFS struct { ID string `json:"id"` Content string `json:"content"` Nick string `json:"nick"` diff --git a/lib/importer/artrans.go b/lib/artransfer/artrans.go similarity index 73% rename from lib/importer/artrans.go rename to lib/artransfer/artrans.go index 5ae9312c1..68a1134ad 100644 --- a/lib/importer/artrans.go +++ b/lib/artransfer/artrans.go @@ -1,4 +1,4 @@ -package importer +package artransfer import ( "fmt" @@ -8,9 +8,39 @@ import ( "github.com/ArtalkJS/ArtalkGo/model" "github.com/cheggaaa/pb/v3" "github.com/jedib0t/go-pretty/v6/table" - "github.com/sirupsen/logrus" ) +var ArtransImporter = &_ArtransImporter{ + ImporterInfo: ImporterInfo{ + Name: "artrans", + Desc: "从 Artrans 导入数据", + Note: "", + }, +} + +type _ArtransImporter struct { + ImporterInfo +} + +func (imp *_ArtransImporter) Run(basic *BasicParams, payload []string) { + err := RequiredBasicTargetSite(basic) + if err != nil { + logFatal(err) + return + } + + // 读取文件 + jsonStr, jErr := JsonFileReady(payload) + if jErr != nil { + logFatal(jErr) + return + } + + basic.UrlResolver = false + + ImportArtransByStr(basic, jsonStr) +} + func ImportArtransByStr(basic *BasicParams, str string) { // 解析内容 comments := []model.Artran{} @@ -21,7 +51,7 @@ func ImportArtransByStr(basic *BasicParams, str string) { func ImportArtrans(basic *BasicParams, comments []model.Artran) { // 汇总 - fmt.Print("# 请过目:\n\n") + print("# 请过目:\n\n") // 第一条评论 PrintEncodeData("第一条评论", comments[0]) @@ -41,7 +71,7 @@ func ImportArtrans(basic *BasicParams, comments []model.Artran) { {"评论数量", len(comments)}, }) - fmt.Print("\n") + print("\n") // 确认开始 if !Confirm("确认开始导入吗?") { @@ -49,7 +79,7 @@ func ImportArtrans(basic *BasicParams, comments []model.Artran) { } // 准备导入评论 - fmt.Print("\n") + print("\n") // 执行导入 idMap := map[string]int{} // ID 映射表 object_id => id @@ -68,7 +98,11 @@ func ImportArtrans(basic *BasicParams, comments []model.Artran) { // 遍历导入 comments for _, c := range comments { // 准备 site - site := SiteReady(c.SiteName, c.SiteUrls) + site, sErr := SiteReady(c.SiteName, c.SiteUrls) + if sErr != nil { + logFatal(sErr) + return + } // 准备 user user := model.FindCreateUser(c.Nick, c.Email, c.Link) @@ -115,9 +149,9 @@ func ImportArtrans(basic *BasicParams, comments []model.Artran) { nComment.UpdatedAt = ParseDate(c.UpdatedAt) // 保存到数据库 - err := lib.DB.Create(&nComment).Error - if err != nil { - logrus.Error(fmt.Sprintf("评论源 ID:%s 保存失败", c.ID)) + dErr := lib.DB.Create(&nComment).Error + if dErr != nil { + logError(fmt.Sprintf("评论源 ID:%s 保存失败", c.ID)) continue } @@ -126,6 +160,7 @@ func ImportArtrans(basic *BasicParams, comments []model.Artran) { bar.Increment() } bar.Finish() + logInfo(fmt.Sprintf("导入 %d 条数据", len(comments))) // reply id 重建 RebuildRid(idChanges) diff --git a/lib/importer/example.go b/lib/artransfer/example.go similarity index 93% rename from lib/importer/example.go rename to lib/artransfer/example.go index 733d9618e..4a04e1419 100644 --- a/lib/importer/example.go +++ b/lib/artransfer/example.go @@ -1,4 +1,4 @@ -package importer +package artransfer var ExampleImporter = &_ExampleImporter{ ImporterInfo: ImporterInfo{ diff --git a/lib/artransfer/exporter.go b/lib/artransfer/exporter.go new file mode 100644 index 000000000..0bed3a556 --- /dev/null +++ b/lib/artransfer/exporter.go @@ -0,0 +1,27 @@ +package artransfer + +import ( + "encoding/json" + + "github.com/ArtalkJS/ArtalkGo/lib" + "github.com/ArtalkJS/ArtalkGo/model" +) + +func ExportArtransString() (string, error) { + comments := []model.Comment{} + lib.DB.Find(&comments) + + artrans := []model.Artran{} + for _, c := range comments { + ct := c.ToArtran() + artrans = append(artrans, ct) + } + + jsonByte, err := json.Marshal(artrans) + if err != nil { + return "", err + } + jsonStr := string(jsonByte) + + return jsonStr, nil +} diff --git a/lib/importer/importer.go b/lib/artransfer/importer.go similarity index 74% rename from lib/importer/importer.go rename to lib/artransfer/importer.go index d44ddcd56..22fa1ee5f 100644 --- a/lib/importer/importer.go +++ b/lib/artransfer/importer.go @@ -1,12 +1,10 @@ -package importer +package artransfer import ( - "bufio" "encoding/json" "errors" "fmt" "io/ioutil" - "log" "net/url" "os" "path/filepath" @@ -22,15 +20,14 @@ import ( "github.com/ArtalkJS/ArtalkGo/model" "github.com/araddon/dateparse" "github.com/jedib0t/go-pretty/v6/table" - "github.com/sirupsen/logrus" "gorm.io/gorm" ) type Map = map[string]interface{} var Supports = []interface{}{ + ArtransImporter, TypechoImporter, - WordPressImporter, ValineImporter, TwikooImporter, ArtalkV1Importer, @@ -47,7 +44,7 @@ func RunByName(dataType string, payload []string) { continue } - fmt.Print("\n") + print("\n") tableData := []table.Row{ {"数据搬家 - 导入"}, {strings.ToUpper(name)}, @@ -57,7 +54,7 @@ func RunByName(dataType string, payload []string) { tableData = append(tableData, table.Row{note}) } PrintTable(tableData) - fmt.Print("\n") + print("\n") //t1 := time.Now() r.MethodByName("Run").Call([]reflect.Value{ @@ -65,12 +62,12 @@ func RunByName(dataType string, payload []string) { reflect.ValueOf(payload), }) //elapsed := time.Since(t1) - fmt.Print("\n") - logrus.Info("导入执行结束") //,耗时: ", elapsed) + print("\n") + logInfo("导入执行结束") //,耗时: ", elapsed) return } - logrus.Fatal("不支持该数据类型导入") + logFatal("不支持该数据类型导入") } type ImporterInfo struct { @@ -116,25 +113,27 @@ func GetBasicParamsFrom(payload []string) *BasicParams { }) if !basic.UrlResolver { - logrus.Warn("目标站点 URL 解析器已关闭") + logWarn("目标站点 URL 解析器已关闭") } return &basic } -func RequiredBasicTargetSite(basic *BasicParams) { +func RequiredBasicTargetSite(basic *BasicParams) error { if basic.TargetSiteName == "" { - logrus.Fatal("请附带参数 `t_name:<目标站点名称>`") + return errors.New("请附带参数 `t_name:<目标站点名称>`") } if basic.TargetSiteUrl == "" { - logrus.Fatal("请附带参数 `t_url:<目标站点根目录 URL>`") + return errors.New("请附带参数 `t_url:<目标站点根目录 URL>`") } if !lib.ValidateURL(basic.TargetSiteUrl) { - logrus.Fatal("参数 `t_url:<目标站点根目录 URL>` 必须为 URL 格式") + return errors.New("参数 `t_url:<目标站点根目录 URL>` 必须为 URL 格式") } + + return nil } -func DbReady(payload []string) *gorm.DB { +func DbReady(payload []string) (*gorm.DB, error) { var host, port, dbName, user, password, dbType, dbFile string GetParamsFrom(payload).To(map[string]interface{}{ "host": &host, @@ -153,33 +152,33 @@ func DbReady(payload []string) *gorm.DB { // sqlite if strings.EqualFold(dbType, string(config.TypeSQLite)) { if dbFile == "" { - logrus.Fatal("SQLite 数据库:请传递参数 `db_file` 指定数据文件路径") + return nil, errors.New("SQLite 数据库:请传递参数 `db_file` 指定数据文件路径") } db, err := lib.OpenSQLite(dbFile) if err != nil { - logrus.Fatal("SQLite 打开失败 ", err) + return nil, errors.New("SQLite 打开失败 " + err.Error()) } - return db + return db, nil } dsn, err := lib.GetDsn(config.DBType(dbType), host, port, dbName, user, password) if err != nil { - logrus.Fatal("数据库连接 DSN 生成错误 ", err) + return nil, errors.New("数据库连接 DSN 生成错误 " + err.Error()) } db, err := lib.OpenDB(config.DBType(dbType), dsn) if err != nil { - logrus.Fatal("数据库连接失败 ", err) + return nil, errors.New("数据库连接失败 " + err.Error()) } - logrus.Info("数据库连接成功") + logInfo("数据库连接成功") - return db + return db, nil } // 站点准备 -func SiteReady(tSiteName string, tSiteUrls string) model.Site { +func SiteReady(tSiteName string, tSiteUrls string) (model.Site, error) { site := model.FindSite(tSiteName) if site.IsEmpty() { // 创建新站点 @@ -188,7 +187,7 @@ func SiteReady(tSiteName string, tSiteUrls string) model.Site { site.Urls = tSiteUrls err := lib.DB.Create(&site).Error if err != nil { - logrus.Fatal("站点创建失败") + return model.Site{}, errors.New("站点创建失败") } } else { // 追加 URL @@ -218,33 +217,39 @@ func SiteReady(tSiteName string, tSiteUrls string) model.Site { site.Urls = strings.Join(rUrls, ",") err := lib.DB.Save(&site).Error if err != nil { - logrus.Fatal("站点数据更新失败") + return model.Site{}, errors.New("站点数据更新失败") } } } - return site + return site, nil } -func JsonFileReady(payload []string) string { - var jsonFile string +func JsonFileReady(payload []string) (string, error) { + var jsonFile, jsonData string GetParamsFrom(payload).To(map[string]interface{}{ "json_file": &jsonFile, + "json_data": &jsonData, }) + // 直接给 JSON 内容,不去读取文件 + if jsonData != "" { + return jsonData, nil + } + if jsonFile == "" { - logrus.Fatal("请附带参数 `json_file:`") + return "", errors.New("请附带参数 `json_file:`") } if _, err := os.Stat(jsonFile); errors.Is(err, os.ErrNotExist) { - logrus.Fatal("文件不存在,请检查参数 `json_file` 传入路径是否正确") + return "", errors.New("文件不存在,请检查参数 `json_file` 传入路径是否正确") } buf, err := ioutil.ReadFile(jsonFile) if err != nil { - logrus.Fatal("json 文件打开失败:", err) + return "", errors.New("json 文件打开失败:" + err.Error()) } - return string(buf) + return string(buf), nil } // PageKey (commentUrlVal 不确定是否为完整 URL 还是一个 path) @@ -255,7 +260,7 @@ func UrlResolverGetPageKey(baseUrl string, commentUrlVal string) string { // 解决拼接路径中的相对地址,例如:https://atk.xxx/abc/../artalk => https://atk.xxx/artalk u, err := url.ParseRequestURI(baseUrl + path) if err != nil { - logrus.Error("GetNewPageKey Error: ", err) + logError("GetNewPageKey Error: ", err) return commentUrlVal } @@ -288,7 +293,7 @@ func ParseVersion(s string) int64 { var result int64 var err error if result, err = strconv.ParseInt(v, 10, 64); err != nil { - logrus.Error("ugh: parseVersion(%s): error=%s", s, err) + logError("ugh: parseVersion(%s): error=%s", s, err) return 0 } return result @@ -346,61 +351,15 @@ func GetArrayParamsFrom(payload []string, key string) []string { return arr } -func PrintTable(rows []table.Row) { - t := table.NewWriter() - t.SetOutputMirror(os.Stdout) - - for _, r := range rows { - t.AppendRow(r) - } - - tStyle := table.StyleLight - tStyle.Options.SeparateRows = true - t.SetStyle(tStyle) - - t.Render() -} - -func PrintEncodeData(dataType string, val interface{}) { - fmt.Print(SprintEncodeData(dataType, val)) -} - -func SprintEncodeData(dataType string, val interface{}) string { - return fmt.Sprintf("[%s]\n\n %#v\n\n", dataType, val) -} - -func Confirm(s string) bool { - r := bufio.NewReader(os.Stdin) - - for { - fmt.Printf("%s [y/n]: ", s) - - res, err := r.ReadString('\n') - if err != nil { - log.Fatal(err) - } - - // Empty input (i.e. "\n") - if len(res) < 2 { - continue - } - - resp := strings.ToLower(strings.TrimSpace(res)) - if resp == "y" || resp == "yes" { - return true - } else if resp == "n" || resp == "no" { - return false - } - } -} - // Json Decode (FAS: Fields All String Type) // 解析 json 为字段全部是 string 类型的 struct -func JsonDecodeFAS(str string, fasStructure interface{}) { +func JsonDecodeFAS(str string, fasStructure interface{}) error { err := json.Unmarshal([]byte(lib.JsonObjInArrAnyStr(str)), fasStructure) // lib.ToString() if err != nil { - logrus.Fatal("JSON 解析失败 ", err) + return errors.New("JSON 解析失败 " + err.Error()) } + + return nil } func HideJsonLongText(key string, text string) string { @@ -426,11 +385,11 @@ func RebuildRid(idChanges map[uint]uint) { nComment.Rid = newId err := lib.DB.Save(&nComment).Error if err != nil { - logrus.Error(fmt.Sprintf("[rid 更新] new_id:%d new_rid:%d", nComment.ID, newId), err) + logError(fmt.Sprintf("[rid 更新] new_id:%d new_rid:%d", nComment.ID, newId), err) } } } - fmt.Print("\n") - logrus.Info("RID 重构完毕") + print("\n") + logInfo("RID 重构完毕") } diff --git a/lib/artransfer/output.go b/lib/artransfer/output.go new file mode 100644 index 000000000..0c1f94776 --- /dev/null +++ b/lib/artransfer/output.go @@ -0,0 +1,122 @@ +package artransfer + +import ( + "bufio" + "fmt" + "log" + "os" + "strings" + + "github.com/jedib0t/go-pretty/v6/table" + "github.com/labstack/echo/v4" + "github.com/sirupsen/logrus" +) + +var HttpOutputEchoCtx echo.Context // TODO 只支持单线执行,同时请求两个地方会出问题 +var HttpOutput func(continueRun bool, text string) +var Assumeyes bool = false + +func logError(a ...interface{}) { + if HttpOutput != nil { + HttpOutput(true, "[ERROR] "+fmt.Sprint(a...)) + return + } + + logrus.Error(a...) +} + +func logFatal(a ...interface{}) { + if HttpOutput != nil { + HttpOutput(false, "[FATAL] "+fmt.Sprint(a...)) + return + } + + logrus.Fatal(a...) +} + +func logWarn(a ...interface{}) { + if HttpOutput != nil { + HttpOutput(true, "[WARN] "+fmt.Sprint(a...)) + return + } + + logrus.Warn(a...) +} + +func logInfo(a ...interface{}) { + if HttpOutput != nil { + HttpOutput(true, "[INFO] "+fmt.Sprint(a...)) + return + } + + logrus.Info(a...) +} + +func print(a ...interface{}) { + if HttpOutput != nil { + HttpOutput(true, fmt.Sprint(a...)) + return + } + + fmt.Print(a...) +} + +func printf(format string, a ...interface{}) { + print(fmt.Sprintf(format, a...)) +} + +func println(a ...interface{}) { + print(fmt.Sprintln(a...)) +} + +func PrintTable(rows []table.Row) { + t := table.NewWriter() + + for _, r := range rows { + t.AppendRow(r) + } + + tStyle := table.StyleLight + tStyle.Options.SeparateRows = true + t.SetStyle(tStyle) + + println(t.Render()) +} + +func PrintEncodeData(dataType string, val interface{}) { + print(SprintEncodeData(dataType, val)) +} + +func SprintEncodeData(dataType string, val interface{}) string { + return fmt.Sprintf("[%s]\n\n %#v\n\n", dataType, val) +} + +func Confirm(s string) bool { + if Assumeyes { + printf("%s [y/n]: y", s) + return true + } + + r := bufio.NewReader(os.Stdin) + + for { + printf("%s [y/n]: ", s) + + res, err := r.ReadString('\n') + if err != nil { + log.Fatal(err) + } + + // Empty input (i.e. "\n") + if len(res) < 2 { + continue + } + + resp := strings.ToLower(strings.TrimSpace(res)) + if resp == "y" || resp == "yes" { + return true + } else if resp == "n" || resp == "no" { + return false + } + } +} diff --git a/lib/importer/twikoo.go b/lib/artransfer/twikoo.go similarity index 90% rename from lib/importer/twikoo.go rename to lib/artransfer/twikoo.go index 5b43d6175..e6795266d 100644 --- a/lib/importer/twikoo.go +++ b/lib/artransfer/twikoo.go @@ -1,4 +1,4 @@ -package importer +package artransfer import ( "github.com/ArtalkJS/ArtalkGo/lib" @@ -19,10 +19,18 @@ type _TwikooImporter struct { } func (imp *_TwikooImporter) Run(basic *BasicParams, payload []string) { - RequiredBasicTargetSite(basic) + err := RequiredBasicTargetSite(basic) + if err != nil { + logFatal(err) + return + } // 读取文件 - jsonStr := JsonFileReady(payload) + jsonStr, jErr := JsonFileReady(payload) + if jErr != nil { + logFatal(jErr) + return + } // 解析 Twikoo JSON var tComments []TwikooCommentFAS diff --git a/lib/importer/typecho.go b/lib/artransfer/typecho.go similarity index 86% rename from lib/importer/typecho.go rename to lib/artransfer/typecho.go index d4479ba10..cf8bc999e 100644 --- a/lib/importer/typecho.go +++ b/lib/artransfer/typecho.go @@ -1,4 +1,4 @@ -package importer +package artransfer import ( "errors" @@ -12,7 +12,6 @@ import ( "github.com/elliotchance/phpserialize" "github.com/jedib0t/go-pretty/v6/table" "github.com/mitchellh/mapstructure" - "github.com/sirupsen/logrus" ) const ( @@ -59,7 +58,11 @@ type _TypechoImporter struct { func (imp *_TypechoImporter) Run(basic *BasicParams, payload []string) { // Ready imp.Basic = basic - typechoDB := DbReady(payload) + typechoDB, dErr := DbReady(payload) + if dErr != nil { + logFatal(dErr) + return + } GetParamsFrom(payload).To(map[string]interface{}{ "prefix": &imp.DbPrefix, @@ -74,7 +77,7 @@ func (imp *_TypechoImporter) Run(basic *BasicParams, payload []string) { // Load Options tbOptions := imp.DbPrefix + "options" typechoDB.Raw("SELECT * FROM " + tbOptions).Scan(&imp.Options) - logrus.Info(fmt.Sprintf("从数据表 `%s` 获取 %d 条记录", tbOptions, len(imp.Options))) + logInfo(fmt.Sprintf("从数据表 `%s` 获取 %d 条记录", tbOptions, len(imp.Options))) for _, opt := range imp.Options { switch opt.Name { @@ -94,7 +97,11 @@ func (imp *_TypechoImporter) Run(basic *BasicParams, payload []string) { if basic.TargetSiteUrl == "" && imp.SrcSiteURL != "" && lib.ValidateURL(imp.SrcSiteURL) { basic.TargetSiteUrl = imp.SrcSiteURL } - RequiredBasicTargetSite(basic) + rErr := RequiredBasicTargetSite(basic) + if rErr != nil { + logFatal(rErr) + return + } // 检查数据源版本号 imp.VersionCheck() @@ -105,27 +112,27 @@ func (imp *_TypechoImporter) Run(basic *BasicParams, payload []string) { // load Metas tbMetas := imp.DbPrefix + "metas" typechoDB.Raw("SELECT * FROM " + tbMetas).Scan(&imp.Metas) - logrus.Info(fmt.Sprintf("从数据表 `%s` 获取 %d 条记录", tbMetas, len(imp.Metas))) + logInfo(fmt.Sprintf("从数据表 `%s` 获取 %d 条记录", tbMetas, len(imp.Metas))) // load Relationships tbRelationships := imp.DbPrefix + "relationships" typechoDB.Raw("SELECT * FROM " + tbRelationships).Scan(&imp.Relationships) - logrus.Info(fmt.Sprintf("从数据表 `%s` 获取 %d 条记录", tbRelationships, len(imp.Relationships))) + logInfo(fmt.Sprintf("从数据表 `%s` 获取 %d 条记录", tbRelationships, len(imp.Relationships))) // 获取 contents tbContents := imp.DbPrefix + "contents" typechoDB.Raw(fmt.Sprintf("SELECT * FROM %s ORDER BY created ASC", tbContents)).Scan(&imp.Contents) - logrus.Info(fmt.Sprintf("从数据表 `%s` 获取 %d 条记录", tbContents, len(imp.Contents))) + logInfo(fmt.Sprintf("从数据表 `%s` 获取 %d 条记录", tbContents, len(imp.Contents))) // 获取 comments tbComments := imp.DbPrefix + "comments" typechoDB.Raw(fmt.Sprintf("SELECT * FROM %s ORDER BY created ASC", tbComments)).Scan(&imp.Comments) - logrus.Info(fmt.Sprintf("从数据表 `%s` 获取 %d 条记录", tbComments, len(imp.Comments))) + logInfo(fmt.Sprintf("从数据表 `%s` 获取 %d 条记录", tbComments, len(imp.Comments))) // 导入前参数汇总 - fmt.Print("\n") + print("\n") - fmt.Print("# 请过目:\n\n") + print("# 请过目:\n\n") // 显示第一条数据 pageKeyEgPost := "" @@ -133,9 +140,9 @@ func (imp *_TypechoImporter) Run(basic *BasicParams, payload []string) { for _, c := range imp.Contents { if c.Type == "post" { firstPost := SprintEncodeData("第一篇文章", imp.Contents[0]) - fmt.Print(HideJsonLongText("Text", firstPost)) + print(HideJsonLongText("Text", firstPost)) pageKeyEgPost = imp.GetNewPageKey(c) - fmt.Printf(" -> 生成 PageKey: %#v\n\n", pageKeyEgPost) + printf(" -> 生成 PageKey: %#v\n\n", pageKeyEgPost) break } } @@ -165,9 +172,9 @@ func (imp *_TypechoImporter) Run(basic *BasicParams, payload []string) { {"独立页面", fmt.Sprintf("%#v", imp.RewritePage), pageKeyEgPage}, }) - fmt.Print("\n") - fmt.Println("若以上内容不符合预期,请向我们反馈:https://artalk.js.org/guide/transfer.html") - fmt.Print("\n") + print("\n") + println("若以上内容不符合预期,请向我们反馈:https://artalk.js.org/guide/transfer.html") + print("\n") // 确认开始 if !Confirm("确认开始导入吗?") { @@ -175,10 +182,15 @@ func (imp *_TypechoImporter) Run(basic *BasicParams, payload []string) { } // 准备导入评论 - fmt.Println() + println() // 准备新的 site - imp.TargetSite = SiteReady(basic.TargetSiteName, basic.TargetSiteUrl) + targetSite, sErr := SiteReady(basic.TargetSiteName, basic.TargetSiteUrl) + if sErr != nil { + logFatal(sErr) + return + } + imp.TargetSite = targetSite // 开始执行导入 imp.ImportComments() @@ -189,9 +201,9 @@ func (imp *_TypechoImporter) ImportComments() { contents := imp.Contents comments := imp.Comments - fmt.Print("\n====================================\n\n") - logrus.Info(fmt.Sprintf("[开始导入] 共 %d 个页面,%d 条评论", len(contents), len(comments))) - fmt.Print("\n") + print("\n====================================\n\n") + logInfo(fmt.Sprintf("[开始导入] 共 %d 个页面,%d 条评论", len(contents), len(comments))) + print("\n") siteName := imp.Basic.TargetSiteName @@ -238,7 +250,7 @@ func (imp *_TypechoImporter) ImportComments() { // 保存到数据库 err := lib.DB.Create(&nComment).Error if err != nil { - logrus.Error(fmt.Sprintf("评论源 ID:%d 保存失败", co.Coid)) + logError(fmt.Sprintf("评论源 ID:%d 保存失败", co.Coid)) continue } @@ -246,7 +258,7 @@ func (imp *_TypechoImporter) ImportComments() { commentTotal++ } - fmt.Printf("+ [%-3d] 条评论 <- [%5d] %-30s | %#v\n", commentTotal, c.Cid, c.Slug, c.Title) + printf("+ [%-3d] 条评论 <- [%5d] %-30s | %#v\n", commentTotal, c.Cid, c.Slug, c.Title) } // reply id 重建 @@ -290,7 +302,7 @@ func (imp *_TypechoImporter) ReplaceAllBracketed(data string, replaces map[strin if val, isExist := replaces[key]; isExist { return val } else { - logrus.Error(fmt.Sprintf("[重写规则] \"%s\" 变量无效", key)) + logError(fmt.Sprintf("[重写规则] \"%s\" 变量无效", key)) } return m }) @@ -301,7 +313,7 @@ func (imp *_TypechoImporter) VersionCheck() { r := regexp.MustCompile(`Typecho[\s]*(.+)\/(.+)`) group := r.FindStringSubmatch(imp.SrcVersion) if len(group) < 2 { - logrus.Warn(`无法确认您的 Typecho 版本号:"` + fmt.Sprintf("%#v", imp.SrcVersion) + `"`) + logWarn(`无法确认您的 Typecho 版本号:"` + fmt.Sprintf("%#v", imp.SrcVersion) + `"`) return } @@ -310,10 +322,10 @@ func (imp *_TypechoImporter) VersionCheck() { if verMain < ParseVersion(TypechoTestedVerMain) || verSub < ParseVersion(TypechoTestedVerSub) { - fmt.Print("\n") - logrus.Warn(fmt.Sprintf("Typecho 当前版本 \"%s\" 旧于 \"Typecho %s/%s\"", + print("\n") + logWarn(fmt.Sprintf("Typecho 当前版本 \"%s\" 旧于 \"Typecho %s/%s\"", imp.SrcVersion, TypechoTestedVerMain, TypechoTestedVerSub)) - logrus.Warn("不确定导入是否能够成功导入,您可以选择升级 Typecho: http://docs.typecho.org/upgrade") + logWarn("不确定导入是否能够成功导入,您可以选择升级 Typecho: http://docs.typecho.org/upgrade") } } @@ -393,11 +405,11 @@ func (imp *_TypechoImporter) RewriteRuleReady() { route, err := imp.GetOptionRoute(routeName) if err != nil || route.URL == "" { if err != nil { - logrus.Error(err) + logError(err) } *field = defaultVal - logrus.Error("[重写规则] \"" + nameText + "\" 无法从数据库读取,将使用默认值 \"" + imp.RewritePost + "\"") + logError("[重写规则] \"" + nameText + "\" 无法从数据库读取,将使用默认值 \"" + imp.RewritePost + "\"") return } @@ -422,9 +434,9 @@ func (imp *_TypechoImporter) RewriteRuleReady() { // 保存从数据库读取到的 rule *field = readRule - logrus.Info("重写规则 \"" + nameText + "\" 读取成功") + logInfo("重写规则 \"" + nameText + "\" 读取成功") } else { - logrus.Info("[重写规则] 自定义 \""+nameText+"\" 规则:", fmt.Sprintf("%#v", *field)) + logInfo("[重写规则] 自定义 \""+nameText+"\" 规则:", fmt.Sprintf("%#v", *field)) } } diff --git a/lib/importer/valine.go b/lib/artransfer/valine.go similarity index 89% rename from lib/importer/valine.go rename to lib/artransfer/valine.go index afe5aa709..a6e0bfd0a 100644 --- a/lib/importer/valine.go +++ b/lib/artransfer/valine.go @@ -1,4 +1,4 @@ -package importer +package artransfer import ( "github.com/ArtalkJS/ArtalkGo/lib" @@ -18,10 +18,18 @@ type _ValineImporter struct { } func (imp *_ValineImporter) Run(basic *BasicParams, payload []string) { - RequiredBasicTargetSite(basic) + rErr := RequiredBasicTargetSite(basic) + if rErr != nil { + logFatal(rErr) + return + } // 读取文件 - jsonStr := JsonFileReady(payload) + jsonStr, jErr := JsonFileReady(payload) + if jErr != nil { + logFatal(jErr) + return + } // 解析 Valine JSON var vComments []ValineCommentFAS diff --git a/lib/importer/wordpress.go b/lib/artransfer/wordpress.go similarity index 93% rename from lib/importer/wordpress.go rename to lib/artransfer/wordpress.go index c55de148a..d07af98e8 100644 --- a/lib/importer/wordpress.go +++ b/lib/artransfer/wordpress.go @@ -1,4 +1,4 @@ -package importer +package artransfer var WordPressImporter = &_WordPressImporter{ ImporterInfo: ImporterInfo{ diff --git a/model/page.go b/model/page.go index 996f0ed5a..1cff432a4 100644 --- a/model/page.go +++ b/model/page.go @@ -13,7 +13,7 @@ import ( type Page struct { gorm.Model - Key string `gorm:"uniqueIndex"` // 页面 Key(一般为不含 hash/query 的完整 url) + Key string `gorm:"index"` // 页面 Key(一般为不含 hash/query 的完整 url) Title string AdminOnly bool From 2a8683a2d547cb4f3b2f7afe0f6740326f2ada6d Mon Sep 17 00:00:00 2001 From: qwqcode Date: Thu, 28 Oct 2021 20:52:54 +0800 Subject: [PATCH 085/349] fix(artrans): Modify Typecho boot param keys. Signed-off-by: qwqcode --- lib/artransfer/importer.go | 14 +++++++------- lib/artransfer/typecho.go | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/lib/artransfer/importer.go b/lib/artransfer/importer.go index 22fa1ee5f..e60f67063 100644 --- a/lib/artransfer/importer.go +++ b/lib/artransfer/importer.go @@ -136,13 +136,13 @@ func RequiredBasicTargetSite(basic *BasicParams) error { func DbReady(payload []string) (*gorm.DB, error) { var host, port, dbName, user, password, dbType, dbFile string GetParamsFrom(payload).To(map[string]interface{}{ - "host": &host, - "port": &port, - "db_name": &dbName, - "user": &user, - "password": &password, - "db_type": &dbType, - "db_file": &dbFile, + "db_host": &host, + "db_port": &port, + "db_name": &dbName, + "db_user": &user, + "db_password": &password, + "db_type": &dbType, + "db_file": &dbFile, }) if dbType == "" { diff --git a/lib/artransfer/typecho.go b/lib/artransfer/typecho.go index cf8bc999e..33b51de0c 100644 --- a/lib/artransfer/typecho.go +++ b/lib/artransfer/typecho.go @@ -65,7 +65,7 @@ func (imp *_TypechoImporter) Run(basic *BasicParams, payload []string) { } GetParamsFrom(payload).To(map[string]interface{}{ - "prefix": &imp.DbPrefix, + "db_prefix": &imp.DbPrefix, "rewrite_post": &imp.RewritePost, "rewrite_page": &imp.RewritePage, }) From 977e8af7e00aca20e3103b5f3367ab4d22c1add9 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Thu, 28 Oct 2021 22:37:32 +0800 Subject: [PATCH 086/349] chore: Modify export param. Signed-off-by: qwqcode --- cmd/export.go | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/cmd/export.go b/cmd/export.go index af5a9f902..df73b2a72 100644 --- a/cmd/export.go +++ b/cmd/export.go @@ -25,18 +25,17 @@ var exportCmd = &cobra.Command{ logrus.Fatal(err) } - outputFile := cmd.Flag("output").Value.String() - if outputFile == "" { + if len(args) < 1 || args[0] == "" { // write to stdout fmt.Println(jsonStr) } else { // mkdir -p - if err := lib.EnsureDir(filepath.Dir(outputFile)); err != nil { + if err := lib.EnsureDir(filepath.Dir(args[0])); err != nil { logrus.Fatal(err) } // touch - f, err := os.Create(outputFile) + f, err := os.Create(args[0]) if err != nil { logrus.Fatal(err) } @@ -52,6 +51,4 @@ var exportCmd = &cobra.Command{ func init() { rootCmd.AddCommand(exportCmd) - - flagP(exportCmd, "output", "o", "", "Write to file instead of stdout") } From 7db57dcd0b5019d9732bf67b7aa4b04b65cadc27 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Fri, 29 Oct 2021 08:16:25 +0800 Subject: [PATCH 087/349] fix(artrans): Frontend import Payload modify to JSON object. Signed-off-by: qwqcode --- http/api_admin_artransfer.go | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/http/api_admin_artransfer.go b/http/api_admin_artransfer.go index 076f1d6b6..5fbe346d0 100644 --- a/http/api_admin_artransfer.go +++ b/http/api_admin_artransfer.go @@ -4,6 +4,7 @@ import ( "encoding/json" "net/http" + "github.com/ArtalkJS/ArtalkGo/lib" "github.com/ArtalkJS/ArtalkGo/lib/artransfer" "github.com/labstack/echo/v4" ) @@ -23,13 +24,17 @@ func ActionAdminArtransfer(c echo.Context) error { return resp } - var payload []string - err := json.Unmarshal([]byte(p.Payload), &payload) + var payloadMap map[string]interface{} + err := json.Unmarshal([]byte(p.Payload), &payloadMap) if err != nil { return RespError(c, "payload 解析错误", Map{ "error": err, }) } + payload := []string{} + for k, v := range payloadMap { + payload = append(payload, k+":"+lib.ToString(v)) + } c.Response().Header().Set(echo.HeaderContentType, echo.MIMETextPlainCharsetUTF8) c.Response().WriteHeader(http.StatusOK) From 3d9ece48fa6df94860d7279189d1301b9a555683 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Sat, 30 Oct 2021 21:29:00 +0800 Subject: [PATCH 088/349] fix: PageEdit not work when Page is not created. --- http/api_admin_page_edit.go | 12 ++++++++++-- http/api_main_get.go | 6 ++++++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/http/api_admin_page_edit.go b/http/api_admin_page_edit.go index 125fbfd6b..98ec654d9 100644 --- a/http/api_admin_page_edit.go +++ b/http/api_admin_page_edit.go @@ -10,7 +10,7 @@ import ( type ParamsAdminPageEdit struct { // 查询值 - ID uint `mapstructure:"id" param:"required"` + ID uint `mapstructure:"id"` SiteName string `mapstructure:"site_name"` SiteID uint @@ -39,7 +39,15 @@ func ActionAdminPageEdit(c echo.Context) error { return resp } - page := model.FindPageByID(p.ID) + // check create page + var page model.Page + if p.ID == 0 { + // create new page + page = model.FindCreatePage(p.Key, p.Title, p.SiteName) + } else { + page = model.FindPageByID(p.ID) + } + if page.IsEmpty() { return RespError(c, "page not found") } diff --git a/http/api_main_get.go b/http/api_main_get.go index 2a69c28f1..f2ab1ce1c 100644 --- a/http/api_main_get.go +++ b/http/api_main_get.go @@ -65,6 +65,12 @@ func ActionGet(c echo.Context) error { var page model.Page if !p.SiteAll { page = model.FindPage(p.PageKey, p.SiteName) + if page.IsEmpty() { // if page not found + page = model.Page{ + Key: p.PageKey, + SiteName: p.SiteName, + } + } } // find user From 861abc2edd0108e69f1c4e7cf1c92ad813948146 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Sat, 30 Oct 2021 22:22:20 +0800 Subject: [PATCH 089/349] docs: Update README.md Signed-off-by: qwqcode --- README.md | 93 ++++++++++++------------------------------------------- 1 file changed, 20 insertions(+), 73 deletions(-) diff --git a/README.md b/README.md index 8f3061504..cf38bfb79 100644 --- a/README.md +++ b/README.md @@ -4,88 +4,30 @@ # ArtalkGo -> ArtalkGo: Golang backend of Artalk. - [![GitHub issues](https://img.shields.io/github/issues/ArtalkJS/ArtalkGo)](https://github.com/ArtalkJS/ArtalkGo/issues) [![](https://img.shields.io/github/issues-pr/ArtalkJS/ArtalkGo)](https://github.com/ArtalkJS/ArtalkGo/pulls) [![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2FArtalkJS%2FArtalkGo.svg?type=shield)](https://app.fossa.com/projects/git%2Bgithub.com%2FArtalkJS%2FArtalkGo?ref=badge_shield) [![CI to Docker Hub](https://github.com/ArtalkJS/ArtalkGo/actions/workflows/dockerhub.yml/badge.svg)](https://github.com/ArtalkJS/ArtalkGo/actions/workflows/dockerhub.yml) -- 高效 -- 跨平台 -- 轻松部署 -- 多站点支持 -- 多数据库类型支持 - -## Supports - -- 跨平台:支持 Linux, Win, Darwin -- 数据存储:支持 SQLite, MySQL, PostgreSQL, SQL Server -- 邮件发送:支持 SMTP, 阿里云邮件, 系统调用 sendmail 等发送邮件 -- 高效缓存:支持 Redis, Memory cache - -## 部署方针 - -### 普通方式 - -1. 前往 [Release](https://github.com/ArtalkJS/ArtalkGo/releases) 下载已编译二进制文件 -2. 解压程序 `tar -zxvf artalk-go.tar.gz` -3. 编辑配置 `vim artalk-go.yml` -4. 运行程序 `./artalk-go serve` -5. 反代设定的端口到 80 并套上 CDN (Nginx, Apache) -6. 持久化运作 artalk-go 程序 (tmux, sysctl) -7. 前端配置 - - ```js - new Artalk({ server: "http://your_domain:端口号/api" }) - ``` - -### Docker 容器(推荐) - -```sh -# 为 ArtalkGo 创建一个目录 -$ mkdir ArtalkGo -$ cd ArtalkGo - -# 下载配置文件模版 -$ curl -L https://raw.githubusercontent.com/ArtalkJS/ArtalkGo/main/artalk-go.example.yml > conf.yml - -# 编译配置文件 -$ vim conf.yml - -# 拉取 docker 镜像 -$ docker pull artalk/artalk-go - -# 新建 docker 容器 -$ docker run -d \ - --name artalk-go \ - -p 0.0.0.0:8080:23366 \ - -v $(pwd)/conf.yml:/conf.yml \ - -v $(pwd)/data:/data \ - artalk/artalk-go -``` - -- 前端配置地址 `http://your_domain:8080/api` +> ArtalkGo: Golang backend of Artalk. - ```js - new Artalk({ server: "http://your_domain:8080/api" }) - ``` +前往:[“**官方文档 · 后端部分**”](https://artalk.js.org/guide/backend/) -- 配置文件路径 `./conf.yml` -- 数据文件目录 `./data/` +--- -### Docker 升级 +- 高效灵快 +- 异步执行 +- 跨平台兼容 +- 轻量级部署 -```sh -# 暂停并删除正在运行的容器,然后从 DockerHub 拉取最新镜像 -docker stop artalk-go \ - && docker rm artalk-go \ - && docker pull artalk/artalk-go -``` +## Supports -之后,重新执行上面创建 Docker 容器步骤即可。 +- 运行环境:支持 Linux, Windows, Darwin (x86 + ARM) +- 数据存储:支持 SQLite, MySQL, PostgreSQL, SQL Server +- 邮件发送:支持 SMTP, 阿里云邮件, 调用 sendmail 发送邮件 +- 高效缓存:支持 Redis, Memory cache -## 编译 +## Build ### 编译二进制文件 @@ -127,10 +69,15 @@ $ make docker-push - [ ] 配置 (GUI) - [ ] 数据分页 - [x] 数据导入 + - [x] Artrans - [x] Artalk v1 (PHP) - [ ] WordPress - - [ ] Typecho -- [ ] 数据导出 + - [x] Typecho + - [x] Valine + - [ ] Disqus + - [ ] Commento + - [x] Twikoo +- [x] 数据导出 - [ ] 数据备份同步 - [x] 邮件异步队列发送 - [ ] 邮件队列持久化 From 2d29536fbc31029a6952306051e6550dbf696fad Mon Sep 17 00:00:00 2001 From: qwqcode Date: Tue, 2 Nov 2021 14:35:34 +0800 Subject: [PATCH 090/349] docs: Update README.md Signed-off-by: qwqcode --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index cf38bfb79..8938ed657 100644 --- a/README.md +++ b/README.md @@ -40,7 +40,7 @@ $ make all ### Docker 镜像制作 ```sh -## 制作镜像 +# 制作镜像 $ make docker-docker # 发布镜像 From 47e16fd3864dc52425e6651dcff7b3cbb3db6d54 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Tue, 2 Nov 2021 20:59:03 +0800 Subject: [PATCH 091/349] chore: Remove useless type conversion. Signed-off-by: qwqcode --- http/api_admin_comment_del.go | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/http/api_admin_comment_del.go b/http/api_admin_comment_del.go index 13476da4c..3494970e1 100644 --- a/http/api_admin_comment_del.go +++ b/http/api_admin_comment_del.go @@ -1,8 +1,6 @@ package http import ( - "strconv" - "github.com/ArtalkJS/ArtalkGo/lib" "github.com/ArtalkJS/ArtalkGo/model" "github.com/labstack/echo/v4" @@ -10,7 +8,7 @@ import ( ) type ParamsCommentDel struct { - ID string `mapstructure:"id" param:"required"` + ID uint `mapstructure:"id" param:"required"` SiteName string `mapstructure:"site_name"` SiteID uint @@ -27,17 +25,12 @@ func ActionAdminCommentDel(c echo.Context) error { return resp } - id, err := strconv.Atoi(p.ID) - if err != nil { - return RespError(c, "invalid id") - } - // find site if isOK, resp := CheckSite(c, &p.SiteName, &p.SiteID, &p.SiteAll); !isOK { return resp } - comment := model.FindComment(uint(id)) + comment := model.FindComment(p.ID) if comment.IsEmpty() { return RespError(c, "comment not found") } From 9bcd9921d53048278a0831db1b70eb5c808393ee Mon Sep 17 00:00:00 2001 From: qwqcode Date: Tue, 2 Nov 2021 22:47:04 +0800 Subject: [PATCH 092/349] feat: Specific comments get flat mode. Signed-off-by: qwqcode --- http/api_main_get.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/http/api_main_get.go b/http/api_main_get.go index f2ab1ce1c..fd4d899d2 100644 --- a/http/api_main_get.go +++ b/http/api_main_get.go @@ -25,6 +25,7 @@ type ParamsGet struct { SiteAll bool WithSites bool `mapstructure:"with_sites"` + FlatMode bool `mapstructure:"flat_mode"` IsAdminReq bool } @@ -87,6 +88,9 @@ func ActionGet(c echo.Context) error { // check if msg center isMsgCenter := IsMsgCenter(p) + if isMsgCenter { + p.FlatMode = true // 通知中心强制平铺模式 + } // comment parents var comments []model.Comment @@ -94,7 +98,7 @@ func ActionGet(c echo.Context) error { query := GetCommentQuery(c, p, p.SiteID).Scopes(Paginate(p.Offset, p.Limit)) cookedComments := []model.CookedComment{} - if !isMsgCenter { + if !p.FlatMode { query = query.Scopes(ParentComment()) query.Find(&comments) From 6d6a0504d8c487822b603686dd6c57b76aace16b Mon Sep 17 00:00:00 2001 From: qwqcode Date: Tue, 2 Nov 2021 23:55:20 +0800 Subject: [PATCH 093/349] feat: ApiVersion & FeMinVersion. Signed-off-by: qwqcode --- http/a_http.go | 7 +------ http/api_main_get.go | 13 +++---------- http/resp.go | 10 ++++++++++ lib/version.go | 3 +++ 4 files changed, 17 insertions(+), 16 deletions(-) diff --git a/http/a_http.go b/http/a_http.go index 5786e408b..5805cbbde 100644 --- a/http/a_http.go +++ b/http/a_http.go @@ -6,7 +6,6 @@ import ( "strings" "github.com/ArtalkJS/ArtalkGo/config" - "github.com/ArtalkJS/ArtalkGo/lib" "github.com/ArtalkJS/ArtalkGo/pkged" "github.com/labstack/echo/v4" "github.com/labstack/echo/v4/middleware" @@ -121,10 +120,6 @@ func InitRoute(e *echo.Echo) { // version api.Any("/version", func(c echo.Context) error { - return c.JSON(200, Map{ - "app": "artalk-go", - "version": lib.Version, - "commit_hash": lib.CommitHash, - }) + return c.JSON(200, GetApiVersionDataMap()) }) } diff --git a/http/api_main_get.go b/http/api_main_get.go index fd4d899d2..8089836a9 100644 --- a/http/api_main_get.go +++ b/http/api_main_get.go @@ -24,8 +24,7 @@ type ParamsGet struct { SiteID uint SiteAll bool - WithSites bool `mapstructure:"with_sites"` - FlatMode bool `mapstructure:"flat_mode"` + FlatMode bool `mapstructure:"flat_mode"` IsAdminReq bool } @@ -37,7 +36,7 @@ type ResponseGet struct { Page model.CookedPage `json:"page"` Unread []model.CookedNotify `json:"unread"` UnreadCount int `json:"unread_count"` - Sites []model.CookedSite `json:"sites,omitempty"` + ApiVersion Map `json:"api_version"` } // 获取评论查询实例 @@ -155,12 +154,6 @@ func ActionGet(c echo.Context) error { NotifyMarkAllAsRead(p.User.ID) } - // with sites for admin - sites := []model.CookedSite{} - if p.IsAdminReq && p.WithSites { - sites = GetAllCookedSites() - } - // unread notifies var unreadNotifies = []model.CookedNotify{} if p.User != nil { @@ -174,7 +167,7 @@ func ActionGet(c echo.Context) error { Page: page.ToCooked(), Unread: unreadNotifies, UnreadCount: len(unreadNotifies), - Sites: sites, + ApiVersion: GetApiVersionDataMap(), }) } diff --git a/http/resp.go b/http/resp.go index af5038aaa..3d1ce61ad 100644 --- a/http/resp.go +++ b/http/resp.go @@ -4,6 +4,7 @@ import ( "net/http" "strconv" + "github.com/ArtalkJS/ArtalkGo/lib" "github.com/labstack/echo/v4" "github.com/sirupsen/logrus" ) @@ -87,3 +88,12 @@ func LogWithHttpInfo(c echo.Context) *logrus.Entry { return logrus.WithFields(fields) } + +func GetApiVersionDataMap() Map { + return Map{ + "app": "artalk-go", + "version": lib.Version, + "commit_hash": lib.CommitHash, + "fe_min_version": lib.FeMinVersion, + } +} diff --git a/lib/version.go b/lib/version.go index 60d9bf9fe..ccc9d63cd 100644 --- a/lib/version.go +++ b/lib/version.go @@ -5,3 +5,6 @@ var ( Version string CommitHash string ) + +// 前端最小要求版本号 +var FeMinVersion string = "2.0.4" From db134ec18a1db6422211d430f9e83833f7c21b1d Mon Sep 17 00:00:00 2001 From: qwqcode Date: Tue, 2 Nov 2021 23:56:20 +0800 Subject: [PATCH 094/349] feat: FeMinVersion update to 2.0.5 Signed-off-by: qwqcode --- lib/version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/version.go b/lib/version.go index ccc9d63cd..bb1b75401 100644 --- a/lib/version.go +++ b/lib/version.go @@ -7,4 +7,4 @@ var ( ) // 前端最小要求版本号 -var FeMinVersion string = "2.0.4" +var FeMinVersion string = "2.0.5" From 2f638aabe3550e4e3ee17e0a568a14238f66054e Mon Sep 17 00:00:00 2001 From: qwqcode Date: Mon, 8 Nov 2021 15:37:24 +0800 Subject: [PATCH 095/349] feat: Pagination of admin_page_get. Signed-off-by: qwqcode --- http/api_admin_page_get.go | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/http/api_admin_page_get.go b/http/api_admin_page_get.go index 71a3702e5..f5364e202 100644 --- a/http/api_admin_page_get.go +++ b/http/api_admin_page_get.go @@ -10,6 +10,13 @@ type ParamsAdminPageGet struct { SiteName string `mapstructure:"site_name"` SiteID uint SiteAll bool + Limit int `mapstructure:"limit"` + Offset int `mapstructure:"offset"` +} + +type ResponseAdminPageGet struct { + Total int64 `json:"total"` + Pages []model.CookedPage `json:"pages"` } func ActionAdminPageGet(c echo.Context) error { @@ -27,11 +34,21 @@ func ActionAdminPageGet(c echo.Context) error { return resp } - var pages []model.Page + // 准备 query query := lib.DB.Model(&model.Page{}) if !p.SiteAll { // 不是查的所有站点 query = query.Where("site_name = ?", p.SiteName) } + + // 总共条数 + var total int64 + query.Count(&total) + + // 数据分页 + query = query.Scopes(Paginate(p.Offset, p.Limit)) + + // 查找 + var pages []model.Page query.Find(&pages) var cookedPages []model.CookedPage @@ -39,8 +56,8 @@ func ActionAdminPageGet(c echo.Context) error { cookedPages = append(cookedPages, p.ToCooked()) } - return RespData(c, Map{ - "pages": cookedPages, - "sites": GetAllCookedSites(), + return RespData(c, ResponseAdminPageGet{ + Pages: cookedPages, + Total: total, }) } From 24764a67bfb0c23cd72a8c98f95af0a1edb08ef1 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Mon, 8 Nov 2021 18:20:38 +0800 Subject: [PATCH 096/349] fix: admin_page_get default Sort by create_at DESC. Signed-off-by: qwqcode --- http/api_admin_page_get.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/http/api_admin_page_get.go b/http/api_admin_page_get.go index f5364e202..24ab7d24c 100644 --- a/http/api_admin_page_get.go +++ b/http/api_admin_page_get.go @@ -35,7 +35,7 @@ func ActionAdminPageGet(c echo.Context) error { } // 准备 query - query := lib.DB.Model(&model.Page{}) + query := lib.DB.Model(&model.Page{}).Order("created_at DESC") if !p.SiteAll { // 不是查的所有站点 query = query.Where("site_name = ?", p.SiteName) } From 16ba3bfd8467c185cc2003341969ae68283ee04f Mon Sep 17 00:00:00 2001 From: qwqcode Date: Tue, 9 Nov 2021 22:13:07 +0800 Subject: [PATCH 097/349] fix: admin_site_edit URL Validator bug. Signed-off-by: qwqcode --- http/a_http.go | 3 +- http/api_admin_site_edit.go | 2 +- ...in_artransfer.go => api_admin_transfer.go} | 33 ++++++++++++++++--- 3 files changed, 31 insertions(+), 7 deletions(-) rename http/{api_admin_artransfer.go => api_admin_transfer.go} (54%) diff --git a/http/a_http.go b/http/a_http.go index 5805cbbde..dce39200e 100644 --- a/http/a_http.go +++ b/http/a_http.go @@ -113,7 +113,8 @@ func InitRoute(e *echo.Echo) { admin.POST("/site-del", ActionAdminSiteDel) admin.POST("/setting-get", ActionAdminSettingGet) admin.POST("/setting-save", ActionAdminSettingSave) - admin.POST("/artransfer", ActionAdminArtransfer) + admin.POST("/import", ActionAdminImport) + admin.POST("/export", ActionAdminExport) // admin.POST("/vote-sync", ActionAdminVoteSync) // 数据导入功能未关注 vote 部分,暂时注释 admin.POST("/send-mail", ActionAdminSendMail) diff --git a/http/api_admin_site_edit.go b/http/api_admin_site_edit.go index 49fa9a655..802f6cfbc 100644 --- a/http/api_admin_site_edit.go +++ b/http/api_admin_site_edit.go @@ -44,7 +44,7 @@ func ActionAdminSiteEdit(c echo.Context) error { // urls 合法性检测 if p.Urls != "" { - for _, url := range site.ToCooked().Urls { + for _, url := range strings.Split(p.Urls, ",") { if !lib.ValidateURL(url) { return RespError(c, "Invalid url exist") } diff --git a/http/api_admin_artransfer.go b/http/api_admin_transfer.go similarity index 54% rename from http/api_admin_artransfer.go rename to http/api_admin_transfer.go index 5fbe346d0..c088de6ea 100644 --- a/http/api_admin_artransfer.go +++ b/http/api_admin_transfer.go @@ -9,18 +9,18 @@ import ( "github.com/labstack/echo/v4" ) -type ParamsAdminArtransfer struct { +type ParamsAdminImport struct { Type string `mapstructure:"type" param:"required"` Payload string `mapstructure:"payload"` } -func ActionAdminArtransfer(c echo.Context) error { +func ActionAdminImport(c echo.Context) error { if isOK, resp := AdminOnly(c); !isOK { return resp } - var p ParamsAdminArtransfer - if isOK, resp := ParamsDecode(c, ParamsAdminArtransfer{}, &p); !isOK { + var p ParamsAdminImport + if isOK, resp := ParamsDecode(c, ParamsAdminImport{}, &p); !isOK { return resp } @@ -36,15 +36,38 @@ func ActionAdminArtransfer(c echo.Context) error { payload = append(payload, k+":"+lib.ToString(v)) } - c.Response().Header().Set(echo.HeaderContentType, echo.MIMETextPlainCharsetUTF8) + c.Response().Header().Set(echo.HeaderContentType, echo.MIMETextHTMLCharsetUTF8) c.Response().WriteHeader(http.StatusOK) + c.Response().Write([]byte( + ` + `)) + c.Response().Flush() + artransfer.Assumeyes = true artransfer.HttpOutput = func(continueRun bool, text string) { c.Response().Write([]byte(text)) + c.Response().Write([]byte("")) c.Response().Flush() } artransfer.RunByName(p.Type, payload) return nil } + +func ActionAdminExport(c echo.Context) error { + if isOK, resp := AdminOnly(c); !isOK { + return resp + } + + jsonStr, err := artransfer.ExportArtransString() + if err != nil { + RespError(c, "导出错误", Map{ + "err": err, + }) + } + + return RespData(c, Map{ + "data": jsonStr, + }) +} From 83f9576de6451a24bdcdb0a6df0458fdf94033f2 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Tue, 9 Nov 2021 23:45:23 +0800 Subject: [PATCH 098/349] fix(vote): Vote up and down at the same time. Signed-off-by: qwqcode --- http/api_admin_vote_sync.go | 8 ++++ http/api_main_vote.go | 94 ++++++++++++++++++++----------------- 2 files changed, 58 insertions(+), 44 deletions(-) diff --git a/http/api_admin_vote_sync.go b/http/api_admin_vote_sync.go index ca508a638..9a53d0c47 100644 --- a/http/api_admin_vote_sync.go +++ b/http/api_admin_vote_sync.go @@ -53,3 +53,11 @@ func GetVoteNum(targetID uint, voteType string) int { lib.DB.Model(&model.Vote{}).Where("target_id = ? AND type = ?", targetID, voteType).Count(&num) return int(num) } + +func GetVoteNumUpDown(targetID uint, voteTo string) (int, int) { + var up int64 + var down int64 + lib.DB.Model(&model.Vote{}).Where("target_id = ? AND type = ?", targetID, voteTo+"_up").Count(&up) + lib.DB.Model(&model.Vote{}).Where("target_id = ? AND type = ?", targetID, voteTo+"_down").Count(&down) + return int(up), int(down) +} diff --git a/http/api_main_vote.go b/http/api_main_vote.go index 27eb190ff..ac11eddc5 100644 --- a/http/api_main_vote.go +++ b/http/api_main_vote.go @@ -10,7 +10,7 @@ import ( type ParamsVote struct { TargetID uint `mapstructure:"target_id" param:"required"` - Type string `mapstructure:"type"` + FullType string `mapstructure:"type"` Name string `mapstructure:"name"` Email string `mapstructure:"email"` @@ -31,13 +31,21 @@ func ActionVote(c echo.Context) error { return resp } + // find user + var user model.User + if p.Name != "" && p.Email != "" { + user = model.FindCreateUser(p.Name, p.Email, "") + } + ip := c.RealIP() // check type - isVoteComment := strings.HasPrefix(p.Type, "comment_") - isVotePage := strings.HasPrefix(p.Type, "page_") - isUp := strings.HasSuffix(p.Type, "_up") - isDown := strings.HasSuffix(p.Type, "_down") + isVoteComment := strings.HasPrefix(p.FullType, "comment_") + isVotePage := strings.HasPrefix(p.FullType, "page_") + isUp := strings.HasSuffix(p.FullType, "_up") + isDown := strings.HasSuffix(p.FullType, "_down") + voteTo := strings.TrimSuffix(strings.TrimSuffix(p.FullType, "_up"), "_down") + voteType := strings.TrimPrefix(strings.TrimPrefix(p.FullType, "comment_"), "page_") if !isUp && !isDown { return RespError(c, "unknown type") @@ -62,63 +70,61 @@ func ActionVote(c echo.Context) error { } // sync target model field value - sync := func(voteNum int) { + save := func(up int, down int) { switch { case isVoteComment: - if isUp { - comment.VoteUp = voteNum - } else { - comment.VoteDown = voteNum - } + comment.VoteUp = up + comment.VoteDown = down lib.DB.Save(&comment) case isVotePage: - if isUp { - page.VoteUp = voteNum - } else { - page.VoteDown = voteNum - } + page.VoteUp = up + page.VoteDown = down lib.DB.Save(&page) } } + createNew := func(t string) error { + // create new vote record + vote := model.Vote{ + TargetID: p.TargetID, + Type: model.VoteType(t), + UserID: user.ID, + UA: c.Request().UserAgent(), + IP: ip, + } + return lib.DB.Create(&vote).Error + } + // un-vote - var avaliableVote model.Vote - lib.DB.Where("target_id = ? AND type = ? AND ip = ?", p.TargetID, p.Type, ip).Find(&avaliableVote) - if !avaliableVote.IsEmpty() { - lib.DB.Unscoped().Delete(&avaliableVote) + var avaliableVotes []model.Vote + lib.DB.Where("target_id = ? AND type LIKE ? AND ip = ?", p.TargetID, voteTo+"%", ip).Find(&avaliableVotes) + if len(avaliableVotes) > 0 { + for _, v := range avaliableVotes { + lib.DB.Unscoped().Delete(&v) + } - voteNum := GetVoteNum(p.TargetID, p.Type) - sync(voteNum) + avaVoteType := strings.TrimPrefix(strings.TrimPrefix(string(avaliableVotes[0].Type), "comment_"), "page_") + if voteType != avaVoteType { + createNew(p.FullType) + } + + up, down := GetVoteNumUpDown(p.TargetID, voteTo) + save(up, down) return RespData(c, Map{ - "vote_num": voteNum, + "up": up, + "down": down, }) } - // find user - var user model.User - if p.Name != "" && p.Email != "" { - user = model.FindCreateUser(p.Name, p.Email, "") - } - - // create new vote record - vote := model.Vote{ - TargetID: p.TargetID, - Type: model.VoteType(p.Type), - UserID: user.ID, - UA: c.Request().UserAgent(), - IP: ip, - } - err := lib.DB.Create(&vote).Error - if err != nil { - return RespError(c, "vote create error") - } + createNew(p.FullType) // sync - voteNum := GetVoteNum(p.TargetID, p.Type) - sync(voteNum) + up, down := GetVoteNumUpDown(p.TargetID, voteTo) + save(up, down) return RespData(c, Map{ - "vote_num": voteNum, + "up": up, + "down": down, }) } From 2e5e04332b95a861e9406c51721fd15abbb8f122 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Thu, 11 Nov 2021 00:07:37 +0800 Subject: [PATCH 099/349] Update FeMinVersion to 2.1 Signed-off-by: qwqcode --- lib/version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/version.go b/lib/version.go index bb1b75401..8a256d490 100644 --- a/lib/version.go +++ b/lib/version.go @@ -7,4 +7,4 @@ var ( ) // 前端最小要求版本号 -var FeMinVersion string = "2.0.5" +var FeMinVersion string = "2.1.0" From 008a98fcfa6c595d19aefa53686801ea57b842da Mon Sep 17 00:00:00 2001 From: qwqcode Date: Sun, 14 Nov 2021 22:01:50 +0800 Subject: [PATCH 100/349] fix(artransfer): improve logger & twikoo importer bug. Signed-off-by: qwqcode --- lib/artransfer/artalk_v1.go | 6 +++++- lib/artransfer/artrans.go | 11 ++++++++++- lib/artransfer/importer.go | 37 +++++++++++++++++++++++++++++++++++++ lib/artransfer/twikoo.go | 6 +++++- lib/artransfer/valine.go | 6 +++++- 5 files changed, 62 insertions(+), 4 deletions(-) diff --git a/lib/artransfer/artalk_v1.go b/lib/artransfer/artalk_v1.go index ed255933c..0e63f7140 100644 --- a/lib/artransfer/artalk_v1.go +++ b/lib/artransfer/artalk_v1.go @@ -31,7 +31,11 @@ func (imp *_ArtalkV1Importer) Run(basic *BasicParams, payload []string) { } var aComments []ArtalkV1CommentAFS - JsonDecodeFAS(jsonStr, &aComments) + dErr := JsonDecodeFAS(jsonStr, &aComments) + if dErr != nil { + logFatal(dErr) + return + } tp := []model.Artran{} for _, tc := range aComments { diff --git a/lib/artransfer/artrans.go b/lib/artransfer/artrans.go index 68a1134ad..d5fc19c79 100644 --- a/lib/artransfer/artrans.go +++ b/lib/artransfer/artrans.go @@ -44,12 +44,21 @@ func (imp *_ArtransImporter) Run(basic *BasicParams, payload []string) { func ImportArtransByStr(basic *BasicParams, str string) { // 解析内容 comments := []model.Artran{} - JsonDecodeFAS(str, &comments) + dErr := JsonDecodeFAS(str, &comments) + if dErr != nil { + logFatal(dErr) + return + } ImportArtrans(basic, comments) } func ImportArtrans(basic *BasicParams, comments []model.Artran) { + if len(comments) == 0 { + logFatal("未读取到任何一条评论") + return + } + // 汇总 print("# 请过目:\n\n") diff --git a/lib/artransfer/importer.go b/lib/artransfer/importer.go index e60f67063..f120fe2a2 100644 --- a/lib/artransfer/importer.go +++ b/lib/artransfer/importer.go @@ -1,6 +1,7 @@ package artransfer import ( + "bytes" "encoding/json" "errors" "fmt" @@ -351,9 +352,45 @@ func GetArrayParamsFrom(payload []string, key string) []string { return arr } +func CheckIfJsonArr(str string) bool { + x := bytes.TrimLeft([]byte(str), " \t\r\n") + return len(x) > 0 && x[0] == '[' +} + +func CheckIfJsonObj(str string) bool { + x := bytes.TrimLeft([]byte(str), " \t\r\n") + return len(x) > 0 && x[0] == '{' +} + +func TryConvertLineJsonToArr(str string) (string, error) { + // 尝试将一行一行的 Obj 转成 Arr + arrTmp := []map[string]interface{}{} + for _, line := range strings.Split(str, "\n") { + var tmp map[string]interface{} + err := json.Unmarshal([]byte(line), &tmp) + if err != nil { + return "", err + } + arrTmp = append(arrTmp, tmp) + } + r, err := json.Marshal(arrTmp) + if err != nil { + return "", err + } + return string(r), nil +} + // Json Decode (FAS: Fields All String Type) // 解析 json 为字段全部是 string 类型的 struct func JsonDecodeFAS(str string, fasStructure interface{}) error { + if !CheckIfJsonArr(str) { + var err error + str, err = TryConvertLineJsonToArr(str) + if err != nil { + return errors.New("JSON 不是 Array 类型," + err.Error()) + } + } + err := json.Unmarshal([]byte(lib.JsonObjInArrAnyStr(str)), fasStructure) // lib.ToString() if err != nil { return errors.New("JSON 解析失败 " + err.Error()) diff --git a/lib/artransfer/twikoo.go b/lib/artransfer/twikoo.go index e6795266d..400a21b52 100644 --- a/lib/artransfer/twikoo.go +++ b/lib/artransfer/twikoo.go @@ -34,7 +34,11 @@ func (imp *_TwikooImporter) Run(basic *BasicParams, payload []string) { // 解析 Twikoo JSON var tComments []TwikooCommentFAS - JsonDecodeFAS(jsonStr, &tComments) + dErr := JsonDecodeFAS(jsonStr, &tComments) + if dErr != nil { + logFatal(dErr) + return + } // twikoo 转 ArtalkTransferParcel // @see https://github.com/imaegoo/twikoo/blob/c528c94105449c6b10c63bded6f813ceaee4bf74/src/vercel/api/index.js#L1155 diff --git a/lib/artransfer/valine.go b/lib/artransfer/valine.go index a6e0bfd0a..70c138784 100644 --- a/lib/artransfer/valine.go +++ b/lib/artransfer/valine.go @@ -33,7 +33,11 @@ func (imp *_ValineImporter) Run(basic *BasicParams, payload []string) { // 解析 Valine JSON var vComments []ValineCommentFAS - JsonDecodeFAS(jsonStr, &vComments) + dErr := JsonDecodeFAS(jsonStr, &vComments) + if dErr != nil { + logFatal(dErr) + return + } // Valine 数据格式转 Artrans tp := []model.Artran{} From 6c3415b6f383277b9c7d2456de8e8e15402c5dbe Mon Sep 17 00:00:00 2001 From: qwqcode Date: Mon, 15 Nov 2021 15:50:50 +0800 Subject: [PATCH 101/349] fix(artransfer): trim json string before checking array type. Signed-off-by: qwqcode --- lib/artransfer/importer.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/artransfer/importer.go b/lib/artransfer/importer.go index f120fe2a2..c5c1d56de 100644 --- a/lib/artransfer/importer.go +++ b/lib/artransfer/importer.go @@ -353,19 +353,19 @@ func GetArrayParamsFrom(payload []string, key string) []string { } func CheckIfJsonArr(str string) bool { - x := bytes.TrimLeft([]byte(str), " \t\r\n") + x := bytes.TrimSpace([]byte(str)) return len(x) > 0 && x[0] == '[' } func CheckIfJsonObj(str string) bool { - x := bytes.TrimLeft([]byte(str), " \t\r\n") + x := bytes.TrimSpace([]byte(str)) return len(x) > 0 && x[0] == '{' } func TryConvertLineJsonToArr(str string) (string, error) { // 尝试将一行一行的 Obj 转成 Arr arrTmp := []map[string]interface{}{} - for _, line := range strings.Split(str, "\n") { + for _, line := range strings.Split(strings.TrimSpace(str), "\n") { var tmp map[string]interface{} err := json.Unmarshal([]byte(line), &tmp) if err != nil { From 94754cf29c742f7c927b22a3673d8f93cfcbd6c2 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Mon, 15 Nov 2021 23:53:48 +0800 Subject: [PATCH 102/349] fix(artransfer): CreatedAt field recovery & json unmarshal number to float64 issue. Signed-off-by: qwqcode --- go.mod | 1 + go.sum | 6 ++++++ lib/artransfer/artrans.go | 9 +++++---- lib/artransfer/typecho.go | 4 ++-- lib/utils.go | 24 +++++++++--------------- 5 files changed, 23 insertions(+), 21 deletions(-) diff --git a/go.mod b/go.mod index 73fe6bb64..b9a0c27de 100644 --- a/go.mod +++ b/go.mod @@ -31,6 +31,7 @@ require ( github.com/spf13/cobra v1.2.1 github.com/spf13/viper v1.8.1 github.com/steambap/captcha v1.4.1 + github.com/tidwall/gjson v1.11.0 // indirect github.com/x-cray/logrus-prefixed-formatter v0.5.2 github.com/yuin/goldmark v1.4.0 golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 // indirect diff --git a/go.sum b/go.sum index b5232eff9..f85b69ce6 100644 --- a/go.sum +++ b/go.sum @@ -639,6 +639,12 @@ github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5Cc github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= +github.com/tidwall/gjson v1.11.0 h1:C16pk7tQNiH6VlCrtIXL1w8GaOsi1X3W8KDkE1BuYd4= +github.com/tidwall/gjson v1.11.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= +github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= +github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= +github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs= +github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= diff --git a/lib/artransfer/artrans.go b/lib/artransfer/artrans.go index d5fc19c79..bc773ca03 100644 --- a/lib/artransfer/artrans.go +++ b/lib/artransfer/artrans.go @@ -153,10 +153,6 @@ func ImportArtrans(basic *BasicParams, comments []model.Artran) { SiteName: site.Name, } - // 日期恢复 - nComment.CreatedAt = ParseDate(c.CreatedAt) - nComment.UpdatedAt = ParseDate(c.UpdatedAt) - // 保存到数据库 dErr := lib.DB.Create(&nComment).Error if dErr != nil { @@ -164,6 +160,11 @@ func ImportArtrans(basic *BasicParams, comments []model.Artran) { continue } + // 日期恢复 + // @see https://gorm.io/zh_CN/docs/conventions.html#CreatedAt + lib.DB.Model(&nComment).Update("CreatedAt", ParseDate(c.CreatedAt)) + lib.DB.Model(&nComment).Update("UpdatedAt", ParseDate(c.UpdatedAt)) + idChanges[uint(idMap[c.ID])] = nComment.ID bar.Increment() diff --git a/lib/artransfer/typecho.go b/lib/artransfer/typecho.go index 33b51de0c..8fc63fa42 100644 --- a/lib/artransfer/typecho.go +++ b/lib/artransfer/typecho.go @@ -244,8 +244,8 @@ func (imp *_TypechoImporter) ImportComments() { // 日期恢复 createdVal := fmt.Sprintf("%v", co.Created) - nComment.CreatedAt = ParseDate(createdVal) - nComment.UpdatedAt = ParseDate(createdVal) + lib.DB.Model(&nComment).Update("CreatedAt", ParseDate(createdVal)) + lib.DB.Model(&nComment).Update("UpdatedAt", ParseDate(createdVal)) // 保存到数据库 err := lib.DB.Create(&nComment).Error diff --git a/lib/utils.go b/lib/utils.go index cb1773d6f..5611195a9 100644 --- a/lib/utils.go +++ b/lib/utils.go @@ -13,6 +13,7 @@ import ( "strings" "github.com/jeremywohl/flatten" + "github.com/tidwall/gjson" "github.com/yuin/goldmark" "github.com/yuin/goldmark/extension" "github.com/yuin/goldmark/parser" @@ -121,26 +122,19 @@ func ToString(val interface{}) string { // => [{"a":"233"}, {"b":"true"}, {"c":"233"}] // @relevant ToString() func JsonObjInArrAnyStr(jsonStr string) string { - var raw []map[string]interface{} - json.Unmarshal([]byte(jsonStr), &raw) - var dest []interface{} - for _, item := range raw { - dest = append(dest, JsonObjAnyStr(item)) + var dest []map[string]string + for _, item := range gjson.Parse(jsonStr).Array() { + dItem := map[string]string{} + item.ForEach(func(key, value gjson.Result) bool { + dItem[key.String()] = value.String() + return true + }) + dest = append(dest, dItem) } j, _ := json.Marshal(dest) return string(j) } -// 将 JSON 对象的 Values 全部转成 String 类型 -// {"test":233} => {"test": "233"}, {"test": true} => {"test": "true"} -func JsonObjAnyStr(item map[string]interface{}) map[string]string { - dest := map[string]string{} - for k, v := range item { - dest[k] = ToString(v) - } - return dest -} - //#endregion //#region Validators From 63719332524f1ddbd650e852e6ce8accc14b8ca8 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Tue, 16 Nov 2021 17:49:57 +0800 Subject: [PATCH 103/349] fix(artransfer): typecho date recovery. Signed-off-by: qwqcode --- lib/artransfer/typecho.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/artransfer/typecho.go b/lib/artransfer/typecho.go index 8fc63fa42..e71c6d9ef 100644 --- a/lib/artransfer/typecho.go +++ b/lib/artransfer/typecho.go @@ -242,11 +242,6 @@ func (imp *_TypechoImporter) ImportComments() { IsPending: co.Status != "approved", } - // 日期恢复 - createdVal := fmt.Sprintf("%v", co.Created) - lib.DB.Model(&nComment).Update("CreatedAt", ParseDate(createdVal)) - lib.DB.Model(&nComment).Update("UpdatedAt", ParseDate(createdVal)) - // 保存到数据库 err := lib.DB.Create(&nComment).Error if err != nil { @@ -254,6 +249,11 @@ func (imp *_TypechoImporter) ImportComments() { continue } + // 日期恢复 + createdVal := fmt.Sprintf("%v", co.Created) + lib.DB.Model(&nComment).Update("CreatedAt", ParseDate(createdVal)) + lib.DB.Model(&nComment).Update("UpdatedAt", ParseDate(createdVal)) + idChanges[uint(co.Coid)] = nComment.ID commentTotal++ } From 6206d7dded2ebf4d28136a77b1ec163ab10bc647 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Thu, 18 Nov 2021 18:42:09 +0800 Subject: [PATCH 104/349] chore: Modify default email-tpl reply btn text. Signed-off-by: qwqcode --- email-tpl/default.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/email-tpl/default.html b/email-tpl/default.html index bfc81e6cc..6b7f765df 100644 --- a/email-tpl/default.html +++ b/email-tpl/default.html @@ -8,6 +8,6 @@
@{{reply_nick}}:
{{reply_content}}
-

传送门  »

+

回复  »

-- {{site_name}}
Powered By ArtalkGo

\ No newline at end of file From f48d7c891b9b47882147670f90f02b4ac57f7c0b Mon Sep 17 00:00:00 2001 From: qwqcode Date: Sun, 21 Nov 2021 00:13:30 +0800 Subject: [PATCH 105/349] fix: Rename field total_parents to total_roots. Signed-off-by: qwqcode --- http/api_main_get.go | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/http/api_main_get.go b/http/api_main_get.go index 8089836a9..ba9e3e282 100644 --- a/http/api_main_get.go +++ b/http/api_main_get.go @@ -30,13 +30,13 @@ type ParamsGet struct { } type ResponseGet struct { - Comments []model.CookedComment `json:"comments"` - Total int64 `json:"total"` - TotalParents int64 `json:"total_parents"` - Page model.CookedPage `json:"page"` - Unread []model.CookedNotify `json:"unread"` - UnreadCount int `json:"unread_count"` - ApiVersion Map `json:"api_version"` + Comments []model.CookedComment `json:"comments"` + Total int64 `json:"total"` + TotalRoots int64 `json:"total_roots"` + Page model.CookedPage `json:"page"` + Unread []model.CookedNotify `json:"unread"` + UnreadCount int `json:"unread_count"` + ApiVersion Map `json:"api_version"` } // 获取评论查询实例 @@ -98,7 +98,7 @@ func ActionGet(c echo.Context) error { cookedComments := []model.CookedComment{} if !p.FlatMode { - query = query.Scopes(ParentComment()) + query = query.Scopes(RootComments()) query.Find(&comments) for _, c := range comments { @@ -147,7 +147,7 @@ func ActionGet(c echo.Context) error { // count comments total := CountComments(GetCommentQuery(c, p, p.SiteID)) - totalParents := CountComments(GetCommentQuery(c, p, p.SiteID).Scopes(ParentComment())) + totalRoots := CountComments(GetCommentQuery(c, p, p.SiteID).Scopes(RootComments())) if isMsgCenter { // mark all as read @@ -161,13 +161,13 @@ func ActionGet(c echo.Context) error { } return RespData(c, ResponseGet{ - Comments: cookedComments, - Total: total, - TotalParents: totalParents, - Page: page.ToCooked(), - Unread: unreadNotifies, - UnreadCount: len(unreadNotifies), - ApiVersion: GetApiVersionDataMap(), + Comments: cookedComments, + Total: total, + TotalRoots: totalRoots, + Page: page.ToCooked(), + Unread: unreadNotifies, + UnreadCount: len(unreadNotifies), + ApiVersion: GetApiVersionDataMap(), }) } @@ -276,7 +276,7 @@ func SiteIsolation(c echo.Context, p ParamsGet) func(db *gorm.DB) *gorm.DB { } } -func ParentComment() func(db *gorm.DB) *gorm.DB { +func RootComments() func(db *gorm.DB) *gorm.DB { return func(db *gorm.DB) *gorm.DB { return db.Where("rid = 0") } From 6b7ba78395d4a47c3a88c72fa4f98783c97cc966 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Sat, 26 Feb 2022 20:07:44 +0800 Subject: [PATCH 106/349] fix: Fix wrong SQL syntax to support mysql database. Signed-off-by: qwqcode --- model/comment.go | 6 +++--- model/notify.go | 2 +- model/page.go | 4 ++-- model/query.go | 4 ++-- model/site.go | 2 +- model/user.go | 4 ++-- 6 files changed, 11 insertions(+), 11 deletions(-) diff --git a/model/comment.go b/model/comment.go index 8db6d900b..742c60b56 100644 --- a/model/comment.go +++ b/model/comment.go @@ -17,8 +17,8 @@ type Comment struct { Content string - PageKey string `gorm:"index"` - SiteName string `gorm:"index"` + PageKey string `gorm:"index;size:255"` + SiteName string `gorm:"index;size:255"` UserID uint `gorm:"index"` UA string @@ -64,7 +64,7 @@ func (c *Comment) FetchPage() Page { } var page Page - lib.DB.Where("key = ?", c.PageKey).First(&page) + lib.DB.Where("`key` = ?", c.PageKey).First(&page) c.Page = page return page diff --git a/model/notify.go b/model/notify.go index ee729abce..718f76cf4 100644 --- a/model/notify.go +++ b/model/notify.go @@ -19,7 +19,7 @@ type Notify struct { IsEmailed bool EmailAt time.Time - Key string `gorm:"index"` + Key string `gorm:"index;size:255"` Comment Comment `gorm:"foreignKey:CommentID;references:ID"` } diff --git a/model/page.go b/model/page.go index 1cff432a4..de4cd48f7 100644 --- a/model/page.go +++ b/model/page.go @@ -13,11 +13,11 @@ import ( type Page struct { gorm.Model - Key string `gorm:"index"` // 页面 Key(一般为不含 hash/query 的完整 url) + Key string `gorm:"index;size:255"` // 页面 Key(一般为不含 hash/query 的完整 url) Title string AdminOnly bool - SiteName string `gorm:"index"` + SiteName string `gorm:"index;size:255"` Site Site `gorm:"foreignKey:SiteName;references:Name"` VoteUp int diff --git a/model/query.go b/model/query.go index db09dd8b5..579ad2fd8 100644 --- a/model/query.go +++ b/model/query.go @@ -100,7 +100,7 @@ func FindNotify(userID uint, commentID uint) Notify { func FindNotifyByKey(key string) Notify { var notify Notify - lib.DB.Where("key = ?", key).First(¬ify) + lib.DB.Where("`key` = ?", key).First(¬ify) return notify } @@ -190,7 +190,7 @@ func UpdateUser(user *User) error { func FindPage(key string, siteName string) Page { var page Page - lib.DB.Where("key = ? AND site_name = ?", key, siteName).First(&page) + lib.DB.Where("`key` = ? AND `site_name` = ?", key, siteName).First(&page) return page } diff --git a/model/site.go b/model/site.go index f5886d841..4dbb826f6 100644 --- a/model/site.go +++ b/model/site.go @@ -9,7 +9,7 @@ import ( type Site struct { gorm.Model - Name string `gorm:"uniqueIndex"` + Name string `gorm:"uniqueIndex;size:255"` Urls string Users string // 分配给指定 UserIDs diff --git a/model/user.go b/model/user.go index 9dbf4c947..fcba7060f 100644 --- a/model/user.go +++ b/model/user.go @@ -6,8 +6,8 @@ import ( type User struct { gorm.Model - Name string `gorm:"index"` - Email string `gorm:"index"` + Name string `gorm:"index;size:255"` + Email string `gorm:"index;size:255"` Link string Password string BadgeName string From 211585016da4aeeb4e0d8b2c13e1347021d74ace Mon Sep 17 00:00:00 2001 From: qwqcode Date: Sat, 26 Feb 2022 20:55:47 +0800 Subject: [PATCH 107/349] feat: admin_users password support to be encrypted by using bcrypt. Signed-off-by: qwqcode --- http/api_user_login.go | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/http/api_user_login.go b/http/api_user_login.go index fdd7caa28..faa925f4c 100644 --- a/http/api_user_login.go +++ b/http/api_user_login.go @@ -1,8 +1,11 @@ package http import ( + "strings" + "github.com/ArtalkJS/ArtalkGo/model" "github.com/labstack/echo/v4" + "golang.org/x/crypto/bcrypt" ) type ParamsLogin struct { @@ -21,7 +24,23 @@ func ActionLogin(c echo.Context) error { RecordAction(c) user := model.FindUser(p.Name, p.Email) // name = ? OR email = ? - if user.IsEmpty() || user.Password != p.Password { + + if user.IsEmpty() { + return RespError(c, "验证失败") + } + + // 密码验证 + bcryptPrefix := "(bcrypt)" + if strings.HasPrefix(user.Password, bcryptPrefix) { + err := bcrypt.CompareHashAndPassword( + []byte(strings.TrimPrefix(user.Password, bcryptPrefix)), + []byte(p.Password), + ) + + if err != nil { + return RespError(c, "验证失败") + } + } else if user.Password != p.Password { return RespError(c, "验证失败") } @@ -29,3 +48,8 @@ func ActionLogin(c echo.Context) error { "token": LoginGetUserToken(user), }) } + +func HashPassword(password string) (string, error) { + bytes, err := bcrypt.GenerateFromPassword([]byte(password), 14) + return string(bytes), err +} From dbce93b40d8d66fa919f8dd20917ad886ff124b4 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Sat, 26 Feb 2022 21:06:10 +0800 Subject: [PATCH 108/349] feat: password support to be encrypted by md5. Signed-off-by: qwqcode --- http/api_user_login.go | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/http/api_user_login.go b/http/api_user_login.go index faa925f4c..0c8c41dfb 100644 --- a/http/api_user_login.go +++ b/http/api_user_login.go @@ -1,6 +1,8 @@ package http import ( + "crypto/md5" + "fmt" "strings" "github.com/ArtalkJS/ArtalkGo/model" @@ -31,16 +33,30 @@ func ActionLogin(c echo.Context) error { // 密码验证 bcryptPrefix := "(bcrypt)" - if strings.HasPrefix(user.Password, bcryptPrefix) { + md5Prefix := "(md5)" + passwordOK := false + switch { + case strings.HasPrefix(user.Password, bcryptPrefix): err := bcrypt.CompareHashAndPassword( []byte(strings.TrimPrefix(user.Password, bcryptPrefix)), []byte(p.Password), ) - if err != nil { - return RespError(c, "验证失败") + if err == nil { + passwordOK = true } - } else if user.Password != p.Password { + case strings.HasPrefix(user.Password, md5Prefix): + if strings.EqualFold(strings.TrimPrefix(user.Password, md5Prefix), + fmt.Sprintf("%x", md5.Sum([]byte(p.Password)))) { + passwordOK = true + } + default: + if user.Password == p.Password { + passwordOK = true + } + } + + if !passwordOK { return RespError(c, "验证失败") } From 109805894cbff1b9dfd5b95201d612b74e81197f Mon Sep 17 00:00:00 2001 From: qwqcode Date: Sat, 26 Feb 2022 21:10:34 +0800 Subject: [PATCH 109/349] feat: Update config example file. Signed-off-by: qwqcode --- artalk-go.example.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/artalk-go.example.yml b/artalk-go.example.yml index 2cd89a17f..7c85d6954 100644 --- a/artalk-go.example.yml +++ b/artalk-go.example.yml @@ -41,7 +41,7 @@ site_default: "默认站点" admin_users: - name: "admin" email: "admin@example.com" - password: "" + password: "" # 密码支持 bcrypt 或 md5 加密,例如填写:"(md5)50c21190c6e4e5418c6a90d2b5031119" badge_name: "管理员" badge_color: "#FF6C00" From 6bee451636e00fa6eeedf29b0f0b6ba0b6aef991 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Sat, 26 Feb 2022 21:28:28 +0800 Subject: [PATCH 110/349] fix: Wrong logic of captcha 'always' config. Signed-off-by: qwqcode --- http/permission.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/http/permission.go b/http/permission.go index 7ed1296b6..95c371e42 100644 --- a/http/permission.go +++ b/http/permission.go @@ -57,7 +57,12 @@ func ActionPermission(conf ActionPermissionConf) echo.MiddlewareFunc { // 操作是否超过限制 func IsActionOverLimit(c echo.Context) bool { if config.Instance.Captcha.Always { // 总是需要验证码 - return true + if getActionCount(c) <= 1 { + RecordAction(c) + return false + } else { + return true + } } if time.Since(getActionLastTime(c)).Seconds() <= float64(config.Instance.Captcha.ActionTimeout) { // 在时间内 From f420fb5cfd420a5c0dd7eb99bc7b5898e7749050 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Sat, 26 Feb 2022 22:18:04 +0800 Subject: [PATCH 111/349] fix: Reduce the use of native raw SQL to process boolean judgments and transfer them to ORM for processing. Signed-off-by: qwqcode --- cmd/root.go | 2 +- http/api_main_add.go | 2 +- model/query.go | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cmd/root.go b/cmd/root.go index a25a27b15..4b0a6dd5b 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -194,7 +194,7 @@ func syncConfWithDB() { // 清理配置文件中不存在的用户 var dbAdminUsers []model.User - lib.DB.Model(&model.User{}).Where("is_in_conf = 1").Find(&dbAdminUsers) + lib.DB.Model(&model.User{}).Where(&model.User{IsInConf: true}).Find(&dbAdminUsers) for _, dbU := range dbAdminUsers { isUserExist := func() bool { for _, confU := range config.Instance.AdminUsers { diff --git a/http/api_main_add.go b/http/api_main_add.go index b3c24646d..965c8b247 100644 --- a/http/api_main_add.go +++ b/http/api_main_add.go @@ -161,7 +161,7 @@ func EmailSend(comment *model.Comment, parentComment *model.Comment) { // 邮件通知管理员 var admins []model.User - lib.DB.Where("is_admin = 1").Find(&admins) + lib.DB.Where(&model.User{IsAdmin: true}).Find(&admins) isAdmin := func(userID uint) bool { for _, admin := range admins { diff --git a/model/query.go b/model/query.go index 579ad2fd8..c69b4dfe7 100644 --- a/model/query.go +++ b/model/query.go @@ -68,8 +68,8 @@ func StoreCache(name string, srcStruct interface{}) error { func IsAdminUser(name string, email string) bool { var user User - lib.DB.Where("LOWER(name) = LOWER(?) AND LOWER(email) = LOWER(?) AND is_admin = 1", name, email).First(&user) - return !user.IsEmpty() + lib.DB.Where("LOWER(name) = LOWER(?) AND LOWER(email) = LOWER(?)", name, email).First(&user) + return !user.IsEmpty() && user.IsAdmin } func UpdateComment(comment *Comment) error { From f518f438abf80ed04ac45d428475d35414f64c9a Mon Sep 17 00:00:00 2001 From: qwqcode Date: Sat, 26 Feb 2022 22:32:16 +0800 Subject: [PATCH 112/349] chore: Update artalk-go.example.yml. Signed-off-by: qwqcode --- artalk-go.example.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/artalk-go.example.yml b/artalk-go.example.yml index 7c85d6954..49c2e1301 100644 --- a/artalk-go.example.yml +++ b/artalk-go.example.yml @@ -15,8 +15,9 @@ timezone: "Asia/Shanghai" # 数据文件 db: - type: "sqlite" # 支持 mysql, sqlite, pgsql, sqlserver + type: "sqlite" # 支持 sqlite, mysql dsn: "./data/artalk-go.db" + #dsn: '用户名:密码@tcp(127.0.0.1:3306)/数据库?charset=utf8mb4&parseTime=true' # MySQL 连接配置 # 日志 log: From 3960a8356ec245b3ac5bec71cc014c113beb46eb Mon Sep 17 00:00:00 2001 From: qwqcode Date: Mon, 11 Apr 2022 21:45:08 +0800 Subject: [PATCH 113/349] fix(UA): Cooperate with client-side to correct Win11 UA. Signed-off-by: qwqcode --- http/api_main_add.go | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/http/api_main_add.go b/http/api_main_add.go index 965c8b247..ade89c354 100644 --- a/http/api_main_add.go +++ b/http/api_main_add.go @@ -1,6 +1,8 @@ package http import ( + "regexp" + "github.com/ArtalkJS/ArtalkGo/config" "github.com/ArtalkJS/ArtalkGo/lib" "github.com/ArtalkJS/ArtalkGo/lib/email" @@ -15,6 +17,7 @@ type ParamsAdd struct { Link string `mapstructure:"link"` Content string `mapstructure:"content" param:"required"` Rid uint `mapstructure:"rid"` + UA string `mapstructure:"ua"` PageKey string `mapstructure:"page_key" param:"required"` PageTitle string `mapstructure:"page_title"` @@ -44,6 +47,13 @@ func ActionAdd(c echo.Context) error { ip := c.RealIP() ua := c.Request().UserAgent() + // 仅允许针对 Win11 的 UA 修正 + if p.UA != "" { + if matchWin11, _ := regexp.MatchString(`Windows\W+NT\W+11.0`, p.UA); matchWin11 { + ua = p.UA + } + } + // record action for limiting action RecordAction(c) From bece167fea673f8f6b9a9666fe073ea17554e5ff Mon Sep 17 00:00:00 2001 From: qwqcode Date: Mon, 11 Apr 2022 23:32:44 +0800 Subject: [PATCH 114/349] feat: Add script to build artalk-sidebar Signed-off-by: qwqcode --- .gitignore | 4 ++++ .goreleaser.yml | 1 + Dockerfile | 18 ++---------------- docker-compose.yml | 1 - go.mod | 4 ++-- makefile | 18 +++++++++++------- scripts/build-frontend.sh | 29 +++++++++++++++++++++++++++++ 7 files changed, 49 insertions(+), 26 deletions(-) create mode 100755 scripts/build-frontend.sh diff --git a/.gitignore b/.gitignore index e006b8639..0668ba884 100644 --- a/.gitignore +++ b/.gitignore @@ -25,3 +25,7 @@ bin/ data/ dist/ pkged/pkged.go + +# always pull latest code and compile +frontend/sidebar +frontend/dist diff --git a/.goreleaser.yml b/.goreleaser.yml index d09a5305e..b345c87f2 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -16,6 +16,7 @@ before: hooks: # install dependencies - make install + - make build-frontend - make update # build multi-platform diff --git a/Dockerfile b/Dockerfile index 8be02f6d5..9cd7c4de1 100644 --- a/Dockerfile +++ b/Dockerfile @@ -6,25 +6,11 @@ WORKDIR /source # install tools RUN set -ex \ && apk upgrade \ - && apk add make git gcc musl-dev yarn + && apk add make git gcc musl-dev nodejs yarn -# 1. build frontend (using latest tag) -# RUN git clone https://github.com/ArtalkJS/Artalk.git Artalk \ -# && cd Artalk \ -# && git fetch --tags \ -# && git checkout $(git describe --tags --abbrev=0) - -# RUN set -ex \ -# && cd ./Artalk \ -# && yarn install --network-timeout 1000000 \ -# && yarn build - -# 2. build backend COPY . ./ArtalkGo -# copy frontend dist folder -# RUN cp -r ./Artalk/dist ./ArtalkGo/frontend - +# build RUN set -ex \ && cd ./ArtalkGo \ && git fetch --tags -f \ diff --git a/docker-compose.yml b/docker-compose.yml index 63887c28b..238b901d0 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -8,6 +8,5 @@ services: - "23366:23366" volumes: - ./email-tpl:/email-tpl - - ./frontend:/frontend - ./artalk-go.yml:/artalk-go.yml - ./data:/data \ No newline at end of file diff --git a/go.mod b/go.mod index b9a0c27de..a58809652 100644 --- a/go.mod +++ b/go.mod @@ -31,10 +31,10 @@ require ( github.com/spf13/cobra v1.2.1 github.com/spf13/viper v1.8.1 github.com/steambap/captcha v1.4.1 - github.com/tidwall/gjson v1.11.0 // indirect + github.com/tidwall/gjson v1.11.0 github.com/x-cray/logrus-prefixed-formatter v0.5.2 github.com/yuin/goldmark v1.4.0 - golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 // indirect + golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d // indirect golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359 // indirect golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect diff --git a/makefile b/makefile index 4d268e169..edd590302 100644 --- a/makefile +++ b/makefile @@ -4,27 +4,31 @@ COMMIT_HASH := $(shell git rev-parse --short HEAD) DEV_VERSION := dev-${COMMIT_HASH} GO_VERSION ?= 1.16.6 -all: install update build +all: install build .PHONY: install install: go mod tidy go install github.com/markbates/pkger/cmd/pkger -.PHONY: update -update: - pkger -include /frontend -include /email-tpl -o pkged - .PHONY: build -build: update +build: build-frontend update go build \ -ldflags "-s -w -X github.com/ArtalkJS/ArtalkGo/lib.Version=${VERSION} \ -X github.com/ArtalkJS/ArtalkGo/lib.CommitHash=${COMMIT_HASH}" \ -o bin/artalk-go \ github.com/ArtalkJS/ArtalkGo +.PHONY: build-frontend +build-frontend: + ./scripts/build-frontend.sh + +.PHONY: update +update: + pkger -include /frontend -include /email-tpl -o pkged + .PHONY: run -run: update build +run: all ./bin/artalk-go serve $(ARGS) .PHONY: dev diff --git a/scripts/build-frontend.sh b/scripts/build-frontend.sh new file mode 100755 index 000000000..a59576093 --- /dev/null +++ b/scripts/build-frontend.sh @@ -0,0 +1,29 @@ +#!/bin/bash + +set -e + +mkdir -p ./local/ + +cd ./local/ +rm -rf ./Artalk + +git clone https://github.com/ArtalkJS/Artalk.git Artalk +cd Artalk + +# using latest tag soruce code +git fetch --tags +git checkout $(git describe --tags --abbrev=0) + +yarn install --network-timeout 1000000 +yarn build:all + +cd ../../ + +rm -rf ./frontend/dist +rm -rf ./frontend/sidebar + +mkdir -p ./frontend/dist +cp -r ./local/Artalk/packages/artalk/dist/{Artalk.css,Artalk.js} ./frontend/dist + +mkdir -p ./frontend/sidebar +cp -r ./local/Artalk/packages/artalk-sidebar/dist/* ./frontend/sidebar From afd88967ab99496efc82725f7cba7f98a34b3713 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Mon, 11 Apr 2022 23:37:39 +0800 Subject: [PATCH 115/349] chore: Remove deprecated artransfer cdoe Signed-off-by: qwqcode --- cmd/export.go | 4 +- cmd/import.go | 4 +- lib/artransfer/artalk_v1.go | 77 -------------------------------- lib/artransfer/importer.go | 5 +-- lib/artransfer/twikoo.go | 89 ------------------------------------- lib/artransfer/valine.go | 83 ---------------------------------- lib/artransfer/wordpress.go | 16 ------- 7 files changed, 5 insertions(+), 273 deletions(-) delete mode 100644 lib/artransfer/artalk_v1.go delete mode 100644 lib/artransfer/twikoo.go delete mode 100644 lib/artransfer/valine.go delete mode 100644 lib/artransfer/wordpress.go diff --git a/cmd/export.go b/cmd/export.go index df73b2a72..0a159f5dc 100644 --- a/cmd/export.go +++ b/cmd/export.go @@ -14,8 +14,8 @@ import ( var exportCmd = &cobra.Command{ Use: "export", Aliases: []string{}, - Short: "数据搬家 - 迁出", - Long: "\n# 数据搬家 - 迁出\n\n 将所有数据从 ArtalkGo 导出,用作备份,或迁移至其他地方\n 打包所有数据并导出成 “ArtalkGo 数据行囊 (Artrans)”,为数据搬家做准备\n" + ` + Short: "数据迁移 - 迁出", + Long: "\n# 数据迁移 - 迁出\n\n 将所有数据从 ArtalkGo 导出,用作备份,或迁移至其他地方\n 打包所有数据并导出成 “ArtalkGo 数据行囊 (Artrans)”,为数据迁移做准备\n" + ` - 重新导入 ArtalkGo,可执行: artalk-go import <数据行囊文件路径> - 文档:https://artalk.js.org/guide/transfer.html `, diff --git a/cmd/import.go b/cmd/import.go index 4bcd677ce..be9c67da4 100644 --- a/cmd/import.go +++ b/cmd/import.go @@ -13,8 +13,8 @@ import ( var importCmd = &cobra.Command{ Use: "import <数据行囊文件路径>", Aliases: []string{}, - Short: "数据搬家 - 迁入", - Long: "\n# 数据搬家 - 迁入\n\n 从其他评论系统迁移数据到 ArtalkGo\n" + ` + Short: "数据迁移 - 迁入", + Long: "\n# 数据迁移 - 迁入\n\n 从其他评论系统迁移数据到 ArtalkGo\n" + ` - 例如:artalk-go import typecho [参数] - 文档:https://artalk.js.org/guide/transfer.html `, diff --git a/lib/artransfer/artalk_v1.go b/lib/artransfer/artalk_v1.go deleted file mode 100644 index 0e63f7140..000000000 --- a/lib/artransfer/artalk_v1.go +++ /dev/null @@ -1,77 +0,0 @@ -package artransfer - -import ( - "github.com/ArtalkJS/ArtalkGo/model" -) - -var ArtalkV1Importer = &_ArtalkV1Importer{ - ImporterInfo: ImporterInfo{ - Name: "artalk_v1", - Desc: "从 Artalk v1 (PHP) 导入数据", - Note: "", - }, -} - -type _ArtalkV1Importer struct { - ImporterInfo -} - -func (imp *_ArtalkV1Importer) Run(basic *BasicParams, payload []string) { - err := RequiredBasicTargetSite(basic) - if err != nil { - logFatal(err) - return - } - - // 读取文件 - jsonStr, jErr := JsonFileReady(payload) - if jErr != nil { - logFatal(jErr) - return - } - - var aComments []ArtalkV1CommentAFS - dErr := JsonDecodeFAS(jsonStr, &aComments) - if dErr != nil { - logFatal(dErr) - return - } - - tp := []model.Artran{} - for _, tc := range aComments { - tp = append(tp, model.Artran{ - ID: tc.ID, - Rid: tc.Rid, - Content: tc.Content, - UA: tc.UA, - IP: tc.IP, - IsCollapsed: tc.IsCollapsed, - IsPending: tc.IsPending, - CreatedAt: tc.Date, - UpdatedAt: tc.Date, - Nick: tc.Nick, - Email: tc.Email, - Link: tc.Link, - PageKey: tc.PageKey, - SiteName: basic.TargetSiteName, - SiteUrls: basic.TargetSiteUrl, - }) - } - - ImportArtrans(basic, tp) -} - -type ArtalkV1CommentAFS struct { - ID string `json:"id"` - Content string `json:"content"` - Nick string `json:"nick"` - Email string `json:"email"` - Link string `json:"link"` - UA string `json:"ua"` - PageKey string `json:"page_key"` - Rid string `json:"rid"` - IP string `json:"ip"` - Date string `json:"date"` - IsPending string `json:"is_pending"` - IsCollapsed string `json:"is_collapsed"` -} diff --git a/lib/artransfer/importer.go b/lib/artransfer/importer.go index c5c1d56de..518f3d660 100644 --- a/lib/artransfer/importer.go +++ b/lib/artransfer/importer.go @@ -29,9 +29,6 @@ type Map = map[string]interface{} var Supports = []interface{}{ ArtransImporter, TypechoImporter, - ValineImporter, - TwikooImporter, - ArtalkV1Importer, } func RunByName(dataType string, payload []string) { @@ -47,7 +44,7 @@ func RunByName(dataType string, payload []string) { print("\n") tableData := []table.Row{ - {"数据搬家 - 导入"}, + {"数据迁移 - 导入"}, {strings.ToUpper(name)}, {desc}, } diff --git a/lib/artransfer/twikoo.go b/lib/artransfer/twikoo.go deleted file mode 100644 index 400a21b52..000000000 --- a/lib/artransfer/twikoo.go +++ /dev/null @@ -1,89 +0,0 @@ -package artransfer - -import ( - "github.com/ArtalkJS/ArtalkGo/lib" - "github.com/ArtalkJS/ArtalkGo/model" -) - -var TwikooImporter = &_TwikooImporter{ - ImporterInfo: ImporterInfo{ - Name: "twikoo", - Desc: "从 Twikoo 导入数据", - Note: "", - }, -} - -type _TwikooImporter struct { - ImporterInfo - TargetSite model.Site -} - -func (imp *_TwikooImporter) Run(basic *BasicParams, payload []string) { - err := RequiredBasicTargetSite(basic) - if err != nil { - logFatal(err) - return - } - - // 读取文件 - jsonStr, jErr := JsonFileReady(payload) - if jErr != nil { - logFatal(jErr) - return - } - - // 解析 Twikoo JSON - var tComments []TwikooCommentFAS - dErr := JsonDecodeFAS(jsonStr, &tComments) - if dErr != nil { - logFatal(dErr) - return - } - - // twikoo 转 ArtalkTransferParcel - // @see https://github.com/imaegoo/twikoo/blob/c528c94105449c6b10c63bded6f813ceaee4bf74/src/vercel/api/index.js#L1155 - // rid 对应 _id @see https://github.com/imaegoo/twikoo/blob/c528c94105449c6b10c63bded6f813ceaee4bf74/src/vercel/api/index.js#L343 - tp := []model.Artran{} - for _, tc := range tComments { - tp = append(tp, model.Artran{ - ID: tc.ID, - Rid: tc.Rid, - Content: tc.Comment, - UA: tc.UA, - IP: tc.IP, - IsCollapsed: lib.ToString(false), - IsPending: lib.ToString(tc.IsSpam == "true"), - CreatedAt: tc.Created, - UpdatedAt: tc.Updated, - Nick: tc.Nick, - Email: tc.Mail, - Link: tc.Link, - PageKey: tc.Url, - SiteName: basic.TargetSiteName, - SiteUrls: basic.TargetSiteUrl, - }) - } - - ImportArtrans(basic, tp) -} - -// TwikooCommentFAS (Fields All String type) -type TwikooCommentFAS struct { - ID string `json:"_id"` - Uid string `json:"uid"` - Nick string `json:"nick"` - Mail string `json:"mail"` - MailMd5 string `json:"mailMd5"` - Link string `json:"link"` - UA string `json:"ua"` - IP string `json:"ip"` - Master string `json:"master"` - Url string `json:"url"` - Href string `json:"href"` - Comment string `json:"comment"` - Pid string `json:"pid"` - Rid string `json:"rid"` - IsSpam string `json:"isSpam"` - Created string `json:"created"` - Updated string `json:"updated"` -} diff --git a/lib/artransfer/valine.go b/lib/artransfer/valine.go deleted file mode 100644 index 70c138784..000000000 --- a/lib/artransfer/valine.go +++ /dev/null @@ -1,83 +0,0 @@ -package artransfer - -import ( - "github.com/ArtalkJS/ArtalkGo/lib" - "github.com/ArtalkJS/ArtalkGo/model" -) - -var ValineImporter = &_ValineImporter{ - ImporterInfo: ImporterInfo{ - Name: "valine", - Desc: "从 Valine 导入数据", - Note: "", - }, -} - -type _ValineImporter struct { - ImporterInfo -} - -func (imp *_ValineImporter) Run(basic *BasicParams, payload []string) { - rErr := RequiredBasicTargetSite(basic) - if rErr != nil { - logFatal(rErr) - return - } - - // 读取文件 - jsonStr, jErr := JsonFileReady(payload) - if jErr != nil { - logFatal(jErr) - return - } - - // 解析 Valine JSON - var vComments []ValineCommentFAS - dErr := JsonDecodeFAS(jsonStr, &vComments) - if dErr != nil { - logFatal(dErr) - return - } - - // Valine 数据格式转 Artrans - tp := []model.Artran{} - for _, vc := range vComments { - tp = append(tp, model.Artran{ - ID: vc.ObjectId, - Rid: vc.Rid, - Content: vc.Comment, - UA: vc.UA, - IP: vc.IP, - IsCollapsed: lib.ToString(false), - IsPending: lib.ToString(vc.IsSpam == "true"), - CreatedAt: vc.CreatedAt, - UpdatedAt: vc.UpdatedAt, - Nick: vc.Nick, - Email: vc.Mail, - Link: vc.Link, - PageKey: vc.Url, - SiteName: basic.TargetSiteName, - SiteUrls: basic.TargetSiteUrl, - }) - } - - ImportArtrans(basic, tp) -} - -// ValineCommentFAS (FieldAllStr) -type ValineCommentFAS struct { - ObjectId string `json:"objectId"` - Nick string `json:"nick"` - IP string `json:"ip"` - Mail string `json:"mail"` - MailMd5 string `json:"mailMd5"` - IsSpam string `json:"isSpam"` - UA string `json:"ua"` - Link string `json:"link"` - Pid string `json:"pid"` - Rid string `json:"rid"` - Comment string `json:"comment"` - Url string `json:"url"` - CreatedAt string `json:"createdAt"` - UpdatedAt string `json:"updatedAt"` -} diff --git a/lib/artransfer/wordpress.go b/lib/artransfer/wordpress.go deleted file mode 100644 index d07af98e8..000000000 --- a/lib/artransfer/wordpress.go +++ /dev/null @@ -1,16 +0,0 @@ -package artransfer - -var WordPressImporter = &_WordPressImporter{ - ImporterInfo: ImporterInfo{ - Name: "wordpress", - Desc: "从 WordPress 导入数据", - Note: "", - }, -} - -type _WordPressImporter struct { - ImporterInfo -} - -func (imp *_WordPressImporter) Run(basic *BasicParams, payload []string) { -} From 72383a0e08895ca3625bad01437511bfe739b4a6 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Mon, 11 Apr 2022 23:40:22 +0800 Subject: [PATCH 116/349] docs: Update README.md Signed-off-by: qwqcode --- README.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 8938ed657..83f308807 100644 --- a/README.md +++ b/README.md @@ -15,14 +15,14 @@ --- -- 高效灵快 +- 高效快速 - 异步执行 - 跨平台兼容 - 轻量级部署 ## Supports -- 运行环境:支持 Linux, Windows, Darwin (x86 + ARM) +- 运行环境:支持 Linux, Windows, Darwin (x64 + ARM) - 数据存储:支持 SQLite, MySQL, PostgreSQL, SQL Server - 邮件发送:支持 SMTP, 阿里云邮件, 调用 sendmail 发送邮件 - 高效缓存:支持 Redis, Memory cache @@ -66,16 +66,16 @@ $ make docker-push - [x] 评论 (增/删/改) - [x] 页面 (增/删/改) - [x] 站点 (增/删/改) + - [x] 数据分页 - [ ] 配置 (GUI) - - [ ] 数据分页 -- [x] 数据导入 +- [x] 数据导入 ([Artransfer](https://github.com/ArtalkJS/Artransfer)) - [x] Artrans - [x] Artalk v1 (PHP) - - [ ] WordPress + - [x] WordPress - [x] Typecho - [x] Valine - - [ ] Disqus - - [ ] Commento + - [x] Disqus + - [x] Commento - [x] Twikoo - [x] 数据导出 - [ ] 数据备份同步 From 17f6897d47aed68bd910c8278e191b6acf9c3fce Mon Sep 17 00:00:00 2001 From: qwqcode Date: Mon, 11 Apr 2022 23:46:05 +0800 Subject: [PATCH 117/349] fix: Dockerfile install bash Signed-off-by: qwqcode --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 9cd7c4de1..8c7de73b3 100644 --- a/Dockerfile +++ b/Dockerfile @@ -6,7 +6,7 @@ WORKDIR /source # install tools RUN set -ex \ && apk upgrade \ - && apk add make git gcc musl-dev nodejs yarn + && apk add make git gcc musl-dev nodejs yarn bash COPY . ./ArtalkGo From 60e91a5ae7a5b592fa787a5b7965576f532de450 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Tue, 12 Apr 2022 00:16:39 +0800 Subject: [PATCH 118/349] chore: Script check and install yarn Signed-off-by: qwqcode --- scripts/build-frontend.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/scripts/build-frontend.sh b/scripts/build-frontend.sh index a59576093..5c56fc074 100755 --- a/scripts/build-frontend.sh +++ b/scripts/build-frontend.sh @@ -2,6 +2,11 @@ set -e +if ! command -v yarn &> /dev/null +then + apt-get update && apt-get install --no-install-recommends -y -q nodejs yarn +fi + mkdir -p ./local/ cd ./local/ From aa902601fb8594ce8a0a59973c49c7f35f866236 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Tue, 12 Apr 2022 00:26:10 +0800 Subject: [PATCH 119/349] feat: Use bluemonday sanitizer Signed-off-by: qwqcode --- go.mod | 1 + go.sum | 6 ++++++ lib/utils.go | 9 ++++++++- 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index a58809652..a81b9c005 100644 --- a/go.mod +++ b/go.mod @@ -20,6 +20,7 @@ require ( github.com/mattn/go-runewidth v0.0.13 // indirect github.com/mattn/go-sqlite3 v1.14.8 // indirect github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect + github.com/microcosm-cc/bluemonday v1.0.18 github.com/mitchellh/mapstructure v1.4.1 github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect github.com/onrik/logrus v0.9.0 diff --git a/go.sum b/go.sum index f85b69ce6..2c1c8023b 100644 --- a/go.sum +++ b/go.sum @@ -80,6 +80,8 @@ github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6l github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= +github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk= +github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= @@ -284,6 +286,8 @@ github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsC github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= +github.com/gorilla/css v1.0.0 h1:BQqNyPTi50JCFMTw/b67hByjMVXZRwGha6wxVGkeihY= +github.com/gorilla/css v1.0.0/go.mod h1:Dn721qIggHpt4+EFCcTLTU/vk5ySda2ReITrtgBl60c= github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= @@ -458,6 +462,8 @@ github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0j github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d h1:5PJl274Y63IEHC+7izoQE9x6ikvDFZS2mDVS3drnohI= github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= +github.com/microcosm-cc/bluemonday v1.0.18 h1:6HcxvXDAi3ARt3slx6nTesbvorIc3QeTzBNRvWktHBo= +github.com/microcosm-cc/bluemonday v1.0.18/go.mod h1:Z0r70sCuXHig8YpBzCc5eGHAap2K7e/u082ZUpDRRqM= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= diff --git a/lib/utils.go b/lib/utils.go index 5611195a9..3e98ddd0a 100644 --- a/lib/utils.go +++ b/lib/utils.go @@ -13,6 +13,7 @@ import ( "strings" "github.com/jeremywohl/flatten" + "github.com/microcosm-cc/bluemonday" "github.com/tidwall/gjson" "github.com/yuin/goldmark" "github.com/yuin/goldmark/extension" @@ -48,6 +49,11 @@ func StructToFlatDotMap(s interface{}) map[string]interface{} { } func Marked(markdownStr string) (string, error) { + bmPolicy := bluemonday.UGCPolicy() + bmPolicy.RequireNoReferrerOnLinks(true) + bmPolicy.AllowAttrs("width", "height", "align").OnElements("img") + bmPolicy.AllowAttrs("style", "class", "align").OnElements("span", "p", "div", "a") + // https://github.com/yuin/goldmark#security md := goldmark.New( goldmark.WithExtensions(extension.GFM), @@ -57,6 +63,7 @@ func Marked(markdownStr string) (string, error) { goldmark.WithRendererOptions( html.WithHardWraps(), html.WithXHTML(), + html.WithUnsafe(), ), ) @@ -65,7 +72,7 @@ func Marked(markdownStr string) (string, error) { return "", err } - return buf.String(), nil + return bmPolicy.SanitizeReader(&buf).String(), nil } func AddQueryToURL(urlStr string, queryMap map[string]string) string { From 0df40c4fea9fb11a26d6caaa1b01aad523312440 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Tue, 12 Apr 2022 00:36:50 +0800 Subject: [PATCH 120/349] chore: Update script use volta install node Signed-off-by: qwqcode --- makefile | 1 + scripts/build-frontend.sh | 10 +++++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/makefile b/makefile index edd590302..0e1d9b6f6 100644 --- a/makefile +++ b/makefile @@ -71,6 +71,7 @@ release-dry-run: .PHONY: release # https://hub.docker.com/r/troian/golang-cross +# https://github.com/troian/golang-cross # https://goreleaser.com/cmd/goreleaser_release/ # --skip-validate 参数跳过 git checks (由于 pkger 和 .release-env 文件生成) release: diff --git a/scripts/build-frontend.sh b/scripts/build-frontend.sh index 5c56fc074..32ae3da08 100755 --- a/scripts/build-frontend.sh +++ b/scripts/build-frontend.sh @@ -4,7 +4,15 @@ set -e if ! command -v yarn &> /dev/null then - apt-get update && apt-get install --no-install-recommends -y -q nodejs yarn + apt-get update && apt-get install --no-install-recommends -y -q curl ca-certificates + + # Install volta + export VOLTA_HOME="${HOME}/.volta" + export PATH="${VOLTA_HOME}/bin:${PATH}" + bash -c "$(curl -fsSL https://get.volta.sh)" -- --skip-setup + + volta install node + volta install yarn fi mkdir -p ./local/ From 94859f8f54007c5726d14ccac894bad241bac9de Mon Sep 17 00:00:00 2001 From: qwqcode Date: Tue, 12 Apr 2022 09:00:22 +0800 Subject: [PATCH 121/349] feat: Global trusted_domain config Signed-off-by: qwqcode --- artalk-go.example.yml | 4 ++++ config/config.go | 31 ++++++++++++++++--------------- http/a_http.go | 15 ++++++++++++++- http/utils.go | 10 +++++++++- 4 files changed, 43 insertions(+), 17 deletions(-) diff --git a/artalk-go.example.yml b/artalk-go.example.yml index 49c2e1301..31c6ba366 100644 --- a/artalk-go.example.yml +++ b/artalk-go.example.yml @@ -24,6 +24,10 @@ log: enabled: true # 总开关 filename: "./data/artalk-go.log" # 日志文件路径 +# 可信域名 +trusted_domains: + - "https://artalk.你的域名:23366" + # 允许跨域访问的域名 allow_origins: - "*" # '*' 跨域无限制 diff --git a/config/config.go b/config/config.go index 65726f3e8..a4406e9d5 100644 --- a/config/config.go +++ b/config/config.go @@ -13,21 +13,22 @@ var Instance *Config // Config 配置 // @link https://godoc.org/github.com/mitchellh/mapstructure type Config struct { - AppKey string `mapstructure:"app_key" json:"app_key"` // 加密密钥 - Debug bool `mapstructure:"debug" json:"debug"` // 调试模式 - TimeZone string `mapstructure:"timezone" json:"timezone"` // 时区 - Host string `mapstructure:"host" json:"host"` // HTTP Server 监听 IP - Port int `mapstructure:"port" json:"port"` // HTTP Server 监听 Port - DB DBConf `mapstructure:"db" json:"db"` // 数据文件 - Log LogConf `mapstructure:"log" json:"log"` // 日志文件 - AllowOrigins []string `mapstructure:"allow_origins" json:"allow_origins"` // 允许跨域访问的域名 - SSL SSLConf `mapstructure:"ssl" json:"ssl"` // SSL - SiteDefault string `mapstructure:"site_default" json:"site_default"` // 默认站点名(当请求无指定 site_name 时使用) - AdminUsers []AdminUserConf `mapstructure:"admin_users" json:"admin_users"` // 管理员账户 - LoginTimeout int `mapstructure:"login_timeout" json:"login_timeout"` // 登陆超时 - Moderator ModeratorConf `mapstructure:"moderator" json:"moderator"` // 评论审查 - Captcha CaptchaConf `mapstructure:"captcha" json:"captcha"` // 验证码 - Email EmailConf `mapstructure:"email" json:"email"` // 邮箱提醒 + AppKey string `mapstructure:"app_key" json:"app_key"` // 加密密钥 + Debug bool `mapstructure:"debug" json:"debug"` // 调试模式 + TimeZone string `mapstructure:"timezone" json:"timezone"` // 时区 + Host string `mapstructure:"host" json:"host"` // HTTP Server 监听 IP + Port int `mapstructure:"port" json:"port"` // HTTP Server 监听 Port + DB DBConf `mapstructure:"db" json:"db"` // 数据文件 + Log LogConf `mapstructure:"log" json:"log"` // 日志文件 + AllowOrigins []string `mapstructure:"allow_origins" json:"allow_origins"` // 允许跨域访问的域名 + TrustedDomains []string `mapstructure:"trusted_domains" json:"trusted_domains"` // 可信任的域名 (新) + SSL SSLConf `mapstructure:"ssl" json:"ssl"` // SSL + SiteDefault string `mapstructure:"site_default" json:"site_default"` // 默认站点名(当请求无指定 site_name 时使用) + AdminUsers []AdminUserConf `mapstructure:"admin_users" json:"admin_users"` // 管理员账户 + LoginTimeout int `mapstructure:"login_timeout" json:"login_timeout"` // 登陆超时 + Moderator ModeratorConf `mapstructure:"moderator" json:"moderator"` // 评论审查 + Captcha CaptchaConf `mapstructure:"captcha" json:"captcha"` // 验证码 + Email EmailConf `mapstructure:"email" json:"email"` // 邮箱提醒 } type DBConf struct { diff --git a/http/a_http.go b/http/a_http.go index dce39200e..61198fa60 100644 --- a/http/a_http.go +++ b/http/a_http.go @@ -6,6 +6,7 @@ import ( "strings" "github.com/ArtalkJS/ArtalkGo/config" + "github.com/ArtalkJS/ArtalkGo/lib" "github.com/ArtalkJS/ArtalkGo/pkged" "github.com/labstack/echo/v4" "github.com/labstack/echo/v4/middleware" @@ -19,8 +20,20 @@ func Run() { e := echo.New() e.HideBanner = true + // 跨域控制 + allowOrigins := []string{} + allowOrigins = append(allowOrigins, config.Instance.AllowOrigins...) // 跨域独立配置 + for _, v := range config.Instance.TrustedDomains { // 可信域名配置 + if !lib.ContainsStr(allowOrigins, v) { + allowOrigins = append(allowOrigins, v) + } + } + if lib.ContainsStr(allowOrigins, "*") { // 通配符关闭跨域控制 + allowOrigins = []string{"*"} + } + e.Use(middleware.CORSWithConfig(middleware.CORSConfig{ - AllowOrigins: config.Instance.AllowOrigins, + AllowOrigins: allowOrigins, })) // Logger diff --git a/http/utils.go b/http/utils.go index bf82895c6..7f192b88c 100644 --- a/http/utils.go +++ b/http/utils.go @@ -135,12 +135,19 @@ func CheckReferer(c echo.Context, site model.Site) (bool, error) { return true, nil } + // 可信域名配置 + confTrustedDomains := config.Instance.TrustedDomains + // 请求 Referer 合法性判断 - if strings.TrimSpace(site.Urls) == "" { + if strings.TrimSpace(site.Urls) == "" && len(confTrustedDomains) == 0 { return true, nil // 若 url 字段为空,则取消控制 } allowUrls := site.ToCooked().Urls + if len(confTrustedDomains) != 0 { + allowUrls = append(allowUrls, confTrustedDomains...) + } + referer := c.Request().Referer() if referer == "" { return true, nil @@ -163,6 +170,7 @@ func CheckReferer(c echo.Context, site model.Site) (bool, error) { } if pu.Hostname() == pr.Hostname() { allow = true + break } } if !allow { From 597d4dbbd1831463fa6ddf0d5e503c874652ed92 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Tue, 12 Apr 2022 09:04:06 +0800 Subject: [PATCH 122/349] feat: trusted_domains disable referer check Signed-off-by: qwqcode --- http/utils.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/http/utils.go b/http/utils.go index 7f192b88c..527794184 100644 --- a/http/utils.go +++ b/http/utils.go @@ -143,6 +143,11 @@ func CheckReferer(c echo.Context, site model.Site) (bool, error) { return true, nil // 若 url 字段为空,则取消控制 } + // 可信域名出现通配符关闭 Referer 控制 + if lib.ContainsStr(confTrustedDomains, "*") { + return true, nil + } + allowUrls := site.ToCooked().Urls if len(confTrustedDomains) != 0 { allowUrls = append(allowUrls, confTrustedDomains...) From 79abdaed281989408da9128868e2a4cb5f9c1881 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Tue, 12 Apr 2022 09:15:14 +0800 Subject: [PATCH 123/349] feat: Remove example config allow_origins field Signed-off-by: qwqcode --- artalk-go.example.yml | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/artalk-go.example.yml b/artalk-go.example.yml index 31c6ba366..e83248a38 100644 --- a/artalk-go.example.yml +++ b/artalk-go.example.yml @@ -26,13 +26,9 @@ log: # 可信域名 trusted_domains: + # - "*" # 无限制 - "https://artalk.你的域名:23366" -# 允许跨域访问的域名 -allow_origins: - - "*" # '*' 跨域无限制 -# - 'http://localhost:8080' - # SSL ssl: enabled: false From e95a9448fec2a1a2d94859a7ddb526aec53c9155 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Tue, 12 Apr 2022 12:59:36 +0800 Subject: [PATCH 124/349] feat: Page PV counter Signed-off-by: qwqcode --- http/api_main_pv.go | 58 +++++++++++++++++++++++++++++++++++++++++++++ model/pv.go | 18 ++++++++++++++ model/query.go | 6 +++++ 3 files changed, 82 insertions(+) create mode 100644 http/api_main_pv.go create mode 100644 model/pv.go diff --git a/http/api_main_pv.go b/http/api_main_pv.go new file mode 100644 index 000000000..b9bc41fc6 --- /dev/null +++ b/http/api_main_pv.go @@ -0,0 +1,58 @@ +package http + +import ( + "github.com/ArtalkJS/ArtalkGo/lib" + "github.com/ArtalkJS/ArtalkGo/model" + "github.com/labstack/echo/v4" +) + +type ParamsPV struct { + PageKey string `mapstructure:"page_key" param:"required"` + PageTitle string `mapstructure:"page_title"` + + SiteName string `mapstructure:"site_name"` + + SiteID uint + SiteAll bool +} + +func ActionPV(c echo.Context) error { + var p ParamsPV + if isOK, resp := ParamsDecode(c, ParamsPV{}, &p); !isOK { + return resp + } + + // find site + if isOK, resp := CheckSite(c, &p.SiteName, &p.SiteID, &p.SiteAll); !isOK { + return resp + } + + // find page + page := model.FindCreatePage(p.PageKey, p.PageTitle, p.SiteName) + + // ip := c.RealIP() + // ua := c.Request().UserAgent() + + newPV := func() error { + // create new PV record + pv := model.PV{ + PageKey: page.Key, + SiteName: p.SiteName, + Num: 1, + } + return lib.DB.Create(&pv).Error + } + + pv := model.FindPV(p.PageKey, p.SiteName) + if pv.IsEmpty() { + newPV() + } else { + // +1s + pv.Num++ + lib.DB.Save(&pv) + } + + return RespData(c, Map{ + "pv": pv.Num, + }) +} diff --git a/model/pv.go b/model/pv.go new file mode 100644 index 000000000..0e2debba9 --- /dev/null +++ b/model/pv.go @@ -0,0 +1,18 @@ +package model + +import ( + "gorm.io/gorm" +) + +type PV struct { + gorm.Model + + PageKey string `gorm:"index;size:255"` // 浏览页面 + SiteName string `gorm:"index;size:255"` // 网站 + + Num uint // 浏览量 +} + +func (v *PV) IsEmpty() bool { + return v.ID == 0 +} diff --git a/model/query.go b/model/query.go index c69b4dfe7..97778d16d 100644 --- a/model/query.go +++ b/model/query.go @@ -255,3 +255,9 @@ func FindUnreadNotifies(userID uint) []CookedNotify { return cookedNotifies } + +func FindPV(pageKey string, siteName string) PV { + var pv PV + lib.DB.Where("page_key = ? AND site_name = ?", pageKey, siteName).First(&pv) + return pv +} From f5e2432eec1b2072cc1a842a0a4b8a663a437c18 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Tue, 12 Apr 2022 14:01:45 +0800 Subject: [PATCH 125/349] feat(pv): Make route rule & create pvs table Signed-off-by: qwqcode --- cmd/root.go | 3 ++- http/a_http.go | 1 + http/api_main_pv.go | 13 +++++-------- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/cmd/root.go b/cmd/root.go index 4b0a6dd5b..2e01d3a10 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -149,7 +149,8 @@ func initDB() { lib.DB = db // Migrate the schema - lib.DB.AutoMigrate(&model.Site{}, &model.Page{}, &model.User{}, &model.Comment{}, &model.Notify{}, &model.Vote{}) // 注意表的创建顺序,因为有关联字段 + lib.DB.AutoMigrate(&model.Site{}, &model.Page{}, &model.User{}, + &model.Comment{}, &model.Notify{}, &model.Vote{}, &model.PV{}) // 注意表的创建顺序,因为有关联字段 } // 4. 同步配置文件与数据库 diff --git a/http/a_http.go b/http/a_http.go index 61198fa60..3a872e01a 100644 --- a/http/a_http.go +++ b/http/a_http.go @@ -103,6 +103,7 @@ func InitRoute(e *echo.Echo) { api.POST("/login", ActionLogin) api.POST("/mark-read", ActionMarkRead) api.POST("/vote", ActionVote) + api.POST("/pv", ActionPV) // api/captcha ca := api.Group("/captcha") diff --git a/http/api_main_pv.go b/http/api_main_pv.go index b9bc41fc6..dc82ca936 100644 --- a/http/api_main_pv.go +++ b/http/api_main_pv.go @@ -33,19 +33,16 @@ func ActionPV(c echo.Context) error { // ip := c.RealIP() // ua := c.Request().UserAgent() - newPV := func() error { - // create new PV record - pv := model.PV{ + pv := model.FindPV(p.PageKey, p.SiteName) + if pv.IsEmpty() { + // create new pv record of page + pv = model.PV{ PageKey: page.Key, SiteName: p.SiteName, Num: 1, } - return lib.DB.Create(&pv).Error - } - pv := model.FindPV(p.PageKey, p.SiteName) - if pv.IsEmpty() { - newPV() + lib.DB.Create(&pv) } else { // +1s pv.Num++ From 931902fd8be0619d93ed343ce447fa2b6d921585 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Tue, 12 Apr 2022 14:05:49 +0800 Subject: [PATCH 126/349] docs: Update README.md Signed-off-by: qwqcode --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 83f308807..7739414d7 100644 --- a/README.md +++ b/README.md @@ -54,7 +54,7 @@ $ make docker-push - [x] 多数据库支持 - [x] 评论获取分页 - [x] 评论点赞投票 -- [ ] 实时浏览量统计 +- [x] 浏览量统计 - [x] 评论分页加载 - [x] 数据 - [x] 通知中心 From eda9ae4fd99ba5650ee4023db8c85268432b8df3 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Tue, 12 Apr 2022 16:19:15 +0800 Subject: [PATCH 127/349] fix(captcha): Always-mode fail on the first req & modify font size Signed-off-by: qwqcode --- http/a_http.go | 24 +++++++----------------- http/api_captcha.go | 43 ++++++++++++++++++++++++++++++++++++++----- http/permission.go | 45 +++++++++++++++++++++++++++++++-------------- 3 files changed, 76 insertions(+), 36 deletions(-) diff --git a/http/a_http.go b/http/a_http.go index 3a872e01a..74feecd7d 100644 --- a/http/a_http.go +++ b/http/a_http.go @@ -3,7 +3,6 @@ package http import ( "fmt" "net/http" - "strings" "github.com/ArtalkJS/ArtalkGo/config" "github.com/ArtalkJS/ArtalkGo/lib" @@ -43,24 +42,15 @@ func Run() { e.Use(echolog.Middleware(logConf)) // Action Limit - ActionPermissionConf := ActionPermissionConf{ - Skipper: func(c echo.Context) bool { - // 不启用操作限制的 path - skipPath := []string{ - "/api/captcha/", - "/api/get", // 获取评论不做限制 - } - - for _, p := range skipPath { - if strings.HasPrefix(c.Request().URL.Path, p) { - return true - } - } - - return false + ActionLimitConf := ActionLimitConf{ + // 启用操作限制路径白名单 + ProtectPaths: []string{ + "/api/add", + "/api/login", + "/api/vote", }, } - e.Use(ActionPermission(ActionPermissionConf)) + e.Use(ActionLimitMiddleware(ActionLimitConf)) CommonJwtConfig = middleware.JWTConfig{ Claims: &jwtCustomClaims{}, diff --git a/http/api_captcha.go b/http/api_captcha.go index 30447188e..af17b7159 100644 --- a/http/api_captcha.go +++ b/http/api_captcha.go @@ -3,6 +3,7 @@ package http import ( "bytes" "encoding/base64" + "image/color" "strings" "time" @@ -12,6 +13,10 @@ import ( "github.com/steambap/captcha" ) +var ( + CaptchaExpiration = 5 * time.Minute // 验证码 5 分钟内有效 +) + func ActionCaptchaGet(c echo.Context) error { ip := c.RealIP() @@ -30,13 +35,16 @@ func ActionCaptchaCheck(c echo.Context) error { if strings.ToLower(inputVal) == GetCaptchaRealCode(ip) { // 验证码正确 - ResetActionRecord(c) // 重置操作记录 - DisposeCaptcha(ip) // 销毁验证码 + ResetActionRecord(c) // 重置操作记录 + DisposeCaptcha(ip) // 销毁验证码 + SetCaptchaIsCheked(ip, true) // 记录该 IP 已经成功验证 return RespSuccess(c) } else { // 验证码错误 - RecordAction(c) // 记录操作 + RecordAction(c) // 记录操作 + DisposeCaptcha(ip) // 销毁验证码 + SetCaptchaIsCheked(ip, false) // 记录该 IP 验证码验证失败 return RespError(c, "验证码错误", Map{ "img_data": GetNewCaptchaImageBase64(ip), @@ -44,6 +52,7 @@ func ActionCaptchaCheck(c echo.Context) error { } } +// 获取 IP 验证码正确的值 func GetCaptchaRealCode(ip string) string { realVal := "" if val, err := lib.CACHE.Get(lib.Ctx, "captcha:"+ip); err == nil { @@ -52,19 +61,43 @@ func GetCaptchaRealCode(ip string) string { return strings.ToLower(realVal) } +// 获取新验证码 base64 格式图片 func GetNewCaptchaImageBase64(ip string) string { // generate a image pngBuffer := bytes.NewBuffer([]byte{}) - data, _ := captcha.New(150, 40) + data, _ := captcha.New(160, 40, func(o *captcha.Options) { + o.FontScale = 1 + o.CurveNumber = 2 + o.FontDPI = 85.0 + o.Noise = 0.7 + o.BackgroundColor = color.White + }) data.WriteImage(pngBuffer) base64 := "data:image/png;base64," + base64.StdEncoding.EncodeToString(pngBuffer.Bytes()) // save real code - lib.CACHE.Set(lib.Ctx, "captcha:"+ip, []byte(data.Text), &store.Options{Expiration: 5 * time.Minute}) // 5分钟失效 + lib.CACHE.Set(lib.Ctx, "captcha:"+ip, []byte(data.Text), &store.Options{Expiration: CaptchaExpiration}) return base64 } +// 销毁验证码 func DisposeCaptcha(ip string) { lib.CACHE.Delete(lib.Ctx, "captcha:"+ip) } + +// 获取 IP 是否验证码检测通过,已经有一次 +func GetCaptchaIsCheked(ip string) bool { + val, err := lib.CACHE.Get(lib.Ctx, "captcha-checked:"+ip) + return err == nil && string(val.([]byte)) == "1" +} + +// 设置该 IP 验证码成功验证,已经有一次 +func SetCaptchaIsCheked(ip string, isCheked bool) { + val := "0" + if isCheked { + val = "1" + } + + lib.CACHE.Set(lib.Ctx, "captcha-checked:"+ip, []byte(val), &store.Options{Expiration: CaptchaExpiration}) +} diff --git a/http/permission.go b/http/permission.go index 95c371e42..60698bb37 100644 --- a/http/permission.go +++ b/http/permission.go @@ -27,19 +27,33 @@ type jwtCustomClaims struct { } type Skipper func(echo.Context) bool -type ActionPermissionConf struct { - Skipper Skipper +type ActionLimitConf struct { + ProtectPaths []string } // 操作限制 中间件 -func ActionPermission(conf ActionPermissionConf) echo.MiddlewareFunc { +func ActionLimitMiddleware(conf ActionLimitConf) echo.MiddlewareFunc { return func(next echo.HandlerFunc) echo.HandlerFunc { return func(c echo.Context) error { - if conf.Skipper(c) { + // 路径是否启用操作限制 + pathInList := false + for _, p := range conf.ProtectPaths { + if strings.HasPrefix(c.Request().URL.Path, p) { + pathInList = true + break + } + } + if !pathInList { + return next(c) + } + + // 管理员直接忽略 + if CheckIsAdminReq(c) { return next(c) } - if !CheckIsAdminReq(c) && IsActionOverLimit(c) { + // 操作限制,响应需要验证码 + if IsActionOverLimit(c) { if config.Instance.Debug { logrus.Debug("[操作限制] 次数: ", getActionCount(c), ", 最后时间:", getActionLastTime(c)) } @@ -47,34 +61,37 @@ func ActionPermission(conf ActionPermissionConf) echo.MiddlewareFunc { "need_captcha": true, "img_data": GetNewCaptchaImageBase64(c.RealIP()), }) - } else { - return next(c) } + + return next(c) } } } // 操作是否超过限制 func IsActionOverLimit(c echo.Context) bool { - if config.Instance.Captcha.Always { // 总是需要验证码 - if getActionCount(c) <= 1 { - RecordAction(c) + userIP := c.RealIP() + // 总是需要验证码 + if config.Instance.Captcha.Always { + if GetCaptchaIsCheked(userIP) { // 只有验证码成功才放行 + SetCaptchaIsCheked(userIP, false) // 总是需要验证码,只允许放行一次 return false - } else { - return true } + + return true } + // 一段时间内操作次数限制 if time.Since(getActionLastTime(c)).Seconds() <= float64(config.Instance.Captcha.ActionTimeout) { // 在时间内 if getActionCount(c) >= config.Instance.Captcha.ActionLimit { // 操作次数超过 RecordAction(c) // 记录操作 - return true + return true // 需要验证码 } } else { // 不在时间内,超时 ResetActionRecord(c) // 重置操作记录 } - return false + return false // 放行 } // 记录操作 From c1dfcab0a6d0a157bd9470bbbc81472e1d77afbe Mon Sep 17 00:00:00 2001 From: qwqcode Date: Tue, 12 Apr 2022 16:44:23 +0800 Subject: [PATCH 128/349] fix(typo): CaptchaCheck typo Signed-off-by: qwqcode --- http/api_captcha.go | 18 +++++++++--------- http/permission.go | 4 ++-- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/http/api_captcha.go b/http/api_captcha.go index af17b7159..46fc00acc 100644 --- a/http/api_captcha.go +++ b/http/api_captcha.go @@ -35,16 +35,16 @@ func ActionCaptchaCheck(c echo.Context) error { if strings.ToLower(inputVal) == GetCaptchaRealCode(ip) { // 验证码正确 - ResetActionRecord(c) // 重置操作记录 - DisposeCaptcha(ip) // 销毁验证码 - SetCaptchaIsCheked(ip, true) // 记录该 IP 已经成功验证 + ResetActionRecord(c) // 重置操作记录 + DisposeCaptcha(ip) // 销毁验证码 + SetCaptchaIsChecked(ip, true) // 记录该 IP 已经成功验证 return RespSuccess(c) } else { // 验证码错误 - RecordAction(c) // 记录操作 - DisposeCaptcha(ip) // 销毁验证码 - SetCaptchaIsCheked(ip, false) // 记录该 IP 验证码验证失败 + RecordAction(c) // 记录操作 + DisposeCaptcha(ip) // 销毁验证码 + SetCaptchaIsChecked(ip, false) // 记录该 IP 验证码验证失败 return RespError(c, "验证码错误", Map{ "img_data": GetNewCaptchaImageBase64(ip), @@ -87,15 +87,15 @@ func DisposeCaptcha(ip string) { } // 获取 IP 是否验证码检测通过,已经有一次 -func GetCaptchaIsCheked(ip string) bool { +func GetCaptchaIsChecked(ip string) bool { val, err := lib.CACHE.Get(lib.Ctx, "captcha-checked:"+ip) return err == nil && string(val.([]byte)) == "1" } // 设置该 IP 验证码成功验证,已经有一次 -func SetCaptchaIsCheked(ip string, isCheked bool) { +func SetCaptchaIsChecked(ip string, isChecked bool) { val := "0" - if isCheked { + if isChecked { val = "1" } diff --git a/http/permission.go b/http/permission.go index 60698bb37..1ab2603cc 100644 --- a/http/permission.go +++ b/http/permission.go @@ -73,8 +73,8 @@ func IsActionOverLimit(c echo.Context) bool { userIP := c.RealIP() // 总是需要验证码 if config.Instance.Captcha.Always { - if GetCaptchaIsCheked(userIP) { // 只有验证码成功才放行 - SetCaptchaIsCheked(userIP, false) // 总是需要验证码,只允许放行一次 + if GetCaptchaIsChecked(userIP) { // 只有验证码成功才放行 + SetCaptchaIsChecked(userIP, false) // 总是需要验证码,只允许放行一次 return false } From fcfba0c6b552812cf395ab7aff617eaa133f08c0 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Tue, 12 Apr 2022 22:23:01 +0800 Subject: [PATCH 129/349] feat(api/get): SortBy & ViewOnlyAdmin param support. Signed-off-by: qwqcode --- http/api_main_add.go | 8 +++----- http/api_main_get.go | 44 +++++++++++++++++++++++++++++++++++++++++--- model/query.go | 15 +++++++++++++++ 3 files changed, 59 insertions(+), 8 deletions(-) diff --git a/http/api_main_add.go b/http/api_main_add.go index ade89c354..e54049f47 100644 --- a/http/api_main_add.go +++ b/http/api_main_add.go @@ -170,10 +170,8 @@ func EmailSend(comment *model.Comment, parentComment *model.Comment) { } // 邮件通知管理员 - var admins []model.User - lib.DB.Where(&model.User{IsAdmin: true}).Find(&admins) - - isAdmin := func(userID uint) bool { + admins := model.GetAllAdmins() + userIsAdmin := func(userID uint) bool { for _, admin := range admins { if admin.ID == userID { return true @@ -191,7 +189,7 @@ func EmailSend(comment *model.Comment, parentComment *model.Comment) { } // 管理员评论不回复给其他管理员 - if isAdmin(comment.UserID) { + if userIsAdmin(comment.UserID) { continue } diff --git a/http/api_main_get.go b/http/api_main_get.go index ba9e3e282..ba04a52d3 100644 --- a/http/api_main_get.go +++ b/http/api_main_get.go @@ -27,6 +27,12 @@ type ParamsGet struct { FlatMode bool `mapstructure:"flat_mode"` IsAdminReq bool + + // Sort By + SortBy string `mapstructure:"sort_by"` // date_asc, date_desc, vote + + // 只看 admin + ViewOnlyAdmin bool `mapstructure:"view_only_admin"` } type ResponseGet struct { @@ -41,7 +47,7 @@ type ResponseGet struct { // 获取评论查询实例 func GetCommentQuery(c echo.Context, p ParamsGet, siteID uint) *gorm.DB { - query := lib.DB.Model(&model.Comment{}).Order("created_at DESC") + query := lib.DB.Model(&model.Comment{}).Order(GetSortRuleSQL(p.SortBy, "created_at DESC")) if IsMsgCenter(p) { return query.Scopes(MsgCenter(c, p, siteID), SiteIsolation(c, p)) @@ -95,9 +101,11 @@ func ActionGet(c echo.Context) error { var comments []model.Comment query := GetCommentQuery(c, p, p.SiteID).Scopes(Paginate(p.Offset, p.Limit)) + query = query.Scopes(ViewOnlyAdmin(c, p)) // 装载只看管理员功能 cookedComments := []model.CookedComment{} if !p.FlatMode { + // 层级嵌套模式 query = query.Scopes(RootComments()) query.Find(&comments) @@ -113,7 +121,7 @@ func ActionGet(c echo.Context) error { } } } else { - // flat mode + // 平铺模式 query.Find(&comments) for _, c := range comments { @@ -129,7 +137,7 @@ func ActionGet(c echo.Context) error { return false } - // find linked comments + // find linked comments (被引用的评论,不单独显示) for _, comment := range comments { if comment.Rid == 0 || containsComment(comment.Rid) { continue @@ -276,6 +284,36 @@ func SiteIsolation(c echo.Context, p ParamsGet) func(db *gorm.DB) *gorm.DB { } } +// 只看管理员功能 +func ViewOnlyAdmin(c echo.Context, p ParamsGet) func(db *gorm.DB) *gorm.DB { + return func(db *gorm.DB) *gorm.DB { + // 是否启用 + if !p.ViewOnlyAdmin { + return db + } + + // 获取管理员列表 + adminIDs := model.GetAllAdminIDs() + + // 只允许管理员 user_id + return db.Where("user_id IN ?", adminIDs) + } +} + +// 排序规则 +func GetSortRuleSQL(sortBy string, defaultSQL string) string { + switch sortBy { + case "date_desc": + return "created_at DESC" + case "date_asc": + return "created_at ASC" + case "vote": + return "vote_up DESC, created_at DESC" + } + + return defaultSQL +} + func RootComments() func(db *gorm.DB) *gorm.DB { return func(db *gorm.DB) *gorm.DB { return db.Where("rid = 0") diff --git a/model/query.go b/model/query.go index 97778d16d..6edf00b2b 100644 --- a/model/query.go +++ b/model/query.go @@ -261,3 +261,18 @@ func FindPV(pageKey string, siteName string) PV { lib.DB.Where("page_key = ? AND site_name = ?", pageKey, siteName).First(&pv) return pv } + +func GetAllAdmins() []User { + var admins []User + lib.DB.Where(&User{IsAdmin: true}).Find(&admins) + return admins +} + +func GetAllAdminIDs() []uint { + admins := GetAllAdmins() + ids := []uint{} + for _, a := range admins { + ids = append(ids, a.ID) + } + return ids +} From e5aac45f1c145f80a39de327f4604fded4103dd1 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Tue, 12 Apr 2022 22:38:41 +0800 Subject: [PATCH 130/349] feat(model): Add IsPinned field into commnent model. Signed-off-by: qwqcode --- model/artran.go | 1 + model/comment.go | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/model/artran.go b/model/artran.go index 7ea1f7a22..c22305e93 100644 --- a/model/artran.go +++ b/model/artran.go @@ -12,6 +12,7 @@ type Artran struct { IP string `json:"ip"` IsCollapsed string `json:"is_collapsed"` // bool => string "true" or "false" IsPending string `json:"is_pending"` // bool + IsPinned string `json:"is_pinned"` // bool // vote VoteUp string `json:"vote_up"` diff --git a/model/comment.go b/model/comment.go index 742c60b56..33883dbd3 100644 --- a/model/comment.go +++ b/model/comment.go @@ -28,6 +28,7 @@ type Comment struct { IsCollapsed bool // 折叠 IsPending bool // 待审 + IsPinned bool // 置顶 User User `gorm:"foreignKey:UserID;references:ID"` Page Page `gorm:"foreignKey:PageKey;references:Key"` @@ -108,6 +109,7 @@ type CookedComment struct { Date string `json:"date"` IsCollapsed bool `json:"is_collapsed"` IsPending bool `json:"is_pending"` + IsPinned bool `json:"is_pinned"` IsAllowReply bool `json:"is_allow_reply"` Rid uint `json:"rid"` BadgeName string `json:"badge_name"` @@ -133,6 +135,7 @@ func (c *Comment) ToCooked() CookedComment { Date: c.CreatedAt.Local().Format("2006-01-02 15:04:05"), IsCollapsed: c.IsCollapsed, IsPending: c.IsPending, + IsPinned: c.IsPinned, IsAllowReply: c.IsAllowReply(), Rid: c.Rid, BadgeName: user.BadgeName, @@ -187,6 +190,7 @@ func (c *Comment) ToCookedForEmail() CookedCommentForEmail { UA: c.UA, IsCollapsed: c.IsCollapsed, IsPending: c.IsPending, + IsPinned: c.IsPinned, IsAllowReply: c.IsAllowReply(), Rid: c.Rid, BadgeName: user.BadgeName, @@ -255,6 +259,7 @@ func (c *Comment) ToArtran() Artran { IP: c.IP, IsCollapsed: lib.ToString(c.IsCollapsed), IsPending: lib.ToString(c.IsPending), + IsPinned: lib.ToString(c.IsPinned), VoteUp: lib.ToString(c.VoteUp), VoteDown: lib.ToString(c.VoteDown), CreatedAt: c.CreatedAt.String(), From a26e8f4360ece466e2f7aec1b567be353e34dde4 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Tue, 12 Apr 2022 22:41:54 +0800 Subject: [PATCH 131/349] feat(pin): Update admin_comment_edit api to edit IsPinned Signed-off-by: qwqcode --- http/api_admin_comment_edit.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/http/api_admin_comment_edit.go b/http/api_admin_comment_edit.go index 21e25adfb..4a6cf5a58 100644 --- a/http/api_admin_comment_edit.go +++ b/http/api_admin_comment_edit.go @@ -24,6 +24,7 @@ type ParamsCommentEdit struct { IP string `mapstructure:"ip"` IsCollapsed bool `mapstructure:"is_collapsed"` IsPending bool `mapstructure:"is_pending"` + IsPinned bool `mapstructure:"is_pinned"` } func ActionAdminCommentEdit(c echo.Context) error { @@ -80,6 +81,7 @@ func ActionAdminCommentEdit(c echo.Context) error { comment.IP = p.IP comment.IsCollapsed = p.IsCollapsed comment.IsPending = p.IsPending + comment.IsPinned = p.IsPinned if err := model.UpdateComment(&comment); err != nil { return RespError(c, "comment save error") From 3538d6a7c89f8921d2fbaea561dfebd0949b418b Mon Sep 17 00:00:00 2001 From: qwqcode Date: Wed, 13 Apr 2022 00:14:34 +0800 Subject: [PATCH 132/349] feat(pin): Pin comments keep most top & Child-comments recursive query use Cooked. Signed-off-by: qwqcode --- http/api_admin_comment_del.go | 16 +++++---- http/api_admin_page_del.go | 2 +- http/api_main_add.go | 1 + http/api_main_get.go | 62 ++++++++++++++++++++++++++++++++--- model/comment.go | 38 ++++++++++----------- 5 files changed, 88 insertions(+), 31 deletions(-) diff --git a/http/api_admin_comment_del.go b/http/api_admin_comment_del.go index 3494970e1..fe8ab834a 100644 --- a/http/api_admin_comment_del.go +++ b/http/api_admin_comment_del.go @@ -35,15 +35,17 @@ func ActionAdminCommentDel(c echo.Context) error { return RespError(c, "comment not found") } - if err := DelComment(&comment); err != nil { + if err := DelComment(comment.ID); err != nil { return RespError(c, "comment delete error") } + commentCooked := comment.ToCooked() + // 删除子评论 hasErr := false - children := comment.FetchChildren(func(db *gorm.DB) *gorm.DB { return db }) + children := commentCooked.FetchChildren(func(db *gorm.DB) *gorm.DB { return db }) for _, c := range children { - err := DelComment(&c) + err := DelComment(c.ID) if err != nil { hasErr = true } @@ -55,16 +57,16 @@ func ActionAdminCommentDel(c echo.Context) error { return RespSuccess(c) } -func DelComment(comment *model.Comment) error { +func DelComment(commentID uint) error { // 清除 notify - if err := lib.DB.Unscoped().Where("comment_id = ?", comment.ID).Delete(&model.Notify{}).Error; err != nil { + if err := lib.DB.Unscoped().Where("comment_id = ?", commentID).Delete(&model.Notify{}).Error; err != nil { return err } // 清除 vote if err := lib.DB.Unscoped().Where( "target_id = ? AND (type = ? OR type = ?)", - comment.ID, + commentID, string(model.VoteTypeCommentUp), string(model.VoteTypeCommentDown), ).Delete(&model.Vote{}).Error; err != nil { @@ -72,7 +74,7 @@ func DelComment(comment *model.Comment) error { } // 删除 comment - err := lib.DB.Delete(comment).Error + err := lib.DB.Delete(&model.Comment{}, commentID).Error if err != nil { return err } diff --git a/http/api_admin_page_del.go b/http/api_admin_page_del.go index ec0da7cca..fa03d1374 100644 --- a/http/api_admin_page_del.go +++ b/http/api_admin_page_del.go @@ -51,7 +51,7 @@ func DelPage(page *model.Page) error { lib.DB.Where("page_key = ? AND site_name = ?", page.Key, page.SiteName).Find(&comments) for _, c := range comments { - DelComment(&c) + DelComment(c.ID) } // 删除 vote diff --git a/http/api_main_add.go b/http/api_main_add.go index e54049f47..028ef791c 100644 --- a/http/api_main_add.go +++ b/http/api_main_add.go @@ -113,6 +113,7 @@ func ActionAdd(c echo.Context) error { IsPending: false, IsCollapsed: false, + IsPinned: false, User: user, Page: page, diff --git a/http/api_main_get.go b/http/api_main_get.go index ba04a52d3..c7682874b 100644 --- a/http/api_main_get.go +++ b/http/api_main_get.go @@ -101,7 +101,8 @@ func ActionGet(c echo.Context) error { var comments []model.Comment query := GetCommentQuery(c, p, p.SiteID).Scopes(Paginate(p.Offset, p.Limit)) - query = query.Scopes(ViewOnlyAdmin(c, p)) // 装载只看管理员功能 + query = query.Scopes(ViewOnlyAdmin(c, p)) // 装载只看管理员功能 + query = query.Scopes(PinnedCommentsScope(c, p)) // 评论置顶功能总控制 cookedComments := []model.CookedComment{} if !p.FlatMode { @@ -113,11 +114,13 @@ func ActionGet(c echo.Context) error { cookedComments = append(cookedComments, c.ToCooked()) } - // comment children - for _, parent := range comments { // TODO: Read more children, pagination for children comment + pinnedCommentsFunction(c, p, &cookedComments) // 插入置顶评论 + + // 获取 comment 子评论 + for _, parent := range cookedComments { // TODO: Read more children, pagination for children comment children := parent.FetchChildren(SiteIsolation(c, p), AllowedComment(c, p)) for _, child := range children { - cookedComments = append(cookedComments, child.ToCooked()) + cookedComments = append(cookedComments, child) } } } else { @@ -128,6 +131,8 @@ func ActionGet(c echo.Context) error { cookedComments = append(cookedComments, c.ToCooked()) } + pinnedCommentsFunction(c, p, &cookedComments) // 插入置顶评论 + containsComment := func(cid uint) bool { for _, c := range cookedComments { if c.ID == cid { @@ -300,6 +305,55 @@ func ViewOnlyAdmin(c echo.Context, p ParamsGet) func(db *gorm.DB) *gorm.DB { } } +func PinnedCommentsScope(c echo.Context, p ParamsGet) func(db *gorm.DB) *gorm.DB { + return func(db *gorm.DB) *gorm.DB { + if p.Offset == 0 { + return db + } else { + // 其他页面不再显示置顶内容 + return db.Where("is_pinned = 0") + } + } +} + +func pinnedCommentsFunction(c echo.Context, p ParamsGet, cookedComments *[]model.CookedComment) { + // 仅在分页的首页加入置顶评论 + if p.Offset != 0 { + return + } + + pinnedComments := []model.Comment{} + GetCommentQuery(c, p, p.SiteID).Where("is_pinned = 1").Find(&pinnedComments) + + if len(pinnedComments) == 0 { + return // 没有置顶评论 + } + + // cook + pinnedCookedComments := []model.CookedComment{} + for _, pCo := range pinnedComments { + pinnedCookedComments = append(pinnedCookedComments, pCo.ToCooked()) + } + + // 去掉已 pinned 且重复存在于原列表中的评论 + filteredCookedComments := []model.CookedComment{} + for _, co := range *cookedComments { + isExistInPinnedList := false + for _, pCo := range pinnedComments { + if co.ID == pCo.ID { + isExistInPinnedList = true + break + } + } + if !isExistInPinnedList { + filteredCookedComments = append(filteredCookedComments, co) + } + } + + // prepend + *cookedComments = append(pinnedCookedComments, filteredCookedComments...) +} + // 排序规则 func GetSortRuleSQL(sortBy string, defaultSQL string) string { switch sortBy { diff --git a/model/comment.go b/model/comment.go index 33883dbd3..098ffe732 100644 --- a/model/comment.go +++ b/model/comment.go @@ -26,9 +26,9 @@ type Comment struct { Rid uint `gorm:"index"` // 父评论 ID - IsCollapsed bool // 折叠 - IsPending bool // 待审 - IsPinned bool // 置顶 + IsCollapsed bool `gorm:"default:false"` // 折叠 + IsPending bool `gorm:"default:false"` // 待审 + IsPinned bool `gorm:"default:false"` // 置顶 User User `gorm:"foreignKey:UserID;references:ID"` Page Page `gorm:"foreignKey:PageKey;references:Key"` @@ -83,22 +83,6 @@ func (c *Comment) FetchSite() Site { return site } -func (c Comment) FetchChildren(filters ...func(db *gorm.DB) *gorm.DB) []Comment { - children := []Comment{} - fetchChildrenOnce(&children, c, filters...) // TODO: children 数量限制 - return children -} - -func fetchChildrenOnce(src *[]Comment, parentComment Comment, filters ...func(db *gorm.DB) *gorm.DB) { - children := []Comment{} - lib.DB.Scopes(filters...).Where("rid = ?", parentComment.ID).Order("created_at ASC").Find(&children) - - for _, child := range children { - *src = append(*src, child) - fetchChildrenOnce(src, child, filters...) // loop - } -} - type CookedComment struct { ID uint `json:"id"` Content string `json:"content"` @@ -148,6 +132,22 @@ func (c *Comment) ToCooked() CookedComment { } } +func (c CookedComment) FetchChildren(filters ...func(db *gorm.DB) *gorm.DB) []CookedComment { + children := []CookedComment{} + fetchChildrenOnce(&children, c, filters...) // TODO: children 数量限制 + return children +} + +func fetchChildrenOnce(src *[]CookedComment, parentComment CookedComment, filters ...func(db *gorm.DB) *gorm.DB) { + children := []Comment{} + lib.DB.Scopes(filters...).Where("rid = ?", parentComment.ID).Order("created_at ASC").Find(&children) + + for _, child := range children { + *src = append(*src, child.ToCooked()) + fetchChildrenOnce(src, child.ToCooked(), filters...) // loop + } +} + type CookedCommentForEmail struct { CookedComment Content string `json:"content"` From 1016adf0caa2e98b824544a69121b7d0f82dd7d5 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Wed, 13 Apr 2022 00:52:10 +0800 Subject: [PATCH 133/349] docs: Update README.md Signed-off-by: qwqcode --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 7739414d7..9d59cb5c5 100644 --- a/README.md +++ b/README.md @@ -56,7 +56,8 @@ $ make docker-push - [x] 评论点赞投票 - [x] 浏览量统计 - [x] 评论分页加载 -- [x] 数据 +- [x] 评论置顶 / 精华 +- [x] 评论排序 (热度 / 时间) - [x] 通知中心 - [x] 提及 - [x] 全部 @@ -101,7 +102,7 @@ $ make docker-push - [x] 全局验证码操作次数限制 - [x] JWT 登陆状态验证 - [x] 时区自定义 -- [ ] 评论置顶 / 精华 +- [x] 只看作者功能 - [ ] AT 提及 (@) - [ ] 评论提及 (#) - [ ] 表情包统一管理 From 5a6f9260852646bc66e3f97249bb79113cb1d4ba Mon Sep 17 00:00:00 2001 From: qwqcode Date: Wed, 13 Apr 2022 18:34:40 +0800 Subject: [PATCH 134/349] feat(img-upload): Add img-upload option to config file. Signed-off-by: qwqcode --- artalk-go.example.yml | 11 +++++++++++ config/config.go | 14 ++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/artalk-go.example.yml b/artalk-go.example.yml index e83248a38..91da0de1e 100644 --- a/artalk-go.example.yml +++ b/artalk-go.example.yml @@ -80,3 +80,14 @@ email: access_key_id: "" # 阿里云颁发给用户的访问服务所用的密钥 ID access_key_secret: "" # 用于加密的密钥 account_name: "example@example.com" # 管理控制台中配置的发信地址 + +# 图片上传 +img-upload: + enabled: true # 总开关 + path: "./data/artalk-img/" # 图片存放路径 + max_size: 10 # 图片大小限制 (单位:MB) + quality: 100 # 图片质量 (启用图片压缩) + # 使用 upgit 将图片上传到 GitHub 或图床 (https://github.com/pluveto/upgit) + upgit: + enabled: false # 启用 upgit + exec: "./upgit -c -t /artalk-img" diff --git a/config/config.go b/config/config.go index a4406e9d5..7c4e4ab59 100644 --- a/config/config.go +++ b/config/config.go @@ -29,6 +29,7 @@ type Config struct { Moderator ModeratorConf `mapstructure:"moderator" json:"moderator"` // 评论审查 Captcha CaptchaConf `mapstructure:"captcha" json:"captcha"` // 验证码 Email EmailConf `mapstructure:"email" json:"email"` // 邮箱提醒 + ImgUpload ImgUploadConf `mapstructure:"img_upload" json:"img_upload"` // 图片上传 } type DBConf struct { @@ -111,6 +112,19 @@ const ( TypeSendmail EmailSenderType = "sendmail" ) +type ImgUploadConf struct { + Enabled bool `mapstructure:"enabled" json:"enabled"` // 总开关 + Path string `mapstructure:"path" json:"path"` // 图片存放路径 + MaxSize string `mapstructure:"max_size" json:"max_size"` // 图片大小限制 + Quality string `mapstructure:"quality" json:"quality"` // 图片质量 + Upgit UpgitConf `mapstructure:"upgit" json:"upgit"` // upgit +} + +type UpgitConf struct { + Enabled bool `mapstructure:"enabled" json:"enabled"` // 启用 upgit + Exec string `mapstructure:"exec" json:"exec"` // 启动命令 +} + // Init 初始化配置 func Init(cfgFile string) { viper.SetConfigType("yaml") From 7b2db0faf802c63262e6f5dc5f98bfcf96d49139 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Wed, 13 Apr 2022 21:06:37 +0800 Subject: [PATCH 135/349] feat(img-upload): Image Upload Api Signed-off-by: qwqcode --- artalk-go.example.yml | 4 +- config/config.go | 11 +-- http/a_http.go | 10 +++ http/api_main_img_upload.go | 149 ++++++++++++++++++++++++++++++++++++ 4 files changed, 167 insertions(+), 7 deletions(-) create mode 100644 http/api_main_img_upload.go diff --git a/artalk-go.example.yml b/artalk-go.example.yml index 91da0de1e..bccf6ed2b 100644 --- a/artalk-go.example.yml +++ b/artalk-go.example.yml @@ -82,11 +82,11 @@ email: account_name: "example@example.com" # 管理控制台中配置的发信地址 # 图片上传 -img-upload: +img_upload: enabled: true # 总开关 path: "./data/artalk-img/" # 图片存放路径 max_size: 10 # 图片大小限制 (单位:MB) - quality: 100 # 图片质量 (启用图片压缩) + public_path: null # 指定图片链接基础路径 (默认为 "/static/images/") # 使用 upgit 将图片上传到 GitHub 或图床 (https://github.com/pluveto/upgit) upgit: enabled: false # 启用 upgit diff --git a/config/config.go b/config/config.go index 7c4e4ab59..49b88f190 100644 --- a/config/config.go +++ b/config/config.go @@ -113,11 +113,12 @@ const ( ) type ImgUploadConf struct { - Enabled bool `mapstructure:"enabled" json:"enabled"` // 总开关 - Path string `mapstructure:"path" json:"path"` // 图片存放路径 - MaxSize string `mapstructure:"max_size" json:"max_size"` // 图片大小限制 - Quality string `mapstructure:"quality" json:"quality"` // 图片质量 - Upgit UpgitConf `mapstructure:"upgit" json:"upgit"` // upgit + Enabled bool `mapstructure:"enabled" json:"enabled"` // 总开关 + Path string `mapstructure:"path" json:"path"` // 图片存放路径 + MaxSize int64 `mapstructure:"max_size" json:"max_size"` // 图片大小限制 + Quality string `mapstructure:"quality" json:"quality"` // 图片质量 + PublicPath string `mapstructure:"public_path" json:"public_path"` // 图片 URL 基础路径 + Upgit UpgitConf `mapstructure:"upgit" json:"upgit"` // upgit } type UpgitConf struct { diff --git a/http/a_http.go b/http/a_http.go index 74feecd7d..653ae81f5 100644 --- a/http/a_http.go +++ b/http/a_http.go @@ -95,6 +95,16 @@ func InitRoute(e *echo.Echo) { api.POST("/vote", ActionVote) api.POST("/pv", ActionPV) + // api/upload-img + api.POST("/img-upload", ActionImgUpload) + if config.Instance.ImgUpload.Enabled { + if config.Instance.ImgUpload.Path == "" { + logrus.Fatal("图片上传功能需配置 img_upload.path") + } + // 静态可访问图片存放目录 + e.Static(ImgUpload_RoutePath, config.Instance.ImgUpload.Path) + } + // api/captcha ca := api.Group("/captcha") ca.GET("/refresh", ActionCaptchaGet) diff --git a/http/api_main_img_upload.go b/http/api_main_img_upload.go new file mode 100644 index 000000000..db323a445 --- /dev/null +++ b/http/api_main_img_upload.go @@ -0,0 +1,149 @@ +package http + +import ( + "fmt" + "io/ioutil" + "net/http" + "os" + "path" + "strings" + "time" + + "github.com/ArtalkJS/ArtalkGo/config" + "github.com/ArtalkJS/ArtalkGo/lib" + "github.com/labstack/echo/v4" + "github.com/sirupsen/logrus" +) + +// 图片目录路由重写路径 +var ImgUpload_RoutePath = "/static/images/" + +type ParamsImgUpload struct { + Name string `mapstructure:"name" param:"required"` + Email string `mapstructure:"email" param:"required"` + + PageKey string `mapstructure:"page_key" param:"required"` + PageTitle string `mapstructure:"page_title"` + + SiteName string `mapstructure:"site_name"` + + SiteID uint + SiteAll bool +} + +func ActionImgUpload(c echo.Context) error { + // 功能开关 + if !config.Instance.ImgUpload.Enabled { + return RespError(c, "图片上传功能已禁用", Map{ + "img_upload_enabled": false, + }) + } + + // 传入参数解析 + var p ParamsImgUpload + if isOK, resp := ParamsDecode(c, ParamsImgUpload{}, &p); !isOK { + return resp + } + + if !lib.ValidateEmail(p.Email) { + return RespError(c, "Invalid email") + } + + // find site + if isOK, resp := CheckSite(c, &p.SiteName, &p.SiteID, &p.SiteAll); !isOK { + return resp + } + + // find page + // page := model.FindPage(p.PageKey, p.PageTitle) + // ip := c.RealIP() + // ua := c.Request().UserAgent() + + // 图片大小限制 (Based on content length) + maxUploadSize := config.Instance.ImgUpload.MaxSize * 1024 * 1024 + if c.Request().ContentLength > maxUploadSize { + return RespError(c, fmt.Sprintf("图片大小超过限制 %dMB", config.Instance.ImgUpload.MaxSize)) + } + + // 获取 Form + file, err := c.FormFile("file") + if err != nil { + logrus.Error(err) + return RespError(c, "文件获取失败") + } + + // 打开文件 + src, err := file.Open() + if err != nil { + logrus.Error(err) + return RespError(c, "文件打开失败") + } + defer src.Close() + + // 读取文件 + buf, err := ioutil.ReadAll(src) + if err != nil { + logrus.Error(err) + return RespError(c, "文件读取失败") + } + + // 大小限制 (Based on content read) + if int64(len(buf)) > maxUploadSize { + return RespError(c, fmt.Sprintf("图片大小超过限制 %dMB", config.Instance.ImgUpload.MaxSize)) + } + + // 文件格式判断 + // @link https://mimesniff.spec.whatwg.org/ + // @link https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Basics_of_HTTP/MIME_types + fileMine := http.DetectContentType(buf) + allowMines := []string{ + "image/jpeg", "image/png", "image/gif", + "image/svg+xml", "image/webp", "image/bmp", + } + if !lib.ContainsStr(allowMines, fileMine) { + return RespError(c, "不支持的格式") + } + + // 图片文件名 + mineToExts := map[string]string{ + "image/jpeg": ".jpg", + "image/png": ".png", + "image/gif": ".gif", + "image/svg+xml": ".svg", + "image/webp": ".webp", + "image/bmp": ".bmp", + } + + t := time.Now() + filename := t.Format("20060102-150405.000") + mineToExts[fileMine] + + // 创建图片目标文件 + if err := lib.EnsureDir(config.Instance.ImgUpload.Path); err != nil { + logrus.Error(err) + return RespError(c, "创建图片存放文件夹失败") + } + + fileFullPath := strings.TrimSuffix(config.Instance.ImgUpload.Path, "/") + "/" + filename + dst, err := os.Create(fileFullPath) + if err != nil { + return err + } + defer dst.Close() + + // 写入图片文件 + if _, err = dst.Write(buf); err != nil { + return err + } + + // 生成外部可访问链接 + baseURL := config.Instance.ImgUpload.PublicPath + if baseURL == "" { + baseURL = ImgUpload_RoutePath + } + + // 响应数据 + return RespData(c, Map{ + "img_file": filename, + "img_url": path.Join(baseURL, filename), + }) +} From c943c8fa08d07d6a6980efcdf42c8600e146bd2c Mon Sep 17 00:00:00 2001 From: qwqcode Date: Wed, 13 Apr 2022 21:13:13 +0800 Subject: [PATCH 136/349] feat(img-upload): Upload rate limitation. Signed-off-by: qwqcode --- http/a_http.go | 1 + http/api_main_img_upload.go | 16 +++++++++++----- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/http/a_http.go b/http/a_http.go index 653ae81f5..a02721860 100644 --- a/http/a_http.go +++ b/http/a_http.go @@ -48,6 +48,7 @@ func Run() { "/api/add", "/api/login", "/api/vote", + "/api/img-upload", }, } e.Use(ActionLimitMiddleware(ActionLimitConf)) diff --git a/http/api_main_img_upload.go b/http/api_main_img_upload.go index db323a445..270d68d7c 100644 --- a/http/api_main_img_upload.go +++ b/http/api_main_img_upload.go @@ -54,15 +54,19 @@ func ActionImgUpload(c echo.Context) error { return resp } + // 记录请求次数 (for 请求频率限制) + RecordAction(c) + // find page // page := model.FindPage(p.PageKey, p.PageTitle) // ip := c.RealIP() // ua := c.Request().UserAgent() // 图片大小限制 (Based on content length) - maxUploadSize := config.Instance.ImgUpload.MaxSize * 1024 * 1024 - if c.Request().ContentLength > maxUploadSize { - return RespError(c, fmt.Sprintf("图片大小超过限制 %dMB", config.Instance.ImgUpload.MaxSize)) + if config.Instance.ImgUpload.MaxSize != 0 { + if c.Request().ContentLength > config.Instance.ImgUpload.MaxSize*1024*1024 { + return RespError(c, fmt.Sprintf("图片大小超过限制 %dMB", config.Instance.ImgUpload.MaxSize)) + } } // 获取 Form @@ -88,8 +92,10 @@ func ActionImgUpload(c echo.Context) error { } // 大小限制 (Based on content read) - if int64(len(buf)) > maxUploadSize { - return RespError(c, fmt.Sprintf("图片大小超过限制 %dMB", config.Instance.ImgUpload.MaxSize)) + if config.Instance.ImgUpload.MaxSize != 0 { + if int64(len(buf)) > config.Instance.ImgUpload.MaxSize*1024*1024 { + return RespError(c, fmt.Sprintf("图片大小超过限制 %dMB", config.Instance.ImgUpload.MaxSize)) + } } // 文件格式判断 From ef3cbf5993e3a73f3a1e4427f079616d32dd4cd2 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Wed, 13 Apr 2022 22:27:42 +0800 Subject: [PATCH 137/349] feat(img-upload): Upload using upgit Signed-off-by: qwqcode --- go.mod | 1 + go.sum | 2 ++ http/api_main_img_upload.go | 69 +++++++++++++++++++++++++++++++++++-- lib/email/sender.go | 2 +- lib/utils.go | 11 +++--- 5 files changed, 75 insertions(+), 10 deletions(-) diff --git a/go.mod b/go.mod index a81b9c005..1e221b2b6 100644 --- a/go.mod +++ b/go.mod @@ -6,6 +6,7 @@ require ( github.com/PuerkitoBio/goquery v1.7.1 github.com/allegro/bigcache/v3 v3.0.0 github.com/araddon/dateparse v0.0.0-20210429162001-6b43995a97de + github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d // indirect github.com/cheggaaa/pb/v3 v3.0.8 github.com/eko/gocache/v2 v2.1.0 github.com/elliotchance/phpserialize v1.3.1 diff --git a/go.sum b/go.sum index 2c1c8023b..3ee16efef 100644 --- a/go.sum +++ b/go.sum @@ -77,6 +77,8 @@ github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hC github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= +github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d h1:Byv0BzEl3/e6D5CLfI0j/7hiIEtvGVFPCZ7Ei2oq8iQ= +github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= diff --git a/http/api_main_img_upload.go b/http/api_main_img_upload.go index 270d68d7c..140250e69 100644 --- a/http/api_main_img_upload.go +++ b/http/api_main_img_upload.go @@ -5,8 +5,10 @@ import ( "io/ioutil" "net/http" "os" + "os/exec" "path" "strings" + "syscall" "time" "github.com/ArtalkJS/ArtalkGo/config" @@ -132,13 +134,15 @@ func ActionImgUpload(c echo.Context) error { fileFullPath := strings.TrimSuffix(config.Instance.ImgUpload.Path, "/") + "/" + filename dst, err := os.Create(fileFullPath) if err != nil { - return err + logrus.Error(err) + return RespError(c, "图片文件创建失败") } defer dst.Close() // 写入图片文件 if _, err = dst.Write(buf); err != nil { - return err + logrus.Error(err) + return RespError(c, "图片文件写入失败") } // 生成外部可访问链接 @@ -146,10 +150,69 @@ func ActionImgUpload(c echo.Context) error { if baseURL == "" { baseURL = ImgUpload_RoutePath } + imgURL := path.Join(baseURL, filename) + + // 使用 upgit + if config.Instance.ImgUpload.Upgit.Enabled { + upgitURL := execUpgitUpload(fileFullPath) + if upgitURL == "" || !lib.ValidateURL(upgitURL) { + // 上传失败,删除源图片文件 + var err = os.Remove(fileFullPath) + if err != nil { + logrus.Error(err) + } + + logrus.Error("[IMG_UPLOAD] [upgit] upgit output: ", upgitURL) + return RespError(c, "图片通过 upgit 上传失败") + } + + // 使用从 upgit 获取的图片 URL + imgURL = upgitURL + } // 响应数据 return RespData(c, Map{ "img_file": filename, - "img_url": path.Join(baseURL, filename), + "img_url": imgURL, }) } + +// 调用 upgit 上传图片获得 URL +func execUpgitUpload(filename string) string { + LogTag := "[IMG_UPLOAD] [upgit] " + + // 处理参数 + cmdStrSplitted := strings.Split(config.Instance.ImgUpload.Upgit.Exec, " ") + execApp := cmdStrSplitted[0] + execArgs := []string{} + for i, arg := range cmdStrSplitted { + if i > 0 { + execArgs = append(execArgs, arg) + } + } + execArgs = append(execArgs, filename) + + // 执行命令 + cmd := exec.Command(execApp, execArgs...) + stdout, _ := cmd.StdoutPipe() + + if err := cmd.Start(); err != nil { + logrus.Error(LogTag, "cmd.Start: ", err) + return "" + } + + result, _ := ioutil.ReadAll(stdout) + if err := cmd.Wait(); err != nil { + if exiterr, ok := err.(*exec.ExitError); ok { + if status, ok := exiterr.Sys().(syscall.WaitStatus); ok { + logrus.Error(LogTag, "Exit Status: ", status.ExitStatus()) + } + } else { + logrus.Error(LogTag, "cmd.Wait: ", err) + } + + return "" + } + + return strings.TrimSpace(string(result)) +} diff --git a/lib/email/sender.go b/lib/email/sender.go index 3fd8c6b68..c8beaf5c8 100644 --- a/lib/email/sender.go +++ b/lib/email/sender.go @@ -65,7 +65,7 @@ func SendByAliDM(email Email) bool { } func SendByUsingSystemCMD(email Email) bool { - LogTag := "[EMAIL] sendmail" + LogTag := "[EMAIL] [sendmail] " msg := GetEmailMineTxt(email) // 调用系统 sendmail diff --git a/lib/utils.go b/lib/utils.go index 3e98ddd0a..bfb37ac63 100644 --- a/lib/utils.go +++ b/lib/utils.go @@ -6,7 +6,6 @@ import ( "encoding/hex" "encoding/json" "fmt" - "net/mail" "net/url" "os" "regexp" @@ -19,6 +18,8 @@ import ( "github.com/yuin/goldmark/extension" "github.com/yuin/goldmark/parser" "github.com/yuin/goldmark/renderer/html" + + "github.com/asaskevich/govalidator" ) // EnsureDir ensures that a target directory exists (like `mkdir -p`), @@ -148,13 +149,11 @@ func JsonObjInArrAnyStr(jsonStr string) string { //****************************************** func ValidateEmail(email string) bool { - _, err := mail.ParseAddress(email) - return err == nil + return govalidator.IsEmail(email) } -func ValidateURL(urlStr string) bool { - _, err := url.ParseRequestURI(urlStr) - return err == nil +func ValidateURL(url string) bool { + return govalidator.IsURL(url) } //#endregion From 30e8ade45a3d8b2ab5ab8b84fb5e42b8951e2841 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Wed, 13 Apr 2022 22:30:39 +0800 Subject: [PATCH 138/349] docs: Update README.md Signed-off-by: qwqcode --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 9d59cb5c5..c4ababf65 100644 --- a/README.md +++ b/README.md @@ -108,7 +108,9 @@ $ make docker-push - [ ] 表情包统一管理 - [ ] 导入表情包 - [ ] 表情包图片地址控制 -- [ ] 图片上传 / 管理 +- [x] 图片上传 +- [x] 图片上传到图床 ([upgit](https://github.com/pluveto/upgit)) +- [ ] 图片管理 - [ ] 附件上传 / 管理 - [ ] 评论标签分类系统 - [ ] 主题样式更换 From d17987d64bec5d795d246ab7e1d56903ecbd7302 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Wed, 13 Apr 2022 22:48:54 +0800 Subject: [PATCH 139/349] feat(img-upload): Admin always enable img_upload function. Signed-off-by: qwqcode --- http/a_http.go | 16 +++++++++------- http/api_main_get.go | 2 ++ http/api_main_img_upload.go | 6 +++--- http/resp.go | 13 +++++++++++++ 4 files changed, 27 insertions(+), 10 deletions(-) diff --git a/http/a_http.go b/http/a_http.go index a02721860..d22c5cec6 100644 --- a/http/a_http.go +++ b/http/a_http.go @@ -97,14 +97,11 @@ func InitRoute(e *echo.Echo) { api.POST("/pv", ActionPV) // api/upload-img - api.POST("/img-upload", ActionImgUpload) - if config.Instance.ImgUpload.Enabled { - if config.Instance.ImgUpload.Path == "" { - logrus.Fatal("图片上传功能需配置 img_upload.path") - } - // 静态可访问图片存放目录 - e.Static(ImgUpload_RoutePath, config.Instance.ImgUpload.Path) + if config.Instance.ImgUpload.Path == "" { + logrus.Fatal("图片上传功能需配置 img_upload.path") } + api.POST("/img-upload", ActionImgUpload) + e.Static(ImgUpload_RoutePath, config.Instance.ImgUpload.Path) // 静态可访问图片存放目录 // api/captcha ca := api.Group("/captcha") @@ -134,6 +131,11 @@ func InitRoute(e *echo.Echo) { admin.POST("/send-mail", ActionAdminSendMail) + // conf + api.Any("/conf", func(c echo.Context) error { + return c.JSON(200, GetApiPublicConfDataMap(c)) + }) + // version api.Any("/version", func(c echo.Context) error { return c.JSON(200, GetApiVersionDataMap()) diff --git a/http/api_main_get.go b/http/api_main_get.go index c7682874b..1460ebb02 100644 --- a/http/api_main_get.go +++ b/http/api_main_get.go @@ -43,6 +43,7 @@ type ResponseGet struct { Unread []model.CookedNotify `json:"unread"` UnreadCount int `json:"unread_count"` ApiVersion Map `json:"api_version"` + Conf Map `json:"conf"` } // 获取评论查询实例 @@ -181,6 +182,7 @@ func ActionGet(c echo.Context) error { Unread: unreadNotifies, UnreadCount: len(unreadNotifies), ApiVersion: GetApiVersionDataMap(), + Conf: GetApiPublicConfDataMap(c), }) } diff --git a/http/api_main_img_upload.go b/http/api_main_img_upload.go index 140250e69..0895b4648 100644 --- a/http/api_main_img_upload.go +++ b/http/api_main_img_upload.go @@ -34,9 +34,9 @@ type ParamsImgUpload struct { } func ActionImgUpload(c echo.Context) error { - // 功能开关 - if !config.Instance.ImgUpload.Enabled { - return RespError(c, "图片上传功能已禁用", Map{ + // 功能开关 (管理员始终开启) + if !config.Instance.ImgUpload.Enabled && !CheckIsAdminReq(c) { + return RespError(c, "禁止图片上传", Map{ "img_upload_enabled": false, }) } diff --git a/http/resp.go b/http/resp.go index 3d1ce61ad..a3dace575 100644 --- a/http/resp.go +++ b/http/resp.go @@ -4,6 +4,7 @@ import ( "net/http" "strconv" + "github.com/ArtalkJS/ArtalkGo/config" "github.com/ArtalkJS/ArtalkGo/lib" "github.com/labstack/echo/v4" "github.com/sirupsen/logrus" @@ -97,3 +98,15 @@ func GetApiVersionDataMap() Map { "fe_min_version": lib.FeMinVersion, } } + +func GetApiPublicConfDataMap(c echo.Context) Map { + isAdmin := CheckIsAdminReq(c) + imgUpload := config.Instance.ImgUpload.Enabled + if isAdmin { + imgUpload = true // 管理员始终允许上传图片 + } + + return Map{ + "img_upload": imgUpload, + } +} From 523fab8036fe1813b1a5ae2fb003a652cb910696 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Thu, 14 Apr 2022 00:13:48 +0800 Subject: [PATCH 140/349] fix(img-upload): Set img_upload.path defualt value Signed-off-by: qwqcode --- http/a_http.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/http/a_http.go b/http/a_http.go index d22c5cec6..317d3d6c1 100644 --- a/http/a_http.go +++ b/http/a_http.go @@ -98,7 +98,8 @@ func InitRoute(e *echo.Echo) { // api/upload-img if config.Instance.ImgUpload.Path == "" { - logrus.Fatal("图片上传功能需配置 img_upload.path") + config.Instance.ImgUpload.Path = "./data/artalk-img/" + logrus.Warn("图片上传功能 img_upload.path 未配置,使用默认值:" + config.Instance.ImgUpload.Path) } api.POST("/img-upload", ActionImgUpload) e.Static(ImgUpload_RoutePath, config.Instance.ImgUpload.Path) // 静态可访问图片存放目录 From 3b3947c1c18c31e2714b7ca7cf2619fcf376cfee Mon Sep 17 00:00:00 2001 From: qwqcode Date: Thu, 14 Apr 2022 00:23:40 +0800 Subject: [PATCH 141/349] chore: Modify img_upload.max_size example value. Signed-off-by: qwqcode --- artalk-go.example.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/artalk-go.example.yml b/artalk-go.example.yml index bccf6ed2b..a81973030 100644 --- a/artalk-go.example.yml +++ b/artalk-go.example.yml @@ -85,7 +85,7 @@ email: img_upload: enabled: true # 总开关 path: "./data/artalk-img/" # 图片存放路径 - max_size: 10 # 图片大小限制 (单位:MB) + max_size: 5 # 图片大小限制 (单位:MB) public_path: null # 指定图片链接基础路径 (默认为 "/static/images/") # 使用 upgit 将图片上传到 GitHub 或图床 (https://github.com/pluveto/upgit) upgit: From ba7c366b97d683c4dd92f2fb105c6c7245b13635 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Thu, 14 Apr 2022 14:04:02 +0800 Subject: [PATCH 142/349] feat(self-upgrade): Add cmd Self-upgrade function Signed-off-by: qwqcode --- README.md | 2 +- cmd/upgrade.go | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++ go.mod | 5 ++++- go.sum | 24 ++++++++++++++++++++- 4 files changed, 85 insertions(+), 3 deletions(-) create mode 100644 cmd/upgrade.go diff --git a/README.md b/README.md index c4ababf65..7ec6ccec2 100644 --- a/README.md +++ b/README.md @@ -119,7 +119,7 @@ $ make docker-push - [ ] 开放用户注册 - [ ] 接入第三方登录 - [ ] 国际化 (i18n) -- [ ] 在线升级 +- [x] 一键升级 ## License diff --git a/cmd/upgrade.go b/cmd/upgrade.go new file mode 100644 index 000000000..b7cb61feb --- /dev/null +++ b/cmd/upgrade.go @@ -0,0 +1,57 @@ +package cmd + +import ( + "fmt" + "os" + + "github.com/ArtalkJS/ArtalkGo/lib" + "github.com/blang/semver" + "github.com/rhysd/go-github-selfupdate/selfupdate" + "github.com/sirupsen/logrus" + "github.com/spf13/cobra" +) + +var upgradeCmd = &cobra.Command{ + Use: "upgrade", + Aliases: []string{"update"}, + Short: "升级 ArtalkGo 到最新版本", + Long: "将 ArtalkGo 升级到最新版本,\n更新源为 GitHub Releases,\n更新需要重启 ArtalkGo 才能生效。", + Run: func(cmd *cobra.Command, args []string) { + logrus.Info("从 GitHub Release 检索更新中...") + + latest, found, err := selfupdate.DetectLatest("ArtalkJS/ArtalkGo") + if err != nil { + logrus.Fatal("Error occurred while detecting version: ", err) + } + + v := semver.MustParse(lib.Version[1:]) + if !found || latest.Version.LTE(v) { + logrus.Println("当前已是最新版本 v" + v.String() + " 无需升级") + return + } + + logrus.Info("发现新版本: v" + latest.Version.String()) + logrus.Info("正在下载更新中...") + + exe, err := os.Executable() + if err != nil { + logrus.Fatal("Could not locate executable path ", err) + } + + if err := selfupdate.UpdateTo(latest.AssetURL, exe); err != nil { + logrus.Fatal("更新失败 ", err) + } + + logrus.Println("更新完毕") + fmt.Println("\n-------------------------------\n v" + + latest.Version.String() + + " Release Note\n" + + "-------------------------------\n\n" + + latest.ReleaseNotes) + }, + Args: cobra.NoArgs, +} + +func init() { + rootCmd.AddCommand(upgradeCmd) +} diff --git a/go.mod b/go.mod index 1e221b2b6..327f706b3 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,8 @@ require ( github.com/PuerkitoBio/goquery v1.7.1 github.com/allegro/bigcache/v3 v3.0.0 github.com/araddon/dateparse v0.0.0-20210429162001-6b43995a97de - github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d // indirect + github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d + github.com/blang/semver v3.5.1+incompatible github.com/cheggaaa/pb/v3 v3.0.8 github.com/eko/gocache/v2 v2.1.0 github.com/elliotchance/phpserialize v1.3.1 @@ -27,8 +28,10 @@ require ( github.com/onrik/logrus v0.9.0 github.com/onsi/gomega v1.16.0 // indirect github.com/qwqcode/go-aliyun-email v0.0.0-20180120030821-cb6e7b1382bf + github.com/rhysd/go-github-selfupdate v1.2.3 github.com/rifflock/lfshook v0.0.0-20180920164130-b9218ef580f5 github.com/sirupsen/logrus v1.8.1 + github.com/smartystreets/assertions v1.0.1 // indirect github.com/spf13/cast v1.4.1 // indirect github.com/spf13/cobra v1.2.1 github.com/spf13/viper v1.8.1 diff --git a/go.sum b/go.sum index 3ee16efef..a8e50ff34 100644 --- a/go.sum +++ b/go.sum @@ -90,6 +90,8 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/bketelsen/crypt v0.0.4/go.mod h1:aI6NrJ0pMGgvZKL1iVgXLnfIFJtfV+bKCoqOes/6LfM= +github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ= +github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= github.com/bradfitz/gomemcache v0.0.0-20190913173617-a41fca850d0b h1:L/QXpzIa3pOvUGt1D1lA5KjYhPBAN/3iWdP7xeFS9F0= github.com/bradfitz/gomemcache v0.0.0-20190913173617-a41fca850d0b/go.mod h1:H0wQNHz2YrLsuXOZozoeDmnHXkNCRmMW0gwFWDfEZDA= github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= @@ -262,6 +264,10 @@ github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-github/v30 v30.1.0 h1:VLDx+UolQICEOKu2m4uAoMti1SxuEBAl7RSEG16L+Oo= +github.com/google/go-github/v30 v30.1.0/go.mod h1:n8jBpHl45a/rlBUtRJMOG4GhNADUQFEufcolZ95JfU8= +github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk= +github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/gofuzz v0.0.0-20161122191042-44d81051d367/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= @@ -325,6 +331,8 @@ github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpO github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/inconshreveable/go-update v0.0.0-20160112193335-8152e7eb6ccf h1:WfD7VjIE6z8dIvMsI4/s+1qr5EL+zoIGev1BQj1eoJ8= +github.com/inconshreveable/go-update v0.0.0-20160112193335-8152e7eb6ccf/go.mod h1:hyb9oH7vZsitZCiBt0ZvifOrB+qc8PS5IiilCIb87rg= github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= @@ -511,6 +519,7 @@ github.com/onsi/ginkgo v1.15.0/go.mod h1:hF8qUzuuC8DJGygJH3726JnCZX4MYbRB8yFfISq github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc= github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= +github.com/onsi/gomega v1.4.2/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= @@ -579,6 +588,8 @@ github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1 github.com/qwqcode/go-aliyun-email v0.0.0-20180120030821-cb6e7b1382bf h1:FH9O7I17HCdVYbK1IMxTGgD3bVuTzyO45bR94iE+T/U= github.com/qwqcode/go-aliyun-email v0.0.0-20180120030821-cb6e7b1382bf/go.mod h1:5N3D7E1/M3G95YK4jPjcPRf/A7XBis0ni4VMmcVnnRY= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= +github.com/rhysd/go-github-selfupdate v1.2.3 h1:iaa+J202f+Nc+A8zi75uccC8Wg3omaM7HDeimXA22Ag= +github.com/rhysd/go-github-selfupdate v1.2.3/go.mod h1:mp/N8zj6jFfBQy/XMYoWsmfzxazpPAODuqarmPDe2Rg= github.com/rifflock/lfshook v0.0.0-20180920164130-b9218ef580f5 h1:mZHayPoR0lNmnHyvtYjDeq0zlVHn9K/ZXoy17ylucdo= github.com/rifflock/lfshook v0.0.0-20180920164130-b9218ef580f5/go.mod h1:GEXHk5HgEKCvEIIrSpFI3ozzG5xOKA2DVlEX/gGnewM= github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= @@ -606,8 +617,9 @@ github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6Mwd github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= -github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/assertions v1.0.1 h1:voD4ITNjPL5jjBfgR/r8fPIIBrliWrWHeiJApdr3r4w= +github.com/smartystreets/assertions v1.0.1/go.mod h1:kHHU4qYBaI3q23Pp3VPrmWhuIUrLW/7eUrw0BU5VaoM= github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= @@ -647,6 +659,8 @@ github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5Cc github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= +github.com/tcnksm/go-gitconfig v0.1.2 h1:iiDhRitByXAEyjgBqsKi9QU4o2TNtv9kPP3RgPgXBPw= +github.com/tcnksm/go-gitconfig v0.1.2/go.mod h1:/8EhP4H7oJZdIPyT+/UIsG87kTzrzM4UsLGSItWYCpE= github.com/tidwall/gjson v1.11.0 h1:C16pk7tQNiH6VlCrtIXL1w8GaOsi1X3W8KDkE1BuYd4= github.com/tidwall/gjson v1.11.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= @@ -654,6 +668,8 @@ github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JT github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs= github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/ulikunitz/xz v0.5.9 h1:RsKRIA2MO8x56wkkcd3LbtcE/uMszhb6DpRf+3uwa3I= +github.com/ulikunitz/xz v0.5.9/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= @@ -722,6 +738,7 @@ golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 h1:7I4JAnoQBe7ZtJcBaYHi5UtiO8tQHbUSXxL+pnGRANg= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= @@ -815,6 +832,7 @@ golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qx golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d h1:LO7XpTYMwTqxjLcGWPijK3vRXg1aWdlNOVOHRq45d7c= golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20181106182150-f42d05182288/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -825,6 +843,7 @@ golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602 h1:0Ja1LBD+yisY6RWM/BH7TJVXWsSjs2VwBSmvSX4HdBc= golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -907,6 +926,7 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359 h1:2B5p2L5IfGiD7+b9BOoRMC6DgObAVZV+Fsp050NqXik= golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -1020,11 +1040,13 @@ google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk google.golang.org/api v0.44.0/go.mod h1:EBOGZqzyhtvMDoxwS97ctnh0zUmYY6CxqXsc1AvkYD8= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= From b86250889d50c183575ba1652ab746797059309f Mon Sep 17 00:00:00 2001 From: qwqcode Date: Thu, 14 Apr 2022 14:58:59 +0800 Subject: [PATCH 143/349] chore(pkm): Replace yarn to pnpm. Signed-off-by: qwqcode --- Dockerfile | 3 ++- scripts/build-frontend.sh | 10 +++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/Dockerfile b/Dockerfile index 8c7de73b3..c231f9402 100644 --- a/Dockerfile +++ b/Dockerfile @@ -6,7 +6,8 @@ WORKDIR /source # install tools RUN set -ex \ && apk upgrade \ - && apk add make git gcc musl-dev nodejs yarn bash + && apk add make git gcc musl-dev nodejs bash npm\ + && npm install -g pnpm@7.0.0-rc.3 COPY . ./ArtalkGo diff --git a/scripts/build-frontend.sh b/scripts/build-frontend.sh index 32ae3da08..0d77eb74c 100755 --- a/scripts/build-frontend.sh +++ b/scripts/build-frontend.sh @@ -2,17 +2,17 @@ set -e -if ! command -v yarn &> /dev/null +if ! command -v pnpm &> /dev/null then apt-get update && apt-get install --no-install-recommends -y -q curl ca-certificates # Install volta + bash -c "$(curl -fsSL https://get.volta.sh)" -- --skip-setup export VOLTA_HOME="${HOME}/.volta" export PATH="${VOLTA_HOME}/bin:${PATH}" - bash -c "$(curl -fsSL https://get.volta.sh)" -- --skip-setup volta install node - volta install yarn + volta install pnpm fi mkdir -p ./local/ @@ -27,8 +27,8 @@ cd Artalk git fetch --tags git checkout $(git describe --tags --abbrev=0) -yarn install --network-timeout 1000000 -yarn build:all +pnpm install +pnpm build:all cd ../../ From 2027f2605385778fd13267ef2582bf159cdeb77b Mon Sep 17 00:00:00 2001 From: qwqcode Date: Thu, 14 Apr 2022 20:43:59 +0800 Subject: [PATCH 144/349] fix(admin_site_edit): Split urls and TrimSpace to allow Space around sep char. Signed-off-by: qwqcode --- http/api_admin_site_add.go | 4 +--- http/api_admin_site_edit.go | 2 +- lib/artransfer/importer.go | 2 +- lib/utils.go | 9 +++++++++ model/site.go | 4 +--- 5 files changed, 13 insertions(+), 8 deletions(-) diff --git a/http/api_admin_site_add.go b/http/api_admin_site_add.go index 13e9b96a5..9229f8931 100644 --- a/http/api_admin_site_add.go +++ b/http/api_admin_site_add.go @@ -1,8 +1,6 @@ package http import ( - "strings" - "github.com/ArtalkJS/ArtalkGo/lib" "github.com/ArtalkJS/ArtalkGo/model" "github.com/labstack/echo/v4" @@ -24,7 +22,7 @@ func ActionAdminSiteAdd(c echo.Context) error { } if p.Urls != "" { - urls := strings.Split(p.Urls, ",") + urls := lib.SplitAndTrimSpace(p.Urls, ",") for _, url := range urls { if !lib.ValidateURL(url) { return RespError(c, "Invalid url exist") diff --git a/http/api_admin_site_edit.go b/http/api_admin_site_edit.go index 802f6cfbc..9bec8d98b 100644 --- a/http/api_admin_site_edit.go +++ b/http/api_admin_site_edit.go @@ -44,7 +44,7 @@ func ActionAdminSiteEdit(c echo.Context) error { // urls 合法性检测 if p.Urls != "" { - for _, url := range strings.Split(p.Urls, ",") { + for _, url := range lib.SplitAndTrimSpace(p.Urls, ",") { if !lib.ValidateURL(url) { return RespError(c, "Invalid url exist") } diff --git a/lib/artransfer/importer.go b/lib/artransfer/importer.go index 518f3d660..7551e4ecf 100644 --- a/lib/artransfer/importer.go +++ b/lib/artransfer/importer.go @@ -200,7 +200,7 @@ func SiteReady(tSiteName string, tSiteUrls string) (model.Site, error) { return false } - tUrlsSpit := strings.Split(tSiteUrls, ",") + tUrlsSpit := lib.SplitAndTrimSpace(tSiteUrls, ",") rUrls := []string{} for _, u := range tUrlsSpit { diff --git a/lib/utils.go b/lib/utils.go index bfb37ac63..2ca1fc013 100644 --- a/lib/utils.go +++ b/lib/utils.go @@ -104,6 +104,15 @@ func ContainsStr(s []string, v string) bool { return false } +func SplitAndTrimSpace(s string, sep string) []string { + splitted := strings.Split(s, sep) + arr := []string{} + for _, v := range splitted { + arr = append(arr, strings.TrimSpace(v)) + } + return arr +} + func RemoveBlankStrings(s []string) []string { var r []string for _, str := range s { diff --git a/model/site.go b/model/site.go index 4dbb826f6..5d88f5bd5 100644 --- a/model/site.go +++ b/model/site.go @@ -1,8 +1,6 @@ package model import ( - "strings" - "github.com/ArtalkJS/ArtalkGo/lib" "gorm.io/gorm" ) @@ -28,7 +26,7 @@ type CookedSite struct { } func (s Site) ToCooked() CookedSite { - splitUrls := lib.RemoveBlankStrings(strings.Split(s.Urls, ",")) + splitUrls := lib.RemoveBlankStrings(lib.SplitAndTrimSpace(s.Urls, ",")) firstUrl := "" if len(splitUrls) > 0 { firstUrl = splitUrls[0] From f70a509213f17ba2151d5a4be3ededd02b4ee205 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Thu, 14 Apr 2022 23:04:20 +0800 Subject: [PATCH 145/349] feat(notify): Various ways to send notify message for admin. Signed-off-by: qwqcode --- README.md | 9 ++- artalk-go.example.yml | 36 ++++++++++++ cmd/root.go | 40 +++++++++++++ config/config.go | 46 +++++++++++++++ go.mod | 12 +--- go.sum | 130 +++++++++++++++++++++++++++++++++++++----- http/api_main_add.go | 82 ++++++++++++++++++++++++++ model/comment.go | 23 ++++++++ model/notify.go | 9 +-- 9 files changed, 353 insertions(+), 34 deletions(-) diff --git a/README.md b/README.md index 7ec6ccec2..50e93eb16 100644 --- a/README.md +++ b/README.md @@ -93,8 +93,13 @@ $ make docker-push - [ ] 阿里云服务 - [ ] 腾讯云服务 - [ ] 关键字 / 正则表达式过滤 -- [ ] 评论通知 WebHook - - [ ] Telegram Bot +- [x] 评论通知管理员 + - [x] Telegram Bot + - [x] 飞书 WebHook Bot + - [x] 钉钉 + - [x] Bark + - [x] Slack + - [x] LINE - [ ] 自定义 HTTP 回调 - [ ] 博客邮件订阅 - [x] 用户鉴权机制 diff --git a/artalk-go.example.yml b/artalk-go.example.yml index a81973030..673737356 100644 --- a/artalk-go.example.yml +++ b/artalk-go.example.yml @@ -91,3 +91,39 @@ img_upload: upgit: enabled: false # 启用 upgit exec: "./upgit -c -t /artalk-img" + +# 其他通知方式 +notify: + # Telegram + telegram: + enabled: false + api_token: "" + receivers: + - 7777777 + # 飞书 + lark: + enabled: false + webhook_url: "" + # 钉钉 + ding_talk: + enabled: false + token: "" + secret: "" + # Bark + bark: + enabled: false + server: "http://day.app/xxxxxxx/" + # Slack + slack: + enabled: false + oauth_token: "" + receivers: + - "CHANNEL_ID" + # LINE + line: + enabled: false + channel_secret: "" + channel_access_token: "" + receivers: + - "USER_ID_1" + - "GROUP_ID_1" diff --git a/cmd/root.go b/cmd/root.go index 2e01d3a10..1bb110b52 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -10,6 +10,11 @@ import ( "github.com/ArtalkJS/ArtalkGo/lib" "github.com/ArtalkJS/ArtalkGo/lib/email" "github.com/ArtalkJS/ArtalkGo/model" + "github.com/nikoksr/notify" + "github.com/nikoksr/notify/service/dingding" + "github.com/nikoksr/notify/service/line" + "github.com/nikoksr/notify/service/slack" + "github.com/nikoksr/notify/service/telegram" "github.com/rifflock/lfshook" "github.com/sirupsen/logrus" "github.com/spf13/cobra" @@ -60,6 +65,7 @@ func init() { cobra.OnInitialize(syncConfWithDB) cobra.OnInitialize(initCache) cobra.OnInitialize(email.InitQueue) // 初始化邮件队列 + cobra.OnInitialize(initNotify) rootCmd.SetVersionTemplate("Artalk-GO {{printf \"version %s\" .Version}}\n") rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "配置文件路径 (defaults are './artalk-go.yml')") @@ -221,3 +227,37 @@ func initCache() { os.Exit(1) } } + +// 6. 初始化 Notify +func initNotify() { + // Telegram + tgConf := config.Instance.Notify.Telegram + if tgConf.Enabled { + telegramService, _ := telegram.New(tgConf.ApiToken) + telegramService.AddReceivers(tgConf.Receivers...) + notify.UseServices(telegramService) + } + + // 钉钉 + dingTalkConf := config.Instance.Notify.DingTalk + if dingTalkConf.Enabled { + dingTalkService := dingding.New(&dingding.Config{Token: dingTalkConf.Token, Secret: dingTalkConf.Secret}) + notify.UseServices(dingTalkService) + } + + // Slack + slackConf := config.Instance.Notify.Slack + if slackConf.Enabled { + slackService := slack.New(slackConf.OauthToken) + slackService.AddReceivers(slackConf.Receivers...) + notify.UseServices(slackService) + } + + // LINE + LINEConf := config.Instance.Notify.LINE + if LINEConf.Enabled { + lineService, _ := line.New(config.Instance.Notify.LINE.ChannelSecret, config.Instance.Notify.LINE.ChannelAccessToken) + lineService.AddReceivers(LINEConf.Receivers...) + notify.UseServices(lineService) + } +} diff --git a/config/config.go b/config/config.go index 49b88f190..0a75c3379 100644 --- a/config/config.go +++ b/config/config.go @@ -30,6 +30,7 @@ type Config struct { Captcha CaptchaConf `mapstructure:"captcha" json:"captcha"` // 验证码 Email EmailConf `mapstructure:"email" json:"email"` // 邮箱提醒 ImgUpload ImgUploadConf `mapstructure:"img_upload" json:"img_upload"` // 图片上传 + Notify NotifyConf `mapstructure:"notify" json:"notify"` // 其他通知方式 } type DBConf struct { @@ -126,6 +127,51 @@ type UpgitConf struct { Exec string `mapstructure:"exec" json:"exec"` // 启动命令 } +// 其他通知方式 +type NotifyConf struct { + Telegram NotifyTelegramConf `mapstructure:"telegram" json:"telegram"` // TG + Lark NotifyLarkConf `mapstructure:"lark" json:"lark"` // 飞书 + DingTalk NotifyDingTalkConf `mapstructure:"ding_talk" json:"ding_talk"` // 钉钉 + Bark NotifyBarkConf `mapstructure:"bark" json:"bark"` // bark + Slack NotifySlackConf `mapstructure:"slack" json:"slack"` // slack + LINE NotifyLINEConf `mapstructure:"line" json:"line"` // LINE +} + +type NotifyTelegramConf struct { + Enabled bool `mapstructure:"enabled" json:"enabled"` + ApiToken string `mapstructure:"api_token" json:"api_token"` + Receivers []int64 `mapstructure:"receivers" json:"receivers"` +} + +type NotifyDingTalkConf struct { + Enabled bool `mapstructure:"enabled" json:"enabled"` + Token string `mapstructure:"token" json:"token"` + Secret string `mapstructure:"secret" json:"secret"` +} + +type NotifyLarkConf struct { + Enabled bool `mapstructure:"enabled" json:"enabled"` + WebhookURL string `mapstructure:"webhook_url" json:"webhook_url"` +} + +type NotifyBarkConf struct { + Enabled bool `mapstructure:"enabled" json:"enabled"` + Server string `mapstructure:"server" json:"server"` +} + +type NotifySlackConf struct { + Enabled bool `mapstructure:"enabled" json:"enabled"` + OauthToken string `mapstructure:"oauth_token" json:"oauth_token"` + Receivers []string `mapstructure:"receivers" json:"receivers"` +} + +type NotifyLINEConf struct { + Enabled bool `mapstructure:"enabled" json:"enabled"` + ChannelSecret string `mapstructure:"channel_secret" json:"channel_secret"` + ChannelAccessToken string `mapstructure:"channel_access_token" json:"channel_access_token"` + Receivers []string `mapstructure:"receivers" json:"receivers"` +} + // Init 初始化配置 func Init(cfgFile string) { viper.SetConfigType("yaml") diff --git a/go.mod b/go.mod index 327f706b3..3afc97491 100644 --- a/go.mod +++ b/go.mod @@ -15,16 +15,14 @@ require ( github.com/golang-jwt/jwt v3.2.2+incompatible github.com/jedib0t/go-pretty/v6 v6.2.4 github.com/jeremywohl/flatten v1.0.1 - github.com/kr/text v0.2.0 // indirect github.com/labstack/echo/v4 v4.5.0 github.com/markbates/pkger v0.17.1 - github.com/mattn/go-isatty v0.0.14 // indirect github.com/mattn/go-runewidth v0.0.13 // indirect github.com/mattn/go-sqlite3 v1.14.8 // indirect github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect github.com/microcosm-cc/bluemonday v1.0.18 github.com/mitchellh/mapstructure v1.4.1 - github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect + github.com/nikoksr/notify v0.23.0 github.com/onrik/logrus v0.9.0 github.com/onsi/gomega v1.16.0 // indirect github.com/qwqcode/go-aliyun-email v0.0.0-20180120030821-cb6e7b1382bf @@ -32,20 +30,14 @@ require ( github.com/rifflock/lfshook v0.0.0-20180920164130-b9218ef580f5 github.com/sirupsen/logrus v1.8.1 github.com/smartystreets/assertions v1.0.1 // indirect - github.com/spf13/cast v1.4.1 // indirect github.com/spf13/cobra v1.2.1 github.com/spf13/viper v1.8.1 github.com/steambap/captcha v1.4.1 github.com/tidwall/gjson v1.11.0 github.com/x-cray/logrus-prefixed-formatter v0.5.2 github.com/yuin/goldmark v1.4.0 - golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 - golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d // indirect - golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359 // indirect - golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect - golang.org/x/text v0.3.7 // indirect + golang.org/x/crypto v0.0.0-20220131195533-30dcbda58838 gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect - gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f // indirect gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df gorm.io/driver/mysql v1.1.2 gorm.io/driver/postgres v1.1.0 diff --git a/go.sum b/go.sum index a8e50ff34..0e330b90d 100644 --- a/go.sum +++ b/go.sum @@ -37,9 +37,11 @@ cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohl cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +github.com/Baozisoftware/qrcode-terminal-go v0.0.0-20170407111555-c0650d8dff0f/go.mod h1:4a58ifQTEe2uwwsaqbh3i2un5/CBPg+At/qHpt18Tmk= github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/Jeffail/gabs v1.4.0/go.mod h1:6xMvQMK4k33lb7GUUpaAPh6nKMmemQeg5d4gn7/bOXc= github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= github.com/Masterminds/semver/v3 v3.1.1 h1:hLg3sBzpNErnxhQtUy/mmLR2I9foDujNK030IGemrRc= github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= @@ -49,6 +51,13 @@ github.com/PuerkitoBio/goquery v1.7.1 h1:oE+T06D+1T7LNrn91B4aERsRIeCLJ/oPSa6xB9F github.com/PuerkitoBio/goquery v1.7.1/go.mod h1:XY0pP4kfraEmmV1O7Uf6XyjoslwsneBbgeDjLYuN8xY= github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= +github.com/Rhymen/go-whatsapp v0.0.0/go.mod h1:rdQr95g2C1xcOfM7QGOhza58HeI3I+tZ/bbluv7VazA= +github.com/Rhymen/go-whatsapp v0.1.1/go.mod h1:o7jjkvKnigfu432dMbQ/w4PH0Yp5u4Y6ysCNjUlcYCk= +github.com/Rhymen/go-whatsapp/examples/echo v0.0.0-20190325075644-cc2581bbf24d/go.mod h1:zgCiQtBtZ4P4gFWvwl9aashsdwOcbb/EHOGRmSzM8ME= +github.com/Rhymen/go-whatsapp/examples/restoreSession v0.0.0-20190325075644-cc2581bbf24d/go.mod h1:5sCUSpG616ZoSJhlt9iBNI/KXBqrVLcNUJqg7J9+8pU= +github.com/Rhymen/go-whatsapp/examples/sendImage v0.0.0-20190325075644-cc2581bbf24d/go.mod h1:RdiyhanVEGXTam+mZ3k6Y3VDCCvXYCwReOoxGozqhHw= +github.com/Rhymen/go-whatsapp/examples/sendTextMessages v0.0.0-20190325075644-cc2581bbf24d/go.mod h1:suwzklatySS3Q0+NCxCDh5hYfgXdQUWU1DNcxwAxStM= +github.com/RocketChat/Rocket.Chat.Go.SDK v0.0.0-20210506200512-3b3352a919f0/go.mod h1:rjP7sIipbZcagro/6TCk6X0ZeFT2eyudH5+fve/cbBA= github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= github.com/VividCortex/ewma v1.1.1 h1:MnEK4VOv6n0RSY4vtRe3h11qjxL3+t0B8yOL8iMXdcM= @@ -79,9 +88,23 @@ github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d h1:Byv0BzEl3/e6D5CLfI0j/7hiIEtvGVFPCZ7Ei2oq8iQ= github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= +github.com/atc0005/go-teams-notify/v2 v2.6.1/go.mod h1:xo6GejLDHn3tWBA181F8LrllIL0xC1uRsRxq7YNXaaY= github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= +github.com/aws/aws-sdk-go-v2 v1.16.1/go.mod h1:ytwTPBG6fXTZLxxeeCCWj2/EMYp/xDUgX+OET6TLNNU= +github.com/aws/aws-sdk-go-v2/config v1.15.2/go.mod h1:S1p1xf7DGVp0srNq0BakyxfirOldPQeDVlx7+fllyok= +github.com/aws/aws-sdk-go-v2/credentials v1.11.1/go.mod h1:pYrHWfKUoWTmbr+xTf6ZoWeyyvLAQ5BPT3aL+nKlTpE= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.2/go.mod h1:jmsqNRVo2XlUTNXG/NF7hM7o2gd2jhfg8vdJ135d4XA= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.8/go.mod h1:LnTQMTqbKsbtt+UI5+wPsB7jedW+2ZgozoPG8k6cMxg= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.2/go.mod h1:1x4ZP3Z8odssdhuLI+/1Tqw6Pt/VAaP4Tr8EUxHvPXE= +github.com/aws/aws-sdk-go-v2/internal/ini v1.3.9/go.mod h1:kASRBzoVW4I8KUmGCjsowAqVor9QU9DuTUABVducrTY= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.2/go.mod h1:7hwSi01X5Yj9H0qLQljrn8OSdLwwSym1aQCfGn1tDQQ= +github.com/aws/aws-sdk-go-v2/service/ses v1.14.2/go.mod h1:xPjwSTJ7+h57gQeTUbsrQ6hvr7wjhfNaf3oK1AWuRvA= +github.com/aws/aws-sdk-go-v2/service/sns v1.17.3/go.mod h1:PrZELgNG6JtNfXie2v033h5LznOiaAcI6jF2Fx6JDZM= +github.com/aws/aws-sdk-go-v2/service/sso v1.11.2/go.mod h1:GdCj3+FzI3D5tauOzz8n3YjN70XvgZz82PVVtJXmDds= +github.com/aws/aws-sdk-go-v2/service/sts v1.16.2/go.mod h1:RoMljzynmRe3jyOsRgqIMTzyhpAv6XNxu549M1X4Mdo= +github.com/aws/smithy-go v1.11.2/go.mod h1:3xHYmszWVx2c0kIwQeEVf9uSm4fYZt67FBJnwub1bgM= github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk= github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= @@ -92,13 +115,18 @@ github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kB github.com/bketelsen/crypt v0.0.4/go.mod h1:aI6NrJ0pMGgvZKL1iVgXLnfIFJtfV+bKCoqOes/6LfM= github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ= github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= -github.com/bradfitz/gomemcache v0.0.0-20190913173617-a41fca850d0b h1:L/QXpzIa3pOvUGt1D1lA5KjYhPBAN/3iWdP7xeFS9F0= +github.com/blinkbean/dingtalk v0.0.0-20210905093040-7d935c0f7e19 h1:pamuM2sgLJLoMWfchc6y071z8ifalajU7btZmZNhoH4= +github.com/blinkbean/dingtalk v0.0.0-20210905093040-7d935c0f7e19/go.mod h1:9BaLuGSBqY3vT5hstValh48DbsKO7vaHaJnG9pXwbto= github.com/bradfitz/gomemcache v0.0.0-20190913173617-a41fca850d0b/go.mod h1:H0wQNHz2YrLsuXOZozoeDmnHXkNCRmMW0gwFWDfEZDA= +github.com/bradfitz/gomemcache v0.0.0-20220106215444-fb4bf637b56d h1:pVrfxiGfwelyab6n21ZBkbkmbevaf+WvMIiR7sr97hw= +github.com/bradfitz/gomemcache v0.0.0-20220106215444-fb4bf637b56d/go.mod h1:H0wQNHz2YrLsuXOZozoeDmnHXkNCRmMW0gwFWDfEZDA= +github.com/bwmarrin/discordgo v0.24.0/go.mod h1:NJZpH+1AfhIcyQsPeuBKsUtYrRnjkyu0kIVMCHkZtRY= github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4= github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= -github.com/cenkalti/backoff/v4 v4.1.0 h1:c8LkOFQTzuO0WBM/ae5HdGQuZPfPxp7lqBRwQRm4fSc= github.com/cenkalti/backoff/v4 v4.1.0/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= +github.com/cenkalti/backoff/v4 v4.1.2 h1:6Yo7N8UP2K6LWZnW94DLVSSrbobcWdVzAYOisuDPIFo= +github.com/cenkalti/backoff/v4 v4.1.2/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= @@ -131,12 +159,17 @@ github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:ma github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/cschomburg/go-pushbullet v0.0.0-20171206132031-67759df45fbb/go.mod h1:RfQ9wji3fjcSEsQ+uFCtIh3+BXgcZum8Kt3JxvzYzlk= github.com/davecgh/go-spew v0.0.0-20151105211317-5215b55f46b2/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/deckarep/golang-set v1.7.1/go.mod h1:93vsz/8Wt4joVM7c2AVqh+YRMiUSc14yDtF28KmMOgQ= github.com/denisenkom/go-mssqldb v0.10.0 h1:QykgLZBorFE95+gO3u9esLd0BmbvpWp0/waNNZfHBM8= github.com/denisenkom/go-mssqldb v0.10.0/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU= +github.com/dghubble/go-twitter v0.0.0-20220319054129-995614af6514/go.mod h1:qPG2N91lrezEUoU/9eem10s7fVt+ohhDh0LFv2tq0Og= +github.com/dghubble/oauth1 v0.7.1/go.mod h1:0eEzON0UY/OLACQrmnjgJjmvCGXzjBCsZqL1kWDXtF0= +github.com/dghubble/sling v1.4.0/go.mod h1:0r40aNsU9EdDUVBNhfCstAtFgutjgJGYbO1oNzkMoM8= github.com/dgraph-io/ristretto v0.0.3 h1:jh22xisGBjrEVnRZ1DVTpBVQm0Xndu8sMl0CWDzSIBI= github.com/dgraph-io/ristretto v0.0.3/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= @@ -164,9 +197,13 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.m github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/facebookgo/ensure v0.0.0-20160127193407-b4ab57deab51/go.mod h1:Yg+htXGokKKdzcwhuNDwVvN+uBxDGXJ7G/VN1d8fa64= +github.com/facebookgo/stack v0.0.0-20160209184415-751773369052/go.mod h1:UbMTZqLaRiH3MsBH8va0n7s1pQYcu3uTb8G4tygF4Zg= +github.com/facebookgo/subset v0.0.0-20150612182917-8dac2c3c4870/go.mod h1:5tD+neXqOorC30/tWg0LCSkrqj/AR6gu8yY8/fpw1q0= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.10.0 h1:s36xzo75JdqLaaWoiEHk767eHiwo0598uUxyfiPkDsg= github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM= +github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw= github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4= @@ -199,6 +236,10 @@ github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfC github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= +github.com/go-telegram-bot-api/telegram-bot-api v4.6.4+incompatible h1:2cauKuaELYAEARXRkq2LrJ0yDDv1rW7+wrTEdVL3uaU= +github.com/go-telegram-bot-api/telegram-bot-api v4.6.4+incompatible/go.mod h1:qf9acutJ8cwBUhm1bqgz6Bei9/C/c93FPDljKWwsOgM= +github.com/go-test/deep v1.0.4 h1:u2CU3YKy9I2pmu9pX0eq50wCgjfGIt539SqR7FbHiho= +github.com/go-test/deep v1.0.4/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= github.com/gobuffalo/here v0.6.0 h1:hYrd0a6gDmWxBM4TnrGw8mQg24iSVoIkHEk7FodQcBI= github.com/gobuffalo/here v0.6.0/go.mod h1:wAG085dHOYqUpf+Ap+WOdrPTp5IYcDAs/x7PLa8Y5fM= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= @@ -232,6 +273,7 @@ github.com/golang/mock v1.5.0 h1:jlYHihg//f7RRwuPfptm04yp4s7O6Kw8EZiVYIGcH0g= github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= github.com/golang/protobuf v0.0.0-20161109072736-4bd1920723d7/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a1/R87v0= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= @@ -250,6 +292,8 @@ github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/gomodule/redigo v1.8.5/go.mod h1:P9dn9mFrCBvWhGE1wpxx6fgq7BAeLBk+UUUzlpkBYO0= +github.com/gomodule/redigo v1.8.8/go.mod h1:7ArFNvsTjH8GMMzB4uy1snslv2BwmginuMs06a1uzZE= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= @@ -262,12 +306,14 @@ github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o= +github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= github.com/google/go-github/v30 v30.1.0 h1:VLDx+UolQICEOKu2m4uAoMti1SxuEBAl7RSEG16L+Oo= github.com/google/go-github/v30 v30.1.0/go.mod h1:n8jBpHl45a/rlBUtRJMOG4GhNADUQFEufcolZ95JfU8= -github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= +github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= +github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= github.com/google/gofuzz v0.0.0-20161122191042-44d81051d367/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= @@ -285,12 +331,16 @@ github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLe github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/uuid v0.0.0-20171113160352-8c31c18f31ed/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= +github.com/gopackage/ddp v0.0.0-20170117053602-652027933df4/go.mod h1:lEO7XoHJ/xNRBCxrn4h/CEB67h0kW1B0t4ooP2yrjUA= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= @@ -298,11 +348,17 @@ github.com/gorilla/css v1.0.0 h1:BQqNyPTi50JCFMTw/b67hByjMVXZRwGha6wxVGkeihY= github.com/gorilla/css v1.0.0/go.mod h1:Dn721qIggHpt4+EFCcTLTU/vk5ySda2ReITrtgBl60c= github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= +github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= +github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542/go.mod h1:Ow0tF8D4Kplbc8s8sSb3V2oUCygFHVp8gC3Dn6U4MNI= github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE= github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= @@ -398,7 +454,10 @@ github.com/jinzhu/now v1.1.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/ github.com/jinzhu/now v1.1.2 h1:eVKgfIdy9b6zbWBMgFpfDPoAMifwSZagU9HmEU6zgiI= github.com/jinzhu/now v1.1.2/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= +github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= +github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= +github.com/jordan-wright/email v4.0.1-0.20210109023952-943e75fe5223+incompatible/go.mod h1:1c7szIrayyPPB/987hsnvNzLushdWf4o/79s3P08L8A= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/json-iterator/go v0.0.0-20180612202835-f2b4162afba3/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= @@ -406,6 +465,7 @@ github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/u github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= @@ -438,9 +498,12 @@ github.com/lib/pq v1.3.0 h1:/qkRGz8zljWiDcFvgpwUpwIAPu3r07TDvs3Rws+o/pU= github.com/lib/pq v1.3.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= +github.com/line/line-bot-sdk-go v7.8.0+incompatible h1:Uf9/OxV0zCVfqyvwZPH8CrdiHXXmMRa/L91G3btQblQ= +github.com/line/line-bot-sdk-go v7.8.0+incompatible/go.mod h1:0RjLjJEAU/3GIcHkC3av6O4jInAbt25nnZVmOFUgDBg= github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= github.com/magiconair/properties v1.8.5 h1:b6kJs+EmPFMYGkow9GiUyCyOvIwYetYJ3fSaWak/Gls= github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= +github.com/mailgun/mailgun-go/v4 v4.6.0/go.mod h1:FJlF9rI5cQT+mrwujtJjPMbIVy3Ebor9bKTVsJ0QU40= github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/markbates/pkger v0.17.1 h1:/MKEtWqtc0mZvu9OinB9UzVN9iYCwLWuyUv4Bw+PCno= github.com/markbates/pkger v0.17.1/go.mod h1:0JoVlrol20BSywW79rN3kdFFsE5xYM+rSCQDXbLhiuI= @@ -448,8 +511,9 @@ github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaO github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= -github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ0s8= github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40= +github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= @@ -489,6 +553,7 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJ github.com/modern-go/reflect2 v0.0.0-20180320133207-05fbef0ca5da/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= @@ -500,8 +565,11 @@ github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzE github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= +github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32/go.mod h1:9wM+0iRr9ahx58uYLpLIr5fm8diHn0JbqRycJi6w0Ms= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= +github.com/nikoksr/notify v0.23.0 h1:DhmnnJKOqz9NO+MKrJFHJ+7prm9VF2BV+OSVskWfH1Y= +github.com/nikoksr/notify v0.23.0/go.mod h1:tx53sxS3kT+WQy6ewsCBrafxdnnjFJUxhA5XL5PDgSk= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= @@ -515,6 +583,7 @@ github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+W github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= +github.com/onsi/ginkgo v1.14.1/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= github.com/onsi/ginkgo v1.15.0/go.mod h1:hF8qUzuuC8DJGygJH3726JnCZX4MYbRB8yFfISqnKUg= github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc= github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= @@ -524,6 +593,7 @@ github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1Cpa github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +github.com/onsi/gomega v1.10.2/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.10.5/go.mod h1:gza4q3jKQJijlu05nKWRCW/GavJumGt8aNRxWg7mt48= github.com/onsi/gomega v1.16.0 h1:6gjqkI8iiRHMvdccRJM8rVKjCWk6ZIm6FTm3ddIe4/c= github.com/onsi/gomega v1.16.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= @@ -549,11 +619,13 @@ github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9 github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.8.1-0.20161029093637-248dadf4e906/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA= github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= +github.com/plivo/plivo-go/v7 v7.8.0/go.mod h1:Jw1e16x0WjW334botVeKQT4hcMXMN55r4HH0XoGsR6Q= github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= @@ -607,16 +679,23 @@ github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0 github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= github.com/scylladb/termtables v0.0.0-20191203121021-c4c0b6d42ff4/go.mod h1:C1a7PQSMz9NShzorzCiG2fk9+xuCgLkPeCvMHYR2OWg= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= +github.com/sendgrid/rest v2.6.7+incompatible/go.mod h1:kXX7q3jZtJXK5c5qK83bSGMdV6tsOE70KbHoqJls4lE= +github.com/sendgrid/sendgrid-go v3.10.5+incompatible/go.mod h1:QRQt+LX/NmgVEvmdRw0VT/QgUn499+iza2FnDca9fg8= github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4= github.com/shopspring/decimal v0.0.0-20200227202807-02e2044944cc h1:jUIKcSPO9MoMJBbEoyE/RJoE8vz7Mb8AjvifMMwSyvY= github.com/shopspring/decimal v0.0.0-20200227202807-02e2044944cc/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= +github.com/silenceper/wechat/v2 v2.1.2/go.mod h1:0OprxYCCp2CZAKw06BBlnaczInTk2KxOLsKeiopshGg= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/skip2/go-qrcode v0.0.0-20190110000554-dc11ecdae0a9/go.mod h1:PLPIyL7ikehBD1OAjmKKiOEhbvWyHGaNDjquXMcYABo= +github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e/go.mod h1:XV66xRDqSt+GTGFMVlhk3ULuV0y9ZmzeVGR4mloJI3M= +github.com/slack-go/slack v0.10.2 h1:KMN/h2sgUninHXvQI8PrR/PHBUuWp2NPvz2Kr66tki4= +github.com/slack-go/slack v0.10.2/go.mod h1:5FLdBRv7VW/d9EBxx/eEktOptWygbA9K2QK/KW7ds1s= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/assertions v1.0.1 h1:voD4ITNjPL5jjBfgR/r8fPIIBrliWrWHeiJApdr3r4w= github.com/smartystreets/assertions v1.0.1/go.mod h1:kHHU4qYBaI3q23Pp3VPrmWhuIUrLW/7eUrw0BU5VaoM= @@ -624,6 +703,7 @@ github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIK github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= +github.com/sony/sonyflake v1.0.0/go.mod h1:Jv3cfhf/UFtolOTTRd3q4Nl6ENqM+KfyZ5PseKfZGF4= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.6.0 h1:xoax2sJ2DT8S8xA2paPFjDCScCNeWsg75VG0DLRreiY= github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= @@ -649,18 +729,23 @@ github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5J github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= +github.com/stretchr/objx v0.3.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= github.com/stretchr/testify v0.0.0-20151208002404-e3a8ff8ce365/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/tcnksm/go-gitconfig v0.1.2 h1:iiDhRitByXAEyjgBqsKi9QU4o2TNtv9kPP3RgPgXBPw= github.com/tcnksm/go-gitconfig v0.1.2/go.mod h1:/8EhP4H7oJZdIPyT+/UIsG87kTzrzM4UsLGSItWYCpE= +github.com/technoweenie/multipartstreamer v1.0.1 h1:XRztA5MXiR1TIRHxH2uNxXxaIkKQDeX7m2XsSOlQEnM= +github.com/technoweenie/multipartstreamer v1.0.1/go.mod h1:jNVxdtShOxzAsukZwTSw6MDx5eUJoiEBsSvzDU9uzog= +github.com/textmagic/textmagic-rest-go-v2/v2 v2.0.2457/go.mod h1:PbP69y7uRiNdwtPE3/bVGDaPYA1sr4vuHaGLQAGzeW8= github.com/tidwall/gjson v1.11.0 h1:C16pk7tQNiH6VlCrtIXL1w8GaOsi1X3W8KDkE1BuYd4= github.com/tidwall/gjson v1.11.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= @@ -672,6 +757,8 @@ github.com/ulikunitz/xz v0.5.9 h1:RsKRIA2MO8x56wkkcd3LbtcE/uMszhb6DpRf+3uwa3I= github.com/ulikunitz/xz v0.5.9/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= +github.com/utahta/go-linenotify v0.5.0 h1:E1tJaB/XhqRY/iz203FD0MaHm10DjQPOq5/Mem2A3Gs= +github.com/utahta/go-linenotify v0.5.0/go.mod h1:KsvBXil2wx+ByaCR0e+IZKTbp4pDesc7yjzRigLf6pE= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= @@ -727,6 +814,7 @@ go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190131182504-b8fe1690c613/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= @@ -739,9 +827,11 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= +golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= -golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 h1:7I4JAnoQBe7ZtJcBaYHi5UtiO8tQHbUSXxL+pnGRANg= -golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= +golang.org/x/crypto v0.0.0-20220131195533-30dcbda58838 h1:71vQrMauZZhcTVK6KdYM+rklehEEwb3E+ZhaE5jrPrE= +golang.org/x/crypto v0.0.0-20220131195533-30dcbda58838/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -780,6 +870,7 @@ golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20171115151908-9dfe39835686/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -818,6 +909,7 @@ golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/ golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200904194848-62affa334b73/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= @@ -829,8 +921,9 @@ golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLd golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d h1:LO7XpTYMwTqxjLcGWPijK3vRXg1aWdlNOVOHRq45d7c= -golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd h1:O7DYs+zxREGLKzKoMQrtrEacpb0ZVXA5rIwylE2Xchk= +golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181106182150-f42d05182288/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -843,8 +936,10 @@ golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602 h1:0Ja1LBD+yisY6RWM/BH7TJVXWsSjs2VwBSmvSX4HdBc= golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8 h1:RerP+noqYHUQ8CMRcPlC2nvTa4dcBIjegkuWdcUDuqg= +golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/sync v0.0.0-20171101214715-fd80eb99c8f6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -855,6 +950,7 @@ golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180816055513-1c9583448a9c/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -901,6 +997,7 @@ golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -924,8 +1021,10 @@ golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359 h1:2B5p2L5IfGiD7+b9BOoRMC6DgObAVZV+Fsp050NqXik= -golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220204135822-1c1b9b1eba6a h1:ppl5mZgokTT8uPkmYOyEUmPTr3ypaKkg5eFOGrAmxxE= +golang.org/x/sys v0.0.0-20220204135822-1c1b9b1eba6a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY= @@ -1049,6 +1148,7 @@ google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCID google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= @@ -1126,8 +1226,9 @@ google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpAD google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ= +google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc h1:2gGKlE2+asNV9m7xrywl36YYNnBG5ZQ0r/BOOxqPpmk= gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc/go.mod h1:m7x9LTH6d71AHyAX77c9yqWCCa3UKHcVEj9y7hAtKDk= @@ -1142,6 +1243,7 @@ gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMy gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df h1:n7WqCuqOuCbNr617RXOY0AWRXxgwEyPp2z+p0+hgMuE= gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df/go.mod h1:LRQQ+SO6ZHR7tOkpBDuZnXENFzX8qRjMDMyPD6BRkCw= +gopkg.in/h2non/gock.v1 v1.0.15/go.mod h1:sX4zAkdYX1TRGJ2JY156cFspQn4yRWn6p9EMdODlynE= gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/ini.v1 v1.62.0 h1:duBzk771uxoUuOlyRLkHsygud9+5lrlGjdFBb4mSKDU= diff --git a/http/api_main_add.go b/http/api_main_add.go index 028ef791c..de7dedad8 100644 --- a/http/api_main_add.go +++ b/http/api_main_add.go @@ -1,13 +1,20 @@ package http import ( + "context" + "fmt" + "net/http" + "net/url" "regexp" + "strconv" + "strings" "github.com/ArtalkJS/ArtalkGo/config" "github.com/ArtalkJS/ArtalkGo/lib" "github.com/ArtalkJS/ArtalkGo/lib/email" "github.com/ArtalkJS/ArtalkGo/model" "github.com/labstack/echo/v4" + "github.com/nikoksr/notify" "github.com/sirupsen/logrus" ) @@ -145,6 +152,9 @@ func ActionAdd(c echo.Context) error { // 邮件通知发送 EmailSend(&comment, &parentComment) + + // 其他通知 + UseNotify(&comment, &parentComment) }() return RespData(c, ResponseAdd{ @@ -200,3 +210,75 @@ func EmailSend(comment *model.Comment, parentComment *model.Comment) { } } } + +var NotifyCtx = context.Background() + +// 其他通知方式 +func UseNotify(comment *model.Comment, parentComment *model.Comment) { + // 忽略管理员回复 + coUser := comment.FetchUser() + if coUser.IsAdmin { + return + } + + // 如果不是 root 评论,并且回复的不是管理员,直接忽略 + if !parentComment.IsEmpty() && !parentComment.FetchUser().IsAdmin { + return + } + + // 评论内容 + coContent := comment.Content + if len(coContent) > 280 { + coContent = string([]rune(coContent)[0:280]) + "..." // 截取文字 + } + + // 消息内容 + title := fmt.Sprintf("来自 @%s 的回复", coUser.Name) + msg := fmt.Sprintf("%s\n\n%s", coContent, comment.GetLinkToReply()) + + // 使用 notify 发送 + go func() { + _ = notify.Send(NotifyCtx, title, msg) + }() + + // 飞书 + go func() { + sendLark(title + "\n\n" + msg) + }() + + // Bark + go func() { + sendBark(title, msg) + }() +} + +func sendLark(msg string) { + larkConf := config.Instance.Notify.Lark + if !larkConf.Enabled { + return + } + + sendData := fmt.Sprintf(`{"msg_type":"text","content":{"text":%s}}`, strconv.Quote(msg)) + result, err := http.Post(larkConf.WebhookURL, "application/json", strings.NewReader(sendData)) + if err != nil { + logrus.Error("[飞书]", " 消息发送失败:", err) + return + } + + defer result.Body.Close() +} + +func sendBark(title string, msg string) { + barkConf := config.Instance.Notify.Bark + if !barkConf.Enabled { + return + } + + result, err := http.Get(fmt.Sprintf("%s/%s/%s", strings.TrimSuffix(barkConf.Server, "/"), url.QueryEscape(title), url.QueryEscape(msg))) + if err != nil { + logrus.Error("[Bark]", " 消息发送失败:", err) + return + } + + defer result.Body.Close() +} diff --git a/model/comment.go b/model/comment.go index 098ffe732..562e204e7 100644 --- a/model/comment.go +++ b/model/comment.go @@ -3,6 +3,7 @@ package model import ( "fmt" "net/url" + "path" "strings" "github.com/ArtalkJS/ArtalkGo/config" @@ -83,6 +84,28 @@ func (c *Comment) FetchSite() Site { return site } +// 获取评论回复链接 +func (c *Comment) GetLinkToReply(notifyKey ...string) string { + url := c.PageKey + + // 若 pageKey 为相对路径,生成相对于站点 URL 配置的 URL + if !lib.ValidateURL(url) { + url = path.Join(c.FetchSite().ToCooked().FirstUrl, c.PageKey) + } + + // 请求 query + queryMap := map[string]string{ + "atk_comment": fmt.Sprintf("%d", c.ID), + } + + // atk_notify_key + if len(notifyKey) > 0 { + queryMap["atk_notify_key"] = notifyKey[0] + } + + return lib.AddQueryToURL(url, queryMap) +} + type CookedComment struct { ID uint `json:"id"` Content string `json:"content"` diff --git a/model/notify.go b/model/notify.go index 718f76cf4..a45db0095 100644 --- a/model/notify.go +++ b/model/notify.go @@ -57,14 +57,7 @@ func (n *Notify) GenerateKey() { func (n *Notify) GetReadLink() string { c := n.FetchComment() - if !lib.ValidateURL(c.PageKey) { - return "" - } - - return lib.AddQueryToURL(c.PageKey, map[string]string{ - "atk_comment": fmt.Sprintf("%d", c.ID), - "atk_notify_key": n.Key, - }) + return c.GetLinkToReply(n.Key) } func (n *Notify) SetInitial() error { From 5d5bc6dd24f790733187b8f3d833c7906f4622d9 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Fri, 15 Apr 2022 00:19:59 +0800 Subject: [PATCH 146/349] chore: Modify FeMinVersion to 2.1.9 Signed-off-by: qwqcode --- README.md | 2 +- lib/version.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 50e93eb16..144493bd0 100644 --- a/README.md +++ b/README.md @@ -93,7 +93,7 @@ $ make docker-push - [ ] 阿里云服务 - [ ] 腾讯云服务 - [ ] 关键字 / 正则表达式过滤 -- [x] 评论通知管理员 +- [x] 评论通知管理员 ([notify](https://github.com/nikoksr/notify)) - [x] Telegram Bot - [x] 飞书 WebHook Bot - [x] 钉钉 diff --git a/lib/version.go b/lib/version.go index 8a256d490..3cf85bb9b 100644 --- a/lib/version.go +++ b/lib/version.go @@ -7,4 +7,4 @@ var ( ) // 前端最小要求版本号 -var FeMinVersion string = "2.1.0" +var FeMinVersion string = "2.1.9" From 996b762d5baf99492d37f94d02c16e3b87cd0d9f Mon Sep 17 00:00:00 2001 From: qwqcode Date: Fri, 15 Apr 2022 12:58:36 +0800 Subject: [PATCH 147/349] feat(cmd): Add workdir parameter & gen cmd. Signed-off-by: qwqcode --- cmd/core.go | 213 +++++++++++++++++++++++++++++++++++++++++++ cmd/export.go | 2 + cmd/gen.go | 90 +++++++++++++++++++ cmd/import.go | 6 +- cmd/root.go | 230 ++++------------------------------------------- cmd/serve.go | 28 ------ cmd/server.go | 30 +++++++ cmd/upgrade.go | 9 +- config/config.go | 13 ++- makefile | 2 +- 10 files changed, 373 insertions(+), 250 deletions(-) create mode 100644 cmd/core.go create mode 100644 cmd/gen.go delete mode 100644 cmd/serve.go create mode 100644 cmd/server.go diff --git a/cmd/core.go b/cmd/core.go new file mode 100644 index 000000000..823cac1ca --- /dev/null +++ b/cmd/core.go @@ -0,0 +1,213 @@ +package cmd + +import ( + "os" + "strings" + "time" + + "github.com/ArtalkJS/ArtalkGo/config" + "github.com/ArtalkJS/ArtalkGo/lib" + "github.com/ArtalkJS/ArtalkGo/lib/email" + "github.com/ArtalkJS/ArtalkGo/model" + "github.com/nikoksr/notify" + "github.com/nikoksr/notify/service/dingding" + "github.com/nikoksr/notify/service/line" + "github.com/nikoksr/notify/service/slack" + "github.com/nikoksr/notify/service/telegram" + "github.com/rifflock/lfshook" + "github.com/sirupsen/logrus" + prefixed "github.com/x-cray/logrus-prefixed-formatter" + "gorm.io/gorm" +) + +// 装载核心功能 +func loadCore() { + initConfig() + initLog() + initDB() + syncConfWithDB() + initCache() + email.InitQueue() // 初始化邮件队列 + initNotify() +} + +// 1. 初始化配置 +func initConfig() { + config.Init(cfgFile, workDir) + + // 检查 app_key 是否设置 + if strings.TrimSpace(config.Instance.AppKey) == "" { + logrus.Fatal("请检查配置文件,并设置一个 app_key (任意字符串) 用于数据加密") + } + + // 设置时区 + if strings.TrimSpace(config.Instance.TimeZone) == "" { + logrus.Fatal("请检查配置文件,并设置 timezone") + } + denverLoc, _ := time.LoadLocation(config.Instance.TimeZone) + time.Local = denverLoc +} + +// 2. 初始化日志 +func initLog() { + if !config.Instance.Log.Enabled { + return + } + + // 命令行输出格式 + stdFormatter := &prefixed.TextFormatter{ + DisableTimestamp: true, + ForceFormatting: true, + ForceColors: true, + DisableColors: false, + } + + // 文件输出格式 + fileFormatter := &prefixed.TextFormatter{ + FullTimestamp: true, + TimestampFormat: "2006-01-02.15:04:05.000000", + ForceFormatting: true, + ForceColors: false, + DisableColors: true, + } + + // logrus.SetLevel(logrus.DebugLevel) + logrus.SetFormatter(stdFormatter) + logrus.SetOutput(os.Stdout) + + if config.Instance.Debug { + logrus.SetLevel(logrus.DebugLevel) + } + + if config.Instance.Log.Filename != "" { + // 文件保存 + pathMap := lfshook.PathMap{ + logrus.InfoLevel: config.Instance.Log.Filename, + logrus.DebugLevel: config.Instance.Log.Filename, + logrus.ErrorLevel: config.Instance.Log.Filename, + } + logrus.AddHook(lfshook.NewHook( + pathMap, + fileFormatter, + )) + } +} + +// 3. 初始化数据库 +func initDB() { + var db *gorm.DB + db, err := lib.OpenDB(config.DBType(config.Instance.DB.Type), config.Instance.DB.Dsn) + if err != nil { + logrus.Error("数据库初始化发生错误 ", err) + os.Exit(1) + } + + lib.DB = db + + // Migrate the schema + lib.DB.AutoMigrate(&model.Site{}, &model.Page{}, &model.User{}, + &model.Comment{}, &model.Notify{}, &model.Vote{}, &model.PV{}) // 注意表的创建顺序,因为有关联字段 +} + +// 4. 同步配置文件与数据库 +func syncConfWithDB() { + // 初始化默认站点 + siteDefault := strings.TrimSpace(config.Instance.SiteDefault) + if siteDefault == "" { + logrus.Error("请设置 SiteDefault 默认站点,不能为空") + os.Exit(1) + } + model.FindCreateSite(siteDefault) + + // 导入配置文件的管理员用户 + for _, admin := range config.Instance.AdminUsers { + user := model.FindUser(admin.Name, admin.Email) + if user.IsEmpty() { + // create + user = model.User{ + Name: admin.Name, + Email: admin.Email, + Link: admin.Link, + Password: admin.Password, + BadgeName: admin.BadgeName, + BadgeColor: admin.BadgeColor, + IsAdmin: true, + IsInConf: true, + } + lib.DB.Create(&user) + } else { + // update + user.Name = admin.Name + user.Email = admin.Email + user.Link = admin.Link + user.Password = admin.Password + user.BadgeName = admin.BadgeName + user.BadgeColor = admin.BadgeColor + user.IsAdmin = true + user.IsInConf = true + lib.DB.Save(&user) + } + } + + // 清理配置文件中不存在的用户 + var dbAdminUsers []model.User + lib.DB.Model(&model.User{}).Where(&model.User{IsInConf: true}).Find(&dbAdminUsers) + for _, dbU := range dbAdminUsers { + isUserExist := func() bool { + for _, confU := range config.Instance.AdminUsers { + // 忽略大小写比较 + if strings.EqualFold(confU.Name, dbU.Name) && strings.EqualFold(confU.Email, dbU.Email) { + return true + } + } + return false + } + + if !isUserExist() { + lib.DB.Unscoped().Delete(&dbU) + } + } +} + +// 5. 初始化缓存 +func initCache() { + err := lib.OpenCache() + if err != nil { + logrus.Error("缓存初始化发生错误 ", err) + os.Exit(1) + } +} + +// 6. 初始化 Notify +func initNotify() { + // Telegram + tgConf := config.Instance.Notify.Telegram + if tgConf.Enabled { + telegramService, _ := telegram.New(tgConf.ApiToken) + telegramService.AddReceivers(tgConf.Receivers...) + notify.UseServices(telegramService) + } + + // 钉钉 + dingTalkConf := config.Instance.Notify.DingTalk + if dingTalkConf.Enabled { + dingTalkService := dingding.New(&dingding.Config{Token: dingTalkConf.Token, Secret: dingTalkConf.Secret}) + notify.UseServices(dingTalkService) + } + + // Slack + slackConf := config.Instance.Notify.Slack + if slackConf.Enabled { + slackService := slack.New(slackConf.OauthToken) + slackService.AddReceivers(slackConf.Receivers...) + notify.UseServices(slackService) + } + + // LINE + LINEConf := config.Instance.Notify.LINE + if LINEConf.Enabled { + lineService, _ := line.New(config.Instance.Notify.LINE.ChannelSecret, config.Instance.Notify.LINE.ChannelAccessToken) + lineService.AddReceivers(LINEConf.Receivers...) + notify.UseServices(lineService) + } +} diff --git a/cmd/export.go b/cmd/export.go index 0a159f5dc..dbad82f8a 100644 --- a/cmd/export.go +++ b/cmd/export.go @@ -20,6 +20,8 @@ var exportCmd = &cobra.Command{ - 文档:https://artalk.js.org/guide/transfer.html `, Run: func(cmd *cobra.Command, args []string) { + loadCore() // 装载核心 + jsonStr, err := artransfer.ExportArtransString() if err != nil { logrus.Fatal(err) diff --git a/cmd/gen.go b/cmd/gen.go new file mode 100644 index 000000000..b08f4de26 --- /dev/null +++ b/cmd/gen.go @@ -0,0 +1,90 @@ +package cmd + +import ( + "fmt" + "io/ioutil" + "math/rand" + "os" + "path/filepath" + "strings" + + "github.com/ArtalkJS/ArtalkGo/pkged" + "github.com/sirupsen/logrus" + "github.com/spf13/cobra" +) + +var genCmd = &cobra.Command{ + Use: "gen <类型> <目标路径>", + Short: "生成一些内容", + Long: "生成一些内容\n例如:artalk-go gen artalk-go.example.yml ./artalk-go.yml", + Args: cobra.RangeArgs(1, 2), + Run: func(cmd *cobra.Command, args []string) { + // 工作目录 + if workDir != "" { + if err := os.Chdir(workDir); err != nil { + logrus.Fatal("工作目录切换错误 ", err) + } + } + + // 参数 + genType := args[0] + genPath := filepath.Base(genType) + if len(args) >= 2 { + genPath = args[1] + } + + file, err := pkged.Open("/" + strings.TrimPrefix(genType, "/")) + if err != nil { + logrus.Fatal("无效的内置资源: "+genType+" ", err) + } + + buf, err := ioutil.ReadAll(file) + if err != nil { + logrus.Fatal("读取内置资源: "+genType+" 失败 ", err) + } + + // 自动生成 app_key + if strings.Contains(filepath.Base(genType), "artalk-go.example.yml") { + str := string(buf) + appKey := RandStringRunes(16) + str = strings.Replace(str, `app_key: ""`, fmt.Sprintf(`app_key: "%s"`, appKey), 1) + buf = []byte(str) + } + + absPath, err := filepath.Abs(genPath) + if err != nil { + logrus.Fatal(err) + } + + _, err = os.Stat(absPath) + if err == nil { + logrus.Fatal("已存在文件: " + absPath) + } + + dst, err := os.Create(absPath) + if err != nil { + logrus.Fatal("创建目标文件失败 ", err) + } + defer dst.Close() + + if _, err = dst.Write(buf); err != nil { + logrus.Fatal("写入目标文件失败 ", err) + } + + logrus.Info("创建文件: " + absPath) + }, +} + +func init() { + rootCmd.AddCommand(genCmd) +} + +var letterRunes = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!@#$%^&*") + +func RandStringRunes(n int) string { + b := make([]rune, n) + for i := range b { + b[i] = letterRunes[rand.Intn(len(letterRunes))] + } + return string(b) +} diff --git a/cmd/import.go b/cmd/import.go index be9c67da4..e62c83d5d 100644 --- a/cmd/import.go +++ b/cmd/import.go @@ -18,7 +18,11 @@ var importCmd = &cobra.Command{ - 例如:artalk-go import typecho [参数] - 文档:https://artalk.js.org/guide/transfer.html `, + Args: cobra.MinimumNArgs(1), + ArgAliases: artransfer.GetSupportNames(), Run: func(cmd *cobra.Command, args []string) { + loadCore() // 装载核心 + parcelFile := args[0] if _, err := os.Stat(parcelFile); errors.Is(err, os.ErrNotExist) { logrus.Fatal("`数据行囊` 文件不存在,请检查路径是否正确") @@ -36,8 +40,6 @@ var importCmd = &cobra.Command{ logrus.Info("导入结束") }, - Args: cobra.MinimumNArgs(1), - ArgAliases: artransfer.GetSupportNames(), } func init() { diff --git a/cmd/root.go b/cmd/root.go index 1bb110b52..e8ad09d86 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -2,24 +2,9 @@ package cmd import ( "fmt" - "os" - "strings" - "time" - "github.com/ArtalkJS/ArtalkGo/config" "github.com/ArtalkJS/ArtalkGo/lib" - "github.com/ArtalkJS/ArtalkGo/lib/email" - "github.com/ArtalkJS/ArtalkGo/model" - "github.com/nikoksr/notify" - "github.com/nikoksr/notify/service/dingding" - "github.com/nikoksr/notify/service/line" - "github.com/nikoksr/notify/service/slack" - "github.com/nikoksr/notify/service/telegram" - "github.com/rifflock/lfshook" - "github.com/sirupsen/logrus" "github.com/spf13/cobra" - prefixed "github.com/x-cray/logrus-prefixed-formatter" - "gorm.io/gorm" ) var Version = lib.Version + `/` + lib.CommitHash @@ -39,7 +24,10 @@ Artalk (` + Version + `) -> https://artalk.js.org ` -var cfgFile string +var ( + cfgFile string + workDir string +) var rootCmd = &cobra.Command{ Use: "artalk-go", @@ -47,10 +35,9 @@ var rootCmd = &cobra.Command{ Long: Banner, Version: Version, Run: func(cmd *cobra.Command, args []string) { - // fmt.Println(Banner) - // fmt.Println() - // fmt.Println("NOTE: add `-h` flag to show help about any command.") - serveCmd.Run(cmd, args) + fmt.Println(Banner) + fmt.Print("-------------------------------\n\n") + fmt.Println("NOTE: add `-h` flag to show help about any command.") }, } @@ -59,205 +46,18 @@ func Execute() { } func init() { - cobra.OnInitialize(initConfig) - cobra.OnInitialize(initLog) - cobra.OnInitialize(initDB) - cobra.OnInitialize(syncConfWithDB) - cobra.OnInitialize(initCache) - cobra.OnInitialize(email.InitQueue) // 初始化邮件队列 - cobra.OnInitialize(initNotify) - - rootCmd.SetVersionTemplate("Artalk-GO {{printf \"version %s\" .Version}}\n") - rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "配置文件路径 (defaults are './artalk-go.yml')") + rootCmd.SetVersionTemplate("ArtalkGo ({{printf \"%s\" .Version}})\n") + rootCmd.PersistentFlags().StringVarP(&cfgFile, "config", "c", "", "配置文件路径 (defaults are './artalk-go.yml')") + rootCmd.PersistentFlags().StringVarP(&workDir, "workdir", "w", "", "程序工作目录 (defaults are './')") + // Version Command versionCmd := &cobra.Command{ - Use: "version", - Short: "输出 ArtalkGo 版本信息", - Version: Version, + Use: "version", + Short: "输出版本信息", Run: func(cmd *cobra.Command, args []string) { - fmt.Println("ArtalkGo (" + lib.Version + "/" + lib.CommitHash + ")") + fmt.Println("ArtalkGo (" + Version + ")") }, } - rootCmd.AddCommand(versionCmd) -} - -// 1. 初始化配置 -func initConfig() { - config.Init(cfgFile) - - // 检查 app_key 是否设置 - if strings.TrimSpace(config.Instance.AppKey) == "" { - logrus.Fatal("请检查配置文件,并设置一个 app_key (任意字符串) 用于数据加密") - } - - // 设置时区 - if strings.TrimSpace(config.Instance.TimeZone) == "" { - logrus.Fatal("请检查配置文件,并设置 timezone") - } - denverLoc, _ := time.LoadLocation(config.Instance.TimeZone) - time.Local = denverLoc -} - -// 2. 初始化日志 -func initLog() { - if !config.Instance.Log.Enabled { - return - } - - // 命令行输出格式 - stdFormatter := &prefixed.TextFormatter{ - DisableTimestamp: true, - ForceFormatting: true, - ForceColors: true, - DisableColors: false, - } - - // 文件输出格式 - fileFormatter := &prefixed.TextFormatter{ - FullTimestamp: true, - TimestampFormat: "2006-01-02.15:04:05.000000", - ForceFormatting: true, - ForceColors: false, - DisableColors: true, - } - - // logrus.SetLevel(logrus.DebugLevel) - logrus.SetFormatter(stdFormatter) - logrus.SetOutput(os.Stdout) - - if config.Instance.Debug { - logrus.SetLevel(logrus.DebugLevel) - } - - if config.Instance.Log.Filename != "" { - // 文件保存 - pathMap := lfshook.PathMap{ - logrus.InfoLevel: config.Instance.Log.Filename, - logrus.DebugLevel: config.Instance.Log.Filename, - logrus.ErrorLevel: config.Instance.Log.Filename, - } - logrus.AddHook(lfshook.NewHook( - pathMap, - fileFormatter, - )) - } -} - -// 3. 初始化数据库 -func initDB() { - var db *gorm.DB - db, err := lib.OpenDB(config.DBType(config.Instance.DB.Type), config.Instance.DB.Dsn) - if err != nil { - logrus.Error("数据库初始化发生错误 ", err) - os.Exit(1) - } - - lib.DB = db - - // Migrate the schema - lib.DB.AutoMigrate(&model.Site{}, &model.Page{}, &model.User{}, - &model.Comment{}, &model.Notify{}, &model.Vote{}, &model.PV{}) // 注意表的创建顺序,因为有关联字段 -} - -// 4. 同步配置文件与数据库 -func syncConfWithDB() { - // 初始化默认站点 - siteDefault := strings.TrimSpace(config.Instance.SiteDefault) - if siteDefault == "" { - logrus.Error("请设置 SiteDefault 默认站点,不能为空") - os.Exit(1) - } - model.FindCreateSite(siteDefault) - - // 导入配置文件的管理员用户 - for _, admin := range config.Instance.AdminUsers { - user := model.FindUser(admin.Name, admin.Email) - if user.IsEmpty() { - // create - user = model.User{ - Name: admin.Name, - Email: admin.Email, - Link: admin.Link, - Password: admin.Password, - BadgeName: admin.BadgeName, - BadgeColor: admin.BadgeColor, - IsAdmin: true, - IsInConf: true, - } - lib.DB.Create(&user) - } else { - // update - user.Name = admin.Name - user.Email = admin.Email - user.Link = admin.Link - user.Password = admin.Password - user.BadgeName = admin.BadgeName - user.BadgeColor = admin.BadgeColor - user.IsAdmin = true - user.IsInConf = true - lib.DB.Save(&user) - } - } - - // 清理配置文件中不存在的用户 - var dbAdminUsers []model.User - lib.DB.Model(&model.User{}).Where(&model.User{IsInConf: true}).Find(&dbAdminUsers) - for _, dbU := range dbAdminUsers { - isUserExist := func() bool { - for _, confU := range config.Instance.AdminUsers { - // 忽略大小写比较 - if strings.EqualFold(confU.Name, dbU.Name) && strings.EqualFold(confU.Email, dbU.Email) { - return true - } - } - return false - } - - if !isUserExist() { - lib.DB.Unscoped().Delete(&dbU) - } - } -} -// 5. 初始化缓存 -func initCache() { - err := lib.OpenCache() - if err != nil { - logrus.Error("缓存初始化发生错误 ", err) - os.Exit(1) - } -} - -// 6. 初始化 Notify -func initNotify() { - // Telegram - tgConf := config.Instance.Notify.Telegram - if tgConf.Enabled { - telegramService, _ := telegram.New(tgConf.ApiToken) - telegramService.AddReceivers(tgConf.Receivers...) - notify.UseServices(telegramService) - } - - // 钉钉 - dingTalkConf := config.Instance.Notify.DingTalk - if dingTalkConf.Enabled { - dingTalkService := dingding.New(&dingding.Config{Token: dingTalkConf.Token, Secret: dingTalkConf.Secret}) - notify.UseServices(dingTalkService) - } - - // Slack - slackConf := config.Instance.Notify.Slack - if slackConf.Enabled { - slackService := slack.New(slackConf.OauthToken) - slackService.AddReceivers(slackConf.Receivers...) - notify.UseServices(slackService) - } - - // LINE - LINEConf := config.Instance.Notify.LINE - if LINEConf.Enabled { - lineService, _ := line.New(config.Instance.Notify.LINE.ChannelSecret, config.Instance.Notify.LINE.ChannelAccessToken) - lineService.AddReceivers(LINEConf.Receivers...) - notify.UseServices(lineService) - } + rootCmd.AddCommand(versionCmd) } diff --git a/cmd/serve.go b/cmd/serve.go deleted file mode 100644 index bc5773a33..000000000 --- a/cmd/serve.go +++ /dev/null @@ -1,28 +0,0 @@ -package cmd - -import ( - "fmt" - - "github.com/ArtalkJS/ArtalkGo/http" - "github.com/spf13/cobra" -) - -var serveCmd = &cobra.Command{ - Use: "serve", - Aliases: []string{"server"}, - Short: "HTTP 服务", - Long: Banner, - Run: func(cmd *cobra.Command, args []string) { - fmt.Println(Banner) - fmt.Print("-------------------------------\n\n") - http.Run() - }, - Args: cobra.NoArgs, -} - -func init() { - rootCmd.AddCommand(serveCmd) - - flagPV(serveCmd, "host", "", "0.0.0.0", "监听 IP") - flagPV(serveCmd, "port", "", 23366, "监听端口") -} diff --git a/cmd/server.go b/cmd/server.go new file mode 100644 index 000000000..295d55d33 --- /dev/null +++ b/cmd/server.go @@ -0,0 +1,30 @@ +package cmd + +import ( + "fmt" + + "github.com/ArtalkJS/ArtalkGo/http" + "github.com/spf13/cobra" +) + +var serverCmd = &cobra.Command{ + Use: "server", + Aliases: []string{"serve"}, + Short: "启动服务器", + Long: Banner, + Args: cobra.NoArgs, + Run: func(cmd *cobra.Command, args []string) { + loadCore() // 装载核心 + + fmt.Println(Banner) + fmt.Print("-------------------------------\n\n") + http.Run() + }, +} + +func init() { + rootCmd.AddCommand(serverCmd) + + flagPV(serverCmd, "host", "", "0.0.0.0", "监听 IP") + flagPV(serverCmd, "port", "", 23366, "监听端口") +} diff --git a/cmd/upgrade.go b/cmd/upgrade.go index b7cb61feb..e6f54ec61 100644 --- a/cmd/upgrade.go +++ b/cmd/upgrade.go @@ -3,6 +3,7 @@ package cmd import ( "fmt" "os" + "strings" "github.com/ArtalkJS/ArtalkGo/lib" "github.com/blang/semver" @@ -14,9 +15,12 @@ import ( var upgradeCmd = &cobra.Command{ Use: "upgrade", Aliases: []string{"update"}, - Short: "升级 ArtalkGo 到最新版本", + Short: "升级到最新版", Long: "将 ArtalkGo 升级到最新版本,\n更新源为 GitHub Releases,\n更新需要重启 ArtalkGo 才能生效。", + Args: cobra.NoArgs, Run: func(cmd *cobra.Command, args []string) { + // loadCore() // 装载核心 + logrus.Info("从 GitHub Release 检索更新中...") latest, found, err := selfupdate.DetectLatest("ArtalkJS/ArtalkGo") @@ -24,7 +28,7 @@ var upgradeCmd = &cobra.Command{ logrus.Fatal("Error occurred while detecting version: ", err) } - v := semver.MustParse(lib.Version[1:]) + v := semver.MustParse(strings.TrimPrefix(lib.Version, "v")) if !found || latest.Version.LTE(v) { logrus.Println("当前已是最新版本 v" + v.String() + " 无需升级") return @@ -49,7 +53,6 @@ var upgradeCmd = &cobra.Command{ "-------------------------------\n\n" + latest.ReleaseNotes) }, - Args: cobra.NoArgs, } func init() { diff --git a/config/config.go b/config/config.go index 0a75c3379..1a7dc7560 100644 --- a/config/config.go +++ b/config/config.go @@ -1,6 +1,7 @@ package config import ( + "os" "strings" "github.com/sirupsen/logrus" @@ -173,7 +174,7 @@ type NotifyLINEConf struct { } // Init 初始化配置 -func Init(cfgFile string) { +func Init(cfgFile string, workDir string) { viper.SetConfigType("yaml") if cfgFile != "" { @@ -189,9 +190,19 @@ func Init(cfgFile string) { viper.AutomaticEnv() viper.SetEnvKeyReplacer(strings.NewReplacer(".", "_")) + // 切换工作目录 + if workDir != "" { + viper.AddConfigPath(workDir) // must before + if err := os.Chdir(workDir); err != nil { + logrus.Fatal("工作目录切换错误 ", err) + } + } + if err := viper.ReadInConfig(); err == nil { // fmt.Print("\n") // fmt.Println("- Using ArtalkGo config file:", viper.ConfigFileUsed()) + } else { + logrus.Fatal("找不到配置文件,使用 `-h` 参数查看帮助") } Instance = &Config{} diff --git a/makefile b/makefile index 0e1d9b6f6..406d631c6 100644 --- a/makefile +++ b/makefile @@ -25,7 +25,7 @@ build-frontend: .PHONY: update update: - pkger -include /frontend -include /email-tpl -o pkged + pkger -include /frontend -include /email-tpl -include /artalk-go.example.yml -o pkged .PHONY: run run: all From 73b97a8c899c153ede6b00bcfc01a0131ea1a2d2 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Fri, 15 Apr 2022 13:17:46 +0800 Subject: [PATCH 148/349] fix(docker): Run artalk-go anywhere with a right config Signed-off-by: qwqcode --- Dockerfile | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/Dockerfile b/Dockerfile index c231f9402..c49985a04 100644 --- a/Dockerfile +++ b/Dockerfile @@ -32,15 +32,19 @@ COPY --from=builder /source/ArtalkGo/bin/artalk-go /artalk-go RUN apk upgrade \ && apk add bash tzdata \ - && ln -s /artalk-go /usr/bin/artalk-go \ && ln -sf /usr/share/zoneinfo/${TZ} /etc/localtime \ && echo ${TZ} > /etc/timezone +# add alias +RUN echo -e '#!/bin/bash\n/artalk-go -w / -c /conf.yml "$@"' > /usr/bin/artalk-go \ + && chmod +x /usr/bin/artalk-go \ + && cp -p /usr/bin/artalk-go /usr/bin/artalk + VOLUME ["/conf.yml", "/data"] -ENTRYPOINT ["/artalk-go"] +ENTRYPOINT ["/usr/bin/artalk-go"] # expose ArtalkGo default port EXPOSE 23366 -CMD ["serve", "--config", "/conf.yml", "--host", "0.0.0.0", "--port", "23366"] +CMD ["server", "--host", "0.0.0.0", "--port", "23366"] From 651ac9d973bf8aac796d6f99cfe12ff1bbd4efae Mon Sep 17 00:00:00 2001 From: qwqcode Date: Fri, 15 Apr 2022 14:00:47 +0800 Subject: [PATCH 149/349] chore(license): Relicense project to LGPL-v3 Signed-off-by: qwqcode --- LICENSE | 827 +++++++++++--------------------------------------------- 1 file changed, 159 insertions(+), 668 deletions(-) diff --git a/LICENSE b/LICENSE index f288702d2..0a041280b 100644 --- a/LICENSE +++ b/LICENSE @@ -1,674 +1,165 @@ - GNU GENERAL PUBLIC LICENSE + GNU LESSER GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. - Preamble - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Use with the GNU Affero General Public License. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -Also add information on how to contact you by electronic and paper mail. - - If the program does terminal interaction, make it output a short -notice like this when it starts in an interactive mode: - - Copyright (C) - This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, your program's commands -might be different; for a GUI interface, you would use an "about box". - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU GPL, see -. - - The GNU General Public License does not permit incorporating your program -into proprietary programs. If your program is a subroutine library, you -may consider it more useful to permit linking proprietary applications with -the library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. But first, please read -. + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. From 9c463c1705b2e119effdaed49d53467504d412f0 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Fri, 15 Apr 2022 22:01:32 +0800 Subject: [PATCH 150/349] feat(tencent_tms): Support tencent tms for Spam detection. Signed-off-by: qwqcode --- artalk-go.example.yml | 9 +++++- config/config.go | 13 +++++++-- go.mod | 2 ++ go.sum | 4 +++ lib/anti_spam.go | 2 +- lib/anti_spam_tms.go | 68 +++++++++++++++++++++++++++++++++++++++++++ makefile | 4 +-- model/comment.go | 20 +++++++++++++ 8 files changed, 116 insertions(+), 6 deletions(-) create mode 100644 lib/anti_spam_tms.go diff --git a/artalk-go.example.yml b/artalk-go.example.yml index 673737356..3ebef6656 100644 --- a/artalk-go.example.yml +++ b/artalk-go.example.yml @@ -52,7 +52,14 @@ login_timeout: 259200 # 评论审核 moderator: pending_default: false # 发表新评论默认为 “待审状态” - akismet_key: "" # 启用 akismet.com 反垃圾 + # akismet.com 反垃圾 + akismet_key: "" + # 腾讯云文本内容安全 (tms) + tencent_tms: # https://cloud.tencent.com/document/product/1124/64508 + enabled: false + secret_id: "" + secret_key: "" + region: "ap-guangzhou" # 验证码 captcha: diff --git a/config/config.go b/config/config.go index 1a7dc7560..c0547da64 100644 --- a/config/config.go +++ b/config/config.go @@ -60,8 +60,17 @@ type AdminUserConf struct { } type ModeratorConf struct { - PendingDefault bool `mapstructure:"pending_default" json:"pending_default"` - AkismetKey string `mapstructure:"akismet_key" json:"akismet_key"` + PendingDefault bool `mapstructure:"pending_default" json:"pending_default"` + AkismetKey string `mapstructure:"akismet_key" json:"akismet_key"` + TencentTMS TencentTMSConf `mapstructure:"tencent_tms" json:"tencent_tms"` +} + +// 腾讯云文本内容安全 +type TencentTMSConf struct { + Enabled bool `mapstructure:"enabled" json:"enabled"` + SecretID string `mapstructure:"secret_id" json:"secret_id"` + SecretKey string `mapstructure:"secret_key" json:"secret_key"` + Region string `mapstructure:"region" json:"region"` } type CaptchaConf struct { diff --git a/go.mod b/go.mod index 3afc97491..7a48a625c 100644 --- a/go.mod +++ b/go.mod @@ -33,6 +33,8 @@ require ( github.com/spf13/cobra v1.2.1 github.com/spf13/viper v1.8.1 github.com/steambap/captcha v1.4.1 + github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.385 + github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/tms v1.0.385 github.com/tidwall/gjson v1.11.0 github.com/x-cray/logrus-prefixed-formatter v0.5.2 github.com/yuin/goldmark v1.4.0 diff --git a/go.sum b/go.sum index 0e330b90d..bf8598961 100644 --- a/go.sum +++ b/go.sum @@ -745,6 +745,10 @@ github.com/tcnksm/go-gitconfig v0.1.2 h1:iiDhRitByXAEyjgBqsKi9QU4o2TNtv9kPP3RgPg github.com/tcnksm/go-gitconfig v0.1.2/go.mod h1:/8EhP4H7oJZdIPyT+/UIsG87kTzrzM4UsLGSItWYCpE= github.com/technoweenie/multipartstreamer v1.0.1 h1:XRztA5MXiR1TIRHxH2uNxXxaIkKQDeX7m2XsSOlQEnM= github.com/technoweenie/multipartstreamer v1.0.1/go.mod h1:jNVxdtShOxzAsukZwTSw6MDx5eUJoiEBsSvzDU9uzog= +github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.385 h1:bwgb0FZJRlPcDn3uRJfA7rI7dZejg7LZS0b8rUBE2CQ= +github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.385/go.mod h1:7sCQWVkxcsR38nffDW057DRGk8mUjK1Ing/EFOK8s8Y= +github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/tms v1.0.385 h1:3ws8Rv3cjIBFcRIAYg+sQ2m28rZ0+oM7pxvqDUWCe+0= +github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/tms v1.0.385/go.mod h1:SixsaLJwZ2HsOwXWDiCtNJJKSTQIXMKE6WShxwrZN0s= github.com/textmagic/textmagic-rest-go-v2/v2 v2.0.2457/go.mod h1:PbP69y7uRiNdwtPE3/bVGDaPYA1sr4vuHaGLQAGzeW8= github.com/tidwall/gjson v1.11.0 h1:C16pk7tQNiH6VlCrtIXL1w8GaOsi1X3W8KDkE1BuYd4= github.com/tidwall/gjson v1.11.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= diff --git a/lib/anti_spam.go b/lib/anti_spam.go index 21a36d681..9db872d1b 100644 --- a/lib/anti_spam.go +++ b/lib/anti_spam.go @@ -32,7 +32,7 @@ type AkismetParams struct { } // @link https://akismet.com/development/api/#comment-check -func SpamCheck_Akismet(params *AkismetParams, key string) (bool, error) { +func SpamCheck_Akismet(params *AkismetParams, key string) (isOK bool, err error) { form := url.Values{} v := reflect.ValueOf(*params) diff --git a/lib/anti_spam_tms.go b/lib/anti_spam_tms.go new file mode 100644 index 000000000..088e800f8 --- /dev/null +++ b/lib/anti_spam_tms.go @@ -0,0 +1,68 @@ +package lib + +import ( + "encoding/base64" + "errors" + "fmt" + + "github.com/ArtalkJS/ArtalkGo/config" + "github.com/sirupsen/logrus" + tCommon "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common" + tErr "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/errors" + tProfile "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/profile" + tms "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/tms/v20200713" +) + +type TMSRequest struct { + ID uint + Content string + UserID uint + UserName string + IP string +} + +// 腾讯云文本内容安全 TMS +// @link https://cloud.tencent.com/document/product/1124/51860 +// @link https://console.cloud.tencent.com/cms/text/overview +func SpamCheck_TencentTMS(co TMSRequest, secretID string, secretKey string, region string) (isOK bool, err error) { + if region == "" { + region = "ap-guangzhou" + } + credential := tCommon.NewCredential(secretID, secretKey) + + cpf := tProfile.NewClientProfile() + cpf.HttpProfile.Endpoint = "tms.tencentcloudapi.com" + client, _ := tms.NewClient(credential, region, cpf) + + dataID := fmt.Sprintf("comment-%d", co.ID) + userID := fmt.Sprintf("%d", co.UserID) + contentBase64 := base64.StdEncoding.EncodeToString([]byte(co.Content)) + + request := tms.NewTextModerationRequest() + request.Content = &contentBase64 + request.DataId = &dataID + request.User = &tms.User{ + UserId: &userID, + Nickname: &co.UserName, + } + request.Device = &tms.Device{ + IP: &co.IP, + } + + response, err := client.TextModeration(request) + + if _, ok := err.(*tErr.TencentCloudSDKError); ok { + return true, errors.New(fmt.Sprintf("An API error has returned: %s", err)) + } + if err != nil { + return true, err + } + + suggestion := response.Response.Suggestion + isPass := suggestion != nil && *suggestion == "Pass" + + if config.Instance.Debug { + logrus.Info(fmt.Sprintf("[腾讯云 TMS 垃圾检测] %s 请求响应 %s\n%s", dataID, response.ToJsonString(), request.ToJsonString())) + } + return isPass, nil +} diff --git a/makefile b/makefile index 406d631c6..ba2ad1cd4 100644 --- a/makefile +++ b/makefile @@ -29,7 +29,7 @@ update: .PHONY: run run: all - ./bin/artalk-go serve $(ARGS) + ./bin/artalk-go server $(ARGS) .PHONY: dev dev: @@ -42,7 +42,7 @@ dev: -X github.com/ArtalkJS/ArtalkGo/lib.CommitHash=${COMMIT_HASH}" \ -o bin/artalk-go \ github.com/ArtalkJS/ArtalkGo - ./bin/artalk-go $(ARGS) + ./bin/artalk-go server $(ARGS) .PHONY: test test: update diff --git a/model/comment.go b/model/comment.go index 562e204e7..7724a4f62 100644 --- a/model/comment.go +++ b/model/comment.go @@ -266,6 +266,26 @@ func (c *Comment) SpamCheck(echoCtx echo.Context) { } } + // 腾讯云 TMS + if config.Instance.Moderator.TencentTMS.Enabled { + secretID := config.Instance.Moderator.TencentTMS.SecretID + secretKey := config.Instance.Moderator.TencentTMS.SecretKey + region := config.Instance.Moderator.TencentTMS.Region + isOK, err := lib.SpamCheck_TencentTMS(lib.TMSRequest{ + ID: c.ID, + Content: c.Content, + UserID: c.UserID, + UserName: user.Name, + IP: c.IP, + }, secretID, secretKey, region) + if err != nil { + logrus.Error("腾讯云 TMS 垃圾检测错误 ", err) + } + if !isOK { + setPending() + } + } + // TODO:关键字过滤 } From a7bb22fa81ee028dcb6cbc1345609c2d30a6d960 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Sat, 16 Apr 2022 00:34:41 +0800 Subject: [PATCH 151/349] feat(anti-spam): Support Aliyun for Spam detection. Signed-off-by: qwqcode --- README.md | 6 +- artalk-go.example.yml | 9 +- config/config.go | 20 +++- go.mod | 1 + go.sum | 12 +- .../anti_spam_akismet.go} | 25 +++-- lib/anti_spam/anti_spam_aliyun.go | 67 +++++++++++ lib/anti_spam/anti_spam_tencent.go | 83 ++++++++++++++ lib/anti_spam_tms.go | 68 ------------ model/comment.go | 105 ++++++++++++------ 10 files changed, 273 insertions(+), 123 deletions(-) rename lib/{anti_spam.go => anti_spam/anti_spam_akismet.go} (82%) create mode 100644 lib/anti_spam/anti_spam_aliyun.go create mode 100644 lib/anti_spam/anti_spam_tencent.go delete mode 100644 lib/anti_spam_tms.go diff --git a/README.md b/README.md index 144493bd0..e281d3b5a 100644 --- a/README.md +++ b/README.md @@ -89,9 +89,9 @@ $ make docker-push - [x] 邮件多模板自定义 - [x] 用户已读标记 - [x] 反垃圾 - - [x] Akismet - - [ ] 阿里云服务 - - [ ] 腾讯云服务 + - [x] [Akismet](https://akismet.com/) + - [x] [阿里云内容安全](https://help.aliyun.com/document_detail/28417.html) + - [x] [腾讯云内容安全](https://cloud.tencent.com/document/product/1124/64508) - [ ] 关键字 / 正则表达式过滤 - [x] 评论通知管理员 ([notify](https://github.com/nikoksr/notify)) - [x] Telegram Bot diff --git a/artalk-go.example.yml b/artalk-go.example.yml index 3ebef6656..8fd79efcd 100644 --- a/artalk-go.example.yml +++ b/artalk-go.example.yml @@ -52,14 +52,21 @@ login_timeout: 259200 # 评论审核 moderator: pending_default: false # 发表新评论默认为 “待审状态” + api_fail_block: false # 垃圾检测 API 请求错误仍然拦截 # akismet.com 反垃圾 akismet_key: "" # 腾讯云文本内容安全 (tms) - tencent_tms: # https://cloud.tencent.com/document/product/1124/64508 + tencent: # https://cloud.tencent.com/document/product/1124/64508 enabled: false secret_id: "" secret_key: "" region: "ap-guangzhou" + # 阿里云内容安全 + aliyun: # https://help.aliyun.com/document_detail/28417.html + enabled: false + access_key_id: "" + access_key_secret: "" + region: "cn-shanghai" # 验证码 captcha: diff --git a/config/config.go b/config/config.go index c0547da64..5b287335d 100644 --- a/config/config.go +++ b/config/config.go @@ -60,19 +60,29 @@ type AdminUserConf struct { } type ModeratorConf struct { - PendingDefault bool `mapstructure:"pending_default" json:"pending_default"` - AkismetKey string `mapstructure:"akismet_key" json:"akismet_key"` - TencentTMS TencentTMSConf `mapstructure:"tencent_tms" json:"tencent_tms"` + PendingDefault bool `mapstructure:"pending_default" json:"pending_default"` + ApiFailBlock bool `mapstructure:"api_fail_block" json:"api_fail_block"` // API 请求错误仍然拦截 + AkismetKey string `mapstructure:"akismet_key" json:"akismet_key"` + Tencent TencentAntispamConf `mapstructure:"tencent" json:"tencent"` + Aliyun AliyunAntispamConf `mapstructure:"aliyun" json:"aliyun"` } -// 腾讯云文本内容安全 -type TencentTMSConf struct { +// 腾讯云反垃圾 +type TencentAntispamConf struct { Enabled bool `mapstructure:"enabled" json:"enabled"` SecretID string `mapstructure:"secret_id" json:"secret_id"` SecretKey string `mapstructure:"secret_key" json:"secret_key"` Region string `mapstructure:"region" json:"region"` } +// 阿里云反垃圾 +type AliyunAntispamConf struct { + Enabled bool `mapstructure:"enabled" json:"enabled"` + AccessKeyID string `mapstructure:"access_key_id" json:"access_key_id"` + AccessKeySecret string `mapstructure:"access_key_secret" json:"access_key_secret"` + Region string `mapstructure:"region" json:"region"` +} + type CaptchaConf struct { Enabled bool `mapstructure:"enabled" json:"enabled"` Always bool `mapstructure:"always" json:"always"` diff --git a/go.mod b/go.mod index 7a48a625c..3112831a3 100644 --- a/go.mod +++ b/go.mod @@ -4,6 +4,7 @@ go 1.16 require ( github.com/PuerkitoBio/goquery v1.7.1 + github.com/aliyun/alibaba-cloud-sdk-go v1.61.1560 github.com/allegro/bigcache/v3 v3.0.0 github.com/araddon/dateparse v0.0.0-20210429162001-6b43995a97de github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d diff --git a/go.sum b/go.sum index bf8598961..b7bb9402f 100644 --- a/go.sum +++ b/go.sum @@ -71,6 +71,8 @@ github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuy github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= +github.com/aliyun/alibaba-cloud-sdk-go v1.61.1560 h1:6rg6LnP+i0Wo6kVx2K7QZafRZ1PyUr5wDYFUzXuzP/c= +github.com/aliyun/alibaba-cloud-sdk-go v1.61.1560/go.mod h1:RcDobYh8k5VP6TNybz9m++gL3ijVI5wueVr0EM10VsU= github.com/allegro/bigcache/v2 v2.2.5 h1:mRc8r6GQjuJsmSKQNPsR5jQVXc8IJ1xsW5YXUYMLfqI= github.com/allegro/bigcache/v2 v2.2.5/go.mod h1:FppZsIO+IZk7gCuj5FiIDHGygD9xvWQcqg1uIPMb6tY= github.com/allegro/bigcache/v3 v3.0.0 h1:5Hxq+GTy8gHEeQccCZZDCfZRTydUfErdUf0iVDcMAFg= @@ -251,6 +253,7 @@ github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7a github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/goji/httpauth v0.0.0-20160601135302-2da839ab0f4d/go.mod h1:nnjvkQ9ptGaCkuDUx6wNykzzlUixGxvkme+H/lnzb+A= github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY= github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe h1:lXe2qZdvpiX5WZkZR4hgp4KJVfY3nMkvmwbVkpv1rVY= @@ -454,17 +457,21 @@ github.com/jinzhu/now v1.1.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/ github.com/jinzhu/now v1.1.2 h1:eVKgfIdy9b6zbWBMgFpfDPoAMifwSZagU9HmEU6zgiI= github.com/jinzhu/now v1.1.2/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= +github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= +github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/jordan-wright/email v4.0.1-0.20210109023952-943e75fe5223+incompatible/go.mod h1:1c7szIrayyPPB/987hsnvNzLushdWf4o/79s3P08L8A= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/json-iterator/go v0.0.0-20180612202835-f2b4162afba3/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.5/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= @@ -549,10 +556,12 @@ github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh github.com/mitchellh/mapstructure v1.4.1 h1:CpVNEelQCZBooIPDn+AR3NpivK/TIKU8bDxdASFVQag= github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v0.0.0-20180320133207-05fbef0ca5da/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= @@ -1250,8 +1259,9 @@ gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df/go.mod h1:LRQQ+SO6ZHR7tOkp gopkg.in/h2non/gock.v1 v1.0.15/go.mod h1:sX4zAkdYX1TRGJ2JY156cFspQn4yRWn6p9EMdODlynE= gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= -gopkg.in/ini.v1 v1.62.0 h1:duBzk771uxoUuOlyRLkHsygud9+5lrlGjdFBb4mSKDU= gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/ini.v1 v1.66.2 h1:XfR1dOYubytKy4Shzc2LHrrGhU0lDCfDGG1yLPmpgsI= +gopkg.in/ini.v1 v1.66.2/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8= gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= diff --git a/lib/anti_spam.go b/lib/anti_spam/anti_spam_akismet.go similarity index 82% rename from lib/anti_spam.go rename to lib/anti_spam/anti_spam_akismet.go index 9db872d1b..7a3fc9656 100644 --- a/lib/anti_spam.go +++ b/lib/anti_spam/anti_spam_akismet.go @@ -1,4 +1,4 @@ -package lib +package anti_spam import ( "errors" @@ -32,7 +32,7 @@ type AkismetParams struct { } // @link https://akismet.com/development/api/#comment-check -func SpamCheck_Akismet(params *AkismetParams, key string) (isOK bool, err error) { +func Akismet(params *AkismetParams, key string) (isPass bool, err error) { form := url.Values{} v := reflect.ValueOf(*params) @@ -49,20 +49,20 @@ func SpamCheck_Akismet(params *AkismetParams, key string) (isOK bool, err error) api := fmt.Sprintf("https://%s.rest.akismet.com/1.1/comment-check", key) req, err := http.NewRequest("POST", api, reqBody) if err != nil { - return true, err + return false, err } req.Header.Add("Content-Type", "application/x-www-form-urlencoded") resp, err := client.Do(req) if err != nil { - return true, err + return false, err } defer resp.Body.Close() respBody, err := ioutil.ReadAll(resp.Body) if err != nil { - return true, err + return false, err } respStr := string(respBody) @@ -71,11 +71,16 @@ func SpamCheck_Akismet(params *AkismetParams, key string) (isOK bool, err error) logrus.Info("akismet 垃圾检测响应 ", respStr) } - if respStr == "true" { - return false, nil // 不是垃圾评论 - } else if respStr == "false" { - return true, nil + switch respStr { + case "true": + // 是垃圾评论 + isPass = false + return isPass, nil + case "false": + // 不是垃圾评论 + isPass = true + return isPass, nil } - return true, errors.New(respStr) + return false, errors.New(respStr) } diff --git a/lib/anti_spam/anti_spam_aliyun.go b/lib/anti_spam/anti_spam_aliyun.go new file mode 100644 index 000000000..1f9fc55c4 --- /dev/null +++ b/lib/anti_spam/anti_spam_aliyun.go @@ -0,0 +1,67 @@ +package anti_spam + +import ( + "errors" + "fmt" + "strconv" + + "github.com/ArtalkJS/ArtalkGo/config" + "github.com/aliyun/alibaba-cloud-sdk-go/services/green" + "github.com/sirupsen/logrus" + "github.com/tidwall/gjson" +) + +type AliyunParams struct { + AccessKeyID string + AccessKeySecret string + Region string + + Content string + CommentID uint +} + +// 阿里云反垃圾 +// @link https://help.aliyun.com/document_detail/70409.html +// @link https://help.aliyun.com/document_detail/107743.html 接入地址 +func Aliyun(p AliyunParams) (isPass bool, err error) { + // Prepare Request + if p.Region == "" { + p.Region = "cn-shanghai" + } + + client, err := green.NewClientWithAccessKey(p.Region, p.AccessKeyID, p.AccessKeySecret) + if err != nil { + return false, err + } + + reqJSON := fmt.Sprintf(`{"scenes":["antispam"],"tasks":[{"content":%s}]}`, strconv.Quote(p.Content)) + + // Send Request + textScanReq := green.CreateTextScanRequest() + textScanReq.SetContent([]byte(reqJSON)) + textScanResp, err := client.TextScan(textScanReq) + if err != nil { + return false, err + } + + if textScanResp.GetHttpStatus() != 200 { + return false, errors.New("Respone got: " + strconv.Itoa(textScanResp.GetHttpStatus())) + } + + // Handle Respone + // @link https://help.aliyun.com/document_detail/70439.html + respRaw := textScanResp.GetHttpContentString() + dataRaw := gjson.Get(respRaw, "data.0.results.0.suggestion") + if !dataRaw.Exists() { + return false, errors.New("Unexpected JSON: " + respRaw) + } + + // Get Result + suggestion := dataRaw.String() + + if config.Instance.Debug { + logrus.Info("[阿里云垃圾检测] ", fmt.Sprintf("%d 请求响应 %s\n%s", p.CommentID, suggestion, respRaw)) + } + + return (suggestion == "pass"), nil +} diff --git a/lib/anti_spam/anti_spam_tencent.go b/lib/anti_spam/anti_spam_tencent.go new file mode 100644 index 000000000..977699b07 --- /dev/null +++ b/lib/anti_spam/anti_spam_tencent.go @@ -0,0 +1,83 @@ +package anti_spam + +import ( + "encoding/base64" + "errors" + "fmt" + + "github.com/ArtalkJS/ArtalkGo/config" + "github.com/sirupsen/logrus" + + // 腾讯啊腾讯.... 怎么这么多引入啊? + tCommon "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common" + tErr "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/errors" + tProfile "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/profile" + tms "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/tms/v20200713" +) + +type TencentParams struct { + SecretID string + SecretKey string + Region string + + Content string + CommentID uint + + UserName string + UserID uint + UserIP string +} + +// 腾讯云文本内容安全 TMS +// @link https://cloud.tencent.com/document/product/1124/51860 +// @link https://console.cloud.tencent.com/cms/text/overview +func Tencent(p TencentParams) (isPass bool, err error) { + // Prepare Request Sign + if p.Region == "" { + p.Region = "ap-guangzhou" + } + + credential := tCommon.NewCredential(p.SecretID, p.SecretKey) + + cpf := tProfile.NewClientProfile() + cpf.HttpProfile.Endpoint = "tms.tencentcloudapi.com" + client, err := tms.NewClient(credential, p.Region, cpf) + if err != nil { + return false, errors.New("NewClient calls error: " + err.Error()) + } + + // Prepare Request Data + dataID := fmt.Sprintf("comment-%d", p.CommentID) + userID := fmt.Sprintf("%d", p.UserID) + + request := tms.NewTextModerationRequest() + request.DataId = &dataID + request.User = &tms.User{ + UserId: &userID, + Nickname: &p.UserName, + } + request.Device = &tms.Device{ + IP: &p.UserIP, + } + + contentBase64 := base64.StdEncoding.EncodeToString([]byte(p.Content)) + request.Content = &contentBase64 + + // Send Request + response, err := client.TextModeration(request) + if _, hasErr := err.(*tErr.TencentCloudSDKError); hasErr { + return false, errors.New("An API error has returned: " + err.Error()) + } + if err != nil { + return false, err + } + + // Get Result + suggestion := response.Response.Suggestion + + if config.Instance.Debug { + logrus.Info("[腾讯云垃圾检测] ", fmt.Sprintf("%s 请求响应 %s\n%s", dataID, response.ToJsonString(), request.ToJsonString())) + } + + return (suggestion != nil && *suggestion == "Pass"), nil +} diff --git a/lib/anti_spam_tms.go b/lib/anti_spam_tms.go deleted file mode 100644 index 088e800f8..000000000 --- a/lib/anti_spam_tms.go +++ /dev/null @@ -1,68 +0,0 @@ -package lib - -import ( - "encoding/base64" - "errors" - "fmt" - - "github.com/ArtalkJS/ArtalkGo/config" - "github.com/sirupsen/logrus" - tCommon "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common" - tErr "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/errors" - tProfile "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/profile" - tms "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/tms/v20200713" -) - -type TMSRequest struct { - ID uint - Content string - UserID uint - UserName string - IP string -} - -// 腾讯云文本内容安全 TMS -// @link https://cloud.tencent.com/document/product/1124/51860 -// @link https://console.cloud.tencent.com/cms/text/overview -func SpamCheck_TencentTMS(co TMSRequest, secretID string, secretKey string, region string) (isOK bool, err error) { - if region == "" { - region = "ap-guangzhou" - } - credential := tCommon.NewCredential(secretID, secretKey) - - cpf := tProfile.NewClientProfile() - cpf.HttpProfile.Endpoint = "tms.tencentcloudapi.com" - client, _ := tms.NewClient(credential, region, cpf) - - dataID := fmt.Sprintf("comment-%d", co.ID) - userID := fmt.Sprintf("%d", co.UserID) - contentBase64 := base64.StdEncoding.EncodeToString([]byte(co.Content)) - - request := tms.NewTextModerationRequest() - request.Content = &contentBase64 - request.DataId = &dataID - request.User = &tms.User{ - UserId: &userID, - Nickname: &co.UserName, - } - request.Device = &tms.Device{ - IP: &co.IP, - } - - response, err := client.TextModeration(request) - - if _, ok := err.(*tErr.TencentCloudSDKError); ok { - return true, errors.New(fmt.Sprintf("An API error has returned: %s", err)) - } - if err != nil { - return true, err - } - - suggestion := response.Response.Suggestion - isPass := suggestion != nil && *suggestion == "Pass" - - if config.Instance.Debug { - logrus.Info(fmt.Sprintf("[腾讯云 TMS 垃圾检测] %s 请求响应 %s\n%s", dataID, response.ToJsonString(), request.ToJsonString())) - } - return isPass, nil -} diff --git a/model/comment.go b/model/comment.go index 7724a4f62..8232f19c4 100644 --- a/model/comment.go +++ b/model/comment.go @@ -4,10 +4,12 @@ import ( "fmt" "net/url" "path" + "strconv" "strings" "github.com/ArtalkJS/ArtalkGo/config" "github.com/ArtalkJS/ArtalkGo/lib" + "github.com/ArtalkJS/ArtalkGo/lib/anti_spam" "github.com/labstack/echo/v4" "github.com/sirupsen/logrus" "gorm.io/gorm" @@ -223,16 +225,40 @@ func (c *Comment) ToCookedForEmail() CookedCommentForEmail { } func (c *Comment) SpamCheck(echoCtx echo.Context) { - setPending := func() { + // 拦截评论 + BlockCommentBy := func(blocker string) { + logrus.Info(fmt.Sprintf("[垃圾拦截] %s 成功拦截评论 ID=%d 内容=%s", blocker, c.ID, strconv.Quote(c.Content))) if c.IsPending { return } - - // 改为待审状态 - c.IsPending = true + c.IsPending = true // 改为待审状态 lib.DB.Save(c) } + // 拦截失败处理 + BlockFailBy := func(blocker string, err error) { + logrus.Error(fmt.Sprintf("[垃圾拦截] %s 拦截发生错误 ID=%d 错误信息: %s", blocker, c.ID, strconv.Quote(c.Content)), err) + } + + // 统一拦截处理 + ApiCommonHandle := func(blocker string, isPass bool, err error) { + // ApiFailBlock mode + isApiFailBlock := config.Instance.Moderator.ApiFailBlock + + if err != nil { + // Api 发生错误 + BlockFailBy(blocker, err) // 报告错误 + if isApiFailBlock { + BlockCommentBy(blocker) // 仍然拦截 + } + } else if !isPass { + // Api 未发生错误,并且 not pass + BlockCommentBy(blocker) // 拦截评论 + } + } + + // Prepare data for Spam-Check + user := c.FetchUser() siteURL := "" if c.SiteName != "" { site := FindSite(c.SiteName) @@ -244,46 +270,55 @@ func (c *Comment) SpamCheck(echoCtx echo.Context) { } } - user := c.FetchUser() - - // akismet + // Akismet akismetKey := strings.TrimSpace(config.Instance.Moderator.AkismetKey) if akismetKey != "" { - isOK, err := lib.SpamCheck_Akismet(&lib.AkismetParams{ - Blog: siteURL, - UserIP: echoCtx.RealIP(), - UserAgent: echoCtx.Request().UserAgent(), + isPass, err := anti_spam.Akismet(&anti_spam.AkismetParams{ + Blog: siteURL, + + UserIP: echoCtx.RealIP(), + UserAgent: echoCtx.Request().UserAgent(), + CommentType: "comment", CommentAuthor: user.Name, CommentAuthorEmail: user.Email, CommentContent: c.Content, }, akismetKey) - if err != nil { - logrus.Error("akismet 垃圾检测错误 ", err) - } - if !isOK { - setPending() - } + + ApiCommonHandle("Akismet", isPass, err) } - // 腾讯云 TMS - if config.Instance.Moderator.TencentTMS.Enabled { - secretID := config.Instance.Moderator.TencentTMS.SecretID - secretKey := config.Instance.Moderator.TencentTMS.SecretKey - region := config.Instance.Moderator.TencentTMS.Region - isOK, err := lib.SpamCheck_TencentTMS(lib.TMSRequest{ - ID: c.ID, - Content: c.Content, - UserID: c.UserID, - UserName: user.Name, - IP: c.IP, - }, secretID, secretKey, region) - if err != nil { - logrus.Error("腾讯云 TMS 垃圾检测错误 ", err) - } - if !isOK { - setPending() - } + // 腾讯云 + tencentConf := config.Instance.Moderator.Tencent + if tencentConf.Enabled { + isPass, err := anti_spam.Tencent(anti_spam.TencentParams{ + SecretID: tencentConf.SecretID, + SecretKey: tencentConf.SecretKey, + Region: tencentConf.Region, + + Content: c.Content, + CommentID: c.ID, + UserID: c.UserID, + UserIP: c.IP, + UserName: user.Name, + }) + + ApiCommonHandle("腾讯云", isPass, err) + } + + // 阿里云 + aliyunConf := config.Instance.Moderator.Aliyun + if aliyunConf.Enabled { + isPass, err := anti_spam.Aliyun(anti_spam.AliyunParams{ + AccessKeyID: aliyunConf.AccessKeyID, + AccessKeySecret: aliyunConf.AccessKeySecret, + Region: aliyunConf.Region, + + Content: c.Content, + CommentID: c.ID, + }) + + ApiCommonHandle("阿里云", isPass, err) } // TODO:关键字过滤 From 93a4f6fe5aa4d920b8a4fe5d1c5a08366e3d6733 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Sat, 16 Apr 2022 01:21:16 +0800 Subject: [PATCH 152/349] feat(anti-spam): Support KeyWords for Spam detection. Signed-off-by: qwqcode --- artalk-go.example.yml | 8 ++++++++ config/config.go | 20 +++++++++++++----- model/comment.go | 47 ++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 69 insertions(+), 6 deletions(-) diff --git a/artalk-go.example.yml b/artalk-go.example.yml index 8fd79efcd..cac16c082 100644 --- a/artalk-go.example.yml +++ b/artalk-go.example.yml @@ -67,6 +67,14 @@ moderator: access_key_id: "" access_key_secret: "" region: "cn-shanghai" + # 关键词词库过滤 + keywords: + enabled: false + pending: false # 匹配成功设为待审状态 + files: # 支持多个词库文件 + - "./data/词库_1.txt" + file_sep: "\n" # 词库文件内容分割符 + replac_to: "*" # 替换字符 # 验证码 captcha: diff --git a/config/config.go b/config/config.go index 5b287335d..83544f25c 100644 --- a/config/config.go +++ b/config/config.go @@ -60,11 +60,12 @@ type AdminUserConf struct { } type ModeratorConf struct { - PendingDefault bool `mapstructure:"pending_default" json:"pending_default"` - ApiFailBlock bool `mapstructure:"api_fail_block" json:"api_fail_block"` // API 请求错误仍然拦截 - AkismetKey string `mapstructure:"akismet_key" json:"akismet_key"` - Tencent TencentAntispamConf `mapstructure:"tencent" json:"tencent"` - Aliyun AliyunAntispamConf `mapstructure:"aliyun" json:"aliyun"` + PendingDefault bool `mapstructure:"pending_default" json:"pending_default"` + ApiFailBlock bool `mapstructure:"api_fail_block" json:"api_fail_block"` // API 请求错误仍然拦截 + AkismetKey string `mapstructure:"akismet_key" json:"akismet_key"` + Tencent TencentAntispamConf `mapstructure:"tencent" json:"tencent"` + Aliyun AliyunAntispamConf `mapstructure:"aliyun" json:"aliyun"` + Keywords KeyWordsAntispamConf `mapstructure:"keywords" json:"keywords"` } // 腾讯云反垃圾 @@ -83,6 +84,15 @@ type AliyunAntispamConf struct { Region string `mapstructure:"region" json:"region"` } +// 关键词词库过滤 +type KeyWordsAntispamConf struct { + Enabled bool `mapstructure:"enabled" json:"enabled"` + Pending bool `mapstructure:"pending" json:"pending"` + Files []string `mapstructure:"files" json:"files"` + FileSep string `mapstructure:"file_sep" json:"file_sep"` + ReplacTo string `mapstructure:"replac_to" json:"replac_to"` +} + type CaptchaConf struct { Enabled bool `mapstructure:"enabled" json:"enabled"` Always bool `mapstructure:"always" json:"always"` diff --git a/model/comment.go b/model/comment.go index 8232f19c4..70eeb272a 100644 --- a/model/comment.go +++ b/model/comment.go @@ -2,6 +2,7 @@ package model import ( "fmt" + "io/ioutil" "net/url" "path" "strconv" @@ -224,6 +225,8 @@ func (c *Comment) ToCookedForEmail() CookedCommentForEmail { } } +var AntiSpamReplaceKeywords *[]string + func (c *Comment) SpamCheck(echoCtx echo.Context) { // 拦截评论 BlockCommentBy := func(blocker string) { @@ -321,7 +324,49 @@ func (c *Comment) SpamCheck(echoCtx echo.Context) { ApiCommonHandle("阿里云", isPass, err) } - // TODO:关键字过滤 + // 关键字过滤 + keywordsConf := config.Instance.Moderator.Keywords + if keywordsConf.Enabled { + // 懒加载,初始化 + if AntiSpamReplaceKeywords == nil { + AntiSpamReplaceKeywords = &[]string{} + // 加载文件 + for _, f := range keywordsConf.Files { + buf, err := ioutil.ReadFile(f) + if err != nil { + logrus.Error("关键词词库文件 " + f + " 加载失败") + } else { + fileContent := string(buf) + *AntiSpamReplaceKeywords = append(*AntiSpamReplaceKeywords, lib.RemoveBlankStrings(lib.SplitAndTrimSpace(fileContent, keywordsConf.FileSep))...) + } + } + } + + // 关键词过滤 + handleContent := c.Content + replaced := false + for _, keyword := range *AntiSpamReplaceKeywords { + if strings.Contains(handleContent, keyword) { + if (keywordsConf.Pending) { + BlockCommentBy("关键词") + break + } + + if (keywordsConf.ReplacTo != "") { + handleContent = strings.Replace(handleContent, keyword, strings.Repeat(keywordsConf.ReplacTo, len(keyword)), -1) + replaced = true + } + } + } + + if (!keywordsConf.Pending && replaced && keywordsConf.ReplacTo != "") { + logrus.Info(fmt.Sprintf("[垃圾拦截] 关键词替换评论 ID=%d 原始内容=%s 替换内容=%s", c.ID, strconv.Quote(c.Content), strconv.Quote(handleContent))) + + // 保存评论 + c.Content = handleContent + lib.DB.Save(c) + } + } } func (c *Comment) ToArtran() Artran { From b85a5a467357601dfa5a54594163d8eeac886267 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Sat, 16 Apr 2022 01:30:37 +0800 Subject: [PATCH 153/349] fix: Truncate Chinese character issue. Signed-off-by: qwqcode --- README.md | 2 +- http/api_main_add.go | 2 +- lib/utils.go | 25 +++++++++++++++++++++++++ 3 files changed, 27 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index e281d3b5a..0d1a5cb9e 100644 --- a/README.md +++ b/README.md @@ -92,7 +92,7 @@ $ make docker-push - [x] [Akismet](https://akismet.com/) - [x] [阿里云内容安全](https://help.aliyun.com/document_detail/28417.html) - [x] [腾讯云内容安全](https://cloud.tencent.com/document/product/1124/64508) - - [ ] 关键字 / 正则表达式过滤 + - [x] 关键字过滤 - [x] 评论通知管理员 ([notify](https://github.com/nikoksr/notify)) - [x] Telegram Bot - [x] 飞书 WebHook Bot diff --git a/http/api_main_add.go b/http/api_main_add.go index de7dedad8..f576a6f2a 100644 --- a/http/api_main_add.go +++ b/http/api_main_add.go @@ -229,7 +229,7 @@ func UseNotify(comment *model.Comment, parentComment *model.Comment) { // 评论内容 coContent := comment.Content if len(coContent) > 280 { - coContent = string([]rune(coContent)[0:280]) + "..." // 截取文字 + coContent = lib.TruncateString(coContent, 280) + "..." // 截取文字 } // 消息内容 diff --git a/lib/utils.go b/lib/utils.go index 2ca1fc013..1aa761913 100644 --- a/lib/utils.go +++ b/lib/utils.go @@ -123,6 +123,31 @@ func RemoveBlankStrings(s []string) []string { return r } +func TruncateString(str string, length int) string { + if length <= 0 { + return "" + } + + // This code cannot support Chinese + // orgLen := len(str) + // if orgLen <= length { + // return str + // } + // return str[:length] + + // Support Chinese + truncated := "" + count := 0 + for _, char := range str { + truncated += string(char) + count++ + if count >= length { + break + } + } + return truncated +} + //#region JSON Any To String (for Transfer) //****************************************** From 53c4a64aa1fa4c50f562f2603852b7a6bb864856 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Sat, 16 Apr 2022 15:08:28 +0800 Subject: [PATCH 154/349] refactor(notify_launcher): notify_launcher refactor and fix some bugs. Signed-off-by: qwqcode --- artalk-go.example.yml | 2 +- cmd/core.go | 45 +------ http/api_main_add.go | 145 ++------------------- http/utils.go | 2 +- lib/anti_spam/anti_spam.go | 159 +++++++++++++++++++++++ lib/email/email.go | 4 - model/comment.go | 152 ---------------------- model/notify_launcher/init.go | 51 ++++++++ model/notify_launcher/notify_launcher.go | 144 ++++++++++++++++++++ model/query.go | 46 +++++-- 10 files changed, 404 insertions(+), 346 deletions(-) create mode 100644 lib/anti_spam/anti_spam.go create mode 100644 model/notify_launcher/init.go create mode 100644 model/notify_launcher/notify_launcher.go diff --git a/artalk-go.example.yml b/artalk-go.example.yml index cac16c082..869864281 100644 --- a/artalk-go.example.yml +++ b/artalk-go.example.yml @@ -74,7 +74,7 @@ moderator: files: # 支持多个词库文件 - "./data/词库_1.txt" file_sep: "\n" # 词库文件内容分割符 - replac_to: "*" # 替换字符 + replac_to: "x" # 替换字符 # 验证码 captcha: diff --git a/cmd/core.go b/cmd/core.go index 823cac1ca..181f93160 100644 --- a/cmd/core.go +++ b/cmd/core.go @@ -7,13 +7,9 @@ import ( "github.com/ArtalkJS/ArtalkGo/config" "github.com/ArtalkJS/ArtalkGo/lib" - "github.com/ArtalkJS/ArtalkGo/lib/email" "github.com/ArtalkJS/ArtalkGo/model" - "github.com/nikoksr/notify" - "github.com/nikoksr/notify/service/dingding" - "github.com/nikoksr/notify/service/line" - "github.com/nikoksr/notify/service/slack" - "github.com/nikoksr/notify/service/telegram" + "github.com/ArtalkJS/ArtalkGo/model/notify_launcher" + "github.com/rifflock/lfshook" "github.com/sirupsen/logrus" prefixed "github.com/x-cray/logrus-prefixed-formatter" @@ -27,8 +23,7 @@ func loadCore() { initDB() syncConfWithDB() initCache() - email.InitQueue() // 初始化邮件队列 - initNotify() + notify_launcher.Init() // 初始化 Notify 发射台 } // 1. 初始化配置 @@ -177,37 +172,3 @@ func initCache() { os.Exit(1) } } - -// 6. 初始化 Notify -func initNotify() { - // Telegram - tgConf := config.Instance.Notify.Telegram - if tgConf.Enabled { - telegramService, _ := telegram.New(tgConf.ApiToken) - telegramService.AddReceivers(tgConf.Receivers...) - notify.UseServices(telegramService) - } - - // 钉钉 - dingTalkConf := config.Instance.Notify.DingTalk - if dingTalkConf.Enabled { - dingTalkService := dingding.New(&dingding.Config{Token: dingTalkConf.Token, Secret: dingTalkConf.Secret}) - notify.UseServices(dingTalkService) - } - - // Slack - slackConf := config.Instance.Notify.Slack - if slackConf.Enabled { - slackService := slack.New(slackConf.OauthToken) - slackService.AddReceivers(slackConf.Receivers...) - notify.UseServices(slackService) - } - - // LINE - LINEConf := config.Instance.Notify.LINE - if LINEConf.Enabled { - lineService, _ := line.New(config.Instance.Notify.LINE.ChannelSecret, config.Instance.Notify.LINE.ChannelAccessToken) - lineService.AddReceivers(LINEConf.Receivers...) - notify.UseServices(lineService) - } -} diff --git a/http/api_main_add.go b/http/api_main_add.go index f576a6f2a..f0add5554 100644 --- a/http/api_main_add.go +++ b/http/api_main_add.go @@ -1,20 +1,15 @@ package http import ( - "context" - "fmt" - "net/http" - "net/url" "regexp" - "strconv" - "strings" "github.com/ArtalkJS/ArtalkGo/config" "github.com/ArtalkJS/ArtalkGo/lib" - "github.com/ArtalkJS/ArtalkGo/lib/email" + "github.com/ArtalkJS/ArtalkGo/lib/anti_spam" "github.com/ArtalkJS/ArtalkGo/model" + "github.com/ArtalkJS/ArtalkGo/model/notify_launcher" "github.com/labstack/echo/v4" - "github.com/nikoksr/notify" + "github.com/sirupsen/logrus" ) @@ -140,145 +135,21 @@ func ActionAdd(c echo.Context) error { // 异步执行 go func() { - // update page + // Page Update if page.ToCooked().URL != "" && page.Title == "" { page.FetchURL() } // 垃圾检测 - if !CheckIsAdminReq(c) { - comment.SpamCheck(c) + if !CheckIsAdminReq(c) { // 忽略检查管理员 + anti_spam.SyncSpamCheck(&comment, c) // 同步执行 } - // 邮件通知发送 - EmailSend(&comment, &parentComment) - - // 其他通知 - UseNotify(&comment, &parentComment) + // 通知发送 + notify_launcher.SendNotify(&comment, &parentComment) }() return RespData(c, ResponseAdd{ Comment: comment.ToCooked(), }) } - -// 邮件发送 (from comment to parentComment) -func EmailSend(comment *model.Comment, parentComment *model.Comment) { - if !config.Instance.Email.Enabled { - return - } - - // 自己回复自己,不提醒 - if comment.UserID == parentComment.UserID { - return - } - - // 邮件回复对方 - if !parentComment.IsEmpty() && !comment.IsPending { - notify := model.FindCreateNotify(parentComment.UserID, comment.ID) - notify.Comment = *comment - email.AsyncSend(¬ify) - } - - // 邮件通知管理员 - admins := model.GetAllAdmins() - userIsAdmin := func(userID uint) bool { - for _, admin := range admins { - if admin.ID == userID { - return true - } - } - return false - } - - if parentComment.IsEmpty() && len(admins) > 0 { - // TODO: 增加用户的站点隔离,指定管理员分配网站 - for _, admin := range admins { - // 管理员自己回复自己,不提醒 - if comment.UserID == admin.ID { - continue - } - - // 管理员评论不回复给其他管理员 - if userIsAdmin(comment.UserID) { - continue - } - - notify := model.FindCreateNotify(admin.ID, comment.ID) - notify.Comment = *comment - email.AsyncSendToAdmin(¬ify, &admin) // 发送邮件给管理员 - } - } -} - -var NotifyCtx = context.Background() - -// 其他通知方式 -func UseNotify(comment *model.Comment, parentComment *model.Comment) { - // 忽略管理员回复 - coUser := comment.FetchUser() - if coUser.IsAdmin { - return - } - - // 如果不是 root 评论,并且回复的不是管理员,直接忽略 - if !parentComment.IsEmpty() && !parentComment.FetchUser().IsAdmin { - return - } - - // 评论内容 - coContent := comment.Content - if len(coContent) > 280 { - coContent = lib.TruncateString(coContent, 280) + "..." // 截取文字 - } - - // 消息内容 - title := fmt.Sprintf("来自 @%s 的回复", coUser.Name) - msg := fmt.Sprintf("%s\n\n%s", coContent, comment.GetLinkToReply()) - - // 使用 notify 发送 - go func() { - _ = notify.Send(NotifyCtx, title, msg) - }() - - // 飞书 - go func() { - sendLark(title + "\n\n" + msg) - }() - - // Bark - go func() { - sendBark(title, msg) - }() -} - -func sendLark(msg string) { - larkConf := config.Instance.Notify.Lark - if !larkConf.Enabled { - return - } - - sendData := fmt.Sprintf(`{"msg_type":"text","content":{"text":%s}}`, strconv.Quote(msg)) - result, err := http.Post(larkConf.WebhookURL, "application/json", strings.NewReader(sendData)) - if err != nil { - logrus.Error("[飞书]", " 消息发送失败:", err) - return - } - - defer result.Body.Close() -} - -func sendBark(title string, msg string) { - barkConf := config.Instance.Notify.Bark - if !barkConf.Enabled { - return - } - - result, err := http.Get(fmt.Sprintf("%s/%s/%s", strings.TrimSuffix(barkConf.Server, "/"), url.QueryEscape(title), url.QueryEscape(msg))) - if err != nil { - logrus.Error("[Bark]", " 消息发送失败:", err) - return - } - - defer result.Body.Close() -} diff --git a/http/utils.go b/http/utils.go index 527794184..1dc252541 100644 --- a/http/utils.go +++ b/http/utils.go @@ -117,7 +117,7 @@ func ParamsDecode(c echo.Context, paramsStruct interface{}, destParams interface } func CheckIfAllowed(c echo.Context, name string, email string, page model.Page, siteName string) (bool, error) { - isAdminUser := model.IsAdminUser(name, email) + isAdminUser := model.IsAdminUserByNameEmail(name, email) // 如果用户是管理员,或者当前页只能管理员评论 if isAdminUser || page.AdminOnly { diff --git a/lib/anti_spam/anti_spam.go b/lib/anti_spam/anti_spam.go new file mode 100644 index 000000000..714918415 --- /dev/null +++ b/lib/anti_spam/anti_spam.go @@ -0,0 +1,159 @@ +package anti_spam + +import ( + "fmt" + "io/ioutil" + "net/url" + "strconv" + "strings" + + "github.com/ArtalkJS/ArtalkGo/config" + "github.com/ArtalkJS/ArtalkGo/lib" + "github.com/ArtalkJS/ArtalkGo/model" + "github.com/labstack/echo/v4" + "github.com/sirupsen/logrus" +) + +var AntiSpamReplaceKeywords *[]string + +func SyncSpamCheck(comment *model.Comment, echoCtx echo.Context) { + // 拦截评论 + BlockCommentBy := func(blocker string) { + logrus.Info(fmt.Sprintf("[垃圾拦截] %s 成功拦截评论 ID=%d 内容=%s", blocker, comment.ID, strconv.Quote(comment.Content))) + if comment.IsPending { + return + } + comment.IsPending = true // 改为待审状态 + lib.DB.Save(comment) + } + + // 拦截失败处理 + BlockFailBy := func(blocker string, err error) { + logrus.Error(fmt.Sprintf("[垃圾拦截] %s 拦截发生错误 ID=%d 错误信息: %s", blocker, comment.ID, strconv.Quote(comment.Content)), err) + } + + // 统一拦截处理 + ApiCommonHandle := func(blocker string, isPass bool, err error) { + // ApiFailBlock mode + isApiFailBlock := config.Instance.Moderator.ApiFailBlock + + if err != nil { + // Api 发生错误 + BlockFailBy(blocker, err) // 报告错误 + if isApiFailBlock { + BlockCommentBy(blocker) // 仍然拦截 + } + } else if !isPass { + // Api 未发生错误,并且 not pass + BlockCommentBy(blocker) // 拦截评论 + } + } + + // Prepare data for Spam-Check + user := comment.FetchUser() + siteURL := "" + if comment.SiteName != "" { + site := model.FindSite(comment.SiteName) + siteURL = site.ToCooked().FirstUrl + } + if siteURL == "" { // 从 referer 中提取网站 + if pr, err := url.Parse(echoCtx.Request().Referer()); err == nil && pr.Scheme != "" && pr.Host != "" { + siteURL = fmt.Sprintf("%s://%s", pr.Scheme, pr.Host) + } + } + + // Akismet + akismetKey := strings.TrimSpace(config.Instance.Moderator.AkismetKey) + if akismetKey != "" { + isPass, err := Akismet(&AkismetParams{ + Blog: siteURL, + + UserIP: echoCtx.RealIP(), + UserAgent: echoCtx.Request().UserAgent(), + + CommentType: "comment", + CommentAuthor: user.Name, + CommentAuthorEmail: user.Email, + CommentContent: comment.Content, + }, akismetKey) + + ApiCommonHandle("Akismet", isPass, err) + } + + // 腾讯云 + tencentConf := config.Instance.Moderator.Tencent + if tencentConf.Enabled { + isPass, err := Tencent(TencentParams{ + SecretID: tencentConf.SecretID, + SecretKey: tencentConf.SecretKey, + Region: tencentConf.Region, + + Content: comment.Content, + CommentID: comment.ID, + UserID: comment.UserID, + UserIP: comment.IP, + UserName: user.Name, + }) + + ApiCommonHandle("腾讯云", isPass, err) + } + + // 阿里云 + aliyunConf := config.Instance.Moderator.Aliyun + if aliyunConf.Enabled { + isPass, err := Aliyun(AliyunParams{ + AccessKeyID: aliyunConf.AccessKeyID, + AccessKeySecret: aliyunConf.AccessKeySecret, + Region: aliyunConf.Region, + + Content: comment.Content, + CommentID: comment.ID, + }) + + ApiCommonHandle("阿里云", isPass, err) + } + + // 关键字过滤 + keywordsConf := config.Instance.Moderator.Keywords + if keywordsConf.Enabled { + // 懒加载,初始化 + if AntiSpamReplaceKeywords == nil { + AntiSpamReplaceKeywords = &[]string{} + // 加载文件 + for _, f := range keywordsConf.Files { + buf, err := ioutil.ReadFile(f) + if err != nil { + logrus.Error("关键词词库文件 " + f + " 加载失败") + } else { + fileContent := string(buf) + *AntiSpamReplaceKeywords = append(*AntiSpamReplaceKeywords, lib.RemoveBlankStrings(lib.SplitAndTrimSpace(fileContent, keywordsConf.FileSep))...) + } + } + } + + // 关键词过滤 + handleContent := comment.Content + replaced := false + for _, keyword := range *AntiSpamReplaceKeywords { + if strings.Contains(handleContent, keyword) { + if keywordsConf.Pending { + BlockCommentBy("关键词") + break + } + + if keywordsConf.ReplacTo != "" { + handleContent = strings.Replace(handleContent, keyword, strings.Repeat(keywordsConf.ReplacTo, len([]rune(keyword))), -1) + replaced = true + } + } + } + + if !keywordsConf.Pending && replaced && keywordsConf.ReplacTo != "" { + logrus.Info(fmt.Sprintf("[垃圾拦截] 关键词替换评论 ID=%d 原始内容=%s 替换内容=%s", comment.ID, strconv.Quote(comment.Content), strconv.Quote(handleContent))) + + // 保存评论 + comment.Content = handleContent + lib.DB.Save(comment) + } + } +} diff --git a/lib/email/email.go b/lib/email/email.go index 8fff45d52..f839945a7 100644 --- a/lib/email/email.go +++ b/lib/email/email.go @@ -24,8 +24,6 @@ func AsyncSend(notify *model.Notify) { return } - notify.SetInitial() - comment := notify.FetchComment() parentComment := notify.GetParentComment() @@ -51,8 +49,6 @@ func AsyncSendToAdmin(notify *model.Notify, admin *model.User) { return } - notify.SetInitial() - comment := notify.FetchComment() from := comment.ToCookedForEmail() to := model.CookedCommentForEmail{ diff --git a/model/comment.go b/model/comment.go index 70eeb272a..2912579c1 100644 --- a/model/comment.go +++ b/model/comment.go @@ -2,17 +2,9 @@ package model import ( "fmt" - "io/ioutil" - "net/url" "path" - "strconv" - "strings" - "github.com/ArtalkJS/ArtalkGo/config" "github.com/ArtalkJS/ArtalkGo/lib" - "github.com/ArtalkJS/ArtalkGo/lib/anti_spam" - "github.com/labstack/echo/v4" - "github.com/sirupsen/logrus" "gorm.io/gorm" ) @@ -225,150 +217,6 @@ func (c *Comment) ToCookedForEmail() CookedCommentForEmail { } } -var AntiSpamReplaceKeywords *[]string - -func (c *Comment) SpamCheck(echoCtx echo.Context) { - // 拦截评论 - BlockCommentBy := func(blocker string) { - logrus.Info(fmt.Sprintf("[垃圾拦截] %s 成功拦截评论 ID=%d 内容=%s", blocker, c.ID, strconv.Quote(c.Content))) - if c.IsPending { - return - } - c.IsPending = true // 改为待审状态 - lib.DB.Save(c) - } - - // 拦截失败处理 - BlockFailBy := func(blocker string, err error) { - logrus.Error(fmt.Sprintf("[垃圾拦截] %s 拦截发生错误 ID=%d 错误信息: %s", blocker, c.ID, strconv.Quote(c.Content)), err) - } - - // 统一拦截处理 - ApiCommonHandle := func(blocker string, isPass bool, err error) { - // ApiFailBlock mode - isApiFailBlock := config.Instance.Moderator.ApiFailBlock - - if err != nil { - // Api 发生错误 - BlockFailBy(blocker, err) // 报告错误 - if isApiFailBlock { - BlockCommentBy(blocker) // 仍然拦截 - } - } else if !isPass { - // Api 未发生错误,并且 not pass - BlockCommentBy(blocker) // 拦截评论 - } - } - - // Prepare data for Spam-Check - user := c.FetchUser() - siteURL := "" - if c.SiteName != "" { - site := FindSite(c.SiteName) - siteURL = site.ToCooked().FirstUrl - } - if siteURL == "" { // 从 referer 中提取网站 - if pr, err := url.Parse(echoCtx.Request().Referer()); err == nil && pr.Scheme != "" && pr.Host != "" { - siteURL = fmt.Sprintf("%s://%s", pr.Scheme, pr.Host) - } - } - - // Akismet - akismetKey := strings.TrimSpace(config.Instance.Moderator.AkismetKey) - if akismetKey != "" { - isPass, err := anti_spam.Akismet(&anti_spam.AkismetParams{ - Blog: siteURL, - - UserIP: echoCtx.RealIP(), - UserAgent: echoCtx.Request().UserAgent(), - - CommentType: "comment", - CommentAuthor: user.Name, - CommentAuthorEmail: user.Email, - CommentContent: c.Content, - }, akismetKey) - - ApiCommonHandle("Akismet", isPass, err) - } - - // 腾讯云 - tencentConf := config.Instance.Moderator.Tencent - if tencentConf.Enabled { - isPass, err := anti_spam.Tencent(anti_spam.TencentParams{ - SecretID: tencentConf.SecretID, - SecretKey: tencentConf.SecretKey, - Region: tencentConf.Region, - - Content: c.Content, - CommentID: c.ID, - UserID: c.UserID, - UserIP: c.IP, - UserName: user.Name, - }) - - ApiCommonHandle("腾讯云", isPass, err) - } - - // 阿里云 - aliyunConf := config.Instance.Moderator.Aliyun - if aliyunConf.Enabled { - isPass, err := anti_spam.Aliyun(anti_spam.AliyunParams{ - AccessKeyID: aliyunConf.AccessKeyID, - AccessKeySecret: aliyunConf.AccessKeySecret, - Region: aliyunConf.Region, - - Content: c.Content, - CommentID: c.ID, - }) - - ApiCommonHandle("阿里云", isPass, err) - } - - // 关键字过滤 - keywordsConf := config.Instance.Moderator.Keywords - if keywordsConf.Enabled { - // 懒加载,初始化 - if AntiSpamReplaceKeywords == nil { - AntiSpamReplaceKeywords = &[]string{} - // 加载文件 - for _, f := range keywordsConf.Files { - buf, err := ioutil.ReadFile(f) - if err != nil { - logrus.Error("关键词词库文件 " + f + " 加载失败") - } else { - fileContent := string(buf) - *AntiSpamReplaceKeywords = append(*AntiSpamReplaceKeywords, lib.RemoveBlankStrings(lib.SplitAndTrimSpace(fileContent, keywordsConf.FileSep))...) - } - } - } - - // 关键词过滤 - handleContent := c.Content - replaced := false - for _, keyword := range *AntiSpamReplaceKeywords { - if strings.Contains(handleContent, keyword) { - if (keywordsConf.Pending) { - BlockCommentBy("关键词") - break - } - - if (keywordsConf.ReplacTo != "") { - handleContent = strings.Replace(handleContent, keyword, strings.Repeat(keywordsConf.ReplacTo, len(keyword)), -1) - replaced = true - } - } - } - - if (!keywordsConf.Pending && replaced && keywordsConf.ReplacTo != "") { - logrus.Info(fmt.Sprintf("[垃圾拦截] 关键词替换评论 ID=%d 原始内容=%s 替换内容=%s", c.ID, strconv.Quote(c.Content), strconv.Quote(handleContent))) - - // 保存评论 - c.Content = handleContent - lib.DB.Save(c) - } - } -} - func (c *Comment) ToArtran() Artran { user := c.FetchUser() page := c.FetchPage() diff --git a/model/notify_launcher/init.go b/model/notify_launcher/init.go new file mode 100644 index 000000000..4e1daeaad --- /dev/null +++ b/model/notify_launcher/init.go @@ -0,0 +1,51 @@ +package notify_launcher + +import ( + "context" + + "github.com/ArtalkJS/ArtalkGo/config" + "github.com/ArtalkJS/ArtalkGo/lib/email" + "github.com/nikoksr/notify" + "github.com/nikoksr/notify/service/dingding" + "github.com/nikoksr/notify/service/line" + "github.com/nikoksr/notify/service/slack" + "github.com/nikoksr/notify/service/telegram" +) + +var NotifyCtx = context.Background() + +func Init() { + // 初始化邮件队列 + email.InitQueue() + + // Telegram + tgConf := config.Instance.Notify.Telegram + if tgConf.Enabled { + telegramService, _ := telegram.New(tgConf.ApiToken) + telegramService.AddReceivers(tgConf.Receivers...) + notify.UseServices(telegramService) + } + + // 钉钉 + dingTalkConf := config.Instance.Notify.DingTalk + if dingTalkConf.Enabled { + dingTalkService := dingding.New(&dingding.Config{Token: dingTalkConf.Token, Secret: dingTalkConf.Secret}) + notify.UseServices(dingTalkService) + } + + // Slack + slackConf := config.Instance.Notify.Slack + if slackConf.Enabled { + slackService := slack.New(slackConf.OauthToken) + slackService.AddReceivers(slackConf.Receivers...) + notify.UseServices(slackService) + } + + // LINE + LINEConf := config.Instance.Notify.LINE + if LINEConf.Enabled { + lineService, _ := line.New(config.Instance.Notify.LINE.ChannelSecret, config.Instance.Notify.LINE.ChannelAccessToken) + lineService.AddReceivers(LINEConf.Receivers...) + notify.UseServices(lineService) + } +} diff --git a/model/notify_launcher/notify_launcher.go b/model/notify_launcher/notify_launcher.go new file mode 100644 index 000000000..ff4b4df32 --- /dev/null +++ b/model/notify_launcher/notify_launcher.go @@ -0,0 +1,144 @@ +package notify_launcher + +import ( + "fmt" + "net/http" + "net/url" + "strconv" + "strings" + + "github.com/ArtalkJS/ArtalkGo/config" + "github.com/ArtalkJS/ArtalkGo/lib" + "github.com/ArtalkJS/ArtalkGo/lib/email" + "github.com/ArtalkJS/ArtalkGo/model" + libNotify "github.com/nikoksr/notify" + + "github.com/sirupsen/logrus" +) + +// 通知发送 (from comment to parentComment) +func SendNotify(comment *model.Comment, pComment *model.Comment) { + // 自己回复自己,不提醒 + if comment.UserID == pComment.UserID { + return + } + + isRootComment := pComment.IsEmpty() + + if !isRootComment { + // ============== + // 回复对方 + // ============== + if !comment.IsPending { // 待审状态评论禁止回复对方 + notify := model.FindCreateNotify(pComment.UserID, comment.ID) + notify.Comment = *comment + notify.SetInitial() + + // 邮件通知 + email.AsyncSend(¬ify) + } + } else { + // ============== + // 回复管理员 + // ============== + // TODO: 增加用户的站点隔离,指定管理员分配网站 + for _, admin := range model.GetAllAdmins() { + // 管理员自己回复自己,不提醒 + if comment.UserID == admin.ID { + continue + } + + // 管理员评论不回复给其他管理员 + if model.IsAdminUser(comment.UserID) { + continue + } + + notify := model.FindCreateNotify(admin.ID, comment.ID) + notify.Comment = *comment + notify.SetInitial() + + // 发送邮件给管理员 + email.AsyncSendToAdmin(¬ify, &admin) + } + } + + // 管理员多元通知 + AdminNotify(comment, pComment) +} + +func AdminNotify(comment *model.Comment, pComment *model.Comment) { + // 忽略来自管理员的评论 + coUser := comment.FetchUser() + if coUser.IsAdmin { + return + } + + isRootComment := pComment.IsEmpty() + + // 如果不是 root 评论 且 回复目标不是管理员,直接忽略 + if !isRootComment && !pComment.FetchUser().IsAdmin { + return + } + + // 评论内容文字截断 + coContent := lib.TruncateString(comment.Content, 280) + if len([]rune(coContent)) > 280 { + coContent = coContent + "..." + } + + // 通知消息 + title := fmt.Sprintf("来自 @%s 的回复", coUser.Name) + if comment.IsPending { + title += " [待审状态]" + } + + msg := fmt.Sprintf("%s\n\n%s", coContent, comment.GetLinkToReply()) + + // 使用 Notify 库发送 + go func() { + _ = libNotify.Send(NotifyCtx, title, msg) + }() + + // 飞书 + go func() { + SendLark(title + "\n\n" + msg) + }() + + // Bark + go func() { + SendBark(title, msg) + }() +} + +// 飞书发送 +func SendLark(msg string) { + larkConf := config.Instance.Notify.Lark + if !larkConf.Enabled { + return + } + + sendData := fmt.Sprintf(`{"msg_type":"text","content":{"text":%s}}`, strconv.Quote(msg)) + result, err := http.Post(larkConf.WebhookURL, "application/json", strings.NewReader(sendData)) + if err != nil { + logrus.Error("[飞书]", " 消息发送失败:", err) + return + } + + defer result.Body.Close() +} + +// Bark 发送 +func SendBark(title string, msg string) { + barkConf := config.Instance.Notify.Bark + if !barkConf.Enabled { + return + } + + result, err := http.Get(fmt.Sprintf("%s/%s/%s", strings.TrimSuffix(barkConf.Server, "/"), url.QueryEscape(title), url.QueryEscape(msg))) + if err != nil { + logrus.Error("[Bark]", " 消息发送失败:", err) + return + } + + defer result.Body.Close() +} diff --git a/model/query.go b/model/query.go index 6edf00b2b..aa4f38345 100644 --- a/model/query.go +++ b/model/query.go @@ -2,6 +2,7 @@ package model import ( "encoding/json" + "strings" "github.com/ArtalkJS/ArtalkGo/lib" "github.com/eko/gocache/v2/store" @@ -66,12 +67,6 @@ func StoreCache(name string, srcStruct interface{}) error { return nil } -func IsAdminUser(name string, email string) bool { - var user User - lib.DB.Where("LOWER(name) = LOWER(?) AND LOWER(email) = LOWER(?)", name, email).First(&user) - return !user.IsEmpty() && user.IsAdmin -} - func UpdateComment(comment *Comment) error { err := lib.DB.Save(comment).Error if err != nil { @@ -262,10 +257,17 @@ func FindPV(pageKey string, siteName string) PV { return pv } +//#region 管理员账号检测 +var allAdmins *[]User = nil + func GetAllAdmins() []User { - var admins []User - lib.DB.Where(&User{IsAdmin: true}).Find(&admins) - return admins + if allAdmins == nil { + var admins []User + lib.DB.Where(&User{IsAdmin: true}).Find(&admins) + allAdmins = &admins + } + + return *allAdmins } func GetAllAdminIDs() []uint { @@ -276,3 +278,29 @@ func GetAllAdminIDs() []uint { } return ids } + +func IsAdminUser(userID uint) bool { + admins := GetAllAdmins() + for _, admin := range admins { + if admin.ID == userID { + return true + } + } + + return false +} + +func IsAdminUserByNameEmail(name string, email string) bool { + admins := GetAllAdmins() + for _, admin := range admins { + // Name 和 Email 都匹配才是管理员 + if strings.EqualFold(admin.Name, name) && + strings.EqualFold(admin.Email, email) { + return true + } + } + + return false +} + +//#endregion From b9cbe4e955c590c663647c6bd7cd5ecd7605f847 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Sat, 16 Apr 2022 16:37:16 +0800 Subject: [PATCH 155/349] feat(geetest): Access geetest API Signed-off-by: qwqcode --- artalk-go.example.yml | 4 ++ config/config.go | 15 ++++-- frontend/captcha-page/geetest.html | 41 +++++++++++++++ lib/captcha/geetest.go | 84 ++++++++++++++++++++++++++++++ 4 files changed, 140 insertions(+), 4 deletions(-) create mode 100644 frontend/captcha-page/geetest.html create mode 100644 lib/captcha/geetest.go diff --git a/artalk-go.example.yml b/artalk-go.example.yml index 869864281..97f1a96e9 100644 --- a/artalk-go.example.yml +++ b/artalk-go.example.yml @@ -83,6 +83,10 @@ captcha: # ↓ 在 {comment_timeout} 秒内,操作次数超过 {comment_limit} 次激活验证码 action_timeout: 60 action_limit: 3 + geetest: # https://www.geetest.com + enabled: false + captcha_id: "" + captcha_key: "" # 邮件通知 email: diff --git a/config/config.go b/config/config.go index 83544f25c..dccf95d1c 100644 --- a/config/config.go +++ b/config/config.go @@ -94,10 +94,17 @@ type KeyWordsAntispamConf struct { } type CaptchaConf struct { - Enabled bool `mapstructure:"enabled" json:"enabled"` - Always bool `mapstructure:"always" json:"always"` - ActionTimeout int `mapstructure:"action_timeout" json:"action_timeout"` - ActionLimit int `mapstructure:"action_limit" json:"action_limit"` + Enabled bool `mapstructure:"enabled" json:"enabled"` + Always bool `mapstructure:"always" json:"always"` + ActionTimeout int `mapstructure:"action_timeout" json:"action_timeout"` + ActionLimit int `mapstructure:"action_limit" json:"action_limit"` + Geetest GeetestConf `mapstructure:"geetest" json:"geetest"` +} + +type GeetestConf struct { + Enabled bool `mapstructure:"enabled" json:"enabled"` + CaptchaID string `mapstructure:"captcha_id" json:"captcha_id"` + CaptchaKey string `mapstructure:"captcha_key" json:"captcha_key"` } type EmailConf struct { diff --git a/frontend/captcha-page/geetest.html b/frontend/captcha-page/geetest.html new file mode 100644 index 000000000..5d624600b --- /dev/null +++ b/frontend/captcha-page/geetest.html @@ -0,0 +1,41 @@ + + + + + + + Geetest + + + + +
+ + + + diff --git a/lib/captcha/geetest.go b/lib/captcha/geetest.go new file mode 100644 index 000000000..574fe8078 --- /dev/null +++ b/lib/captcha/geetest.go @@ -0,0 +1,84 @@ +package captcha + +import ( + "crypto/hmac" + "crypto/sha256" + "encoding/hex" + "encoding/json" + "errors" + "io/ioutil" + "net/http" + "net/url" + "time" + + "github.com/ArtalkJS/ArtalkGo/config" + "github.com/tidwall/gjson" +) + +// geetest 服务地址 +const GEETEST_API_SERVER string = "http://gcaptcha4.geetest.com" + +// hmac-sha256 加密: CAPTCHA_KEY,lot_number +func hmac_encode(key string, data string) string { + mac := hmac.New(sha256.New, []byte(key)) + mac.Write([]byte(data)) + return hex.EncodeToString(mac.Sum(nil)) +} + +type GeetestParams struct { + CaptchaID string `json:"captcha_id"` + LotNumber string `json:"lot_number"` + PassToken string `json:"pass_token"` + GenTime string `json:"gen_time"` + CaptchaOutput string `json:"captcha_output"` +} + +func GeetestCheck(paramsJSON string) (isPass bool, reason string, err error) { + var p GeetestParams + err = json.Unmarshal([]byte(paramsJSON), &p) + if err != nil { + return false, "", errors.New("Reqest params json parse err: " + err.Error()) + } + + // 生成签名 + signToken := hmac_encode(config.Instance.Captcha.Geetest.CaptchaKey, p.LotNumber) + + // 向极验转发前端数据 + sign_token 签名 + form_data := make(url.Values) + form_data["lot_number"] = []string{p.LotNumber} + form_data["captcha_output"] = []string{p.CaptchaOutput} + form_data["pass_token"] = []string{p.PassToken} + form_data["gen_time"] = []string{p.GenTime} + form_data["sign_token"] = []string{signToken} + + // 发起 POST 请求 + url := GEETEST_API_SERVER + "/validate" + "?captcha_id=" + config.Instance.Captcha.Geetest.CaptchaID + cli := http.Client{Timeout: time.Second * 5} // 5s 超时 + resp, err := cli.PostForm(url, form_data) + if err != nil || resp.StatusCode != 200 { + return false, "", errors.New("服务接口异常: " + err.Error()) + } + + // 处理响应结果 + resJsonBuf, _ := ioutil.ReadAll(resp.Body) + resJson := string(resJsonBuf) + + gResult := gjson.Get(resJson, "result") + if !gResult.Exists() { + return false, "", errors.New("响应结果不符合预期: " + resJson) + } + result := gResult.String() + + if result == "success" { + // 验证成功 + return true, "", nil + } else { + // 验证失败 + gReason := gjson.Get(resJson, "reason") + if gReason.Exists() { + reason = gReason.String() + } + + return false, reason, nil + } +} From 14661ed00b0bdbe346b8ea577c028e4c71a256a0 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Sat, 16 Apr 2022 18:38:41 +0800 Subject: [PATCH 156/349] feat(geetest): Provide geetest check API for frontend. Signed-off-by: qwqcode --- http/a_http.go | 2 + http/api_captcha.go | 118 +++++++++++++++--- http/permission.go | 49 ++++++-- lib/captcha/geetest.go | 6 +- .../captcha/pages}/geetest.html | 20 ++- makefile | 2 +- 6 files changed, 158 insertions(+), 39 deletions(-) rename {frontend/captcha-page => lib/captcha/pages}/geetest.html (56%) diff --git a/http/a_http.go b/http/a_http.go index 317d3d6c1..d07c5cc2e 100644 --- a/http/a_http.go +++ b/http/a_http.go @@ -107,7 +107,9 @@ func InitRoute(e *echo.Echo) { // api/captcha ca := api.Group("/captcha") ca.GET("/refresh", ActionCaptchaGet) + ca.GET("/get", ActionCaptchaGet) ca.GET("/check", ActionCaptchaCheck) + ca.GET("/ping", ActionCaptchaPing) // api/admin admin := api.Group("/admin", middleware.JWTWithConfig(CommonJwtConfig)) // use jwt diff --git a/http/api_captcha.go b/http/api_captcha.go index 46fc00acc..70211da93 100644 --- a/http/api_captcha.go +++ b/http/api_captcha.go @@ -4,27 +4,64 @@ import ( "bytes" "encoding/base64" "image/color" + "io/ioutil" + "net/http" "strings" + "text/template" "time" + "github.com/ArtalkJS/ArtalkGo/config" "github.com/ArtalkJS/ArtalkGo/lib" + "github.com/ArtalkJS/ArtalkGo/lib/captcha" + "github.com/ArtalkJS/ArtalkGo/pkged" "github.com/eko/gocache/v2/store" "github.com/labstack/echo/v4" - "github.com/steambap/captcha" + "github.com/sirupsen/logrus" + imgCaptcha "github.com/steambap/captcha" ) var ( CaptchaExpiration = 5 * time.Minute // 验证码 5 分钟内有效 ) +// 获取当前状态,是否需要验证 +func ActionCaptchaPing(c echo.Context) error { + if IsReqNeedCaptchaCheck(c) { + return RespData(c, Map{"need_captcha": true}) + } else { + return RespData(c, Map{"need_captcha": false}) + } +} + +// 获取验证码 func ActionCaptchaGet(c echo.Context) error { ip := c.RealIP() + // =========== + // Geetest + // =========== + if config.Instance.Captcha.Geetest.Enabled { + pageFile, _ := pkged.Open("/lib/captcha/pages/geetest.html") + buf, _ := ioutil.ReadAll(pageFile) + + var page bytes.Buffer + + t := template.New("") + t.Parse(string(buf)) + t.Execute(&page, map[string]interface{}{"gt_id": config.Instance.Captcha.Geetest.CaptchaID}) + + return c.HTML(http.StatusOK, page.String()) + } + + // =========== + // 图片验证码 + // =========== return RespData(c, Map{ - "img_data": GetNewCaptchaImageBase64(ip), + "img_data": GetNewImageCaptchaBase64(ip), }) } +// 验证 func ActionCaptchaCheck(c echo.Context) error { ip := c.RealIP() @@ -33,27 +70,66 @@ func ActionCaptchaCheck(c echo.Context) error { return RespError(c, "param `value` is required") } - if strings.ToLower(inputVal) == GetCaptchaRealCode(ip) { - // 验证码正确 - ResetActionRecord(c) // 重置操作记录 - DisposeCaptcha(ip) // 销毁验证码 - SetCaptchaIsChecked(ip, true) // 记录该 IP 已经成功验证 + // =========== + // Geetest + // =========== + if config.Instance.Captcha.Geetest.Enabled { + isPass, reason, err := captcha.GeetestCheck(inputVal) + if err != nil { + logrus.Error("[Geetest] 验证发生错误 ", err) + return RespError(c, "Geetest API 错误") + } + + if isPass { + // 验证成功 + onCaptchaPass(c) + return RespSuccess(c) + } else { + // 验证失败 + onCaptchaFail(c) + return RespError(c, "验证失败", Map{ + "reason": reason, + }) + } + } + // =========== + // 图片验证码 + // =========== + isPass := strings.ToLower(inputVal) == GetImageCaptchaRealCode(ip) + if isPass { + // 验证码正确 + DisposeImageCaptcha(ip) // 销毁图片验证码 + onCaptchaPass(c) return RespSuccess(c) } else { // 验证码错误 - RecordAction(c) // 记录操作 - DisposeCaptcha(ip) // 销毁验证码 - SetCaptchaIsChecked(ip, false) // 记录该 IP 验证码验证失败 - + DisposeImageCaptcha(ip) + onCaptchaFail(c) return RespError(c, "验证码错误", Map{ - "img_data": GetNewCaptchaImageBase64(ip), + "img_data": GetNewImageCaptchaBase64(ip), }) } } -// 获取 IP 验证码正确的值 -func GetCaptchaRealCode(ip string) string { +// 验证成功操作 +func onCaptchaPass(c echo.Context) { + ip := c.RealIP() + ResetActionRecord(c) // 重置操作记录 + + SetCaptchaIsChecked(ip, true) // 记录该 IP 已经成功验证 +} + +// 验证失败操作 +func onCaptchaFail(c echo.Context) { + ip := c.RealIP() + RecordAction(c) // 记录操作 + SetCaptchaIsChecked(ip, false) // 记录该 IP 验证码验证失败 +} + +//#region 图片验证码 +// 获取对应 IP 图片验证码正确的值 +func GetImageCaptchaRealCode(ip string) string { realVal := "" if val, err := lib.CACHE.Get(lib.Ctx, "captcha:"+ip); err == nil { realVal = string(val.([]byte)) @@ -62,10 +138,10 @@ func GetCaptchaRealCode(ip string) string { } // 获取新验证码 base64 格式图片 -func GetNewCaptchaImageBase64(ip string) string { +func GetNewImageCaptchaBase64(ip string) string { // generate a image pngBuffer := bytes.NewBuffer([]byte{}) - data, _ := captcha.New(160, 40, func(o *captcha.Options) { + data, _ := imgCaptcha.New(160, 40, func(o *imgCaptcha.Options) { o.FontScale = 1 o.CurveNumber = 2 o.FontDPI = 85.0 @@ -81,18 +157,20 @@ func GetNewCaptchaImageBase64(ip string) string { return base64 } -// 销毁验证码 -func DisposeCaptcha(ip string) { +// 销毁图片验证码 +func DisposeImageCaptcha(ip string) { lib.CACHE.Delete(lib.Ctx, "captcha:"+ip) } -// 获取 IP 是否验证码检测通过,已经有一次 +//#endregion + +// 获取 IP 是否验证通过,已经有一次 (for 总是需要验证码的选项) func GetCaptchaIsChecked(ip string) bool { val, err := lib.CACHE.Get(lib.Ctx, "captcha-checked:"+ip) return err == nil && string(val.([]byte)) == "1" } -// 设置该 IP 验证码成功验证,已经有一次 +// 设置该 IP 通过验证,已经有一次 (for 总是需要验证码的选项) func SetCaptchaIsChecked(ip string, isChecked bool) { val := "0" if isChecked { diff --git a/http/permission.go b/http/permission.go index 1ab2603cc..48b609130 100644 --- a/http/permission.go +++ b/http/permission.go @@ -44,37 +44,60 @@ func ActionLimitMiddleware(conf ActionLimitConf) echo.MiddlewareFunc { } } if !pathInList { + // 不启用的 path 直接放行 return next(c) } - // 管理员直接忽略 - if CheckIsAdminReq(c) { - return next(c) - } + // 是否需要验证 + if IsReqNeedCaptchaCheck(c) { + respData := Map{ + "need_captcha": true, + } - // 操作限制,响应需要验证码 - if IsActionOverLimit(c) { - if config.Instance.Debug { - logrus.Debug("[操作限制] 次数: ", getActionCount(c), ", 最后时间:", getActionLastTime(c)) + if config.Instance.Captcha.Geetest.Enabled { + // iframe 验证模式 + respData["iframe"] = true + // 前端新版不会再用到 img_data,给旧版响应 ArtalkFrontent out-of-date 图片 + respData["img_data"] = "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 160 40'%3E%3Cdefs%3E%3Cstyle%3E.a%7Bfill:%23328ce6%3B%7D.b%7Bfont-size:12px%3Bfill:%23fff%3Bfont-family:sans-serif%3B%7D%3C/style%3E%3C/defs%3E%3Crect class='a' width='160' height='40'/%3E%3Ctext class='b' transform='translate(18.37 16.67)'%3EArtalk Frontend%3Ctspan x='0' y='14.4'%3EOut-Of-Date.%3C/tspan%3E%3C/text%3E%3C/svg%3E" + } else { + respData["img_data"] = GetNewImageCaptchaBase64(c.RealIP()) } - return RespError(c, "需要验证码", Map{ - "need_captcha": true, - "img_data": GetNewCaptchaImageBase64(c.RealIP()), - }) + + return RespError(c, "需要验证码", respData) } + // 放行 return next(c) } } } +// 请求是否需要验证码 +func IsReqNeedCaptchaCheck(c echo.Context) bool { + // 管理员直接忽略 + if CheckIsAdminReq(c) { + return false + } + + // 操作超过限制,需要验证码 + if IsActionOverLimit(c) { + if config.Instance.Debug { + logrus.Debug("[操作限制] 次数: ", getActionCount(c), ", 最后时间:", getActionLastTime(c)) + } + + return true + } + + return false +} + // 操作是否超过限制 func IsActionOverLimit(c echo.Context) bool { userIP := c.RealIP() // 总是需要验证码 if config.Instance.Captcha.Always { if GetCaptchaIsChecked(userIP) { // 只有验证码成功才放行 - SetCaptchaIsChecked(userIP, false) // 总是需要验证码,只允许放行一次 + SetCaptchaIsChecked(userIP, false) // 总是需要验证码,放行一次后再次需要验证码 return false } diff --git a/lib/captcha/geetest.go b/lib/captcha/geetest.go index 574fe8078..35d5f350a 100644 --- a/lib/captcha/geetest.go +++ b/lib/captcha/geetest.go @@ -34,6 +34,8 @@ type GeetestParams struct { } func GeetestCheck(paramsJSON string) (isPass bool, reason string, err error) { + geetestConf := config.Instance.Captcha.Geetest + var p GeetestParams err = json.Unmarshal([]byte(paramsJSON), &p) if err != nil { @@ -41,7 +43,7 @@ func GeetestCheck(paramsJSON string) (isPass bool, reason string, err error) { } // 生成签名 - signToken := hmac_encode(config.Instance.Captcha.Geetest.CaptchaKey, p.LotNumber) + signToken := hmac_encode(geetestConf.CaptchaKey, p.LotNumber) // 向极验转发前端数据 + sign_token 签名 form_data := make(url.Values) @@ -52,7 +54,7 @@ func GeetestCheck(paramsJSON string) (isPass bool, reason string, err error) { form_data["sign_token"] = []string{signToken} // 发起 POST 请求 - url := GEETEST_API_SERVER + "/validate" + "?captcha_id=" + config.Instance.Captcha.Geetest.CaptchaID + url := GEETEST_API_SERVER + "/validate" + "?captcha_id=" + geetestConf.CaptchaID cli := http.Client{Timeout: time.Second * 5} // 5s 超时 resp, err := cli.PostForm(url, form_data) if err != nil || resp.StatusCode != 200 { diff --git a/frontend/captcha-page/geetest.html b/lib/captcha/pages/geetest.html similarity index 56% rename from frontend/captcha-page/geetest.html rename to lib/captcha/pages/geetest.html index 5d624600b..d28b18770 100644 --- a/frontend/captcha-page/geetest.html +++ b/lib/captcha/pages/geetest.html @@ -18,7 +18,7 @@ var params = new URLSearchParams(document.location.search) var captchaId = params.get('captcha_id') - var captchaId = "647f5ed2ed8acb4be36784e01556bb71" // gt_id + var captchaId = "{{.gt_id}}" // gt_id // @link https://docs.geetest.com/gt4/apirefer/api/web initGeetest4({ @@ -30,8 +30,22 @@ gt.appendTo("#captcha") .onSuccess(function (e) { var result = gt.getValidate(); - - console.log("[验证结果] ", result) + console.log("[极验验证结果] ", result) + fetch("./check?value="+encodeURIComponent(JSON.stringify(result))) + .then(function (resp) { + resp.json().then(function (json) { + if (json.success) { + console.log("验证成功:" + json) + } + }).catch(function (err) { + console.error(err) + alert("验证失败:" + err) + }) + }) + .catch(function (err) { + console.error(err) + alert("后端 API 请求失败:" + err) + }); }) gt.showCaptcha(); diff --git a/makefile b/makefile index ba2ad1cd4..72ff5e51e 100644 --- a/makefile +++ b/makefile @@ -25,7 +25,7 @@ build-frontend: .PHONY: update update: - pkger -include /frontend -include /email-tpl -include /artalk-go.example.yml -o pkged + pkger -include /frontend -include /email-tpl -include /lib/captcha/pages -include /artalk-go.example.yml -o pkged .PHONY: run run: all From c1279b3089993c9389532285da1aa5d0e039b0bf Mon Sep 17 00:00:00 2001 From: qwqcode Date: Sat, 16 Apr 2022 23:30:29 +0800 Subject: [PATCH 157/349] fix(captcha): Fix lots of bugs. Signed-off-by: qwqcode --- artalk-go.example.yml | 6 ++-- cmd/core.go | 19 ++++++++++ config/config.go | 5 +-- http/a_http.go | 2 +- http/api_captcha.go | 29 ++++++++-------- http/api_main_add.go | 12 +++++-- http/api_main_vote.go | 4 +++ http/permission.go | 80 ++++++++++++++++++++++++++----------------- 8 files changed, 103 insertions(+), 54 deletions(-) diff --git a/artalk-go.example.yml b/artalk-go.example.yml index 97f1a96e9..79783bd3e 100644 --- a/artalk-go.example.yml +++ b/artalk-go.example.yml @@ -80,9 +80,9 @@ moderator: captcha: enabled: true # 总开关 always: false # 总是需要验证码 - # ↓ 在 {comment_timeout} 秒内,操作次数超过 {comment_limit} 次激活验证码 - action_timeout: 60 - action_limit: 3 + action_limit: 3 # 激活验证码所需操作次数 + action_reset: 60 # 重置操作计数器超时 (单位:s, 设为 -1 不重置) + # Geetest 极验 geetest: # https://www.geetest.com enabled: false captcha_id: "" diff --git a/cmd/core.go b/cmd/core.go index 181f93160..d8b235c1b 100644 --- a/cmd/core.go +++ b/cmd/core.go @@ -41,6 +41,25 @@ func initConfig() { } denverLoc, _ := time.LoadLocation(config.Instance.TimeZone) time.Local = denverLoc + + // 配置文件 alias 处理 + if config.Instance.Captcha.ActionLimit == 0 { + config.Instance.Captcha.Always = true + } + + // 检查废弃需更新配置 + if config.Instance.Captcha.ActionTimeout != 0 { + logrus.Warn("captcha.action_timeout 配置项已废弃,请使用 captcha.action_reset 代替") + if config.Instance.Captcha.ActionReset == 0 { + config.Instance.Captcha.ActionReset = config.Instance.Captcha.ActionTimeout + } + } + if len(config.Instance.AllowOrigins) != 0 { + logrus.Warn("allow_origins 配置项已废弃,请使用 trusted_domains 代替") + if len(config.Instance.TrustedDomains) == 0 { + config.Instance.TrustedDomains = config.Instance.AllowOrigins + } + } } // 2. 初始化日志 diff --git a/config/config.go b/config/config.go index dccf95d1c..9604c0b1a 100644 --- a/config/config.go +++ b/config/config.go @@ -21,7 +21,7 @@ type Config struct { Port int `mapstructure:"port" json:"port"` // HTTP Server 监听 Port DB DBConf `mapstructure:"db" json:"db"` // 数据文件 Log LogConf `mapstructure:"log" json:"log"` // 日志文件 - AllowOrigins []string `mapstructure:"allow_origins" json:"allow_origins"` // 允许跨域访问的域名 + AllowOrigins []string `mapstructure:"allow_origins" json:"allow_origins"` // @deprecated 已废弃 (请使用 TrustedDomains) TrustedDomains []string `mapstructure:"trusted_domains" json:"trusted_domains"` // 可信任的域名 (新) SSL SSLConf `mapstructure:"ssl" json:"ssl"` // SSL SiteDefault string `mapstructure:"site_default" json:"site_default"` // 默认站点名(当请求无指定 site_name 时使用) @@ -96,7 +96,8 @@ type KeyWordsAntispamConf struct { type CaptchaConf struct { Enabled bool `mapstructure:"enabled" json:"enabled"` Always bool `mapstructure:"always" json:"always"` - ActionTimeout int `mapstructure:"action_timeout" json:"action_timeout"` + ActionTimeout int `mapstructure:"action_timeout" json:"action_timeout"` // @deprecated 已废弃 (请使用 ActionReset) + ActionReset int `mapstructure:"action_reset" json:"action_reset"` ActionLimit int `mapstructure:"action_limit" json:"action_limit"` Geetest GeetestConf `mapstructure:"geetest" json:"geetest"` } diff --git a/http/a_http.go b/http/a_http.go index d07c5cc2e..7759c457b 100644 --- a/http/a_http.go +++ b/http/a_http.go @@ -109,7 +109,7 @@ func InitRoute(e *echo.Echo) { ca.GET("/refresh", ActionCaptchaGet) ca.GET("/get", ActionCaptchaGet) ca.GET("/check", ActionCaptchaCheck) - ca.GET("/ping", ActionCaptchaPing) + ca.GET("/status", ActionCaptchaStatus) // api/admin admin := api.Group("/admin", middleware.JWTWithConfig(CommonJwtConfig)) // use jwt diff --git a/http/api_captcha.go b/http/api_captcha.go index 70211da93..893a69f8d 100644 --- a/http/api_captcha.go +++ b/http/api_captcha.go @@ -25,11 +25,11 @@ var ( ) // 获取当前状态,是否需要验证 -func ActionCaptchaPing(c echo.Context) error { +func ActionCaptchaStatus(c echo.Context) error { if IsReqNeedCaptchaCheck(c) { - return RespData(c, Map{"need_captcha": true}) + return RespData(c, Map{"is_pass": false}) } else { - return RespData(c, Map{"need_captcha": false}) + return RespData(c, Map{"is_pass": true}) } } @@ -115,16 +115,17 @@ func ActionCaptchaCheck(c echo.Context) error { // 验证成功操作 func onCaptchaPass(c echo.Context) { ip := c.RealIP() - ResetActionRecord(c) // 重置操作记录 - SetCaptchaIsChecked(ip, true) // 记录该 IP 已经成功验证 + setActionCount(c, config.Instance.Captcha.ActionLimit-1) + SetAlwaysCaptchaMode_Pass(ip, true) // 允许 always mode pass } // 验证失败操作 func onCaptchaFail(c echo.Context) { ip := c.RealIP() - RecordAction(c) // 记录操作 - SetCaptchaIsChecked(ip, false) // 记录该 IP 验证码验证失败 + + RecordAction(c) // 记录操作 + SetAlwaysCaptchaMode_Pass(ip, false) // 取消 always mode pass } //#region 图片验证码 @@ -164,18 +165,18 @@ func DisposeImageCaptcha(ip string) { //#endregion -// 获取 IP 是否验证通过,已经有一次 (for 总是需要验证码的选项) -func GetCaptchaIsChecked(ip string) bool { - val, err := lib.CACHE.Get(lib.Ctx, "captcha-checked:"+ip) +// AlwaysMode 是否能 Pass (for 总是需要验证码的选项) +func GetAlwaysCaptchaMode_Pass(ip string) bool { + val, err := lib.CACHE.Get(lib.Ctx, "captcha-am-pass:"+ip) return err == nil && string(val.([]byte)) == "1" } -// 设置该 IP 通过验证,已经有一次 (for 总是需要验证码的选项) -func SetCaptchaIsChecked(ip string, isChecked bool) { +// 设置 AlwaysMode 允许 Pass (for 总是需要验证码的选项) +func SetAlwaysCaptchaMode_Pass(ip string, pass bool) { val := "0" - if isChecked { + if pass { val = "1" } - lib.CACHE.Set(lib.Ctx, "captcha-checked:"+ip, []byte(val), &store.Options{Expiration: CaptchaExpiration}) + lib.CACHE.Set(lib.Ctx, "captcha-am-pass:"+ip, []byte(val), &store.Options{Expiration: CaptchaExpiration}) } diff --git a/http/api_main_add.go b/http/api_main_add.go index f0add5554..48a47a61d 100644 --- a/http/api_main_add.go +++ b/http/api_main_add.go @@ -2,6 +2,7 @@ package http import ( "regexp" + "strings" "github.com/ArtalkJS/ArtalkGo/config" "github.com/ArtalkJS/ArtalkGo/lib" @@ -14,8 +15,8 @@ import ( ) type ParamsAdd struct { - Name string `mapstructure:"name" param:"required"` - Email string `mapstructure:"email" param:"required"` + Name string `mapstructure:"name"` + Email string `mapstructure:"email"` Link string `mapstructure:"link"` Content string `mapstructure:"content" param:"required"` Rid uint `mapstructure:"rid"` @@ -39,6 +40,13 @@ func ActionAdd(c echo.Context) error { return resp } + if strings.TrimSpace(p.Name) == "" { + return RespError(c, "昵称不能为空") + } + if strings.TrimSpace(p.Email) == "" { + return RespError(c, "邮箱不能为空") + } + if !lib.ValidateEmail(p.Email) { return RespError(c, "Invalid email") } diff --git a/http/api_main_vote.go b/http/api_main_vote.go index ac11eddc5..2f924ff6b 100644 --- a/http/api_main_vote.go +++ b/http/api_main_vote.go @@ -111,6 +111,8 @@ func ActionVote(c echo.Context) error { up, down := GetVoteNumUpDown(p.TargetID, voteTo) save(up, down) + RecordAction(c) + return RespData(c, Map{ "up": up, "down": down, @@ -123,6 +125,8 @@ func ActionVote(c echo.Context) error { up, down := GetVoteNumUpDown(p.TargetID, voteTo) save(up, down) + RecordAction(c) + return RespData(c, Map{ "up": up, "down": down, diff --git a/http/permission.go b/http/permission.go index 48b609130..b805a50d7 100644 --- a/http/permission.go +++ b/http/permission.go @@ -12,7 +12,6 @@ import ( "github.com/golang-jwt/jwt" "github.com/labstack/echo/v4" "github.com/labstack/echo/v4/middleware" - "github.com/sirupsen/logrus" ) var CommonJwtConfig middleware.JWTConfig @@ -48,8 +47,34 @@ func ActionLimitMiddleware(conf ActionLimitConf) echo.MiddlewareFunc { return next(c) } + // 管理员直接放行 + if CheckIsAdminReq(c) { + return next(c) + } + + userIP := c.RealIP() + isNeedCheck := IsReqNeedCaptchaCheck(c) + + // 总是需要验证码模式 + if config.Instance.Captcha.Always { + if GetAlwaysCaptchaMode_Pass(userIP) { + SetAlwaysCaptchaMode_Pass(userIP, false) // 总是需要验证码,放行一次后再次需要验证码 + isNeedCheck = false + } else { + isNeedCheck = true + } + } else { + // 超时模式:重置计数 + if config.Instance.Captcha.ActionReset != -1 { + if !IsActionInTimeFrame(c) { // 超时 + ResetActionRecord(c) // 重置计数 + isNeedCheck = false // 放行 + } + } + } + // 是否需要验证 - if IsReqNeedCaptchaCheck(c) { + if isNeedCheck { respData := Map{ "need_captcha": true, } @@ -74,47 +99,33 @@ func ActionLimitMiddleware(conf ActionLimitConf) echo.MiddlewareFunc { // 请求是否需要验证码 func IsReqNeedCaptchaCheck(c echo.Context) bool { + captchaConf := config.Instance.Captcha + // 管理员直接忽略 if CheckIsAdminReq(c) { return false } - // 操作超过限制,需要验证码 - if IsActionOverLimit(c) { - if config.Instance.Debug { - logrus.Debug("[操作限制] 次数: ", getActionCount(c), ", 最后时间:", getActionLastTime(c)) - } - - return true - } - - return false -} - -// 操作是否超过限制 -func IsActionOverLimit(c echo.Context) bool { - userIP := c.RealIP() - // 总是需要验证码 + // 总是需要验证码模式 if config.Instance.Captcha.Always { - if GetCaptchaIsChecked(userIP) { // 只有验证码成功才放行 - SetCaptchaIsChecked(userIP, false) // 总是需要验证码,放行一次后再次需要验证码 - return false - } - - return true + return !GetAlwaysCaptchaMode_Pass(c.RealIP()) } - // 一段时间内操作次数限制 - if time.Since(getActionLastTime(c)).Seconds() <= float64(config.Instance.Captcha.ActionTimeout) { // 在时间内 - if getActionCount(c) >= config.Instance.Captcha.ActionLimit { // 操作次数超过 - RecordAction(c) // 记录操作 - return true // 需要验证码 + // 不重置计数器模式 + if captchaConf.ActionReset == -1 { + if getActionCount(c) >= captchaConf.ActionLimit { // 只要操作次数超过 + return true // 就过限 + } else { + return false // 放行 } - } else { // 不在时间内,超时 - ResetActionRecord(c) // 重置操作记录 } - return false // 放行 + // 开启重置计数器功能的情况:在时间范围内,操作次数超过 + if IsActionInTimeFrame(c) && getActionCount(c) >= captchaConf.ActionLimit { + return true // 过限 + } else { + return false // 放行 + } } // 记录操作 @@ -131,6 +142,11 @@ func ResetActionRecord(c echo.Context) { lib.CACHE.Delete(lib.Ctx, "action-count:"+ip) } +// 操作计数是否应该被重置 +func IsActionInTimeFrame(c echo.Context) bool { + return time.Since(getActionLastTime(c)).Seconds() <= float64(config.Instance.Captcha.ActionReset) +} + // 修改最后操作时间 func updateActionLastTime(c echo.Context) { curtTime := fmt.Sprintf("%v", time.Now().Unix()) From a8faad7b177183623a216316fff81aec318e2e42 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Sun, 17 Apr 2022 00:19:04 +0800 Subject: [PATCH 158/349] fix(api_main_get): Msg center disable comment-pin. Signed-off-by: qwqcode --- http/api_main_get.go | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/http/api_main_get.go b/http/api_main_get.go index 1460ebb02..09c1e240f 100644 --- a/http/api_main_get.go +++ b/http/api_main_get.go @@ -309,6 +309,11 @@ func ViewOnlyAdmin(c echo.Context, p ParamsGet) func(db *gorm.DB) *gorm.DB { func PinnedCommentsScope(c echo.Context, p ParamsGet) func(db *gorm.DB) *gorm.DB { return func(db *gorm.DB) *gorm.DB { + if IsMsgCenter(p) { + // 通知中心关闭置顶 + return db + } + if p.Offset == 0 { return db } else { @@ -319,6 +324,11 @@ func PinnedCommentsScope(c echo.Context, p ParamsGet) func(db *gorm.DB) *gorm.DB } func pinnedCommentsFunction(c echo.Context, p ParamsGet, cookedComments *[]model.CookedComment) { + if IsMsgCenter(p) { + // 通知中心关闭置顶 + return + } + // 仅在分页的首页加入置顶评论 if p.Offset != 0 { return From ab9b9ec818dd5b3856e87cb864aecbc0386f301e Mon Sep 17 00:00:00 2001 From: qwqcode Date: Sun, 17 Apr 2022 00:28:12 +0800 Subject: [PATCH 159/349] feat(api): Get login status API Signed-off-by: qwqcode --- http/a_http.go | 1 + http/api_user_login.go | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/http/a_http.go b/http/a_http.go index 7759c457b..868906cce 100644 --- a/http/a_http.go +++ b/http/a_http.go @@ -92,6 +92,7 @@ func InitRoute(e *echo.Echo) { api.POST("/user-get", ActionUserGet) api.GET("/login", ActionLogin) api.POST("/login", ActionLogin) + api.GET("/login-status", ActionLoginStatus) api.POST("/mark-read", ActionMarkRead) api.POST("/vote", ActionVote) api.POST("/pv", ActionPV) diff --git a/http/api_user_login.go b/http/api_user_login.go index 0c8c41dfb..b1b0370ea 100644 --- a/http/api_user_login.go +++ b/http/api_user_login.go @@ -69,3 +69,10 @@ func HashPassword(password string) (string, error) { bytes, err := bcrypt.GenerateFromPassword([]byte(password), 14) return string(bytes), err } + +// 获取当前登录状态 +func ActionLoginStatus(c echo.Context) error { + return RespData(c, Map{ + "is_login": CheckIsAdminReq(c), + }) +} From 2a5e54f8cbdda2870008cc950f1c983025b2a4f4 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Sun, 17 Apr 2022 00:57:13 +0800 Subject: [PATCH 160/349] fix(limit-middleware): Precise match & fix disable captcha config. Signed-off-by: qwqcode --- http/a_http.go | 17 +++++++++++------ http/permission.go | 5 ++++- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/http/a_http.go b/http/a_http.go index 868906cce..8b800448b 100644 --- a/http/a_http.go +++ b/http/a_http.go @@ -51,7 +51,10 @@ func Run() { "/api/img-upload", }, } - e.Use(ActionLimitMiddleware(ActionLimitConf)) + + if config.Instance.Captcha.Enabled { + e.Use(ActionLimitMiddleware(ActionLimitConf)) + } CommonJwtConfig = middleware.JWTConfig{ Claims: &jwtCustomClaims{}, @@ -106,11 +109,13 @@ func InitRoute(e *echo.Echo) { e.Static(ImgUpload_RoutePath, config.Instance.ImgUpload.Path) // 静态可访问图片存放目录 // api/captcha - ca := api.Group("/captcha") - ca.GET("/refresh", ActionCaptchaGet) - ca.GET("/get", ActionCaptchaGet) - ca.GET("/check", ActionCaptchaCheck) - ca.GET("/status", ActionCaptchaStatus) + if config.Instance.Captcha.Enabled { + ca := api.Group("/captcha") + ca.GET("/refresh", ActionCaptchaGet) + ca.GET("/get", ActionCaptchaGet) + ca.GET("/check", ActionCaptchaCheck) + ca.GET("/status", ActionCaptchaStatus) + } // api/admin admin := api.Group("/admin", middleware.JWTWithConfig(CommonJwtConfig)) // use jwt diff --git a/http/permission.go b/http/permission.go index b805a50d7..d71660188 100644 --- a/http/permission.go +++ b/http/permission.go @@ -3,6 +3,7 @@ package http import ( "encoding/json" "fmt" + "path" "strconv" "strings" "time" @@ -34,10 +35,12 @@ type ActionLimitConf struct { func ActionLimitMiddleware(conf ActionLimitConf) echo.MiddlewareFunc { return func(next echo.HandlerFunc) echo.HandlerFunc { return func(c echo.Context) error { + // 关闭验证码功能 + // 路径是否启用操作限制 pathInList := false for _, p := range conf.ProtectPaths { - if strings.HasPrefix(c.Request().URL.Path, p) { + if path.Clean(c.Request().URL.Path) == path.Clean(p) { pathInList = true break } From 19e188b7f7cb7ec75877151f8ae9e6f2f968ba63 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Sun, 17 Apr 2022 01:18:09 +0800 Subject: [PATCH 161/349] feat(cmd): Add config cmd Signed-off-by: qwqcode --- cmd/root.go | 16 +++++++++++++++- http/a_http.go | 3 +-- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/cmd/root.go b/cmd/root.go index e8ad09d86..a75bb1b0c 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -1,8 +1,10 @@ package cmd import ( + "encoding/json" "fmt" + "github.com/ArtalkJS/ArtalkGo/config" "github.com/ArtalkJS/ArtalkGo/lib" "github.com/spf13/cobra" ) @@ -58,6 +60,18 @@ func init() { fmt.Println("ArtalkGo (" + Version + ")") }, } - rootCmd.AddCommand(versionCmd) + + // Config Command + configCmd := &cobra.Command{ + Use: "config", + Short: "输出配置信息", + Run: func(cmd *cobra.Command, args []string) { + loadCore() + buf, _ := json.MarshalIndent(config.Instance, "", " ") + fmt.Println(string(buf)) + }, + } + rootCmd.AddCommand(configCmd) + } diff --git a/http/a_http.go b/http/a_http.go index 8b800448b..e85067085 100644 --- a/http/a_http.go +++ b/http/a_http.go @@ -21,8 +21,7 @@ func Run() { // 跨域控制 allowOrigins := []string{} - allowOrigins = append(allowOrigins, config.Instance.AllowOrigins...) // 跨域独立配置 - for _, v := range config.Instance.TrustedDomains { // 可信域名配置 + for _, v := range config.Instance.TrustedDomains { // 可信域名配置 if !lib.ContainsStr(allowOrigins, v) { allowOrigins = append(allowOrigins, v) } From b2a780ebb50fc3c6e7283bf4d9497e9cb53c6ce8 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Sun, 17 Apr 2022 01:23:52 +0800 Subject: [PATCH 162/349] fix(api_version): Trim version prefix v char Signed-off-by: qwqcode --- http/resp.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/http/resp.go b/http/resp.go index a3dace575..090856f26 100644 --- a/http/resp.go +++ b/http/resp.go @@ -3,6 +3,7 @@ package http import ( "net/http" "strconv" + "strings" "github.com/ArtalkJS/ArtalkGo/config" "github.com/ArtalkJS/ArtalkGo/lib" @@ -93,9 +94,9 @@ func LogWithHttpInfo(c echo.Context) *logrus.Entry { func GetApiVersionDataMap() Map { return Map{ "app": "artalk-go", - "version": lib.Version, + "version": strings.TrimPrefix(lib.Version, "v"), "commit_hash": lib.CommitHash, - "fe_min_version": lib.FeMinVersion, + "fe_min_version": strings.TrimPrefix(lib.FeMinVersion, "v"), } } From 67358cad181c63f592b4ee0e231767800583fc4f Mon Sep 17 00:00:00 2001 From: qwqcode Date: Sun, 17 Apr 2022 01:35:58 +0800 Subject: [PATCH 163/349] docs: Update README.md Signed-off-by: qwqcode --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 0d1a5cb9e..94e76bd80 100644 --- a/README.md +++ b/README.md @@ -88,6 +88,9 @@ $ make docker-push - [x] 系统调用 sendmail - [x] 邮件多模板自定义 - [x] 用户已读标记 +- [x] 验证码 + - [x] 图片验证码 + - [x] [极验](https://www.geetest.com/)滑动验证码 - [x] 反垃圾 - [x] [Akismet](https://akismet.com/) - [x] [阿里云内容安全](https://help.aliyun.com/document_detail/28417.html) From c216e5a239a8100d946bd4cd896241c440c17f55 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Sun, 17 Apr 2022 01:48:33 +0800 Subject: [PATCH 164/349] feat(api): Modify some APIs method to post Signed-off-by: qwqcode --- http/a_http.go | 5 +++++ http/api_captcha.go | 11 ++++++++--- lib/captcha/pages/geetest.html | 11 ++++++++++- 3 files changed, 23 insertions(+), 4 deletions(-) diff --git a/http/a_http.go b/http/a_http.go index e85067085..00e58c631 100644 --- a/http/a_http.go +++ b/http/a_http.go @@ -95,6 +95,7 @@ func InitRoute(e *echo.Echo) { api.GET("/login", ActionLogin) api.POST("/login", ActionLogin) api.GET("/login-status", ActionLoginStatus) + api.POST("/login-status", ActionLoginStatus) api.POST("/mark-read", ActionMarkRead) api.POST("/vote", ActionVote) api.POST("/pv", ActionPV) @@ -111,9 +112,13 @@ func InitRoute(e *echo.Echo) { if config.Instance.Captcha.Enabled { ca := api.Group("/captcha") ca.GET("/refresh", ActionCaptchaGet) + ca.POST("/refresh", ActionCaptchaGet) ca.GET("/get", ActionCaptchaGet) + ca.POST("/get", ActionCaptchaGet) ca.GET("/check", ActionCaptchaCheck) + ca.POST("/check", ActionCaptchaCheck) ca.GET("/status", ActionCaptchaStatus) + ca.POST("/status", ActionCaptchaStatus) } // api/admin diff --git a/http/api_captcha.go b/http/api_captcha.go index 893a69f8d..e4383118a 100644 --- a/http/api_captcha.go +++ b/http/api_captcha.go @@ -61,14 +61,19 @@ func ActionCaptchaGet(c echo.Context) error { }) } +type ParamsCaptchaCheck struct { + Value string `mapstructure:"value" param:"required"` +} + // 验证 func ActionCaptchaCheck(c echo.Context) error { ip := c.RealIP() - inputVal := c.QueryParam("value") - if inputVal == "" { - return RespError(c, "param `value` is required") + var p ParamsCaptchaCheck + if isOK, resp := ParamsDecode(c, ParamsCaptchaCheck{}, &p); !isOK { + return resp } + inputVal := p.Value // =========== // Geetest diff --git a/lib/captcha/pages/geetest.html b/lib/captcha/pages/geetest.html index d28b18770..e728e3fa3 100644 --- a/lib/captcha/pages/geetest.html +++ b/lib/captcha/pages/geetest.html @@ -30,12 +30,21 @@ gt.appendTo("#captcha") .onSuccess(function (e) { var result = gt.getValidate(); + var form = new FormData() + form.append("value", JSON.stringify(result)) console.log("[极验验证结果] ", result) - fetch("./check?value="+encodeURIComponent(JSON.stringify(result))) + fetch("./check", { + method: 'POST', + body: form, + }) .then(function (resp) { resp.json().then(function (json) { if (json.success) { console.log("验证成功:" + json) + } else { + if (json.msg) { + alert("验证失败:" + json.msg) + } } }).catch(function (err) { console.error(err) From eb529ac941129ab563c313451b33158b28bb6100 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Sun, 17 Apr 2022 02:07:54 +0800 Subject: [PATCH 165/349] feat(version): Update Frontend min version to 2.2.1 Signed-off-by: qwqcode --- lib/version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/version.go b/lib/version.go index 3cf85bb9b..5ee42dc60 100644 --- a/lib/version.go +++ b/lib/version.go @@ -7,4 +7,4 @@ var ( ) // 前端最小要求版本号 -var FeMinVersion string = "2.1.9" +var FeMinVersion string = "2.2.1" From 19885c86d9b98f5e61d7e1b75af02a107dea937c Mon Sep 17 00:00:00 2001 From: qwqcode Date: Sun, 17 Apr 2022 02:18:53 +0800 Subject: [PATCH 166/349] docs: Update README.md Signed-off-by: qwqcode --- README.md | 84 ++----------------------------------------------------- 1 file changed, 3 insertions(+), 81 deletions(-) diff --git a/README.md b/README.md index 94e76bd80..4ba761d29 100644 --- a/README.md +++ b/README.md @@ -47,87 +47,9 @@ $ make docker-docker $ make docker-push ``` -## TODOs - -- [ ] 命令行管理 -- [x] 多站点支持 -- [x] 多数据库支持 -- [x] 评论获取分页 -- [x] 评论点赞投票 -- [x] 浏览量统计 -- [x] 评论分页加载 -- [x] 评论置顶 / 精华 -- [x] 评论排序 (热度 / 时间) -- [x] 通知中心 - - [x] 提及 - - [x] 全部 - - [x] 我的 - - [x] 待审 -- [x] 管理员控制台 - - [x] 评论 (增/删/改) - - [x] 页面 (增/删/改) - - [x] 站点 (增/删/改) - - [x] 数据分页 - - [ ] 配置 (GUI) -- [x] 数据导入 ([Artransfer](https://github.com/ArtalkJS/Artransfer)) - - [x] Artrans - - [x] Artalk v1 (PHP) - - [x] WordPress - - [x] Typecho - - [x] Valine - - [x] Disqus - - [x] Commento - - [x] Twikoo -- [x] 数据导出 -- [ ] 数据备份同步 -- [x] 邮件异步队列发送 -- [ ] 邮件队列持久化 -- [x] 邮件多种发送方式 - - [x] SMTP - - [x] 阿里云邮件 - - [x] 系统调用 sendmail -- [x] 邮件多模板自定义 -- [x] 用户已读标记 -- [x] 验证码 - - [x] 图片验证码 - - [x] [极验](https://www.geetest.com/)滑动验证码 -- [x] 反垃圾 - - [x] [Akismet](https://akismet.com/) - - [x] [阿里云内容安全](https://help.aliyun.com/document_detail/28417.html) - - [x] [腾讯云内容安全](https://cloud.tencent.com/document/product/1124/64508) - - [x] 关键字过滤 -- [x] 评论通知管理员 ([notify](https://github.com/nikoksr/notify)) - - [x] Telegram Bot - - [x] 飞书 WebHook Bot - - [x] 钉钉 - - [x] Bark - - [x] Slack - - [x] LINE - - [ ] 自定义 HTTP 回调 -- [ ] 博客邮件订阅 -- [x] 用户鉴权机制 -- [x] 跨域非法请求阻止 -- [x] 全局验证码操作次数限制 -- [x] JWT 登陆状态验证 -- [x] 时区自定义 -- [x] 只看作者功能 -- [ ] AT 提及 (@) -- [ ] 评论提及 (#) -- [ ] 表情包统一管理 - - [ ] 导入表情包 - - [ ] 表情包图片地址控制 -- [x] 图片上传 -- [x] 图片上传到图床 ([upgit](https://github.com/pluveto/upgit)) -- [ ] 图片管理 -- [ ] 附件上传 / 管理 -- [ ] 评论标签分类系统 -- [ ] 主题样式更换 -- [ ] 规范化 API -- [ ] 扩展中心 -- [ ] 开放用户注册 -- [ ] 接入第三方登录 -- [ ] 国际化 (i18n) -- [x] 一键升级 +## TODOs + +Reference to https://github.com/ArtalkJS/Artalk#todos ## License From 25f0e26fe74f834049516ec0a73b0a33e28e244c Mon Sep 17 00:00:00 2001 From: qwqcode Date: Sun, 17 Apr 2022 14:33:42 +0800 Subject: [PATCH 167/349] fix(import/export): Fix some bugs & simplify code Signed-off-by: qwqcode --- cmd/export.go | 24 +- cmd/import.go | 34 +-- http/api_admin_transfer.go | 3 +- lib/artransfer/artrans.go | 37 ++- lib/artransfer/importer.go | 131 ++------- lib/artransfer/typecho.go | 554 ------------------------------------- 6 files changed, 78 insertions(+), 705 deletions(-) delete mode 100644 lib/artransfer/typecho.go diff --git a/cmd/export.go b/cmd/export.go index dbad82f8a..c74a95780 100644 --- a/cmd/export.go +++ b/cmd/export.go @@ -3,7 +3,9 @@ package cmd import ( "fmt" "os" + "path" "path/filepath" + "time" "github.com/ArtalkJS/ArtalkGo/lib" "github.com/ArtalkJS/ArtalkGo/lib/artransfer" @@ -31,13 +33,29 @@ var exportCmd = &cobra.Command{ // write to stdout fmt.Println(jsonStr) } else { + filename := args[0] + + // make sure is abs path + filename, err := filepath.Abs(filename) + if err != nil { + logrus.Fatal(err) + } + + // check dir + stat, err := os.Stat(filename) + if err == nil { + if stat.IsDir() { + filename = path.Join(filename, "backup-"+time.Now().Format("20060102-150405")+".artrans") + } + } + // mkdir -p - if err := lib.EnsureDir(filepath.Dir(args[0])); err != nil { + if err := lib.EnsureDir(filepath.Dir(filename)); err != nil { logrus.Fatal(err) } // touch - f, err := os.Create(args[0]) + f, err := os.Create(filename) if err != nil { logrus.Fatal(err) } @@ -47,6 +65,8 @@ var exportCmd = &cobra.Command{ if err2 != nil { logrus.Fatal(err2) } + + logrus.Info("已导出 Artrans 文件:" + filename) } }, } diff --git a/cmd/import.go b/cmd/import.go index e62c83d5d..676e6a10b 100644 --- a/cmd/import.go +++ b/cmd/import.go @@ -2,7 +2,6 @@ package cmd import ( "errors" - "io/ioutil" "os" "github.com/ArtalkJS/ArtalkGo/lib/artransfer" @@ -14,12 +13,11 @@ var importCmd = &cobra.Command{ Use: "import <数据行囊文件路径>", Aliases: []string{}, Short: "数据迁移 - 迁入", - Long: "\n# 数据迁移 - 迁入\n\n 从其他评论系统迁移数据到 ArtalkGo\n" + ` -- 例如:artalk-go import typecho [参数] + Long: "\n# 数据迁移 - 迁入\n\n 从其他评论系统迁移数据到 Artalk\n" + ` +- 导入前需要使用转换工具 Artransfer 将其他评论数据转为 Artrans 格式 - 文档:https://artalk.js.org/guide/transfer.html `, - Args: cobra.MinimumNArgs(1), - ArgAliases: artransfer.GetSupportNames(), + Args: cobra.MinimumNArgs(1), Run: func(cmd *cobra.Command, args []string) { loadCore() // 装载核心 @@ -28,15 +26,11 @@ var importCmd = &cobra.Command{ logrus.Fatal("`数据行囊` 文件不存在,请检查路径是否正确") } - buf, err := ioutil.ReadFile(parcelFile) - if err != nil { - logrus.Fatal("数据行囊文件打开失败:", err) - } + payload := args[1:] + payload = append(payload, "json_file:"+parcelFile) - content := string(buf) - basic := artransfer.GetBasicParamsFrom(args[1:]) - basic.UrlResolver = false // 默认关闭 URL 解析器:因为 pageKey 是完整,且站点隔离开 - artransfer.ImportArtransByStr(basic, content) + // 导入 Artrans + artransfer.RunImportArtrans(payload) logrus.Info("导入结束") }, @@ -45,19 +39,5 @@ var importCmd = &cobra.Command{ func init() { rootCmd.AddCommand(importCmd) - for _, item := range artransfer.Supports { - imp := artransfer.GetImporterInfo(item) - subCmd := &cobra.Command{ - Use: imp.Name + " [参数]", - Short: imp.Desc, - Run: func(cmd *cobra.Command, args []string) { - artransfer.Assumeyes, _ = cmd.Flags().GetBool("assumeyes") - artransfer.RunByName(imp.Name, args) - }, - } - - importCmd.AddCommand(subCmd) - } - flagPV(importCmd, "assumeyes", "y", false, "Automatically answer yes for all questions.") } diff --git a/http/api_admin_transfer.go b/http/api_admin_transfer.go index c088de6ea..111668917 100644 --- a/http/api_admin_transfer.go +++ b/http/api_admin_transfer.go @@ -10,7 +10,6 @@ import ( ) type ParamsAdminImport struct { - Type string `mapstructure:"type" param:"required"` Payload string `mapstructure:"payload"` } @@ -50,7 +49,7 @@ func ActionAdminImport(c echo.Context) error { c.Response().Write([]byte("")) c.Response().Flush() } - artransfer.RunByName(p.Type, payload) + artransfer.RunImportArtrans(payload) return nil } diff --git a/lib/artransfer/artrans.go b/lib/artransfer/artrans.go index bc773ca03..51228fdd8 100644 --- a/lib/artransfer/artrans.go +++ b/lib/artransfer/artrans.go @@ -23,12 +23,6 @@ type _ArtransImporter struct { } func (imp *_ArtransImporter) Run(basic *BasicParams, payload []string) { - err := RequiredBasicTargetSite(basic) - if err != nil { - logFatal(err) - return - } - // 读取文件 jsonStr, jErr := JsonFileReady(payload) if jErr != nil { @@ -36,8 +30,6 @@ func (imp *_ArtransImporter) Run(basic *BasicParams, payload []string) { return } - basic.UrlResolver = false - ImportArtransByStr(basic, jsonStr) } @@ -59,6 +51,11 @@ func ImportArtrans(basic *BasicParams, comments []model.Artran) { return } + if basic.TargetSiteUrl != "" && !lib.ValidateURL(basic.TargetSiteUrl) { + logFatal("目标站点 URL 无效") + return + } + // 汇总 print("# 请过目:\n\n") @@ -69,15 +66,24 @@ func ImportArtrans(basic *BasicParams, comments []model.Artran) { showTSiteUrl := basic.TargetSiteUrl if showTSiteName == "" { showTSiteName = "未指定" + } if showTSiteUrl == "" { showTSiteUrl = "未指定" } + // 目标站点名和目标站点URL都不为空,才开启 URL 解析器 + showUrlResolver := "off" + if basic.TargetSiteName != "" && basic.TargetSiteUrl != "" { + basic.UrlResolver = true + showUrlResolver = "on" + } + PrintTable([]table.Row{ {"目标站点名", showTSiteName}, {"目标站点 URL", showTSiteUrl}, {"评论数量", len(comments)}, + {"URL 解析器", showUrlResolver}, }) print("\n") @@ -106,8 +112,18 @@ func ImportArtrans(basic *BasicParams, comments []model.Artran) { // 遍历导入 comments for _, c := range comments { + siteName := c.SiteName + siteUrls := c.SiteUrls + + if basic.TargetSiteName != "" { + siteName = basic.TargetSiteName + } + if basic.TargetSiteUrl != "" { + siteUrls = basic.TargetSiteUrl + } + // 准备 site - site, sErr := SiteReady(c.SiteName, c.SiteUrls) + site, sErr := SiteReady(siteName, siteUrls) if sErr != nil { logFatal(sErr) return @@ -132,7 +148,7 @@ func ImportArtrans(basic *BasicParams, comments []model.Artran) { nPageKey = UrlResolverGetPageKey(basic.TargetSiteUrl, c.PageKey) } - page := model.FindCreatePage(nPageKey, c.PageTitle, c.SiteName) + page := model.FindCreatePage(nPageKey, c.PageTitle, site.Name) page.AdminOnly = c.PageAdminOnly == lib.ToString(true) model.UpdatePage(&page) @@ -147,6 +163,7 @@ func ImportArtrans(basic *BasicParams, comments []model.Artran) { IsCollapsed: c.IsCollapsed == lib.ToString(true), IsPending: c.IsPending == lib.ToString(true), + IsPinned: c.IsPending == lib.ToString(true), UserID: user.ID, PageKey: page.Key, diff --git a/lib/artransfer/importer.go b/lib/artransfer/importer.go index 7551e4ecf..56fc34b48 100644 --- a/lib/artransfer/importer.go +++ b/lib/artransfer/importer.go @@ -21,51 +21,33 @@ import ( "github.com/ArtalkJS/ArtalkGo/model" "github.com/araddon/dateparse" "github.com/jedib0t/go-pretty/v6/table" - "gorm.io/gorm" ) -type Map = map[string]interface{} - -var Supports = []interface{}{ - ArtransImporter, - TypechoImporter, -} - -func RunByName(dataType string, payload []string) { +func RunImportArtrans(payload []string) { basic := GetBasicParamsFrom(payload) - for _, i := range Supports { - r := reflect.ValueOf(i) - name := reflect.Indirect(r).FieldByName("Name").String() - desc := reflect.Indirect(r).FieldByName("Desc").String() - note := reflect.Indirect(r).FieldByName("Note").String() - if !strings.EqualFold(name, dataType) { - continue - } - print("\n") - tableData := []table.Row{ - {"数据迁移 - 导入"}, - {strings.ToUpper(name)}, - {desc}, - } - if note != "" { - tableData = append(tableData, table.Row{note}) - } - PrintTable(tableData) - print("\n") - - //t1 := time.Now() - r.MethodByName("Run").Call([]reflect.Value{ - reflect.ValueOf(basic), - reflect.ValueOf(payload), - }) - //elapsed := time.Since(t1) - print("\n") - logInfo("导入执行结束") //,耗时: ", elapsed) - return + name := ArtransImporter.ImporterInfo.Name + desc := ArtransImporter.ImporterInfo.Desc + note := ArtransImporter.ImporterInfo.Note + + print("\n") + tableData := []table.Row{ + {"数据迁移 - 导入"}, + {strings.ToUpper(name)}, + {desc}, } + if note != "" { + tableData = append(tableData, table.Row{note}) + } + PrintTable(tableData) + print("\n") - logFatal("不支持该数据类型导入") + //t1 := time.Now() + ArtransImporter.Run(basic, payload) + //elapsed := time.Since(t1) + + print("\n") + logInfo("导入执行结束") //,耗时: ", elapsed) } type ImporterInfo struct { @@ -81,17 +63,6 @@ func GetImporterInfo(instance interface{}) ImporterInfo { return info } -func GetSupportNames() []string { - types := []string{} - for _, i := range Supports { - r := reflect.ValueOf(i) - f := reflect.Indirect(r).FieldByName("Name") - types = append(types, f.String()) - } - - return types -} - type BasicParams struct { TargetSiteName string TargetSiteUrl string @@ -131,50 +102,6 @@ func RequiredBasicTargetSite(basic *BasicParams) error { return nil } -func DbReady(payload []string) (*gorm.DB, error) { - var host, port, dbName, user, password, dbType, dbFile string - GetParamsFrom(payload).To(map[string]interface{}{ - "db_host": &host, - "db_port": &port, - "db_name": &dbName, - "db_user": &user, - "db_password": &password, - "db_type": &dbType, - "db_file": &dbFile, - }) - - if dbType == "" { - dbType = string(config.TypeMySql) - } - - // sqlite - if strings.EqualFold(dbType, string(config.TypeSQLite)) { - if dbFile == "" { - return nil, errors.New("SQLite 数据库:请传递参数 `db_file` 指定数据文件路径") - } - - db, err := lib.OpenSQLite(dbFile) - if err != nil { - return nil, errors.New("SQLite 打开失败 " + err.Error()) - } - return db, nil - } - - dsn, err := lib.GetDsn(config.DBType(dbType), host, port, dbName, user, password) - if err != nil { - return nil, errors.New("数据库连接 DSN 生成错误 " + err.Error()) - } - - db, err := lib.OpenDB(config.DBType(dbType), dsn) - if err != nil { - return nil, errors.New("数据库连接失败 " + err.Error()) - } - - logInfo("数据库连接成功") - - return db, nil -} - // 站点准备 func SiteReady(tSiteName string, tSiteUrls string) (model.Site, error) { site := model.FindSite(tSiteName) @@ -281,22 +208,6 @@ func UrlResolverGetPageKey(baseUrl string, commentUrlVal string) string { return u.String() } -func ParseVersion(s string) int64 { - strList := strings.Split(s, ".") - format := fmt.Sprintf("%%s%%0%ds", len(strList)) - v := "" - for _, value := range strList { - v = fmt.Sprintf(format, v, value) - } - var result int64 - var err error - if result, err = strconv.ParseInt(v, 10, 64); err != nil { - logError("ugh: parseVersion(%s): error=%s", s, err) - return 0 - } - return result -} - func ParseDate(s string) time.Time { denverLoc, _ := time.LoadLocation(config.Instance.TimeZone) // 时区 time.Local = denverLoc diff --git a/lib/artransfer/typecho.go b/lib/artransfer/typecho.go deleted file mode 100644 index e71c6d9ef..000000000 --- a/lib/artransfer/typecho.go +++ /dev/null @@ -1,554 +0,0 @@ -package artransfer - -import ( - "errors" - "fmt" - "os" - "regexp" - "strings" - - "github.com/ArtalkJS/ArtalkGo/lib" - "github.com/ArtalkJS/ArtalkGo/model" - "github.com/elliotchance/phpserialize" - "github.com/jedib0t/go-pretty/v6/table" - "github.com/mitchellh/mapstructure" -) - -const ( - // 已测试可用版本 - TypechoTestedVerMain = "1.1" - TypechoTestedVerSub = "17.10.30" - TypechoRewritePostDefault = "/archives/{cid}/" - TypechoRewritePageDefault = "/{slug}.html" -) - -var TypechoImporter = &_TypechoImporter{ - ImporterInfo: ImporterInfo{ - Name: "typecho", - Desc: "从 Typecho 导入数据", - Note: fmt.Sprintf("测试兼容:Typecho %s/%s", TypechoTestedVerMain, TypechoTestedVerSub), - }, -} - -type _TypechoImporter struct { - ImporterInfo - TargetSite model.Site - - Basic *BasicParams - SrcVersion string - SrcSiteName string - SrcSiteURL string - Comments []TypechoComment - Options []TypechoOption - Contents []TypechoContent - Metas []TypechoMeta - Relationships []TypechoRelationship - - DbPrefix string - - RewritePost string - RewritePage string - - OptionRoutingTable map[string]TypechoRoute -} - -// Typecho 升级相关的代码 @see https://github.com/typecho/typecho/blob/64b8e686885d8ab4c7f0cdc3d6dc2d99fa48537c/var/Utils/Upgrade.php -// 路由 @see https://github.com/typecho/typecho/blob/530312443142577509df88ce88cf3274fac9b8c4/var/Widget/Options/Permalink.php#L319 -// DB @see https://github.com/typecho/typecho/blob/6558fd5e030a950335d53038f82728b06ad6c32d/install/Mysql.sql -func (imp *_TypechoImporter) Run(basic *BasicParams, payload []string) { - // Ready - imp.Basic = basic - typechoDB, dErr := DbReady(payload) - if dErr != nil { - logFatal(dErr) - return - } - - GetParamsFrom(payload).To(map[string]interface{}{ - "db_prefix": &imp.DbPrefix, - "rewrite_post": &imp.RewritePost, - "rewrite_page": &imp.RewritePage, - }) - - if imp.DbPrefix == "" { - imp.DbPrefix = "typecho_" - } - - // Load Options - tbOptions := imp.DbPrefix + "options" - typechoDB.Raw("SELECT * FROM " + tbOptions).Scan(&imp.Options) - logInfo(fmt.Sprintf("从数据表 `%s` 获取 %d 条记录", tbOptions, len(imp.Options))) - - for _, opt := range imp.Options { - switch opt.Name { - case "generator": - imp.SrcVersion = opt.Value - case "title": - imp.SrcSiteName = opt.Value - case "siteUrl": - imp.SrcSiteURL = opt.Value - } - } - - // 若未指定 target site 则使用数据库数据 - if basic.TargetSiteName == "" && imp.SrcSiteName != "" { - basic.TargetSiteName = imp.SrcSiteName - } - if basic.TargetSiteUrl == "" && imp.SrcSiteURL != "" && lib.ValidateURL(imp.SrcSiteURL) { - basic.TargetSiteUrl = imp.SrcSiteURL - } - rErr := RequiredBasicTargetSite(basic) - if rErr != nil { - logFatal(rErr) - return - } - - // 检查数据源版本号 - imp.VersionCheck() - - // 重写规则 - imp.RewriteRuleReady() - - // load Metas - tbMetas := imp.DbPrefix + "metas" - typechoDB.Raw("SELECT * FROM " + tbMetas).Scan(&imp.Metas) - logInfo(fmt.Sprintf("从数据表 `%s` 获取 %d 条记录", tbMetas, len(imp.Metas))) - - // load Relationships - tbRelationships := imp.DbPrefix + "relationships" - typechoDB.Raw("SELECT * FROM " + tbRelationships).Scan(&imp.Relationships) - logInfo(fmt.Sprintf("从数据表 `%s` 获取 %d 条记录", tbRelationships, len(imp.Relationships))) - - // 获取 contents - tbContents := imp.DbPrefix + "contents" - typechoDB.Raw(fmt.Sprintf("SELECT * FROM %s ORDER BY created ASC", tbContents)).Scan(&imp.Contents) - logInfo(fmt.Sprintf("从数据表 `%s` 获取 %d 条记录", tbContents, len(imp.Contents))) - - // 获取 comments - tbComments := imp.DbPrefix + "comments" - typechoDB.Raw(fmt.Sprintf("SELECT * FROM %s ORDER BY created ASC", tbComments)).Scan(&imp.Comments) - logInfo(fmt.Sprintf("从数据表 `%s` 获取 %d 条记录", tbComments, len(imp.Comments))) - - // 导入前参数汇总 - print("\n") - - print("# 请过目:\n\n") - - // 显示第一条数据 - pageKeyEgPost := "" - pageKeyEgPage := "" - for _, c := range imp.Contents { - if c.Type == "post" { - firstPost := SprintEncodeData("第一篇文章", imp.Contents[0]) - print(HideJsonLongText("Text", firstPost)) - pageKeyEgPost = imp.GetNewPageKey(c) - printf(" -> 生成 PageKey: %#v\n\n", pageKeyEgPost) - break - } - } - - for _, c := range imp.Contents { - if c.Type == "page" { - pageKeyEgPage = imp.GetNewPageKey(c) - break - } - } - - if len(imp.Comments) > 0 { - PrintEncodeData("第一条评论", imp.Comments[0]) - } - - PrintTable([]table.Row{ - {"[基本信息]", "读取数据", "导入目标"}, - {"站点名称", fmt.Sprintf("%#v", imp.SrcSiteName), fmt.Sprintf("%#v", imp.Basic.TargetSiteName)}, - {"BaseURL", fmt.Sprintf("%#v", imp.SrcSiteURL), fmt.Sprintf("%#v", imp.Basic.TargetSiteUrl)}, - {"版本号", fmt.Sprintf("%v", imp.SrcVersion), fmt.Sprintf("ArtalkGo %v", lib.Version+"/"+lib.CommitHash+"")}, - {"数量统计", fmt.Sprintf("评论: %d", len(imp.Comments)), fmt.Sprintf("页面: %d", len(imp.Contents))}, - }) - - PrintTable([]table.Row{ - {"[重写规则]", "用于生成 pageKey (评论页面唯一标识)", "生成示例"}, - {"文章页面", fmt.Sprintf("%#v", imp.RewritePost), pageKeyEgPost}, - {"独立页面", fmt.Sprintf("%#v", imp.RewritePage), pageKeyEgPage}, - }) - - print("\n") - println("若以上内容不符合预期,请向我们反馈:https://artalk.js.org/guide/transfer.html") - print("\n") - - // 确认开始 - if !Confirm("确认开始导入吗?") { - os.Exit(0) - } - - // 准备导入评论 - println() - - // 准备新的 site - targetSite, sErr := SiteReady(basic.TargetSiteName, basic.TargetSiteUrl) - if sErr != nil { - logFatal(sErr) - return - } - imp.TargetSite = targetSite - - // 开始执行导入 - imp.ImportComments() -} - -// 导入评论 -func (imp *_TypechoImporter) ImportComments() { - contents := imp.Contents - comments := imp.Comments - - print("\n====================================\n\n") - logInfo(fmt.Sprintf("[开始导入] 共 %d 个页面,%d 条评论", len(contents), len(comments))) - print("\n") - - siteName := imp.Basic.TargetSiteName - - idChanges := map[uint]uint{} // comment_id: old => new - - // 导入页面 - for _, c := range contents { - // 创建页面 - pageKey := imp.GetNewPageKey(c) - page := model.FindCreatePage(pageKey, c.Title, imp.Basic.TargetSiteName) - - // 导入评论 - commentTotal := 0 - for _, co := range comments { - if co.Cid != c.Cid { - continue - } - - // 创建 user - user := model.FindCreateUser(co.Author, co.Mail, co.Url) - - // 创建新 comment 实例 - nComment := model.Comment{ - Content: co.Text, - - PageKey: page.Key, - SiteName: siteName, - - UserID: user.ID, - UA: co.Agent, - IP: co.Ip, - - Rid: uint(co.Parent), - - IsCollapsed: false, - IsPending: co.Status != "approved", - } - - // 保存到数据库 - err := lib.DB.Create(&nComment).Error - if err != nil { - logError(fmt.Sprintf("评论源 ID:%d 保存失败", co.Coid)) - continue - } - - // 日期恢复 - createdVal := fmt.Sprintf("%v", co.Created) - lib.DB.Model(&nComment).Update("CreatedAt", ParseDate(createdVal)) - lib.DB.Model(&nComment).Update("UpdatedAt", ParseDate(createdVal)) - - idChanges[uint(co.Coid)] = nComment.ID - commentTotal++ - } - - printf("+ [%-3d] 条评论 <- [%5d] %-30s | %#v\n", commentTotal, c.Cid, c.Slug, c.Title) - } - - // reply id 重建 - RebuildRid(idChanges) -} - -// 获取新的 PageKey (根据重写规则) -func (imp *_TypechoImporter) GetNewPageKey(content TypechoContent) string { - date := ParseDate(fmt.Sprintf("%v", content.Created)) - - // 替换内容制作 - replaces := map[string]string{ - "cid": fmt.Sprintf("%v", content.Cid), - "slug": content.Slug, - "category": imp.GetContentCategory(content.Cid), - "year": fmt.Sprintf("%v", date.Local().Year()), - "month": fmt.Sprintf("%v", date.Local().Month()), - "day": fmt.Sprintf("%v", date.Local().Day()), - } - - baseUrl := imp.Basic.TargetSiteUrl - baseUrl = strings.TrimSuffix(baseUrl, "/") - - rewriteRule := imp.RewritePost - if strings.HasPrefix(content.Type, "post") { - rewriteRule = imp.RewritePost - } else if strings.HasPrefix(content.Type, "page") { - rewriteRule = imp.RewritePage - } - - rewriteRule = "/" + strings.TrimPrefix(rewriteRule, "/") - return baseUrl + imp.ReplaceAllBracketed(rewriteRule, replaces) -} - -// 替换字符串 -// @note 特别注意:replaces 的 key 外侧无 “[]” 或 “{}” -func (imp *_TypechoImporter) ReplaceAllBracketed(data string, replaces map[string]string) string { - r := regexp.MustCompile(`(\[|\{)\s*(.*?)\s*(\]|\})`) // 同时支持 {} 和 [] - return r.ReplaceAllStringFunc(data, func(m string) string { - key := r.FindStringSubmatch(m)[2] - if val, isExist := replaces[key]; isExist { - return val - } else { - logError(fmt.Sprintf("[重写规则] \"%s\" 变量无效", key)) - } - return m - }) -} - -// 版本过旧检测 -func (imp *_TypechoImporter) VersionCheck() { - r := regexp.MustCompile(`Typecho[\s]*(.+)\/(.+)`) - group := r.FindStringSubmatch(imp.SrcVersion) - if len(group) < 2 { - logWarn(`无法确认您的 Typecho 版本号:"` + fmt.Sprintf("%#v", imp.SrcVersion) + `"`) - return - } - - verMain := ParseVersion(group[1]) - verSub := ParseVersion(group[2]) - - if verMain < ParseVersion(TypechoTestedVerMain) || - verSub < ParseVersion(TypechoTestedVerSub) { - print("\n") - logWarn(fmt.Sprintf("Typecho 当前版本 \"%s\" 旧于 \"Typecho %s/%s\"", - imp.SrcVersion, TypechoTestedVerMain, TypechoTestedVerSub)) - logWarn("不确定导入是否能够成功导入,您可以选择升级 Typecho: http://docs.typecho.org/upgrade") - } -} - -// TypechoRoute 路由 -type TypechoRoute struct { - URL string `json:"url"` - Format string `json:"format"` - Params string `json:"params"` - Regx string `json:"regx"` - Action string `json:"action"` - Widget string `json:"widget"` -} - -// 获取 typecho_options 表里面的 name:routingTable option,解析 option.value。 -// option.value 数据为 PHP 序列化后的结果。 -// @see https://www.php.net/manual/en/function.serialize.php -// @see https://www.php.net/manual/en/function.unserialize.php -func (imp *_TypechoImporter) GetOptionRoutingTable() (map[string]TypechoRoute, error) { - // 仅获取一次 - if imp.OptionRoutingTable != nil { - return imp.OptionRoutingTable, nil - } - - dataStr := "" - for _, opt := range imp.Options { - if opt.Name == "routingTable" { - dataStr = opt.Value - break - } - } - - if dataStr == "" { - return map[string]TypechoRoute{}, errors.New("`routingTable` Not Found in Options") - } - - // Unmarshal - var data map[interface{}]interface{} - err := phpserialize.Unmarshal([]byte(dataStr), &data) - if err != nil { - return map[string]TypechoRoute{}, err - } - - // interface{} to struct - routingTable := map[string]TypechoRoute{} - for k, v := range data { - var r TypechoRoute - mapstructure.Decode(v, &r) - routingTable[fmt.Sprintf("%v", k)] = r - } - - imp.OptionRoutingTable = routingTable // 就不再反复获取了 - - return routingTable, nil -} - -// 获取一个 Route -func (imp *_TypechoImporter) GetOptionRoute(name string) (TypechoRoute, error) { - routingTable, err := imp.GetOptionRoutingTable() - if err != nil { - return TypechoRoute{}, err - } - - for n, route := range routingTable { - if n == name { - return route, nil - } - } - - return TypechoRoute{}, errors.New(`Route Name "` + name + `" Not Found`) -} - -// 重写路径获取 -func (imp *_TypechoImporter) RewriteRuleReady() { - check := func(nameText string, routeName string, field *string, defaultVal string) { - if *field == "" { - // 从数据库获取 - route, err := imp.GetOptionRoute(routeName) - if err != nil || route.URL == "" { - if err != nil { - logError(err) - } - - *field = defaultVal - logError("[重写规则] \"" + nameText + "\" 无法从数据库读取,将使用默认值 \"" + imp.RewritePost + "\"") - return - } - - readRule := route.URL - - // 将 [year:digital:4] 变为 [year] - r := regexp.MustCompile(`\[(([a-zA-Z0-9]+):?(.*?))\]`) - subMatches := r.FindAllStringSubmatch(readRule, -1) - replaces := map[string]string{} - for _, m := range subMatches { - if len(m) < 1 { - continue - } - - // 0 => [year:digital:4] - // 1 => year:digital:4 - // 2 => year - // 3 => digital:4 - replaces[m[1]] = "[" + m[2] + "]" - } - readRule = imp.ReplaceAllBracketed(readRule, replaces) // replaces keys 无括号 - - // 保存从数据库读取到的 rule - *field = readRule - logInfo("重写规则 \"" + nameText + "\" 读取成功") - } else { - logInfo("[重写规则] 自定义 \""+nameText+"\" 规则:", fmt.Sprintf("%#v", *field)) - } - } - - check("文章页", "post", &imp.RewritePost, TypechoRewritePostDefault) - check("独立页面", "page", &imp.RewritePage, TypechoRewritePageDefault) -} - -// 获取 Content 的 Metas -func (imp *_TypechoImporter) GetContentMetas(cid int) []TypechoMeta { - metaIds := []int{} - for _, rela := range imp.Relationships { - if rela.Cid == cid { - metaIds = append(metaIds, rela.Mid) - } - } - - metas := []TypechoMeta{} - for _, m := range imp.Metas { - isNeed := false - for _, id := range metaIds { - if id == m.Mid { - isNeed = true - break - } - } - - if isNeed { - metas = append(metas, m) - } - } - - return metas -} - -// 获取 Content 的分类 -func (imp *_TypechoImporter) GetContentCategory(cid int) string { - metas := imp.GetContentMetas(cid) - for _, m := range metas { - if m.Type == "category" { - return m.Slug - } - } - - return "" -} - -// Typecho 评论数据表 -type TypechoComment struct { - Coid int `gorm:"column:coid"` // comment_id - Cid int `gorm:"column:cid"` // content_id - Created int `gorm:"column:created"` - Author string `gorm:"column:author"` - AuthorId int `gorm:"column:authorId"` - OwnerId int `gorm:"column:ownerId"` - Mail string `gorm:"column:mail"` - Url string `gorm:"column:url"` - Ip string `gorm:"column:ip"` - Agent string `gorm:"column:agent"` - Text string `gorm:"column:text"` - Type string `gorm:"column:type"` - Status string `gorm:"column:status"` - Parent int `gorm:"column:parent"` - Stars int `gorm:"column:stars"` - Notify int `gorm:"column:notify"` - Likes int `gorm:"column:likes"` - Dislikes int `gorm:"column:dislikes"` -} - -// Typecho 内容数据表 (Type: post, page) -type TypechoContent struct { - Cid int `gorm:"column:cid"` - Title string `gorm:"column:title"` - Slug string `gorm:"column:slug"` - Created int `gorm:"column:created"` - Modified int `gorm:"column:modified"` - Text string `gorm:"column:text"` - Order int `gorm:"column:order"` - AuthorId int `gorm:"column:authorId"` - Template string `gorm:"column:template"` - Type string `gorm:"column:type"` - Status string `gorm:"column:status"` - Password string `gorm:"column:password"` - CommentsNum int `gorm:"column:commentsNum"` - AllowComment string `gorm:"column:allowComment"` - AllowPing string `gorm:"column:allowPing"` - AllowFeed string `gorm:"column:allowFeed"` - Parent int `gorm:"column:parent"` - Views int `gorm:"column:views"` - ViewsNum int `gorm:"column:viewsNum"` - LikesNum int `gorm:"column:likesNum"` - WordCount int `gorm:"column:wordCount"` - Likes int `gorm:"column:likes"` -} - -// Typecho 配置数据表 -type TypechoOption struct { - Name string `gorm:"column:name"` - User int `gorm:"column:user"` - Value string `gorm:"column:value"` -} - -// Typecho 关联表 (Content => Metas) -type TypechoRelationship struct { - Cid int `gorm:"column:cid"` // content_id - Mid int `gorm:"column:mid"` // meta_id -} - -// Typecho 附加字段数据表 -type TypechoMeta struct { - Mid int `gorm:"column:mid"` - Name string `gorm:"column:name"` - Slug string `gorm:"column:slug"` - Type string `gorm:"column:type"` - Description string `gorm:"column:description"` -} From eb2bf342272a736d84c8ee25a1873ea7b4098a38 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Sun, 17 Apr 2022 14:35:59 +0800 Subject: [PATCH 168/349] chore: Modify build-frontend.sh to use the latest commit Signed-off-by: qwqcode --- scripts/build-frontend.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/build-frontend.sh b/scripts/build-frontend.sh index 0d77eb74c..c79ad6e1d 100755 --- a/scripts/build-frontend.sh +++ b/scripts/build-frontend.sh @@ -23,9 +23,9 @@ rm -rf ./Artalk git clone https://github.com/ArtalkJS/Artalk.git Artalk cd Artalk -# using latest tag soruce code -git fetch --tags -git checkout $(git describe --tags --abbrev=0) +# # using latest tag soruce code +# git fetch --tags +# git checkout $(git describe --tags --abbrev=0) pnpm install pnpm build:all From 0c69206bd036b9d224a27b02b4ca956b8ecf24c7 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Sun, 17 Apr 2022 17:17:15 +0800 Subject: [PATCH 169/349] feat(api-import-upload): Frontend importer upload before. Signed-off-by: qwqcode --- http/a_http.go | 1 + http/api_admin_transfer.go | 44 +++++++++++++++++++++++++++++++++++++- lib/artransfer/artrans.go | 28 ++++++++++++++++++------ lib/artransfer/importer.go | 5 ++--- lib/artransfer/output.go | 19 +++++++++++++++- 5 files changed, 85 insertions(+), 12 deletions(-) diff --git a/http/a_http.go b/http/a_http.go index 00e58c631..877bfcf8d 100644 --- a/http/a_http.go +++ b/http/a_http.go @@ -139,6 +139,7 @@ func InitRoute(e *echo.Echo) { admin.POST("/setting-get", ActionAdminSettingGet) admin.POST("/setting-save", ActionAdminSettingSave) admin.POST("/import", ActionAdminImport) + admin.POST("/import-upload", ActionAdminImportUpload) admin.POST("/export", ActionAdminExport) // admin.POST("/vote-sync", ActionAdminVoteSync) // 数据导入功能未关注 vote 部分,暂时注释 diff --git a/http/api_admin_transfer.go b/http/api_admin_transfer.go index 111668917..1d6fc4fa2 100644 --- a/http/api_admin_transfer.go +++ b/http/api_admin_transfer.go @@ -2,13 +2,55 @@ package http import ( "encoding/json" + "io/ioutil" "net/http" "github.com/ArtalkJS/ArtalkGo/lib" "github.com/ArtalkJS/ArtalkGo/lib/artransfer" "github.com/labstack/echo/v4" + "github.com/sirupsen/logrus" ) +func ActionAdminImportUpload(c echo.Context) error { + if isOK, resp := AdminOnly(c); !isOK { + return resp + } + + // 获取 Form + file, err := c.FormFile("file") + if err != nil { + logrus.Error(err) + return RespError(c, "文件获取失败") + } + + // 打开文件 + src, err := file.Open() + if err != nil { + logrus.Error(err) + return RespError(c, "文件打开失败") + } + defer src.Close() + + // 读取文件 + buf, err := ioutil.ReadAll(src) + if err != nil { + logrus.Error(err) + return RespError(c, "文件读取失败") + } + + tmpFile, err := ioutil.TempFile("", "artalk-import-file-") + if err != nil { + logrus.Error(err) + return RespError(c, "临时文件创建失败") + } + + tmpFile.Write(buf) + + return RespData(c, Map{ + "filename": tmpFile.Name(), + }) +} + type ParamsAdminImport struct { Payload string `mapstructure:"payload"` } @@ -40,7 +82,7 @@ func ActionAdminImport(c echo.Context) error { c.Response().Write([]byte( ` - `)) + `)) c.Response().Flush() artransfer.Assumeyes = true diff --git a/lib/artransfer/artrans.go b/lib/artransfer/artrans.go index 51228fdd8..c854d3acd 100644 --- a/lib/artransfer/artrans.go +++ b/lib/artransfer/artrans.go @@ -7,7 +7,6 @@ import ( "github.com/ArtalkJS/ArtalkGo/lib" "github.com/ArtalkJS/ArtalkGo/model" "github.com/cheggaaa/pb/v3" - "github.com/jedib0t/go-pretty/v6/table" ) var ArtransImporter = &_ArtransImporter{ @@ -79,10 +78,10 @@ func ImportArtrans(basic *BasicParams, comments []model.Artran) { showUrlResolver = "on" } - PrintTable([]table.Row{ + PrintTable([][]interface{}{ {"目标站点名", showTSiteName}, {"目标站点 URL", showTSiteUrl}, - {"评论数量", len(comments)}, + {"评论数量", fmt.Sprintf("%d", len(comments))}, {"URL 解析器", showUrlResolver}, }) @@ -108,10 +107,15 @@ func ImportArtrans(basic *BasicParams, comments []model.Artran) { } // 进度条 - bar := pb.StartNew(len(comments)) + var bar *pb.ProgressBar + if HttpOutput == nil { + bar = pb.StartNew(len(comments)) + } + + total := len(comments) // 遍历导入 comments - for _, c := range comments { + for i, c := range comments { siteName := c.SiteName siteUrls := c.SiteUrls @@ -184,9 +188,19 @@ func ImportArtrans(basic *BasicParams, comments []model.Artran) { idChanges[uint(idMap[c.ID])] = nComment.ID - bar.Increment() + if bar != nil { + bar.Increment() + } + if HttpOutput != nil && i%50 == 0 { + print(fmt.Sprintf("%.0f%%... ", float64(i)/float64(total)*100)) + } + } + if bar != nil { + bar.Finish() + } + if HttpOutput != nil { + println() } - bar.Finish() logInfo(fmt.Sprintf("导入 %d 条数据", len(comments))) // reply id 重建 diff --git a/lib/artransfer/importer.go b/lib/artransfer/importer.go index 56fc34b48..af16ebc88 100644 --- a/lib/artransfer/importer.go +++ b/lib/artransfer/importer.go @@ -20,7 +20,6 @@ import ( "github.com/ArtalkJS/ArtalkGo/lib" "github.com/ArtalkJS/ArtalkGo/model" "github.com/araddon/dateparse" - "github.com/jedib0t/go-pretty/v6/table" ) func RunImportArtrans(payload []string) { @@ -31,13 +30,13 @@ func RunImportArtrans(payload []string) { note := ArtransImporter.ImporterInfo.Note print("\n") - tableData := []table.Row{ + tableData := [][]interface{}{ {"数据迁移 - 导入"}, {strings.ToUpper(name)}, {desc}, } if note != "" { - tableData = append(tableData, table.Row{note}) + tableData = append(tableData, []interface{}{note}) } PrintTable(tableData) print("\n") diff --git a/lib/artransfer/output.go b/lib/artransfer/output.go index 0c1f94776..7320728e1 100644 --- a/lib/artransfer/output.go +++ b/lib/artransfer/output.go @@ -69,7 +69,24 @@ func println(a ...interface{}) { print(fmt.Sprintln(a...)) } -func PrintTable(rows []table.Row) { +func PrintTable(rows [][]interface{}) { + if HttpOutput != nil { + println("-------------------------") + for _, row := range rows { + l := len(row) + print(" + ") + for i, col := range row { + print(col) + if i < l-1 { + print(": ") + } + } + println() + } + println("-------------------------") + return + } + t := table.NewWriter() for _, r := range rows { From 8e8e428300861b504aaee5a67e57fef43e33ee12 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Sun, 17 Apr 2022 19:57:23 +0800 Subject: [PATCH 170/349] chore: Update FeMinVersion to v2.2.2 Signed-off-by: qwqcode --- lib/version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/version.go b/lib/version.go index 5ee42dc60..93ad2302c 100644 --- a/lib/version.go +++ b/lib/version.go @@ -7,4 +7,4 @@ var ( ) // 前端最小要求版本号 -var FeMinVersion string = "2.2.1" +var FeMinVersion string = "2.2.2" From c691c495fad3d65a4d6cd75cc735d5976c86773f Mon Sep 17 00:00:00 2001 From: qwqcode Date: Sun, 17 Apr 2022 21:16:35 +0800 Subject: [PATCH 171/349] chore: Update docker-compose.yml Signed-off-by: qwqcode --- docker-compose.yml | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 238b901d0..252425c93 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -2,11 +2,9 @@ version: "3.5" services: artalk: container_name: artalk - build: - context: . + image: artalk/artalk-go ports: - - "23366:23366" + - 8080:23366 volumes: - - ./email-tpl:/email-tpl - - ./artalk-go.yml:/artalk-go.yml + - ./conf.yml:/conf.yml - ./data:/data \ No newline at end of file From da746c4134e3b467b595d5737dd73756b7ae35db Mon Sep 17 00:00:00 2001 From: qwqcode Date: Sun, 17 Apr 2022 21:57:32 +0800 Subject: [PATCH 172/349] fix: Geetest js resource url Signed-off-by: qwqcode --- lib/captcha/pages/geetest.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/captcha/pages/geetest.html b/lib/captcha/pages/geetest.html index e728e3fa3..58eab0797 100644 --- a/lib/captcha/pages/geetest.html +++ b/lib/captcha/pages/geetest.html @@ -5,7 +5,7 @@ Geetest - + `)) - c.Response().Flush() artransfer.Assumeyes = true artransfer.HttpOutput = func(continueRun bool, text string) { - c.Response().Write([]byte(text)) - c.Response().Write([]byte("")) - c.Response().Flush() + buf.Write([]byte(text)) + buf.Write([]byte("")) } artransfer.RunImportArtrans(payloadArr) + // 刷新 CORS 可信域名 + common.ReloadCorsAllowOrigins() + return nil } -func (a *action) AdminExport(c echo.Context) error { +func adminImportUpload(c *fiber.Ctx) error { + // 获取 Form + file, err := c.FormFile("file") + if err != nil { + logrus.Error(err) + return common.RespError(c, "文件获取失败") + } + + // 打开文件 + src, err := file.Open() + if err != nil { + logrus.Error(err) + return common.RespError(c, "文件打开失败") + } + defer src.Close() + + // 读取文件 + buf, err := io.ReadAll(src) + if err != nil { + logrus.Error(err) + return common.RespError(c, "文件读取失败") + } + + tmpFile, err := os.CreateTemp("", "artalk-import-file-") + if err != nil { + logrus.Error(err) + return common.RespError(c, "临时文件创建失败") + } + + tmpFile.Write(buf) + + return common.RespData(c, common.Map{ + "filename": tmpFile.Name(), + }) +} + +func adminExport(c *fiber.Ctx) error { jsonStr, err := artransfer.ExportArtransString(func(db *gorm.DB) *gorm.DB { - if !GetIsSuperAdmin(c) { + if !common.GetIsSuperAdmin(c) { // 仅导出限定范围内的站点 - u := GetUserByReq(c) + u := common.GetUserByReq(c) db = db.Where("site_name IN (?)", query.CookUser(&u).SiteNames) } return db }) if err != nil { - RespError(c, "导出错误", Map{ + common.RespError(c, "导出错误", common.Map{ "err": err, }) } - return RespData(c, Map{ + return common.RespData(c, common.Map{ "data": jsonStr, }) } diff --git a/server/handler/admin_user_add.go b/server/handler/admin_user_add.go new file mode 100644 index 000000000..f029e9762 --- /dev/null +++ b/server/handler/admin_user_add.go @@ -0,0 +1,74 @@ +package handler + +import ( + "github.com/ArtalkJS/ArtalkGo/internal/entity" + "github.com/ArtalkJS/ArtalkGo/internal/query" + "github.com/ArtalkJS/ArtalkGo/internal/utils" + "github.com/ArtalkJS/ArtalkGo/server/common" + "github.com/gofiber/fiber/v2" + "github.com/sirupsen/logrus" +) + +type ParamsAdminUserAdd struct { + Name string `form:"name" validate:"required"` + Email string `form:"email" validate:"required"` + Password string `form:"password"` + Link string `form:"link"` + IsAdmin bool `form:"is_admin" validate:"required"` + SiteNames string `form:"site_names"` + ReceiveEmail bool `form:"receive_email" validate:"required"` + BadgeName string `form:"badge_name"` + BadgeColor string `form:"badge_color"` +} + +// POST /api/admin/user-add +func AdminUserAdd(router fiber.Router) { + router.Post("/user-add", func(c *fiber.Ctx) error { + if !common.GetIsSuperAdmin(c) { + return common.RespError(c, "无权操作") + } + + var p ParamsAdminUserAdd + if isOK, resp := common.ParamsDecode(c, &p); !isOK { + return resp + } + + if !query.FindUser(p.Name, p.Email).IsEmpty() { + return common.RespError(c, "用户已存在") + } + + if !utils.ValidateEmail(p.Email) { + return common.RespError(c, "Invalid email") + } + if p.Link != "" && !utils.ValidateURL(p.Link) { + return common.RespError(c, "Invalid link") + } + + user := entity.User{} + user.Name = p.Name + user.Email = p.Email + user.Link = p.Link + user.IsAdmin = p.IsAdmin + user.SiteNames = p.SiteNames + user.ReceiveEmail = p.ReceiveEmail + user.BadgeName = p.BadgeName + user.BadgeColor = p.BadgeColor + + if p.Password != "" { + err := user.SetPasswordEncrypt(p.Password) + if err != nil { + logrus.Errorln(err) + return common.RespError(c, "密码设置失败") + } + } + + err := query.CreateUser(&user) + if err != nil { + return common.RespError(c, "user 创建失败") + } + + return common.RespData(c, common.Map{ + "user": query.UserToCookedForAdmin(&user), + }) + }) +} diff --git a/server/handler/admin_user_del.go b/server/handler/admin_user_del.go new file mode 100644 index 000000000..1e9dd62ea --- /dev/null +++ b/server/handler/admin_user_del.go @@ -0,0 +1,36 @@ +package handler + +import ( + "github.com/ArtalkJS/ArtalkGo/internal/query" + "github.com/ArtalkJS/ArtalkGo/server/common" + "github.com/gofiber/fiber/v2" +) + +type ParamsAdminUserDel struct { + ID uint `form:"id" validate:"required"` +} + +// POST /api/admin/user-del +func AdminUserDel(router fiber.Router) { + router.Post("/user-del", func(c *fiber.Ctx) error { + if !common.GetIsSuperAdmin(c) { + return common.RespError(c, "无权操作") + } + + var p ParamsAdminUserDel + if isOK, resp := common.ParamsDecode(c, &p); !isOK { + return resp + } + + user := query.FindUserByID(p.ID) + if user.IsEmpty() { + return common.RespError(c, "user 不存在") + } + + err := query.DelUser(&user) + if err != nil { + return common.RespError(c, "user 删除失败") + } + return common.RespSuccess(c) + }) +} diff --git a/server/handler/admin_user_edit.go b/server/handler/admin_user_edit.go new file mode 100644 index 000000000..d3afe23ea --- /dev/null +++ b/server/handler/admin_user_edit.go @@ -0,0 +1,84 @@ +package handler + +import ( + "github.com/ArtalkJS/ArtalkGo/internal/cache" + "github.com/ArtalkJS/ArtalkGo/internal/query" + "github.com/ArtalkJS/ArtalkGo/internal/utils" + "github.com/ArtalkJS/ArtalkGo/server/common" + "github.com/gofiber/fiber/v2" +) + +type ParamsAdminUserEdit struct { + // 查询值 + ID uint `form:"id" validate:"required"` + + // 修改值 + Name string `form:"name" validate:"required"` + Email string `form:"email" validate:"required"` + Password string `form:"password"` + Link string `form:"link"` + IsAdmin bool `form:"is_admin" validate:"required"` + SiteNames string `form:"site_names"` + ReceiveEmail bool `form:"receive_email" validate:"required"` + BadgeName string `form:"badge_name"` + BadgeColor string `form:"badge_color"` +} + +// POST /api/admin/user-edit +func AdminUserEdit(router fiber.Router) { + router.Post("/user-edit", func(c *fiber.Ctx) error { + if !common.GetIsSuperAdmin(c) { + return common.RespError(c, "无权操作") + } + + var p ParamsAdminUserEdit + if isOK, resp := common.ParamsDecode(c, &p); !isOK { + return resp + } + + user := query.FindUserByID(p.ID) + if user.IsEmpty() { + return common.RespError(c, "user 不存在") + } + + // 改名名合法性检测 + modifyName := p.Name != user.Name + modifyEmail := p.Email != user.Email + + if modifyName && modifyEmail && !query.FindUser(p.Name, p.Email).IsEmpty() { + return common.RespError(c, "user 已存在,请更换用户名和邮箱") + } + + if !utils.ValidateEmail(p.Email) { + return common.RespError(c, "Invalid email") + } + if p.Link != "" && !utils.ValidateURL(p.Link) { + return common.RespError(c, "Invalid link") + } + + // 删除原有缓存 + cache.UserCacheDel(&user) + + // 修改 user + user.Name = p.Name + user.Email = p.Email + if p.Password != "" { + user.SetPasswordEncrypt(p.Password) + } + user.Link = p.Link + user.IsAdmin = p.IsAdmin + user.SiteNames = p.SiteNames + user.ReceiveEmail = p.ReceiveEmail + user.BadgeName = p.BadgeName + user.BadgeColor = p.BadgeColor + + err := query.UpdateUser(&user) + if err != nil { + return common.RespError(c, "user 保存失败") + } + + return common.RespData(c, common.Map{ + "user": query.UserToCookedForAdmin(&user), + }) + }) +} diff --git a/server/handler/admin_user_get.go b/server/handler/admin_user_get.go new file mode 100644 index 000000000..5467e19c4 --- /dev/null +++ b/server/handler/admin_user_get.go @@ -0,0 +1,69 @@ +package handler + +import ( + "github.com/ArtalkJS/ArtalkGo/internal/db" + "github.com/ArtalkJS/ArtalkGo/internal/entity" + "github.com/ArtalkJS/ArtalkGo/internal/query" + "github.com/ArtalkJS/ArtalkGo/server/common" + "github.com/gofiber/fiber/v2" +) + +type ParamsAdminUserGet struct { + Limit int `form:"limit"` + Offset int `form:"offset"` + Type string `form:"type"` +} + +type ResponseAdminUserGet struct { + Total int64 `json:"total"` + Users []entity.CookedUserForAdmin `json:"users"` +} + +// POST /api/admin/user-get +func AdminUserGet(router fiber.Router) { + router.Post("/user-get", func(c *fiber.Ctx) error { + if !common.GetIsSuperAdmin(c) { + return common.RespError(c, "无权操作") + } + + var p ParamsAdminUserGet + if isOK, resp := common.ParamsDecode(c, &p); !isOK { + return resp + } + + // 准备 query + q := db.DB().Model(&entity.User{}).Order("created_at DESC") + + // 总共条数 + var total int64 + q.Count(&total) + + // 类型筛选 + if p.Type == "" { + p.Type = "all" // 默认类型 + } + + if p.Type == "admin" { + q = q.Where("is_admin = ?", true) + } else if p.Type == "in_conf" { + q = q.Where("is_in_conf = ?", true) + } + + // 数据分页 + q = q.Scopes(Paginate(p.Offset, p.Limit)) + + // 查找 + var users []entity.User + q.Find(&users) + + var cookedUsers []entity.CookedUserForAdmin + for _, u := range users { + cookedUsers = append(cookedUsers, query.UserToCookedForAdmin(&u)) + } + + return common.RespData(c, ResponseAdminUserGet{ + Users: cookedUsers, + Total: total, + }) + }) +} diff --git a/server/handler/admin_vote_sync.go b/server/handler/admin_vote_sync.go new file mode 100644 index 000000000..bbf144fd6 --- /dev/null +++ b/server/handler/admin_vote_sync.go @@ -0,0 +1,28 @@ +package handler + +import ( + "github.com/ArtalkJS/ArtalkGo/internal/query" + "github.com/ArtalkJS/ArtalkGo/server/common" + "github.com/gofiber/fiber/v2" +) + +type ParamsAdminVoteSync struct { +} + +// POST /api/admin/vote-sync +func AdminVoteSync(router fiber.Router) { + router.Post("/vote-sync", func(c *fiber.Ctx) error { + var p ParamsAdminVoteSync + if isOK, resp := common.ParamsDecode(c, &p); !isOK { + return resp + } + + if !common.GetIsSuperAdmin(c) { + return common.RespError(c, "无权访问") + } + + query.VoteSync() + + return common.RespSuccess(c) + }) +} diff --git a/server/handler/captcha.go b/server/handler/captcha.go new file mode 100644 index 000000000..52bec83ef --- /dev/null +++ b/server/handler/captcha.go @@ -0,0 +1,124 @@ +package handler + +import ( + "bytes" + "io" + "strings" + "text/template" + + "github.com/ArtalkJS/ArtalkGo/internal/captcha" + "github.com/ArtalkJS/ArtalkGo/internal/config" + "github.com/ArtalkJS/ArtalkGo/server/common" + "github.com/gofiber/fiber/v2" + "github.com/sirupsen/logrus" +) + +func Captcha(router fiber.Router) { + ca := router.Group("/captcha/", func(c *fiber.Ctx) error { + if !config.Instance.Captcha.Enabled { + return common.RespError(c, "验证码功能已关闭") + } + return c.Next() + }) + { + ca.Post("/refresh", captchaGet) + ca.Get("/get", captchaGet) + ca.Post("/get", captchaGet) + ca.Post("/check", captchaCheck) + ca.Post("/status", captchaStatus) + } +} + +// 获取当前状态,是否需要验证 +func captchaStatus(c *fiber.Ctx) error { + if common.IsReqNeedCaptchaCheck(c) { + return common.RespData(c, common.Map{"is_pass": false}) + } else { + return common.RespData(c, common.Map{"is_pass": true}) + } +} + +// 获取验证码 +func captchaGet(c *fiber.Ctx) error { + ip := c.IP() + + // =========== + // Geetest + // =========== + if config.Instance.Captcha.Geetest.Enabled { + pageFile, _ := captcha.GetPage("geetest.html") + buf, _ := io.ReadAll(pageFile) + + var page bytes.Buffer + + t := template.New("") + t.Parse(string(buf)) + t.Execute(&page, map[string]interface{}{"gt_id": config.Instance.Captcha.Geetest.CaptchaID}) + + c.Set("Content-Type", "text/html") + return c.SendString(page.String()) + } + + // =========== + // 图片验证码 + // =========== + return common.RespData(c, common.Map{ + "img_data": common.GetNewImageCaptchaBase64(ip), + }) +} + +type ParamsCaptchaCheck struct { + Value string `form:"value" validate:"required"` +} + +// 验证 +func captchaCheck(c *fiber.Ctx) error { + ip := c.IP() + + var p ParamsCaptchaCheck + if isOK, resp := common.ParamsDecode(c, &p); !isOK { + return resp + } + inputVal := p.Value + + // =========== + // Geetest + // =========== + if config.Instance.Captcha.Geetest.Enabled { + isPass, reason, err := captcha.GeetestCheck(inputVal) + if err != nil { + logrus.Error("[Geetest] 验证发生错误 ", err) + return common.RespError(c, "Geetest API 错误") + } + + if isPass { + // 验证成功 + common.OnCaptchaPass(c) + return common.RespSuccess(c) + } else { + // 验证失败 + common.OnCaptchaFail(c) + return common.RespError(c, "验证失败", common.Map{ + "reason": reason, + }) + } + } + + // =========== + // 图片验证码 + // =========== + isPass := strings.ToLower(inputVal) == common.GetImageCaptchaRealCode(ip) + if isPass { + // 验证码正确 + common.DisposeImageCaptcha(ip) // 销毁图片验证码 + common.OnCaptchaPass(c) + return common.RespSuccess(c) + } else { + // 验证码错误 + common.DisposeImageCaptcha(ip) + common.OnCaptchaFail(c) + return common.RespError(c, "验证码错误", common.Map{ + "img_data": common.GetNewImageCaptchaBase64(ip), + }) + } +} diff --git a/server/handler/comment_add.go b/server/handler/comment_add.go new file mode 100644 index 000000000..d6b9fe7d4 --- /dev/null +++ b/server/handler/comment_add.go @@ -0,0 +1,160 @@ +package handler + +import ( + "strings" + + "github.com/ArtalkJS/ArtalkGo/internal/anti_spam" + "github.com/ArtalkJS/ArtalkGo/internal/config" + "github.com/ArtalkJS/ArtalkGo/internal/entity" + "github.com/ArtalkJS/ArtalkGo/internal/notify_launcher" + "github.com/ArtalkJS/ArtalkGo/internal/query" + "github.com/ArtalkJS/ArtalkGo/internal/utils" + "github.com/ArtalkJS/ArtalkGo/server/common" + "github.com/gofiber/fiber/v2" + "github.com/sirupsen/logrus" +) + +type ParamsAdd struct { + Name string `form:"name"` + Email string `form:"email"` + Link string `form:"link"` + Content string `form:"content" validate:"required"` + Rid uint `form:"rid"` + UA string `form:"ua"` + + PageKey string `form:"page_key" validate:"required"` + PageTitle string `form:"page_title"` + + Token string `form:"token"` + SiteName string + SiteID uint +} + +type ResponseAdd struct { + Comment entity.CookedComment `json:"comment"` +} + +// GET /api/add +func CommentAdd(router fiber.Router) { + router.Post("/add", func(c *fiber.Ctx) error { + var p ParamsAdd + if isOK, resp := common.ParamsDecode(c, &p); !isOK { + return resp + } + + if strings.TrimSpace(p.Name) == "" { + return common.RespError(c, "昵称不能为空") + } + if strings.TrimSpace(p.Email) == "" { + return common.RespError(c, "邮箱不能为空") + } + + if !utils.ValidateEmail(p.Email) { + return common.RespError(c, "Invalid email") + } + if p.Link != "" && !utils.ValidateURL(p.Link) { + return common.RespError(c, "Invalid link") + } + + ip := c.IP() + ua := string(c.Request().Header.UserAgent()) + + // 允许传入修正后的 UA + if p.UA != "" { + ua = p.UA + } + + // record action for limiting action + common.RecordAction(c) + + // use site + common.UseSite(c, &p.SiteName, &p.SiteID, nil) + + // find page + page := query.FindCreatePage(p.PageKey, p.PageTitle, p.SiteName) + + // check if the user is allowed to comment + if isAllowed, resp := common.CheckIsAllowed(c, p.Name, p.Email, page, p.SiteName); !isAllowed { + return resp + } + + // check reply comment + var parentComment entity.Comment + if p.Rid != 0 { + parentComment = query.FindComment(p.Rid) + if parentComment.IsEmpty() { + return common.RespError(c, "找不到父评论") + } + if parentComment.PageKey != p.PageKey { + return common.RespError(c, "与父评论的 pageKey 不一致") + } + if !parentComment.IsAllowReply() { + return common.RespError(c, "不允许回复该评论") + } + } + + // find user + user := query.FindCreateUser(p.Name, p.Email, p.Link) + if user.ID == 0 || page.Key == "" { + logrus.Error("Cannot get user or page") + return common.RespError(c, "评论失败") + } + + // update user + user.Link = p.Link + user.LastIP = ip + user.LastUA = ua + user.Name = p.Name // for 若用户修改用户名大小写 + user.Email = p.Email + query.UpdateUser(&user) + + comment := entity.Comment{ + Content: p.Content, + PageKey: page.Key, + SiteName: p.SiteName, + + UserID: user.ID, + IP: ip, + UA: ua, + + Rid: p.Rid, + + IsPending: false, + IsCollapsed: false, + IsPinned: false, + } + + // default comment type + if !common.CheckIsAdminReq(c) && config.Instance.Moderator.PendingDefault { + // 不是管理员评论 && 配置开启评论默认待审 + comment.IsPending = true + } + + // save to database + err := query.CreateComment(&comment) + if err != nil { + logrus.Error("Save Comment error: ", err) + return common.RespError(c, "评论失败") + } + + // 异步执行 + go func() { + // Page Update + if query.CookPage(&page).URL != "" && page.Title == "" { + query.FetchPageFromURL(&page) + } + + // 垃圾检测 + if !common.CheckIsAdminReq(c) { // 忽略检查管理员 + anti_spam.SyncSpamCheck(&comment, c) // 同步执行 + } + + // 通知发送 + notify_launcher.SendNotify(&comment, &parentComment) + }() + + return common.RespData(c, ResponseAdd{ + Comment: query.CookComment(&comment), + }) + }) +} diff --git a/server/handler/comment_get.go b/server/handler/comment_get.go new file mode 100644 index 000000000..0d698b899 --- /dev/null +++ b/server/handler/comment_get.go @@ -0,0 +1,185 @@ +package handler + +import ( + "github.com/ArtalkJS/ArtalkGo/internal/entity" + "github.com/ArtalkJS/ArtalkGo/internal/query" + "github.com/ArtalkJS/ArtalkGo/server/common" + "github.com/gofiber/fiber/v2" + "gorm.io/gorm" +) + +type ParamsGet struct { + PageKey string `form:"page_key" validate:"required"` + SiteName string + + Limit int `form:"limit"` + Offset int `form:"offset"` + + FlatMode bool `form:"flat_mode"` + SortBy string `form:"sort_by"` // date_asc, date_desc, vote + ViewOnlyAdmin bool `form:"view_only_admin"` // 只看 admin + + Search string `form:"search"` + + // Message Center + Type string `form:"type"` // ["", "all", "mentions", "mine", "pending", "admin_all", "admin_pending"] + Name string `form:"name"` + Email string `form:"email"` + + SiteID uint + SiteAll bool + + IsMsgCenter bool + User *entity.User + IsAdminReq bool +} + +type ResponseGet struct { + Comments []entity.CookedComment `json:"comments"` + Total int64 `json:"total"` + TotalRoots int64 `json:"total_roots"` + Page entity.CookedPage `json:"page"` + Unread []entity.CookedNotify `json:"unread"` + UnreadCount int `json:"unread_count"` + ApiVersion common.Map `json:"api_version"` + Conf common.Map `json:"conf,omitempty"` +} + +// POST /api/get +func CommentGet(router fiber.Router) { + router.Post("/get", func(c *fiber.Ctx) error { + var p ParamsGet + if isOK, resp := common.ParamsDecode(c, &p); !isOK { + return resp + } + + // use site + common.UseSite(c, &p.SiteName, &p.SiteID, &p.SiteAll) + + // handle params + UseCfgFrontend(&p) + + // find page + var page entity.Page + if !p.SiteAll { + page = query.FindPage(p.PageKey, p.SiteName) + if page.IsEmpty() { // if page not found + page = entity.Page{ + Key: p.PageKey, + SiteName: p.SiteName, + } + } + } + + // find user + var user entity.User + if p.Name != "" && p.Email != "" { + user = query.FindUser(p.Name, p.Email) + p.User = &user // init params user field + } + + // check if admin + if common.CheckIsAdminReq(c) { + p.IsAdminReq = true + } + + // check if msg center + if p.Type != "" && p.Name != "" && p.Email != "" { + p.IsMsgCenter = true + p.FlatMode = true // 通知中心强制平铺模式 + } + + // prepare the first query + findScopes := []func(*gorm.DB) *gorm.DB{} + if !p.FlatMode { + // nested_mode prepare the root comments as first query result + findScopes = append(findScopes, RootComments()) + } + if !p.IsMsgCenter { + // pinned comments ignore + findScopes = append(findScopes, func(d *gorm.DB) *gorm.DB { + return d.Where("is_pinned = ?", false) // 因为置顶是独立的查询,这里就不再查) + }) + } + + // search function + if p.Search != "" { + findScopes = append(findScopes, CommentSearchScope(p)) + } + + // get comments for the first query + var comments []entity.Comment + GetCommentQuery(c, p, p.SiteID, findScopes...).Scopes(Paginate(p.Offset, p.Limit)).Find(&comments) + + // prepend the pinned comments + prependPinnedComments(c, p, &comments) + + // cook + cookedComments := query.CookAllComments(comments) + + switch { + case !p.FlatMode: + // ========== + // 层级嵌套模式 + // ========== + + // 获取 comment 子评论 + for _, parent := range cookedComments { // TODO: Read more children, pagination for children comment + children := query.FindCommentChildren(parent.ID, SiteIsolationChecker(c, p), AllowedCommentChecker(c, p)) + cookedComments = append(cookedComments, query.CookAllComments(children)...) + } + + case p.FlatMode: + // ========== + // 平铺模式 + // ========== + + // find linked comments (被引用的评论,不单独显示) + for _, comment := range comments { + if comment.Rid == 0 || entity.ContainsCookedComment(cookedComments, comment.Rid) { + continue + } + + rComment := query.FindComment(comment.Rid, SiteIsolationChecker(c, p)) // 查找被回复的评论 + if rComment.IsEmpty() { + continue + } + + rCooked := query.CookComment(&rComment) + rCooked.Visible = false // 设置为不可见 + cookedComments = append(cookedComments, rCooked) + } + } + + // count comments + total := CountComments(GetCommentQuery(c, p, p.SiteID)) + totalRoots := CountComments(GetCommentQuery(c, p, p.SiteID, RootComments())) + + // mark all as read in msg center + if p.IsMsgCenter { + query.UserNotifyMarkAllAsRead(p.User.ID) + } + + // unread notifies + var unreadNotifies = []entity.CookedNotify{} + if p.User != nil { + unreadNotifies = query.CookAllNotifies(query.FindUnreadNotifies(p.User.ID)) + } + + resp := ResponseGet{ + Comments: cookedComments, + Total: total, + TotalRoots: totalRoots, + Page: query.CookPage(&page), + Unread: unreadNotifies, + UnreadCount: len(unreadNotifies), + ApiVersion: common.GetApiVersionDataMap(), + } + + if p.Offset == 0 { + resp.Conf = common.GetApiPublicConfDataMap(c) + } + + return common.RespData(c, resp) + }) +} diff --git a/http/comment_get_query.go b/server/handler/comment_get_query.go similarity index 68% rename from http/comment_get_query.go rename to server/handler/comment_get_query.go index 46769cd87..fdc315bb5 100644 --- a/http/comment_get_query.go +++ b/server/handler/comment_get_query.go @@ -1,4 +1,4 @@ -package http +package handler import ( "fmt" @@ -7,19 +7,21 @@ import ( "strings" "github.com/ArtalkJS/ArtalkGo/internal/config" + "github.com/ArtalkJS/ArtalkGo/internal/db" "github.com/ArtalkJS/ArtalkGo/internal/entity" "github.com/ArtalkJS/ArtalkGo/internal/query" - "github.com/labstack/echo/v4" + "github.com/ArtalkJS/ArtalkGo/server/common" + "github.com/gofiber/fiber/v2" "gorm.io/gorm" ) // 获取评论查询实例 -func GetCommentQuery(a *action, c echo.Context, p ParamsGet, siteID uint, scopes ...func(*gorm.DB) *gorm.DB) *gorm.DB { - db := a.db.Model(&entity.Comment{}) +func GetCommentQuery(c *fiber.Ctx, p ParamsGet, siteID uint, scopes ...func(*gorm.DB) *gorm.DB) *gorm.DB { + q := db.DB().Model(&entity.Comment{}) - db.Scopes(SiteIsolationScope(c, p), AllowedComment(c, p)) - db.Order(GetSortRuleSQL(p.SortBy, "created_at DESC")) // 排序规则 - db.Scopes(scopes...) + q.Scopes(SiteIsolationScope(c, p), AllowedComment(c, p)) + q.Order(GetSortRuleSQL(p.SortBy, "created_at DESC")) // 排序规则 + q.Scopes(scopes...) switch { case !p.IsMsgCenter: @@ -30,10 +32,10 @@ func GetCommentQuery(a *action, c echo.Context, p ParamsGet, siteID uint, scopes // 只看管理员功能 if p.ViewOnlyAdmin { adminIDs := query.GetAllAdminIDs() // 获取管理员列表 - db.Where("user_id IN ?", adminIDs) // 只允许管理员 user_id + q.Where("user_id IN ?", adminIDs) // 只允许管理员 user_id } - db.Where("page_key = ?", p.PageKey) + q.Where("page_key = ?", p.PageKey) case p.IsMsgCenter: // ========== @@ -41,35 +43,35 @@ func GetCommentQuery(a *action, c echo.Context, p ParamsGet, siteID uint, scopes // ========== user := p.User if user == nil || user.IsEmpty() { - return db.Where("id = 0") // user not found + return q.Where("id = 0") // user not found } // admin_only 检测 if strings.HasPrefix(p.Type, "admin_") { - if !p.IsAdminReq || !IsAdminHasSiteAccess(c, p.SiteName) { - return db.Where("id = 0") + if !p.IsAdminReq || !common.IsAdminHasSiteAccess(c, p.SiteName) { + return q.Where("id = 0") } } switch p.Type { case "all": - db.Where("rid IN (?) OR user_id = ?", query.GetUserAllCommentIDs(user.ID), user.ID) + q.Where("rid IN (?) OR user_id = ?", query.GetUserAllCommentIDs(user.ID), user.ID) case "mentions": - db.Where("rid IN (?) AND user_id != ?", query.GetUserAllCommentIDs(user.ID), user.ID) + q.Where("rid IN (?) AND user_id != ?", query.GetUserAllCommentIDs(user.ID), user.ID) case "mine": - db.Where("user_id = ?", user.ID) + q.Where("user_id = ?", user.ID) case "pending": - db.Where("user_id = ? AND is_pending = ?", user.ID, true) + q.Where("user_id = ? AND is_pending = ?", user.ID, true) case "admin_all": case "admin_pending": - db.Where("is_pending = ?", true) + q.Where("is_pending = ?", true) default: - return db.Where("id = 0") + return q.Where("id = 0") } } - return db + return q } // 根评论 Root comments @@ -80,9 +82,9 @@ func RootComments() func(db *gorm.DB) *gorm.DB { } // 允许的评论 -func AllowedComment(c echo.Context, p ParamsGet) func(db *gorm.DB) *gorm.DB { +func AllowedComment(c *fiber.Ctx, p ParamsGet) func(db *gorm.DB) *gorm.DB { return func(db *gorm.DB) *gorm.DB { - if CheckIsAdminReq(c) { + if common.CheckIsAdminReq(c) { return db // 管理员显示全部 } @@ -95,9 +97,9 @@ func AllowedComment(c echo.Context, p ParamsGet) func(db *gorm.DB) *gorm.DB { } } -func AllowedCommentChecker(c echo.Context, p ParamsGet) func(*entity.Comment) bool { +func AllowedCommentChecker(c *fiber.Ctx, p ParamsGet) func(*entity.Comment) bool { return func(comment *entity.Comment) bool { - if CheckIsAdminReq(c) { + if common.CheckIsAdminReq(c) { return true // 管理员显示全部 } @@ -115,9 +117,9 @@ func AllowedCommentChecker(c echo.Context, p ParamsGet) func(*entity.Comment) bo } } -func SiteIsolationChecker(c echo.Context, p ParamsGet) func(*entity.Comment) bool { +func SiteIsolationChecker(c *fiber.Ctx, p ParamsGet) func(*entity.Comment) bool { return func(comment *entity.Comment) bool { - if CheckIsAdminReq(c) && p.SiteAll { + if common.CheckIsAdminReq(c) && p.SiteAll { return true // 仅管理员支持取消站点隔离 } @@ -130,9 +132,9 @@ func SiteIsolationChecker(c echo.Context, p ParamsGet) func(*entity.Comment) boo } // 站点隔离 -func SiteIsolationScope(c echo.Context, p ParamsGet) func(db *gorm.DB) *gorm.DB { +func SiteIsolationScope(c *fiber.Ctx, p ParamsGet) func(db *gorm.DB) *gorm.DB { return func(db *gorm.DB) *gorm.DB { - if CheckIsAdminReq(c) && p.SiteAll { + if common.CheckIsAdminReq(c) && p.SiteAll { return db // 仅管理员支持取消站点隔离 } @@ -162,9 +164,9 @@ func CountComments(db *gorm.DB) int64 { } // 评论搜索 -func CommentSearchScope(a *action, p ParamsGet) func(d *gorm.DB) *gorm.DB { +func CommentSearchScope(p ParamsGet) func(d *gorm.DB) *gorm.DB { var userIds []uint - a.db.Model(&entity.User{}).Where( + db.DB().Model(&entity.User{}).Where( "LOWER(name) = LOWER(?) OR LOWER(email) = LOWER(?)", p.Search, p.Search, ).Pluck("id", &userIds) @@ -192,13 +194,13 @@ func Paginate(offset int, limit int) func(db *gorm.DB) *gorm.DB { } // 插入置顶的评论 -func prependPinnedComments(a *action, c echo.Context, p ParamsGet, comments *[]entity.Comment) { +func prependPinnedComments(c *fiber.Ctx, p ParamsGet, comments *[]entity.Comment) { if p.IsMsgCenter || p.Offset != 0 { return // 通知中心关闭置顶 & 仅在分页的首页加入置顶评论 } pinnedComments := []entity.Comment{} - GetCommentQuery(a, c, p, p.SiteID).Where("is_pinned = ?", true).Find(&pinnedComments) + GetCommentQuery(c, p, p.SiteID).Where("is_pinned = ?", true).Find(&pinnedComments) if len(pinnedComments) == 0 { return // 没有置顶评论 } @@ -233,7 +235,7 @@ func UseCfgFrontend(p *ParamsGet) { } // pagination.pageSize - cfgPageSizeStr := fmt.Sprintf("%v", pagination.(Map)["pageSize"]) + cfgPageSizeStr := fmt.Sprintf("%v", pagination.(common.Map)["pageSize"]) confPageSize, err := strconv.Atoi(cfgPageSizeStr) if err == nil && confPageSize > 0 { p.Limit = confPageSize diff --git a/server/handler/conf.go b/server/handler/conf.go new file mode 100644 index 000000000..10be6ad7d --- /dev/null +++ b/server/handler/conf.go @@ -0,0 +1,13 @@ +package handler + +import ( + "github.com/ArtalkJS/ArtalkGo/server/common" + "github.com/gofiber/fiber/v2" +) + +// GET /conf +func Conf(router fiber.Router) { + router.All("/conf", func(c *fiber.Ctx) error { + return common.RespData(c, common.GetApiPublicConfDataMap(c)) + }) +} diff --git a/server/handler/img_upload.go b/server/handler/img_upload.go new file mode 100644 index 000000000..7e0b14dfa --- /dev/null +++ b/server/handler/img_upload.go @@ -0,0 +1,225 @@ +package handler + +import ( + "fmt" + "io" + "net/http" + "os" + "os/exec" + "path" + "strings" + "syscall" + "time" + + "github.com/ArtalkJS/ArtalkGo/internal/config" + "github.com/ArtalkJS/ArtalkGo/internal/utils" + "github.com/ArtalkJS/ArtalkGo/server/common" + "github.com/gofiber/fiber/v2" + "github.com/sirupsen/logrus" +) + +type ParamsImgUpload struct { + Name string `form:"name" validate:"required"` + Email string `form:"email" validate:"required"` + + PageKey string `form:"page_key" validate:"required"` + PageTitle string `form:"page_title"` + + SiteName string + + SiteID uint + SiteAll bool +} + +// POST /api/img-upl +func ImgUpload(router fiber.Router) { + router.Post("/img-upload", func(c *fiber.Ctx) error { + // 功能开关 (管理员始终开启) + if !config.Instance.ImgUpload.Enabled && !common.CheckIsAdminReq(c) { + return common.RespError(c, "禁止图片上传", common.Map{ + "img_upload_enabled": false, + }) + } + + // 传入参数解析 + var p ParamsImgUpload + if isOK, resp := common.ParamsDecode(c, &p); !isOK { + return resp + } + + if !utils.ValidateEmail(p.Email) { + return common.RespError(c, "Invalid email") + } + + // use site + common.UseSite(c, &p.SiteName, &p.SiteID, &p.SiteAll) + + // 记录请求次数 (for 请求频率限制) + common.RecordAction(c) + + // find page + // page := entity.FindPage(p.PageKey, p.PageTitle) + // ip := c.RealIP() + // ua := c.Request().UserAgent() + + // 图片大小限制 (Based on content length) + if config.Instance.ImgUpload.MaxSize != 0 { + if int64(c.Request().Header.ContentLength()) > config.Instance.ImgUpload.MaxSize*1024*1024 { + return common.RespError(c, fmt.Sprintf("图片大小超过限制 %dMB", config.Instance.ImgUpload.MaxSize)) + } + } + + // 获取 Form + file, err := c.FormFile("file") + if err != nil { + logrus.Error(err) + return common.RespError(c, "文件获取失败") + } + + // 打开文件 + src, err := file.Open() + if err != nil { + logrus.Error(err) + return common.RespError(c, "文件打开失败") + } + defer src.Close() + + // 读取文件 + buf, err := io.ReadAll(src) + if err != nil { + logrus.Error(err) + return common.RespError(c, "文件读取失败") + } + + // 大小限制 (Based on content read) + if config.Instance.ImgUpload.MaxSize != 0 { + if int64(len(buf)) > config.Instance.ImgUpload.MaxSize*1024*1024 { + return common.RespError(c, fmt.Sprintf("图片大小超过限制 %dMB", config.Instance.ImgUpload.MaxSize)) + } + } + + // 文件格式判断 + // @link https://mimesniff.spec.whatwg.org/ + // @link https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Basics_of_HTTP/MIME_types + fileMine := http.DetectContentType(buf) + allowMines := []string{ + "image/jpeg", "image/png", "image/gif", "image/webp", "image/bmp", + // "image/svg+xml", + } + if !utils.ContainsStr(allowMines, fileMine) { + return common.RespError(c, "不支持的格式") + } + + // 图片文件名 + mineToExts := map[string]string{ + "image/jpeg": ".jpg", + "image/png": ".png", + "image/gif": ".gif", + "image/webp": ".webp", + "image/bmp": ".bmp", + // "image/svg+xml": ".svg", + } + + t := time.Now() + filename := t.Format("20060102-150405.000") + mineToExts[fileMine] + + // 创建图片目标文件 + if err := utils.EnsureDir(config.Instance.ImgUpload.Path); err != nil { + logrus.Error(err) + return common.RespError(c, "创建图片存放文件夹失败") + } + + fileFullPath := strings.TrimSuffix(config.Instance.ImgUpload.Path, "/") + "/" + filename + dst, err := os.Create(fileFullPath) + if err != nil { + logrus.Error(err) + return common.RespError(c, "图片文件创建失败") + } + defer dst.Close() + + // 写入图片文件 + if _, err = dst.Write(buf); err != nil { + logrus.Error(err) + return common.RespError(c, "图片文件写入失败") + } + + // 生成外部可访问链接 + baseURL := config.Instance.ImgUpload.PublicPath + if baseURL == "" { + baseURL = config.IMG_UPLOAD_PUBLIC_PATH + } + imgURL := path.Join(baseURL, filename) + + // 使用 upgit + if config.Instance.ImgUpload.Upgit.Enabled { + upgitURL := execUpgitUpload(fileFullPath) + if upgitURL == "" || !utils.ValidateURL(upgitURL) { + // 上传失败,删除源图片文件 + var err = os.Remove(fileFullPath) + if err != nil { + logrus.Error(err) + } + + logrus.Error("[IMG_UPLOAD] [upgit] upgit output: ", upgitURL) + return common.RespError(c, "图片通过 upgit 上传失败") + } + + // 上传成功,删除本地文件 + if config.Instance.ImgUpload.Upgit.DelLocal { + var err = os.Remove(fileFullPath) + if err != nil { + logrus.Error(err) + } + } + + // 使用从 upgit 获取的图片 URL + imgURL = upgitURL + } + + // 响应数据 + return common.RespData(c, common.Map{ + "img_file": filename, + "img_url": imgURL, + }) + }) +} + +// 调用 upgit 上传图片获得 URL +func execUpgitUpload(filename string) string { + LogTag := "[IMG_UPLOAD] [upgit] " + + // 处理参数 + cmdStrSplitted := strings.Split(config.Instance.ImgUpload.Upgit.Exec, " ") + execApp := cmdStrSplitted[0] + execArgs := []string{} + for i, arg := range cmdStrSplitted { + if i > 0 { + execArgs = append(execArgs, arg) + } + } + execArgs = append(execArgs, filename) + + // 执行命令 + cmd := exec.Command(execApp, execArgs...) + stdout, _ := cmd.StdoutPipe() + + if err := cmd.Start(); err != nil { + logrus.Error(LogTag, "cmd.Start: ", err) + return "" + } + + result, _ := io.ReadAll(stdout) + if err := cmd.Wait(); err != nil { + if exiterr, ok := err.(*exec.ExitError); ok { + if status, ok := exiterr.Sys().(syscall.WaitStatus); ok { + logrus.Error(LogTag, "Exit Status: ", status.ExitStatus()) + } + } else { + logrus.Error(LogTag, "cmd.Wait: ", err) + } + + return "" + } + + return strings.TrimSpace(string(result)) +} diff --git a/server/handler/mark_read.go b/server/handler/mark_read.go new file mode 100644 index 000000000..231b9ae4b --- /dev/null +++ b/server/handler/mark_read.go @@ -0,0 +1,65 @@ +package handler + +import ( + "github.com/ArtalkJS/ArtalkGo/internal/query" + "github.com/ArtalkJS/ArtalkGo/server/common" + "github.com/gofiber/fiber/v2" +) + +type ParamsMarkRead struct { + NotifyKey string `form:"notify_key"` + + Name string `form:"name"` + Email string `form:"email"` + AllRead bool `form:"all_read"` + + SiteName string + SiteID uint + SiteAll bool +} + +// POST /api/mark-read +func MarkRead(router fiber.Router) { + router.Post("/mark-read", func(c *fiber.Ctx) error { + var p ParamsMarkRead + if isOK, resp := common.ParamsDecode(c, &p); !isOK { + return resp + } + + // use site + common.UseSite(c, &p.SiteName, &p.SiteID, &p.SiteAll) + + // all read + if p.AllRead { + if p.Name == "" || p.Email == "" { + return common.RespError(c, "need username and email") + } + + user := query.FindUser(p.Name, p.Email) + err := query.UserNotifyMarkAllAsRead(user.ID) + if err != nil { + return common.RespError(c, err.Error()) + } + + return common.RespSuccess(c) + } + + // find notify + notify := query.FindNotifyByKey(p.NotifyKey) + if notify.IsEmpty() { + return common.RespError(c, "notify key is wrong") + } + + if notify.IsRead { + return common.RespSuccess(c) + } + + // update notify + err := query.NotifySetRead(¬ify) + if err != nil { + return common.RespError(c, "notify save error") + } + + return common.RespSuccess(c) + }) +} diff --git a/server/handler/pv.go b/server/handler/pv.go new file mode 100644 index 000000000..8973192b6 --- /dev/null +++ b/server/handler/pv.go @@ -0,0 +1,42 @@ +package handler + +import ( + "github.com/ArtalkJS/ArtalkGo/internal/query" + "github.com/ArtalkJS/ArtalkGo/server/common" + "github.com/gofiber/fiber/v2" +) + +type ParamsPV struct { + PageKey string `form:"page_key" validate:"required"` + PageTitle string `form:"page_title"` + + SiteName string + SiteID uint + SiteAll bool +} + +// POST /api/pv +func PV(router fiber.Router) { + router.Post("/pv", func(c *fiber.Ctx) error { + var p ParamsPV + if isOK, resp := common.ParamsDecode(c, &p); !isOK { + return resp + } + + // use site + common.UseSite(c, &p.SiteName, &p.SiteID, &p.SiteAll) + + // find page + page := query.FindCreatePage(p.PageKey, p.PageTitle, p.SiteName) + + // ip := c.RealIP() + // ua := c.Request().UserAgent() + + page.PV++ + query.UpdatePage(&page) + + return common.RespData(c, common.Map{ + "pv": page.PV, + }) + }) +} diff --git a/server/handler/stat.go b/server/handler/stat.go new file mode 100644 index 000000000..1e50e543e --- /dev/null +++ b/server/handler/stat.go @@ -0,0 +1,164 @@ +package handler + +import ( + "github.com/ArtalkJS/ArtalkGo/internal/config" + "github.com/ArtalkJS/ArtalkGo/internal/db" + "github.com/ArtalkJS/ArtalkGo/internal/entity" + "github.com/ArtalkJS/ArtalkGo/internal/query" + "github.com/ArtalkJS/ArtalkGo/internal/utils" + "github.com/ArtalkJS/ArtalkGo/server/common" + "github.com/gofiber/fiber/v2" + "gorm.io/gorm" +) + +type ParamsStat struct { + Type string `form:"type" validate:"required"` + + SiteName string + PageKeys string `form:"page_keys"` + + Limit int `form:"limit"` + + SiteID uint + SiteAll bool +} + +// POST /api/stat +func Stat(router fiber.Router) { + router.Post("/stat", func(c *fiber.Ctx) error { + var p ParamsStat + if isOK, resp := common.ParamsDecode(c, &p); !isOK { + return resp + } + + // use site + common.UseSite(c, &p.SiteName, &p.SiteID, &p.SiteAll) + + // Limit 限定 + if p.Limit <= 0 { + p.Limit = 5 + } + if p.Limit > 100 { + p.Limit = 100 + } + + // 公共查询规则 + QueryPages := func(d *gorm.DB) *gorm.DB { + return d.Model(&entity.Page{}).Where("site_name = ?", p.SiteName) + } + QueryComments := func(d *gorm.DB) *gorm.DB { + return d.Model(&entity.Comment{}).Where("site_name = ? AND is_pending = ?", p.SiteName, false) + } + QueryOrderRand := func(d *gorm.DB) *gorm.DB { + if config.Instance.DB.Type == config.TypeSQLite { + return d.Order("RANDOM()") // SQLite case + } else { + return d.Order("RAND()") + } + } + + switch p.Type { + case "latest_comments": + // 最新评论 + var comments []entity.Comment + db.DB().Scopes(QueryComments). + Order("created_at DESC"). + Limit(p.Limit). + Find(&comments) + + return common.RespData(c, query.CookAllComments(comments)) + + case "latest_pages": + // 最新页面 + var pages []entity.Page + db.DB().Scopes(QueryPages). + Order("created_at DESC"). + Limit(p.Limit). + Find(&pages) + + return common.RespData(c, query.CookAllPages(pages)) + + case "pv_most_pages": + // PV 数最多的页面 + var pages []entity.Page + db.DB().Scopes(QueryPages). + Order("pv DESC"). + Limit(p.Limit). + Find(&pages) + + return common.RespData(c, query.CookAllPages(pages)) + + case "comment_most_pages": + // 评论数最多的页面 + var pages []entity.Page + db.DB().Raw( + "SELECT * FROM pages p WHERE p.site_name = ? ORDER BY (SELECT COUNT(*) FROM comments c WHERE c.page_key = p.key AND c.is_pending = ?) DESC LIMIT ?", + p.SiteName, false, p.Limit, + ).Find(&pages) + + return common.RespData(c, query.CookAllPages(pages)) + + case "page_pv": + // 查询页面的 PV 数 + keys := utils.SplitAndTrimSpace(p.PageKeys, ",") + pvs := map[string]int{} + for _, k := range keys { + page := query.FindPage(k, p.SiteName) + if !page.IsEmpty() { + pvs[k] = page.PV + } else { + pvs[k] = 0 + } + } + + return common.RespData(c, pvs) + + case "site_pv": + // 全站 PV 数 + var pv int64 + db.DB().Raw("SELECT SUM(pv) FROM pages WHERE site_name = ?", p.SiteName).Row().Scan(&pv) + + return common.RespData(c, pv) + + case "page_comment": + // 查询页面的评论数 + keys := utils.SplitAndTrimSpace(p.PageKeys, ",") + counts := map[string]int64{} + for _, k := range keys { + var count int64 + db.DB().Scopes(QueryComments).Where("page_key = ?", k).Count(&count) + + counts[k] = count + } + + return common.RespData(c, counts) + + case "site_comment": + // 全站评论数 + var count int64 + db.DB().Scopes(QueryComments).Count(&count) + + return common.RespData(c, count) + + case "rand_comments": + // 随机评论 + var comments []entity.Comment + db.DB().Scopes(QueryComments, QueryOrderRand). + Limit(p.Limit). + Find(&comments) + + return common.RespData(c, query.CookAllComments(comments)) + + case "rand_pages": + // 随机页面 + var pages []entity.Page + db.DB().Scopes(QueryPages, QueryOrderRand). + Limit(p.Limit). + Find(&pages) + + return common.RespData(c, query.CookAllPages(pages)) + } + + return common.RespError(c, "invalid type") + }) +} diff --git a/server/handler/user_get.go b/server/handler/user_get.go new file mode 100644 index 000000000..a12ef5253 --- /dev/null +++ b/server/handler/user_get.go @@ -0,0 +1,45 @@ +package handler + +import ( + "github.com/ArtalkJS/ArtalkGo/internal/query" + "github.com/ArtalkJS/ArtalkGo/server/common" + "github.com/gofiber/fiber/v2" +) + +type ParamsUserGet struct { + Name string `form:"name"` + Email string `form:"email"` +} + +// POST /api/user-get +func UserGet(router fiber.Router) { + router.Post("/user-get", func(c *fiber.Ctx) error { + var p ParamsUserGet + if isOK, resp := common.ParamsDecode(c, &p); !isOK { + return resp + } + + // login status + isLogin := !common.GetUserByReq(c).IsEmpty() + + user := query.FindUser(p.Name, p.Email) + if user.IsEmpty() { + return common.RespData(c, common.Map{ + "user": nil, + "is_login": isLogin, + "unread": []interface{}{}, + "unread_count": 0, + }) + } + + // unread notifies + unreadNotifies := query.CookAllNotifies(query.FindUnreadNotifies(user.ID)) + + return common.RespData(c, common.Map{ + "user": query.CookUser(&user), + "is_login": isLogin, + "unread": unreadNotifies, + "unread_count": len(unreadNotifies), + }) + }) +} diff --git a/server/handler/user_login.go b/server/handler/user_login.go new file mode 100644 index 000000000..4d6560f10 --- /dev/null +++ b/server/handler/user_login.go @@ -0,0 +1,160 @@ +package handler + +import ( + "crypto/md5" + "fmt" + "strings" + "time" + + "github.com/ArtalkJS/ArtalkGo/internal/config" + "github.com/ArtalkJS/ArtalkGo/internal/entity" + "github.com/ArtalkJS/ArtalkGo/internal/query" + "github.com/ArtalkJS/ArtalkGo/internal/utils" + "github.com/ArtalkJS/ArtalkGo/server/common" + "github.com/gofiber/fiber/v2" + "golang.org/x/crypto/bcrypt" +) + +type ParamsLogin struct { + Name string `form:"name"` + Email string `form:"email" validate:"required"` + Password string `form:"password" validate:"required"` +} + +// POST /api/login +func UserLogin(router fiber.Router) { + router.Post("/login", func(c *fiber.Ctx) error { + var p ParamsLogin + if isOK, resp := common.ParamsDecode(c, &p); !isOK { + return resp + } + + // 账户读取 + var user entity.User + if p.Name == "" { + // 仅 Email 的查询 + if !utils.ValidateEmail(p.Email) { + return common.RespError(c, "请输入正确的邮箱") + } + users := query.FindUsersByEmail(p.Email) + if len(users) == 1 { + // 仅有一个 email 匹配的用户 + user = users[0] + } else if len(users) > 1 { + // 存在多个 email 匹配的用户 + userNames := []string{} + for _, u := range users { + userNames = append(userNames, u.Name) + } + return common.RespError(c, "需要选择用户名", common.Map{ + // 前端需做处理让用户选择用户名, + // 之后再发起带 name 参数的请求 + "need_name_select": userNames, + }) + } + } else { + // Name + Email 的精准查询 + user = query.FindUser(p.Name, p.Email) // name = ? AND email = ? + } + + // record action for limiting action + common.RecordAction(c) + + if user.IsEmpty() { + return common.RespError(c, "验证失败") + } + + // 密码验证 + bcryptPrefix := "(bcrypt)" + md5Prefix := "(md5)" + passwordOK := false + switch { + case strings.HasPrefix(user.Password, bcryptPrefix): + err := bcrypt.CompareHashAndPassword( + []byte(strings.TrimPrefix(user.Password, bcryptPrefix)), + []byte(p.Password), + ) + + if err == nil { + passwordOK = true + } + case strings.HasPrefix(user.Password, md5Prefix): + if strings.EqualFold(strings.TrimPrefix(user.Password, md5Prefix), + fmt.Sprintf("%x", md5.Sum([]byte(p.Password)))) { + passwordOK = true + } + default: + if user.Password == p.Password { + passwordOK = true + } + } + + if !passwordOK { + return common.RespError(c, "验证失败") + } + + jwtToken := common.LoginGetUserToken(user) + setAuthCookie(c, jwtToken, time.Now().Add(time.Second*time.Duration(config.Instance.LoginTimeout))) + + return common.RespData(c, common.Map{ + "token": jwtToken, + "user": query.CookUser(&user), + }) + }) +} + +func setAuthCookie(c *fiber.Ctx, jwtToken string, expires time.Time) { + if !config.Instance.Cookie.Enabled { + return + } + + // save jwt token to cookie + cookie := new(fiber.Cookie) + cookie.Name = config.COOKIE_KEY_ATK_AUTH + cookie.Value = jwtToken + cookie.Expires = expires + + // @see https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Cookies + // @see https://owasp.org/www-project-web-security-testing-guide/v41/4-Web_Application_Security_Testing/06-Session_Management_Testing/02-Testing_for_Cookies_Attributes + cookie.Path = "/" + cookie.HTTPOnly = true // prevent XSS + cookie.Secure = true // https only + cookie.SameSite = "" // for cors-request + + // @note cookie secure is not working on localhost + // @see https://bugs.chromium.org/p/chromium/issues/detail?id=1177877#c7 + + c.Cookie(cookie) +} + +func HashPassword(password string) (string, error) { + bytes, err := bcrypt.GenerateFromPassword([]byte(password), 14) + return string(bytes), err +} + +type ParamsLoginStatus struct { + Name string `form:"name"` + Email string `form:"email"` +} + +// 获取当前登录状态 +// +// POST /api/login-status +func UserLoginStatus(router fiber.Router) { + router.Post("/login-status", func(c *fiber.Ctx) error { + var p ParamsLoginStatus + if isOK, resp := common.ParamsDecode(c, &p); !isOK { + return resp + } + + isAdmin := false + if p.Email != "" && p.Name != "" { + isAdmin = query.IsAdminUserByNameEmail(p.Name, p.Email) + } + + return common.RespData(c, common.Map{ + "is_admin": isAdmin, + "is_login": common.CheckIsAdminReq(c), + }) + }) +} diff --git a/server/handler/user_logout.go b/server/handler/user_logout.go new file mode 100644 index 000000000..9411c9137 --- /dev/null +++ b/server/handler/user_logout.go @@ -0,0 +1,28 @@ +package handler + +import ( + "time" + + "github.com/ArtalkJS/ArtalkGo/internal/config" + "github.com/ArtalkJS/ArtalkGo/server/common" + "github.com/gofiber/fiber/v2" +) + +// POST /api/logout +func UserLogout(router fiber.Router) { + router.Post("/logout", func(c *fiber.Ctx) error { + + if !config.Instance.Cookie.Enabled { + return common.RespError(c, "API 未启用 Cookie") + } + + if common.GetJwtStrByReqCookie(c) == "" { + return common.RespError(c, "未登录,无需注销") + } + + // same as login, remove cookie + setAuthCookie(c, "", time.Now().AddDate(0, 0, -1)) + + return common.RespSuccess(c) + }) +} diff --git a/server/handler/version.go b/server/handler/version.go new file mode 100644 index 000000000..4fa75d297 --- /dev/null +++ b/server/handler/version.go @@ -0,0 +1,13 @@ +package handler + +import ( + "github.com/ArtalkJS/ArtalkGo/server/common" + "github.com/gofiber/fiber/v2" +) + +// GET /version +func Version(router fiber.Router) { + router.All("/version", func(c *fiber.Ctx) error { + return c.Status(fiber.StatusOK).JSON(common.GetApiVersionDataMap()) + }) +} diff --git a/server/handler/vote.go b/server/handler/vote.go new file mode 100644 index 000000000..4802022a4 --- /dev/null +++ b/server/handler/vote.go @@ -0,0 +1,132 @@ +package handler + +import ( + "strings" + + "github.com/ArtalkJS/ArtalkGo/internal/db" + "github.com/ArtalkJS/ArtalkGo/internal/entity" + "github.com/ArtalkJS/ArtalkGo/internal/query" + "github.com/ArtalkJS/ArtalkGo/server/common" + "github.com/gofiber/fiber/v2" +) + +type ParamsVote struct { + TargetID uint `form:"target_id" validate:"required"` + FullType string `form:"type"` + + Name string `form:"name"` + Email string `form:"email"` + + SiteName string + SiteID uint + SiteAll bool +} + +// POST /api/vote +func Vote(router fiber.Router) { + router.Post("/vote", func(c *fiber.Ctx) error { + var p ParamsVote + if isOK, resp := common.ParamsDecode(c, &p); !isOK { + return resp + } + + // use site + common.UseSite(c, &p.SiteName, &p.SiteID, &p.SiteAll) + + // find user + var user entity.User + if p.Name != "" && p.Email != "" { + user = query.FindCreateUser(p.Name, p.Email, "") + } + + ip := c.IP() + + // check type + isVoteComment := strings.HasPrefix(p.FullType, "comment_") + isVotePage := strings.HasPrefix(p.FullType, "page_") + isUp := strings.HasSuffix(p.FullType, "_up") + isDown := strings.HasSuffix(p.FullType, "_down") + voteTo := strings.TrimSuffix(strings.TrimSuffix(p.FullType, "_up"), "_down") + voteType := strings.TrimPrefix(strings.TrimPrefix(p.FullType, "comment_"), "page_") + + if !isUp && !isDown { + return common.RespError(c, "unknown type") + } + + var comment entity.Comment + var page entity.Page + + switch { + case isVoteComment: + comment = query.FindComment(p.TargetID) + if comment.IsEmpty() { + return common.RespError(c, "comment not found") + } + case isVotePage: + page = query.FindPageByID(p.TargetID) + if page.IsEmpty() { + return common.RespError(c, "page not found") + } + default: + return common.RespError(c, "unknown type") + } + + // sync target model field value + save := func(up int, down int) { + switch { + case isVoteComment: + comment.VoteUp = up + comment.VoteDown = down + query.UpdateComment(&comment) + case isVotePage: + page.VoteUp = up + page.VoteDown = down + query.UpdatePage(&page) + } + } + + createNew := func(t string) error { + // create new vote record + _, err := query.NewVote(p.TargetID, entity.VoteType(t), user.ID, string(c.Request().Header.UserAgent()), ip) + + return err + } + + // un-vote + var avaliableVotes []entity.Vote + db.DB().Where("target_id = ? AND type LIKE ? AND ip = ?", p.TargetID, voteTo+"%", ip).Find(&avaliableVotes) + if len(avaliableVotes) > 0 { + for _, v := range avaliableVotes { + db.DB().Unscoped().Delete(&v) + } + + avaVoteType := strings.TrimPrefix(strings.TrimPrefix(string(avaliableVotes[0].Type), "comment_"), "page_") + if voteType != avaVoteType { + createNew(p.FullType) + } + + up, down := query.GetVoteNumUpDown(p.TargetID, voteTo) + save(up, down) + + common.RecordAction(c) + + return common.RespData(c, common.Map{ + "up": up, + "down": down, + }) + } + + createNew(p.FullType) + + // sync + up, down := query.GetVoteNumUpDown(p.TargetID, voteTo) + save(up, down) + + common.RecordAction(c) + + return common.RespData(c, common.Map{ + "up": up, + "down": down, + }) + }) +} diff --git a/server/middleware/admin.go b/server/middleware/admin.go new file mode 100644 index 000000000..38f3ea769 --- /dev/null +++ b/server/middleware/admin.go @@ -0,0 +1,16 @@ +package middleware + +import ( + "github.com/ArtalkJS/ArtalkGo/server/common" + "github.com/gofiber/fiber/v2" +) + +func AdminOnlyMiddleware() fiber.Handler { + return func(c *fiber.Ctx) error { + if !common.CheckIsAdminReq(c) { + return common.RespError(c, "需要验证管理员身份", common.Map{"need_login": true}) + } + + return c.Next() + } +} diff --git a/server/middleware/cors.go b/server/middleware/cors.go new file mode 100644 index 000000000..781abb7eb --- /dev/null +++ b/server/middleware/cors.go @@ -0,0 +1,12 @@ +package middleware + +import ( + "github.com/ArtalkJS/ArtalkGo/server/common" + "github.com/ArtalkJS/ArtalkGo/server/middleware/cors" + "github.com/gofiber/fiber/v2" +) + +func CorsMiddleware() func(*fiber.Ctx) error { + common.ReloadCorsAllowOrigins() + return cors.New(common.CorsConf) +} diff --git a/server/middleware/cors/cors.go b/server/middleware/cors/cors.go new file mode 100644 index 000000000..a15dbd803 --- /dev/null +++ b/server/middleware/cors/cors.go @@ -0,0 +1,168 @@ +package cors + +import ( + "net/http" + "strconv" + "strings" + + "github.com/gofiber/fiber/v2" +) + +// Config defines the config for middleware. +type Config struct { + // Next defines a function to skip this middleware when returned true. + // + // Optional. Default: nil + Next func(c *fiber.Ctx) bool + + // AllowOrigin defines a list of origins that may access the resource. + // + // Optional. Default value "*" + AllowOrigins string + + // AllowMethods defines a list methods allowed when accessing the resource. + // This is used in response to a preflight request. + // + // Optional. Default value "GET,POST,HEAD,PUT,DELETE,PATCH" + AllowMethods string + + // AllowHeaders defines a list of request headers that can be used when + // making the actual request. This is in response to a preflight request. + // + // Optional. Default value "". + AllowHeaders string + + // AllowCredentials indicates whether or not the response to the request + // can be exposed when the credentials flag is true. When used as part of + // a response to a preflight request, this indicates whether or not the + // actual request can be made using credentials. + // + // Optional. Default value false. + AllowCredentials bool + + // ExposeHeaders defines a whitelist headers that clients are allowed to + // access. + // + // Optional. Default value "". + ExposeHeaders string + + // MaxAge indicates how long (in seconds) the results of a preflight request + // can be cached. + // + // Optional. Default value 0. + MaxAge int +} + +// ConfigDefault is the default config +var ConfigDefault = Config{ + Next: nil, + AllowOrigins: "*", + AllowMethods: strings.Join([]string{ + fiber.MethodGet, + fiber.MethodPost, + fiber.MethodHead, + fiber.MethodPut, + fiber.MethodDelete, + fiber.MethodPatch, + }, ","), + AllowHeaders: "", + AllowCredentials: false, + ExposeHeaders: "", + MaxAge: 0, +} + +// New creates a new middleware handler +func New(config *Config) fiber.Handler { + cfg := config + + // Set default values + if cfg.AllowMethods == "" { + cfg.AllowMethods = ConfigDefault.AllowMethods + } + if cfg.AllowOrigins == "" { + cfg.AllowOrigins = ConfigDefault.AllowOrigins + } + + // Convert string to slice + allowOrigins := strings.Split(strings.ReplaceAll(cfg.AllowOrigins, " ", ""), ",") + + // Strip white spaces + allowMethods := strings.ReplaceAll(cfg.AllowMethods, " ", "") + allowHeaders := strings.ReplaceAll(cfg.AllowHeaders, " ", "") + exposeHeaders := strings.ReplaceAll(cfg.ExposeHeaders, " ", "") + + // Convert int to string + maxAge := strconv.Itoa(cfg.MaxAge) + + // Return new handler + return func(c *fiber.Ctx) error { + // Don't execute middleware if Next returns true + if cfg.Next != nil && cfg.Next(c) { + return c.Next() + } + + // Get origin header + origin := c.Get(fiber.HeaderOrigin) + allowOrigin := "" + + // Check allowed origins + for _, o := range allowOrigins { + if o == "*" && cfg.AllowCredentials { + allowOrigin = origin + break + } + if o == "*" || o == origin { + allowOrigin = o + break + } + if matchSubdomain(origin, o) { + allowOrigin = origin + break + } + } + + // Simple request + if c.Method() != http.MethodOptions { + c.Vary(fiber.HeaderOrigin) + c.Set(fiber.HeaderAccessControlAllowOrigin, allowOrigin) + + if cfg.AllowCredentials { + c.Set(fiber.HeaderAccessControlAllowCredentials, "true") + } + if exposeHeaders != "" { + c.Set(fiber.HeaderAccessControlExposeHeaders, exposeHeaders) + } + return c.Next() + } + + // Preflight request + c.Vary(fiber.HeaderOrigin) + c.Vary(fiber.HeaderAccessControlRequestMethod) + c.Vary(fiber.HeaderAccessControlRequestHeaders) + c.Set(fiber.HeaderAccessControlAllowOrigin, allowOrigin) + c.Set(fiber.HeaderAccessControlAllowMethods, allowMethods) + + // Set Allow-Credentials if set to true + if cfg.AllowCredentials { + c.Set(fiber.HeaderAccessControlAllowCredentials, "true") + } + + // Set Allow-Headers if not empty + if allowHeaders != "" { + c.Set(fiber.HeaderAccessControlAllowHeaders, allowHeaders) + } else { + h := c.Get(fiber.HeaderAccessControlRequestHeaders) + if h != "" { + c.Set(fiber.HeaderAccessControlAllowHeaders, h) + } + } + + // Set MaxAge is set + if cfg.MaxAge > 0 { + c.Set(fiber.HeaderAccessControlMaxAge, maxAge) + } + + // Send 204 No Content + return c.SendStatus(fiber.StatusNoContent) + } +} diff --git a/server/middleware/cors/utils.go b/server/middleware/cors/utils.go new file mode 100644 index 000000000..fee658ef9 --- /dev/null +++ b/server/middleware/cors/utils.go @@ -0,0 +1,52 @@ +package cors + +import "strings" + +func matchScheme(domain, pattern string) bool { + didx := strings.Index(domain, ":") + pidx := strings.Index(pattern, ":") + return didx != -1 && pidx != -1 && domain[:didx] == pattern[:pidx] +} + +// matchSubdomain compares authority with wildcard +func matchSubdomain(domain, pattern string) bool { + if !matchScheme(domain, pattern) { + return false + } + didx := strings.Index(domain, "://") + pidx := strings.Index(pattern, "://") + if didx == -1 || pidx == -1 { + return false + } + domAuth := domain[didx+3:] + // to avoid long loop by invalid long domain + if len(domAuth) > 253 { + return false + } + patAuth := pattern[pidx+3:] + + domComp := strings.Split(domAuth, ".") + patComp := strings.Split(patAuth, ".") + for i := len(domComp)/2 - 1; i >= 0; i-- { + opp := len(domComp) - 1 - i + domComp[i], domComp[opp] = domComp[opp], domComp[i] + } + for i := len(patComp)/2 - 1; i >= 0; i-- { + opp := len(patComp) - 1 - i + patComp[i], patComp[opp] = patComp[opp], patComp[i] + } + + for i, v := range domComp { + if len(patComp) <= i { + return false + } + p := patComp[i] + if p == "*" { + return true + } + if p != v { + return false + } + } + return false +} diff --git a/server/middleware/limit.go b/server/middleware/limit.go new file mode 100644 index 000000000..9593c9ba0 --- /dev/null +++ b/server/middleware/limit.go @@ -0,0 +1,83 @@ +package middleware + +import ( + "path" + + "github.com/ArtalkJS/ArtalkGo/internal/config" + "github.com/ArtalkJS/ArtalkGo/server/common" + "github.com/gofiber/fiber/v2" +) + +type ActionLimitConf struct { + ProtectPaths []string +} + +// 操作限制 中间件 +func ActionLimitMiddleware(conf ActionLimitConf) fiber.Handler { + return func(c *fiber.Ctx) error { + // 关闭验证码功能,直接 Skip + if !config.Instance.Captcha.Enabled { + return c.Next() + } + + // 路径是否启用操作限制 + pathInList := false + for _, p := range conf.ProtectPaths { + if path.Clean(c.Path()) == path.Clean(p) { + pathInList = true + break + } + } + if !pathInList { + // 不启用的 path 直接放行 + return c.Next() + } + + // 管理员直接放行 + if common.CheckIsAdminReq(c) { + return c.Next() + } + + userIP := c.IP() + isNeedCheck := common.IsReqNeedCaptchaCheck(c) + + // 总是需要验证码模式 + if config.Instance.Captcha.Always { + if common.GetAlwaysCaptchaMode_Pass(userIP) { + common.SetAlwaysCaptchaMode_Pass(userIP, false) // 总是需要验证码,放行一次后再次需要验证码 + isNeedCheck = false + } else { + isNeedCheck = true + } + } else { + // 超时模式:重置计数 + if config.Instance.Captcha.ActionReset != -1 { + if !common.IsActionInTimeFrame(c) { // 超时 + common.ResetActionRecord(c) // 重置计数 + isNeedCheck = false // 放行 + } + } + } + + // 是否需要验证 + if isNeedCheck { + respData := common.Map{ + "need_captcha": true, + } + + if config.Instance.Captcha.Geetest.Enabled { + // iframe 验证模式 + respData["iframe"] = true + // 前端新版不会再用到 img_data,给旧版响应 ArtalkFrontent out-of-date 图片 + respData["img_data"] = "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 160 40'%3E%3Cdefs%3E%3Cstyle%3E.a%7Bfill:%23328ce6%3B%7D.b%7Bfont-size:12px%3Bfill:%23fff%3Bfont-family:sans-serif%3B%7D%3C/style%3E%3C/defs%3E%3Crect class='a' width='160' height='40'/%3E%3Ctext class='b' transform='translate(18.37 16.67)'%3EArtalk Frontend%3Ctspan x='0' y='14.4'%3EOut-Of-Date.%3C/tspan%3E%3C/text%3E%3C/svg%3E" + } else { + respData["img_data"] = common.GetNewImageCaptchaBase64(c.IP()) + } + + return common.RespError(c, "需要验证码", respData) + } + + // 放行 + return c.Next() + } +} diff --git a/http/a_site_origin.go b/server/middleware/site_origin.go similarity index 52% rename from http/a_site_origin.go rename to server/middleware/site_origin.go index 9ad636e69..bae08bed1 100644 --- a/http/a_site_origin.go +++ b/server/middleware/site_origin.go @@ -1,4 +1,4 @@ -package http +package middleware import ( "fmt" @@ -10,7 +10,8 @@ import ( "github.com/ArtalkJS/ArtalkGo/internal/entity" "github.com/ArtalkJS/ArtalkGo/internal/query" "github.com/ArtalkJS/ArtalkGo/internal/utils" - "github.com/labstack/echo/v4" + "github.com/ArtalkJS/ArtalkGo/server/common" + "github.com/gofiber/fiber/v2" ) // 不启用 Origin 控制的 API paths @@ -20,82 +21,68 @@ var SiteOriginSkips = []string{ } // 站点隔离 & Origin 控制 -func SiteOriginMiddleware() echo.MiddlewareFunc { - return func(next echo.HandlerFunc) echo.HandlerFunc { - return func(c echo.Context) error { - // 忽略白名单 - for _, p := range SiteOriginSkips { - if path.Clean(c.Request().URL.Path) == path.Clean(p) { - return next(c) - } +func SiteOriginMiddleware() fiber.Handler { + return func(c *fiber.Ctx) error { + // 忽略白名单 + for _, p := range SiteOriginSkips { + if path.Clean(c.Path()) == path.Clean(p) { + return c.Next() } + } - siteName := c.FormValue("site_name") - siteID := uint(0) - var site *entity.Site = nil - - siteAll := false - isSuperAdmin := GetIsSuperAdmin(c) - - // 请求站点名 == "__ATK_SITE_ALL" 时取消站点隔离 - if siteName == config.ATK_SITE_ALL { - if !isSuperAdmin { - return RespError(c, "仅管理员查询允许取消站点隔离") - } + siteName := c.FormValue("site_name") + siteID := uint(0) + var site *entity.Site = nil - siteAll = true - } else { - // 请求站点名为空,使用默认 site - if siteName == "" { - siteName = strings.TrimSpace(config.Instance.SiteDefault) - if siteName != "" { - query.FindCreateSite(siteName) // 默认站点不存在则创建 - } - } + siteAll := false + isSuperAdmin := common.GetIsSuperAdmin(c) - findSite := query.FindSite(siteName) - if findSite.IsEmpty() { - return RespError(c, fmt.Sprintf("未找到站点:`%s`,请在控制台创建站点", siteName), Map{ - "err_no_site": true, - }) - } - site = &findSite - siteID = findSite.ID + // 请求站点名 == "__ATK_SITE_ALL" 时取消站点隔离 + if siteName == config.ATK_SITE_ALL { + if !isSuperAdmin { + return common.RespError(c, "仅管理员查询允许取消站点隔离") } - // 检测 Origin 合法性 (防止跨域的 CSRF 攻击) - if !isSuperAdmin { // 管理员忽略 Origin 检测 - if isOK, resp := CheckOrigin(c, site); !isOK { - return resp + siteAll = true + } else { + // 请求站点名为空,使用默认 site + if siteName == "" { + siteName = strings.TrimSpace(config.Instance.SiteDefault) + if siteName != "" { + query.FindCreateSite(siteName) // 默认站点不存在则创建 } } - // 设置 Context Values - c.Set(config.CTX_KEY_ATK_SITE_ID, siteID) - c.Set(config.CTX_KEY_ATK_SITE_NAME, siteName) - c.Set(config.CTX_KEY_ATK_SITE_ALL, siteAll) + findSite := query.FindSite(siteName) + if findSite.IsEmpty() { + return common.RespError(c, fmt.Sprintf("未找到站点:`%s`,请在控制台创建站点", siteName), common.Map{ + "err_no_site": true, + }) + } + site = &findSite + siteID = findSite.ID + } - return next(c) + // 检测 Origin 合法性 (防止跨域的 CSRF 攻击) + if !isSuperAdmin { // 管理员忽略 Origin 检测 + if isOK, resp := CheckOrigin(c, site); !isOK { + return resp + } } - } -} -func UseSite(c echo.Context, siteName *string, destID *uint, destSiteAll *bool) { - if destID != nil { - *destID = c.Get(config.CTX_KEY_ATK_SITE_ID).(uint) - } - if siteName != nil { - *siteName = c.Get(config.CTX_KEY_ATK_SITE_NAME).(string) - } - if destSiteAll != nil { - *destSiteAll = c.Get(config.CTX_KEY_ATK_SITE_ALL).(bool) + // 设置 Context Values + c.Locals(config.CTX_KEY_ATK_SITE_ID, siteID) + c.Locals(config.CTX_KEY_ATK_SITE_NAME, siteName) + c.Locals(config.CTX_KEY_ATK_SITE_ALL, siteAll) + + return c.Next() } } // 检测 Origin 合法性 // 防止跨域的 CSRF 攻击 // @see https://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html -func CheckOrigin(c echo.Context, allowSite *entity.Site) (bool, error) { +func CheckOrigin(c *fiber.Ctx, allowSite *entity.Site) (bool, error) { // 可信来源 URL allowURLs := []string{} @@ -112,30 +99,30 @@ func CheckOrigin(c echo.Context, allowSite *entity.Site) (bool, error) { // @note Origin 标头在前端 fetch POST 操作中总是携带的, // 即使配置 Referrer-Policy: no-referrer // @see https://stackoverflow.com/questions/42239643/when-do-browsers-send-the-origin-header-when-do-browsers-set-the-origin-to-null - origin := c.Request().Header.Get(echo.HeaderOrigin) + origin := c.Get(fiber.HeaderOrigin) if origin == "" || origin == "null" { // 从 Referer 获取 Origin - referer := c.Request().Referer() + referer := string(c.Request().Header.Referer()) if referer == "" { - return false, RespError(c, "无效请求,Origin 无法获取") + return false, common.RespError(c, "无效请求,Origin 无法获取") } origin = referer } // 允许同源请求 - host := c.Request().Host - realHostUnderProxy := c.Request().Header.Get("X-Forwarded-Host") + host := string(c.Request().Host()) + realHostUnderProxy := c.Get(fiber.HeaderXForwardedHost) if realHostUnderProxy != "" { host = realHostUnderProxy } - allowURLs = append(allowURLs, c.Scheme()+"://"+host) + allowURLs = append(allowURLs, string(c.Request().URI().Scheme())+"://"+host) // 判断 Origin 是否被允许 if GetIsAllowOrigin(origin, allowURLs) { return true, nil } - return false, RespError(c, "非法请求,请检查可信域名配置") + return false, common.RespError(c, "非法请求,请检查可信域名配置") } // 判断 Origin 是否被允许 diff --git a/http/a_site_origin_test.go b/server/middleware/site_origin_test.go similarity index 99% rename from http/a_site_origin_test.go rename to server/middleware/site_origin_test.go index a16563d04..73f35a7dd 100644 --- a/http/a_site_origin_test.go +++ b/server/middleware/site_origin_test.go @@ -1,4 +1,4 @@ -package http +package middleware import ( "testing" diff --git a/server/server.go b/server/server.go new file mode 100644 index 000000000..e072f9571 --- /dev/null +++ b/server/server.go @@ -0,0 +1,128 @@ +package server + +import ( + "net/http" + + "github.com/ArtalkJS/ArtalkGo/internal/config" + "github.com/ArtalkJS/ArtalkGo/internal/pkged" + "github.com/ArtalkJS/ArtalkGo/server/common" + h "github.com/ArtalkJS/ArtalkGo/server/handler" + "github.com/ArtalkJS/ArtalkGo/server/middleware" + "github.com/gofiber/fiber/v2" + "github.com/gofiber/fiber/v2/middleware/filesystem" + "github.com/sirupsen/logrus" +) + +func Init(app *fiber.App) { + cors(app) + actionLimit(app) + + api := app.Group("/api", middleware.SiteOriginMiddleware()) + { + h.CommentAdd(api) + h.CommentGet(api) + h.Vote(api) + h.PV(api) + h.Stat(api) + h.MarkRead(api) + h.ImgUpload(api) + + h.Conf(api) + h.Version(api) + + // captcha + h.Captcha(api) + + // user + h.UserGet(api) + h.UserLogin(api) + h.UserLoginStatus(api) + h.UserLogout(api) + + // admin + admin(api) + } + + index(app) + + static(app) + uploadedStatic(app) +} + +func admin(f fiber.Router) { + admin := f.Group("/admin", middleware.AdminOnlyMiddleware()) + { + h.AdminCommentEdit(admin) + h.AdminCommentDel(admin) + + h.AdminPageGet(admin) + h.AdminPageEdit(admin) + h.AdminPageDel(admin) + h.AdminPageFetch(admin) + + h.AdminSiteGet(admin) + h.AdminSiteAdd(admin) + h.AdminSiteEdit(admin) + h.AdminSiteDel(admin) + + h.AdminUserGet(admin) + h.AdminUserAdd(admin) + h.AdminUserEdit(admin) + h.AdminUserDel(admin) + + h.AdminCacheWarm(admin) + h.AdminCacheFlush(admin) + + h.AdminSendMail(admin) + h.AdminVoteSync(admin) + + h.AdminSettingGet(admin) + h.AdminSettingSave(admin) + + h.AdminTransfer(admin) + } +} + +func cors(f fiber.Router) { + f.Use(middleware.CorsMiddleware()) +} + +func actionLimit(f fiber.Router) { + f.Use(middleware.ActionLimitMiddleware(middleware.ActionLimitConf{ + // 启用操作限制路径白名单 + ProtectPaths: []string{ + "/api/add", + "/api/login", + "/api/vote", + "/api/img-upload", + }, + })) +} + +func static(f fiber.Router) { + f.Use("/", filesystem.New(filesystem.Config{ + Root: http.FS(pkged.FS()), + PathPrefix: "frontend", + Browse: false, + })) +} + +func index(f fiber.Router) { + f.All("/", func(c *fiber.Ctx) error { + if _, err := pkged.FS().Open("frontend/sidebar/index.html"); err == nil { + return c.Redirect("./sidebar/", fiber.StatusFound) + } + + return c.Status(fiber.StatusOK).JSON(common.GetApiVersionDataMap()) + }) +} + +func uploadedStatic(f fiber.Router) { + if config.Instance.ImgUpload.Path == "" { + config.Instance.ImgUpload.Path = "./data/artalk-img/" + logrus.Warn("图片上传功能 img_upload.path 未配置,使用默认值:" + config.Instance.ImgUpload.Path) + } + + // 图片上传静态资源可访问路径 + f.Static(config.IMG_UPLOAD_PUBLIC_PATH, config.Instance.ImgUpload.Path) +} From 91ae48c852d8068b71a6d2f93eec1d4d09db3309 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Thu, 5 Jan 2023 16:26:53 +0800 Subject: [PATCH 317/349] fix(api/get): fix concurrent map writes error Signed-off-by: qwqcode --- go.mod | 2 +- internal/utils/struct.go | 13 +++++++++++++ scripts/benchmark.sh | 3 +++ server/common/conf.go | 11 ++++++++--- server/server.go | 5 +++++ 5 files changed, 30 insertions(+), 4 deletions(-) create mode 100755 scripts/benchmark.sh diff --git a/go.mod b/go.mod index e9032cf8c..ca64da3bc 100644 --- a/go.mod +++ b/go.mod @@ -35,6 +35,7 @@ require ( github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.570 github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/tms v1.0.570 github.com/tidwall/gjson v1.14.4 + github.com/vmihailenco/msgpack v4.0.4+incompatible github.com/x-cray/logrus-prefixed-formatter v0.5.2 github.com/yuin/goldmark v1.5.3 golang.org/x/crypto v0.4.0 @@ -119,7 +120,6 @@ require ( github.com/valyala/bytebufferpool v1.0.0 // indirect github.com/valyala/fasthttp v1.41.0 // indirect github.com/valyala/tcplisten v1.0.0 // indirect - github.com/vmihailenco/msgpack v4.0.4+incompatible // indirect golang.org/x/exp v0.0.0-20221230185412-738e83a70c30 // indirect golang.org/x/image v0.2.0 // indirect golang.org/x/net v0.4.0 // indirect diff --git a/internal/utils/struct.go b/internal/utils/struct.go index 11e3d52f8..0e2226b95 100644 --- a/internal/utils/struct.go +++ b/internal/utils/struct.go @@ -4,6 +4,7 @@ import ( "encoding/json" "github.com/jeremywohl/flatten" + "github.com/vmihailenco/msgpack" ) func StructToMap(s interface{}) map[string]interface{} { @@ -21,3 +22,15 @@ func StructToFlatDotMap(s interface{}) map[string]interface{} { } return mainFlat } + +func CopyStruct(src *map[string]interface{}, dest *map[string]interface{}) error { + b, err := msgpack.Marshal(src) + if err != nil { + return err + } + err = msgpack.Unmarshal(b, dest) + if err != nil { + return err + } + return nil +} diff --git a/scripts/benchmark.sh b/scripts/benchmark.sh new file mode 100755 index 000000000..e4c40ef65 --- /dev/null +++ b/scripts/benchmark.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +bombardier -c 125 -d 10s -b "site_name=ArtalkDocs&page_key=https%3A%2F%2Fartalk.js.org%2Fguide%2Fintro.html&limit=20&offset=0" -m POST -H "Origin: http://127.0.0.1:5173" -H "Content-Type: application/x-www-form-urlencoded" http://127.0.0.1:23366/api/get \ No newline at end of file diff --git a/server/common/conf.go b/server/common/conf.go index f8c20c66d..a0ec17288 100644 --- a/server/common/conf.go +++ b/server/common/conf.go @@ -4,6 +4,7 @@ import ( "strings" "github.com/ArtalkJS/ArtalkGo/internal/config" + "github.com/ArtalkJS/ArtalkGo/internal/utils" "github.com/gofiber/fiber/v2" ) @@ -23,10 +24,14 @@ func GetApiPublicConfDataMap(c *fiber.Ctx) Map { imgUpload = true // 管理员始终允许上传图片 } - frontendConf := config.Instance.Frontend - if frontendConf == nil { - frontendConf = make(map[string]interface{}) + frontendConfSrc := config.Instance.Frontend + if frontendConfSrc == nil { + frontendConfSrc = make(map[string]interface{}) } + + frontendConf := make(map[string]interface{}) + utils.CopyStruct(&frontendConfSrc, &frontendConf) + frontendConf["imgUpload"] = &imgUpload return Map{ diff --git a/server/server.go b/server/server.go index e072f9571..34a46b519 100644 --- a/server/server.go +++ b/server/server.go @@ -10,6 +10,7 @@ import ( "github.com/ArtalkJS/ArtalkGo/server/middleware" "github.com/gofiber/fiber/v2" "github.com/gofiber/fiber/v2/middleware/filesystem" + "github.com/gofiber/fiber/v2/middleware/pprof" "github.com/sirupsen/logrus" ) @@ -17,6 +18,10 @@ func Init(app *fiber.App) { cors(app) actionLimit(app) + if config.Instance.Debug { + app.Use(pprof.New()) + } + api := app.Group("/api", middleware.SiteOriginMiddleware()) { h.CommentAdd(api) From 8f58754a0ea98d64a453a717b023d8e8f1319a2d Mon Sep 17 00:00:00 2001 From: qwqcode Date: Thu, 5 Jan 2023 17:15:46 +0800 Subject: [PATCH 318/349] feat(conf): add conf option for specific email tpl for admins Signed-off-by: qwqcode --- internal/config/config.go | 1 + internal/email/email.go | 2 +- internal/email/render.go | 11 ++++++++++- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/internal/config/config.go b/internal/config/config.go index 32d5934b3..ae64c5ea3 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -241,6 +241,7 @@ type AdminNotifyConf struct { type AdminEmailConf struct { Enabled bool `koanf:"enabled" json:"enabled"` // 管理员总开关 MailSubject string `koanf:"mail_subject" json:"mail_subject"` // 管理员邮件标题 + MailTpl string `koanf:"mail_tpl" json:"mail_tpl"` // 管理员专用邮件模板 } type NotifyTelegramConf struct { diff --git a/internal/email/email.go b/internal/email/email.go index cb168273c..228ae5cb7 100644 --- a/internal/email/email.go +++ b/internal/email/email.go @@ -30,7 +30,7 @@ func AsyncSend(notify *entity.Notify) { receiveUser := query.FetchUserForNotify(notify) - mailBody := RenderEmailBody(notify) + mailBody := RenderEmailBody(notify, receiveUser.IsAdmin) mailSubject := "" if !receiveUser.IsAdmin { mailSubject = RenderCommon(config.Instance.Email.MailSubject, notify) diff --git a/internal/email/render.go b/internal/email/render.go index 6d0b9f5b0..1d26ea504 100644 --- a/internal/email/render.go +++ b/internal/email/render.go @@ -127,8 +127,15 @@ func HandleEmoticonsImgTagsForNotify(str string) string { } // 渲染邮件 Body 内容 -func RenderEmailBody(notify *entity.Notify) string { +func RenderEmailBody(notify *entity.Notify, isSendToAdmin bool) string { tplName := config.Instance.Email.MailTpl + + // 发送给管理员的邮件单独使用管理员邮件模板 + if isSendToAdmin { + tplName = config.Instance.AdminNotify.Email.MailTpl + } + + // 配置文件未指定邮件模板路径,使用内置默认模板 if tplName == "" { tplName = "default" } @@ -137,6 +144,8 @@ func RenderEmailBody(notify *entity.Notify) string { if _, err := os.Stat(tplName); errors.Is(err, os.ErrNotExist) { tpl = GetInternalEmailTpl(tplName) } else { + // TODO 反复文件 IO 操作会导致性能下降, + // 之后优化可以改成程序启动时加载模板文件到内存中 tpl = GetExternalTpl(tplName) } From 038a1c52a07336343571d24511885e4d83dcbe66 Mon Sep 17 00:00:00 2001 From: pluveto Date: Mon, 16 Jan 2023 09:28:24 +0000 Subject: [PATCH 319/349] chore: move all to tmp dir --- {.circleci => tmp/.circleci}/config.yml | 0 {.github => tmp/.github}/dependabot.yml | 0 {.github => tmp/.github}/workflows/codeql.yml | 0 {.github => tmp/.github}/workflows/dockerhub.yml | 0 {.github => tmp/.github}/workflows/release.yml | 0 .gitignore => tmp/.gitignore | 0 .goreleaser.yml => tmp/.goreleaser.yml | 0 Dockerfile => tmp/Dockerfile | 0 LICENSE => tmp/LICENSE | 0 Makefile => tmp/Makefile | 0 README.md => tmp/README.md | 0 artalk-go.example.yml => tmp/artalk-go.example.yml | 0 {cmd => tmp/cmd}/admin.go | 0 {cmd => tmp/cmd}/export.go | 0 {cmd => tmp/cmd}/gen.go | 0 {cmd => tmp/cmd}/import.go | 0 {cmd => tmp/cmd}/root.go | 0 {cmd => tmp/cmd}/server.go | 0 {cmd => tmp/cmd}/upgrade.go | 0 {cmd => tmp/cmd}/utils.go | 0 docker-compose.yml => tmp/docker-compose.yml | 0 docker-entrypoint.sh => tmp/docker-entrypoint.sh | 0 {docs => tmp/docs}/artalk-go.png | Bin {frontend => tmp/frontend}/index.html | 0 {frontend => tmp/frontend}/robots.txt | 0 go.mod => tmp/go.mod | 0 go.sum => tmp/go.sum | 0 {internal => tmp/internal}/anti_spam/anti_spam.go | 0 .../internal}/anti_spam/anti_spam_akismet.go | 0 .../internal}/anti_spam/anti_spam_aliyun.go | 0 .../internal}/anti_spam/anti_spam_tencent.go | 0 {internal => tmp/internal}/artransfer/artrans.go | 0 {internal => tmp/internal}/artransfer/example.go | 0 {internal => tmp/internal}/artransfer/exporter.go | 0 {internal => tmp/internal}/artransfer/importer.go | 0 {internal => tmp/internal}/artransfer/output.go | 0 {internal => tmp/internal}/cache/actions.go | 0 {internal => tmp/internal}/cache/cache.go | 0 {internal => tmp/internal}/cache/db.go | 0 {internal => tmp/internal}/cache/operate.go | 0 {internal => tmp/internal}/captcha/captcha.go | 0 {internal => tmp/internal}/captcha/geetest.go | 0 .../internal}/captcha/pages/geetest.html | 0 {internal => tmp/internal}/config/config.go | 0 {internal => tmp/internal}/config/const.go | 0 {internal => tmp/internal}/config/init.go | 0 {internal => tmp/internal}/config/var.go | 0 {internal => tmp/internal}/core/core.go | 0 {internal => tmp/internal}/core/gen.go | 0 {internal => tmp/internal}/core/sync.go | 0 {internal => tmp/internal}/db/db.go | 0 {internal => tmp/internal}/db/gorm_logger.go | 0 {internal => tmp/internal}/db/migrate.go | 0 {internal => tmp/internal}/email/email.go | 0 .../internal}/email/email_tpl/default.html | 0 .../internal}/email/notify_tpl/default.html | 0 {internal => tmp/internal}/email/queue.go | 0 {internal => tmp/internal}/email/render.go | 0 {internal => tmp/internal}/email/render_test.go | 0 {internal => tmp/internal}/email/sender.go | 0 {internal => tmp/internal}/email/sender_alidm.go | 0 {internal => tmp/internal}/email/sender_cmd.go | 0 {internal => tmp/internal}/email/sender_smtp.go | 0 {internal => tmp/internal}/entity/artran.go | 0 {internal => tmp/internal}/entity/comment.go | 0 {internal => tmp/internal}/entity/comment_cooked.go | 0 .../internal}/entity/comment_for_email.go | 0 {internal => tmp/internal}/entity/notify.go | 0 {internal => tmp/internal}/entity/notify_cooked.go | 0 {internal => tmp/internal}/entity/page.go | 0 {internal => tmp/internal}/entity/page_cooked.go | 0 {internal => tmp/internal}/entity/site.go | 0 {internal => tmp/internal}/entity/site_coocked.go | 0 {internal => tmp/internal}/entity/user.go | 0 {internal => tmp/internal}/entity/user_cooked.go | 0 {internal => tmp/internal}/entity/user_for_admin.go | 0 {internal => tmp/internal}/entity/utils.go | 0 {internal => tmp/internal}/entity/vote.go | 0 {internal => tmp/internal}/notify_launcher/init.go | 0 .../internal}/notify_launcher/notify_launcher.go | 0 {internal => tmp/internal}/pkged/pkged.go | 0 {internal => tmp/internal}/query/association.go | 0 {internal => tmp/internal}/query/cook.go | 0 {internal => tmp/internal}/query/db.go | 0 {internal => tmp/internal}/query/db_test.go | 0 .../internal}/query/fixtures/comments.yml | 0 {internal => tmp/internal}/query/fixtures/pages.yml | 0 {internal => tmp/internal}/query/fixtures/sites.yml | 0 {internal => tmp/internal}/query/fixtures/users.yml | 0 {internal => tmp/internal}/query/query.go | 0 {internal => tmp/internal}/query/query_del.go | 0 {internal => tmp/internal}/query/query_del_test.go | 0 {internal => tmp/internal}/query/query_find.go | 0 .../internal}/query/query_find_create.go | 0 .../internal}/query/query_find_create_test.go | 0 {internal => tmp/internal}/query/query_find_test.go | 0 {internal => tmp/internal}/query/query_new.go | 0 {internal => tmp/internal}/query/query_update.go | 0 {internal => tmp/internal}/query/service.go | 0 {internal => tmp/internal}/query/service_test.go | 0 .../internal}/query/testdata/model_test_conf.yml | 0 {internal => tmp/internal}/utils/encrypt.go | 0 {internal => tmp/internal}/utils/fs.go | 0 {internal => tmp/internal}/utils/markdown.go | 0 {internal => tmp/internal}/utils/string.go | 0 {internal => tmp/internal}/utils/struct.go | 0 {internal => tmp/internal}/utils/utils.go | 0 {internal => tmp/internal}/utils/validator.go | 0 main.go => tmp/main.go | 0 {scripts => tmp/scripts}/benchmark.sh | 0 {scripts => tmp/scripts}/build-frontend.sh | 0 {scripts => tmp/scripts}/docker-build.sh | 0 {server => tmp/server}/common/auth.go | 0 {server => tmp/server}/common/captcha.go | 0 {server => tmp/server}/common/check.go | 0 {server => tmp/server}/common/conf.go | 0 {server => tmp/server}/common/cors.go | 0 {server => tmp/server}/common/params.go | 0 {server => tmp/server}/common/resp.go | 0 {server => tmp/server}/common/site.go | 0 {server => tmp/server}/handler/admin_cache.go | 0 {server => tmp/server}/handler/admin_comment_del.go | 0 .../server}/handler/admin_comment_edit.go | 0 {server => tmp/server}/handler/admin_page_del.go | 0 {server => tmp/server}/handler/admin_page_edit.go | 0 {server => tmp/server}/handler/admin_page_fetch.go | 0 {server => tmp/server}/handler/admin_page_get.go | 0 {server => tmp/server}/handler/admin_send_mail.go | 0 {server => tmp/server}/handler/admin_setting.go | 0 {server => tmp/server}/handler/admin_site_add.go | 0 {server => tmp/server}/handler/admin_site_del.go | 0 {server => tmp/server}/handler/admin_site_edit.go | 0 {server => tmp/server}/handler/admin_site_get.go | 0 {server => tmp/server}/handler/admin_transfer.go | 0 {server => tmp/server}/handler/admin_user_add.go | 0 {server => tmp/server}/handler/admin_user_del.go | 0 {server => tmp/server}/handler/admin_user_edit.go | 0 {server => tmp/server}/handler/admin_user_get.go | 0 {server => tmp/server}/handler/admin_vote_sync.go | 0 {server => tmp/server}/handler/captcha.go | 0 {server => tmp/server}/handler/comment_add.go | 0 {server => tmp/server}/handler/comment_get.go | 0 {server => tmp/server}/handler/comment_get_query.go | 0 {server => tmp/server}/handler/conf.go | 0 {server => tmp/server}/handler/img_upload.go | 0 {server => tmp/server}/handler/mark_read.go | 0 {server => tmp/server}/handler/pv.go | 0 {server => tmp/server}/handler/stat.go | 0 {server => tmp/server}/handler/user_get.go | 0 {server => tmp/server}/handler/user_login.go | 0 {server => tmp/server}/handler/user_logout.go | 0 {server => tmp/server}/handler/version.go | 0 {server => tmp/server}/handler/vote.go | 0 {server => tmp/server}/middleware/admin.go | 0 {server => tmp/server}/middleware/cors.go | 0 {server => tmp/server}/middleware/cors/cors.go | 0 {server => tmp/server}/middleware/cors/utils.go | 0 {server => tmp/server}/middleware/limit.go | 0 {server => tmp/server}/middleware/site_origin.go | 0 .../server}/middleware/site_origin_test.go | 0 {server => tmp/server}/server.go | 0 161 files changed, 0 insertions(+), 0 deletions(-) rename {.circleci => tmp/.circleci}/config.yml (100%) rename {.github => tmp/.github}/dependabot.yml (100%) rename {.github => tmp/.github}/workflows/codeql.yml (100%) rename {.github => tmp/.github}/workflows/dockerhub.yml (100%) rename {.github => tmp/.github}/workflows/release.yml (100%) rename .gitignore => tmp/.gitignore (100%) rename .goreleaser.yml => tmp/.goreleaser.yml (100%) rename Dockerfile => tmp/Dockerfile (100%) rename LICENSE => tmp/LICENSE (100%) rename Makefile => tmp/Makefile (100%) rename README.md => tmp/README.md (100%) rename artalk-go.example.yml => tmp/artalk-go.example.yml (100%) rename {cmd => tmp/cmd}/admin.go (100%) rename {cmd => tmp/cmd}/export.go (100%) rename {cmd => tmp/cmd}/gen.go (100%) rename {cmd => tmp/cmd}/import.go (100%) rename {cmd => tmp/cmd}/root.go (100%) rename {cmd => tmp/cmd}/server.go (100%) rename {cmd => tmp/cmd}/upgrade.go (100%) rename {cmd => tmp/cmd}/utils.go (100%) rename docker-compose.yml => tmp/docker-compose.yml (100%) rename docker-entrypoint.sh => tmp/docker-entrypoint.sh (100%) rename {docs => tmp/docs}/artalk-go.png (100%) rename {frontend => tmp/frontend}/index.html (100%) rename {frontend => tmp/frontend}/robots.txt (100%) rename go.mod => tmp/go.mod (100%) rename go.sum => tmp/go.sum (100%) rename {internal => tmp/internal}/anti_spam/anti_spam.go (100%) rename {internal => tmp/internal}/anti_spam/anti_spam_akismet.go (100%) rename {internal => tmp/internal}/anti_spam/anti_spam_aliyun.go (100%) rename {internal => tmp/internal}/anti_spam/anti_spam_tencent.go (100%) rename {internal => tmp/internal}/artransfer/artrans.go (100%) rename {internal => tmp/internal}/artransfer/example.go (100%) rename {internal => tmp/internal}/artransfer/exporter.go (100%) rename {internal => tmp/internal}/artransfer/importer.go (100%) rename {internal => tmp/internal}/artransfer/output.go (100%) rename {internal => tmp/internal}/cache/actions.go (100%) rename {internal => tmp/internal}/cache/cache.go (100%) rename {internal => tmp/internal}/cache/db.go (100%) rename {internal => tmp/internal}/cache/operate.go (100%) rename {internal => tmp/internal}/captcha/captcha.go (100%) rename {internal => tmp/internal}/captcha/geetest.go (100%) rename {internal => tmp/internal}/captcha/pages/geetest.html (100%) rename {internal => tmp/internal}/config/config.go (100%) rename {internal => tmp/internal}/config/const.go (100%) rename {internal => tmp/internal}/config/init.go (100%) rename {internal => tmp/internal}/config/var.go (100%) rename {internal => tmp/internal}/core/core.go (100%) rename {internal => tmp/internal}/core/gen.go (100%) rename {internal => tmp/internal}/core/sync.go (100%) rename {internal => tmp/internal}/db/db.go (100%) rename {internal => tmp/internal}/db/gorm_logger.go (100%) rename {internal => tmp/internal}/db/migrate.go (100%) rename {internal => tmp/internal}/email/email.go (100%) rename {internal => tmp/internal}/email/email_tpl/default.html (100%) rename {internal => tmp/internal}/email/notify_tpl/default.html (100%) rename {internal => tmp/internal}/email/queue.go (100%) rename {internal => tmp/internal}/email/render.go (100%) rename {internal => tmp/internal}/email/render_test.go (100%) rename {internal => tmp/internal}/email/sender.go (100%) rename {internal => tmp/internal}/email/sender_alidm.go (100%) rename {internal => tmp/internal}/email/sender_cmd.go (100%) rename {internal => tmp/internal}/email/sender_smtp.go (100%) rename {internal => tmp/internal}/entity/artran.go (100%) rename {internal => tmp/internal}/entity/comment.go (100%) rename {internal => tmp/internal}/entity/comment_cooked.go (100%) rename {internal => tmp/internal}/entity/comment_for_email.go (100%) rename {internal => tmp/internal}/entity/notify.go (100%) rename {internal => tmp/internal}/entity/notify_cooked.go (100%) rename {internal => tmp/internal}/entity/page.go (100%) rename {internal => tmp/internal}/entity/page_cooked.go (100%) rename {internal => tmp/internal}/entity/site.go (100%) rename {internal => tmp/internal}/entity/site_coocked.go (100%) rename {internal => tmp/internal}/entity/user.go (100%) rename {internal => tmp/internal}/entity/user_cooked.go (100%) rename {internal => tmp/internal}/entity/user_for_admin.go (100%) rename {internal => tmp/internal}/entity/utils.go (100%) rename {internal => tmp/internal}/entity/vote.go (100%) rename {internal => tmp/internal}/notify_launcher/init.go (100%) rename {internal => tmp/internal}/notify_launcher/notify_launcher.go (100%) rename {internal => tmp/internal}/pkged/pkged.go (100%) rename {internal => tmp/internal}/query/association.go (100%) rename {internal => tmp/internal}/query/cook.go (100%) rename {internal => tmp/internal}/query/db.go (100%) rename {internal => tmp/internal}/query/db_test.go (100%) rename {internal => tmp/internal}/query/fixtures/comments.yml (100%) rename {internal => tmp/internal}/query/fixtures/pages.yml (100%) rename {internal => tmp/internal}/query/fixtures/sites.yml (100%) rename {internal => tmp/internal}/query/fixtures/users.yml (100%) rename {internal => tmp/internal}/query/query.go (100%) rename {internal => tmp/internal}/query/query_del.go (100%) rename {internal => tmp/internal}/query/query_del_test.go (100%) rename {internal => tmp/internal}/query/query_find.go (100%) rename {internal => tmp/internal}/query/query_find_create.go (100%) rename {internal => tmp/internal}/query/query_find_create_test.go (100%) rename {internal => tmp/internal}/query/query_find_test.go (100%) rename {internal => tmp/internal}/query/query_new.go (100%) rename {internal => tmp/internal}/query/query_update.go (100%) rename {internal => tmp/internal}/query/service.go (100%) rename {internal => tmp/internal}/query/service_test.go (100%) rename {internal => tmp/internal}/query/testdata/model_test_conf.yml (100%) rename {internal => tmp/internal}/utils/encrypt.go (100%) rename {internal => tmp/internal}/utils/fs.go (100%) rename {internal => tmp/internal}/utils/markdown.go (100%) rename {internal => tmp/internal}/utils/string.go (100%) rename {internal => tmp/internal}/utils/struct.go (100%) rename {internal => tmp/internal}/utils/utils.go (100%) rename {internal => tmp/internal}/utils/validator.go (100%) rename main.go => tmp/main.go (100%) rename {scripts => tmp/scripts}/benchmark.sh (100%) rename {scripts => tmp/scripts}/build-frontend.sh (100%) rename {scripts => tmp/scripts}/docker-build.sh (100%) rename {server => tmp/server}/common/auth.go (100%) rename {server => tmp/server}/common/captcha.go (100%) rename {server => tmp/server}/common/check.go (100%) rename {server => tmp/server}/common/conf.go (100%) rename {server => tmp/server}/common/cors.go (100%) rename {server => tmp/server}/common/params.go (100%) rename {server => tmp/server}/common/resp.go (100%) rename {server => tmp/server}/common/site.go (100%) rename {server => tmp/server}/handler/admin_cache.go (100%) rename {server => tmp/server}/handler/admin_comment_del.go (100%) rename {server => tmp/server}/handler/admin_comment_edit.go (100%) rename {server => tmp/server}/handler/admin_page_del.go (100%) rename {server => tmp/server}/handler/admin_page_edit.go (100%) rename {server => tmp/server}/handler/admin_page_fetch.go (100%) rename {server => tmp/server}/handler/admin_page_get.go (100%) rename {server => tmp/server}/handler/admin_send_mail.go (100%) rename {server => tmp/server}/handler/admin_setting.go (100%) rename {server => tmp/server}/handler/admin_site_add.go (100%) rename {server => tmp/server}/handler/admin_site_del.go (100%) rename {server => tmp/server}/handler/admin_site_edit.go (100%) rename {server => tmp/server}/handler/admin_site_get.go (100%) rename {server => tmp/server}/handler/admin_transfer.go (100%) rename {server => tmp/server}/handler/admin_user_add.go (100%) rename {server => tmp/server}/handler/admin_user_del.go (100%) rename {server => tmp/server}/handler/admin_user_edit.go (100%) rename {server => tmp/server}/handler/admin_user_get.go (100%) rename {server => tmp/server}/handler/admin_vote_sync.go (100%) rename {server => tmp/server}/handler/captcha.go (100%) rename {server => tmp/server}/handler/comment_add.go (100%) rename {server => tmp/server}/handler/comment_get.go (100%) rename {server => tmp/server}/handler/comment_get_query.go (100%) rename {server => tmp/server}/handler/conf.go (100%) rename {server => tmp/server}/handler/img_upload.go (100%) rename {server => tmp/server}/handler/mark_read.go (100%) rename {server => tmp/server}/handler/pv.go (100%) rename {server => tmp/server}/handler/stat.go (100%) rename {server => tmp/server}/handler/user_get.go (100%) rename {server => tmp/server}/handler/user_login.go (100%) rename {server => tmp/server}/handler/user_logout.go (100%) rename {server => tmp/server}/handler/version.go (100%) rename {server => tmp/server}/handler/vote.go (100%) rename {server => tmp/server}/middleware/admin.go (100%) rename {server => tmp/server}/middleware/cors.go (100%) rename {server => tmp/server}/middleware/cors/cors.go (100%) rename {server => tmp/server}/middleware/cors/utils.go (100%) rename {server => tmp/server}/middleware/limit.go (100%) rename {server => tmp/server}/middleware/site_origin.go (100%) rename {server => tmp/server}/middleware/site_origin_test.go (100%) rename {server => tmp/server}/server.go (100%) diff --git a/.circleci/config.yml b/tmp/.circleci/config.yml similarity index 100% rename from .circleci/config.yml rename to tmp/.circleci/config.yml diff --git a/.github/dependabot.yml b/tmp/.github/dependabot.yml similarity index 100% rename from .github/dependabot.yml rename to tmp/.github/dependabot.yml diff --git a/.github/workflows/codeql.yml b/tmp/.github/workflows/codeql.yml similarity index 100% rename from .github/workflows/codeql.yml rename to tmp/.github/workflows/codeql.yml diff --git a/.github/workflows/dockerhub.yml b/tmp/.github/workflows/dockerhub.yml similarity index 100% rename from .github/workflows/dockerhub.yml rename to tmp/.github/workflows/dockerhub.yml diff --git a/.github/workflows/release.yml b/tmp/.github/workflows/release.yml similarity index 100% rename from .github/workflows/release.yml rename to tmp/.github/workflows/release.yml diff --git a/.gitignore b/tmp/.gitignore similarity index 100% rename from .gitignore rename to tmp/.gitignore diff --git a/.goreleaser.yml b/tmp/.goreleaser.yml similarity index 100% rename from .goreleaser.yml rename to tmp/.goreleaser.yml diff --git a/Dockerfile b/tmp/Dockerfile similarity index 100% rename from Dockerfile rename to tmp/Dockerfile diff --git a/LICENSE b/tmp/LICENSE similarity index 100% rename from LICENSE rename to tmp/LICENSE diff --git a/Makefile b/tmp/Makefile similarity index 100% rename from Makefile rename to tmp/Makefile diff --git a/README.md b/tmp/README.md similarity index 100% rename from README.md rename to tmp/README.md diff --git a/artalk-go.example.yml b/tmp/artalk-go.example.yml similarity index 100% rename from artalk-go.example.yml rename to tmp/artalk-go.example.yml diff --git a/cmd/admin.go b/tmp/cmd/admin.go similarity index 100% rename from cmd/admin.go rename to tmp/cmd/admin.go diff --git a/cmd/export.go b/tmp/cmd/export.go similarity index 100% rename from cmd/export.go rename to tmp/cmd/export.go diff --git a/cmd/gen.go b/tmp/cmd/gen.go similarity index 100% rename from cmd/gen.go rename to tmp/cmd/gen.go diff --git a/cmd/import.go b/tmp/cmd/import.go similarity index 100% rename from cmd/import.go rename to tmp/cmd/import.go diff --git a/cmd/root.go b/tmp/cmd/root.go similarity index 100% rename from cmd/root.go rename to tmp/cmd/root.go diff --git a/cmd/server.go b/tmp/cmd/server.go similarity index 100% rename from cmd/server.go rename to tmp/cmd/server.go diff --git a/cmd/upgrade.go b/tmp/cmd/upgrade.go similarity index 100% rename from cmd/upgrade.go rename to tmp/cmd/upgrade.go diff --git a/cmd/utils.go b/tmp/cmd/utils.go similarity index 100% rename from cmd/utils.go rename to tmp/cmd/utils.go diff --git a/docker-compose.yml b/tmp/docker-compose.yml similarity index 100% rename from docker-compose.yml rename to tmp/docker-compose.yml diff --git a/docker-entrypoint.sh b/tmp/docker-entrypoint.sh similarity index 100% rename from docker-entrypoint.sh rename to tmp/docker-entrypoint.sh diff --git a/docs/artalk-go.png b/tmp/docs/artalk-go.png similarity index 100% rename from docs/artalk-go.png rename to tmp/docs/artalk-go.png diff --git a/frontend/index.html b/tmp/frontend/index.html similarity index 100% rename from frontend/index.html rename to tmp/frontend/index.html diff --git a/frontend/robots.txt b/tmp/frontend/robots.txt similarity index 100% rename from frontend/robots.txt rename to tmp/frontend/robots.txt diff --git a/go.mod b/tmp/go.mod similarity index 100% rename from go.mod rename to tmp/go.mod diff --git a/go.sum b/tmp/go.sum similarity index 100% rename from go.sum rename to tmp/go.sum diff --git a/internal/anti_spam/anti_spam.go b/tmp/internal/anti_spam/anti_spam.go similarity index 100% rename from internal/anti_spam/anti_spam.go rename to tmp/internal/anti_spam/anti_spam.go diff --git a/internal/anti_spam/anti_spam_akismet.go b/tmp/internal/anti_spam/anti_spam_akismet.go similarity index 100% rename from internal/anti_spam/anti_spam_akismet.go rename to tmp/internal/anti_spam/anti_spam_akismet.go diff --git a/internal/anti_spam/anti_spam_aliyun.go b/tmp/internal/anti_spam/anti_spam_aliyun.go similarity index 100% rename from internal/anti_spam/anti_spam_aliyun.go rename to tmp/internal/anti_spam/anti_spam_aliyun.go diff --git a/internal/anti_spam/anti_spam_tencent.go b/tmp/internal/anti_spam/anti_spam_tencent.go similarity index 100% rename from internal/anti_spam/anti_spam_tencent.go rename to tmp/internal/anti_spam/anti_spam_tencent.go diff --git a/internal/artransfer/artrans.go b/tmp/internal/artransfer/artrans.go similarity index 100% rename from internal/artransfer/artrans.go rename to tmp/internal/artransfer/artrans.go diff --git a/internal/artransfer/example.go b/tmp/internal/artransfer/example.go similarity index 100% rename from internal/artransfer/example.go rename to tmp/internal/artransfer/example.go diff --git a/internal/artransfer/exporter.go b/tmp/internal/artransfer/exporter.go similarity index 100% rename from internal/artransfer/exporter.go rename to tmp/internal/artransfer/exporter.go diff --git a/internal/artransfer/importer.go b/tmp/internal/artransfer/importer.go similarity index 100% rename from internal/artransfer/importer.go rename to tmp/internal/artransfer/importer.go diff --git a/internal/artransfer/output.go b/tmp/internal/artransfer/output.go similarity index 100% rename from internal/artransfer/output.go rename to tmp/internal/artransfer/output.go diff --git a/internal/cache/actions.go b/tmp/internal/cache/actions.go similarity index 100% rename from internal/cache/actions.go rename to tmp/internal/cache/actions.go diff --git a/internal/cache/cache.go b/tmp/internal/cache/cache.go similarity index 100% rename from internal/cache/cache.go rename to tmp/internal/cache/cache.go diff --git a/internal/cache/db.go b/tmp/internal/cache/db.go similarity index 100% rename from internal/cache/db.go rename to tmp/internal/cache/db.go diff --git a/internal/cache/operate.go b/tmp/internal/cache/operate.go similarity index 100% rename from internal/cache/operate.go rename to tmp/internal/cache/operate.go diff --git a/internal/captcha/captcha.go b/tmp/internal/captcha/captcha.go similarity index 100% rename from internal/captcha/captcha.go rename to tmp/internal/captcha/captcha.go diff --git a/internal/captcha/geetest.go b/tmp/internal/captcha/geetest.go similarity index 100% rename from internal/captcha/geetest.go rename to tmp/internal/captcha/geetest.go diff --git a/internal/captcha/pages/geetest.html b/tmp/internal/captcha/pages/geetest.html similarity index 100% rename from internal/captcha/pages/geetest.html rename to tmp/internal/captcha/pages/geetest.html diff --git a/internal/config/config.go b/tmp/internal/config/config.go similarity index 100% rename from internal/config/config.go rename to tmp/internal/config/config.go diff --git a/internal/config/const.go b/tmp/internal/config/const.go similarity index 100% rename from internal/config/const.go rename to tmp/internal/config/const.go diff --git a/internal/config/init.go b/tmp/internal/config/init.go similarity index 100% rename from internal/config/init.go rename to tmp/internal/config/init.go diff --git a/internal/config/var.go b/tmp/internal/config/var.go similarity index 100% rename from internal/config/var.go rename to tmp/internal/config/var.go diff --git a/internal/core/core.go b/tmp/internal/core/core.go similarity index 100% rename from internal/core/core.go rename to tmp/internal/core/core.go diff --git a/internal/core/gen.go b/tmp/internal/core/gen.go similarity index 100% rename from internal/core/gen.go rename to tmp/internal/core/gen.go diff --git a/internal/core/sync.go b/tmp/internal/core/sync.go similarity index 100% rename from internal/core/sync.go rename to tmp/internal/core/sync.go diff --git a/internal/db/db.go b/tmp/internal/db/db.go similarity index 100% rename from internal/db/db.go rename to tmp/internal/db/db.go diff --git a/internal/db/gorm_logger.go b/tmp/internal/db/gorm_logger.go similarity index 100% rename from internal/db/gorm_logger.go rename to tmp/internal/db/gorm_logger.go diff --git a/internal/db/migrate.go b/tmp/internal/db/migrate.go similarity index 100% rename from internal/db/migrate.go rename to tmp/internal/db/migrate.go diff --git a/internal/email/email.go b/tmp/internal/email/email.go similarity index 100% rename from internal/email/email.go rename to tmp/internal/email/email.go diff --git a/internal/email/email_tpl/default.html b/tmp/internal/email/email_tpl/default.html similarity index 100% rename from internal/email/email_tpl/default.html rename to tmp/internal/email/email_tpl/default.html diff --git a/internal/email/notify_tpl/default.html b/tmp/internal/email/notify_tpl/default.html similarity index 100% rename from internal/email/notify_tpl/default.html rename to tmp/internal/email/notify_tpl/default.html diff --git a/internal/email/queue.go b/tmp/internal/email/queue.go similarity index 100% rename from internal/email/queue.go rename to tmp/internal/email/queue.go diff --git a/internal/email/render.go b/tmp/internal/email/render.go similarity index 100% rename from internal/email/render.go rename to tmp/internal/email/render.go diff --git a/internal/email/render_test.go b/tmp/internal/email/render_test.go similarity index 100% rename from internal/email/render_test.go rename to tmp/internal/email/render_test.go diff --git a/internal/email/sender.go b/tmp/internal/email/sender.go similarity index 100% rename from internal/email/sender.go rename to tmp/internal/email/sender.go diff --git a/internal/email/sender_alidm.go b/tmp/internal/email/sender_alidm.go similarity index 100% rename from internal/email/sender_alidm.go rename to tmp/internal/email/sender_alidm.go diff --git a/internal/email/sender_cmd.go b/tmp/internal/email/sender_cmd.go similarity index 100% rename from internal/email/sender_cmd.go rename to tmp/internal/email/sender_cmd.go diff --git a/internal/email/sender_smtp.go b/tmp/internal/email/sender_smtp.go similarity index 100% rename from internal/email/sender_smtp.go rename to tmp/internal/email/sender_smtp.go diff --git a/internal/entity/artran.go b/tmp/internal/entity/artran.go similarity index 100% rename from internal/entity/artran.go rename to tmp/internal/entity/artran.go diff --git a/internal/entity/comment.go b/tmp/internal/entity/comment.go similarity index 100% rename from internal/entity/comment.go rename to tmp/internal/entity/comment.go diff --git a/internal/entity/comment_cooked.go b/tmp/internal/entity/comment_cooked.go similarity index 100% rename from internal/entity/comment_cooked.go rename to tmp/internal/entity/comment_cooked.go diff --git a/internal/entity/comment_for_email.go b/tmp/internal/entity/comment_for_email.go similarity index 100% rename from internal/entity/comment_for_email.go rename to tmp/internal/entity/comment_for_email.go diff --git a/internal/entity/notify.go b/tmp/internal/entity/notify.go similarity index 100% rename from internal/entity/notify.go rename to tmp/internal/entity/notify.go diff --git a/internal/entity/notify_cooked.go b/tmp/internal/entity/notify_cooked.go similarity index 100% rename from internal/entity/notify_cooked.go rename to tmp/internal/entity/notify_cooked.go diff --git a/internal/entity/page.go b/tmp/internal/entity/page.go similarity index 100% rename from internal/entity/page.go rename to tmp/internal/entity/page.go diff --git a/internal/entity/page_cooked.go b/tmp/internal/entity/page_cooked.go similarity index 100% rename from internal/entity/page_cooked.go rename to tmp/internal/entity/page_cooked.go diff --git a/internal/entity/site.go b/tmp/internal/entity/site.go similarity index 100% rename from internal/entity/site.go rename to tmp/internal/entity/site.go diff --git a/internal/entity/site_coocked.go b/tmp/internal/entity/site_coocked.go similarity index 100% rename from internal/entity/site_coocked.go rename to tmp/internal/entity/site_coocked.go diff --git a/internal/entity/user.go b/tmp/internal/entity/user.go similarity index 100% rename from internal/entity/user.go rename to tmp/internal/entity/user.go diff --git a/internal/entity/user_cooked.go b/tmp/internal/entity/user_cooked.go similarity index 100% rename from internal/entity/user_cooked.go rename to tmp/internal/entity/user_cooked.go diff --git a/internal/entity/user_for_admin.go b/tmp/internal/entity/user_for_admin.go similarity index 100% rename from internal/entity/user_for_admin.go rename to tmp/internal/entity/user_for_admin.go diff --git a/internal/entity/utils.go b/tmp/internal/entity/utils.go similarity index 100% rename from internal/entity/utils.go rename to tmp/internal/entity/utils.go diff --git a/internal/entity/vote.go b/tmp/internal/entity/vote.go similarity index 100% rename from internal/entity/vote.go rename to tmp/internal/entity/vote.go diff --git a/internal/notify_launcher/init.go b/tmp/internal/notify_launcher/init.go similarity index 100% rename from internal/notify_launcher/init.go rename to tmp/internal/notify_launcher/init.go diff --git a/internal/notify_launcher/notify_launcher.go b/tmp/internal/notify_launcher/notify_launcher.go similarity index 100% rename from internal/notify_launcher/notify_launcher.go rename to tmp/internal/notify_launcher/notify_launcher.go diff --git a/internal/pkged/pkged.go b/tmp/internal/pkged/pkged.go similarity index 100% rename from internal/pkged/pkged.go rename to tmp/internal/pkged/pkged.go diff --git a/internal/query/association.go b/tmp/internal/query/association.go similarity index 100% rename from internal/query/association.go rename to tmp/internal/query/association.go diff --git a/internal/query/cook.go b/tmp/internal/query/cook.go similarity index 100% rename from internal/query/cook.go rename to tmp/internal/query/cook.go diff --git a/internal/query/db.go b/tmp/internal/query/db.go similarity index 100% rename from internal/query/db.go rename to tmp/internal/query/db.go diff --git a/internal/query/db_test.go b/tmp/internal/query/db_test.go similarity index 100% rename from internal/query/db_test.go rename to tmp/internal/query/db_test.go diff --git a/internal/query/fixtures/comments.yml b/tmp/internal/query/fixtures/comments.yml similarity index 100% rename from internal/query/fixtures/comments.yml rename to tmp/internal/query/fixtures/comments.yml diff --git a/internal/query/fixtures/pages.yml b/tmp/internal/query/fixtures/pages.yml similarity index 100% rename from internal/query/fixtures/pages.yml rename to tmp/internal/query/fixtures/pages.yml diff --git a/internal/query/fixtures/sites.yml b/tmp/internal/query/fixtures/sites.yml similarity index 100% rename from internal/query/fixtures/sites.yml rename to tmp/internal/query/fixtures/sites.yml diff --git a/internal/query/fixtures/users.yml b/tmp/internal/query/fixtures/users.yml similarity index 100% rename from internal/query/fixtures/users.yml rename to tmp/internal/query/fixtures/users.yml diff --git a/internal/query/query.go b/tmp/internal/query/query.go similarity index 100% rename from internal/query/query.go rename to tmp/internal/query/query.go diff --git a/internal/query/query_del.go b/tmp/internal/query/query_del.go similarity index 100% rename from internal/query/query_del.go rename to tmp/internal/query/query_del.go diff --git a/internal/query/query_del_test.go b/tmp/internal/query/query_del_test.go similarity index 100% rename from internal/query/query_del_test.go rename to tmp/internal/query/query_del_test.go diff --git a/internal/query/query_find.go b/tmp/internal/query/query_find.go similarity index 100% rename from internal/query/query_find.go rename to tmp/internal/query/query_find.go diff --git a/internal/query/query_find_create.go b/tmp/internal/query/query_find_create.go similarity index 100% rename from internal/query/query_find_create.go rename to tmp/internal/query/query_find_create.go diff --git a/internal/query/query_find_create_test.go b/tmp/internal/query/query_find_create_test.go similarity index 100% rename from internal/query/query_find_create_test.go rename to tmp/internal/query/query_find_create_test.go diff --git a/internal/query/query_find_test.go b/tmp/internal/query/query_find_test.go similarity index 100% rename from internal/query/query_find_test.go rename to tmp/internal/query/query_find_test.go diff --git a/internal/query/query_new.go b/tmp/internal/query/query_new.go similarity index 100% rename from internal/query/query_new.go rename to tmp/internal/query/query_new.go diff --git a/internal/query/query_update.go b/tmp/internal/query/query_update.go similarity index 100% rename from internal/query/query_update.go rename to tmp/internal/query/query_update.go diff --git a/internal/query/service.go b/tmp/internal/query/service.go similarity index 100% rename from internal/query/service.go rename to tmp/internal/query/service.go diff --git a/internal/query/service_test.go b/tmp/internal/query/service_test.go similarity index 100% rename from internal/query/service_test.go rename to tmp/internal/query/service_test.go diff --git a/internal/query/testdata/model_test_conf.yml b/tmp/internal/query/testdata/model_test_conf.yml similarity index 100% rename from internal/query/testdata/model_test_conf.yml rename to tmp/internal/query/testdata/model_test_conf.yml diff --git a/internal/utils/encrypt.go b/tmp/internal/utils/encrypt.go similarity index 100% rename from internal/utils/encrypt.go rename to tmp/internal/utils/encrypt.go diff --git a/internal/utils/fs.go b/tmp/internal/utils/fs.go similarity index 100% rename from internal/utils/fs.go rename to tmp/internal/utils/fs.go diff --git a/internal/utils/markdown.go b/tmp/internal/utils/markdown.go similarity index 100% rename from internal/utils/markdown.go rename to tmp/internal/utils/markdown.go diff --git a/internal/utils/string.go b/tmp/internal/utils/string.go similarity index 100% rename from internal/utils/string.go rename to tmp/internal/utils/string.go diff --git a/internal/utils/struct.go b/tmp/internal/utils/struct.go similarity index 100% rename from internal/utils/struct.go rename to tmp/internal/utils/struct.go diff --git a/internal/utils/utils.go b/tmp/internal/utils/utils.go similarity index 100% rename from internal/utils/utils.go rename to tmp/internal/utils/utils.go diff --git a/internal/utils/validator.go b/tmp/internal/utils/validator.go similarity index 100% rename from internal/utils/validator.go rename to tmp/internal/utils/validator.go diff --git a/main.go b/tmp/main.go similarity index 100% rename from main.go rename to tmp/main.go diff --git a/scripts/benchmark.sh b/tmp/scripts/benchmark.sh similarity index 100% rename from scripts/benchmark.sh rename to tmp/scripts/benchmark.sh diff --git a/scripts/build-frontend.sh b/tmp/scripts/build-frontend.sh similarity index 100% rename from scripts/build-frontend.sh rename to tmp/scripts/build-frontend.sh diff --git a/scripts/docker-build.sh b/tmp/scripts/docker-build.sh similarity index 100% rename from scripts/docker-build.sh rename to tmp/scripts/docker-build.sh diff --git a/server/common/auth.go b/tmp/server/common/auth.go similarity index 100% rename from server/common/auth.go rename to tmp/server/common/auth.go diff --git a/server/common/captcha.go b/tmp/server/common/captcha.go similarity index 100% rename from server/common/captcha.go rename to tmp/server/common/captcha.go diff --git a/server/common/check.go b/tmp/server/common/check.go similarity index 100% rename from server/common/check.go rename to tmp/server/common/check.go diff --git a/server/common/conf.go b/tmp/server/common/conf.go similarity index 100% rename from server/common/conf.go rename to tmp/server/common/conf.go diff --git a/server/common/cors.go b/tmp/server/common/cors.go similarity index 100% rename from server/common/cors.go rename to tmp/server/common/cors.go diff --git a/server/common/params.go b/tmp/server/common/params.go similarity index 100% rename from server/common/params.go rename to tmp/server/common/params.go diff --git a/server/common/resp.go b/tmp/server/common/resp.go similarity index 100% rename from server/common/resp.go rename to tmp/server/common/resp.go diff --git a/server/common/site.go b/tmp/server/common/site.go similarity index 100% rename from server/common/site.go rename to tmp/server/common/site.go diff --git a/server/handler/admin_cache.go b/tmp/server/handler/admin_cache.go similarity index 100% rename from server/handler/admin_cache.go rename to tmp/server/handler/admin_cache.go diff --git a/server/handler/admin_comment_del.go b/tmp/server/handler/admin_comment_del.go similarity index 100% rename from server/handler/admin_comment_del.go rename to tmp/server/handler/admin_comment_del.go diff --git a/server/handler/admin_comment_edit.go b/tmp/server/handler/admin_comment_edit.go similarity index 100% rename from server/handler/admin_comment_edit.go rename to tmp/server/handler/admin_comment_edit.go diff --git a/server/handler/admin_page_del.go b/tmp/server/handler/admin_page_del.go similarity index 100% rename from server/handler/admin_page_del.go rename to tmp/server/handler/admin_page_del.go diff --git a/server/handler/admin_page_edit.go b/tmp/server/handler/admin_page_edit.go similarity index 100% rename from server/handler/admin_page_edit.go rename to tmp/server/handler/admin_page_edit.go diff --git a/server/handler/admin_page_fetch.go b/tmp/server/handler/admin_page_fetch.go similarity index 100% rename from server/handler/admin_page_fetch.go rename to tmp/server/handler/admin_page_fetch.go diff --git a/server/handler/admin_page_get.go b/tmp/server/handler/admin_page_get.go similarity index 100% rename from server/handler/admin_page_get.go rename to tmp/server/handler/admin_page_get.go diff --git a/server/handler/admin_send_mail.go b/tmp/server/handler/admin_send_mail.go similarity index 100% rename from server/handler/admin_send_mail.go rename to tmp/server/handler/admin_send_mail.go diff --git a/server/handler/admin_setting.go b/tmp/server/handler/admin_setting.go similarity index 100% rename from server/handler/admin_setting.go rename to tmp/server/handler/admin_setting.go diff --git a/server/handler/admin_site_add.go b/tmp/server/handler/admin_site_add.go similarity index 100% rename from server/handler/admin_site_add.go rename to tmp/server/handler/admin_site_add.go diff --git a/server/handler/admin_site_del.go b/tmp/server/handler/admin_site_del.go similarity index 100% rename from server/handler/admin_site_del.go rename to tmp/server/handler/admin_site_del.go diff --git a/server/handler/admin_site_edit.go b/tmp/server/handler/admin_site_edit.go similarity index 100% rename from server/handler/admin_site_edit.go rename to tmp/server/handler/admin_site_edit.go diff --git a/server/handler/admin_site_get.go b/tmp/server/handler/admin_site_get.go similarity index 100% rename from server/handler/admin_site_get.go rename to tmp/server/handler/admin_site_get.go diff --git a/server/handler/admin_transfer.go b/tmp/server/handler/admin_transfer.go similarity index 100% rename from server/handler/admin_transfer.go rename to tmp/server/handler/admin_transfer.go diff --git a/server/handler/admin_user_add.go b/tmp/server/handler/admin_user_add.go similarity index 100% rename from server/handler/admin_user_add.go rename to tmp/server/handler/admin_user_add.go diff --git a/server/handler/admin_user_del.go b/tmp/server/handler/admin_user_del.go similarity index 100% rename from server/handler/admin_user_del.go rename to tmp/server/handler/admin_user_del.go diff --git a/server/handler/admin_user_edit.go b/tmp/server/handler/admin_user_edit.go similarity index 100% rename from server/handler/admin_user_edit.go rename to tmp/server/handler/admin_user_edit.go diff --git a/server/handler/admin_user_get.go b/tmp/server/handler/admin_user_get.go similarity index 100% rename from server/handler/admin_user_get.go rename to tmp/server/handler/admin_user_get.go diff --git a/server/handler/admin_vote_sync.go b/tmp/server/handler/admin_vote_sync.go similarity index 100% rename from server/handler/admin_vote_sync.go rename to tmp/server/handler/admin_vote_sync.go diff --git a/server/handler/captcha.go b/tmp/server/handler/captcha.go similarity index 100% rename from server/handler/captcha.go rename to tmp/server/handler/captcha.go diff --git a/server/handler/comment_add.go b/tmp/server/handler/comment_add.go similarity index 100% rename from server/handler/comment_add.go rename to tmp/server/handler/comment_add.go diff --git a/server/handler/comment_get.go b/tmp/server/handler/comment_get.go similarity index 100% rename from server/handler/comment_get.go rename to tmp/server/handler/comment_get.go diff --git a/server/handler/comment_get_query.go b/tmp/server/handler/comment_get_query.go similarity index 100% rename from server/handler/comment_get_query.go rename to tmp/server/handler/comment_get_query.go diff --git a/server/handler/conf.go b/tmp/server/handler/conf.go similarity index 100% rename from server/handler/conf.go rename to tmp/server/handler/conf.go diff --git a/server/handler/img_upload.go b/tmp/server/handler/img_upload.go similarity index 100% rename from server/handler/img_upload.go rename to tmp/server/handler/img_upload.go diff --git a/server/handler/mark_read.go b/tmp/server/handler/mark_read.go similarity index 100% rename from server/handler/mark_read.go rename to tmp/server/handler/mark_read.go diff --git a/server/handler/pv.go b/tmp/server/handler/pv.go similarity index 100% rename from server/handler/pv.go rename to tmp/server/handler/pv.go diff --git a/server/handler/stat.go b/tmp/server/handler/stat.go similarity index 100% rename from server/handler/stat.go rename to tmp/server/handler/stat.go diff --git a/server/handler/user_get.go b/tmp/server/handler/user_get.go similarity index 100% rename from server/handler/user_get.go rename to tmp/server/handler/user_get.go diff --git a/server/handler/user_login.go b/tmp/server/handler/user_login.go similarity index 100% rename from server/handler/user_login.go rename to tmp/server/handler/user_login.go diff --git a/server/handler/user_logout.go b/tmp/server/handler/user_logout.go similarity index 100% rename from server/handler/user_logout.go rename to tmp/server/handler/user_logout.go diff --git a/server/handler/version.go b/tmp/server/handler/version.go similarity index 100% rename from server/handler/version.go rename to tmp/server/handler/version.go diff --git a/server/handler/vote.go b/tmp/server/handler/vote.go similarity index 100% rename from server/handler/vote.go rename to tmp/server/handler/vote.go diff --git a/server/middleware/admin.go b/tmp/server/middleware/admin.go similarity index 100% rename from server/middleware/admin.go rename to tmp/server/middleware/admin.go diff --git a/server/middleware/cors.go b/tmp/server/middleware/cors.go similarity index 100% rename from server/middleware/cors.go rename to tmp/server/middleware/cors.go diff --git a/server/middleware/cors/cors.go b/tmp/server/middleware/cors/cors.go similarity index 100% rename from server/middleware/cors/cors.go rename to tmp/server/middleware/cors/cors.go diff --git a/server/middleware/cors/utils.go b/tmp/server/middleware/cors/utils.go similarity index 100% rename from server/middleware/cors/utils.go rename to tmp/server/middleware/cors/utils.go diff --git a/server/middleware/limit.go b/tmp/server/middleware/limit.go similarity index 100% rename from server/middleware/limit.go rename to tmp/server/middleware/limit.go diff --git a/server/middleware/site_origin.go b/tmp/server/middleware/site_origin.go similarity index 100% rename from server/middleware/site_origin.go rename to tmp/server/middleware/site_origin.go diff --git a/server/middleware/site_origin_test.go b/tmp/server/middleware/site_origin_test.go similarity index 100% rename from server/middleware/site_origin_test.go rename to tmp/server/middleware/site_origin_test.go diff --git a/server/server.go b/tmp/server/server.go similarity index 100% rename from server/server.go rename to tmp/server/server.go From 6a4195098b45c1ccc41f1ea973137ad4c9ea4c9b Mon Sep 17 00:00:00 2001 From: pluveto Date: Mon, 16 Jan 2023 09:33:03 +0000 Subject: [PATCH 320/349] refactor: merge ci workflows --- .github/dependabot.yml | 11 +++ .github/workflows/codeql_ui.yml | 74 +++++++++++++++ .github/workflows/dockerhub.yml | 83 +++++++++++++++++ .github/workflows/npm_ui.yml | 74 +++++++++++++++ .github/workflows/pages_ui.yml | 41 +++++++++ .github/workflows/release.yml | 50 +++++++++++ .goreleaser.yml | 155 ++++++++++++++++++++++++++++++++ 7 files changed, 488 insertions(+) create mode 100644 .github/dependabot.yml create mode 100644 .github/workflows/codeql_ui.yml create mode 100644 .github/workflows/dockerhub.yml create mode 100644 .github/workflows/npm_ui.yml create mode 100644 .github/workflows/pages_ui.yml create mode 100644 .github/workflows/release.yml create mode 100644 .goreleaser.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 000000000..e0871f93f --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,11 @@ +# To get started with Dependabot version updates, you'll need to specify which +# package ecosystems to update and where the package manifests are located. +# Please see the documentation for all configuration options: +# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates + +version: 2 +updates: + - package-ecosystem: "gomod" # See documentation for possible values + directory: "/" # Location of package manifests + schedule: + interval: "weekly" diff --git a/.github/workflows/codeql_ui.yml b/.github/workflows/codeql_ui.yml new file mode 100644 index 000000000..22ad8bc0a --- /dev/null +++ b/.github/workflows/codeql_ui.yml @@ -0,0 +1,74 @@ +# For most projects, this workflow file will not need changing; you simply need +# to commit it to your repository. +# +# You may wish to alter this file to override the set of languages analyzed, +# or to provide custom queries or build logic. +# +# ******** NOTE ******** +# We have attempted to detect the languages in your repository. Please check +# the `language` matrix defined below to confirm you have the correct set of +# supported CodeQL languages. +# +name: "CodeQL" + +on: + push: + branches: [ "master" ] + pull_request: + # The branches below must be a subset of the branches above + branches: [ "master" ] + schedule: + - cron: '40 17 * * 4' + +jobs: + analyze: + name: Analyze + runs-on: ubuntu-latest + permissions: + actions: read + contents: read + security-events: write + + strategy: + fail-fast: false + matrix: + language: [ 'javascript' ] + # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ] + # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support + + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@v2 + with: + languages: ${{ matrix.language }} + # If you wish to specify custom queries, you can do so here or in a config file. + # By default, queries listed here will override any specified in a config file. + # Prefix the list here with "+" to use these queries and those in the config file. + + # Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs + # queries: security-extended,security-and-quality + + + # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). + # If this step fails, then you should remove it and run the build manually (see below) + - name: Autobuild + uses: github/codeql-action/autobuild@v2 + + # ℹ️ Command-line programs to run using the OS shell. + # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun + + # If the Autobuild fails above, remove it and uncomment the following three lines. + # modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance. + + # - run: | + # echo "Run, Build Application using script" + # ./location_of_script_within_repo/buildscript.sh + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v2 + with: + category: "/language:${{matrix.language}}" diff --git a/.github/workflows/dockerhub.yml b/.github/workflows/dockerhub.yml new file mode 100644 index 000000000..3a9d6af3f --- /dev/null +++ b/.github/workflows/dockerhub.yml @@ -0,0 +1,83 @@ +name: CI to Docker Hub + +on: + push: + # branches: + # - "master" + tags: + - "v*" + # pull_request: + # branches: + # - "master" + +jobs: + docker: + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@master + - run: | + git fetch --prune --unshallow --tags -f + + - name: Login to DockerHub + uses: docker/login-action@v1 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + + - name: Set up Docker Buildx + id: buildx + uses: docker/setup-buildx-action@master + + # Docker tag 值生成 + # https://github.com/docker/metadata-action + - name: Docker meta + id: meta + uses: docker/metadata-action@v3 + with: + images: | + ${{ secrets.DOCKERHUB_USERNAME }}/artalk-go + tags: | + type=ref,event=branch + type=ref,event=pr + type=semver,pattern={{version}} + type=semver,pattern={{major}}.{{minor}} + type=sha + + # 编译多平台 + # https://github.com/docker/setup-qemu-action + # - name: Set up QEMU + # id: qemu + # uses: docker/setup-qemu-action@v1 + # with: + # platforms: all + + # 缓存 Docker + - name: Cache Docker layers + uses: actions/cache@v2 + with: + path: /tmp/.buildx-cache + key: ${{ runner.os }}-buildx-${{ github.sha }} + restore-keys: | + ${{ runner.os }}-buildx- + + # build docker image + # https://github.com/docker/build-push-action + - name: Build and push + id: docker_build + uses: docker/build-push-action@v2 + with: + builder: ${{ steps.buildx.outputs.name }} + context: ./ + file: ./Dockerfile + # platforms: linux/amd64,linux/arm64,linux/arm/v7 + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + # 缓存 + cache-from: type=local,src=/tmp/.buildx-cache + cache-to: type=local,dest=/tmp/.buildx-cache + + - name: Image digest + run: echo ${{ steps.docker_build.outputs.digest }} diff --git a/.github/workflows/npm_ui.yml b/.github/workflows/npm_ui.yml new file mode 100644 index 000000000..89fa2ddc6 --- /dev/null +++ b/.github/workflows/npm_ui.yml @@ -0,0 +1,74 @@ +# https://docs.github.com/en/actions/publishing-packages/publishing-nodejs-packages +name: NPM Publish + +on: + push: + tags: + - v* + +jobs: + publish: + # prevents this action from running on forks + if: github.repository == 'ArtalkJS/Artalk' + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: Use pnpm + uses: pnpm/action-setup@v2.2.4 + with: + version: 7.11.0 + + - name: Set node version to 16.x + uses: actions/setup-node@v3 + with: + node-version: 16.x + registry-url: https://registry.npmjs.org/ + cache: 'pnpm' + + - name: Install dependencies + run: pnpm install + + - name: Build + run: pnpm build + + - name: Publish + run: cd packages/artalk && pnpm publish --no-git-checks + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} + + # GitHub Packages + # + # Setup .npmrc file to publish to GitHub Packages + # - uses: actions/setup-node@v2 + # with: + # registry-url: 'https://npm.pkg.github.com' + # # Publish to GitHub Packages + # - run: npm publish + # env: + # NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + # Docs Update + docs-update: + runs-on: ubuntu-latest + steps: + - name: Get the version + id: get_version + run: echo ::set-output name=VERSION::${GITHUB_REF/refs\/tags\/v/} + + - name: Checkout ArtalkDocs + uses: actions/checkout@v3 + with: + repository: ArtalkJS/Docs + token: ${{ secrets.PAT }} + + - name: Update CDN links + run: | + sed -i 's#artalk@.[^/]*#artalk@${{ steps.get_version.outputs.VERSION }}#g' docs/code/ArtalkCDN.json + perl -pi -e 's#"Artalk"(\W+)?:(\W+)?".*?"#"Artalk": "${{ steps.get_version.outputs.VERSION }}"#g' docs/code/ArtalkVersion.json + sed -i 's#artalk@.[^/]*#artalk@${{ steps.get_version.outputs.VERSION }}#g' docs/code/quick-start/cdn.html + + - uses: stefanzweifel/git-auto-commit-action@v4 + with: + commit_message: Update Artalk CDN link to v${{ steps.get_version.outputs.VERSION }} diff --git a/.github/workflows/pages_ui.yml b/.github/workflows/pages_ui.yml new file mode 100644 index 000000000..19cdf7e4f --- /dev/null +++ b/.github/workflows/pages_ui.yml @@ -0,0 +1,41 @@ +name: GitHub Pages + +on: + push: + branches: + - master + workflow_dispatch: + +jobs: + deploy: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: Use pnpm + uses: pnpm/action-setup@v2.2.4 + with: + version: 7.11.0 + + - name: Set node version to 16.x + uses: actions/setup-node@v3 + with: + node-version: 16.x + registry-url: https://registry.npmjs.org/ + cache: 'pnpm' + + - name: Install dependencies + run: pnpm install + + - name: Build + run: cd packages/artalk && pnpm predeploy + + - name: Deploy + uses: peaceiris/actions-gh-pages@v3 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_branch: gh-pages + publish_dir: ./packages/artalk/deploy + user_name: 'github-actions[bot]' + user_email: 'github-actions[bot]@users.noreply.github.com' diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 000000000..466b568e0 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,50 @@ +name: Release Build + +on: + push: + tags: + - v* + +jobs: + release: + runs-on: ubuntu-latest + + steps: + - name: checkout code + uses: actions/checkout@v3 + - run: git fetch --prune --unshallow --tags -f + + - name: setup go + uses: actions/setup-go@v3 + with: + go-version: '^1.19.4' + + # docker `golang-cross` image cache + # `cache-go-cross-v1-19-4` + - run: mkdir -p ~/docker-cache + - name: docker image cache + id: cache-go-cross-v1-19-4 + uses: actions/cache@v2 + with: + path: ~/docker-cache + # Adjust key to meet your cache time requirements e.g. + # ${{ hashFiles(*) }} can be useful here to invalidate + # cache on file changes + key: cache-go-cross-v1-19-4 + + - if: steps.cache-go-cross-v1-19-4.outputs.cache-hit != 'true' + run: | + docker pull ghcr.io/goreleaser/goreleaser-cross:v1.19.4 + docker save -o ~/docker-cache/golang-cross.tar ghcr.io/goreleaser/goreleaser-cross:v1.19.4 + + - if: steps.cache-go-cross-v1-19-4.outputs.cache-hit == 'true' + run: docker load -i ~/docker-cache/golang-cross.tar + + # build + - name: setup release environment + run: |- + cp artalk-go.example.yml artalk-go.yml + echo 'GITHUB_TOKEN=${{secrets.GORELEASER_ACCESS_TOKEN}}' > .release-env + + - name: build and release publish + run: make release diff --git a/.goreleaser.yml b/.goreleaser.yml new file mode 100644 index 000000000..e4119b8a8 --- /dev/null +++ b/.goreleaser.yml @@ -0,0 +1,155 @@ +# Goreleaser Config +# +# https://goreleaser.com/quick-start/ +# https://goreleaser.com/customization/ +# https://goreleaser.com/customization/templates/ +# https://goreleaser.com/customization/fury/ +# https://goreleaser.com/customization/announce/telegram/ + +project_name: artalk-go + +env: + - GO111MODULE=on + - CGO_ENABLED=1 + +before: + hooks: + # install dependencies + - make install + - make build-frontend + - make update + +# build multi-platform +builds: + ## Amd 64 + + # Linux (amd_64) + - id: linux-amd64 + goos: + - linux + goarch: + - amd64 + env: + - CC=gcc + - CXX=g++ + binary: "{{.ProjectName}}" + main: ./main.go + ldflags: &common_ldflags | + -X github.com/ArtalkJS/ArtalkGo/internal/config.Version={{.Version}} + -X github.com/ArtalkJS/ArtalkGo/internal/config.CommitHash={{ .ShortCommit }} + -s -w + + # Windows (amd_64) + - id: windows-amd64 + goos: + - windows + goarch: + - amd64 + env: + - CC=x86_64-w64-mingw32-gcc + - CXX=x86_64-w64-mingw32-g++ + binary: "{{.ProjectName}}" + main: ./main.go + ldflags: *common_ldflags + flags: + # https://go-review.googlesource.com/c/go/+/224588/ + # https://github.com/ArtalkJS/ArtalkGo/issues/35 + - -tags=timetzdata + + # Darwin (amd_64) + - id: darwin-amd64 + goos: + - darwin + goarch: + - amd64 + env: + - CC=o64-clang + - CXX=o64-clang++ + binary: "{{.ProjectName}}" + main: ./main.go + ldflags: *common_ldflags + + ## Arm + + # Linux (arm_v7) + - id: linux-armhf + goos: + - linux + goarch: + - arm + goarm: + - 7 + env: + - CC=arm-linux-gnueabihf-gcc + - CXX=arm-linux-gnueabihf-g++ + binary: "{{.ProjectName}}" + main: ./main.go + ldflags: *common_ldflags + + # Linux (arm_64) + - id: linux-arm64 + goos: + - linux + goarch: + - arm64 + env: + - CC=aarch64-linux-gnu-gcc + - CXX=aarch64-linux-gnu-g++ + binary: "{{.ProjectName}}" + main: ./main.go + ldflags: *common_ldflags + + # Darwin (arm_64) + - id: darwin-arm64 + goos: + - darwin + goarch: + - arm64 + env: + - CC=oa64-clang + - CXX=oa64-clang++ + binary: "{{.ProjectName}}" + main: ./main.go + ldflags: *common_ldflags + +archives: + - id: artalk-go + builds: + - linux-amd64 + - darwin-amd64 + - windows-amd64 + - linux-armhf + - linux-arm64 + - darwin-arm64 + name_template: "{{.ProjectName}}_v{{.Version}}_{{.Os}}_{{.Arch}}{{.Arm}}" + format: tar.gz + format_overrides: + - goos: windows + format: zip + wrap_in_directory: true + files: + - README* + - LICENSE* + - artalk-go.yml + +checksum: + name_template: 'checksums.txt' + +snapshot: + name_template: "{{.Version}}-SNAPSHOT-{{.ShortCommit}}" + +# changelog +changelog: + sort: asc + filters: + exclude: + - '^docs:' + - '^test:' + - '^chore:' + +release: + github: + owner: ArtalkJS + name: ArtalkGo + prerelease: auto + draft: true From 8da91b3b25a57f9a7a0100ec9fd314cef803bcbd Mon Sep 17 00:00:00 2001 From: pluveto Date: Mon, 16 Jan 2023 09:41:44 +0000 Subject: [PATCH 321/349] fix: naming conflict of node circleci --- .circleci/{config.yml => config_ui.yml} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .circleci/{config.yml => config_ui.yml} (100%) diff --git a/.circleci/config.yml b/.circleci/config_ui.yml similarity index 100% rename from .circleci/config.yml rename to .circleci/config_ui.yml From 4f046f8d0e93b39a56c3feaddcab588afa257204 Mon Sep 17 00:00:00 2001 From: pluveto Date: Mon, 16 Jan 2023 09:50:10 +0000 Subject: [PATCH 322/349] refactor: move from tmp dir to root --- {tmp/.circleci => .circleci}/config.yml | 0 .gitignore | 65 +++++-- tmp/README.md => BACKEND.md | 0 tmp/Dockerfile => Dockerfile | 0 tmp/Makefile => Makefile | 0 ...lk-go.example.yml => artalk-go.example.yml | 0 {tmp/cmd => cmd}/admin.go | 0 {tmp/cmd => cmd}/export.go | 0 {tmp/cmd => cmd}/gen.go | 0 {tmp/cmd => cmd}/import.go | 0 {tmp/cmd => cmd}/root.go | 0 {tmp/cmd => cmd}/server.go | 0 {tmp/cmd => cmd}/upgrade.go | 0 {tmp/cmd => cmd}/utils.go | 0 tmp/docker-compose.yml => docker-compose.yml | 0 ...cker-entrypoint.sh => docker-entrypoint.sh | 0 {tmp/docs => docs}/artalk-go.png | Bin {tmp/frontend => frontend}/index.html | 0 .../public => frontend}/robots.txt | 0 tmp/go.mod => go.mod | 0 tmp/go.sum => go.sum | 0 .../anti_spam/anti_spam.go | 0 .../anti_spam/anti_spam_akismet.go | 0 .../anti_spam/anti_spam_aliyun.go | 0 .../anti_spam/anti_spam_tencent.go | 0 .../artransfer/artrans.go | 0 .../artransfer/example.go | 0 .../artransfer/exporter.go | 0 .../artransfer/importer.go | 0 .../artransfer/output.go | 0 {tmp/internal => internal}/cache/actions.go | 0 {tmp/internal => internal}/cache/cache.go | 0 {tmp/internal => internal}/cache/db.go | 0 {tmp/internal => internal}/cache/operate.go | 0 {tmp/internal => internal}/captcha/captcha.go | 0 {tmp/internal => internal}/captcha/geetest.go | 0 .../captcha/pages/geetest.html | 0 {tmp/internal => internal}/config/config.go | 0 {tmp/internal => internal}/config/const.go | 0 {tmp/internal => internal}/config/init.go | 0 {tmp/internal => internal}/config/var.go | 0 {tmp/internal => internal}/core/core.go | 0 {tmp/internal => internal}/core/gen.go | 0 {tmp/internal => internal}/core/sync.go | 0 {tmp/internal => internal}/db/db.go | 0 {tmp/internal => internal}/db/gorm_logger.go | 0 {tmp/internal => internal}/db/migrate.go | 0 {tmp/internal => internal}/email/email.go | 0 .../email/email_tpl/default.html | 0 .../email/notify_tpl/default.html | 0 {tmp/internal => internal}/email/queue.go | 0 {tmp/internal => internal}/email/render.go | 0 .../email/render_test.go | 0 {tmp/internal => internal}/email/sender.go | 0 .../email/sender_alidm.go | 0 .../internal => internal}/email/sender_cmd.go | 0 .../email/sender_smtp.go | 0 {tmp/internal => internal}/entity/artran.go | 0 {tmp/internal => internal}/entity/comment.go | 0 .../entity/comment_cooked.go | 0 .../entity/comment_for_email.go | 0 {tmp/internal => internal}/entity/notify.go | 0 .../entity/notify_cooked.go | 0 {tmp/internal => internal}/entity/page.go | 0 .../entity/page_cooked.go | 0 {tmp/internal => internal}/entity/site.go | 0 .../entity/site_coocked.go | 0 {tmp/internal => internal}/entity/user.go | 0 .../entity/user_cooked.go | 0 .../entity/user_for_admin.go | 0 {tmp/internal => internal}/entity/utils.go | 0 {tmp/internal => internal}/entity/vote.go | 0 .../notify_launcher/init.go | 0 .../notify_launcher/notify_launcher.go | 0 {tmp/internal => internal}/pkged/pkged.go | 0 .../query/association.go | 0 {tmp/internal => internal}/query/cook.go | 0 {tmp/internal => internal}/query/db.go | 0 {tmp/internal => internal}/query/db_test.go | 0 .../query/fixtures/comments.yml | 0 .../query/fixtures/pages.yml | 0 .../query/fixtures/sites.yml | 0 .../query/fixtures/users.yml | 0 {tmp/internal => internal}/query/query.go | 0 {tmp/internal => internal}/query/query_del.go | 0 .../query/query_del_test.go | 0 .../internal => internal}/query/query_find.go | 0 .../query/query_find_create.go | 0 .../query/query_find_create_test.go | 0 .../query/query_find_test.go | 0 {tmp/internal => internal}/query/query_new.go | 0 .../query/query_update.go | 0 {tmp/internal => internal}/query/service.go | 0 .../query/service_test.go | 0 .../query/testdata/model_test_conf.yml | 0 {tmp/internal => internal}/utils/encrypt.go | 0 {tmp/internal => internal}/utils/fs.go | 0 {tmp/internal => internal}/utils/markdown.go | 0 {tmp/internal => internal}/utils/string.go | 0 {tmp/internal => internal}/utils/struct.go | 0 {tmp/internal => internal}/utils/utils.go | 0 {tmp/internal => internal}/utils/validator.go | 0 tmp/main.go => main.go | 0 {tmp/scripts => scripts}/benchmark.sh | 0 {tmp/scripts => scripts}/build-frontend.sh | 0 {tmp/scripts => scripts}/docker-build.sh | 0 {tmp/server => server}/common/auth.go | 0 {tmp/server => server}/common/captcha.go | 0 {tmp/server => server}/common/check.go | 0 {tmp/server => server}/common/conf.go | 0 {tmp/server => server}/common/cors.go | 0 {tmp/server => server}/common/params.go | 0 {tmp/server => server}/common/resp.go | 0 {tmp/server => server}/common/site.go | 0 {tmp/server => server}/handler/admin_cache.go | 0 .../handler/admin_comment_del.go | 0 .../handler/admin_comment_edit.go | 0 .../handler/admin_page_del.go | 0 .../handler/admin_page_edit.go | 0 .../handler/admin_page_fetch.go | 0 .../handler/admin_page_get.go | 0 .../handler/admin_send_mail.go | 0 .../handler/admin_setting.go | 0 .../handler/admin_site_add.go | 0 .../handler/admin_site_del.go | 0 .../handler/admin_site_edit.go | 0 .../handler/admin_site_get.go | 0 .../handler/admin_transfer.go | 0 .../handler/admin_user_add.go | 0 .../handler/admin_user_del.go | 0 .../handler/admin_user_edit.go | 0 .../handler/admin_user_get.go | 0 .../handler/admin_vote_sync.go | 0 {tmp/server => server}/handler/captcha.go | 0 {tmp/server => server}/handler/comment_add.go | 0 {tmp/server => server}/handler/comment_get.go | 0 .../handler/comment_get_query.go | 0 {tmp/server => server}/handler/conf.go | 0 {tmp/server => server}/handler/img_upload.go | 0 {tmp/server => server}/handler/mark_read.go | 0 {tmp/server => server}/handler/pv.go | 0 {tmp/server => server}/handler/stat.go | 0 {tmp/server => server}/handler/user_get.go | 0 {tmp/server => server}/handler/user_login.go | 0 {tmp/server => server}/handler/user_logout.go | 0 {tmp/server => server}/handler/version.go | 0 {tmp/server => server}/handler/vote.go | 0 {tmp/server => server}/middleware/admin.go | 0 {tmp/server => server}/middleware/cors.go | 0 .../server => server}/middleware/cors/cors.go | 0 .../middleware/cors/utils.go | 0 {tmp/server => server}/middleware/limit.go | 0 .../middleware/site_origin.go | 0 .../middleware/site_origin_test.go | 0 {tmp/server => server}/server.go | 0 tmp/.github/dependabot.yml | 11 -- tmp/.github/workflows/codeql.yml | 74 -------- tmp/.github/workflows/dockerhub.yml | 83 --------- tmp/.github/workflows/release.yml | 50 ------ tmp/.gitignore | 52 ------ tmp/.goreleaser.yml | 155 ---------------- tmp/LICENSE | 165 ------------------ .eslintignore => ui/.eslintignore | 0 .eslintrc.js => ui/.eslintrc.js | 0 ui/.gitignore | 23 +++ .npmignore => ui/.npmignore | 0 .prettierrc => ui/.prettierrc | 0 .travis.yml => ui/.travis.yml | 0 package.json => ui/package.json | 0 .../packages}/artalk-sidebar/.eslintrc.js | 0 .../packages}/artalk-sidebar/.gitignore | 0 .../packages}/artalk-sidebar/README.md | 0 .../artalk-sidebar/auto-imports.d.ts | 0 .../packages}/artalk-sidebar/components.d.ts | 0 .../packages}/artalk-sidebar/index.html | 0 .../packages}/artalk-sidebar/package.json | 0 .../artalk-sidebar/public}/robots.txt | 0 .../artalk-sidebar/scripts/fetch-conf-tpl.js | 0 .../packages}/artalk-sidebar/src/App.vue | 0 .../src/assets/artalk-go.example.yml | 0 .../artalk-sidebar/src/assets/favicon.png | Bin .../src/components/FileUploader.vue | 0 .../artalk-sidebar/src/components/Header.vue | 0 .../src/components/ItemTextEditor.vue | 0 .../src/components/LoadingLayer.vue | 0 .../src/components/LogTerminal.vue | 0 .../src/components/PageEditor.vue | 0 .../src/components/Pagination.vue | 0 .../src/components/PreferenceArr.vue | 0 .../src/components/PreferenceGrp.vue | 0 .../src/components/PreferenceItem.vue | 0 .../src/components/SiteCreate.vue | 0 .../src/components/SiteEditor.vue | 0 .../src/components/SiteSwitcher.vue | 0 .../artalk-sidebar/src/components/Tab.vue | 0 .../src/components/UserEditor.vue | 0 .../packages}/artalk-sidebar/src/global.ts | 0 .../packages}/artalk-sidebar/src/lib/md5.js | 0 .../artalk-sidebar/src/lib/settings.ts | 0 .../packages}/artalk-sidebar/src/main.ts | 0 .../artalk-sidebar/src/pages/comments.vue | 0 .../artalk-sidebar/src/pages/index.vue | 0 .../artalk-sidebar/src/pages/login.vue | 0 .../artalk-sidebar/src/pages/pages.vue | 0 .../artalk-sidebar/src/pages/settings.vue | 0 .../artalk-sidebar/src/pages/sites.vue | 0 .../artalk-sidebar/src/pages/transfer.vue | 0 .../artalk-sidebar/src/pages/users.vue | 0 .../artalk-sidebar/src/stores/nav.ts | 0 .../artalk-sidebar/src/stores/user.ts | 0 .../packages}/artalk-sidebar/src/style.scss | 0 .../artalk-sidebar/src/style/_extends.scss | 0 .../artalk-sidebar/src/style/_variables.scss | 0 .../artalk-sidebar/src/vite-env.d.ts | 0 .../packages}/artalk-sidebar/tsconfig.json | 0 .../artalk-sidebar/typed-router.d.ts | 0 .../packages}/artalk-sidebar/vite.config.ts | 0 {packages => ui/packages}/artalk/CNAME | 0 {packages => ui/packages}/artalk/index.html | 0 {packages => ui/packages}/artalk/package.json | 0 .../packages}/artalk/postcss.config.js | 0 .../packages}/artalk/scripts/build-i18n.mjs | 0 .../packages}/artalk/src/api/admin.ts | 0 .../packages}/artalk/src/api/api-base.ts | 0 .../packages}/artalk/src/api/captcha.ts | 0 .../packages}/artalk/src/api/comment.ts | 0 .../packages}/artalk/src/api/index.ts | 0 .../packages}/artalk/src/api/page.ts | 0 .../packages}/artalk/src/api/request.ts | 0 .../packages}/artalk/src/api/site.ts | 0 .../packages}/artalk/src/api/system.ts | 0 .../packages}/artalk/src/api/upload.ts | 0 .../packages}/artalk/src/api/user.ts | 0 .../packages}/artalk/src/artalk.ts | 0 .../packages}/artalk/src/comment/actions.ts | 0 .../packages}/artalk/src/comment/comment.html | 0 .../packages}/artalk/src/comment/comment.ts | 0 .../packages}/artalk/src/comment/index.ts | 0 .../packages}/artalk/src/comment/render.ts | 0 .../artalk/src/components/action-btn.ts | 0 .../packages}/artalk/src/components/dialog.ts | 0 .../artalk/src/components/pagination.ts | 0 .../artalk/src/components/read-more-btn.ts | 0 .../packages}/artalk/src/context.ts | 0 .../packages}/artalk/src/defaults.ts | 0 .../packages}/artalk/src/editor/editor.html | 0 .../packages}/artalk/src/editor/editor.ts | 0 .../packages}/artalk/src/editor/index.ts | 0 .../artalk/src/editor/plugs/editor-plug.ts | 0 .../src/editor/plugs/emoticons-plug.less | 0 .../artalk/src/editor/plugs/emoticons-plug.ts | 0 .../src/editor/plugs/header-input-plug.ts | 0 .../artalk/src/editor/plugs/preview-plug.less | 0 .../artalk/src/editor/plugs/preview-plug.ts | 0 .../artalk/src/editor/plugs/upload-plug.ts | 0 .../packages}/artalk/src/i18n/en.ts | 0 .../packages}/artalk/src/i18n/index.ts | 0 .../packages}/artalk/src/i18n/jp.ts | 0 .../packages}/artalk/src/i18n/zh-CN.ts | 0 .../packages}/artalk/src/i18n/zh-TW.ts | 0 .../packages}/artalk/src/layer/index.ts | 0 .../packages}/artalk/src/layer/layer.ts | 0 .../artalk/src/layer/sidebar-layer.html | 0 .../artalk/src/layer/sidebar-layer.ts | 0 .../artalk/src/lib/checker/admin-checker.ts | 0 .../artalk/src/lib/checker/captcha-checker.ts | 0 .../packages}/artalk/src/lib/checker/index.ts | 0 .../packages}/artalk/src/lib/component.ts | 0 .../packages}/artalk/src/lib/detect.ts | 0 .../packages}/artalk/src/lib/stat.ts | 0 .../packages}/artalk/src/lib/ui.ts | 0 .../packages}/artalk/src/lib/user.ts | 0 .../packages}/artalk/src/lib/utils.ts | 0 .../packages}/artalk/src/list/index.ts | 0 .../packages}/artalk/src/list/list-lite.ts | 0 .../packages}/artalk/src/list/list-nest.ts | 0 .../packages}/artalk/src/list/list.html | 0 .../packages}/artalk/src/list/list.ts | 0 {packages => ui/packages}/artalk/src/main.ts | 0 .../packages}/artalk/src/style/_color.less | 0 .../packages}/artalk/src/style/_extend.less | 0 .../artalk/src/style/_variables.less | 0 .../packages}/artalk/src/style/comment.less | 0 .../packages}/artalk/src/style/editor.less | 0 .../packages}/artalk/src/style/list.less | 0 .../packages}/artalk/src/style/main.less | 0 .../artalk/src/style/pagination.less | 0 .../artalk/src/style/sidebar-layer.less | 0 .../packages}/artalk/test/ArtalkCount.html | 0 .../packages}/artalk/test/ArtalkI18n.html | 0 .../packages}/artalk/test/ArtalkLite.html | 0 .../packages}/artalk/test/CSRF.html | 0 .../packages}/artalk/tsconfig.json | 0 .../packages}/artalk/types/artalk-config.d.ts | 0 .../packages}/artalk/types/artalk-data.d.ts | 0 .../packages}/artalk/types/context.d.ts | 0 .../packages}/artalk/types/event.d.ts | 0 .../packages}/artalk/types/global.d.ts | 0 .../packages}/artalk/types/plug.d.ts | 0 .../packages}/artalk/vite-base.config.ts | 0 .../packages}/artalk/vite-demo.config.ts | 0 .../packages}/artalk/vite-lite.config.ts | 0 .../packages}/artalk/vite.config.ts | 0 .../packages}/plugin-katex/README.md | 0 .../packages}/plugin-katex/index.html | 0 .../packages}/plugin-katex/main.ts | 0 .../packages}/plugin-katex/package.json | 0 .../packages}/plugin-katex/tsconfig.json | 0 .../packages}/plugin-katex/vite.config.ts | 0 .../packages}/plugin-lightbox/README.md | 0 .../packages}/plugin-lightbox/global.d.ts | 0 .../packages}/plugin-lightbox/index.html | 0 .../packages}/plugin-lightbox/main.ts | 0 .../packages}/plugin-lightbox/package.json | 0 .../packages}/plugin-lightbox/tsconfig.json | 0 .../packages}/plugin-lightbox/vite.config.ts | 0 pnpm-lock.yaml => ui/pnpm-lock.yaml | 0 pnpm-workspace.yaml => ui/pnpm-workspace.yaml | 0 tsconfig.base.json => ui/tsconfig.base.json | 0 319 files changed, 70 insertions(+), 608 deletions(-) rename {tmp/.circleci => .circleci}/config.yml (100%) rename tmp/README.md => BACKEND.md (100%) rename tmp/Dockerfile => Dockerfile (100%) rename tmp/Makefile => Makefile (100%) rename tmp/artalk-go.example.yml => artalk-go.example.yml (100%) rename {tmp/cmd => cmd}/admin.go (100%) rename {tmp/cmd => cmd}/export.go (100%) rename {tmp/cmd => cmd}/gen.go (100%) rename {tmp/cmd => cmd}/import.go (100%) rename {tmp/cmd => cmd}/root.go (100%) rename {tmp/cmd => cmd}/server.go (100%) rename {tmp/cmd => cmd}/upgrade.go (100%) rename {tmp/cmd => cmd}/utils.go (100%) rename tmp/docker-compose.yml => docker-compose.yml (100%) rename tmp/docker-entrypoint.sh => docker-entrypoint.sh (100%) rename {tmp/docs => docs}/artalk-go.png (100%) rename {tmp/frontend => frontend}/index.html (100%) rename {packages/artalk-sidebar/public => frontend}/robots.txt (100%) rename tmp/go.mod => go.mod (100%) rename tmp/go.sum => go.sum (100%) rename {tmp/internal => internal}/anti_spam/anti_spam.go (100%) rename {tmp/internal => internal}/anti_spam/anti_spam_akismet.go (100%) rename {tmp/internal => internal}/anti_spam/anti_spam_aliyun.go (100%) rename {tmp/internal => internal}/anti_spam/anti_spam_tencent.go (100%) rename {tmp/internal => internal}/artransfer/artrans.go (100%) rename {tmp/internal => internal}/artransfer/example.go (100%) rename {tmp/internal => internal}/artransfer/exporter.go (100%) rename {tmp/internal => internal}/artransfer/importer.go (100%) rename {tmp/internal => internal}/artransfer/output.go (100%) rename {tmp/internal => internal}/cache/actions.go (100%) rename {tmp/internal => internal}/cache/cache.go (100%) rename {tmp/internal => internal}/cache/db.go (100%) rename {tmp/internal => internal}/cache/operate.go (100%) rename {tmp/internal => internal}/captcha/captcha.go (100%) rename {tmp/internal => internal}/captcha/geetest.go (100%) rename {tmp/internal => internal}/captcha/pages/geetest.html (100%) rename {tmp/internal => internal}/config/config.go (100%) rename {tmp/internal => internal}/config/const.go (100%) rename {tmp/internal => internal}/config/init.go (100%) rename {tmp/internal => internal}/config/var.go (100%) rename {tmp/internal => internal}/core/core.go (100%) rename {tmp/internal => internal}/core/gen.go (100%) rename {tmp/internal => internal}/core/sync.go (100%) rename {tmp/internal => internal}/db/db.go (100%) rename {tmp/internal => internal}/db/gorm_logger.go (100%) rename {tmp/internal => internal}/db/migrate.go (100%) rename {tmp/internal => internal}/email/email.go (100%) rename {tmp/internal => internal}/email/email_tpl/default.html (100%) rename {tmp/internal => internal}/email/notify_tpl/default.html (100%) rename {tmp/internal => internal}/email/queue.go (100%) rename {tmp/internal => internal}/email/render.go (100%) rename {tmp/internal => internal}/email/render_test.go (100%) rename {tmp/internal => internal}/email/sender.go (100%) rename {tmp/internal => internal}/email/sender_alidm.go (100%) rename {tmp/internal => internal}/email/sender_cmd.go (100%) rename {tmp/internal => internal}/email/sender_smtp.go (100%) rename {tmp/internal => internal}/entity/artran.go (100%) rename {tmp/internal => internal}/entity/comment.go (100%) rename {tmp/internal => internal}/entity/comment_cooked.go (100%) rename {tmp/internal => internal}/entity/comment_for_email.go (100%) rename {tmp/internal => internal}/entity/notify.go (100%) rename {tmp/internal => internal}/entity/notify_cooked.go (100%) rename {tmp/internal => internal}/entity/page.go (100%) rename {tmp/internal => internal}/entity/page_cooked.go (100%) rename {tmp/internal => internal}/entity/site.go (100%) rename {tmp/internal => internal}/entity/site_coocked.go (100%) rename {tmp/internal => internal}/entity/user.go (100%) rename {tmp/internal => internal}/entity/user_cooked.go (100%) rename {tmp/internal => internal}/entity/user_for_admin.go (100%) rename {tmp/internal => internal}/entity/utils.go (100%) rename {tmp/internal => internal}/entity/vote.go (100%) rename {tmp/internal => internal}/notify_launcher/init.go (100%) rename {tmp/internal => internal}/notify_launcher/notify_launcher.go (100%) rename {tmp/internal => internal}/pkged/pkged.go (100%) rename {tmp/internal => internal}/query/association.go (100%) rename {tmp/internal => internal}/query/cook.go (100%) rename {tmp/internal => internal}/query/db.go (100%) rename {tmp/internal => internal}/query/db_test.go (100%) rename {tmp/internal => internal}/query/fixtures/comments.yml (100%) rename {tmp/internal => internal}/query/fixtures/pages.yml (100%) rename {tmp/internal => internal}/query/fixtures/sites.yml (100%) rename {tmp/internal => internal}/query/fixtures/users.yml (100%) rename {tmp/internal => internal}/query/query.go (100%) rename {tmp/internal => internal}/query/query_del.go (100%) rename {tmp/internal => internal}/query/query_del_test.go (100%) rename {tmp/internal => internal}/query/query_find.go (100%) rename {tmp/internal => internal}/query/query_find_create.go (100%) rename {tmp/internal => internal}/query/query_find_create_test.go (100%) rename {tmp/internal => internal}/query/query_find_test.go (100%) rename {tmp/internal => internal}/query/query_new.go (100%) rename {tmp/internal => internal}/query/query_update.go (100%) rename {tmp/internal => internal}/query/service.go (100%) rename {tmp/internal => internal}/query/service_test.go (100%) rename {tmp/internal => internal}/query/testdata/model_test_conf.yml (100%) rename {tmp/internal => internal}/utils/encrypt.go (100%) rename {tmp/internal => internal}/utils/fs.go (100%) rename {tmp/internal => internal}/utils/markdown.go (100%) rename {tmp/internal => internal}/utils/string.go (100%) rename {tmp/internal => internal}/utils/struct.go (100%) rename {tmp/internal => internal}/utils/utils.go (100%) rename {tmp/internal => internal}/utils/validator.go (100%) rename tmp/main.go => main.go (100%) rename {tmp/scripts => scripts}/benchmark.sh (100%) rename {tmp/scripts => scripts}/build-frontend.sh (100%) rename {tmp/scripts => scripts}/docker-build.sh (100%) rename {tmp/server => server}/common/auth.go (100%) rename {tmp/server => server}/common/captcha.go (100%) rename {tmp/server => server}/common/check.go (100%) rename {tmp/server => server}/common/conf.go (100%) rename {tmp/server => server}/common/cors.go (100%) rename {tmp/server => server}/common/params.go (100%) rename {tmp/server => server}/common/resp.go (100%) rename {tmp/server => server}/common/site.go (100%) rename {tmp/server => server}/handler/admin_cache.go (100%) rename {tmp/server => server}/handler/admin_comment_del.go (100%) rename {tmp/server => server}/handler/admin_comment_edit.go (100%) rename {tmp/server => server}/handler/admin_page_del.go (100%) rename {tmp/server => server}/handler/admin_page_edit.go (100%) rename {tmp/server => server}/handler/admin_page_fetch.go (100%) rename {tmp/server => server}/handler/admin_page_get.go (100%) rename {tmp/server => server}/handler/admin_send_mail.go (100%) rename {tmp/server => server}/handler/admin_setting.go (100%) rename {tmp/server => server}/handler/admin_site_add.go (100%) rename {tmp/server => server}/handler/admin_site_del.go (100%) rename {tmp/server => server}/handler/admin_site_edit.go (100%) rename {tmp/server => server}/handler/admin_site_get.go (100%) rename {tmp/server => server}/handler/admin_transfer.go (100%) rename {tmp/server => server}/handler/admin_user_add.go (100%) rename {tmp/server => server}/handler/admin_user_del.go (100%) rename {tmp/server => server}/handler/admin_user_edit.go (100%) rename {tmp/server => server}/handler/admin_user_get.go (100%) rename {tmp/server => server}/handler/admin_vote_sync.go (100%) rename {tmp/server => server}/handler/captcha.go (100%) rename {tmp/server => server}/handler/comment_add.go (100%) rename {tmp/server => server}/handler/comment_get.go (100%) rename {tmp/server => server}/handler/comment_get_query.go (100%) rename {tmp/server => server}/handler/conf.go (100%) rename {tmp/server => server}/handler/img_upload.go (100%) rename {tmp/server => server}/handler/mark_read.go (100%) rename {tmp/server => server}/handler/pv.go (100%) rename {tmp/server => server}/handler/stat.go (100%) rename {tmp/server => server}/handler/user_get.go (100%) rename {tmp/server => server}/handler/user_login.go (100%) rename {tmp/server => server}/handler/user_logout.go (100%) rename {tmp/server => server}/handler/version.go (100%) rename {tmp/server => server}/handler/vote.go (100%) rename {tmp/server => server}/middleware/admin.go (100%) rename {tmp/server => server}/middleware/cors.go (100%) rename {tmp/server => server}/middleware/cors/cors.go (100%) rename {tmp/server => server}/middleware/cors/utils.go (100%) rename {tmp/server => server}/middleware/limit.go (100%) rename {tmp/server => server}/middleware/site_origin.go (100%) rename {tmp/server => server}/middleware/site_origin_test.go (100%) rename {tmp/server => server}/server.go (100%) delete mode 100644 tmp/.github/dependabot.yml delete mode 100644 tmp/.github/workflows/codeql.yml delete mode 100644 tmp/.github/workflows/dockerhub.yml delete mode 100644 tmp/.github/workflows/release.yml delete mode 100644 tmp/.gitignore delete mode 100644 tmp/.goreleaser.yml delete mode 100644 tmp/LICENSE rename .eslintignore => ui/.eslintignore (100%) rename .eslintrc.js => ui/.eslintrc.js (100%) create mode 100644 ui/.gitignore rename .npmignore => ui/.npmignore (100%) rename .prettierrc => ui/.prettierrc (100%) rename .travis.yml => ui/.travis.yml (100%) rename package.json => ui/package.json (100%) rename {packages => ui/packages}/artalk-sidebar/.eslintrc.js (100%) rename {packages => ui/packages}/artalk-sidebar/.gitignore (100%) rename {packages => ui/packages}/artalk-sidebar/README.md (100%) rename {packages => ui/packages}/artalk-sidebar/auto-imports.d.ts (100%) rename {packages => ui/packages}/artalk-sidebar/components.d.ts (100%) rename {packages => ui/packages}/artalk-sidebar/index.html (100%) rename {packages => ui/packages}/artalk-sidebar/package.json (100%) rename {tmp/frontend => ui/packages/artalk-sidebar/public}/robots.txt (100%) rename {packages => ui/packages}/artalk-sidebar/scripts/fetch-conf-tpl.js (100%) rename {packages => ui/packages}/artalk-sidebar/src/App.vue (100%) rename {packages => ui/packages}/artalk-sidebar/src/assets/artalk-go.example.yml (100%) rename {packages => ui/packages}/artalk-sidebar/src/assets/favicon.png (100%) rename {packages => ui/packages}/artalk-sidebar/src/components/FileUploader.vue (100%) rename {packages => ui/packages}/artalk-sidebar/src/components/Header.vue (100%) rename {packages => ui/packages}/artalk-sidebar/src/components/ItemTextEditor.vue (100%) rename {packages => ui/packages}/artalk-sidebar/src/components/LoadingLayer.vue (100%) rename {packages => ui/packages}/artalk-sidebar/src/components/LogTerminal.vue (100%) rename {packages => ui/packages}/artalk-sidebar/src/components/PageEditor.vue (100%) rename {packages => ui/packages}/artalk-sidebar/src/components/Pagination.vue (100%) rename {packages => ui/packages}/artalk-sidebar/src/components/PreferenceArr.vue (100%) rename {packages => ui/packages}/artalk-sidebar/src/components/PreferenceGrp.vue (100%) rename {packages => ui/packages}/artalk-sidebar/src/components/PreferenceItem.vue (100%) rename {packages => ui/packages}/artalk-sidebar/src/components/SiteCreate.vue (100%) rename {packages => ui/packages}/artalk-sidebar/src/components/SiteEditor.vue (100%) rename {packages => ui/packages}/artalk-sidebar/src/components/SiteSwitcher.vue (100%) rename {packages => ui/packages}/artalk-sidebar/src/components/Tab.vue (100%) rename {packages => ui/packages}/artalk-sidebar/src/components/UserEditor.vue (100%) rename {packages => ui/packages}/artalk-sidebar/src/global.ts (100%) rename {packages => ui/packages}/artalk-sidebar/src/lib/md5.js (100%) rename {packages => ui/packages}/artalk-sidebar/src/lib/settings.ts (100%) rename {packages => ui/packages}/artalk-sidebar/src/main.ts (100%) rename {packages => ui/packages}/artalk-sidebar/src/pages/comments.vue (100%) rename {packages => ui/packages}/artalk-sidebar/src/pages/index.vue (100%) rename {packages => ui/packages}/artalk-sidebar/src/pages/login.vue (100%) rename {packages => ui/packages}/artalk-sidebar/src/pages/pages.vue (100%) rename {packages => ui/packages}/artalk-sidebar/src/pages/settings.vue (100%) rename {packages => ui/packages}/artalk-sidebar/src/pages/sites.vue (100%) rename {packages => ui/packages}/artalk-sidebar/src/pages/transfer.vue (100%) rename {packages => ui/packages}/artalk-sidebar/src/pages/users.vue (100%) rename {packages => ui/packages}/artalk-sidebar/src/stores/nav.ts (100%) rename {packages => ui/packages}/artalk-sidebar/src/stores/user.ts (100%) rename {packages => ui/packages}/artalk-sidebar/src/style.scss (100%) rename {packages => ui/packages}/artalk-sidebar/src/style/_extends.scss (100%) rename {packages => ui/packages}/artalk-sidebar/src/style/_variables.scss (100%) rename {packages => ui/packages}/artalk-sidebar/src/vite-env.d.ts (100%) rename {packages => ui/packages}/artalk-sidebar/tsconfig.json (100%) rename {packages => ui/packages}/artalk-sidebar/typed-router.d.ts (100%) rename {packages => ui/packages}/artalk-sidebar/vite.config.ts (100%) rename {packages => ui/packages}/artalk/CNAME (100%) rename {packages => ui/packages}/artalk/index.html (100%) rename {packages => ui/packages}/artalk/package.json (100%) rename {packages => ui/packages}/artalk/postcss.config.js (100%) rename {packages => ui/packages}/artalk/scripts/build-i18n.mjs (100%) rename {packages => ui/packages}/artalk/src/api/admin.ts (100%) rename {packages => ui/packages}/artalk/src/api/api-base.ts (100%) rename {packages => ui/packages}/artalk/src/api/captcha.ts (100%) rename {packages => ui/packages}/artalk/src/api/comment.ts (100%) rename {packages => ui/packages}/artalk/src/api/index.ts (100%) rename {packages => ui/packages}/artalk/src/api/page.ts (100%) rename {packages => ui/packages}/artalk/src/api/request.ts (100%) rename {packages => ui/packages}/artalk/src/api/site.ts (100%) rename {packages => ui/packages}/artalk/src/api/system.ts (100%) rename {packages => ui/packages}/artalk/src/api/upload.ts (100%) rename {packages => ui/packages}/artalk/src/api/user.ts (100%) rename {packages => ui/packages}/artalk/src/artalk.ts (100%) rename {packages => ui/packages}/artalk/src/comment/actions.ts (100%) rename {packages => ui/packages}/artalk/src/comment/comment.html (100%) rename {packages => ui/packages}/artalk/src/comment/comment.ts (100%) rename {packages => ui/packages}/artalk/src/comment/index.ts (100%) rename {packages => ui/packages}/artalk/src/comment/render.ts (100%) rename {packages => ui/packages}/artalk/src/components/action-btn.ts (100%) rename {packages => ui/packages}/artalk/src/components/dialog.ts (100%) rename {packages => ui/packages}/artalk/src/components/pagination.ts (100%) rename {packages => ui/packages}/artalk/src/components/read-more-btn.ts (100%) rename {packages => ui/packages}/artalk/src/context.ts (100%) rename {packages => ui/packages}/artalk/src/defaults.ts (100%) rename {packages => ui/packages}/artalk/src/editor/editor.html (100%) rename {packages => ui/packages}/artalk/src/editor/editor.ts (100%) rename {packages => ui/packages}/artalk/src/editor/index.ts (100%) rename {packages => ui/packages}/artalk/src/editor/plugs/editor-plug.ts (100%) rename {packages => ui/packages}/artalk/src/editor/plugs/emoticons-plug.less (100%) rename {packages => ui/packages}/artalk/src/editor/plugs/emoticons-plug.ts (100%) rename {packages => ui/packages}/artalk/src/editor/plugs/header-input-plug.ts (100%) rename {packages => ui/packages}/artalk/src/editor/plugs/preview-plug.less (100%) rename {packages => ui/packages}/artalk/src/editor/plugs/preview-plug.ts (100%) rename {packages => ui/packages}/artalk/src/editor/plugs/upload-plug.ts (100%) rename {packages => ui/packages}/artalk/src/i18n/en.ts (100%) rename {packages => ui/packages}/artalk/src/i18n/index.ts (100%) rename {packages => ui/packages}/artalk/src/i18n/jp.ts (100%) rename {packages => ui/packages}/artalk/src/i18n/zh-CN.ts (100%) rename {packages => ui/packages}/artalk/src/i18n/zh-TW.ts (100%) rename {packages => ui/packages}/artalk/src/layer/index.ts (100%) rename {packages => ui/packages}/artalk/src/layer/layer.ts (100%) rename {packages => ui/packages}/artalk/src/layer/sidebar-layer.html (100%) rename {packages => ui/packages}/artalk/src/layer/sidebar-layer.ts (100%) rename {packages => ui/packages}/artalk/src/lib/checker/admin-checker.ts (100%) rename {packages => ui/packages}/artalk/src/lib/checker/captcha-checker.ts (100%) rename {packages => ui/packages}/artalk/src/lib/checker/index.ts (100%) rename {packages => ui/packages}/artalk/src/lib/component.ts (100%) rename {packages => ui/packages}/artalk/src/lib/detect.ts (100%) rename {packages => ui/packages}/artalk/src/lib/stat.ts (100%) rename {packages => ui/packages}/artalk/src/lib/ui.ts (100%) rename {packages => ui/packages}/artalk/src/lib/user.ts (100%) rename {packages => ui/packages}/artalk/src/lib/utils.ts (100%) rename {packages => ui/packages}/artalk/src/list/index.ts (100%) rename {packages => ui/packages}/artalk/src/list/list-lite.ts (100%) rename {packages => ui/packages}/artalk/src/list/list-nest.ts (100%) rename {packages => ui/packages}/artalk/src/list/list.html (100%) rename {packages => ui/packages}/artalk/src/list/list.ts (100%) rename {packages => ui/packages}/artalk/src/main.ts (100%) rename {packages => ui/packages}/artalk/src/style/_color.less (100%) rename {packages => ui/packages}/artalk/src/style/_extend.less (100%) rename {packages => ui/packages}/artalk/src/style/_variables.less (100%) rename {packages => ui/packages}/artalk/src/style/comment.less (100%) rename {packages => ui/packages}/artalk/src/style/editor.less (100%) rename {packages => ui/packages}/artalk/src/style/list.less (100%) rename {packages => ui/packages}/artalk/src/style/main.less (100%) rename {packages => ui/packages}/artalk/src/style/pagination.less (100%) rename {packages => ui/packages}/artalk/src/style/sidebar-layer.less (100%) rename {packages => ui/packages}/artalk/test/ArtalkCount.html (100%) rename {packages => ui/packages}/artalk/test/ArtalkI18n.html (100%) rename {packages => ui/packages}/artalk/test/ArtalkLite.html (100%) rename {packages => ui/packages}/artalk/test/CSRF.html (100%) rename {packages => ui/packages}/artalk/tsconfig.json (100%) rename {packages => ui/packages}/artalk/types/artalk-config.d.ts (100%) rename {packages => ui/packages}/artalk/types/artalk-data.d.ts (100%) rename {packages => ui/packages}/artalk/types/context.d.ts (100%) rename {packages => ui/packages}/artalk/types/event.d.ts (100%) rename {packages => ui/packages}/artalk/types/global.d.ts (100%) rename {packages => ui/packages}/artalk/types/plug.d.ts (100%) rename {packages => ui/packages}/artalk/vite-base.config.ts (100%) rename {packages => ui/packages}/artalk/vite-demo.config.ts (100%) rename {packages => ui/packages}/artalk/vite-lite.config.ts (100%) rename {packages => ui/packages}/artalk/vite.config.ts (100%) rename {packages => ui/packages}/plugin-katex/README.md (100%) rename {packages => ui/packages}/plugin-katex/index.html (100%) rename {packages => ui/packages}/plugin-katex/main.ts (100%) rename {packages => ui/packages}/plugin-katex/package.json (100%) rename {packages => ui/packages}/plugin-katex/tsconfig.json (100%) rename {packages => ui/packages}/plugin-katex/vite.config.ts (100%) rename {packages => ui/packages}/plugin-lightbox/README.md (100%) rename {packages => ui/packages}/plugin-lightbox/global.d.ts (100%) rename {packages => ui/packages}/plugin-lightbox/index.html (100%) rename {packages => ui/packages}/plugin-lightbox/main.ts (100%) rename {packages => ui/packages}/plugin-lightbox/package.json (100%) rename {packages => ui/packages}/plugin-lightbox/tsconfig.json (100%) rename {packages => ui/packages}/plugin-lightbox/vite.config.ts (100%) rename pnpm-lock.yaml => ui/pnpm-lock.yaml (100%) rename pnpm-workspace.yaml => ui/pnpm-workspace.yaml (100%) rename tsconfig.base.json => ui/tsconfig.base.json (100%) diff --git a/tmp/.circleci/config.yml b/.circleci/config.yml similarity index 100% rename from tmp/.circleci/config.yml rename to .circleci/config.yml diff --git a/.gitignore b/.gitignore index 83780e9ab..40ed9aaaa 100644 --- a/.gitignore +++ b/.gitignore @@ -1,23 +1,52 @@ -.DS_Store -node_modules/ +# Binaries for programs and plugins +*.exe +*.exe~ +*.dll +*.so +*.dylib + +# Test binary, built with `go test -c` +*.test -# Logs -logs -*.log -npm-debug.log* -yarn-debug.log* -yarn-error.log* -.pnpm-debug.log* +# Output of the go coverage tool, specifically when used with LiteIDE +*.out -# Editor directories and files +# Dependency directories (remove the comment below to include it) +# vendor/ + +# Generated files +.DS_Store +.DS_Store? +._* +.Spotlight-V100 +.Trashes +ehthumbs.db +Thumbs.db +.heartbeat .idea -.vscode -*.suo -*.ntvs* -*.njsproj -*.sln +*~ +.goutputstream* +.c9revisions +.settings +.swp +.tmp +.env +.vscode/*.log .history +.release-env + +.pnpm-store +/sysroot +node_modules + +/artalk-go.yml +/config.yml + +/local +/bin +/data +/dist -dist -deploy -local +# always pull latest code and compile +/frontend/sidebar +/frontend/dist diff --git a/tmp/README.md b/BACKEND.md similarity index 100% rename from tmp/README.md rename to BACKEND.md diff --git a/tmp/Dockerfile b/Dockerfile similarity index 100% rename from tmp/Dockerfile rename to Dockerfile diff --git a/tmp/Makefile b/Makefile similarity index 100% rename from tmp/Makefile rename to Makefile diff --git a/tmp/artalk-go.example.yml b/artalk-go.example.yml similarity index 100% rename from tmp/artalk-go.example.yml rename to artalk-go.example.yml diff --git a/tmp/cmd/admin.go b/cmd/admin.go similarity index 100% rename from tmp/cmd/admin.go rename to cmd/admin.go diff --git a/tmp/cmd/export.go b/cmd/export.go similarity index 100% rename from tmp/cmd/export.go rename to cmd/export.go diff --git a/tmp/cmd/gen.go b/cmd/gen.go similarity index 100% rename from tmp/cmd/gen.go rename to cmd/gen.go diff --git a/tmp/cmd/import.go b/cmd/import.go similarity index 100% rename from tmp/cmd/import.go rename to cmd/import.go diff --git a/tmp/cmd/root.go b/cmd/root.go similarity index 100% rename from tmp/cmd/root.go rename to cmd/root.go diff --git a/tmp/cmd/server.go b/cmd/server.go similarity index 100% rename from tmp/cmd/server.go rename to cmd/server.go diff --git a/tmp/cmd/upgrade.go b/cmd/upgrade.go similarity index 100% rename from tmp/cmd/upgrade.go rename to cmd/upgrade.go diff --git a/tmp/cmd/utils.go b/cmd/utils.go similarity index 100% rename from tmp/cmd/utils.go rename to cmd/utils.go diff --git a/tmp/docker-compose.yml b/docker-compose.yml similarity index 100% rename from tmp/docker-compose.yml rename to docker-compose.yml diff --git a/tmp/docker-entrypoint.sh b/docker-entrypoint.sh similarity index 100% rename from tmp/docker-entrypoint.sh rename to docker-entrypoint.sh diff --git a/tmp/docs/artalk-go.png b/docs/artalk-go.png similarity index 100% rename from tmp/docs/artalk-go.png rename to docs/artalk-go.png diff --git a/tmp/frontend/index.html b/frontend/index.html similarity index 100% rename from tmp/frontend/index.html rename to frontend/index.html diff --git a/packages/artalk-sidebar/public/robots.txt b/frontend/robots.txt similarity index 100% rename from packages/artalk-sidebar/public/robots.txt rename to frontend/robots.txt diff --git a/tmp/go.mod b/go.mod similarity index 100% rename from tmp/go.mod rename to go.mod diff --git a/tmp/go.sum b/go.sum similarity index 100% rename from tmp/go.sum rename to go.sum diff --git a/tmp/internal/anti_spam/anti_spam.go b/internal/anti_spam/anti_spam.go similarity index 100% rename from tmp/internal/anti_spam/anti_spam.go rename to internal/anti_spam/anti_spam.go diff --git a/tmp/internal/anti_spam/anti_spam_akismet.go b/internal/anti_spam/anti_spam_akismet.go similarity index 100% rename from tmp/internal/anti_spam/anti_spam_akismet.go rename to internal/anti_spam/anti_spam_akismet.go diff --git a/tmp/internal/anti_spam/anti_spam_aliyun.go b/internal/anti_spam/anti_spam_aliyun.go similarity index 100% rename from tmp/internal/anti_spam/anti_spam_aliyun.go rename to internal/anti_spam/anti_spam_aliyun.go diff --git a/tmp/internal/anti_spam/anti_spam_tencent.go b/internal/anti_spam/anti_spam_tencent.go similarity index 100% rename from tmp/internal/anti_spam/anti_spam_tencent.go rename to internal/anti_spam/anti_spam_tencent.go diff --git a/tmp/internal/artransfer/artrans.go b/internal/artransfer/artrans.go similarity index 100% rename from tmp/internal/artransfer/artrans.go rename to internal/artransfer/artrans.go diff --git a/tmp/internal/artransfer/example.go b/internal/artransfer/example.go similarity index 100% rename from tmp/internal/artransfer/example.go rename to internal/artransfer/example.go diff --git a/tmp/internal/artransfer/exporter.go b/internal/artransfer/exporter.go similarity index 100% rename from tmp/internal/artransfer/exporter.go rename to internal/artransfer/exporter.go diff --git a/tmp/internal/artransfer/importer.go b/internal/artransfer/importer.go similarity index 100% rename from tmp/internal/artransfer/importer.go rename to internal/artransfer/importer.go diff --git a/tmp/internal/artransfer/output.go b/internal/artransfer/output.go similarity index 100% rename from tmp/internal/artransfer/output.go rename to internal/artransfer/output.go diff --git a/tmp/internal/cache/actions.go b/internal/cache/actions.go similarity index 100% rename from tmp/internal/cache/actions.go rename to internal/cache/actions.go diff --git a/tmp/internal/cache/cache.go b/internal/cache/cache.go similarity index 100% rename from tmp/internal/cache/cache.go rename to internal/cache/cache.go diff --git a/tmp/internal/cache/db.go b/internal/cache/db.go similarity index 100% rename from tmp/internal/cache/db.go rename to internal/cache/db.go diff --git a/tmp/internal/cache/operate.go b/internal/cache/operate.go similarity index 100% rename from tmp/internal/cache/operate.go rename to internal/cache/operate.go diff --git a/tmp/internal/captcha/captcha.go b/internal/captcha/captcha.go similarity index 100% rename from tmp/internal/captcha/captcha.go rename to internal/captcha/captcha.go diff --git a/tmp/internal/captcha/geetest.go b/internal/captcha/geetest.go similarity index 100% rename from tmp/internal/captcha/geetest.go rename to internal/captcha/geetest.go diff --git a/tmp/internal/captcha/pages/geetest.html b/internal/captcha/pages/geetest.html similarity index 100% rename from tmp/internal/captcha/pages/geetest.html rename to internal/captcha/pages/geetest.html diff --git a/tmp/internal/config/config.go b/internal/config/config.go similarity index 100% rename from tmp/internal/config/config.go rename to internal/config/config.go diff --git a/tmp/internal/config/const.go b/internal/config/const.go similarity index 100% rename from tmp/internal/config/const.go rename to internal/config/const.go diff --git a/tmp/internal/config/init.go b/internal/config/init.go similarity index 100% rename from tmp/internal/config/init.go rename to internal/config/init.go diff --git a/tmp/internal/config/var.go b/internal/config/var.go similarity index 100% rename from tmp/internal/config/var.go rename to internal/config/var.go diff --git a/tmp/internal/core/core.go b/internal/core/core.go similarity index 100% rename from tmp/internal/core/core.go rename to internal/core/core.go diff --git a/tmp/internal/core/gen.go b/internal/core/gen.go similarity index 100% rename from tmp/internal/core/gen.go rename to internal/core/gen.go diff --git a/tmp/internal/core/sync.go b/internal/core/sync.go similarity index 100% rename from tmp/internal/core/sync.go rename to internal/core/sync.go diff --git a/tmp/internal/db/db.go b/internal/db/db.go similarity index 100% rename from tmp/internal/db/db.go rename to internal/db/db.go diff --git a/tmp/internal/db/gorm_logger.go b/internal/db/gorm_logger.go similarity index 100% rename from tmp/internal/db/gorm_logger.go rename to internal/db/gorm_logger.go diff --git a/tmp/internal/db/migrate.go b/internal/db/migrate.go similarity index 100% rename from tmp/internal/db/migrate.go rename to internal/db/migrate.go diff --git a/tmp/internal/email/email.go b/internal/email/email.go similarity index 100% rename from tmp/internal/email/email.go rename to internal/email/email.go diff --git a/tmp/internal/email/email_tpl/default.html b/internal/email/email_tpl/default.html similarity index 100% rename from tmp/internal/email/email_tpl/default.html rename to internal/email/email_tpl/default.html diff --git a/tmp/internal/email/notify_tpl/default.html b/internal/email/notify_tpl/default.html similarity index 100% rename from tmp/internal/email/notify_tpl/default.html rename to internal/email/notify_tpl/default.html diff --git a/tmp/internal/email/queue.go b/internal/email/queue.go similarity index 100% rename from tmp/internal/email/queue.go rename to internal/email/queue.go diff --git a/tmp/internal/email/render.go b/internal/email/render.go similarity index 100% rename from tmp/internal/email/render.go rename to internal/email/render.go diff --git a/tmp/internal/email/render_test.go b/internal/email/render_test.go similarity index 100% rename from tmp/internal/email/render_test.go rename to internal/email/render_test.go diff --git a/tmp/internal/email/sender.go b/internal/email/sender.go similarity index 100% rename from tmp/internal/email/sender.go rename to internal/email/sender.go diff --git a/tmp/internal/email/sender_alidm.go b/internal/email/sender_alidm.go similarity index 100% rename from tmp/internal/email/sender_alidm.go rename to internal/email/sender_alidm.go diff --git a/tmp/internal/email/sender_cmd.go b/internal/email/sender_cmd.go similarity index 100% rename from tmp/internal/email/sender_cmd.go rename to internal/email/sender_cmd.go diff --git a/tmp/internal/email/sender_smtp.go b/internal/email/sender_smtp.go similarity index 100% rename from tmp/internal/email/sender_smtp.go rename to internal/email/sender_smtp.go diff --git a/tmp/internal/entity/artran.go b/internal/entity/artran.go similarity index 100% rename from tmp/internal/entity/artran.go rename to internal/entity/artran.go diff --git a/tmp/internal/entity/comment.go b/internal/entity/comment.go similarity index 100% rename from tmp/internal/entity/comment.go rename to internal/entity/comment.go diff --git a/tmp/internal/entity/comment_cooked.go b/internal/entity/comment_cooked.go similarity index 100% rename from tmp/internal/entity/comment_cooked.go rename to internal/entity/comment_cooked.go diff --git a/tmp/internal/entity/comment_for_email.go b/internal/entity/comment_for_email.go similarity index 100% rename from tmp/internal/entity/comment_for_email.go rename to internal/entity/comment_for_email.go diff --git a/tmp/internal/entity/notify.go b/internal/entity/notify.go similarity index 100% rename from tmp/internal/entity/notify.go rename to internal/entity/notify.go diff --git a/tmp/internal/entity/notify_cooked.go b/internal/entity/notify_cooked.go similarity index 100% rename from tmp/internal/entity/notify_cooked.go rename to internal/entity/notify_cooked.go diff --git a/tmp/internal/entity/page.go b/internal/entity/page.go similarity index 100% rename from tmp/internal/entity/page.go rename to internal/entity/page.go diff --git a/tmp/internal/entity/page_cooked.go b/internal/entity/page_cooked.go similarity index 100% rename from tmp/internal/entity/page_cooked.go rename to internal/entity/page_cooked.go diff --git a/tmp/internal/entity/site.go b/internal/entity/site.go similarity index 100% rename from tmp/internal/entity/site.go rename to internal/entity/site.go diff --git a/tmp/internal/entity/site_coocked.go b/internal/entity/site_coocked.go similarity index 100% rename from tmp/internal/entity/site_coocked.go rename to internal/entity/site_coocked.go diff --git a/tmp/internal/entity/user.go b/internal/entity/user.go similarity index 100% rename from tmp/internal/entity/user.go rename to internal/entity/user.go diff --git a/tmp/internal/entity/user_cooked.go b/internal/entity/user_cooked.go similarity index 100% rename from tmp/internal/entity/user_cooked.go rename to internal/entity/user_cooked.go diff --git a/tmp/internal/entity/user_for_admin.go b/internal/entity/user_for_admin.go similarity index 100% rename from tmp/internal/entity/user_for_admin.go rename to internal/entity/user_for_admin.go diff --git a/tmp/internal/entity/utils.go b/internal/entity/utils.go similarity index 100% rename from tmp/internal/entity/utils.go rename to internal/entity/utils.go diff --git a/tmp/internal/entity/vote.go b/internal/entity/vote.go similarity index 100% rename from tmp/internal/entity/vote.go rename to internal/entity/vote.go diff --git a/tmp/internal/notify_launcher/init.go b/internal/notify_launcher/init.go similarity index 100% rename from tmp/internal/notify_launcher/init.go rename to internal/notify_launcher/init.go diff --git a/tmp/internal/notify_launcher/notify_launcher.go b/internal/notify_launcher/notify_launcher.go similarity index 100% rename from tmp/internal/notify_launcher/notify_launcher.go rename to internal/notify_launcher/notify_launcher.go diff --git a/tmp/internal/pkged/pkged.go b/internal/pkged/pkged.go similarity index 100% rename from tmp/internal/pkged/pkged.go rename to internal/pkged/pkged.go diff --git a/tmp/internal/query/association.go b/internal/query/association.go similarity index 100% rename from tmp/internal/query/association.go rename to internal/query/association.go diff --git a/tmp/internal/query/cook.go b/internal/query/cook.go similarity index 100% rename from tmp/internal/query/cook.go rename to internal/query/cook.go diff --git a/tmp/internal/query/db.go b/internal/query/db.go similarity index 100% rename from tmp/internal/query/db.go rename to internal/query/db.go diff --git a/tmp/internal/query/db_test.go b/internal/query/db_test.go similarity index 100% rename from tmp/internal/query/db_test.go rename to internal/query/db_test.go diff --git a/tmp/internal/query/fixtures/comments.yml b/internal/query/fixtures/comments.yml similarity index 100% rename from tmp/internal/query/fixtures/comments.yml rename to internal/query/fixtures/comments.yml diff --git a/tmp/internal/query/fixtures/pages.yml b/internal/query/fixtures/pages.yml similarity index 100% rename from tmp/internal/query/fixtures/pages.yml rename to internal/query/fixtures/pages.yml diff --git a/tmp/internal/query/fixtures/sites.yml b/internal/query/fixtures/sites.yml similarity index 100% rename from tmp/internal/query/fixtures/sites.yml rename to internal/query/fixtures/sites.yml diff --git a/tmp/internal/query/fixtures/users.yml b/internal/query/fixtures/users.yml similarity index 100% rename from tmp/internal/query/fixtures/users.yml rename to internal/query/fixtures/users.yml diff --git a/tmp/internal/query/query.go b/internal/query/query.go similarity index 100% rename from tmp/internal/query/query.go rename to internal/query/query.go diff --git a/tmp/internal/query/query_del.go b/internal/query/query_del.go similarity index 100% rename from tmp/internal/query/query_del.go rename to internal/query/query_del.go diff --git a/tmp/internal/query/query_del_test.go b/internal/query/query_del_test.go similarity index 100% rename from tmp/internal/query/query_del_test.go rename to internal/query/query_del_test.go diff --git a/tmp/internal/query/query_find.go b/internal/query/query_find.go similarity index 100% rename from tmp/internal/query/query_find.go rename to internal/query/query_find.go diff --git a/tmp/internal/query/query_find_create.go b/internal/query/query_find_create.go similarity index 100% rename from tmp/internal/query/query_find_create.go rename to internal/query/query_find_create.go diff --git a/tmp/internal/query/query_find_create_test.go b/internal/query/query_find_create_test.go similarity index 100% rename from tmp/internal/query/query_find_create_test.go rename to internal/query/query_find_create_test.go diff --git a/tmp/internal/query/query_find_test.go b/internal/query/query_find_test.go similarity index 100% rename from tmp/internal/query/query_find_test.go rename to internal/query/query_find_test.go diff --git a/tmp/internal/query/query_new.go b/internal/query/query_new.go similarity index 100% rename from tmp/internal/query/query_new.go rename to internal/query/query_new.go diff --git a/tmp/internal/query/query_update.go b/internal/query/query_update.go similarity index 100% rename from tmp/internal/query/query_update.go rename to internal/query/query_update.go diff --git a/tmp/internal/query/service.go b/internal/query/service.go similarity index 100% rename from tmp/internal/query/service.go rename to internal/query/service.go diff --git a/tmp/internal/query/service_test.go b/internal/query/service_test.go similarity index 100% rename from tmp/internal/query/service_test.go rename to internal/query/service_test.go diff --git a/tmp/internal/query/testdata/model_test_conf.yml b/internal/query/testdata/model_test_conf.yml similarity index 100% rename from tmp/internal/query/testdata/model_test_conf.yml rename to internal/query/testdata/model_test_conf.yml diff --git a/tmp/internal/utils/encrypt.go b/internal/utils/encrypt.go similarity index 100% rename from tmp/internal/utils/encrypt.go rename to internal/utils/encrypt.go diff --git a/tmp/internal/utils/fs.go b/internal/utils/fs.go similarity index 100% rename from tmp/internal/utils/fs.go rename to internal/utils/fs.go diff --git a/tmp/internal/utils/markdown.go b/internal/utils/markdown.go similarity index 100% rename from tmp/internal/utils/markdown.go rename to internal/utils/markdown.go diff --git a/tmp/internal/utils/string.go b/internal/utils/string.go similarity index 100% rename from tmp/internal/utils/string.go rename to internal/utils/string.go diff --git a/tmp/internal/utils/struct.go b/internal/utils/struct.go similarity index 100% rename from tmp/internal/utils/struct.go rename to internal/utils/struct.go diff --git a/tmp/internal/utils/utils.go b/internal/utils/utils.go similarity index 100% rename from tmp/internal/utils/utils.go rename to internal/utils/utils.go diff --git a/tmp/internal/utils/validator.go b/internal/utils/validator.go similarity index 100% rename from tmp/internal/utils/validator.go rename to internal/utils/validator.go diff --git a/tmp/main.go b/main.go similarity index 100% rename from tmp/main.go rename to main.go diff --git a/tmp/scripts/benchmark.sh b/scripts/benchmark.sh similarity index 100% rename from tmp/scripts/benchmark.sh rename to scripts/benchmark.sh diff --git a/tmp/scripts/build-frontend.sh b/scripts/build-frontend.sh similarity index 100% rename from tmp/scripts/build-frontend.sh rename to scripts/build-frontend.sh diff --git a/tmp/scripts/docker-build.sh b/scripts/docker-build.sh similarity index 100% rename from tmp/scripts/docker-build.sh rename to scripts/docker-build.sh diff --git a/tmp/server/common/auth.go b/server/common/auth.go similarity index 100% rename from tmp/server/common/auth.go rename to server/common/auth.go diff --git a/tmp/server/common/captcha.go b/server/common/captcha.go similarity index 100% rename from tmp/server/common/captcha.go rename to server/common/captcha.go diff --git a/tmp/server/common/check.go b/server/common/check.go similarity index 100% rename from tmp/server/common/check.go rename to server/common/check.go diff --git a/tmp/server/common/conf.go b/server/common/conf.go similarity index 100% rename from tmp/server/common/conf.go rename to server/common/conf.go diff --git a/tmp/server/common/cors.go b/server/common/cors.go similarity index 100% rename from tmp/server/common/cors.go rename to server/common/cors.go diff --git a/tmp/server/common/params.go b/server/common/params.go similarity index 100% rename from tmp/server/common/params.go rename to server/common/params.go diff --git a/tmp/server/common/resp.go b/server/common/resp.go similarity index 100% rename from tmp/server/common/resp.go rename to server/common/resp.go diff --git a/tmp/server/common/site.go b/server/common/site.go similarity index 100% rename from tmp/server/common/site.go rename to server/common/site.go diff --git a/tmp/server/handler/admin_cache.go b/server/handler/admin_cache.go similarity index 100% rename from tmp/server/handler/admin_cache.go rename to server/handler/admin_cache.go diff --git a/tmp/server/handler/admin_comment_del.go b/server/handler/admin_comment_del.go similarity index 100% rename from tmp/server/handler/admin_comment_del.go rename to server/handler/admin_comment_del.go diff --git a/tmp/server/handler/admin_comment_edit.go b/server/handler/admin_comment_edit.go similarity index 100% rename from tmp/server/handler/admin_comment_edit.go rename to server/handler/admin_comment_edit.go diff --git a/tmp/server/handler/admin_page_del.go b/server/handler/admin_page_del.go similarity index 100% rename from tmp/server/handler/admin_page_del.go rename to server/handler/admin_page_del.go diff --git a/tmp/server/handler/admin_page_edit.go b/server/handler/admin_page_edit.go similarity index 100% rename from tmp/server/handler/admin_page_edit.go rename to server/handler/admin_page_edit.go diff --git a/tmp/server/handler/admin_page_fetch.go b/server/handler/admin_page_fetch.go similarity index 100% rename from tmp/server/handler/admin_page_fetch.go rename to server/handler/admin_page_fetch.go diff --git a/tmp/server/handler/admin_page_get.go b/server/handler/admin_page_get.go similarity index 100% rename from tmp/server/handler/admin_page_get.go rename to server/handler/admin_page_get.go diff --git a/tmp/server/handler/admin_send_mail.go b/server/handler/admin_send_mail.go similarity index 100% rename from tmp/server/handler/admin_send_mail.go rename to server/handler/admin_send_mail.go diff --git a/tmp/server/handler/admin_setting.go b/server/handler/admin_setting.go similarity index 100% rename from tmp/server/handler/admin_setting.go rename to server/handler/admin_setting.go diff --git a/tmp/server/handler/admin_site_add.go b/server/handler/admin_site_add.go similarity index 100% rename from tmp/server/handler/admin_site_add.go rename to server/handler/admin_site_add.go diff --git a/tmp/server/handler/admin_site_del.go b/server/handler/admin_site_del.go similarity index 100% rename from tmp/server/handler/admin_site_del.go rename to server/handler/admin_site_del.go diff --git a/tmp/server/handler/admin_site_edit.go b/server/handler/admin_site_edit.go similarity index 100% rename from tmp/server/handler/admin_site_edit.go rename to server/handler/admin_site_edit.go diff --git a/tmp/server/handler/admin_site_get.go b/server/handler/admin_site_get.go similarity index 100% rename from tmp/server/handler/admin_site_get.go rename to server/handler/admin_site_get.go diff --git a/tmp/server/handler/admin_transfer.go b/server/handler/admin_transfer.go similarity index 100% rename from tmp/server/handler/admin_transfer.go rename to server/handler/admin_transfer.go diff --git a/tmp/server/handler/admin_user_add.go b/server/handler/admin_user_add.go similarity index 100% rename from tmp/server/handler/admin_user_add.go rename to server/handler/admin_user_add.go diff --git a/tmp/server/handler/admin_user_del.go b/server/handler/admin_user_del.go similarity index 100% rename from tmp/server/handler/admin_user_del.go rename to server/handler/admin_user_del.go diff --git a/tmp/server/handler/admin_user_edit.go b/server/handler/admin_user_edit.go similarity index 100% rename from tmp/server/handler/admin_user_edit.go rename to server/handler/admin_user_edit.go diff --git a/tmp/server/handler/admin_user_get.go b/server/handler/admin_user_get.go similarity index 100% rename from tmp/server/handler/admin_user_get.go rename to server/handler/admin_user_get.go diff --git a/tmp/server/handler/admin_vote_sync.go b/server/handler/admin_vote_sync.go similarity index 100% rename from tmp/server/handler/admin_vote_sync.go rename to server/handler/admin_vote_sync.go diff --git a/tmp/server/handler/captcha.go b/server/handler/captcha.go similarity index 100% rename from tmp/server/handler/captcha.go rename to server/handler/captcha.go diff --git a/tmp/server/handler/comment_add.go b/server/handler/comment_add.go similarity index 100% rename from tmp/server/handler/comment_add.go rename to server/handler/comment_add.go diff --git a/tmp/server/handler/comment_get.go b/server/handler/comment_get.go similarity index 100% rename from tmp/server/handler/comment_get.go rename to server/handler/comment_get.go diff --git a/tmp/server/handler/comment_get_query.go b/server/handler/comment_get_query.go similarity index 100% rename from tmp/server/handler/comment_get_query.go rename to server/handler/comment_get_query.go diff --git a/tmp/server/handler/conf.go b/server/handler/conf.go similarity index 100% rename from tmp/server/handler/conf.go rename to server/handler/conf.go diff --git a/tmp/server/handler/img_upload.go b/server/handler/img_upload.go similarity index 100% rename from tmp/server/handler/img_upload.go rename to server/handler/img_upload.go diff --git a/tmp/server/handler/mark_read.go b/server/handler/mark_read.go similarity index 100% rename from tmp/server/handler/mark_read.go rename to server/handler/mark_read.go diff --git a/tmp/server/handler/pv.go b/server/handler/pv.go similarity index 100% rename from tmp/server/handler/pv.go rename to server/handler/pv.go diff --git a/tmp/server/handler/stat.go b/server/handler/stat.go similarity index 100% rename from tmp/server/handler/stat.go rename to server/handler/stat.go diff --git a/tmp/server/handler/user_get.go b/server/handler/user_get.go similarity index 100% rename from tmp/server/handler/user_get.go rename to server/handler/user_get.go diff --git a/tmp/server/handler/user_login.go b/server/handler/user_login.go similarity index 100% rename from tmp/server/handler/user_login.go rename to server/handler/user_login.go diff --git a/tmp/server/handler/user_logout.go b/server/handler/user_logout.go similarity index 100% rename from tmp/server/handler/user_logout.go rename to server/handler/user_logout.go diff --git a/tmp/server/handler/version.go b/server/handler/version.go similarity index 100% rename from tmp/server/handler/version.go rename to server/handler/version.go diff --git a/tmp/server/handler/vote.go b/server/handler/vote.go similarity index 100% rename from tmp/server/handler/vote.go rename to server/handler/vote.go diff --git a/tmp/server/middleware/admin.go b/server/middleware/admin.go similarity index 100% rename from tmp/server/middleware/admin.go rename to server/middleware/admin.go diff --git a/tmp/server/middleware/cors.go b/server/middleware/cors.go similarity index 100% rename from tmp/server/middleware/cors.go rename to server/middleware/cors.go diff --git a/tmp/server/middleware/cors/cors.go b/server/middleware/cors/cors.go similarity index 100% rename from tmp/server/middleware/cors/cors.go rename to server/middleware/cors/cors.go diff --git a/tmp/server/middleware/cors/utils.go b/server/middleware/cors/utils.go similarity index 100% rename from tmp/server/middleware/cors/utils.go rename to server/middleware/cors/utils.go diff --git a/tmp/server/middleware/limit.go b/server/middleware/limit.go similarity index 100% rename from tmp/server/middleware/limit.go rename to server/middleware/limit.go diff --git a/tmp/server/middleware/site_origin.go b/server/middleware/site_origin.go similarity index 100% rename from tmp/server/middleware/site_origin.go rename to server/middleware/site_origin.go diff --git a/tmp/server/middleware/site_origin_test.go b/server/middleware/site_origin_test.go similarity index 100% rename from tmp/server/middleware/site_origin_test.go rename to server/middleware/site_origin_test.go diff --git a/tmp/server/server.go b/server/server.go similarity index 100% rename from tmp/server/server.go rename to server/server.go diff --git a/tmp/.github/dependabot.yml b/tmp/.github/dependabot.yml deleted file mode 100644 index e0871f93f..000000000 --- a/tmp/.github/dependabot.yml +++ /dev/null @@ -1,11 +0,0 @@ -# To get started with Dependabot version updates, you'll need to specify which -# package ecosystems to update and where the package manifests are located. -# Please see the documentation for all configuration options: -# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates - -version: 2 -updates: - - package-ecosystem: "gomod" # See documentation for possible values - directory: "/" # Location of package manifests - schedule: - interval: "weekly" diff --git a/tmp/.github/workflows/codeql.yml b/tmp/.github/workflows/codeql.yml deleted file mode 100644 index cd715a8d4..000000000 --- a/tmp/.github/workflows/codeql.yml +++ /dev/null @@ -1,74 +0,0 @@ -# For most projects, this workflow file will not need changing; you simply need -# to commit it to your repository. -# -# You may wish to alter this file to override the set of languages analyzed, -# or to provide custom queries or build logic. -# -# ******** NOTE ******** -# We have attempted to detect the languages in your repository. Please check -# the `language` matrix defined below to confirm you have the correct set of -# supported CodeQL languages. -# -name: "CodeQL" - -on: - push: - branches: [ "master" ] - pull_request: - # The branches below must be a subset of the branches above - branches: [ "master" ] - schedule: - - cron: '37 1 * * 4' - -jobs: - analyze: - name: Analyze - runs-on: ubuntu-latest - permissions: - actions: read - contents: read - security-events: write - - strategy: - fail-fast: false - matrix: - language: [ 'go' ] - # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ] - # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support - - steps: - - name: Checkout repository - uses: actions/checkout@v3 - - # Initializes the CodeQL tools for scanning. - - name: Initialize CodeQL - uses: github/codeql-action/init@v2 - with: - languages: ${{ matrix.language }} - # If you wish to specify custom queries, you can do so here or in a config file. - # By default, queries listed here will override any specified in a config file. - # Prefix the list here with "+" to use these queries and those in the config file. - - # Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs - # queries: security-extended,security-and-quality - - - # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). - # If this step fails, then you should remove it and run the build manually (see below) - - name: Autobuild - uses: github/codeql-action/autobuild@v2 - - # ℹ️ Command-line programs to run using the OS shell. - # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun - - # If the Autobuild fails above, remove it and uncomment the following three lines. - # modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance. - - # - run: | - # echo "Run, Build Application using script" - # ./location_of_script_within_repo/buildscript.sh - - - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v2 - with: - category: "/language:${{matrix.language}}" diff --git a/tmp/.github/workflows/dockerhub.yml b/tmp/.github/workflows/dockerhub.yml deleted file mode 100644 index 3a9d6af3f..000000000 --- a/tmp/.github/workflows/dockerhub.yml +++ /dev/null @@ -1,83 +0,0 @@ -name: CI to Docker Hub - -on: - push: - # branches: - # - "master" - tags: - - "v*" - # pull_request: - # branches: - # - "master" - -jobs: - docker: - runs-on: ubuntu-latest - - steps: - - name: Checkout - uses: actions/checkout@master - - run: | - git fetch --prune --unshallow --tags -f - - - name: Login to DockerHub - uses: docker/login-action@v1 - with: - username: ${{ secrets.DOCKERHUB_USERNAME }} - password: ${{ secrets.DOCKERHUB_TOKEN }} - - - name: Set up Docker Buildx - id: buildx - uses: docker/setup-buildx-action@master - - # Docker tag 值生成 - # https://github.com/docker/metadata-action - - name: Docker meta - id: meta - uses: docker/metadata-action@v3 - with: - images: | - ${{ secrets.DOCKERHUB_USERNAME }}/artalk-go - tags: | - type=ref,event=branch - type=ref,event=pr - type=semver,pattern={{version}} - type=semver,pattern={{major}}.{{minor}} - type=sha - - # 编译多平台 - # https://github.com/docker/setup-qemu-action - # - name: Set up QEMU - # id: qemu - # uses: docker/setup-qemu-action@v1 - # with: - # platforms: all - - # 缓存 Docker - - name: Cache Docker layers - uses: actions/cache@v2 - with: - path: /tmp/.buildx-cache - key: ${{ runner.os }}-buildx-${{ github.sha }} - restore-keys: | - ${{ runner.os }}-buildx- - - # build docker image - # https://github.com/docker/build-push-action - - name: Build and push - id: docker_build - uses: docker/build-push-action@v2 - with: - builder: ${{ steps.buildx.outputs.name }} - context: ./ - file: ./Dockerfile - # platforms: linux/amd64,linux/arm64,linux/arm/v7 - push: true - tags: ${{ steps.meta.outputs.tags }} - labels: ${{ steps.meta.outputs.labels }} - # 缓存 - cache-from: type=local,src=/tmp/.buildx-cache - cache-to: type=local,dest=/tmp/.buildx-cache - - - name: Image digest - run: echo ${{ steps.docker_build.outputs.digest }} diff --git a/tmp/.github/workflows/release.yml b/tmp/.github/workflows/release.yml deleted file mode 100644 index 466b568e0..000000000 --- a/tmp/.github/workflows/release.yml +++ /dev/null @@ -1,50 +0,0 @@ -name: Release Build - -on: - push: - tags: - - v* - -jobs: - release: - runs-on: ubuntu-latest - - steps: - - name: checkout code - uses: actions/checkout@v3 - - run: git fetch --prune --unshallow --tags -f - - - name: setup go - uses: actions/setup-go@v3 - with: - go-version: '^1.19.4' - - # docker `golang-cross` image cache - # `cache-go-cross-v1-19-4` - - run: mkdir -p ~/docker-cache - - name: docker image cache - id: cache-go-cross-v1-19-4 - uses: actions/cache@v2 - with: - path: ~/docker-cache - # Adjust key to meet your cache time requirements e.g. - # ${{ hashFiles(*) }} can be useful here to invalidate - # cache on file changes - key: cache-go-cross-v1-19-4 - - - if: steps.cache-go-cross-v1-19-4.outputs.cache-hit != 'true' - run: | - docker pull ghcr.io/goreleaser/goreleaser-cross:v1.19.4 - docker save -o ~/docker-cache/golang-cross.tar ghcr.io/goreleaser/goreleaser-cross:v1.19.4 - - - if: steps.cache-go-cross-v1-19-4.outputs.cache-hit == 'true' - run: docker load -i ~/docker-cache/golang-cross.tar - - # build - - name: setup release environment - run: |- - cp artalk-go.example.yml artalk-go.yml - echo 'GITHUB_TOKEN=${{secrets.GORELEASER_ACCESS_TOKEN}}' > .release-env - - - name: build and release publish - run: make release diff --git a/tmp/.gitignore b/tmp/.gitignore deleted file mode 100644 index 40ed9aaaa..000000000 --- a/tmp/.gitignore +++ /dev/null @@ -1,52 +0,0 @@ -# Binaries for programs and plugins -*.exe -*.exe~ -*.dll -*.so -*.dylib - -# Test binary, built with `go test -c` -*.test - -# Output of the go coverage tool, specifically when used with LiteIDE -*.out - -# Dependency directories (remove the comment below to include it) -# vendor/ - -# Generated files -.DS_Store -.DS_Store? -._* -.Spotlight-V100 -.Trashes -ehthumbs.db -Thumbs.db -.heartbeat -.idea -*~ -.goutputstream* -.c9revisions -.settings -.swp -.tmp -.env -.vscode/*.log -.history -.release-env - -.pnpm-store -/sysroot -node_modules - -/artalk-go.yml -/config.yml - -/local -/bin -/data -/dist - -# always pull latest code and compile -/frontend/sidebar -/frontend/dist diff --git a/tmp/.goreleaser.yml b/tmp/.goreleaser.yml deleted file mode 100644 index e4119b8a8..000000000 --- a/tmp/.goreleaser.yml +++ /dev/null @@ -1,155 +0,0 @@ -# Goreleaser Config -# -# https://goreleaser.com/quick-start/ -# https://goreleaser.com/customization/ -# https://goreleaser.com/customization/templates/ -# https://goreleaser.com/customization/fury/ -# https://goreleaser.com/customization/announce/telegram/ - -project_name: artalk-go - -env: - - GO111MODULE=on - - CGO_ENABLED=1 - -before: - hooks: - # install dependencies - - make install - - make build-frontend - - make update - -# build multi-platform -builds: - ## Amd 64 - - # Linux (amd_64) - - id: linux-amd64 - goos: - - linux - goarch: - - amd64 - env: - - CC=gcc - - CXX=g++ - binary: "{{.ProjectName}}" - main: ./main.go - ldflags: &common_ldflags | - -X github.com/ArtalkJS/ArtalkGo/internal/config.Version={{.Version}} - -X github.com/ArtalkJS/ArtalkGo/internal/config.CommitHash={{ .ShortCommit }} - -s -w - - # Windows (amd_64) - - id: windows-amd64 - goos: - - windows - goarch: - - amd64 - env: - - CC=x86_64-w64-mingw32-gcc - - CXX=x86_64-w64-mingw32-g++ - binary: "{{.ProjectName}}" - main: ./main.go - ldflags: *common_ldflags - flags: - # https://go-review.googlesource.com/c/go/+/224588/ - # https://github.com/ArtalkJS/ArtalkGo/issues/35 - - -tags=timetzdata - - # Darwin (amd_64) - - id: darwin-amd64 - goos: - - darwin - goarch: - - amd64 - env: - - CC=o64-clang - - CXX=o64-clang++ - binary: "{{.ProjectName}}" - main: ./main.go - ldflags: *common_ldflags - - ## Arm - - # Linux (arm_v7) - - id: linux-armhf - goos: - - linux - goarch: - - arm - goarm: - - 7 - env: - - CC=arm-linux-gnueabihf-gcc - - CXX=arm-linux-gnueabihf-g++ - binary: "{{.ProjectName}}" - main: ./main.go - ldflags: *common_ldflags - - # Linux (arm_64) - - id: linux-arm64 - goos: - - linux - goarch: - - arm64 - env: - - CC=aarch64-linux-gnu-gcc - - CXX=aarch64-linux-gnu-g++ - binary: "{{.ProjectName}}" - main: ./main.go - ldflags: *common_ldflags - - # Darwin (arm_64) - - id: darwin-arm64 - goos: - - darwin - goarch: - - arm64 - env: - - CC=oa64-clang - - CXX=oa64-clang++ - binary: "{{.ProjectName}}" - main: ./main.go - ldflags: *common_ldflags - -archives: - - id: artalk-go - builds: - - linux-amd64 - - darwin-amd64 - - windows-amd64 - - linux-armhf - - linux-arm64 - - darwin-arm64 - name_template: "{{.ProjectName}}_v{{.Version}}_{{.Os}}_{{.Arch}}{{.Arm}}" - format: tar.gz - format_overrides: - - goos: windows - format: zip - wrap_in_directory: true - files: - - README* - - LICENSE* - - artalk-go.yml - -checksum: - name_template: 'checksums.txt' - -snapshot: - name_template: "{{.Version}}-SNAPSHOT-{{.ShortCommit}}" - -# changelog -changelog: - sort: asc - filters: - exclude: - - '^docs:' - - '^test:' - - '^chore:' - -release: - github: - owner: ArtalkJS - name: ArtalkGo - prerelease: auto - draft: true diff --git a/tmp/LICENSE b/tmp/LICENSE deleted file mode 100644 index 0a041280b..000000000 --- a/tmp/LICENSE +++ /dev/null @@ -1,165 +0,0 @@ - GNU LESSER GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - - This version of the GNU Lesser General Public License incorporates -the terms and conditions of version 3 of the GNU General Public -License, supplemented by the additional permissions listed below. - - 0. Additional Definitions. - - As used herein, "this License" refers to version 3 of the GNU Lesser -General Public License, and the "GNU GPL" refers to version 3 of the GNU -General Public License. - - "The Library" refers to a covered work governed by this License, -other than an Application or a Combined Work as defined below. - - An "Application" is any work that makes use of an interface provided -by the Library, but which is not otherwise based on the Library. -Defining a subclass of a class defined by the Library is deemed a mode -of using an interface provided by the Library. - - A "Combined Work" is a work produced by combining or linking an -Application with the Library. The particular version of the Library -with which the Combined Work was made is also called the "Linked -Version". - - The "Minimal Corresponding Source" for a Combined Work means the -Corresponding Source for the Combined Work, excluding any source code -for portions of the Combined Work that, considered in isolation, are -based on the Application, and not on the Linked Version. - - The "Corresponding Application Code" for a Combined Work means the -object code and/or source code for the Application, including any data -and utility programs needed for reproducing the Combined Work from the -Application, but excluding the System Libraries of the Combined Work. - - 1. Exception to Section 3 of the GNU GPL. - - You may convey a covered work under sections 3 and 4 of this License -without being bound by section 3 of the GNU GPL. - - 2. Conveying Modified Versions. - - If you modify a copy of the Library, and, in your modifications, a -facility refers to a function or data to be supplied by an Application -that uses the facility (other than as an argument passed when the -facility is invoked), then you may convey a copy of the modified -version: - - a) under this License, provided that you make a good faith effort to - ensure that, in the event an Application does not supply the - function or data, the facility still operates, and performs - whatever part of its purpose remains meaningful, or - - b) under the GNU GPL, with none of the additional permissions of - this License applicable to that copy. - - 3. Object Code Incorporating Material from Library Header Files. - - The object code form of an Application may incorporate material from -a header file that is part of the Library. You may convey such object -code under terms of your choice, provided that, if the incorporated -material is not limited to numerical parameters, data structure -layouts and accessors, or small macros, inline functions and templates -(ten or fewer lines in length), you do both of the following: - - a) Give prominent notice with each copy of the object code that the - Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the object code with a copy of the GNU GPL and this license - document. - - 4. Combined Works. - - You may convey a Combined Work under terms of your choice that, -taken together, effectively do not restrict modification of the -portions of the Library contained in the Combined Work and reverse -engineering for debugging such modifications, if you also do each of -the following: - - a) Give prominent notice with each copy of the Combined Work that - the Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the Combined Work with a copy of the GNU GPL and this license - document. - - c) For a Combined Work that displays copyright notices during - execution, include the copyright notice for the Library among - these notices, as well as a reference directing the user to the - copies of the GNU GPL and this license document. - - d) Do one of the following: - - 0) Convey the Minimal Corresponding Source under the terms of this - License, and the Corresponding Application Code in a form - suitable for, and under terms that permit, the user to - recombine or relink the Application with a modified version of - the Linked Version to produce a modified Combined Work, in the - manner specified by section 6 of the GNU GPL for conveying - Corresponding Source. - - 1) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (a) uses at run time - a copy of the Library already present on the user's computer - system, and (b) will operate properly with a modified version - of the Library that is interface-compatible with the Linked - Version. - - e) Provide Installation Information, but only if you would otherwise - be required to provide such information under section 6 of the - GNU GPL, and only to the extent that such information is - necessary to install and execute a modified version of the - Combined Work produced by recombining or relinking the - Application with a modified version of the Linked Version. (If - you use option 4d0, the Installation Information must accompany - the Minimal Corresponding Source and Corresponding Application - Code. If you use option 4d1, you must provide the Installation - Information in the manner specified by section 6 of the GNU GPL - for conveying Corresponding Source.) - - 5. Combined Libraries. - - You may place library facilities that are a work based on the -Library side by side in a single library together with other library -facilities that are not Applications and are not covered by this -License, and convey such a combined library under terms of your -choice, if you do both of the following: - - a) Accompany the combined library with a copy of the same work based - on the Library, uncombined with any other library facilities, - conveyed under the terms of this License. - - b) Give prominent notice with the combined library that part of it - is a work based on the Library, and explaining where to find the - accompanying uncombined form of the same work. - - 6. Revised Versions of the GNU Lesser General Public License. - - The Free Software Foundation may publish revised and/or new versions -of the GNU Lesser General Public License from time to time. Such new -versions will be similar in spirit to the present version, but may -differ in detail to address new problems or concerns. - - Each version is given a distinguishing version number. If the -Library as you received it specifies that a certain numbered version -of the GNU Lesser General Public License "or any later version" -applies to it, you have the option of following the terms and -conditions either of that published version or of any later version -published by the Free Software Foundation. If the Library as you -received it does not specify a version number of the GNU Lesser -General Public License, you may choose any version of the GNU Lesser -General Public License ever published by the Free Software Foundation. - - If the Library as you received it specifies that a proxy can decide -whether future versions of the GNU Lesser General Public License shall -apply, that proxy's public statement of acceptance of any version is -permanent authorization for you to choose that version for the -Library. diff --git a/.eslintignore b/ui/.eslintignore similarity index 100% rename from .eslintignore rename to ui/.eslintignore diff --git a/.eslintrc.js b/ui/.eslintrc.js similarity index 100% rename from .eslintrc.js rename to ui/.eslintrc.js diff --git a/ui/.gitignore b/ui/.gitignore new file mode 100644 index 000000000..83780e9ab --- /dev/null +++ b/ui/.gitignore @@ -0,0 +1,23 @@ +.DS_Store +node_modules/ + +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +.pnpm-debug.log* + +# Editor directories and files +.idea +.vscode +*.suo +*.ntvs* +*.njsproj +*.sln +.history + +dist +deploy +local diff --git a/.npmignore b/ui/.npmignore similarity index 100% rename from .npmignore rename to ui/.npmignore diff --git a/.prettierrc b/ui/.prettierrc similarity index 100% rename from .prettierrc rename to ui/.prettierrc diff --git a/.travis.yml b/ui/.travis.yml similarity index 100% rename from .travis.yml rename to ui/.travis.yml diff --git a/package.json b/ui/package.json similarity index 100% rename from package.json rename to ui/package.json diff --git a/packages/artalk-sidebar/.eslintrc.js b/ui/packages/artalk-sidebar/.eslintrc.js similarity index 100% rename from packages/artalk-sidebar/.eslintrc.js rename to ui/packages/artalk-sidebar/.eslintrc.js diff --git a/packages/artalk-sidebar/.gitignore b/ui/packages/artalk-sidebar/.gitignore similarity index 100% rename from packages/artalk-sidebar/.gitignore rename to ui/packages/artalk-sidebar/.gitignore diff --git a/packages/artalk-sidebar/README.md b/ui/packages/artalk-sidebar/README.md similarity index 100% rename from packages/artalk-sidebar/README.md rename to ui/packages/artalk-sidebar/README.md diff --git a/packages/artalk-sidebar/auto-imports.d.ts b/ui/packages/artalk-sidebar/auto-imports.d.ts similarity index 100% rename from packages/artalk-sidebar/auto-imports.d.ts rename to ui/packages/artalk-sidebar/auto-imports.d.ts diff --git a/packages/artalk-sidebar/components.d.ts b/ui/packages/artalk-sidebar/components.d.ts similarity index 100% rename from packages/artalk-sidebar/components.d.ts rename to ui/packages/artalk-sidebar/components.d.ts diff --git a/packages/artalk-sidebar/index.html b/ui/packages/artalk-sidebar/index.html similarity index 100% rename from packages/artalk-sidebar/index.html rename to ui/packages/artalk-sidebar/index.html diff --git a/packages/artalk-sidebar/package.json b/ui/packages/artalk-sidebar/package.json similarity index 100% rename from packages/artalk-sidebar/package.json rename to ui/packages/artalk-sidebar/package.json diff --git a/tmp/frontend/robots.txt b/ui/packages/artalk-sidebar/public/robots.txt similarity index 100% rename from tmp/frontend/robots.txt rename to ui/packages/artalk-sidebar/public/robots.txt diff --git a/packages/artalk-sidebar/scripts/fetch-conf-tpl.js b/ui/packages/artalk-sidebar/scripts/fetch-conf-tpl.js similarity index 100% rename from packages/artalk-sidebar/scripts/fetch-conf-tpl.js rename to ui/packages/artalk-sidebar/scripts/fetch-conf-tpl.js diff --git a/packages/artalk-sidebar/src/App.vue b/ui/packages/artalk-sidebar/src/App.vue similarity index 100% rename from packages/artalk-sidebar/src/App.vue rename to ui/packages/artalk-sidebar/src/App.vue diff --git a/packages/artalk-sidebar/src/assets/artalk-go.example.yml b/ui/packages/artalk-sidebar/src/assets/artalk-go.example.yml similarity index 100% rename from packages/artalk-sidebar/src/assets/artalk-go.example.yml rename to ui/packages/artalk-sidebar/src/assets/artalk-go.example.yml diff --git a/packages/artalk-sidebar/src/assets/favicon.png b/ui/packages/artalk-sidebar/src/assets/favicon.png similarity index 100% rename from packages/artalk-sidebar/src/assets/favicon.png rename to ui/packages/artalk-sidebar/src/assets/favicon.png diff --git a/packages/artalk-sidebar/src/components/FileUploader.vue b/ui/packages/artalk-sidebar/src/components/FileUploader.vue similarity index 100% rename from packages/artalk-sidebar/src/components/FileUploader.vue rename to ui/packages/artalk-sidebar/src/components/FileUploader.vue diff --git a/packages/artalk-sidebar/src/components/Header.vue b/ui/packages/artalk-sidebar/src/components/Header.vue similarity index 100% rename from packages/artalk-sidebar/src/components/Header.vue rename to ui/packages/artalk-sidebar/src/components/Header.vue diff --git a/packages/artalk-sidebar/src/components/ItemTextEditor.vue b/ui/packages/artalk-sidebar/src/components/ItemTextEditor.vue similarity index 100% rename from packages/artalk-sidebar/src/components/ItemTextEditor.vue rename to ui/packages/artalk-sidebar/src/components/ItemTextEditor.vue diff --git a/packages/artalk-sidebar/src/components/LoadingLayer.vue b/ui/packages/artalk-sidebar/src/components/LoadingLayer.vue similarity index 100% rename from packages/artalk-sidebar/src/components/LoadingLayer.vue rename to ui/packages/artalk-sidebar/src/components/LoadingLayer.vue diff --git a/packages/artalk-sidebar/src/components/LogTerminal.vue b/ui/packages/artalk-sidebar/src/components/LogTerminal.vue similarity index 100% rename from packages/artalk-sidebar/src/components/LogTerminal.vue rename to ui/packages/artalk-sidebar/src/components/LogTerminal.vue diff --git a/packages/artalk-sidebar/src/components/PageEditor.vue b/ui/packages/artalk-sidebar/src/components/PageEditor.vue similarity index 100% rename from packages/artalk-sidebar/src/components/PageEditor.vue rename to ui/packages/artalk-sidebar/src/components/PageEditor.vue diff --git a/packages/artalk-sidebar/src/components/Pagination.vue b/ui/packages/artalk-sidebar/src/components/Pagination.vue similarity index 100% rename from packages/artalk-sidebar/src/components/Pagination.vue rename to ui/packages/artalk-sidebar/src/components/Pagination.vue diff --git a/packages/artalk-sidebar/src/components/PreferenceArr.vue b/ui/packages/artalk-sidebar/src/components/PreferenceArr.vue similarity index 100% rename from packages/artalk-sidebar/src/components/PreferenceArr.vue rename to ui/packages/artalk-sidebar/src/components/PreferenceArr.vue diff --git a/packages/artalk-sidebar/src/components/PreferenceGrp.vue b/ui/packages/artalk-sidebar/src/components/PreferenceGrp.vue similarity index 100% rename from packages/artalk-sidebar/src/components/PreferenceGrp.vue rename to ui/packages/artalk-sidebar/src/components/PreferenceGrp.vue diff --git a/packages/artalk-sidebar/src/components/PreferenceItem.vue b/ui/packages/artalk-sidebar/src/components/PreferenceItem.vue similarity index 100% rename from packages/artalk-sidebar/src/components/PreferenceItem.vue rename to ui/packages/artalk-sidebar/src/components/PreferenceItem.vue diff --git a/packages/artalk-sidebar/src/components/SiteCreate.vue b/ui/packages/artalk-sidebar/src/components/SiteCreate.vue similarity index 100% rename from packages/artalk-sidebar/src/components/SiteCreate.vue rename to ui/packages/artalk-sidebar/src/components/SiteCreate.vue diff --git a/packages/artalk-sidebar/src/components/SiteEditor.vue b/ui/packages/artalk-sidebar/src/components/SiteEditor.vue similarity index 100% rename from packages/artalk-sidebar/src/components/SiteEditor.vue rename to ui/packages/artalk-sidebar/src/components/SiteEditor.vue diff --git a/packages/artalk-sidebar/src/components/SiteSwitcher.vue b/ui/packages/artalk-sidebar/src/components/SiteSwitcher.vue similarity index 100% rename from packages/artalk-sidebar/src/components/SiteSwitcher.vue rename to ui/packages/artalk-sidebar/src/components/SiteSwitcher.vue diff --git a/packages/artalk-sidebar/src/components/Tab.vue b/ui/packages/artalk-sidebar/src/components/Tab.vue similarity index 100% rename from packages/artalk-sidebar/src/components/Tab.vue rename to ui/packages/artalk-sidebar/src/components/Tab.vue diff --git a/packages/artalk-sidebar/src/components/UserEditor.vue b/ui/packages/artalk-sidebar/src/components/UserEditor.vue similarity index 100% rename from packages/artalk-sidebar/src/components/UserEditor.vue rename to ui/packages/artalk-sidebar/src/components/UserEditor.vue diff --git a/packages/artalk-sidebar/src/global.ts b/ui/packages/artalk-sidebar/src/global.ts similarity index 100% rename from packages/artalk-sidebar/src/global.ts rename to ui/packages/artalk-sidebar/src/global.ts diff --git a/packages/artalk-sidebar/src/lib/md5.js b/ui/packages/artalk-sidebar/src/lib/md5.js similarity index 100% rename from packages/artalk-sidebar/src/lib/md5.js rename to ui/packages/artalk-sidebar/src/lib/md5.js diff --git a/packages/artalk-sidebar/src/lib/settings.ts b/ui/packages/artalk-sidebar/src/lib/settings.ts similarity index 100% rename from packages/artalk-sidebar/src/lib/settings.ts rename to ui/packages/artalk-sidebar/src/lib/settings.ts diff --git a/packages/artalk-sidebar/src/main.ts b/ui/packages/artalk-sidebar/src/main.ts similarity index 100% rename from packages/artalk-sidebar/src/main.ts rename to ui/packages/artalk-sidebar/src/main.ts diff --git a/packages/artalk-sidebar/src/pages/comments.vue b/ui/packages/artalk-sidebar/src/pages/comments.vue similarity index 100% rename from packages/artalk-sidebar/src/pages/comments.vue rename to ui/packages/artalk-sidebar/src/pages/comments.vue diff --git a/packages/artalk-sidebar/src/pages/index.vue b/ui/packages/artalk-sidebar/src/pages/index.vue similarity index 100% rename from packages/artalk-sidebar/src/pages/index.vue rename to ui/packages/artalk-sidebar/src/pages/index.vue diff --git a/packages/artalk-sidebar/src/pages/login.vue b/ui/packages/artalk-sidebar/src/pages/login.vue similarity index 100% rename from packages/artalk-sidebar/src/pages/login.vue rename to ui/packages/artalk-sidebar/src/pages/login.vue diff --git a/packages/artalk-sidebar/src/pages/pages.vue b/ui/packages/artalk-sidebar/src/pages/pages.vue similarity index 100% rename from packages/artalk-sidebar/src/pages/pages.vue rename to ui/packages/artalk-sidebar/src/pages/pages.vue diff --git a/packages/artalk-sidebar/src/pages/settings.vue b/ui/packages/artalk-sidebar/src/pages/settings.vue similarity index 100% rename from packages/artalk-sidebar/src/pages/settings.vue rename to ui/packages/artalk-sidebar/src/pages/settings.vue diff --git a/packages/artalk-sidebar/src/pages/sites.vue b/ui/packages/artalk-sidebar/src/pages/sites.vue similarity index 100% rename from packages/artalk-sidebar/src/pages/sites.vue rename to ui/packages/artalk-sidebar/src/pages/sites.vue diff --git a/packages/artalk-sidebar/src/pages/transfer.vue b/ui/packages/artalk-sidebar/src/pages/transfer.vue similarity index 100% rename from packages/artalk-sidebar/src/pages/transfer.vue rename to ui/packages/artalk-sidebar/src/pages/transfer.vue diff --git a/packages/artalk-sidebar/src/pages/users.vue b/ui/packages/artalk-sidebar/src/pages/users.vue similarity index 100% rename from packages/artalk-sidebar/src/pages/users.vue rename to ui/packages/artalk-sidebar/src/pages/users.vue diff --git a/packages/artalk-sidebar/src/stores/nav.ts b/ui/packages/artalk-sidebar/src/stores/nav.ts similarity index 100% rename from packages/artalk-sidebar/src/stores/nav.ts rename to ui/packages/artalk-sidebar/src/stores/nav.ts diff --git a/packages/artalk-sidebar/src/stores/user.ts b/ui/packages/artalk-sidebar/src/stores/user.ts similarity index 100% rename from packages/artalk-sidebar/src/stores/user.ts rename to ui/packages/artalk-sidebar/src/stores/user.ts diff --git a/packages/artalk-sidebar/src/style.scss b/ui/packages/artalk-sidebar/src/style.scss similarity index 100% rename from packages/artalk-sidebar/src/style.scss rename to ui/packages/artalk-sidebar/src/style.scss diff --git a/packages/artalk-sidebar/src/style/_extends.scss b/ui/packages/artalk-sidebar/src/style/_extends.scss similarity index 100% rename from packages/artalk-sidebar/src/style/_extends.scss rename to ui/packages/artalk-sidebar/src/style/_extends.scss diff --git a/packages/artalk-sidebar/src/style/_variables.scss b/ui/packages/artalk-sidebar/src/style/_variables.scss similarity index 100% rename from packages/artalk-sidebar/src/style/_variables.scss rename to ui/packages/artalk-sidebar/src/style/_variables.scss diff --git a/packages/artalk-sidebar/src/vite-env.d.ts b/ui/packages/artalk-sidebar/src/vite-env.d.ts similarity index 100% rename from packages/artalk-sidebar/src/vite-env.d.ts rename to ui/packages/artalk-sidebar/src/vite-env.d.ts diff --git a/packages/artalk-sidebar/tsconfig.json b/ui/packages/artalk-sidebar/tsconfig.json similarity index 100% rename from packages/artalk-sidebar/tsconfig.json rename to ui/packages/artalk-sidebar/tsconfig.json diff --git a/packages/artalk-sidebar/typed-router.d.ts b/ui/packages/artalk-sidebar/typed-router.d.ts similarity index 100% rename from packages/artalk-sidebar/typed-router.d.ts rename to ui/packages/artalk-sidebar/typed-router.d.ts diff --git a/packages/artalk-sidebar/vite.config.ts b/ui/packages/artalk-sidebar/vite.config.ts similarity index 100% rename from packages/artalk-sidebar/vite.config.ts rename to ui/packages/artalk-sidebar/vite.config.ts diff --git a/packages/artalk/CNAME b/ui/packages/artalk/CNAME similarity index 100% rename from packages/artalk/CNAME rename to ui/packages/artalk/CNAME diff --git a/packages/artalk/index.html b/ui/packages/artalk/index.html similarity index 100% rename from packages/artalk/index.html rename to ui/packages/artalk/index.html diff --git a/packages/artalk/package.json b/ui/packages/artalk/package.json similarity index 100% rename from packages/artalk/package.json rename to ui/packages/artalk/package.json diff --git a/packages/artalk/postcss.config.js b/ui/packages/artalk/postcss.config.js similarity index 100% rename from packages/artalk/postcss.config.js rename to ui/packages/artalk/postcss.config.js diff --git a/packages/artalk/scripts/build-i18n.mjs b/ui/packages/artalk/scripts/build-i18n.mjs similarity index 100% rename from packages/artalk/scripts/build-i18n.mjs rename to ui/packages/artalk/scripts/build-i18n.mjs diff --git a/packages/artalk/src/api/admin.ts b/ui/packages/artalk/src/api/admin.ts similarity index 100% rename from packages/artalk/src/api/admin.ts rename to ui/packages/artalk/src/api/admin.ts diff --git a/packages/artalk/src/api/api-base.ts b/ui/packages/artalk/src/api/api-base.ts similarity index 100% rename from packages/artalk/src/api/api-base.ts rename to ui/packages/artalk/src/api/api-base.ts diff --git a/packages/artalk/src/api/captcha.ts b/ui/packages/artalk/src/api/captcha.ts similarity index 100% rename from packages/artalk/src/api/captcha.ts rename to ui/packages/artalk/src/api/captcha.ts diff --git a/packages/artalk/src/api/comment.ts b/ui/packages/artalk/src/api/comment.ts similarity index 100% rename from packages/artalk/src/api/comment.ts rename to ui/packages/artalk/src/api/comment.ts diff --git a/packages/artalk/src/api/index.ts b/ui/packages/artalk/src/api/index.ts similarity index 100% rename from packages/artalk/src/api/index.ts rename to ui/packages/artalk/src/api/index.ts diff --git a/packages/artalk/src/api/page.ts b/ui/packages/artalk/src/api/page.ts similarity index 100% rename from packages/artalk/src/api/page.ts rename to ui/packages/artalk/src/api/page.ts diff --git a/packages/artalk/src/api/request.ts b/ui/packages/artalk/src/api/request.ts similarity index 100% rename from packages/artalk/src/api/request.ts rename to ui/packages/artalk/src/api/request.ts diff --git a/packages/artalk/src/api/site.ts b/ui/packages/artalk/src/api/site.ts similarity index 100% rename from packages/artalk/src/api/site.ts rename to ui/packages/artalk/src/api/site.ts diff --git a/packages/artalk/src/api/system.ts b/ui/packages/artalk/src/api/system.ts similarity index 100% rename from packages/artalk/src/api/system.ts rename to ui/packages/artalk/src/api/system.ts diff --git a/packages/artalk/src/api/upload.ts b/ui/packages/artalk/src/api/upload.ts similarity index 100% rename from packages/artalk/src/api/upload.ts rename to ui/packages/artalk/src/api/upload.ts diff --git a/packages/artalk/src/api/user.ts b/ui/packages/artalk/src/api/user.ts similarity index 100% rename from packages/artalk/src/api/user.ts rename to ui/packages/artalk/src/api/user.ts diff --git a/packages/artalk/src/artalk.ts b/ui/packages/artalk/src/artalk.ts similarity index 100% rename from packages/artalk/src/artalk.ts rename to ui/packages/artalk/src/artalk.ts diff --git a/packages/artalk/src/comment/actions.ts b/ui/packages/artalk/src/comment/actions.ts similarity index 100% rename from packages/artalk/src/comment/actions.ts rename to ui/packages/artalk/src/comment/actions.ts diff --git a/packages/artalk/src/comment/comment.html b/ui/packages/artalk/src/comment/comment.html similarity index 100% rename from packages/artalk/src/comment/comment.html rename to ui/packages/artalk/src/comment/comment.html diff --git a/packages/artalk/src/comment/comment.ts b/ui/packages/artalk/src/comment/comment.ts similarity index 100% rename from packages/artalk/src/comment/comment.ts rename to ui/packages/artalk/src/comment/comment.ts diff --git a/packages/artalk/src/comment/index.ts b/ui/packages/artalk/src/comment/index.ts similarity index 100% rename from packages/artalk/src/comment/index.ts rename to ui/packages/artalk/src/comment/index.ts diff --git a/packages/artalk/src/comment/render.ts b/ui/packages/artalk/src/comment/render.ts similarity index 100% rename from packages/artalk/src/comment/render.ts rename to ui/packages/artalk/src/comment/render.ts diff --git a/packages/artalk/src/components/action-btn.ts b/ui/packages/artalk/src/components/action-btn.ts similarity index 100% rename from packages/artalk/src/components/action-btn.ts rename to ui/packages/artalk/src/components/action-btn.ts diff --git a/packages/artalk/src/components/dialog.ts b/ui/packages/artalk/src/components/dialog.ts similarity index 100% rename from packages/artalk/src/components/dialog.ts rename to ui/packages/artalk/src/components/dialog.ts diff --git a/packages/artalk/src/components/pagination.ts b/ui/packages/artalk/src/components/pagination.ts similarity index 100% rename from packages/artalk/src/components/pagination.ts rename to ui/packages/artalk/src/components/pagination.ts diff --git a/packages/artalk/src/components/read-more-btn.ts b/ui/packages/artalk/src/components/read-more-btn.ts similarity index 100% rename from packages/artalk/src/components/read-more-btn.ts rename to ui/packages/artalk/src/components/read-more-btn.ts diff --git a/packages/artalk/src/context.ts b/ui/packages/artalk/src/context.ts similarity index 100% rename from packages/artalk/src/context.ts rename to ui/packages/artalk/src/context.ts diff --git a/packages/artalk/src/defaults.ts b/ui/packages/artalk/src/defaults.ts similarity index 100% rename from packages/artalk/src/defaults.ts rename to ui/packages/artalk/src/defaults.ts diff --git a/packages/artalk/src/editor/editor.html b/ui/packages/artalk/src/editor/editor.html similarity index 100% rename from packages/artalk/src/editor/editor.html rename to ui/packages/artalk/src/editor/editor.html diff --git a/packages/artalk/src/editor/editor.ts b/ui/packages/artalk/src/editor/editor.ts similarity index 100% rename from packages/artalk/src/editor/editor.ts rename to ui/packages/artalk/src/editor/editor.ts diff --git a/packages/artalk/src/editor/index.ts b/ui/packages/artalk/src/editor/index.ts similarity index 100% rename from packages/artalk/src/editor/index.ts rename to ui/packages/artalk/src/editor/index.ts diff --git a/packages/artalk/src/editor/plugs/editor-plug.ts b/ui/packages/artalk/src/editor/plugs/editor-plug.ts similarity index 100% rename from packages/artalk/src/editor/plugs/editor-plug.ts rename to ui/packages/artalk/src/editor/plugs/editor-plug.ts diff --git a/packages/artalk/src/editor/plugs/emoticons-plug.less b/ui/packages/artalk/src/editor/plugs/emoticons-plug.less similarity index 100% rename from packages/artalk/src/editor/plugs/emoticons-plug.less rename to ui/packages/artalk/src/editor/plugs/emoticons-plug.less diff --git a/packages/artalk/src/editor/plugs/emoticons-plug.ts b/ui/packages/artalk/src/editor/plugs/emoticons-plug.ts similarity index 100% rename from packages/artalk/src/editor/plugs/emoticons-plug.ts rename to ui/packages/artalk/src/editor/plugs/emoticons-plug.ts diff --git a/packages/artalk/src/editor/plugs/header-input-plug.ts b/ui/packages/artalk/src/editor/plugs/header-input-plug.ts similarity index 100% rename from packages/artalk/src/editor/plugs/header-input-plug.ts rename to ui/packages/artalk/src/editor/plugs/header-input-plug.ts diff --git a/packages/artalk/src/editor/plugs/preview-plug.less b/ui/packages/artalk/src/editor/plugs/preview-plug.less similarity index 100% rename from packages/artalk/src/editor/plugs/preview-plug.less rename to ui/packages/artalk/src/editor/plugs/preview-plug.less diff --git a/packages/artalk/src/editor/plugs/preview-plug.ts b/ui/packages/artalk/src/editor/plugs/preview-plug.ts similarity index 100% rename from packages/artalk/src/editor/plugs/preview-plug.ts rename to ui/packages/artalk/src/editor/plugs/preview-plug.ts diff --git a/packages/artalk/src/editor/plugs/upload-plug.ts b/ui/packages/artalk/src/editor/plugs/upload-plug.ts similarity index 100% rename from packages/artalk/src/editor/plugs/upload-plug.ts rename to ui/packages/artalk/src/editor/plugs/upload-plug.ts diff --git a/packages/artalk/src/i18n/en.ts b/ui/packages/artalk/src/i18n/en.ts similarity index 100% rename from packages/artalk/src/i18n/en.ts rename to ui/packages/artalk/src/i18n/en.ts diff --git a/packages/artalk/src/i18n/index.ts b/ui/packages/artalk/src/i18n/index.ts similarity index 100% rename from packages/artalk/src/i18n/index.ts rename to ui/packages/artalk/src/i18n/index.ts diff --git a/packages/artalk/src/i18n/jp.ts b/ui/packages/artalk/src/i18n/jp.ts similarity index 100% rename from packages/artalk/src/i18n/jp.ts rename to ui/packages/artalk/src/i18n/jp.ts diff --git a/packages/artalk/src/i18n/zh-CN.ts b/ui/packages/artalk/src/i18n/zh-CN.ts similarity index 100% rename from packages/artalk/src/i18n/zh-CN.ts rename to ui/packages/artalk/src/i18n/zh-CN.ts diff --git a/packages/artalk/src/i18n/zh-TW.ts b/ui/packages/artalk/src/i18n/zh-TW.ts similarity index 100% rename from packages/artalk/src/i18n/zh-TW.ts rename to ui/packages/artalk/src/i18n/zh-TW.ts diff --git a/packages/artalk/src/layer/index.ts b/ui/packages/artalk/src/layer/index.ts similarity index 100% rename from packages/artalk/src/layer/index.ts rename to ui/packages/artalk/src/layer/index.ts diff --git a/packages/artalk/src/layer/layer.ts b/ui/packages/artalk/src/layer/layer.ts similarity index 100% rename from packages/artalk/src/layer/layer.ts rename to ui/packages/artalk/src/layer/layer.ts diff --git a/packages/artalk/src/layer/sidebar-layer.html b/ui/packages/artalk/src/layer/sidebar-layer.html similarity index 100% rename from packages/artalk/src/layer/sidebar-layer.html rename to ui/packages/artalk/src/layer/sidebar-layer.html diff --git a/packages/artalk/src/layer/sidebar-layer.ts b/ui/packages/artalk/src/layer/sidebar-layer.ts similarity index 100% rename from packages/artalk/src/layer/sidebar-layer.ts rename to ui/packages/artalk/src/layer/sidebar-layer.ts diff --git a/packages/artalk/src/lib/checker/admin-checker.ts b/ui/packages/artalk/src/lib/checker/admin-checker.ts similarity index 100% rename from packages/artalk/src/lib/checker/admin-checker.ts rename to ui/packages/artalk/src/lib/checker/admin-checker.ts diff --git a/packages/artalk/src/lib/checker/captcha-checker.ts b/ui/packages/artalk/src/lib/checker/captcha-checker.ts similarity index 100% rename from packages/artalk/src/lib/checker/captcha-checker.ts rename to ui/packages/artalk/src/lib/checker/captcha-checker.ts diff --git a/packages/artalk/src/lib/checker/index.ts b/ui/packages/artalk/src/lib/checker/index.ts similarity index 100% rename from packages/artalk/src/lib/checker/index.ts rename to ui/packages/artalk/src/lib/checker/index.ts diff --git a/packages/artalk/src/lib/component.ts b/ui/packages/artalk/src/lib/component.ts similarity index 100% rename from packages/artalk/src/lib/component.ts rename to ui/packages/artalk/src/lib/component.ts diff --git a/packages/artalk/src/lib/detect.ts b/ui/packages/artalk/src/lib/detect.ts similarity index 100% rename from packages/artalk/src/lib/detect.ts rename to ui/packages/artalk/src/lib/detect.ts diff --git a/packages/artalk/src/lib/stat.ts b/ui/packages/artalk/src/lib/stat.ts similarity index 100% rename from packages/artalk/src/lib/stat.ts rename to ui/packages/artalk/src/lib/stat.ts diff --git a/packages/artalk/src/lib/ui.ts b/ui/packages/artalk/src/lib/ui.ts similarity index 100% rename from packages/artalk/src/lib/ui.ts rename to ui/packages/artalk/src/lib/ui.ts diff --git a/packages/artalk/src/lib/user.ts b/ui/packages/artalk/src/lib/user.ts similarity index 100% rename from packages/artalk/src/lib/user.ts rename to ui/packages/artalk/src/lib/user.ts diff --git a/packages/artalk/src/lib/utils.ts b/ui/packages/artalk/src/lib/utils.ts similarity index 100% rename from packages/artalk/src/lib/utils.ts rename to ui/packages/artalk/src/lib/utils.ts diff --git a/packages/artalk/src/list/index.ts b/ui/packages/artalk/src/list/index.ts similarity index 100% rename from packages/artalk/src/list/index.ts rename to ui/packages/artalk/src/list/index.ts diff --git a/packages/artalk/src/list/list-lite.ts b/ui/packages/artalk/src/list/list-lite.ts similarity index 100% rename from packages/artalk/src/list/list-lite.ts rename to ui/packages/artalk/src/list/list-lite.ts diff --git a/packages/artalk/src/list/list-nest.ts b/ui/packages/artalk/src/list/list-nest.ts similarity index 100% rename from packages/artalk/src/list/list-nest.ts rename to ui/packages/artalk/src/list/list-nest.ts diff --git a/packages/artalk/src/list/list.html b/ui/packages/artalk/src/list/list.html similarity index 100% rename from packages/artalk/src/list/list.html rename to ui/packages/artalk/src/list/list.html diff --git a/packages/artalk/src/list/list.ts b/ui/packages/artalk/src/list/list.ts similarity index 100% rename from packages/artalk/src/list/list.ts rename to ui/packages/artalk/src/list/list.ts diff --git a/packages/artalk/src/main.ts b/ui/packages/artalk/src/main.ts similarity index 100% rename from packages/artalk/src/main.ts rename to ui/packages/artalk/src/main.ts diff --git a/packages/artalk/src/style/_color.less b/ui/packages/artalk/src/style/_color.less similarity index 100% rename from packages/artalk/src/style/_color.less rename to ui/packages/artalk/src/style/_color.less diff --git a/packages/artalk/src/style/_extend.less b/ui/packages/artalk/src/style/_extend.less similarity index 100% rename from packages/artalk/src/style/_extend.less rename to ui/packages/artalk/src/style/_extend.less diff --git a/packages/artalk/src/style/_variables.less b/ui/packages/artalk/src/style/_variables.less similarity index 100% rename from packages/artalk/src/style/_variables.less rename to ui/packages/artalk/src/style/_variables.less diff --git a/packages/artalk/src/style/comment.less b/ui/packages/artalk/src/style/comment.less similarity index 100% rename from packages/artalk/src/style/comment.less rename to ui/packages/artalk/src/style/comment.less diff --git a/packages/artalk/src/style/editor.less b/ui/packages/artalk/src/style/editor.less similarity index 100% rename from packages/artalk/src/style/editor.less rename to ui/packages/artalk/src/style/editor.less diff --git a/packages/artalk/src/style/list.less b/ui/packages/artalk/src/style/list.less similarity index 100% rename from packages/artalk/src/style/list.less rename to ui/packages/artalk/src/style/list.less diff --git a/packages/artalk/src/style/main.less b/ui/packages/artalk/src/style/main.less similarity index 100% rename from packages/artalk/src/style/main.less rename to ui/packages/artalk/src/style/main.less diff --git a/packages/artalk/src/style/pagination.less b/ui/packages/artalk/src/style/pagination.less similarity index 100% rename from packages/artalk/src/style/pagination.less rename to ui/packages/artalk/src/style/pagination.less diff --git a/packages/artalk/src/style/sidebar-layer.less b/ui/packages/artalk/src/style/sidebar-layer.less similarity index 100% rename from packages/artalk/src/style/sidebar-layer.less rename to ui/packages/artalk/src/style/sidebar-layer.less diff --git a/packages/artalk/test/ArtalkCount.html b/ui/packages/artalk/test/ArtalkCount.html similarity index 100% rename from packages/artalk/test/ArtalkCount.html rename to ui/packages/artalk/test/ArtalkCount.html diff --git a/packages/artalk/test/ArtalkI18n.html b/ui/packages/artalk/test/ArtalkI18n.html similarity index 100% rename from packages/artalk/test/ArtalkI18n.html rename to ui/packages/artalk/test/ArtalkI18n.html diff --git a/packages/artalk/test/ArtalkLite.html b/ui/packages/artalk/test/ArtalkLite.html similarity index 100% rename from packages/artalk/test/ArtalkLite.html rename to ui/packages/artalk/test/ArtalkLite.html diff --git a/packages/artalk/test/CSRF.html b/ui/packages/artalk/test/CSRF.html similarity index 100% rename from packages/artalk/test/CSRF.html rename to ui/packages/artalk/test/CSRF.html diff --git a/packages/artalk/tsconfig.json b/ui/packages/artalk/tsconfig.json similarity index 100% rename from packages/artalk/tsconfig.json rename to ui/packages/artalk/tsconfig.json diff --git a/packages/artalk/types/artalk-config.d.ts b/ui/packages/artalk/types/artalk-config.d.ts similarity index 100% rename from packages/artalk/types/artalk-config.d.ts rename to ui/packages/artalk/types/artalk-config.d.ts diff --git a/packages/artalk/types/artalk-data.d.ts b/ui/packages/artalk/types/artalk-data.d.ts similarity index 100% rename from packages/artalk/types/artalk-data.d.ts rename to ui/packages/artalk/types/artalk-data.d.ts diff --git a/packages/artalk/types/context.d.ts b/ui/packages/artalk/types/context.d.ts similarity index 100% rename from packages/artalk/types/context.d.ts rename to ui/packages/artalk/types/context.d.ts diff --git a/packages/artalk/types/event.d.ts b/ui/packages/artalk/types/event.d.ts similarity index 100% rename from packages/artalk/types/event.d.ts rename to ui/packages/artalk/types/event.d.ts diff --git a/packages/artalk/types/global.d.ts b/ui/packages/artalk/types/global.d.ts similarity index 100% rename from packages/artalk/types/global.d.ts rename to ui/packages/artalk/types/global.d.ts diff --git a/packages/artalk/types/plug.d.ts b/ui/packages/artalk/types/plug.d.ts similarity index 100% rename from packages/artalk/types/plug.d.ts rename to ui/packages/artalk/types/plug.d.ts diff --git a/packages/artalk/vite-base.config.ts b/ui/packages/artalk/vite-base.config.ts similarity index 100% rename from packages/artalk/vite-base.config.ts rename to ui/packages/artalk/vite-base.config.ts diff --git a/packages/artalk/vite-demo.config.ts b/ui/packages/artalk/vite-demo.config.ts similarity index 100% rename from packages/artalk/vite-demo.config.ts rename to ui/packages/artalk/vite-demo.config.ts diff --git a/packages/artalk/vite-lite.config.ts b/ui/packages/artalk/vite-lite.config.ts similarity index 100% rename from packages/artalk/vite-lite.config.ts rename to ui/packages/artalk/vite-lite.config.ts diff --git a/packages/artalk/vite.config.ts b/ui/packages/artalk/vite.config.ts similarity index 100% rename from packages/artalk/vite.config.ts rename to ui/packages/artalk/vite.config.ts diff --git a/packages/plugin-katex/README.md b/ui/packages/plugin-katex/README.md similarity index 100% rename from packages/plugin-katex/README.md rename to ui/packages/plugin-katex/README.md diff --git a/packages/plugin-katex/index.html b/ui/packages/plugin-katex/index.html similarity index 100% rename from packages/plugin-katex/index.html rename to ui/packages/plugin-katex/index.html diff --git a/packages/plugin-katex/main.ts b/ui/packages/plugin-katex/main.ts similarity index 100% rename from packages/plugin-katex/main.ts rename to ui/packages/plugin-katex/main.ts diff --git a/packages/plugin-katex/package.json b/ui/packages/plugin-katex/package.json similarity index 100% rename from packages/plugin-katex/package.json rename to ui/packages/plugin-katex/package.json diff --git a/packages/plugin-katex/tsconfig.json b/ui/packages/plugin-katex/tsconfig.json similarity index 100% rename from packages/plugin-katex/tsconfig.json rename to ui/packages/plugin-katex/tsconfig.json diff --git a/packages/plugin-katex/vite.config.ts b/ui/packages/plugin-katex/vite.config.ts similarity index 100% rename from packages/plugin-katex/vite.config.ts rename to ui/packages/plugin-katex/vite.config.ts diff --git a/packages/plugin-lightbox/README.md b/ui/packages/plugin-lightbox/README.md similarity index 100% rename from packages/plugin-lightbox/README.md rename to ui/packages/plugin-lightbox/README.md diff --git a/packages/plugin-lightbox/global.d.ts b/ui/packages/plugin-lightbox/global.d.ts similarity index 100% rename from packages/plugin-lightbox/global.d.ts rename to ui/packages/plugin-lightbox/global.d.ts diff --git a/packages/plugin-lightbox/index.html b/ui/packages/plugin-lightbox/index.html similarity index 100% rename from packages/plugin-lightbox/index.html rename to ui/packages/plugin-lightbox/index.html diff --git a/packages/plugin-lightbox/main.ts b/ui/packages/plugin-lightbox/main.ts similarity index 100% rename from packages/plugin-lightbox/main.ts rename to ui/packages/plugin-lightbox/main.ts diff --git a/packages/plugin-lightbox/package.json b/ui/packages/plugin-lightbox/package.json similarity index 100% rename from packages/plugin-lightbox/package.json rename to ui/packages/plugin-lightbox/package.json diff --git a/packages/plugin-lightbox/tsconfig.json b/ui/packages/plugin-lightbox/tsconfig.json similarity index 100% rename from packages/plugin-lightbox/tsconfig.json rename to ui/packages/plugin-lightbox/tsconfig.json diff --git a/packages/plugin-lightbox/vite.config.ts b/ui/packages/plugin-lightbox/vite.config.ts similarity index 100% rename from packages/plugin-lightbox/vite.config.ts rename to ui/packages/plugin-lightbox/vite.config.ts diff --git a/pnpm-lock.yaml b/ui/pnpm-lock.yaml similarity index 100% rename from pnpm-lock.yaml rename to ui/pnpm-lock.yaml diff --git a/pnpm-workspace.yaml b/ui/pnpm-workspace.yaml similarity index 100% rename from pnpm-workspace.yaml rename to ui/pnpm-workspace.yaml diff --git a/tsconfig.base.json b/ui/tsconfig.base.json similarity index 100% rename from tsconfig.base.json rename to ui/tsconfig.base.json From 802749fc940ed8a2ad1315814ad15f45f91dfc03 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Mon, 16 Jan 2023 21:55:13 +0800 Subject: [PATCH 323/349] chore: rename dir frontend to public Signed-off-by: qwqcode --- .gitignore | 4 ++-- main.go | 2 +- {frontend => public}/index.html | 0 {frontend => public}/robots.txt | 0 server/server.go | 4 ++-- 5 files changed, 5 insertions(+), 5 deletions(-) rename {frontend => public}/index.html (100%) rename {frontend => public}/robots.txt (100%) diff --git a/.gitignore b/.gitignore index 40ed9aaaa..7450c9749 100644 --- a/.gitignore +++ b/.gitignore @@ -48,5 +48,5 @@ node_modules /dist # always pull latest code and compile -/frontend/sidebar -/frontend/dist +/public/sidebar +/public/dist diff --git a/main.go b/main.go index 5e4a48854..f6b88eb8b 100644 --- a/main.go +++ b/main.go @@ -7,7 +7,7 @@ import ( "github.com/ArtalkJS/ArtalkGo/internal/pkged" ) -//go:embed frontend/* +//go:embed public/* //go:embed artalk-go.example.yml var embedFS embed.FS diff --git a/frontend/index.html b/public/index.html similarity index 100% rename from frontend/index.html rename to public/index.html diff --git a/frontend/robots.txt b/public/robots.txt similarity index 100% rename from frontend/robots.txt rename to public/robots.txt diff --git a/server/server.go b/server/server.go index 34a46b519..a5ddc4b3f 100644 --- a/server/server.go +++ b/server/server.go @@ -107,14 +107,14 @@ func actionLimit(f fiber.Router) { func static(f fiber.Router) { f.Use("/", filesystem.New(filesystem.Config{ Root: http.FS(pkged.FS()), - PathPrefix: "frontend", + PathPrefix: "public", Browse: false, })) } func index(f fiber.Router) { f.All("/", func(c *fiber.Ctx) error { - if _, err := pkged.FS().Open("frontend/sidebar/index.html"); err == nil { + if _, err := pkged.FS().Open("public/sidebar/index.html"); err == nil { return c.Redirect("./sidebar/", fiber.StatusFound) } From d229a628badb966f5c825983ea3329966ca5af14 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Mon, 16 Jan 2023 23:44:06 +0800 Subject: [PATCH 324/349] refactor: build scripts and CI tests Signed-off-by: qwqcode --- .circleci/conditional_config.yml | 105 ++++++++++++++++++ .circleci/config.yml | 54 ++++----- .circleci/config_ui.yml | 31 ------ .editorconfig | 11 ++ .github/workflows/codeql.yml | 8 +- .github/workflows/codeql_ui.yml | 74 ------------ .github/workflows/dockerhub.yml | 1 + .github/workflows/npm.yml | 8 +- .github/workflows/npm_ui.yml | 74 ------------ .github/workflows/pages.yml | 41 ------- .github/workflows/pages_ui.yml | 41 ------- .goreleaser.yml | 8 +- Dockerfile | 2 +- scripts/build-frontend.sh | 35 ++---- ui/.eslintrc.js | 2 + .../artalk-sidebar/scripts/fetch-conf-tpl.js | 31 +++--- .../src/assets/artalk-go.example.yml | 2 + .../artalk-sidebar/src/components/Header.vue | 1 + ui/packages/artalk-sidebar/tsconfig.json | 3 +- 19 files changed, 188 insertions(+), 344 deletions(-) create mode 100644 .circleci/conditional_config.yml delete mode 100644 .circleci/config_ui.yml delete mode 100644 .github/workflows/codeql_ui.yml delete mode 100644 .github/workflows/npm_ui.yml delete mode 100644 .github/workflows/pages.yml delete mode 100644 .github/workflows/pages_ui.yml diff --git a/.circleci/conditional_config.yml b/.circleci/conditional_config.yml new file mode 100644 index 000000000..79b4e49c4 --- /dev/null +++ b/.circleci/conditional_config.yml @@ -0,0 +1,105 @@ +version: 2.1 + +orbs: + node: circleci/node@5.0.3 + +executors: + base: + docker: + - image: cimg/base:stable + node: + docker: + - image: 'cimg/node:16.15.1' + go: + docker: + - image: cimg/go:1.19 + +parameters: + trigger-app: + type: boolean + default: false + trigger-ui: + type: boolean + default: false + run-them-all: + type: boolean + default: false + +jobs: + ## Backend + test_app: + executor: go + working_directory: ~/go/src/github.com/ArtalkJS/ArtalkGo + environment: + GO111MODULE: "on" + steps: + - checkout + - run: + name: "Print the Go version" + command: > + go version + - restore_cache: + keys: + - go-mod-1.19-{{ checksum "go.sum" }} + - run: + name: Install Dependencies + command: go mod download + - save_cache: + key: go-mod-1.19-{{ checksum "go.sum" }} + paths: + - "~/go/pkg/mod" + - run: + name: Run tests + command: | + mkdir -p /tmp/test-reports + gotestsum --junitfile /tmp/test-reports/unit-tests.xml + - store_test_results: + path: /tmp/test-reports + + ## Frontend + test_ui: + executor: node + steps: + - node/install + - checkout + - run: + name: Print the node version + command: node -v + - run: + name: Install pnpm + command: npm i -g pnpm@7.25.0 + - run: + name: Install Dependencies + command: pnpm --dir ./ui install --frozen-lockfile + - run: + name: Build Artalk + command: pnpm --dir ./ui build:all + + all_projects: + executor: base + steps: + - run: + command: | + echo "all" + +workflows: + build-app: + when: + or: + - << pipeline.parameters.trigger-app >> + - << pipeline.parameters.run-them-all >> + jobs: + - test_app + + build-ui: + when: + or: + - << pipeline.parameters.trigger-ui >> + - << pipeline.parameters.run-them-all >> + jobs: + - test_ui + + build-shared-other: + when: << pipeline.parameters.run-them-all >> + jobs: + - all_projects diff --git a/.circleci/config.yml b/.circleci/config.yml index cf931ce36..501953fa8 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,40 +1,26 @@ # https://circleci.com/docs/2.0/configuration-reference version: 2.1 -# Define a job to be invoked later in a workflow. -jobs: - test: - working_directory: ~/go/src/github.com/ArtalkJS/ArtalkGo - environment: - GO111MODULE: "on" - docker: - - image: cimg/go:1.19 - steps: - - checkout - - run: - name: "Print the Go version" - command: > - go version - - restore_cache: - keys: - - go-mod-1.19-{{ checksum "go.sum" }} - - run: - name: Install Dependencies - command: go mod download - - save_cache: - key: go-mod-1.19-{{ checksum "go.sum" }} - paths: - - "~/go/pkg/mod" - - run: - name: Run tests - command: | - mkdir -p /tmp/test-reports - gotestsum --junitfile /tmp/test-reports/unit-tests.xml - - store_test_results: - path: /tmp/test-reports +# this allows you to use CircleCI's dynamic configuration +# https://circleci.com/docs/2.0/dynamic-config/ +setup: true + +# the path-filtering orb is required to continue a pipeline based on +# https://circleci.com/developer/orbs/orb/circleci/path-filtering +orbs: + path-filtering: circleci/path-filtering@0.0.1 -# Invoke jobs via workflows workflows: - tests: + setup: jobs: - - test + - path-filtering/filter: + mapping: | + (cmd|internal|server|pkg|test)/.* trigger-app true + main.go|go.mod|go.sum|artalk-go.example.yml trigger-app true + (ui)/.* trigger-ui true + base-revision: master # git branch name + config-path: .circleci/conditional_config.yml + filters: + branches: + ignore: + - gh-pages diff --git a/.circleci/config_ui.yml b/.circleci/config_ui.yml deleted file mode 100644 index 826877099..000000000 --- a/.circleci/config_ui.yml +++ /dev/null @@ -1,31 +0,0 @@ -version: 2.1 -orbs: - node: circleci/node@5.0.3 -jobs: - build: - docker: - - image: 'cimg/node:16.15.1' - steps: - - node/install - - checkout - - run: - name: Print the node version - command: node -v - - run: - name: Install pnpm - command: npm i -g pnpm@7.11.0 - - run: - name: Install Dependencies - command: pnpm install --frozen-lockfile - - run: - name: Build Artalk - command: pnpm build:all - -workflows: - tests: - jobs: - - build: - filters: - branches: - ignore: - - gh-pages diff --git a/.editorconfig b/.editorconfig index 9ea64ee86..f268ed3b5 100644 --- a/.editorconfig +++ b/.editorconfig @@ -13,8 +13,19 @@ indent_style = space indent_size = 2 [*.md] +indent_size = 2 trim_trailing_whitespace = false [*.yml] indent_style = space indent_size = 2 + +[{Makefile,go.mod,go.sum,*.go,.gitmodules}] +indent_style = tab +indent_size = 4 + +[*.sh] +indent_size = 4 + +[Dockerfile] +indent_size = 4 diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 22ad8bc0a..6c65c1a95 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -32,7 +32,7 @@ jobs: strategy: fail-fast: false matrix: - language: [ 'javascript' ] + language: [ 'go', 'javascript' ] # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ] # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support @@ -48,11 +48,11 @@ jobs: # If you wish to specify custom queries, you can do so here or in a config file. # By default, queries listed here will override any specified in a config file. # Prefix the list here with "+" to use these queries and those in the config file. - + # Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs # queries: security-extended,security-and-quality - + # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild @@ -61,7 +61,7 @@ jobs: # ℹ️ Command-line programs to run using the OS shell. # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun - # If the Autobuild fails above, remove it and uncomment the following three lines. + # If the Autobuild fails above, remove it and uncomment the following three lines. # modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance. # - run: | diff --git a/.github/workflows/codeql_ui.yml b/.github/workflows/codeql_ui.yml deleted file mode 100644 index 22ad8bc0a..000000000 --- a/.github/workflows/codeql_ui.yml +++ /dev/null @@ -1,74 +0,0 @@ -# For most projects, this workflow file will not need changing; you simply need -# to commit it to your repository. -# -# You may wish to alter this file to override the set of languages analyzed, -# or to provide custom queries or build logic. -# -# ******** NOTE ******** -# We have attempted to detect the languages in your repository. Please check -# the `language` matrix defined below to confirm you have the correct set of -# supported CodeQL languages. -# -name: "CodeQL" - -on: - push: - branches: [ "master" ] - pull_request: - # The branches below must be a subset of the branches above - branches: [ "master" ] - schedule: - - cron: '40 17 * * 4' - -jobs: - analyze: - name: Analyze - runs-on: ubuntu-latest - permissions: - actions: read - contents: read - security-events: write - - strategy: - fail-fast: false - matrix: - language: [ 'javascript' ] - # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ] - # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support - - steps: - - name: Checkout repository - uses: actions/checkout@v3 - - # Initializes the CodeQL tools for scanning. - - name: Initialize CodeQL - uses: github/codeql-action/init@v2 - with: - languages: ${{ matrix.language }} - # If you wish to specify custom queries, you can do so here or in a config file. - # By default, queries listed here will override any specified in a config file. - # Prefix the list here with "+" to use these queries and those in the config file. - - # Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs - # queries: security-extended,security-and-quality - - - # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). - # If this step fails, then you should remove it and run the build manually (see below) - - name: Autobuild - uses: github/codeql-action/autobuild@v2 - - # ℹ️ Command-line programs to run using the OS shell. - # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun - - # If the Autobuild fails above, remove it and uncomment the following three lines. - # modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance. - - # - run: | - # echo "Run, Build Application using script" - # ./location_of_script_within_repo/buildscript.sh - - - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v2 - with: - category: "/language:${{matrix.language}}" diff --git a/.github/workflows/dockerhub.yml b/.github/workflows/dockerhub.yml index 3a9d6af3f..2a5bcf17e 100644 --- a/.github/workflows/dockerhub.yml +++ b/.github/workflows/dockerhub.yml @@ -12,6 +12,7 @@ on: jobs: docker: + if: github.repository == 'ArtalkJS/Artalk' runs-on: ubuntu-latest steps: diff --git a/.github/workflows/npm.yml b/.github/workflows/npm.yml index 89fa2ddc6..fb66015a4 100644 --- a/.github/workflows/npm.yml +++ b/.github/workflows/npm.yml @@ -10,7 +10,13 @@ jobs: publish: # prevents this action from running on forks if: github.repository == 'ArtalkJS/Artalk' + runs-on: ubuntu-latest + + defaults: + run: + working-directory: ./ui # set for building UI + steps: - name: Checkout uses: actions/checkout@v3 @@ -18,7 +24,7 @@ jobs: - name: Use pnpm uses: pnpm/action-setup@v2.2.4 with: - version: 7.11.0 + version: 7.25.0 - name: Set node version to 16.x uses: actions/setup-node@v3 diff --git a/.github/workflows/npm_ui.yml b/.github/workflows/npm_ui.yml deleted file mode 100644 index 89fa2ddc6..000000000 --- a/.github/workflows/npm_ui.yml +++ /dev/null @@ -1,74 +0,0 @@ -# https://docs.github.com/en/actions/publishing-packages/publishing-nodejs-packages -name: NPM Publish - -on: - push: - tags: - - v* - -jobs: - publish: - # prevents this action from running on forks - if: github.repository == 'ArtalkJS/Artalk' - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v3 - - - name: Use pnpm - uses: pnpm/action-setup@v2.2.4 - with: - version: 7.11.0 - - - name: Set node version to 16.x - uses: actions/setup-node@v3 - with: - node-version: 16.x - registry-url: https://registry.npmjs.org/ - cache: 'pnpm' - - - name: Install dependencies - run: pnpm install - - - name: Build - run: pnpm build - - - name: Publish - run: cd packages/artalk && pnpm publish --no-git-checks - env: - NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} - - # GitHub Packages - # - # Setup .npmrc file to publish to GitHub Packages - # - uses: actions/setup-node@v2 - # with: - # registry-url: 'https://npm.pkg.github.com' - # # Publish to GitHub Packages - # - run: npm publish - # env: - # NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - # Docs Update - docs-update: - runs-on: ubuntu-latest - steps: - - name: Get the version - id: get_version - run: echo ::set-output name=VERSION::${GITHUB_REF/refs\/tags\/v/} - - - name: Checkout ArtalkDocs - uses: actions/checkout@v3 - with: - repository: ArtalkJS/Docs - token: ${{ secrets.PAT }} - - - name: Update CDN links - run: | - sed -i 's#artalk@.[^/]*#artalk@${{ steps.get_version.outputs.VERSION }}#g' docs/code/ArtalkCDN.json - perl -pi -e 's#"Artalk"(\W+)?:(\W+)?".*?"#"Artalk": "${{ steps.get_version.outputs.VERSION }}"#g' docs/code/ArtalkVersion.json - sed -i 's#artalk@.[^/]*#artalk@${{ steps.get_version.outputs.VERSION }}#g' docs/code/quick-start/cdn.html - - - uses: stefanzweifel/git-auto-commit-action@v4 - with: - commit_message: Update Artalk CDN link to v${{ steps.get_version.outputs.VERSION }} diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml deleted file mode 100644 index 19cdf7e4f..000000000 --- a/.github/workflows/pages.yml +++ /dev/null @@ -1,41 +0,0 @@ -name: GitHub Pages - -on: - push: - branches: - - master - workflow_dispatch: - -jobs: - deploy: - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v3 - - - name: Use pnpm - uses: pnpm/action-setup@v2.2.4 - with: - version: 7.11.0 - - - name: Set node version to 16.x - uses: actions/setup-node@v3 - with: - node-version: 16.x - registry-url: https://registry.npmjs.org/ - cache: 'pnpm' - - - name: Install dependencies - run: pnpm install - - - name: Build - run: cd packages/artalk && pnpm predeploy - - - name: Deploy - uses: peaceiris/actions-gh-pages@v3 - with: - github_token: ${{ secrets.GITHUB_TOKEN }} - publish_branch: gh-pages - publish_dir: ./packages/artalk/deploy - user_name: 'github-actions[bot]' - user_email: 'github-actions[bot]@users.noreply.github.com' diff --git a/.github/workflows/pages_ui.yml b/.github/workflows/pages_ui.yml deleted file mode 100644 index 19cdf7e4f..000000000 --- a/.github/workflows/pages_ui.yml +++ /dev/null @@ -1,41 +0,0 @@ -name: GitHub Pages - -on: - push: - branches: - - master - workflow_dispatch: - -jobs: - deploy: - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v3 - - - name: Use pnpm - uses: pnpm/action-setup@v2.2.4 - with: - version: 7.11.0 - - - name: Set node version to 16.x - uses: actions/setup-node@v3 - with: - node-version: 16.x - registry-url: https://registry.npmjs.org/ - cache: 'pnpm' - - - name: Install dependencies - run: pnpm install - - - name: Build - run: cd packages/artalk && pnpm predeploy - - - name: Deploy - uses: peaceiris/actions-gh-pages@v3 - with: - github_token: ${{ secrets.GITHUB_TOKEN }} - publish_branch: gh-pages - publish_dir: ./packages/artalk/deploy - user_name: 'github-actions[bot]' - user_email: 'github-actions[bot]@users.noreply.github.com' diff --git a/.goreleaser.yml b/.goreleaser.yml index e4119b8a8..a0c29742b 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -68,9 +68,9 @@ builds: binary: "{{.ProjectName}}" main: ./main.go ldflags: *common_ldflags - + ## Arm - + # Linux (arm_v7) - id: linux-armhf goos: @@ -78,7 +78,7 @@ builds: goarch: - arm goarm: - - 7 + - '7' env: - CC=arm-linux-gnueabihf-gcc - CXX=arm-linux-gnueabihf-g++ @@ -150,6 +150,6 @@ changelog: release: github: owner: ArtalkJS - name: ArtalkGo + name: Artalk prerelease: auto draft: true diff --git a/Dockerfile b/Dockerfile index c2e6a063d..e182af0d6 100644 --- a/Dockerfile +++ b/Dockerfile @@ -7,7 +7,7 @@ WORKDIR /source RUN set -ex \ && apk upgrade \ && apk add make git gcc musl-dev nodejs bash npm\ - && npm install -g pnpm@7.21.0 + && npm install -g pnpm@7.25.0 COPY . ./ArtalkGo diff --git a/scripts/build-frontend.sh b/scripts/build-frontend.sh index c79ad6e1d..b4387e329 100755 --- a/scripts/build-frontend.sh +++ b/scripts/build-frontend.sh @@ -5,7 +5,7 @@ set -e if ! command -v pnpm &> /dev/null then apt-get update && apt-get install --no-install-recommends -y -q curl ca-certificates - + # Install volta bash -c "$(curl -fsSL https://get.volta.sh)" -- --skip-setup export VOLTA_HOME="${HOME}/.volta" @@ -15,28 +15,15 @@ then volta install pnpm fi -mkdir -p ./local/ - -cd ./local/ -rm -rf ./Artalk - -git clone https://github.com/ArtalkJS/Artalk.git Artalk -cd Artalk - -# # using latest tag soruce code -# git fetch --tags -# git checkout $(git describe --tags --abbrev=0) - -pnpm install -pnpm build:all - -cd ../../ - -rm -rf ./frontend/dist -rm -rf ./frontend/sidebar +pnpm --dir ./ui install --frozen-lockfile +pnpm --dir ./ui build:all -mkdir -p ./frontend/dist -cp -r ./local/Artalk/packages/artalk/dist/{Artalk.css,Artalk.js} ./frontend/dist +## dist +DIST_DIR="./public/dist" +rm -rf ${DIST_DIR} && mkdir -p ${DIST_DIR} +cp -r ./ui/packages/artalk/dist/{Artalk.css,Artalk.js} ${DIST_DIR} -mkdir -p ./frontend/sidebar -cp -r ./local/Artalk/packages/artalk-sidebar/dist/* ./frontend/sidebar +## sidebar +SIDEBAR_DIR="./public/sidebar" +rm -rf ${SIDEBAR_DIR} && mkdir -p ${SIDEBAR_DIR} +cp -r ./ui/packages/artalk-sidebar/dist/* ${SIDEBAR_DIR} diff --git a/ui/.eslintrc.js b/ui/.eslintrc.js index 66d5eac20..c3133b302 100644 --- a/ui/.eslintrc.js +++ b/ui/.eslintrc.js @@ -42,4 +42,6 @@ module.exports = { 'AbortController' ] }, + // @see https://stackoverflow.com/questions/63118405/how-to-fix-eslintrc-the-file-does-not-match-your-project-config + ignorePatterns: ['.eslintrc.js'], } diff --git a/ui/packages/artalk-sidebar/scripts/fetch-conf-tpl.js b/ui/packages/artalk-sidebar/scripts/fetch-conf-tpl.js index 783a06357..f76d3e1f3 100644 --- a/ui/packages/artalk-sidebar/scripts/fetch-conf-tpl.js +++ b/ui/packages/artalk-sidebar/scripts/fetch-conf-tpl.js @@ -6,18 +6,23 @@ import { fileURLToPath } from 'url' const __filename = fileURLToPath(import.meta.url) const __dirname = path.dirname(__filename) -const file = fs.createWriteStream(path.join(__dirname, '../src/assets/artalk-go.example.yml')) +fs.copyFile(path.join(__dirname, '../../../../artalk-go.example.yml'), path.join(__dirname, '../src/assets/artalk-go.example.yml'), (err) => { + if (!err) console.log("\nArtalkGo config file 'artalk-go.example.yml' loaded.\n") + else console.error("Failed to load config file 'artalk-go.example.yml':\n\n", err, "\n"); +}) -https.get( - 'https://raw.githubusercontent.com/ArtalkJS/ArtalkGo/master/artalk-go.example.yml', - (resp) => { - resp.pipe(file) +// const file = fs.createWriteStream() - file.on('finish', () => { - file.close() - console.log("\nArtalkGo 'artalk-go.example.yml' file download completed.\n") - }) - } -).on('error', (e) => { - console.error("Failed to download 'artalk-go.example.yml' file:\n\n", e, "\n"); -}) +// https.get( +// 'https://raw.githubusercontent.com/ArtalkJS/ArtalkGo/master/artalk-go.example.yml', +// (resp) => { +// resp.pipe(file) + +// file.on('finish', () => { +// file.close() +// console.log("\nArtalkGo 'artalk-go.example.yml' file download completed.\n") +// }) +// } +// ).on('error', (e) => { +// console.error("Failed to download 'artalk-go.example.yml' file:\n\n", e, "\n"); +// }) diff --git a/ui/packages/artalk-sidebar/src/assets/artalk-go.example.yml b/ui/packages/artalk-sidebar/src/assets/artalk-go.example.yml index 4486bcb1b..f476f6e61 100644 --- a/ui/packages/artalk-sidebar/src/assets/artalk-go.example.yml +++ b/ui/packages/artalk-sidebar/src/assets/artalk-go.example.yml @@ -283,6 +283,8 @@ frontend: default: "mp" # 评论分页 pagination: + # 每页评论数 + pageSize: 20 # 加载更多模式 (关闭则使用分页条) readMore: true # 滚动加载 diff --git a/ui/packages/artalk-sidebar/src/components/Header.vue b/ui/packages/artalk-sidebar/src/components/Header.vue index faffe9bb7..0d54692d9 100644 --- a/ui/packages/artalk-sidebar/src/components/Header.vue +++ b/ui/packages/artalk-sidebar/src/components/Header.vue @@ -1,4 +1,5 @@ + + diff --git a/docs/docs/.vitepress/theme/Artransfer.vue b/docs/docs/.vitepress/theme/Artransfer.vue new file mode 100644 index 000000000..613eca6b8 --- /dev/null +++ b/docs/docs/.vitepress/theme/Artransfer.vue @@ -0,0 +1,38 @@ + + + + + diff --git a/docs/docs/.vitepress/theme/Layout.vue b/docs/docs/.vitepress/theme/Layout.vue new file mode 100644 index 000000000..123450db4 --- /dev/null +++ b/docs/docs/.vitepress/theme/Layout.vue @@ -0,0 +1,15 @@ + + + diff --git a/docs/docs/.vitepress/theme/index.ts b/docs/docs/.vitepress/theme/index.ts new file mode 100644 index 000000000..e9b495ff5 --- /dev/null +++ b/docs/docs/.vitepress/theme/index.ts @@ -0,0 +1,20 @@ +import DefaultTheme from 'vitepress/theme' +import Layout from './Layout.vue' +import Artalk from './Artalk.vue' +import Artransfer from './Artransfer.vue' +import { Theme } from 'vitepress' + +export default { + ...DefaultTheme, + + Layout, + + enhanceApp({ app, router, siteData }) { + app.component('Artransfer', Artransfer) + app.component('Artalk', Artalk) + + // app is the Vue 3 app instance from `createApp()`. + // router is VitePress' custom router. `siteData` is + // a `ref` of current site-level metadata. + } +} as Theme diff --git a/docs/docs/.vitepress/theme/style.scss b/docs/docs/.vitepress/theme/style.scss new file mode 100644 index 000000000..b5c4e6ddc --- /dev/null +++ b/docs/docs/.vitepress/theme/style.scss @@ -0,0 +1,142 @@ +:root { + --vp-c-brand: #558fb5; + --vp-c-brand-light: #498cb8; + --vp-c-brand-lighter: #549ccc; + --vp-c-brand-dark: #366482; + --vp-c-brand-darker: #244f6b; + --vp-code-block-bg: #f6f8fa; + --vp-c-divider: #dfe2e5; + + --vp-home-hero-name-color: transparent; + --vp-home-hero-name-background: linear-gradient(90deg,#0083ff, #37dfd9); +} + +.dark { + --vp-c-bg: #22272e; + --vp-c-bg-alt: #22272e; + --vp-code-block-bg: #2b313a; + --vp-c-text-2: #8094a8; + --vp-button-alt-bg: #1e2224; + --vp-button-alt-border: #2d3235; + --vp-c-bg-soft: #1e2224; + --vp-c-divider-light: #2d3235; + --vp-c-divider: #34404c; + --vp-c-black: #22272e; + --vp-c-bg-soft: #2b313a; +} + +.VPHome .clip { + font-weight: 500; + font-size: 1.5em; + margin-bottom: 0.5em; + display: inline-block; +} + +.VPHome .VPButton.brand { + border-color: #0083ff; + color: #fff; + background-color: #0083ff; + + &:hover { + border-color: #007CF0; + color: #fff; + background-color: #007CF0; + } +} + +/** 一起摇摆 **/ +.wave { + display: inline-block; + transform-origin: center bottom; + animation:upAnimation 2.33s ease .8s 3 both; +} +@keyframes upAnimation { + 0% { + transform: rotate(0deg); + transition-timing-function:cubic-bezier(0.215, .61, .355, 1); + } + 10% { + transform: rotate(-12deg); + transition-timing-function:cubic-bezier(0.215, .61, .355, 1); + } + 20% { + transform: rotate(12deg); + transition-timing-function:cubic-bezier(0.215, .61, .355, 1); + } + 28% { + transform: rotate(-10deg); + transition-timing-function:cubic-bezier(0.215, .61, .355, 1); + } + 36% { + transform: rotate(10deg); + transition-timing-function:cubic-bezier(0.755, .5, .855, .06); + } + 42% { + transform: rotate(-8deg); + transition-timing-function:cubic-bezier(0.755, .5, .855, .06); + } + 48% { + transform: rotate(8deg); + transition-timing-function:cubic-bezier(0.755, .5, .855, .06); + } + 52% { + transform: rotate(-4deg); + transition-timing-function:cubic-bezier(0.755, .5, .855, .06); + } + 56% { + transform: rotate(4deg); + transition-timing-function:cubic-bezier(0.755, .5, .855, .06); + } + 60% { + transform: rotate(0deg); + transition-timing-function:cubic-bezier(0.755, .5, .855, .06); + } + 100% { + transform: rotate(0deg); + transition-timing-function:cubic-bezier(0.215, .61, .355, 1); + } +} + +.vp-doc > div > img { + max-width: 100%; + margin: 1.5em auto; +} + +img[atk-emoticon] { + display: initial; +} + +/* 由于 body 未添加一致的 transition,导致其他地方暗黑模式切换加 transition 比较怪 */ +.vp-doc div[class*='language-'] { transition: none; } +.vp-doc :not(pre) > code { transition: none; } + +.vp-doc { + table { + border-collapse: collapse; + margin: 1rem 0; + display: block; + overflow-x: auto + } + + td,th { + padding: .6em 1em; + } +} + +/* 侧边栏 */ +.VPSidebar::-webkit-scrollbar { + width: 7px +} + +.VPSidebar::-webkit-scrollbar-track { + background-color: transparent +} + +.VPSidebar::-webkit-scrollbar-thumb { + background-color: var(--vp-c-divider) +} + +// details block patch +.custom-block.details > summary { + cursor: pointer; +} diff --git a/docs/docs/.vitepress/types/shims-vue.d.ts b/docs/docs/.vitepress/types/shims-vue.d.ts new file mode 100644 index 000000000..798e8fcfa --- /dev/null +++ b/docs/docs/.vitepress/types/shims-vue.d.ts @@ -0,0 +1,5 @@ +declare module '*.vue' { + import { defineComponent } from 'vue'; + const component: ReturnType; + export default component; +} diff --git a/docs/docs/code/ArtalkCDN.json b/docs/docs/code/ArtalkCDN.json new file mode 100644 index 000000000..9a85b73ea --- /dev/null +++ b/docs/docs/code/ArtalkCDN.json @@ -0,0 +1,4 @@ +{ + "JS": "https://npm.elemecdn.com/artalk@2.4.4/dist/Artalk.js", + "CSS": "https://npm.elemecdn.com/artalk@2.4.4/dist/Artalk.css" +} diff --git a/docs/docs/code/ArtalkVersion.json b/docs/docs/code/ArtalkVersion.json new file mode 100644 index 000000000..bcf536697 --- /dev/null +++ b/docs/docs/code/ArtalkVersion.json @@ -0,0 +1,3 @@ +{ + "Artalk": "2.4.4" +} diff --git a/docs/docs/code/quick-start/cdn.html b/docs/docs/code/quick-start/cdn.html new file mode 100644 index 000000000..f6618a0f4 --- /dev/null +++ b/docs/docs/code/quick-start/cdn.html @@ -0,0 +1,17 @@ + + + + + + + +
+ diff --git a/docs/docs/code/quick-start/normal-install.sh b/docs/docs/code/quick-start/normal-install.sh new file mode 100644 index 000000000..4684316f5 --- /dev/null +++ b/docs/docs/code/quick-start/normal-install.sh @@ -0,0 +1,4 @@ +$ tar xvzf artalk-go.tar.gz +$ cd artalk-go +$ vim artalk-go.yml +$ ./artalk-go server diff --git a/docs/docs/develop/api.md b/docs/docs/develop/api.md new file mode 100644 index 000000000..ee719c3f6 --- /dev/null +++ b/docs/docs/develop/api.md @@ -0,0 +1,588 @@ +# HTTP API + +::: tip 无特殊说明时 API 调用响应格式 + +| 字段名 | 类型 | 说明 | +| ----- | ------- | --- | +| `success` | Boolean | 接口调用结果 | +| `msg` | String | 返回消息,出错时此字段包含错误消息 | +| `data` | Any | 返回数据,可能为 Object / String / Array 类型 | + +::: + +## Normal API + +### 评论新增 + +**POST** `/api/add` + +**参数** + +| 字段名 | 数据类型 | 必需 | 说明 | +| ----- | ------- | :---: | --- | +| `name` | String | 是 | 待新增评论者昵称 | +| `email` | String | 是 | 待新增评论者邮箱 | +| `link` | String | 否 | 待新增评论者链接 | +| `content` | String | 是 | 待新增评论内容 | +| `rid` | Number | 否 | 待新增评论为回复评论时传入父评论 `ID`,否则为 `0` | +| `page_key` | String | 是 | 待新增评论目标页面唯一标识符 | +| `page_title` | String | 否 | 待新增评论目标页面标题 | +| `token` | String | 否 | 评论请求 Token | +| `site_name` | String | 否 | 待新增评论目标站点名称 | + +**响应** + +| 字段名 | 数据类型 | 默认 | 说明 | +| ----- | ------- | :-: | --- | +| `success` | Boolean | `true` | 评论新增成功 | +| `data.comment` | Object | - | 评论数据 | +| `data.comment.id` | Number | - | 评论 ID | +| `data.comment.content` | String | - | 评论正文 | +| `data.comment.nick` | String | - | 评论者昵称 | +| `data.comment.email_encrypted` | String | - | 评论者邮箱 MD5 加密值 | +| `data.comment.link` | String | - | 评论者链接 | +| `data.comment.ua` | String | - | 评论者 User-Agent | +| `data.comment.date` | String | - | 评论时间,格式为 `1970-01-01 00:00:00` | +| `data.comment.is_collapsed` | Boolean | - | 评论是否折叠 | +| `data.comment.is_pending` | Boolean | - | 评论是否待审 | +| `data.comment.is_allow_reply` | Boolean | - | 评论是否允许回复 | +| `data.comment.rid` | Number | `0` | 待新增评论为回复评论时返回父评论 `ID` | +| `data.comment.badge_name` | String | - | 评论者徽章文字 | +| `data.comment.badge_color` | String | - | 评论者徽章颜色 | +| `data.comment.visible` | Boolean | `true` | 评论是否可见 | +| `data.comment.vote_up` | Number | `0` | 评论赞同数 | +| `data.comment.vote_down` | Number | `0` | 评论反对数 | +| `data.comment.page_key` | String | - | 评论所在页面唯一标识符 | +| `data.comment.site_name` | String | - | 评论所在站点名称 | + +### 评论获取 + +**POST** `/api/get` + +**参数** + +| 字段名 | 数据类型 | 必需 | 说明 | +| ----- | ------- | :---: | --- | +| `page_key` | String | 是 | 待获取评论页面的唯一标识符 | +| `limit` | Number | 否 | 待获取评论的数量限制 | +| `offset` | Number | 否 | 待获取评论的起始位置偏移 | +| `type` | String | 否 | 获取指定类型的评论 | +| `name` | String | 否 | 获取指定昵称的评论 | +| `email` | String | 否 | 获取指定邮箱的评论 | +| `site_name` | String | 否 | 获取指定站点名称的评论 | +| `flat_mode` | Boolean | 否 | 待获取评论是否平铺模式 | + +**响应** + +| 字段名 | 数据类型 | 默认 | 说明 | +| ----- | ------- | :-: | --- | +| `success` | Boolean | `true` | 评论获取成功 | +| `data.comments` | Array | - | 页面评论数据 | +| `data.total` | Number | - | 页面评论总数(包括所有子评论) | +| `data.total_parents` | Number | - | 页面评论中父级评论总数 | +| `data.page` | Object | - | 页面数据 | +| `data.page.id` | Number | - | 页面 ID | +| `data.page.admin_only` | Boolean | - | 页面是否仅管理员可评论 | +| `data.page.key` | String | - | 页面唯一标识符 | +| `data.page.url` | String | - | 页面链接 | +| `data.page.title` | String | - | 页面标题 | +| `data.page.site_name` | String | - | 页面所在站点名称 | +| `data.page.vote_up` | Number | - | 页面赞同数 | +| `data.page.vote_down` | Number | - | 页面反对数 | +| `data.unread` | Array | - | 未读的评论提醒数据 | +| `data.unread_count` | Number | - | 未读的评论提醒数据总数 | +| `data.api_version` | Object | - | 目标 Artalk 后端版本数据 | + +::: tip + + - `data.comments` 数组中元素结构参考 [评论新增接口](#评论新增) `/api/add` 响应的 `data.comment` + - `data.unread` 数组中元素结构如下 + | 字段名 | 数据类型 | 默认 | 说明 | + | ----- | ------- | :-: | --- | + | `id` | Number | - | 评论提醒 ID | + | `user_id` | Number | - | 评论提醒目标用户 ID | + | `comment_id` | Number | - | 评论提醒来源评论 ID | + | `is_read` | Boolean | - | 评论提醒是否已读 | + | `is_emailed` | Boolean | - | 评论提醒是否已发送邮件 | + | `read_link` | String | - | 评论提醒已读地址 | + - `data.api_version` 对象结构参考 [Artalk 版本接口](#artalk-版本) `/api/version` 响应 + +::: + +### 用户获取 + +**POST** `/api/user-get` + +**参数** + +| 字段名 | 数据类型 | 必需 | 说明 | +| ----- | ------- | :---: | --- | +| `name` | String | 否 | 待获取用户的昵称 | +| `email` | String | 否 | 待获取用户的邮箱 | + +**响应** + +| 字段名 | 数据类型 | 默认 | 说明 | +| ----- | ------- | :-: | --- | +| `success` | Boolean | `true` | 用户获取成功 | +| `data.user` | Object | `null` | 获取的用户数据,若用户不存在返回空 | +| `data.user.id` | Number | - | 用户 ID | +| `data.user.name` | String | - | 用户昵称 | +| `data.user.email` | String | - | 用户邮箱 | +| `data.user.link` | String | - | 用户链接 | +| `data.user.badge_name` | String | - | 用户徽章文字 | +| `data.user.badge_color` | String | - | 用户徽章颜色 | +| `data.user.is_admin` | Boolean | - | 用户是否管理员 | +| `data.is_login` | Boolean | - | 用户是否登录 | +| `data.unread` | Array | `[]` | 用户未读的评论提醒数据 | +| `data.unread_count` | Number | `0` | 用户未读的评论提醒数据总数 | + +::: tip + + - `data.unread` 数组中元素结构参考 [评论获取接口](#评论获取) `/api/get` **TIP** + +::: + +### 用户登录 + +**GET/POST** `/api/login` + +**参数** + +| 字段名 | 数据类型 | 必需 | 说明 | +| ----- | ------- | :---: | --- | +| `name` | String | 是 | 待登录用户的昵称 | +| `email` | String | 是 | 待登录用户的邮箱 | +| `password` | String | 是 | 待登录用户的密码(管理员身份验证) | + +**响应** + +| 字段名 | 数据类型 | 默认 | 说明 | +| ----- | ------- | :-: | --- | +| `success` | Boolean | `true` | 用户登录成功 | +| `data.token` | String | - | 登录的用户 Token | + +### 提醒已读 + +**POST** `/api/mark-read` + +**参数** + +| 字段名 | 数据类型 | 必需 | 说明 | +| ----- | ------- | :---: | --- | +| `notify_key` | String | 否 | 评论提醒唯一标识符 | +| `name` | String | 否 | 评论提醒用户的昵称 | +| `email` | String | 否 | 评论提醒用户的邮箱 | +| `all_read` | Boolean | 否 | 评论提醒是否已读 | +| `site_name` | String | 否 | 评论提醒所在站点名称 | + +**响应** + +| 字段名 | 数据类型 | 默认 | 说明 | +| ----- | ------- | :-: | --- | +| `success` | Boolean | `true` | 提醒已读成功 | + +### 评论投票 + +**POST** `/api/vote` + +**参数** + +| 字段名 | 数据类型 | 必需 | 说明 | +| ----- | ------- | :---: | --- | +| `target_id` | Number | 是 | 待投票评论 ID | +| `type` | String | 否 | 待投票类型,前缀 `comment_`、`page_` 依次代表对评论投票、对页面投票,后缀 `_up`、`_down` 依次代表赞同、反对 | +| `name` | String | 否 | 投票用户昵称 | +| `email` | String | 否 | 投票用户邮箱 | +| `site_name` | String | 否 | 投票目标评论或页面所在站点名称 | + +**响应** + +| 字段名 | 数据类型 | 默认 | 说明 | +| ----- | ------- | :-: | --- | +| `success` | Boolean | `true` | 评论投票成功 | +| `data.vote_num` | Number | - | 目标评论或页面指定类型投票数据 | + +### Artalk 版本 + +::: warning + +此接口较特殊,返回结果不包含 `success`、`msg`、`data` 字段,直接返回包含指定字段的 JSON。 + +::: + +**GET/POST** `/api/version` + +**参数** 无 + +**响应** + +| 字段名 | 数据类型 | 默认 | 说明 | +| ----- | ------- | :-: | --- | +| `app` | String | `artalk-go` | Artalk 后端程序名 | +| `version` | String | - | Artalk 后端程序版本号 | +| `commit_hash` | String | - | Artalk 后端程序 Git 提交哈希值 | +| `fe_min_version` | String | - | Artalk 后端程序所需前端最低版本 | + +## Captcha API + +### 验证码刷新 + +**GET** `/api/captcha/refresh` + +**参数** 无 + +**响应** + +| 字段名 | 数据类型 | 默认 | 说明 | +| ----- | ------- | :-: | --- | +| `success` | Boolean | `true` | 验证码刷新成功 | +| `data.img_data` | String | - | 根据 IP 获取的验证码图片 Base64 编码 | + +### 验证码检验 + +**GET** `/api/captcha/check` + +**参数** + +| 字段名 | 数据类型 | 必需 | 说明 | +| ----- | ------- | :---: | --- | +| `value` | String | 是 | 验证码 | + +**响应** + +| 字段名 | 数据类型 | 默认 | 说明 | +| ----- | ------- | :-: | --- | +| `success` | Boolean | `true` | 验证码检验成功 | +| `data.img_data` | String | - | 新的验证码图片 Base64 编码,仅验证码检验出错时存在此字段 | + +## Admin API + +### 评论编辑 + +**POST** `/api/admin/comment-edit` + +**参数** + +| 字段名 | 数据类型 | 必需 | 说明 | +| ----- | ------- | :---: | --- | +| `id` | Number | 是 | 待编辑评论 ID,**不可修改** | +| `site_name` | String | 否 | 待编辑评论所在站点名称,**不可修改** | +| `content` | String | 否 | 待编辑评论正文 | +| `page_key` | String | 否 | 待编辑评论所在页面唯一标识符 | +| `nick` | String | 否 | 待编辑评论所属用户昵称 | +| `email` | String | 否 | 待编辑评论所属用户邮箱 | +| `link` | String | 否 | 待编辑评论所属用户链接 | +| `rid` | String | 否 | 待编辑评论为回复评论时传入父评论 `ID`,否则为 `0` | +| `ua` | String | 否 | 待编辑评论所属用户 User-Agent | +| `ip` | String | 否 | 待编辑评论所属用户 IP | +| `is_collapsed` | Boolean | 否 | 待编辑评论是否折叠 | +| `is_pending` | Boolean | 否 | 待编辑评论是否待审 | + +**响应** + +| 字段名 | 数据类型 | 默认 | 说明 | +| ----- | ------- | :-: | --- | +| `success` | Boolean | `true` | 评论编辑成功 | +| `data.comment` | Object | - | 编辑评论的新数据 | + +::: tip + + - `data.comment` 对象结构参考 [评论新增接口](#评论新增) `/api/add` 响应的 `data.comment` + +::: + +### 评论删除 + +::: danger + +此接口不推荐外部调用。 + +调用此接口前请务必核实评论 ID,一旦调用成功将删除该评论下所有相关数据。 + +::: + +**POST** `/api/admin/comment-del` + +**参数** + +| 字段名 | 数据类型 | 必需 | 说明 | +| ----- | ------- | :---: | --- | +| `id` | Number | 是 | 待删除评论 ID | +| `site_name` | String | 是 | 待删除评论所在站点名称 | + +**响应** + +| 字段名 | 数据类型 | 默认 | 说明 | +| ----- | ------- | :-: | --- | +| `success` | Boolean | `true` | 评论删除成功 | + +### 页面获取 + +**POST** `/api/admin/page-get` + +**参数** + +| 字段名 | 数据类型 | 必需 | 说明 | +| ----- | ------- | :---: | --- | +| `site_name` | String | 是 | 待获取页面目标站点名称 | + +**响应** + +| 字段名 | 数据类型 | 默认 | 说明 | +| ----- | ------- | :-: | --- | +| `success` | Boolean | `true` | 页面获取成功 | +| `data.pages` | Array | - | 目标站点的页面数据 | +| `data.sites` | Array | - | 所有站点数据 | + +::: tip + + - `data.pages` 数组中元素结构参考 [评论获取接口](#评论获取) `/api/get` 响应的 `data.page` + - `data.sites` 数组中元素结构参考 [站点编辑接口](#站点编辑) `/api/admin/site-edit` 响应的 `data.site` + +::: + +### 页面编辑 + +**POST** `/api/admin/page-edit` + +**参数** + +| 字段名 | 数据类型 | 必需 | 说明 | +| ----- | ------- | :---: | --- | +| `id` | Number | 是 | 待编辑页面 ID,**不可修改** | +| `site_name` | String | 否 | 待编辑页面所在站点名称,**不可修改** | +| `key` | String | 否 | 待编辑页面唯一标识符 | +| `title` | String | 否 | 待编辑页面标题 | +| `admin_only` | Boolean | 否 | 待编辑页面是否仅管理员可评论 | + +**响应** + +| 字段名 | 数据类型 | 默认 | 说明 | +| ----- | ------- | :-: | --- | +| `success` | Boolean | `true` | 页面编辑成功 | +| `data.page` | Object | - | 编辑页面的新数据 | + +::: tip + + - `data.page` 对象结构参考 [评论获取接口](#评论获取) `/api/get` 响应的 `data.page` + +::: + +### 页面删除 + +::: danger + +此接口不推荐外部调用。 + +调用此接口前请务必核实页面 ID,一旦调用成功将删除该页面下所有相关数据。 + +::: + +**POST** `/api/admin/page-del` + +**参数** + +| 字段名 | 数据类型 | 必需 | 说明 | +| ----- | ------- | :---: | --- | +| `key` | String | 是 | 待删除页面唯一标识符 | +| `site_name` | String | 是 | 待删除页面所在站点名称 | + +**响应** + +| 字段名 | 数据类型 | 默认 | 说明 | +| ----- | ------- | :-: | --- | +| `success` | Boolean | `true` | 页面删除成功 | + +### 页面更新 + +**POST** `/api/admin/page-fetch` + +**参数** + +| 字段名 | 数据类型 | 必需 | 说明 | +| ----- | ------- | :---: | --- | +| `id` | Number | 是 | 待更新页面 ID | + +**响应** + +| 字段名 | 数据类型 | 默认 | 说明 | +| ----- | ------- | :-: | --- | +| `success` | Boolean | `true` | 页面更新成功 | +| `data.page` | Object | - | 更新页面的新数据 | + +::: tip + + - `data.page` 对象结构参考 [评论获取接口](#评论获取) `/api/get` 响应的 `data.page` + +::: + +### 站点获取 + +**POST** `/api/admin/site-get` + +**参数** 无 + +**响应** + +| 字段名 | 数据类型 | 默认 | 说明 | +| ----- | ------- | :-: | --- | +| `success` | Boolean | `true` | 站点获取成功 | +| `data.sites` | Array | - | 所有站点数据 | + +::: tip + + - `data.sites` 数组中元素结构参考 [站点编辑接口](#站点编辑) `/api/admin/site-edit` 响应的 `data.site` + +::: + +### 站点新增 + +**POST** `/api/admin/site-add` + +**参数** + +| 字段名 | 数据类型 | 必需 | 说明 | +| ----- | ------- | :---: | --- | +| `name` | String | 是 | 待新增站点名称 | +| `urls` | String | 是 | 待新增站点链接,如有多个需以英文半角符号 `,` 分割 | + +**响应** + +| 字段名 | 数据类型 | 默认 | 说明 | +| ----- | ------- | :-: | --- | +| `success` | Boolean | `true` | 站点新增成功 | +| `data.site` | Object | - | 新增站点的数据 | +| `data.site.id` | Number | - | 站点 ID | +| `data.site.name` | String | - | 站点名称 | +| `data.site.urls` | Array | - | 站点链接数组,元素为单个站点链接字符串 | +| `data.site.urls_raw` | String | - | 站点链接数组合并字符串,以英文半角符号 `,` 分割 | +| `data.site.first_url` | String | - | 站点第一链接 | + +### 站点编辑 + +**POST** `/api/admin/site-edit` + +**参数** + +| 字段名 | 数据类型 | 必需 | 说明 | +| ----- | ------- | :---: | --- | +| `id` | Number | 是 | 待编辑站点 ID | +| `name` | String | 是 | 待编辑站点新名称 | +| `urls` | String | 是 | 待编辑站点新链接 | + +**响应** + +| 字段名 | 数据类型 | 默认 | 说明 | +| ----- | ------- | :-: | --- | +| `success` | Boolean | `true` | 站点编辑成功 | +| `data.site` | Object | - | 编辑站点的新数据 | +| `data.site.id` | Number | - | 站点 ID | +| `data.site.name` | String | - | 站点名称 | +| `data.site.urls` | Array | - | 站点链接数组,元素为单个站点链接字符串 | +| `data.site.urls_raw` | String | - | 站点链接数组合并字符串,以英文半角符号 `,` 分割 | +| `data.site.first_url` | String | - | 站点第一链接 | + +### 站点删除 + +::: danger + +此接口不推荐外部调用。 + +调用此接口前请务必核实站点 ID,一旦调用成功将删除该站点下所有相关数据。 + +::: + +**POST** `/api/admin/site-del` + +**参数** + +| 字段名 | 数据类型 | 必需 | 说明 | +| ----- | ------- | :---: | --- | +| `id` | Number | 是 | 待删除站点 ID | +| `del_content` | Boolean | 否 | 是否删除站点所有数据,为 `false` 时仅删除站点配置而保留站点评论数据 | + +**响应** + +| 字段名 | 数据类型 | 默认 | 说明 | +| ----- | ------- | :-: | --- | +| `success` | Boolean | `true` | 站点删除成功 | + +### 设置获取 + +**POST** `/api/admin/setting-get` + +**参数** + +| 字段名 | 数据类型 | 必需 | 说明 | +| ----- | ------- | :---: | --- | +| `id` | Number | 是 | 管理员用户 ID | +| `name` | String | 否 | 管理员用户昵称 | +| `url` | String | 否 | 管理员用户链接 | + +**响应** + +| 字段名 | 数据类型 | 默认 | 说明 | +| ----- | ------- | :-: | --- | +| `success` | Boolean | `true` | 设置获取成功 | + +### 设置保存 + +**POST** `/api/admin/setting-save` + +**参数** + +| 字段名 | 数据类型 | 必需 | 说明 | +| ----- | ------- | :---: | --- | +| `id` | Number | 是 | 管理员用户 ID | +| `name` | String | 否 | 管理员用户昵称 | +| `url` | String | 否 | 管理员用户链接 | + +**响应** + +| 字段名 | 数据类型 | 默认 | 说明 | +| ----- | ------- | :-: | --- | +| `success` | Boolean | `true` | 设置保存成功 | + +### 邮件发送 + +::: warning + +页面收到评论、评论收到回复等满足需要发送邮件提醒条件时,后端将自动向目标地址发送邮件提醒,不需手动处理邮件发送。请勿滥用此接口。 + +::: + +**POST** `/api/admin/send-mail` + +**参数** + +| 字段名 | 数据类型 | 必需 | 说明 | +| ----- | ------- | :---: | --- | +| `subject` | String | 是 | 邮件主题 | +| `body` | String | 是 | 邮件正文 | +| `to_addr` | String | 是 | 邮件收件人 | + +**响应** + +| 字段名 | 数据类型 | 默认 | 说明 | +| ----- | ------- | :-: | --- | +| `success` | Boolean | `true` | 邮件发送成功 | + +### Artrans 接口 + +::: warning + +此接口暂不稳定,请避免使用! + +::: + +**POST** `/api/admin/artransfer` + +**参数** + +| 字段名 | 数据类型 | 必需 | 说明 | +| ----- | ------- | :---: | --- | +| `type` | String | 是 | 导入数据类型 | +| `payload` | String | 否 | 导入数据 | + +**响应** 无 diff --git a/docs/docs/develop/event.md b/docs/docs/develop/event.md new file mode 100644 index 000000000..07f3ce587 --- /dev/null +++ b/docs/docs/develop/event.md @@ -0,0 +1,34 @@ +# Event + +## 基本事件 + +- `list-load` 评论加载事件 +- `list-loaded` 评论加载完成事件 +- `list-inserted` 评论插入事件 +- `editor-submit` 编辑器提交事件 +- `editor-submitted` 编辑器提交完成事件 +- `user-changed` 本地用户数据变更事件 +- `conf-updated` 配置变更事件 +- `sidebar-show` 侧边栏显示事件 +- `sidebar-hide` 侧边栏隐藏事件 + +## 添加事件监听 + +```js +Artalk.use(ctx => { + ctx.on('list-loaded', () => { + alert('评论已加载完毕') + }) +}) +``` + +## 解除事件监听 + +```js +let foo = function() { /* do something */ } + +Artalk.use(ctx => { + ctx.on('list-loaded', foo) + ctx.off('list-loaded', foo) +}) +``` diff --git a/docs/docs/develop/index.md b/docs/docs/develop/index.md new file mode 100644 index 000000000..e1dea6744 --- /dev/null +++ b/docs/docs/develop/index.md @@ -0,0 +1,18 @@ +# 开发 + +::: warning + +目前文档仍在陆续完善中... + +::: + +由于 Artalk 正处于开发阶段,使用此文档中 `API`、`Event` 前请务必检查时效性。 + + - `API` 部分参考源码 + * [@ArtalkJS/Artalk - src/api/index.ts](https://github.com/ArtalkJS/Artalk/blob/master/packages/artalk/src/api/index.ts) + * [@ArtalkJS/ArtalkGo - http/a_router.go](https://github.com/ArtalkJS/ArtalkGo/blob/master/http/a_router.go) + * [@ArtalkJS/ArtalkGo - http/a_http.go](https://github.com/ArtalkJS/ArtalkGo/blob/master/http/a_http.go) + - `Event` 部分参考源码 + * [@ArtalkJS/Artalk - types/event.d.ts](https://github.com/ArtalkJS/Artalk/blob/master/packages/artalk/types/event.d.ts) + +通过 Artalk 提供的 `API` 和 `Event`,你可以实现很多高级功能,比如编写评论管理机器人、评论提醒推送插件等。Artalk 并不为此提供技术指导,但鼓励你参考此处的文档自行定制。 diff --git a/docs/docs/guide/about.md b/docs/docs/guide/about.md new file mode 100644 index 000000000..165fe1e08 --- /dev/null +++ b/docs/docs/guide/about.md @@ -0,0 +1,17 @@ +# 🥬 关于我们 + +## ~~开发团队~~有人想自我介绍一下 + +[@qwqcode](https://github.com/qwqcode):🥬 + 🦜 + +P.S. 因为侧边栏太空了,也许。所以,不知道放点什么好。被迫写了个关于页面。 + +## 团队成员 + +ohhhhhhh. + +The Artalk. Made with ♥️. + +## 关于本站 + +该站点通过 [Netlify](https://www.netlify.com/) 对 [master](https://github.com/ArtalkJS/Docs) 分支进行自动部署。 diff --git a/docs/docs/guide/backend/admin_notify.md b/docs/docs/guide/backend/admin_notify.md new file mode 100644 index 000000000..55c7ae7a9 --- /dev/null +++ b/docs/docs/guide/backend/admin_notify.md @@ -0,0 +1,384 @@ +# 多元推送 + +你可以配置 `admin_notify`,让 ArtalkGo 以多种方式通知管理员。 + +支持 **Telegram**、**飞书**、**钉钉**、**Bark**、**Slack**、**LINE**,并且多种方式可以同时启用。 + +完整的 `admin_notify` 配置如下: + +::: details 点击显示 + +```yaml +# 多元推送 +admin_notify: + # 通知模版 + notify_tpl: "default" + noise_mode: false + # 邮件通知管理员 + email: + enabled: true # 当使用其他推送方式时,可以关闭管理员邮件通知 + mail_subject: "[{{site_name}}] 您的文章「{{page_title}}」有新回复" + # Telegram + telegram: + enabled: false + api_token: "" + receivers: + - 7777777 + # 飞书 + lark: + enabled: false + webhook_url: "" + # 钉钉 + ding_talk: + enabled: false + token: "" + secret: "" + # Bark + bark: + enabled: false + server: "http://day.app/xxxxxxx/" + # Slack + slack: + enabled: false + oauth_token: "" + receivers: + - "CHANNEL_ID" + # LINE + line: + enabled: false + channel_secret: "" + channel_access_token: "" + receivers: + - "USER_ID_1" + - "GROUP_ID_1" + # WebHook + webhook: + enabled: false + url: "" +``` + +::: + +## 邮件通知 + +```yaml +admin_notify: + enabled: true # 当使用其他推送方式时,可以关闭管理员邮件通知 + mail_subject: "[{{site_name}}] 您的文章「{{page_title}}」有新回复" +``` + +当使用其他推送方式时,可以关闭管理员邮件通知。 + +配置项 `mail_subject` 为发送给管理员的邮件标题。 + +在这之前,你需要配置全局邮件发送功能:[参考此处](./email.md)。 + +## Telegram + +```yaml +admin_notify: + # Telegram + telegram: + enabled: true + api_token: "" + receivers: + - 7777777 +``` + +- `api_token`:TG Bot 的 API Token。 +- `receivers`:消息接受者的数字 ID,可设置多个。 + +### 创建 TG Bot + +搜索 `@BotFather` 回复 `/newbot` 并按提示创建新的 TG 机器人。 + +![](/images/notify/tg-1.png) + +标红的文字就是你之后需要在 ArtalkGo 配置中填入的 `api_token`。 + +配置中的 `receivers` 填入需要接受消息的账号数字 ID,可以搜索机器人 `@RawDataBot` 获取如图: + +![](/images/notify/tg-2.png) + +详情可参考:[“Bots: An introduction for developers - Telegram”](https://core.telegram.org/bots) + +::: tip + +鉴于复杂的网络环境,如需使用代理,请在 ArtalkGo 启动之前配置环境变量,例如: + +```sh +export https_proxy=http://127.0.0.1:7890 +``` + +::: + +## 飞书 + +```yaml +admin_notify: + # 飞书 + lark: + enabled: true + webhook_url: "" +``` + +- `webhook_url`:填入创建群组机器人时得到的 WebHook 地址。 + +### 创建群组机器人 + +点击顶部的加号,创建一个新的群组: + +![](/images/notify/lark-1.png) + +找到右侧的「群设置」-「群机器人」- 点击「添加机器人」- 选择「自定义机器人」并按照提示创建。 + + + +复制如上图的 WebHook 地址,并修改 ArtalkGo 的 `webhook_url` 配置即可。 + + + +可参考:[“飞书帮助中心文档”](https://www.feishu.cn/hc/zh-CN/articles/360024984973) + +## 钉钉 + +```yaml +admin_notify: + # 钉钉 + ding_talk: + enabled: true + token: "" + secret: "" +``` + +可参考:[“钉钉开放文档”](https://open.dingtalk.com/document/robots/custom-robot-access) + +## Bark + +```yaml +admin_notify: + # Bark + bark: + enabled: true + server: "http://day.app/xxxxxxx/" +``` + +[Bark](https://github.com/Finb/Bark) 是一款开源的 iOS App,并且[支持自托管](https://github.com/Finb/bark-server),你能使用 Bark 轻松地推送消息给你的 iOS 设备。 + +你可以在 App Store 搜索下载,并获得需要填入 ArtalkGo 的 `server` 配置项: + + + + + +## Slack + +```yaml +admin_notify: + # Slack + slack: + enabled: true + oauth_token: "" + receivers: + - "CHANNEL_ID" +``` + +## LINE + +```yaml +admin_notify: + # LINE + line: + enabled: true + channel_secret: "" + channel_access_token: "" + receivers: + - "USER_ID_1" + - "GROUP_ID_1" +``` + +## 通知模版 + +```yaml +admin_notify: + notify_tpl: "default" +``` + +配置项 `admin_notify.notify_tpl` 可设置为自定义通知模版「文件路径」,默认的通知模版为: + +``` +@{{reply_nick}}: + +{{reply_content}} + +{{link_to_reply}} +``` + +可用变量和邮件模板相同,可参考:[“邮件模版”](./email.md#邮件模板) + +## 嘈杂模式 `noise_mode` + +```yaml +admin_notify: + noise_mode: false +``` + +noise_mode 默认为关闭状态,当该项设置为 `false` 时,站内仅向管理员回复的消息会发送通知,例如「普通用户 A」回复「普通用户 B」,这两个用户之间的通讯不会通知管理员。 + +注:当 `moderator.pending_default` 为 `true` 时,noise_mode 为始终开启状态。 + +## WebHook 回调 + +开启 WebHook 后,创建新评论将以 **POST** 方式携带 `application/json` 类型的 Body 数据请求设定的 WebHook 地址。 + +你可以编写自己的 Server 端代码,处理来自 ArtalkGo 的请求。 + +**ArtalkGo 配置文件** + +```yaml +admin_notify: + webhook: + enabled: true + url: "http://localhost:8080/" +``` + +**Body 数据内容** + +`application/json` 类型 + +|Key|描述|类型|备注| +| - | - | - | - | +|`notify_subject`|通知标题 |String| 对应 admin_notify.notify_subject 配置项 | +|`notify_body` |通知内容 |String| 根据 admin_notify.notify_tpl 模版渲染 | +|`comment` |评论内容 |Object| 新创建的评论数据对象 | +|`parent_comment`|评论回复的目标|Object| Root 根节点评论类型改项为 null | + +**Body 数据样本** + +```js +{ + "notify_subject": "", + "notify_body": "@测试用户:\n\n测试内容\n\nhttps://127.0.0.1/index.html?atk_comment=1057", + "comment": { + "id": 1057, + "content": "测试内容", + "user_id": 226, + "nick": "测试用户", + "email_encrypted": "654236c1e78i4c09a17c4869c9d43910", + "link": "https://qwqaq.com", + "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 12_4_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.64 Safari/537.36", + "date": "2022-05-23 17:00:23", + "is_collapsed": false, + "is_pending": false, + "is_pinned": false, + "is_allow_reply": false, + "rid": 0, + "badge_name": "", + "badge_color": "", + "visible": true, + "vote_up": 0, + "vote_down": 0, + "page_key": "/index.html", + "page_url": "https://127.0.0.1/index.html", + "site_name": "ArtalkDocs" + }, + "parent_comment": null +} +``` + +**Node.js express 处理示例** + +```js +const express = require('express'); + +const app = express(); + +app.use(express.json()); // Use JSON middleware + +app.post('/', function(request, response){ + console.log(request.body); + + const notifySubject = request.body.notify_subject + const notifyBody = request.body.notify_body + console.log(notifySubject, notifyBody); + + response.send(request.body); +}); + +app.listen(8080); +``` + +**Node.js http 处理示例** + +```js +const http = require("http"); + +const requestListener = function (req, res) { + // receive json request + let body = ""; + req.on("data", function (data) { + body += data; + }); + req.on("end", function () { + let json = ""; + try { + json = JSON.parse(body); + } catch {} + + // do something with json + console.log(json); + res.end(); + }); + + res.writeHead(200); + res.end("Hello, World!"); +}; + +const server = http.createServer(requestListener); +server.listen(8080); +``` + +**PHP Laravel 处理示例** + +```php +Route::get('/', function (Request $request) { + $data = $request->json()->all(); + $notify_subject = $data["notify_subject"]; + $notify_body = $data["notify_body"]; +}); +``` + +**Golang net/http 处理示例** + +```go +package main + +import ( + "encoding/json" + "log" + "net/http" +) + +type ArtalkGoNotify struct { + NotifySubject string `json:"notify_subject"` + NotifyBody string `json:"notify_body"` + Comment interface{} `json:"comment"` + ParentComment interface{} `json:"parent_comment"` +} + +func webhookHandler(rw http.ResponseWriter, req *http.Request) { + decoder := json.NewDecoder(req.Body) + var notify ArtalkGoNotify + err := decoder.Decode(¬ify) + if err != nil { + panic(err) + } + log.Println(notify.NotifyBody) +} + +func main() { + http.HandleFunc("/webhook", webhookHandler) + log.Fatal(http.ListenAndServe(":8080", nil)) +} +``` + diff --git a/docs/docs/guide/backend/build.md b/docs/docs/guide/backend/build.md new file mode 100644 index 000000000..1485547c6 --- /dev/null +++ b/docs/docs/guide/backend/build.md @@ -0,0 +1,67 @@ +# 后端构建 + +## 编译运行 + +```bash +# 拉取代码 +git clone https://github.com/ArtalkJS/ArtalkGo.git ArtalkGo + +# 编译程序 +cd ArtalkGo && make all + +# 配置文件 +cp artalk-go.example.yml artalk-go.yml +vim artalk-go.yml + +# 运行程序 +./bin/artalk-go help +./bin/artalk-go -c artalk-go.yml server +``` + +## 构建二进制文件 + +```bash +# 拉取代码 +git clone https://github.com/ArtalkJS/ArtalkGo.git + +# 执行编译 +make all +``` + +编译二进制文件将会输出到 `bin` 目录中 + +## Docker Compose 编译运行 + +```bash +# 拉取代码 +git clone https://github.com/ArtalkJS/ArtalkGo +cd ArtalkGo + +# 构建镜像 +docker-compose build + +# 运行 +docker-compose up -d +``` + +## Docker 镜像构建 + +```bash +# 拉取代码 +git clone https://github.com/ArtalkJS/ArtalkGo +cd ArtalkGo + +# 构建镜像 +make docker-docker + +# 发布镜像 +make docker-push +``` + +## DevOps + +后端构建目前已交给 [GitHub Actions](https://github.com/ArtalkJS/ArtalkGo/actions) 自动完成 + +|Docker 镜像构建|Release 编译| +|-|-| +|[![CI to Docker Hub](https://github.com/ArtalkJS/ArtalkGo/actions/workflows/dockerhub.yml/badge.svg)](https://github.com/ArtalkJS/ArtalkGo/actions/workflows/dockerhub.yml)|[![Release Build](https://github.com/ArtalkJS/ArtalkGo/actions/workflows/release.yml/badge.svg?branch=master)](https://github.com/ArtalkJS/ArtalkGo/actions/workflows/release.yml)| diff --git a/docs/docs/guide/backend/captcha.md b/docs/docs/guide/backend/captcha.md new file mode 100644 index 000000000..bf36c7391 --- /dev/null +++ b/docs/docs/guide/backend/captcha.md @@ -0,0 +1,80 @@ +# 验证码 + +ArtalkGo 内置图片验证码功能,你可以配置操作频率限制,当超过限度时激活验证码。 + +此外,你也可以接入[极验](https://www.geetest.com/),拥有一个滑动验证码。 + +完整的 `captcha` 配置如下: + +```yaml +# 验证码 +captcha: + enabled: true # 总开关 + always: false # 总是需要验证码 + action_limit: 3 # 激活验证码所需操作次数 + action_reset: 60 # 重置操作计数器超时 (单位:s, 设为 -1 不重置) + # Geetest 极验 + geetest: # https://www.geetest.com + enabled: false + captcha_id: "" + captcha_key: "" +``` + +- **always**:当该项为 `true` 时,总是需要输入验证码。 +- **action_limit**:激活评论所需的操作次数。 +- **action_reset**:当时间超过该值时会重置操作计数器,单位为秒,设为 `-1` 将永不重置。 + +注:当 `always` 开启时,`action_limit` 和 `action_reset` 配置将失效。 + +## 配置举例 + +#### 例 1 + +在 60s 时间范围内,当操作次数超过 3 次,将一直被要求输入验证码: + +```yaml +captcha: + action_limit: 3 + action_reset: 60 +``` + +在 60s 后将自动重置计数器,即重新获得 3 次不用输入验证码的机会。 + +#### 例 2 + +无论多少时间范围内,这个 IP 地址操作次数只要超过 5 次时,将一直被要求输入验证码: + +```yaml +captcha: + action_limit: 5 + action_reset: -1 +``` + +#### 例 3 + +总是要求输入验证码,无论这个 IP 操作多少次: + +```yaml +captcha: + always: true +``` + +## 操作的定义 + +一个 IP 地址的一次「评论、投票、图片上传、密码验证」都算作一次「操作」。 + +## Geetest 极验 + +ArtalkGo 支持接入 [Geetest 极验](https://www.geetest.com/adaptive-captcha) 第四代「行为验」,启用极验后,验证码将切换为滑动验证码。 + +你需要在官网注册账号,并申请获得 `captcha_id` 和 `captcha_key`,并填入配置文件: + +```yaml +captcha: + # 省略其他配置... + geetest: + enabled: true + captcha_id: "" + captcha_key: "" +``` + diff --git a/docs/docs/guide/backend/config.md b/docs/docs/guide/backend/config.md new file mode 100644 index 000000000..126c39bc1 --- /dev/null +++ b/docs/docs/guide/backend/config.md @@ -0,0 +1,314 @@ +# 后端配置 + +::: tip +后端配置可以在侧边栏 “[控制中心](/guide/frontend/sidebar.md)” 直接修改,无需手动修改配置 +::: + +ArtalkGo 默认以工作目录下的 `artalk-go.yml` 作为配置文件,可使用参数 `-c` 来指定具体文件: + +```bash +artalk-go -c ./conf.yml +``` + +## 获取模版配置文件 + +可参考一份「完整的配置文件」:[artalk-go.example.yml](https://github.com/ArtalkJS/ArtalkGo/blob/master/artalk-go.example.yml) + +#### 使用 gen 命令生成配置文件 + +ArtalkGo 提供 `gen` 命令,你可以快速生成一份新的配置文件: + +```bash +artalk-go gen conf ./artalk-go.yml +``` + +#### 命令行下载配置文件 + +```bash +curl -L https://raw.githubusercontent.com/ArtalkJS/ArtalkGo/master/artalk-go.example.yml > artalk-go.yml +``` + +```bash +wget -O artalk-go.yml https://raw.githubusercontent.com/ArtalkJS/ArtalkGo/master/artalk-go.example.yml +``` + +## 加密密钥 `app_key` + +在 ArtalkGo 启动之前,你需要配置一个 `app_key` 用于对网站内容进行安全加密: + +```yaml +app_key: "<任意的字符>" +``` + +## 数据库 `db` + +ArtalkGo 支持连接多种数据库,支持 SQLite、MySQL、PostgreSQL、SQL Server 配置如下: + +#### SQLite + +SQLite 是轻型数据库,使用单个文件存储数据,无需额外运行程序,尤其适合小型站点,例如个人博客。 + +```yaml +db: + type: "sqlite" + file: "./data/artalk-go.db" +``` + +#### MySQL / PostgreSQL / SQL Server + +修改 `type` 为你的数据库类型: + +```yaml +db: + type: "mysql" # sqlite, mysql, pgsql, mssql + name: "artalk" # 数据库名 + host: "localhost" # 地址 + port: "3306" # 端口 + user: "root" # 账号 + password: "" # 密码 + charset: "utf8mb4" # 编码格式 + table_prefix: "" # 表前缀 (例如:"atk_") +``` + +数据表将在 ArtalkGo 启动时自动完成创建,无需额外操作。 + +## 管理员 `admin_users` + +你需要配置管理员账户,这样才能通过「[控制中心](../frontend/sidebar.md)」对站点内容进行管理。 + +ArtalkGo 支持多站点,你可以创建多个管理员账户,为其分配站点,让你的朋友们共用同一个后端程序。 + +详情参考:[“管理员 × 多站点”](/guide/backend/multi-site.md) + +## 可信域名 `trusted_domains` + +```yaml +trusted_domains: + - "https://前端使用域名A.com" + - "https://前端使用域名B.com" +``` + +配置该项能限制来自列表外的 Referer 和跨域请求。 + +:::tip + +你需要将「使用该后端的前端」URL 地址加入可信域名列表中, + +若非默认 80/443 端口需额外附带端口号,例如:`https://example.com:8080` + +::: + +在侧边栏[控制中心](../frontend/sidebar.md#控制中心)「站点」选项卡 - 选择站点「修改 URL」,填入站点 URL 也具有相同的效果;添加多个 URL 可使用 `","` 英文逗号分隔,修改后请重启 ArtalkGo。 + +可以将其关闭: + +```yaml +trusted_domains: + - "*" +``` + +::: danger + +但并不建议这样做,关闭后将存在潜在安全风险,例如可能遭受 CSRF 跨域攻击。 + +::: + +细节:`trusted_domains` 配置项实际上是对响应标头: + +- `Access-Control-Allow-Origin` 的控制 (参考:[W3C Cross-Origin Resource Sharing](https://fetch.spec.whatwg.org/#http-cors-protocol)) +- `Referer` 的限制 (参考:[Referer - HTTP | MDN](https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Referer)) + +CSRF 跨域攻击防范措施参考:[OWASP 安全备忘单](https://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html) + +## 默认站点 `site_default` + +如果你觉得大概是不会用到 Artalk 的多站点功能,可以直接将该项配置为你的站点名,例如: + +```yaml +site_default: "Artalk 官网" +``` + +然后在前端直接使用这个站点名: + +```js +new Artalk({ site: "Artalk 官网" }) +``` + +这样,你就无需在侧边栏的[控制中心](../frontend/sidebar.md#控制中心)手动创建站点。 + +## 前端配置 `frontend` + +增加 `frontend` 字段内容可以在后端控制前端的配置,详情可参考:[“在后端控制前端”](/guide/backend/fe-control)。 + +## 邮件通知 `email` + +配置邮件通知,让回复通过邮件的形式通知目标用户,你可以自定义邮件发送者名称、标题、模版等。 + +详情参考:[“后端 · 邮件通知”](/guide/backend/email.md) + +## 多元推送 `admin_notify` + +你可以配置多种消息发送方式,例如飞书、Telegram 等,当收到新的评论时通知管理员。 + +详情参考:[“后端 · 多元推送”](/guide/backend/admin_notify.md) + +## 评论审核 `moderator` + +配置评论审核来自动拦截垃圾评论。 + +详情参考:[“后端 · 评论审核”](/guide/backend/moderator.md) + +## 验证码 `captcha` + +支持图片、滑动验证码,通过验证码对请求频率进行限制。 + +详情参考:[“后端 · 验证码”](/guide/backend/captcha.md) + +## 缓存配置 `cache` + +为了提高评论系统的响应速度和性能,ArtalkGo 内置一套缓存机制,并且默认开启,无需额外配置。但如果有需要,你也可以连接外部缓存服务器,支持 Redis 和 Memcache。 + +```yaml +cache: + type: "builtin" # 支持 redis, memcache, builtin (自带缓存) + expires: 30 # 缓存过期时间 (单位:分钟) + warm_up: false # 程序启动时预热缓存 + server: "" # 连接缓存服务器 (例如:"localhost:6379") +``` + +- **warm_up**:缓存预热功能。设置为 `true`,在 ArtalkGo 启动时会立刻对数据库内容进行全面缓存,如果你的评论数据较多,多达上万条,启动时间可能会延长。 +- **type**:缓存类型。可选:`redis`, `memcache`, `builtin`。 + +type 默认为 `builtin`,如遇特殊情况可将缓存关闭,将其设置为 `disabled`。 + +注:如果在 ArtalkGo 程序外部修改数据库内容,需要刷新 ArtalkGo 缓存才能更新。 + +--- + +Redis 身份认证、数据库配置: + +```yaml +# 缓存 +cache: + # 省略其他配置项... + redis: + network: "tcp" # 连接方式 (tcp 或 unix) + username: "" # 用户名 + password: "" # 密码 + db: 0 # 使用零号数据库 +``` + +技术细节:[ArtalkGo 缓存机制 时序图.png](/images/artalk-go/artalk-go-cache.png) + +![](/images/artalk-go/artalk-go-cache.png) + +## 监听地址 `host` + +ArtalkGo 的默认 HTTP 端口为 23366,你可以在配置文件中指定: + +```yaml +host: "0.0.0.0" +port: 23366 +``` + +配置 `host` 监听地址为 `0.0.0.0` 将 ArtalkGo 服务暴露到全网可访问范围, + +如果你只想让 ArtalkGo 仅本地能够访问,可将 `host` 配置为 `127.0.0.1`。 + +命令行下启动 ArtalkGo 时,可以携带 `--host` 和 `--port` 参数分别对地址和端口进行指定,例如: + +```bash +artalk-go server --host 127.0.0.1 --port 8080 +``` + +## 加密传输 `ssl` + +```yaml +ssl: + enabled: true + cert_path: "" + key_path: "" +``` + +你可以配置该项,让 HTTP 升级为 HTTPS,通过 SSL 协议加密传输数据。 + +- `cert_path`:SSL 证书公钥文件路径。 +- `key_path`:SSL 证书私钥文件路径。 + +你也可以直接反向代理 ArtalkGo 本地服务器,然后在例如 Nginx 启用 HTTPS。 + +## 时区配置 `timezone` + +```yaml +timezone: "Asia/Shanghai" +``` + +该值填写你所在地时区,对应 IANA 数据库时区名,参考:[Wikipedia](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones) / [RFC-6557](https://www.rfc-editor.org/rfc/rfc6557.html)。 + +``` +UTC+08:00 Asia/Shanghai +UTC+09:00 Asia/Tokyo +UTC-07:00 America/Los_Angeles +UTC-04:00 America/New_York +``` + +## 登录超时 `login_timeout` + +该值设定管理员账户登录 JWT 令牌的有效期,单位:秒。 + +例如,3 天有效: + +```yaml +login_timeout: 259200 +``` + +## 日志配置 `log` + +打开日志后,系统错误等信息将被记录到设定的文件中。 + +```yaml +log: + enabled: true # 总开关 + filename: "./data/artalk-go.log" # 日志文件路径 +``` + +## 调试模式 `debug` + +将 `debug` 配置为 `true` 启用调试模式。 + +```yaml +debug: true +``` + +## 工作目录 `-w` 参数 + +ArtalkGo 在不指定工作目录的情况下,会使用「程序启动时的目录」作为工作目录。 + +```bash +pwd # 显示当前目录路径 +``` + +使用参数 `-w` 来指定工作目录,它通常是一个「绝对路径」,例如: + +```bash +artalk-go -w /root/artalk -c ./conf.yml +``` + +注:`-c` 的相对路径会基于 `-w` 的路径,ArtalkGo 此时会读取 `/root/artalk/conf.yml` 作为配置文件。 + +其次,在「配置文件中」使用的「相对路径」,也会基于「工作目录」。 + +例如 `conf.yml` 中有这样的配置: + +```yaml +test_file: "./data/artalk-go.log" +``` + +将读取 `/root/artalk/data/artalk-go.log`。 + +::: tip + +配置文件相关代码:[/config/config.go](https://github.com/ArtalkJS/ArtalkGo/blob/master/config/config.go) + +前往:[“前端配置”](/guide/frontend/config.md) +::: diff --git a/docs/docs/guide/backend/daemon.md b/docs/docs/guide/backend/daemon.md new file mode 100644 index 000000000..e7b1e3a51 --- /dev/null +++ b/docs/docs/guide/backend/daemon.md @@ -0,0 +1,75 @@ +# 守护进程 + +## Docker + +更新 Docker 容器的 [Restart 策略](https://docs.docker.com/config/containers/start-containers-automatically/#use-a-restart-policy) 以达到进程守护效果。 + +```bash +docker update --restart=unless-stopped artalk-go +``` + +## Docker Compose + +在 `docker-compose.yml` 文件给服务添加 `restart: unless-stopped` 策略: + +```diff +version: '3' +services: + artalk: ++ restart: unless-stopped +``` + +## tmux + +tmux 将创建一个持续的命令行会话,在 SSH 或 tty 断开后保持在后台。 + +Note: 服务器关闭或重启后,tmux 会话将被清除,需要手动重新运行程序。 + +1. 创建会话 `tmux new -s artalk-go` +2. 运行程序 `./artalk-go server` + +恢复接入会话:`tmux attach -t artalk-go` + +查看所有会话:`tmux ls` + +## systemd + +`sudo vim /etc/systemd/system/artalk-go.service` + +```ini +[Unit] +Description=Artalk Go +After=network.target remote-fs.target nss-lookup.target + +[Service] +User=root +ExecStart= server -w <工作目录绝对路径> -c <配置文件相对于工作目录路径> +ExecReload=/bin/kill -s HUP $MAINPID +ExecStop=/bin/kill -s QUIT $MAINPID +Restart=on-abnormal +RestartSec=5s + +[Install] +WantedBy=multi-user.target +``` +- 更新 systemd 配置:`systemctl daemon-reload` +- 启动:`systemctl start artalk-go.service` +- 停止:`systemctl stop artalk-go.service` +- 状态:`systemctl status artalk-go.service` + +Tip: 设置 `alias` 简化命令输入;ArtalkGo 参数 `-w` 用于指定工作目录,配置文件中的所有「相对路径」会基于该目录,例如 `./data/` 文件夹。 + +## Supervisor + +以宝塔面板举例:打开「软件商店」,搜索并安装「Supervisor管理器」: + +![](/images/baota-supervisor/0.png) + +安装后,打开插件,点击「添加守护程序」: + +![](/images/baota-supervisor/1.png) + +> - 启动用户:`root` 或其他 +> - 运行目录:点击右侧图标,选择 Artalk 所在目录 +> - 启动命令:`./artalk-go server` + diff --git a/docs/docs/guide/backend/data.md b/docs/docs/guide/backend/data.md new file mode 100644 index 000000000..e63d70da3 --- /dev/null +++ b/docs/docs/guide/backend/data.md @@ -0,0 +1,5 @@ +# 数据 + +## 备份 + +前往:[“数据迁移 · 备份”](/guide/transfer.md) diff --git a/docs/docs/guide/backend/docker.md b/docs/docs/guide/backend/docker.md new file mode 100644 index 000000000..e53c0d48b --- /dev/null +++ b/docs/docs/guide/backend/docker.md @@ -0,0 +1,115 @@ +# Docker + +Artalk 提供后端程序的 Docker 镜像,以便加速部署流程,提供一个良好的部署体验。 + +[Docker Hub](https://hub.docker.com/r/artalk/artalk-go) 镜像版本随代码仓库的 [Releases](https://github.com/ArtalkJS/ArtalkGo/releases) 保持同步。 + +## 镜像拉取 + +`docker pull artalk/artalk-go` + +## 容器创建 + +:::tip + +推荐使用 Docker Compose:[“后端部署”](/guide/backend/install) 页面已详细讲解。 + +::: + +常规的 Docker 容器创建可参考: + +```bash +# 为 ArtalkGo 创建一个目录 +mkdir ArtalkGo +cd ArtalkGo + +# 拉取 docker 镜像 +docker pull artalk/artalk-go + +# 生成配置文件 +docker run -it -v $(pwd)/data:/data --rm artalk/artalk-go gen config data/artalk-go.yml + +# 编辑配置文件 +vim data/artalk-go.yml + +# 运行 docker 容器 +docker run -d \ + --name artalk-go \ + -p 0.0.0.0:8080:23366 \ + -v $(pwd)/data:/data \ + artalk/artalk-go +``` + +然后,在前端配置填入后端地址: + +```js +new Artalk({ server: "http://your_domain:8080" }) +``` + +## 重启 + +修改配置文件后,需要重启才能生效。 + +```bash +# Docker Compose +docker-compose restart + +# Docker +docker restart artalk-go +``` + +## 停止 + +```bash +# Docker Compose +docker-compose stop + +# Docker +docker stop artalk-go +``` + +## 升级 + +删除现有容器,拉取最新镜像,然后重新创建容器即可。 + +### Docker Compose + +```bash +docker-compose down +docker-compose pull +docker-compose up -d +``` + +### Docker + +```bash +docker stop artalk-go +docker rm artalk-go +docker pull artalk/artalk-go +``` + +::: tip +升级可能会有配置文件等变动,请注意查看版本 Changelog,通常是在 [GitHub Release](https://github.com/ArtalkJS/ArtalkGo/releases) 页面 +::: + +## 拉取历史镜像 + +镜像会随代码仓库 tags 自动构建发布,您可拉取不同版本号的镜像。 + +```bash +docker pull artalk/artalk-go@版本号 +``` + +## 进入容器 + +```bash +# Docker Compose +docker-compose exec artalk bash + +# Docker +docker exec -it artalk bash +``` + +## 多平台兼容性 + +Docker 镜像暂仅提供 amd_64 构建,若需要在 ARM 架构运行,请下载 [二进制编译构建](/guide/backend/install.md#普通方式) diff --git a/docs/docs/guide/backend/email.md b/docs/docs/guide/backend/email.md new file mode 100644 index 000000000..bf7c9467a --- /dev/null +++ b/docs/docs/guide/backend/email.md @@ -0,0 +1,325 @@ +# 邮件通知 + +启用后,当用户「新增评论」或「回复评论」时,ArtalkGo 会向「普通用户」或「管理员」发送邮件。 + +ArtalkGo 支持 SMTP 协议、阿里云邮件推送、调用系统 sendmail 命令等。 + +完整的 `email` 配置如下: + +```yaml +# 邮件通知 +email: + enabled: false # 总开关 + send_type: "smtp" # 发送方式 [smtp, ali_dm, sendmail] + send_name: '{{reply_nick}}' # 发信人昵称 + send_addr: "example@qq.com" # 发信人地址 + mail_subject: "[{{site_name}}] 您收到了来自 @{{reply_nick}} 的回复" + mail_tpl: "default" # 邮件模板文件 + smtp: + host: "smtp.qq.com" + port: 587 + username: "example@qq.com" + password: "" + ali_dm: # https://help.aliyun.com/document_detail/29444.html + access_key_id: "" # 阿里云颁发给用户的访问服务所用的密钥 ID + access_key_secret: "" # 用于加密的密钥 + account_name: "example@example.com" # 管理控制台中配置的发信地址 +``` + +### 选择发件方式 + +配置项 `enabled` 启用邮件,`send_type` 用于选择发送方式,可选:`smtp`, `ali_dm`, `sendmail`。 + +```yaml +email: + enabled: true + send_type: "smtp" # 发送方式 + # 省略其他配置... + smtp: + # SMTP 配置... + ali_dm: + # 阿里云推送配置... +``` + +### SMTP 配置 + +```yaml +# 邮件通知 +email: + enabled: true + send_type: "smtp" # 选择 smtp + smtp: + host: "smtp.qq.com" + port: 587 + username: "example@qq.com" + password: "" +``` + +### 阿里云推送配置 + +```yaml +email: + enabled: true + send_type: "ali_dm" # 选择 ali_dm + ali_dm: + access_key_id: "" # 阿里云颁发给用户的访问服务所用的密钥 ID + access_key_secret: "" # 用于加密的密钥 + account_name: "example@example.com" # 管理控制台中配置的发信地址 +``` + +可参考:[阿里云官方文档](https://help.aliyun.com/document_detail/29444.html) + +## 评论回复 + +邮件中会有一个评论回复按钮,该链接指向前端给定的页面 PageKey,若你提供的 `pageKey` 配置项为页面的「相对路径」,你需要在「[控制中心](../frontend/sidebar.md#控制中心)」-「站点」为你的站点设置一个 URL: + + + +## 邮件模板 + +### 模板变量 + +你可以在 `mail_subject` 和 `mail_subject_to_admin` 以及邮件模板文件中使用模板变量: + +```yaml +email: + # 省略其他配置... + mail_subject: "[{{site_name}}] 您收到了来自 @{{reply_nick}} 的回复" + mail_subject_to_admin: '[{{site_name}}] 您的文章 "{{page_title}}" 有新回复' + mail_tpl: "default" # 邮件模板文件 +``` + +变量是 “Mustache” 的语法,`双大括号` + `变量名` 的形式即可输出一个变量: + +**基本内容变量** + +``` +{{content}} # 评论内容 +{{link_to_reply}} # 回复链接 +{{nick}} # 评论者昵称 +{{page_title}} # 页面标题 +{{page_url}} # 页面 PageKey (URL) +{{reply_content}} # 回复对象的内容 +{{reply_nick}} # 回复对象的昵称f +{{site_name}} # 站点名 +{{site_url}} # 站点 URL +``` + +::: details 查看其他变量 + +``` +# 评论创建者 +{{comment.badge_color}} +{{comment.badge_name}} +{{comment.content}} +{{comment.content_raw}} +{{comment.date}} +{{comment.datetime}} +{{comment.email}} +{{comment.email_encrypted}} +{{comment.id}} +{{comment.is_allow_reply}} +{{comment.is_collapsed}} +{{comment.is_pending}} +{{comment.link}} +{{comment.nick}} +{{comment.page.admin_only}} +{{comment.page.id}} +{{comment.page.key}} +{{comment.page.site_name}} +{{comment.page.title}} +{{comment.page.url}} +{{comment.page.vote_down}} +{{comment.page.vote_up}} +{{comment.page_key}} +{{comment.page_title}} +{{comment.rid}} +{{comment.site.first_url}} +{{comment.site.id}} +{{comment.site.name}} +{{comment.site.urls.0}} +{{comment.site.urls_raw}} +{{comment.site_name}} +{{comment.time}} +{{comment.ua}} +{{comment.visible}} +{{comment.vote_down}} +{{comment.vote_up}} + +# 父评论(评论创建者回复的评论) +{{parent_comment.badge_color}} +{{parent_comment.badge_name}} +{{parent_comment.content}} +{{parent_comment.content_raw}} +{{parent_comment.date}} +{{parent_comment.datetime}} +{{parent_comment.email}} +{{parent_comment.email_encrypted}} +{{parent_comment.id}} +{{parent_comment.is_allow_reply}} +{{parent_comment.is_collapsed}} +{{parent_comment.is_pending}} +{{parent_comment.link}} +{{parent_comment.nick}} +{{parent_comment.page.admin_only}} +{{parent_comment.page.id}} +{{parent_comment.page.key}} +{{parent_comment.page.site_name}} +{{parent_comment.page.title}} +{{parent_comment.page.url}} +{{parent_comment.page.vote_down}} +{{parent_comment.page.vote_up}} +{{parent_comment.page_key}} +{{parent_comment.page_title}} +{{parent_comment.rid}} +{{parent_comment.site.first_url}} +{{parent_comment.site.id}} +{{parent_comment.site.name}} +{{parent_comment.site.urls}} +{{parent_comment.site.urls_raw}} +{{parent_comment.site_name}} +{{parent_comment.time}} +{{parent_comment.ua}} +{{parent_comment.visible}} +{{parent_comment.vote_down}} +{{parent_comment.vote_up}} +``` + +::: + +::: details 查看数据样例 + +```json +{ + "content": "

测试内容

\n", + "link_to_reply": "https://artalk.js.org/?atk_comment=8100&atk_notify_key=44a9b2f08312565fba47c716df9d177f", + "nick": "用户名", + "page_title": "Artalk", + "page_url": "https://artalk.js.org/", + + "reply_content": "

回复者内容

\n", + "reply_nick": "回复者", + "site_name": "ArtalkDemo", + "site_url": "http://localhost:3000/", + + "comment.badge_color": "", + "comment.badge_name": "", + "comment.content": "

回复者内容

\n", + "comment.content_raw": "回复者内容", + "comment.date": "2021-11-22", + "comment.datetime": "2021-11-22 22:22:42", + "comment.email": "replyer@example.com", + "comment.email_encrypted": "249898bd50e0febc5799485cf10b345a", + "comment.id": 8100, + "comment.is_allow_reply": true, + "comment.is_collapsed": false, + "comment.is_pending": false, + "comment.link": "", + "comment.nick": "回复者", + "comment.page.admin_only": false, + "comment.page.id": 75, + "comment.page.key": "https://artalk.js.org/", + "comment.page.site_name": "ArtalkDemo", + "comment.page.title": "Artalk", + "comment.page.url": "https://artalk.js.org/", + "comment.page.vote_down": 0, + "comment.page.vote_up": 0, + "comment.page_key": "https://artalk.js.org/", + "comment.page_title": "Artalk", + "comment.rid": 8099, + "comment.site.first_url": "http://localhost:3000/", + "comment.site.id": 2, + "comment.site.name": "ArtalkDemo", + "comment.site.urls.0": "http://localhost:3000/", + "comment.site.urls_raw": "http://localhost:3000/", + "comment.site_name": "ArtalkDemo", + "comment.time": "22:22:42", + "comment.ua": "Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.3 Mobile/15E148 Safari/604.1", + "comment.visible": false, + "comment.vote_down": 0, + "comment.vote_up": 0, + + "parent_comment.badge_color": "", + "parent_comment.badge_name": "", + "parent_comment.content": "

测试内容

\n", + "parent_comment.content_raw": "测试内容", + "parent_comment.date": "2021-11-22", + "parent_comment.datetime": "2021-11-22 22:21:17", + "parent_comment.email": "test@example.com", + "parent_comment.email_encrypted": "55502f40dc8b7c769880b10874abc9d0", + "parent_comment.id": 8099, + "parent_comment.is_allow_reply": true, + "parent_comment.is_collapsed": false, + "parent_comment.is_pending": false, + "parent_comment.link": "https://qwqaq.com", + "parent_comment.nick": "用户名", + "parent_comment.page.admin_only": false, + "parent_comment.page.id": 75, + "parent_comment.page.key": "https://artalk.js.org/", + "parent_comment.page.site_name": "ArtalkDemo", + "parent_comment.page.title": "Artalk", + "parent_comment.page.url": "https://artalk.js.org/", + "parent_comment.page.vote_down": 0, + "parent_comment.page.vote_up": 0, + "parent_comment.page_key": "https://artalk.js.org/", + "parent_comment.page_title": "Artalk", + "parent_comment.rid": 0, + "parent_comment.site.first_url": "http://localhost:3000/", + "parent_comment.site.id": 2, + "parent_comment.site.name": "ArtalkDemo", + "parent_comment.site.urls.0": "http://localhost:3000/", + "parent_comment.site.urls_raw": "http://localhost:3000/", + "parent_comment.site_name": "ArtalkDemo", + "parent_comment.time": "22:21:17", + "parent_comment.ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.82 Safari/537.36", + "parent_comment.visible": false, + "parent_comment.vote_down": 0, + "parent_comment.vote_up": 0, +} +``` + +::: + +### 自定义模板 + +你可以将 `mail_tpl` 设置为一个「具体的文件路径」,使用外部的自定义邮件模板。 + +例如,将 `mail_tpl` 配置为 `"/root/Artalk/data/mail_tpl/your_email_template.html"` + +```yaml +email: + mail_tpl: "/root/Artalk/data/mail_tpl/your_email_template.html" + # 其他配置省略... +``` + +那么,在这个路径应该有一个文件: + +```html +
+

Hi, {{nick}}:

+

+ 您在 “{{page_title}}” 收到了回复: +

+
+
@{{reply_nick}}:
+
{{reply_content}}
+
+

回复消息 »

+
+``` + +ArtalkGo 内置许多预设的邮件模板,例如 `mail_tpl: "default"` 使用的就是:[/email-tpl/default.html](https://github.com/ArtalkJS/ArtalkGo/blob/master/email-tpl/default.html) + +## 发向管理员的邮件 + +邮件通知目标为管理员和普通用户,你可通过如下配置,为发向管理员的邮件设定不同的标题: + +```yaml +admin_notify: + enabled: true + mail_subject: "[{{site_name}}] 您的文章「{{page_title}}」有新回复" +``` + +注:旧版 `email.mail_subject_to_admin` 配置项已弃用,请使用以上替代。 + +不局限于邮件,ArtalkGo 支持多种方式向管理员发送通知,参考:[“多元推送”](./admin_notify.md#邮件通知)。 diff --git a/docs/docs/guide/backend/fe-control.md b/docs/docs/guide/backend/fe-control.md new file mode 100644 index 000000000..057d62bf4 --- /dev/null +++ b/docs/docs/guide/backend/fe-control.md @@ -0,0 +1,60 @@ +# 在后端控制前端 + +你可以在后端完全控制前端的行为,我们推荐使用这种方式部署 Artalk。 + +## 在前端引入内置的资源 + +后端 ArtalkGo 服务器中内置了可供前端引入的 JS 和 CSS 资源文件: + +```html + + + + + +``` + +> 提示:将 `` 替换为你的 ArtalkGo 服务器地址。 + +这样如果升级后端 ArtalkGo 程序,前端无需更换新版 ArtalkJS 的引入地址,来使之与后端程序兼容。 + +注:内置的前端 JS 和 CSS 始终与后端版本兼容,但不保证是最新的版本。 + +## 在后端控制前端的配置 + +你能够在后端控制 [前端的配置](/guide/frontend/config)。 + +这个功能处于「默认关闭」状态,首先你需要在前端启用它: + +```diff +new Artalk({ ++ useBackendConf: true, +}) +``` + +然后,在后端 ArtalkGo 的配置文件中添加 `frontend` 字段内容,例如 `artalk-go.yml` 添加: + +```yaml +frontend: + placeholder: "键入内容..." + noComment: "「此时无声胜有声」" + sendBtn: "发送评论" + emoticons: "https://raw.githubusercontent.com/ArtalkJS/Emoticons/master/grps/default.json" + # ----- 此处省略 ------- + # 与前端配置项名称保持一致 +``` + +这样就无需在前端改动配置,前端的配置始终跟随后端。 + +一份完整的后端 `frontend` 字段配置文件可供参考:[artalk-go.frontend.example.yml](https://github.com/ArtalkJS/ArtalkGo/blob/master/artalk-go.frontend.example.yml) + +::: tip + +如果你的表情包配置项 [emoticons](/guide/frontend/emoticons) 需传递 Object 而非 URL,可以将其转为 JSON 字符串,例如: + +```yaml +frontend: + emoticons: '{"表情": { "test": "tttt..." }}' +``` + +::: diff --git a/docs/docs/guide/backend/img-upload.md b/docs/docs/guide/backend/img-upload.md new file mode 100644 index 000000000..9c9c4847a --- /dev/null +++ b/docs/docs/guide/backend/img-upload.md @@ -0,0 +1,90 @@ +# 图片上传 + +Artalk 提供图片上传功能,支持限制图片大小、上传频率等,你还能结合 upgit 将图片上传到图床。 + +完整的 `img-upload` 配置如下: + +```yaml +# 图片上传 +img_upload: + enabled: true # 总开关 + path: "./data/artalk-img/" # 图片存放路径 + max_size: 5 # 图片大小限制 (单位:MB) + public_path: null # 指定图片链接基础路径 (默认为 "/static/images/") + # 使用 upgit 将图片上传到 GitHub 或图床 + upgit: + enabled: false # 启用 upgit + exec: "./upgit -c -t /artalk-img" + del_local: true # 上传后删除本地的图片 +``` + +## 使用 Upgit 上传到图床 + +[Upgit](https://github.com/pluveto/upgit) 支持将图片上传到 Github、Gitee、腾讯云 COS、七牛云、又拍云、SM.MS 等图床或代码仓库。 + +首先,根据 [README.md](https://github.com/pluveto/upgit) 的说明,下载 Upgit 并完成你需要上传的目标图床的配置。 + +然后在 ArtalkGo 的 `img_upload.upgit` 字段填入 Upgit 启动参数 (建议使用程序绝对路径),例如: + +```yaml + upgit: + enabled: true # 启用 upgit + exec: "/root/upgit -c -t /artalk-img" + del_local: true # 上传后删除本地的图片 +``` + +## 上传频率限制 + +频率限制跟随 `captcha` 验证码配置,当超出限制将弹出验证码。 + +可参考:[“后端 · 验证码”](/guide/backend/captcha.md) + +## path + +`img_upload.path` 为上传的图片文件「本地存放目录」路径,该目录会被 ArtalkGo 映射到可访问的: + +``` +http://<后端地址>/static/images/ +``` + +## public_path + +`img.public_path` 为空的默认值为:`/static/images/` + +当该项为「相对路径」时,例如:`/static/images/` 前端上传图片得到的 HTML 标签将为: + +```html + +``` + +注:这里的 `<后端地址>` 是前端 `conf.server` 配置。 + +当该项为「完整 URL 路径」时,例如:`https://cdn.github.com/img/` 时,图片标签将为: + +```html + +``` + +提示:这个配置可以结合负载均衡等场景使用。 + +## 在前端自定义上传 API + +前端提供了配置项 `imgUploader`,你可以自定义前端图片上传时请求的 API,例如: + +```js +new Artalk({ + imgUploader: async (file) => { + const form = new FormData() + form.set('file', file) + + const imgUrl = await fetch("https://api.example.org/upload", { + method: 'POST', + body: form + }) + + return imgUrl + } +}) +``` + +参考:[前端配置文档](../frontend/config.md#imguploader) diff --git a/docs/docs/guide/backend/index.md b/docs/docs/guide/backend/index.md new file mode 100644 index 000000000..f4007d413 --- /dev/null +++ b/docs/docs/guide/backend/index.md @@ -0,0 +1,22 @@ +--- +prev: install.md +next: config.md +--- + +# ArtalkGo + +Artalk 拥有一个 Golang 语言编写的后端程序。 + +[GitHub 代码仓库](https://github.com/ArtalkJS/ArtalkGo) + +- 高效快速 +- 异步执行 +- 跨平台兼容 +- 轻量级部署 + +## Supports + +- 运行环境:支持 Linux, Windows, Darwin (x64 + ARM) +- 数据存储:支持 SQLite, MySQL, PostgreSQL, SQL Server +- 邮件发送:支持 SMTP, 阿里云邮件, 调用 sendmail 发送邮件 +- 高效缓存:支持 Redis, Memcache, In-Memory (BigCache) diff --git a/docs/docs/guide/backend/install.md b/docs/docs/guide/backend/install.md new file mode 100644 index 000000000..c025ca421 --- /dev/null +++ b/docs/docs/guide/backend/install.md @@ -0,0 +1,7 @@ +--- +next: '/guide/backend/config.md' +--- + +# 后端部署 + +参考:[程序部署](../deploy.md) diff --git a/docs/docs/guide/backend/moderator.md b/docs/docs/guide/backend/moderator.md new file mode 100644 index 000000000..3728f5e84 --- /dev/null +++ b/docs/docs/guide/backend/moderator.md @@ -0,0 +1,112 @@ +# 评论审核 + +完整的 `moderator` 配置如下: + +```yaml +# 评论审核 +moderator: + pending_default: false # 发表新评论默认为 “待审状态” + api_fail_block: false # 垃圾检测 API 请求错误仍然拦截 + # akismet.com 反垃圾 + akismet_key: "" + # 腾讯云文本内容安全 (tms) + tencent: # https://cloud.tencent.com/document/product/1124/64508 + enabled: false + secret_id: "" + secret_key: "" + region: "ap-guangzhou" + # 阿里云内容安全 + aliyun: # https://help.aliyun.com/document_detail/28417.html + enabled: false + access_key_id: "" + access_key_secret: "" + region: "cn-shanghai" + # 关键词词库过滤 + keywords: + enabled: false + pending: false # 匹配成功设为待审状态 + files: # 支持多个词库文件 + - "./data/词库_1.txt" + file_sep: "\n" # 词库文件内容分割符 + replac_to: "x" # 替换字符 +``` + +## 默认待审模式 + +开启发表新评论默认为 “待审状态”: + +```yaml +moderator: + pending_default: true +``` + +## Akismet + +[Akismet](https://akismet.com/) 是 WordPress 提供的面向全球范围的老牌垃圾拦截 API,通常对一些英文的垃圾评论十分凑效。Akismet 提供了 Personal 免费版本,适用于个人博客站点。 + +![](/images/akismet/1.png) + +你能在 [Akismet 官网](https://akismet.com/) 轻松地申请 `akismet_key`,并填入配置文件中,即可启用 Akismet 垃圾拦截。 + +![](/images/akismet/2.png) + +```yaml +moderator: + akismet_key: "your_key" +``` + +## 腾讯云文本内容安全 + +可参考:[“腾讯云文档”](https://cloud.tencent.com/document/product/1124/64508) + +开通「文本内容安全」后,在「访问管理」-「API 密钥管理」新增具有权限的 Secret,然后填入配置: + +```yaml +moderator: + tencent: + enabled: true + secret_id: "" + secret_key: "" + region: "ap-guangzhou" +``` + +## 阿里云内容安全 + +可参考:[“阿里云文档”](https://help.aliyun.com/document_detail/28417.html) + +开通「阿里云内容安全」后,阿里云后台创建 Access Key 并填入配置: + +```yaml +moderator: + aliyun: + enabled: true + access_key_id: "" + access_key_secret: "" + region: "cn-shanghai" +``` + +## 关键词词库过滤 + +如果你不想依赖于远程 API,可以在本地配置导入词库文件,让 ArtalkGo 根据词语来检测垃圾评论: + +```yaml +moderator: + keywords: + enabled: true + pending: false # 匹配成功设为待审状态 + files: # 支持多个词库文件 + - "./data/词库_1.txt" + file_sep: "\n" # 词库文件内容分割符 + replac_to: "x" # 替换字符 +``` + +- **pending**:当成功匹配时,是否将评论设为待审核状态。 +- **files**:词库文件。允许多个文件,ArtalkGo 启动时会合并词库。 +- **file_sep**:词库文件内容分割符。例如:文件中每行一个词语,该项配置 `\n`。 +- **replac_to**:替换字符。例如:该项设置为 `x`,你可以将 `pending` 设置为 `false`,评论自动过审,但匹配到的词语会被替换为 `x`,例如 `fxxk`、`xxxx`。 + +注:`replac_to` 不建议使用 `*` 星号,应为它和 Markdown 的加粗语法冲突。 + +## 使用验证码 + +你可以开启 ArtalkGo 的验证码功能,支持图片和滑动验证码,[参考此处](./captcha.md)。 diff --git a/docs/docs/guide/backend/multi-site.md b/docs/docs/guide/backend/multi-site.md new file mode 100644 index 000000000..b515ca31e --- /dev/null +++ b/docs/docs/guide/backend/multi-site.md @@ -0,0 +1,144 @@ +# 管理员 × 多站点 + +ArtalkGo 支持站点隔离,以及为站点分配指定的管理员账户, + +所以,你可以实现两种模式:单人多站点、多人多站点。 + +运用「单人多站点」模式,你能够实现多个站点共用同一个 ArtalkGo 后端程序,集中化管理。 + +运用「多人多站点」模式,你可以和你的朋友们共用同一个 ArtalkGo 后端程序。😉 + +## 管理员配置 + +你可以设置多个管理员账户,当输入框输入匹配管理员用户名和邮箱时,将弹出密码验证提示框, + +并且只有管理员才能访问侧边栏「[控制中心](../frontend/sidebar.md#控制中心)」,在前端对评论内容进行管理操作。 + +在配置文件中添加如下内容: + +```yaml +admin_users: + - name: "admin" + email: "admin@example.com" + password: "" + badge_name: "管理员" + badge_color: "#FF6C00" + - name: "admin2" + email: "admin2@example.com" + password: "" + badge_name: "小管理员" + badge_color: "#FF6C00" +``` + +每一项配置的解释: + +- **name** & **email**:用户名和邮箱,**不区分大小写**。 +- **password**:用户密码。 + + 支持 bcrypt 和 md5 加密,例如填写:`"(md5)50c21190c6e4e5418c6a90d2b5031119"`。 + + **建议使用更安全的 bcrypt 加密算法**,在 Linux 环境下,你可以使用 [htpasswd 命令](https://httpd.apache.org/docs/2.4/programs/htpasswd.html) 来生成密文: + + ```bash + unset HISTFILE # 临时禁用 history 防止密码在历史记录中出现 + htpasswd -bnBC 10 "" "your_password" | tr -d ':' + ``` + + 然后配置填写:`"(bcrypt)$2y$10$ti4vZYIrxVN8rLcY..."`,以 `(bcrypt)` 开头。 + + 命令解释参考:[“Compute bcrypt hash from command line”](https://unix.stackexchange.com/questions/307994/compute-bcrypt-hash-from-command-line#answer-419855) + +- **badge_name**:用户显示的头衔徽标文字。 +- **badge_color**:用户显示的头衔徽标背景颜色。 + +## 站点的创建和管理 + +你可以在侧边栏「[控制中心](../frontend/sidebar.md#控制中心)」创建多个站点,管理站点和快速切换站点,详情可参考:[“侧边栏”](/guide/frontend/sidebar.html)。 + +## 超级管理员、普通管理员 + +管理员分为「超级管理员」和「普通管理员」,前者可以管理全部站点,后者只能管理部分站点。 + +普通管理员将: + + - 不会收到其它站点的评论邮件通知,邮件通知彼此隔离。 + - 不能对设定范围外的站点进行 删除、修改、查询 等操作。 + - 仅能在受限模式下使用 数据导入导出、站点管理 等功能。 + +完整的 `admin_users` 配置如下: + +```yaml +admin_users: + - name: "超级管理员" + email: "super_admin@example.com" + password: "(bcrypt)$2y$10$ti4vZYIrxVN8rLcYXVgXCO.GJND0dyI49r7IoF3xqIx8bBRmIBZRm" + badge_name: "超级管理员" + badge_color: "#FF6C00" + receive_email: false + + - name: "普通管理员1" + email: "admin1@example.com" + password: "(bcrypt)$2y$10$ti4vZYIrxVN8rLcYXVgXCO.GJND0dyI49r7IoF3xqIx8bBRmIBZRm" + badge_name: "管理员" + badge_color: "#FF6C00" + sites: + - 站点名 A + - 站点名 B + + - name: "普通管理员2" + email: "admin2@example.com" + password: "(bcrypt)$2y$10$ti4vZYIrxVN8rLcYXVgXCO.GJND0dyI49r7IoF3xqIx8bBRmIBZRm" + badge_name: "管理员" + badge_color: "#FF6C00" + sites: + - 站点名 C + - 站点名 D +``` + +### 为管理员分配站点 + +- **sites**:向管理员分配站点,即控制管理员对于站点「[控制中心](../frontend/sidebar.md#控制中心)」的可访问权限。 + + 当未分配站点时,即 sites 未配置时,该账户为「**超级管理员**」,可以管理全部站点: + + ```yaml + admin_users: + - name: "super_admin" + # 未分配 sites,为超级管理员 + ``` + + 当分配站点后,即 sites 已配置时,该管理员成为「**普通管理员**」: + + ```yaml + admin_users: + - name: "a_admin_user" + # ↓ 为账户分配 sites + sites: + - 站点名 A + - 站点名 B + ``` + + 注:你至少需要一个超级管理员,这样才能创建站点。 + +### 控制管理员接收邮件通知 + +当页面有新的评论时,邮件会发送给**该站点**的全部管理员,但你可以配置 `receive_email` 强制禁用它。 + +这对于设定了多个邮箱,但又不希望某些邮箱收到评论邮件的情况很有帮助。 + +- **receive_email**:设置为 `false` 系统将不会发送邮件通知给该用户。 + + 注:禁止后该管理员用户仍可以收到来自他人的 @AT 回复,只是当用户对页面进行评论时 (创建根评论时) 不发送邮件通知。 + +```yaml +admin_users: + - name: "super_admin" + # 未分配 sites,即为超级管理员 + receive_email: false # ← 超级管理员不接收邮件 + + - name: "a_admin_user" + # 分配 sites,即为普通管理员 + sites: + - 站点名 A + - 站点名 B +``` diff --git a/docs/docs/guide/backend/notify.md b/docs/docs/guide/backend/notify.md new file mode 100644 index 000000000..1615f7c23 --- /dev/null +++ b/docs/docs/guide/backend/notify.md @@ -0,0 +1,21 @@ +# 多元通知 + +ArtalkGo v2.1.8+ 配置项: + +- `notify` 弃用并变更为 `admin_notify` +- `email.mail_subject_to_admin` 弃用并变更为 `admin_notify.email.mail_subject` + +```yaml +# 管理员多元推送 +admin_notify: + # 通知模版 + notify_tpl: "default" + noise_mode: false + # 邮件通知管理员 + email: + enabled: true # 当使用其他推送方式时,可以关闭管理员邮件通知 + mail_subject: "[{{site_name}}] 您的文章「{{page_title}}」有新回复" +``` + + +请参考新文档:[多元推送](./admin_notify.md) diff --git a/docs/docs/guide/backend/relative-path.md b/docs/docs/guide/backend/relative-path.md new file mode 100644 index 000000000..0612bc961 --- /dev/null +++ b/docs/docs/guide/backend/relative-path.md @@ -0,0 +1,53 @@ +# 相对 / 绝对路径 + +ArtalkGo 支持解析相对路径,因此你可以在前端页面进行如下配置: + +```js +new Artalk({ + site: "举个栗子站点", // 你的站点名 + pageKey: "/relative-path/xx.html", // 使用相对路径 +}) +``` + +建议页面使用相对路径,因为这为日后的「站点迁移」需求创建条件。 + +然后,你需要在侧边栏「[控制中心](../frontend/sidebar.md#控制中心)」-「站点」找到 “举个栗子站点”,修改站点 URL。 + +![](/images/relative-path/1.png) + +之后,所有相对路径都会「基于这个站点 URL」,例如: + +```bash +"/relative-path/xx.html" + ↓ 解析为 +"https://设定的举个栗子站点URL.xxx/relative-path/xx.html" +``` + +### 解析后的 URL 用途 + +站点 URL + 页面 相对路径 将用于: + +- **邮件通知**中的回复评论链接 +- **侧边栏**快速跳转到某条评论 +- **控制中心**页面管理打开页面 +- **获取页面标题**等信息时使用 + +### 配置多个站点 URL 的情况 + +你可能需要配置站点的多个 URL 来允许 Referer 和跨域。 + +「[控制中心](../frontend/sidebar.md#控制中心)」-「站点」修改站点 URL 支持为站点添加多个 URL,用英文逗号 `,` 分隔开每个 URL 即可。 + +**当站点存在多个 URL 时**,「相对路径」会基于多个 URL 中的「**第一个**」URL。 + +### 使用绝对路径的情况 + +区别于使用相对路径,你可以使用绝对路径,例如前端这样配置: + +```js +new Artalk({ + pageKey: "https://your_domain.com/relative-path/xx.html", // 使用绝对路径 +}) +``` + +这时后端不会去解析该地址,邮件、侧边栏等地方都是直接使用 `pageKey` 这个绝对路径来定位页面。 diff --git a/docs/docs/guide/backend/reverse-proxy.md b/docs/docs/guide/backend/reverse-proxy.md new file mode 100644 index 000000000..205ff227f --- /dev/null +++ b/docs/docs/guide/backend/reverse-proxy.md @@ -0,0 +1,111 @@ +# 反向代理 + +## Nginx + +假定: + +- 你想绑定的域名是:`artalk.your_domain.com` +- ArtalkGo 本地地址:`http://localhost:23366` + +以 Ubuntu 20.04 为例: + +创建站点配置文件: + +```bash +sudo vim /etc/nginx/sites-available/artalk.your_domain.com +``` + +编辑反向代理配置文件: + +```nginx +server +{ + listen 80; + listen [::]:80; + + server_name artalk.your_domain.com; + + location / { + proxy_redirect off; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_pass http://localhost:23366/; + } +} +``` + +创建软链接启用站点: + +```bash +sudo ln -s /etc/nginx/sites-available/artalk.your_domain.com /etc/nginx/sites-enabled/ +``` + +验证配置文件是否有效: + +```bash +sudo nginx -t +``` + +配置没有问题,重启 Nginx: + +```bash +sudo systemctl restart nginx +``` + +配置前端: + +```js +new Artalk({ server: "http://artalk.your_domain.com" }) +``` + +::: tip +你还可以再套一层 CDN,然后加上 SSL + +注意配置文件权限,以及反代目标 URL 可访问性 + +尤其是运行在 Docker 容器内的 artalk-go,注意检查 IP 和端口是否能够被 Nginx 正常访问 +::: + +## Caddy + +创建 Caddyfile: + +``` +artalk.your_domain.com { + reverse_proxy / http://localhost:23366 +} +``` + +## Apache + +需要启用反代模块 `mod_proxy.c` + +```apache + + ServerName your_domain.xxx + ServerAlias + + RewriteEngine On + RewriteCond %{QUERY_STRING} transport=polling [NC] + RewriteRule /(.*) http://localhost:23366/$1 [P] + + + ProxyRequests Off + SSLProxyEngine on + ProxyPass / http://localhost:23366/ + ProxyPassReverse / http://localhost:23366/ + + +``` + +## 宝塔面板 + +首先创建一个站点 (例如 `artalk.your_domain.com`),然后点击站点的「设置」: + +![](/images/baota-proxy/1.png) + +打开「反向代理」选项卡,点击「添加反向代理」,「目标 URL」填写 `http://localhost:端口号`(端口号与 ArtalkGo 端口对应),「发送域名」填写 `$host`,如图: + +![](/images/baota-proxy/2.png) + diff --git a/docs/docs/guide/backend/update.md b/docs/docs/guide/backend/update.md new file mode 100644 index 000000000..e48e98ba4 --- /dev/null +++ b/docs/docs/guide/backend/update.md @@ -0,0 +1,27 @@ +# 后端升级 + +## 命令行一键升级 + +执行 `./artalk-go upgrade` + +此操作会从自动从 GitHub Release 下载并升级程序,执行前需关闭 ArtalkGo。 + +:::tip + +执行 `./artalk-go upgrade -f` 携带参数 `-f` 来进行同版本号的补充更新。 + +::: + +## Docker 升级 + +可参考:[“Docker · 升级”](./docker.md#升级) + +## 普通方式 + +前往 [GitHub Release](https://github.com/ArtalkJS/ArtalkGo/releases) 手动下载最新构建 + +替换掉旧版本文件即可。 + +::: tip +升级可能会有配置文件等变动,请注意查看版本 Changelog,通常是在 [GitHub Release](https://github.com/ArtalkJS/ArtalkGo/releases) 页面 +::: diff --git a/docs/docs/guide/cases.md b/docs/docs/guide/cases.md new file mode 100644 index 000000000..f531e670a --- /dev/null +++ b/docs/docs/guide/cases.md @@ -0,0 +1,37 @@ +# 🚀 案例展示 + +### 博客 + +- [一蓑烟雨](https://easyf12.top/) +- [二丫讲梵](https://wiki.eryajf.net) +- [Alliot’s blog](https://www.iots.vip/) +- [小康博客](https://www.antmoe.com/) +- [程序员 Life](https://xuqilong.top) +- [远方的灯塔](https://terwergreen.com) +- [Bowenの破站](https://bowenyoung.cn/) +- [杜老师说](https://dusays.com/) +- [频率](https://pinlyu.com/) +- [子舒](https://zburu.com/) +- [叶开](https://xn--qpru0x.cn/) +- [Thun888](https://blog.thun888.xyz/) +- [青空之蓝](https://blog.ixk.me/) +- [Monstx](https://blog.monsterx.cn/) +- [QWQAQ](https://qwqaq.com/) + +### 主题 + +- [hexo-theme-stellar](https://github.com/xaoxuu/hexo-theme-stellar): Elegant and powerful theme for Hexo. +- [FixIt Theme | Hugo](https://github.com/Lruihao/FixIt): A clean, elegant but advanced blog theme for Hugo +- [hexo-theme-volantis](https://github.com/volantis-x/hexo-theme-volantis): A Wonderful Theme for Hexo +- [hexo-theme-cards](https://github.com/ChrAlpha/hexo-theme-cards): Another Simple & Swift theme for Hexo +- [hexo-theme-butterfly](https://github.com/jerryc127/hexo-theme-butterfly): A Hexo Theme: Butterfly + +::: tip + +此页面案例由团队成员整理... + +如果希望 / 不希望你使用到 Artalk 的项目在此展示,欢迎在下方留言! + +非常感谢你为 Artalk 社区做出的贡献 😘 + +::: diff --git a/docs/docs/guide/deploy.md b/docs/docs/guide/deploy.md new file mode 100644 index 000000000..05d8f80a4 --- /dev/null +++ b/docs/docs/guide/deploy.md @@ -0,0 +1,196 @@ +# 📦 程序部署 + +## Docker 部署 + +推荐使用 Docker 部署,需预先安装 [Docker 引擎](https://docs.docker.com/engine/install/),服务器执行命令创建容器: + +```bash +docker run -d \ + --name artalk-go \ + -p 8080:23366 \ + -v $(pwd)/data:/data \ + artalk/artalk-go +``` + +> 假设域名 `http://your_domain` 已正确添加 DNS 记录并指向你的服务器 IP + +浏览器打开 `http://your_domain:8080` 将出现 Artalk 后台登陆界面。 + +执行命令创建管理员账户: + +```bash +docker exec -it artalk-go artalk admin +``` + +在你的网站引入 Artalk 程序内嵌的的前端 CSS、JS 资源并初始化: + +> 注:将 `http://your_domain:8080` 改为你的服务器域名,或使用 [公共 CDN 资源](#cdn-资源)。 + +```html + + + + + + + +
+ +``` + +在评论框输入管理员的用户名和邮箱,控制台入口按钮将出现在评论框右下角位置。 + +在控制台,你可以根据喜好配置评论系统、[将评论迁移到 Artalk](./transfer.md)。 + +祝贺!你已成功完成 Artalk 部署 🥳 + +## 普通方式部署 + +1. 前往 [GitHub Release](https://github.com/ArtalkJS/ArtalkGo/releases) 下载程序压缩包 +2. 提取压缩包:`tar -zxvf artalk-go_版本号_系统_架构.tar.gz` +3. 运行程序 `./artalk-go server` +4. 前端配置 + + ```js + new Artalk({ server: "http://your_domain:23366" }) + ``` + +**其它可选操作:** + +- [“反向代理端口到 80 / 443 (Nginx, Apache)”](/guide/backend/reverse-proxy.md) +- ["持久化运作 (tmux, systemd, supervisor)"](/guide/backend/daemon.md) + +**附表:文件名释义表** + +|文件名|操作系统|CPU 架构| +|:-|:-:|:-:| +|artalk-go_linux_amd64.tar.gz|Linux|x86_64| +|artalk-go_linux_arm64.tar.gz|Linux|ARM64| +|artalk-go_linux_arm7.tar.gz|Linux|ARMv7| +|artalk-go_windows_amd64.zip|Windows|x86_64| +|artalk-go_darwin_arm64.tar.gz|macOS|Apple Silicon| +|artalk-go_darwin_amd64.tar.gz|macOS|Intel Chip ~~(什么狗屎)~~| + +## Docker Compose 部署 + +提供 docker-compose.yaml 文件可供参考: + +```yaml +version: "3.5" +services: + artalk: + container_name: artalk-go + image: artalk/artalk-go + ports: + - 8080:23366 + volumes: + - ./data:/data +``` + +在与配置文件相同的目录执行命令创建容器: + +```bash +docker-compose up -d +``` + +::: details 一些 Docker Compose 常用命令 + +```bash +docker-compose restart # 重启容器 +docker-compose stop # 暂停容器 +docker-compose down # 删除容器 +docker-compose pull # 更新镜像 +docker-compose exec artalk bash # 进入容器 +``` + +::: + +> 详细可见:[“后端 · Docker”](/guide/backend/docker.md) + +## 自行编译并运行 + +可参考:[“后端构建”](./backend/build.md) + +## CDN 资源 + +::: tip Artalk 最新版本 + +当前 Artalk 前端最新版本号为: :ArtalkVersion: + +若需升级前端,请将 URL 中的版本号数字部分替换即可。 +::: + +Artalk 后端程序内嵌了前端 JS、CSS 文件,使用公共 CDN 资源请注意前后端版本的兼容性。 + +Artalk 静态资源通过上游 [CDNJS](https://cdnjs.com/) 分发,国内有许多镜像可供选择: + +**BootCDN (国内)** + +> https://cdn.bootcdn.net/ajax/libs/artalk/2.4.4/Artalk.js +> +> https://cdn.bootcdn.net/ajax/libs/artalk/2.4.4/Artalk.css + + +**ElemeCDN (国内)** + +> https://npm.elemecdn.com/artalk@2.4.4/dist/Artalk.js +> +> https://npm.elemecdn.com/artalk@2.4.4/dist/Artalk.css + +**CDNJS** + +> https://cdnjs.cloudflare.com/ajax/libs/artalk/2.4.4/Artalk.js +> +> https://cdnjs.cloudflare.com/ajax/libs/artalk/2.4.4/Artalk.css + +**UNPKG** + +> https://unpkg.com/artalk@2.4.4/dist/Artalk.js +> +> https://unpkg.com/artalk@2.4.4/dist/Artalk.css + +**JS DELIVR** + +> https://cdn.jsdelivr.net/npm/artalk@2.4.4/dist/Artalk.js +> +> https://cdn.jsdelivr.net/npm/artalk@2.4.4/dist/Artalk.css + +## ArtalkLite + +可选择精简版 [ArtalkLite](./frontend/artalk-lite.md):体积更小、更简约。 + +## Node 环境 + +```bash +pnpm add artalk +``` + +引入到你的项目: + +```js +import 'artalk/dist/Artalk.css' +import Artalk from 'artalk' + +new Artalk({ + // ... +}) +``` + +## 何时引入、何时 new? + +- 可以在任意位置引入 JS 和 CSS 资源,但需确保 JS 引入在执行 `new Artalk({})` 前。 +- 执行 `new Artalk({ el: '#x' })` 时,需要确保 `
` 存在于页面当中。 + +可参考:[“前端框架引入”](./frontend/import-framework.md) / [“博客引入”](./frontend/import-blog.md) + +## 数据导入 + +从其他评论系统导入数据:[“数据迁移”](./transfer.md) diff --git a/docs/docs/guide/describe.md b/docs/docs/guide/describe.md new file mode 100644 index 000000000..08e257320 --- /dev/null +++ b/docs/docs/guide/describe.md @@ -0,0 +1,42 @@ +# 😴 深入了解 + +::: warning +目前文档仍在陆续完善中 +::: + + +## 控制台(管理后台) + +面向管理员用户,我们提供了 “控制台” 功能,通过控制台,你能对数据内容进行统一管理。 + +### 如何呼出控制台 + +控制台被集成到评论页中,您仅需: +1. 在评论框输入管理员的名字与邮箱 +2. 密码验证框自动弹出,输入正确密码 +3. 控制台按钮将会在评论框右下角显示 + +【图示】 + +## 通知中心 + +通知中心入口按钮将会在用户填入名字和邮箱后显示,它在评论框的右下角,与管理员控制台按钮位置相同。 + +通知中心的评论分为 提及、我的、全部、待审 四类。 + +- 提及:被人 AT 或对你的回复 +- 我的:我发布的评论 +- 全部:我的所有评论及相关评论 +- 待审:我的待审核评论 + +## 邮件发送 + +Artalk 支持以多种方式发送邮件, + +## 审核制度 + +你能够通过设置,开启 评论默认待审,当用户提交评论后,需要管理员审核后才能显示,在此期间仅评论者自己可见。 + +## 反垃圾 + +Artalk 提供多种反垃圾的方法,其具体实现我们称之为 垃圾评论检查器,一旦检测到垃圾评论,检查器会将它标记为 “待审核” 状态。 diff --git a/docs/docs/guide/extras.md b/docs/docs/guide/extras.md new file mode 100644 index 000000000..381fc1fba --- /dev/null +++ b/docs/docs/guide/extras.md @@ -0,0 +1,44 @@ +# 📚 扩展阅读 + +“我们仰望同一片天空,却看着不同的地方。” + +Artalk 离不开社区的支持与帮助,**是你们让 Artalk 走得更远!** + +非常感谢对 Artalk 提供支持与帮助的朋友们!😘 + +## Artalk v2 + +- [Artalk 评论系统推荐 (By @inkss)](https://inkss.cn/blog/8f37d8c3/) +- [Nuxt.js如何部署Artalk和遇到的问题 (By @子舒)](https://imhan.cn/posts/20220218/) +- [宝塔安装过程大概记录 (By @xiamuguizhi)](https://github.com/ArtalkJS/Artalk/discussions/46) + +更多新版读物正在撰写当中( + +## Artalk v1 + +::: warning + +Artalk v1 版本基于 [PHP 后端](https://github.com/ArtalkJS/ArtalkPHP),部分内容可能不适用于 Go 后端,但仍具有参考价值。 + +::: + +- [[!!!] 一个 Artalk 的非官方文档 (By @thun888)](https://blog.thun888.xyz/wiki/Artalk/) +- [为 Gridsome 添加 Artalk 自托管评论系统 - Monstx's Blog](https://blog.monsterx.cn/code/use-self-hosted-comment-system-in-gridsome/) +- [Artalk 自托管评论系统的后端部署 - Jalen's Blog](https://blog.jalenchuh.cn/posts/artalk-api-php/) +- [无服务器搭建 Artalk 评论系统后端 - 陈YFの博客](https://blog.cyfan.top/p/480ab6ed.html) +- [哔哩哔哩 [站内首发] Artalk 评论系统搭建教程 - @thun888](https://www.bilibili.com/s/video/BV1954y1E7uP) +- [Hexo Next 主题添加 Artalk 评论系统 - 心底的河流](https://lhy.life/20201126-artalk-next/) +- [Hexo 添加 Artalk 评论教程 - 我相信我可以](https://butterfly.imlete.cn/article/Hexo-Artalk.html) +- [基于 Butterfly 主题添加 Artalk 评论系统 - 卓越科技的 Blog](https://blog.imzykj.cn/posts/93afb348/) + +## 衍生品 + +- [Artalk:一款 ~~简洁~~ 有趣的自托管评论系统 (By monsterxcn)](https://github.com/monsterxcn/Artalk) + +## 终于更新了! + +在 Artalk v1 向 v2 的跨越期间,我经历了高考,这真是一段超级漫长的时间呢。 + +高考后,时间变得相对充裕,Artalk 后端采用 Golang 完成了重置,同时 Artalk 的功能也在不断完善当中。 🥳 + +

@qwqcode

diff --git a/docs/docs/guide/frontend/artalk-lite.md b/docs/docs/guide/frontend/artalk-lite.md new file mode 100644 index 000000000..468603e73 --- /dev/null +++ b/docs/docs/guide/frontend/artalk-lite.md @@ -0,0 +1,13 @@ +# 精简版本 + +ArtalkLite 是 Artalk 的精简版本,相较于普通版,有以下区别: + +- 体积更小,更为简约 +- 默认关闭表情包、投票、UA 徽标 +- 去除 marked 依赖,但支持一些基本的 Markdown 语法 + +ArtalkLite 随普通版一起发布,你可以将 CDN 地址文件名修改为 ArtalkLite 获取: + +> https://unpkg.com/artalk@2/dist/ArtalkLite.js +> +> https://unpkg.com/artalk@2/dist/ArtalkLite.css diff --git a/docs/docs/guide/frontend/config.md b/docs/docs/guide/frontend/config.md new file mode 100644 index 000000000..3df459e85 --- /dev/null +++ b/docs/docs/guide/frontend/config.md @@ -0,0 +1,451 @@ +# 前端配置 + +::: tip +前端配置可以在侧边栏 “[控制中心](/guide/frontend/sidebar.md)” 直接修改,无需手动修改配置 +::: + +```js +new Artalk({ 你的配置... }) +``` + +- 默认配置:[defaults.ts](https://github.com/ArtalkJS/Artalk/blob/master/packages/artalk/src/defaults.ts) +- 声明文件:[artalk-config.d.ts](https://github.com/ArtalkJS/Artalk/blob/master/packages/artalk/types/artalk-config.d.ts) + +## 基本配置(必填项) + +### el + +**装载元素**(填入需要绑定的元素 Selector) + +- 类型:`String|HTMLElement` +- 默认值:`undefined` + +> 例如:`#Comments` 对应元素 `
` + +### pageKey + +**页面地址**(相对路径 / 完整 URL) + +- 类型:`String` +- 默认值:`location.pathname` + +可留空自动获取页面的相对路径。 + +可以填写由博客系统生成的 `固定链接`,但建议使用相对路径以便日后切换域名。 + +参考:[“关于使用相对 / 绝对路径”](/guide/backend/relative-path.md) + +### pageTitle + +**页面标题**(用于管理列表显示,邮件通知等) + +- 类型:`String` +- 默认值:`document.title` + +可留空自动获取页面的 `` 标签值。 + +### server + +**后端程序 API 地址** + +- 类型:`String` +- 默认值:`undefined` + +部署后端,确保后端地址前端可访问 + +> 例如:http://yourdomain.xxx + +::: warning 更新注意 + +v2.2.6+ 的后续版本,请填入不带 `/api/` 路径的后端 URL。 + +::: + +### site + +**站点名称** + +- 类型:`String` +- 默认值:`undefined` + +可留空使用后端配置的 “默认站点”, + +Artalk 支持多站点统一管理,此项用于站点隔离。 + +### useBackendConf + +**跟随后端的配置** + +- 类型:`Boolean` +- 默认值:`true`(默认启用) + +可以在后端的配置文件中定义前端的配置,让前端配置始终跟随后端。 + +详情可参考:[“在后端控制前端”](/guide/backend/fe-control) + +## 国际化 (i18n) + +### locale + +**语言** + +- 类型:`String|Object|"auto"` +- 默认值:`"zh-CN"` + +遵循 Unicode BCP 47 规范,该项默认为 "zh-CN" (简体中文)。 + +目前 Artalk 内置 "zh-CN" (简体中文) 和 "en-US" (English)。 + +你可以贡献其他语言,欢迎提交 PR:[@artalk/src/i18n/index.ts](https://github.com/ArtalkJS/Artalk/blob/master/packages/artalk/src/i18n/index.ts) + +可传入 Object 类型,按照 [@artalk/src/i18n/zh-CN.ts](https://github.com/ArtalkJS/Artalk/blob/master/packages/artalk/src/i18n/zh-CN.ts) 文件中对象的 Keys 编写自定义 locale 内容。 + +详情参考:[多语言](./i18n.html) + +## 请求 + +### reqTimeout + +**请求超时** + +- 类型:`Number` +- 默认值:`15000` + +当请求时间大于该值,自动断开请求并报错。(单位:毫秒) + +## 表情包 + +### emoticons + +**表情包** + +- 类型:`Object|Array|String|Boolean` +- 默认值:"[https://cdn.jsdelivr.net/gh/ArtalkJS/Emoticons/grps/default.json](https://cdn.jsdelivr.net/gh/ArtalkJS/Emoticons/grps/default.json)" + +详细内容:[“前端 · 表情包”](/guide/frontend/emoticons.md) + +更新兼容 [OwO 格式](https://github.com/DIYgod/OwO),支持 URL 动态加载。 + +设置为 `false` 关闭表情包功能。 + +:::warning 请替换 CDN 资源 +很遗憾,JS DELIVR [在中国大陆的 ICP 牌照被吊销](https://github.com/jsdelivr/jsdelivr/issues/18348#issuecomment-997777996),感谢 JS DELIVR 对社区的贡献 :heart:。 +::: + +## 界面 + +### placeholder + +**评论框占位字符** + +- 类型:`String` +- 默认值:`"键入内容..."` + +### noComment + +**评论为空时显示字符** + +- 类型:`String` +- 默认值:`"「此时无声胜有声」"` + +### sendBtn + +**发送按钮文字** + +- 类型:`String` +- 默认值:`"发送评论"` + +### editorTravel + +**评论框旅行** + +- 类型:`Boolean` +- 默认值:`true` + +设置为 `true` 当回复评论时,评论框移动到待回复评论位置之后,而不是固定不动。 + +### darkMode + +**暗黑模式** + +- 类型:`Boolean|"auto"` +- 默认值:`false` + +当 Artalk 被 new 时会读取该值,并根据该值选择是否开启暗黑模式(可与博客主题配合使用)。 + +代码动态修改 darkMode: + +```js +artalkInstance.setDarkMode(true) +``` + +> 参考代码:“[index.html](https://github.com/ArtalkJS/Artalk/blob/master/packages/artalk/index.html#L97-L150)” + +可设置为 `"auto"`,Artalk 将监听 `(prefers-color-scheme: dark)` 根据用户操作系统判断自动切换暗黑模式。 + +### flatMode + +**平铺模式** + +- 类型:`Boolean|"auto"` +- 默认值:`"auto"` + +默认 `"auto"` 仅小尺寸屏幕设备自动开启「平铺」模式 (屏幕宽度 < 768px 时) + +设置 `true` 评论以「平铺模式」形式显示 + +设置 `false` 评论以「层级嵌套」形式显示 + +### nestMax + +**最大嵌套层数** + +- 类型:`Number` +- 默认值:`2` + +评论「层级嵌套」模式的最大嵌套层数。 + +### nestSort + +**嵌套评论的排序规则** + +- 类型:`"DATE_ASC"|"DATE_DESC"|"VOTE_UP_DESC"` +- 默认值:`"DATE_ASC"` + +嵌套评论的子评论默认以「日期升序 (新评的论在末尾)」排列。 + +## 功能 + +### pvEl + +**页面浏览量 (PV) 绑定元素** + +- 类型:`String` +- 默认值:`"#ArtalkPV"` + +你可以在页面任意位置,放置 HTML 标签:`<span id="ArtalkPV"></span>` + +当 Artalk 完成加载时展示页面的浏览量。 + +该项填入绑定元素的 Selector,默认为 `#ArtalkPV`。 + +### countEl + +**评论数绑定元素** + +- 类型:`String` +- 默认值:`"#ArtalkCount"` + +你可以在页面任意位置,放置 HTML 标签:`<span id="ArtalkCount"></span>` 显示当前页面的评论数。 + +::: tip + +pvEl 和 countEl 元素标签都可以设置 `data-page-key` 属性值,来指定显示某个页面的统计数目,例如:`<span id="ArtalkCount" data-page-key="/t/1.html"></span>` + +详情参考:[浏览量统计](./pv.md#显示多个页面的浏览量) + +::: + +### vote + +**投票按钮** + +- 类型:`Boolean` +- 默认值:`true` + +启用评论投票功能 (赞同 / 反对)。 + +### voteDown + +**反对按钮** + +- 类型:`Boolean` +- 默认值:`false` + +反对的投票按钮(默认隐藏)。 + +### uaBadge + +**显示用户的 UserAgent 信息徽标** + +- 类型:`Boolean` +- 默认值:`true` + +### listSort + +**评论排序功能** + +- 类型:`Boolean` +- 默认值:`true` + +鼠标移到评论列表左上角「n 条评论」的位置,显示悬浮下拉层,可以让评论列表按照「最新 / 最热 / 最早 / 作者」等规则排序筛选显示。 + +### imgUpload + +**图片上传功能** + +- 类型:`Boolean` +- 默认值:`true` + +该配置项自动跟随后端,当后端图片上传功能关闭时,仅管理员会显示图片上传按钮。 + +### imgUploader + +**图片上传器** + +- 类型:`(file: File) => Promise<string>` +- 默认值:`undefined` + +自定义图片上传器,例如: + +```js +new Artalk({ + imgUploader: async (file) => { + const form = new FormData() + form.set('file', file) + + const imgUrl = await fetch("https://api.example.org/upload", { + method: 'POST', + body: form + }) + + return imgUrl + } +}) +``` + +### preview + +**编辑器实时预览功能** + +- 类型:`Boolean` +- 默认值:`true` + +显示编辑器的「预览」按钮。 + +## 头像 + +```js +gravatar: { + mirror: '<Gravatar 镜像地址>', + default: 'mp', +} +``` + +### gravatar.mirror + +**Gravatar 镜像地址** + +- 类型:`String` +- 默认值:`"https://sdn.geekzu.org/avatar/"` + +如果你觉得 Gravatar 头像加载速度不理想,可以尝试替换。 + +例如: + +> Cravatar:https://cravatar.cn/avatar/ +> +> V2EX:https://cdn.v2ex.com/gravatar/ +> +> 极客族:https://sdn.geekzu.org/avatar/ +> +> loli:https://gravatar.loli.net/avatar/ + +### gravatar.default + +**默认头像**(URL or [Gravatar Type](http://cn.gravatar.org/site/implement/images/#default-image)) + +- 类型:`String` +- 默认值:`"mp"` + +### avatarURLBuilder + +**头像链接生成器** + +- 类型:`(comment: CommentData) => string` +- 默认值:`undefined` + +自定义用户头像图片链接生成,例如: + +```js +new Artalk({ + avatarURLBuilder: (comment) => { + return `/api/avatar?email=${comment.email_encrypted}` + } +}) +``` + +## 评论分页 + +```js +pagination: { + pageSize: 20, // 每页评论数 + readMore: true, // 加载更多 or 分页条 + autoLoad: true, // 自动加载 (加载更多) +} +``` + +### pagination.readMore + +**加载更多模式** + +- 类型:`Boolean` +- 默认值:`true` + +设置 `true` 为 “**加载更多**” 模式 + +设置 `false` 为 “**分页条**” 模式 + +### pagination.autoLoad + +**滚动到底部自动加载** + +- 类型:`Boolean` +- 默认值:`true` + +(需同时开启“加载更多”模式,将 `readMore` 设置为 `true`) + +### pagination.pageSize + +**每次请求获取数量** + +- 类型:`Number` +- 默认值:`20` + +## 内容限高 + +超过设定高度的内容将被隐藏,并显示“阅读更多”按钮。 + +```js +heightLimit: { + content: 300, // 评论内容限高 + children: 400, // 子评论区域限高 +} +``` + +### heightLimit.content + +**评论内容限高** + +- 类型:`Number` +- 默认值:`300` + +> 当值为 0 时,关闭限高 + +### heightLimit.children + +**子评论区域限高** + +- 类型:`Number` +- 默认值:`400` + +## 版本检测 + +### versionCheck + +**版本检测** + +- 类型:`Boolean` +- 默认:`true` + +当前端和后端版本不兼容时,显示警告提示框。 diff --git a/docs/docs/guide/frontend/emoticons.md b/docs/docs/guide/frontend/emoticons.md new file mode 100644 index 000000000..d89754958 --- /dev/null +++ b/docs/docs/guide/frontend/emoticons.md @@ -0,0 +1,155 @@ +# 表情包 + +你可以在前端配置表情包列表,例如: + +```js +new Artalk({ + // 默认表情包列表,动态引入 ↓↓ + emoticons: "https://raw.githubusercontent.com/ArtalkJS/Emoticons/master/grps/default.json", +}) +``` + +## 表情包预设 + +Artalk 社区提供许多表情包预设,你能够挑选几套喜欢的表情包,仅需简单的配置,轻松添加到你的评论系统中,前往仓库:[“@ArtalkJS/Emoticons”](https://github.com/ArtalkJS/Emoticons)。 + +## 格式支持 + +### Artalk 标准格式 + +```js +[{ + "name": "颜表情", + "type": "emoticon", // 字符类型 + "items": [ + { "key": "Hi", "val": "|´・ω・)ノ" }, + { "key": "开心", "val": "ヾ(≧∇≦*)ゝ" }, + //... + ] +}, { + "name": "滑稽", + "type": "image", // 图片类型 + "items": [ + { + "key": "原味稽", + "val": "<图片 URL>" + }, + //... + ] +}] +``` + + +### OwO 格式 + +[OwO](https://github.com/DIYgod/OwO) 是作者 [@DIYgod](https://github.com/DIYgod) 开发的 JS 插件,能让输入框快速拥有插入表情符号的功能。 + +Artalk 的表情包功能灵感也源于此,并且 Artalk 适配和兼容 OwO 格式的表情包数据文件,示例如下: + +```js +new Artalk({ + emoticons: "https://raw.githubusercontent.com/DIYgod/OwO/master/demo/OwO.json", + // 直接食用 OwO 格式的表情包 ↑↑ +}) +``` + +社区也有许多可以直接食用的 OwO 格式表情包资源,例如:[@2X-ercha/Twikoo-Magic](https://github.com/2X-ercha/Twikoo-Magic)。 + +## 装载方式 + +### 动态引入 + +将 `emoticons` 属性设置为表情包数据文件的 URL,当打开表情包列表时,Artalk 会动态引入。 + +```js +new Artalk({ + emoticons: "<表情包数据文件 URL>", +}) +``` + +远程的表情包文件支持 Artalk、OwO 格式,且支持嵌套、混合装载。 + +### 静态装载 + +相较于动态引入,可以将表情包列表对象,作为 Artalk 配置,静态保存在页面的 JS 代码中,避免动态加载: + +```js +new Artalk({ + emoticons: [{ + "name": "颜表情", + "type": "emoticon", // 字符类型 + "items": [ + { "key": "Hi", "val": "|´・ω・)ノ" }, + { "key": "开心", "val": "ヾ(≧∇≦*)ゝ" }, + //... + ] + }, { + "name": "滑稽", + "type": "image", // 图片类型 + "items": [ + { + "key": "原味稽", + "val": "<图片 URL>" + }, + //... + ] + }], +}) +``` + +### 混合装载 + +Artalk 支持 **动态**、**静态** 混合装载,例如: + +```js +new Artalk({ + emoticons: [ + // 动态装载 + "https://raw.githubusercontent.com/DIYgod/OwO/master/demo/OwO.json", // OwO 格式表情包 + "https://raw.githubusercontent.com/qwqcode/huaji/master/huaji.json", + // 静态装载 + { + "name": "表情包名字", + "type": "emoticon", // 字符类型 + "items": [ + { "key": "去吧大师球", "val": "(╯°A°)╯︵○○○" }, + //... + ] + } + ] +}) +``` + +### 嵌套装载 + +Artalk 支持远程表情包资源中**嵌套引入**另外的表情包资源,例如: + +```js +new Artalk({ + emoticons: [ + "https://example.org/表情包.json" + ] +}) +``` + +文件 `表情包.json` 中的数据: + +```json +[ + "https://example.org/其他表情包.json", + //... + { // Artalk 格式、OwO 格式 + //... + } +] +``` + +### 关闭表情包功能 + +你可以将 `emoticons` 设置为 `false` 来禁用表情包功能: + +```js +new Artalk({ + emoticons: false +}) +``` diff --git a/docs/docs/guide/frontend/i18n.md b/docs/docs/guide/frontend/i18n.md new file mode 100644 index 000000000..ddbfd5c27 --- /dev/null +++ b/docs/docs/guide/frontend/i18n.md @@ -0,0 +1,38 @@ +# 多语言 + +你可以配置 `locale` 修改 Artalk 的语言: + +```js +new Artalk({ + locale: 'en-US' +}) +``` + +locale 配置项格式遵循 Unicode BCP 47 规范,默认为 "zh-CN" (简体中文)。 + +目前 Artalk 内置 "zh-CN" (简体中文) 和 "en-US" (English)。 + +你可以贡献其他语言,欢迎提交 PR:[@artalk/src/i18n/index.ts](https://github.com/ArtalkJS/Artalk/blob/master/packages/artalk/src/i18n/index.ts) + +### 自动切换 + +可将 locale 配置为 `"auto"`,根据用户浏览器自动切换语言,当语言不存在时,将被设置为 "en-US"。 + +```js +new Artalk({ + locale: "auto" +}) +``` + +### 自定义 locale 内容 + +可传入 Object 类型,按照 [@artalk/src/i18n/zh-CN.ts](https://github.com/ArtalkJS/Artalk/blob/master/packages/artalk/src/i18n/zh-CN.ts) 文件中对象的 Keys 编写自定义 locale 内容。 + +```js +new Artalk({ + locale: { + placeholder: 'こんにちは', + //... + } +}) +``` diff --git a/docs/docs/guide/frontend/import-blog.md b/docs/docs/guide/frontend/import-blog.md new file mode 100644 index 000000000..124336889 --- /dev/null +++ b/docs/docs/guide/frontend/import-blog.md @@ -0,0 +1,200 @@ +# 置入博客 + +## 通用方法 + +<<< @/code/quick-start/cdn.html + +## Hugo + +创建模板文件 `/主题目录/layouts/partials/comment/artalk.html`: + +```html +<link href="/lib/artalk/Artalk.css" rel="stylesheet"> +<script src="/lib/artalk/Artalk.js"></script> + +<!-- Artalk --> +<div id="Comments"></div> + +<script> + new Artalk({ + el: '#Comments', + pageKey: '{{ .Permalink }}', + pageTitle: '{{ .Title }}', + server: '{{ $.Site.Params.artalk.server }}', + site: '{{ $.Site.Params.artalk.site }}', + // ...你的其他配置 + }) +</script> +``` + +文章页模板 `/主题目录/layouts/_default/single.html` 合适的位置添加: + +```html +<div class="article-comments"> + {{- partial "comment/artalk" . -}} +</div> +``` + +配置 `/config.yaml` 文件: + +```yaml +params: + artalk: + server: 'https://artalk.example.org' + site: '你的站点名' +``` + +## Hexo + +创建 `/主题目录/layout/comment/artalk.ejs`: + +```html +<link href="/lib/artalk/Artalk.css" rel="stylesheet"> +<script src="/lib/artalk/Artalk.js"></script> + +<div id="Comments"></div> + +<script> + var artalk = new Artalk({ + el: '#Comments', + pageKey: '<%= page.permalink %>', + pageTitle: '<%= page.title %>', + server: '<%= theme.comment.artalk.server %>' + site: '<%= theme.comment.artalk.site %>', + }) +</script> +``` + +修改文章模板文件,例如 `/主题目录/layout/post.ejs`: + +```html +<div class="article-comments"> + <%- partial('comment/artalk') %> +</div> +``` + +编辑主题配置 `/主题目录/_config.example.yml`: + +```yaml +comment: + artalk: + site: '你的站点名' + server: 'https://artalk.example.org' +``` + +::: tip + +NexT 主题可以安装 [Hexo NexT 主题的 Artalk 插件](https://github.com/leirock/hexo-next-artalk) + +::: + + +## VuePress + +以 [VuePress v2](https://github.com/vuepress/vuepress-next) 为例,继承默认主题 `@vuepress/theme-default` + +可参考:[“/.vuepress/theme/Artalk.vue”](https://github.com/ArtalkJS/Docs/blob/eef37bca8cc0c9973bf121fdef4014dcd940f104/docs/.vuepress/theme/Artalk.vue) 创建 Artalk 评论组件。 + +在 `/.vuepress/theme/clientAppEnhance.ts` 文件中全局注册组件: + +```ts +import { defineClientAppEnhance } from '@vuepress/client' + +import Artalk from './Artalk.vue' + +export default defineClientAppEnhance(({ app, router, siteData }) => { + app.component('Artalk', Artalk) +}) +``` + +主题布局 `/.vuepress/theme/Layout.vue`: + +```vue +<template> + <Layout> + <template #page-bottom> + <div class="page-meta"> + <!-- Artalk --> + <Artalk /> + </div> + </template> + </Layout> +</template> + +<script lang="ts"> +import { defineComponent, nextTick } from 'vue' +import { useRouter } from 'vue-router' +import Layout from '@vuepress/theme-default/lib/client/layouts/Layout.vue' + +export default defineComponent({ + components: { Layout }, + mounted: () => { + } +}) +</script> +``` + +主题配置文件 `/.vuepress/theme/index.ts`: + +```ts +import { path } from '@vuepress/utils' + +export default ({ + name: 'vuepress-theme-local', + extends: '@vuepress/theme-default', + layouts: { + Layout: path.resolve(__dirname, 'Layout.vue'), + }, + clientAppEnhanceFiles: path.resolve(__dirname, 'clientAppEnhance.ts'), +}) +``` + +## Typecho + +修改主题文章模板文件,例如 `post.php`: + +```php +<!-- CSS --> +<link href="/lib/artalk/Artalk.css" rel="stylesheet"> + +<!-- JS --> +<script src="/lib/artalk/Artalk.js"></script> + +<!-- Artalk --> +<div id="Comments"></div> +<script> + new Artalk({ + el: '#Comments', + pageKey: '<?php $this->permalink() ?>', + pageTitle: '<?php $this->title() ?>', + server: '<后端地址>', + site: '<?php $this->options->title() ?>', + // ...你的其他配置 + }) +</script> +``` + +## WordPress + +修改主题文章模板文件,例如 `single.php`: + +```php +<!-- CSS --> +<link href="/lib/artalk/Artalk.css" rel="stylesheet"> + +<!-- JS --> +<script src="/lib/artalk/Artalk.js"></script> + +<!-- Artalk --> +<div id="Comments"></div> +<script> + new Artalk({ + el: '#Comments', + pageKey: '<?= addslashes(get_permalink()) ?>', + pageTitle: '<?= addslashes(get_the_title()) ?>', + server: '<后端地址>', + site: '<?= addslashes(get_bloginfo('name')) ?>', + // ...你的其他配置 + }) +</script> +``` diff --git a/docs/docs/guide/frontend/import-framework.md b/docs/docs/guide/frontend/import-framework.md new file mode 100644 index 000000000..a0e06a22c --- /dev/null +++ b/docs/docs/guide/frontend/import-framework.md @@ -0,0 +1,99 @@ +# 置入框架 + +## 引入 Artalk + +通过包管理工具引入 Artalk,推荐使用 [pnpm](https://pnpm.io/zh/) + +```bash +pnpm add artalk +``` + +## Vue + +Vue 3 + TypeScript 例: + +```vue +<template> + <div class="artalk-comments"></div> +</template> + +<script lang="ts"> +import 'artalk/dist/Artalk.css' + +import { defineComponent } from 'vue' +import Artalk from 'artalk' + +export default defineComponent({ + mounted: () => { + const artalk = new Artalk({ + el: this.$el, + pageKey: `${location.pathname}`, + pageTitle: `${document.title}`, + server: 'http://localhost:8080', + site: 'Artalk 的博客', + // ... + }) + } +}) +</script> +``` + +::: tip 提示 + +VuePress 可参考:[“VuePress 引入”](./import-blog.md#vuepress) + +::: + +## React + +```jsx +import 'artalk/dist/Artalk.css' + +import React, { createRef } from 'react' +import Artalk from 'artalk' + +export default class Artalk extends React.Component { + el = createRef() + + componentDidMount () { + const artalk = new Artalk({ + el: this.el.current, + pageKey: `${location.pathname}`, + pageTitle: `${document.title}`, + server: 'http://localhost:8080', + site: 'Artalk 的博客', + // ... + }) + } + + render () { + return ( + <div ref={this.el} class="artalk-comments" /> + ) + } +} +``` + +## Svelte + +```html +<script> +import 'artalk/dist/Artalk.css' +import Artalk from 'artalk' + +let comments; + +onMount(() => { + new Artalk({ + el: comments, + pageKey: `${location.pathname}`, + pageTitle: `${document.title}`, + server: 'http://localhost:8080', + site: 'Artalk 的博客', + // ... + }) +}) +</script> + +<div bind:this={comments} class="artalk-comments"></div> +``` diff --git a/docs/docs/guide/frontend/index.md b/docs/docs/guide/frontend/index.md new file mode 100644 index 000000000..7806962de --- /dev/null +++ b/docs/docs/guide/frontend/index.md @@ -0,0 +1,34 @@ +--- +prev: install.md +next: config.md +--- + +# ArtalkJS + +Artalk 拥有一个前端,[GitHub 代码仓库](https://github.com/ArtalkJS/Artalk)。 + +## 特性 + +可见:[“README.md · 特性”](https://github.com/ArtalkJS/Artalk#%E7%89%B9%E6%80%A7) + +## 句话概括 + +- 轻量级 (~30kB) +- 易上手 (防秃顶) +- TypeScript & Vanilla (纯天然无添加 / 无依赖) + +<!-- ## 长篇大论 + +Artalk 的前端是重磅戏,它采用 TypeScript + Vite 编写,原生纯净无添加,不依赖于任何前端框架。 + +它体小精悍,得益于我们使用原生 DOM 操作,Artalk 的文件体积十分小巧,功能却非常完整。 + +您可以随意将 Artalk 置入任何位置,与 Vue, React, Svelte 项目紧密友好地结合。 + +开发时,我们考虑到 Artalk 的业务拓展能力,留有许多向外部暴露的 hooks,有助于完成你的预期需求。 + +它同时编译成几个版本,例如 UMD 版能够兼顾多种前端环境下运行。 + +CSS 方面,我们采用 Shadow DOM 特性对样式进行隔离处理,不污染页面样式且不被污染。 + +Vite 这样的下一代开发工具,为开发者创造了一个良好的编程体验,编译和热加载速度飞起。 --> diff --git a/docs/docs/guide/frontend/install.md b/docs/docs/guide/frontend/install.md new file mode 100644 index 000000000..3fbb81e90 --- /dev/null +++ b/docs/docs/guide/frontend/install.md @@ -0,0 +1,8 @@ +--- +prev: '../backend/install.md' +next: 'config.md' +--- + +# 前端部署 + +参考:[程序部署](../deploy.md) diff --git a/docs/docs/guide/frontend/latex.md b/docs/docs/guide/frontend/latex.md new file mode 100644 index 000000000..fff84dc42 --- /dev/null +++ b/docs/docs/guide/frontend/latex.md @@ -0,0 +1,27 @@ +# Latex + +对于学术性站点,支持 Latex 是一个刚需,可以使用 [Katex](https://katex.org/) 这款被前端广泛使用的 Latex 语法解析器。Artalk 为保证简洁性,并未内置 Latex 语法解析功能,但你可以在页面中引入 Latex 和 Artalk Katex 插件,让评论系统获得 Latex 语法支持。 + +```html +<!-- 1. 引入 Katex --> +<link rel="stylesheet" href="https://unpkg.com/katex@0.15.3/dist/katex.min.css"> +<script defer src="https://unpkg.com/katex@0.15.3/dist/katex.min.js"></script> + +<!-- 2. 引入 Artalk --> +<link href="/lib/artalk/Artalk.css" rel="stylesheet"> +<script src="/lib/artalk/Artalk.js"></script> + +<!-- 3. 引入 Artalk Katex 插件 --> +<script src="https://unpkg.com/@artalk/plugin-katex/dist/artalk-plugin-katex.js"></script> +``` + +之后,你可以回复: + +``` +$$ P(A) = \sum P(\{ (e_1,...,e_N) \}) = {{N}\choose{k}} \cdot p^kq^{N-k} $$ +``` + +查看效果: + +![](/images/latex-support/1.png) + diff --git a/docs/docs/guide/frontend/lightbox.md b/docs/docs/guide/frontend/lightbox.md new file mode 100644 index 000000000..ac2b4246e --- /dev/null +++ b/docs/docs/guide/frontend/lightbox.md @@ -0,0 +1,55 @@ +# 图片灯箱 + +Artalk LightBox 插件能帮助你将网站**现有的图片灯箱**功能自动集成到 Artalk 中。 + +```html +<!-- 1. 引入图片灯箱依赖,例如 LightGallery (通常博客主题已提供,无需再引入) --> +<script src="lightgallery.js"></script> + +<!-- 2. 引入 Artalk --> +<link href="/lib/artalk/Artalk.css" rel="stylesheet"> +<script src="/lib/artalk/Artalk.js"></script> + +<!-- 3. 引入 Artalk LightBox 插件 --> +<script src="https://unpkg.com/@artalk/plugin-lightbox/dist/artalk-plugin-lightbox.js"></script> +``` + +如上所示,额外引入一个 `artalk-plugin-lightbox.js` 文件即可。 + +目前自动集成支持:[LightGallery](https://github.com/sachinchoolur/lightGallery) [v2.5.0] / [FancyBox](https://github.com/fancyapps/fancybox) [v4.0.27] / [lightbox2](https://github.com/lokesh/lightbox2) [v2.11.3] + +对于还未适配的图片灯箱,欢迎提交 PR -> [查看代码](https://github.com/ArtalkJS/Artalk/blob/master/packages/plugin-lightbox/main.ts) + +::: details 附:图片灯箱依赖 CDN 资源 + +注:通常一个博客主题本来就是有图片灯箱插件的,所以无需重复引入。 + +#### LightGallery + + ```html + <link rel="stylesheet" href="https://unpkg.com/lightgallery@2.5.0/css/lightgallery.css"> + <script src="https://unpkg.com/lightgallery@2.5.0/lightgallery.min.js"></script> + ``` + +#### FancyBox + + ```html + <link rel="stylesheet" href="https://unpkg.com/@fancyapps/ui@4.0.27/dist/fancybox.css"> + <script src="https://unpkg.com/@fancyapps/ui@4.0.27/dist/fancybox.umd.js"></script> + ``` + +::: + +### 配置灯箱 + +在引入 `artalk-plugin-lightbox.js` 之前对全局变量 `ATK_LIGHTBOX_CONF` 进行设置,如下: + +```html +<script> +window.ATK_LIGHTBOX_CONF = { + groupAll: true, + // ...其他配置 +} +</script> +<script src="artalk-plugin-lightbox.js"></script> +``` diff --git a/docs/docs/guide/frontend/plugs.md b/docs/docs/guide/frontend/plugs.md new file mode 100644 index 000000000..5167a0016 --- /dev/null +++ b/docs/docs/guide/frontend/plugs.md @@ -0,0 +1,17 @@ +# 插件 + +::: warning +目前文档仍在陆续完善中... +::: + +你可以通过 `Artalk.use` 来装载 Artalk 插件。 + +```js +Artalk.use((ctx) => { + ctx.editor.setContent("Hello World") +}) +``` + +## Context + +参考:[@artalk/types/context.d.ts](https://github.com/ArtalkJS/Artalk/blob/master/packages/artalk/types/context.d.ts) diff --git a/docs/docs/guide/frontend/pv.md b/docs/docs/guide/frontend/pv.md new file mode 100644 index 000000000..49d9e5b95 --- /dev/null +++ b/docs/docs/guide/frontend/pv.md @@ -0,0 +1,48 @@ +# 浏览量统计 + +Artalk 内置页面浏览量统计功能,你可以在你的页面任意位置,放置 HTML 标签: + +```html +<span id="ArtalkPV"></span> +``` + +当 Artalk 加载完毕时,该标签内容将修改为页面的浏览量计数。 + +Artalk 加载需要时间,所以你可以给它一个占位字符: + +```html +<span id="ArtalkPV">加载中...</span> +``` + +你也可以绑定使用其他的元素,修改 Artalk 配置项,例如: + +```js +new Artalk({ + pvEl: '.your_element', +}) +``` + +### 显示多个页面的浏览量 + +你能在除评论页面之外的任何页面,例如「文章列表」页,显示页面浏览量或评论数: + +```js +Artalk.LoadCountWidget({ + server: '服务器地址', + site: '站点名', + pvEl: '#ArtalkPV', + countEl: '#ArtalkCount', +}); +``` + +在非评论页时,就无需再 new Artalk 实例了 (否则页面浏览量 PV 数会无故增加),仅调用 `LoadCountWidget` 静态方法即可。 + +然后你可以放置多个 `#ArtalkPV` 元素,通过属性 `data-page-key` 来指定需要查询的页面: + +```html +<span id="ArtalkPV" data-page-key="/test/1.html"></span> +<span id="ArtalkPV" data-page-key="/test/2.html"></span> +<span id="ArtalkPV" data-page-key="/test/3.html"></span> +<span id="ArtalkCount" data-page-key="/test/1.html"></span> +<!-- ... --> +``` diff --git a/docs/docs/guide/frontend/sidebar.md b/docs/docs/guide/frontend/sidebar.md new file mode 100644 index 000000000..08c172155 --- /dev/null +++ b/docs/docs/guide/frontend/sidebar.md @@ -0,0 +1,39 @@ +# 侧边栏 + +侧边栏同时充当 **通知中心** + **控制中心** 的功能,当用户**填写评论框的“昵称”和“邮箱”后**,侧边栏入口按钮能在**评论框右下角**找到。 + +<img src="/images/sidebar/1.png" width="650"> + +## 通知中心 + +普通用户打开侧边栏能查看与自己相关的评论,评论被分类为:提及、全部、我的、待审。 + +你能快速地找到评论,跳转到评论对应的页面。 + +<img src="/images/sidebar/2.png" width="430"> + +当用户收到消息时,会显示红点标记,站内消息功能属于是。 + +即便是不打开邮件通知,也能收到来自对方的回复。 + +<img src="/images/sidebar/3.png" width="350"> + +同时,你能在侧边栏快速回复对方的消息,无需前往评论页面。 + +<img src="/images/sidebar/4.png" width="400"> + +## 控制中心 + +管理员账户侧边栏将从「通知中心」切换为「控制中心」。 + +当输入管理员“昵称”和“邮件”后,会自动弹出密码验证提示框: + +<img src="/images/sidebar/5.png" width="500"> + +进入侧边栏,你可以对「评论、页面、站点」等进行管理。 + +<img src="/images/sidebar/6.png" width="800"> + +点击左上角的站点图标,你能在多个站点之间快速切换。 + +<img src="/images/sidebar/7.png" width="400"> diff --git a/docs/docs/guide/intro.md b/docs/docs/guide/intro.md new file mode 100644 index 000000000..6b702d051 --- /dev/null +++ b/docs/docs/guide/intro.md @@ -0,0 +1,99 @@ +--- +next: frontend/install.md +--- + +# <span class="wave">👋</span> Hello Friend + +**Artalk** 是一款简洁的**自托管**评论系统,你可以在服务器上**轻松部署**并置入前端页面中。 + +来到你的博客,或是任意位置,放置 Artalk 评论框,让页面具备丰富的**社会化**功能。 + +![](https://user-images.githubusercontent.com/22412567/141147152-df30a0ff-bf41-42ee-9958-4722206a7a90.png) + +## 功能亮点 + + - **轻量设计** + + 前端采用 TypeScript (Vanilla JS),轻量级,无冗余依赖,仅 ~30KB (gzipped)。 + + 后端采用 Golang 重制 (Artalk v2),跨平台,体积小巧,五脏俱全,快速部署。 + + - **“麻雀虽小,五脏俱全”** + + - Markdown 语法 + 代码高亮 + - [通知中心](./frontend/sidebar.md) - 站内:侧边栏 + 红点标记 + - [多形式推送](./backend/admin_notify.md) - 站外:邮件、TG、钉钉、飞书 + 异步执行 + - [评论审核](./backend/moderator.md):折叠 / 反垃圾 / 频率限制 / 滑动验证 + - [多站点](./backend/multi-site.md):共用同一个后端程序,多站点集中化管理 + - [表情包](./frontend/emoticons.md):支持 OwO 格式 + 动态加载 + - [Artrans](./transfer.md):评论数据快速迁移 (导入 / 导出) 工具 + - 评论投票 / 身份徽章 / 密码验证 / 说说模式 + - 评论盖楼 / 评论分页 / 滚动加载 / 实时预览 + - 评论排序 / 评论置顶 / 评论防丢 / 自动填充 + - 图片上传 / 页面管理 / 站点隔离 / 暗黑模式 + + 穷举不是我们的特长,更多有趣的功能期待你来探索! + +- **“Unlimited Blade Works”** + + Artalk 正在持续成长,创意由你发挥,价值由你赋予! + + 不论是 Vue、React、Svelte 的前端项目,还是 WordPress、Typecho、Hexo 等博客系统,都可以快速引入 Artalk,结合诸位的聪明才智,我们相信 Artalk 能够自如应对各种业务场景。 + +更多支持 / 计划的功能,详见:[“README.md”](https://github.com/ArtalkJS/Artalk#todos)。 + +## 用户体验 + +我们相信优雅的设计能带来良好的用户体验,良好的用户体验能帮助项目走得更远。 + +「平凡而不平庸的设计」倍受专业 UI 设计师青睐的设计工具 Figma 这次在 Artalk 的重新设计中也帮了大忙。我们预先使用 Figma 设计人性化、现代化的界面,再编写前端样式使其自然融合至现代化的网站中,简约清新的界面由此诞生。此外,我们还设计了用户身份认证徽章、评论平铺 / 无限嵌套模式、评论分页等样式,同时兼顾不同尺寸的设备,在有限的空间体验无限的内容。 + +「崩溃就在一瞬间」对于不加优化的评论系统,用户每次评论可能需要反复输入个人信息,发生意外状况时辛苦键入的见解还可能完全丢失。要知道,成年人的崩溃只在一瞬间。为解决这些痛点,Artalk 借助浏览器缓存自动填充用户信息、自动保存评论数据,让用户以最少的成本发表见解。 + +「丰富站点表情,重燃评论热情」千篇一律的表情包可能容易使访客丧失评论的热情,于是 Artalk 自带一套精心挑选的滑稽表情包。除此之外,Artalk 也支持自定义图片表情。 + +「你所热爱的,就是你的生活?」用户体验不仅仅就访客而言,对于站点管理者,Artalk 也不乏人性化的设计。通过侧边栏集成管理[控制中心](./frontend/sidebar.md#控制中心),管理员用户可以方便快捷地管理名下多个站点,所有数据通过规范化 API 交流并且异步处理,减少数据处理阻塞,降低服务资源占用。针对可能出现的垃圾评论,Artalk 支持自动拦截,降低管理者工作强度,也还站点以清净。 + +--- + +我们希望 Artalk 不仅能实现评论系统应有的基础功能,更能成为搭建 **知识传播者和知识学习者交流思想** 桥梁的媒介,让知识不再局限于文本,帮助知识传播者创造其应有的价值。 + +## 浏览器兼容性 + +| <img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/chrome/chrome_48x48.png" alt="Chrome" width="24px" height="24px" /><br/>Chrome | <img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/firefox/firefox_48x48.png" alt="Firefox" width="24px" height="24px" /><br/>Firefox | <img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/safari/safari_48x48.png" alt="Safari" width="24px" height="24px" /><br/>Safari | <img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/opera/opera_48x48.png" alt="Opera" width="24px" height="24px" /><br/>Opera | +| --------- | --------- | --------- | --------- | +| 51+ | 52+ | 10+ | 38+ | + +理论上兼容所有支持 ES6 (ES2015) 标准的现代浏览器,参考:[“ECMAScript 6 compatibility table”](https://kangax.github.io/compat-table/es6/) + +## 社区理念 + +“**化繁为简,简而不凡**” + +Artalk 的目标是在尽量 **简洁** 的前提下,实现 **丰富** 的功能。 + +2018 年 10 月 2 日,Artalk 的 [第一行代码](https://github.com/ArtalkJS/Artalk/commit/66128e2c8d9a8ac00a8d1498ff0ec035a7727daf) 被推送至 GitHub,直至 2021 年 10 月 20 日,才发布了 v2 版本。由于团队成员较少且开发者时间并不充裕,项目整体发展较慢。我们非常需要社区的力量,无论是为项目反馈 Bug,还是提供新功能的创意,我们都十分期待。 + +Artalk 社区是包容开放的社区,我们欢迎不同水平的人员帮助 / 参与项目开发。如果你是入门新手,除了积极学习项目相关知识外,你也可以尝试体验已有 Artalk 部署,在使用中寻找、确认 Artalk 的不足之处,复现、总结后在相关项目的 [Issues](https://github.com/ArtalkJS/Artalk/issues)、[Discussions](https://github.com/ArtalkJS/Artalk/discussions) 中发表相关讨论,帮助开发者更好地定位问题、更快地做出优化。如果你是颇有技术的开发人员,你可以在 [@ArtalkJS](https://github.com/ArtalkJS) 找到项目的所有源码,结合此文档,我们相信这也许不难理解。无论是优化前后端结构、实现全新功能还是编写社区项目,我们都期待 Artalk 汇入新鲜血液。 + +“More action, less talk”,Artalk 社区不欢迎无意义的争论,我们希望社区成员和谐共处、为社区发展出谋划策。在提出问题前,你应当读过《[提问的智慧](https://lug.ustc.edu.cn/wiki/doc/smart-questions/)》,这可能决定了你最终是否能得到有用的回答。在表达观点前,你应当具备基本的礼仪,比如保持平和的态度、使用得体的语言,切忌恶语相向、冷嘲热讽、不尊重他人信仰和立场等。 + +我们作为开源精神的推崇者以及实践者,希望我们所创造的自由软件,都应该被自由的使用,自由的研究,自由的更改和自由的分享。本项目前后端代码使用第 3 版 GNU 宽通用公共许可证([GNU Lesser General Public License V3](https://www.gnu.org/licenses/lgpl-3.0.html))开源,文档请遵循知识共享许可协议 ([Creative Commons License](https://creativecommons.org/licenses/by-nc-sa/4.0/deed.zh))。 +::: tip 立即为社区贡献力量? + + - 维护 Artalk 前端(仓库地址 [@ArtalkJS/Artalk](https://github.com/ArtalkJS/Artalk)) + - 维护 Artalk 后端(仓库地址 [@ArtalkJS/ArtalkGo](https://github.com/ArtalkJS/ArtalkGo)) + - 完善 Artalk 文档(仓库地址 [@ArtalkJS/Docs](https://github.com/ArtalkJS/Docs)) + - 改进数据迁移工具(仓库地址 [@ArtalkJS/Artransfer](https://github.com/ArtalkJS/Artransfer)) + - 分享你的想法创意(下方留言 / [Discussions](https://github.com/ArtalkJS/Artalk/discussions)) + - 编写相关社区项目(扩展插件 / 部署教程等) + +::: + +## 写在结尾 + +至此,相信你已经了解 Artalk 的基本情况。无论你是否选择 Artalk,我们都十分感谢你对 Artalk 的关注。如果 Artalk 尚未满足你的需求,希望你能提出一针见血的建议帮助 Artalk 成长。 + +欢迎使用 Artalk, + +起飞!🛫️ diff --git a/docs/docs/guide/security.md b/docs/docs/guide/security.md new file mode 100644 index 000000000..afd917f5a --- /dev/null +++ b/docs/docs/guide/security.md @@ -0,0 +1,39 @@ +# 安全防范 + +## 用户身份凭证存储 + +RESTful API 具有无状态 (Stateless) 这一特性,尽管 Artalk 的 API 并不属于 RESTful,但保证无状态这一特性能让 API 更灵活易用,相反使用 Session 会话技术在处理多站点、跨域等操作的时候尤为繁琐,对于普通用户来说,服务器配置也成为麻烦,不当的配置会让用户的安全受到威胁。 + +在各种权衡考虑之下,Artalk 目前还是依然使用 localStorage 保存用户凭证数据,因为使用 localStorage 能保证 API 的无状态性,也无需考虑因使用 Cookie 而带来的各种麻烦,而且使用 Cookie 并不能换来多大的安全性提升。无论是 Cookie 还是 localStorage 都存在有一些缺陷。 + +Cookie 有 CSRF 安全隐患,而无状态 API 不容易有。如果使用 Cookie,就需要在任何有身份验证的地方,额外考虑对 CSRF 安全问题的防范,虽然可以使用全局 CSRF_TOKEN,但这无疑增加了 API 和客户端的复杂程度,开发也很难保证永远不会遗漏一些细节。所以,我认为使用 Cookie 既引入了一些额外的安全隐患,并且程序的开发难度也变大了,为什么要这样折磨自己呢? + +还有一点是 Cookie 这种被广泛用作判断用户身份状态的技术特别容易被跟踪滥用,尽管可信的现代浏览器有很多内部的安全策略,但如果用户操作系统安装了一些恶意流氓软件,拥有较高权限,你无法保证某些软件窃取 Cookie 不是轻而易举的事 (特指某些大厂)。 + +那,Cookie 有啥优点?使用 Cookie 的主要优点在于能防止客户端 (浏览器) 通过 JS 对用户凭证数据的「直接」访问,阻止恶意 XSS 攻击脚本「直接」窃取数据的可能性。注意,这里用了「直接」这一个修饰词。虽然使用 Cookie (httpOnly) 不能通过 JS 读取凭证数据,但 XSS 攻击脚本依然可以在客户端执行 fetch 代码向 API 发起请求,这些请求依然是携带了 Cookie 的,是具有用户身份的 API 访问。也就是说,使用 Cookie (httpOnly) 并不能从根源上解决安全问题,不管你是 Cookie 还是 localStorage,只要网站存在 XSS 漏洞,攻击者成功注入了 XSS 脚本,都会对用户的安全造成威胁。所以使用 Cookie (httpOnly) 防 XSS 我认为是个「伪命题」。 + +XSS 是属于非常严重的问题了。所以无论使用何种方式存放敏感数据,XSS 防范才是重中之重。 + +对于我们用户来说,不应随意引入不明的 JS 脚本;不应在不了解代码意图的情况下到浏览器控制台执行 JS 代码;不应随意点击来历不明的链接;尽量使用新开的隐身模式窗口打开不明链接。 + +Artalk 在努力保护用户的安全。参考 [OWASP 安全备忘录](https://cheatsheetseries.owasp.org/cheatsheets/DOM_based_XSS_Prevention_Cheat_Sheet.html) 中提到的内容,Artalk 的开发对于来自用户输入的任何数据始终持以怀疑的态度,我们严格遵循以下准则防范 XSS 攻击: + +- 不直接或间接地调用 `innerHTML` 输出未经处理的用户输入数据,而是使用 `innerText`。 +- 需要额外注意将用户输入数据带入程序上下文时的处理,防止非法数据在页面被执行。例如不要在 `setAttribute` 时直接引用来自用户的输入值。 +- 注意类型合法性判断、做好类型的转换。例如 URL 以 `javascript:` 前缀开头应被视为非法。 +- 不要去调用一些高风险的内置函数,因为会带来潜在的安全隐患。例如:`eval()`。 +- 注意来自内置 API 的数据,应任被视为不可信的。例如:`location.hash.split("#")[1]`。 + +## 跨域请求安全性 + +参考:[Cross-Origin Resource Sharing (CORS) | MDN](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) + +【待补充】 + +## API 设计安全性 + +【待补充】 + +## 写在结尾 + +Artalk 的功能在不断完善,同时也在不断向提高安全性的目标努力,但在努力的同时还是难免发生一些疏忽和遗漏,若遇问题或有好的建议,欢迎反馈与指正。 diff --git a/docs/docs/guide/transfer.md b/docs/docs/guide/transfer.md new file mode 100644 index 000000000..cd8690ab6 --- /dev/null +++ b/docs/docs/guide/transfer.md @@ -0,0 +1,216 @@ +# 🛬 数据迁移 + +## 数据行囊 + +数据行囊(Artrans)是 Artalk 持久化数据保存规范格式。 + +Artran = Art + Ran (艺术 + 奔跑) + +即 “奔跑的艺术”,又称~~艺术之润~~ Ran 为 Run 的过去式,代表已经润了( + +::: details Artran 格式定义 + +我们这样定义:每一条评论数据 (Object) 称为 Artran,多条评数据论组成一个 Artran**s** (Array 类型) + +```json +{ + "id": "123", + "rid": "233", + "content": "Hello Artalk", + "ua": "ArtalkGo/6.6", + "ip": "233.233.233.233", + "created_at": "2021-10-28 20:50:15 +0800 +0800", + "updated_at": "2021-10-28 20:50:15 +0800 +0800", + "is_collapsed": "false", + "is_pending": "false", + "vote_up": "666", + "vote_down": "0", + "nick": "qwqcode", + "email": "qwqcode@github.com", + "link": "https://qwqaq.com", + "password": "", + "badge_name": "管理员", + "badge_color": "#FF716D", + "page_key": "https://artalk.js.org/guide/transfer.html", + "page_title": "数据迁移", + "page_admin_only": "false", + "site_name": "Artalk", + "site_urls": "http://localhost:3000/demo/,https://artalk.js.org" +} +``` + +我们称:一个 JSON 数组为 Artran **s**, + +数组里的每一个 Object 项目为 Artran (没有 s) + +::: + +## 转换工具 + +使用以下工具,将其他格式的评论数据转换为 Artrans,然后导入 Artalk。[在新窗口中打开](https://artransfer.netlify.app) + +<Artransfer /> + +::: tip 提示 + +下文有各种获取源数据的方法可供参考;若遇问题,请提交 [issue](https://github.com/ArtalkJS/Artransfer/issues) 反馈。 + +::: + +## 数据导入 + +转换为 `.artrans` 格式的数据文件可以导入 Artalk: + +- **前端导入**:你可在「[控制中心](./frontend/sidebar.md#控制中心)」找到「迁移」选项卡,并根据提示导入 Artrans。 +- **命令行导入**:执行 `artalk-go import -h` 查阅帮助文档。 + +## 获取源数据 + +### Typecho + +**安装插件获取 Artrans** + +提供 Artrans 导出插件: + +1. 点击「[这里](https://github.com/ArtalkJS/Artrans-Typecho/releases/download/v1.0.0/ArtransExporter.zip)」下载插件并「解压」到 Typecho 目录 `/usr/plugins/`。 +2. 前往 Typecho 后台「控制台 - 插件」启用插件「ArtransExporter」。 +3. 前往「控制台 - 导出评论 (Artrans)」即可导出 Typecho 所有评论为 Artrans 格式。 + +**直连数据库获取 Artrans** + +如果你的博客已闭站,但数据库还存在,可以使用我们提供的支持直连 Typecho 数据库的命令行工具。 + +[下载 Artransfer-CLI](https://github.com/ArtalkJS/Artransfer-CLI/releases) 压缩包解压后,执行: + +```sh +./artransfer typecho \ + --db="mysql" \ + --host="localhost" \ + --port="3306" \ + --user="root" \ + --password="123456" \ + --name="typecho_数据库名" +``` + +执行后你将得到一份 Artrans 格式的文件: + +```sh +> ls +typecho-20220424-202246.artrans +``` + +注:支持连接多种数据库,详情参考[此处](https://github.com/ArtalkJS/Artransfer-CLI)。 + +### WordPress + +前往 WordPress 后台「工具 - 导出」勾选「所有内容」,导出文件即可使用[转换工具](#转换工具)进行转换。 + +![](/images/transfer/wordpress.png) + +### Valine + +前往 [LeanCloud 后台](https://console.leancloud.cn/) 导出 JSON 格式的评论数据文件,然后使用[转换工具](#转换工具)进行转换。 + +![](/images/transfer/leancloud.png) + +### Waline + +使用 LeanCloud 数据库的 Waline 可参考上面 Valine 的方法,它们格式相通,方法类似。 + +独立部署的 Waline 可下载 [Artransfer-CLI](https://github.com/ArtalkJS/Artransfer-CLI/releases) 连接本地数据库导出,命令行执行: + +```bash +./artransfer waline \ + --db="mysql" \ + --host="localhost" \ + --port="3306" \ + --user="root" \ + --password="123456" \ + --name="waline_数据库名" \ + --table-prefix="wl_" +``` + +你将得到一份 Artrans 格式的数据文件,然后[导入 Artalk](#如何导入-artrans)。 + +注:支持连接多种数据库,详情参考[此处](https://github.com/ArtalkJS/Artransfer-CLI)。 + +### Disqus + +前往 [Disqus 后台](https://disqus.com/admin),找到「Moderation - Export」点击导出,Disqus 会将 `.gz` 格式的压缩包发送至你的邮箱,解压之后可以得到 `.xml` 格式的数据文件,然后使用[转换工具](#转换工具)转为 Artrans。 + +![](/images/transfer/disqus.png) + +### Commento + +你可在 Commento 后台导出 JSON 格式的数据文件,然后使用[转换工具](#转换工具)进行转换。 + +【图示,待补充...】 + +### Twikoo + +[Twikoo](https://twikoo.js.org/) 是一款基于腾讯云开发的评论系统,可前往 [腾讯云后台](https://console.cloud.tencent.com/tcb) 导出 JSON 格式的评论数据,然后使用[转换工具](#转换工具)进行转换。 + +<img src="/images/transfer/tencent-tcb.png" style="max-width: 480px;"> + +### Artalk v1 (PHP 旧版后端) + +[Artalk v1](https://github.com/ArtalkJS/ArtalkPHP) 是 Artalk 的旧版后端,它使用 PHP 编写。新版后端我们全面转向 Golang,并重新设计了数据表结构,升级新版需要通过[转换工具](#转换工具)进行转换。 + +旧版数据路径:`/data/comments.data.json` + +## 命令行导入 + +执行 `artalk-go import -h` 查看帮助文档。 + +```bash +./artalk-go import 数据类型 [参数...] +``` + +参数格式遵循 `<key>:<value>`,例如: + +```bash +./artalk-go import 类型 t_name:"Site" t_url:"https://xx.com" json_file:"文件路径" +``` + +前端的导入同样可以手动输入启动参数,例如: + +```json +{ + "t_name": "Site", + "t_url": "https://xx.com", + "json_file": "服务器上的文件路径" +} +``` + +ArtalkGo 导入功能的通用启动参数: + +| 参数 | 类型 | 说明 | +| :------: | ------ | ------------ | +| `t_name` | String | 导入站点名称 | +| `t_url` | String | 导入站点 URL | +| `json_file` | String | JSON 数据文件路径 | +| `json_data` | String | JSON 数据字符串内容 | + +## 数据备份 + +你可在前端界面的「[控制中心](./frontend/sidebar.md#控制中心)」找到「迁移」选项卡,然后导出 Artrans 格式的评论数据。 + +### 命令行备份 + +导出:`artalk-go export ./artrans` + +导入:`artalk-go import ./artrans` + +### 高级玩法 + +执行 `artalk-go export` 可直接 “标准输出”,并进行 “管道” 或 “输出重定向” 等操作,例如: + +```bash +artalk-go export | gzip -9 | ssh username@remote_ip "cat > ~/backup/artrans.gz" +``` + +## 写在结尾 + +目前已支持将 Typecho、WordPress、Valine、Waline、Disqus、Commento、Twikoo 等类型的数据转为 Artrans,但鉴于评论系统的多样性,虽然我们已经对上述类型数据做了适配,但仍然还有许多并未兼容。如果你恰巧正在使用未被适配的评论系统,你除了等待 Artalk 官方支持之外,还可以尝试了解 Artrans 数据格式后自主编写评论数据导入导出工具。如果你觉得自己的工具写得不错,我们十分乐意将其收录在内,让我们共同创造一个能够在不同评论系统之间自由切换的工具。 + +前往:[“Artransfer 迁移工具代码仓库”](https://github.com/ArtalkJS/Artransfer) diff --git a/docs/docs/images/akismet/1.png b/docs/docs/images/akismet/1.png new file mode 100644 index 0000000000000000000000000000000000000000..74fcc8f0b6177564d419c9d8a2c938cf249ef4a8 GIT binary patch literal 21871 zcmd42Wl)=4+b9~K#kIwuP`p5a;x45WiWf_8ibJsCZUssy#fxik2m}r8T8c|>_Xd~X zvhzIex96NWGiT4<-><!XteITvT9?bZ?|UWUqnZK%E;TLy03cBOAg2icU_k%?bZ=}7 z6lBzbr2qiH0DM%@evd>VA0HpDudf*y8PPMRjiX5)O9AId<jT(e>FL?h($Xg4aBg-E zfj}G`9c^rEba!`;jEu~0?(y^UZ~Q%6+}gwSs7KL6lLnTSmg0Cced|BNcdK1^e7t&m zJb8SSs98~KUVnUCLNPh%`?`_$ar62HwQ_yc_qb9_<XW-w@W{wm{CIo)c-&tBt?EB| zyx)e&ynE~9>eP92cXze@czwzUS-81|moPFuRuHPA10a>%Pd(d<mmeNZCjb~heW8pY zjEooO`<l6H6rYQ-=Wec+a=Sab+n|t#*{_d{T<!a}HJdl{=ePF<?EpOO;I8YwZ(@(N zbPS>W0PS3QX6Xn){)^SJVdOP>HsTX>g^G#_eGtjW7%_G8uycNKwb8o>d07o9eQcMR z-n(j?xp+KZS}U_~6yPuIfOiF=om}7cts`@_p7ObrJT9c0GBRA8tx^F1?-&^#do{EL zd4tda0zdv#I14_GIU{$cAOD!vgXzV?yI4Mz&CJ7(W?KOOilXHceql$`56txHUrc@m zGBSb$1a;sU3Xdm8)ql3Gug@>XlXUg<LL|w}x_T{t6ebK`c8)9x1XRVu#ik#je2Ca> z_8e=5xaYvd1m0}_u6~<2lbJdFb6|y2J~JhObYyOsk<ml#doADR#2@9h06YN;5<u7N z-@Cq01{uAnb}|7H07J&q?#9gCcz#nX+2?A+Y;VP<?4gf8hZcsr!ootGQd{{&zL~^* za9Y2mcW)&(%gh_u4Q^YHaRYL2aOih$H#N6e`6dsS{us+P57vE+DfER-$p-MH`|%*R z<Sk=MKO9()m;8a#tz}P2*Re3ffKE{E>#w@%WG@#>b@Ya#m5!eYjEtL;wDoxr8DWkA zHSj3tKt{1fmZiu@JiQ%A@^yBNrpu4BM%TT0Qvl$lhLuaAJ!4Yk%wm=2ZwRCG{B=TE zP0vheMoxOk$%BYiSY4qMJeQHZ6_E#$?&$1#BA@nNUbt`AQ?6_0*Kp&z^4VF$h}+N@ zDoHds6y@G(d(H1JG=pj0k_N4neU0UyAkJ9-{F>~`lRj)Yd_*Dc2KP}ctL2!1eY%oA zb+e{jLZ1?yENrFI=#LFBk}I`j%1i#vq$=4vIJ-vt><`0{JB${vnm>k+&?f-AdRjh` z2L}Xc{^uurq1KMappc>1>qr%@Qa{R?%fRJv*R<3SKmIRz;zI2NzXlmEKRnhrKhNN_ zcvpY&-vxIAMV|L!M)}zVtw-|?5ycYvjb{JZqGK@dyvC>k#%A_H5&TW?Uv?jBqW1r8 zyq*}H1~2>8Xdhto24EJ!y=$of;OReTiOjuow}*9SWz*%Hr2oOMiaICEEwjyyu6i_G z;=(F7tt|W(on!hB9Y0>lF!>jKLqijuCPQC-oVQ}Yi%<St<#Z1Lj~7Ma&&n}_zL#5? zfL(~SDm?3xt#_<z2HS-P-~U*?snWN!KKSF-R8A*_pSGR-A6)Obq9r{p{z&1P6B`M- zs6Kk@%lbi^LaeF_s7lcSB2rj&5?`u$V+;%^o~?1P^k6GwbiTHhNK>hEpPjzByRCri zZpCs=4%GQv{Zgb`bhZ%$XscYL_NJ7UognsXPHm+!g%bYyJ!~z++=dD3-+$r8R6TXv zjh2N3KkjGxs*oyBc3eA7=>A2Mom6h(cEwTdTt<2sDLH5|JGh>c9IB*mmooh2&tV|0 z<yCzi5<{7&$&P#y;!nwejx&B$T*o3`kpGIIPCtseT#25yPbxQ`_r81fB0aTvY2o>d zN2~a+{Uaimdhwx=fZO4_l*Xm*F0*HOo-n5)o4}9?6&LrJcTZx9EcJ7CKgA3(7(m<X zEYQ7Xdyk)K=|bx&D=SlaY_he*EkGgkM{EZ0gAHh*-&5MF(WaSd@a&L&*Ow&75qdd* z(+a?69-GqX0t*WZ>t+5r2#TN0(}#L^Nb4Ep6!!1zK`pWh-RmYMG-(RX|IU=!eYWB< zRRk`(xVungps}0NH~>DKR&fo&$x$OA<rtJH^2Y*n%fSX4x4oRcy!9L8AOk2(P8O-# z{c32Oy3hx*1-dE6mwCHS*uvg|A;K7dMAe~Bjq_byDD{{Wt7Bn{Z(<MfKczp&tb|oU zO!a+$1|}VUpQzg^E%_tqf0eQH1WOO}Y(D-)bXIf%MRZSJzf5K6d6ER-dj0w}E3f6V zM^b%{6SmTloz_}tTdNdB(>zAqd9BmC`%E-8<j;A8F~pdSZpjSF&GbCsu?S)?`LZ=J zHi{h(yUoH{X(-7{*?7t{UbEe4$`|LwEWYE+_tqPqjumGuG53ybV2OcJ3>K<O$*(wp z{a30Vx~=k?<pj%!OPTONPVl|Glcn1Wdt&It>;yk}fv7eHGh;vMplxa#Gy4ZLi3`M* zEKBs*S3RvQgL}lr`o;};Be77nglLAHIn*5y;7(?&94WH)1O@-Zp7|}8%NSPk+!q>6 zk+aI4Yp!O78J&FE#U&!3@_^wv2Pd1iT#P&QQOUo0nf~pVc^a<sF<`owMNOjief1l) zyhxZ{3aN6`?GNXpVBrtzh6kTkYsFSIUS-zRK+11}lpE#~lE&u_&yeTV;^T1kzv8!7 zJ^FQqnTBKIS-`I3E)ri(-ry<-dk4#sI0ooeZ%(B80ztlk-V>BcyhdQwGtJo^Yr%)r z^>Z)g_QjBqiko%^<FmkzXvBT4@}6?$ht-fBo8%MTS08d9u;Wd7RvdTt1p1%Z_<Szy z&3SQ)X%Y3ueAkUS)b3aSiCr-6pHz4cX-o_5%m;L%;YSnqcSZar!A)+y27xi7YY3<| zsg0uYfxV}wpCrX%*{F1@z}^@2ZK#KCHi#{zvx@XL^S7(4@t-_c5ja1Lme6|*1gO-7 zKO@KYHN_|f`=WyH4*H&cLwl^#YT5J)VSdh#88_ZSxgp?fjuq_C!1Az)bB5uB2gew? zy{yg>gKoow!%ER~Qe{ASkt=zTNt70wTa!Jp?PcDc87R}P0)|)khfKl{b1SojA^~E~ zcB}Es1Ki=v^%UcNL@J}Z)CVU6``6&_9^23)i#jPn0GE?xxm_|#xN_YghB|9`s-J$; zVm9vY8C2NzLAie)&O-lq0b#)qaZ?SFdBK3Igf+y`%WJ6BYtMK5ic+ONVq4XI!yCK4 zv2TNAr80@qpCJ$gpREE$ggs;9$dVu%A<ooKt-JR6vBQ07&bnVmxWKwQjSlAb3cvR! zCFw^FF2-XR5&W#f1}PI7zVys(n&iJ}np2zeX%maUcT~}6N3+C_JqMbhn}g`}o{mEJ z0@|J#`EMYQ-&!h+XST<0zyCbYmGxf{H{TgaG<$5TQaM0IwR=89@$@p*A3lB9Y_4MF z*#&wSwfeX#8yfmoO}EM3SN^?96uPC@nJp8f#O+{1RhRbFFYBVb1B*Uei(30T>=SO) zg8|=O+Q}bWNSct0)Fn7vZTCDg!&Mb~D{c3QNSsf|LAXtf%<=DYkMV|&YdDNbcN%u} zfv=)txE{zaDHt1O@Y5iQWZ7bj3&$$$9j;xI0cXj_&T7>dHol<{IC0tP+J^JGrJUD! z=fns%q3L9^ejqdN?>?bzwQhbamoNydAy9-?bb!<7f^2l{eTO0M0Oy%2wQz^*GgcAp zNNZPcL|U8#33BFLa+B)4qoum(T6#CwM}3^kS&$%2?py3f1`jJPT}HvmoQ5x|42wT5 z4{TeNd(_-vZT;=<c1+389S>Ej?myrCi6dFo`ikR3+palZnNQ~BC?X+e+mGKWO8Z0m zy#INN71ONIYO(nYpa6Gk5}d5f`o3|VEiqAa-fj%;cGIdye@(jx=SxkwBQi3I$61YP z!R$+kXdZOjK_Ex;n!EW9XGaWM=@@A^G=@3K7Bw#I7kdv3i13Y9Z3I8JS+{wj=WWCn z`zO6|{+(Hqe*d~{9aFxOyd{P}<a%La6(JblJk=dqxke#^H>O4Q((B!eys-FV>l6A! zK<wb-Ps~2<>HFj@G%UPy*@O{HuWSNByyQl-F|0LHGgX4mF1=L8&(^QZ2qnJUN(vbE zJP`vqm6L9a7?U8^i9W>Qd_S`l@-bY<!<4sw-nmJ$bFovhHjbq%-YoJ})!lt4j;^hQ z*OM|UN7~2OKL<OP<6)5?79IagnIQd_*NL*5qsU7vMDS#p6?2T|5OPd2*+`twE-PtS zD`r<fm%NR}snNi88tJ;6eUi)Yr%TYxw-ZakNr>Pha{Eb~{Eb*uT88}Ml!<ER*?Csc z=hlL|vNrnV($n&QRkxN8a*Vx%%AI&>Fwm!dP%|~T7U3vKvoSO`*UBs?gkgYy?5Ctb z=J<4Akbfjq(|pL$<o+%g>(6|@R8=9ntsaJyUVQnHtRky%5EXsGo7ABEG~FldnUG7e zUlw6MBJ1CPDu#if(lJfqxpIhbWg91rq}JV8_=4|-)9cC$9o^5Ft;@p*t?m2Diu#z` zFa6H$?3wQO;mb5?A}*tC%T+QD1<T9JB14e$ZJFx`mVR;eBW~4)#3CS8IKsJ%Ik`39 zYIqL`ZJUE{A^))LgsTy2z85DfU;g^+x25N|SIue(aUWNldYEs#k>-_r$GZ$ieWpSx z-;$(!`t~H};KhwTO%5|4CliSeiB<vnTeJCx60;T_-%A_Q;J~49k*%T8eT;c)@`T|y z-vkIi@L8+Elds9kNO<!*EZc`j3H<_h<<W|^J5CeznSb3G$~6tIQt%Ne<n^S@+Bz&A zg*andk;OE5_YPw0ljp?|e0*TzRZgH!>xM<%P|$YmWqGR%f1q=^M}AXVTHX4Ud)Hl- zgL161s)QK97k*wrFPjsN_gKpLeS14AZM)$a2nC`{y6fKr>5Q#-HI0~W(se+4ns)s5 z>w-H)^EI#b(D-?WZURICwsdX&Hf9g>Qm6QP_<=wgmRsIOV@)fSRgh1eCD}3A_^Xo4 zExJD8#jir3n}VYceJ`;I!+*GV2$E_54174GWTWsFExqU)uwJs{;Tdra?jE+HJ<VY$ z-}^*l@Vx$zOPM(&g!y|s)u+ir)-&{O<=n>XBf;%DXkWn*Q|XV!NKgbp!@K50e1egl zR=Q|=lIE%Y`bw|a--ZjxJr(PVezc&-_y+$AN1%vtHpq!Qa0fFi?THBaj=(b=bm8W- zOXJN+&^4Z$wi;8?Gr<&v+ZO%n2m-=f+c?u)r6F|UVR)B#Cqd;mu8i;MjgMa%trmVY z>f6K&kCDskhhlviUf)=fy{99gq;<VIX3i2Zqv>X=OwFBl`=<tSo4yOik?NM;i($^C zn53LsW0#J>qAGQ-DfuDPGjcBz6?)7{)GKKAtSlm`ZKd;eUEjPLNyWHc-cENjMW!05 zdc^)!ir|fDRgHF)*KSBy=VoW8o^yi<sERHh3B_&6XN)r2EBjPZn@Ub=PGZg8jzKqp z>^1;$uO@#s1o4bcTMg={^yPjJYe|`SEd&vyDM;H~wOf{~5bF$qLM<=j2P{vksl!?i zZeU9+&9k@HxH7i-Gfi~#oQ{$;iEj=cUF^+q#*cko*2pcSliw0aD7Bc=7z`XVv_fL6 z@;p<2Xyh!y_cHx3)Eao+CvILwhNo2Za;vVJLCckNm%M5q-ijK7nawvy*^$Oxgh>5L z`O+YhSWGa4DYNwZCAk!#Kuz2oC2x#ROW}h=N`F5t@AB912-dnojxoa*j%S4Xk7dp) z-=@<H{ou_$Sf2!W#*e4U(Or5cTCjD@hv-OBUTEWU*f%uw37x)GE-Ts#DabT3>?#a~ zPSY#O@f7kFc4K_;mM+!HB^-V&5m}3t%=Iz-y{?b6a9y!UjwkHUXIB&C3X^IrqP!81 z;oWI(SQ%c=B}z)7CcDC07aNs=TyUQRWqe@r&%D}uYA+e`7ueFbG6cWuKH;2kzdkYK zdf0q!^TNa?fc5a%a2Ljz82<C7AI<YK8y?j=B?mA9?tw6^oqH^H=(nOeqvJ*k`lhDV z4`>gWR!NXY(<A$L8?U-VvKrsj@|Ljvc{|y_mc`0^qGJE%rjtTjO>zAB+b_@Fl*HzL z{TXx~@~n)#Q-7SAfybsdo;sbVAof)s$6Kv;r0luC5>1nJ8pbxi<H%j%`_Vg|ON;4N zXnkX(?a>3=!pYOg<8*)M?jqION@$cih7+cUnNP6_jKNEzG6Gh=kB)HyH2Z5Itp#st z0w>as3kSgQlt!!T;;!_WPTj_4Ns2avTIavLmw`k;nz4ilh!sp=ALKDMC`(i~Wo828 z$@ZbK!wG&0Dz$cpC@$Hsf*DN~M2!0&)v2pG?52W<Ll;bE^hZ)5Otj5T#Pg0Aav{XT zdB;d5lu2M{X*ORzR(gQ9+Q6Dd`JpKz#UbZ)0e3#wBx2gtlC{!%Y!1iW<wjIFLV{XV zyy41fK8(QT&G?*|dP6?ZTv^=_)|M6W`?`@==BfuT0Fja2bhRss134*Uf_<NcDeq#u zmiI^#871|Xs707`flI=vo)_^|>C++0;%_PG8qRG;b#bnHV(=jExW2+8J_ufDk1lIy z84HOz7iXESo2!CZAWZLpJIXY*E3aSE5th8&5E``pV7zKdj&u14xz~%L-`$%wUABPr z33*_9iF&-CNeLDkZ!DL_$;Po@sQtJw41QpSxc&v1`%G1fTwSSJMsyRU>T)GMDYw;6 z=I{HKz=iRh(9ADr*K8wpS@wORSTus&`c24wqLruh$W4cWw!XU?>$!SPkCbderK-h) zg*AexGK$4}G;D7F1U$+)m#SCpO$h%$dnLf#=$8`mdzbZ7xYwKDYd_`>2$}&lz#l7^ zyL4GDXPL1^3tluFYW4|TN@U%RW{^PA)IC!-lfGPF04$r<K8xiz^X{l;nEAV_JElEQ zdAUHPJrR19FQh*B6;3jYAS`2Qit%3!a&^~PAG@1ueIEV{j=TctwBv2eIbQ@T94D@O zxi4!&U$-}*e=^37tiz}7_hGpACZT^kRfQ+RLs^gUq!Qq?>GC;3b-m_ld&+~!n6qJU z&$1Vgg3o#WQNuqqLSj;Edtv+`<uh!Lco2>Lp1jGbT!-)`H>|%kYeDPCSHh4u9C~0l z(M#H`nuH}pV@`Rsc%40)%am5q1pB@n$X$Hy_CQQFVbO~kxX>5hvNK_C0rM|tsic<s zI@-f}p`Q-7De=|suc#Pj@azmd8MmxD62yQU+%mie=^k(|hp~7bgf@zxJ5X_Q0vBv? zAyEa$Ikwm=9U^{~=mDaW;OhG*RpYWkPM!isoib?rY&E4%D~Z9^dh=<Fv4|eZX^LJe z^fwjR?_c~ldRIneY!+2Py3uh~xP5xsOXesz6wn#QsZ9;iclv!@utg@*oPDQ9Q0dtF zxVy*-X~f7;J)=DDGqlO$meIY1ulQcW-%;t_YZ&YKk5Tt`6BB>QYq{<4uImN&*qM;j z!HR_ctmW@-b%QyJvdYwkQ>d@FX|>UrBvo!&nyEg$9>FGTh#6x}Un;YTo>O<Eiu4|Z z&0z~waO$P%2|^m_Je!CX&D_E9+6N^aOE=hjD=RjkA0;!v^1#9S%1CJC%_lTMt#`|? z=S18LeV!3jYJ&)fH_^$}dtmcqk6&4)NNINQy!^*g%1>7R1P+l$vGp5XadY|xLj@&A z8KA;Tm2M?`(P)<uF6q0j1px0cK>(YK?UzOl=d!n{4aY3BP;RI}k~)`R?aPHgb|;-O z5jHmGRm_4JfA}w~q5<$o0jsBxjMZwY%AN~>o%-iaO+u%^`pP&3psW3x^5^?f7Z!rT zuYvpx{RIJED=c{Efd-;TGr^lH@XF+w8~UIz-c!m?ucENIS1xXk-Yr<r|5CJ|-=QCr zNtY|s3p5%TmIwNp42-A{d)K732sCLgSz0w3-MgRdtaaqpl=Uj=sbp8{ab3Rq4jl%Q zr^zNlJj@OkJn;1bU-zAw3myse-{}3=7cddBaRjBjctc<MEz_r-rgH%(IrQ^N;P5r) zcVWnum<y38dKMR?ksS9yd^<(aAhBJI;it-A!;Fp<o};I5G)GU^DEW-6o-%<`kcm;# zY=h#IZeb3A9@J=i5FC$mvd4z-dfoelt3cJlvT?#rsEV|9Id^zd<Aw=BY?@Zyaj2IS zIwo|`;)we|I(xxVbGgwAWmy*~^S_;*#u7mmn2V@%C8IJS3BFMpm*R|{BOoT8V<U~I zxQKD47d}@L5}A*@>gFRq%i^z@E4yfk&rH=xw?1>BZwUSCg5fyLA*n|w`wqXTetp{E zpSbuAtxW4}{$!G6OA%5xOj#z+(ls0EP&QP?$|SnlX|}24Dwkd5xm=cfx*4m<dtNw; z920j=(ju340@AO#dyy@_b9{1)3O<o(%BT=HMNFEYJX4Usg*h`#*XIlSi3s*G88LlB zb2l#77$u0NKfK<sR?{hHg`<{zF#k?3%7peSDpAZ|eovh;Zad?BlC|c`i?Q421mjoT z9$}C<P{TKVzI#=d)d))jotPnMUuM$)^ThXswVp?R3eCw3e(Qy<uod@}(1Eq1z=)Ls zG9K;1^{bA}5l7vbK*oh5$WNC*^G%U&;IWmU)H)hH?y?B~i!$4};a9X0FJHIEtoC2p zMhtqq`8kcM#<fwOFAyi<s*%6FcMTo4@fLLBFAdY8{>zA|Shla<v((}5sicK2%x7jP zz$(bZ;rRE&S9Bur?ZZugI{u9{rWoaj{MN02hVR^HN2uz<+Du8?aWMY*heQ1jcQIg% zfOL}fXg+6p=C-7tnwVqDZe8|YWdr1!1d{{9i&va~+I8=J*sOv-C9fk2y2UjFW3By} zzfV?MxZf<jh^u0))ISh!x674Ai_tfy_Fn^dxC`cXgy(*89~fdTbR%0?s`8+2lVP<V z7{Pr?VAbrADh=W7rCwX=0>7I}eA(;5-sQ0LC@Gw;O_bY}S>E?|`yx55tJLH2C_%$L z)3jM?@ACT@+(?kFOun?rq5Uy4Qc!;3h5PV$@4#7xm=>4sg)p556rl#|0(<U-SAYZc z32Kc^O6pj+fayFv*7^#Zw?j3jS_%d<3VCnyzTfE*^vm?S>WC%#R_jl5X)k>Fq09e5 z2c7+Z;W$RdwGi_nP<LKInjmQvquoE0)pWzN*15Lx6Ro&!)2I4nW>a%2<<qQpHF5AP zkc%~IgSQR6MUv|4BfMva>-s-^qBQdK-|&5t&;RVQEs(|SCNt?hf}zQ1>(oepn2Sf< z>mj_}li1t5TANGxDZRs&@@H*SVk#U%ut`86!k(OoQ+1I#MiBkLXE#&iqu;RIho&7{ zVTeZBaJUhHk6`VDRE=>^_cj}541+Sz;Hbww*xdi{T6|fB`ArFRwBRcO<B)}W<z$g6 z-QDTbap7BJqsYe}7$$fQxFs$*^V8@it8rW1FlmToHJP63pEMoSS2#F3jr1wPPAPpV z82*mS8XqI|ShgycqgT?Y>*)Bh9Ro`SLf}Dugwq&B#9?K~DW_RFWsc|ZizC3Rlx{^b z-(mT?sSr<GNQvZ<A>UP^K^IP;7T%wy@$`_Y!_Nc^tHX$m=V}sR@q6e{ZgfiLY26!t zzz0FF$ANKxGhYV&B}rQ7?T=r^avN424|C-?S?Wvwvz=Zh?hic?ju|R7f6jSnxk{py z7QgBJ;c5CO|Bs{J3TMmJgz3Q7#!Acw4ogJMyVd3wRuC_WtbEF#Qa^J0$-yC1C!xp6 z5<BoO2?dVx5fxRe7LUhSJ=7sg3ws*-ZtF}6UkF1KNbx#;iefAoyw?6mls8vnCHRrx zAvaw-+VOC#JP7&I6c)|VjCNM@?4HN)Syb;j4L9W!&)RnzT?$k&#Un^&-wNK`#v`pw z*}{_;88H5_aX~VD`Y>(oOPJ0K^E)MtInAMm+`G5v$yNs>sqX%EvEE+B_aBrvZG@#N z_<zCkvc|}qz~_R;JcNRxr!Hy?ryjpievcX;;f)9nJGB;4oXSjHR8}IG^(I*IfJ$d_ z+P+hcI3IY@8?DE_9L7$LL2vH;{qsX;k)?|3D4|3nEC6{}XnbyHp+h7+@R{i{%TIxt z-q>(tMBl=l>?+bz`%=`WHKAz4NuL@LV^cp*+#G;!?B4ReLPX!WTKboHPh^=f#))Oh z7M)xl?%GFN;J9V5?y$_!qtTjdg32gw^tM=R=Z4StyoJ0U?S(t3`?gZeyouKUu&Kt< zX!>2H7&@@qKg;2}7zZg)q8lrl)$Q;USaQI}qm7|-{pN*Xf*S<I;kolCpT)h7t41I6 z7ns#GABlmkTh;%vc+K_wDp|T~PbTa)SWo{vs0p&Voa78t)IDHw<LTTpsz8q6gP1z- zE2TUXwQXm_j3;IU+Xb5K?CodvCqD9(zO-hVex0uRvJAhJyUp5;p!OJZ5j={`7n<=l zaDX@PsTpzrQ!eTL5tkwjy8ofKai3~J1Nsj)#PgEfE1}R72O<i0OuRBF8iZ+RS>K+h zTdn6Sa`*L<q>m==RI726gyiyq>JfX3A|f}cf#^$H)Q7$9gQwgcs3|vzoUFD=G_t4K z8hQ6FQ^~)Qa1qgE4vQvt=oFi1K$|Ix*<!|vgR_d!b>1)(7_&FQt!q0FHNWWOOHYVg zi(%GF?M(9&?%K4UJu-A@B|5%pe)8Pu4M}L#k`c^bGd9Fyc?4rdhx60ovO}q}!m3$N zy$@Djfu&9H64I>|emm4K=ex%oTTHAMm2;rBbhG4hp7~khfAUCriit5jAG1s``Hj3+ zSttu6Ixk)z-choChq$v-e!uN_$i;%oG0M@jpTQ4Y%l*!QpuadYskePexawt2bgup_ zO<EFX(9EKNx7a`UcSY>LGre88O{`CHf2NAHYC4E<!qD75p>@V9{Yd2xx89wO6E~6b z`<>J!<CYvC{m!M1eigDJTC`gA{5@Z@FLHhON|tE)TKmOR78X`(Q9pe}z+df2gb{C1 zu{x*zl2oxR(L#S35F@BxPUCeA{PUQ&^ifpEsw_?)R%^Y<)WhWrbA&B&q_*P7Jv!#F z*^;NMIUy&>E}%Xeg!-1c%4-^7!Iw^m6~a{hE5mI>A6%TZ)eb0vH;?;IO9%-DXgX!7 z&6|#oCKC<IJCtiUsY!(z<ovVGwm|HevkSk0QJd6XH?i<=>vG`U89YWW>BD`Q%vZ<x zNTA7#9ZjH9X#Ma<2YY|F$bUrKzA!A0c4SfXICBv67p5iTIVwD|)+@YhXKIF@jj8&M zBOZhP!6VQ8@M7sZ*^7PkM&>w#l4O;^3ocpVafA!%tE)s^Z9iDc0$Ji({;qsx@A+)* zC#t3hVDdlORJkz=mHic+D8r)36L5Q8&aD7J>#+7W<>iM>1y&WvU27)KOI5*%Uc844 zj)MWmdOn;&W+XI$R)3KN2dH;<X+Y3F$_a{3>l^>o<?tyvRP-MWN0}QJ#rQ7iLP7Rt zYvHnAdLl2PIUTHT6pRvfXTq&9MY#sc(O8Ru+{g0pl}np$Az{&fk!n7t7s>n&W(VDD z_{Z?tCfssNK*JZ{qgBO-Ei)kK<u_FiF<X-di)0y$;ttleVK_j$!N*k)Kn7hlB#;S% z2!k*_t|9)<!HZacSIs<tj~+yToc(2h%$y`zP_-`_!19s^@N<bCwSc;E^8X#j=0t=~ z{s9Kvnb5q|`R|X}5Dc_`=)8QKk^lI=BxAZ0{dWFamq<{1)!Q$tGipZs4bua^#@2cY z#|mTLhbYsMGJSaY&W4zALWKDzwkpA^UzAEO`1H)kYIMT|)EGa|JSqR+OpIG#@ygA1 z#dG^`iG@If(q;V7N%8cs)z`EBZY6o}=|7_UzedW!fky;1r`)&TzB%`x_K%sjENWFm z_7Qu$@UxUdL0X<N#?}{`3b$HuZq(I=Mcgb}4fdBAhc>}w(^hig-rsh^Q23wGx#TDO z$Gzuw_VaBR)<@%hw*0oLflJ>k=#0zfG34g{gY%_dgZi7M$SbkKx5ZoW3@#rg?DCSb zq=!gY8eJEL9_L9=NYQWJ*ZRvuSm$m?ln>tGlE7KRTu51zT1ZiA!Yg?gN`yt<`sDhr zMIi?82krDKtY&-MTa=qRqIL$xGk9JU`1J=G33-iiKwz_hZ6{EXO>S`jK*rZLAeW)F zVdNWTTw=oelDo>$3I7c{ox03Nzn$t@ql<Jx{XU=8Wt_oEu8R6kZCoiK+-=2X-Wf-4 zoqXqLK(2Z(JaL+LnB>-8s$1?id-DlKxz{X8JIy5;)LE|F=TxR_G3^-N<(AQd%6BM5 zN31-jINk+_CEjW;e6FAY0HDJ*-{QMv^V7OM1Lcd>%CFxYJmuTOkT>{=h+i=T*Vp9= zKjY61LeQ^;-kTo2l5iGX6;Evl873_$2#sfya%<hqIum5}tvV5{xRi+60`y&e>z&l_ zb%$PGPc=}~3!D7tDV=j*xACWJCapA{_<=H31FIITTZRxpJNGSdu2^D14X>uqo`bbT z)n>C2Fd03O7EX2fOLB@2;w`Xao#!T*Aek|Dp~WEy@4r?oQ7tVS!MeJd9b0uWE|`TN zc}*=~O_YBWS}&`4ag<9Ud(xZMo!tR|UGg~o+}!KZUA;OXf3{uY!0L3OlsLtR$u_!j z&kc*0dGpi8Pp`!-)eb6;aP=}p1~eLTV&*occ8(_(9o2f&9j7Pn`oYe>1O!}L2<M!9 z`;CzEppkAoT<E<W8cg?!b4N0}ZKhf0P5e^jP^Xg>Of0pBo&HE7+kD(+u$ZbqRoRm6 zDE`qtEO0+ld<b8I@@t};wsJwHta8Cvlm%!#e%FEqw;DI@m5>lFiJS*s*dQw>Qyg~K z_q#)aXZ1><FQ3hPlYPZZ9rq!Fe|y1mn|82TId;ePA<%jx^=w#R)Ne-!0C)s=OO@Zv z>mo9yT5qBT4B4jp`_ow2v$;lptbwI9RM@@)v=x3Qwvqg5@*ZlHIGE-l6Lp*b3O+uH zw!Sum_&1ymtEx{#kD>|}c&D5EJ{z*MvoQ!?SIjO;Z=8FNO31<x7nvvnnh=$=Ni`Ow zboZf|8F<U@K4)ZOyk7aL4Tz1&%I|i2dSFD9@3Jm=Yt~0f;Ay3`=ck>HMN1Hy-rw=p zb(deWN*gJXtTRnhebU2L0Dw1=)0^^qmYJZ@t2cw>Tm*P~Db;4fh?_WwPSJ1m^ydve zmL$;TCg@7-o&E`89V$aoP@?Oo6VqUr>CtiqFAfxV57X)8YQVDzYdZS%X-OCWP>Bro ziFsb5J;n2SiQ{pqs=L6v<o*E);dIx`j4<R1{!=L1Z>cM)9Z|82Q%8ZeTPT>W!o$8} ztz*>MKn>Jv0q+VH9a0pr>5c2puVEPdBV#^mV}C-Zi*_4FzNqtHzUUwLiTkwLE+WUO zsqW*skf>Ha7hooLmz@Mk<U6^AU_KNVu~DmgQ+KPdW`068m-~<L6j~Qm?fG15zvw8O zuI-w~-^CcUzWIz~_FqL50?F+UGHkvjySO(_%4BX$)OFPge;I8W8LpH5)pmHdOul`D z&fg0+{D{h!$zMAHQ^L?Wui8F~L1wWRC3^FNh7;EcMy+ZuR;D2pLsBwOV@f3V?D8(m zin!2@#q8HGgF&M3&w7zpO&3m$?SY-bg8;zlV+V2pQy_#?{Pc9!eBxlrNYZCGiAbxl z+NZ7G8D?{hX3rk@8f15SIz5vSPz9<ZTCKRkN0rt)Hf9*0sBFN{$Vq(|zHt<m8(|@| zY7c6jD*kMvMjAvt-S?{sB5mlTJ*)d&;$ZXX!O^<k0jj!m<l9&}GtosLw<G%@mpiVd zq1$@*7bl4GX5Sy+O{0+C)D46m0Vf=;suf!7QKtROQXGRtT<vPr?W>WN0Kjp34(-&h z;dix|N<FNJL>tIyj&d?BRDhh<i~oe*&L#&sSj!&>^t-~Imo=LtIO!@8G5IjI-3Lq7 z`Yg1sp5GmyjHeQApsDp~{yuf_Rj)0<Ptr2;w4dbOGuCC#8|JgAu2qNrC^@Ge6~LA^ z8s|sZ(+4K^&NSE$zO%Yr^0!TNtrv0Dmv?{X0svCT)6Qu}*Yufq6zC&K=SQ`YYkh(} z6ZR>L%IlifN|ujPq~zujCXw5`6Y$)fR_HIQL|i&~ZM)lv<~Fk1#zis@X;iZ<3}Tgx zoSHDZj2S8MYf05RM((_gi{ZqZ2@4#Diy=*w1vBa{?Fu5cdZ+B+qSDq9pqcyJ-M0ak z&LvrN^5=3MZ7chEmEl!LXW+u0f5jr4|E<it4BK8UhjdFwWZ`6aw7j!as8APQ+h?nY z-T+@q7A9_)<dBD4jO9GrF>hb6W}#}oVFKAT+?L{b7wRk3!`wIOXIhK`a+M+%M=1hk zX#s#wW<PuT#FnL0Le=LzU&h!|Q+tk9$%b05aICfRaqbLl#}8qpKG`7^Q=|8qr<$gC zR<R*N7w50g)cod~|0wMHzVM<)7<a0L=b}WV6k(3QVypVn%-a%RVY-{cigdAX;$e|y z0qn3Sa1LdY6x?|QZJUv^I<;Zvij^a2|E+u$Yj~6JVy8mt^D@nCVIrvjzf+}~TD;ed zRb^G{e~qoj3|2g0K6A}jQbNFU&fvcrvxnz2D>p@H=A(%==eh=v#JYFhOP+?VI(3*( zLhD+)GJ^so9^9qK`wCC!eEAw7r+!61DwzQ)(?w5653ll)77ndp=mUR^7NS2?T073T z<f~i4`Xb;1M21{!(dSDWAQ&H;kbG6T2wC@F8s!>Tu)N!}L|fRgcgmt>kuB?%4rMgW z^Um+FwM<I~d<LFG_^^hJwdF2Qg)qV1;%jD~Bk%V=7s~d-Ii-5<vmovzt@Bb`jFP@w z5WNouZDhU@*9XNAvvCJ}bnNW#G@X*GzGh*yzhMgRt_rYGQT#yp*S4K^XA#lqO+g(c zj<@}!Uz=MZz!04tYi2X^x<=0Lz2`uqwC{6IEA_O4Qd`uP|IHD^v)>u~FK+Ck9aAyt za`S(4;5K{Mqrb(+(3mnb3(+ij1Ulgz_lbA<u2M_U{d-(RF_Fn?1-uM;+4{Hi5IsoU zUE0Z6XNMOHASJM)5t+WUg9SiSGw7`F7$yRstJorkjmzNxxfBoMLO6hV5<#I)AoI-` zD*#px#E3QZxdknBpkZ5K%zy#awlEY(6#}CUve!rLv6uvxW4=rW+6e;YYV{##zYF20 zy+Y;F|0k$H(!SQGK3bH0Ct{qIA;ZpdjB}JO%Bf76U+Jl8WEh=EKwm=-3GhUJSH6L& zM!b5hV);RdN|}nBagshLanv`<b=3Fnu+!*wtI^8n7f-L{OYCc}l}qnYlJY1+E)X6= zsExxWxKSUQLC%f|Gzgc)X3(c;)Q6JGVvo=NhP%LsWxq|!Lz5t3#Im(QE-*u`P~u!z z9Apd35K8>NMIx{tzH!*b70yN<c&O0WP-^}KcCqrt%7(ZM+uUj;)vTPtF%u7BeaVCK z<9)@nR_i=ZP}{Fgl>)aGL4Ev$g5#eN-PYrnJSk`08`jQYXbWXB=jQ;9`suK>NpVgL zl>ENrT*lO1xx@8%VO<>y%IL+UNmzX+U5*rb03RZ5d|Er6#;+tr$^+8-$!xuFz*mhY z=>vVY@@97yt647jl~ddM+w)Ef?d|xLz+8p%1jr){Qgna^Q4goZ>&^^0HN1Dj&cNH) zwviXjklgeY-QRs7QwzCUJ4pnIcV#J?4@$MI%iI|#mp~%0zAk3d4po*c{#YoQGL*b| z?$Q1wR-7;e0@<j68utY<E#@Sg{UfsLbQ;m~+>Mb6jB8U*C<Lp^Y!h*=0+$`P(QNhi zjdwSjTj0glOLZ3PcJSyb7a;~iw@-Tb75UgO<W&+;cU%xuYYdmoZ5~<;yrXdJ=Ql}M z#BSS*_w3ramOF=|uG@qaJUFYysT@hF%;G1cuCrIQ&a<V*a`K&@poMvVHr9@h6IvbI zmwEqSjYz_snS!Lc#S5RHJU(sT7fA&&ADg@*)gdRM{kZ`SwKb>Il+e^|8v{41!kd+0 z97!*#I>;B~5-GE7EiSq`yfaDdp@kc6r%%KvSBH2&!UOPaZAw4HLW?2jc78UW+`*J& ze@Jq!)SRTsQ_%EhHT0`wis&f3d6AKJ>_n9RVfhqU0+W#rm<f*zM#UKKxaD+}9%w^* zuR)Gs6fO$;W9Ik0(X*&2d&fvMQF9tjY`QH0iZLEyl(2Fz^CLe|-a=S4`m9j?NIzBv zsf!~Cf=96VyW|GWFw94NqVrlIp73UBe)DxP(DPo7`EPaF^o?l3Af5iA;K3`CAY$1& zq6W+JlWfDNOv!c^B+J)^d2M>I;B($CB(!j903I}ZX6T@PDT&`;NLeKZb)2WW8d(Z- zL2j$+ydG9++8CDQ@fO(Q<yxSH|8<83jI#Q)LQ;7h>ta6_(!BBK_T5!{8F`-oqQFF% z_u;iq!<%DhU8a3nz#iD;w;4}OJl!~x`swnR5LSp-W0MHGr;*VnR^SiEK9k*xu`R@Q zgU>8$^3w<VEgnOM42uCg6GQT=%q<oJ@biyH;Fb|q4>phjj~c@*Er<t?{>duM&BRhN zPQ1*;h!Odf%e6lCiS(+G1I;|QXS&?c%4TrQlqz9jg#T=B()^Rn2I>m_`%!4Lkok29 zN?CeoHo56Hxhpm;+#umz_{X(vGIk>c<@OPbiUFSk<%yPVB1p0b%)`T7Hqn?S+hI}v zkE<Yeg{OO*(Pz9`8p|EZHm&5kP~w9aPguLRrP#<YMtE9T-dTM_ty?8irjZd~PqqJ6 zJ|klX?CM<?e2A-_07>5jQ+h@ykL;d<cHk6h<BoEPJ9Z7hmS}X%HAt{(gAYrhnr9u| z(GJgtHi+<av)Je6RdO5qfJUbL_t*^c8QDe-gdXhHoPplPMn5hKqF}|DQh3L+ndORx zy{wg!nOp{SI~5QtcsYdqM4+)r4_fCty?e|C8XZh=r_fYoAHi1tyufkPk_L6q;)fQF zpB0@U;({B+mY>#lJkf_HqN9@431LJq?))V62ux{|P^x|h-OL0{S|)goaD`xwLjHO* zue!KDH*DQs>=p3$72_zk(m@RSd=1%ZwDU;>XA*r-Qa<ar9c|=)HO_}??Y~?MQTzxQ z#PD3|<$|9)nK+mjRlS$PW03O=fz*7@OiQ{+Rhra+R*;jhvrTdOuX_q{-d%Ns2y*3p zzHu>H`b6g?t*pMs4SMtiWwVbeJ*Zgc*tWB`{*dh}tKAs17$0`=Vzo6f>{c=xOwHTr z%#Ra9fYA|$AoY4hF^?X$nE_GJg>_U}&pl8yI(S~&$~jzHC+^^23ombRAco4%&WijU zqLp-2rwJF{1p~)2k3f?z)cHO_A9kQtFYMWdHV)VRT*Xh_#q$@n$`56Ov@Exl&g2K+ z(;v@{xNcnt!_$+77tL9P_YwQPgS*9zX^OH+hDe0hL6+_u2;TfLl-ME0Q&1cCsalF6 zyf4veo@FG1+41ts>IDTVlDS_WA;j-}2R}E=oW3b-ggWlGT22o$KW)4*X{HuG!b?c@ zi>a1$_C>qI5^9)~I5szJx#M!=uof=~Sk+nH>rN03Y%*zOX#s+#;D%Iq>H$M-L>Z3h zJ&C!#TgTn8412$sW}N>~z7sx|zcPQ@k<7MUP&fOm-Jh<(!5(B&WR<Bs3G!AS22<Tu z*w4b_vO_O=;2+~4>G1}@O`!IHonGbc0Pmw|IoaR(nz9;~LC>zRD<)k(kHKcKxu;IE zaFzA;nk}PY=AZk?-GRi*OW3G>c`(pKEksXcW72gh+_2xRpL%5PZ)EluZ(_VJUUD<) z=*_jj?ez|Nv2u92GMBr+8V5n%|I=R&LjQkSbU-DjAN`-xQpjC-QB@wZk1Gs<=JkK) z6xk}qjFJ`YrHAef7Ax9AFVGC?Aqa5z&-74X48Z=33`7ECf*?i&GU@-ViMH9JEd33B zn1-&g7fB($+-WSnarMGG%=Rw@WyUSK0auu^EVvYMkfgpfKc3i=-FCuC$66oX^5r9< z@Q31bRfTTFX3CMm_ns4@q<~L}Htq-IheaB~<J*RsxFa+*x4avzcnpd0H85TwAA78) zfGZ(=F7JBaXs}~07rRK!twCSI&vH6KT)^>b)ItpKG9+3knPseEI|Rnmiy34+1|CQ< zXeGT7`1P30S)~IA>bHSegp?olAxUqPUd4IZ1H6KO%0h62;=;2#$0fsQT)@jbczjf? z57=IBBQ`0Ol<g^?;XQ-}S>F`pjWp0FJ}m|SKsK=aZQx}d*RM2Q|3QieA&j636lemd z9;NCCYVTPP1Q_PR<8Snh{tn+}jlBYNu<3J^l)^)xH{1T<k+^`$9C*Bse)$=B^fIH9 z_)|d2I9TyT`JtK5c$Sd$!_d+(#n3v1R5}?zhF$-@bNR)F5Uv~=<@ASX@$RH%rT3=H zxXn4v(xjxWA=nW~Uolm)#fpxdFL0+hbn@MtYv6}{6SxZ@ozWN=cPj*j_h~2QS%cX6 znFy6OxeSXfQ+^<ESUOyD3EcQc*p&KdZ~rtj24)no#!3soRDj&tAjK-TAA+H7B>C5x z{w3~|yQL~-fB#ft(Ew~<ku&9lf35<;>Jp`%G+BF3A<y`_4b}iMkQa9j?iSK7zzILY zWr^D2T*&@TeBeCnL<<6DpVh)`EjO*4w-tY>Zw3qYPy@Js!MUaCeDa<*Mh%ojw-`r~ z)ZzcJeG15d_qW&~m8|PC3m}Xy`ays8I;hpA0jqKlqdPFN`qdV=u<T2fs%3%BYXUC@ zT7V6bH(THTUO>;xT_C#qJT<&9GJt=A{t19C7w+kZ>W`w*!2C9Xn57+xWL%Vxb`rKo z{dC0@Z{crB57n4KV)_T`?;*lEi`Nt4Dbr-mHd`wDNM>=s5A5<b5adj=X~3<xkZox5 zrw#z1f4{O?ZmjpWYt~F33z4Rz=3I#h&^O}$3~_&b5YYPYAY@tL@`WJvA2yf{?mrbF z^#^A$B@2J5QW6dR0e-b}cPtp*xVXNh-S;AX3V6tct6|jX*N5L&@=_cbe!&RRtev;5 z1n%f57kf%m@Sk@1z5?WsmU~c_!sFtUJ=7yp=M;@lFRW{utb%}cjjR41zoevfrC$L6 z<x-S|a3J-8^*I}oM3nEeXauc;sP<+X=)@O2wR54F%<(Ty4m>yx^NgBJ{6rpta*Q}~ z1w2fl|3Y7~H+d8-hpgNK(FzAH)<vc+C@;w+1)z7h+rYF&%Z;tq&!vv|k<u~tM<_cS zOgTY7huTLw;u?LlB7mteaFMY=CYxcP=WUx95QShg34#dY%&bIZdDY_sPzoTb;J?;B zF4+(It^#sUBm>JIx|gX!gh;}i7b|GTfs?tf8U#4d-gYT+QvV7e{PM2cdDlX@_`?SA z>xPDJ?|y~6qs5>?x2*~pV@WWOS-bdd!0P;&)9O`P$+yeHKu>>bV-?8+jI~Fa_?E@y zOW9<T_9OqJC5*h%M$Ln>u+cfjP~u;ZDCTX%T%$J6B~-8H{Ns={>VYd1dZG9mZlxn# zKWflZYiS2WfyUrcIE^<-e>(6;n#5lA9>7D18QoxU7KW1P2+PCoV{iugM$1TIS-D*> zQ$)kfMXqVdP3agsyk#qiOBS2tA3kdcny>zFh;S%$`f7yB07XC+M5EXRhhXaLgh3BY z^o4jriDh>YK~D_tC$s_FZm^LV(rjZ@Yz9U*ck~p)`>q@?Nz;6bApr^v+vo+K3uv^+ z$BW$!>Ex&Uw+t86pqj)irl47w{KY=HP~#@<Io0x|XL|LFw0E^XrpC^Ac1M09rs-`G zJ<=Xy(RXn2LW$R9L2NP=kRvKJnTRcfnY_h%h2av^h&Z_lHhN-IuFj$b44fAoI3(nJ z8ldy985o#6ka!`b<_*+zNlF_$hD*jI*#o8xKJ<?qcWPC&A#;T+26gMFA#A@;PpV&_ zYN5ptYXY2OFQ~ER_V6Jc93BfXnx9Q+3~F9)rmj6|bD~W6YwNe`Xiu;)2fv~rk;VQ6 zQNT1@lE!G`;5Awz5lu)aVQQjQw516?e9QC|5|c%(PGs&XNWb_Nn*p~;3}+S5Ms@6a z-2jCuULf78_Q-dqam{0vSMUv6r+iXG+s?E+-A}$~*A{yfy0P8`t$8eff6S=<@T`xe z@~yq-^nB>r8ajcM7b1-6nl7`W6U%`m+Q4z260kc(R&-(uR9TR$r5Q98rg{IlIG(~{ zBcT5vzyspF2}is~SzHzr^Q>V$1I?s`%h@n$YgH+aMe}`)D;nPTXZK2h%yu$&_lL}a zbn!a?NII3g_lmC%qlh;xytT-u0%A8;O&`J2*q)a_(yOg?&ru2GUS0W04*j#qXO&+3 zE7MWe-)5u=H-lK#Zx<mK1R16}){EFfME?$DUCj7q^y*com9R!0*G2(tSqazYqU77= z`7N)K9A?~|Xz96E7W-n3ZVJt>6O4~eXsvLJxTtR9gh6nEbi4q=7ft#RenT{uYTeBy zJx6Uz(q&d;A`GFlC~asP=KXO0kVWi(U#lc9fynl{YP~Jt{tZnVZ94a{9!4|Gv(`zs zjnwsSeBjkw6VA5HPvhc`dSNqzZFZwR=AqEODM9T5il=+<V8{Yztjmml#rnhdM`h0Y zOW@f{Qdw*?R50&CM@FfXI?S7zQnakJsU^3<hjjc7aH`3RFPgRyFKPT;=Jvt0Rb&us zGy}>fAy};%qlL{r;<I_MIh6h%3jPY6yj_anI5(3QjPg^gs{Zk>iI{^RQKm>UsWyng zpW=@~e1ji35gqV7=-<Wa!ygT^3sxZYC-wP>cO+l(FgRwv^chdVKe(Gu7=z3W8zfAK zu)5U`DS&6rDWSyAWI$|hcfr0Rv1l<{;BU?j-InjGEwAc=i$y-WQ`tH-=+__vFb5n% zAT#6S@Wag>OTWPhOd>Kn7r}XX5D4bsB`uZG4VE%PRRr{1#FH^YNvGdI{qF7>gsHN! za}+kK2-WkDVE6f%_l=%Gka7>Mka<UZx&`<x_DRekBBtb()4w_HU~vUCR(aoG-R~~g zLKz<zexMuTvU>A&DLoCsf<Q!r%_A>rzu9+}h8RYL9XgmBwmyKM4_V(`P(=e(vRJ<! zA-vyVN@PLSS|!VmA(C7dbQhN1(62)77$L<18Vhh-qfA1_R9v6wDVPxJZ3x7Z7v|jB z6jn!ZyR$;zfrM!P<k>;JX~H&gFhfZqV1aU(*lXxlFq@>g`l{^9-%1z{5^l&&YtElm zFW#HQ`mcg-`IR~tbymnK6sT(iqo7Fxtc4>pB!zoW!ksyVx`0?ndqJ*W0R#tCW$8pe zBU^r%aX=y64OEG%7lrYz7e8Fb{@^_M+om4Suq#124CkUU@I4Z#pMr9V+@vg6%A<pt z54igE-fG^@j#OK^ugye%%eY$=x$NI#1#N)wx=RV?GW$BQ8mOxp?;ql8c(Q8ppmemr zcGxcX-^xO0*b1KgMmh>VKFg}R^)_hr*`%oSS(N2(CU$o3$ox7jQTHr^SD*N4Y0uNp z{)`+`4_K!7KFwXcfMFC*morxLjWdT*0+jWi)}cUP=)XV=>~|B?T#S>~3Y+KdzYyzW zSX|c2f?w1oVPp?r*MWq~DkC#&_HUt30dQ%E5s=jgXXIEOG<#*(y^FXjdRoEL<|M5h z#a_OvLJ)axf?;%D$5vMO|JaAUOsH9mRXN&K(TQF}ZSp1xx*;OXWJKM^`&olNClbi> z(FH_LL68}e<rMAFv}+#uk8Djo=N)iJp*jCB^r8K#cX<g>M-b*rITIIctj|Zh98ajt zVG}&yg^ufkrI9}#A6sJaJK0Rrc97tSdI{;u7ah?tj+3kDw)@Ia=Vu^<=*xfr;gen1 zRyz!yogZ8G6NmvQCsa4^|C<G`ZR*!E(nI~lzgA4b0U1@BF@cb>c31o79HEd?-j-On znF74jr6}h@U7gT>5nLzcOcy+fpxeu3`7eME1D7z?|ET8L<DuH#{+2?ybR3~vqYyP@ znA}N{5Q;Nn>~R;yxQ21fCApoX+!DE@<5u>}C}!Mpi$n-vk6c2LVO%@TBqG1j`Tzav z_r9Oc``6xUul20wS<hN~t@W($^Q>W})l6jy_^X<IzN|l~_5%bb#d{fSCyghtARh7@ zR9B-$?EV(!;e`T@?$r|^YvBeipDsac8nYcmetptTFH-}TO*_)}#CbEoT%*D*rC%~I zt5J4(G`1JW&tmwK7ZhVQM0)~L%p?@q5&H_iq`vUTgF1#zF0Nr0DjZ;1Qneed*lV$~ zJ*f>s<a-EVTLPP{ZZWL-om@D?%(k~rD23TO7NP<uX{#mN>0}OZOdlYxT!dySIvxxW zfG}gIb~=i9F}gx+FH4ww?|e&T8N6fTfMtv3k0<g)LkiRglZw-O+3X!YoARrT9)it9 zeSpamd^kV#y|O!^aAJ@E;EUiN9sVrlq`*b_=HUno7kkgB=YlK9aX4qL!xJvo+#AvC z#|Ok>xJ$_TTdfAFBeyk4Jr}fx=|Kh{8*C#BT*mFlrI!U&_srnK=V^Vs3)Y*Zj`yVa z_h?GV&DmuyM!lNsQUyMIe9XP@Pk=@s`J6q>=3+F2>1Rh8ziQAd=n={E=K`jm>?zQy z#61VCt-q_9NtU1D2U<;__92W)$rn0b9~@SgoJIh?p8_QdYql<rQF_zzy~<5l2H#eW zc3xx0(LSGO6kj@MeJ%DPM}m07%c3>mw84fahWgv`GkDZ(1-_FfR1WSclm_o`yREZ< z$znJZx6|2eIE9_kwy5B6md3MoFyfotPisS&QAepHL6B|wNs;@G*EBrH1@+1bxX8<R z0?o++o#X6|h>A5(2A+#jx1u5Vq|>Oi-d_QM#lCAF3kyxgDc?NAxE03te{11z<{<aU z)HJ;Ro7eMIQ?HiJT^D5YO8@fM_T%oVCZ(PsQ#lO9?@`&}Vq2bK{Eg?9Jw`rH0AS-i z^NcI>ApKb7Iq&@K^WMw()pUXM)Cuk#!{4{weEeW#U*bRe(1LB##bX$PxTwJO3n2u^ zbkh8kFyJgm?mJNf3M18?lDWc9(AC*?DkoUbNrnkGBRH`=<2;f2T>`)=`{%CR$}gcy zQ{mgALmVN1=I>zB1OeS;AJwQAAgcS23OJ*{0uvt=oD~o0438r99+`0f=Zavv*BBFw zM`Gq!QSjeY|2W@6z1R<g{E6B9z;v9uL^GDD^!mWkxW+Mk9?!CdPOQ(4oF|-Cd6U|# zuL!j24=_70CWdo&$39=b6fW$ijtYIs;cSa%-NDpa&TVtH%Wv$2EhpYk>QV=mej_{j z5r<9Npyj@VgY@NvHuiBOU#5zZ7(ejC7#g91;ifqXT-UzQG=}J=w*9G}2hvm2n&oFw z8kk~^W}L0OMKA=C%M!2#&l>wGbVD7`tSBd^Xf&EA%19~m`Yh3_BZSOLSx0ZkP#O_U z_!-wbe1J+SrqY{sXsSaDh-Kg0A?r&MJ37k;U=uKm^qQ@uWE9}c&sNJA0d20twt_tH zL@rb4gvzs9J(fW1F|fdJjM;U$8#%ELSQBQG*J!Jnnu#6)Vy*B*kr%MyiMEdjpcM%g z82hj`Ud(A~{^~H<ng}8Zky*$A><%ywXo2L$H9Y^eJ44{c1XmkyckH^n%mL`5cvjXC zk(?v@N!M@3r42l|8GC9l?c{ZpX}50@7T~ikDNl`S^3!@d0(?8_g<k<JP>;zTzMT!B zQWCK-RP7mkGNmP9I{6ro$xc|3DKRLQEB+&5u|nj&I$LOQ)!`^{+m169Gi7|Y9y4NK zeY7@|aSG7zCk``J85o8{d)=EF6j19&`{RC|7x81_!9`zwKqHE~?{&l07e#L#n}$j& zAmD@w9nK_2M?0PoDfb+V6fIM4nGyv8$SsNybml?TH(&0mbe=`{W&;6D^VdhS!m9Ga zKQC%uSsZiU-c@;X)UCIZv0V&rVr_4{QBJrk-=us3xLNoI<Mn#4_@lIbRtTD-wcLAF zHfvGRIwzg0o+~yZk(krZqU;0ic;%gi{J)3+cSa@K4{UwA%Jyk%EDf-uOeq0H$rjSe zgT8w&zM{%il|U@=oT9z!Qy}(&zz_LeLcS_zY+$yp=p0oTxZ1Z3t^L6P7%z|MUniXg zil|2NBT)wc-B=q+6zu?T-*?-+Zt*HGeQPQ4x*b0|jXL=f2G%}c#)q-!cIl9nX?545 zcm8^s`%VM@18oCdM#!K_=6aP*ANXA+u~w7YzHO+Z?db9GA0v#;yqIi`RzV_%cz4Bl z_I)&+^HQxX!3NS$+zjOEHDR^R^>f}6*<LaIy#o8JS-LgxWlzQQTE#@13Y>G;xn05? z9T0{Fo2+eh(9S(e5b2QRqvdsE`5`=t4PH8FqMe6)pt$O?)z*g<`AW|{Lmr@CeL{y< zhTynYT4i!{0?1tC#69@32>u0SQpNUQ&D$8GJ=}7D@C(BP`S<WlLr7*1+r*=O;hg_H zqL}K?P!(jt4WM&zQ$gyB$Xj7#X;#<kcUUzcWPM;UqB_fl6raB&a!fwZIIqV6QcTbO zJLJ_ldzW-sQ))*7&TO+lO|8E-JikDaWv^S_Je8u_-*@-r)aKIYI`U$45{$KohyNQ- zKhosiOXfuiPEk%W{XyI*IP^q!aUNZfX5X2hvHBLGn~iOJO{NDuy!5$)>W7M%%WS-P zK5w?=WcMXYQuc!BmF~a-Tf%sv!`HU$;}llVvBtAgI$?ufYu!AQBd3(4_2uqo@YyMX zAra{kX0ldo1O?3M)5QS4WfZy7w%o2MlKhX(z`M96Yuf1X#?4@lGdV4|RI(#dh(!_f zHShK=O)SjpR2vt*b}rDJwGA$SMbZNNc$%``73_{tB4eR9GqHEf0FxB%M$0wx8kRDX zRoUb5kR_ZOL;Rj2MI*2H+0dnjh3ID4hH98F3x~&~OPH4VdFkdQKl5Z{mJq~Whg7WP zrfE;&&PhuOWb0a6QzW|j5l{!q5qh`l&M$|}ly;%b;vrdb?iSjvm9P-!BbRYH9514+ zX{EgU0-UTBf)q3Bso++b6Ca*<<4kX;L4#X`T5`P*(mop&y`5zA3^Q(II%|Yoe$Ct} zi?cg}r}@Y|685Iqt)iEk4;-#|!wln0fV1A_<MdRE;JoNV{d%`GD#k1xNBQ7(u=o7R zL0^739r~;>c6r`^dWIoN1G!@0JF^7$rn-+3>xCH_;*fV9QHm{x7Of$~JX%O<m`Ut$ z_pfJNvnyLZA`Y2HzGkUIyT{CA5AP|c(m<rZcgv&XF-+UA`Q+<OEAzB@?x^oU($^PP z=fzs&_I?SU&XCZR`oNsGU;8%w*67J&SSj!$*4L7=HZg<uY}ftgV+ru!!o2KZhept% zy1^l=ia?Ig(5uge3*ML<!Pv+LMM!;LJ^x(l13`EhAr853X$vV-j$=$H<BVJPD`u~{ zqQZa2=v0AYfhNiVg0Z4?9*c0PxS1WK7uY*CR(X#yDmFCp<3Sst+r#g^EyLrslMyFQ zauuOK`YGu2{edfSsez@j_U&qwlSOj^yh6$j8Fr@%VQe$TIlO5DUkUa2l2|zF{RD_` zwp5n<zzp-R4{D6?-eBv&ZA8n_B9{kp!0JuZk->r?x%a3uL=E03Qg-(O<JL%b;4U|* z%xA8TptkQe4$+yH67%_f;gC=Ywm?U44gr-S8MiWHTxh&d`E3VZyPme-4KUp$d~k~C z%WLn{R7FvE{-`R~4GP+=c0%xT_iJ=j^DL8hNPhMD-|oZXb<K~qdD+Ynp%`s-*<HU} zU-i@Pxts(2(b+xcx=J>x8~USq%EUX!dmTZBQMu{eyKK%+h}%AP#bFM{1wSQ9a0rU` z3ht5}4<w0|JWQKJc(UV>ahekYneS5@85<QHr0k8ve$QTVQYu_Qis5%bxvM5IZkZ#m z$hniUU)^~*p%?liTF#5MT{Te!M&sx&Tl#dh{$kZl=eg4A{75xP89#1iTDj0Tq0)(J zmDI`AzKAG`wde*1gdeR@<EtLdm9}|W6JsM16dA?J@4Yrc_(-`<i9YfW0kOy3&e9rp zZqH`*``}Wxq~%zI(c2B5bSD?ol#|75F?=zeJ%tS)g#NsF7<%!D2l{hc;D3BBs6-O4 z><9ST&jzT(v^D`<8K&(9+&JpL^ZLJY`2W`gYm&(=(F<XPA2&6aSe#03JKIb89K5hk za6I@{nru{ttT~UOHTc?c%~SRBp^2nA&JOqa1m3X^$sM-3R%!uUWqIp?R$x>U%wK0% zi{4hMQ~1AH=KdEK)HImc$@C4Wj;2b(bvg#wsADyg&UQ0Nugr<IO;PZ8karC66GTH> zO!ZgB9De+Bv5m3lwf)lJF7vF@uDWJTP$$X4*yU(vxIsq>-e0CxhW-~d&5#Fi>_TE( zgwWD)$=76T<NnG4&5QHz6;q5KUhy-#AZH#B@HB5A?HM-s#?|<YS1QwUQLFV@n6>LH z$->>MmPSMOS_+fKmH062g!nA*oloKZERmHvuS9&SEovN-Vi0Lqy=L<o>rOYKK-Cnp zRA#(vb>D@{4$s9fCraKi$-)^@`W{1R?PJb2eXLxDp1sWMG9|6FoHT9r^I*mI$zj%$ z5?WebHo_dux@Y~R_8*!2QJ5nrQ=*LJhXkz&D3<Fa*z1^^KPu#)lO{azH&{I#{i!Ce z^>HNm98C+Ov3csaqEENGq>S$?0yZ@b11+2>uKjKO?bz`OTxe2NT#vV{2%=6@NvpE7 zZVPrJvcyfq9id3okuG|L?n^@+FW$X|4TDi#*OVA@&p~BkodpB4=8AND_bN(kV{vnT zwAWitRsj|h&;t8jxP0SR!|3cYaR1B^&d82zigbwv^NZo`U!1i)m6yjpy?@fr41`<> zQqY%zp^>nC5{d$Q9H^i}vhe~gvdnP7MCuxSZXiFnPEs=fhm7+S3LEuD5w*tFun2?X z&3|Tg^5WCFol&Gqm&@T#KVRs6E|_}S?yxaz`_RI*Ut}Wg?sTC2VGqo%7qYtH`02V% zg3`{-*Mkc`gfCon`d96QkzgF9=jQlNFIsECR9ujIP{1;eqdNa1H`LohE7f4M+V|}f zE^|*Ud7k}helX}e*^GU6nRdx(vf3kaoqj7Xb-GFOKzJXQWypaIJA}i>-K>CkMr(TW zFS+tyjLpU~2>e+KBjd`;i=8PjyBN6q^M+UIZ-ew*>XydvMYRytB6s{A+HGoVd69C# GIqpBjeMG1L literal 0 HcmV?d00001 diff --git a/docs/docs/images/akismet/2.png b/docs/docs/images/akismet/2.png new file mode 100644 index 0000000000000000000000000000000000000000..83f312059dadf0630fc63ba04fb299759c51da34 GIT binary patch literal 45575 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 bolc*<ZR()av1ckpLH^{WRir8<VZr|oWYiww literal 0 HcmV?d00001 diff --git a/docs/docs/images/artalk-go/artalk-go-cache.png b/docs/docs/images/artalk-go/artalk-go-cache.png new file mode 100644 index 0000000000000000000000000000000000000000..5f222bfd4d7ea87aa3551dcc5056b8a72fc18392 GIT binary patch literal 374508 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 T&tBT)a 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≦gDb!N}&67wr~&x)lb?u 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 literal 0 HcmV?d00001 diff --git a/docs/docs/images/artalk-logo.png b/docs/docs/images/artalk-logo.png new file mode 100644 index 0000000000000000000000000000000000000000..919c6813fb63734f0d33c5aa96b698cc433af2b7 GIT binary patch literal 7077 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 MyLjO1oDL@Z2VX5fiU0rr literal 0 HcmV?d00001 diff --git a/docs/docs/images/baota-proxy/1.png b/docs/docs/images/baota-proxy/1.png new file mode 100644 index 0000000000000000000000000000000000000000..51adcad4d87329c2f40809d557981c486c917e3e GIT binary patch literal 10645 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 IR(u`yUrs1PzyJUM literal 0 HcmV?d00001 diff --git a/docs/docs/images/baota-proxy/2.png b/docs/docs/images/baota-proxy/2.png new file mode 100644 index 0000000000000000000000000000000000000000..eb92d91e0bc9ddc21790906f7be78d8d68e18199 GIT binary patch literal 46744 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⁣jV}Lvr<tV4vnD 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 NP|sMm=&DWV{{z%uKqCME literal 0 HcmV?d00001 diff --git a/docs/docs/images/baota-proxy/3.png b/docs/docs/images/baota-proxy/3.png new file mode 100644 index 0000000000000000000000000000000000000000..7ac2600e68ac5e55ca194c1860629a95a39d48d4 GIT binary patch literal 57111 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 literal 0 HcmV?d00001 diff --git a/docs/docs/images/baota-supervisor/0.png b/docs/docs/images/baota-supervisor/0.png new file mode 100644 index 0000000000000000000000000000000000000000..8ec96f7d1325b95f559cbc41076efaf196a31df9 GIT binary patch literal 78342 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⪚qMKQSs0?L*;WUN_|6RNyDJ5FBF%Qt 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 SLdPhXQa4wxgTnoxSN;oD0%fuQ literal 0 HcmV?d00001 diff --git a/docs/docs/images/baota-supervisor/1.png b/docs/docs/images/baota-supervisor/1.png new file mode 100644 index 0000000000000000000000000000000000000000..1b1be8f7c7e627f378b9688759b86230b8f4a2db GIT binary patch literal 77749 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 literal 0 HcmV?d00001 diff --git a/docs/docs/images/latex-support/1.png b/docs/docs/images/latex-support/1.png new file mode 100644 index 0000000000000000000000000000000000000000..4cac99386572689072657dad74ede7ee1b0e7918 GIT binary patch literal 53419 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%0Av zggp$i2h-#IOG1q@<;qVz{2<oPsFGBIQe#up)XB}0&q6lG+33EHFHE@Yd`=V9rDm3E zoV^&&g*W?;Ded=NqD%@2$?I6P?(wF$Y>1tc4wewinU8gw{5xd(TQh{<w9qpv;+@Ge z5$f&DUSg#GY*!B>3S{<H3SmQQK&l|kOx>0&+tzSi`D4fyoA4M^vUJJX{f4rhtz9SO z`>wJ-^4?EO$J3sn0#Xyfur&XYbdeOB@w<^!bAGX6meBTPb>O?Xs;gcN2qAnp?<1Ls zI~Ui_DRD3eT0cuQNUzbR+YFurUXRtp*A?Wy#E6gmF#&b90K%#`1LOV<yKG;>Mk}{x zD8Z0zGxIt4jvV3wFs@Im1a$|o)4fj(Rt0WlFSDzIU3?g{*)gR|hc(byZzjpT034EO z0f#ky&6l0)jS~z)IeS$XLY88Ldc>nsmq5;G6JZ15t~vaXu3uVy;g5;y{mPCkbeh$7 z`TF4kdTAp%aWXnj+)TU4)SLdwq0k-JT?ez$EMuIEBZPM&ER$pjeoF}9Y;LL5>v;m+ zT4^Gf!Sw|2+><fk<kgSP$TyEyuyq@?PIr<ii_)X(<g$3^hizM%8Ya_j7R<5U(@ZUP z^%8azPZMF}m`ms5zC!OrnXLEM<p0R^Jds&a>L7eaG#TigHcCs(9J8<;4E+mYne9vX zijdx#;CSX3&Zg|TlSWlTZq?MwQNFZF$G)bCAgkB=_nqGKc{*K6#{<qT5^i2I{x6@C znAl`QBUqfc#Iv&CwP29Dn}aaI+U&&e)L)u_&Xt*t-={Ci(r%*2w;<JgCJ6L&(b@W? zj@>RT5LJ*zE=<b(V4<^-VP#Iq<{n`0*uEoT58per3u+R4Z0aXg##MvGq92Gwu5K!A z7INbpH_i#>d~R1P8P4Tbbqw;f5Bo9?<~-|zeN$9Ol=W-W_C1_i4S9GYY`mlkGUmwL z`&@b_k>AaA^bCk^7;$d7)o!n`njV(3`dE3fgk#k1;3~R9nlgks8YV|#?S(SwUZcwm zgkQ{UqR7qheiHLko%ZTn&zrn$N3+EzRh|@J-wn%_-!|XGCF-HSOz|5yP979$w}&ij zmfS+AHpx=NXH%@(%W)eC8+0L6-GJMKc@?T_XxaF4u_Ee|;wA&$`Va9Ym0r7zZ)d8; zRT3L_)A$4UF5f~CrAlVcp$F#I#i8|9s(cv1p0f>(f|(?ix7@N8SU*MQ3T91IDTH`W zsSd6?*xH`joZ(?-<l5m>m1?Ber0uTL@MqqeAjooOc3oW%lyem{q{BI|(Dr}vAaktQ zkKr3)ahfEpz4tB>lBy)_I^Dn*-$C0+C^mvpCUFG_?u}OI1$l41zb&kPQxueJbvhkB zEU_GE#S}hwtG~?<`LOdOe|3ZkNPqA!w%Bqf|3K4Ouii5J^8gXXNeQh^dD&Gd=16@~ zp*;_k<92SsBGD~!RzW|qZw@0L5oZ%0Abq`2eGR&w!{j0Oy4A|Ms>^eHrm12xa)#5h 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 X?~fSM%&)Ygw=vW+)vdbe{OrE~G_TP= literal 0 HcmV?d00001 diff --git a/docs/docs/images/notify/bark.png b/docs/docs/images/notify/bark.png new file mode 100644 index 0000000000000000000000000000000000000000..0f7c324b2fa4b2f0b1541730ace8789b06fb7288 GIT binary patch literal 205699 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∾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 literal 0 HcmV?d00001 diff --git a/docs/docs/images/notify/lark-1.png b/docs/docs/images/notify/lark-1.png new file mode 100644 index 0000000000000000000000000000000000000000..526e349cb181616f6eddb77ed7af348ca217eaad GIT binary patch literal 85419 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 literal 0 HcmV?d00001 diff --git a/docs/docs/images/notify/lark-2.png b/docs/docs/images/notify/lark-2.png new file mode 100644 index 0000000000000000000000000000000000000000..9cc21e096268fa220e34c668894358c2fe92868b GIT binary patch literal 31509 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 =Qi?iF1 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 Y8Kq$iY&>#h`R^A1%34YlZ>_%lFAI=s@c;k- literal 0 HcmV?d00001 diff --git a/docs/docs/images/notify/lark-3.png b/docs/docs/images/notify/lark-3.png new file mode 100644 index 0000000000000000000000000000000000000000..9c5aab849a2c26f826904a3f3d6e4dd1b9930137 GIT binary patch literal 15296 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 literal 0 HcmV?d00001 diff --git a/docs/docs/images/notify/tg-1.png b/docs/docs/images/notify/tg-1.png new file mode 100644 index 0000000000000000000000000000000000000000..f5aa5e712fb777b17a9dc02a22538c9936db7c06 GIT binary patch literal 114924 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 BqC@}y literal 0 HcmV?d00001 diff --git a/docs/docs/images/notify/tg-2.png b/docs/docs/images/notify/tg-2.png new file mode 100644 index 0000000000000000000000000000000000000000..8dc64ee9045e5b09948ebbf3d9aa339ece027178 GIT binary patch literal 71451 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 Ur^Ca#s6XM+{U=I!_e@{?51TmDE&u=k literal 0 HcmV?d00001 diff --git a/docs/docs/images/relative-path/1.png b/docs/docs/images/relative-path/1.png new file mode 100644 index 0000000000000000000000000000000000000000..3f0ba3ba6f190c656afd596dc6d56fcc1695634a GIT binary patch literal 28802 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 I=~>8s0s4!w7ytkO literal 0 HcmV?d00001 diff --git a/docs/docs/images/sidebar/1.png b/docs/docs/images/sidebar/1.png new file mode 100644 index 0000000000000000000000000000000000000000..88b8a280c746c4908976948a172a1125ecb50ed1 GIT binary patch literal 56557 zcmeFZ2T)U8*C>nyQ54ZfihvXWML>F!5{f9jSLq@(0YXdYO{F{{MVfR%FQF+AdQlLm zp(m68QR#uu1BChqecyM!``_>0Z|<GBGq-%1Vc6%Kb@pC+mA%(q<-F6;Ql_G0q$DFF zqf%9QrbkA0*^!LwV(Qf^q&xG8%(bL{*W6T0Jjuwe-#P!gK$ezqmyC>@9%%3a@<LNX z%Er}&-`dvol^ws2iyH}=j7&z($IaTt$qvHy%FY1@2C#25wXw4SZ2|1YVw!@QZi;q} zKovg^JAFSb0~<dl8%bMsIaxLtA1P7?E_M)WHXj#fu&0y{fc<yBQl$3zZ2@++-yjet z0K3BZfNU=`b=VYLJ?z*d_yzfF1O)}zBqaHTM8qU)B<&uv2@47f2?$CE2#N9u3QCDc zN{NZH{o}_@8qUMkUP|wo(mw_xT>;n~ArLny0ReAsZ+>qPepe3%0U=3ANdZA&0byZ2 z5(J;8FBoF&!w2@{_-7B#>^yBefNl_=E12!PN9$LvPzZpXgzBF;xVZhRTd?Op=tQEJ zfRDACfDpgn`J8?O+S>dJ&JF6}{CjX)8v#3KI~O}J#FGRo^e<R9M^}ier=#nCqw9Y? z{x1d~(N<IQUt|2cxVX6dYY0!sb1%{~{y~s`7uwUn*Ue5q&(6~o>S1H|+>3-J$N6mB zq!c~utRb!*2ClBo|Kya;KT&2A7UmaYdt?j*+q!yta{rqb?4DUe>;UW}t_kxAit-6d z7zl|<35iRINbm|ikrEXA1FGq23$*wBcR@)E7X2?kNit(=4YB?Yfo*N1>|H%vtVt6F zx>!5d3AlkB*xCL?Mkz&CXIBr>z$ENM{_TBLMMWJCS9_o{>4B%7@>4d|=ZfM&lH%fg z!u&$N(bd$HQU!ZLtid*Rs?PxIB;xP`fwofOc4Crt*0z#-lH$Vle0GAOf_$$8B}Mr} zYz4(_gamDbBm`~$`TjFk8|b+R{PTU=|H1dQJ%A(~w08cV?&n-H&t*qS1?WlQs_#Ek zN8ir<A1!Af+i!7^vbH%_0|2|tIsffQGx&2G_&-g7Kks`x+L1c_@5sd;Fi%%|h_|(e zoq_|2TK}Qk36PK%I9J#|^APy|Px1G&f1}+01ShQ+=gohuRiul5t#)=`(h}!ETFdT^ z4Rn!_jR&YcQ!wz!Sex<op)tgM-|`oi_anQenx7m3d78wp`ISQ9mI93eO=k@GXBoOL z+mSEnA3ut{I8tym_nExk?R@X6&(rQh^ol2a&n7ghRK<G=g)X$gR)4WiW_r}xdM#yn z26YK)j?(;IbIClAqR0p0>E)VU<JAkwHh*sZki5wFr}h5!(4WSOsF3reos8_utIMK) zZqadMU-;enboT<)??y=HRnjhS{(Gz>f9ZGQrO^L*U4@l_LyG>w7xG)Ge3$``FFY$X z`!ks`y>IGOlg`^)goI?|r$$NNUyWBC`7Ijr>#rx%{xEwMMoF(5!Z~-v_YYk{mNc5U zoAOJI`B&G7Psk7G;_B+^P{>}yMb;tnMu_T`aV7kP&KIhL$lvfG8A8tC&78iz{-ruU z*`>ViE5uhEeJGS4&sMETk8E-?dG4Ccul}2=Y_2|&H)sh2{pqkiwVHGz2`*zwh`i_4 z(>E6b-rpMd4MSGv98bDh&aLJ`65#R_qFzlFBm_S<GW>p=9U|-;PD#tp-ZTS->U$KB z0Fv)q_qp^3l?CS!sN9_A>p{7c@@v20Z5NfgZ&C*QgRO3P{}(a;Olgq?>9=9gBI)%` z%de)LyPSw^^4pmaIvlO0B_o^E>Be38fyM7;yao{$^%(dffIY<(l(mftWR$JT4Sw)B zCR0%D$Pl(oCw9o`leYhxz0>1VS(6~ca#)ZefR}0fWl_mKD--OI>h|82aa_B(RRi5Y z)EmPA*4g}%qJ9}n7ILxN!?3h8MLW$V*<E32FmwDlth5m~{P8bZ@5N^R%zeXVz+hVP zEczOwOwjuqc^?m>eN@D@-Hpj~KHMT{=!c|~=ZCfvG<;$OcF9hqE<vy|%pHg${@%$G zX!s)kWZn)?EA*n;OzxFB!e}1#OwOUij_%EA$D4ea#qZL0!2aR43u6ROI%cqDjQ#Ap z;r3Wr16xQ4ZqHYN8hx#%QDHo+{0?^bKy!)K=jgrPYD~I_<>vgW=zCkGTE!pzM5T&= zPSm_Lb1z%Q_~)m@=t8;<j3~(Djh?#dMn{VC&A1vDYzp@djz)NvDmiVY+aR`WbLVL* zY5_1kWH0Slwz)eoWq7L51!lx&Qclpf(uZ-omVzqJaQLOh;#yZ(amo<#i-vh-6sR5E z_|o!w$IvRHOk_IULPSgTcOKy>1II3|ZP5%NeBrBD@W&S0nO#6c)n|>@5cf=R=a?kx z&=QOH8tn|KT@qlUC~oo^=Nu)Ai_rC<h{%jHM9^c^yH{wQoiA&)oyBkm`?9ePdJW>y z(bAyo+O;WSpcUaXppu^)F(hI|t$!9SQNT1{&{VSf#YRA7kHeIRcko+Tl|VUJ=7%2( z;-;uuE`D&m(P6dF;cEDdUs{T0O1$L9713c&F@FMZ@)A?Aa(eUXu=RRoVRBcQ=ia?Y zH;iX@f*mE?lL-w<2lC|j@rrE;J+O0Ilh}78G}^>pMAci`sp=ig@*%e7?53XhXPKgL z1=~?6<dih0oEOM8Ly-d5j#Pg+Y-t}~#L9R<9>I3>N52ztqPLhh$ANgc#umm^HufoK z(D88V7|0TG@q1QwHN8lMuFaI@gDFqrj_=dbnyzg}wXLR^+NcoxHB;h_aA%4hL2G75 z^pPOHWiJUm&ZFCWmfLllC6+T+eJ6#lE!LfsBspksm!;y8pwqVD(*-fmx3=#sDp%gy zR4BZ?U`uhnDbO|5AB&umFY055=*CXPinhVpwaDmb)B^8HsmGPEjnYXQR!FGmM*p7M zLprkYx9!SxydM23nwaE=&Xcl=8!g1DR&%C}pw7Ti!hlm{J(cmf)@Y`SgGLLZry37k zGkISn15Wezz|$4ycl$mvOZg8cx^Kn58tmkey$^$5=z2T?4~%b@THf;u+i_r(VDrTC zxJYrGv%=)9MwW#C8>5OTc2)R9RY`k>1e3TT0`vUQw-2W##0anX;DigdmlQLqe)jLd z#JtgJ$jP57<)vaPW&VD<dM87U&x0gPnko;9)sh{c4koHx^sDJGFJ3eY{3f-xx)sxx ztZb-A>nQH7q6A`X$?L{)j+nlv|H(Dl#sxVXwzaC+bLyi8OW#x`1+5FC@TF4Ro)_O( zp$o;#ufpvGVn_OJ-*KlY!WO!{t+|Re#(*=c`E?lR3!rT$aQA9s&Pso5#|a9d(9l2b z8Hq(`i3Fu(O{2F_jVrHZna8qUxyPa@Ufy5Ap1m>bL;S4gfNn0kPMC0d?+FA0Cr>*_ z1H#>pz&KP(Yp+9<*3=wmWXonCrp@k(kzo_d$?nUhUP`sbA9v{s#6}C3yPliH#|i*o zxB|0L777t*dzg9IU=euKE-%VYW>|9}N$-buhr8LfP~}`Xt=`@$?w3@c_^Zfs#Tk;& zj}Td$1s-mgu{sUJT#sRDZbx}8UqwZ(Rn!^n4S&;oOLM=ccqj1+6qd_XL^W>AE46~8 zV+aJw74YpitR{C8dtB6mEG_n!>a3ej>kc!TTPRC=0oujo>2VaQedgl5`KKAxT+96f z<SVi^jCC7@rvO}$K!vkh{JQ7rIq$5uJ@_!eFFrpo1^x)J#2GY&_Ib8yRd;EOx8q~* z#?G55hq9<yq=U<$OOb`dIE<Si;Je*{pF<~c)~d=)aoZuFM=yG;Dv)Vr`19-ZC4sqx zbnNh#z{=2?4HFD^dAh6+Q7ClG_mRZ~(D?W_Joc|`<W|a^DJlOra9~c$908K$!=#kL zIF?x3&su6>$f7Ft&HV_rn)ouj<Z0?lpcM{ZARzDD?FDRE)G*yR;48^?qr*pP|E=%r zjQjEEvs*|P!hEk{w(zb#WtoM@>a57XKC!)1S1R6dd?8y6K3f00v8`IssnBsjp{f6c zvY=hs))X@_FGkv*;|gjmdur=?m3g5){;zm|f*EOhz&ix$gWta&`ADlSc2+spSX{c@ zR8kACb1sMxbM?R^JSh2 `?iJ^N`b#tbcP!t)soON&mAqTcJx=bKFViA|sQzU|wq zJ!{a~@+xsmzzD-;dKp3(l=u*3nT7ifD$-)5%^KBtXeZR+Iy}x~=+cig_Ux@^=85*r z9+k7EafgbIOM4b+gpS88qBy(EgKgz#k%Ay(rWM(xi;(rzO3{Ht{;>vi#AuL7YqQ0B zEK{j_q3yRZqgbhOeR9DO62%40v1Nj&t(h+U^*&WI^Gx$H-Po4m%Dti%#wztDbpNpZ z#+5@HIJq*IVNC!?+~^9(-dyT(YF9Lz2~w4=1JxYL9+l@-q?MqVYwcrZ!IB#KX+A|( zJqwaAgyAsD<Gl~&(mCtXr>%>FK30Ys!OF1K>9Eh$@)r=EYb`N;JV00M`Lkn#q@(DO z-6bZT8QmYhq@o*x<<sU8=TbyYcjykCRUG!EYb=Ix9-NIz@M<7#tQKPSS_+#Y_`N6F zY?!R1{7Vus+c}MUXF{kg;L_f{SnwVMAnX-?1-0YVgg3HV*QOmxQAV$(3*F(&tMu~% z<X@|VqBb?(l}u$p`aQ>`7k4-Ah@SpUbK34%Qg}l`LK5R(ga%xK878L%H8%S;D&1JE zpo)+3kX7Sn2JPsVvcz%+d^b*Od|6-#j@uLIyuBxL`pr#w>u1g2>d{X>aQh9a;+1-_ zY$d3L&yH@O=QH8cl0rhqi1P+%Zb3U7(Q@pF0H-WVHL27m4KG+_cALMmsviByZw_MB zV$3|O?(tGf&xD!9iZW$Ww(X-^U>ll<^}ar?Wu~R02li+Y9C2^kK*S6`EvwQt0M5yg zi`D|*8~bXH#Da|wryg}+x{WRk+dT$}W{`2q{??}(0*Uo=r(zxf-v!JB6_h)~o!ml~ z`c~V1`W>!r`N7?B3Dq?llhiD$88|Ua!-*JQrZ{@bTW3F%-3p&e&oSEO+S*^-MZevj zG$ID|#%xbX@#>AzkGuCbdmd^l4<<A+LrTYQMxQy=iC1RA&9H9hJCY4r!E3^H;b_Ah z;gK9s%wumeS3<>t&!C^hld{g8k1HGOR49a}3prylv%UvKs@_Azhnga$eM;1$RW;tB z(4lMve1gA|ZS!luRO?RE4GxWHxP#@q_>YPE$W!Y?n_{ha&veB4rhU0ts$cLDNk<gn zo7_f6b@|h`OsiUY&k_j2nVdazMJf0u#C?)+)3ev;(%}>M1e*TKB0Q!u%dB9I!U*`T zsf(Gu;5jx**A|ktF|;J^H1`v!_821{n9(&oR~kIr-XawLO4L(<8MUrAiTAY5u*}8Q zcIW;2Vn*+x#(y(|fAcf3#0XEB#thZ*_riZ<9P5RckyS8XOe>p+&A&`z`4e|EwTeUM zMuKmC7;uIaRmvV2ShelMwKw1BAzU|&ON0AIB-5l8m#lg%Bk7>}F6e25fqusObh*m$ z0qb(wpN(HSPp0Zd635gu8R>g0%;KL7qC#dBYqs+(C_y=`mySw}yKs%F#&%gVMcvql zRcdP1CSNZYdsl1Gz5`x&j0>>)WAgJ#>qJ_*tO3@6nM-cgunC7!pk5tFdoWMGAB*lM z8VLjfo}KK^#DCq%%Fe{fRTQ-WIDNxbS8j7atU7KHCw@U+p&)?$!x#9}<H9T9hNFWg zaKFu`7wggd-<4M4cU~kw);8ZCDT}oES|~c;hg-KcoTl;IIUzO=lHI=hPOqRoH@-o7 zN__@3p1RKO`<>+78JIKwek8kfB+<C96UB1kSh((VH@E$Bj179o#NU>mHP=<Sb7lAJ z;j;Y9S4O#-1o##DkyQMSC^2(i>{KQ3bbs@an2DGQ@}z1j1o`$5q@(@Z5?^*7`y|F& zwW~L$dav7D$Q(9!6f28clj7*(=8G|Z=o?n*-N#ds6>+;#TW1Vq#3;P8lgK-#$>?Oz zErNRjX^8SDNP^p_PacA@9C><Y9MpEr0W))ea?t|#ep{Zzx>E`KYnUElqnazrs9`b> z^*NLirsPL#ku^n~DL+S^Je~8a)gnmYGY(#VXN@BnY`dm)!rb2G(W6-90?brfvDV4D zUMXcvm!JKS3{~*2Kt4d*)3<GAxr>TsO;m(^&AU0X5l*0P30545JGRn|>ex1Mc`JNd zcHkU#{7elpdaP~yXsy*-bUjC$2M^m$y#);loAo6si=Cb-)V=;%BFRDMALKRIXx%3q zEAl}-L(V%9!3LXmNLUQDvStnM&<3jp#<Ab&fw{kvg&%J|3iQG9^<a)q5f=_YgU(bz zQqLBaWHO0{;G%k}In>eT*aSHd*1+b<bN;Yfj-V8S9e?h!LWiK_$>X9cBDEHXzj%Hv z__QtsY`$)tVl5cf-bIDgytdhX>(=bxjR;Vl+i)rYJ>V~pff?uRo_yFaSYKaYZ2Xk# z*DCUKu!d6i^Yt@FVw6J6d#=8S<r5Ps0(4(^r7l`Vzs7_b`r;%fC^jQINt1%xmdMzd z@)|UjUpQ~Gyk6^sfTI00t)`6x5Z8ydqIsbQ@i}Iu*u}k#$HmT}?D20E)5ZI%dW>XV z7~)X<QZL+ZzYq=F*x>D?^!4&^52)MA5=*+PV=AWRQ2Rp_nF25^!v6%#)HRtJK4RZl zlPy1WdCf8Ocg$EnLNh_JJAZSfcXlDIcJI^3K<I+m!)Fr4NWavY<JgmmGrrl}kZmN2 zIDqcy(jNB;kP*_@z*^~Bigyf;+U-e1MtOyD*AZ5d17tKz2N8$rjxVkeF)`e;V7Tpz z@0CwSqBNAAMfAVF)YQM7XmIaId2Ui~4|cEa)xOIpcF**3x%>qM`Gm01wx}Whfe>~) zE$Yj|mffH^y0on|3%}JDY4YC|i<J0GRpQhOI!PzUu*Q<sY`kfkQgU-UEqF~ou|dtL zj#@9YFBzLp*2VkFNQ^(VuU3U*#l*2v5BDa#6YixZS(jN_fxm9w&0#qyTDD9sy(rxl zJbQcKGD1a8TIFS^-;K<Qhfvt?jAF7A_F$jjxdhYuD73%arTvf_2j|XP5JY;kwA0-! zUW|<$gPSQb8%NB@Y^W0M<{L2{V(9sepIutOZkZr&HqF1-PY@7o+o6xSLrF%iwu!d_ z5<E5aVQiPLz`H)|L$>4vsIW8zzN>qV^2o#w(4}wG_kL>VOwHbE-QGAT`(6XirEZji zZ>5Hc#Md~@+&tguv(%)t=-%tZ*2%`<zghS>g_W4tDEIQd`n1@X(N7`1QeZ3#C^Bqm z)id}7DW4KiL2^{>{GAN6jQg4<J^X;}YLuIAGd&G)oQJBR??HxJ_?9KKX$2k0t!<!I zndUHx>^CSh;tiuW%?W%ES@QSl{tmlDsfVYcsk_c_5$6MDdL$riv-cLsbI?m2i=r79 z1Pl>;O>!z1*L9U0mNR9XL7+t0Gf?e10}3V7{LrtW^`PB7fF<5u<>N*8>M#~v#B|6w zk)JGkx)zc~m65An?cj*|f(FN8)W@F}1<jO-jff<4J!(D5V+`h0%agswoww>>dIr*q zW$AKg-%s9$FQls{)vsum1GchzBMPy5)00lSo84Guz^%lp6ItwF9JbnfrJR<&CSc6~ zUype!zd*7?)+7{k3&*z0VR{ra6)va#QQrpwA8S5Z3U5%BYu<TxG^n8p_pS3AYc?yK zA--v9E?oae?L4AB*zcH=4r@_&E&qF@Ub|@3vhFKN7|AE3v19I+S9ln8;vW?r^t045 z?_<%8bY8k*w6-SdD8h8Pv-?^3i{oT1FM))hW!i0>zo($UVp{A;0k-u>_r6e3{-+qw zf{b|ml_#aWdwOHAuI-kJ_awJNXNUqgLe6jgn@MNNNT+a;p%McHRUtz;2NzQ@_J<{R zi~L27v7f^)E$*H+7-b1TUlKu?&eN7(J+8r;Yk^Z!9Sr@U3q8Umcx;u)1wPnVsRd7w zRFIcX4O~t0RAo*gGg(|2q*-SQTIXU&J{vjY3+L1~++Zr!LReV7|8f<2_g0)A1>(qY zb9Gn>NMlI+67^l8puc<UlPXf<{Ut8scD|sp08d?eZ%Hn<ORO}UgT7#UvVrXa8}>tz zeXqOSPCRGcpqbzI85EZp12p(lHH=;@_(OBa7QPYrp`RnzG2O{s!ZVicq)NL=V$?|+ z%lkk|OV9kb0&^NVk4_K^xV>G5Tdy5@#LY$Sc66{HH{qY+0zP5O8myi)rbO%q^LLb( z^?5NDEAvd|e|w~9o;C7dW?DuW=B$?3+)hAW_ioZ$h?de`De+pLeN!arI%QxHKR2Hr zkuET$G{fK6l5roHN>|pncKVg<lfh(~=FE7JARKO8surIg7>sx02Bja?&#k*!$wu!^ z%+=X7xaOI#0_frvp8$FD#F<Sc={F5yyVli%o#7+TkaskDnzK)W9jd3nN*GZ%96D|v ze-H3*ze$$MArGn(-}00p>_KI+LS<S$lKc=3$>pZy%{n9^3Ia-Eq1Qge$991ViVo`; z+UK^L*U}r<3SQ<Twac$WK>}jR?^aYAnXBGBN>0=3tFu%+V<ZoCc#+&+WPe9Yh?8Np zhVTjVe7bF2HX71}AE3a|R@5ENeq0yg44hT#gKV<yW5m-4!(`qL3AMtFOT;st<`4IG zhAty9^Fe{eMZvHicXQ2yLasEf0)CCESggA@d&LEpj}RX}9F+ukCwi*D(uev8LQmxK z0K_QhiPndD=tp+%Mw9Qn=9gd^ZE_sHyt=TjIV&3ni(RWlxeit7b2w9Z_qb>N7N2kF z1&p<5W%D!7W=u;zEP#b^eAyC-aYEO@K&z7av}WRbLjd*|Wmr6C*yX0mnO|_fqIGci za-#02QURyx_pQ9%jfTJ1UQ><bsoP0(Y0IJ3XLS)b6iIr3D%CgjsQBCF@xsEh!PcTf ziZHu-11cr<wxFc1`yR?R`u4uP#q>!XNFHWf@mJ5&L}ks(Zd5cs6umFFdAz49hXg1z zRO&`YbrncAB^BL4Yv9wE^j;;>xvEQUr|PEH{P@5<w|)h*4QnLH>&?fOrELk{zoq-{ zj#r(;8`n#T!PB^0CL5ezla7Jg@EOg0G~s3F$*h>^ik+>`n-BfPa4&DkMy>TDC*^G$ z70Q%mP*E#SMkG>OEKOWJ*nh+Z8hE_2XZBPg*+XWaSf8RgNQUe&Ju7SFPJ{$-6(^a7 zKxztgwlo2x*7Gx>9LhX87{P6cbOK9{wZP(fdARio{$%&vr#<g()Nv=3y!d*;Gu(t2 zOEf5}?{h!-+ve}mmek&cqrX`EHI!R!81iR*rT5Kyqt*~5qaww^WYJVQskv^f>Sx)n zNDqDZbs^@5xZge=Gw)(KG<Msj2K?Qdq;-Ikp~9$%J2b(vrmN^O!}<O;$XMTp{_70< zvx3dJ7)+nB$7L0z)LQt$y5u$9B1#j{f(1OEu#Bz{eEOHKpo8{MBP}ndYSKmnpkr1% z=K(WUZ0%cR$iwOok{8hhV<b5>jA&}Czy5G^b6LbFz8&*~-=0$m*ugI$6xosrY7Fev zKfS5PPgC&mxGvPG9lFTuUA=!dX=4PRbk9}P|K%kpXn6xHLjIljq|5yaR_;WQ+nD5y z#xdM8R_v&-*auejB81mXmh>$PGK1@ch6h3lyOBIgO9vg22czSM?&{9#g@D1AN)Nqd zvKF{a%CxcueMiaW`NE&rErK$3B8=ch4-zhAXe(JHs~0PsxB)vY`LLfflh?f<J+jrF zVI<Dup#GlRyCG?4!ie5Dc(N!4L|A;LiX3|aoY3dTcnG0|K6JC_V)A%->;ua3mUH61 zUVC%BD|x6z*m!M}A>BZh>1b!)!_#5JMl))}fqD$(U{V9crbe}`UHTMnW1o^L!d1}! zG%@u+k%iT}N)PUHMfKTVd2hCln*wE>N4t<N^s$*nV}|<WBeF_MZrphpv5`%?@fuPr z>D4g((MglFA(>*E&++EywvxVEEp5NNTJB0Joy;cX8?D%<d(gHyWd>ymKV>~@<}wtr z)IPXu>n<EuyRIc}zyq6PyXU|bSHadQT|`U2;qy`#wyT5G7PgXd-`ScURH}2Phx{te z>(hTP^^=8`d+$I5u=47A5U?{xKYk<vbZT<Lse9Y?+PKC@nR4v};Sj28hH_)BaM;mT z>DJU615O@aKMko?-zox_3qL_^_4C}fPG$CeN<#-y8|Igo>@8jmk%lgh`bq_Go2GL$ zm-8v5uus*ZgH6ZxeF{r$Q<2^C?9$aTseAF;RNc=VFSA+Q8nR_4_S*9sxI&xS+oIIC zr&0nI%9G~Qob-&(H2Z4o@pgn|^JnyRmF`iz8{@JK-8Sn}9%@JX_AQB}A`yC^(<W(! z?$wh9wV<-_%8OwBqN+}jvs+E^!-lqGXm`Fnr-R-mkTJoDxs3fmDcn9un5XrGVn$+n z-=K7Uz1}lWxE(y~5?-^m#*itIL`dx1yIgJ|*>MsWA@RhI4FUYQT`;}ivqoEiLkXWv zNL+f)EjYve0Ag0eqBl>YoNiXDUJ?DV;#!5sW72sIh1WD}(6bXO(brpe?+^6Y;1aE1 z%c7pBzP*dll6-%lexU%|vn|3?`^;!#k)sDALg~9bFgWAzxI&+6e5H<1G*5dMu9qCU zsxt3tI=P#Zcz<=^=z(Hn%vf_<T48$2_3;;OOjH4gGPFi|E`#)7k7ypkeVE3@TvVG@ zde`V|4;-#x$2Q84YHsWBk*mYYl>XN}s0SI%z00DhDu=(C$GkM`Gq}U-4Y&abp9_Av zK>QmjX$f`Jx7?Oths6D741Aae-eTI6?(Ao#1!t?%rqU8xN%MDm6D3@@bJPqu%RkKj zRF&@)3=!>oIP<qQ#9Vb3&IJGErCK|7)Wm6bZ~=1s?K7mVKn6X+C<+3F6I{t?boMUu z5!YP;5!m(CM-BO-5u;kInSR~R0^aBme!1Cww{*La)RU{T3C($t!lPnZ>)sS|w><M} zWVJ*WZkK$XwpwMh)>zLc2O#COSd(awhRVwBc5Ty5G%-<Z9CJ6hzu@Bx2{O79Q2+~) zR;M3dslKhx*<q~kojlV@$h>2zRz(h@yKCMe=iD&RClUD5Ty?~r_62{AI$F;U6FReB z5!8#<c(eCc4@RAkX8(u@w!;5aKV0#b&gSHu8ZnR7n^u&1nMV|*eGS8Y-e_??^LlM$ zlY!Tb;8Y>a2m$gErMjC{$gCW`oh6VH-ZC|--=Vh6bLqrDbdXggGCrr^0W-1-V6H9{ zDVwD*bo*At!`SAWhf)QKPIQjAenO;>4U}!$DbV_cmPL&W2TOl<;<q`IEKb#TCL2s& z#FVMh`e`WLj$wBT<h;#$d>ZmgKd#?3L>-HZG~9C2+ek66`I-5g8wneC(hq2^b*bTQ zh|pv~baDxr$ERORVo;$}73N)hq*}$b{AEBahSeg{{2^YOsm{sj;VR2ii`)r*;LgX# zth^y_dTNcG+B|o|S2ibX!0+SFT7pd)F*nZSmE$}yJT7t{wiXk@-_70%;3@I&<j@o% z{skJ%Nou~6w@Vnhf7oF%@`L1ZCrn-6C_&Gh7)lL~wWeOL5mq3b+N9eyO2^sn7&dG; zHA-t1<A=ANaF8V8=s=a^STtOhP}@<a)~O$V&UfVY_hJz@kFOv8qVmR|N8mL5K(uV4 zU)r+M<IyQ$e&{$Z%;ENji9o}unz=)C>!q%$$7C6ZbiLYSxTDwic+j>jF*S$?oBzR` zcPRVlpg*w9@%zUYL<6USCMT8W>C@$lom8EbDdlpn^6NF_fM0_Yuc0=^E+N5&T^RKq zx+Y5zdfN?w)80K)<UJ9+w^j_fuH#GIlNJ&4X?*17h4|)!I<E|O^RhCX2YGGPfANgx zCtsls)?#kI7hKaN;i6h1m-;TBA+>)<!`?Q&N~|xzhFBfhG{5YkFZI?kj;sQ3F|Ggd zxH}CoiH3n#di1s!pwL$soW9cY^w}!K0$&%sfb#gR5eV~b;d*vUWZLfI$CF0Dxn^3^ z7D=H%p)T{<0@Kp0fyvCm)l~+T{<>Rw+M26=s*B{&M_{k-tZYK>MeU|&dp1#lbrRaG z!e-?PcYM`_sWpe9XxA0#Jh1{XsRbiEdiv0f&G^I~8*(>`M~mQtu1@G-;Olf7`;i-J z?{p6Xrv56}u;J*L&hr&9num(;&0n=iyj#G!RG}TzFEJx#euu(nxByU1Si?gNtHBnC z<&)N0tdtt{{#v#r;CkP&f7BJx^3pUy8g5n~rntYuhA`*3;sAut;=H<UJXby)a%Gy4 zEoG28=_~aM!qGA;P%I~1pfarK>4=%!AE+EsSF~@Uy5rpWz88yhKib4~n^Q9lL??+X zIS?m-iNI1iv6;tny^BSrh>U6vlG=4oXIV`hkJbBncR4J=uQ4utbuwu7yB;e$N_{3i zAe7&~Tv|)maqYF6XN6TO6LxmnNbwiA<`O#Qy??DR2>bb?hKOab@<~Z*8(9Ah1DwK7 zEWR#(Xzxsw_J{4anslk^lWd#XoMn~3(+&;3X(o=!FSm$C3me=|^<G<vNKNJGjCiDv zOJ8)C*gLJ&i4b5AjuJ$bCv|=jHe*0lBnTfF1Q=;ocZmr1?3iT5n@bfbUh`7@+Q?nh z*+Moic`;2xvhr20Q0H<r>@4X}Eft`Ec}O*!FiL4RWj9^ymF~w7-w+TNgfUgIyj@qw z(gxeL6A)4}Lzh8!Kb2VVA{Cx^y9n`M3lwIqlO%yJctf(~q$%B3MZ03OxqLu9w^rD1 zGmPS%6)u^2_<V@dOS|(@(SF-}U9_WgmAD={ZmZL%MvL92p&UO_x2JZ}Y6XyW+X?T* zei8R+l9uh8Taen`G9Nly7wXfFx4*f7*Dt)}9yOL2hlZBv7xk+L>N(5hGQ4FO^{HD* zgrbNhU2B?)gO#`j2IY}Z(V`mLT{bGLIp<Lagz{7R`f?r@?_`bZ@eyMZ!~?vePdJqW z;>R|24@FLPH|G?^g3zvMJIx#+KmtzqWDn`Ycrc&fw@0|0M!;M|`nKjA32YdyLqmB; zf{Oh@Pni2SvD-Hh>xev?)tuoaIVxs-oJ#l^TDbu^&Ox}%U!Uen>afR>3(IT9W4aq` z?yHYaY9tA~-e8m?V5b7{)$~_k+=`rb1}t+>8*1*jOj`L;=};Q+yJ@O@yQd<G)3D23 z&w*(F4N$_W3n|WfX1SbG6kgPN@M9F-G$$e=q;|G?7D5VE!@!;nwPzX4ta;lOjHd=Z z+YW~j??)uqh>{WkDA0r=*uN_0hjcw8jdb9r9m$C`cX+oSyPOxt+MFLw5j2kWj5$iM zvdM#se0hgHCSPge%A7o{ei(T4&N67h?gUHC3pt3t&#jZhgc!FGXf4>E^-<LpM=m|> zFoc(UwC;WqWY8pXRo0`xRw(RlJW$E$?B@+X8~>`P1R!{Ht&$E@*LQ&=%8?jB%RA#4 zah$}u<uv%ip&BuY(fv==T#p`pcfTR7sLo3?bv932jP+4w4U$whvrv2GE5o5LZttsB z>z#blO4v61qnEzyy%57<g@my5b;gQV>X{;v>pedZyKg+Y^%I1dyJ`3iTk2AJHq<LZ zOBhLpt$fqJB+MU>GRDE_k-E6{q1{SF&aS{_YNEijaha=N)jEORg%puMec|?ldTXCM z(n{V+gJ!wvii42f;ifC0UIQ<(leq4naQNpq1I*{h+gtHUE$%wr)D{(_QO8~64&YPe zb*r^f_ou2s4d{)D@*S_9M{@EB%3hiP&}=bWmi5LcF2>byg-FYYZYc>jUdawBf15BK z?INq8zhRYHp;OGs0L>cNEJ7FWFZn0z&%jSw;FiN?hfA(}hb}pDAcwXs#-Bf(uKi#X zg2VOq=?-m2^(;(fp8=#b_2!K51`mQN=}u~Oj@0A|b1o%2EiXxrmYbgZ)F$kOH|?S$ zubZBFaUl-ZKN_qm5yi$GSY^vo1zKJKU87_cMpd+_SIWsxg2&FTv=)2FMH^8sC6=F} z7*}3{qDLxicJv!au2Y{o+Fm+OnJrIM0_)@|x0H>RPh|OaKUX_ebDmVc%4PR9A9{co z8PXasTvHaE%amZg5YT5#Fm*^~xY!}JI_b~_Tv_sGR?IYwGV1y(ey|)*uq^-{f`ZS3 z5-z3-$IU8JK}D}&B}Do`6C=)g&wUDnXM0|wOMo2$gfTz`<}$-FxtO7MdG?t|CSk^K zSrqU<bVP(BYv_%o6*tKV5AavcZ_Xq+=)cF!4;nB8ifs`RQR1fuZyugntNCfRieXms z@=q8HQA>HTkhPqp^MHtw99m;et)O{7VQSKKdL||Tk`C*`swK7tZ+U5YS2y3VIyVhq zh2`|2t4crcu_X?8W*!VDl%Ar)Ud4<1(=#E`#$G}(IwpLr7^~Y7>236k_-aa$n;@>e zKA98kf3Nycn2~d#J)UV5y{TtH{jNv-If$ouTh!(KRN)Cl{-O!NyszSeA6(D5;nhIO z6kwsv&&JLIwF$_vN%AWi3*540C{lysaJ}oq!}Yf+zRA$X-rE~_18(YiFDL-Bod{Wt zjMFSh&5iyK&3$M?<gN7ni8-mp{ghW4s+0zK75MnKiRU4?+&fDJcS?W9<h;O6n5mh_ zx^$C)?)=eUKheH~(sHw#YVjAH#`~+bX+xYMLLTyp%OQe5@IpGK+%DNeizSkU)s^_@ z<i4r`-){f1wO{?paKGZkbQmMT@&0rEBvMvINnHAyH#v1riZEIl*p7#lQ-9s6ke#C| z9+Bt}d)0sOIWwl*uFH$J<gZX~R0T+%7b^CnYDNjDi-L*$n%Ng~=px6PiYPaspKOQ* zpbi@ZMAzb!)~VO5GYJa;D+v18(F|sK2yoCju)6EBCCYNcvA55H=Ae(2LDm6vbe7+V zQvQ?RHBZiGCV0Q0TsQz~cEm-{fi*G!Ov&gPS1Nuo2G9DIN!6MKYfP5Qar!>Lfu65q zHCQ2U5;Iu2#7H_d9?`dTpYC0c0j61?2^CX@is96T{%2OAJEn5k0rt<D^Qp1*xyiGc z@EmWiaV$sMcCk-B(0kxC0rk$%jj2T#8qO1VkT&P5DaFEd4V07h7G_Mb#7})DW4=)? zNYaiE5>18D-;IOk&vxep_E$<zVsf;ol%a;7v^fAf_^uHf0bJ<`KaAe;XQS)<qZX)g zlv2RY6_NOTH3&o5JMS=D=T{hL@=bB#U_v$>PV(S+%T(tMgCVD?A<Ot+96`)_XztK9 zq0b>Bfkb1!wa$om2b;uu2%Bbv!FgCims|7hd_Xi~fQXXo>D^RZi$I65ohd>0tsZ|L z=6v?021`qWq8?+Aa)`w&u|A7I=<%8VQ#LE&5qYt0!uR!!8e+-QE(bykMp|)<?XAZn zL(^L0WXd2oldgzirSvG6=jYQmYhKFx{Bx0W2Y<1$mQK7-Mp&ocE_&iX(Qpv@r1N{B zws}k7v0=U&UFNP!5ZtiojlDAS7+MpP_+sX58uw%zD9uSR`KBvcNi`>_sv$~0phS9i zB(p&5bQN2JYB1NkF#F^Cera&*VM%Plg$tBa!Ze-(V+9@Qh_3}%dES$ajYY}=s5Z%k zt?=-q4{i9AU-&|`a7i1c<X>M*klp8@qEeCxl<Hrz;o4QpWH=arA*<l)5Jg_}r`jHy ze3A5s&Jil2M{-=TdRrdd%raW>u(Oz|HQ``C1Z8j&nCeX4a#XynB|T??6<0^puC!|+ zX!K;{I|Hf?Ue<6e9}fejymInE*n9Jn6rc110-Cj0r+*P!r^{eIewBNce3hhNXcfYh zjIN67(bmE36Nc5w#)9`fSUINA*2a6DRW0jK9&m?G%aa3r<&B7Jy2c_aYN(5uvEf_& zilT$glRRb$Z{S=mEn~}ew&kI<sYfhRY<)lwP5BGm=hu&Hk5V#d$8CbbUh>9{ugl$; z8&u{B4!Ux<q;Qn6v4iKTfI}Lpwzqo@Jo#m1EsdLxg@Xq&D~EsPIV_kJHY-=gt$JEY zb?;Rk_&3D49Jzn`?s`qXEBQ(R<5VK;D7f&ZGhVr7GhvW$w53B`i!hn9%qn(ikP*9z zUnZ_So10Cmz*C}T6e$+^1ZBpDxIce7YU_(i{zqPCO)5^P6Bdi!y0f)S$z6~h*eoI! zlutApa3<Dtg_ANgS7%Hpl5|>%WH-hI=g9h|^CmZfi;^5Jj(PnsYpixg52{axZ!wDd zmIlC~BR`Z)9VDB0-2mK=7~TNW)Sbo6($^}Ksngaz5qspiwV^m4(W>f~b)AbvU*x$z z*^fGx-!Tw>iuCv-9UL4?ba1c&qmzR}8RvbjlRdWHNf<{Oq8@Y6FMGK6H&~LB5(I_b zO95BE2@pEZ?176*yrMfhH|WFz3=8d84X^huYE^u7FagIBiAcFek6l^Yb^<NC-tIRj ze|@(j2B(|%Wx9Uo8RNu(Tl&dZje|5|@UIJKKN{M<I^-#K{BRLDjU4#l{@NO*g!4I4 zb2&OG4$4AkYOW8?S&Dk>^7rFh2NLYei4<Wa@kL!T&c}R3pttJoKm4E^!oim2k(b7I z*fQc8l&>$jCXj+Xlgyza@(PNi6lwX_dQTDlZ6!i2Sc7AtBYwjD(ac}Z`;6=A9VkQI zJZd(wBL{0+Y@#;`r$Cr;Pc-?bXgF@~kO}wEwOn1GW~K$yy6#y%b*}_#hT1OP?`l&B zqN9*)-83$jvFZJLIa^vSU5yb=p8b-Il!BifvQ15?pZAbFd;DRD6CC}P!&CIy8{LAU zSwD`!^n_q@+?U74L6N;T))!2ul9)1diTqT4b6Q;=N;N);ER_CD5yA5`KDLs==3DL( z==e<@X-8|BX!_W^UD!ajed|wZztiQq;W=0F(S^R`1&eO}cUiAh3$9kh&-^q=j>P70 z%{t?Y7gF9YUg(zlQyuVl4v*(^-Ec<ch2Q((dxcWg-u>e5H1hG5H}Uu9A#_}axBlGt zf2pwGfBVXbt#3WhG|}J|FIfMg-yX+d;8g7S<v_Y5wgo7W<T%)Q#iKndy8~nFL`t-6 z05vIVogXcWwtcyNbC<^avM9@wI)`#`{<PeMV5^?l$XflwrAof3`je=?qB8K(ryIU$ zo57XK3*JSb)vyc~4rOP5LRY=X;Z_$^D!!xE|JO8pnDO|lC|~C0d!vW**r4AXKkB~f zSoLyB(*@(Fa~>T)U3X}C15o(<`7<e**f3zab3R?5(^91YAUiw9B6Ruytjle6?!=jE zGcR7wko|BG?pV!&yJg=kTDP)ff~g49zW=*l%8;i<64}`z{AUHlf#Ll_jd1*`N7wH( zdv&;-qV!E8)+5fqgQMXwrgt%8#dRF|wZPDlIrX<=;@{q0xg1)0lAWCYJ6S$oHtTMo zx8HcY_W<h%;x>H&HrOIhf3HkLUS!#x`!J<OQqN{B-Jr~EaW$nAJZ!<t_~;R<|K4vb z-1u$}+5VgkM@-qL>Fx3a9?tTpj?jjc^abNegDwfEj)Yx0LhS5Hs_MCwpA~!e_^8H@ zhjp0BxTc=+kLXxPj~ivXo6t-2kM>(kx;+1TN={b3OO`pWJl!7Thu`-5r1jDg@a@=r z>y!8y!bE6t`Ib%E@KjspTiK`9_dyt4%3j~qKUCJa>L_d@m)og+`jL~IPSex4A-u6I zNKsYD^k6t*%5F?A!v6mDHkIx-q^kO4jrB*(+FxJcdX<IkoXm2c4W^P(PHIUs*_c6y z?RJ%)XR70jR+1W(wY}<BP7*%590qOvc$^F$b<IB<gLo>FEN7AI2Ji^VS!|dYvtoDX zvHMr&yx*S^7n;W;C$->y`ADIso_rtIu2FLDI{g%5Nw=eZ4)cb=Fj8NXm<_NynV5@= z<E}i2K6DwmMx4;Fcyfztw8qJMJ~ooy1mLd-1$m9*lWHBk#{7`xLn;Unkp6`^=4IaT zQ`y29gZ8X8NEL`9$y+3CWpfXucGU%L_GWb2y+=SU{dd_*h#iR{G<nZGPxVOdpcqZz zt4~SCD*tt(^XzfO>RXwx&z4N$O(y)}O48zm>-(RB`|P<NKPHXq>`#jr{9wxy)ahLA zET@9>j5E1=n;Q6R!*qQ^rr`yL@-h4lyda2!MKAhB?Pq+~SH`7vAzt|hk@P6yt1!K` zo?p4UNBJhE^%6=-p{|F1Qe5;-=y_5k1z7l$S6rWz3T}92zeE?%3kP>JN--Fi2NiOH z{uFD0Z(SB;cz3GL`zoK^?kTO$ynu_;Vp4$dt6|E>M^+m2;wL$z%zeZ4;Yp$C<*#v! z#Ozfiai{6NI|#nrn^cTrvqIm1UyBYM6>^uJzp+U1_g)R*fW?tK2|wEdL0MKUjuqdz zX9aD;6VaNICUW(0EWYJ&eN;s?cBjrr^JcRxFMX1VVsO(LtrJ_Cb?{Y-E-~n$AG6#i zwFEiK0=f9NX>K#aA~Idne@Of$GUOo#>3pG5=YyR1q&xbsXodYRv;vByGCypmu7_np zzMSdED&e7v+3Hn^^V5|||3l`Ux0a+iN_#1hM!VMe9-cpw=q$Nb@k)Cr2jMA78qVSC z4|&72Au|BR*ys~y=X2oRl1<HaREgStb1ql<l~VHrOUCK?_qE5eCL;73S~o%VhO7A$ z8{o{KWm3U1={J7vk4tnKQP)PT7V=_>Koj%jl#awuOXoYe-`X!UHvUvU-;FCxQ}|t{ ziZ$aSjVlUYnVl64o<2!xj(#zkn9CuyXwh{;XK&((YL28M(%xm_9xt~JvI$Tu+;`LQ zxbS%O`OY9Vrlei*jcdHIRy%|Lo13SyMskm3%Y2$_c(`CS7v8Hs;ZUWpj~-=B$^^W3 z4uX$<Zo@%j3ZSE0AX0WnW4%*WD@IH^I_qvuRuTjD@;T!5?xY~vR}98%HjLRiq%Ao6 z;w9z<aBP=V9H+&!nD(8_QTy=~2|aIGzC50voev}<FS7zzOZ6|@=P@gZs#e(y!b>H* z4R@aTm9j2<Ufq$@KK1;O?T&Efi_cGaF~$QJOVLFZ7wn4TJW-RBwXoMa2@@juV1Inb zjlbE~<ZLlBnrE!W$Dk_Jpf%T)RZ+gAK{Qy+XDQeRF8-Q1beYFUp_j;$f#1}Nbz@(H zAP$M_T*wj1N~Okhx8Eg(Zg1~r_v8$DUD`Fe(*>FQK5KGrYjT$OAe*4U+mO*1Mp2<t z0%YkDsX;Q{Pv3B}Vx0{dpmZD`^CS7vc{Jh~Jd)STsx{`sUHf({MctXkIrl-IJ1fRR z?<=FWOS(`EPvvWC@7!{)%qkz#d=N=q*a#q*`oHsQ@r7@gu$5dJ<&|uC2%fMfV64nf z7kmX;HCA?7%I;%Ph#T~-;0x~wP0*#^HG$wKBwh2MI}k(8o5c*WmVDh|mW%MZSC%{_ zS$a&T_3p;6xjDN!>B6a62KofoHX470&yBeHnMHf>O24yJndTB_M{&VN1Tz7ABR$6y zZ^mugC!E>cXDUiR4qU9na7wb+{MmtY`It^V$4u`eW;v%tUlbIVOM0}p?VpiH-+!Lw zd(m(ut4Q<*`mb#d*}w~gBamZ5C*v8xb*j-ROR25Vl9a($6eFe|Zo(j09`+k?`3p+& z3Aaa$6`sGPag=KRIN=#{DDe6@v-i=_BxJqJpe6+(bC^iVUG6-dt2tb)qh)X@oHc^v zE447E9+z5&`pUjfsNUCTo-vT`qbmt#EZEI`haRl1EwP^BF0JO}SG(TkenXmMOA;LK z<mzB{81>qRtL@JEsdw#;?~qDgJofey3R$A9L+z$Hxay-1TXmJqxPnTy(sL2E$8LOL z?PHr+>o^}La`L#rbEzf+%abTga=KwwU5nE>T{5%3&ec7tnY$BXDYD0r1_%f}ZK{qS z9a(gi=J-{33eulmG^ntVAh+6z<MjQn^0ptSil^80lKYB(TRF&uk=6xn5*zmL`qVb0 zsz?y@IQD7nF+4?6M2s)@<KbBUOGOj+l4~}1t#K1Yf!mw8A%}s4_<Q$}ue&P=E2;U` zs;RCcr077CXUszl%ZiTVd)JThnH%SguA$aX3d3ttiWu&E1g$nWmZuAuuG*`RT(`z~ zO3}2stuF>5>3_3BhwS#yd}w(T$Vi~Vurzt4^12vAY_X<)NQq~TBdL7Sz)qiTEZjtV zGLoWHttE{l`jhS+p9}c`>^(Xv5z;f%)|BA93e9oHe)#B=s7)k0524pc!HVPx2pYW{ zC}vmssz1tqzdl@)Yg`N6y|YAsoT1kx(!d}WhbQ_qk)Q+CQ8+N6rnh5{_GYZkqzhC0 zrL4eJIuN!oERAvN!)#mI!~4IBe1C+?%O@xrrlIwEP<^7_YmW^jUv(EV6>eYCouZ*l zZ;m2aCQ`=V`2CMn@iX-n!vid$@$+Vdmc5WsaHr$XdhETg&qy2p1pnNYj$xyhF&>Wv zt~L<T1gk&JZn+gF>~|)Z?)LEZC{~>(4DFOyHj2IVY6utIYFb?BdM-9LJo6^G&Z(!J zs^_&fp@Ppg9iWIAz@x$mETWH@6?2#=N`ogr$V`MDW*`E$4o1u;A@yW`3lNRLWl_mb z!B|;xW87NVS(OQfb4CwOxAKKXGo$_iawOb28SONXKi2civ1_F9LEcbjR(5$p8!5ZK z*DX)OAA8pjIv5NBo{hOgVnwyALK|oV2fjUky%YoLtMe9u6I?qiaoD`pDxM1&G$T>7 z#_EH$*N10WXCBXws$@1XCulocILxFV870hm5Duovf-`0Fmb>k`q;qKvXV(prK&RPq z^<@4YY2!|>-}pXyL9%&QejE#k`njl51>|{noFtP>29oWo9uz3*k-s`JkedB;gH&x` z68cz`RH-OM<cP*XEcLQ+GEctby=p(b9XJ-a)Wq1f(i}5*W@<(B6`#|S|JLG{qi03S zx2QUou}V5$8{-^WHMY{cON*Mk4#^)04k4KtRIaMXS@ub5N_mo^BZ1pHShcc4R=`Xf zw0CE%thCzrXXEO-3*3OWq(P5%9Mb9+qXL-rMs@(WrHXpt-^e$7V~cZsA{(5qBp{V| z+~m6$`in}jut9T&OF$P=vG1nl6m&4bFrbpd3>$h2l~ETVEq_xjti}<7ih5;xgU9l$ z{E@o3fcLXJ;%&}hBIGd*%GC~M<vvX%@0%8ZU-uH5YLO&=@REjwOr5a^dtJe_`=K_{ zGSHM{4-}#K(7h>6Sm)oEn3HVlb55Gwe0at<eGt^LXC#m`e)~k`MBqV64v*n*;dzhq z82y@`uu@5kws|65(C%ydH5o3|^X)#1@G?aYbRTqfK!)PSJ<9M8I8~uK2`V8SkxUXQ zuG=$&8GD85gzKs&@f1!Q*6M}L!*~tc8}gn34Y?P6V*a|MR_cLfj{c2GxA6`4-bg;J zt~{Fu<nR%IHt<XNgLymcA#@McX@Noi0$&p@tO<;sg~^Sk7_N#D=Ll&gwG|+P@(RkN zcF175D~?4qGTN}L&;I1s>G0kiV_LnU@aDR+vW@TMZUa7?hHIOlhjo=1)z%UhNW~k+ zWYK4ksJ#8|3g1KUxG;kG;N$w^bOMfnv~7yZ>c%I&ctUcR-B_8Ia(UvYvRzgf1^m9c zQ7ng8d2u_|+keZ=eDV6k@z~nu+i;Ix^^r7GhC;B!rbuyrQ$?retNFSH3zsay)kv;< z0xAd28mMReps)C<(1Y{2o_{95#A8>DJ194l(cm%v<Q>T7{^uBL6>H{QpXA>7e4ZK0 z(R3<_mDp<uHQSr^E;7v~O!TVN!Wan2{b14*{^sf1d5dp}{NyEI7`+S&I`O`PO7&*C zP|VYg+xx{XU{W=&)Jah*%a)VJ-}AkKAnx3FE~a;=7!x_5GJkqJ_)J{!e$G1Y@c~6x z4|ax`v|sWX^2eI}b~?xp+#2#>XEUd|m?4Kbo?lIRM9M=W`13%2VzaAm;|{S`p@=^& z#NggI`)_NL75aN)Got;k>WURQu22edlGo|Njs~4<dYS+{SJ!~)m^ML!y0z)Db}>M@ zm$d#@3GQd%uSRx1Zt<HL*LkhLr&gSZjkk*#XQYa=ti=6>oKuoz)~=t^DTFD>I<0WY zlf}xWXy7~i*=O^;hdtDLmoue<nd!%&H;vU;;1H@kZ=WUmOx4G5QkA%a6YSmD+Aw-< zYnxAByH1Dqx6$<BHOa4%QrPg#z8cZ9?)MK*!;eN|9pTW7E24?Y<maQ2{onSfhX3t7 zDu2EN@t<V>Eq(t_eof>*MU=$*|D(SL^Pe32k2qNN0Y$a>t)%+1k;I<`k4A@dtTvqq zHE-g-n8x(;-T59BvL-x>Xe9qa_!`iGqnl?@%=o=1{5NFd_`Pm`<dV<&Zy4Wq|BJsq zv^8NL?N798Io^Ka(!27I<kg<%PS{;irT!?k??}q|!684Z&-eT~yFzjrl46MimZH^` z6GU_Ev^L8nz>8xg$jZor&aN)r;q~pywtKBpQVQqa(+EdSCi^j;&p^JF*A{x||D*1! z;@VoGcWYEAQbCHBV#SNQmE!IW#oaw<p@o*B!5vBh1T7jY1SwG5HMl#)J={&tIsbcK z@56n#`;8xynb~XB%wDtP`_LNbNhtOfeBEZ}k(;d(K{qj>8+zK?;Hb8sa2(>y_i=Zy z=q5F{I9EuCN3VQF4ODJ@LHC;%@xdtaOoJ_(jMGZl=Zksu^EKDvpU<jx-eRm+KXnDH zHwD8Qo?!{VJXtSEF-(EGNLBMts8<B@kFsPVhUW&(n2k5jhF(`;JI^K$UUp?<eL*^E zY}el5D$tQJ<fcMh-r5ESvf1^JvlI{DIyM~p6iV}i{?vVg8sF$m#P@y^DjEo3xBgg1 z>UT4*n-Kx|YyOVkUV8BmBRyHQ02d^3^B5va0`(>r%uOrMm94vos+?=J&8ON0*Tuy| zl0{ERu9~(+uc43cMgUO+CrU97pH<4>-kPMVL+F`Tn?+SaFD-=;vPa2n=gHK;rJ23R zR%)X`SqDCqn&CdlF$(hXpbUCrD`?4>y_znN?{P6&ioMq9Uz7|-Fkihm;QmAJ1a8Uc z`TQkc?l+sgHj)dKipxA{m|k8RS-VGA{51w|OdcMhuWo18UiQ&s;ST;GWfP#MqPxXj zDh2L3#3c0CF0~=&`YJGK<J5vLxj2?1A5xxCVvKPe4}ip@&>3P*gCF=OG#T<*7}BFb zD4E<Ds^iC8BMZhG%WqF9yT^B+0^$$>ip2Mla#XC)>2YW*XK{ubRPqN%;Yha1zaKOS zB3Au2nSPK|@8%*nI}xl}D5Dd~Il3itpNiU125S0Jqw~)J@5HBLKt>8KrC3pOm8hfP z0ec<Cap_^#W-=584e6znPgE@~wTXgE85@7YO%Up`^sVBPeQ*(`75KCHKn_qAr=V-1 zcDTx=E<6w{>2T{Isd&ud@PMm+s~BFFTR&;hZacgj#VH_*8Ihk8_|*bbC=16*c%ojI zXQaOMVq>mmRv0~L8zm%Gh}O>Ys)wvgM}PzllV-kpNmGHwyJm0i(Se+pGc;VMu2-af zZ;$;n(u}O5Xd#UTKG05gNQXF9l{K|}{u`lFMCvTFE#$m!#c-QRBJYV7HEivT_2qrl z2$P|>*>42`^zKQ6(AbfFZ{gF9uA{9zAzFj5=pY6VR4+i94i>VeB*74X7n5+6d{7Uk z#L$Rabx+{$?WKm$Q~IIWpZ7_tib}Bhp|ovIEgyF0G@WZb;>?|id#<kr7g1*FHb=0K zjxBn3yDcB|7R*+C**rHNQ0VKlIMl3tt)_aB@levFs4pE`eb9tvWI2Xs<kt?t|Mq|X zw&7J0GXw5qM2A(*!`|r#>--EGJNIDBXQ`QhCsiZ`aBo*6j_zZaatX-ZX8%m|?aM@0 z>a!nGr1P5pe%DoK_vH>0AwajteGQpZ0pI3A)Jt&TS9_b+`I-z4)lSU;XNwzp`&{3i ziZQ;GG2gItl|hAxHRCoUwH&GfCB2~#$`HQF$Dcn7P?~D_mItA0mqvPk8)0-`@M9YT z`qa}mB<l>>m3pFWgq9zFl01sH@J*zho?x93P@0<PR7g^h0U<M}wkN9E{C=0Y=8WXU z<q#?W60`SzO#_+q*FSJMteRS*g*7Os22~2!pDnwMKqFjNWl9NSXA9qI6fUi=sQE=+ z9yjjpVl_m{^^?U3*K63I^obkjuMfWmZ5WXa@G6Fj<2{ej;Yp<Cwofu2evVOSSfPg> z^ZnW(<4-mBLvCecGeTW}O%{1mCz-bm+v4(J|3wcQlNNLH9ej1`rwDmYJD1Owk|u+! z3%cSx7~aRov>D0tzjZAXcw03z>UznaG(FrrRj2(l4Rz&@`<O_it80Gn<2m3OZI81D zQfq;H<1AutDeLQRFMz-XlhNjYd<MG=$(Uo$;Z81om1Cx2nqcvzk5Kg9C2;Q(#Zd?I z^LHyc=q8{W*@Yu1a>nb7{Q3l?a1&tm(6B*|h)9>%kTfv49#ipo6dvB@`X?~=^hB)+ z2oZ9W`8M%c?&r!Mg*lJpr$2pgPf6X!kRQK8ll4REKp5n|<$o@QfZ{UBI(NL(us2yH zl#KP|Q~|ppY}_H~vNyaBk3Eh~0C*~49h3D#gla_C&=Td)R+NkY`>U2OK`VefsrMl` z3LZ8CkP?xXIbSIJ@}+08DeXxqB@iA6x1%U};v4gyA+tU*sW($;`_Bp|UhPc0S~@97 z8zHVGh-5uer$GCwt7hE`T6Fh9UIx{at(nl^Pj|%3UCB*TmrmGUYy>x7$V3`Dr)R9k z*X1gw1hrUfJEu3A47YV(R(_PdIF;~dDS5NMuX}dvX3wF3QMp|Z+4i#X0Obgr7b)bg zek9D0t8}FBtXM0%GPe+o`~5`*#FIBD5byz$CbmD46EawRT&v9hP3#nDR_(_ma$K7c zfv}%^;0phvD!yh<s3_}-E8ss1$g@6#YPzO2?I;>KQVBnD+UHzzHHXL*tNAmlPB`C1 zNE3+*7%A$Uyl+t0^GmIh>XLd1Ww;NS-Twx%j-+yf87f_rp*4=rj3}dQn;Lu))mbDr zw`k*Jr=&{X4E>RS?QIQpK7ZydcVVg`tMp@;{6ib$Tfa2oi8ZF+Jz{e>j=~t1mFj3F zTR+1t*eniLO>`jusIV|6u@W8U0*X2qm@5#_W~%A7m-GPeQ(9Sm)=#?i`8`uE(4b03 z=_id*d*#w2iE!Xk1^B**D`a6Ihh7X7h7vM86R|ohdN9PJ3hR}ezb@kTtyUNc&yh!C zVU})aoT)1->u3MQTYKJg|J2DR_2I!!tM+T?zqk)988FC!Q$&QdC32Mp8<3G!oo5TW zHlJY&LNlZLW0;s-OE_FK-wCt^=TpG}BAy48ifIC|8|*5VC*E!pz^Q>*&Cr%6@>y1m z<Ko^H9l|S<PEXFj-()-?E>P0tGl_(r(V(6jCNKm8O<<=>w{-#|SPc3dI8~J1LZx~j zimIP6Yj>)aG!0+@pYdp6^3JCftU_$!#LoQ3?~26`YAwlb;$@05%oceglgVe{Lto@> zos-m^c}1JtMX3%+F^n81HIchQxvw~s<2Th+%jD5n{gbl!W~v)cmxB7z<L?pY?v6ei zS*FJ>PJLZ3q*+$B0gox@P~667vv@b@A(pH{_s6$#?CL1}*6{{NWWa}YqkB;9s8yOT z#D(Sy=RZJeDP%Oav8239c%R2vT#`)bk8P%{LASMYrYwIWA@8oirS+zRQU1vq#55Po zBr1DTO=!tb?{5T&&xb?U04NE6h}2N4XAP-uct~k8Vwy#K%zKM4WebF+ba_lG(J32` zZFU`0DQnlY9Y!5hjdoC;@@T(>mh-T1`C8IvhPCD70gK<3=T7%fi431>Ptlj^Fc)+9 zDPT@yeMI?aPNi2jh7b4BKwgXUduoRDdAST?6@OO@&{O55qWMC<fnO(A_kwbx#?0*9 zhfXzdZho6#^{0um6*8rkY$`jI?U7EB9Z;!&{*T#eLug2*9Ch#el{5G81gxOfmg(tp zyK!BFvBIy+Hv4)kkU>yj4d`F%dmdr+n@~zcCA^gM=Gr;TTH~_%flDu$D;qEEH)TJ8 z)mD5l#)tQ|;+P{-BQL8b-?g(lMjE5i_dTmy2~&VL@s-P0;TyLCS}eYTkW)9Um&Jo4 z$y@lQviJgm+2|d{wQVzzqTmdo0ev3xXS&{9s1BCSie*98bUiNJ%xh<cnVnlBZKb{t z9KbrcOE0v+6iKkYm#P1b*ZSJ#6bZ|SPhZeqIHEMDMS-@O`6W~d3#$_cda<|ios^x= zlfm~|+~or6H4~K6Bd;~`mTs}MR1VSnKaeMFFdtL3uFxq?@JOSd)XsPQ{CvMl^>V9y z^#v?I>m8VYPnLr~f;t%I#N`2}T8C^@edfTJ%YDa0;@op`g!PTNU&G{Jn?;|XwIaP# zAp0NmhlupJeYbG~e!c{`0*Z>cIQ93NIxN@a0rp^<YpIKd64O^n);v{ah=uA71#mhE z6mt#2JOi0(q^~d<OwFAKB9o4EeGKhb>Ohbl!l_Xwj=~<$Q+VN8b^fcxp}(ZGwi}J! zu!LYbKt7ccjGrlWSj~hF>H@B0^%-H-^=AIsRD%wI0UjlbcjYZ@XN;Z4p87QH?Z1yT zkq_#ZS638tZ-&}>g28|rvcO<!BqrU~?N6A}!49Q{EyIT)bZ^FJ@O~o{kzwN=3%Fx@ z6I+@~0DXKC;dOfBws%c_Yz~<6P1x;K+`Vb~pE*!-(j2|+<VRu7qZJ-qcndPJ6pTNj z3=(x1uZMLoyY1?1*X&fll|Fj1*Gcacps?rG2@27Mvy|5^@(kn)XV<Z{A!w{<(3tCI z9-@=5N!HPGO6a)4G*L@((7F-%0PoW?Ny|LPac%`tLG719I-Etp57qhKw7xAJ;vrF; zdj6_!BVlQ2iGx{rTTzT?YB@njEY#CsEHa+4(y7$cD@N<%S6KsLAY5ir<=ujsB6#%! zb96KRwj`6#P{#bqZ&?TXaLZ_Yr{8vYhaTzpHw{t-rWdDf#>dI@p=%cPhOE`&ef?U0 z*Q$?TFE`kR;oJ;iXXtevabuWDcDo~+ya)J>Pxu@+8XdqLi93<GEG4O4Vs-kz_syq< zK^&88_Jx&m-fUH>ZAZot)YcV8#>`Tm7FDx%;T-ue4rzWC#PSeyeY0~!yvf0tC>k)O zjx2t<ImC0a2-AcUS1<;XOZ6=%Z?y|pByQ>`g&{p$JztZcSMEk6-V1v~|L6UxWit@{ zZ$qgmIw9_fFI#r=_aRh^qGhMqlv%mH$16>}ukADeqO02>9{_+ty!^#xt?JUTJ=Cf7 zc!B~@G)vEmslFn)Gn%im6la~f^rO<eO_f=vOzm=vc|=$WP7GwBtk())TGsf<u=l4a zH>ik;!vsyH6eM;;7+N2zLBnJzHdnN>Y}~f8K>kGPT-{C0Ms&8LlMObvLC5HCb*gff z(JGZmBY8<{h3)4wvbJh0=VRy6U^{wu^R!0t`6Lj(S~mDxlJ=56I$t!Az8py&Ehb8} zkuwUeWj0?|tGlF=^%0PPqZ2Gbpj@g|Tz#3T(rZ&PVl18kjjz9V%&Q|ZOc@TQ8dakj zhaw%J)}J{r#*l(p^fCV0in`7!Dc9$(iUnWhm*a<R{b?4*+&gL@w~rP}`lvK8+1&{9 zfuCJkPQCzQv%BKE8WBvOp^0#^i;W$kE?;t(?Otx+@YL0~MLOnVjTL_Pk$e?X4f-Q^ zwZU6h7$wW2oIt11jaMc7WHcLbIF55UD}`h0+R$o-wam^Y8JYGrIUx7Gyd!gDHUfoj zuYZzn|4o7s^56qTnlb9fzsX=}&0@k*D6T6F;VVrE$oV_=Q^jEcHBY|H8BPVGjGBRJ znQ^8pof;?qf*;L*`+jp8mbCo732eHWi|!XJe9@+g>r|*-TP_(%3RAN*<+?(^OBI3v z#f;8-IO;;sr4YTmb{5d`sb}1Jh4h6x_1Gc$EU~mkWR3kPYMHr1Vwmw8k&&oKVtV7v zB{VAjTw(}oYkwKMg{71`GqTA1aM+H}>E<Ai_NlXq?pZG&NK*zNAWl57OA!&^`GdPZ zH5<8g>=GW~=4^4<f8j8V+4gz0$n!fKiG1X)Q8LIIYZt~mCv$(!n$^+Ka?;2rh`^tn zUZejtP}PR<D3tN_gp&Ik8<=MN5QAO?j68pGq%1Hr_SvM#I1na1&fsAw3YI0znw3nR zs*`wxMbG)8kITB$`7iP&|K^M~6T3^yCYN2wi?)02n|4L*kr!_am{VS^^;s<$F{)wk zmH4MD4$g}MiipQa19`;A?|)?qU7pdmSvB2k@ug~g-~444yqNaIC6W2hwn>rcL%LJ( z3@~VXd)6ZVA}!5eS^;HBM|Bq;Q9de1Cs5}mOaF$6&!QEy>m$Cj=vv9AFAgLO09bDS zCZXJZ@PLSH4BihMILp}B-1t_g5wW#2;adE4&07h@lz4r|wtA;ZMg8a&cG9u93~P&= zYK6P;02~GTN?|U5EU1S=F)(>ZSLu!tmLQ87-M?Sxb`@B;_cPH3q0O&{5+UD7I{%%g zOXu#W%-OwCx@}MbfZ|&2iD?&mP+<Fsh$X({z*$rz6=9%Pra64wECW&$Z!O<k^R^Es zJN|MZa#-Y_!mdKsm+o9IKcqfwEuQk_=^Do<H*lc4+bB!%Spe!Hj2>naaz6|U;h&+Z z6_R0~WQJ|7la<@*wNplR$V$WckuT;{yGMR3g<Sq<#L$k{97@oQT#yGKOrkX*CB4Bx z5rMSW|3^-MJbgAu34x+9=U*Q{Q7DHpQ!u!ke^7Y3Q5Y7wMjd)*)_iL-gB+oLvkF|K zJ{73vfy2yIn!3V;N^*Rn=xHDM)DXzm!#+QK!l3_43oT}RP)d|r4z}TOuN7GcjBHO( zSLPPCmU>5tU#u+t+`414W~plD;wfM_uI9ZVLSS!8;ko~gHjdNM{x-cs3!9Cgw$Ef! z4Yr8WxPgP9B_070>Aaqjrc!<}#=Nn=s^AgJuW;h=rU8wa=U0;fRW~ekw4unVv{!o* z>x8JeO5ZZqab06c2lMl9HBw8r9?si-R24OwQXt|Mw|7kJ;|6D38cuF{yBrgCp3%f! zA9>(m_tk~UpZN4wS}$KwHt!1xU--~g@Mnv@$#TXAQaBAjEz)2lytF}$8Slpl?hGt~ z%3mRapWm}NJQ$evurMya>XN+uSWO}w!9<|sWv=bAX8;YM1`ZQ(K6r%@X4Sb_piD3C zE=L#}Wh9}2{o8_n35ynTC%#abeGlcA{!e}*_>_4?qcbk<dpUpm290i&68PTA%YgSD z93PT3j)6;~Vj6GB3z|dEx}BnyWNI0Ny)52SGb<oVt;v0R>!fdi_sNiyj5)oMOcZkh zw+DEtlH+)ABaS{l)}}DYLoKtX_j(|mC7l!%3u*g~<wwBer>2C-Nb7f#2J?6tvGs$n ztF~e&4X7D&Cwjo401*k3b!1IUpw{0SYkv8F6AXC;7-TdWN=cW*7}n^b75)W>eE?`= zqwM9yAC!9-8&s7mg+Y+XQwa*x7p8g6o#gYX7wI^eD*K3jPT{I4id|EDyXjSQ3&-ox zZ6T9d<s8G=U7H4c{JXRobXMN%s^?AVcw)$4(qiQ_6lk)XwfP_R^p2_{KP57JkyQ;R z=yeV;x{c7^K%^)fcFx|pvJm1eS`U%ud|C2W3#Zp`a4Yn^(S__dBpjR|WoE@b9l-f= zw`UKQIxeog^6QX-((v3;`ZQ*eF}s1r{NQAkijU3rtUu*^xUP-OQ=3UtkCJ>Lo(d>c zi5hU=T<{5W+?25&%S#II$d-;r3l~|fe<9D6W#O!>m6csUi4Z_PbMvj}O7rZB{vg-e zf?nrxTIK<cfsyHc<xBxcwFabvu50N{eR{X7YpJs(8fMCoWPySy{~V!xZ=<Hj-iWXO zAmFvOsYbJoKwPJKB|>?dwmHQiCz*v1m2XjcGnIm;dpK6xQkAQr6r84Od~4XB3MR7Q z<aSy*VtE9%{vnL*R^r*H;~~?b(7BRfAP0%dMFF47|Igj)ytDuuA3|PGiWldv4PU!Y zJ7P=jt{O9g6*dJZAQ8>|Vm@J6m(%A5TE*8c{KWB_$^!AJ`A-@`0OaDrG<|Ug{Cuz} z*ie!udS0>)sYTTZq)og85@0In_sZQz-#L8O+)c?FEG-$g_q%|p*{`{5e9phldTz4^ zQak7|%f%ZL^FzPP&qTW*FK@&90yAmIBun?B8fpy2ccBaNoj=-QeSW9$deU~!vg=^5 zV%Y*-nVLuqFt-%sGt~}SKA>zr=NlL#@IFP@Q`#>L&T5$GKcVJPqbR~GBZVtnOzRCj z5}ahMI^%^pIc<auv9iii^lPkUD?hQG5*kW>!pC~B_3aZ}Znhf|lPGAk#%D>?U-S9H zirM4Qs<Em8(g>Cth%7#Tg0CKIz|^ML2m)3uJp9hJzAR1Fs5;i7xmq0HDQe1?6J~xN zlD>uqB#RtxY8$NFpV2zu+R2UF*3Thh)UsNbeMR&f7bdos0o<G<EZG(iy4;|o1QO#g zE0k_;>bNpd07X=53W>$nSQ0cEeNZ~dsliM<`4Z1{vB55zNM39Ajl-~#?$0^42AD#j z?)l_M5Iu`5Bb|Q^;4KvT`DxduDAC4;?(O1f*@f}GF*A{fK8kp*6aX}49G<3Tk=^pY z<f_d}0$N@OjT)jGQ-y3h0RI?}b5-GGy;2Ern*4*wUp8AoDPOCB6hqjS-+Bm^MW0CF z#uJ0%UL&s6+CMeNzoM`Ep=!aW5FP1t7Vn}Ci_2sr8bXH+Ig&vl`xLJL0|R^<G9_7O zbn}gEs5CuIJmU&-H{vCiRq16laT_E!N+8shtRH#DY|2zMO4+(6Y`a*iZEionBbOT9 z#bG$N{=G}dtWG{E3udzm*H^$Pt~Gw20*IH2zH;UcV(_<;#CK@zl1&;l>^DpyjPx*7 zb59^fUrPd0U3#d9r#WKe6v^cdAlNIU*BY`}RNfX8M0}_IvSL@aBcCo<{0jdkrQ%== z@!@WPzGFK%Ng}%a`xfWnxIJLhvA@|JB!jx@ctNwu=-yt`Ty_9J=jk(i9c%zH9+vvU zQ<vN;|AK*i9qbZeB~zq9QL8Q8)^)niZMGRKlzcMEYAchZ(s>ZmUMTSZt*}dPAw2{D zP%+qlN9&=ge-(HX-{EOqq_<CJGXhHdG4oZ~4qv~0>FKu3B*PzY;)?^HPtGzCt3!_8 zKd-~Rm3?$YqKqptj-P!46ciUdYtL{TCH=$#aEsu0%T--N0A)8Iwp4X(tBoR;(IOCs zn&0ZWj1d`lDlQtwE+&Mvt1hHB&3kCpbSUb$bhG%|hEldI1}|EPVaVqw@aV!$DHE$d zSvYsrtJBFhR4IC~OS-H5S?NKa{_4bjgQK1ygWlQC#{4*M-dKoww&}%Nub&_^2Ti7) zyZzM`P;ogF$^oo*wL~hOsVskk&eL>wC{QiS?OA<WMhjE=XzzauZ((TTn|ZqjFkA_& z$BB&Gw`04VRskqJAKN-K4yJTtCpk%;m)fm39D_6U!-NP^arGhwTLvRxeLFxZ-(H69 zL6`4?iDTof2Z-y#yE1*_!wy~Vf;5KMC{<kEaR30_WR1&SnYRv}wF|f+Vfb0%9&n4E z{qf}%;`Ru1ebh{TJu|~rKe5>x3Lf`-tnRc_f8@0WVpv@Q`Fyn*r-%Mt&zS=9b<M{z z+uzy1{4Trr{MUg%<cr%#<5jocj1Ud4&bF>pJ5iTgZJT+4l}uvk1ebdmbFK1T6AJ1{ zEGO}uFDT^^DwY2Po;{~%G?-@pg^Ne*qBt)nG2EKxc<H@3_HML|dfW+OK51bc>B?$* zlJJJS-=z|8vVY83I;ypy-`Et1RL+;9gJox$CKrL0memtqxO`?0$$kxeAS%<WI`n}e zeK*E%+CxXmPGZPD$37=+jmk!@xpDql<<Gnw^Bk2`L0yKIsA}Ss^#Iog(WMY$4)uCP zjC04yf?rKeqYeR~{Ij~0-PYOIsoCXRshcq=3LHiQYQih&LL~aFQKGjPC;px*SJZs{ zD;i4K#V<L%t_TuINI8J==f?MKK68niul)=db>th@Ov&zMQPV5ClQ+<v?-SK!QKeR| z|Dh2F?Axjceyzv9t!!0AYo>tYrtDaeA>7M?e9#PLfi@(`^{ragd&V&j3Z}Zp)~9J` zJ)6i?$KJDpPdeKKT#km~E7vYZ`M^Erj?9qd7Uc4ViVU@xPc;mL#Y*auSKpX)6@Bm< z&ux^wJioVbh#mQEZL&@^x>p%E(sS^i76u4ONvpzYDm?q#Ebq9f>W&!NkSwlm3`t5H zsjQI-2QCd6%*kG^yrm^I&|>f~1nueZ2z@$eid`YSN%c_sPDr$2vv=hs8kWDFAA6|M zcC-*)ID-n8fBJ;*LGN{frBAx17^6GY1I`d@f@%6sis=y=-%LIwY@>h-UO!<L$5Tfo zWjo&=4M2J9FX$^L--ac~M8`O*Q68%zBfP)#p9m&UvN=R1?@ArKwswH;Q!rOij{u4S zyoZGe&u?Z0p+Yx!Dl5vKtr624JGmv)DGaI;w8IXY2l3qpCntR%2|zS>+U@n4@YezA z%rrYP1=qUob@!u9f5*Nc71D1nj<y`OOpJawmPlT_wC;Y`aZhTUBOiX0nSb=<bK!Vw zM(OJr0){USlMW8M&>Mfc6spw`W}vayMII1$>u}cWP$)i`M2ry28-1;*QFY==zjldF zk7ikf)OQQ6o?1>nGTnKIf40$5Pmq$M6TjDY0vhh0%LBkuwNof-*cDvA^;+1*&Ky6s zLbrMOyGE|z0Mi|Bi69<;sA+*z5|8&+dwc@T+TGVx#5Ahn@SZam@Otm$Ei{t*`VKRK zvX{TwmBN?L3~a7@rti6CBn$_JP$~jl+___GpCGK+*Gkk0l~TN0y*6<?s8~2svG;or zL}Jf1!ta=B^5kE-ppuvUUVb^U5~p;bM8N+lw|!lE8$s9OAFatQ<RZuPJQ`~ae=k*Q zfBGjeAn;y^Ym*Uiu9QZp+ordc-WDN3c}OMHe4sOi-xpdW!Q7Kx@?~||YX&j9a`=;G ztoAuA^WVI=`H)e-FzBV9d27JCR3J5=UQ9p!!ThOFW}7`J2b=j^Ss}DisL_EO-cI~) z8VKIUoNkegK^G_{*|1b|@L?_2IaS`Vr6z4<&r*VR=zsIsTuL=mfxXYrBG`S-sR6u9 zY!q`B1z)j91==cD(BYf=zf?(YvviFjdrtV{!*=^a6P7clM=~d$$L&lOJuL!gf|5?| z34Rm$E4%Zz6?Gg$C9$mw?=?FWu9It>v1w*rO^SWOu?q8&@hBv5zR#$_G_Xml5C11? zVi}%Ba8;~pB2Esc4p@=6CaNbTYB??fh<><J6|_qAtN&#J(s$)cXBQCQvc(Kadnj9S zY*}Jh%amFyDn+WpFi?ED{}0Ph!`(WD+Z}z!sdzcJq`OLeIKVaXJ`{4np&=*ZOvus= zY!TK}k6!%s!1iv7w@vV`eFoC6A%A~zwPh!$%OkZVr0k-4JDJMb8d|9>n$b*{u560$ zn#L_PQeyA#r7;6NfO|<)vjKsik+JOWpa*)nr6@|JUg8f}yzS~W<0^?J{7!<Nfd)VL z`hBxdP;S@uh#uxv8g4|FxSpq6eK}GW_S4CrVGX><qOTd~7_+=R57L~!Pu%%@2#*0k zj$@@>KUnFmOS5wS{#UNQ19;B46S6n>^t=xX`B#Sdl~A$cvZUQ;&P6a}{$U;HxF8Gz zL;qCB60A>n7r27%F7NF*x^w*fag9gUH0@6BLfx9@dT#LC@2_6;N~v*L0Pj<J|3ch6 z4QkqnNbFOI*xwxgCZw(t6@86Hq!!N!PQv1kgP&sF9lQwYHO5Ek{S_W~c>igbnK}9I znG3y}RGyvRww5Q$c8DxuRZ*|mYUrKYf?wdtdR;gzb%5J<ej%0HJuSezHx;X;$kH_l z65~3oCc}8}FCiC3a<5XsfkO$m@is+*R79uv8hp))YZ&fK&I9>dJAB(!R^dU7sg;sq z`W&U}aH#iqMniP#y=KV?X7B0fp#S#Qme|Zftu8_oA4|BFcWo<#tGnI<@AbbE*2it( zmoo<~JCI;NKRP*JJ}CT<!41v&cdqjwmCG9!I67uS^=P`mTFya#I=$l9Vc=f#i+`s% z9u?@6tRcDTKqBx|lsP4K%e8VULie@yn}1$*zRu)B1CVpub^cJ1CHBNW))Twy+f%&9 zir@d;Y+DM)iNFA}Jk&n#XDeyy7k@y`V)^uVvOu>Yqx`oQP%J8_d7lot<G5_#Q@*sA zoL0O>!G!U7&0Y`l*?-55R4wzXhOL(y%XPp^J<=wlD~^3_m+b{GU;R&uy9=sSgf8$1 zL@g6<+DpFlX8Ibj+3K9Y{~1T)(v<!!p^#jpd}1x^PS57@U5>K2QH9@H|B0)g0lQ~( zvwgOC+#_FYI)=2^;_T6?vp6Qfe`8o`koOxjf83bDaj)|dwA{iN3jTXq-N7@{$mp2? z7G2H<*_m2xw&H@5H^G9J0N;80@!tcbW)=h9>DN3@6?>4&tRoZNISJyKN&7z=JRk8l z_^Uf~i8>rR)p>U2MGj(({|P%p`8}XAyWIQz%MI4D7GdyCG=FVznJd|U%PAQH$dND2 zm|pLm%fL%ox-EUn|AvkkK_k;jef)i9tEi}|L=u8*yc&I#u{-#Ac>jGh2Wmikzs5D; zZ(Q9&*ZRxH|Ko>q-~`^;kTsqf(BMYq-Oug`x_zAu5n^1V-JjhXx$VofDGN#d?zuY$ zVlbScbFxX@wj+Bcs?3yFMQuy^qKX~`imsZU+~!^y$_i2fZw%`+ndzTl4Rb0KlKkB> z!0*fy`o&Y`HC0og=ctT;yThD`6L!^hN*Zm?{;6MfP@ja&srpzoa^2VYm*8w(az&;% z@%A?&ka;`L3sG{Dum2PX-rO4j)pEP=|N1XE?R8YmQ>*Ra5y@PJ-veTLO3WT`@(SL6 z#$IM~tz$^Zo#lXB($HIjm|RoLWMi?#OG$*>UR!&E{$<%)ehy5@s?Hv6yuM$QI7(H0 zd4%}zFXdXafU^pFjzu>whZcV=lg}1$f!Wc(-H?C#H`7W{ZvVYt0l*l^faZ;6f@%H7 z`Fqc->&A8k^EFT&TVQIUMob{+uFHv#vag>hK^5WyRAk<~B<G!N7pr+Qb#Y!2V7J;S zKM>5|tJIdCu)AKhr>9!C|84nj_4wZd><$>%SvBeGIi3O*&2?V-bw9<!M3Ox(->GlR z5e=m2=RFA~9|yQebXYbGstOIsgw=%@*EpZL8Y>NeS@(vA=g4InJJ)#(QHJ@cD+PIL zSnAz8i55PI#j}Qx(p?<D4*9#lSBw)cA;TzW;h^d^+s2{;{q9#&{)1mh4cI2^A7$-t z+{M%SiiwLG`~3^^3o}+!6Hj`^ev+fyytb*a3)a#L{ZcRe2kGW0`fi=4z$1z?5ha~> zDr<QH!7=XJ`&nns4jH>C545Og^tK8A0WK$M)q)>`<gWK@3ksSe^IBMUDeSe`jOP5W zgEceUPJYUS5B&$p6g5D)JC%_&ha}r|eisK|XmqIhv-xTuB)y}?>L*WSBTpXP4%y_s zvuu(qHI|1Z*X6K3Yx|qi{f`mB054IajnJQ`*glY$A#C&$EcG06jnVu|p%eh^hM3<r zYU$*Vk#oD7X7gQTRglZOsm|#GXrsPazjG{WyCjtJCfo5S_EGDP+Y#>6?6*nN!Sjy7 z`D%sv!aIXaXvRMq4}$~DMGudXBtQja0jo~|ES+0edf!983mYVrHk)PtK*6Wt(XtQR zo>seq>&7o#r+xl8SZcyzs&SO?+x1K3)%5Iy++XA7(bbX1sqE>bR^V8IUuhgSwK5wx zXy+F5y``);47gFi@$RZ5&eEc4D6jpZHihI_fp@j}Rm?s9J2{63KFApVV)~tn<vLtT zYMGFXL`Z;+sM>odqlII{;z}3v!tZ8ovS^l6NXy7KCa$D%h$EOBY$Vzj$}gh|TjW`> z@w@FPkmSiZ^1JsEM9h_SYi~N8V6`hL3c^hxmwI5j)B)|xfu0_iFS&f?NX@9B<zO_R zazue_%BZgyLwOBu%L4cNQgt^;CjoYxicS3mu!WhYz$*Q<YfrTL&roSHT@Hzg@l54x zJ#-Eb=VtVDHRJ;vrXj_5B8dSAnLmBKVUfqG%3h{3E%K|tWPnAz0>HSwfCGfAZSvv( zfHP{Fna=IVAg6pSlsX$l;$iXwYwPf%{e?H1!#W3cn~4pc2jI$IECxMM5jRu_XHEWU z?M*yNiRF!UB^jT&-^0whZJbpSLwUeH_ZzZ*z&WW7Ygn^f3=JR$Xt8+T<L6x6LHHPH z$mEqH)s})@;6Q#APFlBey%f@F&Ga&oyRT=puGGIO!|Uob#!+{8xp`sHHEgq+_=u!u zfS#FXR7uSNEt~1ix}<_)Wx0{}#0B8_4HrP}Em(g~<9U8UbrsB$#CH2Q;)H~UQoI0Y z{}!~`*0s9VdIjtFk8`bY6z5X8I>K<QxvjP$W2f~<=H)#d=JyxA6>j6k8`s{j))IZx z#Vq!qYdhz0*^V$a5DdJlK;Thqv~-}ys8KW7il4K#d2QTHCgSsDYr#0Gz(Y~4L%$)d z6~FX(V#fQ0>r6GhJ?*x3P_+$^mwEc=<>m8YgPQlNbKS>Ytkwr3d1@KRe<&6^g<{LQ zZ_f^Wi)H}3PAStjKwIV8=_cPbq_jS<)Av4r^;)l#w*jW6k=zI_wJ022GtfXAaesUU ztXxg@XW3R;+3s-}N9KeSjrf#H8DnNhMT8o`cL6F4JSAk^c=88@lnrPHE3f~aj?(5c zFerIc;MTYMj`#3Rt`*zH__v|^mgNo}{UFKNkk{T>YErOa_)ulUP!o4o{nK5#@wLH_ z5~1M{g4O{$qKoD+wMWy;;-axcf5Gut&$UXw>W$VwEVmTA%%xodKLQxF{UhBHnc#{+ z{-i58?)N`zoBz_+WKOHS-Hau-IsUd*n1?L~zJ<e*n%m60e6(J8ZR&R8XZ=1!5KkFd zY7rHoGL9CpITtwH{MPfH*eA$C@d}_@ffsIG@2z88qChU2&k!Po#$(O5_qV`%%-c8{ zhXJGr5%T0W_TC>3PGZCO?}v=WLM<*Kedf?{AdLG^PBvQehDoSqPVQ1c>fND&01ra< z1w==RRK&lrX}`Z%7JM$+RSLMai~Xiq`2k-bikXlBVW^V=R|46URZ^ASgFF>Duo54S zq*q9QVU&m`v%eROeKJ0oNDb3T93wvlPn;ufY|e5&bg)Vq`5nq`2@)MFP0aH9O_b&d zN6r=>$|xLSYE?;cx%t!+*r3Xj3uZ}^w0ydU7BY=A_xev|LrSM+Pk$CX@E$;|Wg@w} zXM^HSEPv(2WF!kp?$1z+o*_Hd(algUfNYR~Vob-#VRPF9AFyi+jt4%62WMivdd_M+ zLh{J{bYMjnJ?jb*aEhC)qw;%^aO4$naR2DU)j%Cpql2s9qrNojqe!8V0uifyvIq$9 zj&_Nf)JC?<kc~{LBER^nyj)MY@0zj{H}qWRQ_nLdaODn{&(6mcT@pm3MP%o%2s-}c z7C<4TwsNaFu$fG-taJdUyiT9IT2ii(6ig~VHN-)dVj#_k%J0;3EXq0lP~Yxix?4A1 znR?j#zKzU%8;kNL+RihHjUZ^QJyh`$;!OhGz~=D6;wfMkG9%AGf2GR~XS|n!MQZd1 zW_ZocaPA2l7ed#WMLyC=slxI){fzoi;eNE^GqpYIGxV+AJx{{~ss)bkeN&mLqLsZR zNFxL{ym`2ViXxYHf8B|@nu~kfQ_twu`6nLkEyl=0ss<ly9pR>qjsLN>8H}FWXfOaM zceJnf&Y9lh0n9<>+w~XqOC%S0;d1;IN&~fr{tUWIB-qt->kSKeSy&;K2?(Fhv>CgF zK1kjlre)visG*o+z=wOss{uHKsJ(ydQemUBqcl%$RBn+o@6q-AzM8*HMbG;9G+xqO zAr29gxHL^EHib`f?b_)KSCJ<k5i2PBK<qu?thZJ^^pp!?`iS%f99NLP42nM-6A0mn z$Y-tkrrd=mD*@$>ILO_2vQ{x(xVqGv9LfP6;duQW0Gh}iiZzFNheCN)Wemt={QRL0 zWG02QPKqhp2!C2vT?doxU^={>nbxV>&`b{5d!bjcF^OqOeUBIpxNVGB5ds=2TIsN_ zd0b{JCBwh{U*fIk7rV@jyYN)fhrZy67@_j)8EU0M4$1AX%gMRy0$?_qm)lWc?2KD6 zdvvh1X0bY-bvq%{HN=oaNFR4hX72miS&$Of{3rzguv(blc)jc_X86T@Y~Z&f12OTc zHu^84Two)M(67Oq_SPxZTL5LBfXAc56cGbz5!b`49|7dlP?6EIYP5|q+i}*=a&>CF z``jND7^th}r188+$<yE()Nr|TYr)m9JWzK_uA<ij5-D>M<pJJXk1M&YnR>{0FpWL9 zT_5aw1<i0js3~(eDx!<9&e*@+^J9!?puRqVjBo}&DNrm*C@@n#Fdrv?sk+yP;q_ga zF~N9L=j!!al9z^VBI0NF<8c~Ze=$F|(tp4ct*DDPQ1g&Y7%u$@3W)}RdljT`I4m*L zo>=JvXxfLDjhol!h6b{Ay^Ml0PiimSqpaGqIyhNiyYlCEL3{fl-t3i~<WmwNzQeNB z0}KVkX$RoR9<Ov^Ur_<gk^yiV2d8Dnm$>*B05j7(oq2fgr7=&5aT_3h7dzzaTZMS4 z2@rB`NB3WgD~JXNvv3&Jj;rJWq!<0Z#}NRO0%BK)GMgo!TEeD4k%~2W5_aw4Qr388 zQfkKGp6x{I=%Yu(mA`&azva{NN28lZ#8u!3wmn02RAD%FODA*`=)uo>CV<!%EynWs z3!?LucN%|NVO$Rhb~_P)Ii~Pyg09|QWVKGv;2R_zT%Lbd^%gG}mLIosiRqCf!K+`q zLVi}~3^r#m<E-!sIzmcYFO#NnH^#Ktsb>%2vO*d=nXF~m-PjC?>t#Sf!`KiV_^K3p zq=f9+A&fvl8Jj*o7f)Hz!i1j47%u(IqbTkV^!tNr4xLRjn;=VsYmm`&er#_0;f zx7L^|vc;Uss0K!>Eg&q&<)ZhBR~gOKs$OlOc8h9J>iDXZ@KHcPJYD*+<E>Dm_uSUf z@-(O%Q{G7QkEXVE(1mi8^ee<Wlv;ZfcY&_HE$ALh=G5(664aH7=a2QL!14=ofg{Cs zaU6FQ?R|^oN+s@ws^qCW+QH>Sv=JspSys|nO(r$#+E`R*4Fh0P@7A5AgtCifp8^HC zJKVA&TSUjcKDDb6>&0Ix>TM=|H*e}wzDD6b2b8y|isM3V!+o4MnFbP&AwO47WxxJ> zooXW}HH%6?WiE?$2v>o6c=s`#zDECBO8Wd0UeH`VSY7B*A;9U{Um0&`^cGR3yGgO& z%}NZwhPsE!b=NO{>}LtmlM&8l_al)*ubAPLzQxERx3p-h^0-G_d-S+AWeB?y;0pkl z2;a@<aBm$0c2tkbTP-k_QI+o@z8vQ3zYujVzvra{O$l;}acE*GM-Y5Dw4gIi=d$>5 zWGZh9Z%qnk5CZ-veRxFvBc4vnYSV3P2OyEY7$~W0i*>TtdN6Z|W`#M(77gpoHBL!% zUOTk>ht%55xt%^~!%<Mkz8P!kaIQ+xTf=Z`6tXu#0r9ngR%=V~>~pU+l0Ru2Puw7K zB3DiP{tO%v2YgUfeu{l=90$_uyHKjMgRAH&`!|3@PRf1&mnGZ#;_8%{7MVc!^-eU; zW<r9nO9(^2cJD{tVLt2qx)C0Gd8aF+{WZS9&%89(WXqYoj-SvpwKU}V8PX$C*DgIj zfb`~+sem-<)f0f86d{6z@MpM0SmBN7*zieBT@_dgSziT17wye1xD!-zKlP;Q(jjp$ z?3-GF)Gt0LP0qzen<Fk1%bML+qiQ_hc%$1ua0^5rq{S-CL*sqjbuGEU!I-CqvsL6d zXPA}X$l`wG0C1YP3mjQI?YHDSFr&cDjo<|!5LZs6706GE0nl3~K?*VEk$U6sziih4 z7h8shIG*w*!HmBp;i&cWd-xa@z<zYp`6by)UjV)*>z?YYc0r$6aOyANXDM8;&lm!5 zM%)ZarO)8i$QC>`bHzJR(D-?7leUfWw6!c)_(U0oV4$yzF!V2tLciK7#FY{(4io6u zIviZPy)-AE<g@SO-rGDK?T;Dda{0xn@ha|gp$91Rs5HKAmrsPvWo7K{9gF6610uiU zw0;yF$NBQ8?WX&679UMjgc}lViZu5Z6TI-;K-=%`UE0Qu(Dn+xD;12}SY@hmKrY>Q z;JY+pw_2>ngbZ!jk|C@ziVL^nLmzK3eQ{5y-4G`t9Ftvx3plX8NSo$pe_Sttna_gp zS>PnOaxaZXVD8%IeoD<-1+O~GF1HDAj&Rqy-H6n;jIDKgu)1gN$~!-{caEEV%k2ui zbsOBK)?GbHmpJQ?O^b<EYP!XKDchTqs;L^QFPcn-N$f>ke>9Rc?~foo>D=v=6(ulH zM@E3zp30`iVW~KjMpn;dyDi;IEWqxq2k={{B)h=Z0Yv6Hn7N41t9@{_qkpHfB|uF$ zx{qDUd>=qP?ng|^*=mlfBTtCbDUiDQ`1P6^D<-87iYdGyMG7WIW|?v#I?lrlA1+_D zt{KT+aw#{-^sTh%!Uu_sL>20iNKK-LoB+8n$YWipZfD7Q^ZAr?u+*{&{R!vp`UGEh z;A&*#ZXV_By*ygHHebxORa$z3YlJtkVmzcO`k`ZjWCpl#k_kKVH<~;AYvS}=Mt!c% zD&Wx2*U!V<^%-IFZKJ0<R^e7Wzd6|z6f8K{y*ax~>lBuG{F&OWJosthJqEp}U%%GZ z%<KLFl6MTIY(`Jkc9(|RpjDcvf-22v{Ara3Dh!1`l78+9P*R#1z3xssyfkI+lxLT* zDDM>&F5NolTJGVq+~wdH$iSVu^bu(~XsucyJQ)h*-5UuFA`ZLG)WJHBI!&P1|I<PX zD&VB4r8AY{JuCG*8^OfX672BnzfRoaamfB%pVjtt1;Ww4T27Ss&VTBy=Sqx5`=)n) z`9XAZ)^~@sX~x};J@}q~9@&a)HR>$A+>SGIFm_!fs3vVl<_XXZm{K?WL5EH_4VeB- zfjs-9zyGIR-(m9jCOXBLdZa-g!+HO>(5*r48HrhZ89E}gW&`#GPv__Io?Oz^Z-^%L zuLc@A8mIj>!o!77iVHvV;&)bBKKhzdl@GU1%GfkH=S*(1*03+U*!N}oPGDxnUO-rX zD)TE#5ck#jPDrMair?1ZZU=tR+ryiv86BT3M@C&#IhsRw@uMWGm&v0mTkL7J@^iJ^ zNJ28!tTOn)CNq2_ghP_)egIdfRw;$=RZ)#;$2m5MZh_j(tTsut@@Ii)zRRK~;Y6<d ztswUTWJ8MgXM`NO_psZ}A_|G9PK=uTZfxqqX16WTQ%CW$YXVLmtU%)NliOQ&_%7g- zcD8P9Rx>kp7dQy=4g3C`WV)YIA+0Zg^-DT(L7Y5b8+RAKGF+SXddT*;fSc2}<pFn* zQU3{<fNwP}>AS!uFKH|H3%`E_9yihAf#7!3uHb1upY1#kl^##pM9LFSjGuFv9K=cA z1_H6`r$zQ&4e&3K31IZi-96-35DA@6pdDM|n{_V=Y-cbX?!GDY(2afG{p-={!)p1% zGRWd<fdn4MnPW-!`e?cYCCWE%g2KYWQhHaU<mg2<>kF;%R5eZRu|y`QtLp1pK4LYv zz_FZ)E|a%)iqiGYysEB7DpGCZ`gbN%aFz$NeIFm*v+<RwX(u)8t?w5Gh}P$1`F3-M zb`U1Rla`qVtXX`Q+ZCvtV~N|<<c}jb%7S&+77UEZCvj2C3M2Q$gV+w$y^MWZ`)}sH z@5(0CsZ}(r6nz$(8%I0naU1QpXmQD}qh#+Z1ltO<UiqH6a7_<|?KPL>i(_z}L@J%_ z%)!U6g#T!{>f-gKT@<=;UolMNxFmaS>2S%pkW{SwM2{CwG!cHBBTf*&$~TO+X<Ap) zE&kEE;r4#4<7&zlnxEU?zGXFQV;B0m1)Oh~Q@gS%hAnJVer;=b<H9%?%xZiB2`Q~> zS(mVU`WW)Ol90oXY)|+~Tj8Df;sc9WKRRTilW4ux$770jfv$ag-}^<3u$uVR(j;!~ z-k<V(_U85>lVCi_+Ly-<b8d-mVialmlOa}Ou`H$k27upPyd2AnTw#WR7R3-S9mDXx zs<nIX#)uot>N|WvvQHl-;}DuRxxcitz<E~#5>%IHQPQ0lUiBKtzL(N#gjB1Kt7iM| zV}XOS6F3#5(Z0qiY~+(3`6*2#H@=huM)J}jy;lZ5BEWA9dCK06TYt7cDY69d$KE59 z*M1Q&#k9*?ys)-&<Z}D2_)9D+k$QT3XZQ3sl>RvJNArHt@tpo0p_MkaI-E>wqQ@PZ zm)4r1VS6V@a3$?o#O;cHfS6i2;HK2g>h7Y?*Uf53CJt$)Z=PW7Dt^C+q0M;WnK5~_ zL?WOCu-qp~@J(<eHE9Yuhz_cpc>((_qPgw<YY_Dnq%B8C*exxveYR^+$tExO6=9Uk z@k$ixvxcNY4CBw-Qca>u;fByTKSNYb8=Kw3waOYFH8M8SnpN64{4iNLxve9&PV?FJ zMD0eb3j<F9&v3gHw$IW>^KxgC%oR1eMUo5_V~DQ%a~Vzj78whkMEheVNe^*8PGPLw zn|}<+F1y`pUn}{S-uYHN<v%Vk`J)odL%{RS@$p+-i~#=4k`Kvzr0*8mf}Q$^la3!A z)nK%DRLxD?$DiwOUh=HJ$*!T<q9*I|yb-L8O}RHd>U=L{`o7)t$|x@nJdk<L7geN2 zgCm&!5>;r|BG>}H>|4Y*q$RJrej$0fWr(C?9Xa~oeRf@3g(AIQyOXh{8|U!wjnCll z^cCu+X=m?G-*z+h4P`~w#L)p$$<@URL*GsQKC2U-BspU-mmC@&d#K4Y^vc9$Y51$1 z7WbaeA@$zgHRGHJJFNF+h=}iCgxeqEIq<|RW!g{rUKBL@5&R<kBABK3tOHq&Wk_F) zXp3}iIj7p%R)5&<|3tvP##G;)rYq3ZjvQs}q#!KsN6vjyeiE%k*wjeN;4-Bq$~eRQ zCa>xGa9deH;;|_iT^5XC|9sT&;#ox^_nvx%QRn=w2bz87<^sdv;sWCoJZ72J8x^Vr zhYQz)9y21%&KLL@N%$VRtWadGtX8LWXc?4o91cS9Cd=gIzuF3h=T9_w8twgxM?Vlr zzhH{pJtH~oA%CeK=yt}Kf!I*=xIQAusC!ovxg;h~mvWA}a7F)I&cf-Q+cJ!D5Ji&9 ze*SyfMBdGCS`G3Wn7h;Uu^nl=V7DH7N6GMk=Y@=INh5wqiU0HlQ%z&TNo{P$*+ao< z^TV<3(Yw(v{XHdjTtlp#j<J7kS=W@}&FVbOaDY+l1xM)}nxI4j?tAQhcC%`LTM;!F zA%3_NauEwh0?NDUWlUjwSP(VQP!Qwyg6>cK8v3_;>-{8xQGFVe_i5)`Eu#mpzQ^Z$ zSBpoq3B{2_txASEtrCnGOS_K@O*)MN+QF8O*bf&v?%R~7*3Q#7H0(LrdA9wbDttWk z^HOdhY%R(C^1ItjK&BJ==X_*uU+04?sWle+ckH)|``lXL_6<a)M;X}^&kho!&$+`< zcl`ozJtOnygB(=C!-86ZLi&dhJZ`76%6GmrrPw=dzDrfut2es;v5(8Yz;$u{X6CUa z-+Xw<9}D-)lr_tyc%dz%p<2XORPV<cyO{coee;_~iCCpsmdQ5(@<ypoO5@<~a~783 z?xi?cwy|%vkPsoyS1vTz-G80(#>fR+ptv3NQ-M$3E@J6<0)>b1QEjp%+MQ7?NV~Lg zxJJ+0c(ASEa=rAt^-|A!?UP(G&)%+Np3tNm#o{KkCeQwQ$s28HM`Dmo6$=mWqY0S! zne5UbDoMjB=sCh#7>>~M2r_-0hojz`al3tgmu1z|(e)6*Yx2mBYl*A<9wINu(P_`y zGC2YtCQLY}vip_~8l>O<Gl3Doc~3EzW7BSPy6O{ta*O$t8mXW^x82o)Rn+cjAsd^b z*WN(_u&jpeX@R+@FIPg>Ey_{%q*u$=hH9AxW_o!q6p`tKxpRuv*7V-><6w>L*8zK) zW8@w#tAFt9EG<E}+jF_t)-x_T2itbLzRs*GfU)7=l@M@aQz?K|-u0Hn-8hA|PdgZV zbl#(b@rUZd<J6U*f>2BFibbvTEShlFJDP7p$!SUHsrTWIo^2|Rp1EDhjcl*WY-Eh* z;e|-4ZR%>DlxMkVE%u2Ax4jc`42igx(}(bRi5-VLy;qukEX8tC!4PkqSiY5$H?5Eo z;f!T%w!-jNQJ&xe%023}KHU%J+iP-NSaP+KJ=HD}-fm(EJZhNl&*c3HKJ<}rxh8pM z<uWg4orfKgcaY^Neq%8`<4Lp~P5dMiE2I~-@X@=q{&-#L^4L}AAyKtGDx3T>sd%~Y zYIVJ#`EUDxQ<zEFaHiSFajEKQ|Bt~ni`nyaO-1V?NUiVwNapXP1LU-Of#Z0B-`-sN zkyPW-RsBud^*ENj3vpaJnp(Ux0N?b4bnJ%zk9qZ>a9!{>+$+Lx?VD0}H?Dp|KaQIT zYc8)yVo9c#6iMA8tXrc;jeoziLu_$(jm!CmSF3hkn~zwfG<1OHC#w;^ID0#r$@2mw zgDmtsuKQ+mC=S1GoQ|v4fBZFMyQoxi`e{B_WHhmRELa6=mt0#Uef1%y_NDg<ynnuC z_fv?^X`J2KA<yjE(oG3%cgYPrDg9ki8I_{xL2c}-(Nfp>Qs%#-zv;ln;C!RZG1`Ss zq@)`D<Ktg}KesmO#kS&C#3kN%)x-N@%4z?fg?JuQoz>X+&kx_cq09}G{QE`y@PYal z-oUL&-#(v{?h*gf%k!9LYNAyCHh*D)Y4vaG5AWsgM*P$GtMpg;tbbcSf5HaL<=^N3 zZRZ5fH}7)N!n1fs#Gm~$dW`7@7uEOqp#yftWCNt#jz#~?FN?EH=Ks^T{J&hE=h@_e zUw`j6nNO-~Xew)H;BRJ22Lj9S^=o*GF>$YOsPJiI4p$@V?FvPx01G?x9zUKS9$)Ic z5Y`h_puL8M#s|r^7x+ZJVlbdB6go!;2sb8o{l@s~gEu7TEAECm%Kt^(TZUD&Ms1@Y z0+Nb!3(|sgr&~IuLqb}*b5RP?4bq`>cXuwjI~R?_S~QF1n{4;{p6~oTKhONZ#YL<+ z=Xgfm;~vj5jkNcxgaart3JYqUEw0pA52nu3k2`Vqnl3cSh=SEM$U03IK9FaRwQgFD z!k@w-%`5Vv@4#XurTL@wvod#Vt4G?VeA`t^*aoTY^4GyGH-EgP2IjA0rT13jwsHbK zz3kKE@v7x*_~?1=kK26XJ6dNQ8j6Vx`!Q_IH;&}P(R06i$!$N!lSFLLT>4Sq4nOMA ziMDs8?_`LSexl>^!hRKDd&k>Me9luaYC~fPyxn=s>)~{mq{PVw>_63X3t>Dkrtqas zf4{5W9ifW)YUO*Sy1GWq+E+9}^`H2BSxAp`f1Hlyzu&h#Dbe#RU_`6VG%hY~WY%Ws zGc+yF;s(o#dB}2N%-;AjfycGS*7h#Dy_m1cR8#F3hIw~p;+60ImV-SEt>Z(|sfT^O z_u;dK@^{vcm?BKyOIj-y5kXNMic9t79c%l3;5zHo>(2XS@;LwYcr(E}e5E$k4v+Sv zPR0nRIn;cG*XqhvlM!JXM~_Ivk-;4EaN?%*b&+gAzgrBcvSfqnvVC4|tdZDF*PKV` z5{oWxi(<uBsCj3aGd5A>xq^a?G9OX_yx$?Ks3`Q$muDp2Fmiy?|L?MjIS2dEl@|m+ z1zqcO5H?uTzAZAP>^xw)Ex8@`;6SZ2WmEiNq4>TOf|UZl3VF`dt~@L^^WQDKAUrI- z7tTk3Ev`2!h2uVyqvkjV>Zh;Qe1JiFAtcM@jYz4#@juP?h^8&E^T@EXypSxpFUf#Y zu$D7F&*qJ2)g4IT7dqXsmDOu2uXmlPAC@EO88*=EC5Ec+O#Z^mcpQ;3;X3D5BJcHY z7mm^hdoTjq57||@{|Rx{@M?-L?Dif@Z*_l9Y5D=aH#hszE>g;sM{usxeBqMXhzvV0 zDt%O@P}$~8r_3l)N6~0HGh3vU_etj`1F(VZYsrMhi+0b-JWpQq?I+enI~^ko$k5j= z9SFN3F7sC1Bs#N+6t<5YXRvvg+(TEZP7%xf%no}$eNraPyL*7!8;~q}<Q_Qyna^P& z?AX|fjz)OtJjp!6^7!&v;Yd?yz*WQdlJUsv^CwpOlY?VTq5B&O*@#j36b~wMOqpy9 zbv5XHEFlEa0c){oIfK_ryB`;U-`OvQCHGX|q=z{0S@J+1d<6MNL<~`m9wB{Ro2QTE z^AbEX8rExjQun;rOrI}E+V#|ZLA3Pt#-JASG9y>ptAq=XEW`1B&=ljgiDVR!{8*31 zmEiXA>kJUL|B6Rhih>l1q=O3XH!~-L1J<#Ubw8Y;EA4tVV=>M?JM-$p2#>9_>ob%w zLu~?N&|GzS#k$BFy<04+ba(~#^OMzv)4EE_ZBJKsZe{cx!F3Ni9-DdPBQpAo`F7Lw z<#pOSV;^MP@=Wl!B)HwjK-)jxzSq^Lf30n#O!q9UJ$DyvOXtZ0FMbYs@%0n~L+8Q^ zOMSd%y7H6E)Z&q8f6s?}K0mPkE2WF!9KMDM^UZwSr%aE>NeBp<^SFB^i(gV5Fhy%g zwfCAyUa}U+N|Snuh_<hDLG;-^zTe3}6n1}jKsLd%HXf+YO>=CjPDZkl&_iY0q+gw3 zCKhT3laGu4Oi)?whqo8>tc1^~J11=z!C8_mxb*L1lklcWb{9XwnxZ`RR&2JeMhIOi zg{C%6-hC#*Sy*8924OXybu2hBYw8Jve!v0shgN(IdpLHreg7jbVqM@LjZqw;SIcgr zRm`Wn!{r_Zfsxkk;dwFLZj{Vs%C_BzBjd%A_TEY7Vdz_}4%;@yFssbtbO>wj`vjJ| z`1za<x}d4;w4^`n$gaIG)}n6h#7uLyN@j07_^Lp1nOXGXXJhl~lWHZ)q8mD%s^aA8 zgt;A<g?rGn^0Hus=tO7aZ%?v!t9MCJRS4O<bE1p9SN62QR!<Sp!j7E!S0zwdA8US? zBGJhXQuzGn?2^-lVR}5T0`Kng!QR|ljuIwT&!;K(t~R_Rg$1$fsm2MJP>ZH|pm@u+ zuT`Fd;kBx)Yk8z3FOrPFY_Mr$6R(&2+S(m{YbZuPD?L}+uVT@3eS0k;lthcl?iL(3 zutqXCYJB%T-#HnY#od;I;FQa^Ww#FXd!n12w=i?bYJGNRS&f!{O3`;H9Wk+k^Quyu z3^RGBUy)5sB}%kw10`+kkP@3ij;atjLn!rJ>F9HbI^Lx86Q_<4@kMAS`V2L7WrT|g zBfdC3>f4vi8Y3vTd!uzsAN28>r;d2&80Voqy;a2~1^vsCoa#|Tt0~3f0k?YPW5@3_ zexcl*qt(__jcRLEG%57Dlk)tB&c^zcj(9wXRq^~ia{HrF;4PWiYuvoZYy%ZqoFu%2 ztxAU>9v(teURx#Zv8)+Eq~d)fY)Yo*%Mhrl=giA2f!v&!@icpsiu(7)4vJ?Yb33|E zAeuDj;1!~R>Id11skp_W?_dz~`U7WLi7<kJI!~L@!UqV1xBQ2{{^N^QZUTmYa*a9L zumx<T_-4?udl#{vl0lHwsp0m$z1c+_)M|N#lYVZ2_mk^B@*OM$!!q>-<x`09^Ld1Z zng(Jy#9i<1-D30s6LM_@6t2`O6Ll(n!2}M6KOW~6V9lOC@m)z1SnUp%8RTAx##6a= zqA1QTN-?s~)lhFWY~S7?jOss}7nXT7z2}rKLBf<?ur|3!N^XCM{$%+oUPPray<-i2 z0zx@MVb*v}rz{P3F1f8VIodg;55fI6ziwi|)E~Z}?7Y``auA<$)|C}8d>QY+^e&6U z(HD=5OcAZTL5U6dOp7QvksIc7O2wK~PWy%Vjvo|$C?ICu+fWon>Fa}5TzMeF26BZ% z9Yg}@Qmn#-`sJi!a3;EO`z^qId75GIcdA`@><O4KRgYTs=AB-8>iZhM%+=s*8)9i8 zcuG$$C#jy1L<KT^{63?B&owD@bcb;C++!G&+2QRX+NJ_g|9wLW19!Gt6=lj3w^Xd& zAID65z|KiAB;iY0WqHv^R$$v2zsPdc^V|MFlEWsLk~=g;0h;DXu!}wLW%TCA1719F zw^Ooaz-oFZvCLMtzFSQwJmQv#KXqGj&|oNize{mlvN!3MLfce&&z#mA@O>3G$-~S5 z9)}9AzG+@ji~MDSl(O7CGc|9N%-6R5KwLT@%~RDfuE%JPiHFfchqX~vOvjNW#gFmW z)Vzn}__8@aC^u((gyVNIJ~5T1Fc!-cSlD#;lG2I#A)l4M33Fp`X)Nz_{fCJbC>h@Q zJ`h;0n+38<GDlGoj&nRC>ic$Gr#8)jk94PTXOa`u8&(ubkeRIq?PM5wO1y1p^M=7r z7VAL8m-)i`6!Nm?pnppVXep59tg2J8l)gA|D-&}EjtK6%vf{CJht4gk)<n{3$k6^k zhBaet7Cd^VREJKLw)=f9rW8EYTfY3}uQ~Z^t!2?WeB@Z;nF1=F!|~eo`#>8fdu1I} z!TPuo{F0K4RSsv9=n((fOxE^6)Gzb>2$s0Re4|2k&ogbLch^o?7u+@ENDg;Y>}%wz zH9Gf2?HLASF4}1(a<!S4)Hb+RbzQxi!)j^iXHmGQK53bJWc$gYukgdk(TRU+U%uRy zQ9hY(G~c5nKg4qD+cP*yc5npofx~*yoYo8{)L2s=?e=Br`5#=V(_d)v<OwRQLW4`K z3En?=CRUWp?B`wp-rM}zHtZkHWT&xv96jhiJhsbn_yod%;V(+YLSn#Cw)eDCLY?2z z$&Z&N#3yv!9q?~`?HqX<AJd*~mbKUH$-XgWNKC7a4Ic|-)IJkFVBOO^BI<T|9&B?G zUHV>hBQZ*`=$?Yi_JlFD)Cf-4QdfemBIPh+@lz<BV)<m<`QJ5&*aI8~-!Zn?J_<+V z3rJLFT}g^Q>*_ZJDNIWW-PZ&DawHJ?X!SIr4gFfi**)9n{T0!?uhrRkjpa%P$(-wE zejL9lE#ypJ0WhJ`4R@6iNT4NUH&dRzFYs!Lj#HSwp&Ls6PD}aAhyAZU&W?VlGinpo zKo2O0uh#&7WSzX_ao<X$n9tO6#H6ymwOg3gn$BmVR>)a7TG(lrCQzTh`?0nRG{gG~ zEqANzob64YKv$?zA_sd%U}@ul$d27v-Rxevve+t2&%~>F)ZFx!r-DxDGmSC5e#-)z zaZ56jbpuGjoCz=Q%PT{|;>4)!y41egaA*f_n1@ZP!eS2BDE}Ru)2t??m73%JHGv*f zxFoqb8Z(x!ereoOScPOVtq5C?H<4osEUkdnwr<0a^Z-dsQxIJFDOQ+G#Lj?NlDEqP zen}x7g>2Pd13$e-Arg50=7&gObPV#r&ZxN@#ER6KhU_?6f%6JKR<{?A%oUCz@VnL% z0SNWiU-U+?N)yv+)KMDY$a)BD$%zj#WM$?~Z^@}#vBkR!s&%?=ISv7qZ+xL;!D zz6-k9Sh+)f+I2OMACD^7ORUHO%)Qio2xePt%gqO>mTR)}_Sd7wIs_KmLG~+(4e-~? zswOQ!DKM&yL@58GJp<>;rS|8f@Y(ecCyWtyG{d;@Z1GLAla{Gh^)&hOb4pHuV;>GP zGIM#d;TDC|h3h@@5>hwe?)`_iZR#COl;|WvKOFuMMOpmZe|5x>phP}iqAy}NR{ZSy zN61;elq=ibDaO4<iF-A=BSWnqr{N;sQ+hZj9v9qVQ*vjGLuo70^^$Vfyk|vo0>acQ zOFZh5_>$(d!wvS+a+n6J3!Lbqp*c>IL@*DdYraRtHeH^c;%DcMA*zmFj*wd}W+2xZ zXog_#`i_=BwrU;Wva3s!a;MSCX&^^DAg1>uE54{{w|mFvLd;h+$F|$bf<QFEh)FzM zY%0fE|8}TqzG_bI#55;wT-47V#cwN)cyb$+!^y@C>6mJzL)y4&T7=ohi8r^bwdHDh z3Nuy2|D9BR9WWQ^muyN_$i-Ij*6VBn_3#Lj9UFB*4}}-Bca=`rHkzd?o$8z+IInW? zw1i}R0>FSG4tDVy4<AqP=EyC-?^5@=IY`j>`7-}g#t-qMJNUG=%LqX4rA1rc&|FeD zbGkE&%zFXQdQQ&pq_|>>9u^H$YHf?A6;pw$J~~X8LRg9q6#80-ylFTc&ILSiL;G$9 zZjk6rTQSfh_eUAbOD+${aW4vK_-Z&g>GCv#@wj%{&#E6$RhOp^lm3{gvny^u7AJJI zBrs(Cxbv0+NK?btW1SM>P8Re<ynKZ>{m~Ljo{8MFKW=CLk|ZNJ*|goDm}~d2br8ud zdzR30#w6D+YkGs6$XVwb4zcfa==uut{+eS~E1mcu&B;Qf_^~1!N#b^3UPJy7kuLJR zKhXs8VG^{W>eZpRA~Ac-s9F-9B*c@HKG&01NAZov{108XW8#OZnovE^<tLvVMxQ(Z zsL?$BV|U5AKAP^Y^?%+uZIc=4DR9Q>mFQitB*}!QayRE?G3X{sVw>{Am=dSU^u7!5 z@J#BpI{&e!P<ssFP;3c*<h{knc!29Tmb@)_Jja@4l}2Yku*UFcc8jTBI$LrD(qKIE zv74XT5ta4B#)?f?h1to%ji`vcnNP8uU(%((4~)weuwlN!sQBPH!bkE)5I7hs;FKg% zqRzB>-^TyIwM$VjHp#sKWCA@q<NT5jwSCdTi6z31Oy`Rhr~iZ1_M4#<mVVW@2et*s zc{0~kChnI95%=rVSLzc0#CG4_ww+OCMCSmr;k7q}T$!a?uIvt3rXZmjbjA*!JKa{f zkG`)GG3aj!@hSS663ycv^j5?`4E)mIWP9PGzvVos{mT@#XpWP7A+{b>L?=AWQL3Hx zJGVA@lAc;#J$*Y**~GT)6E`OvlBpmny@a@AP(W7phv%;)N$9zcS6z>$a1&siBJm$9 zO<(K5%>-QVcClP;$dy1RYG@K}qRH`pjH=*fG3{<v7q17AnKRFX+!byG%7`pzT)5v9 zKgen-d*?fjz3raATA+tj%obrG<m-9cbWDw=jD%*-X-_o>EXrioJP*G^vgX(7U!8%R z=tU~*efxR0*N9HheBY;lDw#1;8a|o^nu&^xD71d6lUb&z0DN7GWU*Pseq@>sjvGO- zOFo#CM@%sH`n_yXzFH1fg^|p_d%~zumt*lp5O>~~+4@p84SB|}3u}aTr=<I{FElOg z<H9zK)kNrZ4M=HHAkEhikAwog&*cYym=pZ?6}t1sGQ-y$k(dDXKn>@zOSVD)^3fnG z1kMn~snkaMljwnPxyA0R<yNn@jaS{@^(Gk2Fo9z<B*0zI2$*%o;>C);M*gJW(kIhH zVP9YT5MHV+valoF$@6eAEy@S4BfW#jFD+Q>`X=4AeqQ*g*;V$j7Z3k=9Zju4nbGMb z)M%*lA4lxnn7GuTwv}tHSwWhIfK{q??MpSZM%p+bX5v7s_2J4TEumdpg6$^IT^gbE zEBlhlYJT_e`*FMNh!`;A?n*!9*f|!0sP|>&VY_vm-L|Tg6OH{KTe-)t^jPAhxz--I zni6F$;D`4jLn4CA^@~4aHQ(*my-av2hP%XpVz}#DK28OcTd%*GrE7|ib}#@vjEUL0 z{8b;<NQ!J~<UB(I6+bd8Grjr7wqDL!!^Z*$A*evN%t;*irQRzEqx8q9#~nv46_lg! zKpW!PCDaTIEAT)0j!EgetFEpqh03dvT_ZEQmUB!bR-zag4ndsUswq15l+`wSOl}v$ z7IF8Q7|30Rz3~I-+FZQl3-1Ij$i3-s+4$`yqx0NEu=$>HO+lZL@D+pO<@UK)3;YU` zQTm)!7sHVnnncauO%`^>yazO-btbdE(Ce0_D?g=8!=-TAwveM}&fi#e$DjKrOkbI2 zE~Vnz!Sc?Ju_xumHZje=<{5AgNN0oG-pmQB7pB=F2Fk!5J|Gk_rjr2YyCEp@wFJyP z)CFQ5yg1lt9Y|aueet-cbvi!9e{f*q6_0E+2Q>uyp)?gWhidb}u|x)+8UJxEvmO$A z!g*<i8Gc#N*O?lsp|ap8<A|qV8)X@XggQd5q<Usi5Y(lZ3JVIhzFy-nu@C}?C--i& z&H=}YDC&&G3$N`|SZWl8lAqF85N@-ivgQO+LpuTr+%If$tx#ahP1cbY!6$cG&(O&X z*SOJBXjv4p61FqS&ea}D`+|1Q;8d9)S|C)g+(xpU*baa$E~|=C_LCFT$el@ezu_Et zi%Whpm&kvkH12{qC;##^$+!Sj;bYc~;`VIj28>FjqSW;V1xVQL!G(&Lz<F;e>MT#m zmG>fot8?_SnM75UgRp&AG*RQ*-jX{Xi5nyeq`x$^#ozUl{Yo5V5!8<$J0#md+%`kF z;_3YT0(qX4rz%1<Mc<6{4ZH$$!O0n-zk>AQPm|(CQ&4kPH^x8(`jw#-yQ+%LdA-CL zkp(6Z9-_8-d;+C~Jum3CD+Ryn@B*X3_x?M|<?_(Gmv_W|H8OL@snvH}Xt+<F84RRF zd9Ank(>4VMg?=FsA$06iF<0*NqgT(3j5h6)P~I0`?hG0>+0p4Hj7+>WjZeT+RZ)?Z zvEbh}rB%~W7ZJAJS4<aJ^@>CEUESCX;h48Y92jpOwJh@ob%?(I<?|TJ!557sJhfJt z3oDe%)C-5Ob^VK#dQTceqJ8=Gc73(iUXF2Cdp)1nfporhz#Df3TBB;QS1M!CC=*qN zBGLN!ld!7s^IiG-lzY@bhu%H3j?NVG!LX=L@)xg9CGUOMM@&;I(|q>C1HpXzqK(E9 z3TIpPgfr$uZ<|YuW9HC>`G?v{le=7ZBTCs!`}D^WhgLE>8?>t%uiOu&VnOq*&MsFw z9Na33Fr_F77;QBn^Qh5RTq=K4ZELMN|JxfC6gH6#S)w74A8r2abjD}ORdC>t=7U8Y zDO(>w)(cv|*E)tjrTm}^o0I4CffgHV3f4o^li_bT=wf>U#8p&OLn0ks<L|9t&V!$0 zPIX+OTgrFrId3=%$S4+KS#i9i*y^8fJR(Fc0uHIEK%cHW-1I)K%!Eo<t%o=!d7xk9 zT?o0hW!j_sBC_=$ue<OQ&F{)6yE@W-hUfcvg^Z85OcBkxL^C4jbDJOPoW$wS$wl8x z6Sl*e->vfOci)q+z=s&(4*88N$ja(k?K8gHv@tArhE(oQo=>at@l#Lov9$SQ9DcX= z`{?uf;RUhy)O`;p(dH4!Ti$CFE)9-*#UrWRRYac(Xp!rUtSm2l#8V>=bSPPr`P1Ez zw~~srAMoM$MCo^4GIRMySdPQ%xh4lZ@QYl`Uv@fP{TfN=0W;fD^5myTPP0oUzW0m< z*mhnwF_lp79h<6(5x&63t8>5Zri2or8Oy^96KiK*&7h3sj&r)@Vr60FBi5I!L5as# zoL2q60d&mM<BPh~Q-JFW27uriR3)Y47xII}ObEe|VN{K(<^r_&v1`uHUhN(4!#|Pt z6V0e|608-h+9Kwe8YiL9y&}e!Q%Te^+DzLb6A-sG6!|H&Qf{0=S60MChJ(|$!c`ze zukP6Q31S(qmEYS!xcp%{UaaV|5O$Z>7c-JHQIbF&N8h%ZCjR41W2BcluY<Z*<P0xx z=AGhyX|kbncXI`Eq_)lfQ|+N(VH}6zFz};0xN>ER)M$|N+TIo=c|_ndMpA1M&so!@ zk9vK#+|_0=DxcfVb=oxN032mWeHc8}?w~nD)Jm+r@;%>-WcW83_GdF2fBkaFq7O1K z*_TL;CC@G?h0qym4b(tGLVy5Yz)#~^R;(&Lqe|vV8lI}shF?T}HL8j^zC=NsYY)w! z`Qd8f$_e57KU3z918sYp4VKpRo)D~~j1N2Gl(&~=m2+p85CR<0>n2Y*%g+fCu+!@j z276RN`j>kz<7)>ldhp2CQjO@}deU8s7(M~b<yLJ=`5sX#>cgX0kSZ?&uHB5Ks+kmB zk0q^IM`7evdVpzQkNM@PZA6mqm-o}7D;aPq!cA`Zsw(Ex)Y+DK??2ceAl0g-2>s;x zL_Y7XK1GzLT<sIxO{_GguiVooI50SxT~ks(m*$|ZPVR=!W#&bb9=mTn%;O;pY2}zY zFMEhQEidqtRH!c#BRRJ)ft-~GZRou(Y4gb&=Ayx-xc#}UN;PA>@_y?f|Gl+IkXjz( z4572m5-qeg^SqW{P3L{q+l@bm3?_S_(D)|I@M$~&RF9^&$|0BnF2QroC72q+#gyZC zP&xW{MhGj#n&|ZyuE(9buvD1FP)iAiY}7noy5gHe_2Q-S-O%LB5v#{L-a2Brxg2rN z^N?)!F?~n$Vg?uDc{AqjJf(s{Olkf`QO2;@Xs17*hx2~yzzF;HGXMzhKS&w;6QAZe z;!kS4kk7UeFJV$ruMLNZUUl#LoF8KTl(@EDR3GjCR%l{9V&VVJP8hXKdpIqz?U$SZ zd>%0rerW2J0YZ;pcNVCpd?zdu{#zH$CjMZ91KB1sywA6@hkVx(pq=%}lR(bc^Fukw zHnTsv_TE<?Q`=c&_SjWVXh9m#oBT6DA32!ibqO6Uw|#CC&1NZ}+FYx^hh$%4M4Bnu z9yk}ClX6t3t<!Z$9<*%C76+teLtaJthfs{<vsIu0gc1}R=rnh=1MgcnyXf;e7CyES zsa*MI3R4?UfE-%9@tW64V$W*V<sD^7u%~`yO?GWpg@kfh6&n|nrkz-yVLQkl7iO^+ zjUl}vCs(l4;U$|;yo9cf#$=QEt`C1<Xc*CBL28@3*wJ;P9VXxON<GP=Y4jbv$1dY* zAH5#@;&XABLUr;Di>fU%(>@Q=m3wkDN4+cA-Z1`T#45Alab_vZ2Fzi5F7plkPho~i zd~}jznvz|#ewtgiTA;+`B^s!z{Wd&5QDa6_X`f*f+r*H*I9&blnv?R-EvlkmjiHYC zpm}jF&|~@j)E2TCzKUt#z9VrUEt2d&Z@U#{BgNoCPQ`olqS1pJ=?M@&$9Qk9;#<B` zu1D{%iQn6D4&wo=cJ}_$+G>VCC}fmm5Y9S=X88hE6k*lSU`YX#@3H{evIWf(AWG@1 z1?r2+TKuwFELt~L1a)rXazi?H=NpfUcb~e_+2h~YLA(FppC#8b#E~7mkU(y0zPh({ z*Yf6rhAWzsG12q|F1H+dLW)D;#tJp{rWVsi8&dX5QjRPxh?>r!ec>2myEy{CLt@h8 z>8)Poilw~`7F&)A*rMsUZyIfIf79}=09Z8feGcm-+f}b0#{HrA?-uX4sYhM_J~lWq zIO|b{J}#cf0JjR^f&vu8Ng<iON4q*Uv(ksVkB9fO!Vc~#D=WLi@{5?)R=2q&Qglhw z-)UCNjLiDMG<_zvYW+Lm%DTcwqqK^HxoNAS+gnJtw|8e--UItPNPvT&S3MRCvDohG zfe7dCgrP-b%42VR-I0XT;P+3g+Uy(T&!V^i-3BM8UCfyZqYuW(JXJ4c*e@W*hZ0I> z{kzziB7zHH89S`+-XR8a2~OM(S2sB9`z@wUWfyB-O%PzKHQK!xdfQ~bAMeEXHaL_y zYI1UC<#|E^-t8SM*tJR1%+k+Pn~d=t)>nvMV<=;({wI2Bk@b0W?iMg?JzVMQ1Y`P) zsxs2V@|f@&mok=uv1Z!7y4Wx6OBw9-=Vxavt{^=pwtqXbds@~@`bH@`TVJA7#il|5 z0p6S+D5xZ=Wl@i$geC?SG3{$iO+#g-KDlpdUku>h)VN9G4*KPN#n)|lRwjaKd#R}q zgH>)Ors#8@uOiUBFts1VIqojDiS`3%PLjoKtVLCSogHZ*^Ibfb)LT@af6nD7|LI?% z2bQwfRPZJG*QVUuiE2&OEb8n6=LJ5pK&9<)w{~KsH=A}%aZ)RxB#EY*r%w8bLwRqG zUIFc5>!G1yoIyX7UlqWH@)kN@&vg0^XFK+ls3RCyS@Vkq$Ksj!^8nodjMN<~2A~$O z%pW}=GtSHaO(ilrkoY$~Wu|!kmKxyUm+wvX0~qLF$Gz(GekX^j^`0pEN)C=mC^0j; z7im)fYEOnz>7WQaVeLrokK|cwa|A__GJDAsdg>}}0=mRc7?)1dyQ`IZXF!)5;Jf(I zi6xjCCeZ<3)LBh!)RgEs<l}5D^ehu5FQ3zAAb`*2*&<T<D6nh*e%2X0ZPx=g*a;jL zn<8r>ujX%j@t`NJ69fe3Z~^eF8X;wja;1pEBGT{wo8F+)TbRr|^lYdLAYD6z^nm%T zip=%{Suz+EY<k(S$i&pt@X#tx;uFa)JXWiiX&tC-7?>t|)`PQ)s{WbMkE8<fX>oB$ z?pw3ZnV`PO$$v#7t%^7PydS6oO>0^cr%|N$NtD#o;vuhkI28&@Ka$ud>bmX4itGF6 zk0c4>b7o}r&8RF>8}<O=$;zHd%<`YuegBl|luEcAAaanr-~qHqfZmyonq$y>F~(-W zCvm`5jt*uj`_?$CqBx)bgAK!G@FxoTr~jd*ejWLA^GnrlMk#bL>@ngJ*9k&%SY{;q z^izwNQ}*S|I5<IuDcr_S7!7d69OnU2)^KSj{$=JFXP81mNAs)}pYx$B`O+jQhQ=iV z_1NM?Nuk2u52s$2bAz&c`AmRQ8AD{21KC{?Ohbg9u8ua0a<_xvza0ugask}{E@>?l zG2DPAe8vRR>i{YWD0l7vC2p|emB#ho-v>*(PpyFbTJm4;Q&W3&kpy)Ypqbtwb3#|x zw5F1uoDpzEvgpjxzlaPDMj<`o!S8skqCB-o6{)?#Fke!g68GN+1rQ>0AyzSCNV#;Z zqgk{hmfA)zDwH~4FIBA=mr|tKXmihq{4f2fD-JgAzlJ8*lF!>XDCf|)Xm_Kc%KWPf ze_#23o{Q~Cejsj|mrGR)jEq<l!FNuL*1Frd^9kFk!vDjlT9;EzOX<YH`Bq$nJ_P(7 zOJ5yRWoZFjl$9mAs@26WMn=X98>40EBOtx}_d*j^ALoj*NSRUR-d0m*wIH_)wD_d$ z5D+_gnsVY%5c?mSi^i+)JFpxVmeN2)QB+jqp{wB<Fd1v~RF~CM4A{w~K5u4D&HhOM zRARLe-|>h4M+m^jKkqD1jd}g8nN>kXh7lmcP?0644w<UzBq(|OJksK7{f|mT(*oS$ zg$t0==)h!C4%5hhQiXk3nwlKOL^P(4J!Q}8t#FWIn88G<)J`&X^nNJs?knR0sM^wV zw4o?p-vfMD`0VxHmx?*gYQA{m{vF$wN^11?$9WCfpYI`TV0H4G8s{6_hHfIj*Hl>p zTE|+bw@0C>Zi;-}d#$ES3U;4{O8u`WCETDNjswUZNML5WTc5O|kE%y-2Ww`Zzg?<g zKe-<#!*=_ssuiu|I{Q0iyY?Wm5oY{9GNo)Xei;qwrF+EZ%GeXvUhs&gWa;f8AH2d) z)A3gpwi(PWsR?Llc{Vr{Y2=~Mt@7r-dpcT=lY6})DgK2BtngaL15$i^!gK&vhHxv= z&jd%0iyD5<oN%Pum(d1VYx=c?qguix0{2dTbyA$ht3bw{(_M4Qy_z}fuIm|s=jFak z8Ye~E4L<A0w#5r;4OA}LT-v8X!@*E_WD=5b;t^F?$?hhtLEM}BKFc^wT%t~2QoG56 zn-s&E%v*7@26mJER8RufH&tYX=obITrU-Z8P>e9Xibn)w30gHZjcG1)TNVPCg#v#N zcFgBL?d<lg#*v-)X|lZKW=f<cvZ6wqk(~7MYvrW-EtEl;)jMC*tH+vMIu(Z7w(0cm z>Ja=^Fdo3>w>oT}{z`9;?R@NRM6I5>mrdcA*@hhFgO4F1z$sgqY#L`Q<W!DPX7Nz~ z*3WSPFEJt3=~zsmHZq^F;w^QSnFZ819bjF~Enkt`-WUwWjR|+ftHCd0xt*@ygI#n{ zqOk%QkBxU+uaR_xiUIx>tnKRY1QLKIbe?IR%>T=@*mhxQbv+T@+T#jBBh9!%ZRdYi zE3x~8O#lvQGxb>t0&$);>)o+h4iT1G9v=Soj1Vk-I{D9^KLioKi(1mUzI&aXqW2Gt zbyqQGwsEduTO6V=Szu0CA2-??W44ECo40}eheXychp^`Y=<sjbH?IjFmd;ObmDa%T z6p{WN_z-Hiqi@OZA$&_Z5Ao=FF-l^03^5&YH@UPSa?0Ectsw~a1rGaZ@kMR-IJD7k zJD^T@u*5zZrjQ?ML;Sl|jx7RpJ1qg9KFVo+)*sRV)q%dJ_4K?4d}bdG6!Vz-Q1X#; zSQ@A~dt5@_iiiy48-Yu(4GslH{95}wO9D6%l3E)M?J|%5JVy#${yiWlXqg|X;AJmT zoWN2Hhg9)WZ1;^Y`V^jdzBKT$3d^U*N;whSxr5T72t-zGHb<C{f3$1=YyLIm*vcQK zbVeLnH62cE`>nJSKr?y!p#<i-)G~UTduijz1qBR1d}gz_mQ{?wMhfE00DkZkQ`-45 ztGYM<Vvko5Xdgvdp;QFFZdhOUGQZLOXd4g_NZ+6-qB4DX?u&R&baeEm$D}O+lSnhx z_n>`=I)h8jokIigO1+3wdA*&fmi3v^g2i%a%gN0i8HG@wNa)9Znf2m1hyb4jvHVSL zvS=soS^?=K0#NJi#iq#b28@dL@d3OkIewubqxyi|nYYy0!J*;Q0$>@Be;6IoH~IzR z<+K-YAous-&ACTX&0&=Nrb?~StEt##BNXy`QZB2#vCtCz%%EhRVC8#(`nwB&aCRgY zRcU^6f0*frvSMsFC6{>CVI&n7q+#pusCzbMV1K=IG30(2(7Akm`)KOvI26SAcR~9S zv2n+zvEF^Z)~<I1Pep;xKsm%8{>c|_a+aYklw(qk0X9}vpsVeawK_?gT4xJ(1LKl! z(tvR!^z{*Ye@Fn(822XpJf{#uKH@F<549O4@5-8wmd-9C=oS^QL-p_lC#}Z=4PY~? zCcS=KgD5KMO45mrwhgHD;w$$HRhb<E9#dd{@Shu-*+JF+Ep62k-Z6VRnPCt9tgFi$ zf)<jKllL09ZB>&c7&psZbCk$zNCSnV_+w_1a!9vf^fWELx!1D=ZEZY!LS+>dQd6S5 zJ=InxX6E`<r#|eaOUhTrO!B28$@8T<Cxvb$UuGi8=%N-LN3nDthI!~j_%iA9Tuz&n zoaL>iRYLxKi2jp2fL~BL&^#ArF01O8Z}Jq4)KJ+n^f_1CKZ{MpnUL(FneDelq9tJ? zNm-LwtTf@^kfMpn$P_B!t{eXVd_{ZP3AbywchdEk?&M|bXMlt%=Z!?9X(A-UKC>51 z9Mta0>yn#$j!?(FOeyu((dHnce|@Ir7OG@qMA($;@*4mVGU+-3EvBC{=4q;~iE#vq zrMv*~lGe4<dH8^Pz%c|kAHv^;mK?UE<hBWKiV}P$$zBS{p-r|nxOv4{cK3}w6BNK$ zXao0r@|6erm)=J!s(F%J2VTk79%6GEM9F_8?u-X$tHsCzW1hupLPELv8o;7uXeSM? z<oT;un)SECLqMLYa+(f~YMI?mqfPA~aS6$o>E86OS{nSOrczzNwg<m}<;Ae;JIg=t z?M*ACw7)eC^7tb<#^EHkH0-v|Zo*T)d{}13wD7=P?%N1>zNHx7oW1n_;!Dd@(>l5c z=Ln@^Rl!BL9Ylg81s0zGAoonOjtqpn_uX7xdEB)%s1fjZI^T8>#b+_K9BtgmL;i}) z)2eK4EdLc_c5ez$-aj5kxGH+|PDk&Qx-Z&|M!y|hbKE0vqMlpECCUokYA!p}-8!sF zE$t(7<)&&@SN=M&FRhYO0$;*b=r;ey85;ntj%UieX(t6}R`x-J7Aq<;iZaE8`VKY! zn95t7g)=fu((uzpWS601AC8ou=?l%NR!_!R1lkfq!OrQ!t!EDsiM-^)O(iy6$zs-e z_PEssws)L>o^_pC8LhPAZK;~zR-yF$=TQ%p#r%&{7O`x2<>PAN@nQvO=j08mj-i~m z?^{w|3(EU%DGsRRs>P<qZQ@Q|iShuu(v;KIee4CH<8|D?_02qdMDujnBR+)SBaq2J z6~xD+eXKj?8j;l)(*8!hm^Tc+PB!#}H_^<5s3JJu$JE%a*bAhqsp*JIr0~i6hsqWM z;muxo&rx#>0r)9^_e?gqWareRO;%AKqi5`+aAW;YCr^gsG4%hPAuB-@z1d^YjoGO+ zp6x@JA9AgrtVR2qT*q|mDYm4j)2Few<lVWaJQGY;M6fRAFxj-0T@m5Us1!&CN+B02 z9y*d^y_rH-O<9FXRr-<JHt&`5!)hy(FNx0iKmoEJlxzB%?5}PHlUd=7tDTjRR5BNv z6-5EmYXEAFRh=v-s3`(9i?3H%>n14Vbboa?gUk}_u~~u%@ri%fEC4S;lb;il6dn9F ztImF~2zNB#^M(9s;uzaOtPEx=6zTG6AiBzl12Jj7-CQtg_~pA~#7(RUw>WLG{m#F4 z?ysb2fq_5v7ud!htS9eJHLAW&k5y%N(9G7F)+lVy<q6!w{@9hPTrpHc5jP}E(e2EN zWc&GNk{D1K0)>@`!Z+bLa@%#xj*N7JW=hOIQkhNNz>r$ADLumdZOuwRmN%)!4OY-T zJ7~i9RmYt5DnXmN#$T;??bCG>DHH&#*KWHs=l2Fh2O3(iCaWI#k8FWxL`%;xzF`1J zI^klw3?ET%om5jZ!6S%{CsI<GbEh5&PC0n)l|mJS1$uYjYag{c$exezYQ~DIe)*0Q z3=azo#WG=bMie!gN1N%RaWU>Ht-c<J0^!b}Cu={=Q29X7u~Dw-oS~eEen)jjr>*g9 zXvcpIl}6~t#ESbLK5A-vb@lb4qSFNmazZ5_r18lk#VrmJ$JL>k9`4Jg1wL>V8B|w3 zT9;c=RNsgm*>_YIss5ASlVW3tKj=Or+%bshhQPVAC5^D5l-f&PzdGvDjobhEipg%l z?`@o2yXYSgIy20<<#Q`o>qZR$tCLN>=s?Mm!E+GrZ55JWo@RTSIFex7Qomt2^g8n{ z*2&g4a&FcV_FsK8O_=Al^LrER9Z*HaHi2<>!^>A~-J!S?GaQ|#Ui0jg4o~UHWOzaH z&eom;uHuk2<w`~9<Kh~T2MWDg+3l9)s=Ei{HbNP+#d{3X?C#{PsA^1X^23#5o8E(y zB+AL+=#R%fTHZFWt0pEcWy_pfZJs0%{e4m~W<}!ron~Fg?xpYjvmv*isO;!}jc|_v zZ(OYPQy1F^&|_=DXXq1X_8e6GHyP-?<-)|~P4#gn_4A2Sf<r}(e^%~Yh@M2H6G&#J zY9E6|lV{Fee1>@Wow0gEvc9~|=-YFiE$NtvS4q5W{uJBTOFk;ZmguWLJ9N}`S+-L0 z`5MQGqB&@(EFI`jnTSoll9YEsFsS}2Au-aHp)X*w@b15G6REcja$AjTN!@NLDzXRg zj-zlo0kF5K9b)9G$Z{4SPYH38RMj_A(N~{1M}&^74xT=eeCc5`+*(_NY7nRDXY|&N zStIp{*}89;r?JtbfFK!t9U#`-PE%I<+jG{&i%h4hUSM-Kj#|g-%P><|kYtHqTJppX zK=G?Ay0Ll4^!p;Wo3DJbvAjm!)_XynYS>BGHm^>uH9L0gD!;-65BVPjZazsmXg}w> z8K>_=i5x)(iutF@LJ<9H!PJ|%s$ig(C$g$N^%d^^j`NiH<tiip&#VpVLAhl_1+CJJ zn)`PI(ArK4)g^@a#j)n7hm;@)WC!~b?Dm~oItkS0z0aFO;rgU4b91MIuq6-JPPNuS z{S9s6$7H&-B6#d&UGK2AgbkmQHfu%w>H2;98l~XDa5{$(|6X|Y^~teX6E;y_2>qqG z7@P*d$j6!Zaq5x$A?AeH*WLH^V@plA@MmWGi#O~t>*0T$%5=V8;391;bU%}QqLObD zcX>>?nPc*#gAGgfCjlSkhH-XqNMvqK4%c*dk@?hI*u1`}vAj^a|aqw!ufColN^ zPKI_`tQ?U29L_Ol8ClkH`=PMY#?0p#-8Xhe49ReOji6UmUwK!7L56goUQOh0cDi*h z=q}*P<a_yC5d3Ad=?lVV?DP?U(>(W_U4}ivi$1(_`DVP9x#@&E;o)d|`BL9bqr~m{ zDEGe#^82$Ck_-#Q2^{4o>!IU$-}BZ|5IYE@UKA`1uazW}oRN1r4N#{t{ka|r>+1-H zvfbb{>D(s6;Xzklv#~;OuU4FVx0=?`9-_E6`L4l@UhX@xC2>+nx5R9#Yd=j>t>ElN z#B2v{x<bEv`Z>OWkKD^f>*DOvh9KWto*Qr3xnDl4=-wTxwCS`X`%&r%tkfq0ILXr` z&D~uG-ONX_MbaqIn%EM_@B>srCJMIl6u6TYr}c|@xM#xoq8*+uj?V*<PEfE_<aw%{ z<MEz5lXWyWY(879H+5Wa<V(hFex^<7G>4J9?C_}mA&4wDH<vq;)$big+X;G-h8j@8 zQoh%d?5QBu^~wXG+5S~VexLtqgbo~Ls_m=*8$@eWdPB#99Ry@=6i}SW=da7Scp}9j z>+RvwC(pS|b7{%uef?VQTKxJJeEw%Xt-mt25iuf<Z@oEGRZWcsK<~KM!|BJr%37(l zKhMgQ^8u9&RWG|bhsPBZNQduJ2>lHg)RPZ*<7?Pv%>Q;{sd*;h{Le5n7p+Lttep5T zsg2%-bmYAL-(k1kzx?u2EK<b5;;%P@yVhTfRpfGm#@&;|fK;+SNt$V>s4H8h;y=lv zPEo;nA`p;Jr^3NNiMPa?n>&?CB9QrZF~mahmTS^R`q$Ba_*d}rvX5%x&Oq7v6<1e@ z4F})i^|rkoM&4t%`D0!Un5$qG-J+$OWpKUC_1D0DGB81<v;BA51E6`L5yTJ#3{+K5 z><a%D2VPxSSsBWnQ(>sQL`Ixa7HzTLiuYI6F>5YBvdGW)?Hke!?^TN%gJDv}udWvj zA1Z*mJYW!JSe*rjhhqI{0Dd2r7C+A8{~vO**CEh@NAEXXW6PJ74$Rev`51oimy-qY zzQE4^gshV<Q(?0p@-4<<VO(0(q?>DRnK2|DCX7G&R}jH9IDn4LLWSP_kH|m#@0!n1 z<?;P38-Q^{&i|G3|DPuo|3A+10bpZ}r0oZXf}l75if5AQ|2<~uC||*ny0Kxz#8j%W zpcIJ&z(T#f@d*imo-}{O$pYN4Yi_;VeXWx4YKM(zM`zW2%i`fm-Sz%HvdnB<u>ATE zo>_WhNqO`%E!X-|ctmw5>>uI3N)ba4_TmCToJ6I;<!$5jiMX4MQJ+of_1e<2veq{h zXNv&z;${c4IJrWg21TwX@+xK(Qq3Ae>Ah{R%M`tdXUeO`RLlH7Yqy+###ZA;u)m}n zs)_NI4rRA=V_HzWxio6;3(|O>*?w%-HfWh%&3*Mi@eoQ#i040%in{@?@*MeQmJT@- zdNaH#`md7i72u6ayH{PFZEIeC**%%fRyrp5Wb&=`*u|%L5XI7NwZ426DPg2fNu;xH z=C-%}6t6v^JblLmi!ZUSoE+WHp(ZWsdp6KhO@9qFdszuI=EQ$0&xBijKHeJga%Kn_ zI^v(P0udMQ-iIY>65PNZS6mZ(eh!9{+8N4PUeq;Ekm;S7>n{*>gGqh5l>)hLIdqaS zn%5X4kfVVCqAX6}1$1t;kB>}E77;+&!fvd^sn;an@xAbU-aLuTzcRJJLjOv`Y|5H3 z)OAOs*zQIB(U`0!-u!fZ8FNsHVniYzjP!{Zl0FY`fvx>V0xWjf8D`2BSRH{gi!ckY zz7CHHAGAsWXD*(u)xbu`)~N`D9)u{lvu8$NKaS3n3C=|y2Nye#;qmFf8~7*p<P5QH zEmIB5BMT<oF4B7?It5=pdWG4()bC|P0QkiEPT0h7);Hd(pTkL1T7`9!WaOJJT=VF8 z;m?VM9#f<G3#w=8tS{BteOK}xOOP`&|Fv3acVKRGefN*0$W=>HfU3FuNW*V&r0C92 z4`P!{dun6F;x@+m`qPIa-(MwtTJQPH@j@h_K48Xtb~@`K*%q>g&^ZEpv3-WJq{E-1 zY6jIna}^f2l)Og_>XP=kIgn*KG7yvO<Pp*H3RWF05_xZi32^Guq(qj$%Rf*B#kCy1 zo)~y|8M0T(_$Q^s&K(vigtSUI8I7M!{>`TsBcG9=3A#>yEqgGf(Z=yEV0fSRj4dJ? zwj0@`2}5KX$w=cqc;=~j(aFG=H*Y1XIbj$YmhC-C3Sc2jRf=b801&jQ^J@BvX|tKr z*51VFeS}M9bN&uy`l<1aJ65j!NWF>HD~J;f;T+445aRCm6NBi=n$W}ZT0Dhh9dgMJ zi#;ddS6+z3nXD!&JqN@DOC^RsM2o{$Fbp<Me)RIGsO)*UliIa4l`iCydSw4MXpP1S zXvX1_iQXObnOvoc)NEnF^i=NoT<}CGJ)#o{d~|)=-5xtzk8W&9JT{S*b?b}F=4ADK zY~1XT<jH$w>L2+Uj1l_3^uBzR$`ve=FW6eQTji)tfnf1AXfA+t6$P8z&#Bi;mh)xB zgdeA{(sTeXNV};l-cV#0i?Fdo?-&uX+soag>73Z9|MQc}mba>^$9dmUtOs=c2N@Yh z`mPU&$zxJUl*eJn`C8=Puwj7;JTzv+S^~Wk0t`P9=IubK3TqA98-TUZEKGTUqVBu} zqA%FtcOLJ60wl~ysh~acU`-=ba7iq^`H?E|BwtGRL&WIQK1Gwi$_H2Len109CiIcK zZhPk&5Baxzl4e<EAis&yRsWdS{GMjWdP8`;58Xhs<0*kiU+)<QUxETZImR^d#LZ}9 z@nXMc;zKV?PvRhdeGeUX;c&Yv;xwfX@7bG42CFLIGgL3<a1^}#Pf3CRC9w)}HCNf# zm#r5VF$=rQJ=?icPdhow<b2()U+@1~Q?n^^4bIH$d12Fb$e(RSn@?g!hK4pmtbL3) za(N*L5Hv8!b<DBj9CAFFWpbRY*4E1Oq}kt0F}<P3$n*mfIa4D+S*%yu{mH}8%FQ}g z!&h}L)-J+J-~o?;9WJyPY?JgYm2<3Xs}~q4-0?Ro*?&>af8-D&0?PNnjo|2$G)()N zXMQEfj~n$Ee$&eGz$q+KL3iFC*iZ5mE*h^{2L^H*_$WB-xFMz=_Zc2%7!kBg@e+CT zWN?2*kGG)X7l$u<5dzGTc9=^Zl_`|APsu^)W90PGWI8Yp;lL2o+GsCZt*IzbNAxlO ztnZy7`aTiokrjonnF48q^uLnIx&G^QtJji|O`>}w2%Gbv?j(BxDk{mY7qz<c++n=> zHyA@aKi3ZV6PhiHj6EBX!j2%jt4GDW#I234*4>B-mm7rcTh(-V05PfYn$Z{k4I-Ny z1E00=JR?n=r(dk>ScaI!{eH@(-ai%FO1T6hR!7W#1700)?<@Ylv)#?;M#Q34JX6I; zL5k-3!!wmX!io5MR-|Y5JAcujBJb)wjd8oH*U@m^^SZIG7E^;;zpHMtTKzxlKH>Vu zYGmd?s{sk}l0D8%>lRJhu<7zLAkRD?JPs2~<?Stu(fPYcLQFK!3t!J4dLx<R(>E}8 zpN4S@vxn24=uGU5XhMpeI!NzsR3GzCn;lh=Fthf2Hi*MdRKLBh-m4}+;fnY(n~L`~ zeHg*Dc0^0@cuArjNtV19Yf6Q2SP;{XQzRs~0Q@K$#yDm&3fhCR@%?K{F>4IJVvdb3 zH_}p%E*G|>WwvWXzR~0U9etWyd}}50E_r$s<qE^&aDLyLBst5OFN%y5bI~YN?Y1I< zOr!0FM3iq|lfiWHLs}onDEG^Y-NAl$YM!>ix0y$QwwnzHWt<iTeO2}JV12x+u)mpA z4K6a!_OF;!+zhk=U)c&ZrTn0@`F*<O#P6$>K5ev8ypBJfq}(I9_ysRU-8|X)P(Pfn z_l<GuNEs5Up)~xak8=44n_Wef=#yJ$yt<@C<2M^{G#;*a{kp4}mehRp!7s>e==T?2 zF{j>8Q6Yks1cmN^NoX4+?2@esK}{5|$S+LA|JkGeGZKDRe3KI>Z*xT~6Q8fvyR<Q; zF9S|W6+J*2vGL~h^L7=PeakDmEi16YsZ6?|H-)y9&zG@j*g1P^pE|f`2819jxGgTK zPVGS^^d}>0rW)iP$SD?<xNr%iNx~SJ+l{@~Fnh4P(Qt15EtGtV<*2#*%Kl85EsiMZ z_1*Db<6Ddcp2KXRSBinl2Ib;h)nRgw46U-~wSpSP=)_TgyOx2x>ns(~#!_D0ltn)0 zMk}%j*-eIK8{bdV{26^!nHybzQ`hmQd%6&5Ka<anl=ReEnpmtni2$==B!}Z<RuEtX z`#?m;;&Tt=aq}~Gz2mLT*GZ4g)_1b`K#`kKoXs5YS|zPBh;x&^Hw)oqM7i(q`pn&J z@7VSGJ}@wYTz~IbWQRcauYJ5m!5i;qw;GGI23S<L8Z3rZiOT1D8Edt%s+|AE^2-$U zY@N@G6^ML<4`Qx2I-z;;F6H9eIGll2<qJKRyl!!|YX-{?t<AfU`H7J>VD^U_IpQO8 z<bv4N+x{9VfDdm-D#VwLCB>S-C>Jqg3jO}l-Q@&P_K+{oqjdRV3e;TXxe98z8#d62 z<qBrx95uU%e$RK>wiy9WY|L*;mU$X^C(K-^H--FHXYgbJDQW6Y`Sz*XiN^Y)wD>zL z%G1-VXV#nv%UE(Ap4}?IcR2Ykjfaz_h-X>}jU}bV={pLUEzBQ7+cQ^CHsJ}LOq;PB zTF&;k?@se(F}^>6T_1<n_vYZy$xgvD{4)oRsWRc2+^GkFw`lAo9JBdH$iS%KZyPVf zZ`F+XRSf|f1v?5@oDtb=q$O`n%0_x*iG~lKwjR)Hb%XULJ?%Sa;+8vnmsrmZ;l$=l zFa%tSi#gUYR?lBm?Ft7%hn*Q~-bl;nJpg|++09mX4(PNERfZ^#^svI(LJcb$OFlO) zw|dXiKaI(-Cd*)odb1%JMIltOP)GvX_xz0Hi!~}bI*o!Ej#2%x$_|=oPGF1^to~|C z0bz!8o`>x#X@-j05Wpj97#T}#?8$zPOPh}W?)9qd44hU@BbQXL!#a48DSSpKVpWQp z(#p5X3+G%pm(?!e&|SD)XaI2@%pR=;mG;IrEswbYH1bn#K}HwyCr;n-d>5a}?Pb2y z<0>W;M{aDDel0kp{9fq4*aK|p5|Eqaz30_T8|EE!I<U|fmey62l4|Fs-h)|Q6l@Y0 z(Hd-M%({_3>ofcQE)5xCT3shl;*gW$2)>@XDi=c=AAR{SEZSDyE)1v-A`A3z!s2it z{NYH@3l1@5&J^f4iqGxHyF<_*J|M`Cv*@-k&m^DbTTHP5JKp5trdlsAMJJugi=?G~ z$eZKo9yVSX+%D<wH<|lw6pC(HY`yVzgNSVh6CBQ;9^)MgaLnsWjZN*0PbTeTAWezs zOLNsux1I?e=~IBMyj<p2pW*&%DvnQyH!a!9;BKZ}-n8kL)JhsSY{c*1nbEQneNHph zK&AGW^{H>&#n*SOv|bIh-^+xpkX{PXrS#+wsl28}qEIT2=_WRgzqWP)N||%c8x%J~ z@E0G?50pG33%x-{<>u$LA5$T?rrkn2IZHiJP4SuG=yy7c2}o}l1IzG3&WYVoj8#%a zy4o@8d>a!^<N3<lb7Ey!7G%J)Mr4eIn4(U6A5kuh<_GexN(0#Ck)+_A@~Qku7J#TE zQ0uD9AN4g%OsXC$2DUQ)YeU2wf0?ganfyQd+Uy!NH}~cgSxw*w5?}kxP1YH}B@a;* zeb=V#eUS;=nLJ}*_}!EGe)&aj7yas6_w46y@d=6FpViClo|mXQ|0t_No}=MO&$H`I zviKkVsO$o_@+)p2onPdVCBqFJP4TeE&T|l6*8Qo=LjyJ$!U;Nm2nuL><`3yTXh@!= z)@enc9<kKq=m42liqH{^6NXBbnu=GPGq!Eu%jkP*9tO2gC1BPgXg6Gm2FE7-{_i+x Uo<{YvKJcX|p00i_>zopr0KuC2=>Px# literal 0 HcmV?d00001 diff --git a/docs/docs/images/sidebar/2.png b/docs/docs/images/sidebar/2.png new file mode 100644 index 0000000000000000000000000000000000000000..d29e16734b0372f54413601e905fd66b0b7703d5 GIT binary patch literal 13377 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 YIuFN=`nr)6r9-IHRdt?~D%%A8FPutREdT%j literal 0 HcmV?d00001 diff --git a/docs/docs/images/sidebar/3.png b/docs/docs/images/sidebar/3.png new file mode 100644 index 0000000000000000000000000000000000000000..e35709fcfabc72ad5769dd64a003bcc62ce24419 GIT binary patch literal 7146 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 NP*>J|j#RXX{0|E-yL$it literal 0 HcmV?d00001 diff --git a/docs/docs/images/sidebar/4.png b/docs/docs/images/sidebar/4.png new file mode 100644 index 0000000000000000000000000000000000000000..1dd46ce617db5c08639aa5e52dcbb7d600f6c958 GIT binary patch literal 76726 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 AI{*Lx literal 0 HcmV?d00001 diff --git a/docs/docs/images/sidebar/5.png b/docs/docs/images/sidebar/5.png new file mode 100644 index 0000000000000000000000000000000000000000..a2785ea0c699cc75b05c19804314ff35b6a0eed6 GIT binary patch literal 19307 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 literal 0 HcmV?d00001 diff --git a/docs/docs/images/sidebar/6.png b/docs/docs/images/sidebar/6.png new file mode 100644 index 0000000000000000000000000000000000000000..67a9e6f55449d6e3be6cd58cd0136f2e8da286bc GIT binary patch literal 178081 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%0AOt7FT2lgEC<n(-r2hyYwM+ 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 literal 0 HcmV?d00001 diff --git a/docs/docs/images/sidebar/7.png b/docs/docs/images/sidebar/7.png new file mode 100644 index 0000000000000000000000000000000000000000..849b37cffc5e2c83e59699be5716221d47ad8c6c GIT binary patch literal 35847 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 literal 0 HcmV?d00001 diff --git a/docs/docs/images/sidebar/site_url.png b/docs/docs/images/sidebar/site_url.png new file mode 100644 index 0000000000000000000000000000000000000000..1e9494c80e68a0117acf74531d3f43aed0f5b53e GIT binary patch literal 40446 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 literal 0 HcmV?d00001 diff --git a/docs/docs/images/transfer/disqus.png b/docs/docs/images/transfer/disqus.png new file mode 100755 index 0000000000000000000000000000000000000000..6ef859688afe7d3022d511afcfe64cd01d86ea84 GIT binary patch literal 33070 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 literal 0 HcmV?d00001 diff --git a/docs/docs/images/transfer/leancloud.png b/docs/docs/images/transfer/leancloud.png new file mode 100644 index 0000000000000000000000000000000000000000..8a676daecbb374fadcfe4d5157a308771d388627 GIT binary patch literal 37967 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≻1Vc_GKc%3z- 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 ZM`jf4E*u*Yg%z?8ppn^`3InIe{{iBT@iPDb literal 0 HcmV?d00001 diff --git a/docs/docs/images/transfer/tencent-tcb.png b/docs/docs/images/transfer/tencent-tcb.png new file mode 100755 index 0000000000000000000000000000000000000000..f906f4d3a813a1a6a723ea084d011f4831cb7c4a GIT binary patch literal 16192 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 literal 0 HcmV?d00001 diff --git a/docs/docs/images/transfer/wordpress.png b/docs/docs/images/transfer/wordpress.png new file mode 100644 index 0000000000000000000000000000000000000000..fc982699b6b96ca854e3b5a7c922d5354ea0d0b2 GIT binary patch literal 53907 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 HUby`?nM{t* literal 0 HcmV?d00001 diff --git a/docs/docs/index.md b/docs/docs/index.md new file mode 100644 index 000000000..9b15a470a --- /dev/null +++ b/docs/docs/index.md @@ -0,0 +1,32 @@ +--- +layout: home + +title: Artalk +titleTemplate: 自托管评论系统 + +hero: + name: Artalk + text: The Selfhosted Comment System + tagline: 轻量、安全、易上手的自托管评论系统 + actions: + - theme: brand + text: 快速开始 + link: /guide/intro + - theme: alt + text: View on GitHub + link: https://github.com/ArtalkJS/Artalk + +features: + - icon: 🍃 + title: "轻量" + details: 小巧的文件体积,迅速响应每一次交互 + - icon: 🔒 + title: 安全 + details: 评论系统自托管,一切尽在掌握之中 + - icon: 🐳 + title: 快捷 + details: 简便的安装步骤,带来简洁的评论界面 + - icon: 🍱 + title: 全面 + details: Golang 后端,支持多种平台和系统环境 +--- diff --git a/docs/docs/public/assets/emoticons/default.json b/docs/docs/public/assets/emoticons/default.json new file mode 100644 index 000000000..2823167fb --- /dev/null +++ b/docs/docs/public/assets/emoticons/default.json @@ -0,0 +1,306 @@ +[ + { + "name": "颜表情", + "type": "emoticon", + "items": [ + { "key": "Hi", "val": "|´・ω・)ノ" }, + { "key": "开心", "val": "ヾ(≧∇≦*)ゝ" }, + { "key": "星星眼", "val": "(☆ω☆)" }, + { "key": "掀桌", "val": "(╯‵□′)╯︵┴─┴" }, + { "key": "流口水", "val": " ̄﹃ ̄" }, + { "key": "捂脸", "val": "(/ω\)" }, + { "key": "给跪", "val": "∠( ᐛ 」∠)_" }, + { "key": "哈?", "val": "(๑•̀ㅁ•́ฅ)" }, + { "key": "斜眼", "val": "→_→" }, + { "key": "加油", "val": "୧(๑•̀⌄•́๑)૭" }, + { "key": "有木有WiFi", "val": "٩(ˊᗜˋ*)و" }, + { "key": "前方高能预警", "val": "(ノ°ο°)ノ" }, + { "key": "纳尼", "val": "(´இ皿இ`)" }, + { "key": "吓死惹", "val": "⌇●﹏●⌇" }, + { "key": "已阅留爪", "val": "(ฅ´ω`ฅ)" }, + { "key": "去吧大师球", "val": "(╯°A°)╯︵○○○" }, + { "key": "太萌惹", "val": "φ( ̄∇ ̄o)" }, + { "key": "咦咦咦", "val": "ヾ(´・ ・`。)ノ\"" }, + { "key": "气呼呼", "val": "( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃" }, + { "key": "我受到了惊吓", "val": "(ó﹏ò。)" }, + { "key": "什么鬼", "val": "Σ(っ °Д °;)っ" }, + { "key": "摸摸头", "val": "( ,,´・ω・)ノ\"(´っω・`。)" }, + { "key": "无奈", "val": "╮(╯▽╰)╭ " }, + { "key": "脸红", "val": "o(*////▽////*)q " }, + { "key": "悲哀", "val": ">﹏<" }, + { "key": "静静地看着你", "val": "( ๑´•ω•) \"(ㆆᴗㆆ)" }, + { "key": "不要哇", "val": "(。•ˇ‸ˇ•。)" } + ] + }, + { + "name": "Emoji", + "type": "emoji", + "items": [ + { "key": "", "val": "😀" }, + { "key": "", "val": "😃" }, + { "key": "", "val": "😄" }, + { "key": "", "val": "😁" }, + { "key": "", "val": "😆" }, + { "key": "", "val": "😅" }, + { "key": "", "val": "😂" }, + { "key": "", "val": "😊" }, + { "key": "", "val": "😉" }, + { "key": "", "val": "👀" }, + { "key": "", "val": "😌" }, + { "key": "", "val": "😍" }, + { "key": "", "val": "😘" }, + { "key": "", "val": "😋" }, + { "key": "", "val": "😜" }, + { "key": "", "val": "😝" }, + { "key": "", "val": "😎" }, + { "key": "", "val": "😏" }, + { "key": "", "val": "😒" }, + { "key": "", "val": "😟" }, + { "key": "", "val": "😕" }, + { "key": "", "val": "😖" }, + { "key": "", "val": "😫" }, + { "key": "", "val": "😩" }, + { "key": "", "val": "😠" }, + { "key": "", "val": "😲" }, + { "key": "", "val": "😵" }, + { "key": "", "val": "😳" }, + { "key": "", "val": "😱" }, + { "key": "", "val": "😨" }, + { "key": "", "val": "😢" }, + { "key": "", "val": "😭" }, + { "key": "", "val": "😷" }, + { "key": "", "val": "✋" }, + { "key": "", "val": "✌️" }, + { "key": "", "val": "👊" }, + { "key": "", "val": "👋" }, + { "key": "", "val": "👏" }, + { "key": "", "val": "👍" }, + { "key": "", "val": "👎" }, + { "key": "", "val": "❤️" }, + { "key": "", "val": "🎉" }, + { "key": "", "val": "🚀" } + ] + }, + { + "name": "滑稽", + "type": "image", + "items": [ + { + "key": "原味稽", + "val": "https://gcore.jsdelivr.net/gh/qwqcode/huaji/%E5%8E%9F%E5%91%B3%E7%A8%BD.png" + }, + { + "key": "还是算了", + "val": "https://gcore.jsdelivr.net/gh/qwqcode/huaji/%E8%BF%98%E6%98%AF%E7%AE%97%E4%BA%86.png" + }, + { + "key": "蓝纹稽", + "val": "https://gcore.jsdelivr.net/gh/qwqcode/huaji/%E8%93%9D%E7%BA%B9%E7%A8%BD.jpg" + }, + { + "key": "随稽应变", + "val": "https://gcore.jsdelivr.net/gh/qwqcode/huaji/%E9%9A%8F%E7%A8%BD%E5%BA%94%E5%8F%98.jpg" + }, + { + "key": "蠕动", + "val": "https://gcore.jsdelivr.net/gh/qwqcode/huaji/%E8%A0%95%E5%8A%A8.gif" + }, + { + "key": "束手无稽", + "val": "https://gcore.jsdelivr.net/gh/qwqcode/huaji/%E6%9D%9F%E6%89%8B%E6%97%A0%E7%A8%BD.jpg" + }, + { + "key": "微笑默叹以为妙绝", + "val": "https://gcore.jsdelivr.net/gh/qwqcode/huaji/%E5%BE%AE%E7%AC%91%E9%BB%98%E5%8F%B9%E4%BB%A5%E4%B8%BA%E5%A6%99%E7%BB%9D.png" + }, + { + "key": "喝嘤料", + "val": "https://gcore.jsdelivr.net/gh/qwqcode/huaji/%E5%96%9D%E5%98%A4%E6%96%99.jpg" + }, + { + "key": "暗中观察", + "val": "https://gcore.jsdelivr.net/gh/qwqcode/huaji/%E6%9A%97%E4%B8%AD%E8%A7%82%E5%AF%9F.jpg" + }, + { + "key": "高兴", + "val": "https://gcore.jsdelivr.net/gh/qwqcode/huaji/%E9%AB%98%E5%85%B4.jpg" + }, + { + "key": "惊稽", + "val": "https://gcore.jsdelivr.net/gh/qwqcode/huaji/%E6%83%8A%E7%A8%BD.jpg" + }, + { + "key": "可这和我的帅有什么关系", + "val": "https://gcore.jsdelivr.net/gh/qwqcode/huaji/%E5%8F%AF%E8%BF%99%E5%92%8C%E6%88%91%E7%9A%84%E5%B8%85%E6%9C%89%E4%BB%80%E4%B9%88%E5%85%B3%E7%B3%BB.jpg" + }, + { + "key": "狱稽", + "val": "https://gcore.jsdelivr.net/gh/qwqcode/huaji/%E7%8B%B1%E7%A8%BD.jpg" + }, + { + "key": "梆", + "val": "https://gcore.jsdelivr.net/gh/qwqcode/huaji/%E6%A2%86.jpg" + }, + { + "key": "吃鱼摆摆", + "val": "https://gcore.jsdelivr.net/gh/qwqcode/huaji/%E5%90%83%E9%B1%BC%E6%91%86%E6%91%86.gif" + }, + { + "key": "跃跃欲试 3", + "val": "https://gcore.jsdelivr.net/gh/qwqcode/huaji/%E8%B7%83%E8%B7%83%E6%AC%B2%E8%AF%95_3.gif" + }, + { + "key": "突然滑稽", + "val": "https://gcore.jsdelivr.net/gh/qwqcode/huaji/%E7%AA%81%E7%84%B6%E6%BB%91%E7%A8%BD.jpg" + }, + { + "key": "扶墙怂", + "val": "https://gcore.jsdelivr.net/gh/qwqcode/huaji/%E6%89%B6%E5%A2%99%E6%80%82.jpg" + }, + { + "key": "阔以", + "val": "https://gcore.jsdelivr.net/gh/qwqcode/huaji/%E9%98%94%E4%BB%A5.jpg" + }, + { + "key": "不得行", + "val": "https://gcore.jsdelivr.net/gh/qwqcode/huaji/%E4%B8%8D%E5%BE%97%E8%A1%8C.jpg" + }, + { + "key": "少儿不宜", + "val": "https://gcore.jsdelivr.net/gh/qwqcode/huaji/%E5%B0%91%E5%84%BF%E4%B8%8D%E5%AE%9C.jpg" + }, + { + "key": "稽日可期", + "val": "https://gcore.jsdelivr.net/gh/qwqcode/huaji/%E7%A8%BD%E6%97%A5%E5%8F%AF%E6%9C%9F.jpg" + }, + { + "key": "哎", + "val": "https://gcore.jsdelivr.net/gh/qwqcode/huaji/%E5%93%8E.jpg" + }, + { + "key": "别看丢人", + "val": "https://gcore.jsdelivr.net/gh/qwqcode/huaji/%E5%88%AB%E7%9C%8B%E4%B8%A2%E4%BA%BA.jpg" + }, + { + "key": "地稽 2", + "val": "https://gcore.jsdelivr.net/gh/qwqcode/huaji/%E5%9C%B0%E7%A8%BD_2.jpg" + }, + { + "key": "地稽", + "val": "https://gcore.jsdelivr.net/gh/qwqcode/huaji/%E5%9C%B0%E7%A8%BD.jpg" + }, + { + "key": "老阔有点扣", + "val": "https://gcore.jsdelivr.net/gh/qwqcode/huaji/%E8%80%81%E9%98%94%E6%9C%89%E7%82%B9%E6%89%A3.gif" + }, + { + "key": "啊哈哈", + "val": "https://gcore.jsdelivr.net/gh/qwqcode/huaji/%E5%95%8A%E5%93%88%E5%93%88.jpg" + }, + { + "key": "无稽可奈", + "val": "https://gcore.jsdelivr.net/gh/qwqcode/huaji/%E6%97%A0%E7%A8%BD%E5%8F%AF%E5%A5%88.jpg" + }, + { + "key": "老实巴交", + "val": "https://gcore.jsdelivr.net/gh/qwqcode/huaji/%E8%80%81%E5%AE%9E%E5%B7%B4%E4%BA%A4.jpg" + }, + { + "key": "紧张", + "val": "https://gcore.jsdelivr.net/gh/qwqcode/huaji/%E7%B4%A7%E5%BC%A0.jpg" + }, + { + "key": "摇摆稽", + "val": "https://gcore.jsdelivr.net/gh/qwqcode/huaji/%E6%91%87%E6%91%86%E7%A8%BD.gif" + }, + { + "key": "又不是不能用", + "val": "https://gcore.jsdelivr.net/gh/qwqcode/huaji/%E5%8F%88%E4%B8%8D%E6%98%AF%E4%B8%8D%E8%83%BD%E7%94%A8.jpg" + }, + { + "key": "一时滑稽", + "val": "https://gcore.jsdelivr.net/gh/qwqcode/huaji/%E4%B8%80%E6%97%B6%E6%BB%91%E7%A8%BD.jpg" + }, + { + "key": "无法接受", + "val": "https://gcore.jsdelivr.net/gh/qwqcode/huaji/%E6%97%A0%E6%B3%95%E6%8E%A5%E5%8F%97.jpg" + }, + { + "key": "嘤雄豪稽", + "val": "https://gcore.jsdelivr.net/gh/qwqcode/huaji/%E5%98%A4%E9%9B%84%E8%B1%AA%E7%A8%BD.jpg" + }, + { + "key": "相视双稽", + "val": "https://gcore.jsdelivr.net/gh/qwqcode/huaji/%E7%9B%B8%E8%A7%86%E5%8F%8C%E7%A8%BD.jpg" + }, + { + "key": "稽皮发麻", + "val": "https://gcore.jsdelivr.net/gh/qwqcode/huaji/%E7%A8%BD%E7%9A%AE%E5%8F%91%E9%BA%BB.jpg" + }, + { + "key": "地稽 3", + "val": "https://gcore.jsdelivr.net/gh/qwqcode/huaji/%E5%9C%B0%E7%A8%BD_3.jpg" + }, + { + "key": "地稽委屈", + "val": "https://gcore.jsdelivr.net/gh/qwqcode/huaji/%E5%9C%B0%E7%A8%BD%E5%A7%94%E5%B1%88.jpg" + }, + { + "key": "地稽抚摸", + "val": "https://gcore.jsdelivr.net/gh/qwqcode/huaji/%E5%9C%B0%E7%A8%BD%E6%8A%9A%E6%91%B8.gif" + }, + { + "key": "绝望", + "val": "https://gcore.jsdelivr.net/gh/qwqcode/huaji/%E7%BB%9D%E6%9C%9B.jpg" + }, + { + "key": "气稽败坏", + "val": "https://gcore.jsdelivr.net/gh/qwqcode/huaji/%E6%B0%94%E7%A8%BD%E8%B4%A5%E5%9D%8F.jpg" + }, + { + "key": "当场去世", + "val": "https://gcore.jsdelivr.net/gh/qwqcode/huaji/%E5%BD%93%E5%9C%BA%E5%8E%BB%E4%B8%96.jpg" + }, + { + "key": "喝酒", + "val": "https://gcore.jsdelivr.net/gh/qwqcode/huaji/%E5%96%9D%E9%85%92.jpg" + }, + { + "key": "老衲摆摊算命", + "val": "https://gcore.jsdelivr.net/gh/qwqcode/huaji/%E8%80%81%E8%A1%B2%E6%91%86%E6%91%8A%E7%AE%97%E5%91%BD.gif" + }, + { + "key": "老哥,稳", + "val": "https://gcore.jsdelivr.net/gh/qwqcode/huaji/%E8%80%81%E5%93%A5%EF%BC%8C%E7%A8%B3.jpg" + }, + { + "key": "自闭稽", + "val": "https://gcore.jsdelivr.net/gh/qwqcode/huaji/%E8%87%AA%E9%97%AD%E7%A8%BD.jpg" + }, + { + "key": "无话可说", + "val": "https://gcore.jsdelivr.net/gh/qwqcode/huaji/%E6%97%A0%E8%AF%9D%E5%8F%AF%E8%AF%B4.jpg" + }, + { + "key": "跃跃欲试", + "val": "https://gcore.jsdelivr.net/gh/qwqcode/huaji/%E8%B7%83%E8%B7%83%E6%AC%B2%E8%AF%95.jpg" + }, + { + "key": "跃跃欲试 2", + "val": "https://gcore.jsdelivr.net/gh/qwqcode/huaji/%E8%B7%83%E8%B7%83%E6%AC%B2%E8%AF%95_2.jpg" + }, + { + "key": "满脑子骚操作", + "val": "https://gcore.jsdelivr.net/gh/qwqcode/huaji/%E6%BB%A1%E8%84%91%E5%AD%90%E9%AA%9A%E6%93%8D%E4%BD%9C.gif" + }, + { + "key": "稽之舞", + "val": "https://gcore.jsdelivr.net/gh/qwqcode/huaji/%E7%A8%BD%E4%B9%8B%E8%88%9E.gif" + }, + { + "key": "将稽就稽", + "val": "https://gcore.jsdelivr.net/gh/qwqcode/huaji/%E5%B0%86%E7%A8%BD%E5%B0%B1%E7%A8%BD.gif" + } + ] + } +] diff --git a/docs/docs/public/favicon.png b/docs/docs/public/favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..0e15f6d0ad9ed394b26a41afede74cc46765c793 GIT binary patch literal 1719 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 literal 0 HcmV?d00001 diff --git a/docs/package.json b/docs/package.json new file mode 100644 index 000000000..4e4566fc0 --- /dev/null +++ b/docs/package.json @@ -0,0 +1,21 @@ +{ + "name": "docs", + "version": "2.0.0", + "description": "Artalk documentation", + "repository": { + "type": "git", + "url": "https://github.com/ArtalkJS/Artalk", + "directory": "docs" + }, + "private": true, + "scripts": { + "docs:dev": "vitepress dev docs", + "docs:build": "vitepress build docs", + "docs:serve": "vitepress serve docs" + }, + "devDependencies": { + "markdown-it-for-inline": "^0.1.1", + "sass": "^1.52.3", + "vitepress": "1.0.0-alpha.1" + } +} \ No newline at end of file diff --git a/docs/pnpm-lock.yaml b/docs/pnpm-lock.yaml new file mode 100644 index 000000000..7262acd2a --- /dev/null +++ b/docs/pnpm-lock.yaml @@ -0,0 +1,837 @@ +lockfileVersion: 5.4 + +specifiers: + markdown-it-for-inline: ^0.1.1 + sass: ^1.52.3 + vitepress: 1.0.0-alpha.1 + +devDependencies: + markdown-it-for-inline: 0.1.1 + sass: 1.52.3 + vitepress: 1.0.0-alpha.1_sass@1.52.3 + +packages: + + /@algolia/autocomplete-core/1.6.3: + resolution: {integrity: sha512-dqQqRt01fX3YuVFrkceHsoCnzX0bLhrrg8itJI1NM68KjrPYQPYsE+kY8EZTCM4y8VDnhqJErR73xe/ZsV+qAA==} + dependencies: + '@algolia/autocomplete-shared': 1.6.3 + dev: true + + /@algolia/autocomplete-shared/1.6.3: + resolution: {integrity: sha512-UV46bnkTztyADFaETfzFC5ryIdGVb2zpAoYgu0tfcuYWjhg1KbLXveFffZIrGVoboqmAk1b+jMrl6iCja1i3lg==} + dev: true + + /@algolia/cache-browser-local-storage/4.13.1: + resolution: {integrity: sha512-UAUVG2PEfwd/FfudsZtYnidJ9eSCpS+LW9cQiesePQLz41NAcddKxBak6eP2GErqyFagSlnVXe/w2E9h2m2ttg==} + dependencies: + '@algolia/cache-common': 4.13.1 + dev: true + + /@algolia/cache-common/4.13.1: + resolution: {integrity: sha512-7Vaf6IM4L0Jkl3sYXbwK+2beQOgVJ0mKFbz/4qSxKd1iy2Sp77uTAazcX+Dlexekg1fqGUOSO7HS4Sx47ZJmjA==} + dev: true + + /@algolia/cache-in-memory/4.13.1: + resolution: {integrity: sha512-pZzybCDGApfA/nutsFK1P0Sbsq6fYJU3DwIvyKg4pURerlJM4qZbB9bfLRef0FkzfQu7W11E4cVLCIOWmyZeuQ==} + dependencies: + '@algolia/cache-common': 4.13.1 + dev: true + + /@algolia/client-account/4.13.1: + resolution: {integrity: sha512-TFLiZ1KqMiir3FNHU+h3b0MArmyaHG+eT8Iojio6TdpeFcAQ1Aiy+2gb3SZk3+pgRJa/BxGmDkRUwE5E/lv3QQ==} + dependencies: + '@algolia/client-common': 4.13.1 + '@algolia/client-search': 4.13.1 + '@algolia/transporter': 4.13.1 + dev: true + + /@algolia/client-analytics/4.13.1: + resolution: {integrity: sha512-iOS1JBqh7xaL5x00M5zyluZ9+9Uy9GqtYHv/2SMuzNW1qP7/0doz1lbcsP3S7KBbZANJTFHUOfuqyRLPk91iFA==} + dependencies: + '@algolia/client-common': 4.13.1 + '@algolia/client-search': 4.13.1 + '@algolia/requester-common': 4.13.1 + '@algolia/transporter': 4.13.1 + dev: true + + /@algolia/client-common/4.13.1: + resolution: {integrity: sha512-LcDoUE0Zz3YwfXJL6lJ2OMY2soClbjrrAKB6auYVMNJcoKZZ2cbhQoFR24AYoxnGUYBER/8B+9sTBj5bj/Gqbg==} + dependencies: + '@algolia/requester-common': 4.13.1 + '@algolia/transporter': 4.13.1 + dev: true + + /@algolia/client-personalization/4.13.1: + resolution: {integrity: sha512-1CqrOW1ypVrB4Lssh02hP//YxluoIYXAQCpg03L+/RiXJlCs+uIqlzC0ctpQPmxSlTK6h07kr50JQoYH/TIM9w==} + dependencies: + '@algolia/client-common': 4.13.1 + '@algolia/requester-common': 4.13.1 + '@algolia/transporter': 4.13.1 + dev: true + + /@algolia/client-search/4.13.1: + resolution: {integrity: sha512-YQKYA83MNRz3FgTNM+4eRYbSmHi0WWpo019s5SeYcL3HUan/i5R09VO9dk3evELDFJYciiydSjbsmhBzbpPP2A==} + dependencies: + '@algolia/client-common': 4.13.1 + '@algolia/requester-common': 4.13.1 + '@algolia/transporter': 4.13.1 + dev: true + + /@algolia/logger-common/4.13.1: + resolution: {integrity: sha512-L6slbL/OyZaAXNtS/1A8SAbOJeEXD5JcZeDCPYDqSTYScfHu+2ePRTDMgUTY4gQ7HsYZ39N1LujOd8WBTmM2Aw==} + dev: true + + /@algolia/logger-console/4.13.1: + resolution: {integrity: sha512-7jQOTftfeeLlnb3YqF8bNgA2GZht7rdKkJ31OCeSH2/61haO0tWPoNRjZq9XLlgMQZH276pPo0NdiArcYPHjCA==} + dependencies: + '@algolia/logger-common': 4.13.1 + dev: true + + /@algolia/requester-browser-xhr/4.13.1: + resolution: {integrity: sha512-oa0CKr1iH6Nc7CmU6RE7TnXMjHnlyp7S80pP/LvZVABeJHX3p/BcSCKovNYWWltgTxUg0U1o+2uuy8BpMKljwA==} + dependencies: + '@algolia/requester-common': 4.13.1 + dev: true + + /@algolia/requester-common/4.13.1: + resolution: {integrity: sha512-eGVf0ID84apfFEuXsaoSgIxbU3oFsIbz4XiotU3VS8qGCJAaLVUC5BUJEkiFENZIhon7hIB4d0RI13HY4RSA+w==} + dev: true + + /@algolia/requester-node-http/4.13.1: + resolution: {integrity: sha512-7C0skwtLdCz5heKTVe/vjvrqgL/eJxmiEjHqXdtypcE5GCQCYI15cb+wC4ytYioZDMiuDGeVYmCYImPoEgUGPw==} + dependencies: + '@algolia/requester-common': 4.13.1 + dev: true + + /@algolia/transporter/4.13.1: + resolution: {integrity: sha512-pICnNQN7TtrcYJqqPEXByV8rJ8ZRU2hCiIKLTLRyNpghtQG3VAFk6fVtdzlNfdUGZcehSKGarPIZEHlQXnKjgw==} + dependencies: + '@algolia/cache-common': 4.13.1 + '@algolia/logger-common': 4.13.1 + '@algolia/requester-common': 4.13.1 + dev: true + + /@babel/helper-validator-identifier/7.16.7: + resolution: {integrity: sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==} + engines: {node: '>=6.9.0'} + dev: true + + /@babel/parser/7.18.5: + resolution: {integrity: sha512-YZWVaglMiplo7v8f1oMQ5ZPQr0vn7HPeZXxXWsxXJRjGVrzUFn9OxFQl1sb5wzfootjA/yChhW84BV+383FSOw==} + engines: {node: '>=6.0.0'} + hasBin: true + dependencies: + '@babel/types': 7.18.4 + dev: true + + /@babel/types/7.18.4: + resolution: {integrity: sha512-ThN1mBcMq5pG/Vm2IcBmPPfyPXbd8S02rS+OBIDENdufvqC7Z/jHPCv9IcP01277aKtDI8g/2XysBN4hA8niiw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-validator-identifier': 7.16.7 + to-fast-properties: 2.0.0 + dev: true + + /@docsearch/css/3.1.0: + resolution: {integrity: sha512-bh5IskwkkodbvC0FzSg1AxMykfDl95hebEKwxNoq4e5QaGzOXSBgW8+jnMFZ7JU4sTBiB04vZWoUSzNrPboLZA==} + dev: true + + /@docsearch/js/3.1.0: + resolution: {integrity: sha512-5XSK+xbP0hcTIp54MECqxkWLs6kf7Ug4nWdxWNtx8cUpLiFNFnKXDxCb35wnyNpjukmrx7Q9DkO5tFFsmNVxng==} + dependencies: + '@docsearch/react': 3.1.0 + preact: 10.7.3 + transitivePeerDependencies: + - '@types/react' + - react + - react-dom + dev: true + + /@docsearch/react/3.1.0: + resolution: {integrity: sha512-bjB6ExnZzf++5B7Tfoi6UXgNwoUnNOfZ1NyvnvPhWgCMy5V/biAtLL4o7owmZSYdAKeFSvZ5Lxm0is4su/dBWg==} + peerDependencies: + '@types/react': '>= 16.8.0 < 19.0.0' + react: '>= 16.8.0 < 19.0.0' + react-dom: '>= 16.8.0 < 19.0.0' + dependencies: + '@algolia/autocomplete-core': 1.6.3 + '@docsearch/css': 3.1.0 + algoliasearch: 4.13.1 + dev: true + + /@vitejs/plugin-vue/2.3.3_vite@2.9.12+vue@3.2.37: + resolution: {integrity: sha512-SmQLDyhz+6lGJhPELsBdzXGc+AcaT8stgkbiTFGpXPe8Tl1tJaBw1A6pxDqDuRsVkD8uscrkx3hA7QDOoKYtyw==} + engines: {node: '>=12.0.0'} + peerDependencies: + vite: ^2.5.10 + vue: ^3.2.25 + dependencies: + vite: 2.9.12_sass@1.52.3 + vue: 3.2.37 + dev: true + + /@vue/compiler-core/3.2.37: + resolution: {integrity: sha512-81KhEjo7YAOh0vQJoSmAD68wLfYqJvoiD4ulyedzF+OEk/bk6/hx3fTNVfuzugIIaTrOx4PGx6pAiBRe5e9Zmg==} + dependencies: + '@babel/parser': 7.18.5 + '@vue/shared': 3.2.37 + estree-walker: 2.0.2 + source-map: 0.6.1 + dev: true + + /@vue/compiler-dom/3.2.37: + resolution: {integrity: sha512-yxJLH167fucHKxaqXpYk7x8z7mMEnXOw3G2q62FTkmsvNxu4FQSu5+3UMb+L7fjKa26DEzhrmCxAgFLLIzVfqQ==} + dependencies: + '@vue/compiler-core': 3.2.37 + '@vue/shared': 3.2.37 + dev: true + + /@vue/compiler-sfc/3.2.37: + resolution: {integrity: sha512-+7i/2+9LYlpqDv+KTtWhOZH+pa8/HnX/905MdVmAcI/mPQOBwkHHIzrsEsucyOIZQYMkXUiTkmZq5am/NyXKkg==} + dependencies: + '@babel/parser': 7.18.5 + '@vue/compiler-core': 3.2.37 + '@vue/compiler-dom': 3.2.37 + '@vue/compiler-ssr': 3.2.37 + '@vue/reactivity-transform': 3.2.37 + '@vue/shared': 3.2.37 + estree-walker: 2.0.2 + magic-string: 0.25.9 + postcss: 8.4.14 + source-map: 0.6.1 + dev: true + + /@vue/compiler-ssr/3.2.37: + resolution: {integrity: sha512-7mQJD7HdXxQjktmsWp/J67lThEIcxLemz1Vb5I6rYJHR5vI+lON3nPGOH3ubmbvYGt8xEUaAr1j7/tIFWiEOqw==} + dependencies: + '@vue/compiler-dom': 3.2.37 + '@vue/shared': 3.2.37 + dev: true + + /@vue/reactivity-transform/3.2.37: + resolution: {integrity: sha512-IWopkKEb+8qpu/1eMKVeXrK0NLw9HicGviJzhJDEyfxTR9e1WtpnnbYkJWurX6WwoFP0sz10xQg8yL8lgskAZg==} + dependencies: + '@babel/parser': 7.18.5 + '@vue/compiler-core': 3.2.37 + '@vue/shared': 3.2.37 + estree-walker: 2.0.2 + magic-string: 0.25.9 + dev: true + + /@vue/reactivity/3.2.37: + resolution: {integrity: sha512-/7WRafBOshOc6m3F7plwzPeCu/RCVv9uMpOwa/5PiY1Zz+WLVRWiy0MYKwmg19KBdGtFWsmZ4cD+LOdVPcs52A==} + dependencies: + '@vue/shared': 3.2.37 + dev: true + + /@vue/runtime-core/3.2.37: + resolution: {integrity: sha512-JPcd9kFyEdXLl/i0ClS7lwgcs0QpUAWj+SKX2ZC3ANKi1U4DOtiEr6cRqFXsPwY5u1L9fAjkinIdB8Rz3FoYNQ==} + dependencies: + '@vue/reactivity': 3.2.37 + '@vue/shared': 3.2.37 + dev: true + + /@vue/runtime-dom/3.2.37: + resolution: {integrity: sha512-HimKdh9BepShW6YozwRKAYjYQWg9mQn63RGEiSswMbW+ssIht1MILYlVGkAGGQbkhSh31PCdoUcfiu4apXJoPw==} + dependencies: + '@vue/runtime-core': 3.2.37 + '@vue/shared': 3.2.37 + csstype: 2.6.20 + dev: true + + /@vue/server-renderer/3.2.37_vue@3.2.37: + resolution: {integrity: sha512-kLITEJvaYgZQ2h47hIzPh2K3jG8c1zCVbp/o/bzQOyvzaKiCquKS7AaioPI28GNxIsE/zSx+EwWYsNxDCX95MA==} + peerDependencies: + vue: 3.2.37 + dependencies: + '@vue/compiler-ssr': 3.2.37 + '@vue/shared': 3.2.37 + vue: 3.2.37 + dev: true + + /@vue/shared/3.2.37: + resolution: {integrity: sha512-4rSJemR2NQIo9Klm1vabqWjD8rs/ZaJSzMxkMNeJS6lHiUjjUeYFbooN19NgFjztubEKh3WlZUeOLVdbbUWHsw==} + dev: true + + /@vueuse/core/8.6.0_vue@3.2.37: + resolution: {integrity: sha512-VirzExCm/N+QdrEWT7J4uSrvJ5hquKIAU9alQ37kUvIJk9XxCLxmfRnmekYc1kz2+6BnoyuKYXVmrMV351CB4w==} + peerDependencies: + '@vue/composition-api': ^1.1.0 + vue: ^2.6.0 || ^3.2.0 + peerDependenciesMeta: + '@vue/composition-api': + optional: true + vue: + optional: true + dependencies: + '@vueuse/metadata': 8.6.0 + '@vueuse/shared': 8.6.0_vue@3.2.37 + vue: 3.2.37 + vue-demi: 0.13.1_vue@3.2.37 + dev: true + + /@vueuse/metadata/8.6.0: + resolution: {integrity: sha512-F+CKPvaExsm7QgRr8y+ZNJFwXasn89rs5wth/HeX9lJ1q8XEt+HJ16Q5Sxh4rfG5YSKXrStveVge8TKvPjMjFA==} + dev: true + + /@vueuse/shared/8.6.0_vue@3.2.37: + resolution: {integrity: sha512-Y/IVywZo7IfEoSSEtCYpkVEmPV7pU35mEIxV7PbD/D3ly18B3mEsBaPbtDkNM/QP3zAZ5mn4nEkOfddX4uwuIA==} + peerDependencies: + '@vue/composition-api': ^1.1.0 + vue: ^2.6.0 || ^3.2.0 + peerDependenciesMeta: + '@vue/composition-api': + optional: true + vue: + optional: true + dependencies: + vue: 3.2.37 + vue-demi: 0.13.1_vue@3.2.37 + dev: true + + /algoliasearch/4.13.1: + resolution: {integrity: sha512-dtHUSE0caWTCE7liE1xaL+19AFf6kWEcyn76uhcitWpntqvicFHXKFoZe5JJcv9whQOTRM6+B8qJz6sFj+rDJA==} + dependencies: + '@algolia/cache-browser-local-storage': 4.13.1 + '@algolia/cache-common': 4.13.1 + '@algolia/cache-in-memory': 4.13.1 + '@algolia/client-account': 4.13.1 + '@algolia/client-analytics': 4.13.1 + '@algolia/client-common': 4.13.1 + '@algolia/client-personalization': 4.13.1 + '@algolia/client-search': 4.13.1 + '@algolia/logger-common': 4.13.1 + '@algolia/logger-console': 4.13.1 + '@algolia/requester-browser-xhr': 4.13.1 + '@algolia/requester-common': 4.13.1 + '@algolia/requester-node-http': 4.13.1 + '@algolia/transporter': 4.13.1 + dev: true + + /anymatch/3.1.2: + resolution: {integrity: sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==} + engines: {node: '>= 8'} + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.1 + dev: true + + /binary-extensions/2.2.0: + resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==} + engines: {node: '>=8'} + dev: true + + /body-scroll-lock/4.0.0-beta.0: + resolution: {integrity: sha512-a7tP5+0Mw3YlUJcGAKUqIBkYYGlYxk2fnCasq/FUph1hadxlTRjF+gAcZksxANnaMnALjxEddmSi/H3OR8ugcQ==} + dev: true + + /braces/3.0.2: + resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} + engines: {node: '>=8'} + dependencies: + fill-range: 7.0.1 + dev: true + + /chokidar/3.5.3: + resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==} + engines: {node: '>= 8.10.0'} + dependencies: + anymatch: 3.1.2 + braces: 3.0.2 + glob-parent: 5.1.2 + is-binary-path: 2.1.0 + is-glob: 4.0.3 + normalize-path: 3.0.0 + readdirp: 3.6.0 + optionalDependencies: + fsevents: 2.3.2 + dev: true + + /csstype/2.6.20: + resolution: {integrity: sha512-/WwNkdXfckNgw6S5R125rrW8ez139lBHWouiBvX8dfMFtcn6V81REDqnH7+CRpRipfYlyU1CmOnOxrmGcFOjeA==} + dev: true + + /esbuild-android-64/0.14.43: + resolution: {integrity: sha512-kqFXAS72K6cNrB6RiM7YJ5lNvmWRDSlpi7ZuRZ1hu1S3w0zlwcoCxWAyM23LQUyZSs1PbjHgdbbfYAN8IGh6xg==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + requiresBuild: true + dev: true + optional: true + + /esbuild-android-arm64/0.14.43: + resolution: {integrity: sha512-bKS2BBFh+7XZY9rpjiHGRNA7LvWYbZWP87pLehggTG7tTaCDvj8qQGOU/OZSjCSKDYbgY7Q+oDw8RlYQ2Jt2BA==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + requiresBuild: true + dev: true + optional: true + + /esbuild-darwin-64/0.14.43: + resolution: {integrity: sha512-/3PSilx011ttoieRGkSZ0XV8zjBf2C9enV4ScMMbCT4dpx0mFhMOpFnCHkOK0pWGB8LklykFyHrWk2z6DENVUg==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /esbuild-darwin-arm64/0.14.43: + resolution: {integrity: sha512-1HyFUKs8DMCBOvw1Qxpr5Vv/ThNcVIFb5xgXWK3pyT40WPvgYIiRTwJCvNs4l8i5qWF8/CK5bQxJVDjQvtv0Yw==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /esbuild-freebsd-64/0.14.43: + resolution: {integrity: sha512-FNWc05TPHYgaXjbPZO5/rJKSBslfG6BeMSs8GhwnqAKP56eEhvmzwnIz1QcC9cRVyO+IKqWNfmHFkCa1WJTULA==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + + /esbuild-freebsd-arm64/0.14.43: + resolution: {integrity: sha512-amrYopclz3VohqisOPR6hA3GOWA3LZC1WDLnp21RhNmoERmJ/vLnOpnrG2P/Zao+/erKTCUqmrCIPVtj58DRoA==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + + /esbuild-linux-32/0.14.43: + resolution: {integrity: sha512-KoxoEra+9O3AKVvgDFvDkiuddCds6q71owSQEYwjtqRV7RwbPzKxJa6+uyzUulHcyGVq0g15K0oKG5CFBcvYDw==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /esbuild-linux-64/0.14.43: + resolution: {integrity: sha512-EwINwGMyiJMgBby5/SbMqKcUhS5AYAZ2CpEBzSowsJPNBJEdhkCTtEjk757TN/wxgbu3QklqDM6KghY660QCUw==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /esbuild-linux-arm/0.14.43: + resolution: {integrity: sha512-e6YzQUoDxxtyamuF12eVzzRC7bbEFSZohJ6igQB9tBqnNmIQY3fI6Cns3z2wxtbZ3f2o6idkD2fQnlvs2902Dg==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /esbuild-linux-arm64/0.14.43: + resolution: {integrity: sha512-UlSpjMWllAc70zYbHxWuDS3FJytyuR/gHJYBr8BICcTNb/TSOYVBg6U7b3jZ3mILTrgzwJUHwhEwK18FZDouUQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /esbuild-linux-mips64le/0.14.43: + resolution: {integrity: sha512-f+v8cInPEL1/SDP//CfSYzcDNgE4CY3xgDV81DWm3KAPWzhvxARrKxB1Pstf5mB56yAslJDxu7ryBUPX207EZA==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /esbuild-linux-ppc64le/0.14.43: + resolution: {integrity: sha512-5wZYMDGAL/K2pqkdIsW+I4IR41kyfHr/QshJcNpUfK3RjB3VQcPWOaZmc+74rm4ZjVirYrtz+jWw0SgxtxRanA==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /esbuild-linux-riscv64/0.14.43: + resolution: {integrity: sha512-lYcAOUxp85hC7lSjycJUVSmj4/9oEfSyXjb/ua9bNl8afonaduuqtw7hvKMoKuYnVwOCDw4RSfKpcnIRDWq+Bw==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /esbuild-linux-s390x/0.14.43: + resolution: {integrity: sha512-27e43ZhHvhFE4nM7HqtUbMRu37I/4eNSUbb8FGZWszV+uLzMIsHDwLoBiJmw7G9N+hrehNPeQ4F5Ujad0DrUKQ==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /esbuild-netbsd-64/0.14.43: + resolution: {integrity: sha512-2mH4QF6hHBn5zzAfxEI/2eBC0mspVsZ6UVo821LpAJKMvLJPBk3XJO5xwg7paDqSqpl7p6IRrAenW999AEfJhQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + requiresBuild: true + dev: true + optional: true + + /esbuild-openbsd-64/0.14.43: + resolution: {integrity: sha512-ZhQpiZjvqCqO8jKdGp9+8k9E/EHSA+zIWOg+grwZasI9RoblqJ1QiZqqi7jfd6ZrrG1UFBNGe4m0NFxCFbMVbg==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + requiresBuild: true + dev: true + optional: true + + /esbuild-sunos-64/0.14.43: + resolution: {integrity: sha512-DgxSi9DaHReL9gYuul2rrQCAapgnCJkh3LSHPKsY26zytYppG0HgkgVF80zjIlvEsUbGBP/GHQzBtrezj/Zq1Q==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + requiresBuild: true + dev: true + optional: true + + /esbuild-windows-32/0.14.43: + resolution: {integrity: sha512-Ih3+2O5oExiqm0mY6YYE5dR0o8+AspccQ3vIAtRodwFvhuyGLjb0Hbmzun/F3Lw19nuhPMu3sW2fqIJ5xBxByw==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /esbuild-windows-64/0.14.43: + resolution: {integrity: sha512-8NsuNfI8xwFuJbrCuI+aBqNTYkrWErejFO5aYM+yHqyHuL8mmepLS9EPzAzk8rvfaJrhN0+RvKWAcymViHOKEw==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /esbuild-windows-arm64/0.14.43: + resolution: {integrity: sha512-7ZlD7bo++kVRblJEoG+cepljkfP8bfuTPz5fIXzptwnPaFwGS6ahvfoYzY7WCf5v/1nX2X02HDraVItTgbHnKw==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /esbuild/0.14.43: + resolution: {integrity: sha512-Uf94+kQmy/5jsFwKWiQB4hfo/RkM9Dh7b79p8yqd1tshULdr25G2szLz631NoH3s2ujnKEKVD16RmOxvCNKRFA==} + engines: {node: '>=12'} + hasBin: true + requiresBuild: true + optionalDependencies: + esbuild-android-64: 0.14.43 + esbuild-android-arm64: 0.14.43 + esbuild-darwin-64: 0.14.43 + esbuild-darwin-arm64: 0.14.43 + esbuild-freebsd-64: 0.14.43 + esbuild-freebsd-arm64: 0.14.43 + esbuild-linux-32: 0.14.43 + esbuild-linux-64: 0.14.43 + esbuild-linux-arm: 0.14.43 + esbuild-linux-arm64: 0.14.43 + esbuild-linux-mips64le: 0.14.43 + esbuild-linux-ppc64le: 0.14.43 + esbuild-linux-riscv64: 0.14.43 + esbuild-linux-s390x: 0.14.43 + esbuild-netbsd-64: 0.14.43 + esbuild-openbsd-64: 0.14.43 + esbuild-sunos-64: 0.14.43 + esbuild-windows-32: 0.14.43 + esbuild-windows-64: 0.14.43 + esbuild-windows-arm64: 0.14.43 + dev: true + + /estree-walker/2.0.2: + resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} + dev: true + + /fill-range/7.0.1: + resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} + engines: {node: '>=8'} + dependencies: + to-regex-range: 5.0.1 + dev: true + + /fsevents/2.3.2: + resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /function-bind/1.1.1: + resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==} + dev: true + + /glob-parent/5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + dependencies: + is-glob: 4.0.3 + dev: true + + /has/1.0.3: + resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==} + engines: {node: '>= 0.4.0'} + dependencies: + function-bind: 1.1.1 + dev: true + + /immutable/4.1.0: + resolution: {integrity: sha512-oNkuqVTA8jqG1Q6c+UglTOD1xhC1BtjKI7XkCXRkZHrN5m18/XsnUp8Q89GkQO/z+0WjonSvl0FLhDYftp46nQ==} + dev: true + + /is-binary-path/2.1.0: + resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} + engines: {node: '>=8'} + dependencies: + binary-extensions: 2.2.0 + dev: true + + /is-core-module/2.9.0: + resolution: {integrity: sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A==} + dependencies: + has: 1.0.3 + dev: true + + /is-extglob/2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + dev: true + + /is-glob/4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + dependencies: + is-extglob: 2.1.1 + dev: true + + /is-number/7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + dev: true + + /jsonc-parser/3.0.0: + resolution: {integrity: sha512-fQzRfAbIBnR0IQvftw9FJveWiHp72Fg20giDrHz6TdfB12UH/uue0D3hm57UB5KgAVuniLMCaS8P1IMj9NR7cA==} + dev: true + + /magic-string/0.25.9: + resolution: {integrity: sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==} + dependencies: + sourcemap-codec: 1.4.8 + dev: true + + /markdown-it-for-inline/0.1.1: + resolution: {integrity: sha512-lLQuczOg90a9q9anIUbmq+M+FFrIYNN5TfpccLDRchQic8nj/uTqaJKoYr73FF2tR4O8mFfh2ZzCDAAB2MZJgA==} + dev: true + + /nanoid/3.3.4: + resolution: {integrity: sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + dev: true + + /normalize-path/3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + dev: true + + /path-parse/1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + dev: true + + /picocolors/1.0.0: + resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} + dev: true + + /picomatch/2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + dev: true + + /postcss/8.4.14: + resolution: {integrity: sha512-E398TUmfAYFPBSdzgeieK2Y1+1cpdxJx8yXbK/m57nRhKSmk1GB2tO4lbLBtlkfPQTDKfe4Xqv1ASWPpayPEig==} + engines: {node: ^10 || ^12 || >=14} + dependencies: + nanoid: 3.3.4 + picocolors: 1.0.0 + source-map-js: 1.0.2 + dev: true + + /preact/10.7.3: + resolution: {integrity: sha512-giqJXP8VbtA1tyGa3f1n9wiN7PrHtONrDyE3T+ifjr/tTkg+2N4d/6sjC9WyJKv8wM7rOYDveqy5ZoFmYlwo4w==} + dev: true + + /readdirp/3.6.0: + resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} + engines: {node: '>=8.10.0'} + dependencies: + picomatch: 2.3.1 + dev: true + + /resolve/1.22.0: + resolution: {integrity: sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==} + hasBin: true + dependencies: + is-core-module: 2.9.0 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + dev: true + + /rollup/2.75.6: + resolution: {integrity: sha512-OEf0TgpC9vU6WGROJIk1JA3LR5vk/yvqlzxqdrE2CzzXnqKXNzbAwlWUXis8RS3ZPe7LAq+YUxsRa0l3r27MLA==} + engines: {node: '>=10.0.0'} + hasBin: true + optionalDependencies: + fsevents: 2.3.2 + dev: true + + /sass/1.52.3: + resolution: {integrity: sha512-LNNPJ9lafx+j1ArtA7GyEJm9eawXN8KlA1+5dF6IZyoONg1Tyo/g+muOsENWJH/2Q1FHbbV4UwliU0cXMa/VIA==} + engines: {node: '>=12.0.0'} + hasBin: true + dependencies: + chokidar: 3.5.3 + immutable: 4.1.0 + source-map-js: 1.0.2 + dev: true + + /shiki/0.10.1: + resolution: {integrity: sha512-VsY7QJVzU51j5o1+DguUd+6vmCmZ5v/6gYu4vyYAhzjuNQU6P/vmSy4uQaOhvje031qQMiW0d2BwgMH52vqMng==} + dependencies: + jsonc-parser: 3.0.0 + vscode-oniguruma: 1.6.2 + vscode-textmate: 5.2.0 + dev: true + + /source-map-js/1.0.2: + resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==} + engines: {node: '>=0.10.0'} + dev: true + + /source-map/0.6.1: + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} + engines: {node: '>=0.10.0'} + dev: true + + /sourcemap-codec/1.4.8: + resolution: {integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==} + dev: true + + /supports-preserve-symlinks-flag/1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + dev: true + + /to-fast-properties/2.0.0: + resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} + engines: {node: '>=4'} + dev: true + + /to-regex-range/5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + dependencies: + is-number: 7.0.0 + dev: true + + /vite/2.9.12_sass@1.52.3: + resolution: {integrity: sha512-suxC36dQo9Rq1qMB2qiRorNJtJAdxguu5TMvBHOc/F370KvqAe9t48vYp+/TbPKRNrMh/J55tOUmkuIqstZaew==} + engines: {node: '>=12.2.0'} + hasBin: true + peerDependencies: + less: '*' + sass: '*' + stylus: '*' + peerDependenciesMeta: + less: + optional: true + sass: + optional: true + stylus: + optional: true + dependencies: + esbuild: 0.14.43 + postcss: 8.4.14 + resolve: 1.22.0 + rollup: 2.75.6 + sass: 1.52.3 + optionalDependencies: + fsevents: 2.3.2 + dev: true + + /vitepress/1.0.0-alpha.1_sass@1.52.3: + resolution: {integrity: sha512-yA0QIl+mB3fQ2j+keQVa0DTT0waP2AeWM/p9VYfUAT9vOkQEGass4/oYmMGPCQrBwCaO3cpOxJL3ZFVooyvybQ==} + engines: {node: '>=14.6.0'} + hasBin: true + dependencies: + '@docsearch/css': 3.1.0 + '@docsearch/js': 3.1.0 + '@vitejs/plugin-vue': 2.3.3_vite@2.9.12+vue@3.2.37 + '@vueuse/core': 8.6.0_vue@3.2.37 + body-scroll-lock: 4.0.0-beta.0 + shiki: 0.10.1 + vite: 2.9.12_sass@1.52.3 + vue: 3.2.37 + transitivePeerDependencies: + - '@types/react' + - '@vue/composition-api' + - less + - react + - react-dom + - sass + - stylus + dev: true + + /vscode-oniguruma/1.6.2: + resolution: {integrity: sha512-KH8+KKov5eS/9WhofZR8M8dMHWN2gTxjMsG4jd04YhpbPR91fUj7rYQ2/XjeHCJWbg7X++ApRIU9NUwM2vTvLA==} + dev: true + + /vscode-textmate/5.2.0: + resolution: {integrity: sha512-Uw5ooOQxRASHgu6C7GVvUxisKXfSgW4oFlO+aa+PAkgmH89O3CXxEEzNRNtHSqtXFTl0nAC1uYj0GMSH27uwtQ==} + dev: true + + /vue-demi/0.13.1_vue@3.2.37: + resolution: {integrity: sha512-xmkJ56koG3ptpLnpgmIzk9/4nFf4CqduSJbUM0OdPoU87NwRuZ6x49OLhjSa/fC15fV+5CbEnrxU4oyE022svg==} + engines: {node: '>=12'} + hasBin: true + requiresBuild: true + peerDependencies: + '@vue/composition-api': ^1.0.0-rc.1 + vue: ^3.0.0-0 || ^2.6.0 + peerDependenciesMeta: + '@vue/composition-api': + optional: true + dependencies: + vue: 3.2.37 + dev: true + + /vue/3.2.37: + resolution: {integrity: sha512-bOKEZxrm8Eh+fveCqS1/NkG/n6aMidsI6hahas7pa0w/l7jkbssJVsRhVDs07IdDq7h9KHswZOgItnwJAgtVtQ==} + dependencies: + '@vue/compiler-dom': 3.2.37 + '@vue/compiler-sfc': 3.2.37 + '@vue/runtime-dom': 3.2.37 + '@vue/server-renderer': 3.2.37_vue@3.2.37 + '@vue/shared': 3.2.37 + dev: true diff --git a/docs/tsconfig.json b/docs/tsconfig.json new file mode 100644 index 000000000..415cf7dbf --- /dev/null +++ b/docs/tsconfig.json @@ -0,0 +1,8 @@ +{ + "compilerOptions": { + "baseUrl": ".", + "types": ["vite/client"], + "resolveJsonModule": true + }, + "include": ["**/.vitepress/**/*"], +} From ac26e674364735299a5f83c922c302e97b2973c6 Mon Sep 17 00:00:00 2001 From: pluveto <i@pluvet.com> Date: Tue, 17 Jan 2023 05:34:16 +0000 Subject: [PATCH 327/349] fix: frontend repository directory issue --- ui/packages/artalk/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/packages/artalk/package.json b/ui/packages/artalk/package.json index 6b4f7f696..b8f1670ad 100644 --- a/ui/packages/artalk/package.json +++ b/ui/packages/artalk/package.json @@ -14,7 +14,7 @@ "repository": { "type": "git", "url": "https://github.com/ArtalkJS/Artalk.git", - "directory": "packages/artalk" + "directory": "ui/packages/artalk" }, "homepage": "https://artalk.js.org", "bugs": "https://github.com/ArtalkJS/Artalk/issue", From 697ed7282ab05d8bf3fd84afb2f6eaaeb2093318 Mon Sep 17 00:00:00 2001 From: pluveto <i@pluvet.com> Date: Tue, 17 Jan 2023 05:37:45 +0000 Subject: [PATCH 328/349] refactor: batch removing artalk `-go` postfix --- .circleci/conditional_config.yml | 2 +- .goreleaser.yml | 6 +- BACKEND.md | 18 +++--- Dockerfile | 10 +-- README.en.md | 4 +- README.md | 4 +- cmd/admin.go | 8 +-- cmd/export.go | 10 +-- cmd/gen.go | 2 +- cmd/import.go | 4 +- cmd/root.go | 8 +-- cmd/server.go | 6 +- cmd/upgrade.go | 8 +-- docker-entrypoint.sh | 4 +- docs/docs/.vitepress/config.ts | 2 +- docs/docs/code/quick-start/normal-install.sh | 8 +-- docs/docs/develop/api.md | 2 +- docs/docs/develop/index.md | 4 +- docs/docs/guide/backend/admin_notify.md | 18 +++--- docs/docs/guide/backend/build.md | 26 ++++---- docs/docs/guide/backend/captcha.md | 4 +- docs/docs/guide/backend/config.md | 62 +++++++++---------- docs/docs/guide/backend/daemon.md | 24 +++---- docs/docs/guide/backend/docker.md | 34 +++++----- docs/docs/guide/backend/email.md | 8 +-- docs/docs/guide/backend/fe-control.md | 10 +-- docs/docs/guide/backend/img-upload.md | 4 +- docs/docs/guide/backend/index.md | 4 +- docs/docs/guide/backend/moderator.md | 6 +- docs/docs/guide/backend/multi-site.md | 6 +- docs/docs/guide/backend/notify.md | 2 +- docs/docs/guide/backend/relative-path.md | 2 +- docs/docs/guide/backend/reverse-proxy.md | 6 +- docs/docs/guide/backend/update.md | 10 +-- docs/docs/guide/deploy.md | 28 ++++----- docs/docs/guide/intro.md | 2 +- docs/docs/guide/transfer.md | 20 +++--- go.mod | 2 +- internal/anti_spam/anti_spam.go | 8 +-- internal/anti_spam/anti_spam_akismet.go | 2 +- internal/anti_spam/anti_spam_aliyun.go | 2 +- internal/anti_spam/anti_spam_tencent.go | 2 +- internal/artransfer/artrans.go | 8 +-- internal/artransfer/exporter.go | 6 +- internal/artransfer/importer.go | 8 +-- internal/cache/actions.go | 4 +- internal/cache/cache.go | 2 +- internal/cache/db.go | 2 +- internal/cache/operate.go | 2 +- internal/captcha/geetest.go | 2 +- internal/core/core.go | 8 +-- internal/core/gen.go | 2 +- internal/core/sync.go | 6 +- internal/db/db.go | 4 +- internal/db/migrate.go | 2 +- internal/email/email.go | 6 +- internal/email/queue.go | 4 +- internal/email/render.go | 8 +-- internal/email/sender.go | 4 +- internal/email/sender_alidm.go | 2 +- internal/email/sender_cmd.go | 2 +- internal/email/sender_smtp.go | 2 +- internal/entity/notify.go | 2 +- internal/notify_launcher/init.go | 4 +- internal/notify_launcher/notify_launcher.go | 12 ++-- internal/query/association.go | 2 +- internal/query/cook.go | 4 +- internal/query/db.go | 2 +- internal/query/db_test.go | 6 +- internal/query/query.go | 2 +- internal/query/query_del.go | 4 +- internal/query/query_find.go | 4 +- internal/query/query_find_create.go | 2 +- internal/query/query_new.go | 4 +- internal/query/query_update.go | 4 +- internal/query/service.go | 4 +- internal/query/service_test.go | 2 +- main.go | 4 +- public/index.html | 4 +- server/common/auth.go | 6 +- server/common/captcha.go | 4 +- server/common/check.go | 6 +- server/common/conf.go | 4 +- server/common/cors.go | 8 +-- server/common/site.go | 2 +- server/handler/admin_cache.go | 4 +- server/handler/admin_comment_del.go | 4 +- server/handler/admin_comment_edit.go | 10 +-- server/handler/admin_page_del.go | 4 +- server/handler/admin_page_edit.go | 10 +-- server/handler/admin_page_fetch.go | 10 +-- server/handler/admin_page_get.go | 8 +-- server/handler/admin_send_mail.go | 4 +- server/handler/admin_setting.go | 6 +- server/handler/admin_site_add.go | 10 +-- server/handler/admin_site_del.go | 4 +- server/handler/admin_site_edit.go | 12 ++-- server/handler/admin_site_get.go | 8 +-- server/handler/admin_transfer.go | 8 +-- server/handler/admin_user_add.go | 8 +-- server/handler/admin_user_del.go | 4 +- server/handler/admin_user_edit.go | 8 +-- server/handler/admin_user_get.go | 8 +-- server/handler/admin_vote_sync.go | 4 +- server/handler/captcha.go | 6 +- server/handler/comment_add.go | 14 ++--- server/handler/comment_get.go | 6 +- server/handler/comment_get_query.go | 10 +-- server/handler/conf.go | 2 +- server/handler/img_upload.go | 6 +- server/handler/mark_read.go | 4 +- server/handler/pv.go | 4 +- server/handler/stat.go | 12 ++-- server/handler/user_get.go | 4 +- server/handler/user_login.go | 10 +-- server/handler/user_logout.go | 4 +- server/handler/version.go | 2 +- server/handler/vote.go | 8 +-- server/middleware/admin.go | 2 +- server/middleware/cors.go | 4 +- server/middleware/limit.go | 4 +- server/middleware/site_origin.go | 10 +-- server/server.go | 10 +-- .../artalk-sidebar/scripts/fetch-conf-tpl.js | 6 +- .../artalk-sidebar/src/pages/login.vue | 2 +- .../artalk/src/editor/plugs/upload-plug.ts | 2 +- 126 files changed, 424 insertions(+), 424 deletions(-) diff --git a/.circleci/conditional_config.yml b/.circleci/conditional_config.yml index 79b4e49c4..bc8d35eee 100644 --- a/.circleci/conditional_config.yml +++ b/.circleci/conditional_config.yml @@ -29,7 +29,7 @@ jobs: ## Backend test_app: executor: go - working_directory: ~/go/src/github.com/ArtalkJS/ArtalkGo + working_directory: ~/go/src/github.com/ArtalkJS/Artalk environment: GO111MODULE: "on" steps: diff --git a/.goreleaser.yml b/.goreleaser.yml index 5074ae6f6..32b0eaf3b 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -35,8 +35,8 @@ builds: binary: "{{.ProjectName}}" main: ./main.go ldflags: &common_ldflags | - -X github.com/ArtalkJS/ArtalkGo/internal/config.Version={{.Version}} - -X github.com/ArtalkJS/ArtalkGo/internal/config.CommitHash={{ .ShortCommit }} + -X github.com/ArtalkJS/Artalk/internal/config.Version={{.Version}} + -X github.com/ArtalkJS/Artalk/internal/config.CommitHash={{ .ShortCommit }} -s -w # Windows (amd_64) @@ -53,7 +53,7 @@ builds: ldflags: *common_ldflags flags: # https://go-review.googlesource.com/c/go/+/224588/ - # https://github.com/ArtalkJS/ArtalkGo/issues/35 + # https://github.com/ArtalkJS/Artalk/issues/35 - -tags=timetzdata # Darwin (amd_64) diff --git a/BACKEND.md b/BACKEND.md index 827de16e1..3a8628937 100644 --- a/BACKEND.md +++ b/BACKEND.md @@ -2,13 +2,13 @@ <img src="./docs/artalk.png" alt="Artalk" width="100%"> </p> -# ArtalkGo +# Artalk -[![CircleCI](https://circleci.com/gh/ArtalkJS/ArtalkGo/tree/master.svg?style=svg)](https://circleci.com/gh/ArtalkJS/ArtalkGo/tree/master) -[![CI to Docker Hub](https://github.com/ArtalkJS/ArtalkGo/actions/workflows/dockerhub.yml/badge.svg)](https://github.com/ArtalkJS/ArtalkGo/actions/workflows/dockerhub.yml) [![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2FArtalkJS%2FArtalkGo.svg?type=shield)](https://app.fossa.com/projects/git%2Bgithub.com%2FArtalkJS%2FArtalkGo?ref=badge_shield) +[![CircleCI](https://circleci.com/gh/ArtalkJS/Artalk/tree/master.svg?style=svg)](https://circleci.com/gh/ArtalkJS/Artalk/tree/master) +[![CI to Docker Hub](https://github.com/ArtalkJS/Artalk/actions/workflows/dockerhub.yml/badge.svg)](https://github.com/ArtalkJS/Artalk/actions/workflows/dockerhub.yml) [![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2FArtalkJS%2FArtalk.svg?type=shield)](https://app.fossa.com/projects/git%2Bgithub.com%2FArtalkJS%2FArtalk?ref=badge_shield) [![Docker Pulls](https://img.shields.io/docker/pulls/artalk/artalk?style=flat-square)](https://hub.docker.com/r/artalk/artalk) -> ArtalkGo: Golang backend of Artalk. +> Artalk: Golang backend of Artalk. 前往:[“**官方文档 · 后端部分**”](https://artalk.js.org/guide/backend/config.html) @@ -42,8 +42,8 @@ $ make all ```sh # 克隆项目 -$ git clone https://github.com/ArtalkJS/ArtalkGo -$ cd ArtalkGo +$ git clone https://github.com/ArtalkJS/Artalk +$ cd Artalk # 构建镜像 $ docker compose build @@ -56,8 +56,8 @@ $ docker compose up -d ```sh # 克隆项目 -$ git clone https://github.com/ArtalkJS/ArtalkGo -$ cd ArtalkGo +$ git clone https://github.com/ArtalkJS/Artalk +$ cd Artalk # 构建镜像 $ make docker-docker @@ -72,4 +72,4 @@ Reference to https://github.com/ArtalkJS/Artalk#todos ## License -[![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2FArtalkJS%2FArtalkGo.svg?type=large)](https://app.fossa.com/projects/git%2Bgithub.com%2FArtalkJS%2FArtalkGo?ref=badge_large) +[![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2FArtalkJS%2FArtalk.svg?type=large)](https://app.fossa.com/projects/git%2Bgithub.com%2FArtalkJS%2FArtalk?ref=badge_large) diff --git a/Dockerfile b/Dockerfile index 9bb93ea38..d1af5540d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -### build ArtalkGo +### build Artalk FROM golang:1.19.4-alpine3.17 as builder WORKDIR /source @@ -9,11 +9,11 @@ RUN set -ex \ && apk add make git gcc musl-dev nodejs bash npm\ && npm install -g pnpm@7.25.0 -COPY . ./ArtalkGo +COPY . ./Artalk # build RUN set -ex \ - && cd ./ArtalkGo \ + && cd ./Artalk \ && git fetch --tags -f \ && export VERSION=$(git describe --tags --abbrev=0) \ && export COMMIT_SHA=$(git rev-parse --short HEAD) \ @@ -28,7 +28,7 @@ ARG TZ="Asia/Shanghai" ENV TZ ${TZ} -COPY --from=builder /source/ArtalkGo/bin/artalk /artalk +COPY --from=builder /source/Artalk/bin/artalk /artalk RUN apk upgrade \ && apk add bash tzdata \ @@ -47,7 +47,7 @@ RUN chmod +x /entrypoint.sh ENTRYPOINT ["/entrypoint.sh"] -# expose ArtalkGo default port +# expose Artalk default port EXPOSE 23366 CMD ["server", "--host", "0.0.0.0", "--port", "23366"] diff --git a/README.en.md b/README.en.md index 5b63ea279..b281055e3 100644 --- a/README.en.md +++ b/README.en.md @@ -11,7 +11,7 @@ > 🌌 A Self-hosted comment system -[简体中文](./README.md) / [Documentation](https://artalk.js.org) / [Releases](https://github.com/ArtalkJS/ArtalkGo/releases) / [ArtalkGo](https://github.com/ArtalkJS/ArtalkGo) +[简体中文](./README.md) / [Documentation](https://artalk.js.org) / [Releases](https://github.com/ArtalkJS/Artalk/releases) / [Artalk](https://github.com/ArtalkJS/Artalk) --- @@ -82,7 +82,7 @@ mkdir Artalk cd Artalk # Download config template -curl -L https://raw.githubusercontent.com/ArtalkJS/ArtalkGo/master/artalk.example.yml > conf.yml +curl -L https://raw.githubusercontent.com/ArtalkJS/Artalk/master/artalk.example.yml > conf.yml docker run -d \ --name artalk \ diff --git a/README.md b/README.md index 9020b1c6e..d5f2488dc 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ > 🌌 Golang 自托管评论系统 -[English](./README.en.md) / [官方文档](https://artalk.js.org) / [最新后端](https://github.com/ArtalkJS/ArtalkGo/releases) / [ArtalkGo](https://github.com/ArtalkJS/ArtalkGo) +[English](./README.en.md) / [官方文档](https://artalk.js.org) / [最新后端](https://github.com/ArtalkJS/Artalk/releases) / [Artalk](https://github.com/ArtalkJS/Artalk) --- @@ -114,7 +114,7 @@ docker-compose up -d ## TODOs -- [x] [Golang 后端](https://github.com/ArtalkJS/ArtalkGo) +- [x] [Golang 后端](https://github.com/ArtalkJS/Artalk) - [x] 多数据库支持 - [x] SQLite - [x] MySQL diff --git a/cmd/admin.go b/cmd/admin.go index e720efee7..3631cd225 100644 --- a/cmd/admin.go +++ b/cmd/admin.go @@ -8,10 +8,10 @@ import ( "strings" "syscall" - "github.com/ArtalkJS/ArtalkGo/internal/core" - "github.com/ArtalkJS/ArtalkGo/internal/entity" - "github.com/ArtalkJS/ArtalkGo/internal/query" - "github.com/ArtalkJS/ArtalkGo/internal/utils" + "github.com/ArtalkJS/Artalk/internal/core" + "github.com/ArtalkJS/Artalk/internal/entity" + "github.com/ArtalkJS/Artalk/internal/query" + "github.com/ArtalkJS/Artalk/internal/utils" "github.com/sirupsen/logrus" "github.com/spf13/cobra" "golang.org/x/term" diff --git a/cmd/export.go b/cmd/export.go index a8310bcf5..456d38184 100644 --- a/cmd/export.go +++ b/cmd/export.go @@ -7,9 +7,9 @@ import ( "path/filepath" "time" - "github.com/ArtalkJS/ArtalkGo/internal/artransfer" - "github.com/ArtalkJS/ArtalkGo/internal/core" - "github.com/ArtalkJS/ArtalkGo/internal/utils" + "github.com/ArtalkJS/Artalk/internal/artransfer" + "github.com/ArtalkJS/Artalk/internal/core" + "github.com/ArtalkJS/Artalk/internal/utils" "github.com/sirupsen/logrus" "github.com/spf13/cobra" ) @@ -18,8 +18,8 @@ var exportCmd = &cobra.Command{ Use: "export", Aliases: []string{}, Short: "数据迁移 - 迁出", - Long: "\n# 数据迁移 - 迁出\n\n 将所有数据从 ArtalkGo 导出,用作备份,或迁移至其他地方\n 打包所有数据并导出成 “ArtalkGo 数据行囊 (Artrans)”,为数据迁移做准备\n" + ` -- 重新导入 ArtalkGo,可执行: artalk import <数据行囊文件路径> + Long: "\n# 数据迁移 - 迁出\n\n 将所有数据从 Artalk 导出,用作备份,或迁移至其他地方\n 打包所有数据并导出成 “Artalk 数据行囊 (Artrans)”,为数据迁移做准备\n" + ` +- 重新导入 Artalk,可执行: artalk import <数据行囊文件路径> - 文档:https://artalk.js.org/guide/transfer.html `, Run: func(cmd *cobra.Command, args []string) { diff --git a/cmd/gen.go b/cmd/gen.go index b89f9c604..8a3a8a4cc 100644 --- a/cmd/gen.go +++ b/cmd/gen.go @@ -3,7 +3,7 @@ package cmd import ( "os" - "github.com/ArtalkJS/ArtalkGo/internal/core" + "github.com/ArtalkJS/Artalk/internal/core" "github.com/sirupsen/logrus" "github.com/spf13/cobra" ) diff --git a/cmd/import.go b/cmd/import.go index 0f965fe3f..fc470e06a 100644 --- a/cmd/import.go +++ b/cmd/import.go @@ -4,8 +4,8 @@ import ( "errors" "os" - "github.com/ArtalkJS/ArtalkGo/internal/artransfer" - "github.com/ArtalkJS/ArtalkGo/internal/core" + "github.com/ArtalkJS/Artalk/internal/artransfer" + "github.com/ArtalkJS/Artalk/internal/core" "github.com/sirupsen/logrus" "github.com/spf13/cobra" ) diff --git a/cmd/root.go b/cmd/root.go index b23ae532e..14d90bd30 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -4,8 +4,8 @@ import ( "encoding/json" "fmt" - "github.com/ArtalkJS/ArtalkGo/internal/config" - "github.com/ArtalkJS/ArtalkGo/internal/core" + "github.com/ArtalkJS/Artalk/internal/config" + "github.com/ArtalkJS/Artalk/internal/core" "github.com/spf13/cobra" ) @@ -48,7 +48,7 @@ func Execute() { } func init() { - rootCmd.SetVersionTemplate("ArtalkGo ({{printf \"%s\" .Version}})\n") + rootCmd.SetVersionTemplate("Artalk ({{printf \"%s\" .Version}})\n") rootCmd.PersistentFlags().StringVarP(&cfgFile, "config", "c", "", "配置文件路径 (defaults are './artalk.yml')") rootCmd.PersistentFlags().StringVarP(&workDir, "workdir", "w", "", "程序工作目录 (defaults are './')") @@ -57,7 +57,7 @@ func init() { Use: "version", Short: "输出版本信息", Run: func(cmd *cobra.Command, args []string) { - fmt.Println("ArtalkGo (" + Version + ")") + fmt.Println("Artalk (" + Version + ")") }, } rootCmd.AddCommand(versionCmd) diff --git a/cmd/server.go b/cmd/server.go index f1bbed5b4..5c2088a2a 100644 --- a/cmd/server.go +++ b/cmd/server.go @@ -4,9 +4,9 @@ import ( "fmt" "io" - "github.com/ArtalkJS/ArtalkGo/internal/config" - "github.com/ArtalkJS/ArtalkGo/internal/core" - "github.com/ArtalkJS/ArtalkGo/server" + "github.com/ArtalkJS/Artalk/internal/config" + "github.com/ArtalkJS/Artalk/internal/core" + "github.com/ArtalkJS/Artalk/server" "github.com/gofiber/fiber/v2" "github.com/gofiber/fiber/v2/middleware/logger" "github.com/sirupsen/logrus" diff --git a/cmd/upgrade.go b/cmd/upgrade.go index d9a23005a..934d3dd0a 100644 --- a/cmd/upgrade.go +++ b/cmd/upgrade.go @@ -5,8 +5,8 @@ import ( "os" "strings" - "github.com/ArtalkJS/ArtalkGo/internal/config" - "github.com/ArtalkJS/ArtalkGo/internal/core" + "github.com/ArtalkJS/Artalk/internal/config" + "github.com/ArtalkJS/Artalk/internal/core" "github.com/blang/semver" "github.com/rhysd/go-github-selfupdate/selfupdate" "github.com/sirupsen/logrus" @@ -17,7 +17,7 @@ var upgradeCmd = &cobra.Command{ Use: "upgrade", Aliases: []string{"update"}, Short: "升级到最新版", - Long: "将 ArtalkGo 升级到最新版本,\n更新源为 GitHub Releases,\n更新需要重启 ArtalkGo 才能生效。", + Long: "将 Artalk 升级到最新版本,\n更新源为 GitHub Releases,\n更新需要重启 Artalk 才能生效。", Args: cobra.NoArgs, Run: func(cmd *cobra.Command, args []string) { // loadCore() // 装载核心 @@ -25,7 +25,7 @@ var upgradeCmd = &cobra.Command{ logrus.Info("从 GitHub Release 检索更新中...") - latest, found, err := selfupdate.DetectLatest("ArtalkJS/ArtalkGo") + latest, found, err := selfupdate.DetectLatest("ArtalkJS/Artalk") if err != nil { logrus.Fatal("Error occurred while detecting version: ", err) } diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh index fc2e23156..8416e8470 100755 --- a/docker-entrypoint.sh +++ b/docker-entrypoint.sh @@ -11,7 +11,7 @@ if [ ! -e /data/artalk.yml ] && [ "$1" != 'gen' ]; then cp /conf.yml /data/artalk.yml upMsg="" upMsg+=$'# [v2.1.9+ Updated]\n' - upMsg+=$'# The new version of the ArtalkGo container recommends mounting\n' + upMsg+=$'# The new version of the Artalk container recommends mounting\n' upMsg+=$'# an entire folder instead of a single file to avoid some issues.\n' upMsg+=$'#\n' upMsg+=$'# The original config file has been moved to the "/data/" folder,\n' @@ -22,5 +22,5 @@ if [ ! -e /data/artalk.yml ] && [ "$1" != 'gen' ]; then fi fi -# Run ArtalkGo +# Run Artalk artalk "$@" diff --git a/docs/docs/.vitepress/config.ts b/docs/docs/.vitepress/config.ts index 84b6ed130..ec698bc52 100644 --- a/docs/docs/.vitepress/config.ts +++ b/docs/docs/.vitepress/config.ts @@ -146,7 +146,7 @@ export default defineConfig({ }, { text: '后端仓库', - link: 'https://github.com/ArtalkJS/ArtalkGo', + link: 'https://github.com/ArtalkJS/Artalk', }, { text: '文档仓库', diff --git a/docs/docs/code/quick-start/normal-install.sh b/docs/docs/code/quick-start/normal-install.sh index 4684316f5..f61777fc6 100644 --- a/docs/docs/code/quick-start/normal-install.sh +++ b/docs/docs/code/quick-start/normal-install.sh @@ -1,4 +1,4 @@ -$ tar xvzf artalk-go.tar.gz -$ cd artalk-go -$ vim artalk-go.yml -$ ./artalk-go server +$ tar xvzf artalk.tar.gz +$ cd artalk +$ vim artalk.yml +$ ./artalk server diff --git a/docs/docs/develop/api.md b/docs/docs/develop/api.md index ee719c3f6..af399eafe 100644 --- a/docs/docs/develop/api.md +++ b/docs/docs/develop/api.md @@ -219,7 +219,7 @@ | 字段名 | 数据类型 | 默认 | 说明 | | ----- | ------- | :-: | --- | -| `app` | String | `artalk-go` | Artalk 后端程序名 | +| `app` | String | `artalk` | Artalk 后端程序名 | | `version` | String | - | Artalk 后端程序版本号 | | `commit_hash` | String | - | Artalk 后端程序 Git 提交哈希值 | | `fe_min_version` | String | - | Artalk 后端程序所需前端最低版本 | diff --git a/docs/docs/develop/index.md b/docs/docs/develop/index.md index e1dea6744..219a874b8 100644 --- a/docs/docs/develop/index.md +++ b/docs/docs/develop/index.md @@ -10,8 +10,8 @@ - `API` 部分参考源码 * [@ArtalkJS/Artalk - src/api/index.ts](https://github.com/ArtalkJS/Artalk/blob/master/packages/artalk/src/api/index.ts) - * [@ArtalkJS/ArtalkGo - http/a_router.go](https://github.com/ArtalkJS/ArtalkGo/blob/master/http/a_router.go) - * [@ArtalkJS/ArtalkGo - http/a_http.go](https://github.com/ArtalkJS/ArtalkGo/blob/master/http/a_http.go) + * [@ArtalkJS/Artalk - http/a_router.go](https://github.com/ArtalkJS/Artalk/blob/master/http/a_router.go) + * [@ArtalkJS/Artalk - http/a_http.go](https://github.com/ArtalkJS/Artalk/blob/master/http/a_http.go) - `Event` 部分参考源码 * [@ArtalkJS/Artalk - types/event.d.ts](https://github.com/ArtalkJS/Artalk/blob/master/packages/artalk/types/event.d.ts) diff --git a/docs/docs/guide/backend/admin_notify.md b/docs/docs/guide/backend/admin_notify.md index 55c7ae7a9..72c1cbc4f 100644 --- a/docs/docs/guide/backend/admin_notify.md +++ b/docs/docs/guide/backend/admin_notify.md @@ -1,6 +1,6 @@ # 多元推送 -你可以配置 `admin_notify`,让 ArtalkGo 以多种方式通知管理员。 +你可以配置 `admin_notify`,让 Artalk 以多种方式通知管理员。 支持 **Telegram**、**飞书**、**钉钉**、**Bark**、**Slack**、**LINE**,并且多种方式可以同时启用。 @@ -94,7 +94,7 @@ admin_notify: ![](/images/notify/tg-1.png) -标红的文字就是你之后需要在 ArtalkGo 配置中填入的 `api_token`。 +标红的文字就是你之后需要在 Artalk 配置中填入的 `api_token`。 配置中的 `receivers` 填入需要接受消息的账号数字 ID,可以搜索机器人 `@RawDataBot` 获取如图: @@ -104,7 +104,7 @@ admin_notify: ::: tip -鉴于复杂的网络环境,如需使用代理,请在 ArtalkGo 启动之前配置环境变量,例如: +鉴于复杂的网络环境,如需使用代理,请在 Artalk 启动之前配置环境变量,例如: ```sh export https_proxy=http://127.0.0.1:7890 @@ -134,7 +134,7 @@ admin_notify: <img src="/images/notify/lark-2.png" width="700px"> -复制如上图的 WebHook 地址,并修改 ArtalkGo 的 `webhook_url` 配置即可。 +复制如上图的 WebHook 地址,并修改 Artalk 的 `webhook_url` 配置即可。 <img src="/images/notify/lark-3.png" width="400px"> @@ -165,7 +165,7 @@ admin_notify: [Bark](https://github.com/Finb/Bark) 是一款开源的 iOS App,并且[支持自托管](https://github.com/Finb/bark-server),你能使用 Bark 轻松地推送消息给你的 iOS 设备。 -你可以在 App Store 搜索下载,并获得需要填入 ArtalkGo 的 `server` 配置项: +你可以在 App Store 搜索下载,并获得需要填入 Artalk 的 `server` 配置项: <img src="/images/notify/bark.png" width="700px"> @@ -231,9 +231,9 @@ noise_mode 默认为关闭状态,当该项设置为 `false` 时,站内仅向 开启 WebHook 后,创建新评论将以 **POST** 方式携带 `application/json` 类型的 Body 数据请求设定的 WebHook 地址。 -你可以编写自己的 Server 端代码,处理来自 ArtalkGo 的请求。 +你可以编写自己的 Server 端代码,处理来自 Artalk 的请求。 -**ArtalkGo 配置文件** +**Artalk 配置文件** ```yaml admin_notify: @@ -359,7 +359,7 @@ import ( "net/http" ) -type ArtalkGoNotify struct { +type ArtalkNotify struct { NotifySubject string `json:"notify_subject"` NotifyBody string `json:"notify_body"` Comment interface{} `json:"comment"` @@ -368,7 +368,7 @@ type ArtalkGoNotify struct { func webhookHandler(rw http.ResponseWriter, req *http.Request) { decoder := json.NewDecoder(req.Body) - var notify ArtalkGoNotify + var notify ArtalkNotify err := decoder.Decode(¬ify) if err != nil { panic(err) diff --git a/docs/docs/guide/backend/build.md b/docs/docs/guide/backend/build.md index 1485547c6..1876eee3c 100644 --- a/docs/docs/guide/backend/build.md +++ b/docs/docs/guide/backend/build.md @@ -4,25 +4,25 @@ ```bash # 拉取代码 -git clone https://github.com/ArtalkJS/ArtalkGo.git ArtalkGo +git clone https://github.com/ArtalkJS/Artalk.git Artalk # 编译程序 -cd ArtalkGo && make all +cd Artalk && make all # 配置文件 -cp artalk-go.example.yml artalk-go.yml -vim artalk-go.yml +cp artalk.example.yml artalk.yml +vim artalk.yml # 运行程序 -./bin/artalk-go help -./bin/artalk-go -c artalk-go.yml server +./bin/artalk help +./bin/artalk -c artalk.yml server ``` ## 构建二进制文件 ```bash # 拉取代码 -git clone https://github.com/ArtalkJS/ArtalkGo.git +git clone https://github.com/ArtalkJS/Artalk.git # 执行编译 make all @@ -34,8 +34,8 @@ make all ```bash # 拉取代码 -git clone https://github.com/ArtalkJS/ArtalkGo -cd ArtalkGo +git clone https://github.com/ArtalkJS/Artalk +cd Artalk # 构建镜像 docker-compose build @@ -48,8 +48,8 @@ docker-compose up -d ```bash # 拉取代码 -git clone https://github.com/ArtalkJS/ArtalkGo -cd ArtalkGo +git clone https://github.com/ArtalkJS/Artalk +cd Artalk # 构建镜像 make docker-docker @@ -60,8 +60,8 @@ make docker-push ## DevOps -后端构建目前已交给 [GitHub Actions](https://github.com/ArtalkJS/ArtalkGo/actions) 自动完成 +后端构建目前已交给 [GitHub Actions](https://github.com/ArtalkJS/Artalk/actions) 自动完成 |Docker 镜像构建|Release 编译| |-|-| -|[![CI to Docker Hub](https://github.com/ArtalkJS/ArtalkGo/actions/workflows/dockerhub.yml/badge.svg)](https://github.com/ArtalkJS/ArtalkGo/actions/workflows/dockerhub.yml)|[![Release Build](https://github.com/ArtalkJS/ArtalkGo/actions/workflows/release.yml/badge.svg?branch=master)](https://github.com/ArtalkJS/ArtalkGo/actions/workflows/release.yml)| +|[![CI to Docker Hub](https://github.com/ArtalkJS/Artalk/actions/workflows/dockerhub.yml/badge.svg)](https://github.com/ArtalkJS/Artalk/actions/workflows/dockerhub.yml)|[![Release Build](https://github.com/ArtalkJS/Artalk/actions/workflows/release.yml/badge.svg?branch=master)](https://github.com/ArtalkJS/Artalk/actions/workflows/release.yml)| diff --git a/docs/docs/guide/backend/captcha.md b/docs/docs/guide/backend/captcha.md index bf36c7391..a7b3fc313 100644 --- a/docs/docs/guide/backend/captcha.md +++ b/docs/docs/guide/backend/captcha.md @@ -1,6 +1,6 @@ # 验证码 -ArtalkGo 内置图片验证码功能,你可以配置操作频率限制,当超过限度时激活验证码。 +Artalk 内置图片验证码功能,你可以配置操作频率限制,当超过限度时激活验证码。 此外,你也可以接入[极验](https://www.geetest.com/),拥有一个滑动验证码。 @@ -65,7 +65,7 @@ captcha: ## Geetest 极验 -ArtalkGo 支持接入 [Geetest 极验](https://www.geetest.com/adaptive-captcha) 第四代「行为验」,启用极验后,验证码将切换为滑动验证码。 +Artalk 支持接入 [Geetest 极验](https://www.geetest.com/adaptive-captcha) 第四代「行为验」,启用极验后,验证码将切换为滑动验证码。 你需要在官网注册账号,并申请获得 `captcha_id` 和 `captcha_key`,并填入配置文件: diff --git a/docs/docs/guide/backend/config.md b/docs/docs/guide/backend/config.md index 126c39bc1..a7a3cba00 100644 --- a/docs/docs/guide/backend/config.md +++ b/docs/docs/guide/backend/config.md @@ -4,37 +4,37 @@ 后端配置可以在侧边栏 “[控制中心](/guide/frontend/sidebar.md)” 直接修改,无需手动修改配置 ::: -ArtalkGo 默认以工作目录下的 `artalk-go.yml` 作为配置文件,可使用参数 `-c` 来指定具体文件: +Artalk 默认以工作目录下的 `artalk.yml` 作为配置文件,可使用参数 `-c` 来指定具体文件: ```bash -artalk-go -c ./conf.yml +artalk -c ./conf.yml ``` ## 获取模版配置文件 -可参考一份「完整的配置文件」:[artalk-go.example.yml](https://github.com/ArtalkJS/ArtalkGo/blob/master/artalk-go.example.yml) +可参考一份「完整的配置文件」:[artalk.example.yml](https://github.com/ArtalkJS/Artalk/blob/master/artalk.example.yml) #### 使用 gen 命令生成配置文件 -ArtalkGo 提供 `gen` 命令,你可以快速生成一份新的配置文件: +Artalk 提供 `gen` 命令,你可以快速生成一份新的配置文件: ```bash -artalk-go gen conf ./artalk-go.yml +artalk gen conf ./artalk.yml ``` #### 命令行下载配置文件 ```bash -curl -L https://raw.githubusercontent.com/ArtalkJS/ArtalkGo/master/artalk-go.example.yml > artalk-go.yml +curl -L https://raw.githubusercontent.com/ArtalkJS/Artalk/master/artalk.example.yml > artalk.yml ``` ```bash -wget -O artalk-go.yml https://raw.githubusercontent.com/ArtalkJS/ArtalkGo/master/artalk-go.example.yml +wget -O artalk.yml https://raw.githubusercontent.com/ArtalkJS/Artalk/master/artalk.example.yml ``` ## 加密密钥 `app_key` -在 ArtalkGo 启动之前,你需要配置一个 `app_key` 用于对网站内容进行安全加密: +在 Artalk 启动之前,你需要配置一个 `app_key` 用于对网站内容进行安全加密: ```yaml app_key: "<任意的字符>" @@ -42,7 +42,7 @@ app_key: "<任意的字符>" ## 数据库 `db` -ArtalkGo 支持连接多种数据库,支持 SQLite、MySQL、PostgreSQL、SQL Server 配置如下: +Artalk 支持连接多种数据库,支持 SQLite、MySQL、PostgreSQL、SQL Server 配置如下: #### SQLite @@ -51,7 +51,7 @@ SQLite 是轻型数据库,使用单个文件存储数据,无需额外运行 ```yaml db: type: "sqlite" - file: "./data/artalk-go.db" + file: "./data/artalk.db" ``` #### MySQL / PostgreSQL / SQL Server @@ -70,13 +70,13 @@ db: table_prefix: "" # 表前缀 (例如:"atk_") ``` -数据表将在 ArtalkGo 启动时自动完成创建,无需额外操作。 +数据表将在 Artalk 启动时自动完成创建,无需额外操作。 ## 管理员 `admin_users` 你需要配置管理员账户,这样才能通过「[控制中心](../frontend/sidebar.md)」对站点内容进行管理。 -ArtalkGo 支持多站点,你可以创建多个管理员账户,为其分配站点,让你的朋友们共用同一个后端程序。 +Artalk 支持多站点,你可以创建多个管理员账户,为其分配站点,让你的朋友们共用同一个后端程序。 详情参考:[“管理员 × 多站点”](/guide/backend/multi-site.md) @@ -98,7 +98,7 @@ trusted_domains: ::: -在侧边栏[控制中心](../frontend/sidebar.md#控制中心)「站点」选项卡 - 选择站点「修改 URL」,填入站点 URL 也具有相同的效果;添加多个 URL 可使用 `","` 英文逗号分隔,修改后请重启 ArtalkGo。 +在侧边栏[控制中心](../frontend/sidebar.md#控制中心)「站点」选项卡 - 选择站点「修改 URL」,填入站点 URL 也具有相同的效果;添加多个 URL 可使用 `","` 英文逗号分隔,修改后请重启 Artalk。 可以将其关闭: @@ -166,7 +166,7 @@ new Artalk({ site: "Artalk 官网" }) ## 缓存配置 `cache` -为了提高评论系统的响应速度和性能,ArtalkGo 内置一套缓存机制,并且默认开启,无需额外配置。但如果有需要,你也可以连接外部缓存服务器,支持 Redis 和 Memcache。 +为了提高评论系统的响应速度和性能,Artalk 内置一套缓存机制,并且默认开启,无需额外配置。但如果有需要,你也可以连接外部缓存服务器,支持 Redis 和 Memcache。 ```yaml cache: @@ -176,12 +176,12 @@ cache: server: "" # 连接缓存服务器 (例如:"localhost:6379") ``` -- **warm_up**:缓存预热功能。设置为 `true`,在 ArtalkGo 启动时会立刻对数据库内容进行全面缓存,如果你的评论数据较多,多达上万条,启动时间可能会延长。 +- **warm_up**:缓存预热功能。设置为 `true`,在 Artalk 启动时会立刻对数据库内容进行全面缓存,如果你的评论数据较多,多达上万条,启动时间可能会延长。 - **type**:缓存类型。可选:`redis`, `memcache`, `builtin`。 type 默认为 `builtin`,如遇特殊情况可将缓存关闭,将其设置为 `disabled`。 -注:如果在 ArtalkGo 程序外部修改数据库内容,需要刷新 ArtalkGo 缓存才能更新。 +注:如果在 Artalk 程序外部修改数据库内容,需要刷新 Artalk 缓存才能更新。 --- @@ -198,27 +198,27 @@ cache: db: 0 # 使用零号数据库 ``` -技术细节:[ArtalkGo 缓存机制 时序图.png](/images/artalk-go/artalk-go-cache.png) +技术细节:[Artalk 缓存机制 时序图.png](/images/artalk/artalk-cache.png) -![](/images/artalk-go/artalk-go-cache.png) +![](/images/artalk/artalk-cache.png) ## 监听地址 `host` -ArtalkGo 的默认 HTTP 端口为 23366,你可以在配置文件中指定: +Artalk 的默认 HTTP 端口为 23366,你可以在配置文件中指定: ```yaml host: "0.0.0.0" port: 23366 ``` -配置 `host` 监听地址为 `0.0.0.0` 将 ArtalkGo 服务暴露到全网可访问范围, +配置 `host` 监听地址为 `0.0.0.0` 将 Artalk 服务暴露到全网可访问范围, -如果你只想让 ArtalkGo 仅本地能够访问,可将 `host` 配置为 `127.0.0.1`。 +如果你只想让 Artalk 仅本地能够访问,可将 `host` 配置为 `127.0.0.1`。 -命令行下启动 ArtalkGo 时,可以携带 `--host` 和 `--port` 参数分别对地址和端口进行指定,例如: +命令行下启动 Artalk 时,可以携带 `--host` 和 `--port` 参数分别对地址和端口进行指定,例如: ```bash -artalk-go server --host 127.0.0.1 --port 8080 +artalk server --host 127.0.0.1 --port 8080 ``` ## 加密传输 `ssl` @@ -235,7 +235,7 @@ ssl: - `cert_path`:SSL 证书公钥文件路径。 - `key_path`:SSL 证书私钥文件路径。 -你也可以直接反向代理 ArtalkGo 本地服务器,然后在例如 Nginx 启用 HTTPS。 +你也可以直接反向代理 Artalk 本地服务器,然后在例如 Nginx 启用 HTTPS。 ## 时区配置 `timezone` @@ -269,7 +269,7 @@ login_timeout: 259200 ```yaml log: enabled: true # 总开关 - filename: "./data/artalk-go.log" # 日志文件路径 + filename: "./data/artalk.log" # 日志文件路径 ``` ## 调试模式 `debug` @@ -282,7 +282,7 @@ debug: true ## 工作目录 `-w` 参数 -ArtalkGo 在不指定工作目录的情况下,会使用「程序启动时的目录」作为工作目录。 +Artalk 在不指定工作目录的情况下,会使用「程序启动时的目录」作为工作目录。 ```bash pwd # 显示当前目录路径 @@ -291,24 +291,24 @@ pwd # 显示当前目录路径 使用参数 `-w` 来指定工作目录,它通常是一个「绝对路径」,例如: ```bash -artalk-go -w /root/artalk -c ./conf.yml +artalk -w /root/artalk -c ./conf.yml ``` -注:`-c` 的相对路径会基于 `-w` 的路径,ArtalkGo 此时会读取 `/root/artalk/conf.yml` 作为配置文件。 +注:`-c` 的相对路径会基于 `-w` 的路径,Artalk 此时会读取 `/root/artalk/conf.yml` 作为配置文件。 其次,在「配置文件中」使用的「相对路径」,也会基于「工作目录」。 例如 `conf.yml` 中有这样的配置: ```yaml -test_file: "./data/artalk-go.log" +test_file: "./data/artalk.log" ``` -将读取 `/root/artalk/data/artalk-go.log`。 +将读取 `/root/artalk/data/artalk.log`。 ::: tip -配置文件相关代码:[/config/config.go](https://github.com/ArtalkJS/ArtalkGo/blob/master/config/config.go) +配置文件相关代码:[/config/config.go](https://github.com/ArtalkJS/Artalk/blob/master/config/config.go) 前往:[“前端配置”](/guide/frontend/config.md) ::: diff --git a/docs/docs/guide/backend/daemon.md b/docs/docs/guide/backend/daemon.md index e7b1e3a51..b8ae92db7 100644 --- a/docs/docs/guide/backend/daemon.md +++ b/docs/docs/guide/backend/daemon.md @@ -5,7 +5,7 @@ 更新 Docker 容器的 [Restart 策略](https://docs.docker.com/config/containers/start-containers-automatically/#use-a-restart-policy) 以达到进程守护效果。 ```bash -docker update --restart=unless-stopped artalk-go +docker update --restart=unless-stopped artalk ``` ## Docker Compose @@ -25,25 +25,25 @@ tmux 将创建一个持续的命令行会话,在 SSH 或 tty 断开后保持 Note: 服务器关闭或重启后,tmux 会话将被清除,需要手动重新运行程序。 -1. 创建会话 `tmux new -s artalk-go` -2. 运行程序 `./artalk-go server` +1. 创建会话 `tmux new -s artalk` +2. 运行程序 `./artalk server` -恢复接入会话:`tmux attach -t artalk-go` +恢复接入会话:`tmux attach -t artalk` 查看所有会话:`tmux ls` ## systemd -`sudo vim /etc/systemd/system/artalk-go.service` +`sudo vim /etc/systemd/system/artalk.service` ```ini [Unit] -Description=Artalk Go +Description=Artalk After=network.target remote-fs.target nss-lookup.target [Service] User=root -ExecStart=<ArtalkGo 执行文件绝对路径> server -w <工作目录绝对路径> -c <配置文件相对于工作目录路径> +ExecStart=<Artalk 执行文件绝对路径> server -w <工作目录绝对路径> -c <配置文件相对于工作目录路径> ExecReload=/bin/kill -s HUP $MAINPID ExecStop=/bin/kill -s QUIT $MAINPID Restart=on-abnormal @@ -53,11 +53,11 @@ RestartSec=5s WantedBy=multi-user.target ``` - 更新 systemd 配置:`systemctl daemon-reload` -- 启动:`systemctl start artalk-go.service` -- 停止:`systemctl stop artalk-go.service` -- 状态:`systemctl status artalk-go.service` +- 启动:`systemctl start artalk.service` +- 停止:`systemctl stop artalk.service` +- 状态:`systemctl status artalk.service` -Tip: 设置 `alias` 简化命令输入;ArtalkGo 参数 `-w` 用于指定工作目录,配置文件中的所有「相对路径」会基于该目录,例如 `./data/` 文件夹。 +Tip: 设置 `alias` 简化命令输入;Artalk 参数 `-w` 用于指定工作目录,配置文件中的所有「相对路径」会基于该目录,例如 `./data/` 文件夹。 ## Supervisor @@ -71,5 +71,5 @@ Tip: 设置 `alias` 简化命令输入;ArtalkGo 参数 `-w` 用于指定工作 > - 启动用户:`root` 或其他 > - 运行目录:点击右侧图标,选择 Artalk 所在目录 -> - 启动命令:`./artalk-go server` +> - 启动命令:`./artalk server` diff --git a/docs/docs/guide/backend/docker.md b/docs/docs/guide/backend/docker.md index e53c0d48b..9c5d92db7 100644 --- a/docs/docs/guide/backend/docker.md +++ b/docs/docs/guide/backend/docker.md @@ -2,11 +2,11 @@ Artalk 提供后端程序的 Docker 镜像,以便加速部署流程,提供一个良好的部署体验。 -[Docker Hub](https://hub.docker.com/r/artalk/artalk-go) 镜像版本随代码仓库的 [Releases](https://github.com/ArtalkJS/ArtalkGo/releases) 保持同步。 +[Docker Hub](https://hub.docker.com/r/artalk/artalk) 镜像版本随代码仓库的 [Releases](https://github.com/ArtalkJS/Artalk/releases) 保持同步。 ## 镜像拉取 -`docker pull artalk/artalk-go` +`docker pull artalk/artalk` ## 容器创建 @@ -19,25 +19,25 @@ Artalk 提供后端程序的 Docker 镜像,以便加速部署流程,提供 常规的 Docker 容器创建可参考: ```bash -# 为 ArtalkGo 创建一个目录 -mkdir ArtalkGo -cd ArtalkGo +# 为 Artalk 创建一个目录 +mkdir Artalk +cd Artalk # 拉取 docker 镜像 -docker pull artalk/artalk-go +docker pull artalk/artalk # 生成配置文件 -docker run -it -v $(pwd)/data:/data --rm artalk/artalk-go gen config data/artalk-go.yml +docker run -it -v $(pwd)/data:/data --rm artalk/artalk gen config data/artalk.yml # 编辑配置文件 -vim data/artalk-go.yml +vim data/artalk.yml # 运行 docker 容器 docker run -d \ - --name artalk-go \ + --name artalk \ -p 0.0.0.0:8080:23366 \ -v $(pwd)/data:/data \ - artalk/artalk-go + artalk/artalk ``` 然后,在前端配置填入后端地址: @@ -55,7 +55,7 @@ new Artalk({ server: "http://your_domain:8080" }) docker-compose restart # Docker -docker restart artalk-go +docker restart artalk ``` ## 停止 @@ -65,7 +65,7 @@ docker restart artalk-go docker-compose stop # Docker -docker stop artalk-go +docker stop artalk ``` ## 升级 @@ -83,13 +83,13 @@ docker-compose up -d ### Docker ```bash -docker stop artalk-go -docker rm artalk-go -docker pull artalk/artalk-go +docker stop artalk +docker rm artalk +docker pull artalk/artalk ``` ::: tip -升级可能会有配置文件等变动,请注意查看版本 Changelog,通常是在 [GitHub Release](https://github.com/ArtalkJS/ArtalkGo/releases) 页面 +升级可能会有配置文件等变动,请注意查看版本 Changelog,通常是在 [GitHub Release](https://github.com/ArtalkJS/Artalk/releases) 页面 ::: ## 拉取历史镜像 @@ -97,7 +97,7 @@ docker pull artalk/artalk-go 镜像会随代码仓库 tags 自动构建发布,您可拉取不同版本号的镜像。 ```bash -docker pull artalk/artalk-go@版本号 +docker pull artalk/artalk@版本号 ``` ## 进入容器 diff --git a/docs/docs/guide/backend/email.md b/docs/docs/guide/backend/email.md index bf7c9467a..7c4733546 100644 --- a/docs/docs/guide/backend/email.md +++ b/docs/docs/guide/backend/email.md @@ -1,8 +1,8 @@ # 邮件通知 -启用后,当用户「新增评论」或「回复评论」时,ArtalkGo 会向「普通用户」或「管理员」发送邮件。 +启用后,当用户「新增评论」或「回复评论」时,Artalk 会向「普通用户」或「管理员」发送邮件。 -ArtalkGo 支持 SMTP 协议、阿里云邮件推送、调用系统 sendmail 命令等。 +Artalk 支持 SMTP 协议、阿里云邮件推送、调用系统 sendmail 命令等。 完整的 `email` 配置如下: @@ -308,7 +308,7 @@ email: </div> ``` -ArtalkGo 内置许多预设的邮件模板,例如 `mail_tpl: "default"` 使用的就是:[/email-tpl/default.html](https://github.com/ArtalkJS/ArtalkGo/blob/master/email-tpl/default.html) +Artalk 内置许多预设的邮件模板,例如 `mail_tpl: "default"` 使用的就是:[/email-tpl/default.html](https://github.com/ArtalkJS/Artalk/blob/master/email-tpl/default.html) ## 发向管理员的邮件 @@ -322,4 +322,4 @@ admin_notify: 注:旧版 `email.mail_subject_to_admin` 配置项已弃用,请使用以上替代。 -不局限于邮件,ArtalkGo 支持多种方式向管理员发送通知,参考:[“多元推送”](./admin_notify.md#邮件通知)。 +不局限于邮件,Artalk 支持多种方式向管理员发送通知,参考:[“多元推送”](./admin_notify.md#邮件通知)。 diff --git a/docs/docs/guide/backend/fe-control.md b/docs/docs/guide/backend/fe-control.md index 057d62bf4..9ec720d27 100644 --- a/docs/docs/guide/backend/fe-control.md +++ b/docs/docs/guide/backend/fe-control.md @@ -4,7 +4,7 @@ ## 在前端引入内置的资源 -后端 ArtalkGo 服务器中内置了可供前端引入的 JS 和 CSS 资源文件: +后端 Artalk 服务器中内置了可供前端引入的 JS 和 CSS 资源文件: ```html <!-- CSS --> @@ -14,9 +14,9 @@ <script src="https://<artalk_go_server>/dist/Artalk.js"></script> ``` -> 提示:将 `<artalk_go_server>` 替换为你的 ArtalkGo 服务器地址。 +> 提示:将 `<artalk_go_server>` 替换为你的 Artalk 服务器地址。 -这样如果升级后端 ArtalkGo 程序,前端无需更换新版 ArtalkJS 的引入地址,来使之与后端程序兼容。 +这样如果升级后端 Artalk 程序,前端无需更换新版 ArtalkJS 的引入地址,来使之与后端程序兼容。 注:内置的前端 JS 和 CSS 始终与后端版本兼容,但不保证是最新的版本。 @@ -32,7 +32,7 @@ new Artalk({ }) ``` -然后,在后端 ArtalkGo 的配置文件中添加 `frontend` 字段内容,例如 `artalk-go.yml` 添加: +然后,在后端 Artalk 的配置文件中添加 `frontend` 字段内容,例如 `artalk.yml` 添加: ```yaml frontend: @@ -46,7 +46,7 @@ frontend: 这样就无需在前端改动配置,前端的配置始终跟随后端。 -一份完整的后端 `frontend` 字段配置文件可供参考:[artalk-go.frontend.example.yml](https://github.com/ArtalkJS/ArtalkGo/blob/master/artalk-go.frontend.example.yml) +一份完整的后端 `frontend` 字段配置文件可供参考:[artalk.frontend.example.yml](https://github.com/ArtalkJS/Artalk/blob/master/artalk.frontend.example.yml) ::: tip diff --git a/docs/docs/guide/backend/img-upload.md b/docs/docs/guide/backend/img-upload.md index 9c9c4847a..41f8f0aea 100644 --- a/docs/docs/guide/backend/img-upload.md +++ b/docs/docs/guide/backend/img-upload.md @@ -24,7 +24,7 @@ img_upload: 首先,根据 [README.md](https://github.com/pluveto/upgit) 的说明,下载 Upgit 并完成你需要上传的目标图床的配置。 -然后在 ArtalkGo 的 `img_upload.upgit` 字段填入 Upgit 启动参数 (建议使用程序绝对路径),例如: +然后在 Artalk 的 `img_upload.upgit` 字段填入 Upgit 启动参数 (建议使用程序绝对路径),例如: ```yaml upgit: @@ -41,7 +41,7 @@ img_upload: ## path -`img_upload.path` 为上传的图片文件「本地存放目录」路径,该目录会被 ArtalkGo 映射到可访问的: +`img_upload.path` 为上传的图片文件「本地存放目录」路径,该目录会被 Artalk 映射到可访问的: ``` http://<后端地址>/static/images/ diff --git a/docs/docs/guide/backend/index.md b/docs/docs/guide/backend/index.md index f4007d413..9ae482b04 100644 --- a/docs/docs/guide/backend/index.md +++ b/docs/docs/guide/backend/index.md @@ -3,11 +3,11 @@ prev: install.md next: config.md --- -# ArtalkGo +# Artalk Artalk 拥有一个 Golang 语言编写的后端程序。 -[GitHub 代码仓库](https://github.com/ArtalkJS/ArtalkGo) +[GitHub 代码仓库](https://github.com/ArtalkJS/Artalk) - 高效快速 - 异步执行 diff --git a/docs/docs/guide/backend/moderator.md b/docs/docs/guide/backend/moderator.md index 3728f5e84..18ac6a9bf 100644 --- a/docs/docs/guide/backend/moderator.md +++ b/docs/docs/guide/backend/moderator.md @@ -87,7 +87,7 @@ moderator: ## 关键词词库过滤 -如果你不想依赖于远程 API,可以在本地配置导入词库文件,让 ArtalkGo 根据词语来检测垃圾评论: +如果你不想依赖于远程 API,可以在本地配置导入词库文件,让 Artalk 根据词语来检测垃圾评论: ```yaml moderator: @@ -101,7 +101,7 @@ moderator: ``` - **pending**:当成功匹配时,是否将评论设为待审核状态。 -- **files**:词库文件。允许多个文件,ArtalkGo 启动时会合并词库。 +- **files**:词库文件。允许多个文件,Artalk 启动时会合并词库。 - **file_sep**:词库文件内容分割符。例如:文件中每行一个词语,该项配置 `\n`。 - **replac_to**:替换字符。例如:该项设置为 `x`,你可以将 `pending` 设置为 `false`,评论自动过审,但匹配到的词语会被替换为 `x`,例如 `fxxk`、`xxxx`。 @@ -109,4 +109,4 @@ moderator: ## 使用验证码 -你可以开启 ArtalkGo 的验证码功能,支持图片和滑动验证码,[参考此处](./captcha.md)。 +你可以开启 Artalk 的验证码功能,支持图片和滑动验证码,[参考此处](./captcha.md)。 diff --git a/docs/docs/guide/backend/multi-site.md b/docs/docs/guide/backend/multi-site.md index b515ca31e..c85d208a3 100644 --- a/docs/docs/guide/backend/multi-site.md +++ b/docs/docs/guide/backend/multi-site.md @@ -1,12 +1,12 @@ # 管理员 × 多站点 -ArtalkGo 支持站点隔离,以及为站点分配指定的管理员账户, +Artalk 支持站点隔离,以及为站点分配指定的管理员账户, 所以,你可以实现两种模式:单人多站点、多人多站点。 -运用「单人多站点」模式,你能够实现多个站点共用同一个 ArtalkGo 后端程序,集中化管理。 +运用「单人多站点」模式,你能够实现多个站点共用同一个 Artalk 后端程序,集中化管理。 -运用「多人多站点」模式,你可以和你的朋友们共用同一个 ArtalkGo 后端程序。😉 +运用「多人多站点」模式,你可以和你的朋友们共用同一个 Artalk 后端程序。😉 ## 管理员配置 diff --git a/docs/docs/guide/backend/notify.md b/docs/docs/guide/backend/notify.md index 1615f7c23..4113b27cc 100644 --- a/docs/docs/guide/backend/notify.md +++ b/docs/docs/guide/backend/notify.md @@ -1,6 +1,6 @@ # 多元通知 -ArtalkGo v2.1.8+ 配置项: +Artalk v2.1.8+ 配置项: - `notify` 弃用并变更为 `admin_notify` - `email.mail_subject_to_admin` 弃用并变更为 `admin_notify.email.mail_subject` diff --git a/docs/docs/guide/backend/relative-path.md b/docs/docs/guide/backend/relative-path.md index 0612bc961..0853ea0bf 100644 --- a/docs/docs/guide/backend/relative-path.md +++ b/docs/docs/guide/backend/relative-path.md @@ -1,6 +1,6 @@ # 相对 / 绝对路径 -ArtalkGo 支持解析相对路径,因此你可以在前端页面进行如下配置: +Artalk 支持解析相对路径,因此你可以在前端页面进行如下配置: ```js new Artalk({ diff --git a/docs/docs/guide/backend/reverse-proxy.md b/docs/docs/guide/backend/reverse-proxy.md index 205ff227f..726876f8a 100644 --- a/docs/docs/guide/backend/reverse-proxy.md +++ b/docs/docs/guide/backend/reverse-proxy.md @@ -5,7 +5,7 @@ 假定: - 你想绑定的域名是:`artalk.your_domain.com` -- ArtalkGo 本地地址:`http://localhost:23366` +- Artalk 本地地址:`http://localhost:23366` 以 Ubuntu 20.04 为例: @@ -64,7 +64,7 @@ new Artalk({ server: "http://artalk.your_domain.com" }) 注意配置文件权限,以及反代目标 URL 可访问性 -尤其是运行在 Docker 容器内的 artalk-go,注意检查 IP 和端口是否能够被 Nginx 正常访问 +尤其是运行在 Docker 容器内的 artalk,注意检查 IP 和端口是否能够被 Nginx 正常访问 ::: ## Caddy @@ -105,7 +105,7 @@ artalk.your_domain.com { ![](/images/baota-proxy/1.png) -打开「反向代理」选项卡,点击「添加反向代理」,「目标 URL」填写 `http://localhost:端口号`(端口号与 ArtalkGo 端口对应),「发送域名」填写 `$host`,如图: +打开「反向代理」选项卡,点击「添加反向代理」,「目标 URL」填写 `http://localhost:端口号`(端口号与 Artalk 端口对应),「发送域名」填写 `$host`,如图: ![](/images/baota-proxy/2.png) diff --git a/docs/docs/guide/backend/update.md b/docs/docs/guide/backend/update.md index e48e98ba4..28e80d4be 100644 --- a/docs/docs/guide/backend/update.md +++ b/docs/docs/guide/backend/update.md @@ -2,13 +2,13 @@ ## 命令行一键升级 -执行 `./artalk-go upgrade` +执行 `./artalk upgrade` -此操作会从自动从 GitHub Release 下载并升级程序,执行前需关闭 ArtalkGo。 +此操作会从自动从 GitHub Release 下载并升级程序,执行前需关闭 Artalk。 :::tip -执行 `./artalk-go upgrade -f` 携带参数 `-f` 来进行同版本号的补充更新。 +执行 `./artalk upgrade -f` 携带参数 `-f` 来进行同版本号的补充更新。 ::: @@ -18,10 +18,10 @@ ## 普通方式 -前往 [GitHub Release](https://github.com/ArtalkJS/ArtalkGo/releases) 手动下载最新构建 +前往 [GitHub Release](https://github.com/ArtalkJS/Artalk/releases) 手动下载最新构建 替换掉旧版本文件即可。 ::: tip -升级可能会有配置文件等变动,请注意查看版本 Changelog,通常是在 [GitHub Release](https://github.com/ArtalkJS/ArtalkGo/releases) 页面 +升级可能会有配置文件等变动,请注意查看版本 Changelog,通常是在 [GitHub Release](https://github.com/ArtalkJS/Artalk/releases) 页面 ::: diff --git a/docs/docs/guide/deploy.md b/docs/docs/guide/deploy.md index 05d8f80a4..2b64ab7c5 100644 --- a/docs/docs/guide/deploy.md +++ b/docs/docs/guide/deploy.md @@ -6,10 +6,10 @@ ```bash docker run -d \ - --name artalk-go \ + --name artalk \ -p 8080:23366 \ -v $(pwd)/data:/data \ - artalk/artalk-go + artalk/artalk ``` > 假设域名 `http://your_domain` 已正确添加 DNS 记录并指向你的服务器 IP @@ -19,7 +19,7 @@ docker run -d \ 执行命令创建管理员账户: ```bash -docker exec -it artalk-go artalk admin +docker exec -it artalk artalk admin ``` 在你的网站引入 Artalk 程序内嵌的的前端 CSS、JS 资源并初始化: @@ -54,9 +54,9 @@ new Artalk({ ## 普通方式部署 -1. 前往 [GitHub Release](https://github.com/ArtalkJS/ArtalkGo/releases) 下载程序压缩包 -2. 提取压缩包:`tar -zxvf artalk-go_版本号_系统_架构.tar.gz` -3. 运行程序 `./artalk-go server` +1. 前往 [GitHub Release](https://github.com/ArtalkJS/Artalk/releases) 下载程序压缩包 +2. 提取压缩包:`tar -zxvf artalk_版本号_系统_架构.tar.gz` +3. 运行程序 `./artalk server` 4. 前端配置 ```js @@ -72,12 +72,12 @@ new Artalk({ |文件名|操作系统|CPU 架构| |:-|:-:|:-:| -|artalk-go_linux_amd64.tar.gz|Linux|x86_64| -|artalk-go_linux_arm64.tar.gz|Linux|ARM64| -|artalk-go_linux_arm7.tar.gz|Linux|ARMv7| -|artalk-go_windows_amd64.zip|Windows|x86_64| -|artalk-go_darwin_arm64.tar.gz|macOS|Apple Silicon| -|artalk-go_darwin_amd64.tar.gz|macOS|Intel Chip <sup>~~(什么狗屎)~~</sup>| +|artalk_linux_amd64.tar.gz|Linux|x86_64| +|artalk_linux_arm64.tar.gz|Linux|ARM64| +|artalk_linux_arm7.tar.gz|Linux|ARMv7| +|artalk_windows_amd64.zip|Windows|x86_64| +|artalk_darwin_arm64.tar.gz|macOS|Apple Silicon| +|artalk_darwin_amd64.tar.gz|macOS|Intel Chip <sup>~~(什么狗屎)~~</sup>| ## Docker Compose 部署 @@ -87,8 +87,8 @@ new Artalk({ version: "3.5" services: artalk: - container_name: artalk-go - image: artalk/artalk-go + container_name: artalk + image: artalk/artalk ports: - 8080:23366 volumes: diff --git a/docs/docs/guide/intro.md b/docs/docs/guide/intro.md index 6b702d051..50e740905 100644 --- a/docs/docs/guide/intro.md +++ b/docs/docs/guide/intro.md @@ -82,7 +82,7 @@ Artalk 社区是包容开放的社区,我们欢迎不同水平的人员帮助 ::: tip 立即为社区贡献力量? - 维护 Artalk 前端(仓库地址 [@ArtalkJS/Artalk](https://github.com/ArtalkJS/Artalk)) - - 维护 Artalk 后端(仓库地址 [@ArtalkJS/ArtalkGo](https://github.com/ArtalkJS/ArtalkGo)) + - 维护 Artalk 后端(仓库地址 [@ArtalkJS/Artalk](https://github.com/ArtalkJS/Artalk)) - 完善 Artalk 文档(仓库地址 [@ArtalkJS/Docs](https://github.com/ArtalkJS/Docs)) - 改进数据迁移工具(仓库地址 [@ArtalkJS/Artransfer](https://github.com/ArtalkJS/Artransfer)) - 分享你的想法创意(下方留言 / [Discussions](https://github.com/ArtalkJS/Artalk/discussions)) diff --git a/docs/docs/guide/transfer.md b/docs/docs/guide/transfer.md index cd8690ab6..71aaffe56 100644 --- a/docs/docs/guide/transfer.md +++ b/docs/docs/guide/transfer.md @@ -17,7 +17,7 @@ Artran = Art + Ran (艺术 + 奔跑) "id": "123", "rid": "233", "content": "Hello Artalk", - "ua": "ArtalkGo/6.6", + "ua": "Artalk/6.6", "ip": "233.233.233.233", "created_at": "2021-10-28 20:50:15 +0800 +0800", "updated_at": "2021-10-28 20:50:15 +0800 +0800", @@ -62,7 +62,7 @@ Artran = Art + Ran (艺术 + 奔跑) 转换为 `.artrans` 格式的数据文件可以导入 Artalk: - **前端导入**:你可在「[控制中心](./frontend/sidebar.md#控制中心)」找到「迁移」选项卡,并根据提示导入 Artrans。 -- **命令行导入**:执行 `artalk-go import -h` 查阅帮助文档。 +- **命令行导入**:执行 `artalk import -h` 查阅帮助文档。 ## 获取源数据 @@ -160,16 +160,16 @@ typecho-20220424-202246.artrans ## 命令行导入 -执行 `artalk-go import -h` 查看帮助文档。 +执行 `artalk import -h` 查看帮助文档。 ```bash -./artalk-go import 数据类型 [参数...] +./artalk import 数据类型 [参数...] ``` 参数格式遵循 `<key>:<value>`,例如: ```bash -./artalk-go import 类型 t_name:"Site" t_url:"https://xx.com" json_file:"文件路径" +./artalk import 类型 t_name:"Site" t_url:"https://xx.com" json_file:"文件路径" ``` 前端的导入同样可以手动输入启动参数,例如: @@ -182,7 +182,7 @@ typecho-20220424-202246.artrans } ``` -ArtalkGo 导入功能的通用启动参数: +Artalk 导入功能的通用启动参数: | 参数 | 类型 | 说明 | | :------: | ------ | ------------ | @@ -197,16 +197,16 @@ ArtalkGo 导入功能的通用启动参数: ### 命令行备份 -导出:`artalk-go export ./artrans` +导出:`artalk export ./artrans` -导入:`artalk-go import ./artrans` +导入:`artalk import ./artrans` ### 高级玩法 -执行 `artalk-go export` 可直接 “标准输出”,并进行 “管道” 或 “输出重定向” 等操作,例如: +执行 `artalk export` 可直接 “标准输出”,并进行 “管道” 或 “输出重定向” 等操作,例如: ```bash -artalk-go export | gzip -9 | ssh username@remote_ip "cat > ~/backup/artrans.gz" +artalk export | gzip -9 | ssh username@remote_ip "cat > ~/backup/artrans.gz" ``` ## 写在结尾 diff --git a/go.mod b/go.mod index ca64da3bc..88f2b13eb 100644 --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -module github.com/ArtalkJS/ArtalkGo +module github.com/ArtalkJS/Artalk go 1.19 diff --git a/internal/anti_spam/anti_spam.go b/internal/anti_spam/anti_spam.go index bd0047dd1..c41cd294d 100644 --- a/internal/anti_spam/anti_spam.go +++ b/internal/anti_spam/anti_spam.go @@ -7,10 +7,10 @@ import ( "strconv" "strings" - "github.com/ArtalkJS/ArtalkGo/internal/config" - "github.com/ArtalkJS/ArtalkGo/internal/entity" - "github.com/ArtalkJS/ArtalkGo/internal/query" - "github.com/ArtalkJS/ArtalkGo/internal/utils" + "github.com/ArtalkJS/Artalk/internal/config" + "github.com/ArtalkJS/Artalk/internal/entity" + "github.com/ArtalkJS/Artalk/internal/query" + "github.com/ArtalkJS/Artalk/internal/utils" "github.com/gofiber/fiber/v2" "github.com/sirupsen/logrus" ) diff --git a/internal/anti_spam/anti_spam_akismet.go b/internal/anti_spam/anti_spam_akismet.go index 0fa03eccb..809aeac0e 100644 --- a/internal/anti_spam/anti_spam_akismet.go +++ b/internal/anti_spam/anti_spam_akismet.go @@ -9,7 +9,7 @@ import ( "reflect" "strings" - "github.com/ArtalkJS/ArtalkGo/internal/config" + "github.com/ArtalkJS/Artalk/internal/config" "github.com/sirupsen/logrus" ) diff --git a/internal/anti_spam/anti_spam_aliyun.go b/internal/anti_spam/anti_spam_aliyun.go index 9e8986a08..9ef3e39be 100644 --- a/internal/anti_spam/anti_spam_aliyun.go +++ b/internal/anti_spam/anti_spam_aliyun.go @@ -5,7 +5,7 @@ import ( "fmt" "strconv" - "github.com/ArtalkJS/ArtalkGo/internal/config" + "github.com/ArtalkJS/Artalk/internal/config" "github.com/aliyun/alibaba-cloud-sdk-go/services/green" "github.com/sirupsen/logrus" "github.com/tidwall/gjson" diff --git a/internal/anti_spam/anti_spam_tencent.go b/internal/anti_spam/anti_spam_tencent.go index 2c9d33a22..39a4a503b 100644 --- a/internal/anti_spam/anti_spam_tencent.go +++ b/internal/anti_spam/anti_spam_tencent.go @@ -5,7 +5,7 @@ import ( "errors" "fmt" - "github.com/ArtalkJS/ArtalkGo/internal/config" + "github.com/ArtalkJS/Artalk/internal/config" "github.com/sirupsen/logrus" // 腾讯啊腾讯.... 怎么这么多引入啊? diff --git a/internal/artransfer/artrans.go b/internal/artransfer/artrans.go index 2f7561be0..38a38d591 100644 --- a/internal/artransfer/artrans.go +++ b/internal/artransfer/artrans.go @@ -6,10 +6,10 @@ import ( "strconv" "time" - "github.com/ArtalkJS/ArtalkGo/internal/db" - "github.com/ArtalkJS/ArtalkGo/internal/entity" - "github.com/ArtalkJS/ArtalkGo/internal/query" - "github.com/ArtalkJS/ArtalkGo/internal/utils" + "github.com/ArtalkJS/Artalk/internal/db" + "github.com/ArtalkJS/Artalk/internal/entity" + "github.com/ArtalkJS/Artalk/internal/query" + "github.com/ArtalkJS/Artalk/internal/utils" "github.com/cheggaaa/pb/v3" ) diff --git a/internal/artransfer/exporter.go b/internal/artransfer/exporter.go index 7fe9743d3..72504bf73 100644 --- a/internal/artransfer/exporter.go +++ b/internal/artransfer/exporter.go @@ -3,9 +3,9 @@ package artransfer import ( "encoding/json" - "github.com/ArtalkJS/ArtalkGo/internal/db" - "github.com/ArtalkJS/ArtalkGo/internal/entity" - "github.com/ArtalkJS/ArtalkGo/internal/query" + "github.com/ArtalkJS/Artalk/internal/db" + "github.com/ArtalkJS/Artalk/internal/entity" + "github.com/ArtalkJS/Artalk/internal/query" "gorm.io/gorm" ) diff --git a/internal/artransfer/importer.go b/internal/artransfer/importer.go index efb29d35e..1fafe3aaf 100644 --- a/internal/artransfer/importer.go +++ b/internal/artransfer/importer.go @@ -15,10 +15,10 @@ import ( "time" "unicode/utf8" - "github.com/ArtalkJS/ArtalkGo/internal/config" - "github.com/ArtalkJS/ArtalkGo/internal/entity" - "github.com/ArtalkJS/ArtalkGo/internal/query" - "github.com/ArtalkJS/ArtalkGo/internal/utils" + "github.com/ArtalkJS/Artalk/internal/config" + "github.com/ArtalkJS/Artalk/internal/entity" + "github.com/ArtalkJS/Artalk/internal/query" + "github.com/ArtalkJS/Artalk/internal/utils" "github.com/araddon/dateparse" ) diff --git a/internal/cache/actions.go b/internal/cache/actions.go index 97864397d..c8c06f8f9 100644 --- a/internal/cache/actions.go +++ b/internal/cache/actions.go @@ -7,8 +7,8 @@ import ( "strings" "time" - "github.com/ArtalkJS/ArtalkGo/internal/config" - "github.com/ArtalkJS/ArtalkGo/internal/entity" + "github.com/ArtalkJS/Artalk/internal/config" + "github.com/ArtalkJS/Artalk/internal/entity" "github.com/eko/gocache/lib/v4/store" "github.com/sirupsen/logrus" "golang.org/x/sync/singleflight" diff --git a/internal/cache/cache.go b/internal/cache/cache.go index 43fb67d51..eaf4285c0 100644 --- a/internal/cache/cache.go +++ b/internal/cache/cache.go @@ -5,7 +5,7 @@ import ( "strings" "time" - "github.com/ArtalkJS/ArtalkGo/internal/config" + "github.com/ArtalkJS/Artalk/internal/config" "github.com/allegro/bigcache" "github.com/bradfitz/gomemcache/memcache" "github.com/eko/gocache/lib/v4/cache" diff --git a/internal/cache/db.go b/internal/cache/db.go index 5c4085582..3374ad4d2 100644 --- a/internal/cache/db.go +++ b/internal/cache/db.go @@ -1,7 +1,7 @@ package cache import ( - "github.com/ArtalkJS/ArtalkGo/internal/db" + "github.com/ArtalkJS/Artalk/internal/db" "gorm.io/gorm" ) diff --git a/internal/cache/operate.go b/internal/cache/operate.go index aac253125..3e8f13eef 100644 --- a/internal/cache/operate.go +++ b/internal/cache/operate.go @@ -4,7 +4,7 @@ import ( "fmt" "time" - "github.com/ArtalkJS/ArtalkGo/internal/entity" + "github.com/ArtalkJS/Artalk/internal/entity" "github.com/sirupsen/logrus" ) diff --git a/internal/captcha/geetest.go b/internal/captcha/geetest.go index 98d388ed1..815ec0622 100644 --- a/internal/captcha/geetest.go +++ b/internal/captcha/geetest.go @@ -11,7 +11,7 @@ import ( "net/url" "time" - "github.com/ArtalkJS/ArtalkGo/internal/config" + "github.com/ArtalkJS/Artalk/internal/config" "github.com/tidwall/gjson" ) diff --git a/internal/core/core.go b/internal/core/core.go index b64aabac4..b684432aa 100644 --- a/internal/core/core.go +++ b/internal/core/core.go @@ -5,10 +5,10 @@ import ( "os" "sync" - "github.com/ArtalkJS/ArtalkGo/internal/cache" - "github.com/ArtalkJS/ArtalkGo/internal/config" - "github.com/ArtalkJS/ArtalkGo/internal/db" - "github.com/ArtalkJS/ArtalkGo/internal/notify_launcher" + "github.com/ArtalkJS/Artalk/internal/cache" + "github.com/ArtalkJS/Artalk/internal/config" + "github.com/ArtalkJS/Artalk/internal/db" + "github.com/ArtalkJS/Artalk/internal/notify_launcher" "github.com/rifflock/lfshook" "github.com/sirupsen/logrus" diff --git a/internal/core/gen.go b/internal/core/gen.go index 4157cc471..999915af3 100644 --- a/internal/core/gen.go +++ b/internal/core/gen.go @@ -8,7 +8,7 @@ import ( "path/filepath" "strings" - "github.com/ArtalkJS/ArtalkGo/internal/pkged" + "github.com/ArtalkJS/Artalk/internal/pkged" "github.com/sirupsen/logrus" ) diff --git a/internal/core/sync.go b/internal/core/sync.go index 792411c69..728340f72 100644 --- a/internal/core/sync.go +++ b/internal/core/sync.go @@ -3,9 +3,9 @@ package core import ( "strings" - "github.com/ArtalkJS/ArtalkGo/internal/config" - "github.com/ArtalkJS/ArtalkGo/internal/entity" - "github.com/ArtalkJS/ArtalkGo/internal/query" + "github.com/ArtalkJS/Artalk/internal/config" + "github.com/ArtalkJS/Artalk/internal/entity" + "github.com/ArtalkJS/Artalk/internal/query" ) func SyncFromConf() { diff --git a/internal/db/db.go b/internal/db/db.go index 53add6ed4..e60343979 100644 --- a/internal/db/db.go +++ b/internal/db/db.go @@ -6,8 +6,8 @@ import ( "os" "path/filepath" - "github.com/ArtalkJS/ArtalkGo/internal/config" - "github.com/ArtalkJS/ArtalkGo/internal/utils" + "github.com/ArtalkJS/Artalk/internal/config" + "github.com/ArtalkJS/Artalk/internal/utils" "github.com/sirupsen/logrus" "gorm.io/driver/mysql" "gorm.io/driver/postgres" diff --git a/internal/db/migrate.go b/internal/db/migrate.go index c67e3cfb7..01bb5313e 100644 --- a/internal/db/migrate.go +++ b/internal/db/migrate.go @@ -1,6 +1,6 @@ package db -import "github.com/ArtalkJS/ArtalkGo/internal/entity" +import "github.com/ArtalkJS/Artalk/internal/entity" func MigrateModels() { // Migrate the schema diff --git a/internal/email/email.go b/internal/email/email.go index 228ae5cb7..b4eb9d7b9 100644 --- a/internal/email/email.go +++ b/internal/email/email.go @@ -3,9 +3,9 @@ package email import ( "time" - "github.com/ArtalkJS/ArtalkGo/internal/config" - "github.com/ArtalkJS/ArtalkGo/internal/entity" - "github.com/ArtalkJS/ArtalkGo/internal/query" + "github.com/ArtalkJS/Artalk/internal/config" + "github.com/ArtalkJS/Artalk/internal/entity" + "github.com/ArtalkJS/Artalk/internal/query" "github.com/sirupsen/logrus" ) diff --git a/internal/email/queue.go b/internal/email/queue.go index 3e942d433..8b6dd187f 100644 --- a/internal/email/queue.go +++ b/internal/email/queue.go @@ -1,8 +1,8 @@ package email import ( - "github.com/ArtalkJS/ArtalkGo/internal/config" - "github.com/ArtalkJS/ArtalkGo/internal/query" + "github.com/ArtalkJS/Artalk/internal/config" + "github.com/ArtalkJS/Artalk/internal/query" "github.com/sirupsen/logrus" ) diff --git a/internal/email/render.go b/internal/email/render.go index 1d26ea504..4fb06040d 100644 --- a/internal/email/render.go +++ b/internal/email/render.go @@ -10,10 +10,10 @@ import ( "regexp" "strings" - "github.com/ArtalkJS/ArtalkGo/internal/config" - "github.com/ArtalkJS/ArtalkGo/internal/entity" - "github.com/ArtalkJS/ArtalkGo/internal/query" - "github.com/ArtalkJS/ArtalkGo/internal/utils" + "github.com/ArtalkJS/Artalk/internal/config" + "github.com/ArtalkJS/Artalk/internal/entity" + "github.com/ArtalkJS/Artalk/internal/query" + "github.com/ArtalkJS/Artalk/internal/utils" ) //go:embed email_tpl/* diff --git a/internal/email/sender.go b/internal/email/sender.go index 73e303af2..c4e6aec87 100644 --- a/internal/email/sender.go +++ b/internal/email/sender.go @@ -3,8 +3,8 @@ package email import ( "bytes" - "github.com/ArtalkJS/ArtalkGo/internal/config" - "github.com/ArtalkJS/ArtalkGo/internal/entity" + "github.com/ArtalkJS/Artalk/internal/config" + "github.com/ArtalkJS/Artalk/internal/entity" "gopkg.in/gomail.v2" ) diff --git a/internal/email/sender_alidm.go b/internal/email/sender_alidm.go index e1c86588f..8f046db34 100644 --- a/internal/email/sender_alidm.go +++ b/internal/email/sender_alidm.go @@ -1,7 +1,7 @@ package email import ( - "github.com/ArtalkJS/ArtalkGo/internal/config" + "github.com/ArtalkJS/Artalk/internal/config" aliyun_email "github.com/qwqcode/go-aliyun-email" "github.com/samber/lo" "github.com/sirupsen/logrus" diff --git a/internal/email/sender_cmd.go b/internal/email/sender_cmd.go index 7d9b9194a..203688b0f 100644 --- a/internal/email/sender_cmd.go +++ b/internal/email/sender_cmd.go @@ -4,7 +4,7 @@ import ( "io" "os/exec" - "github.com/ArtalkJS/ArtalkGo/internal/config" + "github.com/ArtalkJS/Artalk/internal/config" "github.com/sirupsen/logrus" ) diff --git a/internal/email/sender_smtp.go b/internal/email/sender_smtp.go index 0b4ceb6da..6dbab7efe 100644 --- a/internal/email/sender_smtp.go +++ b/internal/email/sender_smtp.go @@ -1,7 +1,7 @@ package email import ( - "github.com/ArtalkJS/ArtalkGo/internal/config" + "github.com/ArtalkJS/Artalk/internal/config" "github.com/sirupsen/logrus" "gopkg.in/gomail.v2" ) diff --git a/internal/entity/notify.go b/internal/entity/notify.go index c410953e9..380f15372 100644 --- a/internal/entity/notify.go +++ b/internal/entity/notify.go @@ -5,7 +5,7 @@ import ( "sync" "time" - "github.com/ArtalkJS/ArtalkGo/internal/utils" + "github.com/ArtalkJS/Artalk/internal/utils" "gorm.io/gorm" ) diff --git a/internal/notify_launcher/init.go b/internal/notify_launcher/init.go index 2c07ce402..9c08e3b22 100644 --- a/internal/notify_launcher/init.go +++ b/internal/notify_launcher/init.go @@ -3,8 +3,8 @@ package notify_launcher import ( "context" - "github.com/ArtalkJS/ArtalkGo/internal/config" - "github.com/ArtalkJS/ArtalkGo/internal/email" + "github.com/ArtalkJS/Artalk/internal/config" + "github.com/ArtalkJS/Artalk/internal/email" "github.com/nikoksr/notify" "github.com/nikoksr/notify/service/dingding" "github.com/nikoksr/notify/service/line" diff --git a/internal/notify_launcher/notify_launcher.go b/internal/notify_launcher/notify_launcher.go index 0230794cb..2999c4afe 100644 --- a/internal/notify_launcher/notify_launcher.go +++ b/internal/notify_launcher/notify_launcher.go @@ -11,11 +11,11 @@ import ( "strings" "time" - "github.com/ArtalkJS/ArtalkGo/internal/config" - "github.com/ArtalkJS/ArtalkGo/internal/email" - "github.com/ArtalkJS/ArtalkGo/internal/entity" - "github.com/ArtalkJS/ArtalkGo/internal/query" - "github.com/ArtalkJS/ArtalkGo/internal/utils" + "github.com/ArtalkJS/Artalk/internal/config" + "github.com/ArtalkJS/Artalk/internal/email" + "github.com/ArtalkJS/Artalk/internal/entity" + "github.com/ArtalkJS/Artalk/internal/query" + "github.com/ArtalkJS/Artalk/internal/utils" "github.com/sirupsen/logrus" ) @@ -207,7 +207,7 @@ func SendBark(title string, msg string) { } if title == "" { - title = "ArtalkGo" + title = "Artalk" } result, err := http.Get(fmt.Sprintf("%s/%s/%s", strings.TrimSuffix(barkConf.Server, "/"), url.QueryEscape(title), url.QueryEscape(msg))) diff --git a/internal/query/association.go b/internal/query/association.go index 86ca6bbd9..109339856 100644 --- a/internal/query/association.go +++ b/internal/query/association.go @@ -1,7 +1,7 @@ package query import ( - "github.com/ArtalkJS/ArtalkGo/internal/entity" + "github.com/ArtalkJS/Artalk/internal/entity" ) // =============== diff --git a/internal/query/cook.go b/internal/query/cook.go index 89b7cd3ca..ae9a5f82b 100644 --- a/internal/query/cook.go +++ b/internal/query/cook.go @@ -1,8 +1,8 @@ package query import ( - "github.com/ArtalkJS/ArtalkGo/internal/entity" - "github.com/ArtalkJS/ArtalkGo/internal/utils" + "github.com/ArtalkJS/Artalk/internal/entity" + "github.com/ArtalkJS/Artalk/internal/utils" ) // =============== diff --git a/internal/query/db.go b/internal/query/db.go index a13f0f486..eb9920eb1 100644 --- a/internal/query/db.go +++ b/internal/query/db.go @@ -1,7 +1,7 @@ package query import ( - "github.com/ArtalkJS/ArtalkGo/internal/db" + "github.com/ArtalkJS/Artalk/internal/db" "gorm.io/gorm" ) diff --git a/internal/query/db_test.go b/internal/query/db_test.go index a65c32747..6a8939f28 100644 --- a/internal/query/db_test.go +++ b/internal/query/db_test.go @@ -8,9 +8,9 @@ import ( "gorm.io/driver/sqlite" "gorm.io/gorm" - "github.com/ArtalkJS/ArtalkGo/internal/config" - "github.com/ArtalkJS/ArtalkGo/internal/db" - "github.com/ArtalkJS/ArtalkGo/internal/utils" + "github.com/ArtalkJS/Artalk/internal/config" + "github.com/ArtalkJS/Artalk/internal/db" + "github.com/ArtalkJS/Artalk/internal/utils" "github.com/go-testfixtures/testfixtures/v3" ) diff --git a/internal/query/query.go b/internal/query/query.go index 21869fd00..111ecddf5 100644 --- a/internal/query/query.go +++ b/internal/query/query.go @@ -1,6 +1,6 @@ package query -import "github.com/ArtalkJS/ArtalkGo/internal/entity" +import "github.com/ArtalkJS/Artalk/internal/entity" func GetUserAllCommentIDs(userID uint) []uint { userAllCommentIDs := []uint{} diff --git a/internal/query/query_del.go b/internal/query/query_del.go index 58bcfb9bc..0e2fce368 100644 --- a/internal/query/query_del.go +++ b/internal/query/query_del.go @@ -1,8 +1,8 @@ package query import ( - "github.com/ArtalkJS/ArtalkGo/internal/cache" - "github.com/ArtalkJS/ArtalkGo/internal/entity" + "github.com/ArtalkJS/Artalk/internal/cache" + "github.com/ArtalkJS/Artalk/internal/entity" ) func DelComment(comment *entity.Comment) error { diff --git a/internal/query/query_find.go b/internal/query/query_find.go index 93515a2cf..236980e03 100644 --- a/internal/query/query_find.go +++ b/internal/query/query_find.go @@ -4,8 +4,8 @@ import ( "fmt" "strings" - "github.com/ArtalkJS/ArtalkGo/internal/cache" - "github.com/ArtalkJS/ArtalkGo/internal/entity" + "github.com/ArtalkJS/Artalk/internal/cache" + "github.com/ArtalkJS/Artalk/internal/entity" ) func FindComment(id uint, checkers ...func(*entity.Comment) bool) entity.Comment { diff --git a/internal/query/query_find_create.go b/internal/query/query_find_create.go index 552857ab5..6a238a7de 100644 --- a/internal/query/query_find_create.go +++ b/internal/query/query_find_create.go @@ -1,7 +1,7 @@ package query import ( - "github.com/ArtalkJS/ArtalkGo/internal/entity" + "github.com/ArtalkJS/Artalk/internal/entity" ) func FindCreateSite(siteName string) entity.Site { diff --git a/internal/query/query_new.go b/internal/query/query_new.go index e57908a8b..3d1954c91 100644 --- a/internal/query/query_new.go +++ b/internal/query/query_new.go @@ -1,8 +1,8 @@ package query import ( - "github.com/ArtalkJS/ArtalkGo/internal/cache" - "github.com/ArtalkJS/ArtalkGo/internal/entity" + "github.com/ArtalkJS/Artalk/internal/cache" + "github.com/ArtalkJS/Artalk/internal/entity" "github.com/sirupsen/logrus" ) diff --git a/internal/query/query_update.go b/internal/query/query_update.go index e1d9339f9..9913b6f11 100644 --- a/internal/query/query_update.go +++ b/internal/query/query_update.go @@ -4,8 +4,8 @@ import ( "errors" "time" - "github.com/ArtalkJS/ArtalkGo/internal/cache" - "github.com/ArtalkJS/ArtalkGo/internal/entity" + "github.com/ArtalkJS/Artalk/internal/cache" + "github.com/ArtalkJS/Artalk/internal/entity" "github.com/sirupsen/logrus" ) diff --git a/internal/query/service.go b/internal/query/service.go index 2c7ace4b2..dcf37287e 100644 --- a/internal/query/service.go +++ b/internal/query/service.go @@ -8,8 +8,8 @@ import ( "regexp" "time" - "github.com/ArtalkJS/ArtalkGo/internal/entity" - "github.com/ArtalkJS/ArtalkGo/internal/utils" + "github.com/ArtalkJS/Artalk/internal/entity" + "github.com/ArtalkJS/Artalk/internal/utils" "github.com/PuerkitoBio/goquery" "github.com/sirupsen/logrus" ) diff --git a/internal/query/service_test.go b/internal/query/service_test.go index 081ea86b6..0cdfebb3b 100644 --- a/internal/query/service_test.go +++ b/internal/query/service_test.go @@ -3,7 +3,7 @@ package query import ( "testing" - "github.com/ArtalkJS/ArtalkGo/internal/entity" + "github.com/ArtalkJS/Artalk/internal/entity" ) func Test_GetPageAccessibleURL(t *testing.T) { diff --git a/main.go b/main.go index e50733a86..c5ed4fcca 100644 --- a/main.go +++ b/main.go @@ -3,8 +3,8 @@ package main import ( "embed" - "github.com/ArtalkJS/ArtalkGo/cmd" - "github.com/ArtalkJS/ArtalkGo/internal/pkged" + "github.com/ArtalkJS/Artalk/cmd" + "github.com/ArtalkJS/Artalk/internal/pkged" ) //go:embed public/* diff --git a/public/index.html b/public/index.html index 78e890b51..05f9d29ef 100644 --- a/public/index.html +++ b/public/index.html @@ -2,11 +2,11 @@ <html> <head> <meta charset="UTF-8"> - <title>Welcome to ArtalkGo! + Welcome to Artalk!

Welcome to ArtalkGo!

For online documentation and support please refer to artalk.js.org.

-

Thank you for using ArtalkGo.

+

Thank you for using Artalk.

\ No newline at end of file diff --git a/server/common/auth.go b/server/common/auth.go index b76064b99..0590ee609 100644 --- a/server/common/auth.go +++ b/server/common/auth.go @@ -6,9 +6,9 @@ import ( "strings" "time" - "github.com/ArtalkJS/ArtalkGo/internal/config" - "github.com/ArtalkJS/ArtalkGo/internal/entity" - "github.com/ArtalkJS/ArtalkGo/internal/query" + "github.com/ArtalkJS/Artalk/internal/config" + "github.com/ArtalkJS/Artalk/internal/entity" + "github.com/ArtalkJS/Artalk/internal/query" "github.com/gofiber/fiber/v2" "github.com/golang-jwt/jwt" ) diff --git a/server/common/captcha.go b/server/common/captcha.go index 595237381..6645085bc 100644 --- a/server/common/captcha.go +++ b/server/common/captcha.go @@ -9,8 +9,8 @@ import ( "strings" "time" - "github.com/ArtalkJS/ArtalkGo/internal/cache" - "github.com/ArtalkJS/ArtalkGo/internal/config" + "github.com/ArtalkJS/Artalk/internal/cache" + "github.com/ArtalkJS/Artalk/internal/config" "github.com/eko/gocache/lib/v4/store" "github.com/gofiber/fiber/v2" imgCaptcha "github.com/steambap/captcha" diff --git a/server/common/check.go b/server/common/check.go index 64efe23c7..32544cafd 100644 --- a/server/common/check.go +++ b/server/common/check.go @@ -1,9 +1,9 @@ package common import ( - "github.com/ArtalkJS/ArtalkGo/internal/entity" - "github.com/ArtalkJS/ArtalkGo/internal/query" - "github.com/ArtalkJS/ArtalkGo/internal/utils" + "github.com/ArtalkJS/Artalk/internal/entity" + "github.com/ArtalkJS/Artalk/internal/query" + "github.com/ArtalkJS/Artalk/internal/utils" "github.com/gofiber/fiber/v2" ) diff --git a/server/common/conf.go b/server/common/conf.go index 15a0a10fd..92553209f 100644 --- a/server/common/conf.go +++ b/server/common/conf.go @@ -3,8 +3,8 @@ package common import ( "strings" - "github.com/ArtalkJS/ArtalkGo/internal/config" - "github.com/ArtalkJS/ArtalkGo/internal/utils" + "github.com/ArtalkJS/Artalk/internal/config" + "github.com/ArtalkJS/Artalk/internal/utils" "github.com/gofiber/fiber/v2" ) diff --git a/server/common/cors.go b/server/common/cors.go index bdfc95669..9e253c4ab 100644 --- a/server/common/cors.go +++ b/server/common/cors.go @@ -5,10 +5,10 @@ import ( "net/url" "strings" - "github.com/ArtalkJS/ArtalkGo/internal/config" - "github.com/ArtalkJS/ArtalkGo/internal/query" - "github.com/ArtalkJS/ArtalkGo/internal/utils" - "github.com/ArtalkJS/ArtalkGo/server/middleware/cors" + "github.com/ArtalkJS/Artalk/internal/config" + "github.com/ArtalkJS/Artalk/internal/query" + "github.com/ArtalkJS/Artalk/internal/utils" + "github.com/ArtalkJS/Artalk/server/middleware/cors" ) var CorsConf = &cors.Config{ diff --git a/server/common/site.go b/server/common/site.go index b01226a86..1706702ca 100644 --- a/server/common/site.go +++ b/server/common/site.go @@ -1,7 +1,7 @@ package common import ( - "github.com/ArtalkJS/ArtalkGo/internal/config" + "github.com/ArtalkJS/Artalk/internal/config" "github.com/gofiber/fiber/v2" ) diff --git a/server/handler/admin_cache.go b/server/handler/admin_cache.go index dc9d81806..0ec9ae4ed 100644 --- a/server/handler/admin_cache.go +++ b/server/handler/admin_cache.go @@ -1,8 +1,8 @@ package handler import ( - "github.com/ArtalkJS/ArtalkGo/internal/cache" - "github.com/ArtalkJS/ArtalkGo/server/common" + "github.com/ArtalkJS/Artalk/internal/cache" + "github.com/ArtalkJS/Artalk/server/common" "github.com/gofiber/fiber/v2" ) diff --git a/server/handler/admin_comment_del.go b/server/handler/admin_comment_del.go index 4e3c4d981..68cd24b7f 100644 --- a/server/handler/admin_comment_del.go +++ b/server/handler/admin_comment_del.go @@ -1,8 +1,8 @@ package handler import ( - "github.com/ArtalkJS/ArtalkGo/internal/query" - "github.com/ArtalkJS/ArtalkGo/server/common" + "github.com/ArtalkJS/Artalk/internal/query" + "github.com/ArtalkJS/Artalk/server/common" "github.com/gofiber/fiber/v2" ) diff --git a/server/handler/admin_comment_edit.go b/server/handler/admin_comment_edit.go index cab2df366..3cc3180fd 100644 --- a/server/handler/admin_comment_edit.go +++ b/server/handler/admin_comment_edit.go @@ -3,11 +3,11 @@ package handler import ( "strconv" - "github.com/ArtalkJS/ArtalkGo/internal/email" - "github.com/ArtalkJS/ArtalkGo/internal/entity" - "github.com/ArtalkJS/ArtalkGo/internal/query" - "github.com/ArtalkJS/ArtalkGo/internal/utils" - "github.com/ArtalkJS/ArtalkGo/server/common" + "github.com/ArtalkJS/Artalk/internal/email" + "github.com/ArtalkJS/Artalk/internal/entity" + "github.com/ArtalkJS/Artalk/internal/query" + "github.com/ArtalkJS/Artalk/internal/utils" + "github.com/ArtalkJS/Artalk/server/common" "github.com/gofiber/fiber/v2" ) diff --git a/server/handler/admin_page_del.go b/server/handler/admin_page_del.go index 4e130cb10..049b4b8fd 100644 --- a/server/handler/admin_page_del.go +++ b/server/handler/admin_page_del.go @@ -1,8 +1,8 @@ package handler import ( - "github.com/ArtalkJS/ArtalkGo/internal/query" - "github.com/ArtalkJS/ArtalkGo/server/common" + "github.com/ArtalkJS/Artalk/internal/query" + "github.com/ArtalkJS/Artalk/server/common" "github.com/gofiber/fiber/v2" ) diff --git a/server/handler/admin_page_edit.go b/server/handler/admin_page_edit.go index 535ca4ff4..ff77d9d9b 100644 --- a/server/handler/admin_page_edit.go +++ b/server/handler/admin_page_edit.go @@ -3,11 +3,11 @@ package handler import ( "strings" - "github.com/ArtalkJS/ArtalkGo/internal/cache" - "github.com/ArtalkJS/ArtalkGo/internal/db" - "github.com/ArtalkJS/ArtalkGo/internal/entity" - "github.com/ArtalkJS/ArtalkGo/internal/query" - "github.com/ArtalkJS/ArtalkGo/server/common" + "github.com/ArtalkJS/Artalk/internal/cache" + "github.com/ArtalkJS/Artalk/internal/db" + "github.com/ArtalkJS/Artalk/internal/entity" + "github.com/ArtalkJS/Artalk/internal/query" + "github.com/ArtalkJS/Artalk/server/common" "github.com/gofiber/fiber/v2" ) diff --git a/server/handler/admin_page_fetch.go b/server/handler/admin_page_fetch.go index 36d6793f2..f25e8c387 100644 --- a/server/handler/admin_page_fetch.go +++ b/server/handler/admin_page_fetch.go @@ -3,11 +3,11 @@ package handler import ( "fmt" - "github.com/ArtalkJS/ArtalkGo/internal/config" - "github.com/ArtalkJS/ArtalkGo/internal/db" - "github.com/ArtalkJS/ArtalkGo/internal/entity" - "github.com/ArtalkJS/ArtalkGo/internal/query" - "github.com/ArtalkJS/ArtalkGo/server/common" + "github.com/ArtalkJS/Artalk/internal/config" + "github.com/ArtalkJS/Artalk/internal/db" + "github.com/ArtalkJS/Artalk/internal/entity" + "github.com/ArtalkJS/Artalk/internal/query" + "github.com/ArtalkJS/Artalk/server/common" "github.com/gofiber/fiber/v2" "github.com/sirupsen/logrus" ) diff --git a/server/handler/admin_page_get.go b/server/handler/admin_page_get.go index 204855bb2..0cd800461 100644 --- a/server/handler/admin_page_get.go +++ b/server/handler/admin_page_get.go @@ -1,10 +1,10 @@ package handler import ( - "github.com/ArtalkJS/ArtalkGo/internal/db" - "github.com/ArtalkJS/ArtalkGo/internal/entity" - "github.com/ArtalkJS/ArtalkGo/internal/query" - "github.com/ArtalkJS/ArtalkGo/server/common" + "github.com/ArtalkJS/Artalk/internal/db" + "github.com/ArtalkJS/Artalk/internal/entity" + "github.com/ArtalkJS/Artalk/internal/query" + "github.com/ArtalkJS/Artalk/server/common" "github.com/gofiber/fiber/v2" ) diff --git a/server/handler/admin_send_mail.go b/server/handler/admin_send_mail.go index 4fcf22e99..2f241fed5 100644 --- a/server/handler/admin_send_mail.go +++ b/server/handler/admin_send_mail.go @@ -1,8 +1,8 @@ package handler import ( - "github.com/ArtalkJS/ArtalkGo/internal/email" - "github.com/ArtalkJS/ArtalkGo/server/common" + "github.com/ArtalkJS/Artalk/internal/email" + "github.com/ArtalkJS/Artalk/server/common" "github.com/gofiber/fiber/v2" ) diff --git a/server/handler/admin_setting.go b/server/handler/admin_setting.go index 348e9693f..b6b76f20c 100644 --- a/server/handler/admin_setting.go +++ b/server/handler/admin_setting.go @@ -3,9 +3,9 @@ package handler import ( "os" - "github.com/ArtalkJS/ArtalkGo/internal/config" - "github.com/ArtalkJS/ArtalkGo/internal/core" - "github.com/ArtalkJS/ArtalkGo/server/common" + "github.com/ArtalkJS/Artalk/internal/config" + "github.com/ArtalkJS/Artalk/internal/core" + "github.com/ArtalkJS/Artalk/server/common" "github.com/gofiber/fiber/v2" "github.com/sirupsen/logrus" ) diff --git a/server/handler/admin_site_add.go b/server/handler/admin_site_add.go index 2f85c36ab..27f9dd8c8 100644 --- a/server/handler/admin_site_add.go +++ b/server/handler/admin_site_add.go @@ -1,11 +1,11 @@ package handler import ( - "github.com/ArtalkJS/ArtalkGo/internal/config" - "github.com/ArtalkJS/ArtalkGo/internal/entity" - "github.com/ArtalkJS/ArtalkGo/internal/query" - "github.com/ArtalkJS/ArtalkGo/internal/utils" - "github.com/ArtalkJS/ArtalkGo/server/common" + "github.com/ArtalkJS/Artalk/internal/config" + "github.com/ArtalkJS/Artalk/internal/entity" + "github.com/ArtalkJS/Artalk/internal/query" + "github.com/ArtalkJS/Artalk/internal/utils" + "github.com/ArtalkJS/Artalk/server/common" "github.com/gofiber/fiber/v2" ) diff --git a/server/handler/admin_site_del.go b/server/handler/admin_site_del.go index efebb97be..b0dbd5d90 100644 --- a/server/handler/admin_site_del.go +++ b/server/handler/admin_site_del.go @@ -1,8 +1,8 @@ package handler import ( - "github.com/ArtalkJS/ArtalkGo/internal/query" - "github.com/ArtalkJS/ArtalkGo/server/common" + "github.com/ArtalkJS/Artalk/internal/query" + "github.com/ArtalkJS/Artalk/server/common" "github.com/gofiber/fiber/v2" ) diff --git a/server/handler/admin_site_edit.go b/server/handler/admin_site_edit.go index bbef6e5c6..bec4ef595 100644 --- a/server/handler/admin_site_edit.go +++ b/server/handler/admin_site_edit.go @@ -3,12 +3,12 @@ package handler import ( "strings" - "github.com/ArtalkJS/ArtalkGo/internal/cache" - "github.com/ArtalkJS/ArtalkGo/internal/db" - "github.com/ArtalkJS/ArtalkGo/internal/entity" - "github.com/ArtalkJS/ArtalkGo/internal/query" - "github.com/ArtalkJS/ArtalkGo/internal/utils" - "github.com/ArtalkJS/ArtalkGo/server/common" + "github.com/ArtalkJS/Artalk/internal/cache" + "github.com/ArtalkJS/Artalk/internal/db" + "github.com/ArtalkJS/Artalk/internal/entity" + "github.com/ArtalkJS/Artalk/internal/query" + "github.com/ArtalkJS/Artalk/internal/utils" + "github.com/ArtalkJS/Artalk/server/common" "github.com/gofiber/fiber/v2" ) diff --git a/server/handler/admin_site_get.go b/server/handler/admin_site_get.go index 7fa965be1..dc0c7ba7f 100644 --- a/server/handler/admin_site_get.go +++ b/server/handler/admin_site_get.go @@ -1,10 +1,10 @@ package handler import ( - "github.com/ArtalkJS/ArtalkGo/internal/entity" - "github.com/ArtalkJS/ArtalkGo/internal/query" - "github.com/ArtalkJS/ArtalkGo/internal/utils" - "github.com/ArtalkJS/ArtalkGo/server/common" + "github.com/ArtalkJS/Artalk/internal/entity" + "github.com/ArtalkJS/Artalk/internal/query" + "github.com/ArtalkJS/Artalk/internal/utils" + "github.com/ArtalkJS/Artalk/server/common" "github.com/gofiber/fiber/v2" ) diff --git a/server/handler/admin_transfer.go b/server/handler/admin_transfer.go index 946d0a880..722978220 100644 --- a/server/handler/admin_transfer.go +++ b/server/handler/admin_transfer.go @@ -6,10 +6,10 @@ import ( "io" "os" - "github.com/ArtalkJS/ArtalkGo/internal/artransfer" - "github.com/ArtalkJS/ArtalkGo/internal/query" - "github.com/ArtalkJS/ArtalkGo/internal/utils" - "github.com/ArtalkJS/ArtalkGo/server/common" + "github.com/ArtalkJS/Artalk/internal/artransfer" + "github.com/ArtalkJS/Artalk/internal/query" + "github.com/ArtalkJS/Artalk/internal/utils" + "github.com/ArtalkJS/Artalk/server/common" "github.com/gofiber/fiber/v2" "github.com/sirupsen/logrus" "gorm.io/gorm" diff --git a/server/handler/admin_user_add.go b/server/handler/admin_user_add.go index f029e9762..e64b122ee 100644 --- a/server/handler/admin_user_add.go +++ b/server/handler/admin_user_add.go @@ -1,10 +1,10 @@ package handler import ( - "github.com/ArtalkJS/ArtalkGo/internal/entity" - "github.com/ArtalkJS/ArtalkGo/internal/query" - "github.com/ArtalkJS/ArtalkGo/internal/utils" - "github.com/ArtalkJS/ArtalkGo/server/common" + "github.com/ArtalkJS/Artalk/internal/entity" + "github.com/ArtalkJS/Artalk/internal/query" + "github.com/ArtalkJS/Artalk/internal/utils" + "github.com/ArtalkJS/Artalk/server/common" "github.com/gofiber/fiber/v2" "github.com/sirupsen/logrus" ) diff --git a/server/handler/admin_user_del.go b/server/handler/admin_user_del.go index 1e9dd62ea..6fb202773 100644 --- a/server/handler/admin_user_del.go +++ b/server/handler/admin_user_del.go @@ -1,8 +1,8 @@ package handler import ( - "github.com/ArtalkJS/ArtalkGo/internal/query" - "github.com/ArtalkJS/ArtalkGo/server/common" + "github.com/ArtalkJS/Artalk/internal/query" + "github.com/ArtalkJS/Artalk/server/common" "github.com/gofiber/fiber/v2" ) diff --git a/server/handler/admin_user_edit.go b/server/handler/admin_user_edit.go index d3afe23ea..44a2bd89c 100644 --- a/server/handler/admin_user_edit.go +++ b/server/handler/admin_user_edit.go @@ -1,10 +1,10 @@ package handler import ( - "github.com/ArtalkJS/ArtalkGo/internal/cache" - "github.com/ArtalkJS/ArtalkGo/internal/query" - "github.com/ArtalkJS/ArtalkGo/internal/utils" - "github.com/ArtalkJS/ArtalkGo/server/common" + "github.com/ArtalkJS/Artalk/internal/cache" + "github.com/ArtalkJS/Artalk/internal/query" + "github.com/ArtalkJS/Artalk/internal/utils" + "github.com/ArtalkJS/Artalk/server/common" "github.com/gofiber/fiber/v2" ) diff --git a/server/handler/admin_user_get.go b/server/handler/admin_user_get.go index 5467e19c4..6a292c174 100644 --- a/server/handler/admin_user_get.go +++ b/server/handler/admin_user_get.go @@ -1,10 +1,10 @@ package handler import ( - "github.com/ArtalkJS/ArtalkGo/internal/db" - "github.com/ArtalkJS/ArtalkGo/internal/entity" - "github.com/ArtalkJS/ArtalkGo/internal/query" - "github.com/ArtalkJS/ArtalkGo/server/common" + "github.com/ArtalkJS/Artalk/internal/db" + "github.com/ArtalkJS/Artalk/internal/entity" + "github.com/ArtalkJS/Artalk/internal/query" + "github.com/ArtalkJS/Artalk/server/common" "github.com/gofiber/fiber/v2" ) diff --git a/server/handler/admin_vote_sync.go b/server/handler/admin_vote_sync.go index bbf144fd6..43eae10b4 100644 --- a/server/handler/admin_vote_sync.go +++ b/server/handler/admin_vote_sync.go @@ -1,8 +1,8 @@ package handler import ( - "github.com/ArtalkJS/ArtalkGo/internal/query" - "github.com/ArtalkJS/ArtalkGo/server/common" + "github.com/ArtalkJS/Artalk/internal/query" + "github.com/ArtalkJS/Artalk/server/common" "github.com/gofiber/fiber/v2" ) diff --git a/server/handler/captcha.go b/server/handler/captcha.go index 52bec83ef..536e74c02 100644 --- a/server/handler/captcha.go +++ b/server/handler/captcha.go @@ -6,9 +6,9 @@ import ( "strings" "text/template" - "github.com/ArtalkJS/ArtalkGo/internal/captcha" - "github.com/ArtalkJS/ArtalkGo/internal/config" - "github.com/ArtalkJS/ArtalkGo/server/common" + "github.com/ArtalkJS/Artalk/internal/captcha" + "github.com/ArtalkJS/Artalk/internal/config" + "github.com/ArtalkJS/Artalk/server/common" "github.com/gofiber/fiber/v2" "github.com/sirupsen/logrus" ) diff --git a/server/handler/comment_add.go b/server/handler/comment_add.go index d6b9fe7d4..d2ce6f086 100644 --- a/server/handler/comment_add.go +++ b/server/handler/comment_add.go @@ -3,13 +3,13 @@ package handler import ( "strings" - "github.com/ArtalkJS/ArtalkGo/internal/anti_spam" - "github.com/ArtalkJS/ArtalkGo/internal/config" - "github.com/ArtalkJS/ArtalkGo/internal/entity" - "github.com/ArtalkJS/ArtalkGo/internal/notify_launcher" - "github.com/ArtalkJS/ArtalkGo/internal/query" - "github.com/ArtalkJS/ArtalkGo/internal/utils" - "github.com/ArtalkJS/ArtalkGo/server/common" + "github.com/ArtalkJS/Artalk/internal/anti_spam" + "github.com/ArtalkJS/Artalk/internal/config" + "github.com/ArtalkJS/Artalk/internal/entity" + "github.com/ArtalkJS/Artalk/internal/notify_launcher" + "github.com/ArtalkJS/Artalk/internal/query" + "github.com/ArtalkJS/Artalk/internal/utils" + "github.com/ArtalkJS/Artalk/server/common" "github.com/gofiber/fiber/v2" "github.com/sirupsen/logrus" ) diff --git a/server/handler/comment_get.go b/server/handler/comment_get.go index 0d698b899..d66d9d085 100644 --- a/server/handler/comment_get.go +++ b/server/handler/comment_get.go @@ -1,9 +1,9 @@ package handler import ( - "github.com/ArtalkJS/ArtalkGo/internal/entity" - "github.com/ArtalkJS/ArtalkGo/internal/query" - "github.com/ArtalkJS/ArtalkGo/server/common" + "github.com/ArtalkJS/Artalk/internal/entity" + "github.com/ArtalkJS/Artalk/internal/query" + "github.com/ArtalkJS/Artalk/server/common" "github.com/gofiber/fiber/v2" "gorm.io/gorm" ) diff --git a/server/handler/comment_get_query.go b/server/handler/comment_get_query.go index fdc315bb5..53a2835b8 100644 --- a/server/handler/comment_get_query.go +++ b/server/handler/comment_get_query.go @@ -6,11 +6,11 @@ import ( "strconv" "strings" - "github.com/ArtalkJS/ArtalkGo/internal/config" - "github.com/ArtalkJS/ArtalkGo/internal/db" - "github.com/ArtalkJS/ArtalkGo/internal/entity" - "github.com/ArtalkJS/ArtalkGo/internal/query" - "github.com/ArtalkJS/ArtalkGo/server/common" + "github.com/ArtalkJS/Artalk/internal/config" + "github.com/ArtalkJS/Artalk/internal/db" + "github.com/ArtalkJS/Artalk/internal/entity" + "github.com/ArtalkJS/Artalk/internal/query" + "github.com/ArtalkJS/Artalk/server/common" "github.com/gofiber/fiber/v2" "gorm.io/gorm" ) diff --git a/server/handler/conf.go b/server/handler/conf.go index 10be6ad7d..117e89cd3 100644 --- a/server/handler/conf.go +++ b/server/handler/conf.go @@ -1,7 +1,7 @@ package handler import ( - "github.com/ArtalkJS/ArtalkGo/server/common" + "github.com/ArtalkJS/Artalk/server/common" "github.com/gofiber/fiber/v2" ) diff --git a/server/handler/img_upload.go b/server/handler/img_upload.go index 7e0b14dfa..2b000e398 100644 --- a/server/handler/img_upload.go +++ b/server/handler/img_upload.go @@ -11,9 +11,9 @@ import ( "syscall" "time" - "github.com/ArtalkJS/ArtalkGo/internal/config" - "github.com/ArtalkJS/ArtalkGo/internal/utils" - "github.com/ArtalkJS/ArtalkGo/server/common" + "github.com/ArtalkJS/Artalk/internal/config" + "github.com/ArtalkJS/Artalk/internal/utils" + "github.com/ArtalkJS/Artalk/server/common" "github.com/gofiber/fiber/v2" "github.com/sirupsen/logrus" ) diff --git a/server/handler/mark_read.go b/server/handler/mark_read.go index 231b9ae4b..81e273bf7 100644 --- a/server/handler/mark_read.go +++ b/server/handler/mark_read.go @@ -1,8 +1,8 @@ package handler import ( - "github.com/ArtalkJS/ArtalkGo/internal/query" - "github.com/ArtalkJS/ArtalkGo/server/common" + "github.com/ArtalkJS/Artalk/internal/query" + "github.com/ArtalkJS/Artalk/server/common" "github.com/gofiber/fiber/v2" ) diff --git a/server/handler/pv.go b/server/handler/pv.go index 8973192b6..612e0dc71 100644 --- a/server/handler/pv.go +++ b/server/handler/pv.go @@ -1,8 +1,8 @@ package handler import ( - "github.com/ArtalkJS/ArtalkGo/internal/query" - "github.com/ArtalkJS/ArtalkGo/server/common" + "github.com/ArtalkJS/Artalk/internal/query" + "github.com/ArtalkJS/Artalk/server/common" "github.com/gofiber/fiber/v2" ) diff --git a/server/handler/stat.go b/server/handler/stat.go index 1e50e543e..c6f13560b 100644 --- a/server/handler/stat.go +++ b/server/handler/stat.go @@ -1,12 +1,12 @@ package handler import ( - "github.com/ArtalkJS/ArtalkGo/internal/config" - "github.com/ArtalkJS/ArtalkGo/internal/db" - "github.com/ArtalkJS/ArtalkGo/internal/entity" - "github.com/ArtalkJS/ArtalkGo/internal/query" - "github.com/ArtalkJS/ArtalkGo/internal/utils" - "github.com/ArtalkJS/ArtalkGo/server/common" + "github.com/ArtalkJS/Artalk/internal/config" + "github.com/ArtalkJS/Artalk/internal/db" + "github.com/ArtalkJS/Artalk/internal/entity" + "github.com/ArtalkJS/Artalk/internal/query" + "github.com/ArtalkJS/Artalk/internal/utils" + "github.com/ArtalkJS/Artalk/server/common" "github.com/gofiber/fiber/v2" "gorm.io/gorm" ) diff --git a/server/handler/user_get.go b/server/handler/user_get.go index a12ef5253..49d8dce15 100644 --- a/server/handler/user_get.go +++ b/server/handler/user_get.go @@ -1,8 +1,8 @@ package handler import ( - "github.com/ArtalkJS/ArtalkGo/internal/query" - "github.com/ArtalkJS/ArtalkGo/server/common" + "github.com/ArtalkJS/Artalk/internal/query" + "github.com/ArtalkJS/Artalk/server/common" "github.com/gofiber/fiber/v2" ) diff --git a/server/handler/user_login.go b/server/handler/user_login.go index 4d6560f10..3259ecf34 100644 --- a/server/handler/user_login.go +++ b/server/handler/user_login.go @@ -6,11 +6,11 @@ import ( "strings" "time" - "github.com/ArtalkJS/ArtalkGo/internal/config" - "github.com/ArtalkJS/ArtalkGo/internal/entity" - "github.com/ArtalkJS/ArtalkGo/internal/query" - "github.com/ArtalkJS/ArtalkGo/internal/utils" - "github.com/ArtalkJS/ArtalkGo/server/common" + "github.com/ArtalkJS/Artalk/internal/config" + "github.com/ArtalkJS/Artalk/internal/entity" + "github.com/ArtalkJS/Artalk/internal/query" + "github.com/ArtalkJS/Artalk/internal/utils" + "github.com/ArtalkJS/Artalk/server/common" "github.com/gofiber/fiber/v2" "golang.org/x/crypto/bcrypt" ) diff --git a/server/handler/user_logout.go b/server/handler/user_logout.go index 9411c9137..6a0979eab 100644 --- a/server/handler/user_logout.go +++ b/server/handler/user_logout.go @@ -3,8 +3,8 @@ package handler import ( "time" - "github.com/ArtalkJS/ArtalkGo/internal/config" - "github.com/ArtalkJS/ArtalkGo/server/common" + "github.com/ArtalkJS/Artalk/internal/config" + "github.com/ArtalkJS/Artalk/server/common" "github.com/gofiber/fiber/v2" ) diff --git a/server/handler/version.go b/server/handler/version.go index 4fa75d297..cecfdcb43 100644 --- a/server/handler/version.go +++ b/server/handler/version.go @@ -1,7 +1,7 @@ package handler import ( - "github.com/ArtalkJS/ArtalkGo/server/common" + "github.com/ArtalkJS/Artalk/server/common" "github.com/gofiber/fiber/v2" ) diff --git a/server/handler/vote.go b/server/handler/vote.go index 4802022a4..3709ab9e4 100644 --- a/server/handler/vote.go +++ b/server/handler/vote.go @@ -3,10 +3,10 @@ package handler import ( "strings" - "github.com/ArtalkJS/ArtalkGo/internal/db" - "github.com/ArtalkJS/ArtalkGo/internal/entity" - "github.com/ArtalkJS/ArtalkGo/internal/query" - "github.com/ArtalkJS/ArtalkGo/server/common" + "github.com/ArtalkJS/Artalk/internal/db" + "github.com/ArtalkJS/Artalk/internal/entity" + "github.com/ArtalkJS/Artalk/internal/query" + "github.com/ArtalkJS/Artalk/server/common" "github.com/gofiber/fiber/v2" ) diff --git a/server/middleware/admin.go b/server/middleware/admin.go index 38f3ea769..ca90d127b 100644 --- a/server/middleware/admin.go +++ b/server/middleware/admin.go @@ -1,7 +1,7 @@ package middleware import ( - "github.com/ArtalkJS/ArtalkGo/server/common" + "github.com/ArtalkJS/Artalk/server/common" "github.com/gofiber/fiber/v2" ) diff --git a/server/middleware/cors.go b/server/middleware/cors.go index 781abb7eb..e4a8ff6e1 100644 --- a/server/middleware/cors.go +++ b/server/middleware/cors.go @@ -1,8 +1,8 @@ package middleware import ( - "github.com/ArtalkJS/ArtalkGo/server/common" - "github.com/ArtalkJS/ArtalkGo/server/middleware/cors" + "github.com/ArtalkJS/Artalk/server/common" + "github.com/ArtalkJS/Artalk/server/middleware/cors" "github.com/gofiber/fiber/v2" ) diff --git a/server/middleware/limit.go b/server/middleware/limit.go index 9593c9ba0..7e90c0e37 100644 --- a/server/middleware/limit.go +++ b/server/middleware/limit.go @@ -3,8 +3,8 @@ package middleware import ( "path" - "github.com/ArtalkJS/ArtalkGo/internal/config" - "github.com/ArtalkJS/ArtalkGo/server/common" + "github.com/ArtalkJS/Artalk/internal/config" + "github.com/ArtalkJS/Artalk/server/common" "github.com/gofiber/fiber/v2" ) diff --git a/server/middleware/site_origin.go b/server/middleware/site_origin.go index bae08bed1..83f3ee2a4 100644 --- a/server/middleware/site_origin.go +++ b/server/middleware/site_origin.go @@ -6,11 +6,11 @@ import ( "path" "strings" - "github.com/ArtalkJS/ArtalkGo/internal/config" - "github.com/ArtalkJS/ArtalkGo/internal/entity" - "github.com/ArtalkJS/ArtalkGo/internal/query" - "github.com/ArtalkJS/ArtalkGo/internal/utils" - "github.com/ArtalkJS/ArtalkGo/server/common" + "github.com/ArtalkJS/Artalk/internal/config" + "github.com/ArtalkJS/Artalk/internal/entity" + "github.com/ArtalkJS/Artalk/internal/query" + "github.com/ArtalkJS/Artalk/internal/utils" + "github.com/ArtalkJS/Artalk/server/common" "github.com/gofiber/fiber/v2" ) diff --git a/server/server.go b/server/server.go index a5ddc4b3f..1af93b6c1 100644 --- a/server/server.go +++ b/server/server.go @@ -3,11 +3,11 @@ package server import ( "net/http" - "github.com/ArtalkJS/ArtalkGo/internal/config" - "github.com/ArtalkJS/ArtalkGo/internal/pkged" - "github.com/ArtalkJS/ArtalkGo/server/common" - h "github.com/ArtalkJS/ArtalkGo/server/handler" - "github.com/ArtalkJS/ArtalkGo/server/middleware" + "github.com/ArtalkJS/Artalk/internal/config" + "github.com/ArtalkJS/Artalk/internal/pkged" + "github.com/ArtalkJS/Artalk/server/common" + h "github.com/ArtalkJS/Artalk/server/handler" + "github.com/ArtalkJS/Artalk/server/middleware" "github.com/gofiber/fiber/v2" "github.com/gofiber/fiber/v2/middleware/filesystem" "github.com/gofiber/fiber/v2/middleware/pprof" diff --git a/ui/packages/artalk-sidebar/scripts/fetch-conf-tpl.js b/ui/packages/artalk-sidebar/scripts/fetch-conf-tpl.js index a76979471..029c0395d 100644 --- a/ui/packages/artalk-sidebar/scripts/fetch-conf-tpl.js +++ b/ui/packages/artalk-sidebar/scripts/fetch-conf-tpl.js @@ -7,20 +7,20 @@ const __filename = fileURLToPath(import.meta.url) const __dirname = path.dirname(__filename) fs.copyFile(path.join(__dirname, '../../../../artalk.example.yml'), path.join(__dirname, '../src/assets/artalk.example.yml'), (err) => { - if (!err) console.log("\nArtalkGo config file 'artalk.example.yml' loaded.\n") + if (!err) console.log("\nArtalk config file 'artalk.example.yml' loaded.\n") else console.error("Failed to load config file 'artalk.example.yml':\n\n", err, "\n"); }) // const file = fs.createWriteStream() // https.get( -// 'https://raw.githubusercontent.com/ArtalkJS/ArtalkGo/master/artalk.example.yml', +// 'https://raw.githubusercontent.com/ArtalkJS/Artalk/master/artalk.example.yml', // (resp) => { // resp.pipe(file) // file.on('finish', () => { // file.close() -// console.log("\nArtalkGo 'artalk.example.yml' file download completed.\n") +// console.log("\nArtalk 'artalk.example.yml' file download completed.\n") // }) // } // ).on('error', (e) => { diff --git a/ui/packages/artalk-sidebar/src/pages/login.vue b/ui/packages/artalk-sidebar/src/pages/login.vue index adb582878..a1c6cbd09 100644 --- a/ui/packages/artalk-sidebar/src/pages/login.vue +++ b/ui/packages/artalk-sidebar/src/pages/login.vue @@ -68,7 +68,7 @@ function login(username?: string) {
diff --git a/ui/packages/artalk/src/editor/plugs/upload-plug.ts b/ui/packages/artalk/src/editor/plugs/upload-plug.ts index ac7dae69d..2a851cec3 100644 --- a/ui/packages/artalk/src/editor/plugs/upload-plug.ts +++ b/ui/packages/artalk/src/editor/plugs/upload-plug.ts @@ -98,7 +98,7 @@ export default class UploadPlug extends EditorPlug { let resp: any try { if (!this.ctx.conf.imgUploader) { - // 使用 ArtalkGo 进行图片上传 + // 使用 Artalk 进行图片上传 resp = await this.ctx.getApi().upload.imgUpload(file) } else { // 使用自定义的图片上传器 From 9441131f076fbb6716e1e13a6e2087a6e18c8aaa Mon Sep 17 00:00:00 2001 From: pluveto Date: Tue, 17 Jan 2023 07:34:02 +0000 Subject: [PATCH 329/349] chore: example file in English --- artalk.example.yml | 260 ++++++++++++++--------------- artalk.example_simple.yml | 155 +++++++++++++++++ artalk.example_zh-CN copy.yml | 301 ++++++++++++++++++++++++++++++++++ 3 files changed, 575 insertions(+), 141 deletions(-) create mode 100644 artalk.example_simple.yml create mode 100644 artalk.example_zh-CN copy.yml diff --git a/artalk.example.yml b/artalk.example.yml index ddd0e5e89..cf574e838 100644 --- a/artalk.example.yml +++ b/artalk.example.yml @@ -1,208 +1,192 @@ -# 服务器地址 +# Listen host host: "0.0.0.0" - -# 服务器端口 +# Listen port port: 23366 - -# 加密密钥 +# Key for generation of JWT token app_key: "" - -# 调试模式 +# Debug mode debug: false - -# 时间区域 +# Timezone. See https://en.wikipedia.org/wiki/List_of_tz_database_time_zones timezone: "Asia/Shanghai" - -# 默认站点名 -site_default: "默认站点" - -# 登陆有效时长 (单位:秒) +# Default site name +site_default: "Default Site" +# Login timeout (in seconds) login_timeout: 259200 - -# 数据库 +# Database db: - # 数据库类型 ["sqlite", "mysql", "pgsql", "mssql"] + # Database type ["sqlite", "mysql", "pgsql", "mssql"] type: "sqlite" - # 数据库文件 (仅 SQLite 数据库需填写) + # Database file (only for SQLite) file: "./data/artalk.db" - # 数据库名称 + # Table prefix (e.g. "atk_") + table_prefix: "" + # The following is not nessary for SQLite + # Database name name: "artalk" - # 数据库地址 + # Host address host: "localhost" - # 数据库端口 + # Host port port: 3306 - # 数据库账户 + # Database user user: "root" - # 数据库密码 + # Database password password: "" - # 编码格式 + # Database charset charset: "utf8mb4" - # 表前缀 (例如:"atk_") - table_prefix: "" -# 日志 +# Logging log: - # 启用日志 + # Enable logging enabled: true - # 日志文件路径 + # Log file path filename: "./data/artalk.log" - -# 缓存 +# Cache cache: - # 缓存类型 ["redis", "memcache", "builtin"] + # Cache type ["redis", "memcache", "builtin"] type: "builtin" - # 缓存过期时间 (单位:分钟) + # Cache expiration time (in minutes) expires: 30 - # 缓存启动预热 (程序启动时预热缓存) + # Cache warm up (warm up cache when program starts) warm_up: false - # 缓存服务器地址 (例如:"localhost:6379") + # Cache server address (e.g. "localhost:6379") server: "" - # Redis 配置 + # Redis config redis: - # 连接方式 ["tcp", "unix"] + # Connection type ["tcp", "unix"] network: "tcp" - # 用户名 + # Redis username username: "" - # 密码 + # Redis password password: "" - # 数据库编号 (例如使用零号数据库填写 0) + # Redis database number (e.g. 0) db: 0 - -# 可信域名 -trusted_domains: [] # 例如:["https://artalk.example.com:23366"] +# Trusted domains, e.g. ["https://artalk.example.com:23366"] add url of your site her # SSL ssl: - # 启用 SSL + # Enable SSL enabled: false - # 证书文件路径 + # Certificate file path, e.g. "/etc/letsencrypt/live/example.com/fullchain.pem" cert_path: "" - # 密钥文件路径 + # Key file path, e.g. "/etc/letsencrypt/live/example.com/privkey.pem" key_path: "" - -# 管理员账户 +# Admin users admin_users: + # Remove the following line comment symbol (#) to enable admin users # - name: "admin" # email: "admin@example.com" - # password: "" # 支持 bcrypt 或 md5 加密,如:"(md5)50c21190c6e4e5418c6a90d2b5031119" - # badge_name: "管理员" # badge_color: "#FF6C00" - -# 评论审核 +# Comment examination before being public moderator: - # 默认待审 (发表新评论需要后台人工审核后才能显示) + # Default pending (new comments need to be approved by admin) pending_default: false - # API 请求错误时拦截 (关闭此项当请求错误时让评论放行) + # Block when API request fails (set to false to let comments pass when API request fails) api_fail_block: false # Akismet Key - # (Akismet 反垃圾服务,https://akismet.com) + # (Akismet anti-spam service, https://akismet.com) akismet_key: "" - # 腾讯云文本内容安全 + # Auto review comments with Tencent Cloud Content Security # (https://cloud.tencent.com/document/product/1124/64508) tencent: enabled: false secret_id: "" secret_key: "" region: "ap-guangzhou" - # 阿里云内容安全 + # Auto review comments with Aliyun Content Security # (https://help.aliyun.com/document_detail/28417.html) aliyun: enabled: false access_key_id: "" access_key_secret: "" region: "cn-shanghai" - # 关键词过滤 (本地离线词库) + # Keyword filter (local offline dictionary) keywords: + # Enable keyword filter enabled: false - # 匹配成功设为待审状态 + # Set to pending when match pending: false - # 词库文件 (支持多个词库文件) + # Dictionary file (support multiple dictionary files) files: - - "./data/词库_1.txt" - # 词库文件内容分割符 (例如填写 "\n" 文件中一行一个关键词) file_sep: "\n" - # 替换字符 replac_to: "x" - -# 验证码 +# Captcha captcha: - # 启用验证码 + # Enable captcha enabled: true - # 总是需要验证码 + # Captcha is required always always: false - # 激活验证码所需操作次数 + # Captcha type ["geetest", "image"] + # The number of actions required to activate captcha action_limit: 3 - # 重置操作计数器超时 (单位:s, 设为 -1 不重置) + # Timeout to reset action counter (unit: s, set to -1 to disable) action_reset: 60 - # Geetest 极验 (https://www.geetest.com) + # Geetest (https://www.geetest.com) geetest: enabled: false captcha_id: "" captcha_key: "" - -# 邮件通知 +# Mail notification email: - # 启用邮件通知 + # Enable mail notification enabled: false - # 发送方式 ["smtp", "ali_dm", "sendmail"] + # Send method ["smtp", "ali_dm", "sendmail"] send_type: "smtp" - # 发信人昵称 + # Nick name of sender send_name: "{{reply_nick}}" - # 发信人地址 + # Email address of sender send_addr: "noreply@example.com" - # 邮件标题 - mail_subject: "[{{site_name}}] 您收到了来自 @{{reply_nick}} 的回复" - # 邮件模板文件 (填入文件路径使用自定义模板) + # Mail title + # Mail template file (set to file path to use custom template) mail_tpl: "default" - # SMTP 发送 (启用请将发送方式设为 "smtp") + # SMTP send (set to "smtp" to enable) smtp: - # 发件地址 + # Email address of sender host: "smtp.qq.com" - # 发件端口 + # Email port port: 587 - # 用户名 + # Email address of sender username: "example@qq.com" - # 密码 + # Password password: "" - # 阿里云邮件推送 - # (启用请将发送方式设为 "ali_dm";参考:https://help.aliyun.com/document_detail/29444.html) + # Aliyun mail push + # (set send method to "ali_dm" to enable; see: https://help.aliyun.com/document_detail/29444.html) ali_dm: access_key_id: "" access_key_secret: "" account_name: "noreply@example.com" - -# 图片上传 +# Image upload for comment img_upload: - # 启用图片上传 + # Enable image upload enabled: true - # 图片存放路径 + # Image storage path: "./data/artalk-img/" - # 图片大小限制 (单位:MB) + # Image size limit (unit: MB) max_size: 5 - # 图片链接基础路径 (默认为 "/static/images/") + # Image link base path (default: "/static/images/") public_path: null - # Upgit 配置 - # (使用 Upgit 将图片上传到 GitHub 或图床:https://github.com/pluveto/upgit) + # Upgit config upgit: - # 启用 Upgit + # Enable Upgit enabled: false - # 命令行参数 - exec: "./upgit -c -t /artalk-img" - # 上传后删除本地的图片 + # Command line arguments + exec: "./upgit -c UPGIT_CONF_FILE_PATH -t /artalk-img" + # Delete local image after upload success del_local: true - -# 多元推送 +# Multi-push admin_notify: - # 通知模版 (填入文件路径使用自定义模板) + # Notification template (set to file path to use custom template) notify_tpl: "default" - # 嘈杂模式 + # Noise mode + # noise_mode is disabled by default. + # When this option is set to `false`, only messages sent to the administrator will be notified, + # such as "user A" replies to "user B", the communication between these two users will not be notified to the administrator. noise_mode: false - # 邮件通知管理员 + # Notify admin email: - # 开启 (当使用其他推送方式时,可以关闭管理员邮件通知) + # Enable (can be disabled when using other push methods) enabled: true - # 邮件标题 (发送给管理员的邮件标题) - mail_subject: "[{{site_name}}] 您的文章「{{page_title}}」有新回复" + # Mail title (mail title sent to admin) + mail_subject: "[{{site_name}}] Post \"{{page_title}}\" has new a comment" # Telegram telegram: enabled: false @@ -213,7 +197,6 @@ admin_notify: bark: enabled: false server: "http://day.app/xxxxxxx/" - # 飞书 lark: enabled: false webhook_url: "" @@ -221,7 +204,6 @@ admin_notify: webhook: enabled: false url: "" - # 钉钉 ding_talk: enabled: false token: "" @@ -240,62 +222,58 @@ admin_notify: receivers: - "USER_ID_1" - "GROUP_ID_1" - -# 前端配置 +# Frontend config frontend: - # 评论框占位文字 - placeholder: "键入内容..." - # 无评论显示文字 - noComment: "「此时无声胜有声」" - # 发送按钮文字 - sendBtn: "发送评论" - # 评论框旅行 + # Comment box placeholder + placeholder: "What do you think?" + # Text to display when there is + noComment: "No comments yet." + # Text of the send button + sendBtn: "Send" editorTravel: true - # 暗黑模式 + # Dark mode darkMode: false - # 表情包 + # Emoticons emoticons: "https://cdn.jsdelivr.net/gh/ArtalkJS/Emoticons/grps/default.json" - # 投票按钮 + # Vote button vote: true - # 反对按钮 + # Dislike button voteDown: false - # 用户 UA 徽标 + # User UA badge uaBadge: true - # 评论排序功能 + # Comment sorting listSort: true - # 页面 PV 绑定元素 + # Page PV binding element pvEl: "#ArtalkPV" - # 评论数绑定元素 + # Comment count binding element countEl: "#ArtalkCount" - # 编辑器实时预览功能 + # Editor real-time preview preview: true - # 平铺模式 ["auto", true, false] + # Flatten mode ["auto", true, false] flatMode: "auto" - # 最大嵌套层数 + # Maximum nesting level nestMax: 2 - # 嵌套评论排序规则 ["DATE_ASC", "DATE_DESC", "VOTE_UP_DESC"] + # Nesting comment sorting rules ["DATE_ASC", "DATE_DESC", "VOTE_UP_DESC"] nestSort: DATE_ASC - # 头像 + # Gravatar gravatar: - # Gravatar 镜像地址 mirror: "https://cravatar.cn/avatar/" - # 默认头像 default: "mp" - # 评论分页 + # Comment pagination pagination: - # 每页评论数 + # Number of comments per page pageSize: 20 - # 加载更多模式 (关闭则使用分页条) + # Load more mode (disabled to use pagination bar) readMore: true - # 滚动加载 + # Scroll loading autoLoad: true - # 内容限高 + # Content height limit heightLimit: - # 评论内容限高 (单位:px) + # Comment content height limit (unit: px) content: 300 - # 子评论区域限高 (单位:px) + # Sub-comment area height limit (unit: px) children: 400 - # 请求超时 (单位:毫秒) + # Request timeout (unit: ms) reqTimeout: 15000 - # 版本检测 + # Version check versionCheck: true diff --git a/artalk.example_simple.yml b/artalk.example_simple.yml new file mode 100644 index 000000000..cb015f035 --- /dev/null +++ b/artalk.example_simple.yml @@ -0,0 +1,155 @@ +host: "0.0.0.0" +port: 23366 +app_key: "" +debug: false +timezone: "Asia/Shanghai" +site_default: "Default Site" +login_timeout: 259200 +db: + type: "sqlite" + file: "./data/artalk.db" + table_prefix: "" + name: "artalk" + host: "localhost" + port: 3306 + user: "root" + password: "" + charset: "utf8mb4" + +log: + enabled: true + filename: "./data/artalk.log" +cache: + type: "builtin" + expires: 30 + warm_up: false + server: "" + redis: + network: "tcp" + username: "" + password: "" + db: 0 + +ssl: + enabled: false + cert_path: "" + key_path: "" +admin_users: +moderator: + pending_default: false + api_fail_block: false + akismet_key: "" + tencent: + enabled: false + secret_id: "" + secret_key: "" + region: "ap-guangzhou" + aliyun: + enabled: false + access_key_id: "" + access_key_secret: "" + region: "cn-shanghai" + keywords: + enabled: false + pending: false + files: + file_sep: "\n" + replac_to: "x" +captcha: + enabled: true + always: false + action_limit: 3 + action_reset: 60 + geetest: + enabled: false + captcha_id: "" + captcha_key: "" +email: + enabled: false + send_type: "smtp" + send_name: "{{reply_nick}}" + send_addr: "noreply@example.com" + mail_tpl: "default" + smtp: + host: "smtp.qq.com" + port: 587 + username: "example@qq.com" + password: "" + ali_dm: + access_key_id: "" + access_key_secret: "" + account_name: "noreply@example.com" +img_upload: + enabled: true + path: "./data/artalk-img/" + max_size: 5 + public_path: null + upgit: + enabled: false + exec: "./upgit -c UPGIT_CONF_FILE_PATH -t /artalk-img" + del_local: true +admin_notify: + notify_tpl: "default" + noise_mode: false + email: + enabled: true + mail_subject: "[{{site_name}}] Post \"{{page_title}}\" has new a comment" + telegram: + enabled: false + api_token: "" + receivers: + - 7777777 + bark: + enabled: false + server: "http://day.app/xxxxxxx/" + lark: + enabled: false + webhook_url: "" + webhook: + enabled: false + url: "" + ding_talk: + enabled: false + token: "" + secret: "" + slack: + enabled: false + oauth_token: "" + receivers: + - "CHANNEL_ID" + line: + enabled: false + channel_secret: "" + channel_access_token: "" + receivers: + - "USER_ID_1" + - "GROUP_ID_1" +frontend: + placeholder: "What do you think?" + noComment: "No comments yet." + sendBtn: "Send" + editorTravel: true + darkMode: false + emoticons: "https://cdn.jsdelivr.net/gh/ArtalkJS/Emoticons/grps/default.json" + vote: true + voteDown: false + uaBadge: true + listSort: true + pvEl: "#ArtalkPV" + countEl: "#ArtalkCount" + preview: true + flatMode: "auto" + nestMax: 2 + nestSort: DATE_ASC + gravatar: + mirror: "https://cravatar.cn/avatar/" + default: "mp" + pagination: + pageSize: 20 + readMore: true + autoLoad: true + heightLimit: + content: 300 + children: 400 + reqTimeout: 15000 + versionCheck: true diff --git a/artalk.example_zh-CN copy.yml b/artalk.example_zh-CN copy.yml new file mode 100644 index 000000000..ddd0e5e89 --- /dev/null +++ b/artalk.example_zh-CN copy.yml @@ -0,0 +1,301 @@ +# 服务器地址 +host: "0.0.0.0" + +# 服务器端口 +port: 23366 + +# 加密密钥 +app_key: "" + +# 调试模式 +debug: false + +# 时间区域 +timezone: "Asia/Shanghai" + +# 默认站点名 +site_default: "默认站点" + +# 登陆有效时长 (单位:秒) +login_timeout: 259200 + +# 数据库 +db: + # 数据库类型 ["sqlite", "mysql", "pgsql", "mssql"] + type: "sqlite" + # 数据库文件 (仅 SQLite 数据库需填写) + file: "./data/artalk.db" + # 数据库名称 + name: "artalk" + # 数据库地址 + host: "localhost" + # 数据库端口 + port: 3306 + # 数据库账户 + user: "root" + # 数据库密码 + password: "" + # 编码格式 + charset: "utf8mb4" + # 表前缀 (例如:"atk_") + table_prefix: "" + +# 日志 +log: + # 启用日志 + enabled: true + # 日志文件路径 + filename: "./data/artalk.log" + +# 缓存 +cache: + # 缓存类型 ["redis", "memcache", "builtin"] + type: "builtin" + # 缓存过期时间 (单位:分钟) + expires: 30 + # 缓存启动预热 (程序启动时预热缓存) + warm_up: false + # 缓存服务器地址 (例如:"localhost:6379") + server: "" + # Redis 配置 + redis: + # 连接方式 ["tcp", "unix"] + network: "tcp" + # 用户名 + username: "" + # 密码 + password: "" + # 数据库编号 (例如使用零号数据库填写 0) + db: 0 + +# 可信域名 +trusted_domains: [] # 例如:["https://artalk.example.com:23366"] + +# SSL +ssl: + # 启用 SSL + enabled: false + # 证书文件路径 + cert_path: "" + # 密钥文件路径 + key_path: "" + +# 管理员账户 +admin_users: + # - name: "admin" + # email: "admin@example.com" + # password: "" # 支持 bcrypt 或 md5 加密,如:"(md5)50c21190c6e4e5418c6a90d2b5031119" + # badge_name: "管理员" + # badge_color: "#FF6C00" + +# 评论审核 +moderator: + # 默认待审 (发表新评论需要后台人工审核后才能显示) + pending_default: false + # API 请求错误时拦截 (关闭此项当请求错误时让评论放行) + api_fail_block: false + # Akismet Key + # (Akismet 反垃圾服务,https://akismet.com) + akismet_key: "" + # 腾讯云文本内容安全 + # (https://cloud.tencent.com/document/product/1124/64508) + tencent: + enabled: false + secret_id: "" + secret_key: "" + region: "ap-guangzhou" + # 阿里云内容安全 + # (https://help.aliyun.com/document_detail/28417.html) + aliyun: + enabled: false + access_key_id: "" + access_key_secret: "" + region: "cn-shanghai" + # 关键词过滤 (本地离线词库) + keywords: + enabled: false + # 匹配成功设为待审状态 + pending: false + # 词库文件 (支持多个词库文件) + files: + - "./data/词库_1.txt" + # 词库文件内容分割符 (例如填写 "\n" 文件中一行一个关键词) + file_sep: "\n" + # 替换字符 + replac_to: "x" + +# 验证码 +captcha: + # 启用验证码 + enabled: true + # 总是需要验证码 + always: false + # 激活验证码所需操作次数 + action_limit: 3 + # 重置操作计数器超时 (单位:s, 设为 -1 不重置) + action_reset: 60 + # Geetest 极验 (https://www.geetest.com) + geetest: + enabled: false + captcha_id: "" + captcha_key: "" + +# 邮件通知 +email: + # 启用邮件通知 + enabled: false + # 发送方式 ["smtp", "ali_dm", "sendmail"] + send_type: "smtp" + # 发信人昵称 + send_name: "{{reply_nick}}" + # 发信人地址 + send_addr: "noreply@example.com" + # 邮件标题 + mail_subject: "[{{site_name}}] 您收到了来自 @{{reply_nick}} 的回复" + # 邮件模板文件 (填入文件路径使用自定义模板) + mail_tpl: "default" + # SMTP 发送 (启用请将发送方式设为 "smtp") + smtp: + # 发件地址 + host: "smtp.qq.com" + # 发件端口 + port: 587 + # 用户名 + username: "example@qq.com" + # 密码 + password: "" + # 阿里云邮件推送 + # (启用请将发送方式设为 "ali_dm";参考:https://help.aliyun.com/document_detail/29444.html) + ali_dm: + access_key_id: "" + access_key_secret: "" + account_name: "noreply@example.com" + +# 图片上传 +img_upload: + # 启用图片上传 + enabled: true + # 图片存放路径 + path: "./data/artalk-img/" + # 图片大小限制 (单位:MB) + max_size: 5 + # 图片链接基础路径 (默认为 "/static/images/") + public_path: null + # Upgit 配置 + # (使用 Upgit 将图片上传到 GitHub 或图床:https://github.com/pluveto/upgit) + upgit: + # 启用 Upgit + enabled: false + # 命令行参数 + exec: "./upgit -c -t /artalk-img" + # 上传后删除本地的图片 + del_local: true + +# 多元推送 +admin_notify: + # 通知模版 (填入文件路径使用自定义模板) + notify_tpl: "default" + # 嘈杂模式 + noise_mode: false + # 邮件通知管理员 + email: + # 开启 (当使用其他推送方式时,可以关闭管理员邮件通知) + enabled: true + # 邮件标题 (发送给管理员的邮件标题) + mail_subject: "[{{site_name}}] 您的文章「{{page_title}}」有新回复" + # Telegram + telegram: + enabled: false + api_token: "" + receivers: + - 7777777 + # Bark + bark: + enabled: false + server: "http://day.app/xxxxxxx/" + # 飞书 + lark: + enabled: false + webhook_url: "" + # WebHook + webhook: + enabled: false + url: "" + # 钉钉 + ding_talk: + enabled: false + token: "" + secret: "" + # Slack + slack: + enabled: false + oauth_token: "" + receivers: + - "CHANNEL_ID" + # LINE + line: + enabled: false + channel_secret: "" + channel_access_token: "" + receivers: + - "USER_ID_1" + - "GROUP_ID_1" + +# 前端配置 +frontend: + # 评论框占位文字 + placeholder: "键入内容..." + # 无评论显示文字 + noComment: "「此时无声胜有声」" + # 发送按钮文字 + sendBtn: "发送评论" + # 评论框旅行 + editorTravel: true + # 暗黑模式 + darkMode: false + # 表情包 + emoticons: "https://cdn.jsdelivr.net/gh/ArtalkJS/Emoticons/grps/default.json" + # 投票按钮 + vote: true + # 反对按钮 + voteDown: false + # 用户 UA 徽标 + uaBadge: true + # 评论排序功能 + listSort: true + # 页面 PV 绑定元素 + pvEl: "#ArtalkPV" + # 评论数绑定元素 + countEl: "#ArtalkCount" + # 编辑器实时预览功能 + preview: true + # 平铺模式 ["auto", true, false] + flatMode: "auto" + # 最大嵌套层数 + nestMax: 2 + # 嵌套评论排序规则 ["DATE_ASC", "DATE_DESC", "VOTE_UP_DESC"] + nestSort: DATE_ASC + # 头像 + gravatar: + # Gravatar 镜像地址 + mirror: "https://cravatar.cn/avatar/" + # 默认头像 + default: "mp" + # 评论分页 + pagination: + # 每页评论数 + pageSize: 20 + # 加载更多模式 (关闭则使用分页条) + readMore: true + # 滚动加载 + autoLoad: true + # 内容限高 + heightLimit: + # 评论内容限高 (单位:px) + content: 300 + # 子评论区域限高 (单位:px) + children: 400 + # 请求超时 (单位:毫秒) + reqTimeout: 15000 + # 版本检测 + versionCheck: true From c7e2c8d3fd773ca30584800143f4aa46bc3ca0c8 Mon Sep 17 00:00:00 2001 From: pluveto Date: Tue, 17 Jan 2023 07:34:54 +0000 Subject: [PATCH 330/349] docs: example in zh-CN --- artalk.example_zh-CN copy.yml => artalk.example_zh-CN.yml | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename artalk.example_zh-CN copy.yml => artalk.example_zh-CN.yml (100%) diff --git a/artalk.example_zh-CN copy.yml b/artalk.example_zh-CN.yml similarity index 100% rename from artalk.example_zh-CN copy.yml rename to artalk.example_zh-CN.yml From 1b7766ca87cf945f76e3cec6dcaad83bd34495fb Mon Sep 17 00:00:00 2001 From: qwqcode Date: Tue, 17 Jan 2023 16:35:46 +0800 Subject: [PATCH 331/349] fix: config alias and Dockerfile Signed-off-by: qwqcode --- Dockerfile | 15 ++++++--------- docker-entrypoint.sh | 14 +++++++------- internal/config/init.go | 5 +---- internal/core/core.go | 5 +++++ internal/core/gen.go | 2 +- scripts/docker-artalk-runner.sh | 6 ++++++ 6 files changed, 26 insertions(+), 21 deletions(-) create mode 100644 scripts/docker-artalk-runner.sh diff --git a/Dockerfile b/Dockerfile index d1af5540d..3fa347d27 100644 --- a/Dockerfile +++ b/Dockerfile @@ -5,8 +5,7 @@ WORKDIR /source # install tools RUN set -ex \ - && apk upgrade \ - && apk add make git gcc musl-dev nodejs bash npm\ + && apk add --no-cache make git gcc musl-dev nodejs bash npm\ && npm install -g pnpm@7.25.0 COPY . ./Artalk @@ -14,7 +13,6 @@ COPY . ./Artalk # build RUN set -ex \ && cd ./Artalk \ - && git fetch --tags -f \ && export VERSION=$(git describe --tags --abbrev=0) \ && export COMMIT_SHA=$(git rev-parse --short HEAD) \ && make all @@ -30,15 +28,14 @@ ENV TZ ${TZ} COPY --from=builder /source/Artalk/bin/artalk /artalk -RUN apk upgrade \ - && apk add bash tzdata \ +RUN apk add --no-cache bash tzdata \ && ln -sf /usr/share/zoneinfo/${TZ} /etc/localtime \ && echo ${TZ} > /etc/timezone -# add alias -RUN echo -e '#!/bin/bash\n/artalk -w / -c /data/artalk.yml "$@"' > /usr/bin/artalk \ - && chmod +x /usr/bin/artalk \ - && cp -p /usr/bin/artalk /usr/bin/artalk +# move runner script to `/usr/bin/` and create alias +COPY scripts/docker-artalk-runner.sh /usr/bin/artalk +RUN chmod +x /usr/bin/artalk \ + && ln -s /usr/bin/artalk /usr/bin/artalk-go VOLUME ["/data"] diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh index 8416e8470..b6c21441f 100755 --- a/docker-entrypoint.sh +++ b/docker-entrypoint.sh @@ -1,12 +1,8 @@ #!/bin/bash set -e -if [ ! -e /data/artalk.yml ] && [ "$1" != 'gen' ]; then - if [ ! -e /conf.yml ]; then - # Generate new config - artalk gen conf /data/artalk.yml - echo "$(date) [info] Generate new config file to '/data/artalk.yml'" - else +if [ "$1" != 'gen' ] && ( [ ! -e /data/artalk.yml ] && [ ! -e /data/artalk-go.yml ] ); then + if [ -e /conf.yml ]; then # Move original config to `/data/` for upgrade (<= v2.1.8) cp /conf.yml /data/artalk.yml upMsg="" @@ -19,8 +15,12 @@ if [ ! -e /data/artalk.yml ] && [ "$1" != 'gen' ]; then upMsg+=$'# and edit "/data/artalk.yml" for configuration.' echo "$upMsg" > /conf.yml echo "$(date) [info] Copy config file from '/conf.yml' to '/data/artalk.yml' for upgrade" + else + # Generate new config + artalk gen conf /data/artalk.yml + echo "$(date) [info] Generate new config file to '/data/artalk.yml'" fi fi # Run Artalk -artalk "$@" +/usr/bin/artalk "$@" diff --git a/internal/config/init.go b/internal/config/init.go index 10221fe52..d423a0bd5 100644 --- a/internal/config/init.go +++ b/internal/config/init.go @@ -10,6 +10,7 @@ import ( "github.com/sirupsen/logrus" ) +// 默认配置文件名 const DEFAULT_CONF_FILE = "artalk.yml" var ( @@ -27,10 +28,6 @@ func GetCfgFileLoaded() string { // Init 初始化配置 func Init(cfgFile string) { - if cfgFile == "" { - cfgFile = DEFAULT_CONF_FILE - } - // load yaml config if err := kf.Load(file.Provider(cfgFile), parser); err != nil { logrus.Errorln(err) diff --git a/internal/core/core.go b/internal/core/core.go index b684432aa..b546ea4fe 100644 --- a/internal/core/core.go +++ b/internal/core/core.go @@ -60,6 +60,11 @@ func initConfig(cfgFile string, workDir string) { if cfgFile == "" { cfgFile = config.DEFAULT_CONF_FILE + + // 默认配置文件名 "artalk-go.yml"(for 向下兼容) + if _, err := os.Stat("artalk-go.yml"); err == nil { + cfgFile = "artalk-go.yml" + } } // 自动生成新配置文件 diff --git a/internal/core/gen.go b/internal/core/gen.go index 999915af3..35773466f 100644 --- a/internal/core/gen.go +++ b/internal/core/gen.go @@ -14,7 +14,7 @@ import ( func Gen(genType string, specificPath string, overwrite bool) { // 参数 - if genType == "config" || genType == "conf" { + if genType == "config" || genType == "conf" || genType == "artalk.yml" { genType = "artalk.example.yml" } diff --git a/scripts/docker-artalk-runner.sh b/scripts/docker-artalk-runner.sh new file mode 100644 index 000000000..79367e376 --- /dev/null +++ b/scripts/docker-artalk-runner.sh @@ -0,0 +1,6 @@ +#!/bin/bash +if [ -e /data/artalk.yml ]; then + /artalk -w / -c /data/artalk.yml "$@" +else + /artalk -w / -c /data/artalk-go.yml "$@" +fi From 15e472aede767973a38902315ce7a8dca5a4505b Mon Sep 17 00:00:00 2001 From: pluveto Date: Tue, 17 Jan 2023 09:06:26 +0000 Subject: [PATCH 332/349] fix: missing trusted_domains field --- artalk.example.yml | 6 +++--- artalk.example_simple.yml | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/artalk.example.yml b/artalk.example.yml index cf574e838..f3882b005 100644 --- a/artalk.example.yml +++ b/artalk.example.yml @@ -61,7 +61,7 @@ cache: # Redis database number (e.g. 0) db: 0 # Trusted domains, e.g. ["https://artalk.example.com:23366"] add url of your site her - +trusted_domains: [] # SSL ssl: # Enable SSL @@ -177,7 +177,7 @@ admin_notify: # Notification template (set to file path to use custom template) notify_tpl: "default" # Noise mode - # noise_mode is disabled by default. + # noise_mode is disabled by default. # When this option is set to `false`, only messages sent to the administrator will be notified, # such as "user A" replies to "user B", the communication between these two users will not be notified to the administrator. noise_mode: false @@ -186,7 +186,7 @@ admin_notify: # Enable (can be disabled when using other push methods) enabled: true # Mail title (mail title sent to admin) - mail_subject: "[{{site_name}}] Post \"{{page_title}}\" has new a comment" + mail_subject: '[{{site_name}}] Post "{{page_title}}" has new a comment' # Telegram telegram: enabled: false diff --git a/artalk.example_simple.yml b/artalk.example_simple.yml index cb015f035..62d09e55f 100644 --- a/artalk.example_simple.yml +++ b/artalk.example_simple.yml @@ -29,7 +29,7 @@ cache: username: "" password: "" db: 0 - +trusted_domains: [] ssl: enabled: false cert_path: "" @@ -93,7 +93,7 @@ admin_notify: noise_mode: false email: enabled: true - mail_subject: "[{{site_name}}] Post \"{{page_title}}\" has new a comment" + mail_subject: '[{{site_name}}] Post "{{page_title}}" has new a comment' telegram: enabled: false api_token: "" From f210f154c316630fe5478d3fa8b615431e0b8876 Mon Sep 17 00:00:00 2001 From: pluveto Date: Tue, 17 Jan 2023 09:09:57 +0000 Subject: [PATCH 333/349] feat: one-key site creating with artalk integrated --- internal/query/testdata/example_site_conf.yml | 162 ++++++++++++++++ scripts/setup_example_site.sh | 178 ++++++++++++++++++ 2 files changed, 340 insertions(+) create mode 100644 internal/query/testdata/example_site_conf.yml create mode 100755 scripts/setup_example_site.sh diff --git a/internal/query/testdata/example_site_conf.yml b/internal/query/testdata/example_site_conf.yml new file mode 100644 index 000000000..0a853f1a6 --- /dev/null +++ b/internal/query/testdata/example_site_conf.yml @@ -0,0 +1,162 @@ +# This script is used by internal/query/testdata/example_site_conf.yml +# Do not modify this script unless you know what you are doing. +host: "0.0.0.0" +port: 23366 +app_key: "test" +debug: false +timezone: "Asia/Shanghai" +site_default: "Default Site" +login_timeout: 259200 +db: + type: "sqlite" + file: "./data/artalk.db" + table_prefix: "" + name: "artalk" + host: "localhost" + port: 3306 + user: "root" + password: "" + charset: "utf8mb4" + +log: + enabled: true + filename: "./data/artalk.log" +cache: + type: "builtin" + expires: 30 + warm_up: false + server: "" + redis: + network: "tcp" + username: "" + password: "" + db: 0 +trusted_domains: ["http://localhost:1313"] +ssl: + enabled: false + cert_path: "" + key_path: "" +admin_users: + - name: "admin" + email: "admin@test.com" + password: "admin" + badge_name: "Admin" + badge_color: "#FF6C00" +moderator: + pending_default: false + api_fail_block: false + akismet_key: "" + tencent: + enabled: false + secret_id: "" + secret_key: "" + region: "ap-guangzhou" + aliyun: + enabled: false + access_key_id: "" + access_key_secret: "" + region: "cn-shanghai" + keywords: + enabled: false + pending: false + files: + file_sep: "\n" + replac_to: "x" +captcha: + enabled: true + always: false + action_limit: 3 + action_reset: 60 + geetest: + enabled: false + captcha_id: "" + captcha_key: "" +email: + enabled: false + send_type: "smtp" + send_name: "{{reply_nick}}" + send_addr: "noreply@example.com" + mail_tpl: "default" + smtp: + host: "smtp.qq.com" + port: 587 + username: "example@qq.com" + password: "" + ali_dm: + access_key_id: "" + access_key_secret: "" + account_name: "noreply@example.com" +img_upload: + enabled: true + path: "./data/artalk-img/" + max_size: 5 + public_path: null + upgit: + enabled: false + exec: "./upgit -c UPGIT_CONF_FILE_PATH -t /artalk-img" + del_local: true +admin_notify: + notify_tpl: "default" + noise_mode: false + email: + enabled: true + mail_subject: '[{{site_name}}] Post "{{page_title}}" has new a comment' + telegram: + enabled: false + api_token: "" + receivers: + - 7777777 + bark: + enabled: false + server: "http://day.app/xxxxxxx/" + lark: + enabled: false + webhook_url: "" + webhook: + enabled: false + url: "" + ding_talk: + enabled: false + token: "" + secret: "" + slack: + enabled: false + oauth_token: "" + receivers: + - "CHANNEL_ID" + line: + enabled: false + channel_secret: "" + channel_access_token: "" + receivers: + - "USER_ID_1" + - "GROUP_ID_1" +frontend: + placeholder: "What do you think?" + noComment: "No comments yet." + sendBtn: "Send" + editorTravel: true + darkMode: false + emoticons: "https://cdn.jsdelivr.net/gh/ArtalkJS/Emoticons/grps/default.json" + vote: true + voteDown: false + uaBadge: true + listSort: true + pvEl: "#ArtalkPV" + countEl: "#ArtalkCount" + preview: true + flatMode: "auto" + nestMax: 2 + nestSort: DATE_ASC + gravatar: + mirror: "https://cravatar.cn/avatar/" + default: "mp" + pagination: + pageSize: 20 + readMore: true + autoLoad: true + heightLimit: + content: 300 + children: 400 + reqTimeout: 15000 + versionCheck: true diff --git a/scripts/setup_example_site.sh b/scripts/setup_example_site.sh new file mode 100755 index 000000000..ad91865d4 --- /dev/null +++ b/scripts/setup_example_site.sh @@ -0,0 +1,178 @@ +#!/bin/bash + +# +# This script sets up a local example site for testing, +# with Artalk integrated. +# Build frontend and backend before running this script. +# After running this script, run: +# ./bin/artalk server -c ./local/local.yml +# to start the comment server. +# And open http://localhost:1313/ in your browser to view the example site. +# + +# exit if any command fails +set -e + +# check if hugo is installed +if ! [ -x "$(command -v hugo)" ]; then + echo 'Error: hugo is not installed.' >&2 + exit 1 +fi + +# check if ./public/dist/Artalk.css exists +if ! [ -f "./public/dist/Artalk.css" ]; then + echo 'Error: ./public/dist/Artalk.css does not exist.' >&2 + exit 1 +fi + +mkdir -p ./local + +# copy internal/query/testdata/example_site_conf.yml to ./local/local.yml if it does not exist +if ! [ -f "./local/artalk.yml" ]; then + echo "Copying internal/query/testdata/example_site_conf.yml to ./local/artalk.yml" + cp ./internal/query/testdata/example_site_conf.yml ./local/local.yml +fi + +# clean up local/example_site if it exists +if [ -d "./local/example_site" ]; then + echo "Cleaning up local/example_site" + rm -rfd ./local/example_site +fi + +echo "Setting up local/example_site" +# create a new example site +hugo new site ./local/example_site + +# copy the theme to the example site +theme_repo="https://github.com/ph-ph/chalk" +theme_dir="./local/example_site/themes/chalk" +echo "Cloning theme from ${theme_repo} to ${theme_dir}" +git clone ${theme_repo} ${theme_dir} + + +# create comment partial +echo "Creating comment partial in local/example_site" +mkdir -p ./local/example_site/layouts/partials/comments +cat << EOF > ./local/example_site/layouts/partials/comments/comments.html + + + + +
+ + +EOF + +# patch ${single_template}, insert code before last tag +single_template=local/example_site/themes/chalk/layouts/_default/single.html +echo "Patching ${single_template}" +sed -i '/<\/article>/i {{ partial "comments/comments.html" . }}' ./${single_template} + +# update the example site config +cat << EOF > ./local/example_site/config.toml +baseURL = 'http://example.org/' +languageCode = 'en-us' +title = 'My New Hugo Site' +theme = "chalk" +[params.chalk] + # chalk theme parameters + about_enabled = true + scrollappear_enabled = true + theme_toggle = true + rss_enabled = true + blog_theme = 'light' + local_fonts = false +[params.social] + twitter='example' + github='example' +[params.artalk] + server='http://localhost:23366' + site='Default Site' +EOF + +# copy ./public/dist/Artalk.css/js to /lib/artalk/Artalk.css/js +echo "Copying ./public/dist/Artalk.css/js to /lib/artalk/Artalk.css/js" +mkdir -p ./local/example_site/static/lib/artalk +cp ./public/dist/Artalk.css ./local/example_site/static/lib/artalk/Artalk.css +cp ./public/dist/Artalk.js ./local/example_site/static/lib/artalk/Artalk.js + +# create a post in the example site +echo "Creating a post in local/example_site" +mkdir -p ./local/example_site/content/posts +cat << EOF > ./local/example_site/content/posts/my-first-post.md +--- +title: "My First Post" +--- + +# Manibus positaeque agrestes + +## Inmurmurat posset saxa + +Lorem markdownum undas, sors matre fata nimiumque parte; sua carae medios. Per +ego ad turritaque pars. Privignae tenuit auget in saxo nebulis. Pende enim +Silvanusque idem favilla, tecta! Motu *modo*, Almo vertuntur sceptroque alto, +mitia. + +## Fuit ardor centum materiam in inquit + +Rarescit digitis, turba debuit auctor inplerant monstra, pararet. Detestatur +**saltem dubitet Aeneadae** pectora celsis doloris, est tutus et circumdat agit +poposcit *precor* et. + +## Bos avidus flammas excusare corpore + +Nova Rutulos, Clytien, conspicuus poterit. Ne hac cladem fatendo postquam +saevitiae Dianae torvos *fluctus*, iuvenis et. Sensit adstitit separat effectum +saevarum fecit, me date imo, adicis nubigenas **ferumque**. Res illa signis! +Videri vagi, hac mori iras exuit similis modo et tempora. + + if (day_widget_saas) { + footer.rate_dhcp(4, association_data, winSpoofingMca(real, + esportsRepository, system)); + } + if (unix_dma.serp(4 + trinitron, -3) == + koffice_function.defragmentQuadMatrix(vista_kernel, + firmware_ntfs_tebibyte, -1 * bing)) { + utility *= web; + tunneling_halftone_primary(-2 + bare, -5, bmp + 5); + } + uddi += crop_error_capacity(bugCpc + boot, publishingSystemOutput( + dvdClientOptical)); + if (2 == file_apple) { + cutDevelopmentData.heuristic_bridge_desktop( + softwareInfotainmentEdutainment - spam, tween, + donationwareSecondary); + } else { + serverSdramRuntime = -2; + } + +## Nostrique miratur repetita suprema vocat sustulit + +Dumosaque adflabat mixtaeque communicat est, Aeolus pinum. Me fecit. + + domain_leak_namespace.visualMonitor(header, gps_archie(service, 4, + basic_networking_unfriend)); + cisc_software_cycle.fiosHertzAndroid += plug - 5 + storage( + firewall_algorithm_troubleshooting); + eup_botnet -= 5; + computerSampleNull += uml * hard_clone_cd; + +Limine habebat frigore, venenis tenebris nota. Fors erubui victa cortice +nullamque iniqui domos viroque, *inquit* ingentia, *crudelia*. Foedera qua! +*Ipsa dum perque*, mea orbi; aversus loca rutilos dona dixerat Bacchus saltus. +EOF + + +# run the example site +echo "Running local/example_site" +pushd ./local/example_site +hugo server +popd \ No newline at end of file From 61da5eb6efedb308b2bd776071c921c12092a466 Mon Sep 17 00:00:00 2001 From: pluveto Date: Tue, 17 Jan 2023 09:15:09 +0000 Subject: [PATCH 334/349] docs: update setup-example-site.sh script usage --- docs/DEVELOPER.md | 28 ++++++++++++++++++- ..._example_site.sh => setup-example-site.sh} | 0 2 files changed, 27 insertions(+), 1 deletion(-) rename scripts/{setup_example_site.sh => setup-example-site.sh} (100%) diff --git a/docs/DEVELOPER.md b/docs/DEVELOPER.md index 6ec3c66d2..c82c2544f 100644 --- a/docs/DEVELOPER.md +++ b/docs/DEVELOPER.md @@ -30,9 +30,35 @@ $ cd Artalk ``` -### Setup a backend for development +### Build frontend and backend First, we need to install the dependencies for backend written in Go. Simply run the following command: ```sh +make build +``` + +This will build both the frontend and backend. + ++ **Frontend** will be built under `./ui/packages/artalk` and copied to `./public` directory. ++ **Backend** will be built under `./bin` directory. + +### Optional: Use one-key script to run a demo site + +If you want to run a demo site, you can use the following command: + +```sh +./scripts/setup-example-site.sh +``` + +This script sets up a local example site for testing, with Artalk integrated. + +After running this script, run: + +```sh +./bin/artalk server -c ./local/local.yml +``` + +to start the artalk server. +And open http://localhost:1313/ in your browser to view the example site. diff --git a/scripts/setup_example_site.sh b/scripts/setup-example-site.sh similarity index 100% rename from scripts/setup_example_site.sh rename to scripts/setup-example-site.sh From 593639f92e92ef7284b2d29b2571a4f75c2276ec Mon Sep 17 00:00:00 2001 From: qwqcode Date: Tue, 17 Jan 2023 18:47:07 +0800 Subject: [PATCH 335/349] chore: move files from `docs/docs` to `docs` Signed-off-by: qwqcode --- docs/{docs => }/.vitepress/config.ts | 0 docs/{docs => }/.vitepress/theme/Artalk.vue | 0 docs/{docs => }/.vitepress/theme/Artransfer.vue | 0 docs/{docs => }/.vitepress/theme/Layout.vue | 0 docs/{docs => }/.vitepress/theme/index.ts | 0 docs/{docs => }/.vitepress/theme/style.scss | 0 docs/{docs => }/.vitepress/types/shims-vue.d.ts | 0 docs/{docs => }/code/ArtalkCDN.json | 0 docs/{docs => }/code/ArtalkVersion.json | 0 docs/{docs => }/code/quick-start/cdn.html | 0 docs/{docs => }/code/quick-start/normal-install.sh | 0 docs/{docs => }/develop/api.md | 0 docs/{docs => }/develop/event.md | 0 docs/{docs => }/develop/index.md | 0 docs/{docs => }/guide/about.md | 0 docs/{docs => }/guide/backend/admin_notify.md | 0 docs/{docs => }/guide/backend/build.md | 0 docs/{docs => }/guide/backend/captcha.md | 0 docs/{docs => }/guide/backend/config.md | 0 docs/{docs => }/guide/backend/daemon.md | 0 docs/{docs => }/guide/backend/data.md | 0 docs/{docs => }/guide/backend/docker.md | 0 docs/{docs => }/guide/backend/email.md | 0 docs/{docs => }/guide/backend/fe-control.md | 0 docs/{docs => }/guide/backend/img-upload.md | 0 docs/{docs => }/guide/backend/index.md | 0 docs/{docs => }/guide/backend/install.md | 0 docs/{docs => }/guide/backend/moderator.md | 0 docs/{docs => }/guide/backend/multi-site.md | 0 docs/{docs => }/guide/backend/notify.md | 0 docs/{docs => }/guide/backend/relative-path.md | 0 docs/{docs => }/guide/backend/reverse-proxy.md | 0 docs/{docs => }/guide/backend/update.md | 0 docs/{docs => }/guide/cases.md | 0 docs/{docs => }/guide/deploy.md | 0 docs/{docs => }/guide/describe.md | 0 docs/{docs => }/guide/extras.md | 0 docs/{docs => }/guide/frontend/artalk-lite.md | 0 docs/{docs => }/guide/frontend/config.md | 0 docs/{docs => }/guide/frontend/emoticons.md | 0 docs/{docs => }/guide/frontend/i18n.md | 0 docs/{docs => }/guide/frontend/import-blog.md | 0 docs/{docs => }/guide/frontend/import-framework.md | 0 docs/{docs => }/guide/frontend/index.md | 0 docs/{docs => }/guide/frontend/install.md | 0 docs/{docs => }/guide/frontend/latex.md | 0 docs/{docs => }/guide/frontend/lightbox.md | 0 docs/{docs => }/guide/frontend/plugs.md | 0 docs/{docs => }/guide/frontend/pv.md | 0 docs/{docs => }/guide/frontend/sidebar.md | 0 docs/{docs => }/guide/intro.md | 0 docs/{docs => }/guide/security.md | 0 docs/{docs => }/guide/transfer.md | 0 docs/{docs => }/images/akismet/1.png | Bin docs/{docs => }/images/akismet/2.png | Bin .../{docs => }/images/artalk-go/artalk-go-cache.png | Bin docs/{docs => }/images/artalk-logo.png | Bin docs/{docs => }/images/baota-proxy/1.png | Bin docs/{docs => }/images/baota-proxy/2.png | Bin docs/{docs => }/images/baota-proxy/3.png | Bin docs/{docs => }/images/baota-supervisor/0.png | Bin docs/{docs => }/images/baota-supervisor/1.png | Bin docs/{docs => }/images/latex-support/1.png | Bin docs/{docs => }/images/notify/bark.png | Bin docs/{docs => }/images/notify/lark-1.png | Bin docs/{docs => }/images/notify/lark-2.png | Bin docs/{docs => }/images/notify/lark-3.png | Bin docs/{docs => }/images/notify/tg-1.png | Bin docs/{docs => }/images/notify/tg-2.png | Bin docs/{docs => }/images/relative-path/1.png | Bin docs/{docs => }/images/sidebar/1.png | Bin docs/{docs => }/images/sidebar/2.png | Bin docs/{docs => }/images/sidebar/3.png | Bin docs/{docs => }/images/sidebar/4.png | Bin docs/{docs => }/images/sidebar/5.png | Bin docs/{docs => }/images/sidebar/6.png | Bin docs/{docs => }/images/sidebar/7.png | Bin docs/{docs => }/images/sidebar/site_url.png | Bin docs/{docs => }/images/transfer/disqus.png | Bin docs/{docs => }/images/transfer/leancloud.png | Bin docs/{docs => }/images/transfer/tencent-tcb.png | Bin docs/{docs => }/images/transfer/wordpress.png | Bin docs/{docs => }/index.md | 0 docs/package.json | 8 ++++---- .../{docs => }/public/assets/emoticons/default.json | 0 docs/{docs => }/public/favicon.png | Bin 86 files changed, 4 insertions(+), 4 deletions(-) rename docs/{docs => }/.vitepress/config.ts (100%) rename docs/{docs => }/.vitepress/theme/Artalk.vue (100%) rename docs/{docs => }/.vitepress/theme/Artransfer.vue (100%) rename docs/{docs => }/.vitepress/theme/Layout.vue (100%) rename docs/{docs => }/.vitepress/theme/index.ts (100%) rename docs/{docs => }/.vitepress/theme/style.scss (100%) rename docs/{docs => }/.vitepress/types/shims-vue.d.ts (100%) rename docs/{docs => }/code/ArtalkCDN.json (100%) rename docs/{docs => }/code/ArtalkVersion.json (100%) rename docs/{docs => }/code/quick-start/cdn.html (100%) rename docs/{docs => }/code/quick-start/normal-install.sh (100%) rename docs/{docs => }/develop/api.md (100%) rename docs/{docs => }/develop/event.md (100%) rename docs/{docs => }/develop/index.md (100%) rename docs/{docs => }/guide/about.md (100%) rename docs/{docs => }/guide/backend/admin_notify.md (100%) rename docs/{docs => }/guide/backend/build.md (100%) rename docs/{docs => }/guide/backend/captcha.md (100%) rename docs/{docs => }/guide/backend/config.md (100%) rename docs/{docs => }/guide/backend/daemon.md (100%) rename docs/{docs => }/guide/backend/data.md (100%) rename docs/{docs => }/guide/backend/docker.md (100%) rename docs/{docs => }/guide/backend/email.md (100%) rename docs/{docs => }/guide/backend/fe-control.md (100%) rename docs/{docs => }/guide/backend/img-upload.md (100%) rename docs/{docs => }/guide/backend/index.md (100%) rename docs/{docs => }/guide/backend/install.md (100%) rename docs/{docs => }/guide/backend/moderator.md (100%) rename docs/{docs => }/guide/backend/multi-site.md (100%) rename docs/{docs => }/guide/backend/notify.md (100%) rename docs/{docs => }/guide/backend/relative-path.md (100%) rename docs/{docs => }/guide/backend/reverse-proxy.md (100%) rename docs/{docs => }/guide/backend/update.md (100%) rename docs/{docs => }/guide/cases.md (100%) rename docs/{docs => }/guide/deploy.md (100%) rename docs/{docs => }/guide/describe.md (100%) rename docs/{docs => }/guide/extras.md (100%) rename docs/{docs => }/guide/frontend/artalk-lite.md (100%) rename docs/{docs => }/guide/frontend/config.md (100%) rename docs/{docs => }/guide/frontend/emoticons.md (100%) rename docs/{docs => }/guide/frontend/i18n.md (100%) rename docs/{docs => }/guide/frontend/import-blog.md (100%) rename docs/{docs => }/guide/frontend/import-framework.md (100%) rename docs/{docs => }/guide/frontend/index.md (100%) rename docs/{docs => }/guide/frontend/install.md (100%) rename docs/{docs => }/guide/frontend/latex.md (100%) rename docs/{docs => }/guide/frontend/lightbox.md (100%) rename docs/{docs => }/guide/frontend/plugs.md (100%) rename docs/{docs => }/guide/frontend/pv.md (100%) rename docs/{docs => }/guide/frontend/sidebar.md (100%) rename docs/{docs => }/guide/intro.md (100%) rename docs/{docs => }/guide/security.md (100%) rename docs/{docs => }/guide/transfer.md (100%) rename docs/{docs => }/images/akismet/1.png (100%) rename docs/{docs => }/images/akismet/2.png (100%) rename docs/{docs => }/images/artalk-go/artalk-go-cache.png (100%) rename docs/{docs => }/images/artalk-logo.png (100%) rename docs/{docs => }/images/baota-proxy/1.png (100%) rename docs/{docs => }/images/baota-proxy/2.png (100%) rename docs/{docs => }/images/baota-proxy/3.png (100%) rename docs/{docs => }/images/baota-supervisor/0.png (100%) rename docs/{docs => }/images/baota-supervisor/1.png (100%) rename docs/{docs => }/images/latex-support/1.png (100%) rename docs/{docs => }/images/notify/bark.png (100%) rename docs/{docs => }/images/notify/lark-1.png (100%) rename docs/{docs => }/images/notify/lark-2.png (100%) rename docs/{docs => }/images/notify/lark-3.png (100%) rename docs/{docs => }/images/notify/tg-1.png (100%) rename docs/{docs => }/images/notify/tg-2.png (100%) rename docs/{docs => }/images/relative-path/1.png (100%) rename docs/{docs => }/images/sidebar/1.png (100%) rename docs/{docs => }/images/sidebar/2.png (100%) rename docs/{docs => }/images/sidebar/3.png (100%) rename docs/{docs => }/images/sidebar/4.png (100%) rename docs/{docs => }/images/sidebar/5.png (100%) rename docs/{docs => }/images/sidebar/6.png (100%) rename docs/{docs => }/images/sidebar/7.png (100%) rename docs/{docs => }/images/sidebar/site_url.png (100%) rename docs/{docs => }/images/transfer/disqus.png (100%) rename docs/{docs => }/images/transfer/leancloud.png (100%) rename docs/{docs => }/images/transfer/tencent-tcb.png (100%) rename docs/{docs => }/images/transfer/wordpress.png (100%) rename docs/{docs => }/index.md (100%) rename docs/{docs => }/public/assets/emoticons/default.json (100%) rename docs/{docs => }/public/favicon.png (100%) diff --git a/docs/docs/.vitepress/config.ts b/docs/.vitepress/config.ts similarity index 100% rename from docs/docs/.vitepress/config.ts rename to docs/.vitepress/config.ts diff --git a/docs/docs/.vitepress/theme/Artalk.vue b/docs/.vitepress/theme/Artalk.vue similarity index 100% rename from docs/docs/.vitepress/theme/Artalk.vue rename to docs/.vitepress/theme/Artalk.vue diff --git a/docs/docs/.vitepress/theme/Artransfer.vue b/docs/.vitepress/theme/Artransfer.vue similarity index 100% rename from docs/docs/.vitepress/theme/Artransfer.vue rename to docs/.vitepress/theme/Artransfer.vue diff --git a/docs/docs/.vitepress/theme/Layout.vue b/docs/.vitepress/theme/Layout.vue similarity index 100% rename from docs/docs/.vitepress/theme/Layout.vue rename to docs/.vitepress/theme/Layout.vue diff --git a/docs/docs/.vitepress/theme/index.ts b/docs/.vitepress/theme/index.ts similarity index 100% rename from docs/docs/.vitepress/theme/index.ts rename to docs/.vitepress/theme/index.ts diff --git a/docs/docs/.vitepress/theme/style.scss b/docs/.vitepress/theme/style.scss similarity index 100% rename from docs/docs/.vitepress/theme/style.scss rename to docs/.vitepress/theme/style.scss diff --git a/docs/docs/.vitepress/types/shims-vue.d.ts b/docs/.vitepress/types/shims-vue.d.ts similarity index 100% rename from docs/docs/.vitepress/types/shims-vue.d.ts rename to docs/.vitepress/types/shims-vue.d.ts diff --git a/docs/docs/code/ArtalkCDN.json b/docs/code/ArtalkCDN.json similarity index 100% rename from docs/docs/code/ArtalkCDN.json rename to docs/code/ArtalkCDN.json diff --git a/docs/docs/code/ArtalkVersion.json b/docs/code/ArtalkVersion.json similarity index 100% rename from docs/docs/code/ArtalkVersion.json rename to docs/code/ArtalkVersion.json diff --git a/docs/docs/code/quick-start/cdn.html b/docs/code/quick-start/cdn.html similarity index 100% rename from docs/docs/code/quick-start/cdn.html rename to docs/code/quick-start/cdn.html diff --git a/docs/docs/code/quick-start/normal-install.sh b/docs/code/quick-start/normal-install.sh similarity index 100% rename from docs/docs/code/quick-start/normal-install.sh rename to docs/code/quick-start/normal-install.sh diff --git a/docs/docs/develop/api.md b/docs/develop/api.md similarity index 100% rename from docs/docs/develop/api.md rename to docs/develop/api.md diff --git a/docs/docs/develop/event.md b/docs/develop/event.md similarity index 100% rename from docs/docs/develop/event.md rename to docs/develop/event.md diff --git a/docs/docs/develop/index.md b/docs/develop/index.md similarity index 100% rename from docs/docs/develop/index.md rename to docs/develop/index.md diff --git a/docs/docs/guide/about.md b/docs/guide/about.md similarity index 100% rename from docs/docs/guide/about.md rename to docs/guide/about.md diff --git a/docs/docs/guide/backend/admin_notify.md b/docs/guide/backend/admin_notify.md similarity index 100% rename from docs/docs/guide/backend/admin_notify.md rename to docs/guide/backend/admin_notify.md diff --git a/docs/docs/guide/backend/build.md b/docs/guide/backend/build.md similarity index 100% rename from docs/docs/guide/backend/build.md rename to docs/guide/backend/build.md diff --git a/docs/docs/guide/backend/captcha.md b/docs/guide/backend/captcha.md similarity index 100% rename from docs/docs/guide/backend/captcha.md rename to docs/guide/backend/captcha.md diff --git a/docs/docs/guide/backend/config.md b/docs/guide/backend/config.md similarity index 100% rename from docs/docs/guide/backend/config.md rename to docs/guide/backend/config.md diff --git a/docs/docs/guide/backend/daemon.md b/docs/guide/backend/daemon.md similarity index 100% rename from docs/docs/guide/backend/daemon.md rename to docs/guide/backend/daemon.md diff --git a/docs/docs/guide/backend/data.md b/docs/guide/backend/data.md similarity index 100% rename from docs/docs/guide/backend/data.md rename to docs/guide/backend/data.md diff --git a/docs/docs/guide/backend/docker.md b/docs/guide/backend/docker.md similarity index 100% rename from docs/docs/guide/backend/docker.md rename to docs/guide/backend/docker.md diff --git a/docs/docs/guide/backend/email.md b/docs/guide/backend/email.md similarity index 100% rename from docs/docs/guide/backend/email.md rename to docs/guide/backend/email.md diff --git a/docs/docs/guide/backend/fe-control.md b/docs/guide/backend/fe-control.md similarity index 100% rename from docs/docs/guide/backend/fe-control.md rename to docs/guide/backend/fe-control.md diff --git a/docs/docs/guide/backend/img-upload.md b/docs/guide/backend/img-upload.md similarity index 100% rename from docs/docs/guide/backend/img-upload.md rename to docs/guide/backend/img-upload.md diff --git a/docs/docs/guide/backend/index.md b/docs/guide/backend/index.md similarity index 100% rename from docs/docs/guide/backend/index.md rename to docs/guide/backend/index.md diff --git a/docs/docs/guide/backend/install.md b/docs/guide/backend/install.md similarity index 100% rename from docs/docs/guide/backend/install.md rename to docs/guide/backend/install.md diff --git a/docs/docs/guide/backend/moderator.md b/docs/guide/backend/moderator.md similarity index 100% rename from docs/docs/guide/backend/moderator.md rename to docs/guide/backend/moderator.md diff --git a/docs/docs/guide/backend/multi-site.md b/docs/guide/backend/multi-site.md similarity index 100% rename from docs/docs/guide/backend/multi-site.md rename to docs/guide/backend/multi-site.md diff --git a/docs/docs/guide/backend/notify.md b/docs/guide/backend/notify.md similarity index 100% rename from docs/docs/guide/backend/notify.md rename to docs/guide/backend/notify.md diff --git a/docs/docs/guide/backend/relative-path.md b/docs/guide/backend/relative-path.md similarity index 100% rename from docs/docs/guide/backend/relative-path.md rename to docs/guide/backend/relative-path.md diff --git a/docs/docs/guide/backend/reverse-proxy.md b/docs/guide/backend/reverse-proxy.md similarity index 100% rename from docs/docs/guide/backend/reverse-proxy.md rename to docs/guide/backend/reverse-proxy.md diff --git a/docs/docs/guide/backend/update.md b/docs/guide/backend/update.md similarity index 100% rename from docs/docs/guide/backend/update.md rename to docs/guide/backend/update.md diff --git a/docs/docs/guide/cases.md b/docs/guide/cases.md similarity index 100% rename from docs/docs/guide/cases.md rename to docs/guide/cases.md diff --git a/docs/docs/guide/deploy.md b/docs/guide/deploy.md similarity index 100% rename from docs/docs/guide/deploy.md rename to docs/guide/deploy.md diff --git a/docs/docs/guide/describe.md b/docs/guide/describe.md similarity index 100% rename from docs/docs/guide/describe.md rename to docs/guide/describe.md diff --git a/docs/docs/guide/extras.md b/docs/guide/extras.md similarity index 100% rename from docs/docs/guide/extras.md rename to docs/guide/extras.md diff --git a/docs/docs/guide/frontend/artalk-lite.md b/docs/guide/frontend/artalk-lite.md similarity index 100% rename from docs/docs/guide/frontend/artalk-lite.md rename to docs/guide/frontend/artalk-lite.md diff --git a/docs/docs/guide/frontend/config.md b/docs/guide/frontend/config.md similarity index 100% rename from docs/docs/guide/frontend/config.md rename to docs/guide/frontend/config.md diff --git a/docs/docs/guide/frontend/emoticons.md b/docs/guide/frontend/emoticons.md similarity index 100% rename from docs/docs/guide/frontend/emoticons.md rename to docs/guide/frontend/emoticons.md diff --git a/docs/docs/guide/frontend/i18n.md b/docs/guide/frontend/i18n.md similarity index 100% rename from docs/docs/guide/frontend/i18n.md rename to docs/guide/frontend/i18n.md diff --git a/docs/docs/guide/frontend/import-blog.md b/docs/guide/frontend/import-blog.md similarity index 100% rename from docs/docs/guide/frontend/import-blog.md rename to docs/guide/frontend/import-blog.md diff --git a/docs/docs/guide/frontend/import-framework.md b/docs/guide/frontend/import-framework.md similarity index 100% rename from docs/docs/guide/frontend/import-framework.md rename to docs/guide/frontend/import-framework.md diff --git a/docs/docs/guide/frontend/index.md b/docs/guide/frontend/index.md similarity index 100% rename from docs/docs/guide/frontend/index.md rename to docs/guide/frontend/index.md diff --git a/docs/docs/guide/frontend/install.md b/docs/guide/frontend/install.md similarity index 100% rename from docs/docs/guide/frontend/install.md rename to docs/guide/frontend/install.md diff --git a/docs/docs/guide/frontend/latex.md b/docs/guide/frontend/latex.md similarity index 100% rename from docs/docs/guide/frontend/latex.md rename to docs/guide/frontend/latex.md diff --git a/docs/docs/guide/frontend/lightbox.md b/docs/guide/frontend/lightbox.md similarity index 100% rename from docs/docs/guide/frontend/lightbox.md rename to docs/guide/frontend/lightbox.md diff --git a/docs/docs/guide/frontend/plugs.md b/docs/guide/frontend/plugs.md similarity index 100% rename from docs/docs/guide/frontend/plugs.md rename to docs/guide/frontend/plugs.md diff --git a/docs/docs/guide/frontend/pv.md b/docs/guide/frontend/pv.md similarity index 100% rename from docs/docs/guide/frontend/pv.md rename to docs/guide/frontend/pv.md diff --git a/docs/docs/guide/frontend/sidebar.md b/docs/guide/frontend/sidebar.md similarity index 100% rename from docs/docs/guide/frontend/sidebar.md rename to docs/guide/frontend/sidebar.md diff --git a/docs/docs/guide/intro.md b/docs/guide/intro.md similarity index 100% rename from docs/docs/guide/intro.md rename to docs/guide/intro.md diff --git a/docs/docs/guide/security.md b/docs/guide/security.md similarity index 100% rename from docs/docs/guide/security.md rename to docs/guide/security.md diff --git a/docs/docs/guide/transfer.md b/docs/guide/transfer.md similarity index 100% rename from docs/docs/guide/transfer.md rename to docs/guide/transfer.md diff --git a/docs/docs/images/akismet/1.png b/docs/images/akismet/1.png similarity index 100% rename from docs/docs/images/akismet/1.png rename to docs/images/akismet/1.png diff --git a/docs/docs/images/akismet/2.png b/docs/images/akismet/2.png similarity index 100% rename from docs/docs/images/akismet/2.png rename to docs/images/akismet/2.png diff --git a/docs/docs/images/artalk-go/artalk-go-cache.png b/docs/images/artalk-go/artalk-go-cache.png similarity index 100% rename from docs/docs/images/artalk-go/artalk-go-cache.png rename to docs/images/artalk-go/artalk-go-cache.png diff --git a/docs/docs/images/artalk-logo.png b/docs/images/artalk-logo.png similarity index 100% rename from docs/docs/images/artalk-logo.png rename to docs/images/artalk-logo.png diff --git a/docs/docs/images/baota-proxy/1.png b/docs/images/baota-proxy/1.png similarity index 100% rename from docs/docs/images/baota-proxy/1.png rename to docs/images/baota-proxy/1.png diff --git a/docs/docs/images/baota-proxy/2.png b/docs/images/baota-proxy/2.png similarity index 100% rename from docs/docs/images/baota-proxy/2.png rename to docs/images/baota-proxy/2.png diff --git a/docs/docs/images/baota-proxy/3.png b/docs/images/baota-proxy/3.png similarity index 100% rename from docs/docs/images/baota-proxy/3.png rename to docs/images/baota-proxy/3.png diff --git a/docs/docs/images/baota-supervisor/0.png b/docs/images/baota-supervisor/0.png similarity index 100% rename from docs/docs/images/baota-supervisor/0.png rename to docs/images/baota-supervisor/0.png diff --git a/docs/docs/images/baota-supervisor/1.png b/docs/images/baota-supervisor/1.png similarity index 100% rename from docs/docs/images/baota-supervisor/1.png rename to docs/images/baota-supervisor/1.png diff --git a/docs/docs/images/latex-support/1.png b/docs/images/latex-support/1.png similarity index 100% rename from docs/docs/images/latex-support/1.png rename to docs/images/latex-support/1.png diff --git a/docs/docs/images/notify/bark.png b/docs/images/notify/bark.png similarity index 100% rename from docs/docs/images/notify/bark.png rename to docs/images/notify/bark.png diff --git a/docs/docs/images/notify/lark-1.png b/docs/images/notify/lark-1.png similarity index 100% rename from docs/docs/images/notify/lark-1.png rename to docs/images/notify/lark-1.png diff --git a/docs/docs/images/notify/lark-2.png b/docs/images/notify/lark-2.png similarity index 100% rename from docs/docs/images/notify/lark-2.png rename to docs/images/notify/lark-2.png diff --git a/docs/docs/images/notify/lark-3.png b/docs/images/notify/lark-3.png similarity index 100% rename from docs/docs/images/notify/lark-3.png rename to docs/images/notify/lark-3.png diff --git a/docs/docs/images/notify/tg-1.png b/docs/images/notify/tg-1.png similarity index 100% rename from docs/docs/images/notify/tg-1.png rename to docs/images/notify/tg-1.png diff --git a/docs/docs/images/notify/tg-2.png b/docs/images/notify/tg-2.png similarity index 100% rename from docs/docs/images/notify/tg-2.png rename to docs/images/notify/tg-2.png diff --git a/docs/docs/images/relative-path/1.png b/docs/images/relative-path/1.png similarity index 100% rename from docs/docs/images/relative-path/1.png rename to docs/images/relative-path/1.png diff --git a/docs/docs/images/sidebar/1.png b/docs/images/sidebar/1.png similarity index 100% rename from docs/docs/images/sidebar/1.png rename to docs/images/sidebar/1.png diff --git a/docs/docs/images/sidebar/2.png b/docs/images/sidebar/2.png similarity index 100% rename from docs/docs/images/sidebar/2.png rename to docs/images/sidebar/2.png diff --git a/docs/docs/images/sidebar/3.png b/docs/images/sidebar/3.png similarity index 100% rename from docs/docs/images/sidebar/3.png rename to docs/images/sidebar/3.png diff --git a/docs/docs/images/sidebar/4.png b/docs/images/sidebar/4.png similarity index 100% rename from docs/docs/images/sidebar/4.png rename to docs/images/sidebar/4.png diff --git a/docs/docs/images/sidebar/5.png b/docs/images/sidebar/5.png similarity index 100% rename from docs/docs/images/sidebar/5.png rename to docs/images/sidebar/5.png diff --git a/docs/docs/images/sidebar/6.png b/docs/images/sidebar/6.png similarity index 100% rename from docs/docs/images/sidebar/6.png rename to docs/images/sidebar/6.png diff --git a/docs/docs/images/sidebar/7.png b/docs/images/sidebar/7.png similarity index 100% rename from docs/docs/images/sidebar/7.png rename to docs/images/sidebar/7.png diff --git a/docs/docs/images/sidebar/site_url.png b/docs/images/sidebar/site_url.png similarity index 100% rename from docs/docs/images/sidebar/site_url.png rename to docs/images/sidebar/site_url.png diff --git a/docs/docs/images/transfer/disqus.png b/docs/images/transfer/disqus.png similarity index 100% rename from docs/docs/images/transfer/disqus.png rename to docs/images/transfer/disqus.png diff --git a/docs/docs/images/transfer/leancloud.png b/docs/images/transfer/leancloud.png similarity index 100% rename from docs/docs/images/transfer/leancloud.png rename to docs/images/transfer/leancloud.png diff --git a/docs/docs/images/transfer/tencent-tcb.png b/docs/images/transfer/tencent-tcb.png similarity index 100% rename from docs/docs/images/transfer/tencent-tcb.png rename to docs/images/transfer/tencent-tcb.png diff --git a/docs/docs/images/transfer/wordpress.png b/docs/images/transfer/wordpress.png similarity index 100% rename from docs/docs/images/transfer/wordpress.png rename to docs/images/transfer/wordpress.png diff --git a/docs/docs/index.md b/docs/index.md similarity index 100% rename from docs/docs/index.md rename to docs/index.md diff --git a/docs/package.json b/docs/package.json index 4e4566fc0..a3b5a2a32 100644 --- a/docs/package.json +++ b/docs/package.json @@ -9,13 +9,13 @@ }, "private": true, "scripts": { - "docs:dev": "vitepress dev docs", - "docs:build": "vitepress build docs", - "docs:serve": "vitepress serve docs" + "docs:dev": "vitepress dev", + "docs:build": "vitepress build", + "docs:serve": "vitepress serve" }, "devDependencies": { "markdown-it-for-inline": "^0.1.1", "sass": "^1.52.3", "vitepress": "1.0.0-alpha.1" } -} \ No newline at end of file +} diff --git a/docs/docs/public/assets/emoticons/default.json b/docs/public/assets/emoticons/default.json similarity index 100% rename from docs/docs/public/assets/emoticons/default.json rename to docs/public/assets/emoticons/default.json diff --git a/docs/docs/public/favicon.png b/docs/public/favicon.png similarity index 100% rename from docs/docs/public/favicon.png rename to docs/public/favicon.png From 664a9e07adcf896d4aaf1a5a236b192a5bf00702 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Tue, 17 Jan 2023 19:33:57 +0800 Subject: [PATCH 336/349] chore: rename `artalk.example_zh-CN.yml` to `artalk.example.zh-CN.yml` Signed-off-by: qwqcode --- .github/workflows/docs-cn.yml | 9 ++++++++- artalk.example_simple.yml => artalk.example.simple.yml | 0 artalk.example_zh-CN.yml => artalk.example.zh-CN.yml | 0 3 files changed, 8 insertions(+), 1 deletion(-) rename artalk.example_simple.yml => artalk.example.simple.yml (100%) rename artalk.example_zh-CN.yml => artalk.example.zh-CN.yml (100%) diff --git a/.github/workflows/docs-cn.yml b/.github/workflows/docs-cn.yml index 4e5c98bb4..bf9096821 100644 --- a/.github/workflows/docs-cn.yml +++ b/.github/workflows/docs-cn.yml @@ -7,7 +7,14 @@ on: jobs: deploy: + if: github.repository == 'ArtalkJS/Artalk' + runs-on: ubuntu-latest + + defaults: + run: + working-directory: ./docs # set for building docs + steps: - name: Checkout uses: actions/checkout@v2 @@ -37,6 +44,6 @@ jobs: secret_key: ${{ secrets.TENCENT_CLOUD_SECRET_KEY }} cos_bucket: ${{ secrets.DOCS_CN_COS_BUCKET }} cos_region: ${{ secrets.DOCS_CN_COS_REGION }} - local_path: docs/.vitepress/dist/ + local_path: .vitepress/dist/ remote_path: / clean: true diff --git a/artalk.example_simple.yml b/artalk.example.simple.yml similarity index 100% rename from artalk.example_simple.yml rename to artalk.example.simple.yml diff --git a/artalk.example_zh-CN.yml b/artalk.example.zh-CN.yml similarity index 100% rename from artalk.example_zh-CN.yml rename to artalk.example.zh-CN.yml From e4ffc0bcd1d4a62cce8aa41bbedbfb7abb6dd1ee Mon Sep 17 00:00:00 2001 From: qwqcode Date: Tue, 17 Jan 2023 19:57:19 +0800 Subject: [PATCH 337/349] fix: add `.npmignore` to fix NPM publish inclusion issue Signed-off-by: qwqcode --- .github/workflows/npm.yml | 2 +- ui/packages/artalk/.npmignore | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) create mode 100644 ui/packages/artalk/.npmignore diff --git a/.github/workflows/npm.yml b/.github/workflows/npm.yml index fb66015a4..9a246570c 100644 --- a/.github/workflows/npm.yml +++ b/.github/workflows/npm.yml @@ -40,7 +40,7 @@ jobs: run: pnpm build - name: Publish - run: cd packages/artalk && pnpm publish --no-git-checks + run: pnpm publish -F artalk --no-git-checks env: NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} diff --git a/ui/packages/artalk/.npmignore b/ui/packages/artalk/.npmignore new file mode 100644 index 000000000..4f62e6be9 --- /dev/null +++ b/ui/packages/artalk/.npmignore @@ -0,0 +1,7 @@ +/* +!dist/ +!src/ +!types/ +!package.json +!README.md +!LICENSE From f89f87d92f53ba1875065e83a9b43e664bcad769 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Tue, 17 Jan 2023 20:24:45 +0800 Subject: [PATCH 338/349] fix: docker image build script Signed-off-by: qwqcode --- BACKEND.md | 2 +- README.md | 2 +- docs/README.md | 2 +- scripts/docker-build.sh | 8 +++----- 4 files changed, 6 insertions(+), 8 deletions(-) diff --git a/BACKEND.md b/BACKEND.md index 3a8628937..1921921fa 100644 --- a/BACKEND.md +++ b/BACKEND.md @@ -60,7 +60,7 @@ $ git clone https://github.com/ArtalkJS/Artalk $ cd Artalk # 构建镜像 -$ make docker-docker +$ make docker-build # 发布镜像 $ make docker-push diff --git a/README.md b/README.md index d5f2488dc..a5d6cda59 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ > 🌌 Golang 自托管评论系统 -[English](./README.en.md) / [官方文档](https://artalk.js.org) / [最新后端](https://github.com/ArtalkJS/Artalk/releases) / [Artalk](https://github.com/ArtalkJS/Artalk) +[English](./README.en.md) / [官方文档](https://artalk.js.org) / [最新版本](https://github.com/ArtalkJS/Artalk/releases) --- diff --git a/docs/README.md b/docs/README.md index 7a4aedecb..d8befb42e 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,6 +1,6 @@ ## Artalk Documentation -> the documentation of Artalk +> The Documentation of Artalk ## Build diff --git a/scripts/docker-build.sh b/scripts/docker-build.sh index b31757fc6..6dd5e471e 100755 --- a/scripts/docker-build.sh +++ b/scripts/docker-build.sh @@ -2,17 +2,15 @@ set -e -IMAGE_NAME="artalk" -REPO_NAME="artalk/artalk" - +IMAGE_NAME="artalk/artalk" VERSION=$(git describe --tags --abbrev=0) if [[ $* == *--push* ]] then # tag and push image for tag in {${VERSION},latest}; do - docker image tag ${IMAGE_NAME} ${REPO_NAME}:${tag} - docker push ${REPO_NAME}:${tag} + docker image tag ${IMAGE_NAME} ${IMAGE_NAME}:${tag} + docker push ${IMAGE_NAME}:${tag} done else # build From 342f3d3ad873839bb6c65632bde5f686b61ddb88 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Tue, 17 Jan 2023 20:25:49 +0800 Subject: [PATCH 339/349] chore: merge .gitignore and clean up Signed-off-by: qwqcode --- .gitignore | 27 ++++++++++++++++++---- docs/.editorconfig | 20 ---------------- docs/.gitignore | 6 ----- docs/artalk-banner.png | Bin 0 -> 16783 bytes docs/{artalk.png => artalk-go-banner.png} | Bin ui/.gitignore | 23 ------------------ ui/.travis.yml | 18 --------------- ui/packages/artalk/CNAME | 1 - 8 files changed, 22 insertions(+), 73 deletions(-) delete mode 100644 docs/.editorconfig delete mode 100644 docs/.gitignore create mode 100644 docs/artalk-banner.png rename docs/{artalk.png => artalk-go-banner.png} (100%) delete mode 100644 ui/.gitignore delete mode 100644 ui/.travis.yml delete mode 100644 ui/packages/artalk/CNAME diff --git a/.gitignore b/.gitignore index 732edd431..aa3e295cf 100644 --- a/.gitignore +++ b/.gitignore @@ -32,21 +32,38 @@ Thumbs.db .tmp .env .vscode/*.log -.history .release-env - +*.suo +*.ntvs* +*.njsproj +*.sln .pnpm-store /sysroot +.history + +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +.pnpm-debug.log* + +# frontend node_modules +/ui/**/dist + +# docs +/docs/.vitepress/dist/ +# backend /artalk.yml /config.yml -/local /bin /data -/dist +/local -# always pull latest code and compile +# always compile latest version /public/sidebar /public/dist diff --git a/docs/.editorconfig b/docs/.editorconfig deleted file mode 100644 index 9ea64ee86..000000000 --- a/docs/.editorconfig +++ /dev/null @@ -1,20 +0,0 @@ -root = true - -[*] -charset = utf-8 -end_of_line = lf -insert_final_newline = true -indent_style = space -indent_size = 2 -trim_trailing_whitespace = true - -[*.js] -indent_style = space -indent_size = 2 - -[*.md] -trim_trailing_whitespace = false - -[*.yml] -indent_style = space -indent_size = 2 diff --git a/docs/.gitignore b/docs/.gitignore deleted file mode 100644 index 80eaed10c..000000000 --- a/docs/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -node_modules -.temp -.cache -.DS_Store -.history -docs/.vitepress/dist/ diff --git a/docs/artalk-banner.png b/docs/artalk-banner.png new file mode 100644 index 0000000000000000000000000000000000000000..f9d0a0fbc88950ff36de5a9b9eafe0dbd343e8ef GIT binary patch literal 16783 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 literal 0 HcmV?d00001 diff --git a/docs/artalk.png b/docs/artalk-go-banner.png similarity index 100% rename from docs/artalk.png rename to docs/artalk-go-banner.png diff --git a/ui/.gitignore b/ui/.gitignore deleted file mode 100644 index 83780e9ab..000000000 --- a/ui/.gitignore +++ /dev/null @@ -1,23 +0,0 @@ -.DS_Store -node_modules/ - -# Logs -logs -*.log -npm-debug.log* -yarn-debug.log* -yarn-error.log* -.pnpm-debug.log* - -# Editor directories and files -.idea -.vscode -*.suo -*.ntvs* -*.njsproj -*.sln -.history - -dist -deploy -local diff --git a/ui/.travis.yml b/ui/.travis.yml deleted file mode 100644 index 0125e1f82..000000000 --- a/ui/.travis.yml +++ /dev/null @@ -1,18 +0,0 @@ -language: node_js - -node_js: - - lts/* - -script: - - pnpm run lint - - pnpm run build - -cache: - npm: false - directories: - - "~/.pnpm-store" -before_install: - - curl -fsSL https://get.pnpm.io/install.sh | sh - - - pnpm config set store-dir ~/.pnpm-store -install: - - pnpm install diff --git a/ui/packages/artalk/CNAME b/ui/packages/artalk/CNAME deleted file mode 100644 index de9a7d813..000000000 --- a/ui/packages/artalk/CNAME +++ /dev/null @@ -1 +0,0 @@ -artalk.js.org From 5b73049ac42d88decdd7b16956d44e7bf9f1e776 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Tue, 17 Jan 2023 20:50:31 +0800 Subject: [PATCH 340/349] feat: docker ci add support for building arm64 wheels Signed-off-by: qwqcode --- .github/workflows/dockerhub.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/dockerhub.yml b/.github/workflows/dockerhub.yml index 13bfa498c..c789ed074 100644 --- a/.github/workflows/dockerhub.yml +++ b/.github/workflows/dockerhub.yml @@ -48,11 +48,11 @@ jobs: # 编译多平台 # https://github.com/docker/setup-qemu-action - # - name: Set up QEMU - # id: qemu - # uses: docker/setup-qemu-action@v1 - # with: - # platforms: all + - name: Set up QEMU + id: qemu + uses: docker/setup-qemu-action@v2 + with: + platforms: 'amd64,arm64' # 'all' # 缓存 Docker - name: Cache Docker layers @@ -72,7 +72,7 @@ jobs: builder: ${{ steps.buildx.outputs.name }} context: ./ file: ./Dockerfile - # platforms: linux/amd64,linux/arm64,linux/arm/v7 + platforms: 'linux/amd64,linux/arm64' # ',linux/arm/v7' push: true tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} From 6c896b34aa07475a7721976e8fceb19a70f529cb Mon Sep 17 00:00:00 2001 From: qwqcode Date: Tue, 17 Jan 2023 20:54:10 +0800 Subject: [PATCH 341/349] chore: rename `dockerhub.yml` to `docker.yml` Signed-off-by: qwqcode --- .github/workflows/{dockerhub.yml => docker.yml} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .github/workflows/{dockerhub.yml => docker.yml} (100%) diff --git a/.github/workflows/dockerhub.yml b/.github/workflows/docker.yml similarity index 100% rename from .github/workflows/dockerhub.yml rename to .github/workflows/docker.yml From 90ebd719a05f2a50c23bbeb0d7c5e11a9de55534 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Tue, 17 Jan 2023 21:25:51 +0800 Subject: [PATCH 342/349] docs: add `CODE_OF_CONDUCT.md` Signed-off-by: qwqcode --- CODE_OF_CONDUCT.md | 131 +++++++++++++++++++++++++++ docs/DEVELOPER.md => CONTRIBUTING.md | 0 2 files changed, 131 insertions(+) create mode 100644 CODE_OF_CONDUCT.md rename docs/DEVELOPER.md => CONTRIBUTING.md (100%) diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 000000000..c4ac9b190 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,131 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +We as members, contributors, and leaders pledge to make participation in our +community a harassment-free experience for everyone, regardless of age, body +size, visible or invisible disability, ethnicity, sex characteristics, gender +identity and expression, level of experience, education, socio-economic status, +nationality, personal appearance, race, caste, color, religion, or sexual +identity and orientation. + +We pledge to act and interact in ways that contribute to an open, welcoming, +diverse, inclusive, and healthy community. + +## Our Standards + +Examples of behavior that contributes to a positive environment for our +community include: + +* Demonstrating empathy and kindness toward other people +* Being respectful of differing opinions, viewpoints, and experiences +* Giving and gracefully accepting constructive feedback +* Accepting responsibility and apologizing to those affected by our mistakes, + and learning from the experience +* Focusing on what is best not just for us as individuals, but for the overall + community + +Examples of unacceptable behavior include: + +* The use of sexualized language or imagery, and sexual attention or advances of + any kind +* Trolling, insulting or derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or email address, + without their explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Enforcement Responsibilities + +Community leaders are responsible for clarifying and enforcing our standards of +acceptable behavior and will take appropriate and fair corrective action in +response to any behavior that they deem inappropriate, threatening, offensive, +or harmful. + +Community leaders have the right and responsibility to remove, edit, or reject +comments, commits, code, wiki edits, issues, and other contributions that are +not aligned to this Code of Conduct, and will communicate reasons for moderation +decisions when appropriate. + +## Scope + +This Code of Conduct applies within all community spaces, and also applies when +an individual is officially representing the community in public spaces. +Examples of representing our community include using an official e-mail address, +posting via an official social media account, or acting as an appointed +representative at an online or offline event. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported to the community leaders responsible for enforcement at artalkjs@gmail.com. +All complaints will be reviewed and investigated promptly and fairly. + +All community leaders are obligated to respect the privacy and security of the +reporter of any incident. + +## Enforcement Guidelines + +Community leaders will follow these Community Impact Guidelines in determining +the consequences for any action they deem in violation of this Code of Conduct: + +### 1. Correction + +**Community Impact**: Use of inappropriate language or other behavior deemed +unprofessional or unwelcome in the community. + +**Consequence**: A private, written warning from community leaders, providing +clarity around the nature of the violation and an explanation of why the +behavior was inappropriate. A public apology may be requested. + +### 2. Warning + +**Community Impact**: A violation through a single incident or series of +actions. + +**Consequence**: A warning with consequences for continued behavior. No +interaction with the people involved, including unsolicited interaction with +those enforcing the Code of Conduct, for a specified period of time. This +includes avoiding interactions in community spaces as well as external channels +like social media. Violating these terms may lead to a temporary or permanent +ban. + +### 3. Temporary Ban + +**Community Impact**: A serious violation of community standards, including +sustained inappropriate behavior. + +**Consequence**: A temporary ban from any sort of interaction or public +communication with the community for a specified period of time. No public or +private interaction with the people involved, including unsolicited interaction +with those enforcing the Code of Conduct, is allowed during this period. +Violating these terms may lead to a permanent ban. + +### 4. Permanent Ban + +**Community Impact**: Demonstrating a pattern of violation of community +standards, including sustained inappropriate behavior, harassment of an +individual, or aggression toward or disparagement of classes of individuals. + +**Consequence**: A permanent ban from any sort of public interaction within the +community. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], +version 2.1, available at +[https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1]. + +Community Impact Guidelines were inspired by +[Mozilla's code of conduct enforcement ladder][Mozilla CoC]. + +For answers to common questions about this code of conduct, see the FAQ at +[https://www.contributor-covenant.org/faq][FAQ]. Translations are available at +[https://www.contributor-covenant.org/translations][translations]. + +[homepage]: https://www.contributor-covenant.org +[v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html +[Mozilla CoC]: https://github.com/mozilla/diversity +[FAQ]: https://www.contributor-covenant.org/faq +[translations]: https://www.contributor-covenant.org/translations diff --git a/docs/DEVELOPER.md b/CONTRIBUTING.md similarity index 100% rename from docs/DEVELOPER.md rename to CONTRIBUTING.md From 5c06c1cd881f92b808785dce33ba90fa8f7ea11c Mon Sep 17 00:00:00 2001 From: pluveto Date: Wed, 18 Jan 2023 12:04:27 +0000 Subject: [PATCH 343/349] docs: update CONTRIBUTING.md `make debug-build` --- CONTRIBUTING.md | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c82c2544f..a2b8ea11a 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -35,10 +35,10 @@ $ cd Artalk First, we need to install the dependencies for backend written in Go. Simply run the following command: ```sh -make build +make debug-build ``` -This will build both the frontend and backend. +This will build both the frontend and backend, with debugging symbols. + **Frontend** will be built under `./ui/packages/artalk` and copied to `./public` directory. + **Backend** will be built under `./bin` directory. @@ -51,7 +51,7 @@ If you want to run a demo site, you can use the following command: ./scripts/setup-example-site.sh ``` -This script sets up a local example site for testing, with Artalk integrated. +This script sets up a local example site for testing at `local` folder, with Artalk integrated into its theme. After running this script, run: @@ -62,3 +62,11 @@ After running this script, run: to start the artalk server. And open http://localhost:1313/ in your browser to view the example site. + +Here is the default admin account (only created in test mode): + +``` +name: "admin" +email: "admin@test.com" +password: "admin" +``` \ No newline at end of file From 1419c3231e1e938514b234789ef2095fb83ef0bc Mon Sep 17 00:00:00 2001 From: pluveto Date: Wed, 18 Jan 2023 12:05:16 +0000 Subject: [PATCH 344/349] chore(makefile): add debug-build target --- Makefile | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/Makefile b/Makefile index 0ec6f83ef..1024c073f 100644 --- a/Makefile +++ b/Makefile @@ -26,15 +26,20 @@ build-frontend: run: all $(BIN_NAME) server $(ARGS) -dev: +debug-build: @if [ ! -f "pkged/pkged.go" ]; then \ make install; \ fi + @echo "Building Artalk ${VERSION} for debugging..." @go build \ - -ldflags "-s -w -X github.com/ArtalkJS/Artalk/internal/config.Version=${VERSION} \ - -X github.com/ArtalkJS/Artalk/internal/config.CommitHash=${COMMIT_HASH}" \ - -o $(BIN_NAME) \ - github.com/ArtalkJS/Artalk + -ldflags " \ + -X github.com/ArtalkJS/Artalk/internal/config.Version=${VERSION} \ + -X github.com/ArtalkJS/Artalk/internal/config.CommitHash=${COMMIT_HASH}" \ + -gcflags "all=-N -l" \ + -o $(BIN_NAME) \ + github.com/ArtalkJS/Artalk + +dev: debug-build $(BIN_NAME) server $(ARGS) test: @@ -83,7 +88,7 @@ release: ghcr.io/goreleaser/goreleaser-cross:v${GO_VERSION} \ release --rm-dist --skip-validate -.PHONY: all install build build-frontend \ +.PHONY: all install build debug-build build-frontend \ run dev test test-coverage \ docker-build docker-push \ release-dry-run release; From e1c1b33232f6410f61b820febd821c5eb67d4206 Mon Sep 17 00:00:00 2001 From: pluveto Date: Wed, 18 Jan 2023 12:05:45 +0000 Subject: [PATCH 345/349] feat: launch with vscode debugger --- .vscode/launch.json | 14 ++++++-------- .vscode/tasks.json | 14 ++++++++++++++ 2 files changed, 20 insertions(+), 8 deletions(-) create mode 100644 .vscode/tasks.json diff --git a/.vscode/launch.json b/.vscode/launch.json index a5e93ef13..5b65e6208 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -1,16 +1,14 @@ { - // 使用 IntelliSense 了解相关属性。 - // 悬停以查看现有属性的描述。 - // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387 "version": "0.2.0", "configurations": [ { - "name": "Launch Package", + "name": "Launch Artalk for Debugging", "type": "go", "request": "launch", - "mode": "auto", - "program": "${fileDirname}", - "args": ["server"] + "mode": "exec", + "program": "${workspaceFolder}/bin/artalk", + "preLaunchTask": "Build for debugging", + "args": ["server", "-c", "${workspaceFolder}/local/local.yml"] } - ] + ], } \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 000000000..0adfa5011 --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,14 @@ +{ + "version": "2.0.0", + "tasks": [ + { + "label": "Build for debugging", + "type": "shell", + "command": "make debug-build", + "group": { + "kind": "build", + "isDefault": true + } + } + ] +} \ No newline at end of file From 0f8d3f935a4cc2da0a954d23a0a24d0539bd8460 Mon Sep 17 00:00:00 2001 From: pluveto Date: Wed, 18 Jan 2023 12:30:00 +0000 Subject: [PATCH 346/349] refactor(scripts): double quote to prevent globbing and word splitting --- scripts/docker-build.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/docker-build.sh b/scripts/docker-build.sh index 6dd5e471e..f69ff3e8a 100755 --- a/scripts/docker-build.sh +++ b/scripts/docker-build.sh @@ -9,10 +9,10 @@ if [[ $* == *--push* ]] then # tag and push image for tag in {${VERSION},latest}; do - docker image tag ${IMAGE_NAME} ${IMAGE_NAME}:${tag} - docker push ${IMAGE_NAME}:${tag} + docker image tag "${IMAGE_NAME}" "${IMAGE_NAME}:${tag}" + docker push "${IMAGE_NAME}:${tag}" done else # build - docker image build -t ${IMAGE_NAME} . + docker image build -t "${IMAGE_NAME}" . fi From bfceff644640e281388d15e17e0f2e9520280007 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Wed, 18 Jan 2023 21:18:05 +0800 Subject: [PATCH 347/349] feat(i18n): add i18n support for backend (#343) Signed-off-by: qwqcode --- Makefile | 3 + artalk.example.simple.yml | 2 +- artalk.example.yml | 4 +- artalk.example.zh-CN.yml | 3 + go.mod | 2 +- i18n/en.yml | 3 + i18n/zh-CN.yml | 3 + internal/config/config.go | 1 + internal/core/core.go | 6 ++ internal/i18n/gen/main.go | 143 +++++++++++++++++++++++++++++++ internal/i18n/i18n.go | 45 ++++++++++ main.go | 1 + server/middleware/site_origin.go | 5 +- 13 files changed, 216 insertions(+), 5 deletions(-) create mode 100644 i18n/en.yml create mode 100644 i18n/zh-CN.yml create mode 100644 internal/i18n/gen/main.go create mode 100644 internal/i18n/i18n.go diff --git a/Makefile b/Makefile index 1024c073f..7a3cd8f49 100644 --- a/Makefile +++ b/Makefile @@ -48,6 +48,9 @@ test: test-coverage: $(GOTEST) -cover ./... +update-i18n: + go generate ./internal/i18n + docker-build: ./scripts/docker-build.sh diff --git a/artalk.example.simple.yml b/artalk.example.simple.yml index 62d09e55f..1c04d662c 100644 --- a/artalk.example.simple.yml +++ b/artalk.example.simple.yml @@ -2,6 +2,7 @@ host: "0.0.0.0" port: 23366 app_key: "" debug: false +locale: "en" timezone: "Asia/Shanghai" site_default: "Default Site" login_timeout: 259200 @@ -15,7 +16,6 @@ db: user: "root" password: "" charset: "utf8mb4" - log: enabled: true filename: "./data/artalk.log" diff --git a/artalk.example.yml b/artalk.example.yml index f3882b005..43a7111ee 100644 --- a/artalk.example.yml +++ b/artalk.example.yml @@ -6,7 +6,9 @@ port: 23366 app_key: "" # Debug mode debug: false -# Timezone. See https://en.wikipedia.org/wiki/List_of_tz_database_time_zones +# Language (follow Unicode BCP 47) +locale: "en" +# Timezone (see https://en.wikipedia.org/wiki/List_of_tz_database_time_zones) timezone: "Asia/Shanghai" # Default site name site_default: "Default Site" diff --git a/artalk.example.zh-CN.yml b/artalk.example.zh-CN.yml index ddd0e5e89..b685ad2ba 100644 --- a/artalk.example.zh-CN.yml +++ b/artalk.example.zh-CN.yml @@ -10,6 +10,9 @@ app_key: "" # 调试模式 debug: false +# 语言 +locale: "zh-CN" + # 时间区域 timezone: "Asia/Shanghai" diff --git a/go.mod b/go.mod index 88f2b13eb..9d2d2a4c4 100644 --- a/go.mod +++ b/go.mod @@ -42,6 +42,7 @@ require ( golang.org/x/sync v0.1.0 golang.org/x/term v0.3.0 gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df + gopkg.in/yaml.v3 v3.0.1 gorm.io/driver/mysql v1.4.5 gorm.io/driver/postgres v1.4.6 gorm.io/driver/sqlite v1.4.4 @@ -130,5 +131,4 @@ require ( google.golang.org/protobuf v1.28.1 // indirect gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect gopkg.in/ini.v1 v1.67.0 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/i18n/en.yml b/i18n/en.yml new file mode 100644 index 000000000..4873cd4d2 --- /dev/null +++ b/i18n/en.yml @@ -0,0 +1,3 @@ +"Invalid request": +"Please check trusted_domains config": +"Unable to get Origin": diff --git a/i18n/zh-CN.yml b/i18n/zh-CN.yml new file mode 100644 index 000000000..16a0fd130 --- /dev/null +++ b/i18n/zh-CN.yml @@ -0,0 +1,3 @@ +"Invalid request": 无效请求 +"Please check trusted_domains config": 请检查可信域名配置 +"Unable to get Origin": 无法获取 Origin diff --git a/internal/config/config.go b/internal/config/config.go index ae64c5ea3..2a37016b1 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -7,6 +7,7 @@ import "time" type Config struct { AppKey string `koanf:"app_key" json:"app_key"` // 加密密钥 Debug bool `koanf:"debug" json:"debug"` // 调试模式 + Locale string `koanf:"locale" json:"locale"` // 语言 TimeZone string `koanf:"timezone" json:"timezone"` // 时区 Host string `koanf:"host" json:"host"` // HTTP Server 监听 IP Port int `koanf:"port" json:"port"` // HTTP Server 监听 Port diff --git a/internal/core/core.go b/internal/core/core.go index b546ea4fe..130920179 100644 --- a/internal/core/core.go +++ b/internal/core/core.go @@ -8,6 +8,7 @@ import ( "github.com/ArtalkJS/Artalk/internal/cache" "github.com/ArtalkJS/Artalk/internal/config" "github.com/ArtalkJS/Artalk/internal/db" + "github.com/ArtalkJS/Artalk/internal/i18n" "github.com/ArtalkJS/Artalk/internal/notify_launcher" "github.com/rifflock/lfshook" @@ -26,6 +27,7 @@ func LoadCore(cfgFile string, workDir string) { firstLoad = false initConfig(cfgFile, workDir) + initI18n() initLog() initCache() initDB() @@ -75,6 +77,10 @@ func initConfig(cfgFile string, workDir string) { config.Init(cfgFile) } +func initI18n() { + i18n.Init(config.Instance.Locale) +} + // 2. 初始化日志 func initLog() { logrus.New() diff --git a/internal/i18n/gen/main.go b/internal/i18n/gen/main.go new file mode 100644 index 000000000..2f63910d4 --- /dev/null +++ b/internal/i18n/gen/main.go @@ -0,0 +1,143 @@ +package main + +import ( + "flag" + "fmt" + "go/ast" + "go/parser" + "go/token" + "io" + "os" + "path/filepath" + "sort" + "strings" + "time" +) + +var ( + workDir string + scanDirs string + outputFile string +) + +func init() { + flag.StringVar(&workDir, "w", "", "specify work directory") + flag.StringVar(&scanDirs, "d", "./internal", "specify which directory to scan") + flag.StringVar(&outputFile, "o", "./i18n/en.yml", "specify output filename") +} + +func main() { + flag.Parse() + + if workDir != "" { + if err := os.Chdir(workDir); err != nil { + panic(err) + } + } + + // Initialize an empty map to store the keys + keys := make(map[string]bool) + + for _, dir := range strings.Split(scanDirs, ",") { + for _, k := range scan(strings.TrimSpace(dir)) { + // Add the key to the map if it doesn't already exist + if !keys[k] { + keys[k] = true + } + } + } + + // Use the sort package to sort the keys alphabetically + var keysSlice []string + for key := range keys { + keysSlice = append(keysSlice, key) + } + sort.Strings(keysSlice) + + // Use the ioutil package to write the keys to the YAML file + content := "" + for _, key := range keysSlice { + content += fmt.Sprintf("%s:\n", key) + } + err := os.WriteFile(outputFile, []byte(content), 0644) + if err != nil { + panic(err) + } +} + +func scan(dir string) []string { + result := []string{} + + // Use the os package to search for Go files recursively + err := filepath.Walk(dir, func(path string, info os.FileInfo, err error) error { + if !info.IsDir() && strings.HasSuffix(path, ".go") { + start := time.Now() + + file, err := os.Open(path) + if err != nil { + return err + } + defer file.Close() + + buf, err := io.ReadAll(file) + if err != nil { + return err + } + + codeStr := string(buf) + if !strings.Contains(codeStr, "i18n.T") { + return nil + } + + extKeys := extractFormCode(codeStr) + + if len(extKeys) > 0 { + result = append(result, extKeys...) + duration := time.Since(start) + fmt.Printf("found %d msgs in `%s` (duration: %v)\n", len(extKeys), path, duration) + } + } + + return nil + }) + + if err != nil { + panic(err) + } + + return result +} + +func extractFormCode(src string) []string { + fileSet := token.NewFileSet() + f, err := parser.ParseFile(fileSet, "", src, 0) + if err != nil { + panic(err) + } + + var i18nKeySet []string + ast.Inspect(f, func(n ast.Node) bool { + call, ok := n.(*ast.CallExpr) + if !ok { + return true + } + + if fun, ok := call.Fun.(*ast.SelectorExpr); ok { + if fun.Sel.Name != "T" { + return true + } + if ident, ok := fun.X.(*ast.Ident); ok { + if ident.Name != "i18n" { + return true + } + if lit, ok := call.Args[0].(*ast.BasicLit); ok { + i18nKeySet = append(i18nKeySet, lit.Value) + return true + } + } + } + return true + }) + + return i18nKeySet +} diff --git a/internal/i18n/i18n.go b/internal/i18n/i18n.go new file mode 100644 index 000000000..41c29041f --- /dev/null +++ b/internal/i18n/i18n.go @@ -0,0 +1,45 @@ +package i18n + +import ( + "fmt" + "strings" + + "github.com/ArtalkJS/Artalk/internal/pkged" + "github.com/sirupsen/logrus" + "gopkg.in/yaml.v3" +) + +//go:generate go run ./gen -w ../../ -d internal,server,cmd -o i18n/en.yml + +var Locales map[string]string + +func Init(locale string) { + if locale == "" { + locale = "en" + } + + yamlStr, err := pkged.FS().ReadFile(fmt.Sprintf("i18n/%s.yml", locale)) + if err != nil { + logrus.Warn("invalid locale config please check, now it is set to `en`") + Init("en") + return + } + + yaml.Unmarshal(yamlStr, &Locales) +} + +func T(msg string, params ...interface{}) string { + v, ok := Locales[msg] + if !ok || v == "" { + v = msg + } + return msgParams(v, params...) +} + +func msgParams(msg string, params ...interface{}) string { + if strings.Contains(msg, "%") { + msg = fmt.Sprintf(msg, params...) + } + + return msg +} diff --git a/main.go b/main.go index c5ed4fcca..bd378e3e5 100644 --- a/main.go +++ b/main.go @@ -8,6 +8,7 @@ import ( ) //go:embed public/* +//go:embed i18n/* //go:embed artalk.example.yml var embedFS embed.FS diff --git a/server/middleware/site_origin.go b/server/middleware/site_origin.go index 83f3ee2a4..29fc491d5 100644 --- a/server/middleware/site_origin.go +++ b/server/middleware/site_origin.go @@ -8,6 +8,7 @@ import ( "github.com/ArtalkJS/Artalk/internal/config" "github.com/ArtalkJS/Artalk/internal/entity" + "github.com/ArtalkJS/Artalk/internal/i18n" "github.com/ArtalkJS/Artalk/internal/query" "github.com/ArtalkJS/Artalk/internal/utils" "github.com/ArtalkJS/Artalk/server/common" @@ -104,7 +105,7 @@ func CheckOrigin(c *fiber.Ctx, allowSite *entity.Site) (bool, error) { // 从 Referer 获取 Origin referer := string(c.Request().Header.Referer()) if referer == "" { - return false, common.RespError(c, "无效请求,Origin 无法获取") + return false, common.RespError(c, i18n.T("Invalid request")+", "+i18n.T("Unable to get Origin")) } origin = referer } @@ -122,7 +123,7 @@ func CheckOrigin(c *fiber.Ctx, allowSite *entity.Site) (bool, error) { return true, nil } - return false, common.RespError(c, "非法请求,请检查可信域名配置") + return false, common.RespError(c, i18n.T("Invalid request")+", "+i18n.T("Please check trusted_domains config")) } // 判断 Origin 是否被允许 From 891246a672dc3f77309df1af9b3463926bbc7644 Mon Sep 17 00:00:00 2001 From: pluveto Date: Thu, 19 Jan 2023 02:17:29 +0000 Subject: [PATCH 348/349] docs: add translation section to `CONTRIBUTING.md` --- CONTRIBUTING.md | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index a2b8ea11a..ab352443c 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -18,7 +18,7 @@ Then we'll setup the development environment. Run the following command to clone the repository: ```sh -$ git clone https://github.com/ArtalkJS/Artalk +git clone https://github.com/ArtalkJS/Artalk ``` It is recommended to fork the repository first, and then clone the forked repository. @@ -26,10 +26,9 @@ It is recommended to fork the repository first, and then clone the forked reposi Enter the directory: ```sh -$ cd Artalk +cd Artalk ``` - ### Build frontend and backend First, we need to install the dependencies for backend written in Go. Simply run the following command: @@ -40,8 +39,8 @@ make debug-build This will build both the frontend and backend, with debugging symbols. -+ **Frontend** will be built under `./ui/packages/artalk` and copied to `./public` directory. -+ **Backend** will be built under `./bin` directory. +- **Frontend** will be built under `./ui/packages/artalk` and copied to `./public` directory. +- **Backend** will be built under `./bin` directory. ### Optional: Use one-key script to run a demo site @@ -61,12 +60,24 @@ After running this script, run: to start the artalk server. -And open http://localhost:1313/ in your browser to view the example site. +And open in your browser to view the example site. Here is the default admin account (only created in test mode): -``` +```yaml name: "admin" email: "admin@test.com" password: "admin" -``` \ No newline at end of file +``` + +## Translation + +Artalk aims to be a multilingual project. If you would like to contribute to the translation, here are some tips: + +If you just write some new features or do some fixes/refactoring, use the following command to generate the translation template + +```sh +go run ./internal/i18n/gen -w . -d . +``` + +If you're not a programmer and would like to help us improve the translation, you can edit the translation files directly in the `.i18n' directory and then submit a pull request. From 1ca892fc2d16b2a50fbfcad5093a0f1522fcc174 Mon Sep 17 00:00:00 2001 From: qwqcode Date: Thu, 19 Jan 2023 20:11:36 +0800 Subject: [PATCH 349/349] feat(i18n): translations for backend (#344) * i18n: add i18n for server pacakge Signed-off-by: qwqcode * i18n: add i18n for cmd pacakge Signed-off-by: qwqcode * feat: add mustache syntax support for i18n.T in backend Signed-off-by: qwqcode * i18n: improve i18n for backend further Signed-off-by: qwqcode * i18n: `zh-CN` translation for backend Signed-off-by: qwqcode Signed-off-by: qwqcode --- cmd/admin.go | 23 +- cmd/export.go | 12 +- cmd/gen.go | 10 +- cmd/import.go | 20 +- cmd/root.go | 20 +- cmd/server.go | 8 +- cmd/upgrade.go | 19 +- cmd/utils.go | 2 +- i18n/en.yml | 76 +++- i18n/zh-CN.yml | 78 +++- internal/anti_spam/anti_spam.go | 12 +- internal/anti_spam/anti_spam_akismet.go | 6 +- internal/anti_spam/anti_spam_aliyun.go | 4 +- internal/anti_spam/anti_spam_tencent.go | 4 +- internal/artransfer/artrans.go | 29 +- internal/artransfer/example.go | 2 +- internal/artransfer/importer.go | 28 +- internal/cache/actions.go | 4 +- internal/cache/cache.go | 2 +- internal/captcha/geetest.go | 6 +- internal/config/init.go | 18 +- internal/core/core.go | 4 +- internal/core/gen.go | 13 +- internal/db/db.go | 6 +- internal/email/queue.go | 2 +- internal/email/render.go | 416 ++++++++++---------- internal/email/sender_alidm.go | 2 +- internal/email/sender_smtp.go | 2 +- internal/i18n/gen/main.go | 4 +- internal/i18n/i18n.go | 10 +- internal/notify_launcher/notify_launcher.go | 6 +- internal/query/service.go | 8 +- internal/utils/template.go | 25 ++ server/common/check.go | 3 +- server/handler/admin_cache.go | 11 +- server/handler/admin_comment_del.go | 9 +- server/handler/admin_comment_edit.go | 11 +- server/handler/admin_page_del.go | 7 +- server/handler/admin_page_edit.go | 11 +- server/handler/admin_page_fetch.go | 13 +- server/handler/admin_page_get.go | 3 +- server/handler/admin_send_mail.go | 3 +- server/handler/admin_setting.go | 15 +- server/handler/admin_site_add.go | 11 +- server/handler/admin_site_del.go | 7 +- server/handler/admin_site_edit.go | 13 +- server/handler/admin_transfer.go | 17 +- server/handler/admin_user_add.go | 13 +- server/handler/admin_user_del.go | 7 +- server/handler/admin_user_edit.go | 13 +- server/handler/admin_user_get.go | 3 +- server/handler/admin_vote_sync.go | 3 +- server/handler/captcha.go | 11 +- server/handler/comment_add.go | 19 +- server/handler/img_upload.go | 29 +- server/handler/mark_read.go | 7 +- server/handler/stat.go | 3 +- server/handler/user_login.go | 9 +- server/handler/user_logout.go | 4 +- server/handler/utils.go | 3 + server/handler/vote.go | 5 +- server/middleware/admin.go | 3 +- server/middleware/limit.go | 3 +- server/middleware/site_origin.go | 16 +- server/server.go | 2 +- 65 files changed, 685 insertions(+), 483 deletions(-) create mode 100644 internal/utils/template.go create mode 100644 server/handler/utils.go diff --git a/cmd/admin.go b/cmd/admin.go index 3631cd225..b8dc314d8 100644 --- a/cmd/admin.go +++ b/cmd/admin.go @@ -10,6 +10,7 @@ import ( "github.com/ArtalkJS/Artalk/internal/core" "github.com/ArtalkJS/Artalk/internal/entity" + "github.com/ArtalkJS/Artalk/internal/i18n" "github.com/ArtalkJS/Artalk/internal/query" "github.com/ArtalkJS/Artalk/internal/utils" "github.com/sirupsen/logrus" @@ -19,14 +20,13 @@ import ( var adminCmd = &cobra.Command{ Use: "admin", - Short: "创建管理员账号", - Long: "根据提示创建管理员账号", + Short: "Create or edit an administrator account", Args: cobra.NoArgs, Run: func(cmd *cobra.Command, args []string) { core.LoadCore(cfgFile, workDir) fmt.Println("--------------------------------") - fmt.Println(" 管理员账户创建 ") + fmt.Println(" " + i18n.T("Create admin account")) fmt.Println("--------------------------------") username, email, password, err := credentials() @@ -41,7 +41,8 @@ var adminCmd = &cobra.Command{ logrus.Fatal(err) } - logrus.Info("该账户已存在,密码修改成功") + logrus.Info(i18n.T("{{name}} already exists", map[string]interface{}{"name": i18n.T("Account")}) + + ", " + i18n.T("Password updated")) return } @@ -49,7 +50,7 @@ var adminCmd = &cobra.Command{ Name: username, Email: email, IsAdmin: true, - BadgeName: "管理员", + BadgeName: i18n.T("Admin"), BadgeColor: "#FF6C00", } user.SetPasswordEncrypt(password) @@ -72,29 +73,29 @@ func init() { func credentials() (string, string, string, error) { reader := bufio.NewReader(os.Stdin) - fmt.Print("Enter Username: ") + fmt.Print(i18n.T("Enter {{name}}", map[string]interface{}{"name": i18n.T("Username")}) + ": ") username, err := reader.ReadString('\n') if err != nil { return "", "", "", err } - fmt.Print("Enter Email: ") + fmt.Print(i18n.T("Enter {{name}}", map[string]interface{}{"name": i18n.T("Email")}) + ": ") email, err := reader.ReadString('\n') if err != nil { return "", "", "", err } if !utils.ValidateEmail(strings.TrimSpace(email)) { - return "", "", "", errors.New("邮箱格式不合法") + return "", "", "", errors.New("invalid email format") } - fmt.Print("Enter Password: ") + fmt.Print(i18n.T("Enter {{name}}", map[string]interface{}{"name": i18n.T("Password")}) + ": ") bytePassword, err := term.ReadPassword(int(syscall.Stdin)) if err != nil { return "", "", "", err } fmt.Println() - fmt.Print("Retype Password: ") + fmt.Print(i18n.T("Retype {{name}}", map[string]interface{}{"name": i18n.T("Password")}) + ": " + ": ") byteRePassword, err := term.ReadPassword(int(syscall.Stdin)) if err != nil { return "", "", "", err @@ -106,7 +107,7 @@ func credentials() (string, string, string, error) { rePassword := strings.TrimSpace(string(byteRePassword)) if rePassword != password { - return "", "", "", errors.New("输入的密码不一致") + return "", "", "", errors.New("inconsistent password input") } return strings.TrimSpace(username), strings.TrimSpace(email), password, nil diff --git a/cmd/export.go b/cmd/export.go index 456d38184..06a781ecc 100644 --- a/cmd/export.go +++ b/cmd/export.go @@ -9,6 +9,7 @@ import ( "github.com/ArtalkJS/Artalk/internal/artransfer" "github.com/ArtalkJS/Artalk/internal/core" + "github.com/ArtalkJS/Artalk/internal/i18n" "github.com/ArtalkJS/Artalk/internal/utils" "github.com/sirupsen/logrus" "github.com/spf13/cobra" @@ -17,13 +18,10 @@ import ( var exportCmd = &cobra.Command{ Use: "export", Aliases: []string{}, - Short: "数据迁移 - 迁出", - Long: "\n# 数据迁移 - 迁出\n\n 将所有数据从 Artalk 导出,用作备份,或迁移至其他地方\n 打包所有数据并导出成 “Artalk 数据行囊 (Artrans)”,为数据迁移做准备\n" + ` -- 重新导入 Artalk,可执行: artalk import <数据行囊文件路径> -- 文档:https://artalk.js.org/guide/transfer.html -`, + Short: "Artransfer - Export", + Long: "\n# Artransfer - Export\n\n See the documentation to learn more: https://artalk.js.org/guide/transfer.html", Run: func(cmd *cobra.Command, args []string) { - core.LoadCore(cfgFile, workDir) // 装载核心 + core.LoadCore(cfgFile, workDir) jsonStr, err := artransfer.ExportArtransString() if err != nil { @@ -67,7 +65,7 @@ var exportCmd = &cobra.Command{ logrus.Fatal(err2) } - logrus.Info("已导出 Artrans 文件:" + filename) + logrus.Info(i18n.T("Export complete") + ": " + filename) } }, } diff --git a/cmd/gen.go b/cmd/gen.go index 8a3a8a4cc..6cc72d6cf 100644 --- a/cmd/gen.go +++ b/cmd/gen.go @@ -9,15 +9,15 @@ import ( ) var genCmd = &cobra.Command{ - Use: "gen <类型> <目标路径>", - Short: "生成一些内容", - Long: "生成一些内容\n例如:artalk gen config ./artalk.yml", + Use: "gen ", + Short: "A collection of several useful generators", + Long: "Generate some content\ne.g. `artalk gen config ./artalk.yml`", Args: cobra.RangeArgs(1, 2), Run: func(cmd *cobra.Command, args []string) { - // 工作目录 + // change working directory if workDir != "" { if err := os.Chdir(workDir); err != nil { - logrus.Fatal("工作目录切换错误 ", err) + logrus.Fatal("change working directory error ", err) } } diff --git a/cmd/import.go b/cmd/import.go index fc470e06a..8267d834f 100644 --- a/cmd/import.go +++ b/cmd/import.go @@ -6,34 +6,32 @@ import ( "github.com/ArtalkJS/Artalk/internal/artransfer" "github.com/ArtalkJS/Artalk/internal/core" + "github.com/ArtalkJS/Artalk/internal/i18n" "github.com/sirupsen/logrus" "github.com/spf13/cobra" ) var importCmd = &cobra.Command{ - Use: "import <数据行囊文件路径>", + Use: "import ", Aliases: []string{}, - Short: "数据迁移 - 迁入", - Long: "\n# 数据迁移 - 迁入\n\n 从其他评论系统迁移数据到 Artalk\n" + ` -- 导入前需要使用转换工具 Artransfer 将其他评论数据转为 Artrans 格式 -- 文档:https://artalk.js.org/guide/transfer.html -`, - Args: cobra.MinimumNArgs(1), + Short: "Artransfer - Import", + Long: "\n# Artransfer - Import\n\n See the documentation to learn more: https://artalk.js.org/guide/transfer.html", + Args: cobra.MinimumNArgs(1), Run: func(cmd *cobra.Command, args []string) { - core.LoadCore(cfgFile, workDir) // 装载核心 + core.LoadCore(cfgFile, workDir) // load core parcelFile := args[0] if _, err := os.Stat(parcelFile); errors.Is(err, os.ErrNotExist) { - logrus.Fatal("`数据行囊` 文件不存在,请检查路径是否正确") + logrus.Fatal(i18n.T("{{name}} not found", map[string]interface{}{"name": i18n.T("File")})) } payload := args[1:] payload = append(payload, "json_file:"+parcelFile) - // 导入 Artrans + // import Artrans artransfer.RunImportArtrans(payload) - logrus.Info("导入结束") + logrus.Info(i18n.T("Import complete")) }, } diff --git a/cmd/root.go b/cmd/root.go index 14d90bd30..244c2937e 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -12,14 +12,14 @@ import ( var Version = config.Version + `/` + config.CommitHash var Banner = ` - ________ ________ _________ ________ ___ ___ __ -|\ __ \|\ __ \|\___ ___\\ __ \|\ \ |\ \|\ \ -\ \ \|\ \ \ \|\ \|___ \ \_\ \ \|\ \ \ \ \ \ \/ /|_ - \ \ __ \ \ _ _\ \ \ \ \ \ __ \ \ \ \ \ ___ \ - \ \ \ \ \ \ \\ \| \ \ \ \ \ \ \ \ \ \____\ \ \\ \ \ + ________ ________ _________ ________ ___ ___ __ +|\ __ \|\ __ \|\___ ___\\ __ \|\ \ |\ \|\ \ +\ \ \|\ \ \ \|\ \|___ \ \_\ \ \|\ \ \ \ \ \ \/ /|_ + \ \ __ \ \ _ _\ \ \ \ \ \ __ \ \ \ \ \ ___ \ + \ \ \ \ \ \ \\ \| \ \ \ \ \ \ \ \ \ \____\ \ \\ \ \ \ \__\ \__\ \__\\ _\ \ \__\ \ \__\ \__\ \_______\ \__\\ \__\ \|__|\|__|\|__|\|__| \|__| \|__|\|__|\|_______|\|__| \|__| - + Artalk (` + Version + `) -> A Selfhosted Comment System. @@ -49,13 +49,13 @@ func Execute() { func init() { rootCmd.SetVersionTemplate("Artalk ({{printf \"%s\" .Version}})\n") - rootCmd.PersistentFlags().StringVarP(&cfgFile, "config", "c", "", "配置文件路径 (defaults are './artalk.yml')") - rootCmd.PersistentFlags().StringVarP(&workDir, "workdir", "w", "", "程序工作目录 (defaults are './')") + rootCmd.PersistentFlags().StringVarP(&cfgFile, "config", "c", "", "config file path (defaults are './artalk.yml')") + rootCmd.PersistentFlags().StringVarP(&workDir, "workdir", "w", "", "program working directory (defaults are './')") // Version Command versionCmd := &cobra.Command{ Use: "version", - Short: "输出版本信息", + Short: "Output Version Information", Run: func(cmd *cobra.Command, args []string) { fmt.Println("Artalk (" + Version + ")") }, @@ -65,7 +65,7 @@ func init() { // Config Command configCmd := &cobra.Command{ Use: "config", - Short: "输出配置信息", + Short: "Output Config Information", Run: func(cmd *cobra.Command, args []string) { core.LoadConfOnly(cfgFile, workDir) buf, _ := json.MarshalIndent(config.Instance, "", " ") diff --git a/cmd/server.go b/cmd/server.go index 5c2088a2a..0f0675988 100644 --- a/cmd/server.go +++ b/cmd/server.go @@ -16,11 +16,11 @@ import ( var serverCmd = &cobra.Command{ Use: "server", Aliases: []string{"serve"}, - Short: "启动服务器", + Short: "Start the server", Long: Banner, Args: cobra.NoArgs, Run: func(cmd *cobra.Command, args []string) { - core.LoadCore(cfgFile, workDir) // 装载核心 + core.LoadCore(cfgFile, workDir) fmt.Println(Banner) fmt.Print("-------------------------------\n\n") @@ -62,6 +62,6 @@ var serverCmd = &cobra.Command{ func init() { rootCmd.AddCommand(serverCmd) - flagPV(serverCmd, "host", "", "0.0.0.0", "监听 IP") - flagPV(serverCmd, "port", "", 23366, "监听端口") + flagPV(serverCmd, "host", "", "0.0.0.0", "Listening IP") + flagPV(serverCmd, "port", "", 23366, "Listening port") } diff --git a/cmd/upgrade.go b/cmd/upgrade.go index 934d3dd0a..c27e5cd2f 100644 --- a/cmd/upgrade.go +++ b/cmd/upgrade.go @@ -7,6 +7,7 @@ import ( "github.com/ArtalkJS/Artalk/internal/config" "github.com/ArtalkJS/Artalk/internal/core" + "github.com/ArtalkJS/Artalk/internal/i18n" "github.com/blang/semver" "github.com/rhysd/go-github-selfupdate/selfupdate" "github.com/sirupsen/logrus" @@ -16,14 +17,14 @@ import ( var upgradeCmd = &cobra.Command{ Use: "upgrade", Aliases: []string{"update"}, - Short: "升级到最新版", - Long: "将 Artalk 升级到最新版本,\n更新源为 GitHub Releases,\n更新需要重启 Artalk 才能生效。", + Short: "Upgrade to the latest version", + Long: "Upgrade Artalk to the latest version, \n update source is GitHub Releases, \n update need to restart Artalk to take effect.", Args: cobra.NoArgs, Run: func(cmd *cobra.Command, args []string) { - // loadCore() // 装载核心 + // loadCore() core.LoadConfOnly(cfgFile, workDir) - logrus.Info("从 GitHub Release 检索更新中...") + logrus.Info(i18n.T("Checking for updates") + "...") latest, found, err := selfupdate.DetectLatest("ArtalkJS/Artalk") if err != nil { @@ -34,13 +35,13 @@ var upgradeCmd = &cobra.Command{ if !ignoreVersionCheck { v := semver.MustParse(strings.TrimPrefix(config.Version, "v")) if !found || latest.Version.LTE(v) { - logrus.Println("当前已是最新版本 v" + v.String() + " 无需升级") + logrus.Println(i18n.T("Current version is the latest") + " (v" + v.String() + ")") return } } - logrus.Info("发现新版本: v" + latest.Version.String()) - logrus.Info("正在下载更新中...") + logrus.Info(i18n.T("New version available") + ": v" + latest.Version.String()) + logrus.Info(i18n.T("Downloading") + "...") exe, err := os.Executable() if err != nil { @@ -48,10 +49,10 @@ var upgradeCmd = &cobra.Command{ } if err := selfupdate.UpdateTo(latest.AssetURL, exe); err != nil { - logrus.Fatal("更新失败 ", err) + logrus.Fatal(i18n.T("Update failed")+" ", err) } - logrus.Println("更新完毕") + logrus.Println(i18n.T("Update complete")) fmt.Println("\n-------------------------------\n v" + latest.Version.String() + " Release Note\n" + diff --git a/cmd/utils.go b/cmd/utils.go index 2f19df90b..9a84b663d 100644 --- a/cmd/utils.go +++ b/cmd/utils.go @@ -4,7 +4,7 @@ import ( "github.com/spf13/cobra" ) -//// 捷径函数 //// +//// Shortcut Functions //// func flag(cmd *cobra.Command, name string, defaultVal interface{}, usage string) { f := cmd.PersistentFlags() diff --git a/i18n/en.yml b/i18n/en.yml index 4873cd4d2..383c27632 100644 --- a/i18n/en.yml +++ b/i18n/en.yml @@ -1,3 +1,75 @@ +"Access denied": +"Account": +"Admin access required": +"Admin": +"Cannot reply to this comment": +"Captcha required": +"Checking for updates": +"Comment count": +"Comment failed": +"Comment": +"Config file read failed": +"Confirm to continue?": +"Contains invalid URL": +"Create admin account": +"Current version is the latest": +"Downloading": +"Email": +"Enter {{name}}": +"Export complete": +"Export error": +"File": +"First comment": +"Image exceeds {{file_size}} limit": +"Image upload forbidden": +"Import complete": "Invalid request": -"Please check trusted_domains config": -"Unable to get Origin": +"Invalid request. Please check your `trusted_domains` config.": +"Invalid {{name}}": +"Link": +"Login failed": +"Name": +"New version available": +"Nickname": +"No comment": +"Notify": +"Page fetch failed": +"Page": +"Parameter": +"Parent comment": +"Password update failed": +"Password updated": +"Password": +"Please review": +"Retype {{name}}": +"Save failed": +"Saving": +"Services restart complete": +"Site `{{name}}` not found. Please create it in control center.": +"Site": +"Sub-comment": +"Target Site": +"Task executing in background, please wait...": +"Task in progress, please wait a moment": +"Type": +"URL Resolver": +"Unable to get `{{name}}`": +"Unspecified": +"Unsupported formats": +"Update complete": +"Update failed": +"Upload image via {{method}} failed": +"User": +"Username": +"Verification failed": +"Working directory retrieval failed": +"Wrong captcha": +"{{count}} items imported": +"{{done}} of {{total}} done": +"{{name}} already exists": +"{{name}} cannot be empty": +"{{name}} creation failed": +"{{name}} deletion failed": +"{{name}} is required": +"{{name}} not found": +"{{name}} save failed": diff --git a/i18n/zh-CN.yml b/i18n/zh-CN.yml index 16a0fd130..5156de06a 100644 --- a/i18n/zh-CN.yml +++ b/i18n/zh-CN.yml @@ -1,3 +1,75 @@ -"Invalid request": 无效请求 -"Please check trusted_domains config": 请检查可信域名配置 -"Unable to get Origin": 无法获取 Origin +"Access denied": 无权限 +"Account": 账户 +"Admin access required": 需要管理员权限 +"Admin": 管理员 +"Cannot reply to this comment": 无法回复此评论 +"Captcha required": 需要验证码 +"Checking for updates": 正在检查更新 +"Comment count": 评论数 +"Comment failed": 评论失败 +"Comment": 评论 +"Config file read failed": 配置文件读取失败 +"Confirm to continue?": 确认继续? +"Contains invalid URL": 包含无效的 URL +"Create admin account": 创建管理员账户 +"Current version is the latest": 当前版本已是最新的 +"Downloading": 下载中 +"Email": 邮箱 +"Enter {{name}}": 输入{{name}} +"Export complete": 导出完毕 +"Export error": 导出失败 +"File": 文件 +"First comment": 第一条评论 +"Image exceeds {{file_size}} limit": 图片超过大小限制 {{file_size}} +"Image upload forbidden": 禁止上传图片 +"Import complete": 导入完毕 +"Invalid request": 无效的请求 +"Invalid request. Please check your `trusted_domains` config.": 请求无效, 请检查 `trusted_domains` 配置项 +"Invalid {{name}}": 无效的{{name}} +"Link": 链接 +"Login failed": 登陆失败 +"Name": 名称 +"New version available": 有更新可用 +"Nickname": 昵称 +"No comment": 无评论 +"Notify": 通知 +"Page fetch failed": 页面获取失败 +"Page": 页面 +"Parameter": 参数 +"Parent comment": 父评论 +"Password update failed": 密码修改失败 +"Password updated": 密码已修改 +"Password": 密码 +"Please review": 请过目 +"Retype {{name}}": 重新输入{{name}} +"Save failed": 保存失败 +"Saving": 保存中 +"Services restart complete": 服务重启完毕 +"Site `{{name}}` not found. Please create it in control center.": 未找到站点:`{{name}}`,请在控制台创建站点 +"Site": 站点 +"Sub-comment": 子评论 +"Target Site": 目标站点 +"Task executing in background, please wait...": 任务已开始在后台执行,请稍后... +"Task in progress, please wait a moment": 任务执行中,请稍后 +"Type": 类型 +"URL Resolver": URL 解析器 +"Unable to get `{{name}}`": 无法获取 `{{name}}` +"Unspecified": 未指定 +"Unsupported formats": 不支持的格式 +"Update complete": 更新完毕 +"Update failed": 更新失败 +"Upload image via {{method}} failed": 通过 {{method}} 上传图片失败 +"User": 用户 +"Username": 用户名 +"Verification failed": 验证失败 +"Working directory retrieval failed": 工作目录获取失败 +"Wrong captcha": 验证码错误 +"{{count}} items imported": 已导入 {{count}} 个项目 +"{{done}} of {{total}} done": 已完成 {{done}} 共 {{total}} 个 +"{{name}} already exists": '{{name}}已存在' +"{{name}} cannot be empty": '{{name}}不能为空' +"{{name}} creation failed": '{{name}}创建失败' +"{{name}} deletion failed": '{{name}}删除失败' +"{{name}} is required": '{{name}}必须填写' +"{{name}} not found": '{{name}}未找到' +"{{name}} save failed": '{{name}}保存失败' diff --git a/internal/anti_spam/anti_spam.go b/internal/anti_spam/anti_spam.go index c41cd294d..4446c5188 100644 --- a/internal/anti_spam/anti_spam.go +++ b/internal/anti_spam/anti_spam.go @@ -17,10 +17,12 @@ import ( var AntiSpamReplaceKeywords *[]string +const LOG_TAG = "[Spam Interception] " + func SyncSpamCheck(comment *entity.Comment, fiberCtx *fiber.Ctx) { // 拦截评论 BlockCommentBy := func(blocker string) { - logrus.Info(fmt.Sprintf("[垃圾拦截] %s 成功拦截评论 ID=%d 内容=%s", blocker, comment.ID, strconv.Quote(comment.Content))) + logrus.Info(fmt.Sprintf(LOG_TAG+"%s Successful blocking of comments ID=%d CONT=%s", blocker, comment.ID, strconv.Quote(comment.Content))) if comment.IsPending { return } @@ -30,7 +32,7 @@ func SyncSpamCheck(comment *entity.Comment, fiberCtx *fiber.Ctx) { // 拦截失败处理 BlockFailBy := func(blocker string, err error) { - logrus.Error(fmt.Sprintf("[垃圾拦截] %s 拦截发生错误 ID=%d 错误信息: %s", blocker, comment.ID, strconv.Quote(comment.Content)), err) + logrus.Error(fmt.Sprintf(LOG_TAG+"%s Interception error occurred ID=%d Err: %s", blocker, comment.ID, strconv.Quote(comment.Content)), err) } // 统一拦截处理 @@ -124,7 +126,7 @@ func SyncSpamCheck(comment *entity.Comment, fiberCtx *fiber.Ctx) { for _, f := range keywordsConf.Files { buf, err := ioutil.ReadFile(f) if err != nil { - logrus.Error("关键词词库文件 " + f + " 加载失败") + logrus.Error("Failed to load Keyword Dictionary file:" + f) } else { fileContent := string(buf) *AntiSpamReplaceKeywords = append(*AntiSpamReplaceKeywords, utils.SplitAndTrimSpace(fileContent, keywordsConf.FileSep)...) @@ -138,7 +140,7 @@ func SyncSpamCheck(comment *entity.Comment, fiberCtx *fiber.Ctx) { for _, keyword := range *AntiSpamReplaceKeywords { if strings.Contains(handleContent, keyword) { if keywordsConf.Pending { - BlockCommentBy("关键词") + BlockCommentBy("Keyword") break } @@ -150,7 +152,7 @@ func SyncSpamCheck(comment *entity.Comment, fiberCtx *fiber.Ctx) { } if !keywordsConf.Pending && replaced && keywordsConf.ReplacTo != "" { - logrus.Info(fmt.Sprintf("[垃圾拦截] 关键词替换评论 ID=%d 原始内容=%s 替换内容=%s", comment.ID, strconv.Quote(comment.Content), strconv.Quote(handleContent))) + logrus.Info(fmt.Sprintf(LOG_TAG+"Keyword Replacement Comments ID=%d Original=%s Processed=%s", comment.ID, strconv.Quote(comment.Content), strconv.Quote(handleContent))) // 保存评论 comment.Content = handleContent diff --git a/internal/anti_spam/anti_spam_akismet.go b/internal/anti_spam/anti_spam_akismet.go index 809aeac0e..ff45c4d77 100644 --- a/internal/anti_spam/anti_spam_akismet.go +++ b/internal/anti_spam/anti_spam_akismet.go @@ -68,16 +68,16 @@ func Akismet(params *AkismetParams, key string) (isPass bool, err error) { respStr := string(respBody) if config.Instance.Debug { - logrus.Info("akismet 垃圾检测响应 ", respStr) + logrus.Info("akismet Spam Detection Response ", respStr) } switch respStr { case "true": - // 是垃圾评论 + // is a spam comment isPass = false return isPass, nil case "false": - // 不是垃圾评论 + // not a spam comment isPass = true return isPass, nil } diff --git a/internal/anti_spam/anti_spam_aliyun.go b/internal/anti_spam/anti_spam_aliyun.go index 9ef3e39be..fafaf501f 100644 --- a/internal/anti_spam/anti_spam_aliyun.go +++ b/internal/anti_spam/anti_spam_aliyun.go @@ -45,7 +45,7 @@ func Aliyun(p AliyunParams) (isPass bool, err error) { } if textScanResp.GetHttpStatus() != 200 { - return false, errors.New("Respone got: " + strconv.Itoa(textScanResp.GetHttpStatus())) + return false, errors.New("response got: " + strconv.Itoa(textScanResp.GetHttpStatus())) } // Handle Respone @@ -53,7 +53,7 @@ func Aliyun(p AliyunParams) (isPass bool, err error) { respRaw := textScanResp.GetHttpContentString() dataRaw := gjson.Get(respRaw, "data.0.results.0.suggestion") if !dataRaw.Exists() { - return false, errors.New("Unexpected JSON: " + respRaw) + return false, errors.New("unexpected JSON: " + respRaw) } // Get Result diff --git a/internal/anti_spam/anti_spam_tencent.go b/internal/anti_spam/anti_spam_tencent.go index 39a4a503b..d4ed3ddbf 100644 --- a/internal/anti_spam/anti_spam_tencent.go +++ b/internal/anti_spam/anti_spam_tencent.go @@ -43,7 +43,7 @@ func Tencent(p TencentParams) (isPass bool, err error) { cpf.HttpProfile.Endpoint = "tms.tencentcloudapi.com" client, err := tms.NewClient(credential, p.Region, cpf) if err != nil { - return false, errors.New("NewClient calls error: " + err.Error()) + return false, errors.New("func NewClient calls error: " + err.Error()) } // Prepare Request Data @@ -66,7 +66,7 @@ func Tencent(p TencentParams) (isPass bool, err error) { // Send Request response, err := client.TextModeration(request) if _, hasErr := err.(*tErr.TencentCloudSDKError); hasErr { - return false, errors.New("An API error has returned: " + err.Error()) + return false, errors.New("an API error has returned: " + err.Error()) } if err != nil { return false, err diff --git a/internal/artransfer/artrans.go b/internal/artransfer/artrans.go index 38a38d591..d6bc8d10e 100644 --- a/internal/artransfer/artrans.go +++ b/internal/artransfer/artrans.go @@ -8,6 +8,7 @@ import ( "github.com/ArtalkJS/Artalk/internal/db" "github.com/ArtalkJS/Artalk/internal/entity" + "github.com/ArtalkJS/Artalk/internal/i18n" "github.com/ArtalkJS/Artalk/internal/query" "github.com/ArtalkJS/Artalk/internal/utils" "github.com/cheggaaa/pb/v3" @@ -16,7 +17,7 @@ import ( var ArtransImporter = &_ArtransImporter{ ImporterInfo: ImporterInfo{ Name: "artrans", - Desc: "从 Artrans 导入数据", + Desc: "Import from Artrans", Note: "", }, } @@ -50,29 +51,29 @@ func ImportArtransByStr(basic *BasicParams, str string) { func ImportArtrans(basic *BasicParams, srcComments []entity.Artran) { if len(srcComments) == 0 { - logFatal("未读取到任何一条评论") + logFatal(i18n.T("No comment")) return } if basic.TargetSiteUrl != "" && !utils.ValidateURL(basic.TargetSiteUrl) { - logFatal("目标站点 URL 无效") + logFatal(i18n.T("Invalid {{name}}", map[string]interface{}{"name": i18n.T("Target Site") + " " + "URL"})) return } // 汇总 - print("# 请过目:\n\n") + print("# " + i18n.T("Please review") + ":\n\n") // 第一条评论 - PrintEncodeData("第一条评论", srcComments[0]) + PrintEncodeData(i18n.T("First comment"), srcComments[0]) showTSiteName := basic.TargetSiteName showTSiteUrl := basic.TargetSiteUrl if showTSiteName == "" { - showTSiteName = "未指定" + showTSiteName = i18n.T("Unspecified") } if showTSiteUrl == "" { - showTSiteUrl = "未指定" + showTSiteUrl = i18n.T("Unspecified") } // 目标站点名和目标站点URL都不为空,才开启 URL 解析器 @@ -86,16 +87,16 @@ func ImportArtrans(basic *BasicParams, srcComments []entity.Artran) { // } PrintTable([][]interface{}{ - {"目标站点名", showTSiteName}, - {"目标站点 URL", showTSiteUrl}, - {"评论数量", fmt.Sprintf("%d", len(srcComments))}, - {"URL 解析器", showUrlResolver}, + {i18n.T("Target Site") + " " + i18n.T("Name"), showTSiteName}, + {i18n.T("Target Site") + " URL", showTSiteUrl}, + {i18n.T("Comment count"), fmt.Sprintf("%d", len(srcComments))}, + {i18n.T("URL Resolver"), showUrlResolver}, }) print("\n") // 确认开始 - if !Confirm("确认开始导入吗?") { + if !Confirm(i18n.T("Confirm to continue?")) { os.Exit(0) } @@ -197,7 +198,7 @@ func ImportArtrans(basic *BasicParams, srcComments []entity.Artran) { importComments = append(importComments, nComment) } - println("数据保存中...") + println(i18n.T("Saving") + "...") // Batch Insert // @link https://gorm.io/docs/create.html#Batch-Insert @@ -264,5 +265,5 @@ func ImportArtrans(basic *BasicParams, srcComments []entity.Artran) { println() } - logInfo(fmt.Sprintf("完成导入 %d 条数据", len(srcComments))) + logInfo(i18n.T("{{count}} items imported", map[string]interface{}{"count": len(srcComments)})) } diff --git a/internal/artransfer/example.go b/internal/artransfer/example.go index 4a04e1419..21cde622e 100644 --- a/internal/artransfer/example.go +++ b/internal/artransfer/example.go @@ -3,7 +3,7 @@ package artransfer var ExampleImporter = &_ExampleImporter{ ImporterInfo: ImporterInfo{ Name: "example", - Desc: "从 Example 导入数据", + Desc: "Import data from ", Note: "", }, } diff --git a/internal/artransfer/importer.go b/internal/artransfer/importer.go index 1fafe3aaf..0af778a51 100644 --- a/internal/artransfer/importer.go +++ b/internal/artransfer/importer.go @@ -17,6 +17,7 @@ import ( "github.com/ArtalkJS/Artalk/internal/config" "github.com/ArtalkJS/Artalk/internal/entity" + "github.com/ArtalkJS/Artalk/internal/i18n" "github.com/ArtalkJS/Artalk/internal/query" "github.com/ArtalkJS/Artalk/internal/utils" "github.com/araddon/dateparse" @@ -31,7 +32,7 @@ func RunImportArtrans(payload []string) { print("\n") tableData := [][]interface{}{ - {"数据迁移 - 导入"}, + {"Artransfer - Import"}, {strings.ToUpper(name)}, {desc}, } @@ -46,7 +47,7 @@ func RunImportArtrans(payload []string) { //elapsed := time.Since(t1) print("\n") - logInfo("导入执行结束") //,耗时: ", elapsed) + logInfo(i18n.T("Import complete")) //,耗时: ", elapsed) } type ImporterInfo struct { @@ -81,7 +82,7 @@ func GetBasicParamsFrom(payload []string) *BasicParams { }) if !basic.UrlResolver { - logWarn("目标站点 URL 解析器已关闭") + logWarn("Target site URL resolver disabled") } return &basic @@ -89,13 +90,13 @@ func GetBasicParamsFrom(payload []string) *BasicParams { func RequiredBasicTargetSite(basic *BasicParams) error { if basic.TargetSiteName == "" { - return errors.New("请附带参数 `t_name:<目标站点名称>`") + return errors.New(i18n.T("{{name}} is required", map[string]interface{}{"name": "t_name:"})) } if basic.TargetSiteUrl == "" { - return errors.New("请附带参数 `t_url:<目标站点根目录 URL>`") + return errors.New(i18n.T("{{name}} is required", map[string]interface{}{"name": "t_url:"})) } if !utils.ValidateURL(basic.TargetSiteUrl) { - return errors.New("参数 `t_url:<目标站点根目录 URL>` 必须为 URL 格式") + return errors.New("invalid URL for parameter `t_url:`") } return nil @@ -111,7 +112,7 @@ func SiteReady(tSiteName string, tSiteUrls string) (entity.Site, error) { site.Urls = tSiteUrls err := query.CreateSite(&site) if err != nil { - return entity.Site{}, errors.New("站点创建失败") + return entity.Site{}, errors.New("failed to create site") } } else { // 追加 URL @@ -141,7 +142,7 @@ func SiteReady(tSiteName string, tSiteUrls string) (entity.Site, error) { site.Urls = strings.Join(rUrls, ",") err := query.UpdateSite(&site) if err != nil { - return entity.Site{}, errors.New("站点数据更新失败") + return entity.Site{}, errors.New("update site data failed") } } } @@ -162,15 +163,16 @@ func JsonFileReady(payload []string) (string, error) { } if jsonFile == "" { - return "", errors.New("请附带参数 `json_file:`") + + return "", errors.New(i18n.T("{{name}} is required", map[string]interface{}{"name": "json_file:"})) } if _, err := os.Stat(jsonFile); errors.Is(err, os.ErrNotExist) { - return "", errors.New("文件不存在,请检查参数 `json_file` 传入路径是否正确") + return "", errors.New(i18n.T("{{name}} not found", map[string]interface{}{"name": i18n.T("File")})) } buf, err := ioutil.ReadFile(jsonFile) if err != nil { - return "", errors.New("json 文件打开失败:" + err.Error()) + return "", errors.New("file open failed" + ": " + err.Error()) } return string(buf), nil @@ -297,13 +299,13 @@ func JsonDecodeFAS(str string, fasStructure interface{}) error { var err error str, err = TryConvertLineJsonToArr(str) if err != nil { - return errors.New("JSON 不是 Array 类型," + err.Error()) + return errors.New("JSON of array type is required: " + err.Error()) } } err := json.Unmarshal([]byte(utils.JsonObjInArrAnyStr(str)), fasStructure) // lib.ToString() if err != nil { - return errors.New("JSON 解析失败 " + err.Error()) + return errors.New("failed to parse JSON: " + err.Error()) } return nil diff --git a/internal/cache/actions.go b/internal/cache/actions.go index c8c06f8f9..565322694 100644 --- a/internal/cache/actions.go +++ b/internal/cache/actions.go @@ -49,7 +49,7 @@ func FindAndStoreCache(name string, dest interface{}, queryDBResult func() inter func FindCache(name string, dest interface{}) error { if !config.Instance.Cache.Enabled { - return errors.New("缓存功能禁用") + return errors.New("cache disabled") } // `Get()` is Thread Safe, so no need to add Mutex @@ -59,7 +59,7 @@ func FindCache(name string, dest interface{}) error { return err } - logrus.Debug("[缓存命中] " + name) + logrus.Debug("[Cache Hit] " + name) return nil } diff --git a/internal/cache/cache.go b/internal/cache/cache.go index eaf4285c0..99d0530ee 100644 --- a/internal/cache/cache.go +++ b/internal/cache/cache.go @@ -66,7 +66,7 @@ func OpenCache() (err error) { ) default: - logrus.Fatal("请检查配置文件 `cache.type` 无效缓存类型:", cacheType) + logrus.Fatal("Invalid cache type `" + cacheType + "`, please check config option `cache.type`") } diff --git a/internal/captcha/geetest.go b/internal/captcha/geetest.go index 815ec0622..6e8184d95 100644 --- a/internal/captcha/geetest.go +++ b/internal/captcha/geetest.go @@ -39,7 +39,7 @@ func GeetestCheck(paramsJSON string) (isPass bool, reason string, err error) { var p GeetestParams err = json.Unmarshal([]byte(paramsJSON), &p) if err != nil { - return false, "", errors.New("Reqest params json parse err: " + err.Error()) + return false, "", errors.New("request params json parse err: " + err.Error()) } // 生成签名 @@ -58,7 +58,7 @@ func GeetestCheck(paramsJSON string) (isPass bool, reason string, err error) { cli := http.Client{Timeout: time.Second * 5} // 5s 超时 resp, err := cli.PostForm(url, form_data) if err != nil || resp.StatusCode != 200 { - return false, "", errors.New("服务接口异常: " + err.Error()) + return false, "", errors.New("service interface exception: " + err.Error()) } // 处理响应结果 @@ -67,7 +67,7 @@ func GeetestCheck(paramsJSON string) (isPass bool, reason string, err error) { gResult := gjson.Get(resJson, "result") if !gResult.Exists() { - return false, "", errors.New("响应结果不符合预期: " + resJson) + return false, "", errors.New("response results are not as expected: " + resJson) } result := gResult.String() diff --git a/internal/config/init.go b/internal/config/init.go index d423a0bd5..a348ad706 100644 --- a/internal/config/init.go +++ b/internal/config/init.go @@ -31,14 +31,14 @@ func Init(cfgFile string) { // load yaml config if err := kf.Load(file.Provider(cfgFile), parser); err != nil { logrus.Errorln(err) - logrus.Fatal("配置文件读取错误") + logrus.Fatal("Config file read error") } Instance = &Config{} if err := kf.Unmarshal("", Instance); err != nil { logrus.Errorln(err) - logrus.Fatal("配置文件解析错误") + logrus.Fatal("Config file parse error") } cfgFileLoaded = cfgFile @@ -50,12 +50,12 @@ func Init(cfgFile string) { func postInit() { // 检查 app_key 是否设置 if strings.TrimSpace(Instance.AppKey) == "" { - logrus.Fatal("请检查配置文件,并设置一个 app_key (任意字符串) 用于数据加密") + logrus.Fatal("Please check config file and set an `app_key` for data encryption") } // 设置时区 if strings.TrimSpace(Instance.TimeZone) == "" { - logrus.Fatal("请检查配置文件,并设置 timezone") + logrus.Fatal("Please check config file and set `timezone`") } denverLoc, _ := time.LoadLocation(Instance.TimeZone) time.Local = denverLoc @@ -63,7 +63,7 @@ func postInit() { // 默认站点配置 Instance.SiteDefault = strings.TrimSpace(Instance.SiteDefault) if Instance.SiteDefault == "" { - logrus.Fatal("请设置 SiteDefault 默认站点,不能为空") + logrus.Fatal("Please check config file and set `site_default`") } // 缓存配置 @@ -83,13 +83,13 @@ func postInit() { /* 检查废弃需更新配置 */ if Instance.Captcha.ActionTimeout != 0 { - logrus.Warn("captcha.action_timeout 配置项已废弃,请使用 captcha.action_reset 代替") + logrus.Warn("The config option `captcha.action_timeout` is deprecated, please use `captcha.action_reset` instead") if Instance.Captcha.ActionReset == 0 { Instance.Captcha.ActionReset = Instance.Captcha.ActionTimeout } } if len(Instance.AllowOrigins) != 0 { - logrus.Warn("allow_origins 配置项已废弃,请使用 trusted_domains 代替") + logrus.Warn("The config option `allow_origins` is deprecated, please use `trusted_domains` instead") if len(Instance.TrustedDomains) == 0 { Instance.TrustedDomains = Instance.AllowOrigins } @@ -97,7 +97,7 @@ func postInit() { // @version < 2.2.0 if Instance.Notify != nil { - logrus.Warn("notify 配置项已废弃,请使用 admin_notify 代替") + logrus.Warn("The config option `notify` is deprecated, please use `admin_notify` instead") Instance.AdminNotify = *Instance.Notify } if Instance.AdminNotify.Email == nil { @@ -106,7 +106,7 @@ func postInit() { } } if Instance.Email.MailSubjectToAdmin != "" { - logrus.Warn("email.mail_subject_to_admin 配置项已废弃,请使用 admin_notify.email.mail_subject 代替") + logrus.Warn("The config option `email.mail_subject_to_admin` is deprecated, please use `admin_notify.email.mail_subject` instead") Instance.AdminNotify.Email.MailSubject = Instance.Email.MailSubjectToAdmin } diff --git a/internal/core/core.go b/internal/core/core.go index 130920179..0a021a5d3 100644 --- a/internal/core/core.go +++ b/internal/core/core.go @@ -56,7 +56,7 @@ func initConfig(cfgFile string, workDir string) { // 切换工作目录 if workDir != "" { if err := os.Chdir(workDir); err != nil { - logrus.Fatal("工作目录切换错误 ", err) + logrus.Fatal("Working directory change error: ", err) } } @@ -137,7 +137,7 @@ func initLog() { func initCache() { err := cache.OpenCache() if err != nil { - logrus.Error("缓存初始化发生错误 ", err) + logrus.Error("[Cache] ", "Init cache error: ", err) os.Exit(1) } } diff --git a/internal/core/gen.go b/internal/core/gen.go index 35773466f..aff82f793 100644 --- a/internal/core/gen.go +++ b/internal/core/gen.go @@ -8,6 +8,7 @@ import ( "path/filepath" "strings" + "github.com/ArtalkJS/Artalk/internal/i18n" "github.com/ArtalkJS/Artalk/internal/pkged" "github.com/sirupsen/logrus" ) @@ -25,12 +26,12 @@ func Gen(genType string, specificPath string, overwrite bool) { file, err := pkged.FS().Open(strings.TrimPrefix(genType, "/")) if err != nil { - logrus.Fatal("无效的内置资源: "+genType+" ", err) + logrus.Fatal("Invalid built-in resource `"+genType+"`: ", err) } buf, err := ioutil.ReadAll(file) if err != nil { - logrus.Fatal("读取内置资源: "+genType+" 失败 ", err) + logrus.Fatal("Read built-in resources `"+genType+"` error: ", err) } // 自动生成 app_key @@ -50,20 +51,20 @@ func Gen(genType string, specificPath string, overwrite bool) { } if CheckFileExist(absPath) && !overwrite { - logrus.Fatal("已存在文件: " + absPath) + logrus.Fatal(i18n.T("{{name}} already exists", map[string]interface{}{"name": i18n.T("File")}) + ": " + absPath) } dst, err := os.Create(absPath) if err != nil { - logrus.Fatal("创建目标文件失败 ", err) + logrus.Fatal("Failed to create target file: ", err) } defer dst.Close() if _, err = dst.Write(buf); err != nil { - logrus.Fatal("写入目标文件失败 ", err) + logrus.Fatal("Failed to write target file: ", err) } - logrus.Info("生成文件: " + absPath) + logrus.Info("File Generated: " + absPath) } var letterRunes = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!@#$%^&*") diff --git a/internal/db/db.go b/internal/db/db.go index e60343979..0f48df859 100644 --- a/internal/db/db.go +++ b/internal/db/db.go @@ -33,7 +33,7 @@ func InitDB() { var err error db, err := OpenDB(config.Instance.DB.Type, config.Instance.DB.Dsn) if err != nil { - logrus.Error("数据库初始化发生错误 ", err) + logrus.Error("[DB] ", "Init database error: ", err) os.Exit(1) } SetDB(db) @@ -53,7 +53,7 @@ func OpenDB(dbType config.DBType, dsn string) (*gorm.DB, error) { switch dbType { case config.TypeSQLite: if dbConf.File == "" { - logrus.Fatal("请配置 db.file 指定一个 sqlite 数据库路径") + logrus.Fatal("Please set `db.file` option in config file to specify a sqlite database path") } dsn = dbConf.File case config.TypePostgreSQL: @@ -86,7 +86,7 @@ func OpenDB(dbType config.DBType, dsn string) (*gorm.DB, error) { return OpenSqlServer(dsn) } - return nil, errors.New(`不支持的数据库类型 "` + string(dbType) + `"`) + return nil, errors.New(`unsupported database type "` + string(dbType) + `"`) } func OpenSQLite(filename string) (*gorm.DB, error) { diff --git a/internal/email/queue.go b/internal/email/queue.go index 8b6dd187f..c5778b3a5 100644 --- a/internal/email/queue.go +++ b/internal/email/queue.go @@ -24,7 +24,7 @@ func InitQueue() { if email.LinkedNotify != nil { // 标记关联评论邮件发送状态 if err := query.NotifySetEmailed(email.LinkedNotify); err != nil { - logrus.Errorf("[EMAIL] 标记关联评论邮件发送状态失败: %s", err) + logrus.Errorf("[Email] Flag associated comment email delivery status failed: %s", err) continue } } diff --git a/internal/email/render.go b/internal/email/render.go index 4fb06040d..ce53f0af9 100644 --- a/internal/email/render.go +++ b/internal/email/render.go @@ -1,211 +1,205 @@ -package email - -import ( - "bytes" - "embed" - "errors" - "fmt" - "html" - "os" - "regexp" - "strings" - - "github.com/ArtalkJS/Artalk/internal/config" - "github.com/ArtalkJS/Artalk/internal/entity" - "github.com/ArtalkJS/Artalk/internal/query" - "github.com/ArtalkJS/Artalk/internal/utils" -) - -//go:embed email_tpl/* -//go:embed notify_tpl/* -var internalTpl embed.FS - -func RenderCommon(str string, notify *entity.Notify, _renderType ...string) string { - // 渲染类型 - renderType := "email" // 默认为邮件发送渲染 - if len(_renderType) > 0 { - renderType = _renderType[0] - } - - fromComment := query.FetchCommentForNotify(notify) - from := query.CookCommentForEmail(&fromComment) - toComment := query.FindNotifyParentComment(notify) - to := query.CookCommentForEmail(&toComment) - - toUser := query.FetchUserForNotify(notify) // 发送目标用户 - - content := to.Content - replyContent := from.Content - if renderType == "notify" { // 多元推送内容 - content = HandleEmoticonsImgTagsForNotify(to.ContentRaw) - replyContent = HandleEmoticonsImgTagsForNotify(from.ContentRaw) - } - - cf := CommonFields{ - From: from, - To: to, - Comment: from, - ParentComment: to, - - Nick: toUser.Name, - Content: content, - ReplyNick: from.Nick, - ReplyContent: replyContent, - PageTitle: from.Page.Title, - PageURL: from.Page.URL, - SiteName: from.SiteName, - SiteURL: from.Site.FirstUrl, - - LinkToReply: query.GetReadLinkByNotify(notify), - } - - flat := utils.StructToFlatDotMap(&cf) - - return ReplaceAllMustache(str, flat) -} - -type CommonFields struct { - From entity.CookedCommentForEmail `json:"from"` - To entity.CookedCommentForEmail `json:"to"` - Comment entity.CookedCommentForEmail `json:"comment"` - ParentComment entity.CookedCommentForEmail `json:"parent_comment"` - - Nick string `json:"nick"` - Content string `json:"content"` - ReplyNick string `json:"reply_nick"` - ReplyContent string `json:"reply_content"` - - PageTitle string `json:"page_title"` - PageURL string `json:"page_url"` - SiteName string `json:"site_name"` - SiteURL string `json:"site_url"` - - LinkToReply string `json:"link_to_reply"` -} - -// 替换 {{ key }} 为 val -func ReplaceAllMustache(data string, dict map[string]interface{}) string { - r := regexp.MustCompile(`{{\s*(.*?)\s*}}`) - return r.ReplaceAllStringFunc(data, func(m string) string { - key := r.FindStringSubmatch(m)[1] - if val, isExist := dict[key]; isExist { - return GetPurifiedValue(key, val) - } - - return m - }) -} - -// 净化文本,防止 XSS -func GetPurifiedValue(k string, v interface{}) string { - val := fmt.Sprintf("%v", v) - - // 白名单 - ignoreEscapeKeys := []string{"reply_content", "content", "link_to_reply"} - if utils.ContainsStr(ignoreEscapeKeys, k) || - strings.HasSuffix(k, ".content") || // 排除 entity.CookedComment.content - strings.HasSuffix(k, ".content_raw") { - return val - } - - val = html.EscapeString(val) - return val -} - -func HandleEmoticonsImgTagsForNotify(str string) string { - r := regexp.MustCompile(`]*?atk-emoticon=["]([^"]*?)["][^>]*?>`) - return r.ReplaceAllStringFunc(str, func(m string) string { - ms := r.FindStringSubmatch(m) - if len(ms) < 2 { - return m - } - if ms[1] == "" { - return "[表情]" - } - return "[" + ms[1] + "]" - }) -} - -// 渲染邮件 Body 内容 -func RenderEmailBody(notify *entity.Notify, isSendToAdmin bool) string { - tplName := config.Instance.Email.MailTpl - - // 发送给管理员的邮件单独使用管理员邮件模板 - if isSendToAdmin { - tplName = config.Instance.AdminNotify.Email.MailTpl - } - - // 配置文件未指定邮件模板路径,使用内置默认模板 - if tplName == "" { - tplName = "default" - } - - tpl := "" - if _, err := os.Stat(tplName); errors.Is(err, os.ErrNotExist) { - tpl = GetInternalEmailTpl(tplName) - } else { - // TODO 反复文件 IO 操作会导致性能下降, - // 之后优化可以改成程序启动时加载模板文件到内存中 - tpl = GetExternalTpl(tplName) - } - - tpl = RenderCommon(tpl, notify) - - return tpl -} - -// 渲染管理员推送 Body 内容 -func RenderNotifyBody(notify *entity.Notify) string { - tplName := config.Instance.AdminNotify.NotifyTpl - if tplName == "" { - tplName = "default" - } - - tpl := "" - if _, err := os.Stat(tplName); errors.Is(err, os.ErrNotExist) { - tpl = GetInternalNotifyTpl(tplName) - } else { - tpl = GetExternalTpl(tplName) - } - - tpl = RenderCommon(tpl, notify, "notify") - - return tpl -} - -// 获取内建邮件模版 -func GetInternalEmailTpl(tplName string) string { - return GetInternalTpl("email_tpl", tplName) -} - -// 获取内建通知模版 -func GetInternalNotifyTpl(tplName string) string { - return GetInternalTpl("notify_tpl", tplName) -} - -// 获取内建模版 -func GetInternalTpl(basePath string, tplName string) string { - filename := fmt.Sprintf("%s/%s.html", basePath, tplName) - f, err := internalTpl.Open(filename) - if err != nil { - return "" - } - - buf := new(bytes.Buffer) - if _, err := buf.ReadFrom(f); err != nil { - return "" - } - contents := buf.String() - - return contents -} - -// 获取外置模版 -func GetExternalTpl(filename string) string { - buf, err := os.ReadFile(filename) - if err != nil { - return "" - } - - return string(buf) -} +package email + +import ( + "bytes" + "embed" + "errors" + "fmt" + "html" + "os" + "regexp" + "strings" + + "github.com/ArtalkJS/Artalk/internal/config" + "github.com/ArtalkJS/Artalk/internal/entity" + "github.com/ArtalkJS/Artalk/internal/query" + "github.com/ArtalkJS/Artalk/internal/utils" +) + +//go:embed email_tpl/* +//go:embed notify_tpl/* +var internalTpl embed.FS + +func RenderCommon(str string, notify *entity.Notify, _renderType ...string) string { + // 渲染类型 + renderType := "email" // 默认为邮件发送渲染 + if len(_renderType) > 0 { + renderType = _renderType[0] + } + + fromComment := query.FetchCommentForNotify(notify) + from := query.CookCommentForEmail(&fromComment) + toComment := query.FindNotifyParentComment(notify) + to := query.CookCommentForEmail(&toComment) + + toUser := query.FetchUserForNotify(notify) // 发送目标用户 + + content := to.Content + replyContent := from.Content + if renderType == "notify" { // 多元推送内容 + content = HandleEmoticonsImgTagsForNotify(to.ContentRaw) + replyContent = HandleEmoticonsImgTagsForNotify(from.ContentRaw) + } + + cf := CommonFields{ + From: from, + To: to, + Comment: from, + ParentComment: to, + + Nick: toUser.Name, + Content: content, + ReplyNick: from.Nick, + ReplyContent: replyContent, + PageTitle: from.Page.Title, + PageURL: from.Page.URL, + SiteName: from.SiteName, + SiteURL: from.Site.FirstUrl, + + LinkToReply: query.GetReadLinkByNotify(notify), + } + + flat := utils.StructToFlatDotMap(&cf) + + return ReplaceAllMustache(str, flat) +} + +type CommonFields struct { + From entity.CookedCommentForEmail `json:"from"` + To entity.CookedCommentForEmail `json:"to"` + Comment entity.CookedCommentForEmail `json:"comment"` + ParentComment entity.CookedCommentForEmail `json:"parent_comment"` + + Nick string `json:"nick"` + Content string `json:"content"` + ReplyNick string `json:"reply_nick"` + ReplyContent string `json:"reply_content"` + + PageTitle string `json:"page_title"` + PageURL string `json:"page_url"` + SiteName string `json:"site_name"` + SiteURL string `json:"site_url"` + + LinkToReply string `json:"link_to_reply"` +} + +// 替换 {{ key }} 为 val +func ReplaceAllMustache(data string, dict map[string]interface{}) string { + return utils.RenderMustaches(data, dict, func(k string, v interface{}) string { + return GetPurifiedValue(k, v) + }) +} + +// 净化文本,防止 XSS +func GetPurifiedValue(k string, v interface{}) string { + val := fmt.Sprintf("%v", v) + + // 白名单 + ignoreEscapeKeys := []string{"reply_content", "content", "link_to_reply"} + if utils.ContainsStr(ignoreEscapeKeys, k) || + strings.HasSuffix(k, ".content") || // 排除 entity.CookedComment.content + strings.HasSuffix(k, ".content_raw") { + return val + } + + val = html.EscapeString(val) + return val +} + +func HandleEmoticonsImgTagsForNotify(str string) string { + r := regexp.MustCompile(`]*?atk-emoticon=["]([^"]*?)["][^>]*?>`) + return r.ReplaceAllStringFunc(str, func(m string) string { + ms := r.FindStringSubmatch(m) + if len(ms) < 2 { + return m + } + if ms[1] == "" { + return "[表情]" + } + return "[" + ms[1] + "]" + }) +} + +// 渲染邮件 Body 内容 +func RenderEmailBody(notify *entity.Notify, isSendToAdmin bool) string { + tplName := config.Instance.Email.MailTpl + + // 发送给管理员的邮件单独使用管理员邮件模板 + if isSendToAdmin { + tplName = config.Instance.AdminNotify.Email.MailTpl + } + + // 配置文件未指定邮件模板路径,使用内置默认模板 + if tplName == "" { + tplName = "default" + } + + tpl := "" + if _, err := os.Stat(tplName); errors.Is(err, os.ErrNotExist) { + tpl = GetInternalEmailTpl(tplName) + } else { + // TODO 反复文件 IO 操作会导致性能下降, + // 之后优化可以改成程序启动时加载模板文件到内存中 + tpl = GetExternalTpl(tplName) + } + + tpl = RenderCommon(tpl, notify) + + return tpl +} + +// 渲染管理员推送 Body 内容 +func RenderNotifyBody(notify *entity.Notify) string { + tplName := config.Instance.AdminNotify.NotifyTpl + if tplName == "" { + tplName = "default" + } + + tpl := "" + if _, err := os.Stat(tplName); errors.Is(err, os.ErrNotExist) { + tpl = GetInternalNotifyTpl(tplName) + } else { + tpl = GetExternalTpl(tplName) + } + + tpl = RenderCommon(tpl, notify, "notify") + + return tpl +} + +// 获取内建邮件模版 +func GetInternalEmailTpl(tplName string) string { + return GetInternalTpl("email_tpl", tplName) +} + +// 获取内建通知模版 +func GetInternalNotifyTpl(tplName string) string { + return GetInternalTpl("notify_tpl", tplName) +} + +// 获取内建模版 +func GetInternalTpl(basePath string, tplName string) string { + filename := fmt.Sprintf("%s/%s.html", basePath, tplName) + f, err := internalTpl.Open(filename) + if err != nil { + return "" + } + + buf := new(bytes.Buffer) + if _, err := buf.ReadFrom(f); err != nil { + return "" + } + contents := buf.String() + + return contents +} + +// 获取外置模版 +func GetExternalTpl(filename string) string { + buf, err := os.ReadFile(filename) + if err != nil { + return "" + } + + return string(buf) +} diff --git a/internal/email/sender_alidm.go b/internal/email/sender_alidm.go index 8f046db34..2453906de 100644 --- a/internal/email/sender_alidm.go +++ b/internal/email/sender_alidm.go @@ -40,7 +40,7 @@ func (s *AliDMSender) Send(email Email) bool { resp, err := client.SingleRequest(req) if err != nil { - logrus.Error("[EMAIL] Aliyun DM 邮件发送失败 ", err) + logrus.Error("[Email] ", "Email sending failed via Aliyun DM", err) return false } diff --git a/internal/email/sender_smtp.go b/internal/email/sender_smtp.go index 6dbab7efe..8aadf04de 100644 --- a/internal/email/sender_smtp.go +++ b/internal/email/sender_smtp.go @@ -27,7 +27,7 @@ func (s *SmtpSender) Send(email Email) bool { // 发送邮件 if err := s.dialer.DialAndSend(m); err != nil { - logrus.Error("[EMAIL] SMTP 邮件发送失败 ", err) + logrus.Error("[Email] ", "Email sending failed via SMTP ", err) return false } diff --git a/internal/i18n/gen/main.go b/internal/i18n/gen/main.go index 2f63910d4..9bdc81aa4 100644 --- a/internal/i18n/gen/main.go +++ b/internal/i18n/gen/main.go @@ -89,7 +89,7 @@ func scan(dir string) []string { return nil } - extKeys := extractFormCode(codeStr) + extKeys := extractFromCode(codeStr) if len(extKeys) > 0 { result = append(result, extKeys...) @@ -108,7 +108,7 @@ func scan(dir string) []string { return result } -func extractFormCode(src string) []string { +func extractFromCode(src string) []string { fileSet := token.NewFileSet() f, err := parser.ParseFile(fileSet, "", src, 0) if err != nil { diff --git a/internal/i18n/i18n.go b/internal/i18n/i18n.go index 41c29041f..4c306d2ac 100644 --- a/internal/i18n/i18n.go +++ b/internal/i18n/i18n.go @@ -2,9 +2,9 @@ package i18n import ( "fmt" - "strings" "github.com/ArtalkJS/Artalk/internal/pkged" + "github.com/ArtalkJS/Artalk/internal/utils" "github.com/sirupsen/logrus" "gopkg.in/yaml.v3" ) @@ -28,7 +28,7 @@ func Init(locale string) { yaml.Unmarshal(yamlStr, &Locales) } -func T(msg string, params ...interface{}) string { +func T(msg string, params ...map[string]interface{}) string { v, ok := Locales[msg] if !ok || v == "" { v = msg @@ -36,9 +36,9 @@ func T(msg string, params ...interface{}) string { return msgParams(v, params...) } -func msgParams(msg string, params ...interface{}) string { - if strings.Contains(msg, "%") { - msg = fmt.Sprintf(msg, params...) +func msgParams(msg string, params ...map[string]interface{}) string { + if len(params) > 0 { + return utils.RenderMustaches(msg, params[0]) } return msg diff --git a/internal/notify_launcher/notify_launcher.go b/internal/notify_launcher/notify_launcher.go index 2999c4afe..6ac34e1e6 100644 --- a/internal/notify_launcher/notify_launcher.go +++ b/internal/notify_launcher/notify_launcher.go @@ -192,7 +192,7 @@ func SendLark(title string, msg string) { sendData := fmt.Sprintf(`{"msg_type":"text","content":{"text":%s}}`, strconv.Quote(msg)) result, err := http.Post(larkConf.WebhookURL, "application/json", strings.NewReader(sendData)) if err != nil { - logrus.Error("[飞书]", " 消息发送失败:", err) + logrus.Error("[飞书] ", "Failed to send msg:", err) return } @@ -212,7 +212,7 @@ func SendBark(title string, msg string) { result, err := http.Get(fmt.Sprintf("%s/%s/%s", strings.TrimSuffix(barkConf.Server, "/"), url.QueryEscape(title), url.QueryEscape(msg))) if err != nil { - logrus.Error("[Bark]", " 消息发送失败:", err) + logrus.Error("[Bark] ", "Failed to send msg:", err) return } @@ -247,7 +247,7 @@ func SendWebHook(subject string, body string, comment *entity.Comment, pComment jsonByte, _ := json.Marshal(reqData) result, err := http.Post(webhookConf.URL, "application/json", bytes.NewReader(jsonByte)) if err != nil { - logrus.Error("[WebHook 推送]", " 消息发送失败:", err) + logrus.Error("[WebHook Push] ", "Failed to send msg:", err) return } diff --git a/internal/query/service.go b/internal/query/service.go index dcf37287e..e94510c45 100644 --- a/internal/query/service.go +++ b/internal/query/service.go @@ -66,7 +66,7 @@ func FetchPageFromURL(p *entity.Page) error { url := cookedPage.URL if url == "" { - return errors.New("URL is null") + return errors.New("URL cannot be null") } // 获取 URL 页面 title @@ -77,7 +77,7 @@ func FetchPageFromURL(p *entity.Page) error { } if err := UpdatePage(p); err != nil { - logrus.Error("FetchURL 保存失败") + logrus.Error("Failed to save in FetchPage") return err } @@ -86,8 +86,8 @@ func FetchPageFromURL(p *entity.Page) error { func GetTitleByURL(url string) (string, error) { if !utils.ValidateURL(url) { - logrus.Error("URL " + url + " is invalid") - return "", errors.New("URL is invalid") + logrus.Error("Invalid URL: " + url) + return "", errors.New("invalid URL") } // Request the HTML page. diff --git a/internal/utils/template.go b/internal/utils/template.go new file mode 100644 index 000000000..759bc8739 --- /dev/null +++ b/internal/utils/template.go @@ -0,0 +1,25 @@ +package utils + +import ( + "fmt" + "regexp" +) + +// 解析 Mustaches 语法 +// 替换 {{ key }} 为 val +func RenderMustaches(data string, dict map[string]interface{}, valueGetter ...func(k string, v interface{}) string) string { + r := regexp.MustCompile(`{{\s*(.*?)\s*}}`) + + return r.ReplaceAllStringFunc(data, func(m string) string { + key := r.FindStringSubmatch(m)[1] + if val, isExist := dict[key]; isExist { + if len(valueGetter) > 0 { + return valueGetter[0](key, val) + } else { + return fmt.Sprintf("%v", val) + } + } + + return m + }) +} diff --git a/server/common/check.go b/server/common/check.go index 32544cafd..a7c6235f2 100644 --- a/server/common/check.go +++ b/server/common/check.go @@ -2,6 +2,7 @@ package common import ( "github.com/ArtalkJS/Artalk/internal/entity" + "github.com/ArtalkJS/Artalk/internal/i18n" "github.com/ArtalkJS/Artalk/internal/query" "github.com/ArtalkJS/Artalk/internal/utils" "github.com/gofiber/fiber/v2" @@ -13,7 +14,7 @@ func CheckIsAllowed(c *fiber.Ctx, name string, email string, page entity.Page, s // 如果用户是管理员,或者当前页只能管理员评论 if isAdminUser || page.AdminOnly { if !CheckIsAdminReq(c) { - return false, RespError(c, "需要验证管理员身份", Map{"need_login": true}) + return false, RespError(c, i18n.T("Admin access required"), Map{"need_login": true}) } } diff --git a/server/handler/admin_cache.go b/server/handler/admin_cache.go index 0ec9ae4ed..7a258c078 100644 --- a/server/handler/admin_cache.go +++ b/server/handler/admin_cache.go @@ -2,6 +2,7 @@ package handler import ( "github.com/ArtalkJS/Artalk/internal/cache" + "github.com/ArtalkJS/Artalk/internal/i18n" "github.com/ArtalkJS/Artalk/server/common" "github.com/gofiber/fiber/v2" ) @@ -20,7 +21,7 @@ func AdminCacheWarm(router fiber.Router) { } if !common.GetIsSuperAdmin(c) { - return common.RespError(c, "无权访问") + return common.RespError(c, i18n.T("Access denied")) } go func() { @@ -28,7 +29,7 @@ func AdminCacheWarm(router fiber.Router) { }() return common.RespData(c, common.Map{ - "msg": "缓存预热任务已在后台开始执行,稍等片刻完成...", + "msg": i18n.T("Task executing in background, please wait..."), }) }) } @@ -48,7 +49,7 @@ func AdminCacheFlush(router fiber.Router) { } if !common.GetIsSuperAdmin(c) { - return common.RespError(c, "无权访问") + return common.RespError(c, i18n.T("Access denied")) } if p.FlushAll { @@ -57,10 +58,10 @@ func AdminCacheFlush(router fiber.Router) { }() return common.RespData(c, common.Map{ - "msg": "缓存清理任务已在后台开始执行,稍等片刻完成...", + "msg": i18n.T("Task executing in background, please wait..."), }) } - return common.RespError(c, "参数错误") + return common.RespError(c, i18n.T("Invalid {{name}}", Map{"name": i18n.T("Parameter")})) }) } diff --git a/server/handler/admin_comment_del.go b/server/handler/admin_comment_del.go index 68cd24b7f..db1965d08 100644 --- a/server/handler/admin_comment_del.go +++ b/server/handler/admin_comment_del.go @@ -1,6 +1,7 @@ package handler import ( + "github.com/ArtalkJS/Artalk/internal/i18n" "github.com/ArtalkJS/Artalk/internal/query" "github.com/ArtalkJS/Artalk/server/common" "github.com/gofiber/fiber/v2" @@ -28,21 +29,21 @@ func AdminCommentDel(router fiber.Router) { // find comment comment := query.FindComment(p.ID) if comment.IsEmpty() { - return common.RespError(c, "comment not found") + return common.RespError(c, i18n.T("{{name}} not found", Map{"name": i18n.T("Comment")})) } if !common.IsAdminHasSiteAccess(c, comment.SiteName) { - return common.RespError(c, "无权操作") + return common.RespError(c, i18n.T("Access denied")) } // 删除主评论 if err := query.DelComment(&comment); err != nil { - return common.RespError(c, "评论删除失败") + return common.RespError(c, i18n.T("{{name}} deletion failed", Map{"name": i18n.T("Comment")})) } // 删除子评论 if err := query.DelCommentChildren(comment.ID); err != nil { - return common.RespError(c, "子评论删除失败") + return common.RespError(c, i18n.T("{{name}} deletion failed", Map{"name": i18n.T("Sub-comment")})) } return common.RespSuccess(c) diff --git a/server/handler/admin_comment_edit.go b/server/handler/admin_comment_edit.go index 3cc3180fd..030647f53 100644 --- a/server/handler/admin_comment_edit.go +++ b/server/handler/admin_comment_edit.go @@ -5,6 +5,7 @@ import ( "github.com/ArtalkJS/Artalk/internal/email" "github.com/ArtalkJS/Artalk/internal/entity" + "github.com/ArtalkJS/Artalk/internal/i18n" "github.com/ArtalkJS/Artalk/internal/query" "github.com/ArtalkJS/Artalk/internal/utils" "github.com/ArtalkJS/Artalk/server/common" @@ -46,19 +47,19 @@ func AdminCommentEdit(router fiber.Router) { // find comment comment := query.FindComment(p.ID) if comment.IsEmpty() { - return common.RespError(c, "comment not found") + return common.RespError(c, i18n.T("{{name}} not found", Map{"name": i18n.T("Comment")})) } if !common.IsAdminHasSiteAccess(c, comment.SiteName) { - return common.RespError(c, "无权操作") + return common.RespError(c, i18n.T("Access denied")) } // check params if p.Email != "" && !utils.ValidateEmail(p.Email) { - return common.RespError(c, "Invalid email") + return common.RespError(c, i18n.T("Invalid {{name}}", Map{"name": i18n.T("Email")})) } if p.Link != "" && !utils.ValidateURL(p.Link) { - return common.RespError(c, "Invalid link") + return common.RespError(c, i18n.T("Invalid {{name}}", Map{"name": i18n.T("Link")})) } // content @@ -116,7 +117,7 @@ func AdminCommentEdit(router fiber.Router) { } if err := query.UpdateComment(&comment); err != nil { - return common.RespError(c, "comment save error") + return common.RespError(c, i18n.T("{{name}} save failed", Map{"name": i18n.T("Comment")})) } return common.RespData(c, common.Map{ diff --git a/server/handler/admin_page_del.go b/server/handler/admin_page_del.go index 049b4b8fd..041a3aee2 100644 --- a/server/handler/admin_page_del.go +++ b/server/handler/admin_page_del.go @@ -1,6 +1,7 @@ package handler import ( + "github.com/ArtalkJS/Artalk/internal/i18n" "github.com/ArtalkJS/Artalk/internal/query" "github.com/ArtalkJS/Artalk/server/common" "github.com/gofiber/fiber/v2" @@ -25,16 +26,16 @@ func AdminPageDel(router fiber.Router) { page := query.FindPage(p.Key, p.SiteName) if page.IsEmpty() { - return common.RespError(c, "page not found") + return common.RespError(c, i18n.T("{{name}} not found", Map{"name": i18n.T("Page")})) } if !common.IsAdminHasSiteAccess(c, page.SiteName) { - return common.RespError(c, "无权操作") + return common.RespError(c, i18n.T("Access denied")) } err := query.DelPage(&page) if err != nil { - return common.RespError(c, "Page 删除失败") + return common.RespError(c, i18n.T("{{name}} deletion failed", Map{"name": i18n.T("Page")})) } return common.RespSuccess(c) diff --git a/server/handler/admin_page_edit.go b/server/handler/admin_page_edit.go index ff77d9d9b..3dd35e624 100644 --- a/server/handler/admin_page_edit.go +++ b/server/handler/admin_page_edit.go @@ -6,6 +6,7 @@ import ( "github.com/ArtalkJS/Artalk/internal/cache" "github.com/ArtalkJS/Artalk/internal/db" "github.com/ArtalkJS/Artalk/internal/entity" + "github.com/ArtalkJS/Artalk/internal/i18n" "github.com/ArtalkJS/Artalk/internal/query" "github.com/ArtalkJS/Artalk/server/common" "github.com/gofiber/fiber/v2" @@ -32,7 +33,7 @@ func AdminPageEdit(router fiber.Router) { } if strings.TrimSpace(p.Key) == "" { - return common.RespError(c, "page key 不能为空白字符") + return common.RespError(c, i18n.T("{{name}} cannot be empty", Map{"name": "key"})) } // use site @@ -41,17 +42,17 @@ func AdminPageEdit(router fiber.Router) { // find page var page = query.FindPageByID(p.ID) if page.IsEmpty() { - return common.RespError(c, "page not found") + return common.RespError(c, i18n.T("{{name}} not found", Map{"name": i18n.T("Page")})) } if !common.IsAdminHasSiteAccess(c, page.SiteName) { - return common.RespError(c, "无权操作") + return common.RespError(c, i18n.T("Access denied")) } // 重命名合法性检测 modifyKey := p.Key != page.Key if modifyKey && !query.FindPage(p.Key, p.SiteName).IsEmpty() { - return common.RespError(c, "page 已存在,请换个 key") + return common.RespError(c, i18n.T("{{name}} already exists", Map{"name": i18n.T("Page")})) } // 预先删除缓存,防止修改主键原有 page_key 占用问题 @@ -73,7 +74,7 @@ func AdminPageEdit(router fiber.Router) { } if err := query.UpdatePage(&page); err != nil { - return common.RespError(c, "page save error") + return common.RespError(c, i18n.T("{{name}} save failed", Map{"name": i18n.T("Page")})) } return common.RespData(c, common.Map{ diff --git a/server/handler/admin_page_fetch.go b/server/handler/admin_page_fetch.go index f25e8c387..91f209bb6 100644 --- a/server/handler/admin_page_fetch.go +++ b/server/handler/admin_page_fetch.go @@ -1,11 +1,10 @@ package handler import ( - "fmt" - "github.com/ArtalkJS/Artalk/internal/config" "github.com/ArtalkJS/Artalk/internal/db" "github.com/ArtalkJS/Artalk/internal/entity" + "github.com/ArtalkJS/Artalk/internal/i18n" "github.com/ArtalkJS/Artalk/internal/query" "github.com/ArtalkJS/Artalk/server/common" "github.com/gofiber/fiber/v2" @@ -37,7 +36,7 @@ func AdminPageFetch(router fiber.Router) { if p.GetStatus { if allPageFetching { return common.RespData(c, common.Map{ - "msg": fmt.Sprintf("已完成 %d 共 %d 个", allPageFetchDone, allPageFetchTotal), + "msg": i18n.T("{{done}} of {{total}} done", Map{"done": allPageFetchDone, "total": allPageFetchTotal}), "is_progress": true, }) } else { @@ -51,7 +50,7 @@ func AdminPageFetch(router fiber.Router) { // 更新全部站点 if p.SiteName != "" { if allPageFetching { - return common.RespError(c, "任务正在进行中,请稍等片刻") + return common.RespError(c, i18n.T("Task in progress, please wait a moment")) } // 异步执行 @@ -82,15 +81,15 @@ func AdminPageFetch(router fiber.Router) { page := query.FindPageByID(p.ID) if page.IsEmpty() { - return common.RespError(c, "page not found") + return common.RespError(c, i18n.T("{{name}} not found", Map{"name": i18n.T("Page")})) } if !common.IsAdminHasSiteAccess(c, page.SiteName) { - return common.RespError(c, "无权操作") + return common.RespError(c, i18n.T("Access denied")) } if err := query.FetchPageFromURL(&page); err != nil { - return common.RespError(c, "page fetch error: "+err.Error()) + return common.RespError(c, i18n.T("Page fetch failed")+": "+err.Error()) } return common.RespData(c, common.Map{ diff --git a/server/handler/admin_page_get.go b/server/handler/admin_page_get.go index 0cd800461..a79b0d169 100644 --- a/server/handler/admin_page_get.go +++ b/server/handler/admin_page_get.go @@ -3,6 +3,7 @@ package handler import ( "github.com/ArtalkJS/Artalk/internal/db" "github.com/ArtalkJS/Artalk/internal/entity" + "github.com/ArtalkJS/Artalk/internal/i18n" "github.com/ArtalkJS/Artalk/internal/query" "github.com/ArtalkJS/Artalk/server/common" "github.com/gofiber/fiber/v2" @@ -33,7 +34,7 @@ func AdminPageGet(router fiber.Router) { common.UseSite(c, &p.SiteName, &p.SiteID, &p.SiteAll) if !common.IsAdminHasSiteAccess(c, p.SiteName) { - return common.RespError(c, "无权操作") + return common.RespError(c, i18n.T("Access denied")) } // 准备 query diff --git a/server/handler/admin_send_mail.go b/server/handler/admin_send_mail.go index 2f241fed5..202ae8919 100644 --- a/server/handler/admin_send_mail.go +++ b/server/handler/admin_send_mail.go @@ -2,6 +2,7 @@ package handler import ( "github.com/ArtalkJS/Artalk/internal/email" + "github.com/ArtalkJS/Artalk/internal/i18n" "github.com/ArtalkJS/Artalk/server/common" "github.com/gofiber/fiber/v2" ) @@ -21,7 +22,7 @@ func AdminSendMail(router fiber.Router) { } if !common.GetIsSuperAdmin(c) { - return common.RespError(c, "无权访问") + return common.RespError(c, i18n.T("Access denied")) } email.AsyncSendTo(p.Subject, p.Body, p.ToAddr) diff --git a/server/handler/admin_setting.go b/server/handler/admin_setting.go index b6b76f20c..42d96004f 100644 --- a/server/handler/admin_setting.go +++ b/server/handler/admin_setting.go @@ -5,6 +5,7 @@ import ( "github.com/ArtalkJS/Artalk/internal/config" "github.com/ArtalkJS/Artalk/internal/core" + "github.com/ArtalkJS/Artalk/internal/i18n" "github.com/ArtalkJS/Artalk/server/common" "github.com/gofiber/fiber/v2" "github.com/sirupsen/logrus" @@ -14,12 +15,12 @@ import ( func AdminSettingGet(router fiber.Router) { router.Post("/setting-get", func(c *fiber.Ctx) error { if !common.GetIsSuperAdmin(c) { - return common.RespError(c, "无权访问") + return common.RespError(c, i18n.T("Access denied")) } dat, err := os.ReadFile(config.GetCfgFileLoaded()) if err != nil { - return common.RespError(c, "配置文件读取失败") + return common.RespError(c, i18n.T("Config file read failed")) } return common.RespData(c, string(dat)) @@ -34,7 +35,7 @@ type ParamsAdminSettingSave struct { func AdminSettingSave(router fiber.Router) { router.Post("/setting-save", func(c *fiber.Ctx) error { if !common.GetIsSuperAdmin(c) { - return common.RespError(c, "无权访问") + return common.RespError(c, i18n.T("Access denied")) } var p ParamsAdminSettingSave @@ -45,24 +46,24 @@ func AdminSettingSave(router fiber.Router) { configFile := config.GetCfgFileLoaded() f, err := os.Create(configFile) if err != nil { - return common.RespError(c, "配置文件读取失败,"+err.Error()) + return common.RespError(c, i18n.T("Config file read failed")+": "+err.Error()) } defer f.Close() _, err2 := f.WriteString(p.Data) if err2 != nil { - return common.RespError(c, "保存失败,"+err2.Error()) + return common.RespError(c, i18n.T("Save failed")+": "+err2.Error()) } // 重启服务 workDir, err3 := os.Getwd() if err3 != nil { - return common.RespError(c, "工作路径获取失败,"+err3.Error()) + return common.RespError(c, i18n.T("Working directory retrieval failed")+": "+err3.Error()) } core.LoadCore(configFile, workDir) common.ReloadCorsAllowOrigins() // 刷新 CORS 可信域名 - logrus.Info("服务已重启完毕") + logrus.Info(i18n.T("Services restart complete")) return common.RespSuccess(c) }) diff --git a/server/handler/admin_site_add.go b/server/handler/admin_site_add.go index 27f9dd8c8..107e9feb6 100644 --- a/server/handler/admin_site_add.go +++ b/server/handler/admin_site_add.go @@ -3,6 +3,7 @@ package handler import ( "github.com/ArtalkJS/Artalk/internal/config" "github.com/ArtalkJS/Artalk/internal/entity" + "github.com/ArtalkJS/Artalk/internal/i18n" "github.com/ArtalkJS/Artalk/internal/query" "github.com/ArtalkJS/Artalk/internal/utils" "github.com/ArtalkJS/Artalk/server/common" @@ -23,24 +24,24 @@ func AdminSiteAdd(router fiber.Router) { } if !common.GetIsSuperAdmin(c) { - return common.RespError(c, "禁止创建站点") + return common.RespError(c, i18n.T("Access denied")) } if p.Urls != "" { urls := utils.SplitAndTrimSpace(p.Urls, ",") for _, url := range urls { if !utils.ValidateURL(url) { - return common.RespError(c, "Invalid url exist") + return common.RespError(c, i18n.T("Contains invalid URL")) } } } if p.Name == config.ATK_SITE_ALL { - return common.RespError(c, "禁止使用保留关键字作为名称") + return common.RespError(c, "Prohibit the use of reserved keywords as names") } if !query.FindSite(p.Name).IsEmpty() { - return common.RespError(c, "site 已存在") + return common.RespError(c, i18n.T("{{name}} already exists", Map{"name": i18n.T("Site")})) } site := entity.Site{} @@ -48,7 +49,7 @@ func AdminSiteAdd(router fiber.Router) { site.Urls = p.Urls err := query.CreateSite(&site) if err != nil { - return common.RespError(c, "site 创建失败") + return common.RespError(c, i18n.T("{{name}} creation failed", Map{"name": i18n.T("Site")})) } // 刷新 CORS 可信域名 diff --git a/server/handler/admin_site_del.go b/server/handler/admin_site_del.go index b0dbd5d90..ed41fd96a 100644 --- a/server/handler/admin_site_del.go +++ b/server/handler/admin_site_del.go @@ -1,6 +1,7 @@ package handler import ( + "github.com/ArtalkJS/Artalk/internal/i18n" "github.com/ArtalkJS/Artalk/internal/query" "github.com/ArtalkJS/Artalk/server/common" "github.com/gofiber/fiber/v2" @@ -19,17 +20,17 @@ func AdminSiteDel(router fiber.Router) { } if !common.GetIsSuperAdmin(c) { - return common.RespError(c, "禁止删除站点") + return common.RespError(c, i18n.T("Access denied")) } site := query.FindSiteByID(p.ID) if site.IsEmpty() { - return common.RespError(c, "site 不存在") + return common.RespError(c, i18n.T("{{name}} not found", Map{"name": i18n.T("Site")})) } err := query.DelSite(&site) if err != nil { - return common.RespError(c, "site 删除失败") + return common.RespError(c, i18n.T("{{name}} deletion failed", Map{"name": i18n.T("Site")})) } // 刷新 CORS 可信域名 diff --git a/server/handler/admin_site_edit.go b/server/handler/admin_site_edit.go index bec4ef595..55c33adfb 100644 --- a/server/handler/admin_site_edit.go +++ b/server/handler/admin_site_edit.go @@ -6,6 +6,7 @@ import ( "github.com/ArtalkJS/Artalk/internal/cache" "github.com/ArtalkJS/Artalk/internal/db" "github.com/ArtalkJS/Artalk/internal/entity" + "github.com/ArtalkJS/Artalk/internal/i18n" "github.com/ArtalkJS/Artalk/internal/query" "github.com/ArtalkJS/Artalk/internal/utils" "github.com/ArtalkJS/Artalk/server/common" @@ -31,29 +32,29 @@ func AdminSiteEdit(router fiber.Router) { site := query.FindSiteByID(p.ID) if site.IsEmpty() { - return common.RespError(c, "site 不存在") + return common.RespError(c, i18n.T("{{name}} not found", Map{"name": i18n.T("Site")})) } // 站点操作权限检查 if !common.IsAdminHasSiteAccess(c, site.Name) { - return common.RespError(c, "无权操作") + return common.RespError(c, i18n.T("Access denied")) } if strings.TrimSpace(p.Name) == "" { - return common.RespError(c, "site 名称不能为空白字符") + return common.RespError(c, i18n.T("{{name}} cannot be empty", Map{"name": "name"})) } // 重命名合法性检测 modifyName := p.Name != site.Name if modifyName && !query.FindSite(p.Name).IsEmpty() { - return common.RespError(c, "site 已存在,请换个名称") + return common.RespError(c, i18n.T("{{name}} already exists", Map{"name": i18n.T("Site")})) } // urls 合法性检测 if p.Urls != "" { for _, url := range utils.SplitAndTrimSpace(p.Urls, ",") { if !utils.ValidateURL(url) { - return common.RespError(c, "Invalid url exist") + return common.RespError(c, i18n.T("Contains invalid URL")) } } } @@ -85,7 +86,7 @@ func AdminSiteEdit(router fiber.Router) { err := query.UpdateSite(&site) if err != nil { - return common.RespError(c, "site 保存失败") + return common.RespError(c, i18n.T("{{name}} save failed", Map{"name": i18n.T("Site")})) } // 刷新 CORS 可信域名 diff --git a/server/handler/admin_transfer.go b/server/handler/admin_transfer.go index 722978220..16c46e372 100644 --- a/server/handler/admin_transfer.go +++ b/server/handler/admin_transfer.go @@ -7,6 +7,7 @@ import ( "os" "github.com/ArtalkJS/Artalk/internal/artransfer" + "github.com/ArtalkJS/Artalk/internal/i18n" "github.com/ArtalkJS/Artalk/internal/query" "github.com/ArtalkJS/Artalk/internal/utils" "github.com/ArtalkJS/Artalk/server/common" @@ -34,7 +35,7 @@ func adminImport(c *fiber.Ctx) error { var payloadMapRaw map[string]interface{} err := json.Unmarshal([]byte(p.Payload), &payloadMapRaw) if err != nil { - return common.RespError(c, "payload 解析错误", common.Map{ + return common.RespError(c, "Payload parsing error", common.Map{ "error": err, }) } @@ -53,10 +54,10 @@ func adminImport(c *fiber.Ctx) error { user := common.GetUserByReq(c) if sitName, isExist := payloadMap["t_name"]; isExist { if !utils.ContainsStr(query.CookUser(&user).SiteNames, sitName) { - return common.RespError(c, "禁止导入的目标站点名") + return common.RespError(c, "Destination site name of prohibited import") } } else { - return common.RespError(c, "请填写目标站点名") + return common.RespError(c, "Please fill in the target site name") } } @@ -92,14 +93,14 @@ func adminImportUpload(c *fiber.Ctx) error { file, err := c.FormFile("file") if err != nil { logrus.Error(err) - return common.RespError(c, "文件获取失败") + return common.RespError(c, "File read failed") } // 打开文件 src, err := file.Open() if err != nil { logrus.Error(err) - return common.RespError(c, "文件打开失败") + return common.RespError(c, "File open failed") } defer src.Close() @@ -107,13 +108,13 @@ func adminImportUpload(c *fiber.Ctx) error { buf, err := io.ReadAll(src) if err != nil { logrus.Error(err) - return common.RespError(c, "文件读取失败") + return common.RespError(c, "File read failed") } tmpFile, err := os.CreateTemp("", "artalk-import-file-") if err != nil { logrus.Error(err) - return common.RespError(c, "临时文件创建失败") + return common.RespError(c, "tmp file creation failed") } tmpFile.Write(buf) @@ -134,7 +135,7 @@ func adminExport(c *fiber.Ctx) error { return db }) if err != nil { - common.RespError(c, "导出错误", common.Map{ + common.RespError(c, i18n.T("Export error"), common.Map{ "err": err, }) } diff --git a/server/handler/admin_user_add.go b/server/handler/admin_user_add.go index e64b122ee..ca4765644 100644 --- a/server/handler/admin_user_add.go +++ b/server/handler/admin_user_add.go @@ -2,6 +2,7 @@ package handler import ( "github.com/ArtalkJS/Artalk/internal/entity" + "github.com/ArtalkJS/Artalk/internal/i18n" "github.com/ArtalkJS/Artalk/internal/query" "github.com/ArtalkJS/Artalk/internal/utils" "github.com/ArtalkJS/Artalk/server/common" @@ -25,7 +26,7 @@ type ParamsAdminUserAdd struct { func AdminUserAdd(router fiber.Router) { router.Post("/user-add", func(c *fiber.Ctx) error { if !common.GetIsSuperAdmin(c) { - return common.RespError(c, "无权操作") + return common.RespError(c, i18n.T("Access denied")) } var p ParamsAdminUserAdd @@ -34,14 +35,14 @@ func AdminUserAdd(router fiber.Router) { } if !query.FindUser(p.Name, p.Email).IsEmpty() { - return common.RespError(c, "用户已存在") + return common.RespError(c, i18n.T("{{name}} already exists", Map{"name": i18n.T("User")})) } if !utils.ValidateEmail(p.Email) { - return common.RespError(c, "Invalid email") + return common.RespError(c, i18n.T("Invalid {{name}}", Map{"name": i18n.T("Email")})) } if p.Link != "" && !utils.ValidateURL(p.Link) { - return common.RespError(c, "Invalid link") + return common.RespError(c, i18n.T("Invalid {{name}}", Map{"name": i18n.T("Link")})) } user := entity.User{} @@ -58,13 +59,13 @@ func AdminUserAdd(router fiber.Router) { err := user.SetPasswordEncrypt(p.Password) if err != nil { logrus.Errorln(err) - return common.RespError(c, "密码设置失败") + return common.RespError(c, i18n.T("Password update failed")) } } err := query.CreateUser(&user) if err != nil { - return common.RespError(c, "user 创建失败") + return common.RespError(c, i18n.T("{{name}} creation failed", Map{"name": i18n.T("User")})) } return common.RespData(c, common.Map{ diff --git a/server/handler/admin_user_del.go b/server/handler/admin_user_del.go index 6fb202773..2a0f292b1 100644 --- a/server/handler/admin_user_del.go +++ b/server/handler/admin_user_del.go @@ -1,6 +1,7 @@ package handler import ( + "github.com/ArtalkJS/Artalk/internal/i18n" "github.com/ArtalkJS/Artalk/internal/query" "github.com/ArtalkJS/Artalk/server/common" "github.com/gofiber/fiber/v2" @@ -14,7 +15,7 @@ type ParamsAdminUserDel struct { func AdminUserDel(router fiber.Router) { router.Post("/user-del", func(c *fiber.Ctx) error { if !common.GetIsSuperAdmin(c) { - return common.RespError(c, "无权操作") + return common.RespError(c, i18n.T("Access denied")) } var p ParamsAdminUserDel @@ -24,12 +25,12 @@ func AdminUserDel(router fiber.Router) { user := query.FindUserByID(p.ID) if user.IsEmpty() { - return common.RespError(c, "user 不存在") + return common.RespError(c, i18n.T("{{name}} not found", Map{"name": i18n.T("User")})) } err := query.DelUser(&user) if err != nil { - return common.RespError(c, "user 删除失败") + return common.RespError(c, i18n.T("{{name}} deletion failed", Map{"name": i18n.T("User")})) } return common.RespSuccess(c) }) diff --git a/server/handler/admin_user_edit.go b/server/handler/admin_user_edit.go index 44a2bd89c..4fdebca04 100644 --- a/server/handler/admin_user_edit.go +++ b/server/handler/admin_user_edit.go @@ -2,6 +2,7 @@ package handler import ( "github.com/ArtalkJS/Artalk/internal/cache" + "github.com/ArtalkJS/Artalk/internal/i18n" "github.com/ArtalkJS/Artalk/internal/query" "github.com/ArtalkJS/Artalk/internal/utils" "github.com/ArtalkJS/Artalk/server/common" @@ -28,7 +29,7 @@ type ParamsAdminUserEdit struct { func AdminUserEdit(router fiber.Router) { router.Post("/user-edit", func(c *fiber.Ctx) error { if !common.GetIsSuperAdmin(c) { - return common.RespError(c, "无权操作") + return common.RespError(c, i18n.T("Access denied")) } var p ParamsAdminUserEdit @@ -38,7 +39,7 @@ func AdminUserEdit(router fiber.Router) { user := query.FindUserByID(p.ID) if user.IsEmpty() { - return common.RespError(c, "user 不存在") + return common.RespError(c, i18n.T("{{name}} not found", Map{"name": i18n.T("User")})) } // 改名名合法性检测 @@ -46,14 +47,14 @@ func AdminUserEdit(router fiber.Router) { modifyEmail := p.Email != user.Email if modifyName && modifyEmail && !query.FindUser(p.Name, p.Email).IsEmpty() { - return common.RespError(c, "user 已存在,请更换用户名和邮箱") + return common.RespError(c, i18n.T("{{name}} already exists", Map{"name": i18n.T("User")})) } if !utils.ValidateEmail(p.Email) { - return common.RespError(c, "Invalid email") + return common.RespError(c, i18n.T("Invalid {{name}}", Map{"name": i18n.T("Email")})) } if p.Link != "" && !utils.ValidateURL(p.Link) { - return common.RespError(c, "Invalid link") + return common.RespError(c, i18n.T("Invalid {{name}}", Map{"name": i18n.T("Link")})) } // 删除原有缓存 @@ -74,7 +75,7 @@ func AdminUserEdit(router fiber.Router) { err := query.UpdateUser(&user) if err != nil { - return common.RespError(c, "user 保存失败") + return common.RespError(c, i18n.T("{{name}} save failed", Map{"name": i18n.T("User")})) } return common.RespData(c, common.Map{ diff --git a/server/handler/admin_user_get.go b/server/handler/admin_user_get.go index 6a292c174..9f60093f8 100644 --- a/server/handler/admin_user_get.go +++ b/server/handler/admin_user_get.go @@ -3,6 +3,7 @@ package handler import ( "github.com/ArtalkJS/Artalk/internal/db" "github.com/ArtalkJS/Artalk/internal/entity" + "github.com/ArtalkJS/Artalk/internal/i18n" "github.com/ArtalkJS/Artalk/internal/query" "github.com/ArtalkJS/Artalk/server/common" "github.com/gofiber/fiber/v2" @@ -23,7 +24,7 @@ type ResponseAdminUserGet struct { func AdminUserGet(router fiber.Router) { router.Post("/user-get", func(c *fiber.Ctx) error { if !common.GetIsSuperAdmin(c) { - return common.RespError(c, "无权操作") + return common.RespError(c, i18n.T("Access denied")) } var p ParamsAdminUserGet diff --git a/server/handler/admin_vote_sync.go b/server/handler/admin_vote_sync.go index 43eae10b4..d347d9766 100644 --- a/server/handler/admin_vote_sync.go +++ b/server/handler/admin_vote_sync.go @@ -1,6 +1,7 @@ package handler import ( + "github.com/ArtalkJS/Artalk/internal/i18n" "github.com/ArtalkJS/Artalk/internal/query" "github.com/ArtalkJS/Artalk/server/common" "github.com/gofiber/fiber/v2" @@ -18,7 +19,7 @@ func AdminVoteSync(router fiber.Router) { } if !common.GetIsSuperAdmin(c) { - return common.RespError(c, "无权访问") + return common.RespError(c, i18n.T("Access denied")) } query.VoteSync() diff --git a/server/handler/captcha.go b/server/handler/captcha.go index 536e74c02..b61b95c72 100644 --- a/server/handler/captcha.go +++ b/server/handler/captcha.go @@ -8,6 +8,7 @@ import ( "github.com/ArtalkJS/Artalk/internal/captcha" "github.com/ArtalkJS/Artalk/internal/config" + "github.com/ArtalkJS/Artalk/internal/i18n" "github.com/ArtalkJS/Artalk/server/common" "github.com/gofiber/fiber/v2" "github.com/sirupsen/logrus" @@ -16,7 +17,7 @@ import ( func Captcha(router fiber.Router) { ca := router.Group("/captcha/", func(c *fiber.Ctx) error { if !config.Instance.Captcha.Enabled { - return common.RespError(c, "验证码功能已关闭") + return common.RespError(c, "Captcha disabled") } return c.Next() }) @@ -87,8 +88,8 @@ func captchaCheck(c *fiber.Ctx) error { if config.Instance.Captcha.Geetest.Enabled { isPass, reason, err := captcha.GeetestCheck(inputVal) if err != nil { - logrus.Error("[Geetest] 验证发生错误 ", err) - return common.RespError(c, "Geetest API 错误") + logrus.Error("[Geetest] Failed to verify: ", err) + return common.RespError(c, "Geetest API error") } if isPass { @@ -98,7 +99,7 @@ func captchaCheck(c *fiber.Ctx) error { } else { // 验证失败 common.OnCaptchaFail(c) - return common.RespError(c, "验证失败", common.Map{ + return common.RespError(c, i18n.T("Verification failed"), common.Map{ "reason": reason, }) } @@ -117,7 +118,7 @@ func captchaCheck(c *fiber.Ctx) error { // 验证码错误 common.DisposeImageCaptcha(ip) common.OnCaptchaFail(c) - return common.RespError(c, "验证码错误", common.Map{ + return common.RespError(c, i18n.T("Wrong captcha"), common.Map{ "img_data": common.GetNewImageCaptchaBase64(ip), }) } diff --git a/server/handler/comment_add.go b/server/handler/comment_add.go index d2ce6f086..9822a19ef 100644 --- a/server/handler/comment_add.go +++ b/server/handler/comment_add.go @@ -6,6 +6,7 @@ import ( "github.com/ArtalkJS/Artalk/internal/anti_spam" "github.com/ArtalkJS/Artalk/internal/config" "github.com/ArtalkJS/Artalk/internal/entity" + "github.com/ArtalkJS/Artalk/internal/i18n" "github.com/ArtalkJS/Artalk/internal/notify_launcher" "github.com/ArtalkJS/Artalk/internal/query" "github.com/ArtalkJS/Artalk/internal/utils" @@ -43,17 +44,17 @@ func CommentAdd(router fiber.Router) { } if strings.TrimSpace(p.Name) == "" { - return common.RespError(c, "昵称不能为空") + return common.RespError(c, i18n.T("{{name}} cannot be empty", Map{"name": i18n.T("Nickname")})) } if strings.TrimSpace(p.Email) == "" { - return common.RespError(c, "邮箱不能为空") + return common.RespError(c, i18n.T("{{name}} cannot be empty", Map{"name": i18n.T("Email")})) } if !utils.ValidateEmail(p.Email) { - return common.RespError(c, "Invalid email") + return common.RespError(c, i18n.T("Invalid {{name}}", Map{"name": i18n.T("Email")})) } if p.Link != "" && !utils.ValidateURL(p.Link) { - return common.RespError(c, "Invalid link") + return common.RespError(c, i18n.T("Invalid {{name}}", Map{"name": i18n.T("Link")})) } ip := c.IP() @@ -83,13 +84,13 @@ func CommentAdd(router fiber.Router) { if p.Rid != 0 { parentComment = query.FindComment(p.Rid) if parentComment.IsEmpty() { - return common.RespError(c, "找不到父评论") + return common.RespError(c, i18n.T("{{name}} not found", Map{"name": i18n.T("Parent comment")})) } if parentComment.PageKey != p.PageKey { - return common.RespError(c, "与父评论的 pageKey 不一致") + return common.RespError(c, "Inconsistent with the page_key of the parent comment") } if !parentComment.IsAllowReply() { - return common.RespError(c, "不允许回复该评论") + return common.RespError(c, i18n.T("Cannot reply to this comment")) } } @@ -97,7 +98,7 @@ func CommentAdd(router fiber.Router) { user := query.FindCreateUser(p.Name, p.Email, p.Link) if user.ID == 0 || page.Key == "" { logrus.Error("Cannot get user or page") - return common.RespError(c, "评论失败") + return common.RespError(c, i18n.T("Comment failed")) } // update user @@ -134,7 +135,7 @@ func CommentAdd(router fiber.Router) { err := query.CreateComment(&comment) if err != nil { logrus.Error("Save Comment error: ", err) - return common.RespError(c, "评论失败") + return common.RespError(c, i18n.T("Comment failed")) } // 异步执行 diff --git a/server/handler/img_upload.go b/server/handler/img_upload.go index 2b000e398..ae8bb7eb7 100644 --- a/server/handler/img_upload.go +++ b/server/handler/img_upload.go @@ -12,6 +12,7 @@ import ( "time" "github.com/ArtalkJS/Artalk/internal/config" + "github.com/ArtalkJS/Artalk/internal/i18n" "github.com/ArtalkJS/Artalk/internal/utils" "github.com/ArtalkJS/Artalk/server/common" "github.com/gofiber/fiber/v2" @@ -36,7 +37,7 @@ func ImgUpload(router fiber.Router) { router.Post("/img-upload", func(c *fiber.Ctx) error { // 功能开关 (管理员始终开启) if !config.Instance.ImgUpload.Enabled && !common.CheckIsAdminReq(c) { - return common.RespError(c, "禁止图片上传", common.Map{ + return common.RespError(c, i18n.T("Image upload forbidden"), common.Map{ "img_upload_enabled": false, }) } @@ -48,7 +49,7 @@ func ImgUpload(router fiber.Router) { } if !utils.ValidateEmail(p.Email) { - return common.RespError(c, "Invalid email") + return common.RespError(c, i18n.T("Invalid {{name}}", Map{"name": i18n.T("Email")})) } // use site @@ -65,7 +66,9 @@ func ImgUpload(router fiber.Router) { // 图片大小限制 (Based on content length) if config.Instance.ImgUpload.MaxSize != 0 { if int64(c.Request().Header.ContentLength()) > config.Instance.ImgUpload.MaxSize*1024*1024 { - return common.RespError(c, fmt.Sprintf("图片大小超过限制 %dMB", config.Instance.ImgUpload.MaxSize)) + return common.RespError(c, i18n.T("Image exceeds {{file_size}} limit", Map{ + "file_size": fmt.Sprintf("%dMB", config.Instance.ImgUpload.MaxSize), + })) } } @@ -73,14 +76,14 @@ func ImgUpload(router fiber.Router) { file, err := c.FormFile("file") if err != nil { logrus.Error(err) - return common.RespError(c, "文件获取失败") + return common.RespError(c, "File read failed") } // 打开文件 src, err := file.Open() if err != nil { logrus.Error(err) - return common.RespError(c, "文件打开失败") + return common.RespError(c, "File open failed") } defer src.Close() @@ -88,13 +91,15 @@ func ImgUpload(router fiber.Router) { buf, err := io.ReadAll(src) if err != nil { logrus.Error(err) - return common.RespError(c, "文件读取失败") + return common.RespError(c, "File read failed") } // 大小限制 (Based on content read) if config.Instance.ImgUpload.MaxSize != 0 { if int64(len(buf)) > config.Instance.ImgUpload.MaxSize*1024*1024 { - return common.RespError(c, fmt.Sprintf("图片大小超过限制 %dMB", config.Instance.ImgUpload.MaxSize)) + return common.RespError(c, i18n.T("Image exceeds {{file_size}} limit", Map{ + "file_size": fmt.Sprintf("%dMB", config.Instance.ImgUpload.MaxSize), + })) } } @@ -107,7 +112,7 @@ func ImgUpload(router fiber.Router) { // "image/svg+xml", } if !utils.ContainsStr(allowMines, fileMine) { - return common.RespError(c, "不支持的格式") + return common.RespError(c, i18n.T("Unsupported formats")) } // 图片文件名 @@ -126,21 +131,21 @@ func ImgUpload(router fiber.Router) { // 创建图片目标文件 if err := utils.EnsureDir(config.Instance.ImgUpload.Path); err != nil { logrus.Error(err) - return common.RespError(c, "创建图片存放文件夹失败") + return common.RespError(c, "Folder creation failed") } fileFullPath := strings.TrimSuffix(config.Instance.ImgUpload.Path, "/") + "/" + filename dst, err := os.Create(fileFullPath) if err != nil { logrus.Error(err) - return common.RespError(c, "图片文件创建失败") + return common.RespError(c, "File creation failed") } defer dst.Close() // 写入图片文件 if _, err = dst.Write(buf); err != nil { logrus.Error(err) - return common.RespError(c, "图片文件写入失败") + return common.RespError(c, "File write failed") } // 生成外部可访问链接 @@ -161,7 +166,7 @@ func ImgUpload(router fiber.Router) { } logrus.Error("[IMG_UPLOAD] [upgit] upgit output: ", upgitURL) - return common.RespError(c, "图片通过 upgit 上传失败") + return common.RespError(c, i18n.T("Upload image via {{method}} failed", Map{"method": "upgit"})) } // 上传成功,删除本地文件 diff --git a/server/handler/mark_read.go b/server/handler/mark_read.go index 81e273bf7..5ac2587ce 100644 --- a/server/handler/mark_read.go +++ b/server/handler/mark_read.go @@ -1,6 +1,7 @@ package handler import ( + "github.com/ArtalkJS/Artalk/internal/i18n" "github.com/ArtalkJS/Artalk/internal/query" "github.com/ArtalkJS/Artalk/server/common" "github.com/gofiber/fiber/v2" @@ -32,7 +33,7 @@ func MarkRead(router fiber.Router) { // all read if p.AllRead { if p.Name == "" || p.Email == "" { - return common.RespError(c, "need username and email") + return common.RespError(c, "username or email cannot be empty") } user := query.FindUser(p.Name, p.Email) @@ -47,7 +48,7 @@ func MarkRead(router fiber.Router) { // find notify notify := query.FindNotifyByKey(p.NotifyKey) if notify.IsEmpty() { - return common.RespError(c, "notify key is wrong") + return common.RespError(c, i18n.T("{{name}} not found", Map{"name": i18n.T("Notify")})) } if notify.IsRead { @@ -57,7 +58,7 @@ func MarkRead(router fiber.Router) { // update notify err := query.NotifySetRead(¬ify) if err != nil { - return common.RespError(c, "notify save error") + return common.RespError(c, i18n.T("{{name}} save failed", Map{"name": i18n.T("Notify")})) } return common.RespSuccess(c) diff --git a/server/handler/stat.go b/server/handler/stat.go index c6f13560b..d042d790f 100644 --- a/server/handler/stat.go +++ b/server/handler/stat.go @@ -4,6 +4,7 @@ import ( "github.com/ArtalkJS/Artalk/internal/config" "github.com/ArtalkJS/Artalk/internal/db" "github.com/ArtalkJS/Artalk/internal/entity" + "github.com/ArtalkJS/Artalk/internal/i18n" "github.com/ArtalkJS/Artalk/internal/query" "github.com/ArtalkJS/Artalk/internal/utils" "github.com/ArtalkJS/Artalk/server/common" @@ -159,6 +160,6 @@ func Stat(router fiber.Router) { return common.RespData(c, query.CookAllPages(pages)) } - return common.RespError(c, "invalid type") + return common.RespError(c, i18n.T("Invalid {{name}}", Map{"name": i18n.T("Type")})) }) } diff --git a/server/handler/user_login.go b/server/handler/user_login.go index 3259ecf34..7f370f97d 100644 --- a/server/handler/user_login.go +++ b/server/handler/user_login.go @@ -8,6 +8,7 @@ import ( "github.com/ArtalkJS/Artalk/internal/config" "github.com/ArtalkJS/Artalk/internal/entity" + "github.com/ArtalkJS/Artalk/internal/i18n" "github.com/ArtalkJS/Artalk/internal/query" "github.com/ArtalkJS/Artalk/internal/utils" "github.com/ArtalkJS/Artalk/server/common" @@ -34,7 +35,7 @@ func UserLogin(router fiber.Router) { if p.Name == "" { // 仅 Email 的查询 if !utils.ValidateEmail(p.Email) { - return common.RespError(c, "请输入正确的邮箱") + return common.RespError(c, i18n.T("Invalid {{name}}", Map{"name": i18n.T("Email")})) } users := query.FindUsersByEmail(p.Email) if len(users) == 1 { @@ -46,7 +47,7 @@ func UserLogin(router fiber.Router) { for _, u := range users { userNames = append(userNames, u.Name) } - return common.RespError(c, "需要选择用户名", common.Map{ + return common.RespError(c, "Need to select username", common.Map{ // 前端需做处理让用户选择用户名, // 之后再发起带 name 参数的请求 "need_name_select": userNames, @@ -61,7 +62,7 @@ func UserLogin(router fiber.Router) { common.RecordAction(c) if user.IsEmpty() { - return common.RespError(c, "验证失败") + return common.RespError(c, i18n.T("Login failed")) } // 密码验证 @@ -90,7 +91,7 @@ func UserLogin(router fiber.Router) { } if !passwordOK { - return common.RespError(c, "验证失败") + return common.RespError(c, i18n.T("Login failed")) } jwtToken := common.LoginGetUserToken(user) diff --git a/server/handler/user_logout.go b/server/handler/user_logout.go index 6a0979eab..3fdb18da8 100644 --- a/server/handler/user_logout.go +++ b/server/handler/user_logout.go @@ -13,11 +13,11 @@ func UserLogout(router fiber.Router) { router.Post("/logout", func(c *fiber.Ctx) error { if !config.Instance.Cookie.Enabled { - return common.RespError(c, "API 未启用 Cookie") + return common.RespError(c, "API cookie disabled") } if common.GetJwtStrByReqCookie(c) == "" { - return common.RespError(c, "未登录,无需注销") + return common.RespError(c, "Not logged in yet, no need to log out") } // same as login, remove cookie diff --git a/server/handler/utils.go b/server/handler/utils.go new file mode 100644 index 000000000..bf47a5221 --- /dev/null +++ b/server/handler/utils.go @@ -0,0 +1,3 @@ +package handler + +type Map = map[string]interface{} diff --git a/server/handler/vote.go b/server/handler/vote.go index 3709ab9e4..5be1d4a66 100644 --- a/server/handler/vote.go +++ b/server/handler/vote.go @@ -5,6 +5,7 @@ import ( "github.com/ArtalkJS/Artalk/internal/db" "github.com/ArtalkJS/Artalk/internal/entity" + "github.com/ArtalkJS/Artalk/internal/i18n" "github.com/ArtalkJS/Artalk/internal/query" "github.com/ArtalkJS/Artalk/server/common" "github.com/gofiber/fiber/v2" @@ -60,12 +61,12 @@ func Vote(router fiber.Router) { case isVoteComment: comment = query.FindComment(p.TargetID) if comment.IsEmpty() { - return common.RespError(c, "comment not found") + return common.RespError(c, i18n.T("{{name}} not found", Map{"name": i18n.T("Comment")})) } case isVotePage: page = query.FindPageByID(p.TargetID) if page.IsEmpty() { - return common.RespError(c, "page not found") + return common.RespError(c, i18n.T("{{name}} not found", Map{"name": i18n.T("Page")})) } default: return common.RespError(c, "unknown type") diff --git a/server/middleware/admin.go b/server/middleware/admin.go index ca90d127b..798e7f76d 100644 --- a/server/middleware/admin.go +++ b/server/middleware/admin.go @@ -1,6 +1,7 @@ package middleware import ( + "github.com/ArtalkJS/Artalk/internal/i18n" "github.com/ArtalkJS/Artalk/server/common" "github.com/gofiber/fiber/v2" ) @@ -8,7 +9,7 @@ import ( func AdminOnlyMiddleware() fiber.Handler { return func(c *fiber.Ctx) error { if !common.CheckIsAdminReq(c) { - return common.RespError(c, "需要验证管理员身份", common.Map{"need_login": true}) + return common.RespError(c, i18n.T("Admin access required"), common.Map{"need_login": true}) } return c.Next() diff --git a/server/middleware/limit.go b/server/middleware/limit.go index 7e90c0e37..d16d3b35c 100644 --- a/server/middleware/limit.go +++ b/server/middleware/limit.go @@ -4,6 +4,7 @@ import ( "path" "github.com/ArtalkJS/Artalk/internal/config" + "github.com/ArtalkJS/Artalk/internal/i18n" "github.com/ArtalkJS/Artalk/server/common" "github.com/gofiber/fiber/v2" ) @@ -74,7 +75,7 @@ func ActionLimitMiddleware(conf ActionLimitConf) fiber.Handler { respData["img_data"] = common.GetNewImageCaptchaBase64(c.IP()) } - return common.RespError(c, "需要验证码", respData) + return common.RespError(c, i18n.T("Captcha required"), respData) } // 放行 diff --git a/server/middleware/site_origin.go b/server/middleware/site_origin.go index 29fc491d5..644ea7f95 100644 --- a/server/middleware/site_origin.go +++ b/server/middleware/site_origin.go @@ -1,7 +1,6 @@ package middleware import ( - "fmt" "net/url" "path" "strings" @@ -41,7 +40,7 @@ func SiteOriginMiddleware() fiber.Handler { // 请求站点名 == "__ATK_SITE_ALL" 时取消站点隔离 if siteName == config.ATK_SITE_ALL { if !isSuperAdmin { - return common.RespError(c, "仅管理员查询允许取消站点隔离") + return common.RespError(c, "Only admin can query sites with disable isolation") } siteAll = true @@ -56,9 +55,12 @@ func SiteOriginMiddleware() fiber.Handler { findSite := query.FindSite(siteName) if findSite.IsEmpty() { - return common.RespError(c, fmt.Sprintf("未找到站点:`%s`,请在控制台创建站点", siteName), common.Map{ - "err_no_site": true, - }) + return common.RespError(c, + i18n.T("Site `{{name}}` not found. Please create it in control center.", map[string]interface{}{"name": siteName}), + common.Map{ + "err_no_site": true, + }, + ) } site = &findSite siteID = findSite.ID @@ -105,7 +107,7 @@ func CheckOrigin(c *fiber.Ctx, allowSite *entity.Site) (bool, error) { // 从 Referer 获取 Origin referer := string(c.Request().Header.Referer()) if referer == "" { - return false, common.RespError(c, i18n.T("Invalid request")+", "+i18n.T("Unable to get Origin")) + return false, common.RespError(c, i18n.T("Invalid request")+", "+i18n.T("Unable to get `{{name}}`", map[string]interface{}{"name": "origin"})) } origin = referer } @@ -123,7 +125,7 @@ func CheckOrigin(c *fiber.Ctx, allowSite *entity.Site) (bool, error) { return true, nil } - return false, common.RespError(c, i18n.T("Invalid request")+", "+i18n.T("Please check trusted_domains config")) + return false, common.RespError(c, i18n.T("Invalid request. Please check your `trusted_domains` config.")) } // 判断 Origin 是否被允许 diff --git a/server/server.go b/server/server.go index 1af93b6c1..d691c8d43 100644 --- a/server/server.go +++ b/server/server.go @@ -125,7 +125,7 @@ func index(f fiber.Router) { func uploadedStatic(f fiber.Router) { if config.Instance.ImgUpload.Path == "" { config.Instance.ImgUpload.Path = "./data/artalk-img/" - logrus.Warn("图片上传功能 img_upload.path 未配置,使用默认值:" + config.Instance.ImgUpload.Path) + logrus.Warn("[Image Upload] img_upload.path is not configured, using the default value: " + config.Instance.ImgUpload.Path) } // 图片上传静态资源可访问路径