myscripts/install-discord-linux.rb

337 lines
9.8 KiB
Ruby
Raw Normal View History

2024-10-19 02:04:58 +00:00
#!/usr/bin/env ruby
# BEGIN: Includes & Requires
require 'erb'
2024-10-19 03:48:44 +00:00
require 'time'
2024-10-19 02:04:58 +00:00
require 'json'
2024-10-19 03:48:44 +00:00
require 'zlib'
require 'find'
2024-10-19 16:20:47 +00:00
require 'English'
require 'net/http'
require 'optparse'
require 'fileutils'
require 'rubygems/package'
2024-10-19 02:04:58 +00:00
# END: Includes & Requires
# BEGIN: Overrides
class Dir
def / (path)
2024-10-19 16:20:47 +00:00
output_path = File.join(self.path + '/' + path)
2024-10-19 02:04:58 +00:00
if File.directory? output_path
Dir.new(output_path)
else
output_path
end
end
## For backwards compat
2024-10-25 01:53:32 +00:00
def chdir(dir = nil, &block)
if dir.nil?
Dir.chdir(self, &block)
else
Dir.chdir(dir, &block)
end
end
2024-10-19 02:04:58 +00:00
end
class String
def / (other)
2024-10-19 16:20:47 +00:00
File.join(self, other)
2024-10-19 02:04:58 +00:00
end
end
# END: Overrides
# BEGIN: Variables
URL_DOWNLOAD_BASE='https://dl.discordapp.net/apps/linux/{VERSION}/discord-{VERSION}.tar.gz'
DOWNLOAD_URL='https://discord.com/api/download/stable?platform=linux&format=tar.gz'
$CONFIG = Hash.new
$CONFIG[:icon_dir] = Dir.new(Dir.home) / '.local' / 'share' / 'icons'
File.mkdir($CONFIG[:icon_dir]) if not File.exist?($CONFIG[:icon_dir])
2024-10-19 03:48:44 +00:00
$CONFIG[:discord_config_path] = Dir.new(Dir.home) / '.config' / 'discord'
2024-10-19 02:04:58 +00:00
$CONFIG[:local_application_install_dir] = Dir.new(Dir.home) / '.local' / 'share' / 'applications'
File.mkdir($CONFIG[:local_application_install_dir]) if not File.exist?($CONFIG[:local_application_install_dir])
$CONFIG[:install_dir] = Dir.new(Dir.home) / '.opt'
2024-10-25 01:53:32 +00:00
$CONFIG[:desktop_path] = $CONFIG[:install_dir] / 'Discord' / 'discord.desktop'
2024-10-19 02:04:58 +00:00
File.mkdir($CONFIG[:install_dir]) if not File.exist?($CONFIG[:install_dir])
$CONFIG[:discord_path] = $CONFIG[:install_dir] / 'Discord'
$CONFIG[:desktop_file_path] = $CONFIG[:discord_path] / 'discord.desktop'
$CONFIG[:discord_version_file] = $CONFIG[:discord_path] / 'resources' / 'build_info.json'
$CONFIG[:action] = 'install'
$CONFIG[:keep_installer] = false
$CONFIG[:debug] = false
2024-10-19 02:04:58 +00:00
DISCORD_DESKTOP_CONTENTS=<<EOF
[Desktop Entry]
Name=Discord
StartupWMClass=discord
Comment=All-in-one voice and text chat for gamers that's free, secure, and works on both your desktop and phone.
GenericName=Internet Messenger
2024-10-25 01:53:32 +00:00
Exec=#{$CONFIG[:discord_dir]}/Discord
2024-10-19 02:04:58 +00:00
Icon=discord
Type=Application
Categories=Network;InstantMessaging;
2024-10-25 01:53:32 +00:00
Path=#{$CONFIG[:discord_path]}
2024-10-19 02:04:58 +00:00
EOF
# END: Variables
# BEGIN: Handle CLI ARgs
OptionParser.new do |parser|
parser.banner = "#{ File.basename($0) } [action]"
parser.separator ""
parser.separator " Actions"
parser.separator "------------------------------------------------------------------------"
parser.on('-c', '--check', "Check and report installed & remote versions") do
$CONFIG[:action] = 'check'
end
parser.on('-i', '--install', "Check for & Install new version of discord (default)") do
$CONFIG[:action] = 'install'
end
2024-10-19 03:48:44 +00:00
parser.on('-u', '--uninstall', "Uninstall Discord (not-implemented)") do
$CONFIG[:action] = 'uninstall'
2024-10-25 01:53:32 +00:00
$CONFIG[:backup_filename] = Dir.home / 'discord-backup-' + Time.now.strftime('%Y-%m-%d') + '.tar.gz'
2024-10-19 03:48:44 +00:00
end
parser.on('-b', '--backup [FILENAME]', "Backup Discord Installation") do |backup_filename|
2024-10-19 03:48:44 +00:00
$CONFIG[:action] = 'backup'
if backup_filename.nil?
2024-10-22 19:20:55 +00:00
$CONFIG[:backup_filename] = Dir.home / 'discord-backup-' + Time.now.strftime('%Y-%m-%d') + '.tar.gz'
else
$CONFIG[:backup_filename] = backup_filename + ".tar.gz"
end
2024-10-19 03:48:44 +00:00
end
2024-10-19 02:04:58 +00:00
parser.separator ""
parser.separator " General Flags"
parser.separator "------------------------------------------------------------------------"
parser.on('-h', '--help', "Show this help output") do
puts parser
exit
end
parser.on('-d', '--debug', "Turn on debug logging") do
$CONFIG[:debug] = true
end
2024-10-25 01:53:32 +00:00
parser.on('--keep', "Keep discord tar.gz file (default: #{$CONFIG[:keep_installer].to_s})") do
2024-10-19 02:04:58 +00:00
$CONFIG[:keep_installer] = true
end
end.parse!
# BEGIN: Handle CLI ARgs
2024-10-19 16:13:45 +00:00
# BEGIN: Helper Classes
2024-10-19 02:04:58 +00:00
2024-10-19 16:13:45 +00:00
class Installer
URL_DOWNLOAD_BASE='https://dl.discordapp.net/apps/linux/{VERSION}/discord-{VERSION}.tar.gz'
DOWNLOAD_URL='https://discord.com/api/download/stable?platform=linux&format=tar.gz'
2024-10-19 02:04:58 +00:00
2024-10-19 16:13:45 +00:00
def needs_update?
local_version < remote_version
2024-10-19 02:04:58 +00:00
end
2024-10-19 16:13:45 +00:00
def remote_version
if @remote_version.nil?
uri = URI(DOWNLOAD_URL)
response = Net::HTTP.get(uri)
if response =~ /discord-(?<version>\d+\.\d+\.\d+).tar.gz/
@remote_version = Gem::Version.new($LAST_MATCH_INFO['version'])
else
raise "Failed to retrieve remote version"
end
end
@remote_version
2024-10-19 02:04:58 +00:00
end
2024-10-19 03:48:44 +00:00
2024-10-19 16:13:45 +00:00
def local_version
if @local_version.nil?
@local_version = if File.exist? $CONFIG[:discord_version_file]
data = JSON.load_file($CONFIG[:discord_version_file])
Gem::Version.new(data['version'])
else
Gem::Version.new('0.0.0')
end
2024-10-19 02:04:58 +00:00
end
2024-10-19 16:13:45 +00:00
@local_version
2024-10-19 02:04:58 +00:00
end
2024-10-19 16:13:45 +00:00
def download
version = self.remote_version.to_s
uri = URI(URL_DOWNLOAD_BASE.gsub('{VERSION}',version))
puts "download_installer: Downloading The discord #{version} tar.gz"
file_contents = Net::HTTP.get(uri)
output_file = "discord-#{version}.tar.gz"
puts "download_installer: Output file will #{output_file}"
$CONFIG[:install_dir].chdir do
2024-10-19 16:13:45 +00:00
File.open(output_file, 'wb') do |file|
file.write(file_contents)
end
2024-10-19 02:04:58 +00:00
end
2024-10-19 16:13:45 +00:00
puts "download_installer: tar.gz was downloaded"
end
def install
installer_file = "discord-#{self.remote_version}.tar.gz"
puts "do_install: Extracting new installer"
$CONFIG[:install_dir].chdir do
2024-10-19 16:13:45 +00:00
File.open(installer_file, 'rb') do |file|
Gem::Package.new("").extract_tar_gz(file, $CONFIG[:install_dir])
end
2024-10-19 02:04:58 +00:00
2024-10-19 16:13:45 +00:00
if not $CONFIG[:keep_installer]
puts "do_install: Removing new installer (#{installer_file})"
File.unlink(installer_file)
end
end
2024-10-25 01:53:32 +00:00
update_desktop_file
2024-10-19 02:04:58 +00:00
end
end
2024-10-25 01:53:32 +00:00
2024-10-19 16:13:45 +00:00
# END: Helper Classes
# BEGIN: Helper Functions
2024-10-19 02:04:58 +00:00
def update_desktop_file
file_needs_updating = true
puts "update_desktop_file: Checking if desktop entry needs updating"
if File.exist?($CONFIG[:desktop_path])
puts "update_desktop_file: Desktop file exists, checking if it matches template"
File.open($CONFIG[:desktop_path], 'r') do |file|
if file.read() == DISCORD_DESKTOP_CONTENTS
puts "update_desktop_file: Desktop file matches template. Not updating"
file_needs_updating = false
end
end
end
if file_needs_updating
File.open($CONFIG[:desktop_path], 'w') do |file|
puts "update_desktop_file: Desktop File was written"
file.write(DISCORD_DESKTOP_CONTENTS)
end
puts "update_desktop_file: Triggering desktop to install new desktop entry and refresh entries"
%x[ desktop-file-install --dir=#{$CONFIG[:local_application_install_dir].path} #{$CONFIG[:desktop_path]} ]
end
end
2024-10-19 03:48:44 +00:00
def make_backup
files = {
files: Array.new,
dirs: Array.new,
symlinks: Array.new
}
[ $CONFIG[:discord_config_path].path, $CONFIG[:discord_path].path ].each do |backup_dir|
puts "make_backup: Getting Files from #{backup_dir})"
Find.find("#{backup_dir}").each{ |item|
puts("#{item} was retrieved from #{backup_dir}") if $CONFIG[:debug]
if File.file?(item)
puts("#{item} was found to be a file") if $CONFIG[:debug]
files[:files] << item
elsif File.symlink?(item)
puts("#{item} was found to be a symlink") if $CONFIG[:debug]
files[:symlinks] << item
elsif File.directory?(item)
puts("#{item} was found to be a directory") if $CONFIG[:debug]
files[:dirs] << item
end
}
end
2024-10-19 03:48:44 +00:00
Dir.chdir(Dir.home) do
2024-10-22 19:20:55 +00:00
puts "make_backup: Beginning backup process (OUTPUT_FILE = #{$CONFIG[:backup_filename]})"
File.open($CONFIG[:backup_filename], "wb") do |backup_file|
Zlib::GzipWriter.wrap(backup_file) do |gzip|
2024-10-19 03:48:44 +00:00
Gem::Package::TarWriter.new(gzip) do |tar|
puts "\nmake_backup : files : Beginning backup process for files (Count: #{files[:files].count})"
file_count = files[:files].count
files[:files].each_with_index { |file, i|
puts "make_backup : files : Backing up #{file} (#{i+1}/#{file_count})" if $CONFIG[:debug]
File.open(file, 'rb') { |file_to_archive|
contents = file_to_archive.read()
tar.add_file_simple(file_to_archive.path.sub("#{Dir.home}/",''), file_to_archive.stat.mode, contents.length) { |io|
io.write(contents)
}
}
}
puts "\nmake_backup : directories : Beginning backup process for directories (Count: #{files[:dirs].count})"
dir_count = files[:dirs].count
files[:dirs].each_with_index {|dir,i|
puts "make_backup : directories : Backing up #{dir} (#{i+1}/#{dir_count})" if $CONFIG[:debug]
tar.mkdir(dir.sub("#{Dir.home}/",""), File.stat(dir).mode)
}
puts "\nmake_backup : symlinks : Beginning backup process for symlinks (Count: #{files[:symlinks].count})"
symlink_count = files[:symlinks].count
files[:symlinks].each_with_index {|symlink,i|
puts "make_backup : symlinks : Backing up #{symlink} (#{i+1}/#{symlink_count})" if $CONFIG[:debug]
tar.add_symlink(symlink.sub("#{Dir.home}/",""), File.readlink(symlink), File.lstat(symlink).mode)
}
2024-10-19 03:48:44 +00:00
end
end
end
end
end
2024-10-19 02:04:58 +00:00
# END: Helper Functions
# BEGIN: Work
2024-10-19 16:20:47 +00:00
installer = Installer.new
2024-10-19 02:04:58 +00:00
case $CONFIG[:action]
2024-10-19 16:13:45 +00:00
2024-10-19 02:04:58 +00:00
when 'install'
2024-10-19 16:13:45 +00:00
if installer.needs_update?
2024-10-19 02:04:58 +00:00
puts "main: Installed Version will be updated"
2024-10-19 16:13:45 +00:00
installer.download
installer.install
elsif installer.local_version == installer.remote_version
2024-10-19 02:04:58 +00:00
puts "main: Installed Version is up-to-date"
else
puts "main: What?"
end
2024-10-19 16:13:45 +00:00
2024-10-19 02:04:58 +00:00
when 'check'
puts
puts " Report"
puts "-------------------------------------"
2024-10-19 16:20:47 +00:00
puts " Remote Version: #{installer.remote_version.to_s}"
puts " Local Version: #{installer.local_version.to_s}"
puts " Needs Updating: #{installer.needs_update? ? "Yes" : "No"}"
2024-10-19 16:13:45 +00:00
2024-10-19 03:48:44 +00:00
when 'backup'
make_backup
2024-10-19 16:13:45 +00:00
2024-10-19 02:04:58 +00:00
end
# END: Work