diff --git a/.gitignore b/.gitignore index f48d33a..449f8e6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ .* !.git* +/buildOnLinux.sh /main /ContentServer.sublime-project /ContentServer.sublime-workspace diff --git a/ContentServer b/ContentServer new file mode 100755 index 0000000..f48144b Binary files /dev/null and b/ContentServer differ diff --git a/main.go b/main.go index 0d0d64b..aa9536f 100644 --- a/main.go +++ b/main.go @@ -1,12 +1,53 @@ package main import ( + "flag" + "fmt" "github.com/foomo/ContentServer/server" "github.com/foomo/ContentServer/server/log" + "os" ) -func main() { - log.SetLogLevel(log.LOG_LEVEL_DEBUG) - //server.Run(":8080", "http://test.bestbytes/foomo/modules/Foomo.Page.Content/services/content.php") - server.RunSocketServer("http://test.bestbytes/foomo/modules/Foomo.Page.Content/services/content.php", "0.0.0.0:8081") +const ( + PROTOCOL_TCP = "tcp" + PROTOCOL_HTTP = "http" +) + +type ExitCode int + +const ( + EXIT_CODE_OK = 0 + EXIT_CODE_INSUFFICIENT_ARGS = 1 +) + +var contentServer string + +var protocol = flag.String("protocol", PROTOCOL_TCP, "what protocol to server for") +var address = flag.String("address", "127.0.0.1:8081", "address to bind host:port") + +func exitUsage(code int) { + fmt.Printf("Usage: %s http(s)://your-content-server/path/to/content.json\n", os.Args[0]) + flag.PrintDefaults() + os.Exit(code) +} + +func main() { + flag.Parse() + log.SetLogLevel(log.LOG_LEVEL_DEBUG) + if len(flag.Args()) == 1 { + fmt.Println(*protocol, *address, flag.Arg(0)) + //server.Run(":8080", "http://test.bestbytes/foomo/modules/Foomo.Page.Content/services/content.php") + switch *protocol { + case PROTOCOL_TCP: + server.RunSocketServer(flag.Arg(0), *address) + break + case PROTOCOL_HTTP: + fmt.Println("http server does not work yet - use tcp instead") + break + default: + exitUsage(EXIT_CODE_INSUFFICIENT_ARGS) + } + } else { + exitUsage(EXIT_CODE_INSUFFICIENT_ARGS) + } } diff --git a/server/http.go b/server/http.go index b1f02f0..8438070 100644 --- a/server/http.go +++ b/server/http.go @@ -57,7 +57,7 @@ func commandHandler(w http.ResponseWriter, r *http.Request) { } func Run(addr string, serverUrl string) { - log.Notice("staring content server") + log.Notice("starting content server") log.Notice(" loading content from " + serverUrl) contentRepo = repo.NewRepo(serverUrl) contentRepo.Update() diff --git a/server/repo/content/node.go b/server/repo/content/node.go index 2c3bdf5..b2ee390 100644 --- a/server/repo/content/node.go +++ b/server/repo/content/node.go @@ -5,6 +5,7 @@ import () type Node struct { Item *Item `json:"item"` Nodes map[string]*Node `json:"nodes"` + Index []string `json:"index"` } func NewNode() *Node { diff --git a/server/repo/content/repoNode.go b/server/repo/content/repoNode.go index ce79c0b..d0d6361 100644 --- a/server/repo/content/repoNode.go +++ b/server/repo/content/repoNode.go @@ -6,20 +6,21 @@ import ( ) type RepoNode struct { - Id string `json:"id"` - MimeType string `json:"mimeType"` - Handler string `json:"handler"` - Regions []string `json:"regions"` - URIs map[string]map[string]string `json:"URIs"` - Names map[string]string `json:"names"` - Hidden bool `json:"hidden"` // hidden in tree - Groups []string `json:"groups"` - Data map[string]interface{} `json:"data"` - Content map[string]interface{} `json:"content"` - Index []string `json:"index"` - Nodes map[string]*RepoNode `json:"nodes"` - LinkIds map[string]map[string]string `json:"linkIds"` // ids to link to - parent *RepoNode + Id string `json:"id"` + MimeType string `json:"mimeType"` + Handler string `json:"handler"` + Regions []string `json:"regions"` + URIs map[string]map[string]string `json:"URIs"` + DestinationIds map[string]map[string]string `json:"destinationIds"` + Names map[string]string `json:"names"` + Hidden bool `json:"hidden"` // hidden in tree + Groups []string `json:"groups"` + Data map[string]interface{} `json:"data"` + Content map[string]interface{} `json:"content"` + Nodes map[string]*RepoNode `json:"nodes"` + Index []string `json:"index"` + LinkIds map[string]map[string]string `json:"linkIds"` // ids to link to + parent *RepoNode // published from - to } @@ -45,12 +46,39 @@ func (node *RepoNode) WireParents() { } } -func (node *RepoNode) GetPath(region string, language string) map[string]*Item { - path := make(map[string]*Item) +func (node *RepoNode) InPath(path []*Item) bool { + myParentId := node.parent.Id + for _, pathItem := range path { + if pathItem.Id == myParentId { + 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 { parentNode := node.parent + pathLength := 0 for parentNode != nil { - path[parentNode.Id] = parentNode.ToItem(region, language) parentNode = parentNode.parent + pathLength++ + } + parentNode = node.parent + i := 0 + path := make([]*Item, pathLength) + for parentNode != nil { + path[i] = parentNode.ToItem(region, language) + parentNode = parentNode.parent + i++ } return path } @@ -59,6 +87,7 @@ func (node *RepoNode) ToItem(region string, language string) *Item { item := NewItem() item.Id = node.Id item.Name = node.GetName(language) + //todo handle destinationIds .... item.URI = node.URIs[region][language] return item } @@ -77,12 +106,16 @@ func (node *RepoNode) GetName(language string) string { } func (node *RepoNode) IsOneOfTheseMimeTypes(mimeTypes []string) bool { - for _, mimeType := range mimeTypes { - if mimeType == node.MimeType { - return true + if len(mimeTypes) == 0 { + return true + } else { + for _, mimeType := range mimeTypes { + if mimeType == node.MimeType { + return true + } } + return false } - return false } func (node *RepoNode) PrintNode(id string, level int) { @@ -98,6 +131,5 @@ func (node *RepoNode) PrintNode(id string, level int) { func NewRepoNode() *RepoNode { node := new(RepoNode) - return node } diff --git a/server/repo/content/siteContent.go b/server/repo/content/siteContent.go index 5ae0b22..029b298 100644 --- a/server/repo/content/siteContent.go +++ b/server/repo/content/siteContent.go @@ -11,9 +11,10 @@ type SiteContent struct { 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 map[string]*Item `json:"path"` + Path []*Item `json:"path"` URIs map[string]string `json:"URIs"` Nodes map[string]*Node `json:"nodes"` } diff --git a/server/repo/repo.go b/server/repo/repo.go index 90caca8..ee4bf76 100644 --- a/server/repo/repo.go +++ b/server/repo/repo.go @@ -1,6 +1,7 @@ package repo import ( + "fmt" "github.com/foomo/ContentServer/server/log" "github.com/foomo/ContentServer/server/repo/content" "github.com/foomo/ContentServer/server/requests" @@ -31,9 +32,18 @@ func (repo *Repo) ResolveContent(URI string) (resolved bool, resolvedURI string, testURI := strings.Join(parts[0:i], content.PATH_SEPARATOR) log.Debug(" testing" + testURI) if repoNode, ok := repo.URIDirectory[testURI]; ok { - log.Debug(" => " + testURI) resolved = true _, region, language := repoNode.GetLanguageAndRegionForURI(testURI) + log.Debug(" => " + testURI) + log.Debug(" destionations " + fmt.Sprint(repoNode.DestinationIds)) + log.Debug(" .region " + region + " " + fmt.Sprint(repoNode.DestinationIds[region])) + if languageDestinations, regionOk := repoNode.DestinationIds[region]; regionOk { + log.Debug(" there is a destionation map for this one " + fmt.Sprint(languageDestinations)) + if languageDestination, destinationOk := languageDestinations[language]; destinationOk { + // what if it is not there .... + repoNode = repo.Directory[languageDestination] + } + } return true, testURI, region, language, repoNode } else { log.Debug(" => !" + testURI) @@ -43,6 +53,14 @@ func (repo *Repo) ResolveContent(URI string) (resolved bool, resolvedURI string, return } +func (repo *Repo) GetURIs(region string, language string, ids []string) map[string]string { + uris := make(map[string]string) + for _, id := range ids { + uris[id] = repo.GetURI(region, language, id) + } + return uris +} + func (repo *Repo) GetURI(region string, language string, id string) string { repoNode, ok := repo.Directory[id] if ok { @@ -57,16 +75,19 @@ func (repo *Repo) GetURI(region string, language string, id string) string { return "" } -func (repo *Repo) GetNode(repoNode *content.RepoNode, expanded bool, mimeTypes []string, path []string, region string, language string) *content.Node { +func (repo *Repo) GetNode(repoNode *content.RepoNode, expanded bool, mimeTypes []string, path []*content.Item, region string, language string) *content.Node { node := content.NewNode() node.Item = repoNode.ToItem(region, language) log.Debug("repo.GetNode: " + repoNode.Id) for _, childId := range repoNode.Index { childNode := repoNode.Nodes[childId] - if expanded && !childNode.Hidden && childNode.IsOneOfTheseMimeTypes(mimeTypes) { - // || in path and in region mimes + if (expanded || !expanded && childNode.InPath(path)) && !childNode.Hidden && childNode.IsOneOfTheseMimeTypes(mimeTypes) && childNode.InRegion(region) { node.Nodes[childId] = repo.GetNode(childNode, expanded, mimeTypes, path, region, language) + node.Index = append(node.Index, childId) + } else { + fmt.Println("no see for", childNode.GetName(language), childNode.Hidden) } + } return node } @@ -81,13 +102,14 @@ func (repo *Repo) GetContent(r *requests.Content) *content.SiteContent { c.Region = region c.Language = language c.Status = content.STATUS_OK + c.Handler = node.Handler c.URI = resolvedURI c.Item = node.ToItem(region, language) c.Path = node.GetPath(region, language) c.Data = node.Data for treeName, treeRequest := range r.Nodes { log.Debug(" adding tree " + treeName + " " + treeRequest.Id) - c.Nodes[treeName] = repo.GetNode(repo.Directory[treeRequest.Id], treeRequest.Expand, treeRequest.MimeTypes, []string{}, region, language) + c.Nodes[treeName] = repo.GetNode(repo.Directory[treeRequest.Id], treeRequest.Expand, treeRequest.MimeTypes, c.Path, region, language) } } else { log.Notice("404 for " + r.URI) @@ -99,6 +121,7 @@ func (repo *Repo) GetContent(r *requests.Content) *content.SiteContent { func (repo *Repo) builDirectory(dirNode *content.RepoNode) { log.Debug("repo.buildDirectory: " + dirNode.Id) 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) diff --git a/server/requests/uri.go b/server/requests/uri.go deleted file mode 100644 index b444af5..0000000 --- a/server/requests/uri.go +++ /dev/null @@ -1,11 +0,0 @@ -package requests - -type URI struct { - Id string `json:"id"` - Region string `json:"region"` - Language string `json:"language"` -} - -func NewURI() *URI { - return new(URI) -} diff --git a/server/requests/uris.go b/server/requests/uris.go new file mode 100644 index 0000000..aa57a03 --- /dev/null +++ b/server/requests/uris.go @@ -0,0 +1,11 @@ +package requests + +type URIs struct { + Ids []string `json:"ids"` + Region string `json:"region"` + Language string `json:"language"` +} + +func NewURIs() *URIs { + return new(URIs) +} diff --git a/server/socket.go b/server/socket.go index 2a215ea..59e9568 100644 --- a/server/socket.go +++ b/server/socket.go @@ -27,13 +27,13 @@ func handleSocketRequest(handler string, jsonBuffer []byte) (replyBytes []byte, var jsonErr error log.Record(fmt.Sprintf("socket.handleSocketRequest(%d): %s %s", numRequests(), handler, string(jsonBuffer))) switch handler { - case "getURI": - getURIRequest := requests.NewURI() + case "getURIs": + getURIRequest := requests.NewURIs() jsonErr = json.Unmarshal(jsonBuffer, &getURIRequest) log.Debug(" getURIRequest: " + fmt.Sprint(getURIRequest)) - uri := contentRepo.GetURI(getURIRequest.Region, getURIRequest.Language, getURIRequest.Id) - log.Debug(" resolved: " + uri) - reply = uri + uris := contentRepo.GetURIs(getURIRequest.Region, getURIRequest.Language, getURIRequest.Ids) + log.Debug(" resolved: " + fmt.Sprint(uris)) + reply = uris break case "content": contentRequest := requests.NewContent() @@ -104,8 +104,8 @@ func handleConnection(conn net.Conn) { log.Error("socket.handleConnection: could not write my reply: " + fmt.Sprint(writeError)) return } else { - log.Debug(" replied.") - return + log.Debug(" replied. waiting for next request on open connection") + //return } } } else {