mirror of
https://git.cyberia.club/cyberia/matrix-synapse-diskspace-janitor
synced 2024-05-20 01:16:33 +02:00
adding room names
This commit is contained in:
parent
cd9f34ee75
commit
a2eec17b5f
|
@ -32,7 +32,7 @@ func GetTotalFilesizeWithinFolder(path string) (int64, error) {
|
||||||
func getTotalFilesizeWithinFolderRecurse(currentPath string, info os.FileInfo) (int64, error) {
|
func getTotalFilesizeWithinFolderRecurse(currentPath string, info os.FileInfo) (int64, error) {
|
||||||
|
|
||||||
size := info.Size()
|
size := info.Size()
|
||||||
if info.Mode().IsRegular() {
|
if info.Mode().IsRegular() && !info.IsDir() {
|
||||||
return size, nil
|
return size, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,14 +49,14 @@ func getTotalFilesizeWithinFolderRecurse(currentPath string, info os.FileInfo) (
|
||||||
}
|
}
|
||||||
for _, fi := range fis {
|
for _, fi := range fis {
|
||||||
if fi.Name() != "." && fi.Name() != ".." {
|
if fi.Name() != "." && fi.Name() != ".." {
|
||||||
continue
|
subfolderSize, err := getTotalFilesizeWithinFolderRecurse(filepath.Join(currentPath, fi.Name()), fi)
|
||||||
}
|
if err != nil {
|
||||||
subfolderSize, err := getTotalFilesizeWithinFolderRecurse(filepath.Join(currentPath, fi.Name()), fi)
|
return -1, err
|
||||||
if err != nil {
|
} else {
|
||||||
return -1, err
|
size += subfolderSize
|
||||||
} else {
|
}
|
||||||
size += subfolderSize
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
56
frontend.go
56
frontend.go
|
@ -14,6 +14,7 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
@ -37,6 +38,13 @@ type FrontendApp struct {
|
||||||
cssHash string
|
cssHash string
|
||||||
basicURLPathRegex *regexp.Regexp
|
basicURLPathRegex *regexp.Regexp
|
||||||
base58Regex *regexp.Regexp
|
base58Regex *regexp.Regexp
|
||||||
|
roomNameCache map[string]string
|
||||||
|
}
|
||||||
|
|
||||||
|
type MatrixRoom struct {
|
||||||
|
Id string
|
||||||
|
Name string
|
||||||
|
Rows int
|
||||||
}
|
}
|
||||||
|
|
||||||
func initFrontend(config *Config) FrontendApp {
|
func initFrontend(config *Config) FrontendApp {
|
||||||
|
@ -56,6 +64,7 @@ func initFrontend(config *Config) FrontendApp {
|
||||||
basicURLPathRegex: regexp.MustCompile("(?i)[a-z0-9/?&_+-]+"),
|
basicURLPathRegex: regexp.MustCompile("(?i)[a-z0-9/?&_+-]+"),
|
||||||
base58Regex: regexp.MustCompile("(?i)[a-z0-9_-]+"),
|
base58Regex: regexp.MustCompile("(?i)[a-z0-9_-]+"),
|
||||||
cssHash: cssHash,
|
cssHash: cssHash,
|
||||||
|
roomNameCache: map[string]string{},
|
||||||
}
|
}
|
||||||
|
|
||||||
// serve the homepage
|
// serve the homepage
|
||||||
|
@ -72,16 +81,51 @@ func initFrontend(config *Config) FrontendApp {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
(*session.Flash)["error"] = "an error occurred reading dbTableSizes json"
|
(*session.Flash)["error"] = "an error occurred reading dbTableSizes json"
|
||||||
}
|
}
|
||||||
rowCountByRoom, err := os.ReadFile("data/stateGroupsStateRowCountByRoom.json")
|
|
||||||
|
rowCountByRoomObject, err := ReadJsonFile[map[string]int]("data/stateGroupsStateRowCountByRoom.json")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
(*session.Flash)["error"] = "an error occurred reading rowCountByRoom json"
|
(*session.Flash)["error"] = "an error occurred reading rowCountByRoom json object"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
roomsSlice := []MatrixRoom{}
|
||||||
|
totalRowCount := 0
|
||||||
|
for roomId, rows := range rowCountByRoomObject {
|
||||||
|
totalRowCount += rows
|
||||||
|
if rows > 10000 {
|
||||||
|
roomsSlice = append(roomsSlice, MatrixRoom{
|
||||||
|
Id: roomId,
|
||||||
|
Rows: rows,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sort.Slice(roomsSlice, func(i, j int) bool {
|
||||||
|
return roomsSlice[i].Rows > roomsSlice[j].Rows
|
||||||
|
})
|
||||||
|
|
||||||
|
biggestRooms := roomsSlice[0:6]
|
||||||
|
bigRoomsRowCount := 0
|
||||||
|
for _, room := range biggestRooms {
|
||||||
|
name, err := matrixAdmin.GetRoomName(room.Id)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("error getting name for '%s': %s\n", room.Id, err)
|
||||||
|
}
|
||||||
|
room.Name = name
|
||||||
|
bigRoomsRowCount += room.Rows
|
||||||
|
}
|
||||||
|
|
||||||
|
biggestRooms = append(biggestRooms, MatrixRoom{
|
||||||
|
Name: "Others",
|
||||||
|
Rows: totalRowCount - bigRoomsRowCount,
|
||||||
|
})
|
||||||
|
|
||||||
|
bigRoomsBytes, _ := json.Marshal(biggestRooms)
|
||||||
|
log.Println(string(bigRoomsBytes))
|
||||||
|
|
||||||
panelTemplateData := struct {
|
panelTemplateData := struct {
|
||||||
DiskUsage template.JS
|
DiskUsage template.JS
|
||||||
DBTableSizes template.JS
|
DBTableSizes template.JS
|
||||||
RowCountByRoom template.JS
|
BigRooms template.JS
|
||||||
}{template.JS(diskUsage), template.JS(dbTableSizes), template.JS(rowCountByRoom)}
|
}{template.JS(diskUsage), template.JS(dbTableSizes), template.JS(bigRoomsBytes)}
|
||||||
|
|
||||||
app.buildPageFromTemplate(responseWriter, request, session, "panel.html", panelTemplateData)
|
app.buildPageFromTemplate(responseWriter, request, session, "panel.html", panelTemplateData)
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="chart-container">
|
<div class="chart-container">
|
||||||
<h3>matrix rooms</h3>
|
<h3>state_groups_state by room</h3>
|
||||||
<canvas id="chart3" width="350" height="550"></canvas>
|
<canvas id="chart3" width="350" height="550"></canvas>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@
|
||||||
|
|
||||||
const diskUsage = {{ .DiskUsage }};
|
const diskUsage = {{ .DiskUsage }};
|
||||||
const dbTableSizes = {{ .DBTableSizes }};
|
const dbTableSizes = {{ .DBTableSizes }};
|
||||||
const rowCountByRoom = {{ .RowCountByRoom }};
|
const bigRooms = {{ .BigRooms }};
|
||||||
|
|
||||||
// disk space chart
|
// disk space chart
|
||||||
|
|
||||||
|
@ -51,22 +51,22 @@
|
||||||
return b.Bytes - a.Bytes;
|
return b.Bytes - a.Bytes;
|
||||||
});
|
});
|
||||||
|
|
||||||
const top8Tables = dbTableSizes.slice(0, 7);
|
const top7Tables = dbTableSizes.slice(0, 6);
|
||||||
const others = dbTableSizes.slice(7, dbTableSizes.length)
|
const others = dbTableSizes.slice(6, dbTableSizes.length)
|
||||||
top8Tables.push({
|
top7Tables.push({
|
||||||
Name: "others",
|
Name: "others",
|
||||||
Bytes: others.reduce((accumulator, table) => accumulator + table.Bytes, 0)
|
Bytes: others.reduce((accumulator, table) => accumulator + table.Bytes, 0)
|
||||||
})
|
})
|
||||||
|
|
||||||
const totalBytes = top8Tables.reduce((accumulator, table) => accumulator + table.Bytes, 0);
|
const totalBytes = top7Tables.reduce((accumulator, table) => accumulator + table.Bytes, 0);
|
||||||
|
|
||||||
new Chart(document.getElementById('chart2'), {
|
new Chart(document.getElementById('chart2'), {
|
||||||
type: 'doughnut',
|
type: 'doughnut',
|
||||||
data: {
|
data: {
|
||||||
labels: top8Tables.map(table => table.Name),
|
labels: top7Tables.map(table => table.Name),
|
||||||
datasets: [{
|
datasets: [{
|
||||||
label: 'filesize %',
|
label: 'filesize %',
|
||||||
data: top8Tables.map(table => Math.round((table.Bytes/totalBytes)*100)),
|
data: top7Tables.map(table => Math.round((table.Bytes/totalBytes)*100)),
|
||||||
borderWidth: 2
|
borderWidth: 2
|
||||||
}]
|
}]
|
||||||
},
|
},
|
||||||
|
@ -77,28 +77,15 @@
|
||||||
|
|
||||||
|
|
||||||
// matrix room size chart
|
// matrix room size chart
|
||||||
const rooms = Object.entries(rowCountByRoom).map(entry => ({roomid: entry[0], rows: entry[1]}));
|
const totalRows = bigRooms.reduce((accumulator, room) => accumulator + room.Rows, 0);
|
||||||
|
|
||||||
rooms.sort((a, b) => {
|
|
||||||
return b.rows - a.rows;
|
|
||||||
});
|
|
||||||
|
|
||||||
const top8Rooms = rooms.slice(0, 7);
|
|
||||||
const otherRooms = rooms.slice(7, rooms.length)
|
|
||||||
top8Rooms.push({
|
|
||||||
roomid: "others",
|
|
||||||
rows: otherRooms.reduce((accumulator, table) => accumulator + table.rows, 0)
|
|
||||||
})
|
|
||||||
|
|
||||||
const totalRows = top8Rooms.reduce((accumulator, table) => accumulator + table.rows, 0);
|
|
||||||
|
|
||||||
new Chart(document.getElementById('chart3'), {
|
new Chart(document.getElementById('chart3'), {
|
||||||
type: 'doughnut',
|
type: 'doughnut',
|
||||||
data: {
|
data: {
|
||||||
labels: top8Rooms.map(table => table.roomid),
|
labels: bigRooms.map(room => room.Name),
|
||||||
datasets: [{
|
datasets: [{
|
||||||
label: '%',
|
label: '%',
|
||||||
data: top8Rooms.map(table => Math.round((table.rows/totalRows)*100)),
|
data: bigRooms.map(room => Math.round((room.Rows/totalRows)*100)),
|
||||||
borderWidth: 2
|
borderWidth: 2
|
||||||
}]
|
}]
|
||||||
},
|
},
|
||||||
|
|
|
@ -67,6 +67,11 @@ type RoomMembersResponseBody struct {
|
||||||
Members []string `json:"members"`
|
Members []string `json:"members"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type RoomDetails struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
CanonicalAlias string `json:"canonical_alias"`
|
||||||
|
}
|
||||||
|
|
||||||
func initMatrixAdmin(config *Config) *MatrixAdmin {
|
func initMatrixAdmin(config *Config) *MatrixAdmin {
|
||||||
|
|
||||||
return &MatrixAdmin{
|
return &MatrixAdmin{
|
||||||
|
@ -212,6 +217,45 @@ func (admin *MatrixAdmin) GetDeleteRoomStatus(roomId string) (string, []string,
|
||||||
return mostCompleteStatus, usersSlice, nil
|
return mostCompleteStatus, usersSlice, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (admin *MatrixAdmin) GetRoomName(roomId string) (string, error) {
|
||||||
|
|
||||||
|
urlWithoutToken := fmt.Sprintf(
|
||||||
|
"%s/_synapse/admin/v1/rooms/%s/members?access_token=",
|
||||||
|
admin.URL, admin.AdminMatrixRoomId,
|
||||||
|
)
|
||||||
|
url := fmt.Sprintf("%s%s", urlWithoutToken, admin.Token)
|
||||||
|
response, err := admin.Client.Get(url)
|
||||||
|
if err != nil {
|
||||||
|
return "", errors.Wrapf(err, "HTTP GET %sxxxxxxx", urlWithoutToken)
|
||||||
|
}
|
||||||
|
|
||||||
|
responseBody, err := ioutil.ReadAll(response.Body)
|
||||||
|
if err != nil {
|
||||||
|
return "", errors.Wrapf(err, "HTTP GET %sxxxxxxx read error", urlWithoutToken)
|
||||||
|
}
|
||||||
|
|
||||||
|
if response.StatusCode != 200 {
|
||||||
|
return "", fmt.Errorf(
|
||||||
|
"HTTP GET %sxxxxxxx: HTTP %d: %s",
|
||||||
|
urlWithoutToken, response.StatusCode, string(responseBody),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
var responseObject RoomDetails
|
||||||
|
err = json.Unmarshal(responseBody, &responseObject)
|
||||||
|
if err != nil {
|
||||||
|
return "", errors.Wrapf(err, "HTTP GET %sxxxxxxxxx response json parse error", urlWithoutToken)
|
||||||
|
}
|
||||||
|
|
||||||
|
if responseObject.CanonicalAlias != "" {
|
||||||
|
return responseObject.CanonicalAlias, nil
|
||||||
|
}
|
||||||
|
if responseObject.Name != "" {
|
||||||
|
return responseObject.Name, nil
|
||||||
|
}
|
||||||
|
return roomId, nil
|
||||||
|
}
|
||||||
|
|
||||||
// curl 'https://matrix.cyberia.club/_matrix/client/r0/login' -X POST -H 'Accept: application/json' -H 'content-type: application/json'
|
// curl 'https://matrix.cyberia.club/_matrix/client/r0/login' -X POST -H 'Accept: application/json' -H 'content-type: application/json'
|
||||||
// --data-raw '{"type":"m.login.password","password":"xxxxxxxxx","identifier":{"type":"m.id.user","user":"forestjohnson"},"initial_device_display_name":"chat.cyberia.club (Firefox, Ubuntu)"}'
|
// --data-raw '{"type":"m.login.password","password":"xxxxxxxxx","identifier":{"type":"m.id.user","user":"forestjohnson"},"initial_device_display_name":"chat.cyberia.club (Firefox, Ubuntu)"}'
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue