images: update implementations

This commit is contained in:
Tigor Hutasuhut 2024-08-24 19:21:01 +07:00
parent 39c0ef1bd9
commit 1ce878fdfb
5 changed files with 159 additions and 19 deletions

109
go/api/images_list.go Normal file
View file

@ -0,0 +1,109 @@
package api
import (
"context"
"fmt"
"github.com/tigorlazuardi/bluemage/go/gen/jet/model"
"github.com/tigorlazuardi/bluemage/go/pkg/telemetry"
. "github.com/go-jet/jet/v2/sqlite"
. "github.com/tigorlazuardi/bluemage/go/gen/jet/table"
)
type ImageListRequest struct {
Subreddits []string
Devices []string
Limit int64
After int64
Before int64
OrderBy string
Sort Sort
Search string
NSFW *bool
Blacklist *bool
}
// CREATE VIRTUAL TABLE images_fts5 USING fts5(
//
// post_author,
// post_title,
// post_name,
// image_relative_path,
// post_url,
// post_author_url,
// content='images',
// content_rowid='id'
//
// );
//
// matching list:
//
// - Author's name
// - Post Title
// - Post ID
// - Author's ID
// - Image filename (url path suffix to get this image from web browser)
// - Image original url
// - Post url
// - Author's url
var imagesFTSBM25 = fmt.Sprintf("bm25(%s, 25, 20, 10, 5, 3, 3)", ImagesFts5.TableName())
func (request ImageListRequest) Statement() SelectStatement {
cond := Bool(true)
from := Images
if request.NSFW != nil {
n := *request.NSFW
if n {
cond.AND(Images.Nsfw.EQ(Int(1)))
} else {
cond.AND(Images.Nsfw.EQ(Int(0)))
}
}
if request.Blacklist != nil {
b := *request.Blacklist
if b {
cond.AND(Images.Blacklisted.EQ(Int(1)))
} else {
cond.AND(Images.Blacklisted.EQ(Int(0)))
}
}
if request.After > 0 {
cond.AND(Images.CreatedAt.LT_EQ(Int(request.After)))
}
if request.Before > 0 {
cond.AND(Images.CreatedAt.GT_EQ(Int(request.Before)))
}
stmt := SELECT(Images.AllColumns).FROM(from).WHERE(cond)
if request.Limit > 0 {
stmt.LIMIT(request.Limit)
}
if len(request.Search) > 0 {
from.INNER_JOIN(ImagesFts5, Images.PostName.EQ(ImagesFts5.PostName))
cond.AND(ImagesFts5.ImagesFts5.EQ(String(request.Search)))
return stmt.ORDER_BY(RawString(imagesFTSBM25).ASC())
}
if request.OrderBy == "" {
return stmt.ORDER_BY(Images.CreatedAt.DESC())
}
orderBy := StringColumn(request.OrderBy)
if request.Sort == SortDesc {
return stmt.ORDER_BY(orderBy.DESC())
}
return stmt.ORDER_BY(orderBy.ASC())
}
func (api *API) ImageList(ctx context.Context, request ImageListRequest) (images []*model.Images, err error) {
ctx, span := tracer.Start(ctx, "ImageList")
defer func() { telemetry.EndWithStatus(span, err) }()
return images, err
}

View file

@ -0,0 +1,25 @@
package server
import (
"context"
"connectrpc.com/connect"
"github.com/tigorlazuardi/bluemage/go/api"
images "github.com/tigorlazuardi/bluemage/go/gen/proto/images/v1"
)
type ImageHandler struct {
API *api.API
}
func (im *ImageHandler) ListImages(ctx context.Context, request *connect.Request[images.ListImagesRequest]) (*connect.Response[images.ListImagesResponse], error) {
panic("not implemented") // TODO: Implement
}
func (im *ImageHandler) DeleteImages(ctx context.Context, request *connect.Request[images.DeleteImagesRequest]) (*connect.Response[images.DeleteImagesResponse], error) {
panic("not implemented") // TODO: Implement
}
func (im *ImageHandler) GetImage(ctx context.Context, request *connect.Request[images.GetImageRequest]) (*connect.Response[images.GetImageResponse], error) {
panic("not implemented") // TODO: Implement
}

