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,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