mirror of
https://github.com/openmhz/trunk-server.git
synced 2026-11-15 02:07:50 -05:00
serving podcasts
This commit is contained in:
@@ -4,6 +4,7 @@ const https = require('https');
|
|||||||
var db = require('../db');
|
var db = require('../db');
|
||||||
var mongoose = require("mongoose");
|
var mongoose = require("mongoose");
|
||||||
var Event = require("../models/event");
|
var Event = require("../models/event");
|
||||||
|
var Podcast = require("../models/podcast");
|
||||||
var System = require("../models/system");
|
var System = require("../models/system");
|
||||||
var Talkgroup = require("../models/talkgroup");
|
var Talkgroup = require("../models/talkgroup");
|
||||||
const AdmZip = require("adm-zip");
|
const AdmZip = require("adm-zip");
|
||||||
@@ -104,7 +105,7 @@ const createEventZip = async (folder, filename, zipFolder) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const uploadEventZip = (zipFile, s3File) => {
|
const uploadFile = (zipFile, s3File) => {
|
||||||
var s3Src = fs.createReadStream(zipFile);
|
var s3Src = fs.createReadStream(zipFile);
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
const s3Params = {
|
const s3Params = {
|
||||||
@@ -137,7 +138,7 @@ const ffmpeg = async (command) => {
|
|||||||
console.error(data.toString()); //I'm not sure what debug is
|
console.error(data.toString()); //I'm not sure what debug is
|
||||||
});
|
});
|
||||||
ffmpeg.stdout.on("data", (data) => {
|
ffmpeg.stdout.on("data", (data) => {
|
||||||
console.log(data.toString()); //I'm not sure what debug is
|
//console.log(data.toString()); //I'm not sure what debug is
|
||||||
});
|
});
|
||||||
ffmpeg.on("exit", (code, signal) => {
|
ffmpeg.on("exit", (code, signal) => {
|
||||||
if (signal)
|
if (signal)
|
||||||
@@ -229,8 +230,21 @@ const cleanupEvent = (folder, filename) => {
|
|||||||
fs.rmSync(filename);
|
fs.rmSync(filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const savePodcast = (event, podcastUrl) => {
|
||||||
|
let podcast = new Podcast(event.toObject());
|
||||||
|
podcast.downloadUrl = podcastUrl;
|
||||||
|
let totalTime = 0;
|
||||||
|
event.calls.forEach((call) => {
|
||||||
|
totalTime = totalTime + call.len;
|
||||||
|
if (podcast.systems.indexOf(call.systemName) === -1) {
|
||||||
|
podcast.systems.push(call.systemName);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
podcast.len = totalTime;
|
||||||
|
podcast.save();
|
||||||
|
}
|
||||||
|
|
||||||
const packageEvent = (eventId) => {
|
const packageEvent = (eventId) => {
|
||||||
const event = "tst"
|
|
||||||
const tmpdir = os.tmpdir();
|
const tmpdir = os.tmpdir();
|
||||||
return new Promise(async (resolve, reject) => {
|
return new Promise(async (resolve, reject) => {
|
||||||
var objectId = eventId;
|
var objectId = eventId;
|
||||||
@@ -262,14 +276,15 @@ const packageEvent = (eventId) => {
|
|||||||
|
|
||||||
exportEventJson(tmpEventFolder, event);
|
exportEventJson(tmpEventFolder, event);
|
||||||
createEventZip(tmpEventFolder, zipFile, eventFolder);
|
createEventZip(tmpEventFolder, zipFile, eventFolder);
|
||||||
await uploadEventZip(zipFile, s3ZipFile);
|
await uploadFile(zipFile, s3ZipFile);
|
||||||
|
|
||||||
var downloadUrl = 'https://' + s3_endpoint + "/" + s3_bucket + "/" + s3ZipFile;
|
var downloadUrl = 'https://' + s3_endpoint + "/" + s3_bucket + "/" + s3ZipFile;
|
||||||
var podcastUrl = 'https://' + s3_endpoint + "/" + s3_bucket + "/" + s3PodcastFile;
|
var podcastUrl = 'https://' + s3_endpoint + "/" + s3_bucket + "/" + s3PodcastFile;
|
||||||
event.downloadUrl = downloadUrl;
|
event.downloadUrl = downloadUrl;
|
||||||
await event.save();
|
await event.save();
|
||||||
await createPodcast(tmpEventFolder, podcastFile, event);
|
await createPodcast(tmpEventFolder, podcastFile, event);
|
||||||
await uploadEventZip(podcastFile,s3PodcastFile);
|
await uploadFile(podcastFile,podcastUrl);
|
||||||
|
await savePodcast(event,podcastUrl);
|
||||||
console.log("uploaded to: " + podcastUrl);
|
console.log("uploaded to: " + podcastUrl);
|
||||||
|
|
||||||
|
|
||||||
@@ -283,7 +298,6 @@ const packageEvent = (eventId) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
const compareCalls = (a, b) => {
|
const compareCalls = (a, b) => {
|
||||||
const aTimestamp = new Date(a.time).getTime()
|
const aTimestamp = new Date(a.time).getTime()
|
||||||
const bTimestamp = new Date(b.time).getTime()
|
const bTimestamp = new Date(b.time).getTime()
|
||||||
|
|||||||
21
backend/models/podcast.js
Normal file
21
backend/models/podcast.js
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
var mongoose = require('mongoose');
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
var podcastSchema = mongoose.Schema({
|
||||||
|
title: String,
|
||||||
|
description: String,
|
||||||
|
expireTime: Date,
|
||||||
|
startTime: Date,
|
||||||
|
endTime: Date,
|
||||||
|
downloadUrl: String,
|
||||||
|
systems: [String],
|
||||||
|
numCalls: Number,
|
||||||
|
len: Number
|
||||||
|
},
|
||||||
|
{
|
||||||
|
timestamps: true
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
module.exports = mongoose.model('Podcast', podcastSchema);
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
# build environment
|
# build environment
|
||||||
FROM node:13.12.0-alpine as build
|
FROM node:19-alpine3.16 as build
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
ENV PATH /app/node_modules/.bin:$PATH
|
ENV PATH /app/node_modules/.bin:$PATH
|
||||||
ARG REACT_APP_BACKEND_SERVER
|
ARG REACT_APP_BACKEND_SERVER
|
||||||
@@ -13,7 +13,7 @@ COPY . ./
|
|||||||
RUN npm run build
|
RUN npm run build
|
||||||
|
|
||||||
# production environment
|
# production environment
|
||||||
FROM node:13.12.0-alpine
|
FROM node:19-alpine3.16
|
||||||
RUN mkdir -p /app/public
|
RUN mkdir -p /app/public
|
||||||
COPY ./package.json /tmp
|
COPY ./package.json /tmp
|
||||||
RUN cd /tmp && npm install
|
RUN cd /tmp && npm install
|
||||||
|
|||||||
@@ -4,16 +4,17 @@
|
|||||||
"private": true,
|
"private": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@artsy/fresnel": "6.1.0",
|
"@artsy/fresnel": "6.1.0",
|
||||||
|
"@lagunovsky/redux-react-router": "^4.3.0",
|
||||||
"@reduxjs/toolkit": "^1.9.1",
|
"@reduxjs/toolkit": "^1.9.1",
|
||||||
"@testing-library/jest-dom": "^5.16.5",
|
"@testing-library/jest-dom": "^5.16.5",
|
||||||
"@testing-library/react": "^13.4.0",
|
"@testing-library/react": "^13.4.0",
|
||||||
"@testing-library/user-event": "^14.4.3",
|
"@testing-library/user-event": "^14.4.3",
|
||||||
"axios": "1.2.1",
|
"axios": "1.2.1",
|
||||||
"connected-react-router": "^6.9.3",
|
|
||||||
"date-fns": "2.29.3",
|
"date-fns": "2.29.3",
|
||||||
"ejs": "3.1.8",
|
"ejs": "3.1.8",
|
||||||
"history": "^5.3.0",
|
"history": "^5.3.0",
|
||||||
"mongodb": "^4.13.0",
|
"mongodb": "^4.13.0",
|
||||||
|
"podcast": "^2.0.1",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-audio-player": "0.17.0",
|
"react-audio-player": "0.17.0",
|
||||||
"react-datepicker": "4.8.0",
|
"react-datepicker": "4.8.0",
|
||||||
|
|||||||
BIN
frontend/public/podcast/channel_icon.png
Normal file
BIN
frontend/public/podcast/channel_icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 50 KiB |
BIN
frontend/public/podcast/cover.png
Normal file
BIN
frontend/public/podcast/cover.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.5 MiB |
@@ -4,7 +4,7 @@ const express = require("express");
|
|||||||
const path = require("path");
|
const path = require("path");
|
||||||
const secrets = require("./config/secrets");
|
const secrets = require("./config/secrets");
|
||||||
const configureExpress = require("./config/express");
|
const configureExpress = require("./config/express");
|
||||||
|
const { Podcast,Item,FeedOptions } = require('podcast');
|
||||||
|
|
||||||
// -------------------------------------------
|
// -------------------------------------------
|
||||||
|
|
||||||
@@ -26,12 +26,6 @@ db.connect(function (err) {
|
|||||||
const isDev = process.env.NODE_ENV === "development"
|
const isDev = process.env.NODE_ENV === "development"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------
|
// -------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
@@ -115,6 +109,59 @@ exports.get_card = function(req, res) {
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
async function getPodcast(req, res, next) {
|
||||||
|
const now = new Date();
|
||||||
|
try {
|
||||||
|
const podcastsCollection = db.get().collection('podcasts');
|
||||||
|
podcastsCollection.find().toArray(function(err, podcasts) {
|
||||||
|
const feed = new Podcast({
|
||||||
|
title: 'OpenMHz',
|
||||||
|
description: 'Real public safety radio recordings, from across the U.S - Interesting events, curated by the OpenMHz community.',
|
||||||
|
feedUrl: 'https://openmhz.com/rss.xml',
|
||||||
|
siteUrl: 'https://openmhz.com',
|
||||||
|
imageUrl: 'https://openmhz.com/podcast/cover.png',
|
||||||
|
author: 'OpenMHz',
|
||||||
|
copyright: '© 2022 Robotastic',
|
||||||
|
language: 'en',
|
||||||
|
pubDate: 'May 20, 2012 04:00:00 GMT',
|
||||||
|
ttl: 60,
|
||||||
|
itunesAuthor: 'OpenMHz',
|
||||||
|
itunesSubtitle: 'I am a sub title',
|
||||||
|
itunesSummary: 'Real public safety radio recordings, from across the U.S - Interesting events, curated by the OpenMHz community.',
|
||||||
|
itunesOwner: { name: 'Luke Berndt', email: 'luke@robotastic.com' },
|
||||||
|
itunesExplicit: false,
|
||||||
|
itunesCategory: [{
|
||||||
|
text: 'Government'
|
||||||
|
}, { text: "Daily News"}, {text: "True Crime"}],
|
||||||
|
itunesImage: 'https://openmhz.com/podcast/cover.png'
|
||||||
|
});
|
||||||
|
for (const podcast of podcasts) {
|
||||||
|
feed.addItem({
|
||||||
|
title: podcast.title,
|
||||||
|
description: podcast.description,
|
||||||
|
enclosure: {
|
||||||
|
url: podcast.downloadUrl, // link to the item
|
||||||
|
},
|
||||||
|
author: 'OpenMHz', // optional - defaults to feed author property
|
||||||
|
date: podcast.startTime, // any format that js Date can parse.
|
||||||
|
itunesAuthor: 'OpenMHz',
|
||||||
|
itunesExplicit: false,
|
||||||
|
itunesSummary: podcast.description,
|
||||||
|
itunesDuration: podcast.len
|
||||||
|
});
|
||||||
|
}
|
||||||
|
const xml = feed.buildXml();
|
||||||
|
res.set('Content-Type', 'text/xml');
|
||||||
|
res.send(xml);
|
||||||
|
});
|
||||||
|
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async function getCalls(req, res, next) {
|
async function getCalls(req, res, next) {
|
||||||
|
|
||||||
if (req.query && req.query["call-id"]) {
|
if (req.query && req.query["call-id"]) {
|
||||||
@@ -186,6 +233,9 @@ app.use(express.static(path.join(__dirname, "public")));
|
|||||||
//app.get("/system/:shortName", getCalls)
|
//app.get("/system/:shortName", getCalls)
|
||||||
//app.get("/cards/:id", getCard)
|
//app.get("/cards/:id", getCard)
|
||||||
|
|
||||||
|
|
||||||
|
app.get("/rss.xml", getPodcast);
|
||||||
|
|
||||||
app.get("*", (req, res, next) => {
|
app.get("*", (req, res, next) => {
|
||||||
res.sendFile(__dirname + '/public/index.html');
|
res.sendFile(__dirname + '/public/index.html');
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -3,7 +3,8 @@
|
|||||||
|
|
||||||
import { createBrowserHistory } from 'history'
|
import { createBrowserHistory } from 'history'
|
||||||
import { applyMiddleware, compose, createStore } from 'redux'
|
import { applyMiddleware, compose, createStore } from 'redux'
|
||||||
import { routerMiddleware } from 'connected-react-router'
|
import { createRouterMiddleware } from '@lagunovsky/redux-react-router'
|
||||||
|
//import { routerMiddleware } from 'connected-react-router'
|
||||||
import createRootReducer from './reducers'
|
import createRootReducer from './reducers'
|
||||||
import { apiSlice } from '../features/api/apiSlice'
|
import { apiSlice } from '../features/api/apiSlice'
|
||||||
|
|
||||||
@@ -18,7 +19,7 @@ export default function configureStore(preloadedState) {
|
|||||||
preloadedState,
|
preloadedState,
|
||||||
composeEnhancers(
|
composeEnhancers(
|
||||||
applyMiddleware(
|
applyMiddleware(
|
||||||
routerMiddleware(history), // for dispatching history actions
|
createRouterMiddleware(history), // for dispatching history actions
|
||||||
thunk,
|
thunk,
|
||||||
apiSlice.middleware,
|
apiSlice.middleware,
|
||||||
// ... other middlewares ...
|
// ... other middlewares ...
|
||||||
|
|||||||
@@ -1,13 +1,14 @@
|
|||||||
|
|
||||||
// from https://github.com/supasate/connected-react-router
|
// from https://github.com/supasate/connected-react-router
|
||||||
import { combineReducers } from 'redux'
|
import { combineReducers } from 'redux'
|
||||||
import { connectRouter } from 'connected-react-router'
|
//import { connectRouter } from 'connected-react-router'
|
||||||
|
import { createRouterReducer } from '@lagunovsky/redux-react-router'
|
||||||
import {apiSlice} from "../features/api/apiSlice"
|
import {apiSlice} from "../features/api/apiSlice"
|
||||||
import callPlayerSlice from "../features/callPlayer/callPlayerSlice"
|
import callPlayerSlice from "../features/callPlayer/callPlayerSlice"
|
||||||
import { callsReducer } from "../features/calls/callsSlice"
|
import { callsReducer } from "../features/calls/callsSlice"
|
||||||
|
|
||||||
export default (history) => combineReducers({
|
export default (history) => combineReducers({
|
||||||
router: connectRouter(history),
|
router: createRouterReducer(history),
|
||||||
callPlayer: callPlayerSlice,
|
callPlayer: callPlayerSlice,
|
||||||
calls: callsReducer,
|
calls: callsReducer,
|
||||||
[apiSlice.reducerPath]: apiSlice.reducer,
|
[apiSlice.reducerPath]: apiSlice.reducer,
|
||||||
|
|||||||
@@ -2293,6 +2293,11 @@
|
|||||||
"@jridgewell/resolve-uri" "3.1.0"
|
"@jridgewell/resolve-uri" "3.1.0"
|
||||||
"@jridgewell/sourcemap-codec" "1.4.14"
|
"@jridgewell/sourcemap-codec" "1.4.14"
|
||||||
|
|
||||||
|
"@lagunovsky/redux-react-router@^4.3.0":
|
||||||
|
version "4.3.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@lagunovsky/redux-react-router/-/redux-react-router-4.3.0.tgz#2969158850b6f304f6af59de966a8e5589e2d2e7"
|
||||||
|
integrity sha512-zjjIu0xiX4cAE6O0ttLwo/Fk2zF3oeDfP3nC9YPUFSMnK7QumxS4xQIaH8x+amIIrg3klvPAk64L1bZLvDHl5w==
|
||||||
|
|
||||||
"@leichtgewicht/ip-codec@^2.0.1":
|
"@leichtgewicht/ip-codec@^2.0.1":
|
||||||
version "2.0.4"
|
version "2.0.4"
|
||||||
resolved "https://registry.yarnpkg.com/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz#b2ac626d6cb9c8718ab459166d4bb405b8ffa78b"
|
resolved "https://registry.yarnpkg.com/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz#b2ac626d6cb9c8718ab459166d4bb405b8ffa78b"
|
||||||
@@ -4059,17 +4064,6 @@ connect-history-api-fallback@^2.0.0:
|
|||||||
resolved "https://registry.yarnpkg.com/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz#647264845251a0daf25b97ce87834cace0f5f1c8"
|
resolved "https://registry.yarnpkg.com/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz#647264845251a0daf25b97ce87834cace0f5f1c8"
|
||||||
integrity sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==
|
integrity sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==
|
||||||
|
|
||||||
connected-react-router@^6.9.3:
|
|
||||||
version "6.9.3"
|
|
||||||
resolved "https://registry.yarnpkg.com/connected-react-router/-/connected-react-router-6.9.3.tgz#72300aca9f9d6f38e1f4a2901572faa02adec972"
|
|
||||||
integrity sha512-4ThxysOiv/R2Dc4Cke1eJwjKwH1Y51VDwlOrOfs1LjpdYOVvCNjNkZDayo7+sx42EeGJPQUNchWkjAIJdXGIOQ==
|
|
||||||
dependencies:
|
|
||||||
lodash.isequalwith "^4.4.0"
|
|
||||||
prop-types "^15.7.2"
|
|
||||||
optionalDependencies:
|
|
||||||
immutable "^3.8.1 || ^4.0.0"
|
|
||||||
seamless-immutable "^7.1.3"
|
|
||||||
|
|
||||||
content-disposition@0.5.4:
|
content-disposition@0.5.4:
|
||||||
version "0.5.4"
|
version "0.5.4"
|
||||||
resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.4.tgz#8b82b4efac82512a02bb0b1dcec9d2c5e8eb5bfe"
|
resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.4.tgz#8b82b4efac82512a02bb0b1dcec9d2c5e8eb5bfe"
|
||||||
@@ -5859,11 +5853,6 @@ immer@^9.0.16, immer@^9.0.7:
|
|||||||
resolved "https://registry.yarnpkg.com/immer/-/immer-9.0.16.tgz#8e7caab80118c2b54b37ad43e05758cdefad0198"
|
resolved "https://registry.yarnpkg.com/immer/-/immer-9.0.16.tgz#8e7caab80118c2b54b37ad43e05758cdefad0198"
|
||||||
integrity sha512-qenGE7CstVm1NrHQbMh8YaSzTZTFNP3zPqr3YU0S0UY441j4bJTg4A2Hh5KAhwgaiU6ZZ1Ar6y/2f4TblnMReQ==
|
integrity sha512-qenGE7CstVm1NrHQbMh8YaSzTZTFNP3zPqr3YU0S0UY441j4bJTg4A2Hh5KAhwgaiU6ZZ1Ar6y/2f4TblnMReQ==
|
||||||
|
|
||||||
"immutable@^3.8.1 || ^4.0.0":
|
|
||||||
version "4.2.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/immutable/-/immutable-4.2.1.tgz#8a4025691018c560a40c67e43d698f816edc44d4"
|
|
||||||
integrity sha512-7WYV7Q5BTs0nlQm7tl92rDYYoyELLKHoDMBKhrxEoiV4mrfVdRz8hzPiYOzH7yWjzoVEamxRuAqhxL2PLRwZYQ==
|
|
||||||
|
|
||||||
import-fresh@^3.0.0, import-fresh@^3.1.0, import-fresh@^3.2.1:
|
import-fresh@^3.0.0, import-fresh@^3.1.0, import-fresh@^3.2.1:
|
||||||
version "3.3.0"
|
version "3.3.0"
|
||||||
resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b"
|
resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b"
|
||||||
@@ -7004,11 +6993,6 @@ lodash.debounce@^4.0.8:
|
|||||||
resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af"
|
resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af"
|
||||||
integrity sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==
|
integrity sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==
|
||||||
|
|
||||||
lodash.isequalwith@^4.4.0:
|
|
||||||
version "4.4.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/lodash.isequalwith/-/lodash.isequalwith-4.4.0.tgz#266726ddd528f854f21f4ea98a065606e0fbc6b0"
|
|
||||||
integrity sha512-dcZON0IalGBpRmJBmMkaoV7d3I80R2O+FrzsZyHdNSFrANq/cgDqKQNmAHE8UEj4+QYWwwhkQOVdLHiAopzlsQ==
|
|
||||||
|
|
||||||
lodash.memoize@^4.1.2:
|
lodash.memoize@^4.1.2:
|
||||||
version "4.1.2"
|
version "4.1.2"
|
||||||
resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe"
|
resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe"
|
||||||
@@ -7148,6 +7132,18 @@ mime-db@1.52.0, "mime-db@>= 1.43.0 < 2":
|
|||||||
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70"
|
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70"
|
||||||
integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==
|
integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==
|
||||||
|
|
||||||
|
mime-db@~1.25.0:
|
||||||
|
version "1.25.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.25.0.tgz#c18dbd7c73a5dbf6f44a024dc0d165a1e7b1c392"
|
||||||
|
integrity sha512-5k547tI4Cy+Lddr/hdjNbBEWBwSl8EBc5aSdKvedav8DReADgWJzcYiktaRIw3GtGC1jjwldXtTzvqJZmtvC7w==
|
||||||
|
|
||||||
|
mime-types@2.1.13:
|
||||||
|
version "2.1.13"
|
||||||
|
resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.13.tgz#e07aaa9c6c6b9a7ca3012c69003ad25a39e92a88"
|
||||||
|
integrity sha512-ryBDp1Z/6X90UvjUK3RksH0IBPM137T7cmg4OgD5wQBojlAiUwuok0QeELkim/72EtcYuNlmbkrcGuxj3Kl0YQ==
|
||||||
|
dependencies:
|
||||||
|
mime-db "~1.25.0"
|
||||||
|
|
||||||
mime-types@^2.1.12, mime-types@^2.1.27, mime-types@^2.1.31, mime-types@~2.1.17, mime-types@~2.1.24, mime-types@~2.1.34:
|
mime-types@^2.1.12, mime-types@^2.1.27, mime-types@^2.1.31, mime-types@~2.1.17, mime-types@~2.1.24, mime-types@~2.1.34:
|
||||||
version "2.1.35"
|
version "2.1.35"
|
||||||
resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a"
|
resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a"
|
||||||
@@ -7662,6 +7658,13 @@ pkg-up@^3.1.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
find-up "^3.0.0"
|
find-up "^3.0.0"
|
||||||
|
|
||||||
|
podcast@^2.0.1:
|
||||||
|
version "2.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/podcast/-/podcast-2.0.1.tgz#72167bab5221ec373e38dac5ffb3d1717f82a190"
|
||||||
|
integrity sha512-TWXe/zVziwJNksAn7RLkSre+Z6VQgbs/+gC7qQCKdkyw0hv2hdFGOY9rHgKqa4LI+UP+yZBa6Wr+b9a9vrYDYQ==
|
||||||
|
dependencies:
|
||||||
|
rss "^1.2.2"
|
||||||
|
|
||||||
postcss-attribute-case-insensitive@^5.0.2:
|
postcss-attribute-case-insensitive@^5.0.2:
|
||||||
version "5.0.2"
|
version "5.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/postcss-attribute-case-insensitive/-/postcss-attribute-case-insensitive-5.0.2.tgz#03d761b24afc04c09e757e92ff53716ae8ea2741"
|
resolved "https://registry.yarnpkg.com/postcss-attribute-case-insensitive/-/postcss-attribute-case-insensitive-5.0.2.tgz#03d761b24afc04c09e757e92ff53716ae8ea2741"
|
||||||
@@ -8835,6 +8838,14 @@ rollup@^2.43.1:
|
|||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
fsevents "~2.3.2"
|
fsevents "~2.3.2"
|
||||||
|
|
||||||
|
rss@^1.2.2:
|
||||||
|
version "1.2.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/rss/-/rss-1.2.2.tgz#50a1698876138133a74f9a05d2bdc8db8d27a921"
|
||||||
|
integrity sha512-xUhRTgslHeCBeHAqaWSbOYTydN2f0tAzNXvzh3stjz7QDhQMzdgHf3pfgNIngeytQflrFPfy6axHilTETr6gDg==
|
||||||
|
dependencies:
|
||||||
|
mime-types "2.1.13"
|
||||||
|
xml "1.0.1"
|
||||||
|
|
||||||
run-parallel@^1.1.9:
|
run-parallel@^1.1.9:
|
||||||
version "1.2.0"
|
version "1.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee"
|
resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee"
|
||||||
@@ -8947,11 +8958,6 @@ schema-utils@^4.0.0:
|
|||||||
ajv-formats "^2.1.1"
|
ajv-formats "^2.1.1"
|
||||||
ajv-keywords "^5.0.0"
|
ajv-keywords "^5.0.0"
|
||||||
|
|
||||||
seamless-immutable@^7.1.3:
|
|
||||||
version "7.1.4"
|
|
||||||
resolved "https://registry.yarnpkg.com/seamless-immutable/-/seamless-immutable-7.1.4.tgz#6e9536def083ddc4dea0207d722e0e80d0f372f8"
|
|
||||||
integrity sha512-XiUO1QP4ki4E2PHegiGAlu6r82o5A+6tRh7IkGGTVg/h+UoeX4nFBeCGPOhb4CYjvkqsfm/TUtvOMYC1xmV30A==
|
|
||||||
|
|
||||||
select-hose@^2.0.0:
|
select-hose@^2.0.0:
|
||||||
version "2.0.0"
|
version "2.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca"
|
resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca"
|
||||||
@@ -10374,6 +10380,11 @@ xml-name-validator@^3.0.0:
|
|||||||
resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a"
|
resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a"
|
||||||
integrity sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==
|
integrity sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==
|
||||||
|
|
||||||
|
xml@1.0.1:
|
||||||
|
version "1.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/xml/-/xml-1.0.1.tgz#78ba72020029c5bc87b8a81a3cfcd74b4a2fc1e5"
|
||||||
|
integrity sha512-huCv9IH9Tcf95zuYCsQraZtWnJvBtLVE0QHMOs8bWyZAFZNDcYjsPq1nEx8jKA9y+Beo9v+7OBPRisQTjinQMw==
|
||||||
|
|
||||||
xmlchars@^2.2.0:
|
xmlchars@^2.2.0:
|
||||||
version "2.2.0"
|
version "2.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/xmlchars/-/xmlchars-2.2.0.tgz#060fe1bcb7f9c76fe2a17db86a9bc3ab894210cb"
|
resolved "https://registry.yarnpkg.com/xmlchars/-/xmlchars-2.2.0.tgz#060fe1bcb7f9c76fe2a17db86a9bc3ab894210cb"
|
||||||
|
|||||||
Reference in New Issue
Block a user