pione 0.2.1 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (214) hide show
  1. data/.gitignore +16 -13
  2. data/.travis.yml +1 -1
  3. data/History.txt +11 -0
  4. data/Rakefile +13 -0
  5. data/bin/pione-package +5 -0
  6. data/example/AbstractRule/package.yml +6 -0
  7. data/example/AbstractRule/scenario/a/output/message.txt +1 -0
  8. data/example/AbstractRule/scenario/a/scenario.yml +4 -0
  9. data/example/AbstractRule/scenario/b/output/message.txt +1 -0
  10. data/example/AbstractRule/scenario/b/scenario.yml +4 -0
  11. data/example/AbstractRule/scenario/c/output/message.txt +1 -0
  12. data/example/AbstractRule/scenario/c/scenario.yml +4 -0
  13. data/example/HelloWorld/package.yml +5 -1
  14. data/example/HelloWorld/scenario/scenario.yml +2 -1
  15. data/example/LoopByTouch/package.yml +4 -1
  16. data/example/MakePair/package.yml +6 -0
  17. data/example/MakePair/scenario/{input → case1/input}/1.i +0 -0
  18. data/example/MakePair/scenario/{input → case1/input}/2.i +0 -0
  19. data/example/MakePair/scenario/{input → case1/input}/3.i +0 -0
  20. data/example/MakePair/scenario/{input → case1/input}/4.i +0 -0
  21. data/example/MakePair/scenario/{input → case1/input}/5.i +0 -0
  22. data/example/MakePair/scenario/{output → case1/output}/comb-1-2.pair +0 -0
  23. data/example/MakePair/scenario/{output → case1/output}/comb-1-3.pair +0 -0
  24. data/example/MakePair/scenario/{output → case1/output}/comb-1-4.pair +0 -0
  25. data/example/MakePair/scenario/{output → case1/output}/comb-1-5.pair +0 -0
  26. data/example/MakePair/scenario/{output → case1/output}/comb-2-3.pair +0 -0
  27. data/example/MakePair/scenario/{output → case1/output}/comb-2-4.pair +0 -0
  28. data/example/MakePair/scenario/{output → case1/output}/comb-2-5.pair +0 -0
  29. data/example/MakePair/scenario/{output → case1/output}/comb-3-4.pair +0 -0
  30. data/example/MakePair/scenario/{output → case1/output}/comb-3-5.pair +0 -0
  31. data/example/MakePair/scenario/{output → case1/output}/comb-4-5.pair +0 -0
  32. data/example/MakePair/scenario/{output → case1/output}/perm-1-2.pair +0 -0
  33. data/example/MakePair/scenario/{output → case1/output}/perm-1-3.pair +0 -0
  34. data/example/MakePair/scenario/{output → case1/output}/perm-1-4.pair +0 -0
  35. data/example/MakePair/scenario/{output → case1/output}/perm-1-5.pair +0 -0
  36. data/example/MakePair/scenario/{output → case1/output}/perm-2-1.pair +0 -0
  37. data/example/MakePair/scenario/{output → case1/output}/perm-2-3.pair +0 -0
  38. data/example/MakePair/scenario/{output → case1/output}/perm-2-4.pair +0 -0
  39. data/example/MakePair/scenario/{output → case1/output}/perm-2-5.pair +0 -0
  40. data/example/MakePair/scenario/{output → case1/output}/perm-3-1.pair +0 -0
  41. data/example/MakePair/scenario/{output → case1/output}/perm-3-2.pair +0 -0
  42. data/example/MakePair/scenario/{output → case1/output}/perm-3-4.pair +0 -0
  43. data/example/MakePair/scenario/{output → case1/output}/perm-3-5.pair +0 -0
  44. data/example/MakePair/scenario/{output → case1/output}/perm-4-1.pair +0 -0
  45. data/example/MakePair/scenario/{output → case1/output}/perm-4-2.pair +0 -0
  46. data/example/MakePair/scenario/{output → case1/output}/perm-4-3.pair +0 -0
  47. data/example/MakePair/scenario/{output → case1/output}/perm-4-5.pair +0 -0
  48. data/example/MakePair/scenario/{output → case1/output}/perm-5-1.pair +0 -0
  49. data/example/MakePair/scenario/{output → case1/output}/perm-5-2.pair +0 -0
  50. data/example/MakePair/scenario/{output → case1/output}/perm-5-3.pair +0 -0
  51. data/example/MakePair/scenario/{output → case1/output}/perm-5-4.pair +0 -0
  52. data/example/MakePair/scenario/{output → case1/output}/succ-1-2.pair +0 -0
  53. data/example/MakePair/scenario/{output → case1/output}/succ-2-3.pair +0 -0
  54. data/example/MakePair/scenario/{output → case1/output}/succ-3-4.pair +0 -0
  55. data/example/MakePair/scenario/{output → case1/output}/succ-4-5.pair +0 -0
  56. data/example/MakePair/scenario/case1/scenario.yml +42 -0
  57. data/example/MakePair/scenario/case2/input/10.i +0 -0
  58. data/example/MakePair/scenario/case2/input/11.i +0 -0
  59. data/example/MakePair/scenario/case2/input/9.i +0 -0
  60. data/example/MakePair/scenario/case2/output/comb-10-11.pair +0 -0
  61. data/example/MakePair/scenario/case2/output/comb-9-10.pair +0 -0
  62. data/example/MakePair/scenario/case2/output/comb-9-11.pair +0 -0
  63. data/example/MakePair/scenario/case2/output/perm-10-11.pair +0 -0
  64. data/example/MakePair/scenario/case2/output/perm-10-9.pair +0 -0
  65. data/example/MakePair/scenario/case2/output/perm-11-10.pair +0 -0
  66. data/example/MakePair/scenario/case2/output/perm-11-9.pair +0 -0
  67. data/example/MakePair/scenario/case2/output/perm-9-10.pair +0 -0
  68. data/example/MakePair/scenario/case2/output/perm-9-11.pair +0 -0
  69. data/example/MakePair/scenario/case2/output/succ-10-11.pair +0 -0
  70. data/example/MakePair/scenario/case2/output/succ-9-10.pair +0 -0
  71. data/example/MakePair/scenario/case2/scenario.yml +17 -0
  72. data/example/MakePair/scenario/case3/input/1.i +0 -0
  73. data/example/MakePair/scenario/case3/input/3.i +0 -0
  74. data/example/MakePair/scenario/case3/input/5.i +0 -0
  75. data/example/MakePair/scenario/case3/input/7.i +0 -0
  76. data/example/MakePair/scenario/case3/input/9.i +0 -0
  77. data/example/MakePair/scenario/case3/output/comb-1-3.pair +0 -0
  78. data/example/MakePair/scenario/case3/output/comb-1-5.pair +0 -0
  79. data/example/MakePair/scenario/case3/output/comb-1-7.pair +0 -0
  80. data/example/MakePair/scenario/case3/output/comb-1-9.pair +0 -0
  81. data/example/MakePair/scenario/case3/output/comb-3-5.pair +0 -0
  82. data/example/MakePair/scenario/case3/output/comb-3-7.pair +0 -0
  83. data/example/MakePair/scenario/case3/output/comb-3-9.pair +0 -0
  84. data/example/MakePair/scenario/case3/output/comb-5-7.pair +0 -0
  85. data/example/MakePair/scenario/case3/output/comb-5-9.pair +0 -0
  86. data/example/MakePair/scenario/case3/output/comb-7-9.pair +0 -0
  87. data/example/MakePair/scenario/case3/output/perm-1-3.pair +0 -0
  88. data/example/MakePair/scenario/case3/output/perm-1-5.pair +0 -0
  89. data/example/MakePair/scenario/case3/output/perm-1-7.pair +0 -0
  90. data/example/MakePair/scenario/case3/output/perm-1-9.pair +0 -0
  91. data/example/MakePair/scenario/case3/output/perm-3-1.pair +0 -0
  92. data/example/MakePair/scenario/case3/output/perm-3-5.pair +0 -0
  93. data/example/MakePair/scenario/case3/output/perm-3-7.pair +0 -0
  94. data/example/MakePair/scenario/case3/output/perm-3-9.pair +0 -0
  95. data/example/MakePair/scenario/case3/output/perm-5-1.pair +0 -0
  96. data/example/MakePair/scenario/case3/output/perm-5-3.pair +0 -0
  97. data/example/MakePair/scenario/case3/output/perm-5-7.pair +0 -0
  98. data/example/MakePair/scenario/case3/output/perm-5-9.pair +0 -0
  99. data/example/MakePair/scenario/case3/output/perm-7-1.pair +0 -0
  100. data/example/MakePair/scenario/case3/output/perm-7-3.pair +0 -0
  101. data/example/MakePair/scenario/case3/output/perm-7-5.pair +0 -0
  102. data/example/MakePair/scenario/case3/output/perm-7-9.pair +0 -0
  103. data/example/MakePair/scenario/case3/output/perm-9-1.pair +0 -0
  104. data/example/MakePair/scenario/case3/output/perm-9-3.pair +0 -0
  105. data/example/MakePair/scenario/case3/output/perm-9-5.pair +0 -0
  106. data/example/MakePair/scenario/case3/output/perm-9-7.pair +0 -0
  107. data/example/MakePair/scenario/case3/scenario.yml +39 -0
  108. data/example/PegasusWMS/Merge/Merge.pione +21 -0
  109. data/example/PegasusWMS/Merge/package.yml +2 -0
  110. data/example/PegasusWMS/Pipeline/Pipeline.pione +20 -0
  111. data/example/PegasusWMS/Pipeline/package.yml +2 -0
  112. data/example/PegasusWMS/Split/Split.pione +27 -0
  113. data/example/PegasusWMS/Split/package.yml +2 -0
  114. data/example/ScoreAggregation/package.yml +4 -0
  115. data/example/ScoreAggregation/scenario/case1/scenario.yml +27 -1
  116. data/example/SerialProcessing/package.yml +5 -1
  117. data/example/SerialProcessing/scenario/scenario.yml +10 -0
  118. data/lib/pione.rb +20 -71
  119. data/lib/pione/agent.rb +17 -0
  120. data/lib/pione/agent/basic-agent.rb +2 -4
  121. data/lib/pione/command.rb +1 -0
  122. data/lib/pione/command/option.rb +4 -1
  123. data/lib/pione/command/pione-package.rb +97 -0
  124. data/lib/pione/command/pione-task-worker.rb +11 -7
  125. data/lib/pione/component.rb +5 -0
  126. data/lib/pione/component/document.rb +22 -5
  127. data/lib/pione/component/package-archiver.rb +92 -0
  128. data/lib/pione/component/package-expander.rb +37 -0
  129. data/lib/pione/component/package-filename.rb +38 -0
  130. data/lib/pione/component/package-reader.rb +276 -0
  131. data/lib/pione/component/package.rb +50 -162
  132. data/lib/pione/front.rb +14 -0
  133. data/lib/pione/location.rb +5 -0
  134. data/lib/pione/location/basic-location.rb +47 -274
  135. data/lib/pione/location/data-location.rb +328 -0
  136. data/lib/pione/location/dropbox-location.rb +30 -7
  137. data/lib/pione/location/exception.rb +38 -0
  138. data/lib/pione/location/ftp-location.rb +24 -13
  139. data/lib/pione/location/git-repository-location.rb +153 -0
  140. data/lib/pione/location/http-location.rb +65 -0
  141. data/lib/pione/location/https-location.rb +37 -0
  142. data/lib/pione/location/local-location.rb +24 -5
  143. data/lib/pione/parser.rb +14 -0
  144. data/lib/pione/patch.rb +10 -0
  145. data/lib/pione/patch/drb-patch.rb +2 -2
  146. data/lib/pione/relay.rb +11 -0
  147. data/lib/pione/system/file-cache.rb +1 -1
  148. data/lib/pione/system/global.rb +15 -0
  149. data/lib/pione/tuple-space.rb +11 -0
  150. data/lib/pione/tuple-space/tuple-space-server.rb +1 -1
  151. data/lib/pione/util.rb +1 -0
  152. data/lib/pione/util/error-report.rb +7 -0
  153. data/lib/pione/util/misc.rb +2 -2
  154. data/lib/pione/util/zip.rb +60 -0
  155. data/lib/pione/version.rb +1 -1
  156. data/pione.gemspec +5 -1
  157. data/test/agent/spec_rule-provider.rb +2 -2
  158. data/test/command/spec_pione-package.rb +15 -0
  159. data/test/component/spec_document.rb +2 -2
  160. data/test/component/spec_package-archiver.rb +27 -0
  161. data/test/component/spec_package-expander.rb +11 -0
  162. data/test/component/spec_package-filename.rb +79 -0
  163. data/test/component/spec_package-reader.rb +100 -0
  164. data/test/component/spec_package.rb +50 -33
  165. data/test/location/http-behavior.rb +59 -0
  166. data/test/location/location-behavior.rb +8 -0
  167. data/test/location/spec_basic-location.rb +5 -1
  168. data/test/location/spec_git-repository-location.rb +143 -0
  169. data/test/location/spec_http-location.rb +28 -0
  170. data/test/location/spec_http-location/a.txt +1 -0
  171. data/test/location/spec_http-location/b.txt +1 -0
  172. data/test/location/spec_http-location/c.txt +1 -0
  173. data/test/location/spec_http-location/dir/d.txt +1 -0
  174. data/test/location/spec_https-location.rb +37 -0
  175. data/test/rule-handler/spec_flow-handler.rb +1 -1
  176. data/test/rule-handler/spec_update-criteria.rb +1 -1
  177. data/test/test-data/package/HelloWorld+v0.1.0.ppg +0 -0
  178. data/test/test-data/package/HelloWorld-gitrepos.zip +0 -0
  179. data/test/test-data/package/HelloWorld/HelloWorld.pione +5 -0
  180. data/test/test-data/package/HelloWorld/package.yml +6 -0
  181. data/test/test-data/package/HelloWorld/scenario/output/message.txt +1 -0
  182. data/test/test-data/package/HelloWorld/scenario/scenario.yml +3 -0
  183. data/test/test-data/package/TestPackage1+v0.1.0.ppg +0 -0
  184. data/test/{component/spec_package/TestPackage → test-data/package/TestPackage1}/Test.pione +3 -1
  185. data/test/test-data/package/TestPackage1/bin/count +11 -0
  186. data/test/test-data/package/TestPackage1/package.yml +9 -0
  187. data/test/{component/spec_package/TestPackage → test-data/package/TestPackage1}/scenario/case1/input/1.txt +0 -0
  188. data/test/test-data/package/TestPackage1/scenario/case1/output/1.count +1 -0
  189. data/test/test-data/package/TestPackage1/scenario/case1/scenario.yml +6 -0
  190. data/test/test-data/package/TestPackage1/scenario/case2/input/1.txt +2 -0
  191. data/test/test-data/package/TestPackage1/scenario/case2/input/2.txt +1 -0
  192. data/test/test-data/package/TestPackage1/scenario/case2/input/3.txt +3 -0
  193. data/test/test-data/package/TestPackage1/scenario/case2/output/1.count +1 -0
  194. data/test/test-data/package/TestPackage1/scenario/case2/output/2.count +1 -0
  195. data/test/test-data/package/TestPackage1/scenario/case2/output/3.count +1 -0
  196. data/test/test-data/package/TestPackage1/scenario/case2/scenario.yml +10 -0
  197. data/test/test-data/package/TestPackage1/scenario/case3/input/a.txt +1 -0
  198. data/test/test-data/package/TestPackage1/scenario/case3/input/b.txt +1 -0
  199. data/test/test-data/package/TestPackage1/scenario/case3/output/a.count +1 -0
  200. data/test/test-data/package/TestPackage1/scenario/case3/output/b.count +1 -0
  201. data/test/test-data/package/TestPackage1/scenario/case3/scenario.yml +8 -0
  202. data/test/test-util.rb +10 -146
  203. data/test/test-util/command.rb +53 -0
  204. data/test/test-util/package.rb +9 -0
  205. data/test/test-util/parser.rb +45 -0
  206. data/test/test-util/transformer.rb +50 -0
  207. data/test/test-util/webserver.rb +43 -0
  208. data/test/util/spec_error-report.rb +12 -3
  209. data/test/util/spec_zip.rb +36 -0
  210. metadata +282 -54
  211. data/example/MakePair/scenario/scenario.yml +0 -1
  212. data/test/component/spec_package/TestPackage/bin/count +0 -3
  213. data/test/component/spec_package/TestPackage/package.yml +0 -7
  214. data/test/component/spec_package/TestPackage/scenario/case1/scenario.yml +0 -1
