aniview 2.1.2 → 3.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 6824d7f28e7bebe026f0081c09d7442e99d50e64
4
- data.tar.gz: e645a210dcd58f0d039430e64ffd9b9254a4cbe0
3
+ metadata.gz: 4b35aefbae5c33c60dd90e34e39ba25538fb537d
4
+ data.tar.gz: f930e37c98cab765b2baaf880e1631e9b8cee308
5
5
  SHA512:
6
- metadata.gz: dad87f8040707a9718894b85f4ab715b20d38947a3c6007a61b8bdbfe4718c430ce13ec80c5d54398a58fa5813927d88547509b4e43f6c0bc1feb468429b0434
7
- data.tar.gz: 865b2b9710b445419ae625aa8ad9b95703ea1e9edecd148e5b55df6fc95e5848cb110ca56e231c496371c5704a25b4fdb140961b1cdf1950b0e8db2bd763d874
6
+ metadata.gz: 0cb7100a4503b321ebac1a28582d856fc2b536fbae03ffa7dbc3d9bcacb5d5506e3ba8f75871822f749695afff13c9249bee1fc6bdb309c2d0265e366e49cace
7
+ data.tar.gz: def2061bba9ae07a58886a26a0f8d468632d98623c1d13be405f895651be834e4d737aebc7df084fcf79b5bd44ac274012c264f35bdad467c245078b4428597c
data/bin/aniview CHANGED
@@ -1,14 +1,14 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  begin
4
- require 'aniview'
4
+ require 'aniview'
5
5
  rescue LoadError
6
- require_relative '../lib/aniview' if File.exist?(File.join(File.dirname(__FILE__), '../lib/aniview.rb'))
6
+ require_relative '../lib/aniview' if File.exist?(File.join(File.dirname(__FILE__), '../lib/aniview.rb'))
7
7
  end
8
8
 
9
9
  unless defined? Aniview
10
- puts "cant find aniview library"
11
- exit
10
+ puts "cant find aniview library"
11
+ exit
12
12
  end
13
13
 
14
14
  Aniview::main(ARGV)
data/lib/aniview.rb CHANGED
@@ -32,6 +32,7 @@ module Aniview
32
32
  case arg
33
33
  when "-d"
34
34
  argv.delete_at(0)
35
+ daemonize = true
35
36
  main_class = Aniview::Daemon.new(argv)
36
37
  when "-h"
37
38
  self.show_help
@@ -49,7 +50,6 @@ module Aniview
49
50
  process = fork do
50
51
  main_class.run
51
52
  end
52
-
53
53
  Process.detach(process)
54
54
  else
55
55
  main_class.run
@@ -11,17 +11,19 @@ module Aniview
11
11
  include Aniview::Util
12
12
 
13
13
  attr_accessor :last_modified
14
+ attr_accessor :accessible
14
15
  attr_accessor :path
15
16
 
16
17
  def initialize(path_, seen = false)
17
- @watched = seen
18
+ @watched = seen
19
+ @accessible = true
18
20
  begin
19
21
  @last_modified = File::Stat.new(path_).mtime
20
22
  rescue Errno::ENOENT
21
23
  @last_modified = "0"
22
24
  end
23
25
  @watched_on = 0
24
- @path = path_
26
+ @path = path_
25
27
 
