different approch for complex multidimensional structures

This commit is contained in:
Jan Halfar 2014-10-02 23:32:43 +02:00
parent 8a9c1f321f
commit c5f97d80c9
9 changed files with 160 additions and 330 deletions

View File

@ -1,4 +1,4 @@
Content2Go Server
Content Server
===========
Serves content tree structures very quickly through a json socket api
@ -14,22 +14,19 @@ It's up to you how you use it and which data you want to export to the server. O
All you have to do is to provide a tree of content nodes as a JSON encoded RepoNode.
| Attribute | Type | Usage |
| ------------- |:-------------:| -----:|
| Id | string | unique id to identify the node |
| MimeType | string | mime-type of the node, e.g. text/html, image/png, ... |
| LinkIds | map[string]map[string]string | (symbolic) link/alias to another node |
| Handler | string | define a handler to easily control the output rendering |
| Regions | []string | define regions for multi-market websites |
| Groups | []string | access control |
| States | []string | server states |
| URIs | map[string]map[string]string | a map of unique URIs for each region and language to resolve and link to the node |
| Names | map[string]map[string]string | a name for this node in every region and language |
| Hidden | map[string]map[string]bool | hide in menu specific for region and language |
| DestinationIds | map[string]map[string]string | alias or symlink handling |
| Data | map[string]interface{} | payload data |
| Nodes | map[string]*RepoNode | child nodes |
| Index | []string | ??? |
| Attribute | Type | Usage |
| ------------- |:----------------------:| -----:|
| Id | string | unique id to identify the node |
| MimeType | string | mime-type of the node, e.g. text/html, image/png, ... |
| LinkId | string | (symbolic) link/alias to another node |
| Groups | []string | access control |
| URI | string | a map of unique URIs for each region and language to resolve and link to the node |
| Name | string | a name for this node in every region and language |
| Hidden | bool | hide in menu specific for region and language |
| DestinationId | string | alias or symlink handling |
| Data | map[string]interface{} | payload data |
| Nodes | map[string]*RepoNode | child nodes |
| Index | []string | contains the order of ou nodes|
### Tips
@ -43,4 +40,3 @@ All you have to do is to provide a tree of content nodes as a JSON encoded RepoN
## Request Data
There is a PHP Proxy implementation for foomo in Foomo.ContentServer. Feel free to use it or to implement your own proxy in the language you love. The API should be easily to implement in every other framework and language, too.

View File

@ -1,71 +0,0 @@
package server
import (
"fmt"
"github.com/foomo/contentserver/server/log"
"github.com/foomo/contentserver/server/repo"
"github.com/foomo/contentserver/server/requests"
"github.com/foomo/contentserver/server/utils"
"net/http"
"strconv"
"strings"
)
func contentHandler(w http.ResponseWriter, r *http.Request) {
request := requests.NewContent()
utils.PopulateRequest(r, request)
utils.JsonResponse(w, contentRepo.GetContent(request))
}
func uriHandler(w http.ResponseWriter, r *http.Request) {
parts := strings.Split(r.RequestURI, "/")
if len(parts) == 5 {
utils.JsonResponse(w, contentRepo.GetURI(parts[2], parts[3], parts[4]))
} else {
wtfHandler(w, r)
}
}
func wtfHandler(w http.ResponseWriter, r *http.Request) {
msg := "unhandled request: " + r.RequestURI
fmt.Fprint(w, msg, "\n")
log.Error(msg)
}
func update() interface{} {
contentRepo.Update()
return contentRepo.Directory
}
func commandHandler(w http.ResponseWriter, r *http.Request) {
parts := strings.Split(r.RequestURI, "/")
switch true {
case true == (len(parts) > 1):
switch parts[2] {
case "update":
utils.JsonResponse(w, update())
return
default:
help := make(map[string]interface{})
help["input"] = parts[2]
help["commands"] = []string{"update", "help", "content"}
utils.JsonResponse(w, help)
}
default:
wtfHandler(w, r)
}
}
func Run(addr string, serverUrl string) {
log.Notice("starting content server")
log.Notice(" loading content from " + serverUrl)
contentRepo = repo.NewRepo(serverUrl)
contentRepo.Update()
log.Notice(" loaded " + strconv.Itoa(len(contentRepo.Directory)) + " items")
http.HandleFunc("/content", contentHandler)
http.HandleFunc("/uri/", uriHandler)
http.HandleFunc("/cmd/", commandHandler)
http.HandleFunc("/", wtfHandler)
log.Notice(" starting service on " + addr)
http.ListenAndServe(addr, nil)
}

