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