<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0"><channel><atom:link rel="hub" href="http://tumblr.superfeedr.com/" xmlns:atom="http://www.w3.org/2005/Atom"/><description></description><title>Leon's notes</title><generator>Tumblr (3.0; @leondu)</generator><link>http://leondu.com/</link><item><title>Paypal on Rails, gotchas and tricks</title><description>&lt;p&gt;With the help of &lt;a href="https://github.com/Shopify/active_merchant"&gt;Activemerchant&lt;/a&gt;, integrate Paypal into Rails is really easy, yet there are some gotchas you should be aware of.&lt;/p&gt;
&lt;ol&gt;&lt;li&gt;The original ‘_ext-enter’ for ‘cmd’ is deprecated&lt;/li&gt;
&lt;li&gt;If you are to submit multiple line items, the ‘cmd’ value must be ‘_cart’, then you can use item_name_x/quantity_x/amount_x as the line items details&lt;/li&gt;
&lt;li&gt;The built in helper in &lt;a href="https://github.com/Shopify/active_merchant"&gt;Activemerchant&lt;/a&gt; do not provide the multiple line mapping, I’ved add one myself, the &lt;strong&gt;line_items&lt;/strong&gt; method.&lt;br/&gt;then you can use it in your view like 
&lt;pre class="sh_ruby"&gt;- service.line_items line_items&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;The shipping cost to whole cart should be set in ‘handling_cart’, instead of ‘shipping’ as suggested in Paypal’s document, this is really bad.&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;See the comments you can understand how the customized helper works&lt;/p&gt;
&lt;pre class="sh_ruby"&gt;# We changed this paypal helper provided by activemerchant because:
# 
# 1) change the initializer to meet our need, for example, 
#   to submit mulitple items, the 'cmd' value should be '_cart',
#   see here: &lt;a href="https://www.x.com/thread/43442"&gt;https://www.x.com/thread/43442&lt;/a&gt;
#   and here: &lt;a href="https://www.x.com/docs/DOC-1340"&gt;https://www.x.com/docs/DOC-1340&lt;/a&gt;
#   the original '_ext-enter' for 'cmd' is deprecated
# 
# 2) add the line_items method to prepare details for each line item
# 
# 3) accroding to &lt;a href="https://www.x.com/thread/39507"&gt;https://www.x.com/thread/39507&lt;/a&gt;
#   if you want to pass shpping cost for the whole cart, 
#   you should set up the 'handling_cart' instead of 'shipping' as documented
#   mapping :shipping, 'handling_cart'

module ActiveMerchant #:nodoc:
  module Billing #:nodoc:
    module Integrations #:nodoc:
      module Paypal
        class Helper &lt; ActiveMerchant::Billing::Integrations::Helper
          def initialize(order, account, options = {})
            super
            # indecate we are using thirdparty shopping cart
            add_field('cmd', '_cart')
            add_field('upload', '1')


            add_field('no_shipping', '1')
            add_field('no_note', '1')
            add_field('charset', 'utf-8')
            add_field('address_override', '0')
            add_field('bn', application_id.to_s.slice(0,32)) unless application_id.blank?
          end
          
          # pass the shipping cost for whole cart
          mapping :shipping, 'handling_cart'

          # mapping header image
          mapping :cpp_header_image, 'cpp_header_image'

          # add line item details, note the amount_x 
          # should be price instead of line total   
          def line_items(items = [])
            items.each_with_index do |line, index|
              add_field("item_name_#{index+1}", line.item.item_name)
              add_field("amount_#{index+1}", line.price.value_without_unit)
              add_field("quantity_#{index+1}", line.quantity)
            end
          end          

        end
      end
    end
  end
end
&lt;br/&gt;&lt;/pre&gt;
&lt;p&gt;Also, you need to create your own &lt;strong&gt;payment_service_for&lt;/strong&gt;( I named it &lt;strong&gt;paypal_payment_service_for&lt;/strong&gt;) to support encrypt data before sending to paypal, because the built in payment_service_for in Activemerchant does not suppor that&lt;/p&gt;
&lt;pre class="sh_ruby"&gt;require_library_or_gem 'action_pack'

