mls 1.6.0 → 1.7.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 +5 -5
- data/bin/mls +22 -1
- data/lib/mls/cli.rb +13 -1
- data/lib/mls/cli/documents.rb +4 -3
- data/lib/mls/cli/storage.rb +2 -1
- data/lib/mls/cli/storage/b2.rb +87 -0
- data/lib/mls/models/account.rb +1 -0
- data/lib/mls/models/broadcast.rb +11 -0
- data/lib/mls/models/document.rb +2 -1
- data/lib/mls/models/listing.rb +1 -1
- data/lib/mls/models/property.rb +2 -2
- data/lib/mls/models/region.rb +1 -0
- data/lib/mls/models/review.rb +18 -0
- data/lib/mls/models/task.rb +2 -0
- data/mls.gemspec +1 -1
- metadata +6 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 61267aa211891a0f0f6d22339b6997745fa532cdb4d50390b5b8645cfb887ffe
|
4
|
+
data.tar.gz: 1df8ded07de72295b7ea2852323cb51838398c77a2a782dffa0c6b4ff03c2c0b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 169618f8b6f8aec727b99d2a4a893cdcd292ae925095f57df1431d28f72d1fde6a6a3891b65505abd935de9268a5c8b639b1f5c72393c7bff72ee4391c790593
|
7
|
+
data.tar.gz: 983cc885eb785faa6dc33e4dce9246b368b9519ab4d451aca20708e0fc47f282401d9238ed5fbc8b33ef253b8715df88200247768b1b72882d17c819a8b143d7
|
data/bin/mls
CHANGED
@@ -3,7 +3,7 @@ require File.expand_path('../../lib/mls/cli', __FILE__)
|
|
3
3
|
|
4
4
|
case ARGV.shift.downcase.strip
|
5
5
|
when "documents:backup"
|
6
|
-
MLS::CLI.parse_args(ARGV)
|
6
|
+
MLS::CLI.parse_args(ARGV)
|
7
7
|
directory = ARGV.shift
|
8
8
|
|
9
9
|
if directory.nil? || !File.directory?(directory)
|
@@ -12,6 +12,27 @@ when "documents:backup"
|
|
12
12
|
end
|
13
13
|
|
14
14
|
MLS::CLI::Documents.backup(directory)
|
15
|
+
when "documents:migrate"
|
16
|
+
MLS::CLI.parse_args(ARGV)
|
17
|
+
directory = ARGV.shift
|
18
|
+
|
19
|
+
if directory.nil? || !File.directory?(directory)
|
20
|
+
puts "Usage: mls documents:backup dir [options...]"
|
21
|
+
exit 1
|
22
|
+
end
|
23
|
+
|
24
|
+
b2 = MLS::CLI::Storage::B2.new(MLS::CLI.options[:b2])
|
25
|
+
Document.where(excludes: 'b2/sha256').find_each do |document|
|
26
|
+
if document.sha256 && File.exists?(File.join(directory, MLS::CLI::Documents.partition(document.sha256)))
|
27
|
+
b2.upload_file(documents.sha256, File.open(File.join(directory, MLS::CLI::Documents.partition(document.sha256))), {
|
28
|
+
filename: document.filename,
|
29
|
+
sha1: document.sha1,
|
30
|
+
content_type: document.content_type,
|
31
|
+
size: document.size
|
32
|
+
})
|
33
|
+
end
|
34
|
+
end
|
35
|
+
when "documents:check"
|
15
36
|
else
|
16
37
|
puts "Usage: mls documents:backup dir [options...]"
|
17
38
|
end
|
data/lib/mls/cli.rb
CHANGED
@@ -32,7 +32,19 @@ module MLS::CLI
|
|
32
32
|
end
|
33
33
|
end
|
34
34
|
when 'b2'
|
35
|
-
|
35
|
+
MLS::CLI.options[:b2] = {
|
36
|
+
account_id: URI.unescape(url.user),
|
37
|
+
application_key: URI.unescape(url.password),
|
38
|
+
bucket: URI.unescape(url.host)
|
39
|
+
prefix: url.path&.empty? ? url.path : nil
|
40
|
+
}
|
41
|
+
url.query.split('&').each do |qp|
|
42
|
+
key, value = qp.split('=').map { |d| URI.unescape(d) }
|
43
|
+
case key
|
44
|
+
when 'partition'
|
45
|
+
MLS::CLI.options[:b2][:partition] = value.to_i
|
46
|
+
end
|
47
|
+
end
|
36
48
|
when 'mls'
|
37
49
|
arg = arg.sub('mls://', 'https://')
|
38
50
|
MLS::CLI.options[:mls] = arg
|
data/lib/mls/cli/documents.rb
CHANGED
@@ -33,7 +33,7 @@ module MLS::CLI::Documents
|
|
33
33
|
|
34
34
|
query = if File.exist?(last_sync_file)
|
35
35
|
from_timestamp = Time.iso8601(File.read(last_sync_file))
|
36
|
-
Document.
|
36
|
+
Document.where(Document.arel_table['created_at'].gteq(from_timestamp))
|
37
37
|
else
|
38
38
|
Document.all
|
39
39
|
end
|
@@ -51,15 +51,16 @@ module MLS::CLI::Documents
|
|
51
51
|
raise 'unkown storage engine'
|
52
52
|
end
|
53
53
|
|
54
|
-
|
54
|
+
print "Downloading #{document.id.to_s.ljust(7)} "
|
55
55
|
storage_engine.copy_to_tempfile(document.send(key)) do |file|
|
56
56
|
digests = calculate_digest(file)
|
57
|
+
puts partition(document.sha256)
|
57
58
|
|
58
59
|
raise 'MD5 does not match' if digests[:md5] != document.md5
|
59
60
|
document.update!(digests.merge({provider: ['s3/hash_key']}))
|
60
61
|
|
61
62
|
FileUtils.mkdir_p(File.dirname(File.join(dir, partition(document.sha256))))
|
62
|
-
FileUtils.mv(file.path, File.join(dir, partition(document.sha256))
|
63
|
+
FileUtils.mv(file.path, File.join(dir, partition(document.sha256)))
|
63
64
|
end
|
64
65
|
|
65
66
|
File.write(last_sync_file, document.created_at.iso8601(6))
|
data/lib/mls/cli/storage.rb
CHANGED
@@ -1 +1,2 @@
|
|
1
|
-
require File.expand_path('../storage/s3', __FILE__)
|
1
|
+
require File.expand_path('../storage/s3', __FILE__)
|
2
|
+
require File.expand_path('../storage/b2', __FILE__)
|
@@ -0,0 +1,87 @@
|
|
1
|
+
require 'b2'
|
2
|
+
|
3
|
+
module MLS::CLI::Storage
|
4
|
+
class B2
|
5
|
+
|
6
|
+
def initialize(configs = {})
|
7
|
+
@configs = configs
|
8
|
+
@configs[:prefix] ||= ""
|
9
|
+
|
10
|
+
@client = B2::Bucket.new({
|
11
|
+
'bucketId' => configs[:bucket_id]
|
12
|
+
}, B2.new({
|
13
|
+
account_id: configs[:account_id],
|
14
|
+
application_key: configs[:application_key]
|
15
|
+
}))
|
16
|
+
end
|
17
|
+
|
18
|
+
def local?
|
19
|
+
false
|
20
|
+
end
|
21
|
+
|
22
|
+
# def url(key)
|
23
|
+
# [host, destination(key)].join('/')
|
24
|
+
# end
|
25
|
+
|
26
|
+
# def host
|
27
|
+
# h = @configs[:bucket_host_alias] || "https://s3.amazonaws.com/#{@configs[:bucket]}"
|
28
|
+
# h.delete_suffix('/')
|
29
|
+
# end
|
30
|
+
|
31
|
+
def destination(key)
|
32
|
+
"#{@configs[:prefix]}#{partition(key)}".gsub(/^\//, '')
|
33
|
+
end
|
34
|
+
|
35
|
+
def exists?(key)
|
36
|
+
@client.has_key?(destination(key))
|
37
|
+
end
|
38
|
+
|
39
|
+
def write(key, file, meta_info)
|
40
|
+
file = file.tempfile if file.is_a?(ActionDispatch::Http::UploadedFile)
|
41
|
+
file = File.open(file) if file.is_a?(String)
|
42
|
+
|
43
|
+
@client.upload_file(key, file, mime_type: meta_info[:content_type], sha1: meta_info[:sha1], content_disposition: "inline; filename=\"#{meta_info[:filename]}\"")
|
44
|
+
end
|
45
|
+
|
46
|
+
def download(key, to=nil, &block)
|
47
|
+
@client.download(destination(key), to, &block)
|
48
|
+
end
|
49
|
+
|
50
|
+
def delete(key)
|
51
|
+
@client.delete!(key)
|
52
|
+
end
|
53
|
+
|
54
|
+
def copy_to_tempfile(key)
|
55
|
+
tmpfile = Tempfile.new([File.basename(key), File.extname(key)], binmode: true)
|
56
|
+
download(key, tmpfile.path)
|
57
|
+
if block_given?
|
58
|
+
begin
|
59
|
+
yield(tmpfile)
|
60
|
+
ensure
|
61
|
+
tmpfile.close!
|
62
|
+
end
|
63
|
+
else
|
64
|
+
tmpfile
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def partition(value)
|
69
|
+
return value unless @configs[:partition]
|
70
|
+
split = value.scan(/.{1,4}/)
|
71
|
+
split.shift(@configs[:partition_depth] || 3).join("/") + split.join("")
|
72
|
+
end
|
73
|
+
|
74
|
+
def sha1(key)
|
75
|
+
@client.file(destination(key)).sha1
|
76
|
+
end
|
77
|
+
|
78
|
+
def last_modified(key)
|
79
|
+
@client.file(destination(key)).uploaded_at
|
80
|
+
end
|
81
|
+
|
82
|
+
def mime_type(key)
|
83
|
+
@client.file(destination(key)).mime_type
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
87
|
+
end
|
data/lib/mls/models/account.rb
CHANGED
data/lib/mls/models/document.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
class Document < MLS::Model
|
2
2
|
|
3
3
|
has_many :image_orderings, foreign_key: :image_id
|
4
|
+
has_many :reviews
|
4
5
|
|
5
6
|
def self.create(file)
|
6
7
|
if doc = find_matching(file)
|
@@ -18,7 +19,7 @@ class Document < MLS::Model
|
|
18
19
|
end
|
19
20
|
|
20
21
|
def url(style=:original)
|
21
|
-
MLS.config['document_host'] + '/' + path(style)
|
22
|
+
MLS.config['document_host'].gsub(/\/$/, '') + '/' + path(style)
|
22
23
|
end
|
23
24
|
|
24
25
|
def path(style=:original)
|
data/lib/mls/models/listing.rb
CHANGED
data/lib/mls/models/property.rb
CHANGED
@@ -33,7 +33,7 @@ class Property < MLS::Model
|
|
33
33
|
accepts_nested_attributes_for :image_orderings, :addresses
|
34
34
|
|
35
35
|
def contacts
|
36
|
-
@contact ||= listings.eager_load(:accounts => [:email_addresses, :phones, :organization]).filter(leased_at: nil, authorized: true, type: ['Lease', 'Sublease'], :touched_at => {:gte =>
|
36
|
+
@contact ||= listings.eager_load(:accounts => [:email_addresses, :phones, :organization]).filter(leased_at: nil, authorized: true, type: ['Lease', 'Sublease'], :touched_at => {:gte => 180.days.ago})
|
37
37
|
.order(size: :desc).first.try(:contacts)
|
38
38
|
end
|
39
39
|
|
@@ -128,7 +128,7 @@ class Property < MLS::Model
|
|
128
128
|
region = neighborhood_region
|
129
129
|
region ||= city_region
|
130
130
|
region ||= market
|
131
|
-
region ||= regions.
|
131
|
+
region ||= regions.filter(depth: true).select{ |r| r.type != "Zip Code Tabulation Area" }.sort_by(&:depth).reverse.first
|
132
132
|
region
|
133
133
|
end
|
134
134
|
|
data/lib/mls/models/region.rb
CHANGED
@@ -15,6 +15,7 @@ class Region < MLS::Model
|
|
15
15
|
has_one :geometry, as: :subject
|
16
16
|
has_many :stats, as: :subject
|
17
17
|
|
18
|
+
has_and_belongs_to_many :tasks
|
18
19
|
has_and_belongs_to_many :organizations
|
19
20
|
has_and_belongs_to_many :parents, :join_table => 'regions_regions', :class_name => 'Region', :foreign_key => 'child_id', :association_foreign_key => 'parent_id'
|
20
21
|
has_and_belongs_to_many :children, :join_table => 'regions_regions', :class_name => 'Region', :foreign_key => 'parent_id', :association_foreign_key => 'child_id'
|
data/lib/mls/models/task.rb
CHANGED
@@ -11,6 +11,8 @@ class Task < MLS::Model
|
|
11
11
|
has_many :reviews, -> { where(:type => "review") }, :class_name => "Task", :as => :subject, :inverse_of => :subject
|
12
12
|
has_many :fixes, -> { where(:type => "fix") }, :class_name => "Task", :as => :subject, :inverse_of => :subject
|
13
13
|
|
14
|
+
has_and_belongs_to_many :regions
|
15
|
+
|
14
16
|
def for_source?
|
15
17
|
subject_type == "Source"
|
16
18
|
end
|
data/mls.gemspec
CHANGED
@@ -3,7 +3,7 @@ $:.push File.expand_path("../lib", __FILE__)
|
|
3
3
|
|
4
4
|
Gem::Specification.new do |s|
|
5
5
|
s.name = "mls"
|
6
|
-
s.version = '1.
|
6
|
+
s.version = '1.7.0'
|
7
7
|
s.authors = ["Jon Bracy", "James R. Bracy"]
|
8
8
|
s.email = ["jon@42floors.com", "james@42floors.com"]
|
9
9
|
s.homepage = "http://mls.42floors.com"
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mls
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.7.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jon Bracy
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2018-
|
12
|
+
date: 2018-07-18 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rake
|
@@ -253,6 +253,7 @@ files:
|
|
253
253
|
- lib/mls/cli.rb
|
254
254
|
- lib/mls/cli/documents.rb
|
255
255
|
- lib/mls/cli/storage.rb
|
256
|
+
- lib/mls/cli/storage/b2.rb
|
256
257
|
- lib/mls/cli/storage/s3.rb
|
257
258
|
- lib/mls/comment.rb
|
258
259
|
- lib/mls/models/account.rb
|
@@ -260,6 +261,7 @@ files:
|
|
260
261
|
- lib/mls/models/action.rb
|
261
262
|
- lib/mls/models/address.rb
|
262
263
|
- lib/mls/models/api_key.rb
|
264
|
+
- lib/mls/models/broadcast.rb
|
263
265
|
- lib/mls/models/coworking_space.rb
|
264
266
|
- lib/mls/models/credit_card.rb
|
265
267
|
- lib/mls/models/datum.rb
|
@@ -286,6 +288,7 @@ files:
|
|
286
288
|
- lib/mls/models/recommendation.rb
|
287
289
|
- lib/mls/models/reference.rb
|
288
290
|
- lib/mls/models/region.rb
|
291
|
+
- lib/mls/models/review.rb
|
289
292
|
- lib/mls/models/search.rb
|
290
293
|
- lib/mls/models/service.rb
|
291
294
|
- lib/mls/models/session.rb
|
@@ -331,7 +334,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
331
334
|
version: '0'
|
332
335
|
requirements: []
|
333
336
|
rubyforge_project: mls
|
334
|
-
rubygems_version: 2.
|
337
|
+
rubygems_version: 2.7.4
|
335
338
|
signing_key:
|
336
339
|
specification_version: 4
|
337
340
|
summary: 42Floors MLS Client
|