aniview 2.0.0 → 2.1.0
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.
- checksums.yaml +4 -4
- data/lib/aniview/interface/animeio/animefile.rb +4 -0
- data/lib/aniview/interface/animeio/animeio.rb +42 -17
- data/lib/aniview/interface/deluge/delugec.rb +1 -1
- data/lib/aniview/interface/mpv/mpvbridge.rb +14 -2
- data/lib/aniview/interface/pref/defaults.json +2 -2
- data/lib/aniview/interface/pref/pref.rb +117 -110
- data/lib/aniview/util/term.rb +32 -29
- data/lib/aniview/util/util.rb +5 -0
- data/lib/aniview/view/aiomenu.rb +7 -7
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2c5f585fc35515dc5a6a3711eeae7aa8e49fe85d
|
4
|
+
data.tar.gz: f63599d23c1cfc65641bbca8cd4c1b429671dadd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8aaa333dbd7d119f668807f5f2a471e8c74ced69ed5801d5b3f190319d035e56db4d12c272b1d2422d19c6767bc4c15d21f12b5f26bebbe8b1837b1a8bd26bea
|
7
|
+
data.tar.gz: cae32d83c6f162daa32704d3d56d188537031de31cc95ceb1acfd7890a483ea7e835293255d610c6997de87895d155472f77e73e0e4fde00377549844af0af18
|
@@ -9,19 +9,21 @@ module Aniview
|
|
9
9
|
include Aniview::Util
|
10
10
|
class AnimeIO
|
11
11
|
def initialize(pref, mpvbridge)
|
12
|
-
|
13
|
-
@mpvbridge
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
)
|
18
|
-
}
|
19
|
-
@watch_log_tag = "♪"
|
12
|
+
@pref = pref
|
13
|
+
@mpvbridge = mpvbridge
|
14
|
+
@empty_hash = make_empty_hash
|
15
|
+
@watch_log_tag = "♪"
|
16
|
+
@dir_last_modified = {}
|
20
17
|
|
21
18
|
self.load
|
22
19
|
index_anime
|
23
20
|
end
|
24
21
|
|
22
|
+
def make_empty_hash
|
23
|
+
af = AnimeFile.new("empty")
|
24
|
+
{AnimeSeries.new("empty", [af]) => [af]}
|
25
|
+
end
|
26
|
+
|
25
27
|
def save
|
26
28
|
@pref.set "local_anime", Util.encode_object(@@local_anime)
|
27
29
|
end
|
@@ -37,12 +39,29 @@ module Aniview
|
|
37
39
|
|
38
40
|
def index_anime(force: false, verbose: false)
|
39
41
|
ret = {}
|
42
|
+
made_changes = false
|
43
|
+
|
40
44
|
(@pref.get("anime_locations").split(":")).each { |dir|
|
41
45
|
|
42
|
-
dir
|
46
|
+
dir = @pref.parseDir dir
|
47
|
+
dir_mtime = File::Stat.new(dir).mtime
|
48
|
+
|
49
|
+
if @dir_last_modified.key? dir
|
50
|
+
if @dir_last_modified[dir] == dir_mtime
|
51
|
+
#puts "skipping"
|
52
|
+
next
|
53
|
+
else
|
54
|
+
@dir_last_modified[dir] = dir_mtime
|
55
|
+
end
|
56
|
+
else
|
57
|
+
@dir_last_modified.merge!(dir => dir_mtime)
|
58
|
+
end
|
59
|
+
|
60
|
+
# puts "not skipping..."
|
61
|
+
#p @dir_last_modified
|
43
62
|
|
44
63
|
files = Dir.glob("#{dir}*/*.{mkv,avi,mp4}") + Dir.glob("#{dir}/*.{mkv,avi,mp4}")
|
45
|
-
|
64
|
+
|
46
65
|
files.each { |file|
|
47
66
|
puts "indexing #{file}" if verbose
|
48
67
|
seen_this = false
|
@@ -56,6 +75,7 @@ module Aniview
|
|
56
75
|
next
|
57
76
|
end
|
58
77
|
end
|
78
|
+
made_changes = true
|
59
79
|
ret.merge!(
|
60
80
|
file => AnimeFile.new(
|
61
81
|
file,
|
@@ -69,14 +89,14 @@ module Aniview
|
|
69
89
|
else
|
70
90
|
@@local_anime = ret
|
71
91
|
end
|
72
|
-
|
92
|
+
|
73
93
|
pruned = {}
|
74
94
|
@@local_anime.each{ |a|
|
75
95
|
pruned.merge!(a[0] => a[1]) if File.exist? a[1].path
|
76
96
|
}
|
77
97
|
@@local_anime = pruned
|
78
|
-
|
79
|
-
self.save
|
98
|
+
puts "made changes" if made_changes
|
99
|
+
self.save if made_changes
|
80
100
|
end
|
81
101
|
|
82
102
|
#returns the parent directory of a file
|
@@ -100,11 +120,12 @@ module Aniview
|
|
100
120
|
this_parent = parent animefile.path
|
101
121
|
|
102
122
|
if this_parent != last_parent
|
123
|
+
sorted_subarray = subarray.sort_by { |a| a.title }
|
103
124
|
ret.merge!(
|
104
125
|
AnimeSeries.new(
|
105
126
|
last_parent,
|
106
|
-
|
107
|
-
) =>
|
127
|
+
sorted_subarray
|
128
|
+
) => sorted_subarray)
|
108
129
|
subarray = [animefile]
|
109
130
|
else
|
110
131
|
subarray << animefile
|
@@ -113,17 +134,20 @@ module Aniview
|
|
113
134
|
last_parent = this_parent
|
114
135
|
|
115
136
|
}
|
137
|
+
|
138
|
+
sorted_subarray = subarray.sort_by { |a| a.title }
|
116
139
|
ret.merge!(
|
117
140
|
AnimeSeries.new(
|
118
141
|
parent(sarr[sarr.length - 1].path),
|
119
|
-
|
120
|
-
) =>
|
142
|
+
sorted_subarray
|
143
|
+
) => sorted_subarray
|
121
144
|
)
|
122
145
|
return Hash[ret.sort_by{ |a| a[0].title}]
|
123
146
|
end
|
124
147
|
|
125
148
|
#return the difference of getAired and getWatched
|
126
149
|
def getUnwatched
|
150
|
+
index_anime
|
127
151
|
ret = []
|
128
152
|
#puts @@local_anime
|
129
153
|
@@local_anime.each{ |anime|
|
@@ -134,6 +158,7 @@ module Aniview
|
|
134
158
|
|
135
159
|
#return an AnimeFile array of all mkvs in any dir specified in $pref["dirs"]
|
136
160
|
def getAll
|
161
|
+
index_anime
|
137
162
|
return @@local_anime.values
|
138
163
|
end
|
139
164
|
|
@@ -7,25 +7,37 @@ module Aniview
|
|
7
7
|
include Aniview::Util
|
8
8
|
def initialize pref
|
9
9
|
@pref = pref
|
10
|
+
@mpv_enabled = true
|
10
11
|
connect
|
11
12
|
end
|
12
13
|
|
13
14
|
def quit!
|
14
|
-
@mpv.quit!
|
15
|
+
@mpv.quit! unless @mpv == nil
|
15
16
|
end
|
16
17
|
|
17
18
|
def connect
|
19
|
+
return unless @mpv_enabled
|
18
20
|
return unless @mpv == nil or @mpv.client.get_property("idle-active") == nil
|
19
|
-
@mpv =
|
21
|
+
@mpv = nil
|
22
|
+
@mpv_enabled = false
|
23
|
+
begin
|
24
|
+
@mpv = MPV::Session.new(user_args: @pref.get("mpv_args").split(" "))
|
25
|
+
rescue MPV::MPVNotAvailableError
|
26
|
+
rescue MPV::MPVUnsupportedFlagError
|
27
|
+
else
|
28
|
+
@mpv_enabled = true
|
29
|
+
end
|
20
30
|
end
|
21
31
|
|
22
32
|
def play file
|
33
|
+
return unless @mpv_enabled
|
23
34
|
connect
|
24
35
|
@playing_file = file
|
25
36
|
@mpv.client.command "loadfile", file.path
|
26
37
|
end
|
27
38
|
|
28
39
|
def playing?
|
40
|
+
return false unless @mpv_enabled
|
29
41
|
@mpv.client.get_property("time-pos") != nil
|
30
42
|
end
|
31
43
|
|
@@ -7,136 +7,143 @@ require_relative '../../view/color'
|
|
7
7
|
module Aniview
|
8
8
|
module Interface
|
9
9
|
class Pref
|
10
|
-
|
10
|
+
def initialize
|
11
11
|
|
12
|
-
|
13
|
-
|
12
|
+
@home = Dir.home
|
13
|
+
@conf = @home + "/.config/aniview"
|
14
14
|
|
15
|
-
|
16
|
-
|
17
|
-
|
15
|
+
File.open(File.join(File.dirname(__FILE__), "/validate.json"), "r") {
|
16
|
+
|f| @validate = JSON.parse(f.read)
|
17
|
+
}
|
18
18
|
|
19
|
-
|
19
|
+
FileUtils.mkdir_p(@conf) unless File.directory?(@conf)
|
20
20
|
|
21
|
-
|
21
|
+
@pref_file = @conf + "/aniview.json"
|
22
22
|
|
23
|
-
|
24
|
-
|
25
|
-
|
23
|
+
self.defaults if not File.exist?(@pref_file)
|
24
|
+
self.load
|
25
|
+
end
|
26
26
|
|
27
|
-
|
27
|
+
def parseDir path
|
28
28
|
path = path.gsub("$airing_dir", @pref["airing_dir"])
|
29
29
|
path = path.gsub("$conf_dir", @pref["conf_dir"])
|
30
|
-
|
30
|
+
path = path.gsub("~", Dir.home)
|
31
|
+
|
32
|
+
path += "/" if path[-1] != "/"
|
33
|
+
|
31
34
|
return path
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
35
|
+
end
|
36
|
+
|
37
|
+
def defaults(should_save:true)
|
38
|
+
File.open(File.join(File.dirname(__FILE__), "/defaults.json"), "r") {|f| @pref = JSON.parse(f.read)}
|
39
|
+
self.save if should_save
|
40
|
+
end
|
41
|
+
|
42
|
+
def set(s, val)
|
43
|
+
trail = [s] if s.class == String
|
44
|
+
trail = s if s.class == Array
|
45
|
+
if valpref(trail, val, @validate)
|
46
|
+
@pref = setpref(trail, val, @pref)
|
47
|
+
end
|
48
|
+
|
49
|
+
save
|
50
|
+
end
|
51
|
+
|
52
|
+
def setpref(trail, destination, map)
|
53
|
+
if trail.length == 1
|
54
|
+
map[trail[0]] = destination
|
55
|
+
return map
|
56
|
+
else
|
57
|
+
|
58
|
+
blaze = trail[0]
|
59
|
+
map[blaze] = setpref(trail[1..-1], destination, map[blaze])
|
60
|
+
|
61
|
+
end
|
62
|
+
return map
|
63
|
+
end
|
64
|
+
|
65
|
+
def valpref(trail, destination, map)
|
66
|
+
|
67
|
+
if trail.length == 1
|
68
|
+
skeys = [
|
69
|
+
"space",
|
70
|
+
"up",
|
71
|
+
"down",
|
72
|
+
"left",
|
73
|
+
"right",
|
74
|
+
"enter"
|
75
|
+
]
|
76
|
+
|
77
|
+
case map[trail[0]]
|
78
|
+
when "key"
|
79
|
+
return false if destination.length != 1 and not skeys.include? destination
|
80
|
+
|
81
|
+
when "path"
|
82
|
+
destination.split(":").each { |d|
|
80
83
|
return false if not Dir.exist?(parseDir d)
|
81
84
|
}
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
85
|
+
|
86
|
+
when "color"
|
87
|
+
return false if not Aniview::View::Color.respond_to? destination
|
88
|
+
|
89
|
+
when "int"
|
90
|
+
return false if not destination.scan(/\D/).empty? and destination.length > 1
|
88
91
|
|
89
92
|
when "locked"
|
90
93
|
return false
|
91
94
|
|
92
|
-
|
95
|
+
end
|
93
96
|
|
94
|
-
|
97
|
+
return true
|
95
98
|
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
99
|
+
else
|
100
|
+
blaze = trail[0]
|
101
|
+
return valpref(trail[1..-1], destination, map[blaze])
|
102
|
+
end
|
103
|
+
end
|
101
104
|
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
+
def get s
|
106
|
+
return @pref[s] if @pref.key?(s)
|
107
|
+
end
|
105
108
|
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
+
def getAll
|
110
|
+
ignore = {
|
111
|
+
"local_anime" => true,
|
109
112
|
"schedule" => true,
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
113
|
+
}
|
114
|
+
|
115
|
+
r = {}
|
116
|
+
@pref.each{ |item|
|
117
|
+
next if ignore.key? item[0]
|
118
|
+
title = item[0]
|
119
|
+
if item[1].class == String
|
120
|
+
val = item[1]
|
121
|
+
elsif item[1].class == Array
|
122
|
+
val = item[1].join(":")
|
123
|
+
elsif item[1].class == Hash
|
124
|
+
item[1].each { |subitem|
|
125
|
+
subtitle = title + "_" + subitem[0]
|
126
|
+
subval = subitem[1]
|
127
|
+
r.merge!(PrefItem.new(subtitle, subval, []) => [PrefItem.new("", "", [item[0], subitem[0]])])
|
128
|
+
}
|
129
|
+
next
|
130
|
+
end
|
131
|
+
r.merge!(PrefItem.new(title, val, []) => [ PrefItem.new("", "", [item[0]]) ] )
|
132
|
+
}
|
133
|
+
return r
|
134
|
+
end
|
135
|
+
|
136
|
+
def save
|
137
|
+
File.open(@pref_file, "w") { |f| f.write(JSON.pretty_generate(@pref)) }
|
138
|
+
end
|
139
|
+
|
140
|
+
def load
|
141
|
+
begin
|
142
|
+
File.open(@pref_file, "r") {|f| @pref = JSON.parse(f.read)}
|
143
|
+
#rescue JSON::ParserError
|
144
|
+
#defaults should_save: false
|
145
|
+
end
|
146
|
+
end
|
140
147
|
end
|
141
148
|
end
|
142
149
|
end
|
data/lib/aniview/util/term.rb
CHANGED
@@ -1,39 +1,42 @@
|
|
1
1
|
module Aniview
|
2
2
|
module Util
|
3
3
|
class Term
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
4
|
+
def initialize
|
5
|
+
@tput=Hash[
|
6
|
+
"smcup" => %x(tput smcup),
|
7
|
+
"rmcup" => %x(tput rmcup),
|
8
|
+
"civis" => %x(tput civis),
|
9
|
+
"cnorm" => %x(tput cnorm),
|
10
|
+
"el1" => "\e[2K",
|
11
|
+
"bold" => %x(tput bold),
|
12
|
+
"nobold" => %x(tput sgr0),
|
13
|
+
]
|
14
|
+
end
|
15
15
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
16
|
+
def save; print @tput["smcup"]; return self; end
|
17
|
+
def restore; print @tput["rmcup"]; return self; end
|
18
|
+
def hide_cursor; print @tput["civis"]; return self; end
|
19
|
+
def show_cursor; print @tput["cnorm"]; return self; end
|
20
|
+
def clear_line; print @tput["el1"]; return self; end
|
21
|
+
def echo_off; %x(stty -echo); return self; end
|
22
|
+
def echo_on; %x(stty echo); return self; end
|
23
|
+
def clear; print "\033[2J"; return self; end
|
24
|
+
def bold; print @tput["bold"]; return self; end
|
25
|
+
def nobold; print @tput["nobold"]; return self; end
|
26
26
|
|
27
|
-
|
28
|
-
|
27
|
+
def cols; return HighLine::SystemExtensions.terminal_size[0]; end
|
28
|
+
def rows; return HighLine::SystemExtensions.terminal_size[1]; end
|
29
|
+
|
30
|
+
def self.cols; return HighLine::SystemExtensions.terminal_size[0]; end
|
31
|
+
def self.rows; return HighLine::SystemExtensions.terminal_size[1]; end
|
29
32
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
+
def getKey
|
34
|
+
return STDIN.getch.gsub("\r", "enter").gsub(" ", "space").gsub("A", "up").gsub("B", "down").gsub("C", "right").gsub("D", "left").gsub("\e", "skip").gsub("[", "skip")
|
35
|
+
end
|
33
36
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
+
def reset
|
38
|
+
self.restore.show_cursor.echo_on
|
39
|
+
end
|
37
40
|
|
38
41
|
end
|
39
42
|
end
|
data/lib/aniview/util/util.rb
CHANGED
data/lib/aniview/view/aiomenu.rb
CHANGED
@@ -40,27 +40,27 @@ module Aniview
|
|
40
40
|
|
41
41
|
def customControl(key, sel)
|
42
42
|
path = @items.values[sel["out"]][sel["in"]].path
|
43
|
+
|
44
|
+
empty = path == "empty"
|
43
45
|
|
44
46
|
if key == @pref.get("keybindings")["menu_nav_expand"]
|
45
47
|
expand(sel["out"])
|
46
48
|
elsif key == "r"
|
47
49
|
refresh
|
48
|
-
elsif key == "enter"
|
50
|
+
elsif key == "enter" and not empty
|
49
51
|
|
50
52
|
@interface.watch(@items.values[sel["out"]][sel["in"]])
|
51
|
-
|
53
|
+
|
52
54
|
@interface.logWatched(path)
|
53
|
-
|
54
|
-
#@malanime.update(path)
|
55
|
-
|
55
|
+
|
56
56
|
refresh
|
57
|
-
elsif key == @pref.get("keybindings")["anime_set_watched"]
|
57
|
+
elsif key == @pref.get("keybindings")["anime_set_watched"] and not empty
|
58
58
|
@interface.addWatched(path)
|
59
59
|
refresh
|
60
60
|
elsif key == @pref.get("keybindings")["anime_undo_set_watched"]
|
61
61
|
@interface.rmWatched()
|
62
62
|
refresh
|
63
|
-
elsif key == @pref.get("keybindings")["anime_set_unwatched"]
|
63
|
+
elsif key == @pref.get("keybindings")["anime_set_unwatched"] and not empty
|
64
64
|
@interface.rmWatched(path)
|
65
65
|
|
66
66
|
end
|