From 3062d573a7617339324c23cdd4755f8f04956b92 Mon Sep 17 00:00:00 2001 From: rich Date: Tue, 7 Sep 2004 10:14:07 +0000 Subject: [PATCH 1/1] Moved to merjis/tools/wiki. --- .cvsignore | 1 + COPYING | 341 ++++++++++++++++++++++ MANIFEST | 112 +++++++ Makefile | 90 ++++++ Makefile.config | 13 + README | 115 ++++++++ cocanwiki.sql | 419 +++++++++++++++++++++++++++ conf/cocanwiki.conf | 75 +++++ debian/.cvsignore | 4 + debian/changelog | 6 + debian/compat | 1 + debian/control | 17 ++ debian/copyright | 21 ++ debian/docs | 2 + debian/rules | 78 +++++ html/_bin/.cvsignore | 1 + html/_css/admin.css | 33 +++ html/_css/create.css | 22 ++ html/_css/editor.css | 95 ++++++ html/_css/files.css | 8 + html/_css/images.css | 12 + html/_css/markup.css | 32 ++ html/_css/standard.css | 189 ++++++++++++ html/_graphics/.cvsignore | 1 + html/_graphics/arrow-down.png | Bin 0 -> 215 bytes html/_graphics/arrow-up.png | Bin 0 -> 211 bytes html/_graphics/cross.png | Bin 0 -> 177 bytes html/_graphics/error.png | Bin 0 -> 363 bytes html/_graphics/external.png | Bin 0 -> 267 bytes html/_graphics/file.png | Bin 0 -> 305 bytes html/_graphics/mailto.png | Bin 0 -> 235 bytes html/_graphics/markup-preview.png | Bin 0 -> 23363 bytes html/_graphics/newpage.png | Bin 0 -> 201 bytes html/_graphics/ok.png | Bin 0 -> 1636 bytes html/_js/editor.js | 45 +++ html/_static/markup.html | 134 +++++++++ html/robots.txt | 0 scripts/.cvsignore | 4 + scripts/.depend | 110 +++++++ scripts/Makefile | 103 +++++++ scripts/admin/.cvsignore | 2 + scripts/admin/admin.ml | 74 +++++ scripts/admin/create_host.ml | 86 ++++++ scripts/admin/create_host_form.ml | 24 ++ scripts/admin/edit_emails.ml | 80 +++++ scripts/admin/edit_emails_form.ml | 44 +++ scripts/admin/edit_host_css.ml | 48 +++ scripts/admin/edit_host_css_form.ml | 34 +++ scripts/admin/edit_hostnames.ml | 79 +++++ scripts/admin/edit_hostnames_form.ml | 40 +++ scripts/admin/host.ml | 98 +++++++ scripts/cgi_expires.ml | 54 ++++ scripts/cocanwiki.ml | 89 ++++++ scripts/cocanwiki_diff.ml | 82 ++++++ scripts/cocanwiki_emailnotify.ml | 41 +++ scripts/cocanwiki_ok.ml | 34 +++ scripts/cocanwiki_version.ml.in | 4 + scripts/create.ml | 78 +++++ scripts/create_form.ml | 40 +++ scripts/delete_file.ml | 46 +++ scripts/delete_file_form.ml | 33 +++ scripts/delete_image.ml | 45 +++ scripts/delete_image_form.ml | 41 +++ scripts/diff.ml | 51 ++++ scripts/edit.ml | 482 +++++++++++++++++++++++++++++++ scripts/edit_page_css.ml | 92 ++++++ scripts/edit_page_css_form.ml | 35 +++ scripts/file.ml | 48 +++ scripts/files.ml | 52 ++++ scripts/history.ml | 70 +++++ scripts/hoststyle.ml | 36 +++ scripts/image.ml | 51 ++++ scripts/images.ml | 72 +++++ scripts/merjisforwiki.ml | 334 +++++++++++++++++++++ scripts/merjisforwiki.mli | 56 ++++ scripts/page.ml | 212 ++++++++++++++ scripts/pagestyle.ml | 51 ++++ scripts/preview.ml | 25 ++ scripts/recent.ml | 68 +++++ scripts/restore.ml | 89 ++++++ scripts/restore_form.ml | 51 ++++ scripts/search.ml | 26 ++ scripts/sitemap.ml | 59 ++++ scripts/undelete_file.ml | 56 ++++ scripts/undelete_file_form.ml | 38 +++ scripts/undelete_image.ml | 61 ++++ scripts/undelete_image_form.ml | 42 +++ scripts/upload_file.ml | 76 +++++ scripts/upload_file_form.ml | 22 ++ scripts/upload_image.ml | 126 ++++++++ scripts/upload_image_form.ml | 22 ++ scripts/wikilib.ml | 469 ++++++++++++++++++++++++++++++ scripts/wikilib.mli | 16 + templates/admin/admin.html | 53 ++++ templates/admin/create_host_form.html | 56 ++++ templates/admin/edit_emails_form.html | 48 +++ templates/admin/edit_host_css_form.html | 45 +++ templates/admin/edit_hostnames_form.html | 52 ++++ templates/admin/host.html | 87 ++++++ templates/create_form.html | 56 ++++ templates/delete_file_form.html | 44 +++ templates/delete_image_form.html | 42 +++ templates/diff.html | 40 +++ templates/edit.html | 84 ++++++ templates/edit_conflict.html | 51 ++++ templates/edit_page_css_form.html | 45 +++ templates/files.html | 73 +++++ templates/history.html | 42 +++ templates/images.html | 75 +++++ templates/ok_error.html | 45 +++ templates/page.html | 65 +++++ templates/page_404.html | 37 +++ templates/recent.html | 43 +++ templates/restore_form.html | 46 +++ templates/sitemap.html | 36 +++ templates/undelete_file_form.html | 44 +++ templates/undelete_image_form.html | 42 +++ templates/upload_file_form.html | 74 +++++ templates/upload_image_form.html | 107 +++++++ 119 files changed, 7600 insertions(+) create mode 100644 .cvsignore create mode 100644 COPYING create mode 100644 MANIFEST create mode 100644 Makefile create mode 100644 Makefile.config create mode 100644 README create mode 100644 cocanwiki.sql create mode 100644 conf/cocanwiki.conf create mode 100644 debian/.cvsignore create mode 100644 debian/changelog create mode 100644 debian/compat create mode 100644 debian/control create mode 100644 debian/copyright create mode 100644 debian/docs create mode 100755 debian/rules create mode 100644 html/_bin/.cvsignore create mode 100644 html/_css/admin.css create mode 100644 html/_css/create.css create mode 100644 html/_css/editor.css create mode 100644 html/_css/files.css create mode 100644 html/_css/images.css create mode 100644 html/_css/markup.css create mode 100644 html/_css/standard.css create mode 100644 html/_graphics/.cvsignore create mode 100644 html/_graphics/arrow-down.png create mode 100644 html/_graphics/arrow-up.png create mode 100644 html/_graphics/cross.png create mode 100644 html/_graphics/error.png create mode 100644 html/_graphics/external.png create mode 100644 html/_graphics/file.png create mode 100644 html/_graphics/mailto.png create mode 100644 html/_graphics/markup-preview.png create mode 100644 html/_graphics/newpage.png create mode 100644 html/_graphics/ok.png create mode 100644 html/_js/editor.js create mode 100644 html/_static/markup.html create mode 100644 html/robots.txt create mode 100644 scripts/.cvsignore create mode 100644 scripts/.depend create mode 100644 scripts/Makefile create mode 100644 scripts/admin/.cvsignore create mode 100644 scripts/admin/admin.ml create mode 100644 scripts/admin/create_host.ml create mode 100644 scripts/admin/create_host_form.ml create mode 100644 scripts/admin/edit_emails.ml create mode 100644 scripts/admin/edit_emails_form.ml create mode 100644 scripts/admin/edit_host_css.ml create mode 100644 scripts/admin/edit_host_css_form.ml create mode 100644 scripts/admin/edit_hostnames.ml create mode 100644 scripts/admin/edit_hostnames_form.ml create mode 100644 scripts/admin/host.ml create mode 100644 scripts/cgi_expires.ml create mode 100644 scripts/cocanwiki.ml create mode 100644 scripts/cocanwiki_diff.ml create mode 100644 scripts/cocanwiki_emailnotify.ml create mode 100644 scripts/cocanwiki_ok.ml create mode 100644 scripts/cocanwiki_version.ml.in create mode 100644 scripts/create.ml create mode 100644 scripts/create_form.ml create mode 100644 scripts/delete_file.ml create mode 100644 scripts/delete_file_form.ml create mode 100644 scripts/delete_image.ml create mode 100644 scripts/delete_image_form.ml create mode 100644 scripts/diff.ml create mode 100644 scripts/edit.ml create mode 100644 scripts/edit_page_css.ml create mode 100644 scripts/edit_page_css_form.ml create mode 100644 scripts/file.ml create mode 100644 scripts/files.ml create mode 100644 scripts/history.ml create mode 100644 scripts/hoststyle.ml create mode 100644 scripts/image.ml create mode 100644 scripts/images.ml create mode 100644 scripts/merjisforwiki.ml create mode 100644 scripts/merjisforwiki.mli create mode 100644 scripts/page.ml create mode 100644 scripts/pagestyle.ml create mode 100644 scripts/preview.ml create mode 100644 scripts/recent.ml create mode 100644 scripts/restore.ml create mode 100644 scripts/restore_form.ml create mode 100644 scripts/search.ml create mode 100644 scripts/sitemap.ml create mode 100644 scripts/undelete_file.ml create mode 100644 scripts/undelete_file_form.ml create mode 100644 scripts/undelete_image.ml create mode 100644 scripts/undelete_image_form.ml create mode 100644 scripts/upload_file.ml create mode 100644 scripts/upload_file_form.ml create mode 100644 scripts/upload_image.ml create mode 100644 scripts/upload_image_form.ml create mode 100644 scripts/wikilib.ml create mode 100644 scripts/wikilib.mli create mode 100644 templates/admin/admin.html create mode 100644 templates/admin/create_host_form.html create mode 100644 templates/admin/edit_emails_form.html create mode 100644 templates/admin/edit_host_css_form.html create mode 100644 templates/admin/edit_hostnames_form.html create mode 100644 templates/admin/host.html create mode 100644 templates/create_form.html create mode 100644 templates/delete_file_form.html create mode 100644 templates/delete_image_form.html create mode 100644 templates/diff.html create mode 100644 templates/edit.html create mode 100644 templates/edit_conflict.html create mode 100644 templates/edit_page_css_form.html create mode 100644 templates/files.html create mode 100644 templates/history.html create mode 100644 templates/images.html create mode 100644 templates/ok_error.html create mode 100644 templates/page.html create mode 100644 templates/page_404.html create mode 100644 templates/recent.html create mode 100644 templates/restore_form.html create mode 100644 templates/sitemap.html create mode 100644 templates/undelete_file_form.html create mode 100644 templates/undelete_image_form.html create mode 100644 templates/upload_file_form.html create mode 100644 templates/upload_image_form.html diff --git a/.cvsignore b/.cvsignore new file mode 100644 index 0000000..20cd39b --- /dev/null +++ b/.cvsignore @@ -0,0 +1 @@ +cocanwiki-*.tar.gz \ No newline at end of file diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..1942c43 --- /dev/null +++ b/COPYING @@ -0,0 +1,341 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place - Suite 330 + Boston, MA 02111-1307, USA. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) 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 +this service 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 make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. 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. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute 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 and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +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 +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the 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 a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, 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. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE 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. + + 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 +convey 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) 19yy + + 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 2 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; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19yy name of author + Gnomovision 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, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This 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 Library General +Public License instead of this License. diff --git a/MANIFEST b/MANIFEST new file mode 100644 index 0000000..dc0f32a --- /dev/null +++ b/MANIFEST @@ -0,0 +1,112 @@ +.cvsignore +COPYING +MANIFEST +Makefile +Makefile.config +README +cocanwiki.sql +conf/cocanwiki.conf +html/_bin/.cvsignore +html/_css/admin.css +html/_css/create.css +html/_css/editor.css +html/_css/files.css +html/_css/images.css +html/_css/markup.css +html/_css/standard.css +html/_graphics/.cvsignore +html/_graphics/arrow-down.png +html/_graphics/arrow-up.png +html/_graphics/cross.png +html/_graphics/error.png +html/_graphics/external.png +html/_graphics/file.png +html/_graphics/mailto.png +html/_graphics/markup-preview.png +html/_graphics/newpage.png +html/_graphics/ok.png +html/_js/editor.js +html/_static/markup.html +html/robots.txt +scripts/.cvsignore +scripts/.depend +scripts/Makefile +scripts/admin/.cvsignore +scripts/admin/admin.ml +scripts/admin/create_host.ml +scripts/admin/create_host_form.ml +scripts/admin/edit_emails.ml +scripts/admin/edit_emails_form.ml +scripts/admin/edit_host_css.ml +scripts/admin/edit_host_css_form.ml +scripts/admin/edit_hostnames.ml +scripts/admin/edit_hostnames_form.ml +scripts/admin/host.ml +scripts/cgi_expires.ml +scripts/cocanwiki.ml +scripts/cocanwiki_diff.ml +scripts/cocanwiki_emailnotify.ml +scripts/cocanwiki_ok.ml +scripts/cocanwiki_version.ml.in +scripts/create.ml +scripts/create_form.ml +scripts/delete_file.ml +scripts/delete_file_form.ml +scripts/delete_image.ml +scripts/delete_image_form.ml +scripts/diff.ml +scripts/edit.ml +scripts/edit_page_css.ml +scripts/edit_page_css_form.ml +scripts/file.ml +scripts/files.ml +scripts/history.ml +scripts/hoststyle.ml +scripts/image.ml +scripts/images.ml +scripts/merjisforwiki.ml +scripts/merjisforwiki.mli +scripts/page.ml +scripts/pagestyle.ml +scripts/preview.ml +scripts/recent.ml +scripts/restore.ml +scripts/restore_form.ml +scripts/search.ml +scripts/sitemap.ml +scripts/undelete_file.ml +scripts/undelete_file_form.ml +scripts/undelete_image.ml +scripts/undelete_image_form.ml +scripts/upload_file.ml +scripts/upload_file_form.ml +scripts/upload_image.ml +scripts/upload_image_form.ml +scripts/wikilib.ml +scripts/wikilib.mli +templates/admin/admin.html +templates/admin/create_host_form.html +templates/admin/edit_emails_form.html +templates/admin/edit_host_css_form.html +templates/admin/edit_hostnames_form.html +templates/admin/host.html +templates/create_form.html +templates/delete_file_form.html +templates/delete_image_form.html +templates/diff.html +templates/edit.html +templates/edit_conflict.html +templates/edit_page_css_form.html +templates/files.html +templates/history.html +templates/images.html +templates/ok_error.html +templates/page.html +templates/page_404.html +templates/recent.html +templates/restore_form.html +templates/sitemap.html +templates/undelete_file_form.html +templates/undelete_image_form.html +templates/upload_file_form.html +templates/upload_image_form.html diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..f3fe0e3 --- /dev/null +++ b/Makefile @@ -0,0 +1,90 @@ +# $Id: Makefile,v 1.1 2004/09/07 10:14:07 rich Exp $ + +include Makefile.config + +all: + $(MAKE) -C scripts all + +install: + $(MAKE) -C scripts install + +# This installs the package centrally (you need to be root). I only +# use this for packaging up .debs. +pkg-install: + $(MAKE) -C scripts install + + install -d -m 0755 $(DESTDIR)$(APACHECONFDIR) + install -m 0644 conf/cocanwiki.conf $(DESTDIR)$(APACHECONFDIR)/cocanwiki.conf + + install -d -m 0755 $(DESTDIR)$(WIKIINSTALLDIR) + install -d -m 0755 $(DESTDIR)$(WIKIINSTALLDIR)/conf + install -d -m 0755 $(DESTDIR)$(WIKIINSTALLDIR)/html + install -d -m 0755 $(DESTDIR)$(WIKIINSTALLDIR)/html/_bin + install -d -m 0755 $(DESTDIR)$(WIKIINSTALLDIR)/html/_bin/admin + install -d -m 0755 $(DESTDIR)$(WIKIINSTALLDIR)/html/_css + install -d -m 0755 $(DESTDIR)$(WIKIINSTALLDIR)/html/_graphics + install -d -m 0755 $(DESTDIR)$(WIKIINSTALLDIR)/html/_js + install -d -m 0755 $(DESTDIR)$(WIKIINSTALLDIR)/html/_static + install -d -m 0755 $(DESTDIR)$(WIKIINSTALLDIR)/templates + + install -m 0644 cocanwiki.sql $(DESTDIR)$(WIKIINSTALLDIR) + install -m 0644 conf/cocanwiki.conf $(DESTDIR)$(WIKIINSTALLDIR)/conf + install -m 0644 html/robots.txt $(DESTDIR)$(WIKIINSTALLDIR)/html + install -m 0644 html/_bin/*.cma $(DESTDIR)$(WIKIINSTALLDIR)/html/_bin + install -m 0644 html/_bin/*.cmo $(DESTDIR)$(WIKIINSTALLDIR)/html/_bin + install -m 0644 html/_bin/admin/*.cmo $(DESTDIR)$(WIKIINSTALLDIR)/html/_bin/admin + install -m 0644 html/_css/*.css $(DESTDIR)$(WIKIINSTALLDIR)/html/_css + install -m 0644 html/_graphics/*.png $(DESTDIR)$(WIKIINSTALLDIR)/html/_graphics + install -m 0644 html/_js/*.js $(DESTDIR)$(WIKIINSTALLDIR)/html/_js + install -m 0644 html/_static/*.html $(DESTDIR)$(WIKIINSTALLDIR)/html/_static + install -m 0644 templates/*.html $(DESTDIR)$(WIKIINSTALLDIR)/templates + +clean: + rm -f *~ core + $(MAKE) -C scripts clean + +cocanwiki.sql: + pg_dump -i -s cocanwiki > $@ + +dist: + $(MAKE) check-manifest + rm -rf $(PACKAGE)-$(VERSION) + mkdir $(PACKAGE)-$(VERSION) + tar -cf - -T MANIFEST | tar -C $(PACKAGE)-$(VERSION) -xf - + tar zcf $(PACKAGE)-$(VERSION).tar.gz $(PACKAGE)-$(VERSION) + rm -rf $(PACKAGE)-$(VERSION) + ls -l $(PACKAGE)-$(VERSION).tar.gz + +check-manifest: + @for d in `find -type d -name CVS | grep -v '^\./debian/'`; \ + do \ + b=`dirname $$d`/; \ + awk -F/ '$$1 != "D" {print $$2}' $$d/Entries | \ + sed -e "s|^|$$b|" -e "s|^\./||"; \ + done | sort > .check-manifest; \ + sort MANIFEST > .orig-manifest; \ + diff -u .orig-manifest .check-manifest; rv=$$?; \ + rm -f .orig-manifest .check-manifest; \ + exit $$rv + +# Build Debian package. +dpkg: + @if [ 0 != `cvs -q update | wc -l` ]; then \ + echo Please commit all changes to CVS first.; \ + exit 1; \ + fi + $(MAKE) dist + rm -rf /tmp/dbuild + mkdir /tmp/dbuild + cp $(PACKAGE)-$(VERSION).tar.gz \ + /tmp/dbuild/cocanwiki_$(VERSION).orig.tar.gz + export CVSROOT=`cat CVS/Root`; \ + cd /tmp/dbuild && \ + cvs export \ + -d cocanwiki-$(VERSION) \ + -D now merjis/test/wiki + cd /tmp/dbuild/cocanwiki-$(VERSION) && dpkg-buildpackage -rfakeroot + rm -rf /tmp/dbuild/cocanwiki-$(VERSION) + ls -l /tmp/dbuild + +.PHONY: depend pkg-install dist check-manifest dpkg diff --git a/Makefile.config b/Makefile.config new file mode 100644 index 0000000..16524af --- /dev/null +++ b/Makefile.config @@ -0,0 +1,13 @@ +# $Id: Makefile.config,v 1.1 2004/09/07 10:14:07 rich Exp $ + +PACKAGE := cocanwiki +VERSION := 0.9.7 + +# Normally ignored. However, if you are installing centrally (using +# 'make pkg-install'), then the components are installed in the +# following directories. This really only applies for packagers +# building the Debian package. + +APACHECONFDIR := /etc/apache + +WIKIINSTALLDIR := /usr/share/cocanwiki diff --git a/README b/README new file mode 100644 index 0000000..f71bd17 --- /dev/null +++ b/README @@ -0,0 +1,115 @@ +README for COCANWIKI +-------------------- + +This is a Wiki, written in Objective CAML by Richard W.M. Jones +(rich@merjis.com). + +It is licensed to you under the GNU General Public License (GNU GPL). +Please see the file COPYING in this directory for full details. + +Requirements +------------ + +* Apache (probably Apache version 1.3, unless you want to build your + own version of Apache 2.0 which doesn't include PCRE). + +* Objective CAML 3.07 or above. + +* PCRE library for OCaml. + +* ExtLib for OCaml. + http://ocaml-lib.sourceforge.net/ + +* mod_caml and DBI libraries for OCaml. + http://www.merjis.com/developers/mod_caml/ + +* PostgreSQL database 7.3 or above. + +* Postgres bindings for OCaml. + http://www.eleves.ens.fr/home/frisch/soft#postgres + (Markus Mottl's later version, renamed PostgreSQL, will probably work, but + you may need to modify a little bit of the code in scripts/cocanwiki.ml so + it connects to the right database using the right driver). + +Installation +------------ + +First install all of the above requirements, and check that they're +working. + +Type 'make all install' (you don't need to be root). + +Then create a UNICODE database called 'cocanwiki' and load the schema +from 'cocanwiki.sql'. + +Create a Wiki site by hand in the database: + + begin work; + set constraints "hosts_hostname_cn" deferred; + insert into hosts (canonical_hostname) values ('test.cocan.org'); + -- HOSTID is the value of hosts.id, normally 1 + insert into hostnames (hostid, name) values (HOSTID, 'test.cocan.org'); + commit work; + +Create an index page by hand in the database: + + insert into pages (hostid, url, title, description) values (HOSTID, 'index', + 'Index Page', 'Index Page'); + +Modify your Apache configuration, adding: + + CamlLoad ...path/to/html/_bin/cocanwiki.cma + + + ServerAdmin you@example.com + DocumentRoot ...path/to/html + ServerName test.cocan.org + Include ....path/to/conf/cocanwiki.conf + + +(Change 'test.cocan.org' to a suitable local server name, and set the +paths as appropriate). + +Set any necessary environment variables and start up the server: + + export COCANWIKI_TEMPLATES=...path/to/templates + # The following is not required if the database is running locally: + export PGHOST=hostname.of.database + # Replace this with however you would normally start your webserver: + /usr/bin/apache + +Try connecting to the local server using your browser. If it doesn't +work, look in the Apache error_log file. + +More notes on setting environment variables +------------------------------------------- + +You CANNOT use SetEnv to set COCANWIKI_TEMPLATES and/or PGHOST. This +is because SetEnv runs too late in the Apache handler cycle for it to +be picked up by the scripts. + +On Debian you must modify /etc/init.d/apache in order to set up +environment variables. On the line which reads: + +ENV="env -i ...." + +remove the -i option from env (Debian bug #252627, marked as WONTFIX). + +Directory layout +---------------- + + html/ + + Everything visible under the webserver root. + + conf/ + + Configuration fragment for Apache. + + scripts/ + + CGI scripts. + + templates/ + + Templates used by the CGI scripts. diff --git a/cocanwiki.sql b/cocanwiki.sql new file mode 100644 index 0000000..b3f8646 --- /dev/null +++ b/cocanwiki.sql @@ -0,0 +1,419 @@ +-- +-- PostgreSQL database dump +-- + +SET client_encoding = 'UNICODE'; +SET check_function_bodies = false; + +SET SESSION AUTHORIZATION 'postgres'; + +-- +-- TOC entry 4 (OID 2200) +-- Name: public; Type: ACL; Schema: -; Owner: postgres +-- + +REVOKE ALL ON SCHEMA public FROM PUBLIC; +REVOKE ALL ON SCHEMA public FROM postgres; +GRANT ALL ON SCHEMA public TO PUBLIC; + + +SET SESSION AUTHORIZATION 'rich'; + +SET search_path = public, pg_catalog; + +-- +-- TOC entry 5 (OID 536004) +-- Name: pages; Type: TABLE; Schema: public; Owner: rich +-- + +CREATE TABLE pages ( + id serial NOT NULL, + url text, + url_deleted text, + title text NOT NULL, + description text NOT NULL, + creation_date timestamp without time zone DEFAULT ('now'::text)::timestamp(6) with time zone NOT NULL, + last_modified_date timestamp without time zone DEFAULT ('now'::text)::timestamp(6) with time zone NOT NULL, + hostid integer NOT NULL, + logged_ip text, + redirect text, + css text +); + + +-- +-- TOC entry 6 (OID 536004) +-- Name: pages; Type: ACL; Schema: public; Owner: rich +-- + +REVOKE ALL ON TABLE pages FROM PUBLIC; +GRANT ALL ON TABLE pages TO "www-data"; + + +-- +-- TOC entry 19 (OID 536004) +-- Name: pages_id_seq; Type: ACL; Schema: public; Owner: rich +-- + +REVOKE ALL ON TABLE pages_id_seq FROM PUBLIC; +GRANT ALL ON TABLE pages_id_seq TO "www-data"; + + +-- +-- TOC entry 7 (OID 536021) +-- Name: contents; Type: TABLE; Schema: public; Owner: rich +-- + +CREATE TABLE contents ( + id serial NOT NULL, + pageid integer NOT NULL, + ordering integer NOT NULL, + sectionname text NOT NULL, + content text NOT NULL, + divname text +); + + +-- +-- TOC entry 8 (OID 536021) +-- Name: contents; Type: ACL; Schema: public; Owner: rich +-- + +REVOKE ALL ON TABLE contents FROM PUBLIC; +GRANT ALL ON TABLE contents TO "www-data"; + + +-- +-- TOC entry 20 (OID 536021) +-- Name: contents_id_seq; Type: ACL; Schema: public; Owner: rich +-- + +REVOKE ALL ON TABLE contents_id_seq FROM PUBLIC; +GRANT ALL ON TABLE contents_id_seq TO "www-data"; + + +-- +-- TOC entry 9 (OID 536371) +-- Name: hosts; Type: TABLE; Schema: public; Owner: rich +-- + +CREATE TABLE hosts ( + id serial NOT NULL, + canonical_hostname text NOT NULL, + css text +); + + +-- +-- TOC entry 10 (OID 536371) +-- Name: hosts; Type: ACL; Schema: public; Owner: rich +-- + +REVOKE ALL ON TABLE hosts FROM PUBLIC; +GRANT ALL ON TABLE hosts TO "www-data"; + + +-- +-- TOC entry 21 (OID 536371) +-- Name: hosts_id_seq; Type: ACL; Schema: public; Owner: rich +-- + +REVOKE ALL ON TABLE hosts_id_seq FROM PUBLIC; +GRANT ALL ON TABLE hosts_id_seq TO "www-data"; + + +-- +-- TOC entry 11 (OID 536379) +-- Name: hostnames; Type: TABLE; Schema: public; Owner: rich +-- + +CREATE TABLE hostnames ( + hostid integer NOT NULL, + name text NOT NULL +); + + +-- +-- TOC entry 12 (OID 536379) +-- Name: hostnames; Type: ACL; Schema: public; Owner: rich +-- + +REVOKE ALL ON TABLE hostnames FROM PUBLIC; +GRANT ALL ON TABLE hostnames TO "www-data"; + + +-- +-- TOC entry 13 (OID 536915) +-- Name: email_notify; Type: TABLE; Schema: public; Owner: rich +-- + +CREATE TABLE email_notify ( + hostid integer NOT NULL, + email text NOT NULL, + name text +); + + +-- +-- TOC entry 14 (OID 536915) +-- Name: email_notify; Type: ACL; Schema: public; Owner: rich +-- + +REVOKE ALL ON TABLE email_notify FROM PUBLIC; +GRANT ALL ON TABLE email_notify TO "www-data"; + + +-- +-- TOC entry 15 (OID 537151) +-- Name: images; Type: TABLE; Schema: public; Owner: rich +-- + +CREATE TABLE images ( + id serial NOT NULL, + hostid integer NOT NULL, + name text, + name_deleted text, + image bytea NOT NULL, + width integer NOT NULL, + height integer NOT NULL, + alt text NOT NULL, + title text, + longdesc text, + "class" text, + mime_type text NOT NULL, + thumbnail bytea, + tn_width integer, + tn_height integer, + tn_mime_type text, + upload_date timestamp without time zone DEFAULT ('now'::text)::timestamp(6) with time zone NOT NULL +); + + +-- +-- TOC entry 16 (OID 537151) +-- Name: images; Type: ACL; Schema: public; Owner: rich +-- + +REVOKE ALL ON TABLE images FROM PUBLIC; +GRANT ALL ON TABLE images TO "www-data"; + + +-- +-- TOC entry 22 (OID 537151) +-- Name: images_id_seq; Type: ACL; Schema: public; Owner: rich +-- + +REVOKE ALL ON TABLE images_id_seq FROM PUBLIC; +GRANT ALL ON TABLE images_id_seq TO "www-data"; + + +-- +-- TOC entry 17 (OID 537166) +-- Name: files; Type: TABLE; Schema: public; Owner: rich +-- + +CREATE TABLE files ( + id serial NOT NULL, + hostid integer NOT NULL, + name text, + name_deleted text, + content bytea NOT NULL, + title text, + mime_type text NOT NULL, + upload_date timestamp without time zone DEFAULT ('now'::text)::timestamp(6) with time zone NOT NULL +); + + +-- +-- TOC entry 18 (OID 537166) +-- Name: files; Type: ACL; Schema: public; Owner: rich +-- + +REVOKE ALL ON TABLE files FROM PUBLIC; +GRANT ALL ON TABLE files TO "www-data"; + + +-- +-- TOC entry 23 (OID 537166) +-- Name: files_id_seq; Type: ACL; Schema: public; Owner: rich +-- + +REVOKE ALL ON TABLE files_id_seq FROM PUBLIC; +GRANT ALL ON TABLE files_id_seq TO "www-data"; + + +-- +-- TOC entry 28 (OID 536388) +-- Name: hostnames_hostid_name_uq; Type: INDEX; Schema: public; Owner: rich +-- + +CREATE UNIQUE INDEX hostnames_hostid_name_uq ON hostnames USING btree (hostid, name); + + +-- +-- TOC entry 29 (OID 536389) +-- Name: hostnams_name_uq; Type: INDEX; Schema: public; Owner: rich +-- + +CREATE UNIQUE INDEX hostnams_name_uq ON hostnames USING btree (name); + + +-- +-- TOC entry 25 (OID 536419) +-- Name: pages_url_uq; Type: INDEX; Schema: public; Owner: rich +-- + +CREATE UNIQUE INDEX pages_url_uq ON pages USING btree (hostid, url); + + +-- +-- TOC entry 30 (OID 536924) +-- Name: email_notify_email_uq; Type: INDEX; Schema: public; Owner: rich +-- + +CREATE UNIQUE INDEX email_notify_email_uq ON email_notify USING btree (hostid, email); + + +-- +-- TOC entry 31 (OID 540251) +-- Name: images_name_uq; Type: INDEX; Schema: public; Owner: rich +-- + +CREATE UNIQUE INDEX images_name_uq ON images USING btree (hostid, name); + + +-- +-- TOC entry 33 (OID 540252) +-- Name: files_name_uq; Type: INDEX; Schema: public; Owner: rich +-- + +CREATE UNIQUE INDEX files_name_uq ON files USING btree (hostid, name); + + +-- +-- TOC entry 24 (OID 536012) +-- Name: pages_pkey; Type: CONSTRAINT; Schema: public; Owner: rich +-- + +ALTER TABLE ONLY pages + ADD CONSTRAINT pages_pkey PRIMARY KEY (id); + + +-- +-- TOC entry 26 (OID 536027) +-- Name: contents_pkey; Type: CONSTRAINT; Schema: public; Owner: rich +-- + +ALTER TABLE ONLY contents + ADD CONSTRAINT contents_pkey PRIMARY KEY (id); + + +-- +-- TOC entry 27 (OID 536377) +-- Name: hosts_pkey; Type: CONSTRAINT; Schema: public; Owner: rich +-- + +ALTER TABLE ONLY hosts + ADD CONSTRAINT hosts_pkey PRIMARY KEY (id); + + +-- +-- TOC entry 32 (OID 537158) +-- Name: images_pkey; Type: CONSTRAINT; Schema: public; Owner: rich +-- + +ALTER TABLE ONLY images + ADD CONSTRAINT images_pkey PRIMARY KEY (id); + + +-- +-- TOC entry 34 (OID 537173) +-- Name: files_pkey; Type: CONSTRAINT; Schema: public; Owner: rich +-- + +ALTER TABLE ONLY files + ADD CONSTRAINT files_pkey PRIMARY KEY (id); + + +-- +-- TOC entry 37 (OID 536029) +-- Name: $1; Type: FK CONSTRAINT; Schema: public; Owner: rich +-- + +ALTER TABLE ONLY contents + ADD CONSTRAINT "$1" FOREIGN KEY (pageid) REFERENCES pages(id); + + +-- +-- TOC entry 39 (OID 536384) +-- Name: $1; Type: FK CONSTRAINT; Schema: public; Owner: rich +-- + +ALTER TABLE ONLY hostnames + ADD CONSTRAINT "$1" FOREIGN KEY (hostid) REFERENCES hosts(id); + + +-- +-- TOC entry 38 (OID 536394) +-- Name: hosts_hostname_cn; Type: FK CONSTRAINT; Schema: public; Owner: rich +-- + +ALTER TABLE ONLY hosts + ADD CONSTRAINT hosts_hostname_cn FOREIGN KEY (id, canonical_hostname) REFERENCES hostnames(hostid, name) DEFERRABLE; + + +-- +-- TOC entry 35 (OID 536404) +-- Name: $1; Type: FK CONSTRAINT; Schema: public; Owner: rich +-- + +ALTER TABLE ONLY pages + ADD CONSTRAINT "$1" FOREIGN KEY (hostid) REFERENCES hosts(id); + + +-- +-- TOC entry 40 (OID 536920) +-- Name: $1; Type: FK CONSTRAINT; Schema: public; Owner: rich +-- + +ALTER TABLE ONLY email_notify + ADD CONSTRAINT "$1" FOREIGN KEY (hostid) REFERENCES hosts(id); + + +-- +-- TOC entry 41 (OID 537160) +-- Name: $1; Type: FK CONSTRAINT; Schema: public; Owner: rich +-- + +ALTER TABLE ONLY images + ADD CONSTRAINT "$1" FOREIGN KEY (hostid) REFERENCES hosts(id); + + +-- +-- TOC entry 42 (OID 537175) +-- Name: $1; Type: FK CONSTRAINT; Schema: public; Owner: rich +-- + +ALTER TABLE ONLY files + ADD CONSTRAINT "$1" FOREIGN KEY (hostid) REFERENCES hosts(id); + + +-- +-- TOC entry 36 (OID 539155) +-- Name: pages_redirect_cn; Type: FK CONSTRAINT; Schema: public; Owner: rich +-- + +ALTER TABLE ONLY pages + ADD CONSTRAINT pages_redirect_cn FOREIGN KEY (hostid, redirect) REFERENCES pages(hostid, url) DEFERRABLE; + + +SET SESSION AUTHORIZATION 'postgres'; + +-- +-- TOC entry 3 (OID 2200) +-- Name: SCHEMA public; Type: COMMENT; Schema: -; Owner: postgres +-- + +COMMENT ON SCHEMA public IS 'Standard public namespace'; + + diff --git a/conf/cocanwiki.conf b/conf/cocanwiki.conf new file mode 100644 index 0000000..88053b7 --- /dev/null +++ b/conf/cocanwiki.conf @@ -0,0 +1,75 @@ +# Apache configuration for COCANWIKI. +# $Id: cocanwiki.conf,v 1.1 2004/09/07 10:14:07 rich Exp $ + +# Uncomment the following lines if necessary. You will probably need +# to adjust the paths to reflect where cocanwiki is really installed. + +# DocumentRoot /usr/share/cocanwiki/html +# CamlLoad /usr/share/cocanwiki/html/_bin/cocanwiki.cma + + + SetHandler ocaml-bytecode + CamlHandler Registry.handler + Options ExecCGI + Allow from all + + + + # The admin subdirectory contains sensitive scripts, and should + # be protected by ACLs and/or passwords. This is just an example: + Deny from all + Allow from 10.0.0.249 + + + + ExpiresActive On + ExpiresDefault "now plus 1 hour" + + + + ExpiresActive On + ExpiresDefault "now plus 1 hour" + + + + ExpiresActive On + ExpiresDefault "now plus 1 hour" + + + + ExpiresActive On + ExpiresDefault "now plus 1 hour" + + +RewriteEngine on + +# The robots.txt file needs special treatment. +RewriteRule ^/robots.txt /robots.txt [PT,L] + +# Global scripts. +RewriteRule ^/_admin$ /_bin/admin/admin.cmo [PT,L,QSA] +RewriteRule ^/_files$ /_bin/files.cmo [PT,L,QSA] +RewriteRule ^/_global.css$ /_bin/hoststyle.cmo [PT,L,QSA] +RewriteRule ^/_images$ /_bin/images.cmo [PT,L,QSA] +RewriteRule ^/_recent$ /_bin/recent.cmo [PT,L,QSA] +RewriteRule ^/_sitemap$ /_bin/sitemap.cmo [PT,L,QSA] + +# Image and file downloads. +RewriteRule ^/_file/(.*)$ /_bin/file.cmo?name=$1 [PT,L,QSA] +RewriteRule ^/_image/(.*)$ /_bin/image.cmo?image=$1 [PT,L,QSA] + +# Old _dist subdirectory no longer exists. +RewriteRule ^/_dist/ / [R] + +# Page-related scripts. +RewriteRule ^/([^_].*)/diff$ /_bin/diff.cmo?page=$1 [PT,L,QSA] +RewriteRule ^/([^_].*)/edit$ /_bin/edit.cmo?page=$1 [PT,L,QSA] +RewriteRule ^/([^_].*)/editcss$ /_bin/edit_page_css_form.cmo?page=$1 [PT,L,QSA] +RewriteRule ^/([^_].*)/history$ /_bin/history.cmo?page=$1 [PT,L,QSA] +RewriteRule ^/([^_].*)/styles.css$ /_bin/pagestyle.cmo?page=$1 [PT,L,QSA] + +# Serve pages. +RewriteRule ^/$ /_bin/page.cmo?page=index [PT,L,QSA] +#non-greedy matches don't parse - why? +#RewriteRule ^/([^_].*?)/?$ /_bin/page.cmo?page=$1 [PT,L,QSA] +RewriteRule ^/([^_].*[^/])/?$ /_bin/page.cmo?page=$1 [PT,L,QSA] diff --git a/debian/.cvsignore b/debian/.cvsignore new file mode 100644 index 0000000..8bb990a --- /dev/null +++ b/debian/.cvsignore @@ -0,0 +1,4 @@ +tmp +files +cocanwiki +*.substvars diff --git a/debian/changelog b/debian/changelog new file mode 100644 index 0000000..4d236ca --- /dev/null +++ b/debian/changelog @@ -0,0 +1,6 @@ +cocanwiki (0.9.7-1) unstable; urgency=low + + * Initial Release. + + -- Richard W.M. Jones Sat, 1 Nov 2003 12:41:34 +0000 + diff --git a/debian/compat b/debian/compat new file mode 100644 index 0000000..b8626c4 --- /dev/null +++ b/debian/compat @@ -0,0 +1 @@ +4 diff --git a/debian/control b/debian/control new file mode 100644 index 0000000..0429cfb --- /dev/null +++ b/debian/control @@ -0,0 +1,17 @@ +Source: cocanwiki +Priority: optional +Maintainer: Richard W.M. Jones +Build-Depends: debhelper (>= 4.0.0), libpcre-ocaml-dev, libpgsql-ocaml-dev, + libextlib-ocaml-dev, ocaml-findlib, ocaml-nox +Standards-Version: 3.6.0 + +Package: cocanwiki +Section: web +Architecture: any +Depends: libpgsql-ocaml, libdbi-ocaml (>= 0.9.9), libpcre-ocaml, + ocaml-nox (>= 3.08), imagemagick +Suggests: apache +Description: A Wiki written in Objective CAML (OCaml) + This is a Wiki written entirely in Objective CAML (OCaml). + . + More information is available at http://sandbox.merjis.com/ diff --git a/debian/copyright b/debian/copyright new file mode 100644 index 0000000..87a1a25 --- /dev/null +++ b/debian/copyright @@ -0,0 +1,21 @@ +This package was debianized by Richard W.M. Jones on +Sat, 1 Nov 2003 12:41:34 +0000. + +Upstream Author: Richard W.M. Jones + +Copyright: Copyright (C) 2004 Merjis Ltd. + + 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 2 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; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. diff --git a/debian/docs b/debian/docs new file mode 100644 index 0000000..2e3abae --- /dev/null +++ b/debian/docs @@ -0,0 +1,2 @@ +COPYING +README diff --git a/debian/rules b/debian/rules new file mode 100755 index 0000000..f7da905 --- /dev/null +++ b/debian/rules @@ -0,0 +1,78 @@ +#!/usr/bin/make -f +# -*- makefile -*- +# Sample debian/rules that uses debhelper. +# GNU copyright 1997 to 1999 by Joey Hess. + +# Uncomment this to turn on verbose mode. +#export DH_VERBOSE=1 + +configure: configure-stamp +configure-stamp: + dh_testdir + touch configure-stamp + +build: build-stamp +build-stamp: configure-stamp + dh_testdir + + $(MAKE) + touch build-stamp + +clean: + dh_testdir + dh_testroot + rm -f build-stamp configure-stamp + + -$(MAKE) clean + dh_clean + +install: build + dh_testdir + dh_testroot + dh_clean -k + dh_installdirs + + if [ -x /usr/bin/ocamlopt ]; then \ + BUILD_OPT=1; \ + else \ + BUILD_OPT=0; \ + fi; \ + $(MAKE) pkg-install DESTDIR=$(CURDIR)/debian/cocanwiki + +# Build architecture-independent files here. +binary-indep: build install +# We have nothing to do by default. + +# Build architecture-dependent files here. +binary-arch: build install + dh_testdir + dh_testroot + dh_installchangelogs + dh_installdocs + dh_installexamples +# dh_install +# dh_installmenu +# dh_installdebconf +# dh_installlogrotate +# dh_installemacsen +# dh_installpam +# dh_installmime +# dh_installinit +# dh_installcron +# dh_installinfo + dh_installman + dh_link +# dh_strip # Nothing to strip, hopefully. + dh_compress + dh_fixperms +# dh_perl +# dh_python +# dh_makeshlibs + dh_installdeb + dh_shlibdeps + dh_gencontrol + dh_md5sums + dh_builddeb + +binary: binary-indep binary-arch +.PHONY: build clean binary-indep binary-arch binary install configure diff --git a/html/_bin/.cvsignore b/html/_bin/.cvsignore new file mode 100644 index 0000000..72e8ffc --- /dev/null +++ b/html/_bin/.cvsignore @@ -0,0 +1 @@ +* diff --git a/html/_css/admin.css b/html/_css/admin.css new file mode 100644 index 0000000..dfd1a6b --- /dev/null +++ b/html/_css/admin.css @@ -0,0 +1,33 @@ +/* Stylesheet for COCANWIKI, derived from EWM. + * $Id: admin.css,v 1.1 2004/09/07 10:14:08 rich Exp $ + */ + +table#hosts { + width: 100%; +} + +table#host { + border-collapse: collapse; +} + +table#host th { + padding: 6px; +/* border: 1px solid #000; */ + text-align: right; + vertical-align: top; +} + +table#host td { + padding: 6px; +/* border: 1px solid #000; */ + vertical-align: top; +} + +a.alias { + font-size: 70%; +} + +span.explanation { + font-size: 70%; + font-style: italic; +} \ No newline at end of file diff --git a/html/_css/create.css b/html/_css/create.css new file mode 100644 index 0000000..6e9d1ec --- /dev/null +++ b/html/_css/create.css @@ -0,0 +1,22 @@ +/* Stylesheet for COCANWIKI, derived from EWM. + * $Id: create.css,v 1.1 2004/09/07 10:14:08 rich Exp $ + */ + +table#create { + empty-cells: show; + margin-left: auto; + margin-right: auto; +} + +table#create th { + vertical-align: top; + text-align: right; +} + +table#create td { + vertical-align: top; +} + +table#create td.explanation { + font-size: 70%; +} \ No newline at end of file diff --git a/html/_css/editor.css b/html/_css/editor.css new file mode 100644 index 0000000..af67ca0 --- /dev/null +++ b/html/_css/editor.css @@ -0,0 +1,95 @@ +/* Stylesheet for COCANWIKI editor, derived from EWM. + * $Id: editor.css,v 1.1 2004/09/07 10:14:08 rich Exp $ + */ + +body { + margin-top: 4em; +} + +p.insert { + text-align: center; +} + +p.insert input { + font-size: 70%; +} + +div.action { + float: right; +} + +div.action button.action { + text-align: left; + width: 6em; +} + +div.action input.action { + width: 6em; +} + +input.heading { + color: #003; + background-color: #ffc; + padding: 6px 3px 3px 3px; + font-size: 120%; + font-weight: bold; +} + +div.preview { + border: 1px dashed #ddd; + background-color: #f8f8f8; + padding: 3px; +} + +abbr.css_id { + font-size: 70%; +} + +input.css_id { + font-size: 70%; +} + +div#errors { + border: solid 2px #f00; + color: #c00; + padding: 4px; + width: 80%; + margin-left: 10%; +} + +div#errors p { + margin-top: 0px; + margin-bottom: 0px; +} + +div#errors ul { + list-style: none; + margin-left: 0px; + padding-left: 0px; +} + +a.help_link { + font-size: 0.7em; +} + +table#edit_conflict { +} + +table#edit_conflict pre { + background-color: inherit; + border: none; +} + +table#edit_conflict th.other { + background-color: #fcc; +} +table#edit_conflict td.other { + background-color: #fcc; +} + +table#edit_conflict th.our { + background-color: #cfc; +} +table#edit_conflict td.our { + background-color: #cfc; +} diff --git a/html/_css/files.css b/html/_css/files.css new file mode 100644 index 0000000..16c8482 --- /dev/null +++ b/html/_css/files.css @@ -0,0 +1,8 @@ +/* Stylesheet for COCANWIKI, derived from EWM. + * $Id: files.css,v 1.1 2004/09/07 10:14:08 rich Exp $ + */ + +table#files td.actions { + text-align: right; + vertical-align: bottom; +} diff --git a/html/_css/images.css b/html/_css/images.css new file mode 100644 index 0000000..34f1ade --- /dev/null +++ b/html/_css/images.css @@ -0,0 +1,12 @@ +/* Stylesheet for COCANWIKI, derived from EWM. + * $Id: images.css,v 1.1 2004/09/07 10:14:08 rich Exp $ + */ + +table#images td.thumbnail { + text-align: center; +} + +table#images td.actions { + text-align: right; + vertical-align: bottom; +} diff --git a/html/_css/markup.css b/html/_css/markup.css new file mode 100644 index 0000000..18eea4d --- /dev/null +++ b/html/_css/markup.css @@ -0,0 +1,32 @@ +/* Stylesheet for COCANWIKI, derived from EWM. + * $Id: markup.css,v 1.1 2004/09/07 10:14:08 rich Exp $ + */ + +table#markup { + border-collapse: collapse; + empty-cells: show; + margin-left: auto; + margin-right: auto; +} + +table#markup th { + padding-top: 6px; + padding-bottom: 6px; + border: 1px solid #000; + vertical-align: top; + text-align: center; +} + +table#markup td { + border: 1px solid #000; + vertical-align: top; +} + +table#markup td.notes { + font-style: italic; +} + +pre { + border: none; + background: #fff; +} \ No newline at end of file diff --git a/html/_css/standard.css b/html/_css/standard.css new file mode 100644 index 0000000..b729af7 --- /dev/null +++ b/html/_css/standard.css @@ -0,0 +1,189 @@ +/* Stylesheet for COCANWIKI, derived from EWM. + * $Id: standard.css,v 1.1 2004/09/07 10:14:08 rich Exp $ + */ + +body { + background: #fff; + color: #000; + font-family: arial, helvetica, sans-serif; + margin-top: 6em; +} + +/* Headers. */ +h1 { + background-color: #fff; + border-bottom: 1px solid #000; + position: absolute; + top: 0px; + left: 0px; + font-size: 140%; + width: 100%; + padding-left: 2em; +} + +h2 { + color: #003; + background-color: #ffc; + padding: 6px 3px 3px 3px; + border-top: 1px solid #eeb; + font-size: 120%; +} + +/* Ordinary text. */ +p { + margin-left: 1em; +} + +/* Links. */ +a.external { + background: url(/_graphics/external.png) center right no-repeat; + padding-right: 13px; +} + +a.newpage { + background: url(/_graphics/newpage.png) center right no-repeat; + padding-right: 13px; + color: #ba0000; +} + +a.mailto { + background: url(/_graphics/mailto.png) center right no-repeat; + padding-right: 13px; +} + +a.image_not_found { + background: url(/_graphics/newpage.png) center right no-repeat; + padding-right: 13px; + color: #ba0000; +} + +a.file_not_found { + background: url(/_graphics/newpage.png) center right no-repeat; + padding-right: 13px; + color: #ba0000; +} + +/* Preformatted text. */ +pre { + margin-left: 1em; + background-color: #eee; + padding: 3px; + border: dashed 1px #ddd; +} + +/* Images. (Try setting 'class' on an image). */ +img.border { + border: 1px solid #000; + margin: 0.3em; +} + +img.right_float { + float: right; + margin: 0.3em; +} + +img.right_float_border { + border: 1px solid #000; + float: right; + margin: 0.3em; +} + +img.left_float { + float: left; + margin: 0.3em; +} + +img.left_float_border { + border: 1px solid #000; + float: left; + margin: 0.3em; +} + +/* Edit links. */ +p.edit_link { + margin: 6px 0px 0px 0px; + padding-right: 12px; + float: right; +} + +/* Menus. */ +ul.menu { + padding: 0px; + margin-left: 1em; + list-style: none; +} + +ul.menu li { + display: inline; +} + +ul#topmenu { + position: absolute; + top: 3em; + left: 0.8em; +} + +ul#footer { + text-align: center; + font-size: 70%; +} + +/* Sitemap page. */ +ul#sitemap { + list-style: none; + margin-left: 0px; + padding-left: 0px; +} + +ul#sitemap p.content { + margin-top: 0px; + margin-bottom: 0px; + font-size: 0.7em; +} + +ul#sitemap p.info { + margin-top: 0px; + margin-bottom: 0px; + font-size: 0.7em; +} + +ul#sitemap p.info a { + color: green; + text-decoration: none; +} + +/* Recent changes list. */ +ul#recent_changes { + list-style: none; + margin-left: 0px; + padding-left: 0px; +} + +ul#recent_changes span.date { + display: block; + float: left; + width: 8.5em; +} + +/* History list. */ +ul#history { + list-style: none; + margin-left: 0px; + padding-left: 0px; +} + +ul#history span.date { + display: block; + float: left; + width: 8.5em; +} + +/* Versions. */ +div#old_version { + border: solid 2px #f00; + color: #c00; + padding: 4px; + width: 80%; + margin-left: 10%; + clear: both; +} diff --git a/html/_graphics/.cvsignore b/html/_graphics/.cvsignore new file mode 100644 index 0000000..5c165d9 --- /dev/null +++ b/html/_graphics/.cvsignore @@ -0,0 +1 @@ +.xvpics diff --git a/html/_graphics/arrow-down.png b/html/_graphics/arrow-down.png new file mode 100644 index 0000000000000000000000000000000000000000..1fce1f3a777ae9c3b1da41797acda1d08ae1d56f GIT binary patch literal 215 zcmeAS@N?(olHy`uVBq!ia0vp^AT}2V8<6ZZI=>f4u_bxCyDx`7I;J! zGca%qf-qx!O8i8iAbW|YuPgf%c3B<~u{IBz)j**XPZ!6KiaD(l4)PvQ;9)-B(Ys6d z%$2#PeBLcq2yzVduDoHTT9h(d(etuMw?b{>H#~nxI_o9nGv2-maqBf1M`p zdl9|8c#inClOIfK_Ab*l^WVK8zUn8>f?I9!Pp6sR31`q+$rzL)3AB&F)78&qol`;+ E08wK`VgLXD literal 0 HcmV?d00001 diff --git a/html/_graphics/arrow-up.png b/html/_graphics/arrow-up.png new file mode 100644 index 0000000000000000000000000000000000000000..610ef3c756c0fd56161605222ac6343200ca6f72 GIT binary patch literal 211 zcmeAS@N?(olHy`uVBq!ia0vp^AT}2V8<6ZZI=>f4u_bxCyDx`7I;J! zGca%qfiUBxyLEqng6t)pzOL+7*kyTywVtJ2dkqvy@N{tushHDy{vvOK0#D1s{~gjh zC!aauXL0$b0#lao-X)p0YBU|U%~U>_Bi5hMHtAOa{~8`mr;Br@e7|mVh{>tsblOsX zlaixmOJ|k+U9&Cz^iAuW{q+Y|*V*r7(0D)p0|P^`O?Z7%Rw&Re22WQ%mvv4FO#tmh BOl|-G literal 0 HcmV?d00001 diff --git a/html/_graphics/cross.png b/html/_graphics/cross.png new file mode 100644 index 0000000000000000000000000000000000000000..4878cf0f79f4e36ebac1a5a4cef194aeba876dd8 GIT binary patch literal 177 zcmeAS@N?(olHy`uVBq!ia0vp^AT}2V8<6ZZI=>f4u_bxCyDx`7I;J! zGca%qf-qx!O8i8iAbW|YuPgf%c3B>AN!wdRKY>Dao-U3d6?1y~Jh>PYc$hE$`G3A@ zVneA2vu(=KNha3>AMNb46%pxRwQ-EP^C#=rMwcf$GdL0@<(F^LSA0}I|E4H$4CV literal 0 HcmV?d00001 diff --git a/html/_graphics/error.png b/html/_graphics/error.png new file mode 100644 index 0000000000000000000000000000000000000000..caf01793aa413851466bac9c2a9c0f56e7cc5bde GIT binary patch literal 363 zcmV-x0hIoUP)UYU2zuTIw|h4T5Ehf1MI|yf;c5kL8OPxc%g;w2od%`PiFo1 zTfS8Gk-gx1uR>md5=>B(UGywED`n4Sr&KAZ!ny~tO6+9r?$Xj(HJ2d%Z4Cfh0Y*T~ z+)V>GU>ZPn1?ud}0LmhI9bne&?4C%h0LcG-nNbtR(I=qRTJj38fj25~0m)m-7+4v@ ziLYnh0i@=Em^l}GYptaNNZ;L*B}3eO=RQ7=R{o0Y(tUR>F?}7!X$2?FWKMtuu9ba_Im7002ov JPDHLkV1lHhnGOH| literal 0 HcmV?d00001 diff --git a/html/_graphics/external.png b/html/_graphics/external.png new file mode 100644 index 0000000000000000000000000000000000000000..8ae475d8a2ae689d352340ee5a1a51f044dd02c4 GIT binary patch literal 267 zcmeAS@N?(olHy`uVBq!ia0vp^AT}2VGmzZ%#=aj&v7|ftIx;YR|DNig)WpGT%PfAtr%uP&B4N6T+sVqF1Y6Dax8sHP+nl|%{@ys(b&-`adJHwFn z9|BxnaZCj&U@r;s3xT^vIyZY3o!Gl>~6a44`TbWdy)<%nQl>R{A4 z#gW9sBEW1cu)&~l1_R@f13W4-B4$cNMlvvQoM71)5g`Fo$8jPhDIqB_EjfjmLtz4w xnpjxcg0uz(Cc{RCBP<*W8#o;pQkYmI7$V;=&Xz1L{0+2}!PC{xWt~$(699>fQZWDk literal 0 HcmV?d00001 diff --git a/html/_graphics/file.png b/html/_graphics/file.png new file mode 100644 index 0000000000000000000000000000000000000000..3201e407350d78697ef75c6301d57ec3dd3be8f6 GIT binary patch literal 305 zcmeAS@N?(olHy`uVBq!ia0vp^B0wz0!VDyh@)w!{DTx4|5ZC|z|DXB)f9A}Y#>U1# zF*w-HF-s80VJZpo3;xgWbi08UkjI$h?e4-Zme}zc$l)yTh%5%u9$@TtGTRQwaPo9< z45_%4Y{16s?C9vo#>}RWkmhC}$s_2K#v-i2lelTdj2Q=J=;`SNs4-8T#MN`M;Yi8? z>&p?GObvY^C5=pu45^%aAsu1bEzopr0LWxlfB*mh literal 0 HcmV?d00001 diff --git a/html/_graphics/mailto.png b/html/_graphics/mailto.png new file mode 100644 index 0000000000000000000000000000000000000000..26ea9460a39b9e0c982b4a9c752e261d1389fb4d GIT binary patch literal 235 zcmeAS@N?(olHy`uVBq!ia0vp^AT}2V8<6ZZI=>f4u_bxCyDx`7I;J! zGca%qf-qx!O8i8iAbW|YuPgf%b{PRR=GCbi9e_d=o-U3d6?3NcALM0L6%oz_RZCGVG#@eU36ubuzuM=9q-_Yr+ovWU1DzT zIx*{liD}pk@3$A9y)AJ+yZPtrob}QFa~TXBtcAY2r^*Z6p4gGNs*lme|1R_P__hP` atLLj5nFp0AeZK~D1B0ilpUXO@geCy&lu|(e literal 0 HcmV?d00001 diff --git a/html/_graphics/markup-preview.png b/html/_graphics/markup-preview.png new file mode 100644 index 0000000000000000000000000000000000000000..ad300133840c4592407d862cddaff34cbea849ac GIT binary patch literal 23363 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 literal 0 HcmV?d00001 diff --git a/html/_graphics/ok.png b/html/_graphics/ok.png new file mode 100644 index 0000000000000000000000000000000000000000..b7e10c47fa993c4ffdbaa8a0e1efb11dfacecf4f GIT binary patch literal 1636 zcmWkvYgAKL7CtvO4+u9Ho+gSKUP2}61?3^4+z4n`BW*xN!)WC~c(iJT@|Z;cA(vzuRq+TXXo zQz!a(AB(w$2>@Uv3lq~wy`6w&E`0mW^y{62!OPS*T$HLljFDSl%Qf?9s85IKtQSGGr;DKd{Y*VH~HqOE=Yvn zD@)T9kb!_9NR6)siX)WEpT@#Bvev7$?n-n1Qip+&-@nR%z44F12GAn->%f^dx3X_K48Rtx9p_d zaz?~B>6q))F>f420JNWtM~w_>9w^v|rf_%g@qaO?x1c z4tEoy(x+NW)k3Kv}0}X#b zkbk!KF3gAEk8ESnnz?s_oY5l=P2ps4f~3!1@gp|$6mu{SuBA}ff%iu>JCM7ICggBN z;zjAuE-Ue+y>5Gdcc;K|&WJ3u9?i8mYRq$w*CG?ATDd2QO4j_Yu2{MYZ|{k`BU^G* z>^FI0b#Jfo+0>>1HLoWrM?kYKR%}spcf@at8=j|TFQzERS~)l6o_;;jU*18a*tEGX zr+M_`%u>avwm4)><#LdBVL=Rc{TG#L%dCgyyJ-zFaXpim<15C{74n}op{46I#rVYC z=JQ@JD2qvP%L`|TORj#fUe?l0rG-ZIX91o}Y?0DAalcJdcnn97KeQ|{nIyO=8ycU> zG`wbokoxR$2a!LBF@IonXWE$70AYwdo8E;S5J^t2>00&27VgxxOaa z#}u^z_KJQ1@f_>Kd*c}`cRC19Jz=A8piYJJ7tVaZ?fMni%e1vRf?tE{E%aKXOsz?>%{@pi@k-% z?Yk7CO>!jvo89HeSq>Y&d{RSNjb22#m7ds02+~dy<`EydB6xxG*K4DB;)WX%3LE3c z3|G;WrcBLLh}UxZT21R|rZ->49Txh?UsmZ=No2#rYibE9c}9z>N%hc2 cNSmXB "" in + let title = q#param "title" in + + (* Check the title is reasonable. *) + let title = trim title in + if title = "" then ( + Cocanwiki_ok.error ~back_button:true ~title:"Bad title" + q "You must give a title for this Wiki."; + ) else ( + (* In theory we could verify characters in hostnames. However + * it's probably best to assume the sysadmin knows what they're up to + * here. If this script is allowed to be accessed by untrusted + * users, then this has security implications. + *) + let check_hostname h = + let h = trim h in (* Trim whitespace. *) + let h = String.lowercase h in (* Lowercase. *) + h + in + + let canonical_hostname = check_hostname canonical_hostname in + let hostnames = Pcre.split ~rex:split_re hostnames in + let hostnames = List.map check_hostname hostnames in + let hostnames = List.filter ((<>) "") hostnames in + + (* Update the database. *) + let sth = dbh#prepare_cached + "set constraints \"hosts_hostname_cn\" deferred" in + sth#execute []; + let sth = dbh#prepare_cached "insert into hosts (canonical_hostname) + values (?)" in + sth#execute [`String canonical_hostname]; + + let hostid = sth#serial "hosts_id_seq" in + + let sth = dbh#prepare_cached "insert into hostnames (hostid, name) + values (?, ?)" in + sth#execute [`Int hostid; `String canonical_hostname]; + List.iter (fun name -> + sth#execute [`Int hostid; `String name]) hostnames; + + let sth = dbh#prepare_cached "insert into pages (hostid, url, title, + description) values (?, 'index', ?, ?)" in + sth#execute [`Int hostid; `String title; `String title]; + + (* Commit to the database. *) + dbh#commit (); + + (* Print confirmation page. *) + let buttons = [ + { StdPages.label = "OK"; + StdPages.link = "/_bin/admin/host.cmo"; + StdPages.method_ = None; + StdPages.params = [ "hostid", string_of_int hostid ] } + ] in + + Cocanwiki_ok.ok ~title:"Wiki created" ~buttons + q "A new Wiki was created." + ) + +let () = + register_script run diff --git a/scripts/admin/create_host_form.ml b/scripts/admin/create_host_form.ml new file mode 100644 index 0000000..824536f --- /dev/null +++ b/scripts/admin/create_host_form.ml @@ -0,0 +1,24 @@ +(* COCANWIKI scripts. + * Written by Richard W.M. Jones . + * Copyright (C) 2004 Merjis Ltd. + * $Id: create_host_form.ml,v 1.1 2004/09/07 10:14:10 rich Exp $ + * + * NB. Because there might not be any hosts existing when this Wiki + * is created, this is not a normal Cocanwiki.register_script script. + * Instead, we're using the standard mod_caml Registry. + *) + +open Apache +open Registry +open Cgi +open Printf + +let template = Cocanwiki.get_template "admin/create_host_form.html" + +let run r = + let q = new cgi r in + (* let dbh = Cocanwiki._get_dbh r in *) + q#template template + +let () = + register_script run diff --git a/scripts/admin/edit_emails.ml b/scripts/admin/edit_emails.ml new file mode 100644 index 0000000..732dee0 --- /dev/null +++ b/scripts/admin/edit_emails.ml @@ -0,0 +1,80 @@ +(* COCANWIKI scripts. + * Written by Richard W.M. Jones . + * Copyright (C) 2004 Merjis Ltd. + * $Id: edit_emails.ml,v 1.1 2004/09/07 10:14:10 rich Exp $ + *) + +open Apache +open Registry +open Cgi +open Printf + +open Merjisforwiki + +open Cocanwiki +open Cocanwiki_ok + +let split_re = Pcre.regexp "[\\r\\n,;]+" +let email_re = Pcre.regexp "(.*)<(.*)>" + +let run r (q : cgi) (dbh : Dbi.connection) hostid_hostname _ = + let hostid = int_of_string (q#param "hostid") in + + if q#param_true "cancel" then ( + let _, hostname = hostid_hostname in + q#redirect ("http://" ^ hostname ^ "/_bin/admin/host.cmo?hostid=" ^ + string_of_int hostid); + raise CgiExit + ); + + let emails = try q#param "emails" with Not_found -> "" in + + (* It's very hard to verify email addresses. Thus this script + * should not be exposed to untrusted users. + *) + let check_email str = + let name, email = + try + let subs = Pcre.exec ~rex:email_re str in + Pcre.get_substring subs 1, Pcre.get_substring subs 2 + with + Not_found -> + "", str in + + (* Trim whitespace. *) + trim name, trim email + in + + let emails = Pcre.split ~rex:split_re emails in + let emails = List.map check_email emails in + let emails = List.filter ((<>) ("","")) emails in + + (* Update the database. *) + let sth = dbh#prepare_cached + "delete from email_notify where hostid = ?" in + sth#execute [`Int hostid]; + let sth = dbh#prepare_cached "insert into email_notify (hostid, email, name) + values (?, ?, ?)" in + List.iter (fun (name, email) -> + if name = "" then + sth#execute [`Int hostid; `String email; `Null] + else + sth#execute [`Int hostid; `String email; `String name]) + emails; + + (* Commit to the database. *) + dbh#commit (); + + (* Print confirmation page. *) + let buttons = [ + { StdPages.label = "OK"; + StdPages.link = "/_bin/admin/host.cmo"; + StdPages.method_ = None; + StdPages.params = [ "hostid", string_of_int hostid ] } + ] in + + ok ~title:"Saved" ~buttons + q "Email notifications updated." + +let () = + register_script run diff --git a/scripts/admin/edit_emails_form.ml b/scripts/admin/edit_emails_form.ml new file mode 100644 index 0000000..8c32335 --- /dev/null +++ b/scripts/admin/edit_emails_form.ml @@ -0,0 +1,44 @@ +(* COCANWIKI scripts. + * Written by Richard W.M. Jones . + * Copyright (C) 2004 Merjis Ltd. + * $Id: edit_emails_form.ml,v 1.1 2004/09/07 10:14:10 rich Exp $ + *) + +open Apache +open Registry +open Cgi +open Printf + +open Cocanwiki + +let template = get_template "admin/edit_emails_form.html" + +let run r (q : cgi) (dbh : Dbi.connection) _ _ = + let hostid = int_of_string (q#param "hostid") in + + template#set "id" (string_of_int hostid); + + let sth = dbh#prepare_cached + "select canonical_hostname from hosts where id = ?" in + sth#execute [`Int hostid]; + + let canonical_hostname = sth#fetch1string () in + template#set "canonical_hostname" canonical_hostname; + + let sth = dbh#prepare_cached + "select email, name from email_notify where hostid = ?" in + sth#execute [`Int hostid]; + + let emails = sth#map (function + [`String email; `Null] -> + email + | [`String email; `String name] -> + sprintf "%s <%s>" name email + | _ -> assert false) in + + template#set "emails" (String.concat "\n" emails); + + q#template template + +let () = + register_script run diff --git a/scripts/admin/edit_host_css.ml b/scripts/admin/edit_host_css.ml new file mode 100644 index 0000000..04a2ad9 --- /dev/null +++ b/scripts/admin/edit_host_css.ml @@ -0,0 +1,48 @@ +(* COCANWIKI scripts. + * Written by Richard W.M. Jones . + * Copyright (C) 2004 Merjis Ltd. + * $Id: edit_host_css.ml,v 1.1 2004/09/07 10:14:10 rich Exp $ + *) + +open Apache +open Registry +open Cgi +open Printf + +open Merjisforwiki + +open Cocanwiki +open Cocanwiki_ok + +let run r (q : cgi) (dbh : Dbi.connection) (hostid, _) _ = + let hostid = int_of_string (q#param "hostid") in + + let css = q#param "css" in + + let css = if string_is_whitespace css then `Null else `String css in + + (* XXX We should version the global stylesheet. However this requires + * some fairly non-trivial coding. + *) + let sth = dbh#prepare_cached "update hosts set css = ? where id = ?" in + sth#execute [css; `Int hostid]; + + dbh#commit (); + + let buttons = [ + { StdPages.label = "OK"; + StdPages.link = "/_bin/admin/host.cmo"; + StdPages.method_ = None; + StdPages.params = [ "hostid", string_of_int hostid ] }; + { StdPages.label = "Edit stylesheet again"; + StdPages.link = "/_bin/admin/edit_host_css_form.cmo"; + StdPages.method_ = None; + StdPages.params = [ "hostid", string_of_int hostid ] } + ] in + + ok ~title:"Stylesheet changed" ~buttons + q ("The stylesheet was changed successfully. " ^ + "Note: You must RELOAD the page to see changes to stylesheets.") + +let () = + register_script run diff --git a/scripts/admin/edit_host_css_form.ml b/scripts/admin/edit_host_css_form.ml new file mode 100644 index 0000000..815fe9c --- /dev/null +++ b/scripts/admin/edit_host_css_form.ml @@ -0,0 +1,34 @@ +(* COCANWIKI scripts. + * Written by Richard W.M. Jones . + * Copyright (C) 2004 Merjis Ltd. + * $Id: edit_host_css_form.ml,v 1.1 2004/09/07 10:14:10 rich Exp $ + *) + +open Apache +open Registry +open Cgi +open Printf + +open Cocanwiki + +let template = get_template "admin/edit_host_css_form.html" + +let run r (q : cgi) (dbh : Dbi.connection) _ _ = + let hostid = int_of_string (q#param "hostid") in + template#set "id" (string_of_int hostid); + + let sth = dbh#prepare_cached "select css from hosts where id = ?" in + sth#execute [`Int hostid]; + + let css = + match sth#fetch1 () with + | [ `Null ] -> "" + | [ `String css ] -> css + | _ -> assert false in + + template#set "css" css; + + q#template template + +let () = + register_script run diff --git a/scripts/admin/edit_hostnames.ml b/scripts/admin/edit_hostnames.ml new file mode 100644 index 0000000..3a37aa7 --- /dev/null +++ b/scripts/admin/edit_hostnames.ml @@ -0,0 +1,79 @@ +(* COCANWIKI scripts. + * Written by Richard W.M. Jones . + * Copyright (C) 2004 Merjis Ltd. + * $Id: edit_hostnames.ml,v 1.1 2004/09/07 10:14:10 rich Exp $ + *) + +open Apache +open Registry +open Cgi +open Printf + +open Merjisforwiki + +open Cocanwiki +open Cocanwiki_ok + +let split_re = Pcre.regexp "[\\s,;]+" + +let run r (q : cgi) (dbh : Dbi.connection) hostid_hostname _ = + let hostid = int_of_string (q#param "hostid") in + + if q#param_true "cancel" then ( + let _, hostname = hostid_hostname in + q#redirect ("http://" ^ hostname ^ "/_bin/admin/host.cmo?hostid=" ^ + string_of_int hostid); + raise CgiExit + ); + + let canonical_hostname = q#param "canonical_hostname" in + let hostnames = try q#param "hostnames" with Not_found -> "" in + + (* In theory we could verify characters in hostnames, and call + * error / raise CgiExit if the format is incorrect. However + * it's probably best to assume the sysadmin knows what they're up to + * here. If this script is allowed to be accessed by untrusted users, + * then this has security implications. + *) + let check_hostname h = + let h = trim h in (* Trim whitespace. *) + let h = String.lowercase h in (* Lowercase. *) + h + in + + let canonical_hostname = check_hostname canonical_hostname in + let hostnames = Pcre.split ~rex:split_re hostnames in + let hostnames = List.map check_hostname hostnames in + let hostnames = List.filter ((<>) "") hostnames in + + (* Update the database. *) + let sth = dbh#prepare_cached + "set constraints \"hosts_hostname_cn\" deferred" in + sth#execute []; + let sth = dbh#prepare_cached "update hosts set canonical_hostname = ? + where id = ?" in + sth#execute [`String canonical_hostname; `Int hostid]; + let sth = dbh#prepare_cached "delete from hostnames where hostid = ?" in + sth#execute [`Int hostid]; + let sth = dbh#prepare_cached "insert into hostnames (hostid, name) + values (?, ?)" in + sth#execute [`Int hostid; `String canonical_hostname]; + List.iter (fun name -> + sth#execute [`Int hostid; `String name]) hostnames; + + (* Commit to the database. *) + dbh#commit (); + + (* Print confirmation page. *) + let buttons = [ + { StdPages.label = "OK"; + StdPages.link = "/_bin/admin/host.cmo"; + StdPages.method_ = None; + StdPages.params = [ "hostid", string_of_int hostid ] } + ] in + + ok ~title:"Saved" ~buttons + q "Hostnames updated." + +let () = + register_script run diff --git a/scripts/admin/edit_hostnames_form.ml b/scripts/admin/edit_hostnames_form.ml new file mode 100644 index 0000000..30dd87d --- /dev/null +++ b/scripts/admin/edit_hostnames_form.ml @@ -0,0 +1,40 @@ +(* COCANWIKI scripts. + * Written by Richard W.M. Jones . + * Copyright (C) 2004 Merjis Ltd. + * $Id: edit_hostnames_form.ml,v 1.1 2004/09/07 10:14:10 rich Exp $ + *) + +open Apache +open Registry +open Cgi +open Printf + +open Cocanwiki + +let template = get_template "admin/edit_hostnames_form.html" + +let run r (q : cgi) (dbh : Dbi.connection) _ _ = + let hostid = int_of_string (q#param "hostid") in + + template#set "id" (string_of_int hostid); + + let sth = dbh#prepare_cached + "select canonical_hostname from hosts where id = ?" in + sth#execute [`Int hostid]; + + let canonical_hostname = sth#fetch1string () in + template#set "canonical_hostname" canonical_hostname; + + let sth = dbh#prepare_cached "select name from hostnames + where hostid = ? + and name <> ?" in + sth#execute [`Int hostid; `String canonical_hostname]; + + let hostnames = sth#map (function [`String hostname] -> hostname + | _ -> assert false) in + template#set "hostnames" (String.concat "\n" hostnames); + + q#template template + +let () = + register_script run diff --git a/scripts/admin/host.ml b/scripts/admin/host.ml new file mode 100644 index 0000000..96d6a04 --- /dev/null +++ b/scripts/admin/host.ml @@ -0,0 +1,98 @@ +(* COCANWIKI scripts. + * Written by Richard W.M. Jones . + * Copyright (C) 2004 Merjis Ltd. + * $Id: host.ml,v 1.1 2004/09/07 10:14:10 rich Exp $ + *) + +open Apache +open Registry +open Cgi +open Printf + +open Merjisforwiki + +open Cocanwiki + +let template = get_template "admin/host.html" + +let run r (q : cgi) (dbh : Dbi.connection) _ _ = + let hostid = int_of_string (q#param "hostid") in + + template#set "id" (string_of_int hostid); + + (* Pull out some overall details for this host. *) + let sth = dbh#prepare_cached + "select h.canonical_hostname, h.css is not null, + (select count(*) from pages + where hostid = h.id and url is not null), + (select count(*) from pages + where hostid = h.id), + (select max(last_modified_date) from pages + where hostid = h.id and url is not null), + (select min(last_modified_date) from pages + where hostid = h.id and url is not null) + from hosts h + where h.id = ?" in + sth#execute [`Int hostid]; + + let canonical_hostname, has_css, page_count, total_count, + last_modified_date, creation_date = + match sth#fetch1 () with + [ `String canonical_hostname; + `Bool has_css; + (`Null | `Int _) as page_count; (`Null | `Int _) as total_count; + (`Null | `Timestamp _) as last_modified_date; + (`Null | `Timestamp _) as creation_date ] -> + let page_count = match page_count with + `Null -> 0 + | `Int n -> n in + let total_count = match total_count with + `Null -> 0 + | `Int n -> n in + let last_modified_date = match last_modified_date with + `Null -> "" + | `Timestamp t -> printable_date t in + let creation_date = match creation_date with + `Null -> "" + | `Timestamp t -> printable_date t in + canonical_hostname, has_css, page_count, total_count, + last_modified_date, creation_date + | _ -> assert false in + + template#set "canonical_hostname" canonical_hostname; + template#conditional "has_css" has_css; + template#set "page_count" (string_of_int page_count); + template#set "total_count" (string_of_int total_count); + template#set "last_modified_date" last_modified_date; + template#set "creation_date" creation_date; + + (* Pull out any aliases. *) + let sth = dbh#prepare_cached "select name from hostnames + where hostid = ? + and name <> ?" in + sth#execute [`Int hostid; `String canonical_hostname]; + + let table = sth#map (function [`String hostname] -> + [ "hostname", Template.VarString hostname ] + | _ -> assert false) in + template#table "hostnames" table; + + (* Pull out any email notifications. *) + let sth = dbh#prepare_cached "select email, name from email_notify + where hostid = ?" in + sth#execute [`Int hostid]; + + let table = sth#map (function + [`String email; `Null] -> + [ "email", Template.VarString email; + "name", Template.VarString "" ] + | [ `String email; `String name] -> + [ "email", Template.VarString email; + "name", Template.VarString name ] + | _ -> assert false) in + template#table "emails" table; + + q#template template + +let () = + register_script run diff --git a/scripts/cgi_expires.ml b/scripts/cgi_expires.ml new file mode 100644 index 0000000..48d6b8e --- /dev/null +++ b/scripts/cgi_expires.ml @@ -0,0 +1,54 @@ +(* COCANWIKI scripts. + * Written by Richard W.M. Jones . + * Copyright (C) 2004 Merjis Ltd. + * $Id: cgi_expires.ml,v 1.1 2004/09/07 10:14:09 rich Exp $ + *) + +open Apache +open Registry +open Cgi + +open Printf + +open Merjisforwiki + +(* This library should eventually be integrated with mod_caml. XXX *) + +(* Expires headers. + * + * All content on wiki sites is dynamic, but we try to make it look static + * for users and search engines. We have 4 types of 'Expires' headers that + * we can send: + * + * expires_past () + * Send an expiry header in the past (theoretically removing content from + * caches). + * expires_short () + * Send a short expiry header (now + 5 minutes). This should be used for + * all news pages. + * expires_medium () + * Send a medium-term expiry header (now + 24 hours). This should be used + * for all "static" content. + * expires_long () + * Send a very long expiry header (now + 2 years). This should be used for + * content which really never will change. + *) +let expires_past, expires_short, expires_medium, expires_long = + let make offset = + let t = Unix.time () in + let tm = Unix.gmtime (t +. float offset) in + sprintf "%s, %02d %s %04d %02d:%02d:%02d GMT" + (short_weekday tm.Unix.tm_wday) + tm.Unix.tm_mday + (short_month (tm.Unix.tm_mon + 1)) + (tm.Unix.tm_year + 1900) + tm.Unix.tm_hour + tm.Unix.tm_min + tm.Unix.tm_sec + in + let mins m = m * 60 in + let days d = d * 86400 in + (fun () -> make (mins (-5))), + (fun () -> make (mins 5)), + (fun () -> make (days 1)), + (fun () -> make (days (365*2))) diff --git a/scripts/cocanwiki.ml b/scripts/cocanwiki.ml new file mode 100644 index 0000000..6852dc4 --- /dev/null +++ b/scripts/cocanwiki.ml @@ -0,0 +1,89 @@ +(* COCANWIKI scripts. + * Written by Richard W.M. Jones . + * Copyright (C) 2004 Merjis Ltd. + * $Id: cocanwiki.ml,v 1.1 2004/09/07 10:14:09 rich Exp $ + *) + +open Apache +open Registry +open Cgi +open Printf + +open Merjisforwiki + +module Pool = DbiPool (Dbi_postgres) + +(* Wrapper around [Cgi.Template.template] function which loads the + * template from a pre-defined path and sets up some default variables. + *) +let get_template = + let path = + try Sys.getenv "COCANWIKI_TEMPLATES" + with Not_found -> "/usr/share/cocanwiki/templates" in + let is_dir path = + try (Unix.stat path).Unix.st_kind = Unix.S_DIR + with Unix.Unix_error _ -> false in + if not (is_dir path) then + failwith ("environment variable $COCANWIKI_TEMPLATES " ^ + "must be set to point to my 'templates' directory " ^ + "(see README file for more details)"); + fun filename -> + Template.template (path // filename) + +(* Generate a printable datestamp for pages. *) +let printable_date (date, _) = + sprintf "%d %s %04d" date.Dbi.day (short_month date.Dbi.month) date.Dbi.year + +let printable_date_time (date, time) = + sprintf "%d %s %04d %02d:%02d" date.Dbi.day (short_month date.Dbi.month) + date.Dbi.year time.Dbi.hour time.Dbi.min + +(* This function is used to grab a database handle. It's used in a couple + * of very special places, and is not for general consumption. + *) +let _get_dbh r = Pool.get r "cocanwiki" + +(* The [CgiExit] exception should be folded back into the base + * mod_caml code at some point. It just causes the 'run' function to + * return at that point safely. (XXX) + *) +exception CgiExit + +(* Our wrapper around the standard [register_script] function. *) +let register_script run = + (* Actually register the script with the real [Registry] module. *) + register_script + (fun r -> + let q = new cgi r in + let dbh = _get_dbh r in + + (* Get the host ID, by comparing the Host: header with the hostnames + * table in the database. + *) + let hostid, hostname = + let hostname = try Request.hostname r + with Not_found -> failwith "No ``Host:'' header in request" in + let hostname = String.lowercase hostname in + + let sth = dbh#prepare_cached "select h.id, h.canonical_hostname + from hostnames hn, hosts h + where hn.name = ? + and hn.hostid = h.id" in + sth#execute [`String hostname]; + + try + (match sth#fetch1 () with + [ `Int id; `String hostname ] -> id, hostname + | _ -> assert false) + with + Not_found -> + failwith ("Hostname ``" ^ hostname ^ "'' not found in " ^ + "the hosts/hostnames tables in the database.") in + + (* Call the actual CGI script. Note the fourth (unit) argument + * is reserved for later usage (for authentication information). + *) + try + run r q dbh (hostid, hostname) () + with + CgiExit -> ()) diff --git a/scripts/cocanwiki_diff.ml b/scripts/cocanwiki_diff.ml new file mode 100644 index 0000000..0da7f42 --- /dev/null +++ b/scripts/cocanwiki_diff.ml @@ -0,0 +1,82 @@ +(* COCANWIKI scripts. + * Written by Richard W.M. Jones . + * Copyright (C) 2004 Merjis Ltd. + * $Id: cocanwiki_diff.ml,v 1.1 2004/09/07 10:14:09 rich Exp $ + *) + +open Apache +open Registry +open Cgi +open Printf + +open Merjisforwiki + +(* Convenience code for generating diffs between versions. See diff.ml + * and edit.ml which both use this code. + *) +let page_for_diff css sections = + (String.concat "" + (List.map (fun (sectionname, content) -> + "HEADING: " ^ sectionname ^ "\n\n" ^ + content ^ "\n\n") sections)) ^ + "CSS:\n\n" ^ css + +let diff_cmd old_page new_page = + let new_filename = output_tempfile new_page in + let old_filename = output_tempfile old_page in + + let cmd = sprintf "diff -u %s %s ||:" old_filename new_filename in + let diff = pget cmd in + + let diff = + match diff with + _ :: _ :: diff -> diff + | diff -> diff in + + unlink new_filename; unlink old_filename; + String.concat "\n" diff + +let get_version_for_diff (dbh : Dbi.connection) version = + if version = 0 then "" else ( + let sth = dbh#prepare_cached "select coalesce (css, '') as css + from pages where id = ?" in + sth#execute [`Int version]; + + let css = sth#fetch1string () in + + let sth = dbh#prepare_cached "select sectionname, content + from contents where pageid = ? + order by ordering" in + sth#execute [`Int version]; + + let sections = + sth#map (function + [`String sectionname; `String content] -> + sectionname, content + | _ -> assert false) in + let page = page_for_diff css sections in + + page + ) + +let get_diff (dbh : Dbi.connection) hostid page ?old_version ~version () = + let old_version = + match old_version with + | Some version -> version + | None -> + let sth = dbh#prepare_cached "select id from pages + where hostid = ? + and url_deleted = ? and id < ? + order by 1 desc limit 1" in + sth#execute [`Int hostid; `String page; `Int version]; + + try sth#fetch1int () + with Not_found -> 0 in + + (* Get the two versions. *) + let new_page = get_version_for_diff dbh version in + let old_page = get_version_for_diff dbh old_version in + + (* Compute the diff of the two versions. *) + let diff = diff_cmd old_page new_page in + diff, old_version diff --git a/scripts/cocanwiki_emailnotify.ml b/scripts/cocanwiki_emailnotify.ml new file mode 100644 index 0000000..79ca5e7 --- /dev/null +++ b/scripts/cocanwiki_emailnotify.ml @@ -0,0 +1,41 @@ +(* COCANWIKI scripts. + * Written by Richard W.M. Jones . + * Copyright (C) 2004 Merjis Ltd. + * $Id: cocanwiki_emailnotify.ml,v 1.1 2004/09/07 10:14:09 rich Exp $ + *) + +open Apache +open Registry +open Cgi +open Printf + +open Merjisforwiki + +(* This is where we coordinate email notification from various + * scripts which create or update the wiki. + *) +let email_notify ~subject ~body (dbh : Dbi.connection) hostid = + (* Is anyone listed for email notification at this host? *) + let sth = dbh#prepare_cached "select email, name from email_notify + where hostid = ?" in + sth#execute [`Int hostid]; + + let to_addr = sth#map (function + | [`String email; `String name] -> + name ^ " <" ^ email ^ ">" + | [`String email; `Null] -> + email + | _ -> assert false) in + + if to_addr <> [] then ( + (* Prepare the body of the message. The assumption is that + * this takes time and database access, so we defer the creation + * of the body until we know that someone needs to be notified. + *) + let body = body () in + + let subject = "Wiki notice: " ^ subject in + + (* Send the email. *) + Sendmail.send_mail ~subject ~to_addr ~body () + ) diff --git a/scripts/cocanwiki_ok.ml b/scripts/cocanwiki_ok.ml new file mode 100644 index 0000000..02b6f2f --- /dev/null +++ b/scripts/cocanwiki_ok.ml @@ -0,0 +1,34 @@ +(* COCANWIKI scripts. + * Written by Richard W.M. Jones . + * Copyright (C) 2004 Merjis Ltd. + * $Id: cocanwiki_ok.ml,v 1.1 2004/09/07 10:14:09 rich Exp $ + *) + +open Apache +open Registry +open Cgi +open Printf + +open Merjisforwiki + +open Cocanwiki + +(* Override StdPages.ok and StdPages.error with out our versions. + * Also have some standard buttons around. + *) +let ok_error_template = get_template "ok_error.html" + +let error ?cookie ?cookies ?title ?(icon = "/_graphics/error.png") + ?icon_alt ?back_button ?close_button q message = + StdPages.error ?cookie ?cookies ~template:ok_error_template + ?title ~icon ?icon_alt ?back_button ?close_button q message + +let ok ?cookie ?cookies ?title ?(icon = "/_graphics/ok.png") + ?icon_alt ?back_button ?close_button ?buttons q message = + StdPages.ok ?cookie ?cookies ~template:ok_error_template + ?title ~icon ?icon_alt ?back_button ?close_button ?buttons q message + +let ok_button url = { StdPages.label = " OK "; + StdPages.link = url; + StdPages.method_ = None; + StdPages.params = [] } diff --git a/scripts/cocanwiki_version.ml.in b/scripts/cocanwiki_version.ml.in new file mode 100644 index 0000000..c0197ea --- /dev/null +++ b/scripts/cocanwiki_version.ml.in @@ -0,0 +1,4 @@ +#define xstr(s) str(s) +#define str(s) #s +let package = xstr(PACKAGE) +let version = xstr(VERSION) diff --git a/scripts/create.ml b/scripts/create.ml new file mode 100644 index 0000000..420d1ef --- /dev/null +++ b/scripts/create.ml @@ -0,0 +1,78 @@ +(* COCANWIKI scripts. + * Written by Richard W.M. Jones . + * Copyright (C) 2004 Merjis Ltd. + * $Id: create.ml,v 1.1 2004/09/07 10:14:09 rich Exp $ + *) + +open Apache +open Registry +open Cgi +open Printf + +open ExtString + +open Cocanwiki +open Cocanwiki_emailnotify +open Cocanwiki_ok + +let run r (q : cgi) (dbh : Dbi.connection) (hostid, hostname) _ = + (* Get the page title. *) + let title = q#param "title" in + + let url = + match Wikilib.generate_url_of_title dbh hostid title with + Wikilib.GenURL_OK url -> url + | Wikilib.GenURL_TooShort | Wikilib.GenURL_BadURL -> + error ~back_button:true ~title:"Bad page name" + q "The page name supplied is too short or invalid."; + raise CgiExit + | Wikilib.GenURL_Duplicate url -> + q#redirect ("http://" ^ hostname ^ "/" ^ url); + raise CgiExit in + + (* Description field must contain something. *) + let description = q#param "description" in + if description = "" then ( + error ~back_button:true ~title:"Description field missing" + q "You must write a brief description for search engines and + directories."; + raise CgiExit + ); + + (* Get the IP address of the user, if available. *) + let logged_ip = + try `String (Connection.remote_ip (Request.connection r)) + with Not_found -> `Null in + + (* Create the page. *) + let sth = dbh#prepare_cached "insert into pages (hostid, url, title, + description, logged_ip) + values (?, ?, ?, ?, ?)" in + sth#execute [`Int hostid; `String url; `String title; `String description; + logged_ip]; + + let pageid = sth#serial "pages_id_seq" in + + (* Create a single section. *) + let sectionname = "Section title - change this" in + let content = "Write some content here." in + + let sth = dbh#prepare_cached "insert into contents (pageid, ordering, + sectionname, content) values (?, 1, ?, ?)" in + sth#execute [`Int pageid; `String sectionname; `String content]; + + (* Commit. *) + dbh#commit (); + + (* Email notification, if anyone is listed for this host. *) + let subject = "Page " ^ url ^ " has been created" in + let body = fun () -> + "Page: http://" ^ hostname ^ "/" ^ url ^ "\n" in + + email_notify ~subject ~body dbh hostid; + + (* Redirect to the editing page. *) + q#redirect ("http://" ^ hostname ^ "/" ^ url ^ "/edit") + +let () = + register_script run diff --git a/scripts/create_form.ml b/scripts/create_form.ml new file mode 100644 index 0000000..6336021 --- /dev/null +++ b/scripts/create_form.ml @@ -0,0 +1,40 @@ +(* COCANWIKI scripts. + * Written by Richard W.M. Jones . + * Copyright (C) 2004 Merjis Ltd. + * $Id: create_form.ml,v 1.1 2004/09/07 10:14:09 rich Exp $ + *) + +open Apache +open Registry +open Cgi +open Printf + +open ExtString + +open Cocanwiki +open Cocanwiki_ok + +let template = get_template "create_form.html" + +let run r (q : cgi) (dbh : Dbi.connection) (hostid, hostname) _ = + (* Get the page title. *) + let title = q#param "title" in + + let url = + match Wikilib.generate_url_of_title dbh hostid title with + Wikilib.GenURL_OK url -> url + | Wikilib.GenURL_TooShort | Wikilib.GenURL_BadURL -> + error ~back_button:true ~title:"Bad page name" + q "The page name supplied is too short or invalid."; + raise CgiExit + | Wikilib.GenURL_Duplicate url -> + q#redirect ("http://" ^ hostname ^ "/" ^ url); + raise CgiExit in + + (* Show the form. *) + template#set "title" title; + + q#template template + +let () = + register_script run diff --git a/scripts/delete_file.ml b/scripts/delete_file.ml new file mode 100644 index 0000000..e2b5e2f --- /dev/null +++ b/scripts/delete_file.ml @@ -0,0 +1,46 @@ +(* COCANWIKI scripts. + * Written by Richard W.M. Jones . + * Copyright (C) 2004 Merjis Ltd. + * $Id: delete_file.ml,v 1.1 2004/09/07 10:14:09 rich Exp $ + *) + +open Apache +open Registry +open Cgi +open Printf + +open Cocanwiki +open Cocanwiki_ok +open Cocanwiki_emailnotify + +open Merjisforwiki + +let run r (q : cgi) (dbh : Dbi.connection) (hostid, hostname) _ = + let id = int_of_string (q#param "id") in + + if q#param_true "yes" then ( + (* Delete the file. *) + let sth = dbh#prepare_cached "update files + set name_deleted = name, name = null + where hostid = ? and id = ? + and name is not null" in + sth#execute [`Int hostid; `Int id]; + + dbh#commit (); + + (* Email notify. *) + let subject = "File #" ^ string_of_int id ^ " has been deleted." in + let body = fun () -> + "Page: http://" ^ hostname ^ "/_files?deleted=1" in + + email_notify ~body ~subject dbh hostid; + + (* Done. *) + let buttons = [ ok_button "/_files" ] in + ok ~title:"File deleted" ~buttons + q "File was deleted successfully." + ) else + q#redirect ("http://" ^ hostname ^ "/_files") + +let () = + register_script run diff --git a/scripts/delete_file_form.ml b/scripts/delete_file_form.ml new file mode 100644 index 0000000..1b71ec2 --- /dev/null +++ b/scripts/delete_file_form.ml @@ -0,0 +1,33 @@ +(* COCANWIKI scripts. + * Written by Richard W.M. Jones . + * Copyright (C) 2004 Merjis Ltd. + * $Id: delete_file_form.ml,v 1.1 2004/09/07 10:14:09 rich Exp $ + *) + +open Apache +open Registry +open Cgi +open Printf + +open Cocanwiki + +open Merjisforwiki + +let template = get_template "delete_file_form.html" + +let run r (q : cgi) (dbh : Dbi.connection) (hostid, _) _ = + let id = int_of_string (q#param "id") in + + let sth = dbh#prepare_cached "select name from files + where hostid = ? and id = ?" in + sth#execute [`Int hostid; `Int id]; + + let name = sth#fetch1string () in + + template#set "id" (string_of_int id); + template#set "name" name; + + q#template template + +let () = + register_script run diff --git a/scripts/delete_image.ml b/scripts/delete_image.ml new file mode 100644 index 0000000..63b03d1 --- /dev/null +++ b/scripts/delete_image.ml @@ -0,0 +1,45 @@ +(* COCANWIKI scripts. + * Written by Richard W.M. Jones . + * Copyright (C) 2004 Merjis Ltd. + * $Id: delete_image.ml,v 1.1 2004/09/07 10:14:09 rich Exp $ + *) + +open Apache +open Registry +open Cgi +open Printf + +open Cocanwiki +open Cocanwiki_ok +open Cocanwiki_emailnotify + +open Merjisforwiki + +let run r (q : cgi) (dbh : Dbi.connection) (hostid, hostname) _ = + let id = int_of_string (q#param "id") in + + if q#param_true "yes" then ( + (* Delete the image. *) + let sth = dbh#prepare_cached "update images + set name_deleted = name, name = null + where hostid = ? and id = ? + and name is not null" in + sth#execute [`Int hostid; `Int id]; + + dbh#commit (); + + (* Email notify. *) + let subject = "Image #" ^ string_of_int id ^ " has been deleted." in + let body = fun () -> + "Page: http://" ^ hostname ^ "/_images?deleted=1" in + + email_notify ~body ~subject dbh hostid; + (* Done. *) + let buttons = [ ok_button "/_images" ] in + ok ~title:"Image deleted" ~buttons + q "Image was deleted successfully." + ) else + q#redirect ("http://" ^ hostname ^ "/_images") + +let () = + register_script run diff --git a/scripts/delete_image_form.ml b/scripts/delete_image_form.ml new file mode 100644 index 0000000..6d17059 --- /dev/null +++ b/scripts/delete_image_form.ml @@ -0,0 +1,41 @@ +(* COCANWIKI scripts. + * Written by Richard W.M. Jones . + * Copyright (C) 2004 Merjis Ltd. + * $Id: delete_image_form.ml,v 1.1 2004/09/07 10:14:09 rich Exp $ + *) + +open Apache +open Registry +open Cgi +open Printf + +open Cocanwiki + +open Merjisforwiki + +let template = get_template "delete_image_form.html" + +let run r (q : cgi) (dbh : Dbi.connection) (hostid, _) _ = + let id = int_of_string (q#param "id") in + + let sth = dbh#prepare_cached "select name, width, height, alt + from images + where hostid = ? and id = ?" in + sth#execute [`Int hostid; `Int id]; + + let name, width, height, alt = + match sth#fetch1 () with + [ `String name; `Int width; `Int height; `String alt] -> + name, width, height, alt + | _ -> assert false in + + template#set "id" (string_of_int id); + template#set "name" name; + template#set "width" (string_of_int width); + template#set "height" (string_of_int height); + template#set "alt" alt; + + q#template template + +let () = + register_script run diff --git a/scripts/diff.ml b/scripts/diff.ml new file mode 100644 index 0000000..1d0ad76 --- /dev/null +++ b/scripts/diff.ml @@ -0,0 +1,51 @@ +(* COCANWIKI scripts. + * Written by Richard W.M. Jones . + * Copyright (C) 2004 Merjis Ltd. + * $Id: diff.ml,v 1.1 2004/09/07 10:14:09 rich Exp $ + *) + +open Apache +open Registry +open Cgi +open Printf + +open Cocanwiki +open Cocanwiki_diff + +open Merjisforwiki + +let template = get_template "diff.html" + +let run r (q : cgi) (dbh : Dbi.connection) (hostid, _) _ = + let page = q#param "page" in + let page = if page = "" then "index" else page in + + (* "version" parameter, required, is the newest version. If the + * "old_version" parameter is given then we compare against that. + * Otherwise we look in the database to find the version of this + * page previous to "version", and use that as "old_version". If + * there is no older version in the database, then we compare against + * version '0' which means a blank page. + * + * NB. In case you hadn't worked it out yet, version numbers are + * page.ids. + *) + let version = int_of_string (q#param "version") in + + let diff, old_version = + try + let old_version = int_of_string (q#param "old_version") in + get_diff dbh hostid page ~old_version ~version () + with + Not_found -> + get_diff dbh hostid page ~version () in + + template#set "version" (string_of_int version); + template#set "old_version" (string_of_int old_version); + template#set "page" page; + template#set "diff" diff; + + q#template template + +let () = + register_script run diff --git a/scripts/edit.ml b/scripts/edit.ml new file mode 100644 index 0000000..d86815c --- /dev/null +++ b/scripts/edit.ml @@ -0,0 +1,482 @@ +(* COCANWIKI scripts. + * Written by Richard W.M. Jones . + * Copyright (C) 2004 Merjis Ltd. + * $Id: edit.ml,v 1.1 2004/09/07 10:14:09 rich Exp $ + *) + +open Apache +open Registry +open Cgi +open Printf + +open ExtString + +open Merjisforwiki + +open Cocanwiki +open Cocanwiki_ok +open Cocanwiki_emailnotify +open Cocanwiki_diff + +let template = get_template "edit.html" +let template_conflict = get_template "edit_conflict.html" + +(* We keep an "internal model" of the page - see build_internal_model () + * below. + *) +type model_t = { + id : int; (* Original page ID. *) + description : string; (* Description. *) + redirect : string; (* Redirect to ("" = none). *) + contents : (string * string * string) list; + (* (sectionname, divname, content) + * for each section. *) +} + +let run r (q : cgi) (dbh : Dbi.connection) (hostid, hostname) _ = + (* Workaround bugs in IE, specifically lack of support for
+