module ActiveMerchant #:nodoc:
  module Billing #:nodoc:
    module Integrations #:nodoc:
      module ActionViewHelper
        def paypal_payment_service_for(order, account, options = {}, &amp;proc)
          raise ArgumentError, "Missing block" unless block_given?

          integration_module = ActiveMerchant::Billing::Integrations.const_get(options.delete(:service).to_s.camelize)

          encrypt = options.delete(:encrypt)

          result = []
          result &lt;&lt; form_tag(integration_module.service_url, options.delete(:html) || {})

          service_class = integration_module.const_get('Helper')
          service = service_class.new(order, account, options)

          result &lt;&lt; capture(service, &amp;proc)

          if encrypt
            paypal_params = { :cert_id =&gt; cert_id }
            service.form_fields.each do |field, value|
              paypal_params.merge!(field =&gt; value)
            end

            result &lt;&lt; hidden_field_tag(:cmd, "_s_xclick")
            result &lt;&lt; "\n"
            result &lt;&lt; hidden_field_tag(:encrypted, encrypt_for_paypal(paypal_params))
          else
            service.form_fields.each do |field, value|
              result &lt;&lt; hidden_field_tag(field, value)
            end
          end

          result &lt;&lt; ''
          result= result.join("\n")

          concat(result.respond_to?(:html_safe) ? result.html_safe : result)
          nil
        end

        # encrypt values
        def encrypt_for_paypal(values)
          unless Settings.payment.paypal.test_mode
            app_cert_pem = File.read("#{Rails.root}/config/paypal/paypal-pubcert.pem")
            app_key_pem = File.read("#{Rails.root}/config/paypal/paypal-prvkey.pem")
            paypal_cert_pem = File.read("#{Rails.root}/config/paypal/paypal-cert.pem")
          else
            app_cert_pem = File.read("#{Rails.root}/config/paypal/paypal-sandbox-pubcert.pem")
            app_key_pem = File.read("#{Rails.root}/config/paypal/paypal-sandbox-prvkey.pem")
            paypal_cert_pem = File.read("#{Rails.root}/config/paypal/paypal-sandbox-cert.pem")
          end

          signed = OpenSSL::PKCS7::sign(OpenSSL::X509::Certificate.new(app_cert_pem), OpenSSL::PKey::RSA.new(app_key_pem, ''), values.map { |k, v| "#{k}=#{v}" }.join("\n"), [], OpenSSL::PKCS7::BINARY)
          OpenSSL::PKCS7::encrypt([OpenSSL::X509::Certificate.new(paypal_cert_pem)], signed.to_der, OpenSSL::Cipher::Cipher::new("DES3"), OpenSSL::PKCS7::BINARY).to_s.gsub("\n", "")
        end

        def cert_id
          Settings.payment.paypal.certificate_id
        end
      end
    end
  end
