teuton-get 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,70 @@
1
+ require_relative "../application"
2
+ require_relative "../writer/file_writer"
3
+ require_relative "../writer/terminal_writer"
4
+
5
+ class LocalRepo
6
+ def initialize(args)
7
+ @repoindex_writer = args[:repoindex_writer]
8
+ @dev = args[:progress_writer]
9
+ end
10
+
11
+ def self.new_by_default
12
+ LocalRepo.new(
13
+ repoindex_writer: FileWriter.new,
14
+ progress_writer: TerminalWriter.new
15
+ )
16
+ end
17
+
18
+ def create(dirpath)
19
+ infofilename = Application::INFOFILENAME
20
+ infofiles = Dir.glob(File.join(dirpath, "**", infofilename))
21
+ return if infofiles.size.zero?
22
+
23
+ @dev.writeln "\n==> Creating repository", color: :light_yellow
24
+ data = read_files(infofiles)
25
+
26
+ filepath = File.join(dirpath, Application::INDEXFILENAME)
27
+ @repoindex_writer.open(filepath)
28
+ @repoindex_writer.write data.to_yaml
29
+ @repoindex_writer.close
30
+
31
+ @dev.writeln " Created file #{filepath} with #{data.keys.size} tests.", color: :white
32
+ true
33
+ end
34
+
35
+ private
36
+
37
+ def read_files(infofiles)
38
+ data = {}
39
+ infofiles.each do |filepath|
40
+ cleanpath = filepath
41
+ if cleanpath.start_with? "./"
42
+ # delete 2 chars at the begining. Example: "./"
43
+ cleanpath[0, 2] = ""
44
+ end
45
+ infodata = LocalInfo.new(@dev).read(cleanpath)
46
+ dirpath = File.dirname(cleanpath)
47
+ data[dirpath] = infodata
48
+ end
49
+ data
50
+ end
51
+
52
+ def copyfile(target, dest)
53
+ if File.exist? dest
54
+ @dev.write " WARN: exits file "
55
+ @dev.writeln dest, color: :light_yellow
56
+ return true
57
+ end
58
+ begin
59
+ FileUtils.cp(target, dest)
60
+ @dev.write "===> Created file "
61
+ @dev.writeln dest, color: :light_green
62
+ true
63
+ rescue => e
64
+ @dev.write " ERROR: Creating file "
65
+ @dev.writeln dest, color: :light_red
66
+ puts e
67
+ false
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,92 @@
1
+ require "fileutils"
2
+ require_relative "../application"
3
+ require_relative "../reader/inifile_reader"
4
+ require_relative "../writer/terminal_writer"
5
+
6
+ class RepoConfig
7
+ attr_reader :data
8
+
9
+ def initialize(args)
10
+ @reader = args[:config_reader]
11
+ @data = @reader.read
12
+ @dev = args[:progress_writer]
13
+
14
+ @config_dirpath = args[:config_dirpath] || ""
15
+ @config_filepath = File.join(@config_dirpath, Application::CONFIGFILE)
16
+ end
17
+
18
+ def self.new_by_default
19
+ config_filepath = Application.instance.get(:config_filepath)
20
+
21
+ RepoConfig.new(
22
+ config_reader: IniFileReader.new(config_filepath),
23
+ progress_writer: TerminalWriter.new,
24
+ config_dirpath: Application.instance.get(:config_dirpath)
25
+ )
26
+ end
27
+
28
+ def create
29
+ @dev.writeln "\n==> Creating configuration files", color: :light_yellow
30
+ create_dir
31
+ create_ini_file
32
+ end
33
+
34
+ def show_list
35
+ rows = []
36
+ rows << ["E", "NAME", "DESCRIPTION"]
37
+ rows << :separator
38
+
39
+ @data.each_pair do |key, value|
40
+ enable = "\u{2714}"
41
+ enable = " " unless value["enable"]
42
+ description = value["description"] || "?"
43
+ rows << [enable, key, description]
44
+ end
45
+ @dev.writeln "Repository list"
46
+ @dev.write_table(rows)
47
+ @dev.write "Config: "
48
+ @dev.writeln "#{@reader.source}\n", color: :white
49
+ end
50
+
51
+ private
52
+
53
+ def create_dir
54
+ dirpath = @config_dirpath
55
+ if Dir.exist? dirpath
56
+ @dev.write " \u{2716} Exists dir! : "
57
+ @dev.writeln dirpath, color: :yellow
58
+ else
59
+ begin
60
+ FileUtils.mkdir_p(dirpath)
61
+ @dev.write " \u{2714} Create dir : "
62
+ @dev.writeln dirpath, color: :green
63
+ rescue => e
64
+ @dev.write " \u{2716} Create dir ERROR: "
65
+ @dev.writeln dirpath, color: :red
66
+ puts e
67
+ end
68
+ end
69
+ end
70
+
71
+ def create_ini_file
72
+ src = File.join(File.dirname(__FILE__), "..", "files", Application::CONFIGFILE)
73
+ copyfile(src, @config_filepath)
74
+ end
75
+
76
+ def copyfile(target, dest)
77
+ if File.exist? dest
78
+ @dev.write " \u{2716} Exists file! : "
79
+ @dev.writeln dest, color: :yellow
80
+ return true
81
+ end
82
+ begin
83
+ FileUtils.cp(target, dest)
84
+ @dev.write " \u{2714} Create file : "
85
+ @dev.writeln dest, color: :green
86
+ rescue => e
87
+ @dev.write " \u{2716} Create file ERROR: "
88
+ @dev.writeln dest, color: :red
89
+ puts e
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,126 @@
1
+ require "yaml"
2
+ require_relative "../application"
3
+ require_relative "../reader/url_reader"
4
+ require_relative "../reader/inifile_reader"
5
+ require_relative "../reader/yaml_reader"
6
+
7
+ class RepoData
8
+ attr_reader :data
9
+
10
+ def initialize(args)
11
+ @reader = args[:config_reader]
12
+ @data = @reader.read
13
+ @dev = args[:progress_writer]
14
+ @cache_dirpath = args[:cache_dirpath]
15
+ end
16
+
17
+ def self.new_by_default
18
+ config_filepath = Application.instance.get(:config_filepath)
19
+ RepoData.new(
20
+ config_reader: IniFileReader.new(config_filepath),
21
+ progress_writer: TerminalWriter.new,
22
+ cache_dirpath: Application.instance.get(:cache_dirpath)
23
+ )
24
+ end
25
+
26
+ def refresh
27
+ @database = {}
28
+ dirpath = @cache_dirpath
29
+ FileUtils.rm_r(dirpath) if Dir.exist? dirpath
30
+
31
+ @dev.writeln "\n==> Refreshing active repos", color: :light_yellow
32
+ @data.keys.sort.each do |key|
33
+ refresh_repo key
34
+ end
35
+ save_database
36
+ end
37
+
38
+ def get(test_id)
39
+ reponame, id = test_id.split(Application::SEPARATOR)
40
+ database = YamlReader.new.read(database_filename)
41
+ return {} if database[reponame].nil?
42
+ database[reponame][id]
43
+ end
44
+
45
+ def show_testinfo(item)
46
+ return unless item
47
+ @dev.writeln ""
48
+ ["name", "author", "date", "desc"].each do |key|
49
+ @dev.write "#{key.ljust(7)} : ", color: :white
50
+ @dev.writeln item[key].to_s
51
+ end
52
+ ["tags", "files"].each do |key|
53
+ next if item[key].nil?
54
+ @dev.write "#{key.ljust(7)} : ", color: :white
55
+ @dev.writeln item[key].join(", ")
56
+ end
57
+ end
58
+
59
+ def database_filename
60
+ # REVISE: Used by teutonget search... replace by #get()
61
+ File.join(@cache_dirpath, "database.yaml")
62
+ end
63
+
64
+ private
65
+
66
+ def refresh_repo(reponame)
67
+ unless enabled? reponame
68
+ @dev.writeln " \u{2716} Skiping repo #{reponame}"
69
+ return false
70
+ end
71
+ dirpath = File.join(@cache_dirpath)
72
+ ok1 = create_dir(dirpath)
73
+ ok2 = get_database(reponame)
74
+
75
+ @dev.writeln " \u{2714} Repo #{reponame} (#{ok2.size} tests)"
76
+
77
+ true && ok1 && ok2
78
+ end
79
+
80
+ def enabled?(reponame)
81
+ @data[reponame]["enable"] == true
82
+ end
83
+
84
+ def create_dir(dirpath)
85
+ unless Dir.exist? dirpath
86
+ begin
87
+ FileUtils.mkdir_p(dirpath)
88
+ return true
89
+ rescue => e
90
+ @dev.write "* Create dir ERROR => "
91
+ @dev.writeln dirpath, color: :red
92
+ puts e
93
+ return false
94
+ end
95
+ end
96
+ false
97
+ end
98
+
99
+ def get_database(reponame)
100
+ data = @data[reponame]
101
+
102
+ @database[reponame] = if data["URL"].start_with? "http"
103
+ get_remote_database(data["URL"])
104
+ else
105
+ get_local_database(data["URL"])
106
+ end
107
+ end
108
+
109
+ def get_local_database(dirpath)
110
+ filepath = File.join(dirpath, Application::INDEXFILENAME)
111
+ @reader.read(filepath)
112
+ end
113
+
114
+ def get_remote_database(url_repo)
115
+ url_file = "#{url_repo}/#{Application::INDEXFILENAME}"
116
+ content_page = URLReader.new(url_file).read
117
+ YAML.safe_load(
118
+ content_page,
119
+ permitted_classes: [Array, Date, Hash, Symbol]
120
+ )
121
+ end
122
+
123
+ def save_database
124
+ File.write(database_filename, @database.to_yaml)
125
+ end
126
+ end
@@ -0,0 +1,21 @@
1
+ require_relative "../application"
2
+
3
+ class Result
4
+ attr_accessor :score
5
+ attr_reader :reponame
6
+ attr_reader :testname
7
+
8
+ def initialize(args)
9
+ @score = args[:score] || 0
10
+ @reponame = args[:reponame] || "???"
11
+ @testname = args[:testname] || "???"
12
+ end
13
+
14
+ def id
15
+ "#{reponame}#{Application::SEPARATOR}#{testname}"
16
+ end
17
+
18
+ def to_h
19
+ {score: @score, id: id, reponame: @reponame, testname: @testname}
20
+ end
21
+ end
@@ -0,0 +1,142 @@
1
+ require_relative "application"
2
+ require_relative "reader/yaml_reader"
3
+ require_relative "repo/repo_data"
4
+ require_relative "searcher/result"
5
+ require_relative "writer/terminal_writer"
6
+
7
+ class Searcher
8
+ def initialize(args)
9
+ @dev = args[:writer]
10
+
11
+ @repodata = args[:repodata]
12
+ filename = @repodata.database_filename
13
+
14
+ @reader = args[:reader]
15
+ @database = @reader.read(filename)
16
+
17
+ @results = {}
18
+ end
19
+
20
+ def self.new_by_default
21
+ Searcher.new(
22
+ writer: TerminalWriter.new,
23
+ repodata: RepoData.new_by_default,
24
+ reader: YamlReader.new
25
+ )
26
+ end
27
+
28
+ def get(input)
29
+ reponame_filter, filters = parse_input(input)
30
+ search_inside(reponame_filter, filters)
31
+ end
32
+
33
+ def show(result)
34
+ @results.each do |i|
35
+ @dev.write "(x#{i[:score]}) ", color: :white
36
+ @dev.writeln "#{i[:reponame]}#{Application::SEPARATOR}#{i[:testname]}"
37
+ end
38
+ end
39
+
40
+ private
41
+
42
+ def parse_input(input)
43
+ reponame_filter = :all
44
+ filter = :all
45
+ options = input.split(Application::SEPARATOR)
46
+ if options.size == 1
47
+ reponame_filter = :all
48
+ filter = options[0]
49
+ elsif options[0] == ""
50
+ reponame_filter = :all
51
+ filter = options[1]
52
+ elsif options.size == 2
53
+ reponame_filter = options[0]
54
+ filter = options[1]
55
+ end
56
+ reponame_filter = :all if reponame_filter == "ALL"
57
+ filters = if filter == "ALL"
58
+ :all
59
+ else
60
+ filter.split(",")
61
+ end
62
+ [reponame_filter, filters]
63
+ end
64
+
65
+ def search_inside(reponame_filter, filters)
66
+ @results = {}
67
+ if reponame_filter == :all
68
+ @database.keys.each { |reponame| search_inside_repo(reponame, filters) }
69
+ else
70
+ @database.keys.each do |reponame|
71
+ search_inside_repo(reponame, filters) if reponame.include? reponame_filter
72
+ end
73
+ end
74
+ sort_results
75
+ end
76
+
77
+ def search_inside_repo(reponame, filters)
78
+ return if reponame != :all && @database[reponame].nil?
79
+
80
+ @database[reponame].each do |testname, data|
81
+ result = Result.new(
82
+ score: 0,
83
+ reponame: reponame,
84
+ testname: testname
85
+ )
86
+ if filters == :all
87
+ add_result(result)
88
+ next
89
+ end
90
+ score = 0
91
+ filters.each do |filter|
92
+ score += evaluate_test(
93
+ testname: testname,
94
+ data: data,
95
+ filter: filter
96
+ )
97
+ if score > 0
98
+ result.score = score
99
+ add_result result
100
+ end
101
+ end
102
+ end
103
+ end
104
+
105
+ def evaluate_test(args)
106
+ testname = args[:testname]
107
+ data = args[:data]
108
+ filter = args[:filter]
109
+
110
+ score = 0
111
+ data.each_pair do |key, value|
112
+ if value.instance_of? String
113
+ score += 1 if value.downcase.include? filter
114
+ elsif value.instance_of? Date
115
+ score += 1 if value.to_s.include? filter
116
+ elsif value.instance_of? Array
117
+ score += 1 if value.include? filter
118
+ end
119
+ end
120
+ score += 1 if testname.include? filter
121
+ score
122
+ end
123
+
124
+ def add_result(result)
125
+ key = result.id
126
+ if @results[key].nil?
127
+ @results[key] = result
128
+ return
129
+ end
130
+ @results[key].score += result.score
131
+ end
132
+
133
+ def sort_results
134
+ results = []
135
+ @results.each_pair { |key, value| results += [value.to_h] }
136
+
137
+ results.sort_by! do |i|
138
+ [(Application::MAGICNUMBER - i[:score]), i[:id]]
139
+ end
140
+ @results = results
141
+ end
142
+ end
@@ -0,0 +1,6 @@
1
+ module Version
2
+ NAME = "teuton-get"
3
+ EXECUTABLE = "teutonget"
4
+ VERSION = "0.1.0"
5
+ HOMEPAGE = "https://github.com/teuton-software/#{NAME}"
6
+ end
@@ -0,0 +1,19 @@
1
+ require_relative "writer"
2
+
3
+ class FileWriter < Writer
4
+ def open(filepath)
5
+ @file = File.open(filepath, "w")
6
+ end
7
+
8
+ def write(text)
9
+ @file.write text
10
+ end
11
+
12
+ def writeln(text)
13
+ @file.write text
14
+ end
15
+
16
+ def close
17
+ @file.close
18
+ end
19
+ end
@@ -0,0 +1,15 @@
1
+ require_relative "writer"
2
+
3
+ class NullWriter < Writer
4
+ def write(text = "", args = {})
5
+ # Nothing
6
+ end
7
+
8
+ def writeln(text = "", args = {})
9
+ # Nothing
10
+ end
11
+
12
+ def write_table(rows)
13
+ # Nothing
14
+ end
15
+ end
@@ -0,0 +1,20 @@
1
+ require "colorize"
2
+ require "tty-table"
3
+ require_relative "writer"
4
+
5
+ class TerminalWriter < Writer
6
+ def write(text = "", args = {})
7
+ color = args[:color] || :silver
8
+ print text.colorize(color)
9
+ end
10
+
11
+ def writeln(text = "", args = {})
12
+ write("#{text}\n", args)
13
+ end
14
+
15
+ def write_table(rows)
16
+ table = TTY::Table.new(rows)
17
+ # puts table.render(:basic)
18
+ puts table.render(:ascii)
19
+ end
20
+ end
@@ -0,0 +1,9 @@
1
+ class Writer
2
+ def write(data)
3
+ raise "Define method"
4
+ end
5
+
6
+ def writeln(data)
7
+ raise "Define method"
8
+ end
9
+ end
data/lib/teuton-get.rb ADDED
@@ -0,0 +1,45 @@
1
+ require_relative "teuton-get/repo/local_info"
2
+ require_relative "teuton-get/repo/local_repo"
3
+ require_relative "teuton-get/repo/repo_config"
4
+ require_relative "teuton-get/repo/repo_data"
5
+ require_relative "teuton-get/searcher"
6
+ require_relative "teuton-get/downloader"
7
+
8
+ module TeutonGet
9
+ def self.create_info(testpath)
10
+ LocalInfo.new.user_create(testpath)
11
+ end
12
+
13
+ def self.create_repo(dirpath)
14
+ LocalRepo.new_by_default.create(dirpath)
15
+ end
16
+
17
+ def self.init
18
+ RepoConfig.new_by_default.create
19
+ refresh # Auto repo refresh
20
+ end
21
+
22
+ def self.refresh
23
+ RepoData.new_by_default.refresh
24
+ end
25
+
26
+ def self.show_repo_list
27
+ RepoConfig.new_by_default.show_list
28
+ end
29
+
30
+ def self.show_info(test_id)
31
+ repo_data = RepoData.new_by_default
32
+ info = repo_data.get(test_id)
33
+ repo_data.show_testinfo(info) unless info == {}
34
+ end
35
+
36
+ def self.search(filter)
37
+ searcher = Searcher.new_by_default
38
+ result = searcher.get(filter)
39
+ searcher.show(result)
40
+ end
41
+
42
+ def self.download(test_id)
43
+ Downloader.new.run(test_id)
44
+ end
45
+ end