@@ -0,0 +1,328 @@
1
+ module Pione
2
+ module Location
3
+ class DataLocation < BasicLocation
4
+ location_type :data
5
+
6
+ class << self
7
+ # @return [String]
8
+ # location's scheme name
9
+ attr_reader :scheme
10
+
11
+ # Declare the name as location scheme.
12
+ #
13
+ # @param name [String]
14
+ # scheme name
15
+ def set_scheme(name)
16
+ @scheme = name
17
+ SCHEMES[name] = self
18
+ end
19
+
20
+ def set_real_appendable(b)
21
+ @appendable = b
22
+ end
23
+
24
+ def real_appendable?
25
+ @appendable
26
+ end
27
+
28
+ def set_writable(b)
29
+ @writable = b
30
+ end
31
+
32
+ def writable?
33
+ @writable
34
+ end
35
+ end
36
+
37
+ forward! :class, :scheme, :real_appendable?, :writable?
38
+ forward :@uri, :host
39
+
40
+ # @return [URI]
41
+ # URI of the location
42
+ attr_reader :uri
43
+
44
+ # @return [Pathname]
45
+ # path of the location
46
+ attr_reader :path
47
+
48
+ # Create a location with the URI.
49
+ #
50
+ # @param uri [URI]
51
+ # location URI
52
+ def initialize(uri)
53
+ @address = uri.to_s
54
+ @uri = uri.kind_of?(URI::Generic) ? uri : URI.parse(uri)
55
+ @path = Pathname.new(uri.path)
56
+ raise ArgumentError.new(uri) unless @uri.scheme = scheme
57
+ end
58
+
59
+ # Copy the content to temporary local location and return it. If the
60
+ # scheme is local, return itselft.
61
+ def local
62
+ if scheme == "local"
63
+ self
64
+ else
65
+ Location[Temppath.create].tap {|tmp| copy(tmp)}
66
+ end
67
+ end
68
+
69
+ # Create new location appended the name.
70
+ #
71
+ # @param name [String]
72
+ # filename or directory name
73
+ # @return [BasicLocation]
74
+ # new location
75
+ def +(name)
76
+ self.class.new(@uri.as_directory + name.to_s)
77
+ end
78
+
79
+ # Create new location that has URI as a directory.
80
+ #
81
+ # @return [BasicLocation]
82
+ # new location
83
+ def as_directory
84
+ self.class.new(@uri.as_directory)
85
+ end
86
+
87
+ # Return the basename of the location.
88
+ #
89
+ # @param suffix [String]
90
+ # suffix name
91
+ # @return [String]
92
+ # basename
93
+ def basename(suffix="")
94
+ File.basename(@path, suffix)
95
+ end
96
+
97
+ # Return the extension name of location.
98
+ #
99
+ # @return
100
+ # the extension name of location
101
+ def extname
102
+ File.extname(basename)
103
+ end
104
+
105
+ # Rebuild location with the path.
106
+ #
107
+ # @param path [Pathname]
108
+ # new path
109
+ # @return [Location]
110
+ # location with new path
111
+ def rebuild(path)
112
+ scheme = @uri.scheme
113
+ auth = "%s:%s@" % [@uri.user, @uri.password] if @uri.user and @uri.password
114
+ host = @uri.host
115
+ port = ":%i" % @uri.port
116
+ path = path.expand_path("/").to_s
117
+ Location["%s://%s%s%s%s" % [scheme, auth, host, port, path]]
118
+ end
119
+
120
+ # Return true if the location is cached.
121
+ #
122
+ # @return [Boolean]
123
+ # true if the location is cached
124
+ def cached?
125
+ System::FileCache.cached?(self)
126
+ end
127
+
128
+ # Write a data into the location.
129
+ #
130
+ # @param data [String]
131
+ # data content
132
+ # @return [void]
133
+ def write(data)
134
+ if exist?
135
+ update(data)
136
+ else
137
+ create(data)
138
+ end
139
+ end
140
+
141
+ # Creates a file at the location. If a file exists at the location aleady,
142
+ # it raises an exception.
143
+ #
144
+ # @param data [String]
145
+ # data content
146
+ # @return [void]
147
+ def create(data)
148
+ raise NotImplementedError
149
+ end
150
+
151
+ # Append data to the location data.
152
+ #
153
+ # @param data [String]
154
+ # data content
155
+ # @return [void]
156
+ def append(data)
157
+ raise NotImplmentedError
158
+ end
159
+
160
+ # Read location data.
161
+ #
162
+ # @return [String]
163
+ # data content
164
+ def read
165
+ raise NotImplementedError
166
+ end
167
+
168
+ # Update with the data.
169
+ #
170
+ # @param data [String]
171
+ # new data content
172
+ # @return [void]
173
+ def update(data)
174
+ raise NotImplementedError
175
+ end
176
+
177
+ # Delete data of the location.
178
+ #
179
+ # @return [void]
180
+ def delete
181
+ raise NotImplementedError
182
+ end
183
+
184
+ # Return last modification time of the location.
185
+ #
186
+ # @return [Time]
187
+ # last modification time
188
+ def mtime
189
+ raise NotImplementedError
190
+ end
191
+
192
+ # Return byte size of data in the location.
193
+ #
194
+ # @return [Integer]
195
+ # byte size of data
196
+ def size
197
+ raise NotImplementedError
198
+ end
199
+
200
+ # Return entries of the location.
201
+ #
202
+ # @return [Array<Location>]
203
+ # entries of the location
204
+ def entries
205
+ raise NotImplementedError
206
+ end
207
+
208
+ # Return relative entries of the location.
209
+ #
210
+ # @return [Array<String>]
211
+ # entries of the location
212
+ def rel_entries(option)
213
+ raise NotImplementedError
214
+ end
215
+
216
+ # Return file entries of the location.
217
+ #
218
+ # @return [Array<Location>]
219
+ # file entries of the location
220
+ def file_entries
221
+ entries.select{|entry| entry.file?}
222
+ end
223
+
224
+ # Return directory entries of the location.
225
+ #
226
+ # @return [Array<Location>]
227
+ # directory entries of the location
228
+ def directory_entries
229
+ entries.select do |entry|
230
+ entry.directory? and not(entry.path.basename == "." or entry.path.basename == "..")
231
+ end
232
+ end
233
+
234
+ # Return true if there is data in the location.
235
+ #
236
+ # @return [Boolean]
237
+ # if there is data in the location
238
+ def exist?
239
+ raise NotImplementedError
240
+ end
241
+
242
+ # Return true if data in the location is a file.
243
+ #
244
+ # @return [Boolean]
245
+ # true if data in the location is a file
246
+ def file?
247
+ raise NotImplementedError
248
+ end
249
+
250
+ # Return true if data in the location is a directory.
251
+ #
252
+ # @return [Boolean]
253
+ # true if data in the location is a directory
254
+ def directory?
255
+ raise NotImplementedError
256
+ end
257
+
258
+ # Move to the destination.
259
+ #
260
+ # @param dest [BasicLocation]
261
+ # destination
262
+ # @return [void]
263
+ def move(dest)
264
+ raise NotImplementedError
265
+ end
266
+
267
+ # Copy location's content to the destination.
268
+ #
269
+ # @param dest [BasicLocation]
270
+ # destination
271
+ # @return [void]
272
+ def copy(dest)
273
+ raise NotImplementedError
274
+ end
275
+
276
+ # Link to the destination. If the location scheme is same to destination,
277
+ # create link by a symbolic link or lightweight copy method. If not, copy
278
+ # it simply.
279
+ #
280
+ # @param dest [BasicLocation]
281
+ # destination
282
+ # @return [void]
283
+ def link(dest)
284
+ raise NotImplementedError
285
+ end
286
+
287
+ # Move data to the destination and link self to it.
288
+ #
289
+ # @param dest [BasicLocation]
290
+ # destination
291
+ # @return [void]
292
+ def turn(dest)
293
+ raise NotImplementedError
294
+ end
295
+
296
+ # Return the digest string by SHA1.
297
+ #
298
+ # @return [String]
299
+ # hex-string of the file
300
+ def sha1
301
+ if file?
302
+ Digest::SHA1.file(local.path)
303
+ else
304
+ raise InvalidFileOperation.new(self)
305
+ end
306
+ end
307
+
308
+ # @api private
309
+ def inspect
310
+ "#<%s %s:%s>" % [self.class, scheme, @path.to_s]
311
+ end
312
+ alias :to_s :inspect
313
+
314
+ # @api private
315
+ def ==(other)
316
+ return false unless other.kind_of?(self.class)
317
+ @uri == other.uri
318
+ end
319
+ alias :eql? :"=="
320
+
321
+ # @api private
322
+ def hash
323
+ @uri.hash
324
+ end
325
+ end
326
+ end
327
+ end
328
+
@@ -1,7 +1,7 @@
1
1
  module Pione