+

+

+
+(Editing help) +::end:: + + + +
+ +CSS id: + +

+ +

+::end:: + + + +
+ + + + + \ No newline at end of file diff --git a/templates/edit_conflict.html b/templates/edit_conflict.html new file mode 100644 index 0000000..234c347 --- /dev/null +++ b/templates/edit_conflict.html @@ -0,0 +1,51 @@ + + + +Edit conflict + + + + + + + +

Edit conflict

+ +

+Someone else edited that page while you were editing it. This leads +to an edit conflict which you have to fix by hand. +

+ + + + + + + + + + + + +
Other person's edits Your edits
+
+::other_diff_html::
+
+
+
+::our_diff_html::
+
+
+ +
+ + + + + \ No newline at end of file diff --git a/templates/edit_page_css_form.html b/templates/edit_page_css_form.html new file mode 100644 index 0000000..820592e --- /dev/null +++ b/templates/edit_page_css_form.html @@ -0,0 +1,45 @@ + + + +Edit stylesheet for this page + + + + +

Edit stylesheet for this page

+ +
+ +

+Editing the stylesheet for ::page_html::: +

+ +

+ +

+ +

+ +

+
+ + + + + +
+ + + + + \ No newline at end of file diff --git a/templates/files.html b/templates/files.html new file mode 100644 index 0000000..14c0ec3 --- /dev/null +++ b/templates/files.html @@ -0,0 +1,73 @@ + + + +Files + + + + + +

