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.
- checksums.yaml +7 -0
- data/.gitignore +10 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +21 -0
- data/README.md +41 -0
- data/Rakefile +2 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/exe/flumtter +5 -0
- data/flumtter.gemspec +31 -0
- data/lib/flumtter.rb +2 -0
- data/lib/flumtter/app/core/account_selector.rb +88 -0
- data/lib/flumtter/app/core/client.rb +148 -0
- data/lib/flumtter/app/core/command.rb +24 -0
- data/lib/flumtter/app/core/command/dm.rb +12 -0
- data/lib/flumtter/app/core/command/tweet.rb +24 -0
- data/lib/flumtter/app/core/command/user.rb +52 -0
- data/lib/flumtter/app/core/command/userlist.rb +8 -0
- data/lib/flumtter/app/core/core.rb +58 -0
- data/lib/flumtter/app/core/curses.rb +90 -0
- data/lib/flumtter/app/core/hash.rb +29 -0
- data/lib/flumtter/app/core/initializer.rb +28 -0
- data/lib/flumtter/app/core/keyboard.rb +54 -0
- data/lib/flumtter/app/core/plugins.rb +27 -0
- data/lib/flumtter/app/core/string.rb +148 -0
- data/lib/flumtter/app/core/terminal.rb +13 -0
- data/lib/flumtter/app/core/thread.rb +29 -0
- data/lib/flumtter/app/core/toast.rb +26 -0
- data/lib/flumtter/app/core/util.rb +107 -0
- data/lib/flumtter/app/core/windows/base.rb +16 -0
- data/lib/flumtter/app/core/windows/buf_window.rb +194 -0
- data/lib/flumtter/app/core/windows/dialog.rb +62 -0
- data/lib/flumtter/app/core/windows/dmbase.rb +28 -0
- data/lib/flumtter/app/core/windows/dynamic_view.rb +43 -0
- data/lib/flumtter/app/core/windows/favorite.rb +31 -0
- data/lib/flumtter/app/core/windows/follower.rb +20 -0
- data/lib/flumtter/app/core/windows/following.rb +20 -0
- data/lib/flumtter/app/core/windows/mention.rb +29 -0
- data/lib/flumtter/app/core/windows/popup.rb +35 -0
- data/lib/flumtter/app/core/windows/tweet.rb +31 -0
- data/lib/flumtter/app/core/windows/tweetbase.rb +24 -0
- data/lib/flumtter/app/core/windows/userbase.rb +43 -0
- data/lib/flumtter/app/main.rb +3 -0
- data/lib/flumtter/app/plugins/commands.rb +15 -0
- data/lib/flumtter/app/plugins/commands/account_changer.rb +9 -0
- data/lib/flumtter/app/plugins/commands/change_profile.rb +69 -0
- data/lib/flumtter/app/plugins/commands/conversation.rb +39 -0
- data/lib/flumtter/app/plugins/commands/delete.rb +26 -0
- data/lib/flumtter/app/plugins/commands/directmessage.rb +35 -0
- data/lib/flumtter/app/plugins/commands/directmessages.rb +33 -0
- data/lib/flumtter/app/plugins/commands/favorite.rb +22 -0
- data/lib/flumtter/app/plugins/commands/mention.rb +7 -0
- data/lib/flumtter/app/plugins/commands/new_tweet.rb +17 -0
- data/lib/flumtter/app/plugins/commands/reply.rb +26 -0
- data/lib/flumtter/app/plugins/commands/retweet.rb +30 -0
- data/lib/flumtter/app/plugins/commands/unfavorite.rb +26 -0
- data/lib/flumtter/app/plugins/commands/user.rb +77 -0
- data/lib/flumtter/app/plugins/commands/utility.rb +17 -0
- data/lib/flumtter/app/plugins/load.rb +16 -0
- data/lib/flumtter/app/plugins/pry.rb +12 -0
- data/lib/flumtter/app/plugins/timeline.rb +42 -0
- data/lib/flumtter/app/plugins/timeline/base.rb +74 -0
- data/lib/flumtter/app/plugins/timeline/deleted_tweet.rb +23 -0
- data/lib/flumtter/app/plugins/timeline/dm.rb +23 -0
- data/lib/flumtter/app/plugins/timeline/event.rb +11 -0
- data/lib/flumtter/app/plugins/timeline/fav.rb +43 -0
- data/lib/flumtter/app/plugins/timeline/tweet.rb +51 -0
- data/lib/flumtter/app/plugins/toast.rb +45 -0
- data/lib/flumtter/version.rb +3 -0
- 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,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
|