Dne 21.10.2010 21:19, Jan Provazník napsal(a):
Hi,
sending updated version of selection model.
TODO:
- styling (multicolumns, loadmasks)
- (maybe?) grouping packages by groups (as in previous model)
- pagination
- type-ahead search enhancement of previous suggestion (quite difficult)
Jan
Sending again rebased patch.
From bf6220efe4b1e2c5311d1ad5ebf000b228681501 Mon Sep 17 00:00:00 2001
From: Jan Provaznik <[email protected]>
Date: Thu, 21 Oct 2010 22:37:49 +0200
Subject: [PATCH aggregator] selection model - first shoot
Rerun "rake dc:prepare_repos" after applying. Note that this not yet final
version, should be applied on patcheset "rebased pending patches".
---
src/app/controllers/templates_controller.rb | 38 +++++++++++--
src/app/util/repository_manager.rb | 59 ++++++++++++++++++++
.../util/repository_manager/comps_repository.rb | 58 +++++++++++++++++---
src/app/util/repository_manager/pulp_repository.rb | 25 ++++++++-
src/app/views/templates/_collections.haml | 6 ++
src/app/views/templates/_managed_content.haml | 4 +-
src/app/views/templates/_metagroup_packages.haml | 8 +++
src/app/views/templates/content_selection.haml | 49 ++++++++++-------
src/app/views/templates/new.haml | 24 +++++---
.../image_descriptor_package_metagroups.conf | 20 +++++++
10 files changed, 246 insertions(+), 45 deletions(-)
create mode 100644 src/app/views/templates/_collections.haml
create mode 100644 src/app/views/templates/_metagroup_packages.haml
create mode 100644 src/config/image_descriptor_package_metagroups.conf
diff --git a/src/app/controllers/templates_controller.rb
b/src/app/controllers/templates_controller.rb
index c58f513..32523f6 100644
--- a/src/app/controllers/templates_controller.rb
+++ b/src/app/controllers/templates_controller.rb
@@ -62,6 +62,13 @@ class TemplatesController < ApplicationController
params[:packages] = params[:selected_packages]
new
+ elsif params.include?('show_metagroup')
+ @metagroup = params['show_metagroup']
+ content_selection
+
+ elsif not params[:package_search].blank?
+ content_selection
+
end
end
@@ -105,9 +112,32 @@ class TemplatesController < ApplicationController
@tpl = @id.blank? ? Template.new : Template.find(@id)
@tpl.attributes = params[:tpl] unless params[:tpl].nil?
@packages = []
- @packages = params[:packages].collect{ |p| { :name => p } } if
params[:packages]
+ @packages += params[:packages].collect{ |p| { :name => p } } unless
params[:packages].blank?
+ @packages += params[:selected_packages].collect{ |p| { :name => p } }
unless params[:selected_packages].blank?
@groups =
@repository_manager.all_groups_with_tagged_selected_packages(@packages,
@tpl.platform)
@embed = params[:embed]
+ @categories = @repository_manager.categories(params[:tpl] ?
params[:tpl][:platform] : nil)
+ @metagroups = @repository_manager.metagroups
+
+ if not params[:package_search].blank?
+ @metagroup_packages =
@repository_manager.search_package(params[:package_search], params[:repository])
+ elsif not @metagroup.blank?
+ if @metagroup == 'Collections'
+ # TODO: if we remember selected groups, this could be done much more
simply
+ @collections =
@repository_manager.all_groups_with_tagged_selected_packages(@packages,
params[:repository])
+ else
+ @metagroup_packages =
@repository_manager.metagroup_packages(@metagroup, params[:repository])
+ end
+ end
+ if request.xhr?
+ if @metagroup_packages
+ render :partial => 'metagroup_packages' and return
+ end
+ if @collections
+ render :partial => 'collections' and return
+ end
+ end
+
if @embed
render :layout => false
else
@@ -219,10 +249,8 @@ add account on <a href=\"#{url_for :controller =>
'provider', \
@repository_manager = RepositoryManager.new
@groups = @repository_manager.all_groups(params[:repository])
- if params[:packages]
- @selected_packages = params[:packages]
- elsif params[:selected_packages]
- @selected_packages = params[:selected_packages]
+ if not params[:packages].blank? or not params[:selected_packages].blank?
+ @selected_packages = params[:packages].to_a +
params[:selected_packages].to_a
elsif !tpl.nil?
@selected_packages = tpl.xml.packages.collect { |p| p[:name] }
else
diff --git a/src/app/util/repository_manager.rb
b/src/app/util/repository_manager.rb
index fbe7a8b..64de179 100644
--- a/src/app/util/repository_manager.rb
+++ b/src/app/util/repository_manager.rb
@@ -47,6 +47,61 @@ class RepositoryManager
return @all_groups
end
+ def packages(repository = nil)
+ end
+
+ def categories(repository = nil)
+ unless @all_categories
+ @all_categories = {}
+ repositories.each do |r|
+ next if repository and repository != 'all' and repository != r.id
+ r.categories.each do |id, data|
+ if @all_categories[id]
+ @all_categories[id][:groups] += data[:groups]
+ else
+ @all_categories[id] = data
+ end
+ end
+ end
+ end
+ return @all_categories
+ end
+
+ def packages(repository = nil)
+ unless @packages
+ @packages = []
+ repositories.each do |r|
+ next if repository and repository != 'all' and repository != r.id
+ @packages += r.packages
+ end
+ end
+ return @packages
+ end
+
+ # TODO: this is temporary solution for categorizing packages
+ def metagroups
+ unless @metagroups
+ @metagroups = {}
+ File.readlines('config/image_descriptor_package_metagroups.conf').each
do |line|
+ group, entries_str = line.chomp.split('=')
+ next unless group and entries_str
+ @metagroups[group] = entries_str.split(',')
+ end
+ end
+ @metagroups
+ end
+
+ def metagroup_packages(category, repository = nil)
+ res = []
+ groups = all_groups(repository)
+ metagroups[category].to_a.each do |entry|
+ cat, group = entry.split(';')
+ next unless c = categories[cat] and c[:groups].include?(group) and
groups[group]
+ res += groups[group][:packages].keys
+ end
+ res.sort.uniq
+ end
+
def all_groups_with_tagged_selected_packages(pkgs, repository = nil)
groups = all_groups(repository)
groups.each_value do |group|
@@ -67,6 +122,10 @@ class RepositoryManager
res
end
+ def search_package(str, repository = nil)
+ packages.select {|p| p =~ /#{Regexp.escape(str)}/i}
+ end
+
private
# returns true if all non-optional packages are selected
diff --git a/src/app/util/repository_manager/comps_repository.rb
b/src/app/util/repository_manager/comps_repository.rb
index 80391ef..86c4da7 100644
--- a/src/app/util/repository_manager/comps_repository.rb
+++ b/src/app/util/repository_manager/comps_repository.rb
@@ -11,11 +11,19 @@ class CompsRepository < AbstractRepository
end
def groups
- begin
- @groups ||= Marshal.load(File.open(@cache_file, 'r'))
- rescue Errno::ENOENT
- raise "failed to read cached packages info, run 'rake dc:prepare_repos'"
+ @groups ||= load_data[:groups]
+ end
+
+ def categories
+ @categories ||= load_data[:categories]
+ end
+
+ def packages
+ pkgs = []
+ groups.each_value do |g|
+ pkgs += g[:packages].keys
end
+ pkgs.uniq
end
def prepare_repo
@@ -25,7 +33,8 @@ class CompsRepository < AbstractRepository
pkgs = group_packages(g)
next if pkgs.empty?
name = g.at_xpath('name').text
- grps[name] = {
+ id = g.at_xpath('id').text
+ grps[id] = {
:name => name,
:repository_id => @id,
:packages => pkgs
@@ -45,18 +54,51 @@ class CompsRepository < AbstractRepository
}
end
+ categories = {}
+ category_nodes.each do |cat|
+ id = cat.at_xpath('id').text
+ categories[id] = {
+ :name => cat.at_xpath('name').text,
+ :groups => cat.xpath('./grouplist/groupid').map {|g| g.text}
+ }
+ end
+
Dir.mkdir(@cache_dir) unless File.directory?(@cache_dir)
- Marshal.dump(grps, File.open(@cache_file, 'w'))
+ Marshal.dump({:groups => grps,
+ :categories => categories}, File.open(@cache_file, 'w'))
end
private
+ def load_data
+ unless @load_data
+ begin
+ @load_data = Marshal.load(File.open(@cache_file, 'r'))
+ rescue Errno::ENOENT
+ raise "failed to read cached packages info, run 'rake
dc:prepare_repos'"
+ end
+ end
+ @load_data
+ end
+
+ def parsed_group_xml
+ unless @xml
+ return nil unless data = group_xml
+ @xml = Nokogiri::XML(data)
+ end
+ @xml
+ end
+
def group_nodes
- return [] unless data = group_xml
- xml = Nokogiri::XML(data)
+ return [] unless xml = parsed_group_xml
xml.xpath('/comps/group')
end
+ def category_nodes
+ return [] unless xml = parsed_group_xml
+ xml.xpath('/comps/category')
+ end
+
def pkg_names
pkgs = {}
xml = Nokogiri::XML(primary_xml)
diff --git a/src/app/util/repository_manager/pulp_repository.rb
b/src/app/util/repository_manager/pulp_repository.rb
index a0ea005..051bc47 100644
--- a/src/app/util/repository_manager/pulp_repository.rb
+++ b/src/app/util/repository_manager/pulp_repository.rb
@@ -30,6 +30,8 @@ class PulpRepository < AbstractRepository
def initialize(conf)
super
@groups_url = File.join(strip_path(@baseurl), conf['packagegroups'])
+ @categories_url = File.join(strip_path(@baseurl),
conf['packagegroupcategories'])
+ @packages_url = File.join(strip_path(@baseurl), conf['packages'])
end
def groups
@@ -41,8 +43,8 @@ class PulpRepository < AbstractRepository
info['mandatory_package_names'].each {|p| pkgs[p] = {:type =>
'mandatory'}}
next if pkgs.empty?
name = info['name']
- groups[name] = {
- :name => name,
+ groups[info['id']] = {
+ :name => info['name'],
:description => info['description'].to_s,
:repository_id => @id,
:packages => pkgs,
@@ -51,6 +53,25 @@ class PulpRepository < AbstractRepository
return groups
end
+ def categories
+ categories = {}
+ WrappedRestClient.get(@categories_url, HTTP_OPTS).each do |id, info|
+ categories[info['id']] = {
+ :name => info['name'],
+ :groups => info['packagegroupids'],
+ }
+ end
+ return categories
+ end
+
+ def packages
+ packages = []
+ WrappedRestClient.get(@packages_url, HTTP_OPTS).each do |info|
+ packages << info['name']
+ end
+ return packages
+ end
+
private
def strip_path(url)
diff --git a/src/app/views/templates/_collections.haml
b/src/app/views/templates/_collections.haml
new file mode 100644
index 0000000..1b4604b
--- /dev/null
+++ b/src/app/views/templates/_collections.haml
@@ -0,0 +1,6 @@
+%ul.metagrouppackages
+ - @collections.keys.sort.each do |id|
+ %li
+ - selected = @collections[id][:selected] ? true : false
+ = check_box_tag 'groups[]', id, selected, {:disabled => selected, :id =>
"group_#{id}"}
+ = label_tag "group_#{id}", @collections[id][:name]
diff --git a/src/app/views/templates/_managed_content.haml
b/src/app/views/templates/_managed_content.haml
index 97c4046..0657ff1 100644
--- a/src/app/views/templates/_managed_content.haml
+++ b/src/app/views/templates/_managed_content.haml
@@ -9,10 +9,10 @@
No selected packages
- else
- repos = @repository_manager.repositories_hash
- - @selected_packages.each do |pkg|
+ - @selected_packages.sort.each do |pkg|
- pkg_group = @groups.keys.find {|g| @groups[g][:packages][pkg]}
%fieldset.clearfix
- = text_field_tag 'packages[]', pkg, :id =>
"selected_package_#{pkg}", :class => "alpha grid_7 packagename"
+ = text_field_tag 'packages[]', pkg, :id => "package_#{pkg}", :class
=> "alpha grid_7 packagename"
.grid_2= (pkg_group and repo =
rep...@groups[pkg_group][:repository_id]]) ? repo.name.to_s : ' '
.grid_5.omega
%button{:type => 'button', :disabled => 'disabled'} Config
diff --git a/src/app/views/templates/_metagroup_packages.haml
b/src/app/views/templates/_metagroup_packages.haml
new file mode 100644
index 0000000..f1a42ec
--- /dev/null
+++ b/src/app/views/templates/_metagroup_packages.haml
@@ -0,0 +1,8 @@
+%h4
+ = params[:package_search].blank? ? "#...@metagroup} Packages" : "Search
Results for '#{params[:package_search]}'"
+%ul.metagrouppackages
+ - @metagroup_packages.sort.each do |pkg|
+ %li
+ - selected = @packages.to_a.find {|p| p[:name] == pkg}
+ = check_box_tag 'packages[]', pkg, selected, {:disabled => selected, :id
=> "package_#{pkg}"}
+ = label_tag "package_#{pkg}", pkg
diff --git a/src/app/views/templates/content_selection.haml
b/src/app/views/templates/content_selection.haml
index 7fd2175..43ae9be 100644
--- a/src/app/views/templates/content_selection.haml
+++ b/src/app/views/templates/content_selection.haml
@@ -1,3 +1,17 @@
+:javascript
+ $(document).ready(function() {
+ var $metagrouppackages = $('#metagrouppackages');
+ $('input[name="show_metagroup"]').click(function(e) {
+ e.preventDefault();
+ var data = {
+ 'show_metagroup': e.currentTarget.value,
+ selected_packages:
$("input:hidden[name='selected_packages[]']").map(function() {return
$(this).val()}).get()
+ };
+ var url = '#{url_for :action => 'dispatch', :id => @id}';
+ $metagrouppackages.load(url, data);
+ });
+ });
+
.grid_16
%h3 Managed Content Selection
@@ -8,31 +22,26 @@
<input type="hidden" id="selected_package_#{p[:name]}"
name="selected_packages[]" value="#{p[:name]}" />
%fieldset.clearfix
.search.grid_4.alpha
- %input{:type => "search", :placeholder => "Search for package",
:disabled => "disabled"}
+ %input{:type => "search", :placeholder => "Search for package", :name
=> 'package_search'}
%button.action
.grid_8
%a.grid_4.omega Advanced Search
- %ul.softwaregroups
- - groups = @groups.keys.sort
- - unsorted = groups.delete('unsorted')
- - groups.push('unsorted') if params[:show_unsorted] and unsorted
- - groups.each do |group|
- - group_sel = @groups[group][:selected]
- - group_id = group.gsub(/\s/, '_')
+ %ul.metagroups{:class => 'actionsidebar', :style => 'float:left'}
+ %li
+ = submit_tag 'Collections', :name => 'show_metagroup', :class => 'icon'
+ %hr
+ - @metagroups.keys.sort.each do |cat|
%li
- = check_box_tag 'groups[]', group, group_sel, :id =>
"group_#{group_id}"
- %label.disclosure
- =group
- %ul{:class => "packages group_#{group_id}"}
- - pkgs = @groups[group][:packages]
- - pkgs.keys.sort.each do |pkg|
- - pkg_sel = pkgs[pkg][:selected] ? true : false
- - pkg_id = pkg.gsub(/\s/, '_')
- %li
- = check_box_tag 'packages[]', pkg, pkg_sel, :id =>
"package_#{pkg_id}"
- = label_tag "package_#{pkg_id}", pkg
- = link_to "Show unsorted packages", {:action => 'dispatch',
:add_software_form => true, :show_unsorted => true, 'tpl[id]' => @tpl.id}, {:id
=> 'switch_all_link'} unless params[:show_unsorted]
+ = submit_tag cat, :name => "show_metagroup", :class => 'icon'
+ #metagrouppackages
+ - if @collections
+ = render :partial => 'collections'
+ - else
+ - if @metagroup_packages.blank?
+ No group selected
+ - else
+ = render :partial => 'metagroup_packages'
%fieldset.clearfix
= submit_tag "Add Selected", :name => "add_selected", :class => "grid_2
alpha", :id => "do_add_software"
diff --git a/src/app/views/templates/new.haml b/src/app/views/templates/new.haml
index 2de44cb..152d7cc 100644
--- a/src/app/views/templates/new.haml
+++ b/src/app/views/templates/new.haml
@@ -11,7 +11,7 @@
'tpl[platform]': $("select[name='tpl[platform]']").val() || ''
}
var url = '#{url_for :action => 'content_selection', :embed => true, :id
=> @id}';
- $content_container.empty().show();
+ //$content_container.empty().show();
$sel_pkg_container.empty().show().addClass('loading');
$sel_pkg_container.load(url, data, function(){
$sel_pkg_container.removeClass('loading');
@@ -19,8 +19,11 @@
$('#do_add_software').click(function(e) {
e.preventDefault();
var url = '#{url_for :action => 'managed_content'}';
+ var new_pkgs = $("input:checked[name='packages[]']").map(function()
{return $(this).val()}).get();
+ var old_pkgs =
$("input:hidden[name='selected_packages[]']").map(function() {return
$(this).val()}).get();
var data = {
- 'selected_packages[]':
$("input:checked[name='packages[]']").map(function() {return
$(this).val()}).get(),
+ 'selected_packages[]': old_pkgs.concat(new_pkgs),
+ 'selected_groups[]':
$("input:checked[name='groups[]']").map(function() {return
$(this).val()}).get(),
'template_id' : '#[email protected]? ? nil : @id}'
};
$content_container.load(url, data, function(){
@@ -45,14 +48,19 @@
$submit.show();
});
});
- //select all packages in group
- $(".softwaregroups input[type='checkbox']").click(function() {
- if ($(this).attr("checked") === true) {
-
$(this).siblings("ul").find("input[type='checkbox']").attr("checked","checked");
- } else {
-
$(this).siblings("ul").find("input[type='checkbox']").removeAttr("checked");
+ //search
+ $("input[name='package_search']").keypress(function(event) {
+ if (event.keyCode == '13') {
+ event.preventDefault();
+ $("input[name=package_search] ~ button").click();
}
});
+ $("input[name=package_search] ~ button").click(function(event) {
+ event.preventDefault();
+ var data = { 'package_search':
$("input[name='package_search']").val() };
+ var url = '#{url_for :action => 'dispatch', :id => @id}';
+ $('#metagrouppackages').load(url, data);
+ });
//disclosure triangles
$(".packages").hide();
$groups.click(function() {
diff --git a/src/config/image_descriptor_package_metagroups.conf
b/src/config/image_descriptor_package_metagroups.conf
new file mode 100644
index 0000000..7218e5c
--- /dev/null
+++ b/src/config/image_descriptor_package_metagroups.conf
@@ -0,0 +1,20 @@
+admin-tools=base-system;system-tools,base-system;admin-tools,rpmfusion_free;hardware-support
+desktop-gnome=rpmfusion_free;gnome-desktop,desktops;gnome-desktop
+desktop-kde=desktops;kde-desktop,rpmfusion_free;kde-desktop
+desktop-xfce=desktops;xfce-desktop
+desktop-other=desktops;window-managers,desktops;sugar-desktop,desktops;lxde-desktop,desktops;moblin-desktop
+education=apps;education,development;electronic-lab
+fonts=base-system;fonts,base-system;legacy-fonts
+games=apps;games,rpmfusion_free;games,rpmfusion_nonfree;games
+graphics=apps;graphics
+internet=apps;text-internet,apps;graphical-internet,rpmfusion_free;internet
+legacy=base-system;legacy-software-support
+localization=base-system;input-methods,language-support;khmer-support,language-support;persian-support,language-support;georgian-support,language-support;malay-support,language-support;tonga-support,language-support;portuguese-support,language-support;japanese-support,language-support;hungarian-support,language-support;somali-support,language-support;punjabi-support,language-support;bhutanese-support,language-support;british-support,language-support;korean-support,language-support;lao-support,language-support;inuktitut-support,language-support;german-support,language-support;hindi-support,language-support;faeroese-support,language-support;swedish-support,language-support;tsonga-support,language-support;russian-support,language-support;serbian-support,language-support;latvian-support,language-support;samoan-support,language-support;sinhala-support,language-support;catalan-support,language-support;lithuanian-support,language-support;turkish-support,language-support;arabic-support,language-support;vietnamese-support,language-support;mongolian-support,language-support;tswana-support,language-support;irish-support,language-support;italian-support,language-support;slovak-support,language-support;slovenian-support,language-support;belarusian-support,language-support;northern-sotho-support,language-support;kannada-support,language-support;malayalam-support,language-support;swati-support,language-support;breton-support,language-support;romanian-support,language-support;greek-support,language-support;tagalog-support,language-support;zulu-support,language-support;tibetan-support,language-support;danish-support,language-support;afrikaans-support,language-support;southern-sotho-support,language-support;bosnian-support,language-support;brazilian-support,language-support;basque-support,language-support;welsh-support,language-support;thai-support,language-support;telugu-support,language-support;low-saxon-support,language-support;urdu-support,language-support;tamil-support,language-support;indonesian-support,language-support;gujarati-support,language-support;xhosa-support,language-support;chinese-support,language-support;czech-support,language-support;venda-support,language-support;bulgarian-support,language-support;albanian-support,language-support;galician-support,language-support;armenian-support,language-support;dutch-support,language-support;oriya-support,language-support;maori-support,language-support;nepali-support,language-support;icelandic-support,language-support;ukrainian-support,language-support;assamese-support,language-support;bengali-support,language-support;spanish-support,language-support;hebrew-support,language-support;estonian-support,language-support;french-support,language-support;croatian-support,language-support;filipino-support,language-support;finnish-support,language-support;norwegian-support,language-support;southern-ndebele-support,language-support;polish-support,language-support;gaelic-support,language-support;marathi-support,language-support;ethiopic-support,language-support;esperanto-support,language-support;northern-sami-support,language-support;macedonian-support,language-support;walloon-support,language-support;kashubian-support,language-support;kashmiri-support,language-support;konkani-support,language-support;tajik-support,language-support;sindhi-support,language-support;uzbek-support,language-support;burmese-support,language-support;maithili-support,language-support;kazakh-support,language-support;azerbaijani-support,language-support;fijian-support,language-support;tetum-support,language-support;upper-sorbian-support,language-support;sanskrit-support,language-support;sardinian-support,language-support;swahili-support,language-support;maltese-support,language-support;friulian-support,language-support;latin-support,language-support;interlingua-support,language-support;occitan-support,language-support;hiligaynon-support,language-support;malagasy-support,language-support;amazigh-support,language-support;manx-support,language-support;turkmen-support,language-support;kinyarwanda-support,language-support;kurdish-support,language-support;coptic-support,language-support;luxembourgish-support,language-support;frisian-support,language-support;chichewa-support
+multimedia=apps;sound-and-video,rpmfusion_free;sound-and-video
+office=apps;office,apps;editors
+other=apps;engineering-and-scientific,rpmfusion_free;misc-libs,rpmfusion_nonfree;emulators
+programming=development;haskell,development;kde-software-development,development;gnome-software-development,development;development-tools,development;eclipse,development;development-libs,development;x-software-development,development;web-development,development;legacy-software-development,development;ruby,development;java-development,development;xfce-software-development,development;fedora-packager,development;mingw32,development;ocaml;development;perl;development;books
+publishing=apps;authoring-and-publishing,apps;font-design
+servers=servers;clustering,servers;dns-server,servers;server-cfg,servers;news-server,servers;web-server,servers;smb-server,servers;sql-server,servers;ftp-server,servers;printing,servers;mysql,servers;mail-server,servers;network-server,servers;legacy-network-server;servers;directory-server
+system=base-system;java,base-system;base-x,base-system;hardware-support,base-system;dial-up,base-system;base,rpmfusion_free;base,rpmfusion_free;system-tools,rpmfusion_nonfree;hardware-support,rpmfusion_nonfree;misc-tools,rpmfusion_nonfree;base
+virtualization=base-system;virtualization
--
1.7.2.3
_______________________________________________
deltacloud-devel mailing list
[email protected]
https://fedorahosted.org/mailman/listinfo/deltacloud-devel