Files

+ + + + +::table(files):: + + + + + + + +::end:: +
File icon +

+Name: ::name_html:: (size: ::ksize_html:: K)
+::if(is_deleted):: +(This file has been deleted or replaced) +::else:: +[[file:::name_html::]] +::end:: +

+
+ +
+ + + + + +
+ + + + + \ No newline at end of file diff --git a/templates/history.html b/templates/history.html new file mode 100644 index 0000000..dde437c --- /dev/null +++ b/templates/history.html @@ -0,0 +1,42 @@ + + + +Versions of this page + + + + + +

Versions of this page

+ +
    +::table(history):: +
  • +::last_modified_date_html:: +(diff) +::if(is_live)::::title_html:: (live)::else::::title_html::::end:: +::if(has_logged_ip)::(from ::logged_ip_html::)::end:: +
  • +::end:: +
+ + + + + +
+ + + + + \ No newline at end of file diff --git a/templates/images.html b/templates/images.html new file mode 100644 index 0000000..48e0fec --- /dev/null +++ b/templates/images.html @@ -0,0 +1,75 @@ + + + +Images + + + + + +

Images

+ + + + +::table(images):: + + + + + + + +::end:: +
::if(has_thumbnail):: ::alt_html_tag:: ::else:: No thumbnail. Show full-size version. ::end:: +

