aniview 0.3.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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 + "/.aw"
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
- dirname = File.dirname(@conf)
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
- @l = ALogger.new(Dir.home + "/desktop/validate.log")
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 parseTilde path
28
- path.gsub("~", Dir.home)
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
- return false if not Dir.exist?(parseTilde d)}
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.to_json) }
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
@@ -1,9 +1,18 @@
1
1
  class ALogger
2
- def initialize(file)
2
+
3
+ def initialize(file, overwrite = true)
4
+
3
5
  @logfile = file
4
- open(@logfile, 'w') { |f| f.puts "initialized..." }
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
- open(@logfile, 'a') { |f| f.puts string }
13
+
14
+ open(@logfile, 'a') { |f| f.puts "#{Time.now.to_s} string" }
15
+
8
16
  end
17
+
9
18
  end
@@ -8,6 +8,7 @@ class Command
8
8
  print "\033[" + String(term.rows) + ";1H"
9
9
  term.show_cursor
10
10
 
11
+ Readline.completion_append_character = ""
11
12
  Readline.pre_input_hook = -> do
12
13
  Readline.insert_text default
13
14
  Readline.redisplay