qnap-file_station 0.0.1 → 0.0.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: afd92ae3b99527ea64cb659f422cf54e8f4e3b04
4
- data.tar.gz: 06665735be81179b757a10b1d980013eef0232b3
3
+ metadata.gz: 7b53bdac66bf563c2314cdad578479e57b1c621b
4
+ data.tar.gz: eba64d3cf0bec2d666fd2d43ce771317e327cb2e
5
5
  SHA512:
6
- metadata.gz: 0c1ee4272265edcbed969ea1f7d93e1e628bb38568cc29723b89f0b6493aab5f4f9df27270a69b42812d75a009b7c03489dd5ad278a4a23cbf16b8e717617bc1
7
- data.tar.gz: 3a88ad3757fabce25d6ad8a80b7619921fc290c9a46be98125ce1eea302ecd1247ad318df9d0914024a17fc2e20650bd3925a05ec397b46461aec125a11678a9
6
+ metadata.gz: 7e6c546e57b12b145e6101f97e69bc7f6509f886baff56c6add067a2996fc5ceddeba238c43e08acdb405b74441b2102611c0c9d24fad90805a8449bf895ab42
7
+ data.tar.gz: a080dea3bfb8c1868a7cd722234dfa91997c447d353dea539a94e182cb369bfb3ffcce7487c85fc9989bc04246c8dde09b20aa1ebc63708adee31a76d89aa9e7
data/README.md CHANGED
@@ -17,7 +17,7 @@ Usage
17
17
  require 'qnap/file_station'
18
18
 
19
19
  fs = Qnap::FileStation.new '192.168.1.100', 'username', 'password'
20
- fs.createdir dest_folder: "", dest_path: ""
20
+ fs.createdir dest_folder: "new_folder", dest_path: "/some/path"
21
21
  contents = fs.get_extract_list extract_file: "my_zip_file.zip"
22
22
  fs.logout
23
23
  ```
@@ -25,15 +25,47 @@ fs.logout
25
25
  ```ruby
26
26
  # Alternative syntax to guarantee logout
27
27
 
28
+ Qnap::FileStation::DEBUG = true
29
+
28
30
  Qnap::FileStation.session('192.168.1.100', 'username', 'password') do |fs|
29
31
  # Show contents of the recycle bin
30
32
  pp fs.get_tree node: "recycle_root"
33
+
34
+ # Show available network players (AirPlay, Chromecast, DLNA players, etc.)
35
+ # May not be available, depending on model
36
+ pp fs.get_network_players op: 1
31
37
  # logout is automatically called, even if there was an exception
32
38
  end
33
39
 
