inqlude 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,66 @@
1
+ # Copyright (C) 2011 Cornelius Schumacher <schumacher@kde.org>
2
+ #
3
+ # This program is free software; you can redistribute it and/or modify
4
+ # it under the terms of the GNU General Public License as published by
5
+ # the Free Software Foundation; either version 2 of the License, or
6
+ # (at your option) any later version.
7
+ #
8
+ # This program is distributed in the hope that it will be useful,
9
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
+ # GNU General Public License for more details.
12
+ #
13
+ # You should have received a copy of the GNU General Public License along
14
+ # with this program; if not, write to the Free Software Foundation, Inc.,
15
+ # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
16
+
17
+ class Suse
18
+
19
+ attr_accessor :name, :version
20
+
21
+ def is_it_me?
22
+ begin
23
+ File.open "/etc/SuSE-release" do |file|
24
+ if file.readline =~ /^openSUSE/
25
+ @name = "openSUSE"
26
+ file.readline =~ /VERSION = (.*)/
27
+ @version = $1
28
+ end
29
+ end
30
+
31
+ true
32
+ rescue Errno::ENOENT
33
+ false
34
+ end
35
+ end
36
+
37
+ def installed handler
38
+ packages = Hash.new
39
+
40
+ `rpmqpack`.each_line do |package|
41
+ packages[package.chomp] = true
42
+ end
43
+
44
+ unknown = 0
45
+
46
+ installed = Array.new
47
+ handler.manifests.each do |manifest|
48
+ unknown += 1
49
+ package_section = manifest["packages"]
50
+ next unless package_section
51
+ name_section = package_section[name]
52
+ next unless name_section
53
+ version_section = name_section[version]
54
+ next unless version_section
55
+ if packages.has_key? version_section["package_name"]
56
+ installed.push manifest
57
+ unknown -= 1
58
+ end
59
+ end
60
+
61
+ STDERR.puts "Warning: #{unknown} libraries don't have package information"
62
+
63
+ installed
64
+ end
65
+
66
+ end
data/lib/inqlude.rb ADDED
@@ -0,0 +1,12 @@
1
+ require "rubygems"
2
+
3
+ require "thor"
4
+ require "json"
5
+
6
+ require File.expand_path('../version', __FILE__)
7
+ require File.expand_path('../cli', __FILE__)
8
+ require File.expand_path('../manifest_handler', __FILE__)
9
+ require File.expand_path('../view', __FILE__)
10
+ require File.expand_path('../distro', __FILE__)
11
+ require File.expand_path('../rpm_manifestizer', __FILE__)
12
+ require File.expand_path('../settings', __FILE__)
@@ -0,0 +1,35 @@
1
+ # Copyright (C) 2011 Cornelius Schumacher <schumacher@kde.org>
2
+ #
3
+ # This program is free software; you can redistribute it and/or modify
4
+ # it under the terms of the GNU General Public License as published by
5
+ # the Free Software Foundation; either version 2 of the License, or
6
+ # (at your option) any later version.
7
+ #
8
+ # This program is distributed in the hope that it will be useful,
9
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
+ # GNU General Public License for more details.
12
+ #
13
+ # You should have received a copy of the GNU General Public License along
14
+ # with this program; if not, write to the Free Software Foundation, Inc.,
15
+ # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
16
+
17
+ class ManifestHandler
18
+
19
+ attr_reader :manifests
20
+
21
+ def initialize settings
22
+ @settings = settings
23
+
24
+ @manifests = Array.new
25
+ end
26
+
27
+ def read_remote
28
+ Dir.glob( "#{@settings.manifest_dir}/*.manifest" ).sort.each do |filename|
29
+ File.open filename do |file|
30
+ manifests.push JSON file.read
31
+ end
32
+ end
33
+ end
34
+
35
+ end
@@ -0,0 +1,230 @@
1
+ # Copyright (C) 2011 Cornelius Schumacher <schumacher@kde.org>
2
+ #
3
+ # This program is free software; you can redistribute it and/or modify
4
+ # it under the terms of the GNU General Public License as published by
5
+ # the Free Software Foundation; either version 2 of the License, or
6
+ # (at your option) any later version.
7
+ #
8
+ # This program is distributed in the hope that it will be useful,
9
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
+ # GNU General Public License for more details.
12
+ #
13
+ # You should have received a copy of the GNU General Public License along
14
+ # with this program; if not, write to the Free Software Foundation, Inc.,
15
+ # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
16
+
17
+ class RpmManifestizer
18
+
19
+ attr_accessor :dry_run
20
+
21
+ def initialize settings
22
+ @settings = settings
23
+
24
+ @cut_off_exceptions = [ "qt4-x11" ]
25
+ @source_rpms = Hash.new
26
+ end
27
+
28
+ def create_manifest name, rpm_name
29
+ filename = "#{@settings.manifest_dir}/#{name}.manifest"
30
+ File.open( filename, "w") do |f2|
31
+ source_rpm = `rpm -q --queryformat '%{SOURCERPM}' #{rpm_name}`
32
+ @source_rpms[source_rpm] = Array.new
33
+
34
+ raw = `rpm -q --queryformat '%{DESCRIPTION}' #{rpm_name}`
35
+ parse_authors = false
36
+ description = ""
37
+ authors = Array.new
38
+ raw.each_line do |line3|
39
+ if line3 =~ /^Authors:/
40
+ parse_authors = true
41
+ next
42
+ end
43
+ if parse_authors
44
+ if line3 =~ /^---/
45
+ next
46
+ end
47
+ authors.push "\"#{line3.strip}\""
48
+ else
49
+ description += line3.chomp + "\\n"
50
+ end
51
+ end
52
+ description.gsub! /"/, "\\\""
53
+ description.strip!
54
+
55
+ qf = ' "version": "%{VERSION}",\n'
56
+ qf += ' "summary": "%{SUMMARY}",\n'
57
+ qf += ' "homepage": "%{URL}",\n'
58
+ qf += ' "license": "%{LICENSE}",\n'
59
+ header = `rpm -q --queryformat '#{qf}' #{rpm_name}`
60
+
61
+ f2.puts '{';
62
+ f2.puts ' "schema_version": 1,'
63
+ f2.puts " \"name\": \"#{name}\","
64
+ f2.puts header
65
+ f2.puts " \"description\": \"#{description}\","
66
+ f2.puts ' "authors": [' + authors.join(",") + '],'
67
+ f2.puts ' "maturity": "stable",'
68
+ f2.puts ' "packages": {'
69
+ f2.puts ' "openSUSE": {'
70
+ f2.puts ' "11.4": {'
71
+ f2.puts " \"package_name\": \"#{rpm_name}\","
72
+ f2.puts ' "repository": {'
73
+ f2.puts ' "url": "http://download.opensuse.org/distribution/11.4/repo/oss/",'
74
+ f2.puts ' "name": "openSUSE-11.4-Oss"'
75
+ f2.puts ' },'
76
+ f2.puts " \"source_rpm\": \"#{source_rpm}\""
77
+ f2.puts ' }'
78
+ f2.puts ' }'
79
+ f2.puts ' }'
80
+ f2.puts '}'
81
+ end
82
+ end
83
+
84
+ def requires_qt? rpm_name
85
+ IO.popen "rpm -q --requires #{rpm_name}" do |f2|
86
+ while line2 = f2.gets do
87
+ if line2 =~ /Qt/
88
+ return true
89
+ end
90
+ end
91
+ end
92
+ false
93
+ end
94
+
95
+ def is_library? rpm_name
96
+ rpm_name =~ /^lib/
97
+ end
98
+
99
+ def is_32bit? rpm_name
100
+ rpm_name =~ /\-32bit/
101
+ end
102
+
103
+ def cut_off_number_suffix name
104
+ if @cut_off_exceptions.include? name
105
+ return name
106
+ end
107
+
108
+ i = name.length - 1
109
+ while i > 0
110
+ if name[i].chr !~ /[\-_0-9]/
111
+ break
112
+ end
113
+ i -= 1
114
+ end
115
+ if i > 0
116
+ return name[0..i]
117
+ end
118
+ name
119
+ end
120
+
121
+ def process_all_rpms
122
+ if !File.exist? @settings.cache_dir + "/qt_source.json"
123
+ create_qt_source_cache
124
+ end
125
+
126
+ qt_sources = Hash.new
127
+ File.open @settings.cache_dir + "/qt_source.json" do |file|
128
+ qt_sources = JSON file.read
129
+ end
130
+
131
+ qt_sources.each do |source,sections|
132
+ sections["all"].each do |rpm|
133
+ if rpm =~ /(.*)-devel$/
134
+ name = $1
135
+
136
+ if name =~ /^lib(.*)/
137
+ name = $1
138
+ end
139
+
140
+ lib_rpm = ""
141
+ sections["lib"].each do |lib|
142
+ if lib !~ /\-devel$/
143
+ lib_rpm = lib
144
+ break
145
+ end
146
+ end
147
+ if lib_rpm.empty?
148
+ lib_rpm = rpm
149
+ end
150
+
151
+ puts "Identified manifest: #{name} (Library RPM: #{lib_rpm})"
152
+
153
+ if !dry_run
154
+ create_manifest name, lib_rpm
155
+ end
156
+ end
157
+ end
158
+ end
159
+ end
160
+
161
+ def read_source_cache
162
+ if !File.exist? @settings.cache_dir + "/source.json"
163
+ create_source_cache
164
+ end
165
+
166
+ sources = Hash.new
167
+ File.open @settings.cache_dir + "/source.json" do |file|
168
+ sources = JSON file.read
169
+ end
170
+
171
+ sources
172
+ end
173
+
174
+ def create_source_cache
175
+ puts "Creating cache of RPM meta data"
176
+ get_involved "Create more friendly progress display for cache creation"
177
+ sources = Hash.new
178
+ IO.popen "rpmqpack" do |f|
179
+ while line = f.gets do
180
+ rpm_name = line.chomp
181
+ puts "SCAN #{rpm_name}"
182
+ source_rpm = `rpm -q --queryformat '%{SOURCERPM}' #{rpm_name}`
183
+ sources[rpm_name] = source_rpm
184
+ end
185
+ end
186
+
187
+ File.open @settings.cache_dir + "/source.json", "w" do |f|
188
+ f.puts sources.to_json
189
+ end
190
+ end
191
+
192
+ def create_qt_source_cache
193
+ puts "Creating cache of Qt library RPMs"
194
+
195
+ sources = read_source_cache
196
+
197
+ rpms = Hash.new
198
+ sources.each do |rpm,source|
199
+ if rpms.has_key? source
200
+ rpms[source] = rpms[source].push rpm
201
+ else
202
+ rpms[source] = Array.new.push rpm
203
+ end
204
+ end
205
+
206
+ qt_sources = Hash.new
207
+ sources.each do |rpm,source|
208
+ next unless requires_qt? rpm
209
+ next unless is_library? rpm
210
+ next if is_32bit? rpm
211
+
212
+ if !qt_sources.has_key? source
213
+ sections = Hash.new
214
+ sections[:all] = Array.new
215
+ sections[:lib] = Array.new
216
+ qt_sources[source] = sections
217
+ end
218
+
219
+ qt_sources[source][:all] = rpms[source]
220
+ qt_sources[source][:lib] = qt_sources[source][:lib].push rpm
221
+
222
+ puts "Found RPM #{rpm} (#{source})"
223
+ end
224
+
225
+ File.open @settings.cache_dir + "/qt_source.json", "w" do |f|
226
+ f.puts JSON.pretty_generate qt_sources
227
+ end
228
+ end
229
+
230
+ end
data/lib/settings.rb ADDED
@@ -0,0 +1,41 @@
1
+ # Copyright (C) 2011 Cornelius Schumacher <schumacher@kde.org>
2
+ #
3
+ # This program is free software; you can redistribute it and/or modify
4
+ # it under the terms of the GNU General Public License as published by
5
+ # the Free Software Foundation; either version 2 of the License, or
6
+ # (at your option) any later version.
7
+ #
8
+ # This program is distributed in the hope that it will be useful,
9
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
+ # GNU General Public License for more details.
12
+ #
13
+ # You should have received a copy of the GNU General Public License along
14
+ # with this program; if not, write to the Free Software Foundation, Inc.,
15
+ # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
16
+
17
+ class Settings
18
+
19
+ def manifest_dir
20
+ local_dir "manifests"
21
+ end
22
+
23
+ def cache_dir
24
+ local_dir "cache"
25
+ end
26
+
27
+ def version
28
+ Inqlude::VERSION
29
+ end
30
+
31
+ private
32
+
33
+ def local_dir dirname
34
+ home = ENV["HOME"] + "/.inqlude/"
35
+ Dir::mkdir home unless File.exists? home
36
+ path = home + dirname
37
+ Dir::mkdir path unless File.exists? path
38
+ path
39
+ end
40
+
41
+ end
data/lib/version.rb ADDED
@@ -0,0 +1,5 @@
1
+ module Inqlude
2
+
3
+ VERSION = "0.0.2"
4
+
5
+ end
data/lib/view.rb ADDED
@@ -0,0 +1,93 @@
1
+ # Copyright (C) 2011 Cornelius Schumacher <schumacher@kde.org>
2
+ #
3
+ # This program is free software; you can redistribute it and/or modify
4
+ # it under the terms of the GNU General Public License as published by
5
+ # the Free Software Foundation; either version 2 of the License, or
6
+ # (at your option) any later version.
7
+ #
8
+ # This program is distributed in the hope that it will be useful,
9
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
+ # GNU General Public License for more details.
12
+ #
13
+ # You should have received a copy of the GNU General Public License along
14
+ # with this program; if not, write to the Free Software Foundation, Inc.,
15
+ # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
16
+
17
+ require "rubygems"
18
+
19
+ require "haml"
20
+
21
+ class View
22
+
23
+ attr_accessor :enable_disqus
24
+
25
+ def initialize handler
26
+ @manifest_handler = handler
27
+ end
28
+
29
+ def create output_dir
30
+ assert_dir output_dir
31
+
32
+ assert_dir "#{output_dir}/public"
33
+ system "cp #{view_dir}/public/* #{output_dir}/public/"
34
+
35
+ index = template "index"
36
+ engine = Haml::Engine.new index
37
+
38
+ File.open "#{output_dir}/index.html", "w" do |file|
39
+ file.puts engine.render( binding )
40
+ end
41
+
42
+ library_path = "#{output_dir}/libraries/"
43
+ assert_dir library_path
44
+
45
+ engine = Haml::Engine.new template "library"
46
+
47
+ manifests.each do |manifest|
48
+ File.open library_path + manifest["name"] + ".html", "w" do |file|
49
+ @manifest = manifest
50
+ file.puts engine.render( binding )
51
+ end
52
+ end
53
+
54
+ end
55
+
56
+ def m attr
57
+ @manifest[ attr ]
58
+ end
59
+
60
+ def link_to_manifest name
61
+ "<a href=\"libraries/#{name}.html\">#{name}</a>"
62
+ end
63
+
64
+ def link url
65
+ "<a href=\"#{url}\" target=\"_blank\">#{url}</a>"
66
+ end
67
+
68
+ def manifests
69
+ if @manifest_handler.manifests.empty?
70
+ @manifest_handler.read_remote
71
+ end
72
+ @manifest_handler.manifests
73
+ end
74
+
75
+ def disqus_enabled?
76
+ @enable_disqus
77
+ end
78
+
79
+ private
80
+
81
+ def assert_dir name
82
+ Dir::mkdir name unless File.exists? name
83
+ end
84
+
85
+ def template name
86
+ File.read( view_dir + "#{name}.html.haml" )
87
+ end
88
+
89
+ def view_dir
90
+ File.expand_path( File.dirname( __FILE__ ) + "/../view/" ) + "/"
91
+ end
92
+
93
+ end
@@ -0,0 +1,11 @@
1
+ require File.expand_path('../test_helper', __FILE__)
2
+
3
+ class RpmManifestizerTest < Test::Unit::TestCase
4
+
5
+ def test_is_library
6
+ m = RpmManifestizer.new Settings.new
7
+ assert m.is_library?( "libjson" )
8
+ assert !m.is_library?( "kontact" )
9
+ end
10
+
11
+ end
@@ -0,0 +1,3 @@
1
+ require File.expand_path('../../lib/inqlude',__FILE__)
2
+
3
+ require 'test/unit'
@@ -0,0 +1,26 @@
1
+ %head
2
+ %link{ :rel => "stylesheet", :type => "text/css",
3
+ :href => "public/inqlude.css" }
4
+ <link href='http://fonts.googleapis.com/css?family=Droid+Sans' rel='stylesheet' type='text/css'>
5
+ %body
6
+ .header.center
7
+ %h1
8
+ %span.logo><
9
+ \#in
10
+ %span.logo.green><
11
+ q
12
+ %span.logo><
13
+ lude
14
+ %span.subtitle
15
+ The Qt library archive
16
+
17
+ .menu.center
18
+
19
+ .content.center
20
+ %table
21
+ - manifests.each do |manifest|
22
+ %tr
23
+ %td.first
24
+ = link_to_manifest manifest["name"]
25
+ %td.last
26
+ = manifest["summary"]
@@ -0,0 +1,53 @@
1
+ %head
2
+ %link{ :rel => "stylesheet", :type => "text/css",
3
+ :href => "../public/inqlude.css" }
4
+
5
+ %body
6
+ .header.center
7
+ %h1
8
+ %span.logo><
9
+ \#in
10
+ %span.logo.green><
11
+ q
12
+ %span.logo><
13
+ lude
14
+ %span.subtitle
15
+ The Qt library archive
16
+
17
+ .menu.center
18
+
19
+ .content.center
20
+ %h2
21
+ = m "name"
22
+
23
+ %p
24
+ %em
25
+ Version
26
+ = m "version"
27
+
28
+ %p
29
+ = m "summary"
30
+
31
+ %p
32
+ = m "description"
33
+
34
+ %p
35
+ = link m( "homepage" )
36
+
37
+ - if disqus_enabled?
38
+ %hr
39
+
40
+ #disqus_thread
41
+
42
+ :javascript
43
+ var disqus_shortname = 'inqlude';
44
+
45
+ var disqus_identifier = '#{m "name"}';
46
+ var disqus_url = 'http://inqlude.org/libraries/#{m "name"}.html';
47
+
48
+ /* * * DON'T EDIT BELOW THIS LINE * * */
49
+ (function() {
50
+ var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
51
+ dsq.src = 'http://' + disqus_shortname + '.disqus.com/embed.js';
52
+ (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
53
+ })();
@@ -0,0 +1,60 @@
1
+ body {
2
+ background-color: yellowgreen;
3
+ margin: 0px;
4
+ font-family: 'Droid Sans', arial, serif;
5
+ }
6
+
7
+ .center {
8
+ margin-left: auto;
9
+ margin-right: auto;
10
+ }
11
+
12
+ h1 {
13
+ text-align: center;
14
+ font-family: monospace;
15
+ font-size: 200%;
16
+ font-weight: normal;
17
+ margin-top: 0px;
18
+ margin-bottom: 0px;
19
+ }
20
+
21
+ h1 .logo {
22
+ font-size: 200%;
23
+ font-weight: bold;
24
+ }
25
+
26
+ h1 .green {
27
+ color: green;
28
+ }
29
+
30
+
31
+ h1 .subtitle {
32
+ padding-left: 12px;
33
+ }
34
+
35
+ .header {
36
+ width: 80%;
37
+ background-color: white;
38
+ padding: 10px;
39
+ }
40
+
41
+ .menu {
42
+ width: 85%;
43
+ height: 20px;
44
+ background-color: green;
45
+ }
46
+
47
+ .content {
48
+ width: 80%;
49
+ background-color: white;
50
+ padding: 10px;
51
+ }
52
+
53
+ table {
54
+ margin: auto;
55
+ }
56
+
57
+ td {
58
+ vertical-align: top;
59
+ padding-left: 16px;
60
+ }