flumtter 5.0.1

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.
Files changed (71) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +10 -0
  3. data/CODE_OF_CONDUCT.md +74 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE.txt +21 -0
  6. data/README.md +41 -0
  7. data/Rakefile +2 -0
  8. data/bin/console +14 -0
  9. data/bin/setup +8 -0
  10. data/exe/flumtter +5 -0
  11. data/flumtter.gemspec +31 -0
  12. data/lib/flumtter.rb +2 -0
  13. data/lib/flumtter/app/core/account_selector.rb +88 -0
  14. data/lib/flumtter/app/core/client.rb +148 -0
  15. data/lib/flumtter/app/core/command.rb +24 -0
  16. data/lib/flumtter/app/core/command/dm.rb +12 -0
  17. data/lib/flumtter/app/core/command/tweet.rb +24 -0
  18. data/lib/flumtter/app/core/command/user.rb +52 -0
  19. data/lib/flumtter/app/core/command/userlist.rb +8 -0
  20. data/lib/flumtter/app/core/core.rb +58 -0
  21. data/lib/flumtter/app/core/curses.rb +90 -0
  22. data/lib/flumtter/app/core/hash.rb +29 -0
  23. data/lib/flumtter/app/core/initializer.rb +28 -0
  24. data/lib/flumtter/app/core/keyboard.rb +54 -0
  25. data/lib/flumtter/app/core/plugins.rb +27 -0
  26. data/lib/flumtter/app/core/string.rb +148 -0
  27. data/lib/flumtter/app/core/terminal.rb +13 -0
  28. data/lib/flumtter/app/core/thread.rb +29 -0
  29. data/lib/flumtter/app/core/toast.rb +26 -0
  30. data/lib/flumtter/app/core/util.rb +107 -0
  31. data/lib/flumtter/app/core/windows/base.rb +16 -0
  32. data/lib/flumtter/app/core/windows/buf_window.rb +194 -0
  33. data/lib/flumtter/app/core/windows/dialog.rb +62 -0
  34. data/lib/flumtter/app/core/windows/dmbase.rb +28 -0
  35. data/lib/flumtter/app/core/windows/dynamic_view.rb +43 -0
  36. data/lib/flumtter/app/core/windows/favorite.rb +31 -0
  37. data/lib/flumtter/app/core/windows/follower.rb +20 -0
  38. data/lib/flumtter/app/core/windows/following.rb +20 -0
  39. data/lib/flumtter/app/core/windows/mention.rb +29 -0
  40. data/lib/flumtter/app/core/windows/popup.rb +35 -0
  41. data/lib/flumtter/app/core/windows/tweet.rb +31 -0
  42. data/lib/flumtter/app/core/windows/tweetbase.rb +24 -0
  43. data/lib/flumtter/app/core/windows/userbase.rb +43 -0
  44. data/lib/flumtter/app/main.rb +3 -0
  45. data/lib/flumtter/app/plugins/commands.rb +15 -0
  46. data/lib/flumtter/app/plugins/commands/account_changer.rb +9 -0
  47. data/lib/flumtter/app/plugins/commands/change_profile.rb +69 -0
  48. data/lib/flumtter/app/plugins/commands/conversation.rb +39 -0
  49. data/lib/flumtter/app/plugins/commands/delete.rb +26 -0
  50. data/lib/flumtter/app/plugins/commands/directmessage.rb +35 -0
  51. data/lib/flumtter/app/plugins/commands/directmessages.rb +33 -0
  52. data/lib/flumtter/app/plugins/commands/favorite.rb +22 -0
  53. data/lib/flumtter/app/plugins/commands/mention.rb +7 -0
  54. data/lib/flumtter/app/plugins/commands/new_tweet.rb +17 -0
  55. data/lib/flumtter/app/plugins/commands/reply.rb +26 -0
  56. data/lib/flumtter/app/plugins/commands/retweet.rb +30 -0
  57. data/lib/flumtter/app/plugins/commands/unfavorite.rb +26 -0
  58. data/lib/flumtter/app/plugins/commands/user.rb +77 -0
  59. data/lib/flumtter/app/plugins/commands/utility.rb +17 -0
  60. data/lib/flumtter/app/plugins/load.rb +16 -0
  61. data/lib/flumtter/app/plugins/pry.rb +12 -0
  62. data/lib/flumtter/app/plugins/timeline.rb +42 -0
  63. data/lib/flumtter/app/plugins/timeline/base.rb +74 -0
  64. data/lib/flumtter/app/plugins/timeline/deleted_tweet.rb +23 -0
  65. data/lib/flumtter/app/plugins/timeline/dm.rb +23 -0
  66. data/lib/flumtter/app/plugins/timeline/event.rb +11 -0
  67. data/lib/flumtter/app/plugins/timeline/fav.rb +43 -0
  68. data/lib/flumtter/app/plugins/timeline/tweet.rb +51 -0
  69. data/lib/flumtter/app/plugins/toast.rb +45 -0
  70. data/lib/flumtter/version.rb +3 -0
  71. metadata +213 -0
