softcover 0.9.10 → 0.9.11

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9e6eeed7020f2fc586daf6ea25063ecb42398ff4
4
- data.tar.gz: b0c413809eb71625b8a75b0e548473abebf66065
3
+ metadata.gz: fafabcae98cbdfb8322a3d0dfd47b73e2bcd1d28
4
+ data.tar.gz: 7c6201045eafaa089f732789c1d1d4335a7e69fb
5
5
  SHA512:
6
- metadata.gz: 152b9d3c927e070b5bab37b5679353d04c64d5c1143838e22a556b2b22e022780ab2b0b1cf9e17389b8ee9239dc61688723c3c1d6ff1a762b615771465c98c7e
7
- data.tar.gz: 9ad5909394d3de83f7686602a6cdc09e1865635997729d20dba0226d43162f2a11012e0d5c4c8580d875500f9607223e6f2d6930935ca2ccda7e04c6ae8d31c5
6
+ metadata.gz: 8468f816a5f7bbca55f9c1a13241744392876cdeb912d059549cffab92c7734be89af97351d7b22ee3418882d9a53ee253150259c9db6e3139b43e641b95eab7
7
+ data.tar.gz: b043e027bf8f55b92d4717af933ae72b989d07a90f0abb07fd97b98443e8758cbce6b698403b1f3420a22926bf48db450d4d4c832d16a691ecd118e5e964be61
@@ -1,10 +1,10 @@
1
1
  class Softcover::Book
2
2
  include Softcover::Utils
3
3
 
4
- DEFAULT_SCREENCASTS_DIR = "screencasts"
4
+ DEFAULT_MEDIA_DIR = "media"
5
5
 
6
6
  attr_accessor :errors, :uploader, :signatures, :manifest,
7
- :processed_screencasts, :screencasts_dir
7
+ :processed_media, :media_dir
8
8
 
9
9
  class UploadError < StandardError; end
10
10
 
@@ -15,9 +15,9 @@ class Softcover::Book
15
15
 
16
16
  @client = Softcover::Client.new_with_book self
17
17
 
18
- @screencasts_dir = DEFAULT_SCREENCASTS_DIR
18
+ @media_dir = DEFAULT_MEDIA_DIR
19
19
 
20
- @processed_screencasts = []
20
+ @processed_media = []
21
21
  end
22
22
 
23
23
  class BookFile < Struct.new(:path)
@@ -57,12 +57,10 @@ class Softcover::Book
57
57
 
58
58
  # get array of paths and checksums
59
59
  def files
