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!, #article?, #as_size, #book_file_lines, #chapter_label, #commands, #current_book, #dependency_filename, #digest, #executable, #execute, #filename_or_default, #first_path, #get_filename, #html_extension, #in_book_directory?, #language_labels, #linux?, #logged_in?, #master_content, #master_filename, #master_latex_header, #mkdir, #non_comment_lines, #os_x?, #path, #polytexnic_html, #raw_lines, #reset_current_book!, #rm, #rm_r, #silence, #silence_stream, #source, #template_dir, #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)



246
247
248
# File 'lib/softcover/book.rb', line 246

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



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

def chapter_attributes
  chapters.map(&:to_hash)
end

#create_or_update(options = {}) ⇒ Object



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
137
138
139
140
141
142
143
144
145
146
147
# File 'lib/softcover/book.rb', line 97

def create_or_update(options={})
  raise "HTML not built!" if Dir['html/*'].empty?

  params = {
    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,
    author_name: author,
    authors: authors,
    ga_account: ,
    repo_url: repo_url,
    remove_unused_media_bundles: options[:remove_unused_media_bundles],
    custom_math: custom_math,
    convert_kit_follow_tag_id: convert_kit_follow_tag_id
  }

  res = @client.create_or_update_book params

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

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

  self.id = @attrs['id']

  # Not needed for now:
  # 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

#custom_mathObject



241
242
243
# File 'lib/softcover/book.rb', line 241

def custom_math
  Softcover::Mathjax.custom_macros
end

#destroyObject



176
177
178
179
180
181
182
183
# File 'lib/softcover/book.rb', line 176

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

#filenamesObject



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

def filenames
  files.map &:path
end

#filesObject

get array of paths and checksums



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

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

#get_book_files(dir) ⇒ Object



215
216
217
218
219
# File 'lib/softcover/book.rb', line 215

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



168
169
170
171
172
173
174
# File 'lib/softcover/book.rb', line 168

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



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

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.



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

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).



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

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

#process_media(options = {}) ⇒ Object

  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



194
195
196
197
198
199
# File 'lib/softcover/book.rb', line 194

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

#process_media_directory(dir, options = {}) ⇒ Object



201
202
203
204
205
206
207
208
209
210
211
212
213
# File 'lib/softcover/book.rb', line 201

def process_media_directory(dir, options={})
  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, options

  @processed_media.push dir
end

#upload!(options = {}) ⇒ Object



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

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, options = {}) ⇒ Object



221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
# File 'lib/softcover/book.rb', line 221

def upload_media!(path, files, options={})
  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, options

  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



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

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