flumtter 5.0.1

Sign up to get free protection for your applications and to get access to all the features.
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,28 @@
1
+ module Flumtter
2
+ class Window::DMBase < Window::Buf::Element
3
+ def id
4
+ @object.id
5
+ end
6
+
7
+ private
8
+ def user
9
+ "#{@object.sender.name} (@#{@object.sender.screen_name})"
10
+ end
11
+
12
+ def created_at
13
+ @object.created_at.strftime("%Y/%m/%d %H:%M:%S")
14
+ end
15
+
16
+ def header
17
+ "#{@index} ".ljust(width, ?-, "@#{@object.sender.screen_name} => @#{@object.recipient.screen_name}")
18
+ end
19
+
20
+ def body
21
+ @object.text.nl
22
+ end
23
+
24
+ def footer
25
+ created_at
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,43 @@
1
+ require_relative 'base'
2
+
3
+ module Flumtter
4
+ module Window
5
+ class DynamicView < Dialog
6
+ def initialize(*args)
7
+ super
8
+ @hight += 1
9
+ end
10
+
11
+ def dynamic_view(&blk)
12
+ @view = blk
13
+ end
14
+
15
+ def show(recall=false)
16
+ Dispel::Screen.open do |screen|
17
+ view = @view.nil? ? "" : @view.call
18
+ Dispel::Window.open(@hight + (view.nil? ? 0 : view.size_of_lines), @width, 0, 0) do |win|
19
+ win.box(?|,?-,?*)
20
+ win.setpos(win.cury+2, win.curx+1)
21
+ win.addstr @title.title
22
+ win.setpos(win.cury+1, 1)
23
+ win.addstr "¯"*(@title.title.size+2)
24
+
25
+ add_multiline_str(win, @body)
26
+ win.setpos(win.cury+1, 1)
27
+ add_multiline_str(win, view)
28
+
29
+ win.setpos(win.cury+2, 1)
30
+ win.addstr "help: ?".rjust(win.maxx - 2)
31
+ win.setpos(win.cury+1, 1)
32
+ call getstr(win)
33
+ end
34
+ end
35
+ rescue Dispel::Recall
36
+ show(recall)
37
+ rescue Dispel::NoCommandError => e
38
+ Window::Popup::Error.new(e.class.to_s).show
39
+ show(recall) if recall
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,31 @@
1
+ module Flumtter
2
+ module Window
3
+ class FavoriteBuf < Buf::Buf
4
+ Options = {count: 50}
5
+
6
+ def initialize(user, twitter)
7
+ @twitter = twitter
8
+ @user = user
9
+ super(TweetBase)
10
+ end
11
+
12
+ def prefetch
13
+ adds(
14
+ @twitter.rest.favorites(
15
+ @user.id,
16
+ @buf.last.nil? ? Options : Options.merge(max_id: @buf.last.id-1)
17
+ )
18
+ )
19
+ end
20
+ end
21
+
22
+ class Favorite < Buf::Screen
23
+ include Command::Tweet
24
+
25
+ def initialize(user, twitter)
26
+ super(FavoriteBuf.new(user, twitter), "#{user.screen_name}'s Favorites")
27
+ add_command(twitter)
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,20 @@
1
+ require_relative 'userbase'
2
+
3
+ module Flumtter
4
+ module Window
5
+ class FollowerBuf < UserBuf
6
+ def prefetch
7
+ @ids ||= @twitter.rest.follower_ids(@user.id).to_a
8
+ adds(
9
+ @twitter.rest.users @ids.pop(100)
10
+ )
11
+ end
12
+ end
13
+
14
+ class Follower < User
15
+ def initialize(user, twitter)
16
+ super(FollowerBuf.new(user, twitter), "#{user.screen_name}'s Follower", twitter)
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,20 @@
1
+ require_relative 'userbase'
2
+
3
+ module Flumtter
4
+ module Window
5
+ class FollowingBuf < UserBuf
6
+ def prefetch
7
+ @ids ||= @twitter.rest.friend_ids(@user.id).to_a
8
+ adds(
9
+ @twitter.rest.users @ids.pop(100)
10
+ )
11
+ end
12
+ end
13
+
14
+ class Following < User
15
+ def initialize(user, twitter)
16
+ super(FollowingBuf.new(user, twitter), "#{user.screen_name}'s Following", twitter)
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,29 @@
1
+ module Flumtter
2
+ module Window
3
+ class MentionBuf < Buf::Buf
4
+ Options = {count: 50}
5
+
6
+ def initialize(twitter)
7
+ @twitter = twitter
8
+ super(TweetBase)
9
+ end
10
+
11
+ def prefetch
12
+ adds(
13
+ @twitter.rest.mentions(
14
+ @buf.last.nil? ? Options : Options.merge(max_id: @buf.last.id-1)
15
+ )
16
+ )
17
+ end
18
+ end
19
+
20
+ class Mention < Buf::Screen
21
+ include Command::Tweet
22
+
23
+ def initialize(twitter)
24
+ super(MentionBuf.new(twitter), "#{twitter.account.screen_name}'s Mentions")
25
+ add_command(twitter)
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,35 @@
1
+ require_relative 'base'
2
+
3
+ module Flumtter
4
+ module Window
5
+ class Popup < Base
6
+ def show
7
+ Dispel::Screen.open do |screen|
8
+ Dispel::Window.open(@hight, @width, 0, 0) do |win|
9
+ win.box(?|,?-,?*)
10
+ win.setpos(win.cury+2, win.curx+1)
11
+ win.addstr @title.title
12
+ win.setpos(win.cury+1, 1)
13
+ win.addstr "¯"*(@title.title.size+2)
14
+
15
+ add_multiline_str(win, @body)
16
+
17
+ win.getch
18
+ end
19
+ end
20
+ end
21
+ end
22
+
23
+ class Popup::Error < Popup
24
+ def initialize(body)
25
+ super("Error", body)
26
+ end
27
+ end
28
+
29
+ class Popup::Success < Popup
30
+ def initialize(body)
31
+ super("Success", body)
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,31 @@
1
+ module Flumtter
2
+ module Window
3
+ class TweetBuf < Buf::Buf
4
+ Options = {count: 50}
5
+
6
+ def initialize(user, twitter)
7
+ @twitter = twitter
8
+ @user = user
9
+ super(TweetBase)
10
+ end
11
+
12
+ def prefetch
13
+ adds(
14
+ @twitter.rest.user_timeline(
15
+ @user.id,
16
+ @buf.last.nil? ? Options : Options.merge(max_id: @buf.last.id-1)
17
+ )
18
+ )
19
+ end
20
+ end
21
+
22
+ class Tweet < Buf::Screen
23
+ include Command::Tweet
24
+
25
+ def initialize(user, twitter)
26
+ super(TweetBuf.new(user, twitter), "#{user.screen_name}'s Tweets")
27
+ add_command(twitter)
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,24 @@
1
+ module Flumtter
2
+ class Window::TweetBase < Window::Buf::Element
3
+ def id
4
+ @object.id
5
+ end
6
+
7
+ private
8
+ def user
9
+ "#{@object.user.name} (@#{@object.user.screen_name})"
10
+ end
11
+
12
+ def created_at
13
+ @object.created_at.strftime("%Y/%m/%d %H:%M:%S")
14
+ end
15
+
16
+ def body
17
+ @object.text.nl
18
+ end
19
+
20
+ def footer
21
+ "#{created_at}".ljust(width, nil, @object.via)
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,43 @@
1
+ module Flumtter
2
+ module Window
3
+ class UserBase < Buf::Element
4
+ def id
5
+ @object.id
6
+ end
7
+
8
+ def element
9
+ @text ||= <<~EOF
10
+ #{header}
11
+ #{
12
+ {
13
+ "#{@object.name} (@#{@object.screen_name})": {
14
+ description: @object.description.split_num(Terminal.x - 20),
15
+ location: @object.location,
16
+ url: @object.website.to_s
17
+ }
18
+ }.indent
19
+ }
20
+ EOF
21
+ end
22
+ end
23
+
24
+ class UserBuf < Buf::Buf
25
+ Options = {count: 50}
26
+
27
+ def initialize(user, twitter)
28
+ @twitter = twitter
29
+ @user = user
30
+ super(UserBase)
31
+ end
32
+ end
33
+
34
+ class User < Buf::Screen
35
+ include Command::UserList
36
+
37
+ def initialize(buf, title, twitter)
38
+ super(buf, title)
39
+ add_command(twitter)
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,3 @@
1
+ require_relative 'core/core'
2
+
3
+ Flumtter.start
@@ -0,0 +1,15 @@
1
+ module Flumtter
2
+ sarastire 'plugins/commands'
3
+
4
+ plugin do
5
+ Keyboard.add("v", "Version Information") do
6
+ Window::Popup.new("Version Information", <<~EOF).show
7
+ #{
8
+ {
9
+ Version: VERSION,
10
+ }.indent
11
+ }
12
+ EOF
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,9 @@
1
+ module Flumtter
2
+ plugin do
3
+ Keyboard.add("a", "Account Selector") do |m, twitter|
4
+ twitter.kill
5
+ twitter.set AccountSelector.select
6
+ twitter.start
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,69 @@
1
+ module Flumtter
2
+ plugin do
3
+ class self::Profile
4
+ include Util
5
+ alias_method :cvr, :command_value_regexp
6
+
7
+ def initialize(twitter)
8
+ @twitter = twitter
9
+ setting = Window::DynamicView.new("Change Profile", <<~EOF)
10
+ Please select item you want to change with new profile.
11
+ Syntax: '\#{item} \#{new profile}'
12
+ EOF
13
+ setting.dynamic_view do
14
+ user = twitter.rest.user
15
+ {
16
+ "Current value": {
17
+ name: user.name,
18
+ description: user.description.split_num(40),
19
+ location: user.location,
20
+ url: user.website.to_s
21
+ },
22
+ }.indent
23
+ end
24
+ %w(name description url location).each do |meth|
25
+ setting.command(cvr(meth)) do |m|
26
+ begin
27
+ send(meth, m)
28
+ rescue RangeError
29
+ Window::Popup::Error.new("Too short or Too long.").show
30
+ end
31
+ raise Dispel::Recall
32
+ end
33
+ end
34
+ setting.show(true)
35
+ end
36
+
37
+ def name(m)
38
+ m[1].range?(20)
39
+ update_profile(name: m[1])
40
+ end
41
+
42
+ def description(m)
43
+ m[1].range?(160)
44
+ update_profile(description: m[1])
45
+ end
46
+
47
+ def url(m)
48
+ m[1].range?(30)
49
+ update_profile(url: m[1])
50
+ end
51
+
52
+ def location(m)
53
+ m[1].range?(100)
54
+ update_profile(location: m[1])
55
+ end
56
+
57
+ private
58
+ def update_profile(hash)
59
+ @twitter.rest.update_profile(hash)
60
+ rescue Twitter::Error::Forbidden => e
61
+ Window::Popup::Error.new(e.message).show
62
+ end
63
+ end
64
+
65
+ Keyboard.add("c", "Change Profile") do |m, twitter|
66
+ self::Profile.new(twitter)
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,39 @@
1
+ module Flumtter
2
+ plugin do
3
+ class self::Buf < Window::Buf::Buf
4
+ def initialize(twitter)
5
+ @twitter = twitter
6
+ super(Window::TweetBase)
7
+ end
8
+
9
+ def prefetch
10
+ id = @buf.last&.object&.in_reply_to_status_id
11
+ add(
12
+ @twitter.rest.status(id)
13
+ ) unless id.nil?
14
+ end
15
+ end
16
+
17
+ class self::Conversation < Window::Buf::Screen
18
+ include Command::Tweet
19
+
20
+ def initialize(obj, twitter)
21
+ buf = Plugins::Conversation::Buf.new(twitter)
22
+ buf.add(obj)
23
+ super(buf, "Conversation")
24
+ add_command(twitter)
25
+ end
26
+ end
27
+
28
+ Keyboard.add("g", "Conversation") do |m, twitter|
29
+ error_handler do
30
+ obj, _ = index_with_dialog(m[1], "Conversation Screen", <<~EOF)
31
+ Please input target index.
32
+ EOF
33
+ if_tweet(obj, twitter) do |tweet|
34
+ self::Conversation.new(tweet, twitter).show
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end