This commit is contained in:
@@ -12,11 +12,6 @@ RUN go generate ./...
|
|||||||
# Build server and tools (CGO disabled to make them 100% static)
|
# Build server and tools (CGO disabled to make them 100% static)
|
||||||
ENV CGO_ENABLED 0
|
ENV CGO_ENABLED 0
|
||||||
RUN go build -installsuffix cgo -ldflags="-s -w" -o /binaries/rpdata-server ./cmd/rpdata-server
|
RUN go build -installsuffix cgo -ldflags="-s -w" -o /binaries/rpdata-server ./cmd/rpdata-server
|
||||||
RUN go build -installsuffix cgo -ldflags="-s -w" -o /binaries/rpdata-lb2charimport ./cmd/rpdata-lb2charimport
|
|
||||||
RUN go build -installsuffix cgo -ldflags="-s -w" -o /binaries/rpdata-lb2logimport ./cmd/rpdata-lb2logimport
|
|
||||||
# TODO: RUN go build -installsuffix cgo -ldflags="-s -w" -o /binaries/rpdata-wikifileimport ./cmd/rpdata-wikifileimport
|
|
||||||
RUN go build -installsuffix cgo -ldflags="-s -w" -o /binaries/rpdata-ensurechannels ./cmd/rpdata-ensurechannels
|
|
||||||
RUN go build -installsuffix cgo -ldflags="-s -w" -o /binaries/rpdata-as2storyimport ./cmd/rpdata-as2storyimport
|
|
||||||
|
|
||||||
## 2. Distribute
|
## 2. Distribute
|
||||||
# Use alpine linux
|
# Use alpine linux
|
||||||
|
|||||||
@@ -1,139 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"flag"
|
|
||||||
"fmt"
|
|
||||||
"log"
|
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"git.aiterp.net/rpdata/api/internal/store"
|
|
||||||
"git.aiterp.net/rpdata/api/models"
|
|
||||||
"git.aiterp.net/rpdata/api/models/chapters"
|
|
||||||
"git.aiterp.net/rpdata/api/models/stories"
|
|
||||||
_ "github.com/go-sql-driver/mysql"
|
|
||||||
"github.com/jmoiron/sqlx"
|
|
||||||
)
|
|
||||||
|
|
||||||
var flagHost = flag.String("host", "127.0.0.1:3306", "SQL host")
|
|
||||||
var flagDB = flag.String("database", "aitestory", "SQL database")
|
|
||||||
var flagUser = flag.String("user", "aitestory", "SQL user")
|
|
||||||
var flagPassword = flag.String("password", "", "SQL password")
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
flag.Parse()
|
|
||||||
|
|
||||||
db, err := sqlx.Connect("mysql", fmt.Sprintf("%s:%s@(%s)/%s", *flagUser, *flagPassword, *flagHost, *flagDB))
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalln(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
err = db.Ping()
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalln(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
store.Init()
|
|
||||||
|
|
||||||
results := make([]storyResult, 0, 64)
|
|
||||||
rows, err := db.Queryx("SELECT * FROM page WHERE unlisted=0;")
|
|
||||||
for rows.Next() {
|
|
||||||
result := storyResult{}
|
|
||||||
err := rows.StructScan(&result)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalln(err)
|
|
||||||
}
|
|
||||||
results = append(results, result)
|
|
||||||
}
|
|
||||||
|
|
||||||
tagResults := make([]tagResult, 0, 256)
|
|
||||||
rows, err = db.Queryx("SELECT page_id,type,name FROM page_tag LEFT JOIN tag ON tag_id=tag.id;")
|
|
||||||
for rows.Next() {
|
|
||||||
result := tagResult{}
|
|
||||||
err := rows.StructScan(&result)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalln(err)
|
|
||||||
}
|
|
||||||
tagResults = append(tagResults, result)
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, result := range results {
|
|
||||||
fictionalDate, err := time.Parse("2006-01-02 15:04:05", result.FictionalDate)
|
|
||||||
if err != nil {
|
|
||||||
if result.FictionalDate != "0000-00-00 00:00:00" {
|
|
||||||
log.Fatalln(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if fictionalDate.Year() < 1800 {
|
|
||||||
fictionalDate = time.Time{}
|
|
||||||
}
|
|
||||||
|
|
||||||
publishDate, err := time.Parse("2006-01-02 15:04:05", result.PublishDate)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalln(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
tags := make([]models.Tag, 0, 8)
|
|
||||||
for _, tagResult := range tagResults {
|
|
||||||
if tagResult.PageID == result.ID {
|
|
||||||
tags = append(tags, models.Tag{Kind: models.TagKind(tagResult.Type), Name: tagResult.Name})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
category := models.StoryCategory(result.Category)
|
|
||||||
if !category.IsValid() {
|
|
||||||
log.Println(result.Name, "does not have a valid category:", result.Category)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
story, err := stories.Add(result.Name, result.Author[5:], category, true, false, tags, publishDate, fictionalDate)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalln(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Change the story title
|
|
||||||
title := result.Name
|
|
||||||
if strings.HasPrefix(result.Source, "#") {
|
|
||||||
firstNewline := strings.Index(result.Source, "\n")
|
|
||||||
result.Name = strings.Replace(result.Source[1:firstNewline], "\r", "", -1)
|
|
||||||
result.Source = result.Source[firstNewline+1:]
|
|
||||||
|
|
||||||
result.Source = strings.Replace(result.Source, "\r\n", "\n", -1)
|
|
||||||
if strings.HasPrefix(result.Source, "\r") || strings.HasPrefix(result.Source, "\n") {
|
|
||||||
result.Source = result.Source[1:]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
chapter, err := chapters.Add(story, title, result.Author[5:], result.Source, publishDate, &fictionalDate, models.ChapterCommentModeDisabled)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalln(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Println(result.ID, "->", story.ID, chapter.ID)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type tagResult struct {
|
|
||||||
PageID string `db:"page_id"`
|
|
||||||
Type string `db:"type"`
|
|
||||||
Name string `db:"name"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type storyResult struct {
|
|
||||||
ID string `db:"id"`
|
|
||||||
Name string `db:"name"`
|
|
||||||
Author string `db:"author"`
|
|
||||||
Category string `db:"category"`
|
|
||||||
FictionalDate string `db:"fictional_date"`
|
|
||||||
PublishDate string `db:"publish_date"`
|
|
||||||
EditDate string `db:"edit_date"`
|
|
||||||
Unlisted bool `db:"unlisted"`
|
|
||||||
Dated bool `db:"dated"`
|
|
||||||
Spesific bool `db:"specific"`
|
|
||||||
Indexed bool `db:"indexed"`
|
|
||||||
Published bool `db:"published"`
|
|
||||||
Type string `db:"type"`
|
|
||||||
Source string `db:"source"`
|
|
||||||
Cache string `db:"cache"`
|
|
||||||
BackgroundURL *string `db:"background_url"`
|
|
||||||
}
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
|
|
||||||
"git.aiterp.net/rpdata/api/internal/store"
|
|
||||||
"git.aiterp.net/rpdata/api/models/channels"
|
|
||||||
"git.aiterp.net/rpdata/api/models/logs"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
err := store.Init()
|
|
||||||
if err != nil {
|
|
||||||
fmt.Fprintln(os.Stderr, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
logs, err := logs.List(nil)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Fprintln(os.Stderr, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
added := make(map[string]bool, 1024)
|
|
||||||
for _, log := range logs {
|
|
||||||
if added[log.ChannelName] {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err := channels.Ensure(log.ChannelName, false)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Fprintln(os.Stderr, log.ID, err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
added[log.ChannelName] = true
|
|
||||||
|
|
||||||
fmt.Println(log.ChannelName, "ensured")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
characters.json
|
|
||||||
characters.cson
|
|
||||||
debug
|
|
||||||
@@ -1,55 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"io"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
type charInfo struct {
|
|
||||||
Nicks []string `json:"nicks"`
|
|
||||||
Name string `json:"name"`
|
|
||||||
Author string `json:"player"`
|
|
||||||
ShortName string `json:"first"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func load(reader io.Reader) ([]charInfo, error) {
|
|
||||||
data := make(map[string]interface{})
|
|
||||||
err := json.NewDecoder(reader).Decode(&data)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
links := make(map[string]string, len(data))
|
|
||||||
infos := make([]charInfo, 0, 64)
|
|
||||||
|
|
||||||
for key, value := range data {
|
|
||||||
if info, ok := value.(map[string]interface{}); ok {
|
|
||||||
name := info["name"].(string)
|
|
||||||
author := info["player"].(string)
|
|
||||||
shortName, ok := info["first"].(string)
|
|
||||||
if !ok {
|
|
||||||
shortName = strings.SplitN(name, " ", 2)[0]
|
|
||||||
}
|
|
||||||
|
|
||||||
infos = append(infos, charInfo{
|
|
||||||
Nicks: []string{key},
|
|
||||||
Name: name,
|
|
||||||
Author: author,
|
|
||||||
ShortName: shortName,
|
|
||||||
})
|
|
||||||
} else if nick, ok := value.(string); ok {
|
|
||||||
links[key] = nick
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for key, value := range links {
|
|
||||||
for i := range infos {
|
|
||||||
if infos[i].Nicks[0] == value {
|
|
||||||
infos[i].Nicks = append(infos[i].Nicks, key)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return infos, nil
|
|
||||||
}
|
|
||||||
@@ -1,62 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"flag"
|
|
||||||
"log"
|
|
||||||
"os"
|
|
||||||
|
|
||||||
"git.aiterp.net/rpdata/api/internal/store"
|
|
||||||
"git.aiterp.net/rpdata/api/models/characters"
|
|
||||||
)
|
|
||||||
|
|
||||||
var fileName = flag.String("file", "./characters.json", "json file to load")
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
file, err := os.Open(*fileName)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalln("Open:", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
infos, err := load(file)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalln("Parse:", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
err = store.Init()
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalln("Store:", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
charsAdded, charsFailed := 0, 0
|
|
||||||
nicksAdded, nicksFailed := 0, 0
|
|
||||||
|
|
||||||
for _, info := range infos {
|
|
||||||
char, err := characters.Add(info.Nicks[0], info.Name, info.ShortName, info.Author, "")
|
|
||||||
if err != nil {
|
|
||||||
log.Println(info.Nicks[0], "failed to insert:", err)
|
|
||||||
charsFailed++
|
|
||||||
|
|
||||||
char, err = characters.FindNick(info.Nicks[0])
|
|
||||||
if err != nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
log.Println(info.Nicks[0], "added")
|
|
||||||
charsAdded++
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, alt := range info.Nicks[1:] {
|
|
||||||
char, err = characters.AddNick(char, alt)
|
|
||||||
if err != nil {
|
|
||||||
log.Println(info.Nicks[0], "failed to add nick", alt, "error:", err)
|
|
||||||
nicksFailed++
|
|
||||||
} else {
|
|
||||||
log.Println(info.Nicks[0], "addded nick", alt)
|
|
||||||
nicksAdded++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Printf("Characters – %d/%d", charsAdded, charsFailed+charsAdded)
|
|
||||||
log.Printf("Alt. Nicks – %d/%d", nicksAdded, nicksFailed+nicksAdded)
|
|
||||||
}
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
logs
|
|
||||||
debug
|
|
||||||
@@ -1,85 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bufio"
|
|
||||||
"errors"
|
|
||||||
"io"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
type logLine struct {
|
|
||||||
Verb string
|
|
||||||
Args []string
|
|
||||||
Text string
|
|
||||||
}
|
|
||||||
|
|
||||||
func parseFile(reader io.Reader) []logLine {
|
|
||||||
bufReader := bufio.NewReader(reader)
|
|
||||||
results := make([]logLine, 0, 512)
|
|
||||||
|
|
||||||
for {
|
|
||||||
line, err := bufReader.ReadString('\n')
|
|
||||||
if err == io.EOF {
|
|
||||||
if len(line) < 2 {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
} else if err != nil {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(line) <= 2 {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
line = strings.Replace(line, "\n", "", 1)
|
|
||||||
line = strings.Replace(line, "\r", "", 1)
|
|
||||||
|
|
||||||
results = append(results, parseLine(line))
|
|
||||||
}
|
|
||||||
|
|
||||||
return results
|
|
||||||
}
|
|
||||||
|
|
||||||
func parseLine(line string) logLine {
|
|
||||||
textSplit := strings.SplitN(line, " :", 2)
|
|
||||||
tokens := strings.Split(textSplit[0], " ")
|
|
||||||
|
|
||||||
ll := logLine{
|
|
||||||
Verb: tokens[0],
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(tokens) > 1 {
|
|
||||||
ll.Args = tokens[1:]
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(textSplit) > 1 {
|
|
||||||
ll.Text = textSplit[1]
|
|
||||||
}
|
|
||||||
|
|
||||||
return ll
|
|
||||||
}
|
|
||||||
|
|
||||||
func parseFilename(fname string) (date time.Time, channel string, err error) {
|
|
||||||
date, err = time.ParseInLocation("2006-01-02_150405", fname[:17], time.Local)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
ms, err := strconv.Atoi(fname[17:20])
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
date = date.Add(time.Duration(ms) * time.Millisecond)
|
|
||||||
|
|
||||||
if len(fname) < 23 {
|
|
||||||
err = errors.New("filename too short")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
channel = fname[21:]
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
@@ -1,110 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"log"
|
|
||||||
"os"
|
|
||||||
"path"
|
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"git.aiterp.net/rpdata/api/models/posts"
|
|
||||||
|
|
||||||
"git.aiterp.net/rpdata/api/internal/store"
|
|
||||||
"git.aiterp.net/rpdata/api/models/logs"
|
|
||||||
)
|
|
||||||
|
|
||||||
var prefixReplacer = strings.NewReplacer("+", "", "@", "", "!", "", "%", "")
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
err := store.Init()
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalln(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, filepath := range os.Args[1:] {
|
|
||||||
name := strings.Replace(path.Base(filepath), ".txt", "", 1)
|
|
||||||
file, err := os.Open(filepath)
|
|
||||||
if err != nil {
|
|
||||||
log.Println(filepath, err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
logLines := parseFile(file)
|
|
||||||
file.Close()
|
|
||||||
|
|
||||||
// Get title and event
|
|
||||||
title := ""
|
|
||||||
event := ""
|
|
||||||
for _, line := range logLines {
|
|
||||||
if line.Verb == "TITLE" {
|
|
||||||
title = line.Text
|
|
||||||
}
|
|
||||||
if line.Verb == "TAG" {
|
|
||||||
event = line.Text
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
date, channel, err := parseFilename(name)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalln(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
l, err := logs.Add(date, channel, title, event, "", false)
|
|
||||||
if err != nil {
|
|
||||||
log.Println(err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = posts.Add(l, time.Now(), "annotation.info", "rpdata-lb2logimport", "This logfile is imported from aitelogs2 and may contain errors or wrong timestamps.")
|
|
||||||
if err != nil {
|
|
||||||
log.Println(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, line := range logLines {
|
|
||||||
if line.Verb != "CHARS" {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = posts.Add(l, l.Date, "chars", prefixReplacer.Replace(line.Args[0]), line.Text)
|
|
||||||
if err != nil {
|
|
||||||
log.Println(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, line := range logLines {
|
|
||||||
if line.Verb != "SCENE" && line.Verb != "ACTION" && line.Verb != "TEXT" {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
postTime, err := time.ParseInLocation("2006-01-02 15:04:05", date.Format("2006-01-02")+" "+line.Args[1], time.Local)
|
|
||||||
diff := postTime.Sub(date)
|
|
||||||
if err != nil {
|
|
||||||
log.Println(err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if diff < 0 {
|
|
||||||
if diff > -time.Second {
|
|
||||||
postTime = postTime.Add(diff)
|
|
||||||
} else {
|
|
||||||
postTime = postTime.Add(time.Hour * 24)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if line.Args[0][0] == '=' {
|
|
||||||
line.Verb = "SCENE"
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = posts.Add(l, postTime, strings.ToLower(line.Verb), prefixReplacer.Replace(line.Args[0]), line.Text)
|
|
||||||
if err != nil {
|
|
||||||
log.Println(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
l, err = logs.UpdateCharacters(l, nil)
|
|
||||||
if err != nil {
|
|
||||||
log.Println(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Println(l.ID, "completed")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,77 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"log"
|
|
||||||
"net/http"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"git.aiterp.net/rpdata/api/internal/config"
|
|
||||||
"git.aiterp.net/rpdata/api/internal/store"
|
|
||||||
"git.aiterp.net/rpdata/api/models/files"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
client := http.Client{Timeout: time.Second * 30}
|
|
||||||
|
|
||||||
res, err := client.Get(config.Global().Wiki.URL + "?action=query&list=allimages&ailimit=5&aiprop=dimensions|mime|url|user|timestamp&format=json&ailimit=500")
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalln(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if res.StatusCode != 200 {
|
|
||||||
log.Fatalln(res.Status)
|
|
||||||
}
|
|
||||||
|
|
||||||
data := ResponseData{}
|
|
||||||
err = json.NewDecoder(res.Body).Decode(&data)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalln(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
store.Init()
|
|
||||||
|
|
||||||
for _, info := range data.Query.Allimages {
|
|
||||||
existing, err := files.FindName("wiki", info.Name, info.User)
|
|
||||||
if err == nil && existing.ID != "" {
|
|
||||||
log.Println("Skipping", info.Name, "because it already exists")
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
ts, err := time.Parse(time.RFC3339, info.Timestamp)
|
|
||||||
if err != nil {
|
|
||||||
log.Println("Skipping", info.Name, "error:", err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
file, err := files.Insert(info.Name, "wiki", info.Mime, info.User, ts, info.Size, info.URL)
|
|
||||||
if err != nil {
|
|
||||||
log.Println("Skipping", info.Name, "error:", err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Println(file.Name, "inserted ( id:", file.ID, ")")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// The ResponseData from the wiki looks like this
|
|
||||||
type ResponseData struct {
|
|
||||||
Batchcomplete string `json:"batchcomplete"`
|
|
||||||
Query struct {
|
|
||||||
Allimages []struct {
|
|
||||||
Descriptionshorturl string `json:"descriptionshorturl"`
|
|
||||||
Descriptionurl string `json:"descriptionurl"`
|
|
||||||
Height int `json:"height"`
|
|
||||||
Mime string `json:"mime"`
|
|
||||||
Name string `json:"name"`
|
|
||||||
Ns int `json:"ns"`
|
|
||||||
Size int64 `json:"size"`
|
|
||||||
Timestamp string `json:"timestamp"`
|
|
||||||
Title string `json:"title"`
|
|
||||||
URL string `json:"url"`
|
|
||||||
User string `json:"user"`
|
|
||||||
Width int `json:"width"`
|
|
||||||
} `json:"allimages"`
|
|
||||||
} `json:"query"`
|
|
||||||
}
|
|
||||||
@@ -8,15 +8,10 @@ require (
|
|||||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible
|
github.com/dgrijalva/jwt-go v3.2.0+incompatible
|
||||||
github.com/globalsign/mgo v0.0.0-20180403085842-f76e4f9da92e
|
github.com/globalsign/mgo v0.0.0-20180403085842-f76e4f9da92e
|
||||||
github.com/go-ini/ini v1.35.0 // indirect
|
github.com/go-ini/ini v1.35.0 // indirect
|
||||||
github.com/go-sql-driver/mysql v1.4.0
|
|
||||||
github.com/golang/protobuf v1.3.1 // indirect
|
github.com/golang/protobuf v1.3.1 // indirect
|
||||||
github.com/google/go-cmp v0.3.0 // indirect
|
github.com/google/go-cmp v0.3.0 // indirect
|
||||||
github.com/gorilla/websocket v1.4.0 // indirect
|
github.com/gorilla/websocket v1.4.0 // indirect
|
||||||
github.com/graph-gophers/dataloader v0.0.0-20180104184831-78139374585c
|
|
||||||
github.com/h2non/filetype v1.0.8
|
github.com/h2non/filetype v1.0.8
|
||||||
github.com/jmoiron/sqlx v0.0.0-20180614180643-0dae4fefe7c0
|
|
||||||
github.com/lib/pq v1.1.1 // indirect
|
|
||||||
github.com/mattn/go-sqlite3 v1.10.0 // indirect
|
|
||||||
github.com/minio/minio-go v0.0.0-20180409193742-3d2d02921f05
|
github.com/minio/minio-go v0.0.0-20180409193742-3d2d02921f05
|
||||||
github.com/mitchellh/go-homedir v0.0.0-20161203194507-b8bc1bf76747 // indirect
|
github.com/mitchellh/go-homedir v0.0.0-20161203194507-b8bc1bf76747 // indirect
|
||||||
github.com/prometheus/client_golang v0.9.1
|
github.com/prometheus/client_golang v0.9.1
|
||||||
@@ -33,7 +28,6 @@ require (
|
|||||||
golang.org/x/net v0.0.0-20190514140710-3ec191127204 // indirect
|
golang.org/x/net v0.0.0-20190514140710-3ec191127204 // indirect
|
||||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58
|
golang.org/x/sync v0.0.0-20190423024810-112230192c58
|
||||||
golang.org/x/text v0.3.0 // indirect
|
golang.org/x/text v0.3.0 // indirect
|
||||||
google.golang.org/appengine v1.1.0 // indirect
|
|
||||||
gopkg.in/ini.v1 v1.42.0 // indirect
|
gopkg.in/ini.v1 v1.42.0 // indirect
|
||||||
gopkg.in/yaml.v2 v2.2.2
|
gopkg.in/yaml.v2 v2.2.2
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -21,8 +21,6 @@ github.com/go-ini/ini v1.35.0 h1:D/my3+xOfqZMkJpciRcyqU7XMBUgiZa9qXjZIa8uv2k=
|
|||||||
github.com/go-ini/ini v1.35.0/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8=
|
github.com/go-ini/ini v1.35.0/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8=
|
||||||
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||||
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
||||||
github.com/go-sql-driver/mysql v1.4.0 h1:7LxgVwFb2hIQtMm87NdgAVfXjnt4OePseqT1tKx+opk=
|
|
||||||
github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
|
|
||||||
github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=
|
github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=
|
||||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||||
github.com/gogo/protobuf v1.0.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
github.com/gogo/protobuf v1.0.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||||
@@ -40,14 +38,10 @@ github.com/gorilla/mux v1.6.1/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2z
|
|||||||
github.com/gorilla/websocket v1.2.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
github.com/gorilla/websocket v1.2.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
||||||
github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q=
|
github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q=
|
||||||
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
||||||
github.com/graph-gophers/dataloader v0.0.0-20180104184831-78139374585c h1:94S+uoVVMpQAEOrqGjCDyUdML4dJDkh6aC4MYmXECg4=
|
|
||||||
github.com/graph-gophers/dataloader v0.0.0-20180104184831-78139374585c/go.mod h1:jk4jk0c5ZISbKaMe8WsVopGB5/15GvGHMdMdPtwlRp4=
|
|
||||||
github.com/h2non/filetype v1.0.8 h1:le8gpf+FQA0/DlDABbtisA1KiTS0Xi+YSC/E8yY3Y14=
|
github.com/h2non/filetype v1.0.8 h1:le8gpf+FQA0/DlDABbtisA1KiTS0Xi+YSC/E8yY3Y14=
|
||||||
github.com/h2non/filetype v1.0.8/go.mod h1:isekKqOuhMj+s/7r3rIeTErIRy4Rub5uBWHfvMusLMU=
|
github.com/h2non/filetype v1.0.8/go.mod h1:isekKqOuhMj+s/7r3rIeTErIRy4Rub5uBWHfvMusLMU=
|
||||||
github.com/hashicorp/golang-lru v0.5.0 h1:CL2msUPvZTLb5O648aiLNJw3hnBxN2+1Jq8rCOH9wdo=
|
github.com/hashicorp/golang-lru v0.5.0 h1:CL2msUPvZTLb5O648aiLNJw3hnBxN2+1Jq8rCOH9wdo=
|
||||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||||
github.com/jmoiron/sqlx v0.0.0-20180614180643-0dae4fefe7c0 h1:5B0uxl2lzNRVkJVg+uGHxWtRt4C0Wjc6kJKo5XYx8xE=
|
|
||||||
github.com/jmoiron/sqlx v0.0.0-20180614180643-0dae4fefe7c0/go.mod h1:IiEW3SEiiErVyFdH8NTuWjSifiEQKUoyK3LNqr2kCHU=
|
|
||||||
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
|
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
|
||||||
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
||||||
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
||||||
@@ -58,10 +52,6 @@ github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORN
|
|||||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||||
github.com/lib/pq v1.1.1 h1:sJZmqHoEaY7f+NPP8pgLB/WxulyR3fewgCM2qaSlBb4=
|
|
||||||
github.com/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
|
||||||
github.com/mattn/go-sqlite3 v1.10.0 h1:jbhqpg7tQe4SupckyijYiy0mJJ/pRyHvXf7JdWK860o=
|
|
||||||
github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
|
||||||
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
|
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
|
||||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||||
github.com/minio/minio-go v0.0.0-20180409193742-3d2d02921f05 h1:YEyFCqmHcmbcTLqZ7yEAg7VIUat6PuDzGbIctZy888k=
|
github.com/minio/minio-go v0.0.0-20180409193742-3d2d02921f05 h1:YEyFCqmHcmbcTLqZ7yEAg7VIUat6PuDzGbIctZy888k=
|
||||||
@@ -138,8 +128,6 @@ golang.org/x/tools v0.0.0-20190125232054-d66bd3c5d5a6/go.mod h1:n7NCudcB/nEzxVGm
|
|||||||
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||||
golang.org/x/tools v0.0.0-20190515012406-7d7faa4812bd h1:oMEQDWVXVNpceQoVd1JN3CQ7LYJJzs5qWqZIUcxXHHw=
|
golang.org/x/tools v0.0.0-20190515012406-7d7faa4812bd h1:oMEQDWVXVNpceQoVd1JN3CQ7LYJJzs5qWqZIUcxXHHw=
|
||||||
golang.org/x/tools v0.0.0-20190515012406-7d7faa4812bd/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
golang.org/x/tools v0.0.0-20190515012406-7d7faa4812bd/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||||
google.golang.org/appengine v1.1.0 h1:igQkv0AAhEIvTEpD5LIpAfav2eeVO9HBTjvKHVJPRSs=
|
|
||||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
|
||||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
||||||
|
|||||||
@@ -1,83 +0,0 @@
|
|||||||
package files
|
|
||||||
|
|
||||||
import (
|
|
||||||
"crypto/rand"
|
|
||||||
"encoding/binary"
|
|
||||||
"strconv"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"git.aiterp.net/rpdata/api/internal/store"
|
|
||||||
"git.aiterp.net/rpdata/api/models"
|
|
||||||
"github.com/globalsign/mgo"
|
|
||||||
)
|
|
||||||
|
|
||||||
var collection *mgo.Collection
|
|
||||||
|
|
||||||
func find(query interface{}) (models.File, error) {
|
|
||||||
file := models.File{}
|
|
||||||
|
|
||||||
err := collection.Find(query).One(&file)
|
|
||||||
if err != nil {
|
|
||||||
return models.File{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return file, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func list(query interface{}) ([]models.File, error) {
|
|
||||||
list := make([]models.File, 0, 32)
|
|
||||||
|
|
||||||
err := collection.Find(query).Sort("-time").All(&list)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return list, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// makeID makes a random file ID that's 32 characters long
|
|
||||||
func makeID() string {
|
|
||||||
result := "F" + strconv.FormatInt(time.Now().UnixNano(), 36)
|
|
||||||
offset := 0
|
|
||||||
data := make([]byte, 32)
|
|
||||||
|
|
||||||
rand.Read(data)
|
|
||||||
for len(result) < 32 {
|
|
||||||
result += strconv.FormatUint(binary.LittleEndian.Uint64(data[offset:]), 36)
|
|
||||||
offset += 8
|
|
||||||
|
|
||||||
if offset >= 32 {
|
|
||||||
rand.Read(data)
|
|
||||||
offset = 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result[:32]
|
|
||||||
}
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
store.HandleInit(func(db *mgo.Database) {
|
|
||||||
collection = db.C("file.headers")
|
|
||||||
|
|
||||||
collection.EnsureIndexKey("author")
|
|
||||||
collection.EnsureIndexKey("public")
|
|
||||||
collection.EnsureIndexKey("kind", "name", "author")
|
|
||||||
collection.EnsureIndexKey("author", "public")
|
|
||||||
collection.EnsureIndexKey("kind")
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
var allowdMimeTypes = map[string]bool{
|
|
||||||
"": false,
|
|
||||||
"image/jpeg": true,
|
|
||||||
"image/png": true,
|
|
||||||
"image/gif": true,
|
|
||||||
"image/tiff": true,
|
|
||||||
"image/tga": true,
|
|
||||||
"text/plain": true,
|
|
||||||
"application/json": true,
|
|
||||||
"application/pdf": false,
|
|
||||||
"binary/octet-stream": false,
|
|
||||||
"video/mp4": false,
|
|
||||||
"audio/mp3": false,
|
|
||||||
}
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
package files
|
|
||||||
|
|
||||||
import (
|
|
||||||
"git.aiterp.net/rpdata/api/models"
|
|
||||||
"github.com/globalsign/mgo/bson"
|
|
||||||
)
|
|
||||||
|
|
||||||
// FindID finds a file by ID
|
|
||||||
func FindID(id string) (models.File, error) {
|
|
||||||
return find(bson.M{"_id": id})
|
|
||||||
}
|
|
||||||
|
|
||||||
// FindName finds a file by ID
|
|
||||||
func FindName(kind, name, author string) (models.File, error) {
|
|
||||||
return find(bson.M{"name": name, "kind": kind, "author": author})
|
|
||||||
}
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
package files
|
|
||||||
|
|
||||||
import (
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"git.aiterp.net/rpdata/api/models"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Insert manually inserts file information into the database. This should never, ever be HTTP API accessible
|
|
||||||
func Insert(name, kind, mimeType, author string, time time.Time, size int64, url string) (models.File, error) {
|
|
||||||
file := models.File{
|
|
||||||
ID: makeID(),
|
|
||||||
Kind: kind,
|
|
||||||
Time: time,
|
|
||||||
Public: false,
|
|
||||||
Author: author,
|
|
||||||
Name: name,
|
|
||||||
MimeType: mimeType,
|
|
||||||
Size: size,
|
|
||||||
URL: url,
|
|
||||||
}
|
|
||||||
|
|
||||||
err := collection.Insert(file)
|
|
||||||
if err != nil {
|
|
||||||
return models.File{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return file, nil
|
|
||||||
}
|
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
package files
|
|
||||||
|
|
||||||
import (
|
|
||||||
"git.aiterp.net/rpdata/api/models"
|
|
||||||
"github.com/globalsign/mgo/bson"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Filter for files.List
|
|
||||||
type Filter struct {
|
|
||||||
Author *string
|
|
||||||
Public *bool
|
|
||||||
MimeType []string
|
|
||||||
}
|
|
||||||
|
|
||||||
// List lists files according to the standard lookup. By default it's just the author's own files,
|
|
||||||
// but if `public` is true it will alos include files made public by other authors. If `mimeTypes` contains
|
|
||||||
// any, it will limit the results to that. If `author` is empty, it will only list public files
|
|
||||||
func List(filter *Filter) ([]models.File, error) {
|
|
||||||
query := bson.M{}
|
|
||||||
|
|
||||||
if filter != nil {
|
|
||||||
if filter.Author != nil {
|
|
||||||
query["author"] = *filter.Author
|
|
||||||
}
|
|
||||||
|
|
||||||
if filter.Public != nil {
|
|
||||||
query["public"] = *filter.Public
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(filter.MimeType) > 0 {
|
|
||||||
query["mimeTypes"] = bson.M{"$in": filter.MimeType}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return list(query)
|
|
||||||
}
|
|
||||||
@@ -1,52 +0,0 @@
|
|||||||
package files
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"errors"
|
|
||||||
"io"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"git.aiterp.net/rpdata/api/internal/store"
|
|
||||||
"git.aiterp.net/rpdata/api/models"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Upload adds a file to the space.
|
|
||||||
func Upload(ctx context.Context, name, mimeType, author string, size int64, input io.Reader) (models.File, error) {
|
|
||||||
if !allowdMimeTypes[mimeType] {
|
|
||||||
return models.File{}, errors.New("File type not allowed:" + mimeType)
|
|
||||||
}
|
|
||||||
|
|
||||||
if name == "" {
|
|
||||||
date := time.Now().UTC().Format("Jan 02 2006 15:04:05 MST")
|
|
||||||
name = "Unnamed file (" + date + ")"
|
|
||||||
}
|
|
||||||
if mimeType == "" {
|
|
||||||
mimeType = "binary/octet-stream"
|
|
||||||
}
|
|
||||||
|
|
||||||
id := makeID()
|
|
||||||
|
|
||||||
path, err := store.UploadFile(ctx, "files", id, mimeType, input, size)
|
|
||||||
if err != nil {
|
|
||||||
return models.File{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
file := models.File{
|
|
||||||
ID: id,
|
|
||||||
Kind: "upload",
|
|
||||||
Time: time.Now(),
|
|
||||||
Public: false,
|
|
||||||
Author: author,
|
|
||||||
Name: name,
|
|
||||||
MimeType: mimeType,
|
|
||||||
Size: size,
|
|
||||||
URL: store.URLFromPath(path),
|
|
||||||
}
|
|
||||||
|
|
||||||
err = collection.Insert(file)
|
|
||||||
if err != nil {
|
|
||||||
return models.File{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return file, nil
|
|
||||||
}
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
package users
|
|
||||||
|
|
||||||
import (
|
|
||||||
"git.aiterp.net/rpdata/api/internal/store"
|
|
||||||
"github.com/globalsign/mgo"
|
|
||||||
)
|
|
||||||
|
|
||||||
var collection *mgo.Collection
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
store.HandleInit(func(db *mgo.Database) {
|
|
||||||
collection = db.C("core.users")
|
|
||||||
})
|
|
||||||
}
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
package users
|
|
||||||
|
|
||||||
import (
|
|
||||||
"git.aiterp.net/rpdata/api/models"
|
|
||||||
"github.com/globalsign/mgo"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Ensure finds a user by id, or makes a new one.
|
|
||||||
func Ensure(id string) (models.User, error) {
|
|
||||||
user := models.User{}
|
|
||||||
err := collection.FindId(id).One(&user)
|
|
||||||
|
|
||||||
if err == mgo.ErrNotFound {
|
|
||||||
user = models.User{
|
|
||||||
ID: id,
|
|
||||||
Nick: "",
|
|
||||||
Permissions: []string{
|
|
||||||
"member",
|
|
||||||
"log.edit",
|
|
||||||
"post.edit",
|
|
||||||
"post.move",
|
|
||||||
"post.remove",
|
|
||||||
"file.upload",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
err := collection.Insert(user)
|
|
||||||
if err != nil {
|
|
||||||
return models.User{}, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return user, err
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
package users
|
|
||||||
|
|
||||||
import (
|
|
||||||
"git.aiterp.net/rpdata/api/models"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Find finds a user by id
|
|
||||||
func Find(id string) (models.User, error) {
|
|
||||||
user := models.User{}
|
|
||||||
err := collection.FindId(id).One(&user)
|
|
||||||
|
|
||||||
return user, err
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user