pdfinfo 0.0.2 → 1.0.0

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: 4aaac914cb686f9cdd99edfbc378b8fbb4f91ef1
4
- data.tar.gz: 404f4ebdb111f48bd5b538b03f1cc08a870d1dde
3
+ metadata.gz: c353a570a0806dfe590c8f5f2f13397a065030b0
4
+ data.tar.gz: 9e09d7118c9006868b586ddce96738ea88a51af1
5
5
  SHA512:
6
- metadata.gz: 0c4b285a441417f340030ed932a18aabc294b3784c0d358165dcff2d220b46663b98a503c8c8cfa5b1a467edef02e1882cf8db8acd0a5c379fd9e3ffca5acf40
7
- data.tar.gz: 10956090e1a0ca786a85470fe43928bac9a83bad46cb8d1dc61c88e78c90c29be9fee3248b376d727779eec160d2991ba3acf7b5100bd6760cf142f536de9495
6
+ metadata.gz: 777a7cd47cea0d6ebc9d077d5dd3c32f7e89e28de7d11b321d686b1491a04d5c47e5488c14816dd631513d979cb429076c1cb99506a2e356352e6922af5e3ff2
7
+ data.tar.gz: 13b389f1cdbf9fafab32c811b80faefc7003315e3cb13f5faeb2463decc1bcd4350faf80647afbc2c31698a361d53d73f0d865aca4d0c14d776998586124692d
data/.gitignore CHANGED
@@ -21,3 +21,4 @@ tmp
21
21
  *.a
22
22
  mkmf.log
23
23
  .idea
