Class: Softcover::Book

Inherits:
Object
  • Object
show all
Includes:
Output, Utils
Defined in:
lib/softcover/book.rb

Defined Under Namespace

Classes: BookFile, UploadError

Constant Summary collapse

DEFAULT_MEDIA_DIR =
"media"

Constants included from Utils

Utils::UNITS

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Output

should_output?, silence!, silent?, #system, unsilence!

Methods included from Utils

#add_highlight_class!, #as_size, #book_file_lines, #chapter_label, #commands, #current_book, #dependency_filename, #digest, #executable, #execute, #in_book_directory?, #language_labels, #linux?, #logged_in?, #master_content, #master_filename, #master_latex_header, #mkdir, #non_comment_lines, #os_x?, #path, #raw_lines, #reset_current_book!, #rm, #silence, #source, #tmpify, #unpublish_slug, #write_master_latex_file, #write_pygments_file

Constructor Details

#initialize(options = {}) ⇒ Book

Returns a new instance of Book.



12
13
14
15
16
17
18
19
20
21
22
# File 'lib/softcover/book.rb', line 12

def initialize(options={})
  require "softcover/client"
  @manifest = Softcover::BookManifest.new(options)
  @marketing = Softcover::MarketingManifest.new

  @client = Softcover::Client.new_with_book self

  @media_dir = DEFAULT_MEDIA_DIR

  @processed_media = []
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(name, *args, &block) ⇒ Object (private)



231
232
233
# File 'lib/softcover/book.rb', line 231

def method_missing(name, *args, &block)
  @manifest.send(name) || @marketing.send(name) || nil
end

Instance Attribute Details

#errorsObject

Returns the value of attribute errors.



7
8
9
# File 'lib/softcover/book.rb', line 7

def errors
  @errors
end

#manifestObject

Returns the value of attribute manifest.



7
8
9
# File 'lib/softcover/book.rb', line 7

def manifest
  @manifest
end

#media_dirObject

Returns the value of attribute media_dir.



7
8
9
# File 'lib/softcover/book.rb', line 7

def media_dir
  @media_dir
end

#processed_mediaObject

Returns the value of attribute processed_media.



7
8
9
# File 'lib/softcover/book.rb', line 7

def processed_media
  @processed_media
end

#signaturesObject

Returns the value of attribute signatures.



7
8
9
# File 'lib/softcover/book.rb', line 7

def signatures
  @signatures
end

#uploaderObject

Returns the value of attribute uploader.



7
8
9
# File 'lib/softcover/book.rb', line 7

def uploader
  @uploader
end

Instance Method Details

#chapter_attributesObject



71
72
73
# File 'lib/softcover/book.rb', line 71

def chapter_attributes
  chapters.map(&:to_hash)
end

#create_or_updateObject



96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
# File 'lib/softcover/book.rb', line 96

def create_or_update
  raise "HTML not built!" if Dir['html/*'].empty?

  res = @client.create_or_update_book id: id,
                                      files: files,
                                      title: title,
                                      slug: slug,
                                      subtitle: subtitle,
                                      description: description,
                                      chapters: chapter_attributes,
                                      prices: prices,
                                      faq: faq,
                                      testimonials: testimonials,
                                      marketing_content: marketing_content,
                                      contact_email: contact_email,
                                      hide_softcover_footer:
                                        hide_softcover_footer,
                                      authors: authors,
                                      ga_account: 

  if res['errors']
    @errors = res['errors']
    return false
  end

  # is this needed?
  @attrs = res['book']

  self.id = @attrs['id']
  Softcover::BookConfig['last_uploaded_at'] = Time.now

  # res contains the S3 upload signatures needed
  @uploader = Softcover::Uploader.new res

  true

rescue Exception => e
  @errors = [e.message]
  raise e
  false
end

#destroyObject



165
166
167
168
169
170
171
172
# File 'lib/softcover/book.rb', line 165

def destroy
  res = @client.destroy
  if res['errors']
    @errors = res['errors']
    return false
  end
  true
end

#filenamesObject



67
68
69
# File 'lib/softcover/book.rb', line 67

def filenames
  files.map &:path
