Merge branch 'master' into RegexCheatSheet
Conflicts: lib/DDG/Goodie/RegexCheatSheet.pmmaster
commit
9cefa77e70
|
@ -1,3 +1,4 @@
|
|||
DDG-*
|
||||
.build
|
||||
*.sw*
|
||||
*~
|
||||
|
|
|
@ -0,0 +1,70 @@
|
|||
# Contributing to Goodie
|
||||
|
||||
At DuckDuckGo, we truly appreciate our community members taking the time to contribute to our open-source repositories. In an effort to ensure contributions are easy for you to make and for us to manage, we have written some guidelines that we ask our contributors to follow so that we can handle pull requests in a timely manner with as little friction as possible.
|
||||
|
||||
## Getting Started
|
||||
|
||||
Before you can do anything, you first need a [GitHub account](https://github.com/signup/free). This is required because we use GitHub to handle all incoming *Pull Requests* (code modifications) and *Issues* (bug reports) which cannot be made without a GitHub account.
|
||||
|
||||
## Submitting a **Bug** or **Suggestion**
|
||||
|
||||
- Firstly, please make sure the bug is related to the Goodie repository. If this bug is about the DuckDuckGo API, or the relevancy of our search results, please visit our feedback page at <https://duckduckgo.com/feedback>. If you're unsure, its best to use the feedback page (your message will be passed along to the correct people).
|
||||
|
||||
- Check the Goodie [issues](https://github.com/duckduckgo/zeroclickinfo-goodies/issues) to see if an issue already exists for the given bug or suggestion
|
||||
- If one doesn't exist, create a GitHub issue in the Goodie repository
|
||||
- Clearly describe the bug/improvemnt, including steps to reproduce when it is a bug
|
||||
- If one already exists, please add any additional comments you have regarding the matter
|
||||
|
||||
If you're submitting a **pull request** (bugfix/addition):
|
||||
- Fork the Goodie repository on GitHub
|
||||
|
||||
## Making Changes
|
||||
|
||||
- Before making any changes, refer to the [DuckDuckHack Styleguide](https://dukgo.com/duckduckhack/styleguide_overview) to ensure your changes are made in the correct fashion
|
||||
- Make sure your commits are of a reasonable size. They shouldn't be too big (or too small)
|
||||
- Make sure your commit messages effectively explain what changes have been made, and please identify which instant answer or file has been modified:
|
||||
|
||||
```shell
|
||||
CONTRIBUTING.md - Added the example commit message because it was missing
|
||||
```
|
||||
|
||||
is much better than:
|
||||
|
||||
```shell
|
||||
<bad_commit_example>
|
||||
```
|
||||
|
||||
- Make sure you have added the necessary tests for your changes
|
||||
- Run `dzil test` (executes all tests in t/) to ensure nothing else was accidentally broken
|
||||
- If your change affects an instant answer, remember to add yourself to the Metadata attribution list in the appropriate `.pm` file
|
||||
|
||||
## Submitting Changes
|
||||
|
||||
1. Commit your changes.
|
||||
|
||||
```shell
|
||||
git commit -a -m "My first instant answer that does X is ready to go!"
|
||||
```
|
||||
|
||||
2. Get your commit history [how you like it](http://book.git-scm.com/4_interactive_rebasing.html).
|
||||
|
||||
```shell
|
||||
git rebase -i origin/master
|
||||
```
|
||||
|
||||
or
|
||||
|
||||
```shell
|
||||
git pull --rebase origin/master
|
||||
```
|
||||
|
||||
3. Push your forked repository back to GitHub.
|
||||
|
||||
```shell
|
||||
git push
|
||||
```
|
||||
|
||||
4. Add your info to the instant answer so we can give you credit for it on the [Goodies page](https://duckduckgo.com/goodies). You'll see your name or handle on the live site!
|
||||
Check out the [Metadata documentation](https://dukgo.com/duckduckhack/metadata) for detailed instructions on how to include your name and links.
|
||||
|
||||
5. Go into GitHub and submit a [pull request!](http://help.github.com/send-pull-requests/) to the Goodie repository, making sure to use the Goodie repository's **[Pull Request Template](https://github.com/duckduckgo/zeroclickinfo-goodies/blob/master/goodie_pr_template.md)**. This will let us know about your changes and start the conversation about integrating it into the live code.
|
|
@ -0,0 +1,11 @@
|
|||
Copyright 2010 Duck Duck Go, Inc.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
|
17
README.md
17
README.md
|
@ -1,12 +1,11 @@
|
|||
DuckDuckHack Goodies
|
||||
====
|
||||
# DuckDuckHack Goodie Instant Answers
|
||||
|
||||
Goodies are DuckDuckGo plugins that work with pure [Perl](https://en.wikipedia.org/wiki/Perl).
|
||||
This repository contains all the Goodie instant answers. If you are developing a Goodie instant answer you will need to fork this repository.
|
||||
|
||||
**If you would like to contribute to DuckDuckHack, please start by reading the [DuckDuckHack Documentation](https://dukgo.com/duckduckhack/ddh-intro).**
|
||||
|
||||
------
|
||||
|
||||
### Goodie Instant Answer Example
|
||||
|
||||
![morse code example](https://s3.amazonaws.com/ddg-assets/docs/goodie_example.png)
|
||||
|
||||
We recommend starting at the [DuckDuckHack Intro Site](http://duckduckhack.com). If you've read that, but are still looking for more detail, checkout the [DuckDuckHack Goodie Overview](https://github.com/duckduckgo/duckduckgo/blob/master/README.md).
|
||||
|
||||
### Writing a Goodie
|
||||
|
||||
If you're ready to start writing a Goodie, go to the [Goodies Overview](https://github.com/duckduckgo/duckduckgo#goodies-overview).
|
||||
|
|
1
dist.ini
1
dist.ini
|
@ -29,6 +29,7 @@ Locale::Codes = 3.25
|
|||
Gravatar::URL = 1.06
|
||||
CGI = 3.60
|
||||
Email::Valid = 0.190
|
||||
Net::Domain::TLD = 0.170
|
||||
; ParseCron
|
||||
Schedule::Cron::Events = 0
|
||||
Convert::Color = 0.08
|
||||
|
|
|
@ -0,0 +1,85 @@
|
|||
# Goodie Pull Request Template
|
||||
|
||||
We ask that you please use this template when submitting an instant answer pull request so we can better understand it and help you along when necessary.
|
||||
|
||||
**What does your instant answer do?**
|
||||
|
||||
|
||||
**What problem does your instant answer solve (Why is it better than organic links)?**
|
||||
|
||||
|
||||
**What is the data source for your instant answer? (Provide a link if possible)**
|
||||
|
||||
|
||||
**Why did you choose this data source?**
|
||||
|
||||
|
||||
**Are there any other alternative (better) data sources?**
|
||||
|
||||
|
||||
**What are some example queries that trigger this instant answer?**
|
||||
|
||||
|
||||
**Which communities will this instant answer be especially useful for? (gamers, book lovers, etc)**
|
||||
|
||||
|
||||
**Is this instant answer connected to an [Ideas.DuckDuckHack](https://duckduckhack.uservoice.com/forums/5168-ideas-for-duckduckgo-instant-answer-plugins) or [Duck.co](http://duck.co/) thread?**
|
||||
|
||||
|
||||
**Which existing instant answers will this one supercede/overlap with?**
|
||||
|
||||
|
||||
**Are you having any problems? Do you need our help with anything?**
|
||||
|
||||
**\*\*Note:** Please attach a screenshot for new instant answer pull requests, and for pull requests which modify the look/design of existing instant answers.
|
||||
|
||||
##Checklist
|
||||
Please place a ✔ where appropriate.
|
||||
|
||||
```
|
||||
[] Added metadata and attribution information
|
||||
[] Wrote test file and added to t/ directory
|
||||
[] Verified that instant answer adheres to design guidelines(https://github.com/duckduckgo/duckduckgo-documentation/blob/master/duckduckhack/styleguides/design_styleguide.md)
|
||||
[] Tested cross-browser compatability
|
||||
|
||||
Please let us know which browsers/devices you've tested on:
|
||||
- Windows 8
|
||||
[] Google Chrome
|
||||
[] Firefox
|
||||
[] Opera
|
||||
[] IE 10
|
||||
|
||||
- Windows 7
|
||||
[] Google Chrome
|
||||
[] Firefox
|
||||
[] Opera
|
||||
[] IE 8
|
||||
[] IE 9
|
||||
[] IE 10
|
||||
|
||||
- Windows XP
|
||||
[] IE 7
|
||||
[] IE 8
|
||||
|
||||
- Mac OSX
|
||||
[] Google Chrome
|
||||
[] Firefox
|
||||
[] Opera
|
||||
[] Safari
|
||||
|
||||
- iOS (iPhone)
|
||||
[] Safari Mobile
|
||||
[] Google Chrome
|
||||
[] Opera
|
||||
|
||||
- iOS (iPad)
|
||||
[] Safari Mobile
|
||||
[] Google Chrome
|
||||
[] Opera
|
||||
|
||||
- Android
|
||||
[] Firefox
|
||||
[] Native Browser
|
||||
[] Google Chrome
|
||||
[] Opera
|
||||
```
|
|
@ -21,7 +21,7 @@ attribution twitter => 'crazedpsyc',
|
|||
handle query => sub {
|
||||
return if $_ =~ /^root/i && $_ !~ /^root mean square/i;
|
||||
|
||||
s/^[a-zA-Z\s]+//; s/\s+[a-zA-Z]+$//; s/[;,\s]+/ /g;
|
||||
s/^[a-zA-Z\s]+//; s/\s+[a-zA-Z]+$//; s/[;,\s{}\[\]\(\)]+/ /g;
|
||||
return unless /^\s*(?:\d+(?:\.\d+)?\s?)*$/;
|
||||
|
||||
my @nums = split ' ', $_;
|
||||
|
|
|
@ -2,10 +2,11 @@ package DDG::Goodie::Coin;
|
|||
|
||||
use DDG::Goodie;
|
||||
|
||||
triggers start => 'flip', 'toss', 'coin';
|
||||
triggers start => 'flip', 'toss', 'coin', 'heads';
|
||||
|
||||
primary_example_queries 'flip a coin', 'toss a coin';
|
||||
secondary_example_queries 'flip 4 coins';
|
||||
secondary_example_queries 'flip 4 coins', 'heads or tails';
|
||||
|
||||
description 'flip a coin';
|
||||
name 'Coin Flip';
|
||||
code_url 'https://github.com/duckduckgo/zeroclickinfo-goodies/blob/master/lib/DDG/Goodie/Coin.pm';
|
||||
|
@ -14,23 +15,24 @@ category 'random';
|
|||
attribution github => [ 'http://github.com/mattlehning', 'mattlehning' ];
|
||||
|
||||
handle query_lc => sub {
|
||||
return unless my ($a, $n) = $_ =~ /^((?:flip|toss) a coin|(?:flip|toss) (\d{0,2}) coins?)$/;
|
||||
my $flips;
|
||||
if ($_ =~ /^(heads or tails[ ]?[\?]?)|((flip|toss) a coin)$/) {
|
||||
$flips = 1;
|
||||
}
|
||||
elsif ($_ =~ /^(?:flip|toss) (\d{0,2}) coins?$/) {
|
||||
$flips = $1;
|
||||
}
|
||||
|
||||
return unless ($flips);
|
||||
|
||||
my @output;
|
||||
my @ht = ("heads", "tails");
|
||||
my $flips = 1;
|
||||
my $flip;
|
||||
my $b = "flip a coin";
|
||||
my $c = "toss a coin";
|
||||
my $count;
|
||||
|
||||
$n = 1 if ($a eq $b||$a eq $c);
|
||||
|
||||
if($n >= 1) {
|
||||
for ($count = 1; $count <= $n; $count++) {
|
||||
$flip = $ht[int rand @ht];
|
||||
push @output, $flip;
|
||||
}
|
||||
for (1..$flips) {
|
||||
my $flip = $ht[int rand @ht];
|
||||
push @output, $flip;
|
||||
}
|
||||
|
||||
return join(', ', @output) . ' (random)' if @output;
|
||||
};
|
||||
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
package DDG::Goodie::Dessert;
|
||||
|
||||
use DDG::Goodie;
|
||||
|
||||
sub itemify{
|
||||
my $i = rand scalar @_;
|
||||
my $dessert = $_[$i];
|
||||
$dessert =~ s/\s/+/g;
|
||||
|
||||
return "<a href='http://duckduckgo.com/?q=$dessert+recipe'>$_[$i]</a>";
|
||||
};
|
||||
|
||||
my %desserts = (
|
||||
a => ['Apple Turnover'],
|
||||
b => ['Banana Split', 'Biscuits'],
|
||||
c => ['Cherry Pie', 'Cupcake', 'Chocolate'],
|
||||
d => ['Donut'],
|
||||
e => ['Eclair'],
|
||||
f => ['Froyo', 'Fudge'],
|
||||
g => ['Gingerbread'],
|
||||
h => ['Honeycomb'],
|
||||
i => ['Ice Cream Sandwich', 'Ice Cream'],
|
||||
j => ['Jam Rolly Polly','Jelly Bean','Jelly'],
|
||||
k => ['Key Lime Pie'],
|
||||
l => ['Lollipop','Liqourice'],
|
||||
m => ['Macaroons','Meringues','Marshmallow','Muffin'],
|
||||
n => ['Nougat','Nutella'],
|
||||
o => ['Oatmeal Pie','Oreos'],
|
||||
p => ['Profiteroles','Pop Tart'],
|
||||
q => ['Quiche'],
|
||||
r => ['Rocky Road','Red Velvet Cake','Ruhbarb and Custard'],
|
||||
s => ['Sundae','Strudel','Strawberries and Cream','Souffle'],
|
||||
t => ['Tiramisu','Trifle','Twinkies','Taffy','Toffee'],
|
||||
u => ['Unicorn Cake','Upside-down cake'],
|
||||
v => ['Vanilla Swirl'],
|
||||
w => ['Waffles','Watermelon','White Chocolate'],
|
||||
x => ['Xmas Cake'],
|
||||
z => ['Zepolle','Zucchini Pie'],
|
||||
);
|
||||
|
||||
triggers start => 'dessert', 'desserts', 'a dessert';
|
||||
handle remainder => sub{
|
||||
if(lc $_ =~ m/^(?:that )?(?:start|beginn?)s?(?:ing)? ?(?:with)? (?:the letter )?([a-zA-Z])$/i){
|
||||
my $in = lc $1;
|
||||
my $items = $desserts{lc $in};
|
||||
|
||||
my $output = itemify(@{$items}) . " is a dessert that begins with the letter " . uc $in . '.';
|
||||
return $output;
|
||||
}
|
||||
return;
|
||||
};
|
||||
|
||||
zci is_cached => 0;
|
||||
1;
|
|
@ -32,7 +32,7 @@ sub get_info {
|
|||
sub line {
|
||||
my($num) = @_;
|
||||
chomp $num;
|
||||
return "<td>$num</td><td>".(get_info($num) or return)."</td>";
|
||||
return "<td>$num</td><td> ".(get_info($num) or return)."</td>";
|
||||
}
|
||||
|
||||
sub single_format {
|
||||
|
@ -91,7 +91,7 @@ handle remainder => sub {
|
|||
$out_html =~ s/\[\[(.+?)\]\]/<a href="\/?q=$1">$1<\/a>/g;
|
||||
$out =~ s/\[\[.+?\|(.+?)\]\]/$1/g;
|
||||
$out =~ s/\[\[(.+?)\]\]/$1/g;
|
||||
return ($multi) ? "" : $out, html => ($multi) ? "<table>$out_html</table>" : $out_html;
|
||||
return ($multi) ? "" : $out, html => ($multi) ? "<table cellpadding=1>$out_html</table>" : $out_html;
|
||||
};
|
||||
|
||||
1;
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
package DDG::Goodie::EmailValidator;
|
||||
# ABSTRACT: Checks given email address
|
||||
|
||||
use DDG::Goodie;
|
||||
use Email::Valid;
|
||||
|
||||
topics 'sysadmin';
|
||||
category 'computing_info';
|
||||
|
||||
zci is_cached => 0;
|
||||
triggers start => 'validate';
|
||||
|
||||
primary_example_queries 'validate foo@example.com';
|
||||
|
||||
attribution github => ['https://github.com/stelim', 'Stefan Limbacher'],
|
||||
twitter => ['http://twitter.com/stefanlimbacher', 'Stefan Limbacher'];
|
||||
|
||||
my $message_part = {
|
||||
tldcheck => 'top-level domain',
|
||||
fqdn => 'fully qualified domain name',
|
||||
localpart => 'localpart',
|
||||
address_too_long => 'address length',
|
||||
};
|
||||
|
||||
handle remainder => sub {
|
||||
return if !$_;
|
||||
|
||||
$_ =~ /\b([^\s]+@[^\s]+)\b/g ;
|
||||
my $address = $1;
|
||||
|
||||
return if !$address;
|
||||
|
||||
my $email_valid = Email::Valid->new(
|
||||
-tldcheck => 1,
|
||||
);
|
||||
|
||||
# Danger: address returns possible modified string!
|
||||
my $result = $email_valid->address($address);
|
||||
|
||||
if (! $result) {
|
||||
|
||||
my $message = "$address is invalid. Please check the " . $message_part->{$email_valid->details} . "."
|
||||
if defined $message_part->{$email_valid->details};
|
||||
|
||||
return $message || "E-mail address $address is not valid. ${\$email_valid->details} (see also: RFC 822)";
|
||||
}
|
||||
|
||||
return "$result seems to be valid.";
|
||||
};
|
||||
|
||||
1;
|
|
@ -36,7 +36,7 @@ our @category_column = (
|
|||
# Titles of tables and the symbols to explain
|
||||
our %categories = (
|
||||
'Anchors' => [
|
||||
'^', '\A', '$', '\Z', '\b', '\B', '\<' , '\>'
|
||||
'^', '\A', '$', '\Z', '\b', '\B', '\<', '\>'
|
||||
],
|
||||
'Character Classes' => [
|
||||
'\c', '\s', '\S', '\d', '\D', '\w', '\W', '\x', '\O'
|
||||
|
@ -71,32 +71,32 @@ our %categories = (
|
|||
|
||||
# Symbols and their explanation/description
|
||||
our %syntax_map = (
|
||||
'.' => 'Any character except newline (\n)',
|
||||
'(a|b)' => 'a or b',
|
||||
'(...)' => 'Group',
|
||||
'.' => 'Any character except newline (\n)',
|
||||
'(a|b)' => 'a or b',
|
||||
'(...)' => 'Group',
|
||||
'(?:...)' => 'Passive (non-capturing) group',
|
||||
'[abc]' => 'Single character (a or b or c)',
|
||||
'[abc]' => 'Single character (a or b or c)',
|
||||
'[^abc]' => 'Single character (not a or b or c)',
|
||||
'[a-q]' => 'Single character range (a or b ... or q)',
|
||||
'[A-Z]' => 'Single character range (A or B ... or Z)',
|
||||
'[0-9]' => 'Single digit from 0 to 9',
|
||||
'^' => "Start of string or line",
|
||||
'\A' => "Start of string",
|
||||
'$' => "End of string or line",
|
||||
'\Z' => "End of string",
|
||||
'\b' => 'Word boundary',
|
||||
'\B' => 'Not word boundary',
|
||||
'\<' => 'Start of word',
|
||||
'\>' => 'End of word',
|
||||
'\c' => 'Control character',
|
||||
'\s' => 'Whitespace',
|
||||
'\S' => 'Not Whitespace',
|
||||
'\d' => 'Digit',
|
||||
'\D' => 'Not digit',
|
||||
'\w' => 'Word',
|
||||
'\W' => 'Not Word',
|
||||
'\x' => 'Hexadecimal digit',
|
||||
'\O' => 'Octal Digit',
|
||||
'[a-q]' => 'Single character range (a or b ... or q)',
|
||||
'[A-Z]' => 'Single character range (A or B ... or Z)',
|
||||
'[0-9]' => 'Single digit from 0 to 9',
|
||||
'^' => "Start of string or line",
|
||||
'\A' => "Start of string",
|
||||
'$' => "End of string or line",
|
||||
'\Z' => "End of string",
|
||||
'\b' => 'Word boundary',
|
||||
'\B' => 'Not word boundary',
|
||||
'\<' => 'Start of word',
|
||||
'\>' => 'End of word',
|
||||
'\c' => 'Control character',
|
||||
'\s' => 'Whitespace',
|
||||
'\S' => 'Not Whitespace',
|
||||
'\d' => 'Digit',
|
||||
'\D' => 'Not digit',
|
||||
'\w' => 'Word',
|
||||
'\W' => 'Not Word',
|
||||
'\x' => 'Hexadecimal digit',
|
||||
'\O' => 'Octal Digit',
|
||||
'[:upper:]' => 'Uppercase letters [A-Z]',
|
||||
'[:lower:]' => 'Lowercase letters [a-z]',
|
||||
'[:alpha:]' => 'All letters [A-Za-z]',
|
||||
|
@ -111,119 +111,122 @@ our %syntax_map = (
|
|||
'[:graph:]' => 'Printed characters [\x21-\x7E]',
|
||||
'[:print:]' => 'Printed characters and spaces [\x20-\x7E]',
|
||||
'[:word:]' => 'Digits, letters and underscore [A-Za-z0-9_]',
|
||||
'?=' => 'Lookahead assertion',
|
||||
'?!' => 'Negative lookahead',
|
||||
'?<=' => 'Lookbehind assertion',
|
||||
'?=' => 'Lookahead assertion',
|
||||
'?!' => 'Negative lookahead',
|
||||
'?<=' => 'Lookbehind assertion',
|
||||
'?!= or ?<!' => 'Negative lookbehind',
|
||||
'?>' => 'Once-only Subexpression',
|
||||
'?()' => 'Condition [if then]',
|
||||
'?()|' => 'Condition [if then else]',
|
||||
'?#' => 'Comment',
|
||||
'*' => '0 or more',
|
||||
'+' => '1 or more',
|
||||
'?' => '0 or 1 (optional)',
|
||||
'{3}' => 'Exactly 3',
|
||||
'{3,}' => '3 or more',
|
||||
'{2,5}' => '2, 3, 4 or 5',
|
||||
'\\' => 'Escape following character',
|
||||
'\Q' => 'Begin literal sequence',
|
||||
'\E' => 'End literal sequence',
|
||||
'\n' => 'New line',
|
||||
'\r' => 'Carriage return',
|
||||
'\t' => 'Tab',
|
||||
'\v' => 'Vertical tab',
|
||||
'\f' => 'Form feed',
|
||||
'\ooo' => 'Octal character ooo',
|
||||
'\xhh' => 'Hex character hh',
|
||||
'//g' => 'Global Match (all occurrences)',
|
||||
'//i' => 'Case-insensitive',
|
||||
'//m' => 'Multiple line',
|
||||
'//s' => 'Treat string as single line',
|
||||
'//x' => 'Allow comments and whitespace',
|
||||
'//e' => 'Evaluate replacement',
|
||||
'//U' => 'Ungreedy pattern',
|
||||
'$n' => 'n-th non-passive group',
|
||||
'$2' => '"xyz" in /^(abc(xyz))$/',
|
||||
'$1' => '"xyz" in /^(?:abc)(xyz)$/',
|
||||
'$`' => 'Before matched string',
|
||||
q{$'} => 'After matched string',
|
||||
'$+' => 'Last matched string',
|
||||
'$&' => 'Entire matched string',
|
||||
'?>' => 'Once-only Subexpression',
|
||||
'?()' => 'Condition [if then]',
|
||||
'?()|' => 'Condition [if then else]',
|
||||
'?#' => 'Comment',
|
||||
'*' => '0 or more',
|
||||
'+' => '1 or more',
|
||||
'?' => '0 or 1 (optional)',
|
||||
'{3}' => 'Exactly 3',
|
||||
'{3,}' => '3 or more',
|
||||
'{2,5}' => '2, 3, 4 or 5',
|
||||
'\\' => 'Escape following character',
|
||||
'\Q' => 'Begin literal sequence',
|
||||
'\E' => 'End literal sequence',
|
||||
'\n' => 'New line',
|
||||
'\r' => 'Carriage return',
|
||||
'\t' => 'Tab',
|
||||
'\v' => 'Vertical tab',
|
||||
'\f' => 'Form feed',
|
||||
'\ooo' => 'Octal character ooo',
|
||||
'\xhh' => 'Hex character hh',
|
||||
'//g' => 'Global Match (all occurrences)',
|
||||
'//i' => 'Case-insensitive',
|
||||
'//m' => 'Multiple line',
|
||||
'//s' => 'Treat string as single line',
|
||||
'//x' => 'Allow comments and whitespace',
|
||||
'//e' => 'Evaluate replacement',
|
||||
'//U' => 'Ungreedy pattern',
|
||||
'$n' => 'n-th non-passive group',
|
||||
'$2' => '"xyz" in /^(abc(xyz))$/',
|
||||
'$1' => '"xyz" in /^(?:abc)(xyz)$/',
|
||||
'$`' => 'Before matched string',
|
||||
q{$'} => 'After matched string',
|
||||
'$+' => 'Last matched string',
|
||||
'$&' => 'Entire matched string',
|
||||
);
|
||||
|
||||
handle remainder => sub {
|
||||
|
||||
#if the user has requested information on a specific thing
|
||||
if (length $_ > 0)
|
||||
{
|
||||
my $syntax_key = $_;
|
||||
#let the user provide a number for {3}
|
||||
if ($_ =~ /\{([0-9]+)\}/)
|
||||
{
|
||||
return "$_ - Exactly $1 occurrences", html => "<code> " . encode_entities($_) . " </code> - Exactly " . encode_entities($_) . " occurrences";
|
||||
}
|
||||
#let the user provide numbers for {3,} and {3,5}
|
||||
elsif ($_ =~ /\{([0-9]+),([0-9]+)?\}/)
|
||||
{
|
||||
if ($2) {
|
||||
return unless ($1 < $2);
|
||||
return "$_ - Between $1 and $2 occurrences", html => "<code> " . encode_entities($_) . " </code> - Between $1 and $2 occurrences";
|
||||
}
|
||||
return "$_ - $1 or more", html => "<code> " . encode_entities($_) . " </code> - $1 or more occurrences";
|
||||
}
|
||||
# If the user has requested information on a specific pattern.
|
||||
if (length $_ > 0) {
|
||||
my $syntax_key = $_;
|
||||
|
||||
return unless $syntax_map{$syntax_key};
|
||||
my $text_output = "$_ - $syntax_map{$syntax_key}";
|
||||
my $html_output = "<code> " . encode_entities($_) . " </code> - " . encode_entities($syntax_map{$syntax_key});
|
||||
return $text_output, html => $html_output;
|
||||
# Let the user provide a number for the {n} pattern, e.g., {5} would say "Exactly 5 occurrences".
|
||||
if ($_ =~ /\{([0-9]+)\}/) {
|
||||
return answer => "$_ - Exactly $1 occurrences",
|
||||
html => "<code>" . encode_entities($_) . "</code> - Exactly " . encode_entities($_) . " occurrences";
|
||||
}
|
||||
# Let the user provide numbers for {n,} and {n,m}, e.g., {4,} would say "4 or more occurrences".
|
||||
elsif ($_ =~ /\{([0-9]+),([0-9]+)?\}/) {
|
||||
if ($2) {
|
||||
return unless ($1 < $2);
|
||||
return answer => "$_ - Between $1 and $2 occurrences",
|
||||
html => "<code>" . encode_entities($_) . "</code> - Between $1 and $2 occurrences";
|
||||
}
|
||||
return answer => "$_ - $1 or more",
|
||||
html => "<code> " . encode_entities($_) . " </code> - $1 or more occurrences";
|
||||
}
|
||||
# Check our map if it's in our list of regex patterns.
|
||||
return unless $syntax_map{$syntax_key};
|
||||
|
||||
#otherwise display the complete tabular output, into n columns in the order specified
|
||||
my $text_output = "$_ - $syntax_map{$syntax_key}";
|
||||
my $html_output = "<code> " . encode_entities($_) . " </code> - " . encode_entities($syntax_map{$syntax_key});
|
||||
return answer => $text_output, html => $html_output;
|
||||
}
|
||||
|
||||
my $text_output = '';
|
||||
# Otherwise display the complete tabular output, into n columns in the order specified.
|
||||
|
||||
#style assigned to the outside wrapper div (around all content)
|
||||
my $div_wrapper_style = 'max-height: 45ex; overflow-y: scroll; overflow-x: hidden';
|
||||
my $text_output = '';
|
||||
|
||||
#style assigned to the wrapper column divs
|
||||
my $div_column_style = 'width: 48%; display: inline-block; vertical-align: top;';
|
||||
# Style assigned to the outside wrapper div (around all content).
|
||||
my $div_wrapper_style = 'max-height: 45ex; overflow-y: scroll; overflow-x: hidden';
|
||||
|
||||
#style assigned to each table of results (Anchors, Quantifiers etc)
|
||||
my $table_style = 'width: 100%; margin-bottom: 1ex;';
|
||||
# Style assigned to the wrapper column divs
|
||||
my $div_column_style = 'width: 48%; display: inline-block; vertical-align: top;';
|
||||
|
||||
# Style assigned to each table of results (Anchors, Quantifiers etc)
|
||||
my $table_style = 'width: 100%; margin-bottom: 1ex;';
|
||||
|
||||
#content of the div column wrapper
|
||||
my @html_columns = ();
|
||||
# Content of the div column wrapper.
|
||||
my @html_columns = ();
|
||||
|
||||
for(my $column = 0; $column < scalar(@category_column); ++$column)
|
||||
{
|
||||
for my $category ( @{$category_column[$column]} )
|
||||
{
|
||||
my $new_table = "<table style='$table_style'>
|
||||
<caption><b> $category </b></caption>";
|
||||
|
||||
$text_output .= "$category\n";
|
||||
|
||||
for my $syntax_object ( @{$categories{$category}} )
|
||||
{
|
||||
$new_table .= " <tr>
|
||||
<td><code> " . encode_entities($syntax_object) . " </code></td>
|
||||
<td> " . encode_entities($syntax_map{$syntax_object}) . " </td>
|
||||
</tr>" . "\n";
|
||||
|
||||
$text_output .= "\t$syntax_object - $syntax_map{$syntax_object} \n";
|
||||
}
|
||||
|
||||
$text_output .= "\n";
|
||||
$new_table .= "</table>" . "\n";
|
||||
|
||||
$html_columns[$column] .= "\n" . $new_table;
|
||||
}
|
||||
# Add a helper function for adding the <td> tag.
|
||||
sub add_table_data {
|
||||
my ($text, $is_code) = @_;
|
||||
if($is_code) {
|
||||
return "<td><code>" . encode_entities($text) . "</code></td>";
|
||||
}
|
||||
return "<td>" . encode_entities($text) . "</tb>";
|
||||
}
|
||||
|
||||
for(my $column = 0; $column < scalar(@category_column); ++$column) {
|
||||
for my $category (@{$category_column[$column]}) {
|
||||
my $new_table = "<table style='$table_style'><b>$category</b>";
|
||||
|
||||
$text_output .= "$category\n";
|
||||
|
||||
for my $syntax_object (@{$categories{$category}}) {
|
||||
$new_table .= "<tr>" . add_table_data($syntax_object, 1) . add_table_data($syntax_map{$syntax_object}, 0) . "</tr>\n";
|
||||
$text_output .= "\t$syntax_object - $syntax_map{$syntax_object}\n";
|
||||
}
|
||||
|
||||
$text_output .= "\n";
|
||||
$new_table .= "</table>\n";
|
||||
|
||||
$html_columns[$column] .= $new_table;
|
||||
}
|
||||
}
|
||||
|
||||
my $html_output = "<div style='$div_wrapper_style'><div style='$div_column_style'>";
|
||||
$html_output .= join ("</div><div style='$div_column_style'>", @html_columns);
|
||||
$html_output .= "</div></div>";
|
||||
return $text_output, html => $html_output;
|
||||
my $html_output = "<div style='$div_wrapper_style'><div style='$div_column_style'>";
|
||||
$html_output .= join ("</div><div style='$div_column_style'>", @html_columns);
|
||||
$html_output .= "</div></div>";
|
||||
return answer => $text_output, html => $html_output;
|
||||
};
|
||||
|
||||
1;
|
||||
1;
|
||||
|
|
|
@ -1,44 +0,0 @@
|
|||
package DDG::Goodie::SharkWeek;
|
||||
|
||||
use DDG::Goodie;
|
||||
use JSON;
|
||||
use DateTime;
|
||||
|
||||
zci answer_type => 'schedule';
|
||||
|
||||
primary_example_queries 'shark week schedule';
|
||||
secondary_example_queries 'shark week';
|
||||
description 'see the schedule for shark week';
|
||||
name 'Calculator';
|
||||
code_url 'https://github.com/duckduckgo/zeroclickinfo-goodies/blob/master/lib/DDG/Goodie/Calculator.pm';
|
||||
category 'entertainment';
|
||||
topics 'entertainment';
|
||||
attribution web => [ 'https://www.duckduckgo.com', 'DuckDuckGo' ],
|
||||
github => [ 'https://github.com/duckduckgo', 'duckduckgo' ],
|
||||
twitter => ['http://twitter.com/duckduckgo', 'duckduckgo' ];
|
||||
|
||||
triggers start => 'shark';
|
||||
my $schedule = decode_json(scalar share('shark.json')->slurp);
|
||||
|
||||
handle query_lc => sub {
|
||||
return unless $_ =~ /^shark week(?: schedule|)$/;
|
||||
my $dt = DateTime->today();
|
||||
my $key = $dt->day_name.' '.$dt->month_name . ' '.$dt->day;
|
||||
my @episodes = @{$schedule->{$key}};
|
||||
# return scalar(@episodes);
|
||||
|
||||
my $html = "<ul>";
|
||||
my $txt = "$key Schedule\n";
|
||||
foreach my $e (@episodes) {
|
||||
my $time = $e->{'time'};
|
||||
my $title = $e->{'title'};
|
||||
my $description = $e->{'description'};
|
||||
$html .= "<li>$time - $title</li>";
|
||||
$txt .= "$time | $title\n";
|
||||
}
|
||||
$html .= "</ul>";
|
||||
|
||||
return $txt, html => $html, heading => "$key Schedule";
|
||||
};
|
||||
|
||||
1;
|
|
@ -0,0 +1,64 @@
|
|||
package DDG::Goodie::Shortcut;
|
||||
# ABSTRACT: Display keyboard shortcut for an action.
|
||||
|
||||
use DDG::Goodie;
|
||||
|
||||
triggers any => 'shortcut','keyboard shortcut', 'key combination';
|
||||
|
||||
zci answer_type => 'shortcut';
|
||||
|
||||
primary_example_queries 'windows show desktop shortcut';
|
||||
secondary_example_queries 'ubuntu shortcut new folder';
|
||||
description 'Keyboard shortcuts';
|
||||
name 'Shortcut';
|
||||
topics 'computing';
|
||||
category 'computing_info';
|
||||
attribution github => ['https://github.com/dariog88a','dariog88a'],
|
||||
email => [ 'mailto:dariog88@gmail.com', 'dariog88' ],
|
||||
twitter => ['http://twitter.com/dariog88','dariog88'];
|
||||
|
||||
my @shortcuts = share('shortcuts.csv')->slurp(iomode => '<:encoding(UTF-8)');
|
||||
|
||||
handle remainder_lc => sub {
|
||||
#keep only letters and spaces (remove versioning)
|
||||
s/[^a-z ]//gi;
|
||||
#replace all OS words with starting char
|
||||
s/windows|win|xp|vista|seven|eight/W/gi;
|
||||
s/mac|os[ ]*x/M/gi;
|
||||
s/linux|ubuntu|debian|fedora|kde|gnome/L/gi;
|
||||
|
||||
#get OS char (if any)
|
||||
my $search = $_;
|
||||
$search =~ /(W|M|L)/;
|
||||
my $os = $1; #save OS char
|
||||
$search =~ tr/[WML]//d; #remove all OS chars from search
|
||||
$search =~ tr/ / /s; #leave just one blank between words
|
||||
$search =~ s/^\s+|\s+$//g; #trim
|
||||
|
||||
if(!$os) {$os='';} #line added to avoid error, remove when UA detection added.
|
||||
|
||||
my $line;
|
||||
foreach (@shortcuts) {
|
||||
if($_ =~ /^$search/i) { #matches only the start
|
||||
$line = $_;
|
||||
$line =~ s/\R//g; #remove carriage return
|
||||
last;
|
||||
}
|
||||
}
|
||||
|
||||
return if !$line;
|
||||
|
||||
my @columns = split('\|',$line);
|
||||
my $answer = 'The shortcut for ' . $columns[0];
|
||||
my %systems = (W=>'Windows',M=>'Mac OS',L=>'KDE/GNOME');
|
||||
my %keys = (W => $columns[1], M => $columns[2], L => $columns[3]);
|
||||
|
||||
return if !$keys{$os};
|
||||
|
||||
if ($os) { $answer .= ' in ' . $systems{$os} . ' is ' . $keys{$os}; }
|
||||
|
||||
my $source = '<br/><a href="https://en.wikipedia.org/wiki/Table_of_keyboard_shortcuts">More at Wikipedia</a>';
|
||||
return $answer, html => "$answer $source";
|
||||
};
|
||||
|
||||
1;
|
|
@ -7,7 +7,7 @@ use warnings;
|
|||
use DDG::Goodie;
|
||||
|
||||
# TODO: This (sh|c)ould be re-written to be more precise
|
||||
triggers query => qr`^([0-9]{1,3}\.){3}([0-9]{1,3})[\s/](([1-3]?[0-9])|(([0-9]{1,3}\.){3}([0-9]{1,3})))$`;
|
||||
triggers query => qr#^([0-9]{1,3}\.){3}([0-9]{1,3})[\s/](([1-3]?[0-9])|(([0-9]{1,3}\.){3}([0-9]{1,3})))$#;
|
||||
|
||||
zci answer_type => "subnet_info";
|
||||
zci is_cached => 1;
|
||||
|
@ -20,78 +20,110 @@ category 'computing_tools';
|
|||
topics 'sysadmin';
|
||||
|
||||
handle query => sub {
|
||||
sub int_to_str($) {
|
||||
my ($ip) = @_;
|
||||
return sprintf "%u.%u.%u.%u", ($ip>>24&0xff),($ip>>16&0xff),($ip>>8&0xff),($ip&0xff);
|
||||
}
|
||||
sub ip_to_int(@) {
|
||||
return (int($_[0])<<24) + (int($_[1])<<16) + (int($_[2])<<8) + (int($_[3]));
|
||||
}
|
||||
# Convert an integer into an IP address.
|
||||
sub int_to_str {
|
||||
my ($ip) = @_;
|
||||
sprintf "%u.%u.%u.%u", $ip >> 24 & 0xff, $ip >> 16 & 0xff, $ip >> 8 & 0xff, $ip & 0xff;
|
||||
}
|
||||
|
||||
my ($input) = @_;
|
||||
my ($address,$cidr) = split qr`[\s/]`, $input;
|
||||
|
||||
my @octlets = split /\./,$address;
|
||||
for (@octlets) {
|
||||
return if int($_)>255;
|
||||
}
|
||||
# Convert an IP address into an integer.
|
||||
sub ip_to_int {
|
||||
(int($_[0]) << 24) + (int($_[1]) << 16) + (int($_[2]) << 8) + int($_[3]);
|
||||
}
|
||||
|
||||
my $address_raw = ip_to_int(@octlets);
|
||||
my $wildcard_mask = 0;
|
||||
my $mask = 0;
|
||||
my ($input) = @_;
|
||||
my ($address, $cidr) = split qr`[\s/]`, $input;
|
||||
|
||||
my @octlets = split /\./, $address;
|
||||
for (@octlets) {
|
||||
return if int($_) > 255;
|
||||
}
|
||||
|
||||
# Convert CIDR & Subnets
|
||||
if ($cidr =~ /^[0-9]+$/) {
|
||||
return if ($cidr>32 || $cidr<1);
|
||||
$wildcard_mask = 2**(32-$cidr)-1;
|
||||
$mask = 0xffffffff ^ $wildcard_mask;
|
||||
}
|
||||
elsif ($cidr =~ /([0-9]{1,3}\.){3}([0-9]{1,3})/) {
|
||||
my @cidr_octlets = split /\./,$cidr;
|
||||
for(@cidr_octlets) {
|
||||
return if int($_)>255;
|
||||
}
|
||||
|
||||
$mask = ip_to_int(@cidr_octlets);
|
||||
my $mask_binary = sprintf("%b",$mask);
|
||||
return unless ($mask_binary =~ /^1+0*$/);
|
||||
$wildcard_mask = 0xffffffff ^ $mask;
|
||||
$cidr = ($mask_binary =~ tr/1//); #count number of 1's
|
||||
}
|
||||
else {
|
||||
return;
|
||||
}
|
||||
|
||||
my $host = $address_raw & $wildcard_mask;
|
||||
my $network = $address_raw & $mask;
|
||||
|
||||
my $start = $network+1;
|
||||
my $end = $network+($wildcard_mask-1);
|
||||
my $broadcast = $network+$wildcard_mask;
|
||||
my $host_count = 1+$end-$start;
|
||||
|
||||
my $class = "A";
|
||||
$class = "E (reserved)" if (($network>>28 & 0x0F) == 0x0F);
|
||||
$class = "D (multicast)" if (($network>>28 & 0x0F) == 0x0E);
|
||||
$class = "C" if (($network>>29 & 0x07) == 0x06);
|
||||
$class = "B" if (($network>>30 & 0x03) == 0x02);
|
||||
|
||||
my $which_specified = "Host #".($host);
|
||||
$which_specified = "Network" if ($host==0);
|
||||
$which_specified = "Broadcast" if ($host==$host_count+1);
|
||||
$which_specified = "Point-To-Point (".int_to_str($end).", ".int_to_str($start).")" if ($cidr==31);
|
||||
$which_specified = "Host Only" if ($cidr==32);
|
||||
|
||||
my $output_str = "Network: ".int_to_str($network)."/$cidr,".
|
||||
" Netmask: ".int_to_str($mask).",".
|
||||
" $which_specified specified,".
|
||||
" Class: $class";
|
||||
$output_str .= ", Host Address Range: ".int_to_str($start)."-".int_to_str($end).",".
|
||||
" $host_count Usable Addresses,".
|
||||
" Broadcast: ".int_to_str($broadcast)
|
||||
unless($cidr > 30);
|
||||
return $output_str;
|
||||
my $address_raw = ip_to_int(@octlets);
|
||||
my $wildcard_mask = 0;
|
||||
my $mask = 0;
|
||||
|
||||
# Convert CIDR & Subnets
|
||||
if ($cidr =~ /^[0-9]+$/) {
|
||||
return if ($cidr > 32 || $cidr < 1);
|
||||
$wildcard_mask = 2**(32-$cidr) - 1;
|
||||
|
||||
# Flip the bits.
|
||||
$mask = 0xffffffff ^ $wildcard_mask;
|
||||
} elsif ($cidr =~ /([0-9]{1,3}\.){3}([0-9]{1,3})/) {
|
||||
my @cidr_octlets = split /\./, $cidr;
|
||||
|
||||
# An octlet cannot be over 255.
|
||||
for(@cidr_octlets) {
|
||||
return if int($_) > 255;
|
||||
}
|
||||
|
||||
$mask = ip_to_int(@cidr_octlets);
|
||||
# Convert the integer into its binary representation.
|
||||
my $mask_binary = sprintf("%b", $mask);
|
||||
|
||||
# The mask cannot have alternating 1s and 0s.
|
||||
return unless ($mask_binary =~ /^1+0*$/);
|
||||
|
||||
# Flip the bits.
|
||||
$wildcard_mask = 0xffffffff ^ $mask;
|
||||
|
||||
# Count the number of 1s.
|
||||
$cidr = ($mask_binary =~ tr/1//);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
my $host = $address_raw & $wildcard_mask;
|
||||
my $network = $address_raw & $mask;
|
||||
|
||||
my $start = $network + 1;
|
||||
my $end = $network + ($wildcard_mask - 1);
|
||||
my $broadcast = $network + $wildcard_mask;
|
||||
my $host_count = 1 + $end - $start;
|
||||
|
||||
# Check the class type of the IP address.
|
||||
my $class = "A";
|
||||
$class = "E (reserved)" if (($network >> 28 & 0x0F) == 0x0F);
|
||||
$class = "D (multicast)" if (($network >> 28 & 0x0F) == 0x0E);
|
||||
$class = "C" if (($network >> 29 & 0x07) == 0x06);
|
||||
$class = "B" if (($network >> 30 & 0x03) == 0x02);
|
||||
|
||||
my $which_specified = "Host #".($host);
|
||||
$which_specified = "Network" if ($host == 0);
|
||||
$which_specified = "Broadcast" if ($host == $host_count+1);
|
||||
$which_specified = "Point-To-Point (".int_to_str($end).", ".int_to_str($start).")" if ($cidr == 31);
|
||||
$which_specified = "Host Only" if ($cidr == 32);
|
||||
|
||||
sub to_html {
|
||||
my $results = "";
|
||||
foreach my $result (@_) {
|
||||
$results .= "<div><i>$result->[0]: </i>$result->[1]</div>";
|
||||
}
|
||||
return $results;
|
||||
}
|
||||
|
||||
sub to_text {
|
||||
my $results = "";
|
||||
foreach my $result (@_) {
|
||||
$results .= "$result->[0]: $result->[1]\n";
|
||||
}
|
||||
return $results;
|
||||
}
|
||||
|
||||
# We're putting them into an array because we want the output to be sorted.
|
||||
my @output = (
|
||||
["Network", int_to_str($network) . "/$cidr (Class $class)"],
|
||||
["Netmask", int_to_str($mask)],
|
||||
["Specified", "$which_specified"],
|
||||
);
|
||||
|
||||
unless($cidr > 30) {
|
||||
push @output, (["Host Address Range", int_to_str($start) . "-" . int_to_str($end) . " ($host_count hosts)"],
|
||||
["Broadcast", int_to_str($broadcast)]);
|
||||
}
|
||||
|
||||
return answer => to_text(@output), html => to_html(@output);
|
||||
};
|
||||
|
||||
1;
|
||||
1;
|
||||
|
|
|
@ -5,8 +5,8 @@ use DDG::Goodie;
|
|||
zci is_cached => 1;
|
||||
zci answer_type => "ups";
|
||||
|
||||
primary_example_queries '1Z0884XV0399906189';
|
||||
secondary_example_queries 'ups 1Z0884XV0399906189';
|
||||
primary_example_queries '1Z2807700371226497';
|
||||
secondary_example_queries 'ups 1Z2807700371226497';
|
||||
description 'Track a UPS package';
|
||||
icon_url "/i/www.ups.com.ico";
|
||||
name 'UPS';
|
||||
|
@ -110,4 +110,4 @@ handle query_nowhitespace_nodash => sub {
|
|||
return;
|
||||
};
|
||||
|
||||
1;
|
||||
1;
|
||||
|
|
|
@ -1,326 +0,0 @@
|
|||
862=>NJ, US
|
||||
863=>FL, US
|
||||
864=>SC, US
|
||||
865=>TN, US
|
||||
867=>Yukon, NW Terr., Nunavut, CANADA
|
||||
868=>Trinidad and Tobago, TRINIDAD AND TOBAGO
|
||||
869=>St. Kitts and Nevis, ST. KITTS AND NEVIS
|
||||
870=>AR, US
|
||||
876=>Jamaica, JAMAICA
|
||||
878=>PA, US
|
||||
901=>TN, US
|
||||
902=>Nova Scotia, Prince Edward Island, CANADA
|
||||
903=>TX, US
|
||||
904=>FL, US
|
||||
905=>Ontario, CANADA
|
||||
906=>MI, US
|
||||
907=>AK, US
|
||||
908=>NJ, US
|
||||
909=>CA, US
|
||||
910=>NC, US
|
||||
912=>GA, US
|
||||
913=>KS, US
|
||||
914=>NY, US
|
||||
915=>TX, US
|
||||
916=>CA, US
|
||||
917=>NY, US
|
||||
918=>OK, US
|
||||
919=>NC, US
|
||||
920=>WI, US
|
||||
925=>CA, US
|
||||
928=>AZ, US
|
||||
931=>TN, US
|
||||
936=>TX, US
|
||||
937=>OH, US
|
||||
939=>Puerto Rico, US
|
||||
940=>TX, US
|
||||
941=>FL, US
|
||||
947=>MI, US
|
||||
949=>CA, US
|
||||
951=>CA, US
|
||||
952=>MN, US
|
||||
954=>FL, US
|
||||
956=>TX, US
|
||||
970=>CO, US
|
||||
971=>OR, US
|
||||
972=>TX, US
|
||||
973=>NJ, US
|
||||
978=>MA, US
|
||||
979=>TX, US
|
||||
980=>NC, US
|
||||
985=>LA, US
|
||||
989=>MI, US
|
||||
682=>TX, US
|
||||
684=>AS, US
|
||||
701=>ND, US
|
||||
702=>NV, US
|
||||
703=>VA, US
|
||||
704=>NC, US
|
||||
705=>Ontario, CANADA
|
||||
706=>GA, US
|
||||
707=>CA, US
|
||||
708=>IL, US
|
||||
709=>Newfoundland, CANADA
|
||||
710=>US, US
|
||||
712=>IA, US
|
||||
713=>TX, US
|
||||
714=>CA, US
|
||||
715=>WI, US
|
||||
716=>NY, US
|
||||
717=>PA, US
|
||||
718=>NY, US
|
||||
719=>CO, US
|
||||
720=>CO, US
|
||||
724=>PA, US
|
||||
727=>FL, US
|
||||
731=>TN, US
|
||||
732=>NJ, US
|
||||
734=>MI, US
|
||||
740=>OH, US
|
||||
754=>FL, US
|
||||
757=>VA, US
|
||||
758=>St. Lucia, ST. LUCIA
|
||||
760=>CA, US
|
||||
762=>GA, US
|
||||
763=>MN, US
|
||||
765=>IN, US
|
||||
767=>Dominica, DOMINICA
|
||||
769=>MS, US
|
||||
770=>GA, US
|
||||
772=>FL, US
|
||||
773=>IL, US
|
||||
774=>MA, US
|
||||
775=>NV, US
|
||||
778=>British Columbia, CANADA
|
||||
779=>IL, US
|
||||
780=>Alberta, CANADA
|
||||
781=>MA, US
|
||||
784=>St. Vincent and the Grenadines, ST. VINCENT & GRENADINES
|
||||
785=>KS, US
|
||||
786=>FL, US
|
||||
787=>Puerto Rico, US
|
||||
801=>UT, US
|
||||
802=>VT, US
|
||||
803=>SC, US
|
||||
804=>VA, US
|
||||
805=>CA, US
|
||||
806=>TX, US
|
||||
807=>Ontario, CANADA
|
||||
808=>HI, US
|
||||
809=>the Dominican Republic, DOMINICAN REPUBLIC
|
||||
810=>MI, US
|
||||
812=>IN, US
|
||||
813=>FL, US
|
||||
814=>PA, US
|
||||
815=>IL, US
|
||||
816=>MO, US
|
||||
817=>TX, US
|
||||
818=>CA, US
|
||||
819=>Quebec, CANADA
|
||||
828=>NC, US
|
||||
829=>the Dominican Republic, DOMINICAN REPUBLIC
|
||||
830=>TX, US
|
||||
831=>CA, US
|
||||
832=>TX, US
|
||||
843=>SC, US
|
||||
845=>NY, US
|
||||
847=>IL, US
|
||||
848=>NJ, US
|
||||
850=>FL, US
|
||||
856=>NJ, US
|
||||
857=>MA, US
|
||||
858=>CA, US
|
||||
859=>KY, US
|
||||
860=>CT, US
|
||||
574=>IN, US
|
||||
575=>NM, US
|
||||
580=>OK, US
|
||||
585=>NY, US
|
||||
586=>MI, US
|
||||
601=>MS, US
|
||||
602=>AZ, US
|
||||
603=>NH, US
|
||||
604=>British Columbia, CANADA
|
||||
605=>SD, US
|
||||
606=>KY, US
|
||||
607=>NY, US
|
||||
608=>WI, US
|
||||
609=>NJ, US
|
||||
610=>PA, US
|
||||
201=>NJ, US
|
||||
202=>DC, US
|
||||
203=>CT, US
|
||||
204=>Manitoba, CANADA
|
||||
205=>AL, US
|
||||
206=>WA, US
|
||||
207=>ME, US
|
||||
208=>ID, US
|
||||
209=>CA, US
|
||||
210=>TX, US
|
||||
212=>NY, US
|
||||
213=>CA, US
|
||||
214=>TX, US
|
||||
215=>PA, US
|
||||
216=>OH, US
|
||||
217=>IL, US
|
||||
218=>MN, US
|
||||
219=>IN, US
|
||||
224=>IL, US
|
||||
225=>LA, US
|
||||
226=>Ontario, CANADA
|
||||
228=>MS, US
|
||||
229=>GA, US
|
||||
231=>MI, US
|
||||
234=>OH, US
|
||||
239=>FL, US
|
||||
240=>MD, US
|
||||
242=>the Bahamas, BAHAMAS
|
||||
246=>Barbados, BARBADOS
|
||||
248=>MI, US
|
||||
250=>British Columbia, CANADA
|
||||
251=>AL, US
|
||||
252=>NC, US
|
||||
253=>WA, US
|
||||
254=>TX, US
|
||||
256=>AL, US
|
||||
260=>IN, US
|
||||
262=>WI, US
|
||||
264=>Anguilla, ANGUILLA
|
||||
267=>PA, US
|
||||
268=>Antigua and Barbuda, ANTIGUA/BARBUDA
|
||||
269=>MI, US
|
||||
270=>KY, US
|
||||
276=>VA, US
|
||||
281=>TX, US
|
||||
284=>the British Virgin Islands, BRITISH VIRGIN ISLANDS
|
||||
289=>Ontario, CANADA
|
||||
301=>MD, US
|
||||
302=>DE, US
|
||||
303=>CO, US
|
||||
304=>WV, US
|
||||
305=>FL, US
|
||||
306=>Saskatchewan, CANADA
|
||||
307=>WY, US
|
||||
308=>NE, US
|
||||
309=>IL, US
|
||||
310=>CA, US
|
||||
312=>IL, US
|
||||
313=>MI, US
|
||||
314=>MO, US
|
||||
315=>NY, US
|
||||
316=>KS, US
|
||||
317=>IN, US
|
||||
318=>LA, US
|
||||
319=>IA, US
|
||||
320=>MN, US
|
||||
321=>FL, US
|
||||
323=>CA, US
|
||||
325=>TX, US
|
||||
330=>OH, US
|
||||
331=>IL, US
|
||||
334=>AL, US
|
||||
336=>NC, US
|
||||
337=>LA, US
|
||||
339=>MA, US
|
||||
340=>the US Virgin Islands, US
|
||||
345=>the Cayman Islands, CAYMAN ISLANDS
|
||||
347=>NY, US
|
||||
351=>MA, US
|
||||
352=>FL, US
|
||||
360=>WA, US
|
||||
361=>TX, US
|
||||
386=>FL, US
|
||||
401=>RI, US
|
||||
402=>NE, US
|
||||
403=>Alberta, CANADA
|
||||
404=>GA, US
|
||||
405=>OK, US
|
||||
406=>MT, US
|
||||
407=>FL, US
|
||||
408=>CA, US
|
||||
409=>TX, US
|
||||
410=>MD, US
|
||||
412=>PA, US
|
||||
413=>MA, US
|
||||
414=>WI, US
|
||||
415=>CA, US
|
||||
416=>Ontario, CANADA
|
||||
417=>MO, US
|
||||
418=>Quebec, CANADA
|
||||
419=>OH, US
|
||||
423=>TN, US
|
||||
424=>CA, US
|
||||
425=>WA, US
|
||||
430=>TX, US
|
||||
432=>TX, US
|
||||
434=>VA, US
|
||||
435=>UT, US
|
||||
438=>Quebec, CANADA
|
||||
440=>OH, US
|
||||
441=>Bermuda, BERMUDA
|
||||
443=>MD, US
|
||||
450=>Quebec, CANADA
|
||||
469=>TX, US
|
||||
473=>Grenada, GRENADA
|
||||
478=>GA, US
|
||||
479=>AR, US
|
||||
480=>AZ, US
|
||||
484=>PA, US
|
||||
501=>AR, US
|
||||
502=>KY, US
|
||||
503=>OR, US
|
||||
504=>LA, US
|
||||
505=>NM, US
|
||||
506=>New Brunswick, CANADA
|
||||
507=>MN, US
|
||||
508=>MA, US
|
||||
509=>WA, US
|
||||
510=>CA, US
|
||||
512=>TX, US
|
||||
513=>OH, US
|
||||
514=>Quebec, CANADA
|
||||
515=>IA, US
|
||||
516=>NY, US
|
||||
517=>MI, US
|
||||
518=>NY, US
|
||||
519=>Ontario, CANADA
|
||||
520=>AZ, US
|
||||
530=>CA, US
|
||||
540=>VA, US
|
||||
541=>OR, US
|
||||
551=>NJ, US
|
||||
559=>CA, US
|
||||
561=>FL, US
|
||||
562=>CA, US
|
||||
563=>IA, US
|
||||
567=>OH, US
|
||||
570=>PA, US
|
||||
571=>VA, US
|
||||
573=>MO, US
|
||||
612=>MN, US
|
||||
613=>Ontario, CANADA
|
||||
614=>OH, US
|
||||
615=>TN, US
|
||||
616=>MI, US
|
||||
617=>MA, US
|
||||
618=>IL, US
|
||||
619=>CA, US
|
||||
620=>KS, US
|
||||
623=>AZ, US
|
||||
626=>CA, US
|
||||
630=>IL, US
|
||||
631=>NY, US
|
||||
636=>MO, US
|
||||
641=>IA, US
|
||||
646=>NY, US
|
||||
647=>Ontario, CANADA
|
||||
649=>the Turks and Caicos Islands, TURKS & CAICOS ISLANDS
|
||||
650=>CA, US
|
||||
651=>MN, US
|
||||
660=>MO, US
|
||||
661=>CA, US
|
||||
662=>MS, US
|
||||
664=>Montserrat, MONTSERRAT
|
||||
671=>GU, US
|
||||
678=>GA, US
|
||||
959=>CT, US
|
|
@ -1,51 +0,0 @@
|
|||
AL=>Alabama
|
||||
AK=>Alaska
|
||||
AZ=>Arizona
|
||||
AR=>Arkansas
|
||||
CA=>California
|
||||
CO=>Colorado
|
||||
CT=>Connecticut
|
||||
DE=>Delaware
|
||||
DC=>District of Columbia
|
||||
FL=>Florida
|
||||
GA=>Georgia
|
||||
HI=>Hawaii
|
||||
ID=>Idaho
|
||||
IL=>Illinois
|
||||
IN=>Indiana
|
||||
IA=>Iowa
|
||||
KS=>Kansas
|
||||
KY=>Kentucky
|
||||
LA=>Louisiana
|
||||
ME=>Maine
|
||||
MD=>Maryland
|
||||
MA=>Massachusetts
|
||||
MI=>Michigan
|
||||
MN=>Minnesota
|
||||
MS=>Mississippi
|
||||
MO=>Missouri
|
||||
MT=>Montana
|
||||
NE=>Nebraska
|
||||
NV=>Nevada
|
||||
NH=>New Hampshire
|
||||
NJ=>New Jersey
|
||||
NM=>New Mexico
|
||||
NY=>New York
|
||||
NC=>North Carolina
|
||||
ND=>North Dakota
|
||||
OH=>Ohio
|
||||
OK=>Oklahoma
|
||||
OR=>Oregon
|
||||
PA=>Pennsylvania
|
||||
RI=>Rhode Island
|
||||
SC=>South Carolina
|
||||
SD=>South Dakota
|
||||
TN=>Tennessee
|
||||
TX=>Texas
|
||||
UT=>Utah
|
||||
VT=>Vermont
|
||||
VA=>Virginia
|
||||
WA=>Washington
|
||||
WV=>West Virginia
|
||||
WI=>Wisconsin
|
||||
WY=>Wyoming
|
File diff suppressed because one or more lines are too long
|
@ -1,4 +0,0 @@
|
|||
Monday August 5
|
||||
Sharkbite Summer 3:00 PM The bite-by-bite account of America's notorious "Summer of the Shark" in 2001. Were the Ocean's apex predators really taking back America's shores?
|
||||
Sharkbite Beach 4:00 PM In the summer of 2008, panic gripped the Pacific coast in the wake of 4 horrific shark attacks. Sharkbite Beach reveals the dramatic stories of survival and searches for clues that might explain why sharks turned on humans with such fury.
|
||||
Rogue Sharks 5:00 PM The existence of man eating 'rogue' sharks has been hotly debated since the 1950s. This film unravels the truth behind the theory by analyzing some of the most notorious attacks from the last century and consulting the leading experts on shark biology.
|
|
@ -0,0 +1,78 @@
|
|||
File menu|Alt+F, or F10 then F|Ctrl+F2, then F (requires full keyboard access active, using System Preferences > Keyboard > Keyboard Shortcuts > Full Keyboard Access > All Controls. Alternatively use Ctrl+F1 to toggle this setting.)|Alt+F
|
||||
Edit menu|Alt+E|Ctrl+F2, then E|Alt+E
|
||||
View menu|Alt+V|Ctrl+F2, then V|Alt+V
|
||||
Undo|Ctrl+Z, or Alt+←Backspace|⌘Cmd+Z|Ctrl+Z
|
||||
Redo|Ctrl+Y|⇧Shift+⌘Cmd+Z|⇧Shift+Ctrl+Z, or Ctrl+Y
|
||||
Cut|Ctrl+X, or ⇧Shift+Del|⌘Cmd+X|Ctrl+X
|
||||
Copy|Ctrl+C, or Ctrl+Ins|⌘Cmd+C|Ctrl+C
|
||||
Paste|Ctrl+V, or ⇧Shift+Ins|⌘Cmd+V|Ctrl+V
|
||||
Paste special|Ctrl+Alt+V||Ctrl+⇧Shift+V
|
||||
Select all|Ctrl+A|⌘Cmd+A|Ctrl+A
|
||||
New folder|Ctrl+⇧Shift+N|⇧Shift+⌘Cmd+N|Ctrl+⇧Shift+N
|
||||
Applications menu|⊞Win or Ctrl+Esc||Alt + "n" e.g. for _File_ Alt + F
|
||||
Lock desktop|⊞Win+L|Ctrl+⇧Shift+Eject or MBR Ctrl+⇧Shift+Pwr (If "Require password after sleep or screen saver" is enabled in "System Preferences — Security & Privacy")|Ctrl+Alt+L
|
||||
Show desktop|⊞Win+D or ⊞Win+M (then use ⊞Win+⇧Shift+M to bring back all windows)|F11|Ctrl+Alt+D
|
||||
Log out user||⇧Shift+⌘Cmd+Q|Ctrl+Alt+Delete
|
||||
Switch user|⊞Win+L||
|
||||
Task manager|Ctrl+⇧Shift+Esc or Ctrl+Alt+Delete|Alt+⌘Cmd+Esc|Ctrl+Esc
|
||||
Rename object|F2|↵Enter|F2
|
||||
Open file or program|↵Enter|⌘Cmd+O|↵Enter
|
||||
Switch window (next/previous)|Alt+Tab↹ / ⇧Shift+Alt+Tab↹|⌘Cmd+Tab↹ / ⇧Shift+⌘Cmd+Tab↹|Alt+Tab↹ / Alt+⇧Shift+Tab↹
|
||||
Switch window without dialog (next/previous)|Alt+Esc / ⇧Shift+Alt+Esc|⌘Cmd+` / ⌘Cmd+~ Only works within single Applications|
|
||||
Run application|⊞Win, enter executable name or ⊞Win+R, enter executable name|⌘Cmd+Space, enter executable name|Alt+F2, enter executable name
|
||||
Search|⊞Win, enter search or ⊞Win+F|⌘Cmd+Space / Alt+F |
|
||||
Save screenshot of entire screen as file|Windows+Print Screen|⇧Shift+⌘Cmd+3|Print Screen set the name and click "Save".
|
||||
Copy screenshot of entire screen to clipboard|Print Screen or Ctrl+Print Screen|Ctrl+⇧Shift+⌘Cmd+3|Print Screen click "Copy to Clipboard".
|
||||
Save screenshot of window as file||⇧Shift+⌘Cmd+4 then Space|Alt+Print Screen set the name and click "Save". GNOME
|
||||
Copy screenshot of window to clipboard|Alt+Print Screen|Ctrl+⇧Shift+⌘Cmd+4 then Space|Alt+Print Screen click "Copy to Clipboard". GNOME
|
||||
Delete char to the right of cursor|Del or Fn+←Backspace|Del, or Ctrl+d, or Fn+←Backspace |
|
||||
Delete word to the right of cursor|Ctrl+Del|⌥Opt+Del or ⌥Opt+Fn+←Backspace|Ctrl+Del
|
||||
Delete word to the left of cursor|Ctrl+←Backspace|⌥Opt+←Backspace|Ctrl+←Backspace
|
||||
Start of line|Home, or Fn+←|⌘Cmd+← or Ctrl+A|Home
|
||||
End of line|End, or Fn+→|⌘Cmd+→ or Ctrl+E|End
|
||||
Start of document|Ctrl + Home|⌘Cmd+↑|Ctrl + Home
|
||||
End of document|Ctrl + End|⌘Cmd+↓|Ctrl + End
|
||||
Previous word|Ctrl+←|⌥Opt+←|Ctrl+←
|
||||
Next word|Ctrl+→|⌥Opt+→|Ctrl+→
|
||||
Previous line|↑|↑, or Ctrl+p|↑
|
||||
Next line|↓|↓, or Ctrl+n|↓
|
||||
Previous line break (paragraph)|Ctrl+↑|⌥Opt+↑|Ctrl+↑ (kword or GNOME)
|
||||
Next line break|Ctrl+↓|⌥Opt+↓|Ctrl+↓ (kword or GNOME)
|
||||
Move the cursor down the length of the viewport|Page Down|Fn+↓|Page Down
|
||||
Move the cursor up the length of the viewport|Page Up|Fn+↑|Page Up
|
||||
Find|Ctrl+F|⌘Cmd+F, ⌘Cmd+E (Search with current selection)|Ctrl+F, Ctrl+K (GNOME; interactive search)
|
||||
Next search result|F3|⌘Cmd+G|Ctrl+G (GNOME) or F3 (KDE)
|
||||
Previous search result|⇧Shift+F3|⇧Shift+⌘Cmd+G|⇧Shift+Ctrl+G (GNOME) or ⇧Shift+F3 (KDE)
|
||||
Search and replace|Ctrl+H|⌘Cmd+F|Ctrl+H (GNOME) or Ctrl+R (KDE)
|
||||
Bold|Ctrl+B|⌘Cmd+B|Ctrl+B
|
||||
Underline|Ctrl+U|⌘Cmd+U|Ctrl+U
|
||||
Italic|Ctrl+I|⌘Cmd+I|Ctrl+I
|
||||
Uppercase|⇧Shift+F3|⌥Opt+⌘Cmd+C|⇧Shift+F3
|
||||
Lowercase|⇧Shift+F3|⌥Opt+⌘Cmd+C|⇧Shift+F3
|
||||
Superscript|Ctrl+⇧Shift++|Ctrl+⌘Cmd++ (Pages and Adobe Applications only?)|Ctrl+⇧Shift+P
|
||||
Subscript|Ctrl+=|Ctrl+⌘Cmd+- (Pages and Adobe Applications only?)|Ctrl+⇧Shift+B
|
||||
Previous location in history|Alt+← or ←Backspace|⌘Cmd+ ⌘Cmd+←|Alt+←
|
||||
Next location in history|Alt+→ or ⇧Shift+←Backspace (web browser only)|⌘Cmd+] or ⌘Cmd+→|Alt+→
|
||||
Go up one level in the navigation hierarchy|Alt+↑(Vista, 7 or 8 only) or ←Backspace(Windows Explorer)|⌘Cmd+↑|Alt+↑
|
||||
Startup page|Alt+Home|⌘Cmd+Home|Ctrl+Home (KDE) / Alt+Home (GNOME)
|
||||
Bookmarks menu|Ctrl+B|⌘Cmd+B (Firefox)|Alt+B
|
||||
URL Shortcuts (Adds www. + .com)|Ctrl+↵Enter|⌘Cmd+↵Enter (Firefox) or Ctrl+↵Enter (Chrome)|Ctrl+↵Enter
|
||||
URL Shortcuts (Adds www. + .org)|Ctrl+⇧Shift+↵Enter|⇧Shift+⌘Cmd+↵Enter (Firefox)|Ctrl+⇧Shift+↵Enter
|
||||
URL Shortcuts (Adds www. + .net)|⇧Shift +↵Enter|⇧Shift +↵Enter (Firefox)|⇧Shift +↵Enter
|
||||
Bookmark page|Ctrl+D|⌘Cmd+D|Ctrl+B / Ctrl+D
|
||||
Manage bookmarks|Ctrl+B|⌘Cmd+⌥Opt+B (Chrome/Safari) or ⌘Cmd+⇧Shift+B (Firefox)|Ctrl+⇧Shift+R / Ctrl+B
|
||||
Address bar|Ctrl+L or F6 or Alt+D|⌘Cmd+L|Ctrl+L or Alt+D or F6
|
||||
Search bar|Ctrl+E|⌘Cmd+E (Opera) or ⌘Cmd+K (Firefox) or ⌥Opt+⌘Cmd+F (Safari)|Ctrl+K
|
||||
Refresh a webpage|F5 or Ctrl+R|⌘Cmd+R|F5 or Ctrl+R
|
||||
New window|Ctrl+N|⌘Cmd+N (Chrome)|Ctrl+N
|
||||
Zoom in|Ctrl++|⌘Cmd++|Ctrl++
|
||||
Zoom out|Ctrl+-|⌘Cmd+-|Ctrl+-
|
||||
Zoom 100%|Ctrl+0|⌘Cmd+0|Ctrl+0
|
||||
New tab|Ctrl+T|⌘Cmd+T|Ctrl+⇧Shift+N or Ctrl+⇧Shift+T or Ctrl+T
|
||||
Close tab|Ctrl+W|⌘Cmd+W|Ctrl+W or Ctrl+F4
|
||||
Close other tabs||⌘Cmd+⌥Opt+W (Safari)|
|
||||
Next tab|Ctrl+Tab↹|Control+Tab↹ or ⌘Cmd+⇧Shift+→ (Safari)|Ctrl+PageDown or Ctrl+Tab↹ or Ctrl+.
|
||||
Previous tab|Ctrl+⇧Shift+Tab↹|⇧Shift+Control+Tab↹ or ⌘Cmd+⇧Shift+← (Safari)|Ctrl+PageUp or Ctrl+⇧Shift+Tab↹ or Ctrl+,
|
||||
Go to tab-n|Ctrl+n (Chrome/Firefox)|⌘Cmd+n (Chrome)|Alt+n (Chrome/Firefox) or Ctrl+n (Chrome)
|
||||
Reopen closed tab|Ctrl+⇧Shift+T|⌘Cmd+⇧Shift+T (Firefox/Opera/Chrome)|Ctrl+⇧Shift+T (Firefox/Opera/Chrome)
|
||||
Reopen closed window|Ctrl+⇧Shift+N (Firefox)| |
|
Can't render this file because it contains an unexpected character in line 12 and column 45.
|
2
t/Coin.t
2
t/Coin.t
|
@ -18,6 +18,8 @@ ddg_goodie_test(
|
|||
'toss a coin' => test_zci(qr/(heads|tails) \(random\)/),
|
||||
'toss 1 coin' => test_zci(qr/(heads|tails) \(random\)/),
|
||||
'toss 2 coins' => test_zci(qr/(heads|tails), (heads|tails) \(random\)/),
|
||||
'heads or tails' => test_zci(qr/(heads|tails) \(random\)/),
|
||||
'heads or tails?' => test_zci(qr/(heads|tails) \(random\)/),
|
||||
);
|
||||
|
||||
done_testing;
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
#!/usr/bin/env perl
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use Test::More;
|
||||
use DDG::Test::Goodie;
|
||||
|
||||
zci answer_type => 'dessert';
|
||||
zci is_cached => 0;
|
||||
|
||||
ddg_goodie_test(
|
||||
[qw(
|
||||
DDG::Goodie::Dessert
|
||||
)],
|
||||
'desserts beginning with a' => test_zci( qr/(.*?) is a dessert that begins with the letter A.$/ ),
|
||||
'dessert start with a' => test_zci( qr/(.*?) is a dessert that begins with the letter A.$/ ),
|
||||
'desserts starting with a' => test_zci( qr/(.*?) is a dessert that begins with the letter A$./ ),
|
||||
'dessert starts with a' => test_zci( qr/(.*?) is a dessert that begins with the letter A.$/ ),
|
||||
|
||||
'desserts beginning with A' => test_zci( qr/(.*?) is a dessert that begins with the letter A.$/ ),
|
||||
'desserts beginning with z' => test_zci( qr/(.*?) is a dessert that begins with the letter Z.$/ ),
|
||||
'a dessert that begins with the letter a' => test_zci( qr/(.*?) is a dessert that begins with the letter A.$/ ),
|
||||
);
|
||||
|
||||
done_testing;
|
|
@ -14,10 +14,10 @@ ddg_goodie_test(
|
|||
)],
|
||||
'dewey 123' => test_zci("123 is determinism and indeterminism in the Dewey Decimal System.", html => "123 is <a href=\"/?q=determinism\">determinism</a> and <a href=\"/?q=indeterminism\">indeterminism</a> in the Dewey Decimal System."),
|
||||
'646 dewey decimal system' => test_zci("646 is sewing, clothing, personal living in the Dewey Decimal System.", html => "646 is <a href=\"/?q=sewing\">sewing</a>, <a href=\"/?q=clothing\">clothing</a>, personal living in the Dewey Decimal System."),
|
||||
'dewey decimal system 640s' => test_zci("", html => '<table><tr><td>641</td><td><a href="/?q=Food">Food</a> & <a href="/?q=drink">drink</a></td></tr><tr><td>642</td><td><a href="/?q=Meal">Meal</a>s & table service</td></tr><tr><td>643</td><td><a href="/?q=House">Housing</a> & household equipment</td></tr><tr><td>644</td><td><a href="/?q=Household">Household</a> utilities</td></tr><tr><td>645</td><td><a href="/?q=Furniture">Household furnishings</a></td></tr><tr><td>646</td><td><a href="/?q=Sewing">Sewing</a>, <a href="/?q=clothing">clothing</a>, personal living</td></tr><tr><td>647</td><td><a href="/?q=Household management">Management of public household</a>s</td></tr><tr><td>648</td><td><a href="/?q=Household chore">Housekeeping</a></td></tr><tr><td>649</td><td><a href="/?q=Child rearing">Child rearing</a> & <a href="/?q=home care">home care</a> of sick</td></tr></table>'),
|
||||
'dewey decimal system 640s' => test_zci("", html => '<table cellpadding=1><tr><td>641</td><td> <a href="/?q=Food">Food</a> & <a href="/?q=drink">drink</a></td></tr><tr><td>642</td><td> <a href="/?q=Meal">Meal</a>s & table service</td></tr><tr><td>643</td><td> <a href="/?q=House">Housing</a> & household equipment</td></tr><tr><td>644</td><td> <a href="/?q=Household">Household</a> utilities</td></tr><tr><td>645</td><td> <a href="/?q=Furniture">Household furnishings</a></td></tr><tr><td>646</td><td> <a href="/?q=Sewing">Sewing</a>, <a href="/?q=clothing">clothing</a>, personal living</td></tr><tr><td>647</td><td> <a href="/?q=Household management">Management of public household</a>s</td></tr><tr><td>648</td><td> <a href="/?q=Household chore">Housekeeping</a></td></tr><tr><td>649</td><td> <a href="/?q=Child rearing">Child rearing</a> & <a href="/?q=home care">home care</a> of sick</td></tr></table>'),
|
||||
'#1 in the dewey decimal system' => test_zci("001 is knowledge in the Dewey Decimal System.", html => '001 is <a href="/?q=outline of knowledge">knowledge</a> in the Dewey Decimal System.'),
|
||||
'dewey decimal system naturalism' => test_zci("146 is naturalism and related systems in the Dewey Decimal System.", html => '146 is <a href="/?q=naturalism (philosophy)">naturalism</a> and related systems in the Dewey Decimal System.'),
|
||||
'etymology in the dewey decimal system' => test_zci("", html => qr{^<table>.*</table>$}),
|
||||
'etymology in the dewey decimal system' => test_zci("", html => qr{^<table cellpadding=1>.*</table>$}),
|
||||
);
|
||||
|
||||
done_testing;
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
#! /usr/bin/env perl
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use Test::More;
|
||||
use DDG::Test::Goodie;
|
||||
|
||||
zci answer_type => 'emailvalidator';
|
||||
zci is_cached => 0;
|
||||
|
||||
ddg_goodie_test(
|
||||
[
|
||||
'DDG::Goodie::EmailValidator'
|
||||
],
|
||||
'validate foo' => undef,
|
||||
'validate my email foo@example.com' => test_zci (qr/seems to be valid/),
|
||||
'validate my email foo+abc@example.com' => test_zci (qr/seems to be valid/),
|
||||
'validate my email foo.bar@example.com' => test_zci (qr/seems to be valid/),
|
||||
'validate user@exampleaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.com' => test_zci (qr/Please check the address/),
|
||||
'validate foo@example.com' => test_zci (qr/seems to be valid/),
|
||||
'validate customer/department=shipping@example.com' => test_zci (qr/seems to be valid/),
|
||||
'validate foo@!!!.com' => test_zci(qr/Please check the fully qualified domain name/),
|
||||
'validate foo@example.xyz' => test_zci(qr/Please check the top-level domain/),
|
||||
);
|
||||
|
||||
done_testing;
|
|
@ -30,7 +30,7 @@ ddg_goodie_test(
|
|||
html => 'Default login for the BELKIN F5D6130:<br><i>Username</i>: (none)<br><i>Password</i>: password'
|
||||
),
|
||||
# You should include more test cases here. Try to think of ways that your
|
||||
# plugin might break, and add them here to ensure they won't. Here are a
|
||||
# instant answer might break, and add them here to ensure they won't. Here are a
|
||||
# few others that were thought of for this goodie.
|
||||
'Belkin f5d6130 password default' =>
|
||||
test_zci('Default login for the BELKIN F5D6130: Username: (none) Password: password',
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
#!/usr/bin/env perl
|
||||
|
||||
use utf8;
|
||||
use strict;
|
||||
use warnings;
|
||||
use Test::More;
|
||||
use DDG::Test::Goodie;
|
||||
|
||||
zci answer_type => 'shortcut';
|
||||
|
||||
my $start = 'The shortcut for ';
|
||||
my $first = 'Show desktop in Windows is ⊞Win+D or ⊞Win+M (then use ⊞Win+⇧Shift+M to bring back all windows)';
|
||||
my $second = 'New folder in KDE/GNOME is Ctrl+⇧Shift+N';
|
||||
my $third = 'Redo in Mac OS is ⇧Shift+⌘Cmd+Z';
|
||||
my $fourth = 'Paste special in KDE/GNOME is Ctrl+⇧Shift+V';
|
||||
my $br = ' <br/>';
|
||||
my $link = '<a href="https://en.wikipedia.org/wiki/Table_of_keyboard_shortcuts">More at Wikipedia</a>';
|
||||
|
||||
ddg_goodie_test(
|
||||
[qw( DDG::Goodie::Shortcut
|
||||
)],
|
||||
'windows show desktop shortcut' => test_zci($start . $first, html => $start . $first . $br . $link),
|
||||
'ubuntu shortcut new folder' => test_zci($start . $second, html => $start . $second . $br . $link),
|
||||
'redo shortcut mac' => test_zci($start . $third, html => $start . $third . $br . $link),
|
||||
'paste special shortcut' => undef #test_zci($start . $fourth, html => $start . $fourth . $br . $link)
|
||||
);
|
||||
|
||||
done_testing;
|
|
@ -14,17 +14,18 @@ ddg_goodie_test(
|
|||
# This is the name of the goodie that will be loaded to test.
|
||||
'DDG::Goodie::SubnetCalc'
|
||||
],
|
||||
"10.0.0.0/24" => test_zci("Network: 10.0.0.0/24, Netmask: 255.255.255.0, Network specified, Class: A, Host Address Range: 10.0.0.1-10.0.0.254, 254 Usable Addresses, Broadcast: 10.0.0.255"),
|
||||
"192.168.0.0/24" => test_zci("Network: 192.168.0.0/24, Netmask: 255.255.255.0, Network specified, Class: C, Host Address Range: 192.168.0.1-192.168.0.254, 254 Usable Addresses, Broadcast: 192.168.0.255"),
|
||||
"8.8.8.8 255.255.224.0" => test_zci("Network: 8.8.0.0/19, Netmask: 255.255.224.0, Host #2056 specified, Class: A, Host Address Range: 8.8.0.1-8.8.31.254, 8190 Usable Addresses, Broadcast: 8.8.31.255"),
|
||||
"4.4.4.255/24" => test_zci("Network: 4.4.4.0/24, Netmask: 255.255.255.0, Broadcast specified, Class: A, Host Address Range: 4.4.4.1-4.4.4.254, 254 Usable Addresses, Broadcast: 4.4.4.255"),
|
||||
"42.24.42.24/17" => test_zci("Network: 42.24.0.0/17, Netmask: 255.255.128.0, Host #10776 specified, Class: A, Host Address Range: 42.24.0.1-42.24.127.254, 32766 Usable Addresses, Broadcast: 42.24.127.255"),
|
||||
"172.32.1.3/31" => test_zci("Network: 172.32.1.2/31, Netmask: 255.255.255.254, Point-To-Point (172.32.1.2, 172.32.1.3) specified, Class: B"),
|
||||
"10.255.255.16/32" => test_zci("Network: 10.255.255.16/32, Netmask: 255.255.255.255, Host Only specified, Class: A"),
|
||||
"10.1.2.3/255.0.0.0" => test_zci("Network: 10.0.0.0/8, Netmask: 255.0.0.0, Host #66051 specified, Class: A, Host Address Range: 10.0.0.1-10.255.255.254, 16777214 Usable Addresses, Broadcast: 10.255.255.255"),
|
||||
"192.168.16.1 23" => test_zci("Network: 192.168.16.0/23, Netmask: 255.255.254.0, Host #1 specified, Class: C, Host Address Range: 192.168.16.1-192.168.17.254, 510 Usable Addresses, Broadcast: 192.168.17.255"),
|
||||
"224.241.221.2/23" => test_zci("Network: 224.241.220.0/23, Netmask: 255.255.254.0, Host #258 specified, Class: D (multicast), Host Address Range: 224.241.220.1-224.241.221.254, 510 Usable Addresses, Broadcast: 224.241.221.255"),
|
||||
"241.1.1.254/32" => test_zci("Network: 241.1.1.254/32, Netmask: 255.255.255.255, Host Only specified, Class: E (reserved)")
|
||||
"10.0.0.0/24" => test_zci(
|
||||
"Network: 10.0.0.0/24 (Class A)\nNetmask: 255.255.255.0\nSpecified: Network\nHost Address Range: 10.0.0.1-10.0.0.254 (254 hosts)\nBroadcast: 10.0.0.255\n",
|
||||
html => "<div><i>Network: </i>10.0.0.0/24 (Class A)</div><div><i>Netmask: </i>255.255.255.0</div><div><i>Specified: </i>Network</div><div><i>Host Address Range: </i>10.0.0.1-10.0.0.254 (254 hosts)</div><div><i>Broadcast: </i>10.0.0.255</div>",
|
||||
),
|
||||
"192.168.0.0/24" => test_zci(
|
||||
"Network: 192.168.0.0/24 (Class C)\nNetmask: 255.255.255.0\nSpecified: Network\nHost Address Range: 192.168.0.1-192.168.0.254 (254 hosts)\nBroadcast: 192.168.0.255\n",
|
||||
html => "<div><i>Network: </i>192.168.0.0/24 (Class C)</div><div><i>Netmask: </i>255.255.255.0</div><div><i>Specified: </i>Network</div><div><i>Host Address Range: </i>192.168.0.1-192.168.0.254 (254 hosts)</div><div><i>Broadcast: </i>192.168.0.255</div>",
|
||||
),
|
||||
"8.8.8.8 255.255.224.0" => test_zci(
|
||||
"Network: 8.8.0.0/19 (Class A)\nNetmask: 255.255.224.0\nSpecified: Host #2056\nHost Address Range: 8.8.0.1-8.8.31.254 (8190 hosts)\nBroadcast: 8.8.31.255\n",
|
||||
html => "<div><i>Network: </i>8.8.0.0/19 (Class A)</div><div><i>Netmask: </i>255.255.224.0</div><div><i>Specified: </i>Host #2056</div><div><i>Host Address Range: </i>8.8.0.1-8.8.31.254 (8190 hosts)</div><div><i>Broadcast: </i>8.8.31.255</div>",
|
||||
),
|
||||
);
|
||||
|
||||
done_testing;
|
||||
done_testing;
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
package DDG::Goodie::<: $ia_name :>;
|
||||
# ABSTRACT: Write and abstract here
|
||||
# Start at https://dukgo.com/duckduckhack/goodie_overview if you are new
|
||||
# to instant answer development
|
||||
|
||||
use DDG::Goodie;
|
||||
|
||||
#Attribution
|
||||
primary_example_queries "first example query", "second example query";
|
||||
secondary_example_queries "optional -- demonstrate any additional triggers";
|
||||
description "Succinct explanation of what this instant answer does";
|
||||
name "<: $ia_name :>";
|
||||
icon_url "";
|
||||
source "";
|
||||
code_url "https://github.com/duckduckgo/zeroclickinfo-spice/blob/master/lib/DDG/Spice/<: $ia_name :>.pm";
|
||||
category "";
|
||||
topics "";
|
||||
attribution github => ["https://github.com/", ""],
|
||||
twitter => ["https://twitter.com/", ""];
|
||||
|
||||
# Triggers
|
||||
triggers any => "triggerWord", "trigger phrase";
|
||||
|
||||
# Handle statement
|
||||
handle remainder => sub {
|
||||
|
||||
# optional - regex guard
|
||||
# return unless qr/^\w+/;
|
||||
|
||||
return $_ if $_;
|
||||
return;
|
||||
};
|
||||
|
||||
1;
|
|
@ -0,0 +1,15 @@
|
|||
#!/usr/bin/env perl
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use Test::More;
|
||||
use DDG::Test::Goodie;
|
||||
|
||||
ddg_goodie_test(
|
||||
[qw(
|
||||
DDG::Goodie::<: $ia_name :>
|
||||
)],
|
||||
'example query' => test_zci('query')
|
||||
);
|
||||
|
||||
done_testing;
|
Loading…
Reference in New Issue