text:
# VMR in Openshift

This repository contains Openshift templates to use the VMR in Openshift.  It also contains a template to demonstrate
the VMR used by a Demo application to distribute work to workers.

## Overview

This demonstration consists of a single VMR used by two different Java Sprint Boot applications :
  * An aggregator which generates units of work.  A Unit of Work describes a task that takes some time to complete.
  * A worker which executes the task described by a unit of work.  When a task completes its unit of work is deemed
    consumed and is removed from the queue.

## Application's Architecture

![Architecture Diagram](https://github.com/SolaceLabs/solace-messaging-demo/blob/master/resources/demo-overview.png)

The Aggregator is a singleton process, there will only be one instance of it running.  It serves a Web Application over
port 8080 where the user will create the unit of work to be executed.  The unit of work are simply dummy work unit
implemented as a sleep for the amount of time specified by the user.

The worker is horizontally scalable and a system's throughput (A metric measured in Unit of Work per second) will scale
linearly with the number of worker instances.  This process offers no web interface and the user do not interact with it
directly.

The VMR is used as a load balancer of Work Units that guarantees delivery of work.  This is done via a non-exclusive
queue to which the aggregator publishes Units of Work each serialized as a message.  The queue will then distribute the
unit of work to the workers.  While the VMR distributes messages from the queue to consumers in a fair matter, the
distribution of work is done in no particular pattern and is affected by the worker's performance.

## Openshift Project Architecture

![Diagram of the Openshift VMR Demo Project](/resources/demo-openshift-project-diagram.png)

The Aggregator will be reached from HTTPS request made from external users.  The Aggregator route will expose the
aggregator as a HTTPS hostname.  The Aggregator service allows the route to reach the Pod hosting the Aggregator.  The
aggregator initiates a TCP connection to the VMR Service's IP in order to reach the VMR.

The Worker processes each runs in their own pod.  They initiates a TCP connection to the VMR Service's IP in order to
reach the VMR.

The Aggregator and Workers processes will exchange information thru messaging done thru the VMR.

The VMR will be hosted in a Pod and its services are exposed by the VMR Service.

## Prerequisites

* A target OpenShift environment
* A host with OpenShift client and Docker tools installed (IE. to run the Quick Start example)
* Have cluster admin privileges
* The VMR docker container (Available here : http://dev.solace.com/downloads/, under Docker in "VMR Community Edition")
* Have an administrator make the internal registry externally accessible :

```
oc expose service docker-registry -n default
```

## Deploying the Messaging Demo Template

The steps in this section can be executed automatically with the following script :

```
./deploy.sh <ssh-host> <project-name> <openshift-domain>
```
IE:
```
./deploy.sh<EMAIL_ADDRESS>demo-project openshift.example.com
```

The script will automate these steps for you :
* Log you in OpenShift (If you are not logged in yet)
* Create the project if it doesn't exists yet.
* Assign the required SCCs to the project's service account.
* Push the docker image to the OpenShift's project docker repository.
* Install the VMR template and instantiate it.

The following sections describes how to complete the above steps manually.

### Setup a new project

It is assumed that you have logged in to OpenShift :
```
oc login <host>:<port> --username=<user> --password=<password>
```

The first step consists of creating the OpenShift project for our demo application.  This command will create the
project :

```
oc new-project vmr-openshift-demo
```

Then the project needs the `privileged` and `anyuid` SCCs assigned to the service account.  This will allow the VMR
to run its processes as root and have privileged access (Required by the fact that we will mount an external tmpfs
on /dev/shm) :
```
oadm policy add-scc-to-user privileged system:serviceaccount:vmr-openshift-demo:default
oadm policy add-scc-to-user anyuid system:serviceaccount:vmr-openshift-demo:default
```

### Upload the VMR docker image to OpenShift's internal docker registry

Pushing the docker image to the internal registry requires the use of a machine running docker (IE. Docker machine).
The image is then loaded locally, and tagged as a repository image.  Then login to the OpenShift registry and push
the image using these commands :

```
docker load -i <image>.tar.gz
docker login --username=<user> --password=`oc whoami -t` docker-registry-default.<domain>
docker tag solace-app:<version-tag> docker-registry-default.<domain>/vmr-openshift-demo/solace-app:latest
docker push docker-registry-default.<domain>/vmr-openshift-demo/solace-app
```

### Learning the image stream fully qualified name

After pushing the image to OpenShift it is necessary to know the cluster IP of the docker registry :
```
oc get imagestreams solace-app
```

This will output something like this :
```
NAME         DOCKER REPO                                      TAGS      UPDATED
solace-app   <IP_ADDRESS>:5000/vmr-openshift-demo/solace-app   latest    About an hour ago
```

The IP portion `<IP_ADDRESS>:5000` is specific to the environment and will be different in your case.  Note the
full name, IE : here it is VMR_IMAGE = `<IP_ADDRESS>:5000/vmr-openshift-demo/solace-app`

### Create the Java App S2I ImageStream

Compiling the demonstration software will require a S2I (Source to Image) docker image.  This can be created from
a public repository by running this command :

```
oc create -f https://raw.githubusercontent.com/jorgemoralespou/s2i-java/master/ose3/s2i-java-imagestream.json
```

### Upload the demonstration's template

Running this command will create the 'solace-springboot-messaging-sample' template in the project:

```
oc create -f solace-messaging-demo-template.yml
```

### Using the template

The template can be used to instantiate the system and all of its components with this command :

Replace `<IP_ADDRESS>:5000/vmr-openshift-demo/solace-app` with the actual value from the
[Learning the image stream fully qualified name](#Learning-the-image-stream-fully-qualified-name) section. Also replace
openshift.example.com your wildcard subdomain (The wildcard DNS entry).

```
oc process solace-springboot-messaging-sample VMR_IMAGE=<IP_ADDRESS>:5000/vmr-openshift-demo/solace-app APPLICATION_SUBDOMAIN=openshift.example.com | oc create -f -
```

## Template description

Templates are explained on the OpenShift official documentation web site.  Templates are explained on that web site at
[this location](https://docs.openshift.org/latest/dev_guide/templates.html).

The template is used to automate the creation of these objects :
* A BuildConfig for the aggregator app.  It defines where the source code is and the output ImageStream.
* A BuildConfig for the worker app.
* An ImageStream for the aggregator app.  This will contain the image produced by the aggregator app's builds.
* An ImageStream for the worker app.
* A DeploymentConfig for the VMR.  This defines a template of a VMR pod.  A deployment will then instantiate this
  template into an actual VMR Pod.  The Pod contains all the container settings for the VMR.
* A DeploymentConfig for the aggregator app.
* A DeploymentConfig for the worker app.
* A Service for the VMR.  The service fronts a group of pods providing the same service over a set of TCP ports.  The
  Service has a single cluster IP associated with it, and a hostname.  The applications needing the service will connect
  to the hostname of the service instead of connection directly to the pods offering the service.  The service can
  load balance connections, and failover to pods that are healthy.
* A service for the aggregator application.  The aggregator application serves a web app over port 8080 and this service
  fronts that.
* A route for the aggregator application.  The route will proxy requests from the route's hostname to the aggregator
  service, to be handled by the aggregator pod.

The template also defines parameters that can be customized :

| Parameter                    | Description |
| ---------------------------- | ----------- |
| APPLICATION_NAME             | The name of the application.  This is used to prefix the name of objects created. |
| APPLICATION_SUBDOMAIN        | The application's subdomain.  The application will be available at https://aggregator.<APPLICATION_SUBDOMAIN>.  Make sure this FQDN exists in DNS. |
| GIT_URI                      | The git URI of the repository containing the demonstration's application. |
| GIT_REF                      | The branch or commit hash to use. |
| GIT_SECRET                   | The name of the secret to login to git. |
| GITHUB_TRIGGER_SECRET        | Trigger secret from Github.  Optional. |
| GENERIC_TRIGGER_SECRET       | Generic trigger secret.  Optional. |
| ADMIN_USER                   | The username of the initial CLI user created at VMR startup. |
| ADMIN_PASSWORD               | The password of the initial CLI user created at VMR startup. |

### Template header and metadata

The template yaml file starts with the header and metadata.  Here we specify that the object is a template and then
assign metadata to that template.

```
apiVersion: v1
kind: Template
metadata:
  name: solace-springboot-messaging-sample
  namespace: vmr-openshift-demo
  annotations:
    description: Sample Spring Boot Application that demonstrate messaging with the Solace VMR
    iconClass: icon-jboss
    tags: 'instant-app,springboot,gradle,java'
```

### Object list

The template defines a list of objects that must be instantiated when the template is used.  The list of objects is
defined by the `objects:` section.

### BuildConfig

The first two objects in the `objects:` section are BuildConfigs.  A BuildConfig describe how to build an image from
source code.  The OpenShift documentation explains BuildConfig
[here](https://docs.openshift.com/container-platform/3.4/dev_guide/builds/index.html).

These are the two buildconfig used by this template :
```
  - kind: BuildConfig
    apiVersion: v1
    metadata:
      name: '${APPLICATION_NAME}-aggregator'
    spec:
      triggers:
        - type: GitHub
          github:
            secret: '${GITHUB_TRIGGER_SECRET}'
        - type: Generic
          generic:
            secret: '${GENERIC_TRIGGER_SECRET}'
        - type: ImageChange
          imageChange: {}
      source:
        type: Git
        git:
          uri: '${GIT_URI}'
          ref: '${GIT_REF}'
        contextDir: 'aggregator'
      strategy:
        type: Source
        sourceStrategy:
          from:
            kind: ImageStreamTag
            name: 's2i-java:latest'
      output:
        to:
          kind: ImageStreamTag
          name: '${APPLICATION_NAME}-aggregator:latest'
      resources: {}
  - kind: BuildConfig
    apiVersion: v1
    metadata:
      name: '${APPLICATION_NAME}-worker'
    spec:
      triggers:
        - type: GitHub
          github:
            secret: '${GITHUB_TRIGGER_SECRET}'
        - type: Generic
          generic:
            secret: '${GENERIC_TRIGGER_SECRET}'
        - type: ImageChange
          imageChange: {}
      source:
        type: Git
        git:
          uri: '${GIT_URI}'
          ref: '${GIT_REF}'
        contextDir: 'worker'
      strategy:
        type: Source
        sourceStrategy:
          from:
            kind: ImageStreamTag
            name: 's2i-java:latest'
      output:
        to:
          kind: ImageStreamTag
          name: '${APPLICATION_NAME}-worker:latest'
      resources: {}
```

This defines the build for these application : The worker and the aggregator (As described in the
[Application's Architecture](#Application's-Architecture) section).  Note that there are no default Source-to-image
ImageStream that can build a standard java application based on Maven or Gradle.  Thus it was necessary to use a custom
source-to-image ImageStream : `s2i-java:latest`.  Section
[Create the Java App S2I ImageStream](#Create-the-Java-App-S2I-ImageStream) explains how that ImageStream was added to
the project, so that this template can use it.  Those BuildConfig defines which repository are hosting the
source code to be built.  Since both applications lives in the same repository, both BuildConfig refer to the same
repository : `${GIT_URI}` and `${GIT_REF}` (Which defines which commit/branch/tag to get).  Both applications lives in
their own subdirectory in that repo, and each BuildConfig will define the subdirectory via the `contextDir` attribute.
The `output:` section defines the output ImageStream that receives the Build output which is in fact a Docker Image
packing the built application.  This ImageStream can then be used by other parts of the template, to instantiate
containers running the application.

### ImageStreams

This part of the template simply create two ImageStreams to receive the Docker images produced by the BuildConfig
described in the [previous section](#BuildConfig).

```
  - kind: ImageStream
    apiVersion: v1
    metadata:
      name: '${APPLICATION_NAME}-aggregator'
    spec:
      dockerImageRepository: ''
      tags:
        - name: latest
  - kind: ImageStream
    apiVersion: v1
    metadata:
      name: '${APPLICATION_NAME}-worker'
    spec:
      dockerImageRepository: ''
      tags:
        - name: latest
```

### Deployment Config for Solace's VMR

A deployment describes how an application must be deployed in OpenShift.  More information on them can be found
[here](https://docs.openshift.com/container-platform/3.4/dev_guide/deployments/how_deployments_work.html) on OpenShift's
official documentation website.

Solace's VMR requires the `recreate` strategy.  To upgrade, or replace the VMR, the old pod must be destroyed before the
replacement pod starts.  This means that the `rolling` strategy cannot work for the VMR.  The POD that is declared
by this DeploymentConfig will run a VMR container.  How this container must be setup is explained [here](/readme.md).

```
  - kind: DeploymentConfig
    apiVersion: v1
    metadata:
      name: '${APPLICATION_NAME}-vmr'
    spec:
      strategy:
        type: Rolling
        rollingParams:
          timeoutSeconds: 1200
          maxSurge: 0
          maxUnavailable: 1
      triggers:
        - type: ConfigChange
      replicas: 1
      selector:
        deploymentconfig: '${APPLICATION_NAME}-vmr'
      template:
        metadata:
          name: '${APPLICATION_NAME}-vmr'
          labels:
            name: '${APPLICATION_NAME}-vmr'
            deploymentconfig: '${APPLICATION_NAME}-vmr'
        spec:
          volumes:
          - name: dshm
            emptyDir:
              medium: Memory
          containers:
            - name: "solace-vmr"
              env:
              - name: USERNAME_${ADMIN_USER}_PASSWORD
                value: '${ADMIN_PASSWORD}'
              - name: USERNAME_${ADMIN_USER}_GLOBALACCESSLEVEL
                value: 'admin'
              - name: SERVICE_SSH_PORT
                value: '22'
              - name: ALWAYS_DIE_ON_FAILURE
                value: '0'
              - name: ROUTERNAME
                value: '${ROUTER_NAME}'
              - name: NODETYPE
                value: 'message_routing'
              image: "${VMR_IMAGE}"
              volumeMounts:
              - mountPath: /dev/shm
                name: dshm
              securityContext:
                privileged: true
              ports:
              - containerPort: 8080
                protocol: TCP
              - containerPort: 943
                protocol: TCP
              - containerPort: 55555
                protocol: TCP
              - containerPort: 55003
                protocol: TCP
              - containerPort: 55556
                protocol: TCP
              - containerPort: 55443
                protocol: TCP
              - containerPort: 80
                protocol: TCP
              - containerPort: 443
                protocol: TCP
              - containerPort: 1883
                protocol: TCP
              - containerPort: 8883
                protocol: TCP
              - containerPort: 8000
                protocol: TCP
              - containerPort: 8443
                protocol: TCP
              - containerPort: 9000
                protocol: TCP
              - containerPort: 9443
                protocol: TCP
              - containerPort: 22
                protocol: TCP
              readinessProbe:
                initialDelaySeconds: 30
                periodSeconds: 5
                tcpSocket:
                  port: 55555
              livenessProbe:
                timeoutSeconds: 6
                initialDelaySeconds: 300
                periodSeconds: 60
                tcpSocket:
                  port: 55555
```

### VMR Service

Since a Pod's IP is not permanent having applications know about each Pod IPs address is not practical.  Applications
thus connect to pod indirectly thru an object called `service` which are documented
[here](https://kubernetes.io/docs/concepts/services-networking/service/) on Kubernete's official website.  A service
act as a proxy between applications and the Pod offering a service.  A service also have a name and Kubernetes define
will resolve the service's name to the service's IP.  The service IP is virtual as IP tables rules will translate that IP
into a pod's internal IP in the PREROUTING table.

Thus applications using the VMRwill simply connect to this hostname `${APPLICATION_NAME}-vmr`, and under the hood, a
Kubernetes ensure that iptables always route requests to the VMR pod.  The service listen on these ports :
* 443 (Web Messaging)
* 80 (SSL Web Messaging)
* 8080 (SEMP)
* 8443 (SSL SEMP)
* 55555 (Messaging)
* 22 (Management CLI access via SSH)

```
  - kind: Service
    apiVersion: v1
    metadata:
      name: '${APPLICATION_NAME}-vmr'
      annotations:
        description: 'Exposes the VMR services'
    spec:
      ports:
      - name: 'semp'
        port: 8080
        targetPort: 8080
      - name: 'semp-secure'
        port: 943
        targetPort: 943
      - name: 'smf'
        port: 55555
        targetPort: 55555
      - name: 'smf-zip'
        port: 55003
        targetPort: 55003
      - name: 'smf-routing'
        port: 55556
        targetPort: 55556
      - name: 'smf-secure'
        port: 55443
        targetPort: 55443
      - name: 'smf-http'
        port: 80
        targetPort: 80
      - name: 'smf-https'
        port: 443
        targetPort: 443
      - name: 'mqtt'
        port: 1883
        targetPort: 1883
      - name: 'mqtt-secure'
        port: 8883
        targetPort: 8883
      - name: 'mqtt-http'
        port: 8000
        targetPort: 8000
      - name: 'mqtt-https'
        port: 8443
        targetPort: 8443
      - name: 'rest'
        port: 9000
        targetPort: 9000
      - name: 'rest-secure'
        port: 9443
        targetPort: 9443
      - name: 'ssh'
        port: 22
        targetPort: 22
      selector:
        deploymentconfig: '${APPLICATION_NAME}-vmr'
      type: ClusterIP
      sessionAffinity: None
```

### Demo application's deployments

One DeploymentConfig are defined for the aggregator, and also for the worker:

```
  - kind: DeploymentConfig
    apiVersion: v1
    metadata:
      name: '${APPLICATION_NAME}-aggregator'
    spec:
      strategy:
        type: Rolling
        rollingParams:
          updatePeriodSeconds: 1
          intervalSeconds: 1
          timeoutSeconds: 600
        resources: {}
      triggers:
        - type: ConfigChange
        - type: ImageChange
          imageChangeParams:
            automatic: true
            containerNames:
              - '${APPLICATION_NAME}-aggregator'
            from:
              kind: ImageStreamTag
              name: '${APPLICATION_NAME}-aggregator:latest'
      replicas: 1
      selector:
        deploymentconfig: '${APPLICATION_NAME}-aggregator'
      template:
        metadata:
          labels:
            deploymentconfig: '${APPLICATION_NAME}-aggregator'
        spec:
          containers:
            - name: '${APPLICATION_NAME}-aggregator'
              image: '${APPLICATION_NAME}-aggregator'
              ports:
                - containerPort: 8090
                  protocol: TCP
              env:
              - name: 'solace_java_host'
                value: '${APPLICATION_NAME}-vmr'
              - name: 'solace_java_msgVpn'
                value: 'default'
              - name: 'solace_java_clientUsername'
                value: 'default'
              - name: 'solace_java_clientPassword'
                value: 'default'
              livenessProbe:
                tcpSocket:
                  port: 8090
                initialDelaySeconds: 30
                timeoutSeconds: 1
              resources: {}
              terminationMessagePath: /dev/termination-log
              imagePullPolicy: IfNotPresent
              securityContext:
                capabilities: {}
                privileged: false
          restartPolicy: Always
          dnsPolicy: ClusterFirst
  - kind: DeploymentConfig
    apiVersion: v1
    metadata:
      name: '${APPLICATION_NAME}-worker'
    spec:
      strategy:
        type: Rolling
        rollingParams:
          updatePeriodSeconds: 1
          intervalSeconds: 1
          timeoutSeconds: 600
        resources: {}
      triggers:
        - type: ConfigChange
        - type: ImageChange
          imageChangeParams:
            automatic: true
            containerNames:
              - '${APPLICATION_NAME}-worker'
            from:
              kind: ImageStreamTag
              name: '${APPLICATION_NAME}-worker:latest'
      replicas: 1
      selector:
        deploymentconfig: '${APPLICATION_NAME}-worker'
      template:
        metadata:
          labels:
            deploymentconfig: '${APPLICATION_NAME}-worker'
        spec:
          containers:
            - name: '${APPLICATION_NAME}-worker'
              image: '${APPLICATION_NAME}-worker'
              env:
              - name: 'solace_java_host'
                value: '${APPLICATION_NAME}-vmr'
              - name: 'solace_java_msgVpn'
                value: 'default'
              - name: 'solace_java_clientUsername'
                value: 'default'
              - name: 'solace_java_clientPassword'
                value: 'default'
              resources: {}
              terminationMessagePath: /dev/termination-log
              imagePullPolicy: IfNotPresent
              securityContext:
                capabilities: {}
                privileged: false
          restartPolicy: Always
          dnsPolicy: ClusterFirst
```

### Route

The aggregator must expose its web UI to the public network.  To do so, it exposes a route, which the router will
forward to the aggregator.  The router will look at the HTTP host, or `SNI` for the case of HTTPS.

Routes are documented [here](https://docs.openshift.com/container-platform/3.4/architecture/core_concepts/routes.html)
on OpenShift's official documentation website.

The route for the aggregator will have the `aggregator.${APPLICATION_SUBDOMAIN}` hostname.  And the router will route
HTTPS requests sent there to the service with the `deploymentconfig: '${APPLICATION_NAME}-aggregator'` selector.

```
  - kind: Route
    apiVersion: v1
    metadata:
      name: '${APPLICATION_NAME}-aggregator'
    spec:
      host: 'aggregator.${APPLICATION_SUBDOMAIN}'
      to:
        kind: Service
        name: 'aggregator'
      tls:
        termination: edge
      wildcardPolicy: None
  - kind: Service
    apiVersion: v1
    metadata:
      name: 'aggregator'
    spec:
      ports:
        - name: '${APPLICATION_NAME}-aggregator-http'
          port: 8090
          targetPort: 8090
      selector:
        deploymentconfig: '${APPLICATION_NAME}-aggregator'
      type: ClusterIP
      sessionAffinity: None
```

### Template parameters

Finally at the end of the template, we have all the parameters that the user can use to control aspects of the project
that is instantiated by the tamplate:

| Parameter              | Description                                                                                | Default value                                           |
| ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------- |
| APPLICATION_NAME       | The name of the application.  This will be prefixing the names of the objects created by this template.                                                                                | messaging-sample                                        |
| APPLICATION_SUBDOMAIN  | The subdomain assigned to the application.  DNS entries must already have been provisioned in this subdomain for the application's route to work.                                                                                | openshift.example.com                                   |
| VMR_IMAGE              | The ImageStream that contains the VMR docker image.  Docker-machine can be used to push the VMR docker image to the project.  Note that the default value must be adjusted to match your environment's Docker registry clusterIP.                    | <IP_ADDRESS>:5000/vmr-openshift-demo/solace-app          |
| GIT_URI                | The location of the Aggregator and Worker applications.  The default value shouldn't be changed, unless you want to use a fork instead to experiment.                                                                                | https://github.com/SolaceLabs/solace-messaging-demo.git |
| GIT_REF                | Defines which branch, tag or commit to checkout.                                                                                | master                                                  |
| ADMIN_USER             | Defines the initial administrative user of the VMR.                                                                                | admin                                                   |
| ADMIN_PASSWORD         | Defines the initial password of the administrative user of the VMR.                                                                                | admin                                                   |

This part of the template describes these parameters :

```
parameters:
  - name: APPLICATION_NAME
    displayName: Application name
    description: The name for the application.
    value: messaging-sample
    required: true
  - name: APPLICATION_SUBDOMAIN
    displayName: Application subdomain
    description: >-
      Custom subdomain for service routes.  Leave blank for default subdomain,
      This template creates two routes : aggregator.<subdomain> and workers.<subdomain>
    value: openshift.example.com
  - name: VMR_IMAGE
    displayName: VMR Image
    description: >-
      Fully qualified VMR image name.
    value: <IP_ADDRESS>:5000/vmr-openshift-demo/solace-app
  - name: GIT_URI
    description: Git source URI for application
    value: 'https://github.com/SolaceLabs/solace-messaging-demo.git'
  - name: GIT_REF
    description: Git branch/tag reference
    value: master
  - name: ADMIN_USER
    description: Username of the admin user
    generate: expression
    from: '[A-Z0-9]{8}'
    value: admin
  - name: ADMIN_PASSWORD
    description: Password of the admin user
    generate: expression
    from: '[A-Z0-9]{8}'
    value: admin
```

## Contributing

Please read [CONTRIBUTING.md](CONTRIBUTING.md) for details on our code of conduct, and the process for submitting pull requests to us.

## Authors

See the list of [contributors](https://github.com/SolaceLabs/solace-openshift-quickstart/graphs/contributors) who participated in this project.

## License

This project is licensed under the Apache License, Version 2.0. - See the [LICENSE](LICENSE) file for details.

## References

Here are some interesting links if you're new to these concepts:

* [The Solace Developer Portal](http://dev.solace.com/)
* [OpenShift's Core concepts](https://docs.openshift.com/container-platform/3.4/architecture/core_concepts/index.html)
* [Kubernetes Concepts](https://kubernetes.io/docs/concepts/)
* [Docker Machine Overview](https://docs.docker.com/machine/overview/)


text:
# Song Recommendation System

System works for mp3 files. It extracts the acoustic features for first and last 30 seconds from files and saves as a csv file. It gives a recommendation for choosen song. Purpose of the system is to give recommendation to users for best crossfade.

## Getting Started

if you would like to change the music file, just replace the songs with new ones and run the main.py.you can change csv file name inside of the code as well or you can merge them

Put only your song files under the music directory.

### Prerequisites

What things you need to install the software and how to install them

```
pip install -r requirements.txt
```

### Installing

A step by step series of examples that tell you how to get a development env running

Say what the step will be

```
Not given
```

And repeat

```
Not given
```

End with an example of getting some data out of the system or using it for a little demo

## Running the tests

Not given

### Break down into end to end tests

Explain what these tests test and why

```
Not given
```

### And coding style tests

Explain what these tests test and why

```
Not given
```

## Deployment

run main.py file and wait until it ends the feaure extraction

```
python recommend.py music/David_August_-_Epikur_-_Epikur_EP_\(Official_Video\)-Zvi4JYmRXzI.mp3
```

## Contributing

Please read [CONTRIBUTING.md](https://gist.github.com/egndz/b24679402957c63ec426) for details on our code of conduct, and the process for submitting pull requests to us.

## Versioning

We use [SemVer](http://semver.org/) for versioning. For the versions available, see the [tags on this repository](https://github.com/egndz/song-recommendation).

## Authors

* **Egehan Gunduz** - *Initial work* - [egndz](https://github.com/egndz)

See also the list of [contributors](https://github.com/your/project/contributors) who participated in this project.

## License

This project is licensed under the MIT License - see the [LICENSE.md](LICENSE.md) file for details

## Acknowledgments

Not given

license: MIT

repository: egndz/song-recommendation

branch_name: refs/heads/master

extension: md

license_type: permissive

repo_name: egndz/song-recommendation


text:
Equestria Combat Launcher
=========================

This project was a launcher for a never released MLP fan game *Equestria Combat* designed by the Drunked Lullabies team in late 2012 and early 2013.

![Comparison between their early version and my version of the launcher](docs/comparison.png "Comparison between their early version and my version of the launcher")

repository: thecatkitty/ECLaunch

branch_name: refs/heads/main

repo_name: thecatkitty/ECLaunch


text:
# My Personal Blog Website.
* https://bart-blog.herokuapp.com/
* An End-to-End application, managed from development through deployment to production.

## Functionality
* Users need to register/login in order to comment on posts.
* Passwords are securely encoded with hashing and salting functions of the werkzeug.security package.
* User authentication is done with a flask_login object
* Only Admin users can create and delete posts.
* Users can get in contact with the the owner(me) by sending a message, which gets transferred via email over a SMTP client session object.
* The App makes use of CKEditor (for creating posts and comments); a WYSIWYG rich text editor which enables writing content directly inside of web pages/online applications.
* (Production) WSGI server is setup with Gunicorn to run the Live Python Application on Heroku. PostgreSQL database is used for production.
* (Development) Development and testing is done locally with a SQLite database.

## Topics covered

* Python, HTML, CSS, Heroku, SQL
* Flask Web Framework
* SQL Databases
* Decorators
* OOP
* Functions

## Packages
* See requirements.txt for all packages and dependencies used.


text:
# Bitcoin UTXO Metrics

## BTC UTXO Average Age

This endpoint returns the average age of the bitcoin supply at the specified date, held in unspent transaction outputs stratified by their age. For instance outputs in the category `12-18m` are unspent outputs (UTXOs) from transactions that occurred `12-18m` ago. Time is measured relative to blocktime assuming 6 blocks are generated per hour. This means that the proportion of UTXOs in the `<1d` category were generated less than or equal to 144 blocks ago (`6 blocks * 24 hours`).

The age in block height is used over the block timestamp because the block timestamp serves as a source of variation when calculating the blockhash and is only accurate to within an hour or two. By using timestamps some UTXOs could be considered older than a previously generated UTXO. By using block-age from current the blockheight, the age of utxos is strictly ordinal as blockheight is strictly sequential.

```shell
# Make sure you substitute API_KEY for your unique API key.

curl "https://api.tokenanalyst.io/analytics/private/v1/token_utxo_metric_window_historical/last?metric=avg_age&limit=2&window=1d&format=json&token=btc&key=API_KEY"
```

> The above command returns JSON structured like this:

```json
[
  {
   "date": "2019-10-16",
   "1-3m": 1429.2267,
   "12-18m": 10891.7902,
   "18-24m": 15520.8613,
   "1d-1w": 90.3656,
   "1w-1m": 435.0935,
   "2-3y": 21635.8451,
   "3-5y": 35142.7048,
   "3-6m": 3189.9665,
   "5-10y": 56884.8621,
   "6-12m": 6392.2049,
   "<1d": 12.0231,
   ">10y": 95228.0092
  },
  {
   "date": "2019-10-17",
   "1-3m": 1425.9911,
   "12-18m": 10888.0116,
   "18-24m": 15524.2703,
   "1d-1w": 90.6531,
   "1w-1m": 437.233,
   "2-3y": 21629.4766,
   "3-5y": 35148.2189,
   "3-6m": 3192.6356,
   "5-10y": 56902.5727,
   "6-12m": 6385.1655,
   "<1d": 11.1082,
   ">10y": 95242.9982
}
  }
]
]
```

### HTTP Request

`GET https://api.tokenanalyst.io/analytics/private/v1/token_utxo_metric_window_historical/last`

### Query Parameters

| Parameter    | Type      | Description                                                                               |
| ------------ | --------- | ----------------------------------------------------------------------------------------- |
| key          | _string_  | Your unique API key                                                                       |
| format       | _string_  | What format you want your data in (`json` or `csv`)                                       |
| metric       | _string_  | `avg_age`                                                                                |
| window       | _string_  | `1d` (no support for 1h at this time)                                                     |
| token        | _string_  | `btc`                                                                                |
| from_date \* | _string_  | Start date of returned data specified as YYYY-MM-DD (ISO date format)                     |
| to_date \*   | _string_  | End date of returned data specified as YYYY-MM-DD (ISO date format)                       |
| limit \*     | _integer_ | The number of entries returned before the latest data point (or the to_date if specified) |

Note: All params with a \* are optional and `limit` is only available in the JSON return format

### Data Overview

| Field  | Type      | Description                                                                                |
| ------ | --------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
| date   | _string_  | The date in _YYYY-MM-DD_                                                                                |
| <1d    | _decimal_ | The average age of unspent outputs (UTXOs) on this date from transactions that occurred less than a day prior to this date.       |
| 1d-1w  | _decimal_ | The average age of unspent outputs (UTXOs) on this date from transactions that occurred 1 day to 1 week prior to this date.       |
| 1w-1m  | _decimal_ | The average age of unspent outputs (UTXOs) on this date from transactions that occurred 1 week to 1 month prior to this date.     |
| 1-3m   | _decimal_ | The average age of unspent outputs (UTXOs) on this date from transactions that occurred 1 to 3 months prior to this date.         |
| 3-6m   | _decimal_ | The average age of unspent outputs (UTXOs) on this date from transactions that occurred 3 to 6 months prior to this date.         |
| 6-12m  | _decimal_ | The average age of unspent outputs (UTXOs) on this date from transactions that occurred 6 to 12 months prior to this date.        |
| 12-18m | _decimal_ | The average age of unspent outputs (UTXOs) on this date) from transactions that occurred 12 to 18 months prior to this date.       |
| 18-24m | _decimal_ | The average age of unspent outputs (UTXOs) on this date from transactions that occurred 18 to 24 months prior to this date.       |
| 2-3y   | _decimal_ | The average age of unspent outputs (UTXOs) on this date from transactions that occurred 2 to 3 years prior to this date.          |
| 3-5y   | _decimal_ | The average age of unspent outputs (UTXOs) on this date from transactions that occurred 3 to 5 years prior to this date.          |
| 5-10y  | _decimal_ | The average age of unspent outputs (UTXOs) on this date from transactions that occurred 5 to 10 years prior to this date.         |
| >10y   | _decimal_ | The average age of unspent outputs (UTXOs) on this date from transactions that occurred greater than 10 years prior to this date. |

## BTC UTXO Average Value

This endpoint returns the average value of unspent transaction outputs (UTXOs) at the specified date, stratified by their age. For instance outputs in the category `12-18m` are unspent outputs (UTXOs) from transactions that occurred `12-18m` ago. Time is measured relative to blocktime assuming 6 blocks are generated per hour. This means that the average value of UTXOs in the `>10y` category is the average for unspent outputs that were generated 525, 600 blocks ago (`6 blocks * 24 hours * 365 days * 10 years`).

The age in block height is used over the block timestamp because the block timestamp serves as a source of variation when calculating the blockhash and is only accurate to within an hour or two. By using timestamps some UTXOs could be considered older than a previously generated UTXO. By using block-age from current the blockheight, the age of utxos is strictly ordinal as blockheight is strictly sequential.

```shell
# Make sure you substitute API_KEY for your unique API key.

curl "https://api.tokenanalyst.io/analytics/private/v1/token_utxo_metric_window_historical/last?metric=avg_value&limit=2&window=1d&format=json&token=btc&key=API_KEY"
```

> The above command returns JSON structured like this:

```json
[
  {
   "date": "2019-10-16",
   "1-3m": 0.3169,
   "12-18m": 0.2018,
   "18-24m": 0.3342,
   "1d-1w": 0.3745,
   "1w-1m": 0.3462,
   "2-3y": 0.2303,
   "3-5y": 0.0834,
   "3-6m": 0.2905,
   "5-10y": 0.2852,
   "6-12m": 0.3736,
   "<1d": 0.4967,
   ">10y": 50.6428
  },
  {
   "date": "2019-10-17",
   "1-3m": 0.3153,
   "12-18m": 0.2001,
   "18-24m": 0.3353,
   "1d-1w": 0.384,
   "1w-1m": 0.3132,
   "2-3y": 0.2309,
   "3-5y": 0.0834,
   "3-6m": 0.2895,
   "5-10y": 0.2848,
   "6-12m": 0.3728,
   "<1d": 0.8995,
   ">10y": 50.6194
}
  }
]
]
```

### HTTP Request

`GET https://api.tokenanalyst.io/analytics/private/v1/token_utxo_metric_window_historical/last`

### Query Parameters

| Parameter    | Type      | Description                                                                               |
| ------------ | --------- | ----------------------------------------------------------------------------------------- |
| key          | _string_  | Your unique API key                                                                       |
| format       | _string_  | What format you want your data in (`json` or `csv`)                                       |
| metric       | _string_  | `avg_value`                                                                                |
| window       | _string_  | `1d` (no support for 1h at this time)                                                     |
| token        | _string_  | `btc`                                                                                |
| from_date \* | _string_  | Start date of returned data specified as YYYY-MM-DD (ISO date format)                     |
| to_date \*   | _string_  | End date of returned data specified as YYYY-MM-DD (ISO date format)                       |
| limit \*     | _integer_ | The number of entries returned before the latest data point (or the to_date if specified) |

Note: All params with a \* are optional and `limit` is only available in the JSON return format

### Data Overview

| Field  | Type      | Description                                                                                |
| ------ | --------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
| date   | _string_  | The date in _YYYY-MM-DD_                                                                                |
| <1d    | _decimal_ | The average value of unspent outputs (UTXOs) on this date from transactions that occurred less than a day prior to this date.       |
| 1d-1w  | _decimal_ | The average value of unspent outputs (UTXOs) on this date from transactions that occurred 1 day to 1 week prior to this date.       |
| 1w-1m  | _decimal_ | The average value of unspent outputs (UTXOs) on this date from transactions that occurred 1 week to 1 month prior to this date.     |
| 1-3m   | _decimal_ | The average value of unspent outputs (UTXOs) on this date from transactions that occurred 1 to 3 months prior to this date.         |
| 3-6m   | _decimal_ | The average value of unspent outputs (UTXOs) on this date from transactions that occurred 3 to 6 months prior to this date.         |
| 6-12m  | _decimal_ | The average value of unspent outputs (UTXOs) on this date from transactions that occurred 6 to 12 months prior to this date.        |
| 12-18m | _decimal_ | The average value of unspent outputs (UTXOs) on this date) from transactions that occurred 12 to 18 months prior to this date.       |
| 18-24m | _decimal_ | The average value of unspent outputs (UTXOs) on this date from transactions that occurred 18 to 24 months prior to this date.       |
| 2-3y   | _decimal_ | The average value of unspent outputs (UTXOs) on this date from transactions that occurred 2 to 3 years prior to this date.          |
| 3-5y   | _decimal_ | The average value of unspent outputs (UTXOs) on this date from transactions that occurred 3 to 5 years prior to this date.          |
| 5-10y  | _decimal_ | The average value of unspent outputs (UTXOs) on this date from transactions that occurred 5 to 10 years prior to this date.         |
| >10y   | _decimal_ | The average value of unspent outputs (UTXOs) on this date from transactions that occurred greater than 10 years prior to this date. |

## BTC UTXO Count

This endpoint returns the count of unspent transaction outputs (UTXOs) at the specified date, stratified by their age. For instance the category `12-18m` contains the count of currently unspent outputs from transactions that occurred `12-18m` ago. Time is measured relative to blocktime assuming 6 blocks are generated per hour. This means that the count of UTXOs in the `<1d` category were from UTXOs generated less than or equal to `144 blocks ago (6 blocks * 24 hours)`.

The age in block height is used over the block timestamp because the block timestamp serves as a source of variation when calculating the blockhash and is only accurate to within an hour or two. By using timestamps some UTXOs could be considered older than a previously generated UTXO. By using block-age from current the blockheight, the age of utxos is strictly ordinal as blockheight is strictly sequential.

```shell
# Make sure you substitute API_KEY for your unique API key.

curl "https://api.tokenanalyst.io/analytics/private/v1/token_utxo_metric_window_historical/last?metric=count&limit=2&window=1d&format=json&token=btc&key=API_KEY"
```

> The above command returns JSON structured like this:

```json
[
  {
   "date": "2019-10-16",
   "1-3m": 5608778,
   "12-18m": 5737941,
   "18-24m": 6219351,
   "1d-1w": 1139380,
   "1w-1m": 3060596,
   "2-3y": 7402366,
   "3-5y": 11597627,
   "3-6m": 7248319,
   "5-10y": 8067592,
   "6-12m": 6916852,
   "<1d": 349249,
   ">10y": 32772
  },
  {
   "date": "2019-10-17",
   "1-3m": 5615040,
   "12-18m": 5753489,
   "18-24m": 6214569,
   "1d-1w": 1141220,
   "1w-1m": 2987535,
   "2-3y": 7412377,
   "3-5y": 11613309,
   "3-6m": 7282144,
   "5-10y": 8071654,
   "6-12m": 6916407,
   "<1d": 323682,
   ">10y": 32815
}
  }
]
]
```

### HTTP Request

`GET https://api.tokenanalyst.io/analytics/private/v1/token_utxo_metric_window_historical/last`

### Query Parameters

| Parameter    | Type      | Description                                                                               |
| ------------ | --------- | ----------------------------------------------------------------------------------------- |
| key          | _string_  | Your unique API key                                                                       |
| format       | _string_  | What format you want your data in (`json` or `csv`)                                       |
| metric       | _string_  | `count`                                                                                |
| window       | _string_  | `1d` (no support for 1h at this time)                                                     |
| token        | _string_  | `btc`                                                                                |
| from_date \* | _string_  | Start date of returned data specified as YYYY-MM-DD (ISO date format)                     |
| to_date \*   | _string_  | End date of returned data specified as YYYY-MM-DD (ISO date format)                       |
| limit \*     | _integer_ | The number of entries returned before the latest data point (or the to_date if specified) |

Note: All params with a \* are optional and `limit` is only available in the JSON return format

### Data Overview

| Field  | Type      | Description                                                                                |
| ------ | --------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
| date   | _string_  | The date in _YYYY-MM-DD_                                                                                |
| <1d    | _decimal_ | The count of unspent outputs (UTXOs) on this date from transactions that occurred less than a day prior to this date.       |
| 1d-1w  | _decimal_ | The count of unspent outputs (UTXOs) on this date from transactions that occurred 1 day to 1 week prior to this date.       |
| 1w-1m  | _decimal_ | The count of unspent outputs (UTXOs) on this date from transactions that occurred 1 week to 1 month prior to this date.     |
| 1-3m   | _decimal_ | The count of unspent outputs (UTXOs) on this date from transactions that occurred 1 to 3 months prior to this date.         |
| 3-6m   | _decimal_ | The count of unspent outputs (UTXOs) on this date from transactions that occurred 3 to 6 months prior to this date.         |
| 6-12m  | _decimal_ | The count of unspent outputs (UTXOs) on this date from transactions that occurred 6 to 12 months prior to this date.        |
| 12-18m | _decimal_ | The count of unspent outputs (UTXOs) on this date) from transactions that occurred 12 to 18 months prior to this date.       |
| 18-24m | _decimal_ | The count of unspent outputs (UTXOs) on this date from transactions that occurred 18 to 24 months prior to this date.       |
| 2-3y   | _decimal_ | The count of unspent outputs (UTXOs) on this date from transactions that occurred 2 to 3 years prior to this date.          |
| 3-5y   | _decimal_ | The count of unspent outputs (UTXOs) on this date from transactions that occurred 3 to 5 years prior to this date.          |
| 5-10y  | _decimal_ | The count of unspent outputs (UTXOs) on this date from transactions that occurred 5 to 10 years prior to this date.         |
| >10y   | _decimal_ | The count of unspent outputs (UTXOs) on this date from transactions that occurred greater than 10 years prior to this date. |

## BTC UTXO Median Age

This endpoint returns the median age of the bitcoin supply at the specified date, held in unspent transaction outputs stratified by their age. For instance outputs in the category `12-18m` are unspent outputs (UTXOs) from transactions that occurred `12-18m` ago. Time is measured relative to blocktime assuming 6 blocks are generated per hour. This means that the median age of UTXOs in the `<1d` category were generated less than or equal to `144 blocks ago (6 blocks * 24 hours)`.

The age in block height is used over the block timestamp because the block timestamp serves as a source of variation when calculating the blockhash and is only accurate to within an hour or two. By using timestamps some UTXOs could be considered older than a previously generated UTXO. By using block-age from current the blockheight, the age of utxos is strictly ordinal as blockheight is strictly sequential.

```shell
# Make sure you substitute API_KEY for your unique API key.

curl "https://api.tokenanalyst.io/analytics/private/v1/token_utxo_metric_window_historical/last?metric=median_age&limit=2&window=1d&format=json&token=btc&key=API_KEY"
```

> The above command returns JSON structured like this:

```json
[
  {
   "date": "2019-10-16",
   "1-3m": 1428.5,
   "12-18m": 10879.8333,
   "18-24m": 15663.8333,
   "1d-1w": 88.5,
   "1w-1m": 430.5,
   "2-3y": 21493.1667,
   "3-5y": 35925.1667,
   "3-6m": 3146.5,
   "5-10y": 55743.8333,
   "6-12m": 6271.8333,
   "<1d": 11.5,
   ">10y": 96415.8333
  },
  {
   "date": "2019-10-17",
   "1-3m": 1435.8333,
   "12-18m": 10885.1667,
   "18-24m": 15663.8333,
   "1d-1w": 87.3333,
   "1w-1m": 433.1667,
   "2-3y": 21482.5,
   "3-5y": 35903.8333,
   "3-6m": 3149.1667,
   "5-10y": 55765.1667,
   "6-12m": 6266.5,
   "<1d": 10.3333,
   ">10y": 96426.5
}
  }
]
]
```

### HTTP Request

`GET https://api.tokenanalyst.io/analytics/private/v1/token_utxo_metric_window_historical/last`

### Query Parameters

| Parameter    | Type      | Description                                                                               |
| ------------ | --------- | ----------------------------------------------------------------------------------------- |
| key          | _string_  | Your unique API key                                                                       |
| format       | _string_  | What format you want your data in (`json` or `csv`)                                       |
| metric       | _string_  | `median_age`                                                                                |
| window       | _string_  | `1d` (no support for 1h at this time)                                                     |
| token        | _string_  | `btc`                                                                                |
| from_date \* | _string_  | Start date of returned data specified as YYYY-MM-DD (ISO date format)                     |
| to_date \*   | _string_  | End date of returned data specified as YYYY-MM-DD (ISO date format)                       |
| limit \*     | _integer_ | The number of entries returned before the latest data point (or the to_date if specified) |

Note: All params with a \* are optional and `limit` is only available in the JSON return format

### Data Overview

| Field  | Type      | Description                                                                                |
| ------ | --------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
| date   | _string_  | The date in _YYYY-MM-DD_                                                                                |
| <1d    | _decimal_ | The median age of unspent outputs (UTXOs) on this date from transactions that occurred less than a day prior to this date.       |
| 1d-1w  | _decimal_ | The median age of unspent outputs (UTXOs) on this date from transactions that occurred 1 day to 1 week prior to this date.       |
| 1w-1m  | _decimal_ | The median age of unspent outputs (UTXOs) on this date from transactions that occurred 1 week to 1 month prior to this date.     |
| 1-3m   | _decimal_ | The median age of unspent outputs (UTXOs) on this date from transactions that occurred 1 to 3 months prior to this date.         |
| 3-6m   | _decimal_ | The median age of unspent outputs (UTXOs) on this date from transactions that occurred 3 to 6 months prior to this date.         |
| 6-12m  | _decimal_ | The median age of unspent outputs (UTXOs) on this date from transactions that occurred 6 to 12 months prior to this date.        |
| 12-18m | _decimal_ | The median age of unspent outputs (UTXOs) on this date) from transactions that occurred 12 to 18 months prior to this date.       |
| 18-24m | _decimal_ | The median age of unspent outputs (UTXOs) on this date from transactions that occurred 18 to 24 months prior to this date.       |
| 2-3y   | _decimal_ | The median age of unspent outputs (UTXOs) on this date from transactions that occurred 2 to 3 years prior to this date.          |
| 3-5y   | _decimal_ | The median age of unspent outputs (UTXOs) on this date from transactions that occurred 3 to 5 years prior to this date.          |
| 5-10y  | _decimal_ | The median age of unspent outputs (UTXOs) on this date from transactions that occurred 5 to 10 years prior to this date.         |
| >10y   | _decimal_ | The median age of unspent outputs (UTXOs) on this date from transactions that occurred greater than 10 years prior to this date. |

## BTC UTXO Total Value

This endpoint returns the total BTC value of the bitcoin supply at the specified date, held in unspent transaction outputs stratified by their age. For instance outputs in the category `12-18m` are unspent outputs (UTXOs) from transactions that occurred `12-18m` ago. Time is measured relative to blocktime assuming 6 blocks are generated per hour. This means that the BTC value of UTXOs in the `<1d` category were generated less than or equal to `144 blocks ago (6 blocks * 24 hours)`.

The age in block height is used over the block timestamp because the block timestamp serves as a source of variation when calculating the blockhash and is only accurate to within an hour or two. By using timestamps some UTXOs could be considered older than a previously generated UTXO. By using block-age from current the blockheight, the age of utxos is strictly ordinal as blockheight is strictly sequential.

```shell
# Make sure you substitute API_KEY for your unique API key.

curl "https://api.tokenanalyst.io/analytics/private/v1/token_utxo_metric_window_historical/last?metric=total_value&limit=2&window=1d&format=json&token=btc&key=API_KEY"
```

> The above command returns JSON structured like this:

```json
[
  {
   "date": "2019-10-16",
   "1-3m": 1777347.3869,
   "12-18m": 1158032.9532,
   "18-24m": 2078703.5591,
   "1d-1w": 426700.584,
   "1w-1m": 1059641.5382,
   "2-3y": 1704598.3775,
   "3-5y":<PHONE_NUMBER>,
   "3-6m": 2105447.8466,
   "5-10y": 2300642.2641,
   "6-12m": 2584202.2294,
   "<1d":<PHONE_NUMBER>,
   ">10y": 1659664.5
  },
  {
   "date": "2019-10-17",
   "1-3m": 1770545.9191,
   "12-18m": 1151530.6676,
   "18-24m": 2083877.5908,
   "1d-1w":<PHONE_NUMBER>,
   "1w-1m":<PHONE_NUMBER>,
   "2-3y": 1711474.8656,
   "3-5y":<PHONE_NUMBER>,
   "3-6m": 2108284.9723,
   "5-10y": 2299152.7543,
   "6-12m": 2578503.3151,
   "<1d": 291163.752,
   ">10y": 1661075.32
}
  }
]
]
```

### HTTP Request

`GET https://api.tokenanalyst.io/analytics/private/v1/token_utxo_metric_window_historical/last`

### Query Parameters

| Parameter    | Type      | Description                                                                               |
| ------------ | --------- | ----------------------------------------------------------------------------------------- |
| key          | _string_  | Your unique API key                                                                       |
| format       | _string_  | What format you want your data in (`json` or `csv`)                                       |
| metric       | _string_  | `total_value`                                                                                |
| window       | _string_  | `1d` (no support for 1h at this time)                                                     |
| token        | _string_  | `btc`                                                                                |
| from_date \* | _string_  | Start date of returned data specified as YYYY-MM-DD (ISO date format)                     |
| to_date \*   | _string_  | End date of returned data specified as YYYY-MM-DD (ISO date format)                       |
| limit \*     | _integer_ | The number of entries returned before the latest data point (or the to_date if specified) |

Note: All params with a \* are optional and `limit` is only available in the JSON return format

### Data Overview

| Field  | Type      | Description                                                                                |
| ------ | --------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
| date   | _string_  | The date in _YYYY-MM-DD_                                                                                |
| <1d    | _decimal_ | The total value of unspent outputs (UTXOs) on this date from transactions that occurred less than a day prior to this date.       |
| 1d-1w  | _decimal_ | The total value of unspent outputs (UTXOs) on this date from transactions that occurred 1 day to 1 week prior to this date.       |
| 1w-1m  | _decimal_ | The total value of unspent outputs (UTXOs) on this date from transactions that occurred 1 week to 1 month prior to this date.     |
| 1-3m   | _decimal_ | The total value of unspent outputs (UTXOs) on this date from transactions that occurred 1 to 3 months prior to this date.         |
| 3-6m   | _decimal_ | The total value of unspent outputs (UTXOs) on this date from transactions that occurred 3 to 6 months prior to this date.         |
| 6-12m  | _decimal_ | The total value of unspent outputs (UTXOs) on this date from transactions that occurred 6 to 12 months prior to this date.        |
| 12-18m | _decimal_ | The total value of unspent outputs (UTXOs) on this date) from transactions that occurred 12 to 18 months prior to this date.       |
| 18-24m | _decimal_ | The total value of unspent outputs (UTXOs) on this date from transactions that occurred 18 to 24 months prior to this date.       |
| 2-3y   | _decimal_ | The total value of unspent outputs (UTXOs) on this date from transactions that occurred 2 to 3 years prior to this date.          |
| 3-5y   | _decimal_ | The total value of unspent outputs (UTXOs) on this date from transactions that occurred 3 to 5 years prior to this date.          |
| 5-10y  | _decimal_ | The total value of unspent outputs (UTXOs) on this date from transactions that occurred 5 to 10 years prior to this date.         |
| >10y   | _decimal_ | The total value of unspent outputs (UTXOs) on this date from transactions that occurred greater than 10 years prior to this date. |

## BTC UTXO Weighted Average Age

This endpoint returns the weighted average age of the current bitcoin supply held in unspent transaction outputs stratified by their age.
The weighted average age is sum of the ages of UTXOs multiplied by their bitocoinvalue, divided by the total bitcoin value in that stratum. The formula is below:

For instance outputs in the category `12-18m` are unspent outputs (UTXOs) from transactions that occurred `12-18m` ago. Time is measured relative to blocktime assuming 6 blocks are generated per hour. This means that the proportion of UTXOs in the `<1d` category were generated less than or equal to `144 blocks ago (6 blocks * 24 hours)`.

The age in block height is used over the block timestamp because the block timestamp serves as a source of variation when calculating the blockhash and is only accurate to within an hour or two. By using timestamps some UTXOs could be considered older than a previously generated UTXO. By using block-age from current the blockheight, the age of utxos is strictly ordinal as blockheight is strictly sequential.

```shell
# Make sure you substitute API_KEY for your unique API key.

curl "https://api.tokenanalyst.io/analytics/private/v1/token_utxo_metric_window_historical/last?metric=weighted_avg_age&limit=2&window=1d&format=json&token=btc&key=API_KEY"
```

> The above command returns JSON structured like this:

```json
[
  {
   "date": "2019-10-16",
   "1-3m": 1545.2336,
   "12-18m": 11035.8792,
   "18-24m": 15596.1418,
   "1d-1w": 76.1194,
   "1w-1m": 451.0636,
   "2-3y": 20471.2648,
   "3-5y": 33903.6172,
   "3-6m": 3142.9224,
   "5-10y": 64551.2214,
   "6-12m": 6871.3697,
   "<1d": 10.3378,
   ">10y": 95306.9022
  },
  {
   "date": "2019-10-17",
   "1-3m": 1553.5454,
   "12-18m": 11016.0713,
   "18-24m": 15595.3426,
   "1d-1w": 78.7768,
   "1w-1m": 452.0231,
   "2-3y": 20477.4807,
   "3-5y": 33919.834,
   "3-6m": 3157.0836,
   "5-10y": 64560.6276,
   "6-12m": 6884.0698,
   "<1d": 6.1814,
   ">10y": 95325.3456
}
}
  }
]
]
```

### HTTP Request

`GET https://api.tokenanalyst.io/analytics/private/v1/token_utxo_metric_window_historical/last`

### Query Parameters

| Parameter    | Type      | Description                                                                               |
| ------------ | --------- | ----------------------------------------------------------------------------------------- |
| key          | _string_  | Your unique API key                                                                       |
| format       | _string_  | What format you want your data in (`json` or `csv`)                                       |
| metric       | _string_  | `weighted_avg_age`                                                                                |
| window       | _string_  | `1d` (no support for 1h at this time)                                                     |
| token        | _string_  | `btc`                                                                                |
| from_date \* | _string_  | Start date of returned data specified as YYYY-MM-DD (ISO date format)                     |
| to_date \*   | _string_  | End date of returned data specified as YYYY-MM-DD (ISO date format)                       |
| limit \*     | _integer_ | The number of entries returned before the latest data point (or the to_date if specified) |

Note: All params with a \* are optional and `limit` is only available in the JSON return format

### Data Overview

| Field  | Type      | Description                                                                                |
| ------ | --------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
| date   | _string_  | The date in _YYYY-MM-DD_                                                                                |
| <1d    | _decimal_ | The weighted average age of unspent outputs (UTXOs) on this date from transactions that occurred less than a day prior to this date.       |
| 1d-1w  | _decimal_ | The weighted average age of unspent outputs (UTXOs) on this date from transactions that occurred 1 day to 1 week prior to this date.       |
| 1w-1m  | _decimal_ | The weighted average age of unspent outputs (UTXOs) on this date from transactions that occurred 1 week to 1 month prior to this date.     |
| 1-3m   | _decimal_ | The weighted average age of unspent outputs (UTXOs) on this date from transactions that occurred 1 to 3 months prior to this date.         |
| 3-6m   | _decimal_ | The weighted average age of unspent outputs (UTXOs) on this date from transactions that occurred 3 to 6 months prior to this date.         |
| 6-12m  | _decimal_ | The weighted average age of unspent outputs (UTXOs) on this date from transactions that occurred 6 to 12 months prior to this date.        |
| 12-18m | _decimal_ | The weighted average age of unspent outputs (UTXOs) on this date) from transactions that occurred 12 to 18 months prior to this date.       |
| 18-24m | _decimal_ | The weighted average age of unspent outputs (UTXOs) on this date from transactions that occurred 18 to 24 months prior to this date.       |
| 2-3y   | _decimal_ | The weighted average age of unspent outputs (UTXOs) on this date from transactions that occurred 2 to 3 years prior to this date.          |
| 3-5y   | _decimal_ | The weighted average age of unspent outputs (UTXOs) on this date from transactions that occurred 3 to 5 years prior to this date.          |
| 5-10y  | _decimal_ | The weighted average age of unspent outputs (UTXOs) on this date from transactions that occurred 5 to 10 years prior to this date.         |
| >10y   | _decimal_ | The weighted average age of unspent outputs (UTXOs) on this date from transactions that occurred greater than 10 years prior to this date. |

## BTC UTXO Supply Percentage

```shell
# Make sure you substitute API_KEY for your unique API key.

curl "https://api.tokenanalyst.io/analytics/private/v1/token_utxo_metric_window_historical/last?window=1d&metric=supply_pct&format=json&token=btc&limit=2&key=API_KEY"
```

> The above command returns JSON structured like this:

```json
[
  {
    "date": "2019-09-01",
    "1-3m": 0.0812,
    "12-18m": 0.1705,
    "18-24m": 0.0795,
    "1d-1w": 0.0219,
    "1w-1m": 0.0646,
    "2-3y": 0.0491,
    "3-5y": 0.0657,
    "3-6m": 0.1322,
    "5-10y": 0.1438,
    "6-12m": 0.1105,
    "<1d": 0.0131,
    ">10y": 0.0679
  },
  {
    "date": "2019-09-02",
    "1-3m": 0.0815,
    "12-18m": 0.1705,
    "18-24m": 0.0798,
    "1d-1w": 0.0226,
    "1w-1m": 0.0634,
    "2-3y": 0.0491,
    "3-5y": 0.0658,
    "3-6m": 0.1317,
    "5-10y": 0.1436,
    "6-12m": 0.1109,
    "<1d": 0.0132,
    ">10y": 0.068,
    "date": "2019-03-15"
  }
]
```

This endpoint returns the proportion of the bitcoin supply on the specified date, held in unspent transaction outputs stratified by their age. For instance outputs in the category `12-18m` are unspent outputs (UTXOs) from transactions that occurred `12-18m` ago. Time is measured relative to blocktime assuming 6 blocks are generated per hour. This means that the proportion of UTXOs in the `<1d` category were generated less than or equal to `144 blocks ago (6 blocks * 24 hours)`.

The age in block height is used over the block timestamp because the block timestamp serves as a source of variation when calculating the blockhash and is only accurate to within an hour or two. By using timestamps some UTXOs could be considered older than a previously generated UTXO. By using block-age from current the blockheight, the age of utxos is strictly ordinal as blockheight is strictly sequential.

### HTTP Request

`GET https://api.tokenanalyst.io/analytics/private/v1/token_utxo_metric_window_historical/last`

### Query Parameters

| Parameter    | Type      | Description                                                                               |
| ------------ | --------- | ----------------------------------------------------------------------------------------- |
| key          | _string_  | Your unique API key                                                                       |
| format       | _string_  | What format you want your data in (`json` or `csv`)                                       |
| metric       | _string_  | `supply_pct`                                                                                |
| window       | _string_  | `1d` (no support for 1h at this time)                                                     |
| token        | _string_  | `btc`                                                                                |
| from_date \* | _string_  | Start date of returned data specified as YYYY-MM-DD (ISO date format)                     |
| to_date \*   | _string_  | End date of returned data specified as YYYY-MM-DD (ISO date format)                       |
| limit \*     | _integer_ | The number of entries returned before the latest data point (or the to_date if specified) |

Note: All params with a \* are optional and `limit` is only available in the JSON return format

### Data Overview

| Field  | Type      | Description                                                                                |
| ------ | --------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
| 1-3m   | _decimal_ | Proportion of bitcoin supply on this date held in unspent outputs (UTXOs) from transactions that occurred 1 to 3 months prior to this date.         |
| 12-18m | _decimal_ | Proportion of bitcoin supply on this date held in unspent outputs (UTXOs) from transactions that occurred 12 to 18 months prior to this date.       |
| 18-24m | _decimal_ | Proportion of bitcoin supply on this date held in unspent outputs (UTXOs) from transactions that occurred 18 to 24 months prior to this date.       |
| 1d-1w  | _decimal_ | Proportion of bitcoin supply on this date held in unspent outputs (UTXOs) from transactions that occurred 1 day to 1 week prior to this date.       |
| 1w-1m  | _decimal_ | Proportion of bitcoin supply on this date held in unspent outputs (UTXOs) from transactions that occurred 1 week to 1 month prior to this date.     |
| 2-3y   | _decimal_ | Proportion of bitcoin supply on this date held in unspent outputs (UTXOs) from transactions that occurred 2 to 3 years prior to this date.          |
| 3-5y   | _decimal_ | Proportion of bitcoin supply on this date held in unspent outputs (UTXOs) from transactions that occurred 3 to 5 years prior to this date.          |
| 3-6m   | _decimal_ | Proportion of bitcoin supply on this date held in unspent outputs (UTXOs) from transactions that occurred 3 to 6 months prior to this date.         |
| 5-10y  | _decimal_ | Proportion of bitcoin supply on this date held in unspent outputs (UTXOs) from transactions that occurred 5 to 10 years prior to this date.         |
| 6-12m  | _decimal_ | Proportion of bitcoin supply on this date held in unspent outputs (UTXOs) from transactions that occurred 6 to 12 months prior to this date.        |
| <1d    | _decimal_ | Proportion of bitcoin supply on this date held in unspent outputs (UTXOs) from transactions that occurred less than a day prior to this date.       |
| >10y   | _decimal_ | Proportion of bitcoin supply on this date held in unspent outputs (UTXOs) from transactions that occurred greater than 10 years prior to this date. |
| date   | _string_  | The date in _YYYY-MM-DD_                                                                                |

repository: tokenanalyst/slate

gha_language: JavaScript

gha_license_id: NOASSERTION

repo_name: tokenanalyst/slate


text:
# Version Control

![](../.gitbook/assets/Version-Control.png)

This page displays previous versions of configurations, and allows you to revert/restore the system to any saved configuration.

To do this, hover the cursor over the desired configuration. The "Restore Version" button will appear, as shown above.

Select this button. Once the process is complete, [publish](../settings/publish-changes.md). Curiefense will push the selected configuration out to all deployments.


text:
# Hippogotchi

#### A Tamagotchi-style app where users can "adopt" and care for an adorable hippo pet, 4/6/2020

#### By **Andrew Kim and Winter A. Runion**

### Description
_An exercise in functional programming for Epicodus. Pure functions and closures are used to store state in an efficient way._

### Instructions

* To play the game, view the app [here](https://wrunion.github.io/hippogotchi/)
* To create your own:
  * Clone this repository
  * Open the code in the editor of your choice.
  * Make any changes you like!
* If you want to follow along, this exercise goes with [this free Epicodus lesson](https://www.learnhowtoprogram.com/react-part-time-react-track/functional-programming-with-javascript-continued/building-a-functional-application-part-1-ac22a409-1e2b-41ba-bbc8-d3ba6b2a5a4e)

<!-- ### Specs
| Spec | Input | Output |
| :-------------     | :------------- | :------------- |
| **Spec Description**  | User Input: | Output: |
| **Spec Description**  | User Input: | Output: |
| **Spec Description**  | User Input: | Output: |
| **Spec Description**  | User Input: | Output: |
| **Spec Description**  | User Input: | Output: |
| **Spec Description**  | User Input: | Output: | -->

### Bugs

None known.

### Contact
Please open an issue if you find any bugs.

### License
_This software is licensed under the MIT license._

_Copyright (c) 2020 **Andrew Kim and Winter A. Runion**_

repository: wrunion/hippogotchi

repo_name: wrunion/hippogotchi


text:
**Status:** Archive - code is provided as-is, no updates expected.

# Improving the Generalization of End-to-End Driving through Procedural Generation

This is the official material of the paper: "Improving the Generalization of End-to-End Driving through Procedural Generation".

Please visit the following links to learn more on our PGDrive simulator:

**[ 📺 [Website](https://decisionforce.github.io/pgdrive/) | 🏗 [PGDrive Repo](https://github.com/decisionforce/pgdrive) | 📜 [Documentation](https://pgdrive.readthedocs.io/) | 🎓 [Paper](https://arxiv.org/pdf/2012.13681) ]**

## Setup the environment

```bash
# Clone this repo to local
git clone https://github.com/decisionforce/pgdrive-generalization-paper.git
cd pgdrive-generalization-paper

# Install dependencies
pip install -r requirements.txt
```

## Draw the main experiments' results

Before you draw the results, please decompress the `/data.zip` to `/data` folder.

```bash
# Generate result to results/ppo-main-result-up.pdf and results/ppo-main-result-down.pdf
python draw_ppo_results.py

# Generate result to results/sac-main-result-up.pdf and results/sac-main-result-down.pdf
python draw_sac_results.py
```

## Draw the other experiments' results

```bash
# Draw change density experiment result to results/change-friction-result.pdf
python eval_density.py

# Draw change friction experiment result to results/change-friction-result.pdf
python eval_friction.py
```

## Reproduce the experiments

```bash
# PPO main experiments
python train_ppo.py --exp-name main_ppo --num-gpus 0

# SAC Main experiments
python train_ppo.py --exp-name main_ppo --num-gpus 0

# Change friction experiments
python train_ppo_change_friction.py --exp-name change_friction --num-gpus 0

# Change density experiments
python train_ppo_change_density.py --exp-name change_density --num-gpus 0

# For the change density / friction experiments, you need to uncomment the script to call
# get_result function, then call
python eval_density.py
python eval_friction.py
```

## Cite this work

If you find this work useful in your project, please consider to cite it through:

```
@article{li2020improving,
  title={Improving the Generalization of End-to-End Driving through Procedural Generation},
  author={Li, Quanyi and Peng, Zhenghao and Zhang, Qihang and Qiu, Cong and Liu, Chunxiao and Zhou, Bolei},
  journal={arXiv preprint arXiv:2012.13681},
  year={2020}
}
```


text:
# Cube with background

**Tier:** 1-Beginner

I already experimented making 3d cubes in the previews day, so i tryed to make a cube that had a background video with its html body blurred and the same video.

## User Stories

-   [✔] User can see the html body blurred with the same video.
-   [✔] User can see all the cube faces passing a video.

## Bonus features

-   [✔] User can select any type of images as background color.
-   [✔] User can select gif as background.
-   [✔] User can hear the video.

## 12/100 3/19/2021 - DONE

## #100DAYSCHALLENGE

license: Unlicense