A modest string writer

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. # -*- coding: utf-8 -*-
  2. import imp
  3. import os
  4. import sys
  5. class SardinePluginError(Exception):
  6. pass
  7. class XGPRenderer(object):
  8. def __init__(self, txt=None):
  9. self.txt = txt
  10. self.img = None
  11. self.tool = txt
  12. self.bar = None
  13. self.click = None
  14. self._fields = ['txt', 'img', 'tool', 'bar', 'click']
  15. def __str__(self):
  16. out = ""
  17. for field in self._fields:
  18. value = getattr(self, field, None)
  19. if value is not None:
  20. out += "<%(f)s>%(v)s</%(f)s>" % {'f': field, 'v': value}
  21. return out
  22. class BasePlugin(object):
  23. def __init__(self, data):
  24. self.data = data
  25. def render(self):
  26. method_n = "render_" + self.data.fmt
  27. def ex(__):
  28. raise SardinePluginError("method not defined: " + method_n)
  29. render_fn = getattr(self, method_n, ex)
  30. return render_fn()
  31. def render_xgp(self):
  32. return XGPRenderer(self.render_plain())
  33. class PluginData(object):
  34. def __init__(self, cmdargs):
  35. self.args = []
  36. self.fmt = "plain"
  37. self.maxlen = 40
  38. self.name = ""
  39. self._load(cmdargs)
  40. def _load(self, cmdargs):
  41. if cmdargs['--plain']:
  42. self.fmt = "plain"
  43. elif cmdargs['--xgp']:
  44. self.fmt = "xgp"
  45. self.name = cmdargs['COMMAND']
  46. self.args = cmdargs['ARGS']
  47. if cmdargs['--chars']:
  48. self.maxlen = int(cmdargs['--chars'])
  49. class Subcommand(object):
  50. def __init__(self, cmdargs, pluginpath):
  51. self.plugindata = PluginData(cmdargs)
  52. self.name = cmdargs['COMMAND']
  53. self._load_plugin(pluginpath)
  54. def _load_plugin(self, pluginpath):
  55. modpath = "%s/%s.py" % (pluginpath, self.name)
  56. try:
  57. with open(modpath) as fh:
  58. module = imp.load_module(self.name, fh, modpath,
  59. (".py", "r", imp.PY_SOURCE))
  60. except IOError:
  61. raise SardinePluginError(self.name)
  62. self.plugin = module.Plugin(self.plugindata)
  63. def _format_output(self, raw):
  64. suffix = "..."
  65. cooked = raw
  66. if self.plugindata.fmt == "plain":
  67. if len(raw) > self.plugindata.maxlen:
  68. newlen = self.plugindata.maxlen - len(suffix)
  69. cooked = raw[:newlen] + suffix
  70. return cooked
  71. def get_output(self):
  72. return self._format_output(self.plugin.render())
  73. class App:
  74. def __init__(self, cmdargs):
  75. self._set_pluginpath()
  76. try:
  77. self.subcommand = Subcommand(cmdargs, self.pluginpath)
  78. except SardinePluginError as e:
  79. self.die("no such plugin: %s" % e)
  80. def _set_pluginpath(self):
  81. mypath = os.path.dirname(os.path.realpath(sys.argv[0]))
  82. path = mypath + "/plugins"
  83. path = os.environ.get("SARDINE_PLUGINS", path)
  84. self.pluginpath = path
  85. def die(self, msg, rv=9):
  86. sys.stderr.write(msg + "\n")
  87. self.exit(rv)
  88. def exit(self, rv=0):
  89. sys.exit(rv)
  90. def run(self):
  91. print self.subcommand.get_output()