text:
---
date: "2014-10-27"
title: "Flux, qu'est-ce que c'est ?"
tags:
  - javascript
  - reactjs
  - flux
authors:
  - bloodyowl
---

Allez, tant pis, on saute l'intro et on entre directement dans le vif du sujet (on n'a pas que ça à foutre, après tout).

## La petite histoire

Il était une fois un gros site web *que s'apelorio* Facebook. Qui dit Facebook, dit webapp plus grosse que la plus grosse de tes copines (*no offense* [1](#foonote-1)) ; et du coup, propension à se retrouver submergé de bugs plus élevée.

Les ingénieurs front-end de Facebook, confrontés à une codebase de plus en plus bordélique (personne ne voulant toucher certaines parties de celle-ci) ont dû repenser la structure des composants les plus cruciaux.

Face à ce besoin, ces développeurs sont donc parvenus à deux solutions :

- [ReactJS](http://putaindecode.fr/posts/js/introduction-a-reactjs/)
- Flux

Flux n'est pas un framework, mais simplement une architecture, une sorte de *guideline* qui résout pas mal de problèmes ayant pu apparaître avec les divers bibliothèques et frameworks MV* apparus lors des dernières années.

## Flux, l'explication claire

Flux comporte 4 concepts :

- les **actions**, qu'elles proviennent du serveur ou d'une interaction utilisateur ;
- le **dispatcher** dans lequel sont envoyées les actions que ce dernier transmet *à qui veut*, un peu comme un `EventEmitter` global ;
- les **stores**, qui sont l'équivalent du `model` de l'architecture MVC, ils contiennent les données, et réagissent aux actions que le dispatcher leur transmet ;
- les **views**, qui s'occupent du rendu des données dans le DOM, et de lancer des actions lorsque l'utilisateur effectue certaines actions.

Jusque-là, rien de bien fou. C'est dans leur manière d'interagir que la particularité se dessine :

  ![](http://cl.ly/YENt/flux.png)

Oh bah dis donc, ça va toujours dans le même sens

En effet, le *flux* en question est unidirectionnel. Pour faire simple, on procède ainsi :

On définit une action via un **action creator** (on passera toujours par ces action-creators pour signaler une action) :

```javascript
// actions/BasketActions.js
var AppDispatcher = require("../AppDispacher")
/*
  On garde un dictionnaire des types d'actions
  afin d'avoir un fichier donnant une vision
  globale de toutes les interactions de l'app.
 */
var ActionTypes = require("../constants").ActionTypes

module.exports = {
  addToBasket : function(productId){
    AppDispatcher.handleViewAction({
      type : ActionTypes.ADD_TO_BASKET,
      productId : productId
    })
  }
}
```

On lancera par la suite cette action lorsque l'utilisateur aura cliqué sur un certain bouton, dans la vue concernée.

```javascript
// components/Product.jsx
var React = require("react/addons")
var BasketActions = require("../actions/BasketActions")

var Button = require("./common/Button.jsx")

var Product = React.createClass({
  addToBasket : function(productId){
    BasketActions.addToBasket(productId)
  },
  render : function(){
    return (
      <div className="Product">
        {/* rest of the component*/}
        <Button
          onClick={this.addToBasket.bind(this.props.productId)}
          label="Add to basket"
        />
      </div>
    )
  }
})

module.exports = Product
```

Dès lors, à chaque clic sur le bouton en question, l'action `ADD_TO_BASKET` sera passée au dispatcher, qui le signalera aux stores.

```javascript
// stores/BasketStore.js
var AppDispatcher = require("../AppDispatcher")
var ActionTypes = require("../constants").ActionTypes
var API = require("../api")

var merge = require("../utils/merge")
var Store = require("../utils/store")

var _store = {
  products : []
}

var BasketStore = merge(Store, {
  /*
    Ici, on `register` un callback sur l'AppDispatcher,
    ce qui signifie qu'on verra passer toutes les actions
    de l'app.
   */
  dispatchToken : AppDispatcher.register(function(payload){
    var action = payload.action
    switch(action.type) {
      case ActionTypes.ADD_TO_BASKET:
          /*
             L'API va ajouter le produit et lancer une
             action `BASKET_UPDATED` dès que le serveur a répondu.
          */
        API.addToBasket(action.productId)
        break
      case ActionTypes.BASKET_UPDATED:
          /*
            L'API a répondu, on peut stocker la réponse
            et signaler le changement
            aux vues récupérant ces données.
          */
          _store = action.reponse
          BasketStore.emitChange()
        break
      default:
        break
    }
  })
})

module.exports = BasketStore
```

La vue, quant à elle, sera notifiée du changement, et effectuera un `render()` :

```javascript
// components/Basket.jsx
var React = require("react/addons")
var BasketActions = require("../actions/BasketActions")
var BasketStore = require("../stores/BasketStore")

function getState(){
  return BasketStore.getStore()
}

var Product = React.createClass({
  getInitialState : function(){
    return getState()
  },
  _onStoreChange : function(){
    /*
      À chaque changement du store, on update naïvement
      le component et on laisse le virtual DOM faire son job.
    */
    this.setState(getState())
  },
  componentDidMount : function(){
    /*
      On écoute le store uniquement lorsque le
      component est monté.
     */
    BasketStore.addChangeListener(this._onStoreChange)
  },
  componentWillUnmount : function(){
    /*
      Et on arrête d'écouter quand il ne l'est plus.
     */
    BasketStore.removeChangeListener(this._onStoreChange)
  },
  render : function(){
    return (
      <div className="Basket">
        <div className="Basket-count">
          {this.state.products.length + " products"}
        </div>
        {/* rest of the component */}
      </div>
    )
  }
})

module.exports = Product
```

Tout cela peut sembler relativement verbeux, mais il faut préciser deux choses :

- les exemples ici le sont volontairement pour la démonstration, et il est aisément faisable d'utiliser un `StoreMixin` simplifier la déclaration des `class` React ;
- pour ce qui est du reste, notamment stocker les noms d'actions dans un objet partagé dans l'app, c'est pour rendre plus idiomatique et cohérente la façon dont on code l'app, et pour simplifier ses *refactoring*.

## Ce qu'il faut savoir sur l'alliance Flux + React

Si React et Flux vont si bien ensemble, c'est que l'approche de rendu "naïf" de React (comprendre "React s'en fout de ce qui change, il appelle `render` à chaque changement") permet de réduire la logique à écrire dans les Stores, et donc de simplifier très fortement la codebase de l'app.

Lorsque qu'un ou plusieurs stores composent l'état d'un state React, alors à chaque changement de l'un de ces stores, tous les composants React concernés et leurs enfants vont appeler leur méthode `render()`. Afin d'éviter des appels superflus à ces méthodes, React donne la possibilité de tester soi-même s'il est nécessaire de mettre à jour le component en déclarant une méthode `shouldComponentUpdate` retournant un `boolean` qui stipulera si oui ou non il est nécessaire d'appeler `render()`.

## tl;dr

- Flux, c'est comme du MVC en plus simple, et avec moins de bugs
- L'architecture est unidirectionnelle
- On raisonne en actions, qui sont déclenchées par la vue ou le serveur
- Toutes les actions passent par le dispatcher
- Seuls les stores signalent aux vues qu'il faut se mettre à jour

Bisous bisous.

![angulol](http://media.giphy.com/media/lxd2cZ2BkM4IE/giphy.gif)

Pour aller un peu plus loin :

- [Les sources des exemples](https://gist.github.com/bloodyowl/b41532cf3627c560b57e) contenant le dispatcher et les constants ;
- [La doc de Flux](http://facebook.github.io/flux/docs/overview.html#content) ;
- [Le repository Flux](https://github.com/facebook/flux) et ses différents exemples.

  1: [Référence utile (`ntm install reference`)](https://www.youtube.com/watch?v=jRzv9gep5Ng&t=4m)


text:
function Grid(size, previousState) {
  this.size = size;
  this.vals = [];
  this.cells = previousState ? this.fromState(previousState) : this.empty();
}

Grid.prototype.getNewValue = function (){
  if(!window.MyEasyModeA){
    return Math.random() < 0.9 ? 2 : 2*2;
  }
  var scale = this.getMaxScore()/16;
  scale = scale > 1 ? scale : 1;
  var value = 2*scale;
  value = Math.min(this.getMinScore(), value);
  return Math.random() < 0.9 ? value : value*2;
}

Grid.prototype.getMaxScore = function (){
  var maxval = 2;
  for(i in this.vals){if(this.vals[i]&&this.vals[i]>maxval){maxval = this.vals[i];}}
  return maxval;
}

Grid.prototype.getMinScore = function (){
  var minval = Math.pow(2,20);
  for(i in this.vals){if(this.vals[i]&&this.vals[i]<minval){minval = this.vals[i];}}
  return minval;
}

// Build a grid of the specified size
Grid.prototype.empty = function () {
  var cells = [];

  for (var x = 0; x < this.size; x++) {
    var row = cells[x] = [];

    for (var y = 0; y < this.size; y++) {
      row.push(null);
    }
  }

  return cells;
};

Grid.prototype.fromState = function (state) {
  var cells = [];

  for (var x = 0; x < this.size; x++) {
    var row = cells[x] = [];

    for (var y = 0; y < this.size; y++) {
      var tile = state[x][y];
      row.push(tile ? new Tile(tile.position, tile.value) : null);
    }
  }
  return cells;
};

// Find the first available random position
Grid.prototype.randomAvailableCell = function () {
  var cells = this.availableCells();

  if (cells.length) {
    return cells[Math.floor(Math.random() * cells.length)];
  }
};

Grid.prototype.availableCells = function () {
  var cells = [];

  this.eachCell(function (x, y, tile) {
    if (!tile) {
      cells.push({ x: x, y: y });
    }
  });

  return cells;
};

// Call callback for every cell
Grid.prototype.eachCell = function (callback) {
  for (var x = 0; x < this.size; x++) {
    for (var y = 0; y < this.size; y++) {
      callback(x, y, this.cells[x][y]);
    }
  }
};

// Check if there are any cells available
Grid.prototype.cellsAvailable = function () {
  return !!this.availableCells().length;
};

// Check if the specified cell is taken
Grid.prototype.cellAvailable = function (cell) {
  return !this.cellOccupied(cell);
};

Grid.prototype.cellOccupied = function (cell) {
  return !!this.cellContent(cell);
};

Grid.prototype.cellContent = function (cell) {
  if (this.withinBounds(cell)) {
    return this.cells[cell.x][cell.y];
  } else {
    return null;
  }
};

// Inserts a tile at its position
Grid.prototype.insertTile = function (tile) {
  this.cells[tile.x][tile.y] = tile;
};

Grid.prototype.removeTile = function (tile) {
  this.cells[tile.x][tile.y] = null;
};

Grid.prototype.withinBounds = function (position) {
  return position.x >= 0 && position.x < this.size &&
         position.y >= 0 && position.y < this.size;
};

Grid.prototype.serialize = function () {
  var cellState = [];

  for (var x = 0; x < this.size; x++) {
    var row = cellState[x] = [];

    for (var y = 0; y < this.size; y++) {
      row.push(this.cells[x][y] ? this.cells[x][y].serialize() : null);
    }
  }

  return {
    size: this.size,
    cells: cellState
  };
};

redpajama_set_name: RedPajamaGithub


text:
[Plugin triggers](https://github.com/dokku/plugn) (formerly [pluginhooks](https://github.com/progrium/pluginhook)) are a good way to jack into existing Dokku infrastructure. You can use them to modify the output of various Dokku commands or override internal configuration.

Plugin triggers are simply scripts that are executed by the system. You can use any language you want, so long as the script:

- Is executable
- Has the proper language requirements installed

For instance, if you wanted to write a plugin trigger in PHP, you would need to have `php` installed and available on the CLI prior to plugin trigger invocation.

The following is an example for the `nginx-hostname` plugin trigger. It reverses the hostname that is provided to nginx during deploys. If you created an executable file named `nginx-hostname` with the following code in your plugin trigger, it would be invoked by Dokku during the normal app deployment process:

```shell
#!/usr/bin/env bash
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x

APP="$1"; SUBDOMAIN="$2"; VHOST="$3"

NEW_SUBDOMAIN=`echo $SUBDOMAIN | rev`
echo "$NEW_SUBDOMAIN.$VHOST"
```

## Available plugin triggers

There are a number of plugin-related triggers. These can be optionally implemented by plugins and allow integration into the standard Dokku setup/teardown process.

The following plugin triggers describe those available to a Dokku installation. As well, there is an example for each trigger that you can use as templates for your own plugin development.

> The example plugin trigger code is not guaranteed to be implemented as in within dokku, and are merely simplified examples. Please look at the Dokku source for larger, more in-depth examples.

### `app-urls`

- Description: Allows you to change the urls Dokku reports for an application. Will override any auto-detected urls.
- Invoked by: `dokku deploy`, `dokku url`, and `dokku urls`
- Arguments: `$APP $URL_TYPE`
- Example:

```shell
#!/usr/bin/env bash
# Sets the domain to `internal.tld`
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x

APP="$1"; URL_TYPE="$2"
case "$URL_TYPE" in
  url)
    echo "https://internal.tld/${APP}/"
    ;;
  urls)
    echo "https://internal.tld/${APP}/"
    echo "http://internal.tld/${APP}/"
    ;;
esac
```

### `check-deploy`

- Description: Allows you to run checks on a deploy before Dokku allows the container to handle requests.
- Invoked by: `dokku deploy`
- Arguments: `$APP $CONTAINER_ID $PROC_TYPE $PORT $IP`
- Example:

```shell
#!/usr/bin/env bash
# Disables deploys of containers based on whether the
# `DOKKU_DISABLE_DEPLOY` env var is set to `true` for an app

set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_AVAILABLE_PATH/config/functions"

APP="$1"; CONTAINERID="$2"; PROC_TYPE="$3"; PORT="$4" ; IP="$5"

eval "$(config_export app $APP)"
DOKKU_DISABLE_DEPLOY="${DOKKU_DISABLE_DEPLOY:-false}"

if [[ "$DOKKU_DISABLE_DEPLOY" = "true" ]]; then
  echo -e "\033[31m\033[1mDeploys disabled, sorry.\033[0m"
  exit 1
fi
```

### `commands help` and `commands <PLUGIN_NAME>:help`

- Description: Your plugin should implement a `help` command in your `commands` file to take advantage of this plugin trigger. `commands help` is used by `dokku help` to aggregate all plugins abbreviated `help` output. Implementing  `<PLUGIN_NAME>:help` in your `commands` file gives users looking for help, a more detailed output. 'commands help' must be implemented inside the `commands` plugin file. It's recommended that `PLUGIN_NAME:help` be added to the commands file to ensure consistency among community plugins and give you a new avenue to share rich help content with your user.
- Invoked by: `dokku help` and `commands <PLUGIN_NAME>:help`
- Arguments: None
- Example:

```shell
#!/usr/bin/env bash
# Outputs help for the derp plugin

set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x

case "$1" in
  help | hello:help)
    help_content_func () {
      declare desc="return help_content string"
      cat<<help_content
    hello <app>, Says "Hello <app>"
    hello:world, Says "Hello world"
help_content
    }

    if [[ $1 = "hello:help" ]] ; then
        echo -e 'Usage: dokku hello[:world] [<app>]'
        echo ''
        echo 'Say Hello World.'
        echo ''
        echo 'Example:'
        echo ''
        echo '$ dokku hello:world'
        echo 'Hello world'
        echo ''
        echo 'Additional commands:'
        help_content_func | sort | column -c2 -t -s,
    else
        help_content_func
    fi
    ;;

  *)
    exit $DOKKU_NOT_IMPLEMENTED_EXIT
    ;;

esac
```

### `core-post-deploy`

> To avoid issues with community plugins, this plugin trigger should be used *only* for core plugins. Please avoid using this trigger in your own plugins.

- Description: Allows running of commands after an app's processes have been scaled up, but before old containers are torn down. Dokku core currently uses this to switch traffic on nginx.
- Invoked by: `dokku deploy`
- Arguments: `$APP $INTERNAL_PORT $INTERNAL_IP_ADDRESS $IMAGE_TAG`
- Example:

```shell
#!/usr/bin/env bash
# Notify an external service that a successful deploy has occurred.

set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x

curl "http://httpstat.us/200"
```

### `dependencies`

- Description: Used to install system-level dependencies.
- Invoked by: `dokku plugin:install-dependencies`
- Arguments: None
- Example:

```shell
#!/usr/bin/env bash
# Installs nginx for the current plugin
# Supports both opensuse and ubuntu

set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x

export DEBIAN_FRONTEND=noninteractive

case "$DOKKU_DISTRO" in
  debian|ubuntu)
    apt-get install --force-yes -qq -y nginx
    ;;

  opensuse)
    zypper -q in -y nginx
    ;;
esac
```

### `deploy-source`

- Description: Used for reporting what the current detected deployment source is. The first detected source should always win.
- Invoked by: `dokku apps:report`
- Arguments: `$APP`
- Example:

```shell
#!/usr/bin/env bash
# Checks if the app should be deployed via git

set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x

APP="$1"
STDIN=$(cat)

# bail if another source is detected
if [[ -n "$STDIN" ]]; then
  echo "$STDIN"
  return
fi

if [[ -d "$DOKKU_ROOT/$APP/refs" ]]; then
  echo "git"
fi
```

### `deployed-app-image-repo`

- Description: Used to manage the full repo of the image being deployed. Useful for deploying from an external registry where the repository name is not `dokku/$APP`
- Invoked by: `internal function dokku_deploy_cmd() (deploy phase)`
- Arguments: `$APP`
- Example:

```shell
#!/usr/bin/env bash

set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x

APP="$1"
# change the repo from dokku/APP to dokkupaas/APP
echo "dokkupaas/$APP"
```

### `deployed-app-image-tag`

- Description: Used to manage the tag of the image being deployed. Useful for deploying a specific version of an image, or when deploying from an external registry
- Invoked by: `internal function dokku_deploy_cmd() (deploy phase)`
- Arguments: `$APP`
- Example:

```shell
#!/usr/bin/env bash

set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x

# customize the tag version
echo 'not-latest'
```

### `deployed-app-repository`

- Description: Used to manage the remote repository of the image being deployed.
- Invoked by: `internal function dokku_deploy_cmd() (deploy phase)`
- Arguments: `$APP`
- Example:

```shell
#!/usr/bin/env bash

set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x

echo 'derp.dkr.ecr.us-east-1.amazonaws.com'
```

### `docker-args-build`

- Description:
- Invoked by: `internal function dokku_build() (build phase)`
- Arguments: `$APP $IMAGE_SOURCE_TYPE`
- Example:

```shell
#!/usr/bin/env bash
# Sets a docker build-arg called CACHEBUST which can be used
# to bust cache at any arbitrary point in a Dockerfile build
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x

STDIN=$(cat)
APP="$1"; IMAGE_SOURCE_TYPE="$2"
output=""

if [[ "$IMAGE_SOURCE_TYPE" == "dockerfile" ]]; then
  output=" --build-arg CACHEBUST=$(date +%s)"
fi
echo -n "$STDIN$output"
```

### `docker-args-deploy`

- Description:
- Invoked by: `dokku deploy`
- Arguments: `$APP $IMAGE_TAG [$PROC_TYPE $CONTAINER_INDEX]`
- Example:

```shell
#!/usr/bin/env bash

set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
APP="$1"; IMAGE_TAG="$2"; IMAGE=$(get_app_image_name $APP $IMAGE_TAG)
verify_app_name "$APP"

# TODO
```

### `docker-args-run`

- Description:
- Invoked by: `dokku run`
- Arguments: `$APP $IMAGE_TAG`
- Example:

```shell
#!/usr/bin/env bash

set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
APP="$1"; IMAGE_TAG="$2"; IMAGE=$(get_app_image_name $APP $IMAGE_TAG)
verify_app_name "$APP"

# TODO
```

### `git-post-pull`

- Description:
- Invoked by: `dokku git-upload-pack`
- Arguments: `$APP`
- Example:

```shell
#!/usr/bin/env bash

set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x

# TODO
```

### `git-pre-pull`

- Description:
- Invoked by: `dokku git-upload-pack`
- Arguments: `$APP`
- Example:

```shell
#!/usr/bin/env bash

set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x

# TODO
```

> Warning: The `git-pre-pull` trigger should _not_ be used for authentication
since it does not get called for commands that use `git-upload-archive` such
as `git archive`. Instead, use the [`user-auth`](#user-auth) trigger.

### `install`

- Description: Used to setup any files/configuration for a plugin.
- Invoked by: `dokku plugin:install`.
- Arguments: None
- Example:

```shell
#!/usr/bin/env bash
# Sets the hostname of the Dokku server
# based on the output of `hostname -f`

set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x

if [[ ! -f  "$DOKKU_ROOT/HOSTNAME" ]]; then
  hostname -f > $DOKKU_ROOT/HOSTNAME
fi
```

### `network-build-config`

- Description: Rebuilds network configuration
- Invoked by: `internally triggered by proxy-build-config within proxy implementations`
- Arguments: `$APP`
- Example:

```shell
#!/usr/bin/env bash

set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x

# TODO
```

### `network-clear-config`

- Description: Clears network configuration
- Invoked by: `internally triggered by proxy-clear-config within proxy implementations`
- Arguments: `$APP`
- Example:

```shell
#!/usr/bin/env bash

set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x

# TODO
```

### `network-compute-ports`

- Description: Computes the ports for a given app container
- Invoked by: `internally triggered by proxy-build-config within proxy implementations`
- Arguments: `$APP`
- Example:

```shell
#!/usr/bin/env bash

set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x

# TODO
```

### `network-config-exists`

- Description: Returns whether the network configuration for a given app exists
- Invoked by: `internally triggered by core-post-deploy within proxy implementations`
- Arguments: `$APP`
- Example:

```shell
#!/usr/bin/env bash

set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x

# TODO
```

### `network-get-ipaddr`

- Description: Return the ipaddr for a given app container
- Invoked by: `internally triggered by a deploy`
- Arguments: `$APP $PROC_TYPE $CONTAINER_ID`
- Example:

```shell
#!/usr/bin/env bash

set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x

# TODO
```

### `network-get-listeners`

- Description: Return the listeners (host:port combinations) for a given app container
- Invoked by: `internally triggered by a deploy`
- Arguments: `$APP`
- Example:

```shell
#!/usr/bin/env bash

set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x

# TODO
```

### `network-get-port`

- Description: Return the port for a given app container
- Invoked by: `internally triggered by a deploy`
- Arguments: `$APP $PROC_TYPE $CONTAINER_ID $IS_HEROKUISH_CONTAINER`
- Example:

```shell
#!/usr/bin/env bash

set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x

# TODO
```

### `network-get-property`

- Description: Return the network value for an app's property
- Invoked by: `internally triggered by a deploy`
- Arguments: `$APP $KEY`
- Example:

```shell
#!/usr/bin/env bash

set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x

# TODO
```

### `network-write-ipaddr`

- Description: Write the ipaddr for a given app index
- Invoked by: `internally triggered by a deploy`
- Arguments: `$APP $PROC_TYPE $CONTAINER_INDEX $IP_ADDRESS`
- Example:

```shell
#!/usr/bin/env bash

set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x

# TODO
```

### `network-write-port`

- Description: Write the port for a given app index
- Invoked by: `internally triggered by a deploy`
- Arguments: `$APP $PROC_TYPE $CONTAINER_INDEX $PORT`
- Example:

```shell
#!/usr/bin/env bash

set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x

# TODO
```

### `nginx-hostname`

- Description: Allows you to customize the hostname for a given app
- Invoked by: `dokku domains:setup`
- Arguments: `$APP $SUBDOMAIN $VHOST`
- Example:

```shell
#!/usr/bin/env bash
# Reverses the hostname for the app

set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x

APP="$1"; SUBDOMAIN="$2"; VHOST="$3"

NEW_SUBDOMAIN=`echo $SUBDOMAIN | rev`
echo "$NEW_SUBDOMAIN.$VHOST"
```

### `nginx-pre-reload`

- Description: Run before nginx reloads hosts
- Invoked by: `dokku nginx:build-config`
- Arguments: `$APP $INTERNAL_PORT $INTERNAL_IP_ADDRESS`
- Example:

```shell
#!/usr/bin/env bash
# Runs a check against all nginx conf files
# to ensure they are valid

set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x

nginx -t
```

### `post-app-clone`

- Description: Allows you to run commands after an app was cloned.
- Invoked by: `dokku apps:clone`
- Arguments: `$OLD_APP_NAME $NEW_APP_NAME`
- Example:

```shell
#!/usr/bin/env bash

set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x

# TODO
```

### `post-app-clone-setup`

- Description: Allows you to run commands after an app is setup, and before it is rebuild. This is useful for cleaning up tasks, or ensuring configuration from an old app is copied to the new app
- Invoked by: `dokku apps:clone`
- Arguments: `$OLD_APP_NAME $NEW_APP_NAME`
- Example:

```shell
#!/usr/bin/env bash

set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x

# TODO
```

### `post-app-rename`

- Description: Allows you to run commands after an app was renamed.
- Invoked by: `dokku apps:rename`
- Arguments: `$OLD_APP_NAME $NEW_APP_NAME`
- Example:

```shell
#!/usr/bin/env bash

set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x

# TODO
```

### `post-build-buildpack`

- Description: Allows you to run commands after the build image is create for a given app. Only applies to apps using buildpacks.
- Invoked by: `internal function dokku_build() (build phase)`
- Arguments: `$APP`
- Example:

```shell
#!/usr/bin/env bash

set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x

# TODO
```

### `post-build-dockerfile`

- Description: Allows you to run commands after the build image is create for a given app. Only applies to apps using a dockerfile.
- Invoked by: `internal function dokku_build() (build phase)`
- Arguments: `$APP`
- Example:

```shell
#!/usr/bin/env bash

set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x

# TODO
```

### `post-certs-remove`

- Description: Allows you to run commands after a cert is removed
- Invoked by: `dokku certs:remove`
- Arguments: `$APP`
- Example:

```shell
#!/usr/bin/env bash

set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
APP="$1"; verify_app_name "$APP"

# TODO
```

### `post-certs-update`

- Description: Allows you to run commands after a cert is added/updated
- Invoked by: `dokku certs:add`, `dokku certs:update`
- Arguments: `$APP`
- Example:

```shell
#!/usr/bin/env bash

set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
APP="$1"; verify_app_name "$APP"

# TODO
```

### `post-config-update`

- Description: Allows you to get notified when one or more configs is added or removed. Action can be *set* or *unset*
- Invoked by: `dokku config:set`, `dokku config:unset`
- Arguments: `$APP` `set|unset` `key1=VALUE1 key2=VALUE2`
- Example:

```shell
#!/usr/bin/env bash

set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x

# TODO
```

### `post-create`

- Description: Can be used to run commands after an app is created.
- Invoked by: `dokku apps:create`
- Arguments: `$APP`
- Example:

```shell
#!/usr/bin/env bash
# Runs a command to ensure that an app
# has a postgres database when it is starting

set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x

APP="$1";
POSTGRES="$1"

dokku postgres:create $POSTGRES
dokku postgres:link $POSTGRES $APP
```

### `post-delete`

- Description: Can be used to run commands after an app is deleted.
- Invoked by: `dokku apps:destroy`
- Arguments: `$APP $IMAGE_TAG`
- Example:

```shell
#!/usr/bin/env bash
# Runs a command to ensure that an app's
# postgres installation is removed

set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x

APP="$1";

dokku postgres:destroy $APP
```

### `post-deploy`

> Please see [core-post-deploy](#core-post-deploy) if contributing a core plugin with the `post-deploy` hook.

- Description: Allows running of commands after an app's processes have been scaled up, but before old containers are torn down. Dokku calls this _after_ `core-post-deploy`. Deployment Tasks are also invoked by this plugin trigger.
- Invoked by: `dokku deploy`
- Arguments: `$APP $INTERNAL_PORT $INTERNAL_IP_ADDRESS $IMAGE_TAG`
- Example:

```shell
#!/usr/bin/env bash
# Notify an external service that a successful deploy has occurred.

set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x

curl "http://httpstat.us/200"
```

### `post-domains-update`

- Description: Allows you to run commands once the domain for an app has been updated. It also sends in the command that has been used. This can be "add", "clear" or "remove". The third argument will be the optional list of domains
- Invoked by: `dokku domains:add`, `dokku domains:clear`, `dokku domains:remove`, `dokku domains:set`
- Arguments: `$APP` `action name` `domains`
- Example:

```shell
#!/usr/bin/env bash
# Reloads haproxy for our imaginary haproxy plugin
# that replaces the nginx-vhosts plugin

set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x

sudo service haproxy reload
```

### `post-extract`

- Description: Allows you to modify the contents of an app *after* it has been extracted from git/tarball but *before* the image source type is detected.
- Invoked by: `dokku tar:in`, `dokku tar:from` and the `receive-app` plugin trigger
- Arguments: `$APP` `$TMP_WORK_DIR` `$REV`
- Example:

```shell
#!/usr/bin/env bash
# Adds a clock process to an app's Procfile

set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
APP="$1"; verify_app_name "$APP"
TMP_WORK_DIR="$2"
REV="$3" # optional, may not be sent for tar-based builds

pushd "$TMP_WORK_DIR" >/dev/null
touch Procfile
echo "clock: some-command" >> Procfile
```

### `post-proxy-ports-update`

- Description: Allows you to run commands once the proxy port mappings for an app have been updated. It also sends the invoking command. This can be "add", "clear" or "remove".
- Invoked by: `dokku proxy:ports-add`, `dokku proxy:ports-clear`, `dokku proxy:ports-remove`
- Arguments: `$APP` `action name`
- Example:

```shell
#!/usr/bin/env bash
# Rebuilds haproxy config for our imaginary haproxy plugin
# that replaces the nginx-vhosts plugin

set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_AVAILABLE_PATH/haproxy/functions"
APP="$1"; verify_app_name "$APP"

haproxy-build-config "$APP"
```

### `post-release-buildpack`

- Description: Allows you to run commands after environment variables are set for the release step of the deploy. Only applies to apps using buildpacks.
- Invoked by: `internal function dokku_release() (release phase)`
- Arguments: `$APP $IMAGE_TAG`
- Example:

```shell
#!/usr/bin/env bash
# Installs a package specified by the `CONTAINER_PACKAGE` env var

set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
APP="$1"; IMAGE_TAG="$2"; IMAGE=$(get_app_image_name $APP $IMAGE_TAG)
verify_app_name "$APP"

dokku_log_info1 "Installing $CONTAINER_PACKAGE..."

CMD="cat > gm && \
  dpkg -s CONTAINER_PACKAGE >/dev/null 2>&1 || \
  (apt-get update && apt-get install -y CONTAINER_PACKAGE && apt-get clean)"

ID=$(docker run $DOKKU_GLOBAL_RUN_ARGS -i -a stdin $IMAGE /bin/bash -c "$CMD")
test $(docker wait $ID) -eq 0
docker commit $ID $IMAGE >/dev/null
```

### `post-release-dockerfile`

- Description: Allows you to run commands after environment variables are set for the release step of the deploy. Only applies to apps using a dockerfile.
- Invoked by: `internal function dokku_release() (release phase)`
- Arguments: `$APP $IMAGE_TAG`
- Example:

```shell
#!/usr/bin/env bash

set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
APP="$1"; IMAGE_TAG="$2"; IMAGE=$(get_app_image_name $APP $IMAGE_TAG)
verify_app_name "$APP"

# TODO
```

### `post-stop`

- Description: Can be used to run commands after an app is manually stopped
- Invoked by: `dokku ps:stop` and `dokku ps:stopall`
- Arguments: `$APP`
- Example:

```shell
#!/usr/bin/env bash
# Marks an app as manually stopped

set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x

APP="$1";

dokku config:set --no-restart $APP MANUALLY_STOPPED=1
```

### `pre-build-buildpack`

- Description: Allows you to run commands before the build image is created for a given app. For instance, this can be useful to add env vars to your container. Only applies to apps using buildpacks.
- Invoked by: `internal function dokku_build() (build phase)`
- Arguments: `$APP`
- Example:

```shell
#!/usr/bin/env bash

set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x

# TODO
```

### `pre-build-dockerfile`

- Description: Allows you to run commands before the build image is created for a given app. For instance, this can be useful to add env vars to your container. Only applies to apps using a dockerfile.
- Invoked by: `internal function dokku_build() (build phase)`
- Arguments: `$APP`
- Example:

```shell
#!/usr/bin/env bash

set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x

# TODO
```

### `pre-delete`

- Description: Can be used to run commands before an app is deleted.
- Invoked by: `dokku apps:destroy`
- Arguments: `$APP $IMAGE_TAG`
- Example:

```shell
#!/usr/bin/env bash
# Clears out the gulp asset build cache for apps

set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"

APP="$1"; GULP_CACHE_DIR="$DOKKU_ROOT/$APP/gulp"; IMAGE=$(get_app_image_name $APP $IMAGE_TAG)
verify_app_name "$APP"

if [[ -d $GULP_CACHE_DIR ]]; then
  docker run $DOKKU_GLOBAL_RUN_ARGS --rm -v "$GULP_CACHE_DIR:/gulp" "$IMAGE" find /gulp -depth -mindepth 1 -maxdepth 1 -exec rm -Rf {} \; || true
fi
```

### `pre-deploy`

- Description: Allows the running of code before the app's processes are scaled up and after the docker images are prepared.
- Invoked by: `dokku deploy`
- Arguments: `$APP $IMAGE_TAG`
- Example:

```shell
#!/usr/bin/env bash
# Runs gulp in our container

set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
APP="$1"; IMAGE_TAG="$2"; IMAGE=$(get_app_image_name $APP $IMAGE_TAG)
verify_app_name "$APP"

dokku_log_info1 "Running gulp"
id=$(docker run $DOKKU_GLOBAL_RUN_ARGS -d $IMAGE /bin/bash -c "cd /app && gulp default")
test $(docker wait $id) -eq 0
docker commit $id $IMAGE >/dev/null
dokku_log_info1 "Building UI Complete"
```

### `pre-disable-vhost`

- Description: Allows you to run commands before the VHOST feature is disabled
- Invoked by: `dokku domains:disable`
- Arguments: `$APP`
- Example:

```shell
#!/usr/bin/env bash

set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
APP="$1"; verify_app_name "$APP"

# TODO
```

### `pre-enable-vhost`

- Description: Allows you to run commands before the VHOST feature is enabled
- Invoked by: `dokku domains:enable`
- Arguments: `$APP`
- Example:

```shell
#!/usr/bin/env bash

set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
APP="$1"; verify_app_name "$APP"

# TODO
```

### `pre-receive-app`

- Description: Allows you to customize the contents of an app directory before they are processed for deployment. The `IMAGE_SOURCE_TYPE` can be any of `[herokuish, dockerfile]`
- Invoked by: `dokku git-hook`, `dokku tar-build-locked`
- Arguments: `$APP $IMAGE_SOURCE_TYPE $TMP_WORK_DIR $REV`
- Example:

```shell
#!/usr/bin/env bash
# Adds a file called `dokku-is-awesome` to the repository
# the contents will be the app name

set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x

APP="$1"; IMAGE_SOURCE_TYPE="$2"; TMP_WORK_DIR="$3"; REV="$4"

echo "$APP" > "$TMP_WORK_DIR/dokku-is-awesome"
```

### `pre-release-buildpack`

- Description: Allows you to run commands before environment variables are set for the release step of the deploy. Only applies to apps using buildpacks.
- Invoked by: `internal function dokku_release() (release phase)`
- Arguments: `$APP $IMAGE_TAG`
- Example:

```shell
#!/usr/bin/env bash
# Installs the graphicsmagick package into the container

set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
APP="$1"; IMAGE_TAG="$2"; IMAGE=$(get_app_image_name $APP $IMAGE_TAG)
verify_app_name "$APP"

dokku_log_info1 "Installing GraphicsMagick..."

CMD="cat > gm && \
  dpkg -s graphicsmagick >/dev/null 2>&1 || \
  (apt-get update && apt-get install -y graphicsmagick && apt-get clean)"

ID=$(docker run $DOKKU_GLOBAL_RUN_ARGS -i -a stdin $IMAGE /bin/bash -c "$CMD")
test $(docker wait $ID) -eq 0
docker commit $ID $IMAGE >/dev/null
```

### `pre-release-dockerfile`

- Description: Allows you to run commands before environment variables are set for the release step of the deploy. Only applies to apps using a dockerfile.
- Invoked by: `internal function dokku_release() (release phase)`
- Arguments: `$APP $IMAGE_TAG`
- Example:

```shell
#!/usr/bin/env bash

set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
APP="$1"; IMAGE_TAG="$2"; IMAGE=$(get_app_image_name $APP $IMAGE_TAG)
verify_app_name "$APP"

# TODO
```

### `pre-restore`

- Description: Allows you to run commands before all containers are restored
- Invoked by: `dokku ps:restore`
- Arguments: `$DOKKU_SCHEDULER`
- Example:

```shell
#!/usr/bin/env bash

set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
DOKKU_SCHEDULER="$1"

# TODO
```

### `pre-start`

- Description: Can be used to run commands before an app is started
- Invoked by: `dokku ps:start`
- Arguments: `$APP`
- Example:

```shell
#!/usr/bin/env bash
# Notifies an example url that an app is starting

set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x

APP="$1";

curl "https://dokku.me/starting/${APP}" || true
```

### `proxy-build-config`

- Description: Builds the proxy implementation configuration for a given app
- Invoked by: `internally triggered by ps:restore`
- Arguments: `$APP`
- Example:

```shell
#!/usr/bin/env bash

set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x

# TODO
```

### `proxy-clear-config`

- Description: Clears the proxy implementation configuration for a given app
- Invoked by: `internally triggered by apps:rename`
- Arguments: `$APP`
- Example:

```shell
#!/usr/bin/env bash

set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x

# TODO
```

### `proxy-enable`

- Description: Enables the configured proxy implementation for an app
- Invoked by: `internally triggered by ps:restore`
- Arguments: `$APP`
- Example:

```shell
#!/usr/bin/env bash

set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x

# TODO
```

### `proxy-disable`

- Description: Disables the configured proxy implementation for an app
- Invoked by: `internally triggered by ps:restore`
- Arguments: `$APP`
- Example:

```shell
#!/usr/bin/env bash

set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x

# TODO
```

### `receive-app`

- Description: Allows you to customize what occurs when an app is received. Normally just triggers an app build.
- Invoked by: `dokku git-hook`, `dokku ps:rebuild`
- Arguments: `$APP $REV` (`$REV` may not be included in cases where a repository is not pushed)
- Example:

```shell
#!/usr/bin/env bash
# For our imaginary mercurial plugin, triggers a rebuild

set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x

APP="$1"; REV="$2"

dokku hg-build $APP $REV
```

### `receive-branch`

- Description: Allows you to customize what occurs when a specific branch is received. Can be used to add support for specific branch names
- Invoked by: `dokku git-hook`, `dokku ps:rebuild`
- Arguments: `$APP $REV $REFNAME`
- Example:

```shell
#!/bin/bash
# Gives Dokku the ability to support multiple branches for a given service
# Allowing you to have multiple staging environments on a per-branch basis

reference_app=$1
refname=$3
newrev=$2
APP=${refname/*\//}.$reference_app

if [[ ! -d "$DOKKU_ROOT/$APP" ]]; then
  REFERENCE_REPO="$DOKKU_ROOT/$reference_app"
  git clone --bare --shared --reference "$REFERENCE_REPO" "$REFERENCE_REPO" "$DOKKU_ROOT/$APP" >/dev/null
fi
plugn trigger receive-app $APP $newrev
```

### `retire-container-failed`

- Description: Allows you to run commands if/when retiring old containers has failed
- Invoked by: `dokku deploy`
- Arguments: `$APP`
- Example:

```shell
#!/usr/bin/env bash
# Send an email when a container failed to retire

set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
APP="$1"; HOSTNAME=$(hostname -s)

mail -s "$APP containers on $HOSTNAME failed to retire" ops@dokku.me
```

### `report`

- Description: Allows you to report on any custom configuration in use by your application
- Invoked by: `dokku report`
- Arguments: `$APP`
- Example:

```shell
#!/usr/bin/env bash

set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
APP="$1";

# TODO
```

### `scheduler-deploy`

> Warning: The scheduler plugin trigger apis are under development and may change
> between minor releases until the 1.0 release.

- Description: Allows you to run scheduler commands when an app is deployed
- Invoked by: `dokku deploy`
- Arguments: `$DOKKU_SCHEDULER $APP $IMAGE_TAG`
- Example:

```shell
#!/usr/bin/env bash

set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
DOKKU_SCHEDULER="$1"; APP="$2"; IMAGE_TAG="$3";

# TODO
```

### `scheduler-docker-cleanup`

> Warning: The scheduler plugin trigger apis are under development and may change
> between minor releases until the 1.0 release.

- Description: Allows you to run scheduler commands when dokku cleanup is invoked
- Invoked by: `dokku deploy, dokku cleanup`
- Arguments: `$DOKKU_SCHEDULER $APP $FORCE_CLEANUP`
- Example:

```shell
#!/usr/bin/env bash

set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
DOKKU_SCHEDULER="$1"; APP="$2"; FORCE_CLEANUP="$3";

# TODO
```

### `scheduler-inspect`

> Warning: The scheduler plugin trigger apis are under development and may change
> between minor releases until the 1.0 release.

- Description: Allows you to run inspect commands for all containers for a given app
- Invoked by: `dokku ps:inspect`
- Arguments: `$DOKKU_SCHEDULER $APP`
- Example:

```shell
#!/usr/bin/env bash

set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
DOKKU_SCHEDULER="$1"; APP="$2";

# TODO
```

### `scheduler-logs-failed`

> Warning: The scheduler plugin trigger apis are under development and may change
> between minor releases until the 1.0 release.

- Description: Allows you to run scheduler commands when retrieving failed container logs
- Invoked by: `dokku logs:failed`
- Arguments: `$DOKKU_SCHEDULER $APP`
- Example:

```shell
#!/usr/bin/env bash

set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
DOKKU_SCHEDULER="$1"; APP="$2"; ARGS="${@:3}";

# TODO
```

### `scheduler-run`

> Warning: The scheduler plugin trigger apis are under development and may change
> between minor releases until the 1.0 release.

- Description: Allows you to run scheduler commands when a command is executed for your app
- Invoked by: `dokku run`
- Arguments: `$DOKKU_SCHEDULER $APP ...ARGS`
- Example:

```shell
#!/usr/bin/env bash

set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
DOKKU_SCHEDULER="$1"; APP="$2"; ARGS="${@:3}";

# TODO
```

### `scheduler-stop`

> Warning: The scheduler plugin trigger apis are under development and may change
> between minor releases until the 1.0 release.

- Description: Allows you to run scheduler commands when a tag is destroyed
- Invoked by: `dokku apps:destroy, dokku ps:stop`
- Arguments: `$DOKKU_SCHEDULER $APP $REMOVE_CONTAINERS`
- Example:

```shell
#!/usr/bin/env bash

set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
DOKKU_SCHEDULER="$1"; APP="$2"; REMOVE_CONTAINERS="$3";

# TODO
```

### `scheduler-tags-create`

> Warning: The scheduler plugin trigger apis are under development and may change
> between minor releases until the 1.0 release.

- Description: Allows you to run scheduler commands when a tag is created
- Invoked by: `dokku tags:create`
- Arguments: `$DOKKU_SCHEDULER $APP $SOURCE_IMAGE $TARGET_IMAGE`
- Example:

```shell
#!/usr/bin/env bash

set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
DOKKU_SCHEDULER="$1" APP="$2" SOURCE_IMAGE="$3" TARGET_IMAGE="$4"

# TODO
```

### `scheduler-tags-destroy`

> Warning: The scheduler plugin trigger apis are under development and may change
> between minor releases until the 1.0 release.

- Description: Allows you to run scheduler commands when a tag is destroyed
- Invoked by: `dokku tags:destroy`
- Arguments: `$DOKKU_SCHEDULER $APP $IMAGE_REPO $IMAGE_TAG`
- Example:

```shell
#!/usr/bin/env bash

set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
DOKKU_SCHEDULER="$1"; APP="$2"; IMAGE_REPO="$3"; IMAGE_TAG="$4";

# TODO
```

### `tags-create`

- Description: Allows you to run commands once a tag for an app image has been added
- Invoked by: `dokku tags:create`
- Arguments: `$APP $IMAGE_TAG`
- Example:

```shell
#!/usr/bin/env bash
# Upload an app image to docker hub

set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
APP="$1"; IMAGE_TAG="$2"; IMAGE=$(get_app_image_name $APP $IMAGE_TAG)

IMAGE_ID=$(docker inspect --format '{{ .Id }}' $IMAGE)
docker tag -f $IMAGE_ID $DOCKER_HUB_USER/$APP:$IMAGE_TAG
docker push $DOCKER_HUB_USER/$APP:$IMAGE_TAG
```

### `tags-destroy`

- Description: Allows you to run commands once a tag for an app image has been removed
- Invoked by: `dokku tags:destroy`
- Arguments: `$APP $IMAGE_TAG`
- Example:

```shell
#!/usr/bin/env bash
# Remove an image tag from docker hub

set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
APP="$1"; IMAGE_TAG="$2"

# some code to remove a docker hub tag because it's not implemented in the CLI...
```

### `uninstall`

 - Description: Used to cleanup after itself.
 - Invoked by: `dokku plugin:uninstall`
 - Arguments: `$PLUGIN`
 - Example:

```shell
#!/usr/bin/env bash
# Cleanup up extra containers created

set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x

PLUGIN="$1"

[[ "$PLUGIN" = "my-plugin" ]] && docker rmi -f "${PLUGIN_IMAGE_DEPENDENCY}"
```

 > To avoid uninstalling other plugins make sure to check the plugin name like shown in the example.

### `update`

- Description: Can be used to run plugin updates on a regular interval. You can schedule the invoker in a cron-task to ensure your system gets regular updates.
- Invoked by: `dokku plugin:update`.
- Arguments: None
- Example:

```shell
#!/usr/bin/env bash
# Update the herokuish image from git source

set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x

cd /root/dokku
sudo BUILD_STACK=true make install
```

### `user-auth`

This is a special plugin trigger that is executed on *every* command run. As Dokku sometimes internally invokes the `dokku` command, special care should be taken to properly handle internal command redirects.

Note that the trigger should exit as follows:

- `0` to continue running as normal
- `1` to halt execution of the command

The `SSH_USER` is the original ssh user. If you are running remote commands, this user will typically be `dokku`, and as such should not be trusted when checking permissions. If you are connected via ssh as a different user who then invokes `dokku`, the value of this variable will be that user's name (`root`, `myuser`, etc.).

The `SSH_NAME` is the `NAME` variable set via the `sshcommand acl-add` command. If you have set a user via the `dokku-installer`, this value will be set to `admin`. For installs via debian package, this value *may* be `default`. For reference, the following command can be run as the root user to specify a specific `NAME` for a given ssh key:

```shell
sshcommand acl-add dokku NAME < $PATH_TO_SSH_KEY
```

Note that the `NAME` value is set at the first ssh key match. If an ssh key is set in the `/home/dokku/.ssh/authorized_keys` multiple times, the first match will decide the value.

- Description: Allows you to deny access to a Dokku command by either ssh user or associated ssh-command NAME user.
- Invoked by: `dokku`
- Arguments: `$SSH_USER $SSH_NAME $DOKKU_COMMAND`
- Example:

```shell
#!/usr/bin/env bash
# Allow root/admin users to do everything
# Deny plugin access to default users
# Allow access to all other commands

set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x

SSH_USER=$1
SSH_NAME=$2
shift 2
[[ "$SSH_USER" == "root" ]] && exit 0
[[ "$SSH_NAME" == "admin" ]] && exit 0
[[ "$SSH_NAME" == "default" && $1 == plugin:* ]] && exit 1
exit 0
```


text:
.PHONY: all qing2sky container push clean test

TAG = 1.9
PREFIX = qingyuan

all: container

qing2sky: qing2sky.go
	GOOS=linux GOARCH=amd64 CGO_ENABLED=0 godep go build -a -installsuffix cgo --ldflags '-w' ./qing2sky.go

container: qing2sky
	docker build -t $(PREFIX)/qing2sky:$(TAG) .

push:
	docker push $(PREFIX)/qing2sky:$(TAG)

clean:
	rm -f qing2sky

test: clean
	godep go test -v --vmodule=*=4


text:
var Transform = require('stream').Transform
var utils = require('./utils')

// public
/**
 * the merge stream
 * public methods of the stream see stream.Transform
 *     .onThreshold( thresholdValue: Number
 *                  , thresholdListener: Function [ array of merge candidates ]
 *                  )
 *        will set the thresholdValue and add a listener for the 'threshold' event.
 * events:
 *     'threshold' emitted if a value is set and the number of unmerged payloads exceed the value
 */
module.exports = function merge (mergerFunc, shouldMergeCheck) {
  return new Merge(mergerFunc, shouldMergeCheck)
}

// convenience factory methods
module.exports.takeFirstMerge = function takeFirstMerge(){
  return new Merge( firstWins, mergeASAP )
}

module.exports.takeLastMerge = function takeLastMerge(){
  return new Merge( lastWins )
}

// convenience: some default shouldMergeCheck candidates
module.exports.checkers   = { waitForAll  : waitForAll
                            , mergeASAP   : mergeASAP
                            }

// convenience: some default mergerFunc candidates
module.exports.strategies = { firstWins  : firstWins
                            , lastWins   : lastWins
                            }

/**
 * for inheritance
 */
module.exports.Merge = Merge

// private

function Merge( merger, shouldMergeCheck ){
  if( ! ( this instanceof Merge ) ) return new Merge( merger, shouldMergeCheck )

  Transform.call( this, {objectMode:true} )

  var self = this

  if ( typeof merger !== 'function' )
    throw new TypeError('merger should be a function(arrayOfPayloads)')

  this.merger = merger

  if ( typeof shouldMergeCheck === 'function' || shouldMergeCheck == null ) {
    this.shouldMergeCheck = shouldMergeCheck || waitForAll
    this.mergeCount       = 0

    this.on('pipe', function(){
      self.mergeCount += 1
    })

    this.on('unpipe', function(){
      self.mergeCount -= 1
    })

  } else if ( typeof shouldMergeCheck === 'number' ) {
    this.shouldMergeCheck = waitForAll
    this.mergeCount       = shouldMergeCheck
  }

  this.cache = Object.create(null)
  this.threshholdValue = null
}

require('util').inherits( Merge, Transform )

require('./piping')(Merge.prototype)

Merge.prototype._transform = function _transform( item, encoding, callback ){
  var self          = this
  var cacheItem  = this.cache[ item.id ]
  if ( cacheItem === null ) {
    return callback()
  }

  if ( cacheItem === undefined ) {
    this.cache[ item.id ] = cacheItem = [ item.payload ]
    checkThreshold(this)
  } else {
    cacheItem.push( item.payload )
  }

  if ( this.shouldMergeCheck( cacheItem, this.mergeCount) !== true ) {
    return callback()
  }

  utils.asyncReduce( cacheItem, this.merger, function reduceCallback( err, result ) {
    if ( err ) {
      return callback(err)
    }

    item.applyPayload(result)
    self.push(item)
    self.cache[item.id] = null

    return callback()
  })
}

Merge.prototype.onThreshhold = function onThreshold( thresholdValue, listener ) {
  this.threshholdValue = thresholdValue

  if ( listener )
    this.on( 'threshold', listener )

  return this
}

function checkThreshold( merge ){
  if ( merge.threshholdValue > 0) {
    var cache = merge.cache
    var filteredCache = Object.keys( cache )
                                .map( function(key){  if ( cache[key] != null ) return cache[key]  } )

    if ( filteredCache.length > merge.threshholdValue ) {
      merge.emit('threshold', filteredCache )
    }
  }
}

// MERGE_CHECKER

function waitForAll( arr, mergeCount ){
  return arr.length >= mergeCount
}

function mergeASAP( arr, mergeCount ){
  return arr.length > 0
}

// MERGE_STRATEGIES

function firstWins (arr1, arr2, cb) {
  cb( null, arr1 )
}

function lastWins (arr1, arr2, cb) {
  cb( null, arr2 || arr1 )
}


text:
{% extends "layout/layout_8-4.html" %}
{% load static from staticfiles %}
{% load i18n %}
{% load cache %}
{% load pagination_tags %}
{% load crowdataapp_tags %}
{% load humanize %}

{% block headercontent %}

  Documentos por {{ field_name }}
{% endblock %}

{% block maincolumn %}

  {{ entry_value }}

{{ _('Documents') }}

{{ _('These are the ') }}{{ _('documents') }}{{ _(' that contains the text ') }}"{{ entry_value }}"{{ _(' in the field ') }}{{ field_name }}

  {% autopaginate documents %}
  {% for doc in documents %}

        {{ forloop.counter }}.

          {{ doc.1 }} - $ {{ doc.2|floatformat:"0"|intcomma }}

  {% endfor %}
  {% paginate %}

{% endblock %}

{% block rightcolumn %}
{% load humanize %}

  {% call_to_action document_set %}
  {% documents_verified document_set %}

{% list_ranking_user document_set.leaderboard|slice:":10" %}

{% list_ranking_organizations document_set.organization_board|slice:":10" %}

{% endblock %}


text:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:gravity="center"
    >
    <TextView
        android:layout_height="50dp"
        android:layout_width="match_parent"
        android:text="恭喜你,登录成功"
        android:gravity="center"
        />

</LinearLayout>


text:
/* eslint-disable */

'use strict';

/*::
import type { ConcreteRequest, Query } from 'relay-runtime';
import type { UserCustomGreetingResolver$key } from "./../resolvers/__generated__/UserCustomGreetingResolver.graphql";
import {custom_greeting as userCustomGreetingResolver} from "../resolvers/UserCustomGreetingResolver.js";
// Type assertion validating that `userCustomGreetingResolver` resolver is correctly implemented.
// A type error here indicates that the type signature of the resolver module is incorrect.
(userCustomGreetingResolver: (
  rootKey: UserCustomGreetingResolver$key,
  args: {|
    salutation: string,
  |},
) => mixed);
export type RelayReaderResolverTestCustomGreetingDynamicQuery$variables = {|
  salutation: string,
|};
export type RelayReaderResolverTestCustomGreetingDynamicQuery$data = {|
  +me: ?{|
    +dynamic_greeting: ?$Call<<R>((...empty[]) => R) => R, typeof userCustomGreetingResolver>,
    +greetz: ?$Call<<R>((...empty[]) => R) => R, typeof userCustomGreetingResolver>,
    +willkommen: ?$Call<<R>((...empty[]) => R) => R, typeof userCustomGreetingResolver>,
  |},
|};
export type RelayReaderResolverTestCustomGreetingDynamicQuery = {|
  response: RelayReaderResolverTestCustomGreetingDynamicQuery$data,
  variables: RelayReaderResolverTestCustomGreetingDynamicQuery$variables,
|};
*/

var node/*: ConcreteRequest*/ = (function(){
var v0 = [
  {
    "defaultValue": null,
    "kind": "LocalArgument",
    "name": "salutation"
  }
],
v1 = [
  {
    "kind": "Variable",
    "name": "salutation",
    "variableName": "salutation"
  }
],
v2 = {
  "args": null,
  "kind": "FragmentSpread",
  "name": "UserCustomGreetingResolver"
},
v3 = [
  {
    "kind": "Literal",
    "name": "salutation",
    "value": "Greetz"
  }
],
v4 = [
  {
    "kind": "Literal",
    "name": "salutation",
    "value": "Willkommen"
  }
],
v5 = {
  "kind": "InlineFragment",
  "selections": [
    {
      "alias": null,
      "args": null,
      "kind": "ScalarField",
      "name": "name",
      "storageKey": null
    }
  ],
  "type": "User",
  "abstractKey": null
};
return {
  "fragment": {
    "argumentDefinitions": (v0/*: any*/),
    "kind": "Fragment",
    "metadata": null,
    "name": "RelayReaderResolverTestCustomGreetingDynamicQuery",
    "selections": [
      {
        "alias": null,
        "args": null,
        "concreteType": "User",
        "kind": "LinkedField",
        "name": "me",
        "plural": false,
        "selections": [
          {
            "alias": "dynamic_greeting",
            "args": (v1/*: any*/),
            "fragment": (v2/*: any*/),
            "kind": "RelayResolver",
            "name": "custom_greeting",
            "resolverModule": require('./../resolvers/UserCustomGreetingResolver').custom_greeting,
            "path": "me.dynamic_greeting"
          },
          {
            "alias": "greetz",
            "args": (v3/*: any*/),
            "fragment": (v2/*: any*/),
            "kind": "RelayResolver",
            "name": "custom_greeting",
            "resolverModule": require('./../resolvers/UserCustomGreetingResolver').custom_greeting,
            "path": "me.greetz"
          },
          {
            "alias": "willkommen",
            "args": (v4/*: any*/),
            "fragment": (v2/*: any*/),
            "kind": "RelayResolver",
            "name": "custom_greeting",
            "resolverModule": require('./../resolvers/UserCustomGreetingResolver').custom_greeting,
            "path": "me.willkommen"
          }
        ],
        "storageKey": null
      }
    ],
    "type": "Query",
    "abstractKey": null
  },
  "kind": "Request",
  "operation": {
    "argumentDefinitions": (v0/*: any*/),
    "kind": "Operation",
    "name": "RelayReaderResolverTestCustomGreetingDynamicQuery",
    "selections": [
      {
        "alias": null,
        "args": null,
        "concreteType": "User",
        "kind": "LinkedField",
        "name": "me",
        "plural": false,
        "selections": [
          {
            "name": "custom_greeting",
            "args": (v1/*: any*/),
            "fragment": (v5/*: any*/),
            "kind": "RelayResolver",
            "storageKey": null
          },
          {
            "name": "custom_greeting",
            "args": (v3/*: any*/),
            "fragment": (v5/*: any*/),
            "kind": "RelayResolver",
            "storageKey": "custom_greeting(salutation:\"Greetz\")"
          },
          {
            "name": "custom_greeting",
            "args": (v4/*: any*/),
            "fragment": (v5/*: any*/),
            "kind": "RelayResolver",
            "storageKey": "custom_greeting(salutation:\"Willkommen\")"
          },
          {
            "alias": null,
            "args": null,
            "kind": "ScalarField",
            "name": "id",
            "storageKey": null
          }
        ],
        "storageKey": null
      }
    ]
  },
  "params": {
    "cacheID": "d531ee7ec8d062c94b16cdb2821cb2c9",
    "id": null,
    "metadata": {},
    "name": "RelayReaderResolverTestCustomGreetingDynamicQuery",
    "operationKind": "query",
    "text": "query RelayReaderResolverTestCustomGreetingDynamicQuery {\n  me {\n    ...UserCustomGreetingResolver\n    id\n  }\n}\n\nfragment UserCustomGreetingResolver on User {\n  name\n}\n"
  }
};
})();

if (__DEV__) {
  (node/*: any*/).hash = "8c67182e4793c86d528dbe4b8cf94a87";
}

module.exports = ((node/*: any*/)/*: Query<
  RelayReaderResolverTestCustomGreetingDynamicQuery$variables,
  RelayReaderResolverTestCustomGreetingDynamicQuery$data,
>*/);


text:
from os import environ
environ["CUDA_DEVICE_ORDER"] = "PCI_BUS_ID"
environ["CUDA_VISIBLE_DEVICES"] = ""

from _common import *
from ..generators.gen_singletons import make_coll, generate
from ..generators import gen_singletons as generator

'''
some global definitions
'''

NEPOCH = 50
VERSION = 4
MODELDIR = environ.get('MODELDIR', 'models/') + '/shallow/'
BASEDIR = environ['BASEDIR']
BASEDIR_VAR = environ.get('BASEDIR_VAR')
VARIATIONS = ['ISRRenorm']
#VARIATIONS = ['ISRRenorm', 'FSRRenorm']
_APOSTLE = None

# must be called!
def instantiate(default_variables=config.gen_default_variables,
                default_mus=config.gen_default_mus,
                default_sigmas=config.gen_default_sigmas):
    global _APOSTLE
    _APOSTLE = 'v%s'%(str(VERSION))
    system('mkdir -p %s/%s/'%(MODELDIR,_APOSTLE))
    system('cp -v %s %s/%s/trainer.py'%(sys.argv[0], MODELDIR, _APOSTLE))
    system('cp -v %s %s/%s/lib.py'%(__file__.replace('.pyc','.py'), MODELDIR, _APOSTLE))

    config.gen_default_variables = default_variables
    config.gen_default_mus = default_mus
    config.gen_default_sigmas = default_sigmas

    with open('%s/%s/setup.py'%(MODELDIR, _APOSTLE),'w') as fsetup:
        fsetup.write('''
# auto-generated. do not edit!
from subtlenet import config
from subtlenet.generators import gen_singletons as generator
config.gen_singletons = %s
config.gen_default_variables = %s
config.gen_default_mus = %s
config.gen_default_sigmas = %s
'''%(repr(config.gen_singletons),
     repr(config.gen_default_variables),
     repr(config.gen_default_mus),
     repr(config.gen_default_sigmas)))

    # instantiate data loaders
    top = make_coll(BASEDIR + '/PARTITION/Top_*_CATEGORY.npy')
    qcd = make_coll(BASEDIR + '/PARTITION/QCD_*_CATEGORY.npy', label=0)

    data = [top, qcd]

    if BASEDIR_VAR is not None:
        counter = 1
        for v in VARIATIONS:
            suffixes = [''] if v == 'Nominal' else ['Up', 'Down']
            for s in suffixes:
                data.append(make_coll(BASEDIR_VAR + '/PARTITION/QCD_%s_*_CATEGORY.npy'%(v + s),
                                      counter))
                counter += 1

    return data, (len(config.gen_default_variables),)

'''
first build the classifier!
'''

# set up data
def setup_data(data, opts=None):
    if opts is None:
        opts = {}
    gen = {
        'train' : generate(data, partition='train', batch=1000, **opts),
        'validation' : generate(data, partition='validate', batch=10000, **opts),
        'test' : generate(data, partition='test', batch=10, **opts),
        }
    return gen

def setup_adv_data(data):
    opts = {'decorr_mass':True}
    gen = {
        'train' : generate(data, partition='train', batch=1000, **opts),
        'validation' : generate(data, partition='validate', batch=10000, **opts),
        'test' : generate(data, partition='test', batch=10, **opts),
        }
    return gen

# this is purely a discriminatory classifier
def build_classifier(dims):
    N = dims[0]
    inputs  = Input(shape=dims, name='input')
    h = inputs
    h = BatchNormalization(momentum=0.6)(h)
    h = Dense(2*N, activation='tanh',kernel_initializer='lecun_uniform') (h)
    h = Dense(2*N, activation='tanh',kernel_initializer='lecun_uniform') (h)
    h = Dense(2*N, activation='tanh',kernel_initializer='lecun_uniform') (h)
    h = Dense(2*N, activation='tanh',kernel_initializer='lecun_uniform') (h)
    y_hat   = Dense(config.n_truth, activation='softmax', name='y_hat') (h)

    classifier = Model(inputs=inputs, outputs=[y_hat])
    classifier.compile(optimizer=Adam(lr=0.0001),
                       loss='categorical_crossentropy',
                       metrics=['accuracy'])

    print '########### CLASSIFIER ############'
    classifier.summary()
    print '###################################'

    return classifier

def build_kl_classifier(clf, n_class, loss='kl'):
    kl_input = Input(shape=(n_class,), name='kl_input')
    y_hat = clf.outputs[0]
    tag = Lambda(lambda x : x[:,-1:], output_shape=(1,))(y_hat)
    kl_output = concatenate([tag, kl_input], axis=-1, name='kl')
    inputs = clf.inputs + [kl_input]
    outputs = clf.outputs + [kl_output]

    lossfn = DistCompatibility(config.n_decorr_bins, n_class, loss)

    kl = Model(inputs=inputs, outputs=outputs)
    kl.compile(optimizer=Adam(lr=0.0001),
               loss=['categorical_crossentropy', lossfn],
               loss_weights=[1,10])

    print '########### KL-MODIFIED ############'
    kl.summary()
    print '###################################'

    return kl

def build_adversary(clf, loss, scale, w_clf, w_adv, N=config.n_decorr_bins):
    y_hat = clf.outputs[0]
    inputs= clf.inputs
    kin_hats = Adversary(N, n_outputs=1, scale=scale)(y_hat)
    adversary = Model(inputs=inputs,
                      outputs=[y_hat]+kin_hats)
    adversary.compile(optimizer=Adam(lr=0.00025),
                      loss=['categorical_crossentropy']+[loss for _ in kin_hats],
                      loss_weights=[w_clf]+[w_adv for _ in kin_hats])

    print '########### ADVERSARY ############'
    adversary.summary()
    print '###################################'

    return adversary

# train any model
def train(model, name, train_gen, validation_gen, save_clf_params=None):
    if save_clf_params is not None:
        callbacks = [PartialModelCheckpoint(filepath='%s/%s/%s_clf_best.h5'%(MODELDIR,_APOSTLE,name),
                                            save_best_only=True, verbose=True,
                                            **save_clf_params)]
        save_clf = save_clf_params['partial_model']
    else:
        save_clf = model
        callbacks = []
    callbacks += [ModelCheckpoint('%s/%s/%s_best.h5'%(MODELDIR,_APOSTLE,name),
                                  save_best_only=True, verbose=True)]

    def save_classifier(name_=name, model_=save_clf):
        model_.save('%s/%s/%s.h5'%(MODELDIR,_APOSTLE,name_))

    def save_and_exit(signal=None, frame=None):
        save_classifier()
        exit(1)

    signal.signal(signal.SIGINT, save_and_exit)

    model.fit_generator(train_gen,
                        steps_per_epoch=3000,
                        epochs=NEPOCH,
                        validation_data=validation_gen,
                        validation_steps=100,
                        callbacks = callbacks,
                       )
    save_classifier()

def infer(modelh5, name):
    print 'loading',modelh5
    model = load_model(modelh5,
                       custom_objects={'DenseBroadcast':DenseBroadcast})
    model.summary()

    coll = generator.make_coll(BASEDIR + '/PARTITION/*_CATEGORY.npy')

    def predict_t(data):
        inputs = data['singletons'][:,[config.gen_singletons[x]
                                       for x in config.gen_default_variables]]
        if config.gen_default_mus is not None:
            mus = np.array(config.gen_default_mus)
            sigmas = np.array(config.gen_default_sigmas)

        if inputs.shape[0] > 0:
            if config.gen_default_mus is not None:
                inputs -= mus
                inputs /= sigmas
            r_t = model.predict(inputs)[:,config.n_truth-1]
        else:
            r_t = np.empty((0,))

        return r_t

    coll.infer(['singletons'], f=predict_t, name=name, partition='test')


text:
<!DOCTYPE html>

	<meta http-equiv="content-type" content="text/html; charset=utf-8" />
	<meta name="author" content="Fabricio Bianchi" />
    <link rel="icon" type="image/png" href="favicon.png">

	<link href="http://fonts.googleapis.com/css?family=Lato:300,400,400italic,600,700|Raleway:300,400,500,600,700|Crete+Round:400italic" rel="stylesheet" type="text/css" />
	<link rel="stylesheet" href="css/bootstrap.css" type="text/css" />
	<link rel="stylesheet" href="style.css" type="text/css" />
	<link rel="stylesheet" href="css/swiper.css" type="text/css" />
	<link rel="stylesheet" href="css/dark.css" type="text/css" />
	<link rel="stylesheet" href="css/font-icons.css" type="text/css" />
	<link rel="stylesheet" href="css/animate.css" type="text/css" />
	<link rel="stylesheet" href="css/magnific-popup.css" type="text/css" />

	<link rel="stylesheet" href="css/responsive.css" type="text/css" />
	<link rel="stylesheet" href="css/colors.css" type="text/css" />
	<meta name="viewport" content="width=device-width, initial-scale=1" />

	<title>Comunidad Padre Misericordioso - Rosario, Argentina.</title>

Facebook

Instagram

							Rosario, Argentina
							Zeballos 668

							Llamanos
							(0341) 440-6670

Inicio

Conocenos

Dispositivos

Colaborar

Contacto

							Donar ahora

Colaborar

A continuación te presentamos las distintas actividades concretas que se realizan en nuestra comunidad. Estás invitado a participar a cualquiera de ellas, ¡te esperamos!

Grupo de oración

Cuando todavía estaba lejos, su padre lo vio y se conmovió profundamente, corrió a su encuentro, lo abrazó y lo besó.

								Lc. 15, 20.

Como Comunidad buscamos a Dios que nos invita a orar por nosotros mismos y por los demás. Con cánticos de alabanzas y adoraciones al santísimo sacramento, piden todos los miércoles a las 20:00 hs. en Zeballos 668 por los jóvenes que se encuentran haciendo tratamiento, aquellos en situación de calle e intenciones particulares.

Encontrarás un lugar muy especial para llegar a Dios.

Adoración Eucarística

Sentimos el llamado de brindar nuestro tiempo orando al Padre, para que todos aquellos que se sientan solos, desprotegidos, hambrientos, sin techo, sientan en sus corazones el amor y recuerden que el Padre es misericordioso,que siempre está esperando en la puerta el regreso de su hijo. Es el mismo Espíritu Santo quien le recuerda, al corazón del hijo pródigo, la vida con su Padre y le hace añorar su hogar.

Te esperamos en Zeballos 668 para que juntos a Jesús Eucaristía pidamos al Padre por nuestros hermanos más necesitados.

Horario de invierno: Jueves de 16:00 a 20:00hs. Horario de verano: Jueves de 17:00 a 21:00hs.

Cocinero solidario

Dentro de esta tarea nos encontramos tanto quienes donamos alimentos como aquellos que compramos los alimentos, cocinamos y disponemos en viandas para que Callejeros de la Fe repartan a personas en situación de calle.

No hay una cantidad definida, cada uno aporta según su situación y disponibilidad, pero por lo general se realizan aproximadamente unas 15 viandas por cocinero.

Señor, cuando tenga hambre, dame alguien que tenga necesidad de alimento. Cuando tenga sed, mándame a alguien que necesite de bebida. Haznos dignos, Señor, de servir a nuestros hermanos que, en todo el mundo, viven y mueren pobres y hambrientos.

								Santa Teresa de Calcuta.

Si estás interesado en colaborar como Cocinero Solidario, acercate a la Sede o simplemente llamá por teléfono.

Feria americana

La Feria de la Comunidad funciona todos los lunes de 16:30 a 19:30hs. en la cual se puede encontrar diversos artículos y ropas en muy buen estado. La misma funciona gracias a la donación de la gente y lo que recauda ayuda a que la Comunidad pueda cumplir los objetivos de brindar esperanza y dignificar a personas en situación vulnerable.

Acércate a conocerla y a colaborar con la Comunidad.

Callejeros de la fe

Somos un grupo de jóvenes voluntarios que salimos al encuentro de personas en situación de calle, tratando de generar un vínculo a través de la escucha y contención.

En estas salidas brindamos nuestro tiempo, un plato de comida y abrigo; llevando un mensaje de esperanza y dándole la oportunidad de ingresar al centro de rehabilitación a quien manifieste el deseo.

... Son muchos los jóvenes que se solidarizan ante los males del mundo y se embarcan en diversas formas de militancia y voluntariado. (...) ¡Qué bueno es que los jóvenes sean «callejeros de la fe», felices de llevar a Jesucristo a cada esquina, a cada plaza, a cada rincón de la tierra!

								Francisco. Evangelii Gaudium N° 106

Callejeamos la fe porque:

Sabemos que el cambio comienza en uno mismo.

Queremos ser instrumentos de Dios para que otros lo conozcan y sepan que Él los ama.

Buscamos olvidarnos de nosotros mismos y encontrarnos en la mirada del otro.

Tratamos de poner en práctica lo que Jesús nos enseñó, ver al prójimo con sus ojos.

Voluntario para mí es dar un poco de tu tiempo a los demás. Y descubrir en esa pequeña acción a mi hermano que está en situación de calle. Es descubrir a Cristo que esta esperándome.

														Betiana
														Callejeros de la fe.

Amar es darse. No hay mejor recompensa que sentirse útil y lleno. Y como decía la Madre Teresa, "A veces sentimos que lo que hacemos es tan solo una gota en el mar, pero el mar sería menos si le faltara una gota."

														Rixio
														Callejeros de la fe.

No pases de largo

								Decidí no pasarle de largo a la realidad de muchos hermanos.
Te animamos a registrate como voluntario y comprometerte a callejear la fe.

							Registrarme

								<form id="widget-subscribe-form" action="include/subscribe.php" role="form" method="post" class="nobottommargin">

										<input type="email" id="widget-subscribe-form-email" name="widget-subscribe-form-email" class="form-control required email" placeholder="Ingresa tu correo">

											<button class="btn btn-success" type="submit">Registrarme</button>

								</form>

								Cerrar

						<video poster="images/videos/callejeros.jpg" preload="auto" loop autoplay muted>
							<source src='images/videos/callejeros.mp4' type='video/mp4' />

						</video>

						  comunidadpadremisericordioso@gmail.com
  (0341) 440-6670 ·  Zeballos 668 - Rosario, Argentina.

Sitio web por: Fabricio Bianchi

						Comunidad Padre Misericordioso, personería jurídica:
Resolución 1127 - 30/12/2010 - Santa Fe. Expte. N° 70117/2010.

Estamos trabajando

De momento sólo podemos recibir donaciones de forma personal en nuestra sede de calle Zeballos 668 - Rosario, Argentina.

Estamos trabajando para poder recibir donaciones de forma online a través de este medio.

				Entendido


text:
Customers

            Name
            Email
            Mobile(Phone)
            States
            City
            Address
            Register Date
            Approved

        <?php foreach ($customers as $customer) {
            $acc = $customer['account'];
            $cus = $customer['customer'];
            ?>

                <?php echo $acc->fullname ?>
                <?php echo $acc->email_address; ?>
                <?php echo $acc->accountPhone; ?>
                Malaysia
                <?php echo $acc->accountCity; ?>
                <?php echo $acc->accountAddress ?>
                <?php echo substr($acc->registered_date, 0, 10); ?>
                <input type="checkbox" class="approve" <?php echo ($cus->company_permit == 'Approved') ? 'checked' : '' ?> user_data_id="<?php echo $cus->user_data_id; ?>">

        <?php } ?>


text:
<!DOCTYPE html>
<html class="app-loading">

    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
        <meta http-equiv="Content-Security-Policy" content="default-src * 'self' data:; img-src * 'self' 'unsafe-inline' 'unsafe-eval' data: blob: filesystem:; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' 'unsafe-eval'">

        <title>{%=o.htmlWebpackPlugin.options.pkg.title %}</title>
        <script>
            var wordpressHybridClient = {};
            wordpressHybridClient.version = "{%= o.htmlWebpackPlugin.options.appVersion %}";
        </script>
        <script src="admob.js"></script>
        <!-- cordova script (this will be a 404 during development) -->
        <script src="cordova.js"></script>
    </head>

    <body ng-strict-di ng-app="dekutcuapp">
        <ion-nav-view></ion-nav-view>
        {% for (var chunk in o.htmlWebpackPlugin.files.chunks) { %}
        <script src="{%=o.htmlWebpackPlugin.files.chunks[chunk].entry %}"></script>
        {% } %}
    </body>
    <!-- {%= o.htmlWebpackPlugin.options.pkg.name + ' v' + o.htmlWebpackPlugin.options.pkg.version + ' built on ' + new Date() %} -->

</html>


text:
var request = require('request');

/**
 * Initializes the Mailgun module
 * @param api_key {String} the API Key for the mailgun account
 * @param domain {String} the mailgun domain
 * @type {Function}
 */
module.exports = function (api_key, domain) {
  if (!api_key) {
    throw new Error('Mailgun "API key" required');
  }

  if (!domain) {
    throw new Error('Mailgun "domain" required');
  }

  var username = 'api';
  var protocol = 'https://';
  var host = 'api.mailgun.net';
  var endpoint = '/v2';

  var headers = {};
  var b = new Buffer([username, api_key].join(':'));
  headers['Authorization'] = "Basic " + b.toString('base64');

  /**
   * The main function that does all the work. The client really shouldn't call this.
   * @param method {String} HTTP method
   * @param resource {String} the resource
   * @param data {Object} the data to be sent in the request
   * @param cb {Function} callback for the request
   * @return
   */
  function _request(method, resource, data, cb) {

    if (typeof data === 'function' && !cb) {
      cb = data;
      data = {};
    }

    var getDomain = function () {
      var d = '/' + domain;
      //filter out API calls that do not require a domain specified
      if ((resource.indexOf('routes') >= 0)
        || (resource.indexOf('lists') >= 0)) {
        d = '';
      }
      return d;
    };

    var url = '';
    url = url.concat(
      protocol,
      username, ':', api_key,
      '@',
      host,
      endpoint,
      getDomain(),
      resource);

    var opts = {
      url: url,
      method: method,
      headers: headers,
      agent: false
    };

    if (method === 'GET' || method === 'DELETE') {
      opts.qs = data;
    }
    else {
      opts.form = data;
    }

    var responseCb = function (error, response, body) {
      if (response && (response.headers['content-type'] === 'application/json')) {
        try {
          body = JSON.parse(body);

          if (!error && response.statusCode !== 200) {
            error = new Error(body.message);
          }
        } catch (e) {

        }
      }

      return (cb || Function)(error, response, body);
    };

    return request(opts, responseCb);
  }

  function post(path, data, callback) {
    return _request('POST', path, data, callback);
  }

  function get(path, data, callback) {
    return _request('GET', path, data, callback);
  }

  function del(path, data, callback) {
    return _request('DELETE', path, data, callback);
  }

  function put(path, data, callback) {
    return _request('PUT', path, data, callback);
  }

  return {
    messages: {
      /**
       * Creates a new email message and sends it using mailgun
       * @param data {Object} the object containing the data to be sent.
       *                      Required parameters are 'to', 'from', and 'text' or 'html'
       * @param cb {Function} callback function accepting error, response and body
       * @type {Function}
       */
      send: function (data, cb) {
        if (!data.to) {
          return (cb || Function)(new Error('You must include a "to" parameter.'));
        }
        if (!data.from) {
          return (cb || Function)(new Error('You must include a "from" parameter.'));
        }
        if (!data.text && !data.html) {
          return (cb || Function)(new Error('You must include a "text" or "html" parameter.'));
        }

        return post('/messages', data, cb);
      }
    },

    mailboxes: {
      /**
       * Lists mailboxes associated with the mailgun account
       * @param data {Object} the optional object containing the GET options 'limit' and 'skip'
       * @param cb {Function} callback function accepting error, response and body
       * @type {Function}
       */
      list: function (data, cb) {
        return get('/mailboxes', data, cb);
      },

      /**
       * Creates a new mailbox associated with the mailgun account
       * @param data {Object} the object containing the new mailbox name ('mailbox') and new password ('password')
       * @param cb {Function} callback function accepting error, response and body
       * @type {Function}
       */
      create: function (data, cb) {
        if (!data.mailbox) {
          return (cb || Function)(new Error('You must include name of the mailbox in the \'mailbox\' parameter.'));
        }
        if (!data.password) {
          return (cb || Function)(new Error('You must include a password for the new mailbox.'));
        }

        return post('/mailboxes', data, cb);
      },

      /**
       * Deletes a mailbox associated with the mailgun account
       * @param mailbox {String} the mailbox to be deleted
       * @param cb {Function} callback function accepting error, response and body
       * @type {Function}
       */
      del: function (mailbox, cb) {
        if (!mailbox || typeof mailbox !== 'string') {
          return (cb || Function)(new Error('You must include name of the mailbox.'));
        }

        return del('/mailboxes/' + mailbox, cb);
      },

      /**
       * Updates the mailbox associated with the mailgun account
       * @param data {Object} the object containing the mailbox name ('mailbox') and new password ('password')
       * @param cb {Function} callback function accepting error, response and body
       * @type {Function}
       */
      update: function (data, cb) {
        if (!data.mailbox) {
          return (cb || Function)(new Error('You must include name of the mailbox in the \'mailbox\' parameter.'));
        }
        if (!data.password) {
          return (cb || Function)(new Error('You must include a password for the mailbox.'));
        }

        var mailbox = data.mailbox;
        delete data.mailbox;

        return put('/mailboxes/' + mailbox, data, cb);
      }
    },

    routes: {
      /**
       * Lists routes associated with the mailgun account
       * @param data {Object} the optional object containing the GET options 'limit' and 'skip'
       * @param cb {Function} callback function accepting error, response and body
       * @type {Function}
       */
      list: function (data, cb) {
        return get('/routes', data, cb);
      },

      /**
       * Returns a single route object based on its ID.
       * @param id {String} the route ID
       * @param cb {Function} callback function accepting error, response and body
       * @type {Function}
       */
      get: function (id, cb) {
        if (!id || typeof id !== 'string') {
          return (cb || Function)(new Error('You must include id of the route.'));
        }

        return get('/routes/' + id, cb);
      },

      /**
       * Creates a new route
       * @param data {Object} the object containing the priority, description, expression and action as strings
       * @param cb {Function} callback function accepting error, response and body
       * @type {Function}
       */
      create: function (data, cb) {
        if (!data.expression) {
          return (cb || Function)(new Error('You must include route expression.'));
        }
        if (!data.action) {
          return (cb || Function)(new Error('You must include route action.'));
        }

        return post('/routes', data, cb);
      },

      /**
       * Updates a given route by ID. All data parameters optional:
       * this API call only updates the specified fields leaving others unchanged.
       * @param id {String} the route ID
       * @param data {Object} the object containing the priority, description, expression and action as strings
       * @param cb {Function} callback function accepting error, response and body
       * @type {Function}
       */
      update: function (id, data, cb) {
        if (!data || (typeof data !== 'object')) {
          return (cb || Function)(new Error('You must include data.'));
        }

        if (!id || typeof id !== 'string') {
          return cb(new Error('You must include id of the route.'));
        }

        return put('/routes/' + id, data, cb);
      },

      /**
       * Deletes a route based on the id.
       * @param id {String} the id of the route to be deleted
       * @param cb {Function} callback function accepting error, response and body
       * @type {Function}
       */
      del: function (id, cb) {
        if (!id || typeof id !== 'string') {
          return (cb || Function)(new Error('You must include the id of the route.'));
        }

        return del('/routes/' + id, cb);
      }
    },

    lists: {
      /**
       * Returns a list of mailing lists under your account.
       * @param data {Object} the optional object containing the GET options 'address', 'limit' and 'skip'
       * @param cb {Function} callback function accepting error, response and body
       * @type {Function}
       */
      list: function (data, cb) {
        return get('/lists', data, cb);
      },

      /**
       * Returns a single mailing list by a given address.
       * @param address {String} the mailing list address
       * @param cb {Function} callback function accepting error, response and body
       * @type {Function}
       */
      get: function (address, cb) {
        if (!address || typeof address !== 'string') {
          return (cb || Function)(new Error('You must include mailing list address.'));
        }

        return get('/lists/' + address, cb);
      },

      /**
       * Creates a new mailing list.
       * @param data {Object} the object containing the address, name, description, and access_level as strings
       * @param cb {Function} callback function accepting error, response and body
       * @type {Function}
       */
      create: function (data, cb) {
        if (!data.address) {
          return (cb || Function)(new Error('You must include mailing list address.'));
        }

        return post('/lists', data, cb);
      },

      /**
       * Update mailing list properties, such as address, description or name.
       * @param address {String} mailing list address
       * @param data {Object} the object containing the address, name, description, and access_level as strings
       * @param cb {Function} callback function accepting error, response and body
       * @type {Function}
       */
      update: function (address, data, cb) {
        if (!data || (typeof data !== 'object')) {
          return (cb || Function)(new Error('You must include data.'));
        }

        if (!address || typeof address !== 'string') {
          return (cb || Function)(new Error('You must include mailing list address.'));
        }

        return put('/lists/' + address, data, cb);
      },

      /**
       * Deletes a mailing list.
       * @param address {String} mailing list address
       * @param cb {Function} callback function accepting error, response and body
       * @type {Function}
       */
      del: function (address, cb) {
        if (!address || typeof address !== 'string') {
          return (cb || Function)(new Error('You must include mailing list address.'));
        }

        return del('/lists/' + address, cb);
      },

      /**
       * Fetches mailing list stats.
       * @param address {String} mailing list address
       * @param cb {Function} callback function accepting error, response and body
       * @type {Function}
       */
      stats: function (address, cb) {
        if (!address || typeof address !== 'string') {
          return (cb || Function)(new Error('You must include mailing list address.'));
        }

        return get('/lists/' + address + '/stats', cb);
      },

      members: {
        /**
         * Fetches the list of mailing list members.
         * @param listAddress {String} mailing list address
         * @param data {Object} the optional object containing the GET options 'subscribed', 'limit' and 'skip'
         * @param cb {Function} callback function accepting error, response and body
         * @type {Function}
         */
        list: function (listAddress, data, cb) {
          if (!listAddress || typeof listAddress !== 'string') {
            var last = arguments.length - 1;
            var callback = (arguments[last] && (typeof arguments[last] === 'function')) ? arguments[last] : Function;
            return callback(new Error('You must include mailing list address.'));
          }

          return get('/lists/' + listAddress + '/members', data, cb);
        },

        /**
         * Retrieves a mailing list member.
         * @param listAddress {String} mailing list address
         * @param memberAddress {String} member address
         * @param cb {Function} callback function accepting error, response and body
         * @type {Function}
         */
        get: function (listAddress, memberAddress, cb) {
          var last = arguments.length - 1;
          var callback = (arguments[last] && (typeof arguments[last] === 'function')) ? arguments[last] : Function;
          if (!listAddress || typeof listAddress !== 'string') {
            return callback(new Error('You must include mailing list address.'));
          }

          if (!memberAddress || typeof memberAddress !== 'string') {
            return callback(new Error('You must include member address.'));
          }

          return get('/lists/' + listAddress + '/members/' + memberAddress, cb);
        },

        /**
         * Adds a member to the mailing list.
         * @param listAddress {String} mailing list address
         * @param data {Object} the object containing the address, name, vars, subscribed and upsert
         * @param cb {Function} callback function accepting error, response and body
         * @type {Function}
         */
        create: function (listAddress, data, cb) {
          var last = arguments.length - 1;
          var callback = (arguments[last] && (typeof arguments[last] === 'function')) ? arguments[last] : Function;
          if (!data || (typeof data !== 'object')) {
            return callback(new Error('You must include data.'));
          }

          if (!listAddress || typeof listAddress !== 'string') {
            return callback(new Error('You must include mailing list address.'));
          }

          if (!data.address || typeof data.address !== 'string') {
            return callback(new Error('You must include member address.'));
          }

          var params = {};
          // prepare vars, has to be valid JSON
          if (data.vars && typeof data.vars === 'object') {
            for (var key in data) {
              params[key] = data[key];
            }
            params.vars = JSON.stringify(params.vars);
          }
          else {
            params = data;
          }

          return post('/lists/' + listAddress + '/members', params, cb);
        },

        /**
         * Updates a mailing list member with given properties. Won't touch the property if it's not passed in.
         * @param listAddress {String} mailing list address
         * @param memberAddress {String} member address
         * @param data {Object} the object containing the address, name, vars, subscribed
         * @param cb {Function} callback function accepting error, response and body
         * @type {Function}
         */
        update: function (listAddress, memberAddress, data, cb) {
          var last = arguments.length - 1;
          var callback = (arguments[last] && (typeof arguments[last] === 'function')) ? arguments[last] : Function;

          if (!listAddress || typeof listAddress !== 'string') {
            return callback(new Error('You must include mailing list address.'));
          }

          if (!memberAddress || typeof memberAddress !== 'string') {
            return callback(new Error('You must include member address.'));
          }

          if (!data || (typeof data !== 'object')) {
            return callback(new Error('You must include data to update.'));
          }

          var params = {};
          // prepare vars, has to be valid JSON
          if (data.vars && typeof data.vars === 'object') {
            for (var key in data) {
              params[key] = data[key];
            }
            params.vars = JSON.stringify(params.vars);
          }
          else {
            params = data;
          }

          return put('/lists/' + listAddress + '/members/' + memberAddress, params, cb);
        },

        /**
         * Delete a mailing list member.
         * @param listAddress {String} mailing list address
         * @param memberAddress {String} member address
         * @param cb {Function} callback function accepting error, response and body
         * @type {Function}
         */
        del: function (listAddress, memberAddress, cb) {
          var last = arguments.length - 1;
          var callback = (arguments[last] && (typeof arguments[last] === 'function')) ? arguments[last] : Function;
          if (!listAddress || typeof listAddress !== 'string') {
            return callback(new Error('You must include mailing list address.'));
          }

          if (!memberAddress || typeof memberAddress !== 'string') {
            return callback(new Error('You must include member address.'));
          }

          return del('/lists/' + listAddress + '/members/' + memberAddress, cb);
        }
      }
    }
  };
};