twterm 1.3.0 → 2.0.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (121) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +14 -18
  3. data/bin/twterm +1 -1
  4. data/lib/twterm/app.rb +120 -30
  5. data/lib/twterm/client.rb +10 -13
  6. data/lib/twterm/completion_mamanger.rb +11 -6
  7. data/lib/twterm/direct_message.rb +6 -28
  8. data/lib/twterm/direct_message_composer.rb +10 -5
  9. data/lib/twterm/direct_message_manager.rb +5 -6
  10. data/lib/twterm/event/notification/abstract_notification.rb +27 -0
  11. data/lib/twterm/event/notification/error.rb +13 -0
  12. data/lib/twterm/event/notification/info.rb +13 -0
  13. data/lib/twterm/event/notification/success.rb +13 -0
  14. data/lib/twterm/event/notification/warning.rb +13 -0
  15. data/lib/twterm/event_dispatcher.rb +1 -1
  16. data/lib/twterm/extensions/array.rb +5 -0
  17. data/lib/twterm/extensions/enumerator/lazy.rb +3 -0
  18. data/lib/twterm/extensions/string.rb +0 -4
  19. data/lib/twterm/friendship.rb +1 -85
  20. data/lib/twterm/image/between.rb +31 -0
  21. data/lib/twterm/image/blank_line.rb +21 -0
  22. data/lib/twterm/image/bold.rb +31 -0
  23. data/lib/twterm/image/brackets.rb +21 -0
  24. data/lib/twterm/image/color.rb +45 -0
  25. data/lib/twterm/image/empty.rb +21 -0
  26. data/lib/twterm/image/horizontal_sequential_image.rb +48 -0
  27. data/lib/twterm/image/parens.rb +21 -0
  28. data/lib/twterm/image/string_image.rb +38 -0
  29. data/lib/twterm/image/vertical_sequential_image.rb +43 -0
  30. data/lib/twterm/image.rb +107 -0
  31. data/lib/twterm/key_mapper/abstract_key_mapper.rb +51 -0
  32. data/lib/twterm/key_mapper/app_key_mapper.rb +13 -0
  33. data/lib/twterm/key_mapper/cursor_key_mapper.rb +13 -0
  34. data/lib/twterm/key_mapper/general_key_mapper.rb +18 -0
  35. data/lib/twterm/key_mapper/no_such_command.rb +20 -0
  36. data/lib/twterm/key_mapper/no_such_key.rb +16 -0
  37. data/lib/twterm/key_mapper/status_key_mapper.rb +18 -0
  38. data/lib/twterm/key_mapper/tab_key_mapper.rb +31 -0
  39. data/lib/twterm/key_mapper.rb +127 -0
  40. data/lib/twterm/list.rb +0 -31
  41. data/lib/twterm/notifier.rb +7 -7
  42. data/lib/twterm/repository/abstract_entity_repository.rb +41 -0
  43. data/lib/twterm/repository/abstract_expirable_entity_repository.rb +35 -0
  44. data/lib/twterm/repository/abstract_repository.rb +64 -0
  45. data/lib/twterm/repository/direct_message_repository.rb +14 -0
  46. data/lib/twterm/repository/friendship_repository.rb +108 -0
  47. data/lib/twterm/repository/hashtag_repository.rb +39 -0
  48. data/lib/twterm/repository/list_repository.rb +14 -0
  49. data/lib/twterm/repository/status_repository.rb +36 -0
  50. data/lib/twterm/repository/user_repository.rb +22 -0
  51. data/lib/twterm/rest_client.rb +107 -63
  52. data/lib/twterm/screen.rb +21 -15
  53. data/lib/twterm/search_query_window.rb +139 -0
  54. data/lib/twterm/status.rb +14 -108
  55. data/lib/twterm/streaming_client.rb +13 -12
  56. data/lib/twterm/tab/base.rb +48 -8
  57. data/lib/twterm/tab/direct_message/conversation.rb +53 -52
  58. data/lib/twterm/tab/direct_message/conversation_list.rb +46 -45
  59. data/lib/twterm/tab/dumpable.rb +3 -3
  60. data/lib/twterm/tab/key_assignments_cheatsheet.rb +58 -57
  61. data/lib/twterm/tab/loadable.rb +20 -0
  62. data/lib/twterm/tab/new/list.rb +32 -43
  63. data/lib/twterm/tab/new/search.rb +31 -44
  64. data/lib/twterm/tab/new/start.rb +44 -55
  65. data/lib/twterm/tab/new/user.rb +15 -12
  66. data/lib/twterm/tab/rate_limit_status.rb +84 -0
  67. data/lib/twterm/tab/scrollable.rb +39 -19
  68. data/lib/twterm/tab/searchable.rb +133 -0
  69. data/lib/twterm/tab/statuses/base.rb +139 -129
  70. data/lib/twterm/tab/statuses/conversation.rb +26 -15
  71. data/lib/twterm/tab/statuses/favorites.rb +10 -8
  72. data/lib/twterm/tab/statuses/home.rb +10 -9
  73. data/lib/twterm/tab/statuses/list_timeline.rb +12 -8
  74. data/lib/twterm/tab/statuses/mentions.rb +17 -11
  75. data/lib/twterm/tab/statuses/search.rb +8 -5
  76. data/lib/twterm/tab/statuses/user_timeline.rb +11 -8
  77. data/lib/twterm/tab/user_list_management.rb +109 -0
  78. data/lib/twterm/tab/user_tab.rb +125 -126
  79. data/lib/twterm/tab/users/base.rb +39 -41
  80. data/lib/twterm/tab/users/followers.rb +9 -6
  81. data/lib/twterm/tab/users/friends.rb +9 -6
  82. data/lib/twterm/tab_manager.rb +64 -40
  83. data/lib/twterm/tweetbox.rb +18 -13
  84. data/lib/twterm/uri_opener.rb +2 -1
  85. data/lib/twterm/user.rb +2 -110
  86. data/lib/twterm/version.rb +1 -1
  87. data/lib/twterm/view.rb +30 -0
  88. data/lib/twterm.rb +3 -9
  89. data/spec/fixtures/status.json +107 -0
  90. data/spec/fixtures/user.json +102 -0
  91. data/spec/spec_helper.rb +7 -0
  92. data/spec/supports/shared_examples/abstract_key_mapper.rb +17 -0
  93. data/spec/twterm/extension/enumerator/lazy_spec.rb +11 -0
  94. data/spec/twterm/friendship_spec.rb +0 -102
  95. data/spec/twterm/image/blank_line_spec.rb +11 -0
  96. data/spec/twterm/image/brackets_spec.rb +12 -0
  97. data/spec/twterm/image/color_spec.rb +22 -0
  98. data/spec/twterm/image/empry_spec.rb +11 -0
  99. data/spec/twterm/image/horizontal_sequential_image_spec.rb +15 -0
  100. data/spec/twterm/image/parens_spec.rb +12 -0
  101. data/spec/twterm/image/string_image_spec.rb +12 -0
  102. data/spec/twterm/image/vertical_sequential_image_spec.rb +14 -0
  103. data/spec/twterm/image_spec.rb +65 -0
  104. data/spec/twterm/key_mapper/abstract_key_mapper_spec.rb +21 -0
  105. data/spec/twterm/key_mapper/app_key_mapper_spec.rb +7 -0
  106. data/spec/twterm/key_mapper/status_key_mapper_spec.rb +7 -0
  107. data/spec/twterm/key_mapper/tab_key_mapper_spec.rb +7 -0
  108. data/spec/twterm/repository/friendship_repository_spec.rb +108 -0
  109. data/spec/twterm/status_spec.rb +58 -0
  110. data/spec/twterm/user_spec.rb +94 -0
  111. data/twterm.gemspec +13 -10
  112. metadata +129 -35
  113. data/lib/twterm/event/notification.rb +0 -33
  114. data/lib/twterm/extensions/integer.rb +0 -5
  115. data/lib/twterm/filter_query_window.rb +0 -91
  116. data/lib/twterm/filterable_list.rb +0 -41
  117. data/lib/twterm/history/base.rb +0 -21
  118. data/lib/twterm/history/hashtag.rb +0 -13
  119. data/lib/twterm/history/savable.rb +0 -37
  120. data/lib/twterm/history/screen_name.rb +0 -11
  121. data/lib/twterm/promise.rb +0 -143
