Commit e9a88e8c authored by yPhil's avatar yPhil

Pipelines..?

parent 1b428e5b
# Petrolette
*RSS/Atom morning news reader ; Works at night too.*
---
[![License GPLv3](https://img.shields.io/badge/license-GPL_v3-green.svg)](http://www.gnu.org/licenses/gpl-3.0.html) [![Gratipay](http://img.shields.io/gratipay/yassinphilip.svg)](https://www.gratipay.com/yassinphilip/)
Read about it in French [ici](http://linuxfr.org/users/philippemc/journaux/avec-quoi-tu-lis-tes-rss-le-matin).
## Petrolette is a personal track-free online RSS news reader
Petrolette is a simple but powerful web app to view and manage various XML (RSS, aTom, etc) news feeds and present them in a nice, ergonomic fashion. I made it to replace the online news services (NetVibes, Google news, etc.) that I use up until around 2007, when they became bloated and **crippled with spyware**. It's a fast, simple and light system, and I've been using it for ~~weeks~~ years now ; It does what I want from a no-nonsense, every-morning-every-day news reader.
### Practical Features
Make the page your home page, and read it every morning. You know instantly what article you've read ; We're already on the web, right? Just click and read the article. This is *so much better than TV*.
### Technical Features
WIP :)
### LICENSE
This program 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.
This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*Icon by [Buuf](https://mattahan.deviantart.com/art/Buuf-37966044)*
---
var express = require('express');
var path = require('path');
var index = require('./routes/index');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.engine('html', require('ejs').renderFile);
app.set('view engine', 'html');
app.use('/static', express.static(__dirname + '/public'));
app.use('/tmp', express.static(__dirname + '/tmp'));
app.use('/bower', express.static(__dirname + '/bower_components'));
app.use('/', index);
module.exports = app;
#!/usr/bin/env node
/**
* Module dependencies.
*/
var app = require('../app');
var debug = require('debug')('petrolette:server');
var http = require('http');
/**
* Get port from environment and store in Express.
*/
var port = normalizePort(process.env.PORT || '8666');
app.set('port', port);
/**
* Create HTTP server.
*/
var server = http.createServer(app);
/**
* Listen on provided port, on all network interfaces.
*/
server.listen(port);
server.on('error', onError);
server.on('listening', onListening);
/**
* Normalize a port into a number, string, or false.
*/
function normalizePort(val) {
var port = parseInt(val, 10);
if (isNaN(port)) {
// named pipe
return val;
}
if (port >= 0) {
// port number
return port;
}
return false;
}
/**
* Event listener for HTTP server "error" event.
*/
function onError(error) {
if (error.syscall !== 'listen') {
throw error;
}
var bind = typeof port === 'string'
? 'Pipe ' + port
: 'Port ' + port;
// handle specific listen errors with friendly messages
switch (error.code) {
case 'EACCES':
console.error(bind + ' requires elevated privileges');
process.exit(1);
break;
case 'EADDRINUSE':
console.error(bind + ' is already in use');
process.exit(1);
break;
default:
throw error;
}
}
/**
* Event listener for HTTP server "listening" event.
*/
function onListening() {
var addr = server.address();
var bind = typeof addr === 'string'
? 'pipe ' + addr
: 'port ' + addr.port;
debug('Listening on ' + bind);
}
{
"name": "petrolette",
"version": "0.4.5",
"description": "Fly by night RSS feed reader",
"main": "",
"authors": [
"yassinphilip <xaccrocheur@gmail.com>"
],
"license": "GPLv3",
"keywords": [
"rss"
],
"homepage": "",
"ignore": [
"**/.*",
"node_modules",
"bower_components",
"test",
"tests"
],
"dependencies": {
"jquery-ui": "^1.12.1",
"fancybox": "^3.1.25",
"notifyjs": "latest",
"intro.js": "latest"
}
}
{
"legacyWatch": true,
"ignoreRoot": [".git"]
}
This diff is collapsed.
{
"name": "petrolette",
"version": "0.8.1",
"private": true,
"engines": {
"node": "8.5.0"
},
"scripts": {
"start": "pm2 start bin/www --watch --name petrolette",
"stop": "pm2 stop petrolette",
"postinstall": "bower install"
},
"devDependencies": {
"mocha": "latest",
"should": "latest"
},
"dependencies": {
"body-parser": "~1.18.2",
"bower": "^1.3.2",
"cookie-parser": "~1.4.3",
"cors": "2.8.4",
"debug": "~2.6.9",
"ejs": "^2.5.7",
"express": "~4.15.5",
"favicon": "0.0.2",
"feedparser": "2.2.2",
"feedrat": "0.1.30",
"find-favicon": "0.1.2",
"hyperquest": "2.1.2",
"jquery": "3.2.1",
"jquery-ui": "1.12.1",
"pm2": "2.8.0"
}
}
This diff is collapsed.
@font-face {
font-family: 'fontello';
src: url('../font/fontello.eot?32980406');
src: url('../font/fontello.eot?32980406#iefix') format('embedded-opentype'),
url('../font/fontello.woff2?32980406') format('woff2'),
url('../font/fontello.woff?32980406') format('woff'),
url('../font/fontello.ttf?32980406') format('truetype'),
url('../font/fontello.svg?32980406#fontello') format('svg');
font-weight: normal;
font-style: normal;
}
/* Chrome hack: SVG is rendered more smooth in Windozze. 100% magic, uncomment if you need it. */
/* Note, that will break hinting! In other OS-es font will be not as sharp as it could be */
/*
@media screen and (-webkit-min-device-pixel-ratio:0) {
@font-face {
font-family: 'fontello';
src: url('../font/fontello.svg?32980406#fontello') format('svg');
}
}
*/
[class^="icon-"]:before, [class*=" icon-"]:before {
font-family: "fontello";
font-style: normal;
font-weight: normal;
speak: none;
display: inline-block;
text-decoration: inherit;
width: 1em;
margin-right: .2em;
text-align: center;
/* opacity: .8; */
/* For safety - reset parent styles, that can break glyph codes*/
font-variant: normal;
text-transform: none;
/* fix buttons height, for twitter bootstrap */
line-height: 1em;
/* Animation center compensation - margins should be symmetric */
/* remove if not needed */
margin-left: .2em;
/* you can be more comfortable with increased icons size */
/* font-size: 120%; */
/* Font smoothing. That was taken from TWBS */
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
/* Uncomment for 3D effect */
/* text-shadow: 1px 1px 1px rgba(127, 127, 127, 0.3); */
}
.icon-arrows-cw:before { content: '\e800'; } /* '' */
.icon-help-circled:before { content: '\e801'; } /* '' */
.icon-cog:before { content: '\e803'; } /* '' */
.icon-down-open:before { content: '\e805'; } /* '' */
.icon-ok:before { content: '\e807'; } /* '' */
.icon-check-empty:before { content: '\e808'; } /* '' */
.icon-cancel-circled:before { content: '\e809'; } /* '' */
.icon-trash-empty:before { content: '\e80a'; } /* '' */
.icon-cancel-circled-outline:before { content: '\e80b'; } /* '' */
.icon-trash:before { content: '\e80c'; } /* '' */
.icon-sun:before { content: '\e80d'; } /* '' */
.icon-book-open:before { content: '\e80f'; } /* '' */
.icon-heart:before { content: '\e810'; } /* '' */
.icon-heart-empty:before { content: '\e811'; } /* '' */
.icon-flashlight:before { content: '\e812'; } /* '' */
.icon-plus-1:before { content: '\e813'; } /* '' */
.icon-police:before { content: '\e82b'; } /* '' */
.icon-right-open:before { content: '\f006'; } /* '' */
.icon-left-open:before { content: '\f007'; } /* '' */
.icon-download:before { content: '\f02e'; } /* '' */
.icon-upload:before { content: '\f02f'; } /* '' */
.icon-check-empty-1:before { content: '\f096'; } /* '' */
.icon-sun-1:before { content: '\f185'; } /* '' */
.icon-motorcycle:before { content: '\f21c'; } /* '' */
.icon-heartbeat:before { content: '\f21e'; } /* '' */
\ No newline at end of file
This diff is collapsed.
html {
font-size: 100%;
overflow-y: scroll;
/* -webkit-text-size-adjust: 100%; */
/* -ms-text-size-adjust: 100%; */
}
/* Bootstrapping */
ul {
list-style-type: none;
margin:0;
padding:0;
}
/* Petrolette */
body {
/* font-size:.8em !important; */
margin:0 !important;
}
@font-face {
font-family: LobsterRegular;
src: url('/static/font/Lobster.otf') format("opentype");
src: url('/static/font/Lobster.ttf') format('truetype');
font-weight: normal;
font-style: normal;
}
@font-face {
font-family: Ubuntu;
src: url('/static/font/ubuntu/Ubuntu-R.ttf') format("truetype");
font-weight: normal;
font-style: normal;
}
/* TABS */
li.mobTab,
#newTabButton {
margin: 0 0 0 0 !important;
border: 0 !important;
border-radius: 0 !important;
box-shadow: inset 4px 0px 6px -4px rgba(0,0,0,0.19) !important;
}
.tabCloser {
display: none;
}
/* FEEDS */
.ui-tabs-panel {
padding:0 !important;
}
@keyframes spin-animation {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(359deg);
}
}
.spin {
animation: spin-animation 0.5s infinite;
display: inline-block;
}
#waitScreen > .spin {
animation: spin-animation 2s infinite;
font-size: 400%;
}
.rotate {
display:inline-block;
cursor:pointer;
transition: all .2s linear;
}
.rotate.down {
transform: rotate(-90deg);
}
.rotate.close {
transform: rotate(-180deg);
}
/* Fontello */
i[class^="icon-"]:before, i[class*=" icon-"]:before {
margin: 0;
}
.tab {
border: none !important;
margin:0 !important;
}
#tabs li .ui-icon-close {
/* float: left; */
/* margin: 0.4em 0.2em 0 0; */
cursor: pointer;
}
.newFeedButton {
position: absolute;
text-align: center;
cursor: pointer;
/* float: right; */
top: 0px;
right: .2em;
width: 78px;
height: 78px;
}
.newFeedButton > p {
margin: 6px -92px 5px auto;
vertical-align:middle;
}
.newFeedButton > p > span.plus {
font-weight: normal;
}
.newFeedButton > p > span.text {
position: relative;
top: 5px;
opacity: 0.1;
font-size: 1em;
font-weight: bold;
}
/* Feed */
ul.tabSort {
/* display: flex; */
/* flex-wrap: wrap; */
/* align-items:flex-start; */
/* padding-bottom: 0px !important; */
/* column-count: 3; */
/* columns: 15em; */
/* column-gap: .3em; */
padding: 0 .2em .2em;
columns: 18rem;
column-gap: .3em;
min-height:30px;
}
li.feed {
font-family: Verdana, Arial, sans-serif;
page-break-inside: avoid;
break-inside: avoid;
display: inline-block;
break-inside: avoid;
vertical-align:top;
margin: .2em 0 0 0;
/* break-inside: avoid-column; */
/* padding: 5px; */
}
.ui-tabs .ui-tabs-nav li.ui-tabs-active .ui-tabs-anchor {
cursor: pointer !important;
}
.selected,
li.feed {
width: 100%;
min-height:20px !important;
}
.feedBody {
margin: 0;
}
.selected {
opacity: 0.5;
}
/* Item */
li.feedItem {
font-size: 10pt !important;
}
li.feedItem a:not(.error) {
display: block;
width:100%;
font-weight: bold;
}
li.feedItem {
padding: .2rem;
}
div.feedItem img {
max-width:30%;
float:left;
margin: 0 .2rem .2rem 0; /* Some gutter */
}
div.feedItem img.full {
min-width:100%;
}
.feedIcon {
width: 18px;
height: 18px;
background-image: url("/static/images/feed-generic-rss.png");
background-size: 18px;
background-repeat: no-repeat;
}
.tabSort .ui-sortable-placeholder {
visibility: visible !important;
border: 3px dashed !important;
}
.feedToggle > .ui-icon {
margin: .1rem .2rem 0 .1rem;
}
li.feedItem {
border:0 !important;
}
/* Theme Overrides */
.ui-widget-content,
.ui-widget-header {
border: none !important;
}
.feed {
border: #AAAAAA 1px solid !important;
padding: 0;
}
.introjs-helperLayer {
background-color: rgba(255,255,255,.1) !important;
}
.introjs-helperNumberLayer {
position: absolute !important;
top: -16px !important;
left: -9px !important;
z-index: 9999999999 !important;
padding: 2px !important;
font-family: Arial, verdana, tahoma !important;
font-size: 13px !important;
font-weight: bold !important;
color: #fff !important;
background: #DA4433 !important;
width: 20px !important;
box-shadow: 0 1px 1px rgba(0,0,0,.35) !important;
height: 20px !important;
text-align: center !important;
line-height: 20px !important;
border: 2px solid #DA4433 !important;
border-radius: 0 !important;
}
.introjs-helperNumberLayer::after {
content: "" !important;
width: 0 !important;
height: 0 !important;
position: absolute !important;
content: 0 !important;
left: -3px !important;
bottom: -10px !important;
border: 4px solid transparent !important;
border-right-color: #900 !important;
border-top-color: #900 !important;
}
div.wiki {
float:right;
}
div.wiki i:hover {
color: green;
}
i.feedIcon {
background-image:url("/static/images/feed-generic-rss.png");
}
#loadRadial {
position:fixed;
right:3vw;
bottom:5vh;
opacity:0.5;
}
#loadRadial .fill,
#loadRadial .bar {
border-color: var(--color-qua) !important;
}
:root {
--bg-color-pri: #C3DCD9;
--bg-color-sec: #eeeeee;
--bg-color-ter: #DDE0FA;
--bg-color-qua: #e3eff3;
--color-pri: #3C4440;
--color-sec: #5294E2;
--color-tri: #FFDC00;
--color-qua: #7395AE;
--color-danger: #660000;
}
.arrow {
background-image: url("/static/images/feed-toggle-triangle-000.png") !important;
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/* Item */
li.feedItem a {
display: block;
width:100%;
color: #fff;
}
li.feedItem a:link {
}
li.feedItem a:visited {
color: #ddd !important;
}
li.feedItem a:hover {
color: #f00 !important;
}
li.feedItem a:active {
/* color: blue; */
}
li.feedItem {
background-color: #eee !important;
padding: .2rem;
}
li.feedItem:nth-child(odd) {
background-color: #333 !important;
}
li.feedItem:hover {
background-color: #555 !important;
}
legend {
background-color: #555 !important;
color: #e9ce97 !important;
}
/* Item */
li.feedItem a {
display: block;
width:100%;
color: #111;
}
li.feedItem a:link {
}
li.feedItem a:visited {
color: #777 !important;
}
li.feedItem a:hover {
color: #fff !important;