34
40
  ```
35
41
 
42
+ Constants
43
+ -------
44
+ `Qnap::FileStation::DEBUG`, default: `false`. Print extensive debugging information to @stdout of `true`
45
+ `Qnap::FileStation::DISCARD_EXTRANEOUS` default: `true`, Discard any parameters we're not expecting, before despatching to the API
46
+ `Qnap::FileStation::PROTOCOL`, default: `"https"`
47
+
48
+ Exceptions
49
+ -------
50
+ API communication errors will raise a Qnap::ApiError exception. The message will indicate what went wrong, the `uri` method will return the URI that was being queried at the time, and `the response` method will return the `Net::HTTPResponse` response
51
+
52
+ ```ruby
53
+ begin
54
+ Qnap::FileStation.session('192.168.1.100', 'username', 'invalid_password') do |fs|
55
+ fs.get_tree node: "recycle_root"
56
+ end
57
+ rescue Qnap::ApiError => e
58
+ puts "Error message was" + e.message
59
+ puts "URI was " + e.uri.to_s
60
+ puts "Response code was " + e.response.code
61
+ puts "Response body was " + e.response.read_body
62
+ end
63
+
64
+ ```
65
+
66
+
36
67
  Available methods
68
+ -------
37
69
 
38
70
  ### createdir
39
71
  Create a folder in the specified path.
@@ -423,6 +455,14 @@ Key | Description
423
455
  path | The path folder name of recycle bin
424
456
  file_name | Same as the value ${path}
425
457
 
458
+ ### get_network_players (alias: `qrpac`)
459
+ Show available network players (AirPlay, Chromecast, DLNA players, etc.) May not be available, depending on model
460
+
461
+ #### Parameters
462
+ Key | Description
463
+ --- | ---
464
+ op | 1:
465
+
426
466
  ### video_ml_queue
427
467
  Retrieve the status of media library transcoding queue.
428
468
 
@@ -0,0 +1,64 @@
1
+ module Qnap
2
+ class ApiError < StandardError
3
+ attr_reader :uri, :response
4
+
5
+ STATUS_CODES = [
6
+ [ 0, "WFM2_FAIL", "Unknown error"],
7
+ [ 1, "WFM2_DONE", "Success"],
8
+ # [ 1, "WFM2_SUCCESS", "Success"],
9
+ [ 2, "WFM2_FILE_EXIST", "File already exists"],
10
+ [ 3, "WFM2_AUTH_FAIL", "Authentication Failure"],
11
+ [ 4, "WFM2_PERMISSION_DENY", "Permission Denied"],
12
+ [ 5, "WFM2_FILE_NO_EXIST", "File or folder does not exist"],
13
+ # [ 5, "WFM2_SRC_FILE_NO_EXIST", "File/folder does not exist"],
14
+ [ 6, "WFM2_EXTRACTING", "FILE EXTRACTING"],
15
+ [ 7, "WFM2_OPEN_FILE_FAIL", "Failed to open file"],
16
+ [ 8, "WFM2_DISABLE", "Web File Manager is not enabled"],
17
+ [ 9, "WFM2_QUOTA_ERROR", "You have reached the disk quota limit"],
18
+ [10, "WFM2_SRC_PERMISSION_DENY", "You do not have permission to perform this action"],
19
+ [11, "WFM2_DES_PERMISSION_DENY", "You do not have permission to perform this action"],
20
+ [12, "WFM2_ILLEGAL_NAME", "Invalid character encountered: \"+=/\\:|*?<>;[]%,`'"],
21
+ [13, "WFM2_EXCEED_ISO_MAX", "The maximum number of allowed ISO shares is 256"],
22
+ [14, "WFM2_EXCEED_SHARE_MAX", "The maximum number of shares is going to be exceeded"],
23
+ [15, "WFM2_NEED_CHECK", nil],
24
+ [16, "WFM2_RECYCLE_BIN_NOT_ENABLE", "Recycle bin is not enabled"],
25
+ [17, "WFM2_CHECK_PASSWORD_FAIL", "Enter password"],
26
+ [18, "WFM2_VIDEO_TCS_DISABLE", nil],
27
+ [19, "WFM2_DB_FAIL", "The system is currently busy"],
28
+ # [19, "WFM2_DB_QUERY_FAIL", "The system is currently busy"],
29
+ [20, "WFM2_PARAMETER_ERROR", "There were input errors"],
30
+ [21, "WFM2_DEMO_SITE", "Your files are now being transcoded"],
31
+ [22, "WFM2_TRANSCODE_ONGOING", "Your files are now being transcoded"],
32
+ [23, "WFM2_SRC_VOLUME_ERROR", "An error occurred in the source file"],
33
+ [24, "WFM2_DES_VOLUME_ERROR", "A write error has occurred at the destination"],
34
+ [25, "WFM2_DES_FILE_NO_EXIST", "The destination is unavailable"],
35
+ [26, "WFM2_FILE_NAME_TOO_LONG", "255 filename byte limit exceeded"],
36
+ [27, "WFM2_FOLDER_ENCRYPTION", "This folder has been encrypted"],
37
+ [28, "WFM2_PREPARE", "Processing now"],
38
+ [29, "WFM2_NO_SUPPORT_MEDIA", "This file format is not supported"],
39
+ [30, "WFM2_DLNA_QDMS_DISABLE", "Please enable the DLNA Media Server"],
40
+ [31, "WFM2_RENDER_NOT_FOUND", "Cannot find any available DLNA devices"],
41
+ [32, "WFM2_CLOUD_SERVER_ERROR", "The SmartLink service is currently busy"],
42
+ [33, "WFM2_NAME_DUP", "File or folder name already exists"],
43
+ [34, "WFM2_EXCEED_SEARCH_MAX", nil],
44
+ [35, "WFM2_MEMORY_ERROR", nil],
45
+ [36, "WFM2_COMPRESSING", nil],
46
+ [37, "WFM2_EXCEED_DAV_MAX", nil],
47
+ [38, "WFM2_UMOUNT_FAIL", nil],
48
+ [39, "WFM2_MOUNT_FAIL", nil],
49
+ [40, "WFM2_WEBDAV_ACCOUNT_PASSWD_ERROR", nil],
50
+ [41, "WFM2_WEBDAV_SSL_ERROR", nil],
51
+ [42, "WFM2_WEBDAV_REMOUNT_ERROR", nil],
52
+ [43, "WFM2_WEBDAV_HOST_ERROR", nil],
53
+ [44, "WFM2_WEBDAV_TIMEOUT_ERROR", nil],
54
+ [45, "WFM2_WEBDAV_CONF_ERROR", nil],
55
+ [46, "WFM2_WEBDAV_BASE_ERROR", nil],
56
+ ]
57
+
58
+ def initialize(status_code, uri, response=nil)
59
+ @uri = uri
60
+ @response = response
61
+ super STATUS_CODES[status_code.to_i].last(2).compact.join ' - '
62
+ end
63
+ end
64
+ end
@@ -2,10 +2,14 @@ require 'json'
2
2
  require 'net/http'