+Name: ::name_html:: (size: ::ksize_html:: K)
+::width_html::x::height_html::
+ALT text: ::alt_html::
+::if(is_deleted):: +(This image has been deleted or replaced) +::else:: +[[image:::name_html::]] +::end:: +

+
+ +
+ + + + + +
+ + + + + \ No newline at end of file diff --git a/templates/ok_error.html b/templates/ok_error.html new file mode 100644 index 0000000..8fa7653 --- /dev/null +++ b/templates/ok_error.html @@ -0,0 +1,45 @@ + + + +::if(has_title)::::title_html::::end:: + + + + + +::if(has_title):: +

::title_html::

+::end:: + +
+
+ +::if(has_icon):: +::icon_alt_html_tag:: +::end:: +

::message_html::

+
+ +::if(has_back_button):: + +::end:: +::if(has_close_button):: + +::end:: +::table(buttons):: + +::end:: + + + + + + diff --git a/templates/page.html b/templates/page.html new file mode 100644 index 0000000..0a94033 --- /dev/null +++ b/templates/page.html @@ -0,0 +1,65 @@ + + + +::title_html:: +::if(is_old_version)::::end:: + + + +::if(has_host_css)::::end:: +::if(has_page_css)::::end:: + + +

::title_html::

+ +::if(redirected):: +

