aniview 3.0.1 → 3.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/README.md +12 -0
- data/lib/aniview.rb +1 -0
- data/lib/aniview/interface/pref/pref.rb +142 -125
- data/lib/aniview/util/error.rb +9 -0
- data/lib/aniview/view/menu.rb +8 -6
- data/lib/aniview/view/prefmenu.rb +3 -4
- data/lib/application.rb +14 -8
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 827d5b9084b305647f640fd4cf3ba14ce15bcea5
|
4
|
+
data.tar.gz: 3e10b4ccf9d9f02cfee4260921eb7f22ae097339
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 69a1e2a4ba2c11f38811bb5eb951993f5ea41228796c77f397a9292c2f053993f653b8ecbe614df7c41a9fe3d3a88c481bc8379e73340d0ea580166974c57206
|
7
|
+
data.tar.gz: 6195b01dcd02520fb7119c4b690f2266c0459ea603b96c6eaea03ab9e6aa352314800cac6b6f3052f846306886a409b7772fa0d6534ae2d29f7ad18ff73dbb97
|
data/README.md
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
# aniview
|
2
|
+
command line anime library viewer
|
3
|
+
|
4
|
+

|
5
|
+
|
6
|
+
## installation
|
7
|
+
### using rubygems
|
8
|
+
`gem install aniview`
|
9
|
+
|
10
|
+
### Find out more on the wiki
|
11
|
+
+ [Default Keybingings](https://github.com/annacrombie/aniview/wiki/Default-Keybindings)
|
12
|
+
+ [Format Strings](https://github.com/annacrombie/aniview/wiki/Format-Strings)
|
data/lib/aniview.rb
CHANGED
@@ -6,166 +6,183 @@ require_relative '../../view/color'
|
|
6
6
|
require_relative '../bridge'
|
7
7
|
|
8
8
|
module Aniview
|
9
|
+
|
9
10
|
module Interface
|
11
|
+
|
12
|
+
##
|
13
|
+
## @brief Class for preferences.
|
14
|
+
##
|
10
15
|
class Pref < Bridge
|
11
16
|
|
12
17
|
include Observable
|
13
18
|
|
14
|
-
|
15
|
-
@home = Dir.home
|
16
|
-
@conf = @home + "/.config/aniview"
|
17
|
-
|
18
|
-
File.open(File.join(File.dirname(__FILE__), "/validate.json"), "r") {
|
19
|
-
|f| @validate = JSON.parse(f.read)
|
20
|
-
}
|
21
|
-
|
22
|
-
FileUtils.mkdir_p(@conf) unless File.directory?(@conf)
|
19
|
+
attr_accessor :logger
|
23
20
|
|
24
|
-
|
21
|
+
##
|
22
|
+
## @brief Initializes pref object, with optional logger
|
23
|
+
##
|
24
|
+
## @param logger The logger
|
25
|
+
##
|
26
|
+
## @return A new pref object
|
27
|
+
##
|
28
|
+
def initialize(logger: nil)
|
29
|
+
@logger = logger
|
30
|
+
conf = Dir.home + "/.config/aniview"
|
31
|
+
@default_file = File.join(File.dirname(__FILE__), "/defaults.json")
|
32
|
+
@pref_file = conf + "/aniview.json"
|
33
|
+
validation_file = File.join(File.dirname(__FILE__), "/validate.json")
|
34
|
+
@validations = read(validation_file)
|
25
35
|
|
26
|
-
|
27
|
-
|
28
|
-
defaults should_save: true if not File.exist?(@pref_file)
|
36
|
+
FileUtils.mkdir_p(conf) unless File.directory?(conf)
|
29
37
|
load
|
38
|
+
save unless File.exist?(@pref_file)
|
30
39
|
end
|
31
40
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
def
|
41
|
-
|
42
|
-
|
41
|
+
##
|
42
|
+
## @brief converts a directory like "~/movies" to
|
43
|
+
## "/users/shinji/movies/"
|
44
|
+
##
|
45
|
+
## @param path The path to parse
|
46
|
+
##
|
47
|
+
## @return the parsed directory string
|
48
|
+
##
|
49
|
+
def parseDir(path)
|
50
|
+
{
|
51
|
+
"$airing_dir" => @pref["airing_dir"],
|
52
|
+
"$conf_dir" => @pref["conf_dir"],
|
53
|
+
"~" => Dir.home
|
54
|
+
}.inject(path) { |path, r| path.gsub(r[0], r[1]) }
|
43
55
|
end
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
56
|
+
|
57
|
+
##
|
58
|
+
## @brief gets a preference
|
59
|
+
##
|
60
|
+
## @param key The key
|
61
|
+
##
|
62
|
+
## @return the preference at key or nil if there is no such preference
|
63
|
+
##
|
64
|
+
def get(key)
|
65
|
+
@pref[key] if @pref.key?(key)
|
54
66
|
end
|
55
67
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
68
|
+
##
|
69
|
+
## @brief Validates and sets a preference
|
70
|
+
##
|
71
|
+
## @param trail The key or array of keys that specify where
|
72
|
+
## the preference is stored
|
73
|
+
## @param destination The new value for the preference
|
74
|
+
##
|
75
|
+
## @return nil
|
76
|
+
##
|
77
|
+
def set(trail, destination)
|
78
|
+
trail = [trail] if trail.class == String
|
79
|
+
return unless valid_preference?(trail, destination)
|
80
|
+
|
81
|
+
trail[0...-1].inject(@pref, :fetch)[trail.last] = destination
|
82
|
+
save
|
83
|
+
changed
|
84
|
+
notify_observers
|
67
85
|
end
|
68
86
|
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
return false if not destination.scan(/\D/).empty? and destination.length > 1
|
95
|
-
|
96
|
-
when "locked"
|
97
|
-
return false
|
98
|
-
|
99
|
-
end
|
100
|
-
|
101
|
-
return true
|
102
|
-
|
103
|
-
else
|
104
|
-
blaze = trail[0]
|
105
|
-
return valpref(trail[1..-1], destination, map[blaze])
|
87
|
+
##
|
88
|
+
## @brief validates a preference
|
89
|
+
##
|
90
|
+
## @param trail The array of keys that specify where the
|
91
|
+
## preference is stored
|
92
|
+
## @param destination The new value for the preference
|
93
|
+
##
|
94
|
+
## @return true if preference is valid, false otherwise
|
95
|
+
##
|
96
|
+
def valid_preference?(trail, destination)
|
97
|
+
skeys = [ "space", "up", "down", "left", "right", "enter" ]
|
98
|
+
|
99
|
+
case trail.inject(@validations, :fetch)
|
100
|
+
when "key"
|
101
|
+
destination.length == 1 or skeys.include?(destination)
|
102
|
+
when "path"
|
103
|
+
destination.split(":").map { |d| Dir.exist?(parseDir d) }.reduce { |m, n| m and n }
|
104
|
+
when "color"
|
105
|
+
Aniview::View::Color.respond_to?(destination)
|
106
|
+
when "int"
|
107
|
+
destination.scan(/\D/).empty? and destination.length > 1
|
108
|
+
when "locked"
|
109
|
+
false
|
110
|
+
else
|
111
|
+
true
|
106
112
|
end
|
107
113
|
end
|
108
|
-
|
109
|
-
def get s
|
110
|
-
return @pref[s] if @pref.key?(s)
|
111
|
-
end
|
112
114
|
|
115
|
+
##
|
116
|
+
## @brief gets an array of PrefItems to be displayed in the menu
|
117
|
+
##
|
118
|
+
## @return an array of PrefItems
|
119
|
+
##
|
113
120
|
def items
|
114
121
|
ignore = {
|
115
122
|
"local_anime" => true,
|
116
123
|
"schedule" => true,
|
117
124
|
}
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
if item[1].class == String
|
124
|
-
val = item[1]
|
125
|
-
elsif item[1].class == Array
|
126
|
-
val = item[1].join(":")
|
127
|
-
elsif item[1].class == Hash
|
128
|
-
item[1].each { |subitem|
|
129
|
-
subtitle = title + "_" + subitem[0]
|
130
|
-
subval = subitem[1]
|
131
|
-
r.merge!(PrefItem.new(subtitle, subval, []) => [PrefItem.new("", "", [item[0], subitem[0]])])
|
125
|
+
@pref.map{ |title, preference|
|
126
|
+
next if ignore.key? title
|
127
|
+
if preference.class == Hash
|
128
|
+
preference.map { |subtitle, subpreference|
|
129
|
+
PrefItem.new(title + "_" + subtitle, subpreference, [title, subtitle])
|
132
130
|
}
|
133
|
-
|
131
|
+
else
|
132
|
+
preference = preference.join(":") if preference.class == Array
|
133
|
+
PrefItem.new(title, preference, [title])
|
134
134
|
end
|
135
|
-
|
136
|
-
}
|
137
|
-
return r
|
135
|
+
}.flatten.compact
|
138
136
|
end
|
139
137
|
|
138
|
+
##
|
139
|
+
## @brief saves the prefs to disk
|
140
|
+
##
|
141
|
+
## @return nil
|
142
|
+
##
|
140
143
|
def save
|
141
|
-
@saving = true
|
142
144
|
File.open(@pref_file, "w") { |f| f.write(JSON.pretty_generate(@pref)) }
|
143
|
-
@saving = false
|
144
145
|
end
|
145
146
|
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
147
|
+
##
|
148
|
+
## @brief loads the prefs from file
|
149
|
+
##
|
150
|
+
## @param file The file
|
151
|
+
##
|
152
|
+
## @return nil
|
153
|
+
##
|
150
154
|
def load
|
151
|
-
|
152
|
-
#json = ""
|
153
|
-
json = File.open(@pref_file, "r") {|f| f.read}
|
154
|
-
#puts json
|
155
|
-
if json == ""
|
156
|
-
#puts "going to defaults"
|
157
|
-
defaults
|
158
|
-
return
|
159
|
-
end
|
160
|
-
@pref = JSON.parse json
|
161
|
-
rescue JSON::ParserError
|
162
|
-
puts "severe! your preference file #{@pref_file} is corrupted,"
|
163
|
-
puts "please fix the file or delete it to restore defaults"
|
164
|
-
exit
|
165
|
-
end
|
155
|
+
@pref = read(@pref_file) || read(@default_file)
|
166
156
|
changed
|
167
157
|
notify_observers
|
168
158
|
end
|
159
|
+
|
160
|
+
##
|
161
|
+
## @brief reads json from a file
|
162
|
+
##
|
163
|
+
## @param file The file
|
164
|
+
##
|
165
|
+
## @return parsed json
|
166
|
+
##
|
167
|
+
def read(file)
|
168
|
+
begin
|
169
|
+
File.open(file, "r") { |f|
|
170
|
+
json = f.read
|
171
|
+
if json.empty?
|
172
|
+
return nil
|
173
|
+
else
|
174
|
+
begin
|
175
|
+
JSON.parse json
|
176
|
+
rescue JSON::ParserError
|
177
|
+
raise Aniview::Error::InvalidPref.new
|
178
|
+
end
|
179
|
+
end
|
180
|
+
}
|
181
|
+
rescue Errno::ENOENT
|
182
|
+
return nil
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
169
186
|
end
|
170
187
|
end
|
171
188
|
end
|
data/lib/aniview/view/menu.rb
CHANGED
@@ -11,9 +11,11 @@ module Aniview
|
|
11
11
|
|
12
12
|
attr_accessor :visible
|
13
13
|
|
14
|
-
def initialize(refresh_function: :items, interface:, name:, pref:, format:, term:, children: true, visible: false)
|
14
|
+
def initialize(refresh_function: :items, interface:, name:, pref:, format:, term:, children: true, visible: false, logger: nil)
|
15
15
|
@attributes = {}
|
16
16
|
|
17
|
+
@logger = logger
|
18
|
+
|
17
19
|
@visible = visible
|
18
20
|
|
19
21
|
@refresh_function = refresh_function
|
@@ -111,7 +113,7 @@ module Aniview
|
|
111
113
|
@items = @interface.send(@refresh_function)
|
112
114
|
refreshFormats
|
113
115
|
refresh_attributes
|
114
|
-
@expanded = -1 if @items.values[@expanded] == nil
|
116
|
+
@expanded = -1 if @children and @items.values[@expanded] == nil
|
115
117
|
fixCursor
|
116
118
|
changed
|
117
119
|
notify_observers
|
@@ -132,7 +134,7 @@ module Aniview
|
|
132
134
|
notify_observers
|
133
135
|
end
|
134
136
|
|
135
|
-
def
|
137
|
+
def resolve_selected(resolve_me=@selected)
|
136
138
|
in_expanded=false
|
137
139
|
inside = 0
|
138
140
|
outside = resolve_me
|
@@ -274,7 +276,7 @@ module Aniview
|
|
274
276
|
print lo + @cl["m"] + @title_formatted + "\e[K"
|
275
277
|
|
276
278
|
#get the resolved start positions
|
277
|
-
resolved_start_position =
|
279
|
+
resolved_start_position = resolve_selected line_on
|
278
280
|
outer_index = resolved_start_position["out"]
|
279
281
|
inner_index = resolved_start_position["in"]
|
280
282
|
|
@@ -288,7 +290,7 @@ module Aniview
|
|
288
290
|
while line_on < lines_to_draw
|
289
291
|
|
290
292
|
in_outer_region = ! (line_on >= getLen)
|
291
|
-
in_expanded_region =
|
293
|
+
in_expanded_region = resolve_selected(line_on)["in_expanded"]
|
292
294
|
line = line_on-offset+1
|
293
295
|
selected = line_on == @selected
|
294
296
|
|
@@ -311,7 +313,7 @@ module Aniview
|
|
311
313
|
end
|
312
314
|
|
313
315
|
def control(key)
|
314
|
-
sel =
|
316
|
+
sel = resolve_selected
|
315
317
|
if key == @pref.get("keybindings")["menu_nav_up"]
|
316
318
|
moveCursor("up")
|
317
319
|
elsif key == @pref.get("keybindings")["menu_nav_down"]
|
@@ -7,10 +7,9 @@ module Aniview
|
|
7
7
|
include Aniview::Util
|
8
8
|
|
9
9
|
def customControl(key, sel)
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
value = @items.keys[sel["out"]].attributes["v"]
|
10
|
+
path = @items[sel["out"]].path
|
11
|
+
title = @items[sel["out"]].attributes["t"]
|
12
|
+
value = @items[sel["out"]].attributes["v"]
|
14
13
|
if key == "enter"
|
15
14
|
newval = Util.readline(@term, title + ":", value)
|
16
15
|
@interface.set(path, newval)
|
data/lib/application.rb
CHANGED
@@ -42,13 +42,14 @@ module Aniview
|
|
42
42
|
#
|
43
43
|
def initialize
|
44
44
|
|
45
|
-
#@logger = Logger.new('aniview.log')
|
46
|
-
#@logger.level = Logger::DEBUG
|
47
|
-
|
48
45
|
@term = Util::Term.new
|
49
46
|
|
50
47
|
@pref = Interface::Pref.new
|
51
48
|
|
49
|
+
@logger = Logger.new(@pref.parseDir(@pref.get("log_file")))
|
50
|
+
@logger.level = Logger::DEBUG
|
51
|
+
@pref.logger = @logger
|
52
|
+
|
52
53
|
@mpvbridge = Interface::MPVBridge.new @pref
|
53
54
|
|
54
55
|
@aio = Interface::AnimeIO.new @pref, @mpvbridge
|
@@ -78,7 +79,8 @@ module Aniview
|
|
78
79
|
pref: @pref,
|
79
80
|
format: "format_library_unwatched",
|
80
81
|
term: @term,
|
81
|
-
refresh_function: :unwatched
|
82
|
+
refresh_function: :unwatched,
|
83
|
+
logger: @logger
|
82
84
|
)
|
83
85
|
@prefmenu = View::PrefMenu.new(
|
84
86
|
interface: @pref,
|
@@ -86,7 +88,8 @@ module Aniview
|
|
86
88
|
pref: @pref,
|
87
89
|
format: "format_preferences",
|
88
90
|
term: @term,
|
89
|
-
children: false
|
91
|
+
children: false,
|
92
|
+
logger: @logger
|
90
93
|
)
|
91
94
|
@delugemenu = View::DelugeMenu.new(
|
92
95
|
interface: @delugec,
|
@@ -94,7 +97,8 @@ module Aniview
|
|
94
97
|
pref: @pref,
|
95
98
|
format: "format_torrents",
|
96
99
|
term: @term,
|
97
|
-
children: false
|
100
|
+
children: false,
|
101
|
+
logger: @logger
|
98
102
|
)
|
99
103
|
@schedulemenu = View::ScheduleMenu.new(
|
100
104
|
interface: @schedule,
|
@@ -102,7 +106,8 @@ module Aniview
|
|
102
106
|
pref: @pref,
|
103
107
|
format: "format_schedule",
|
104
108
|
term: @term,
|
105
|
-
children: false
|
109
|
+
children: false,
|
110
|
+
logger: @logger
|
106
111
|
)
|
107
112
|
@subscriptionmenu = View::SubscriptionMenu.new(
|
108
113
|
interface: @subscription,
|
@@ -110,7 +115,8 @@ module Aniview
|
|
110
115
|
pref: @pref,
|
111
116
|
format: "format_subscriptions",
|
112
117
|
term: @term,
|
113
|
-
children: false
|
118
|
+
children: false,
|
119
|
+
logger: @logger
|
114
120
|
)
|
115
121
|
@term.save.hide_cursor.echo_off
|
116
122
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: aniview
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.0
|
4
|
+
version: 3.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- annacrombie
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-07-
|
11
|
+
date: 2017-07-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: streamio-ffmpeg
|
@@ -137,6 +137,7 @@ executables:
|
|
137
137
|
extensions: []
|
138
138
|
extra_rdoc_files: []
|
139
139
|
files:
|
140
|
+
- "./README.md"
|
140
141
|
- "./lib/aniview.rb"
|
141
142
|
- "./lib/aniview/client/aniclient.rb"
|
142
143
|
- "./lib/aniview/interface/animeio/animefile.rb"
|
@@ -154,6 +155,7 @@ files:
|
|
154
155
|
- "./lib/aniview/interface/schedule/schedule.rb"
|
155
156
|
- "./lib/aniview/interface/schedule/scheduleitem.rb"
|
156
157
|
- "./lib/aniview/interface/subscription/subscription.rb"
|
158
|
+
- "./lib/aniview/util/error.rb"
|
157
159
|
- "./lib/aniview/util/term.rb"
|
158
160
|
- "./lib/aniview/util/util.rb"
|
159
161
|
- "./lib/aniview/view/aiomenu.rb"
|