Class: Lt::Google::Api::Drive

Inherits:
Object
  • Object
show all
Defined in:
lib/lt/google/api/drive.rb

Constant Summary collapse

FOLDER_RE =
%r{/drive/(.*/)?folders/([^/?]+)/?}.freeze
MIME_FILE =
'application/vnd.google-apps.document'
MIME_FOLDER =
'application/vnd.google-apps.folder'

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(credentials) ⇒ Drive

Returns a new instance of Drive.



29
30
31
32
# File 'lib/lt/google/api/drive.rb', line 29

def initialize(credentials)
  @service = ::Google::Apis::DriveV3::DriveService.new
  @service.authorization = credentials
end

Instance Attribute Details

#serviceObject (readonly)

Returns the value of attribute service.



13
14
15
# File 'lib/lt/google/api/drive.rb', line 13

def service
  @service
end

Class Method Details

.build(credentials) ⇒ Object



16
17
18
# File 'lib/lt/google/api/drive.rb', line 16

def build(credentials)
  new(credentials).service
end

.file_url_for(file_id) ⇒ Object



20
21
22
# File 'lib/lt/google/api/drive.rb', line 20

def file_url_for(file_id)
  "https://drive.google.com/open?id=#{file_id}"
end

.folder_id_for(url) ⇒ Object



24
25
26
# File 'lib/lt/google/api/drive.rb', line 24

def folder_id_for(url)
  url.match(FOLDER_RE)[2]
end

Instance Method Details

#copy(file_ids, folder_id) ⇒ Object



34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/lt/google/api/drive.rb', line 34

def copy(file_ids, folder_id)
  file_ids.each do |id|
    service.get_file(id, fields: 'name', supports_all_drives: true) do |f, err|
      if err.present?
        Rails.logger.error "Failed to get file with #{id}, #{err.message}"
      else
        service.copy_file(
          id,
          ::Google::Apis::DriveV3::File.new(name: f.name, parents: [folder_id]),
          supports_all_drives: true
        )
      end
    end
  end
  folder_id
end

#copy_files(folder_id, target_id) ⇒ Object



51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/lt/google/api/drive.rb', line 51

def copy_files(folder_id, target_id)
  new_files = list folder_id
  current_files = list target_id

  # delete old files not present on new version
  current_files.each do |file|
    next if new_files.detect { |f| f.name == file.name }

    service.delete_file(file.id, supports_all_drives: true)
  end

  new_files.each do |file|
    # skip if the file already exists
    next if current_files.detect { |f| f.name == file.name }

    # copy if it's a new file
    new_file = ::Google::Apis::DriveV3::File.new(name: file.name, parents: [target_id])
    service.copy_file(file.id, new_file, supports_all_drives: true)
  end
end

#create_folder(name, parent_id = nil) ⇒ Object



72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/lt/google/api/drive.rb', line 72

def create_folder(name, parent_id = nil)
  if parent_id.present? && (folders = fetch_folders(name, parent_id)).any?
    return folders.first.id
  end

   = ::Google::Apis::DriveV3::File.new(
    name: name,
    mime_type: MIME_FOLDER,
    parents: [parent_id]
  )
  service.create_file(, supports_all_drives: true)&.id
end

#fetch_folders(name, folder_id) ⇒ Object



112
113
114
115
116
117
118
119
# File 'lib/lt/google/api/drive.rb', line 112

def fetch_folders(name, folder_id)
  service.list_files(
    q: %("#{folder_id}" in parents and name = "#{name}" and mimeType = "#{MIME_FOLDER}" and trashed = false),
    fields: 'files(id)',
    include_items_from_all_drives: true,
    supports_all_drives: true
  )&.files
end

#list_file_ids_in(folder_id, mime_type: MIME_FILE, with_subfolders: true) ⇒ Object



85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/lt/google/api/drive.rb', line 85

def list_file_ids_in(folder_id, mime_type: MIME_FILE, with_subfolders: true)
  [].tap do |result|
    page_token = nil
    loop do
      response = service.list_files(
        q: %("#{folder_id}" in parents and trashed = false),
        fields: 'files(id, mime_type), nextPageToken',
        page_token: page_token.to_s,
        include_items_from_all_drives: true,
        supports_all_drives: true
      )
      break if response.nil?

      response.files.each do |f|
        case f.mime_type
        when mime_type then result << f.id
        when MIME_FOLDER
          result.concat(list_file_ids_in(f.id, mime_type: mime_type)) if with_subfolders
        end
      end

      page_token = response.next_page_token
      break if page_token.nil?
    end
  end.flatten
end