3
3
  require 'openssl'
4
4
  require 'base64'
5
+ require 'qnap/api_error'
5
6
 
6
7
  module Qnap
7
8
  class FileStation
9
+ DEBUG = false
10
+ DISCARD_EXTRANEOUS = true
8
11
  PROTOCOL = 'https'
12
+
9
13
  API_METHODS = {
10
14
  cancel_compress: [:pid],
11
15
  cancel_extract: [:pid],
@@ -31,6 +35,7 @@ module Qnap
31
35
  get_tree: [:is_iso, :node],
32
36
  get_video_qstatus: [:pid],
33
37
  move: [:mode, :source_file, :source_path, :source_total],
38
+ qrpac: [:op],
34
39
  rename: [:dest_name, :path, :source_name],
35
40
  search: [:dir, :keyword, :limit, :sort, :source_path, :start],
36
41
  share_file: [:access_code, :access_enabled, :addressee, :content, :day, :dowdownload_type, :expire_time, :file_name, :file_total, :hostname, :hour, :include_access_code, :link_url, :mail_content_date, :mail_content_pwd, :network_type, :path, :ssl, :subject, :valid_duration],
@@ -58,21 +63,24 @@ module Qnap
58
63
 
59
64
  define_method method_name, Proc.new { |params={}|
60
65
  if (diff = fields - params.keys).count > 0
61
- puts "Missing keys: #{diff}"
66
+ puts "Missing keys: #{diff}" if DEBUG
62
67
  end
63
68
 
64
- if (diff = params.keys - fields).count > 0
65
- puts "Extra keys: #{diff}"
69
+ if DISCARD_EXTRANEOUS and (diff = params.keys - fields).count > 0
70
+ puts "Discarding extra keys: #{diff}"
71
+ params.select! { |k, v| fields.include? k }
66
72
  end
67
73
 
68
- despatch_query @url, params.merge(func: method_name, sid: get_sid)
74
+ despatch_query @path, params.merge(func: method_name, sid: get_sid)
69
75
  }
70
76
 
71
77
  end
72
78
 
79
+ alias get_network_players qrpac
80
+
73
81
  def login(params={})
74
82
  despatch_query(
75
- "#{PROTOCOL}://#{@host}/cgi-bin/filemanager/wfm2Login.cgi",
83
+ "/cgi-bin/filemanager/wfm2Login.cgi",
76
84
  params
77
85
  )
78
86
  end
@@ -80,10 +88,15 @@ module Qnap
80
88
  def logout(params={})
81
89
  return unless @sid
82
90
  despatch_query(
83
- "#{PROTOCOL}://#{@host}/cgi-bin/filemanager/wfm2Logout.cgi",
91
+ "/cgi-bin/filemanager/wfm2Logout.cgi",
84
92
  params.merge(sid: @sid)
85
93
  )
86
94
  @sid = nil
95
+
96
+ if @agent.started?
97
+ @agent.finish
98
+ puts "\e[1;32mClosing connection\e[0m" if DEBUG
99
+ end
87
100
  end
88
101
 
89
102
  def get_sid
@@ -95,27 +108,33 @@ module Qnap
95
108
  @username = username
96
109
  @password = password
97
110
  @sid = nil
98
- @url = "#{PROTOCOL}://#{@host}/cgi-bin/filemanager/utilRequest.cgi"
111
+ @base_uri = URI "#{PROTOCOL}://#{@host}"
112
+ @path = "/cgi-bin/filemanager/utilRequest.cgi"
113
+ @agent = Net::HTTP.new @base_uri.host, @base_uri.port
114
+
115
+ @agent.use_ssl = PROTOCOL == 'https',
116
+ @agent.verify_mode = OpenSSL::SSL::VERIFY_NONE
117
+ @agent.keep_alive_timeout = 10
118
+ @agent.set_debug_output $stdout if DEBUG
99
119
  end
100
120
 
101
121
  private
102
122
 
103
- def despatch_query(url, params)
104
- uri = URI url
123
+ def despatch_query(path, params)
124
+ uri = @base_uri.clone
125
+ uri.path = path
105
126
  uri.query = URI.encode_www_form(params) if params.keys.length > 0
106
127
  req = Net::HTTP::Get.new uri
107
128
 
108
- response = Net::HTTP.start(
109
- uri.host,
110
- uri.port,
111
- use_ssl: PROTOCOL == 'https',
112
- verify_mode: OpenSSL::SSL::VERIFY_NONE
113
- ) do |https|
114
- https.request req
115
- end
129
+ puts "\n\n\e[1;32mDespatching request to #{params[:func]}\e[0m" if DEBUG
130
+
131
+ @session = @agent.start unless @agent.started?
132
+ response = @session.request req
133
+
134
+ puts "\e[1;32mResponse received\e[0m" if DEBUG
116
135
 
117
136
  unless (200..299).include? response.code.to_i
118
- raise RuntimeError.new "Error response from #{uri} -> #{response.read_body}"
137
+ raise "Error response from #{uri} -> #{response.read_body}"
119
138
  end
120
139
 
121
140
  unless response['content-type'] =~ /application\/json/
@@ -125,63 +144,10 @@ module Qnap
125
144
  data = JSON.parse response.read_body, symbolize_names: true
126
145
 
127
146
  if data.respond_to?(:key?) and data.key?(:status) and data[:status] != 1
128
- raise RuntimeError.new "Error response from #{uri} -> #{data}"
147
+ raise Qnap::ApiError.new data[:status], uri, response
129
148
  end
130
149
 
131
150
  data
132
151
  end
133
152
  end
134
153
  end
135
-
136
- __END__
137
- Error code, Token, Description
138
- 0 WFM2_FAIL UNKNOWN ERROR
139
- 1 WFM2_DONE SUCCESS
140
- 1 WFM2_SUCCESS SUCCESS
141
- 2 WFM2_FILE_EXIST FILE EXIST
142
- 3 WFM2_AUTH_FAIL Authentication Failure
143
- 4 WFM2_PERMISSION_DENY Permission Denied
144
- 5 WFM2_FILE_NO_EXIST FILE/FOLDER NOT EXIST
145
- 5 WFM2_SRC_FILE_NO_EXIST FILE/FOLDER NOT EXIST
146
- 6 WFM2_EXTRACTING FILE EXTRACTING
147
- 7 WFM2_OPEN_FILE_FAIL FILE IO ERROR
148
- 8 WFM2_DISABLE Web File Manager is not enabled.
149
- 9 WFM2_QUOTA_ERROR You have reached the disk quota limit.
150
- 10 WFM2_SRC_PERMISSION_DENY You do not have permission to perform this action.
151
- 11 WFM2_DES_PERMISSION_DENY You do not have permission to perform this action.
152
- 12 WFM2_ILLEGAL_NAME " + = / \ : | * ? < > ; [ ] % , ` '
153
- 13 WFM2_EXCEED_ISO_MAX The maximum number of allowed ISO shares is 256. Please unmount an ISO share
154
- 14 WFM2_EXCEED_SHARE_MAX The maximum number of shares is going to be exceeded.
155
- 15 WFM2_NEED_CHECK
156
- 16 WFM2_RECYCLE_BIN_NOT_ENABLE
157
- 17 WFM2_CHECK_PASSWORD_FAIL Enter password
158
- 18 WFM2_VIDEO_TCS_DISABLE
159
- 19 WFM2_DB_FAIL The system is currently busy. Please try again later.
160
- 19 WFM2_DB_QUERY_FAIL The system is currently busy. Please try again later.
161
- 20 WFM2_PARAMETER_ERROR There were input errors. Please try again later.
162
- 21 WFM2_DEMO_SITE Your files are now being transcoded.
163
- 22 WFM2_TRANSCODE_ONGOING Your files are now being transcoded.
164
- 23 WFM2_SRC_VOLUME_ERROR An error occurred in the source file. Please check and try again later.
165
- 24 WFM2_DES_VOLUME_ERROR A write error has occurred at the target destination. Please check and try again
166
- 25 WFM2_DES_FILE_NO_EXIST The target destination is unavailable. Please check and try again later.
167
- 26 WFM2_FILE_NAME_TOO_LONG 255 byte limit exceeded
168
- 27 WFM2_FOLDER_ENCRYPTION This folder has been encrypted. Please decrypt it and try again.
169
- 28 WFM2_PREPARE Processing now
170
- 29 WFM2_NO_SUPPORT_MEDIA This file format is not supported.
171
- 30 WFM2_DLNA_QDMS_DISABLE Please enable the DLNA Media Server
172
- 31 WFM2_RENDER_NOT_FOUND Cannot find any available DLNA devices.
173
- 32 WFM2_CLOUD_SERVER_ERROR The SmartLink service is currently busy. Please try again later.
174
- 33 WFM2_NAME_DUP That folder or file name already exists. Please use another name.
175
- 34 WFM2_EXCEED_SEARCH_MAX 1000
176
- 35 WFM2_MEMORY_ERROR
177
- 36 WFM2_COMPRESSING
178
- 37 WFM2_EXCEED_DAV_MAX
179
- 38 WFM2_UMOUNT_FAIL
180
- 39 WFM2_MOUNT_FAIL
181
- 40 WFM2_WEBDAV_ACCOUNT_PASSWD_ERROR
182
- 41 WFM2_WEBDAV_SSL_ERROR
183
- 42 WFM2_WEBDAV_REMOUNT_ERROR
184
- 43 WFM2_WEBDAV_HOST_ERROR
185
- 44 WFM2_WEBDAV_TIMEOUT_ERROR
186
- 45 WFM2_WEBDAV_CONF_ERROR
187
- 46 WFM2_WEBDAV_BASE_ERROR
@@ -1,11 +1,11 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = "qnap-file_station"
3
- s.version = "0.0.1"
3
+ s.version = "0.0.2"
4
4
  s.date = "2016-09-28"
5
5
  s.summary = "Interface to the File Station API"
6
6
  s.description = "Manage your files and folders in File Station"
7
7
  s.authors = "cyclotron3k"
8
- s.files = ["lib/qnap/file_station.rb", "Rakefile", "qnap-file_station.gemspec", "README.md"]
8
+ s.files = ["lib/qnap/file_station.rb", "lib/qnap/api_error.rb", "Rakefile", "qnap-file_station.gemspec", "README.md"]
9
9
  s.test_files = ["test/test_file_station.rb"]
10
10
  s.homepage = "https://github.com/cyclotron3k/qnap-file_station"
11
11
  s.license = "MIT"
@@ -1,5 +1,6 @@
1
1
  require 'minitest/autorun'
2
2
  require 'qnap/file_station'
3
+ require 'qnap/api_error'
3
4
 
4
5
  class TestFileStation < Minitest::Test
5
6
  def test_argument
@@ -7,4 +8,8 @@ class TestFileStation < Minitest::Test
7
8
  Qnap::FileStation.new
8
9
  end
9
10
  end
11
+
12
+ def test_error_code_integrity
13
+ assert_equal (0..46).to_a, Qnap::ApiError::STATUS_CODES.map(&:first)
14
+ end
10
15
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: qnap-file_station
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - cyclotron3k
@@ -18,6 +18,7 @@ extra_rdoc_files: []
18
18
  files:
19
19
  - README.md
20
20
  - Rakefile
21
+ - lib/qnap/api_error.rb
21
22
  - lib/qnap/file_station.rb
22
23
  - qnap-file_station.gemspec
23
24
  - test/test_file_station.rb