@@ -0,0 +1,31 @@
1
+ require 'twterm/key_mapper/abstract_key_mapper'
2
+
3
+ module Twterm
4
+ class KeyMapper
5
+ class TabKeyMapper < Twterm::KeyMapper::AbstractKeyMapper
6
+ DEFAULT_MAPPINGS = {
7
+ :'1st' => '1',
8
+ :'2nd' => '2',
9
+ :'3rd' => '3',
10
+ :'4th' => '4',
11
+ :'5th' => '5',
12
+ :'6th' => '6',
13
+ :'7th' => '7',
14
+ :'8th' => '8',
15
+ :'9th' => '9',
16
+ close: 'w',
17
+ find_next: 'n',
18
+ find_previous: 'N',
19
+ last: '0',
20
+ new: '^T',
21
+ reload: '^R',
22
+ search_down: '/',
23
+ search_up: '?',
24
+ }.freeze
25
+
26
+ def self.category
27
+ 'tab'.freeze
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,127 @@
1
+ require 'toml'
2
+ require 'singleton'
3
+
4
+ require 'twterm/app'
5
+ require 'twterm/key_mapper/abstract_key_mapper'
6
+ require 'twterm/key_mapper/app_key_mapper'
7
+ require 'twterm/key_mapper/cursor_key_mapper'
8
+ require 'twterm/key_mapper/general_key_mapper.rb'
9
+ require 'twterm/key_mapper/no_such_command'
10
+ require 'twterm/key_mapper/no_such_key'
11
+ require 'twterm/key_mapper/status_key_mapper.rb'
12
+ require 'twterm/key_mapper/tab_key_mapper'
13
+
14
+ module Twterm
15
+ class KeyMapper
16
+ include Singleton
17
+
18
+ MAPPERS = {
19
+ app: AppKeyMapper,
20
+ cursor: CursorKeyMapper,
21
+ general: GeneralKeyMapper,
22
+ status: StatusKeyMapper,
23
+ tab: TabKeyMapper,
24
+ }.freeze
25
+
26
+ def initialize
27
+ create_default_dict_file! unless dict_file_exists?
28
+ load_dict_file!
29
+ end
30
+
31
+ def [](category, kind)
32
+ (@mappings[category] || {})[kind]
33
+ end
34
+
35
+ def as_string(category, kind)
36
+ key = self[category, kind]
37
+
38
+ case key
39
+ when '!'..'}' then key
40
+ when Curses::Key::F1 then 'F1'
41
+ when Curses::Key::F2 then 'F2'
42
+ when Curses::Key::F3 then 'F3'
43
+ when Curses::Key::F4 then 'F4'
44
+ when Curses::Key::F5 then 'F5'
45
+ when Curses::Key::F6 then 'F6'
46
+ when Curses::Key::F7 then 'F7'
47
+ when Curses::Key::F8 then 'F8'
48
+ when Curses::Key::F9 then 'F9'
49
+ when Curses::Key::F10 then 'F10'
50
+ when Curses::Key::F11 then 'F11'
51
+ when Curses::Key::F12 then 'F12'
52
+ when 1..26 then "^#{(key + 'A'.ord - 1).chr}"
53
+ else ''
54
+ end
55
+ end
56
+
57
+ private
58
+
59
+ def assign_mappings!(dict)
60
+ @mappings = MAPPERS
61
+ .map { |c, m| { c => m.new(dict[c]) } }
62
+ .reduce({}) { |acc, x| acc.merge(x) }
63
+ rescue NoSuchCommand => e
64
+ warn "Unrecognized command detected: #{e.full_command}"
65
+ warn 'Make sure you have specified the correct command'
66
+ warn "Your key assignments are defined in #{dict_file_path}"
67
+
68
+ exit
69
+ rescue NoSuchKey => e
70
+ warn "Unrecognized key detected: #{e.key}"
71
+ warn 'Make sure you have specified the correct key'
72
+ warn "Your key assignments are defined in #{dict_file_path}"
73
+
74
+ exit
75
+ end
76
+
77
+ def create_default_dict_file!
78
+ dict = TOML.dump(default_mappings).gsub("\n[", "\n\n[")
79
+ File.open(dict_file_path, 'w', 0644) { |f| f.write(dict) }
80
+ end
81
+
82
+ def default_mappings
83
+ MAPPERS.map { |key, klass| [key, klass::DEFAULT_MAPPINGS] }.to_h
84
+ end
85
+
86
+ def dict_file_exists?
87
+ File.exist?(dict_file_path)
88
+ end
89
+
90
+ def dict_file_path
91
+ "#{App::DATA_DIR}/keys.toml".freeze
92
+ end
93
+
94
+ def getc
95
+ system('stty raw -echo')
96
+ STDIN.getc
97
+ ensure
98
+ system('stty -raw echo')
99
+ end
100
+
101
+ def load_dict_file!
102
+ dict = TOML.load_file(dict_file_path, symbolize_keys: true)
103
+ rescue TOML::ParseError, TOML::ValueOverwriteError => e
104
+ first_line =
105
+ case e
106
+ when TOML::ParseError
107
+ "Your key assignments dictionary file (#{dict_file_path}) could not be parsed"
108
+ when TOML::ValueOverwriteError
109
+ "Command `#{e.key}` is declared more than once"
110
+ end
111
+
112
+ warn <<-EOS
113
+ #{first_line}
114
+ Falling back to the default key assignments
115
+
116
+ Check the syntax and edit the file manually,
117
+ or remove it and launch twterm again to restore
118
+
119
+ Press any key to continue
120
+ EOS
121
+
122
+ getc
123
+ ensure
124
+ assign_mappings!(dict || default_mappings)
125
+ end
126
+ end
127
+ end
data/lib/twterm/list.rb CHANGED
@@ -2,8 +2,6 @@ module Twterm
2
2
  class List
