From b040eb9e1e185ce7056dda1786782faf39382a0e Mon Sep 17 00:00:00 2001 From: divyam234 <47589864+divyam234@users.noreply.github.com> Date: Sun, 3 Dec 2023 02:53:06 +0530 Subject: [PATCH] api changes --- .github/workflows/dev.yml | 35 ----- .goreleaser.yaml | 3 + .vscode/launch.json | 2 +- api/router.go | 5 +- cmd/teldrive/main.go | 11 +- go.mod | 3 + go.sum | 6 + internal/logger/logger.go | 2 +- pkg/database/database.go | 3 +- .../migrations/20230817172319_init.sql | 93 ++++++------ .../migrations/20230817172325_tables.sql | 88 ------------ .../migrations/20230817172329_functions.sql | 116 --------------- .../migrations/20230911113332_alter_table.sql | 7 - .../migrations/20230916012507_tables.sql | 27 ---- .../20230918234353_account_stats.sql | 22 --- .../migrations/20230927152733_alter_bots.sql | 7 - .../20231031220919_create_dirs_from_path.sql | 49 ------- .../20231031223444_alter_uploads.sql | 3 - .../migrations/20231102165658_tables.sql | 90 +++++++++++- .../migrations/20231104192800_functions.sql | 136 +++++++++++++++++- pkg/services/common.go | 2 +- ui/teldrive-ui | 2 +- 22 files changed, 284 insertions(+), 428 deletions(-) delete mode 100644 .github/workflows/dev.yml delete mode 100644 pkg/database/migrations/20230817172325_tables.sql delete mode 100644 pkg/database/migrations/20230817172329_functions.sql delete mode 100644 pkg/database/migrations/20230911113332_alter_table.sql delete mode 100644 pkg/database/migrations/20230916012507_tables.sql delete mode 100644 pkg/database/migrations/20230918234353_account_stats.sql delete mode 100644 pkg/database/migrations/20230927152733_alter_bots.sql delete mode 100644 pkg/database/migrations/20231031220919_create_dirs_from_path.sql delete mode 100644 pkg/database/migrations/20231031223444_alter_uploads.sql diff --git a/.github/workflows/dev.yml b/.github/workflows/dev.yml deleted file mode 100644 index 9dc41fe..0000000 --- a/.github/workflows/dev.yml +++ /dev/null @@ -1,35 +0,0 @@ -# .github/workflows/release.yaml - -on: - workflow_dispatch: - -jobs: - releases-matrix: - name: Release Go Binary - permissions: - contents: write - packages: write - runs-on: ubuntu-latest - strategy: - matrix: - goos: [linux] - goarch: [amd64] - steps: - - name: Checkout - uses: actions/checkout@v3 - with: - fetch-depth: 0 - submodules: true - - - uses: divyam234/go-release-action@master - with: - github_token: ${{ secrets.GITHUB_TOKEN }} - goos: ${{ matrix.goos }} - goarch: ${{ matrix.goarch }} - binary_name: "teldrive" - extra_files: LICENSE README.md - goversion: "https://dl.google.com/go/go1.21.1.linux-amd64.tar.gz" - pre_command: make pre-ui && make ui && export CGO_ENABLED=0 - release_tag: canary - overwrite: true - ldflags: -s -w -extldflags=-static \ No newline at end of file diff --git a/.goreleaser.yaml b/.goreleaser.yaml index ff7de0a..299033e 100644 --- a/.goreleaser.yaml +++ b/.goreleaser.yaml @@ -9,6 +9,9 @@ before: builds: - env: - CGO_ENABLED=0 + main: + - cmd/teldrive/main.go + flags: - -trimpath ldflags: diff --git a/.vscode/launch.json b/.vscode/launch.json index 6deb9a6..ab21f50 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -9,7 +9,7 @@ "type": "go", "request": "launch", "mode": "auto", - "program": "main.go" + "program": "cmd/teldrive/main.go" } ] } \ No newline at end of file diff --git a/api/router.go b/api/router.go index 0383af7..49e0659 100644 --- a/api/router.go +++ b/api/router.go @@ -13,9 +13,6 @@ func InitRouter() *gin.Engine { r.Use(gin.Logger()) - // if gin.Mode() == gin.ReleaseMode { - // r.Use(middleware.Security()) - // } r.Use(middleware.Cors()) c := controller.NewController() @@ -54,7 +51,7 @@ func InitRouter() *gin.Engine { } users := api.Group("/users") { - uploads.Use(middleware.Authmiddleware) + users.Use(middleware.Authmiddleware) users.GET("/profile", c.GetProfilePhoto) users.GET("/stats", c.Stats) users.GET("/bots", c.GetBots) diff --git a/cmd/teldrive/main.go b/cmd/teldrive/main.go index 9ac9646..09a571f 100644 --- a/cmd/teldrive/main.go +++ b/cmd/teldrive/main.go @@ -4,11 +4,14 @@ import ( "fmt" "mime" "path/filepath" + "time" "github.com/divyam234/teldrive/api" + "github.com/divyam234/teldrive/internal/cron" "github.com/divyam234/teldrive/internal/logger" "github.com/divyam234/teldrive/internal/utils" "github.com/divyam234/teldrive/pkg/database" + "github.com/go-co-op/gocron" cnf "github.com/divyam234/teldrive/config" "github.com/divyam234/teldrive/internal/cache" @@ -27,13 +30,13 @@ func main() { cache.InitCache() - // scheduler := gocron.NewScheduler(time.UTC) + scheduler := gocron.NewScheduler(time.UTC) - // scheduler.Every(1).Hour().Do(cron.FilesDeleteJob) + scheduler.Every(1).Hour().Do(cron.FilesDeleteJob) - // scheduler.Every(12).Hour().Do(cron.UploadCleanJob) + scheduler.Every(12).Hour().Do(cron.UploadCleanJob) - // scheduler.StartAsync() + scheduler.StartAsync() mime.AddExtensionType(".js", "application/javascript") diff --git a/go.mod b/go.mod index 3f5e039..d6e9037 100644 --- a/go.mod +++ b/go.mod @@ -26,7 +26,10 @@ require ( require ( github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/chenzhuoyu/iasm v0.9.1 // indirect + github.com/go-co-op/gocron v1.36.0 // indirect + github.com/google/uuid v1.4.0 // indirect github.com/jackc/puddle/v2 v2.2.1 // indirect + github.com/robfig/cron/v3 v3.0.1 // indirect github.com/sethvargo/go-retry v0.2.4 // indirect golang.org/x/tools v0.16.0 // indirect ) diff --git a/go.sum b/go.sum index 73ce0a7..8b8c50d 100644 --- a/go.sum +++ b/go.sum @@ -64,6 +64,8 @@ github.com/gin-gonic/gin v1.5.0/go.mod h1:Nd6IXA8m5kNZdNEHMBd93KT+mdY3+bewLgRvmC github.com/gin-gonic/gin v1.8.1/go.mod h1:ji8BvRH1azfM+SYow9zQ6SZMvR8qOMZHmsCuWR9tTTk= github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg= github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU= +github.com/go-co-op/gocron v1.36.0 h1:sEmAwg57l4JWQgzaVWYfKZ+w13uHOqeOtwjo72Ll5Wc= +github.com/go-co-op/gocron v1.36.0/go.mod h1:3L/n6BkO7ABj+TrfSVXLRzsP26zmikL4ISkLQ0O8iNY= github.com/go-faster/city v1.0.1 h1:4WAxSZ3V2Ws4QRDrscLEDcibJY8uf41H6AhXDrNDcGw= github.com/go-faster/city v1.0.1/go.mod h1:jKcUJId49qdW3L1qKHH/3wPeUstCVpVSXTM6vO3VcTw= github.com/go-faster/errors v0.7.0 h1:UnD/xusnfUgtEYkgRZohqL2AfmPTwv13NAJwwFFaNYc= @@ -209,8 +211,11 @@ github.com/quantumsheep/range-parser v1.1.0 h1:k4f1F58f8FF54FBYc9dYBRM+8JkAxFo11 github.com/quantumsheep/range-parser v1.1.0/go.mod h1:acv4Vt2PvpGvRsvGju7Gk2ahKluZJsIUNR69W53J22I= github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE= github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= +github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs= +github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro= github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= +github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o= github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= github.com/segmentio/asm v1.2.0 h1:9BQrFxC+YOHJlTlHGkTrFWf59nbL3XnCoFLTwDCI7ys= @@ -262,6 +267,7 @@ go.opentelemetry.io/otel v1.20.0 h1:vsb/ggIY+hUjD/zCAQHpzTmndPqv/ml2ArbsbfBYTAc= go.opentelemetry.io/otel v1.20.0/go.mod h1:oUIGj3D77RwJdM6PPZImDpSZGDvkD9fhesHny69JFrs= go.opentelemetry.io/otel/trace v1.20.0 h1:+yxVAPZPbQhbC3OfAkeIVTky6iTFpcr4SiY9om7mXSQ= go.opentelemetry.io/otel/trace v1.20.0/go.mod h1:HJSK7F/hA5RlzpZ0zKDCHCDHm556LCDtKaAo6JmBFUU= +go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk= diff --git a/internal/logger/logger.go b/internal/logger/logger.go index adccc27..0ac8e35 100644 --- a/internal/logger/logger.go +++ b/internal/logger/logger.go @@ -13,7 +13,7 @@ func InitLogger() { config := zap.NewProductionEncoderConfig() config.EncodeTime = zapcore.ISO8601TimeEncoder consoleEncoder := zapcore.NewConsoleEncoder(config) - defaultLogLevel := zapcore.DebugLevel + defaultLogLevel := zapcore.InfoLevel core := zapcore.NewCore(consoleEncoder, zapcore.AddSync(os.Stdout), defaultLogLevel) Logger = zap.New(core, zap.AddCaller(), zap.AddStacktrace(zapcore.ErrorLevel)) } diff --git a/pkg/database/database.go b/pkg/database/database.go index e8b0741..61694b2 100644 --- a/pkg/database/database.go +++ b/pkg/database/database.go @@ -61,10 +61,9 @@ func InitDB() { } sqlDB.SetMaxIdleConns(25) sqlDB.SetMaxOpenConns(25) + sqlDB.SetConnMaxIdleTime(10 * time.Minute) - sqlDB.SetConnMaxLifetime(time.Hour) go func() { - DB.Exec(`create collation if not exists numeric (provider = icu, locale = 'en@colnumeric=yes');`) if config.RunMigrations { migrate() } diff --git a/pkg/database/migrations/20230817172319_init.sql b/pkg/database/migrations/20230817172319_init.sql index 69fc7ad..e6a1296 100644 --- a/pkg/database/migrations/20230817172319_init.sql +++ b/pkg/database/migrations/20230817172319_init.sql @@ -1,66 +1,55 @@ -- +goose Up -create extension if not exists pgcrypto; -create extension if not exists btree_gin; +CREATE EXTENSION IF NOT EXISTS pgcrypto; -create schema if not exists teldrive; +CREATE EXTENSION IF NOT EXISTS btree_gin; -create collation if not exists numeric (provider = icu, locale = 'en@colnumeric=yes'); +CREATE SCHEMA IF NOT EXISTS teldrive; + +CREATE COLLATION IF NOT EXISTS numeric (PROVIDER = ICU, LOCALE = 'en@colnumeric=yes'); -- +goose StatementBegin -create or replace -function teldrive.generate_uid(size int) returns text language plpgsql as $$ -declare characters text := 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; -bytes bytea := gen_random_bytes(size); +CREATE OR REPLACE +FUNCTION teldrive.generate_uid(size INT) RETURNS TEXT LANGUAGE PLPGSQL AS $$ +DECLARE + characters TEXT := 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; + bytes BYTEA := gen_random_bytes(size); + l INT := LENGTH(characters); + i INT := 0; + output TEXT := ''; +BEGIN + WHILE i < size LOOP + output := output || SUBSTR(characters, GET_BYTE(bytes, i) % l + 1, 1); + i := i + 1; + END LOOP; + RETURN output; +END; +$$; -l int := length(characters); - -i int := 0; - -output text := ''; - -begin while i < size loop output := output || substr(characters, -get_byte(bytes, -i) % l + 1, -1); - -i := i + 1; -end loop; - -return output; -end; +CREATE OR REPLACE +FUNCTION teldrive.get_tsvector(t TEXT) RETURNS TSVECTOR LANGUAGE PLPGSQL IMMUTABLE AS $$ +DECLARE + res TSVECTOR := to_tsvector(regexp_replace(t, '[^A-Za-z0-9 ]', ' ', 'g')); +BEGIN + RETURN res; +END; +$$; +CREATE OR REPLACE +FUNCTION teldrive.get_tsquery(t TEXT) RETURNS TSQUERY LANGUAGE PLPGSQL IMMUTABLE AS $$ +DECLARE + res TSQUERY := CONCAT(plainto_tsquery(regexp_replace(t, '[^A-Za-z0-9 ]', ' ', 'g')), ':*')::TSQUERY; +BEGIN + RETURN res; +END; $$; -- +goose StatementEnd + +-- +goose Down -- +goose StatementBegin -create or replace -function teldrive.get_tsvector(t text) returns tsvector language plpgsql immutable as $$ -declare res tsvector := to_tsvector(regexp_replace(t, -'[^A-Za-z0-9 ]', -' ', -'g')); - -begin return res; -end; - -$$; --- +goose StatementEnd - --- +goose StatementBegin -create or replace -function teldrive.get_tsquery(t text) returns tsquery language plpgsql immutable as $$ -declare res tsquery = concat( -plainto_tsquery(regexp_replace(t, -'[^A-Za-z0-9 ]', -' ', -'g')), -':*' -)::tsquery; - -begin return res; -end; - -$$; +DROP FUNCTION IF EXISTS teldrive.generate_uid; +DROP FUNCTION IF EXISTS teldrive.get_tsvector; +DROP FUNCTION IF EXISTS teldrive.get_tsquery; -- +goose StatementEnd diff --git a/pkg/database/migrations/20230817172325_tables.sql b/pkg/database/migrations/20230817172325_tables.sql deleted file mode 100644 index f392d35..0000000 --- a/pkg/database/migrations/20230817172325_tables.sql +++ /dev/null @@ -1,88 +0,0 @@ --- +goose Up -create table teldrive.files ( -id text primary key not null default teldrive.generate_uid(16), -name text not null, -type text not null, -mime_type text not null, -path text null, -size bigint null, -starred bool not null, -depth integer null, -user_id bigint not null, -parent_id text null, -status text default 'active'::text, -channel_id bigint null, -parts jsonb null, -created_at timestamp not null default timezone('utc'::text, -now()), -updated_at timestamp not null default timezone('utc'::text, -now()), -constraint unique_file unique (name, -parent_id,user_id) -); - -create table teldrive.uploads ( - id text not null primary key default teldrive.generate_uid(16), - upload_id text not null, - name text not null, - part_no int4 not null, - part_id int4 not null, - total_parts int4 not null, - channel_id int8 not null, - size int8 not null, - created_at timestamp null default timezone('utc'::text, -now()) -); - -create table teldrive.users ( - user_id bigint not null primary key, - name text null, - user_name text null, - is_premium bool not null, - tg_session text not null, - settings jsonb null, - created_at timestamptz not null default timezone('utc'::text, -now()), - updated_at timestamptz not null default timezone('utc'::text, -now()) -); - -create collation if not exists numeric (provider = icu, locale = 'en@colnumeric=yes'); -create index name_search_idx on -teldrive.files - using gin (teldrive.get_tsvector(name), -updated_at); - -create index name_numeric_idx on -teldrive.files(name collate numeric nulls first); - -create index parent_name_numeric_idx on -teldrive.files (parent_id, -name collate numeric desc); - -create index path_idx on -teldrive.files (path); - -create index parent_idx on -teldrive.files (parent_id); - -create index starred_updated_at_idx on -teldrive.files (starred, -updated_at desc); - -create index status_idx on teldrive.files (status); - -create index user_id_idx on teldrive.files (user_id); - --- +goose Down -drop table if exists teldrive.files; -drop table if exists teldrive.uploads; -drop table if exists teldrive.users; -drop index if exists teldrive.name_search_idx; -drop index if exists teldrive.name_numeric_idx; -drop index if exists teldrive.parent_name_numeric_idx; -drop index if exists teldrive.path_idx; -drop index if exists teldrive.parent_idx; -drop index if exists teldrive.starred_updated_at_idx; -drop index if exists teldrive.status_idx; -drop index if exists teldrive.user_id_idx; \ No newline at end of file diff --git a/pkg/database/migrations/20230817172329_functions.sql b/pkg/database/migrations/20230817172329_functions.sql deleted file mode 100644 index 74bb0ba..0000000 --- a/pkg/database/migrations/20230817172329_functions.sql +++ /dev/null @@ -1,116 +0,0 @@ --- +goose Up - --- +goose StatementBegin -create procedure teldrive.update_size() language plpgsql as $$ -declare rec record; - -total_size bigint; - -begin - -for rec in -select - id -from - files -where - type = 'folder' -order by - depth desc loop total_size := ( - select - sum(size) as total_size - from - teldrive.files - where - parent_id = rec.id -); - -update - teldrive.files -set - size = total_size -where - id = rec.id; -end loop; -end; - -$$; --- +goose StatementEnd - --- +goose StatementBegin -create procedure teldrive.delete_files(in file_ids text[], -in op text default 'bulk') - language plpgsql -as $$ - declare - rec record; - -begin - if op = 'bulk' then - for rec in -select - id, - type -from - teldrive.files -where - id = any (file_ids) - loop - if rec.type = 'folder' then - call teldrive.delete_files(array [rec.id], - 'single'); - -delete -from - teldrive.files -where - id = rec.id; -else - update - teldrive.files -set - status = 'pending_deletion' -where - id = rec.id; -end if; -end loop; -else - - for rec in -select - id, - type -from - teldrive.files -where - parent_id = file_ids[1] - loop - if rec.type = 'folder' then - call teldrive.delete_files(array [rec.id], - 'single'); - -delete -from - teldrive.files -where - id = rec.id; -else - update - teldrive.files -set - status = 'pending_deletion' -where - id = rec.id; -end if; -end loop; -end if; -end; - -$$ -; --- +goose StatementEnd - - --- +goose Down -drop procedure if exists teldrive.update_size; -drop procedure if exists teldrive.delete_files; \ No newline at end of file diff --git a/pkg/database/migrations/20230911113332_alter_table.sql b/pkg/database/migrations/20230911113332_alter_table.sql deleted file mode 100644 index bb91bec..0000000 --- a/pkg/database/migrations/20230911113332_alter_table.sql +++ /dev/null @@ -1,7 +0,0 @@ --- +goose Up - -ALTER TABLE teldrive.files DROP CONSTRAINT IF EXISTS unique_file; - -ALTER TABLE teldrive.users DROP COLUMN settings; - -CREATE UNIQUE INDEX unique_file ON teldrive.files (name, parent_id, user_id) WHERE (status= 'active'); diff --git a/pkg/database/migrations/20230916012507_tables.sql b/pkg/database/migrations/20230916012507_tables.sql deleted file mode 100644 index 21a2e43..0000000 --- a/pkg/database/migrations/20230916012507_tables.sql +++ /dev/null @@ -1,27 +0,0 @@ --- +goose Up --- +goose StatementBegin - -CREATE TABLE teldrive.bots ( - user_id bigint NOT NULL, - token text NOT NULL, - bot_user_name text NOT NULL, - bot_id bigint NOT NULL, - FOREIGN KEY (user_id) REFERENCES teldrive.users(user_id), - CONSTRAINT btoken_user_un UNIQUE (user_id,token) -); - -CREATE TABLE teldrive.channels ( - channel_id bigint NOT NULL PRIMARY KEY, - channel_name text NOT NULL, - user_id bigint NOT NULL, - selected boolean DEFAULT false, - FOREIGN KEY (user_id) REFERENCES teldrive.users(user_id) -); - --- +goose StatementEnd - --- +goose Down --- +goose StatementBegin -DROP TABLE IF EXISTS teldrive.bots; -DROP TABLE IF EXISTS teldrive.channels; --- +goose StatementEnd diff --git a/pkg/database/migrations/20230918234353_account_stats.sql b/pkg/database/migrations/20230918234353_account_stats.sql deleted file mode 100644 index a15d258..0000000 --- a/pkg/database/migrations/20230918234353_account_stats.sql +++ /dev/null @@ -1,22 +0,0 @@ --- +goose Up --- +goose StatementBegin -CREATE OR REPLACE FUNCTION teldrive.account_stats( - IN u_id BIGINT -) RETURNS TABLE (total_size BIGINT, total_files BIGINT, ch_id BIGINT,ch_name TEXT ) AS $$ -DECLARE - total_size BIGINT; - total_files BIGINT; - ch_id BIGINT; - ch_name TEXT; -BEGIN - SELECT COUNT(*), SUM(size) into total_files,total_size FROM teldrive.files WHERE user_id=u_id AND type= 'file' and status='active'; - SELECT channel_id ,channel_name into ch_id,ch_name FROM teldrive.channels WHERE selected=TRUE AND user_id=u_id; - RETURN QUERY SELECT total_size,total_files,ch_id,ch_name; -END; -$$ LANGUAGE plpgsql; --- +goose StatementEnd - --- +goose Down --- +goose StatementBegin -DROP FUNCTION IF EXISTS teldrive.account_stats; --- +goose StatementEnd diff --git a/pkg/database/migrations/20230927152733_alter_bots.sql b/pkg/database/migrations/20230927152733_alter_bots.sql deleted file mode 100644 index 25f5bf9..0000000 --- a/pkg/database/migrations/20230927152733_alter_bots.sql +++ /dev/null @@ -1,7 +0,0 @@ --- +goose Up - -ALTER TABLE teldrive.bots ADD COLUMN channel_id BIGINT; - -ALTER TABLE teldrive.bots DROP CONSTRAINT IF EXISTS btoken_user_un; - -ALTER TABLE teldrive.bots ADD CONSTRAINT btoken_user_channel_un UNIQUE (user_id, token,channel_id); diff --git a/pkg/database/migrations/20231031220919_create_dirs_from_path.sql b/pkg/database/migrations/20231031220919_create_dirs_from_path.sql deleted file mode 100644 index 939dc3a..0000000 --- a/pkg/database/migrations/20231031220919_create_dirs_from_path.sql +++ /dev/null @@ -1,49 +0,0 @@ --- +goose Up --- +goose StatementBegin - -CREATE OR REPLACE FUNCTION teldrive.create_directories( - IN tg_id BIGINT, - IN long_path TEXT -) RETURNS SETOF teldrive.files AS $$ -DECLARE - path_parts TEXT[]; - current_directory_id TEXT; - new_directory_id TEXT; - directory_name TEXT; - path_so_far TEXT; - depth_dir integer; -begin - - path_parts := string_to_array(regexp_replace(long_path, '^/+', ''), '/'); - - path_so_far := ''; - - depth_dir := 0; - - SELECT id into current_directory_id FROM teldrive.files WHERE parent_id='root' AND user_id=tg_id; - - - FOR directory_name IN SELECT unnest(path_parts) LOOP - path_so_far := CONCAT(path_so_far,'/', directory_name); - depth_dir := depth_dir +1; - SELECT id INTO new_directory_id - FROM teldrive.files - WHERE parent_id = current_directory_id - AND "name" = directory_name AND "user_id"=tg_id; - - IF new_directory_id IS NULL THEN - INSERT INTO teldrive.files ("name", "type", mime_type, parent_id, "user_id",starred,"depth","path") - VALUES (directory_name, 'folder', 'drive/folder', current_directory_id, tg_id,false,depth_dir,path_so_far) - RETURNING id INTO new_directory_id; - END IF; - - current_directory_id := new_directory_id; - END LOOP; - - RETURN QUERY SELECT * FROM teldrive.files WHERE id = current_directory_id; -END; -$$ LANGUAGE plpgsql; --- +goose StatementEnd - --- +goose Down -DROP FUNCTION IF EXISTS teldrive.create_directories; \ No newline at end of file diff --git a/pkg/database/migrations/20231031223444_alter_uploads.sql b/pkg/database/migrations/20231031223444_alter_uploads.sql deleted file mode 100644 index 0c71ab9..0000000 --- a/pkg/database/migrations/20231031223444_alter_uploads.sql +++ /dev/null @@ -1,3 +0,0 @@ --- +goose Up - -ALTER TABLE teldrive.uploads ADD COLUMN user_id BIGINT; \ No newline at end of file diff --git a/pkg/database/migrations/20231102165658_tables.sql b/pkg/database/migrations/20231102165658_tables.sql index a527b0a..4c5a397 100644 --- a/pkg/database/migrations/20231102165658_tables.sql +++ b/pkg/database/migrations/20231102165658_tables.sql @@ -1,20 +1,104 @@ -- +goose Up -- +goose StatementBegin -ALTER TABLE teldrive.users DROP COLUMN IF EXISTS tg_session; +CREATE TABLE IF NOT EXISTS teldrive.files ( + id text NOT NULL DEFAULT teldrive.generate_uid(16) PRIMARY KEY, + "name" text NOT NULL, + "type" text NOT NULL, + mime_type text NOT NULL, + "path" text, + "size" bigint, + starred bool NOT NULL, + "depth" int, + user_id bigint NOT NULL, + parent_id text, + status text DEFAULT 'active'::text, + channel_id bigint, + parts jsonb, + created_at timestamp NOT NULL DEFAULT timezone('utc'::text, now()), + updated_at timestamp NOT NULL DEFAULT timezone('utc'::text, now()) +); -CREATE TABLE teldrive.sessions ( +CREATE TABLE IF NOT EXISTS teldrive.users ( + user_id bigint NOT NULL PRIMARY KEY, + "name" text, + user_name text NOT NULL, + is_premium bool NOT NULL, + created_at timestamptz NOT NULL DEFAULT timezone('utc'::text, now()), + updated_at timestamptz NOT NULL DEFAULT timezone('utc'::text, now()) +); + + +CREATE TABLE IF NOT EXISTS teldrive.uploads ( + id text NOT NULL DEFAULT teldrive.generate_uid(16) PRIMARY KEY, + upload_id text NOT NULL, + "name" text NOT NULL, + user_id bigint, + part_no int NOT NULL, + part_id int NOT NULL, + total_parts int NOT NULL, + channel_id bigint NOT NULL, + "size" bigint NOT NULL, + created_at timestamp DEFAULT timezone('utc'::text, now()), +); + + +CREATE TABLE IF NOT EXISTS teldrive.channels ( + channel_id bigint NOT NULL PRIMARY KEY, + channel_name text NOT NULL, + user_id bigint NOT NULL, + selected boolean DEFAULT false, + FOREIGN KEY (user_id) REFERENCES teldrive.users(user_id) +); + +CREATE TABLE IF NOT EXISTS teldrive.bots ( + user_id bigint NOT NULL, + "token" text NOT NULL, + bot_user_name text NOT NULL, + bot_id bigint NOT NULL, + channel_id bigint NULL, + FOREIGN KEY (user_id) REFERENCES teldrive.users(user_id), + CONSTRAINT btoken_user_un UNIQUE (user_id,token) +); + +CREATE TABLE IF NOT EXISTS teldrive.sessions ( session text NOT NULL, user_id bigint NOT NULL, hash text NOT NULL, - created_at timestamp null default timezone('utc'::text,now()), + created_at timestamp default timezone('utc'::text,now()), PRIMARY KEY(session, hash), FOREIGN KEY (user_id) REFERENCES teldrive.users(user_id) ); +CREATE INDEX IF NOT EXISTS name_numeric_idx ON teldrive.files USING btree (name COLLATE "numeric" NULLS FIRST); +CREATE INDEX IF NOT EXISTS name_search_idx ON teldrive.files USING gin (teldrive.get_tsvector(name), updated_at); +CREATE INDEX IF NOT EXISTS parent_idx ON teldrive.files USING btree (parent_id); +CREATE INDEX IF NOT EXISTS parent_name_numeric_idx ON teldrive.files USING btree (parent_id, name COLLATE "numeric" DESC); +CREATE INDEX IF NOT EXISTS path_idx ON teldrive.files USING btree (path); +CREATE INDEX IF NOT EXISTS starred_updated_at_idx ON teldrive.files USING btree (starred, updated_at DESC); +CREATE INDEX IF NOT EXISTS status_idx ON teldrive.files USING btree (status); +CREATE UNIQUE IF NOT EXISTS INDEX unique_file ON teldrive.files USING btree (name, parent_id, user_id) WHERE (status = 'active'::text); +CREATE INDEX IF NOT EXISTS user_id_idx ON teldrive.files USING btree (user_id); + -- +goose StatementEnd -- +goose Down -- +goose StatementBegin + +DROP INDEX IF EXISTS name_numeric_idx ; +DROP INDEX IF EXISTS name_search_idx ; +DROP INDEX IF EXISTS parent_idx ; +DROP INDEX IF EXISTS parent_name_numeric_idx ; +DROP INDEX IF EXISTS path_idx ; +DROP INDEX IF EXISTS starred_updated_at_idx ; +DROP INDEX IF EXISTS status_idx ; +DROP UNIQUE IF EXISTS INDEX unique_file; +DROP INDEX IF EXISTS user_id_idx; + +DROP TABLE IF EXISTS teldrive.files; +DROP TABLE IF EXISTS teldrive.uploads; +DROP TABLE IF EXISTS teldrive.users; +DROP TABLE IF EXISTS teldrive.channels; +DROP TABLE IF EXISTS teldrive.bots; DROP TABLE IF EXISTS teldrive.sessions; -- +goose StatementEnd diff --git a/pkg/database/migrations/20231104192800_functions.sql b/pkg/database/migrations/20231104192800_functions.sql index 5c62113..f486b19 100644 --- a/pkg/database/migrations/20231104192800_functions.sql +++ b/pkg/database/migrations/20231104192800_functions.sql @@ -1,6 +1,112 @@ -- +goose Up -- +goose StatementBegin +CREATE OR REPLACE PROCEDURE teldrive.update_size() LANGUAGE PLPGSQL AS $$ +DECLARE + rec RECORD; + total_size BIGINT; +BEGIN + FOR rec IN + SELECT id + FROM files + WHERE type = 'folder' + ORDER BY depth DESC + LOOP + total_size := ( + SELECT SUM(size) AS total_size + FROM teldrive.files + WHERE parent_id = rec.id + ); + + UPDATE teldrive.files + SET size = total_size + WHERE id = rec.id; + END LOOP; +END; +$$; + + +CREATE OR REPLACE PROCEDURE teldrive.delete_files(IN file_ids TEXT[], IN op TEXT DEFAULT 'bulk') LANGUAGE PLPGSQL AS $$ +DECLARE + rec RECORD; +BEGIN + IF op = 'bulk' THEN + FOR rec IN + SELECT id, type + FROM teldrive.files + WHERE id = ANY (file_ids) + LOOP + IF rec.type = 'folder' THEN + CALL teldrive.delete_files(ARRAY[rec.id], 'single'); + END IF; + + DELETE FROM teldrive.files + WHERE id = rec.id; + END LOOP; + ELSE + FOR rec IN + SELECT id, type + FROM teldrive.files + WHERE parent_id = file_ids[1] + LOOP + IF rec.type = 'folder' THEN + CALL teldrive.delete_files(ARRAY[rec.id], 'single'); + END IF; + + DELETE FROM teldrive.files + WHERE id = rec.id; + END LOOP; + END IF; +END; +$$; + + +CREATE OR REPLACE FUNCTION teldrive.create_directories( + IN tg_id BIGINT, + IN long_path TEXT +) RETURNS SETOF teldrive.files AS $$ +DECLARE + path_parts TEXT[]; + current_directory_id TEXT; + new_directory_id TEXT; + directory_name TEXT; + path_so_far TEXT; + depth_dir INTEGER; +BEGIN + path_parts := string_to_array(regexp_replace(long_path, '^/+', ''), '/'); + + path_so_far := ''; + depth_dir := 0; + + SELECT id INTO current_directory_id + FROM teldrive.files + WHERE parent_id = 'root' AND user_id = tg_id; + + FOR directory_name IN SELECT unnest(path_parts) LOOP + path_so_far := CONCAT(path_so_far, '/', directory_name); + depth_dir := depth_dir + 1; + + SELECT id INTO new_directory_id + FROM teldrive.files + WHERE parent_id = current_directory_id + AND "name" = directory_name + AND "user_id" = tg_id; + + IF new_directory_id IS NULL THEN + INSERT INTO teldrive.files ("name", "type", mime_type, parent_id, "user_id", starred, "depth", "path") + VALUES (directory_name, 'folder', 'teldrive/folder', current_directory_id, tg_id, false, depth_dir, path_so_far) + RETURNING id INTO new_directory_id; + END IF; + + current_directory_id := new_directory_id; + END LOOP; + + RETURN QUERY SELECT * FROM teldrive.files WHERE id = current_directory_id; +END; +$$ LANGUAGE plpgsql; + + + CREATE OR REPLACE FUNCTION teldrive.split_path(path text, OUT parent text, OUT base text) AS $$ BEGIN IF path = '/' THEN @@ -84,8 +190,6 @@ BEGIN END; $$; -drop function if exists teldrive.move_directory; - CREATE OR REPLACE FUNCTION teldrive.move_directory(src text, dest text,u_id bigint) RETURNS VOID AS $$ DECLARE src_parent TEXT; @@ -126,11 +230,33 @@ BEGIN END; $$ LANGUAGE plpgsql; + + +CREATE OR REPLACE FUNCTION teldrive.account_stats( + IN u_id BIGINT +) RETURNS TABLE (total_size BIGINT, total_files BIGINT, ch_id BIGINT,ch_name TEXT ) AS $$ +DECLARE + total_size BIGINT; + total_files BIGINT; + ch_id BIGINT; + ch_name TEXT; +BEGIN + SELECT COUNT(*), SUM(size) into total_files,total_size FROM teldrive.files WHERE user_id=u_id AND type= 'file' and status='active'; + SELECT channel_id ,channel_name into ch_id,ch_name FROM teldrive.channels WHERE selected=TRUE AND user_id=u_id; + RETURN QUERY SELECT total_size,total_files,ch_id,ch_name; +END; +$$ LANGUAGE plpgsql; + + -- +goose StatementEnd -- +goose Down -- +goose StatementBegin -drop function if exists teldrive.split_path; -drop function if exists teldrive.update_folder; -drop function if exists teldrive.move_directory; +DROP PROCEDURE IF EXISTS teldrive.update_size; +DROP PROCEDURE IF EXISTS teldrive.delete_files; +DROP FUNCTION IF EXISTS teldrive.create_directories; +DROP FUNCTION IF EXISTS teldrive.split_path; +DROP FUNCTION IF EXISTS teldrive.update_folder; +DROP FUNCTION IF EXISTS teldrive.move_directory; +DROP FUNCTION IF EXISTS teldrive.account_stats; -- +goose StatementEnd diff --git a/pkg/services/common.go b/pkg/services/common.go index 35fca7b..6355d43 100644 --- a/pkg/services/common.go +++ b/pkg/services/common.go @@ -114,7 +114,7 @@ func getBotInfo(ctx context.Context, token string) (*BotInfo, error) { func getTGMessages(ctx context.Context, client *telegram.Client, parts []schemas.Part, channelId int64, userID string) (*tg.MessagesChannelMessages, error) { - ids := funk.Map(parts, func(part models.Part) tg.InputMessageClass { + ids := funk.Map(parts, func(part schemas.Part) tg.InputMessageClass { return tg.InputMessageClass(&tg.InputMessageID{ID: int(part.ID)}) }) diff --git a/ui/teldrive-ui b/ui/teldrive-ui index 82ff775..f5e563e 160000 --- a/ui/teldrive-ui +++ b/ui/teldrive-ui @@ -1 +1 @@ -Subproject commit 82ff775d8c7a6d2620b4113a09d8a78ee4f9519f +Subproject commit f5e563e9b3a66bcb9779d9af782ee6f9767c86d3