fluxbox_apps_menu 1.1.0
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.
- data/Gemfile +4 -0
- data/Gemfile.lock +21 -0
- data/LICENSE +674 -0
- data/README.md +57 -0
- data/Rakefile +2 -0
- data/bin/fluxbox_apps_menu +6 -0
- data/fluxbox_apps_menu.gemspec +26 -0
- data/lib/fluxbox_apps_menu.rb +85 -0
- data/lib/fluxbox_apps_menu.yaml +123 -0
- data/lib/fluxbox_apps_menu/cli.rb +50 -0
- data/lib/fluxbox_apps_menu/config.rb +50 -0
- data/lib/fluxbox_apps_menu/desktop_file.rb +69 -0
- data/lib/fluxbox_apps_menu/menu.rb +100 -0
- data/lib/fluxbox_apps_menu/utils.rb +21 -0
- data/lib/fluxbox_apps_menu/version.rb +3 -0
- metadata +127 -0
data/README.md
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
# FluxboxAppsMenu
|
2
|
+
|
3
|
+
FluxboxAppsMenu create an applications menu file for Fluxbox Window Manager
|
4
|
+
including the applications stored within the folders containing the
|
5
|
+
_.desktop_ files and discarding automatically those marked as hidden.
|
6
|
+
|
7
|
+
They will be organized in several categories and sub-categories specified
|
8
|
+
within the config file *fluxbox_apps_menu.yaml*
|
9
|
+
|
10
|
+
|
11
|
+
## Installation
|
12
|
+
|
13
|
+
Add this line to your application's Gemfile:
|
14
|
+
|
15
|
+
gem 'fluxbox_apps_menu'
|
16
|
+
|
17
|
+
And then execute:
|
18
|
+
|
19
|
+
$ bundle
|
20
|
+
|
21
|
+
Or install it yourself as:
|
22
|
+
|
23
|
+
$ gem install fluxbox_apps_menu
|
24
|
+
|
25
|
+
## Usage
|
26
|
+
|
27
|
+
Build the menu
|
28
|
+
|
29
|
+
$ fluxbox_apps_menu build
|
30
|
+
|
31
|
+
Create a copy of the config file (*fluxbox_apps_menu.yaml*) under
|
32
|
+
the _~/.fluxbox_ folder
|
33
|
+
|
34
|
+
$ fluxbox_apps_menu menuconfig
|
35
|
+
|
36
|
+
Get help
|
37
|
+
|
38
|
+
$ fluxbox_apps_menu help
|
39
|
+
|
40
|
+
Get help for a specific task
|
41
|
+
|
42
|
+
$ fluxbox_apps_menu help build
|
43
|
+
$ fluxbox_apps_menu help menuconfig
|
44
|
+
|
45
|
+
When the application's menu is built it can be included in
|
46
|
+
your main fluxbox menu file (usually *~/.fluxbox/menu*) adding
|
47
|
+
the row below where you want display it:
|
48
|
+
|
49
|
+
[include] (~/.fluxbox/menu-apps)
|
50
|
+
|
51
|
+
## Contributing
|
52
|
+
|
53
|
+
1. Fork it ( https://github.com/fabiomux/fluxbox_apps_menu/fork )
|
54
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
55
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
56
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
57
|
+
5. Create a new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'fluxbox_apps_menu/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'fluxbox_apps_menu'
|
8
|
+
spec.version = FluxboxAppsMenu::VERSION
|
9
|
+
spec.authors = ['Fabio Mucciante']
|
10
|
+
spec.email = ['fabio.mucciante@gmail.com']
|
11
|
+
spec.summary = %q{Build the Fluxbox apps menu.}
|
12
|
+
spec.description = %q{This script reads the .desktop files installed and build the application's menu under the Fluxbox home folder.}
|
13
|
+
spec.homepage = 'https://github.com/fabiomux/fluxbox_apps_menu'
|
14
|
+
spec.license = 'GPL v.3'
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.6"
|
22
|
+
spec.add_development_dependency "rake"
|
23
|
+
|
24
|
+
spec.add_runtime_dependency "inifile", "~> 3.0"
|
25
|
+
spec.add_runtime_dependency "thor"
|
26
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
require 'fluxbox_apps_menu/version'
|
2
|
+
require 'fluxbox_apps_menu/config'
|
3
|
+
require 'fluxbox_apps_menu/menu'
|
4
|
+
require 'fluxbox_apps_menu/desktop_file'
|
5
|
+
require 'fluxbox_apps_menu/utils'
|
6
|
+
|
7
|
+
$VERBOSE = nil
|
8
|
+
|
9
|
+
module FluxboxAppsMenu
|
10
|
+
|
11
|
+
class Builder
|
12
|
+
|
13
|
+
def initialize(opts)
|
14
|
+
#p opts; exit
|
15
|
+
@filename = opts[:filename].to_s.empty? ? 'menu-apps' : opts[:filename]
|
16
|
+
@silent = opts[:silent]
|
17
|
+
@overwrite = opts[:overwrite]
|
18
|
+
@cfg = FluxboxAppsMenu::Config.new
|
19
|
+
@fmenu = FluxboxAppsMenu::Menu.new(@cfg)
|
20
|
+
end
|
21
|
+
|
22
|
+
def create_menu
|
23
|
+
if @overwrite == false
|
24
|
+
if File.exists?(File.expand_path("~/.fluxbox/#{@filename}"))
|
25
|
+
puts "The file #{@filename} already exists!" unless @silent
|
26
|
+
exit
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
scan_app_folder
|
31
|
+
text = @fmenu.render
|
32
|
+
File.open(File.expand_path("~/.fluxbox/#{@filename}"), 'w') { |f| f.write(text) }
|
33
|
+
end
|
34
|
+
|
35
|
+
def init_config
|
36
|
+
unless @overwrite
|
37
|
+
if File.exists?(File.expand_path("~/.fluxbox/fluxbox_apps_menu.yaml"))
|
38
|
+
puts '[Error] '.bold.red + "The file 'fluxbox_apps_menu.yaml' already exists in '#{File.expand_path('~/.fluxbox')}'" unless @silent
|
39
|
+
exit
|
40
|
+
end
|
41
|
+
end
|
42
|
+
FileUtils.copy(File.dirname(__FILE__) + '/fluxbox_apps_menu.yaml', File.expand_path('~/.fluxbox/'))
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def scan_app_folder
|
48
|
+
@cfg.app_paths.each do |d|
|
49
|
+
|
50
|
+
Dir.glob(d + '/*.desktop') do |f|
|
51
|
+
|
52
|
+
ini = DesktopFile.new(f, @cfg)
|
53
|
+
|
54
|
+
next if ini.banned_file?
|
55
|
+
|
56
|
+
name = ini.name
|
57
|
+
|
58
|
+
if ini.hidden?
|
59
|
+
puts '[Hidden] '.bold.green + "The application #{name} is hidden" unless @silent
|
60
|
+
next
|
61
|
+
end
|
62
|
+
|
63
|
+
cat = ini.categories
|
64
|
+
if cat.nil?
|
65
|
+
puts '[No Category] '.bold.red + "The application #{name} doesn't have any category" unless @silent
|
66
|
+
next
|
67
|
+
end
|
68
|
+
|
69
|
+
submenu = @fmenu.assign_menu(cat, name)
|
70
|
+
unless submenu.nil?
|
71
|
+
icon = ini.icon
|
72
|
+
if icon.nil?
|
73
|
+
puts '[No Icon] '.bold.yellow + "#{name} doesn't have any icon" unless @silent
|
74
|
+
end
|
75
|
+
|
76
|
+
submenu[name] = @fmenu.item_exec(name, icon, ini.exec)
|
77
|
+
else
|
78
|
+
puts "[No mapped category] #{name} doesn't have any mapped category within the menu".bold.red unless @silent
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,123 @@
|
|
1
|
+
---
|
2
|
+
# other options: kdesu and gnomesu
|
3
|
+
:switch_user: 'xdg-su'
|
4
|
+
:terminal: 'xdg-terminal'
|
5
|
+
:icons:
|
6
|
+
App Name: 'icon-name'
|
7
|
+
:banned_files:
|
8
|
+
- 'qmmp_.*'
|
9
|
+
- 'umplayer_.*'
|
10
|
+
:icon_paths:
|
11
|
+
- /usr/share/icons/gnome/16x16/apps
|
12
|
+
- /usr/share/icons/oxygen/16x16/apps
|
13
|
+
- /usr/share/icons/hicolor/16x16/apps
|
14
|
+
- /usr/share/pixmaps
|
15
|
+
- /usr/share/icons/hicolor/32x32/apps
|
16
|
+
- /usr/share/icons/oxygen/16x16/categories
|
17
|
+
- /usr/share/icons/hicolor/48x48/apps
|
18
|
+
- /usr/share/icons/hicolor/128x128/apps
|
19
|
+
:app_paths:
|
20
|
+
- /usr/share/applications
|
21
|
+
- /usr/share/applications/kde4
|
22
|
+
- /usr/share/applications/YaST2
|
23
|
+
:menu:
|
24
|
+
Development:
|
25
|
+
:icon: applications-development
|
26
|
+
:categories:
|
27
|
+
- Development
|
28
|
+
Educational:
|
29
|
+
:icon: applications-education-science
|
30
|
+
:categories:
|
31
|
+
- Science
|
32
|
+
- Astronomy
|
33
|
+
- Education
|
34
|
+
- Geography
|
35
|
+
Games:
|
36
|
+
:icon: applications-games
|
37
|
+
:categories:
|
38
|
+
- Game
|
39
|
+
- CardGame
|
40
|
+
Graphic:
|
41
|
+
:icon: applications-graphics
|
42
|
+
:categories:
|
43
|
+
- Graphics
|
44
|
+
- VectorGraphics
|
45
|
+
Internet:
|
46
|
+
:icon: applications-internet
|
47
|
+
:categories:
|
48
|
+
- Network
|
49
|
+
Multimedia:
|
50
|
+
:icon: applications-multimedia
|
51
|
+
:categories:
|
52
|
+
- Audio
|
53
|
+
- Video
|
54
|
+
- Player
|
55
|
+
- AudioVideoEditing
|
56
|
+
- Mixer
|
57
|
+
- Recorder
|
58
|
+
- DiscBurning
|
59
|
+
Office:
|
60
|
+
:icon: applications-office
|
61
|
+
:categories:
|
62
|
+
- Office
|
63
|
+
LibreOffice Draw: ''
|
64
|
+
System:
|
65
|
+
:icon: applications-system
|
66
|
+
:categories:
|
67
|
+
- Settings
|
68
|
+
- System
|
69
|
+
- DesktopSettings
|
70
|
+
- Documentation
|
71
|
+
'. / Yast /':
|
72
|
+
:icon: yast-mascot
|
73
|
+
:categories:
|
74
|
+
- Yast
|
75
|
+
Hardware:
|
76
|
+
:icon: package_yast_hardware
|
77
|
+
:categories:
|
78
|
+
- X-SuSE-YaST-Hardware
|
79
|
+
Miscellaneous:
|
80
|
+
:icon: package_yast_misc
|
81
|
+
:categories:
|
82
|
+
- X-SuSE-YaST-Misc
|
83
|
+
Network Devices:
|
84
|
+
:icon: yast-network_devices
|
85
|
+
:categories:
|
86
|
+
- X-SuSE-YaST-Network
|
87
|
+
Network Services:
|
88
|
+
:icon: yast-network_services
|
89
|
+
:categories:
|
90
|
+
- X-SuSE-YaST-Net_advanced
|
91
|
+
Security and Users:
|
92
|
+
:icon: yast-security
|
93
|
+
:categories:
|
94
|
+
- X-SuSE-YaST-Security
|
95
|
+
System:
|
96
|
+
:icon: package_yast_system
|
97
|
+
:categories:
|
98
|
+
- X-SuSE-YaST-System
|
99
|
+
Software:
|
100
|
+
:icon: yast-software
|
101
|
+
:categories:
|
102
|
+
- X-SuSE-YaST-Software
|
103
|
+
Support:
|
104
|
+
:icon: yast-support
|
105
|
+
:categories:
|
106
|
+
- X-SuSE-YaST-Support
|
107
|
+
Utility:
|
108
|
+
:icon: applications-utilities
|
109
|
+
:categories:
|
110
|
+
- Archiving
|
111
|
+
- Utility
|
112
|
+
'. / Text Files /':
|
113
|
+
:icon: accessories-text-editor
|
114
|
+
:categories:
|
115
|
+
- TextEditor
|
116
|
+
'. / File Managers /':
|
117
|
+
:icon: system-file-manager
|
118
|
+
:categories:
|
119
|
+
- FileManager
|
120
|
+
'. / Terminal Emulators /':
|
121
|
+
:icon: utilities-terminal
|
122
|
+
:categories:
|
123
|
+
- TerminalEmulator
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'thor'
|
2
|
+
require 'fluxbox_apps_menu'
|
3
|
+
require 'fluxbox_apps_menu/version'
|
4
|
+
|
5
|
+
module FluxboxAppsMenu
|
6
|
+
|
7
|
+
class CLI < Thor
|
8
|
+
|
9
|
+
desc 'build', 'Build the menu'
|
10
|
+
method_option :filename, :aliases => '-f', :default => '', :desc => 'Save as filename.'
|
11
|
+
method_option :silent, :aliases => '-s', :default => false, :type => :boolean, :desc => 'Don\'t show any output message.'
|
12
|
+
method_option :overwrite, :aliases => '-o', :default => true, :type => :boolean, :desc => 'Overwrite the app menu if exists.'
|
13
|
+
def build
|
14
|
+
FluxboxAppsMenu::Builder.new(options).create_menu
|
15
|
+
end
|
16
|
+
|
17
|
+
desc 'menuconfig', 'Make a local copy of the configuration file.'
|
18
|
+
method_option :overwrite, :aliases => '-o', :default => false, :type => :boolean, :desc => 'Overwrite the config file if exists.'
|
19
|
+
def menuconfig
|
20
|
+
FluxboxAppsMenu::Builder.new(options).init_config
|
21
|
+
end
|
22
|
+
|
23
|
+
def help(arg = nil)
|
24
|
+
if arg.nil?
|
25
|
+
puts <<EOL
|
26
|
+
FluxboxAppsMenu v.#{FluxboxAppsMenu::VERSION} by Fabio Mucciante
|
27
|
+
|
28
|
+
Description:
|
29
|
+
Build a Fluxbox menu putting the applications in the right
|
30
|
+
section as configured within the "fluxbox_apps_menu.yaml" file.
|
31
|
+
|
32
|
+
Using the "menuconfig" task a copy of this file will be created
|
33
|
+
under the "~/.fluxbox" path.
|
34
|
+
|
35
|
+
The application's menu file will be created in "~/.fluxbox/menu-apps"
|
36
|
+
and can be included within your fluxbox menu adding the row below:
|
37
|
+
|
38
|
+
[include] (~/.fluxbox/menu-apps)
|
39
|
+
|
40
|
+
EOL
|
41
|
+
super
|
42
|
+
else
|
43
|
+
super arg
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
default_task :build
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
module FluxboxAppsMenu
|
4
|
+
class Config
|
5
|
+
attr_reader :lang, :icon_paths, :filename, :banned_files, :app_paths, :icons, :terminal
|
6
|
+
attr_accessor :menu
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
if File.exists?(ENV['HOME'] + '/.fluxbox/fluxbox_apps_menu.yaml')
|
10
|
+
@filename = ENV['HOME'] + '/.fluxbox/fluxbox_apps_menu.yaml'
|
11
|
+
elsif File.exists?(ENV['HOME'] + '/.fluxbox_apps_menu.yaml')
|
12
|
+
@filename = ENV['HOME'] + '/.fluxbox_apps_menu.yaml'
|
13
|
+
elsif File.exists?('/etc/fluxbox_apps_menu.yaml')
|
14
|
+
@filename = '/etc/fluxbox_apps_menu.yaml'
|
15
|
+
else
|
16
|
+
@filename = File.expand_path(File.dirname(__FILE__) + '/../fluxbox_apps_menu.yaml')
|
17
|
+
end
|
18
|
+
|
19
|
+
yaml = YAML.load_file(@filename)
|
20
|
+
|
21
|
+
@banned_files = yaml[:banned_files]
|
22
|
+
@icon_paths = yaml[:icon_paths]
|
23
|
+
@app_paths = yaml[:app_paths] + [ ENV['HOME'] + '/.local/share/applications']
|
24
|
+
@menu = yaml[:menu]
|
25
|
+
@icons = yaml[:icons]
|
26
|
+
@terminal = yaml[:terminal]
|
27
|
+
|
28
|
+
@lang = ENV['LANG'].split('.')[0]
|
29
|
+
@lang = { :short => @lang.split('_')[0], :long => @lang }
|
30
|
+
end
|
31
|
+
|
32
|
+
def expand_icon(app_name, icon_name)
|
33
|
+
iname = @icons[app_name] unless app_name.nil?
|
34
|
+
iname = icon_name if iname.nil?
|
35
|
+
|
36
|
+
return nil if iname.to_s.empty?
|
37
|
+
return iname if iname.to_s.match('/') && File.exists?(iname)
|
38
|
+
|
39
|
+
iname.gsub!(/\.png$/, '')
|
40
|
+
|
41
|
+
@icon_paths.each do |p|
|
42
|
+
return "#{p}/#{iname}.png" if File.exists?("#{p}/#{iname}.png")
|
43
|
+
end
|
44
|
+
|
45
|
+
return nil
|
46
|
+
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
@@ -0,0 +1,69 @@
|
|
1
|
+
require 'inifile'
|
2
|
+
#require 'fluxbox_apps_menu/config'
|
3
|
+
module FluxboxAppsMenu
|
4
|
+
|
5
|
+
class DesktopFile
|
6
|
+
|
7
|
+
def initialize(filename, cfg = nil)
|
8
|
+
@ini = IniFile.new(:filename => filename, :comment => '#', :encoding => 'UTF-8')
|
9
|
+
@cfg = cfg.nil? ? FluxboxAppsMenu::Config.new : cfg
|
10
|
+
@filename = filename
|
11
|
+
end
|
12
|
+
|
13
|
+
def name(lang = true)
|
14
|
+
if lang
|
15
|
+
name = @ini['Desktop Entry']["Name[#{@cfg.lang[:short]}]"]
|
16
|
+
name = @ini['Desktop Entry']["Name[#{@cfg.lang[:long]}]"] if name.nil?
|
17
|
+
end
|
18
|
+
|
19
|
+
name = @ini['Desktop Entry']['Name'] if name.nil?
|
20
|
+
|
21
|
+
name
|
22
|
+
end
|
23
|
+
|
24
|
+
def hidden?
|
25
|
+
@ini['Desktop Entry']['NoDisplay'] == true
|
26
|
+
end
|
27
|
+
|
28
|
+
def banned_file?
|
29
|
+
@cfg.banned_files.each { |r| return true if @filename =~ Regexp.new(r) }
|
30
|
+
false
|
31
|
+
end
|
32
|
+
|
33
|
+
def icon
|
34
|
+
=begin
|
35
|
+
iname = @cfg.icons[name(false)]
|
36
|
+
iname = @ini['Desktop Entry']['Icon'] if iname.nil?
|
37
|
+
|
38
|
+
return nil if iname.to_s.empty?
|
39
|
+
return iname if iname.to_s.match('/') && File.exists?(iname)
|
40
|
+
|
41
|
+
iname.gsub!(/\.png$/, '')
|
42
|
+
|
43
|
+
@cfg.icon_paths.each do |p|
|
44
|
+
return "#{p}/#{iname}.png" if File.exists?("#{p}/#{iname}.png")
|
45
|
+
end
|
46
|
+
return nil
|
47
|
+
=end
|
48
|
+
@cfg.expand_icon(name(false), @ini['Desktop Entry']['Icon'])
|
49
|
+
end
|
50
|
+
|
51
|
+
def terminal?
|
52
|
+
@ini['Desktop Entry']['Terminal'] == 'true'
|
53
|
+
end
|
54
|
+
|
55
|
+
def categories
|
56
|
+
cat = @ini['Desktop Entry']['Categories']
|
57
|
+
cat.split(';') unless cat.nil?
|
58
|
+
end
|
59
|
+
|
60
|
+
def exec
|
61
|
+
com = @ini['Desktop Entry']['Exec'].to_s.gsub('%c', name).gsub('%F', '')
|
62
|
+
.gsub('%i', '').gsub('%U', '').gsub('%f', '').gsub('%m', '')
|
63
|
+
.gsub('%u', '').gsub(/[ ]{2,}/, ' ').gsub(/\ }/, '}')
|
64
|
+
|
65
|
+
terminal? ? @cfg.terminal + ' ' + com : com
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|