Code Monkey home page Code Monkey logo

grackle's People

Contributors

akahn avatar earth2marsh avatar hayesdavis avatar jcsalterego avatar mando avatar robrasmussen avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

grackle's Issues

extra /users gets added if call attempt is made, but fails because variable wasn't set prior

pretty odd.

u = client.users.show? :user_id => x
NameError: undefined local variable or method `x' for #<Object:0x389a0 @controller=#ApplicationController:0x2313e20>
from (irb):8
x = 12
=> 12

u = client.users.show? :user_id => x
Grackle::TwitterError: get http://twitter.com/users/users/show.json?user_id=12 => 404: {"request":"/users/users/show.json?user_id=12","error":"Not found"}
from /Users/damon/rails/tf/vendor/gems/hayesdavis-grackle-0.1.4/lib/grackle/client.rb:240:in handle_error_response' from /Users/damon/rails/tf/vendor/gems/hayesdavis-grackle-0.1.4/lib/grackle/client.rb:218:inprocess_response'
from /Users/damon/rails/tf/vendor/gems/hayesdavis-grackle-0.1.4/lib/grackle/client.rb:198:in call_with_format' from /Users/damon/rails/tf/vendor/gems/hayesdavis-grackle-0.1.4/lib/grackle/client.rb:142:inmethod_missing'
from (irb):10
u = client.users.show? :user_id => x
=> #<Grackle::TwitterStruct....

It seems that because x wasn't set the first time through, the /users part of the path gets added twice.

Handle use of convenience methods for dates

When I'm calling the search API with grackle (eg. from a rails app), I should be able to do this:
results = client.search?(:from => 'Ben_Hall', :since => 1.day.ago, :rpp => 20)
At the moment I am forced to do this:
results = client.search?(:from => 'Ben_Hall', :since => 1.day.ago.to_s(:sane), :rpp => 20)
having already added a "sane" date format to rails that uses "%Y-%m-%d"

Lee.

Provide Hash Style Access To Attributes

TwitterStructs returned by requests have methods for each attribute returned. It would also be nice to be able to reference these attributes using strings in a hash-style syntax like

res = client.users.show? :screen_name=>'hayesdavis'
res['screen_name'] #returns hayesdavis

This would be especially useful for the trend methods from the Search API since they include attributes names that are actually timestamps. The only way to get to those now is to use send to do a method invocation.

Not able to get retweets count

Hi,
I am using the following query to fetch retweets count from API, but not getting any value.

@client = Grackle::Client.new(:auth {:type=>:oauth,:consumer_key=>consumer_key,:consumer_secret=>consumer_secret,:token=>'xxxxxxxxxxxxx',:token_secret=>'xxxxxxxxxxxxxxxxxx'})

@client.statuses.retweets_of_me.json? :screen_name=> profile_name, :include_entities => true,:page=> retweet_page, :count => 100

output : Grackle::TwitterError: get http://api.twitter.com/1/users/statuses/retweets_of_me.json?screen_name=xxxxxx&include_entities=true&page=1&count=100 => 404: {"errors":[{"message":"Sorry, that page does not exist","code":34}]}

Is there is any change to the retweet method?

grackle depends on mime-types >= 0

I'm preparing mime-types 2.0 for release, and it has some breaking API changes (not for most uses, but some esoteric features). The most important API change is that mime-types 2.0 no longer supports Ruby 1.8.

If this matters, the gemspec needs to be changed from >= 0 to ~> 1.16.

Grackle::TwitterError: Unable to decode response: 618: unexpected token at 'false'

Sometimes the twitter api simply returns true/fase

/opt/ruby-enterprise-1.8.6-20090520/lib/ruby/gems/1.8/gems/hayesdavis-grackle-0.1.2/lib/grackle/client.rb:224:in `process_response'

/opt/ruby-enterprise-1.8.6-20090520/lib/ruby/gems/1.8/gems/hayesdavis-grackle-0.1.2/lib/grackle/client.rb:197:in `call_with_format'

/opt/ruby-enterprise-1.8.6-20090520/lib/ruby/gems/1.8/gems/hayesdavis-grackle-0.1.2/lib/grackle/client.rb:130:in `method_missing'

Provide Better to_s on TwitterStruct That Includes id

Several people have noted that the id method that is often placed on TwitterStructs which represent Tweets, Users, etc is not printed in irb sessions. This has caused some confusion and made people think you can't access the id.

