On Apr 13, 2006, at 11:50 AM, David K. Hess wrote: > > Generally speaking, I'm not convinced that the method interface to > Site isn't already generic enough to be used by many types of Site > implementations. In fact, I think that interface should be > *required* of all Site implementations. If so, then bin/qp and for > instance bin/tqp should really only differ in one line of > functionality: an import statement. I'm with you up to here. > However, I also believe that the Site to use should not be chosen > by the management tool. That decision should be in the > implementation; i.e. slash.qpy. I understand what you are saying, but you haven't said why you believe that. I guess you mean that you want bin/qp to be able to manage a collection of sites at the same time, each with a different Site class. The bin/qp tool expects Site.start_web() to start the web and scgi servers. If I understand it correctly, you want your start_web() to not do that. I don't think your subclass is satisfying the "contract". > > Once you have made that decision, then I think moving run_web to > the Publisher just forces unnecessary work on the developer. This does not require anything from the developer. The default Publisher provides the default implementation of run_web(), and this is used by the default implementation of start_web(). If you want a customized run_web(), you can override. I'm pretty sure this is two notches simpler than writing a customized Site subclass that overrides start_web(). > start_web in the customized site already knows all the details of > what needs to be done to start a twisted web application. Also, > making this choice conveniently gets rid of the issue of start_web > in the Site and run_web in the Publisher both needing to coordinate > whether or not to behave as a standalone application. > > So, here's what I've got working. I changed get_sites to the > following: > > def get_sites(klass): > """() -> {name:str : site:Site} > Note that this is a method of the class. > It returns an index of all of the installed sites. > """ > sites_package= import_object(klass.sites_package_name) > sites_directory = sites_package.__path__[0] > names = [name > for name in listdir(sites_directory) > if (isdir(join(sites_directory, name)) > and '.' not in name)] > sites = {} > for name in names: > m = import_object("%s.%s.slash" % > (klass.sites_package_name, name)) > if hasattr(m, "Site"): > sites[name] = m.Site(name) > else: > sites[name] = Site(name) > > return sites > > And I have this in slash.qpy: > > ..... > from qp.hub.twistedhub import TwistedSite > > Site = TwistedSite > > class SitePublisher (Publisher): > > configuration = dict( > http_address=('', 8001), > ) > ..... > > I also have a suitable twistedhub.py which has a TwistedSite class > with just one method so far: a twisted specific start_web. I still > have more integration and cleanup to do, but this basic approach is > working. At least "bin/qp -s echo start" works and the demo is > reachable from a web browser. I don't think, though, that your "bin/tqp -v" does what I want it to. But, the good news is that your "bin/tqp" has the behavior *you* want.