Skip to content
Browse files

initial checkin

  • Loading branch information...
0 parents commit 4778b17e939e119417cc5ec25b82c4e9a65621b2 @KeyserSosa KeyserSosa committed
Showing with 13,638 additions and 0 deletions.
  1. +25 −0 .gitignore
  2. +507 −0 LICENSE
  3. +453 −0 config/solr/schema.xml
  4. +387 −0 config/solr/server.xml
  5. +464 −0 config/solr/solrconfig.xml
  6. +36 −0 r2/babel.cfg
  7. +4 −0 r2/check_procs.sh
  8. +71 −0 r2/compress_js.sh
  9. +100 −0 r2/example.ini
  10. +15 −0 r2/ez_setup/README.txt
  11. +249 −0 r2/ez_setup/__init__.py
  12. +26 −0 r2/r2/__init__.py
  13. +96 −0 r2/r2/commands.py
  14. +28 −0 r2/r2/config/__init__.py
  15. +30 −0 r2/r2/config/admin_routes.py
  16. +84 −0 r2/r2/config/databases.py
  17. +77 −0 r2/r2/config/environment.py
  18. +375 −0 r2/r2/config/middleware.py
  19. +34 −0 r2/r2/config/rewrites.py
  20. +139 −0 r2/r2/config/routing.py
  21. +45 −0 r2/r2/config/templates.py
  22. +226 −0 r2/r2/config/utils.py
  23. +52 −0 r2/r2/controllers/__init__.py
  24. +33 −0 r2/r2/controllers/admin.py
  25. +977 −0 r2/r2/controllers/api.py
  26. +113 −0 r2/r2/controllers/buttons.py
  27. +33 −0 r2/r2/controllers/captcha.py
  28. +59 −0 r2/r2/controllers/embed.py
  29. +152 −0 r2/r2/controllers/error.py
  30. +101 −0 r2/r2/controllers/errors.py
  31. +54 −0 r2/r2/controllers/feedback.py
  32. +517 −0 r2/r2/controllers/front.py
  33. +175 −0 r2/r2/controllers/i18n.py
  34. +485 −0 r2/r2/controllers/listingcontroller.py
  35. +120 −0 r2/r2/controllers/post.py
  36. +444 −0 r2/r2/controllers/reddit_base.py
  37. +27 −0 r2/r2/controllers/redirect.py
  38. +49 −0 r2/r2/controllers/template.py
  39. +50 −0 r2/r2/controllers/toolbar.py
  40. +630 −0 r2/r2/controllers/validator.py
  41. +28 −0 r2/r2/controllers/validator/__init__.py
  42. +639 −0 r2/r2/controllers/validator/validator.py
  43. +11 −0 r2/r2/docs/index.txt
  44. +21 −0 r2/r2/i18n/__init__.py
  45. +41 −0 r2/r2/i18n/en/LC_MESSAGES/r2.data
  46. BIN r2/r2/i18n/en/LC_MESSAGES/r2.mo
  47. +2,005 −0 r2/r2/i18n/en/LC_MESSAGES/r2.po
  48. +1,873 −0 r2/r2/i18n/r2.pot
  49. +21 −0 r2/r2/lib/__init__.py
  50. +154 −0 r2/r2/lib/app_globals.py
  51. +134 −0 r2/r2/lib/base.py
  52. +358 −0 r2/r2/lib/c/filters.c
  53. +70 −0 r2/r2/lib/c/recommendations/Database.cpp
  54. +49 −0 r2/r2/lib/c/recommendations/Database.h
  55. +45 −0 r2/r2/lib/c/recommendations/Dictionary.h
  56. +69 −0 r2/r2/lib/c/recommendations/Makefile.bsd
  57. +67 −0 r2/r2/lib/c/recommendations/Makefile.darwin
  58. +70 −0 r2/r2/lib/c/recommendations/Makefile.linux
  59. +280 −0 r2/r2/lib/c/recommendations/ModsTable.cpp
  60. +161 −0 r2/r2/lib/c/recommendations/ModsTable.h