(Redirected from ::original_page_html::)

+::end:: + +::if(is_old_version):: +
+

You are seeing an old version of this page.

+ +
+::end:: + +::table(sections):: +::if(has_divname)::
::end::

::sectionname_html::

+::content:: +::if(has_divname)::
::end::::end:: + + + + + +
+ + + + + \ No newline at end of file diff --git a/templates/page_404.html b/templates/page_404.html new file mode 100644 index 0000000..57b3348 --- /dev/null +++ b/templates/page_404.html @@ -0,0 +1,37 @@ + + + +Page not found + + + +::if(has_host_css)::::end:: + + +

Page not found

+ +

+Search our site for this page: +

+ + +

+ + +

+ + + + +
+ + + + + \ No newline at end of file diff --git a/templates/recent.html b/templates/recent.html new file mode 100644 index 0000000..83c30f1 --- /dev/null +++ b/templates/recent.html @@ -0,0 +1,43 @@ + + + +Recent changes + + + + + +

Recent changes

+ +
    +::table(recent_changes):: +
  • +::last_modified_date_html:: +(diff) +(history) +::if(is_live)::::title_html:: (live)::else::::title_html::::end:: +::if(has_logged_ip)::(from ::logged_ip_html::)::end:: +
  • +::end:: +
+ + + + + +
+ + + + + \ No newline at end of file diff --git a/templates/restore_form.html b/templates/restore_form.html new file mode 100644 index 0000000..7312c2b --- /dev/null +++ b/templates/restore_form.html @@ -0,0 +1,46 @@ + + + +Restore page + + + + +

