Compare commits
126 Commits
3054d6519e
...
2023-03
Author | SHA1 | Date | |
---|---|---|---|
|
4fa79187a9 | ||
|
d5406f3cce | ||
|
5369bea657 | ||
|
0e9ad6ba65 | ||
|
610e91ea9f | ||
|
860ce671f8 | ||
|
51d6188542 | ||
c9278c0dd6
|
|||
aabeca44f5
|
|||
3a8b6db348
|
|||
7a6ace156f
|
|||
dee924e6a8
|
|||
5b4421071f
|
|||
|
61311b30dd | ||
7406a9baa4
|
|||
|
ce4aefe828 | ||
|
ebcd906300 | ||
|
3b144ecaf5 | ||
fc7975379e
|
|||
207eabec86
|
|||
c9af4fbde8
|
|||
|
e557f103b9 | ||
ea8403c7b6
|
|||
b16a1c3a5f
|
|||
|
8783ca5099 | ||
f65e892182
|
|||
14bafbc3ab
|
|||
231a50957f
|
|||
|
bdc28d21c4 | ||
9310a8642d
|
|||
97a5d4ebbd
|
|||
b420453abd
|
|||
7feae31e11
|
|||
d6068778ab
|
|||
82d761bf68
|
|||
|
0f4fdc2d46 | ||
|
d3c2401e28 | ||
|
c744bdf175 | ||
16d6cf99aa
|
|||
add4f338be
|
|||
|
444c05f8f9 | ||
24a12a5af3
|
|||
add92ef20d
|
|||
f8e397d0bd
|
|||
6d588dc558
|
|||
|
f0b0b5ea59 | ||
a33fa197df
|
|||
e7e752f1e8
|
|||
094287837c
|
|||
a53f201842
|
|||
2ce1280cc0
|
|||
d45ca0de96
|
|||
13aeb647ad
|
|||
ee6a4e601d
|
|||
b544687f0f
|
|||
0ed7efe93b
|
|||
|
b4e4187902 | ||
431126e8a3
|
|||
|
91ceefd88e | ||
8feb37e831
|
|||
4a34496f24
|
|||
|
f7e54233e2 | ||
59875e772e
|
|||
|
f84ee71b7c | ||
927424901b
|
|||
27a84529c6
|
|||
59549daa63
|
|||
|
ec7a6ce379 | ||
756bdc0fa1
|
|||
b2eaea1eb8
|
|||
|
fe9bf574cf | ||
309ea05c15
|
|||
|
649d6c3746 | ||
e41f6029aa
|
|||
|
4bd7c6f867 | ||
138b0fdd1b
|
|||
d437e66f0e
|
|||
|
a213efa695 | ||
|
314127441c | ||
2a486cb58b
|
|||
7c44f6b680
|
|||
71a63e1beb
|
|||
8e1232517a | |||
cb65d25cfc
|
|||
2b4802508d
|
|||
1312e3d374
|
|||
3cc6da57ad
|
|||
675f8fa9d5
|
|||
6f28bb2a16
|
|||
cb881558ca
|
|||
4e8edf2640
|
|||
|
e86d2c010d | ||
f0fa21ae45
|
|||
0b99483f0d
|
|||
8c3874ad8b
|
|||
6f95a33e67
|
|||
979c8b43e5
|
|||
e3abe5fd68
|
|||
5612eeed42
|
|||
4af117fb7a
|
|||
e1b0189275
|
|||
aad77f3c78
|
|||
be1344e10c
|
|||
|
308d03d63c | ||
0837e11bfe
|
|||
06ace35c41
|
|||
6d0d1b99a6
|
|||
fdeff3879a
|
|||
b667c30d40
|
|||
b08f5c30df
|
|||
|
d8613143d3 | ||
3de4476a3f
|
|||
4984ac3383
|
|||
e4463dc5ba
|
|||
|
bf8bf8daad | ||
1d4e6e15b7
|
|||
d556e28e2d
|
|||
fb70ae6253
|
|||
64ae9c4f86
|
|||
b0d31ee507
|
|||
|
6ac65212d7 | ||
991b3dcec1
|
|||
|
1c9eb16934 | ||
2eaaa11a69
|
|||
3723303e31
|
|||
|
db46938de6 |
202
GETTING_STARTED.md
Normal file
@@ -0,0 +1,202 @@
|
|||||||
|
# Clone the repository
|
||||||
|
|
||||||
|
If git is not installed on the operating system, please install it now
|
||||||
|
(see the git documentation for [instructions on installing git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git)).
|
||||||
|
|
||||||
|
To retrieve the code from the repository on anhonesthost.net (a username and
|
||||||
|
password are required), run:
|
||||||
|
|
||||||
|
`git clone https://repo.anhonesthost.net/rho_n/hpr_generator.git`
|
||||||
|
|
||||||
|
To retrieve the code from the repository on gitlab.com, run:
|
||||||
|
|
||||||
|
`git clone https://gitlab.com/roan.horning/hpr_generator.git`
|
||||||
|
|
||||||
|
On success, an "hpr_generator" directory will be created in the folder from
|
||||||
|
which the clone command was executed containing a local copy of the git repository.
|
||||||
|
|
||||||
|
# Install required Perl modules
|
||||||
|
|
||||||
|
Installing the Perl modules is the most finicky part of the installation process.
|
||||||
|
The needed Perl modules can be found using the operating system's package
|
||||||
|
manager or using the modules found in the
|
||||||
|
[Comprehensive Perl Archive Network (CPAN)](https://www.cpan.org/).
|
||||||
|
|
||||||
|
## Installing modules on Debian based Linux distributions
|
||||||
|
|
||||||
|
Run command (tested on Debian 11):
|
||||||
|
|
||||||
|
```
|
||||||
|
apt install libconfig-std-perl \
|
||||||
|
libtemplate-perl \
|
||||||
|
libtemplate-plugin-dbi-perl \
|
||||||
|
libdbd-sqlite3-perl libdate-calc-perl \
|
||||||
|
libtie-dbi-perl
|
||||||
|
```
|
||||||
|
|
||||||
|
## Using CPAN to install the modules
|
||||||
|
|
||||||
|
A cross platform method to install the needed modules is the Perl CPAN application.
|
||||||
|
Make sure both the [make](https://www.gnu.org/software/make/manual/make.html)
|
||||||
|
command and the [cpan](https://perldoc.perl.org/CPAN) command are available.
|
||||||
|
Install them using the operating system's package manager, or from source.
|
||||||
|
|
||||||
|
Run commands:
|
||||||
|
|
||||||
|
```
|
||||||
|
cpan Config::Std
|
||||||
|
cpan Template
|
||||||
|
cpan Template::Plugin::DBI
|
||||||
|
cpan DBD::SQLite
|
||||||
|
cpan Date::Calc
|
||||||
|
cpan Tie::DBI
|
||||||
|
```
|
||||||
|
|
||||||
|
# Create the HPR database
|
||||||
|
|
||||||
|
The hpr_generator relies on information from a database to generate many of the
|
||||||
|
files for the website (for example: index.html, series/index.html,
|
||||||
|
hpr_mp3.rss, etc). This data is available from a MySQL dump file found on
|
||||||
|
hackerpublicradio.org at URL "https://www.hackerpublicradio.org/hpr.sql".
|
||||||
|
|
||||||
|
The first step is to download the hpr.sql file. This can be done using your
|
||||||
|
browser, or by running one of the following commands:
|
||||||
|
|
||||||
|
`curl https://www.hackerpublicradio.org/hpr.sql --output ./hpr.sql`
|
||||||
|
|
||||||
|
or
|
||||||
|
|
||||||
|
`wget --directory-prefix=./ https://www.hackerpublicradio.org/hpr.sql`
|
||||||
|
|
||||||
|
## Creating an SQLite database file
|
||||||
|
|
||||||
|
The SQL of the hpr.sql file must be converted from MySQL specific statements to
|
||||||
|
SQLite specific statements. The mysql2sqlite script found in the utils directory
|
||||||
|
is used for this conversion. First remove the lines from hpr.sql that
|
||||||
|
mysql2sqlite can't handle:
|
||||||
|
|
||||||
|
`sed '/^DELIMITER ;;/,/^DELIMITER ;/d' < ./hpr.sql > ./hpr-sqlite.sql`
|
||||||
|
|
||||||
|
Next run the mysql2sqlite script piping its output into the sqlite3
|
||||||
|
program which creates the hpr.db file:
|
||||||
|
|
||||||
|
`./utils/mysql2sqlite ./hpr-sqlite.sql | sqlite3 ./hpr.db`
|
||||||
|
|
||||||
|
For convenience, the update-sqlite-db.sh script in the utils directory
|
||||||
|
automates the above steps (including downloading the hpr.sql file).
|
||||||
|
From the root of the local hpr_generator repository run:
|
||||||
|
|
||||||
|
`./utils/update-sqlite-db.sh`
|
||||||
|
|
||||||
|
# Configure the site-generator
|
||||||
|
|
||||||
|
In your favorite text editor, open the site.cfg file found in the root of the
|
||||||
|
"hpr_generator" folder. Full details about options for configuring the site.cfg
|
||||||
|
file are found in the comments within the file.
|
||||||
|
|
||||||
|
## Configuring the database connection
|
||||||
|
|
||||||
|
Any database supported by the Perl:DBI and Perl::DBD modules can be used with
|
||||||
|
the site-generator program. Currently the hpr_generator project works with
|
||||||
|
a MySQL or SQLite database.
|
||||||
|
|
||||||
|
Find the [DBI] section of the file. It should look like the following
|
||||||
|
|
||||||
|
```
|
||||||
|
[DBI]
|
||||||
|
# Configuration settings for SQLite
|
||||||
|
#database: sqlite
|
||||||
|
#driver: dbi:SQLite:hpr.db
|
||||||
|
#user: (not used - leave blank)
|
||||||
|
#password: (not used - leave blank)
|
||||||
|
# Configuration settings for MySQL
|
||||||
|
#database: mysql
|
||||||
|
#driver: dbi:mysql:database=hpr_hpr:hostname=localhost
|
||||||
|
#user: hpr-generator (Suggested user with read-only privileges)
|
||||||
|
#password: ********* (Password for user)
|
||||||
|
```
|
||||||
|
|
||||||
|
### SQLite
|
||||||
|
|
||||||
|
Remove the comment character from the start of the database and driver
|
||||||
|
option lines:
|
||||||
|
|
||||||
|
```
|
||||||
|
# Configuration settings for SQLite
|
||||||
|
database: sqlite
|
||||||
|
driver: dbi:SQLite:hpr.db
|
||||||
|
#user: (not used - leave blank)
|
||||||
|
#password: (not used - leave blank)
|
||||||
|
```
|
||||||
|
|
||||||
|
The hpr.db section of the driver option `dbi:SQLite:hpr.db` is the path
|
||||||
|
to the sqlite file. The default assumes the hpr.db file is located in the same
|
||||||
|
directory as the site-generator.
|
||||||
|
|
||||||
|
### MySQL
|
||||||
|
|
||||||
|
Remove the comment character from the start of the database, driver,
|
||||||
|
user, and password option lines:
|
||||||
|
|
||||||
|
```
|
||||||
|
# Configuration settings for MySQL
|
||||||
|
database: mysql
|
||||||
|
driver: dbi:mysql:database=hpr_hpr:hostname=localhost
|
||||||
|
user: hpr-generator
|
||||||
|
password: *********
|
||||||
|
```
|
||||||
|
|
||||||
|
This assumes that the MySQL database service is available at the localhost
|
||||||
|
hostname, that the database name (hpr_hpr) is the database created from
|
||||||
|
the hpr.sql dump file or manually created by you, that the user (hpr-generator)
|
||||||
|
was added by you and has read rights to the hpr_hpr database, and that the
|
||||||
|
password (replace ********* with the actual password) matches the password set
|
||||||
|
for the hpr-generator database user.
|
||||||
|
|
||||||
|
## Configuring the website for viewing locally
|
||||||
|
|
||||||
|
For HTML links to work when viewing the files on your local machine using the
|
||||||
|
"file://" protocal (i.e. using the "Open..." command in your browser, each HTML
|
||||||
|
file must include a \<base\> meta-data tag in the \<head\> section of its
|
||||||
|
contents. To configure this in the site.cfg file, find the [root_template]
|
||||||
|
section. It should look like the following:
|
||||||
|
|
||||||
|
```
|
||||||
|
[root_template]
|
||||||
|
content: page.tpl.html
|
||||||
|
#baseurl: OPTIONAL [i.e. file://<full path to local website directory>]
|
||||||
|
```
|
||||||
|
Below the #baseurl comment line add:
|
||||||
|
|
||||||
|
```
|
||||||
|
baseurl: file://</path/to>/hpr_generator/public_html
|
||||||
|
```
|
||||||
|
|
||||||
|
Replace \<path/to\> with the full path to the hpr_generator directory. For
|
||||||
|
example: `file:///home/rho_n/development/hpr_generator/public_html`
|
||||||
|
|
||||||
|
## Configuring the website media file links
|
||||||
|
|
||||||
|
If you do not want to host all the media files (currently, audio files and
|
||||||
|
transcription files), you can configure the `media_baseurl` option. This can
|
||||||
|
be added to the [root_template] section of the site.cfg file. Suggested
|
||||||
|
external site is archive.org. To use this site add:
|
||||||
|
|
||||||
|
```
|
||||||
|
media_baseurl: https://archive.org/download/hpr$eps_id/
|
||||||
|
```
|
||||||
|
|
||||||
|
# Run the site-generator
|
||||||
|
|
||||||
|
Run the site generator form the hpr_generator directory:
|
||||||
|
|
||||||
|
```
|
||||||
|
./site-generator --all
|
||||||
|
```
|
||||||
|
|
||||||
|
This will generate all the files for the website. For more examples and to see
|
||||||
|
all available options run:
|
||||||
|
|
||||||
|
```
|
||||||
|
./site-generator --help
|
||||||
|
```
|
33
README.md
@@ -3,12 +3,27 @@ Static web page generator for the Hacker Public Radio website.
|
|||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
* Clone or download this repository
|
* Clone or download this repository
|
||||||
* Create the sqlite3 database from the files in the _sql directory. The default name for the database file is "hpr.db" and should be located in the root of the project directory. The name and location can be set in the site.cfg file.
|
* With SQLite
|
||||||
* Two sql helper scripts are available to generate an empty database or a database filled with test data.
|
* Create the sqlite3 database from the hpr.sql MySQL dump file available on
|
||||||
- For an empty database: `cat Create_Database_Empty.sql | sqlite3 hpr.db`
|
hackerpublicradio.org. The default name for the database file is "hpr.db"
|
||||||
- For a database with test data: `cat Create_Database_Test.sql | sqlite3 hpr.db`
|
and should be located in the root of the project directory. The name and
|
||||||
* SQLite v3.8.3 or greater is recommended. CTE WITH clauses are used in some template queries. Must convert WITH
|
location can be set in the site.cfg file.
|
||||||
|
* An "update-hpr.sh" helper script is available in the utils directory. This
|
||||||
|
script will download the hpr.sql file, convert it to the SQLite hpr.db file,
|
||||||
|
and regenerate the website using the site-generator.
|
||||||
|
1. `cd` into the root of the project directory
|
||||||
|
2. Run `./utils/update-hpr.sh`
|
||||||
|
* SQLite v3.8.3 or greater is recommended. CTE WITH clauses are used in some template queries. Must convert WITH
|
||||||
clauses to sub-queries when using earlier versions of SQLite.
|
clauses to sub-queries when using earlier versions of SQLite.
|
||||||
|
* With MySQL
|
||||||
|
* Create database hpr_hpr in the MySQL server from HPR dump file.
|
||||||
|
- ``sudo mysql --host=localhost < hpr.sql``
|
||||||
|
* Create a user that will be used by the site-generator.
|
||||||
|
- Suggested username: hpr-generator
|
||||||
|
- ``CREATE USER 'hpr-generator'@'localhost' IDENTIFIED BY '<password>';``
|
||||||
|
* Limit the user's privileges to EXECUTE and SELECT
|
||||||
|
- ``GRANT SELECT ON hpr_hpr.* TO 'hpr-generator'@'localhost';``
|
||||||
|
- ``GRANT EXECUTE ON `hpr_hpr`.* TO 'hpr-generator'@'localhost';``
|
||||||
* Install the needed Perl modules using preferred method (distribution packages, CPAN, etc.)
|
* Install the needed Perl modules using preferred method (distribution packages, CPAN, etc.)
|
||||||
* GetOpt
|
* GetOpt
|
||||||
* Pod::Usage
|
* Pod::Usage
|
||||||
@@ -18,9 +33,10 @@ Static web page generator for the Hacker Public Radio website.
|
|||||||
* Template::Plugin::DBI
|
* Template::Plugin::DBI
|
||||||
* DBI
|
* DBI
|
||||||
* Tie::DBI
|
* Tie::DBI
|
||||||
* DBD::SQLite
|
* DBD::SQLite or DBD:mysql
|
||||||
* Date::Calc
|
* Date::Calc
|
||||||
|
* See the Getting Started tutorial (GETTING_STARTED.md) for more details on
|
||||||
|
installing the HPR generator.
|
||||||
## Usage
|
## Usage
|
||||||
Generate two specific pages:
|
Generate two specific pages:
|
||||||
`site-generator index about`
|
`site-generator index about`
|
||||||
@@ -50,4 +66,5 @@ and add the label "**Feature Request**".
|
|||||||
|
|
||||||
## Authors and acknowledgment
|
## Authors and acknowledgment
|
||||||
* Roan "Rho`n" Horning
|
* Roan "Rho`n" Horning
|
||||||
|
* gordons
|
||||||
|
* Ken Fallon
|
@@ -235,6 +235,17 @@ pre { /* Add background, border and scrollbar to <pre> */
|
|||||||
clear: both;
|
clear: both;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
table.hosts {
|
||||||
|
background: white
|
||||||
|
}
|
||||||
|
table.hosts tr:nth-child(even) { background-color:#cccccc; }
|
||||||
|
table.hosts tr:nth-child(odd) { background-color:white; }
|
||||||
|
table.hosts tr td img { vertical-align:middle }
|
||||||
|
|
||||||
|
pre.comment {
|
||||||
|
white-space: pre-wrap;
|
||||||
|
padding: 2px;
|
||||||
|
line-height: 1.2rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media only screen and (max-width: 680px) {
|
@media only screen and (max-width: 680px) {
|
||||||
|
BIN
public_html/images/livestream.png
Normal file
After Width: | Height: | Size: 405 B |
BIN
public_html/images/mumble-howto/01-intro.png
Normal file
After Width: | Height: | Size: 36 KiB |
BIN
public_html/images/mumble-howto/02-device-selection.png
Normal file
After Width: | Height: | Size: 48 KiB |
BIN
public_html/images/mumble-howto/03-device-tuning.png
Normal file
After Width: | Height: | Size: 45 KiB |
BIN
public_html/images/mumble-howto/04-volume.png
Normal file
After Width: | Height: | Size: 59 KiB |
BIN
public_html/images/mumble-howto/05-ptt.png
Normal file
After Width: | Height: | Size: 48 KiB |
BIN
public_html/images/mumble-howto/06-notts.png
Normal file
After Width: | Height: | Size: 77 KiB |
BIN
public_html/images/mumble-howto/07-positional-audio.png
Normal file
After Width: | Height: | Size: 54 KiB |
BIN
public_html/images/mumble-howto/08-stats.png
Normal file
After Width: | Height: | Size: 44 KiB |
BIN
public_html/images/mumble-howto/09-cert.png
Normal file
After Width: | Height: | Size: 68 KiB |
BIN
public_html/images/mumble-howto/10-finished.png
Normal file
After Width: | Height: | Size: 20 KiB |
BIN
public_html/images/mumble-howto/11-username.png
Normal file
After Width: | Height: | Size: 36 KiB |
BIN
public_html/images/mumble-howto/12-accept-cert.png
Normal file
After Width: | Height: | Size: 66 KiB |
BIN
public_html/images/mumble-howto/13-audio-test.png
Normal file
After Width: | Height: | Size: 80 KiB |
BIN
public_html/images/mumble-howto/14-audio-ping.png
Normal file
After Width: | Height: | Size: 80 KiB |
BIN
public_html/images/mumble-howto/15-audio-pong.png
Normal file
After Width: | Height: | Size: 81 KiB |
BIN
public_html/images/mumble-howto/16-hpr-room.png
Normal file
After Width: | Height: | Size: 82 KiB |
BIN
public_html/images/mumble-howto/17-register.png
Normal file
After Width: | Height: | Size: 114 KiB |
BIN
public_html/images/mumble-howto/18-register-confirm.png
Normal file
After Width: | Height: | Size: 68 KiB |
BIN
public_html/images/mumble-howto/20-add-new.png
Normal file
After Width: | Height: | Size: 27 KiB |
BIN
public_html/images/mumble-howto/21-add-server.png
Normal file
After Width: | Height: | Size: 40 KiB |
BIN
public_html/images/mumble-howto/22-pavucontrol-recording.png
Normal file
After Width: | Height: | Size: 22 KiB |
BIN
public_html/images/mumble-howto/23-pavucontrol-playback.png
Normal file
After Width: | Height: | Size: 29 KiB |
@@ -9,6 +9,7 @@
|
|||||||
site-generator [OPTION]... PAGE|PAGE=<comma separated list of ids>...
|
site-generator [OPTION]... PAGE|PAGE=<comma separated list of ids>...
|
||||||
|
|
||||||
-a, --all generate all pages defined in configuration file
|
-a, --all generate all pages defined in configuration file
|
||||||
|
-c, --configure path to configuration file
|
||||||
-l, --list print list of configured pages
|
-l, --list print list of configured pages
|
||||||
-p, --preview print generated pages to standard out
|
-p, --preview print generated pages to standard out
|
||||||
-q, --quiet suppress progress information while generating pages
|
-q, --quiet suppress progress information while generating pages
|
||||||
@@ -35,15 +36,30 @@ This is a site generator for the Hacker Public Radio website based upon the Perl
|
|||||||
|
|
||||||
=head1 INSTALLATION
|
=head1 INSTALLATION
|
||||||
|
|
||||||
* Create the sqlite3 database from the files in the _sql directory. The default name for the
|
With SQLite
|
||||||
database file is "hpr.db" and should be located in the root of the project directory. The
|
* Create the sqlite3 database from the hpr.sql MySQL dump file available on
|
||||||
name and location can be set in the site.cfg file.
|
hackerpublicradio.org. The default name for the database file is "hpr.db"
|
||||||
* Two sql helper scripts are available to generate an empty database or a database filled with test data.
|
and should be located in the root of the project directory. The name and
|
||||||
- For an empty database: `cat Create_Database_Empty.sql | sqlite3 hpr.db`
|
location can be set in the site.cfg file.
|
||||||
- For a database with test data: `cat Create_Database_Test.sql | sqlite3 hpr.db`
|
* An "update-hpr.sh" helper script is available in the utils directory. This
|
||||||
* SQLite v3.8.3 or greater is recommended. CTE WITH clauses are used in some template queries. Must convert WITH
|
script will download the hpr.sql file, convert it to the SQLite hpr.db file,
|
||||||
clauses to sub-queries when using earlier versions of SQLite.
|
and regenerate the website using the site-generator.
|
||||||
* Install the needed Perl modules using preferred method (distribution packages, CPAN, etc.)
|
1. `cd` into the root of the project directory
|
||||||
|
2. Run `./utils/update-hpr.sh`
|
||||||
|
* SQLite v3.8.3 or greater is recommended. CTE WITH clauses are used in some template queries.
|
||||||
|
Must convert WITH clauses to sub-queries when using earlier versions of SQLite.
|
||||||
|
|
||||||
|
With MySQL
|
||||||
|
* Create database hpr_hpr in the MySQL server from HPR dump file.
|
||||||
|
- sudo mysql --host=localhost < hpr.sql
|
||||||
|
* Create a user that will be used by the site-generator.
|
||||||
|
- Suggested username: hpr-generator
|
||||||
|
- CREATE USER 'hpr-generator'@'localhost' IDENTIFIED BY '<password>';
|
||||||
|
* Limit the user's privileges to EXECUTE and SELECT
|
||||||
|
- GRANT SELECT ON hpr_hpr.* TO 'hpr-generator'@'localhost';
|
||||||
|
- GRANT EXECUTE ON `hpr_hpr`.* TO 'hpr-generator'@'localhost';
|
||||||
|
|
||||||
|
Install the needed Perl modules using preferred method (distribution packages, CPAN, etc.)
|
||||||
* GetOpt
|
* GetOpt
|
||||||
* Pod::Usage
|
* Pod::Usage
|
||||||
* Config::Std
|
* Config::Std
|
||||||
@@ -52,7 +68,7 @@ This is a site generator for the Hacker Public Radio website based upon the Perl
|
|||||||
* Template::Plugin::DBI
|
* Template::Plugin::DBI
|
||||||
* DBI
|
* DBI
|
||||||
* Tie::DBI
|
* Tie::DBI
|
||||||
* DBD::SQLite
|
* DBD::SQLite or DBD:mysql
|
||||||
* Date::Calc
|
* Date::Calc
|
||||||
|
|
||||||
=head1 AUTHOR
|
=head1 AUTHOR
|
||||||
@@ -94,11 +110,13 @@ sub main {
|
|||||||
|
|
||||||
# Argument parsing
|
# Argument parsing
|
||||||
my $all;
|
my $all;
|
||||||
|
my $configuration_path;
|
||||||
my $preview;
|
my $preview;
|
||||||
my $verbose;
|
my $verbose;
|
||||||
my $quiet;
|
my $quiet;
|
||||||
GetOptions(
|
GetOptions(
|
||||||
'all' => \$all,
|
'all' => \$all,
|
||||||
|
'configuration=s' => \$configuration_path,
|
||||||
'list' => \&print_available_pages,
|
'list' => \&print_available_pages,
|
||||||
'preview' => \$preview,
|
'preview' => \$preview,
|
||||||
'verbose' => \$verbose,
|
'verbose' => \$verbose,
|
||||||
@@ -111,10 +129,21 @@ sub main {
|
|||||||
$verbose = 'quiet';
|
$verbose = 'quiet';
|
||||||
};
|
};
|
||||||
|
|
||||||
# Load config file
|
if (!$configuration_path) {
|
||||||
read_config "site.cfg" => my %config;
|
$configuration_path = "site.cfg";
|
||||||
|
}
|
||||||
|
|
||||||
my $tt = get_template_html($config{DBI});
|
my %config;
|
||||||
|
if ( -f $configuration_path ) {
|
||||||
|
# Load config file
|
||||||
|
read_config $configuration_path => %config;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
print STDOUT "Could not read configuration file: $configuration_path\n";
|
||||||
|
exit 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
my $tt = get_template_html($config{DBI}, $config{app_paths});
|
||||||
|
|
||||||
# If command line option all is set, parse configuration file
|
# If command line option all is set, parse configuration file
|
||||||
# for all pages
|
# for all pages
|
||||||
@@ -125,7 +154,7 @@ sub main {
|
|||||||
# from the generated list of pages.
|
# from the generated list of pages.
|
||||||
@page_args= grep { $_ ne 'DBI' } @page_args;
|
@page_args= grep { $_ ne 'DBI' } @page_args;
|
||||||
@page_args= grep { $_ ne 'root_template' } @page_args;
|
@page_args= grep { $_ ne 'root_template' } @page_args;
|
||||||
@page_args= grep { $_ ne 'media_hostname' } @page_args;
|
@page_args= grep { $_ ne 'app_paths' } @page_args;
|
||||||
|
|
||||||
};
|
};
|
||||||
foreach my $page_arg (@page_args) {
|
foreach my $page_arg (@page_args) {
|
||||||
@@ -140,12 +169,13 @@ sub main {
|
|||||||
$page_config->{'root_template'} = $config{root_template}{content};
|
$page_config->{'root_template'} = $config{root_template}{content};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (exists $config{root_template}{baseurl}) {
|
# Set all config root_template properties as default page config properties
|
||||||
$page_config->{'baseurl'} = $config{root_template}{baseurl};
|
# except the previously set root_template content property
|
||||||
|
my @root_args = grep { $_ ne 'content' } keys %{$config{root_template}};
|
||||||
|
foreach my $root_arg (@root_args) {
|
||||||
|
if (exists $page_config->{$root_arg} == 0) {
|
||||||
|
$page_config->{$root_arg} = $config{root_template}{$root_arg};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (exists $config{root_template}{media_hostname}) {
|
|
||||||
$page_config->{'media_hostname'} = $config{root_template}{media_hostname};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($page_config->{'multipage'} && $page_config->{'multipage'} eq 'true') {
|
if ($page_config->{'multipage'} && $page_config->{'multipage'} eq 'true') {
|
||||||
@@ -177,14 +207,15 @@ sub get_template_html (\%@) {
|
|||||||
# HTML comments to make the template file valid HTML.
|
# HTML comments to make the template file valid HTML.
|
||||||
#
|
#
|
||||||
return Template->new({
|
return Template->new({
|
||||||
INCLUDE_PATH => './templates',
|
INCLUDE_PATH => $_[1]{templates_path},
|
||||||
OUTPUT_PATH => './public_html',
|
OUTPUT_PATH => $_[1]{output_path},
|
||||||
EVAL_PERL => 1,
|
EVAL_PERL => 1,
|
||||||
START_TAG => '<!--%',
|
START_TAG => '<!--%',
|
||||||
END_TAG => '%-->',
|
END_TAG => '%-->',
|
||||||
PRE_CHOMP => 1,
|
PRE_CHOMP => 1,
|
||||||
POST_CHOMP => 1,
|
POST_CHOMP => 1,
|
||||||
CONSTANTS => {
|
CONSTANTS => {
|
||||||
|
database => $_[0]{database},
|
||||||
driver => $_[0]{driver},
|
driver => $_[0]{driver},
|
||||||
user => $_[0]{user},
|
user => $_[0]{user},
|
||||||
password => $_[0]{password},
|
password => $_[0]{password},
|
||||||
|
33
site.cfg
@@ -2,9 +2,21 @@
|
|||||||
# with the database.
|
# with the database.
|
||||||
# dbi:<driver name [SQLite, CSV, ADO, mSQL, etc.]>:<database name>
|
# dbi:<driver name [SQLite, CSV, ADO, mSQL, etc.]>:<database name>
|
||||||
[DBI]
|
[DBI]
|
||||||
driver: dbi:SQLite:hpr.db
|
# Configuration settings for SQLite
|
||||||
user:
|
#database: sqlite
|
||||||
password:
|
#driver: dbi:SQLite:hpr.db
|
||||||
|
#user: (not used - leave blank)
|
||||||
|
#password: (not used - leave blank)
|
||||||
|
# Configuration settings for MySQL
|
||||||
|
#database: mysql
|
||||||
|
#driver: dbi:mysql:database=hpr_hpr:hostname=localhost
|
||||||
|
#user: hpr-generator (Suggested user with read-only privileges)
|
||||||
|
#password: ********* (Password for user)
|
||||||
|
|
||||||
|
# Configure the location of the templates and the generated HTML
|
||||||
|
[app_paths]
|
||||||
|
templates_path: ./templates
|
||||||
|
output_path: ./public_html
|
||||||
|
|
||||||
# Configure the root template page which pulls in the navigation and
|
# Configure the root template page which pulls in the navigation and
|
||||||
# content templates used by each page. An optional baseurl property may
|
# content templates used by each page. An optional baseurl property may
|
||||||
@@ -13,6 +25,8 @@ password:
|
|||||||
[root_template]
|
[root_template]
|
||||||
content: page.tpl.html
|
content: page.tpl.html
|
||||||
#baseurl: OPTIONAL [i.e. file://<full path to local website directory>]
|
#baseurl: OPTIONAL [i.e. file://<full path to local website directory>]
|
||||||
|
baseurl: file:///home/roan/Development/hpr/website/hpr_generator/public_html/
|
||||||
|
media_baseurl: https://archive.org/download/hpr$eps_id/
|
||||||
|
|
||||||
# Configure the navigation menu and the content templates for each page
|
# Configure the navigation menu and the content templates for each page
|
||||||
# of the site:
|
# of the site:
|
||||||
@@ -137,6 +151,15 @@ navigation: navigation-get-shows.tpl.html
|
|||||||
content: content-twat_episode.tpl.html
|
content: content-twat_episode.tpl.html
|
||||||
multipage: true
|
multipage: true
|
||||||
filename: eps/twat[id]/index.html
|
filename: eps/twat[id]/index.html
|
||||||
|
media_baseurl: https://www.hackerpublicradio.org/eps/
|
||||||
|
|
||||||
|
[mumble-howto]
|
||||||
|
navigation: navigation-about.tpl.html
|
||||||
|
content: content-mumble-howto.tpl.html
|
||||||
|
|
||||||
|
[comments_viewer]
|
||||||
|
navigation: navigation-about.tpl.html
|
||||||
|
content: content-comments_viewer.tpl.html
|
||||||
|
|
||||||
[hpr_ogg]
|
[hpr_ogg]
|
||||||
root_template: rss.tpl.xml
|
root_template: rss.tpl.xml
|
||||||
@@ -175,3 +198,7 @@ root_template: rss.tpl.xml
|
|||||||
content: rss-hpr_total.tpl.xml
|
content: rss-hpr_total.tpl.xml
|
||||||
filename: hpr_total_spx.rss
|
filename: hpr_total_spx.rss
|
||||||
media_file_extension: spx
|
media_file_extension: spx
|
||||||
|
|
||||||
|
[comments]
|
||||||
|
root_template: rss-comments.tpl.xml
|
||||||
|
filename: comments.rss
|
||||||
|
42
templates/content-comments_viewer.tpl.html
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
<!--% PROCESS 'shared-episode-summary.tpl.html' %-->
|
||||||
|
<!--% PROCESS 'shared-utils.tpl.html' %-->
|
||||||
|
<!--% PROCESS 'shared-listen-now.tpl.html' %-->
|
||||||
|
<!--% PROCESS "queries-episode-${constants.database}.tpl.html" %-->
|
||||||
|
<!--% USE DBI(constants.driver, constants.user, constants.password) %-->
|
||||||
|
<h2>Comment Viewer</h2>
|
||||||
|
<p>Because of the spammers we have had to turn on comment moderation. Sorry about the delay this will cause.</p>
|
||||||
|
<p><a href="<!--% absolute_path(baseurl) %-->comments.rss">Subscribe</a> to the comment feed.</p>
|
||||||
|
<hr />
|
||||||
|
<!--% FOREACH item IN DBI.query('
|
||||||
|
SELECT C.*,
|
||||||
|
H.host, H.hostid AS host_id,
|
||||||
|
E.title AS episode_title,
|
||||||
|
E.date AS episode_date,
|
||||||
|
E.duration AS episode_duration,
|
||||||
|
M.id AS series_id, M.name AS series_name
|
||||||
|
FROM comments AS C
|
||||||
|
INNER JOIN eps AS E
|
||||||
|
ON C.eps_id = E.id
|
||||||
|
INNER JOIN hosts AS H
|
||||||
|
ON E.hostid = H.hostid
|
||||||
|
INNER JOIN miniseries AS M
|
||||||
|
ON E.series = M.id
|
||||||
|
ORDER BY C.comment_timestamp DESC
|
||||||
|
LIMIT 30
|
||||||
|
')
|
||||||
|
%-->
|
||||||
|
|
||||||
|
<article>
|
||||||
|
<header>
|
||||||
|
<h1><!--% item.comment_author_name %--> says: <!--% item.comment_title %--></h1>
|
||||||
|
<p><small>Posted at <!--% item.comment_timestamp %--> relating to the show <a href="<!--% absolute_path(baseurl) %-->eps/hpr<!--% zero_pad_left(item.eps_id) %-->/index.html">hpr<!--% item.eps_id %--></a> which was released on <!--% item.episode_date %--> by <a href="<!--% absolute_path(baseurl) %-->correspondents/<!--% zero_pad_left(item.host_id) %-->.html"><!--% item.host %--></a> entitled <em><!--% item.episode_title %--></em></small>
|
||||||
|
</p>
|
||||||
|
</header>
|
||||||
|
<pre class="comment">
|
||||||
|
<!--% item.comment_text %-->
|
||||||
|
</pre>
|
||||||
|
<footer>
|
||||||
|
Listen in <a href="<!--% media_path(item.eps_id, 'hpr', 'ogg', baseurl, media_baseurl) %-->">ogg</a>, <a href="<!--% media_path(item.eps_id, 'hpr', 'spx', baseurl, media_baseurl) %-->">spx</a>, or <a href="<!--% media_path(item.eps_id, 'hpr', 'mp3', baseurl, media_baseurl) %-->">mp3</a> format.</p></footer>
|
||||||
|
</article>
|
||||||
|
<hr />
|
||||||
|
<!--% END %-->
|
@@ -1,31 +1,18 @@
|
|||||||
<!--% PROCESS 'shared-episode-summary.tpl.html' %-->
|
<!--% PROCESS 'shared-episode-summary.tpl.html' %-->
|
||||||
<!--% PROCESS 'shared-avatar.tpl.html' %-->
|
<!--% PROCESS 'shared-avatar.tpl.html' %-->
|
||||||
<!--% PROCESS 'shared-utils.tpl.html' %-->
|
<!--% PROCESS 'shared-utils.tpl.html' %-->
|
||||||
|
<!--% PROCESS "queries-correspondent-${constants.database}.tpl.html" %-->
|
||||||
<!--% USE DBI(constants.driver, constants.user, constants.password) %-->
|
<!--% USE DBI(constants.driver, constants.user, constants.password) %-->
|
||||||
<!--% query_hpr_show_count = DBI.prepare('
|
<!--% query_hpr_show_count = DBI.prepare('
|
||||||
SELECT id
|
SELECT id
|
||||||
FROM eps
|
FROM eps
|
||||||
WHERE eps.hostid = ? ')
|
WHERE eps.hostid = ?
|
||||||
|
')
|
||||||
%-->
|
%-->
|
||||||
<!--% query_hpr_shows = DBI.prepare('
|
<!--% results_hpr_shows = DBI.prepare(query_hpr_shows)
|
||||||
SELECT
|
|
||||||
eps.id,
|
|
||||||
CASE eps.explicit WHEN 1 THEN \'Explicit\' ELSE \'Clean\' END AS explicit ,
|
|
||||||
eps.date, eps.license, eps.duration,
|
|
||||||
eps.title, eps.summary, eps.tags,
|
|
||||||
eps.notes,
|
|
||||||
hosts.local_image,
|
|
||||||
hosts.hostid,
|
|
||||||
hosts.host, hosts.email,
|
|
||||||
miniseries.name AS series, miniseries.id AS seriesid
|
|
||||||
FROM eps
|
|
||||||
INNER JOIN hosts ON eps.hostid = hosts.hostid
|
|
||||||
INNER JOIN miniseries ON eps.series = miniseries.id
|
|
||||||
WHERE hosts.hostid = ? AND eps.date < date(\'now\', \'+1 days\')
|
|
||||||
ORDER BY date DESC ')
|
|
||||||
%-->
|
%-->
|
||||||
<!--% hpr_shows_to_count = query_hpr_show_count.execute(id); %-->
|
<!--% hpr_shows_to_count = query_hpr_show_count.execute(id); %-->
|
||||||
<!--% hpr_shows = query_hpr_shows.execute(id); %-->
|
<!--% hpr_shows = results_hpr_shows.execute(id); %-->
|
||||||
<!--% hpr_show_count = 0 %-->
|
<!--% hpr_show_count = 0 %-->
|
||||||
<!--% FOREACH show IN hpr_shows_to_count %-->
|
<!--% FOREACH show IN hpr_shows_to_count %-->
|
||||||
<!--% hpr_show_count = hpr_show_count +1; %-->
|
<!--% hpr_show_count = hpr_show_count +1; %-->
|
||||||
@@ -33,8 +20,9 @@
|
|||||||
|
|
||||||
<!--% query_twat_show_count = DBI.prepare('
|
<!--% query_twat_show_count = DBI.prepare('
|
||||||
SELECT id
|
SELECT id
|
||||||
FROM twat_eps AS \'eps\'
|
FROM twat_eps AS eps
|
||||||
WHERE eps.hostid = ? ')
|
WHERE eps.hostid = ?
|
||||||
|
')
|
||||||
%-->
|
%-->
|
||||||
<!--% query_twat_shows = DBI.prepare('
|
<!--% query_twat_shows = DBI.prepare('
|
||||||
SELECT
|
SELECT
|
||||||
@@ -51,7 +39,7 @@
|
|||||||
INNER JOIN hosts ON eps.hostid = hosts.hostid
|
INNER JOIN hosts ON eps.hostid = hosts.hostid
|
||||||
INNER JOIN miniseries ON eps.series = miniseries.id
|
INNER JOIN miniseries ON eps.series = miniseries.id
|
||||||
WHERE hosts.hostid = ?
|
WHERE hosts.hostid = ?
|
||||||
ORDER BY date DESC
|
ORDER BY eps.id DESC
|
||||||
')
|
')
|
||||||
%-->
|
%-->
|
||||||
<!--% twat_shows_to_count = query_twat_show_count.execute(id); %-->
|
<!--% twat_shows_to_count = query_twat_show_count.execute(id); %-->
|
||||||
@@ -67,8 +55,7 @@
|
|||||||
<!--% this_host = hosts.$id %-->
|
<!--% this_host = hosts.$id %-->
|
||||||
<h2 class="title">Correspondent</h2>
|
<h2 class="title">Correspondent</h2>
|
||||||
<h2><!--% this_host.host %--></h2>
|
<h2><!--% this_host.host %--></h2>
|
||||||
<p><img src="<!--% absolute_path(baseurl) %-->images/<!--% get_avatar(this_host.hostid) %-->"
|
<p><!--% get_avatar(this_host.hostid, this_host.host) %--><br>
|
||||||
height="80" alt="Host Image" /><br>
|
|
||||||
<label>Host ID</label>: <!--% this_host.hostid %--><br><br>
|
<label>Host ID</label>: <!--% this_host.hostid %--><br><br>
|
||||||
<label>email:</label> <u><!--% this_host.email %--></u><br>
|
<label>email:</label> <u><!--% this_host.email %--></u><br>
|
||||||
<label>episodes:</label> <strong><!--% hpr_show_count + twat_show_count %--></strong>
|
<label>episodes:</label> <strong><!--% hpr_show_count + twat_show_count %--></strong>
|
||||||
|
@@ -1,10 +1,11 @@
|
|||||||
<!--% PROCESS 'shared-utils.tpl.html' %-->
|
<!--% PROCESS 'shared-utils.tpl.html' %-->
|
||||||
|
<!--% PROCESS 'shared-avatar.tpl.html' %-->
|
||||||
<article>
|
<article>
|
||||||
<h2 class="title">Correspondents</h2>
|
<h2 class="title">Correspondents</h2>
|
||||||
<p>For more information on how to become a Correspondent see our <a href="<!--% absolute_path(baseurl) %-->contribute.html">contribute</a></center> page. To add a logo here, either email one to admin at hpr or setup your email on <a href="https://en.gravatar.com/">Gravatar</a>. To protect your browsing privacy we gather the images every hour and serve them directly from HPR.<p />
|
<p>For more information on how to become a Correspondent see our <a href="<!--% absolute_path(baseurl) %-->contribute.html">contribute</a></center> page. To add a logo here, either email one to admin at hpr or setup your email on <a href="https://en.gravatar.com/">Gravatar</a>. To protect your browsing privacy we gather the images every hour and serve them directly from HPR.<p />
|
||||||
<!--% USE DBI(constants.driver, constants.user, constants.password) %-->
|
<!--% USE DBI(constants.driver, constants.user, constants.password) %-->
|
||||||
<!--% PROCESS 'shared-avatar.tpl.html' %-->
|
<!--% host_cnt = 0 %-->
|
||||||
<table>
|
<table class="hosts">
|
||||||
<th >Avatar</th>
|
<th >Avatar</th>
|
||||||
<th >Name & Host ID</th>
|
<th >Name & Host ID</th>
|
||||||
<th >license</th>
|
<th >license</th>
|
||||||
@@ -16,15 +17,15 @@
|
|||||||
inner join (select hostid, max(date) as date from eps group by hostid) as e
|
inner join (select hostid, max(date) as date from eps group by hostid) as e
|
||||||
on h.hostid = e.hostid '
|
on h.hostid = e.hostid '
|
||||||
) %-->
|
) %-->
|
||||||
<tr height="80" bgcolor="#CCCCCC">
|
<tr height="80">
|
||||||
<td><img src="<!--% absolute_path(baseurl) %-->images/<!--% get_avatar(host.hostid) %-->" height="80" width="80" alt="avatar" /></td>
|
<td><!--% get_avatar(host.hostid, host.host, host_cnt > 8) %--></td>
|
||||||
|
|
||||||
<td><strong><!--% host.host %--></strong><br>
|
<td><strong><!--% host.host %--></strong><br>
|
||||||
|
|
||||||
Host ID: <a href="<!--% absolute_path(baseurl) %-->correspondents/<!--% zero_pad_left(host.hostid) %-->.html"><!--% host.hostid %--></a></td>
|
Host ID: <a href="<!--% absolute_path(baseurl) %-->correspondents/<!--% zero_pad_left(host.hostid) %-->.html"><!--% host.hostid %--></a></td>
|
||||||
<td><!--% host.license %--></td>
|
<td><!--% host.license %--></td>
|
||||||
<td><!--% host.date %--></td>
|
<td><!--% host.date %--></td>
|
||||||
</tr>
|
</tr><!--% host_cnt = host_cnt + 1 %-->
|
||||||
<!--% END %-->
|
<!--% END %-->
|
||||||
</table>
|
</table>
|
||||||
<p><a href="<!--% absolute_path(baseurl) %-->contribute.html">Become a Correspondent</a></p>
|
<p><a href="<!--% absolute_path(baseurl) %-->contribute.html">Become a Correspondent</a></p>
|
||||||
|
@@ -2,57 +2,10 @@
|
|||||||
<!--% PROCESS 'shared-avatar.tpl.html' %-->
|
<!--% PROCESS 'shared-avatar.tpl.html' %-->
|
||||||
<!--% PROCESS 'shared-utils.tpl.html' %-->
|
<!--% PROCESS 'shared-utils.tpl.html' %-->
|
||||||
<!--% PROCESS 'shared-listen-now.tpl.html' %-->
|
<!--% PROCESS 'shared-listen-now.tpl.html' %-->
|
||||||
|
<!--% PROCESS 'shared-show-transcript.tpl.html' %-->
|
||||||
|
<!--% PROCESS "queries-episode-${constants.database}.tpl.html" %-->
|
||||||
<!--% USE DBI(constants.driver, constants.user, constants.password) %-->
|
<!--% USE DBI(constants.driver, constants.user, constants.password) %-->
|
||||||
<!--% query_episodes = DBI.prepare('
|
<!--% query_episodes = DBI.prepare(query_episode_maxmin)
|
||||||
WITH episode_maxmin AS (
|
|
||||||
SELECT MAX(id) AS \'latest\', MIN(id) AS \'earliest\', ? AS \'id\'
|
|
||||||
FROM eps
|
|
||||||
WHERE eps.date < date (\'now\', \'+1 days\')
|
|
||||||
),
|
|
||||||
episode_date AS (
|
|
||||||
SELECT eps.date
|
|
||||||
FROM eps
|
|
||||||
WHERE eps.id = ?
|
|
||||||
),
|
|
||||||
episode_previous AS (
|
|
||||||
SELECT MAX(id) AS \'previous\', ? AS \'id\'
|
|
||||||
FROM eps
|
|
||||||
INNER JOIN episode_date
|
|
||||||
ON eps.date < episode_date.date
|
|
||||||
WHERE eps.id > 1
|
|
||||||
),
|
|
||||||
episode_next AS (
|
|
||||||
SELECT MIN(id) AS \'next\', ? AS \'id\'
|
|
||||||
FROM eps
|
|
||||||
INNER JOIN episode_date
|
|
||||||
ON eps.date > episode_date.date
|
|
||||||
WHERE eps.date < date (\'now\')
|
|
||||||
),
|
|
||||||
comment_tallies AS (
|
|
||||||
SELECT
|
|
||||||
eps_id,
|
|
||||||
COUNT(eps_id) AS eps_tally
|
|
||||||
FROM comments
|
|
||||||
GROUP BY eps_id
|
|
||||||
)
|
|
||||||
SELECT eps.id, eps.date, eps.title, eps.duration,
|
|
||||||
eps.summary, eps.notes, eps.explicit, eps.license,
|
|
||||||
eps.tags, eps.version, eps.downloads, eps.valid,
|
|
||||||
episode_maxmin.latest, episode_maxmin.earliest,
|
|
||||||
episode_previous.previous, episode_next.next,
|
|
||||||
hosts.hostid, hosts.host,
|
|
||||||
miniseries.name AS \'series\', miniseries.id AS \'seriesid\',
|
|
||||||
miniseries.description AS \'series_description\',
|
|
||||||
COALESCE (comment_tallies.eps_tally, 0) AS eps_tally
|
|
||||||
FROM eps
|
|
||||||
INNER JOIN hosts ON eps.hostid = hosts.hostid
|
|
||||||
INNER JOIN miniseries ON eps.series = miniseries.id
|
|
||||||
INNER JOIN episode_maxmin ON eps.id = episode_maxmin.id
|
|
||||||
INNER JOIN episode_previous ON eps.id = episode_previous.id
|
|
||||||
INNER JOIN episode_next ON eps.id = episode_next.id
|
|
||||||
LEFT JOIN comment_tallies ON eps.id = comment_tallies.eps_id
|
|
||||||
WHERE eps.id = ?
|
|
||||||
')
|
|
||||||
%-->
|
%-->
|
||||||
<!--% episode_result = query_episodes.execute(id, id, id, id, id) %-->
|
<!--% episode_result = query_episodes.execute(id, id, id, id, id) %-->
|
||||||
<!--% FOREACH episode IN episode_result %-->
|
<!--% FOREACH episode IN episode_result %-->
|
||||||
@@ -63,10 +16,10 @@
|
|||||||
<h3><!--% episode.summary %--></h3>
|
<h3><!--% episode.summary %--></h3>
|
||||||
<p class="meta"><!--% episode_navigation %-->
|
<p class="meta"><!--% episode_navigation %-->
|
||||||
</p>
|
</p>
|
||||||
<p><!--% IF get_avatar(episode.hostid) != 'hpr_logo.png' %-->
|
<p><!--% show_avatar(episode.hostid, episode.host) %-->
|
||||||
<img src="<!--% absolute_path(baseurl) %-->images/<!--% get_avatar(episode.hostid) %-->" height="80" width="80" alt="" /></a><br><!--% END %-->
|
|
||||||
Hosted by <a href="<!--% absolute_path(baseurl) %-->correspondents/<!--% zero_pad_left(episode.hostid) %-->.html"><!--% episode.host %--></a> on <span><!--% episode.date %--></span> is flagged as <span><!--% display_explicit(episode.explicit) %--></span> and is released under a <span><!--% episode.license %--> license</span>. <br>
|
Hosted by <a href="<!--% absolute_path(baseurl) %-->correspondents/<!--% zero_pad_left(episode.hostid) %-->.html"><!--% episode.host %--></a> on <span><!--% episode.date %--></span> is flagged as <span><!--% display_explicit(episode.explicit) %--></span> and is released under a <span><!--% episode.license %--> license</span>. <br>
|
||||||
<!--% display_tags(episode.tags) %--> <br>
|
<!--% display_tags(episode.tags) %--> <br>
|
||||||
|
<!--% listen_now(episode, "hpr", baseurl, media_baseurl) %-->
|
||||||
<!--% display_listen_in(episode.id) %--> |
|
<!--% display_listen_in(episode.id) %--> |
|
||||||
<!--% display_comments_tally(episode.id, episode.eps_tally) %-->
|
<!--% display_comments_tally(episode.id, episode.eps_tally) %-->
|
||||||
</p>
|
</p>
|
||||||
@@ -75,7 +28,7 @@ Hosted by <a href="<!--% absolute_path(baseurl) %-->correspondents/<!--% zero_pa
|
|||||||
</header>
|
</header>
|
||||||
<div><!--% episode.notes %--></div>
|
<div><!--% episode.notes %--></div>
|
||||||
<footer>
|
<footer>
|
||||||
<!--% listen_now(episode, "hpr", baseurl, media_hostname) %-->
|
<!--% show_transcript(episode, "hpr", baseurl, media_baseurl) %-->
|
||||||
<p>
|
<p>
|
||||||
<!--% episode_navigation %-->
|
<!--% episode_navigation %-->
|
||||||
</p>
|
</p>
|
||||||
@@ -84,10 +37,11 @@ Hosted by <a href="<!--% absolute_path(baseurl) %-->correspondents/<!--% zero_pa
|
|||||||
<hr />
|
<hr />
|
||||||
<h1>Comments</h1>
|
<h1>Comments</h1>
|
||||||
<p id="comments">
|
<p id="comments">
|
||||||
Subscribe to the comments <a href="https://www.hackerpublicradio.org/comments_rss.php">RSS</a> feed.
|
Subscribe to the comments <a href="<!--% absolute_path(baseurl) %-->comments.rss">RSS</a> feed.
|
||||||
</p>
|
</p>
|
||||||
<!--% query_comments = DBI.prepare('
|
<!--% query_comments = DBI.prepare('
|
||||||
SELECT
|
SELECT
|
||||||
|
id,
|
||||||
comment_timestamp,
|
comment_timestamp,
|
||||||
comment_author_name,
|
comment_author_name,
|
||||||
comment_title,
|
comment_title,
|
||||||
@@ -99,7 +53,7 @@ Subscribe to the comments <a href="https://www.hackerpublicradio.org/comments_rs
|
|||||||
<!--% comment_index = 1 %-->
|
<!--% comment_index = 1 %-->
|
||||||
<!--% comments_result = query_comments.execute(id) %-->
|
<!--% comments_result = query_comments.execute(id) %-->
|
||||||
<!--% FOREACH comment IN comments_result %-->
|
<!--% FOREACH comment IN comments_result %-->
|
||||||
<h5 id="1">Comment #<!--% comment_index %--> posted on <!--% comment.comment_timestamp %--> by <!--% comment.comment_author_name %--></h5>
|
<h5 id="comment_<!--% comment.id %-->">Comment #<!--% comment_index %--> posted on <!--% comment.comment_timestamp %--> by <!--% comment.comment_author_name %--></h5>
|
||||||
<h4><!--% comment.comment_title %--></h4>
|
<h4><!--% comment.comment_title %--></h4>
|
||||||
<!--% comment.comment_text %-->
|
<!--% comment.comment_text %-->
|
||||||
<!--% comment_index = comment_index + 1 %-->
|
<!--% comment_index = comment_index + 1 %-->
|
||||||
@@ -108,11 +62,11 @@ Subscribe to the comments <a href="https://www.hackerpublicradio.org/comments_rs
|
|||||||
<h2>Leave Comment</h2>
|
<h2>Leave Comment</h2>
|
||||||
<p>
|
<p>
|
||||||
<strong>Note to Verbose Commenters</strong><br />
|
<strong>Note to Verbose Commenters</strong><br />
|
||||||
If you can't fit everything you want to say in the comment below then you really should <a href="/contribute.php">record</a> a response show instead.
|
If you can't fit everything you want to say in the comment below then you really should <a href="<!--% absolute_path(baseurl) %-->contribute.html">record</a> a response show instead.
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<strong>Note to Spammers</strong><br />
|
<strong>Note to Spammers</strong><br />
|
||||||
All comments are moderated. All links are checked by humans. We strip out all html. Feel free to <a href="/contribute.php">record</a> a show about yourself, or your industry, or any other topic we may find interesting. <em>We also check shows for spam :)</em>.
|
All comments are moderated. All links are checked by humans. We strip out all html. Feel free to <a href="<!--% absolute_path(baseurl) %-->contribute.html">record</a> a show about yourself, or your industry, or any other topic we may find interesting. <em>We also check shows for spam :)</em>.
|
||||||
</p>
|
</p>
|
||||||
<form method="POST" action="comment_confirm.php">
|
<form method="POST" action="comment_confirm.php">
|
||||||
<fieldset>
|
<fieldset>
|
||||||
|
@@ -1,4 +1,5 @@
|
|||||||
<!--% PROCESS 'shared-episode-summary.tpl.html' %-->
|
<!--% PROCESS 'shared-episode-summary.tpl.html' %-->
|
||||||
|
<!--% PROCESS "queries-episodes-${constants.database}.tpl.html" %-->
|
||||||
<article>
|
<article>
|
||||||
<header>
|
<header>
|
||||||
<h1>Complete Archive of Shows.</h1>
|
<h1>Complete Archive of Shows.</h1>
|
||||||
@@ -7,21 +8,7 @@
|
|||||||
</p>
|
</p>
|
||||||
</header>
|
</header>
|
||||||
<!--% USE DBI(constants.driver, constants.user, constants.password) %-->
|
<!--% USE DBI(constants.driver, constants.user, constants.password) %-->
|
||||||
<!--% FOREACH episodes IN DBI.query('
|
<!--% FOREACH episodes IN DBI.query(query_episodes)
|
||||||
SELECT
|
|
||||||
eps.id,
|
|
||||||
eps.explicit,
|
|
||||||
eps.date, eps.license, eps.title, eps.summary,
|
|
||||||
eps.duration, eps.notes, eps.tags,
|
|
||||||
hosts.hostid,
|
|
||||||
hosts.host, hosts.email, hosts.local_image,
|
|
||||||
miniseries.name AS series, miniseries.id AS seriesid
|
|
||||||
FROM eps
|
|
||||||
INNER JOIN hosts ON eps.hostid = hosts.hostid
|
|
||||||
INNER JOIN miniseries ON eps.series = miniseries.id
|
|
||||||
WHERE eps.date < date(\'now\', \'+1 days\')
|
|
||||||
ORDER BY date DESC
|
|
||||||
')
|
|
||||||
%-->
|
%-->
|
||||||
<!--% show_summary(episodes) %-->
|
<!--% show_summary(episodes) %-->
|
||||||
<!--% END %-->
|
<!--% END %-->
|
||||||
@@ -42,7 +29,7 @@
|
|||||||
FROM twat_eps as eps
|
FROM twat_eps as eps
|
||||||
INNER JOIN hosts ON eps.hostid = hosts.hostid
|
INNER JOIN hosts ON eps.hostid = hosts.hostid
|
||||||
INNER JOIN miniseries ON eps.series = miniseries.id
|
INNER JOIN miniseries ON eps.series = miniseries.id
|
||||||
ORDER BY date DESC
|
ORDER BY eps.id DESC
|
||||||
')
|
')
|
||||||
%-->
|
%-->
|
||||||
<!--% twat_show_summary(twat_episode) %-->
|
<!--% twat_show_summary(twat_episode) %-->
|
||||||
|
2
templates/content-index-announcement.tpl.html
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
<!--% PROCESS 'shared-utils.tpl.html' %-->
|
||||||
|
|
@@ -1,6 +1,28 @@
|
|||||||
<!--% PROCESS 'shared-avatar.tpl.html' %-->
|
<!--% PROCESS 'shared-avatar.tpl.html' %-->
|
||||||
<!--% PROCESS 'shared-utils.tpl.html' %-->
|
<!--% PROCESS 'shared-utils.tpl.html' %-->
|
||||||
<!--% PROCESS 'shared-listen-now.tpl.html' %-->
|
<!--% PROCESS 'shared-listen-now.tpl.html' %-->
|
||||||
|
<!--% PROCESS 'shared-show-transcript.tpl.html' %-->
|
||||||
|
<!--% PROCESS 'shared-call_for_shows.tpl.html' %-->
|
||||||
|
<!--% INCLUDE 'content-index-announcement.tpl.html' %-->
|
||||||
|
<!--% PROCESS "queries-index-${constants.database}.tpl.html" %-->
|
||||||
|
<!--% MACRO tidy_notes(all_lines) BLOCK %-->
|
||||||
|
<!--% lines = all_lines %-->
|
||||||
|
<!--% after_html = all_lines %-->
|
||||||
|
<!--% img_re = '(?six)^(.*?)\<img ([^\>]+\>)(.+)$' %-->
|
||||||
|
<!--% lazy_re = '(?i)loading="lazy"' %-->
|
||||||
|
<!--% WHILE (matches = lines.match(img_re)) %-->
|
||||||
|
<!--% img_tag = matches.1 %-->
|
||||||
|
<!--% after_html = matches.2 %-->
|
||||||
|
<!--% matches.0 %-->
|
||||||
|
<!--% IF (img_tag.search(lazy_re)) %-->
|
||||||
|
<img <!--% img_tag %-->
|
||||||
|
<!--% ELSE %-->
|
||||||
|
<img loading="lazy" <!--% img_tag %-->
|
||||||
|
<!--% END %-->
|
||||||
|
<!--% lines = after_html %-->
|
||||||
|
<!--% END %-->
|
||||||
|
<!--% after_html %-->
|
||||||
|
<!--% END %-->
|
||||||
<hr>
|
<hr>
|
||||||
<article>
|
<article>
|
||||||
<header>
|
<header>
|
||||||
@@ -8,20 +30,7 @@
|
|||||||
</header>
|
</header>
|
||||||
<!--% days_till_next_episode = 0 %-->
|
<!--% days_till_next_episode = 0 %-->
|
||||||
<!--% USE DBI(constants.driver, constants.user, constants.password) %-->
|
<!--% USE DBI(constants.driver, constants.user, constants.password) %-->
|
||||||
<!--% FOREACH next_available_episode_result IN DBI.query('
|
<!--% FOREACH next_available_episode_result IN DBI.query(query_next_available_episode)
|
||||||
WITH next_id AS (SELECT id, id + 1 AS \'id_next\', date as \'last_date\'
|
|
||||||
FROM eps
|
|
||||||
WHERE eps.date > date(\'now\')
|
|
||||||
)
|
|
||||||
SELECT
|
|
||||||
MIN (next_id.id_next) AS \'next_id\',
|
|
||||||
strftime(\'%Y\', MIN (last_date)) AS \'last_year\',
|
|
||||||
strftime(\'%d\', MIN (last_date)) AS \'last_day\',
|
|
||||||
strftime(\'%m\', MIN (last_date)) AS \'last_month\'
|
|
||||||
FROM next_id
|
|
||||||
LEFT JOIN eps ON next_id.id_next = eps.id
|
|
||||||
WHERE eps.id IS NULL
|
|
||||||
')
|
|
||||||
%-->
|
%-->
|
||||||
<!--% USE date %-->
|
<!--% USE date %-->
|
||||||
<!--% calc = date.calc %-->
|
<!--% calc = date.calc %-->
|
||||||
@@ -30,6 +39,9 @@
|
|||||||
<!--% USE date %-->
|
<!--% USE date %-->
|
||||||
<!--% delta = date.calc.N_Delta_YMD(2005,9,19, date.format(date.now, '%Y'),date.format(date.now, '%m'),date.format(date.now, '%d')) %-->
|
<!--% delta = date.calc.N_Delta_YMD(2005,9,19, date.format(date.now, '%Y'),date.format(date.now, '%m'),date.format(date.now, '%d')) %-->
|
||||||
<p>We started producing shows as <a href="<!--% absolute_path(baseurl) %-->eps/index.html#twat_episodes"><em>Today with a Techie</em></a> on 2005-09-19, <!--% delta.0 %--> years, <!--% delta.1 %--> months, <!--% delta.2 %--> days ago. our shows are produced by <a href="<!--% absolute_path(baseurl) %-->correspondents/index.html">listeners</a> like you and can be on any <a href="<!--% absolute_path(baseurl) %-->eps/index.html">topic</a> that <strong>"are of interest to <a href="https://en.wikipedia.org/wiki/hacker_(hobbyist)">hackers</a>"</strong>. if you listen to HPR then please consider contributing one show a year. if you <a href="<!--% absolute_path(baseurl) %-->contribute.html">record</a> your show now it could be <a href="https://www.hackerpublicradio.org/calendar.php">released</a> in <strong><!--% days_till_next_episode %--></strong> days.</p>
|
<p>We started producing shows as <a href="<!--% absolute_path(baseurl) %-->eps/index.html#twat_episodes"><em>Today with a Techie</em></a> on 2005-09-19, <!--% delta.0 %--> years, <!--% delta.1 %--> months, <!--% delta.2 %--> days ago. our shows are produced by <a href="<!--% absolute_path(baseurl) %-->correspondents/index.html">listeners</a> like you and can be on any <a href="<!--% absolute_path(baseurl) %-->eps/index.html">topic</a> that <strong>"are of interest to <a href="https://en.wikipedia.org/wiki/hacker_(hobbyist)">hackers</a>"</strong>. if you listen to HPR then please consider contributing one show a year. if you <a href="<!--% absolute_path(baseurl) %-->contribute.html">record</a> your show now it could be <a href="https://www.hackerpublicradio.org/calendar.php">released</a> in <strong><!--% days_till_next_episode %--></strong> days.</p>
|
||||||
|
</article>
|
||||||
|
<!--% display_call_for_shows() %-->
|
||||||
|
<article>
|
||||||
<h4>Meet the team</h4>
|
<h4>Meet the team</h4>
|
||||||
<p>
|
<p>
|
||||||
<audio controls preload="none">";
|
<audio controls preload="none">";
|
||||||
@@ -41,74 +53,35 @@
|
|||||||
<hr>
|
<hr>
|
||||||
<!--% PROCESS 'shared-episode-summary.tpl.html' %-->
|
<!--% PROCESS 'shared-episode-summary.tpl.html' %-->
|
||||||
<h1>Latest Shows</h1>
|
<h1>Latest Shows</h1>
|
||||||
<!--% FOREACH latest_episodes IN DBI.query('
|
<!--% host_cnt = 0 %-->
|
||||||
WITH comment_tallies AS (
|
<!--% FOREACH latest_episodes IN DBI.query(query_latest_episodes)
|
||||||
SELECT
|
|
||||||
eps_id,
|
|
||||||
COUNT(eps_id) AS eps_tally
|
|
||||||
FROM comments
|
|
||||||
GROUP BY eps_id
|
|
||||||
)
|
|
||||||
SELECT
|
|
||||||
eps.id,
|
|
||||||
eps.explicit,
|
|
||||||
eps.date, eps.license, eps.duration,
|
|
||||||
eps.title, eps.summary, eps.tags,
|
|
||||||
eps.notes,
|
|
||||||
hosts.local_image,
|
|
||||||
hosts.hostid,
|
|
||||||
hosts.host, hosts.email,
|
|
||||||
miniseries.name AS series, miniseries.id AS seriesid,
|
|
||||||
COALESCE (comment_tallies.eps_tally, 0) AS eps_tally
|
|
||||||
FROM eps
|
|
||||||
INNER JOIN hosts ON eps.hostid = hosts.hostid
|
|
||||||
INNER JOIN miniseries ON eps.series = miniseries.id
|
|
||||||
LEFT JOIN comment_tallies ON eps.id = comment_tallies.eps_id
|
|
||||||
WHERE eps.date < date(\'now\', \'+1 days\')
|
|
||||||
ORDER BY date DESC
|
|
||||||
LIMIT 10
|
|
||||||
')
|
|
||||||
%-->
|
%-->
|
||||||
<hr>
|
<hr>
|
||||||
<article>
|
<article>
|
||||||
<header>
|
<header>
|
||||||
<h1><a href="<!--% absolute_path(baseurl) %-->eps/hpr<!--% zero_pad_left(latest_episodes.id) %-->/index.html">hpr<!--% latest_episodes.id %--> :: <!--% latest_episodes.title %--></a></h1>
|
<h1><a href="<!--% absolute_path(baseurl) %-->eps/hpr<!--% zero_pad_left(latest_episodes.id) %-->/index.html">hpr<!--% latest_episodes.id %--> :: <!--% latest_episodes.title %--></a></h1>
|
||||||
<h3><!--% latest_episodes.summary%--></h3>
|
<h3><!--% latest_episodes.summary%--></h3>
|
||||||
<p class="meta"$><!--% IF get_avatar(latest_episodes.hostid) != 'hpr_logo.png' %-->
|
<p class="meta"$><!--% show_avatar(latest_episodes.hostid, latest_episodes.host, host_cnt) %-->
|
||||||
<img src="<!--% absolute_path(baseurl) %-->images/<!--% get_avatar(latest_episodes.hostid) %-->" height="80" width="80" alt="" /></a><!--% END %-->
|
Hosted by <a href="<!--% absolute_path(baseurl) %-->correspondents/<!--% zero_pad_left(latest_episodes.hostid) %-->.html"><!--% latest_episodes.host %--></a> on <!--% latest_episodes.date %--> is flagged as <!--% display_explicit(latest_episodes.explicit) %--> and released under a <!--% latest_episodes.license %--> license. <br>
|
||||||
<br>Hosted by <a href="<!--% absolute_path(baseurl) %-->correspondents/<!--% zero_pad_left(latest_episodes.hostid) %-->.html"><!--% latest_episodes.host %--></a> on <!--% latest_episodes.date %--> is flagged as <!--% display_explicit(latest_episodes.explicit) %--> and released under a <!--% latest_episodes.license %--> license. <br>
|
|
||||||
<!--% display_tags(latest_episodes.tags) %--><br>
|
<!--% display_tags(latest_episodes.tags) %--><br>
|
||||||
|
<!--% listen_now(latest_episodes, "hpr", baseurl, media_baseurl) %-->
|
||||||
<small><!--% display_listen_in(latest_episodes.id) %--> <!--% show_series(latest_episodes.series, latest_episodes.seriesid) %--> |
|
<small><!--% display_listen_in(latest_episodes.id) %--> <!--% show_series(latest_episodes.series, latest_episodes.seriesid) %--> |
|
||||||
<!--% display_comments_tally(latest_episodes.id, latest_episodes.eps_tally) %--></small>
|
<!--% display_comments_tally(latest_episodes.id, latest_episodes.eps_tally) %--></small>
|
||||||
</p>
|
</p>
|
||||||
</header>
|
</header>
|
||||||
<!--% latest_episodes.notes %-->
|
<!--% tidy_notes(latest_episodes.notes) %-->
|
||||||
<footer>
|
<footer>
|
||||||
<!--% listen_now(latest_episodes, "hpr", baseurl, media_hostname) %-->
|
<!--% show_transcript(latest_episodes, "hpr", baseurl, media_baseurl) %-->
|
||||||
</footer>
|
</footer>
|
||||||
</article>
|
</article>
|
||||||
|
<!--% host_cnt = host_cnt + 1 %-->
|
||||||
<!--% END %-->
|
<!--% END %-->
|
||||||
<article>
|
<article>
|
||||||
<header>
|
<header>
|
||||||
<hr>
|
<hr>
|
||||||
<h1>Previous five weeks</h1>
|
<h1>Previous five weeks</h1>
|
||||||
</header>
|
</header>
|
||||||
<!--% FOREACH last_5_weeks_episodes IN DBI.query('
|
<!--% FOREACH last_5_weeks_episodes IN DBI.query(query_last_5_weeks_episodes)
|
||||||
SELECT
|
|
||||||
eps.id,
|
|
||||||
CASE eps.explicit WHEN 1 THEN \'Explicit\' ELSE \'Clean\' END AS explicit ,
|
|
||||||
eps.date, eps.license, eps.title, eps.summary,
|
|
||||||
eps.duration, eps.notes, eps.tags,
|
|
||||||
hosts.hostid,
|
|
||||||
hosts.host, hosts.email, hosts.local_image,
|
|
||||||
miniseries.name AS series, miniseries.id AS seriesid
|
|
||||||
FROM eps
|
|
||||||
INNER JOIN hosts ON eps.hostid = hosts.hostid
|
|
||||||
INNER JOIN miniseries ON eps.series = miniseries.id
|
|
||||||
WHERE eps.date < date(\'now\', \'+1 days\')
|
|
||||||
ORDER BY date DESC
|
|
||||||
LIMIT 30 OFFSET 10
|
|
||||||
')
|
|
||||||
%-->
|
%-->
|
||||||
<!--% show_summary(last_5_weeks_episodes) %-->
|
<!--% show_summary(last_5_weeks_episodes) %-->
|
||||||
<!--% END %-->
|
<!--% END %-->
|
||||||
|
189
templates/content-mumble-howto.tpl.html
Normal file
@@ -0,0 +1,189 @@
|
|||||||
|
<!--% PROCESS 'shared-utils.tpl.html' %-->
|
||||||
|
<p>In this article we will show you how to connect to the HPR Community Room on Mumble.</p>
|
||||||
|
|
||||||
|
<p>You can think of Mumble like visiting a hotel that has different meeting rooms. Some are locked to you, some only allow you access if you are registered, some you can join but only listen to. In most, like the HPR room, you can hear the other people in the room talking. If you talk they can also hear you. There is a chat section where text can be shared as well.</p>
|
||||||
|
|
||||||
|
<p>When using Mumble <strong><em>you should always use a microphone and headset</em></strong> positioned close to your mouth but slightly off to the side.</p>
|
||||||
|
<h2>Install the software</h2>
|
||||||
|
|
||||||
|
<p>The <a href="https://www.mumble.info/downloads/">Mumble website offers download and install instructions</a> for different operating systems.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>Once you have installed the client then connect to the <a href="mumble://chatter.skyehaven.net:64738/Hacker%20Public%20Radio?version=1.2.0">HPR Room on Mumble</a>.
|
||||||
|
|
||||||
|
<p>There is a first run wizard that will step you through the process of configuring Mumble the first time. This will open up a series of configuration options.</p>
|
||||||
|
|
||||||
|
<p>Press <strong>Next</strong> on the introduction.</p>
|
||||||
|
|
||||||
|
<p><img alt="intro screenshot" src="<!--% absolute_path(baseurl) %-->images/mumble-howto/01-intro.png" ></p>
|
||||||
|
|
||||||
|
<p>The device selection page will allow you to select which audio to use. As this will be different for everyone we can't offer you much help here other than to say that the defaults are usually fine.</p>
|
||||||
|
|
||||||
|
<p>When you are done press <strong>Next</strong>.</p>
|
||||||
|
|
||||||
|
<p><img alt="device selection screenshot" src="<!--% absolute_path(baseurl) %-->images/mumble-howto/02-device-selection.png" ></p>
|
||||||
|
|
||||||
|
<p>The device tuning page will allow you to fine tune the latency. Normally the defaults are usually fine.</p>
|
||||||
|
|
||||||
|
<p>When you are done press <strong>Next</strong>.</p>
|
||||||
|
|
||||||
|
<p><img alt="device tuning screenshot" src="<!--% absolute_path(baseurl) %-->images/mumble-howto/03-device-tuning.png" ></p>
|
||||||
|
|
||||||
|
<p>The Volume Tuning page will allow you to set your audio levels. Normally the defaults are usually fine.</p>
|
||||||
|
|
||||||
|
<p>Then press <strong>Next</strong>.</p>
|
||||||
|
|
||||||
|
<p><img alt="volume tuning screenshot" src="<!--% absolute_path(baseurl) %-->images/mumble-howto/04-volume.png" ></p>
|
||||||
|
|
||||||
|
<p>It is <strong>very important</strong> that you set <strong>Push to Talk (PTT)</strong>, as you will disturb the other people in the room if you select the other methods. It may seem to be working fine to you, but it <em>will</em> result in issues for the others.
|
||||||
|
</p>
|
||||||
|
<ul>
|
||||||
|
<li>Click "Push to Talk:"</li>
|
||||||
|
<li>Click in the area next to it and press the key you intend to use as the Push To Talk (PTT) Key</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<p>Try and pick a key that you don't normally use or need. You may have to disable that key mapping in the operating system you are using.</p>
|
||||||
|
|
||||||
|
<p>Then press <strong>Next</strong>.</p>
|
||||||
|
|
||||||
|
<p><img alt="ptt screenshot" src="<!--% absolute_path(baseurl) %-->images/mumble-howto/05-ptt.png" ></p>
|
||||||
|
|
||||||
|
<p>The Quality Settings page will allow you to adjust the bandwidth. Normally the defaults are usually fine.</p>
|
||||||
|
|
||||||
|
<p>It is <strong>very important</strong> that you <strong>Disable Text-To-Speech</strong>, as all notifications will be read back and will disturb the other people in the room. It may seem to be working fine to you, but it <em>will</em> result in issues for the others.</p>
|
||||||
|
<ul>
|
||||||
|
<li>Click "Disable Text-To-Speech and use sounds instead"</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<p>Then press <strong>Next</strong>.</p>
|
||||||
|
|
||||||
|
<p><img alt="no tts screenshot" src="<!--% absolute_path(baseurl) %-->images/mumble-howto/06-notts.png" ></p>
|
||||||
|
|
||||||
|
<p>The positional audio page will allow you to fine tune the latency. Normally the defaults are usually fine.</p>
|
||||||
|
|
||||||
|
<p>Just press <strong>Next</strong>.</p>
|
||||||
|
|
||||||
|
<p><img alt="positional audio screenshot" src="<!--% absolute_path(baseurl) %-->images/mumble-howto/07-positional-audio.png" ></p>
|
||||||
|
|
||||||
|
<p>That's it the initial configuration is done.</p>
|
||||||
|
|
||||||
|
<p>Then press <strong>Finish</strong>.</p>
|
||||||
|
|
||||||
|
<p><img alt="stats screenshot" src="<!--% absolute_path(baseurl) %-->images/mumble-howto/08-stats.png" ></p>
|
||||||
|
|
||||||
|
<p>You are expected to have a digital certificate when connecting to Mumble servers.</p>
|
||||||
|
|
||||||
|
<p>This screen will allow you to Automatically create one.</p>
|
||||||
|
|
||||||
|
<p>Just press <strong>Next</strong>.</p>
|
||||||
|
|
||||||
|
<p><img alt="cert screenshot" src="<!--% absolute_path(baseurl) %-->images/mumble-howto/09-cert.png" ></p>
|
||||||
|
|
||||||
|
<p>That completes the first setup of Mumble.</p>
|
||||||
|
|
||||||
|
<p>Then press <strong>Finish</strong>.</p>
|
||||||
|
|
||||||
|
<p><img alt="finished screenshot" src="<!--% absolute_path(baseurl) %-->images/mumble-howto/10-finished.png" ></p>
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
<p>Now that you have the Mumble client set up we can now start the process of connecting to the <a href="mumble://chatter.skyehaven.net:64738/Hacker%20Public%20Radio?version=1.2.0">HPR Room on Mumble</a>.</p>
|
||||||
|
|
||||||
|
<p>If you opened Mumble by clicking the link above, then you may not see the following options, but we'll cover them here if at any time you need to add the HPR server again</p>
|
||||||
|
|
||||||
|
<p>Just open mumble and press <strong>Server - Connect</strong></p>
|
||||||
|
|
||||||
|
<p>Then press <strong>Add New...</strong>.</p>
|
||||||
|
|
||||||
|
<p><img alt="add new connection screenshot" src="<!--% absolute_path(baseurl) %-->images/mumble-howto/20-add-new.png" ></p>
|
||||||
|
|
||||||
|
<p>You will need to enter the information for the HPR server:</p>
|
||||||
|
<ul>
|
||||||
|
<li>Address: <strong>chatter.skyehaven.net</strong></li>
|
||||||
|
<li>Port: 64738</li>
|
||||||
|
<li>Username: <strong><em>Your Username</em></strong></li>
|
||||||
|
<li>Label: chatter.skyehaven.net</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<p>Think about your username a bit as if you register it on the server you will not be able to change it again.</p>
|
||||||
|
|
||||||
|
<p>Then press <strong>Next</strong>.</p>
|
||||||
|
|
||||||
|
<p><img alt="add new server screenshot" src="<!--% absolute_path(baseurl) %-->images/mumble-howto/21-add-server.png" ></p>
|
||||||
|
|
||||||
|
<p>If you clicked the link to the <a href="mumble://chatter.skyehaven.net:64738/Hacker%20Public%20Radio?version=1.2.0">HPR Room on Mumble</a>, then you may be brought to the option to enter a username. Think about this a bit as if you register it on the server you will not be able to change it again.</p>
|
||||||
|
|
||||||
|
<p>Then press <strong>Next</strong>.</p>
|
||||||
|
|
||||||
|
<p><img alt="username screenshot" src="<!--% absolute_path(baseurl) %-->images/mumble-howto/11-username.png" ></p>
|
||||||
|
|
||||||
|
<p>You will need to confirm the servers Certificate matches this:</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<pre>Digest (SHA-1): 09:22:05:88:D6:60:17:FD:39:8F:55:B0:F5:A0:45:DA:96:32:9C:23</pre>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>If it matches then press <strong>Yes</strong>.</p>
|
||||||
|
|
||||||
|
<p><img alt="accept cert screenshot" src="<!--% absolute_path(baseurl) %-->images/mumble-howto/12-accept-cert.png" ></p>
|
||||||
|
|
||||||
|
<p>All going well you will be connected to the server. By default you will end up in the <strong>Root</strong> - think the lobby of an hotel !</p>
|
||||||
|
|
||||||
|
<p>You will see a lot of rooms with names of other podcasts that use the server.</p>
|
||||||
|
|
||||||
|
<p>Before connecting to any room it's good etiquette to make sure your audio is working correctly.</p>
|
||||||
|
|
||||||
|
<p>The room <strong>Audio Test</strong> will allow you to speak and the <strong>OpieTheRepeatherBot</strong> will record your speech and after 10 seconds will play it back for you.</p>
|
||||||
|
|
||||||
|
<p><em>Click and hold</em> on your username (<em>ken1</em> in this example) and <em>drag</em> yourself into the <strong>Audio Test</strong> room.</p>
|
||||||
|
|
||||||
|
<p><img alt="audio test screenshot" src="<!--% absolute_path(baseurl) %-->images/mumble-howto/13-audio-test.png" ></p>
|
||||||
|
|
||||||
|
<p>You now know how to switch from room to room.</p>
|
||||||
|
|
||||||
|
<p>Try to say something. Remember to press the <strong>Push to talk (PTT)</strong>. Everyone forgets to do this but it will become second nature after a while.</p>
|
||||||
|
|
||||||
|
<p>A good test is to count to ten slowly.</p>
|
||||||
|
|
||||||
|
<p>When you are talking the server should change your icon from a green person to a <em>blue</em> one with <em>sound circles</em> around the head.</p>
|
||||||
|
|
||||||
|
<p><img alt="audio ping screenshot" src="<!--% absolute_path(baseurl) %-->images/mumble-howto/14-audio-ping.png" ></p>
|
||||||
|
|
||||||
|
<p>The <strong>OpieTheRepeatherBot</strong> will create another client with the prefix <strong>Mimic-</strong> followed by your username.</p>
|
||||||
|
|
||||||
|
<p>In this example it is <em>Mimic-ken1</em>.</p>
|
||||||
|
|
||||||
|
<p>You should hear your audio back.</p>
|
||||||
|
|
||||||
|
<p><img alt="audio pong screenshot" src="<!--% absolute_path(baseurl) %-->images/mumble-howto/15-audio-pong.png" ></p>
|
||||||
|
|
||||||
|
<p>If your audio is poor - as is often the case - then this gives you the opportunity to fix it before interrupting other people.</p>
|
||||||
|
|
||||||
|
<p>How you fix it will depend on the operating system that you are using and the exact nature of the problem.</p>
|
||||||
|
|
||||||
|
<p>A common problem is that the operating system uses the built in speaker and microphone from the laptop instead of your headset. A tip would be to press the <strong>Push to talk (PTT)</strong> button and tap the microphone of your head set lightly. If you don't hear the tapping then Mumble is probably getting the wrong microphone as input.</p>
|
||||||
|
|
||||||
|
<p>In the example below I clicked the Microphone icon in my taskbar and a application (<em>pavucontrol</em>) opened allowing me to set the correct microphone.</p>
|
||||||
|
|
||||||
|
<p><img alt="hpr room screenshot" src="<!--% absolute_path(baseurl) %-->images/mumble-howto/22-pavucontrol-recording.png" ></p>
|
||||||
|
|
||||||
|
<p>While I was there I also checked to make sure that Mumble was playing audio to my headset.</p>
|
||||||
|
|
||||||
|
<p><img alt="hpr room screenshot" src="<!--% absolute_path(baseurl) %-->images/mumble-howto/23-pavucontrol-playback.png" ></p>
|
||||||
|
|
||||||
|
<p>Satisfied that the audio is good, you can <em>click and drag</em> your icon to the <strong>HPR</strong> room.</p>
|
||||||
|
|
||||||
|
<p><img alt="hpr room screenshot" src="<!--% absolute_path(baseurl) %-->images/mumble-howto/16-hpr-room.png" ></p>
|
||||||
|
|
||||||
|
<p>Some rooms require you to be registered to enter a room, to speak, to record, or to chat in the room.</p>
|
||||||
|
|
||||||
|
<p>To register first <em>Right Click</em> on your icon and a menu will open.</p>
|
||||||
|
|
||||||
|
<p>Press <strong>Register....</strong></p>
|
||||||
|
|
||||||
|
<p><img alt="register screenshot" src="<!--% absolute_path(baseurl) %-->images/mumble-howto/17-register.png" ></p>
|
||||||
|
|
||||||
|
<p>Then press <strong>Yes</strong></p>
|
||||||
|
|
||||||
|
<p><img alt="register confirm screenshot" src="<!--% absolute_path(baseurl) %-->images/mumble-howto/18-register-confirm.png" ></p>
|
||||||
|
|
||||||
|
<p>That's it - you are now all set to use mumble.</p>
|
@@ -1,28 +1,16 @@
|
|||||||
<!--% PROCESS 'shared-utils.tpl.html' %-->
|
<!--% PROCESS 'shared-utils.tpl.html' %-->
|
||||||
|
<!--% PROCESS "queries-series-${constants.database}.tpl.html" %-->
|
||||||
<article>
|
<article>
|
||||||
<!--% USE DBI(constants.driver, constants.user, constants.password) %-->
|
<!--% USE DBI(constants.driver, constants.user, constants.password) %-->
|
||||||
<h1 class="title">In-Depth Series</h1>
|
<h1 class="title">In-Depth Series</h1>
|
||||||
<!--% FOREACH series IN DBI.query(
|
<!--% FOREACH series IN DBI.query(query_episodes) %-->
|
||||||
'SELECT miniseries.id, miniseries.name, miniseries.description,
|
|
||||||
miniseries.private, miniseries.image, miniseries.valid,
|
|
||||||
ep.number_of_episodes, ep.latest_show, ep.earliest_show
|
|
||||||
FROM miniseries
|
|
||||||
INNER JOIN
|
|
||||||
(SELECT series,
|
|
||||||
COUNT(eps.id) AS number_of_episodes,
|
|
||||||
MAX(eps.date) AS latest_show,
|
|
||||||
MIN(eps.date) AS earliest_show
|
|
||||||
FROM eps
|
|
||||||
GROUP BY series) AS ep ON ep.series = miniseries.id
|
|
||||||
ORDER BY name'
|
|
||||||
) %-->
|
|
||||||
<h2><a href="<!--% absolute_path(baseurl) %-->series/<!--% zero_pad_left(series.id) %-->.html"><!--% series.name %--></a></h2>
|
<h2><a href="<!--% absolute_path(baseurl) %-->series/<!--% zero_pad_left(series.id) %-->.html"><!--% series.name %--></a></h2>
|
||||||
<ul>
|
<ul>
|
||||||
<li>Number of episodes: <!--% series.number_of_episodes %--></li>
|
<li>Number of episodes: <!--% series.number_of_episodes %--></li>
|
||||||
<li>Open/closed: <!--% display_choice(series.private, 'closed', 'open') %--></li>
|
<li>Open/closed: <!--% display_choice(series.private, 'closed', 'open') %--></li>
|
||||||
<li>Date of earliest show: <!--% series.earliest_show %--></li>
|
<li>Date of earliest show: <!--% series.earliest_show %--></li>
|
||||||
<li>Date of latest show: <!--% series.latest_show %--></li>
|
<li>Date of latest show: <!--% series.latest_show %--></li>
|
||||||
<li>Series RSS feeds: <a href="hpr_ogg_rss.php?series=38">ogg</a>, <a href="hpr_spx_rss.php?series=38">spx</a>, <a href="hpr_mp3_rss.php?series=38">mp3</a></li>
|
<li>Series RSS feeds: <a href="https://www.hackerpublicradio.org/hpr_ogg_rss.php?series=<!--% series.id %-->">ogg</a>, <a href="https://www.hackerpublicradio.org/hpr_spx_rss.php?series=<!--% series.id %-->">spx</a>, <a href="https://www.hackerpublicradio.org/hpr_mp3_rss.php?series=<!--% series.id %-->">mp3</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
<em><!--% series.description %--></em>
|
<em><!--% series.description %--></em>
|
||||||
<!--% END %-->
|
<!--% END %-->
|
||||||
|
@@ -1,20 +1,8 @@
|
|||||||
<!--% PROCESS 'shared-episode-summary.tpl.html' %-->
|
<!--% PROCESS 'shared-episode-summary.tpl.html' %-->
|
||||||
<!--% PROCESS 'shared-avatar.tpl.html' %-->
|
<!--% PROCESS 'shared-avatar.tpl.html' %-->
|
||||||
|
<!--% PROCESS "queries-series_episodes-${constants.database}.tpl.html" %-->
|
||||||
<!--% USE DBI(constants.driver, constants.user, constants.password) %-->
|
<!--% USE DBI(constants.driver, constants.user, constants.password) %-->
|
||||||
<!--% query_series = DBI.prepare('SELECT miniseries.id, miniseries.name,
|
<!--% query_series = DBI.prepare(query_series_sql)
|
||||||
miniseries.description,
|
|
||||||
miniseries.private, miniseries.image, miniseries.valid,
|
|
||||||
ep.number_of_episodes, ep.latest_show, ep.earliest_show
|
|
||||||
FROM miniseries
|
|
||||||
INNER JOIN
|
|
||||||
(SELECT series,
|
|
||||||
COUNT(eps.id) AS number_of_episodes,
|
|
||||||
MAX(eps.date) AS latest_show,
|
|
||||||
MIN(eps.date) AS earliest_show
|
|
||||||
FROM eps
|
|
||||||
GROUP BY series) AS ep ON ep.series = miniseries.id
|
|
||||||
WHERE miniseries.id = ?
|
|
||||||
ORDER BY name')
|
|
||||||
%-->
|
%-->
|
||||||
<!--% series_result = query_series.execute(id) %-->
|
<!--% series_result = query_series.execute(id) %-->
|
||||||
<article>
|
<article>
|
||||||
@@ -25,21 +13,11 @@
|
|||||||
<li>Open/closed: open</li>
|
<li>Open/closed: open</li>
|
||||||
<li>Date of earliest show: <!--% series.earliest_show %--></li>
|
<li>Date of earliest show: <!--% series.earliest_show %--></li>
|
||||||
<li>Date of latest show: <!--% series.latest_show %--></li>
|
<li>Date of latest show: <!--% series.latest_show %--></li>
|
||||||
<li>Series RSS feeds: <a href="hpr_ogg_rss.php?series=79&full=1&gomax=1">ogg</a>, <a href="hpr_spx_rss.php?series=79&full=1&gomax=1">spx</a>, <a href="hpr_mp3_rss.php?series=79&full=1&gomax=1">mp3</a></li>
|
<li>Series RSS feeds: <a href="https://www.hackerpublicradio.org/hpr_ogg_rss.php?series=<!--% series.id %-->&full=1&gomax=1">ogg</a>, <a href="https://www.hackerpublicradio.org/hpr_spx_rss.php?series=<!--% series.id %-->&full=1&gomax=1">spx</a>, <a href="https://www.hackerpublicradio.org/hpr_mp3_rss.php?series=<!--% series.id %-->&full=1&gomax=1">mp3</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
<div><em><!--% series.description %--></em></div>
|
<div><em><!--% series.description %--></em></div>
|
||||||
<!--% END %-->
|
<!--% END %-->
|
||||||
<!--% query_shows = DBI.prepare('SELECT
|
<!--% query_shows = DBI.prepare(query_shows_sql)
|
||||||
id, date, title,
|
|
||||||
duration, summary, notes,
|
|
||||||
explicit, eps.license, tags,
|
|
||||||
hosts.host, hosts.hostid
|
|
||||||
FROM eps
|
|
||||||
INNER JOIN hosts
|
|
||||||
ON eps.hostid = hosts.hostid
|
|
||||||
WHERE series = ?
|
|
||||||
ORDER BY date DESC
|
|
||||||
')
|
|
||||||
%-->
|
%-->
|
||||||
<!--% show_results = query_shows.execute(id) %-->
|
<!--% show_results = query_shows.execute(id) %-->
|
||||||
<!--% FOREACH show IN show_results %-->
|
<!--% FOREACH show IN show_results %-->
|
||||||
|
@@ -1,3 +1,51 @@
|
|||||||
|
<h1>RSS Syndication</h1>
|
||||||
|
<p><small><em><a href="http://hackerpublicradio.org/advanced_rss_settings.php">Advanced Settings</a>.</em></small></p>
|
||||||
|
|
||||||
|
<article>
|
||||||
|
<header>
|
||||||
|
<h2>Subscribe to our Feeds</h2>
|
||||||
|
</header>
|
||||||
|
<p>
|
||||||
|
Great that you want to listen. Have a look below at the feeds that best suite your listening habits.
|
||||||
|
</p>
|
||||||
|
</article>
|
||||||
|
<article>
|
||||||
|
<header>
|
||||||
|
<h2><img src="<!--% absolute_path(baseurl) %-->images/feed.png" alt="rss logo"> The Community News Summary</h2>
|
||||||
|
<h3>One show a month</h3>
|
||||||
|
</header>
|
||||||
|
<p>
|
||||||
|
If you get overwhelmend by the amount of shows we produce, then this is a good place to start.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Every month, the HPR Janitors put down their mops had have a chat about all the shows, and what else has been going on in the HPR community. This is a regular show scheduled for the first Monday of the month.
|
||||||
|
</p>
|
||||||
|
<ul>
|
||||||
|
<li><a href="https://hackerpublicradio.org/hpr_ogg_rss.php?series=47">ogg</a> Larger file size higher quality feed.</li>
|
||||||
|
<li><a href="https://hackerpublicradio.org/hpr_spx_rss.php?series=47">mp3</a> Larger file size regular quality feed in a common format.</li>
|
||||||
|
<li><a href="https://hackerpublicradio.org/hpr_mp3_rss.php?series=47">spx</a> Small file size lower quality feed. <br/>Ideal for dial-up/mobile connections.</li>
|
||||||
|
</ul>
|
||||||
|
<p>
|
||||||
|
We also maintain an <a href="https://archive.org/details/hackerpublicradio?and[]=subject%3A%22Community+News%22">Archive.org</a> page where you can get the shows in even more formats.
|
||||||
|
</p>
|
||||||
|
</article>
|
||||||
|
<article>
|
||||||
|
<header>
|
||||||
|
<h2><img src="<!--% absolute_path(baseurl) %-->images/feed.png" alt="rss logo"> Two week Audio feed</h2>
|
||||||
|
<h3>5 shows a week</h3>
|
||||||
|
</header>
|
||||||
|
<p>
|
||||||
|
Use these feeds to keep up to date with the latest HPR Episodes.
|
||||||
|
</p>
|
||||||
|
<ul>
|
||||||
|
<li><a href="hpr_ogg_rss.php">ogg</a> Larger file size higher quality feed.</li>
|
||||||
|
<li><a href="hpr_rss.php">mp3</a> Larger file size regular quality feed in a common format.</li>
|
||||||
|
<li><a href="hpr_spx_rss.php">spx</a> Small file size lower quality feed. <br/>Ideal for dial-up/mobile connections.</li>
|
||||||
|
</ul>
|
||||||
|
<p>
|
||||||
|
We also maintain an <a href="https://archive.org/details/hackerpublicradio">Archive.org</a> page where you can get the shows in even more formats. For more recent shows we are now including the original upload as delivered.
|
||||||
|
</p>
|
||||||
|
</article>
|
||||||
<article>
|
<article>
|
||||||
<header>
|
<header>
|
||||||
<h2><img src="<!--% absolute_path(baseurl) %-->images/feed.png" alt="rss logo"> Entire Archive Audio feed</h2>
|
<h2><img src="<!--% absolute_path(baseurl) %-->images/feed.png" alt="rss logo"> Entire Archive Audio feed</h2>
|
||||||
@@ -19,7 +67,7 @@
|
|||||||
Use this feed to get the shows as they are posted. The shows will be posted out of order as they come in and may be replaced/reposted if errors are found. This is intended as a means to provide find issues with metadata or the audio quality of new shows before they hit the main feed.
|
Use this feed to get the shows as they are posted. The shows will be posted out of order as they come in and may be replaced/reposted if errors are found. This is intended as a means to provide find issues with metadata or the audio quality of new shows before they hit the main feed.
|
||||||
</p>
|
</p>
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="rss-future.php">Shows as they are posted.</a> OGG Only</li>
|
<li><a href="https://www.hackerpublicradio.org/rss-future.php">Shows as they are posted.</a> OGG Only</li>
|
||||||
</ul>
|
</ul>
|
||||||
</article>
|
</article>
|
||||||
<article>
|
<article>
|
||||||
@@ -27,6 +75,27 @@
|
|||||||
<h2><img src="<!--% absolute_path(baseurl) %-->images/feed.png" alt="rss logo"> Comment feed</h2>
|
<h2><img src="<!--% absolute_path(baseurl) %-->images/feed.png" alt="rss logo"> Comment feed</h2>
|
||||||
</header>
|
</header>
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="http://www.hackerpublicradio.org/comments_rss.php">Listener contributed comments to the episodes</a></li>
|
<li><a href="<!--% absolute_path(baseurl) %-->comments.rss">Listener contributed comments to the episodes</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</article>
|
</article>
|
||||||
|
<article>
|
||||||
|
<header>
|
||||||
|
<h2>Site Replication Sources</h2>
|
||||||
|
</header>
|
||||||
|
<ul>
|
||||||
|
<li><a href="<!--% absolute_path(baseurl) %-->hpr.sql">Daily Database Dump in SQL Format</a></li>
|
||||||
|
<ul>
|
||||||
|
</article>
|
||||||
|
<article>
|
||||||
|
<header>
|
||||||
|
<h2>External Sources</h2>
|
||||||
|
</header>
|
||||||
|
<ul>
|
||||||
|
<li><a href="https://archive.org/details/hackerpublicradio">Archive.org</a></li>
|
||||||
|
<li><a href="https://itunes.apple.com/us/podcast/hacker-public-radio/id281699640?mt=2">iTunes</a></li>
|
||||||
|
<li><a href="https://podcasts.google.com/feed/aHR0cDovL2hhY2tlcnB1YmxpY3JhZGlvLm9yZy9ocHJfcnNzLnBocA">Google Podcasts</a></li>
|
||||||
|
<li><a href="https://player.fm/series/hacker-public-radio">PlayerFM</a></li>
|
||||||
|
<li><a href="https://open.spotify.com/show/7e2hYcnHj9vKgUzsIOf4r3">Spotify</a></li>
|
||||||
|
<li><a href="https://www.mixcloud.com/hackerpublicradio/">MixCloud</a></li>
|
||||||
|
<ul>
|
||||||
|
</article>
|
||||||
|
@@ -7,7 +7,6 @@
|
|||||||
WITH episode_maxmin AS (
|
WITH episode_maxmin AS (
|
||||||
SELECT MAX(id) AS \'latest\', MIN(id) AS \'earliest\', ? AS \'id\'
|
SELECT MAX(id) AS \'latest\', MIN(id) AS \'earliest\', ? AS \'id\'
|
||||||
FROM twat_eps AS eps
|
FROM twat_eps AS eps
|
||||||
WHERE eps.date < date (\'now\', \'+1 days\')
|
|
||||||
),
|
),
|
||||||
episode_date AS (
|
episode_date AS (
|
||||||
SELECT eps.date
|
SELECT eps.date
|
||||||
@@ -26,7 +25,6 @@
|
|||||||
FROM twat_eps AS eps
|
FROM twat_eps AS eps
|
||||||
INNER JOIN episode_date
|
INNER JOIN episode_date
|
||||||
ON eps.date > episode_date.date
|
ON eps.date > episode_date.date
|
||||||
WHERE eps.date < date (\'now\')
|
|
||||||
)
|
)
|
||||||
SELECT eps.id, eps.date, eps.title, eps.duration,
|
SELECT eps.id, eps.date, eps.title, eps.duration,
|
||||||
eps.summary, eps.notes, eps.explicit, eps.license,
|
eps.summary, eps.notes, eps.explicit, eps.license,
|
||||||
@@ -54,18 +52,17 @@
|
|||||||
<h3><!--% episode.summary %--></h3>
|
<h3><!--% episode.summary %--></h3>
|
||||||
<p class="meta"><!--% episode_navigation %-->
|
<p class="meta"><!--% episode_navigation %-->
|
||||||
</p>
|
</p>
|
||||||
<p><!--% IF get_avatar(episode.hostid) != 'hpr_logo.png' %-->
|
<p><!--% show_avatar(episode.hostid, episode.host) %-->
|
||||||
<img src="<!--% absolute_path(baseurl) %-->images/<!--% get_avatar(episode.hostid) %-->" height="80" width="80" alt="" /></a><br><!--% END %-->
|
|
||||||
Hosted by <a href="<!--% absolute_path(baseurl) %-->correspondents/<!--% zero_pad_left(episode.hostid) %-->.html"><!--% episode.host %--></a> on <span><!--% episode.date %--></span> is flagged as <span><!--% display_explicit(episode.explicit) %--></span> and is released under a <span><!--% episode.license %--> license</span>. <br>
|
Hosted by <a href="<!--% absolute_path(baseurl) %-->correspondents/<!--% zero_pad_left(episode.hostid) %-->.html"><!--% episode.host %--></a> on <span><!--% episode.date %--></span> is flagged as <span><!--% display_explicit(episode.explicit) %--></span> and is released under a <span><!--% episode.license %--> license</span>. <br>
|
||||||
<!--% display_tags(episode.tags) %--> <br>
|
<!--% display_tags(episode.tags) %--> <br>
|
||||||
<!--% display_listen_in(episode.id) %-->
|
<!--% listen_now(episode, "twat", baseurl, media_baseurl) %-->
|
||||||
|
<!--% display_listen_in(episode.id, "twat") %-->
|
||||||
</p>
|
</p>
|
||||||
<h3><!--% show_series(episode.series, episode.seriesid, "Part of the series") %--></h3>
|
<h3><!--% show_series(episode.series, episode.seriesid, "Part of the series") %--></h3>
|
||||||
<p><em><!--% episode.series_description %--></em></p>
|
<p><em><!--% episode.series_description %--></em></p>
|
||||||
</header>
|
</header>
|
||||||
<div><!--% episode.notes %--></div>
|
<div><!--% episode.notes %--></div>
|
||||||
<footer>
|
<footer>
|
||||||
<!--% listen_now(episode, "twat", baseurl, media_hostname) %-->
|
|
||||||
<p>
|
<p>
|
||||||
<!--% episode_navigation %-->
|
<!--% episode_navigation %-->
|
||||||
</p>
|
</p>
|
||||||
|
@@ -1,8 +1,6 @@
|
|||||||
|
<!--% PROCESS "queries-ids-episode-${constants.database}.tpl.html" %-->
|
||||||
<!--% USE DBI(constants.driver, constants.user, constants.password) %-->
|
<!--% USE DBI(constants.driver, constants.user, constants.password) %-->
|
||||||
<!--% FOREACH episode IN DBI.query(
|
<!--% FOREACH episode IN DBI.query(query_ids_episode) %-->
|
||||||
'select eps.id from eps
|
|
||||||
where eps.date < date (\'now\', \'+1 days\') '
|
|
||||||
) %-->
|
|
||||||
,<!--% episode.id %-->
|
,<!--% episode.id %-->
|
||||||
<!--% END %-->
|
<!--% END %-->
|
||||||
|
|
||||||
|
@@ -1,7 +1,6 @@
|
|||||||
<!--% USE DBI(constants.driver, constants.user, constants.password) %-->
|
<!--% USE DBI(constants.driver, constants.user, constants.password) %-->
|
||||||
<!--% FOREACH episode IN DBI.query(
|
<!--% FOREACH episode IN DBI.query(
|
||||||
'select eps.id from twat_eps AS \'eps\'
|
'select eps.id from twat_eps AS eps'
|
||||||
where eps.date < date (\'now\', \'+1 days\') '
|
|
||||||
) %-->
|
) %-->
|
||||||
,<!--% episode.id %-->
|
,<!--% episode.id %-->
|
||||||
<!--% END %-->
|
<!--% END %-->
|
||||||
|
@@ -6,5 +6,5 @@
|
|||||||
<li><a href="<!--% absolute_path(baseurl) %-->correspondents/index.html">Hosts</a></li>
|
<li><a href="<!--% absolute_path(baseurl) %-->correspondents/index.html">Hosts</a></li>
|
||||||
<li><a href="<!--% absolute_path(baseurl) %-->contact.html">Contact</a></li>
|
<li><a href="<!--% absolute_path(baseurl) %-->contact.html">Contact</a></li>
|
||||||
<li><a href="<!--% absolute_path(baseurl) %-->promote.html">Promote HPR</a></li>
|
<li><a href="<!--% absolute_path(baseurl) %-->promote.html">Promote HPR</a></li>
|
||||||
<li><a href="<!--% absolute_path(baseurl) %-->comments_viewer.php">Show Comments</a></li>
|
<li><a href="<!--% absolute_path(baseurl) %-->comments_viewer.html">Show Comments</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
|
@@ -5,7 +5,7 @@
|
|||||||
<li><a href="<!--% absolute_path(baseurl) %-->syndication.html">Get Shows</a></li>
|
<li><a href="<!--% absolute_path(baseurl) %-->syndication.html">Get Shows</a></li>
|
||||||
<li><a href="<!--% absolute_path(baseurl) %-->contribute.html">Give Shows</a></li>
|
<li><a href="<!--% absolute_path(baseurl) %-->contribute.html">Give Shows</a></li>
|
||||||
<li><a href="<!--% absolute_path(baseurl) %-->help_out.html">Contribute</a></li>
|
<li><a href="<!--% absolute_path(baseurl) %-->help_out.html">Contribute</a></li>
|
||||||
<li><a href="<!--% absolute_path(baseurl) %-->tags.html">Tags</a></li>
|
<li><a href="http://www.hackerpublicradio.org/tags.php">Tags</a></li>
|
||||||
<li><a href="<!--% absolute_path(baseurl) %-->about.html">About</a></li>
|
<li><a href="<!--% absolute_path(baseurl) %-->about.html">About</a></li>
|
||||||
<li><a href="<!--% absolute_path(baseurl) %-->search.html">Search</a></li>
|
<li><a href="<!--% absolute_path(baseurl) %-->search.html">Search</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
|
6
templates/queries-call_for_shows-mysql.tpl.html
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<!--% query_call_for_shows = '
|
||||||
|
SELECT CASE WHEN COUNT(id) < 7 THEN True ELSE False END AS `request_for_shows`
|
||||||
|
FROM eps
|
||||||
|
WHERE eps.date > NOW() AND eps.date < DATE_ADD(NOW(), INTERVAL 10 DAY)
|
||||||
|
'
|
||||||
|
%-->
|
6
templates/queries-call_for_shows-sqlite.tpl.html
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<!--% query_call_for_shows = '
|
||||||
|
SELECT CASE WHEN COUNT(id) < 7 THEN True ELSE False END AS `request_for_shows`
|
||||||
|
FROM eps
|
||||||
|
WHERE eps.date > date(\'now\') AND eps.date < date(\'now\', \'+10 days\')
|
||||||
|
'
|
||||||
|
%-->
|
18
templates/queries-correspondent-mysql.tpl.html
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
<!--% query_hpr_shows = '
|
||||||
|
SELECT
|
||||||
|
eps.id,
|
||||||
|
CASE eps.explicit WHEN 1 THEN \'Explicit\' ELSE \'Clean\' END AS explicit ,
|
||||||
|
eps.date, eps.license, eps.duration,
|
||||||
|
eps.title, eps.summary, eps.tags,
|
||||||
|
eps.notes,
|
||||||
|
hosts.local_image,
|
||||||
|
hosts.hostid,
|
||||||
|
hosts.host, hosts.email,
|
||||||
|
miniseries.name AS series, miniseries.id AS seriesid
|
||||||
|
FROM eps
|
||||||
|
INNER JOIN hosts ON eps.hostid = hosts.hostid
|
||||||
|
INNER JOIN miniseries ON eps.series = miniseries.id
|
||||||
|
WHERE hosts.hostid = ? AND eps.date < DATE_ADD(NOW(), INTERVAL 1 DAY)
|
||||||
|
ORDER BY eps.id DESC
|
||||||
|
'
|
||||||
|
%-->
|
18
templates/queries-correspondent-sqlite.tpl.html
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
<!--% query_hpr_shows = '
|
||||||
|
SELECT
|
||||||
|
eps.id,
|
||||||
|
CASE eps.explicit WHEN 1 THEN \'Explicit\' ELSE \'Clean\' END AS explicit ,
|
||||||
|
eps.date, eps.license, eps.duration,
|
||||||
|
eps.title, eps.summary, eps.tags,
|
||||||
|
eps.notes,
|
||||||
|
hosts.local_image,
|
||||||
|
hosts.hostid,
|
||||||
|
hosts.host, hosts.email,
|
||||||
|
miniseries.name AS series, miniseries.id AS seriesid
|
||||||
|
FROM eps
|
||||||
|
INNER JOIN hosts ON eps.hostid = hosts.hostid
|
||||||
|
INNER JOIN miniseries ON eps.series = miniseries.id
|
||||||
|
WHERE hosts.hostid = ? AND eps.date < date(\'now\', \'+1 days\')
|
||||||
|
ORDER BY eps.id + 0 DESC
|
||||||
|
'
|
||||||
|
%-->
|
51
templates/queries-episode-mysql.tpl.html
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
<!--% query_episode_maxmin = '
|
||||||
|
WITH episode_maxmin AS (
|
||||||
|
SELECT MAX(id) AS \'latest\', MIN(id) AS \'earliest\', ? AS \'id\'
|
||||||
|
FROM eps
|
||||||
|
WHERE eps.date < DATE_ADD(NOW(), INTERVAL 1 DAY)
|
||||||
|
),
|
||||||
|
episode_date AS (
|
||||||
|
SELECT eps.date
|
||||||
|
FROM eps
|
||||||
|
WHERE eps.id = ?
|
||||||
|
),
|
||||||
|
episode_previous AS (
|
||||||
|
SELECT MAX(id) AS \'previous\', ? AS \'id\'
|
||||||
|
FROM eps
|
||||||
|
INNER JOIN episode_date
|
||||||
|
ON eps.date < episode_date.date
|
||||||
|
WHERE eps.id > 1
|
||||||
|
),
|
||||||
|
episode_next AS (
|
||||||
|
SELECT MIN(id) AS \'next\', ? AS \'id\'
|
||||||
|
FROM eps
|
||||||
|
INNER JOIN episode_date
|
||||||
|
ON eps.date > episode_date.date
|
||||||
|
WHERE eps.date < NOW()
|
||||||
|
),
|
||||||
|
comment_tallies AS (
|
||||||
|
SELECT
|
||||||
|
eps_id,
|
||||||
|
COUNT(eps_id) AS eps_tally
|
||||||
|
FROM comments
|
||||||
|
GROUP BY eps_id
|
||||||
|
)
|
||||||
|
SELECT eps.id, eps.date, eps.title, eps.duration,
|
||||||
|
eps.summary, eps.notes, eps.explicit, eps.license,
|
||||||
|
eps.tags, eps.version, eps.downloads, eps.valid,
|
||||||
|
episode_maxmin.latest, episode_maxmin.earliest,
|
||||||
|
episode_previous.previous, episode_next.next,
|
||||||
|
hosts.hostid, hosts.host,
|
||||||
|
miniseries.name AS \'series\', miniseries.id AS \'seriesid\',
|
||||||
|
miniseries.description AS \'series_description\',
|
||||||
|
COALESCE (comment_tallies.eps_tally, 0) AS eps_tally
|
||||||
|
FROM eps
|
||||||
|
INNER JOIN hosts ON eps.hostid = hosts.hostid
|
||||||
|
INNER JOIN miniseries ON eps.series = miniseries.id
|
||||||
|
INNER JOIN episode_maxmin ON eps.id = episode_maxmin.id
|
||||||
|
INNER JOIN episode_previous ON eps.id = episode_previous.id
|
||||||
|
INNER JOIN episode_next ON eps.id = episode_next.id
|
||||||
|
LEFT JOIN comment_tallies ON eps.id = comment_tallies.eps_id
|
||||||
|
WHERE eps.id = ?
|
||||||
|
'
|
||||||
|
%-->
|
51
templates/queries-episode-sqlite.tpl.html
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
<!--% query_episode_maxmin = '
|
||||||
|
WITH episode_maxmin AS (
|
||||||
|
SELECT MAX(id) AS \'latest\', MIN(id) AS \'earliest\', ? AS \'id\'
|
||||||
|
FROM eps
|
||||||
|
WHERE eps.date < date(\'now\', \'+1 days\')
|
||||||
|
),
|
||||||
|
episode_date AS (
|
||||||
|
SELECT eps.date
|
||||||
|
FROM eps
|
||||||
|
WHERE eps.id = ?
|
||||||
|
),
|
||||||
|
episode_previous AS (
|
||||||
|
SELECT MAX(id) AS \'previous\', ? AS \'id\'
|
||||||
|
FROM eps
|
||||||
|
INNER JOIN episode_date
|
||||||
|
ON eps.date < episode_date.date
|
||||||
|
WHERE eps.id > 1
|
||||||
|
),
|
||||||
|
episode_next AS (
|
||||||
|
SELECT MIN(id) AS \'next\', ? AS \'id\'
|
||||||
|
FROM eps
|
||||||
|
INNER JOIN episode_date
|
||||||
|
ON eps.date > episode_date.date
|
||||||
|
WHERE eps.date < date(\'now\')
|
||||||
|
),
|
||||||
|
comment_tallies AS (
|
||||||
|
SELECT
|
||||||
|
eps_id,
|
||||||
|
COUNT(eps_id) AS eps_tally
|
||||||
|
FROM comments
|
||||||
|
GROUP BY eps_id
|
||||||
|
)
|
||||||
|
SELECT eps.id, eps.date, eps.title, eps.duration,
|
||||||
|
eps.summary, eps.notes, eps.explicit, eps.license,
|
||||||
|
eps.tags, eps.version, eps.downloads, eps.valid,
|
||||||
|
episode_maxmin.latest, episode_maxmin.earliest,
|
||||||
|
episode_previous.previous, episode_next.next,
|
||||||
|
hosts.hostid, hosts.host,
|
||||||
|
miniseries.name AS \'series\', miniseries.id AS \'seriesid\',
|
||||||
|
miniseries.description AS \'series_description\',
|
||||||
|
COALESCE (comment_tallies.eps_tally, 0) AS eps_tally
|
||||||
|
FROM eps
|
||||||
|
INNER JOIN hosts ON eps.hostid = hosts.hostid
|
||||||
|
INNER JOIN miniseries ON eps.series = miniseries.id
|
||||||
|
INNER JOIN episode_maxmin ON eps.id = episode_maxmin.id
|
||||||
|
INNER JOIN episode_previous ON eps.id = episode_previous.id
|
||||||
|
INNER JOIN episode_next ON eps.id = episode_next.id
|
||||||
|
LEFT JOIN comment_tallies ON eps.id = comment_tallies.eps_id
|
||||||
|
WHERE eps.id = ?
|
||||||
|
'
|
||||||
|
%-->
|
15
templates/queries-episodes-mysql.tpl.html
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
<!--% query_episodes = 'SELECT
|
||||||
|
eps.id,
|
||||||
|
eps.explicit,
|
||||||
|
eps.date, eps.license, eps.title, eps.summary,
|
||||||
|
eps.duration, eps.notes, eps.tags,
|
||||||
|
hosts.hostid,
|
||||||
|
hosts.host, hosts.email, hosts.local_image,
|
||||||
|
miniseries.name AS series, miniseries.id AS seriesid
|
||||||
|
FROM eps
|
||||||
|
INNER JOIN hosts ON eps.hostid = hosts.hostid
|
||||||
|
INNER JOIN miniseries ON eps.series = miniseries.id
|
||||||
|
WHERE eps.date < DATE_ADD(NOW(), INTERVAL 1 DAY)
|
||||||
|
ORDER BY eps.id DESC'
|
||||||
|
%-->
|
||||||
|
|
15
templates/queries-episodes-sqlite.tpl.html
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
<!--% query_episodes = 'SELECT
|
||||||
|
eps.id,
|
||||||
|
eps.explicit,
|
||||||
|
eps.date, eps.license, eps.title, eps.summary,
|
||||||
|
eps.duration, eps.notes, eps.tags,
|
||||||
|
hosts.hostid,
|
||||||
|
hosts.host, hosts.email, hosts.local_image,
|
||||||
|
miniseries.name AS series, miniseries.id AS seriesid
|
||||||
|
FROM eps
|
||||||
|
INNER JOIN hosts ON eps.hostid = hosts.hostid
|
||||||
|
INNER JOIN miniseries ON eps.series = miniseries.id
|
||||||
|
WHERE eps.date < date(\'now\', \'+1 days\')
|
||||||
|
ORDER BY eps.id + 0 DESC'
|
||||||
|
%-->
|
||||||
|
|
4
templates/queries-ids-episode-mysql.tpl.html
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
<!--% query_ids_episode = 'select eps.id from eps
|
||||||
|
where eps.date < DATE_ADD(NOW(), INTERVAL 1 DAY) '
|
||||||
|
%-->
|
||||||
|
|
4
templates/queries-ids-episode-sqlite.tpl.html
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
<!--% query_ids_episode = 'select eps.id from eps
|
||||||
|
where eps.date < date(\'now\', \'+1 days\')'
|
||||||
|
%-->
|
||||||
|
|
62
templates/queries-index-mysql.tpl.html
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
<!--% query_next_available_episode = '
|
||||||
|
WITH next_id AS (
|
||||||
|
SELECT id, id + 1 AS \'id_next\', date as \'last_date\'
|
||||||
|
FROM eps
|
||||||
|
WHERE eps.date > NOW()
|
||||||
|
)
|
||||||
|
SELECT
|
||||||
|
MIN(next_id.id_next) AS \'next_id\',
|
||||||
|
DATE_FORMAT(MIN(last_date), \'%Y\') AS \'last_year\',
|
||||||
|
DATE_FORMAT(MIN(last_date), \'%d\') AS \'last_day\',
|
||||||
|
DATE_FORMAT(MIN(last_date), \'%m\') AS \'last_month\'
|
||||||
|
FROM next_id
|
||||||
|
LEFT JOIN eps ON next_id.id_next = eps.id
|
||||||
|
WHERE eps.id IS NULL
|
||||||
|
'
|
||||||
|
%-->
|
||||||
|
<!--% query_latest_episodes = '
|
||||||
|
WITH comment_tallies AS (
|
||||||
|
SELECT
|
||||||
|
eps_id,
|
||||||
|
COUNT(eps_id) AS eps_tally
|
||||||
|
FROM comments
|
||||||
|
GROUP BY eps_id
|
||||||
|
)
|
||||||
|
SELECT
|
||||||
|
eps.id,
|
||||||
|
eps.explicit,
|
||||||
|
eps.date, eps.license, eps.duration,
|
||||||
|
eps.title, eps.summary, eps.tags,
|
||||||
|
eps.notes,
|
||||||
|
hosts.local_image,
|
||||||
|
hosts.hostid,
|
||||||
|
hosts.host, hosts.email,
|
||||||
|
miniseries.name AS series, miniseries.id AS seriesid,
|
||||||
|
COALESCE (comment_tallies.eps_tally, 0) AS eps_tally
|
||||||
|
FROM eps
|
||||||
|
INNER JOIN hosts ON eps.hostid = hosts.hostid
|
||||||
|
INNER JOIN miniseries ON eps.series = miniseries.id
|
||||||
|
LEFT JOIN comment_tallies ON eps.id = comment_tallies.eps_id
|
||||||
|
WHERE eps.date < DATE_ADD(NOW(), INTERVAL 1 DAY)
|
||||||
|
ORDER BY eps.id DESC
|
||||||
|
LIMIT 10
|
||||||
|
'
|
||||||
|
%-->
|
||||||
|
<!--% query_last_5_weeks_episodes = '
|
||||||
|
SELECT
|
||||||
|
eps.id,
|
||||||
|
CASE eps.explicit WHEN 1 THEN \'Explicit\' ELSE \'Clean\' END AS explicit ,
|
||||||
|
eps.date, eps.license, eps.title, eps.summary,
|
||||||
|
eps.duration, eps.notes, eps.tags,
|
||||||
|
hosts.hostid,
|
||||||
|
hosts.host, hosts.email, hosts.local_image,
|
||||||
|
miniseries.name AS series, miniseries.id AS seriesid
|
||||||
|
FROM eps
|
||||||
|
INNER JOIN hosts ON eps.hostid = hosts.hostid
|
||||||
|
INNER JOIN miniseries ON eps.series = miniseries.id
|
||||||
|
WHERE eps.date < DATE_ADD(NOW(), INTERVAL 1 DAY)
|
||||||
|
ORDER BY eps.id DESC
|
||||||
|
LIMIT 30 OFFSET 10
|
||||||
|
'
|
||||||
|
%-->
|
||||||
|
|
62
templates/queries-index-sqlite.tpl.html
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
<!--% query_next_available_episode = '
|
||||||
|
WITH next_id AS (
|
||||||
|
SELECT id, id + 1 AS \'id_next\', date as \'last_date\'
|
||||||
|
FROM eps
|
||||||
|
WHERE eps.date > date(\'now\')
|
||||||
|
)
|
||||||
|
SELECT
|
||||||
|
MIN(next_id.id_next) AS \'next_id\',
|
||||||
|
strftime(\'%Y\', MIN (last_date)) AS \'last_year\',
|
||||||
|
strftime(\'%d\', MIN (last_date)) AS \'last_day\',
|
||||||
|
strftime(\'%m\', MIN (last_date)) AS \'last_month\'
|
||||||
|
FROM next_id
|
||||||
|
LEFT JOIN eps ON next_id.id_next = eps.id
|
||||||
|
WHERE eps.id IS NULL
|
||||||
|
'
|
||||||
|
%-->
|
||||||
|
<!--% query_latest_episodes = '
|
||||||
|
WITH comment_tallies AS (
|
||||||
|
SELECT
|
||||||
|
eps_id,
|
||||||
|
COUNT(eps_id) AS eps_tally
|
||||||
|
FROM comments
|
||||||
|
GROUP BY eps_id
|
||||||
|
)
|
||||||
|
SELECT
|
||||||
|
eps.id,
|
||||||
|
eps.explicit,
|
||||||
|
eps.date, eps.license, eps.duration,
|
||||||
|
eps.title, eps.summary, eps.tags,
|
||||||
|
eps.notes,
|
||||||
|
hosts.local_image,
|
||||||
|
hosts.hostid,
|
||||||
|
hosts.host, hosts.email,
|
||||||
|
miniseries.name AS series, miniseries.id AS seriesid,
|
||||||
|
COALESCE (comment_tallies.eps_tally, 0) AS eps_tally
|
||||||
|
FROM eps
|
||||||
|
INNER JOIN hosts ON eps.hostid = hosts.hostid
|
||||||
|
INNER JOIN miniseries ON eps.series = miniseries.id
|
||||||
|
LEFT JOIN comment_tallies ON eps.id = comment_tallies.eps_id
|
||||||
|
WHERE eps.date < date(\'now\', \'+1 days\')
|
||||||
|
ORDER BY eps.id + 0 DESC
|
||||||
|
LIMIT 10
|
||||||
|
'
|
||||||
|
%-->
|
||||||
|
<!--% query_last_5_weeks_episodes = '
|
||||||
|
SELECT
|
||||||
|
eps.id,
|
||||||
|
CASE eps.explicit WHEN 1 THEN \'Explicit\' ELSE \'Clean\' END AS explicit ,
|
||||||
|
eps.date, eps.license, eps.title, eps.summary,
|
||||||
|
eps.duration, eps.notes, eps.tags,
|
||||||
|
hosts.hostid,
|
||||||
|
hosts.host, hosts.email, hosts.local_image,
|
||||||
|
miniseries.name AS series, miniseries.id AS seriesid
|
||||||
|
FROM eps
|
||||||
|
INNER JOIN hosts ON eps.hostid = hosts.hostid
|
||||||
|
INNER JOIN miniseries ON eps.series = miniseries.id
|
||||||
|
WHERE eps.date < date(\'now\', \'+1 days\')
|
||||||
|
ORDER BY eps.id + 0 DESC
|
||||||
|
LIMIT 30 OFFSET 10
|
||||||
|
'
|
||||||
|
%-->
|
||||||
|
|
15
templates/queries-series-mysql.tpl.html
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
<!--% query_episodes = 'SELECT miniseries.id, miniseries.name, miniseries.description,
|
||||||
|
miniseries.private, miniseries.image, miniseries.valid,
|
||||||
|
ep.number_of_episodes, ep.latest_show, ep.earliest_show
|
||||||
|
FROM miniseries
|
||||||
|
INNER JOIN
|
||||||
|
(SELECT series,
|
||||||
|
COUNT(eps.id) AS number_of_episodes,
|
||||||
|
MAX(eps.date) AS latest_show,
|
||||||
|
MIN(eps.date) AS earliest_show
|
||||||
|
FROM eps
|
||||||
|
WHERE eps.date < DATE_ADD(NOW(), INTERVAL 1 DAY)
|
||||||
|
GROUP BY series) AS ep ON ep.series = miniseries.id
|
||||||
|
ORDER BY name'
|
||||||
|
%-->
|
||||||
|
|
15
templates/queries-series-sqlite.tpl.html
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
<!--% query_episodes = 'SELECT miniseries.id, miniseries.name, miniseries.description,
|
||||||
|
miniseries.private, miniseries.image, miniseries.valid,
|
||||||
|
ep.number_of_episodes, ep.latest_show, ep.earliest_show
|
||||||
|
FROM miniseries
|
||||||
|
INNER JOIN
|
||||||
|
(SELECT series,
|
||||||
|
COUNT(eps.id) AS number_of_episodes,
|
||||||
|
MAX(eps.date) AS latest_show,
|
||||||
|
MIN(eps.date) AS earliest_show
|
||||||
|
FROM eps
|
||||||
|
WHERE eps.date < date(\'now\', \'+1 days\')
|
||||||
|
GROUP BY series) AS ep ON ep.series = miniseries.id
|
||||||
|
ORDER BY name'
|
||||||
|
%-->
|
||||||
|
|
29
templates/queries-series_episodes-mysql.tpl.html
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
<!--% query_series_sql = 'SELECT miniseries.id, miniseries.name,
|
||||||
|
miniseries.description,
|
||||||
|
miniseries.private, miniseries.image, miniseries.valid,
|
||||||
|
ep.number_of_episodes, ep.latest_show, ep.earliest_show
|
||||||
|
FROM miniseries
|
||||||
|
INNER JOIN
|
||||||
|
(SELECT series,
|
||||||
|
COUNT(eps.id) AS number_of_episodes,
|
||||||
|
MAX(eps.date) AS latest_show,
|
||||||
|
MIN(eps.date) AS earliest_show
|
||||||
|
FROM eps
|
||||||
|
WHERE eps.date < DATE_ADD(NOW(), INTERVAL 1 DAY)
|
||||||
|
GROUP BY series) AS ep ON ep.series = miniseries.id
|
||||||
|
WHERE miniseries.id = ?
|
||||||
|
ORDER BY name'
|
||||||
|
%-->
|
||||||
|
<!--% query_shows_sql = 'SELECT
|
||||||
|
id, date, title,
|
||||||
|
duration, summary, notes,
|
||||||
|
explicit, eps.license, tags,
|
||||||
|
hosts.host, hosts.hostid
|
||||||
|
FROM eps
|
||||||
|
INNER JOIN hosts
|
||||||
|
ON eps.hostid = hosts.hostid
|
||||||
|
WHERE series = ? AND eps.date < DATE_ADD(NOW(), INTERVAL 1 DAY)
|
||||||
|
ORDER BY eps.id DESC
|
||||||
|
'
|
||||||
|
%-->
|
||||||
|
|
28
templates/queries-series_episodes-sqlite.tpl.html
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
<!--% query_series_sql = 'SELECT miniseries.id, miniseries.name,
|
||||||
|
miniseries.description,
|
||||||
|
miniseries.private, miniseries.image, miniseries.valid,
|
||||||
|
ep.number_of_episodes, ep.latest_show, ep.earliest_show
|
||||||
|
FROM miniseries
|
||||||
|
INNER JOIN
|
||||||
|
(SELECT series,
|
||||||
|
COUNT(eps.id) AS number_of_episodes,
|
||||||
|
MAX(eps.date) AS latest_show,
|
||||||
|
MIN(eps.date) AS earliest_show
|
||||||
|
FROM eps
|
||||||
|
WHERE eps.date < date(\'now\', \'+1 days\')
|
||||||
|
GROUP BY series) AS ep ON ep.series = miniseries.id
|
||||||
|
WHERE miniseries.id = ?
|
||||||
|
ORDER BY name'
|
||||||
|
%-->
|
||||||
|
<!--% query_shows_sql = 'SELECT
|
||||||
|
id, date, title,
|
||||||
|
duration, summary, notes,
|
||||||
|
explicit, eps.license, tags,
|
||||||
|
hosts.host, hosts.hostid
|
||||||
|
FROM eps
|
||||||
|
INNER JOIN hosts
|
||||||
|
ON eps.hostid = hosts.hostid
|
||||||
|
WHERE series = ? AND eps.date < date(\'now\', \'+1 days\')
|
||||||
|
ORDER BY eps.id DESC
|
||||||
|
'
|
||||||
|
%-->
|
59
templates/rss-comments.tpl.xml
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" >
|
||||||
|
<!--% PROCESS 'shared-utils.tpl.html' %-->
|
||||||
|
<!--% PROCESS 'shared-episode-summary.tpl.html' %-->
|
||||||
|
<!--% USE date %-->
|
||||||
|
<channel>
|
||||||
|
<title>Hacker Public Radio ~ Comment Feed</title>
|
||||||
|
<link><!--% baseurl %-->about.html</link>
|
||||||
|
<description>Comments Feed: Hacker Public Radio is an podcast that releases shows every weekday Monday through Friday. Our shows are produced by the community (you) and can be on any topic that are of interest to hackers and hobbyists.</description>
|
||||||
|
<language>en-us</language>
|
||||||
|
<copyright>Creative Commons Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) License</copyright>
|
||||||
|
<managingEditor>feedback.nospam@nospam.hackerpublicradio.org (HPR Feedback)</managingEditor>
|
||||||
|
<webMaster>admin.nospam@nospam.hackerpublicradio.org (HPR Webmaster)</webMaster>
|
||||||
|
<generator>hpr_generator</generator>
|
||||||
|
<docs>http://www.rssboard.org/rss-specification</docs>
|
||||||
|
<ttl>600</ttl>
|
||||||
|
<image>
|
||||||
|
<url><!--% baseurl %-->images/hpr_feed_small.png</url>
|
||||||
|
<title>Hacker Public Radio ~ Comment Feed</title>
|
||||||
|
<link><!--% baseurl %-->about.html</link>
|
||||||
|
<description>The Hacker Public Radio Old Microphone Logo</description>
|
||||||
|
<height>164</height>
|
||||||
|
<width>144</width>
|
||||||
|
</image>
|
||||||
|
<atom:link href="<!--% baseurl %-->comments.rss" rel="self" type="application/rss+xml" />
|
||||||
|
<pubDate><!--% format_feed_date(date.now) %--></pubDate>
|
||||||
|
<!--% USE DBI(constants.driver, constants.user, constants.password) %-->
|
||||||
|
<!--% FOREACH item IN DBI.query('
|
||||||
|
SELECT C.*,
|
||||||
|
H.host, H.hostid AS host_id,
|
||||||
|
E.title AS episode_title,
|
||||||
|
E.date AS episode_date,
|
||||||
|
E.duration AS episode_duration,
|
||||||
|
M.id AS series_id, M.name AS series_name
|
||||||
|
FROM comments AS C
|
||||||
|
INNER JOIN eps AS E
|
||||||
|
ON C.eps_id = E.id
|
||||||
|
INNER JOIN hosts AS H
|
||||||
|
ON E.hostid = H.hostid
|
||||||
|
INNER JOIN miniseries AS M
|
||||||
|
ON E.series = M.id
|
||||||
|
ORDER BY C.comment_timestamp DESC
|
||||||
|
LIMIT 30
|
||||||
|
')
|
||||||
|
%-->
|
||||||
|
|
||||||
|
<item>
|
||||||
|
<title><!--% item.comment_author_name %--> says: <!--% item.comment_title %--></title>
|
||||||
|
<author>feedback.nospam@nospam.hackerpublicradio.org (<!--% item.comment_author_name %-->)</author>
|
||||||
|
<link><!--% baseurl %-->eps/hpr<!--% zero_pad_left(item.eps_id) %-->/index.html#comments</link>
|
||||||
|
<description><![CDATA[<strong>RE: hpr<!--% zero_pad_left(item.eps_id) %-->::<!--% item.episode_date %--> <em><!--% item.episode_title %--></em> by <a href="<!--% baseurl %-->correspondents/<!--% zero_pad_left(item.host_id) %-->.html"><!--% item.host %--></a></strong><!--% rss_show_series(item.series_name, item.series_id) %--><br />
|
||||||
|
<!--% display_episode_duration(item.episode_duration) %--><!--% display_listen_in(item.eps_id) %--><br /><!--% item.comment_text %-->
|
||||||
|
]]></description>
|
||||||
|
<pubDate><!--% format_feed_date(item.comment_timestamp) %--></pubDate>
|
||||||
|
<guid isPermaLink="false"><!--% baseurl %-->eps/hpr<!--% zero_pad_left(item.eps_id) %-->/index.html#comment_<!--% item.id %--></guid>
|
||||||
|
</item>
|
||||||
|
<!--% END %-->
|
||||||
|
</channel>
|
||||||
|
</rss>
|
@@ -1,5 +1,5 @@
|
|||||||
<!--% PROCESS 'shared-item.tpl.xml' %-->
|
<!--% PROCESS 'shared-item.tpl.xml' %-->
|
||||||
<!--% PROCESS 'rss-query-hpr.tpl.xml' %-->
|
<!--% PROCESS "rss-query-hpr-${constants.database}.tpl.xml" %-->
|
||||||
<!--% FOREACH episode IN feed_result %-->
|
<!--% FOREACH episode IN feed_result %-->
|
||||||
<!--% display_item(episode, media_file_extension, audio_mime_type) %-->
|
<!--% display_item(episode, media_file_extension, audio_mime_type) %-->
|
||||||
<!--% END %-->
|
<!--% END %-->
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
<!--% PROCESS 'shared-item.tpl.xml' %-->
|
<!--% PROCESS 'shared-item.tpl.xml' %-->
|
||||||
<!--% PROCESS 'rss-query-hpr_total.tpl.xml' %-->
|
<!--% PROCESS "rss-query-hpr_total-${constants.database}.tpl.xml" %-->
|
||||||
<!--% FOREACH episode IN feed_result %-->
|
<!--% FOREACH episode IN feed_result %-->
|
||||||
<!--% display_item(episode, media_file_extension, audio_mime_type) %-->
|
<!--% display_item(episode, media_file_extension, audio_mime_type) %-->
|
||||||
<!--% END %-->
|
<!--% END %-->
|
||||||
|
23
templates/rss-query-hpr-mysql.tpl.xml
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
<!--% USE DBI(constants.driver, constants.user, constants.password) %-->
|
||||||
|
<!--% query_hpr_feed = DBI.prepare('
|
||||||
|
SELECT
|
||||||
|
eps.id,
|
||||||
|
eps.explicit,
|
||||||
|
DATE_FORMAT(eps.date, \'%H:%i:%S %d:%m:%Y\') AS \'date\',
|
||||||
|
eps.license, eps.duration,
|
||||||
|
eps.title, eps.summary, eps.tags,
|
||||||
|
eps.notes,
|
||||||
|
hosts.local_image,
|
||||||
|
hosts.hostid,
|
||||||
|
hosts.host, hosts.email,
|
||||||
|
miniseries.name AS series, miniseries.id AS seriesid
|
||||||
|
FROM eps
|
||||||
|
INNER JOIN hosts ON eps.hostid = hosts.hostid
|
||||||
|
INNER JOIN miniseries ON eps.series = miniseries.id
|
||||||
|
WHERE eps.date < DATE_ADD(NOW(), INTERVAL 1 DAY)
|
||||||
|
ORDER BY eps.date DESC
|
||||||
|
LIMIT 10
|
||||||
|
')
|
||||||
|
%-->
|
||||||
|
<!--% feed_result = query_hpr_feed.execute() %-->
|
||||||
|
|
22
templates/rss-query-hpr_total-mysql.tpl.xml
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
<!--% USE DBI(constants.driver, constants.user, constants.password) %-->
|
||||||
|
<!--% query_hpr_feed = DBI.prepare('
|
||||||
|
SELECT
|
||||||
|
eps.id,
|
||||||
|
eps.explicit,
|
||||||
|
DATE_FORMAT(eps.date, \'%H:%i:%S %d:%m:%Y\') AS \'date\',
|
||||||
|
eps.license, eps.duration,
|
||||||
|
eps.title, eps.summary, eps.tags,
|
||||||
|
eps.notes,
|
||||||
|
hosts.local_image,
|
||||||
|
hosts.hostid,
|
||||||
|
hosts.host, hosts.email,
|
||||||
|
miniseries.name AS series, miniseries.id AS seriesid
|
||||||
|
FROM eps
|
||||||
|
INNER JOIN hosts ON eps.hostid = hosts.hostid
|
||||||
|
INNER JOIN miniseries ON eps.series = miniseries.id
|
||||||
|
WHERE eps.date < DATE_ADD(NOW(), INTERVAL 1 DAY)
|
||||||
|
ORDER BY eps.date DESC
|
||||||
|
')
|
||||||
|
%-->
|
||||||
|
<!--% feed_result = query_hpr_feed.execute() %-->
|
||||||
|
|
@@ -1,5 +1,16 @@
|
|||||||
<!--% MACRO get_avatar(host_id) BLOCK %-->
|
<!--% MACRO lazy_load(is_lazy) BLOCK %-->
|
||||||
|
<!--% IF is_lazy %-->loading="lazy"<!--% END %-->
|
||||||
|
<!--% END %-->
|
||||||
|
<!--% MACRO get_avatar_src(host_id) BLOCK %-->
|
||||||
<!--% TRY %-->
|
<!--% TRY %-->
|
||||||
<!--% USE File ("./public_html/images/hosts/${host_id}.png") %-->hosts/<!--% File.name %-->
|
<!--% USE File ("./public_html/images/hosts/${host_id}.png") %-->hosts/<!--% File.name %-->
|
||||||
<!--% CATCH File %-->hpr_logo.png<!--% END %-->
|
<!--% CATCH File %-->hpr_logo.png<!--% END %-->
|
||||||
<!--% END %-->
|
<!--% END %-->
|
||||||
|
<!--% MACRO get_avatar(host_id, host_name, is_lazy_loaded) BLOCK %-->
|
||||||
|
<img src="<!--% absolute_path(baseurl) %-->images/<!--% get_avatar_src(host_id) %-->" height="80" width="80" alt="Thumbnail of <!--% host_name | html %-->" <!--% lazy_load(is_lazy_loaded) %--> />
|
||||||
|
<!--% END %-->
|
||||||
|
<!--% MACRO show_avatar(host_id, host_name, is_lazy_loaded) BLOCK %-->
|
||||||
|
<!--% IF get_avatar_src(host_id) != 'hpr_logo.png' %-->
|
||||||
|
<a href="<!--% absolute_path(baseurl) %-->correspondents/<!--% zero_pad_left(host_id) %-->.html"><!--% get_avatar(host_id, host_name, is_lazy_loaded) %--></a><br>
|
||||||
|
<!--% END %-->
|
||||||
|
<!--% END %-->
|
||||||
|
18
templates/shared-call_for_shows.tpl.html
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
<!--% PROCESS 'shared-utils.tpl.html' %-->
|
||||||
|
<!--% PROCESS "queries-call_for_shows-${constants.database}.tpl.html" %-->
|
||||||
|
<!--% MACRO display_call_for_shows BLOCK %-->
|
||||||
|
<!--% result_call_for_shows = DBI.prepare(query_call_for_shows)
|
||||||
|
%-->
|
||||||
|
<!--% results_call_for_shows = result_call_for_shows.execute().get_all() %-->
|
||||||
|
<!--% IF results_call_for_shows.0.request_for_shows == 1 %-->
|
||||||
|
<!--% USE date %-->
|
||||||
|
<article>
|
||||||
|
<header>
|
||||||
|
<h3>Call for shows</h3>
|
||||||
|
</header>
|
||||||
|
<p><strong><em>We are running very low on shows</em></strong> at the moment. Have a look at the <a href="<!--% absolute_path(baseurl) %-->correspondents/index.html">hosts</a> page and if you don't see "<!--% date.format(date.now, '%Y') %-->-??-??" next to your name, or if your name is not listed, you might consider sending us in something.</p>
|
||||||
|
<!-- <img src="/images/hprstats.png" alt="hpr queue showing an graph showing how few shows we have" /> -->
|
||||||
|
<p>There are no files to process on the FTP server.</p>
|
||||||
|
</article>
|
||||||
|
<!--% END %-->
|
||||||
|
<!--% END %-->
|
@@ -1,5 +1,9 @@
|
|||||||
<!--% PROCESS 'shared-utils.tpl.html' %-->
|
<!--% PROCESS 'shared-utils.tpl.html' %-->
|
||||||
|
|
||||||
|
<!--% MACRO rss_show_series(series, series_id) IF series != "general" %-->
|
||||||
|
from the series <em><a href="<!--% baseurl %-->series/<!--% zero_pad_left(series_id) %-->.html"><!--% series %--></em></a>.
|
||||||
|
<!--% END %-->
|
||||||
|
|
||||||
<!--% MACRO show_series(series, series_id, label) IF series != "" %-->
|
<!--% MACRO show_series(series, series_id, label) IF series != "" %-->
|
||||||
<!--% IF label == "" %-->
|
<!--% IF label == "" %-->
|
||||||
<!--% label = "Series" %-->
|
<!--% label = "Series" %-->
|
||||||
@@ -11,8 +15,15 @@
|
|||||||
<span><label>Tags:</label> <em><!--% tags %--></em>.</span>
|
<span><label>Tags:</label> <em><!--% tags %--></em>.</span>
|
||||||
<!--% END %-->
|
<!--% END %-->
|
||||||
|
|
||||||
<!--% MACRO display_listen_in(eps_id) BLOCK %-->
|
<!--% MACRO display_listen_in(eps_id, episode_type) BLOCK %-->
|
||||||
Listen in <a href="<!--% media_baseurl(baseurl, media_hostname) %-->local/hpr<!--% eps_id %-->.ogg">ogg</a>, <a href="<!--% media_baseurl(baseurl, media_hostname) %-->local/hpr<!--% eps_id %-->.spx">spx</a>, or <a href="<!--% media_baseurl(baseurl, media_hostname) %-->local/hpr<!--% eps_id %-->.mp3">mp3</a> format.
|
<!--% IF episode_type == "" %--><!--% episode_type = 'hpr' %--><!--% END %-->
|
||||||
|
Listen in
|
||||||
|
<!--% IF episode_type == 'hpr' %-->
|
||||||
|
<a href="<!--% media_path(eps_id, episode_type, 'ogg', baseurl, media_baseurl) %-->">ogg</a>,
|
||||||
|
<a href="<!--% media_path(eps_id, episode_type, 'spx', baseurl, media_baseurl) %-->">spx</a>,
|
||||||
|
or
|
||||||
|
<!--% END %-->
|
||||||
|
<a href="<!--% media_path(eps_id, episode_type, 'mp3', baseurl, media_baseurl) %-->">mp3</a> format.
|
||||||
<!--% END %-->
|
<!--% END %-->
|
||||||
|
|
||||||
<!--% MACRO display_comments_tally(eps_id, tally) BLOCK %-->
|
<!--% MACRO display_comments_tally(eps_id, tally) BLOCK %-->
|
||||||
|
@@ -1,19 +1,16 @@
|
|||||||
<!--% MACRO listen_now(episode, episode_type, baseurl, media_hostname) BLOCK %-->
|
<!--% MACRO listen_now(episode, episode_type, baseurl, media_baseurl) BLOCK %-->
|
||||||
<!--% IF episode_type == "twat" %-->
|
|
||||||
<!--% media_folder = "eps" %--><!--% ELSE %--><!--% media_folder = "local" %-->
|
|
||||||
<!--% END %-->
|
|
||||||
<h2>Listen Now</h2>
|
<h2>Listen Now</h2>
|
||||||
<p>Duration: <!--% display_episode_duration(episode.duration) %--></p>
|
<p>Duration: <!--% display_episode_duration(episode.duration) %--></p>
|
||||||
<audio controls preload="none">
|
<audio controls preload="none">
|
||||||
<source src="<!--% media_baseurl(baseurl, media_hostname) %--><!--% media_folder %-->/<!--% episode_type %--><!--% episode.id %-->.ogg" type="audio/ogg" >
|
<source src="<!--% media_path(episode.id, episode_type, 'ogg', baseurl, media_baseurl) %-->" type="audio/ogg" >
|
||||||
<source src="<!--% media_baseurl(baseurl, media_hostname) %--><!--% media_folder %-->/<!--% episode_type %--><!--% episode.id %-->.mp3" type="audio/mpeg" >
|
<source src="<!--% media_path(episode.id, episode_type, 'mp3', baseurl, media_baseurl) %-->" type="audio/mpeg" >
|
||||||
</audio>
|
</audio>
|
||||||
<ul>
|
<ul>
|
||||||
<!--% IF episode_type != "twat" %-->
|
<!--% IF episode_type != "twat" %-->
|
||||||
<li>ogg: <a href="<!--% media_baseurl(baseurl, media_hostname) %--><!--% media_folder %-->/<!--% episode_type %--><!--% episode.id %-->.ogg"><!--% media_baseurl(baseurl, media_hostname) %--><!--% media_folder %-->/<!--% episode_type %--><!--% episode.id %-->.ogg</a></li>
|
<li>ogg: <a href="<!--% media_path(episode.id, episode_type, 'ogg', baseurl, media_baseurl) %-->"><!--% media_path(episode.id, episode_type, 'ogg', baseurl, media_baseurl) %--></a></li>
|
||||||
<li>spx: <a href="<!--% media_baseurl(baseurl, media_hostname) %--><!--% media_folder %-->/<!--% episode_type %--><!--% episode.id %-->.spx"><!--% media_baseurl(baseurl, media_hostname) %--><!--% media_folder %-->/<!--% episode_type %--><!--% episode.id %-->.spx</a></li>
|
<li>spx: <a href="<!--% media_path(episode.id, episode_type, 'spx', baseurl, media_baseurl) %-->"><!--% media_path(episode.id, episode_type, 'spx', baseurl, media_baseurl) %--></a></li>
|
||||||
<!--% END %-->
|
<!--% END %-->
|
||||||
<li>mp3: <a href="<!--% media_baseurl(baseurl, media_hostname) %--><!--% media_folder %-->/<!--% episode_type %--><!--% episode.id %-->.mp3"><!--% media_baseurl(baseurl, media_hostname) %--><!--% media_folder %-->/<!--% episode_type %--><!--% episode.id %-->.mp3</a></li>
|
<li>mp3: <a href="<!--% media_path(episode.id, episode_type, 'mp3', baseurl, media_baseurl) %-->"><!--% media_path(episode.id, episode_type, 'mp3', baseurl, media_baseurl) %--></a></li>
|
||||||
</ul>
|
</ul>
|
||||||
<!--% END %-->
|
<!--% END %-->
|
||||||
|
|
||||||
|
12
templates/shared-show-transcript.tpl.html
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
<!--% MACRO show_transcript(episode, episode_type, baseurl, media_baseurl) BLOCK %-->
|
||||||
|
<h2>Show Transcript</h2>
|
||||||
|
<p>Automatically generated using <a href="https://github.com/openai/whisper">whisper</a>
|
||||||
|
<pre><code>whisper --model tiny --language en hpr<!--% zero_pad_left(episode.id) %-->.wav</code></pre></p>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<li>Text: <a href="<!--% media_path(episode.id, episode_type, 'txt', baseurl, media_baseurl) %-->">hpr<!--% zero_pad_left(episode.id) %-->.txt</a></li>
|
||||||
|
<li><a href="https://en.wikipedia.org/wiki/WebVTT">WebVTT</a>: <a href="<!--% media_path(episode.id, episode_type, 'vtt', baseurl, media_baseurl) %-->">hpr<!--% zero_pad_left(episode.id) %-->.vtt</a></li>
|
||||||
|
<li><a href="https://en.wikipedia.org/wiki/SubRip">SubRip</a>: <a href="<!--% media_path(episode.id, episode_type, 'srt', baseurl, media_baseurl) %-->">hpr<!--% zero_pad_left(episode.id) %-->.srt</a></li>
|
||||||
|
</ul>
|
||||||
|
<!--% END %-->
|
||||||
|
|
@@ -1,6 +1,11 @@
|
|||||||
<!--% MACRO zero_pad_left(word) BLOCK %-->
|
<!--% MACRO zero_pad_left(word, pad_length) BLOCK %-->
|
||||||
<!--% USE String(word) %-->
|
<!--% IF pad_length %-->
|
||||||
<!--% String.format("%04s") %-->
|
<!--% zero_pad_format = "%0${pad_length}s" %-->
|
||||||
|
<!--% ELSE %-->
|
||||||
|
<!--% zero_pad_format = "%04s" %-->
|
||||||
|
<!--% END %-->
|
||||||
|
<!--% USE String(word) %-->
|
||||||
|
<!--% String.format(zero_pad_format) %-->
|
||||||
<!--% END %-->
|
<!--% END %-->
|
||||||
|
|
||||||
<!--% MACRO display_choice(choice, display_when_true, display_when_false) BLOCK %-->
|
<!--% MACRO display_choice(choice, display_when_true, display_when_false) BLOCK %-->
|
||||||
@@ -31,7 +36,7 @@
|
|||||||
<!--% END %-->
|
<!--% END %-->
|
||||||
|
|
||||||
<!--% MACRO format_feed_date(date_to_format) BLOCK %-->
|
<!--% MACRO format_feed_date(date_to_format) BLOCK %-->
|
||||||
<!--% USE feed_date = date(format = '%a, %e %b %Y 00:00:00 +0000', gmt=1) %-->
|
<!--% USE feed_date = date(format = '%a, %d %b %Y %H:%M:%S +0000', gmt=1) %-->
|
||||||
<!--% feed_date.format(date_to_format) %-->
|
<!--% feed_date.format(date_to_format) %-->
|
||||||
<!--% END %-->
|
<!--% END %-->
|
||||||
|
|
||||||
@@ -39,15 +44,36 @@
|
|||||||
<!--% IF baseurl %-->./<!--% ELSE %-->/<!--% END %-->
|
<!--% IF baseurl %-->./<!--% ELSE %-->/<!--% END %-->
|
||||||
<!--% END %-->
|
<!--% END %-->
|
||||||
|
|
||||||
<!--% MACRO media_baseurl(baseurl, media_hostname) BLOCK %-->
|
<!--% MACRO media_basepath(baseurl, media_baseurl) BLOCK %-->
|
||||||
<!--% IF media_hostname %-->
|
<!--% IF media_baseurl %-->
|
||||||
https://<!--% media_hostname %-->/<!--% ELSE %-->
|
<!--% media_baseurl %--><!--% ELSE %-->
|
||||||
<!--% baseurl %--><!--% END %-->
|
<!--% IF baseurl %--><!--% baseurl %--><!--% ELSE %-->/<!--% END %-->
|
||||||
|
<!--% END %-->
|
||||||
|
<!--% END %-->
|
||||||
|
|
||||||
|
<!--% MACRO media_path(episode_id, episode_type, media_type, baseurl, media_baseurl) BLOCK %-->
|
||||||
|
<!--% IF episode_type == "twat" %-->
|
||||||
|
<!--% padding = 3 %-->
|
||||||
|
<!--% media_folder = "eps/"; padding = 3 %-->
|
||||||
|
<!--% ELSE %-->
|
||||||
|
<!--% media_folder = "local/" %-->
|
||||||
|
<!--% END %-->
|
||||||
|
<!--% IF media_baseurl %-->
|
||||||
|
<!--% transcription_types = "txt srt vtt" %-->
|
||||||
|
<!--% USE String(transcription_types) %-->
|
||||||
|
<!--% USE String(media_baseurl) %-->
|
||||||
|
<!--% IF transcription_types.search(media_type) && media_baseurl.search('archive.org') %-->
|
||||||
|
<!--% media_baseurl = "${media_baseurl}hpr\$eps_id/" %-->
|
||||||
|
<!--% END %-->
|
||||||
|
<!--% media_folder = "" %-->
|
||||||
|
<!--% media_baseurl = media_baseurl.replace('\$eps_id', zero_pad_left(episode_id)) %-->
|
||||||
|
<!--% END %-->
|
||||||
|
<!--% media_basepath(baseurl, media_baseurl) %--><!--% media_folder %--><!--% episode_type %--><!--% zero_pad_left(episode_id, padding) %-->.<!--% media_type %-->
|
||||||
<!--% END %-->
|
<!--% END %-->
|
||||||
|
|
||||||
<!--% MACRO step_navigation(baseurl, links, folder) BLOCK %-->
|
<!--% MACRO step_navigation(baseurl, links, folder) BLOCK %-->
|
||||||
<!--% IF folder == "" %-->
|
<!--% IF folder %-->
|
||||||
<!--% folder = hpr %-->
|
<!--% folder = folder %--><!--% ELSE %--><!--% folder = "hpr" %-->
|
||||||
<!--% END %-->
|
<!--% END %-->
|
||||||
<small><a href="<!--% absolute_path(baseurl) %-->eps/<!--% folder %--><!--% zero_pad_left(links.earliest) %-->/index.html" rel="first"><< First</a>,
|
<small><a href="<!--% absolute_path(baseurl) %-->eps/<!--% folder %--><!--% zero_pad_left(links.earliest) %-->/index.html" rel="first"><< First</a>,
|
||||||
<!--% IF links.previous %-->
|
<!--% IF links.previous %-->
|
||||||
|
184
utils/lib_utils.sh
Normal file
@@ -0,0 +1,184 @@
|
|||||||
|
#!/bin/bash -
|
||||||
|
#===============================================================================
|
||||||
|
#
|
||||||
|
# FILE: lib_utils.sh
|
||||||
|
#
|
||||||
|
# USAGE: ./lib_utils.sh
|
||||||
|
#
|
||||||
|
# DESCRIPTION: functions for scripts used to update local HPR installations
|
||||||
|
# using the HPR static site generator
|
||||||
|
#
|
||||||
|
# OPTIONS: ---
|
||||||
|
# REQUIREMENTS: mysql2sqlite (https://github.com/dumblob/mysql2sqlite)
|
||||||
|
# BUGS: ---
|
||||||
|
# NOTES: ---
|
||||||
|
# AUTHOR: Roan "Rho`n" Horning <roan.horning@gmail.com>
|
||||||
|
# CREATED: 02/26/2023 03:27:08 PM -5 UTC
|
||||||
|
# REVISION: ---
|
||||||
|
# LICENSE: GNU AGPLv3
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Affero General Public License
|
||||||
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
#
|
||||||
|
#===============================================================================
|
||||||
|
|
||||||
|
set -o nounset # Treat unset variables as an error
|
||||||
|
|
||||||
|
#--- FUNCTION ----------------------------------------------------------------
|
||||||
|
# NAME: make_working_dir
|
||||||
|
# DESCRIPTION: Creates a local temporary working directory
|
||||||
|
# SEE: https://stackoverflow.com/questions/4632028/how-to-create-a-temporary-directory#answer-34676160
|
||||||
|
# PARAMETERS:
|
||||||
|
# RETURNS: The path to the working directory
|
||||||
|
#-------------------------------------------------------------------------------
|
||||||
|
function make_working_dir {
|
||||||
|
|
||||||
|
# the directory of the script
|
||||||
|
local DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||||
|
|
||||||
|
# the temp directory used, within $DIR
|
||||||
|
# omit the -p parameter to create a temporal directory in
|
||||||
|
# the default location
|
||||||
|
|
||||||
|
local WORK_DIR=`mktemp -d -p "$DIR"`
|
||||||
|
|
||||||
|
# check if tmp dir was created
|
||||||
|
if [[ ! "$WORK_DIR" || ! -d "$WORK_DIR" ]]; then
|
||||||
|
echo "Could not create temp dir"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo $WORK_DIR
|
||||||
|
}
|
||||||
|
|
||||||
|
#--- FUNCTION ----------------------------------------------------------------
|
||||||
|
# NAME: clean_working_dir
|
||||||
|
# DESCRIPTION: Remove local temporary working directory
|
||||||
|
# PARAMETERS: WORK_DIR -- Temporay directory to be delted
|
||||||
|
# RETURNS:
|
||||||
|
#-------------------------------------------------------------------------------
|
||||||
|
function clean_working_dir {
|
||||||
|
|
||||||
|
if [[ -d $1 ]] && expr $1 : '.*/tmp.*' ; then
|
||||||
|
rm -rf $1
|
||||||
|
echo "Deleted temp working directory $1"
|
||||||
|
else
|
||||||
|
echo "Did not delete directory: $1"
|
||||||
|
echo "Not a temporary directory."
|
||||||
|
fi
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#--- FUNCTION ----------------------------------------------------------------
|
||||||
|
# NAME: download_hpr_sql
|
||||||
|
# DESCRIPTION: Download the HPR SQL dump file into a working directory
|
||||||
|
# PARAMETERS:
|
||||||
|
# RETURNS:
|
||||||
|
#-------------------------------------------------------------------------------
|
||||||
|
function download_hpr_sql {
|
||||||
|
|
||||||
|
if [[ ! -d $1 ]] || ! expr $1 : '.*/tmp.*' ;
|
||||||
|
then
|
||||||
|
echo "Please provide the temporary directory when calling this function"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
local CURL=`which curl`
|
||||||
|
local WGET=`which wget`
|
||||||
|
local HPR_URL=https://www.hackerpublicradio.org/hpr.sql
|
||||||
|
|
||||||
|
if [ -f $1/hpr.sql ];
|
||||||
|
then
|
||||||
|
echo "Removing temporary hpr.sql"
|
||||||
|
rm $1/hpr.sql
|
||||||
|
else
|
||||||
|
echo "No temporary hpr.sql to remove"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$CURL" != "" ];
|
||||||
|
then
|
||||||
|
curl $HPR_URL --output $1/hpr.sql
|
||||||
|
echo "Downloaded hpr.sql via curl"
|
||||||
|
elif [ "$WGET" != "" ];
|
||||||
|
then
|
||||||
|
wget --directory-prefix=$1 $HPR_URL
|
||||||
|
echo "Downloaded hpr.sql via wget"
|
||||||
|
else
|
||||||
|
echo "Could not download file. Please install either curl or wget."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
#--- FUNCTION ----------------------------------------------------------------
|
||||||
|
# NAME: make_hpr_sqlite_db
|
||||||
|
# DESCRIPTION: Converts the hpr sql file into an sqlite db file
|
||||||
|
# PARAMETERS:
|
||||||
|
# RETURNS:
|
||||||
|
#-------------------------------------------------------------------------------
|
||||||
|
function make_hpr_sqlite_db {
|
||||||
|
|
||||||
|
if [[ ! -d $1 ]] || ! expr $1 : '.*/tmp.*' ;
|
||||||
|
then
|
||||||
|
echo "Please provide the temporary directory when calling this function"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
local MYSQL2SQLITE=`which mysql2sqlite`
|
||||||
|
local BIN_PATH=""
|
||||||
|
|
||||||
|
if [ "$MYSQL2SQLITE" = "" ];
|
||||||
|
then
|
||||||
|
if [ $# -gt 1 ] && [ -z "$2" ];
|
||||||
|
then
|
||||||
|
BIN_PATH=$2
|
||||||
|
else
|
||||||
|
BIN_PATH=`find . -type f -name "mysql2sqlite" -print | head -1`
|
||||||
|
if [ "$BIN_PATH" != "" ];
|
||||||
|
then
|
||||||
|
BIN_PATH=${BIN_PATH/mysql2sqlite//}
|
||||||
|
else
|
||||||
|
echo "Could not find mysql2sqlite script."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
echo $BIN_PATH
|
||||||
|
|
||||||
|
if [ -f $1/hpr.db ];
|
||||||
|
then
|
||||||
|
rm $1/hpr.db
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Remove lines from hpr.sql that mysql2sqlite can't handle
|
||||||
|
sed '/^DELIMITER ;;/,/^DELIMITER ;/d' < $1/hpr.sql > $1/hpr-sqlite.sql
|
||||||
|
|
||||||
|
${BIN_PATH}mysql2sqlite $1/hpr-sqlite.sql | sqlite3 $1/hpr.db
|
||||||
|
echo "Created hpr.db"
|
||||||
|
}
|
||||||
|
|
||||||
|
#--- FUNCTION ----------------------------------------------------------------
|
||||||
|
# NAME: copy_to_public_dir
|
||||||
|
# DESCRIPTION: Move HPR sql and db files to public website folder
|
||||||
|
# PARAMETERS:
|
||||||
|
# RETURNS:
|
||||||
|
#-------------------------------------------------------------------------------
|
||||||
|
function copy_to_public_dir {
|
||||||
|
|
||||||
|
if [ $# -gt 1 ] && [ ! -z "$1" ] && [ ! -z "$2" ];
|
||||||
|
then
|
||||||
|
cp $1/hpr.sql $2/hpr.sql
|
||||||
|
cp $1/hpr.db $2/hpr.db
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
echo "Bad arguments. Can't copy files to public directory."
|
||||||
|
fi
|
||||||
|
}
|
289
utils/mysql2sqlite
Executable file
@@ -0,0 +1,289 @@
|
|||||||
|
#!/usr/bin/awk -f
|
||||||
|
|
||||||
|
# Authors: @esperlu, @artemyk, @gkuenning, @dumblob
|
||||||
|
|
||||||
|
# FIXME detect empty input file and issue a warning
|
||||||
|
|
||||||
|
function printerr( s ){ print s | "cat >&2" }
|
||||||
|
|
||||||
|
BEGIN {
|
||||||
|
if( ARGC != 2 ){
|
||||||
|
printerr( \
|
||||||
|
"USAGE:\n"\
|
||||||
|
" mysql2sqlite dump_mysql.sql > dump_sqlite3.sql\n" \
|
||||||
|
" OR\n" \
|
||||||
|
" mysql2sqlite dump_mysql.sql | sqlite3 sqlite.db\n" \
|
||||||
|
"\n" \
|
||||||
|
"NOTES:\n" \
|
||||||
|
" Dash in filename is not supported, because dash (-) means stdin." )
|
||||||
|
no_END = 1
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Find INT_MAX supported by both this AWK (usually an ISO C signed int)
|
||||||
|
# and SQlite.
|
||||||
|
# On non-8bit-based architectures, the additional bits are safely ignored.
|
||||||
|
|
||||||
|
# 8bit (lower precision should not exist)
|
||||||
|
s="127"
|
||||||
|
# "63" + 0 avoids potential parser misbehavior
|
||||||
|
if( (s + 0) "" == s ){ INT_MAX_HALF = "63" + 0 }
|
||||||
|
# 16bit
|
||||||
|
s="32767"
|
||||||
|
if( (s + 0) "" == s ){ INT_MAX_HALF = "16383" + 0 }
|
||||||
|
# 32bit
|
||||||
|
s="2147483647"
|
||||||
|
if( (s + 0) "" == s ){ INT_MAX_HALF = "1073741823" + 0 }
|
||||||
|
# 64bit (as INTEGER in SQlite3)
|
||||||
|
s="9223372036854775807"
|
||||||
|
if( (s + 0) "" == s ){ INT_MAX_HALF = "4611686018427387904" + 0 }
|
||||||
|
# # 128bit
|
||||||
|
# s="170141183460469231731687303715884105728"
|
||||||
|
# if( (s + 0) "" == s ){ INT_MAX_HALF = "85070591730234615865843651857942052864" + 0 }
|
||||||
|
# # 256bit
|
||||||
|
# s="57896044618658097711785492504343953926634992332820282019728792003956564819968"
|
||||||
|
# if( (s + 0) "" == s ){ INT_MAX_HALF = "28948022309329048855892746252171976963317496166410141009864396001978282409984" + 0 }
|
||||||
|
# # 512bit
|
||||||
|
# s="6703903964971298549787012499102923063739682910296196688861780721860882015036773488400937149083451713845015929093243025426876941405973284973216824503042048"
|
||||||
|
# if( (s + 0) "" == s ){ INT_MAX_HALF = "3351951982485649274893506249551461531869841455148098344430890360930441007518386744200468574541725856922507964546621512713438470702986642486608412251521024" + 0 }
|
||||||
|
# # 1024bit
|
||||||
|
# s="89884656743115795386465259539451236680898848947115328636715040578866337902750481566354238661203768010560056939935696678829394884407208311246423715319737062188883946712432742638151109800623047059726541476042502884419075341171231440736956555270413618581675255342293149119973622969239858152417678164812112068608"
|
||||||
|
# if( (s + 0) "" == s ){ INT_MAX_HALF = "44942328371557897693232629769725618340449424473557664318357520289433168951375240783177119330601884005280028469967848339414697442203604155623211857659868531094441973356216371319075554900311523529863270738021251442209537670585615720368478277635206809290837627671146574559986811484619929076208839082406056034304" + 0 }
|
||||||
|
# # higher precision probably not needed
|
||||||
|
|
||||||
|
FS=",$"
|
||||||
|
print "PRAGMA synchronous = OFF;"
|
||||||
|
print "PRAGMA journal_mode = MEMORY;"
|
||||||
|
print "BEGIN TRANSACTION;"
|
||||||
|
}
|
||||||
|
|
||||||
|
# historically 3 spaces separate non-argument local variables
|
||||||
|
function bit_to_int( str_bit, powtwo, i, res, bit, overflow ){
|
||||||
|
powtwo = 1
|
||||||
|
overflow = 0
|
||||||
|
# 011101 = 1*2^0 + 0*2^1 + 1*2^2 ...
|
||||||
|
for( i = length( str_bit ); i > 0; --i ){
|
||||||
|
bit = substr( str_bit, i, 1 )
|
||||||
|
if( overflow || ( bit == 1 && res > INT_MAX_HALF ) ){
|
||||||
|
printerr( \
|
||||||
|
NR ": WARN Bit field overflow, number truncated (LSBs saved, MSBs ignored)." )
|
||||||
|
break
|
||||||
|
}
|
||||||
|
res = res + bit * powtwo
|
||||||
|
# no warning here as it might be the last iteration
|
||||||
|
if( powtwo > INT_MAX_HALF ){ overflow = 1; continue }
|
||||||
|
powtwo = powtwo * 2
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
# CREATE TRIGGER statements have funny commenting. Remember we are in trigger.
|
||||||
|
/^\/\*.*(CREATE.*TRIGGER|create.*trigger)/ {
|
||||||
|
gsub( /^.*(TRIGGER|trigger)/, "CREATE TRIGGER" )
|
||||||
|
print
|
||||||
|
inTrigger = 1
|
||||||
|
next
|
||||||
|
}
|
||||||
|
# The end of CREATE TRIGGER has a stray comment terminator
|
||||||
|
/(END|end) \*\/;;/ { gsub( /\*\//, "" ); print; inTrigger = 0; next }
|
||||||
|
# The rest of triggers just get passed through
|
||||||
|
inTrigger != 0 { print; next }
|
||||||
|
|
||||||
|
# CREATE VIEW looks like a TABLE in comments
|
||||||
|
/^\/\*.*(CREATE.*TABLE|create.*table)/ {
|
||||||
|
inView = 1
|
||||||
|
next
|
||||||
|
}
|
||||||
|
# end of CREATE VIEW
|
||||||
|
/^(\).*(ENGINE|engine).*\*\/;)/ {
|
||||||
|
inView = 0
|
||||||
|
next
|
||||||
|
}
|
||||||
|
# content of CREATE VIEW
|
||||||
|
inView != 0 { next }
|
||||||
|
|
||||||
|
# skip comments
|
||||||
|
/^\/\*/ { next }
|
||||||
|
|
||||||
|
# skip PARTITION statements
|
||||||
|
/^ *[(]?(PARTITION|partition) +[^ ]+/ { next }
|
||||||
|
|
||||||
|
# print all INSERT lines
|
||||||
|
( /^ *\(/ && /\) *[,;] *$/ ) || /^(INSERT|insert|REPLACE|replace)/ {
|
||||||
|
prev = ""
|
||||||
|
|
||||||
|
# first replace \\ by \_ that mysqldump never generates to deal with
|
||||||
|
# sequnces like \\n that should be translated into \n, not \<LF>.
|
||||||
|
# After we convert all escapes we replace \_ by backslashes.
|
||||||
|
gsub( /\\\\/, "\\_" )
|
||||||
|
|
||||||
|
# single quotes are escaped by another single quote
|
||||||
|
gsub( /\\'/, "''" )
|
||||||
|
gsub( /\\n/, "\n" )
|
||||||
|
gsub( /\\r/, "\r" )
|
||||||
|
gsub( /\\"/, "\"" )
|
||||||
|
gsub( /\\\032/, "\032" ) # substitute char
|
||||||
|
|
||||||
|
gsub( /\\_/, "\\" )
|
||||||
|
|
||||||
|
# sqlite3 is limited to 16 significant digits of precision
|
||||||
|
while( match( $0, /0x[0-9a-fA-F]{17}/ ) ){
|
||||||
|
hexIssue = 1
|
||||||
|
sub( /0x[0-9a-fA-F]+/, substr( $0, RSTART, RLENGTH-1 ), $0 )
|
||||||
|
}
|
||||||
|
if( hexIssue ){
|
||||||
|
printerr( \
|
||||||
|
NR ": WARN Hex number trimmed (length longer than 16 chars)." )
|
||||||
|
hexIssue = 0
|
||||||
|
}
|
||||||
|
print
|
||||||
|
next
|
||||||
|
}
|
||||||
|
|
||||||
|
# CREATE DATABASE is not supported
|
||||||
|
/^(CREATE DATABASE|create database)/ { next }
|
||||||
|
|
||||||
|
# print the CREATE line as is and capture the table name
|
||||||
|
/^(CREATE|create)/ {
|
||||||
|
if( $0 ~ /IF NOT EXISTS|if not exists/ || $0 ~ /TEMPORARY|temporary/ ){
|
||||||
|
caseIssue = 1
|
||||||
|
printerr( \
|
||||||
|
NR ": WARN Potential case sensitivity issues with table/column naming\n" \
|
||||||
|
" (see INFO at the end)." )
|
||||||
|
}
|
||||||
|
if( match( $0, /`[^`]+/ ) ){
|
||||||
|
tableName = substr( $0, RSTART+1, RLENGTH-1 )
|
||||||
|
}
|
||||||
|
aInc = 0
|
||||||
|
prev = ""
|
||||||
|
firstInTable = 1
|
||||||
|
print
|
||||||
|
next
|
||||||
|
}
|
||||||
|
|
||||||
|
# Replace `FULLTEXT KEY` (probably other `XXXXX KEY`)
|
||||||
|
/^ (FULLTEXT KEY|fulltext key)/ { gsub( /[A-Za-z ]+(KEY|key)/, " KEY" ) }
|
||||||
|
|
||||||
|
# Get rid of field lengths in KEY lines
|
||||||
|
/ (PRIMARY |primary )?(KEY|key)/ { gsub( /\([0-9]+\)/, "" ) }
|
||||||
|
|
||||||
|
aInc == 1 && /PRIMARY KEY|primary key/ { next }
|
||||||
|
|
||||||
|
# Replace COLLATE xxx_xxxx_xx statements with COLLATE BINARY
|
||||||
|
/ (COLLATE|collate) [a-z0-9_]*/ { gsub( /(COLLATE|collate) [a-z0-9_]*/, "COLLATE BINARY" ) }
|
||||||
|
|
||||||
|
# Print all fields definition lines except the `KEY` lines.
|
||||||
|
/^ / && !/^( (KEY|key)|\);)/ {
|
||||||
|
if( match( $0, /[^"`]AUTO_INCREMENT|auto_increment[^"`]/) ){
|
||||||
|
aInc = 1
|
||||||
|
gsub( /AUTO_INCREMENT|auto_increment/, "PRIMARY KEY AUTOINCREMENT" )
|
||||||
|
}
|
||||||
|
gsub( /(UNIQUE KEY|unique key) (`.*`|".*") /, "UNIQUE " )
|
||||||
|
gsub( /(CHARACTER SET|character set) [^ ]+[ ,]/, "" )
|
||||||
|
# FIXME
|
||||||
|
# CREATE TRIGGER [UpdateLastTime]
|
||||||
|
# AFTER UPDATE
|
||||||
|
# ON Package
|
||||||
|
# FOR EACH ROW
|
||||||
|
# BEGIN
|
||||||
|
# UPDATE Package SET LastUpdate = CURRENT_TIMESTAMP WHERE ActionId = old.ActionId;
|
||||||
|
# END
|
||||||
|
gsub( /(ON|on) (UPDATE|update) (CURRENT_TIMESTAMP|current_timestamp)(\(\))?/, "" )
|
||||||
|
gsub( /(DEFAULT|default) (CURRENT_TIMESTAMP|current_timestamp)(\(\))?/, "DEFAULT current_timestamp")
|
||||||
|
gsub( /(COLLATE|collate) [^ ]+ /, "" )
|
||||||
|
gsub( /(ENUM|enum)[^)]+\)/, "text " )
|
||||||
|
gsub( /(SET|set)\([^)]+\)/, "text " )
|
||||||
|
gsub( /UNSIGNED|unsigned/, "" )
|
||||||
|
gsub( /_utf8mb3/, "" )
|
||||||
|
gsub( /` [^ ]*(INT|int|BIT|bit)[^ ]*/, "` integer" )
|
||||||
|
gsub( /" [^ ]*(INT|int|BIT|bit)[^ ]*/, "\" integer" )
|
||||||
|
ere_bit_field = "[bB]'[10]+'"
|
||||||
|
if( match($0, ere_bit_field) ){
|
||||||
|
sub( ere_bit_field, bit_to_int( substr( $0, RSTART +2, RLENGTH -2 -1 ) ) )
|
||||||
|
}
|
||||||
|
|
||||||
|
# remove USING BTREE and other suffixes for USING, for example: "UNIQUE KEY
|
||||||
|
# `hostname_domain` (`hostname`,`domain`) USING BTREE,"
|
||||||
|
gsub( / USING [^, ]+/, "" )
|
||||||
|
|
||||||
|
# field comments are not supported
|
||||||
|
gsub( / (COMMENT|comment).+$/, "" )
|
||||||
|
# Get commas off end of line
|
||||||
|
gsub( /,.?$/, "" )
|
||||||
|
if( prev ){
|
||||||
|
if( firstInTable ){
|
||||||
|
print prev
|
||||||
|
firstInTable = 0
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
print "," prev
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
# FIXME check if this is correct in all cases
|
||||||
|
if( match( $1,
|
||||||
|
/(CONSTRAINT|constraint) ["].*["] (FOREIGN KEY|foreign key)/ ) ){
|
||||||
|
print ","
|
||||||
|
}
|
||||||
|
}
|
||||||
|
prev = $1
|
||||||
|
}
|
||||||
|
|
||||||
|
/ ENGINE| engine/ {
|
||||||
|
if( prev ){
|
||||||
|
if( firstInTable ){
|
||||||
|
print prev
|
||||||
|
firstInTable = 0
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
print "," prev
|
||||||
|
}
|
||||||
|
}
|
||||||
|
prev=""
|
||||||
|
print ");"
|
||||||
|
next
|
||||||
|
}
|
||||||
|
# `KEY` lines are extracted from the `CREATE` block and stored in array for later print
|
||||||
|
# in a separate `CREATE KEY` command. The index name is prefixed by the table name to
|
||||||
|
# avoid a sqlite error for duplicate index name.
|
||||||
|
/^( (KEY|key)|\);)/ {
|
||||||
|
if( prev ){
|
||||||
|
if( firstInTable ){
|
||||||
|
print prev
|
||||||
|
firstInTable = 0
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
print "," prev
|
||||||
|
}
|
||||||
|
}
|
||||||
|
prev = ""
|
||||||
|
if( $0 == ");" ){
|
||||||
|
print
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if( match( $0, /`[^`]+/ ) ){
|
||||||
|
indexName = substr( $0, RSTART+1, RLENGTH-1 )
|
||||||
|
}
|
||||||
|
if( match( $0, /\([^()]+/ ) ){
|
||||||
|
indexKey = substr( $0, RSTART+1, RLENGTH-1 )
|
||||||
|
}
|
||||||
|
# idx_ prefix to avoid name clashes (they really happen!)
|
||||||
|
key[tableName] = key[tableName] "CREATE INDEX \"idx_" \
|
||||||
|
tableName "_" indexName "\" ON \"" tableName "\" (" indexKey ");\n"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
END {
|
||||||
|
if( no_END ){ exit 1}
|
||||||
|
# print all KEY creation lines.
|
||||||
|
for( table in key ){ printf key[table] }
|
||||||
|
|
||||||
|
print "END TRANSACTION;"
|
||||||
|
|
||||||
|
if( caseIssue ){
|
||||||
|
printerr( \
|
||||||
|
"INFO Pure sqlite identifiers are case insensitive (even if quoted\n" \
|
||||||
|
" or if ASCII) and doesnt cross-check TABLE and TEMPORARY TABLE\n" \
|
||||||
|
" identifiers. Thus expect errors like \"table T has no column named F\".")
|
||||||
|
}
|
||||||
|
}
|
54
utils/update-hpr-db.sh
Executable file
@@ -0,0 +1,54 @@
|
|||||||
|
#!/bin/bash -
|
||||||
|
#===============================================================================
|
||||||
|
#
|
||||||
|
# FILE: update-hpr-db.sh
|
||||||
|
#
|
||||||
|
# USAGE: ./update-hpr-db.sh
|
||||||
|
#
|
||||||
|
# DESCRIPTION: Download MySQL hpr.sql file and create SQLite3 file
|
||||||
|
#
|
||||||
|
# OPTIONS: ---
|
||||||
|
# REQUIREMENTS: lib_utils.sh
|
||||||
|
# BUGS: ---
|
||||||
|
# NOTES: ---
|
||||||
|
# AUTHOR: Roan "Rho`n" Horning (roan.horning@gmail.com)
|
||||||
|
# ORGANIZATION:
|
||||||
|
# CREATED: 03/05/2023 07:21:29 PM
|
||||||
|
# REVISION: ---
|
||||||
|
# LICENSE: GNU AGPLv3
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Affero General Public License
|
||||||
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
#
|
||||||
|
#===============================================================================
|
||||||
|
|
||||||
|
set -o nounset # Treat unset variables as an error
|
||||||
|
|
||||||
|
BASEDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||||
|
|
||||||
|
#
|
||||||
|
# Load library functions
|
||||||
|
#
|
||||||
|
LIB="$BASEDIR/lib_utils.sh"
|
||||||
|
[ -e $LIB ] || { echo "Unable to load functions.\n$LIB not found."; exit; }
|
||||||
|
source $LIB
|
||||||
|
|
||||||
|
WORKING_DIR=`make_working_dir`
|
||||||
|
|
||||||
|
download_hpr_sql $WORKING_DIR
|
||||||
|
|
||||||
|
make_hpr_sqlite_db $WORKING_DIR
|
||||||
|
|
||||||
|
copy_to_public_dir $WORKING_DIR `pwd`
|
||||||
|
|
||||||
|
clean_working_dir $WORKING_DIR
|
72
utils/update-hpr.sh
Executable file
@@ -0,0 +1,72 @@
|
|||||||
|
#!/bin/bash -
|
||||||
|
#===============================================================================
|
||||||
|
#
|
||||||
|
# FILE: update-hpr.sh
|
||||||
|
#
|
||||||
|
# USAGE: ./update-hpr.sh
|
||||||
|
#
|
||||||
|
# DESCRIPTION: Script to update local statically generated HPR website
|
||||||
|
#
|
||||||
|
# OPTIONS: ---
|
||||||
|
# REQUIREMENTS: lib_utils.sh
|
||||||
|
# BUGS: ---
|
||||||
|
# NOTES: ---
|
||||||
|
# AUTHOR: Roan "Rho`n" Horning (roan.horning@gmail.com),
|
||||||
|
# ORGANIZATION:
|
||||||
|
# CREATED: 03/03/2023 09:26:29 PM
|
||||||
|
# REVISION: ---
|
||||||
|
# LICENSE: GNU AGPLv3
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Affero General Public License
|
||||||
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
#
|
||||||
|
#===============================================================================
|
||||||
|
|
||||||
|
set -o nounset # Treat unset variables as an error
|
||||||
|
|
||||||
|
BASEDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||||
|
|
||||||
|
#
|
||||||
|
# Load library functions
|
||||||
|
#
|
||||||
|
LIB="$BASEDIR/lib_utils.sh"
|
||||||
|
[ -e $LIB ] || { echo "Unable to load functions.\n$LIB not found."; exit; }
|
||||||
|
source $LIB
|
||||||
|
|
||||||
|
WORKING_DIR=`make_working_dir`
|
||||||
|
|
||||||
|
download_hpr_sql $WORKING_DIR
|
||||||
|
|
||||||
|
make_hpr_sqlite_db $WORKING_DIR
|
||||||
|
|
||||||
|
copy_to_public_dir $WORKING_DIR `pwd`
|
||||||
|
|
||||||
|
mv hpr.sql public_html/
|
||||||
|
|
||||||
|
echo "Update static HTML files"
|
||||||
|
|
||||||
|
# Clean up previously generated files
|
||||||
|
rm -rf public_html/*.html public_html/correspondents public_html/eps public_html/series
|
||||||
|
|
||||||
|
git restore public_html/will-my-show-be-of-interest-to-hackers.html
|
||||||
|
|
||||||
|
# stash changes to configuration file to preserve DB settings
|
||||||
|
git stash
|
||||||
|
|
||||||
|
git pull
|
||||||
|
|
||||||
|
git stash pop
|
||||||
|
|
||||||
|
./site-generator --quiet --all
|
||||||
|
|
||||||
|
clean_working_dir $WORKING_DIR
|