magicshelf 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 1442269b371a6a584ed4a00eede012300e8f48af
4
+ data.tar.gz: e311a0dd3d245eaa42c8a0c2cfa488e9805234db
5
+ SHA512:
6
+ metadata.gz: f61e304a272623e583b13f1fdfd1d83ad62316d0323613479e2fc943eae1d4317100e91a0da7ee6a11e7460c6528a060b1f3b91b80c24115df82b7c1ab6a8948
7
+ data.tar.gz: 04bfca83c4fb273026ba2dfea8484f82f03dac508ea108c8407c986bd2a877fdf2ca866af718a2ff5e4755e00f770e437c3bcc31d8c4bde8dee0f7a991de664c
@@ -0,0 +1,3 @@
1
+ vendor/
2
+ Gemfile.lock
3
+ .bundle/
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec
4
+
5
+ gem 'gepub', github: 'skoji/gepub' # git: 'https://xxxxxx/yyyy.git'
6
+ #gem 'naturally', github: 'zedalaye/naturally'
@@ -0,0 +1,4 @@
1
+ web: bundle exec shotgun -p 4567 -o 0.0.0.0
2
+ resque: QUEUE=* bundle exec rake resque:work
3
+ redisserver: redis-server
4
+ #resque-web: resque-web --foreground
@@ -0,0 +1,38 @@
1
+ # MagicShelf
2
+
3
+ Access and get your e-book from kindle anywhere.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'magicshelf'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install magicshelf
20
+
21
+ ## Usage
22
+
23
+ ### Console app
24
+ ````
25
+ magicconvert --inputfile comic.rar --outputfile comic.mobi --booktype novel/comic/novelimage --title booktitle
26
+ ````
27
+
28
+
29
+ ### File Server
30
+ ````
31
+ bundle exec foreman start
32
+ ````
33
+
34
+
35
+ ## Contributing
36
+
37
+ Bug reports and pull requests are welcome on GitHub at https://github.com/ompugao/magicshelf.
38
+
@@ -0,0 +1,16 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rake/testtask'
3
+ require 'resque/tasks'
4
+
5
+ desc 'Run test_unit based test'
6
+ Rake::TestTask.new do |t|
7
+ # To run test for only one file (or file path pattern)
8
+ # $ bundle exec rake test TEST=test/test_specified_path.rb
9
+ t.libs << "test"
10
+ t.test_files = Dir["test/**/test_*.rb"]
11
+ t.verbose = true
12
+ end
13
+
14
+ task :'resque:setup' do
15
+ Dir["./lib/magicshelf/mobitask.rb"].each {|file| require file}
16
+ end
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "magicshelf"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ require "pry"
11
+ Pry.start
12
+
13
+ #require "irb"
14
+ #IRB.start
@@ -0,0 +1,40 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'magicshelf'
4
+ require 'magicshelf/executionpipe'
5
+ require 'optparse'
6
+
7
+ optparams = ARGV.getopts("", "inputfile:", "title:", "outputfile:", "booktype:comic")
8
+
9
+ MagicShelf::ExecutionPipe.new.enter { |params,&block|
10
+ Dir.mktmpdir("magicshelf") do |dir|
11
+ params[:workdir] = dir
12
+ block.call
13
+ end
14
+ }.pipe(MagicShelf::FileExtractor.new,:workdir => [:destdir]) { |this|
15
+ this.inputfile = File.expand_path(optparams["inputfile"])
16
+ }.enter(:destdir => [:workdir]) {|params, &block|
17
+ Dir.chdir(params[:workdir]) do
18
+ block.call
19
+ end
20
+ }.pipe(MagicShelf::DirRenamer.new, :workdir => [:workdir]) { |this|
21
+ }.pipe(MagicShelf::FileNameValidator.new, :workdir => [:workdir]) { |this|
22
+ }.pipe(MagicShelf::MakeItVertical.new, :workdir => [:workdir]) { |this|
23
+ }.pipe(MagicShelf::EpubGenerator.new, :workdir => [:workdir]) { |this|
24
+ this.title = optparams['title']
25
+ this.book_type = optparams['booktype']
26
+ this.outputfile = 'test.epub'
27
+ }.pipe(MagicShelf::KindleGenWrapper.new, :outputfile => [:inputfile]) { |this|
28
+ this.outputfile = 'test.mobi'
29
+ }.process(:inputfile => [:file,:inputfile], :outputfile => [:outputfile]) { |params|
30
+ FileUtils.remove(params[:file])
31
+ }.pipe(MagicShelf::KindleStripper.new, :outputfile => [:inputfile]) { |this|
32
+ this.outputfile = File.expand_path('test_strip.mobi')
33
+ }.pipe(MagicShelf::FileCleaner.new, :inputfile => [:file], :outputfile => [:outputfile]) { |this|
34
+ }.pipe(MagicShelf::FileMover.new, :outputfile => [:inputfile]) { |this|
35
+ this.outputfile = File.expand_path(optparams["outputfile"])
36
+ }.execute
37
+
38
+ # vim: set ft=ruby ts=22 sw=2:
39
+
40
+
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+ require 'sinatra'
3
+ require 'magicshelf'
4
+
5
+ run MagicShelf::FileServer
6
+
7
+
8
+ # vim: set ft=ruby:
@@ -0,0 +1,7 @@
1
+ #!/bin/bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+
5
+ bundle install
6
+
7
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,6 @@
1
+ require './lib/magicshelf/fileserver'
2
+ require 'resque/server'
3
+
4
+ run Rack::URLMap.new \
5
+ "/" => MagicShelf::FileServer,
6
+ "/resque" => Resque::Server.new
@@ -0,0 +1,33 @@
1
+ require 'rubygems'
2
+ require "magicshelf/version"
3
+
4
+ require "magicshelf/dirchanger"
5
+ require "magicshelf/dirrenamer"
6
+ require "magicshelf/dirstructureflattener"
7
+ require "magicshelf/epubgenerator"
8
+ require "magicshelf/executionpipe"
9
+ require "magicshelf/filecleaner"
10
+ require "magicshelf/fileextractor"
11
+ require "magicshelf/filemover"
12
+ require "magicshelf/filenamevalidator"
13
+ require "magicshelf/fileserver"
14
+ require "magicshelf/kindlegenwrapper"
15
+ require "magicshelf/kindlestripper"
16
+ require "magicshelf/makeitvertical"
17
+ require "magicshelf/tempdiropener"
18
+
19
+
20
+ Dir.glob('monkeypatches/*') do |f|
21
+ require f
22
+ end
23
+
24
+ require 'logger'
25
+
26
+ module MagicShelf
27
+ (class << self; self end).module_eval do
28
+ attr_accessor :logger
29
+ end
30
+ end
31
+
32
+ MagicShelf.logger = Logger.new(STDOUT)
33
+
@@ -0,0 +1,22 @@
1
+ require 'magicshelf/exception'
2
+
3
+ module MagicShelf
4
+ class DirChangerError < Error; end
5
+
6
+ class DirChanger
7
+ attr_accessor :workdir
8
+
9
+ def enter()
10
+ raise MagicShelf::DirChangerError.new("workdir is not set") if @workdir == nil
11
+ Dir.chdir(@workdir) {|dir|
12
+ MagicShelf.logger.debug("DirChanger: chdir to #{dir}")
13
+ yield
14
+ }
15
+ end
16
+
17
+ def process()
18
+ end
19
+
20
+ end
21
+ end
22
+
@@ -0,0 +1,30 @@
1
+ require 'magicshelf/exception'
2
+
3
+ module MagicShelf
4
+ class DirRenamerError < Error; end
5
+
6
+ class DirRenamer
7
+ attr_accessor :workdir
8
+ def enter()
9
+ yield
10
+ end
11
+
12
+ def process()
13
+ @workdir ||= Dir.pwd
14
+ rename_dir_recursively(@workdir)
15
+ end
16
+
17
+ def rename_dir_recursively(path)
18
+ Dir.chdir(path) {
19
+ Dir['./*'].select{|f|File.directory?(f)}.each.with_index { |f,index|
20
+ if File.directory?(f)
21
+ rename_dir_recursively(f)
22
+ FileUtils.mv(f, index.to_s)
23
+ end
24
+ }
25
+ }
26
+ end
27
+ end
28
+ end
29
+
30
+
@@ -0,0 +1,25 @@
1
+ require 'magicshelf/exception'
2
+
3
+ module MagicShelf
4
+ class DirStructureFlattenerError < Error; end
5
+
6
+ class DirStructureFlattener
7
+ attr_accessor :workdir
8
+ def enter()
9
+ yield
10
+ end
11
+
12
+ def process()
13
+ @workdir ||= Dir.pwd
14
+ Dir.glob(File.join(@workdir,'**/*')).select{|f|File.file?(f)}.each do |f|
15
+ begin
16
+ FileUtils.mv f, @workdir
17
+ rescue => e
18
+ MagicShelf.logger.warn(e.message)
19
+ end
20
+
21
+ end
22
+ end
23
+ end
24
+ end
25
+
@@ -0,0 +1,86 @@
1
+ require 'magicshelf/exception'
2
+ require 'gepub'
3
+ require 'shellwords'
4
+ require 'naturally'
5
+
6
+ module MagicShelf
7
+ class EpubGeneratorError < Error; end
8
+
9
+ # create a epub file with the file under the current directory
10
+ class EpubGenerator
11
+ attr_accessor :book_type, :title, :outputfile, :language, :identifier_url, :creator, :creator_en
12
+
13
+ def enter()
14
+ MagicShelf.logger.debug('enter EpubGenerator')
15
+ # check parameters
16
+ raise MagicShelf::EpubGeneratorError.new("@title is not set") if @title == nil
17
+ raise MagicShelf::EpubGeneratorError.new("@outputfile is not set") if @outputfile == nil
18
+ # default parameters
19
+ @book_type ||= 'comic'
20
+ @language ||= 'ja'
21
+ @identifier_url ||= 'http:/example.jp/bookid_in_url'
22
+
23
+ yield
24
+ end
25
+
26
+ def process()
27
+ epubname = @outputfile
28
+
29
+ book = GEPUB::Book.new
30
+ book.unique_identifier @identifier_url
31
+ book.identifier @identifier_url
32
+ book.language = @language
33
+
34
+
35
+ book.add_title(@title, nil, GEPUB::TITLE_TYPE::MAIN) { |title|
36
+ title.lang = @language
37
+ title.file_as = Shellwords.escape(@title)
38
+ title.display_seq = 1
39
+ }
40
+ if @creator
41
+ book.add_creator(@creator) { |creator|
42
+ creator.display_seq = 1
43
+ creator.add_alternates('en' => @creator_en) if @creator_en
44
+ }
45
+ end
46
+
47
+ if @book_type == "comic"
48
+ book.page_progression_direction = 'rtl'
49
+ metadata = book.instance_eval{@package}.instance_eval{@metadata}
50
+ metacomic = metadata.add_metadata('meta', '')
51
+ metacomic['name'] = 'book-type'
52
+ metacomic['content'] = 'comic'
53
+ metafixedlayout = metadata.add_metadata('meta', '')
54
+ metafixedlayout['name'] = 'fixed-layout'
55
+ metafixedlayout['content'] = 'true'
56
+ elsif @book_type == "novelimage"
57
+ book.page_progression_direction = 'rtl'
58
+ metadata = book.instance_eval{@package}.instance_eval{@metadata}
59
+ metafixedlayout = metadata.add_metadata('meta', '')
60
+ metafixedlayout['name'] = 'fixed-layout'
61
+ metafixedlayout['content'] = 'true'
62
+ elsif @book_type == "novel"
63
+ book.page_progression_direction = 'rtl'
64
+ #nothing to do
65
+ elsif @book_type == "ltr"
66
+ book.page_progression_direction = 'ltr'
67
+ end
68
+
69
+ # within ordered block, add_item will be added to spine.
70
+ book.ordered {
71
+ # to add nav file:
72
+ #navpath = 'nav.xhtml'
73
+ #book.add_item(navpath).add_content(File.open(navpath)).add_property('nav')
74
+ Naturally.sort(Dir.glob('**/*.{jpg,png}')).each_with_index do |filepath,index|
75
+ MagicShelf.logger.info("append image #{filepath}, index: #{index}")
76
+ item = book.add_item(filepath)
77
+ item.add_content(File.open(filepath)).toc_text(index.to_s)
78
+ item.cover_image if index == 0
79
+ end
80
+ }
81
+
82
+ book.generate_epub(epubname)
83
+ end
84
+
85
+ end
86
+ end
@@ -0,0 +1,4 @@
1
+
2
+ module MagicShelf
3
+ class Error < StandardError; end
4
+ end
@@ -0,0 +1,105 @@
1
+ require 'magicshelf/exception'
2
+
3
+ module MagicShelf
4
+ class ExecutionPipe
5
+ class Procedure
6
+ attr_accessor :command_obj, :proc, :proc_withblock, :map_params, :params
7
+ def initialize
8
+ @command_obj = nil
9
+ @proc = nil
10
+ @proc_withblock = nil
11
+ @params = nil
12
+ @map_params = nil #from previous procedure
13
+ end
14
+ end
15
+
16
+ def initialize
17
+ @procedures = []
18
+ end
19
+
20
+ def pipe(command_obj, **map_params, &block)
21
+ procedure = Procedure.new()
22
+ block.call(command_obj)
23
+ procedure.command_obj = command_obj
24
+ procedure.map_params = map_params
25
+ @procedures.push(procedure)
26
+ self
27
+ end
28
+
29
+ def enter(**map_params, &block)
30
+ procedure = Procedure.new()
31
+ procedure.proc_withblock = block
32
+ procedure.map_params = map_params
33
+ @procedures.push(procedure)
34
+ self
35
+ end
36
+
37
+ def process(**map_params, &block)
38
+ procedure = Procedure.new()
39
+ procedure.proc = block
40
+ procedure.map_params = map_params
41
+ @procedures.push(procedure)
42
+ self
43
+ end
44
+
45
+ def execute
46
+ self.execute_(0)
47
+ end
48
+
49
+ def execute_(i_proc)
50
+ procedure = @procedures[i_proc]
51
+ previous_procedure = @procedures[i_proc-1]
52
+
53
+ if procedure.nil?
54
+ return
55
+ end
56
+
57
+ if not procedure.command_obj.nil?
58
+ if not previous_procedure.nil?
59
+ if not previous_procedure.command_obj.nil?
60
+ procedure.map_params.each_pair do |param_key_recv, param_keys|
61
+ param_keys.each do |param_key|
62
+ procedure.command_obj.instance_variable_set('@'+param_key.to_s, previous_procedure.command_obj.instance_variable_get('@'+param_key_recv.to_s))
63
+ end
64
+ end
65
+ else
66
+ procedure.map_params.each_pair do |param_key_recv, param_keys|
67
+ param_keys.each do |param_key|
68
+ procedure.command_obj.instance_variable_set('@'+param_key.to_s, previous_procedure.params[param_key_recv])
69
+ end
70
+ end
71
+ end
72
+ end
73
+ procedure.command_obj.enter {
74
+ procedure.command_obj.process
75
+ self.execute_(i_proc+1)
76
+ }
77
+ elsif not procedure.proc.nil? or not procedure.proc_withblock.nil?
78
+
79
+ procedure.params = {}
80
+ if not previous_procedure.command_obj.nil?
81
+ procedure.map_params.each_pair do |param_key_recv, param_keys|
82
+ param_keys.each do |param_key|
83
+ procedure.params[param_key] = previous_procedure.command_obj.instance_variable_get('@'+param_key_recv.to_s)
84
+ end
85
+ end
86
+ else
87
+ procedure.map_params.each_pair do |param_key_recv, param_keys|
88
+ param_keys.each do |param_key|
89
+ procedure.params[param_key] = previous_procedure.params[param_key_recv]
90
+ end
91
+ end
92
+ end
93
+
94
+ if not procedure.proc.nil?
95
+ procedure.proc.call(procedure.params)
96
+ self.execute_(i_proc+1)
97
+ else
98
+ procedure.proc_withblock.call(procedure.params) do
99
+ self.execute_(i_proc+1)
100
+ end
101
+ end
102
+ end
103
+ end
104
+ end
105
+ end