commit 6e470cd78f9685f57591e23f0d894f9a019d0c16 Author: Rudis Muiznieks Date: Wed Nov 23 12:00:14 2022 -0600 initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9d5b955 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +icon-cache/ +links.json +newtab.html diff --git a/README.md b/README.md new file mode 100644 index 0000000..5104cc2 --- /dev/null +++ b/README.md @@ -0,0 +1,15 @@ +## NewTabber + +Simple script I use to generate my [static new tab page](https://static.sitosis.com/newtab.html). + +### Usage + +Create a `links.json` containing the links you want. See `links.json.example` for an example. The `icon` attribute is the name of the [Bootstrap icon](https://icons.getbootstrap.com/) to use. Each icon used is initially fetched from the web and then cached locally in an `icon-cache` directory for future uses. + +You can also edit the files in `templates` and some of the variables defined at the top of `generate.pl` to customize the look and behavior of the page. + +Then simply run the `generate.pl` script. It will create or overwrite an existing `newtab.html` in the same directory. + +### Installation + +You'll need to install Perl, plus the Perl modules `utf8`, `JSON`, `LWP::UserAgent`, `LWP::Protocol::https`, and `Storable` either from CPAN or using your distribution's package manager. diff --git a/generate.pl b/generate.pl new file mode 100755 index 0000000..1016eff --- /dev/null +++ b/generate.pl @@ -0,0 +1,80 @@ +#!/usr/bin/env perl + +use utf8; +use strict; +use warnings; +use open qw(:std :utf8); +use JSON qw(decode_json); +use LWP::UserAgent; +use Storable qw(store retrieve); + +## CONFIG +my $icons_per_line = 5; +## END CONFIG + +open my $links_file, '<', 'links.json'; +my $links = decode_json(join('', <$links_file>)); +close $links_file; + +open my $newtab, '>', 'newtab.html'; + +open my $header, '<', 'template/header.html' + or die "couldn't open template/header.html"; +print $newtab join('', <$header>); +close $header; + +open my $link_template_file, '<', 'template/link.html' + or die "couldn't open template/link.html"; +my $link_template = join('', <$link_template_file>); +close $link_template_file; + +my $ua = LWP::UserAgent->new(); +$ua->agent('Mozilla/5.0 (X11; Linux x86_64; rv:107.0) Gecko/20100101 Firefox/107.0'); + +my $link_counter = 0; +foreach my $link(@{$links}) { + my $link_html = $link_template; + $link_html =~ s/\{\{title\}\}/$link->{title}/g; + $link_html =~ s/\{\{url\}\}/$link->{url}/g; + + if(! -d 'icon-cache') { + mkdir 'icon-cache'; + } + if (! -e "icon-cache/$link->{icon}") { + my $icon_url = "https://icons.getbootstrap.com/icons/$link->{icon}/"; + my $resp = $ua->get($icon_url); + if(!$resp->is_success) { + my $status = $resp->status_line; + die "couldn't fetch icon $icon_url\n$status"; + } + my $icon_full_html = $resp->decoded_content; + if($icon_full_html =~ /
]*>(.*?)<\/svg/s) { + my $icon = {viewBox => $1, paths => $2}; + store($icon, "icon-cache/$link->{icon}") + or die "couldn't save icon-cache/$link->{icon}"; + } else { + die "couldn't parse icon $link->{icon}"; + } + } + my $icon = retrieve("icon-cache/$link->{icon}"); + + $link_html =~ s/\{\{viewBox\}\}/$icon->{viewBox}/g; + $link_html =~ s/\{\{icon\}\}/$icon->{paths}/g; + + print $newtab $link_html; + + if(++$link_counter == $icons_per_line) { + open my $line_separator, '<', 'template/link_line_separator.html' + or die "couldn't open template/link_line_separator.html"; + print $newtab join('', <$line_separator>); + close $line_separator; + $link_counter = 0; + } +} + +open my $footer, '<', 'template/footer.html' + or die "couldn't open template/footer.html"; +print $newtab join('', <$footer>); +close $footer; + +close $newtab; diff --git a/links.json.example b/links.json.example new file mode 100644 index 0000000..1df5dc0 --- /dev/null +++ b/links.json.example @@ -0,0 +1,27 @@ +[ + { + "title": "Hacker News", + "url": "https://hckrnews.com/", + "icon": "newspaper" + }, + { + "title": "Tildes", + "url": "https://tildes.net/", + "icon": "chat-dots" + }, + { + "title": "Nebula", + "url": "https://nebula.app/myshows", + "icon": "film" + }, + { + "title": "Twitch", + "url": "https://twitch.tv/", + "icon": "twitch" + }, + { + "title": "YouTube", + "url": "https://www.youtube.com/feed/subscriptions", + "icon": "youtube" + } +] diff --git a/template/footer.html b/template/footer.html new file mode 100644 index 0000000..876e893 --- /dev/null +++ b/template/footer.html @@ -0,0 +1,26 @@ + + +
+
+ +
+
+ + + + diff --git a/template/header.html b/template/header.html new file mode 100644 index 0000000..70409bd --- /dev/null +++ b/template/header.html @@ -0,0 +1,60 @@ + + + + New Tab + + + + +
+
+
    diff --git a/template/link.html b/template/link.html new file mode 100644 index 0000000..9003fb7 --- /dev/null +++ b/template/link.html @@ -0,0 +1,8 @@ +
  • + + + {{icon}} + + {{title}} + +
  • diff --git a/template/link_line_separator.html b/template/link_line_separator.html new file mode 100644 index 0000000..167197e --- /dev/null +++ b/template/link_line_separator.html @@ -0,0 +1,4 @@ +
+
+
+