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)



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

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



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
148
# File 'lib/softcover/book.rb', line 98

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



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

def custom_math
  Softcover::Mathjax.custom_macros
end

#destroyObject



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

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



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

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



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

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



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

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.



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

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
85
# File 'lib/softcover/book.rb', line 82

def open_in_browser
  puts url
  `#{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



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

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



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

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



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

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



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

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