I attached a patch to the google code ticket for this.  
http://code.google.com/p/recaptcha/issues/detail?id=10

It looks like the packages line in their setup.py is not right. I switched it to use find_packages instead of listing recaptcha.client and it seemed to install fine. I put a patched version of the tarball into the curdle dependencies folder so that the installer will work.

- Luke

On Jul 15, 2008, at 1:52 PM, Joshua Bronson wrote:

If you're getting "ImportError: No module named recaptcha", this is a known issue ticketed at http://code.google.com/p/recaptcha/issues/detail?id=10 . The workaround for now is to svn checkout http://recaptcha.googlecode.com/svn/trunk/recaptcha-plugins/python && python setup.py develop. Apologies for not catching this sooner. Stay tuned for further updates on this issue.

Josh

On Mon, Jul 14, 2008 at 5:29 PM, Joshua Bronson <[EMAIL PROTECTED]> wrote: I added recaptcha captchas to the email_link form for non-logged-in users in r1043. This adds a new dependency on recaptcha-client (google code project here). This also adds two new configuration settings, melkjug.recaptcha.public_key (checked in below) and melkjug.recaptcha.private_key (not checked in for security reasons), which identifies melkjug.com, the domain I registered, to the recaptcha servers. I have emailed the private key to a new closed mailing list I set up, [EMAIL PROTECTED] According to http://recaptcha.net/apidocs/captcha/client.html,

If one of your servers is "localhost" or "127.0.0.1", reCAPTCHA will not enforce the same-domain rule. Just use the same key as for the production server.

so once you add the private key to your development.ini, your anonymous email_link forms will work locally again.

Josh

---------- Forwarded message ----------
From: <[EMAIL PROTECTED]>
Date: Mon, Jul 14, 2008 at 5:06 PM
Subject: [Melkjug SVN Commits] melkjug r1043 - in melkjug/trunk: . melkjug/controllers melkjug/lib melkjug/public/javascripts melkjug/ templates/reader
To: [EMAIL PROTECTED]


Author: jab
Date: 2008-07-14 17:06:50 -0400 (Mon, 14 Jul 2008)
New Revision: 1043

Modified:
  melkjug/trunk/development.ini
  melkjug/trunk/melkjug/controllers/reader.py
  melkjug/trunk/melkjug/lib/helpers.py
  melkjug/trunk/melkjug/lib/validation.py
  melkjug/trunk/melkjug/public/javascripts/melk_widgets.js
  melkjug/trunk/melkjug/templates/reader/email_link.mako
  melkjug/trunk/setup.py
Log:
add recaptcha captcha to email_link form for non-logged-in users. the captcha widget could stand to be customized as it's a little big, but at least it's nicely rigged into the formencode validation.

Modified: melkjug/trunk/development.ini
===================================================================
--- melkjug/trunk/development.ini 2008-07-14 20:48:35 UTC (rev 1042) +++ melkjug/trunk/development.ini 2008-07-14 21:06:50 UTC (rev 1043)
@@ -47,6 +47,10 @@

 melkjug.http_cache = %(here)s/data/http_cache

+## recaptcha keys
+# registered to melkjug.com domain:
+melkjug.recaptcha.public_key = 6LfbdAIAAAAAAKx_MLzSqmCV_5O83p9GUScukAQD
+melkjug.recaptcha.private_key =

 ## melkjug will send various emails from this name & address:
 melkjug.email.from_name = Melkjug

Modified: melkjug/trunk/melkjug/controllers/reader.py
===================================================================
--- melkjug/trunk/melkjug/controllers/reader.py 2008-07-14 20:48:35 UTC (rev 1042) +++ melkjug/trunk/melkjug/controllers/reader.py 2008-07-14 21:06:50 UTC (rev 1043)
@@ -23,10 +23,11 @@
 from melkjug.lib.base import *
 from melkjug.lib import backend
from melkjug.lib.itemchoice import choose_items, compute_rating, get_starred_items, get_read_items
-from melkjug.lib.validation import EmailList
+from melkjug.lib.validation import EmailList, LoggedIn, RecaptchaResponse
 from pylons import session
 import formencode
 from formencode import Schema, Invalid, htmlfill
+from formencode.compound import Any
 from formencode.validators import *
 from melkjug.lib import filterui
 import traceback
@@ -51,6 +52,7 @@
    note = String()
    link = String()
    title = String()
+    chained_validators = [Any(RecaptchaResponse(), LoggedIn())]

 class ReaderController(BaseController):


Modified: melkjug/trunk/melkjug/lib/helpers.py
===================================================================
--- melkjug/trunk/melkjug/lib/helpers.py 2008-07-14 20:48:35 UTC (rev 1042) +++ melkjug/trunk/melkjug/lib/helpers.py 2008-07-14 21:06:50 UTC (rev 1043)
@@ -34,6 +34,16 @@
 from dateutil.tz import tzlocal, tzutc


+def display_captcha():
+    return """
+ <script type="text/javascript" src="http://api.recaptcha.net/js/recaptcha_ajax.js ">
+    </script>
+    <script type="text/javascript">
+      Recaptcha.create('%s', 'recaptcha_div', {theme: 'white'});
+    </script>
+    """ % pylons.config['melkjug.recaptcha.public_key']
+
+
 def javascript_include_tag(file, **kw):
    if 'melkjug.deploy_timestamp' in config:
        kw['dts'] = config['melkjug.deploy_timestamp']

