PageRenderTime 43ms CodeModel.GetById 0ms RepoModel.GetById 0ms app.codeStats 0ms

/htpicker/handler.py

https://github.com/mackstann/htpicker
Python | 126 lines | 103 code | 15 blank | 8 comment | 7 complexity | aca251c188c4737b8b7423eb189a6413 MD5 | raw file
  1. #!/usr/bin/env python
  2. import os
  3. import fnmatch
  4. import itertools
  5. import json
  6. import logging
  7. import pkg_resources
  8. import stat
  9. import types
  10. import urllib
  11. from htpicker.browser import URLHandler, URLAction
  12. class HTPickerURLHandler(URLHandler):
  13. def __init__(self, scheme, config, dir_change_cb):
  14. super(HTPickerURLHandler, self).__init__(scheme)
  15. self.config = config
  16. self.dir_change_cb = dir_change_cb
  17. def return_uri_filter(self, data):
  18. if isinstance(data, types.DictType):
  19. return ('data:application/json;charset=utf-8;base64,'
  20. + json.dumps(data).encode('base64'))
  21. return data
  22. @URLAction
  23. def exit(self):
  24. raise SystemExit
  25. @URLAction
  26. def enable_fullscreen(self):
  27. self.browser.fullscreen()
  28. @URLAction
  29. def disable_fullscreen(self):
  30. self.browser.unfullscreen()
  31. @URLAction
  32. def get_startup_config(self):
  33. return {
  34. 'show_animations': int(self.config.get_show_animations()),
  35. 'fullscreen': int(self.config.get_fullscreen()),
  36. 'initial_dir': os.path.abspath(self.config.get_initial_dir()),
  37. }
  38. @URLAction
  39. def file_resource(self, filepath, mime_type):
  40. # sadly there appears to be no way to sniff the mime type from the
  41. # Accept header (or access request headers in general), so we must also
  42. # ask for it in the URL.
  43. filename = pkg_resources.resource_filename(__name__, 'data/'+filepath)
  44. if os.name == 'nt':
  45. filename = '/' + filename.replace('\\', '/')
  46. return 'file://' + urllib.quote(filename)
  47. @URLAction
  48. def play_file(self, fullpath):
  49. command = self.config.get_command(fullpath)
  50. if not command:
  51. logging.warn("No command is set for this file: " + fullpath)
  52. return
  53. os.system(command + ' &')
  54. #subprocess.Popen(command, shell=True)
  55. #os.waitpid(proc.pid, 0)
  56. # the above "should" work but results in a mysterious situation
  57. # on my eeepc: mplayer outputs one line ("MPlayer SVN-r29237-4.4.1
  58. # (C) 2000-2009 MPlayer Team") to the shell, and then everything
  59. # stops. mplayer is hung, and htpicker has mysteriously received a
  60. # SIGSTOP from somewhere. i don't get it AT ALL.
  61. # system(command + ' &') is ugly but works fine.
  62. def _get_file_info(self, directory, filename):
  63. info = { 'display_name': filename, 'fullpath': directory + '/' + filename }
  64. try:
  65. mode = os.stat(info['fullpath']).st_mode
  66. except OSError:
  67. # broken symlink, among other things.
  68. # maybe this should fall back to lstat and try a little harder to
  69. # give info about this broken file-thingie, instead of hiding it.
  70. return None
  71. if stat.S_ISDIR(mode):
  72. info['type'] = 'directory'
  73. info['icon'] = 'directory'
  74. elif stat.S_ISREG(mode):
  75. info['type'] = 'file'
  76. info['icon'] = self.config.get_icon(info['fullpath'])
  77. info['display_name'] = os.path.splitext(filename)[0]
  78. else:
  79. info['type'] = 'other'
  80. info['icon'] = ''
  81. return info
  82. @URLAction
  83. def list_files(self, directory):
  84. files = []
  85. ignore_match = self.config.get_ignore_regex().match
  86. listing = [ f for f in os.listdir(directory) if not ignore_match(f.lower()) ]
  87. listing = sorted(listing, key=str.lower)
  88. for filename in listing:
  89. file_info = self._get_file_info(directory, filename)
  90. if file_info:
  91. files.append(file_info)
  92. if directory != '/':
  93. files.insert(0, {
  94. 'fullpath': directory.rsplit('/', 1)[0] or '/',
  95. 'display_name': '↑ Parent Folder',
  96. 'type': 'directory',
  97. 'icon': 'directory',
  98. })
  99. self.dir_change_cb(directory)
  100. return { 'files': files }