Merge pull request #43 from Yocraft-2000/web-launcher
Web launcher plugin
This commit is contained in:
@@ -0,0 +1,39 @@
|
|||||||
|
# Web Launcher
|
||||||
|
|
||||||
|
Quickly open your favorite websites from the launcher. Favicons are downloaded automatically!
|
||||||
|
|
||||||
|
## Plugin
|
||||||
|
|
||||||
|
| Field | Value |
|
||||||
|
| --- | --- |
|
||||||
|
| ID | `yocraft/web-launcher` |
|
||||||
|
| Entries | Launcher provider: `web-launcher` |
|
||||||
|
| Launcher Prefix | `/web` |
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
|
||||||
|
A browser and `xdg-utils`.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
Open the Noctalia launcher and type `/web` to list all configurated websites.
|
||||||
|
Continue typing to filter by name, then activate a result to launch that website in your default browser.
|
||||||
|
You can customize the list and order of websites in settings.
|
||||||
|
|
||||||
|
## Settings
|
||||||
|
|
||||||
|
| Setting | Type | Default | Description |
|
||||||
|
| --- | --- | --- | --- |
|
||||||
|
| `links` | `string_list` | `see below` | Websites list and order. |
|
||||||
|
| `notify` | `bool` | `true` | Toggle notification when launching website. |
|
||||||
|
| `icon_provider` | `select` | `google` | Icon download source. |
|
||||||
|
|
||||||
|
Default links:
|
||||||
|
```
|
||||||
|
"GitHub|https://github.com",
|
||||||
|
"GitLab|https://gitlab.com",
|
||||||
|
"Codeberg|https://codeberg.org",
|
||||||
|
"Reddit|https://reddit.com",
|
||||||
|
"YouTube|https://youtube.com",
|
||||||
|
"Gmail|https://mail.google.com",
|
||||||
|
```
|
||||||
@@ -0,0 +1,126 @@
|
|||||||
|
local function loadLinks()
|
||||||
|
local raw = noctalia.getConfig("links")
|
||||||
|
local links = {}
|
||||||
|
|
||||||
|
if type(raw) ~= "table" then
|
||||||
|
return links
|
||||||
|
end
|
||||||
|
|
||||||
|
for _, line in ipairs(raw) do
|
||||||
|
local name, url = line:match("^([^|]+)|(.+)$")
|
||||||
|
if name and url then
|
||||||
|
name = noctalia.string.trim(name)
|
||||||
|
url = noctalia.string.trim(url)
|
||||||
|
if url:match("^https?://") then
|
||||||
|
table.insert(links, { name = name, url = url })
|
||||||
|
else
|
||||||
|
noctalia.log("web-launcher: skipped non-http(s) URL: " .. tostring(line))
|
||||||
|
end
|
||||||
|
else
|
||||||
|
noctalia.log("web-launcher: skipped malformed line (expected Name|https://url): " .. tostring(line))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return links
|
||||||
|
end
|
||||||
|
|
||||||
|
local links = loadLinks()
|
||||||
|
|
||||||
|
local function extractDomain(url)
|
||||||
|
local domain = url:match("^https?://([^/]+)")
|
||||||
|
if domain then
|
||||||
|
domain = domain:gsub("^.*@", "")
|
||||||
|
end
|
||||||
|
return domain
|
||||||
|
end
|
||||||
|
|
||||||
|
local function faviconUrl(domain)
|
||||||
|
local provider = noctalia.getConfig("icon_provider")
|
||||||
|
local encoded = noctalia.string.urlEncode(domain)
|
||||||
|
|
||||||
|
if provider == "duckduckgo" then
|
||||||
|
return "https://icons.duckduckgo.com/ip3/" .. encoded .. ".ico"
|
||||||
|
elseif provider == "direct" then
|
||||||
|
return "https://" .. domain .. "/favicon.ico"
|
||||||
|
else
|
||||||
|
return "https://www.google.com/s2/favicons?sz=64&domain=" .. encoded
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function faviconCachePath(domain)
|
||||||
|
local provider = noctalia.getConfig("icon_provider")
|
||||||
|
|
||||||
|
local dir = noctalia.pluginDir() .. "/cache"
|
||||||
|
local safe = domain:gsub("[^%w%.%-]", "_")
|
||||||
|
|
||||||
|
local path = dir .. "/" .. safe .. "_" .. provider .. ".png"
|
||||||
|
return path, dir
|
||||||
|
end
|
||||||
|
|
||||||
|
local function downloadFavicon(domain, onDone)
|
||||||
|
local path, dir = faviconCachePath(domain)
|
||||||
|
if noctalia.fileExists(path) then
|
||||||
|
onDone(path)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
noctalia.mkdirAll(dir)
|
||||||
|
noctalia.download(faviconUrl(domain), path, function(ok)
|
||||||
|
if ok then
|
||||||
|
onDone(path)
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
function onQuery(query)
|
||||||
|
local text = noctalia.string.trim(query)
|
||||||
|
local results = {}
|
||||||
|
|
||||||
|
for _, link in ipairs(links) do
|
||||||
|
local domain = extractDomain(link.url)
|
||||||
|
local iconPath = faviconCachePath(domain)
|
||||||
|
local hasIcon = noctalia.fileExists(iconPath)
|
||||||
|
|
||||||
|
local glyphValue = hasIcon and nil or "world"
|
||||||
|
local iconValue = hasIcon and iconPath or nil
|
||||||
|
|
||||||
|
if not hasIcon then
|
||||||
|
downloadFavicon(domain, function() end)
|
||||||
|
end
|
||||||
|
|
||||||
|
if text == "" then
|
||||||
|
table.insert(results, {
|
||||||
|
id = link.url,
|
||||||
|
title = link.name, subtitle = link.url,
|
||||||
|
glyph = glyphValue, icon = iconValue
|
||||||
|
})
|
||||||
|
else
|
||||||
|
local score = noctalia.fuzzyScore(text, link.name)
|
||||||
|
if score ~= nil then
|
||||||
|
table.insert(results, {
|
||||||
|
id = link.url,
|
||||||
|
title = link.name, subtitle = link.url,
|
||||||
|
glyph = glyphValue, icon = iconValue,
|
||||||
|
score = score
|
||||||
|
})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
launcher.setResults(query, results)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function shellEscape(raw)
|
||||||
|
return "'" .. raw:gsub("'", "'\\''") .. "'"
|
||||||
|
end
|
||||||
|
|
||||||
|
function onActivate(id)
|
||||||
|
noctalia.runAsync("xdg-open " .. shellEscape(id))
|
||||||
|
|
||||||
|
if noctalia.getConfig("notify") then
|
||||||
|
noctalia.notify(
|
||||||
|
noctalia.tr("notify.title"),
|
||||||
|
noctalia.tr("notify.message", { name = id })
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
id = "yocraft/web-launcher"
|
||||||
|
name = "Web Launcher"
|
||||||
|
version = "1.0.0"
|
||||||
|
plugin_api = 3
|
||||||
|
author = "yocraft"
|
||||||
|
license = "MIT"
|
||||||
|
deprecated = false
|
||||||
|
icon = "world"
|
||||||
|
description = "Quickly open your favorite websites from the launcher."
|
||||||
|
tags = ["launcher", "utility", "network", "productivity"]
|
||||||
|
dependencies = [ "xdg-utils" ]
|
||||||
|
|
||||||
|
[[launcher_provider]]
|
||||||
|
id = "web-launcher"
|
||||||
|
entry = "launcher.luau"
|
||||||
|
prefix = "web"
|
||||||
|
glyph = "world"
|
||||||
|
include_in_global_search = false
|
||||||
|
|
||||||
|
[[setting]]
|
||||||
|
key = "links"
|
||||||
|
type = "string_list"
|
||||||
|
label_key = "settings.links.label"
|
||||||
|
description_key = "settings.links.description"
|
||||||
|
default = [
|
||||||
|
"GitHub|https://github.com",
|
||||||
|
"GitLab|https://gitlab.com",
|
||||||
|
"Codeberg|https://codeberg.org",
|
||||||
|
"Reddit|https://reddit.com",
|
||||||
|
"YouTube|https://youtube.com",
|
||||||
|
"Gmail|https://mail.google.com",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[setting]]
|
||||||
|
key = "notify"
|
||||||
|
type = "bool"
|
||||||
|
label_key = "settings.notify.label"
|
||||||
|
description_key = "settings.notify.description"
|
||||||
|
default = true
|
||||||
|
|
||||||
|
[[setting]]
|
||||||
|
key = "icon_provider"
|
||||||
|
type = "select"
|
||||||
|
label_key = "settings.icon_provider.label"
|
||||||
|
description_key = "settings.icon_provider.description"
|
||||||
|
default = "google"
|
||||||
|
options = [
|
||||||
|
{ value = "google", label_key = "settings.icon_provider.google" },
|
||||||
|
{ value = "duckduckgo", label_key = "settings.icon_provider.duckduckgo" },
|
||||||
|
{ value = "direct", label_key = "settings.icon_provider.direct" },
|
||||||
|
]
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 49 KiB |
@@ -0,0 +1,23 @@
|
|||||||
|
{
|
||||||
|
"settings": {
|
||||||
|
"links": {
|
||||||
|
"label": "Links",
|
||||||
|
"description": "Format: Name|https://url"
|
||||||
|
},
|
||||||
|
"notify": {
|
||||||
|
"label": "Notify",
|
||||||
|
"description": "Notify when opening link."
|
||||||
|
},
|
||||||
|
"icon_provider": {
|
||||||
|
"label": "Icon Provider",
|
||||||
|
"description": "Icon download source.",
|
||||||
|
"google": "Google",
|
||||||
|
"duckduckgo": "DuckDuckGo",
|
||||||
|
"direct": "Site's own favicon.ico"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notify": {
|
||||||
|
"title": "Websites",
|
||||||
|
"message": "Opening {name}"
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user