aniview 0.3.0 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/aniview.rb +59 -10
- data/lib/aniview/client/aniclient.rb +50 -0
- data/lib/aniview/interface/animeio/animeio.rb +2 -7
- data/lib/aniview/interface/deluge/delugec.rb +146 -49
- data/lib/aniview/interface/deluge/torrentitem.rb +4 -1
- data/lib/aniview/interface/pref/defaults.json +95 -66
- data/lib/aniview/interface/pref/pref.rb +18 -10
- data/lib/aniview/interface/pref/validate.json +32 -2
- data/lib/aniview/interface/schedule/schedule.rb +74 -0
- data/lib/aniview/interface/schedule/scheduleitem.rb +46 -0
- data/lib/aniview/interface/subscription/subscription.rb +102 -0
- data/lib/aniview/interface/subscription/subscriptiondaemon.rb +42 -0
- data/lib/aniview/util/alogger.rb +12 -3
- data/lib/aniview/util/command.rb +1 -0
- data/lib/aniview/util/format.rb +106 -105
- data/lib/aniview/util/stringhelp.rb +50 -0
- data/lib/aniview/view/delugemenu.rb +14 -3
- data/lib/aniview/view/menu.rb +2 -2
- data/lib/aniview/view/schedulemenu.rb +36 -0
- data/lib/aniview/view/subscriptionmenu.rb +35 -0
- data/lib/aniviewd.rb +167 -0
- metadata +11 -3
- data/lib/aniview/interface/rssfeed/rssfeed.rb +0 -26
@@ -1,4 +1,6 @@
|
|
1
1
|
require 'fileutils'
|
2
|
+
require 'json'
|
3
|
+
|
2
4
|
require_relative 'prefitem'
|
3
5
|
require_relative '../../view/emote.rb'
|
4
6
|
require_relative '../../util/alogger'
|
@@ -7,25 +9,25 @@ class Pref
|
|
7
9
|
def initialize
|
8
10
|
|
9
11
|
@home = Dir.home
|
10
|
-
@conf = @home + "/.
|
12
|
+
@conf = @home + "/.config/aniview"
|
11
13
|
|
12
14
|
File.open(File.join(File.dirname(__FILE__), "/validate.json"), "r") {
|
13
15
|
|f| @validate = JSON.parse(f.read)
|
14
16
|
}
|
15
17
|
|
16
|
-
|
17
|
-
FileUtils.mkdir_p(dirname) unless File.directory?(dirname)
|
18
|
-
|
19
|
-
@pref_file = @conf + "/r_anime.json"
|
18
|
+
FileUtils.mkdir_p(@conf) unless File.directory?(@conf)
|
20
19
|
|
21
|
-
@
|
20
|
+
@pref_file = @conf + "/aniview.json"
|
22
21
|
|
23
22
|
self.defaults if not File.exist?(@pref_file)
|
24
23
|
self.load
|
25
24
|
end
|
26
25
|
|
27
|
-
def
|
28
|
-
|
26
|
+
def parseDir path
|
27
|
+
path = path.gsub("$airing_dir", @pref["airing_dir"])
|
28
|
+
path = path.gsub("$conf_dir", @pref["conf_dir"])
|
29
|
+
path = path.gsub("~", Dir.home)
|
30
|
+
return path
|
29
31
|
end
|
30
32
|
|
31
33
|
def defaults
|
@@ -74,13 +76,18 @@ class Pref
|
|
74
76
|
|
75
77
|
when "path"
|
76
78
|
destination.split(":").each { |d|
|
77
|
-
|
79
|
+
return false if not Dir.exist?(parseDir d)
|
80
|
+
}
|
78
81
|
|
79
82
|
when "color"
|
80
83
|
return false if not $clr.key? destination
|
81
84
|
|
82
85
|
when "int"
|
83
86
|
return false if not destination.scan(/\D/).empty? and destination.length > 1
|
87
|
+
|
88
|
+
when "locked"
|
89
|
+
return false
|
90
|
+
|
84
91
|
end
|
85
92
|
|
86
93
|
return true
|
@@ -98,6 +105,7 @@ class Pref
|
|
98
105
|
def getAll
|
99
106
|
ignore = {
|
100
107
|
"local_anime" => true,
|
108
|
+
"schedule" => true,
|
101
109
|
}
|
102
110
|
|
103
111
|
r = {}
|
@@ -122,7 +130,7 @@ class Pref
|
|
122
130
|
end
|
123
131
|
|
124
132
|
def save
|
125
|
-
File.open(@pref_file, "w") { |f| f.write(@pref
|
133
|
+
File.open(@pref_file, "w") { |f| f.write(JSON.pretty_generate(@pref)) }
|
126
134
|
end
|
127
135
|
|
128
136
|
def load
|
@@ -5,14 +5,24 @@
|
|
5
5
|
"goto_unwatched" : "key",
|
6
6
|
"goto_library" : "key",
|
7
7
|
"goto_torrents" : "key",
|
8
|
+
"goto_schedule" : "key",
|
9
|
+
"goto_subscriptions" : "key",
|
8
10
|
"anime_set_watched" : "key",
|
9
11
|
"anime_set_unwatched" : "key",
|
10
12
|
"anime_undo_set_watched" : "key",
|
13
|
+
"torrents_pause" : "key",
|
14
|
+
"torrents_remove" : "key",
|
15
|
+
"torrents_remove_data" : "key",
|
16
|
+
"schedule_add_item" : "key",
|
17
|
+
"schedule_delete_item" : "key",
|
18
|
+
"schedule_edit_item" : "key",
|
19
|
+
"subscriptions_edit" : "key",
|
11
20
|
"menu_nav_up" : "key",
|
12
21
|
"menu_nav_down" : "key",
|
13
22
|
"menu_nav_expand" : "key"
|
14
23
|
},
|
15
24
|
"anime_locations" : "path",
|
25
|
+
"airing_dir" : "path",
|
16
26
|
"clr" :
|
17
27
|
{
|
18
28
|
"main" : "color",
|
@@ -25,7 +35,10 @@
|
|
25
35
|
"unwatched" : "any",
|
26
36
|
"library" : "any",
|
27
37
|
"torrents" : "any",
|
28
|
-
"preferences" : "any"
|
38
|
+
"preferences" : "any",
|
39
|
+
"schedule" : "any",
|
40
|
+
"subscriptions" : "any"
|
41
|
+
|
29
42
|
},
|
30
43
|
"format_library" :
|
31
44
|
{
|
@@ -44,11 +57,21 @@
|
|
44
57
|
"title" : "any",
|
45
58
|
"parent" : "any"
|
46
59
|
},
|
60
|
+
"format_schedule" :
|
61
|
+
{
|
62
|
+
"title" : "any",
|
63
|
+
"parent" : "any"
|
64
|
+
},
|
47
65
|
"format_preferences" :
|
48
66
|
{
|
49
67
|
"title" : "any",
|
50
68
|
"parent" : "any"
|
51
69
|
},
|
70
|
+
"format_subscriptions" :
|
71
|
+
{
|
72
|
+
"title" : "any",
|
73
|
+
"parent" : "any"
|
74
|
+
},
|
52
75
|
"deluge_config" :
|
53
76
|
{
|
54
77
|
"host" : "any",
|
@@ -61,8 +84,15 @@
|
|
61
84
|
"url" : "any",
|
62
85
|
"refresh_interval" : "int"
|
63
86
|
},
|
87
|
+
"daemon" :
|
88
|
+
{
|
89
|
+
"port" : "int"
|
90
|
+
},
|
64
91
|
"log_file" : "path",
|
92
|
+
"daemon_log_file" : "path",
|
65
93
|
"watch_log" : "path",
|
94
|
+
"conf_dir" : "locked",
|
66
95
|
"watch_command" : "any",
|
67
|
-
"local_anime" : "any"
|
96
|
+
"local_anime" : "any",
|
97
|
+
"schedule" : "any"
|
68
98
|
}
|
@@ -0,0 +1,74 @@
|
|
1
|
+
require 'base64'
|
2
|
+
require 'fileutils'
|
3
|
+
|
4
|
+
require_relative 'scheduleitem'
|
5
|
+
|
6
|
+
class Schedule
|
7
|
+
|
8
|
+
def initialize pref
|
9
|
+
@pref = pref
|
10
|
+
load
|
11
|
+
end
|
12
|
+
|
13
|
+
def empty?
|
14
|
+
if @schedule == nil or @schedule.length == 0
|
15
|
+
@schedule = [ScheduleItem.new("no schedule", "")]
|
16
|
+
save
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def getAll
|
21
|
+
empty?
|
22
|
+
return @schedule
|
23
|
+
end
|
24
|
+
|
25
|
+
def addItem item
|
26
|
+
@schedule.delete_at 0 if @schedule[0].attributes["t"] == "no schedule"
|
27
|
+
|
28
|
+
new_item = ScheduleItem.new(item, @pref.get("airing_dir"))
|
29
|
+
|
30
|
+
FileUtils.mkdir_p @pref.parseDir new_item.attributes["p"]
|
31
|
+
|
32
|
+
@schedule << new_item
|
33
|
+
|
34
|
+
save
|
35
|
+
end
|
36
|
+
|
37
|
+
def editItem loc, val
|
38
|
+
old_dir = @pref.parseDir @schedule[loc].attributes["p"]
|
39
|
+
@schedule[loc].setTitle val
|
40
|
+
new_dir = @pref.parseDir @schedule[loc].attributes["p"]
|
41
|
+
|
42
|
+
FileUtils.mv old_dir, new_dir unless old_dir == new_dir
|
43
|
+
|
44
|
+
save
|
45
|
+
end
|
46
|
+
|
47
|
+
def removeItem loc
|
48
|
+
@schedule.delete_at loc
|
49
|
+
save
|
50
|
+
end
|
51
|
+
|
52
|
+
def save
|
53
|
+
@pref.set "schedule", Base64.encode64(Marshal.dump @schedule)
|
54
|
+
end
|
55
|
+
|
56
|
+
def load
|
57
|
+
@pref.load
|
58
|
+
raw = @pref.get "schedule"
|
59
|
+
if not raw == nil and raw.class == String
|
60
|
+
@schedule = Marshal.load(Base64.decode64(raw))
|
61
|
+
else
|
62
|
+
empty?
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def makeHash(arr)
|
67
|
+
ret = {}
|
68
|
+
arr.each{ |t|
|
69
|
+
ret.merge!(t => t)
|
70
|
+
}
|
71
|
+
return ret
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require_relative '../item'
|
2
|
+
require 'securerandom'
|
3
|
+
|
4
|
+
class ScheduleItem < Item
|
5
|
+
|
6
|
+
def initialize(title, dir)
|
7
|
+
@dirpath = dir
|
8
|
+
@basepath = escapePath title
|
9
|
+
|
10
|
+
@attr = {
|
11
|
+
"t" => title,
|
12
|
+
"f" => title[0..4] + "…",
|
13
|
+
"r" => title,
|
14
|
+
"p" => @dirpath + @basepath,
|
15
|
+
"m" => "never"
|
16
|
+
}
|
17
|
+
|
18
|
+
@lastseen = 0
|
19
|
+
#@id = SecureRandom.uuid
|
20
|
+
end
|
21
|
+
|
22
|
+
def updataDir nd
|
23
|
+
@dirpath = nd
|
24
|
+
@attr["p"] = nd + @basepath
|
25
|
+
end
|
26
|
+
|
27
|
+
def escapePath path
|
28
|
+
path_ = path.gsub(":", "_")
|
29
|
+
path_.gsub("/", ":")
|
30
|
+
end
|
31
|
+
|
32
|
+
def setTitle newtitle
|
33
|
+
@attr["t"] = newtitle
|
34
|
+
@attr["f"] = newtitle[0..4] + "…"
|
35
|
+
@attr["p"] = @dirpath + escapePath(newtitle)
|
36
|
+
end
|
37
|
+
|
38
|
+
def setRegexp regexp
|
39
|
+
@attr["r"] = regexp
|
40
|
+
end
|
41
|
+
|
42
|
+
def setSeen
|
43
|
+
@lastseen = Time.now.to_s
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
@@ -0,0 +1,102 @@
|
|
1
|
+
require 'simple-rss'
|
2
|
+
require 'open-uri'
|
3
|
+
|
4
|
+
require_relative "../../util/stringhelp"
|
5
|
+
require_relative "../schedule/scheduleitem"
|
6
|
+
|
7
|
+
|
8
|
+
class Subscription
|
9
|
+
def initialize pref, schedule, delugec, client
|
10
|
+
@c = client
|
11
|
+
@pref = pref
|
12
|
+
@schedule = schedule
|
13
|
+
@delugec = delugec
|
14
|
+
end
|
15
|
+
|
16
|
+
def checkDaemon
|
17
|
+
if @c.server?
|
18
|
+
"daemon up"
|
19
|
+
else
|
20
|
+
"daemon down"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def updateFeed
|
25
|
+
begin
|
26
|
+
@rss = SimpleRSS.parse open(@pref.get("rss_feed")["url"])
|
27
|
+
|
28
|
+
rescue SocketError
|
29
|
+
@rss = nil
|
30
|
+
|
31
|
+
rescue
|
32
|
+
@rss = nil
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def feed
|
38
|
+
@rss
|
39
|
+
end
|
40
|
+
|
41
|
+
def getLastChecked
|
42
|
+
@c.lastchecked
|
43
|
+
end
|
44
|
+
|
45
|
+
def match regexp
|
46
|
+
updateFeed if @rss == nil
|
47
|
+
return [] if @rss == nil
|
48
|
+
re = Regexp.new regexp
|
49
|
+
matches = []
|
50
|
+
@rss.items.each{ |item|
|
51
|
+
re.match item[:title] { matches << item }
|
52
|
+
}
|
53
|
+
return matches
|
54
|
+
end
|
55
|
+
|
56
|
+
def matchAll
|
57
|
+
total_matches = 0
|
58
|
+
getAll.each { |subs|
|
59
|
+
matches = match subs.attributes["r"]
|
60
|
+
if matches.length >= 1
|
61
|
+
|
62
|
+
downloaddir = @pref.parseDir(subs.attributes["p"]) + "/"
|
63
|
+
newfile = downloaddir + matches[0][:title]
|
64
|
+
|
65
|
+
next if File.exist? newfile
|
66
|
+
|
67
|
+
s = @delugec.addTorrent matches[0][:link], @pref.parseDir(subs.attributes["p"])
|
68
|
+
subs.setSeen if s
|
69
|
+
@schedule.save
|
70
|
+
total_matches+=1
|
71
|
+
|
72
|
+
end
|
73
|
+
}
|
74
|
+
return total_matches
|
75
|
+
end
|
76
|
+
|
77
|
+
def forceMatch
|
78
|
+
@mthread = Thread.new do
|
79
|
+
updateFeed
|
80
|
+
matchAll
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def getAll
|
85
|
+
@schedule.load
|
86
|
+
@schedule.getAll
|
87
|
+
end
|
88
|
+
|
89
|
+
def editItem loc, newval
|
90
|
+
@schedule.getAll[loc].setRegexp newval
|
91
|
+
@schedule.save
|
92
|
+
end
|
93
|
+
|
94
|
+
def makeHash(arr)
|
95
|
+
ret = {}
|
96
|
+
arr.each{ |subs|
|
97
|
+
ret.merge!(subs => subs)
|
98
|
+
}
|
99
|
+
return ret
|
100
|
+
end
|
101
|
+
|
102
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'socket'
|
2
|
+
|
3
|
+
class SubscriptionDaemon
|
4
|
+
|
5
|
+
def initialize pref, subscription
|
6
|
+
@subscription = subscription
|
7
|
+
@pref = pref
|
8
|
+
|
9
|
+
end
|
10
|
+
|
11
|
+
def match
|
12
|
+
@subscription.updateFeed
|
13
|
+
@subscription.matchAll
|
14
|
+
end
|
15
|
+
|
16
|
+
def run
|
17
|
+
|
18
|
+
while true
|
19
|
+
|
20
|
+
match
|
21
|
+
|
22
|
+
sleep Integer(@pref.get("rss_feed")["refresh_interval"])
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
def start(mode="s")
|
29
|
+
|
30
|
+
puts "started daemon" if mode == "v"
|
31
|
+
|
32
|
+
@thread = Thread.new do
|
33
|
+
run
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
def exit
|
39
|
+
@thread.exit if @thread != nil
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
data/lib/aniview/util/alogger.rb
CHANGED
@@ -1,9 +1,18 @@
|
|
1
1
|
class ALogger
|
2
|
-
|
2
|
+
|
3
|
+
def initialize(file, overwrite = true)
|
4
|
+
|
3
5
|
@logfile = file
|
4
|
-
|
6
|
+
mode = "a"
|
7
|
+
mode = "w" if overwrite
|
8
|
+
open(@logfile, mode) { |f| f.puts "initialized..." }
|
9
|
+
|
5
10
|
end
|
11
|
+
|
6
12
|
def log(string)
|
7
|
-
|
13
|
+
|
14
|
+
open(@logfile, 'a') { |f| f.puts "#{Time.now.to_s} string" }
|
15
|
+
|
8
16
|
end
|
17
|
+
|
9
18
|
end
|