2
2
  module Location
3
3
  # DropboxLocation represents locations on Dropbox server.
4
- class DropboxLocation < BasicLocation
4
+ class DropboxLocation < DataLocation
5
5
  set_scheme "dropbox"
6
6
 
7
7
  class << self
@@ -27,6 +27,10 @@ module Pione
27
27
  @session.set_access_token(access_token_key, access_token_secret)
28
28
  end
29
29
 
30
+ def rebuild(path)
31
+ Location["dropbox:%s" % path]
32
+ end
33
+
30
34
  # Share dropbox's access token with PIONE agents.
31
35
  #
32
36
  # @param tuple_space_server [TupleSpaceServer]
@@ -89,14 +93,23 @@ module Pione
89
93
  Time.parse(metadata["modified"])
90
94
  end
91
95
 
92
- def entries
96
+ def entries(option={})
97
+ rel_entries(option).map {|entry| rebuild(@path + entry)}
98
+ end
99
+
100
+ def rel_entries(option={})
101
+ list = []
102
+ raise NotFound.new(self) if not(directory?)
93
103
  metadata = @client.metadata(@path)
94
- if not(metadata["is_dir"]) or metadata["is_deleted"]
95
- raise NotFound.new(self)
96
- end
97
- metadata["contents"].select{|entry| not(entry["is_dir"]) and not(entry["is_deleted"])}.map do |entry|
98
- Location["dropbox:%s" % entry["path"]]
104
+ metadata["contents"].select{|entry| not(entry["is_deleted"])}.each do |entry|
105
+ list << entry["path"][0, @path.size]
106
+ entry_location = rebuild(@path + entry)
107
+ if option[:rec] and entry_location.directory?
108
+ _list = entry_location.rel_entries(option).map {|subentry| entry + subentry}
109
+ list = list + _list
110
+ end
99
111
  end
