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 +4 -4
- data/.gitignore +1 -0
- data/.rake_tasks~ +5 -0
- data/README.md +45 -12
- data/Rakefile +3 -1
- data/lib/pdfinfo.rb +56 -12
- data/lib/pdfinfo/version.rb +1 -1
- data/lib/tasks/generate_pdf.rake +56 -0
- data/pdfinfo.gemspec +2 -1
- data/spec/fixtures/shell_responses/encrypted.txt +15 -0
- data/spec/fixtures/shell_responses/test.txt +15 -0
- data/spec/pdfinfo_spec.rb +208 -26
- metadata +23 -7
- data/spec/fixtures/shell_response.txt +0 -10
- data/spec/fixtures/test.pdf +0 -127
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c353a570a0806dfe590c8f5f2f13397a065030b0
|
4
|
+
data.tar.gz: 9e09d7118c9006868b586ddce96738ea88a51af1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 777a7cd47cea0d6ebc9d077d5dd3c32f7e89e28de7d11b321d686b1491a04d5c47e5488c14816dd631513d979cb429076c1cb99506a2e356352e6922af5e3ff2
|
7
|
+
data.tar.gz: 13b389f1cdbf9fafab32c811b80faefc7003315e3cb13f5faeb2463decc1bcd4350faf80647afbc2c31698a361d53d73f0d865aca4d0c14d776998586124692d
|
data/.gitignore
CHANGED
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
|
30
|
-
|
31
|
-
pdfinfo.
|
32
|
-
pdfinfo.
|
33
|
-
pdfinfo.
|
34
|
-
pdfinfo.
|
35
|
-
|
36
|
-
pdfinfo.
|
37
|
-
pdfinfo.
|
38
|
-
pdfinfo.
|
39
|
-
pdfinfo.
|
40
|
-
pdfinfo.
|
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
data/lib/pdfinfo.rb
CHANGED
@@ -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 :
|
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
|
-
|
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
|
-
@
|
33
|
-
@
|
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
|
-
|
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(
|
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(&:
|
103
|
+
str.match(DIMENSIONS_REGEXP).captures.map(&:to_f)
|
60
104
|
end
|
61
105
|
end
|
data/lib/pdfinfo/version.rb
CHANGED
@@ -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
|
data/pdfinfo.gemspec
CHANGED
@@ -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 "
|
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
|
data/spec/pdfinfo_spec.rb
CHANGED
@@ -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(:
|
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
|
-
|
9
|
-
|
10
|
-
|
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(
|
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('
|
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) {
|
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('
|
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) {
|
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) {
|
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) {
|
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(
|
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) {
|
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) {
|
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 '
|
82
|
-
|
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(
|
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(
|
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
|
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-
|
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:
|
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/
|
74
|
-
- spec/fixtures/test.
|
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/
|
103
|
-
- spec/fixtures/test.
|
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
|
data/spec/fixtures/test.pdf
DELETED
@@ -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
|