diglossa 0.2.19
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.
- data/.gitignore +20 -0
- data/Gemfile +10 -0
- data/LICENSE.txt +22 -0
- data/README.md +64 -0
- data/Rakefile +7 -0
- data/bin/dg +5 -0
- data/diglossa.gemspec +37 -0
- data/lib/diglossa/classext.rb +25 -0
- data/lib/diglossa/cli.rb +133 -0
- data/lib/diglossa/parse.rb +188 -0
- data/lib/diglossa/remote.rb +123 -0
- data/lib/diglossa/version.rb +4 -0
- data/lib/diglossa.rb +13 -0
- data/spec/spec_helper.rb +20 -0
- metadata +126 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 michael
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
# Diglossa
|
2
|
+
|
3
|
+
Diglossa is a helper gem for diglossa.org-like libraries.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
|
8
|
+
Install it as:
|
9
|
+
|
10
|
+
$ gem install diglossa
|
11
|
+
|
12
|
+
## CLI Usage
|
13
|
+
|
14
|
+
After installing the diglossa gem, Diglossa is available from your command line using the <tt>dg</tt> command. To get a complete overview of possible options type:
|
15
|
+
|
16
|
+
dg help
|
17
|
+
|
18
|
+
The examples and descriptions below does not cover all the options available via the CLI. So remember to refer back to the <tt>dg help</tt> command.
|
19
|
+
|
20
|
+
Commands:
|
21
|
+
|
22
|
+
dg help [COMMAND] # Describe available commands or one specific command
|
23
|
+
dg author [NIC, push] # get author by NIC
|
24
|
+
|
25
|
+
book contents:
|
26
|
+
|
27
|
+
dg build [PATH] # parse BOOK by root PATH(.json/.yml) and build hash, ex: dg build "NT/Palama/Triads"
|
28
|
+
dg warns [PATH] # print errors and warns about BOOK by PATH
|
29
|
+
dg get [PATH/URL] # get BOOK tree by root path or url, i.e. "Greek/Plato/Dialogues" or "NT/Greek/Plat...
|
30
|
+
dg push [PATH] # builds, checks and pushes BOOK to couchdb by root PATH
|
31
|
+
|
32
|
+
texts (paragraphs):
|
33
|
+
|
34
|
+
dg gettexts [URL, delete] # get or delete! text docs by exact URL: dg gettexts "Psell/Chronographia/Part-1" N...
|
35
|
+
dg pushtexts [PATH] # parse texts for root PATH, ex: dg docs "NT/Palama/Triads"
|
36
|
+
|
37
|
+
|
38
|
+
|
39
|
+
## ToDo
|
40
|
+
|
41
|
+
dg library # library contents get/push
|
42
|
+
|
43
|
+
## Community
|
44
|
+
|
45
|
+
Join https://groups.google.com/forum/?fromgroups#!forum/diglossa mailing list
|
46
|
+
|
47
|
+
## Special Thanks
|
48
|
+
|
49
|
+
Diglossa was inspired by soca.gem by Aaron Quint which I used to work with. Many thanks.
|
50
|
+
|
51
|
+
|
52
|
+
## License
|
53
|
+
|
54
|
+
released under the GPL License.
|
55
|
+
|
56
|
+
## Contributing
|
57
|
+
|
58
|
+
In the spirit of free software, everyone is encouraged to help improve this project.
|
59
|
+
|
60
|
+
1. Fork it
|
61
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
62
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
63
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
64
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
data/bin/dg
ADDED
data/diglossa.gemspec
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'diglossa/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |gem|
|
7
|
+
gem.name = "diglossa"
|
8
|
+
gem.version = Diglossa::VERSION
|
9
|
+
gem.authors = ["michael"]
|
10
|
+
gem.email = ["m.bykov@gmail.com"]
|
11
|
+
gem.description = %q{Write a gem description}
|
12
|
+
gem.summary = %q{Write a gem summary}
|
13
|
+
gem.homepage = ""
|
14
|
+
|
15
|
+
gem.files = `git ls-files`.split($/)
|
16
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
17
|
+
gem.executables = ["dg"]
|
18
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
19
|
+
gem.require_paths = ["lib"]
|
20
|
+
|
21
|
+
#gem.add_development_dependency "redcarpet", "~> 1.17"
|
22
|
+
gem.add_development_dependency "yard", "~> 0.7.5"
|
23
|
+
|
24
|
+
gem.add_development_dependency "rspec-core", "~> 2.0"
|
25
|
+
gem.add_development_dependency "rspec-expectations", "~> 2.0"
|
26
|
+
gem.add_development_dependency "rr", "~> 1.0"
|
27
|
+
|
28
|
+
#gem.add_runtime_dependency(%q<json>, ["~> 1.7.5"])
|
29
|
+
#gem.add_runtime_dependency(%q<mime-types>, ["~> 1.16"])
|
30
|
+
#gem.add_runtime_dependency(%q<typhoeus>, ["~> 0.6.3"])
|
31
|
+
#gem.add_runtime_dependency(%q<rest-client>)
|
32
|
+
#gem.add_runtime_dependency(%q<thor>, ["~> 0.15"])
|
33
|
+
#gem.add_runtime_dependency(%q<uuidtools>, ["~> 2.1"])
|
34
|
+
# gem.add_runtime_dependency(%q<redcarpet>, ["~> 2.2.2"])
|
35
|
+
|
36
|
+
|
37
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
#module Diglossa
|
2
|
+
class String
|
3
|
+
|
4
|
+
def to_defis
|
5
|
+
self.gsub('_', '-').gsub(' ', '-')
|
6
|
+
end
|
7
|
+
|
8
|
+
def to_underscore
|
9
|
+
self.gsub(' ', '_').gsub('-', '_')
|
10
|
+
end
|
11
|
+
|
12
|
+
def to_space
|
13
|
+
self.gsub('_', ' ').gsub('-', ' ')
|
14
|
+
end
|
15
|
+
|
16
|
+
def to_url # aka path_to_url
|
17
|
+
self.split('/')[1..-1].join('/').to_defis
|
18
|
+
end
|
19
|
+
|
20
|
+
# end
|
21
|
+
end
|
22
|
+
|
23
|
+
# class ::String
|
24
|
+
# include Classext
|
25
|
+
# end
|
data/lib/diglossa/cli.rb
ADDED
@@ -0,0 +1,133 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require 'thor'
|
3
|
+
require 'thor/actions'
|
4
|
+
require 'uuidtools'
|
5
|
+
#require 'typhoeus'
|
6
|
+
require 'rest_client'
|
7
|
+
#require 'yaml'
|
8
|
+
require 'pp'
|
9
|
+
#require 'redcarpet'
|
10
|
+
|
11
|
+
module Diglossa
|
12
|
+
class CLI < ::Thor
|
13
|
+
include Thor::Actions
|
14
|
+
|
15
|
+
attr_accessor :appdir, :config_file, :debug
|
16
|
+
attr_reader :config
|
17
|
+
|
18
|
+
class_option "appdir",
|
19
|
+
:type => :string,
|
20
|
+
:banner => "set the application directory to work with. assumes the current directory"
|
21
|
+
|
22
|
+
|
23
|
+
default_task :help
|
24
|
+
|
25
|
+
|
26
|
+
desc 'get [PATH/URL]', 'get BOOK tree by root path or url, i.e. "Greek/Plato/Dialogues" or "NT/Greek/Plato/Dialogues" '
|
27
|
+
def get(path, env = 'default')
|
28
|
+
size = path.split("/").size
|
29
|
+
url = size < 3 ? path : path.to_url
|
30
|
+
resp = remote(env).get_book url
|
31
|
+
resp ? pp(resp) : say("no book by url #{url}", :red)
|
32
|
+
end
|
33
|
+
|
34
|
+
desc 'build [PATH]', 'parse BOOK by root PATH(.json/.yml) and build hash, ex: dg build "NT/Palama/Triads"'
|
35
|
+
def build(path = 'default', push = "book")
|
36
|
+
book = parse.build path, "book"
|
37
|
+
book ? pp(book) : say("can not build book by path #{path}", :red)
|
38
|
+
end
|
39
|
+
|
40
|
+
desc 'push [PATH]', 'builds, checks and pushes BOOK to couchdb by root PATH'
|
41
|
+
def push(path, env = 'default')
|
42
|
+
books = parse.build path, "book"
|
43
|
+
resp = remote(env).push_book books
|
44
|
+
resp ? pp(resp) : say("WARN: no book to push by #{path}", :red)
|
45
|
+
end
|
46
|
+
|
47
|
+
desc 'warns [PATH]', 'print errors and warns about BOOK by PATH'
|
48
|
+
def warns(path, env = 'default')
|
49
|
+
resp = parse.build path, "warns"
|
50
|
+
resp ? pp(resp) : say("WARN: no book to push by #{path}", :red)
|
51
|
+
end
|
52
|
+
|
53
|
+
desc 'pushtexts [PATH]', 'parse texts for root PATH, ex: dg docs "NT/Palama/Triads"'
|
54
|
+
def pushtexts(path = 'default')
|
55
|
+
fpaths = parse.build path, "docs"
|
56
|
+
fpaths ? pp(fpaths) : say("can not build texts by path #{path}", :red)
|
57
|
+
end
|
58
|
+
|
59
|
+
desc 'gettexts [URL, delete]', 'get or delete! text docs by exact URL: dg gettexts "Psell/Chronographia/Part-1" NB: defis'
|
60
|
+
def gettexts(url, delete=false, env = 'default') # 125037 rows
|
61
|
+
docs = remote(env).texts_get url
|
62
|
+
docs.empty? ? say("WARN: no docs by url: #{url}", :red) : pp(docs)
|
63
|
+
return unless delete == "delete!"
|
64
|
+
docs.each{|doc|doc["_deleted"] = true}
|
65
|
+
response = remote(env).push_docs docs
|
66
|
+
pp response
|
67
|
+
end
|
68
|
+
|
69
|
+
# choose seeds directory
|
70
|
+
desc 'author [NIC, push]', 'get author by NIC'
|
71
|
+
def author(nic, push=false, env = 'default')
|
72
|
+
response = remote(env).author nic
|
73
|
+
response.empty? ? say("WARN: no author #{nic}", :red) : pp(response)
|
74
|
+
return unless push
|
75
|
+
doc = parse.parse_author(nic)
|
76
|
+
dbdoc = response.find{|d|d["nic"] == nic}
|
77
|
+
if dbdoc
|
78
|
+
doc["_id"] = dbdoc["_id"]
|
79
|
+
doc["_rev"] = dbdoc["_rev"]
|
80
|
+
end
|
81
|
+
response = remote(env).push_docs doc
|
82
|
+
pp response
|
83
|
+
end
|
84
|
+
|
85
|
+
def initialize(*)
|
86
|
+
super
|
87
|
+
self.appdir = options[:appdir] || File.expand_path(Dir.pwd)
|
88
|
+
# self.config_file = options[:config]
|
89
|
+
# self.debug = options[:debug]
|
90
|
+
# if debug
|
91
|
+
# Soca.debug = true
|
92
|
+
# logger.level = Logger::DEBUG
|
93
|
+
# end
|
94
|
+
self.source_paths << File.expand_path(File.join(File.dirname(__FILE__), 'templates'))
|
95
|
+
end
|
96
|
+
|
97
|
+
# desc 'consts [ENV]', 'outputs the app CONSTS for the ENV'
|
98
|
+
# def consts(env = 'default')
|
99
|
+
# say DIGLOSSA::lib
|
100
|
+
# end
|
101
|
+
|
102
|
+
|
103
|
+
# desc 'blog [FILE]', 'parse blog FILE.en or FILE.ru'
|
104
|
+
# def blog(fname = 'default')
|
105
|
+
# parse.blog fname
|
106
|
+
# end
|
107
|
+
|
108
|
+
# desc 'get [URL]', 'get URL'
|
109
|
+
# def get(url, env = 'default')
|
110
|
+
# remote(env).get url
|
111
|
+
# end
|
112
|
+
|
113
|
+
# end
|
114
|
+
|
115
|
+
private
|
116
|
+
|
117
|
+
def remote(env)
|
118
|
+
Diglossa::Remote.new appdir, env #, config_file
|
119
|
+
rescue => e
|
120
|
+
say e.message, :red
|
121
|
+
exit
|
122
|
+
end
|
123
|
+
|
124
|
+
def parse
|
125
|
+
Diglossa::Parse.new appdir #, config_file
|
126
|
+
rescue => e
|
127
|
+
say e.message, :red
|
128
|
+
exit
|
129
|
+
end
|
130
|
+
|
131
|
+
|
132
|
+
end
|
133
|
+
end
|
@@ -0,0 +1,188 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'diglossa/remote'
|
4
|
+
#require 'remote'
|
5
|
+
|
6
|
+
module Diglossa
|
7
|
+
class Parse
|
8
|
+
attr_accessor :app_dir, :document, :root, :dbauthors, :author_nic, :nics, :locale, :rpp, :filepaths, :warns, :counter #, :config_path, :revision
|
9
|
+
attr_reader :config
|
10
|
+
|
11
|
+
def initialize(app_dir) #, config_path = nil)
|
12
|
+
self.app_dir = File.expand_path(app_dir) + '/'
|
13
|
+
@warns = {file:[], size:[]}
|
14
|
+
@counter = []
|
15
|
+
#load_couchapprc
|
16
|
+
end
|
17
|
+
|
18
|
+
def parse_author(nic)
|
19
|
+
# FIXME: поправить название, это чтение файла
|
20
|
+
fn = File.expand_path(File.join(app_dir, nic))
|
21
|
+
fullname = "#{fn}.json"
|
22
|
+
return nil unless File.exist?(fullname)
|
23
|
+
doc = YAML.load_file fullname
|
24
|
+
doc
|
25
|
+
end
|
26
|
+
|
27
|
+
|
28
|
+
def build root, push=false
|
29
|
+
# FIXME: Lib to .diglossarc
|
30
|
+
fn = File.expand_path(File.join(Diglossa::Lib, root))
|
31
|
+
fullname = File.exist?("#{fn}.json") ? "#{fn}.json" : File.exist?("#{fn}.yml") ? "#{fn}.yml" : false
|
32
|
+
return nil unless fullname
|
33
|
+
doc = fullname ? YAML.load_file(fullname) : "no .json or .yml file at #{root}"
|
34
|
+
@nics = doc["authors"]
|
35
|
+
remote = Diglossa::Remote.new(app_dir)
|
36
|
+
#puts "locales #{remote.config["locales"]}"
|
37
|
+
@rpp = {}
|
38
|
+
@dbauthors = remote.author(doc["authors"])
|
39
|
+
@author_nic = root.split("/")[1].downcase
|
40
|
+
#lang = root.split('/').first.downcase
|
41
|
+
@locale = "ru"
|
42
|
+
title = root.split("/").last # .gsub("_", " ")
|
43
|
+
if push == "book"
|
44
|
+
jsru = {isFolder:true, expand: true, children:[]}
|
45
|
+
jsen = {isFolder:true, expand: true, children:[]}
|
46
|
+
traverse jsru, doc["tree"], root, title do |path|
|
47
|
+
parallels path # cause of rpp, alas
|
48
|
+
end
|
49
|
+
@locale = "en"
|
50
|
+
traverse jsen, doc["tree"], root, title
|
51
|
+
[{type:"book", url:root.to_url, jstree:jsru, rpp:rpp, locale:"ru"},
|
52
|
+
{type:"book", url:root.to_url, jstree:jsen, rpp:rpp, locale:"en"}]
|
53
|
+
elsif push == "docs"
|
54
|
+
jsru = {url:root.to_url, isFolder:true, expand: true, children:[]}
|
55
|
+
traverse jsru, doc["tree"], root, title do |path|
|
56
|
+
parallels path, true
|
57
|
+
end
|
58
|
+
elsif push == "warns"
|
59
|
+
jsru = {url:root.to_url, isFolder:true, expand: true, children:[]}
|
60
|
+
traverse jsru, doc["tree"], root, title do |path|
|
61
|
+
parallels path
|
62
|
+
end
|
63
|
+
warns
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
private
|
68
|
+
|
69
|
+
def parallels path, push = false
|
70
|
+
remote = Diglossa::Remote.new(app_dir)
|
71
|
+
dpath = File.expand_path(File.join(Diglossa::Lib, path))
|
72
|
+
return if File.directory?(dpath)
|
73
|
+
@counter = []
|
74
|
+
docs = []
|
75
|
+
nics.each do |nic|
|
76
|
+
author = dbauthors.find{|a|a["nic"] == nic}
|
77
|
+
fpath = "#{dpath}.#{nic}"
|
78
|
+
unless File.exist?(fpath)
|
79
|
+
warns[:file].push fpath
|
80
|
+
next
|
81
|
+
end
|
82
|
+
docs += paragraphs(fpath, path.to_url, nic, author["lang"], push)
|
83
|
+
end
|
84
|
+
if push
|
85
|
+
puts "pushing #{docs.size} - #{path}"
|
86
|
+
remote.texts_push path.to_url, nics, docs
|
87
|
+
end
|
88
|
+
# some stupid heuristique for rpp
|
89
|
+
vol = docs.inject(0){|vol,doc| vol + doc[:text].size}
|
90
|
+
rows_per_page = vol == 0 ? 25 : (10000*(docs.size)/vol).round
|
91
|
+
rpp[path.to_url] = rows_per_page #.to_s
|
92
|
+
|
93
|
+
if (nics.size != counter.size) || (counter.uniq.size != 1)
|
94
|
+
warns[:size].push "#{path} - #{counter.inspect}"
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
def paragraphs fpath, url, nic, lang, push
|
99
|
+
docs = []
|
100
|
+
lines = File.readlines fpath
|
101
|
+
counter.push lines.size
|
102
|
+
lines.each do |line|
|
103
|
+
line.gsub!(/\s+/, " ").strip! #.gsub!("*", " *").gsub!(" /", "/")
|
104
|
+
next if line.empty?
|
105
|
+
docs << {type:'text', url:url, nic:nic, lang:lang, text:line}
|
106
|
+
end
|
107
|
+
docs.each_with_index.map{|doc, index| doc[:pos] = index; doc}
|
108
|
+
end
|
109
|
+
|
110
|
+
def parse_nics narrow = true, nics = nil
|
111
|
+
nics ||= @nics
|
112
|
+
authors = {}
|
113
|
+
nics.each do |nic|
|
114
|
+
next if narrow && nic == author_nic
|
115
|
+
dbauthor = dbauthors.find{|a| a["nic"] == nic}
|
116
|
+
hash = {:name=>dbauthor[locale], :lang=>dbauthor["lang"]}
|
117
|
+
hash["author"] = true if nic == author_nic
|
118
|
+
authors[nic] = hash
|
119
|
+
end
|
120
|
+
authors
|
121
|
+
end
|
122
|
+
|
123
|
+
def traverse(jstree, doc, path, title=fase, &blk)
|
124
|
+
case doc
|
125
|
+
when Hash
|
126
|
+
hash = {}
|
127
|
+
if doc["title"] == title
|
128
|
+
hash = jstree
|
129
|
+
@nics = doc["authors"] if doc["authors"]
|
130
|
+
hash["nics"] = parse_nics false
|
131
|
+
hash["title"] = doc[locale]
|
132
|
+
else
|
133
|
+
path += "/#{doc["title"].gsub(" ","_")}"
|
134
|
+
title = doc[locale]
|
135
|
+
@nics = doc["authors"] if doc["authors"]
|
136
|
+
authors = parse_nics nics
|
137
|
+
dir = doc["children"].nil?
|
138
|
+
hash = dir ? {url: path.to_url, title: title, nics: authors} : {url: path.to_url, title: title, isFolder: true, expand: true, children:[]}
|
139
|
+
jstree[:children].push hash unless doc["title"] == title
|
140
|
+
end
|
141
|
+
traverse(hash, doc["children"], path, title, &blk)
|
142
|
+
when Array
|
143
|
+
doc.each {|v| traverse(jstree, v, path, title, &blk) }
|
144
|
+
else
|
145
|
+
blk.call(path) if blk
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
# def print_warns
|
150
|
+
# unless warns_file.empty?
|
151
|
+
# puts "NO FILE: " # тут непонятка - при отключении paragraphs выводятся warnings, что не нужно
|
152
|
+
# pp warns_file
|
153
|
+
# end
|
154
|
+
# unless warns_size.empty?
|
155
|
+
# puts "NON EQUAL SIZES: "
|
156
|
+
# pp warns_size
|
157
|
+
# end
|
158
|
+
# end
|
159
|
+
|
160
|
+
|
161
|
+
|
162
|
+
|
163
|
+
def json fname # это для блога
|
164
|
+
#
|
165
|
+
document = {}
|
166
|
+
puts "building DOC fname: #{fname}"
|
167
|
+
puts "APDIR.self #{self.app_dir}"
|
168
|
+
puts "APDIR #{app_dir}"
|
169
|
+
path = File.expand_path(File.join(app_dir, fname))
|
170
|
+
puts "path #{path}"
|
171
|
+
uuid = UUIDTools::UUID.sha1_create UUIDTools::UUID_DNS_NAMESPACE, "#{fname}"
|
172
|
+
puts "_ID = #{path} - #{uuid}"
|
173
|
+
lines = File.readlines path
|
174
|
+
lines.reject!{|c|c.empty? || c == "\n"}
|
175
|
+
document[:_id] = uuid.to_s
|
176
|
+
document[:title] = lines.shift.strip
|
177
|
+
document[:tags] = lines.shift.strip.split(/[[:punct:]]| /).reject!{|c|c.empty?}
|
178
|
+
#markdown = Redcarpet::Markdown.new(Redcarpet::Render::HTML, :autolink => true, :space_after_headers => true)
|
179
|
+
#body = markdown.render lines.join("\n")
|
180
|
+
document[:body] = "body"
|
181
|
+
puts "----------"
|
182
|
+
pp document
|
183
|
+
document
|
184
|
+
end
|
185
|
+
|
186
|
+
|
187
|
+
end
|
188
|
+
end
|
@@ -0,0 +1,123 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
module Diglossa
|
3
|
+
class Remote
|
4
|
+
attr_accessor :app_dir, :env #, :document, :config_path, :revision
|
5
|
+
attr_reader :config
|
6
|
+
|
7
|
+
def initialize(app_dir, env = 'default') #, config_path = nil)
|
8
|
+
self.env = env
|
9
|
+
self.app_dir = File.expand_path(app_dir) + '/'
|
10
|
+
#self.config_path = config_path
|
11
|
+
#load_config
|
12
|
+
#load_couchapprc
|
13
|
+
load_diglossarc
|
14
|
+
end
|
15
|
+
|
16
|
+
# def config_path=(config_path)
|
17
|
+
# @config_path = config_path || File.join(app_dir, 'config.js')
|
18
|
+
# end
|
19
|
+
|
20
|
+
# def load_config
|
21
|
+
# if File.readable?(config_path)
|
22
|
+
# @config = JSON.parse(File.read(config_path))
|
23
|
+
# else
|
24
|
+
# raise "Could not find config at '#{config_path}'. Run `dg init`"
|
25
|
+
# end
|
26
|
+
# end
|
27
|
+
|
28
|
+
def load_diglossarc
|
29
|
+
# тут есть теперь "data-dir", но она нужна в parse, а не здесь. Как загружать один раз эту хрень?
|
30
|
+
@config ||= {}
|
31
|
+
@config = JSON.parse(File.read(File.join(app_dir, '.couchapprc')))
|
32
|
+
@config['couchapprc'] = JSON.parse(File.read(File.join(app_dir, '.couchapprc')))
|
33
|
+
end
|
34
|
+
|
35
|
+
def db_url
|
36
|
+
if env =~ /^https?\:\/\// # the env is actual a db_url
|
37
|
+
env
|
38
|
+
else
|
39
|
+
env_config = config['couchapprc']['env'][env]
|
40
|
+
raise "No such env: #{env}" unless env_config && env_config['db']
|
41
|
+
env_config['db']
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def author(nic = "abelard")
|
46
|
+
nics = nic.kind_of?(Array) ? nic : [nic]
|
47
|
+
path = "#{db_url}/_design/diglossa.coffee/_view/byAuthor?include_docs=true"
|
48
|
+
response = RestClient.post path, {"keys"=> nics}.to_json, :content_type => :json, :accept => :json
|
49
|
+
return "no authors with nics #{nics}" unless response.code == 200
|
50
|
+
authors = JSON.parse(response.body)["rows"].map{|r|r['doc']}
|
51
|
+
#pp authors
|
52
|
+
response.code == 200 ? authors : nil
|
53
|
+
end
|
54
|
+
|
55
|
+
def push_docs docs
|
56
|
+
docs = docs.kind_of?(Array) ? docs : [docs]
|
57
|
+
# http://stackoverflow.com/questions/4435538/ruby-rest-client-make-it-never-timeout
|
58
|
+
json = RestClient.post "#{db_url}/_bulk_docs", {"docs" => docs}.to_json, :content_type => :json, :accept => :json
|
59
|
+
JSON.parse(json)
|
60
|
+
end
|
61
|
+
|
62
|
+
def get_book url
|
63
|
+
locales = ["ru", "en"]
|
64
|
+
books = []
|
65
|
+
locales.each do |locale|
|
66
|
+
json = RestClient.get "#{db_url}/_design/diglossa.coffee/_view/byBook?key=%5B%22#{url}%22%2C%22#{locale}%22%5D&include_docs=true", :content_type => :json, :accept => :json
|
67
|
+
book = JSON.parse(json)['rows'][0]["doc"] rescue nil
|
68
|
+
books.push book
|
69
|
+
end
|
70
|
+
books
|
71
|
+
end
|
72
|
+
|
73
|
+
def push_book books
|
74
|
+
dbbooks = get_book books[0][:url]
|
75
|
+
unless dbbooks.compact.empty?
|
76
|
+
books.each_with_index do |book, index|
|
77
|
+
book["_id"] = dbbooks[index]["_id"]
|
78
|
+
book["_rev"] = dbbooks[index]["_rev"]
|
79
|
+
end
|
80
|
+
end
|
81
|
+
#pp books
|
82
|
+
push_docs books
|
83
|
+
end
|
84
|
+
|
85
|
+
def texts_get url
|
86
|
+
response = RestClient.get("#{db_url}/_design/diglossa.coffee/_view/byUrl?key=%22#{url}%22&include_docs=true")
|
87
|
+
JSON.parse(response)['rows'].map{|r|r['doc']} || []
|
88
|
+
end
|
89
|
+
|
90
|
+
def texts_delete url
|
91
|
+
dbdocs = texts_get url
|
92
|
+
return if dbdocs.empty?
|
93
|
+
dbdocs.each{|doc|doc["_deleted"] = true}
|
94
|
+
push_docs dbdocs
|
95
|
+
end
|
96
|
+
|
97
|
+
def texts_push url, nics, docs
|
98
|
+
dbdocs = texts_get url
|
99
|
+
if dbdocs.size == docs.size
|
100
|
+
docs.each_with_index do |doc, index|
|
101
|
+
doc["_id"] = dbdocs[index]["_id"]
|
102
|
+
doc["_rev"] = dbdocs[index]["_rev"]
|
103
|
+
end
|
104
|
+
else
|
105
|
+
texts_delete url
|
106
|
+
end
|
107
|
+
push_docs docs
|
108
|
+
end
|
109
|
+
|
110
|
+
def seeds(name = "authors", push = false)
|
111
|
+
path = "#{db_url}/_design/diglossa.coffee/_view/byAuthor?include_docs=true"
|
112
|
+
response = RestClient.get "#{db_url}/_design/diglossa.coffee/_view/byAuthor?key=%22#{path.to_url}%22&include_docs=true", :content_type => :json, :accept => :json
|
113
|
+
#JSON.parse( RestClient.get( "#{Diglossa::DBD}/_design/diglossa.coffee/_view/byAuthor?include_docs=true"))['rows'].map{|r|r['doc']} rescue nil
|
114
|
+
response = RestClient.post path, {"keys"=> nics}.to_json, :content_type => :json, :accept => :json
|
115
|
+
return "no authors with nics #{nics}" unless response.code == 200
|
116
|
+
authors = JSON.parse(response.body)["rows"].map{|r|r['doc']}
|
117
|
+
#pp authors
|
118
|
+
response.code == 200 ? authors : nil
|
119
|
+
end
|
120
|
+
|
121
|
+
|
122
|
+
end
|
123
|
+
end
|
data/lib/diglossa.rb
ADDED
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
# This file was generated by the `rspec --init` command. Conventionally, all
|
2
|
+
# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
|
3
|
+
# Require this file using `require "spec_helper"` to ensure that it is only
|
4
|
+
# loaded once.
|
5
|
+
#
|
6
|
+
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
|
7
|
+
RSpec.configure do |config|
|
8
|
+
config.treat_symbols_as_metadata_keys_with_true_values = true
|
9
|
+
config.run_all_when_everything_filtered = true
|
10
|
+
config.filter_run :focus
|
11
|
+
|
12
|
+
# Run specs in random order to surface order dependencies. If you find an
|
13
|
+
# order dependency and want to debug it, you can fix the order by providing
|
14
|
+
# the seed, which is printed after each run.
|
15
|
+
# --seed 1234
|
16
|
+
config.order = 'random'
|
17
|
+
|
18
|
+
config.mock_with :rr
|
19
|
+
|
20
|
+
end
|
metadata
ADDED
@@ -0,0 +1,126 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: diglossa
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.2.19
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- michael
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-05-22 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: yard
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 0.7.5
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 0.7.5
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: rspec-core
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ~>
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '2.0'
|
38
|
+
type: :development
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ~>
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '2.0'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: rspec-expectations
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ~>
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '2.0'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '2.0'
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: rr
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ~>
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '1.0'
|
70
|
+
type: :development
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ~>
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '1.0'
|
78
|
+
description: Write a gem description
|
79
|
+
email:
|
80
|
+
- m.bykov@gmail.com
|
81
|
+
executables:
|
82
|
+
- dg
|
83
|
+
extensions: []
|
84
|
+
extra_rdoc_files: []
|
85
|
+
files:
|
86
|
+
- .gitignore
|
87
|
+
- Gemfile
|
88
|
+
- LICENSE.txt
|
89
|
+
- README.md
|
90
|
+
- Rakefile
|
91
|
+
- bin/dg
|
92
|
+
- diglossa.gemspec
|
93
|
+
- lib/diglossa.rb
|
94
|
+
- lib/diglossa/classext.rb
|
95
|
+
- lib/diglossa/cli.rb
|
96
|
+
- lib/diglossa/parse.rb
|
97
|
+
- lib/diglossa/remote.rb
|
98
|
+
- lib/diglossa/version.rb
|
99
|
+
- spec/spec_helper.rb
|
100
|
+
homepage: ''
|
101
|
+
licenses: []
|
102
|
+
post_install_message:
|
103
|
+
rdoc_options: []
|
104
|
+
require_paths:
|
105
|
+
- lib
|
106
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
107
|
+
none: false
|
108
|
+
requirements:
|
109
|
+
- - ! '>='
|
110
|
+
- !ruby/object:Gem::Version
|
111
|
+
version: '0'
|
112
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
113
|
+
none: false
|
114
|
+
requirements:
|
115
|
+
- - ! '>='
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
requirements: []
|
119
|
+
rubyforge_project:
|
120
|
+
rubygems_version: 1.8.24
|
121
|
+
signing_key:
|
122
|
+
specification_version: 3
|
123
|
+
summary: Write a gem summary
|
124
|
+
test_files:
|
125
|
+
- spec/spec_helper.rb
|
126
|
+
has_rdoc:
|