mchat 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,34 @@
1
+ module Mchat
2
+ module Command
3
+ # Command Clear
4
+ module Clear
5
+ def self.configure(repl)
6
+ CommandConditions.push({
7
+ name: 'clear',
8
+ description: "c[lear]\t\tclean mchat screen",
9
+ help_condition: ['clear','c'],
10
+ help_doc: :clear_help_doc,
11
+ command_condition: ['/clear', '/c'],
12
+ command_run: :clear_command_run
13
+ })
14
+ end
15
+ module InstanceMethods
16
+ def clear_help_doc
17
+ _puts %Q(
18
+ #{"Help: Clear".style.bold}
19
+
20
+ command: /clear
21
+ explain: clear chat screen.
22
+
23
+ )
24
+ end
25
+
26
+ def clear_command_run(repl = nil)
27
+ timeline_clear
28
+ end
29
+ end
30
+ end
31
+
32
+ mount_command :clear, Clear
33
+ end
34
+ end
@@ -0,0 +1,39 @@
1
+ module Mchat
2
+ module Command
3
+ module Default
4
+ CommandConditions.push({
5
+ name: 'default',
6
+ description: "default\t\tdefault model, send message",
7
+ help_condition: ['default'],
8
+ help_doc: :default_help_doc,
9
+ command_condition: [/([^\s].*)/],
10
+ command_run: :default_command_run
11
+ })
12
+ module InstanceMethods
13
+ def default_help_doc
14
+ _puts %Q(
15
+ #{"Help: Default Mode".style.bold}
16
+
17
+ if you have joined `channel`
18
+ and you have a `name` in channel
19
+
20
+ you can send message without /m command, that's default mode.
21
+
22
+ )
23
+ end
24
+
25
+ def default_command_run(words)
26
+ if _current_channel && _current_nickname && words
27
+ return message_command_run(words)
28
+ else
29
+ _puts "Oops.. This is `Default Mode`:".style.warn
30
+ _puts "if you join channel and have name, it will send message.".style.warn
31
+ _puts "Do nothing. maybe you need join channel or use commands. try /h for more.".style.warn
32
+ end
33
+ end
34
+ end
35
+ end
36
+ mount_command :default, Default
37
+ end
38
+ end
39
+
@@ -0,0 +1,33 @@
1
+ module Mchat
2
+ module Command
3
+ module Guide
4
+ CommandConditions.push({
5
+ name: 'guide',
6
+ description: "guide\t\tguide & HOWTO",
7
+ help_condition: ['guide'],
8
+ help_doc: :guide_help_doc,
9
+ command_condition: ['/guide'],
10
+ command_run: :guide_command_run
11
+ })
12
+
13
+ module InstanceMethods
14
+ def guide_help_doc
15
+ _puts %Q(
16
+ #{"Help: Guide".style.bold}
17
+
18
+ Mchat is a tiny chat software.
19
+ Howto:
20
+ .....
21
+
22
+ )
23
+ end
24
+
25
+ def guide_command_run
26
+ _puts "TODO run command guide"
27
+ end
28
+ end
29
+ end
30
+ mount_command :guide, Guide
31
+ end
32
+ end
33
+
@@ -0,0 +1,55 @@
1
+ module Mchat
2
+ module Command
3
+ module Help
4
+ def self.configure(repl)
5
+ CommandConditions.push({
6
+ name: 'help',
7
+ description: "h[elp]\t\tfind help",
8
+ help_condition: ['help','h'],
9
+ help_doc: :help_help_doc,
10
+ command_condition: ['/help', /\/help (.*)/, '/h', /\/h (.*)/],
11
+ command_run: :help_command_run
12
+ })
13
+ end
14
+ module InstanceMethods
15
+ def help_help_doc
16
+ cmd_list = ""
17
+ CommandConditions.each do |c|
18
+ cmd_list << "#{c[:description]}\n"
19
+ end
20
+
21
+ _puts %Q(
22
+ #{"Help: Index".style.bold}
23
+
24
+ Choose subject to help:
25
+
26
+ #{cmd_list}
27
+
28
+ e.g:
29
+ type `/h guide` you will find guide guide.
30
+ )
31
+ end
32
+
33
+ def help_command_run(subject = nil)
34
+ if !subject
35
+ return help_help_doc
36
+ end
37
+ subject = subject && subject.strip
38
+ catch :halt do
39
+ CommandConditions.each do |command|
40
+ help_condition = command[:help_condition]
41
+ help_condition.each do |hc|
42
+ if hc.match(subject)
43
+ catch_subject = $1 ? $1 : nil
44
+ _dispatch(command[:help_doc], catch_subject)
45
+ throw :halt
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
53
+ mount_command :help, Help
54
+ end
55
+ end
@@ -0,0 +1,47 @@
1
+ module Mchat
2
+ module Command
3
+ # Command Join
4
+ module Join
5
+ CommandConditions.push({
6
+ name: 'join',
7
+ description: "j[oin]\t\tjoin the channel",
8
+ help_condition: ['join','j'],
9
+ help_doc: :join_help_doc,
10
+ command_condition: ['/join', /\/join (.*)/, '/j', /\/j (.*)/],
11
+ command_run: :join_command_run
12
+ })
13
+
14
+ module InstanceMethods
15
+ def join_help_doc
16
+ _puts %Q(
17
+ #{"Help: Join".style.bold}
18
+
19
+ command: /join <channel_name>
20
+ explain: join the channel
21
+
22
+ )
23
+ end
24
+
25
+ def join_command_run(channel_name = nil)
26
+ if !channel_name
27
+ _puts "channel_name missing !\n type`/join <channel_name>`".style.warn
28
+ else
29
+ # TODO channel password
30
+ # TODO channel 白名单
31
+ resp = _api.get_channels
32
+ all_channels = resp.fetch("data")
33
+
34
+ if all_channels.any? channel_name
35
+ _mchat_action("join channel: #{channel_name}")
36
+ _set_current_channel channel_name
37
+ fetch_channel_task
38
+ else
39
+ _puts "Channel: #{channel_name} not found!".style.warn
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
45
+ mount_command :join, Join
46
+ end
47
+ end
@@ -0,0 +1,43 @@
1
+ module Mchat
2
+ module Command
3
+ # Command Join
4
+ module Leave
5
+ def self.configure(repl)
6
+ CommandConditions.push({
7
+ name: 'leave',
8
+ description: "l[eave]]\tleave channel",
9
+ help_condition: ['leave','l'],
10
+ help_doc: :leave_help_doc,
11
+ command_condition: ['/leave', /\/leave (.*)/, '/l', /\/l (.*)/],
12
+ command_run: :leave_command_run
13
+ })
14
+ end
15
+ module InstanceMethods
16
+ def leave_help_doc
17
+ _puts %Q(
18
+ #{"Help: Leave".style.bold}
19
+
20
+ command: /leave
21
+ explain: leave channel and delete your name.
22
+ )
23
+ end
24
+
25
+ def leave_command_run
26
+ if _current_nickname
27
+ resp = _api.leave_channel( _current_channel , _current_nickname)
28
+ code = resp.fetch("code")
29
+ if code == StatusCode::Success
30
+ _puts "#{_current_nickname} leave success.".style.primary
31
+ _set_current_nickname nil
32
+ else
33
+ _puts "leave request connect fail. try again.".style.warn
34
+ end
35
+ else
36
+ _puts "You use leave".style.warn
37
+ end
38
+ end
39
+ end
40
+ end
41
+ mount_command :leave, Leave
42
+ end
43
+ end
@@ -0,0 +1,53 @@
1
+ module Mchat
2
+ module Command
3
+ # Command Message
4
+ module Message
5
+ def self.configure(repl)
6
+ CommandConditions.push({
7
+ name: 'message',
8
+ description: "m[essage]\tsend message in channel",
9
+ help_condition: ['message','m'],
10
+ help_doc: :message_help_doc,
11
+ command_condition: ['/message', /\/message (.*)/, '/m', /\/m (.*)/],
12
+ command_run: :message_command_run
13
+ })
14
+ end
15
+ module InstanceMethods
16
+ def message_help_doc
17
+ _puts %Q(
18
+ #{"Help: Message".style.bold}
19
+
20
+ command: /message <message>
21
+ explain: send your message
22
+
23
+ )
24
+ end
25
+
26
+ def message_command_run(words)
27
+ if !_current_channel
28
+ _puts "You are not in channel, so you cannot message.".style.warn
29
+ _puts "type `/n[ame] <your name>` before chat".style.warn
30
+ elsif !_current_nickname
31
+ _puts "You must register a name to this channel".style.warn
32
+ _puts "type `/n[ame] <your name>` before chat".style.warn
33
+ elsif _current_channel && _current_nickname
34
+ resp = _api.create_channel_message(_current_channel, _current_nickname, words)
35
+ code = resp.fetch("code")
36
+
37
+ if code != StatusCode::Success
38
+ _puts warn "Send Message Fail:"
39
+ _puts "quote----"
40
+ _puts "#{words}"
41
+ _puts "---------"
42
+ else
43
+ _puts "send success"
44
+ end
45
+ end
46
+ # TODO send to server
47
+ # _puts2("#{Message.new(words).display}")
48
+ end
49
+ end
50
+ end
51
+ mount_command :message, Message
52
+ end
53
+ end
@@ -0,0 +1,47 @@
1
+ module Mchat
2
+ module Command
3
+ # Command Join
4
+ module Name
5
+ def self.configure(repl)
6
+ CommandConditions.push({
7
+ name: 'name',
8
+ description: "n[ame]\t\tset name in channel",
9
+ help_condition: ['name','n'],
10
+ help_doc: :name_help_doc,
11
+ command_condition: ['/name', /\/name (.*)/, '/n', /\/n (.*)/],
12
+ command_run: :name_command_run
13
+ })
14
+ end
15
+ module InstanceMethods
16
+ def name_help_doc
17
+ _puts %Q(
18
+ #{"Help: Name".style.bold}
19
+
20
+ command: /name <your name in channel>
21
+ explain: give your name in channel for chatting.
22
+
23
+ )
24
+ end
25
+
26
+ def name_command_run(user_name = nil)
27
+ if _current_nickname
28
+ _puts "You have `name` and active in this channel now.".style.warn
29
+ _puts "Please leave this channel then change your name.".style.warn
30
+ else
31
+ resp = _api.join_channel( _current_channel , user_name)
32
+ code = resp.fetch("code")
33
+ if code == StatusCode::Success
34
+ _puts "#{user_name} is avalibale.".style.primary
35
+ _set_current_nickname user_name
36
+ channel_heartbeat_task
37
+ else
38
+ _set_current_nickname nil
39
+ _puts "#{user_name} has been used in channel: #{_current_channel}\ntry rename.".style.warn
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
45
+ mount_command :name, Name
46
+ end
47
+ end
@@ -0,0 +1,38 @@
1
+ module Mchat
2
+ module Command
3
+ module Quit
4
+ def self.configure(repl)
5
+ CommandConditions.push({
6
+ name: 'quit',
7
+ description: "q[uit]\t\tquit mchat",
8
+ help_condition: ['quit','q'],
9
+ help_doc: :quit_help_doc,
10
+ command_condition: ['/quit', '/q'],
11
+ command_run: :quit_command_run
12
+ })
13
+ end
14
+
15
+ module InstanceMethods
16
+ def quit_help_doc
17
+ _puts QuitDoc
18
+ end
19
+
20
+ def quit_command_run(words=nil)
21
+ _dispatch :leave_command_run
22
+ _puts "Bye :D"
23
+ sleep 1
24
+ timeline_close_window
25
+ exit 0
26
+ end
27
+ end
28
+ QuitDoc = %Q(
29
+ #{"Help: Quit".style.bold}
30
+
31
+ command: /q
32
+ explain: quit the mchat.
33
+
34
+ )
35
+ end
36
+ mount_command :quit, Quit
37
+ end
38
+ end
@@ -0,0 +1,38 @@
1
+ require "rainbow"
2
+
3
+ module Mchat
4
+ class StyleFont
5
+ def initialize(text)
6
+ @text = Rainbow(text)
7
+ end
8
+
9
+ def primary
10
+ @text.bold.cyan
11
+ end
12
+
13
+ def jade
14
+ @text.bold.green
15
+ end
16
+
17
+ def sea
18
+ @text.bold.blue
19
+ end
20
+
21
+ def warn
22
+ @text.bold.yellow
23
+ end
24
+
25
+ def danger
26
+ @text.bold.red
27
+ end
28
+
29
+ def bold
30
+ @text.bold
31
+ end
32
+ end
33
+ module Style
34
+ def style
35
+ ::Mchat::StyleFont.new(self)
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,18 @@
1
+ module Mchat
2
+ class Message
3
+ def initialize(message, format = :std)
4
+ @message = message
5
+ @format = format
6
+ end
7
+
8
+ def display
9
+ if @format == :std
10
+ # Time format https://devdocs.io/ruby~3/datetime#method-i-strftime
11
+ tstring = Time.at(@message['timestamp'].to_i).strftime("%H:%M:%S")
12
+ username = @message['user_name']
13
+ content = @message['content']
14
+ "[#{tstring.style.sea}] #{username.style.jade}: #{content.strip}\n"
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,17 @@
1
+ require_relative '../timeline'
2
+
3
+ module Mchat
4
+ module TimelineApi
5
+ def timeline_clear
6
+ _chat_screen_print(TimelineCommand.new(:clear))
7
+ end
8
+
9
+ def timeline_bossmode
10
+ _chat_screen_print(TimelineCommand.new(:bossmode))
11
+ end
12
+
13
+ def timeline_close_window
14
+ _chat_screen_print(TimelineCommand.new(:close_window))
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,55 @@
1
+ require 'pathname'
2
+
3
+ module Mchat
4
+ module UserConfig
5
+ CONFIG_DIR = Pathname.new(Dir.home).join('.mchat')
6
+ CONFIG_PATH = Pathname.new(Dir.home).join('.mchat').join('mchatrc')
7
+ def user_config_exist?
8
+ File.exist? CONFIG_PATH
9
+ end
10
+ def create_user_config
11
+ require 'fileutils'
12
+ FileUtils.mkdir_p(CONFIG_DIR) unless File.exist?(CONFIG_DIR)
13
+ File.open(CONFIG_PATH, 'w') do |f|
14
+ init_config = %Q(
15
+ # Mchat user config
16
+ # use yaml syntax
17
+
18
+ wait_prefix: ">>"
19
+ display_welcome: true
20
+ clear_repl_everytime: true
21
+ server: "localhost:4567"
22
+
23
+ )
24
+ f << init_config
25
+ end
26
+ end
27
+
28
+ def read_user_config
29
+ if !user_config_exist?
30
+ create_user_config
31
+ end
32
+
33
+ require 'yaml'
34
+ opt = YAML.load(File.open(CONFIG_PATH))
35
+ return opt
36
+ end
37
+
38
+ def first_time_use
39
+ if !user_config_exist?
40
+ read_user_config
41
+ puts "Mchat first run TIPS".style.jade
42
+ puts ""
43
+ puts "Mchat not found user config, maybe this is your first time run Mchat."
44
+ init_config = "~/.mchat".style.warn
45
+ puts "Mchat has help your create config to #{init_config}"
46
+ server_field = "<server> field".style.warn
47
+ puts "Before you run mchat, edit your config file, change #{server_field} to yours:"
48
+ puts "vim #{CONFIG_PATH.to_s}".style.warn
49
+ puts "make sure your server works, before run Mchat. :D"
50
+
51
+ exit 0
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,23 @@
1
+ module Mchat
2
+ module Welcome
3
+ def welcome(switch)
4
+ if switch
5
+ display_ascii_art
6
+ end
7
+ end
8
+
9
+ def display_ascii_art
10
+ # https://rubygems.org/gems/artii
11
+ content = <<-'EOF'
12
+ __ __ _ _
13
+ | \/ | | | | |
14
+ | \ / | ___| |__ __ _| |_
15
+ | |\/| |/ __| '_ \ / _` | __|
16
+ | | | | (__| | | | (_| | |_
17
+ |_| |_|\___|_| |_|\__,_|\__|
18
+
19
+ EOF
20
+ content.style.jade
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,29 @@
1
+ npm WARN ERESOLVE overriding peer dependency
2
+ npm WARN While resolving: @babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.16.7
3
+ npm WARN Found: @babel/core@7.12.3
4
+ npm WARN node_modules/@babel/core
5
+ npm WARN @babel/core@"7.12.3" from the root project
6
+ npm WARN 102 more (@babel/helper-compilation-targets, ...)
7
+ npm WARN
8
+ npm WARN Could not resolve dependency:
9
+ npm WARN peer @babel/core@"^7.13.0" from @babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.16.7
10
+ npm WARN node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining
11
+ npm WARN @babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@"^7.16.7" from @babel/preset-env@7.16.11
12
+ npm WARN node_modules/@babel/preset-env
13
+ npm WARN
14
+ npm WARN Conflicting peer dependency: @babel/core@7.18.10
15
+ npm WARN node_modules/@babel/core
16
+ npm WARN peer @babel/core@"^7.13.0" from @babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.16.7
17
+ npm WARN node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining
18
+ npm WARN @babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@"^7.16.7" from @babel/preset-env@7.16.11
19
+ npm WARN node_modules/@babel/preset-env
20
+ npm WARN deprecated source-map-resolve@0.6.0: See https://github.com/lydell/source-map-resolve#deprecated
21
+ npm WARN deprecated source-map-resolve@0.5.3: See https://github.com/lydell/source-map-resolve#deprecated
22
+ npm WARN deprecated source-map-resolve@0.5.3: See https://github.com/lydell/source-map-resolve#deprecated
23
+ npm WARN deprecated fsevents@1.2.13: fsevents 1 will break on node v14+ and could be using insecure binaries. Upgrade to fsevents 2.
24
+ npm WARN deprecated fsevents@1.2.13: fsevents 1 will break on node v14+ and could be using insecure binaries. Upgrade to fsevents 2.
25
+ npm WARN deprecated chokidar@2.1.8: Chokidar 2 does not receive security updates since 2019. Upgrade to chokidar 3 with 15x fewer dependencies
26
+ npm WARN deprecated chokidar@2.1.8: Chokidar 2 does not receive security updates since 2019. Upgrade to chokidar 3 with 15x fewer dependencies
27
+ npm WARN deprecated rollup-plugin-babel@4.4.0: This package has been deprecated and is no longer maintained. Please use @rollup/plugin-babel.
28
+ npm WARN deprecated querystring@0.2.1: The querystring API is considered Legacy. new code should use the URLSearchParams API instead.
29
+ npm WARN deprecated querystring@0.2.0: The querystring API is considered Legacy. new code should use the URLSearchParams API instead.
@@ -0,0 +1,21 @@
1
+ class Logger
2
+ def initialize(switch)
3
+ @switch = switch
4
+ if @switch == :on
5
+ @output = File.absolute_path("#{__dir__}/../../log")
6
+ @f = File.open("#{@output}/#{Time.now.to_s}.log","w+")
7
+ end
8
+ end
9
+
10
+ def log(component, info)
11
+ @f << "[#{component}]: #{Time.now.to_s}: #{info}\n" if @switch == :on
12
+ end
13
+
14
+ def close
15
+ @f.close if @switch == :on
16
+ end
17
+ end
18
+
19
+ LoggerMan = Logger.new(:off)
20
+
21
+ at_exit { LoggerMan.close }