Class: Wavesync::Transport::Mtp

Inherits:
Object
  • Object
show all
Defined in:
lib/wavesync/transport/mtp.rb

Constant Summary collapse

DEFAULT_CACHE_ROOT =
File.join(Dir.home, '.cache', 'wavesync').freeze
MTP_ILLEGAL_CHARACTERS =

: Regexp

%r{[<>:"/\\|?*\x00-\x1f]}
CACHE_DIR_ILLEGAL_CHARACTERS =

: Regexp

/[^a-z0-9._-]/
MANIFEST_FILENAME =
'.manifest.yml'

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(device_config, libmtp: Libmtp.new, cache_root: DEFAULT_CACHE_ROOT) ⇒ Mtp

: ({ name: String, model: String, path: String, transport: String?, mp3_bitrate: Integer } device_config, ?libmtp: Libmtp, ?cache_root: String) -> void



35
36
37
38
39
40
41
# File 'lib/wavesync/transport/mtp.rb', line 35

def initialize(device_config, libmtp: Libmtp.new, cache_root: DEFAULT_CACHE_ROOT)
  @name = device_config[:name]
  @device_path = device_config[:path]
  @libmtp = libmtp
  @working_directory = self.class.cache_path(@name, cache_root: cache_root)
  FileUtils.mkdir_p(@working_directory)
end

Instance Attribute Details

#device_pathObject (readonly)

: String



20
21
22
# File 'lib/wavesync/transport/mtp.rb', line 20

def device_path
  @device_path
end

#nameObject (readonly)

: String



21
22
23
# File 'lib/wavesync/transport/mtp.rb', line 21

def name
  @name
end

#working_directoryObject (readonly)

: String



19
20
21
# File 'lib/wavesync/transport/mtp.rb', line 19

def working_directory
  @working_directory
end

Class Method Details

.cache_path(name, cache_root: DEFAULT_CACHE_ROOT) ⇒ Object

: (String name, ?cache_root: String) -> String



24
25
26
# File 'lib/wavesync/transport/mtp.rb', line 24

def self.cache_path(name, cache_root: DEFAULT_CACHE_ROOT)
  File.join(cache_root, sanitize_dir_name(name))
end

.sanitize_dir_name(name) ⇒ Object

: (String name) -> String



29
30
31
32
# File 'lib/wavesync/transport/mtp.rb', line 29

def self.sanitize_dir_name(name)
  sanitized = name.downcase.gsub(CACHE_DIR_ILLEGAL_CHARACTERS, '_')
  sanitized.empty? ? 'device' : sanitized
end

Instance Method Details

#begin_push!Object

: () -> void



67
68
69
70
71
72
# File 'lib/wavesync/transport/mtp.rb', line 67

def begin_push!
  @push_files_by_parent = @libmtp.files.group_by(&:parent_id)
  @push_folders_by_parent = @libmtp.folders.group_by(&:parent_id)
  @push_storage_id = primary_storage_id(@push_folders_by_parent)
  @push_manifest = load_manifest
end

#commit!(&progress) ⇒ Object

: () ?{ (Integer, Integer, String) -> void } -> void



100
101
102
103
104
105
106
107
108
# File 'lib/wavesync/transport/mtp.rb', line 100

def commit!(&progress)
  begin_push!
  local_files = enumerate_local_files
  local_files.each_with_index do |entry, index|
    progress&.call(index, local_files.size, entry[:relative_path])
    push_file!(entry[:relative_path])
  end
  finish_push!
end

#finish_push!Object

: () -> void



90
91
92
93
94
95
96
97
# File 'lib/wavesync/transport/mtp.rb', line 90

def finish_push!
  save_manifest if @push_manifest
  @push_files_by_parent = nil
  @push_folders_by_parent = nil
  @push_storage_id = nil
  @push_manifest = nil
  @libmtp.close!
end

#prepare!(&progress) ⇒ Object

: () ?{ (Integer, Integer, String) -> void } -> void



44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/wavesync/transport/mtp.rb', line 44

def prepare!(&progress)
  device_files = @libmtp.files
  folder_paths = build_folder_paths(@libmtp.folders)

  candidates = device_files.filter_map do |device_file|
    next unless wav?(device_file.filename)

    relative_path = relative_path_for(device_file, folder_paths)
    next unless relative_path

    local_path = File.join(@working_directory, relative_path)
    { device_file: device_file, relative_path: relative_path, local_path: local_path }
  end

  Dir.mktmpdir('wavesync_mtp_pull') do |tmpdir|
    candidates.each_with_index do |candidate, index|
      progress&.call(index, candidates.size, candidate[:relative_path])
      pull_if_cues_differ(candidate, tmpdir)
    end
  end
end

#push_file!(relative_path) ⇒ Object

: (String relative_path) -> void

Raises:



75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/wavesync/transport/mtp.rb', line 75

def push_file!(relative_path)
  files_by_parent = @push_files_by_parent
  folders_by_parent = @push_folders_by_parent
  storage_id = @push_storage_id
  raise Libmtp::Error, 'push_file! called before begin_push!' unless files_by_parent && folders_by_parent && storage_id

  local_path = File.join(@working_directory, relative_path)
  return unless File.file?(local_path)

  remote_path = join_remote_paths(@device_path, relative_path)
  entry = { local_path: local_path, relative_path: relative_path, remote_path: remote_path } #: { local_path: String, relative_path: String, remote_path: String }
  push_one(entry, files_by_parent: files_by_parent, folders_by_parent: folders_by_parent, storage_id: storage_id)
end