3
3
  attr_reader :id, :name, :slug, :full_name, :mode, :description, :member_count, :subscriber_count
4
4
 
5
- @@instances = {}
6
-
7
5
  def ==(other)
8
6
  other.is_a?(self.class) && id == other.id
9
7
  end
@@ -11,13 +9,6 @@ module Twterm
11
9
  def initialize(list)
12
10
  @id = list.id
13
11
  update!(list)
14
-
15
- @@instances[@id] = self
16
- self
17
- end
18
-
19
- def matches?(query)
20
- [full_name, description].any? { |x| x.downcase.include?(query.downcase) }
21
12
  end
22
13
 
23
14
  def update!(list)
@@ -31,27 +22,5 @@ module Twterm
31
22
 
32
23
  self
33
24
  end
34
-
35
- def self.all
36
- @@instances.values
37
- end
38
-
39
- def self.find(id)
40
- @@instances[id]
41
- end
42
-
43
- def self.find_or_fetch(id)
44
- Promise.new do |resolve, reject|
45
- instance = find(id)
46
- (resolve.(instance) && next) if instance
47
-
48
- Client.current.list(id).then { |list| resolve.(list) }
49
- end
50
- end
51
-
52
- def self.new(list)
53
- instance = find(list.id)
54
- instance.nil? ? super : instance.update!(list)
55
- end
56
25
  end
