diff options
-rw-r--r-- | .rubocop.yml | 10 | ||||
-rwxr-xr-x | ag | 72 | ||||
-rw-r--r-- | lib/hotfixes.rb | 1 | ||||
-rw-r--r-- | lib/rendering.rb | 18 | ||||
-rw-r--r-- | lib/storage.rb | 38 | ||||
-rw-r--r-- | lib/threading.rb | 43 | ||||
-rw-r--r-- | lib/utils.rb | 21 |
7 files changed, 101 insertions, 102 deletions
diff --git a/.rubocop.yml b/.rubocop.yml new file mode 100644 index 0000000..8c9e220 --- /dev/null +++ b/.rubocop.yml @@ -0,0 +1,10 @@ +Style/GlobalVars: + Enabled: false +LineLength: + Max: 300 +Metrics/PerceivedComplexity: + Max: 25 +Metrics/PerceivedComplexity: + Max: 25 +Metrics/MethodLength: + Max: 40 @@ -2,7 +2,7 @@ # Ag -- archiving all the 'golden' flamewars on -dev # Alex Legler <a3li@gentoo.org> -$VERBOSE=nil +$VERBOSE = nil require 'bundler/setup' require 'mail' @@ -31,70 +31,70 @@ $options.argmode = nil $options.comment = nil op = OptionParser.new do |opts| - actions = %w(hide-msg unhide-msg index-full index-new delete-msg delete-index reindex rethread info).map { |s| '--'+s }.join('|') + actions = %w(hide-msg unhide-msg index-full index-new delete-msg delete-index reindex rethread info).map { |s| '--' + s }.join('|') opts.banner = "Usage: ag <<#{actions}>> <--list listname>> <[--file|--msgid|--hash] <maildir/file/hash/messageid>> [options]" opts.on('--index-full', 'Read the full past archive from Maildir/cur. Does --delete-index by default. Needs --list and a Maildir') do - abort 'Can only select one action' if $options.action != nil + abort 'Can only select one action' unless $options.action.nil? $options.action = :do_full $options.argmode = :dir end opts.on('--index-new', 'Read new messages from Maildir/new and move them to Maildir/cur. Needs --list and a Maildir') do - abort 'Can only select one action' if $options.action != nil + abort 'Can only select one action' unless $options.action.nil? $options.action = :do_incremental $options.argmode = :dir end opts.on('--delete-msg', 'Delete message. Needs --list and one of --file, --msgid, or --hash') do - abort 'Can only select one action' if $options.action != nil + abort 'Can only select one action' unless $options.action.nil? $options.action = :do_delete_msg end opts.on('--hide-msg', 'Hides a message. Needs --list and one of --file, --msgid, or --hash') do - abort 'Can only select one action' if $options.action != nil + abort 'Can only select one action' unless $options.action.nil? $options.action = :do_hide_msg end opts.on('--unhide-msg', 'Unhides a message. Needs --list and one of --file, --msgid, or --hash') do - abort 'Can only select one action' if $options.action != nil + abort 'Can only select one action' unless $options.action.nil? $options.action = :do_unhide_msg end opts.on('--create-index', 'Create index but do not populate. Needs --list') do - abort 'Can only select one action' if $options.action != nil + abort 'Can only select one action' unless $options.action.nil? $options.action = :do_create_index $options.need_argument = false end opts.on('--rethread', 'Rethread messages. Needs --list') do - abort 'Can only select one action' if $options.action != nil + abort 'Can only select one action' unless $options.action.nil? $options.action = :do_rethread $options.need_argument = false end opts.on('--delete-index', 'Delete index. Needs --list') do - abort 'Can only select one action' if $options.action != nil + abort 'Can only select one action' unless $options.action.nil? $options.action = :do_delete_index $options.need_argument = false end opts.on('--info', 'Display message details. Needs --list and one of --file, --msgid, or --hash') do - abort 'Can only select one action' if $options.action != nil + abort 'Can only select one action' unless $options.action.nil? $options.action = :do_info end opts.on('--reindex', 'Reindex message. Needs --list and --file') do - abort 'Can only select one action' if $options.action != nil + abort 'Can only select one action' unless $options.action.nil? $options.action = :do_reindex end @@ -154,9 +154,12 @@ op.parse! abort op.help unless $options.action abort 'List name required' unless $options.name -$options.dir = ARGV[0] or abort 'Need a Maildir/File/Hash/Message-Id to work with' if $options.need_argument +if $options.need_argument + abort 'Need a Maildir/File/Hash/Message-Id to work with' if ARGV.empty? + $options.dir = ARGV[0] +end -if($options.argmode == :dir) +if $options.argmode == :dir # Open maildir and set serializer $maildir = Maildir.new(File.join($options.dir), false) $maildir.serializer = Maildir::Serializer::Mail.new @@ -171,14 +174,14 @@ Ag::Utils.proc_count = $options.jobs ############################################################################### def do_full - abort "Wrong argument type: #{$options.argmode.to_s}" unless $options.argmode == :dir + abort "Wrong argument type: #{$options.argmode}" unless $options.argmode == :dir do_delete_index(ignore_missing: true, _raise: true) unless $options.readonly do_create_index(ignore_exists: true, _raise: true) messages = $maildir.list(:cur) opts = { - :in_processes => Ag::Utils.proc_count, + in_processes: Ag::Utils.proc_count } opts[:progress] = "Importing #{$options.name}" if $options.progress Parallel.each(messages, opts) do |maildir_message| @@ -196,12 +199,12 @@ def do_full end def do_incremental - abort "Wrong argument type: #{$options.argmode.to_s}" unless $options.argmode == :dir + abort "Wrong argument type: #{$options.argmode}" unless $options.argmode == :dir messages = $maildir.list(:new) do_create_index(ignore_exists: true, _raise: true) opts = { - :in_processes => Ag::Utils.proc_count, + in_processes: Ag::Utils.proc_count } opts[:progress] = "Importing #{$options.name}" if $options.progress Parallel.each(messages, opts) do |maildir_message| @@ -254,27 +257,23 @@ def do_unhide_msg end def do_delete_index(ignore_missing: false, _raise: false) - begin - Ag::Storage.delete_index($options.name) - rescue Elasticsearch::Transport::Transport::Errors::NotFound => e - unless ignore_missing - raise e if _raise - $stderr.puts "Index does not exist: #{e}" - end - rescue => e + Ag::Storage.delete_index($options.name) +rescue Elasticsearch::Transport::Transport::Errors::NotFound => e + unless ignore_missing raise e if _raise - $stderr.puts "Cannot delete index: #{e}" + $stderr.puts "Index does not exist: #{e}" end +rescue => e + raise e if _raise + $stderr.puts "Cannot delete index: #{e}" end def do_create_index(ignore_exists: false, _raise: false) - begin - Ag::Storage.create_index($options.name) - rescue Elasticsearch::Transport::Transport::Errors::BadRequest => e - unless (ignore_exists and e.message =~ /IndexAlreadyExistsException/) - raise e if _raise - $stderr.puts "Cannot create index #{e}" - end + Ag::Storage.create_index($options.name) +rescue Elasticsearch::Transport::Transport::Errors::BadRequest => e + unless ignore_exists && e.message =~ /IndexAlreadyExistsException/ + raise e if _raise + $stderr.puts "Cannot create index #{e}" end end @@ -293,8 +292,7 @@ def do_info require 'pp' str = "Message #{id}" - $stderr.puts str - $stderr.puts '-' * str.length + $stderr.puts str, '-' * str.length pp message['_source'] rescue => e @@ -304,7 +302,7 @@ end ############################################################################### -if self.private_methods.include? $options.action +if private_methods.include? $options.action send $options.action else abort "Internal Error: Unknown action: #{$options.action}" diff --git a/lib/hotfixes.rb b/lib/hotfixes.rb index 1c60dad..99a39a5 100644 --- a/lib/hotfixes.rb +++ b/lib/hotfixes.rb @@ -3,6 +3,7 @@ # If the INFO block contains multiple colons, @info will be wrong. class Maildir::Message protected + # Sets dir, unique_name, and info based on the key def parse_key(key) @dir, filename = key.split(File::SEPARATOR) diff --git a/lib/rendering.rb b/lib/rendering.rb index 4d81197..5c164da 100644 --- a/lib/rendering.rb +++ b/lib/rendering.rb @@ -7,14 +7,14 @@ module Ag::Rendering if mail.multipart? content_type = mime_split(mail.parts.first.content_type) - if content_type == 'text/plain' or content_type == 'text/html' + if content_type == 'text/plain' || content_type == 'text/html' to_content(content_type, mail.parts.first.decoded, get_encoding(mail.parts.first)) else # Nested multipart? if mail.parts.first.multipart? content_type = mime_split(mail.parts.first.parts.first.content_type) - if content_type == 'text/plain' or content_type == 'text/html' + if content_type == 'text/plain' || content_type == 'text/html' to_content(content_type, mail.parts.first.parts.first.decoded, get_encoding(mail.parts.first.parts.first)) else raise "Cannot find body: #{mail.message_id}" @@ -26,7 +26,7 @@ module Ag::Rendering end else # No Content-Type, assume plain text (git-send-email) - if mail.content_type == nil + if mail.content_type.nil? to_content('text/plain', mail.body.decoded, get_encoding(mail)) else to_content(mime_split(mail.content_type), mail.body.decoded, get_encoding(mail)) @@ -35,18 +35,14 @@ module Ag::Rendering end def self.get_encoding(part) - if part.content_type_parameters - part.content_type_parameters['charset'] - else - nil - end + part.content_type_parameters['charset'] if part.content_type_parameters end - def self.to_content(content_type, content, charset = nil) - #content = content.force_encoding(charset) if charset + def self.to_content(content_type, content, _charset = nil) + # content = content.force_encoding(charset) if charset if content_type == 'text/plain' - escaped_content = CGI::escapeHTML(content) + escaped_content = CGI.escapeHTML(content) escaped_content.lines.map do |line| if line.start_with? '>' "<div class=\"ag-quote\">#{line.rstrip}</div>\n" diff --git a/lib/storage.rb b/lib/storage.rb index a22450d..32945e9 100644 --- a/lib/storage.rb +++ b/lib/storage.rb @@ -6,7 +6,7 @@ module Ag::Storage module_function def index_names(list) - return 'ml-' + list + 'ml-' + list end def index_status(indexname) @@ -22,7 +22,7 @@ module Ag::Storage # throws Elasticsearch::Transport::Transport::Errors::NotFound # if the list does not exist def delete_index(list) - $es.indices.delete(index: index_name(list)) + $es.indices.delete(index: index_name(list)) end # Create an index for list @@ -100,19 +100,19 @@ module Ag::Storage type: 'string' }, hidden: { - type: 'boolean', + type: 'boolean' }, comment: { type: 'string', - index: 'not_analyzed', - }, + index: 'not_analyzed' + } } } } }) # Give elasticsearch some time to process the new index - sleep sleeptime while not index_ready?(indexname) + sleep sleeptime until index_ready?(indexname) end def get_content(message, filename) @@ -132,7 +132,7 @@ module Ag::Storage end def resolve_by_field(list, field, value) - return nil if value == nil + return nil if value.nil? result = $es.search( index: index_name(list), @@ -218,12 +218,12 @@ module Ag::Storage from: from, from_realname: from_realname, date: date, - month: ("%i%02i" % [date.year, date.month]).to_i, # this is a sortable number! + month: ('%i%02i' % [date.year, date.month]).to_i, # this is a sortable number! content: content, attachments: attachments, received: received, raw_parent: raw_parent, - raw_filename: filename, + raw_filename: filename } ) end @@ -256,12 +256,12 @@ module Ag::Storage ) opts = { - :in_processes => Ag::Utils.proc_count, + in_processes: Ag::Utils.proc_count } opts[:progress] = "Calculating Threading (Pass #{pass})" if $options.progress Parallel.each(result['hits']['hits'], opts) do |hit| msg = resolve_message_id(list, hit['_source']['raw_parent']) - update(list, hit['_id'], { doc: { parent: msg } }) unless msg.nil? + update(list, hit['_id'], doc: { parent: msg }) unless msg.nil? end result['hits']['total'] @@ -274,27 +274,25 @@ module Ag::Storage def _hide_unhide(list, id, hide_status, comment) doc = { hidden: hide_status } doc[:comment] = comment if comment # Only modify it if it exists - update(list, id, { - doc: doc, - detect_noop: true, - }) + update(list, id, doc: doc, + detect_noop: true) end - def unhide(list, id, comment) - hide_unhide(list, id, true, comment) + def hide(list, id, comment) + hide_unhide(list, id, true, comment) end def unhide(list, id, comment) - _hide_unhide(list, id, false, comment) + _hide_unhide(list, id, false, comment) end def update(list, id, doc_changes) - raise "Invalid update for #{list}/#{id} #{doc_changes.to_s}" unless doc_changes.is_a?(Hash) + raise "Invalid update for #{list}/#{id} #{doc_changes}" unless doc_changes.is_a?(Hash) $es.update( index: index_name(list), type: 'message', id: id, - body: doc_changes, + body: doc_changes ) end diff --git a/lib/threading.rb b/lib/threading.rb index a90929e..09b7d7e 100644 --- a/lib/threading.rb +++ b/lib/threading.rb @@ -1,11 +1,12 @@ module Ag module Threading module_function + # Figures out the Message-Id of the parent message, # or returns nil if we asusme this message is not a reply def get_parent_message_id(mail) # No headers -> no parent message - if mail.in_reply_to == nil and mail.references == nil + if mail.in_reply_to.nil? && mail.references.nil? return nil else irt_value = nil @@ -15,16 +16,18 @@ module Ag elsif mail.in_reply_to.is_a? String irt_value = mail.in_reply_to - # Gnus/Emacs specialty du jour - # => "<1075186049.4264.1.camel@TesterTop.tester.ca> (Olivier Crête's message of \"Tue, 27 Jan 2004 07:47:29 +0100\")" - if irt_value.start_with? '<' - irt_value = irt_value[0..irt_value.rindex('>')] unless irt_value.end_with? '>' - irt_value.gsub!(/(^<|>$)/, '') - end - elsif mail.in_reply_to == nil + # rubocop:disable Style/AsciiComments + # Gnus/Emacs specialty du jour + # => "<1075186049.4264.1.camel@TesterTop.tester.ca> (Olivier Crête's message of \"Tue, 27 Jan 2004 07:47:29 +0100\")" + # rubocop:enable Style/AsciiComments + if irt_value.start_with? '<' + irt_value = irt_value[0..irt_value.rindex('>')] unless irt_value.end_with? '>' + irt_value.gsub!(/(^<|>$)/, '') + end + elsif mail.in_reply_to.nil? # nothing to do - else - $stderr.puts "In-Reply-To is a weird type: #{mail.message_id}" if $options.debug + elsif $options.debug + $stderr.puts "In-Reply-To is a weird type: #{mail.message_id}" end ref_value = nil @@ -32,23 +35,19 @@ module Ag ref_value = mail.references.last elsif mail.references.is_a? String ref_value = mail.references - elsif mail.references == nil + elsif mail.references.nil? # nothing to do else $stderr.puts "References is a weird type: #{mail.message_id}" if $options.debug end - if irt_value == ref_value - return irt_value.to_s - elsif irt_value == nil - return ref_value.to_s - elsif ref_value == nil - return irt_value.to_s - else - $stderr.puts "In-Reply-To and References disagree: #{mail.message_id}" if $options.debug - # If in doubt, let In-Reply-To win - return irt_value.to_s - end + return irt_value.to_s if irt_value == ref_value + return ref_value.to_s if irt_value.nil? + return irt_value.to_s if ref_value.nil? + + $stderr.puts "In-Reply-To and References disagree: #{mail.message_id}" if $options.debug + # If in doubt, let In-Reply-To win + return irt_value.to_s end $stderr.puts "Couldn't find a parent id for Message-Id: #{mail.message_id}" if $options.debug diff --git a/lib/utils.rb b/lib/utils.rb index e3a4836..a2c7251 100644 --- a/lib/utils.rb +++ b/lib/utils.rb @@ -6,8 +6,8 @@ end module Ag module Utils - module_function + def fix_encoding2(str) s = str.encode('UTF-8', 'UTF-8', invalid: :replace, replace: '') s = s.unpack('C*').pack('U*') unless s.valid_encoding? @@ -18,12 +18,9 @@ module Ag detection = CharlockHolmes::EncodingDetector.detect(str) CharlockHolmes::Converter.convert(str, detection[:encoding], 'UTF-8') rescue => e - if fail_hard - raise e - else - $stderr.puts e.message if $options.debug - 'Encoding could not be reliably detected. Contents not available.' - end + raise e if fail_hard + $stderr.puts e.message if $options.debug + 'Encoding could not be reliably detected. Contents not available.' end def resolve_id @@ -47,13 +44,13 @@ module Ag def resolve_address_header(message, header) if message[header].is_a? Mail::StructuredField # Good header, properly parsed - message[header].addrs.map {|s| fix_encoding(s.to_s)} + message[header].addrs.map { |s| fix_encoding(s.to_s) } elsif nil == message[header] # Header not set, return empty [] else # Parsing failed, do best-effort parsing - [message[header].to_s.split(/,\s*/)].flatten.map {|s| fix_encoding(s)} + [message[header].to_s.split(/,\s*/)].flatten.map { |s| fix_encoding(s) } end rescue ArgumentError [] @@ -74,12 +71,12 @@ module Ag @proc_count = nil def proc_count=(cnt) - cnt = nil if cnt == false - @proc_count = cnt + cnt = nil if cnt == false + @proc_count = cnt end def proc_count - return @proc_count unless @proc_count.nil? or @proc_count == false + return @proc_count unless @proc_count.nil? || @proc_count == false (Parallel::ProcessorCount.processor_count.to_f * 0.75).floor end end |