Restore page

+ + + + +

+Are you sure you want to restore this old version? Please +check the differences below to see the changes which you will +be deleting. + + +

+ + +
+::diff_html::
+
+ + + + + +
+ + + + + \ No newline at end of file diff --git a/templates/sitemap.html b/templates/sitemap.html new file mode 100644 index 0000000..523a4bf --- /dev/null +++ b/templates/sitemap.html @@ -0,0 +1,36 @@ + + + +Sitemap + + + + +

Sitemap

+ + + + + + + +
+ + + + + \ No newline at end of file diff --git a/templates/undelete_file_form.html b/templates/undelete_file_form.html new file mode 100644 index 0000000..981f895 --- /dev/null +++ b/templates/undelete_file_form.html @@ -0,0 +1,44 @@ + + + +Restore file + + + + +

Restore file

+ + + +

+Are you sure you want to restore this file? + + +

+ + +

+File icon +Name: ::name_html:: +

+ + + + + +
+ + + + + \ No newline at end of file diff --git a/templates/undelete_image_form.html b/templates/undelete_image_form.html new file mode 100644 index 0000000..b2e475a --- /dev/null +++ b/templates/undelete_image_form.html @@ -0,0 +1,42 @@ + + + +Restore image + + + + +

Restore image

+ + + +

