Navigation Menu

Skip to content
This repository has been archived by the owner on Oct 15, 2022. It is now read-only.

Commit

Permalink
Libraries IA: Rewrite stale PR (#3330)
Browse files Browse the repository at this point in the history
* libraries.io #3101

Libraries.io #3101

Libraries #3101

Libraries.io #3101

Libraries.io #3101

Libraries #3101

Libraries.io #3101

Libraries.io #3101

Libraries.io #3101

Libraries.io #3101

Libraries.io #3101

Libraries.io #3103

Libraries.io #3101

Libraries.io #3101

Libraries.io #3101

Libraries.io #3101

Libraries.io #3101

Libraries.io #3101

Libraries.io #3101

Libraries.io #3101

Libraries.io #3101

Libraries.io #3101

Libraries.io #3101

Libraries.io #3101

Libraries.io #3101

Libraries.io #3101

Libraries.io #3101

Libraries.io #3101

Libraries.io #3101

Libraries.io #3101

Libraries.io #3172

Libraries.io #3172

Libraries.io #3172

Libraries.io #3172

Libraries.io #3172

Libraries.io #3172

Libraries.io #3172

Libraries.io #3172

Libraries.io #3172

Libraries.io #3172

Initial commit

Fix broken test.

Removed icon. Added meteor command.

Add libraries IA.

Updated test.

Add except from Elm - author/pkgname

Remove void package references.

Fix incorrect url.

Add dart back in.

Allow go to reach single view.

Add key to env constant.

Refactor js.

Adjust env var for my typo

Update code.

Refactored code.

Fix up PR

Fix url.

* Add libraries url.

* Switch from regex to string replace
  • Loading branch information
pjhampton authored and moollaza committed Jun 26, 2017
1 parent 02b186b commit 8576d64
Show file tree
Hide file tree
Showing 8 changed files with 363 additions and 0 deletions.
52 changes: 52 additions & 0 deletions lib/DDG/Spice/Libraries.pm
@@ -0,0 +1,52 @@
package DDG::Spice::Libraries;
# ABSTRACT: Search for code on libraries.io

use strict;
use DDG::Spice;

my @blocked_triggers = ('go', 'wordpress', 'emacs', 'julia');
my @triggers_from_file = share('triggers.txt')->slurp;
my @trigger_aliases;
my %alias_hash = ();

foreach my $line (@triggers_from_file){
chomp($line);
my @aliases = split(/,/, $line);
push(@trigger_aliases, @aliases);
$alias_hash{$aliases[0]} = \@aliases;
}

triggers start => @trigger_aliases;

spice from => '(.+)/(.+)';
spice to => 'https://libraries.io/api/search?platforms=$1&q=$2&api_key={{ENV{DDG_SPICE_LIBRARIES_IO_APIKEY}}}';
spice wrap_jsonp_callback => 1;

# Maps alias to package manger
# wp --> wordpress, go lang --> go
sub get_package_manager {
my $input = shift;

return undef if grep(/^$input$/, @blocked_triggers); # go is too ambigious as a trigger

foreach my $key (keys %alias_hash) {
if(exists $alias_hash{$key}) {
my @hash_kv = @{$alias_hash{$key}};
foreach my $value (@hash_kv) {
if($input eq $value) {
return $key;
}
}
}
}
}

handle remainder_lc => sub {
return unless $_;

my $package_manager = get_package_manager($req->matched_trigger);
return unless $package_manager;
return $package_manager, $_;
};

1;
5 changes: 5 additions & 0 deletions share/spice/libraries/content.handlebars
@@ -0,0 +1,5 @@
<p>{{description}}</p>

{{#if install}}
<pre>{{install}}</pre>
{{/if}}
10 changes: 10 additions & 0 deletions share/spice/libraries/footer.handlebars
@@ -0,0 +1,10 @@
{{#if latest_release}}
<div>Latest Release - {{latest_release}}</div>
{{/if}}

<div id="meta-info">
{{#if stars}}
<i class="star starIcon"></i>
<span>Stars - {{stars}}</span>
{{/if}}
</div>
Binary file added share/spice/libraries/icons/libraries.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
14 changes: 14 additions & 0 deletions share/spice/libraries/libraries.css
@@ -0,0 +1,14 @@
/* CSS for Libraries.io */

.zci--libraries #zci__more-at {
margin-top: 1.3em;
}

.zci--libraries #meta-info {
display: inline-block;
}

.zci--libraries .star.starIcon {
margin-top: -5px;
font-size: 1.4em;
}
232 changes: 232 additions & 0 deletions share/spice/libraries/libraries.js
@@ -0,0 +1,232 @@
(function(env) {
"use strict";
var search_items = DDG.get_query().split(" ");

var supported_package_managers = {
alcatraz: "http://alcatraz.io/",
atom: "https://atom.io/packages",
bower: "https://bower.io/",
cran: "https://cran.r-project.org",
dub: "https://code.dlang.org/download",
elm: "http://elm-lang.org/",
emacs: "https://www.gnu.org/software/emacs/",
go: "https://golang.org/",
inqlude: "https://inqlude.org/",
julia: "http://pkg.julialang.org/",
meteor: "https://www.meteor.com/",
nimble: "https://nim-lang.org/",
nuget: "https://www.nuget.org/",
shards: "https://crystal-shards-registry.herokuapp.com/",
wordpress: "https://wordpress.org/",
}

// if it makes sense and we can build it, we will show the user how to install a package
var install_scripts = {
bower: "$ bower install {{package}}",
cran: "install.packages(\"{{package}}\")",
elm: "$ elm-package install {{package}}",
go: "$ go get {{package}}",
julia: "Pkg.add(\"{{package}}\")",
meteor: "$ meteor npm install --save {{package}}",
nimble: "$ nimble install {{package}}",
nuget: "PM> Install-Package {{package}} -Version {{version}}",
pub: "dependencies:\n\t\t {{package}}: ^{{version}}",
}

// sets up the install script for text view
// eg. elm-package install elm-lang/html
function getInstallScript(pkg_manager, pkg_name, pkg_version) {
var index = pkg_manager.toLowerCase();
var text = install_scripts[index] || false;

return text && text.replace('{{package}}', pkg_name).replace('{{version}}', pkg_version);
}

// returns the url
function getUrl(item) {

var url;
// sets the home page for the package
// official website (1st) --> package manager page (2nd) --> GH repo (3rd) --> libraries.io (4th)
if(item.homepage != null && item.homepage != "") {
return url = item.homepage;
} else if(item.package_manager_url != null && item.package_manager_url != "") {
return url = item.package_manager_url;
} else if(item.repository_url != null && item.homepage != item.repository_url) {
return url = item.repository_url;
} else {
return url = 'https://libraries.io/api/search?q=' + search_items;
}
}

// gets the domain (host) name
function getDomainName(url) {
var hostname;

if (url.indexOf("://") > -1) {
hostname = url.split('/')[2];
} else {
hostname = url.split('/')[0];
}

hostname = hostname.split(':')[0];
hostname = hostname.split('?')[0];

return hostname;
}

env.ddg_spice_libraries = function(api_result) {

if(!api_result || api_result.length === 0) {
return Spice.failed('libraries');
}

// we'll show the text template if there is an exact match in the
// query to a highly ranked package
var text_template = {
group: 'text',
options: {
content: Spice.libraries.content,
moreAt: true,
moreText: {
href: "https://libraries.io",
text: "Data by Libraries.io"
}
}
}

// we'll show the tile template if it's a fuzzy match
var tile_template = {
group: 'text',
detail: false,
item_detail: false,
variants: {
tile: 'basic1',
tileTitle: '1line',
tileFooter: '2line',
tileSnippet: 'large'
},
options: {
footer: Spice.libraries.footer,
moreAt: true
}
}

var template, meta;
var signal = "high";
var query = DDG.get_query().split(" ");
query = query[query.length-1];
var pkgname = api_result[0].name;
var total = api_result.length;

meta = {
search_term: search_items,
total: total,
}

// determine which template to show and set high/low signal
if(total === 1) {
template = text_template;
} else if(
(pkgname.toLowerCase() == query) ||
(api_result[0].platform === "Go" && pkgname.split("/").pop() === query) ||
(api_result[0].platform === "Elm" && pkgname.split("/")[1] === query)
) {
template = text_template;

// set the result to the first result
if (total > 1) {
api_result = api_result.shift();
}

meta.sourceUrl = getUrl(api_result);
meta.sourceName = getDomainName(meta.sourceUrl);
} else {
template = tile_template;
signal = "low";

// we'll pass further meta information to the tile template if we're using it
meta.sourceName = 'libraries.io';
meta.sourceUrl = 'https://libraries.io/api/search?q=' + search_items;
}

Spice.add({
id: 'libraries',
name: 'Software',
signal: signal,
data: api_result,
meta: meta,
templates: template,
sort_fields: {
rank: function(a, b) {
return a.rank > b.rank ? -1 : 1;
}
},
sort_default: 'rank',
normalize: function(item) {

var name, url;
var package_manager = item.platform;
var infoboxData = [
{ heading: 'Package information:' },
];

// show the license if it exists
if(item.latest_release_number !== undefined
&& item.latest_release_number !== ""
&& item.latest_release_number !== null) {

infoboxData.push({
label: "Version",
value: item.latest_release_number,
});
}

// show the license type if it exists
if(item.normalized_licenses[0] !== undefined) {
infoboxData.push({
label: "License",
value: item.normalized_licenses[0],
});
}

// show stars if there is any
if(item.stars > 0) {
infoboxData.push({
label: "Stars",
value: item.stars,
});
}

// show forks if there is any
if(item.forks > 0) {
infoboxData.push({
label: "Forks",
value: item.forks,
});
}

// if a go package, we'll trim the github url from the package name
if(package_manager === "Go") {
name = item.name.replace("github.com/", '');
} else {
name = item.name;
}

return {
title: name,
subtitle: item.platform + " Package",
description: item.description,
install: getInstallScript(item.platform, item.name, item.latest_release_number),
stars: item.stars,
forks: item.forks,
url: getUrl(item),
latest_release: item.latest_release_number,
infoboxData: infoboxData.length > 1 ? infoboxData : undefined,
librariesIcon: DDG.get_asset_path('libraries',"icons/libraries.png"),
moreAtIcon: DDG.get_favicon_url(supported_package_managers[package_manager.toLowerCase()]),
}
}
});
};
}(this));
16 changes: 16 additions & 0 deletions share/spice/libraries/triggers.txt
@@ -0,0 +1,16 @@
alcatraz,alcatraz.io,alcatraz packages,
atom,atom.io,atom package,atom packages,
bower,bower install,bower package,
cran,rlang,r lang,r project,
dub,dlang,d lang,
elm,elm-lang,elm lang,
emacs,
go,go get,golang,go lang,
inqlude,
julia,julia install,julia lang,
meteor,
nimble,nim,nim install,nimble install,
nuget,
pub,dart,dart lang,dartlang,
shards,shards install,crystal,crystal lang,crystal install,
wordpress,wp plugins,wordpress plugins,
34 changes: 34 additions & 0 deletions t/Libraries.t
@@ -0,0 +1,34 @@
#!/usr/bin/env perl

use strict;
use warnings;
use Test::More;
use DDG::Test::Spice;

ddg_spice_test(
[qw( DDG::Spice::Libraries )],

# should trigger
'cran ggplot2' => test_spice(
'/js/spice/libraries/cran/ggplot2',
caller => 'DDG::Spice::Libraries',
),
'elm elm-html' => test_spice(
'/js/spice/libraries/elm/elm-html',
caller => 'DDG::Spice::Libraries',
),
'go get glog' => test_spice(
'/js/spice/libraries/go/glog',
caller => 'DDG::Spice::Libraries',
),

# shouldn't trigger
'r wtf' => undef,
'wp jetpack' => undef,
'emacs rocks' => undef,
'julia roberts' => undef,
'wordpress themes' => undef,
);

done_testing;

0 comments on commit 8576d64

Please sign in to comment.