crane 0.1.9

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,118 @@
1
+ require "net/ftp"
2
+ require "crane/config"
3
+ require File.expand_path("../../shell/shell.rb", __FILE__)
4
+
5
+ module Crane
6
+
7
+ class Engine < Shell::Run
8
+
9
+ include Config
10
+ # @argv
11
+ # @command
12
+ # options
13
+
14
+ def initialize argv = []
15
+ return true if defined? TESTING
16
+ require File.expand_path("../ftp.rb", __FILE__)
17
+
18
+ super argv
19
+ @ftp = nil
20
+ @config = Config.load_config
21
+ @ignored_files = get_ignored_files
22
+ @local_files = []
23
+
24
+ @errors = []
25
+ @connection = nil
26
+
27
+ (help; exit) if ["help", "h"].any? { |e| true if Shell::Parser.get_options(@argv).include? e }
28
+ (version; exit) if ["version", "v"].any? { |e| true if Shell::Parser.get_options(@argv).include? e }
29
+
30
+ begin
31
+ run unless defined? TESTING
32
+ rescue Interrupt
33
+ puts "\n"
34
+ rescue
35
+
36
+ end
37
+ end
38
+
39
+ # return an instance of a FTP connection
40
+ def connect_ftp
41
+ require "net/ftp"
42
+ require 'timeout'
43
+ result = true
44
+
45
+ if @connection.nil? then
46
+ host = @config['ftp']['host_address']
47
+ username = @config['ftp']['username']
48
+ password = @config['ftp']['password']
49
+ @connection = Net::FTP.new
50
+ @connection.passive = true
51
+ begin
52
+ Timeout.timeout(7) do
53
+ @connection.connect host, 21
54
+ end
55
+ rescue
56
+ @connection_error = "couldn't connect to host"
57
+ result = false
58
+ end
59
+
60
+ begin
61
+ Timeout.timeout(4) do
62
+ @connection.login username, password
63
+ end
64
+ rescue
65
+ @connection_error = "invalid username/password"
66
+ result = false
67
+ end
68
+ end
69
+
70
+ if result == false
71
+ @connection = false
72
+ end
73
+
74
+ @connection
75
+
76
+ end # connect_ftp
77
+
78
+ # if there was typed any argument on ARGV starting with either -- or -
79
+ def is_option option
80
+ Shell::Parser.is_option option, @argv
81
+ end
82
+
83
+ def get_ignored_files
84
+ require File.expand_path("../config.rb", __FILE__);
85
+ Config.get_ignored_files || []
86
+ end
87
+
88
+ def no_command
89
+ help
90
+ end
91
+
92
+ def version
93
+ require "crane/version"
94
+ print "Crane v" + Crane::VERSION + "\n"
95
+ end
96
+
97
+ def help
98
+ print "Usage:\n"
99
+ print "\s\scrane COMMAND [options]"
100
+ print "\n\n"
101
+ print "Commands available:"
102
+ print "\n"
103
+ print "\s\spush\t\tSend files to a remote server"
104
+ print "\n\n"
105
+ print "Examples:"
106
+ print "\n"
107
+ print "\s\scrane push 1h"
108
+ print "\n"
109
+ print "\t\tPushes all files modified in the last hour.\n"
110
+ print "\n"
111
+ print "For more information, try:\n"
112
+ print "\s\scrane COMMAND -h"
113
+ print "\n"
114
+ end
115
+
116
+ end
117
+
118
+ end
data/lib/crane/ftp.rb ADDED
@@ -0,0 +1,142 @@
1
+ require "net/ftp"
2
+ require 'timeout'
3
+
4
+ module Crane
5
+
6
+ class Ftp
7
+
8
+ attr_accessor :connection, :connection_error
9
+
10
+ def initialize c = false
11
+ @connection = nil
12
+ @existent_dirs = []
13
+ @nlst = {}
14
+ unless c
15
+ config = Config.load_config
16
+ unless config.empty?
17
+ c = {}
18
+ c[:ftp] = config[:ftp] unless config[:ftp].empty?
19
+ end
20
+ end
21
+ connect(c) if c
22
+ self
23
+ end
24
+
25
+ def connect c = {}
26
+ port = c[:port] || 21
27
+ c = c[:ftp] if c.include? :ftp
28
+
29
+ return false unless c.has_key? :host
30
+
31
+ @connection = Net::FTP.new
32
+ @connection_error = false
33
+ @connection.passive = true
34
+ begin
35
+ Timeout.timeout(10) do
36
+ @connection.connect c[:host], port
37
+ end
38
+ rescue Timeout::Error
39
+ @connection_error = "Timeout on connection"
40
+ rescue
41
+ @connection_error = "Error on connection FTP"
42
+ end
43
+
44
+ begin
45
+ Timeout.timeout(20) do
46
+ @connection.login c[:username], c[:password]
47
+ end
48
+ rescue Timeout::Error
49
+ @connection_error = "Timeout on authentication (20 seconds)"
50
+ rescue Net::FTPPermError
51
+ @connection_error = "Invalid username/password"
52
+ rescue
53
+ @connection_error = "Unknown error related to username/password"
54
+ end
55
+
56
+ return false if @connection_error
57
+ true
58
+ end
59
+
60
+ def remote_dir_exists? remote_dir = false
61
+ return nil if Config.load_config.empty?
62
+ connect(Config.CONFIG[:ftp]) if @connection.nil?
63
+
64
+ begin
65
+ Timeout.timeout(10) do
66
+ @connection.chdir(remote_dir || Config.CONFIG[:ftp][:remote_root_dir])
67
+ end
68
+ rescue
69
+ return false
70
+ end
71
+ @connection.close
72
+ true
73
+ end
74
+
75
+ def close
76
+ @connection.close
77
+ end
78
+
79
+ def putbinaryfile f, f2
80
+ @connection.putbinaryfile f, f2
81
+ end
82
+
83
+ def chdir var
84
+ @connection.chdir var
85
+ end
86
+
87
+ # Accepts deep directories as parameter
88
+ def mkdir dir
89
+ each_dir = dir.split("/")
90
+ return false if dir.empty?
91
+ last_dir = ""
92
+
93
+ each_dir.each { |d|
94
+ next if ["", ".", ".."].include? d
95
+
96
+ slashed_d = "/" + d if d[0,1] != "/"
97
+ current_dir = last_dir + slashed_d
98
+
99
+ if @existent_dirs.include? current_dir
100
+ last_dir << slashed_d
101
+ next
102
+ else
103
+ @connection.chdir last_dir unless last_dir.empty?
104
+
105
+ if @nlst.include? last_dir
106
+ nlst = @nlst[last_dir]
107
+ else
108
+ nlst = @connection.nlst
109
+ end
110
+ @nlst[last_dir] = nlst
111
+ if nlst.include? d
112
+ @existent_dirs << current_dir
113
+ last_dir << slashed_d
114
+ next
115
+ else
116
+ @connection.mkdir d
117
+ @connection.chdir current_dir
118
+ last_dir << slashed_d
119
+ @existent_dirs << current_dir
120
+ end
121
+ end
122
+ }
123
+ @connection.chdir pwd
124
+ end
125
+
126
+ def pwd
127
+ @connection.pwd
128
+ end
129
+
130
+ private
131
+ def map_args args
132
+ result = {}
133
+ args.each { |k,v|
134
+ result[k] = v
135
+ }
136
+ result
137
+ end #map_args
138
+
139
+ end
140
+
141
+
142
+ end
@@ -0,0 +1,55 @@
1
+ require "shell/shell"
2
+ require "crane"
3
+ require "crane/crane"
4
+
5
+ module Shell
6
+ class Initializer
7
+
8
+ attr_accessor :command
9
+
10
+ def initialize argv
11
+ @args = argv
12
+ get_command
13
+ run
14
+ end
15
+
16
+ def run
17
+ if @command
18
+ if command_exist?
19
+ require get_command_file
20
+ return run_command @command
21
+ end
22
+ end
23
+ inexistent_command
24
+ end
25
+
26
+ def should_exit?
27
+ return false || true unless @command
28
+ end
29
+
30
+ def get_command
31
+ @command = Shell::Parser::get_command @args
32
+ end
33
+
34
+ def command_exist? command = false
35
+ File.exists? get_command_file(command)
36
+ end
37
+
38
+ def get_command_file command = false
39
+ command = @command unless command
40
+ File.expand_path("../commands/" + command + ".rb", __FILE__)
41
+ end
42
+
43
+ def run_command command, args = []
44
+ command = @command unless command
45
+ return inexistent_command unless command_exist?(command)
46
+ require get_command_file(command)
47
+ command = command.capitalize
48
+ @command_obj = Crane::Commands.const_get(command).new(@args)
49
+ end
50
+
51
+ def inexistent_command
52
+ @command_obj = Crane::Engine.new(@args)
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,3 @@
1
+ module Crane
2
+ VERSION = "0.1.9"
3
+ end
@@ -0,0 +1,125 @@
1
+ module Shell
2
+
3
+ class Run
4
+
5
+ # all arguments passed
6
+ @argv
7
+
8
+ def initialize argv
9
+ @argv = argv
10
+
11
+ @options = Shell::Parser.get_options @argv
12
+ @command = Shell::Parser.get_command @argv
13
+ @arguments = Shell::Parser.get_arguments @argv
14
+ end
15
+
16
+ end
17
+
18
+ class Input
19
+
20
+ def self.text
21
+ STDOUT.flush
22
+ STDIN.gets.strip
23
+ end
24
+
25
+ def self.yesno message
26
+ STDOUT.flush
27
+ has_result = false
28
+ while has_result == false
29
+ print message.strip + " "
30
+ input = STDIN.gets.strip
31
+
32
+ if input == "yes" or input == "y" then
33
+ final_input = "yes"
34
+ elsif input == "no" or input == "n" then
35
+ final_input = "no"
36
+ end
37
+
38
+ if ( final_input == "yes" or final_input == "no" )
39
+ has_result = true
40
+ end
41
+ end
42
+
43
+ if final_input == "yes"
44
+ result = true
45
+ else
46
+ result = false
47
+ end
48
+ result
49
+ end
50
+
51
+ end
52
+
53
+ class Parser
54
+
55
+ # ARGV has a command, options and arguments. The design is:
56
+ #
57
+ # $ bin_file command argument1 argument2 -option1 -option2
58
+ #
59
+ # get_options() and get_arguments() return Array. get_command()
60
+ # returns String.
61
+
62
+ def self.get_command argv = []
63
+ command = String.new
64
+
65
+ argv.each {
66
+ |e|
67
+ e_length = e.length
68
+ if (e[0,2] != "--" and e[0,1] != "-") then
69
+ command = e
70
+ break
71
+ end
72
+ }
73
+ return false if command.empty?
74
+ command
75
+ end
76
+
77
+ def self.get_options argv
78
+ return [] if argv.nil?
79
+ @options = []
80
+ @sanitized_options = []
81
+
82
+ argv.each {
83
+ |e|
84
+ e_length = e.length
85
+ if e[0,2] == "--"
86
+ @options.push e[2,e_length]
87
+ elsif e[0,1] == "-"
88
+ @options.push e[1,e_length]
89
+ end
90
+ }
91
+ unless @options.empty?
92
+ @options.each { |e|
93
+ next if @sanitized_options.include?(e)
94
+ @sanitized_options << e
95
+ }
96
+ end
97
+
98
+ @sanitized_options
99
+ end
100
+
101
+ def self.get_arguments argv
102
+ @arguments = []
103
+ i = 0
104
+ argv.each {
105
+ |e|
106
+
107
+ i+= 1
108
+ next if i == 1
109
+
110
+ e_length = e.length
111
+ if e[0,2] != "--" and e[0,1] != "-"
112
+ @arguments.push e[0,e_length]
113
+ end
114
+ }
115
+ @arguments
116
+ end
117
+
118
+ def self.is_option option, argv = []
119
+ argv_options = self.get_options argv
120
+ argv_options.include?(option)
121
+ end
122
+
123
+ end
124
+
125
+ end