<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>MakerLab Blog &#187; kissing!</title>
	<atom:link href="http://blog.makerlab.org/tag/kissing/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.makerlab.org</link>
	<description>Go on, be curious</description>
	<lastBuildDate>Wed, 24 Aug 2011 19:34:30 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.6</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>@kissmehere and there! and there! and there! Kissing Booths FTW!</title>
		<link>http://blog.makerlab.org/2009/04/kissmehere_silly_a_new_twitterbot/</link>
		<comments>http://blog.makerlab.org/2009/04/kissmehere_silly_a_new_twitterbot/#comments</comments>
		<pubDate>Mon, 13 Apr 2009 22:19:32 +0000</pubDate>
		<dc:creator>anselm</dc:creator>
				<category><![CDATA[activities]]></category>
		<category><![CDATA[art]]></category>
		<category><![CDATA[cyborgs]]></category>
		<category><![CDATA[happiness]]></category>
		<category><![CDATA[geocode]]></category>
		<category><![CDATA[hearts]]></category>
		<category><![CDATA[kissing!]]></category>
		<category><![CDATA[local]]></category>
		<category><![CDATA[love]]></category>
		<category><![CDATA[twitter]]></category>

		<guid isPermaLink="false">http://blog.makerlab.org/?p=675</guid>
		<description><![CDATA[Last night at <a href="http://twitter.com/makerlab">makerlab</a> we were talking about dating sites a bit - commenting on how strange it was that they didn't leverage social networks.

For fun today I threw a fun idea together as a test of how to make dating more social. It isn't terribly serious but perhaps amusing. I like to combine talk with praxis. Here it is:]]></description>
			<content:encoded><![CDATA[<p>Last night at <a href="http://twitter.com/makerlab">makerlab</a> we were talking about dating sites a bit &#8211; we had some fun thinking about the different ways that we could imagine designing a simple tool for twitter. We decided we wanted it to be really really simple. </p>
<p>Like REALLY REALLY simple.  Like this:</p>
<p><a href="http://twitter.com/kissmehere">twitter.com/kissmehere</a></p>
<p>Kinda like a kiss. Yeah, just like that. Like a kissing booth! JUST like a Kissing Booth!</p>
<div class="wp-caption alignnone" style="width: 466px"><a href="http://farm3.static.flickr.com/2233/2261770914_22a5eb1384.jpg?v=1202860065"><img alt="kisses!" src="http://farm3.static.flickr.com/2233/2261770914_22a5eb1384.jpg?v=1202860065" title="kissing booth" width="456" height="500" /></a><p class="wp-caption-text">kisses!</p></div>
<p>The way this all works is that when you send a message to <a href="http://twitter.com/kissmehere">@kissmehere</a> on twitter and you include the name of some people, it will send a kiss to all those people.  For example:</p>
<p>   @kissmehere go kiss @paigesaez @zephoria @soycamo @semaphoria @anselm</p>
<p>Kissmehere is no prude, you can kiss more than one person at the same time &#8211; or kiss only one person &#8211; it is up to you.</p>
<p>Kissmehere maps your kisses too!</p>
<p><a href="http://kissmehere.makerlab.org/">MakerLab Kiss Map!</a></p>
<div id="attachment_685" class="wp-caption alignnone" style="width: 310px"><a href="http://kissmehere.makerlab.org"><img src="http://blog.makerlab.org/wp-content/uploads/2009/04/mozilla-firefox-300x227.jpg" alt="@kissmehere" title="mozilla-firefox" width="300" height="227" class="size-medium wp-image-685" /></a><p class="wp-caption-text">@kissmehere</p></div>
<p>How did I build it? This is just a riff on the same twitter code I have been using before.  There are a few twists.  First we have some pre-amble and we have a geocoding engine &#8211; thanks MetaCarta!!!:</p>
<div style="padding:20px;border:3px dotted green">
<pre>

require 'rubygems'
require 'dm-core'
require 'twitter'
require 'net/smtp'
require 'net/http'
require 'uri'
require 'json'
require 'dm-core'

#
# passwords
#
TWITTER_USER_NAME = "kissmehere"
TWITTER_PASSWORD = ""
METACARTA_USERID = ""
METACARTA_PASSWORD = ""
METACARTA_KEY = ""

#
# a very very nice metacarta utility to brute force discover location in text
#
def geolocate(location)
  location = URI.escape(location, Regexp.new("[^#{URI::PATTERN::UNRESERVED}]"))
  # location = URI.escape(location)
  host = "ondemand.metacarta.com"
  path = "/webservices/GeoTagger/JSON/basic?version=1.0.0"
  path = "#{path}&amp;doc=#{location}"
  data = {}
  begin
    req = Net::HTTP::Get.new(path)
    req.basic_auth METACARTA_USERID, METACARTA_PASSWORD
    http = Net::HTTP.start(host)
    #if response.is_a?(Net::HTTPSuccess)
      response = http.request(req)
      puts response.body
      data = JSON.parse(response.body)
    #end
  rescue Timeout::Error
    # DO SOMETHING WISER
    return 0,0
  rescue
    return 0,0
  end
  begin
    lat = data["Locations"][0]["Centroid"]["Latitude"]
    lon = data["Locations"][0]["Centroid"]["Longitude"]
    return lat,lon
  rescue
  end
  return 0,0
end</pre>
</div>
<p>We have a simple data model as usual to track our activity&#8230; again using datamapper which is a favorite of mine.</p>
<div style="padding:20px;border:3px dotted green">
<pre>

#
# Only send out 10 tweets at a time
#
twittercap = 10

#
# Grab a database
#
DataMapper.setup(:default, {
    :adapter  =&gt; 'postgres',
    :database =&gt; "kissmehere",
    :username =&gt; '',
    :password =&gt; '',
    :host     =&gt; 'localhost'
})

#
# here is our schema
#
class Kiss
  include DataMapper::Resource
  property :id,          Integer, :serial =&gt; true
  property :provenance,  Text
  property :uuid,        Text
  property :title,       Text
  property :link,        Text
  property :description, Text
  property :screenname,  Text
  property :userid,      Text
  property :location,    Text
  property :lat,         Float
  property :lon,         Float
  property :secret,      Integer, :default =&gt; 0
  property :friended,    Integer, :default =&gt; 0
  property :kissed_at,   DateTime
  property :created_at,  DateTime
end
</pre>
</div>
<p><br/></p>
<p>We have the usual twitter gem code to peek at the twitter state. I am really starting to wonder how the heck twitter even stays up with the amount of traffic it is getting&#8230;  In any case mine is not to worry but to do!</p>
<p><br/></p>
<div style="padding:20px;border:3px dotted green">
<pre>
#
# Remember kiss requests
#
twitter = Twitter::Base.new(TWITTER_USER_NAME, TWITTER_PASSWORD )
twitter.replies().each do |twit|
  uuid = "#{twit.id}"
  kiss = Kiss.first(:provenance =&gt; "twitter", :uuid =&gt; uuid)
  next if kiss
  secret = 0
  secret = 1 if twit.text[/ secret/] != nil
  lat = 0
  lon = 0
  if twit.user.location &amp;&amp; twit.user.location.length &gt; 1
    lat,lon = geolocate(twit.user.location)
  end
  kiss = Kiss.create(
             :provenance =&gt; "twitter",
             :uuid =&gt; uuid,
             :title =&gt; twit.text,
             :link =&gt; nil,
             :description =&gt; nil,
             :screenname =&gt; twit.user.screen_name,
             :userid =&gt; twit.user.id,
             :location =&gt; twit.user.location,
             :lon =&gt; lon,
             :lat =&gt; lat,
             :secret =&gt; secret
          )
  kiss.save
  puts "Saved a kiss on twitter! #{kiss.userid} #{kiss.title} #{kiss.lat} #{kiss.lon}"
end
</pre>
</div>
<p><br/><br />
Next we want to respond to kisses in an intelligent way; telling everybody, friending new friends and all that kind of fun stuff.<br />
<br/></p>
<div style="padding:20px;border:3px dotted green">
<pre>

#
# Pass new kisses onwards ( only do twittercaps worth )
#
@kisses = Kiss.all(:order =&gt; [:created_at.desc],
                   :limit =&gt; twittercap,
                   :kissed_at =&gt; nil
              ).each do |kiss|

  # tease each kiss apart for multiple receivers
  kisses = kiss.title.scan(/\@\w+/)
  kisses.each do |luckyduck|
    next if luckyduck == "@kissmehere"
    if kiss.secret == 0
      kiss.link = "http://twitter.com/#{kiss.screenname}/statuses/#{kiss.uuid}"
      gossip = "#{luckyduck} got a kiss from @#{kiss.screenname} - see #{kiss.link} "
      # if kiss.lat != 0 &amp;&amp; kiss.lon != 0
      #  gossip = " - #{gossip} near #{kiss.location}"
      # end
    else
      kiss.link = nil
      gossip = "@#{luckyduck} got a kiss from an anonymous admirer!"
    end
    kiss.description = gossip
    result = twitter.post(gossip)
    puts "Told everybody #{result} of #{gossip}"
  end
  if kisses.length == 0
    puts "No love from #{kiss.screenname}"
  end
  kiss.kissed_at = DateTime.now
  kiss.save

  # friend everybody - could improve this
  begin
    twitter.create_friendship(kiss.screenname)
  rescue
  end
  kisses.each do |luckyduck|
    begin
      #if twitter.friendship_exists(TWITTER_USER_NAME,luckyduck)
      twitter.create_friendship(luckyduck)
    rescue
    end
  end

end
</pre>
</div>
<p>Finally we write out an RSS feed for Google Maps &#8211; thanks @ajturner for the quick tip.  I wasn&#8217;t able to get ruby rss maker to do anything useful such as allow me to specify custom namespaces for the geo:lat and geo:long attributes so I wrote everything by hand!  By doing this we can then make a map page which has all the kisses on it just for fun.  I guess I won&#8217;t show this blob because it breaks the layout engine in wordpress&#8230;  I will link to the original file however at <a href="http://kissmehere.makerlab.org/agent.txt">agent.txt</a></p>
<p>That&#8217;s it.  Have fun out there in the twitter verse!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.makerlab.org/2009/04/kissmehere_silly_a_new_twitterbot/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

