diff --git a/lib/manifest_handler.rb b/lib/manifest_handler.rb index bb2e25b..eaeec64 100644 --- a/lib/manifest_handler.rb +++ b/lib/manifest_handler.rb @@ -1,169 +1,180 @@ # Copyright (C) 2011-2013 Cornelius Schumacher # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. class ManifestHandler attr_reader :manifests, :settings def initialize settings @settings = settings @libraries = Array.new @manifests = Array.new + + @topics_cache = Hash.new + @no_of_libraries_cache = Hash.new end def manifest_path manifest File.join(@settings.manifest_path, manifest.path) end def libraries maturity = nil if !maturity return @libraries else return @libraries.select do |l| manifest = l.latest_manifest manifest.maturity == maturity.to_s && manifest.licenses != [ "Commercial" ] end end end def unreleased_libraries return @libraries.select do |l| !l.latest_manifest.is_released? end end def commercial_libraries return @libraries.select do |l| manifest = l.latest_manifest manifest.licenses.include? "Commercial" end end def latest_libraries releases = Array.new is_kde_added = false libraries.select do |library| if library.latest_manifest.has_version? && library.latest_manifest.group != "kde-frameworks" releases.push library elsif library.latest_manifest.has_version? && library.latest_manifest.group == "kde-frameworks" if !is_kde_added is_kde_added = true releases.push library end end end releases.sort! {|a,b| a.latest_manifest.release_date <=> b.latest_manifest.release_date} releases.reverse! return releases[0 .. 4] end def group name return @libraries.select do |l| manifest = l.latest_manifest manifest.group == name end end def library name @libraries.each do |library| if library.name == name return library end end nil end def manifest name @libraries.each do |library| if library.name == name return library.latest_manifest end end raise InqludeError.new("Unable to find manifest '#{name}'") end def topic name - return @libraries.select do |l| - manifest = l.latest_manifest - if manifest.topics - manifest.topics.include? name + if !@topics_cache.has_key?(name) + @topics_cache[name] = @libraries.select do |l| + manifest = l.latest_manifest + if manifest.topics + manifest.topics.include? name + end end end + @topics_cache[name] end def no_of_libraries topic - count = 0 - @libraries.each do |l| - topics = l.latest_manifest.topics - if topics - if l.latest_manifest.topics.include? topic - count += 1 + if !@no_of_libraries_cache.has_key?(topic) + count = 0 + @libraries.each do |l| + topics = l.latest_manifest.topics + if topics + if l.latest_manifest.topics.include? topic + count += 1 + end end end + @no_of_libraries_cache[topic] = count end - count + @no_of_libraries_cache[topic] end def read_remote @libraries.clear @manifests.clear + @topics_cache.clear + @no_of_libraries_cache.clear if !@settings.offline fetch_remote end Dir.glob( "#{@settings.manifest_path}/*" ).sort.each do |dirname| next if !File.directory?( dirname ) library = Library.new library.name = File.basename dirname local_manifests = Array.new Dir.glob( "#{dirname}/*.manifest" ).sort.each do |filename| manifest = Manifest.parse_file filename local_manifests.push manifest manifests.push manifest end library.manifests = local_manifests libraries.push library end end def fetch_remote if File.exists? @settings.manifest_path if !File.exists? @settings.manifest_path + "/.git" raise "Can't fetch data into '#{@settings.manifest_path}' because it's not a git repository." else system "cd #{@settings.manifest_path}; git pull >/dev/null" end else system "git clone git://anongit.kde.org/websites/inqlude-data " + "#{@settings.manifest_path}" end end def generate_inqlude_all all = [] libraries.each do |l| all.push(l.latest_manifest.to_hash) end JSON.pretty_generate(all) end end diff --git a/lib/view.rb b/lib/view.rb index cc854ac..5198ec7 100644 --- a/lib/view.rb +++ b/lib/view.rb @@ -1,347 +1,347 @@ # Copyright (C) 2011 Cornelius Schumacher # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. class View attr_accessor :enable_disqus,:enable_search,:manifest,:library,:group_name,:templates attr_reader :root - + def initialize handler @manifest_handler = handler end def create output_dir assert_dir output_dir system "cp #{view_dir}/favicon.ico #{output_dir}" if templates == "two-column" system "cp #{view_dir}/ios.ico #{output_dir}" end - + assert_dir "#{output_dir}/public" system "cp #{view_dir}/public/* #{output_dir}/public/" - + assert_dir "#{output_dir}/schema" system "cp #{schema_dir}/* #{output_dir}/schema" create_inqlude_all(output_dir) @root = "" Dir.glob("#{view_dir}*.html.haml") do |file| template_name = (File.basename file).split(".").first if !["layout","group","library"].include? template_name render_template template_name, output_dir end end groups_path = "#{output_dir}/groups/" assert_dir groups_path - + @root = "../" - + @group_name = "kde-frameworks" file_name = "groups/kde-frameworks" render_template "group", output_dir, file_name - + library_path = "#{output_dir}/libraries/" assert_dir library_path @root = "../" @manifest_handler.libraries.each do |library| @library = library @manifest = library.latest_manifest file_name = "libraries/" + library.name render_template "library", output_dir, file_name end if templates == 'two-column' topics_path = "#{output_dir}/topics/" assert_dir topics_path @root = "../" topics.each do |topic| @topic = topic file_name = "topics/" + topic render_template "topic", output_dir, file_name end end end def create_inqlude_all(output_dir) File.open(File.join(output_dir, "inqlude-all.json"), "w") do |f| f.write(@manifest_handler.generate_inqlude_all) end end def template_directory_exists? File.directory?(view_dir) ? true : false end def render_template name, output_dir, file_name = nil layout = template "layout" layout_engine = Haml::Engine.new layout page = template name @content = Haml::Engine.new( page ).render( binding ) output_path = "" if file_name output_path = "#{output_dir}/#{file_name}.html" @file = file_name else output_path = "#{output_dir}/#{name}.html" @file = name end File.open output_path, "w" do |file| file.puts layout_engine.render( binding ) end end def yank @content end def style_sheet "" end def m @manifest end def t @topic end def link_to_manifest name "#{name}" end def link_to_library name, display_name "#{display_name}" end def link url "#{url}" end def link_to title, url if url !~ /^mailto:/ && url !~ /^http:/ && url !~ /^https:/ && url !~ /^ftp:/ url = "#{@root}#{url}.html" end "#{title}" end def link_to_group name, display_name "#{display_name}" end def link_to_topic name "#{name}" end def list_attribute attribute attr = @manifest.send(attribute) return "" if !attr || attr.size == 0 # We assume attribute is plural formed by adding an 's' label = attribute.capitalize entries = Array.new attr.each do |a| entries.push markup_email( a ) end if attr.size > 1 return list_attribute_content label, entries.join(", ") else return list_attribute_content label[0..-2], entries.first end end def list_attribute_content label, value out = "
" out += "
" + label + ":" + "
" out += "
" + value + "
" out += "
" out end def version_content if @manifest.class == ManifestGeneric raise InqludeError.new("Can't get version for generic manifest '#{@manifest.name}'") end out = @manifest.version out += " (#{@manifest.maturity})" out += "" out += "released on #{@manifest.release_date}" out += "" if !old_versions.empty? out += "" out += "(older versions: #{old_versions.join(", ")})" out += "" end out end def add_footer if @file == "index" text = 'Last updated on ' + Date.today.to_s else text = "" end out = "Inqlude is a " out += link_to "KDE project", "http://kde.org" out += "|" out += link_to "Legal", "http://www.kde.org/community/whatiskde/impressum.php" out += "" out += text out += "" out end - + def markup_email email if email =~ /(.*) <(.*)>/ name = $1 email = $2 - + return "#{name}" else return email end end def link_item key, label if m.urls.send(key) out = "
  • #{label}
  • " return out else return "" end end def custom_urls out = "" urls = @manifest.urls.custom if urls && !urls.empty? urls.each do |text,url| out += "
  • #{text}
  • " end end out end - + def libraries maturity = nil @manifest_handler.libraries(maturity) end - + def unreleased_libraries @manifest_handler.unreleased_libraries end def commercial_libraries @manifest_handler.commercial_libraries end def latest_libraries @manifest_handler.latest_libraries end def group_title if @group_name == "kde-frameworks" return "KDE Frameworks" end "" end - + def group @manifest_handler.group(@group_name) end def topic name @manifest_handler.topic(name) end def no_of_libraries topic @manifest_handler.no_of_libraries(topic) end - + def disqus_enabled? @enable_disqus end def more_urls? @manifest.urls.class.all_keys.each do |key, type| if key != :homepage && key != :screenshots && key != :logo && key != :description_source if @manifest.urls.send(key) return true end end end return false end - + def editor_url url = "https://github.com/cornelius/inqlude-data/blob/master/" url += @manifest.name url += "/#{@manifest.name}.#{@manifest.release_date}.manifest" url end def old_versions versions = @library.versions.reject{ |v| v == @manifest.version } versions.reverse end def render_description doc = Kramdown::Document.new(@manifest.description) doc.to_html end def topics ['API', 'Artwork', 'Bindings', 'Communication', 'Data', 'Desktop', 'Development', 'Graphics', 'Logging', 'Mobile', 'Multimedia', 'Printing', 'QML', 'Scripting', 'Security', 'Text', 'Web', 'Widgets'] end private - + def assert_dir name Dir::mkdir name unless File.exists? name - end - + end + def template name File.read( view_dir + "#{name}.html.haml" ) end def view_dir File.expand_path( File.dirname( __FILE__ ) + "/../view/#{templates}" ) + "/" end def schema_dir File.expand_path( File.dirname( __FILE__ ) + "/../schema/" ) + "/" end end diff --git a/spec/unit/manifest_handler_spec.rb b/spec/unit/manifest_handler_spec.rb index eca1603..9907f81 100644 --- a/spec/unit/manifest_handler_spec.rb +++ b/spec/unit/manifest_handler_spec.rb @@ -1,160 +1,180 @@ require File.expand_path('../spec_helper', __FILE__) include GivenFilesystemSpecHelpers describe ManifestHandler do let(:settings) do s = Settings.new s.manifest_path = File.expand_path('spec/data/manifests') s.offline = true s end let(:mh) do mh = ManifestHandler.new settings mh.read_remote mh end it "reads manifests" do expect(mh.manifests.count).to eq 5 expect(mh.libraries.count).to eq 5 mh.read_remote expect(mh.manifests.count).to eq 5 expect(mh.libraries.count).to eq 5 end it "provides access to manifests" do expect(mh.manifest("awesomelib")).to be_a Manifest expect { mh.manifest("nonexisting") }.to raise_error(InqludeError) end it "reads schema type" do expect(mh.manifest("awesomelib").class).to be ManifestRelease expect(mh.manifest("newlib").class).to be ManifestGeneric expect(mh.manifest("proprietarylib").class).to be ManifestProprietaryRelease end context "default manifest path" do before(:each) do @handler = ManifestHandler.new Settings.new end it "returns generic manifest path" do manifest = create_generic_manifest( "mylib" ) expect( @handler.manifest_path( manifest ) ).to eq( File.expand_path( "~/.local/share/inqlude/manifests/mylib/mylib.manifest" ) ) end it "returns release manifest path" do manifest = create_manifest( "mylib", "2014-02-01", "1.0" ) expect( @handler.manifest_path( manifest ) ).to eq( File.expand_path( "~/.local/share/inqlude/manifests/mylib/mylib.2014-02-01.manifest" ) ) end end describe "#libraries" do it "returns all libraries" do expect( mh.libraries.count ).to eq 5 end it "returns stable libraries" do libraries = mh.libraries :stable expect( libraries.count ).to eq 2 expect( libraries.first.manifests.last.name ).to eq "awesomelib" expect( libraries.first.manifests.last.version ).to eq "0.2.0" end it "returns development versions" do libraries = mh.libraries :edge expect( libraries.count ).to eq 1 expect( libraries.first.manifests.last.name ).to eq "bleedingedge" expect( libraries.first.manifests.last.version ).to eq "edge" end it "returns unreleased libraries" do libraries = mh.unreleased_libraries expect( libraries.count ).to eq 1 expect( libraries.first.manifests.last.name ).to eq "newlib" end it "returns commercial libraries" do libraries = mh.commercial_libraries expect( libraries.count ).to eq 3 expect( libraries.first.manifests.last.name ).to eq "awesomelib" expect( libraries[1].manifests.last.name ).to eq "commercial" end it "returns latest libraries" do libraries = mh.latest_libraries expect(libraries.first.manifests.last.name).to eq "proprietarylib" expect(libraries).not_to include "newlib" end end describe "#group" do it "returns all libraries of a group" do libraries = mh.group("kde-frameworks") expect( libraries.count ).to eq 2 expect( libraries.first.manifests.last.name ).to eq "awesomelib" end end describe "#topic" do it "returns all libraries of a topic" do libraries = mh.topic("API") expect( libraries.count ).to eq 2 expect( libraries.first.manifests.last.name ).to eq "awesomelib" end + + it "returns same results when called again" do + libraries = mh.topic("API") + expect( libraries.count ).to eq 2 + expect( libraries.first.manifests.last.name ).to eq "awesomelib" + + libraries2 = mh.topic("API") + expect(libraries2).to eq(libraries) + end + end + + describe "#no_of_libraries" do + it "returns number of libraries with given topic" do + expect(mh.no_of_libraries("API")).to eq(2) + end + + it "returns same result when called again" do + no = mh.no_of_libraries("API") + expect(mh.no_of_libraries("API")).to eq(no) + end end describe "#library" do it "returns one library" do library = mh.library "awesomelib" expect( library.name ).to eq "awesomelib" end end context "library with generic and release manifest" do use_given_filesystem before(:each) do @manifest_path = given_directory do given_directory "karchive" do given_file "karchive.manifest", :from => "karchive-generic.manifest" given_file "karchive.2014-02-01.manifest", :from => "karchive-release-beta.manifest" end end s = Settings.new s.manifest_path = @manifest_path s.offline = true @manifest_handler = ManifestHandler.new s @manifest_handler.read_remote end it "reads generic manifest" do expect( @manifest_handler.library("karchive").manifests.count ).to eq 2 generic_manifest = @manifest_handler.library("karchive").generic_manifest expect( generic_manifest.name ).to eq "karchive" expect( generic_manifest.class ).to be ManifestGeneric end it "lists development versions" do libraries = @manifest_handler.libraries :beta expect( libraries.count ).to eq 1 expect( libraries.first.latest_manifest.name ).to eq "karchive" expect( libraries.first.latest_manifest.version ).to eq "4.9.90" end it "lists unreleased libraries" do libraries = @manifest_handler.unreleased_libraries expect( libraries.count ).to eq 0 end end it "generates inqlude-all.json" do expected_json = File.read(test_data_path("inqlude-all.json")).chomp expect(mh.generate_inqlude_all).to eq expected_json end end