<commit_before># Wysteria

An open source asset tracking, versioning & publishing system written in Go. 

* [Before You Start](#before-you-start)
* [Building and Requirements](#building-and-requirements)
* [Available Clients](#clients)
* [Go Client Example](#connecting)
* [Types](#collections)
* [Notes](#notes)
* [Contributing](#contributing)
* [Todo List](#todo-list)

## Before You Start

There are three components that a wysteria server uses in conjunction to work, they are:
- A database for long term storage
- A 'searchbase' for indexing and running queries against
- A middleware for ferrying data back and forth between server(s) and client(s)

Each of these components is behind an interface so it's easy to write implementations for your favourite solutions. Currently there are implementations for

Databases
 - MongoDb
 - BoltDB (embedded)

Search
 - ElasticSearch
 - Bleve (embedded)

Middleware
 - Gorpc (embedded)
 - Nats.io (either)

You can also start wysteria with no config at all in which case it will spin up it's own embedded Nats server
and use BoltDB & Bleve to write to an OS temporary folder.

## Building and Requirements

Project can either be cloned or use `go get github.com/voidshard/wysteria/server`

Dependencies are managed via [glide](http://glide.sh/)

Build the server (requires [Go runtime](https://golang.org/dl/) to be installed):

```
cd wysteria
go build -o wysteria ./server
```


## Clients

* Go: https://godoc.org/github.com/voidshard/wysteria/client
* Python 2.7: https://github.com/voidshard/pywysteria (implements nats.io middleware)

## Connecting
Once you're set up, opening a connection to the server is reasonably simple
```Go
import (       
  wyc "wysteria/wysteria_client"
)

func main() {
  client, err := wyc.New()
  if err != nil {       
    panic(err)
  }
  defer client.Close()
}
```
By default wysteria will check for an ini file in the current directory, then it'll poll the env variable WYSTERIA_CLIENT_INI to see if it can find a config file there. Failing that, it'll assume a set of default values.

## Collections
At the highest level are collections. Collections are straight forward enough - each has a unique name and can be created via

```Go
client.CreateCollection("spriteSets")
```

You can easily fetch a collection via either the name or id
```Go
collection, _ := client.Collection("spriteSets")
sameCollection, _ := client.Collection(collection.Id())
```
And all child items of a collection via
```Go
items, _ := collection.Items()
```

You many also create child collections to help you organise your data better like so
```Go
foo, _ := client.CreateCollection("foo")
mapsOfFoo, _ := foo.CreateCollection("maps")
```
And fetch children of a collection.
```Go
children, _ := foo.Collections()
```
All collections of a given parent are still required to have unique names.

## Items
A collection can have any number of items, with the constraint that there is at most one item of each 'item type' and 'variant'.
The 'item type' and 'variant' are simply strings that are passed in when an item is created. 
```Go
item1, _ := collection.CreateItem("2dSprite", "alice", nil)
item2, _ := collection.CreateItem("2dSprite", "bob", nil)
item3, _ := collection.CreateItem("spriteSheet", "batman", nil)
```
They also have facets so that one can add custom searchable metadata to them for easy finding later. 
```Go
item1.SetFacets(map[string]string{"colour": "white", "publisher": "batman"})<commit_msg>Fix typo<commit_after># Wysteria

An open source asset tracking, versioning & publishing system written in Go. 

* [Before You Start](#before-you-start)
* [Building and Requirements](#building-and-requirements)
* [Available Clients](#clients)
* [Go Client Example](#connecting)
* [Types](#collections)
* [Notes](#notes)
* [Contributing](#contributing)
* [Todo List](#todo-list)

## Before You Start

There are three components that a wysteria server uses in conjunction to work, they are:
- A database for long term storage
- A 'searchbase' for indexing and running queries against
- A middleware for ferrying data back and forth between server(s) and client(s)

Each of these components is behind an interface so it's easy to write implementations for your favourite solutions. Currently there are implementations for

Databases
 - MongoDb
 - BoltDB (embedded)

Search
 - ElasticSearch
 - Bleve (embedded)

Middleware
 - Gorpc (embedded)
 - Nats.io (either)

You can also start wysteria with no config at all in which case it will spin up it's own embedded Nats server
and use BoltDB & Bleve to write to an OS temporary folder.

## Building and Requirements

Project can either be cloned or use `go get github.com/voidshard/wysteria/server`

Dependencies are managed via [glide](http://glide.sh/)

Build the server (requires [Go runtime](https://golang.org/dl/) to be installed):

```
cd wysteria
go build -o wysteria ./server
```


## Clients

* Go: https://godoc.org/github.com/voidshard/wysteria/client
* Python 2.7: https://github.com/voidshard/pywysteria (implements nats.io middleware)

## Connecting
Once you're set up, opening a connection to the server is reasonably simple
```Go
import (       
  wyc "wysteria/wysteria_client"
)

func main() {
  client, err := wyc.New()
  if err != nil {       
    panic(err)
  }
  defer client.Close()
}
```
By default wysteria will check for an ini file in the current directory, then it'll poll the env variable WYSTERIA_CLIENT_INI to see if it can find a config file there. Failing that, it'll assume a set of default values.

## Collections
At the highest level are collections. Collections are straight forward enough - each has a unique name and can be created via

```Go
client.CreateCollection("spriteSets")
```

You can easily fetch a collection via either the name or id
```Go
collection, _ := client.Collection("spriteSets")
sameCollection, _ := client.Collection(collection.Id())
```
And all child items of a collection via
```Go
items, _ := collection.Items()
```

You may also create child collections to help you organise your data better like so
```Go
foo, _ := client.CreateCollection("foo")
mapsOfFoo, _ := foo.CreateCollection("maps")
```
And fetch children of a collection.
```Go
children, _ := foo.Collections()
```
All collections of a given parent are still required to have unique names.

## Items
A collection can have any number of items, with the constraint that there is at most one item of each 'item type' and 'variant'.
The 'item type' and 'variant' are simply strings that are passed in when an item is created. 
```Go
item1, _ := collection.CreateItem("2dSprite", "alice", nil)
item2, _ := collection.CreateItem("2dSprite", "bob", nil)
item3, _ := collection.CreateItem("spriteSheet", "batman", nil)
```
They also have facets so that one can add custom searchable metadata to them for easy finding later. 
```Go
item1.SetFacets(map[string]string{"colour": "white", "publisher": "batman"})
{'fraction_non_alphanumeric': 0.10368663594470046, 'fraction_numerical': 0.002304147465437788, 'mean_word_length': 4.582797427652733, 'pattern_counts': {'":': 4, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 6, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '36749', 'n_tokens_mistral': 2087, 'n_tokens_neox': 1980, 'n_words': 850}