26
28
  @attr = {
27
29
  "t" => "empty",
@@ -1,212 +1,263 @@
1
1
  require 'mkmf'
2
2
  require 'fileutils'
3
+ require 'observer'
4
+ require 'listen'
5
+ require 'benchmark'
6
+
3
7
  require_relative 'animefile'
4
8
  require_relative 'animeseries'
5
9
  require_relative '../../util/util'
10
+ require_relative '../bridge'
6
11
 
7
12
  module Aniview
8
13
  module Interface
9
- include Aniview::Util
10
- class AnimeIO
11
- def initialize(pref, mpvbridge)
14
+
15
+ class AnimeIO < Bridge
16
+
17
+ include Aniview::Util
18
+
19
+ include Observable
20
+
21
+ def initialize(pref, mpvbridge)
12
22
  @pref = pref
13
23
  @mpvbridge = mpvbridge
14
24
  @empty_hash = make_empty_hash
15
25
  @watch_log_tag = "♪"
16
26
  @dir_last_modified = {}
17
-
18
- self.load
19
- index_anime
20
- end
27
+ @made_changes = true
28
+
29
+ self.load
30
+ pref_changed!
31
+ relisten
32
+
33
+ @pref.add_observer(self, :pref_changed!)
34
+ @mpvbridge.add_observer(self, :animefile_changed!)
35
+ #@@local_anime.each { |key, obj| obj.add_observer(self, :animefile_changed!)}
36
+ end
37
+
38
+ def relisten
39
+ @listener.stop unless @listener == nil
40
+ return if @anime_dirs == nil or @anime_dirs[0] == ""
41
+ @listener = Listen.to(*@anime_dirs, only: /\.mkv$/) do |modified, added, removed|
42
+ index_anime
43
+ end
44
+ @listener.start
45
+ end
46
+
47
+ def cleanup
48
+ @listener.stop unless @listener == nil
49
+ end
21
50
 
22
51
  def make_empty_hash
23
52
  af = AnimeFile.new("empty")
24
53
  {AnimeSeries.new("empty", [af]) => [af]}
25
54
  end
26
55
 
27
- def save
28
- @pref.set "local_anime", Util.encode_object(@@local_anime)
29
- end
30
-
31
- def load
32
- raw = @pref.get "local_anime"
33
- if not raw == nil and raw.class == String
34
- @@local_anime = Util.decode_object raw
35
- else
36
- @@local_anime = {}
37
- end
38
- end
56
+ def save
57
+ @pref.set "local_anime", Util.encode_object(@@local_anime)
58
+ end
59
+
60
+ def load
61
+ raw = @pref.get "local_anime"
62
+ if not raw == nil and raw.class == String
63
+ @@local_anime = Util.decode_object raw
64
+ else
65
+ @@local_anime = {}
66
+ end
67
+ end
68
+
69
+ def pref_changed!
70
+ new_dirs = (@pref.get("anime_locations").split(":")).collect { |dir|
71
+ @pref.parseDir(dir)
72
+ }
73
+ if new_dirs != @anime_dirs
74
+ @anime_dirs = new_dirs
75
+ index_anime
76
+ relisten
77
+ end
78
+ end
79
+
80
+ def animefile_changed!
81
+ return unless @mpvbridge.what_changed == "local_anime"
82
+ changed
83
+ notify_observers
84
+ end
39
85
 
40
- def index_anime(force: false, verbose: false)
41
- ret = {}
42
- made_changes = false
43
86
 
44
- (@pref.get("anime_locations").split(":")).each { |dir|
45
-
46
- dir = @pref.parseDir dir
47
- dir += "/" if dir[-1] != "/"
87
+ ##
88
+ ## @brief Indexes anime files up to 1 level deep in specified anime directories
89
+ ##
90
+ ## @param force The force
91
+ ## @param verbose The verbose
92
+ ##
93
+ ## @return { description_of_the_return_value }
94
+ ##
95
+ def index_anime(force: false, verbose: false)
96
+ Thread.new {
97
+ ret = {}
98
+ made_changes = false
99
+ lal = @@local_anime.length
48
100
 
49
- dir_mtime = File::Stat.new(dir).mtime
101
+ @anime_dirs.each { |dir|
50
102
 
51
- if @dir_last_modified.key? dir
52
- if @dir_last_modified[dir] == dir_mtime
53
- #puts "skipping"
103
+ # check if the directory exists
104
+ if not File.exist? dir
105
+ if @dir_last_modified[dir] != "check"
106
+ @dir_last_modified[dir] = "check"
107
+ made_changes = true
108
+ end
54
109
  next
55
- else
56
- @dir_last_modified[dir] = dir_mtime
57
110
  end
58
- else
59
- @dir_last_modified.merge!(dir => dir_mtime)
60
- end
61
111
 
62
- files = Dir.glob("#{dir}*/*.{mkv,avi,mp4}") + Dir.glob("#{dir}/*.{mkv,avi,mp4}")
63
-
64
- files.each { |file|
65
- puts "indexing #{file}" if verbose
66
- seen_this = false
67
- if @@local_anime != nil and @@local_anime.key?(file)
68
- seen_this = @@local_anime[file].seen?
69
-
70
- last_modified = File::Stat.new(file).mtime
71
-
72
- if not force or last_modified == @@local_anime[file].last_modified
73
- ret.merge!(file => @@local_anime[file])
74
- next
75
- end
76
- end
77
- made_changes = true
78
- ret.merge!(
79
- file => AnimeFile.new(
80
- file,
81
- seen_this
82
- )
83
- )
84
- }
85
- }
86
- if @@local_anime != nil
87
- @@local_anime.merge!(ret)
88
- else
89
- @@local_anime = ret
90
- end
91
-
92
- pruned = {}
93
- @@local_anime.each{ |a|
94
- pruned.merge!(a[0] => a[1]) if File.exist? a[1].path
95
- }
96
- @@local_anime = pruned
97
- puts "made changes" if made_changes
98
- self.save if made_changes
99
- end
100
-
101
- #returns the parent directory of a file
102
- def parent(file)
103
- return File.basename(File.dirname(file))
104
- end
105
-
106
- #convert an AnimeFile array to a hash structured like
107
- #(string)parent => (AnimeFile array)[child0, child1, child2] and return it
108
- def makeHash(arr)
109
- return @empty_hash if arr[0] == nil
110
- ret = {}
111
- subarray = []
112
-
113
-
114
- sarr = arr.sort_by {|s| s.path}
115
- last_parent = parent sarr[0].path
116
-
117
- (sarr).each { |animefile|
118
-
119
- this_parent = parent animefile.path
120
-
121
- if this_parent != last_parent
122
- sorted_subarray = subarray.sort_by { |a| a.title }
123
- ret.merge!(
124
- AnimeSeries.new(
125
- last_parent,
126
- sorted_subarray
127
- ) => sorted_subarray)
128
- subarray = [animefile]
129
- else
130
- subarray << animefile
131
- end
132
-
133
- last_parent = this_parent
134
-
135
- }
136
-
137
- sorted_subarray = subarray.sort_by { |a| a.title }
138
- ret.merge!(
139
- AnimeSeries.new(
140
- parent(sarr[sarr.length - 1].path),
141
- sorted_subarray
142
- ) => sorted_subarray
143
- )
144
- return Hash[ret.sort_by{ |a| a[0].title}]
145
- end
146
-
147
- #return the difference of getAired and getWatched
148
- def getUnwatched
149
- index_anime
150
- ret = []
151
- #puts @@local_anime
152
- @@local_anime.each{ |anime|
153
- ret << anime[1] if not anime[1].seen?
154
- }
155
- return ret
156
- end
157
-
158
- #return an AnimeFile array of all mkvs in any dir specified in $pref["dirs"]
159
- def getAll
160
- index_anime
161
- return @@local_anime.values
162
- end
163
-
164
- def getAllSeries
165
- arr = getAll
112
+ puts "checking #{dir}" if verbose
113
+
114
+ # skip indexing a directory if it hasn't been modified since the last
115
+ # check (disabled because doesn't save to much time)
116
+ #
117
+ #dir_mtime = File::Stat.new(dir).mtime
118
+ #
119
+ #if @dir_last_modified.key? dir
120
+ # if @dir_last_modified[dir] == dir_mtime
121
+ # next
122
+ # else
123
+ # @dir_last_modified[dir] = dir_mtime
124
+ # end
125
+ #else
126
+ # @dir_last_modified.merge!(dir => dir_mtime)
127
+ #end
128
+
129
+ # get all files in the directory and in all subfolders of the directory
130
+ files = Dir.glob("#{dir}*/*.{mkv,avi,mp4}") + Dir.glob("#{dir}/*.{mkv,avi,mp4}")
131
+
132
+ files.each { |file|
133
+ print "indexing #{file} -> " if verbose
134
+ seen_this = false
135
+
136
+ # we have already indexed this file
137
+ if @@local_anime != nil and @@local_anime.key?(file)
138
+
139
+ # get its seen data
140
+ seen_this = @@local_anime[file].seen?
141
+ # get its last modifed data
142
+ last_modified = File::Stat.new(file).mtime
143
+ # get wether or not it is accessible
144
+ @@local_anime[file].accessible = true
145
+
146
+ # if we arent forcing or the anime hasn't been modified since the
147
+ # last check, skip it
148
+ if not force or last_modified == @@local_anime[file].last_modified
149
+ puts "unchanged" if verbose
150
+ ret.merge!(file => @@local_anime[file])
151
+ next
152
+ end
153
+ end
154
+
155
+ #puts "changed!"
156
+
157
+ # okay we are making changes to local_anime
158
+ made_changes = true
159
+
160
+ # this is the anime file we are adding
161
+ ret.merge!(
162
+ file => AnimeFile.new(
163
+ file,
164
+ seen_this
165
+ )
166
+ )
167
+ }
168
+ }
169
+
170
+ #if @@local_anime != nil
171
+ # @@local_anime.merge!(ret)
172
+ #else
173
+ @@local_anime = ret
174
+ #end
175
+
176
+ #pruned = {}
177
+ #@@local_anime.each{ |a|
178
+ # pruned.merge!(a[0] => a[1]) if File.exist? a[1].path
179
+ #}
180
+ #@@local_anime = pruned
181
+ made_changes = true if @@local_anime.length != lal
182
+ if @made_changes
183
+ self.save
184
+ changed
185
+ notify_observers
186
+ end
187
+ }
188
+ end
166
189
 
167
- last_parent = parent arr[0].path
168
- ret = [ last_parent ]
190
+ #returns the parent directory of a file
191
+ def parent(file)
192
+ return File.basename(File.dirname(file))
193
+ end
169
194
 
170
- arr.each { |animefile|
171
- this_parent = parent animefile.path
172
- if this_parent != last_parent
173
- ret << this_parent
174
- end
175
- last_parent = this_parent
176
- }
177
- return ret
178
- end
195
+ #convert an AnimeFile array to a hash structured like
196
+ #(string)parent => (AnimeFile array)[child0, child1, child2] and return it
197
+ def makeHash arr
198
+ #return @empty_hash if arr[0] == nil
199
+
200
+ keys = {}
201
+ hash = {}
202
+
203
+ arr.sort_by {|i| i.title}.each { |file|
204
+ if ! keys.key?(parent file.path)
205
+ key = AnimeSeries.new parent(file.path)
206
+ keys.merge! parent(file.path) => key
207
+ hash.merge! key => []
208
+ else
209
+ key = keys[parent file.path]
210
+ end
211
+
212
+ hash[key] << file
213
+ key += file
214
+ }
215
+ hash.sort_by{ |j| j[0].title }.to_h
216
+ end
179
217
 
180
- def logWatched(file)
181
- open(@pref.parseDir(@pref.get("watch_log")), 'a') do |f|
182
- f.puts %x(date).chomp + " ./" + File.basename(file) + " " + @watch_log_tag
183
- end
184
- end
218
+ #return the difference of getAired and getWatched
219
+ def unwatched
220
+ makeHash @@local_anime.reject { |f, a| a.seen? }.values
221
+ end
185
222
 
186
- def addWatched(file)
187
- @@local_anime[file].watch
188
- self.save
189
- end
223
+ #return an AnimeFile array of all mkvs in any dir specified in $pref["dirs"]
224
+ def items
225
+ makeHash @@local_anime.values
226
+ end
190
227
 
191
- def rmWatched(path = "zoz")
228
+ def logWatched(file)
229
+ open(@pref.parseDir(@pref.get("watch_log")), 'a') do |f|
230
+ f.puts %x(date).chomp + " ./" + File.basename(file) + " " + @watch_log_tag
231
+ end
232
+ end
192
233
 
193
- if @@local_anime.key? path
194
- @@local_anime[path].unwatch
195
- return
196
- end
234
+ def addWatched(file)
235
+ @@local_anime[file].watch
236
+ self.save
237
+ changed
238
+ notify_observers
239
+ end
197
240
 
198
- r = []
199
- @@local_anime.values.each_with_index{ |v, i| r << {Integer(v.seenOn) => @@local_anime.keys[i]} if v.seen? }
200
- return if r.length == 0
201
- last_watched = (r.sort_by{ |h| h.keys.first}.reverse)[0].values[0]
202
- @@local_anime[last_watched].unwatch
203
- self.save
204
- end
241
+ def rmWatched(path = "")
242
+ if @@local_anime.key? path
243
+ @@local_anime[path].unwatch
244
+ return
245
+ end
205
246
 
206
- #run mpv
207
- def watch(file)
208
- @mpvbridge.play file
209
- end
247
+ r = []
248
+ @@local_anime.values.each_with_index{ |v, i| r << {Integer(v.seenOn) => @@local_anime.keys[i]} if v.seen? }
249
+ return if r.length == 0
250
+ last_watched = (r.sort_by{ |h| h.keys.first}.reverse)[0].values[0]
251
+ @@local_anime[last_watched].unwatch
252
+ self.save
253
+ changed
254
+ notify_observers
255
+ end
256
+
257
+ def watch(file)
258
+ @mpvbridge.play file
259
+ end
260
+
210
261
  end
211
262
  end
212
263
  end