-----Original Message-----
From: cobbler-devel-bounces(a)lists.fedorahosted.org [mailto:cobbler-devel-
bounces(a)lists.fedorahosted.org] On Behalf Of Michael DeHaan
Sent: woensdag 1 april 2009 21:56
To: cobbler development list
Subject: Re: WebUI search patch
Vreman, Peter - Acision wrote:
>> Thanks for all the patches, Peter. I have applied all I could except
the
>> filter one, which I explained why below. I'm definitely interested in
>> search upgrades, but am not sure we want a "filter" object.
>> I'm not saying that's final, it's just that I first would have to
see
>> what some email/text demo of what a filter object would look like and
>> how some one would use it. Most likely I would like to see simpler
>> ways of implementing saved search, even if it's something that simply
>> saves them in a datastructure and not using the cobbler object system,
>> that would be ok... perhaps even Bookmarklets?
>>
>> All of these are applied to the devel branch when I say "Applied". If
>> there are any fixes to the 1.6.2 search (i.e for bugs, those go against
>> master).
>>
>
> Thanks for applying the patches.
>
> The commit 4e155e67b6cc5c8b756f0df59b21c9e14c400b67 (> 0009-rename-with-
same-name-does-nothing-instead-of-deleti.patch) is a bug fix that should
also be in master.
>
>
>
Cherry-picked, thanks for the heads up!
>> 0004-filter-objects-added.patch.gz
>>
>> Not applied. In my previous email, I indicated we strongly didn't want
>> to introduce the concept of a new cobbler "noun" for something like
>> saved search results. A better way to do this would be to just have a
>> way to save search parameters in the settings file and let them show up
>> on the search page, perhaps as hyperlinks. We want to reserve cobbler
>> "nouns" for data that cobbler is trying to model. The main reason for
>> all this is that new object types require a tremendous amount of code
>> (that we eventually want to clean up), and we want to keep things as
>> simple as possible.
>>
>
> To show you what my goal was to create I have attached two screenshots
of the patch. The saved filters will allow quick filtering using a
dropdown box on the list screen.
>
> The filter object is a hash with the following keys:
> - name
> - what (distro/system/profile/...)
> - keys hash
> - (not implemented yet) matching type ALL or ANY
>
> I still used the cobbler "noun" in this patch because that part was
already finished and working. Refactoring of the "noun" to a custom array
of hashes can be done. But how shall the serialization to disk be
implemented if the "noun" part can't be reused?
>
> Peter
>
I see and very much like where you are going from a user perspective.
I guess I was hesistant to have to explain what a "filter" object was
and maintain the code involved. Perhaps I'm wrong though.
What we could do is have something in settings:
search_filters:
- "labA" : { "what" : "systems" }, { "keys"
: "..." }
- "labB" : { ... }
Though this would require adding them to settings yourself, rather than
making them editable in the web application. Perhaps my reasoning is
not correct and it is worth it to have these, I don't know.
Creating filters like this is not easy for less-techie users.
What would the command line invocation look like?
cobbler filter add --name=LabA --what=system --keys="network=LabA"
??
Yes it is possible to add the filter creation to the CLI. For the criteria we can allow
multiple --keys arguments or use '--key1="network=LabA"
--key2="network=Public"'
If we had the following, I could see it being useful:
cobbler report --what=systems --matches-filter=LabA
--fields=name,mac_address,ip_address
(Keep in mind there is some weirdness about "cobbler report" being
implemented differently than "cobbler system report" ... cleaning this
up would also be desirable).
This is also possible. Instead of 'get_systems' it needs to be replaced by
'find_system'. Maybe the find_system **kargs argument can then better can be
replaced by a filter object so it also allows ALL/ANY matching.
You are correct in that coming up with a seperate system of saving
things is extra work. I guess what I'm trying to avoid is maintaining a
lot of seperate pages in the web app for editing different things, CLI
options, and everything else that comes with a new noun.
I like the concept of having the object model having very few
primatives, but I'm not neccessarily stuck on it.
Thoughts?
I'm aware of this issue. I'm already thinking how I can create a generate
list-page with the multiple checkboxes support without requiring a separate xx_list.tmp
page per type.
But for the (Remote) API it is also how do you want to expose the methods. You can do it
two ways:
Remote.Find(what="distro",page="1",token=token)
Remote.Find(what="system",filter="FilterB",page="1",token=token)
Or
Remote.find_distro(page=1,token=token)
Remote.find_system(page=1,filter="FilterB",token=token)
With the latter you end a lot of code that is common. An example from the remote.py that
illustrates this is below. There is a single function that handles everything and only
dummy wrapper methods around it for the different types:
def
__get_multiple(self,collection_name,criteria={},expand=False,pageinfo=False,page=None,results_per_page=None,page
"""
Internal function to return an array of hash representations for all objects
matching
the criteria
"""
if collection_name == "distro":
find_func=self.api.find_distro
all_func=self.api.distros
elif collection_name == "profile":
find_func=self.api.find_profile
all_func=self.api.profiles
elif collection_name == "system":
find_func=self.api.find_system
all_func=self.api.systems
elif collection_name == "repo":
find_func=self.api.find_repo
all_func=self.api.repos
elif collection_name == "image":
find_func=self.api.find_image
all_func=self.api.images
elif collection_name == "filter":
find_func=self.api.find_filter
all_func=self.api.filters
else:
raise CX("internal error, collection name is %s" % collection_name)
....
Do common things
...
def get_distros(self,expand=True,token=None,**rest):
self._log("get_distros", token=token)
return self.__get_multiple("distro",expand=expand,token=token)
def get_profiles(self,expand=True,token=None,**rest):
self._log("get_profiles", token=token)
return self.__get_multiple("profile",expand=expand,token=token)
def
find_distro(self,criteria={},expand=False,pageinfo=False,page=None,results_per_page=None,token=None,**rest):
self._log("find_distro", attribute=hash_to_string(criteria),
token=token)
return
self.__get_multiple("distro",criteria,expand,pageinfo,page,results_per_page,token)
def
find_profile(self,criteria={},expand=False,pageinfo=False,page=None,results_per_page=None,token=None,**rest):
self._log("find_profile", attribute=hash_to_string(criteria),
token=token)
return
self.__get_multiple("profile",criteria,expand,pageinfo,page,results_per_page,token)
It seems like the "Quick Filter" thing is really the same
as a saved
search, right? (Or does this allow filtering search results further?
If so, very cool!)
The quick filter is just applying the save filters. If multiple filter support is wanted
this also needs to be implemented in the .api.find() commands.
Peter
This e-mail and any attachment is for authorised use by the intended recipient(s) only. It
may contain proprietary material, confidential information and/or be subject to legal
privilege. It should not be copied, disclosed to, retained or used by, any other party. If
you are not an intended recipient then please promptly delete this e-mail and any
attachment and all copies and inform the sender. Thank you.