View file

@ -34,12 +34,12 @@ CREATE TABLE images(
); );
CREATE VIRTUAL TABLE images_fts5 USING fts5( CREATE VIRTUAL TABLE images_fts5 USING fts5(
post_author,
post_title, post_title,
post_name, post_name,
post_author,
image_relative_path, image_relative_path,
image_original_url, post_url,
thumbnail_relative_path, post_author_url,
content='images', content='images',
content_rowid='id' content_rowid='id'
); );
@ -68,8 +68,11 @@ END;
CREATE TRIGGER images_update_fts_insert AFTER INSERT ON images FOR EACH ROW CREATE TRIGGER images_update_fts_insert AFTER INSERT ON images FOR EACH ROW
BEGIN BEGIN
INSERT INTO images_fts5(rowid, post_title, post_name, post_author, image_relative_path, image_original_url, thumbnail_relative_path) INSERT INTO images_fts5(
VALUES (new.id, new.post_title, new.post_name, new.post_author, new.image_relative_path, new.image_original_url, new.thumbnail_relative_path); rowid, post_author, post_title, post_name, image_relative_path, post_url, post_author_url
) VALUES(
new.id, new.post_author, new.post_title, new.post_name, new.image_relative_path, new.post_url, new.post_author_url
);
END; END;
CREATE TRIGGER images_update_fts_delete AFTER DELETE ON images FOR EACH ROW CREATE TRIGGER images_update_fts_delete AFTER DELETE ON images FOR EACH ROW

View file

@ -15,7 +15,7 @@ message ListImagesRequest {
// subreddits filter the images to be fetched belonging to the given subreddits names. // subreddits filter the images to be fetched belonging to the given subreddits names.
// //
// If empty, images from all subreddits will be fetched. // If empty, images from all subreddits will be fetched.
string subreddit = 1 [(buf.validate.field).string.min_len = 1]; repeated string subreddits = 1;
// devices filter the images to be fetched belonging to the given devices slugs. // devices filter the images to be fetched belonging to the given devices slugs.
// //
// If empty, images from all devices will be fetched. // If empty, images from all devices will be fetched.
@ -54,12 +54,10 @@ message ListImagesRequest {
// It will look up by following rank and prioritizes matches // It will look up by following rank and prioritizes matches
// based on following fields: // based on following fields:
// //
// - Author's name
// - Post Title // - Post Title
// - Post ID // - Post ID
// - Author's name
// - Author's ID
// - Image filename (url path suffix to get this image from web browser) // - Image filename (url path suffix to get this image from web browser)
// - Image original url
// - Post url // - Post url
// - Author's url // - Author's url
string search = 8; string search = 8;

View file

@ -7,16 +7,21 @@ message Image {
string subreddit = 2; string subreddit = 2;
string device = 3; string device = 3;
string post_title = 4; string post_title = 4;
string post_url = 5; string post_name = 5;
int64 post_created = 6; string post_url = 6;
string post_author = 7; int64 post_created = 7;
string post_author_url = 8; string post_author = 8;
string image_relative_path = 9; string post_author_url = 9;
string image_original_url = 10; string image_relative_path = 10;
int64 image_height = 11; string image_original_url = 11;
int64 image_width = 12; int64 image_height = 12;
int64 image_size = 13; int64 image_width = 13;
bool nsfw = 14; int64 image_size = 14;
string thumbnail_relative_path = 15;
bool nsfw = 16;
bool blacklisted = 17;
int64 created_at = 18;
int64 updated_at = 19;
} }
message GroupedByDeviceImages { message GroupedByDeviceImages {