It's not printed in irb because id is normally a method on Object and so OpenStruct (which TwitterStruct extends) doesn't include it in its to_s.

Provide a custom to_s method on TwitterStruct that includes the id.

update_with_media! doesn't work when status is in UTF-8

It works only if status doesn't contain UTF-8 characters.

Grackle::TwitterError => Unexpected failure making request: incompatible character encodings: UTF-8 and ASCII-8BIT

ruby-1.9.3-p448/gems/grackle-0.3.0/lib/grackle/client.rb:266:in `rescue in send_request'
ruby-1.9.3-p448/gems/grackle-0.3.0/lib/grackle/client.rb:254:in `send_request'
ruby-1.9.3-p448/gems/grackle-0.3.0/lib/grackle/client.rb:247:in `call_with_format'

Make json gem optional

On my production environment I cannot compile gems. This makes the json gem requirement problematic, especially since I can use the xml format just fine.

After stripping out the json dependency, Grackle works fine with xml format. i.e. the json dependency would better be optional.

Only SSL allowed

Seems like Twitter no longer accepts non-ssl post's; so the function of ssl could be changed to default.

Use Faster HTTP Library

It's been suggested that the Transport layer use a faster HTTP library like curb or httparty. Right now it uses Net::HTTP.

Permit Sending a Query String on GETs

Both GET (?) and POST (!) method chains only support specifying URL parameters via a hash. This is normally the most useful way to do it but there are certain GET requests where a pre-built string of URL params would be helpful. This is specifically useful when using the "next_page" attribute available in the response to ".search?". There's no way to simply pass that string into the next request to ".search?"

I think the best solution would be to check for a string argument instead of a hash on GET method chain terminators and pass that string to the transport for direct inclusion as URL parameters on the request. I don't see any reason this should work on POSTs.

Provide Access to An Enumerable of Attributes

There's no way to iterate over all attributes in a TwitterStruct returned by a request. Provide a method like attributes which returns an array of only those attributes defined by the parsed response.

Passing in `id` param to a query puts it in the URL rather than as actual param.

The oembed part of the 1.1 Twitter API can take param named id. If it's passed in, then it becomes part of the URL like so:

21] pry(main)> client.statuses.oembed.json? maxwidth: 500, id: "337793757426614272"
Grackle::TwitterError: get http://api.twitter.com/1.1/statuses/oembed/337793757426614272.json?maxwidth=500 => 404: {"errors":[{"message":"Sorry, that page does not exist"...

Unable to decode response: 756 (twitter over capacity)

While running some rspec tests that use grackle, Twitter was over capacity.

The code run:

client = Grackle::Client.new
client.statuses.user_timeline.json? :screen_name => 'vtsatskin', :count => 200, :page => 1

This was the output:

    Grackle::TwitterError:
       Unable to decode response: 756: unexpected token at '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
       <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
         <head>
           <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
           <meta http-equiv="Content-Language" content="en-us" />
           <title>Twitter / Over capacity</title>
           <link href="//si0.twimg.com/sticky/error_pages/favicon.ico" rel="shortcut icon" type="image/x-icon" />

           <style type="text/css">
             /* Page
             ----------------------------------------------- */
             * { border: 0; padding: 0; margin: 0; }
             body{ margin: 10px 0; background:#C0DEED url(//si0.twimg.com/sticky/error_pages/bg-clouds.png) repeat-x; color:#333; font: 12px Lucida Grande, Arial, sans-serif; text-align:center }
             #container { width: 755px; margin: 0 auto; padding: 0px 0; text-align: left; position: relative; }
             #content { width: 100%; margin-top: 0px; float: left; margin-top: 8px; padding-bottom: 15px; background: transparent url(//si0.twimg.com/sticky/error_pages/arr2.gif) no-repeat scroll 25px 0px;}
             .subpage #content .wrapper { background-color: #fff;  padding: 10px 0px 10px 0px; -moz-border-radius: 5px 5px 0 0; -webkit-border-radius: 5px; -webkit-border-bottom-left-radius: 0px; -webkit-border-bottom-right-radius: 0px;}
             .subpage #content h2 { margin: 8px 20px 5px 20px; font: bold 26px Helvetica Neue, Helvetica, Arial, sans-serif; }
             .subpage #content p { margin: 0 20px 10px 20px; color: #666; font-size: 13px;}
             .subpage #content ul { padding-left: 30px; }
             .subpage #content ol, #side ol { padding-left: 30px; }
             a{text-decoration:none;color: #0084b4;}
             #content div.desc { margin: 11px 0px 10px 0px; }
             a img{border:0;}
             a:hover { text-decoration: underline;}
             ul{list-style:square;padding-left:20px;}
             div.error { width: 100%; text-align: center; margin: 0px 0;}

             /* Navigation
             ----------------------------------------------- */
             #navigation { background-color: #fff; position: absolute; top: 8px; right: 0; padding: 6px 6px; font-size: 13px; text-align: center; }
             #navigation ul { margin: 0; padding: 0px; width: auto; height: 100%; _width: 60px;}
             #navigation li { display:inline; padding: 0 5px; }
             #navigation li:before { content: ' '; padding-right: 0; }
             #navigation li.first:before { content: ''; padding-right: 0; }
             #navigation, #footer { -moz-border-radius: 5px;-webkit-border-radius: 5px;}

             /* Footer
             ----------------------------------------------- */
             #footer { clear: left; width: 555px; text-align: left; padding: 0px 0; font-size: 11px; color: #778899;}
             #footer ul { clear: both; display: block;}
             #footer li { display: block; float: left; margin: 0 16px 0 0;}
             #footer li.first:before { content: ''; padding-right: 0; }
             #languages li { margin-bottom: 25px; font-size: 12px; width: 14%; text-align: center; }

           </style>
         </head>
         <body>
           <div id="container" class="subpage">
             <div id="navigation">
               <ul>
                 <li class="first"><a href="//twitter.com">Home &#8250;</a></li>
               </ul>
             </div>
             <h1 id="header"><a href="//twitter.com"><img src="//si0.twimg.com/sticky/error_pages/twitter_logo_header.png" width="155" height="36" alt="Twitter.com" /></a></h1>
             <div id="content">
               <div class="desc"></div>
               <div class="wrapper">
                 <h2>Twitter is over capacity.</h2>
                 <p>Please wait a moment and try again. For more information, check out <a href="http://status.twitter.com">Twitter Status &#187;</a></p>
               </div>
               <div class="error"><img src="//si0.twimg.com/sticky/error_pages/whale_error.gif" alt="" width="755" height="397" /></div>
             </div>
             <div id="footer" style="width:100%">
               <ul id="languages">
                 <li><a onclick="displayLanguage('id');return false;" href="#">Bahasa Indonesia</a></li>
                 <li><a onclick="displayLanguage('msa');return false;" href="#">Bahasa Melayu</a></li>
                 <li><a onclick="displayLanguage('de');return false;" href="#">Deutsch</a></li>
                 <li class="first"><a onclick="displayLanguage('en');return false;" href="#">English</a></li>
                 <li><a onclick="displayLanguage('es');return false;" href="#">Español</a></li>
                 <li><a onclick="displayLanguage('fil');return false;" href="#">Filipino</a></li>
                 <li><a onclick="displayLanguage('fr');return false;" href="#">Français</a></li>
                 <li><a onclick="displayLanguage('it');return false;" href="#">Italiano</a></li>
                 <li><a onclick="displayLanguage('nl');return false;" href="#">Nederlands</a></li>
                 <li><a onclick="displayLanguage('pt');return false;" href="#">Português</a></li>
                 <li><a onclick="displayLanguage('tr');return false;" href="#">Türkçe</a></li>
                 <li><a onclick="displayLanguage('ru');return false;" href="#">Русский</a></li>
                 <li><a onclick="displayLanguage('hi');return false;" href="#">हिन्दी</a></li>
                 <li><a onclick="displayLanguage('ja');return false;" href="#">日本語</a></li>
                 <li><a onclick="displayLanguage('zh_cn');return false;" href="#">简体中文</a></li>
                 <li><a onclick="displayLanguage('zh_tw');return false;" href="#">繁體中文</a></li>
                 <li><a onclick="displayLanguage('ko');return false;" href="#">한국어</a></li>
               </ul>

               <ul>
                 <li class="first">&copy; 2012 Twitter</li>
                 <li><a href="/about">About Us</a></li>
                 <li><a href="/about/contact">Contact</a></li>
                 <li><a href="http://blog.twitter.com/">Blog</a></li>
                 <li><a href="http://status.twitter.com/">Status</a></li>
                 <li><a href="http://dev.twitter.com/">API</a></li>
                 <li><a href="/help">Help</a></li>
                 <li><a href="/jobs">Jobs</a></li>
                 <li><a href="/tos">TOS</a></li>
                 <li><a href="/privacy">Privacy</a></li>
               </ul>
             </div>
           </div>
           <!-- BEGIN google analytics -->
           <script type="text/javascript">
             var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
             document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
           </script>
           <script type="text/javascript">
             var pageTracker = _gat._getTracker("UA-30775-6");
             pageTracker._setDomainName("twitter.com");
             pageTracker._trackPageview('503 Error');
           </script>
           <!-- END google analytics -->

           <script type="text/javascript">
           //<![CDATA[
           var twttr = {};

           twttr.translations = {
             "ja": {
               "title": "Twitterは処理能力の限界を超えています。",
               "description": "しばらく待ってから、再度お試し頂けますようお願いいたします。詳細については、 <a href=\"http://status.twitter.jp\">ステータスブログ</a>をご確認ください。",
               "home": "ホーム &#8250;"
             },
             "ru": {
               "title": "Твиттер перегружен.",
               "description": "Пожалуйста, повторите попытку позднее. Получите более подробную информацию  <a href=\"http://status.twitter.com\">о состоянии Твиттера &raquo;</a>",
               "home": "Главная &#8250;"
             },
             "hi": {
               "title": "ट्विटर क्षमता पार कर गया है.",
               "description": "कृपया कुछ क्षण प्रतीक्षा करें और फिर कोशिश करें. अधिक जानकारी के लिए, ट्विटर स्टेट्स  <a href=\"http://status.twitter.com\">देखें &raquo;</a>",
               "home": "मुख पृष्ठ &#8250;"
             },
             "nl": {
               "title": "Twitter is overbelast.",
               "description": "Probeer het later opnieuw. Voor meer informatie, zie <a href=\"http://status.twitter.com\">Twitter Status &raquo;</a>",
               "home": "Startpagina &#8250;"
             },
             "en": {
               "title": "Twitter is over capacity.",
               "description": "Please wait a moment and try again. For more information, check out <a href=\"http://status.twitter.com\">Twitter Status &raquo;</a>",
               "home": "Home &#8250;"
             },
             "fr": {
               "title": "Twitter est en surcapacité.",
               "description": "Veuillez attendre un moment avant de réessayer. Pour plus d\\'informations, rendez-vous sur le <a href=\"http://status.twitter.com\">blog d\\'état &raquo;</a>",
               "home": "Accueil &#8250;"
             },
             "de": {
               "title": "Twitter ist ausgelastet.",
               "description": "Bitte warte einen Moment und versuche es dann erneut. Weitere Informationen gibt es auf der <a href=\"http://status.twitter.com\">Twitter Status Seite &raquo;</a>",
               "home": "Startseite &#8250;"
             },
             "tr": {
               "title": "Twitter kapasiteyi aştı.",
               "description": "Lütfen biraz bekle ve tekrar dene. Daha fazla bilgi için <a href=\"http://status.twitter.com\">Twitter Durum</a> sayfasını ziyaret et &raquo;",
               "home": "Ana Sayfa &#8250;"
             },
             "msa": {
               "title": "Twitter melebihi kapasiti.",
               "description": "Sila tunggu sebentar dan cuba semula. Untuk maklumat lanjut, lihat <a href=\"http://status.twitter.com\">Status Twitter &raquo;</a>",
               "home": "Laman Utama &#8250;"
             },
             "es": {
               "title": "Twitter está sobrecargado",
               "description": "Por favor espera un momento e inténtalo de nuevo. Para más información visita <a href=\"http://status.twitter.com\">Twitter Status &raquo;</a>",
               "home": "Página de Inicio &#8250;"
             },
             "it": {
               "title": "Twitter è sovraccarico.",
               "description": "Aspetta qualche minuto e riprova. Per maggiori informazioni controlla<a href=\"http://status.twitter.com\">Twitter Status &raquo;</a>",
               "home": "Pagina Iniziale &#8250;"
             },
             "fil": {
               "title": "Lagpas na sa kapasidad ang Twitter.",
               "description": "Mangyaring maghintay ng ilang sandali at subukan muli. Para sa karagdagang impormasyon, tingnan ang <a href=\"http://status.twitter.com\">Twitter Status &raquo;</a>",
               "home": "Home &#8250;"
             },
             "pt": {
               "title": "O Twitter está sobrecarregado",
               "description": "Por favor, aguarde alguns minutos e tente novamente. Para mais informações, acesse <a href=\"http://status.twitter.com\">Twitter Status &raquo;</a>",
               "home": "Página Inicial &#8250;"
             },
             "zh_tw": {
               "title": "Twitter 超出負荷了。",
               "description": "請稍等一會再嘗試。要了解更多資訊,請查看 <a href=\"http://status.twitter.com\">Twitter 狀態 &raquo;</a>",
               "home": "首頁 &#8250;"
             },
             "ko": {
               "title": "사용량 증가로 트위터가 지연되고 있습니다.",
               "description": "잠시 후에 다시 해보세요. 자세한 정보는  <a href=\"http://status.twitter.com\">트위터 상태</a>를 확인해보세요 &raquo;",
               "home": "홈 &#8250;"
             },
             "id": {
               "title": "Twitter sedang kelebihan kapasitas.",
               "description": "Silakan tunggu sebentar dan coba lagi. Untuk informasi lebih lanjut, kunjungi <a href=\"http://status.twitter.com\">Status Twitter &raquo;</a>",
               "home": "Beranda &#8250;"
             },
             "zh_cn": {
               "title": "Twitter 超载啦。",
               "description": "请稍后再试。更多信息请查看 <a href=\"http://status.twitter.com\">Twitter 状态 &raquo;</a>",
               "home": "主页 &#8250;"
             }
           };

           function displayLanguage(lang) {
             if (lang && twttr.translations[lang]) {
               document.getElementsByTagName('h2')[0].innerHTML = twttr.translations[lang].title;
               document.getElementsByTagName('p')[0].innerHTML = twttr.translations[lang].description;
               document.getElementById('navigation').getElementsByTagName('a')[0].innerHTML = twttr.translations[lang].home;
             }
           }

           var lang = window.navigator.language ? window.navigator.language.replace(/^(..).*$/, '$1') : undefined;
           displayLanguage(lang);
           //]]>
           </script>
         </body>
       </html>

Does this gem work with Apigee?

I've been using this gem for a while now on Heroku. Love it. My app has recently started hitting the rate limit so I thought I'd try Apigee a try since it's free for 50k/hr... more than enough for my app. Anyway, after diving into it a bit, Apigee is basically just a reverse proxy for api.twitter.com and so, when doing oauth, the oauth signature base string needs to be based off of api.twitter.com. Since the OAuth is being handled by ruby-oauth, I thought it would be ok if I just ran the oauth against api.twitter.com, get the tokens I need, add the :apigee key in Grackle::Client::TWITTER_API_HOSTS, then set the :api key when creating a new Grackle::Client, but every time I try, it gives me an invalid signature error which seems like the oauth sig that's being sent out by Grackle is wrong.

@consumer ||= OAuth::Consumer.new(consumer_key, consumer_secret, :site => "http://api.twitter.com")

if !session[:oauth][:request_token].nil? && !session[:oauth][:request_token_secret].nil?
  @request_token = OAuth::RequestToken.new(@consumer, session[:oauth][:request_token], session[:oauth][:request_token_secret])
end

if !session[:oauth][:access_token].nil? && !session[:oauth][:access_token_secret].nil?
  @access_token = OAuth::AccessToken.new(@consumer, session[:oauth][:access_token], session[:oauth][:access_token_secret])
end

if @access_token
  @client = Grackle::Client.new(:auth => {
      :type => :oauth,
      :consumer_key => consumer_key,
      :consumer_secret => consumer_secret,
      :token => @access_token.token, 
      :token_secret => @access_token.secret
    },
    :api => :apigee,
    :headers => {'User-Agent' => "onlythelinks.com/1.0"})

  cached_user = cache.get(@access_token.token)
  if cached_user
    @current_user = cached_user[:current_user]
    @all_lists = cached_user[:lists]
  else
    ...
  end
  @logged_in = true
else
  @logged_in = false
end

Do you know if this gem works with Apigee? I saw that Apigee has forked this project and added some "proxy" code. I tried using that gem, but it has a few problems of its own and doesn't seem to have tests for the additions they added.

Thoughts? TIA!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.