Class: Tempest::REPL::Runner

Inherits:
Object
  • Object
show all
Defined in:
lib/tempest/repl/runner.rb

Constant Summary collapse

PROMPT =
"tempest> ".freeze
HELP_TEXT =
<<~HELP
  Available commands:
    :timeline       Fetch and print the home timeline
    :stream on|off  Toggle the Jetstream live feed
    :open $LX       Open the URL with id $LX in the browser
    :help           Show this help
    :quit           Exit tempest (or Ctrl-D)

    $XX <text>      Reply to the post with id $XX

  Any other input is sent as a new post.
HELP
DEFAULT_OPENER =
->(url) { system("open", url) }

Instance Method Summary collapse

Constructor Details

#initialize(session:, client:, input:, output:, dispatcher: Dispatcher.new, stream_manager: nil, handle_resolver: nil, stream_output: nil, timeline_store: nil, registry: Registry.new, opener: DEFAULT_OPENER, avatar_store: nil) ⇒ Runner

Returns a new instance of Runner.



31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/tempest/repl/runner.rb', line 31

def initialize(session:, client:, input:, output:, dispatcher: Dispatcher.new,
               stream_manager: nil, handle_resolver: nil, stream_output: nil,
               timeline_store: nil, registry: Registry.new, opener: DEFAULT_OPENER,
               avatar_store: nil)
  @session = session
  @client = client
  @input = input
  @output = output
  @stream_output = stream_output || output
  @dispatcher = dispatcher
  @stream_manager = stream_manager
  @handle_resolver = handle_resolver
  @timeline_store = timeline_store
  @registry = registry
  @opener = opener
  @avatar_store = avatar_store
  # URIs already printed via bootstrap_timeline or backfill_timeline.
  # Jetstream's cursor-replay can re-emit those same posts on startup
  # (the persisted cursor is older than the getTimeline window), so the
  # stream handler skips post events whose URI is in this set.
  @displayed_post_uris = Set.new
end

Instance Method Details

#auto_start_streamObject



76
77
78
79
80
81
# File 'lib/tempest/repl/runner.rb', line 76

def auto_start_stream
  return unless @stream_manager
  return if @stream_manager.running?

  @stream_manager.start { |event| handle_stream_event(event) }
end

#bootstrap_timelineObject



54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/tempest/repl/runner.rb', line 54

def bootstrap_timeline
  return unless @timeline_store

  cached = @timeline_store.load
  cached_posts = cached ? Array(cached[:posts]) : []
  cached_posts.each { |post| print_post(post) }

  cached_uris = cached_posts.map(&:uri).to_set
  begin
    fetched = Timeline.fetch(@client)
  rescue Tempest::Error => e
    @output.puts "-- timeline fetch failed: #{e.message}"
    return
  end

  new_posts = fetched.reject { |post| cached_uris.include?(post.uri) }
  new_posts.reverse_each { |post| print_post(post) }

  merged = cached_posts + new_posts.reverse
  @timeline_store.save(posts: merged)
end

#runObject



83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# File 'lib/tempest/repl/runner.rb', line 83

def run
  loop do
    line = read_line
    command = @dispatcher.dispatch(line)

    case command.name
    when :quit
      @stream_manager&.stop
      @output.puts "bye."
      break
    when :noop
      next
    when :help
      @output.puts HELP_TEXT
    when :timeline
      handle_timeline
    when :stream
      handle_stream(command.args.first)
    when :post
      handle_post(command.args.first)
    when :reply
      handle_reply(command.args[0], command.args[1])
    when :open
      handle_open(command.args.first)
    when :unknown
      @output.puts "unknown command: :#{command.args.first}"
    end
  end
end