qubes-session-autostart 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. #
  4. # The Qubes OS Project, http://www.qubes-os.org
  5. #
  6. # Copyright (C) 2015 Marek Marczykowski-Górecki
  7. # <marmarek@invisiblethingslab.com>
  8. #
  9. # This program is free software; you can redistribute it and/or
  10. # modify it under the terms of the GNU General Public License
  11. # as published by the Free Software Foundation; either version 2
  12. # of the License, or (at your option) any later version.
  13. #
  14. # This program is distributed in the hope that it will be useful,
  15. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. # GNU General Public License for more details.
  18. #
  19. # You should have received a copy of the GNU General Public License
  20. # along with this program; if not, write to the Free Software
  21. # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  22. #
  23. #
  24. import subprocess
  25. import sys
  26. from xdg.DesktopEntry import DesktopEntry
  27. from qubesxdg import launch
  28. import xdg.BaseDirectory
  29. import os
  30. QUBES_XDG_CONFIG_DROPINS = '/etc/qubes/autostart'
  31. def open_desktop_entry_and_dropins(filename):
  32. desktop_entry = DesktopEntry(filename)
  33. dropins_dir = os.path.join(QUBES_XDG_CONFIG_DROPINS,
  34. os.path.basename(filename) + '.d')
  35. if os.path.isdir(dropins_dir):
  36. for dropin in sorted(os.listdir(dropins_dir)):
  37. dropin_content = DesktopEntry(os.path.join(dropins_dir, dropin))
  38. desktop_entry.content.update(dropin_content.content)
  39. return desktop_entry
  40. def entry_should_be_started(entry, environments):
  41. """
  42. :type entry: DesktopEntry
  43. """
  44. if entry.getHidden():
  45. return False
  46. if entry.getOnlyShowIn():
  47. return bool(set(entry.getOnlyShowIn()).intersection(environments))
  48. if entry.getNotShowIn():
  49. return not bool(set(entry.getNotShowIn()).intersection(environments))
  50. return True
  51. def process_autostart(environments):
  52. # handle only "most important" entry
  53. processed_entries = {}
  54. for path in xdg.BaseDirectory.load_config_paths('autostart'):
  55. for entry_name in os.listdir(path):
  56. if entry_name in processed_entries:
  57. continue
  58. # make the entry as processed, even if not actually started
  59. processed_entries[entry_name] = True
  60. try:
  61. entry_path = os.path.join(path, entry_name)
  62. # files in $HOME have higher priority than dropins
  63. if not path.startswith(xdg.BaseDirectory.xdg_config_home):
  64. entry = open_desktop_entry_and_dropins(entry_path)
  65. else:
  66. entry = DesktopEntry(entry_path)
  67. if entry_should_be_started(entry, environments):
  68. launch(entry_path)
  69. except Exception as e:
  70. print >>sys.stderr, "Failed to process '{}': {}".format(
  71. entry_name, str(e)
  72. )
  73. def main():
  74. process_autostart(sys.argv[1:])
  75. if __name__ == '__main__':
  76. main()