Skip to content

Commit 944febe

Browse files
author
Ilja Bobkevic
committed
Merge pull request #34 from jlyheden/feature/module-info
Added detailed module view in frontend
2 parents bf8c104 + fd66ac3 commit 944febe

File tree

14 files changed

+404
-13
lines changed

14 files changed

+404
-13
lines changed

lib/puppet_forge_server.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ module Utils
6060
autoload :OptionParser, 'puppet_forge_server/utils/option_parser'
6161
autoload :Buffer, 'puppet_forge_server/utils/buffer'
6262
autoload :Http, 'puppet_forge_server/utils/http'
63+
autoload :MarkdownRenderer, 'puppet_forge_server/utils/md_renderer'
6364
end
6465

6566
module Http

lib/puppet_forge_server/api/v3/releases.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@ def get_releases(metadata)
3232
:tags => element.tags ? element.tags : [element.metadata.author, name],
3333
:file_uri => "/v3/files#{element.path}",
3434
:file_md5 => element.checksum,
35-
:deleted_at => element.deleted_at
35+
:deleted_at => element.deleted_at,
36+
:readme => element.readme
3637
}
3738
end.uniq{|r| r[:version]}.sort_by { |r| Gem::Version.new(r[:version]) }
3839
end

lib/puppet_forge_server/app/frontend.rb

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,11 @@
1717
require 'sinatra/base'
1818
require 'haml'
1919
require 'json'
20+
require 'tilt/haml'
2021

2122
module PuppetForgeServer::App
2223
class Frontend < Sinatra::Base
24+
include PuppetForgeServer::Utils::MarkdownRenderer
2325

2426
configure do
2527
set :haml, :format => :html5
@@ -47,6 +49,23 @@ def initialize(root, http_client = PuppetForgeServer::Http::HttpClient.new)
4749
haml :modules, :locals => {:query => query, :modules => modules}
4850
end
4951

