pdfinfo 0.0.2 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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