end
&lt;/pre&gt;</description><link>http://leondu.com/post/8772680776</link><guid>http://leondu.com/post/8772680776</guid><pubDate>Thu, 11 Aug 2011 04:57:18 -0400</pubDate></item><item><title>Hello Lion!
到目前为止的问题：
git：command not...</title><description>&lt;img src="http://27.media.tumblr.com/tumblr_lpa98sAQaI1qklpzyo1_500.png"/&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;Hello Lion!&lt;/p&gt;
&lt;p&gt;到目前为止的问题：&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;git：command not found，重新下载了git的安装包安装&lt;/li&gt;
&lt;li&gt;imagemagick好像坏了，所有相关的cuke feature都失败了&lt;/li&gt;
&lt;li&gt;打开itunes提示说itunes的lib是新版本的itunes创建的，需要下载新版本itunes才能打开，wtf？&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;好处：&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;细节比以前漂亮了很多，窗口出现、消失时的效果，窗口的圆角等等&lt;/li&gt;
&lt;li&gt;Mail!!!当初没买sparrow是正确的，太好用了！&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;其他：&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;滚动方向基本适应&lt;/li&gt;
&lt;li&gt;输入法有改进，不过既然QIM都免费了，这个意义就不大了&lt;/li&gt;
&lt;/ul&gt;</description><link>http://leondu.com/post/8371259647</link><guid>http://leondu.com/post/8371259647</guid><pubDate>Tue, 02 Aug 2011 00:17:16 -0400</pubDate></item><item><title>
2011.07.24 珠三角技术沙龙HTML5专场, a set on...</title><description>&lt;img src="http://29.media.tumblr.com/tumblr_lou7yzzGmZ1qklpzyo1_r1_500.jpg"/&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;&lt;a title="P1110466" href="http://www.flickr.com/photos/leondu/5969659410/in/set-72157627267280884/"&gt;&lt;img width="200" src="http://farm7.static.flickr.com/6134/5969659410_edbabe7d08_m.jpg" alt="P1110466"/&gt;&lt;/a&gt;&lt;a title="P1110467" href="http://www.flickr.com/photos/leondu/5969102459/in/set-72157627267280884/"&gt;&lt;img width="200" src="http://farm7.static.flickr.com/6121/5969102459_b999aa3188_m.jpg" alt="P1110467"/&gt;&lt;/a&gt;&lt;a title="P1110468" href="http://www.flickr.com/photos/leondu/5969103161/in/set-72157627267280884/"&gt;&lt;img width="200" src="http://farm7.static.flickr.com/6026/5969103161_438e6ebf31_m.jpg" alt="P1110468"/&gt;&lt;/a&gt;&lt;a title="P1110469" href="http://www.flickr.com/photos/leondu/5969661078/in/set-72157627267280884/"&gt;&lt;img width="200" src="http://farm7.static.flickr.com/6027/5969661078_98bfb8a813_m.jpg" alt="P1110469"/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.flickr.com/photos/leondu/sets/72157627267280884/"&gt;2011.07.24 珠三角技术沙龙HTML5专场&lt;/a&gt;, a set on Flickr.&lt;/p&gt;
&lt;p&gt;一些感受：&lt;/p&gt;
&lt;ol&gt;&lt;li&gt;Web仍然有很强的生命力。虽然最近有一波波的Web已死的言论，但是正如@DHH所说，Web是十年来沉淀下证明最有生命力的技术，虽然一再有人宣称它已死，但事实证明它的生命力超乎想象。随着HTML5为它增加更加强大的表达能力，Web应该会焕发更强的光彩。&lt;/li&gt;
&lt;li&gt;HTML5目前还处在有限使用阶段。主要的障碍来自浏览器支持不统一、自身实现的效率等等，不过可以在考虑兼容性的情况下选择局部选用。这方面今天qqmail和网易都给出了很好的例子，尤其是网易使用HTML5来实现全站变色这个“神奇”的需求的例子，全场都响起了会心的笑声和掌声。&lt;/li&gt;
&lt;li&gt;从上海专程该来的google市场经理（忘记名字），则从市场的角度给大家上了一课，非常的有用。跳出技术的禁锢，从产品和市场的角度来重新审视这个世界，相信大家都会有新发现。今天他提到的两个例子都非常有说服力：一个是每天新增50w下载的一个团队，本身并不是特别在意这些下载量，而是关心活跃用户数和用户反馈，把所有一星反馈逐条研读，确实存在的问题一定改进；一个是在市场已经100多款闹钟的情况下，依然选择闹钟作为产品方向，并且做到单款产品的下载量就达到“北京白领中高收入水平”。这说明只要用心打造满足用户需要、高质量的产品，就无须刻意追求市场，相信好产品自己会召唤用户。&lt;/li&gt;
&lt;li&gt;演讲技巧。今天感觉网易邮箱的张极的演讲最好，讲解深入浅出，slide也做的非常的生动。而个别演讲人，技术水准应该是毋庸置疑的，但讲起来节奏拖沓，例子也准备的不充分，看来演讲也是一门艺术，要修炼才行，不能茶壶里装饺子，肚里有货，嘴里倒不出阿。&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;流水账记完，看变形金刚去咯 ;-)&lt;/p&gt;
&lt;p&gt;ps, 更多信息请前往珠三角技术沙龙官方网站： &lt;a title="techparty" href="http://techparty.org"&gt;techparty.org&lt;/a&gt;&lt;/p&gt;</description><link>http://leondu.com/post/7999209269</link><guid>http://leondu.com/post/7999209269</guid><pubDate>Sun, 24 Jul 2011 08:28:00 -0400</pubDate><category>html5 techparty</category></item><item><title>Test basic auth with Cucumber</title><description>&lt;p&gt;The senario&lt;/p&gt;
&lt;pre class="sh_ruby"&gt;Scenario: admin dashboard
  Given I perform HTTP authentication as "admin/secret"
    And I am on "/admin"
  Then I should see "Dashboard"
&lt;/pre&gt;
&lt;p&gt;The step&lt;/p&gt;
&lt;pre class="sh_ruby"&gt;When /^I perform HTTP authentication as "([^\"]*)\/([^\"]*)"$/ do |name, password|
  if page.driver.respond_to?(:basic_auth)
    page.driver.basic_auth(name, password)
  elsif page.driver.respond_to?(:basic_authorize)
    page.driver.basic_authorize(name, password)
  elsif page.driver.respond_to?(:browser) &amp;&amp; page.driver.browser.respond_to?(:basic_authorize)
    page.driver.browser.basic_authorize(name, password)
  else
    raise "I don't know how to log in!"
  end
