ffnpdf 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +7 -0
- data/.rspec +2 -0
- data/Gemfile +4 -0
- data/README.md +65 -0
- data/Rakefile +1 -0
- data/autotest/discover.rb +1 -0
- data/bin/ffnpdf +5 -0
- data/ffnpdf.gemspec +29 -0
- data/lib/ffnpdf.rb +8 -0
- data/lib/ffnpdf/converter.rb +16 -0
- data/lib/ffnpdf/exec.rb +57 -0
- data/lib/ffnpdf/story.rb +218 -0
- data/lib/ffnpdf/version.rb +3 -0
- data/spec/ffnpdf/converter_spec.rb +14 -0
- data/spec/ffnpdf/exec_spec.rb +4 -0
- data/spec/ffnpdf/story_spec.rb +138 -0
- data/spec/ffnpdf_spec.rb +9 -0
- data/spec/spec_helper.rb +4 -0
- metadata +142 -0
data/.gitignore
ADDED
data/.rspec
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
# FFNPDF
|
2
|
+
|
3
|
+
Just scratched an coding itch I've had for quite some time.
|
4
|
+
|
5
|
+
This gem scrapes stories from FanFiction.net and generates LaTeX PDFs. Polished turds, anyone?
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
To install this stupid gem:
|
10
|
+
|
11
|
+
gem install ffnpdf
|
12
|
+
|
13
|
+
It also requires [pandoc](http://johnmacfarlane.net/pandoc/) as well as a bunch of extra stuff related to LaTeX/XeTeX. In Ubuntu, you can install this using the following command:
|
14
|
+
|
15
|
+
sudo apt-get install pandoc texlive-latex-extra texlive-xetex
|
16
|
+
|
17
|
+
It also uses [DejaVu Fonts](http://dejavu-fonts.org/wiki/Main_Page) as the default font. This font family is installed by default in Ubuntu.
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
The basic command only requires the story's story ID.
|
22
|
+
|
23
|
+
ffnpdf [STORY_ID]
|
24
|
+
|
25
|
+
This will scrape FFN for the story, convert the chapters into markdown, combine all chapters into a single file, and converts it into PDF, all inside the `STORY_ID` folder.
|
26
|
+
|
27
|
+
## Additional Commands
|
28
|
+
|
29
|
+
Since you may want to do your own edits to the fics (e.g. remove authors notes, correct chapter headers) there are additional commands that allow you to perform individual steps of the process.
|
30
|
+
|
31
|
+
### Pull
|
32
|
+
|
33
|
+
ffnpdf pull [STORY_ID]
|
34
|
+
|
35
|
+
This command
|
36
|
+
|
37
|
+
* creates the `STORY_ID` folder
|
38
|
+
* pulls chapters and converts them to Markdown
|
39
|
+
* creates template and variables (config) file
|
40
|
+
|
41
|
+
The markdown files are numbered from `0001.md` onwards. A title section, `0000.md`, is also created.
|
42
|
+
|
43
|
+
The `xetex.template` file is obviously the XeTeX template, while the `variables.txt` defines the [template variables section](http://johnmacfarlane.net/pandoc/README.html#general-writer-options) used when generating the PDF. Both can be modified to affect the result of running both `ffnpdf build` and `ffnpdf convert`.
|
44
|
+
|
45
|
+
|
46
|
+
### Build
|
47
|
+
|
48
|
+
ffnpdf build [STORY_ID]
|
49
|
+
|
50
|
+
This command
|
51
|
+
|
52
|
+
* combines all `.md` files to a single file, `combined.md`, in alphabetical order
|
53
|
+
* converts `combined.md` to `combined.pdf` while using both the template and variables file
|
54
|
+
|
55
|
+
### Build
|
56
|
+
|
57
|
+
ffnpdf convert [STORY_ID]
|
58
|
+
|
59
|
+
This command does only the second step of the Build i.e. converts `combined.md` to `combined.pdf`.
|
60
|
+
|
61
|
+
## Troubleshooting
|
62
|
+
|
63
|
+
**Table of Contents don't match the actual pages of the chapters.**
|
64
|
+
|
65
|
+
[This is a LaTeX issue](http://tex.stackexchange.com/a/30946). Just rerun the `ffnpdf convert` command to rebuild the PDF.
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
@@ -0,0 +1 @@
|
|
1
|
+
Autotest.add_discovery { "rspec2" }
|
data/bin/ffnpdf
ADDED
data/ffnpdf.gemspec
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "ffnpdf/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "ffnpdf"
|
7
|
+
s.version = Ffnpdf::VERSION
|
8
|
+
s.authors = ["Bryan Bibat"]
|
9
|
+
s.email = ["bry@bryanbibat.net"]
|
10
|
+
s.homepage = "https://github.com/bryanbibat/ffnpdf"
|
11
|
+
s.summary = %q{PDF generator for FF.net stories}
|
12
|
+
s.description = %q{Scrapes a story off FF.net, converts it to Markdown, and turns it to PDF with LaTeX}
|
13
|
+
|
14
|
+
s.rubyforge_project = "ffnpdf"
|
15
|
+
|
16
|
+
s.files = `git ls-files`.split("\n")
|
17
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
18
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
19
|
+
s.require_paths = ["lib"]
|
20
|
+
|
21
|
+
# specify any dependencies here; for example:
|
22
|
+
s.add_development_dependency "rspec"
|
23
|
+
s.add_development_dependency "test_notifier"
|
24
|
+
s.add_development_dependency "autotest"
|
25
|
+
s.add_development_dependency "nokogiri"
|
26
|
+
s.add_development_dependency "httparty"
|
27
|
+
s.add_runtime_dependency "nokogiri"
|
28
|
+
s.add_runtime_dependency "httparty"
|
29
|
+
end
|
data/lib/ffnpdf.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
module Ffnpdf
|
2
|
+
class Converter
|
3
|
+
def self.exec(command)
|
4
|
+
`#{command}`
|
5
|
+
end
|
6
|
+
|
7
|
+
def self.convert_to_pdf(story_id)
|
8
|
+
Dir.chdir story_id
|
9
|
+
|
10
|
+
command = "markdown2pdf --xetex --template=xetex.template --toc #{IO.readlines("variables.txt")[0].strip} combined.md"
|
11
|
+
Converter.exec(command)
|
12
|
+
|
13
|
+
Dir.chdir "../"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
data/lib/ffnpdf/exec.rb
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
module Ffnpdf
|
2
|
+
class Exec
|
3
|
+
def initialize(argv)
|
4
|
+
invalid = false
|
5
|
+
if argv.size == 0
|
6
|
+
invalid = true
|
7
|
+
elsif /^[\d]+$/.match argv[0]
|
8
|
+
story = Ffnpdf::Story.new(argv[0])
|
9
|
+
if story.check_story
|
10
|
+
story.pull_story
|
11
|
+
story.build_story
|
12
|
+
else
|
13
|
+
$stderr.puts story.error
|
14
|
+
end
|
15
|
+
elsif argv[0] == "pull" and /^[\d]+$/.match argv[1]
|
16
|
+
story = Ffnpdf::Story.new(argv[1])
|
17
|
+
if story.check_story
|
18
|
+
story.pull_story
|
19
|
+
else
|
20
|
+
$stderr.puts story.error
|
21
|
+
end
|
22
|
+
elsif argv[0] == "build" and /^[\d]+$/.match argv[1]
|
23
|
+
story = Ffnpdf::Story.new(argv[1])
|
24
|
+
if story.check_story_dir
|
25
|
+
story.build_story
|
26
|
+
else
|
27
|
+
$stderr.puts story.error
|
28
|
+
end
|
29
|
+
elsif argv[0] == "convert" and /^[\d]+$/.match argv[1]
|
30
|
+
story = Ffnpdf::Story.new(argv[1])
|
31
|
+
if story.check_story_dir
|
32
|
+
story.convert_to_pdf
|
33
|
+
else
|
34
|
+
$stderr.puts story.error
|
35
|
+
end
|
36
|
+
else
|
37
|
+
invalid = true
|
38
|
+
end
|
39
|
+
|
40
|
+
if invalid
|
41
|
+
$stderr.puts <<-MSG
|
42
|
+
Usage
|
43
|
+
ffnpdf [STORY_ID]
|
44
|
+
ffnpdf [COMMAND] [STORY_ID]
|
45
|
+
|
46
|
+
Description
|
47
|
+
Scrapes story from FanFiction.net and generates pdf at STORY_ID/ folder.
|
48
|
+
|
49
|
+
The following commands are available
|
50
|
+
pull scrapes story and puts the markdown and template files at STORY_ID/ folder
|
51
|
+
build compiles *.md files at STORY_ID/ into a single pdf
|
52
|
+
convert converts STORY_ID/combined.md to pdf using the template files
|
53
|
+
MSG
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
data/lib/ffnpdf/story.rb
ADDED
@@ -0,0 +1,218 @@
|
|
1
|
+
require 'httparty'
|
2
|
+
require 'nokogiri'
|
3
|
+
require 'fileutils'
|
4
|
+
require 'open3'
|
5
|
+
|
6
|
+
module Ffnpdf
|
7
|
+
class Story
|
8
|
+
FFN_URL = "http://www.fanfiction.net/"
|
9
|
+
|
10
|
+
attr_accessor :custom_url, :error
|
11
|
+
|
12
|
+
def initialize(story_id)
|
13
|
+
@story_id = story_id
|
14
|
+
end
|
15
|
+
|
16
|
+
def check_story_id
|
17
|
+
unless /^[\d]*$/.match @story_id
|
18
|
+
@error = "Story ID is invalid"
|
19
|
+
return false
|
20
|
+
end
|
21
|
+
true
|
22
|
+
end
|
23
|
+
|
24
|
+
def check_story
|
25
|
+
return false unless check_story_id
|
26
|
+
|
27
|
+
test_pull = HTTParty.get(story_url)
|
28
|
+
unless test_pull.code == 200
|
29
|
+
@error = "Story does not exist (#{story_url})"
|
30
|
+
return false
|
31
|
+
end
|
32
|
+
|
33
|
+
unless Nokogiri::HTML(test_pull.body).css(".storytext")
|
34
|
+
@error = "Story does not exist (#{story_url})"
|
35
|
+
return false
|
36
|
+
end
|
37
|
+
|
38
|
+
true
|
39
|
+
end
|
40
|
+
|
41
|
+
def check_story_dir
|
42
|
+
return false unless check_story_id
|
43
|
+
|
44
|
+
unless File.directory?(@story_id)
|
45
|
+
@error = "Story folder does not exist (#{@story_id}/)"
|
46
|
+
return false
|
47
|
+
end
|
48
|
+
|
49
|
+
unless chapter_mds.count > 0
|
50
|
+
@error = "Story folder does not have markdown files (#{@story_id}/)"
|
51
|
+
return false
|
52
|
+
end
|
53
|
+
|
54
|
+
true
|
55
|
+
end
|
56
|
+
|
57
|
+
def chapter_mds
|
58
|
+
Dir["#{@story_id}/*"].grep(/.md$/).reject { |x| /combined.md$/.match x }.sort
|
59
|
+
end
|
60
|
+
|
61
|
+
def story_url
|
62
|
+
custom_url ? "#{@custom_url}s/#{@story_id}/" : "#{FFN_URL}s/#{@story_id}/"
|
63
|
+
end
|
64
|
+
|
65
|
+
def pull_story
|
66
|
+
return unless check_story
|
67
|
+
FileUtils.mkdir_p @story_id
|
68
|
+
Dir.chdir @story_id
|
69
|
+
|
70
|
+
tempfile = File.new("temp.html", "w")
|
71
|
+
pull = HTTParty.get(story_url)
|
72
|
+
doc = Nokogiri::HTML(pull.body)
|
73
|
+
doc.css(".storytext")[0].children.each do |paragraph|
|
74
|
+
if /^<(p|hr|i|b)/.match paragraph.to_s
|
75
|
+
tempfile.puts paragraph
|
76
|
+
end
|
77
|
+
end
|
78
|
+
tempfile.close
|
79
|
+
|
80
|
+
Converter.exec 'pandoc temp.html -o 0001.md'
|
81
|
+
|
82
|
+
title = doc.xpath("//div/div/b")[0].text
|
83
|
+
author = doc.xpath("//div/table//a[not(@title or @onclick)]")[0].text
|
84
|
+
|
85
|
+
generate_template(title, author, get_doc_date(doc))
|
86
|
+
generate_variables_file
|
87
|
+
generate_title_page
|
88
|
+
|
89
|
+
chapters = doc.xpath('//form//select[@name="chapter"]/option').count
|
90
|
+
if chapters > 1
|
91
|
+
append_header_to_ch1
|
92
|
+
|
93
|
+
(2..chapters).each do |chapter|
|
94
|
+
tempfile = File.new("temp.html", "w")
|
95
|
+
tempfile.puts "<h2>Chapter #{chapter}</h2>"
|
96
|
+
pull = HTTParty.get("#{story_url}#{chapter}/")
|
97
|
+
doc = Nokogiri::HTML(pull.body)
|
98
|
+
doc.css(".storytext")[0].children.each do |paragraph|
|
99
|
+
if /^<(p|hr|i|b)/.match paragraph.to_s
|
100
|
+
tempfile.puts paragraph
|
101
|
+
end
|
102
|
+
end
|
103
|
+
tempfile.close
|
104
|
+
Converter.exec("pandoc temp.html -o #{"%04d" % chapter}.md")
|
105
|
+
end
|
106
|
+
end
|
107
|
+
Dir.chdir "../"
|
108
|
+
end
|
109
|
+
|
110
|
+
def get_doc_date(doc)
|
111
|
+
parsing = doc.xpath('//div[@style="padding-left:1em;padding-right:1em;padding-top:0.5em;"]')[0].text
|
112
|
+
match = /Updated: (.{8})/.match parsing
|
113
|
+
if match
|
114
|
+
return Date.strptime(match[1], "%m-%d-%y").strftime("%d %B %Y")
|
115
|
+
else
|
116
|
+
match = /Published: (.{8})/.match parsing
|
117
|
+
return Date.strptime(match[1], "%m-%d-%y").strftime("%d %B %Y")
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
def generate_template(title, author, date)
|
122
|
+
template = File.new("xetex.template", "w")
|
123
|
+
contents = <<-CONTENTS
|
124
|
+
% Shamelessly ripped off from https://github.com/karlseguin/the-little-mongodb-book
|
125
|
+
\\documentclass[$fontsize$,$columns$]{book}
|
126
|
+
\\usepackage{fullpage}
|
127
|
+
\\usepackage{changepage}
|
128
|
+
\\usepackage{fontspec,xltxtra,xunicode}
|
129
|
+
\\defaultfontfeatures{Mapping=tex-text,Scale=MatchLowercase}
|
130
|
+
\\setmainfont{$mainfont$}
|
131
|
+
\\setsansfont{$sansfont$}
|
132
|
+
\\setmonofont{$monofont$}
|
133
|
+
|
134
|
+
\\setlength{\\parindent}{0pt}
|
135
|
+
\\setlength{\\parskip}{12pt plus 2pt minus 1pt}
|
136
|
+
\\linespread{1.2}
|
137
|
+
|
138
|
+
\\usepackage{listings}
|
139
|
+
\\usepackage[dvipsnames,usenames]{color}
|
140
|
+
|
141
|
+
$if(fancy-enums)$
|
142
|
+
\\usepackage{enumerate}
|
143
|
+
$endif$
|
144
|
+
\\setcounter{secnumdepth}{-1}
|
145
|
+
|
146
|
+
\\usepackage{hyperref}
|
147
|
+
\\hypersetup{
|
148
|
+
colorlinks=true,%
|
149
|
+
citecolor=Black,%
|
150
|
+
filecolor=Black,%
|
151
|
+
linkcolor=Black,%
|
152
|
+
urlcolor=Black
|
153
|
+
}
|
154
|
+
|
155
|
+
\\title{#{title}}
|
156
|
+
\\author{#{author}}
|
157
|
+
\\date{#{date}}
|
158
|
+
\\begin{document}
|
159
|
+
$body$
|
160
|
+
\\end{document}
|
161
|
+
CONTENTS
|
162
|
+
template.puts(contents)
|
163
|
+
template.close
|
164
|
+
end
|
165
|
+
|
166
|
+
def generate_variables_file
|
167
|
+
variables = File.new("variables.txt", "w")
|
168
|
+
variables.puts("-V paper=a4paper -V hmargin=3cm -V vmargin=3cm -V mainfont=\"DejaVu Serif\" -V sansfont=\"DejaVu Sans\" -V monofont=\"DejaVu Sans Mono\" -V geometry=portrait -V columns=onecolumn -V fontsize=11pt ")
|
169
|
+
variables.close
|
170
|
+
end
|
171
|
+
|
172
|
+
def generate_title_page
|
173
|
+
title_page = File.new("0000.md", "w")
|
174
|
+
contents = <<-CONTENTS
|
175
|
+
\\thispagestyle{empty}
|
176
|
+
\\maketitle
|
177
|
+
\\tableofcontents
|
178
|
+
|
179
|
+
CONTENTS
|
180
|
+
title_page.puts(contents)
|
181
|
+
title_page.close
|
182
|
+
end
|
183
|
+
|
184
|
+
def append_header_to_ch1
|
185
|
+
chapter1 = File.new("0001.temp", "w")
|
186
|
+
chapter1.puts "\#\# Chapter 1"
|
187
|
+
chapter1.puts
|
188
|
+
IO.foreach("0001.md") do |line|
|
189
|
+
chapter1.puts line
|
190
|
+
end
|
191
|
+
chapter1.close
|
192
|
+
FileUtils.rm("0001.md")
|
193
|
+
File.rename("0001.temp", "0001.md")
|
194
|
+
end
|
195
|
+
|
196
|
+
def build_story
|
197
|
+
return unless check_story_dir
|
198
|
+
combine_mds
|
199
|
+
convert_to_pdf
|
200
|
+
end
|
201
|
+
|
202
|
+
def combine_mds
|
203
|
+
combined = File.new("#{@story_id}/combined.md", "w")
|
204
|
+
chapter_mds.each do |chapter|
|
205
|
+
IO.foreach("#{chapter}") do |line|
|
206
|
+
combined.puts(line)
|
207
|
+
end
|
208
|
+
combined.puts("\\clearpage")
|
209
|
+
combined.puts()
|
210
|
+
end
|
211
|
+
combined.close
|
212
|
+
end
|
213
|
+
|
214
|
+
def convert_to_pdf
|
215
|
+
Converter.convert_to_pdf(@story_id)
|
216
|
+
end
|
217
|
+
end
|
218
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Ffnpdf::Converter do
|
4
|
+
context "exec" do
|
5
|
+
it "should be able to run commands" do
|
6
|
+
Ffnpdf::Converter.exec("pwd")
|
7
|
+
end
|
8
|
+
it "should be able to run syncrhonously" do
|
9
|
+
Ffnpdf::Converter.exec("rm temp.txt")
|
10
|
+
Ffnpdf::Converter.exec("pwd > temp.txt")
|
11
|
+
File.exists?("temp.txt").should == true
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,138 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Ffnpdf::Story do
|
4
|
+
|
5
|
+
it "should create a story" do
|
6
|
+
story = Ffnpdf::Story.new("1234567")
|
7
|
+
story.custom_url = "http://bryanbibat.github.com/ffnpdf-test/"
|
8
|
+
story.check_story.should == true
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should allow setting custom url" do
|
12
|
+
story = Ffnpdf::Story.new("1234567")
|
13
|
+
story.story_url.should == "http://www.fanfiction.net/s/1234567/"
|
14
|
+
story.custom_url = "http://bryanbibat.github.com/ffnpdf-test/"
|
15
|
+
story.story_url.should == "http://bryanbibat.github.com/ffnpdf-test/s/1234567/"
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should check if story id is valid" do
|
19
|
+
blah = Ffnpdf::Story.new("blah")
|
20
|
+
blah.check_story.should == false
|
21
|
+
blah.error.should == "Story ID is invalid"
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should check story's existence" do
|
25
|
+
story = Ffnpdf::Story.new("0")
|
26
|
+
story.custom_url = "http://bryanbibat.github.com/ffnpdf-test/"
|
27
|
+
story.check_story.should == false
|
28
|
+
story.error.should == "Story does not exist (#{story.story_url})"
|
29
|
+
end
|
30
|
+
|
31
|
+
context "pulling" do
|
32
|
+
before :each do
|
33
|
+
@story = Ffnpdf::Story.new("1234567")
|
34
|
+
@story.custom_url = "http://bryanbibat.github.com/ffnpdf-test/"
|
35
|
+
end
|
36
|
+
|
37
|
+
after :each do
|
38
|
+
if File.directory?("1234567")
|
39
|
+
FileUtils.rm_rf("1234567")
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should create a story directory" do
|
44
|
+
pwd = Dir.pwd
|
45
|
+
@story.pull_story
|
46
|
+
Dir.pwd.should == pwd
|
47
|
+
File.should be_directory("1234567")
|
48
|
+
File.should exist("1234567/0001.md")
|
49
|
+
File.should exist("1234567/0000.md")
|
50
|
+
File.should exist("1234567/variables.txt")
|
51
|
+
File.should exist("1234567/xetex.template")
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
context "building" do
|
56
|
+
after :each do
|
57
|
+
if File.directory?("1234567")
|
58
|
+
FileUtils.rm_rf("1234567")
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
it "should check non existence of directory" do
|
63
|
+
story = Ffnpdf::Story.new("1234567")
|
64
|
+
story.custom_url = "http://bryanbibat.github.com/ffnpdf-test/"
|
65
|
+
story.check_story_dir.should == false
|
66
|
+
story.error.should == "Story folder does not exist (1234567/)"
|
67
|
+
end
|
68
|
+
|
69
|
+
it "should check non existence of files" do
|
70
|
+
story = Ffnpdf::Story.new("1234567")
|
71
|
+
story.custom_url = "http://bryanbibat.github.com/ffnpdf-test/"
|
72
|
+
story.pull_story
|
73
|
+
story = Ffnpdf::Story.new("1234567")
|
74
|
+
story.custom_url = "http://bryanbibat.github.com/ffnpdf-test/"
|
75
|
+
FileUtils.rm("1234567/0001.md")
|
76
|
+
FileUtils.rm("1234567/0000.md")
|
77
|
+
story.check_story_dir.should == false
|
78
|
+
story.error.should == "Story folder does not have markdown files (1234567/)"
|
79
|
+
end
|
80
|
+
|
81
|
+
it "should check existence of directory" do
|
82
|
+
story = Ffnpdf::Story.new("1234567")
|
83
|
+
story.custom_url = "http://bryanbibat.github.com/ffnpdf-test/"
|
84
|
+
story.pull_story
|
85
|
+
story = Ffnpdf::Story.new("1234567")
|
86
|
+
story.custom_url = "http://bryanbibat.github.com/ffnpdf-test/"
|
87
|
+
story.check_story_dir.should == true
|
88
|
+
end
|
89
|
+
|
90
|
+
end
|
91
|
+
|
92
|
+
context "pulling multi" do
|
93
|
+
before :each do
|
94
|
+
@story = Ffnpdf::Story.new("0000001")
|
95
|
+
@story.custom_url = "http://bryanbibat.github.com/ffnpdf-test/"
|
96
|
+
end
|
97
|
+
|
98
|
+
after :each do
|
99
|
+
if File.directory?("0000001")
|
100
|
+
FileUtils.rm_rf("0000001")
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
it "should create a story directory" do
|
105
|
+
pwd = Dir.pwd
|
106
|
+
@story.pull_story
|
107
|
+
Dir.pwd.should == pwd
|
108
|
+
File.should be_directory("0000001")
|
109
|
+
File.should exist("0000001/0001.md")
|
110
|
+
File.should exist("0000001/0002.md")
|
111
|
+
File.should exist("0000001/0003.md")
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
context "building multi" do
|
116
|
+
before :each do
|
117
|
+
@story = Ffnpdf::Story.new("0000001")
|
118
|
+
@story.custom_url = "http://bryanbibat.github.com/ffnpdf-test/"
|
119
|
+
end
|
120
|
+
|
121
|
+
after :each do
|
122
|
+
if File.directory?("0000001")
|
123
|
+
#FileUtils.rm_rf("0000001")
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
it "should build a story" do
|
128
|
+
pwd = Dir.pwd
|
129
|
+
@story.pull_story
|
130
|
+
Dir.pwd.should == pwd
|
131
|
+
@story.build_story
|
132
|
+
Dir.pwd.should == pwd
|
133
|
+
File.should exist("0000001/combined.md")
|
134
|
+
File.should exist("0000001/combined.pdf")
|
135
|
+
end
|
136
|
+
|
137
|
+
end
|
138
|
+
end
|
data/spec/ffnpdf_spec.rb
ADDED
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,142 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ffnpdf
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.2
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Bryan Bibat
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-02-14 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rspec
|
16
|
+
requirement: &79274890 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *79274890
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: test_notifier
|
27
|
+
requirement: &79272240 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
33
|
+
type: :development
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *79272240
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: autotest
|
38
|
+
requirement: &79270640 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ! '>='
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '0'
|
44
|
+
type: :development
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *79270640
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: nokogiri
|
49
|
+
requirement: &79269170 !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
type: :development
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: *79269170
|
58
|
+
- !ruby/object:Gem::Dependency
|
59
|
+
name: httparty
|
60
|
+
requirement: &79268340 !ruby/object:Gem::Requirement
|
61
|
+
none: false
|
62
|
+
requirements:
|
63
|
+
- - ! '>='
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: '0'
|
66
|
+
type: :development
|
67
|
+
prerelease: false
|
68
|
+
version_requirements: *79268340
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: nokogiri
|
71
|
+
requirement: &79267380 !ruby/object:Gem::Requirement
|
72
|
+
none: false
|
73
|
+
requirements:
|
74
|
+
- - ! '>='
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '0'
|
77
|
+
type: :runtime
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: *79267380
|
80
|
+
- !ruby/object:Gem::Dependency
|
81
|
+
name: httparty
|
82
|
+
requirement: &79266680 !ruby/object:Gem::Requirement
|
83
|
+
none: false
|
84
|
+
requirements:
|
85
|
+
- - ! '>='
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
version: '0'
|
88
|
+
type: :runtime
|
89
|
+
prerelease: false
|
90
|
+
version_requirements: *79266680
|
91
|
+
description: Scrapes a story off FF.net, converts it to Markdown, and turns it to
|
92
|
+
PDF with LaTeX
|
93
|
+
email:
|
94
|
+
- bry@bryanbibat.net
|
95
|
+
executables:
|
96
|
+
- ffnpdf
|
97
|
+
extensions: []
|
98
|
+
extra_rdoc_files: []
|
99
|
+
files:
|
100
|
+
- .gitignore
|
101
|
+
- .rspec
|
102
|
+
- Gemfile
|
103
|
+
- README.md
|
104
|
+
- Rakefile
|
105
|
+
- autotest/discover.rb
|
106
|
+
- bin/ffnpdf
|
107
|
+
- ffnpdf.gemspec
|
108
|
+
- lib/ffnpdf.rb
|
109
|
+
- lib/ffnpdf/converter.rb
|
110
|
+
- lib/ffnpdf/exec.rb
|
111
|
+
- lib/ffnpdf/story.rb
|
112
|
+
- lib/ffnpdf/version.rb
|
113
|
+
- spec/ffnpdf/converter_spec.rb
|
114
|
+
- spec/ffnpdf/exec_spec.rb
|
115
|
+
- spec/ffnpdf/story_spec.rb
|
116
|
+
- spec/ffnpdf_spec.rb
|
117
|
+
- spec/spec_helper.rb
|
118
|
+
homepage: https://github.com/bryanbibat/ffnpdf
|
119
|
+
licenses: []
|
120
|
+
post_install_message:
|
121
|
+
rdoc_options: []
|
122
|
+
require_paths:
|
123
|
+
- lib
|
124
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
125
|
+
none: false
|
126
|
+
requirements:
|
127
|
+
- - ! '>='
|
128
|
+
- !ruby/object:Gem::Version
|
129
|
+
version: '0'
|
130
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
131
|
+
none: false
|
132
|
+
requirements:
|
133
|
+
- - ! '>='
|
134
|
+
- !ruby/object:Gem::Version
|
135
|
+
version: '0'
|
136
|
+
requirements: []
|
137
|
+
rubyforge_project: ffnpdf
|
138
|
+
rubygems_version: 1.8.10
|
139
|
+
signing_key:
|
140
|
+
specification_version: 3
|
141
|
+
summary: PDF generator for FF.net stories
|
142
|
+
test_files: []
|