On Thu, Aug 24, 2006 at 04:23:30PM -0600, Tieg Zaharia
wrote:> I''m using mousehole for the first time today (love the artwork,
btw) and I
> seem to be having problems with Camping and Markaby. When I go to the Apps
> page I get:
Heya, welcome to you, Tieg Z.  There''s a whole separate mousehole list
over here: <http://rubyforge.org/mailman/listinfo/mousehole-scripters>
For interested parties, MouseHole is Camping + Mongrel + Hpricot, all inside a
web proxy.  So you can do Greasemonkey-like thing with your Camping apps.
<http://code.whytheluckystiff.net/mouseHole/>
> Camping Problem! MouseHole::Controllers::RApps.GET TypeError
> /Users/tzaharia/Sites/mouseHole/lib/mouseHole/views.rb:78:in `+'':
can''t
> convert String into Array:bla bla bla...
This indicates an old version of Markaby.  Update both Camping and Markaby,
if you will.
  gem install camping --source code.whytheluckystiff
  gem install markaby --source code.whytheluckystiff
> Also, this is a dumb quesiton, but where do you put scripts in mousehole? I
> noticed the three scripts in /samples weren''t listed in apps.
In ~/.mouseHole.  MouseHole version 1 scripts won''t work, so
I''m attaching two
examples of MouseHole 2 scripts.  Also, Camping scripts will work as well.
> Also, if anyone knows of another way to setup a really simple proxy that
can
> proxy https pages, I would be grateful to know how (as far as I know you
> can''t do this with webrick http proxy),
You can do it with WEBrick or Mongrel.  In fact, WEBrick has an http proxying
class.  I''m attaching the simple proxy I used as a basis of MouseHole
on
Mongrel.  It''s kind of hacky, but.
_why
-------------- next part --------------
require ''resolv-replace''
require ''rubygems''
require ''logger''
require ''mongrel''
require ''mongrel/camping''
require ''mh2''
# require ''net/http''
# require ''net/httpio''
module MouseHole
class ProxyHandler < Mongrel::HttpHandler
    def initialize
      @logger = Logger.new STDOUT
    end
    def proxy_auth(req, res)
      if proc = @config[:ProxyAuthProc]
        proc.call(req, res)
      end
      req.header.delete("proxy-authorization")
    end
    # Some header fields shuold not be transfered.
    HopByHop = %w( connection keep-alive proxy-authenticate upgrade
                   proxy-authorization te trailers transfer-encoding )
    ShouldNotTransfer = %w( set-cookie proxy-connection )
    def split_field(f) f ? f.split(/,\s+/).collect{|i| i.downcase } : [] end
    def choose_header(src, dst)
      connections = split_field(src[''connection''])
      src.each{|key, value|
        key = key.downcase
        if HopByHop.member?(key)          || # RFC2616: 13.5.1
           connections.member?(key)       || # RFC2616: 14.10
           ShouldNotTransfer.member?(key)    # pragmatics
          # @logger.debug("choose_header: `#{key}:
#{value}''")
          next
        end
        dst[key.capitalize] = value
      }
    end
    # Net::HTTP is stupid about the multiple header fields.
    # Here is workaround:
    def set_cookie(src, dst)
      if str = src[''set-cookie'']
        cookies = []
        str.split(/,\s*/).each{|token|
          if /^[^=]+;/o =~ token
            cookies[-1] << ", " << token
          elsif /=/o =~ token
            cookies << token
          else
            cookies[-1] << ", " << token
          end
        }
        dst.cookies.replace(cookies)
      end
    end
    def set_via(h)
      # if @config[:ProxyVia]
      #   if  h[''via'']
      #     h[''via''] << ", " << @via
      #   else
      #     h[''via''] = @via
      #   end
      # end
    end
    def proxy_uri(req, res)
      @config[:ProxyURI]
    end
    def process(request, response)
        proxy_host, proxy_port = *[]
        env = request.params.inject({}) do |hsh, (k, v)|
            hsh[k.downcase.gsub(''_'',''-'')] =
v; hsh
        end
        path =
