Skip to content

Commit 7463767

Browse files
committed
Sharing peer is done, fixed #294
Fixed issue #294 with a Vue.js plugin instead of using the `datatime-local` input tag. Still need to work on the end-user UI for sharing.
1 parent 958bc86 commit 7463767

File tree

5 files changed

+136
-45
lines changed

5 files changed

+136
-45
lines changed

src/dashboard.py

+20-20
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,7 @@ def __init__(self, ShareID:str, Configuration: str, Peer: str, ExpireDate: datet
346346
self.Configuration = Configuration
347347
self.ShareDate = ShareDate
348348
self.ExpireDate = ExpireDate
349+
349350

350351
def toJson(self):
351352
return {
@@ -358,10 +359,10 @@ def toJson(self):
358359
class PeerShareLinks:
359360
def __init__(self):
360361
self.Links: list[PeerShareLink] = []
361-
362-
existingTables = cursor.execute("SELECT name FROM sqlite_master WHERE type='table' and name = 'PeerShareLinks'").fetchall()
362+
self.PeerShareLinkCursor = sqldb.cursor()
363+
existingTables = self.PeerShareLinkCursor.execute("SELECT name FROM sqlite_master WHERE type='table' and name = 'PeerShareLinks'").fetchall()
363364
if len(existingTables) == 0:
364-
cursor.execute(
365+
self.PeerShareLinkCursor.execute(
365366
"""
366367
CREATE TABLE PeerShareLinks (
367368
ShareID VARCHAR NOT NULL PRIMARY KEY, Configuration VARCHAR NOT NULL, Peer VARCHAR NOT NULL,
@@ -375,43 +376,40 @@ def __init__(self):
375376
# print(self.Links)
376377
def __getSharedLinks(self):
377378
self.Links.clear()
378-
allLinks = cursor.execute("SELECT * FROM PeerShareLinks WHERE ExpireDate IS NULL OR ExpireDate > datetime('now', 'localtime')").fetchall()
379+
allLinks = self.PeerShareLinkCursor.execute("SELECT * FROM PeerShareLinks WHERE ExpireDate IS NULL OR ExpireDate > datetime('now', 'localtime')").fetchall()
379380
for link in allLinks:
380381
self.Links.append(PeerShareLink(*link))
381382

382383
def getLink(self, Configuration: str, Peer: str) -> list[PeerShareLink]:
384+
self.__getSharedLinks()
383385
return list(filter(lambda x : x.Configuration == Configuration and x.Peer == Peer, self.Links))
384386

385387
def getLinkByID(self, ShareID: str) -> list[PeerShareLink]:
388+
self.__getSharedLinks()
386389
return list(filter(lambda x : x.ShareID == ShareID, self.Links))
387390

388391
def addLink(self, Configuration: str, Peer: str, ExpireDate: datetime = None) -> tuple[bool, str]:
389392
try:
390393
newShareID = str(uuid.uuid4())
391394
if len(self.getLink(Configuration, Peer)) > 0:
392-
cursor.execute("UPDATE PeerShareLinks SET ExpireDate = datetime('now', 'localtime') WHERE Configuration = ? AND Peer = ?", (Configuration, Peer, ))
395+
self.PeerShareLinkCursor.execute("UPDATE PeerShareLinks SET ExpireDate = datetime('now', 'localtime') WHERE Configuration = ? AND Peer = ?", (Configuration, Peer, ))
393396

394-
if ExpireDate is not None:
395-
ExpireDate = datetime.strptime(ExpireDate, '%Y-%m-%d %H:%M:%S')
396-
397-
cursor.execute("INSERT INTO PeerShareLinks (ShareID, Configuration, Peer, ExpireDate) VALUES (?, ?, ?, ?)", (newShareID, Configuration, Peer, ExpireDate, ))
397+
# if ExpireDate is not None:
398+
# ExpireDate = datetime.strptime(ExpireDate, '%Y-%m-%d %H:%M:%S')
399+
400+
self.PeerShareLinkCursor.execute("INSERT INTO PeerShareLinks (ShareID, Configuration, Peer, ExpireDate) VALUES (?, ?, ?, ?)", (newShareID, Configuration, Peer, ExpireDate, ))
398401
sqldb.commit()
399402
self.__getSharedLinks()
400403
except Exception as e:
401404
return False, str(e)
402405
return True, newShareID
403406

404407
def updateLinkExpireDate(self, ShareID, ExpireDate: datetime = None) -> tuple[bool, str]:
405-
try:
406-
if ExpireDate is None:
407-
cursor.execute("UPDATE PeerShareLinks SET ExpireDate = datetime('now', 'localtime') WHERE ShareID = ?", (ShareID, ))
408-
else:
409-
cursor.execute("UPDATE PeerShareLinks SET ExpireDate = ? WHERE ShareID = ?", (ShareID, datetime.strptime(ExpireDate, '%Y-%m-%d %H:%M:%S'), ))
410-
sqldb.commit()
411-
self.__getSharedLinks()
412-
return True
413-
except Exception as e:
414-
return False, str(e)
408+
409+
self.PeerShareLinkCursor.execute("UPDATE PeerShareLinks SET ExpireDate = ? WHERE ShareID = ?;", (ExpireDate, ShareID, ))
410+
sqldb.commit()
411+
self.__getSharedLinks()
412+
return True, ""
415413

416414

417415

@@ -1511,7 +1509,7 @@ def API_newDashboardAPIKey():
15111509
if data['neverExpire']:
15121510
expiredAt = None
15131511
else:
1514-
expiredAt = datetime.strptime(data['ExpiredAt'], '%Y-%m-%dT%H:%M:%S')
1512+
expiredAt = datetime.strptime(data['ExpiredAt'], '%Y-%m-%d %H:%M:%S')
15151513
DashboardConfig.createAPIKeys(expiredAt)
15161514
return ResponseObject(True, data=DashboardConfig.DashboardAPIKeys)
15171515
except Exception as e:
@@ -1594,6 +1592,8 @@ def API_sharePeer_update():
15941592
data: dict[str, str] = request.get_json()
15951593
ShareID: str = data.get("ShareID")
15961594
ExpireDate: str = data.get("ExpireDate")
1595+
print(ShareID)
1596+
print(ExpireDate)
15971597

15981598
if ShareID is None:
15991599
return ResponseObject(False, "Please specify ShareID")

src/static/app/src/components/configurationComponents/peerScheduleJobsComponents/schedulePeerJob.vue

+36-7
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,12 @@ import ScheduleDropdown from "@/components/configurationComponents/peerScheduleJ
33
import {ref} from "vue";
44
import {DashboardConfigurationStore} from "@/stores/DashboardConfigurationStore.js";
55
import {fetchPost} from "@/utilities/fetch.js";
6+
import VueDatePicker from "@vuepic/vue-datepicker";
7+
import dayjs from "dayjs";
68
79
export default {
810
name: "schedulePeerJob",
9-
components: {ScheduleDropdown},
11+
components: {VueDatePicker, ScheduleDropdown},
1012
props: {
1113
dropdowns: Array[Object],
1214
pjob: Object,
@@ -94,6 +96,11 @@ export default {
9496
})
9597
}
9698
this.$emit('delete')
99+
},
100+
parseTime(modelData){
101+
if(modelData){
102+
this.job.Value = dayjs(modelData).format("YYYY-MM-DD HH:mm:ss");
103+
}
97104
}
98105
},
99106
}
@@ -128,12 +135,26 @@ export default {
128135
:data="this.job.Operator"
129136
@update="(value) => this.job.Operator = value"
130137
></ScheduleDropdown>
131-
<input class="form-control form-control-sm form-control-dark rounded-3 flex-grow-1"
132-
:disabled="!edit"
133-
type="datetime-local"
134-
v-if="this.job.Field === 'date'"
135-
v-model="this.job.Value"
136-
style="width: auto">
138+
139+
<VueDatePicker
140+
:is24="true"
141+
:min-date="new Date()"
142+
:model-value="this.job.Value"
143+
@update:model-value="this.parseTime" time-picker-inline
144+
format="yyyy-MM-dd HH:mm:ss"
145+
preview-format="yyyy-MM-dd HH:mm:ss"
146+
:clearable="false"
147+
:disabled="!edit"
148+
v-if="this.job.Field === 'date'"
149+
:dark="this.store.Configuration.Server.dashboard_theme === 'dark'"
150+
/>
151+
152+
<!-- <input class="form-control form-control-sm form-control-dark rounded-3 flex-grow-1"-->
153+
<!-- :disabled="!edit"-->
154+
<!-- type="datetime-local"-->
155+
<!-- v-if="this.job.Field === 'date'"-->
156+
<!-- v-model="this.job.Value"-->
157+
<!-- style="width: auto">-->
137158
<input class="form-control form-control-sm form-control-dark rounded-3 flex-grow-1"
138159
:disabled="!edit"
139160
v-else
@@ -188,4 +209,12 @@ input:disabled{
188209
background-color: rgba(13, 110, 253, 0.09);
189210
color: #0d6efd;
190211
}
212+
213+
.dp__main{
214+
width: auto;
215+
flex-grow: 1;
216+
--dp-input-padding: 2.5px 30px 2.5px 12px;
217+
--dp-border-radius: 0.5rem;
218+
}
219+
191220
</style>

src/static/app/src/components/configurationComponents/peerShareLinkModal.vue

+53-11
Original file line numberDiff line numberDiff line change
@@ -27,17 +27,28 @@ export default {
2727
mounted() {
2828
this.dataCopy = JSON.parse(JSON.stringify(this.peer.ShareLink)).at(0);
2929
},
30+
watch: {
31+
'peer.ShareLink': {
32+
deep: true,
33+
handler(newVal, oldVal){
34+
if (oldVal.length !== newVal.length){
35+
this.dataCopy = JSON.parse(JSON.stringify(this.peer.ShareLink)).at(0);
36+
}
37+
}
38+
}
39+
},
40+
3041
methods: {
3142
startSharing(){
3243
this.loading = true;
3344
fetchPost("/api/sharePeer/create", {
3445
Configuration: this.peer.configuration.Name,
3546
Peer: this.peer.id,
36-
ExpireDate: dayjs().add(30, 'd').format("YYYY-MM-DD hh:mm:ss")
47+
ExpireDate: dayjs().add(7, 'd').format("YYYY-MM-DD HH:mm:ss")
3748
}, (res) => {
3849
if (res.status){
3950
this.peer.ShareLink = res.data;
40-
this.dataCopy = res.data;
51+
this.dataCopy = res.data.at(0);
4152
this.store.newMessage("Server", "Share link created successfully", "success")
4253
}else{
4354
this.store.newMessage("Server",
@@ -49,8 +60,29 @@ export default {
4960
},
5061
updateLinkExpireDate(){
5162
fetchPost("/api/sharePeer/update", this.dataCopy, (res) => {
52-
console.log(res)
53-
})
63+
if (res.status){
64+
this.dataCopy = res.data.at(0)
65+
this.peer.ShareLink = res.data;
66+
this.store.newMessage("Server", "Link expire date updated", "success")
67+
}else{
68+
this.store.newMessage("Server",
69+
"Link expire date failed to update. Reason: " + res.message, "danger")
70+
}
71+
this.loading = false
72+
});
73+
},
74+
stopSharing(){
75+
this.loading = true;
76+
this.dataCopy.ExpireDate = dayjs().format("YYYY-MM-DD HH:mm:ss")
77+
this.updateLinkExpireDate()
78+
},
79+
parseTime(modelData){
80+
if(modelData){
81+
this.dataCopy.ExpireDate = dayjs(modelData).format("YYYY-MM-DD HH:mm:ss");
82+
}else{
83+
this.dataCopy.ExpireDate = undefined
84+
}
85+
this.updateLinkExpireDate()
5486
}
5587
},
5688
computed: {
@@ -60,11 +92,6 @@ export default {
6092
+ this.$router.resolve(
6193
{path: "/share", query: {"ShareID": this.dataCopy.ShareID}}).href;
6294
}
63-
},
64-
watch: {
65-
'dataCopy.ExpireDate'(){
66-
this.updateLinkExpireDate()
67-
}
6895
}
6996
}
7097
</script>
@@ -101,16 +128,31 @@ export default {
101128
{{ getUrl }}
102129
</a>
103130
</div>
104-
<div class="d-flex flex-column gap-2">
131+
<div class="d-flex flex-column gap-2 mb-3">
105132
<small>
106133
<i class="bi bi-calendar me-2"></i>
107134
Expire Date
108135
</small>
109-
<VueDatePicker v-model="this.dataCopy.ExpireDate" time-picker-inline
136+
<VueDatePicker
137+
:is24="true"
138+
:min-date="new Date()"
139+
:model-value="this.dataCopy.ExpireDate"
140+
@update:model-value="this.parseTime" time-picker-inline
110141
format="yyyy-MM-dd HH:mm:ss"
142+
preview-format="yyyy-MM-dd HH:mm:ss"
143+
111144
:dark="this.store.Configuration.Server.dashboard_theme === 'dark'"
112145
/>
113146
</div>
147+
<button
148+
@click="this.stopSharing()"
149+
:disabled="this.loading"
150+
class="w-100 btn bg-danger-subtle text-danger-emphasis border-1 border-danger-subtle rounded-3 shadow-sm">
151+
<span :class="{'animate__animated animate__flash animate__infinite animate__slower': this.loading}">
152+
<i class="bi bi-send-slash-fill me-2" ></i>
153+
</span>
154+
{{this.loading ? "Stop Sharing...":"Stop Sharing"}}
155+
</button>
114156
</div>
115157
</div>
116158
</div>

src/static/app/src/components/settingsComponent/dashboardAPIKeysComponents/newDashboardAPIKey.vue

+22-6
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,15 @@
22
import dayjs from "dayjs";
33
import {fetchPost} from "@/utilities/fetch.js";
44
import {DashboardConfigurationStore} from "@/stores/DashboardConfigurationStore.js";
5+
import VueDatePicker from "@vuepic/vue-datepicker";
56
67
export default {
78
name: "newDashboardAPIKey",
9+
components: {VueDatePicker},
810
data(){
911
return{
1012
newKeyData:{
11-
ExpiredAt: dayjs().add(1, 'd').format("YYYY-MM-DDTHH:mm:ss"),
13+
ExpiredAt: dayjs().add(7, 'd').format("YYYY-MM-DD HH:mm:ss"),
1214
neverExpire: false
1315
},
1416
submitting: false
@@ -39,6 +41,13 @@ export default {
3941
fixDate(date){
4042
console.log(dayjs(date).format("YYYY-MM-DDTHH:mm:ss"))
4143
return dayjs(date).format("YYYY-MM-DDTHH:mm:ss")
44+
},
45+
parseTime(modelData){
46+
if(modelData){
47+
this.newKeyData.ExpiredAt = dayjs(modelData).format("YYYY-MM-DD HH:mm:ss");
48+
}else{
49+
this.newKeyData.ExpiredAt = undefined
50+
}
4251
}
4352
}
4453
}
@@ -49,16 +58,23 @@ export default {
4958
style="background-color: #00000060; backdrop-filter: blur(3px)">
5059
<div class="card m-auto rounded-3 mt-5">
5160
<div class="card-header bg-transparent d-flex align-items-center gap-2 border-0 p-4 pb-0">
52-
Create API Key
61+
<h6 class="mb-0">Create API Key</h6>
5362
<button type="button" class="btn-close ms-auto" @click="this.$emit('close')"></button>
5463
</div>
5564
<div class="card-body d-flex gap-2 p-4 flex-column">
5665
<small class="text-muted">When should this API Key expire?</small>
5766
<div class="d-flex align-items-center gap-2">
58-
<input class="form-control" type="datetime-local"
59-
@change="this.newKeyData.ExpiredAt = this.fixDate(this.newKeyData.ExpiredAt)"
60-
:disabled="this.newKeyData.neverExpire || this.submitting"
61-
v-model="this.newKeyData.ExpiredAt">
67+
<VueDatePicker
68+
:is24="true"
69+
:min-date="new Date()"
70+
:model-value="this.newKeyData.ExpiredAt"
71+
@update:model-value="this.parseTime" time-picker-inline
72+
format="yyyy-MM-dd HH:mm:ss"
73+
preview-format="yyyy-MM-dd HH:mm:ss"
74+
:clearable="false"
75+
:disabled="this.newKeyData.neverExpire || this.submitting"
76+
:dark="this.store.Configuration.Server.dashboard_theme === 'dark'"
77+
/>
6278
</div>
6379
<div class="form-check">
6480
<input class="form-check-input" type="checkbox"

src/static/css/dashboard.css

+5-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
*,
1+
/**{*/
2+
/* font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";*/
3+
/*}*/
4+
25
.dp__input{
36
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol" !important;
47
}
@@ -1125,6 +1128,7 @@ pre.index-alert {
11251128
background-color: #00000060;
11261129
z-index: 9999;
11271130
backdrop-filter: blur(1px);
1131+
-webkit-backdrop-filter: blur(1px);
11281132
}
11291133

11301134
.dashboardModal{

0 commit comments

Comments
 (0)