Skip to content

Commit

Permalink
Merge pull request #24 from mauricerenck/develop
Browse files Browse the repository at this point in the history
Show stats in panel
  • Loading branch information
mauricerenck authored Jun 10, 2019
2 parents ff13155 + 9a5c533 commit 854af36
Show file tree
Hide file tree
Showing 13 changed files with 2,741 additions and 7 deletions.
12 changes: 12 additions & 0 deletions blueprints/pages/podcasterfeed.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
title: Podcaster Feed
tabs:
statistics:
label: Statistics
columns:
- width: 2/3
sections:
podstatsy:
type: podcasterYearlyGraph
- width: 1/3
sections:
podstatsEpisodic:
type: podcasterEpisodeStats
content:
label: Content
icon: text
Expand Down Expand Up @@ -55,6 +66,7 @@ tabs:
podcasterCopyright:
label: Copyright
type: text

settings:
label: RSS Settings
icon: settings
Expand Down
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"name": "mauricerenck/podcaster",
"version": "1.1.0",
"description": "A podcast plugin for Kirby 3",
"type": "kirby-plugin",
"license": "MIT",
Expand All @@ -9,7 +10,6 @@
"email": "[email protected]"
}
],
"version": "1.0.6",
"autoload": {
"files": [
"utils/PodcasterUtils.php",
Expand Down
2 changes: 1 addition & 1 deletion composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions index.css

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions index.js

Large diffs are not rendered by default.

45 changes: 44 additions & 1 deletion index.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,14 @@
'files/podcaster-episode' => __DIR__ . '/blueprints/files/podcaster-episode.yml'
],
'sections' => [
'podcaster-stats' => [
'podcasterEpisodeStats' => [
'props' => [
'headline' => function ($headline = 'Last modified') {
return $headline;
}
]
],
'podcasterYearlyGraph' => [
'props' => [
'headline' => function ($headline = 'Last modified') {
return $headline;
Expand Down Expand Up @@ -139,6 +146,42 @@
}
]
],
'api' => [
'routes' => [
[
'pattern' => 'podcaster/stats/(:any)/year/(:num)/month/(:num)',
'action' => function ($podcast, $year, $month) {

if(option('mauricerenck.podcaster.statsInternal') === false || option('mauricerenck.podcaster.statsType') === 'file') {
$errorMessage = ['error' => 'cannot use stats on file method, use mysql version instead'];
echo new Response(json_encode($errorMessage), 'application/json', 501);
}

$podcasterStats = new PodcasterStats();
$stats = $podcasterStats->getEpisodeStatsOfMonth($podcast, $year, $month);
return [
'stats' => $stats
];
}
],
[
'pattern' => 'podcaster/stats/(:any)/yearly-downloads/(:any)',
'action' => function ($podcast, $year) {

if(option('mauricerenck.podcaster.statsInternal') === false || option('mauricerenck.podcaster.statsType') === 'file') {
$errorMessage = ['error' => 'cannot use stats on file method, use mysql version instead'];
echo new Response(json_encode($errorMessage), 'application/json', 501);
}

$podcasterStats = new PodcasterStats();
$stats = $podcasterStats->getDownloadsOfYear($podcast, $year);
return [
'stats' => $stats
];
}
]
]
],
'hooks' => [
'file.create:after' => function ($file) {
if($file->extension() == 'mp3') {
Expand Down
23 changes: 23 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"name": "podcaster",
"version": "1.1.0",
"description": "Theme",
"main": "index.js",
"author": "Maurice Renck",
"scripts": {
"dev": "parcel watch src/index.js --no-source-maps -d ./",
"build": "parcel build src/index.js --no-source-maps --experimental-scope-hoisting -d ./"
},
"devDependencies": {
"@vue/component-compiler-utils": "^3.0.0",
"cssnano": "^4.1.10",
"sass": "^1.20.3",
"vue-template-compiler": "^2.6.10"
},
"dependencies": {
"date-fns": "^2.0.0-alpha.31",
"frappe-charts": "^1.2.0",
"vue": "^2.2.4",
"vue-hot-reload-api": "^2.3.3"
}
}
166 changes: 166 additions & 0 deletions src/components/Episode.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
<template>
<section class="k-modified-section">
<div class="podcaster-prev-next">
<button class="k-link k-button" v-on:click="prevMonth"><k-icon type="angle-left"></button>
<button class="k-link k-button" v-on:click="nextMonth"><k-icon type="angle-right"></button>
</div>
<k-text>{{ error }}</k-text>
<k-headline>{{ headline }}</k-headline>
<table id="episodeStats">
<tr v-for="episode in episodes">
<td>{{ episode.downloads }}</td>
<td>{{ episode.title }}</td>
</tr>
</table>

</section>
</template>

<script>
import getMonth from 'date-fns/getMonth'
import addMonths from 'date-fns/addMonths'
import subMonths from 'date-fns/subMonths'
import getYear from 'date-fns/getYear'
export default {
data: function() {
return {
currentDate: new Date(),
currentMonthName: null,
currentMonth: null,
currentYear: null,
headline: null,
episodes: [],
error: null,
podcasterSlug: null
}
},
created: function() {
this.setNewDateVars()
},
mounted() {
this.podcasterSlug = this.sanitizeTitle(this.pageValues.podcastertitle)
this.getStats()
},
computed: {
id() {
return this.$store.state.form.current
},
pageValues() {
return this.$store.getters['form/values'](this.id)
},
},
watch: {
currentDate: {
immediate: false,
handler(newVal, oldVal) {
this.getStats()
},
}
},
methods: {
getStats() {
fetch('/api/podcaster/stats/'+ this.podcasterSlug + '/year/' + this.currentYear + '/month/' + (this.currentMonth+1), {
method: 'GET',
headers: {
'X-CSRF': panel.csrf,
},
})
.then(response => {
if(response.status !== 200) {
throw 'You are tracking your downloads, using the file method. Stats are currently available only when using mysql'
}
return response
})
.then(response => response.json())
.then(response => {
this.episodes = this.computeStats(response.stats)
})
.catch(error => {
this.error = error
console.log(this.error)
})
},
computeStats(stats) {
const episodeStats = stats.episodes.map(function(episode) {
return { title: episode.episode.replace(/-/g, ' '), downloads: episode.downloaded }
})
return episodeStats
},
prevMonth() {
const newDate = subMonths(this.currentDate, 1)
this.currentDate = newDate
this.setNewDateVars()
},
nextMonth() {
const newDate = addMonths(this.currentDate, 1)
this.currentDate = newDate
this.setNewDateVars()
},
setNewDateVars() {
this.currentMonth = getMonth(this.currentDate)
this.currentYear= getYear(this.currentDate)
this.currentMonthName = this.currentDate.toLocaleString('en', { month: 'long' })
this.headline = 'Stats for ' + this.currentMonthName + ' ' + this.currentYear
},
sanitizeTitle: function(title) {
var slug = ''
// Change to lower case
var titleLower = title.toLowerCase()
// Letter "e"
slug = titleLower.replace(/e|é|è||||ê|ế||||/gi, 'e')
// Letter "a"
slug = slug.replace(/a|á|à|ã|||ă||||||â|||||/gi, 'a')
// Letter "o"
slug = slug.replace(/o|ó|ò|õ|||ô||||||ơ|||||/gi, 'o')
// Letter "u"
slug = slug.replace(/u|ú|ù|ũ|||ư|||||/gi, 'u')
// Letter "d"
slug = slug.replace(/đ/gi, 'd')
// Trim the last whitespace
slug = slug.replace(/\s*$/g, '')
// Change whitespace to "-"
slug = slug.replace(/\s+/g, '-')
return slug
},
},
}
</script>

<style lang="scss">
.k-section-name-podstatsEpisodic {
table {
width: 100%;
border: 1px solid #ccc;
background: #fff;
margin-top: 0.5em;
}
td {
border-bottom: 1px solid #ccc;
line-height: 2;
padding: 0 10px;
}
td:first-child {
text-align: right;
}
.podcaster-prev-next {
display: inline;
text-align: right;
color: #666;
}
.k-headline {
display: inline;
}
.k-text {
color: red;
}
}
</style>
Loading

0 comments on commit 854af36

Please sign in to comment.