24
+ spec/fixtures/pdfs/*
@@ -0,0 +1,5 @@
1
+ build
2
+ generate_pdf
3
+ install
4
+ release
5
+ spec
data/README.md CHANGED
@@ -1,6 +1,7 @@
1
1
  # Pdfinfo
2
2
 
3
3
  Simple ruby wrapper around the pdfinfo command
4
+ NOTE: This gem is only intended to provide quick access to the metadata returned by the pdfinfo command without flags
4
5
 
5
6
  ## Depdendecies
6
7
 
@@ -26,18 +27,35 @@ Or install it yourself as:
26
27
 
27
28
 
28
29
  ```ruby
29
- pdfinfo = Pdfinfo.new("path/to/file.pdf")
30
-
31
- pdfinfo.creator #=> "Creator Name" # or nil
32
- pdfinfo.producer #=> "Producer Name" # or nil
33
- pdfinfo.form #=> "none"
34
- pdfinfo.page_count #=> 3
35
- pdfinfo.width #=> 612
36
- pdfinfo.height #=> 792
37
- pdfinfo.size #=> 1521 # file size in bytes
38
- pdfinfo.pdf_version #=> "1.3"
39
- pdfinfo.encrypted? #=> false # or true
40
- pdfinfo.tagged? #=> false # or true
30
+ pdfinfo.title #=> "Title" # or nil
31
+ pdfinfo.subject #=> "Subject" # or nil
32
+ pdfinfo.keywords #=> ["Keyword1", "Keyword2"] # or nil
33
+ pdfinfo.author #=> "Author Name" # or nil
34
+ pdfinfo.creator #=> "Creator Name" # or nil
35
+ pdfinfo.producer #=> "Producer Name" # or nil
36
+ ddfinfo.creation_date #=> 2014-10-26 20:50:45 -0700 # Time object
37
+ pdfinfo.form #=> "none"
38
+ pdfinfo.page_count #=> 3
39
+ pdfinfo.width #=> 612
40
+ pdfinfo.height #=> 792
41
+ pdfinfo.size #=> 1521 # file size in bytes
42
+ pdfinfo.pdf_version #=> "1.3"
43
+ pdfinfo.encrypted? #=> false # or true
44
+ pdfinfo.usage_rights #=> {print: true, copy: true, change: true, add_notes: true}
45
+ pdfinfo.printable? #=> true # or false
46
+ pdfinfo.copyable? #=> true # or false
47
+ pdfinfo.changeable? #=> true # or false
48
+ pdfinfo.modifiable? #=> true # or false. alias for #changeable?
49
+ pdfinfo.annotatable? #=> true # or false
50
+ pdfinfo.tagged? #=> false # or true
51
+ ```
52
+ For encrypted files with a password you can pass in the user or owner password as options
53
+
54
+ ```ruby
55
+ pdfinfo = Pdfinfo.new("path/to/encrypted.pdf", user_password: 'foo')
56
+ # pdfinfo = Pdfinfo.new("path/to/encrypted.pdf", owner_password: 'foo')
57
+ pdfinfo.encrypted? #=> true
58
+ pdfinfo.usage_rights #=> {print: false, copy: false, change: false, add_notes: false}
41
59
  ```
42
60
 
43
61
  You can directly set the location of the executable if its not located in your environment $PATH or you just want to point to a different location.
@@ -47,6 +65,16 @@ Pdfinfo.pdfinfo_command = '/another/bin/path/pdfinfo'
47
65
  Pdfinfo.pdfinfo_command #=> '/another/bin/path/pdfinfo'
48
66
  ```
49
67
 
68
+ ## Running specs
69
+
70
+ generate pdf fixtures by first running
71
+
72
+ $ rake generate_fixtures
73
+
74
+ Then run specs by running
75
+
76
+ $ rake
77
+
50
78
  ## Contributing
51
79
 
52
80
  1. Fork it ( https://github.com/[my-github-username]/pdfinfo/fork )
@@ -54,3 +82,8 @@ Pdfinfo.pdfinfo_command #=> '/another/bin/path/pdfinfo'
54
82
  3. Commit your changes (`git commit -am 'Add some feature'`)
55
83
  4. Push to the branch (`git push origin my-new-feature`)
56
84
  5. Create a new Pull Request
85
+
86
+ ## TODO
87
+ * Error handling
88
+ * type coersion is getting messy in initialize. refactor.
89
+ * Add #to_hash/#to_h/#as_json method to output all metadata as a hash
data/Rakefile CHANGED
@@ -3,4 +3,6 @@ require "bundler/gem_tasks"
3
3
  require 'rspec/core/rake_task'
4
4
  RSpec::Core::RakeTask.new(:spec)
5
5
 
6
- task :default => :spec
6
+ task :default => :spec
7
+
8
+ load File.expand_path("../lib/tasks/generate_pdf.rake", __FILE__)
@@ -1,10 +1,15 @@
1
1
  require 'open3'
2
- require 'pathname'
3
2
 
4
3
  class Pdfinfo
5
- DIMENSIONS_REGEXP = /(\d+) x (\d+)/
4
+ DIMENSIONS_REGEXP = /([\d\.]+) x ([\d\.]+)/
6
5
 
7
- attr_reader :creator,
6
+ attr_reader :title,
7
+ :subject,
8
+ :keywords,
9
+ :author,
10
+ :creator,
11
+ :creation_date,
12
+ :usage_rights,
8
13
  :producer,
9
14
  :form,
10
15
  :page_count,
@@ -13,8 +18,15 @@ class Pdfinfo
13
18
  :file_size,
14
19
  :pdf_version
15
20
 
16
- def self.exec(file_path)
17
- stdout, stderr, status = Open3.capture2e("#{pdfinfo_command} #{file_path}")
21
+ def self.exec(file_path, opts = {})
22
+ flags = []
23
+ if opts[:owner_password]
24
+ flags << ['-opw', opts[:owner_password]]
25
+ elsif opts[:user_password]
26
+ flags << ['-upw', opts[:user_password]]
27
+ end
28
+
29
+ stdout, stderr, status = Open3.capture2e("#{pdfinfo_command} #{flags.join(" ")} #{file_path}")
18
30
  stdout.chomp
19
31
  end
20
32
 
@@ -26,15 +38,31 @@ class Pdfinfo
26
38
  @pdfinfo_command = cmd
27
39
  end
28
40
 
29
- def initialize(source_path)
30
- info_hash = parse_shell_response(Pdfinfo.exec(source_path))
41
+ def initialize(source_path, opts = {})
42
+ info_hash = parse_shell_response(Pdfinfo.exec(source_path, opts))
31
43
 
32
- @creator = info_hash['Creator']
33
- @producer = info_hash['Producer']
44
+ @title = info_hash['Title'].empty? ? nil : info_hash['Title']
45
+ @subject = info_hash['Subject'].empty? ? nil : info_hash['Subject']
46
+ @keywords = info_hash['Keywords'].empty? ? [] : info_hash['Keywords'].split(/\s/)
47
+ @author = info_hash['Author'].empty? ? nil : info_hash['Author']
48
+ @creator = info_hash['Creator'].empty? ? nil : info_hash['Creator']
49
+ @producer = info_hash['Producer'].empty? ? nil : info_hash['Producer']
50
+ @creation_date = info_hash['CreationDate'].empty? ? nil : Time.parse(info_hash['CreationDate'])
34
51
  @tagged = !!(info_hash['Tagged'] =~ /yes/)
35
52
  @form = info_hash['Form']
36
53
  @page_count = info_hash['Pages'].to_i
37
54
  @encrypted = !!(info_hash['Encrypted'] =~ /yes/)
55
+
56
+ raw_usage_rights = Hash[info_hash['Encrypted'].scan(/(\w+):(\w+)/)]
57
+ booleanize_usage_right = lambda {|val| !(raw_usage_rights[val] == 'no') }
58
+
59
+ @usage_rights = {}.tap do |ur|
60
+ ur[:print] = booleanize_usage_right.call('print')
61
+ ur[:copy] = booleanize_usage_right.call('copy')
62
+ ur[:change] = booleanize_usage_right.call('change')
63
+ ur[:add_notes] = booleanize_usage_right.call('addNotes')
64
+ end
65
+
38
66
  @width, @height = extract_page_dimensions(info_hash['Page size'])
39
67
  @file_size = info_hash['File size'].to_i
40
68
  @pdf_version = info_hash['PDF version']
@@ -48,14 +76,30 @@ class Pdfinfo
48
76
  @encrypted
49
77
  end
50
78
 
51
- private
79
+ def printable?
80
+ @usage_rights[:print]
81
+ end
52
82
 
83
+ def copyable?
84
+ @usage_rights[:copy]
85
+ end
86
+
87
+ def changeable?
88
+ @usage_rights[:change]
89
+ end
90
+ alias modifiable? changeable?
91
+
92
+ def annotatable?
93
+ @usage_rights[:add_notes]
94
+ end
95
+
96
+ private
53
97
  def parse_shell_response(response_str)
54
- Hash[response_str.split(/\n/).map {|kv| kv.split(/:\s+/) }]
98
+ Hash[response_str.split(/\n/).map {|kv| kv.split(/:/, 2).map(&:strip) }]
55
99
  end
56
100
 
57
101
  def extract_page_dimensions(str)
58
102
  return unless str
59
- str.match(DIMENSIONS_REGEXP).captures.map(&:to_i)
103
+ str.match(DIMENSIONS_REGEXP).captures.map(&:to_f)
60
104
  end
61
105
  end
@@ -1,3 +1,3 @@
1
1
  class Pdfinfo
2
- VERSION = '0.0.2'
2
+ VERSION = '1.0.0'
3
3
  end
@@ -0,0 +1,56 @@
1
+ require 'time'
2
+
3
+ desc 'generates pdf for testing'
4
+ task :generate_fixtures do
5
+ class PdfGenerator
6
+ ROOT_DIR = File.expand_path("../../..", __FILE__)
7
+ METADATA_OPTIONS = {
8
+ Title: "Pdfinfo Title",
9
+ Author: "Pdfinfo Author",
10
+ Subject: "Pdfinfo Subject",
11
+ Keywords: "Keyword1 Keyword2",
12
+ Creator: "Pdfinfo Creator",
13
+ Producer: "Pdfinfo Producer",
14
+ CreationDate: Time.parse("2014-10-26 18:23:25 -0700")
15
+ }
16
+ ENCRYPTION_PERMISSIONS = {
17
+ print_document: false,
18
+ modify_contents: false,
19
+ copy_contents: false,
20
+ modify_annotations: false
21
+ }
22
+ ENCRYPTION_OPTIONS = {
23
+ user_password: 'foo',
24
+ owner_password: 'bar',
25
+ permissions: ENCRYPTION_PERMISSIONS
26
+ }
27
+
28
+ def self.generate(dest_path, opts = {})
29
+ new(opts).write_to(dest_path)
30
+ end
31
+
32
+ def initialize(opts = {})
33
+ @encryption = opts[:encryption]
34
+ end
35
+
36
+ # @param [String] dest_path path relative to gem root directory to write file to
37
+ def write_to(dest_path)
38
+ require 'prawn'
39
+
40
+ dest_path = File.join(ROOT_DIR, dest_path)
41
+
42
+ Prawn::Document.generate(dest_path, skip_page_creation: true, info: METADATA_OPTIONS, page_size: 'A4') do |pdf|
43
+ 1.upto(5) do |n|
44
+ pdf.start_new_page
45
+ pdf.text("Page #{n}")
46
+ end
47
+
48
+ pdf.encrypt_document(ENCRYPTION_OPTIONS) if @encryption
49
+ end
50
+ end
51
+ end
52
+
53
+
54
+ PdfGenerator.generate("spec/fixtures/pdfs/test.pdf")
55
+ PdfGenerator.generate("spec/fixtures/pdfs/encrypted.pdf", encryption: true)
56
+ end
@@ -18,6 +18,7 @@ Gem::Specification.new do |spec|
18
18
  spec.require_paths = ["lib"]
19
19
 
20
20
  spec.add_development_dependency "bundler", "~> 1.6"
21
- spec.add_development_dependency "rspec"
21
+ spec.add_development_dependency "prawn"
22
+ spec.add_development_dependency "rspec", '~> 3.1.0'
22
23
  spec.add_development_dependency "rake"
23
24
  end
@@ -0,0 +1,15 @@
1
+ Title: Pdfinfo Title
2
+ Subject: Pdfinfo Subject
3
+ Keywords: Keyword1 Keyword2
4
+ Author: Pdfinfo Author
5
+ Creator: Pdfinfo Creator
6
+ Producer: Pdfinfo Producer
7
+ CreationDate: Sun Oct 26 18:23:25 2014
8
+ Tagged: no
9
+ Form: none
10
+ Pages: 5
11
+ Encrypted: yes (print:no copy:no change:no addNotes:no)
12
+ Page size: 595.28 x 841.89 pts (A4) (rotated 0 degrees)
13
+ File size: 2861 bytes
14
+ Optimized: no
15
+ PDF version: 1.3
@@ -0,0 +1,15 @@
1
+ Title: Pdfinfo Title
2
+ Subject: Pdfinfo Subject
3
+ Keywords: Keyword1 Keyword2
4
+ Author: Pdfinfo Author
5
+ Creator: Pdfinfo Creator
6
+ Producer: Pdfinfo Producer
7
+ CreationDate: Sun Oct 26 18:23:25 2014
8
+ Tagged: no
9
+ Form: none
10
+ Pages: 5
11
+ Encrypted: no
12
+ Page size: 595.28 x 841.89 pts (A4) (rotated 0 degrees)
13
+ File size: 2867 bytes
14
+ Optimized: no
15
+ PDF version: 1.3
@@ -1,20 +1,27 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  RSpec.describe Pdfinfo do
4
- let(:pdf_path) { fixture_path('test.pdf') }
4
+ let(:pdf_path) { fixture_path('pdfs/test.pdf') }
5
5
  let(:pdfinfo) { described_class.new(pdf_path) }
6
- let(:mock_response) { File.read(fixture_path('shell_response.txt')).chomp }
6
+ let(:encrypted_response) { File.read(fixture_path('shell_responses/encrypted.txt')).chomp }
7
+ let(:unencrypted_response) { File.read(fixture_path('shell_responses/test.txt')).chomp }
8
+ let(:mock_response) { unencrypted_response }
7
9
 
8
- before(:suite) do
9
- # validate that our mock response matches the real response
10
- expect(described_class.exec(pdf_path)).to eq(mock_response)
10
+
11
+ def modified_response(response, key, new_value = '')
12
+ response.sub(/(?<=#{key}:)(.+)$/, new_value)
13
+ end
14
+
15
+ specify "mock responses match" do
16
+ expect(`pdfinfo -upw foo #{fixture_path('pdfs/encrypted.pdf')}`.chomp).to eq(encrypted_response)
17
+ expect(`pdfinfo #{fixture_path('pdfs/test.pdf')}`.chomp).to eq(unencrypted_response)
11
18
  end
12
19
 
13
20
  before(:each) do
14
- allow(described_class).to receive(:exec).and_return(mock_response)
21
+ allow(Open3).to receive(:capture2e).and_return([mock_response, nil, nil])
15
22
  end
16
23
 
17
- describe 'pdfinfo_command' do
24
+ describe '.pdfinfo_command' do
18
25
  it "falls back to pdfinfo" do
19
26
  Pdfinfo.pdfinfo_command = nil
20
27
  expect(Pdfinfo.pdfinfo_command).to eq('pdfinfo')
@@ -26,33 +33,128 @@ RSpec.describe Pdfinfo do
26
33
  end
27
34
  end
28
35
 
36
+ describe '.exec' do
37
+ context 'with no options given' do
38
+ it 'runs the pdfinfo command without flags' do
39
+ expect(Open3).to receive(:capture2e).with("pdfinfo path/to/file.pdf")
40
+ Pdfinfo.new("path/to/file.pdf")
41
+ end
42
+ end
43
+
44
+ context "passing in :user_password" do
45
+ it 'runs the pdfinfo command passing the user password flag' do
46
+ expect(Open3).to receive(:capture2e).with("pdfinfo -upw foo path/to/file.pdf")
47
+ Pdfinfo.new("path/to/file.pdf", user_password: 'foo')
48
+ end
49
+ end
50
+ context 'passing in :owner_password' do
51
+ it 'runs the pdfinfo command passing the user password flag' do
52
+ expect(Open3).to receive(:capture2e).with("pdfinfo -opw bar path/to/file.pdf")
53
+ Pdfinfo.new("path/to/file.pdf", owner_password: 'bar')
54
+ end
55
+ end
56
+ end
57
+
58
+ describe '#title' do
59
+ context 'when given a title' do
60
+ it 'returns the title' do
61
+ expect(pdfinfo.title).to eq('Pdfinfo Title')
62
+ end
63
+ end
64
+ context 'when title is not present' do
65
+ let(:mock_response) { modified_response(unencrypted_response, 'Title', '') }
66
+ it 'returns nil' do
67
+ expect(pdfinfo.title).to be_nil
68
+ end
69
+ end
70
+ end
71
+
72
+ describe '#subject' do
73
+ context 'when given a subject' do
74
+ it 'returns the subject' do
75
+ expect(pdfinfo.subject).to eq('Pdfinfo Subject')
76
+ end
77
+ end
78
+ context 'when title is not present' do
79
+ let(:mock_response) { modified_response(unencrypted_response, 'Subject', '') }
80
+ it 'returns nil' do
81
+ expect(pdfinfo.subject).to be_nil
82
+ end
83
+ end
84
+ end
85
+
86
+ describe '#keywords' do
87
+ context 'when given keywords' do
88
+ it 'returns the keywords' do
89
+ expect(pdfinfo.keywords).to eq(['Keyword1', 'Keyword2'])
90
+ end
91
+ end
92
+ context 'when keywords is not present' do
93
+ let(:mock_response) { modified_response(unencrypted_response, 'Keywords', '') }
94
+ it 'returns an empty array' do
95
+ expect(pdfinfo.keywords).to eq([])
96
+ end
97
+ end
98
+ end
99
+
100
+ describe '#author' do
101
+ context 'when given an author' do
102
+ it 'returns the author' do
103
+ expect(pdfinfo.author).to eq('Pdfinfo Author')
104
+ end
105
+ end
106
+ context 'when author is not present' do
107
+ let(:mock_response) { modified_response(unencrypted_response, 'Author', '') }
108
+ it 'returns nil' do
109
+ expect(pdfinfo.author).to be_nil
110
+ end
111
+ end
112
+ end
113
+
114
+ describe '#creation_date' do
115
+ context 'when given an author' do
116
+ it 'returns a time object' do
117
+ expect(pdfinfo.creation_date).to be_an_instance_of(Time)
118
+ end
119
+ it 'returns the time correctly parsed' do
120
+ expect(pdfinfo.creation_date).to eq(Time.parse("2014-10-26 18:23:25 -0700"))
121
+ end
122
+ end
123
+ context 'when creation date is not present' do
124
+ let(:mock_response) { modified_response(unencrypted_response, 'CreationDate', '') }
125
+ it 'returns nil' do
126
+ expect(pdfinfo.creation_date).to be_nil
127
+ end
128
+ end
129
+ end
130
+
29
131
  describe '#creator' do
30
132
  context 'when given a creator' do
31
- it { expect(pdfinfo.creator).to eq('Prawn') }
133
+ it { expect(pdfinfo.creator).to eq('Pdfinfo Creator') }
32
134
  end
33
135
  context 'when creator is not present' do
34
- let(:mock_response) { "Creator: \n" }
136
+ let(:mock_response) { modified_response(unencrypted_response, 'Creator', '') }
35
137
  it { expect(pdfinfo.creator).to be_nil }
36
138
  end
37
139
  end
38
140
 
39
141
  describe '#producer' do
40
142
  context 'when given a creator' do
41
- it { expect(pdfinfo.producer).to eq('Prawn') }
143
+ it { expect(pdfinfo.producer).to eq('Pdfinfo Producer') }
42
144
  end
43
145
  context 'when creator is not present' do
44
- let(:mock_response) { "Producer: \n" }
146
+ let(:mock_response) { modified_response(unencrypted_response, 'Producer', '') }
45
147
  it { expect(pdfinfo.producer).to be_nil }
46
148
  end
47
149
  end
48
150
 
49
- describe 'tagged?' do
151
+ describe '#tagged?' do
50
152
  context 'when tagged' do
51
- let(:mock_response) { "Tagged: yes" }
153
+ let(:mock_response) { modified_response(unencrypted_response, 'Tagged', 'yes') }
52
154
  it { expect(pdfinfo.tagged?).to eq(true) }
53
155
  end
54
156
  context 'when not tagged' do
55
- let(:mock_response) { "Tagged: no" }
157
+ let(:mock_response) { modified_response(unencrypted_response, 'Tagged', 'no') }
56
158
  it { expect(pdfinfo.tagged?).to eq(false) }
57
159
  end
58
160
  end
@@ -61,38 +163,118 @@ RSpec.describe Pdfinfo do
61
163
  it { expect(pdfinfo.form).to eq('none') }
62
164
  end
63
165
 
64
- describe 'page_count' do
166
+ describe '#page_count' do
65
167
  it 'returns a fixnum value of the number of pages' do
66
- expect(pdfinfo.page_count).to eq(3)
168
+ expect(pdfinfo.page_count).to eq(5)
67
169
  end
68
170
  end
69
171
 
70
- describe 'encrypted?' do
172
+ describe '#encrypted?' do
71
173
  context 'given encrypted pdf' do
72
- let(:mock_response) { "Encrypted: yes\n" }
174
+ let(:mock_response) { encrypted_response }
73
175
  it { expect(pdfinfo.encrypted?).to eq(true) }
74
176
  end
75
177
  context 'given unencrypted pdf' do
76
- let(:mock_response) { 'Encrypted: no' }
178
+ let(:mock_response) { unencrypted_response }
77
179
  it { expect(pdfinfo.encrypted?).to eq(false) }
78
180
  end
79
181
  end
80
182
 
81
- describe 'width' do
82
- it { expect(pdfinfo.width).to eq(612) }
183
+ describe '#usage_rights' do
184
+ context 'given encrypted pdf (all flags off)' do
185
+ let(:mock_response) { encrypted_response }
186
+ it 'returns a permissions hash' do
187
+ expect(pdfinfo.usage_rights).to eq({
188
+ print: false,
189
+ copy: false,
190
+ change: false,
191
+ add_notes: false
192
+ })
193
+ end
194
+ end
195
+ context 'given unencrypted pdf' do
196
+ let(:mock_response) { unencrypted_response }
197
+ it 'returns a permissions hash' do
198
+ expect(pdfinfo.usage_rights).to eq({
199
+ print: true,
200
+ copy: true,
201
+ change: true,
202
+ add_notes: true
203
+ })
204
+ end
205
+ end
206
+ end
207
+
208
+ describe '#printable?' do
209
+ context 'given a pdf that is printable' do
210
+ let(:mock_response) { unencrypted_response }
211
+ it { expect(pdfinfo.printable?).to eq(true) }
212
+ end
213
+ context 'given a pdf that is not printable' do
214
+ let(:mock_response) { encrypted_response }
215
+ it { expect(pdfinfo.printable?).to eq(false) }
216
+ end
217
+ end
218
+
219
+ describe '#copyable?' do
220
+ context 'given a pdf that is copyable' do
221
+ let(:mock_response) { unencrypted_response }
222
+ it { expect(pdfinfo.copyable?).to eq(true) }
223
+ end
224
+ context 'given a pdf that is not copyable' do
225
+ let(:mock_response) { encrypted_response }
226
+ it { expect(pdfinfo.copyable?).to eq(false) }
227
+ end
228
+ end
229
+
230
+ describe '#changeable?' do
231
+ context 'given a pdf that is changeable' do
232
+ let(:mock_response) { unencrypted_response }
233
+ it { expect(pdfinfo.changeable?).to eq(true) }
234
+ end
235
+ context 'given a pdf that is not changeable' do
236
+ let(:mock_response) { encrypted_response }
237
+ it { expect(pdfinfo.changeable?).to eq(false) }
238
+ end
239
+ end
240
+
241
+ describe "#modifiable? (alias to changeable?)" do
242
+ context 'given a pdf that is changeable' do
243
+ let(:mock_response) { unencrypted_response }
244
+ it { expect(pdfinfo.modifiable?).to eq(true) }
245
+ end
246
+ context 'given a pdf that is not changeable' do
247
+ let(:mock_response) { encrypted_response }
248
+ it { expect(pdfinfo.modifiable?).to eq(false) }
249
+ end
250
+ end
251
+
252
+ describe '#annotatable?' do
253
+ context 'given a pdf that is annotatable' do
254
+ let(:mock_response) { unencrypted_response }
255
+ it { expect(pdfinfo.annotatable?).to eq(true) }
256
+ end
257
+ context 'given a pdf that is not annotatable' do
258
+ let(:mock_response) { encrypted_response }
259
+ it { expect(pdfinfo.annotatable?).to eq(false) }
260
+ end
261
+ end
262
+
263
+ describe '#width' do
264
+ it { expect(pdfinfo.width).to eq(595.28) }
83
265
  end
84
266
 
85
- describe 'height' do
86
- it { expect(pdfinfo.height).to eq(792) }
267
+ describe '#height' do
268
+ it { expect(pdfinfo.height).to eq(841.89) }
87
269
  end
88
270
 
89
- describe 'size' do
271
+ describe '#size' do
90
272
  it 'returns a fixnm value for the file size in bytes' do
91
- expect(pdfinfo.file_size).to eq(1521)
273
+ expect(pdfinfo.file_size).to eq(2867)
92
274
  end
93
275
  end
94
276
 
95
- describe 'pdf_version' do
277
+ describe '#pdf_version' do
96
278
  it 'returns a string value for the PDF spec version' do
97
279
  expect(pdfinfo.pdf_version).to eq('1.3')
98
280
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pdfinfo
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ryan Venegas
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-10-25 00:00:00.000000000 Z
11
+ date: 2014-10-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -25,7 +25,7 @@ dependencies:
25
25
  - !ruby/object:Gem::Version
26
26
  version: '1.6'
27
27
  - !ruby/object:Gem::Dependency
28
- name: rspec
28
+ name: prawn
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - ">="
@@ -38,6 +38,20 @@ dependencies:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 3.1.0
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 3.1.0
41
55
  - !ruby/object:Gem::Dependency
42
56
  name: rake
43
57
  requirement: !ruby/object:Gem::Requirement
@@ -60,6 +74,7 @@ extensions: []
60
74
  extra_rdoc_files: []
61
75
  files:
62
76
  - ".gitignore"
77
+ - ".rake_tasks~"
63
78
  - ".rspec"
64
79
  - ".ruby-gemset"
65
80
  - ".ruby-version"
@@ -69,9 +84,10 @@ files:
69
84
  - Rakefile
70
85
  - lib/pdfinfo.rb
71
86
  - lib/pdfinfo/version.rb
87
+ - lib/tasks/generate_pdf.rake
72
88
  - pdfinfo.gemspec
73
- - spec/fixtures/shell_response.txt
74
- - spec/fixtures/test.pdf
89
+ - spec/fixtures/shell_responses/encrypted.txt
90
+ - spec/fixtures/shell_responses/test.txt
75
91
  - spec/pdfinfo_spec.rb
76
92
  - spec/spec_helper.rb
77
93
  homepage: ''
@@ -99,7 +115,7 @@ signing_key:
99
115
  specification_version: 4
100
116
  summary: Simple ruby wrapper around the pdfinfo executable
101
117
  test_files:
102
- - spec/fixtures/shell_response.txt
103
- - spec/fixtures/test.pdf
118
+ - spec/fixtures/shell_responses/encrypted.txt
119
+ - spec/fixtures/shell_responses/test.txt
104
120
  - spec/pdfinfo_spec.rb
105
121
  - spec/spec_helper.rb
@@ -1,10 +0,0 @@
1
- Creator: Prawn
2
- Producer: Prawn
3
- Tagged: no
4
- Form: none
5
- Pages: 3
6
- Encrypted: no
7
- Page size: 612 x 792 pts (letter) (rotated 0 degrees)
8
- File size: 1521 bytes
9
- Optimized: no
10
- PDF version: 1.3
@@ -1,127 +0,0 @@
1
- %PDF-1.3
2
- %����
3
- 1 0 obj
4
- << /Creator <feff0050007200610077006e>
5
- /Producer <feff0050007200610077006e>
6
- >>
7
- endobj
8
- 2 0 obj
9
- << /Type /Catalog
10
- /Pages 3 0 R
11
- >>
12
- endobj
13
- 3 0 obj
14
- << /Type /Pages
15
- /Count 3
16
- /Kids [5 0 R 8 0 R 10 0 R]
17
- >>
18
- endobj
19
- 4 0 obj
20
- << /Length 71
21
- >>
22
- stream
23
- q
24
-
25
- BT
26
- 36 747.384 Td
27
- /F1.0 12 Tf
28
- [<50> 120 <41> 30 <47452031>] TJ
29
- ET
30
-
31
- Q
32
-
33
- endstream
34
- endobj
35
- 5 0 obj
36
- << /Type /Page
37
- /Parent 3 0 R
38
- /MediaBox [0 0 612.0 792.0]
39
- /Contents 4 0 R
40
- /Resources << /ProcSet [/PDF /Text /ImageB /ImageC /ImageI]
41
- /Font << /F1.0 6 0 R
42
- >>
43
- >>
44
- >>
45
- endobj
46
- 6 0 obj
47
- << /Type /Font
48
- /Subtype /Type1
49
- /BaseFont /Helvetica
50
- /Encoding /WinAnsiEncoding
51
- >>
52
- endobj
53
- 7 0 obj
54
- << /Length 71
55
- >>
56
- stream
57
- q
58
-
59
- BT
60
- 36 747.384 Td
61
- /F1.0 12 Tf
62
- [<50> 120 <41> 30 <47452032>] TJ
63
- ET
64
-
65
- Q
66
-
67
- endstream
68
- endobj
69
- 8 0 obj
70
- << /Type /Page
71
- /Parent 3 0 R
72
- /MediaBox [0 0 612.0 792.0]
73
- /Contents 7 0 R
74
- /Resources << /ProcSet [/PDF /Text /ImageB /ImageC /ImageI]
75
- /Font << /F1.0 6 0 R
76
- >>
77
- >>
78
- >>
79
- endobj
80
- 9 0 obj
81
- << /Length 71
82
- >>
83
- stream
84
- q
85
-
86
- BT
87
- 36 747.384 Td
88
- /F1.0 12 Tf
89
- [<50> 120 <41> 30 <47452033>] TJ
90
- ET
91
-
92
- Q
93
-
94
- endstream
95
- endobj
96
- 10 0 obj
97
- << /Type /Page
98
- /Parent 3 0 R
99
- /MediaBox [0 0 612.0 792.0]
100
- /Contents 9 0 R
101
- /Resources << /ProcSet [/PDF /Text /ImageB /ImageC /ImageI]
102
- /Font << /F1.0 6 0 R
103
- >>
104
- >>
105
- >>
106
- endobj
107
- xref
108
- 0 11
109
- 0000000000 65535 f
110
- 0000000015 00000 n
111
- 0000000109 00000 n
112
- 0000000158 00000 n
113
- 0000000228 00000 n
114
- 0000000349 00000 n
115
- 0000000527 00000 n
116
- 0000000624 00000 n
117
- 0000000745 00000 n
118
- 0000000923 00000 n
119
- 0000001044 00000 n
120
- trailer
121
- << /Size 11
122
- /Root 2 0 R
123
- /Info 1 0 R
124
- >>
125
- startxref
126
- 1223
127
- %%EOF