mirror of
https://github.com/Sagit-chu/flvx.git
synced 2026-10-11 03:36:37 +08:00
init
This commit is contained in:
@@ -0,0 +1,49 @@
|
||||
package loader
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"context"
|
||||
"io"
|
||||
"os"
|
||||
)
|
||||
|
||||
type fileLoader struct {
|
||||
filename string
|
||||
}
|
||||
|
||||
// FileLoader loads data from file.
|
||||
func FileLoader(filename string) Loader {
|
||||
return &fileLoader{
|
||||
filename: filename,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *fileLoader) Load(ctx context.Context) (io.Reader, error) {
|
||||
data, err := os.ReadFile(l.filename)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return bytes.NewReader(data), nil
|
||||
}
|
||||
|
||||
// List implements Lister interface{}
|
||||
func (l *fileLoader) List(ctx context.Context) (list []string, err error) {
|
||||
f, err := os.Open(l.filename)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
scanner := bufio.NewScanner(f)
|
||||
for scanner.Scan() {
|
||||
list = append(list, scanner.Text())
|
||||
}
|
||||
err = scanner.Err()
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (l *fileLoader) Close() error {
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
package loader
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"time"
|
||||
)
|
||||
|
||||
type httpLoaderOptions struct {
|
||||
timeout time.Duration
|
||||
}
|
||||
|
||||
type HTTPLoaderOption func(opts *httpLoaderOptions)
|
||||
|
||||
func TimeoutHTTPLoaderOption(timeout time.Duration) HTTPLoaderOption {
|
||||
return func(opts *httpLoaderOptions) {
|
||||
opts.timeout = timeout
|
||||
}
|
||||
}
|
||||
|
||||
type httpLoader struct {
|
||||
url string
|
||||
httpClient *http.Client
|
||||
}
|
||||
|
||||
// HTTPLoader loads data from HTTP request.
|
||||
func HTTPLoader(url string, opts ...HTTPLoaderOption) Loader {
|
||||
var options httpLoaderOptions
|
||||
for _, opt := range opts {
|
||||
if opt != nil {
|
||||
opt(&options)
|
||||
}
|
||||
}
|
||||
return &httpLoader{
|
||||
url: url,
|
||||
httpClient: &http.Client{
|
||||
Timeout: options.timeout,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (l *httpLoader) Load(ctx context.Context) (io.Reader, error) {
|
||||
req, err := http.NewRequest(http.MethodGet, l.url, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
resp, err := l.httpClient.Do(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return nil, fmt.Errorf("%d %s", resp.StatusCode, resp.Status)
|
||||
}
|
||||
|
||||
data, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return bytes.NewReader(data), nil
|
||||
}
|
||||
|
||||
func (l *httpLoader) Close() error {
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package loader
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
)
|
||||
|
||||
type Loader interface {
|
||||
Load(context.Context) (io.Reader, error)
|
||||
Close() error
|
||||
}
|
||||
|
||||
type Lister interface {
|
||||
List(ctx context.Context) ([]string, error)
|
||||
}
|
||||
|
||||
type Mapper interface {
|
||||
Map(ctx context.Context) (map[string]string, error)
|
||||
}
|
||||
@@ -0,0 +1,242 @@
|
||||
package loader
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"strings"
|
||||
|
||||
"github.com/go-redis/redis/v8"
|
||||
)
|
||||
|
||||
const (
|
||||
DefaultRedisKey = "gost"
|
||||
)
|
||||
|
||||
type redisLoaderOptions struct {
|
||||
db int
|
||||
username string
|
||||
password string
|
||||
key string
|
||||
}
|
||||
|
||||
type RedisLoaderOption func(opts *redisLoaderOptions)
|
||||
|
||||
func DBRedisLoaderOption(db int) RedisLoaderOption {
|
||||
return func(opts *redisLoaderOptions) {
|
||||
opts.db = db
|
||||
}
|
||||
}
|
||||
|
||||
func UsernameRedisLoaderOption(username string) RedisLoaderOption {
|
||||
return func(opts *redisLoaderOptions) {
|
||||
opts.username = username
|
||||
}
|
||||
}
|
||||
|
||||
func PasswordRedisLoaderOption(password string) RedisLoaderOption {
|
||||
return func(opts *redisLoaderOptions) {
|
||||
opts.password = password
|
||||
}
|
||||
}
|
||||
|
||||
func KeyRedisLoaderOption(key string) RedisLoaderOption {
|
||||
return func(opts *redisLoaderOptions) {
|
||||
opts.key = key
|
||||
}
|
||||
}
|
||||
|
||||
type redisStringLoader struct {
|
||||
client *redis.Client
|
||||
key string
|
||||
}
|
||||
|
||||
// RedisStringLoader loads data from redis string.
|
||||
func RedisStringLoader(addr string, opts ...RedisLoaderOption) Loader {
|
||||
var options redisLoaderOptions
|
||||
for _, opt := range opts {
|
||||
if opt != nil {
|
||||
opt(&options)
|
||||
}
|
||||
}
|
||||
|
||||
key := options.key
|
||||
if key == "" {
|
||||
key = DefaultRedisKey
|
||||
}
|
||||
|
||||
return &redisStringLoader{
|
||||
client: redis.NewClient(&redis.Options{
|
||||
Addr: addr,
|
||||
Password: options.password,
|
||||
DB: options.db,
|
||||
}),
|
||||
key: key,
|
||||
}
|
||||
}
|
||||
|
||||
func (p *redisStringLoader) Load(ctx context.Context) (io.Reader, error) {
|
||||
v, err := p.client.Get(ctx, p.key).Bytes()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return bytes.NewReader(v), nil
|
||||
}
|
||||
|
||||
func (p *redisStringLoader) Close() error {
|
||||
return p.client.Close()
|
||||
}
|
||||
|
||||
type redisSetLoader struct {
|
||||
client *redis.Client
|
||||
key string
|
||||
}
|
||||
|
||||
// RedisSetLoader loads data from redis set.
|
||||
func RedisSetLoader(addr string, opts ...RedisLoaderOption) Loader {
|
||||
var options redisLoaderOptions
|
||||
for _, opt := range opts {
|
||||
if opt != nil {
|
||||
opt(&options)
|
||||
}
|
||||
}
|
||||
|
||||
key := options.key
|
||||
if key == "" {
|
||||
key = DefaultRedisKey
|
||||
}
|
||||
|
||||
return &redisSetLoader{
|
||||
client: redis.NewClient(&redis.Options{
|
||||
Addr: addr,
|
||||
Password: options.password,
|
||||
DB: options.db,
|
||||
}),
|
||||
key: key,
|
||||
}
|
||||
}
|
||||
|
||||
func (p *redisSetLoader) Load(ctx context.Context) (io.Reader, error) {
|
||||
v, err := p.List(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return bytes.NewReader([]byte(strings.Join(v, "\n"))), nil
|
||||
}
|
||||
|
||||
// List implements Lister interface{}
|
||||
func (p *redisSetLoader) List(ctx context.Context) ([]string, error) {
|
||||
return p.client.SMembers(ctx, p.key).Result()
|
||||
}
|
||||
|
||||
func (p *redisSetLoader) Close() error {
|
||||
return p.client.Close()
|
||||
}
|
||||
|
||||
type redisListLoader struct {
|
||||
client *redis.Client
|
||||
key string
|
||||
}
|
||||
|
||||
// RedisListLoader loads data from redis list.
|
||||
func RedisListLoader(addr string, opts ...RedisLoaderOption) Loader {
|
||||
var options redisLoaderOptions
|
||||
for _, opt := range opts {
|
||||
opt(&options)
|
||||
}
|
||||
|
||||
key := options.key
|
||||
if key == "" {
|
||||
key = DefaultRedisKey
|
||||
}
|
||||
|
||||
return &redisListLoader{
|
||||
client: redis.NewClient(&redis.Options{
|
||||
Addr: addr,
|
||||
Password: options.password,
|
||||
DB: options.db,
|
||||
}),
|
||||
key: key,
|
||||
}
|
||||
}
|
||||
|
||||
func (p *redisListLoader) Load(ctx context.Context) (io.Reader, error) {
|
||||
v, err := p.List(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return bytes.NewReader([]byte(strings.Join(v, "\n"))), nil
|
||||
}
|
||||
|
||||
// List implements Lister interface{}
|
||||
func (p *redisListLoader) List(ctx context.Context) ([]string, error) {
|
||||
return p.client.LRange(ctx, p.key, 0, -1).Result()
|
||||
}
|
||||
|
||||
func (p *redisListLoader) Close() error {
|
||||
return p.client.Close()
|
||||
}
|
||||
|
||||
type redisHashLoader struct {
|
||||
client *redis.Client
|
||||
key string
|
||||
}
|
||||
|
||||
// RedisHashLoader loads data from redis hash.
|
||||
func RedisHashLoader(addr string, opts ...RedisLoaderOption) Loader {
|
||||
var options redisLoaderOptions
|
||||
for _, opt := range opts {
|
||||
opt(&options)
|
||||
}
|
||||
|
||||
key := options.key
|
||||
if key == "" {
|
||||
key = DefaultRedisKey
|
||||
}
|
||||
|
||||
return &redisHashLoader{
|
||||
client: redis.NewClient(&redis.Options{
|
||||
Addr: addr,
|
||||
Password: options.password,
|
||||
DB: options.db,
|
||||
}),
|
||||
key: key,
|
||||
}
|
||||
}
|
||||
|
||||
func (p *redisHashLoader) Load(ctx context.Context) (io.Reader, error) {
|
||||
m, err := p.Map(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var b strings.Builder
|
||||
for k, v := range m {
|
||||
fmt.Fprintf(&b, "%s %s\n", k, v)
|
||||
}
|
||||
return bytes.NewBufferString(b.String()), nil
|
||||
}
|
||||
|
||||
// List implements Lister interface{}
|
||||
func (p *redisHashLoader) List(ctx context.Context) (list []string, err error) {
|
||||
m, err := p.Map(ctx)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
for k, v := range m {
|
||||
list = append(list, fmt.Sprintf("%s %s", k, v))
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Map implements Mapper interface{}
|
||||
func (p *redisHashLoader) Map(ctx context.Context) (map[string]string, error) {
|
||||
return p.client.HGetAll(ctx, p.key).Result()
|
||||
}
|
||||
|
||||
func (p *redisHashLoader) Close() error {
|
||||
return p.client.Close()
|
||||
}
|
||||
Reference in New Issue
Block a user