112
+ return list
100
113
  end
101
114
 
102
115
  def exist?
@@ -106,6 +119,16 @@ module Pione
106
119
  return false
107
120
  end
108
121
 
122
+ def file?
123
+ metadata = @client.metadata(@path)
124
+ return (not(metadata["is_dir"]) and not(metadata["is_deleted"]))
125
+ end
126
+
127
+ def directory?
128
+ metadata = @client.metadata(@path)
129
+ return (metadata["is_dir"] and not(metadata["is_deleted"]))
130
+ end
131
+
109
132
  def move(dest)
110
133
  if dest.scheme == scheme
111
134
  @client.file_move(@path, dest.path)
@@ -0,0 +1,38 @@
1
+ module Pione
2
+ module Location
3
+ # LocationError is raised when any resource errors happen.
4
+ class LocationError < StandardError
5
+ def initialize(location, option={})
6
+ @location = location
7
+ @option = option
8
+ end
9
+ end
10
+
11
+ # ExistAlready is raised when there is data on the location already.
12
+ class ExistAlready < LocationError
13
+ def message
14
+ "the location exists already: %s" % @location.inspect
15
+ end
16
+ end
17
+
18
+ # NotFound is raised when there isn't data on the location.
19
+ class NotFound < LocationError
20
+ def message
21
+ "%s not found" % @location.inspect
22
+ end
23
+ end
24
+
25
+ # InvalidFileOperation represents you do file operation to directory.
26
+ class InvalidFileOperation < LocationError
27
+ def message
28
+ "invalid file operation: %s" % @location.inspect
29
+ end
30
+ end
31
+
32
+ class GitError < LocationError
33
+ def message
34
+ "%s: %s" % [@option[:message], @location.address]
35
+ end
36
+ end
37
+ end
38
+ end
@@ -1,7 +1,7 @@
1
1
  module Pione
