diff --git a/__init__.py b/__init__.py
new file mode 100644
index 0000000..b4ee948
--- /dev/null
+++ b/__init__.py
@@ -0,0 +1,108 @@
+# Copyright 2016 Mycroft AI, Inc.
+#
+# This file is part of Mycroft Core.
+#
+# Mycroft Core is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Mycroft Core is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Mycroft Core. If not, see .
+
+
+import sys
+import urllib2
+import webbrowser
+
+from adapt.intent import IntentBuilder
+from adapt.tools.text.tokenizer import EnglishTokenizer
+from os.path import dirname, join
+
+from mycroft.skills.core import MycroftSkill
+from mycroft.util.log import getLogger
+
+logger = getLogger(__name__)
+__author__ = 'seanfitz'
+
+IFL_TEMPLATE = "http://www.google.com/search?&sourceid=navclient&btnI=I&q=%s"
+
+
+class DesktopLauncherSkill(MycroftSkill):
+ def __init__(self):
+ MycroftSkill.__init__(self, "DesktopLauncherSkill")
+ self.appmap = {}
+
+ def initialize(self):
+ try:
+ import gio
+ except:
+ sys.path.append("/usr/lib/python2.7/dist-packages")
+ try:
+ import gio
+ except:
+ logger.error("Could not import gio")
+ return
+
+ tokenizer = EnglishTokenizer()
+
+ for app in gio.app_info_get_all():
+ name = app.get_name().lower()
+ entry = [app]
+ tokenized_name = tokenizer.tokenize(name)[0]
+
+ if name in self.appmap:
+ self.appmap[name] += entry
+ else:
+ self.appmap[name] = entry
+
+ self.register_vocabulary(name, "Application")
+ if name != tokenized_name:
+ self.register_vocabulary(tokenized_name, "Application")
+ if tokenized_name in self.appmap:
+ self.appmap[tokenized_name] += entry
+ else:
+ self.appmap[tokenized_name] = entry
+
+ launch_intent = IntentBuilder(
+ "LaunchDesktopApplicationIntent").require("LaunchKeyword").require(
+ "Application").build()
+ self.register_intent(launch_intent, self.handle_launch_desktop_app)
+
+ launch_website_intent = IntentBuilder(
+ "LaunchWebsiteIntent").require("LaunchKeyword").require(
+ "Website").build()
+ self.register_intent(launch_website_intent, self.handle_launch_website)
+
+ search_website = IntentBuilder("SearchWebsiteIntent").require(
+ "SearchKeyword").require("Website").require(
+ "SearchTerms").build()
+ self.register_intent(search_website, self.handle_search_website)
+
+ def handle_launch_desktop_app(self, message):
+ app_name = message.data.get('Application')
+ apps = self.appmap.get(app_name)
+ if apps and len(apps) > 0:
+ apps[0].launch()
+
+ def handle_launch_website(self, message):
+ site = message.data.get("Website")
+ webbrowser.open(IFL_TEMPLATE % (urllib2.quote(site)))
+
+ def handle_search_website(self, message):
+ site = message.data.get("Website")
+ search_terms = message.data.get("SearchTerms")
+ search_str = site + " " + search_terms
+ webbrowser.open(IFL_TEMPLATE % (urllib2.quote(search_str)))
+
+ def stop(self):
+ pass
+
+
+def create_skill():
+ return DesktopLauncherSkill()
diff --git a/regex/en-us/search.terms.rx b/regex/en-us/search.terms.rx
new file mode 100644
index 0000000..e4d0a6d
--- /dev/null
+++ b/regex/en-us/search.terms.rx
@@ -0,0 +1,3 @@
+for (?P.*)
+for (?P.*) on
+(?P.*) on
\ No newline at end of file
diff --git a/test/intent/sample1.intent.json b/test/intent/sample1.intent.json
new file mode 100644
index 0000000..1e9b295
--- /dev/null
+++ b/test/intent/sample1.intent.json
@@ -0,0 +1,9 @@
+{
+ "utterance": "search for kittens on youtube",
+ "intent_type": "SearchWebsiteIntent",
+ "intent": {
+ "SearchKeyword": "search",
+ "Website": "youtube",
+ "SearchTerms": "for kittens"
+ }
+}
\ No newline at end of file
diff --git a/test/intent/sample2.intent.json b/test/intent/sample2.intent.json
new file mode 100644
index 0000000..8980a1a
--- /dev/null
+++ b/test/intent/sample2.intent.json
@@ -0,0 +1,9 @@
+{
+ "utterance": "find puppies on wikipedia",
+ "intent_type": "SearchWebsiteIntent",
+ "intent": {
+ "SearchKeyword": "find",
+ "Website": "wikipedia",
+ "SearchTerms": "puppies"
+ }
+}
diff --git a/test/intent/sample3.intent.json b/test/intent/sample3.intent.json
new file mode 100644
index 0000000..37a5e87
--- /dev/null
+++ b/test/intent/sample3.intent.json
@@ -0,0 +1,8 @@
+{
+ "utterance": "launch imgur",
+ "intent_type": "LaunchWebsiteIntent",
+ "intent": {
+ "LaunchKeyword": "launch",
+ "Website": "imgur"
+ }
+}
diff --git a/test/intent/sample4.intent.json b/test/intent/sample4.intent.json
new file mode 100644
index 0000000..574837c
--- /dev/null
+++ b/test/intent/sample4.intent.json
@@ -0,0 +1,8 @@
+{
+ "utterance": "open tumblr",
+ "intent_type": "LaunchWebsiteIntent",
+ "intent": {
+ "LaunchKeyword": "open",
+ "Website": "tumblr"
+ }
+}
diff --git a/vocab/en-us/LaunchKeyword.voc b/vocab/en-us/LaunchKeyword.voc
new file mode 100644
index 0000000..246b55f
--- /dev/null
+++ b/vocab/en-us/LaunchKeyword.voc
@@ -0,0 +1,3 @@
+launch
+open
+run
\ No newline at end of file
diff --git a/vocab/en-us/SearchKeyword.voc b/vocab/en-us/SearchKeyword.voc
new file mode 100644
index 0000000..c41d4e9
--- /dev/null
+++ b/vocab/en-us/SearchKeyword.voc
@@ -0,0 +1,2 @@
+search
+find
\ No newline at end of file
diff --git a/vocab/en-us/Website.voc b/vocab/en-us/Website.voc
new file mode 100644
index 0000000..724b9c1
--- /dev/null
+++ b/vocab/en-us/Website.voc
@@ -0,0 +1,25 @@
+google
+facebook
+amazon
+youtube
+yahoo
+wikipedia
+ebay
+twitter
+go
+craigslist
+reddit
+linkedin
+netflix
+live
+bing
+pinterest
+espn
+imgur
+tumblr
+chase
+cnn
+paypal
+instagram
+blogspot
+apple
\ No newline at end of file