Created
January 21, 2012 07:17
-
-
Save no6v/1651877 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/lib/earthquake.rb b/lib/earthquake.rb | |
index be11649..328df67 100644 | |
--- a/lib/earthquake.rb | |
+++ b/lib/earthquake.rb | |
@@ -27,4 +27,5 @@ Encoding.default_external = Encoding.find('UTF-8') | |
help | |
commands | |
id_var | |
+ item | |
).each { |name| require_dependency File.expand_path("../earthquake/#{name}", __FILE__) } | |
diff --git a/lib/earthquake/item.rb b/lib/earthquake/item.rb | |
new file mode 100644 | |
index 0000000..0a144e4 | |
--- /dev/null | |
+++ b/lib/earthquake/item.rb | |
@@ -0,0 +1,243 @@ | |
+module Earthquake | |
+ class Item | |
+ [ | |
+ :config, | |
+ :color_of, | |
+ :id2var, | |
+ ].each do |m| | |
+ delegate m, :to => Earthquake | |
+ private m | |
+ end | |
+ | |
+ def initialize(item) | |
+ @item = item | |
+ end | |
+ | |
+ def to_status | |
+ text = body.u | |
+ if config[:raw_text] | |
+ text.prepend("\n") | |
+ else | |
+ text.gsub!(/\s+/, " ") | |
+ end | |
+ text = highlight(text) | |
+ [prefix, screen_name, text, protected_mark, info].compact.join(" ") | |
+ end | |
+ | |
+ def inspect | |
+ super.split.first << ?> | |
+ end | |
+ | |
+ protected | |
+ | |
+ def body | |
+ if truncated? and retweet? | |
+ item = Item.new(retweeted_status) | |
+ "RT #{item.screen_name(?@)} #{item.body}" | |
+ else | |
+ colored_text | |
+ end | |
+ end | |
+ | |
+ def screen_name(prefix = "") | |
+ screen_name = @item["user"]["screen_name"] | |
+ "#{prefix}#{screen_name}".c(color_of(screen_name)) + ":" | |
+ end | |
+ | |
+ private | |
+ | |
+ def protected_mark | |
+ "[P]".c(:notice) if protected? | |
+ end | |
+ | |
+ def protected? | |
+ @item["user"]["protected"] | |
+ end | |
+ | |
+ def highlight(text) | |
+ if highlights = @item["_highlights"] | |
+ highlights.each do |h| | |
+ color = config[:color][:highlight].nil? ? color_of(h).to_i + 10 : :highlight | |
+ text = text.coloring(/#{h}/i, color) | |
+ end | |
+ end | |
+ text | |
+ end | |
+ | |
+ def info | |
+ info = [] | |
+ info << (reply_info || retweet_info) | |
+ info << time_info unless config[:hide_time] | |
+ info << source_info unless config[:hide_app_name] | |
+ info.compact.join(" - ").c(:info) | |
+ end | |
+ | |
+ def reply_info | |
+ if in_reply_to_status_id_str = @item["in_reply_to_status_id_str"] | |
+ "(reply to #{id2var(in_reply_to_status_id_str)})" | |
+ end | |
+ end | |
+ | |
+ def retweet_info | |
+ if retweet? | |
+ "(retweet of #{id2var(retweeted_status["id_str"])})" | |
+ end | |
+ end | |
+ | |
+ def time_info | |
+ if created_at = @item["created_at"] | |
+ Time.parse(created_at).strftime(config[:time_format]) | |
+ end | |
+ end | |
+ | |
+ def source_info | |
+ if source = @item["source"] | |
+ source.u =~ />(.*)</ ? $1 : 'web' | |
+ end | |
+ end | |
+ | |
+ def prefix | |
+ mark + "[#{id2var(status_id)}]".c(:info) | |
+ end | |
+ | |
+ def mark | |
+ @item["_mark"] || "" | |
+ end | |
+ | |
+ def status_id | |
+ @item["id_str"] | |
+ end | |
+ | |
+ def truncated? | |
+ @item["truncated"] | |
+ end | |
+ | |
+ def retweet? | |
+ @item.key?("retweeted_status") | |
+ end | |
+ | |
+ def retweeted_status | |
+ @item["retweeted_status"] | |
+ end | |
+ | |
+ def colored_text | |
+ Entity.apply(@item["text"], @item["entities"]) | |
+ end | |
+ | |
+ module Entity | |
+ class << self | |
+ def apply(text, item_entities) | |
+ text = text.dup | |
+ parse(item_entities).inject(0) do |offset, entity| | |
+ offset + entity.apply(text, offset) | |
+ end | |
+ text | |
+ end | |
+ | |
+ private | |
+ | |
+ def parse(item_entities) | |
+ item_entities.flat_map{|type, entities| | |
+ entities.map{|entity| | |
+ klass = type.classify | |
+ const_get(klass).new(entity) if const_defined?(klass) | |
+ }.compact | |
+ }.sort_by!(&:position) | |
+ end | |
+ end | |
+ | |
+ class Base | |
+ [ | |
+ :config, | |
+ :color_of, | |
+ ].each do |m| | |
+ delegate m, :to => Earthquake | |
+ private m | |
+ end | |
+ | |
+ def initialize(entity) | |
+ @entity = entity | |
+ @first, @last = entity["indices"] | |
+ end | |
+ | |
+ def position | |
+ @first | |
+ end | |
+ | |
+ def apply(text, offset) | |
+ colored_text = coloring | |
+ text[range(offset)] = colored_text | |
+ colored_text.size - size | |
+ end | |
+ | |
+ private | |
+ | |
+ def size | |
+ @last - @first | |
+ end | |
+ | |
+ def body | |
+ @entity[key] | |
+ end | |
+ | |
+ def key | |
+ raise NotImplementedError, "need to define `key'" | |
+ end | |
+ | |
+ def string | |
+ body | |
+ end | |
+ | |
+ def range(offset) | |
+ (@first + offset) ... (@last + offset) | |
+ end | |
+ | |
+ def coloring | |
+ string.c(color_of(string)) | |
+ end | |
+ end | |
+ | |
+ class UrlBase < Base | |
+ private | |
+ | |
+ def string | |
+ config[:expand_url] && @entity["expanded_url"] || @entity["url"] | |
+ end | |
+ | |
+ def coloring | |
+ string.c(:url) | |
+ end | |
+ end | |
+ | |
+ class Url < UrlBase | |
+ end | |
+ | |
+ class Medium < UrlBase | |
+ end | |
+ | |
+ class Hashtag < Base | |
+ private | |
+ | |
+ def key | |
+ "text" | |
+ end | |
+ | |
+ def string | |
+ "#" + body | |
+ end | |
+ end | |
+ | |
+ class UserMention < Base | |
+ private | |
+ | |
+ def key | |
+ "screen_name" | |
+ end | |
+ | |
+ def string | |
+ "@" + body | |
+ end | |
+ end | |
+ end | |
+ end | |
+end | |
diff --git a/lib/earthquake/output.rb b/lib/earthquake/output.rb | |
index a5a19dc..ad866f8 100644 | |
--- a/lib/earthquake/output.rb | |
+++ b/lib/earthquake/output.rb | |
@@ -85,56 +85,8 @@ module Earthquake | |
output :tweet do |item| | |
next unless item["text"] | |
- info = [] | |
- if item["in_reply_to_status_id"] | |
- info << "(reply to #{id2var(item["in_reply_to_status_id"])})" | |
- elsif item["retweeted_status"] | |
- info << "(retweet of #{id2var(item["retweeted_status"]["id"])})" | |
- end | |
- if !config[:hide_time] && item["created_at"] | |
- info << Time.parse(item["created_at"]).strftime(config[:time_format]) | |
- end | |
- if !config[:hide_app_name] && item["source"] | |
- info << (item["source"].u =~ />(.*)</ ? $1 : 'web') | |
- end | |
- | |
- id = id2var(item["id"]) | |
- | |
- text = (item["retweeted_status"] && item["truncated"] ? "RT @#{item["retweeted_status"]["user"]["screen_name"]}: #{item["retweeted_status"]["text"]}" : item["text"]).u | |
- text.gsub!(/\s+/, ' ') unless config[:raw_text] | |
- text.prepend("\n") if config[:raw_text] | |
- text = text.coloring(/@[0-9A-Za-z_]+/) { |i| color_of(i) } | |
- text = text.coloring(/(^#[^\s]+)|(\s+#[^\s]+)/) { |i| color_of(i) } | |
- if config[:expand_url] | |
- entities = (item["retweeted_status"] && item["truncated"]) ? item["retweeted_status"]["entities"] : item["entities"] | |
- if entities | |
- entities.values_at("urls", "media").flatten.compact.each do |entity| | |
- url, expanded_url = entity.values_at("url", "expanded_url") | |
- if url && expanded_url | |
- text = text.sub(url, expanded_url) | |
- end | |
- end | |
- end | |
- end | |
- text = text.coloring(URI.regexp(["http", "https"]), :url) | |
- | |
- if item["_highlights"] | |
- item["_highlights"].each do |h| | |
- color = config[:color][:highlight].nil? ? color_of(h).to_i + 10 : :highlight | |
- text = text.coloring(/#{h}/i, color) | |
- end | |
- end | |
- | |
- mark = item["_mark"] || "" | |
- | |
- status = [ | |
- "#{mark}" + "[#{id}]".c(:info), | |
- "#{item["user"]["screen_name"].c(color_of(item["user"]["screen_name"]))}:", | |
- "#{text}", | |
- (item["user"]["protected"] ? "[P]".c(:notice) : nil), | |
- info.join(' - ').c(:info) | |
- ].compact.join(" ") | |
- puts status | |
+ item = Item.new(item) | |
+ puts item.to_status | |
end | |
output :delete do |item| | |
diff --git a/lib/earthquake/twitter.rb b/lib/earthquake/twitter.rb | |
index 0c09ddb..9949f39 100644 | |
--- a/lib/earthquake/twitter.rb | |
+++ b/lib/earthquake/twitter.rb | |
@@ -49,6 +49,23 @@ module Earthquake | |
options | |
) | |
end | |
+ | |
+ private | |
+ | |
+ def get_with_entities(path, headers = {}) | |
+ separator = | |
+ case URI.parse(path).query | |
+ when nil | |
+ "?" | |
+ when "" | |
+ "" | |
+ else | |
+ "&" | |
+ end | |
+ get_without_entities(path + separator + "include_entities=1", headers) | |
+ end | |
+ | |
+ alias_method_chain :get, :entities | |
end | |
end | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment