Compare commits
14 Commits
Author | SHA1 | Date |
---|---|---|
Gonçalo Valério | 029ad0bc0f | |
dependabot[bot] | 5cfbf4df7d | |
Gonçalo Valério | 5df7d65acf | |
Gonçalo Valério | d9d41f2d5c | |
dependabot[bot] | 7ea2ea08f3 | |
Gonçalo Valério | 09a017b8d8 | |
Gonçalo Valério | b6cb960dee | |
Gonçalo Valério | 06c66ceef3 | |
Gonçalo Valério | 417fad1009 | |
Gonçalo Valério | c032bd06f6 | |
Gonçalo Valério | 5d6a3b23d5 | |
Gonçalo Valério | a50785137a | |
Gonçalo Valério | 4e5200bb40 | |
Gonçalo Valério | 7473334a98 |
|
@ -0,0 +1,71 @@
|
|||
# For most projects, this workflow file will not need changing; you simply need
|
||||
# to commit it to your repository.
|
||||
#
|
||||
# You may wish to alter this file to override the set of languages analyzed,
|
||||
# or to provide custom queries or build logic.
|
||||
#
|
||||
# ******** NOTE ********
|
||||
# We have attempted to detect the languages in your repository. Please check
|
||||
# the `language` matrix defined below to confirm you have the correct set of
|
||||
# supported CodeQL languages.
|
||||
#
|
||||
name: "CodeQL"
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ master ]
|
||||
pull_request:
|
||||
# The branches below must be a subset of the branches above
|
||||
branches: [ master ]
|
||||
schedule:
|
||||
- cron: '40 16 * * 3'
|
||||
|
||||
jobs:
|
||||
analyze:
|
||||
name: Analyze
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
actions: read
|
||||
contents: read
|
||||
security-events: write
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
language: [ 'javascript' ]
|
||||
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ]
|
||||
# Learn more:
|
||||
# https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v2
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v1
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
# If you wish to specify custom queries, you can do so here or in a config file.
|
||||
# By default, queries listed here will override any specified in a config file.
|
||||
# Prefix the list here with "+" to use these queries and those in the config file.
|
||||
# queries: ./path/to/local/query, your-org/your-repo/queries@main
|
||||
|
||||
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
||||
# If this step fails, then you should remove it and run the build manually (see below)
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@v1
|
||||
|
||||
# ℹ️ Command-line programs to run using the OS shell.
|
||||
# 📚 https://git.io/JvXDl
|
||||
|
||||
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
|
||||
# and modify them (or add more) to build your code if your project
|
||||
# uses a compiled language
|
||||
|
||||
#- run: |
|
||||
# make bootstrap
|
||||
# make release
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v1
|
|
@ -9,3 +9,4 @@ worker/
|
|||
node_modules/
|
||||
.cargo-ok
|
||||
wrangler.toml
|
||||
.wrangler
|
||||
|
|
50
README.md
50
README.md
|
@ -1,33 +1,41 @@
|
|||
# Worker-planet
|
||||
|
||||
This project is meant to be an easy way to aggregate in a single page content from multiple sources.
|
||||
This project is meant to be an easy way to aggregate, on a single page, content from multiple sources.
|
||||
|
||||
It takes a list of existing RSS feeds, aggregates their contents and displays them in chronological order.
|
||||
|
||||
It was inspired by other software packages such as [Planet](<https://en.wikipedia.org/wiki/Planet_(software)>) and [MoonMoon](https://moonmoon.org/) but runs on top of Cloudflare Workers instead of being deployed on your own server.
|
||||
It was inspired by other software packages, such as [Planet](<https://en.wikipedia.org/wiki/Planet_(software)>) and [MoonMoon](https://moonmoon.org/), but runs on top of Cloudflare Workers instead of being deployed on your own server.
|
||||
|
||||
This ends up being specially useful for communities, in order to follow the work being done and published by its members. Some examples of existing "planets" (but using different software):
|
||||
This ends up being especially useful for communities to follow the work being done and published by their members.
|
||||
|
||||
Below are some examples of existing "planets" that use different software:
|
||||
|
||||
- https://planet.debian.org/
|
||||
- https://planet.kde.org/
|
||||
- https://planet.gnome.org/
|
||||
|
||||
**Note:** This project is still in its early days, so expect some rough edges. Any contributions are welcome.
|
||||
An example of a live planet using `worker-planet` software is:
|
||||
|
||||
- https://infosecplanet.ovalerio.net
|
||||
|
||||
_If you wish to add your deployment to this list, feel free to create a PR._
|
||||
|
||||
# How to deploy
|
||||
|
||||
First you need to have [wrangler](https://github.com/cloudflare/wrangler) correctly setup on your machine. Then:
|
||||
1. Clone this repository.
|
||||
2. Install the project dependencies: `npm install`.
|
||||
3. Create a `wrangler.toml` file based on the existing `wrangler.toml.example`.
|
||||
4. Create KV namespaces and add their IDs to the `kv_namespaces` setting on `wrangler.toml`.
|
||||
5. Add your `account_id` and customize all the `vars` in `wrangler.toml`. `FEEDS` should be a string of comma-separated URLs, one for each of the RSS/ATOM sources that will be part of your planet.
|
||||
6. Build the worker bundle: `npm run build`.
|
||||
7. Deploy your new worker: `npm run deploy`.
|
||||
|
||||
1. Clone this repository
|
||||
2. Create a `wrangler.toml` file based on the existing `wrangler.toml.example`
|
||||
3. Create KV namespaces and add their ids to the `kv_namespaces` setting on `wrangler.toml`
|
||||
4. Add your `account_id` and customize all the `vars` in `wrangler.toml`. `FEEDS` should be
|
||||
a string of coma separated urls, to each of the RSS/ATOM sources that will be part of your planet.
|
||||
5. Run `wrangler publish`
|
||||
**Note:** For the last step, you might need to set the `CLOUDFLARE_API_TOKEN` environment variable.
|
||||
|
||||
## Configuration variables
|
||||
|
||||
- **FEEDS** - list of sources used to fetch the planet's content (separate each url with a comma)
|
||||
- **TITLE** - Name of your planet (included in the generated html page and RSS feed)
|
||||
- **FEEDS** - list of sources used to fetch the planet's content (separate each URL with a comma)
|
||||
- **TITLE** - Name of your planet (included in the generated HTML page and RSS feed)
|
||||
- **DESCRIPTION** - Free text to be included on the page (currently not used on the included template)
|
||||
- **MAX_SIZE** - Number of posts/entries that will be included on the page/feed
|
||||
- **CACHE_MAX_AGE** - To avoid hitting the KV store each time the content is fetched, the static content is cached. You should adjust this value to the frequency you pick for your cron. Defined in seconds (default: 3600)
|
||||
|
@ -35,10 +43,18 @@ First you need to have [wrangler](https://github.com/cloudflare/wrangler) correc
|
|||
## Customize the generated HTML
|
||||
|
||||
Each community has its own identity, so you should be able to easily customize the look and feel
|
||||
of the generated page. To do so, before publishing you can edit the `templates/list_posts.handlebars` file.
|
||||
of the generated page. To do so, before publishing, you can edit one of the existing templates in the `templates` folder.
|
||||
|
||||
After you should "precompile" that file using the following command:
|
||||
After that, you should "precompile" that file using the following command:
|
||||
|
||||
> \$ handlebars templates/list_posts.handlebars -f templates/list_posts.precompiled.js -c handlebars/runtime
|
||||
> \$ npm run template -- templates/default.handlebars -f templates/default.precompiled.js
|
||||
|
||||
**Note:** You need to have handlebars installed "globally" for this step.
|
||||
If the template name you are using is different from `default`, you should change the following 2 lines in `index.js`:
|
||||
|
||||
```javascript
|
||||
import template from './templates/default.precompiled'
|
||||
```
|
||||
|
||||
```javascript
|
||||
let template = Handlebars.templates['default']
|
||||
```
|
||||
|
|
93
index.js
93
index.js
|
@ -1,12 +1,28 @@
|
|||
import Parser from 'rss-parser'
|
||||
import { Feed } from 'feed'
|
||||
import Handlebars from 'handlebars/runtime'
|
||||
import template from './templates/list_posts.precompiled'
|
||||
import template from './templates/default.precompiled'
|
||||
import * as striptags from 'striptags'
|
||||
|
||||
addEventListener('scheduled', event => {
|
||||
event.waitUntil(handleScheduled(event))
|
||||
/**
|
||||
* Extra Handlerbars template helpers
|
||||
*/
|
||||
Handlebars.registerHelper('isRowElemN', function(index, rowItems, n, options) {
|
||||
return index % rowItems == n ? options.fn(this) : options.inverse(this)
|
||||
})
|
||||
|
||||
/**
|
||||
* Handle CRON jobs
|
||||
* Where information is gathered and HTML and RSS is generated.
|
||||
*/
|
||||
addEventListener('scheduled', event => {
|
||||
event.waitUntil(handleScheduled())
|
||||
})
|
||||
|
||||
/**
|
||||
* Serve the existing generated elements.
|
||||
* CACHE is used to speed up the operation.
|
||||
*/
|
||||
addEventListener('fetch', event => {
|
||||
event.respondWith(handleRequest(event.request))
|
||||
})
|
||||
|
@ -14,6 +30,7 @@ addEventListener('fetch', event => {
|
|||
/**
|
||||
* Deliver aggregated content according to the formats requested
|
||||
* @param {Request} request
|
||||
* @returns Response
|
||||
*/
|
||||
async function handleRequest(request) {
|
||||
const cacheUrl = new URL(request.url)
|
||||
|
@ -38,12 +55,17 @@ async function handleRequest(request) {
|
|||
response = new Response(content, {
|
||||
headers: {
|
||||
'content-type': 'application/rss+xml',
|
||||
'Cache-Control': 'max-age=3600',
|
||||
'Cache-Control': `max-age=${cacheMaxAge}`,
|
||||
},
|
||||
})
|
||||
} else if (path === '/atom') {
|
||||
let content = await WORKER_PLANET_STORE.get('atom')
|
||||
response = new Response(content, {
|
||||
headers: {
|
||||
'content-type': 'application/atom+xml',
|
||||
'Cache-Control': `max-age=${cacheMaxAge}`,
|
||||
},
|
||||
})
|
||||
// } else if (path === '/atom') {
|
||||
// let content = await WORKER_PLANET_STORE.get('atom')
|
||||
// response = new Response(content)
|
||||
} else {
|
||||
return new Response('', { status: 404 })
|
||||
}
|
||||
|
@ -53,25 +75,30 @@ async function handleRequest(request) {
|
|||
|
||||
/**
|
||||
* Fetch all source feeds and generate the aggregated content
|
||||
*
|
||||
* TODO implement a faster way to fetch several sources
|
||||
*
|
||||
* @param {*} event
|
||||
*/
|
||||
async function handleScheduled(event) {
|
||||
async function handleScheduled() {
|
||||
let feeds = FEEDS.split(',')
|
||||
let content = []
|
||||
let sources = []
|
||||
let items
|
||||
|
||||
let promises = []
|
||||
for (let url of feeds) {
|
||||
try {
|
||||
items = await fetchAndHydrate(url)
|
||||
sources.push({ name: items[0].source_title, link: items[0].source_link })
|
||||
} catch (error) {
|
||||
console.log(`Failed to fetch ${url}`)
|
||||
console.log(error)
|
||||
promises.push(fetchAndHydrate(url))
|
||||
}
|
||||
const results = await Promise.allSettled(promises)
|
||||
|
||||
for (let [index, result] of results.entries()) {
|
||||
if (result.status == 'fulfilled') {
|
||||
let posts = result.value
|
||||
let title = posts[0].source_title
|
||||
let link = posts[0].source_link
|
||||
let name = title != '' ? title : new URL(link).host
|
||||
sources.push({ name, link })
|
||||
content.push(...posts)
|
||||
} else {
|
||||
console.log(`Failed to fetch ${feeds[index]}`)
|
||||
console.log(result.reason)
|
||||
}
|
||||
content.push(...items)
|
||||
}
|
||||
|
||||
//sort all the elements chronologically (recent first)
|
||||
|
@ -96,13 +123,14 @@ async function handleScheduled(event) {
|
|||
let html = createHTML(content, sources)
|
||||
// Store
|
||||
await WORKER_PLANET_STORE.put('rss', feed.rss2())
|
||||
//await WORKER_PLANET_STORE.put('atom', feed.atom1())
|
||||
await WORKER_PLANET_STORE.put('atom', feed.atom1())
|
||||
await WORKER_PLANET_STORE.put('html', html)
|
||||
}
|
||||
|
||||
/**
|
||||
* Take a feed URL, fetch all items and attach source information
|
||||
* @param {Array} feeds
|
||||
* @param {String} feed The URL of the feed to be fetched and parsed
|
||||
* @returns Array containing all the feed items parsed by rss-parser
|
||||
*/
|
||||
async function fetchAndHydrate(feed) {
|
||||
console.log(`[fetchAndHydrate] start to fetch feed: ${feed}`)
|
||||
|
@ -127,7 +155,8 @@ async function fetchAndHydrate(feed) {
|
|||
|
||||
/**
|
||||
* Builds a feed object from the provided items
|
||||
* @param {Array} items
|
||||
* @param {Array} items parsed by rss-parser
|
||||
* @return Feed object created by feed
|
||||
*/
|
||||
function createFeed(items) {
|
||||
console.log(`[createFeed] start building the aggregated feed`)
|
||||
|
@ -160,13 +189,23 @@ function createFeed(items) {
|
|||
return feed
|
||||
}
|
||||
/**
|
||||
* Generete the HTML page with the aggregated contents
|
||||
* @param {*} items
|
||||
* @returns
|
||||
* Generate the HTML page with the aggregated contents
|
||||
* @param {Array} items parsed by rss-parser
|
||||
* @returns String with HTML page containing the parsed contents
|
||||
*/
|
||||
function createHTML(items, sources) {
|
||||
console.log(`[createHTML] building the HTML document`)
|
||||
let template = Handlebars.templates['list_posts']
|
||||
let template = Handlebars.templates['default']
|
||||
let dateFormatter = new Intl.DateTimeFormat('pt-PT', { timeZone: 'UTC' })
|
||||
|
||||
for (let item of items) {
|
||||
let shortdescription = striptags(item.content).substring(0, 250)
|
||||
item.description = shortdescription ? shortdescription + ' [...]' : ''
|
||||
item.formattedDate = item.pubDate
|
||||
? dateFormatter.format(new Date(item.pubDate))
|
||||
: ''
|
||||
}
|
||||
|
||||
return template({
|
||||
items: items,
|
||||
sources: sources,
|
||||
|
|
File diff suppressed because it is too large
Load Diff
26
package.json
26
package.json
|
@ -1,21 +1,35 @@
|
|||
{
|
||||
"private": true,
|
||||
"name": "worker-planet",
|
||||
"version": "1.0.0",
|
||||
"version": "1.2.0",
|
||||
"description": "Generate a single feed of content from multiple RSS/Atom sources. Runs on Cloudflare Workers.",
|
||||
"main": "index.js",
|
||||
"main": "./index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1",
|
||||
"format": "prettier --write '**/*.{js,css,json,md}'"
|
||||
"format": "prettier --write '**/*.{js,css,json,md}' '!**/worker/*' '!**/templates/*'",
|
||||
"template": "handlebars -c handlebars/runtime",
|
||||
"build": "webpack",
|
||||
"dev": "webpack && wrangler dev",
|
||||
"deploy": "wrangler deploy"
|
||||
},
|
||||
"author": "Gonçalo Valério <gon@ovalerio.net>",
|
||||
"license": "AGPL-3.0",
|
||||
"devDependencies": {
|
||||
"prettier": "^1.18.2"
|
||||
"buffer": "^6.0.3",
|
||||
"https-browserify": "^1.0.0",
|
||||
"prettier": "^1.18.2",
|
||||
"stream-browserify": "^3.0.0",
|
||||
"stream-http": "^3.2.0",
|
||||
"timers-browserify": "^2.0.12",
|
||||
"url": "^0.11.3",
|
||||
"webpack": "^5.89.0",
|
||||
"webpack-cli": "^4.10.0",
|
||||
"wrangler": "^3.19.0",
|
||||
"wranglerjs-compat-webpack-plugin": "^0.0.6"
|
||||
},
|
||||
"dependencies": {
|
||||
"feed": "^4.2.2",
|
||||
"handlebars": "^4.7.7",
|
||||
"rss-parser": "^3.12.0"
|
||||
"rss-parser": "^3.13.0",
|
||||
"striptags": "3.2.0"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,23 +8,27 @@
|
|||
<title>{{page_title}}</title>
|
||||
<meta property="og:title" content="{{page_title}}" />
|
||||
<meta property="og:description" content="{{page_description}}" />
|
||||
<meta http-equiv="Content-Security-Policy" content="script-src https://cdn.jsdelivr.net/npm/bootstrap@5.0.1/dist/js/bootstrap.bundle.min.js; style-src https://cdn.jsdelivr.net/npm/bootstrap@5.0.1/dist/css/bootstrap.min.css https://cdn.jsdelivr.net/npm/bootstrap-icons@1.5.0/font/bootstrap-icons.css 'sha256-Rlrl8UtcuZXDdr9KU9SZlhcRnb8Epry8Jgy1xIoCOkg=';">
|
||||
<meta http-equiv="Content-Security-Policy" content="script-src https://cdn.jsdelivr.net/npm/bootstrap@5.0.1/dist/js/bootstrap.bundle.min.js; style-src https://cdn.jsdelivr.net/npm/bootstrap@5.0.1/dist/css/bootstrap.min.css https://cdn.jsdelivr.net/npm/bootstrap-icons@1.5.0/font/bootstrap-icons.css 'sha256-G3Hryz5a3r//doprn3mQdVn71SMV/Wb1C6hMehrBGnk=';" />
|
||||
<link rel="alternate" type="application/rss+xml" title="Planet RSS feed" href="/rss" />
|
||||
<link rel="alternate" type="application/atom+xml" title="Planet Atom feed" href="/atom" />
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.1/dist/css/bootstrap.min.css" rel="stylesheet"
|
||||
integrity="sha384-+0n0xVW2eSR5OomGNYDnhzAbDsOXxcvSN1TPprVMTNDbiYZCxYbOOl7+AMvyTG2x" crossorigin="anonymous" />
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.5.0/font/bootstrap-icons.css"
|
||||
integrity="sha256-PDJQdTN7dolQWDASIoBVrjkuOEaI137FI15sqI3Oxu8=" crossorigin="anonymous" />
|
||||
<style>
|
||||
img {
|
||||
width: 100% !important;
|
||||
max-width:600px !important;
|
||||
height: auto;
|
||||
width: 100% !important;
|
||||
max-width:100% !important;
|
||||
height: auto;
|
||||
}
|
||||
code {
|
||||
display: block;
|
||||
white-space: pre-wrap;
|
||||
overflow-wrap: break-word;
|
||||
}
|
||||
video {
|
||||
max-width: 100%;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
var Handlebars = require("handlebars/runtime"); var template = Handlebars.template, templates = Handlebars.templates = Handlebars.templates || {};
|
||||
templates['default'] = template({"1":function(container,depth0,helpers,partials,data) {
|
||||
var stack1, helper, alias1=depth0 != null ? depth0 : (container.nullContext || {}), alias2=container.hooks.helperMissing, alias3="function", alias4=container.escapeExpression, lookupProperty = container.lookupProperty || function(parent, propertyName) {
|
||||
if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
|
||||
return parent[propertyName];
|
||||
}
|
||||
return undefined
|
||||
};
|
||||
|
||||
return " <div class=\"row p-2\">\n <article>\n <div class=\"card\">\n <div class=\"card-body\">\n <h2 class=\"card-title\"><a href=\""
|
||||
+ alias4(((helper = (helper = lookupProperty(helpers,"link") || (depth0 != null ? lookupProperty(depth0,"link") : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"link","hash":{},"data":data,"loc":{"start":{"line":65,"column":44},"end":{"line":65,"column":52}}}) : helper)))
|
||||
+ "\">"
|
||||
+ alias4(((helper = (helper = lookupProperty(helpers,"title") || (depth0 != null ? lookupProperty(depth0,"title") : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"title","hash":{},"data":data,"loc":{"start":{"line":65,"column":54},"end":{"line":65,"column":63}}}) : helper)))
|
||||
+ "</a></h2>\n <p class=\"card-subtitle mb-2 text-muted\">\n <small>Date: "
|
||||
+ alias4(((helper = (helper = lookupProperty(helpers,"pubDate") || (depth0 != null ? lookupProperty(depth0,"pubDate") : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"pubDate","hash":{},"data":data,"loc":{"start":{"line":67,"column":27},"end":{"line":67,"column":38}}}) : helper)))
|
||||
+ "</small><br>\n <small>Source: <a href=\""
|
||||
+ alias4(((helper = (helper = lookupProperty(helpers,"source_link") || (depth0 != null ? lookupProperty(depth0,"source_link") : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"source_link","hash":{},"data":data,"loc":{"start":{"line":68,"column":38},"end":{"line":68,"column":53}}}) : helper)))
|
||||
+ "\">"
|
||||
+ alias4(((helper = (helper = lookupProperty(helpers,"source_title") || (depth0 != null ? lookupProperty(depth0,"source_title") : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"source_title","hash":{},"data":data,"loc":{"start":{"line":68,"column":55},"end":{"line":68,"column":71}}}) : helper)))
|
||||
+ "</a></small>\n </p>\n\n "
|
||||
+ ((stack1 = ((helper = (helper = lookupProperty(helpers,"content") || (depth0 != null ? lookupProperty(depth0,"content") : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"content","hash":{},"data":data,"loc":{"start":{"line":71,"column":12},"end":{"line":71,"column":25}}}) : helper))) != null ? stack1 : "")
|
||||
+ "\n </div>\n </div>\n </article>\n </div>\n";
|
||||
},"3":function(container,depth0,helpers,partials,data) {
|
||||
var helper, alias1=depth0 != null ? depth0 : (container.nullContext || {}), alias2=container.hooks.helperMissing, alias3="function", alias4=container.escapeExpression, lookupProperty = container.lookupProperty || function(parent, propertyName) {
|
||||
if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
|
||||
return parent[propertyName];
|
||||
}
|
||||
return undefined
|
||||
};
|
||||
|
||||
return " <li><a href=\""
|
||||
+ alias4(((helper = (helper = lookupProperty(helpers,"link") || (depth0 != null ? lookupProperty(depth0,"link") : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"link","hash":{},"data":data,"loc":{"start":{"line":97,"column":23},"end":{"line":97,"column":31}}}) : helper)))
|
||||
+ "\">"
|
||||
+ alias4(((helper = (helper = lookupProperty(helpers,"name") || (depth0 != null ? lookupProperty(depth0,"name") : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"name","hash":{},"data":data,"loc":{"start":{"line":97,"column":33},"end":{"line":97,"column":41}}}) : helper)))
|
||||
+ "</a></li>\n";
|
||||
},"compiler":[8,">= 4.3.0"],"main":function(container,depth0,helpers,partials,data) {
|
||||
var stack1, helper, alias1=depth0 != null ? depth0 : (container.nullContext || {}), alias2=container.hooks.helperMissing, alias3="function", alias4=container.escapeExpression, lookupProperty = container.lookupProperty || function(parent, propertyName) {
|
||||
if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
|
||||
return parent[propertyName];
|
||||
}
|
||||
return undefined
|
||||
};
|
||||
|
||||
return "<!DOCTYPE html>\n<html lang=\"en\">\n\n<head>\n <meta charset=\"UTF-8\">\n <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <title>"
|
||||
+ alias4(((helper = (helper = lookupProperty(helpers,"page_title") || (depth0 != null ? lookupProperty(depth0,"page_title") : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"page_title","hash":{},"data":data,"loc":{"start":{"line":8,"column":9},"end":{"line":8,"column":23}}}) : helper)))
|
||||
+ "</title>\n <meta property=\"og:title\" content=\""
|
||||
+ alias4(((helper = (helper = lookupProperty(helpers,"page_title") || (depth0 != null ? lookupProperty(depth0,"page_title") : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"page_title","hash":{},"data":data,"loc":{"start":{"line":9,"column":37},"end":{"line":9,"column":51}}}) : helper)))
|
||||
+ "\" />\n <meta property=\"og:description\" content=\""
|
||||
+ alias4(((helper = (helper = lookupProperty(helpers,"page_description") || (depth0 != null ? lookupProperty(depth0,"page_description") : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"page_description","hash":{},"data":data,"loc":{"start":{"line":10,"column":43},"end":{"line":10,"column":63}}}) : helper)))
|
||||
+ "\" />\n <meta http-equiv=\"Content-Security-Policy\" content=\"script-src https://cdn.jsdelivr.net/npm/bootstrap@5.0.1/dist/js/bootstrap.bundle.min.js; style-src https://cdn.jsdelivr.net/npm/bootstrap@5.0.1/dist/css/bootstrap.min.css https://cdn.jsdelivr.net/npm/bootstrap-icons@1.5.0/font/bootstrap-icons.css 'sha256-G3Hryz5a3r//doprn3mQdVn71SMV/Wb1C6hMehrBGnk=';\" />\n <link rel=\"alternate\" type=\"application/rss+xml\" title=\"Planet RSS feed\" href=\"/rss\" />\n <link rel=\"alternate\" type=\"application/atom+xml\" title=\"Planet Atom feed\" href=\"/atom\" />\n <link href=\"https://cdn.jsdelivr.net/npm/bootstrap@5.0.1/dist/css/bootstrap.min.css\" rel=\"stylesheet\"\n integrity=\"sha384-+0n0xVW2eSR5OomGNYDnhzAbDsOXxcvSN1TPprVMTNDbiYZCxYbOOl7+AMvyTG2x\" crossorigin=\"anonymous\" />\n <link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/npm/bootstrap-icons@1.5.0/font/bootstrap-icons.css\"\n integrity=\"sha256-PDJQdTN7dolQWDASIoBVrjkuOEaI137FI15sqI3Oxu8=\" crossorigin=\"anonymous\" />\n <style>\n img {\n width: 100% !important;\n max-width:100% !important;\n height: auto;\n }\n code {\n display: block;\n white-space: pre-wrap;\n overflow-wrap: break-word;\n }\n video {\n max-width: 100%;\n }\n </style>\n</head>\n\n<body>\n <nav class=\"navbar navbar-expand-lg navbar-light bg-light\">\n <div class=\"container-fluid\">\n <a class=\"navbar-brand\" href=\"#\">"
|
||||
+ alias4(((helper = (helper = lookupProperty(helpers,"page_title") || (depth0 != null ? lookupProperty(depth0,"page_title") : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"page_title","hash":{},"data":data,"loc":{"start":{"line":38,"column":39},"end":{"line":38,"column":53}}}) : helper)))
|
||||
+ "</a>\n <ul class=\"navbar-nav ms-auto\">\n <li class=\"nav-item\">\n <a class=\"nav-link active\" aria-current=\"page\" href=\"/rss\">\n <i class=\"bi bi-rss\" role=\"img\" aria-label=\"RSS\"></i> RSS Feed\n </a>\n </li>\n <li class=\"nav-item\">\n <a class=\"nav-link active\" aria-current=\"page\" href=\"https://github.com/dethos/worker-planet\">\n <i class=\"bi bi-github\" role=\"img\" aria-label=\"GitHub\"></i> Source Code\n </a>\n </li>\n <li class=\"nav-item\">\n <a class=\"nav-link active\" aria-current=\"page\" data-bs-toggle=\"offcanvas\" data-bs-target=\"#aboutPanel\" aria-controls=\"offcanvasRight\" href=\"#\">\n <i class=\"bi bi-patch-question\" role=\"img\" aria-label=\"About\"></i> About\n </a>\n </li>\n </ul>\n </div>\n </nav>\n\n <main class=\"container d-grid\">\n"
|
||||
+ ((stack1 = lookupProperty(helpers,"each").call(alias1,(depth0 != null ? lookupProperty(depth0,"items") : depth0),{"name":"each","hash":{},"fn":container.program(1, data, 0),"inverse":container.noop,"data":data,"loc":{"start":{"line":60,"column":4},"end":{"line":76,"column":13}}})) != null ? stack1 : "")
|
||||
+ " </main>\n <footer class=\"footer mt-auto py-3 bg-light\">\n <div class=\"container-fluid\">\n <p class=\"text-muted\">\n <span>All rights belong to the original authors. Powered by <a href=\"https://github.com/dethos/worker-planet\">worker-planet</a>.</span>\n <span class=\"float-end\"><a href=\"#\">Back to top</a></span>\n </p>\n </div>\n </footer>\n <div class=\"offcanvas offcanvas-end\" tabindex=\"-1\" id=\"aboutPanel\" aria-labelledby=\"aboutLabel\">\n <div class=\"offcanvas-header\">\n <h4 id=\"aboutLabel\">About</h4>\n <button type=\"button\" class=\"btn-close text-reset\" data-bs-dismiss=\"offcanvas\" aria-label=\"Close\"></button>\n </div>\n <div class=\"offcanvas-body\">\n <p>"
|
||||
+ alias4(((helper = (helper = lookupProperty(helpers,"page_description") || (depth0 != null ? lookupProperty(depth0,"page_description") : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"page_description","hash":{},"data":data,"loc":{"start":{"line":92,"column":9},"end":{"line":92,"column":29}}}) : helper)))
|
||||
+ "</p>\n\n <h5>Sources</h5>\n <ul>\n"
|
||||
+ ((stack1 = lookupProperty(helpers,"each").call(alias1,(depth0 != null ? lookupProperty(depth0,"sources") : depth0),{"name":"each","hash":{},"fn":container.program(3, data, 0),"inverse":container.noop,"data":data,"loc":{"start":{"line":96,"column":8},"end":{"line":98,"column":17}}})) != null ? stack1 : "")
|
||||
+ " </ul>\n </div>\n </div>\n <script src=\"https://cdn.jsdelivr.net/npm/bootstrap@5.0.1/dist/js/bootstrap.bundle.min.js\"\n integrity=\"sha384-gtEjrD/SeCtmISkJkNUaaKMoLD0//ElJ19smozuHV6z3Iehds+3Ulb9Bn9Plx0x4\" crossorigin=\"anonymous\"></script>\n</body>\n\n</html>\n";
|
||||
},"useData":true});
|
|
@ -0,0 +1,80 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>{{page_title}}</title>
|
||||
<meta property="og:title" content="{{page_title}}" />
|
||||
<meta property="og:description" content="{{page_description}}" />
|
||||
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-hashes' 'sha256-2drSom6Fplo+OFvNUVKnb+wZyrq6v1lOEkVaexi/Fw4=' 'sha256-JeTyInHTbNelTT9AfPH8MBCkB4sU4yMQjoaIQNeLIZ8='; style-src https://cdn.jsdelivr.net/npm/@picocss/pico@1/css/pico.min.css;" />
|
||||
<link rel="alternate" type="application/rss+xml" title="Planet RSS feed" href="/rss" />
|
||||
<link rel="alternate" type="application/atom+xml" title="Planet Atom feed" href="/atom" />
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@picocss/pico@1/css/pico.min.css">
|
||||
</head>
|
||||
<body>
|
||||
<nav class="container">
|
||||
<ul>
|
||||
<li></li>
|
||||
</ul>
|
||||
<ul>
|
||||
<li><a href="/rss">RSS</a></li>
|
||||
<li><a href="https://github.com/dethos/worker-planet">Code</a></li>
|
||||
<li><a href="#open" onclick="document.getElementById('sources').setAttribute('open', '');">Sources</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
<main class="container-fluid">
|
||||
<div class="grid">
|
||||
<div class="container">
|
||||
<hgroup>
|
||||
<h1>{{page_title}}</h1>
|
||||
<h3>{{page_description}}</h3>
|
||||
</hgroup>
|
||||
</div>
|
||||
</div>
|
||||
{{#each items}}
|
||||
{{#isRowElemN @index 4 0 }}
|
||||
<div class="grid">
|
||||
{{/isRowElemN}}
|
||||
<article>
|
||||
<hgroup>
|
||||
<h3>{{title}}</h2>
|
||||
<small>{{formattedDate}}</small>
|
||||
</hgroup>
|
||||
<p>
|
||||
{{{description}}}
|
||||
</p>
|
||||
<p>
|
||||
<a href="{{link}}">More</a>
|
||||
</p>
|
||||
</article>
|
||||
{{#isRowElemN @index 4 3}}
|
||||
</div>
|
||||
{{/isRowElemN}}
|
||||
{{/each}}
|
||||
</main>
|
||||
<footer>
|
||||
<div class="container">
|
||||
<p>
|
||||
All rights belong to the original authors. Powered by <a href="https://github.com/dethos/worker-planet">worker-planet</a>.
|
||||
</p>
|
||||
</div>
|
||||
</footer>
|
||||
<dialog id="sources">
|
||||
<article>
|
||||
<header>
|
||||
<a href="#close" aria-label="Close" class="close" onclick="document.getElementById('sources').removeAttribute('open');"></a>
|
||||
Sources
|
||||
</header>
|
||||
<p>The content of this page is fetched from the following sources:</p>
|
||||
<p>
|
||||
<ul>
|
||||
{{#each sources}}
|
||||
<li><a href="{{link}}">{{name}}</a></li>
|
||||
{{/each}}
|
||||
</ul>
|
||||
</p>
|
||||
</article>
|
||||
</dialog>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,61 @@
|
|||
var Handlebars = require("handlebars/runtime"); var template = Handlebars.template, templates = Handlebars.templates = Handlebars.templates || {};
|
||||
templates['headlines'] = template({"1":function(container,depth0,helpers,partials,data) {
|
||||
var stack1, helper, alias1=depth0 != null ? depth0 : (container.nullContext || {}), alias2=container.hooks.helperMissing, alias3="function", alias4=container.escapeExpression, lookupProperty = container.lookupProperty || function(parent, propertyName) {
|
||||
if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
|
||||
return parent[propertyName];
|
||||
}
|
||||
return undefined
|
||||
};
|
||||
|
||||
return ((stack1 = (lookupProperty(helpers,"isRowElemN")||(depth0 && lookupProperty(depth0,"isRowElemN"))||alias2).call(alias1,(data && lookupProperty(data,"index")),4,0,{"name":"isRowElemN","hash":{},"fn":container.program(2, data, 0),"inverse":container.noop,"data":data,"loc":{"start":{"line":36,"column":8},"end":{"line":38,"column":23}}})) != null ? stack1 : "")
|
||||
+ " <article>\n <hgroup>\n <h3>"
|
||||
+ alias4(((helper = (helper = lookupProperty(helpers,"title") || (depth0 != null ? lookupProperty(depth0,"title") : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"title","hash":{},"data":data,"loc":{"start":{"line":41,"column":18},"end":{"line":41,"column":27}}}) : helper)))
|
||||
+ "</h2>\n <small>"
|
||||
+ alias4(((helper = (helper = lookupProperty(helpers,"formattedDate") || (depth0 != null ? lookupProperty(depth0,"formattedDate") : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"formattedDate","hash":{},"data":data,"loc":{"start":{"line":42,"column":21},"end":{"line":42,"column":38}}}) : helper)))
|
||||
+ "</small>\n </hgroup>\n <p>\n "
|
||||
+ ((stack1 = ((helper = (helper = lookupProperty(helpers,"description") || (depth0 != null ? lookupProperty(depth0,"description") : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"description","hash":{},"data":data,"loc":{"start":{"line":45,"column":14},"end":{"line":45,"column":31}}}) : helper))) != null ? stack1 : "")
|
||||
+ "\n </p>\n <p>\n <a href=\""
|
||||
+ alias4(((helper = (helper = lookupProperty(helpers,"link") || (depth0 != null ? lookupProperty(depth0,"link") : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"link","hash":{},"data":data,"loc":{"start":{"line":48,"column":23},"end":{"line":48,"column":31}}}) : helper)))
|
||||
+ "\">More</a>\n </p>\n </article>\n"
|
||||
+ ((stack1 = (lookupProperty(helpers,"isRowElemN")||(depth0 && lookupProperty(depth0,"isRowElemN"))||alias2).call(alias1,(data && lookupProperty(data,"index")),4,3,{"name":"isRowElemN","hash":{},"fn":container.program(4, data, 0),"inverse":container.noop,"data":data,"loc":{"start":{"line":51,"column":8},"end":{"line":53,"column":23}}})) != null ? stack1 : "");
|
||||
},"2":function(container,depth0,helpers,partials,data) {
|
||||
return " <div class=\"grid\">\n";
|
||||
},"4":function(container,depth0,helpers,partials,data) {
|
||||
return " </div>\n";
|
||||
},"6":function(container,depth0,helpers,partials,data) {
|
||||
var helper, alias1=depth0 != null ? depth0 : (container.nullContext || {}), alias2=container.hooks.helperMissing, alias3="function", alias4=container.escapeExpression, lookupProperty = container.lookupProperty || function(parent, propertyName) {
|
||||
if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
|
||||
return parent[propertyName];
|
||||
}
|
||||
return undefined
|
||||
};
|
||||
|
||||
return " <li><a href=\""
|
||||
+ alias4(((helper = (helper = lookupProperty(helpers,"link") || (depth0 != null ? lookupProperty(depth0,"link") : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"link","hash":{},"data":data,"loc":{"start":{"line":73,"column":27},"end":{"line":73,"column":35}}}) : helper)))
|
||||
+ "\">"
|
||||
+ alias4(((helper = (helper = lookupProperty(helpers,"name") || (depth0 != null ? lookupProperty(depth0,"name") : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"name","hash":{},"data":data,"loc":{"start":{"line":73,"column":37},"end":{"line":73,"column":45}}}) : helper)))
|
||||
+ "</a></li>\n";
|
||||
},"compiler":[8,">= 4.3.0"],"main":function(container,depth0,helpers,partials,data) {
|
||||
var stack1, helper, alias1=depth0 != null ? depth0 : (container.nullContext || {}), alias2=container.hooks.helperMissing, alias3="function", alias4=container.escapeExpression, lookupProperty = container.lookupProperty || function(parent, propertyName) {
|
||||
if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
|
||||
return parent[propertyName];
|
||||
}
|
||||
return undefined
|
||||
};
|
||||
|
||||
return "<!DOCTYPE html>\n<html lang=\"en\">\n <head>\n <meta charset=\"UTF-8\">\n <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <title>"
|
||||
+ alias4(((helper = (helper = lookupProperty(helpers,"page_title") || (depth0 != null ? lookupProperty(depth0,"page_title") : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"page_title","hash":{},"data":data,"loc":{"start":{"line":7,"column":11},"end":{"line":7,"column":25}}}) : helper)))
|
||||
+ "</title>\n <meta property=\"og:title\" content=\""
|
||||
+ alias4(((helper = (helper = lookupProperty(helpers,"page_title") || (depth0 != null ? lookupProperty(depth0,"page_title") : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"page_title","hash":{},"data":data,"loc":{"start":{"line":8,"column":39},"end":{"line":8,"column":53}}}) : helper)))
|
||||
+ "\" />\n <meta property=\"og:description\" content=\""
|
||||
+ alias4(((helper = (helper = lookupProperty(helpers,"page_description") || (depth0 != null ? lookupProperty(depth0,"page_description") : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"page_description","hash":{},"data":data,"loc":{"start":{"line":9,"column":45},"end":{"line":9,"column":65}}}) : helper)))
|
||||
+ "\" />\n <meta http-equiv=\"Content-Security-Policy\" content=\"script-src 'self' 'unsafe-hashes' 'sha256-2drSom6Fplo+OFvNUVKnb+wZyrq6v1lOEkVaexi/Fw4=' 'sha256-JeTyInHTbNelTT9AfPH8MBCkB4sU4yMQjoaIQNeLIZ8='; style-src https://cdn.jsdelivr.net/npm/@picocss/pico@1/css/pico.min.css;\" />\n <link rel=\"alternate\" type=\"application/rss+xml\" title=\"Planet RSS feed\" href=\"/rss\" />\n <link rel=\"alternate\" type=\"application/atom+xml\" title=\"Planet Atom feed\" href=\"/atom\" />\n <link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/npm/@picocss/pico@1/css/pico.min.css\">\n </head>\n <body>\n <nav class=\"container\">\n <ul>\n <li></li>\n </ul>\n <ul>\n <li><a href=\"/rss\">RSS</a></li>\n <li><a href=\"https://github.com/dethos/worker-planet\">Code</a></li>\n <li><a href=\"#open\" onclick=\"document.getElementById('sources').setAttribute('open', '');\">Sources</a></li>\n </ul>\n </nav>\n <main class=\"container-fluid\">\n <div class=\"grid\">\n <div class=\"container\">\n <hgroup>\n <h1>"
|
||||
+ alias4(((helper = (helper = lookupProperty(helpers,"page_title") || (depth0 != null ? lookupProperty(depth0,"page_title") : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"page_title","hash":{},"data":data,"loc":{"start":{"line":30,"column":16},"end":{"line":30,"column":30}}}) : helper)))
|
||||
+ "</h1>\n <h3>"
|
||||
+ alias4(((helper = (helper = lookupProperty(helpers,"page_description") || (depth0 != null ? lookupProperty(depth0,"page_description") : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"page_description","hash":{},"data":data,"loc":{"start":{"line":31,"column":16},"end":{"line":31,"column":36}}}) : helper)))
|
||||
+ "</h3>\n </hgroup>\n </div>\n </div>\n"
|
||||
+ ((stack1 = lookupProperty(helpers,"each").call(alias1,(depth0 != null ? lookupProperty(depth0,"items") : depth0),{"name":"each","hash":{},"fn":container.program(1, data, 0),"inverse":container.noop,"data":data,"loc":{"start":{"line":35,"column":6},"end":{"line":54,"column":15}}})) != null ? stack1 : "")
|
||||
+ " </main>\n <footer>\n <div class=\"container\">\n <p>\n All rights belong to the original authors. Powered by <a href=\"https://github.com/dethos/worker-planet\">worker-planet</a>.\n </p>\n </div>\n </footer>\n <dialog id=\"sources\">\n <article>\n <header>\n <a href=\"#close\" aria-label=\"Close\" class=\"close\" onclick=\"document.getElementById('sources').removeAttribute('open');\"></a>\n Sources\n </header>\n <p>The content of this page is fetched from the following sources:</p>\n <p>\n <ul>\n"
|
||||
+ ((stack1 = lookupProperty(helpers,"each").call(alias1,(depth0 != null ? lookupProperty(depth0,"sources") : depth0),{"name":"each","hash":{},"fn":container.program(6, data, 0),"inverse":container.noop,"data":data,"loc":{"start":{"line":72,"column":12},"end":{"line":74,"column":21}}})) != null ? stack1 : "")
|
||||
+ " </ul>\n </p>\n </article>\n </dialog>\n </body>\n</html>";
|
||||
},"useData":true});
|
|
@ -1,376 +0,0 @@
|
|||
var Handlebars = require('handlebars/runtime')
|
||||
var template = Handlebars.template,
|
||||
templates = (Handlebars.templates = Handlebars.templates || {})
|
||||
templates['list_posts'] = template({
|
||||
'1': function(container, depth0, helpers, partials, data) {
|
||||
var stack1,
|
||||
helper,
|
||||
alias1 = depth0 != null ? depth0 : container.nullContext || {},
|
||||
alias2 = container.hooks.helperMissing,
|
||||
alias3 = 'function',
|
||||
alias4 = container.escapeExpression,
|
||||
lookupProperty =
|
||||
container.lookupProperty ||
|
||||
function(parent, propertyName) {
|
||||
if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
|
||||
return parent[propertyName]
|
||||
}
|
||||
return undefined
|
||||
}
|
||||
|
||||
return (
|
||||
' <div class="row p-2">\n <article>\n <div class="card">\n <div class="card-body">\n <h2 class="card-title"><a href="' +
|
||||
alias4(
|
||||
((helper =
|
||||
(helper =
|
||||
lookupProperty(helpers, 'link') ||
|
||||
(depth0 != null ? lookupProperty(depth0, 'link') : depth0)) != null
|
||||
? helper
|
||||
: alias2),
|
||||
typeof helper === alias3
|
||||
? helper.call(alias1, {
|
||||
name: 'link',
|
||||
hash: {},
|
||||
data: data,
|
||||
loc: {
|
||||
start: { line: 61, column: 44 },
|
||||
end: { line: 61, column: 52 },
|
||||
},
|
||||
})
|
||||
: helper),
|
||||
) +
|
||||
'">' +
|
||||
alias4(
|
||||
((helper =
|
||||
(helper =
|
||||
lookupProperty(helpers, 'title') ||
|
||||
(depth0 != null ? lookupProperty(depth0, 'title') : depth0)) != null
|
||||
? helper
|
||||
: alias2),
|
||||
typeof helper === alias3
|
||||
? helper.call(alias1, {
|
||||
name: 'title',
|
||||
hash: {},
|
||||
data: data,
|
||||
loc: {
|
||||
start: { line: 61, column: 54 },
|
||||
end: { line: 61, column: 63 },
|
||||
},
|
||||
})
|
||||
: helper),
|
||||
) +
|
||||
'</a></h2>\n <p class="card-subtitle mb-2 text-muted">\n <small>Date: ' +
|
||||
alias4(
|
||||
((helper =
|
||||
(helper =
|
||||
lookupProperty(helpers, 'pubDate') ||
|
||||
(depth0 != null ? lookupProperty(depth0, 'pubDate') : depth0)) !=
|
||||
null
|
||||
? helper
|
||||
: alias2),
|
||||
typeof helper === alias3
|
||||
? helper.call(alias1, {
|
||||
name: 'pubDate',
|
||||
hash: {},
|
||||
data: data,
|
||||
loc: {
|
||||
start: { line: 63, column: 27 },
|
||||
end: { line: 63, column: 38 },
|
||||
},
|
||||
})
|
||||
: helper),
|
||||
) +
|
||||
'</small><br>\n <small>Source: <a href="' +
|
||||
alias4(
|
||||
((helper =
|
||||
(helper =
|
||||
lookupProperty(helpers, 'source_link') ||
|
||||
(depth0 != null
|
||||
? lookupProperty(depth0, 'source_link')
|
||||
: depth0)) != null
|
||||
? helper
|
||||
: alias2),
|
||||
typeof helper === alias3
|
||||
? helper.call(alias1, {
|
||||
name: 'source_link',
|
||||
hash: {},
|
||||
data: data,
|
||||
loc: {
|
||||
start: { line: 64, column: 38 },
|
||||
end: { line: 64, column: 53 },
|
||||
},
|
||||
})
|
||||
: helper),
|
||||
) +
|
||||
'">' +
|
||||
alias4(
|
||||
((helper =
|
||||
(helper =
|
||||
lookupProperty(helpers, 'source_title') ||
|
||||
(depth0 != null
|
||||
? lookupProperty(depth0, 'source_title')
|
||||
: depth0)) != null
|
||||
? helper
|
||||
: alias2),
|
||||
typeof helper === alias3
|
||||
? helper.call(alias1, {
|
||||
name: 'source_title',
|
||||
hash: {},
|
||||
data: data,
|
||||
loc: {
|
||||
start: { line: 64, column: 55 },
|
||||
end: { line: 64, column: 71 },
|
||||
},
|
||||
})
|
||||
: helper),
|
||||
) +
|
||||
'</a></small>\n </p>\n\n ' +
|
||||
((stack1 =
|
||||
((helper =
|
||||
(helper =
|
||||
lookupProperty(helpers, 'content') ||
|
||||
(depth0 != null ? lookupProperty(depth0, 'content') : depth0)) !=
|
||||
null
|
||||
? helper
|
||||
: alias2),
|
||||
typeof helper === alias3
|
||||
? helper.call(alias1, {
|
||||
name: 'content',
|
||||
hash: {},
|
||||
data: data,
|
||||
loc: {
|
||||
start: { line: 67, column: 12 },
|
||||
end: { line: 67, column: 25 },
|
||||
},
|
||||
})
|
||||
: helper)) != null
|
||||
? stack1
|
||||
: '') +
|
||||
'\n </div>\n </div>\n </article>\n </div>\n'
|
||||
)
|
||||
},
|
||||
'3': function(container, depth0, helpers, partials, data) {
|
||||
var helper,
|
||||
alias1 = depth0 != null ? depth0 : container.nullContext || {},
|
||||
alias2 = container.hooks.helperMissing,
|
||||
alias3 = 'function',
|
||||
alias4 = container.escapeExpression,
|
||||
lookupProperty =
|
||||
container.lookupProperty ||
|
||||
function(parent, propertyName) {
|
||||
if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
|
||||
return parent[propertyName]
|
||||
}
|
||||
return undefined
|
||||
}
|
||||
|
||||
return (
|
||||
' <li><a href="' +
|
||||
alias4(
|
||||
((helper =
|
||||
(helper =
|
||||
lookupProperty(helpers, 'link') ||
|
||||
(depth0 != null ? lookupProperty(depth0, 'link') : depth0)) != null
|
||||
? helper
|
||||
: alias2),
|
||||
typeof helper === alias3
|
||||
? helper.call(alias1, {
|
||||
name: 'link',
|
||||
hash: {},
|
||||
data: data,
|
||||
loc: {
|
||||
start: { line: 93, column: 23 },
|
||||
end: { line: 93, column: 31 },
|
||||
},
|
||||
})
|
||||
: helper),
|
||||
) +
|
||||
'">' +
|
||||
alias4(
|
||||
((helper =
|
||||
(helper =
|
||||
lookupProperty(helpers, 'name') ||
|
||||
(depth0 != null ? lookupProperty(depth0, 'name') : depth0)) != null
|
||||
? helper
|
||||
: alias2),
|
||||
typeof helper === alias3
|
||||
? helper.call(alias1, {
|
||||
name: 'name',
|
||||
hash: {},
|
||||
data: data,
|
||||
loc: {
|
||||
start: { line: 93, column: 33 },
|
||||
end: { line: 93, column: 41 },
|
||||
},
|
||||
})
|
||||
: helper),
|
||||
) +
|
||||
'</a></li>\n'
|
||||
)
|
||||
},
|
||||
compiler: [8, '>= 4.3.0'],
|
||||
main: function(container, depth0, helpers, partials, data) {
|
||||
var stack1,
|
||||
helper,
|
||||
alias1 = depth0 != null ? depth0 : container.nullContext || {},
|
||||
alias2 = container.hooks.helperMissing,
|
||||
alias3 = 'function',
|
||||
alias4 = container.escapeExpression,
|
||||
lookupProperty =
|
||||
container.lookupProperty ||
|
||||
function(parent, propertyName) {
|
||||
if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
|
||||
return parent[propertyName]
|
||||
}
|
||||
return undefined
|
||||
}
|
||||
|
||||
return (
|
||||
'<!DOCTYPE html>\n<html lang="en">\n\n<head>\n <meta charset="UTF-8">\n <meta http-equiv="X-UA-Compatible" content="IE=edge">\n <meta name="viewport" content="width=device-width, initial-scale=1.0">\n <title>' +
|
||||
alias4(
|
||||
((helper =
|
||||
(helper =
|
||||
lookupProperty(helpers, 'page_title') ||
|
||||
(depth0 != null ? lookupProperty(depth0, 'page_title') : depth0)) !=
|
||||
null
|
||||
? helper
|
||||
: alias2),
|
||||
typeof helper === alias3
|
||||
? helper.call(alias1, {
|
||||
name: 'page_title',
|
||||
hash: {},
|
||||
data: data,
|
||||
loc: {
|
||||
start: { line: 8, column: 9 },
|
||||
end: { line: 8, column: 23 },
|
||||
},
|
||||
})
|
||||
: helper),
|
||||
) +
|
||||
'</title>\n <meta property="og:title" content="' +
|
||||
alias4(
|
||||
((helper =
|
||||
(helper =
|
||||
lookupProperty(helpers, 'page_title') ||
|
||||
(depth0 != null ? lookupProperty(depth0, 'page_title') : depth0)) !=
|
||||
null
|
||||
? helper
|
||||
: alias2),
|
||||
typeof helper === alias3
|
||||
? helper.call(alias1, {
|
||||
name: 'page_title',
|
||||
hash: {},
|
||||
data: data,
|
||||
loc: {
|
||||
start: { line: 9, column: 37 },
|
||||
end: { line: 9, column: 51 },
|
||||
},
|
||||
})
|
||||
: helper),
|
||||
) +
|
||||
'" />\n <meta property="og:description" content="' +
|
||||
alias4(
|
||||
((helper =
|
||||
(helper =
|
||||
lookupProperty(helpers, 'page_description') ||
|
||||
(depth0 != null
|
||||
? lookupProperty(depth0, 'page_description')
|
||||
: depth0)) != null
|
||||
? helper
|
||||
: alias2),
|
||||
typeof helper === alias3
|
||||
? helper.call(alias1, {
|
||||
name: 'page_description',
|
||||
hash: {},
|
||||
data: data,
|
||||
loc: {
|
||||
start: { line: 10, column: 43 },
|
||||
end: { line: 10, column: 63 },
|
||||
},
|
||||
})
|
||||
: helper),
|
||||
) +
|
||||
'" />\n <meta http-equiv="Content-Security-Policy" content="script-src https://cdn.jsdelivr.net/npm/bootstrap@5.0.1/dist/js/bootstrap.bundle.min.js; style-src https://cdn.jsdelivr.net/npm/bootstrap@5.0.1/dist/css/bootstrap.min.css https://cdn.jsdelivr.net/npm/bootstrap-icons@1.5.0/font/bootstrap-icons.css \'sha256-Rlrl8UtcuZXDdr9KU9SZlhcRnb8Epry8Jgy1xIoCOkg=\';">\n <link rel="alternate" type="application/rss+xml" title="Planet RSS feed" href="/rss" />\n <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.1/dist/css/bootstrap.min.css" rel="stylesheet"\n integrity="sha384-+0n0xVW2eSR5OomGNYDnhzAbDsOXxcvSN1TPprVMTNDbiYZCxYbOOl7+AMvyTG2x" crossorigin="anonymous" />\n <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.5.0/font/bootstrap-icons.css"\n integrity="sha256-PDJQdTN7dolQWDASIoBVrjkuOEaI137FI15sqI3Oxu8=" crossorigin="anonymous" />\n <style>\n img {\n width: 100% !important;\n max-width:600px !important;\n height: auto;\n }\n code {\n display: block;\n white-space: pre-wrap;\n overflow-wrap: break-word;\n }\n </style>\n</head>\n\n<body>\n <nav class="navbar navbar-expand-lg navbar-light bg-light">\n <div class="container-fluid">\n <a class="navbar-brand" href="#">' +
|
||||
alias4(
|
||||
((helper =
|
||||
(helper =
|
||||
lookupProperty(helpers, 'page_title') ||
|
||||
(depth0 != null ? lookupProperty(depth0, 'page_title') : depth0)) !=
|
||||
null
|
||||
? helper
|
||||
: alias2),
|
||||
typeof helper === alias3
|
||||
? helper.call(alias1, {
|
||||
name: 'page_title',
|
||||
hash: {},
|
||||
data: data,
|
||||
loc: {
|
||||
start: { line: 34, column: 39 },
|
||||
end: { line: 34, column: 53 },
|
||||
},
|
||||
})
|
||||
: helper),
|
||||
) +
|
||||
'</a>\n <ul class="navbar-nav ms-auto">\n <li class="nav-item">\n <a class="nav-link active" aria-current="page" href="/rss">\n <i class="bi bi-rss" role="img" aria-label="RSS"></i> RSS Feed\n </a>\n </li>\n <li class="nav-item">\n <a class="nav-link active" aria-current="page" href="https://github.com/dethos/worker-planet">\n <i class="bi bi-github" role="img" aria-label="GitHub"></i> Source Code\n </a>\n </li>\n <li class="nav-item">\n <a class="nav-link active" aria-current="page" data-bs-toggle="offcanvas" data-bs-target="#aboutPanel" aria-controls="offcanvasRight" href="#">\n <i class="bi bi-patch-question" role="img" aria-label="About"></i> About\n </a>\n </li>\n </ul>\n </div>\n </nav>\n\n <main class="container d-grid">\n' +
|
||||
((stack1 = lookupProperty(helpers, 'each').call(
|
||||
alias1,
|
||||
depth0 != null ? lookupProperty(depth0, 'items') : depth0,
|
||||
{
|
||||
name: 'each',
|
||||
hash: {},
|
||||
fn: container.program(1, data, 0),
|
||||
inverse: container.noop,
|
||||
data: data,
|
||||
loc: {
|
||||
start: { line: 56, column: 4 },
|
||||
end: { line: 72, column: 13 },
|
||||
},
|
||||
},
|
||||
)) != null
|
||||
? stack1
|
||||
: '') +
|
||||
' </main>\n <footer class="footer mt-auto py-3 bg-light">\n <div class="container-fluid">\n <p class="text-muted">\n <span>All rights belong to the original authors. Powered by <a href="https://github.com/dethos/worker-planet">worker-planet</a>.</span>\n <span class="float-end"><a href="#">Back to top</a></span>\n </p>\n </div>\n </footer>\n <div class="offcanvas offcanvas-end" tabindex="-1" id="aboutPanel" aria-labelledby="aboutLabel">\n <div class="offcanvas-header">\n <h4 id="aboutLabel">About</h4>\n <button type="button" class="btn-close text-reset" data-bs-dismiss="offcanvas" aria-label="Close"></button>\n </div>\n <div class="offcanvas-body">\n <p>' +
|
||||
alias4(
|
||||
((helper =
|
||||
(helper =
|
||||
lookupProperty(helpers, 'page_description') ||
|
||||
(depth0 != null
|
||||
? lookupProperty(depth0, 'page_description')
|
||||
: depth0)) != null
|
||||
? helper
|
||||
: alias2),
|
||||
typeof helper === alias3
|
||||
? helper.call(alias1, {
|
||||
name: 'page_description',
|
||||
hash: {},
|
||||
data: data,
|
||||
loc: {
|
||||
start: { line: 88, column: 9 },
|
||||
end: { line: 88, column: 29 },
|
||||
},
|
||||
})
|
||||
: helper),
|
||||
) +
|
||||
'</p>\n\n <h5>Sources</h5>\n <ul>\n' +
|
||||
((stack1 = lookupProperty(helpers, 'each').call(
|
||||
alias1,
|
||||
depth0 != null ? lookupProperty(depth0, 'sources') : depth0,
|
||||
{
|
||||
name: 'each',
|
||||
hash: {},
|
||||
fn: container.program(3, data, 0),
|
||||
inverse: container.noop,
|
||||
data: data,
|
||||
loc: {
|
||||
start: { line: 92, column: 8 },
|
||||
end: { line: 94, column: 17 },
|
||||
},
|
||||
},
|
||||
)) != null
|
||||
? stack1
|
||||
: '') +
|
||||
' </ul>\n </div>\n </div>\n <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.1/dist/js/bootstrap.bundle.min.js"\n integrity="sha384-gtEjrD/SeCtmISkJkNUaaKMoLD0//ElJ19smozuHV6z3Iehds+3Ulb9Bn9Plx0x4" crossorigin="anonymous"></script>\n</body>\n\n</html>\n'
|
||||
)
|
||||
},
|
||||
useData: true,
|
||||
})
|
|
@ -0,0 +1,21 @@
|
|||
const path = require('path')
|
||||
const {
|
||||
WranglerJsCompatWebpackPlugin,
|
||||
} = require('wranglerjs-compat-webpack-plugin')
|
||||
|
||||
module.exports = {
|
||||
mode: 'production',
|
||||
entry: './index.js',
|
||||
plugins: [new WranglerJsCompatWebpackPlugin()],
|
||||
resolve: {
|
||||
fallback: {
|
||||
stream: require.resolve('stream-browserify'),
|
||||
http: require.resolve('stream-http'),
|
||||
url: require.resolve('url/'),
|
||||
http: require.resolve('stream-http'),
|
||||
https: require.resolve('https-browserify'),
|
||||
timers: require.resolve('timers-browserify'),
|
||||
buffer: require.resolve('buffer/'),
|
||||
},
|
||||
},
|
||||
}
|
|
@ -1,9 +1,9 @@
|
|||
name = "worker-planet"
|
||||
type = "webpack"
|
||||
main = "./worker/script.js"
|
||||
compatibility_date = "2023-05-18"
|
||||
node_compat = true
|
||||
account_id = ""
|
||||
workers_dev = true
|
||||
route = ""
|
||||
zone_id = ""
|
||||
|
||||
kv_namespaces = [
|
||||
{ binding = "WORKER_PLANET_STORE", id = "", preview_id = "" }
|
||||
|
|
Loading…
Reference in New Issue