lib/ayadn/action.rb in ayadn-3.0 vs lib/ayadn/action.rb in ayadn-4.0

- old
+ new

@@ -8,108 +8,47 @@ require_relative "stream" def initialize @api = API.new - @view = View.new - @workers = Workers.new - @status = Status.new - @check = Check.new + @status = Status.new + @workers = Workers.new(@status) + @view = View.new(@status, @workers) + @check = Check.new(@status) Settings.load_config Settings.get_token Settings.init_config Logs.create_logger Databases.open_databases end - def method_missing(meth, options) - case meth.to_s - when 'unified', 'checkins', 'global', 'trending', 'photos', 'conversations', 'interactions' - begin - Settings.options[:timeline][:compact] = true if options[:compact] == true - stream = Stream.new(@api, @view, @workers) - stream.send(meth.to_sym, options) - rescue => e - Errors.global_error({error: e, caller: caller, data: [meth, options]}) - end - else - super - end - end - - def mentions(username, options) + # Uses method_missing to template a single method for several streams + def method_missing(meth, *args) begin - Settings.options[:timeline][:compact] = true if options[:compact] == true - stream = Stream.new(@api, @view, @workers) - stream.mentions(username, options) + options = if args.size > 1 + args[1] + else + args[0] + end + Settings.options.timeline.compact = true if options[:compact] + Settings.global.force = true if options[:force] + stream = Stream.new(@api, @view, @workers, @check, @status) + case meth + when :mentions, :posts, :whatstarred, :whoreposted, :whostarred, :convo, :followings, :followers, :messages + stream.send(meth, args[0], options) + when :unified, :checkins, :global, :trending, :photos, :conversations, :interactions, :muted, :blocked, :random_posts + stream.send(meth, options) + end rescue => e - Errors.global_error({error: e, caller: caller, data: [username, options]}) + Errors.global_error({error: e, caller: caller, data: [meth, options]}) end end - def posts(username, options) - begin - Settings.options[:timeline][:compact] = true if options[:compact] == true - stream = Stream.new(@api, @view, @workers) - stream.posts(username, options) - rescue => e - Errors.global_error({error: e, caller: caller, data: [username, options]}) - end - end - - def whatstarred(username, options) - begin - Settings.options[:timeline][:compact] = true if options[:compact] == true - stream = Stream.new(@api, @view, @workers) - stream.whatstarred(username, options) - rescue => e - Errors.global_error({error: e, caller: caller, data: [username, options]}) - end - end - - def whoreposted(post_id, options) - begin - Settings.options[:timeline][:compact] = true if options[:compact] == true - stream = Stream.new(@api, @view, @workers) - stream.whoreposted(post_id, options) - rescue => e - Errors.global_error({error: e, caller: caller, data: [post_id, options]}) - end - end - - def whostarred(post_id, options) - begin - Settings.options[:timeline][:compact] = true if options[:compact] == true - stream = Stream.new(@api, @view, @workers) - stream.whostarred(post_id, options) - rescue => e - Errors.global_error({error: e, caller: caller, data: [post_id, options]}) - end - end - - def convo(post_id, options) - begin - Settings.options[:timeline][:compact] = true if options[:compact] == true - stream = Stream.new(@api, @view, @workers) - stream.convo(post_id, options) - rescue => e - Errors.global_error({error: e, caller: caller, data: [post_id, options]}) - end - end - def delete(post_ids, options = {}) begin - ids = post_ids.select { |post_id| post_id.is_integer? } - if ids.empty? - @status.error_missing_post_id - exit - end - if options[:force] - Settings.global[:force] = true - else - ids.map! { |post_id| @workers.get_real_post_id(post_id) } - end + ids = get_posts_ids_or_exit(post_ids) { @status.error_missing_post_id } + ids = get_real_posts_ids_or_force(options, ids) puts "\n" ids.each do |post_id| @status.deleting_post(post_id) resp = @api.delete_post(post_id) @check.has_been_deleted(post_id, resp) @@ -125,15 +64,11 @@ @status.error_missing_message_id exit end channel = args[0] args.shift - ids = args.select {|message_id| message_id.is_integer?} - if ids.empty? - @status.error_missing_message_id - exit - end + ids = get_posts_ids_or_exit(args) { @status.error_missing_message_id } channel_id = @workers.get_channel_id_from_alias(channel) puts "\n" ids.each do |message_id| @status.deleting_message(message_id) resp = @api.delete_message(channel_id, message_id) @@ -144,12 +79,12 @@ end end def unfollow(usernames) begin - @check.no_username(usernames) - users = @workers.all_but_me(usernames) + # Verify CLI input, remove current user from list (you never know) to avoid API error + users = get_all_usernames_but_me(usernames) puts "\n" @status.unfollowing(users.join(',')) users.each do |user| resp = @api.unfollow(user) @check.has_been_unfollowed(user, resp) @@ -159,12 +94,11 @@ end end def follow(usernames) begin - @check.no_username(usernames) - users = @workers.all_but_me(usernames) + users = get_all_usernames_but_me(usernames) puts "\n" @status.following(users.join(',')) users.each do |user| resp = @api.follow(user) @check.has_been_followed(user, resp) @@ -174,12 +108,11 @@ end end def unmute(usernames) begin - @check.no_username(usernames) - users = @workers.all_but_me(usernames) + users = get_all_usernames_but_me(usernames) puts "\n" @status.unmuting(users.join(',')) users.each do |user| resp = @api.unmute(user) @check.has_been_unmuted(user, resp) @@ -189,12 +122,11 @@ end end def mute(usernames) begin - @check.no_username(usernames) - users = @workers.all_but_me(usernames) + users = get_all_usernames_but_me(usernames) puts "\n" @status.muting(users.join(',')) users.each do |user| resp = @api.mute(user) @check.has_been_muted(user, resp) @@ -204,12 +136,11 @@ end end def unblock(usernames) begin - @check.no_username(usernames) - users = @workers.all_but_me(usernames) + users = get_all_usernames_but_me(usernames) puts "\n" @status.unblocking(users.join(',')) users.each do |user| resp = @api.unblock(user) @check.has_been_unblocked(user, resp) @@ -219,12 +150,11 @@ end end def block(usernames) begin - @check.no_username(usernames) - users = @workers.all_but_me(usernames) + users = get_all_usernames_but_me(usernames) puts "\n" @status.blocking(users.join(',')) users.each do |user| resp = @api.block(user) @check.has_been_blocked(user, resp) @@ -234,45 +164,33 @@ end end def repost(post_ids, options = {}) begin - ids = post_ids.select { |post_id| post_id.is_integer? } - if ids.empty? - @status.error_missing_post_id - exit - end - if options[:force] - Settings.global[:force] = true - else - ids.map! { |post_id| @workers.get_real_post_id(post_id) } - end + ids = get_posts_ids_or_exit(post_ids) { @status.error_missing_post_id } + ids = get_real_posts_ids_or_force(options, ids) puts "\n" ids.each do |post_id| @status.reposting(post_id) + # Retrieve the post we want to repost resp = @api.get_details(post_id) + # Verify it hasn't been already reposted by us @check.already_reposted(resp) + # Maybe the post is already a repost by someone else? id = @workers.get_original_id(post_id, resp) + # Repost then verify it has been done @check.has_been_reposted(id, @api.repost(id)) end rescue => e Errors.global_error({error: e, caller: caller, data: [post_ids, id]}) end end def unrepost(post_ids, options = {}) begin - ids = post_ids.select { |post_id| post_id.is_integer? } - if ids.empty? - @status.error_missing_post_id - exit - end - if options[:force] - Settings.global[:force] = true - else - ids.map! { |post_id| @workers.get_real_post_id(post_id) } - end + ids = get_posts_ids_or_exit(post_ids) { @status.error_missing_post_id } + ids = get_real_posts_ids_or_force(options, ids) puts "\n" ids.each do |post_id| @status.unreposting(post_id) if @api.get_details(post_id)['data']['you_reposted'] @check.has_been_unreposted(post_id, @api.unrepost(post_id)) @@ -285,20 +203,12 @@ end end def unstar(post_ids, options = {}) begin - ids = post_ids.select { |post_id| post_id.is_integer? } - if ids.empty? - @status.error_missing_post_id - exit - end - if options[:force] - Settings.global[:force] = true - else - ids.map! { |post_id| @workers.get_real_post_id(post_id) } - end + ids = get_posts_ids_or_exit(post_ids) { @status.error_missing_post_id } + ids = get_real_posts_ids_or_force(options, ids) puts "\n" ids.each do |post_id| @status.unstarring(post_id) resp = @api.get_details(post_id) id = @workers.get_original_id(post_id, resp) @@ -314,20 +224,12 @@ end end def star(post_ids, options = {}) begin - ids = post_ids.select { |post_id| post_id.is_integer? } - if ids.empty? - @status.error_missing_post_id - exit - end - if options[:force] - Settings.global[:force] = true - else - ids.map! { |post_id| @workers.get_real_post_id(post_id) } - end + ids = get_posts_ids_or_exit(post_ids) { @status.error_missing_post_id } + ids = get_real_posts_ids_or_force(options, ids) puts "\n" ids.each do |post_id| @status.starring(post_id) resp = @api.get_details(post_id) @check.already_starred(resp) @@ -339,75 +241,32 @@ end end def hashtag(hashtag, options) begin - Settings.options[:timeline][:compact] = true if options[:compact] == true search = Search.new(@api, @view, @workers) search.hashtag(hashtag, options) rescue => e Errors.global_error({error: e, caller: caller, data: [hashtag, options]}) end end def search(words, options) begin - Settings.options[:timeline][:compact] = true if options[:compact] == true search = Search.new(@api, @view, @workers) search.find(words, options) rescue => e Errors.global_error({error: e, caller: caller, data: [words, options]}) end end - def followings(username, options) - begin - Settings.options[:timeline][:compact] = true if options[:compact] == true - stream = Stream.new(@api, @view, @workers) - stream.followings(username, options) - rescue => e - Errors.global_error({error: e, caller: caller, data: [username, options]}) - end - end - - def followers(username, options) - begin - Settings.options[:timeline][:compact] = true if options[:compact] == true - stream = Stream.new(@api, @view, @workers) - stream.followers(username, options) - rescue => e - Errors.global_error({error: e, caller: caller, data: [username, options]}) - end - end - - def muted(options) - begin - Settings.options[:timeline][:compact] = true if options[:compact] == true - stream = Stream.new(@api, @view, @workers) - stream.muted(options) - rescue => e - Errors.global_error({error: e, caller: caller, data: [options]}) - end - end - - def blocked(options) - begin - Settings.options[:timeline][:compact] = true if options[:compact] == true - stream = Stream.new(@api, @view, @workers) - stream.blocked(options) - rescue => e - Errors.global_error({error: e, caller: caller, data: [options]}) - end - end - def view_settings(options) begin if options[:raw] - jj JSON.parse(Settings.config.to_json) - jj JSON.parse(Settings.options.to_json) + jj JSON.parse(Settings.options.to_h.to_json) else - Settings.options[:timeline][:compact] = true if options[:compact] == true + Settings.options.timeline.compact = true if options[:compact] @view.show_settings end rescue => e Errors.global_error({error: e, caller: caller, data: [options]}) end @@ -427,72 +286,72 @@ end end def userinfo(username, options = {}) begin - Settings.options[:timeline][:compact] = true if options[:compact] == true + Settings.options.timeline.compact = true if options[:compact] @check.no_username(username) usernames = @workers.add_arobases_to_usernames(username) usernames.each.with_index do |username, index| if options[:raw] @view.show_raw(@api.get_user(username), options) else @view.downloading if index == 0 - stream = @api.get_user(username) - @check.no_user(stream, username) - @check.same_username(stream) ? token = @api.get_token_info['data'] : token = nil + user_object = UserObject.new(@api.get_user(username), username) + # Is it us? If yes, get *our* info + @check.same_username(user_object) ? token = @api.get_token_info['data'] : token = nil @view.clear_screen if index == 0 - @view.infos(stream['data'], token) + @view.infos(user_object, token) end end rescue => e Errors.global_error({error: e, caller: caller, data: [username, options]}) end end def postinfo(post_id, options) begin @check.bad_post_id(post_id) - Settings.options[:timeline][:compact] = true if options[:compact] == true - if options[:force] - Settings.global[:force] = true - else - post_id = @workers.get_real_post_id(post_id) - end + Settings.options.timeline.compact = true if options[:compact] + post_id = get_real_post_id_or_force(options, post_id) details = lambda { @api.get_details(post_id, options) } if options[:raw] @view.show_raw(details.call, options) exit end @view.clear_screen response = details.call - @check.no_post(response, post_id) - resp = response['data'] + @check.no_details(response, post_id) - if resp["is_deleted"] == true - @status.user_404(resp["id"]) + post_object = PostObject.new(response["data"]) + + if post_object.is_deleted + @status.user_404(post_object.id) Errors.global_error({error: "user 404", caller: caller, data: [post_id, options]}) end - response = @api.get_user("@#{resp['user']['username']}") - @check.no_user(response, response['data']['username']) - stream = response['data'] + response = @api.get_user("@#{post_object.user.username}") + user_object = UserObject.new(response, post_object.user.username) + @status.post_info - @view.show_simple_post([resp], options) - puts "\n" if Settings.options[:timeline][:compact] == true + @view.show_simple_post([post_object], options) + puts "\n" if Settings.options.timeline.compact @status.say_info "author" - puts "\n" unless Settings.options[:timeline][:compact] == true - if response['data']['username'] == Settings.config[:identity][:username] - @view.show_userinfos(stream, @api.get_token_info['data'], true) + puts "\n" unless Settings.options.timeline.compact + # Is it us? ... + if user_object.username == Settings.config.identity.username + @view.show_userinfos(post_object.user, @api.get_token_info['data'], true) else - @view.show_userinfos(stream, nil, true) + @view.show_userinfos(post_object.user, nil, true) end - if resp['repost_of'] + + if !post_object.repost_of.nil? @status.repost_info - Errors.repost(post_id, resp['repost_of']['id']) - @view.show_simple_post([resp['repost_of']], options) - puts "\n" if Settings.options[:timeline][:compact] == true + # If we ask infos for a reposted post, fetch the original instead + Errors.repost(post_id, post_object.repost_of.id) + @view.show_simple_post([post_object.repost_of], options) + puts "\n" if Settings.options.timeline.compact end rescue => e Errors.global_error({error: e, caller: caller, data: [post_id, options]}) end end @@ -524,81 +383,74 @@ end end def channels options begin + # Input could be channel IDs or channel aliases channels = if options[:id] channel_id = options[:id].map {|id| @workers.get_channel_id_from_alias(id)} lambda { @api.get_channel(channel_id, options) } else lambda { @api.get_channels } end if options[:raw] - @view.show_raw(channels.call) + @view.show_direct_raw(channels.call) exit else @view.downloading resp = channels.call @view.clear_screen - @view.show_channels(resp, options) + channels = resp["data"].map { |ch| ChannelObject.new(ch) } + @view.show_channels(channels, options) end rescue => e Errors.global_error({error: e, caller: caller, data: [options]}) end end - def messages(channel_id, options) - begin - Settings.options[:timeline][:compact] = true if options[:compact] == true - stream = Stream.new(@api, @view, @workers) - stream.messages(channel_id, options) - rescue => e - Errors.global_error({error: e, caller: caller, data: [channel_id, options]}) - end - end - def messages_unread(options) begin - Settings.options[:timeline][:compact] = true if options[:compact] == true - if options[:silent] - Settings.options[:marker][:messages] = false - end + Settings.options.timeline.compact = true if options[:compact] + Settings.options.marker.messages = false if options[:silent] # Option to not mark the messages as read puts "\n" @status.say_nocolor :searching, "channels with unread PMs" - response = @api.get_channels + channels_objects = @api.get_channels['data'].map { |obj| ChannelObject.new(obj) } unread_channels = [] - response['data'].map do |ch| - if ch['type'] == "net.app.core.pm" && ch['has_unread'] == true - unread_channels << ch['id'] + channels_objects.each do |ch| + # Channels can be of many types, PMs are only one type + if ch.type == "net.app.core.pm" && ch.has_unread + unread_channels << ch.id end end if unread_channels.empty? @status.no_new_messages exit end unread_messages = {} unread_channels.reverse.each do |id| @status.say_nocolor :downloading, "messages from channel #{id}" + # Find the last time we've done this since = Databases.find_last_id_from("channel:#{id}") unless since.nil? api_options = {count: 20, since_id: since} else api_options = {count: 20} end ch = @api.get_messages(id, api_options) + # Find the last message seen and the last message in the channel last_read_id = ch['meta']['marker']['last_read_id'].to_i last_message_id = ch['meta']['max_id'] - messages = [] - ch['data'].each do |msg| - messages << msg if msg['id'].to_i > last_read_id - end + messages = ch['data'].map { |msg| msg if msg['id'].to_i > last_read_id } unread_messages[id] = [messages, last_message_id] end - if Settings.options[:marker][:messages] == true + # If we want to mark the messages as read + if Settings.options.marker.messages unread_messages.each do |k,v| name = "channel:#{k}" + # Save the reading position locally Databases.pagination_insert(name, v[1]) + # Mark as read resp = @api.update_marker(name, v[1]) res = JSON.parse(resp) if res['meta']['code'] != 200 @status.say_error "couldn't update channel #{k} as read" else @@ -607,13 +459,14 @@ end end @view.clear_screen unread_messages.each do |k,v| @status.unread_from_channel(k) - @view.show_posts(v[0]) + messages_objects = v[0].map { |post_hash| PostObject.new(post_hash) } + @view.show_messages(messages_objects) end - puts "\n" if Settings.options[:timeline][:compact] + puts "\n" if Settings.options.timeline.compact rescue => e Errors.global_error({error: e, caller: caller, data: [options]}) end end @@ -626,33 +479,36 @@ puts "RUBY: #{e}\n\n" exit end begin @check.bad_post_id(post_id) - Settings.options[:timeline][:compact] = true if options[:compact] == true - if options[:force] - Settings.global[:force] = true - else - post_id = @workers.get_real_post_id(post_id) - end + Settings.options.timeline.compact = true if options[:compact] + post_id = get_real_post_id_or_force(options, post_id) @view.downloading - resp = @api.get_details(post_id)['data'] + # Get the details from the post we want to send to Pinboard + # resp = @api.get_details(post_id)['data'] @view.clear_screen - links = @workers.extract_links(resp) - resp['text'].nil? ? text = "" : text = resp['text'] + # Extract links from the post + post_object = PostObject.new(@api.get_details(post_id)['data']) + links = @workers.extract_links(post_object) + # In case the post has no text, to prevent an error + post_object.text.nil? ? text = "" : text = post_object.text + # The first tag is always "ADN" usertags << "ADN" - handle = "@" + resp['user']['username'] + handle = "@" + post_object.user.username post_text = "From: #{handle} -- Text: #{text} -- Links: #{links.join(" ")}" pinner = Ayadn::PinBoard.new unless pinner.has_credentials_file? + # No Pinboard account registered? Ask for one. @status.no_pin_creds - pinner.ask_credentials + pinner.ask_credentials(@status) @status.pin_creds_saved end + # Get stored credentials credentials = pinner.load_credentials maker = Struct.new(:username, :password, :url, :tags, :text, :description) - bookmark = maker.new(credentials[0], credentials[1], resp['canonical_url'], usertags.join(","), post_text, resp['canonical_url']) + bookmark = maker.new(credentials[0], credentials[1], post_object.canonical_url, usertags.join(","), post_text, post_object.canonical_url) @status.saving_pin pinner.pin(bookmark) @status.done rescue => e Errors.global_error({error: e, caller: caller, data: [post_id, usertags]}) @@ -661,256 +517,210 @@ def auto(options) begin @view.clear_screen @status.auto - Post.new.auto_readline + Post.new(@status).auto_readline rescue => e Errors.global_error({error: e, caller: caller, data: [options]}) end end def post(args, options) begin - Settings.options[:timeline][:compact] = true if options[:compact] == true - writer = Post.new - if options[:poster] # Returns the same options hash + poster embed - settings = options.dup - options = NowWatching.new.get_poster(settings[:poster], settings) - end - text = args.join(" ") - writer.post_size_error(text) if writer.post_size_ok?(text) == false - @view.clear_screen - @status.posting - resp = writer.post({options: options, text: text}) - save_and_view(resp) + Settings.options.timeline.compact = true if options[:compact] + post_and_show(Post.new(@status), args.join(" "), options) rescue => e Errors.global_error({error: e, caller: caller, data: [args, options]}) end end def write(options) begin - Settings.options[:timeline][:compact] = true if options[:compact] == true - writer = Post.new + Settings.options.timeline.compact = true if options[:compact] + writer = Post.new(@status) @status.writing @status.post - lines_array = writer.compose - text = lines_array.join("\n") - writer.post_size_error(text) if writer.post_size_ok?(text) == false - @view.clear_screen - @status.posting - if options[:poster] - settings = options.dup - options = NowWatching.new.get_poster(settings[:poster], settings) - end - resp = writer.post({options: options, text: text}) - save_and_view(resp) + text = writer.compose.join("\n") + post_and_show(writer, text, options) rescue => e Errors.global_error({error: e, caller: caller, data: [text, options]}) end end def pmess(username, options = {}) - begin - Settings.options[:timeline][:compact] = true if options[:compact] == true - if options[:silent] - Settings.options[:marker][:messages] = false - end + begin + Settings.options.timeline.compact = true if options[:compact] + Settings.options.marker.messages = false if options[:silent] @check.no_username(username) username = [@workers.add_arobase(username)] - writer = Post.new + writer = Post.new(@status) @status.message_from(username) - @status.message - lines_array = writer.compose - text = lines_array.join("\n") - writer.message_size_error(text) if writer.message_size_ok?(text) == false - @view.clear_screen + @status.message + text = writer.compose.join("\n") + writer.message_size_error(text) if !writer.message_size_ok?(text) + @view.clear_screen @status.posting - if options[:poster] - settings = options.dup - options = NowWatching.new.get_poster(settings[:poster], settings) - end resp = writer.pm({options: options, text: text, username: username}) - if Settings.options[:marker][:messages] == true + post_object = PostObject.new(resp["data"]) + if Settings.options.marker.messages if resp['meta']['code'] == 200 - data = resp['data'] - name = "channel:#{data['channel_id']}" - Databases.pagination_insert(name, data['id']) - marked = @api.update_marker(name, data['id']) + name = "channel:#{post_object.channel_id}" + Databases.pagination_insert(name, post_object.id) + marked = @api.update_marker(name, post_object.id) updated = JSON.parse(marked) if updated['meta']['code'] != 200 - raise "couldn't update channel #{data['channel_id']} as read" + raise "couldn't update channel #{post_object.channel_id} as read" end end end - FileOps.save_message(resp) if Settings.options[:backup][:messages] - @view.clear_screen - @status.yourmessage(username[0]) - @view.show_posted(resp) - rescue => e + FileOps.save_message(resp) if Settings.options.backup.messages + @view.clear_screen + @status.yourmessage(username[0]) + @view.show_simple_post([post_object]) + rescue => e Errors.global_error({error: e, caller: caller, data: [username, options]}) - end + end end def reply(post_id, options = {}) begin - Settings.options[:timeline][:compact] = true if options[:compact] == true + Settings.options.timeline.compact = true if options[:compact] @check.bad_post_id(post_id) - if options[:force] - Settings.global[:force] = true - else - post_id = @workers.get_real_post_id(post_id) - end - @status.replying_to(post_id) - replied_to = @api.get_details(post_id) - @check.no_post(replied_to, post_id) + post_id = get_real_post_id_or_force(options, post_id) + @status.replying_to(post_id) + replied_to = @api.get_details(post_id) + @check.no_details(replied_to, post_id) + # API specifies to always reply to the original post of a reposted post. We offer the user an option to not. unless options[:noredirect] post_id = @workers.get_original_id(post_id, replied_to) end if replied_to['data']['repost_of'] if post_id == replied_to['data']['repost_of']['id'] replied_to = @api.get_details(post_id) - @check.no_post(replied_to, post_id) + @check.no_details(replied_to, post_id) end end # ---- - writer = Post.new + writer = Post.new(@status) @status.writing @status.reply - lines_array = writer.compose - text = lines_array.join("\n") - # text length is tested in Post class for the reply command + text = writer.compose.join("\n") + # Text length is tested in Post class for the reply command @view.clear_screen - replied_to = @workers.build_posts([replied_to['data']]) - if options[:poster] - settings = options.dup - options = NowWatching.new.get_poster(settings[:poster], settings) - end + replied_to = @workers.build_posts([PostObject.new(replied_to['data'])])[0] resp = writer.reply({options: options, text: text, id: post_id, reply_to: replied_to}) - FileOps.save_post(resp) if Settings.options[:backup][:posts] + FileOps.save_post(resp) if Settings.options.backup.posts # ---- + # "options" from CLI is immutable, we have to make a copy to add items options = options.dup unless resp['data']['reply_to'].nil? options[:reply_to] = resp['data']['reply_to'].to_i end options[:post_id] = resp['data']['id'].to_i - @view.render(@api.get_convo(post_id), options) - puts "\n" if Settings.options[:timeline][:compact] == true && !options[:raw] + stream = @api.get_convo(post_id) + stream_object = StreamObject.new(stream) + @view.render(stream_object, options) + puts "\n" if Settings.options.timeline.compact && !options[:raw] rescue => e Errors.global_error({error: e, caller: caller, data: [post_id, options]}) end end def send_to_channel(channel_id, options = {}) begin - Settings.options[:timeline][:compact] = true if options[:compact] == true - if options[:silent] - Settings.options[:marker][:messages] = false - end + Settings.options.timeline.compact = true if options[:compact] + Settings.options.marker.messages = false if options[:silent] channel_id = @workers.get_channel_id_from_alias(channel_id) - writer = Post.new + writer = Post.new(@status) @status.writing @status.message - lines_array = writer.compose - text = lines_array.join("\n") - writer.message_size_error(text) if writer.message_size_ok?(text) == false + text = writer.compose.join("\n") + writer.message_size_error(text) if !writer.message_size_ok?(text) @view.clear_screen @status.posting - if options[:poster] - settings = options.dup - options = NowWatching.new.get_poster(settings[:poster], settings) - end resp = writer.message({options: options, id: channel_id, text: text}) - if Settings.options[:marker][:messages] == true + post_object = PostObject.new(resp["data"]) + if Settings.options.marker.messages if resp['meta']['code'] == 200 - data = resp['data'] - name = "channel:#{data['channel_id']}" - Databases.pagination_insert(name, data['id']) - marked = @api.update_marker(name, data['id']) + name = "channel:#{post_object.channel_id}" + Databases.pagination_insert(name, post_object.id) + marked = @api.update_marker(name, post_object.id) updated = JSON.parse(marked) if updated['meta']['code'] != 200 - raise "couldn't update channel #{data['channel_id']} as read" + raise "couldn't update channel #{post_object.channel_id} as read" end end end - FileOps.save_message(resp) if Settings.options[:backup][:messages] + FileOps.save_message(resp) if Settings.options.backup.messages @view.clear_screen @status.yourpost - @view.show_posted(resp) + @view.show_simple_post([post_object]) rescue => e Errors.global_error({error: e, caller: caller, data: [channel_id, options]}) end end def nowplaying(options = {}) - Settings.options[:timeline][:compact] = true if options[:compact] == true - np = NowPlaying.new(@api, @view, @workers, options) + Settings.options.timeline.compact = true if options[:compact] + np = NowPlaying.new(@api, @view, @workers, @status, options) if options[:lastfm] np.lastfm(options) elsif options[:deezer] np.deezer(options) else np.itunes(options) end end - def nowwatching(args, options = {}) - begin - Settings.options[:timeline][:compact] = true if options[:compact] == true - if args.empty? - @status.error_missing_title - exit - end - nw = NowWatching.new(@view) - nw.post(args, options) - rescue ArgumentError => e - @status.no_movie - rescue => e - @status.wtf - Errors.global_error({error: e, caller: caller, data: [args, options]}) + private + + def save_and_view(resp) + FileOps.save_post(resp) if Settings.options.backup.posts + @view.clear_screen + @status.yourpost + puts "\n\n" + @view.show_posted(resp) + end + + def get_posts_ids_or_exit ids + int_ids = ids.select { |post_id| post_id.is_integer? } + if int_ids.empty? + yield + exit end + int_ids end - def tvshow(args, options = {}) - begin - Settings.options[:timeline][:compact] = true if options[:compact] == true - if args.empty? - @status.error_missing_title - exit - end - client = TvShow.new - show_obj = if options[:alt] - client.find_alt(args.join(' ')) - else - client.find(args.join(' ')) - end - candidate = client.create_details(show_obj) - candidate.ok ? candidate.post(options) : candidate.cancel - rescue => e - @status.wtf - Errors.global_error({error: e, caller: caller, data: [args, options]}) + def get_all_usernames_but_me usernames + @check.no_username(usernames) + @workers.all_but_me(usernames) + end + + def get_real_posts_ids_or_force options, posts_ids + if options[:force] + Settings.global.force = true + posts_ids + else + posts_ids.map { |post_id| @workers.get_real_post_id(post_id) } end end - def random_posts(options) - begin - Settings.options[:timeline][:compact] = true if options[:compact] == true - stream = Stream.new(@api, @view, @workers) - stream.random_posts(options) - rescue => e - Errors.global_error({error: e, caller: caller, data: [@max_id, @random_post_id, @resp, options]}) + def get_real_post_id_or_force options, post_id + if options[:force] + Settings.global.force = true + post_id + else + @workers.get_real_post_id(post_id) end end - private - - def save_and_view(resp) - FileOps.save_post(resp) if Settings.options[:backup][:posts] + def post_and_show writer, text, options + writer.post_size_error(text) if !writer.post_size_ok?(text) @view.clear_screen - @status.yourpost - puts "\n\n" - @view.show_posted(resp) + @status.posting + resp = writer.post({options: options, text: text}) + save_and_view(resp) end end end