Skip to content

Commit

Permalink
add domain
Browse files Browse the repository at this point in the history
  • Loading branch information
sunwei committed Dec 5, 2024
1 parent 4035c4e commit 239ad4e
Show file tree
Hide file tree
Showing 8 changed files with 224 additions and 26 deletions.
2 changes: 1 addition & 1 deletion internal/application/deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ func DeployToNetlify(target string, deployment *valueobject.SiteDeployment, toke
SiteID: deployment.NetlifySiteID,
Directory: path.Join(target, "public"),
Draft: false,
DeployMessage: "Deployed from Hugoverse",
DeployMessage: "Deployed by MDFriday",
LogLevel: "debug",
LogFormat: "text",
}
Expand Down
33 changes: 20 additions & 13 deletions internal/domain/content/entity/deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,17 @@ import (
"errors"
"fmt"
"github.com/gohugonet/hugoverse/internal/domain/content/valueobject"
"net/url"
"time"
)

func (c *Content) GetDeployment(siteId string) (*valueobject.SiteDeployment, error) {
func (c *Content) GetDeployment(siteId string, domain *valueobject.Domain) (*valueobject.SiteDeployment, error) {
content, err := c.getContent("Site", siteId)
if err != nil {
return nil, err
}

if site, ok := content.(*valueobject.Site); ok {
sd, err := c.searchDeployment(siteId)
sd, err := c.searchDeployment(domain.Root, domain.Sub, domain.Owner)
if err != nil {
return nil, err
}
Expand All @@ -30,7 +29,7 @@ func (c *Content) GetDeployment(siteId string) (*valueobject.SiteDeployment, err
sd = &valueobject.SiteDeployment{
Item: *item,
Site: site.QueryString(),
Netlify: fmt.Sprintf("mdf-%d-%s", time.Now().Unix(), site.ItemSlug()),
Netlify: fmt.Sprintf("mdf-%d-%s", time.Now().UnixMilli(), site.ItemSlug()),
Domain: site.ItemSlug(),
Status: "Not Started",
}
Expand All @@ -47,27 +46,35 @@ func (c *Content) GetDeployment(siteId string) (*valueobject.SiteDeployment, err
return nil, errors.New("only site could be deployed")
}

func (c *Content) searchDeployment(siteId string) (*valueobject.SiteDeployment, error) {
q := fmt.Sprintf(`site%s`, siteId)
encodedQ := url.QueryEscape(q)
func (c *Content) searchDeployment(root string, sub string, owner string) (*valueobject.SiteDeployment, error) {
conditions := map[string]string{
"root": root,
"domain": sub,
"owner": owner,
}

siteDeployments, err := c.search("SiteDeployment", fmt.Sprintf("slug:%s", encodedQ))
// 查询域名信息
deploys, err := c.termSearch("SiteDeployment", conditions)
if err != nil {
return nil, err
}

if len(siteDeployments) == 1 && siteDeployments[0] == nil {
// 如果返回仅一个结果且为 nil,返回 nil
if len(deploys) == 1 && deploys[0] == nil {
return nil, nil
}

for _, data := range siteDeployments {
var sd valueobject.SiteDeployment
if err := json.Unmarshal(data, &sd); err != nil {
// 遍历查询结果并解析
for _, data := range deploys {
var deployment valueobject.SiteDeployment
if err := json.Unmarshal(data, &deployment); err != nil {
return nil, err
}

return &sd, nil
// 返回匹配的域名对象
return &deployment, nil
}

// 未找到匹配结果
return nil, nil
}
83 changes: 83 additions & 0 deletions internal/domain/content/entity/domain.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
package entity

import (
"encoding/json"
"errors"
"github.com/gohugonet/hugoverse/internal/domain/content/valueobject"
)

func (c *Content) ApplyDomain(siteId string, domain string) (*valueobject.Domain, error) {
site, err := c.getContent("Site", siteId)
if err != nil {
return nil, err
}

if site, ok := site.(*valueobject.Site); ok {
slug, err := Slug(site)
if err != nil {
return nil, err
}

sd, err := c.searchDomain(domain, slug, site.Owner)
if err != nil {
return nil, err
}

if sd == nil {
item, err := valueobject.NewItemWithNamespace("Domain")
if err != nil {
return nil, err
}

sd = &valueobject.Domain{
Item: *item,
Root: domain,
Sub: slug,
Owner: site.Owner,
}

_, err = c.newContent("Domain", sd)
if err != nil {
return nil, err
}
}

return sd, nil
}

return nil, errors.New("only site could be deployed with domain")
}

func (c *Content) searchDomain(root string, sub string, owner string) (*valueobject.Domain, error) {
// 构建精确匹配的查询条件
conditions := map[string]string{
"root": root,
"sub": sub,
"owner": owner,
}

// 查询域名信息
domains, err := c.termSearch("Domain", conditions)
if err != nil {
return nil, err
}

// 如果返回仅一个结果且为 nil,返回 nil
if len(domains) == 1 && domains[0] == nil {
return nil, nil
}

// 遍历查询结果并解析
for _, data := range domains {
var domain valueobject.Domain
if err := json.Unmarshal(data, &domain); err != nil {
return nil, err
}

// 返回匹配的域名对象
return &domain, nil
}

// 未找到匹配结果
return nil, nil
}
23 changes: 23 additions & 0 deletions internal/domain/content/entity/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,29 @@ func (c *Content) search(contentType string, query string) ([][]byte, error) {
return bb, nil
}

func (c *Content) termSearch(contentType string, keyValue map[string]string) ([][]byte, error) {
// execute search for query provided, if no index for type send 404
indices, err := c.Search.TermQuery(contentType, keyValue, 10, 0)
if errors.Is(err, content.ErrNoIndex) {
c.Log.Errorf("Index for type %s not found", contentType)

return nil, err
}
if err != nil {
c.Log.Errorf("Error searching for type %s: %v", contentType, err)
return nil, err
}

// respond with json formatted results
bb, err := c.GetContents(indices)
if err != nil {
c.Log.Errorf("Error getting content: %v", err)
return nil, err
}

return bb, nil
}

func (c *Content) getContent(contentType, id string) (any, error) {
bs, err := c.GetContent(contentType, id, "")
if err != nil {
Expand Down
40 changes: 40 additions & 0 deletions internal/domain/content/entity/search.go
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,46 @@ func (s *Search) TypeQuery(typeName, query string, count, offset int) ([]content
return results, nil
}

func (s *Search) TermQuery(typeName string, keyValues map[string]string, count, offset int) ([]content.Identifier, error) {
// 获取索引
idx, err := s.getSearchIndex(typeName)
if err != nil {
s.Log.Debugln("Index for type ", typeName, " not found", err.Error())
return nil, content.ErrNoIndex
}

s.Log.Debugln("KeyValueQuery KeyValues: ", keyValues)

// 创建每个 Key-Value 的查询
var termQueries []bleve.Query
for key, value := range keyValues {
tq := bleve.NewTermQuery(value)
tq.SetField(key)

termQueries = append(termQueries, tq)
}

// 将查询组合成一个 ConjunctionQuery
finalQuery := bleve.NewConjunctionQuery(termQueries...)

// 创建搜索请求
req := bleve.NewSearchRequestOptions(finalQuery, count, offset, false)

// 执行搜索
res, err := idx.Search(req)
if err != nil {
return nil, err
}

// 处理搜索结果
var results []content.Identifier
for _, hit := range res.Hits {
results = append(results, valueobject.CreateIndex(hit.ID))
}

return results, nil
}

// UpdateIndex sets data into a content type's search index at the given
// identifier
func (s *Search) UpdateIndex(ns, id string, data []byte) error {
Expand Down
30 changes: 21 additions & 9 deletions internal/domain/content/valueobject/domain.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,31 +9,38 @@ import (
type Domain struct {
Item

Id uint64 `json:"id"`
Root string `json:"root"`
Sub string `json:"sub"`
Email string `json:"email"`
Owner string `json:"owner"`
}

func (d *Domain) Name() string {
return d.Sub
return fmt.Sprintf("%s.%s - %s", d.Sub, d.Root, d.Owner)
}

// MarshalEditor writes a buffer of html to edit a Song within the CMS
// and implements editor.Editable
func (d *Domain) MarshalEditor() ([]byte, error) {
view, err := editor.Form(d,
editor.Field{
View: editor.Input("Root", d, map[string]string{
"label": "Root",
"type": "text",
"placeholder": "Enter the root domain here",
}),
},
editor.Field{
View: editor.Input("Sub", d, map[string]string{
"label": "SubDomain",
"label": "Sub",
"type": "text",
"placeholder": "Enter the subdomain here",
"placeholder": "Enter the sub domain here",
}),
},
editor.Field{
View: editor.Input("Email", d, map[string]string{
"label": "Email",
View: editor.Input("Owner", d, map[string]string{
"label": "Owner",
"type": "text",
"placeholder": "Enter the Email here",
"placeholder": "Enter the Owner here",
}),
},
)
Expand All @@ -54,8 +61,9 @@ func (d *Domain) String() string { return d.Name() }
func (d *Domain) Create(res http.ResponseWriter, req *http.Request) error {
// do form data validation for required fields
required := []string{
"root",
"sub",
"email",
"owner",
}

for _, r := range required {
Expand Down Expand Up @@ -125,3 +133,7 @@ func (d *Domain) AutoApprove(res http.ResponseWriter, req *http.Request) error {

return nil
}

func (d *Domain) IndexContent() bool {
return true
}
12 changes: 12 additions & 0 deletions internal/domain/content/valueobject/sitedeployment.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@ import (
"strings"
)

// TODO: deployment belongs to admin
// need netlify sub domain, and site id
// need domain root, sub, and owner info
// no need site info

type SiteDeployment struct {
Item

Expand Down Expand Up @@ -54,6 +59,13 @@ func (s *SiteDeployment) MarshalEditor() ([]byte, error) {
"placeholder": "Enter the Customized sub domain here",
}),
},
editor.Field{
View: editor.Input("Root", s, map[string]string{
"label": "Root",
"type": "text",
"placeholder": "Enter the Customized root domain here",
}),
},
editor.Field{
View: editor.Input("Status", s, map[string]string{
"label": "Status",
Expand Down
27 changes: 24 additions & 3 deletions internal/interfaces/api/handler/handledeploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,27 @@ func (s *Handler) DeployContentHandler(res http.ResponseWriter, req *http.Reques
return
}

err := req.ParseForm()
if err != nil {
s.log.Errorf("Error parsing deploy form: %v", err)
res.WriteHeader(http.StatusInternalServerError)
return
}

netlify := req.PostForm.Get("netlify")
root := req.PostForm.Get("domain")
if netlify == "" || root == "" {
netlify = s.adminApp.Netlify.Token()
root = "app.mdfriday.com"
}

d, err := s.contentApp.ApplyDomain(id, root)
if err != nil {
s.log.Errorf("Error applying domain: %v", err)
res.WriteHeader(http.StatusInternalServerError)
return
}

pt, ok := s.contentApp.GetContentCreator(t)
if !ok {
res.WriteHeader(http.StatusNotFound)
Expand All @@ -34,7 +55,7 @@ func (s *Handler) DeployContentHandler(res http.ResponseWriter, req *http.Reques
return
}

t, err := s.contentApp.BuildTarget(t, id, status)
t, err = s.contentApp.BuildTarget(t, id, status)
if err != nil {
s.log.Errorf("Error building: %v", err)
res.WriteHeader(http.StatusInternalServerError)
Expand All @@ -48,14 +69,14 @@ func (s *Handler) DeployContentHandler(res http.ResponseWriter, req *http.Reques
return
}

sd, err := s.contentApp.GetDeployment(id)
sd, err := s.contentApp.GetDeployment(id, d)
if err != nil {
s.log.Errorf("Error getting deployment: %v", err)
res.WriteHeader(http.StatusInternalServerError)
return
}

err = application.DeployToNetlify(t, sd, s.adminApp.Netlify.Token())
err = application.DeployToNetlify(t, sd, netlify)
if err != nil {
s.log.Errorf("Error building: %v", err)
res.WriteHeader(http.StatusInternalServerError)
Expand Down

0 comments on commit 239ad4e

Please sign in to comment.