at_email 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 074b5f8e272c1f28f2fa4089e5396b13b061c1dd
4
+ data.tar.gz: f5eaf714aa99285d339078fe5ee59965ca12614c
5
+ SHA512:
6
+ metadata.gz: e689e838a44d38ec50bee5c5afc6624bcefb5eb064fdc2f01231799d229bf84d8b15287d05e1cd93f84a18811da2e354672e3c8a4f5cd5d3bbc15b9e2afacd95
7
+ data.tar.gz: 83e37a70a22770e6abb9ee613aeb40af85668f196223a81f1a767b7da9af09afba065cd2cc12f13f8de24ac005a9e4cd35cd2f1957d51f607d6896f24d9e2b6b
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2018 Robin Patel
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,28 @@
1
+ # at_email
2
+
3
+ A project to build an e-mail management and support toolkit.
4
+
5
+ The project is currently at a very early stage and the functionality is likely to be unstable and possible destructive for the time being, I would not recommend using this software at this time. We will update this information when the software is in a more stable stage of development.
6
+
7
+ ## Prerequisites
8
+
9
+ * ruby 2.3.7+
10
+ * GEM: concurrent-ruby (1.1.3)
11
+
12
+ ## License
13
+
14
+ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details
15
+
16
+ ## Acknowledgments
17
+
18
+ * https://github.com/joeyates
19
+
20
+ ## Disclaimer
21
+
22
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28
+ SOFTWARE.
@@ -0,0 +1,24 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $LOAD_PATH.unshift(File.expand_path("../lib/", __dir__))
4
+ require 'at_email'
5
+ $runtime_configure = At_email::RuntimeConfigure.new
6
+ $runtime_configure.get_app_path
7
+ $options = At_email::Config::Cmd_Opt_Parser.new(ARGV)
8
+ config_file = At_email::Config::Config_File.new
9
+ $config = config_file.get_config()
10
+ $runtime_configure.configure_logger
11
+
12
+ $logger.debug ''
13
+ $logger.warn 'Welcome to atEmail - Build: ' + At_email::VERSION + ' - PID: ' + Process.pid.to_s
14
+ $logger.debug ''
15
+ $logger.warn 'Config File: ' + $options.config_file + ' - Task Starting'
16
+ $logger.warn 'Log File: ' + $logger.log_file_default
17
+
18
+ $runtime_configure.output_config
19
+
20
+ task = At_email::Tasks::Imap_To_Fs.new()
21
+
22
+ task.execute
23
+
24
+ $logger.warn 'Config File: ' + $options.config_file + ' - Task Complete'
@@ -0,0 +1,210 @@
1
+ module At_email ; end
2
+
3
+ ### libs
4
+ require 'fileutils'
5
+ require "logger"
6
+ require 'digest'
7
+
8
+ ### at_email libs
9
+ require "at_email/core"
10
+ require "at_email/version"
11
+ require "at_email/config"
12
+ require "at_email/account"
13
+ require "at_email/tasks"
14
+ require "at_email/threads"
15
+
16
+ module At_email
17
+
18
+ DEFAULT_CONFIG_FILE = 'cfg/defaults/default_config.json'
19
+
20
+ end
21
+
22
+ module At_email
23
+
24
+ class At_email::At_Logger
25
+
26
+ attr_reader :log_file_default
27
+
28
+ def initialize
29
+
30
+ filename_timestamp = Time.now.strftime("%Y%m%d_%H%M%S")
31
+ log_file_dir = $config[:output_base_dir] + '/_logs'
32
+
33
+ @log_file_default = log_file_dir + '/' + $config[:task] + '.' + $config[:account_id] + '.' + filename_timestamp + '.log'
34
+ if !Dir.exists?(log_file_dir)
35
+ FileUtils.mkdir_p log_file_dir
36
+ end
37
+ @logger_stdout = Logger.new(STDOUT)
38
+ @logger_stderr = Logger.new(STDERR)
39
+ @logger_file_default = Logger.new(@log_file_default)
40
+ @logger_stdout.datetime_format = '%Y-%m-%d %H:%M:%S'
41
+ @logger_stdout.formatter = proc do |severity, datetime, progname, msg|
42
+ "#{datetime} - " + $config[:task] + " - " + $config[:account_id] + " - #{msg}\n"
43
+ end
44
+ @logger_stderr.datetime_format = '%Y-%m-%d %H:%M:%S'
45
+ @logger_stderr.formatter = proc do |severity, datetime, progname, msg|
46
+ "#{datetime} - " + $config[:task] + " - " + $config[:account_id] + " - #{msg}\n"
47
+ end
48
+ @logger_file_default.datetime_format = '%Y-%m-%d %H:%M:%S'
49
+ @logger_file_default.formatter = proc do |severity, datetime, progname, msg|
50
+ "#{datetime} - " + $config[:task] + " - " + $config[:account_id] + " - #{msg}\n"
51
+ end
52
+ if $options.silent
53
+ @logger_stdout.level = Logger::FATAL
54
+ @logger_stderr.level = Logger::FATAL
55
+ @logger_file_default.level = Logger::FATAL
56
+ elsif $options.quiet
57
+ @logger_stdout.level = Logger::WARN
58
+ @logger_stderr.level = Logger::WARN
59
+ @logger_file_default.level = Logger::WARN
60
+ elsif $options.verbose
61
+ @logger_stdout.level = Logger::DEBUG
62
+ @logger_stderr.level = Logger::DEBUG
63
+ @logger_file_default.level = Logger::DEBUG
64
+ else
65
+ @logger_stdout.level = Logger::INFO
66
+ @logger_stderr.level = Logger::INFO
67
+ @logger_file_default.level = Logger::INFO
68
+ end
69
+ end
70
+
71
+ def debug(event)
72
+ @logger_stdout.debug(event)
73
+ @logger_file_default.debug(event)
74
+ end
75
+
76
+ def info(event)
77
+ @logger_stdout.info(event)
78
+ @logger_file_default.info(event)
79
+ end
80
+
81
+ def warn(event)
82
+ @logger_stderr.warn(event)
83
+ @logger_file_default.warn(event)
84
+ end
85
+
86
+ def error(event)
87
+ @logger_stderr.error(event)
88
+ @logger_file_default.error(event)
89
+ end
90
+
91
+ def fatal(event)
92
+ @logger_stderr.fatal(event)
93
+ @logger_file_default.fatal(event)
94
+ end
95
+
96
+ def unknown(event)
97
+ @logger_stderr.unknown(event)
98
+ @logger_file_default.unknown(event)
99
+ end
100
+
101
+ def event(event_level, event_tag, event_data)
102
+ event_tag_formatted = get_event_tag_formatted(event_tag)
103
+ if event_tag_formatted === ''
104
+ log_string = event_data
105
+ else
106
+ log_string = event_tag_formatted + ' - ' + event_data
107
+ end
108
+ case event_level
109
+ when 'DEBUG'
110
+ $logger.debug log_string
111
+ when 'WARN'
112
+ $logger.error log_string
113
+ when 'ERROR'
114
+ $logger.fatal ''
115
+ $logger.error log_string
116
+ $logger.error ''
117
+ $logger.error 'Error at line number: ' + __LINE__.to_s + ' of file: ' + __FILE__
118
+ caller.each do |stack_line|
119
+ $logger.error ' ' + stack_line
120
+ end
121
+ $logger.error ''
122
+ when 'FATAL'
123
+ error_code = 1
124
+ $logger.fatal ''
125
+ $logger.fatal log_string
126
+ $logger.fatal ''
127
+ $logger.fatal 'Fatal Error at line number: ' + __LINE__.to_s + ' of file: ' + __FILE__
128
+ caller.each do |stack_line|
129
+ $logger.fatal ' ' + stack_line
130
+ end
131
+ $logger.fatal ''
132
+ $logger.fatal 'Exiting with error code: ' + error_code.to_s
133
+ $logger.fatal ''
134
+ puts "\n"
135
+ exit(error_code)
136
+ else
137
+ $logger.info log_string
138
+ end
139
+ end
140
+
141
+ def get_event_tag_formatted(event_tag)
142
+ event_tag_formatted = ''
143
+ if event_tag.length == 0
144
+ event_tag_formatted = ''
145
+ else
146
+ if event_tag.length <= 2
147
+ event_tag_formatted = '*' + event_tag + '*'
148
+ else
149
+ event_tag_formatted = '***** ' + event_tag + ' *****'
150
+ end
151
+ end
152
+ return event_tag_formatted
153
+ end
154
+
155
+ end
156
+
157
+ class At_email::RuntimeConfigure
158
+
159
+ def configure_logger
160
+ $logger = At_email::At_Logger.new()
161
+ end
162
+
163
+ def output_config
164
+ $logger.debug ''
165
+ $logger.debug 'Configuration'
166
+ $config.each do |key, value|
167
+ if key.to_s === 'password'
168
+ $logger.debug ' ' + key.to_s + ' = ' + '*' * value.to_s.length
169
+ else
170
+ $logger.debug ' ' + key.to_s + ' = ' + value.to_s
171
+ end
172
+ end
173
+ $logger.debug ''
174
+ end
175
+
176
+ def get_app_path
177
+ $app_path = File.dirname(File.expand_path(File.dirname($0)))
178
+ end
179
+
180
+ end
181
+
182
+ class At_email::Formatting
183
+
184
+ def initialize
185
+ end
186
+
187
+ def get_hash(data, hash_length)
188
+ if !hash_length.is_a? Numeric
189
+ $logger.event('FATAL', 'FATAL ERROR', 'hash_length variable is not numeric')
190
+ return false
191
+ end
192
+ if (hash_length > 32)
193
+ $logger.event('FATAL', 'FATAL ERROR', 'hash_length maximum limit is 32 - Requested length: ' + hash_length.to_s)
194
+ return false
195
+ end
196
+ return Digest::MD5.hexdigest(data)[0...hash_length]
197
+ end
198
+
199
+ def get_random_id(id_length)
200
+ hash = get_hash(Time.now.to_f.to_s + '-' + rand(1..1000000000000).to_s, id_length)
201
+ if hash
202
+ return hash
203
+ else
204
+ return false
205
+ end
206
+ end
207
+
208
+ end
209
+
210
+ end
@@ -0,0 +1,3 @@
1
+ module At_email::Account ; end
2
+
3
+ require "at_email/account/connection"
@@ -0,0 +1,32 @@
1
+
2
+ require 'net/imap'
3
+
4
+ class At_email::Account::Imap < Net::IMAP
5
+ attr_accessor :debug
6
+ end
7
+
8
+ class At_email::Account::ImapConnection
9
+
10
+ attr_reader :imap
11
+
12
+ METADATA_ATTRIBUTES = [ 'ENVELOPE', 'FLAGS' ].freeze
13
+ REQUESTED_ATTRIBUTES = [ 'INTERNALDATE', 'RFC822', 'RFC822.SIZE' ].freeze
14
+
15
+ def initialize()
16
+ $logger.info 'Connecting to IMAP server - Host: ' + $config[:server] + ' - Port: ' + $config[:port].to_s
17
+ connect_config = {port: $config[:port], ssl: $config[:ssl]}
18
+ @imap = At_email::Account::Imap.new($config[:server], connect_config)
19
+ end
20
+
21
+ def login
22
+ $logger.info 'Logging into IMAP server - Username: ' + $config[:username]
23
+ @imap.login($config[:username], $config[:password])
24
+ end
25
+
26
+ def disconnect
27
+ $logger.debug 'Logging out from IMAP server'
28
+ @imap.logout
29
+ @imap.disconnect
30
+ end
31
+
32
+ end
@@ -0,0 +1,4 @@
1
+ module At_email::Config ; end
2
+
3
+ require "at_email/config/config_file"
4
+ require "at_email/config/cmd_opt_parser"
@@ -0,0 +1,58 @@
1
+
2
+ require 'optparse'
3
+ require 'optparse/time'
4
+ require 'ostruct'
5
+ require 'pp'
6
+
7
+ class At_email::Config::Cmd_Opt_Parser
8
+
9
+ attr_reader :config_file
10
+ attr_reader :verbose
11
+ attr_reader :quiet
12
+ attr_reader :silent
13
+
14
+ CODES = %w[iso-2022-jp shift_jis euc-jp utf8 binary]
15
+ CODE_ALIASES = { "jis" => "iso-2022-jp", "sjis" => "shift_jis" }
16
+
17
+ def initialize(args)
18
+ @silent = false
19
+ @quiet = false
20
+ @verbose = false
21
+ opt_parser = OptionParser.new do |opts|
22
+ opts.banner = "Usage: #{$PROGRAM_NAME} [options]"
23
+ opts.separator ""
24
+ opts.separator "Options:"
25
+ opts.on("-c [CONFIG FILE]", "--config-file [CONFIG FILE]", String, "Config File (JSON)") do |config_file|
26
+ @config_file = config_file
27
+ end
28
+ opts.on("-s", "--silent", "Run silently") do
29
+ @silent = true
30
+ end
31
+ opts.on("-q", "--quiet", "Run quietly") do
32
+ @quiet = true
33
+ if @silent
34
+ @silent = false
35
+ end
36
+ end
37
+ opts.on("-v", "--verbose", "Run verbosely") do
38
+ @verbose = true
39
+ if @quiet
40
+ @quiet = false
41
+ end
42
+ if @silent
43
+ @silent = false
44
+ end
45
+ end
46
+ opts.on_tail("-h", "--help", "Show this message") do
47
+ puts opts
48
+ exit
49
+ end
50
+ opts.on_tail("--version", "Show version") do
51
+ puts At_email::VERSION
52
+ exit
53
+ end
54
+ end
55
+ opt_parser.parse!(args)
56
+ end
57
+
58
+ end
@@ -0,0 +1,100 @@
1
+
2
+ require 'json'
3
+
4
+ class At_email::Config::Config_File
5
+
6
+ def get_config()
7
+
8
+ if File.exist?($options.config_file)
9
+ contents = File.read($options.config_file)
10
+ config = JSON.parse(contents, symbolize_names: true)
11
+ else
12
+ raise "Config file does not exist: " + $options.config_file
13
+ end
14
+
15
+ default_config_file_path = $app_path + '/' + At_email::DEFAULT_CONFIG_FILE
16
+ if File.exist?(default_config_file_path)
17
+ default_config_contents = File.read(default_config_file_path)
18
+ default_config = JSON.parse(default_config_contents, symbolize_names: true)
19
+ else
20
+ raise "Default config file does not exist: " + default_config_file_path
21
+ end
22
+
23
+ config.each do |key, value|
24
+ if !default_config[key]
25
+ raise 'Config Error: Property: ' + key.to_s + ' is not a valid configuration option for this system'
26
+ end
27
+ end
28
+
29
+ default_config.each do |key, data|
30
+ if !config[key] && data[:value]
31
+ config[key] = data[:value]
32
+ end
33
+ end
34
+
35
+ default_config.each do |key, data|
36
+ if config[key]
37
+ if data[:type]
38
+ if data[:type] === 'boolean'
39
+ if ![true, false].include? config[key]
40
+ raise 'Config Error: Property: ' + key.to_s + ' is not type: boolean - config value: ' + config[key].to_s
41
+ end
42
+ end
43
+ if data[:type] === 'numeric'
44
+ if !config[key].is_a? Numeric
45
+ raise 'Config Error: Property: ' + key.to_s + ' is not type: numeric - config value: ' + config[key].to_s
46
+ end
47
+ if data[:min_value]
48
+ if config[key] < data[:min_value]
49
+ raise 'Config Error: Property: ' + key.to_s + ' is below minimum value: ' + data[:min_value].to_s + ' - config value: ' + config[key].to_s
50
+ end
51
+ end
52
+ if data[:max_value]
53
+ if config[key] > data[:max_value]
54
+ raise 'Config Error: Property: ' + key.to_s + ' is above maximum value: ' + data[:max_value].to_s + ' - config value: ' + config[key].to_s
55
+ end
56
+ end
57
+ end
58
+ if data[:type] === 'string'
59
+ if !config[key].is_a? String
60
+ raise 'Config Error: Property: ' + key.to_s + ' is not type: string - value: ' + config[key].to_s
61
+ end
62
+ if data[:min_length]
63
+ if config[key].length < data[:min_length]
64
+ raise 'Config Error: Property: ' + key.to_s + ' is below minimum lenth: ' + data[:min_length].to_s + ' - config value: ' + config[key].to_s
65
+ end
66
+ end
67
+ if data[:max_length]
68
+ if config[key].length > data[:max_length]
69
+ raise 'Config Error: Property: ' + key.to_s + ' is above minimum lenth: ' + data[:max_length].to_s + ' - config value: ' + config[key].to_s
70
+ end
71
+ end
72
+ end
73
+ if data[:type] === 'path'
74
+ if data[:path_type]
75
+ if data[:path_type] === 'dir'
76
+ if !Dir.exists?(config[key].to_s)
77
+ raise 'Config Error: Property: ' + key.to_s + ' is not a directory path - config value: ' + config[key].to_s
78
+ end
79
+ end
80
+ if data[:path_type] === 'file'
81
+ if !File.exists?(config[key].to_s)
82
+ raise 'Config Error: Property: ' + key.to_s + ' is not a file path - config value: ' + config[key].to_s
83
+ end
84
+ end
85
+ end
86
+ end
87
+ end
88
+ end
89
+ end
90
+
91
+ output = {}
92
+ config.sort_by { |k, v| k }.each do |key, value|
93
+ output[key] = value
94
+ end
95
+
96
+ return output
97
+
98
+ end
99
+
100
+ end