Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update from main repo #16

Merged
merged 33 commits into from
May 10, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
a3a2daf
Remove file extension check (#801)
calzoneman Apr 7, 2019
97266b6
Better fix for jank dailymotion race conditions
calzoneman Apr 12, 2019
2a1f1df
Bump some crufty dependencies
calzoneman Apr 28, 2019
60c348a
Clamp timeouts to 1 day
calzoneman Apr 29, 2019
df934f4
Add clarity to custom media doc about how the user must host the JSON…
calzoneman May 5, 2019
6b2dfa4
Fix #813
calzoneman May 25, 2019
5a2494a
Prevent uncaught exception if spawn() throws synchronously (e.g. ENOMEM)
calzoneman May 29, 2019
959ef89
add autoplay attribute to custom embed iframe tag, so autoplay works …
mrx1983 Jun 9, 2019
5c51d73
Update nodemailer
calzoneman Jun 16, 2019
77b7af7
deps: bump cytubefilters
calzoneman Jun 28, 2019
27e8885
Add kick logline (#821)
calzoneman Aug 2, 2019
1ec3eab
Preserve current playing item when shuffling (#812)
calzoneman Aug 2, 2019
08f9fee
Match word boundaries for nick highlight (#819)
calzoneman Aug 2, 2019
c4a1d4b
Add dummy ID to migrator to fix #831
calzoneman Oct 27, 2019
06b3916
Fix #822
calzoneman Oct 27, 2019
b0b22a7
Fix migrator (#831)
calzoneman Oct 27, 2019
9aa73be
Remove --loose babel parameter that throws errors now
calzoneman Dec 2, 2019
4d3c90f
Sunset node v8, add node v13 to travis
calzoneman Dec 2, 2019
40b5a0f
Upgrade knex
calzoneman Dec 2, 2019
842d0bb
update button labels (#839)
Olie440 Dec 6, 2019
c809b19
Fix redirect logic for ffprobe pre-flight check
calzoneman Jan 11, 2020
58e4e09
Replace twitch clip player (#842)
calzoneman Jan 27, 2020
46311bd
Add missed file
calzoneman Jan 27, 2020
b80a532
Add YouTube cache table
calzoneman Feb 7, 2020
e3a9915
Clean up a few things that no longer work/are no longer used
calzoneman Feb 10, 2020
1060651
Remove old flatfile chandump storage
calzoneman Feb 16, 2020
d235892
Add tabcompletion for PMs
Mar 14, 2020
5a386d0
Remove fallback to YT from library search
calzoneman Mar 21, 2020
83fd8f1
Fix updated_at in media_metadata_cache
calzoneman Mar 21, 2020
47bb3e4
Add metric for yt cached result age
calzoneman Mar 21, 2020
a53f65a
Fix channel password prompt
Xaekai Mar 29, 2020
f2adbe1
Explicitly use UTF8 encoding for media metadata table (#863)
Xaekai Apr 11, 2020
8836561
Replace userlist visibility check logic (#859)
Xaekai Apr 17, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 2 additions & 2 deletions .travis.yml
Expand Up @@ -9,6 +9,6 @@ addons:
env:
- CXX="g++-4.8"
node_js:
- "11"
- "13"
- "12"
- "10"
- "8"
39 changes: 39 additions & 0 deletions NEWS.md
@@ -1,3 +1,42 @@
2020-02-15
==========

Old versions of CyTube defaulted to storing channel state in flatfiles located
in the `chandump` directory. The default was changed a while ago, and the
flatfile storage mechanism has now been removed.

Admins who have not already migrated their installation to the "database"
channel storage type can do so by following these instructions:

1. Run `git checkout e3a9915b454b32e49d3871c94c839899f809520a` to temporarily
switch to temporarily revert to the previous version of the code that
supports the "file" channel storage type
2. Run `npm run build-server` to build the old version
3. Run `node lib/channel-storage/migrator.js |& tee migration.log` to migrate
channel state from files to the database
4. Inspect the output of the migration tool for errors
5. Set `channel-storage`/`type` to `"database"` in `config.yaml` and start the
server. Load a channel to verify the migration worked as expected
6. Upgrade back to the latest version with `git checkout 3.0` and `npm run
build-server`
7. Remove the `channel-storage` block from `config.yaml` and remove the
`chandump` directory since it is no longer needed (you may wish to archive
it somewhere in case you later discover the migration didn't work as
expected).

If you encounter any errors during the process, please file an issue on GitHub
and attach the output of the migration tool (which if you use the above commands
will be written to `migration.log`).

2019-12-01
==========

In accordance with node v8 LTS becoming end-of-life on 2019-12-31, CyTube no
longer supports v8.

Please upgrade to v10 or v12 (active LTS); refer to
https://nodejs.org/en/about/releases/ for the node.js support timelines.

2018-12-07
==========

Expand Down
1 change: 1 addition & 0 deletions bin/build-player.js
Expand Up @@ -26,6 +26,7 @@ var order = [
'gdrive-youtube.coffee',
'hls.coffee',
'mixer.coffee',
'twitchclip.coffee',
'update.coffee'
];

Expand Down
3 changes: 0 additions & 3 deletions config.template.yaml
Expand Up @@ -133,9 +133,6 @@ channel-path: 'r'
channel-blacklist: []
# Minutes between saving channel state to disk
channel-save-interval: 5
# Determines channel data storage mechanism.
channel-storage:
type: 'database'

# Configure periodic clearing of old alias data
aliases:
Expand Down
18 changes: 18 additions & 0 deletions docs/custom-media.md
@@ -1,6 +1,8 @@
CyTube Custom Content Metadata
==============================

*Last updated: 2019-05-05*

## Purpose ##

CyTube currently supports adding custom audio/video content by allowing the user
Expand All @@ -24,6 +26,22 @@ This document specifies a new supported media provider which allows users to
provide a JSON manifest specifying the metadata for custom content in a way that
avoids the above issues and is more flexible for extension.

## Custom Manifest URLs ##

Custom media manifests are added to CyTube by adding a link to a public URL
hosting the JSON metadata manifest. Pasting the JSON directly into CyTube is
not supported. Valid JSON manifests must:

* Have a URL path ending with the file extension `.json` (not counting
querystring parameters)
* Be served with the `Content-Type` header set to `application/json`
* Be retrievable at any time while the item is on the playlist (CyTube may
re-request the metadata for an item already on the playlist to revalidate)
* Respond to valid requests with a 200 OK HTTP response code (redirects are
not supported)
* Respond within 10 seconds
* Not exceed 100 KiB in size

## Manifest Format ##

To add custom content, the user provides a JSON object with the following keys:
Expand Down
4 changes: 2 additions & 2 deletions index.js
Expand Up @@ -2,10 +2,10 @@

const ver = process.version.match(/v(\d+)\.\d+\.\d+/);

if (parseInt(ver[1], 10) < 8) {
if (parseInt(ver[1], 10) < 10) {
console.error(
`node.js ${process.version} is not supported. ` +
'CyTube requires node v6 or later.'
'CyTube requires node v10 or later.'
)
process.exit(1);
}
Expand Down
9 changes: 6 additions & 3 deletions integration_test/channel/kickban.js
Expand Up @@ -228,7 +228,8 @@ describe('KickbanModule', () => {
await tx.table('aliases')
.insert([{
name: 'test_user',
ip: '1.2.3.4'
ip: '1.2.3.4',
time: Date.now()
}]);
});
});
Expand Down Expand Up @@ -385,7 +386,8 @@ describe('KickbanModule', () => {
await tx.table('aliases')
.insert({
name: 'test_user',
ip: longIP
ip: longIP,
time: Date.now()
});
}).then(() => {
kickban.handleCmdIPBan(
Expand Down Expand Up @@ -489,7 +491,8 @@ describe('KickbanModule', () => {
await tx.table('aliases')
.insert({
name: 'another_user',
ip: '1.2.3.3' // different IP, same /24 range
ip: '1.2.3.3', // different IP, same /24 range
time: Date.now()
});
}).then(() => {
mockUser.socket.emit = (frame, obj) => {
Expand Down
6 changes: 3 additions & 3 deletions integration_test/db/aliases.js
Expand Up @@ -21,9 +21,9 @@ function addSomeAliases() {
return cleanup().then(() => {
return testDB.knex.table('aliases')
.insert([
{ ip: testIPs[0], name: testNames[0] },
{ ip: testIPs[0], name: testNames[1] },
{ ip: testIPs[1], name: testNames[1] }
{ ip: testIPs[0], name: testNames[0], time: Date.now() },
{ ip: testIPs[0], name: testNames[1], time: Date.now() },
{ ip: testIPs[1], name: testNames[1], time: Date.now() }
]);
});
}
Expand Down
38 changes: 18 additions & 20 deletions package.json
Expand Up @@ -2,15 +2,15 @@
"author": "Calvin Montgomery",
"name": "CyTube",
"description": "Online media synchronizer and chat",
"version": "3.63.6",
"version": "3.70.0",
"repository": {
"url": "http://github.com/calzoneman/sync"
},
"license": "MIT",
"dependencies": {
"@calzoneman/express-babel-decorators": "^1.0.0",
"@calzoneman/jsli": "^2.0.1",
"bcrypt": "^2.0.1",
"bcrypt": "^3.0.6",
"bluebird": "^3.5.1",
"body-parser": "^1.18.2",
"cheerio": "^1.0.0-rc.2",
Expand All @@ -20,16 +20,16 @@
"create-error": "^0.3.1",
"csrf": "^3.0.0",
"cytube-mediaquery": "git://github.com/CyTube/mediaquery",
"cytubefilters": "git://github.com/calzoneman/cytubefilters.git#ffdbce83c6cf806f9ae0983cc735230fefcfdb5a",
"cytubefilters": "git://github.com/calzoneman/cytubefilters.git#c6df180eeb226eaffc7909cf047d3667dc58ef67",
"express": "^4.16.2",
"express-minify": "^1.0.0",
"graceful-fs": "^4.1.2",
"json-typecheck": "^0.1.3",
"knex": "^0.14.3",
"knex": "^0.20.3",
"lodash": "^4.17.5",
"morgan": "^1.6.1",
"mysql": "^2.9.0",
"nodemailer": "^4.4.2",
"nodemailer": "^6.2.1",
"prom-client": "^10.0.2",
"proxy-addr": "^2.0.2",
"pug": "^2.0.0-beta3",
Expand All @@ -45,42 +45,40 @@
},
"scripts": {
"build-player": "./bin/build-player.js",
"build-server": "babel -D --source-maps --loose es6.destructuring,es6.forOf --out-dir lib/ src/",
"build-server": "babel -D --source-maps --out-dir lib/ src/",
"flow": "flow",
"lint": "eslint src",
"pretest": "npm run lint",
"postinstall": "./postinstall.sh",
"server-dev": "babel -D --watch --source-maps --loose es6.destructuring,es6.forOf --out-dir lib/ src/",
"server-dev": "babel -D --watch --source-maps --verbose --out-dir lib/ src/",
"generate-userscript": "$npm_node_execpath gdrive-userscript/generate-userscript $@ > www/js/cytube-google-drive.user.js",
"test": "mocha --recursive --exit test",
"integration-test": "mocha --recursive --exit integration_test"
},
"devDependencies": {
"babel-cli": "^6.26.0",
"babel-core": "^6.26.3",
"babel-eslint": "^8.2.2",
"babel-plugin-add-module-exports": "^0.2.1",
"babel-plugin-transform-decorators-legacy": "^1.3.4",
"babel-preset-env": "^1.5.2",
"@babel/cli": "^7.4.4",
"@babel/core": "^7.4.4",
"@babel/preset-env": "^7.4.4",
"babel-eslint": "^10.0.1",
"babel-plugin-add-module-exports": "^1.0.2",
"coffeescript": "^1.9.2",
"eslint": "^4.19.1",
"mocha": "^5.2.0",
"sinon": "^2.3.2"
"eslint": "^5.16.0",
"mocha": "^6.1.4",
"sinon": "^7.3.2"
},
"babel": {
"presets": [
[
"env",
"@babel/env",
{
"targets": {
"node": "8"
"node": "10"
}
}
]
],
"plugins": [
"add-module-exports",
"transform-decorators-legacy"
"add-module-exports"
]
}
}
35 changes: 22 additions & 13 deletions player/dailymotion.coffee
Expand Up @@ -5,6 +5,7 @@ window.DailymotionPlayer = class DailymotionPlayer extends Player

@setMediaProperties(data)
@initialVolumeSet = false
@playbackReadyCb = null

waitUntilDefined(window, 'DM', =>
removeOld()
Expand All @@ -26,8 +27,7 @@ window.DailymotionPlayer = class DailymotionPlayer extends Player
)

@dm.addEventListener('apiready', =>
@dm.ready = true
@dm.apiready = true
@dmReady = true
@dm.addEventListener('ended', ->
if CLIENT.leader
socket.emit('playNext')
Expand All @@ -53,50 +53,59 @@ window.DailymotionPlayer = class DailymotionPlayer extends Player
# becomes unusable and attempting to load() will corrupt it and
# crash the player with an error. As a short–medium term
# workaround, mark the player as "not ready" until the next
# video loads
# playback_ready event
@dm.addEventListener('video_end', =>
@dm.ready = false
@dmReady = false
)
@dm.addEventListener('playback_ready', =>
@dm.ready = true
@dmReady = true
if @playbackReadyCb
@playbackReadyCb()
@playbackReadyCb = null
)
)
)

load: (data) ->
@setMediaProperties(data)
if @dm and @dm.apiready
if @dm and @dmReady
@dm.load(data.id)
@dm.seek(data.currentTime)
else if @dm
# TODO: Player::load() needs to be made asynchronous in the future
console.log('Warning: load() called before DM is ready, queueing callback')
@playbackReadyCb = () =>
@dm.load(data.id)
@dm.seek(data.currentTime)
else
console.error('WTF? DailymotionPlayer::load() called but dm is not ready')
console.error('WTF? DailymotionPlayer::load() called but @dm is undefined')

pause: ->
if @dm and @dm.ready
if @dm and @dmReady
@paused = true
@dm.pause()

play: ->
if @dm and @dm.ready
if @dm and @dmReady
@paused = false
@dm.play()

seekTo: (time) ->
if @dm and @dm.ready
if @dm and @dmReady
@dm.seek(time)

setVolume: (volume) ->
if @dm and @dm.ready
if @dm and @dmReady
@dm.setVolume(volume)

getTime: (cb) ->
if @dm and @dm.ready
if @dm and @dmReady
cb(@dm.currentTime)
else
cb(0)

getVolume: (cb) ->
if @dm and @dm.ready
if @dm and @dmReady
if @dm.muted
cb(0)
else
Expand Down
1 change: 1 addition & 0 deletions player/embed.coffee
Expand Up @@ -59,6 +59,7 @@ window.EmbedPlayer = class EmbedPlayer extends Player
iframe = $('<iframe/>').attr(
src: embed.src
frameborder: '0'
allow: 'autoplay'
allowfullscreen: '1'
)

Expand Down
12 changes: 12 additions & 0 deletions player/twitchclip.coffee
@@ -0,0 +1,12 @@
window.TwitchClipPlayer = class TwitchClipPlayer extends EmbedPlayer
constructor: (data) ->
if not (this instanceof TwitchClipPlayer)
return new TwitchClipPlayer(data)

@load(data)

load: (data) ->
data.meta.embed =
tag: 'iframe'
src: "https://clips.twitch.tv/embed?clip=#{data.id}"
super(data)
2 changes: 1 addition & 1 deletion player/update.coffee
Expand Up @@ -18,7 +18,7 @@ TYPE_MAP =
vm: VideoJSPlayer
hl: HLSPlayer
sb: StreamablePlayer
tc: VideoJSPlayer
tc: TwitchClipPlayer
cm: VideoJSPlayer
mx: MixerPlayer

Expand Down
14 changes: 7 additions & 7 deletions src/channel-storage/channelstore.js
@@ -1,4 +1,3 @@
import { FileStore } from './filestore';
import { DatabaseStore } from './dbstore';
import Config from '../config';
import Promise from 'bluebird';
Expand Down Expand Up @@ -26,11 +25,12 @@ export function save(id, channelName, data) {
}

function loadChannelStore() {
switch (Config.get('channel-storage.type')) {
case 'database':
return new DatabaseStore();
case 'file':
default:
return new FileStore();
if (Config.get('channel-storage.type') === 'file') {
throw new Error(
'channel-storage type "file" is no longer supported. Please see ' +
'NEWS.md for instructions on upgrading.'
);
}

return new DatabaseStore();
}