View File

@ -6,39 +6,21 @@ import (
)
type RepoNode struct {
Id string `json:"id"` // unique identifier - it is your responsibility, that they are unique
MimeType string `json:"mimeType"` // well a mime type http://www.ietf.org/rfc/rfc2046.txt
LinkIds map[string]map[string]string `json:"linkIds"` // (symbolic) link/alias to another node
Handler string `json:"handler"` // that information is for you
Regions []string `json:"regions"` // in what regions is this node available, if empty it will be accessible everywhere
Groups []string `json:"groups"` // which groups have access to the node, if empty everybody has access to it
States []string `json:"states"` // in which states is this node valid, if empty => in all of them
URIs map[string]map[string]string `json:"URIs"`
Names map[string]map[string]string `json:"names"`
Hidden map[string]map[string]bool `json:"hidden"` // hidden in content.nodes, but can still be resolved when being directly addressed
DestinationIds map[string]map[string]string `json:"destinationIds"` // if a node does not have any content like a folder the destinationIds can point to nodes that do aka. the first displayable child node
Data map[string]interface{} `json:"data"` // what ever you want to stuff into it - the payload you want to attach to a node
Nodes map[string]*RepoNode `json:"nodes"` // child nodes
Index []string `json:"index"` // defines the order of the child nodes
parent *RepoNode // parent node - helps to resolve a path / bread crumb
Id string `json:"id"` // unique identifier - it is your responsibility, that they are unique
MimeType string `json:"mimeType"` // well a mime type http://www.ietf.org/rfc/rfc2046.txt
LinkId string `json:"linkIds"` // (symbolic) link/alias to another node
Groups []string `json:"groups"` // which groups have access to the node, if empty everybody has access to it
URI string `json:"URI"`
Name string `json:"names"`
Hidden bool `json:"hidden"` // hidden in content.nodes, but can still be resolved when being directly addressed
DestinationId string `json:"destinationId"` // if a node does not have any content like a folder the destinationIds can point to nodes that do aka. the first displayable child node
Data map[string]interface{} `json:"data"` // what ever you want to stuff into it - the payload you want to attach to a node
Nodes map[string]*RepoNode `json:"nodes"` // child nodes
Index []string `json:"index"` // defines the order of the child nodes
parent *RepoNode // parent node - helps to resolve a path / bread crumb
// published from - to is going to be an array of fromTos
}
func (node *RepoNode) GetLanguageAndRegionForURI(URI string) (resolved bool, region string, language string) {
for possibleRegion, URIs := range node.URIs {
for possibleLanguage, regionLangURI := range URIs {
if regionLangURI == URI {
resolved = true
region = possibleRegion
language = possibleLanguage
return
}
}
}
resolved = false
return
}
func (node *RepoNode) WireParents() {
for _, childNode := range node.Nodes {
childNode.parent = node
@ -56,29 +38,7 @@ func (node *RepoNode) InPath(path []*Item) bool {
return false
}
func (node *RepoNode) InState(state string) bool {
if len(node.States) == 0 {
return true
} else {
for _, nodeState := range node.States {
if state == nodeState {
return true
}
}
return false
}
}
func (node *RepoNode) InRegion(region string) bool {
for _, nodeRegion := range node.Regions {
if nodeRegion == region {
return true
}
}
return false
}
func (node *RepoNode) GetPath(region string, language string) []*Item {
func (node *RepoNode) GetPath() []*Item {
parentNode := node.parent
pathLength := 0
for parentNode != nil {
@ -89,18 +49,18 @@ func (node *RepoNode) GetPath(region string, language string) []*Item {
i := 0
path := make([]*Item, pathLength)
for parentNode != nil {
path[i] = parentNode.ToItem(region, language, []string{})
path[i] = parentNode.ToItem([]string{})
parentNode = parentNode.parent
i++
}
return path
}
func (node *RepoNode) ToItem(region string, language string, dataFields []string) *Item {
func (node *RepoNode) ToItem(dataFields []string) *Item {
item := NewItem()
item.Id = node.Id
item.Name = node.GetName(region, language)
item.URI = node.URIs[region][language] //uri //repo.GetURI(region, language, node.Id)
item.Name = node.Name
item.URI = node.URI
for _, dataField := range dataFields {
if data, ok := node.Data[dataField]; ok {
item.Data[dataField] = data
@ -118,21 +78,6 @@ func (node *RepoNode) AddNode(name string, childNode *RepoNode) *RepoNode {
return node
}
func (node *RepoNode) IsHidden(region string, language string) bool {
if regionMap, ok := node.Hidden[region]; ok {
if languageHidden, ok := regionMap[language]; ok {
return languageHidden
} else {
return false
}
}
return false
}
func (node *RepoNode) GetName(region string, language string) string {
return node.Names[region][language]
}
func (node *RepoNode) IsOneOfTheseMimeTypes(mimeTypes []string) bool {
if len(mimeTypes) == 0 {
return true
@ -164,10 +109,7 @@ func (node *RepoNode) CanBeAccessedByGroups(groups []string) bool {
func (node *RepoNode) PrintNode(id string, level int) {
prefix := strings.Repeat(INDENT, level)
fmt.Printf("%s %s:\n", prefix, id)
for lang, name := range node.Names {
fmt.Printf("%s %s: %s\n", prefix+INDENT, lang, name)
}
fmt.Printf("%s %s %s:\n", prefix, id, node.Name)
for key, childNode := range node.Nodes {
childNode.PrintNode(key, level+1)
}

View File

@ -7,16 +7,15 @@ const (
)
type SiteContent struct {
Status int `json:"status"`
URI string `json:"URI"`
Region string `json:"region"`
Language string `json:"language"`
Handler string `json:"handler"`
Item *Item `json:"item"`
Data interface{} `json:"data"`
Path []*Item `json:"path"`
URIs map[string]string `json:"URIs"`
Nodes map[string]*Node `json:"nodes"`
Status int `json:"status"`
URI string `json:"URI"`
Dimension string `json:"dimension"`
MimeType string `json:"mimeType"`
Item *Item `json:"item"`
Data interface{} `json:"data"`
Path []*Item `json:"path"`
URIs map[string]string `json:"URIs"`
Nodes map[string]*Node `json:"nodes"`
}
func NewSiteContent() *SiteContent {

View File

@ -12,38 +12,49 @@ import (
"time"
)
type Dimension struct {
Directory map[string]*content.RepoNode
URIDirectory map[string]*content.RepoNode
Node *content.RepoNode
}
type RepoDimension struct {
Dimension string
Node *content.RepoNode
}
type Repo struct {
server string
Regions []string
Languages []string
Directory map[string]*content.RepoNode
URIDirectory map[string]*content.RepoNode
Node *content.RepoNode
updateChannel chan *content.RepoNode
Directory map[string]*Dimension
updateChannel chan *RepoDimension
updateDoneChannel chan error
}
func NewRepo(server string) *Repo {
log.Notice("creating new repo for " + server)
repo := new(Repo)
repo.Directory = make(map[string]*Dimension)
repo.server = server
repo.updateChannel = make(chan *content.RepoNode)
repo.updateChannel = make(chan *RepoDimension)
repo.updateDoneChannel = make(chan error)
go func() {
select {
case newNode := <-repo.updateChannel:
repo.updateDoneChannel <- repo.load(newNode)
case newDimension := <-repo.updateChannel:
repo.updateDoneChannel <- repo.load(newDimension.Dimension, newDimension.Node)
}
}()
return repo
}
func (repo *Repo) Load(newNode *content.RepoNode) error {
repo.updateChannel <- newNode
func (repo *Repo) Load(dimension string, node *content.RepoNode) error {
repo.updateChannel <- &RepoDimension{
Dimension: dimension,
Node: node,
}
return <-repo.updateDoneChannel
}
func (repo *Repo) load(newNode *content.RepoNode) error {
func (repo *Repo) load(dimension string, newNode *content.RepoNode) error {
newNode.WireParents()
newDirectory := make(map[string]*content.RepoNode)
newURIDirectory := make(map[string]*content.RepoNode)
@ -56,104 +67,81 @@ func (repo *Repo) load(newNode *content.RepoNode) error {
if err != nil {
return err
}
repo.Node = newNode
repo.Directory = newDirectory
repo.URIDirectory = newURIDirectory
repo.Directory[dimension] = &Dimension{
Node: newNode,
Directory: newDirectory,
URIDirectory: newURIDirectory,
}
return nil
}
func (repo *Repo) ResolveContent(state string, URI string) (resolved bool, resolvedURI string, region string, language string, repoNode *content.RepoNode) {
func (repo *Repo) ResolveContent(dimensions []string, URI string) (resolved bool, resolvedURI string, resolvedDimension string, repoNode *content.RepoNode) {
parts := strings.Split(URI, content.PATH_SEPARATOR)
log.Debug("repo.ResolveContent: " + URI)
for i := len(parts); i > -1; i-- {
testURI := strings.Join(parts[0:i], content.PATH_SEPARATOR)
testURIKey := uriKeyForState(state, testURI)
log.Debug(" testing" + testURIKey)
if repoNode, ok := repo.URIDirectory[testURIKey]; ok {
resolved = true
_, region, language := repoNode.GetLanguageAndRegionForURI(testURI)
log.Debug(" => " + testURIKey)
log.Debug(" destination " + fmt.Sprint(repoNode.DestinationIds))
// check this one
// repoNode = repo.Directory[repoNode.DestinationIds]
if languageDestinations, regionOk := repoNode.DestinationIds[region]; regionOk {
// this check should happen, when updating the repo
log.Debug(" there is a destionation map for this one " + fmt.Sprint(languageDestinations))
if languageDestination, destinationOk := languageDestinations[language]; destinationOk {
if destinationNode, destinationNodeOk := repo.Directory[languageDestination]; destinationNodeOk {
repoNode = destinationNode
} else {
log.Debug(" could not resolve this destinationId : " + languageDestination)
for _, dimension := range dimensions {
if d, ok := repo.Directory[dimension]; ok {
for i := len(parts); i > -1; i-- {
testURI := strings.Join(parts[0:i], content.PATH_SEPARATOR)
log.Debug(" testing" + testURI)
if repoNode, ok := d.URIDirectory[testURI]; ok {
resolved = true
log.Debug(" => " + testURI)
log.Debug(" destination " + fmt.Sprint(repoNode.DestinationId))
if len(repoNode.DestinationId) > 0 {
if destionationNode, destinationNodeOk := d.Directory[repoNode.DestinationId]; destinationNodeOk {
repoNode = destionationNode
}
}
return true, testURI, dimension, repoNode
} else {
log.Debug(" => !" + testURI)
resolved = false
}
}
return true, testURI, region, language, repoNode
} else {
log.Debug(" => !" + testURI)
resolved = false
}
}
return
}
func (repo *Repo) GetItemMap(id string, dataFields []string) map[string]map[string]*content.Item {
itemMap := make(map[string]map[string]*content.Item)
if repoNode, ok := repo.Directory[id]; ok {
for region, languageURIs := range repoNode.URIs {
itemMap[region] = make(map[string]*content.Item)
for language, URI := range languageURIs {
log.Debug(fmt.Sprintf("region :%s language :%s URI: %s", region, language, URI))
itemMap[region][language] = repoNode.ToItem(region, language, dataFields)
}
}
} else {
log.Warning("GetItemMapForAllRegionsAndLanguages invalid id " + id)
}
return itemMap
}
func (repo *Repo) GetURIs(region string, language string, ids []string) map[string]string {
func (repo *Repo) GetURIs(dimension string, ids []string) map[string]string {
uris := make(map[string]string)
for _, id := range ids {
uris[id] = repo.GetURI(region, language, id)
uris[id] = repo.GetURI(dimension, id)
}
return uris
}
func (repo *Repo) GetURIForNode(region string, language string, repoNode *content.RepoNode) string {
func (repo *Repo) GetURIForNode(dimension string, repoNode *content.RepoNode) string {
if len(repoNode.LinkIds) == 0 {
languageURIs, regionExists := repoNode.URIs[region]
if regionExists {
languageURI, languageURIExists := languageURIs[language]
if languageURIExists {
return languageURI
}
}
return ""
if len(repoNode.LinkId) == 0 {
return repoNode.URI
} else {
return repo.GetURI(region, language, repoNode.LinkIds[region][language])
linkedNode, ok := repo.Directory[dimension].Directory[repoNode.LinkId]
if ok {
return repo.GetURIForNode(dimension, linkedNode)
} else {
return ""
}
}
}
func (repo *Repo) GetURI(region string, language string, id string) string {
repoNode, ok := repo.Directory[id]
func (repo *Repo) GetURI(dimension string, id string) string {
repoNode, ok := repo.Directory[dimension].Directory[id]
if ok {
return repo.GetURIForNode(region, language, repoNode)
return repo.GetURIForNode(dimension, repoNode)
}
return ""
}
func (repo *Repo) GetNode(repoNode *content.RepoNode, expanded bool, mimeTypes []string, path []*content.Item, level int, state string, groups []string, region string, language string, dataFields []string) *content.Node {
func (repo *Repo) GetNode(repoNode *content.RepoNode, expanded bool, mimeTypes []string, path []*content.Item, level int, groups []string, dataFields []string) *content.Node {
node := content.NewNode()
node.Item = repoNode.ToItem(region, language, dataFields)
node.Item = repoNode.ToItem(dataFields)
log.Debug("repo.GetNode: " + repoNode.Id)
for _, childId := range repoNode.Index {
childNode := repoNode.Nodes[childId]
if (level == 0 || expanded || !expanded && childNode.InPath(path)) && childNode.InState(state) && !childNode.IsHidden(region, language) && childNode.CanBeAccessedByGroups(groups) && childNode.IsOneOfTheseMimeTypes(mimeTypes) && childNode.InRegion(region) {
node.Nodes[childId] = repo.GetNode(childNode, expanded, mimeTypes, path, level+1, state, groups, region, language, dataFields)
if (level == 0 || expanded || !expanded && childNode.InPath(path)) && !childNode.Hidden && childNode.CanBeAccessedByGroups(groups) && childNode.IsOneOfTheseMimeTypes(mimeTypes) {
node.Nodes[childId] = repo.GetNode(childNode, expanded, mimeTypes, path, level+1, groups, dataFields)
node.Index = append(node.Index, childId)
}
}
@ -165,8 +153,8 @@ func (repo *Repo) GetNodes(r *requests.Nodes) map[string]*content.Node {
path := make([]*content.Item, 0)
for nodeName, nodeRequest := range r.Nodes {
log.Debug(" adding node " + nodeName + " " + nodeRequest.Id)
if treeNode, ok := repo.Directory[nodeRequest.Id]; ok {
nodes[nodeName] = repo.GetNode(treeNode, nodeRequest.Expand, nodeRequest.MimeTypes, path, 0, r.Env.State, r.Env.Groups, r.Env.Defaults.Region, r.Env.Defaults.Language, nodeRequest.DataFields)
if treeNode, ok := repo.Directory[nodeRequest.Dimension].Directory[nodeRequest.Id]; ok {
nodes[nodeName] = repo.GetNode(treeNode, nodeRequest.Expand, nodeRequest.MimeTypes, path, 0, r.Env.Groups, nodeRequest.DataFields)
} else {
log.Warning("you are requesting an invalid tree node for " + nodeName + " : " + nodeRequest.Id)
}
@ -177,28 +165,26 @@ func (repo *Repo) GetNodes(r *requests.Nodes) map[string]*content.Node {
func (repo *Repo) GetContent(r *requests.Content) *content.SiteContent {
log.Debug("repo.GetContent: " + r.URI)
c := content.NewSiteContent()
resolved, resolvedURI, region, language, node := repo.ResolveContent(r.Env.State, r.URI)
resolved, resolvedURI, resolvedDimension, node := repo.ResolveContent(r.Env.Dimensions, r.URI)
if resolved {
log.Notice("200 for " + r.URI)
// forbidden ?!
c.Region = region
c.Language = language
c.Status = content.STATUS_OK
c.Handler = node.Handler
c.MimeType = node.MimeType
c.Dimension = resolvedDimension
c.URI = resolvedURI
c.Item = node.ToItem(region, language, []string{})
c.Path = node.GetPath(region, language)
c.Item = node.ToItem([]string{})
c.Path = node.GetPath()
c.Data = node.Data
} else {
log.Notice("404 for " + r.URI)
c.Status = content.STATUS_NOT_FOUND
region = r.Env.Defaults.Region
language = r.Env.Defaults.Language
c.Dimension = r.Env.Dimensions[0]
}
for treeName, treeRequest := range r.Nodes {
log.Debug(" adding tree " + treeName + " " + treeRequest.Id)
if treeNode, ok := repo.Directory[treeRequest.Id]; ok {
c.Nodes[treeName] = repo.GetNode(treeNode, treeRequest.Expand, treeRequest.MimeTypes, c.Path, 0, r.Env.State, r.Env.Groups, region, language, treeRequest.DataFields)
if treeNode, ok := repo.Directory[resolvedDimension].Directory[treeRequest.Id]; ok {
c.Nodes[treeName] = repo.GetNode(treeNode, treeRequest.Expand, treeRequest.MimeTypes, c.Path, 0, r.Env.Groups, treeRequest.DataFields)
} else {
log.Warning("you are requesting an invalid tree node for " + treeName + " : " + treeRequest.Id)
}
@ -206,10 +192,11 @@ func (repo *Repo) GetContent(r *requests.Content) *content.SiteContent {
return c
}
/*
func (repo *Repo) GetRepo() *content.RepoNode {
return repo.Node
}
*/
func uriKeyForState(state string, uri string) string {
return state + "-" + uri
}
@ -222,30 +209,10 @@ func builDirectory(dirNode *content.RepoNode, directory map[string]*content.Repo
}
directory[dirNode.Id] = dirNode
//todo handle duplicate uris
for _, languageURIs := range dirNode.URIs {
for _, uri := range languageURIs {
log.Debug(" uri: " + uri + " => Id: " + dirNode.Id)
if len(dirNode.States) == 0 {
key := uriKeyForState("", uri)
existingNode, ok = uRIDirectory[key]
if ok {
return errors.New("duplicate node with uri: " + uri)
}
uRIDirectory[key] = dirNode
} else {
for _, state := range dirNode.States {
key := uriKeyForState(state, uri)
existingNode, ok = uRIDirectory[key]
if ok {
return errors.New("dupicate node with uri: " + uri + " for state " + state)
}
uRIDirectory[key] = dirNode
}
}
}
if _, thereIsAnExistingUriNode := uRIDirectory[dirNode.URI]; thereIsAnExistingUriNode {
return errors.New("duplicate node with uri: " + dirNode.URI)
}
uRIDirectory[dirNode.URI] = dirNode
for _, childNode := range dirNode.Nodes {
err := builDirectory(childNode, directory, uRIDirectory)
if err != nil {
@ -256,15 +223,12 @@ func builDirectory(dirNode *content.RepoNode, directory map[string]*content.Repo
}
func wireAliases(directory map[string]*content.RepoNode) error {
// validation ?!
for _, repoNode := range directory {
if len(repoNode.LinkIds) > 0 {
for region, languages := range repoNode.LinkIds {
for language, linkId := range languages {
if destinationNode, ok := directory[linkId]; ok {
repoNode.URIs[region][language] = destinationNode.URIs[region][language]
}
}
if len(repoNode.LinkId) > 0 {
if destinationNode, ok := directory[repoNode.LinkId]; ok {
repoNode.URI = destinationNode.URI
} else {
return errors.New("that link id point nowhere " + repoNode.LinkId + " from " + repoNode.Id)
}
}
}
@ -273,16 +237,18 @@ func wireAliases(directory map[string]*content.RepoNode) error {
func (repo *Repo) Update() *responses.Update {
updateResponse := responses.NewUpdate()
newNode := content.NewRepoNode()
newNodes := make(map[string]*content.RepoNode) //content.NewRepoNode()
startTimeRepo := time.Now()
ok, err := utils.Get(repo.server, newNode)
ok, err := utils.Get(repo.server, newNodes)
updateResponse.Stats.RepoRuntime = time.Now().Sub(startTimeRepo).Seconds()
startTimeOwn := time.Now()
updateResponse.Success = ok
if ok {
repo.Load(newNode)
updateResponse.Stats.NumberOfNodes = len(repo.Directory)
updateResponse.Stats.NumberOfURIs = len(repo.URIDirectory)
for dimension, newNode := range newNodes {
repo.Load(dimension, newNode)
updateResponse.Stats.NumberOfNodes = len(repo.Directory[dimension].Directory)
updateResponse.Stats.NumberOfURIs = len(repo.Directory[dimension].URIDirectory)
}
} else {
log.Error(fmt.Sprintf("update error: %", err))
updateResponse.ErrorMessage = fmt.Sprintf("%", err)

View File

@ -1,8 +1,8 @@
package requests
type Content struct {
Env *Env `json:"env"`
URI string
Env *Env `json:"env"`
URI string `json:"URI"`
Nodes map[string]*Node `json:"nodes"`
}

View File

@ -1,19 +1,14 @@
package requests
type Defaults struct {
Region string `json:"region"`
Language string `json:"language"`
}
type Env struct {
Defaults *Defaults `json:"defaults"`
Groups []string `json:"groups"`
State string
Data interface{} `json:"data"`
Dimensions []string `json:"dimensions"`
Groups []string `json:"groups"`
Data interface{} `json:"data"`
}
type Node struct {
Id string `json:"id"`
Dimension string `json:"id"`
MimeTypes []string `json:"mimeTypes"`
Expand bool `json:"expand"`
DataFields []string `json:"dataFields"`

View File

@ -1,9 +1,8 @@
package requests
type URIs struct {
Ids []string `json:"ids"`
Region string `json:"region"`
Language string `json:"language"`
Ids []string `json:"ids"`
Dimension string `json:"dimension"`
}
func NewURIs() *URIs {

View File

@ -32,7 +32,7 @@ func handleSocketRequest(handler string, jsonBuffer []byte) (replyBytes []byte,
getURIRequest := requests.NewURIs()
jsonErr = json.Unmarshal(jsonBuffer, &getURIRequest)
log.Debug(" getURIRequest: " + fmt.Sprint(getURIRequest))
uris := contentRepo.GetURIs(getURIRequest.Region, getURIRequest.Language, getURIRequest.Ids)
uris := contentRepo.GetURIs(getURIRequest.Dimension, getURIRequest.Ids)
log.Debug(" resolved: " + fmt.Sprint(uris))
reply = uris
break
@ -43,13 +43,15 @@ func handleSocketRequest(handler string, jsonBuffer []byte) (replyBytes []byte,
content := contentRepo.GetContent(contentRequest)
reply = content
break
case "getItemMap":
itemMapRequest := requests.NewItemMap()
jsonErr = json.Unmarshal(jsonBuffer, &itemMapRequest)
log.Debug(" itemMapRequest: " + fmt.Sprint(itemMapRequest))
itemMap := contentRepo.GetItemMap(itemMapRequest.Id, itemMapRequest.DataFields)
reply = itemMap
break
/*
case "getItemMap":
itemMapRequest := requests.NewItemMap()
jsonErr = json.Unmarshal(jsonBuffer, &itemMapRequest)
log.Debug(" itemMapRequest: " + fmt.Sprint(itemMapRequest))
itemMap := contentRepo.GetItemMap(itemMapRequest.Id, itemMapRequest.DataFields)
reply = itemMap
break
*/
case "getNodes":
nodesRequest := requests.NewNodes()
jsonErr = json.Unmarshal(jsonBuffer, &nodesRequest)
@ -64,13 +66,15 @@ func handleSocketRequest(handler string, jsonBuffer []byte) (replyBytes []byte,
updateResponse := contentRepo.Update()
reply = updateResponse
break
case "getRepo":
repoRequest := requests.NewRepo()
jsonErr = json.Unmarshal(jsonBuffer, &repoRequest)
log.Debug(" getRepoRequest: " + fmt.Sprint(repoRequest))
repoResponse := contentRepo.GetRepo()
reply = repoResponse
break
/*
case "getRepo":
repoRequest := requests.NewRepo()
jsonErr = json.Unmarshal(jsonBuffer, &repoRequest)
log.Debug(" getRepoRequest: " + fmt.Sprint(repoRequest))
repoResponse := contentRepo.GetRepo()
reply = repoResponse
break
*/
default:
err = errors.New(log.Error(" can not handle this one " + handler))
errorResponse := responses.NewError(1, "unkown handler")