#!/usr/bin/env ruby # -*- ruby -*- # # Copyright (C) 2010-2016 Kouhei Sutou # Copyright (C) 2010 OBATA Akio # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. require "drb/drb" require "uri" require "rabbit/console" require "rabbiter" include Rabbiter::GetText def parse(args=ARGV, logger=nil) Rabbit::Console.parse!(args, logger) do |parser, options| options.version = Rabbiter::VERSION options.rabbit_uri = options.druby_uri options.filters = [] options.user_languages = [] options.resolve_shorten_url = true options.log_status = false parser.separator "" parser.on("--rabbit-uri=URI", _("Rabbit's dRuby URI"), "(#{options.rabbit_uri})") do |uri| options.rabbit_uri = uri end parser.on("--filter=FILTER", _("Filter by word."), _("To use multiple filters, use this option multiple.")) do |filter| options.filters << filter end parser.on("--user-language=LANGUAGE", _("Filter by user language."), _("(e.g.: ja, en)"), _("To use multiple language, use this option multiple.")) do |language| options.user_languages << language end parser.on("--[no-]resolve-shorten-url", _("Resolve shorten URL such as https://t.co/XXX."), "(#{options.resolve_shorten_url})") do |boolean| options.resolve_shorten_url = boolean end parser.category(_("Debug")) parser.on("--[no-]log-status", _("Log target statuses.")) do |boolean| options.log_status = boolean end end end def target?(status, options) return true if options.user_languages.empty? user = status.user return false if user.nil? user_lang = user.lang return false if user_lang.nil? options.user_languages.include?(user_lang) end def clean_text(status, options) raw_text = status.full_text if options.resolve_shorten_url target_text = resolve_shorten_urls(raw_text, status, options) else target_text = raw_text end cleaned_text = remove_hash_tag(target_text, options.filters) cleaned_text = remove_ustream_link(cleaned_text) cleaned_text end def remove_hash_tag(text, filters) hash_tag_regexps = filters.collect do |filter| if filter.start_with?("#") Regexp.escape(filter) else Regexp.escape("\##{filter}") end end text.gsub(Regexp.union(*hash_tag_regexps), "") end def resolve_t_co(url) Net::HTTP.start(url.host, url.port) do |http| response = http.head(url.path) location = response["location"] if location URI(location) else url end end end def resolve_shorten_url(url) case url.host when "t.co" resolve_t_co else url end end def resolve_shorten_urls(raw_text, status, options) resolved_text = raw_text.dup target_urls = status.urls + status.media.uniq {|media| media.id} reversed_urls = target_urls.sort_by do |url| start_position, _ = url.indices -start_position end reversed_urls.each do |url| start_position, end_position = url.indices resolved_url = resolve_shorten_url(url.expanded_url) resolved_text[start_position...end_position] = resolved_url.to_s end resolved_text end def remove_ustream_link(text) text.gsub(/\(.* live at https:\/\/ustre\.am\/.*\)/, "") end def main options, logger = parse if options.filters.empty? logger.error(_("must specify one or more filters by --filter")) exit(false) end rabbit = DRbObject.new_with_uri(options.rabbit_uri) client = Rabbiter::Client.new(logger) client.start(*options.filters) do |status| text = status.full_text next if text.nil? next unless target?(status, options) text = clean_text(status, options) comment = "@#{status.user.screen_name}: #{text}" logger.info(comment) begin rabbit.append_comment(comment) rescue DRb::DRbConnError logger.error("Rabbiter: #{$!.class}: #{$!.message}") end end main_loop = GLib::MainLoop.new trap("INT") do client.close main_loop.quit end main_loop.run end main