From afbb262c2339ec8d581786b37ba3123db7d6a87a Mon Sep 17 00:00:00 2001
From: "(no author)" <(no author)@2cc4e26e-97ec-11dd-87e9-a30ea5446288>
Date: Sat, 11 Oct 2008 23:27:31 +0000
Subject: [PATCH 01/60] Initial directory structure.
git-svn-id: https://django-phpbb.googlecode.com/svn/trunk@1 2cc4e26e-97ec-11dd-87e9-a30ea5446288
From 6285a116ab4b90d6455bc940c372f7324d8b3279 Mon Sep 17 00:00:00 2001
From: "maciej.blizinski"
Date: Mon, 13 Oct 2008 07:33:01 +0000
Subject: [PATCH 02/60] Checking in basic set of files, generated from
autoproject.
git-svn-id: https://django-phpbb.googlecode.com/svn/trunk@2 2cc4e26e-97ec-11dd-87e9-a30ea5446288
---
AUTHORS | 1 +
COPYING | 674 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
ChangeLog | 4 +
NEWS | 0
README | 23 ++
5 files changed, 702 insertions(+)
create mode 100644 AUTHORS
create mode 100644 COPYING
create mode 100644 ChangeLog
create mode 100644 NEWS
create mode 100644 README
diff --git a/AUTHORS b/AUTHORS
new file mode 100644
index 0000000..c897ef4
--- /dev/null
+++ b/AUTHORS
@@ -0,0 +1 @@
+Maciej Bliziński
diff --git a/COPYING b/COPYING
new file mode 100644
index 0000000..94a9ed0
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,674 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc.
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+
+ Copyright (C)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+ Copyright (C)
+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+.
+
+ The GNU General Public License does not permit incorporating your program
+into proprietary programs. If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License. But first, please read
+.
diff --git a/ChangeLog b/ChangeLog
new file mode 100644
index 0000000..442f3d7
--- /dev/null
+++ b/ChangeLog
@@ -0,0 +1,4 @@
+2008-10-12 Maciej Bliziński
+
+ * django-phpbb: initial version.
+
diff --git a/NEWS b/NEWS
new file mode 100644
index 0000000..e69de29
diff --git a/README b/README
new file mode 100644
index 0000000..f3899b5
--- /dev/null
+++ b/README
@@ -0,0 +1,23 @@
+ djangophpbb - Django PhpBB integration
+
+
+
+ Copyright (C) 2008 Maciej Bliziński
+
+ djangophpbb 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; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+Comments are welcome.
+
+ - Maciej Bliziński
From 7eba15618638934a9b8044a769bf92ddfb5c8bd2 Mon Sep 17 00:00:00 2001
From: "maciej.blizinski"
Date: Mon, 13 Oct 2008 07:40:09 +0000
Subject: [PATCH 03/60] Basic set of classes.
- Code copied from the previous repository, without history, but there wasn't
much of it anyway.
- Added PhpbbPassword class which handles password checking. Generating new
passwords is not implemented.
git-svn-id: https://django-phpbb.googlecode.com/svn/trunk@3 2cc4e26e-97ec-11dd-87e9-a30ea5446288
---
phpbb/__init__.py | 0
phpbb/backends.py | 58 +++++++++++
phpbb/feeds.py | 32 ++++++
phpbb/models.py | 178 +++++++++++++++++++++++++++++++++
phpbb/password.py | 113 +++++++++++++++++++++
phpbb/password_unittest.py | 62 ++++++++++++
phpbb/sitemap.py | 39 ++++++++
phpbb/templatetags/__init__.py | 0
phpbb/templatetags/phpbb.py | 58 +++++++++++
phpbb/urls.py | 43 ++++++++
phpbb/views.py | 138 +++++++++++++++++++++++++
11 files changed, 721 insertions(+)
create mode 100644 phpbb/__init__.py
create mode 100644 phpbb/backends.py
create mode 100644 phpbb/feeds.py
create mode 100644 phpbb/models.py
create mode 100644 phpbb/password.py
create mode 100644 phpbb/password_unittest.py
create mode 100644 phpbb/sitemap.py
create mode 100644 phpbb/templatetags/__init__.py
create mode 100644 phpbb/templatetags/phpbb.py
create mode 100644 phpbb/urls.py
create mode 100644 phpbb/views.py
diff --git a/phpbb/__init__.py b/phpbb/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/phpbb/backends.py b/phpbb/backends.py
new file mode 100644
index 0000000..4742aed
--- /dev/null
+++ b/phpbb/backends.py
@@ -0,0 +1,58 @@
+# -*- coding: UTF-8 -*-
+# This file is part of Atopowe, a Django site with phpBB integration
+# Copyright (C) 2007 Maciej Bliziński
+#
+# Atopowe 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.
+#
+# Atopowe 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 Atopowe; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor,
+# Boston, MA 02110-1301 USA
+
+from django.contrib.auth.models import User
+from atopowe.phpbb.models import ForumUser
+import md5
+
+class PhpbbBackend:
+ def authenticate(self, username = None, password = None):
+ """Check if the user exists in Django users. If not, create it.
+ Then authenticate."""
+ user = None
+ wrongly_encoded_username = username.decode('utf-8').encode('latin2').decode('latin1')
+ try:
+ phpbb_user = ForumUser.objects.get(username = wrongly_encoded_username)
+ except ForumUser.DoesNotExist:
+ # The user does not exist in phpBB. Bailing out.
+ return None
+ m = md5.new()
+ m.update(password)
+ pass_md5 = m.hexdigest()
+ # print "%s, %s" % (pass_md5, phpbb_user.user_password)
+ if pass_md5 == phpbb_user.user_password:
+ valid = True
+ else:
+ # Invalid password
+ return None
+ try:
+ user = User.objects.get(username = username)
+ except User.DoesNotExist:
+ if username is not None:
+ user = User(username = username, password = "")
+ user.set_password(password)
+ user.is_staff = False
+ user.is_superuser = False
+ user.email = phpbb_user.user_email
+ user.save()
+ else:
+ return None
+ return user
+ def get_user(self, id):
+ return User.objects.get(pk = id)
diff --git a/phpbb/feeds.py b/phpbb/feeds.py
new file mode 100644
index 0000000..56909c0
--- /dev/null
+++ b/phpbb/feeds.py
@@ -0,0 +1,32 @@
+# -*- coding: UTF-8 -*-
+#
+# This file is part of Atopowe, a Django site with phpBB integration
+# Copyright (C) 2007 Maciej Bliziński
+#
+# Atopowe 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.
+#
+# Atopowe 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 Atopowe; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor,
+# Boston, MA 02110-1301 USA
+
+from django.utils.translation import gettext_lazy as _
+from django.contrib.syndication.feeds import Feed
+from atopowe.phpbb.models import ForumPost
+
+class LatestForumPosts(Feed):
+ title = u"Forum Atopowe.pl"
+ link = "/forum/"
+ description = _("Newest posts on the forum.")
+ def items(self):
+ return ForumPost.objects.order_by('-post_time').exclude(topic__forum__forum_id=15).exclude(topic__forum__forum_id=6)[:20]
+ def item_link(self, obj):
+ return obj.get_external_url()
diff --git a/phpbb/models.py b/phpbb/models.py
new file mode 100644
index 0000000..cfb89ff
--- /dev/null
+++ b/phpbb/models.py
@@ -0,0 +1,178 @@
+# -*- coding: utf-8 -*-
+# This file is part of Atopowe, a Django site with phpBB integration
+# Copyright (C) 2007 Maciej Bliziński
+#
+# Atopowe 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.
+#
+# Atopowe 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 Atopowe; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor,
+# Boston, MA 02110-1301 USA
+
+from django.db import models
+from django.contrib.auth.models import User
+from atopowe.portal.utils import slugify
+from datetime import datetime
+from django.core import exceptions
+# from atopowe.phpbb.views import PAGINATE_BY
+
+def repair_latin1_encoding(s):
+ try:
+ return s.decode('utf-8').encode('latin1').decode('latin2')
+ except:
+ return s
+
+
+# Create your models here.
+class ForumUser(models.Model):
+ user_id = models.IntegerField(primary_key = True)
+ username = models.CharField(max_length = 25)
+ user_password = models.CharField(max_length = 32)
+ user_posts = models.IntegerField()
+ user_email = models.CharField(max_length = 255)
+ user_website = models.CharField(max_length = 100)
+ user_avatar_type = models.IntegerField()
+ user_avatar = models.CharField(max_length = 250)
+ def get_username(self):
+ return repair_latin1_encoding(self.username)
+ def __unicode__(self):
+ return self.get_username()
+ class Meta:
+ db_table = 'phpbb3_users'
+ ordering = ['username']
+ class Admin:
+ pass
+
+class DjangoPhpbbUserMapping(models.Model):
+ django_user = models.OneToOneField(User)
+ phpbb_user = models.ForeignKey(ForumUser,
+ unique = True)
+
+class ForumForum(models.Model):
+ forum_id = models.IntegerField(primary_key = True)
+ forum_name = models.CharField(max_length = 60)
+ forum_topics = models.IntegerField()
+ forum_posts = models.IntegerField()
+ forum_last_post = models.ForeignKey('ForumPost', db_column = 'forum_last_post_id')
+ # forum_order = models.IntegerField()
+ forum_desc = models.TextField()
+ # auth_read = models.SmallIntegerField()
+ def __unicode__(self):
+ return repair_latin1_encoding(self.forum_name)
+ # return self.get_name()
+ # return self.forum_name.encode('latin1').decode('latin2')
+ # return self.forum_name
+ # return "Type: '%s'" % type(self.forum_name)
+ def get_absolute_url(self):
+ return u"/forum/%s/%s/" % (self.forum_id, self.get_slug())
+ def get_slug(self):
+ return slugify(self.get_name())
+ def get_name(self):
+ # raise exceptions.ObjectDoesNotExist
+ return repair_latin1_encoding(self.forum_name)
+ def get_desc(self):
+ return repair_latin1_encoding(self.forum_desc)
+ class Meta:
+ db_table = 'phpbb3_forums'
+ ordering = ['forum_name']
+ class Admin:
+ pass
+
+
+class ForumTopic(models.Model):
+ topic_id = models.IntegerField(primary_key = True)
+ topic_title = models.CharField(max_length = 60)
+ topic_replies = models.IntegerField()
+ topic_poster = models.ForeignKey(ForumUser, db_column = 'topic_poster')
+ topic_time = models.IntegerField()
+ forum = models.ForeignKey(ForumForum)
+ topic_last_post = models.ForeignKey('ForumPost', related_name = 'last_in')
+ topic_first_post = models.ForeignKey('ForumPost', related_name = 'first_in')
+ def get_title(self):
+ return repair_latin1_encoding(self.topic_title)
+ def __unicode__(self):
+ return self.get_title()
+ def get_absolute_url(self):
+ return "/forum/tematy/%s/%s/" % (self.topic_id, self.get_slug())
+ def get_slug(self):
+ return slugify(self.get_title())
+ class Meta:
+ db_table = 'phpbb3_topics'
+ ordering = ['-topic_time']
+ # ordering = ['-topic_last_post_id']
+ # order_with_respect_to = 'topic_last_post'
+ # ordering = ['-post_time']
+ class Admin:
+ pass
+
+class ForumPost(models.Model):
+ PAGINATE_BY = 10
+ post_id = models.IntegerField(primary_key = True)
+ # post_title = models.CharField(max_length = 60)
+ topic = models.ForeignKey(ForumTopic)
+ poster = models.ForeignKey(ForumUser)
+ post_time = models.IntegerField()
+ post_text = models.TextField()
+ def get_time(self):
+ return datetime.fromtimestamp(self.post_time)
+ def __unicode__(self):
+ return unicode(self.post_id)
+ def get_external_url(self):
+ return "http://www.atopowe-zapalenie.pl/forum/viewtopic.php?p=%s#%s" % (self.post_id, self.post_id)
+ def get_absolute_url(self):
+ # return self.topic.get_absolute_url()
+ return "/forum/tematy/%s/%s/page%d/" % (self.topic.topic_id, self.topic.get_slug(), self.get_page())
+ def get_page(self):
+ # TODO: find out, which post in the row it is.
+ return 1
+ # def get_forumtopic_order(self):
+ # return self.post_time
+
+ class Meta:
+ db_table = 'phpbb3_posts'
+ ordering = ['post_time']
+ class Admin:
+ pass
+ def foo(self):
+ return u"foobar"
+
+
+class ForumAclOption(models.Model):
+ auth_option_id = models.IntegerField(primary_key = True)
+ is_global = models.IntegerField()
+ is_local = models.IntegerField()
+ founder_only = models.IntegerField()
+ auth_option = models.CharField(max_length = 60)
+ class Meta:
+ db_table = 'phpbb3_acl_options'
+ ordering = ['auth_option']
+ class Admin:
+ pass
+
+class ForumAclRole(models.Model):
+ role_id = models.IntegerField(primary_key = True)
+ role_name = models.CharField(max_length = 255)
+ role_order = models.IntegerField()
+ class Meta:
+ db_table = 'phpbb3_acl_roles'
+ ordering = ['role_order']
+ class Admin:
+ pass
+
+class ForumAclRoleData(models.Model):
+ role_id = models.ForeignKey('ForumAclRole', db_column = 'role_id')
+ auth_option_id = models.ForeignKey('ForumAclOption', db_column = 'auth_option_id')
+ auth_setting = models.IntegerField()
+ class Meta:
+ db_table = ['phpbb3_acl_roles_data']
+ class Admin:
+ pass
+
diff --git a/phpbb/password.py b/phpbb/password.py
new file mode 100644
index 0000000..0f04543
--- /dev/null
+++ b/phpbb/password.py
@@ -0,0 +1,113 @@
+import md5
+
+class PhpbbPassword(object):
+ """PhpBB3 password compatibility class.
+
+Ported from:
+http://code.phpbb.com/repositories/entry/5/trunk/phpBB/includes/functions.php
+ """
+
+ itoa64 = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
+ wrong = "*"
+
+ def php_hash(self, password):
+ """Hash the password."""
+ raise NotImplementedError
+
+
+ def phpbb_check_hash(self, password, hash):
+ """Check for correct password.
+
+ @param string $password The password in plain text
+ @param string $hash The stored password hash
+
+ @return bool Returns true if the password is correct, false if not.
+ """
+ if len(hash) == 34:
+ return self._hash_crypt_private(password, hash, self.itoa64) == hash
+ password_hash = md5.md5()
+ password_hash.update(password)
+ return password_hash.hexdigest() == hash
+
+
+ def _hash_gensalt_private(self, input, itoa64=itoa64,
+ iteration_count_log2=6):
+ """Generate salt for hash generation."""
+ raise NotImplementedError
+
+
+ def _hash_encode64(self, input, count, itoa64=itoa64):
+ """Encode hash."""
+ output = ""
+ i = 0
+ first = True # emulate do ... while ... construct
+ while first or (i < count):
+ first = False
+ value = self._ordx(input, i)
+ i += 1
+ output += itoa64[value & 0x3f]
+ if i < count:
+ value |= self._ordx(input, i) << 8;
+ output += itoa64[(value >> 6) & 0x3f]
+ if i >= count:
+ i += 1
+ break
+ i += 1
+ if i < count:
+ value |= self._ordx(input, i) << 16;
+ output += itoa64[(value >> 12) & 0x3f]
+ if i >= count:
+ i += 1
+ break
+ i += 1
+ output += itoa64[(value >> 18) & 0x3f]
+ return output
+
+
+ def _hash_crypt_private(self, password, setting, itoa64=itoa64):
+ """The crypt function/replacement
+
+ 'setting' means 'hash' or 'salt' here."""
+ output = self.wrong
+ if setting[0:3] != "$H$":
+ return output
+ count_log2 = itoa64.index(setting[3])
+ if count_log2 < 7 or count_log2 > 30:
+ return output
+ count = 1 << count_log2
+ salt = setting[4:12]
+ if len(salt) != 8:
+ return output
+ # Copied from PHP source code:
+ #
+ # We're kind of forced to use MD5 here since it's the only cryptographic
+ # primitive available in all versions of PHP currently in use. To
+ # implement our own low-level crypto in PHP would result in much worse
+ # performance and consequently in lower iteration counts and hashes that
+ # are quicker to crack (by non-PHP code).
+ hash = md5.md5()
+ hash.update(salt + password)
+ first = True # emulating the "do ... while ..." construct
+ while count or first:
+ first = False
+ # 16-character binary digest is used here.
+ hash_digest = hash.digest()
+ hash = md5.md5()
+ hash.update(hash_digest + password)
+ count -= 1
+ output = setting[0:12]
+ output += self._hash_encode64(hash.digest(), 16, itoa64)
+ return output
+
+
+ def _ordx(self, input, idx):
+ """Emulating PHP behavior:
+
+ - When extracting a character outside the string length, PHP
+ returns nothing and doesn't generate an error.
+ - When calculating ord() of a null object, PHP returns 0.
+ """
+ if idx >= len(input):
+ return 0
+ else:
+ return ord(input[idx])
diff --git a/phpbb/password_unittest.py b/phpbb/password_unittest.py
new file mode 100644
index 0000000..c4deba0
--- /dev/null
+++ b/phpbb/password_unittest.py
@@ -0,0 +1,62 @@
+#!/usr/bin/python
+
+import password
+import unittest
+
+class PhpbbPassword(unittest.TestCase):
+
+ def setUp(self):
+ self.p1 = password.PhpbbPassword()
+
+ def tearDown(self):
+ del self.p1
+
+ def test_hash_crypt_private01(self):
+ """Wrong length."""
+ self.assertEquals(
+ self.p1.wrong,
+ self.p1._hash_crypt_private('foo', 'bar'))
+
+ def test_hash_crypt_private02(self):
+ self.assertEquals(
+ "$H$9qS9RNyN8vivqlYBLHPGI9g5HJWHvD1",
+ self.p1._hash_crypt_private(
+ "foobar", "$H$9qS9RNyN8vivqlYBLHPGI9g5HJWHvD1"))
+
+ def test_hash_crypt_private03(self):
+ """No $H$ at the beginning."""
+ self.assertEquals(
+ self.p1.wrong,
+ self.p1._hash_crypt_private(
+ 'foo', '0123456789023456789012345678901234'))
+
+ def test_hash_encode64_1(self):
+ self.assertNotEquals("", self.p1._hash_encode64("foobar", 6));
+
+ def test_hash_encode64_2(self):
+ self.assertEquals("axqPW3aQ", self.p1._hash_encode64("foobar", 6));
+
+ def test_hash_encode64_3(self):
+ self.assertEquals("........", self.p1._hash_encode64("", 6));
+
+ def test_hash_encode64_4(self):
+ self.assertEquals("a/......", self.p1._hash_encode64("f", 6));
+
+ def test_hash_encode64_5(self):
+ self.assertEquals("..", self.p1._hash_encode64("", 0));
+
+ def test_phpbb_check_hash(self):
+ self.assertTrue(self.p1.phpbb_check_hash(
+ "foobar", "$H$9qS9RNyN8vivqlYBLHPGI9g5HJWHvD1"))
+
+ def test_ordx1(self):
+ self.assertEquals(0, self.p1._ordx("", 0));
+
+ def test_ordx2(self):
+ self.assertEquals(97, self.p1._ordx("a", 0));
+
+ def test_ordx3(self):
+ self.assertEquals(0, self.p1._ordx("a", 1));
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/phpbb/sitemap.py b/phpbb/sitemap.py
new file mode 100644
index 0000000..3b0e23c
--- /dev/null
+++ b/phpbb/sitemap.py
@@ -0,0 +1,39 @@
+# -*- coding: utf-8 -*-
+# This file is part of Atopowe, a Django site with phpBB integration
+# Copyright (C) 2007 Maciej Bliziński
+#
+# Atopowe 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.
+#
+# Atopowe 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 Atopowe; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor,
+# Boston, MA 02110-1301 USA
+
+from django.contrib import sitemaps
+from atopowe.phpbb.models import ForumTopic, ForumPost, ForumForum
+from atopowe.phpbb.urls import forumqs
+
+class ForumForumSitemap(sitemaps.Sitemap):
+ changefreq = "monthly"
+ priority = 0.4
+ def items(self):
+ return forumqs
+
+class ForumTopicSitemap(sitemaps.Sitemap):
+ changefreq = "monthly"
+ priority = 0.4
+ def items(self):
+ return ForumTopic.objects.exclude(forum__forum_id=15).exclude(forum__forum_id=6)
+ def lastmod(self, obj):
+ try:
+ return obj.topic_last_post.get_time()
+ except ForumPost.DoesNotExist:
+ return None
diff --git a/phpbb/templatetags/__init__.py b/phpbb/templatetags/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/phpbb/templatetags/phpbb.py b/phpbb/templatetags/phpbb.py
new file mode 100644
index 0000000..4a0ec39
--- /dev/null
+++ b/phpbb/templatetags/phpbb.py
@@ -0,0 +1,58 @@
+# -*- coding: UTF-8 -*-
+# This file is part of Atopowe, a Django site with phpBB integration
+# Copyright (C) 2007 Maciej Bliziński
+#
+# Atopowe 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.
+#
+# Atopowe 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 Atopowe; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor,
+# Boston, MA 02110-1301 USA
+
+from django import template
+import re
+
+register = template.Library()
+
+# @register.filter
+def bbcode(s):
+ # s = re.sub(r'\[quote:\w+\]([^\[]*)\[/quote:\w+\]', r'\1
', s)
+ s = re.sub(r'\[quote:\w+\]([^\[]*)\[/quote:\w+\]', r'\1
', s)
+ s = re.sub(r'\[quote:\w+="([\w\s]+)"\]([^\[]*)\[/quote:\w+\]', r'\1:
\2
', s)
+ # s = re.sub(r'\[size=([0-9]+):\w+\](.*)\[/size:\w+\]', r'\2', s)
+ s = re.sub(r'\[b:[^\]]*\]([^\[]*)\[/b:[^\]]*\]', r'\1', s)
+ s = re.sub(r'\[i:[^\]]*\]([^\[]*)\[/i:[^\]]*\]', r'\1', s)
+ # s = re.sub(r'(\s)http://([\w,.?=%/-]+)', r'\2(\s)', s)
+ s = re.sub(r'\[url=([^\]]*)\]([^\[]*)\[/url\]', r'\2', s)
+ s = re.sub(r'\[url\]([^\[]*)\[/url\]', r'\1', s)
+ s = re.sub(r'\[img:\w+\]([^\[]*)\[/img:\w+\]', r'', s)
+ s = re.sub(r':lol:', r'', s)
+ s = re.sub(r':wink:', r'', s)
+ s = re.sub(r':!:', r'/!\\', s)
+ s = re.sub(r'\n\n', r'\n', s)
+ s = re.sub(r'\n', r'
', s)
+ # Cudzysłowy drukarskie
+ # s = re.sub(r'"([^"]+)"', r'„\1”', s)
+ # usuwamy odstępy przed interpunkcją
+ s = re.sub(r'\s+([?!.,]\))', r'\1', s)
+ # spacja po interpunkcji
+ # s = re.sub(r'([?!.,\)])([\wąćęłńóśżź])', r'\1 \2', s)
+ # musi być spacja przed nawiasem
+ # s = re.sub(r'([\wąćęłńóśżź])(\()', r'\1 \2', s)
+ s = re.sub(r'\?+', r'?', s)
+ return s
+
+# @register.filter
+def withlink(obj):
+ return "%s" % (obj.get_absolute_url(), str(obj))
+
+register.filter('bbcode', bbcode)
+register.filter('withlink', withlink)
diff --git a/phpbb/urls.py b/phpbb/urls.py
new file mode 100644
index 0000000..552e263
--- /dev/null
+++ b/phpbb/urls.py
@@ -0,0 +1,43 @@
+# -*- coding: utf-8 -*-
+# This file is part of Atopowe, a Django site with phpBB integration
+# Copyright (C) 2007 Maciej Bliziński
+#
+# Atopowe 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.
+#
+# Atopowe 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 Atopowe; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor,
+# Boston, MA 02110-1301 USA
+
+from django.conf.urls.defaults import *
+from atopowe.phpbb.models import ForumForum
+
+# forumqs = ForumForum.objects.filter(auth_read = 0).exclude(forum_name = 'INDEX PAGE').exclude(forum_name = 'MEMBERLIST')
+forumqs = ForumForum.objects.exclude(forum_name='INDEX PAGE').exclude(forum_name='MEMBERLIST').exclude(forum_id=15).exclude(forum_id=6)
+
+urlpatterns = patterns('',
+ # Example:
+ # (r'^atopowe/', include('atopowe.apps.foo.urls.foo')),
+
+ (r'^$', 'django.views.generic.list_detail.object_list', {'queryset': forumqs, }),
+ (r'^tematy/(?P[0-9]+)/(?P[\w-]*)/page(?P[0-9]+)/$', 'atopowe.phpbb.views.topic', ),
+ (r'^tematy/(?P[0-9]+)/(?P[\w-]*)/$', 'atopowe.phpbb.views.topic', ),
+ (r'^(?P[0-9]+)/(?P[\w-]*)/$', 'atopowe.phpbb.views.forum_index', ),
+ (r'^(?P[0-9]+)/(?P[\w-]*)/page(?P[0-9]+)/$', 'atopowe.phpbb.views.forum_index', ),
+ (r'^(?P[0-9]+)/$', 'atopowe.phpbb.views.forum_index', {'slug': ''}),
+ (r'^bez-odpowiedzi/$', 'atopowe.phpbb.views.unanswered', ),
+ (r'^viewtopic.php$', 'atopowe.phpbb.views.handle_viewtopic', ),
+ # (r'^(?P[0-9]+)/[\w-]/$', 'django.views.generic.list_detail.object_list', ),
+
+ # (r'^forum/$', 'django.views.generic.simple.redirect_to', {'url': 'http://www.atopowe-zapalenie.pl/forum/'}),
+ # (r'^forum/(?P.*)$', 'django.views.generic.simple.redirect_to', {'url': 'http://www.atopowe-zapalenie.pl/forum/%(path)s'}),
+ # (r'^accounts/$', 'atopowe.portal.views.redirect_to_main', ),
+)
diff --git a/phpbb/views.py b/phpbb/views.py
new file mode 100644
index 0000000..9a704d1
--- /dev/null
+++ b/phpbb/views.py
@@ -0,0 +1,138 @@
+# -*- coding: utf-8 -*-
+# This file is part of Atopowe, a Django site with phpBB integration
+# Copyright (C) 2007 Maciej Bliziński
+#
+# Atopowe 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.
+#
+# Atopowe 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 Atopowe; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor,
+# Boston, MA 02110-1301 USA
+
+from atopowe.phpbb.models import ForumForum, ForumTopic, ForumPost
+from django.http import HttpResponseRedirect, Http404
+from django.template.context import RequestContext
+from django.shortcuts import get_object_or_404, render_to_response
+from django.core.paginator import ObjectPaginator, InvalidPage
+from django.core import exceptions
+
+# PAGINATE_BY = 10
+
+# def forum_index(request, forum_id, slug, page = None, paginate_by = PAGINATE_BY):
+def forum_index(request, forum_id, slug, page = None, paginate_by = 10):
+ if page:
+ try:
+ if int(page) == 1:
+ return HttpResponseRedirect("../")
+ except:
+ pass
+ path_prefix = "../"
+ else:
+ path_prefix = ""
+ try:
+ page = int(page)
+ except:
+ page = 1
+ if not(page >= 1 and page <= 1000):
+ raise Http404
+ f = ForumForum.objects.get(pk = forum_id)
+ # if f.auth_read != 0:
+ # raise Http404
+ if f.get_slug() != slug:
+ return HttpResponseRedirect(f.get_absolute_url())
+ topics = f.forumtopic_set.all()
+ paginator = ObjectPaginator(topics, paginate_by)
+ try:
+ object_list = paginator.get_page(page - 1)
+ except InvalidPage:
+ raise Http404
+ c = RequestContext(request, {
+ 'path_prefix': path_prefix,
+ 'is_paginated': paginator.pages > 1,
+ 'results_per_page': paginate_by,
+ 'has_next': paginator.has_next_page(page - 1),
+ 'has_previous': paginator.has_previous_page(page - 1),
+ 'page': page,
+ 'next': page + 1,
+ 'previous': page - 1,
+ 'pages': paginator.pages,
+ 'hits' : paginator.hits,
+ 'page_list': range(1, paginator.pages + 1),
+ })
+ return render_to_response("phpbb/forum_detail.html", {
+ 'object': f,
+ 'topics': object_list,
+ }, context_instance = c)
+
+def topic(request, topic_id, slug, page = None, paginate_by = 10):
+ if page:
+ try:
+ if int(page) == 1:
+ return HttpResponseRedirect("../")
+ except:
+ pass
+ path_prefix = "../"
+ else:
+ path_prefix = ""
+ try:
+ page = int(page)
+ except:
+ page = 1
+ if not(page >= 1 and page <= 1000):
+ raise Http404
+ try:
+ t = ForumTopic.objects.get(pk = topic_id)
+ except exceptions.ObjectDoesNotExist, e:
+ raise Http404
+ # if t.forum.auth_read != 0:
+ # raise Http404
+ posts = t.forumpost_set.all()
+ if t.get_slug() != slug:
+ return HttpResponseRedirect(t.get_absolute_url())
+ paginator = ObjectPaginator(posts, paginate_by)
+ try:
+ object_list = paginator.get_page(page - 1)
+ except InvalidPage:
+ raise Http404
+ c = RequestContext(request, {
+ 'path_prefix': path_prefix,
+ 'is_paginated': paginator.pages > 1,
+ 'results_per_page': paginate_by,
+ 'has_next': paginator.has_next_page(page - 1),
+ 'has_previous': paginator.has_previous_page(page - 1),
+ 'page': page,
+ 'next': page + 1,
+ 'previous': page - 1,
+ 'pages': paginator.pages,
+ 'hits' : paginator.hits,
+ 'page_list': range(1, paginator.pages + 1),
+ })
+ return render_to_response("phpbb/topic_detail.html", {
+ 'object': t,
+ 'posts': object_list,
+ }, context_instance = c)
+
+def unanswered(request):
+ topics = ForumTopic.objects.filter(topic_replies = 0)
+ return render_to_response("phpbb/unanswered.html", {
+ 'topics': topics,
+ }, context_instance = RequestContext(request))
+
+def handle_viewtopic(request):
+ if request.GET.has_key('t'):
+ topic_id = request.GET['t']
+ t = ForumTopic.objects.get(pk = topic_id)
+ return HttpResponseRedirect(t.get_absolute_url())
+ if request.GET.has_key('p'):
+ topic_id = request.GET['p']
+ t = ForumPost.objects.get(pk = topic_id)
+ return HttpResponseRedirect(t.get_absolute_url())
+
From 7fd308bdae8cf7bd1c5a11e05cb74a9d7248c99c Mon Sep 17 00:00:00 2001
From: "maciej.blizinski"
Date: Mon, 13 Oct 2008 07:41:30 +0000
Subject: [PATCH 04/60] ChangeLog update: PhpbbPassword works now.
git-svn-id: https://django-phpbb.googlecode.com/svn/trunk@4 2cc4e26e-97ec-11dd-87e9-a30ea5446288
---
ChangeLog | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/ChangeLog b/ChangeLog
index 442f3d7..1a23027 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2008-10-12 Maciej Bliziński
+
+ * PhpbbPassword: password checking added.
+
2008-10-12 Maciej Bliziński
* django-phpbb: initial version.
From 4674f2667692cce32ba41d79c09ae035dc8a53b9 Mon Sep 17 00:00:00 2001
From: "maciej.blizinski"
Date: Tue, 14 Oct 2008 20:10:03 +0000
Subject: [PATCH 05/60] Updated project name in comments.
git-svn-id: https://django-phpbb.googlecode.com/svn/trunk@5 2cc4e26e-97ec-11dd-87e9-a30ea5446288
---
phpbb/backends.py | 2 +-
phpbb/feeds.py | 2 +-
phpbb/models.py | 2 +-
phpbb/sitemap.py | 2 +-
phpbb/templatetags/phpbb.py | 2 +-
phpbb/urls.py | 2 +-
phpbb/views.py | 2 +-
7 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/phpbb/backends.py b/phpbb/backends.py
index 4742aed..9cd1768 100644
--- a/phpbb/backends.py
+++ b/phpbb/backends.py
@@ -1,5 +1,5 @@
# -*- coding: UTF-8 -*-
-# This file is part of Atopowe, a Django site with phpBB integration
+# This file is part of django-phpbb, integration between Django and phpBB
# Copyright (C) 2007 Maciej Bliziński
#
# Atopowe is free software; you can redistribute it and/or modify
diff --git a/phpbb/feeds.py b/phpbb/feeds.py
index 56909c0..6ac0729 100644
--- a/phpbb/feeds.py
+++ b/phpbb/feeds.py
@@ -1,6 +1,6 @@
# -*- coding: UTF-8 -*-
#
-# This file is part of Atopowe, a Django site with phpBB integration
+# This file is part of django-phpbb, integration between Django and phpBB
# Copyright (C) 2007 Maciej Bliziński
#
# Atopowe is free software; you can redistribute it and/or modify
diff --git a/phpbb/models.py b/phpbb/models.py
index cfb89ff..452aae0 100644
--- a/phpbb/models.py
+++ b/phpbb/models.py
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
-# This file is part of Atopowe, a Django site with phpBB integration
+# This file is part of django-phpbb, integration between Django and phpBB
# Copyright (C) 2007 Maciej Bliziński
#
# Atopowe is free software; you can redistribute it and/or modify
diff --git a/phpbb/sitemap.py b/phpbb/sitemap.py
index 3b0e23c..51a0395 100644
--- a/phpbb/sitemap.py
+++ b/phpbb/sitemap.py
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
-# This file is part of Atopowe, a Django site with phpBB integration
+# This file is part of django-phpbb, integration between Django and phpBB
# Copyright (C) 2007 Maciej Bliziński
#
# Atopowe is free software; you can redistribute it and/or modify
diff --git a/phpbb/templatetags/phpbb.py b/phpbb/templatetags/phpbb.py
index 4a0ec39..4e1c147 100644
--- a/phpbb/templatetags/phpbb.py
+++ b/phpbb/templatetags/phpbb.py
@@ -1,5 +1,5 @@
# -*- coding: UTF-8 -*-
-# This file is part of Atopowe, a Django site with phpBB integration
+# This file is part of django-phpbb, integration between Django and phpBB
# Copyright (C) 2007 Maciej Bliziński
#
# Atopowe is free software; you can redistribute it and/or modify
diff --git a/phpbb/urls.py b/phpbb/urls.py
index 552e263..c738b51 100644
--- a/phpbb/urls.py
+++ b/phpbb/urls.py
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
-# This file is part of Atopowe, a Django site with phpBB integration
+# This file is part of django-phpbb, integration between Django and phpBB
# Copyright (C) 2007 Maciej Bliziński
#
# Atopowe is free software; you can redistribute it and/or modify
diff --git a/phpbb/views.py b/phpbb/views.py
index 9a704d1..d3e4100 100644
--- a/phpbb/views.py
+++ b/phpbb/views.py
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
-# This file is part of Atopowe, a Django site with phpBB integration
+# This file is part of django-phpbb, integration between Django and phpBB
# Copyright (C) 2007 Maciej Bliziński
#
# Atopowe is free software; you can redistribute it and/or modify
From 55beb738db87c051e34723e819ff37c20b8e1857 Mon Sep 17 00:00:00 2001
From: "maciej.blizinski"
Date: Tue, 14 Oct 2008 20:23:15 +0000
Subject: [PATCH 06/60] Updated comments, code cleanup in various places.
git-svn-id: https://django-phpbb.googlecode.com/svn/trunk@6 2cc4e26e-97ec-11dd-87e9-a30ea5446288
---
ChangeLog | 5 +++++
phpbb/backends.py | 10 +++++-----
phpbb/feeds.py | 12 ++++++------
phpbb/models.py | 16 +++++++++-------
phpbb/sitemap.py | 12 ++++++------
phpbb/templatetags/phpbb.py | 8 ++++----
phpbb/urls.py | 35 +++++++++++++++++++++--------------
phpbb/views.py | 16 ++++++++--------
8 files changed, 64 insertions(+), 50 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 1a23027..545800e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2008-10-14 Maciej Bliziński
+
+ * django-phpbb: Updated comments and removed references to the
+ previous project
+
2008-10-12 Maciej Bliziński
* PhpbbPassword: password checking added.
diff --git a/phpbb/backends.py b/phpbb/backends.py
index 9cd1768..d73fc85 100644
--- a/phpbb/backends.py
+++ b/phpbb/backends.py
@@ -1,24 +1,24 @@
# -*- coding: UTF-8 -*-
# This file is part of django-phpbb, integration between Django and phpBB
-# Copyright (C) 2007 Maciej Bliziński
+# Copyright (C) 2007-2008 Maciej Bliziński
#
-# Atopowe is free software; you can redistribute it and/or modify
+# django-phpbb 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.
#
-# Atopowe is distributed in the hope that it will be useful,
+# django-phpbb 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 Atopowe; if not, write to the Free Software
+# along with django-phpbb; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor,
# Boston, MA 02110-1301 USA
from django.contrib.auth.models import User
-from atopowe.phpbb.models import ForumUser
+from phpbb.models import ForumUser
import md5
class PhpbbBackend:
diff --git a/phpbb/feeds.py b/phpbb/feeds.py
index 6ac0729..33cc002 100644
--- a/phpbb/feeds.py
+++ b/phpbb/feeds.py
@@ -1,29 +1,29 @@
# -*- coding: UTF-8 -*-
#
# This file is part of django-phpbb, integration between Django and phpBB
-# Copyright (C) 2007 Maciej Bliziński
+# Copyright (C) 2007-2008 Maciej Bliziński
#
-# Atopowe is free software; you can redistribute it and/or modify
+# django-phpbb 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.
#
-# Atopowe is distributed in the hope that it will be useful,
+# django-phpbb 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 Atopowe; if not, write to the Free Software
+# along with django-phpbb; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor,
# Boston, MA 02110-1301 USA
from django.utils.translation import gettext_lazy as _
from django.contrib.syndication.feeds import Feed
-from atopowe.phpbb.models import ForumPost
+from phpbb.models import ForumPost
class LatestForumPosts(Feed):
- title = u"Forum Atopowe.pl"
+ title = u"Forum"
link = "/forum/"
description = _("Newest posts on the forum.")
def items(self):
diff --git a/phpbb/models.py b/phpbb/models.py
index 452aae0..6213362 100644
--- a/phpbb/models.py
+++ b/phpbb/models.py
@@ -1,19 +1,19 @@
# -*- coding: utf-8 -*-
# This file is part of django-phpbb, integration between Django and phpBB
-# Copyright (C) 2007 Maciej Bliziński
+# Copyright (C) 2007-2008 Maciej Bliziński
#
-# Atopowe is free software; you can redistribute it and/or modify
+# django-phpbb 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.
#
-# Atopowe is distributed in the hope that it will be useful,
+# django-phpbb 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 Atopowe; if not, write to the Free Software
+# along with django-phpbb; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor,
# Boston, MA 02110-1301 USA
@@ -22,16 +22,17 @@
from atopowe.portal.utils import slugify
from datetime import datetime
from django.core import exceptions
-# from atopowe.phpbb.views import PAGINATE_BY
def repair_latin1_encoding(s):
+ """Needed to cope with broken character encoding in a MySQL database.
+
+ TODO: remove this function."""
try:
return s.decode('utf-8').encode('latin1').decode('latin2')
except:
return s
-# Create your models here.
class ForumUser(models.Model):
user_id = models.IntegerField(primary_key = True)
username = models.CharField(max_length = 25)
@@ -169,7 +170,8 @@ class Admin:
class ForumAclRoleData(models.Model):
role_id = models.ForeignKey('ForumAclRole', db_column = 'role_id')
- auth_option_id = models.ForeignKey('ForumAclOption', db_column = 'auth_option_id')
+ auth_option_id = models.ForeignKey(
+ 'ForumAclOption', db_column = 'auth_option_id')
auth_setting = models.IntegerField()
class Meta:
db_table = ['phpbb3_acl_roles_data']
diff --git a/phpbb/sitemap.py b/phpbb/sitemap.py
index 51a0395..7062a69 100644
--- a/phpbb/sitemap.py
+++ b/phpbb/sitemap.py
@@ -1,25 +1,25 @@
# -*- coding: utf-8 -*-
# This file is part of django-phpbb, integration between Django and phpBB
-# Copyright (C) 2007 Maciej Bliziński
+# Copyright (C) 2007-2008 Maciej Bliziński
#
-# Atopowe is free software; you can redistribute it and/or modify
+# django-phpbb 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.
#
-# Atopowe is distributed in the hope that it will be useful,
+# django-phpbb 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 Atopowe; if not, write to the Free Software
+# along with django-phpbb; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor,
# Boston, MA 02110-1301 USA
from django.contrib import sitemaps
-from atopowe.phpbb.models import ForumTopic, ForumPost, ForumForum
-from atopowe.phpbb.urls import forumqs
+from phpbb.models import ForumTopic, ForumPost, ForumForum
+from phpbb.urls import forumqs
class ForumForumSitemap(sitemaps.Sitemap):
changefreq = "monthly"
diff --git a/phpbb/templatetags/phpbb.py b/phpbb/templatetags/phpbb.py
index 4e1c147..a2b9b88 100644
--- a/phpbb/templatetags/phpbb.py
+++ b/phpbb/templatetags/phpbb.py
@@ -1,19 +1,19 @@
# -*- coding: UTF-8 -*-
# This file is part of django-phpbb, integration between Django and phpBB
-# Copyright (C) 2007 Maciej Bliziński
+# Copyright (C) 2007-2008 Maciej Bliziński
#
-# Atopowe is free software; you can redistribute it and/or modify
+# django-phpbb 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.
#
-# Atopowe is distributed in the hope that it will be useful,
+# django-phpbb 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 Atopowe; if not, write to the Free Software
+# along with django-phpbb; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor,
# Boston, MA 02110-1301 USA
diff --git a/phpbb/urls.py b/phpbb/urls.py
index c738b51..533ffc9 100644
--- a/phpbb/urls.py
+++ b/phpbb/urls.py
@@ -1,40 +1,47 @@
# -*- coding: utf-8 -*-
# This file is part of django-phpbb, integration between Django and phpBB
-# Copyright (C) 2007 Maciej Bliziński
+# Copyright (C) 2007-2008 Maciej Bliziński
#
-# Atopowe is free software; you can redistribute it and/or modify
+# django-phpbb 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.
#
-# Atopowe is distributed in the hope that it will be useful,
+# django-phpbb 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 Atopowe; if not, write to the Free Software
+# along with django-phpbb; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor,
# Boston, MA 02110-1301 USA
from django.conf.urls.defaults import *
-from atopowe.phpbb.models import ForumForum
+from phpbb.models import ForumForum
# forumqs = ForumForum.objects.filter(auth_read = 0).exclude(forum_name = 'INDEX PAGE').exclude(forum_name = 'MEMBERLIST')
-forumqs = ForumForum.objects.exclude(forum_name='INDEX PAGE').exclude(forum_name='MEMBERLIST').exclude(forum_id=15).exclude(forum_id=6)
+forumqs = (ForumForum.objects.
+ exclude(forum_name='INDEX PAGE').
+ exclude(forum_name='MEMBERLIST').
+ exclude(forum_id=15).
+ exclude(forum_id=6))
urlpatterns = patterns('',
# Example:
# (r'^atopowe/', include('atopowe.apps.foo.urls.foo')),
- (r'^$', 'django.views.generic.list_detail.object_list', {'queryset': forumqs, }),
- (r'^tematy/(?P[0-9]+)/(?P[\w-]*)/page(?P[0-9]+)/$', 'atopowe.phpbb.views.topic', ),
- (r'^tematy/(?P[0-9]+)/(?P[\w-]*)/$', 'atopowe.phpbb.views.topic', ),
- (r'^(?P[0-9]+)/(?P[\w-]*)/$', 'atopowe.phpbb.views.forum_index', ),
- (r'^(?P[0-9]+)/(?P[\w-]*)/page(?P[0-9]+)/$', 'atopowe.phpbb.views.forum_index', ),
- (r'^(?P[0-9]+)/$', 'atopowe.phpbb.views.forum_index', {'slug': ''}),
- (r'^bez-odpowiedzi/$', 'atopowe.phpbb.views.unanswered', ),
- (r'^viewtopic.php$', 'atopowe.phpbb.views.handle_viewtopic', ),
+ (r'^$', 'django.views.generic.list_detail.object_list',
+ {'queryset': forumqs, }),
+ (r'^topics/(?P[0-9]+)/(?P[\w-]*)/page(?P[0-9]+)/$',
+ 'phpbb.views.topic', ),
+ (r'^topics/(?P[0-9]+)/(?P[\w-]*)/$', 'phpbb.views.topic', ),
+ (r'^(?P[0-9]+)/(?P[\w-]*)/$', 'phpbb.views.forum_index', ),
+ (r'^(?P[0-9]+)/(?P[\w-]*)/page(?P[0-9]+)/$',
+ 'phpbb.views.forum_index', ),
+ (r'^(?P[0-9]+)/$', 'phpbb.views.forum_index', {'slug': ''}),
+ (r'^unanswered/$', 'phpbb.views.unanswered', ),
+ (r'^viewtopic.php$', 'phpbb.views.handle_viewtopic', ),
# (r'^(?P[0-9]+)/[\w-]/$', 'django.views.generic.list_detail.object_list', ),
# (r'^forum/$', 'django.views.generic.simple.redirect_to', {'url': 'http://www.atopowe-zapalenie.pl/forum/'}),
diff --git a/phpbb/views.py b/phpbb/views.py
index d3e4100..29fdc36 100644
--- a/phpbb/views.py
+++ b/phpbb/views.py
@@ -1,32 +1,30 @@
# -*- coding: utf-8 -*-
# This file is part of django-phpbb, integration between Django and phpBB
-# Copyright (C) 2007 Maciej Bliziński
+# Copyright (C) 2007-2008 Maciej Bliziński
#
-# Atopowe is free software; you can redistribute it and/or modify
+# django-phpbb 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.
#
-# Atopowe is distributed in the hope that it will be useful,
+# django-phpbb 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 Atopowe; if not, write to the Free Software
+# along with django-phpbb; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor,
# Boston, MA 02110-1301 USA
-from atopowe.phpbb.models import ForumForum, ForumTopic, ForumPost
+from phpbb.models import ForumForum, ForumTopic, ForumPost
from django.http import HttpResponseRedirect, Http404
from django.template.context import RequestContext
from django.shortcuts import get_object_or_404, render_to_response
from django.core.paginator import ObjectPaginator, InvalidPage
from django.core import exceptions
-# PAGINATE_BY = 10
-# def forum_index(request, forum_id, slug, page = None, paginate_by = PAGINATE_BY):
def forum_index(request, forum_id, slug, page = None, paginate_by = 10):
if page:
try:
@@ -72,6 +70,7 @@ def forum_index(request, forum_id, slug, page = None, paginate_by = 10):
'topics': object_list,
}, context_instance = c)
+
def topic(request, topic_id, slug, page = None, paginate_by = 10):
if page:
try:
@@ -120,12 +119,14 @@ def topic(request, topic_id, slug, page = None, paginate_by = 10):
'posts': object_list,
}, context_instance = c)
+
def unanswered(request):
topics = ForumTopic.objects.filter(topic_replies = 0)
return render_to_response("phpbb/unanswered.html", {
'topics': topics,
}, context_instance = RequestContext(request))
+
def handle_viewtopic(request):
if request.GET.has_key('t'):
topic_id = request.GET['t']
@@ -135,4 +136,3 @@ def handle_viewtopic(request):
topic_id = request.GET['p']
t = ForumPost.objects.get(pk = topic_id)
return HttpResponseRedirect(t.get_absolute_url())
-
From 9893ddf518f0c05997c091601f785c62747bd74c Mon Sep 17 00:00:00 2001
From: "maciej.blizinski"
Date: Sat, 22 Nov 2008 20:21:25 +0000
Subject: [PATCH 07/60] Fixed a bug when password is provided as unicode.
git-svn-id: https://django-phpbb.googlecode.com/svn/trunk@7 2cc4e26e-97ec-11dd-87e9-a30ea5446288
---
phpbb/password.py | 2 ++
phpbb/password_unittest.py | 7 +++++++
2 files changed, 9 insertions(+)
diff --git a/phpbb/password.py b/phpbb/password.py
index 0f04543..46c17d6 100644
--- a/phpbb/password.py
+++ b/phpbb/password.py
@@ -69,6 +69,8 @@ def _hash_crypt_private(self, password, setting, itoa64=itoa64):
'setting' means 'hash' or 'salt' here."""
output = self.wrong
+ if type(password) != str:
+ password = str(password)
if setting[0:3] != "$H$":
return output
count_log2 = itoa64.index(setting[3])
diff --git a/phpbb/password_unittest.py b/phpbb/password_unittest.py
index c4deba0..1c1b9e5 100644
--- a/phpbb/password_unittest.py
+++ b/phpbb/password_unittest.py
@@ -23,6 +23,12 @@ def test_hash_crypt_private02(self):
self.p1._hash_crypt_private(
"foobar", "$H$9qS9RNyN8vivqlYBLHPGI9g5HJWHvD1"))
+ def test_unicodePassword(self):
+ self.assertEquals(
+ "$H$9qS9RNyN8vivqlYBLHPGI9g5HJWHvD1",
+ self.p1._hash_crypt_private(
+ unicode("foobar"), "$H$9qS9RNyN8vivqlYBLHPGI9g5HJWHvD1"))
+
def test_hash_crypt_private03(self):
"""No $H$ at the beginning."""
self.assertEquals(
@@ -58,5 +64,6 @@ def test_ordx2(self):
def test_ordx3(self):
self.assertEquals(0, self.p1._ordx("a", 1));
+
if __name__ == "__main__":
unittest.main()
From cc82d74bfb00f238e69ddb45f9242abb40c58eb2 Mon Sep 17 00:00:00 2001
From: "maciej.blizinski"
Date: Mon, 24 Nov 2008 09:23:50 +0000
Subject: [PATCH 08/60] - Fixed views - Fixed backends.py, logging in is now
working - Added templates. They currently contain code specific to my current
project. I'm going to remove those bits and replace them with a context
object.
git-svn-id: https://django-phpbb.googlecode.com/svn/trunk@8 2cc4e26e-97ec-11dd-87e9-a30ea5446288
---
README | 2 +-
phpbb/backends.py | 50 +++++++++-----
phpbb/feeds.py | 2 +-
phpbb/models.py | 59 ++++++----------
phpbb/sitemap.py | 4 +-
phpbb/templates/phpbb/forum_detail.html | 57 ++++++++++++++++
phpbb/templates/phpbb/forumforum_list.html | 20 ++++++
phpbb/templates/phpbb/index.html | 18 +++++
phpbb/templates/phpbb/topic_detail.html | 62 +++++++++++++++++
phpbb/templates/phpbb/unanswered.html | 17 +++++
phpbb/urls.py | 41 ++++++-----
phpbb/views.py | 79 +++++++++++-----------
12 files changed, 300 insertions(+), 111 deletions(-)
create mode 100644 phpbb/templates/phpbb/forum_detail.html
create mode 100644 phpbb/templates/phpbb/forumforum_list.html
create mode 100644 phpbb/templates/phpbb/index.html
create mode 100644 phpbb/templates/phpbb/topic_detail.html
create mode 100644 phpbb/templates/phpbb/unanswered.html
diff --git a/README b/README
index f3899b5..3c4346f 100644
--- a/README
+++ b/README
@@ -1,4 +1,4 @@
- djangophpbb - Django PhpBB integration
+ django-phpbb - Django PhpBB integration
diff --git a/phpbb/backends.py b/phpbb/backends.py
index d73fc85..24ed527 100644
--- a/phpbb/backends.py
+++ b/phpbb/backends.py
@@ -17,42 +17,60 @@
# Foundation, Inc., 51 Franklin St, Fifth Floor,
# Boston, MA 02110-1301 USA
+import logging
from django.contrib.auth.models import User
-from phpbb.models import ForumUser
-import md5
+from models import ForumUser
+import password as php_password
+
+logging.basicConfig(level=logging.DEBUG)
class PhpbbBackend:
- def authenticate(self, username = None, password = None):
- """Check if the user exists in Django users. If not, create it.
+
+ def authenticate(self, username=None, password=None):
+ """Authenticate user against phpBB3 database.
+
+ Check if the user exists in Django users. If not, create it.
Then authenticate."""
+ logging.debug("PhpbbBackend::authenticate()")
user = None
- wrongly_encoded_username = username.decode('utf-8').encode('latin2').decode('latin1')
try:
- phpbb_user = ForumUser.objects.get(username = wrongly_encoded_username)
+ phpbb_user = ForumUser.objects.get(username = username)
except ForumUser.DoesNotExist:
# The user does not exist in phpBB. Bailing out.
+ logging.warning("User '%s' doesn't exist." % username)
return None
- m = md5.new()
- m.update(password)
- pass_md5 = m.hexdigest()
- # print "%s, %s" % (pass_md5, phpbb_user.user_password)
- if pass_md5 == phpbb_user.user_password:
- valid = True
+ phpbb_checker = php_password.PhpbbPassword()
+ if phpbb_checker.phpbb_check_hash(password, phpbb_user.user_password):
+ logging.debug("User %s successfully authenticated "
+ "with phpBB database." % username)
else:
# Invalid password
+ logging.warning("Wrong password for user %s" % username)
return None
+ # At this point we have successfully checked phpBB user password.
+ # Now we're getting and returning Django user. If necessary, we're
+ # creating the user on the fly.
try:
user = User.objects.get(username = username)
except User.DoesNotExist:
- if username is not None:
+ logging.info("Creating new Django user '%s'" % username)
+ if username:
user = User(username = username, password = "")
- user.set_password(password)
user.is_staff = False
user.is_superuser = False
user.email = phpbb_user.user_email
user.save()
else:
+ logging.warning("User name empty. Not creating.")
return None
+ # In case the phpBB password has changed, we're updating user's
+ # Django password. Django password is necessary when user wants to log
+ # in to the admin interface.
+ user.set_password(password)
+ logging.debug("Returning user '%s'" % user)
+ return user
+
+ def get_user(self, user_id):
+ user = User.objects.get(pk = user_id)
+ logging.debug("get_user(): Returning user '%s'" % user)
return user
- def get_user(self, id):
- return User.objects.get(pk = id)
diff --git a/phpbb/feeds.py b/phpbb/feeds.py
index 33cc002..cffe5d5 100644
--- a/phpbb/feeds.py
+++ b/phpbb/feeds.py
@@ -20,7 +20,7 @@
from django.utils.translation import gettext_lazy as _
from django.contrib.syndication.feeds import Feed
-from phpbb.models import ForumPost
+from models import ForumPost
class LatestForumPosts(Feed):
title = u"Forum"
diff --git a/phpbb/models.py b/phpbb/models.py
index 6213362..690acac 100644
--- a/phpbb/models.py
+++ b/phpbb/models.py
@@ -23,16 +23,6 @@
from datetime import datetime
from django.core import exceptions
-def repair_latin1_encoding(s):
- """Needed to cope with broken character encoding in a MySQL database.
-
- TODO: remove this function."""
- try:
- return s.decode('utf-8').encode('latin1').decode('latin2')
- except:
- return s
-
-
class ForumUser(models.Model):
user_id = models.IntegerField(primary_key = True)
username = models.CharField(max_length = 25)
@@ -42,45 +32,41 @@ class ForumUser(models.Model):
user_website = models.CharField(max_length = 100)
user_avatar_type = models.IntegerField()
user_avatar = models.CharField(max_length = 250)
- def get_username(self):
- return repair_latin1_encoding(self.username)
def __unicode__(self):
- return self.get_username()
+ return self.username
class Meta:
db_table = 'phpbb3_users'
ordering = ['username']
class Admin:
pass
+
class DjangoPhpbbUserMapping(models.Model):
+ """Maps phpBB users to Django users, 1:1."""
django_user = models.OneToOneField(User)
- phpbb_user = models.ForeignKey(ForumUser,
- unique = True)
+ phpbb_user = models.ForeignKey(ForumUser, unique = True)
+
class ForumForum(models.Model):
forum_id = models.IntegerField(primary_key = True)
forum_name = models.CharField(max_length = 60)
forum_topics = models.IntegerField()
forum_posts = models.IntegerField()
- forum_last_post = models.ForeignKey('ForumPost', db_column = 'forum_last_post_id')
+ forum_last_post = models.ForeignKey(
+ 'ForumPost', db_column = 'forum_last_post_id')
# forum_order = models.IntegerField()
forum_desc = models.TextField()
# auth_read = models.SmallIntegerField()
def __unicode__(self):
- return repair_latin1_encoding(self.forum_name)
- # return self.get_name()
- # return self.forum_name.encode('latin1').decode('latin2')
- # return self.forum_name
- # return "Type: '%s'" % type(self.forum_name)
+ return self.forum_name
def get_absolute_url(self):
return u"/forum/%s/%s/" % (self.forum_id, self.get_slug())
def get_slug(self):
return slugify(self.get_name())
def get_name(self):
- # raise exceptions.ObjectDoesNotExist
- return repair_latin1_encoding(self.forum_name)
+ return self.forum_name
def get_desc(self):
- return repair_latin1_encoding(self.forum_desc)
+ return self.forum_desc
class Meta:
db_table = 'phpbb3_forums'
ordering = ['forum_name']
@@ -98,11 +84,11 @@ class ForumTopic(models.Model):
topic_last_post = models.ForeignKey('ForumPost', related_name = 'last_in')
topic_first_post = models.ForeignKey('ForumPost', related_name = 'first_in')
def get_title(self):
- return repair_latin1_encoding(self.topic_title)
+ return self.topic_title
def __unicode__(self):
return self.get_title()
def get_absolute_url(self):
- return "/forum/tematy/%s/%s/" % (self.topic_id, self.get_slug())
+ return "/forum/topics/%s/%s/" % (self.topic_id, self.get_slug())
def get_slug(self):
return slugify(self.get_title())
class Meta:
@@ -114,7 +100,9 @@ class Meta:
class Admin:
pass
+
class ForumPost(models.Model):
+ """phpBB3 forum post."""
PAGINATE_BY = 10
post_id = models.IntegerField(primary_key = True)
# post_title = models.CharField(max_length = 60)
@@ -127,23 +115,19 @@ def get_time(self):
def __unicode__(self):
return unicode(self.post_id)
def get_external_url(self):
- return "http://www.atopowe-zapalenie.pl/forum/viewtopic.php?p=%s#%s" % (self.post_id, self.post_id)
+ return ("http://www.atopowe-zapalenie.pl/forum/viewtopic.php?p=%s#%s" %
+ (self.post_id, self.post_id))
def get_absolute_url(self):
- # return self.topic.get_absolute_url()
- return "/forum/tematy/%s/%s/page%d/" % (self.topic.topic_id, self.topic.get_slug(), self.get_page())
+ return ("/forum/topics/%s/%s/page%d/" %
+ (self.topic.topic_id, self.topic.get_slug(), self.get_page()))
def get_page(self):
- # TODO: find out, which post in the row it is.
+ """TODO: find out, which post in the row it is."""
return 1
- # def get_forumtopic_order(self):
- # return self.post_time
-
class Meta:
db_table = 'phpbb3_posts'
ordering = ['post_time']
class Admin:
pass
- def foo(self):
- return u"foobar"
class ForumAclOption(models.Model):
@@ -158,6 +142,7 @@ class Meta:
class Admin:
pass
+
class ForumAclRole(models.Model):
role_id = models.IntegerField(primary_key = True)
role_name = models.CharField(max_length = 255)
@@ -168,13 +153,13 @@ class Meta:
class Admin:
pass
+
class ForumAclRoleData(models.Model):
role_id = models.ForeignKey('ForumAclRole', db_column = 'role_id')
auth_option_id = models.ForeignKey(
'ForumAclOption', db_column = 'auth_option_id')
auth_setting = models.IntegerField()
class Meta:
- db_table = ['phpbb3_acl_roles_data']
+ db_table = 'phpbb3_acl_roles_data'
class Admin:
pass
-
diff --git a/phpbb/sitemap.py b/phpbb/sitemap.py
index 7062a69..2b49b4f 100644
--- a/phpbb/sitemap.py
+++ b/phpbb/sitemap.py
@@ -18,8 +18,8 @@
# Boston, MA 02110-1301 USA
from django.contrib import sitemaps
-from phpbb.models import ForumTopic, ForumPost, ForumForum
-from phpbb.urls import forumqs
+from models import ForumTopic, ForumPost, ForumForum
+from urls import forumqs
class ForumForumSitemap(sitemaps.Sitemap):
changefreq = "monthly"
diff --git a/phpbb/templates/phpbb/forum_detail.html b/phpbb/templates/phpbb/forum_detail.html
new file mode 100644
index 0000000..622120f
--- /dev/null
+++ b/phpbb/templates/phpbb/forum_detail.html
@@ -0,0 +1,57 @@
+{% extends "phpbb/index.html" %}
+{% load phpbb %}
+
+
+{% block sidebar %}
+{% endblock %}
+
+{% block bartitle %}{{ object }}{% endblock %}
+
+{% block content %}
+{% block forum_detail %}
+{{ object }}
+Forum Atopowe Zapalenie Skóry Strona Główna
+→
+{{ object }}
+{% endblock %}
+
+{% if is_paginated %}
+
+{% endif %}
+
+
+{% for topic in topics %}
+-
+{{ topic }}
+
+{{ topic.topic_poster.get_username }},
+odpowiedzi: {{ topic.topic_replies }}, ost. {{ topic.topic_last_post.poster.get_username }}, {{ topic.topic_last_post.get_time|timesince }} temu
+»
+
+
+{% endfor %}
+
+
+
+{% if is_paginated %}
+
+{% if has_next %}wcześniejsze →{% endif %}
+
+
+{% endif %}
+
+{% endblock %}
diff --git a/phpbb/templates/phpbb/forumforum_list.html b/phpbb/templates/phpbb/forumforum_list.html
new file mode 100644
index 0000000..8ac2dd1
--- /dev/null
+++ b/phpbb/templates/phpbb/forumforum_list.html
@@ -0,0 +1,20 @@
+{% extends "phpbb/index.html" %}
+{% load phpbb %}
+
+{% block content %}
+Forum Atopowe Zapalenie Skóry Strona Główna
+
+Przeglądasz w tej chwili archiwum naszego forum. Nie można tutaj pisać
+nowych postów. Jeżeli chcesz pisać, zapraszam
+tutaj.
+Tematy bez odpowiedzi
+
+
+ {% for object in object_list %}
+ -
+ {{ object }}
+
+ {{ object.get_desc }}
+ {% endfor %}
+
+{% endblock %}
diff --git a/phpbb/templates/phpbb/index.html b/phpbb/templates/phpbb/index.html
new file mode 100644
index 0000000..8ba1523
--- /dev/null
+++ b/phpbb/templates/phpbb/index.html
@@ -0,0 +1,18 @@
+{% extends "base.html" %}
+{% load phpbb %}
+{% block subtitle %}
+Archiwum forum dyskusyjnego
+{% endblock %}
+
+{% block sidebar %}
+ {% if last_forum_posts %}
+ Obecnie na forum
+
+ {% endif %}
+
+{% endblock %}
diff --git a/phpbb/templates/phpbb/topic_detail.html b/phpbb/templates/phpbb/topic_detail.html
new file mode 100644
index 0000000..af4ad58
--- /dev/null
+++ b/phpbb/templates/phpbb/topic_detail.html
@@ -0,0 +1,62 @@
+{% extends "phpbb/index.html" %}
+{% load phpbb %}
+{% block bartitle %}{{ object }}{% endblock %}
+
+{% block sidebar %}
+
+
+{% endblock %}
+
+{% block content %}
+{{ object }}
+Forum Atopowe Zapalenie Skóry Strona Główna
+→
+{{ object.forum }}
+{% if is_paginated %}
+
+{% endif %}
+
+
+{% for post in posts %}
+-
+{% ifequal post.poster.user_avatar_type 1 %}
+
+
+{% endifequal %}
+
+{{ post.poster }}:
+{{ post.post_text|bbcode }}
+
+{% endfor %}
+
+{% if is_paginated %}
+{% if has_next %}późniejsze →{% endif %}
+
+{% endif %}
+{% endblock %}
+
diff --git a/phpbb/templates/phpbb/unanswered.html b/phpbb/templates/phpbb/unanswered.html
new file mode 100644
index 0000000..61a031a
--- /dev/null
+++ b/phpbb/templates/phpbb/unanswered.html
@@ -0,0 +1,17 @@
+{% extends "phpbb/forum_detail.html" %}
+{% block content %}
+{% load phpbb %}
+
+{% for topic in topics %}
+-
+{{ topic.get_title }}
+({{ topic.topic_first_post.poster }})
+
+{{ topic.topic_first_post.forumposttext.get_post_text|bbcode }}
+
+odpowiedz
+
+{% endfor %}
+
+
+{% endblock %}
diff --git a/phpbb/urls.py b/phpbb/urls.py
index 533ffc9..efb5d60 100644
--- a/phpbb/urls.py
+++ b/phpbb/urls.py
@@ -18,12 +18,15 @@
# Boston, MA 02110-1301 USA
from django.conf.urls.defaults import *
-from phpbb.models import ForumForum
+# import django.contrib.phpbb
+import django.contrib.phpbb.views
+import models
-# forumqs = ForumForum.objects.filter(auth_read = 0).exclude(forum_name = 'INDEX PAGE').exclude(forum_name = 'MEMBERLIST')
-forumqs = (ForumForum.objects.
- exclude(forum_name='INDEX PAGE').
+# forumqs = models.ForumForum.objects.filter(auth_read = 0).
+# exclude(forum_name = 'INDEX PAGE').exclude(forum_name = 'MEMBERLIST')
+forumqs = (models.ForumForum.objects.exclude(forum_name='INDEX PAGE').
exclude(forum_name='MEMBERLIST').
+ # FIXME: hardcoded forum IDs
exclude(forum_id=15).
exclude(forum_id=6))
@@ -33,18 +36,24 @@
(r'^$', 'django.views.generic.list_detail.object_list',
{'queryset': forumqs, }),
- (r'^topics/(?P[0-9]+)/(?P[\w-]*)/page(?P[0-9]+)/$',
- 'phpbb.views.topic', ),
- (r'^topics/(?P[0-9]+)/(?P[\w-]*)/$', 'phpbb.views.topic', ),
- (r'^(?P[0-9]+)/(?P[\w-]*)/$', 'phpbb.views.forum_index', ),
- (r'^(?P[0-9]+)/(?P[\w-]*)/page(?P[0-9]+)/$',
- 'phpbb.views.forum_index', ),
- (r'^(?P[0-9]+)/$', 'phpbb.views.forum_index', {'slug': ''}),
- (r'^unanswered/$', 'phpbb.views.unanswered', ),
- (r'^viewtopic.php$', 'phpbb.views.handle_viewtopic', ),
- # (r'^(?P[0-9]+)/[\w-]/$', 'django.views.generic.list_detail.object_list', ),
+ (r'^topics/(?P[0-9]+)/(?P[\w-]*)/page(?P[0-9]+)/$',
+ 'django.contrib.phpbb.views.topic', ),
+ (r'^topics/(?P[0-9]+)/(?P[\w-]*)/$',
+ 'django.contrib.phpbb.views.topic', ),
+ (r'^(?P[0-9]+)/(?P[\w-]*)/$',
+ 'django.contrib.phpbb.views.forum_index', ),
+ (r'^(?P[0-9]+)/(?P[\w-]*)/page(?P[0-9]+)/$',
+ 'django.contrib.phpbb.views.forum_index', ),
+ (r'^(?P[0-9]+)/$',
+ 'django.contrib.phpbb.views.forum_index', {'slug': ''}),
+ (r'^unanswered/$', 'django.contrib.phpbb.views.unanswered', ),
+ (r'^viewtopic.php$', 'django.contrib.phpbb.views.handle_viewtopic', ),
+ # (r'^(?P[0-9]+)/[\w-]/$',
+ # 'django.views.generic.list_detail.object_list', ),
- # (r'^forum/$', 'django.views.generic.simple.redirect_to', {'url': 'http://www.atopowe-zapalenie.pl/forum/'}),
- # (r'^forum/(?P.*)$', 'django.views.generic.simple.redirect_to', {'url': 'http://www.atopowe-zapalenie.pl/forum/%(path)s'}),
+ # (r'^forum/$', 'django.views.generic.simple.redirect_to',
+ # {'url': 'http://www.atopowe-zapalenie.pl/forum/'}),
+ # (r'^forum/(?P.*)$', 'django.views.generic.simple.redirect_to',
+ # {'url': 'http://www.atopowe-zapalenie.pl/forum/%(path)s'}),
# (r'^accounts/$', 'atopowe.portal.views.redirect_to_main', ),
)
diff --git a/phpbb/views.py b/phpbb/views.py
index 29fdc36..fd48f95 100644
--- a/phpbb/views.py
+++ b/phpbb/views.py
@@ -17,18 +17,18 @@
# Foundation, Inc., 51 Franklin St, Fifth Floor,
# Boston, MA 02110-1301 USA
-from phpbb.models import ForumForum, ForumTopic, ForumPost
+from models import ForumForum, ForumTopic, ForumPost
from django.http import HttpResponseRedirect, Http404
from django.template.context import RequestContext
from django.shortcuts import get_object_or_404, render_to_response
-from django.core.paginator import ObjectPaginator, InvalidPage
+from django.core.paginator import Paginator, InvalidPage
from django.core import exceptions
-def forum_index(request, forum_id, slug, page = None, paginate_by = 10):
- if page:
+def forum_index(request, forum_id, slug, page_no = None, paginate_by = 10):
+ if page_no:
try:
- if int(page) == 1:
+ if int(page_no) == 1:
return HttpResponseRedirect("../")
except:
pass
@@ -36,10 +36,10 @@ def forum_index(request, forum_id, slug, page = None, paginate_by = 10):
else:
path_prefix = ""
try:
- page = int(page)
+ page_no = int(page_no)
except:
- page = 1
- if not(page >= 1 and page <= 1000):
+ page_no = 1
+ if not(page_no >= 1 and page_no <= 1000):
raise Http404
f = ForumForum.objects.get(pk = forum_id)
# if f.auth_read != 0:
@@ -47,34 +47,37 @@ def forum_index(request, forum_id, slug, page = None, paginate_by = 10):
if f.get_slug() != slug:
return HttpResponseRedirect(f.get_absolute_url())
topics = f.forumtopic_set.all()
- paginator = ObjectPaginator(topics, paginate_by)
+ paginator = Paginator(topics, paginate_by)
+ print "page_no:", page_no
try:
- object_list = paginator.get_page(page - 1)
+ print "requesting page"
+ page = paginator.page(page_no)
+ print "got page", page
except InvalidPage:
raise Http404
c = RequestContext(request, {
'path_prefix': path_prefix,
- 'is_paginated': paginator.pages > 1,
+ 'is_paginated': paginator.num_pages > 1,
'results_per_page': paginate_by,
- 'has_next': paginator.has_next_page(page - 1),
- 'has_previous': paginator.has_previous_page(page - 1),
- 'page': page,
- 'next': page + 1,
- 'previous': page - 1,
- 'pages': paginator.pages,
- 'hits' : paginator.hits,
- 'page_list': range(1, paginator.pages + 1),
+ 'has_next': page.has_next(),
+ 'has_previous': page.has_previous(),
+ 'page': page_no,
+ 'next': page_no + 1,
+ 'previous': page_no - 1,
+ 'pages': paginator.num_pages,
+ 'hits' : 'what hits?',
+ 'page_list': range(1, paginator.num_pages + 1),
})
return render_to_response("phpbb/forum_detail.html", {
'object': f,
- 'topics': object_list,
+ 'topics': page.object_list,
}, context_instance = c)
-def topic(request, topic_id, slug, page = None, paginate_by = 10):
- if page:
+def topic(request, topic_id, slug, page_no = None, paginate_by = 10):
+ if page_no:
try:
- if int(page) == 1:
+ if int(page_no) == 1:
return HttpResponseRedirect("../")
except:
pass
@@ -82,10 +85,10 @@ def topic(request, topic_id, slug, page = None, paginate_by = 10):
else:
path_prefix = ""
try:
- page = int(page)
+ page_no = int(page_no)
except:
- page = 1
- if not(page >= 1 and page <= 1000):
+ page_no = 1
+ if not(page_no >= 1 and page_no <= 1000):
raise Http404
try:
t = ForumTopic.objects.get(pk = topic_id)
@@ -96,27 +99,27 @@ def topic(request, topic_id, slug, page = None, paginate_by = 10):
posts = t.forumpost_set.all()
if t.get_slug() != slug:
return HttpResponseRedirect(t.get_absolute_url())
- paginator = ObjectPaginator(posts, paginate_by)
+ paginator = Paginator(posts, paginate_by)
try:
- object_list = paginator.get_page(page - 1)
+ page = paginator.page(page_no)
except InvalidPage:
raise Http404
c = RequestContext(request, {
'path_prefix': path_prefix,
- 'is_paginated': paginator.pages > 1,
+ 'is_paginated': paginator.num_pages > 1,
'results_per_page': paginate_by,
- 'has_next': paginator.has_next_page(page - 1),
- 'has_previous': paginator.has_previous_page(page - 1),
- 'page': page,
- 'next': page + 1,
- 'previous': page - 1,
- 'pages': paginator.pages,
- 'hits' : paginator.hits,
- 'page_list': range(1, paginator.pages + 1),
+ 'has_next': page.has_next(),
+ 'has_previous': page.has_previous(),
+ 'page': page_no,
+ 'next': page_no + 1,
+ 'previous': page_no - 1,
+ 'pages': paginator.num_pages,
+ 'hits' : "hits? what hits?",
+ 'page_list': range(1, paginator.num_pages + 1),
})
return render_to_response("phpbb/topic_detail.html", {
'object': t,
- 'posts': object_list,
+ 'posts': page.object_list,
}, context_instance = c)
From 3fa1a79c7a73bf1a135cc35971e5a8607c9cbb9b Mon Sep 17 00:00:00 2001
From: "maciej.blizinski"
Date: Mon, 24 Nov 2008 09:29:56 +0000
Subject: [PATCH 09/60] Added a TODO file.
git-svn-id: https://django-phpbb.googlecode.com/svn/trunk@9 2cc4e26e-97ec-11dd-87e9-a30ea5446288
---
TODO | 5 +++++
1 file changed, 5 insertions(+)
create mode 100644 TODO
diff --git a/TODO b/TODO
new file mode 100644
index 0000000..523e320
--- /dev/null
+++ b/TODO
@@ -0,0 +1,5 @@
+django-phpbb - Django PhpBB integration
+
+To do list:
+
+- Add support for bbcode http://code.google.com/p/postmarkup/
From 914c1dd40c1cb5f5424016c573f6c3a2d5f66318 Mon Sep 17 00:00:00 2001
From: "maciej.blizinski"
Date: Thu, 27 Nov 2008 10:40:05 +0000
Subject: [PATCH 10/60] - Added admin site code - Removed a dependency on the
former parent project
git-svn-id: https://django-phpbb.googlecode.com/svn/trunk@12 2cc4e26e-97ec-11dd-87e9-a30ea5446288
---
phpbb/models.py | 36 ++++++----------
phpbb/templates/phpbb/forum_detail.html | 25 +++++------
phpbb/templates/phpbb/forumforum_list.html | 13 ++++--
phpbb/templates/phpbb/index.html | 12 ++++--
phpbb/templates/phpbb/topic_detail.html | 1 -
phpbb/urls.py | 16 +-------
phpbb/utils.py | 48 ++++++++++++++++++++++
phpbb/views.py | 11 ++---
8 files changed, 97 insertions(+), 65 deletions(-)
create mode 100644 phpbb/utils.py
diff --git a/phpbb/models.py b/phpbb/models.py
index 690acac..bbcefc6 100644
--- a/phpbb/models.py
+++ b/phpbb/models.py
@@ -19,9 +19,10 @@
from django.db import models
from django.contrib.auth.models import User
-from atopowe.portal.utils import slugify
+from django.contrib.phpbb.utils import slugify
from datetime import datetime
from django.core import exceptions
+from django.utils.encoding import force_unicode
class ForumUser(models.Model):
user_id = models.IntegerField(primary_key = True)
@@ -32,13 +33,17 @@ class ForumUser(models.Model):
user_website = models.CharField(max_length = 100)
user_avatar_type = models.IntegerField()
user_avatar = models.CharField(max_length = 250)
+ user_regdate_int = models.IntegerField(db_column="user_regdate")
+ user_lastvisit_int = models.IntegerField(db_column="user_regdate")
def __unicode__(self):
return self.username
+ def user_regdate(self):
+ return datetime.fromtimestamp(self.user_regdate_int)
+ def user_lastvisit(self):
+ return datetime.fromtimestamp(self.user_lastvisit_int)
class Meta:
db_table = 'phpbb3_users'
ordering = ['username']
- class Admin:
- pass
class DjangoPhpbbUserMapping(models.Model):
@@ -54,24 +59,16 @@ class ForumForum(models.Model):
forum_posts = models.IntegerField()
forum_last_post = models.ForeignKey(
'ForumPost', db_column = 'forum_last_post_id')
- # forum_order = models.IntegerField()
forum_desc = models.TextField()
- # auth_read = models.SmallIntegerField()
def __unicode__(self):
- return self.forum_name
+ return force_unicode(self.forum_name)
def get_absolute_url(self):
return u"/forum/%s/%s/" % (self.forum_id, self.get_slug())
def get_slug(self):
- return slugify(self.get_name())
- def get_name(self):
- return self.forum_name
- def get_desc(self):
- return self.forum_desc
+ return slugify(self.forum_name)
class Meta:
db_table = 'phpbb3_forums'
ordering = ['forum_name']
- class Admin:
- pass
class ForumTopic(models.Model):
@@ -113,12 +110,13 @@ class ForumPost(models.Model):
def get_time(self):
return datetime.fromtimestamp(self.post_time)
def __unicode__(self):
- return unicode(self.post_id)
+ # return force_unicode(self.topic.topic_title + u" (post_id=%s)" % self.post_id)
+ return force_unicode(u" (post_id=%s)" % self.post_id)
def get_external_url(self):
return ("http://www.atopowe-zapalenie.pl/forum/viewtopic.php?p=%s#%s" %
(self.post_id, self.post_id))
def get_absolute_url(self):
- return ("/forum/topics/%s/%s/page%d/" %
+ return (u"/forum/topics/%s/%s/page%d/" %
(self.topic.topic_id, self.topic.get_slug(), self.get_page()))
def get_page(self):
"""TODO: find out, which post in the row it is."""
@@ -126,8 +124,6 @@ def get_page(self):
class Meta:
db_table = 'phpbb3_posts'
ordering = ['post_time']
- class Admin:
- pass
class ForumAclOption(models.Model):
@@ -139,8 +135,6 @@ class ForumAclOption(models.Model):
class Meta:
db_table = 'phpbb3_acl_options'
ordering = ['auth_option']
- class Admin:
- pass
class ForumAclRole(models.Model):
@@ -150,8 +144,6 @@ class ForumAclRole(models.Model):
class Meta:
db_table = 'phpbb3_acl_roles'
ordering = ['role_order']
- class Admin:
- pass
class ForumAclRoleData(models.Model):
@@ -161,5 +153,3 @@ class ForumAclRoleData(models.Model):
auth_setting = models.IntegerField()
class Meta:
db_table = 'phpbb3_acl_roles_data'
- class Admin:
- pass
diff --git a/phpbb/templates/phpbb/forum_detail.html b/phpbb/templates/phpbb/forum_detail.html
index 622120f..929c22d 100644
--- a/phpbb/templates/phpbb/forum_detail.html
+++ b/phpbb/templates/phpbb/forum_detail.html
@@ -27,7 +27,7 @@ {{ object }}
{{ topic }}
{{ topic.topic_poster.get_username }},
-odpowiedzi: {{ topic.topic_replies }}, ost. {{ topic.topic_last_post.poster.get_username }}, {{ topic.topic_last_post.get_time|timesince }} temu
+ {% trans "odpowiedzi" %}: {{ topic.topic_replies }}, {% trans "last" %} {{ topic.topic_last_post.poster.get_username }}, {{ topic.topic_last_post.get_time|timesince }} {% trans "ago" %}
»
@@ -36,19 +36,20 @@ {{ object }}
{% if is_paginated %}
-
-{% if has_next %}wcześniejsze →{% endif %}
-
+{% if has_next %}
+ wcześniejsze →
+{% endif %}
diff --git a/phpbb/templates/phpbb/forumforum_list.html b/phpbb/templates/phpbb/forumforum_list.html
index 8ac2dd1..d82e40a 100644
--- a/phpbb/templates/phpbb/forumforum_list.html
+++ b/phpbb/templates/phpbb/forumforum_list.html
@@ -2,12 +2,17 @@
{% load phpbb %}
{% block content %}
-Forum Atopowe Zapalenie Skóry Strona Główna
+
+ {% trans "Forum" %}
+ {% trans "Atopic Dermatitis" %}
+ {% trans "Main Page" %}
+
-Przeglądasz w tej chwili archiwum naszego forum. Nie można tutaj pisać
-nowych postów. Jeżeli chcesz pisać, zapraszam
+
Przeglądasz w tej chwili archiwum naszego forum.
+Nie można tutaj pisać nowych postów.
+Jeżeli chcesz pisać, zapraszamy
tutaj.
-Tematy bez odpowiedzi
+{% trans "Unanswered topics" %}
{% for object in object_list %}
diff --git a/phpbb/templates/phpbb/index.html b/phpbb/templates/phpbb/index.html
index 8ba1523..52a18ba 100644
--- a/phpbb/templates/phpbb/index.html
+++ b/phpbb/templates/phpbb/index.html
@@ -1,7 +1,10 @@
+{% comment %}
+This template assumes you have a 'base.html' file that can be extended.
+{% endcomment %}
{% extends "base.html" %}
{% load phpbb %}
{% block subtitle %}
-Archiwum forum dyskusyjnego
+{% trans "Discussion forum" %}
{% endblock %}
{% block sidebar %}
@@ -9,8 +12,11 @@
Obecnie na forum
{% endif %}
diff --git a/phpbb/templates/phpbb/topic_detail.html b/phpbb/templates/phpbb/topic_detail.html
index af4ad58..03325de 100644
--- a/phpbb/templates/phpbb/topic_detail.html
+++ b/phpbb/templates/phpbb/topic_detail.html
@@ -59,4 +59,3 @@ {{ object }}
{% endif %}
{% endblock %}
-
diff --git a/phpbb/urls.py b/phpbb/urls.py
index efb5d60..d2a27fd 100644
--- a/phpbb/urls.py
+++ b/phpbb/urls.py
@@ -18,12 +18,9 @@
# Boston, MA 02110-1301 USA
from django.conf.urls.defaults import *
-# import django.contrib.phpbb
-import django.contrib.phpbb.views
+import views
import models
-# forumqs = models.ForumForum.objects.filter(auth_read = 0).
-# exclude(forum_name = 'INDEX PAGE').exclude(forum_name = 'MEMBERLIST')
forumqs = (models.ForumForum.objects.exclude(forum_name='INDEX PAGE').
exclude(forum_name='MEMBERLIST').
# FIXME: hardcoded forum IDs
@@ -31,9 +28,6 @@
exclude(forum_id=6))
urlpatterns = patterns('',
- # Example:
- # (r'^atopowe/', include('atopowe.apps.foo.urls.foo')),
-
(r'^$', 'django.views.generic.list_detail.object_list',
{'queryset': forumqs, }),
(r'^topics/(?P[0-9]+)/(?P[\w-]*)/page(?P[0-9]+)/$',
@@ -48,12 +42,4 @@
'django.contrib.phpbb.views.forum_index', {'slug': ''}),
(r'^unanswered/$', 'django.contrib.phpbb.views.unanswered', ),
(r'^viewtopic.php$', 'django.contrib.phpbb.views.handle_viewtopic', ),
- # (r'^(?P[0-9]+)/[\w-]/$',
- # 'django.views.generic.list_detail.object_list', ),
-
- # (r'^forum/$', 'django.views.generic.simple.redirect_to',
- # {'url': 'http://www.atopowe-zapalenie.pl/forum/'}),
- # (r'^forum/(?P.*)$', 'django.views.generic.simple.redirect_to',
- # {'url': 'http://www.atopowe-zapalenie.pl/forum/%(path)s'}),
- # (r'^accounts/$', 'atopowe.portal.views.redirect_to_main', ),
)
diff --git a/phpbb/utils.py b/phpbb/utils.py
new file mode 100644
index 0000000..6064a8a
--- /dev/null
+++ b/phpbb/utils.py
@@ -0,0 +1,48 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# This file is part of django-phpbb, a Django-phpBB integration project
+# Copyright (C) 2007-2008 Maciej Bliziński
+#
+# Atopowe 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.
+#
+# Atopowe 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 Atopowe; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor,
+# Boston, MA 02110-1301 USA
+
+import re
+import string
+
+def slugify(s):
+ # FIXME: This is Polish-language-specific.
+ STOPLIST = [ 'i', 'a', 'z', 'w', 'u', 'o',
+ 'jak', 'sie', 'do',
+ 'na', 'to', 'quot', 'gt',
+ ]
+ if type(s) != unicode:
+ s = unicode(s, 'utf-8')
+ s = s.lower()
+ # FIXME: This is Polish-language-specific.
+ s = s.replace(u'ą', u'a')
+ s = s.replace(u'ć', u'c')
+ s = s.replace(u'ę', u'e')
+ s = s.replace(u'ł', u'l')
+ s = s.replace(u'ń', u'n')
+ s = s.replace(u'ó', u'o')
+ s = s.replace(u'ś', u's')
+ s = s.replace(u'ż', u'z')
+ s = s.replace(u'ź', u'z')
+ s = s.encode('utf-8')
+ keywords = re.findall(r'\w+', s.lower())
+ for stopkw in STOPLIST:
+ while stopkw in keywords:
+ keywords.remove(stopkw)
+ return u'-'.join(keywords)
diff --git a/phpbb/views.py b/phpbb/views.py
index fd48f95..9500412 100644
--- a/phpbb/views.py
+++ b/phpbb/views.py
@@ -42,8 +42,6 @@ def forum_index(request, forum_id, slug, page_no = None, paginate_by = 10):
if not(page_no >= 1 and page_no <= 1000):
raise Http404
f = ForumForum.objects.get(pk = forum_id)
- # if f.auth_read != 0:
- # raise Http404
if f.get_slug() != slug:
return HttpResponseRedirect(f.get_absolute_url())
topics = f.forumtopic_set.all()
@@ -94,8 +92,6 @@ def topic(request, topic_id, slug, page_no = None, paginate_by = 10):
t = ForumTopic.objects.get(pk = topic_id)
except exceptions.ObjectDoesNotExist, e:
raise Http404
- # if t.forum.auth_read != 0:
- # raise Http404
posts = t.forumpost_set.all()
if t.get_slug() != slug:
return HttpResponseRedirect(t.get_absolute_url())
@@ -125,9 +121,10 @@ def topic(request, topic_id, slug, page_no = None, paginate_by = 10):
def unanswered(request):
topics = ForumTopic.objects.filter(topic_replies = 0)
- return render_to_response("phpbb/unanswered.html", {
- 'topics': topics,
- }, context_instance = RequestContext(request))
+ return render_to_response(
+ "phpbb/unanswered.html",
+ {'topics': topics,},
+ context_instance = RequestContext(request))
def handle_viewtopic(request):
From 47af16a8b38a3b1bf2f8fb078c758d6e48c231fd Mon Sep 17 00:00:00 2001
From: "maciej.blizinski"
Date: Thu, 27 Nov 2008 21:48:48 +0000
Subject: [PATCH 11/60] Adding admin interface file.
git-svn-id: https://django-phpbb.googlecode.com/svn/trunk@13 2cc4e26e-97ec-11dd-87e9-a30ea5446288
---
phpbb/admin.py | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)
create mode 100644 phpbb/admin.py
diff --git a/phpbb/admin.py b/phpbb/admin.py
new file mode 100644
index 0000000..30f6491
--- /dev/null
+++ b/phpbb/admin.py
@@ -0,0 +1,22 @@
+from django.contrib import admin
+from django.contrib.phpbb.models import ForumForum
+from django.contrib.phpbb.models import ForumPost
+from django.contrib.phpbb.models import ForumTopic
+from django.contrib.phpbb.models import ForumUser
+
+class ForumForumAdmin(admin.ModelAdmin):
+ pass
+admin.site.register(ForumForum, ForumForumAdmin)
+class ForumTopicAdmin(admin.ModelAdmin):
+ pass
+admin.site.register(ForumTopic, ForumTopicAdmin)
+class ForumPostAdmin(admin.ModelAdmin):
+ list_display = ('post_id', 'get_absolute_url', 'get_time', )
+admin.site.register(ForumPost, ForumPostAdmin)
+class ForumUserAdmin(admin.ModelAdmin):
+ list_display = ('username',
+ 'user_id',
+ 'user_regdate',
+ 'user_posts',
+ 'user_email', )
+admin.site.register(ForumUser, ForumUserAdmin)
From cb8e463398a549dc1c2ce86438d6b9cdd6db22b5 Mon Sep 17 00:00:00 2001
From: "maciej.blizinski"
Date: Fri, 28 Nov 2008 10:27:01 +0000
Subject: [PATCH 12/60] Better RSS feeds.
git-svn-id: https://django-phpbb.googlecode.com/svn/trunk@14 2cc4e26e-97ec-11dd-87e9-a30ea5446288
---
phpbb/admin.py | 2 +-
phpbb/feeds.py | 2 +-
phpbb/models.py | 8 ++++----
phpbb/templates/feeds/forum_description.html | 2 ++
phpbb/templates/feeds/forum_title.html | 2 ++
phpbb/templatetags/phpbb.py | 13 ++++++++++++-
6 files changed, 22 insertions(+), 7 deletions(-)
create mode 100644 phpbb/templates/feeds/forum_description.html
create mode 100644 phpbb/templates/feeds/forum_title.html
diff --git a/phpbb/admin.py b/phpbb/admin.py
index 30f6491..5197850 100644
--- a/phpbb/admin.py
+++ b/phpbb/admin.py
@@ -11,7 +11,7 @@ class ForumTopicAdmin(admin.ModelAdmin):
pass
admin.site.register(ForumTopic, ForumTopicAdmin)
class ForumPostAdmin(admin.ModelAdmin):
- list_display = ('post_id', 'get_absolute_url', 'get_time', )
+ list_display = ('post_id', 'get_absolute_url', 'post_time', )
admin.site.register(ForumPost, ForumPostAdmin)
class ForumUserAdmin(admin.ModelAdmin):
list_display = ('username',
diff --git a/phpbb/feeds.py b/phpbb/feeds.py
index cffe5d5..dba4db2 100644
--- a/phpbb/feeds.py
+++ b/phpbb/feeds.py
@@ -27,6 +27,6 @@ class LatestForumPosts(Feed):
link = "/forum/"
description = _("Newest posts on the forum.")
def items(self):
- return ForumPost.objects.order_by('-post_time').exclude(topic__forum__forum_id=15).exclude(topic__forum__forum_id=6)[:20]
+ return ForumPost.objects.order_by('-post_time_int').exclude(topic__forum__forum_id=15).exclude(topic__forum__forum_id=6)[:20]
def item_link(self, obj):
return obj.get_external_url()
diff --git a/phpbb/models.py b/phpbb/models.py
index bbcefc6..0b27b74 100644
--- a/phpbb/models.py
+++ b/phpbb/models.py
@@ -105,10 +105,10 @@ class ForumPost(models.Model):
# post_title = models.CharField(max_length = 60)
topic = models.ForeignKey(ForumTopic)
poster = models.ForeignKey(ForumUser)
- post_time = models.IntegerField()
+ post_time_int = models.IntegerField(db_column='post_time')
post_text = models.TextField()
- def get_time(self):
- return datetime.fromtimestamp(self.post_time)
+ def post_time(self):
+ return datetime.fromtimestamp(self.post_time_int)
def __unicode__(self):
# return force_unicode(self.topic.topic_title + u" (post_id=%s)" % self.post_id)
return force_unicode(u" (post_id=%s)" % self.post_id)
@@ -123,7 +123,7 @@ def get_page(self):
return 1
class Meta:
db_table = 'phpbb3_posts'
- ordering = ['post_time']
+ ordering = ['post_time_int']
class ForumAclOption(models.Model):
diff --git a/phpbb/templates/feeds/forum_description.html b/phpbb/templates/feeds/forum_description.html
new file mode 100644
index 0000000..28fc3c8
--- /dev/null
+++ b/phpbb/templates/feeds/forum_description.html
@@ -0,0 +1,2 @@
+{% load phpbb %}
+{{ obj.post_text|bbcode }}
diff --git a/phpbb/templates/feeds/forum_title.html b/phpbb/templates/feeds/forum_title.html
new file mode 100644
index 0000000..1f350f6
--- /dev/null
+++ b/phpbb/templates/feeds/forum_title.html
@@ -0,0 +1,2 @@
+{{ obj.poster.username|escape }}: {{ obj.topic.get_title|escape }}
+({{ obj.post_time }})
diff --git a/phpbb/templatetags/phpbb.py b/phpbb/templatetags/phpbb.py
index a2b9b88..8f111d8 100644
--- a/phpbb/templatetags/phpbb.py
+++ b/phpbb/templatetags/phpbb.py
@@ -38,7 +38,6 @@ def bbcode(s):
s = re.sub(r':wink:', r'', s)
s = re.sub(r':!:', r'/!\\', s)
s = re.sub(r'\n\n', r'\n', s)
- s = re.sub(r'\n', r'
', s)
# Cudzysłowy drukarskie
# s = re.sub(r'"([^"]+)"', r'„\1”', s)
# usuwamy odstępy przed interpunkcją
@@ -48,6 +47,18 @@ def bbcode(s):
# musi być spacja przed nawiasem
# s = re.sub(r'([\wąćęłńóśżź])(\()', r'\1 \2', s)
s = re.sub(r'\?+', r'?', s)
+ # Remove HTML comment tags
+ s = re.sub(r']+>', r' ', s)
+ s = re.sub(r']+>', r' ', s)
+ s = re.sub(r']+>', r' ', s)
+ s = re.sub(r'[^>]+>', r' ', s)
+ # change URLs
+ s = re.sub(r'\[url=([^]]+)\]([^\[]+)\[/url:?[^]]+\]', r'\2', s)
+ # TODO: implement links
+ # re.sub(r'\[url=([^]]+)\]([^\[]+)\[/url:?[^]]+\]', r'\2',
+ # s)
+ # Quotations
+ s = re.sub(r'\[quote=([^]]+)\]([^\[]+)\[/quote:?[^]]+\]', r'"""\2"""', s)
return s
# @register.filter
From 739e900dcc282a7f2a97fac84d3d773bc247917e Mon Sep 17 00:00:00 2001
From: "maciej.blizinski"
Date: Sat, 29 Nov 2008 21:01:07 +0000
Subject: [PATCH 13/60] Updated admin interface and models. - Added displayed
columns to the admin interface - Minor phpBB model tweaks
git-svn-id: https://django-phpbb.googlecode.com/svn/trunk@15 2cc4e26e-97ec-11dd-87e9-a30ea5446288
---
phpbb/admin.py | 12 ++++++++++--
phpbb/models.py | 6 ++++--
2 files changed, 14 insertions(+), 4 deletions(-)
diff --git a/phpbb/admin.py b/phpbb/admin.py
index 5197850..0a1c04e 100644
--- a/phpbb/admin.py
+++ b/phpbb/admin.py
@@ -5,10 +5,18 @@
from django.contrib.phpbb.models import ForumUser
class ForumForumAdmin(admin.ModelAdmin):
- pass
+ list_display = (
+ 'forum_name',
+ 'forum_id',
+ 'forum_desc',
+ )
admin.site.register(ForumForum, ForumForumAdmin)
class ForumTopicAdmin(admin.ModelAdmin):
- pass
+ list_display = (
+ 'topic_title',
+ 'topic_id',
+ 'topic_time',
+ )
admin.site.register(ForumTopic, ForumTopicAdmin)
class ForumPostAdmin(admin.ModelAdmin):
list_display = ('post_id', 'get_absolute_url', 'post_time', )
diff --git a/phpbb/models.py b/phpbb/models.py
index 0b27b74..76638b2 100644
--- a/phpbb/models.py
+++ b/phpbb/models.py
@@ -76,7 +76,7 @@ class ForumTopic(models.Model):
topic_title = models.CharField(max_length = 60)
topic_replies = models.IntegerField()
topic_poster = models.ForeignKey(ForumUser, db_column = 'topic_poster')
- topic_time = models.IntegerField()
+ topic_time_int = models.IntegerField(db_column='topic_time')
forum = models.ForeignKey(ForumForum)
topic_last_post = models.ForeignKey('ForumPost', related_name = 'last_in')
topic_first_post = models.ForeignKey('ForumPost', related_name = 'first_in')
@@ -88,9 +88,11 @@ def get_absolute_url(self):
return "/forum/topics/%s/%s/" % (self.topic_id, self.get_slug())
def get_slug(self):
return slugify(self.get_title())
+ def topic_time(self):
+ return datetime.fromtimestamp(self.topic_time_int)
class Meta:
db_table = 'phpbb3_topics'
- ordering = ['-topic_time']
+ ordering = ['-topic_time_int']
# ordering = ['-topic_last_post_id']
# order_with_respect_to = 'topic_last_post'
# ordering = ['-post_time']
From 11e52b85e8274b870faa02fe483f52579f5b034c Mon Sep 17 00:00:00 2001
From: "maciej.blizinski"
Date: Sat, 29 Nov 2008 21:01:58 +0000
Subject: [PATCH 14/60] Bugfix: added loading of i18n tags to templates.
git-svn-id: https://django-phpbb.googlecode.com/svn/trunk@16 2cc4e26e-97ec-11dd-87e9-a30ea5446288
---
phpbb/templates/phpbb/forum_detail.html | 1 +
phpbb/templates/phpbb/forumforum_list.html | 1 +
phpbb/templates/phpbb/index.html | 3 ++-
phpbb/templates/phpbb/topic_detail.html | 1 +
4 files changed, 5 insertions(+), 1 deletion(-)
diff --git a/phpbb/templates/phpbb/forum_detail.html b/phpbb/templates/phpbb/forum_detail.html
index 929c22d..8eff7a0 100644
--- a/phpbb/templates/phpbb/forum_detail.html
+++ b/phpbb/templates/phpbb/forum_detail.html
@@ -1,4 +1,5 @@
{% extends "phpbb/index.html" %}
+{% load i18n %}
{% load phpbb %}
diff --git a/phpbb/templates/phpbb/forumforum_list.html b/phpbb/templates/phpbb/forumforum_list.html
index d82e40a..267c469 100644
--- a/phpbb/templates/phpbb/forumforum_list.html
+++ b/phpbb/templates/phpbb/forumforum_list.html
@@ -1,4 +1,5 @@
{% extends "phpbb/index.html" %}
+{% load i18n %}
{% load phpbb %}
{% block content %}
diff --git a/phpbb/templates/phpbb/index.html b/phpbb/templates/phpbb/index.html
index 52a18ba..f807ee7 100644
--- a/phpbb/templates/phpbb/index.html
+++ b/phpbb/templates/phpbb/index.html
@@ -1,8 +1,9 @@
+{% extends "base.html" %}
{% comment %}
This template assumes you have a 'base.html' file that can be extended.
{% endcomment %}
-{% extends "base.html" %}
{% load phpbb %}
+{% load i18n %}
{% block subtitle %}
{% trans "Discussion forum" %}
{% endblock %}
diff --git a/phpbb/templates/phpbb/topic_detail.html b/phpbb/templates/phpbb/topic_detail.html
index 03325de..3bb107a 100644
--- a/phpbb/templates/phpbb/topic_detail.html
+++ b/phpbb/templates/phpbb/topic_detail.html
@@ -1,4 +1,5 @@
{% extends "phpbb/index.html" %}
+{% load i18n %}
{% load phpbb %}
{% block bartitle %}{{ object }}{% endblock %}
From 175cba31c40df189a10f03764f426331187c7d61 Mon Sep 17 00:00:00 2001
From: "maciej.blizinski"
Date: Sun, 30 Nov 2008 11:45:54 +0000
Subject: [PATCH 15/60] - Added license note to admin.py - Started porting
bbcode - bitfield class port is complete (also has tests) - bbcode and
bbcode_first_pass classes are under construction - models.py - Added
fields: user_sig_bbcode_uid and user_sig_bbcode_bitfield - Style changes
git-svn-id: https://django-phpbb.googlecode.com/svn/trunk@17 2cc4e26e-97ec-11dd-87e9-a30ea5446288
---
TODO | 8 +-
phpbb/admin.py | 19 +++++
phpbb/bbcode.py | 155 +++++++++++++++++++++++++++++++++++++++
phpbb/bbcode_unittest.py | 99 +++++++++++++++++++++++++
phpbb/models.py | 56 +++++++-------
5 files changed, 307 insertions(+), 30 deletions(-)
create mode 100644 phpbb/bbcode.py
create mode 100644 phpbb/bbcode_unittest.py
diff --git a/TODO b/TODO
index 523e320..0b1199b 100644
--- a/TODO
+++ b/TODO
@@ -2,4 +2,10 @@ django-phpbb - Django PhpBB integration
To do list:
-- Add support for bbcode http://code.google.com/p/postmarkup/
+- Add support for bbcode
+ - Option 1: use http://code.google.com/p/postmarkup/
+ - Issues: Doesn't support integration with a real phpBB database
+ - Option 2: port original bbcode[1].
+
+[1] http://code.phpbb.com/repositories/entry/5/trunk/phpBB/includes/bbcode.php
+ http://code.phpbb.com/repositories/entry/5/trunk/phpBB/includes/message_parser.php
diff --git a/phpbb/admin.py b/phpbb/admin.py
index 0a1c04e..8c8395b 100644
--- a/phpbb/admin.py
+++ b/phpbb/admin.py
@@ -1,3 +1,22 @@
+# -*- coding: utf-8 -*-
+# This file is part of django-phpbb, integration between Django and phpBB
+# Copyright (C) 2007-2008 Maciej Bliziński
+#
+# django-phpbb 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.
+#
+# django-phpbb 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 django-phpbb; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor,
+# Boston, MA 02110-1301 USA
+
from django.contrib import admin
from django.contrib.phpbb.models import ForumForum
from django.contrib.phpbb.models import ForumPost
diff --git a/phpbb/bbcode.py b/phpbb/bbcode.py
new file mode 100644
index 0000000..2b75e8d
--- /dev/null
+++ b/phpbb/bbcode.py
@@ -0,0 +1,155 @@
+# -*- coding: utf-8 -*-
+# This file is part of django-phpbb, integration between Django and phpBB
+# Copyright (C) 2007-2008 Maciej Bliziński
+#
+# django-phpbb 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.
+#
+# django-phpbb 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 django-phpbb; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor,
+# Boston, MA 02110-1301 USA
+
+"""Port of phpBB's bbcode.
+
+Sources:
+http://code.phpbb.com/repositories/entry/5/trunk/phpBB/includes/bbcode.php
+http://code.phpbb.com/repositories/entry/5/trunk/phpBB/includes/message_parser.php
+"""
+
+import logging
+
+def decbin(n):
+ """PHP in-built function port."""
+ bin_str = ""
+ if n < 0:
+ raise ValueError, "Positive integer required"
+ if n == 0:
+ return '0'
+ while n > 0:
+ bin_str = str(n % 2) + bin_str
+ n = n >> 1
+ return bin_str
+
+
+class BitField(object):
+ """Bitfield class from phpBB.
+
+http://code.phpbb.com/repositories/entry/5/trunk/phpBB/includes/functions_content.php"""
+ def __init__(self, bitfield=""):
+ self.data = bitfield.decode("base64")
+
+ def get(self, n):
+ byte = n >> 3
+ if len(self.data) >= byte + 1:
+ c = self.data[byte]
+ # Lookup the (n % 8)th bit of the byte
+ bit = 7 - (n & 7);
+ return ord(c) & (1 << bit)
+ else:
+ return False
+
+ def set(self, n):
+ byte = n >> 3
+ bit = 7 - (n & 7)
+ if len(self.data) >= byte + 1:
+ # Strings in Python are immutable.
+ list_data = list(self.data)
+ list_data[byte] = chr(ord(self.data[byte]) | (1 << bit))
+ self.data = "".join(list_data)
+ else:
+ self.data += chr(0) * (byte - len(self.data))
+ self.data += chr(1 << bit)
+
+ def clear(self, n):
+ byte = n >> 3
+ if len(self.data) >= byte + 1:
+ bit = 7 - (n & 7)
+ # Strings in Python are immutable.
+ list_data = list(self.data)
+ list_data[byte] = chr(ord(self.data[byte]) &~ (1 << bit))
+ self.data = "".join(list_data)
+
+ def get_blob(self):
+ return self.data
+
+ def get_base64(self):
+ return self.data.encode("base64")
+
+ def get_bin(self):
+ bin = "";
+ data_len = len(self.data)
+ for i in range(data_len):
+ # str_pad(decbin(ord($this->data[$i])), 8, '0', STR_PAD_LEFT);
+ bin += decbin(ord(self.data[i])).rjust(8, '0')
+ return bin
+
+ def get_all_set(self):
+ pairs_with_ones = filter(lambda x: x[1] == '1',
+ enumerate(self.get_bin()))
+ return [x[0] for x in pairs_with_ones]
+
+ def merge(self, bitfield):
+ # Python doesn't support binary operations on strings
+ data_list = list(self.data)
+ # When PHP makes an 'or' on two strings of different length, it
+ # justifies to the left before merging.
+ max_len = max(len(self.data), len(bitfield.get_blob()))
+ a = self.get_blob().ljust(max_len, chr(0))
+ b = bitfield.get_blob().ljust(max_len, chr(0))
+ dst_list = []
+ for i in range(max_len):
+ dst_list.append(chr(ord(a[i]) | ord(b[i])))
+ self.data = "".join(dst_list)
+
+
+class BbCode(object):
+ """Port of bbcode phpBB class.
+
+Differences from the original class:
+
+- user is passed to the constructor (on original code, a global variable is
+ used)
+"""
+
+ def __init__(self, user, bitfield=""):
+ self.user = user
+ if bitfield:
+ self.bbcode_bitfield = bitfield
+ self.bbcode_cache_init()
+ self.bbcode_uid = ''
+ self.bbcode_bitfield = ''
+ self.bbcode_cache = []
+ self.bbcode_template = []
+ self.bbcodes = []
+ self.template_bitfield = None
+ self.template_filename = ''
+
+ def bbcode_cache_init(self):
+ if not self.template_filename:
+ template_bitfield = BitField(self.user.user_sig_bbcode_bitfield)
+ # TODO: continue from here.
+ # Create a way to access phpBB settings.
+
+
+class BbCodeFirstPass(BbCode):
+
+ def __init__(self, message="", warn_msg=None, parsed_items=None):
+ self.message = message
+ if not warn_msg:
+ warn_msg = []
+ self.warn_msg = warn_msg
+ if not parsed_items:
+ parsed_items = []
+ self.parsed_items = parsed_items
+
+ def parse_bbcode(self):
+ if not self.bbcodes:
+ self.bbcode_init()
diff --git a/phpbb/bbcode_unittest.py b/phpbb/bbcode_unittest.py
new file mode 100644
index 0000000..62cfd0d
--- /dev/null
+++ b/phpbb/bbcode_unittest.py
@@ -0,0 +1,99 @@
+# -*- coding: utf-8 -*-
+# This file is part of django-phpbb, integration between Django and phpBB
+# Copyright (C) 2007-2008 Maciej Bliziński
+#
+# django-phpbb 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.
+#
+# django-phpbb 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 django-phpbb; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor,
+# Boston, MA 02110-1301 USA
+
+import unittest
+import bbcode
+import mocker
+
+
+class BbCodeUnitTest(unittest.TestCase):
+
+ def setUp(self):
+ self.mocker = mocker.Mocker()
+ self.user = self.mocker.mock()
+ self.b1 = bbcode.BbCode(self.user)
+
+ def tearDown(self):
+ del self.b1
+
+ def testFoo(self):
+ self.user.replay()
+ self.b1.bbcode_cache_init()
+
+
+class BbCodeFirstPassUnitTest(unittest.TestCase):
+
+ def setUp(self):
+ self.bfp1 = bbcode.BbCodeFirstPass()
+
+ def tearDown(self):
+ del self.bfp1
+
+ def testWarnMsg1(self):
+ self.assertEquals(self.bfp1.warn_msg, [])
+
+
+class BitFieldUnitTest(unittest.TestCase):
+
+ def setUp(self):
+ self.b1 = bbcode.BitField("EA==\n")
+
+ def testGet0(self):
+ self.assertEquals(self.b1.get(0), 0)
+
+ def testGet3(self):
+ self.assertEquals(self.b1.get(3), 16)
+
+ def testGet4(self):
+ self.assertEquals(self.b1.get(4), 0)
+
+ def testSet0(self):
+ self.b1.set(0)
+ self.assertEquals(self.b1.get(0), 128)
+
+ def testSet0(self):
+ self.b1.set(0)
+ self.assertEquals(self.b1.get_bin(), "10010000")
+
+ def testGetBin(self):
+ self.assertEquals(self.b1.get_bin(), "00010000")
+
+ def testGetAllSet(self):
+ self.assertEquals(self.b1.get_all_set(), [3, ])
+
+ def testGetBlob(self):
+ self.assertEquals(self.b1.get_blob(), '\x10')
+
+ def testMerge(self):
+ b1 = bbcode.BitField()
+ b2 = bbcode.BitField()
+ b1.set(0)
+ b2.set(1)
+ self.assertEquals(b2.get(1), 64)
+ b1.merge(b2)
+ self.assertEquals(b1.get(0), 128)
+ self.assertEquals(b1.get(1), 64)
+ del b1, b2
+
+ def tearDown(self):
+ del self.b1
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/phpbb/models.py b/phpbb/models.py
index 76638b2..b440a02 100644
--- a/phpbb/models.py
+++ b/phpbb/models.py
@@ -25,16 +25,18 @@
from django.utils.encoding import force_unicode
class ForumUser(models.Model):
- user_id = models.IntegerField(primary_key = True)
- username = models.CharField(max_length = 25)
- user_password = models.CharField(max_length = 32)
+ user_id = models.IntegerField(primary_key=True)
+ username = models.CharField(max_length=25)
+ user_password = models.CharField(max_length=32)
user_posts = models.IntegerField()
- user_email = models.CharField(max_length = 255)
- user_website = models.CharField(max_length = 100)
+ user_email = models.CharField(max_length=255)
+ user_website = models.CharField(max_length=100)
user_avatar_type = models.IntegerField()
- user_avatar = models.CharField(max_length = 250)
+ user_avatar = models.CharField(max_length=250)
user_regdate_int = models.IntegerField(db_column="user_regdate")
user_lastvisit_int = models.IntegerField(db_column="user_regdate")
+ user_sig_bbcode_uid = models.CharField(max_length=8)
+ user_sig_bbcode_bitfield = models.CharField(max_length=255)
def __unicode__(self):
return self.username
def user_regdate(self):
@@ -49,16 +51,16 @@ class Meta:
class DjangoPhpbbUserMapping(models.Model):
"""Maps phpBB users to Django users, 1:1."""
django_user = models.OneToOneField(User)
- phpbb_user = models.ForeignKey(ForumUser, unique = True)
+ phpbb_user = models.ForeignKey(ForumUser, unique=True)
class ForumForum(models.Model):
- forum_id = models.IntegerField(primary_key = True)
- forum_name = models.CharField(max_length = 60)
+ forum_id = models.IntegerField(primary_key=True)
+ forum_name = models.CharField(max_length=60)
forum_topics = models.IntegerField()
forum_posts = models.IntegerField()
forum_last_post = models.ForeignKey(
- 'ForumPost', db_column = 'forum_last_post_id')
+ 'ForumPost', db_column='forum_last_post_id')
forum_desc = models.TextField()
def __unicode__(self):
return force_unicode(self.forum_name)
@@ -72,14 +74,14 @@ class Meta:
class ForumTopic(models.Model):
- topic_id = models.IntegerField(primary_key = True)
- topic_title = models.CharField(max_length = 60)
+ topic_id = models.IntegerField(primary_key=True)
+ topic_title = models.CharField(max_length=60)
topic_replies = models.IntegerField()
- topic_poster = models.ForeignKey(ForumUser, db_column = 'topic_poster')
+ topic_poster = models.ForeignKey(ForumUser, db_column='topic_poster')
topic_time_int = models.IntegerField(db_column='topic_time')
forum = models.ForeignKey(ForumForum)
- topic_last_post = models.ForeignKey('ForumPost', related_name = 'last_in')
- topic_first_post = models.ForeignKey('ForumPost', related_name = 'first_in')
+ topic_last_post = models.ForeignKey('ForumPost', related_name='last_in')
+ topic_first_post = models.ForeignKey('ForumPost', related_name='first_in')
def get_title(self):
return self.topic_title
def __unicode__(self):
@@ -93,17 +95,12 @@ def topic_time(self):
class Meta:
db_table = 'phpbb3_topics'
ordering = ['-topic_time_int']
- # ordering = ['-topic_last_post_id']
- # order_with_respect_to = 'topic_last_post'
- # ordering = ['-post_time']
- class Admin:
- pass
class ForumPost(models.Model):
"""phpBB3 forum post."""
PAGINATE_BY = 10
- post_id = models.IntegerField(primary_key = True)
+ post_id = models.IntegerField(primary_key=True)
# post_title = models.CharField(max_length = 60)
topic = models.ForeignKey(ForumTopic)
poster = models.ForeignKey(ForumUser)
@@ -112,14 +109,15 @@ class ForumPost(models.Model):
def post_time(self):
return datetime.fromtimestamp(self.post_time_int)
def __unicode__(self):
- # return force_unicode(self.topic.topic_title + u" (post_id=%s)" % self.post_id)
return force_unicode(u" (post_id=%s)" % self.post_id)
def get_external_url(self):
return ("http://www.atopowe-zapalenie.pl/forum/viewtopic.php?p=%s#%s" %
(self.post_id, self.post_id))
def get_absolute_url(self):
return (u"/forum/topics/%s/%s/page%d/" %
- (self.topic.topic_id, self.topic.get_slug(), self.get_page()))
+ (self.topic.topic_id,
+ self.topic.get_slug(),
+ self.get_page()))
def get_page(self):
"""TODO: find out, which post in the row it is."""
return 1
@@ -129,19 +127,19 @@ class Meta:
class ForumAclOption(models.Model):
- auth_option_id = models.IntegerField(primary_key = True)
+ auth_option_id = models.IntegerField(primary_key=True)
is_global = models.IntegerField()
is_local = models.IntegerField()
founder_only = models.IntegerField()
- auth_option = models.CharField(max_length = 60)
+ auth_option = models.CharField(max_length=60)
class Meta:
db_table = 'phpbb3_acl_options'
ordering = ['auth_option']
class ForumAclRole(models.Model):
- role_id = models.IntegerField(primary_key = True)
- role_name = models.CharField(max_length = 255)
+ role_id = models.IntegerField(primary_key=True)
+ role_name = models.CharField(max_length=255)
role_order = models.IntegerField()
class Meta:
db_table = 'phpbb3_acl_roles'
@@ -149,9 +147,9 @@ class Meta:
class ForumAclRoleData(models.Model):
- role_id = models.ForeignKey('ForumAclRole', db_column = 'role_id')
+ role_id = models.ForeignKey('ForumAclRole', db_column='role_id')
auth_option_id = models.ForeignKey(
- 'ForumAclOption', db_column = 'auth_option_id')
+ 'ForumAclOption', db_column='auth_option_id')
auth_setting = models.IntegerField()
class Meta:
db_table = 'phpbb3_acl_roles_data'
From b3c75f9988af91e3980b0921466b2d76809c34a2 Mon Sep 17 00:00:00 2001
From: "maciej.blizinski"
Date: Sun, 30 Nov 2008 22:23:45 +0000
Subject: [PATCH 16/60] - Renamed classes Forum* to Phpbb*. - Added model for
PhpbbConfig.
git-svn-id: https://django-phpbb.googlecode.com/svn/trunk@18 2cc4e26e-97ec-11dd-87e9-a30ea5446288
---
phpbb/admin.py | 30 +++++++-----
phpbb/backends.py | 6 +--
phpbb/bbcode_unittest.py | 6 ++-
phpbb/feeds.py | 8 ++--
phpbb/models.py | 47 ++++++++++++-------
phpbb/sitemap.py | 10 ++--
...umforum_list.html => phpbbforum_list.html} | 0
phpbb/urls.py | 2 +-
phpbb/views.py | 16 +++----
9 files changed, 74 insertions(+), 51 deletions(-)
rename phpbb/templates/phpbb/{forumforum_list.html => phpbbforum_list.html} (100%)
diff --git a/phpbb/admin.py b/phpbb/admin.py
index 8c8395b..0af9233 100644
--- a/phpbb/admin.py
+++ b/phpbb/admin.py
@@ -18,32 +18,38 @@
# Boston, MA 02110-1301 USA
from django.contrib import admin
-from django.contrib.phpbb.models import ForumForum
-from django.contrib.phpbb.models import ForumPost
-from django.contrib.phpbb.models import ForumTopic
-from django.contrib.phpbb.models import ForumUser
+from django.contrib.phpbb.models import PhpbbForum
+from django.contrib.phpbb.models import PhpbbPost
+from django.contrib.phpbb.models import PhpbbTopic
+from django.contrib.phpbb.models import PhpbbUser
+from django.contrib.phpbb.models import PhpbbConfig
-class ForumForumAdmin(admin.ModelAdmin):
+class PhpbbForumAdmin(admin.ModelAdmin):
list_display = (
'forum_name',
'forum_id',
'forum_desc',
)
-admin.site.register(ForumForum, ForumForumAdmin)
-class ForumTopicAdmin(admin.ModelAdmin):
+admin.site.register(PhpbbForum, PhpbbForumAdmin)
+class PhpbbTopicAdmin(admin.ModelAdmin):
list_display = (
'topic_title',
'topic_id',
'topic_time',
)
-admin.site.register(ForumTopic, ForumTopicAdmin)
-class ForumPostAdmin(admin.ModelAdmin):
+admin.site.register(PhpbbTopic, PhpbbTopicAdmin)
+class PhpbbPostAdmin(admin.ModelAdmin):
list_display = ('post_id', 'get_absolute_url', 'post_time', )
-admin.site.register(ForumPost, ForumPostAdmin)
-class ForumUserAdmin(admin.ModelAdmin):
+admin.site.register(PhpbbPost, PhpbbPostAdmin)
+class PhpbbUserAdmin(admin.ModelAdmin):
list_display = ('username',
'user_id',
'user_regdate',
'user_posts',
'user_email', )
-admin.site.register(ForumUser, ForumUserAdmin)
+admin.site.register(PhpbbUser, PhpbbUserAdmin)
+class PhpbbConfigAdmin(admin.ModelAdmin):
+ list_display = ('config_name',
+ 'config_value',
+ 'is_dynamic')
+admin.site.register(PhpbbConfig, PhpbbConfigAdmin)
diff --git a/phpbb/backends.py b/phpbb/backends.py
index 24ed527..2f6da46 100644
--- a/phpbb/backends.py
+++ b/phpbb/backends.py
@@ -19,7 +19,7 @@
import logging
from django.contrib.auth.models import User
-from models import ForumUser
+from models import PhpbbUser
import password as php_password
logging.basicConfig(level=logging.DEBUG)
@@ -34,8 +34,8 @@ def authenticate(self, username=None, password=None):
logging.debug("PhpbbBackend::authenticate()")
user = None
try:
- phpbb_user = ForumUser.objects.get(username = username)
- except ForumUser.DoesNotExist:
+ phpbb_user = PhpbbUser.objects.get(username = username)
+ except PhpbbUser.DoesNotExist:
# The user does not exist in phpBB. Bailing out.
logging.warning("User '%s' doesn't exist." % username)
return None
diff --git a/phpbb/bbcode_unittest.py b/phpbb/bbcode_unittest.py
index 62cfd0d..063495f 100644
--- a/phpbb/bbcode_unittest.py
+++ b/phpbb/bbcode_unittest.py
@@ -19,6 +19,7 @@
import unittest
import bbcode
+# http://labix.org/mocker
import mocker
@@ -67,7 +68,7 @@ def testSet0(self):
self.b1.set(0)
self.assertEquals(self.b1.get(0), 128)
- def testSet0(self):
+ def testSet1(self):
self.b1.set(0)
self.assertEquals(self.b1.get_bin(), "10010000")
@@ -75,7 +76,8 @@ def testGetBin(self):
self.assertEquals(self.b1.get_bin(), "00010000")
def testGetAllSet(self):
- self.assertEquals(self.b1.get_all_set(), [3, ])
+ self.b1.set(7)
+ self.assertEquals(self.b1.get_all_set(), [3, 7])
def testGetBlob(self):
self.assertEquals(self.b1.get_blob(), '\x10')
diff --git a/phpbb/feeds.py b/phpbb/feeds.py
index dba4db2..03dfe7c 100644
--- a/phpbb/feeds.py
+++ b/phpbb/feeds.py
@@ -20,13 +20,15 @@
from django.utils.translation import gettext_lazy as _
from django.contrib.syndication.feeds import Feed
-from models import ForumPost
+from models import PhpbbPost
-class LatestForumPosts(Feed):
+class LatestPhpbbPosts(Feed):
title = u"Forum"
link = "/forum/"
description = _("Newest posts on the forum.")
def items(self):
- return ForumPost.objects.order_by('-post_time_int').exclude(topic__forum__forum_id=15).exclude(topic__forum__forum_id=6)[:20]
+ return (PhpbbPost.objects.order_by('-post_time_int').
+ exclude(topic__forum__forum_id=15).
+ exclude(topic__forum__forum_id=6)[:20])
def item_link(self, obj):
return obj.get_external_url()
diff --git a/phpbb/models.py b/phpbb/models.py
index b440a02..d7977ad 100644
--- a/phpbb/models.py
+++ b/phpbb/models.py
@@ -24,7 +24,7 @@
from django.core import exceptions
from django.utils.encoding import force_unicode
-class ForumUser(models.Model):
+class PhpbbUser(models.Model):
user_id = models.IntegerField(primary_key=True)
username = models.CharField(max_length=25)
user_password = models.CharField(max_length=32)
@@ -51,16 +51,16 @@ class Meta:
class DjangoPhpbbUserMapping(models.Model):
"""Maps phpBB users to Django users, 1:1."""
django_user = models.OneToOneField(User)
- phpbb_user = models.ForeignKey(ForumUser, unique=True)
+ phpbb_user = models.ForeignKey(PhpbbUser, unique=True)
-class ForumForum(models.Model):
+class PhpbbForum(models.Model):
forum_id = models.IntegerField(primary_key=True)
forum_name = models.CharField(max_length=60)
forum_topics = models.IntegerField()
forum_posts = models.IntegerField()
forum_last_post = models.ForeignKey(
- 'ForumPost', db_column='forum_last_post_id')
+ 'PhpbbPost', db_column='forum_last_post_id')
forum_desc = models.TextField()
def __unicode__(self):
return force_unicode(self.forum_name)
@@ -73,15 +73,15 @@ class Meta:
ordering = ['forum_name']
-class ForumTopic(models.Model):
+class PhpbbTopic(models.Model):
topic_id = models.IntegerField(primary_key=True)
topic_title = models.CharField(max_length=60)
topic_replies = models.IntegerField()
- topic_poster = models.ForeignKey(ForumUser, db_column='topic_poster')
+ topic_poster = models.ForeignKey(PhpbbUser, db_column='topic_poster')
topic_time_int = models.IntegerField(db_column='topic_time')
- forum = models.ForeignKey(ForumForum)
- topic_last_post = models.ForeignKey('ForumPost', related_name='last_in')
- topic_first_post = models.ForeignKey('ForumPost', related_name='first_in')
+ forum = models.ForeignKey(PhpbbForum)
+ topic_last_post = models.ForeignKey('PhpbbPost', related_name='last_in')
+ topic_first_post = models.ForeignKey('PhpbbPost', related_name='first_in')
def get_title(self):
return self.topic_title
def __unicode__(self):
@@ -97,13 +97,13 @@ class Meta:
ordering = ['-topic_time_int']
-class ForumPost(models.Model):
+class PhpbbPost(models.Model):
"""phpBB3 forum post."""
PAGINATE_BY = 10
post_id = models.IntegerField(primary_key=True)
# post_title = models.CharField(max_length = 60)
- topic = models.ForeignKey(ForumTopic)
- poster = models.ForeignKey(ForumUser)
+ topic = models.ForeignKey(PhpbbTopic)
+ poster = models.ForeignKey(PhpbbUser)
post_time_int = models.IntegerField(db_column='post_time')
post_text = models.TextField()
def post_time(self):
@@ -126,7 +126,7 @@ class Meta:
ordering = ['post_time_int']
-class ForumAclOption(models.Model):
+class PhpbbAclOption(models.Model):
auth_option_id = models.IntegerField(primary_key=True)
is_global = models.IntegerField()
is_local = models.IntegerField()
@@ -137,7 +137,7 @@ class Meta:
ordering = ['auth_option']
-class ForumAclRole(models.Model):
+class PhpbbAclRole(models.Model):
role_id = models.IntegerField(primary_key=True)
role_name = models.CharField(max_length=255)
role_order = models.IntegerField()
@@ -146,10 +146,23 @@ class Meta:
ordering = ['role_order']
-class ForumAclRoleData(models.Model):
- role_id = models.ForeignKey('ForumAclRole', db_column='role_id')
+class PhpbbAclRoleData(models.Model):
+ role_id = models.ForeignKey('PhpbbAclRole', db_column='role_id')
auth_option_id = models.ForeignKey(
- 'ForumAclOption', db_column='auth_option_id')
+ 'PhpbbAclOption', db_column='auth_option_id')
auth_setting = models.IntegerField()
class Meta:
db_table = 'phpbb3_acl_roles_data'
+
+
+class PhpbbConfig(models.Model):
+ config_name = models.CharField(max_length=255, primary_key=True)
+ config_value = models.CharField(max_length=255)
+ is_dynamic = models.IntegerField()
+ def __unicode__(self):
+ return self.config_name
+ class Meta:
+ db_table = 'phpbb3_config'
+ ordering = ['config_name']
+ verbose_name = 'config entry'
+ verbose_name_plural = 'config entries'
diff --git a/phpbb/sitemap.py b/phpbb/sitemap.py
index 2b49b4f..51e0105 100644
--- a/phpbb/sitemap.py
+++ b/phpbb/sitemap.py
@@ -18,22 +18,22 @@
# Boston, MA 02110-1301 USA
from django.contrib import sitemaps
-from models import ForumTopic, ForumPost, ForumForum
+from models import PhpbbTopic, PhpbbPost, PhpbbForum
from urls import forumqs
-class ForumForumSitemap(sitemaps.Sitemap):
+class PhpbbForumSitemap(sitemaps.Sitemap):
changefreq = "monthly"
priority = 0.4
def items(self):
return forumqs
-class ForumTopicSitemap(sitemaps.Sitemap):
+class PhpbbTopicSitemap(sitemaps.Sitemap):
changefreq = "monthly"
priority = 0.4
def items(self):
- return ForumTopic.objects.exclude(forum__forum_id=15).exclude(forum__forum_id=6)
+ return PhpbbTopic.objects.exclude(forum__forum_id=15).exclude(forum__forum_id=6)
def lastmod(self, obj):
try:
return obj.topic_last_post.get_time()
- except ForumPost.DoesNotExist:
+ except PhpbbPost.DoesNotExist:
return None
diff --git a/phpbb/templates/phpbb/forumforum_list.html b/phpbb/templates/phpbb/phpbbforum_list.html
similarity index 100%
rename from phpbb/templates/phpbb/forumforum_list.html
rename to phpbb/templates/phpbb/phpbbforum_list.html
diff --git a/phpbb/urls.py b/phpbb/urls.py
index d2a27fd..cc66772 100644
--- a/phpbb/urls.py
+++ b/phpbb/urls.py
@@ -21,7 +21,7 @@
import views
import models
-forumqs = (models.ForumForum.objects.exclude(forum_name='INDEX PAGE').
+forumqs = (models.PhpbbForum.objects.exclude(forum_name='INDEX PAGE').
exclude(forum_name='MEMBERLIST').
# FIXME: hardcoded forum IDs
exclude(forum_id=15).
diff --git a/phpbb/views.py b/phpbb/views.py
index 9500412..b5a94d8 100644
--- a/phpbb/views.py
+++ b/phpbb/views.py
@@ -17,7 +17,7 @@
# Foundation, Inc., 51 Franklin St, Fifth Floor,
# Boston, MA 02110-1301 USA
-from models import ForumForum, ForumTopic, ForumPost
+from models import PhpbbForum, PhpbbTopic, PhpbbPost
from django.http import HttpResponseRedirect, Http404
from django.template.context import RequestContext
from django.shortcuts import get_object_or_404, render_to_response
@@ -41,10 +41,10 @@ def forum_index(request, forum_id, slug, page_no = None, paginate_by = 10):
page_no = 1
if not(page_no >= 1 and page_no <= 1000):
raise Http404
- f = ForumForum.objects.get(pk = forum_id)
+ f = PhpbbForum.objects.get(pk = forum_id)
if f.get_slug() != slug:
return HttpResponseRedirect(f.get_absolute_url())
- topics = f.forumtopic_set.all()
+ topics = f.phpbbtopic_set.all()
paginator = Paginator(topics, paginate_by)
print "page_no:", page_no
try:
@@ -89,10 +89,10 @@ def topic(request, topic_id, slug, page_no = None, paginate_by = 10):
if not(page_no >= 1 and page_no <= 1000):
raise Http404
try:
- t = ForumTopic.objects.get(pk = topic_id)
+ t = PhpbbTopic.objects.get(pk = topic_id)
except exceptions.ObjectDoesNotExist, e:
raise Http404
- posts = t.forumpost_set.all()
+ posts = t.phpbbpost_set.all()
if t.get_slug() != slug:
return HttpResponseRedirect(t.get_absolute_url())
paginator = Paginator(posts, paginate_by)
@@ -120,7 +120,7 @@ def topic(request, topic_id, slug, page_no = None, paginate_by = 10):
def unanswered(request):
- topics = ForumTopic.objects.filter(topic_replies = 0)
+ topics = PhpbbTopic.objects.filter(topic_replies = 0)
return render_to_response(
"phpbb/unanswered.html",
{'topics': topics,},
@@ -130,9 +130,9 @@ def unanswered(request):
def handle_viewtopic(request):
if request.GET.has_key('t'):
topic_id = request.GET['t']
- t = ForumTopic.objects.get(pk = topic_id)
+ t = PhpbbTopic.objects.get(pk = topic_id)
return HttpResponseRedirect(t.get_absolute_url())
if request.GET.has_key('p'):
topic_id = request.GET['p']
- t = ForumPost.objects.get(pk = topic_id)
+ t = PhpbbPost.objects.get(pk = topic_id)
return HttpResponseRedirect(t.get_absolute_url())
From 9ceb18aeb9518c0ccb3f812e98a87bf8d0cb2307 Mon Sep 17 00:00:00 2001
From: "maciej.blizinski"
Date: Sun, 30 Nov 2008 22:31:38 +0000
Subject: [PATCH 17/60] Added localization files with some polish translations.
git-svn-id: https://django-phpbb.googlecode.com/svn/trunk@19 2cc4e26e-97ec-11dd-87e9-a30ea5446288
---
phpbb/locale/pl/LC_MESSAGES/django.mo | Bin 0 -> 790 bytes
phpbb/locale/pl/LC_MESSAGES/django.po | 53 ++++++++++++++++++++++++
phpbb/templates/phpbb/forum_detail.html | 4 +-
3 files changed, 55 insertions(+), 2 deletions(-)
create mode 100644 phpbb/locale/pl/LC_MESSAGES/django.mo
create mode 100644 phpbb/locale/pl/LC_MESSAGES/django.po
diff --git a/phpbb/locale/pl/LC_MESSAGES/django.mo b/phpbb/locale/pl/LC_MESSAGES/django.mo
new file mode 100644
index 0000000000000000000000000000000000000000..5ef86f3bcd853cf9d68c21496de98bf35edd19c0
GIT binary patch
literal 790
zcmYk3&2G~`6osd>6tKik5eukT%z|AtAq_$*rj)vgTO#Zv89{bFlW8YtQmp&0x06l~T&`szoI?9-YsL++%Lmei!}
zkF1qi(Iag}L$W)&rd%r8;<+FVF&5U*LR)7kT<%!Roh8y!T-mWOBBQgumhfDY`7=uf
z+&a=S`b6{{t7mLq7=KJiTT%6Ov=`I;xZSBY8$nwX+BlZlTxM)%lv~!-Aq`s1E~^@W
zoLaFOcOs;fa(RQTud^p*TB(GUXKQ5?jI1r*OW*v$_co5&EN!w{L|-+-w7z!GY{Wr=
zK&)$!Z@`^4A>HjI32j7aOgG~+swdk~t=5h^oh?{ZKEl_tuHeIvCQ)Or=Ob?>$@V~&
zw8^)Ew4TP7AGKa82UV?{P&i{!AgmJ~+~Z<^ANid2kGZkJz36p!*~X>MXE_pv#j39}
zsq&C+97-3=#-zuB9`J$>gpz`GPS4NGWIi04P3-B&PEM4#m{!LbtvKEL{_*^5tT<`#
n6Q##?DrRGwP`sNBw?uZtl, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2008-11-30 22:29+0000\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME \n"
+"Language-Team: LANGUAGE \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: feeds.py:28
+msgid "Newest posts on the forum."
+msgstr "Najnowsze posty na forum."
+
+#: templates/phpbb/forum_detail.html:31
+msgid "answers"
+msgstr "odpowiedzi"
+
+#: templates/phpbb/forum_detail.html:31
+msgid "last"
+msgstr "ost."
+
+#: templates/phpbb/forum_detail.html:31
+msgid "ago"
+msgstr "temu"
+
+#: templates/phpbb/index.html:8
+msgid "Discussion forum"
+msgstr "Forum dyskusyjne"
+
+#: templates/phpbb/phpbbforum_list.html:7
+msgid "Forum"
+msgstr "Forum"
+
+#: templates/phpbb/phpbbforum_list.html:8
+msgid "Atopic Dermatitis"
+msgstr "Atopowe Zapalenie Skóry"
+
+#: templates/phpbb/phpbbforum_list.html:9
+msgid "Main Page"
+msgstr "Strona Główna"
+
+#: templates/phpbb/phpbbforum_list.html:16
+msgid "Unanswered topics"
+msgstr "Bez odpowiedzi"
diff --git a/phpbb/templates/phpbb/forum_detail.html b/phpbb/templates/phpbb/forum_detail.html
index 8eff7a0..438051d 100644
--- a/phpbb/templates/phpbb/forum_detail.html
+++ b/phpbb/templates/phpbb/forum_detail.html
@@ -27,8 +27,8 @@ {{ object }}
-
{{ topic }}
-{{ topic.topic_poster.get_username }},
- {% trans "odpowiedzi" %}: {{ topic.topic_replies }}, {% trans "last" %} {{ topic.topic_last_post.poster.get_username }}, {{ topic.topic_last_post.get_time|timesince }} {% trans "ago" %}
+{{ topic.topic_poster.username }},
+ {% trans "answers" %}: {{ topic.topic_replies }}, {% trans "last" %} {{ topic.topic_last_post.poster.username }}, {{ topic.topic_last_post.post_time|timesince }} {% trans "ago" %}
»
From 76901e90393073aa478ab0d7de97f36836ebbcbd Mon Sep 17 00:00:00 2001
From: "maciej.blizinski"
Date: Sun, 30 Nov 2008 22:48:40 +0000
Subject: [PATCH 18/60] Better ordering of topics in forum index.
git-svn-id: https://django-phpbb.googlecode.com/svn/trunk@20 2cc4e26e-97ec-11dd-87e9-a30ea5446288
---
phpbb/models.py | 4 ++++
phpbb/urls.py | 6 +++---
phpbb/views.py | 8 +++++---
3 files changed, 12 insertions(+), 6 deletions(-)
diff --git a/phpbb/models.py b/phpbb/models.py
index d7977ad..b53fb19 100644
--- a/phpbb/models.py
+++ b/phpbb/models.py
@@ -82,8 +82,12 @@ class PhpbbTopic(models.Model):
forum = models.ForeignKey(PhpbbForum)
topic_last_post = models.ForeignKey('PhpbbPost', related_name='last_in')
topic_first_post = models.ForeignKey('PhpbbPost', related_name='first_in')
+ topic_last_post_time_int = models.IntegerField(
+ db_column='topic_last_post_time')
def get_title(self):
return self.topic_title
+ def topic_last_post_time(self):
+ return datetime.fromtimestamp(self.topic_last_post_time_int)
def __unicode__(self):
return self.get_title()
def get_absolute_url(self):
diff --git a/phpbb/urls.py b/phpbb/urls.py
index cc66772..3daf2ce 100644
--- a/phpbb/urls.py
+++ b/phpbb/urls.py
@@ -22,10 +22,10 @@
import models
forumqs = (models.PhpbbForum.objects.exclude(forum_name='INDEX PAGE').
- exclude(forum_name='MEMBERLIST').
+ exclude(forum_name='MEMBERLIST').
# FIXME: hardcoded forum IDs
- exclude(forum_id=15).
- exclude(forum_id=6))
+ exclude(forum_id=15).
+ exclude(forum_id=6))
urlpatterns = patterns('',
(r'^$', 'django.views.generic.list_detail.object_list',
diff --git a/phpbb/views.py b/phpbb/views.py
index b5a94d8..606bbd1 100644
--- a/phpbb/views.py
+++ b/phpbb/views.py
@@ -30,21 +30,23 @@ def forum_index(request, forum_id, slug, page_no = None, paginate_by = 10):
try:
if int(page_no) == 1:
return HttpResponseRedirect("../")
- except:
+ except ValueError:
pass
path_prefix = "../"
else:
path_prefix = ""
try:
page_no = int(page_no)
- except:
+ except ValueError:
+ page_no = 1
+ except TypeError:
page_no = 1
if not(page_no >= 1 and page_no <= 1000):
raise Http404
f = PhpbbForum.objects.get(pk = forum_id)
if f.get_slug() != slug:
return HttpResponseRedirect(f.get_absolute_url())
- topics = f.phpbbtopic_set.all()
+ topics = f.phpbbtopic_set.all().order_by('-topic_last_post_time_int')
paginator = Paginator(topics, paginate_by)
print "page_no:", page_no
try:
From 8981e45cb9edf5ee2028d3d66e51815b6d5afebc Mon Sep 17 00:00:00 2001
From: "maciej.blizinski"
Date: Tue, 2 Dec 2008 08:22:47 +0000
Subject: [PATCH 19/60] Updated links to forum posts.
git-svn-id: https://django-phpbb.googlecode.com/svn/trunk@21 2cc4e26e-97ec-11dd-87e9-a30ea5446288
---
phpbb/models.py | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/phpbb/models.py b/phpbb/models.py
index b53fb19..ad0be30 100644
--- a/phpbb/models.py
+++ b/phpbb/models.py
@@ -115,8 +115,10 @@ def post_time(self):
def __unicode__(self):
return force_unicode(u" (post_id=%s)" % self.post_id)
def get_external_url(self):
- return ("http://www.atopowe-zapalenie.pl/forum/viewtopic.php?p=%s#%s" %
- (self.post_id, self.post_id))
+ # Example:
+ # http://www.atopowe-zapalenie.pl/forum/viewtopic.php?p=80491#p80491
+ return ("http://www.atopowe-zapalenie.pl/forum/viewtopic.php?p=%s#p%s"
+ % (self.post_id, self.post_id))
def get_absolute_url(self):
return (u"/forum/topics/%s/%s/page%d/" %
(self.topic.topic_id,
From 675aa10ae34c57ba619b40f56f0785323bea6e4d Mon Sep 17 00:00:00 2001
From: "maciej.blizinski"
Date: Fri, 5 Dec 2008 09:52:25 +0000
Subject: [PATCH 20/60] Added translation for 'topics'.
git-svn-id: https://django-phpbb.googlecode.com/svn/trunk@22 2cc4e26e-97ec-11dd-87e9-a30ea5446288
---
phpbb/locale/pl/LC_MESSAGES/django.mo | Bin 790 -> 836 bytes
phpbb/locale/pl/LC_MESSAGES/django.po | 6 +++++-
phpbb/models.py | 6 +++++-
phpbb/urls.py | 9 +++++----
4 files changed, 15 insertions(+), 6 deletions(-)
diff --git a/phpbb/locale/pl/LC_MESSAGES/django.mo b/phpbb/locale/pl/LC_MESSAGES/django.mo
index 5ef86f3bcd853cf9d68c21496de98bf35edd19c0..b9f0f662c6dba75145f09fca1dba82ce08276e77 100644
GIT binary patch
delta 314
zcmX}ny$-=p7{>8as-+TN6Jn59EKM3AXkv2;`cO
z{9nYIJo%lI<~-+gZ=8+gEu-%g6DI}YlQg*ynUwb3r!mF8gb}P_3|-7)8|7RN!#G6~
z1JrSW2ClG1)+DRcQXNCz;wwt=9h3OP9KJAtIa;Ntj27CzeFLSqg>?QW%1VApzDch<
yRz^Bxq{IBDcSmdz9Kd0>d9qhW**r(>hkgc4|eZ=~nB9lh)Nte=zd=xq1Vw%N#}k
delta 284
zcmXZWyAA8RuqWH7Fr1_3L24k0SP*VTOlDtw%=O4AznkYDp7a@l~#)<
z@IM=qeEH2JXTLo+<6yYYOlYq-aZ)5pk{}l%=S@uVA!!oSN`*0tF)UyK%P4bg3}O!>
zIKU8&ut6py$NL!Y`&@P6B868>;T`k%z$AWA3N)>cL}Z&zc-E9sfH)BSj@Qm\n"
"Language-Team: LANGUAGE \n"
@@ -20,6 +20,10 @@ msgstr ""
msgid "Newest posts on the forum."
msgstr "Najnowsze posty na forum."
+#: models.py:96
+msgid "topics"
+msgstr "tematy"
+
#: templates/phpbb/forum_detail.html:31
msgid "answers"
msgstr "odpowiedzi"
diff --git a/phpbb/models.py b/phpbb/models.py
index ad0be30..490ca74 100644
--- a/phpbb/models.py
+++ b/phpbb/models.py
@@ -23,6 +23,7 @@
from datetime import datetime
from django.core import exceptions
from django.utils.encoding import force_unicode
+from django.utils.translation import gettext_lazy as _
class PhpbbUser(models.Model):
user_id = models.IntegerField(primary_key=True)
@@ -91,7 +92,10 @@ def topic_last_post_time(self):
def __unicode__(self):
return self.get_title()
def get_absolute_url(self):
- return "/forum/topics/%s/%s/" % (self.topic_id, self.get_slug())
+ return "/forum/%s/%s/%s/" % (
+ _("topics"),
+ self.topic_id,
+ self.get_slug())
def get_slug(self):
return slugify(self.get_title())
def topic_time(self):
diff --git a/phpbb/urls.py b/phpbb/urls.py
index 3daf2ce..e382871 100644
--- a/phpbb/urls.py
+++ b/phpbb/urls.py
@@ -18,6 +18,7 @@
# Boston, MA 02110-1301 USA
from django.conf.urls.defaults import *
+from django.utils.translation import gettext_lazy as _
import views
import models
@@ -30,10 +31,10 @@
urlpatterns = patterns('',
(r'^$', 'django.views.generic.list_detail.object_list',
{'queryset': forumqs, }),
- (r'^topics/(?P[0-9]+)/(?P[\w-]*)/page(?P[0-9]+)/$',
- 'django.contrib.phpbb.views.topic', ),
- (r'^topics/(?P[0-9]+)/(?P[\w-]*)/$',
- 'django.contrib.phpbb.views.topic', ),
+ (r'^%s/(?P[0-9]+)/(?P[\w-]*)/page(?P[0-9]+)/$' % (
+ _("topics"),), 'django.contrib.phpbb.views.topic', ),
+ (r'^%s/(?P[0-9]+)/(?P[\w-]*)/$' % (
+ _("topics"),), 'django.contrib.phpbb.views.topic', ),
(r'^(?P[0-9]+)/(?P[\w-]*)/$',
'django.contrib.phpbb.views.forum_index', ),
(r'^(?P[0-9]+)/(?P[\w-]*)/page(?P[0-9]+)/$',
From c243b9e7bd30f179d980455e0ee74b7122a42e8c Mon Sep 17 00:00:00 2001
From: "maciej.blizinski"
Date: Tue, 9 Dec 2008 07:57:47 +0000
Subject: [PATCH 21/60] - Updated sitemaps - Started working on better views
(templatetags) - Added phpbb_config to models
git-svn-id: https://django-phpbb.googlecode.com/svn/trunk@23 2cc4e26e-97ec-11dd-87e9-a30ea5446288
---
phpbb/models.py | 26 +++++++++++++++++-----
phpbb/sitemap.py | 10 ++++++---
phpbb/templates/phpbb/index.html | 5 ++++-
phpbb/templates/phpbb/phpbbforum_list.html | 2 +-
phpbb/templates/phpbb/unanswered.html | 5 +++--
phpbb/templatetags/phpbb.py | 9 ++++++++
phpbb/urls.py | 6 ++++-
phpbb/views.py | 20 ++++++++++++-----
8 files changed, 63 insertions(+), 20 deletions(-)
diff --git a/phpbb/models.py b/phpbb/models.py
index 490ca74..ce6513b 100644
--- a/phpbb/models.py
+++ b/phpbb/models.py
@@ -18,6 +18,7 @@
# Boston, MA 02110-1301 USA
from django.db import models
+from django.utils.translation import gettext_lazy as _
from django.contrib.auth.models import User
from django.contrib.phpbb.utils import slugify
from datetime import datetime
@@ -60,11 +61,18 @@ class PhpbbForum(models.Model):
forum_name = models.CharField(max_length=60)
forum_topics = models.IntegerField()
forum_posts = models.IntegerField()
- forum_last_post = models.ForeignKey(
- 'PhpbbPost', db_column='forum_last_post_id')
+ forum_last_post = models.OneToOneField(
+ 'PhpbbPost',
+ db_column='forum_last_post_id',
+ related_name="last_post_of_forum")
forum_desc = models.TextField()
+ parent = models.ForeignKey('self', related_name="child")
+ left = models.OneToOneField('self', related_name="right_of")
+ right = models.OneToOneField('self', related_name="left_of")
def __unicode__(self):
return force_unicode(self.forum_name)
+ def __str__(self):
+ return str(self.forum_name)
def get_absolute_url(self):
return u"/forum/%s/%s/" % (self.forum_id, self.get_slug())
def get_slug(self):
@@ -81,8 +89,12 @@ class PhpbbTopic(models.Model):
topic_poster = models.ForeignKey(PhpbbUser, db_column='topic_poster')
topic_time_int = models.IntegerField(db_column='topic_time')
forum = models.ForeignKey(PhpbbForum)
- topic_last_post = models.ForeignKey('PhpbbPost', related_name='last_in')
- topic_first_post = models.ForeignKey('PhpbbPost', related_name='first_in')
+ topic_last_post = models.OneToOneField(
+ 'PhpbbPost',
+ related_name='last_post_of_topic')
+ topic_first_post = models.OneToOneField(
+ 'PhpbbPost',
+ related_name='first_post_of_topic')
topic_last_post_time_int = models.IntegerField(
db_column='topic_last_post_time')
def get_title(self):
@@ -111,6 +123,7 @@ class PhpbbPost(models.Model):
post_id = models.IntegerField(primary_key=True)
# post_title = models.CharField(max_length = 60)
topic = models.ForeignKey(PhpbbTopic)
+ forum = models.ForeignKey(PhpbbForum)
poster = models.ForeignKey(PhpbbUser)
post_time_int = models.IntegerField(db_column='post_time')
post_text = models.TextField()
@@ -124,8 +137,9 @@ def get_external_url(self):
return ("http://www.atopowe-zapalenie.pl/forum/viewtopic.php?p=%s#p%s"
% (self.post_id, self.post_id))
def get_absolute_url(self):
- return (u"/forum/topics/%s/%s/page%d/" %
- (self.topic.topic_id,
+ return (u"/forum/%s/%s/%s/page%d/" %
+ (_("topics"),
+ self.topic.topic_id,
self.topic.get_slug(),
self.get_page()))
def get_page(self):
diff --git a/phpbb/sitemap.py b/phpbb/sitemap.py
index 51e0105..18a041f 100644
--- a/phpbb/sitemap.py
+++ b/phpbb/sitemap.py
@@ -28,12 +28,16 @@ def items(self):
return forumqs
class PhpbbTopicSitemap(sitemaps.Sitemap):
- changefreq = "monthly"
+ changefreq = "weekly"
priority = 0.4
+ limit = 500
def items(self):
- return PhpbbTopic.objects.exclude(forum__forum_id=15).exclude(forum__forum_id=6)
+ return (PhpbbTopic.
+ objects.
+ exclude(forum__forum_id=15).
+ exclude(forum__forum_id=6))
def lastmod(self, obj):
try:
- return obj.topic_last_post.get_time()
+ return obj.topic_last_post.post_time()
except PhpbbPost.DoesNotExist:
return None
diff --git a/phpbb/templates/phpbb/index.html b/phpbb/templates/phpbb/index.html
index f807ee7..96cbd0c 100644
--- a/phpbb/templates/phpbb/index.html
+++ b/phpbb/templates/phpbb/index.html
@@ -4,8 +4,11 @@
{% endcomment %}
{% load phpbb %}
{% load i18n %}
+{% block sitetitle %}
+{{ sitename }}
+{% endblock %}
{% block subtitle %}
-{% trans "Discussion forum" %}
+{{ site_desc }}
{% endblock %}
{% block sidebar %}
diff --git a/phpbb/templates/phpbb/phpbbforum_list.html b/phpbb/templates/phpbb/phpbbforum_list.html
index 267c469..2bfa739 100644
--- a/phpbb/templates/phpbb/phpbbforum_list.html
+++ b/phpbb/templates/phpbb/phpbbforum_list.html
@@ -20,7 +20,7 @@
-
{{ object }}
- {{ object.get_desc }}
+ {{ object.forum_desc }}
{% endfor %}
{% endblock %}
diff --git a/phpbb/templates/phpbb/unanswered.html b/phpbb/templates/phpbb/unanswered.html
index 61a031a..fdc7f21 100644
--- a/phpbb/templates/phpbb/unanswered.html
+++ b/phpbb/templates/phpbb/unanswered.html
@@ -1,5 +1,6 @@
{% extends "phpbb/forum_detail.html" %}
{% block content %}
+{% load i18n %}
{% load phpbb %}
{% for topic in topics %}
@@ -7,9 +8,9 @@
{{ topic.get_title }}
({{ topic.topic_first_post.poster }})
-{{ topic.topic_first_post.forumposttext.get_post_text|bbcode }}
+{{ topic.topic_first_post.post_text|bbcode }}
-odpowiedz
+{% trans "answer" %}
{% endfor %}
diff --git a/phpbb/templatetags/phpbb.py b/phpbb/templatetags/phpbb.py
index 8f111d8..5d9b6e2 100644
--- a/phpbb/templatetags/phpbb.py
+++ b/phpbb/templatetags/phpbb.py
@@ -67,3 +67,12 @@ def withlink(obj):
register.filter('bbcode', bbcode)
register.filter('withlink', withlink)
+
+class BaseForumNode(template.Node):
+ pass
+
+def forum_list(parser, token):
+ """Gets list of forums."""
+ pass
+
+register.tag(forum_list)
diff --git a/phpbb/urls.py b/phpbb/urls.py
index e382871..cbeeff2 100644
--- a/phpbb/urls.py
+++ b/phpbb/urls.py
@@ -28,9 +28,13 @@
exclude(forum_id=15).
exclude(forum_id=6))
+forum_context = views.phpbb_config_context(None)
+
urlpatterns = patterns('',
+ # TODO: add context with Django config
(r'^$', 'django.views.generic.list_detail.object_list',
- {'queryset': forumqs, }),
+ {'queryset': forumqs,
+ 'extra_context': forum_context}),
(r'^%s/(?P[0-9]+)/(?P[\w-]*)/page(?P[0-9]+)/$' % (
_("topics"),), 'django.contrib.phpbb.views.topic', ),
(r'^%s/(?P[0-9]+)/(?P[\w-]*)/$' % (
diff --git a/phpbb/views.py b/phpbb/views.py
index 606bbd1..5a4364c 100644
--- a/phpbb/views.py
+++ b/phpbb/views.py
@@ -17,13 +17,20 @@
# Foundation, Inc., 51 Franklin St, Fifth Floor,
# Boston, MA 02110-1301 USA
-from models import PhpbbForum, PhpbbTopic, PhpbbPost
+from models import PhpbbForum, PhpbbTopic, PhpbbPost, PhpbbConfig
from django.http import HttpResponseRedirect, Http404
from django.template.context import RequestContext
from django.shortcuts import get_object_or_404, render_to_response
from django.core.paginator import Paginator, InvalidPage
from django.core import exceptions
+def phpbb_config_context(request):
+ sitename = PhpbbConfig.objects.get(pk='sitename')
+ site_desc = PhpbbConfig.objects.get(pk='site_desc')
+ return {
+ 'sitename': sitename.config_value,
+ 'site_desc': site_desc.config_value,
+ }
def forum_index(request, forum_id, slug, page_no = None, paginate_by = 10):
if page_no:
@@ -67,11 +74,11 @@ def forum_index(request, forum_id, slug, page_no = None, paginate_by = 10):
'pages': paginator.num_pages,
'hits' : 'what hits?',
'page_list': range(1, paginator.num_pages + 1),
- })
+ }, [phpbb_config_context])
return render_to_response("phpbb/forum_detail.html", {
'object': f,
'topics': page.object_list,
- }, context_instance = c)
+ }, context_instance=c)
def topic(request, topic_id, slug, page_no = None, paginate_by = 10):
@@ -114,19 +121,20 @@ def topic(request, topic_id, slug, page_no = None, paginate_by = 10):
'pages': paginator.num_pages,
'hits' : "hits? what hits?",
'page_list': range(1, paginator.num_pages + 1),
- })
+ }, [phpbb_config_context])
return render_to_response("phpbb/topic_detail.html", {
'object': t,
'posts': page.object_list,
- }, context_instance = c)
+ }, context_instance=c)
def unanswered(request):
topics = PhpbbTopic.objects.filter(topic_replies = 0)
+ c = RequestContext(request, {}, [phpbb_config_context])
return render_to_response(
"phpbb/unanswered.html",
{'topics': topics,},
- context_instance = RequestContext(request))
+ context_instance=c)
def handle_viewtopic(request):
From 5cdff45d4fd55b7f44977f1e29c0364dae26111f Mon Sep 17 00:00:00 2001
From: "maciej.blizinski"
Date: Tue, 16 Dec 2008 07:28:43 +0000
Subject: [PATCH 22/60] Removing 'changefreq' and 'priority' from sitemap.
git-svn-id: https://django-phpbb.googlecode.com/svn/trunk@24 2cc4e26e-97ec-11dd-87e9-a30ea5446288
---
phpbb/sitemap.py | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)
diff --git a/phpbb/sitemap.py b/phpbb/sitemap.py
index 18a041f..e3e0ae1 100644
--- a/phpbb/sitemap.py
+++ b/phpbb/sitemap.py
@@ -17,19 +17,24 @@
# Foundation, Inc., 51 Franklin St, Fifth Floor,
# Boston, MA 02110-1301 USA
+# TODO: Implement sitemap caching.
+
from django.contrib import sitemaps
from models import PhpbbTopic, PhpbbPost, PhpbbForum
from urls import forumqs
class PhpbbForumSitemap(sitemaps.Sitemap):
- changefreq = "monthly"
- priority = 0.4
def items(self):
return forumqs
+ def lastmod(self, obj):
+ try:
+ return obj.forum_last_post.post_time()
+ except PhpbbPost.DoesNotExist:
+ return None
class PhpbbTopicSitemap(sitemaps.Sitemap):
- changefreq = "weekly"
- priority = 0.4
+ # Default limit value is too high; requests retrieving thousands of posts
+ # take a long time to execute.
limit = 500
def items(self):
return (PhpbbTopic.
From 0301a925ba60f9969492f98c98088b2a9abf3acb Mon Sep 17 00:00:00 2001
From: "maciej.blizinski"
Date: Tue, 16 Dec 2008 07:42:22 +0000
Subject: [PATCH 23/60] - Added translation for unanswered topics - Grouped
forum display (but still no support for left_id and right_id)
git-svn-id: https://django-phpbb.googlecode.com/svn/trunk@25 2cc4e26e-97ec-11dd-87e9-a30ea5446288
---
phpbb/locale/pl/LC_MESSAGES/django.mo | Bin 836 -> 867 bytes
phpbb/locale/pl/LC_MESSAGES/django.po | 21 ++++++++++++++-------
phpbb/models.py | 1 +
phpbb/templates/phpbb/phpbbforum_list.html | 16 ++++++++++++----
phpbb/urls.py | 7 +++----
5 files changed, 30 insertions(+), 15 deletions(-)
diff --git a/phpbb/locale/pl/LC_MESSAGES/django.mo b/phpbb/locale/pl/LC_MESSAGES/django.mo
index b9f0f662c6dba75145f09fca1dba82ce08276e77..b6f2558ac3166d1b91d339b7df0b4b8533430c77 100644
GIT binary patch
delta 349
zcmX@Y_L!~yo)F7a1|Z-8Vi_Q=0b)TQz5~P{puh;>D*|a&Am12Ba{_5gAT0%?ouTq^
zK$;oIF96bPK)M7-vjgdBAk6}#o1x+zK$;84?+4PRj6mirAVUHuaA9Jnbgl@HAqg}F
zq(cu#gKRPe(jXnSP;n0+4YI)(Nb>>d5FiaS1MCAJ1-6wN!~g=2IUqAY0OWcQ0GS2S
z&oP;iQE9RXqq{sqVqS51YEdymPGWHhLrH!?W^yq@X&yv0HDz)KV>pMQnSz12m9gdI
s=ZxPbzhly756CYrsZ>asEX6D{S%+DIKPk0JH$SByzdSQFr7DvF0F9R}RR910
delta 322
zcmaFNc7(0|o)F7a1|Z-DVi_PV0b)TQJ_E!cAixOW3j%2YAYU0svjS-oAk7J+t$?%?
zkahvmAbs&bni)tJ0%>+2T?(XGfOIX8W&_eqK-v_DJAqh&fq{!*KNG~@8xuRFWBGt8
zB!SvNIy8VZ7m(J4@-2Wg$OKy;4b%(=96%Px^&mNr%RsII0gxFW05SvQ5{Aiwj7kD7
znZ?Pa#l@NVc?xOyMWwlujTk+6iy3kfi%S?v@(VJPizm-y4CgQ~RWPu$GBKb0gYg@;
eLP}+Ec4={CR$l7l7fgnXPLmawWhT2Z^8o\n"
"Language-Team: LANGUAGE \n"
@@ -20,10 +20,14 @@ msgstr ""
msgid "Newest posts on the forum."
msgstr "Najnowsze posty na forum."
-#: models.py:96
+#: models.py:109 models.py:142 urls.py:38 urls.py:40
msgid "topics"
msgstr "tematy"
+#: urls.py:47 templates/phpbb/phpbbforum_list.html:16
+msgid "unanswered"
+msgstr "bez-odpowiedzi"
+
#: templates/phpbb/forum_detail.html:31
msgid "answers"
msgstr "odpowiedzi"
@@ -36,10 +40,6 @@ msgstr "ost."
msgid "ago"
msgstr "temu"
-#: templates/phpbb/index.html:8
-msgid "Discussion forum"
-msgstr "Forum dyskusyjne"
-
#: templates/phpbb/phpbbforum_list.html:7
msgid "Forum"
msgstr "Forum"
@@ -54,4 +54,11 @@ msgstr "Strona Główna"
#: templates/phpbb/phpbbforum_list.html:16
msgid "Unanswered topics"
-msgstr "Bez odpowiedzi"
+msgstr "Posty bez odpowiedzi"
+
+#: templates/phpbb/unanswered.html:13
+msgid "answer"
+msgstr "odpowiedz"
+
+#~ msgid "Discussion forum"
+#~ msgstr "Forum dyskusyjne"
diff --git a/phpbb/models.py b/phpbb/models.py
index ce6513b..e7186d2 100644
--- a/phpbb/models.py
+++ b/phpbb/models.py
@@ -27,6 +27,7 @@
from django.utils.translation import gettext_lazy as _
class PhpbbUser(models.Model):
+ """Model for phpBB user."""
user_id = models.IntegerField(primary_key=True)
username = models.CharField(max_length=25)
user_password = models.CharField(max_length=32)
diff --git a/phpbb/templates/phpbb/phpbbforum_list.html b/phpbb/templates/phpbb/phpbbforum_list.html
index 2bfa739..cd4e8be 100644
--- a/phpbb/templates/phpbb/phpbbforum_list.html
+++ b/phpbb/templates/phpbb/phpbbforum_list.html
@@ -13,14 +13,22 @@
Nie można tutaj pisać nowych postów.
Jeżeli chcesz pisać, zapraszamy
tutaj.
-{% trans "Unanswered topics" %}
+{% trans "Unanswered topics" %}
{% for object in object_list %}
-
- {{ object }}
-
- {{ object.forum_desc }}
+ {{ object }}
+
+ {% for forum in object.child.all %}
+
+ {{ forum }}
+
+
+ {{ forum.forum_desc }}
+ {% endfor %}
+
+
{% endfor %}
{% endblock %}
diff --git a/phpbb/urls.py b/phpbb/urls.py
index cbeeff2..8c590cf 100644
--- a/phpbb/urls.py
+++ b/phpbb/urls.py
@@ -22,11 +22,10 @@
import views
import models
-forumqs = (models.PhpbbForum.objects.exclude(forum_name='INDEX PAGE').
- exclude(forum_name='MEMBERLIST').
+forumqs = (models.PhpbbForum.objects.
# FIXME: hardcoded forum IDs
exclude(forum_id=15).
- exclude(forum_id=6))
+ exclude(forum_id=6).filter(parent__forum_id=0))
forum_context = views.phpbb_config_context(None)
@@ -45,6 +44,6 @@
'django.contrib.phpbb.views.forum_index', ),
(r'^(?P[0-9]+)/$',
'django.contrib.phpbb.views.forum_index', {'slug': ''}),
- (r'^unanswered/$', 'django.contrib.phpbb.views.unanswered', ),
+ (r'^%s/$' % (_("unanswered"),), 'django.contrib.phpbb.views.unanswered', ),
(r'^viewtopic.php$', 'django.contrib.phpbb.views.handle_viewtopic', ),
)
From aa0cc0bef89c04d32b86c586c72366eeb8375533 Mon Sep 17 00:00:00 2001
From: "maciej.blizinski"
Date: Fri, 26 Dec 2008 14:13:16 +0000
Subject: [PATCH 24/60] Added a random tool to fix MySQL encoding.
git-svn-id: https://django-phpbb.googlecode.com/svn/trunk@26 2cc4e26e-97ec-11dd-87e9-a30ea5446288
---
phpbb/tools/mysql_repair_encoding.py | 111 +++++++++++++++++++++++++++
1 file changed, 111 insertions(+)
create mode 100755 phpbb/tools/mysql_repair_encoding.py
diff --git a/phpbb/tools/mysql_repair_encoding.py b/phpbb/tools/mysql_repair_encoding.py
new file mode 100755
index 0000000..b0d376d
--- /dev/null
+++ b/phpbb/tools/mysql_repair_encoding.py
@@ -0,0 +1,111 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+# mysql_repair_encoding.py 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.
+
+# django-phpbb 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 django-phpbb; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor,
+# Boston, MA 02110-1301 USA
+
+"""mysql_repair_encoding.py - Fixes utf-8 represented as latin1 in MySQL."""
+
+__author__ = "Maciej Bliziński"
+__version__ = "1.0.0"
+
+import MySQLdb
+import optparse
+import getpass
+
+class EncodingFixer(object):
+ """Returns SQL code to fix encodings."""
+ GET_TABLES_SQL = """
+SELECT
+ table_name,
+ column_name,
+ column_type,
+ character_set_name
+FROM
+ columns
+WHERE
+ table_schema = %s
+ AND
+ (
+ data_type = 'varchar'
+ OR
+ data_type = 'text'
+ )
+ AND
+ character_set_name != 'utf8'
+;
+"""
+
+ def __init__(self, db_name, mysql_user, mysql_passwd=None):
+ self.db_name = db_name
+ if mysql_passwd:
+ passwd = getpass.getpass("Password of MySQL %s user: " % mysql_user)
+ self.conn = MySQLdb.connect(db='information_schema',
+ user=mysql_user,
+ passwd=passwd)
+ else:
+ self.conn = MySQLdb.connect(db='information_schema',
+ user=mysql_user)
+
+ def get_sql_statements(self):
+ """Returns a list of SQL statements."""
+ sql_list = []
+ c = self.conn.cursor()
+ c.execute(self.GET_TABLES_SQL, (self.db_name,))
+ if not c.rowcount:
+ sql_list.append("-- No non-utf-8 columns found.")
+ return sql_list
+ sql_list.append("-- Got %s rows." % c.rowcount)
+ row = c.fetchone()
+ while row:
+ table_name, column_name, column_type, character_set_name = row
+ sql_list.append(("ALTER TABLE %s MODIFY COLUMN %s %s "
+ "CHARACTER SET utf8 COLLATE utf8_bin;"
+ ) % (table_name, column_name, column_type))
+ sql_list.append("UPDATE %s SET %s = CONVERT(CONVERT(CONVERT("
+ "%s USING %s) USING binary) USING utf8);"
+ % (table_name, column_name, column_name, character_set_name))
+ row = c.fetchone()
+ return sql_list
+
+ def get_sql(self):
+ return "\n".join(self.get_sql_statements())
+
+
+def main():
+ parser = optparse.OptionParser()
+ parser.add_option("-d", "--database",
+ dest="database",
+ help="MySQL database name")
+ parser.add_option("-u", "--user", dest="user")
+ parser.add_option("-p", "--password",
+ dest="passwd",
+ default=None,
+ action="store_true",
+ help="Use password")
+ (options, args) = parser.parse_args()
+ if not options.database:
+ raise Exception("Please provide a database name. Use --help.")
+ if not options.user:
+ raise Exception("Please provide a user name. Use --help.")
+ f = EncodingFixer(
+ db_name=options.database,
+ mysql_user=options.user,
+ mysql_passwd=options.passwd)
+ print f.get_sql()
+
+
+if __name__ == "__main__":
+ main()
From 4d99b8ca0f0e16b3f2accf96f43e190550abc6f7 Mon Sep 17 00:00:00 2001
From: "maciej.blizinski"
Date: Thu, 26 Feb 2009 10:10:58 +0000
Subject: [PATCH 25/60] Removed some Polish from forum templates.
git-svn-id: https://django-phpbb.googlecode.com/svn/trunk@32 2cc4e26e-97ec-11dd-87e9-a30ea5446288
---
phpbb/templates/phpbb/forum_detail.html | 2 +-
phpbb/templates/phpbb/index.html | 2 +-
phpbb/templates/phpbb/topic_detail.html | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/phpbb/templates/phpbb/forum_detail.html b/phpbb/templates/phpbb/forum_detail.html
index 438051d..6751197 100644
--- a/phpbb/templates/phpbb/forum_detail.html
+++ b/phpbb/templates/phpbb/forum_detail.html
@@ -11,7 +11,7 @@
{% block content %}
{% block forum_detail %}
{{ object }}
-Forum Atopowe Zapalenie Skóry Strona Główna
+{% trans "Forum main page" %}
→
{{ object }}
{% endblock %}
diff --git a/phpbb/templates/phpbb/index.html b/phpbb/templates/phpbb/index.html
index 96cbd0c..af94e86 100644
--- a/phpbb/templates/phpbb/index.html
+++ b/phpbb/templates/phpbb/index.html
@@ -13,7 +13,7 @@
{% block sidebar %}
{% if last_forum_posts %}
- Obecnie na forum
+ {% trans "Who is online" %}
{{ post.poster.get_username }}: + {{ post.forumposttext.get_post_text|bbcode|removetags:"br"|truncatewords:"19" }} »