57
26
  end
@@ -1,6 +1,6 @@
1
1
  require 'twterm/subscriber'
2
2
  require 'twterm/event/favorite'
3
- require 'twterm/event/notification'
3
+ require 'twterm/event/notification/abstract_notification'
4
4
  require 'twterm/event/screen/resize'
5
5
 
6
6
  module Twterm
@@ -14,15 +14,15 @@ module Twterm
14
14
  @queue = Queue.new
15
15
 
16
16
  subscribe(Event::Favorite) do |e|
17
- break if e.source.id == e.authenticating_user.user_id
17
+ next if e.source.id == e.authenticating_user.user_id
18
18
 
19
19
  msg = '@%s has favorited your tweet: %s' % [
20
20
  e.source.screen_name, e.target.text
21
21
  ]
22
- show_message(msg)
22
+ show_info(msg)
23
23
  end
24
24
 
25
- subscribe(Event::Notification) do |e|
25
+ subscribe(Event::Notification::AbstractNotification) do |e|
26
26
  queue(e)
27
27
  end
28
28
 
@@ -37,8 +37,8 @@ module Twterm
37
37
  end
38
38
  end
39
39
 
40
- def show_message(message)
41
- notification = Event::Notification.new(:message, message)
40
+ def show_info(message)
41
+ notification = Event::Notification::Info.new(message)
42
42
  @queue.push(notification)
43
43
  self
44
44
  end
@@ -51,7 +51,7 @@ module Twterm
51
51
 
52
52
  @window.clear
53
53
 
54
- if notification.is_a?(Event::Notification)
54
+ if notification.is_a?(Event::Notification::AbstractNotification)
55
55
  fg_color, bg_color = notification.color
56
56
 
57
57
  @window.with_color(fg_color, bg_color) do
