jcangas-datagateway 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,145 @@
1
+ #--
2
+ require 'nexus/nax_ar'
3
+ NAX::ActiveRecord::Base.logger = ActiveRecord::Base.logger
4
+
5
+ ## Correccion necesaria en sqlserver_adapter:
6
+ ## el tipo timestamp NO es un datetime, sino un ROW_VERSION
7
+ require 'activerecord-sqlserver-adapter'
8
+ module ActiveRecord #:nodoc: all
9
+ module ConnectionAdapters
10
+ class SQLServerColumn
11
+ alias :old_type_cast :type_cast
12
+ def type_cast(value)
13
+ return nil if value.nil?
14
+ case type
15
+ when :timestamp then value.to_int
16
+ else old_type_cast(value)
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+
23
+ class Array
24
+ # para que funcione la correcion anterior del sqlserver_adapter.
25
+ def to_int
26
+ map{|byte| byte.to_s(16)}.join.to_i(16)
27
+ end
28
+ end
29
+
30
+ class BigDecimal
31
+ #alias :value :to_s #for use in _invoke as oleparam (nax_tlb)
32
+ end
33
+
34
+ class ActiveRecord::Base
35
+ self.table_name_prefix = 'MM'
36
+ end
37
+
38
+ class Product < ActiveRecord::Base
39
+ self.primary_key = "CODE"
40
+ end
41
+
42
+ class User < ActiveRecord::Base
43
+ self.primary_key = "USERID"
44
+ end
45
+
46
+ class TarifaVenta < ActiveRecord::Base
47
+ self.table_name = "TARIFAVE"
48
+ self.primary_key = "IDTARIFAV"
49
+ belongs_to :articulo, :foreign_key => 'CODART'
50
+ end
51
+
52
+ class LineItems < ActiveRecord::Base
53
+ self.table_name = "LINEPEDI"
54
+ self.primary_key = "IDLIN"
55
+ def save
56
+ if new_record?
57
+ unless attributes['IDPEDV'].nil?
58
+ nax_ped = NAX_Pedido.update(attributes['IDPEDV'].to_i)
59
+ nax_ped.add_line('CODART' => attributes['CODART'], 'UNIDADES' => attributes['UNIDADES'])
60
+ nax_ped.save
61
+ end
62
+ end
63
+ self
64
+ end
65
+ end
66
+
67
+ class Order < ActiveRecord::Base
68
+ self.table_name = "CABEPEDV"
69
+ self.primary_key = "IDPEDV"
70
+ validates_presence_of :CODCLI
71
+
72
+ def save
73
+ if new_record?
74
+ if valid?
75
+ NAX_Pedido.create(attributes).save
76
+ else
77
+ logger.info "Errors found:\n" + errors.full_messages.join("\n")
78
+ logger.info "in object:\n #{attributes.inspect}\n"
79
+ errors.clear
80
+ end
81
+ else
82
+ unless attributes['IDPEDV'].nil?
83
+ delta = attributes
84
+ delta.keys.each{|key| delta.delete(key) unless changed.include? key}
85
+ NAX_Pedido.update(attributes['IDPEDV'].to_i, delta).save
86
+ end
87
+ end
88
+ self
89
+ end
90
+ end
91
+
92
+ class NAX_Pedido
93
+ include NAX::ActiveRecord::InstanceMethods
94
+ extend NAX::ActiveRecord::ClassMethods
95
+
96
+ def self.create(attrs)
97
+ ensure_connected
98
+ fecha = Time.now.strftime "%d/%m/%Y"
99
+ result = NAX_Pedido.new
100
+ result.attributes = attrs
101
+ result.Iniciar
102
+ result.Nuevo(fecha, result.attributes['CODCLI'], false)
103
+ result.attributes.delete('CODCLI')
104
+ result.add_fake_line
105
+ result
106
+ end
107
+
108
+ def self.update(rec_id, delta={})
109
+ ensure_connected
110
+ logger.debug "NAX !! #{self}.update(#{delta.inspect})"
111
+ result = NAX_Pedido.new
112
+ result.attributes = delta
113
+ result.Iniciar
114
+ result.Modifica(rec_id, false)
115
+ logger.debug "NAX !! #{self}.updated "
116
+ result
117
+ end
118
+
119
+ def save
120
+ logger.debug "Saving with NAX !!: #{attributes.inspect}"
121
+ attributes.each{|key, val|
122
+ self.AsStringCab[key.to_s] = val if val
123
+ }
124
+ self.Anade
125
+ logger.debug "Saved with NAX !!"
126
+ self
127
+ end
128
+
129
+ def add_line(line)
130
+ logger.debug "(NAX) add_line"
131
+ self.NuevaLineaArt(line['CODART'], line['UNIDADES'])
132
+ self.AnadirLinea;
133
+ end
134
+
135
+ def add_fake_line
136
+ logger.debug "(NAX) add_fake_line"
137
+ self.NuevaLinea
138
+ self.AsFloatLin['UNIDADES'] = 1
139
+ self.AsStringLin['DESCLIN'] = '[shopin] Pedido realizado desde web'
140
+ self.AsStringLin['TIPIVA'] = 'ORD'
141
+ self.AsFloatLin['PRCMONEDA'] = 0
142
+ self.AnadirLinea;
143
+ logger.debug "(NAX) fake_line_added"
144
+ end
145
+ end
@@ -0,0 +1,80 @@
1
+ require 'net/sftp'
2
+ require 'net/sftp/errors'
3
+
4
+ class SSHTransfer
5
+ attr :host
6
+ attr :username
7
+ attr :local_files
8
+ attr :upload_to
9
+ attr :download_from
10
+ attr :options
11
+ attr :logger
12
+
13
+ def initialize(opts)
14
+ @options = {}
15
+ opts.each{ |key, value| @options[key.to_sym] = value }
16
+ @host = options.delete(:host)
17
+ @username = options.delete(:username)
18
+ @local_files = options.delete(:local_files)
19
+ @upload_to = options.delete(:upload_to)
20
+ @download_from = options.delete(:download_from)
21
+ @logger = options.delete(:logger)
22
+ end
23
+
24
+ def upload
25
+ Net::SFTP.start(host, username, options) do |sftp|
26
+ Dir[local_files].each do |file|
27
+ begin
28
+ sftp.upload!(file, File.join(upload_to, File.basename(file)), :progress => self)
29
+ File.delete(file)
30
+ rescue Net::SFTP::StatusException => e
31
+ on_file_error(file, e)
32
+ end
33
+ end
34
+ end
35
+ end
36
+
37
+
38
+ def download
39
+ Net::SFTP.start(host, username, options) do |sftp|
40
+ begin
41
+ sftp.download!(download_from, local_files, :progress => self, :recursive => true)
42
+ sftp.dir.foreach(download_from) do |entry|
43
+ sftp.remove!(File.join(download_from, entry.name)) if entry.file?
44
+ end
45
+
46
+ rescue Net::SFTP::StatusException => e
47
+ on_file_error(file, e)
48
+ end
49
+ end
50
+ end
51
+
52
+ # even handlers
53
+ def on_open(uploader, file)
54
+ logger.info "starting transfer: #{file.local} -> #{file.remote} (#{file.size} bytes)"
55
+ end
56
+
57
+ def on_file_error(file, exception)
58
+ logger.error "error: " + exception
59
+ end
60
+
61
+ def on_put(uploader, file, offset, data)
62
+ # puts "writing #{data.length} bytes to #{file.remote} starting at #{offset}"
63
+ end
64
+
65
+ def on_get(downloader, file, offset, data)
66
+ #puts "writing #{data.length} bytes to #{file.local} starting at #{offset}"
67
+ end
68
+
69
+ def on_mkdir(uploader, path)
70
+ logger.info "creating directory #{path}"
71
+ end
72
+
73
+ def on_close(uploader, file)
74
+ logger.info "finished with #{file.remote}"
75
+ end
76
+
77
+ def on_finish(uploader)
78
+ logger.info "Transfer completed!"
79
+ end
80
+ end
@@ -0,0 +1,13 @@
1
+ require 'time'
2
+ module Application
3
+ module VERSION #:nodoc:
4
+ PRODUCT = 'DataGateway'
5
+ COMPANY = 'Memory Comm S. L.'
6
+ AUTHOR = 'jorge.cangas@gmail.com'
7
+ MAJOR = 1
8
+ MINOR = 1
9
+ TINY = 0
10
+ STRING = [MAJOR, MINOR, TINY].join('.')
11
+ RELEASED_AT = Time.parse('2008/03/22 03:04:54')
12
+ end
13
+ end
@@ -0,0 +1,294 @@
1
+
2
+ $KCODE = 'UTF8'
3
+
4
+ require 'rubygems'
5
+ require 'optparse'
6
+ require 'rdoc/usage'
7
+ require 'ostruct'
8
+ require 'date'
9
+ require 'fileutils'
10
+ require 'erb'
11
+ require 'yaml'
12
+ require 'logger'
13
+ require 'version'
14
+
15
+ $:.unshift File.join(File.dirname(__FILE__), 'datagateway')
16
+ require 'data_gateway'
17
+
18
+
19
+ unless defined? APP_ROOT
20
+ APP_ROOT = File.join(File.dirname(__FILE__), '')
21
+ end
22
+
23
+ class LogFormatter < Logger::Formatter
24
+ @@format = "%s #%d [%s] %5s: %s\n"
25
+ def call(severity, time, progname, msg)
26
+ @@format % [ progname, $$, format_datetime(time), severity, msg2str(msg)]
27
+ end
28
+ end
29
+
30
+ class AppConfig
31
+ ROOT = File.join(File.dirname(__FILE__), '')
32
+ class << self
33
+ attr :config
34
+
35
+ def options
36
+ @options
37
+ end
38
+
39
+ def run
40
+ if parsed_options? && arguments_valid?
41
+ puts "Start at #{DateTime.now}\\n\\n" if @options.verbose
42
+
43
+ output_options if @options.verbose # [Optional]
44
+
45
+ process_arguments
46
+ process_command
47
+
48
+ puts "\\nFinished at #{DateTime.now}" if @options.verbose
49
+ else
50
+ output_usage
51
+ end
52
+ end
53
+
54
+ def parsed_options?
55
+ parse_options unless @parsed_options
56
+ @parsed_options
57
+ end
58
+
59
+ def parse_options
60
+ @parsed_options = true
61
+ # Set defaults
62
+ @options = OpenStruct.new
63
+ @options.verbose = false
64
+ @options.quiet = false
65
+ @options.debug_on = false
66
+ @options.environment = (ENV['APP_ENV'] || 'production').dup
67
+ @options.generate = false
68
+
69
+
70
+ # Specify options
71
+ opts = OptionParser.new do |opts|
72
+ opts.banner = "\nUso: init.rb [options]"
73
+ opts.separator "----------------------"
74
+ opts.separator "Opciones:"
75
+
76
+ opts.on('-h', '--help') { output_help }
77
+
78
+ opts.on("-e", "--environment [ENVIRONMENT]", %w[development production test],
79
+ "(development | production | test)") { |env| @options.environment = env }
80
+
81
+ opts.on("-g", '--generate [prj_name]', "Genera un proyecto nuevo") { |project|
82
+ @options.project = project
83
+ @options.generate = true
84
+ }
85
+
86
+ opts.on("-q", '--quiet', 'Modo "silencioso": no muestra nada en pantalla durante la ejecución') { @options.quiet = true }
87
+
88
+ opts.on('-v', '--version', 'Print version and exit') { output_version ; exit 0 }
89
+
90
+ opts.on('-d', '--debug', 'Modo depuración') { @options.debug_on = true }
91
+ end
92
+
93
+ opts.parse! rescue return false
94
+
95
+ process_options
96
+ true
97
+ end
98
+
99
+ # Performs post-parse processing on options
100
+ def process_options
101
+
102
+ end
103
+
104
+ # True if required arguments were provided
105
+ def arguments_valid?
106
+ # TO DO - implement your real logic here
107
+ true
108
+ end
109
+
110
+ # Setup the arguments
111
+ def process_arguments
112
+ end
113
+
114
+ def output_options
115
+ puts "Options:\\n"
116
+
117
+ @options.marshal_dump.each do |name, val|
118
+ puts " #{name} = #{val}"
119
+ end
120
+ end
121
+
122
+ def output_help
123
+ output_version
124
+ RDoc::usage #exits app
125
+ end
126
+
127
+ def output_usage
128
+ output_version
129
+ RDoc::usage('usage') # gets usage from comments above
130
+ end
131
+
132
+ def output_version
133
+ puts "#{Application::VERSION::PRODUCT} version #{Application::VERSION::STRING}"
134
+ end
135
+
136
+ def process_command
137
+ # TO DO - do whatever this app does
138
+ # TO DO - place in local vars, etc
139
+ if @options.generate
140
+ target = File.expand_path(@options.project)
141
+ FileUtils.mkdir target
142
+ puts "generating #{target}"
143
+ FileUtils.cp_r(File.expand_path(File.join(AppConfig::ROOT, '..', 'template-prj'))+'/.', target, :verbose => !@options.quiet)
144
+
145
+ end
146
+
147
+ #process_standard_input # [Optional]
148
+ end
149
+
150
+ def process_standard_input
151
+ input = @stdin.read
152
+ # TO DO - process input
153
+
154
+ # [Optional]
155
+ # @stdin.each do |line|
156
+ # # TO DO - process each line
157
+ #end
158
+ end
159
+
160
+ def logger
161
+ @logger ||= setup_logger
162
+ end
163
+
164
+ def path(filename='')
165
+ File.expand_path(filename, APP_ROOT)
166
+ end
167
+
168
+ def run_app
169
+ AppConfig.logger.info echo("Data Gateway started")
170
+ AppConfig.logger.debug echo("Entorno: #{APP_ENV} \n Opciones: #{AppConfig.config.inspect}")
171
+ AppConfig.logger.info echo("job list: #{AppConfig.jobs.join(',')}")
172
+
173
+ include DataGateway
174
+ AppConfig.jobs.each do |job|
175
+ require File.join('jobs', job)
176
+ end
177
+ AppConfig.logger.info echo("Data Gateway finished ok")
178
+
179
+ rescue Exception => e
180
+ puts "Error:\n#{e}\n."
181
+ AppConfig.logger.error "#{e}\n" + e.backtrace.join("\n")
182
+ end
183
+
184
+ def log_path
185
+ path('log/application.log')
186
+ end
187
+
188
+ def settings(name)
189
+ env = (APP_ENV == 'production' ? '' : '.' + APP_ENV)
190
+ path("config#{env}/#{name}.yml")
191
+ end
192
+
193
+ def connections
194
+ unless @connections
195
+ @connections = yaml_load(settings('database'))
196
+ class << @connections
197
+ def [](name)
198
+ super(name.to_s)
199
+ end
200
+ end
201
+ end
202
+ return @connections
203
+ end
204
+
205
+ def [](name)
206
+ method_missing(name.to_sym)
207
+ end
208
+
209
+ private
210
+
211
+ def setup_logger
212
+ load
213
+ FileUtils.mkpath(File.dirname(log_path))
214
+ @logger = Logger.new(log_path, log_options['rotate'] )
215
+ @logger.progname = ''
216
+ @logger.formatter = LogFormatter.new
217
+ @logger.datetime_format = log_options['time_format']
218
+ @logger.level = (options.debug_on ? Logger::DEBUG : Logger.const_get(log_options['level'].upcase))
219
+ #@logger.level = Logger.const_get(log_options['level'].upcase)
220
+ @logger
221
+ rescue StandardError => e
222
+ @logger = Logger.new(STDERR)
223
+ @logger.level = Logger::WARN
224
+ @logger.formatter = LogFormatter.new
225
+ @logger.datetime_format = "%H:%M:%S"
226
+ @logger.warn e.message
227
+ @logger.warn(
228
+ "Unable to access log file. Please ensure that #{self.log_path} exists and has correct permissions. " +
229
+ "The log level has been raised to WARN and the output directed to STDERR until the problem is fixed."
230
+ )
231
+ @logger
232
+ end
233
+
234
+ def yaml_load(file_name)
235
+ YAML::load(ERB.new(IO.read(file_name)).result)
236
+ end
237
+
238
+ def load
239
+ return if @config
240
+ @config = yaml_load(settings('settings'))
241
+ end
242
+
243
+ def echo(msg)
244
+ puts msg unless AppConfig.options.quiet
245
+ msg
246
+ end
247
+
248
+ def method_missing(name, *args)
249
+ load
250
+ if (args.size > 0)
251
+ if /=$/ =~ name.to_s
252
+ @config[name.to_s.sub('=', '')]= *args
253
+ else
254
+ @config.send(name, *args)
255
+ end
256
+ elsif @config.has_key?(name.to_s) #@config.instance_variable_defined?(var_name)
257
+ @config[name.to_s] #@config.instance_variable_get(var_name)
258
+ else
259
+ super
260
+ end
261
+ end
262
+ end
263
+ end
264
+
265
+
266
+ __END__
267
+
268
+ AppConfig.parse_options
269
+
270
+ APP_ENV = AppConfig.options.environment unless defined?(APP_ENV)
271
+
272
+
273
+ ['actionmailer','actionpack', 'activerecord', 'activeresource', 'activesupport'].each {|gem|
274
+ $:.unshift File.join(File.dirname(__FILE__), '..', 'vendor', 'rails',gem, 'lib')
275
+ }
276
+
277
+
278
+ #gem 'activerecord', '<2.2.2'
279
+
280
+ require 'active_record'
281
+
282
+ ActiveRecord::Base.logger = AppConfig.logger
283
+ ActiveRecord::Base.colorize_logging = false
284
+
285
+ DataGateway.logger = AppConfig.logger
286
+ DataGateway.inbox = AppConfig.path(AppConfig.data['inbox'])
287
+ DataGateway.outbox = AppConfig.path(AppConfig.data['outbox'])
288
+ DataGateway.donebox = AppConfig.path(AppConfig.data['donebox'])
289
+ DataGateway.use_resources = AppConfig.data['use_resources']
290
+ DataGateway.resource_path(AppConfig.path(AppConfig.data['resource_path']))
291
+
292
+ AppConfig.jobs ||= []
293
+
294
+
data/lib/version.rb ADDED
@@ -0,0 +1,16 @@
1
+ require 'time'
2
+
3
+ module Application
4
+ module VERSION #:nodoc:
5
+ @res = File.join(File.dirname(__FILE__), '..', 'VERSION.yml')
6
+ PRODUCT = 'DataGateway'
7
+ COMPANY = 'Memory Comm S. L.'
8
+ AUTHOR = 'jorge.cangas@gmail.com'
9
+ NUMBER = YAML::load(ERB.new(IO.read(@res)).result)
10
+ #MAJOR = 1
11
+ #MINOR = 1
12
+ #TINY = 0
13
+ STRING = [NUMBER[:major], NUMBER[:minor], NUMBER[:patch]].join('.')
14
+ RELEASED_AT = Time.parse('2008/03/22 03:04:54')
15
+ end
16
+ end
File without changes
@@ -0,0 +1,4 @@
1
+ Carpeta para ficheros de configuracion:
2
+ - database.yml: conexiones a bases de datos en formato YAML.
3
+ - settings.yml: parametros de configuración generales en formato YAML.
4
+
@@ -0,0 +1,32 @@
1
+
2
+ nexusdb:
3
+ adapter: sqlserver
4
+ host: '.\NEXUS'
5
+ mode: ado # or odbc
6
+ username: sa
7
+ password: sie48
8
+ autocommit: true
9
+
10
+ # required for ado:
11
+ database: 'TRADE_SL'
12
+ nax_empresa: 'VTRADE'
13
+
14
+ #required for odbc:
15
+ #dsn:
16
+ #provider: SQLOLEDB
17
+
18
+
19
+ shopindb_production: &shopin_production
20
+ adapter: mysql
21
+ database: shopin
22
+ timeout: 5000
23
+ user: root
24
+ password: masterkey
25
+ socket: /var/run/mysqld/mysqld.sock
26
+
27
+ shopindb_development: &shopin_development
28
+ adapter: sqlite3
29
+ database: '../db/development.sqlite3'
30
+ timeout: 5000
31
+
32
+ shopindb: *shopin_development
@@ -0,0 +1,25 @@
1
+ sftp:
2
+ host: 192.168.0.3
3
+ upload_to: shopin-data/inbox
4
+ download_from: shopin-data/outbox
5
+ username: vallestrade
6
+ password: valles1234$
7
+
8
+ log_options:
9
+ level: info
10
+ rotate: daily
11
+ time_format: %H:%M:%S
12
+
13
+ data:
14
+ inbox: data/inbox
15
+ outbox: data/outbox
16
+ donebox: data/donebox
17
+ use_resources: false
18
+ resource_path: C:/Archivos de programa/SIE/NEXUS/shopin/img/
19
+
20
+ jobs:
21
+ #- nexus_export
22
+ #- nexus_import
23
+ #- shopin_export
24
+ - shopin_import
25
+
@@ -0,0 +1 @@
1
+ Esta carpeta contine los ficheros que han sido recibidos y procesados
@@ -0,0 +1 @@
1
+ Esta carpeta contine los ficheros que han sido recibidos y estan pendientes de procesarse
@@ -0,0 +1 @@
1
+ Esta carpeta contine los ficheros que han sido pendientes de ser enviados
@@ -0,0 +1,18 @@
1
+ require 'datagateway'
2
+
3
+ begin
4
+ AppConfig.logger.info echo("Data Gateway started")
5
+ AppConfig.logger.debug echo("Entorno: #{APP_ENV} \n Opciones: #{AppConfig.config.inspect}")
6
+ AppConfig.logger.info echo("job list: #{AppConfig.jobs.join(',')}")
7
+
8
+ include DataGateway
9
+ AppConfig.jobs.each do |job|
10
+ #require File.join('jobs', job)
11
+ end
12
+ AppConfig.logger.info echo("Data Gateway finished ok")
13
+
14
+ rescue Exception => e
15
+ puts "Error:\n#{e}\n."
16
+ AppConfig.logger.error "#{e}\n" + e.backtrace.join("\n")
17
+ end
18
+
@@ -0,0 +1,2 @@
1
+ Carpeta para contener ficheros de historial de ejecucion. El numero de ficheros
2
+ variara segun la configuracion
@@ -0,0 +1,7 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+
3
+ class DatagatewayTest < Test::Unit::TestCase
4
+ should "probably rename this file and start testing for real" do
5
+ flunk "hey buddy, you should probably rename this file and start testing for real"
6
+ end
7
+ end
@@ -0,0 +1,10 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+ require 'shoulda'
4
+ require 'mocha'
5
+
6
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
7
+ require 'datagateway'
8
+
9
+ class Test::Unit::TestCase
10
+ end