mullvadrb 0.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 +3 -0
- data/Gemfile +7 -0
- data/README.md +19 -0
- data/bin/mullvadrb +3 -0
- data/lib/mullvadrb/account.rb +17 -0
- data/lib/mullvadrb/connection.rb +33 -0
- data/lib/mullvadrb/servers.rb +107 -0
- data/lib/mullvadrb.rb +61 -0
- data/mullvadrb.gemspec +14 -0
- metadata +52 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 3efb415f1b28c22ae2da6a06d3f2d7d695e84c2bab9e9894d3c3d560b2bca172
|
4
|
+
data.tar.gz: 86fdb6c682838b06643aa6af8db3397e72a7bbc015666e49f76784c1a48b4ac8
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 1621452ffdfe7a4b16d88796839752670752cb7dec214af858455cad4f38dcae77d1992a1e175eadbe9f19d86ccb4332322ed9780f0dcc2ed5b1ea43c99ddb53
|
7
|
+
data.tar.gz: 84a6e4b648fa849c3a0c3f2bc7e660cca96427d92954b9a0ba7a46798b4eca486a4478b761c23de94e115725c170ef37cbdb9100c663b6ae7658a318b2789679
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
# Ruby TUI for Mullvad VPN
|
2
|
+
|
3
|
+
This is a Terminal App I wrote for myself to use with Mullvad VPN on Linux. It adds a Ruby terminal interface to [Mullvad CLI](https://mullvad.net/en/help/how-use-mullvad-cli).
|
4
|
+
|
5
|
+
On first run, you need to log in (unless you've already run `mullvad account login` on your terminal before). The servers list will be updated and will be serialized to `~/.local/share/mullvadrb.dump`.
|
6
|
+
|
7
|
+
|
8
|
+
## Requirements
|
9
|
+
|
10
|
+
You need to have a [Mullvad VPN](https://mullvad.net) account and install [the CLI](https://mullvad.net/en/download/vpn/linux).
|
11
|
+
|
12
|
+
## Development
|
13
|
+
|
14
|
+
Run gem from the source:
|
15
|
+
|
16
|
+
```bash
|
17
|
+
$ irb -Ilib -rmullvadrb
|
18
|
+
```
|
19
|
+
|
data/bin/mullvadrb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
module Mullvadrb
|
2
|
+
module Account
|
3
|
+
class << self
|
4
|
+
def login(account)
|
5
|
+
puts `mullvad account login #{account}`
|
6
|
+
end
|
7
|
+
|
8
|
+
def info
|
9
|
+
puts `mullvad account get`
|
10
|
+
end
|
11
|
+
|
12
|
+
def devices
|
13
|
+
puts `mullvad account list-devices`
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Mullvadrb
|
2
|
+
#
|
3
|
+
# Manage Mullvad connect, disconnect and status
|
4
|
+
#
|
5
|
+
module Connection
|
6
|
+
class << self
|
7
|
+
def connect
|
8
|
+
puts `mullvad connect`
|
9
|
+
if $?.success?
|
10
|
+
puts 'โ Connecting...'
|
11
|
+
else
|
12
|
+
puts 'Error connecting'
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def disconnect
|
17
|
+
puts `mullvad disconnect`
|
18
|
+
if $?.success?
|
19
|
+
puts '๐ Pulling the plug'
|
20
|
+
else
|
21
|
+
puts 'Error disconnecting'
|
22
|
+
puts 'Maybe the connection wasn\'t active? ๐คจ'
|
23
|
+
end
|
24
|
+
sleep 2
|
25
|
+
status
|
26
|
+
end
|
27
|
+
|
28
|
+
def status
|
29
|
+
puts `mullvad status -v`
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,107 @@
|
|
1
|
+
module Mullvadrb
|
2
|
+
module Servers
|
3
|
+
SERVERS_FILE = File.expand_path('~/.local/share/mullvadrb.dump').freeze
|
4
|
+
|
5
|
+
def update
|
6
|
+
`mullvad relay update`
|
7
|
+
data = `mullvad relay list`
|
8
|
+
country, city, info, flag, value = nil
|
9
|
+
|
10
|
+
# Each line is either a country, a city or a server
|
11
|
+
servers = data.split("\n").compact.reject(&:empty?).map do |s|
|
12
|
+
if s.start_with?("\t\t")
|
13
|
+
info = s.gsub("\t\t", '')
|
14
|
+
{ country: country, city: city, info: info, flag: flag, value: info.split(' ').first }
|
15
|
+
elsif s.start_with?("\t")
|
16
|
+
city = s.gsub("\t", '').split("(").first.strip
|
17
|
+
next
|
18
|
+
else
|
19
|
+
regexp = /\(([a-z]{2})\)/ # Country (xx) - Country name + code and group code
|
20
|
+
flag = s.match(regexp)[1]
|
21
|
+
.upcase
|
22
|
+
.codepoints
|
23
|
+
.map { |c| (c + 127397).chr('utf-8') }.join
|
24
|
+
country = s.gsub(regexp, '').strip
|
25
|
+
next
|
26
|
+
end
|
27
|
+
end.compact
|
28
|
+
|
29
|
+
save_servers(servers)
|
30
|
+
puts '๐ Server list updated'
|
31
|
+
puts
|
32
|
+
end
|
33
|
+
|
34
|
+
def select_country
|
35
|
+
servers = @servers
|
36
|
+
country = TTY::Prompt.new.select('Select country', countries(servers), cycle: true, per_page: 10, filter: true, symbols: { marker: '๐ซ' })
|
37
|
+
connection = servers.select do |s|
|
38
|
+
s[:country] == country
|
39
|
+
end.sample
|
40
|
+
puts `mullvad relay set location #{connection[:value]}`
|
41
|
+
end
|
42
|
+
|
43
|
+
def random
|
44
|
+
server = all_connections.sample
|
45
|
+
puts "Connecting to #{server[:name]}"
|
46
|
+
puts `mullvad relay set location #{server[:value]}`
|
47
|
+
end
|
48
|
+
|
49
|
+
def select_specific
|
50
|
+
connections = all_connections
|
51
|
+
server = TTY::Prompt.new.select(
|
52
|
+
'Select server',
|
53
|
+
connections,
|
54
|
+
cycle: true,
|
55
|
+
per_page: 10,
|
56
|
+
filter: true,
|
57
|
+
symbols: { marker: '๐ซ' }
|
58
|
+
)
|
59
|
+
puts `mullvad relay set location #{server}`
|
60
|
+
end
|
61
|
+
|
62
|
+
def servers
|
63
|
+
@servers ||= load_servers
|
64
|
+
end
|
65
|
+
|
66
|
+
private
|
67
|
+
|
68
|
+
def countries(servers)
|
69
|
+
servers.uniq { |s| s[:country] }.map do |server|
|
70
|
+
{
|
71
|
+
name: "#{server[:flag]} #{server[:country]}",
|
72
|
+
value: server[:country]
|
73
|
+
}
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def all_connections
|
78
|
+
servers.map do |server|
|
79
|
+
{
|
80
|
+
name: "#{server[:flag]} #{server[:country]} - #{server[:city]}: #{server[:info]}",
|
81
|
+
value: server[:value]
|
82
|
+
}
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def emoji_from_code(code)
|
87
|
+
code.upcase
|
88
|
+
.codepoints
|
89
|
+
.map { |c| (c + 127397).chr('utf-8') }.join
|
90
|
+
end
|
91
|
+
|
92
|
+
def load_servers
|
93
|
+
servers = File.expand_path(SERVERS_FILE)
|
94
|
+
if File.file?(servers)
|
95
|
+
Marshal.load(File.read(servers))
|
96
|
+
else
|
97
|
+
update
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
def save_servers(servers)
|
102
|
+
File.open(SERVERS_FILE, 'w+') do |f|
|
103
|
+
f.write(Marshal.dump(servers))
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
data/lib/mullvadrb.rb
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'tty-prompt'
|
4
|
+
require 'mullvadrb/account'
|
5
|
+
require 'mullvadrb/connection'
|
6
|
+
require 'mullvadrb/servers'
|
7
|
+
|
8
|
+
include Mullvadrb::Servers
|
9
|
+
@servers = load_servers
|
10
|
+
|
11
|
+
def main_menu
|
12
|
+
TTY::Prompt.new.select('Select', cycle: true, per_page: 10) do |menu|
|
13
|
+
menu.choice name: '๐ก Status', value: 'status'
|
14
|
+
menu.choice name: '๐ฐ Random', value: 'random'
|
15
|
+
menu.choice name: "#{['๐', '๐', '๐'].sample} Choose country", value: 'country'
|
16
|
+
menu.choice name: '๐บ Choose specific', value: 'specific'
|
17
|
+
menu.choice name: '๐ Disconnect', value: 'disconnect'
|
18
|
+
menu.choice name: '๐ Update Servers', value: 'update_servers'
|
19
|
+
menu.choice name: '๐ Log in', value: 'account_login'
|
20
|
+
menu.choice name: '๐ Account info', value: 'account_info'
|
21
|
+
menu.choice name: '๐ฅ Devices', value: 'account_devices'
|
22
|
+
menu.choice name: 'โ Exit', value: 'exit'
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
puts Mullvadrb::Connection.status
|
27
|
+
|
28
|
+
loop do
|
29
|
+
selection = main_menu
|
30
|
+
puts "\e[H\e[2J"
|
31
|
+
case selection
|
32
|
+
when 'status'
|
33
|
+
puts Mullvadrb::Connection.status
|
34
|
+
when 'disconnect'
|
35
|
+
Mullvadrb::Connection.disconnect
|
36
|
+
when 'country'
|
37
|
+
select_country
|
38
|
+
Mullvadrb::Connection.connect
|
39
|
+
when 'specific'
|
40
|
+
Mullvadrb::Servers.select_specific
|
41
|
+
Mullvadrb::Connection.connect
|
42
|
+
when 'random'
|
43
|
+
random
|
44
|
+
Mullvadrb::Connection.connect
|
45
|
+
when 'update_servers'
|
46
|
+
update
|
47
|
+
when 'account_login'
|
48
|
+
Mullvadrb::Account.login(
|
49
|
+
TTY::Prompt.new.ask('Please enter your account number:')
|
50
|
+
)
|
51
|
+
when 'account_info'
|
52
|
+
Mullvadrb::Account.info
|
53
|
+
when 'account_devices'
|
54
|
+
Mullvadrb::Account.devices
|
55
|
+
when 'exit'
|
56
|
+
abort('Tioraidh!')
|
57
|
+
end
|
58
|
+
rescue SystemExit, Interrupt
|
59
|
+
puts
|
60
|
+
exit
|
61
|
+
end
|
data/mullvadrb.gemspec
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = 'mullvadrb'
|
3
|
+
s.version = '0.0.1'
|
4
|
+
s.summary = 'A TUI to use with Mullvad VPN'
|
5
|
+
s.description = 'A Terminal User Interface to use with Mullvad VPN'
|
6
|
+
s.authors = ['Fernando Briano']
|
7
|
+
s.email = 'fernando@picandocodigo.net'
|
8
|
+
s.files = `git ls-files`.split($/)
|
9
|
+
s.require_paths = ['lib']
|
10
|
+
s.homepage = 'https://github.com/picandocodigo/mullvad-ruby'
|
11
|
+
s.license = 'GPL-3.0-or-later'
|
12
|
+
s.required_ruby_version = '>= 3.0'
|
13
|
+
s.executables << 'mullvadrb'
|
14
|
+
end
|
metadata
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: mullvadrb
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Fernando Briano
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2024-10-22 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: A Terminal User Interface to use with Mullvad VPN
|
14
|
+
email: fernando@picandocodigo.net
|
15
|
+
executables:
|
16
|
+
- mullvadrb
|
17
|
+
extensions: []
|
18
|
+
extra_rdoc_files: []
|
19
|
+
files:
|
20
|
+
- ".gitignore"
|
21
|
+
- Gemfile
|
22
|
+
- README.md
|
23
|
+
- bin/mullvadrb
|
24
|
+
- lib/mullvadrb.rb
|
25
|
+
- lib/mullvadrb/account.rb
|
26
|
+
- lib/mullvadrb/connection.rb
|
27
|
+
- lib/mullvadrb/servers.rb
|
28
|
+
- mullvadrb.gemspec
|
29
|
+
homepage: https://github.com/picandocodigo/mullvad-ruby
|
30
|
+
licenses:
|
31
|
+
- GPL-3.0-or-later
|
32
|
+
metadata: {}
|
33
|
+
post_install_message:
|
34
|
+
rdoc_options: []
|
35
|
+
require_paths:
|
36
|
+
- lib
|
37
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - ">="
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '3.0'
|
42
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - ">="
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '0'
|
47
|
+
requirements: []
|
48
|
+
rubygems_version: 3.5.20
|
49
|
+
signing_key:
|
50
|
+
specification_version: 4
|
51
|
+
summary: A TUI to use with Mullvad VPN
|
52
|
+
test_files: []
|