env[''path-info''].gsub("//#{env[''server-name'']}",'''')
            
        header = {}
        choose_header(env, header)
        set_via(header)
        def response.send_status
          if not @status_sent
            @socket.write("HTTP/1.1 %d %s\r\n" % [status,
Mongrel::HTTP_STATUS_CODES[@status]])
            @status_sent = true
          end
        end
        begin
            @logger.debug("start HTTP:
http:#{env[''path-info'']}")
            http =
MH2::HTTP.new("http:#{env[''path-info'']}")
            http.headers = header
            http.request(env[''request-method'']) do |resin|
                choose_header(resin.headers, response.header)
                set_cookie(resin.headers, response.header)
                set_via(response.header)
                response.status = resin.status
                response.header[''Proxy-connection''] =
"close"
                response.header[''Connection''] =
"close"
                response.send_status
                response.send_header
                resin.read_body do |chunk|
                    response.write(chunk)
                end
            end
        rescue => err
            @logger.debug("#{err.class}: #{err.message};
#{err.backtrace}")
            # raise Net::HTTPServiceUnavailable, err.message
        end
        @logger.debug("end HTTP:
http:#{env[''path-info'']}")
    end
end
def self.serve
    # Use the Configurator as an example rather than Mongrel::Camping.start
    Mongrel::Const.const_set :REQUEST_PATH, "REQUEST_URI".freeze
    config = Mongrel::Configurator.new :host => "0.0.0.0" do
        listener :port => 3704 do
            uri "http:", :handler => ProxyHandler.new
            trap("INT") { stop }
            run
        end
    end
    config.join
end
end
if __FILE__ == $0
    MouseHole.serve
end
-------------- next part --------------
# Simple MouseHole 2.0 script, based on the Greasemonkey script
# by Adam Vandenberg.  His is GPL, so this is GPL.
# <http://adamv.com/dev/grease/scripts/comicalt.user.js>
class ComicAlt < MouseHole::App
    name "Comics Alt Text" 
    namespace "http://adamv.com/greases/" 
    description ''Shows the "hover text" for some comics on
the page''
    + url("http://achewood.com/*")
    + url("http://*.achewood.com/*")
    + url("http://qwantz.com/*")
    + url("http://*.qwantz.com/*")
    + url("http://asofterworld.com/*")
    + url("http://*.asofterworld.com/*")
    + url("http://drmcninja.com/*")
    + url("http://www.wondermark.com/*")
    version "0.3" 
    COMICS = {
        "achewood" =>
''img[@src^="/comic.php?date="]'',
        "qwantz" =>
''img[@src^="http://www.qwantz.com/comics/"]'',
        "asofterworld" => ''td/center/img'',
        "drmcninja" =>
''img[@src^="/issue"]'',
        "wondermark" =>
''img[@src^="/comics/"]''
    }
    # the pages flow through here
    def rewrite(page)
        whichSite, xpath = 
            COMICS.detect do |key,|
                page.location.host.include? key
            end
        return unless whichSite
        comic = document/xpath
        return unless comic
        if comic.attributes[''title'']
            div = Element.new ''div''
            div.attributes[''className''] =
''msg''
            div.text = "(#{ comic.attributes[''title'']
})"
            comic.parent.insert_after comic, div
        end
    end
end
-------------- next part --------------
class LinkHints < MouseHole::App
    name ''Link Hints''
    namespace ''http://dysbiote.blogspot.com/mousehole''
    description "inserts the link''s host name after each
link"
    version ''0.1''
    # very obnoxious on these sites
    - url(%r{^https?://www.google.com/})
    # slightly less obnoxious everywhere else
    + url(%r{^https?://.+})
    def absolute_href?(href)
        href && href.strip =~ %r{^(http:|https:|ftp:)//.+}
    end
    def rewrite(page)
        document.search(''//a[@href]'') do |link|
            href = URI(link.attributes[''href'']) rescue nil
            next unless href && href.host && href.host !=
page.location.host
            span = REXML::Element.new ''span''
            span.attributes[''style''] =
''font-size:8px''
            span.text = "[#{href.host}]"
            link.parent.insert_after link, span
        end
    end
end