Skip to content

Commit fc477e4

Browse files
gloriajwfuyloon2018tunguyentk
authored
Release 2.0.2 (#1023)
* Release 2.0.2 * Task/fix bug delete stage (#1027) * Fix bug at backstage can not delete stage * Fix Bug Studio UI load file i18n form dashboard get 403 code * Task/fix statis duplicate delete (#1040) * Move button Clone, Delete from Stage to Stage Management * Update Code Sort by Created Date and Id DESC * FIx bug statistics worng * sort by created date decs * fix bug statistics wrong * debug fix statistics on dev-app env * debug fix statistics wrong * debug * debug * debug * Fix bug Created_on have the same date after clone * change "manage stage" to "manage" * Check upload file limit on studio * implement player upload limit enhancement * Update format size * Fix does not return to start at end of playing (once mode) * Add Create_On and last access in backstage * add create date and last access on backstage * delete notify * update "without time zone" Co-authored-by: TU_COMPUTER\justr <nhtu160220@gmail.com> * make clear chat to clear player and public chat on stage- clear all chat in clear chat button in stage management (#1042) * Merge branch 'main' into BlueMoon-2.0.2 * make save chat option on stage (#1048) * Make separate chat log and make timestamp for file name (#1045) * Rebase * Update mail_utils.py Need a more forgiving encoding scheme. * Make owner display name in player and edit access column (#1051) Co-authored-by: fuyloon2018 <62701756+fuyloon2018@users.noreply.github.com> Co-authored-by: TU_COMPUTER\justr <nhtu160220@gmail.com> Co-authored-by: tunguyentk <117065175+tunguyentk@users.noreply.github.com> Co-authored-by: Jamse Liew <liew2018@gmail.com>
1 parent ddbfa32 commit fc477e4

File tree

18 files changed

+662
-144
lines changed

18 files changed

+662
-144
lines changed

studio/schema.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,6 @@ class Mutation(graphene.ObjectType):
9292
requestPermission = RequestPermission.Field()
9393
quickAssignMutation = QuickAssignMutation.Field()
9494

95-
9695
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
9796
studio_schema = graphene.Schema(query=Query, mutation=Mutation)
9897
app.add_url_rule(

system/prod/certbot_renew_script.sh

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ DOMAIN=SET_THIS_TO_THE_FULL_DOMAIN_NAME_NOT_HOSTNAME
88
#SVC_SERVER=
99
#SVC_SERVER=1
1010
#APP_SERVER=
11-
#APP_SERVER=1
11+
APP_SERVER=1
1212

1313
CERTCHECK_FILE=/etc/letsencrypt/live/${DOMAIN}/cert.pem
1414
if [[ -n ${SVC_SERVER} ]]
@@ -18,28 +18,28 @@ else
1818
OTHER_COPY=
1919
fi
2020

21+
now_seconds=`date +%s`
22+
sleep 2
2123
$CERTBOT renew
22-
cert_seconds=`/usr/bin/stat -c %Y $CERTCHECK_FILE`
2324

2425
# See if certs were updated. certbot doesn't always return a 0 status when expected.
2526
# So ignore return code issued by certbot and do our own check.
26-
if [[ ! -f "${OTHER_COPY}" ]]
27-
then
28-
mos_seconds=0
29-
else
30-
mos_seconds=`/usr/bin/stat -c %Y $OTHER_COPY`
31-
fi
27+
mod_seconds=`/usr/bin/stat -c %Y $CERTCHECK_FILE`
3228

33-
if [[ $cert_seconds -ne $mos_seconds ]]
29+
if [[ $now_seconds -lt $mod_seconds ]]
3430
then
3531
echo "Updating..."
3632
systemctl reload nginx
3733
if [[ -n ${SVC_SERVER} ]]
3834
then
39-
cd /etc/letsencrypt/live/${DOMAIN}
40-
cp -Lpr * /etc/mosquitto/ca_certificates
41-
chown -R mosquitto:mosquitto /etc/mosquitto/ca_certificates
42-
systemctl reload mosquitto.service >> /var/log/le-renew.log 2>&1
35+
other_seconds=`/usr/bin/stat -c %Y $OTHER_COPY`
36+
if [[ $other_seconds -lt $mod_seconds ]]
37+
then
38+
cd /etc/letsencrypt/live/${DOMAIN}
39+
cp * /etc/mosquitto/ca_certificates
40+
chown -R mosquitto:mosquitto /etc/mosquitto/ca_certificates
41+
systemctl reload mosquitto.service >> /var/log/le-renew.log 2>&1
42+
fi
4343
fi
4444
else
4545
echo "No update."
@@ -52,8 +52,6 @@ then
5252
systemctl restart event_archive.service >> /var/log/le-renew.log 2>&1
5353
elif [[ -n ${STREAMING_SERVER} ]]
5454
then
55-
echo "Restarting our nodejs streaming service, in case streaming1 server certs were updated. This does not restart jitsi-videobridge, which uses its own cert files"then
5655
echo "Restarting our nodejs streaming service, in case streaming1 server certs were updated. This does not restart jitsi-videobridge, which uses its own cert files"
5756
systemctl restart upstage-streaming.service >> /var/log/le-renew.log 2>&1
5857
fi
59-
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# Edit this file to introduce tasks to be run by cron.
2+
#
3+
# Each task to run has to be defined through a single line
4+
# indicating with different fields when the task will be run
5+
# and what command to run for the task
6+
#
7+
# To define the time you can provide concrete values for
8+
# minute (m), hour (h), day of month (dom), month (mon),
9+
# and day of week (dow) or use '*' in these fields (for 'any').
10+
#
11+
# Notice that tasks will be started based on the cron's system
12+
# daemon's notion of time and timezones.
13+
#
14+
# Output of the crontab jobs (including errors) is sent through
15+
# email to the user the crontab file belongs to (unless redirected).
16+
#
17+
# For example, you can run a backup of all your user accounts
18+
# at 5 a.m every week with:
19+
# 0 5 * * 1 tar -zcf /var/backups/home.tgz /home/
20+
#
21+
# For more information see the manual pages of crontab(5) and cron(8)
22+
#
23+
# m h dom mon dow command
24+
30 2 * * 1 certbot renew --post-hook "cp /etc/letsencrypt/live/svc1.upstage.org.nz/* /etc/mosquitto/ca_certificates && chown -R mosquitto:mosquitto /etc/mosquitto/ca_certificates && systemctl reload mosquitto.service" >> /var/log/le-renew.log 2>&1
25+

system/prod/streaming_nms_app.js

Lines changed: 0 additions & 83 deletions
This file was deleted.

system/prod/upstage.ini

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,6 @@ chmod-socket=777
2020
chdir=/home/upstage/upstage/
2121
module = run_upstage:app
2222
env = PYTHONPATH=/home/upstage/upstage
23-
# NO!!! daemonize=/var/log/uwsgi/upstage.log
23+
# NO!!! daemonize=/var/log/uwsgi/urbn_stripe_webhook.log
2424
logto2 = /var/log/uwsgi/upstage.log
2525

Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,182 @@
1+
<template>
2+
<div class="columns">
3+
<template v-for="(column, i) in columns" :key="column">
4+
<div class="column">
5+
<article class="panel is-light">
6+
<p class="panel-heading">
7+
{{ column }}
8+
<span class="tag is-primary">
9+
{{i==(columns.length-1)? count(i)+1: count(i) }}
10+
</span>
11+
</p>
12+
<div class="panel-heading pt-0">
13+
<p class="control has-icons-left">
14+
<input
15+
class="input is-primary"
16+
type="text"
17+
placeholder="Search"
18+
v-model="searchs[i]"
19+
/>
20+
<span class="icon is-left">
21+
<i class="fas fa-search" aria-hidden="true"></i>
22+
</span>
23+
</p>
24+
</div>
25+
<div class="panel-body">
26+
<a
27+
v-if="i==(columns.length-1)"
28+
class="panel-block owner"
29+
>
30+
{{ renderLabel(owner) }}
31+
<p class="panel-tag">owner</p>
32+
</a>
33+
<template v-for="(item, j) in data" :key="renderValue(item)">
34+
<a
35+
v-if="shouldVisible(j, i)"
36+
class="panel-block"
37+
@click="moveRight(j)"
38+
@contextmenu.prevent="moveLeft(j)"
39+
>
40+
{{ renderLabel(item) }}
41+
</a>
42+
</template>
43+
</div>
44+
</article>
45+
</div>
46+
<div class="column is-narrow px-0" v-if="i < columns.length - 1">
47+
<button class="button is-primary is-small" @click="moveAll(i, i + 1)">
48+
<i class="fas fa-angle-double-right"></i>
49+
</button>
50+
<br />
51+
<br />
52+
<button class="button is-primary is-small" @click="moveAll(i + 1, i)">
53+
<i class="fas fa-angle-double-left"></i>
54+
</button>
55+
</div>
56+
</template>
57+
</div>
58+
</template>
59+
60+
<script>
61+
import { reactive } from "@vue/reactivity";
62+
import { watch } from "@vue/runtime-core";
63+
import { includesIgnoreCase } from "@/utils/common";
64+
export default {
65+
props: {
66+
columns: Number,
67+
modelValue: Array,
68+
data: { type: Array, default: () => [] },
69+
owner: Object,
70+
renderLabel: {
71+
type: Function,
72+
default: (item) => item,
73+
},
74+
renderValue: {
75+
type: Function,
76+
default: (item) => item,
77+
},
78+
renderKeywords: Function,
79+
},
80+
emits: ["update:modelValue"],
81+
setup: (props, { emit }) => {
82+
const positions = reactive([]);
83+
const searchs = reactive([]);
84+
85+
const matchSearch = (item, column) => {
86+
if (!searchs[column]) {
87+
return true;
88+
}
89+
const transform = props.renderKeywords ?? props.renderLabel;
90+
return includesIgnoreCase(transform(props.data[item]), searchs[column]);
91+
};
92+
93+
const shouldVisible = (item, column) => {
94+
return (positions[item] ?? 0) === column && matchSearch(item, column);
95+
};
96+
97+
const moveRight = (item) => {
98+
let currentPosition = positions[item] ?? 0;
99+
if (currentPosition < props.columns.length - 1) {
100+
positions[item] = currentPosition + 1;
101+
}
102+
};
103+
104+
const moveLeft = (item) => {
105+
positions[item] = (positions[item] ?? 1) - 1;
106+
};
107+
108+
watch(positions, () => {
109+
let res = [];
110+
for (let i = 1; i < props.columns.length; i++) {
111+
if (!res[i - 1]) {
112+
res[i - 1] = [];
113+
}
114+
for (let j = 0; j < props.data.length; j++) {
115+
if (positions[j] === i) {
116+
res[i - 1].push(props.renderValue(props.data[j]));
117+
}
118+
}
119+
}
120+
emit("update:modelValue", res);
121+
});
122+
123+
watch(
124+
[() => props.modelValue, () => props.data],
125+
([val]) => {
126+
if (props.data) {
127+
for (let i = 0; i < val.length; i++) {
128+
for (let j = 0; j < (val[i] ?? []).length; j++) {
129+
positions[
130+
props.data.findIndex(
131+
(item) => props.renderValue(item) === val[i][j]
132+
)
133+
] = i + 1;
134+
}
135+
}
136+
}
137+
},
138+
{ immediate: true }
139+
);
140+
141+
const count = (i) =>
142+
props.data
143+
? props.data.filter((item, p) => (positions[p] ?? 0) === i).length
144+
: 0;
145+
146+
const moveAll = (from, to) => {
147+
for (let i = 0; i < props.data.length; i++) {
148+
if ((positions[i] ?? 0) === from && shouldVisible(i, from)) {
149+
positions[i] = to;
150+
}
151+
}
152+
};
153+
154+
return { shouldVisible, moveRight, moveLeft, count, searchs, moveAll };
155+
},
156+
};
157+
</script>
158+
159+
<style scoped>
160+
article.panel {
161+
width: 100%;
162+
}
163+
.panel-heading {
164+
font-size: unset;
165+
}
166+
.panel-body {
167+
max-height: 50vh;
168+
overflow-y: auto !important;
169+
}
170+
.panel-block.owner{
171+
position: relative;
172+
background-color: #00000015;
173+
}
174+
.panel-tag{
175+
position: absolute;
176+
background-color: #007011;
177+
font-size: 0.8rem;
178+
color: #fff;
179+
padding:0 5px;
180+
right: 10px;
181+
}
182+
</style>
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<template>
2+
<button
3+
class="button is-primary"
4+
:class="{ 'is-loading': loading }"
5+
v-bind="$attrs"
6+
>
7+
<slot>
8+
<span class="icon is-small">
9+
<i class="fas fa-download"></i>
10+
</span>
11+
<span>{{ $t("download") }}</span>
12+
</slot>
13+
</button>
14+
</template>
15+
16+
<script>
17+
export default {
18+
props: ["loading"],
19+
};
20+
</script>
21+
22+
<style scoped>
23+
.button {
24+
margin-left: auto;
25+
display: block;
26+
}
27+
</style>

0 commit comments

Comments
 (0)