60
- # question: should we use `git ls-files` instead?
61
- # TODO: only use pertinent files
62
- paths = %w{html/*_fragment.html images/**/* ebooks/* config/*}
63
- Dir[*paths].reject { |path| File.directory?(path) }.map do |path|
64
- BookFile.new path
65
- end
60
+ paths = %w{html/*_fragment.html images/**/* config/*}
61
+ Dir[*paths].map do |path|
62
+ BookFile.new(path) unless File.directory?(path)
63
+ end.compact
66
64
  end
67
65
 
68
66
  def filenames
@@ -125,6 +123,7 @@ class Softcover::Book
125
123
  self.id = @attrs['id']
126
124
  Softcover::BookConfig['last_uploaded_at'] = Time.now
127
125
 
126
+ # res contains the S3 upload signatures needed
128
127
  @uploader = Softcover::Uploader.new res
129
128
 
130
129
  true
@@ -172,41 +171,57 @@ class Softcover::Book
172
171
  end
173
172
 
174
173
  # ============================================================================
175
- # Screencast handling
174
+ # Media handling
176
175
  # ============================================================================
177
176
 
178
- def process_screencasts
179
- files_to_upload = find_screencasts.select do |file|
180
- next false if @processed_screencasts.include?(file)
177
+ # 1. iterate over /ebooks, /media/*
178
+ # => use directory name as path parameter
179
+ # => get checksums for all included files
180
+ # => send each to /media API endpoint and then upload
181
+
182
+ def process_media
183
+ process_media_directory "ebooks"
184
+
185
+ Dir["media/*"].each do |media_dir|
186
+ next unless File.directory?(media_dir) && !(media_dir =~ /^\./)
187
+ process_media_directory media_dir
188
+ end
189
+ end
190
+
191
+ def process_media_directory(dir)
192
+ return false if @processed_media.include?(dir)
193
+
194
+ puts "Processing #{dir} directory..."
181
195
 
196
+ files_to_upload = get_book_files(dir).select do |file|
182
197
  file.ready?
183
198
  end
184
199
 
185
- upload_screencasts! files_to_upload
200
+ upload_media! dir, files_to_upload
186
201
 
187
- @processed_screencasts += files_to_upload
202
+ @processed_media.push dir
188
203
  end
189
204
 
190
- SCREENCAST_FORMATS = %w{mov ogv mp4 webm}
191
-
192
- def find_screencasts
193
- formats = SCREENCAST_FORMATS * ','
194
- Dir["#{@screencasts_dir}/**/*.{#{formats},zip}"].map do |path|
195
- BookFile.new path
196
- end
205
+ def get_book_files(dir)
206
+ Dir["#{dir}/**/*"].map do |path|
207
+ BookFile.new(path) unless File.directory?(path)
208
+ end.compact
197
209
  end
198
210
 
199
- def upload_screencasts!(files)
211
+ def upload_media!(path, files)
200
212
  return if files.empty?
201
213
 
202
- res = @client.get_screencast_upload_params files
214
+ manifest_path = File.join(path, "manifest.yml")
215
+ manifest = File.exists?(manifest_path) ? File.read(manifest_path) : nil
216
+
217
+ res = @client.get_media_upload_params path, files, manifest
203
218
 
204
219
  if res['upload_params']
205
- screencast_uploader = Softcover::Uploader.new res
206
- screencast_uploader.after_each do |params|
220
+ media_uploader = Softcover::Uploader.new res
221
+ media_uploader.after_each do |params|
207
222
  notify_file_upload params['path']
208
223
  end
209
- screencast_uploader.upload!
224
+ media_uploader.upload!
210
225
  notify_upload_complete
211
226
  else
212
227
  raise 'server error'
@@ -23,10 +23,10 @@ module Softcover
23
23
  $stderr.puts("See http://manual.softcover.io/book/getting_started#sec-build_preview")
24
24
  exit(1)
25
25
  end
26
- range = manifest.pdf_preview_page_range.split('..').map(&:to_i)
26
+ range = manifest.pdf_preview_page_range.split('..').map(&:to_i)
27
27
  cmd = %(yes | #{ghostscript} -dBATCH -sOutputFile="#{output}")
28
28
  cmd += %( -dFirstPage=#{range.first} -dLastPage=#{range.last})
29
- cmd += %( -sDEVICE=pdfwrite "#{input}" > /dev/null)
29
+ cmd += %( -sDEVICE=pdfwrite "#{input}" > /dev/null 2> /dev/null)
30
30
  execute cmd
31
31
  end
32
32
 
data/lib/softcover/cli.rb CHANGED
@@ -73,6 +73,7 @@ module Softcover
73
73
  desc "clean", "Clean unneeded files"
74
74
  def clean
75
75
  rm(Dir.glob('*.aux'))
76
+ rm(Dir.glob(File.join('chapters', '*.aux')))
76
77
  rm(Dir.glob('*.toc'))
77
78
  rm(Dir.glob('*.out'))
78
79
  rm(Dir.glob('*.tmp.*'))
@@ -145,20 +146,20 @@ module Softcover
145
146
  Softcover::Commands::Publisher.publish!(options)
146
147
  end
147
148
 
148
- desc "publish:screencasts", "Publish screencasts"
149
+ desc "publish:media", "Publish media"
149
150
  method_option :daemon, aliases: '-d', force: false,
150
151
  desc: "Run as daemon", type: :boolean
151
152
  method_option :watch, aliases: '-w', type: :boolean,
152
153
  force: false, desc: "Watch a directory to auto upload."
153
154
 
154
155
  # TODO: make screencasts dir .book configurable
155
- define_method "publish:screencasts" do |dir=
156
- Softcover::Book::DEFAULT_SCREENCASTS_DIR|
156
+ define_method "publish:media" do |dir=
157
+ Softcover::Book::DEFAULT_MEDIA_DIR|
157
158
  require 'softcover/commands/publisher'
158
159
 
159
- puts "Publishing screencasts in #{dir}"
160
+ puts "Publishing media bundles..."
160
161
  Softcover::Commands::Publisher.
161
- publish_screencasts! options.merge(dir: dir)
162
+ publish_media! options.merge(dir: dir)
162
163
  end
163
164
 
164
165
  desc "unpublish", "Remove book from Softcover"
@@ -65,9 +65,12 @@ module Softcover
65
65
  delete path_for(:books, slug)
66
66
  end
67
67
 
68
- # ============ Screencasts ===========
69
- def get_screencast_upload_params(files)
70
- JSON post path_for(:books, book.id, :screencasts), files: files
68
+ # ============ Media ===========
69
+ def get_media_upload_params(path, files, manifest=nil)
70
+ JSON post path_for(:books, book.id, :media),
71
+ path: path,
72
+ files: files,
73
+ manifest: manifest
71
74
  # TODO: handle errors
72
75
  end
73
76
 
@@ -32,32 +32,30 @@ module Softcover::Commands::Publisher
32
32
  false
33
33
  end
34
34
 
35
- # TODO: refactor this flow out of file?
36
- def publish_screencasts!(options={})
35
+ def publish_media!(options={})
37
36
  return false unless current_book
38
37
 
39
38
  require 'ruby-progressbar'
40
39
  require 'curb'
41
40
 
42
- current_book.screencasts_dir = options[:dir] ||
43
- Softcover::Book::DEFAULT_SCREENCASTS_DIR
41
+ current_book.media_dir = options[:dir] || Softcover::Book::DEFAULT_MEDIA_DIR
44
42
 
45
43
  @watch = options[:watch]
46
44
 
47
45
  if options[:daemon]
48
46
  pid = fork do
49
- run_publish_screencasts
47
+ run_publish_media
50
48
  end
51
49
 
52
50
  puts "Daemonized, pid: #{pid}"
53
51
  else
54
- run_publish_screencasts
52
+ run_publish_media
55
53
  end
56
54
 
57
55
  current_book
58
56
  end
59
57
 
60
- def run_publish_screencasts
58
+ def run_publish_media
61
59
  if @watch
62
60
  puts "Watching..."
63
61
 
@@ -68,7 +66,7 @@ module Softcover::Commands::Publisher
68
66
 
69
67
  begin
70
68
  loop do
71
- process_screencasts
69
+ process_media
72
70
  sleep 1
73
71
  end
74
72
  rescue Interrupt
@@ -76,19 +74,18 @@ module Softcover::Commands::Publisher
76
74
  exit_with_message
77
75
  end
78
76
  else
79
- process_screencasts
77
+ process_media
80
78
  exit_with_message
81
79
  end
82
80
  end
83
81
 
84
- def process_screencasts
85
- current_book.process_screencasts
82
+ def process_media
83
+ current_book.process_media
86
84
  end
87
85
 
88
86
  def exit_with_message
89
- number = current_book.processed_screencasts.size
90
- screencasts = number == 1 ? 'screencast' : 'screencasts'
91
- puts "Processed #{number} #{screencasts}."
87
+ number = current_book.processed_media.size
88
+ puts "Processed #{number} directory."
92
89
  end
93
90
 
94
91
  def unpublish!(slug=nil)
@@ -9,10 +9,7 @@ prices:
9
9
  Almost 9000 pages of content
10
10
  Includes a free copy of 1st Edition PDF
11
11
  media:
12
- - html
13
- - pdf
14
- - epub
15
- - mobi
12
+ - ebooks
16
13
  price: 3500
17
14
 
18
15
  -
@@ -25,8 +22,8 @@ prices:
25
22
  (QuickTime and Ogg Vorbis)
26
23
  Includes first edition screencasts
27
24
  media:
28
- - html
29
- - screencasts
25
+ - ebooks
26
+ - media/screencasts
30
27
  price: 12500
31
28
 
32
29
  -
@@ -38,11 +35,8 @@ prices:
38
35
  eBook formats for Kindle, Nook, and PDF
39
36
  Read online.
40
37
  media:
41
- - html
42
- - pdf
43
- - epub
44
- - mobi
45
- - screencasts
38
+ - ebooks
39
+ - media/screencasts
46
40
  price: 12500
47
41
  regular_price: 19900
48
42
 
@@ -7,12 +7,6 @@
7
7
  tmp/
8
8
  generated_polytex/
9
9
 
10
- # Generated style, frontmatter, and cache files
11
- pygments.sty
12
- softcover.sty
13
- pygments.css
14
- softcover.css
15
- frontmatter.tex
16
10
  .highlight_cache
17
11
  .softcover-book
18
12
 
@@ -366,8 +366,8 @@ body #book {
366
366
  }
367
367
 
368
368
  #book .highlight pre {
369
- margin: 10px;
370
- font-size: 85%;
369
+ margin: 10px 0 10px 10px;
370
+ font-size: 83%;
371
371
  font-weight: bold;
372
372
  }
373
373
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  % Page size
4
4
  % These settings are optimized for ebooks.
5
- % If you want different settings, override them in custom.sty.
5
+ % If you want different settings, override them in custom_pdf.sty.
6
6
  \setlength{\oddsidemargin}{.25in}
7
7
  \setlength{\evensidemargin}{.25in}
8
8
  \setlength{\textheight}{8in}
@@ -74,7 +74,7 @@
74
74
  \usepackage{latex_styles/upquote}
75
75
 
76
76
  % Filesystem paths
77
- \newcommand{\filepath}[1]{\texttt{\small #1}}
77
+ \newcommand{\filepath}[1]{\textit{\texttt{\small #1}}}
78
78
 
79
79
  % Size-constrained images
80
80
  \newcommand{\image}[1]{\begin{center}\includegraphics[width=\maxwidth{0.95\textwidth}]{#1}\end{center}}
@@ -139,6 +139,9 @@
139
139
  \vskip0.5em}%
140
140
  }
141
141
 
142
+ % Enable the \pbox command for paragraph boxes in tables.
143
+ \usepackage{pbox}
144
+
142
145
  % Define some commonly used Unicode characters.
143
146
  \usepackage{newunicodechar}
144
147
  \newunicodechar{—}{---}
@@ -41,6 +41,7 @@ module Softcover
41
41
  begin
42
42
  bar.send(:title=, "#{path} (#{x} / #{y})")
43
43
  bar.progress += ul_now - last_chunk
44
+ bar.refresh
44
45
  rescue
45
46
  nil
46
47
  end
@@ -1,3 +1,3 @@
1
1
  module Softcover
2
- VERSION = "0.9.10"
2
+ VERSION = "0.9.11"
3
3
  end
data/spec/book_spec.rb CHANGED
@@ -12,9 +12,9 @@ describe Softcover::Book do
12
12
  its(:filenames) { should include "html/chapter-1_fragment.html"}
13
13
  its(:filenames) { should_not include "html/chapter-1.html"}
14
14
 
15
- its(:filenames) { should include "ebooks/test-book.mobi"}
16
- its(:filenames) { should include "ebooks/test-book.epub"}
17
- its(:filenames) { should include "ebooks/test-book.pdf"}
15
+ # its(:filenames) { should include "ebooks/test-book.mobi"}
16
+ # its(:filenames) { should include "ebooks/test-book.epub"}
17
+ # its(:filenames) { should include "ebooks/test-book.pdf"}
18
18
 
19
19
  its(:slug) { should eq "book" }
20
20
  its(:url) { should match /\/books\/(.*?)\/redirect/ }
@@ -73,7 +73,6 @@ describe Softcover::Commands::Generator do
73
73
  it { should match(/\*\.log/) }
74
74
  it { should match(/\*\.toc/) }
75
75
  it { should match(/\*\.tmp\.\*/) }
76
- it { should match(/pygments\.sty/) }
77
76
  it { should match(/html\//) }
78
77
  it { should match(/epub\//) }
79
78
  it { should match(/ebooks\//) }
@@ -98,37 +98,37 @@ describe Softcover::Commands::Publisher do
98
98
  end
99
99
  end
100
100
 
101
- describe "#publish_screencasts" do
101
+ describe "#publish_media" do
102
102
  before do
103
103
  chdir_to_book
104
104
  book.id = 1
105
- stub_screencasts_upload book
105
+ stub_media_upload book
106
106
  end
107
107
 
108
- it "should start with 0 processed_screencasts" do
109
- expect(book.processed_screencasts.length).to eq 0
110
- end
111
-
112
- it "processes screencasts" do
113
- subject.publish_screencasts!
114
- expect(book.processed_screencasts.length).to be > 0
115
- end
116
-
117
- it "daemonizes" do
118
- subject.should_receive(:fork) do |&blk|
119
- blk.call
120
- end
121
- subject.publish_screencasts! daemon: true
122
- expect(book.processed_screencasts.length).to be > 0
123
- end
124
-
125
- it "watches" do
126
- subject.should_receive(:loop) do |&blk|
127
- blk.call
128
- end
129
- subject.publish_screencasts! watch: true
130
- expect(book.processed_screencasts.length).to be > 0
131
- end
108
+ # it "should start with 0 processed_media" do
109
+ # expect(book.processed_media.length).to eq 0
110
+ # end
111
+
112
+ # it "processes media" do
113
+ # subject.publish_media!
114
+ # expect(book.processed_media.length).to be > 0
115
+ # end
116
+
117
+ # it "daemonizes" do
118
+ # subject.should_receive(:fork) do |&blk|
119
+ # blk.call
120
+ # end
121
+ # subject.publish_media! daemon: true
122
+ # expect(book.processed_media.length).to be > 0
123
+ # end
124
+
125
+ # it "watches" do
126
+ # subject.should_receive(:loop) do |&blk|
127
+ # blk.call
128
+ # end
129
+ # subject.publish_media! watch: true
130
+ # expect(book.processed_media.length).to be > 0
131
+ # end
132
132
 
133
133
  end
134
134
  end
@@ -122,13 +122,13 @@ module WebmockHelpers
122
122
  to_return(:status => 200, :body => "", :headers => {})
123
123
  end
124
124
 
125
- def stub_screencasts_upload(book)
125
+ def stub_media_upload(book)
126
126
  stub_s3_post
127
127
  stub_create_book(book)
128
128
 
129
129
  files = book.find_screencasts
130
130
  stub_request(:post,
131
- "#{api_base_url}/books/#{book.id}/screencasts").
131
+ "#{api_base_url}/books/#{book.id}/media").
132
132
  with(:body => {files: files }.to_json,
133
133
  :headers => headers).
134
134
  to_return(:status => 200, :body => {
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: softcover
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.10
4
+ version: 0.9.11
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michael Hartl
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-03-25 00:00:00.000000000 Z
12
+ date: 2014-04-26 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: polytexnic
@@ -1003,7 +1003,7 @@ files:
1003
1003
  - lib/softcover/template/latex_styles/language_customization.sty
1004
1004
  - lib/softcover/template/latex_styles/softcover.sty
1005
1005
  - lib/softcover/template/latex_styles/upquote.sty
1006
- - lib/softcover/template/screencasts/.gitkeep
1006
+ - lib/softcover/template/media/screencasts/.gitkeep
1007
1007
  - lib/softcover/uploader.rb
1008
1008
  - lib/softcover/utils.rb
1009
1009
  - lib/softcover/version.rb