end
&lt;/pre&gt;
&lt;p&gt;from the discussion here:&lt;br/&gt;&lt;a href="ref:http://stackoverflow.com/questions/4329985/http-basic-auth-for-capybara"&gt;&lt;a href="http://stackoverflow.com/questions/4329985/http-basic-auth-for-capybara"&gt;http://stackoverflow.com/questions/4329985/http-basic-auth-for-capybara&lt;/a&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;When using selenium driver, according to &lt;a href="http://wiki.openqa.org/display/SEL/Selenium+Core+FAQ#SeleniumCoreFAQ-HowdoIuseSeleniumtologintositesthatrequireHTTPbasicauthentication%28wherethebrowsermakesamodaldialogaskingforcredentials%29%3F"&gt;their wiki&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;How do I use Selenium to login to sites that require HTTP basic authentication (where the browser makes a modal dialog asking for credentials)?&lt;/p&gt;
&lt;p&gt;Use a username and password in the URL, as described in RFC 1738:&lt;/p&gt;
&lt;p&gt;open  http://myusername:myuserpassword@myexample.com/blah/blah/blah&lt;/p&gt;
&lt;p&gt;Note that on Internet Explorer this won’t work, since Microsoft has disabled usernames/passwords in URLs in IE. However, you can add that functionality back in by modifying your registry, as described in the linked KB article. Set an “iexplore.exe” DWORD to 0 in HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_HTTP_USERNAME_PASSWORD_DISABLE.&lt;/p&gt;
&lt;p&gt;If you don’t want to modify the registry yourself, you can always just use Selenium Remote Control, which automatically sets that that registry key for you as of version 0.9.2.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Also the &lt;a href="https://github.com/jnicklas/capybara/issues/237"&gt;discussion on github&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;iast opened this issue January 02, 2011&lt;/p&gt;
&lt;p&gt;HTTP Basic Authentication for Selenium driver&lt;/p&gt;
&lt;p&gt;No milestone&lt;/p&gt;
&lt;p&gt;No one is assigned&lt;/p&gt;
&lt;p&gt;Hi, I’m using Cucumber+Capybara+Selenium to test the app that relies on HTTP Basic Authentication. There is a way to use this kind of auth by calling page.driver.basic_authorize(user, pass) method.&lt;/p&gt;
&lt;p&gt;But when I mark the Scenario with @javascript tag (enabling Selenium driver) I get an error: undefined method `basic_authorize’ for #Capybara::Driver::Selenium:0x000000041ea880 (NoMethodError)&lt;/p&gt;

&lt;p&gt; jnicklas commented&lt;/p&gt;
&lt;p&gt;January 09, 2011&lt;/p&gt;
&lt;p&gt;You’re accessing a private API and calling through to a method which is specific to the rack-test driver. Selenium doesn’t support basic authentication other than through the URL afaik, which is why we don’t have an API for it in Capybara in the first place.&lt;/p&gt;


&lt;p&gt; iast commented&lt;/p&gt;
&lt;p&gt;January 12, 2011&lt;/p&gt;
&lt;p&gt;It’s a pity. It would be nice to have a cross-driver way of using basic auth.&lt;/p&gt;
&lt;p&gt;But, anyway, I solved the problem in my case by using URL to identify current user and session to persist current user between requests (when Selenium is active only).&lt;/p&gt;
&lt;p&gt;Thanks for the reply.&lt;/p&gt;

&lt;/blockquote&gt;
&lt;p&gt;The only way would be something like “http://myusername:myuserpassword@myexample.com/blah/blah/blah”&lt;/p&gt;</description><link>http://leondu.com/post/7677016950</link><guid>http://leondu.com/post/7677016950</guid><pubDate>Sat, 16 Jul 2011 00:22:00 -0400</pubDate></item><item><title>iTerm2</title><description>&lt;p&gt;&lt;span&gt; &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;早上在twitter看到：&lt;/p&gt;
&lt;p&gt;&lt;span class="tweet-user-name"&gt;“&lt;a title="Robin Lu" href="http://twitter.com/#!/robinlu"&gt;robinlu&lt;/a&gt; &lt;/span&gt;&lt;span&gt;iTerm2 发布1.0了，最近一直在用。我比较喜欢的功能主要是可分割窗口，窗口内容可搜索。”&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;下载试了一下，非常惊喜，可分割窗口和搜索功能确实很实用，感谢robinlu的推荐。&lt;/p&gt;
&lt;p&gt;more: &lt;a href="http://www.iterm2.com/"&gt;&lt;a href="http://www.iterm2.com/"&gt;http://www.iterm2.com/&lt;/a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Update(2011-07-16): &lt;/strong&gt;iTem2 到行首和行尾的快捷键是 fn + 左右方向键，和terminal中默认的fn + shift + 左右方向键不同。&lt;/p&gt;</description><link>http://leondu.com/post/7367875442</link><guid>http://leondu.com/post/7367875442</guid><pubDate>Thu, 07 Jul 2011 22:44:00 -0400</pubDate></item></channel></rss>