@@ -0,0 +1,41 @@
1
+ require 'concurrent'
2
+
3
+ require 'twterm/repository/abstract_repository'
4
+
5
+ module Twterm
6
+ module Repository
7
+ class AbstractEntityRepository < AbstractRepository
8
+ def create(*args)
9
+ invoke_callbacks(:before_create, *args)
10
+
11
+ existing_instance = find(extract_key(args))
12
+
13
+ instance = existing_instance.nil? ? type.new(*args) : existing_instance.update!(*args)
14
+
15
+ store(instance)
16
+
17
+ invoke_callbacks(:after_create, instance)
18
+
19
+ instance
20
+ end
21
+
22
+ def find(key)
23
+ repository[key]
24
+ end
25
+
26
+ private
27
+
28
+ def empty_repository
29
+ Concurrent::Hash.new
30
+ end
31
+
32
+ def extract_key(args)
33
+ args[0].id
34
+ end
35
+
36
+ def store(instance)
37
+ repository[instance.id] = instance
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,35 @@
1
+ require 'concurrent'
2
+
3
+ require 'twterm/repository/abstract_entity_repository'
4
+
5
+ module Twterm
6
+ module Repository
7
+ class AbstractExpirableEntityRepository < AbstractEntityRepository
8
+ def initialize
9
+ super
10
+ @touched_at = Concurrent::Hash.new
11
+ end
12
+
13
+ def create(args, *)
14
+ touch(args.id)
15
+ super
16
+ end
17
+
18
+ def find(id)
19
+ touch(id)
20
+ super
21
+ end
22
+
23
+ def expire(threshold)
24
+ now = Time.now
25
+ repository.delete_if { |id, _| !@touched_at[id] || @touched_at[id] + threshold < now }
26
+ end
27
+
28
+ private
29
+
30
+ def touch(id)
31
+ @touched_at[id] = Time.now
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,64 @@
1
+ module Twterm
2
+ module Repository
3
+ class AbstractRepository
4
+ def initialize
5
+ @repository = empty_repository
6
+
7
+ @callbacks = {
8
+ after_create: [],
9
+ before_create: [],
10
+ }
11
+ end
12
+
13
+ def after_create(&block)
14
+ @callbacks[:after_create] << block
15
+ end
16
+
17
+ def before_create(&block)
18
+ @callbacks[:before_create] << block
19
+ end
20
+
21
+ def create(*args)
22
+ invoke_callbacks(:before_create, *args)
23
+
24
+ existing_instance = find(extract_key(args))
25
+
26
+ instance = existing_instance.nil? ? type.new(*args) : existing_instance
27
+
28
+ store(instance) if existing_instance.nil?
29
+
30
+ invoke_callbacks(:after_create, instance)
31
+
32
+ instance
33
+ end
34
+
35
+ def find(_key)
36
+ raise NotImplementedError, '`find` must be implemented'
37
+ end
38
+
39
+ def type
40
+ raise NotImplementedError, '`type` must be implemented'
41
+ end
42
+
43
+ private
44
+
45
+ attr_reader :repository
46
+
47
+ def empty_repository
48
+ raise NotImplementedError, '`empty_repository` must be implemented'
49
+ end
50
+
51
+ def extract_key(_args)
52
+ raise NotImplementedError, '`extract_key` must be implemented'
53
+ end
54
+
55
+ def invoke_callbacks(type, *args)
56
+ @callbacks[type].each { |cb| cb.call(*args) }
57
+ end
58
+
59
+ def store(_instance)
60
+ raise NotImplementedError, '`store` must be implemented'
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,14 @@
1
+ require 'twterm/direct_message'
2
+ require 'twterm/repository/abstract_entity_repository'
3
+
4
+ module Twterm
5
+ module Repository
6
+ class DirectMessageRepository < AbstractEntityRepository
7
+ private
8
+
9
+ def type
10
+ DirectMessage
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,108 @@
1
+ require 'concurrent'
2
+
3
+ require 'twterm/friendship'
4
+ require 'twterm/repository//abstract_repository'
5
+
6
+ module Twterm
7
+ module Repository
8
+ class FriendshipRepository < AbstractRepository
9
+ private :create
10
+
11
+ def initialize
12
+ super
13
+
14
+ @user_ids = Set.new
15
+ @m = Mutex.new
16
+ end
17
+
18
+ def already_looked_up?(user_id)
19
+ @m.synchronize { @user_ids.include?(user_id) }
20
+ end
21
+
22
+ def block(from, to)
23
+ create(:blocking, from, to)
24
+ end
25
+
26
+ def blocking?(from, to)
27
+ !find([:blocking, from, to]).nil?
28
+ end
29
+
30
+ def cancel_follow_request(from, to)
31
+ create(:following_requested, from, to)
32
+ end
33
+
34
+ def delete(status, from, to)
35
+ repository[status].delete_if { |f| f.status == status && f.from == from && f.to == to }
36
+ end
37
+
38
+ def follow(from, to)
39
+ create(:following, from, to)
40
+ end
41
+
42
+ def following?(from, to)
43
+ !find([:following, from, to]).nil?
44
+ end
45
+
46
+ def following_not_requested(from, to)
47
+ delete(:following_requested, from, to)
48
+ end
49
+
50
+ def following_requested(from, to)
51
+ create(:following_requested, from, to)
52
+ end
53
+
54
+ def following_requested?(from, to)
55
+ !find([:following_requested, from, to]).nil?
56
+ end
57
+
58
+ def looked_up!(user_id)
59
+ @m.synchronize { @user_ids << user_id }
60
+ user_id
61
+ end
62
+
63
+ def mute(from, to)
64
+ create(:muting, from, to)
65
+ end
66
+
67
+ def muting?(from, to)
68
+ !find([:muting, from, to]).nil?
69
+ end
70
+
71
+ def unblock(from, to)
72
+ delete(:blocking, from, to)
73
+ end
74
+
75
+ def unfollow(from, to)
76
+ delete(:following, from, to)
77
+ end
78
+
79
+ def unmute(from, to)
80
+ delete(:muting, from, to)
81
+ end
82
+
83
+ private
84
+
85
+ def find(key)
86
+ status, from, to = key
87
+
88
+ repository[status].find { |f| f.from == from && f.to == to }
89
+ end
90
+
91
+ def extract_key(args)
92
+ args
93
+ end
94
+
95
+ def empty_repository
96
+ Friendship::STATUSES.map { |s| [s, Concurrent::Array.new] }.to_h
97
+ end
98
+
99
+ def store(instance)
100
+ repository[instance.status] << instance
101
+ end
102
+
103
+ def type
104
+ Friendship
105
+ end
106
+ end
107
+ end
108
+ end
@@ -0,0 +1,39 @@
1
+ require 'twterm/repository/abstract_repository'
2
+
3
+ module Twterm
4
+ module Repository
5
+ class HashtagRepository < AbstractRepository
6
+ def initialize
7
+ @m = Mutex.new
8
+
9
+ super
10
+ end
11
+
12
+ def all
13
+ repository.to_a
14
+ end
15
+
16
+ private
17
+
18
+ def empty_repository
19
+ Set.new
20
+ end
21
+
22
+ def extract_key(args)
23
+ args[0]
24
+ end
25
+
26
+ def find(key)
27
+ repository.include?(key) ? key : nil
28
+ end
29
+
30
+ def store(hashtag)
31
+ @m.synchronize { repository << hashtag }
32
+ end
33
+
34
+ def type
35
+ String
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,14 @@
1
+ require 'twterm/repository/abstract_entity_repository'
2
+ require 'twterm/list'
3
+
4
+ module Twterm
5
+ module Repository
6
+ class ListRepository < AbstractEntityRepository
7
+ private
8
+
9
+ def type
10
+ List
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,36 @@
1
+ require 'twterm/repository/abstract_expirable_entity_repository'
2
+ require 'twterm/status'
3
+
4
+ module Twterm
5
+ module Repository
6
+ class StatusRepository < AbstractExpirableEntityRepository
7
+ def all
8
+ repository.values
9
+ end
10
+
11
+ def create(tweet, is_retweeted_status = false)
12
+ create(tweet.retweeted_status, true) unless tweet.retweeted_status.is_a?(Twitter::NullObject)
13
+ super
14
+ end
15
+
16
+ def delete(id)
17
+ @touched_at.delete(id)
18
+ repository.delete(id)
19
+ end
20
+
21
+ def find_replies_for(id)
22
+ repository.values.select { |s| s.in_reply_to_status_id == id }
23
+ end
24
+
25
+ def ids
26
+ repository.keys
27
+ end
28
+
29
+ private
30
+
31
+ def type
32
+ Status
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,22 @@
1
+ require 'twterm/repository/abstract_expirable_entity_repository'
2
+ require 'twterm/user'
3
+
4
+ module Twterm
5
+ module Repository
6
+ class UserRepository < AbstractExpirableEntityRepository
7
+ def all
8
+ repository.values
9
+ end
10
+
11
+ def ids
12
+ repository.keys
13
+ end
14
+
15
+ private
16
+
17
+ def type
18
+ User
19
+ end
20
+ end
21
+ end
22
+ end