end

#filesObject

get array of paths and checksums



60
61
62
63
64
65
# File 'lib/softcover/book.rb', line 60

def files
  paths = %W{html/#{slug}.html html/*_fragment.html images/**/* config/*}
  Dir[*paths].map do |path|
    BookFile.new(path) unless File.directory?(path)
  end.compact
end

#get_book_files(dir) ⇒ Object



204
205
206
207
208
# File 'lib/softcover/book.rb', line 204

def get_book_files(dir)
  Dir["#{dir}/**/*"].map do |path|
    BookFile.new(path) unless File.directory?(path)
  end.compact
end

#idObject

TODO: extract pattern to config helper:

has_config_for :id, :last_uploaded_at, path: ".polytex-book"


51
52
53
# File 'lib/softcover/book.rb', line 51

def id
  Softcover::BookConfig['id']
end

#id=(n) ⇒ Object



55
56
57
# File 'lib/softcover/book.rb', line 55

def id=(n)
  Softcover::BookConfig['id'] = n
end

#notify_file_upload(path) ⇒ Object



157
158
159
160
161
162
163
# File 'lib/softcover/book.rb', line 157

def notify_file_upload(path)
  book_file = BookFile.find path

  # this could spin off new thread:
  @client.notify_file_upload path: book_file.path,
    checksum: book_file.checksum
end

#notify_upload_completeObject



147
148
149
150
151
152
153
154
155
# File 'lib/softcover/book.rb', line 147

def notify_upload_complete
  res = @client.notify_upload_complete

  if res['errors'].nil?
    return url
  else
    raise UploadError, "Couldn't verify upload: #{res['errors']}"
  end
end

#openObject

Returns the system-dependent ‘open` command.



86
87
88
89
90
91
92
93
94
# File 'lib/softcover/book.rb', line 86

def open
  if os_x?
    'open'
  elsif linux?
    'xdg-open'
  else
    raise "Platform #{RUBY_PLATFORM} not supported"
  end
end

#open_in_browserObject

Opens the book in the browser (OS X & Linux).



81
82
83
# File 'lib/softcover/book.rb', line 81

def open_in_browser
  `#{open} #{url}`
end

#process_mediaObject

  1. iterate over /media/*

> use directory name as path parameter

> get checksums for all included files

> send each to /media API endpoint and then upload



183
184
185
186
187
188
# File 'lib/softcover/book.rb', line 183

def process_media
  Dir["media/*"].each do |media_dir|
    next unless File.directory?(media_dir) && !(media_dir =~ /^\./)
    process_media_directory media_dir
  end
end

#process_media_directory(dir) ⇒ Object



190
191
192
193
194
195
196
197
198
199
200
201
202
# File 'lib/softcover/book.rb', line 190

def process_media_directory(dir)
  return false if @processed_media.include?(dir)

  puts "Processing #{dir} directory..."

  files_to_upload = get_book_files(dir).select do |file|
    file.ready?
  end

  upload_media! dir, files_to_upload

  @processed_media.push dir
end

#upload!(options = {}) ⇒ Object



138
139
140
141
142
143
144
145
# File 'lib/softcover/book.rb', line 138

def upload!(options={})
  @uploader.after_each do |params|
    notify_file_upload params['path']
  end

  @uploader.upload!(options)
  notify_upload_complete
end

#upload_media!(path, files) ⇒ Object



210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
# File 'lib/softcover/book.rb', line 210

def upload_media!(path, files)
  return if files.empty?

  manifest_path = File.join(path, "manifest.yml")
  manifest = File.exists?(manifest_path) ? File.read(manifest_path) : nil

  res = @client.get_media_upload_params path, files, manifest

  if res['upload_params']
    media_uploader = Softcover::Uploader.new res
    media_uploader.after_each do |params|
      notify_file_upload params['path']
    end
    media_uploader.upload!
    notify_upload_complete
  else
    raise 'server error'
  end
end

#urlObject



75
76
77
78
# File 'lib/softcover/book.rb', line 75

def url
  # TODO: append api_token to auto-login?
  "#{@client.host}/books/#{id}/redirect"
end