Skip to content

Instantly share code, notes, and snippets.

@Papierkorb
Created January 14, 2017 00:04
Show Gist options
  • Save Papierkorb/574f70be36e69bbca7350f8745fd4289 to your computer and use it in GitHub Desktop.
Save Papierkorb/574f70be36e69bbca7350f8745fd4289 to your computer and use it in GitHub Desktop.
Set KDE/XDG file associations in bulk
#!/usr/bin/env ruby
# A script to bulk change file associations. Intended for KDE, but might work
# with other XDG conforming software. Run it without arguments to see how to
# use it. Created by me out of frustration, so the code just works ;)
require "inifile" # gem install inifile
ASSOC_FILE = "#{ENV['HOME']}/.config/mimeapps.list"
ASSOC_FILE_BAK = "#{ASSOC_FILE}.bak"
MIME_TYPES = File.readlines("/etc/mime.types").map{|line| line.split(/\s/).first}.reject(&:empty?)
APPLICATION_DIRS = %W[/usr/share/applications #{ENV['HOME']}.local/share/applications]
mime_type = ARGV[0]
program = ARGV[1]
if !mime_type || !program
puts "#$0 - Bulk change file associations in KDE (and possibly others)"
puts "Usage: #$0 <MIME-Type> <Program>"
puts " <Program>: The program to use (.desktop file)"
puts " <MIME-Type>: The MIME-Type to change. Examples:"
puts " video/mp4 Exactly video/mp4"
puts " video/ Match everything in the video group"
puts " /pdf Match pdf in every group"
puts
puts "Changes to #{ASSOC_FILE} are stored at #{ASSOC_FILE_BAK}"
puts "Directory files are stored in: #{APPLICATION_DIRS.join(', ')}"
exit 0
end
program += ".desktop" unless program.end_with?('.desktop')
known = APPLICATION_DIRS.find{|path| File.exist? "#{path}/#{program}"}
if known.nil?
puts "Can't find file #{program.inspect} in any of the following directories:"
APPLICATION_DIRS.each{|path| puts " #{path}"}
exit 1
end
change = [ mime_type ]
if mime_type.end_with? '/'
change = MIME_TYPES.select{|type| type.start_with? mime_type}
elsif mime_type.start_with? '/'
change = MIME_TYPES.select{|type| type.end_with? mime_type}
end
#
change.each{|mime| puts "Changing #{mime} -> #{program}"}
mapping = change.map{|mime| [ mime.downcase, program ]}.to_h
ini = IniFile.load(ASSOC_FILE)
ini['Default Applications'].merge! mapping
#
puts "Writing backup to #{ASSOC_FILE_BAK}"
File.write ASSOC_FILE_BAK, File.read(ASSOC_FILE)
puts "Writing #{ASSOC_FILE}"
ini.write
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment