Podcast scrobbling
This commit is contained in:
7
Rakefile
7
Rakefile
@@ -30,6 +30,13 @@ namespace :blog do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
task scrobble_podcasts: ["blog:load_environment"] do
|
||||||
|
require "hanami/prepare"
|
||||||
|
|
||||||
|
command = Adamantium::OvercastScrobbler.new(username: "daniel@dnitza.com", password: "impacted-mingle.buckeye4incise")
|
||||||
|
command.()
|
||||||
|
end
|
||||||
|
|
||||||
task load_from_bookshelf: ["blog:load_environment"] do
|
task load_from_bookshelf: ["blog:load_environment"] do
|
||||||
require "hanami/prepare"
|
require "hanami/prepare"
|
||||||
require "csv"
|
require "csv"
|
||||||
|
@@ -1082,6 +1082,10 @@ video {
|
|||||||
margin-bottom: 0px;
|
margin-bottom: 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.mb-1 {
|
||||||
|
margin-bottom: 0.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
.mb-12 {
|
.mb-12 {
|
||||||
margin-bottom: 3rem;
|
margin-bottom: 3rem;
|
||||||
}
|
}
|
||||||
@@ -1114,10 +1118,6 @@ video {
|
|||||||
margin-left: 0.375rem;
|
margin-left: 0.375rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ml-2 {
|
|
||||||
margin-left: 0.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ml-\[5\] {
|
.ml-\[5\] {
|
||||||
margin-left: 5;
|
margin-left: 5;
|
||||||
}
|
}
|
||||||
@@ -1278,10 +1278,6 @@ video {
|
|||||||
width: 100vw;
|
width: 100vw;
|
||||||
}
|
}
|
||||||
|
|
||||||
.w-64 {
|
|
||||||
width: 16rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.max-w-3xl {
|
.max-w-3xl {
|
||||||
max-width: 48rem;
|
max-width: 48rem;
|
||||||
}
|
}
|
||||||
@@ -1302,6 +1298,10 @@ video {
|
|||||||
flex: 1 1 0%;
|
flex: 1 1 0%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.flex-auto {
|
||||||
|
flex: 1 1 auto;
|
||||||
|
}
|
||||||
|
|
||||||
.flex-initial {
|
.flex-initial {
|
||||||
flex: 0 1 auto;
|
flex: 0 1 auto;
|
||||||
}
|
}
|
||||||
@@ -1310,22 +1310,10 @@ video {
|
|||||||
flex: none;
|
flex: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.flex-auto {
|
|
||||||
flex: 1 1 auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.grow {
|
.grow {
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.basis-1\/4 {
|
|
||||||
flex-basis: 25%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.basis-full {
|
|
||||||
flex-basis: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.basis-auto {
|
.basis-auto {
|
||||||
flex-basis: auto;
|
flex-basis: auto;
|
||||||
}
|
}
|
||||||
@@ -1365,6 +1353,10 @@ video {
|
|||||||
grid-auto-flow: row;
|
grid-auto-flow: row;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.grid-flow-col {
|
||||||
|
grid-auto-flow: column;
|
||||||
|
}
|
||||||
|
|
||||||
.grid-cols-2 {
|
.grid-cols-2 {
|
||||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||||
}
|
}
|
||||||
@@ -1389,6 +1381,10 @@ video {
|
|||||||
grid-template-rows: repeat(1, minmax(0, 1fr));
|
grid-template-rows: repeat(1, minmax(0, 1fr));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.grid-rows-2 {
|
||||||
|
grid-template-rows: repeat(2, minmax(0, 1fr));
|
||||||
|
}
|
||||||
|
|
||||||
.flex-row {
|
.flex-row {
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
}
|
}
|
||||||
@@ -1405,6 +1401,10 @@ video {
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.justify-end {
|
||||||
|
justify-content: flex-end;
|
||||||
|
}
|
||||||
|
|
||||||
.justify-center {
|
.justify-center {
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
}
|
}
|
||||||
@@ -1421,6 +1421,16 @@ video {
|
|||||||
gap: 1rem;
|
gap: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.gap-x-1 {
|
||||||
|
-moz-column-gap: 0.25rem;
|
||||||
|
column-gap: 0.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gap-x-1\.5 {
|
||||||
|
-moz-column-gap: 0.375rem;
|
||||||
|
column-gap: 0.375rem;
|
||||||
|
}
|
||||||
|
|
||||||
.space-x-1 > :not([hidden]) ~ :not([hidden]) {
|
.space-x-1 > :not([hidden]) ~ :not([hidden]) {
|
||||||
--tw-space-x-reverse: 0;
|
--tw-space-x-reverse: 0;
|
||||||
margin-right: calc(0.25rem * var(--tw-space-x-reverse));
|
margin-right: calc(0.25rem * var(--tw-space-x-reverse));
|
||||||
@@ -1587,6 +1597,16 @@ video {
|
|||||||
background-color: rgb(224 231 255 / var(--tw-bg-opacity));
|
background-color: rgb(224 231 255 / var(--tw-bg-opacity));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.bg-indigo-300 {
|
||||||
|
--tw-bg-opacity: 1;
|
||||||
|
background-color: rgb(165 180 252 / var(--tw-bg-opacity));
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg-indigo-50 {
|
||||||
|
--tw-bg-opacity: 1;
|
||||||
|
background-color: rgb(238 242 255 / var(--tw-bg-opacity));
|
||||||
|
}
|
||||||
|
|
||||||
.bg-orange-100 {
|
.bg-orange-100 {
|
||||||
--tw-bg-opacity: 1;
|
--tw-bg-opacity: 1;
|
||||||
background-color: rgb(255 237 213 / var(--tw-bg-opacity));
|
background-color: rgb(255 237 213 / var(--tw-bg-opacity));
|
||||||
@@ -1617,28 +1637,14 @@ video {
|
|||||||
background-color: rgb(255 255 255 / var(--tw-bg-opacity));
|
background-color: rgb(255 255 255 / var(--tw-bg-opacity));
|
||||||
}
|
}
|
||||||
|
|
||||||
.bg-yellow-100\/60 {
|
.bg-pink-400 {
|
||||||
background-color: rgb(254 249 195 / 0.6);
|
--tw-bg-opacity: 1;
|
||||||
|
background-color: rgb(244 114 182 / var(--tw-bg-opacity));
|
||||||
}
|
}
|
||||||
|
|
||||||
.bg-indigo-50 {
|
.bg-pink-200 {
|
||||||
--tw-bg-opacity: 1;
|
--tw-bg-opacity: 1;
|
||||||
background-color: rgb(238 242 255 / var(--tw-bg-opacity));
|
background-color: rgb(251 207 232 / var(--tw-bg-opacity));
|
||||||
}
|
|
||||||
|
|
||||||
.bg-indigo-400 {
|
|
||||||
--tw-bg-opacity: 1;
|
|
||||||
background-color: rgb(129 140 248 / var(--tw-bg-opacity));
|
|
||||||
}
|
|
||||||
|
|
||||||
.bg-indigo-600 {
|
|
||||||
--tw-bg-opacity: 1;
|
|
||||||
background-color: rgb(79 70 229 / var(--tw-bg-opacity));
|
|
||||||
}
|
|
||||||
|
|
||||||
.bg-indigo-300 {
|
|
||||||
--tw-bg-opacity: 1;
|
|
||||||
background-color: rgb(165 180 252 / var(--tw-bg-opacity));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.bg-opacity-75 {
|
.bg-opacity-75 {
|
||||||
@@ -1736,6 +1742,10 @@ video {
|
|||||||
padding-right: 2rem;
|
padding-right: 2rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.pt-1 {
|
||||||
|
padding-top: 0.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
.pt-2 {
|
.pt-2 {
|
||||||
padding-top: 0.5rem;
|
padding-top: 0.5rem;
|
||||||
}
|
}
|
||||||
@@ -1744,22 +1754,6 @@ video {
|
|||||||
padding-top: 1rem;
|
padding-top: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.pr-1 {
|
|
||||||
padding-right: 0.25rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pr-4 {
|
|
||||||
padding-right: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pt-1 {
|
|
||||||
padding-top: 0.25rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pt-1\.5 {
|
|
||||||
padding-top: 0.375rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.text-left {
|
.text-left {
|
||||||
text-align: left;
|
text-align: left;
|
||||||
}
|
}
|
||||||
@@ -1796,10 +1790,6 @@ video {
|
|||||||
font-size: 1.25rem;
|
font-size: 1.25rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.text-xsm {
|
|
||||||
font-size: 0.75rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.font-bold {
|
.font-bold {
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
}
|
}
|
||||||
@@ -1816,10 +1806,6 @@ video {
|
|||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
}
|
}
|
||||||
|
|
||||||
.leading-10 {
|
|
||||||
line-height: 2.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.leading-6 {
|
.leading-6 {
|
||||||
line-height: 1.5rem;
|
line-height: 1.5rem;
|
||||||
}
|
}
|
||||||
@@ -1903,11 +1889,21 @@ video {
|
|||||||
color: rgb(129 140 248 / var(--tw-text-opacity));
|
color: rgb(129 140 248 / var(--tw-text-opacity));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.text-indigo-900 {
|
||||||
|
--tw-text-opacity: 1;
|
||||||
|
color: rgb(49 46 129 / var(--tw-text-opacity));
|
||||||
|
}
|
||||||
|
|
||||||
.text-orange-100 {
|
.text-orange-100 {
|
||||||
--tw-text-opacity: 1;
|
--tw-text-opacity: 1;
|
||||||
color: rgb(255 237 213 / var(--tw-text-opacity));
|
color: rgb(255 237 213 / var(--tw-text-opacity));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.text-pink-400 {
|
||||||
|
--tw-text-opacity: 1;
|
||||||
|
color: rgb(244 114 182 / var(--tw-text-opacity));
|
||||||
|
}
|
||||||
|
|
||||||
.text-pink-600 {
|
.text-pink-600 {
|
||||||
--tw-text-opacity: 1;
|
--tw-text-opacity: 1;
|
||||||
color: rgb(219 39 119 / var(--tw-text-opacity));
|
color: rgb(219 39 119 / var(--tw-text-opacity));
|
||||||
@@ -1928,14 +1924,14 @@ video {
|
|||||||
color: rgb(255 255 255 / var(--tw-text-opacity));
|
color: rgb(255 255 255 / var(--tw-text-opacity));
|
||||||
}
|
}
|
||||||
|
|
||||||
.text-indigo-50 {
|
.text-pink-900 {
|
||||||
--tw-text-opacity: 1;
|
--tw-text-opacity: 1;
|
||||||
color: rgb(238 242 255 / var(--tw-text-opacity));
|
color: rgb(131 24 67 / var(--tw-text-opacity));
|
||||||
}
|
}
|
||||||
|
|
||||||
.text-indigo-900 {
|
.text-pink-800 {
|
||||||
--tw-text-opacity: 1;
|
--tw-text-opacity: 1;
|
||||||
color: rgb(49 46 129 / var(--tw-text-opacity));
|
color: rgb(157 23 77 / var(--tw-text-opacity));
|
||||||
}
|
}
|
||||||
|
|
||||||
.underline {
|
.underline {
|
||||||
@@ -2172,11 +2168,6 @@ h1, h2, h3, h4, h5, h6, h1 a, h2 a, h3 a, h4 a, h5 a, h6 a {
|
|||||||
border-color: rgb(37 99 235 / var(--tw-border-opacity));
|
border-color: rgb(37 99 235 / var(--tw-border-opacity));
|
||||||
}
|
}
|
||||||
|
|
||||||
.hover\:border-blue-800:hover {
|
|
||||||
--tw-border-opacity: 1;
|
|
||||||
border-color: rgb(30 64 175 / var(--tw-border-opacity));
|
|
||||||
}
|
|
||||||
|
|
||||||
.hover\:bg-blue-100:hover {
|
.hover\:bg-blue-100:hover {
|
||||||
--tw-bg-opacity: 1;
|
--tw-bg-opacity: 1;
|
||||||
background-color: rgb(219 234 254 / var(--tw-bg-opacity));
|
background-color: rgb(219 234 254 / var(--tw-bg-opacity));
|
||||||
@@ -2192,11 +2183,6 @@ h1, h2, h3, h4, h5, h6, h1 a, h2 a, h3 a, h4 a, h5 a, h6 a {
|
|||||||
background-color: rgb(147 197 253 / var(--tw-bg-opacity));
|
background-color: rgb(147 197 253 / var(--tw-bg-opacity));
|
||||||
}
|
}
|
||||||
|
|
||||||
.hover\:bg-blue-800:hover {
|
|
||||||
--tw-bg-opacity: 1;
|
|
||||||
background-color: rgb(30 64 175 / var(--tw-bg-opacity));
|
|
||||||
}
|
|
||||||
|
|
||||||
.hover\:bg-emerald-100:hover {
|
.hover\:bg-emerald-100:hover {
|
||||||
--tw-bg-opacity: 1;
|
--tw-bg-opacity: 1;
|
||||||
background-color: rgb(209 250 229 / var(--tw-bg-opacity));
|
background-color: rgb(209 250 229 / var(--tw-bg-opacity));
|
||||||
@@ -2237,11 +2223,6 @@ h1, h2, h3, h4, h5, h6, h1 a, h2 a, h3 a, h4 a, h5 a, h6 a {
|
|||||||
background-color: rgb(254 226 226 / var(--tw-bg-opacity));
|
background-color: rgb(254 226 226 / var(--tw-bg-opacity));
|
||||||
}
|
}
|
||||||
|
|
||||||
.hover\:bg-yellow-200:hover {
|
|
||||||
--tw-bg-opacity: 1;
|
|
||||||
background-color: rgb(254 240 138 / var(--tw-bg-opacity));
|
|
||||||
}
|
|
||||||
|
|
||||||
.hover\:fill-blue-400:hover {
|
.hover\:fill-blue-400:hover {
|
||||||
fill: #60a5fa;
|
fill: #60a5fa;
|
||||||
}
|
}
|
||||||
@@ -2254,11 +2235,6 @@ h1, h2, h3, h4, h5, h6, h1 a, h2 a, h3 a, h4 a, h5 a, h6 a {
|
|||||||
fill: #c084fc;
|
fill: #c084fc;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hover\:text-blue-100:hover {
|
|
||||||
--tw-text-opacity: 1;
|
|
||||||
color: rgb(219 234 254 / var(--tw-text-opacity));
|
|
||||||
}
|
|
||||||
|
|
||||||
.hover\:text-blue-400:hover {
|
.hover\:text-blue-400:hover {
|
||||||
--tw-text-opacity: 1;
|
--tw-text-opacity: 1;
|
||||||
color: rgb(96 165 250 / var(--tw-text-opacity));
|
color: rgb(96 165 250 / var(--tw-text-opacity));
|
||||||
@@ -2304,6 +2280,11 @@ h1, h2, h3, h4, h5, h6, h1 a, h2 a, h3 a, h4 a, h5 a, h6 a {
|
|||||||
color: rgb(244 114 182 / var(--tw-text-opacity));
|
color: rgb(244 114 182 / var(--tw-text-opacity));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.hover\:text-pink-600:hover {
|
||||||
|
--tw-text-opacity: 1;
|
||||||
|
color: rgb(219 39 119 / var(--tw-text-opacity));
|
||||||
|
}
|
||||||
|
|
||||||
.hover\:text-red-400:hover {
|
.hover\:text-red-400:hover {
|
||||||
--tw-text-opacity: 1;
|
--tw-text-opacity: 1;
|
||||||
color: rgb(248 113 113 / var(--tw-text-opacity));
|
color: rgb(248 113 113 / var(--tw-text-opacity));
|
||||||
@@ -2313,6 +2294,10 @@ h1, h2, h3, h4, h5, h6, h1 a, h2 a, h3 a, h4 a, h5 a, h6 a {
|
|||||||
text-decoration-line: underline;
|
text-decoration-line: underline;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.hover\:decoration-wavy:hover {
|
||||||
|
text-decoration-style: wavy;
|
||||||
|
}
|
||||||
|
|
||||||
.hover\:opacity-80:hover {
|
.hover\:opacity-80:hover {
|
||||||
opacity: 0.8;
|
opacity: 0.8;
|
||||||
}
|
}
|
||||||
@@ -2463,10 +2448,6 @@ h1, h2, h3, h4, h5, h6, h1 a, h2 a, h3 a, h4 a, h5 a, h6 a {
|
|||||||
background-color: rgb(251 191 36 / var(--tw-bg-opacity));
|
background-color: rgb(251 191 36 / var(--tw-bg-opacity));
|
||||||
}
|
}
|
||||||
|
|
||||||
.dark\:bg-amber-400\/60 {
|
|
||||||
background-color: rgb(251 191 36 / 0.6);
|
|
||||||
}
|
|
||||||
|
|
||||||
.dark\:bg-black {
|
.dark\:bg-black {
|
||||||
--tw-bg-opacity: 1;
|
--tw-bg-opacity: 1;
|
||||||
background-color: rgb(0 0 0 / var(--tw-bg-opacity));
|
background-color: rgb(0 0 0 / var(--tw-bg-opacity));
|
||||||
@@ -2506,6 +2487,11 @@ h1, h2, h3, h4, h5, h6, h1 a, h2 a, h3 a, h4 a, h5 a, h6 a {
|
|||||||
background-color: rgb(17 24 39 / var(--tw-bg-opacity));
|
background-color: rgb(17 24 39 / var(--tw-bg-opacity));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.dark\:bg-indigo-400 {
|
||||||
|
--tw-bg-opacity: 1;
|
||||||
|
background-color: rgb(129 140 248 / var(--tw-bg-opacity));
|
||||||
|
}
|
||||||
|
|
||||||
.dark\:bg-indigo-950 {
|
.dark\:bg-indigo-950 {
|
||||||
--tw-bg-opacity: 1;
|
--tw-bg-opacity: 1;
|
||||||
background-color: rgb(30 27 75 / var(--tw-bg-opacity));
|
background-color: rgb(30 27 75 / var(--tw-bg-opacity));
|
||||||
@@ -2531,21 +2517,6 @@ h1, h2, h3, h4, h5, h6, h1 a, h2 a, h3 a, h4 a, h5 a, h6 a {
|
|||||||
background-color: rgb(15 23 42 / var(--tw-bg-opacity));
|
background-color: rgb(15 23 42 / var(--tw-bg-opacity));
|
||||||
}
|
}
|
||||||
|
|
||||||
.dark\:bg-indigo-300 {
|
|
||||||
--tw-bg-opacity: 1;
|
|
||||||
background-color: rgb(165 180 252 / var(--tw-bg-opacity));
|
|
||||||
}
|
|
||||||
|
|
||||||
.dark\:bg-indigo-400 {
|
|
||||||
--tw-bg-opacity: 1;
|
|
||||||
background-color: rgb(129 140 248 / var(--tw-bg-opacity));
|
|
||||||
}
|
|
||||||
|
|
||||||
.dark\:text-amber-100 {
|
|
||||||
--tw-text-opacity: 1;
|
|
||||||
color: rgb(254 243 199 / var(--tw-text-opacity));
|
|
||||||
}
|
|
||||||
|
|
||||||
.dark\:text-amber-500 {
|
.dark\:text-amber-500 {
|
||||||
--tw-text-opacity: 1;
|
--tw-text-opacity: 1;
|
||||||
color: rgb(245 158 11 / var(--tw-text-opacity));
|
color: rgb(245 158 11 / var(--tw-text-opacity));
|
||||||
@@ -2596,11 +2567,6 @@ h1, h2, h3, h4, h5, h6, h1 a, h2 a, h3 a, h4 a, h5 a, h6 a {
|
|||||||
color: rgb(75 85 99 / var(--tw-text-opacity));
|
color: rgb(75 85 99 / var(--tw-text-opacity));
|
||||||
}
|
}
|
||||||
|
|
||||||
.dark\:text-gray-800 {
|
|
||||||
--tw-text-opacity: 1;
|
|
||||||
color: rgb(31 41 55 / var(--tw-text-opacity));
|
|
||||||
}
|
|
||||||
|
|
||||||
.dark\:text-indigo-300 {
|
.dark\:text-indigo-300 {
|
||||||
--tw-text-opacity: 1;
|
--tw-text-opacity: 1;
|
||||||
color: rgb(165 180 252 / var(--tw-text-opacity));
|
color: rgb(165 180 252 / var(--tw-text-opacity));
|
||||||
@@ -2651,6 +2617,16 @@ h1, h2, h3, h4, h5, h6, h1 a, h2 a, h3 a, h4 a, h5 a, h6 a {
|
|||||||
color: rgb(255 255 255 / var(--tw-text-opacity));
|
color: rgb(255 255 255 / var(--tw-text-opacity));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.dark\:text-pink-200 {
|
||||||
|
--tw-text-opacity: 1;
|
||||||
|
color: rgb(251 207 232 / var(--tw-text-opacity));
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark\:text-pink-100 {
|
||||||
|
--tw-text-opacity: 1;
|
||||||
|
color: rgb(252 231 243 / var(--tw-text-opacity));
|
||||||
|
}
|
||||||
|
|
||||||
.dark\:shadow-pink-200 {
|
.dark\:shadow-pink-200 {
|
||||||
--tw-shadow-color: #fbcfe8;
|
--tw-shadow-color: #fbcfe8;
|
||||||
--tw-shadow: var(--tw-shadow-colored);
|
--tw-shadow: var(--tw-shadow-colored);
|
||||||
@@ -2741,10 +2717,6 @@ h1, h2, h3, h4, h5, h6, h1 a, h2 a, h3 a, h4 a, h5 a, h6 a {
|
|||||||
border-color: rgb(15 23 42 / var(--tw-border-opacity));
|
border-color: rgb(15 23 42 / var(--tw-border-opacity));
|
||||||
}
|
}
|
||||||
|
|
||||||
.dark\:hover\:bg-amber-400\/80:hover {
|
|
||||||
background-color: rgb(251 191 36 / 0.8);
|
|
||||||
}
|
|
||||||
|
|
||||||
.dark\:hover\:bg-emerald-800:hover {
|
.dark\:hover\:bg-emerald-800:hover {
|
||||||
--tw-bg-opacity: 1;
|
--tw-bg-opacity: 1;
|
||||||
background-color: rgb(6 95 70 / var(--tw-bg-opacity));
|
background-color: rgb(6 95 70 / var(--tw-bg-opacity));
|
||||||
@@ -2790,9 +2762,9 @@ h1, h2, h3, h4, h5, h6, h1 a, h2 a, h3 a, h4 a, h5 a, h6 a {
|
|||||||
background-color: rgb(131 24 67 / var(--tw-bg-opacity));
|
background-color: rgb(131 24 67 / var(--tw-bg-opacity));
|
||||||
}
|
}
|
||||||
|
|
||||||
.dark\:hover\:text-yellow-100:hover {
|
.dark\:hover\:text-pink-100:hover {
|
||||||
--tw-text-opacity: 1;
|
--tw-text-opacity: 1;
|
||||||
color: rgb(254 249 195 / var(--tw-text-opacity));
|
color: rgb(252 231 243 / var(--tw-text-opacity));
|
||||||
}
|
}
|
||||||
|
|
||||||
.hover\:dark\:text-blue-100:hover {
|
.hover\:dark\:text-blue-100:hover {
|
||||||
|
11
app/relations/podcast_scrobbles.rb
Normal file
11
app/relations/podcast_scrobbles.rb
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
module Adamantium
|
||||||
|
module Relations
|
||||||
|
class PodcastScrobbles < ROM::Relation[:sql]
|
||||||
|
schema :podcast_scrobbles, infer: true
|
||||||
|
|
||||||
|
auto_struct(true)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
20
app/repos/podcast_scrobble_repo.rb
Normal file
20
app/repos/podcast_scrobble_repo.rb
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
module Adamantium
|
||||||
|
module Repos
|
||||||
|
class PodcastScrobbleRepo < Adamantium::Repo[:podcast_scrobbles]
|
||||||
|
commands :create
|
||||||
|
|
||||||
|
def exists?(id:)
|
||||||
|
!!podcast_scrobbles
|
||||||
|
.where(overcast_id: id)
|
||||||
|
.one
|
||||||
|
end
|
||||||
|
|
||||||
|
def listing
|
||||||
|
podcast_scrobbles
|
||||||
|
.order(Sequel.desc(:listened_at))
|
||||||
|
.limit(5)
|
||||||
|
.to_a
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
@@ -4,6 +4,14 @@ div class="mb-12 prose dark:prose-invert max-w-prose mx-auto text-gray-800 dark:
|
|||||||
h1 🎙️ Podcasts
|
h1 🎙️ Podcasts
|
||||||
|
|
||||||
div class="mb-12 max-w-prose mx-auto"
|
div class="mb-12 max-w-prose mx-auto"
|
||||||
|
- if listens && listens.count > 0
|
||||||
|
div class="p-4 bg-pink-200 dark:bg-pink-900 rounded"
|
||||||
|
h4 class="p-0 m-0 text-pink-900 dark:text-pink-200" Recent listens
|
||||||
|
- listens.each do |listen|
|
||||||
|
div
|
||||||
|
a class="text-pink-800 dark:text-pink-100 no-underline hover:decoration-wavy hover:underline" href=listen.url
|
||||||
|
= "#{listen.podcast_name}: #{listen.title}"
|
||||||
|
|
||||||
table class="prose dark:prose-invert table-auto"
|
table class="prose dark:prose-invert table-auto"
|
||||||
thead
|
thead
|
||||||
tr
|
tr
|
||||||
|
@@ -2,11 +2,15 @@ module Adamantium
|
|||||||
module Views
|
module Views
|
||||||
module Podcasts
|
module Podcasts
|
||||||
class Index < View
|
class Index < View
|
||||||
include Deps["repos.podcast_repo"]
|
include Deps["repos.podcast_repo", "repos.podcast_scrobble_repo"]
|
||||||
|
|
||||||
expose :podcasts do
|
expose :podcasts do
|
||||||
podcast_repo.listing
|
podcast_repo.listing
|
||||||
end
|
end
|
||||||
|
|
||||||
|
expose :listens do
|
||||||
|
podcast_scrobble_repo.listing
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
17
db/migrate/20231130095816_create_podcast_scrobbles.rb
Normal file
17
db/migrate/20231130095816_create_podcast_scrobbles.rb
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
ROM::SQL.migration do
|
||||||
|
change do
|
||||||
|
create_table :podcast_scrobbles do
|
||||||
|
primary_key :id
|
||||||
|
column :overcast_id, :text
|
||||||
|
column :podcast_name, :text
|
||||||
|
column :title, :text
|
||||||
|
column :url, :text
|
||||||
|
column :enclosure_url, :text
|
||||||
|
column :listened_at, :date
|
||||||
|
|
||||||
|
index :overcast_id
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
46
lib/adamantium/overcast_scrobbler.rb
Normal file
46
lib/adamantium/overcast_scrobbler.rb
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
require "httparty"
|
||||||
|
require "nokogiri"
|
||||||
|
require "down"
|
||||||
|
|
||||||
|
module Adamantium
|
||||||
|
class OvercastScrobbler
|
||||||
|
def initialize(username:, password:)
|
||||||
|
@username = username
|
||||||
|
@password = password
|
||||||
|
end
|
||||||
|
|
||||||
|
def call
|
||||||
|
repo = Adamantium::Container["repos.podcast_scrobble_repo"]
|
||||||
|
response = HTTParty.post("https://overcast.fm/login", body: {email: @username, password: @password})
|
||||||
|
cookie = response.request.options[:headers]["Cookie"]
|
||||||
|
|
||||||
|
opml_file = Down::NetHttp.download("https://overcast.fm/account/export_opml/extended", headers: {"Cookie" => cookie})
|
||||||
|
doc = File.open(opml_file) { |f| Nokogiri::XML(f) }
|
||||||
|
|
||||||
|
podcast_list = []
|
||||||
|
|
||||||
|
doc.xpath("//outline[@type='rss']").each_with_object(podcast_list) do |rss, memo|
|
||||||
|
podcasts = rss.xpath("outline[@type='podcast-episode']").select{|ep| ep.get_attribute("played") == "1" }
|
||||||
|
|
||||||
|
name = rss.get_attribute("title")
|
||||||
|
|
||||||
|
podcasts.each do |episode|
|
||||||
|
attrs = {}
|
||||||
|
attrs[:overcast_id] = episode.get_attribute("overcastId")
|
||||||
|
attrs[:podcast_name] = name
|
||||||
|
attrs[:title] = episode.get_attribute("title")
|
||||||
|
attrs[:url] = episode.get_attribute("url")
|
||||||
|
attrs[:enclosure_url] = episode.get_attribute("enclosureUrl")
|
||||||
|
attrs[:listened_at] = episode.get_attribute("userUpdatedDate")
|
||||||
|
|
||||||
|
memo << attrs
|
||||||
|
end
|
||||||
|
|
||||||
|
podcast_list.each do |podcast|
|
||||||
|
next if repo.exists?(id: podcast[:overcast_id])
|
||||||
|
repo.create(podcast)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
Reference in New Issue
Block a user