Browse Source

Fixed issue #2552 - Apply changes (updated or if channel is deleted) to email channel even if channel is already fetching emails.

Martin Edenhofer 5 years ago
parent
commit
34037219b7
2 changed files with 126 additions and 8 deletions
  1. 92 4
      app/models/channel/driver/imap.rb
  2. 34 4
      app/models/channel/driver/pop3.rb

+ 92 - 4
app/models/channel/driver/imap.rb

@@ -198,12 +198,20 @@ example
     end
 
     # fetch regular messages
-    count_all     = message_ids.count
-    count         = 0
-    count_fetched = 0
-    notice        = ''
+    count_all             = message_ids.count
+    count                 = 0
+    count_fetched         = 0
+    count_max             = 5000
+    active_check_interval = 20
+    notice                = ''
     message_ids.each do |message_id|
       count += 1
+
+      if (count % active_check_interval).zero?
+        break if channel_has_changed?(channel)
+      end
+      break if max_process_count_has_reached?(channel, count, count_max)
+
       Rails.logger.info " - message #{count}/#{count_all}"
 
       message_meta = nil
@@ -331,6 +339,18 @@ returns
     headers
   end
 
+=begin
+
+check if email is already impoted
+
+  Channel::Driver::IMAP.already_imported?(message_id, message_meta, count, count_all, keep_on_server, channel)
+
+returns
+
+  true|false
+
+=end
+
   # rubocop:disable Metrics/ParameterLists
   def already_imported?(message_id, message_meta, count, count_all, keep_on_server, channel)
     # rubocop:enable Metrics/ParameterLists
@@ -358,6 +378,18 @@ returns
     true
   end
 
+=begin
+
+check if email is already marked as deleted
+
+  Channel::Driver::IMAP.deleted?(message_meta, count, count_all)
+
+returns
+
+  true|false
+
+=end
+
   def deleted?(message_meta, count, count_all)
     return false if !message_meta.attr['FLAGS'].include?(:Deleted)
 
@@ -365,6 +397,18 @@ returns
     true
   end
 
+=begin
+
+check if email is to big
+
+  Channel::Driver::IMAP.too_big?(message_meta, count, count_all)
+
+returns
+
+  true|false
+
+=end
+
   def too_big?(message_meta, count, count_all)
     max_message_size = Setting.get('postmaster_max_size').to_f
     real_message_size = message_meta.attr['RFC822.SIZE'].to_f / 1024 / 1024
@@ -376,6 +420,50 @@ returns
     false
   end
 
+=begin
+
+check if channel config has changed
+
+  Channel::Driver::IMAP.channel_has_changed?(channel)
+
+returns
+
+  true|false
+
+=end
+
+  def channel_has_changed?(channel)
+    Rails.logger.info "CC #{channel.id} CHECK."
+    current_channel = Channel.find_by(id: channel.id)
+    if !current_channel
+      Rails.logger.info "Channel with id #{channel.id} is deleted in the meantime. Stop fetching."
+      return true
+    end
+    return false if channel.updated_at == current_channel.updated_at
+
+    Rails.logger.info "Channel with id #{channel.id} has changed. Stop fetching."
+    true
+  end
+
+=begin
+
+check if maximal fetching email count has reached
+
+  Channel::Driver::IMAP.max_process_count_has_reached?(channel, count, count_max)
+
+returns
+
+  true|false
+
+=end
+
+  def max_process_count_has_reached?(channel, count, count_max)
+    return false if count < count_max
+
+    Rails.logger.info "Maximal fetched emails (#{count_max}) reached for this interval for Channel with id #{channel.id}."
+    true
+  end
+
   def timeout(seconds)
     Timeout.timeout(seconds) do
       yield

+ 34 - 4
app/models/channel/driver/pop3.rb

@@ -133,12 +133,18 @@ returns
     end
 
     # fetch regular messages
-    count_all     = mails.size
-    count         = 0
-    count_fetched = 0
-    notice        = ''
+    count_all             = mails.size
+    count                 = 0
+    count_fetched         = 0
+    active_check_interval = 20
+    notice                = ''
     mails.first(2000).each do |m|
       count += 1
+
+      if (count % active_check_interval).zero?
+        break if channel_has_changed?(channel)
+      end
+
       Rails.logger.info " - message #{count}/#{count_all}"
       mail = m.pop
       next if !mail
@@ -211,6 +217,30 @@ returns
     false
   end
 
+=begin
+
+check if channel config has changed
+
+  Channel::Driver::IMAP.channel_has_changed?(channel)
+
+returns
+
+  true|false
+
+=end
+
+  def channel_has_changed?(channel)
+    current_channel = Channel.find_by(id: channel.id)
+    if !current_channel
+      Rails.logger.info "Channel with id #{channel.id} is deleted in the meantime. Stop fetching."
+      return true
+    end
+    return false if channel.updated_at == current_channel.updated_at
+
+    Rails.logger.info "Channel with id #{channel.id} has changed. Stop fetching."
+    true
+  end
+
   def disconnect
     return if !@pop