Merge branch 'master' into v2
This commit is contained in:
Коммит
5723e32710
|
@ -8,3 +8,7 @@ AllCops:
|
|||
|
||||
Performance:
|
||||
enabled: true
|
||||
|
||||
Style/FrozenStringLiteralComment:
|
||||
Exclude:
|
||||
- db/schema.rb
|
||||
|
|
4
Gemfile
4
Gemfile
|
@ -3,9 +3,10 @@
|
|||
source "https://rubygems.org"
|
||||
ruby "2.4.2"
|
||||
|
||||
gem "rails", "4.2.10"
|
||||
gem "rails", "~> 4.2.10"
|
||||
|
||||
gem "asciidoctor", ">=1.5.4"
|
||||
gem "elasticsearch", "2.0.2"
|
||||
gem "faraday"
|
||||
gem "faraday_middleware"
|
||||
gem "iso8601"
|
||||
|
@ -13,7 +14,6 @@ gem "octokit"
|
|||
gem "pg", "0.21.0"
|
||||
gem "puma"
|
||||
gem "tilt"
|
||||
gem "tire"
|
||||
|
||||
gem "diff-lcs"
|
||||
gem "json"
|
||||
|
|
102
Gemfile.lock
102
Gemfile.lock
|
@ -1,43 +1,42 @@
|
|||
GEM
|
||||
remote: https://rubygems.org/
|
||||
specs:
|
||||
actionmailer (4.2.10)
|
||||
actionpack (= 4.2.10)
|
||||
actionview (= 4.2.10)
|
||||
activejob (= 4.2.10)
|
||||
actionmailer (4.2.11)
|
||||
actionpack (= 4.2.11)
|
||||
actionview (= 4.2.11)
|
||||
activejob (= 4.2.11)
|
||||
mail (~> 2.5, >= 2.5.4)
|
||||
rails-dom-testing (~> 1.0, >= 1.0.5)
|
||||
actionpack (4.2.10)
|
||||
actionview (= 4.2.10)
|
||||
activesupport (= 4.2.10)
|
||||
actionpack (4.2.11)
|
||||
actionview (= 4.2.11)
|
||||
activesupport (= 4.2.11)
|
||||
rack (~> 1.6)
|
||||
rack-test (~> 0.6.2)
|
||||
rails-dom-testing (~> 1.0, >= 1.0.5)
|
||||
rails-html-sanitizer (~> 1.0, >= 1.0.2)
|
||||
actionview (4.2.10)
|
||||
activesupport (= 4.2.10)
|
||||
actionview (4.2.11)
|
||||
activesupport (= 4.2.11)
|
||||
builder (~> 3.1)
|
||||
erubis (~> 2.7.0)
|
||||
rails-dom-testing (~> 1.0, >= 1.0.5)
|
||||
rails-html-sanitizer (~> 1.0, >= 1.0.3)
|
||||
activejob (4.2.10)
|
||||
activesupport (= 4.2.10)
|
||||
activejob (4.2.11)
|
||||
activesupport (= 4.2.11)
|
||||
globalid (>= 0.3.0)
|
||||
activemodel (4.2.10)
|
||||
activesupport (= 4.2.10)
|
||||
activemodel (4.2.11)
|
||||
activesupport (= 4.2.11)
|
||||
builder (~> 3.1)
|
||||
activerecord (4.2.10)
|
||||
activemodel (= 4.2.10)
|
||||
activesupport (= 4.2.10)
|
||||
activerecord (4.2.11)
|
||||
activemodel (= 4.2.11)
|
||||
activesupport (= 4.2.11)
|
||||
arel (~> 6.0)
|
||||
activesupport (4.2.10)
|
||||
activesupport (4.2.11)
|
||||
i18n (~> 0.7)
|
||||
minitest (~> 5.1)
|
||||
thread_safe (~> 0.3, >= 0.3.4)
|
||||
tzinfo (~> 1.1)
|
||||
addressable (2.5.2)
|
||||
public_suffix (>= 2.0.2, < 4.0)
|
||||
ansi (1.5.0)
|
||||
arel (6.0.4)
|
||||
asciidoctor (1.5.6.1)
|
||||
ast (2.4.0)
|
||||
|
@ -61,12 +60,18 @@ GEM
|
|||
database_cleaner (1.6.2)
|
||||
debug_inspector (0.0.3)
|
||||
diff-lcs (1.3)
|
||||
domain_name (0.5.20170404)
|
||||
unf (>= 0.0.5, < 1.0.0)
|
||||
dotenv (2.2.1)
|
||||
dotenv-rails (2.2.1)
|
||||
dotenv (= 2.2.1)
|
||||
railties (>= 3.2, < 5.2)
|
||||
elasticsearch (2.0.2)
|
||||
elasticsearch-api (= 2.0.2)
|
||||
elasticsearch-transport (= 2.0.2)
|
||||
elasticsearch-api (2.0.2)
|
||||
multi_json
|
||||
elasticsearch-transport (2.0.2)
|
||||
faraday
|
||||
multi_json
|
||||
erubi (1.7.1)
|
||||
erubis (2.7.0)
|
||||
fabrication (2.20.1)
|
||||
|
@ -79,9 +84,6 @@ GEM
|
|||
globalid (0.4.1)
|
||||
activesupport (>= 4.2.0)
|
||||
hashdiff (0.3.7)
|
||||
hashr (0.0.22)
|
||||
http-cookie (1.0.3)
|
||||
domain_name (~> 0.5)
|
||||
i18n (0.9.5)
|
||||
concurrent-ruby (~> 1.0)
|
||||
iso8601 (0.10.1)
|
||||
|
@ -92,11 +94,10 @@ GEM
|
|||
loofah (2.2.3)
|
||||
crass (~> 1.0.2)
|
||||
nokogiri (>= 1.5.9)
|
||||
mail (2.7.0)
|
||||
mail (2.7.1)
|
||||
mini_mime (>= 0.1.1)
|
||||
method_source (0.9.0)
|
||||
mime-types (2.99.3)
|
||||
mini_mime (1.0.0)
|
||||
mini_mime (1.0.1)
|
||||
mini_portile2 (2.3.0)
|
||||
minitest (5.11.3)
|
||||
multi_json (1.13.1)
|
||||
|
@ -119,24 +120,22 @@ GEM
|
|||
pry (~> 0.10)
|
||||
public_suffix (3.0.2)
|
||||
puma (3.11.3)
|
||||
<<<<<<< HEAD
|
||||
rack (1.6.10)
|
||||
rack (1.6.11)
|
||||
rack-proxy (0.6.5)
|
||||
rack
|
||||
rack (1.6.11)
|
||||
rack-test (0.6.3)
|
||||
rack (>= 1.0)
|
||||
rack-timeout (0.4.2)
|
||||
rails (4.2.10)
|
||||
actionmailer (= 4.2.10)
|
||||
actionpack (= 4.2.10)
|
||||
actionview (= 4.2.10)
|
||||
activejob (= 4.2.10)
|
||||
activemodel (= 4.2.10)
|
||||
activerecord (= 4.2.10)
|
||||
activesupport (= 4.2.10)
|
||||
rails (4.2.11)
|
||||
actionmailer (= 4.2.11)
|
||||
actionpack (= 4.2.11)
|
||||
actionview (= 4.2.11)
|
||||
activejob (= 4.2.11)
|
||||
activemodel (= 4.2.11)
|
||||
activerecord (= 4.2.11)
|
||||
activesupport (= 4.2.11)
|
||||
bundler (>= 1.3.0, < 2.0)
|
||||
railties (= 4.2.10)
|
||||
railties (= 4.2.11)
|
||||
sprockets-rails
|
||||
rails-deprecated_sanitizer (1.0.3)
|
||||
activesupport (>= 4.2.0.alpha)
|
||||
|
@ -152,9 +151,9 @@ GEM
|
|||
rails_stdout_logging
|
||||
rails_serve_static_assets (0.0.5)
|
||||
rails_stdout_logging (0.0.5)
|
||||
railties (4.2.10)
|
||||
actionpack (= 4.2.10)
|
||||
activesupport (= 4.2.10)
|
||||
railties (4.2.11)
|
||||
actionpack (= 4.2.11)
|
||||
activesupport (= 4.2.11)
|
||||
rake (>= 0.8.7)
|
||||
thor (>= 0.18.1, < 2.0)
|
||||
rainbow (3.0.0)
|
||||
|
@ -177,10 +176,6 @@ GEM
|
|||
redis-store (>= 1.2, < 2)
|
||||
redis-store (1.4.1)
|
||||
redis (>= 2.2, < 5)
|
||||
rest-client (1.8.0)
|
||||
http-cookie (>= 1.0.2, < 2.0)
|
||||
mime-types (>= 1.16, < 3.0)
|
||||
netrc (~> 0.7)
|
||||
rspec-core (3.7.1)
|
||||
rspec-support (~> 3.7.0)
|
||||
rspec-expectations (3.7.0)
|
||||
|
@ -227,19 +222,8 @@ GEM
|
|||
thor (0.19.4)
|
||||
thread_safe (0.3.6)
|
||||
tilt (2.0.8)
|
||||
tire (0.6.2)
|
||||
activemodel (>= 3.0)
|
||||
activesupport
|
||||
ansi
|
||||
hashr (~> 0.0.19)
|
||||
multi_json (~> 1.3)
|
||||
rake
|
||||
rest-client (~> 1.6)
|
||||
tzinfo (1.2.5)
|
||||
thread_safe (~> 0.1)
|
||||
unf (0.1.4)
|
||||
unf_ext
|
||||
unf_ext (0.0.7.5)
|
||||
unicode-display_width (1.4.0)
|
||||
uniform_notifier (1.11.0)
|
||||
vcr (4.0.0)
|
||||
|
@ -265,6 +249,7 @@ DEPENDENCIES
|
|||
database_cleaner
|
||||
diff-lcs
|
||||
dotenv-rails
|
||||
elasticsearch (= 2.0.2)
|
||||
fabrication
|
||||
faraday
|
||||
faraday_middleware
|
||||
|
@ -279,7 +264,7 @@ DEPENDENCIES
|
|||
pry-byebug
|
||||
puma
|
||||
rack-timeout
|
||||
rails (= 4.2.10)
|
||||
rails (~> 4.2.10)
|
||||
rails-perftest
|
||||
rails_12factor
|
||||
redcarpet
|
||||
|
@ -290,7 +275,6 @@ DEPENDENCIES
|
|||
shoulda-matchers
|
||||
sqlite3
|
||||
tilt
|
||||
tire
|
||||
vcr
|
||||
webmock
|
||||
webpacker
|
||||
|
@ -300,4 +284,4 @@ RUBY VERSION
|
|||
ruby 2.4.2p198
|
||||
|
||||
BUNDLED WITH
|
||||
1.16.3
|
||||
1.17.1
|
||||
|
|
3
app.json
3
app.json
|
@ -19,9 +19,6 @@
|
|||
}
|
||||
},
|
||||
"formation": {
|
||||
"worker": {
|
||||
"quantity": 1
|
||||
},
|
||||
"web": {
|
||||
"quantity": 1
|
||||
}
|
||||
|
|
|
@ -46,10 +46,12 @@ ul.books-list {
|
|||
li {
|
||||
@include clearfix;
|
||||
padding-left: 125px;
|
||||
height: 150px;
|
||||
|
||||
img {
|
||||
float: left;
|
||||
width: 109px;
|
||||
max-height: 150px;
|
||||
margin-right: -125px;
|
||||
margin-left: -125px;
|
||||
border: solid 1px #b7b7b7;
|
||||
|
|
|
@ -55,16 +55,6 @@
|
|||
color: $font-color;
|
||||
transition-duration: 0s;
|
||||
|
||||
span.metadata {
|
||||
display: block;
|
||||
margin-top: -3px;
|
||||
margin-bottom: 3px;
|
||||
font-size: 11px;
|
||||
font-weight: normal;
|
||||
line-height: 1;
|
||||
color: $light-font-color;
|
||||
}
|
||||
|
||||
&:hover,
|
||||
&.highlight {
|
||||
color: #fff;
|
||||
|
|
|
@ -9,12 +9,14 @@ class SiteController < ApplicationController
|
|||
@subsection = ""
|
||||
end
|
||||
|
||||
# called when you start typing into search form
|
||||
def search
|
||||
@term = sname = params["search"].to_s.downcase
|
||||
@data = search_term(sname)
|
||||
render partial: "shared/search"
|
||||
end
|
||||
|
||||
# called when you submit your search
|
||||
def search_results
|
||||
@term = sname = params["search"].to_s.downcase
|
||||
data = search_term(sname, true)
|
||||
|
|
|
@ -46,17 +46,17 @@ class DocVersion < ApplicationRecord
|
|||
def index
|
||||
file = self.doc_file
|
||||
doc = self.doc
|
||||
data = {
|
||||
"id" => file.name,
|
||||
"type" => "doc",
|
||||
"name" => file.name,
|
||||
"blob_sha" => doc.blob_sha,
|
||||
"text" => doc.plain,
|
||||
}
|
||||
client = ElasticClient.instance
|
||||
|
||||
begin
|
||||
Tire.index ELASTIC_SEARCH_INDEX do
|
||||
store data
|
||||
end
|
||||
client.index index: ELASTIC_SEARCH_INDEX,
|
||||
type: "man_doc",
|
||||
id: file.name,
|
||||
body: {
|
||||
name: file.name,
|
||||
blob_sha: doc.blob_sha,
|
||||
text: doc.plain
|
||||
}
|
||||
rescue StandardError
|
||||
nil
|
||||
end
|
||||
|
|
|
@ -73,20 +73,20 @@ class Section < ApplicationRecord
|
|||
end
|
||||
|
||||
def index
|
||||
client = ElasticClient.instance
|
||||
|
||||
code = self.book.code
|
||||
data = {
|
||||
"id" => "#{code}---#{self.slug}",
|
||||
"type" => "book",
|
||||
"chapter" => self.chapter.title,
|
||||
"section" => self.title,
|
||||
"number" => self.cs_number,
|
||||
"lang" => code,
|
||||
"html" => self.html,
|
||||
}
|
||||
begin
|
||||
Tire.index ELASTIC_SEARCH_INDEX do
|
||||
store data
|
||||
end
|
||||
client.index index: ELASTIC_SEARCH_INDEX,
|
||||
type: "book",
|
||||
id: "#{code}---#{self.slug}",
|
||||
body: {
|
||||
chapter: self.chapter.title,
|
||||
section: self.title,
|
||||
number: self.cs_number,
|
||||
lang: code,
|
||||
html: self.html
|
||||
}
|
||||
rescue StandardError
|
||||
nil
|
||||
end
|
||||
|
|
|
@ -79,15 +79,17 @@ class DownloadService
|
|||
downloads = []
|
||||
releases = @octokit.releases(repository)
|
||||
|
||||
releases.each do |release|
|
||||
release.assets.each do |asset|
|
||||
downloads << [
|
||||
asset.name,
|
||||
asset.updated_at,
|
||||
asset.browser_download_url
|
||||
]
|
||||
end
|
||||
end
|
||||
releases
|
||||
.reject { |release| release.prerelease || release.draft }
|
||||
.each do |release|
|
||||
release.assets.each do |asset|
|
||||
downloads << [
|
||||
asset.name,
|
||||
asset.updated_at,
|
||||
asset.browser_download_url
|
||||
]
|
||||
end
|
||||
end
|
||||
|
||||
downloads
|
||||
end
|
||||
|
|
|
@ -5,20 +5,23 @@
|
|||
<option title="български език" data-locale="bg" value="bg" <%= "selected" if @book.code == "bg" %>>български език</option>
|
||||
<option title="Español" data-locale="es" value="es" <%= "selected" if @book.code == "es" %>>Español</option>
|
||||
<option title="Français" data-locale="fr" value="fr" <%= "selected" if @book.code == "fr" %>>Français</option>
|
||||
<option title="Ελληνικά" data-locale="gr" value="gr" <%= "selected" if @book.code == "gr" %>>Ελληνικά</option>
|
||||
<option title="日本語" data-locale="ja" value="ja" <%= "selected" if @book.code == "ja" %>>日本語</option>
|
||||
<option title="한국어" data-locale="ko" value="ko" <%= "selected" if @book.code == "ko" %>>한국어</option>
|
||||
<option title="Nederlands" data-locale="nl" value="nl" <%= "selected" if @book.code == "nl" %>>Nederlands</option>
|
||||
<option title="Русский" data-locale="ru" value="ru" <%= "selected" if @book.code == "ru" %>>Русский</option>
|
||||
<option title="Tagalog" data-locale="sl" value="sl" <%= "selected" if @book.code == "sl" %>>Slovenščina</option>
|
||||
<option title="Tagalog" data-locale="tl" value="tl" <%= "selected" if @book.code == "tl" %>>Tagalog</option>
|
||||
<option title="Українська" data-locale="uk" value="uk" <%= "selected" if @book.code == "uk" %>>Українська</option>
|
||||
<option title="简体中文" data-locale="zh" value="zh" <%= "selected" if @book.code == "zh" %>>简体中文</option>
|
||||
</optgroup>
|
||||
|
||||
<optgroup label="Partial translations">
|
||||
<option title="Čeština" data-locale="cs" value="cs" <%= "selected" if @book.code == "cs" %>>Čeština</option>
|
||||
<option title="Indonesian" data-locale="id" value="id" <%= "selected" if @book.code == "id" %>>Indonesian</option>
|
||||
<option title="Македонски" data-locale="mk" value="mk" <%= "selected" if @book.code == "mk" %>>Македонски</option>
|
||||
<option title="Polski" data-locale="pl" value="pl" <%= "selected" if @book.code == "pl" %>>Polski</option>
|
||||
<option title="Српски" data-locale="sr" value="sr" <%= "selected" if @book.code == "sr" %>>Српски</option>
|
||||
<option title="Tagalog" data-locale="tl" value="tl" <%= "selected" if @book.code == "tl" %>>Tagalog</option>
|
||||
<option title="Ўзбекча" data-locale="uz" value="uz" <%= "selected" if @book.code == "uz" %>>Ўзбекча</option>
|
||||
<option title="繁體中文" data-locale="zh-tw" value="zh-tw" <%= "selected" if @book.code == "zh-tw" %>>繁體中文</option>
|
||||
</optgroup>
|
||||
|
||||
|
@ -26,13 +29,12 @@
|
|||
<option title="Беларуская" data-locale="be" value="be" <%= "selected" if @book.code == "be" %>>Беларуская</option>
|
||||
<option title="Deutsch" data-locale="de" value="de" <%= "selected" if @book.code == "de" %>>Deutsch</option>
|
||||
<option title="فارسی" data-locale="fa" value="fa" dir="rtl" <%= "selected" if @book.code == "fa" %>>فارسی</option>
|
||||
<option title="Ελληνικά" data-locale="gr" value="gr" <%= "selected" if @book.code == "gr" %>>Ελληνικά</option>
|
||||
<option title="Indonesian" data-locale="id" value="id" <%= "selected" if @book.code == "id" %>>Indonesian</option>
|
||||
<option title="Italiano" data-locale="it" value="it" <%= "selected" if @book.code == "it" %>>Italiano</option>
|
||||
<option title="Македонски" data-locale="mk" value="mk" <%= "selected" if @book.code == "mk" %>>Македонски</option>
|
||||
<option title="Bahasa Melayu" data-locale="ms" value="ms" <%= "selected" if @book.code == "ms" %>>Bahasa Melayu</option>
|
||||
<option title="Português (Brasil)" data-locale="pt-br" value="pt-br" <%= "selected" if @book.code == "pt-br" %>>Português (Brasil)</option>
|
||||
<option title="Português (Portugal)" data-locale="pt-pt" value="pt-pt" <%= "selected" if @book.code == "pt-pt" %>>Português (Portugal)</option>
|
||||
<option title="Türkçe" data-locale="tr" value="tr" <%= "selected" if @book.code == "tr" %>>Türkçe</option>
|
||||
<option title="Ўзбекча" data-locale="uz" value="uz" <%= "selected" if @book.code == "uz" %>>Ўзбекча</option>
|
||||
</optgroup>
|
||||
</select>
|
||||
</form>
|
||||
|
|
|
@ -3,22 +3,21 @@
|
|||
<div class='column-left'>
|
||||
<ul class='books-list'>
|
||||
<li>
|
||||
<a href="/book"><img src="/images/progit2.png" width="107" height="141" /></a>
|
||||
<a href="/book"><img src="/images/progit2.png"/></a>
|
||||
<h4><a href="/book">Pro Git</a></h4>
|
||||
<p class='description'>
|
||||
By Scott Chacon and Ben Straub
|
||||
<img class="creative-commons" src="/images/creative-commons@2x.png" width="115" height="28" />
|
||||
</p>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://www.packtpub.com/application-development/mastering-git"><img src="https://d1ldz4te4covpm.cloudfront.net/sites/default/files/imagecache/ppv4_main_book_cover/3754OS_3537_Mastering%20Git_0.jpg" width="107"></a>
|
||||
<a href="https://www.packtpub.com/application-development/mastering-git"><img src="https://d1ldz4te4covpm.cloudfront.net/sites/default/files/imagecache/ppv4_main_book_cover/B03537_cover.png"></a>
|
||||
<h4><a href="https://www.packtpub.com/application-development/mastering-git">Mastering Git</a></h4>
|
||||
<p class='description'>
|
||||
By Jakub Narębski
|
||||
</p>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://www.manning.com/mcquaid/?a_aid=MikeMcQuaid&a_bid=5688bbf4"><img src="https://www.manning.com/mcquaid/mcquaid_cover150.jpg" width="107"></a>
|
||||
<a href="https://www.manning.com/mcquaid/?a_aid=MikeMcQuaid&a_bid=5688bbf4"><img src="https://www.manning.com/mcquaid/mcquaid_cover150.jpg"></a>
|
||||
<h4><a href="https://www.manning.com/mcquaid/?a_aid=MikeMcQuaid&a_bid=5688bbf4">Git in Practice</a></h4>
|
||||
<p class='description'>
|
||||
By Mike McQuaid
|
||||
|
@ -29,24 +28,23 @@
|
|||
<h4><a href="https://cbx33.github.io/gitt/">Git in the Trenches</a></h4>
|
||||
<p class='description'>
|
||||
By Peter Savage
|
||||
<img class="creative-commons" src="/images/creative-commons.png" />
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://www.packtpub.com/git-version-control-for-everyone/book"><img src="https://www.packtpub.com/sites/default/files/7522OS_mockupcover_bg_0.jpg" width="107"/></a>
|
||||
<a href="https://www.packtpub.com/git-version-control-for-everyone/book"><img src="https://www.packtpub.com/sites/default/files/7522OS_mockupcover_bg_0.jpg"/></a>
|
||||
<h4><a href="https://www.packtpub.com/git-version-control-for-everyone/book">Git: Version Control for Everyone</a></h4>
|
||||
<p class='description'>
|
||||
By Ravishankar Somasundaram
|
||||
</p>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://www.packtpub.com/application-development/git-essentials-second-edition"><img src="https://www.packtpub.com/sites/default/files/B06881.png" width="113"/></a>
|
||||
<a href="https://www.packtpub.com/application-development/git-essentials-second-edition"><img src="https://www.packtpub.com/sites/default/files/B06881.png"/></a>
|
||||
<h4><a href="https://www.packtpub.com/application-development/git-essentials-second-edition">Git Essentials - Second Edition</a></h4>
|
||||
<p class='description'>
|
||||
By Ferdinando Santacroce
|
||||
</p>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://www.amazon.com/dp/1789137543"><img src="https://www.packtpub.com/sites/default/files/B10764_MockupCover.png" width="113"/></a>
|
||||
<a href="https://www.amazon.com/dp/1789137543"><img src="https://www.packtpub.com/sites/default/files/B10764_MockupCover.png"/></a>
|
||||
<h4><a href="https://www.amazon.com/dp/1789137543">Git Version Control Cookbook - Second Edition</a></h4>
|
||||
<p class='description'>
|
||||
By Kenneth Geisshirt
|
||||
|
@ -57,48 +55,54 @@
|
|||
<div class='column-right'>
|
||||
<ul class='books-list'>
|
||||
<li>
|
||||
<a href="https://www.amazon.com/Version-Control-Git-collaborative-development/dp/0596520123"><img src="/images/books/version-control-with-git@2x.jpg" width="107" height="140" /></a>
|
||||
<a href="https://www.amazon.com/Version-Control-Git-collaborative-development/dp/0596520123"><img src="/images/books/version-control-with-git@2x.jpg"/></a>
|
||||
<h4><a href="https://www.amazon.com/Version-Control-Git-collaborative-development/dp/1449316387">Version Control with Git, 2nd ed.</a></h4>
|
||||
<p class='description'>
|
||||
By Jon Loeliger & Matthew McCullough
|
||||
</p>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://www.pragprog.com/titles/pg_git/pragmatic-guide-to-git"><img src="/images/books/pragmatic-guide-to-git@2x.jpg" width="107" height="162" /></a>
|
||||
<a href="https://www.pragprog.com/titles/pg_git/pragmatic-guide-to-git"><img src="/images/books/pragmatic-guide-to-git@2x.jpg"/></a>
|
||||
<h4><a href="https://www.pragprog.com/titles/pg_git/pragmatic-guide-to-git">Pragmatic Guide to Git</a></h4>
|
||||
<p class='description'>
|
||||
By Travis Swicegood
|
||||
</p>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://www.pragprog.com/titles/tsgit/pragmatic-version-control-using-git"><img src="/images/books/pragmatic-version-control@2x.jpg" width="107" height="128" /></a>
|
||||
<a href="https://www.pragprog.com/titles/tsgit/pragmatic-version-control-using-git"><img src="/images/books/pragmatic-version-control@2x.jpg"/></a>
|
||||
<h4><a href="https://www.pragprog.com/titles/tsgit/pragmatic-version-control-using-git">Pragmatic Version Control Using Git</a></h4>
|
||||
<p class='description'>
|
||||
By Travis Swicegood
|
||||
</p>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://github.com/pluralsight/git-internals-pdf/releases/download/v2.0/peepcode-git.pdf"><img src="/images/books/git-internals@2x.jpg" width="107" height="81" /></a>
|
||||
<a href="https://github.com/pluralsight/git-internals-pdf/releases/download/v2.0/peepcode-git.pdf"><img src="/images/books/git-internals@2x.jpg"/></a>
|
||||
<h4><a href="https://github.com/pluralsight/git-internals-pdf/releases/download/v2.0/peepcode-git.pdf">Git Internals Peepcode PDF</a></h4>
|
||||
<p class='description'>
|
||||
By Scott Chacon
|
||||
<img class="creative-commons" src="/images/creative-commons@2x.png" width="115" height="28" />
|
||||
</p>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://www.packtpub.com/application-development/git-version-control-cookbook"><img src="https://dgdsbygo8mp3h.cloudfront.net/sites/default/files/imagecache/ppv4_main_book_cover/8454OS_cov.jpg" width="107"></a>
|
||||
<a href="https://www.packtpub.com/application-development/git-version-control-cookbook"><img src="https://dgdsbygo8mp3h.cloudfront.net/sites/default/files/imagecache/ppv4_main_book_cover/8454OS_cov.jpg"></a>
|
||||
<h4><a href="https://www.packtpub.com/application-development/git-version-control-cookbook">Git Version Control Cookbook</a></h4>
|
||||
<p class='description'>
|
||||
By Aske Olsson and Rasmus Voss
|
||||
</p>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://www.manning.com/books/learn-git-in-a-month-of-lunches"><img src="https://www.manning.com/umali/umali_cover150.jpg" width="107"></a>
|
||||
<a href="https://www.manning.com/books/learn-git-in-a-month-of-lunches"><img src="https://www.manning.com/umali/umali_cover150.jpg"></a>
|
||||
<h4><a href="https://www.manning.com/books/learn-git-in-a-month-of-lunches">Learn Git in a Month of Lunches</a></h4>
|
||||
<p class='description'>
|
||||
By Rick Umali
|
||||
</p>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://www.packtpub.com/application-development/version-control-git-and-github"><img src="https://d1ldz4te4covpm.cloudfront.net/sites/default/files/imagecache/ppv4_main_book_cover/B12556_Lowres_Cover.png"></a>
|
||||
<h4><a href="https://www.packtpub.com/application-development/version-control-git-and-github">Version Control with Git and GitHub</a></h4>
|
||||
<p class='description'>
|
||||
By Alex Magana, Joseph Muli
|
||||
</p>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,62 +0,0 @@
|
|||
<p>
|
||||
This book is available in
|
||||
<a href="/book/en">English</a>.
|
||||
</p>
|
||||
<p>
|
||||
Full translation available in
|
||||
<table>
|
||||
<tr><td><a href="/book/bg">български език</a>,</td></tr>
|
||||
<tr><td><a href="/book/es">Español</a>,</td></tr>
|
||||
<tr><td><a href="/book/fr">Français</a>,</td></tr>
|
||||
<tr><td><a href="/book/ja">日本語</a>,</td></tr>
|
||||
<tr><td><a href="/book/ko">한국어</a>,</td></tr>
|
||||
<tr><td><a href="/book/nl">Nederlands</a>,</td></tr>
|
||||
<tr><td><a href="/book/ru">Русский</a>,</td></tr>
|
||||
<tr><td><a href="/book/uk">Українська</a></td></tr>
|
||||
<tr><td><a href="/book/zh">简体中文</a>,</td></tr>
|
||||
</table>
|
||||
</p>
|
||||
<p>
|
||||
Partial translations available in
|
||||
<table>
|
||||
<tr><td><a href="/book/cs">Čeština</a>,</td></tr>
|
||||
<tr><td><a href="/book/id">Indonesian</a>,</td></tr>
|
||||
<!-- <a href="/book/fi">Suomi</a>, -->
|
||||
<tr><td><a href="/book/pl">Polski</a>,</td></tr>
|
||||
<tr><td><a href="/book/sr">Српски</a>,</td></tr>
|
||||
<tr><td><a href="/book/tl">Tagalog</a>,</td></tr>
|
||||
<tr><td><a href="/book/zh-tw">繁體中文</a>,</td></tr>
|
||||
</table>
|
||||
</p>
|
||||
<p>
|
||||
Translations started for
|
||||
<table>
|
||||
<!-- <tr><td><a href="/book/ar">Arabic</a>,</td></tr>
|
||||
<a href="/book/az">Azərbaycan dili</a>, -->
|
||||
<tr><td><a href="/book/be">Беларуская</a>,</td></tr>
|
||||
<!-- <a href="/book/ca">Català</a>, -->
|
||||
<tr><td><a href="/book/de">Deutsch</a>,</td></tr>
|
||||
<!-- <a href="/book/eo">Esperanto</a>,
|
||||
<a href="/book/es-ni">Español (Nicaragua)</a>, -->
|
||||
<tr><td><a href="/book/fa" dir="rtl">فارسی</a>,</td></tr>
|
||||
<tr><td><a href="/book/gr">Ελληνικά</a>,</td></tr>
|
||||
<!-- <a href="/book/hi">हिन्दी</a>,
|
||||
<a href="/book/hu">Magyar</a>, -->
|
||||
<tr><td><a href="/book/it">Italiano</a>,</td></tr>
|
||||
<tr><td><a href="/book/mk">Македонски</a>,</td></tr>
|
||||
<!-- <a href="/book/no-nb">Norwegian Bokmål</a>, -->
|
||||
<tr><td><a href="/book/ms">Bahasa Melayu</a>,</td></tr>
|
||||
<tr><td><a href="/book/pl">Polski</a>,</td></tr>
|
||||
<tr><td><a href="/book/pt-br">Português (Brasil)</a>,</td></tr>
|
||||
<!-- <a href="/book/ro">Română</a>,
|
||||
<tr><td><a href="/book/th">ภาษาไทย</a>,</td></tr> -->
|
||||
<!-- <a href="/book/vi">Tiếng Việt</a>, -->
|
||||
<tr><td><a href="/book/tr">Türkçe</a>,</td></tr>
|
||||
<tr><td><a href="/book/uz/v2">Ўзбекча</a>.</td></tr>
|
||||
</table>
|
||||
</p>
|
||||
<hr class="sidebar"/>
|
||||
<p>
|
||||
The source of this book is <a href="https://github.com/progit/progit2">hosted on GitHub.</a></br>
|
||||
Patches, suggestions and comments are welcome.
|
||||
</p>
|
|
@ -17,7 +17,9 @@
|
|||
<%= stylesheet_pack_tag "index" %>
|
||||
</head>
|
||||
|
||||
<body class="sans-serif bg-tan dark-gray mw9 center page-body js-page-body" id="<%= @section %>">
|
||||
<body class="sans-serif bg-tan dark-gray mw9 center page-body js-page-body" id="<%= @section %>">
|
||||
|
||||
<div class="inner">
|
||||
<%= render partial: "shared/header" %>
|
||||
<div class="page-overlay">
|
||||
<main><%= yield %></main>
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<td class="matches">
|
||||
<ul>
|
||||
<li>
|
||||
<%= link_to "Show all results...", "/search/results?search=#{@term}" %>
|
||||
<a>Show all results...</a>
|
||||
</li>
|
||||
</ul>
|
||||
</td>
|
||||
|
@ -20,9 +20,6 @@
|
|||
<li>
|
||||
<%= link_to match[:url] do %>
|
||||
<%= match[:name] %>
|
||||
<% if match[:meta] %>
|
||||
<span class="metadata"> <%= match[:meta] %> </span>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</li>
|
||||
<% end %>
|
||||
|
|
|
@ -1,7 +1,15 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
Tire.configure do
|
||||
url (ENV["BONSAI_URL"] || "http://0.0.0.0:9200")
|
||||
class ElasticClient
|
||||
|
||||
@@instance = Elasticsearch::Client.new url: (ENV["BONSAI_URL"] || "http://0.0.0.0:9200"), log: false
|
||||
|
||||
def self.instance
|
||||
return @@instance
|
||||
end
|
||||
|
||||
private_class_method :new
|
||||
end
|
||||
|
||||
|
||||
ELASTIC_SEARCH_INDEX = "gitscm"
|
||||
|
|
|
@ -35,7 +35,7 @@ Rails.application.routes.draw do
|
|||
get "/ext" => redirect("/manual/ext")
|
||||
end
|
||||
|
||||
scope :docs do
|
||||
scope :docs, as: :docs do
|
||||
get "/" => redirect("/manuals")
|
||||
|
||||
get "/howto/:file", to: redirect { |path_params, _req|
|
||||
|
@ -113,9 +113,9 @@ Rails.application.routes.draw do
|
|||
end
|
||||
|
||||
get "/course/svn" => "site#svn"
|
||||
get "/sfc" => "site#sfc"
|
||||
get "/site" => "site#about"
|
||||
get "/trademark" => redirect("/about/trademark")
|
||||
get "/sfc" => "site#sfc"
|
||||
get "/site" => "site#about"
|
||||
get "/trademark" => redirect("/about/trademark")
|
||||
|
||||
get "/contributors" => redirect("https://github.com/git/git/graphs/contributors")
|
||||
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
# frozen_string_literal: true
|
||||
#
|
||||
# encoding: UTF-8
|
||||
# This file is auto-generated from the current state of the database. Instead
|
||||
# of editing this file, please use the migrations feature of Active Record to
|
||||
# incrementally modify your database, and then regenerate this schema definition.
|
||||
|
|
|
@ -1,271 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require "faraday"
|
||||
require "yajl"
|
||||
require "time"
|
||||
|
||||
module ElasticSearch
|
||||
class JSONResponse < Faraday::Response::Middleware
|
||||
def parse(body)
|
||||
Yajl.load body
|
||||
end
|
||||
end
|
||||
|
||||
class Error < StandardError
|
||||
end
|
||||
|
||||
def self.get_connection(server)
|
||||
return unless server
|
||||
|
||||
Faraday.new(url: server) do |builder|
|
||||
# TODO: add timeout middleware
|
||||
builder.request :json
|
||||
# builder.response :logger
|
||||
builder.use JSONResponse
|
||||
builder.adapter Faraday.default_adapter
|
||||
end
|
||||
end
|
||||
|
||||
def self.available?
|
||||
conn = get_connection
|
||||
resp = conn.get "/"
|
||||
resp.status == 200
|
||||
end
|
||||
|
||||
# Object to represent an ElasticSearch property mapping
|
||||
class PropertyMapping < Struct.new(:name, :type)
|
||||
end
|
||||
|
||||
# Object to represent an index in elasticsearch
|
||||
class Index
|
||||
def initialize(name, server)
|
||||
@name = name
|
||||
@server = server
|
||||
@conn = ElasticSearch.get_connection(server)
|
||||
end
|
||||
|
||||
# Some helpers for making REST calls to elasticsearch
|
||||
%w[ get post put delete head ].each do |method|
|
||||
class_eval <<-EOC, __FILE__, __LINE__
|
||||
def #{method}(*args, &blk)
|
||||
raise Error, "no connection" unless @conn
|
||||
resp = @conn.#{method}(*args, &blk)
|
||||
raise Error, "elasticsearch server is offline or not accepting requests" if resp.status == 0
|
||||
raise Error, resp.body['error'] if resp.body && resp.body['error']
|
||||
@last_resp = resp
|
||||
resp.body
|
||||
end
|
||||
EOC
|
||||
end
|
||||
|
||||
# Check if the index exists.
|
||||
#
|
||||
# Returns true if the index exists, false otherwise.
|
||||
def exists?
|
||||
get("/#{@name}/_status")["error"].nil?
|
||||
rescue ElasticSearch::Error
|
||||
false
|
||||
end
|
||||
|
||||
# Destroy the index.
|
||||
#
|
||||
# Returns a hash, the parsed response body from elasticsearch.
|
||||
def destroy
|
||||
delete "/#{@name}"
|
||||
end
|
||||
|
||||
# Clear all content from the index
|
||||
#
|
||||
# Returns a hash, the parsed response body from elasticsearch
|
||||
def clear
|
||||
delete "/#{@name}/_all"
|
||||
end
|
||||
|
||||
# Create the index.
|
||||
#
|
||||
# server - elasticsearch base URL
|
||||
# create_options - a hash of index creation options
|
||||
#
|
||||
# Returns a hash, the parsed response body from elasticsearch.
|
||||
def create(create_options = {})
|
||||
self.class.create @name, @server, create_options
|
||||
end
|
||||
|
||||
# Force a refresh of this index
|
||||
#
|
||||
# This basically tells elasticsearch to flush its buffers
|
||||
# but not clear caches (unlike a commit in Solr)
|
||||
# "Commits" happen automatically and are managed by elasticsearch
|
||||
#
|
||||
# Returns a hash, the parsed response body from elasticsearch
|
||||
def refresh
|
||||
post "/#{@name}/_refresh"
|
||||
end
|
||||
|
||||
def bulk(data)
|
||||
return if data.empty?
|
||||
body = post "/#{@name}/_bulk", data
|
||||
|
||||
raise Error, "bulk import got HTTP #{@last_resp.status} response" if @last_resp.status != 200
|
||||
end
|
||||
|
||||
# Grab a bunch of items from this index
|
||||
#
|
||||
# type - the type to pull from
|
||||
# ids - an Array of ids to fetch
|
||||
#
|
||||
# Returns a hash, the parsed response body from elasticsearch
|
||||
def mget(type, ids)
|
||||
get do |req|
|
||||
req.url "#{@name}/#{type}/_mget"
|
||||
req.body = {"ids" => ids}
|
||||
end
|
||||
end
|
||||
|
||||
# Grab all the items from this index
|
||||
#
|
||||
# type - the type to pull from
|
||||
#
|
||||
# Returns a hash, the parsed response body from elasticsearch
|
||||
def all(type)
|
||||
get do |req|
|
||||
req.url "#{@name}/#{type}/_search", "q" => "*"
|
||||
end
|
||||
end
|
||||
|
||||
# Search this index using a post body
|
||||
#
|
||||
# types - the type or types (comma-separated) to search
|
||||
# options - options hash for this search request
|
||||
#
|
||||
# Returns a hash, the parsed response body from elasticsearch
|
||||
def search(types, options)
|
||||
get do |req|
|
||||
req.url "#{@name}/#{types}/_search"
|
||||
req.body = options
|
||||
end
|
||||
end
|
||||
|
||||
# Search this index using a query string
|
||||
#
|
||||
# types - the type or types (comma-separated) to search
|
||||
# query - the search query string
|
||||
# options - options hash for this search request (optional)
|
||||
#
|
||||
# Returns a hash, the parsed response body from elasticsearch
|
||||
def query(types, query, options = {})
|
||||
query = {"q" => query} if query.is_a?(String)
|
||||
|
||||
get do |req|
|
||||
req.url "#{@name}/#{types}/_search", query.merge(options)
|
||||
req.body = options if options
|
||||
end
|
||||
end
|
||||
|
||||
# Count results using a query string
|
||||
#
|
||||
# types - the type or types (comma-separated) to search
|
||||
# query - the search query string
|
||||
# options - options hash for this search request (optional)
|
||||
#
|
||||
# Returns a hash, the parsed response body from elasticsearch
|
||||
def count(types, query = {}, options = nil)
|
||||
query = {"q" => query} if query.is_a?(String)
|
||||
|
||||
get do |req|
|
||||
req.url "#{@name}/#{types}/_count", query
|
||||
req.body = options if options
|
||||
end
|
||||
end
|
||||
|
||||
# Add a document to this index
|
||||
#
|
||||
# type - the type of this document
|
||||
# id - the unique identifier for this document
|
||||
# doc - the document to be indexed
|
||||
#
|
||||
# Returns a hash, the parsed response body from elasticsearch
|
||||
def add(type, id, doc, params = {})
|
||||
doc.each do |key, val|
|
||||
# make sure dates are in a consistent format for indexing
|
||||
doc[key] = val.iso8601 if val.respond_to?(:iso8601)
|
||||
end
|
||||
|
||||
put do |req|
|
||||
req.url "/#{@name}/#{type}/#{id}", params
|
||||
req.body = doc
|
||||
end
|
||||
end
|
||||
|
||||
# Remove a document from this index
|
||||
#
|
||||
# type - the type of document to be removed
|
||||
# id - the unique identifier of the document to be removed
|
||||
#
|
||||
# Returns a hash, the parsed response body from elasticsearch
|
||||
def remove(type, id)
|
||||
delete do |req|
|
||||
req.url "#{@name}/#{type}/#{id}"
|
||||
end
|
||||
end
|
||||
|
||||
# Remove a collection of documents matched by a query
|
||||
#
|
||||
# types - the type or types to query
|
||||
# options - the search options hash
|
||||
#
|
||||
# Returns a hash, the parsed response body from elasticsearch
|
||||
def remove_by_query(types, options)
|
||||
delete do |req|
|
||||
req.url "#{@name}/#{types}/_query"
|
||||
req.body = options
|
||||
end
|
||||
end
|
||||
|
||||
# Mapping for the specified type.
|
||||
#
|
||||
# type - type to get the mapping for
|
||||
#
|
||||
# Returns a hash, the mapping for the specified type
|
||||
def mapping(type)
|
||||
get do |req|
|
||||
req.url "#{@name}/#{type}/_mapping"
|
||||
end
|
||||
end
|
||||
|
||||
# Update ElasticSearch's mapping for the specified type
|
||||
#
|
||||
# type - type whose mapping we're updating
|
||||
# properties - array of PropertyMappings
|
||||
#
|
||||
# Returns a hash, the parsed response body from elasticsearch
|
||||
def update_mapping(type, *properties)
|
||||
properties_for_body = {}
|
||||
|
||||
properties.each do |property|
|
||||
properties_for_body[property.name] = { "type" => property.type }
|
||||
end
|
||||
|
||||
put do |req|
|
||||
req.url "#{@name}/#{type}/_mapping"
|
||||
req.body = { type => { "properties" => properties_for_body } }
|
||||
end
|
||||
end
|
||||
|
||||
# Create a new index in elasticsearch
|
||||
#
|
||||
# name - the name of the index to be created
|
||||
# server - URL for the connection
|
||||
# create_options - a hash of index creation options
|
||||
#
|
||||
# Returns a new ElasticSearch::Index instance
|
||||
def self.create(name, server, create_options = {})
|
||||
ElasticSearch.get_connection(server).put do |req|
|
||||
req.url "/#{name}"
|
||||
req.body = create_options
|
||||
end
|
||||
|
||||
new name, server
|
||||
end
|
||||
end
|
||||
end
|
|
@ -7,8 +7,12 @@ module Searchable
|
|||
|
||||
def self.search(keywords, options = {})
|
||||
|
||||
# TODO find more OOP solution
|
||||
# we should never look to search_type variable again here
|
||||
# nor when adding to index
|
||||
class_name = self.name.to_s.downcase
|
||||
search_type = (class_name == "section" ? "book" : "doc")
|
||||
search_type = (class_name == "section" ? "book" : "man_doc")
|
||||
|
||||
type_name = (search_type == "book" ? "section" : "name")
|
||||
category_name = (search_type == "book" ? "Book" : "Reference")
|
||||
format = (search_type == "book" ? "html" : "text")
|
||||
|
@ -34,25 +38,27 @@ module Searchable
|
|||
query_options["query"]["bool"]["should"] << { "term" => { format => keyword } }
|
||||
end
|
||||
|
||||
search = Tire::Search::Search.new(ELASTIC_SEARCH_INDEX, type: search_type, payload: query_options) rescue nil
|
||||
client = ElasticClient.instance
|
||||
search = client.search index: ELASTIC_SEARCH_INDEX, body: query_options rescue nil
|
||||
|
||||
if search
|
||||
ref_hits = []
|
||||
results = search.results rescue []
|
||||
results = search["hits"]["hits"] rescue []
|
||||
results.each do |result|
|
||||
name = result.section || result.chapter || result.name
|
||||
slug = result.id.gsub("---", "/")
|
||||
source = result["_source"]
|
||||
name = source["section"] || source["chapter"] || source["name"]
|
||||
slug = result["_id"].gsub("---", "/")
|
||||
highlight = if search_type == "book"
|
||||
result.highlight.html.first rescue nil
|
||||
result["highlight"]["html"].first rescue nil
|
||||
else
|
||||
result.highlight.text.first rescue nil
|
||||
result["highlight"]["text"].first rescue nil
|
||||
end
|
||||
hit = {
|
||||
name: name,
|
||||
score: result._score,
|
||||
score: result["_score"],
|
||||
highlight: highlight,
|
||||
url: (search_type == "book" ? "/book/#{slug}" : "/docs/#{name}")
|
||||
}
|
||||
hit[:meta] = result.meta if search_type == "book"
|
||||
ref_hits << hit
|
||||
end
|
||||
if ref_hits.size > 0
|
||||
|
|
|
@ -1,162 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require "redcarpet"
|
||||
require "octokit"
|
||||
require "digest/sha1"
|
||||
|
||||
# export GITBOOK_DIR=../../writing/progit/
|
||||
# bundle exec rake genbook GENLANG=en
|
||||
|
||||
SCRIPT_SHA = Digest::SHA1.hexdigest(File.open("lib/tasks/book.rake", "r").read)
|
||||
|
||||
def generate_pages(lang, chapter, content, sha)
|
||||
toc = {title: "", sections: []}
|
||||
|
||||
markdown = Redcarpet::Markdown.new(Redcarpet::Render::HTML, tables: true)
|
||||
|
||||
content.gsub! /(\n(\n\t([^\t\n]+)\t([^\t\n]+))+\n\n)/ do
|
||||
first_col=20
|
||||
$1.gsub /(\n?)\n\t([^\t\n]+)\t([^\t\n]+)/ do
|
||||
if $1=="\n"
|
||||
# This is the header, need to add the dash line
|
||||
$1 << "\n " << $2 << " "*(first_col-$2.length) + "| " << $3 <<
|
||||
"\n " << "-"*first_col << "|-" << "-"*$3.length
|
||||
else
|
||||
# Table row : format the first column as typewriter and align
|
||||
$1 << "\n `" << $2 << "`" + " "*(first_col-$2.length-2) + "| " << $3
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
raw = markdown.render(content)
|
||||
|
||||
if m = raw.match(/<h1(.*?)>(.*?)<\/h1>/)
|
||||
chapter_title = m[2]
|
||||
toc[:title] = chapter_title
|
||||
end
|
||||
|
||||
# replace images
|
||||
if images = raw.scan(/Insert (.*?).png/)
|
||||
images.each do |img|
|
||||
img = img.first
|
||||
real = "<center><img src=\"/figures/#{img}-tn.png\"></center><br/>"
|
||||
raw.gsub!(/Insert #{img}.png/, real)
|
||||
end
|
||||
end
|
||||
|
||||
# add anchors to h3s
|
||||
if subsec = raw.scan(/<h3>(.*?)<\/h3>/)
|
||||
subsec.each do |sub|
|
||||
sub = sub.first
|
||||
id = sub.gsub(" ", "-")
|
||||
raw.gsub!(/<h3>#{sub}<\/h3>/, "<h3 id=\"#{id}\"><a href=\"##{id}\">#{sub}</a></h3>")
|
||||
end
|
||||
end
|
||||
|
||||
# add a class to tables
|
||||
raw.gsub! /<table>/, "<table class='ref'>"
|
||||
|
||||
sections = raw.split("<h2")
|
||||
|
||||
section = 0
|
||||
# create book (if needed)
|
||||
book = Book.where(edition: 1, code: lang).first_or_create
|
||||
|
||||
# create chapter (if needed)
|
||||
schapter = book.chapters.where(number: chapter).first_or_create
|
||||
schapter.title = chapter_title.to_s
|
||||
schapter.sha = sha + SCRIPT_SHA
|
||||
schapter.save
|
||||
|
||||
schapter.destroy if sections.empty?
|
||||
|
||||
sections.each do |sec|
|
||||
|
||||
section_title = ""
|
||||
if section_match = sec.match(/>(.*?)<\/h2>/)
|
||||
section_title = section_match[1]
|
||||
toc[:sections] << [section, section_title]
|
||||
else
|
||||
toc[:sections] << [section, nil]
|
||||
end
|
||||
|
||||
full_title = section_match ? "#{chapter_title} #{section_title}" : chapter_title
|
||||
|
||||
html = ""
|
||||
if section_match
|
||||
sec = "<h2" + sec
|
||||
else
|
||||
html += "<h1>Chapter #{chapter}</h1>"
|
||||
end
|
||||
|
||||
html += sec
|
||||
|
||||
nav = '<div id="nav"><a href="[[nav-prev]]">prev</a> | <a href="[[nav-next]]">next</a></div>'
|
||||
html += nav
|
||||
|
||||
# create/update section
|
||||
csection = schapter.sections.where(number: section).first_or_create
|
||||
csection.title = section_title.to_s
|
||||
csection.html = html.to_s
|
||||
csection.save
|
||||
|
||||
puts "\t\t#{chapter}.#{section} : #{chapter_title} . #{section_title} - #{html.size}"
|
||||
|
||||
section += 1
|
||||
end
|
||||
schapter.sections.where("number >= #{section}").destroy_all
|
||||
toc
|
||||
end
|
||||
|
||||
namespace :book do
|
||||
desc "Update slug name"
|
||||
task update_slug: :environment do
|
||||
Book.includes(chapters: :sections).all.each do |book|
|
||||
book.sections.each do |section|
|
||||
section.set_slug
|
||||
section.save
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
desc "Generate the book html for the sites (Using Octokit gem)"
|
||||
task remote_genbook: :environment do
|
||||
@octokit = Octokit::Client.new(login: ENV["API_USER"], password: ENV["API_PASS"])
|
||||
repo = "progit/progit"
|
||||
book = {}
|
||||
blob_content = Hash.new do |blobs, sha|
|
||||
content = Base64.decode64(@octokit.blob(repo, sha, encoding: "base64").content)
|
||||
blobs[sha] = content.force_encoding("UTF-8")
|
||||
end
|
||||
repo_tree = @octokit.tree(repo, "HEAD", recursive: true)
|
||||
trees = repo_tree.tree.map { |tree| tree if tree.path =~ /\.markdown$/ }.compact
|
||||
trees.each do |tree|
|
||||
#tree = trees.first
|
||||
lang, section, chapter = tree.path.split("/")
|
||||
section_number = $1 if section =~ /^(\d+)/
|
||||
chapter_number = $1 if chapter =~ /chapter(\d+)\.markdown/
|
||||
|
||||
skip = false
|
||||
|
||||
if book = Book.where(edition: 1, code: lang).first
|
||||
c = book.chapters.where(number: chapter_number.to_i).first
|
||||
if c && (c.sha == (tree.sha + SCRIPT_SHA))
|
||||
skip = true
|
||||
end
|
||||
end
|
||||
|
||||
skip = true if chapter_number.to_i == 0
|
||||
skip = false if ENV["REGEN_ALL"]
|
||||
|
||||
puts "*** #{skip} #{tree.sha}- #{lang} - #{section} - #{chapter} - #{section_number}:#{chapter_number}"
|
||||
|
||||
if !skip
|
||||
#book[lang] ||= []
|
||||
content = blob_content[tree.sha]
|
||||
#book[lang] << {:sha => tree.sha, :section => section, :chapter => chapter, :blob => content}
|
||||
generate_pages(lang, chapter_number, content, tree.sha)
|
||||
end
|
||||
end
|
||||
#p book
|
||||
end
|
|
@ -1,4 +1,4 @@
|
|||
# frozen_string_literal: true
|
||||
# rubocop:disable Style/FrozenStringLiteralComment
|
||||
|
||||
require "nokogiri"
|
||||
require "octokit"
|
||||
|
@ -216,6 +216,7 @@ task remote_genbook2: :environment do
|
|||
"nl" => "progit/progit2-nl",
|
||||
"pl" => "progit2-pl/progit2-pl",
|
||||
"pt-br" => "progit2-pt-br/progit2",
|
||||
"pt-pt" => "progit2-pt-pt/progit2",
|
||||
"ru" => "progit/progit2-ru",
|
||||
"sl" => "progit/progit2-sl",
|
||||
"sr" => "progit/progit2-sr",
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# frozen_string_literal: true
|
||||
# rubocop:disable Style/FrozenStringLiteralComment
|
||||
|
||||
task :copy do
|
||||
puts "copying images"
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# frozen_string_literal: true
|
||||
# rubocop:disable Style/FrozenStringLiteralComment
|
||||
|
||||
desc "find newest mac and windows binary downloads"
|
||||
task downloads: %i[windows_downloads mac_downloads]
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# frozen_string_literal: true
|
||||
# rubocop:disable Style/FrozenStringLiteralComment
|
||||
|
||||
require "asciidoctor"
|
||||
require "octokit"
|
||||
|
|
|
@ -1,11 +1,15 @@
|
|||
# frozen_string_literal: true
|
||||
# rubocop:disable Style/FrozenStringLiteralComment
|
||||
|
||||
task search_clear: :environment do
|
||||
# BONSAI.clear
|
||||
Tire.index ELASTIC_SEARCH_INDEX do
|
||||
delete
|
||||
create
|
||||
client = ElasticClient.instance
|
||||
|
||||
if client.indices.exists? index: ELASTIC_SEARCH_INDEX
|
||||
client.indices.delete index: ELASTIC_SEARCH_INDEX
|
||||
end
|
||||
|
||||
client.indices.create index: ELASTIC_SEARCH_INDEX
|
||||
|
||||
end
|
||||
|
||||
task search_index: :environment do
|
||||
|
|
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 83 KiB |
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 231 KiB |
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 36 KiB |
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 105 KiB |
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 76 KiB |
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 190 KiB |
|
@ -146,6 +146,7 @@ guis:
|
|||
platforms:
|
||||
- Windows
|
||||
- Mac
|
||||
- Linux
|
||||
price: Free
|
||||
license: Proprietary
|
||||
order: 16
|
||||
|
@ -199,8 +200,8 @@ guis:
|
|||
- Windows
|
||||
- Mac
|
||||
- Linux
|
||||
price: Free for non-commercial use
|
||||
license: Proprietary
|
||||
price: Free
|
||||
license: MIT
|
||||
order: 22
|
||||
- name: Pocket Git
|
||||
url: http://pocketgit.com/
|
||||
|
@ -272,3 +273,27 @@ guis:
|
|||
price: "$99/user, $75 annual business sub, free eval"
|
||||
license: Proprietary
|
||||
order: 30
|
||||
- name: SnailGit
|
||||
url: https://langui.net/snailgit/
|
||||
image_tag: guis/snailgit@2x.png
|
||||
platforms:
|
||||
- Mac
|
||||
price: "$9.99 / Lite version"
|
||||
license: Proprietary
|
||||
order: 31
|
||||
- name: GitFinder
|
||||
url: https://gitfinder.com
|
||||
image_tag: guis/gitfinder@2x.png
|
||||
platforms:
|
||||
- Mac
|
||||
price: "$24.95"
|
||||
license: Proprietary
|
||||
order: 32
|
||||
- name: Gitfox
|
||||
url: https://www.gitfox.app
|
||||
image_tag: guis/gitfox@2x.png
|
||||
platforms:
|
||||
- Mac
|
||||
price: Free (Beta)
|
||||
license: Proprietary
|
||||
order: 33
|
||||
|
|
1
spec/fixtures/cassettes/DownloadService/mac/reaches_out_to_Sourceforge_for_releases.json
поставляемый
Normal file
1
spec/fixtures/cassettes/DownloadService/mac/reaches_out_to_Sourceforge_for_releases.json
поставляемый
Normal file
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
|
@ -7,6 +7,8 @@ RSpec.describe DownloadService do
|
|||
|
||||
context "windows", :vcr do
|
||||
before do
|
||||
mocked_version = Version.new(id: 0, name: "0.0.0", commit_sha: "sha", committed: Time.current, created_at: Time.current, updated_at: Time.current, vorder: Version.version_to_num("0.0.0"))
|
||||
allow(Version).to receive(:find_by).with(any_args).and_return(mocked_version)
|
||||
subject.download_windows_versions
|
||||
end
|
||||
|
||||
|
@ -14,29 +16,31 @@ RSpec.describe DownloadService do
|
|||
expect(WebMock).to have_requested(:get, "https://api.github.com/repos/git-for-windows/git/releases")
|
||||
end
|
||||
|
||||
skip "creates Downloads with a windows platform" do
|
||||
it "creates Downloads with a windows platform" do
|
||||
expect(Download.first.platform).to include("windows")
|
||||
end
|
||||
|
||||
skip "should have the correct download URL" do
|
||||
it "should have the correct download URL" do
|
||||
expect(Download.first.url).to include("https://github.com/git-for-windows/git/releases/download/")
|
||||
end
|
||||
end
|
||||
|
||||
context "mac", :vcr do
|
||||
before do
|
||||
mocked_version = Version.new(id: 0, name: "0.0.0", commit_sha: "sha", committed: Time.current, created_at: Time.current, updated_at: Time.current, vorder: Version.version_to_num("0.0.0"))
|
||||
allow(Version).to receive(:find_by).with(any_args).and_return(mocked_version)
|
||||
subject.download_mac_versions
|
||||
end
|
||||
|
||||
skip "reaches out to Sourceforge for releases" do
|
||||
it "reaches out to Sourceforge for releases" do
|
||||
expect(WebMock).to have_requested(:get, "https://sourceforge.net/projects/git-osx-installer/rss?limit=20")
|
||||
end
|
||||
|
||||
skip "creates Downloads with a mac platform" do
|
||||
it "creates Downloads with a mac platform" do
|
||||
expect(Download.first.platform).to eql("mac")
|
||||
end
|
||||
|
||||
skip "should have the correct download URL" do
|
||||
it "should have the correct download URL" do
|
||||
expect(Download.first.url).to include("https://sourceforge.net/projects/git-osx-installer/files/")
|
||||
end
|
||||
end
|
||||
|
|
1322
yarn.lock
1322
yarn.lock
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Загрузка…
Ссылка в новой задаче