@@ -0,0 +1,26 @@
1
+ module Flumtter
2
+ plugin do
3
+ def delete(obj, twitter)
4
+ if obj.user.id == twitter.account.id
5
+ begin
6
+ twitter.rest.destroy_status(obj.id)
7
+ rescue Twitter::Error::NotFound => e
8
+ raise ExecutedError, e.message
9
+ end
10
+ else
11
+ raise ExecutedError, "You may not delete another user's status."
12
+ end
13
+ end
14
+
15
+ Keyboard.add("k", "Delete") do |m,twitter|
16
+ error_handler do
17
+ obj, _ = index_with_dialog(m[1], "Delete Screen", <<~EOF)
18
+ Please input target index.
19
+ EOF
20
+ if_tweet(obj, twitter) do |tweet|
21
+ delete(tweet, twitter)
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,35 @@
1
+ module Flumtter
2
+ plugin do
3
+ def directmessage(user, text, twitter)
4
+ case user
5
+ when Twitter::User
6
+ twitter.rest.create_direct_message(user.id, text)
7
+ else
8
+ twitter.rest.create_direct_message(user, text)
9
+ end
10
+ end
11
+
12
+ Keyboard.add("d", "Direct Message") do |m, twitter|
13
+ error_handler do
14
+ obj, m2 = index_with_dialog(m[1], "DirectMessage Screen", <<~EOF, true)
15
+ Please input target (index or screen_name) and DM content.
16
+ Syntax: '\#{index} \#{content}'
17
+ EOF
18
+ raise NoContentError if m2.empty?
19
+
20
+ case obj
21
+ when Twitter::Tweet, Twitter::Streaming::Event
22
+ if_tweet(obj, twitter) do |tweet|
23
+ directmessage(tweet.user, m2, twitter)
24
+ end
25
+ when Twitter::DirectMessage
26
+ directmessage(obj.sender, m2, twitter)
27
+ when String
28
+ directmessage(obj, m2, twitter)
29
+ else
30
+ raise UnSupportError
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,33 @@
1
+ module Flumtter
2
+ plugin do
3
+ class self::Buf < Window::Buf::Buf
4
+ Options = {count: 50}
5
+
6
+ def initialize(twitter)
7
+ @twitter = twitter
8
+ super(Window::DMBase)
9
+ end
10
+
11
+ def prefetch
12
+ adds(
13
+ @twitter.rest.direct_messages(
14
+ @buf.last.nil? ? Options : Options.merge(max_id: @buf.last.id-1)
15
+ )
16
+ )
17
+ end
18
+ end
19
+
20
+ class self::DirectMessage < Window::Buf::Screen
21
+ include Command::DM
22
+
23
+ def initialize(twitter)
24
+ super(Plugins::Directmessages::Buf.new(twitter), "#{twitter.account.screen_name}'s DirectMessages")
25
+ add_command(twitter)
26
+ end
27
+ end
28
+
29
+ Keyboard.add("b", "DirectMessages") do |m, twitter|
30
+ self::DirectMessage.new(twitter).show
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,22 @@
1
+ module Flumtter
2
+ plugin do
3
+ def favorite(obj, twitter)
4
+ if obj.favorited?
5
+ raise ExecutedError, "already favorited"
6
+ else
7
+ twitter.rest.favorite(obj.id)
8
+ end
9
+ end
10
+
11
+ Keyboard.add("f", "Favorite") do |m,twitter|
12
+ error_handler do
13
+ obj, _ = index_with_dialog(m[1], "Favorite Screen", <<~EOF)
14
+ Please input target index.
15
+ EOF
16
+ if_tweet(obj, twitter) do |tweet|
17
+ favorite(tweet, twitter)
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,7 @@
1
+ module Flumtter
2
+ plugin do
3
+ Keyboard.add("m", "Mention") do |m, twitter|
4
+ Window::Mention.new(twitter).show
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,17 @@
1
+ module Flumtter
2
+ plugin do
3
+ Keyboard.add("n", "New Tweet") do |m, twitter|
4
+ if m[1].empty?
5
+ dialog = Window::Dialog.new("Tweet Screen", <<~EOF)
6
+ Please input tweet content.
7
+ EOF
8
+ dialog.command(/(.+)/) do |m|
9
+ twitter.rest.update(m[1])
10
+ end
11
+ dialog.show(true, false)
12
+ else
13
+ twitter.rest.update(m[1])
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,26 @@
1
+ module Flumtter
2
+ plugin do
3
+ def update(obj,text,twitter)
4
+ twitter.rest.update("@#{obj.user.screen_name} #{text}", :in_reply_to_status_id => obj.id)
5
+ end
6
+
7
+ Keyboard.add("r", "Reply") do |m, twitter|
8
+ error_handler do
9
+ obj, m2 = index_with_dialog(m[1], "Reply Screen", <<~EOF)
10
+ Please input target index and tweet content.
11
+ Syntax: '\#{index} \#{content}'
12
+ EOF
13
+ case obj
14
+ when Twitter::Tweet, Twitter::Streaming::Event
15
+ if_tweet(obj, twitter) do |tweet|
16
+ update(tweet, m2, twitter)
17
+ end
18
+ when Twitter::DirectMessage
19
+ twitter.rest.create_direct_message(obj.sender.id, m2)
20
+ else
21
+ raise UnSupportError
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,30 @@
1
+ module Flumtter
2
+ plugin do
3
+ def retweet(obj, twitter)
4
+ if obj.retweeted?
5
+ raise ExecutedError, "already retweeted"
6
+ else
7
+ begin
8
+ twitter.rest.retweet(obj.id)
9
+ rescue Twitter::Error::Forbidden => e
10
+ if e.message == "You have already retweeted this tweet."
11
+ raise ExecutedError, "already retweeted"
12
+ else
13
+ raise e
14
+ end
15
+ end
16
+ end
17
+ end
18
+
19
+ Keyboard.add("t", "Retweet") do |m, twitter|
20
+ error_handler do
21
+ obj, _ = index_with_dialog(m[1], "Retweet Screen", <<~EOF)
22
+ Please input target index.
23
+ EOF
24
+ if_tweet(obj, twitter) do |tweet|
25
+ retweet(tweet, twitter)
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,26 @@
1
+ module Flumtter
2
+ plugin do
3
+ def unfavorite(obj, twitter)
4
+ begin
5
+ twitter.rest.unfavorite(obj.id)
6
+ rescue Twitter::Error::NotFound => e
7
+ if e.message == "No status found with that ID."
8
+ raise ExecutedError, "not favorited"
9
+ else
10
+ raise e
11
+ end
12
+ end
13
+ end
14
+
15
+ Keyboard.add("l", "UnFavorite") do |m,twitter|
16
+ error_handler do
17
+ obj, _ = index_with_dialog(m[1], "UnFavorite Screen", <<~EOF)
18
+ Please input target index.
19
+ EOF
20
+ if_tweet(obj, twitter) do |tweet|
21
+ unfavorite(tweet, twitter)
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,77 @@
1
+ module Flumtter
2
+ plugin do
3
+ class self::Profile < Window::DynamicView
4
+ include Command::User
5
+
6
+ def initialize(object, twitter)
7
+ @twitter = twitter
8
+ parse(object)
9
+ super("#{@user.screen_name}'s profile", "")
10
+ @width = 60
11
+ dynamic_view do
12
+ user = twitter.rest.user(@user)
13
+ <<~EOF
14
+ #{mutual.rjust(@width - 3)}
15
+ #{profile(user)}
16
+
17
+ #{statistics(user)}
18
+ EOF
19
+ end
20
+ add_command(@user, twitter)
21
+ show(true)
22
+ end
23
+
24
+ private
25
+ def mutual
26
+ friendship = @twitter.rest.friendship(@twitter.account.id, @user)
27
+ following = friendship.source.following? ? ">" : "/"
28
+ follower = friendship.source.followed_by? ? "<": "/"
29
+ "@#{@twitter.account.screen_name} #{following}=#{follower} @#{@user.screen_name}"
30
+ end
31
+
32
+ def profile(user)
33
+ {
34
+ name: user.name,
35
+ description: user.description.split_num(44),
36
+ location: user.location,
37
+ url: user.website.to_s
38
+ }.indent
39
+ end
40
+
41
+ def statistics(user)
42
+ {
43
+ tweets: user.tweets_count,
44
+ follow: user.friends_count,
45
+ follower: user.followers_count,
46
+ favorite: user.favorites_count
47
+ }.indent
48
+ end
49
+
50
+ def parse(obj)
51
+ @user = case obj
52
+ when Twitter::Tweet
53
+ obj.user
54
+ when Twitter::DirectMessage
55
+ ob.sender
56
+ when Twitter::Streaming::Event
57
+ ob.source
58
+ when Twitter::Streaming::DeletedTweet
59
+ obj.user
60
+ when String
61
+ @twitter.rest.user(obj)
62
+ else
63
+ raise UnSupportError
64
+ end
65
+ end
66
+ end
67
+
68
+ Keyboard.add("p", "User Profile") do |m, twitter|
69
+ error_handler do
70
+ obj, _ = index_with_dialog(m[1], "Select User Screen", <<~EOF, true)
71
+ Please input target (index or screen_name) and DM content.
72
+ EOF
73
+ self::Profile.new(obj, twitter)
74
+ end
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,17 @@
1
+ module Flumtter
2
+ plugin do
3
+ Keyboard.add("e", "Exit") do
4
+ puts "終了します".color
5
+ exit
6
+ end
7
+
8
+ Keyboard.add("q", "Clear Terminal Screen") do
9
+ print "\e[2J\e[f"
10
+ end
11
+
12
+ Keyboard.add("^", "Reconnection") do |m, twitter|
13
+ twitter.kill
14
+ twitter.start
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,16 @@
1
+ module Flumtter
2
+ plugin do
3
+ add_opt do |opt, options|
4
+ opt.on('--timeline_load VALUE', 'load timeline num'){|v|options[:timeline_load] = v.to_i}
5
+ opt.on('--[no-]timeline_load?', 'load timeline on init'){|v|options[:timeline_load?] = v}
6
+ end
7
+
8
+ on_event(:init) do |twitter|
9
+ if Setting[:timeline_load?]
10
+ twitter.rest.home_timeline(count: Setting[:timeline_load] || 20).reverse_each do |object|
11
+ puts TimeLine::Tweet.new(object, twitter).to_s
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,12 @@
1
+ module Flumtter
2
+ plugin do
3
+ add_opt do |opt, options|
4
+ opt.on('--pry', 'console mode'){|v|options[:pry] = v}
5
+ end
6
+
7
+ run_opt(:pry) do
8
+ binding.pry
9
+ exit
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,42 @@
1
+ module Flumtter
2
+ sarastire 'plugins/timeline'
3
+
4
+ plugin do
5
+ Client.on_event(:tweet) do |object, twitter|
6
+ type = object.type(twitter.account)
7
+ cls = if type.include?(:quote)
8
+ TimeLine::Quote
9
+ elsif type.include?(:retweet)
10
+ TimeLine::Retweet
11
+ elsif type.include?(:self_tweet)
12
+ TimeLine::SelfTweet
13
+ elsif type.include?(:reply_to_me)
14
+ TimeLine::ReplyTweet
15
+ else
16
+ TimeLine::Tweet
17
+ end
18
+ puts cls.new(object, twitter).to_s
19
+ end
20
+
21
+ Client.on_event(:event) do |object, twitter|
22
+ type = object.type(twitter.account)
23
+ cls = if type.include?(:favorite)
24
+ TimeLine::Favorite
25
+ elsif type.include?(:unfavorite)
26
+ TimeLine::UnFavorite
27
+ end
28
+ puts cls.new(object, twitter).to_s if cls
29
+ end
30
+
31
+ Client.on_event(:directmessage) do |object, twitter|
32
+ puts TimeLine::DirectMessage.new(object, twitter).to_s
33
+ end
34
+
35
+ Client.on_event(:deletedtweet) do |object, twitter|
36
+ begin
37
+ puts TimeLine::DeletedTweet.new(object, twitter).to_s
38
+ rescue TimeLine::DeletedTweet::TweetNotFound
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,74 @@
1
+ module Flumtter
2
+ module TimeLine
3
+ class Base
4
+ @@elements = []
5
+
6
+ def self.[](key)
7
+ @@elements[key]
8
+ end
9
+
10
+ def initialize(object, twitter)
11
+ @object = object
12
+ @twitter = twitter
13
+ @@elements << object
14
+ end
15
+
16
+ def to_s
17
+ text = <<~EOF.color(fg_color)
18
+ #{header}
19
+ #{user}
20
+ #{body}
21
+ #{footer}
22
+ EOF
23
+ bg_color.nil? ? text : text.background_color(bg_color)
24
+ end
25
+
26
+ private
27
+ def user
28
+ "#{@object.user.name} (@#{@object.user.screen_name})"
29
+ end
30
+
31
+ def color
32
+ :white
33
+ end
34
+
35
+ def fg_color
36
+ case color
37
+ when Symbol
38
+ color
39
+ when Array
40
+ color[0]
41
+ end
42
+ end
43
+
44
+ def bg_color
45
+ case color
46
+ when Symbol
47
+ nil
48
+ when Array
49
+ color[1]
50
+ end
51
+ end
52
+
53
+ def created_at
54
+ @object.created_at.strftime("%Y/%m/%d %H:%M:%S")
55
+ end
56
+
57
+ def index
58
+ @@elements.rindex(@object)
59
+ end
60
+
61
+ def header
62
+ "#{index} ".ljust(Terminal.x, ?-)
63
+ end
64
+
65
+ def body
66
+ @object.text.nl
67
+ end
68
+
69
+ def footer
70
+ "#{created_at}".ljust(Terminal.x, nil, @object.via)
71
+ end
72
+ end
73
+ end
74
+ end