foscam-ruby 0.0.3 → 0.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.
- checksums.yaml +6 -14
- data/.travis.yml +1 -1
- data/foscam-ruby.gemspec +1 -0
- data/lib/foscam-ruby.rb +20 -0
- data/lib/foscam/client.rb +69 -248
- data/lib/foscam/constants.rb +144 -0
- data/lib/foscam/model/alarm_config.rb +147 -0
- data/lib/foscam/model/base.rb +48 -0
- data/lib/foscam/model/device.rb +92 -0
- data/lib/foscam/model/ftp_server.rb +109 -0
- data/lib/foscam/model/mail_server.rb +124 -0
- data/lib/foscam/model/network.rb +79 -0
- data/lib/foscam/model/user.rb +174 -0
- data/lib/foscam/schedule/day.rb +63 -0
- data/lib/foscam/schedule/third_of_a_day.rb +42 -0
- data/lib/foscam/schedule/week.rb +89 -0
- data/lib/foscam/version.rb +1 -1
- data/spec/foscam/client_spec.rb +18 -60
- data/spec/foscam/model/alarm_config_spec.rb +164 -0
- data/spec/foscam/model/base_spec.rb +22 -0
- data/spec/foscam/model/device_spec.rb +136 -0
- data/spec/foscam/model/ftp_server_spec.rb +135 -0
- data/spec/foscam/model/mail_server_spec.rb +126 -0
- data/spec/foscam/model/network_spec.rb +128 -0
- data/spec/foscam/model/user_spec.rb +322 -0
- data/spec/foscam/schedule/day_spec.rb +37 -0
- data/spec/foscam/schedule/third_of_a_day_spec.rb +42 -0
- data/spec/foscam/schedule/week_spec.rb +109 -0
- metadata +64 -19
@@ -0,0 +1,144 @@
|
|
1
|
+
module Foscam
|
2
|
+
# DDNS_STATUS
|
3
|
+
DDNS_STATUS = {
|
4
|
+
0 => "No Action",
|
5
|
+
1 => "It's connecting...",
|
6
|
+
2 => "Can't connect to the Server",
|
7
|
+
3 => "Dyndns Succeed",
|
8
|
+
4 => "DynDns Failed: Dyndns.org Server Error",
|
9
|
+
5 => "DynDns Failed: Incorrect User or Password",
|
10
|
+
6 => "DynDns Failed: Need Credited User",
|
11
|
+
7 => "DynDns Failed: Illegal Host Format",
|
12
|
+
8 => "DynDns Failed: The Host Does not Exist",
|
13
|
+
9 => "DynDns Failed: The Host Does not Belong to You",
|
14
|
+
10 => "DynDns Failed: Too Many or Too Few Hosts",
|
15
|
+
11 => "DynDns Failed: The Host is Blocked for Abusing",
|
16
|
+
12 => "DynDns Failed: Bad Reply from Server",
|
17
|
+
13 => "DynDns Failed: Bad Reply from Server",
|
18
|
+
14 => "Oray Failed: Bad Reply from Server",
|
19
|
+
15 => "Oray Failed: Incorrect User or Password",
|
20
|
+
16 => "Oray Failed: Incorrect Hostname",
|
21
|
+
17 => "Oray Succeed"
|
22
|
+
}
|
23
|
+
|
24
|
+
# UPNP_STATUS
|
25
|
+
UPNP_STATUS = {
|
26
|
+
0 => "No Action",
|
27
|
+
1 => "Succeed",
|
28
|
+
2 => "Device System Error",
|
29
|
+
3 => "Errors in Network Communication",
|
30
|
+
4 => "Errors in Chat with UPnP Device",
|
31
|
+
5 => "Rejected by UPnP Device, Maybe Port Conflict"
|
32
|
+
}
|
33
|
+
|
34
|
+
# ALARM_STATUS
|
35
|
+
ALARM_STATUS = {
|
36
|
+
0 => "No alarm",
|
37
|
+
1 => "Motion alarm",
|
38
|
+
2 => "Input Alarm"
|
39
|
+
}
|
40
|
+
|
41
|
+
# CAMERA_PARAMS_MODE
|
42
|
+
CAMERA_PARAMS_MODE = {
|
43
|
+
0 => "50hz",
|
44
|
+
1 => "60hz",
|
45
|
+
2 => "outdoor"
|
46
|
+
}
|
47
|
+
|
48
|
+
# CAMERA_CONTROL_MODE
|
49
|
+
CAMERA_CONTROL_MODE = CAMERA_PARAMS_MODE.inject({}){|memo,(k,v)| memo[v.to_sym] = k; memo}
|
50
|
+
|
51
|
+
# CAMERA_PARAMS_ORIENTATION
|
52
|
+
CAMERA_PARAMS_ORIENTATION = {
|
53
|
+
0 => "default",
|
54
|
+
1 => "flip",
|
55
|
+
2 => "mirror",
|
56
|
+
3 => "flip+mirror"
|
57
|
+
}
|
58
|
+
|
59
|
+
# CAMERA_CONTROL_ORIENTATION
|
60
|
+
CAMERA_CONTROL_ORIENTATION = CAMERA_PARAMS_ORIENTATION.inject({}){|memo,(k,v)| memo[v.to_sym] = k; memo}
|
61
|
+
|
62
|
+
# CAMERA_PARAMS_RESOLUTION
|
63
|
+
CAMERA_PARAMS_RESOLUTION = {
|
64
|
+
8 => "qvga",
|
65
|
+
32 => "vga"
|
66
|
+
}
|
67
|
+
|
68
|
+
# CAMERA_CONTROL_RESOLUTION
|
69
|
+
CAMERA_CONTROL_RESOLUTION = CAMERA_PARAMS_RESOLUTION.inject({}){|memo,(k,v)| memo[v.to_sym] = k; memo}
|
70
|
+
|
71
|
+
# CAMERA_CONTROLS
|
72
|
+
CAMERA_CONTROLS = {
|
73
|
+
:resolution => 0,
|
74
|
+
:brightness => 1,
|
75
|
+
:contrast => 2,
|
76
|
+
:mode => 3,
|
77
|
+
:flip => 5
|
78
|
+
}
|
79
|
+
|
80
|
+
# DECODER_CONTROLS
|
81
|
+
DECODER_CONTROLS = {
|
82
|
+
:up => 0,
|
83
|
+
:stop => 1,
|
84
|
+
:stop_up => 1,
|
85
|
+
:down => 2,
|
86
|
+
:stop_down => 3,
|
87
|
+
:left => 4,
|
88
|
+
:stop_left => 5,
|
89
|
+
:right => 6,
|
90
|
+
:stop_right => 7,
|
91
|
+
:center => 25,
|
92
|
+
:vertical_patrol => 26,
|
93
|
+
:stop_vertical_patrol => 27,
|
94
|
+
:horizon_patrol => 28,
|
95
|
+
:stop_horizon_patrol => 29,
|
96
|
+
:io_output_high => 94,
|
97
|
+
:io_output_low => 95,
|
98
|
+
}
|
99
|
+
|
100
|
+
# USER_PERMISSIONS
|
101
|
+
USER_PERMISSIONS = {
|
102
|
+
0 => :visitor,
|
103
|
+
1 => :operator,
|
104
|
+
2 => :administrator
|
105
|
+
}
|
106
|
+
|
107
|
+
# USER_PERMISSIONS_ID
|
108
|
+
USER_PERMISSIONS_ID = USER_PERMISSIONS.invert
|
109
|
+
|
110
|
+
# PTZ_AUTO_PATROL_TYPE
|
111
|
+
PTZ_AUTO_PATROL_TYPE = {
|
112
|
+
0 => :none,
|
113
|
+
1 => :horizontal,
|
114
|
+
2 => :vertical,
|
115
|
+
3 => :"horizontal+vertical"
|
116
|
+
}
|
117
|
+
|
118
|
+
# PTZ_AUTO_PATROL_TYPE_ID
|
119
|
+
PTZ_AUTO_PATROL_TYPE_ID = PTZ_AUTO_PATROL_TYPE.invert
|
120
|
+
|
121
|
+
# LED_MODE
|
122
|
+
LED_MODE = {
|
123
|
+
0 => :mode1,
|
124
|
+
1 => :mode2,
|
125
|
+
2 => :disabled
|
126
|
+
}
|
127
|
+
|
128
|
+
# LED_MODE_ID
|
129
|
+
LED_MODE_ID = LED_MODE.invert
|
130
|
+
|
131
|
+
# DECODER_BAUD
|
132
|
+
DECODER_BAUD = {
|
133
|
+
9 => :B1200,
|
134
|
+
11 => :B2400,
|
135
|
+
12 => :B4800,
|
136
|
+
13 => :B9600,
|
137
|
+
14 => :B19200,
|
138
|
+
15 => :B38400,
|
139
|
+
4097 => :B57600,
|
140
|
+
4098 => :B115200
|
141
|
+
}
|
142
|
+
# DECODER_BAUD_ID
|
143
|
+
DECODER_BAUD_ID = DECODER_BAUD.invert
|
144
|
+
end
|
@@ -0,0 +1,147 @@
|
|
1
|
+
module Foscam
|
2
|
+
module Model
|
3
|
+
class AlarmConfig < Base
|
4
|
+
include Singleton
|
5
|
+
|
6
|
+
define_model_callbacks :save
|
7
|
+
|
8
|
+
attr_reader :motion_armed, :motion_sensitivity, :motion_compensation, :input_armed, :ioin_level, :iolinkage, :preset, :ioout_level, :mail, :upload_interval, :http, :http_url, :msn, :schedule_enable, :schedule
|
9
|
+
|
10
|
+
|
11
|
+
def motion_armed=(val)
|
12
|
+
motion_armed_will_change! unless val == @motion_armed
|
13
|
+
@motion_armed = val
|
14
|
+
end
|
15
|
+
|
16
|
+
def motion_sensitivity=(val)
|
17
|
+
motion_sensitivity_will_change! unless val == @motion_sensitivity
|
18
|
+
@motion_sensitivity = val
|
19
|
+
end
|
20
|
+
|
21
|
+
def motion_compensation=(val)
|
22
|
+
motion_compensation_will_change! unless val == @motion_compensation
|
23
|
+
@motion_compensation = val
|
24
|
+
end
|
25
|
+
|
26
|
+
def input_armed=(val)
|
27
|
+
input_armed_will_change! unless val == @input_armed
|
28
|
+
@input_armed = val
|
29
|
+
end
|
30
|
+
|
31
|
+
def ioin_level=(val)
|
32
|
+
ioin_level_will_change! unless val == @ioin_level
|
33
|
+
@ioin_level = val
|
34
|
+
end
|
35
|
+
|
36
|
+
def iolinkage=(val)
|
37
|
+
iolinkage_will_change! unless val == @iolinkage
|
38
|
+
@iolinkage = val
|
39
|
+
end
|
40
|
+
|
41
|
+
def preset=(val)
|
42
|
+
preset_will_change! unless val == @preset
|
43
|
+
@preset = val
|
44
|
+
end
|
45
|
+
|
46
|
+
def ioout_level=(val)
|
47
|
+
ioout_level_will_change! unless val == @ioout_level
|
48
|
+
@ioout_level = val
|
49
|
+
end
|
50
|
+
|
51
|
+
def mail=(val)
|
52
|
+
mail_will_change! unless val == @mail
|
53
|
+
@mail = val
|
54
|
+
end
|
55
|
+
|
56
|
+
|
57
|
+
def upload_interval=(val)
|
58
|
+
upload_interval_will_change! unless val == @upload_interval
|
59
|
+
@upload_interval = val
|
60
|
+
end
|
61
|
+
|
62
|
+
def http=(val)
|
63
|
+
http_will_change! unless val == @http
|
64
|
+
@http = val
|
65
|
+
end
|
66
|
+
|
67
|
+
def http_url=(val)
|
68
|
+
http_url_will_change! unless val == @http_url
|
69
|
+
@http_url = val
|
70
|
+
end
|
71
|
+
|
72
|
+
def msn=(val)
|
73
|
+
msn_will_change! unless val == @msn
|
74
|
+
@msn = val
|
75
|
+
end
|
76
|
+
|
77
|
+
def schedule_enable=(val)
|
78
|
+
schedule_enable_will_change! unless val == @schedule_enable
|
79
|
+
@schedule_enable = val
|
80
|
+
end
|
81
|
+
|
82
|
+
def schedule=(val)
|
83
|
+
schedule_will_change! unless val == @schedule
|
84
|
+
@schedule = val
|
85
|
+
end
|
86
|
+
|
87
|
+
def client=(obj)
|
88
|
+
unless obj.nil?
|
89
|
+
AlarmConfig::client = obj
|
90
|
+
params = client.get_params
|
91
|
+
unless params.empty?
|
92
|
+
self.motion_armed = params[:alarm_motion_armed]
|
93
|
+
self.motion_sensitivity = params[:alarm_motion_sensitivity]
|
94
|
+
self.motion_compensation = params[:alarm_motion_compensation]
|
95
|
+
self.input_armed = params[:alarm_input_armed]
|
96
|
+
self.ioin_level = params[:alarm_ioin_level]
|
97
|
+
self.iolinkage = params[:alarm_iolinkage]
|
98
|
+
self.preset = params[:alarm_preset]
|
99
|
+
self.ioout_level = params[:alarm_ioout_level]
|
100
|
+
self.mail = params[:alarm_mail]
|
101
|
+
self.http = params[:alarm_http]
|
102
|
+
self.msn = params[:alarm_msn]
|
103
|
+
self.http_url = params[:alarm_http_url]
|
104
|
+
self.schedule_enable = params[:alarm_schedule_enable]
|
105
|
+
self.schedule = params[:alarm_schedule]
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
define_attribute_methods [:motion_armed, :motion_sensitivity, :motion_compensation, :input_armed, :ioin_level, :iolinkage, :preset, :ioout_level, :mail, :upload_interval, :http, :http_url, :msn, :schedule_enable, :schedule]
|
111
|
+
|
112
|
+
def save
|
113
|
+
run_callbacks :save do
|
114
|
+
flag = false
|
115
|
+
if changed? && is_valid?
|
116
|
+
@previously_changed = changes
|
117
|
+
flag = client.set_alarm(dirty_params_hash)
|
118
|
+
@changed_attributes.clear if flag
|
119
|
+
end
|
120
|
+
flag
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
private
|
125
|
+
|
126
|
+
def dirty_params_hash
|
127
|
+
h = {}
|
128
|
+
h.merge!({:motion_armed => self.motion_armed }) if motion_armed_changed?
|
129
|
+
h.merge!({:motion_sensitivity => self.motion_sensitivity }) if motion_sensitivity_changed?
|
130
|
+
h.merge!({:motion_compensation => self.motion_compensation }) if motion_compensation_changed?
|
131
|
+
h.merge!({:input_armed => self.input_armed }) if input_armed_changed?
|
132
|
+
h.merge!({:ioin_level => self.ioin_level }) if ioin_level_changed?
|
133
|
+
h.merge!({:iolinkage => self.iolinkage }) if iolinkage_changed?
|
134
|
+
h.merge!({:preset => self.preset }) if preset_changed?
|
135
|
+
h.merge!({:ioout_level => self.ioout_level }) if ioout_level_changed?
|
136
|
+
h.merge!({:mail => self.mail }) if mail_changed?
|
137
|
+
h.merge!({:upload_interval => self.upload_interval }) if upload_interval_changed?
|
138
|
+
h.merge!({:http => self.http }) if http_changed?
|
139
|
+
h.merge!({:msn => self.msn }) if msn_changed?
|
140
|
+
# h.merge!({:http_url => self.http_url }) if http_url_changed?
|
141
|
+
h.merge!({:schedule_enable => self.schedule_enable }) if schedule_enable_changed?
|
142
|
+
# h.merge!({:schedule => self.schedule }) if schedule_changed?
|
143
|
+
h
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module Foscam
|
2
|
+
module Model
|
3
|
+
class Base
|
4
|
+
include ::ActiveModel::Dirty
|
5
|
+
include ::ActiveModel::Validations
|
6
|
+
include ::ActiveModel::Conversion
|
7
|
+
extend ::ActiveModel::Callbacks
|
8
|
+
extend ::ActiveModel::Naming
|
9
|
+
extend ::ActiveModel::Translation
|
10
|
+
|
11
|
+
|
12
|
+
# the Foscam client connection
|
13
|
+
cattr_accessor :client
|
14
|
+
|
15
|
+
define_model_callbacks :initialize, :only => [:after]
|
16
|
+
##
|
17
|
+
# @param params [Hash] Device attributes
|
18
|
+
# @option params [Fixnum] :resolution
|
19
|
+
# @option params [Fixnum] :brightness
|
20
|
+
# @option params [Fixnum] :contrast
|
21
|
+
# @option params [String] :orientation
|
22
|
+
def initialize(params ={})
|
23
|
+
# Check if it is a Hash
|
24
|
+
# get the parameters and set them to the attributes
|
25
|
+
run_callbacks :initialize do
|
26
|
+
params.each do |attr, value|
|
27
|
+
self.public_send("#{attr}=", value)
|
28
|
+
end if params
|
29
|
+
end
|
30
|
+
# Check if it is a Foscam::Client
|
31
|
+
end
|
32
|
+
|
33
|
+
##
|
34
|
+
# Connects to the foscam webcam
|
35
|
+
# @param url [String] The address to your camera
|
36
|
+
# @param username [String] username to authorize with the camera
|
37
|
+
# @param password [String] password to authorize with the camera
|
38
|
+
def connect(params)
|
39
|
+
client = ::Foscam::Client.new(params) if params.has_key?(:url)
|
40
|
+
end
|
41
|
+
|
42
|
+
#:nodoc
|
43
|
+
def persisted?
|
44
|
+
true
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
|
2
|
+
module Foscam
|
3
|
+
module Model
|
4
|
+
class Device < Base
|
5
|
+
include Singleton
|
6
|
+
|
7
|
+
define_model_callbacks :save
|
8
|
+
|
9
|
+
# attr_accessor :name (get_params, set_alias)
|
10
|
+
# attr_accessor :name (get_misc, set_misc)
|
11
|
+
attr_reader :resolution, :brightness, :contrast, :orientation
|
12
|
+
|
13
|
+
def resolution=(val)
|
14
|
+
resolution_will_change! unless val == @resolution
|
15
|
+
@resolution = val
|
16
|
+
end
|
17
|
+
|
18
|
+
def brightness=(val)
|
19
|
+
brightness_will_change! unless val == @brightness
|
20
|
+
@brightness = val
|
21
|
+
end
|
22
|
+
|
23
|
+
def contrast=(val)
|
24
|
+
contrast_will_change! unless val == @contrast
|
25
|
+
@contrast = val
|
26
|
+
end
|
27
|
+
|
28
|
+
def orientation=(val)
|
29
|
+
orientation_will_change! unless val == @orientation
|
30
|
+
@orientation = val
|
31
|
+
end
|
32
|
+
|
33
|
+
def client=(obj)
|
34
|
+
unless obj.nil?
|
35
|
+
Device::client = obj
|
36
|
+
cam_params = client.get_camera_params
|
37
|
+
unless cam_params.empty?
|
38
|
+
@resolution = cam_params[:resolution]
|
39
|
+
@brightness = cam_params[:brightness]
|
40
|
+
@contrast = cam_params[:contrast]
|
41
|
+
@orientation = cam_params[:flip]
|
42
|
+
# mode
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
define_attribute_methods [:resolution, :brightness, :contrast, :orientation]
|
48
|
+
|
49
|
+
##
|
50
|
+
# Save the current device
|
51
|
+
# @return [FalseClass, TrueClass] Whether or not the device was successfully saved
|
52
|
+
def save
|
53
|
+
run_callbacks :save do
|
54
|
+
flag = false
|
55
|
+
if changed? && is_valid?
|
56
|
+
@previously_changed = changes
|
57
|
+
flag = client.camera_control(dirty_params_hash)
|
58
|
+
@changed_attributes.clear if flag
|
59
|
+
end
|
60
|
+
flag
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
##
|
65
|
+
# Capture the current image
|
66
|
+
# @return [nil, ::MiniMagick::Image]
|
67
|
+
def capture
|
68
|
+
client.snapshot
|
69
|
+
end
|
70
|
+
|
71
|
+
##
|
72
|
+
# Preform a decoder action
|
73
|
+
# @param value [Symbol] The desired motion action to be sent to the camera
|
74
|
+
# @return [FalseClass,TrueClass] whether the request was successful.
|
75
|
+
def action(value)
|
76
|
+
# have an action map to map some subset to the foscam set
|
77
|
+
client.decoder_control(value)
|
78
|
+
end
|
79
|
+
|
80
|
+
private
|
81
|
+
|
82
|
+
def dirty_params_hash
|
83
|
+
h = {}
|
84
|
+
h.merge!({:resolution => @resolution}) if resolution_changed?
|
85
|
+
h.merge!({:brightness => @brightness}) if brightness_changed?
|
86
|
+
h.merge!({:contrast => @contrast}) if contrast_changed?
|
87
|
+
h.merge!({:flip => @orientation}) if orientation_changed?
|
88
|
+
h
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,109 @@
|
|
1
|
+
# * :ftp_svr (String)
|
2
|
+
# * :ftp_port (String)
|
3
|
+
# * :ftp_user (String)
|
4
|
+
# * :ftp_pwd (String)
|
5
|
+
# * :ftp_dir (String)
|
6
|
+
# * :ftp_mode (String)
|
7
|
+
# * :ftp_upload_interval (String)
|
8
|
+
# * :ftp_filename (String)
|
9
|
+
# * :ftp_numberoffiles (Fixnum)
|
10
|
+
# * :ftp_schedule_enable (FalseClass, TrueClass)
|
11
|
+
# * :ftp_schedule (Fixnum)
|
12
|
+
|
13
|
+
module Foscam
|
14
|
+
module Model
|
15
|
+
class FtpServer < Base
|
16
|
+
|
17
|
+
include Singleton
|
18
|
+
|
19
|
+
|
20
|
+
define_model_callbacks :save, :clear
|
21
|
+
|
22
|
+
attr_reader :dir, :username, :password, :address, :port, :upload_interval, :schedule
|
23
|
+
|
24
|
+
|
25
|
+
def dir=(val)
|
26
|
+
dir_will_change! unless val == @dir
|
27
|
+
@dir = val
|
28
|
+
end
|
29
|
+
|
30
|
+
def username=(val)
|
31
|
+
username_will_change! unless val == @username
|
32
|
+
@username = val
|
33
|
+
end
|
34
|
+
|
35
|
+
def password=(val)
|
36
|
+
password_will_change! unless val == @password
|
37
|
+
@password = val
|
38
|
+
end
|
39
|
+
|
40
|
+
def address=(val)
|
41
|
+
address_will_change! unless val == @address
|
42
|
+
@address = val
|
43
|
+
end
|
44
|
+
|
45
|
+
def port=(val)
|
46
|
+
port_will_change! unless val == @port
|
47
|
+
@port = val
|
48
|
+
end
|
49
|
+
|
50
|
+
def upload_interval=(val)
|
51
|
+
upload_interval_will_change! unless val == @upload_interval
|
52
|
+
@upload_interval = val
|
53
|
+
end
|
54
|
+
|
55
|
+
|
56
|
+
def client=(obj)
|
57
|
+
unless obj.nil?
|
58
|
+
FtpServer::client = obj
|
59
|
+
params = client.get_params
|
60
|
+
unless params.empty?
|
61
|
+
self.dir = params[:ftp_dir]
|
62
|
+
self.address = params[:ftp_svr]
|
63
|
+
self.port = params[:ftp_port]
|
64
|
+
self.username = params[:ftp_user]
|
65
|
+
self.password = params[:ftp_pwd]
|
66
|
+
self.upload_interval = params[:ftp_upload_interval]
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
define_attribute_methods [:dir, :username, :password, :address, :port, :upload_interval]
|
72
|
+
|
73
|
+
def save
|
74
|
+
run_callbacks :save do
|
75
|
+
flag = false
|
76
|
+
if changed? && is_valid?
|
77
|
+
@previously_changed = changes
|
78
|
+
flag = client.set_ftp(dirty_params_hash)
|
79
|
+
@changed_attributes.clear if flag
|
80
|
+
end
|
81
|
+
flag
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def clear
|
86
|
+
run_callbacks :clear do
|
87
|
+
flag = false
|
88
|
+
params = {:dir => "", :user => "", :pwd => "", :svr => "", :port => 21, :upload_interval => 0}
|
89
|
+
flag = client.set_ftp(params)
|
90
|
+
@changed_attributes.clear if flag
|
91
|
+
flag
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
private
|
96
|
+
|
97
|
+
def dirty_params_hash
|
98
|
+
h = {}
|
99
|
+
h.merge!({:dir => self.dir}) if dir_changed?
|
100
|
+
h.merge!({:user => self.username}) if username_changed?
|
101
|
+
h.merge!({:pwd => self.password}) if password_changed?
|
102
|
+
h.merge!({:svr => self.address}) if address_changed?
|
103
|
+
h.merge!({:port => self.port}) if port_changed?
|
104
|
+
h.merge!({:upload_interval => self.upload_interval}) if upload_interval_changed?
|
105
|
+
h
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|