Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Complete

  • Loading branch information...
commit cf4fb8e7d1f26781467852293269a7e301224510 1 parent fb5f054
@yayugu authored
View
11 app/controllers/auth_controller.rb
@@ -34,7 +34,16 @@ def callback
)
end
- #bookmarklet = URI.encode "javascript:void(function(){location.href = '#{base_url}/#{@id}' + location.pathname;})();"
+ if @user
+ session[:user_id] = @user.id
+ end
+
+ redirect_to root_url
+ end
+
+ def logout
+ reset_session
+ redirect_to root_url
end
private
View
37 app/controllers/feed_controller.rb
@@ -1,10 +1,47 @@
class FeedController < ApplicationController
+ TWEET_COUNT = 200
+
+ before_action :prepare_twitter_client
+
def user
+ res = @client.user(params[:name], TWEET_COUNT)
+ @image_url = res.first['user']['profile_image_url']
+ @name = res.first['user']['screen_name']
+ @tweets = Tweet.tweets_from_hash_list(res)
+ render_rss
end
def list
+ res = @client.list(params[:name], params[:slug], TWEET_COUNT)
+ @name = params[:name]
+ @slug = params[:slug]
+ @tweets = Tweet.tweets_from_hash_list(res)
+ render_rss
end
def search
+ res = @client.search(params[:q], TWEET_COUNT)
+ @query = params[:q]
+ @tweets = Tweet.tweets_from_hash_list(res)
+ render_rss
+ end
+
+ private
+
+ def user_for_api_token
+ url_id_hash = params[:url_id_hash]
+ url_id_hash && (@user = User.where(url_id_hash: url_id_hash).first)
+ end
+
+ def prepare_twitter_client
+ user = user_for_api_token
+ unless user
+ render :file => "public/404.html", :status => :unauthorized
+ end
+ @client = TwitterClient.new(user.twitter_access_token, user.twitter_access_secret)
+ end
+
+ def render_rss
+ render layout: false, content_type: 'application/rss+xml'
end
end
View
14 app/controllers/main_controller.rb
@@ -0,0 +1,14 @@
+class MainController < ApplicationController
+ before_action :set_user
+
+ def index
+ end
+
+ private
+
+ def set_user
+ if session[:user_id]
+ @user = User.find(session[:user_id])
+ end
+ end
+end
View
10 app/helpers/application_helper.rb
@@ -1,2 +1,12 @@
module ApplicationHelper
+ def bookmarklet_escape(js)
+ # output_safety string to raw string
+ String.new(js)
+ .gsub(/^\s+/, '')
+ .gsub(/\s+$/, '')
+ .gsub("\n", '')
+ .gsub('%', '%25')
+ .gsub(" ", '%20')
+ .gsub('"', '%22')
+ end
end
View
36 app/models/tweet.rb
@@ -0,0 +1,36 @@
+class Tweet
+ class << self
+ def tweets_from_hash_list(hash_list)
+ hash_list.map{|tweet_hash| Tweet.new(tweet_hash) }
+ end
+ end
+
+ def initialize(tweet_hash)
+ @hash = tweet_hash
+ Rails.logger.debug @hash
+ end
+
+ def markupped_text
+ MarkupTweet::markup_tweet(@hash)
+ end
+
+ def screen_name
+ @hash['user']['screen_name']
+ end
+
+ def url
+ "https://twitter.com/#{screen_name}/status/#{@hash['id']}"
+ end
+
+ def description
+ " <img src='#{@hash['user']['profile_image_url']}' width='16px' height='16px' /> #{markupped_text} "
+ end
+
+ def created_at
+ @hash['created_at']
+ end
+
+ def author
+ @hash['source'].gsub(/<\/?[^>]*>/, "")
+ end
+end
View
19 app/views/feed/_rss.slim
@@ -0,0 +1,19 @@
+doctype xml
+rss[version='2.0'
+ xmlns:content='http://purl.org/rss/1.0/modules/content/']
+ channel
+ title= @title
+ link= @link
+ description= ' '
+ - if @image_url
+ image
+ url= @image_url
+ title= @image_title
+ link= @link
+ - @tweets.each do |tweet|
+ item
+ title= tweet.screen_name
+ link= tweet.url
+ description= tweet.description
+ author= tweet.author
+ pubDate= tweet.created_at
View
4 app/views/feed/list.erb
@@ -0,0 +1,4 @@
+<%
+@title = "#{@slug} / #{@name} / Twitter"
+@link = "http://twitter.com/#{@name}/#{@slug}"
+%><%= render partial: "rss" %>
View
5 app/views/feed/search.erb
@@ -0,0 +1,5 @@
+<%
+require 'uri'
+@title = "#{@query} / search / Twitter"
+@link = "http://twitter.com/search?q=#{URI::encode_www_form_component(@query)}"
+%><%= render partial: "rss" %>
View
5 app/views/feed/user.erb
@@ -0,0 +1,5 @@
+<%
+@title = "#{@name} / Twitter"
+@link = "http://twitter.com/#{@name}"
+@image_title = "#{@name}'s icon"
+%><%= render partial: "rss" %>
View
50 app/views/main/_bookmarklet.js.erb
@@ -0,0 +1,50 @@
+javascript:void(function(){
+ <%# http://stackoverflow.com/questions/901115/how-can-i-get-query-string-values-in-javascript %>
+ <%# without decode escape %>
+ var parameterByName = function (query, name) {
+ name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
+ var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"),
+ results = regex.exec(query);
+ return results == null ? "" : results[1];
+ };
+ var rssUrl = function (path, query, root_url, url_id_hash) {
+ var search_pattern = /search\/?$/;
+ var list_pattern = /([a-zA-Z0-9_]+)\/lists\/([a-zA-Z0-9_]+)/;
+ var user_pattern = /([a-zA-Z0-9_]+)/;
+ var m;
+ if (m = path.match(search_pattern)) {
+ return root_url +
+ 'feed/search?q=' +
+ parameterByName(query, 'q') +
+ '&url_id_hash=' +
+ url_id_hash;
+ }
+ if (m = path.match(list_pattern)) {
+ return root_url +
+ 'feed/list?name=' +
+ m[0] +
+ '&slug=' +
+ m[1] +
+ '&url_id_hash=' +
+ url_id_hash;
+ }
+ if (m = path.match(user_pattern)) {
+ return root_url +
+ 'feed/user?name=' +
+ m[0] +
+ '&url_id_hash=' +
+ url_id_hash;
+ }
+ return null;
+ };
+ var url = rssUrl(
+ location.pathname,
+ location.search,
+ "<%= root_url %>",
+ "<%= @user.url_id_hash %>"
+ );
+ if (!rssUrl) {
+ alert('Twitter Good RSS error: generate URL failed.');
+ }
+ location.href = url;
+})();
View
30 app/views/main/index.html.slim
@@ -0,0 +1,30 @@
+h1 Twitter Great RSS
+div
+
+ - if @user
+ div You can generate RSS with URL like:
+ ul
+ li #{root_url}feed/user?user=USERNAME&url_id_hash=#{@user.url_id_hash}
+ li #{root_url}feed/list?user=USERNAME&slug=LISTNAME&url_id_hash=#{@user.url_id_hash}
+ li #{root_url}feed/search?q=KEYWORD&url_id_hash=#{@user.url_id_hash}
+ div
+ | Bookmarklet is also available. →
+ a href=bookmarklet_escape(render(partial: 'bookmarklet', formats: ['js']))
+ | Bookmark this Bookmarklet
+ br
+ div
+ == link_to "Logout", controller: "auth", action: "logout"
+
+ - else
+ div
+ == link_to "Sign in with twitter", controller: "auth", action: "auth"
+ div Generate RSS for:
+ ul
+ li user tweets
+ li list tweets
+ li search result tweets
+
+ br
+ div
+ | Code is available on
+ a href="http://github.com/yayugu/twitter-great-rss" GitHub
View
1  config/application.rb
@@ -19,5 +19,6 @@ class Application < Rails::Application
# The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
# config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
# config.i18n.default_locale = :de
+ config.autoload_paths += %W(#{config.root}/lib)
end
end
View
1  config/routes.rb
@@ -4,6 +4,7 @@
scope :auth do
get 'auth' => 'auth#auth'
get 'callback' => 'auth#callback'
+ get 'logout' => 'auth#logout'
end
scope :feed do
View
46 lib/markup_tweet.rb
@@ -0,0 +1,46 @@
+class MarkupTweet
+ class << self
+ def markup_tweet(tweet)
+ text = tweet['text']
+ entities = tweet['entities']
+ MarkupTweet::markup_media(text, entities)
+ MarkupTweet::markup_urls(text, entities)
+ MarkupTweet::markup_user_mentions(text, entities)
+ MarkupTweet::markup_hashtags(text, entities)
+ text
+ end
+
+ # see https://dev.twitter.com/docs/tweet-entities
+ def markup_media(text, entities)
+ return text unless entities['media']
+ entities['media'].each do |image|
+ text << "<div><a href='#{image['display_url']}'><img src='#{image['media_url']}' /></a></div>"
+ end
+ text
+ end
+
+ def markup_urls(text, entities)
+ entities['urls'].each do |url|
+ new_url = url['expanded_url'] || url['url']
+ text.gsub!(url['url'], "<a href='#{new_url}'>#{new_url}</a>")
+ end
+ text
+ end
+
+ def markup_user_mentions(text, entities)
+ entities['user_mentions'].each do |mention|
+ screen_name = mention['screen_name']
+ text.gsub!("@#{screen_name}", "<a href='http://twitter.com/#{screen_name}'>@#{screen_name}</a>")
+ end
+ text
+ end
+
+ def markup_hashtags(text, entities)
+ entities['hashtags'].each do |hashtag|
+ hashtag_text = hashtag['text']
+ text.gsub!(/[\##♯]#{Regexp.quote hashtag_text}/, "<a href='http://twitter.com/search?q=%23#{hashtag_text}'>##{hashtag_text}</a>")
+ end
+ text
+ end
+ end
+end
View
7 lib/oauth_twitter.rb
@@ -17,13 +17,6 @@ def access_token(request_token, request_token_secret, oauth_token, oauth_verifie
)
end
- def get_and_json_parse(url, account)
- body = OAuth::AccessToken.new(self.consumer, account.access_token, account.access_secret)
- .get(url)
- .body
- JSON.parse(body)
- end
-
def consumer
OAuth::Consumer.new(
ENV['CONSUMER_KEY'],
View
46 lib/twitter_client.rb
@@ -0,0 +1,46 @@
+require 'oauth'
+require 'oauth_twitter'
+require 'uri'
+
+class TwitterClient
+ def initialize(access_token, access_secret)
+ @access_token = OAuth::AccessToken.new(OAuthTwitter.new.consumer, access_token, access_secret)
+ end
+
+ def user(name, count)
+ get_and_json_parse(user_sub_url(name, count))
+ end
+
+ def list(name, slug, count)
+ get_and_json_parse(list_sub_url(name, slug, count))
+ end
+
+ def search(query, count)
+ get_and_json_parse(search_sub_url(query, count))['statuses']
+ end
+
+ private
+
+ def user_sub_url(name, count)
+ "/statuses/user_timeline.json?screen_name=#{name}&include_entities=true&count=#{count}&include_rts=true"
+ end
+
+ def list_sub_url(name, slug, count)
+ "/lists/statuses.json?slug=#{slug}&owner_screen_name=#{name}&include_entities=true&count=#{count}&include_rts=true"
+ end
+
+ def search_sub_url(query, count)
+ "/search/tweets.json?q=#{URI::encode_www_form_component(query)}&include_entities=true&count=#{count}"
+ end
+
+ def get_and_json_parse(sub_url)
+ body = @access_token
+ .get(api_url(sub_url))
+ .body
+ JSON.parse(body)
+ end
+
+ def api_url(sub_url)
+ "#{OAuthTwitter::SITE_URL}/1.1/#{sub_url}"
+ end
+end
Please sign in to comment.
Something went wrong with that request. Please try again.