+Are you sure you want to restore this image? + + +

+ + +::alt_html_tag:: + + + + + +
+ + + + + \ No newline at end of file diff --git a/templates/upload_file_form.html b/templates/upload_file_form.html new file mode 100644 index 0000000..b4dc980 --- /dev/null +++ b/templates/upload_file_form.html @@ -0,0 +1,74 @@ + + + +Upload file + + + + + +

Upload file

+ + +
+::table(params):: + +::end:: +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+You need to provide a short name for this file. Use only lowercase letters, numbers, dots ('.'), dashed ('-') and underscores ('_'). +
File Name:
+Upload the file itself. +
File:
+The title appears when users hover over a file link with their mouse. It is not required. +
Title:
+ + + + + + +
+ + + + + \ No newline at end of file diff --git a/templates/upload_image_form.html b/templates/upload_image_form.html new file mode 100644 index 0000000..0d131f5 --- /dev/null +++ b/templates/upload_image_form.html @@ -0,0 +1,107 @@ + + + +Upload image + + + + + +

Upload image

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+You need to provide a short name for this image. Use only lowercase letters, numbers and underscores ('_'). JPEG images should end in .jpg and GIF images should end in .gif. +
Image Name:
+Upload the image itself. +
Image:
+The 'Alt'(-ernate) text is what blind users and search engines read. It should explain what the image is. You must provide this text to meet accessibility laws and allow search engines to discover the content of images. +
Alt text:
+The title appears when users hover over an image with their mouse. It is not required. +
Title:
+The 'Longdesc'(-ription) gives a longer, complete description of the content of the image, for blind users. If your Alt text adequately describes the image, then it is not required. +
Longdesc:
+Class is used with stylesheets. If in doubt, leave it blank. +
Class:
+
+ + + + + +
+ + + + + \ No newline at end of file -- 1.8.3.1