Sorry, we could not display the entire diff because too many files (391) changed.
25 .gitignore
@@ -0,0 +1,25 @@
+*.pyc
+*.pyo
+*~
+*.html.py
+*.so
+*.o
+*.orig
+*.tmp
+*.md5
+*.*.py
+.\#*
+\#*.*\#
+.hg
+.hgignore
+development.ini
+production.ini
+r2/r2/public/static/frame.js
+r2/r2/public/static/reddit.js
+r2/r2/public/static/vote.js
+r2/r2/public/static/reddit_rtl.css
+r2/data/*
+r2/count.pickle
+r2/myproduction.ini
+.DS_Store
+r2/r2.egg-info/**
507 LICENSE
@@ -0,0 +1,507 @@
+CondeNet, Inc. - Reddit
+
+Common Public Attribution License Version 1.0 (CPAL)
+
+1. "Definitions"
+
+1.0.1 "Commercial Use" means distribution or otherwise making the Covered Code
+ available to a third party.
+
+1.1 "Contributor" means each entity that creates or contributes to the creation
+ of Modifications.
+
+1.2 "Contributor Version" means the combination of the Original Code, prior
+ Modifications used by a Contributor, and the Modifications made by that
+ particular Contributor.
+
+1.3 "Covered Code" means the Original Code or Modifications or the combination
+ of the Original Code and Modifications, in each case including portions
+ thereof.
+
+1.4 "Electronic Distribution Mechanism" means a mechanism generally accepted in
+ the software development community for the electronic transfer of data.
+
+1.5 "Executable" means Covered Code in any form other than Source Code.
+
+1.6 "Initial Developer" means the individual or entity identified as the Initial
+ Developer in the Source Code notice required by Exhibit A.
+
+1.7 "Larger Work" means a work which combines Covered Code or portions thereof
+ with code not governed by the terms of this License.
+
+1.8 "License" means this document.
+
+1.8.1 "Licensable" means having the right to grant, to the maximum extent
+ possible, whether at the time of the initial grant or subsequently acquired,
+ any and all of the rights conveyed herein.
+
+1.9 "Modifications" means any addition to or deletion from the substance or
+ structure of either the Original Code or any previous Modifications. When
+ Covered Code is released as a series of files, a Modification is:
+
+A. Any addition to or deletion from the contents of a file containing Original
+Code or previous Modifications.
+
+B. Any new file that contains any part of the Original Code or previous
+Modifications.
+
+1.10 "Original Code" means Source Code of computer software code which is
+ described in the Source Code notice required by Exhibit A as Original Code,
+ and which, at the time of its release under this License is not already
+ Covered Code governed by this License.
+
+1.10.1 "Patent Claims" means any patent claim(s), now owned or hereafter
+ acquired, including without limitation, method, process, and apparatus
+ claims, in any patent Licensable by grantor.
+
+1.11 "Source Code" means the preferred form of the Covered Code for making
+ modifications to it, including all modules it contains, plus any associated
+ interface definition files, scripts used to control compilation and
+ installation of an Executable, or source code differential comparisons against
+ either the Original Code or another well known, available Covered Code of the
+ Contributor's choice. The Source Code can be in a compressed or archival form,
+ provided the appropriate decompression or de-archiving software is widely
+ available for no charge.
+
+1.12 "You" (or "Your") means an individual or a legal entity exercising rights
+ under, and complying with all of the terms of, this License or a future
+ version of this License issued under Section 6.1. For legal entities, "You"
+ includes any entity which controls, is controlled by, or is under common
+ control with You. For purposes of this definition, "control" means (a) the
+ power, direct or indirect, to cause the direction or management of such
+ entity, whether by contract or otherwise, or (b) ownership of more than fifty
+ percent (50%) of the outstanding shares or beneficial ownership of such
+ entity.
+
+2. Source Code License.
+
+2.1 The Initial Developer Grant.
+
+The Initial Developer hereby grants You a world-wide, royalty-free,
+non-exclusive license, subject to third party intellectual property claims:
+
+(a) under intellectual property rights (other than patent or trademark)
+Licensable by Initial Developer to use, reproduce, modify, display, perform,
+sublicense and distribute the Original Code (or portions thereof) with or
+without Modifications, and/or as part of a Larger Work; and
+
+(b) under Patents Claims infringed by the making, using or selling of Original
+Code, to make, have made, use, practice, sell, and offer for sale, and/or
+otherwise dispose of the Original Code (or portions thereof).
+
+(c) the licenses granted in this Section 2.1(a) and (b) are effective on the
+date Initial Developer first distributes Original Code under the terms of this
+License.
+
+(d) Notwithstanding Section 2.1(b) above, no patent license is granted: 1) for
+code that You delete from the Original Code; 2) separate from the Original Code;
+or 3) for infringements caused by: i) the modification of the Original Code or
+ii) the combination of the Original Code with other software or devices.
+
+2.2 Contributor Grant.
+
+Subject to third party intellectual property claims, each Contributor hereby
+grants You a world-wide, royalty-free, non-exclusive license
+
+(a) under intellectual property rights (other than patent or trademark)
+Licensable by Contributor, to use, reproduce, modify, display, perform,
+sublicense and distribute the Modifications created by such Contributor (or
+portions thereof) either on an unmodified basis, with other Modifications, as
+Covered Code and/or as part of a Larger Work; and
+
+(b) under Patent Claims infringed by the making, using, or selling of
+Modifications made by that Contributor either alone and/or in combination with
+its Contributor Version (or portions of such combination), to make, use, sell,
+offer for sale, have made, and/or otherwise dispose of: 1) Modifications made by
+that Contributor (or portions thereof); and 2) the combination of Modifications
+made by that Contributor with its Contributor Version (or portions of such
+combination).
+
+(c) the licenses granted in Sections 2.2(a) and 2.2(b) are effective on the date
+Contributor first makes Commercial Use of the Covered Code.
+
+(d) Notwithstanding Section 2.2(b) above, no patent license is granted: 1) for
+any code that Contributor has deleted from the Contributor Version; 2) separate
+from the Contributor Version; 3) for infringements caused by: i) third party
+modifications of Contributor Version or ii) the combination of Modifications
+made by that Contributor with other software (except as part of the Contributor
+Version) or other devices; or 4) under Patent Claims infringed by Covered Code
+in the absence of Modifications made by that Contributor.
+
+3. Distribution Obligations.
+
+3.1 Application of License.
+
+The Modifications which You create or to which You contribute are governed by
+the terms of this License, including without limitation Section 2.2. The Source
+Code version of Covered Code may be distributed only under the terms of this
+License or a future version of this License released under Section 6.1, and You
+must include a copy of this License with every copy of the Source Code You
+distribute. You may not offer or impose any terms on any Source Code version
+that alters or restricts the applicable version of this License or the
+recipients' rights hereunder. However, You may include an additional document
+offering the additional rights described in Section 3.5.
+
+3.2 Availability of Source Code.
+
+Any Modification which You create or to which You contribute must be made
+available in Source Code form under the terms of this License either on the same
+media as an Executable version or via an accepted Electronic Distribution
+Mechanism to anyone to whom you made an Executable version available; and if
+made available via Electronic Distribution Mechanism, must remain available for
+at least twelve (12) months after the date it initially became available, or at
+least six (6) months after a subsequent version of that particular Modification
+has been made available to such recipients. You are responsible for ensuring
+that the Source Code version remains available even if the Electronic
+Distribution Mechanism is maintained by a third party.
+
+3.3 Description of Modifications.
+
+You must cause all Covered Code to which You contribute to contain a file
+documenting the changes You made to create that Covered Code and the date of any
+change. You must include a prominent statement that the Modification is derived,
+directly or indirectly, from Original Code provided by the Initial Developer and
+including the name of the Initial Developer in (a) the Source Code, and (b) in
+any notice in an Executable version or related documentation in which You
+describe the origin or ownership of the Covered Code.
+
+3.4 Intellectual Property Matters
+
+(a) Third Party Claims.
+
+If Contributor has knowledge that a license under a third party's intellectual
+property rights is required to exercise the rights granted by such Contributor
+under Sections 2.1 or 2.2, Contributor must include a text file with the Source
+Code distribution titled "LEGAL" which describes the claim and the party making
+the claim in sufficient detail that a recipient will know whom to contact. If
+Contributor obtains such knowledge after the Modification is made available as
+described in Section 3.2, Contributor shall promptly modify the LEGAL file in
+all copies Contributor makes available thereafter and shall take other steps
+(such as notifying appropriate mailing lists or newsgroups) reasonably
+calculated to inform those who received the Covered Code that new knowledge has
+been obtained.
+
+(b) Contributor APIs.
+
+If Contributor's Modifications include an application programming interface and
+Contributor has knowledge of patent licenses which are reasonably necessary to
+implement that API, Contributor must also include this information in the LEGAL
+file.
+
+(c) Representations.
+
+Contributor represents that, except as disclosed pursuant to Section 3.4(a)
+above, Contributor believes that Contributor's Modifications are Contributor's
+original creation(s) and/or Contributor has sufficient rights to grant the
+rights conveyed by this License.
+
+3.5 Required Notices.
+
+You must duplicate the notice in Exhibit A in each file of the Source Code. If
+it is not possible to put such notice in a particular Source Code file due to
+its structure, then You must include such notice in a location (such as a
+relevant directory) where a user would be likely to look for such a notice. If
+You created one or more Modification(s) You may add your name as a Contributor
+to the notice described in Exhibit A. You must also duplicate this License in
+any documentation for the Source Code where You describe recipients' rights or
+ownership rights relating to Covered Code. You may choose to offer, and to
+charge a fee for, warranty, support, indemnity or liability obligations to one
+or more recipients of Covered Code. However, You may do so only on Your own
+behalf, and not on behalf of the Initial Developer or any Contributor. You must
+make it absolutely clear than any such warranty, support, indemnity or liability
+obligation is offered by You alone, and You hereby agree to indemnify the
+Initial Developer and every Contributor for any liability incurred by the
+Initial Developer or such Contributor as a result of warranty, support,
+indemnity or liability terms You offer.
+
+3.6 Distribution of Executable Versions.
+
+You may distribute Covered Code in Executable form only if the requirements of
+Section 3.1-3.5 have been met for that Covered Code, and if You include a notice
+stating that the Source Code version of the Covered Code is available under the
+terms of this License, including a description of how and where You have
+fulfilled the obligations of Section 3.2. The notice must be conspicuously
+included in any notice in an Executable version, related documentation or
+collateral in which You describe recipients' rights relating to the Covered
+Code. You may distribute the Executable version of Covered Code or ownership
+rights under a license of Your choice, which may contain terms different from
+this License, provided that You are in compliance with the terms of this License
+and that the license for the Executable version does not attempt to limit or
+alter the recipient's rights in the Source Code version from the rights set
+forth in this License. If You distribute the Executable version under a
+different license You must make it absolutely clear that any terms which differ
+from this License are offered by You alone, not by the Initial Developer,
+Original Developer or any Contributor. You hereby agree to indemnify the Initial
+Developer, Original Developer and every Contributor for any liability incurred
+by the Initial Developer, Original Developer or such Contributor as a result of
+any such terms You offer.
+
+3.7 Larger Works.
+
+You may create a Larger Work by combining Covered Code with other code not
+governed by the terms of this License and distribute the Larger Work as a single
+product. In such a case, You must make sure the requirements of this License are
+fulfilled for the Covered Code.
+
+4. Inability to Comply Due to Statute or Regulation.
+
+If it is impossible for You to comply with any of the terms of this License with
+respect to some or all of the Covered Code due to statute, judicial order, or
+regulation then You must: (a) comply with the terms of this License to the
+maximum extent possible; and (b) describe the limitations and the code they
+affect. Such description must be included in the LEGAL file described in Section
+3.4 and must be included with all distributions of the Source Code. Except to
+the extent prohibited by statute or regulation, such description must be
+sufficiently detailed for a recipient of ordinary skill to be able to understand
+it.
+
+5. Application of this License.
+
+This License applies to code to which the Initial Developer has attached the
+notice in Exhibit A and to related Covered Code.
+
+6. Versions of the License.
+
+6.1 New Versions.
+
+CondeNet, Inc. ("CondeNet") may publish revised and/or new versions of the
+License from time to time. Each version will be given a distinguishing version
+number.
+
+6.2 Effect of New Versions.
+
+Once Covered Code has been published under a particular version of the License,
+You may always continue to use it under the terms of that version. You may also
+choose to use such Covered Code under the terms of any subsequent version of the
+License published by CondeNet. No one other than CondeNet has the right to
+modify the terms applicable to Covered Code created under this License.
+
+6.3 Derivative Works.
+
+If You create or use a modified version of this License (which you may only do
+in order to apply it to code which is not already Covered Code governed by this
+License), You must (a) rename Your license so that the phrases "CondeNet",
+"CPAL" or any confusingly similar phrase do not appear in your license (except
+to note that your license differs from this License) and (b) otherwise make it
+clear that Your version of the license contains terms which differ from the
+CPAL. (Filling in the name of the Initial Developer, Original Developer,
+Original Code or Contributor in the notice described in Exhibit A shall not of
+themselves be deemed to be modifications of this License.)
+
+7. DISCLAIMER OF WARRANTY.
+
+COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT
+WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT
+LIMITATION, WARRANTIES THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE,
+FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING. THE ENTIRE RISK AS TO THE
+QUALITY AND PERFORMANCE OF THE COVERED CODE IS WITH YOU. SHOULD ANY COVERED CODE
+PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT THE INITIAL DEVELOPER, ORIGINAL
+DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY SERVICING,
+REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART
+OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER
+THIS DISCLAIMER.
+
+8. TERMINATION.
+
+8.1 This License and the rights granted hereunder will terminate automatically
+ if You fail to comply with terms herein and fail to cure such breach within 30
+ days of becoming aware of the breach. All sublicenses to the Covered Code
+ which are properly granted shall survive any termination of this
+ License. Provisions which, by their nature, must remain in effect beyond the
+ termination of this License shall survive.
+
+8.2 If You initiate litigation by asserting a patent infringement claim
+ (excluding declatory judgment actions) against Initial Developer, Original
+ Developer or a Contributor (the Initial Developer, Original Developer or
+ Contributor against whom You file such action is referred to as "Participant")
+ alleging that:
+
+(a) such Participant's Contributor Version directly or indirectly infringes any
+patent, then any and all rights granted by such Participant to You under
+Sections 2.1 and/or 2.2 of this License shall, upon 60 days notice from
+Participant terminate prospectively, unless if within 60 days after receipt of
+notice You either: (i) agree in writing to pay Participant a mutually agreeable
+reasonable royalty for Your past and future use of Modifications made by such
+Participant, or (ii) withdraw Your litigation claim with respect to the
+Contributor Version against such Participant. If within 60 days of notice, a
+reasonable royalty and payment arrangement are not mutually agreed upon in
+writing by the parties or the litigation claim is not withdrawn, the rights
+granted by Participant to You under Sections 2.1 and/or 2.2 automatically
+terminate at the expiration of the 60 day notice period specified above.
+
+(b) any software, hardware, or device, other than such Participant's Contributor
+Version, directly or indirectly infringes any patent, then any rights granted to
+You by such Participant under Sections 2.1(b) and 2.2(b) are revoked effective
+as of the date You first made, used, sold, distributed, or had made,
+Modifications made by that Participant.
+
+8.3 If You assert a patent infringement claim against Participant alleging that
+ such Participant's Contributor Version directly or indirectly infringes any
+ patent where such claim is resolved (such as by license or settlement) prior
+ to the initiation of patent infringement litigation, then the reasonable value
+ of the licenses granted by such Participant under Sections 2.1 or 2.2 shall be
+ taken into account in determining the amount or value of any payment or
+ license.
+
+8.4 In the event of termination under Sections 8.1 or 8.2 above, all end user
+ license agreements (excluding distributors and resellers) which have been
+ validly granted by You or any distributor hereunder prior to termination shall
+ survive termination.
+
+9. LIMITATION OF LIABILITY.
+
+UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT (INCLUDING
+NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE INITIAL DEVELOPER, ORIGINAL
+DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED CODE, OR ANY
+SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR ANY INDIRECT,
+SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY CHARACTER INCLUDING,
+WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL, WORK STOPPAGE, COMPUTER
+FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER COMMERCIAL DAMAGES OR LOSSES, EVEN
+IF SUCH PARTY SHALL HAVE BEEN INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS
+LIMITATION OF LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL
+INJURY RESULTING FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT APPLICABLE LAW
+PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OR
+LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THIS EXCLUSION AND
+LIMITATION MAY NOT APPLY TO YOU.
+
+10. U.S. GOVERNMENT END USERS.
+
+The Covered Code is a "commercial item," as that term is defined in 48
+C.F.R. 2.101 (Oct. 1995), consisting of "commercial computer software" and
+"commercial computer software documentation," as such terms are used in 48
+C.F.R. 12.212 (Sept. 1995). Consistent with 48 C.F.R. 12.212 and 48
+C.F.R. 227.7202-1 through 227.7202-4 (June 1995), all U.S. Government End Users
+acquire Covered Code with only those rights set forth herein.
+
+11. MISCELLANEOUS.
+
+This License represents the complete agreement concerning subject matter
+hereof. If any provision of this License is held to be unenforceable, such
+provision shall be reformed only to the extent necessary to make it
+enforceable. This License shall be governed by California law provisions (except
+to the extent applicable law, if any, provides otherwise), excluding its
+conflict-of-law provisions. With respect to disputes in which at least one party
+is a citizen of, or an entity chartered or registered to do business in the
+United States of America, any litigation relating to this License shall be
+subject to the jurisdiction of the Federal Courts of the Northern District of
+California, with venue lying in Santa Clara County, California, with the losing
+party responsible for costs, including without limitation, court costs and
+reasonable attorneys' fees and expenses. The application of the United Nations
+Convention on Contracts for the International Sale of Goods is expressly
+excluded. Any law or regulation which provides that the language of a contract
+shall be construed against the drafter shall not apply to this License.
+
+12. RESPONSIBILITY FOR CLAIMS.
+
+As between Initial Developer, Original Developer and the Contributors, each
+party is responsible for claims and damages arising, directly or indirectly, out
+of its utilization of rights under this License and You agree to work with
+Initial Developer, Original Developer and Contributors to distribute such
+responsibility on an equitable basis. Nothing herein is intended or shall be
+deemed to constitute any admission of liability.
+
+13. MULTIPLE-LICENSED CODE.
+
+Initial Developer may designate portions of the Covered Code as
+Multiple-Licensed. Multiple-Licensed means that the Initial Developer permits
+you to utilize portions of the Covered Code under Your choice of the CPAL or the
+alternative licenses, if any, specified by the Initial Developer in the file
+described in Exhibit A.
+
+14. ADDITIONAL TERM: ATTRIBUTION
+
+(a) As a modest attribution to the organizer of the development of the Original
+Code ("Original Developer"), in the hope that its promotional value may help
+justify the time, money and effort invested in writing the Original Code, the
+Original Developer may include in Exhibit B ("Attribution Information") a
+requirement that each time an Executable and Source Code or a Larger Work is
+launched or initially run (which includes initiating a session), a prominent
+display of the Original Developer's Attribution Information (as defined below)
+must occur on the graphic user interface employed by the end user to access such
+Covered Code (which may include display on a splash screen), if any. The size of
+the graphic image should be consistent with the size of the other elements of
+the Attribution Information. If the access by the end user to the Executable and
+Source Code does not create a graphic user interface for access to the Covered
+Code, this obligation shall not apply. If the Original Code displays such
+Attribution Information in a particular form (such as in the form of a splash
+screen, notice at login, an "about" display, or dedicated attribution area on
+user interface screens), continued use of such form for that Attribution
+Information is one way of meeting this requirement for notice.
+
+(b) Attribution information may only include a copyright notice, a brief phrase,
+graphic image and a URL ("Attribution Information") and is subject to the
+Attribution Limits as defined below. For these purposes, prominent shall mean
+display for sufficient duration to give reasonable notice to the user of the
+identity of the Original Developer and that if You include Attribution
+Information or similar information for other parties, You must ensure that the
+Attribution Information for the Original Developer shall be no less prominent
+than such Attribution Information or similar information for the other
+party. For greater certainty, the Original Developer may choose to specify in
+Exhibit B below that the above attribution requirement only applies to an
+Executable and Source Code resulting from the Original Code or any Modification,
+but not a Larger Work. The intent is to provide for reasonably modest
+attribution, therefore the Original Developer cannot require that You display,
+at any time, more than the following information as Attribution Information: (a)
+a copyright notice including the name of the Original Developer; (b) a word or
+one phrase (not exceeding 10 words); (c) one graphic image provided by the
+Original Developer; and (d) a URL (collectively, the "Attribution Limits").
+
+(c) If Exhibit B does not include any Attribution Information, then there are no
+requirements for You to display any Attribution Information of the Original
+Developer.
+
+(d) You acknowledge that all trademarks, service marks and/or trade names
+contained within the Attribution Information distributed with the Covered Code
+are the exclusive property of their owners and may only be used with the
+permission of their owners, or under circumstances otherwise permitted by law or
+as expressly set out in this License.
+
+15. ADDITIONAL TERM: NETWORK USE.
+
+The term "External Deployment" means the use, distribution, or communication of
+the Original Code or Modifications in any way such that the Original Code or
+Modifications may be used by anyone other than You, whether those works are
+distributed or communicated to those persons or made available as an application
+intended for use over a network. As an express condition for the grants of
+license hereunder, You must treat any External Deployment by You of the Original
+Code or Modifications as a distribution under section 3.1 and make Source Code
+available under Section 3.2.
+
+EXHIBIT A. Common Public Attribution License Version 1.0.
+
+"The contents of this file are subject to the Common Public Attribution License
+Version 1.0. (the "License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+http://code.reddit.com/LICENSE. The License is based on the Mozilla Public
+License Version 1.1, but Sections 14 and 15 have been added to cover use of
+software over a computer network and provide for limited attribution for the
+Original Developer. In addition, Exhibit A has been modified to be consistent
+with Exhibit B.
+
+Software distributed under the License is distributed on an "AS IS" basis,
+WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the
+specific language governing rights and limitations under the License.
+
+The Original Code is Reddit.
+
+The Original Developer is the Initial Developer. The Initial Developer of the
+Original Code is CondeNet, Inc.
+
+All portions of the code written by CondeNet are Copyright (c) 2006-2008
+CondeNet, Inc. All Rights Reserved.
+
+EXHIBIT B. Attribution Information
+
+Attribution Copyright Notice: Copyright (c) 2006-2008 CondeNet, Inc. All Rights
+Reserved.
+
+Attribution Phrase (not exceeding 10 words): Powered by Reddit
+
+Attribution URL: http://code.reddit.com
+
+Graphic Image as provided in the Covered Code:
+http://code.reddit.com/reddit_logo.png
+
+Display of Attribution Information is required in Larger Works which are defined
+in the CPAL as a work which combines Covered Code or portions thereof with code
+not governed by the terms of the CPAL.
453 config/solr/schema.xml
@@ -0,0 +1,453 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!--
+"The contents of this file are subject to the Common Public Attribution
+License Version 1.0. (the "License"); you may not use this file except in
+compliance with the License. You may obtain a copy of the License at
+http://code.reddit.com/LICENSE. The License is based on the Mozilla Public
+License Version 1.1, but Sections 14 and 15 have been added to cover use of
+software over a computer network and provide for limited attribution for the
+Original Developer. In addition, Exhibit A has been modified to be consistent
+with Exhibit B.
+
+Software distributed under the License is distributed on an "AS IS" basis,
+WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+the specific language governing rights and limitations under the License.
+
+The Original Code is Reddit.
+
+The Original Developer is the Initial Developer. The Initial Developer of
+the Original Code is CondeNet, Inc.
+
+All portions of the code written by CondeNet are Copyright (c) 2006-2008
+CondeNet, Inc. All Rights Reserved.
+-->
+
+<schema name="reddit" version="1.1">
+ <types>
+ <!-- field type definitions. The "name" attribute is
+ just a label to be used by field definitions. The "class"
+ attribute and any other attributes determine the real
+ behavior of the fieldType.
+ Class names starting with "solr" refer to java classes in the
+ org.apache.solr.analysis package.
+ -->
+
+ <!-- The StrField type is not analyzed, but indexed/stored verbatim.
+ - StrField and TextField support an optional compressThreshold which
+ limits compression (if enabled in the derived fields) to values which
+ exceed a certain size (in characters).
+ -->
+ <fieldType name="string" class="solr.StrField" sortMissingLast="true" omitNorms="true"/>
+
+ <!-- boolean type: "true" or "false" -->
+ <fieldType name="boolean" class="solr.BoolField" sortMissingLast="true" omitNorms="true"/>
+
+ <!-- The optional sortMissingLast and sortMissingFirst attributes are
+ currently supported on types that are sorted internally as strings.
+ - If sortMissingLast="true", then a sort on this field will cause documents
+ without the field to come after documents with the field,
+ regardless of the requested sort order (asc or desc).
+ - If sortMissingFirst="true", then a sort on this field will cause documents
+ without the field to come before documents with the field,
+ regardless of the requested sort order.
+ - If sortMissingLast="false" and sortMissingFirst="false" (the default),
+ then default lucene sorting will be used which places docs without the
+ field first in an ascending sort and last in a descending sort.
+ -->
+
+
+ <!-- numeric field types that store and index the text
+ value verbatim (and hence don't support range queries, since the
+ lexicographic ordering isn't equal to the numeric ordering) -->
+ <fieldType name="integer" class="solr.IntField" omitNorms="true"/>
+ <fieldType name="long" class="solr.LongField" omitNorms="true"/>
+ <fieldType name="float" class="solr.FloatField" omitNorms="true"/>
+ <fieldType name="double" class="solr.DoubleField" omitNorms="true"/>
+
+
+ <!-- Numeric field types that manipulate the value into
+ a string value that isn't human-readable in its internal form,
+ but with a lexicographic ordering the same as the numeric ordering,
+ so that range queries work correctly. -->
+ <fieldType name="sint" class="solr.SortableIntField" sortMissingLast="true" omitNorms="true"/>
+ <fieldType name="slong" class="solr.SortableLongField" sortMissingLast="true" omitNorms="true"/>
+ <fieldType name="sfloat" class="solr.SortableFloatField" sortMissingLast="true" omitNorms="true"/>
+ <fieldType name="sdouble" class="solr.SortableDoubleField" sortMissingLast="true" omitNorms="true"/>
+
+ <fieldType name="hotness" class="solr.SortableDoubleField" sortMissingLast="true" omitNorms="false"/>
+
+ <!-- The format for this date field is of the form 1995-12-31T23:59:59Z, and
+ is a more restricted form of the canonical representation of dateTime
+ http://www.w3.org/TR/xmlschema-2/#dateTime
+ The trailing "Z" designates UTC time and is mandatory.
+ Optional fractional seconds are allowed: 1995-12-31T23:59:59.999Z
+ All other components are mandatory.
+
+ Expressions can also be used to denote calculations that should be
+ performed relative to "NOW" to determine the value, ie...
+
+ NOW/HOUR
+ ... Round to the start of the current hour
+ NOW-1DAY
+ ... Exactly 1 day prior to now
+ NOW/DAY+6MONTHS+3DAYS
+ ... 6 months and 3 days in the future from the start of
+ the current day
+
+ Consult the DateField javadocs for more information.
+ -->
+ <fieldType name="date" class="solr.DateField" sortMissingLast="true" omitNorms="true"/>
+
+ <!-- solr.TextField allows the specification of custom text analyzers
+ specified as a tokenizer and a list of token filters. Different
+ analyzers may be specified for indexing and querying.
+
+ The optional positionIncrementGap puts space between multiple fields of
+ this type on the same document, with the purpose of preventing false phrase
+ matching across fields.
+
+ For more info on customizing your analyzer chain, please see
+ http://wiki.apache.org/solr/AnalyzersTokenizersTokenFilters
+ -->
+
+ <!-- One can also specify an existing Analyzer class that has a
+ default constructor via the class attribute on the analyzer element -->
+
+ <!-- languages -->
+ <fieldtype name="text_dk" class="solr.TextField">
+ <analyzer>
+ <tokenizer class="solr.StandardTokenizerFactory"/>
+ <filter class="solr.StandardFilterFactory"/>
+ <filter class="solr.ISOLatin1AccentFilterFactory"/>
+ <filter class="solr.LowerCaseFilterFactory"/>
+
+ <filter class="solr.SnowballPorterFilterFactory" language="Danish" />
+ </analyzer>
+ </fieldtype>
+ <fieldtype name="text_nl" class="solr.TextField">
+ <analyzer>
+ <tokenizer class="solr.StandardTokenizerFactory"/>
+ <filter class="solr.StandardFilterFactory"/>
+ <filter class="solr.ISOLatin1AccentFilterFactory"/>
+ <filter class="solr.LowerCaseFilterFactory"/>
+
+ <filter class="solr.SnowballPorterFilterFactory" language="Dutch" />
+ </analyzer>
+
+ </fieldtype>
+ <fieldtype name="text_en" class="solr.TextField">
+ <analyzer>
+ <tokenizer class="solr.StandardTokenizerFactory"/>
+ <filter class="solr.StandardFilterFactory"/>
+ <filter class="solr.ISOLatin1AccentFilterFactory"/>
+ <filter class="solr.LowerCaseFilterFactory"/>
+
+ <filter class="solr.SnowballPorterFilterFactory" language="English" />
+ </analyzer>
+ </fieldtype>
+ <fieldtype name="text_fi" class="solr.TextField">
+ <analyzer>
+ <tokenizer class="solr.StandardTokenizerFactory"/>
+ <filter class="solr.StandardFilterFactory"/>
+ <filter class="solr.ISOLatin1AccentFilterFactory"/>
+ <filter class="solr.LowerCaseFilterFactory"/>
+
+ <filter class="solr.SnowballPorterFilterFactory" language="Finnish" />
+ </analyzer>
+ </fieldtype>
+ <fieldtype name="text_fr" class="solr.TextField">
+ <analyzer>
+ <tokenizer class="solr.StandardTokenizerFactory"/>
+ <filter class="solr.StandardFilterFactory"/>
+ <filter class="solr.ISOLatin1AccentFilterFactory"/>
+ <filter class="solr.LowerCaseFilterFactory"/>
+
+ <filter class="solr.SnowballPorterFilterFactory" language="French" />
+ </analyzer>
+ </fieldtype>
+ <fieldtype name="text_de" class="solr.TextField">
+ <analyzer>
+ <tokenizer class="solr.StandardTokenizerFactory"/>
+ <filter class="solr.StandardFilterFactory"/>
+ <filter class="solr.ISOLatin1AccentFilterFactory"/>
+ <filter class="solr.LowerCaseFilterFactory"/>
+
+ <filter class="solr.SnowballPorterFilterFactory" language="German" />
+ </analyzer>
+ </fieldtype>
+ <fieldtype name="text_it" class="solr.TextField">
+ <analyzer>
+ <tokenizer class="solr.StandardTokenizerFactory"/>
+ <filter class="solr.StandardFilterFactory"/>
+ <filter class="solr.ISOLatin1AccentFilterFactory"/>
+ <filter class="solr.LowerCaseFilterFactory"/>
+
+ <filter class="solr.SnowballPorterFilterFactory" language="Italian" />
+ </analyzer>
+ </fieldtype>
+ <fieldtype name="text_no" class="solr.TextField">
+ <analyzer>
+ <tokenizer class="solr.StandardTokenizerFactory"/>
+ <filter class="solr.StandardFilterFactory"/>
+ <filter class="solr.ISOLatin1AccentFilterFactory"/>
+ <filter class="solr.LowerCaseFilterFactory"/>
+
+ <filter class="solr.SnowballPorterFilterFactory" language="Norwegian" />
+ </analyzer>
+ </fieldtype>
+ <fieldtype name="text_nn" class="solr.TextField">
+ <analyzer>
+ <tokenizer class="solr.StandardTokenizerFactory"/>
+ <filter class="solr.StandardFilterFactory"/>
+ <filter class="solr.ISOLatin1AccentFilterFactory"/>
+ <filter class="solr.LowerCaseFilterFactory"/>
+
+ <filter class="solr.SnowballPorterFilterFactory" language="Norwegian" />
+ </analyzer>
+ </fieldtype>
+ <fieldtype name="text_pt" class="solr.TextField">
+ <analyzer>
+ <tokenizer class="solr.StandardTokenizerFactory"/>
+ <filter class="solr.StandardFilterFactory"/>
+ <filter class="solr.ISOLatin1AccentFilterFactory"/>
+ <filter class="solr.LowerCaseFilterFactory"/>
+
+ <filter class="solr.SnowballPorterFilterFactory" language="Portuguese" />
+ </analyzer>
+ </fieldtype>
+ <fieldType name="text_ru" class="solr.TextField">
+ <analyzer class="org.apache.lucene.analysis.ru.RussianAnalyzer"/>
+ <filter class="solr.SnowballPorterFilterFactory" language="Russian" />
+ </fieldType>
+ <fieldtype name="text_es" class="solr.TextField">
+ <analyzer>
+ <tokenizer class="solr.StandardTokenizerFactory"/>
+ <filter class="solr.StandardFilterFactory"/>
+ <filter class="solr.ISOLatin1AccentFilterFactory"/>
+ <filter class="solr.LowerCaseFilterFactory"/>
+
+ <filter class="solr.SnowballPorterFilterFactory" language="Spanish" />
+ </analyzer>
+ </fieldtype>
+ <fieldtype name="text_sv" class="solr.TextField">
+ <analyzer>
+ <tokenizer class="solr.StandardTokenizerFactory"/>
+ <filter class="solr.StandardFilterFactory"/>
+ <filter class="solr.ISOLatin1AccentFilterFactory"/>
+ <filter class="solr.LowerCaseFilterFactory"/>
+
+ <filter class="solr.SnowballPorterFilterFactory" language="Swedish" />
+ </analyzer>
+ </fieldtype>
+
+ <fieldType name="text_zh" class="solr.TextField">
+ <tokenizer class="org.apache.lucene.analysis.cjk.CJKTokenizer" />
+ <analyzer class="org.apache.lucene.analysis.cjk.CJKAnalyzer"/>
+ </fieldType>
+ <fieldType name="text_ja" class="solr.TextField">
+ <tokenizer class="org.apache.lucene.analysis.cjk.CJKTokenizer" />
+ <analyzer class="org.apache.lucene.analysis.cjk.CJKAnalyzer"/>
+ </fieldType>
+ <fieldType name="text_ko" class="solr.TextField">
+ <tokenizer class="org.apache.lucene.analysis.cjk.CJKTokenizer" />
+ <analyzer class="org.apache.lucene.analysis.cjk.CJKAnalyzer"/>
+ </fieldType>
+ <fieldType name="text_cs" class="solr.TextField">
+ <analyzer class="org.apache.lucene.analysis.cz.CzechAnalyzer"/>
+ </fieldType>
+ <fieldType name="text_el" class="solr.TextField">
+ <analyzer class="org.apache.lucene.analysis.el.GreekAnalyzer"/>
+ </fieldType>
+ <fieldType name="text_th" class="solr.TextField">
+ <analyzer class="org.apache.lucene.analysis.th.ThaiAnalyzer"/>
+ </fieldType>
+
+ <!-- A text field that only splits on whitespace for exact matching of words -->
+ <fieldType name="text_ws" class="solr.TextField" positionIncrementGap="100">
+ <analyzer>
+ <filter class="solr.LowerCaseFilterFactory"/>
+
+ <tokenizer class="solr.WhitespaceTokenizerFactory"/>
+ </analyzer>
+ </fieldType>
+
+ <!-- A text field that uses WordDelimiterFilter to enable splitting and matching of
+ words on case-change, alpha numeric boundaries, and non-alphanumeric chars,
+ so that a query of "wifi" or "wi fi" could match a document containing "Wi-Fi".
+ Synonyms and stopwords are customized by external files, and stemming is enabled.
+ Duplicate tokens at the same position (which may result from Stemmed Synonyms or
+ WordDelim parts) are removed.
+ -->
+ <fieldType name="text" class="solr.TextField" positionIncrementGap="100">
+ <analyzer type="index">
+ <tokenizer class="solr.StandardTokenizerFactory"/>
+ <!-- <tokenizer class="solr.WhitespaceTokenizerFactory"/> -->
+ <!-- in this example, we will only use synonyms at query time
+ <filter class="solr.SynonymFilterFactory" synonyms="index_synonyms.txt" ignoreCase="true" expand="false"/>
+ -->
+ <filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt"/>
+ <filter class="solr.WordDelimiterFilterFactory" generateWordParts="1" generateNumberParts="1" catenateWords="1" catenateNumbers="1" catenateAll="0"/>
+ <filter class="solr.LowerCaseFilterFactory"/>
+ <filter class="solr.EnglishPorterFilterFactory" protected="protwords.txt"/>
+ <filter class="solr.RemoveDuplicatesTokenFilterFactory"/>
+ </analyzer>
+ <analyzer type="query">
+ <tokenizer class="solr.StandardTokenizerFactory"/>
+ <!-- <tokenizer class="solr.WhitespaceTokenizerFactory"/> -->
+ <filter class="solr.SynonymFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="true"/>
+ <filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt"/>
+ <filter class="solr.WordDelimiterFilterFactory" generateWordParts="1" generateNumberParts="1" catenateWords="0" catenateNumbers="0" catenateAll="0"/>
+ <filter class="solr.LowerCaseFilterFactory"/>
+ <filter class="solr.EnglishPorterFilterFactory" protected="protwords.txt"/>
+ <filter class="solr.RemoveDuplicatesTokenFilterFactory"/>
+ </analyzer>
+ </fieldType>
+
+
+ <!-- Less flexible matching, but less false matches. Probably not ideal for product names,
+ but may be good for SKUs. Can insert dashes in the wrong place and still match. -->
+ <fieldType name="textTight" class="solr.TextField" positionIncrementGap="100" >
+ <analyzer>
+ <tokenizer class="solr.WhitespaceTokenizerFactory"/>
+ <filter class="solr.SynonymFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="false"/>
+ <filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt"/>
+ <filter class="solr.WordDelimiterFilterFactory" generateWordParts="0" generateNumberParts="0" catenateWords="1" catenateNumbers="1" catenateAll="0"/>
+ <filter class="solr.LowerCaseFilterFactory"/>
+ <filter class="solr.EnglishPorterFilterFactory" protected="protwords.txt"/>
+ <filter class="solr.RemoveDuplicatesTokenFilterFactory"/>
+ </analyzer>
+ </fieldType>
+
+ <!-- This is an example of using the KeywordTokenizer along
+ With various TokenFilterFactories to produce a sortable field
+ that does not include some properties of the source text
+ -->
+ <fieldType name="alphaOnlySort" class="solr.TextField" sortMissingLast="true" omitNorms="true">
+ <analyzer>
+ <!-- KeywordTokenizer does no actual tokenizing, so the entire
+ input string is preserved as a single token
+ -->
+ <tokenizer class="solr.KeywordTokenizerFactory"/>
+ <!-- The LowerCase TokenFilter does what you expect, which can be
+ when you want your sorting to be case insensitive
+ -->
+ <filter class="solr.LowerCaseFilterFactory" />
+ <!-- The TrimFilter removes any leading or trailing whitespace -->
+ <filter class="solr.TrimFilterFactory" />
+ <!-- The PatternReplaceFilter gives you the flexibility to use
+ Java Regular expression to replace any sequence of characters
+ matching a pattern with an arbitrary replacement string,
+ which may include back refrences to portions of the orriginal
+ string matched by the pattern.
+
+ See the Java Regular Expression documentation for more
+ infomation on pattern and replacement string syntax.
+
+ http://java.sun.com/j2se/1.5.0/docs/api/java/util/regex/package-summary.html
+ -->
+ <filter class="solr.PatternReplaceFilterFactory"
+ pattern="([^a-z])" replacement="" replace="all"
+ />
+ </analyzer>
+ </fieldType>
+
+ <!-- since fields of this type are by default not stored or indexed, any data added to
+ them will be ignored outright
+ -->
+ <fieldtype name="ignored" stored="false" indexed="false" class="solr.StrField" />
+
+ </types>
+
+
+ <fields>
+ <!-- Valid attributes for fields:
+ name: mandatory - the name for the field
+ type: mandatory - the name of a previously defined type from the <types> section
+ indexed: true if this field should be indexed (searchable or sortable)
+ stored: true if this field should be retrievable
+ compressed: [false] if this field should be stored using gzip compression
+ (this will only apply if the field type is compressable; among
+ the standard field types, only TextField and StrField are)
+ multiValued: true if this field may contain multiple values per document
+ omitNorms: (expert) set to true to omit the norms associated with
+ this field (this disables length normalization and index-time
+ boosting for the field, and saves some memory). Only full-text
+ fields or fields that need an index-time boost need norms.
+ -->
+
+ <!-- Thing -->
+ <field name="fullname" type="string" indexed="true" stored="true" required="true" />
+ <field name="type" type="string" indexed="true" stored="false" required="true" multiValued="true" />
+ <field name="date" type="date" indexed="true" stored="false" required="true" reversed="true" />
+ <field name="lang" type="string" indexed="true" stored="false" required="false" />
+ <field name="ups" type="sint" indexed="true" stored="false" required="true" reversed="true" />
+ <field name="downs" type="sint" indexed="true" stored="false" required="true" reversed="true" />
+ <field name="hot" type="hotness" indexed="true" stored="true" required="true" reversed="true" />
+ <field name="points" type="sint" indexed="true" stored="false" required="true" reversed="true" />
+ <!-- subreddit,link,comment -->
+ <field name="author_id" type="integer" indexed="true" stored="false" required="false" />
+ <field name="author" type="string" indexed="true" stored="false" required="false" />
+ <!-- subreddit -->
+ <field name="title" type="text" indexed="true" stored="false" required="false" />
+ <field name="description" type="text" indexed="true" stored="false" required="false" />
+ <field name="firsttext" type="text" indexed="true" stored="false" required="false" />
+ <field name="name" type="string" indexed="true" stored="false" required="false" />
+ <field name="over_18" type="boolean" indexed="true" stored="false" required="false" />
+ <field name="sr_type" type="string" indexed="true" stored="false" required="false" />
+ <!-- link -->
+ <field name="sr_id" type="integer" indexed="true" stored="false" required="false" />
+ <field name="reddit" type="string" indexed="true" stored="false" required="false" />
+ <field name="subreddit" type="string" indexed="true" stored="false" required="false" />
+ <field name="url" type="text" indexed="true" stored="false" required="false" />
+ <field name="domain" type="string" indexed="true" stored="false" required="false" multiValued="true" />
+ <field name="site" type="string" indexed="true" stored="false" required="false" multiValued="true" />
+ <field name="is_self" type="boolean" indexed="true" stored="false" required="false" />
+ <!-- comment (none) -->
+
+ <!-- all objects must have a 'contents' field, and most will also
+ have a field for their particular languages. Searches are then
+ done according to the fields in the languages that the user
+ has specified -->
+
+ <field name="contents" type="text" indexed="true" stored="false" required="true" />
+ <field name="contents_ws" type="text_ws" indexed="true" stored="false" required="false" />
+ <field name="contents_en" type="text_en" indexed="true" stored="false" required="false" />
+ <field name="contents_cs" type="text_cs" indexed="true" stored="false" required="false" />
+ <field name="contents_pt" type="text_pt" indexed="true" stored="false" required="false" />
+ <field name="contents_zh" type="text_zh" indexed="true" stored="false" required="false" />
+ <field name="contents_ja" type="text_ja" indexed="true" stored="false" required="false" />
+ <field name="contents_ko" type="text_ko" indexed="true" stored="false" required="false" />
+ <field name="contents_de" type="text_de" indexed="true" stored="false" required="false" />
+ <field name="contents_fr" type="text_fr" indexed="true" stored="false" required="false" />
+ <field name="contents_el" type="text_el" indexed="true" stored="false" required="false" />
+ <field name="contents_nl" type="text_nl" indexed="true" stored="false" required="false" />
+ <field name="contents_no" type="text_no" indexed="true" stored="false" required="false" />
+ <field name="contents_nn" type="text_nn" indexed="true" stored="false" required="false" />
+ <field name="contents_ru" type="text_ru" indexed="true" stored="false" required="false" />
+ <field name="contents_it" type="text_it" indexed="true" stored="false" required="false" />
+ <field name="contents_es" type="text_es" indexed="true" stored="false" required="false" />
+ <field name="contents_sv" type="text_sv" indexed="true" stored="false" required="false" />
+ <field name="contents_fi" type="text_fi" indexed="true" stored="false" required="false" />
+ <field name="contents_dk" type="text_dk" indexed="true" stored="false" required="false" />
+ <field name="contents_th" type="text_th" indexed="true" stored="false" required="false" />
+
+
+ </fields>
+
+ <!-- Field to use to determine and enforce document uniqueness.
+ Unless this field is marked with required="false", it will be a required field
+ -->
+ <uniqueKey>fullname</uniqueKey>
+
+ <!-- field for the QueryParser to use when an explicit fieldname is absent -->
+ <defaultSearchField>contents</defaultSearchField>
+
+ <!-- SolrQueryParser configuration: defaultOperator="AND|OR" -->
+ <solrQueryParser defaultOperator="OR"/>
+
+ <!-- Similarity is the scoring routine for each document vs. a query.
+ A custom similarity may be specified here, but the default is fine
+ for most applications. -->
+ <!-- <similarity class="org.apache.lucene.search.DefaultSimilarity"/> -->
+
+</schema>
387 config/solr/server.xml
@@ -0,0 +1,387 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+"The contents of this file are subject to the Common Public Attribution
+License Version 1.0. (the "License"); you may not use this file except in
+compliance with the License. You may obtain a copy of the License at
+http://code.reddit.com/LICENSE. The License is based on the Mozilla Public
+License Version 1.1, but Sections 14 and 15 have been added to cover use of
+software over a computer network and provide for limited attribution for the
+Original Developer. In addition, Exhibit A has been modified to be consistent
+with Exhibit B.
+
+Software distributed under the License is distributed on an "AS IS" basis,
+WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+the specific language governing rights and limitations under the License.
+
+The Original Code is Reddit.
+
+The Original Developer is the Initial Developer. The Initial Developer of
+the Original Code is CondeNet, Inc.
+
+All portions of the code written by CondeNet are Copyright (c) 2006-2008
+CondeNet, Inc. All Rights Reserved.
+-->
+
+<Server port="8081" shutdown="SHUTDOWN">
+
+ <!-- Comment these entries out to disable JMX MBeans support used for the
+ administration web application -->
+ <Listener className="org.apache.catalina.core.AprLifecycleListener" />
+ <Listener className="org.apache.catalina.mbeans.ServerLifecycleListener" />
+ <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
+ <Listener className="org.apache.catalina.storeconfig.StoreConfigLifecycleListener"/>
+
+ <!-- Global JNDI resources -->
+ <GlobalNamingResources>
+
+ <!-- Test entry for demonstration purposes -->
+ <Environment name="simpleValue" type="java.lang.Integer" value="30"/>
+
+ <!-- Editable user database that can also be used by
+ UserDatabaseRealm to authenticate users -->
+ <Resource name="UserDatabase" auth="Container"
+ type="org.apache.catalina.UserDatabase"
+ description="User database that can be updated and saved"
+ factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
+ pathname="conf/tomcat-users.xml" />
+
+ </GlobalNamingResources>
+
+ <!-- A "Service" is a collection of one or more "Connectors" that share
+ a single "Container" (and therefore the web applications visible
+ within that Container). Normally, that Container is an "Engine",
+ but this is not required.
+
+ Note: A "Service" is not itself a "Container", so you may not
+ define subcomponents such as "Valves" or "Loggers" at this level.
+ -->
+
+ <!-- Define the Tomcat Stand-Alone Service -->
+ <Service name="Catalina">
+
+ <!-- A "Connector" represents an endpoint by which requests are received
+ and responses are returned. Each Connector passes requests on to the
+ associated "Container" (normally an Engine) for processing.
+
+ By default, a non-SSL HTTP/1.1 Connector is established on port 8080.
+ You can also enable an SSL HTTP/1.1 Connector on port 8443 by
+ following the instructions below and uncommenting the second Connector
+ entry. SSL support requires the following steps (see the SSL Config
+ HOWTO in the Tomcat 5 documentation bundle for more detailed
+ instructions):
+ * If your JDK version 1.3 or prior, download and install JSSE 1.0.2 or
+ later, and put the JAR files into "$JAVA_HOME/jre/lib/ext".
+ * Execute:
+ %JAVA_HOME%\bin\keytool -genkey -alias tomcat -keyalg RSA (Windows)
+ $JAVA_HOME/bin/keytool -genkey -alias tomcat -keyalg RSA (Unix)
+ with a password value of "changeit" for both the certificate and
+ the keystore itself.
+
+ By default, DNS lookups are enabled when a web application calls
+ request.getRemoteHost(). This can have an adverse impact on
+ performance, so you can disable it by setting the
+ "enableLookups" attribute to "false". When DNS lookups are disabled,
+ request.getRemoteHost() will return the String version of the
+ IP address of the remote client.
+ -->
+
+ <!-- Define a non-SSL HTTP/1.1 Connector on port 8080 -->
+ <Connector port="8080" maxHttpHeaderSize="8192"
+ maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
+ enableLookups="false" redirectPort="8443" acceptCount="100"
+ connectionTimeout="20000" disableUploadTimeout="true"
+ URIEncoding="UTF-8" />
+ <!-- Note : To disable connection timeouts, set connectionTimeout value
+ to 0 -->
+
+ <!-- Note : To use gzip compression you could set the following properties :
+
+ compression="on"
+ compressionMinSize="2048"
+ noCompressionUserAgents="gozilla, traviata"
+ compressableMimeType="text/html,text/xml"
+ -->
+
+ <!-- Define a SSL HTTP/1.1 Connector on port 8443 -->
+ <!--
+ <Connector port="8443" maxHttpHeaderSize="8192"
+ maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
+ enableLookups="false" disableUploadTimeout="true"
+ acceptCount="100" scheme="https" secure="true"
+ clientAuth="false" sslProtocol="TLS" />
+ -->
+
+ <!-- Define an AJP 1.3 Connector on port 8009 -->
+ <Connector port="8009"
+ enableLookups="false" redirectPort="8443" protocol="AJP/1.3" />
+
+ <!-- Define a Proxied HTTP/1.1 Connector on port 8082 -->
+ <!-- See proxy documentation for more information about using this. -->
+ <!--
+ <Connector port="8082"
+ maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
+ enableLookups="false" acceptCount="100" connectionTimeout="20000"
+ proxyPort="80" disableUploadTimeout="true" />
+ -->
+
+ <!-- An Engine represents the entry point (within Catalina) that processes
+ every request. The Engine implementation for Tomcat stand alone
+ analyzes the HTTP headers included with the request, and passes them
+ on to the appropriate Host (virtual host). -->
+
+ <!-- You should set jvmRoute to support load-balancing via AJP ie :
+ <Engine name="Standalone" defaultHost="localhost" jvmRoute="jvm1">
+ -->
+
+ <!-- Define the top level container in our container hierarchy -->
+ <Engine name="Catalina" defaultHost="localhost">
+
+ <!-- The request dumper valve dumps useful debugging information about
+ the request headers and cookies that were received, and the response
+ headers and cookies that were sent, for all requests received by
+ this instance of Tomcat. If you care only about requests to a
+ particular virtual host, or a particular application, nest this
+ element inside the corresponding <Host> or <Context> entry instead.
+
+ For a similar mechanism that is portable to all Servlet 2.4
+ containers, check out the "RequestDumperFilter" Filter in the
+ example application (the source for this filter may be found in
+ "$CATALINA_HOME/webapps/examples/WEB-INF/classes/filters").
+
+ Note that this Valve uses the platform's default character encoding.
+ This may cause problems for developers in another encoding, e.g.
+ UTF-8. Use the RequestDumperFilter instead.
+
+ Also note that enabling this Valve will write a ton of stuff to your
+ logs. They are likely to grow quite large. This extensive log writing
+ will definitely slow down your server.
+
+ Request dumping is disabled by default. Uncomment the following
+ element to enable it. -->
+ <!--
+ <Valve className="org.apache.catalina.valves.RequestDumperValve"/>
+ -->
+
+ <!-- Because this Realm is here, an instance will be shared globally -->
+
+ <!-- This Realm uses the UserDatabase configured in the global JNDI
+ resources under the key "UserDatabase". Any edits
+ that are performed against this UserDatabase are immediately
+ available for use by the Realm. -->
+ <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
+ resourceName="UserDatabase"/>
+
+ <!-- Comment out the old realm but leave here for now in case we
+ need to go back quickly -->
+ <!--
+ <Realm className="org.apache.catalina.realm.MemoryRealm" />
+ -->
+
+ <!-- Replace the above Realm with one of the following to get a Realm
+ stored in a database and accessed via JDBC -->
+
+ <!--
+ <Realm className="org.apache.catalina.realm.JDBCRealm"
+ driverName="org.gjt.mm.mysql.Driver"
+ connectionURL="jdbc:mysql://localhost/authority"
+ connectionName="test" connectionPassword="test"
+ userTable="users" userNameCol="user_name" userCredCol="user_pass"
+ userRoleTable="user_roles" roleNameCol="role_name" />
+ -->
+
+ <!--
+ <Realm className="org.apache.catalina.realm.JDBCRealm"
+ driverName="oracle.jdbc.driver.OracleDriver"
+ connectionURL="jdbc:oracle:thin:@ntserver:1521:ORCL"
+ connectionName="scott" connectionPassword="tiger"
+ userTable="users" userNameCol="user_name" userCredCol="user_pass"
+ userRoleTable="user_roles" roleNameCol="role_name" />
+ -->
+
+ <!--
+ <Realm className="org.apache.catalina.realm.JDBCRealm"
+ driverName="sun.jdbc.odbc.JdbcOdbcDriver"
+ connectionURL="jdbc:odbc:CATALINA"
+ userTable="users" userNameCol="user_name" userCredCol="user_pass"
+ userRoleTable="user_roles" roleNameCol="role_name" />
+ -->
+
+ <!-- Define the default virtual host
+ Note: XML Schema validation will not work with Xerces 2.2.
+ -->
+ <Host name="localhost" appBase="webapps"
+ unpackWARs="true" autoDeploy="true"
+ xmlValidation="false" xmlNamespaceAware="false">
+
+ <!-- Defines a cluster for this node,
+ By defining this element, means that every manager will be changed.
+ So when running a cluster, only make sure that you have webapps in there
+ that need to be clustered and remove the other ones.
+ A cluster has the following parameters:
+
+ className = the fully qualified name of the cluster class
+
+ clusterName = a descriptive name for your cluster, can be anything
+
+ mcastAddr = the multicast address, has to be the same for all the nodes
+
+ mcastPort = the multicast port, has to be the same for all the nodes
+
+ mcastBindAddress = bind the multicast socket to a specific address
+
+ mcastTTL = the multicast TTL if you want to limit your broadcast
+
+ mcastSoTimeout = the multicast readtimeout
+
+ mcastFrequency = the number of milliseconds in between sending a "I'm alive" heartbeat
+
+ mcastDropTime = the number a milliseconds before a node is considered "dead" if no heartbeat is received
+
+ tcpThreadCount = the number of threads to handle incoming replication requests, optimal would be the same amount of threads as nodes
+
+ tcpListenAddress = the listen address (bind address) for TCP cluster request on this host,
+ in case of multiple ethernet cards.
+ auto means that address becomes
+ InetAddress.getLocalHost().getHostAddress()
+
+ tcpListenPort = the tcp listen port
+
+ tcpSelectorTimeout = the timeout (ms) for the Selector.select() method in case the OS
+ has a wakup bug in java.nio. Set to 0 for no timeout
+
+ printToScreen = true means that managers will also print to std.out
+
+ expireSessionsOnShutdown = true means that
+
+ useDirtyFlag = true means that we only replicate a session after setAttribute,removeAttribute has been called.
+ false means to replicate the session after each request.
+ false means that replication would work for the following piece of code: (only for SimpleTcpReplicationManager)
+ <%
+ HashMap map = (HashMap)session.getAttribute("map");
+ map.put("key","value");
+ %>
+ replicationMode = can be either 'pooled', 'synchronous' or 'asynchronous'.
+ * Pooled means that the replication happens using several sockets in a synchronous way. Ie, the data gets replicated, then the request return. This is the same as the 'synchronous' setting except it uses a pool of sockets, hence it is multithreaded. This is the fastest and safest configuration. To use this, also increase the nr of tcp threads that you have dealing with replication.
+ * Synchronous means that the thread that executes the request, is also the
+ thread the replicates the data to the other nodes, and will not return until all
+ nodes have received the information.
+ * Asynchronous means that there is a specific 'sender' thread for each cluster node,
+ so the request thread will queue the replication request into a "smart" queue,
+ and then return to the client.
+ The "smart" queue is a queue where when a session is added to the queue, and the same session
+ already exists in the queue from a previous request, that session will be replaced
+ in the queue instead of replicating two requests. This almost never happens, unless there is a
+ large network delay.
+ -->
+ <!--
+ When configuring for clustering, you also add in a valve to catch all the requests
+ coming in, at the end of the request, the session may or may not be replicated.
+ A session is replicated if and only if all the conditions are met:
+ 1. useDirtyFlag is true or setAttribute or removeAttribute has been called AND
+ 2. a session exists (has been created)
+ 3. the request is not trapped by the "filter" attribute
+
+ The filter attribute is to filter out requests that could not modify the session,
+ hence we don't replicate the session after the end of this request.
+ The filter is negative, ie, anything you put in the filter, you mean to filter out,
+ ie, no replication will be done on requests that match one of the filters.
+ The filter attribute is delimited by ;, so you can't escape out ; even if you wanted to.
+
+ filter=".*\.gif;.*\.js;" means that we will not replicate the session after requests with the URI
+ ending with .gif and .js are intercepted.
+
+ The deployer element can be used to deploy apps cluster wide.
+ Currently the deployment only deploys/undeploys to working members in the cluster
+ so no WARs are copied upons startup of a broken node.
+ The deployer watches a directory (watchDir) for WAR files when watchEnabled="true"
+ When a new war file is added the war gets deployed to the local instance,
+ and then deployed to the other instances in the cluster.
+ When a war file is deleted from the watchDir the war is undeployed locally
+ and cluster wide
+ -->
+
+ <!--
+ <Cluster className="org.apache.catalina.cluster.tcp.SimpleTcpCluster"
+ managerClassName="org.apache.catalina.cluster.session.DeltaManager"
+ expireSessionsOnShutdown="false"
+ useDirtyFlag="true"
+ notifyListenersOnReplication="true">
+
+ <Membership
+ className="org.apache.catalina.cluster.mcast.McastService"
+ mcastAddr="228.0.0.4"
+ mcastPort="45564"
+ mcastFrequency="500"
+ mcastDropTime="3000"/>
+
+ <Receiver
+ className="org.apache.catalina.cluster.tcp.ReplicationListener"
+ tcpListenAddress="auto"
+ tcpListenPort="4001"
+ tcpSelectorTimeout="100"
+ tcpThreadCount="6"/>
+
+ <Sender
+ className="org.apache.catalina.cluster.tcp.ReplicationTransmitter"
+ replicationMode="pooled"
+ ackTimeout="15000"
+ waitForAck="true"/>
+
+ <Valve className="org.apache.catalina.cluster.tcp.ReplicationValve"
+ filter=".*\.gif;.*\.js;.*\.jpg;.*\.png;.*\.htm;.*\.html;.*\.css;.*\.txt;"/>
+
+ <Deployer className="org.apache.catalina.cluster.deploy.FarmWarDeployer"
+ tempDir="/tmp/war-temp/"
+ deployDir="/tmp/war-deploy/"
+ watchDir="/tmp/war-listen/"
+ watchEnabled="false"/>
+
+ <ClusterListener className="org.apache.catalina.cluster.session.ClusterSessionListener"/>
+ </Cluster>
+ -->
+
+
+
+ <!-- Normally, users must authenticate themselves to each web app
+ individually. Uncomment the following entry if you would like
+ a user to be authenticated the first time they encounter a
+ resource protected by a security constraint, and then have that
+ user identity maintained across *all* web applications contained
+ in this virtual host. -->
+ <!--
+ <Valve className="org.apache.catalina.authenticator.SingleSignOn" />
+ -->
+
+ <!-- Access log processes all requests for this virtual host. By
+ default, log files are created in the "logs" directory relative to
+ $CATALINA_HOME. If you wish, you can specify a different
+ directory with the "directory" attribute. Specify either a relative
+ (to $CATALINA_HOME) or absolute path to the desired directory.
+ -->
+ <!--
+ <Valve className="org.apache.catalina.valves.AccessLogValve"
+ directory="logs" prefix="localhost_access_log." suffix=".txt"
+ pattern="common" resolveHosts="false"/>
+ -->
+
+ <!-- Access log processes all requests for this virtual host. By
+ default, log files are created in the "logs" directory relative to
+ $CATALINA_HOME. If you wish, you can specify a different
+ directory with the "directory" attribute. Specify either a relative
+ (to $CATALINA_HOME) or absolute path to the desired directory.
+ This access log implementation is optimized for maximum performance,
+ but is hardcoded to support only the "common" and "combined" patterns.
+ -->
+ <!--
+ <Valve className="org.apache.catalina.valves.FastCommonAccessLogValve"
+ directory="logs" prefix="localhost_access_log." suffix=".txt"
+ pattern="common" resolveHosts="false"/>
+ -->
+
+ </Host>
+
+ </Engine>
+
+ </Service>
+
+</Server>
464 config/solr/solrconfig.xml
@@ -0,0 +1,464 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!--
+"The contents of this file are subject to the Common Public Attribution
+License Version 1.0. (the "License"); you may not use this file except in
+compliance with the License. You may obtain a copy of the License at
+http://code.reddit.com/LICENSE. The License is based on the Mozilla Public
+License Version 1.1, but Sections 14 and 15 have been added to cover use of
+software over a computer network and provide for limited attribution for the
+Original Developer. In addition, Exhibit A has been modified to be consistent
+with Exhibit B.
+
+Software distributed under the License is distributed on an "AS IS" basis,
+WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+the specific language governing rights and limitations under the License.
+
+The Original Code is Reddit.
+
+The Original Developer is the Initial Developer. The Initial Developer of
+the Original Code is CondeNet, Inc.
+
+All portions of the code written by CondeNet are Copyright (c) 2006-2008
+CondeNet, Inc. All Rights Reserved.
+-->
+<config>
+ <!-- Set this to 'false' if you want solr to continue working after it has
+ encountered an severe configuration error. In a production environment,
+ you may want solr to keep working even if one handler is mis-configured.
+
+ You may also set this to false using by setting the system property:
+ -Dsolr.abortOnConfigurationError=false
+ -->
+ <abortOnConfigurationError>${solr.abortOnConfigurationError:true}</abortOnConfigurationError>
+
+ <!-- Used to specify an alternate directory to hold all index data
+ other than the default ./data under the Solr home.
+ If replication is in use, this should match the replication configuration. -->
+ <!--
+ <dataDir>./solr/data</dataDir>
+ -->
+
+ <indexDefaults>
+ <!-- Values here affect all index writers and act as a default unless overridden. -->
+ <useCompoundFile>false</useCompoundFile>
+ <mergeFactor>10</mergeFactor>
+ <maxBufferedDocs>1000</maxBufferedDocs>
+ <maxMergeDocs>2147483647</maxMergeDocs>
+ <maxFieldLength>10000</maxFieldLength>
+ <writeLockTimeout>1000</writeLockTimeout>
+ <commitLockTimeout>10000</commitLockTimeout>
+ </indexDefaults>
+
+ <mainIndex>
+ <!-- options specific to the main on-disk lucene index -->
+ <useCompoundFile>false</useCompoundFile>
+ <mergeFactor>10</mergeFactor>
+ <maxBufferedDocs>1000</maxBufferedDocs>
+ <maxMergeDocs>2147483647</maxMergeDocs>
+ <maxFieldLength>10000</maxFieldLength>
+
+ <!-- If true, unlock any held write or commit locks on startup.
+ This defeats the locking mechanism that allows multiple
+ processes to safely access a lucene index, and should be
+ used with care. -->
+ <unlockOnStartup>false</unlockOnStartup>
+ </mainIndex>
+
+ <!-- the default high-performance update handler -->
+ <updateHandler class="solr.DirectUpdateHandler2">
+
+ <!-- A prefix of "solr." for class names is an alias that
+ causes solr to search appropriate packages, including
+ org.apache.solr.(search|update|request|core|analysis)
+ -->
+
+ <!-- autocommit pending docs if certain criteria are met
+ <autoCommit>
+ <maxDocs>10000</maxDocs>
+ <maxTime>1000</maxTime>
+ </autoCommit>
+ -->
+
+ <!-- The RunExecutableListener executes an external command.
+ exe - the name of the executable to run
+ dir - dir to use as the current working directory. default="."
+ wait - the calling thread waits until the executable returns. default="true"
+ args - the arguments to pass to the program. default=nothing
+ env - environment variables to set. default=nothing
+ -->
+ <!-- A postCommit event is fired after every commit or optimize command
+ <listener event="postCommit" class="solr.RunExecutableListener">
+ <str name="exe">snapshooter</str>
+ <str name="dir">solr/bin</str>
+ <bool name="wait">true</bool>
+ <arr name="args"> <str>arg1</str> <str>arg2</str> </arr>
+ <arr name="env"> <str>MYVAR=val1</str> </arr>
+ </listener>
+ -->
+ <!-- A postOptimize event is fired only after every optimize command, useful
+ in conjunction with index distribution to only distribute optimized indicies
+ <listener event="postOptimize" class="solr.RunExecutableListener">
+ <str name="exe">snapshooter</str>
+ <str name="dir">solr/bin</str>
+ <bool name="wait">true</bool>
+ </listener>
+ -->
+
+ </updateHandler>
+
+
+ <query>
+ <!-- Maximum number of clauses in a boolean query... can affect
+ range or prefix queries that expand to big boolean
+ queries. An exception is thrown if exceeded. -->
+ <maxBooleanClauses>1024</maxBooleanClauses>
+
+
+ <!-- Cache used by SolrIndexSearcher for filters (DocSets),
+ unordered sets of *all* documents that match a query.
+ When a new searcher is opened, its caches may be prepopulated
+ or "autowarmed" using data from caches in the old searcher.
+ autowarmCount is the number of items to prepopulate. For LRUCache,
+ the autowarmed items will be the most recently accessed items.
+ Parameters:
+ class - the SolrCache implementation (currently only LRUCache)
+ size - the maximum number of entries in the cache
+ initialSize - the initial capacity (number of entries) of
+ the cache. (seel java.util.HashMap)
+ autowarmCount - the number of entries to prepopulate from
+ and old cache.
+ -->
+ <filterCache
+ class="solr.LRUCache"
+ size="512"
+ initialSize="512"
+ autowarmCount="256"/>
+
+ <!-- queryResultCache caches results of searches - ordered lists of
+ document ids (DocList) based on a query, a sort, and the range
+ of documents requested. -->
+ <queryResultCache
+ class="solr.LRUCache"
+ size="512"
+ initialSize="512"
+ autowarmCount="256"/>
+
+ <!-- documentCache caches Lucene Document objects (the stored fields for each document).
+ Since Lucene internal document ids are transient, this cache will not be autowarmed. -->
+ <documentCache
+ class="solr.LRUCache"
+ size="512"
+ initialSize="512"
+ autowarmCount="0"/>
+
+ <!-- If true, stored fields that are not requested will be loaded lazily.
+
+ This can result in a significant speed improvement if the usual case is to
+ not load all stored fields, especially if the skipped fields are large compressed
+ text fields.
+ -->
+ <enableLazyFieldLoading>true</enableLazyFieldLoading>
+
+ <!-- Example of a generic cache. These caches may be accessed by name
+ through SolrIndexSearcher.getCache(),cacheLookup(), and cacheInsert().
+ The purpose is to enable easy caching of user/application level data.
+ The regenerator argument should be specified as an implementation
+ of solr.search.CacheRegenerator if autowarming is desired. -->
+ <!--
+ <cache name="myUserCache"
+ class="solr.LRUCache"
+ size="4096"
+ initialSize="1024"
+ autowarmCount="1024"
+ regenerator="org.mycompany.mypackage.MyRegenerator"
+ />
+ -->
+
+ <!-- An optimization that attempts to use a filter to satisfy a search.
+ If the requested sort does not include score, then the filterCache
+ will be checked for a filter matching the query. If found, the filter
+ will be used as the source of document ids, and then the sort will be
+ applied to that.
+ <useFilterForSortedQuery>true</useFilterForSortedQuery>
+ -->
+
+ <!-- An optimization for use with the queryResultCache. When a search
+ is requested, a superset of the requested number of document ids
+ are collected. For example, if a search for a particular query
+ requests matching documents 10 through 19, and queryWindowSize is 50,
+ then documents 0 through 50 will be collected and cached. Any further
+ requests in that range can be satisfied via the cache. -->
+ <queryResultWindowSize>10</queryResultWindowSize>
+
+ <!-- This entry enables an int hash representation for filters (DocSets)
+ when the number of items in the set is less than maxSize. For smaller
+ sets, this representation is more memory efficient, more efficient to
+ iterate over, and faster to take intersections. -->
+ <HashDocSet maxSize="3000" loadFactor="0.75"/>
+
+
+ <!-- boolToFilterOptimizer converts boolean clauses with zero boost
+ into cached filters if the number of docs selected by the clause exceeds
+ the threshold (represented as a fraction of the total index) -->
+ <boolTofilterOptimizer enabled="true" cacheSize="32" threshold=".05"/>
+
+
+ <!-- a newSearcher event is fired whenever a new searcher is being prepared
+ and there is a current searcher handling requests (aka registered). -->
+ <!-- QuerySenderListener takes an array of NamedList and executes a
+ local query request for each NamedList in sequence. -->
+ <!--
+ <listener event="newSearcher" class="solr.QuerySenderListener">
+ <arr name="queries">
+ <lst> <str name="q">solr</str> <str name="start">0</str> <str name="rows">10</str> </lst>
+ <lst> <str name="q">rocks</str> <str name="start">0</str> <str name="rows">10</str> </lst>
+ </arr>
+ </listener>
+ -->
+
+ <!-- a firstSearcher event is fired whenever a new searcher is being
+ prepared but there is no current registered searcher to handle
+ requests or to gain autowarming data from. -->
+ <!--
+ <listener event="firstSearcher" class="solr.QuerySenderListener">
+ <arr name="queries">
+ <lst> <str name="q">fast_warm</str> <str name="start">0</str> <str name="rows">10</str> </lst>
+ </arr>
+ </listener>
+ -->
+
+ <!-- If a search request comes in and there is no current registered searcher,
+ then immediately register the still warming searcher and use it. If
+ "false" then all requests will block until the first searcher is done
+ warming. -->
+ <useColdSearcher>false</useColdSearcher>
+
+ <!-- Maximum number of searchers that may be warming in the background
+ concurrently. An error is returned if this limit is exceeded. Recommend
+ 1-2 for read-only slaves, higher for masters w/o cache warming. -->
+ <maxWarmingSearchers>4</maxWarmingSearchers>
+
+ </query>
+
+ <!--
+ Let the dispatch filter handler /select?qt=XXX
+ handleSelect=true will use consistent error handling for /select and /update
+ handleSelect=false will use solr1.1 style error formatting
+ -->
+ <requestDispatcher handleSelect="true" >
+ <!--Make sure your system has some authentication before enabling remote streaming! -->
+ <requestParsers enableRemoteStreaming="false" multipartUploadLimitInKB="2048" />
+ </requestDispatcher>
+
+
+ <!-- requestHandler plugins... incoming queries will be dispatched to the
+ correct handler based on the qt (query type) param matching the
+ name of registered handlers.
+ The "standard" request handler is the default and will be used if qt
+ is not specified in the request.
+ -->
+ <requestHandler name="standard" class="solr.StandardRequestHandler">
+ <!-- default values for query parameters -->
+ <lst name="defaults">
+ <str name="echoParams">explicit</str>
+ <!--
+ <int name="rows">10</int>
+ <str name="fl">*</str>
+ <str name="version">2.1</str>
+ -->
+ </lst>
+ </requestHandler>
+
+ <!-- DisMaxRequestHandler allows easy searching across multiple fields
+ for simple user-entered phrases.
+ see http://wiki.apache.org/solr/DisMaxRequestHandler
+ -->
+ <requestHandler name="dismax" class="solr.DisMaxRequestHandler" >
+ <lst name="defaults">
+ <str name="qf">contents</str>
+ <!-- <str name="echoParams">explicit</str>
+ <float name="tie">0.01</float>
+ <str name="qf">
+ text^0.5 features^1.0 name^1.2 sku^1.5 id^10.0 manu^1.1 cat^1.4
+ </str>
+ <str name="pf">
+ text^0.2 features^1.1 name^1.5 manu^1.4 manu_exact^1.9
+ </str>
+ <str name="bf">
+ ord(poplarity)^0.5 recip(rord(price),1,1000,1000)^0.3
+ </str>
+ <str name="fl">
+ id,name,price,score
+ </str>
+ <str name="mm">
+ 2&lt;-1 5&lt;-2 6&lt;90%
+ </str>
+ <int name="ps">100</int>
+ <str name="q.alt">*:*</str> -->
+ </lst>
+ </requestHandler>
+
+ <!-- Note how you can register the same handler multiple times with
+ different names (and different init parameters)
+ -->
+ <requestHandler name="partitioned" class="solr.DisMaxRequestHandler" >
+ <lst name="defaults">
+ <str name="echoParams">explicit</str>
+ <str name="qf">text^0.5 features^1.0 name^1.2 sku^1.5 id^10.0</str>
+ <str name="mm">2&lt;-1 5&lt;-2 6&lt;90%</str>
+ <!-- This is an example of using Date Math to specify a constantly
+ moving date range in a config...
+ -->
+ <str name="bq">incubationdate_dt:[* TO NOW/DAY-1MONTH]^2.2</str>
+ </lst>
+ <!-- In addition to defaults, "appends" params can be specified
+ to identify values which should be appended to the list of
+ multi-val params from the query (or the existing "defaults").
+
+ In this example, the param "fq=instock:true" will be appended to
+ any query time fq params the user may specify, as a mechanism for
+ partitioning the index, independent of any user selected filtering
+ that may also be desired (perhaps as a result of faceted searching).
+
+ NOTE: there is *absolutely* nothing a client can do to prevent these
+ "appends" values from being used, so don't use this mechanism
+ unless you are sure you always want it.
+ -->
+ <lst name="appends">
+ <str name="fq">inStock:true</str>
+ </lst>
+ <!-- "invariants" are a way of letting the Solr maintainer lock down
+ the options available to Solr clients. Any params values
+ specified here are used regardless of what values may be specified
+ in either the query, the "defaults", or the "appends" params.
+
+ In this example, the facet.field and facet.query params are fixed,
+ limiting the facets clients can use. Faceting is not turned on by
+ default - but if the client does specify facet=true in the request,
+ these are the only facets they will be able to see counts for;
+ regardless of what other facet.field or facet.query params they
+ may specify.
+
+ NOTE: there is *absolutely* nothing a client can do to prevent these
+ "invariants" values from being used, so don't use this mechanism
+ unless you are sure you always want it.
+ -->
+ <lst name="invariants">
+ <str name="facet.field">cat</str>
+ <str name="facet.field">manu_exact</str>
+ <str name="facet.query">price:[* TO 500]</str>
+ <str name="facet.query">price:[500 TO *]</str>
+ </lst>
+ </requestHandler>
+
+ <requestHandler name="instock" class="solr.DisMaxRequestHandler" >
+ <!-- for legacy reasons, DisMaxRequestHandler will assume all init
+ params are "defaults" if you don't explicitly specify any defaults.
+ -->
+ <str name="fq">
+ inStock:true
+ </str>
+ <str name="qf">
+ text^0.5 features^1.0 name^1.2 sku^1.5 id^10.0 manu^1.1 cat^1.4
+ </str>
+ <str name="mm">
+ 2&lt;-1 5&lt;-2 6&lt;90%
+ </str>
+ </requestHandler>
+
+
+ <!-- SpellCheckerRequestHandler takes in a word (or several words) as the
+ value of the "q" parameter and returns a list of alternative spelling
+ suggestions. If invoked with a ...&cmd=rebuild, it will rebuild the
+ spellchecker index.
+ -->
+ <requestHandler name="spellchecker" class="solr.SpellCheckerRequestHandler" startup="lazy">
+ <!-- default values for query parameters -->
+ <lst name="defaults">
+ <int name="suggestionCount">1</int>
+ <float name="accuracy">0.5</float>
+ </lst>
+
+ <!-- Main init params for handler -->
+
+ <!-- The directory where your SpellChecker Index should live. -->
+ <!-- May be absolute, or relative to the Solr "dataDir" directory. -->
+ <!-- If this option is not specified, a RAM directory will be used -->
+ <str name="spellcheckerIndexDir">spell</str>
+
+ <!-- the field in your schema that you want to be able to build -->
+ <!-- your spell index on. This should be a field that uses a very -->
+ <!-- simple FieldType without a lot of Analysis (ie: string) -->
+ <str name="termSourceField">word</str>
+
+ </requestHandler>
+
+
+ <!-- Update request handler.
+
+ Note: Since solr1.1 requestHandlers requires a valid content type header if posted in
+ the body. For example, curl now requires: -H 'Content-type:text/xml; charset=utf-8'
+ The response format differs from solr1.1 formatting and returns a standard error code.
+
+ To enable solr1.1 behavior, remove the /update handler or change its path
+ -->
+ <requestHandler name="/update" class="solr.XmlUpdateRequestHandler" />
+
+ <!-- CSV update handler, loaded on demand -->
+ <requestHandler name="/update/csv" class="solr.CSVRequestHandler" startup="lazy" />
+
+
+ <!-- Admin Handlers. TODO? There could be a single handler that loads them all... -->
+ <!-- <requestHandler name="/admin/luke" class="org.apache.solr.handler.admin.LukeRequestHandler" />
+ <requestHandler name="/admin/system" class="org.apache.solr.handler.admin.SystemInfoHandler" />
+ <requestHandler name="/admin/plugins" class="org.apache.solr.handler.admin.PluginInfoHandler" />
+ <requestHandler name="/admin/threads" class="org.apache.solr.handler.admin.ThreadDumpHandler" />
+ <requestHandler name="/admin/properties" class="org.apache.solr.handler.admin.PropertiesRequestHandler" /> -->
+
+ <!-- Echo the request contents back to the client -->
+ <!-- <requestHandler name="/debug/dump" class="solr.DumpRequestHandler" >
+ <lst name="defaults">
+ <str name="echoParams">explicit</str> --> <!-- for all params (including the default etc) use: 'all' -->
+ <!-- <str name="echoHandler">true</str>
+ </lst>
+ </requestHandler> -->
+
+ <!-- queryResponseWriter plugins... query responses will be written using the
+ writer specified by the 'wt' request parameter matching the name of a registered
+ writer.
+ The "standard" writer is the default and will be used if 'wt' is not specified
+ in the request. XMLResponseWriter will be used if nothing is specified here.
+ The json, python, and ruby writers are also available by default.
+
+ <queryResponseWriter name="standard" class="org.apache.solr.request.XMLResponseWriter"/>
+ <queryResponseWriter name="json" class="org.apache.solr.request.JSONResponseWriter"/>
+ <queryResponseWriter name="python" class="org.apache.solr.request.PythonResponseWriter"/>
+ <queryResponseWriter name="ruby" class="org.apache.solr.request.RubyResponseWriter"/>
+
+ <queryResponseWriter name="custom" class="com.example.MyResponseWriter"/>
+ -->
+
+ <!-- XSLT response writer transforms the XML output by any xslt file found
+ in Solr's conf/xslt directory. Changes to xslt files are checked for
+ every xsltCacheLifetimeSeconds.
+ -->
+ <!-- <queryResponseWriter name="xslt" class="org.apache.solr.request.XSLTResponseWriter">
+ <int name="xsltCacheLifetimeSeconds">5</int>
+ </queryResponseWriter> -->
+
+ <!-- config for the admin interface -->
+ <admin>
+ <defaultQuery>solr</defaultQuery>
+ <gettableFiles>solrconfig.xml schema.xml admin-extra.html</gettableFiles>
+ <!-- pingQuery should be "URLish" ...
+ &amp; separated key=val pairs ... but there shouldn't be any
+ URL escaping of the values -->
+ <pingQuery>
+ qt=standard&amp;q=solrpingquery
+ </pingQuery>
+ <!-- configure a healthcheck file for servers behind a loadbalancer
+ <healthcheck type="file">server-enabled</healthcheck>
+ -->
+ </admin>
+
+</config>
36 r2/babel.cfg
@@ -0,0 +1,36 @@
+## "The contents of this file are subject to the Common Public Attribution
+## License Version 1.0. (the "License"); you may not use this file except in
+## compliance with the License. You may obtain a copy of the License at
+## http://code.reddit.com/LICENSE. The License is based on the Mozilla Public
+## License Version 1.1, but Sections 14 and 15 have been added to cover use of
+## software over a computer network and provide for limited attribution for the
+## Original Developer. In addition, Exhibit A has been modified to be consistent
+## with Exhibit B.
+##
+## Software distributed under the License is distributed on an "AS IS" basis,
+## WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+## the specific language governing rights and limitations under the License.
+##
+## The Original Code is Reddit.
+##
+## The Original Developer is the Initial Developer. The Initial Developer of
+## the Original Code is CondeNet, Inc.
+##
+## All portions of the code written by CondeNet are Copyright (c) 2006-2008
+## CondeNet, Inc. All Rights Reserved.
+################################################################################
+
+# Extraction from Mako templates
+
+[mako:**.html]
+input_encoding = utf-8
+[mako:**.xml]
+input_encoding = utf-8
+[mako:**.htmllite]
+input_encoding = utf-8
+
+# Extraction from Python source files
+
+[python:**.py]
+
+
4 r2/check_procs.sh
@@ -0,0 +1,4 @@
+#!/bin/sh
+
+cd /home/ri/hgreddit/r2
+/usr/bin/paster run local.ini supervise_watcher.py -c "Alert(restart_list=['MEM'])"
71 r2/compress_js.sh
@@ -0,0 +1,71 @@
+#!/bin/bash
+
+# "The contents of this file are subject to the Common Public Attribution
+# License Version 1.0. (the "License"); you may not use this file except in
+# compliance with the License. You may obtain a copy of the License at
+# http://code.reddit.com/LICENSE. The License is based on the Mozilla Public
+# License Version 1.1, but Sections 14 and 15 have been added to cover use of
+# software over a computer network and provide for limited attribution for the
+# Original Developer. In addition, Exhibit A has been modified to be consistent
+# with Exhibit B.
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+# the specific language governing rights and limitations under the License.
+#
+# The Original Code is Reddit.
+#
+# The Original Developer is the Initial Developer. The Initial Developer of the
+# Original Code is CondeNet, Inc.
+#
+# All portions of the code written by CondeNet are Copyright (c) 2006-2008
+# CondeNet, Inc. All Rights Reserved.
+################################################################################
+
+files=( psrs.js utils.js animate.js link.js comments.js subreddit.js vote_piece.js reddit_piece.js organic.js )
+
+wd=`pwd`
+redditjs='reddit.js'
+framejs='frame.js'
+votejs='vote.js'
+compressor=" $wd/r2/lib/contrib/jsjam -g -i"
+
+
+echo "generating rtl style sheet"
+
+./rtl.sh
+
+
+echo "Generating reddit.js..."
+
+cd r2/public/static
+[ -e $redditjs ] && rm $redditjs
+[ -e $redditjs-big ] && rm $redditjs-big
+
+cat json.js > $redditjs.tmp
+for f in "${files[@]}"
+do
+ $compressor $f >> $redditjs.tmp
+done;
+sed 's/\$/ \$/g' $redditjs.tmp > $redditjs
+
+
+echo "Generating vote.js..."
+# compress the votes alone (for buttons)
+cat psrs.js | $compressor | sed 's/\$/ \$/g' > $votejs
+cat utils.js vote_piece.js | $compressor >> $votejs
+
+echo "Generating frame.js..."
+# compress frame alone (for the toolbar)
+cat psrs.js > $framejs
+cat vote_piece.js utils.js frame_piece.js | $compressor >> $framejs
+
+echo "droppping md5s..."
+for file in *.js
+do
+ cat $file | openssl md5 > $file.md5
+done
+for file in *.css
+do
+ cat $file | openssl md5 > $file.md5
+done
100 r2/example.ini
@@ -0,0 +1,100 @@
+#
+# r2 - Pylons development environment configuration
+#
+# The %(here)s variable will be replaced with the parent directory of this file
+#
+[DEFAULT]
+debug = true
+template_debug = true
+uncompressedJS = true
+translator = true
+
+proxy_addr =
+log_path =
+
+memcaches = 127.0.0.1:11211
+rec_cache = 127.0.0.1:11311
+tracker_url =
+
+main_db_name = reddit
+main_db_host = 127.0.0.1
+main_db_user = reddit
+main_db_pass = password
+
+comment_db_name = reddit
+comment_db_host = 127.0.0.1
+comment_db_user = reddit
+comment_db_pass = password
+
+vote_db_name = reddit
+vote_db_host = 127.0.0.1
+vote_db_user = reddit
+vote_db_pass = password
+
+change_db_name = changes
+change_db_host = 127.0.0.1
+change_db_user = reddit
+change_db_pass = password
+
+###
+# Other magic settings
+###
+
+timezone = UTC
+monitored_servers = localhost
+
+stylesheet = reddit.css
+stylesheet_rtl = reddit_rtl.css
+
+login_cookie = reddit_session
+domain = localhost
+default_sr = localhost
+admins =
+page_cache_time = 30
+static_path = /static/
+
+solr_url =
+
+SECRET = abcdefghijklmnopqrstuvwxyz0123456789
+MODSECRET = abcdefghijklmnopqrstuvwxyz0123456789
+ip_hash =
+
+MIN_DOWN_LINK = 0
+MIN_UP_KARMA = 0
+MIN_DOWN_KARMA = 0
+MIN_RATE_LIMIT_KARMA = 0
+MIN_RATE_LIMIT_COMMENT_KARMA = 0
+
+# time in days
+MODWINDOW = 2
+HOT_PAGE_AGE = 1
+
+# time of ratelimit purgatory (min)
+RATELIMIT = 10
+
+num_comments = 200
+max_comments = 500
+num_side_reddits = 20
+
+#user-agents to limit
+agents =
+
+feedback_email = abuse@localhost
+
+[server:main]
+use = egg:Paste#http
+host = 0.0.0.0
+port = %(port)s
+
+[app:main]
+use = egg:r2
+cache_dir = %(here)s/data
+beaker.session_key = r2
+beaker.session_secret = somesecret
+#lang = en
+
+# WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT*
+# Debug mode will enable the interactive debugging tool, allowing ANYONE to
+# execute malicious code after an exception is raised.
+#set debug = false
+
15 r2/ez_setup/README.txt
@@ -0,0 +1,15 @@
+This directory exists so that Subversion-based projects can share a single
+copy of the ``ez_setup`` bootstrap module for ``setuptools``, and have it
+automatically updated in their projects when ``setuptools`` is updated.
+
+For your convenience, you may use the following svn:externals definition::
+
+ ez_setup svn://svn.eby-sarna.com/svnroot/ez_setup
+
+You can set this by executing this command in your project directory::
+
+ svn propedit svn:externals .
+
+And then adding the line shown above to the file that comes up for editing.
+Then, whenever you update your project, ``ez_setup`` will be updated as well.
+
249 r2/ez_setup/__init__.py
@@ -0,0 +1,249 @@
+# "The contents of this file are subject to the Common Public Attribution
+# License Version 1.0. (the "License"); you may not use this file except in
+# compliance with the License. You may obtain a copy of the License at
+# http://code.reddit.com/LICENSE. The License is based on the Mozilla Public
+# License Version 1.1, but Sections 14 and 15 have been added to cover use of
+# software over a computer network and provide for limited attribution for the
+# Original Developer. In addition, Exhibit A has been modified to be consistent
+# with Exhibit B.
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+# the specific language governing rights and limitations under the License.
+#
+# The Original Code is Reddit.
+#
+# The Original Developer is the Initial Developer. The Initial Developer of the
+# Original Code is CondeNet, Inc.
+#
+# All portions of the code written by CondeNet are Copyright (c) 2006-2008
+# CondeNet, Inc. All Rights Reserved.
+################################################################################
+#!python
+"""Bootstrap setuptools installation
+
+If you want to use setuptools in your package's setup.py, just include this
+file in the same directory with it, and add this to the top of your setup.py::
+
+ from ez_setup import use_setuptools
+ use_setuptools()
+
+If you want to require a specific version of setuptools, set a download
+mirror, or use an alternate download directory, you can do so by supplying
+the appropriate options to ``use_setuptools()``.
+
+This file can also be run as a script to install or upgrade setuptools.
+"""
+import sys
+DEFAULT_VERSION = "0.6c5"
+DEFAULT_URL = "http://cheeseshop.python.org/packages/%s/s/setuptools/" % sys.version[:3]
+
+md5_data = {
+ 'setuptools-0.6b1-py2.3.egg': '8822caf901250d848b996b7f25c6e6ca',
+ 'setuptools-0.6b1-py2.4.egg': 'b79a8a403e4502fbb85ee3f1941735cb',
+ 'setuptools-0.6b2-py2.3.egg': '5657759d8a6d8fc44070a9d07272d99b',
+ 'setuptools-0.6b2-py2.4.egg': '4996a8d169d2be661fa32a6e52e4f82a',
+ 'setuptools-0.6b3-py2.3.egg': 'bb31c0fc7399a63579975cad9f5a0618',
+ 'setuptools-0.6b3-py2.4.egg': '38a8c6b3d6ecd22247f179f7da669fac',
+ 'setuptools-0.6b4-py2.3.egg': '62045a24ed4e1ebc77fe039aa4e6f7e5',
+ 'setuptools-0.6b4-py2.4.egg': '4cb2a185d228dacffb2d17f103b3b1c4',
+ 'setuptools-0.6c1-py2.3.egg': 'b3f2b5539d65cb7f74ad79127f1a908c',
+ 'setuptools-0.6c1-py2.4.egg': 'b45adeda0667d2d2ffe14009364f2a4b',
+ 'setuptools-0.6c2-py2.3.egg': 'f0064bf6aa2b7d0f3ba0b43f20817c27',
+ 'setuptools-0.6c2-py2.4.egg': '616192eec35f47e8ea16cd6a122b7277',
+ 'setuptools-0.6c3-py2.3.egg': 'f181fa125dfe85a259c9cd6f1d7b78fa',
+ 'setuptools-0.6c3-py2.4.egg': 'e0ed74682c998bfb73bf803a50e7b71e',
+ 'setuptools-0.6c3-py2.5.egg': 'abef16fdd61955514841c7c6bd98965e',
+ 'setuptools-0.6c4-py2.3.egg': 'b0b9131acab32022bfac7f44c5d7971f',
+ 'setuptools-0.6c4-py2.4.egg': '2a1f9656d4fbf3c97bf946c0a124e6e2',
+ 'setuptools-0.6c4-py2.5.egg': '8f5a052e32cdb9c72bcf4b5526f28afc',
+ 'setuptools-0.6c5-py2.3.egg': 'ee9fd80965da04f2f3e6b3576e9d8167',
+ 'setuptools-0.6c5-py2.4.egg': 'afe2adf1c01701ee841761f5bcd8aa64',
+ 'setuptools-0.6c5-py2.5.egg': 'a8d3f61494ccaa8714dfed37bccd3d5d',
+}
+
+import sys, os
+
+def _validate_md5(egg_name, data):
+ if egg_name in md5_data:
+ from md5 import md5
+ digest = md5(data).hexdigest()
+ if digest != md5_data[egg_name]:
+ print >>sys.stderr, (
+ "md5 validation of %s failed! (Possible download problem?)"
+ % egg_name
+ )
+ sys.exit(2)
+ return data
+
+
+def use_setuptools(
+ version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir,
+ download_delay=15
+):
+ """Automatically find/download setuptools and make it available on sys.path
+
+ `version` should be a valid setuptools version number that is available
+ as an egg for download under the `download_base` URL (which should end with
+ a '/'). `to_dir` is the directory where setuptools will be downloaded, if
+ it is not already available. If `download_delay` is specified, it should
+ be the number of seconds that will be paused before initiating a download,
+ should one be required. If an older version of setuptools is installed,
+ this routine will print a message to ``sys.stderr`` and raise SystemExit in
+ an attempt to abort the calling script.
+ """
+ try:
+ import setuptools
+ if setuptools.__version__ == '0.0.1':
+ print >>sys.stderr, (
+ "You have an obsolete version of setuptools installed. Please\n"
+ "remove it from your system entirely before rerunning this script."
+ )
+ sys.exit(2)
+ except ImportError:
+ egg = download_setuptools(version, download_base, to_dir, download_delay)
+ sys.path.insert(0, egg)
+ import setuptools; setuptools.bootstrap_install_from = egg
+
+ import pkg_resources
+ try:
+ pkg_resources.require("setuptools>="+version)
+
+ except pkg_resources.VersionConflict, e:
+ # XXX could we install in a subprocess here?
+ print >>sys.stderr, (
+ "The required version of setuptools (>=%s) is not available, and\n"
+ "can't be installed while this script is running. Please install\n"
+ " a more recent version first.\n\n(Currently using %r)"
+ ) % (version, e.args[0])
+ sys.exit(2)
+
+def download_setuptools(
+ version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir,
+ delay = 15
+):
+ """Download setuptools from a specified location and return its filename
+
+ `version` should be a valid setuptools version number that is available
+ as an egg for download under the `download_base` URL (which should end
+ with a '/'). `to_dir` is the directory where the egg will be downloaded.
+ `delay` is the number of seconds to pause before an actual download attempt.
+ """
+ import urllib2, shutil
+ egg_name = "setuptools-%s-py%s.egg" % (version,sys.version[:3])
+ url = download_base + egg_name
+ saveto = os.path.join(to_dir, egg_name)
+ src = dst = None
+ if not os.path.exists(saveto): # Avoid repeated downloads
+ try:
+ from distutils import log
+ if delay:
+ log.warn("""
+---------------------------------------------------------------------------
+This script requires setuptools version %s to run (even to display
+help). I will attempt to download it for you (from
+%s), but
+you may need to enable firewall access for this script first.
+I will start the download in %d seconds.
+
+(Note: if this machine does not have network access, please obtain the file
+
+ %s
+
+and place it in this directory before rerunning this script.)
+---------------------------------------------------------------------------""",
+ version, download_base, delay, url
+ ); from time import sleep; sleep(delay)
+ log.warn("Downloading %s", url)
+ src = urllib2.urlopen(url)