2
2
  module Location
3
3
  # FTPLocation represents locations on FTP server.
4
- class FTPLocation < BasicLocation
4
+ class FTPLocation < DataLocation
5
5
  set_scheme "ftp"
6
6
  set_real_appendable false
7
7
 
@@ -44,15 +44,11 @@ module Pione
44
44
  end
45
45
 
46
46
  def read
47
- begin
48
- data = nil
49
- file = Temppath.create
50
- connect {|ftp| ftp.get(@path, file.to_s)}
51
- data = File.read(file.to_s)
52
- return data
53
- rescue Net::FTPPermError
54
- raise NotFound.new(@uri)
55
- end
47
+ file = Temppath.create
48
+ connect {|ftp| ftp.get(@path, file.to_s)}
49
+ return File.read(file.to_s)
50
+ rescue Net::FTPPermError
51
+ raise NotFound.new(@uri)
56
52
  end
57
53
 
58
54
  def update(data)
@@ -71,6 +67,10 @@ module Pione
71
67
  connect {|ftp| ftp.delete(@path.to_s)} if exist?
72
68
  end
73
69
 
70
+ def mkdir
71
+ connect {|ftp| makedirs(ftp, @path)} unless exist?
72
+ end
73
+
74
74
  def mtime
75
75
  connect {|ftp| exist? ? ftp.mtime(@path.to_s) : (raise NotFound.new(self))}
76
76
  end
@@ -79,12 +79,23 @@ module Pione
79
79
  connect {|ftp| exist? ? ftp.size(@path.to_s) : (raise NotFound.new(self))}
80
80
  end
81
81
 
82
- def entries
82
+ def entries(option={})
83
+ rel_entries(option).map {|entry| rebuild(@path + entry)}
84
+ end
85
+
86
+ def rel_entries(option={})
87
+ list = []
83
88
  connect do |ftp|
84
- ftp.nlst(@path.to_s).map do |entry|
85
- rebuild(@path + entry)
89
+ ftp.nlst(@path.to_s).each do |entry|
90
+ list << entry
91
+ entry_location = rebuild(@path + entry)
92
+ if option[:rec] and entry_location.directory?
93
+ _list = entry_location.rel_entries(option).map {|subentry| entry + subentry}
94
+ list = list + _list
95
+ end
86
96
  end
87
97
  end
98
+ return list
88
99
  end
89
100
 
90
101
  def exist?