Modified: melkjug/trunk/melkjug/lib/validation.py
===================================================================
--- melkjug/trunk/melkjug/lib/validation.py 2008-07-14 20:48:35 UTC (rev 1042) +++ melkjug/trunk/melkjug/lib/validation.py 2008-07-14 21:06:50 UTC (rev 1043)
@@ -36,6 +36,8 @@
 import pylons
from pylons.decorators import determine_response_charset, encode_formencode_errors

+from recaptcha.client.captcha import submit as submit_captcha
+
 log = logging.getLogger(__name__)

 BAD_FILE_CHARS = re.compile(r'[^a-zA-Z0-9\-\_]')
@@ -84,9 +86,42 @@
        if re.search(self._pat, value) is not None:
raise Invalid(self.message('invalid', state), value, state)

+class LoggedIn(FancyValidator):
+    messages = {
+        'invalid': 'must be logged in'
+        }
+    def __init__(self, *args, **kwargs):
+        FancyValidator.__init__(self, *args, **kwargs)
+
+    def validate_python(self, value, state):
+        if pylons.c.security.is_anonymous():
+ raise Invalid(self.message('invalid', state), value, state)
+
+class RecaptchaResponse(FormValidator):
+    messages = {
+        'invalid': 'Please type the words below (case matters!)'
+        }
+    def __init__(self, *args, **kwargs):
+        FancyValidator.__init__(self, *args, **kwargs)
+
+    def validate_python(self, field_dict, state):
+ forwarded_for = pylons.request.environ.get('HTTP_X_FORWARDED_FOR')
+        if forwarded_for: # we're behind a proxy
+            remote_ip = forwarded_for
+        else:
+            remote_ip = pylons.request.environ['REMOTE_ADDR']
+        private_key = pylons.config['melkjug.recaptcha.private_key']
+        recaptcha_response = submit_captcha(
+            field_dict['recaptcha_challenge_field'],
+ field_dict['recaptcha_response_field'], private_key, remote_ip)
+        if not recaptcha_response.is_valid:
+            errormsg = self.message('invalid', state)
+            errors = {'recaptcha_marker_field': errormsg}
+ raise Invalid(errormsg, field_dict, state, error_dict=errors)
+
 class EmailList(FancyValidator):
    messages = {
- 'invalid': 'must contain a comma-separated list of email addresses' + 'invalid': 'Please enter a comma-separated list of email addresses.'
        }
    def __init__(self, sep=',', *args, **kwargs):
        FancyValidator.__init__(self, *args, **kwargs)

Modified: melkjug/trunk/melkjug/public/javascripts/melk_widgets.js
===================================================================
--- melkjug/trunk/melkjug/public/javascripts/melk_widgets.js 2008-07-14 20:48:35 UTC (rev 1042) +++ melkjug/trunk/melkjug/public/javascripts/melk_widgets.js 2008-07-14 21:06:50 UTC (rev 1043)
@@ -224,7 +224,7 @@

var options = {setup_callback: Melk.with_scope(this, this._setup_dialog),
                   width: 450,
-                   height: 400,
+                   height: 450,
                   top: 50};
    var cb = {
        success: function(response) {
@@ -258,7 +258,7 @@

var options = {setup_callback: Melk.with_scope(this, this._setup_dialog),
                     width: 450,
-                     height: 400,
+                     height: 450,
                     top: 50};
      var cb = {
        success: function(response) {

Modified: melkjug/trunk/melkjug/templates/reader/email_link.mako
===================================================================
--- melkjug/trunk/melkjug/templates/reader/email_link.mako 2008-07-14 20:48:35 UTC (rev 1042) +++ melkjug/trunk/melkjug/templates/reader/email_link.mako 2008-07-14 21:06:50 UTC (rev 1043)
@@ -21,7 +21,12 @@
          <label for="note">Note (optional)</label>
          <textarea name="note" id="note"></textarea>

-          ## XXX spam protection???
+          ## display a captcha if the user is not logged in
+          % if c.security.is_anonymous():
+          <input type="hidden" name="recaptcha_marker_field" />
+          ${h.display_captcha()}
+          <div id="recaptcha_div"></div>
+          % endif
          <ul class="form-buttons">
              <li><a href="#" class="ok-button">Send</a></li>
              <li><a href="#" class="cancel-button">Cancel</a></li>

Modified: melkjug/trunk/setup.py
===================================================================
--- melkjug/trunk/setup.py      2008-07-14 20:48:35 UTC (rev 1042)
+++ melkjug/trunk/setup.py      2008-07-14 21:06:50 UTC (rev 1043)
@@ -44,6 +44,7 @@
                      'minibrain',
                      'melk.selection',
                      'BeautifulSoup',
+                      'recaptcha-client',
    ],
    dependency_links=[
      "https://svn.openplans.org/melk/eggs/links.html";,



--
To unsubscribe send an email with subject "unsubscribe" to [EMAIL PROTECTED] . Please contact [EMAIL PROTECTED] for questions.



!DSPAM:4013,487ce43945493668746562!

Reply via email to