script_ripper 0.1.1 → 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/workflow.yml +31 -0
- data/Gemfile.lock +4 -1
- data/README.md +58 -9
- data/bin/release +20 -0
- data/lib/script_ripper/cli.rb +6 -14
- data/lib/script_ripper/parser.rb +39 -11
- data/lib/script_ripper/script_writer.rb +6 -0
- data/lib/script_ripper/util.rb +15 -0
- data/lib/script_ripper/version.rb +1 -1
- metadata +8 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e87995a5227deec059bd902676dc876ab8d28679d7a9a935bf6226fd96f65f24
|
4
|
+
data.tar.gz: cdc950877b56524fd4b5a458016a018f065d33a17705e59c94101334cc5916cb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: dc1b7ab672c04339ed68236dd3b5dc076739d95d489366cae71b923a6034813c8b1dc2cc879de4854c5cc66229001a3164fa3f98a13c932cfd9a84104bdd4aa6
|
7
|
+
data.tar.gz: 6cbb76afffc5c87246b241d830ab1d7634d4055e0d6c608e30c9719c7312a183eef07cae37899615a1f1a9ee3ad37c1c60e8daba67d9d4db7bdbfa21a44b90c6
|
@@ -0,0 +1,31 @@
|
|
1
|
+
name: CI and CD
|
2
|
+
on:
|
3
|
+
- push
|
4
|
+
jobs:
|
5
|
+
ci:
|
6
|
+
runs-on: ubuntu-latest
|
7
|
+
steps:
|
8
|
+
- uses: actions/checkout@v3
|
9
|
+
- name: Set up Ruby
|
10
|
+
uses: ruby/setup-ruby@v1
|
11
|
+
- name: Install dependencies
|
12
|
+
run: bundle install
|
13
|
+
- name: Run tests
|
14
|
+
run: bundle exec rake
|
15
|
+
cd:
|
16
|
+
env:
|
17
|
+
GEM_HOST_API_KEY: ${{ secrets.GEM_HOST_API_KEY }}
|
18
|
+
if: startsWith(github.ref, 'refs/tags/v')
|
19
|
+
runs-on: ubuntu-latest
|
20
|
+
needs:
|
21
|
+
- ci
|
22
|
+
steps:
|
23
|
+
- uses: actions/checkout@v3
|
24
|
+
- name: Set up Ruby
|
25
|
+
uses: ruby/setup-ruby@v1
|
26
|
+
- name: Install dependencies
|
27
|
+
run: bundle install
|
28
|
+
- name: Build gem
|
29
|
+
run: bundle exec rake build
|
30
|
+
- name: Publish gem
|
31
|
+
run: gem push pkg/*.gem
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
script_ripper (0.
|
4
|
+
script_ripper (0.2.1)
|
5
5
|
nokogiri (~> 1.13)
|
6
6
|
|
7
7
|
GEM
|
@@ -22,6 +22,8 @@ GEM
|
|
22
22
|
mocha (1.14.0)
|
23
23
|
nokogiri (1.13.8-arm64-darwin)
|
24
24
|
racc (~> 1.4)
|
25
|
+
nokogiri (1.13.8-x86_64-linux)
|
26
|
+
racc (~> 1.4)
|
25
27
|
public_suffix (5.0.0)
|
26
28
|
racc (1.6.0)
|
27
29
|
rake (13.0.6)
|
@@ -36,6 +38,7 @@ GEM
|
|
36
38
|
|
37
39
|
PLATFORMS
|
38
40
|
arm64-darwin-21
|
41
|
+
x86_64-linux
|
39
42
|
|
40
43
|
DEPENDENCIES
|
41
44
|
bundler (~> 2.3)
|
data/README.md
CHANGED
@@ -8,18 +8,67 @@ Given a website like https://jellyfin.org/docs/general/administration/installing
|
|
8
8
|
Get a bash script like
|
9
9
|
|
10
10
|
```bash
|
11
|
+
#!/usr/bin/env bash
|
12
|
+
|
11
13
|
# https://jellyfin.org/docs/general/administration/installing.html
|
14
|
+
# Ubuntu
|
15
|
+
|
16
|
+
# Remove the old /etc/apt/sources.list.d/jellyfin.list file:
|
17
|
+
/etc/apt/sources.list.d/jellyfin.list
|
18
|
+
|
19
|
+
# Remove the old /etc/apt/sources.list.d/jellyfin.list file:
|
20
|
+
sudo rm /etc/apt/sources.list.d/jellyfin.list
|
21
|
+
|
22
|
+
# Install HTTPS transport for APT if you haven't already:
|
23
|
+
sudo apt install apt-transport-https
|
24
|
+
|
25
|
+
# Enable the Universe repository to obtain all the FFMpeg dependencies:
|
26
|
+
# If the above command fails you will need to install the following package software-properties-common.
|
27
|
+
# This can be achieved with the following command sudo apt-get install software-properties-common
|
28
|
+
sudo add-apt-repository universe
|
29
|
+
|
30
|
+
# If the above command fails you will need to install the following package software-properties-common.
|
31
|
+
# This can be achieved with the following command sudo apt-get install software-properties-common
|
32
|
+
sudo apt-get install software-properties-common
|
33
|
+
|
34
|
+
# Import the GPG signing key (signed by the Jellyfin Team):
|
35
|
+
curl -fsSL https://repo.jellyfin.org/ubuntu/jellyfin_team.gpg.key | sudo gpg --dearmor -o /etc/apt/trusted.gpg.d/debian-jellyfin.gpg
|
36
|
+
|
37
|
+
# Add a repository configuration at /etc/apt/sources.list.d/jellyfin.list:
|
38
|
+
/etc/apt/sources.list.d/jellyfin.list
|
39
|
+
|
40
|
+
# Add a repository configuration at /etc/apt/sources.list.d/jellyfin.list:
|
41
|
+
# Supported releases are bionic, cosmic, disco, eoan, and focal.
|
42
|
+
echo "deb [arch=$( dpkg --print-architecture )] https://repo.jellyfin.org/ubuntu $( lsb_release -c -s ) main" | sudo tee /etc/apt/sources.list.d/jellyfin.list
|
43
|
+
|
44
|
+
# Update APT repositories:
|
45
|
+
sudo apt update
|
46
|
+
|
47
|
+
# Install Jellyfin:
|
48
|
+
sudo apt install jellyfin
|
49
|
+
|
50
|
+
# Manage the Jellyfin system service with your tool of choice:
|
51
|
+
sudo service jellyfin status
|
52
|
+
sudo systemctl restart jellyfin
|
53
|
+
sudo /etc/init.d/jellyfin stop
|
54
|
+
|
55
|
+
# Enable the Universe repository to obtain all the FFMpeg dependencies, and update repositories:
|
56
|
+
sudo add-apt-repository universe
|
57
|
+
sudo apt update
|
58
|
+
|
59
|
+
# Install the required dependencies:
|
60
|
+
sudo apt install at libsqlite3-0 libfontconfig1 libfreetype6 libssl1.0.0
|
61
|
+
|
62
|
+
# Install the downloaded .deb packages:
|
63
|
+
sudo dpkg -i jellyfin_*.deb jellyfin-ffmpeg_*.deb
|
12
64
|
|
13
|
-
#
|
14
|
-
|
65
|
+
# Use apt to install any missing dependencies:
|
66
|
+
sudo apt -f install
|
15
67
|
|
16
|
-
#
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
mkdir /path/to/cache
|
21
|
-
docker volume create jellyfin-config
|
22
|
-
docker volume create jellyfin-cache
|
68
|
+
# Manage the Jellyfin system service with your tool of choice:
|
69
|
+
sudo service jellyfin status
|
70
|
+
sudo systemctl restart jellyfin
|
71
|
+
sudo /etc/init.d/jellyfin stop
|
23
72
|
```
|
24
73
|
|
25
74
|
## Installation
|
data/bin/release
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "script_ripper/version"
|
5
|
+
|
6
|
+
`bundle`
|
7
|
+
|
8
|
+
if `git branch --show-current`.chomp != "master"
|
9
|
+
$stderr.puts "You must be on the master branch to release a new version."
|
10
|
+
|
11
|
+
exit 1
|
12
|
+
end
|
13
|
+
|
14
|
+
if `git status -s`.length > 0
|
15
|
+
$stderr.puts "Please commit all changes first"
|
16
|
+
|
17
|
+
exit 1
|
18
|
+
end
|
19
|
+
|
20
|
+
puts `git tag -a v#{ScriptRipper::VERSION} -m "Release v#{ScriptRipper::VERSION}" && git push origin master --tags`
|
data/lib/script_ripper/cli.rb
CHANGED
@@ -3,9 +3,12 @@ require "optparse"
|
|
3
3
|
require "script_ripper/downloader"
|
4
4
|
require "script_ripper/parser"
|
5
5
|
require "script_ripper/script_writer"
|
6
|
+
require "script_ripper/util"
|
6
7
|
|
7
8
|
module ScriptRipper
|
8
9
|
class CLI
|
10
|
+
include Util
|
11
|
+
|
9
12
|
attr_reader :arguments, :options, :url, :group_name
|
10
13
|
|
11
14
|
def initialize(arguments = ARGV)
|
@@ -17,10 +20,10 @@ module ScriptRipper
|
|
17
20
|
parse_arguments!
|
18
21
|
|
19
22
|
content = Downloader.call(url)
|
20
|
-
code_blocks = Parser.call(content, group_by
|
23
|
+
code_blocks = Parser.call(content, group_by)
|
21
24
|
|
22
25
|
if code_blocks.is_a?(Hash)
|
23
|
-
ScriptWriter.call(code_blocks: code_blocks
|
26
|
+
ScriptWriter.call(code_blocks: code_blocks.fetch(group_name), from_url: url, group_name: group_name)
|
24
27
|
else
|
25
28
|
ScriptWriter.call(code_blocks: code_blocks, from_url: url)
|
26
29
|
end
|
@@ -47,7 +50,7 @@ module ScriptRipper
|
|
47
50
|
opts.on(
|
48
51
|
"-g GROUPBY",
|
49
52
|
"--group-by GROUPBY",
|
50
|
-
"Group by an element type
|
53
|
+
"Group by an element type, typically something like h2, h3, etc. Required if group_name is provided."
|
51
54
|
)
|
52
55
|
|
53
56
|
opts.on("-h", "--help", "Show this message")
|
@@ -79,16 +82,5 @@ module ScriptRipper
|
|
79
82
|
puts option_parser
|
80
83
|
exit 1
|
81
84
|
end
|
82
|
-
|
83
|
-
def present?(value)
|
84
|
-
return false if value.nil?
|
85
|
-
return false if value.respond_to?(:empty?) && value.empty?
|
86
|
-
|
87
|
-
true
|
88
|
-
end
|
89
|
-
|
90
|
-
def blank?(value)
|
91
|
-
!present?(value)
|
92
|
-
end
|
93
85
|
end
|
94
86
|
end
|
data/lib/script_ripper/parser.rb
CHANGED
@@ -1,8 +1,13 @@
|
|
1
1
|
require "nokogiri"
|
2
|
+
require "set"
|
3
|
+
|
2
4
|
require "script_ripper/code_block"
|
5
|
+
require "script_ripper/util"
|
3
6
|
|
4
7
|
module ScriptRipper
|
5
8
|
class Parser
|
9
|
+
include Util
|
10
|
+
|
6
11
|
attr_reader :contents
|
7
12
|
attr_reader :group_by
|
8
13
|
|
@@ -14,21 +19,36 @@ module ScriptRipper
|
|
14
19
|
def call
|
15
20
|
code_blocks = document.css("ol").map do |ordered_list|
|
16
21
|
ordered_list.css("li").map do |list_item|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
+
list_item.css("code").map do |code_element|
|
23
|
+
parent_p_element = find_p_parent(code_element)
|
24
|
+
if parent_p_element
|
25
|
+
# This means the code block is inside a <p/> element
|
26
|
+
CodeBlock.new(
|
27
|
+
description: parent_p_element.text,
|
28
|
+
code: code_element.text,
|
29
|
+
nokogiri_list_item: list_item
|
30
|
+
)
|
31
|
+
else
|
32
|
+
# This means the code block is preceded by zero or more <p/> elements
|
33
|
+
CodeBlock.new(
|
34
|
+
description: list_item.css("p").map(&:text).join("\n"),
|
35
|
+
code: code_element.text,
|
36
|
+
nokogiri_list_item: list_item
|
37
|
+
)
|
38
|
+
end
|
39
|
+
end
|
22
40
|
end
|
23
|
-
end.flatten.reject { |code_block|
|
41
|
+
end.flatten.reject { |code_block| blank?(code_block.code) }
|
24
42
|
|
25
|
-
return code_blocks if
|
43
|
+
return code_blocks if blank?(group_by)
|
26
44
|
|
27
45
|
{}.tap do |result|
|
28
46
|
code_blocks.each do |code_block|
|
29
47
|
grouping = find_previous_grouping_element(find_list_parent(code_block.nokogiri_list_item))
|
30
48
|
|
31
|
-
|
49
|
+
next if grouping.nil?
|
50
|
+
|
51
|
+
group_name = grouping.text
|
32
52
|
|
33
53
|
result[group_name] ||= []
|
34
54
|
result[group_name] << code_block
|
@@ -48,7 +68,7 @@ module ScriptRipper
|
|
48
68
|
previous_element = element&.previous_element
|
49
69
|
|
50
70
|
return nil if previous_element.nil?
|
51
|
-
return previous_element if
|
71
|
+
return previous_element if grouping_names.include?(previous_element.text)
|
52
72
|
|
53
73
|
find_previous_grouping_element(previous_element)
|
54
74
|
end
|
@@ -68,8 +88,16 @@ module ScriptRipper
|
|
68
88
|
@groupings ||= document.css(group_by)
|
69
89
|
end
|
70
90
|
|
71
|
-
def
|
72
|
-
@
|
91
|
+
def grouping_names
|
92
|
+
@grouping_names ||= Set.new(groupings.map(&:text))
|
93
|
+
end
|
94
|
+
|
95
|
+
def find_p_parent(element)
|
96
|
+
return nil if element == document.root
|
97
|
+
return nil if blank?(element)
|
98
|
+
return element if element.name == "p"
|
99
|
+
|
100
|
+
find_p_parent(element.parent)
|
73
101
|
end
|
74
102
|
end
|
75
103
|
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module ScriptRipper
|
2
|
+
module Util
|
3
|
+
def present?(value)
|
4
|
+
return false if value.nil?
|
5
|
+
return false if value.respond_to?(:empty?) && value.empty?
|
6
|
+
return false if value.respond_to?(:length) && value.length == 0
|
7
|
+
|
8
|
+
true
|
9
|
+
end
|
10
|
+
|
11
|
+
def blank?(value)
|
12
|
+
!present?(value)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
metadata
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: script_ripper
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dave Benvenuti
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
11
|
date: 2022-09-04 00:00:00.000000000 Z
|
@@ -122,7 +122,7 @@ dependencies:
|
|
122
122
|
- - "~>"
|
123
123
|
- !ruby/object:Gem::Version
|
124
124
|
version: '3.18'
|
125
|
-
description:
|
125
|
+
description:
|
126
126
|
email:
|
127
127
|
- davebenvenuti@gmail.com
|
128
128
|
executables:
|
@@ -131,6 +131,7 @@ extensions: []
|
|
131
131
|
extra_rdoc_files: []
|
132
132
|
files:
|
133
133
|
- ".editorconfig"
|
134
|
+
- ".github/workflows/workflow.yml"
|
134
135
|
- ".gitignore"
|
135
136
|
- ".ruby-version"
|
136
137
|
- ".travis.yml"
|
@@ -140,6 +141,7 @@ files:
|
|
140
141
|
- README.md
|
141
142
|
- Rakefile
|
142
143
|
- bin/console
|
144
|
+
- bin/release
|
143
145
|
- bin/setup
|
144
146
|
- exe/script_ripper
|
145
147
|
- lib/script_ripper.rb
|
@@ -148,6 +150,7 @@ files:
|
|
148
150
|
- lib/script_ripper/downloader.rb
|
149
151
|
- lib/script_ripper/parser.rb
|
150
152
|
- lib/script_ripper/script_writer.rb
|
153
|
+
- lib/script_ripper/util.rb
|
151
154
|
- lib/script_ripper/version.rb
|
152
155
|
- script_ripper.gemspec
|
153
156
|
homepage: https://github.com/davebenvenuti/script_ripper
|
@@ -156,7 +159,7 @@ licenses:
|
|
156
159
|
metadata:
|
157
160
|
homepage_uri: https://github.com/davebenvenuti/script_ripper
|
158
161
|
source_code_uri: https://github.com/davebenvenuti/script_ripper
|
159
|
-
post_install_message:
|
162
|
+
post_install_message:
|
160
163
|
rdoc_options: []
|
161
164
|
require_paths:
|
162
165
|
- lib
|
@@ -172,7 +175,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
172
175
|
version: '0'
|
173
176
|
requirements: []
|
174
177
|
rubygems_version: 3.3.7
|
175
|
-
signing_key:
|
178
|
+
signing_key:
|
176
179
|
specification_version: 4
|
177
180
|
summary: Rip shell scripts out of instructional web pages
|
178
181
|
test_files: []
|