52+
get '/module' do
53+
module_v3_name = params[:name].gsub(/\//, '-')
54+
releases = get("#{request.base_url}/v3/modules/#{module_v3_name}")['releases']
55+
if params.has_key? 'version'
56+
module_uri = releases.find {|r| r['version'] == params['version']}['uri']
57+
module_metadata = get("#{request.base_url}#{module_uri}")
58+
else
59+
module_metadata = get("#{request.base_url}#{releases[0]['uri']}")
60+
end
61+
begin
62+
readme_markdown = markdown(module_metadata['readme'])
63+
rescue
64+
readme_markdown = ''
65+
end
66+
haml :module, :locals => { :module_metadata => module_metadata, :base_url => request.base_url, :readme_markdown => readme_markdown, :releases => releases }
67+
end
68+
5069
get '/upload' do
5170
haml :upload, :locals => {:upload_status => ''}
5271
end

lib/puppet_forge_server/app/public/css/puppetlabs.css

Lines changed: 235 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,214 @@ h3.search-results-title {
215215
margin: 0;
216216
border-bottom: solid 1px #cccccc;
217217
}
218+
.module-header {
219+
position: relative;
220+
float: left;
221+
width: 90%;
222+
min-height: 77px;
223+
padding: 1em;
224+
background-color: #f4f4f4;
225+
}
226+
.module-header.supported {
227+
background-image: url("/assets/41dfc34/images/supported-tag-upper-right.png");
228+
background-repeat: no-repeat;
229+
background-position: top right;
230+
}
231+
.module-header.approved {
232+
background-image: url("/assets/41dfc34/images/approved-tag-upper-right.png");
233+
background-repeat: no-repeat;
234+
background-position: top right;
235+
}
236+
.module-header .author,
237+
.module-header .tag-section {
238+
padding-top: 0.25em;
239+
}
240+
.module-header .popular {
241+
display: inline;
242+
margin-left: 0;
243+
}
244+
.module-header .tags {
245+
display: inline;
246+
margin-left: 0;
247+
}
248+
.module-header .endorsement-trigger {
249+
position: absolute;
250+
top: 0;
251+
right: 0;
252+
width: 77px;
253+
height: 77px;
254+
}
255+
.module-header .details {
256+
font-size: 0.95em;
257+
}
258+
.module-header .details table {
259+
width: 100%;
260+
position: relative;
261+
}
262+
.module-header .details .gravatar {
263+
float: left;
264+
width: 77px;
265+
}
266+
.module-header .details .gravatar .avatar {
267+
margin: 0;
268+
padding: 0;
269+
}
270+
.module-header .details .module-info-basic {
271+
margin-left: 93px;
272+
/* width of gravatar (77) + 1em (16) */
273+
}
274+
.module-header .details .module-info-basic .module-info-header {
275+
margin: 0;
276+
padding-right: 45px;
277+
}
278+
.module-header .details .module-info-basic .module-info-header a:hover {
279+
text-decoration: underline;
280+
}
281+
.module-header .details .module-info-basic .module-info-header h2 {
282+
display: inline-block;
283+
margin: 0 10px 0 0;
284+
line-height: 1.1rem;
285+
}
286+
@media (max-width: 1150px) {
287+
.module-header .details .module-info-basic .module-info-header h2 .namespace {
288+
display: none;
289+
}
290+
}
291+
.module-header .details .module-info-basic .module-info-header .module-info-author {
292+
display: inline-block;
293+
margin-right: 15px;
294+
font-size: 12px;
295+
white-space: nowrap;
296+
}
297+
.module-header .details .module-info-basic .module-info-header .module-links {
298+
display: inline-block;
299+
font-size: 12px;
300+
}
301+
.module-header .details .module-info-basic .module-info-header .module-links li {
302+
display: inline-block;
303+
margin-bottom: 0;
304+
margin-right: 15px;
305+
}
306+
.module-header .details .module-info-basic > div {
307+
padding-bottom: 0.35em;
308+
}
309+
.module-header .details .module-info-basic ul {
310+
margin: 0;
311+
list-style-type: none;
312+
}
313+
.module-header .details .module-info-basic ul.release-os-compat li {
314+
display: inline;
315+
margin-right: 5px;
316+
}
317+
.module-header .details .module-info-basic ul.release-os-compat span[data-releases] {
318+
border-bottom: 1px dotted;
319+
cursor: default;
320+
}
321+
.module-header .details .module-info-basic .module-info-summary {
322+
margin-bottom: 1em;
323+
}
324+
.module-header .details .module-info-basic .module-info-tags {
325+
font-size: 0.85em;
326+
margin-top: 1.75em;
327+
width: 85%;
328+
}
329+
.module-header .details .module-info-basic .compatibility {
330+
background-color: #ffffff;
331+
padding: 0.5em;
332+
margin-top: 0.25em;
333+
}
334+
.module-header .details .module-info-basic .compatibility ul.bullets {
335+
list-style-type: disc;
336+
margin-left: 1.5em;
337+
}
338+
.module-header .details .module-info-basic .compatibility ul.bullets li {
339+
margin-bottom: 0;
340+
padding-bottom: 0;
341+
}
342+
.module-header .download-info {
343+
padding-top: 1em;
344+
margin-top: 1em;
345+
border-top: 1px #ccc solid;
346+
}
347+
.module-header .download-info > div {
348+
-moz-box-sizing: border-box;
349+
box-sizing: border-box;
350+
}
351+
.module-header .download-info .installation {
352+
float: left;
353+
width: 75%;
354+
}
355+
.module-header .download-info .installation small {
356+
display: block;
357+
float: left;
358+
width: 50%;
359+
font-size: 11px;
360+
}
361+
.module-header .download-info .installation small.download-link {
362+
text-align: right;
363+
font-weight: bold;
364+
}
365+
.module-header .download-info .download-counts {
366+
float: left;
367+
width: 25%;
368+
padding-top: 36px;
369+
padding-right: 5%;
370+
text-align: right;
371+
font-size: 1.1em;
372+
line-height: 1em;
373+
font-weight: bold;
374+
}
375+
.module-header .download-info .download-counts small {
376+
font-size: 11px;
377+
font-weight: normal;
378+
color: #6c6d6d;
379+
}
380+
.module-header .download-info .pe-only {
381+
padding-left: 93px;
382+
}
383+
.module-header .download-info .pe-only input[type=text] {
384+
box-sizing: border-box;
385+
max-width: none;
386+
width: 100%;
387+
}
388+
.module-header .download-info .pe-only p {
389+
margin-bottom: 0.5em;
390+
}
391+
.module-header-sidebar {
392+
float: right;
393+
width: 22%;
394+
}
395+
.module-meta-info ul.release-dependencies {
396+
margin-top: 1.25em;
397+
}
398+
#module-release-header {
399+
overflow: auto;
400+
margin-top: 20px;
401+
margin-bottom: 10px;
402+
}
403+
#module-release-header #module-release-title {
404+
float: left;
405+
font-size: 1.2em;
406+
}
407+
#module-release-header #module-release-switcher {
408+
float: right;
409+
padding-top: 3px;
410+
text-align: right;
411+
font-size: 13px;
412+
}
413+
#module-release-header #module-release-switcher label {
414+
display: inline-block;
415+
font-weight: normal;
416+
}
417+
#module-release-header #module-release-switcher a {
418+
display: inline-block;
419+
margin-left: 6px;
420+
padding: 3px 9px;
421+
min-width: 60px;
422+
border-radius: 4px;
423+
background-color: #f4f4f4;
424+
text-align: center;
425+
}
218426
ul, ol, dl {
219427
margin-bottom: 1.5em;
220428
margin-left: 0;
@@ -249,6 +457,11 @@ li.private {
249457
background-repeat: no-repeat;
250458
background-position: right top;
251459
}
460+
section.private {
461+
background-image: url("/img/endorsement-private.png");
462+
background-repeat: no-repeat;
463+
background-position: right top;
464+
}
252465
p {
253466
margin: 0;
254467
}
@@ -277,3 +490,25 @@ a.module-link {
277490
color: #0095dd;
278491
font-size: 0.9em;
279492
}
493+
.installation input.paste-code {
494+
display: block;
495+
-moz-box-sizing: border-box;
496+
box-sizing: border-box;
497+
margin-top: 0.5em;
498+
margin-bottom: 3px;
499+
width: 100%;
500+
max-width: none;
501+
padding: 0.75em;
502+
border: 0;
503+
background: #e5e5e5;
504+
color: #5d5e59;
505+
font-family: Monaco, "Liberation Mono", Courier, monospace;
506+
}
507+
pre {
508+
border-radius: .25em;
509+
background: #f5f2f0;
510+
border: 1px solid #DDD;
511+
padding: .5em 1em;
512+
overflow: auto;
513+
display: block;
514+
}

lib/puppet_forge_server/app/views/layout.haml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,4 +61,4 @@
6161
.side-width.clearfix
6262
= yield
6363
%script{ :src => 'https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/js/bootstrap.min.js' }
64-
%script{ :src => 'js/internal.js' }
64+
%script{ :src => 'js/internal.js' }
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
-# -*- encoding: utf-8 -*-
2+
-#
3+
-# Copyright 2015 North Development AB
4+
-#
5+
-# Licensed under the Apache License, Version 2.0 (the "License");
6+
-# you may not use this file except in compliance with the License.
7+
-# You may obtain a copy of the License at
8+
-#
9+
-# http://www.apache.org/licenses/LICENSE-2.0
10+
-#
11+
-# Unless required by applicable law or agreed to in writing, software
12+
-# distributed under the License is distributed on an "AS IS" BASIS,
13+
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
-# See the License for the specific language governing permissions and
15+
-# limitations under the License.
16+
17+
- if !module_metadata.has_key? 'metadata'
18+
%section{:id => 'content'}
19+
%div{:class => 'site-width clearfix'}
20+
%section{:id => 'body', :class => ' '}
21+
No such module
22+
- else
23+
%section{:id => 'content'}
24+
%div{:class => 'site-width clearfix'}
25+
%section{:id => 'body', :class => ' '}
26+
%div{:class => 'module-header-container clearfix'}
27+
%section{:class => module_metadata['private'] ? 'module-header private' : 'module-header'}
28+
%section{:class => 'details clearfix'}
29+
%div{:class => 'module-info-basic'}
30+
%div{:class => 'module-info-header'}
31+
%h2
32+
%span{:class => 'namespace'}= module_metadata['metadata']['name']
33+
%div{:class => 'module-info-author'}= "by: #{module_metadata['metadata']['author']}"
34+
%ul{:class => 'module-links'}
35+
%li
36+
%a{:href => module_metadata['metadata']['homepage_url']}= 'Project URL'
37+
%li
38+
%a{:href => module_metadata['metadata']['issues_url']}= 'Report issues'
39+
%div{:class => 'module-info-summary'}= module_metadata['metadata']['summary']
40+
%div{:class => 'download-info clearfix'}
41+
%div{:class => 'installation'}
42+
%div{:class => 'pmt-option clearfix'}
43+
%strong= 'Use this command to install the latest compatible version:'
44+
%input{:type => 'text', :class => 'paste-code', :value => "puppet module install --module_repository=#{base_url} #{module_metadata['metadata']['name']}", :onclick => 'this.select()'}
45+
%div{:class => 'module-meta-info clearfix'}
46+
%h3= 'Module dependencies'
47+
%ul.release-dependencies
48+
- module_metadata['metadata']['dependencies'].each do |dep|
49+
%li
50+
%a{:href => "/module?name=#{dep['name']}"}= dep['name']
51+
= "(#{dep['version_requirement']})"
52+
%section{:id => 'module-release-info'}
53+
%div
54+
%div{:id => 'module-release-header'}
55+
%div{:id => 'module-release-title'}
56+
Version
57+
%strong= module_metadata['metadata']['version']
58+
%div{:id => 'module-release-switcher'}
59+
%label= 'Select another release: '
60+
%select{:id => 'module-release-selector', :onchange => "location = this.options[this.selectedIndex].value;"}
61+
- releases.each do |release|
62+
%option{:value => "/module?name=#{module_metadata['metadata']['name']}&version=#{release['version']}", :selected => module_metadata['metadata']['version'] == release['version']}= release['version']
63+
%a{:class => 'module-release-download', :href => module_metadata['file_uri'], :title => 'Download module'}= 'Download'
64+
%div{:id => 'release-info-tabs', :class => 'module-meta-info'}
65+
%div{:class => 'tabbed content'}
66+
%div
67+
%div
68+
%section{:class => 'markdown'}
69+
:preserve
70+
#{readme_markdown}

lib/puppet_forge_server/app/views/modules.haml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
- modules.each do |element|
2121
%li{:class => element['private'] ? 'clearfix private' : 'clearfix'}
2222
.col
23-
%h3= "#{element['owner']['username']}/#{element['name']}"
23+
%a{:class => "h3", :href => "/module?name=#{element['current_release']['metadata']['name']}" }= "#{element['owner']['username']}/#{element['name']}"
2424
%p= element['current_release']['metadata']['summary']
2525
%span.release-info= "Version #{element['current_release']['metadata']['version']}"
2626
- if element['current_release']['metadata']['issues_url']

0 commit comments

Comments
 (0)