text:
<!DOCTYPE html>

<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Writing Custom Alfred Worklows | blog.kilian.io</title>
<link rel="stylesheet" href="https://blog.kilian.io//css/style.css">
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">

<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.9.0/styles/github.min.css">

blog.kilian.io

October 23, 2016

Writing Custom Alfred Worklows

A friend of mine has recently started automating some of his tasks using Alfred workflows, a feature of Alfred I’ve been using for years, but have never really thought about using for my own stuff before.

Although they can sometimes come across rather gimicky, Alfred workflows are actually quite powerful. There’s a huge amount of possibilities built right in, but in this post I really only want to focus on a short introduction to so called script filters.

Please be aware that workflows are a paid powerpack feature of Alfred. I can definitely recommend the upgrade though!

What’s a Script Filter?

On creating a new blank workflow you’re presented with an empty page. Here you can add a bunch of stuff, but the most straight-forward thing (in my opinion at least) is a script filter.

Script filters are input actions, meaning they can be run on certain keywords and with certain arguments. The argument can then be passed on to a given script (hence the name), which does some 🎩🐰✨ and returns some items for Alfred to display.

Alfred has a list of supported default “languages”, including bash or zsh, php, ruby, python, perl and applescript. Or you can just choose “External script” and go with whatever you want.

Caveat: If you’re looking to distribute your workflow to others, it might make sense to go with something that they can run natively without having to install additional dependencies. My first workflow was written in Node.js, which unfortunately doesn’t come preinstalled on macOS. And then one of the users had an older version running into all kinds of additional errors. On the other hand, if you’re writing a wrapper for npm tooling, node will probably be on your user’s machines and the language is their tool of choice anyways. It’s always a question of your target audience.

What’s also noteworthy here is the “Run Behaviour”. Alfred defaults to running one instance of your script after each other. That means that if an instance is already running (maybe being rather slow due to a network call or something else), any further user input will only be processed after the first script has finished and a new instance can be started.
My experience has been that this can easily be changed to terminate the previous instance if the users adds additional input for most cases, making things a lot snappier.

Getting Started with a Script Filter

A user’s input is handed over to your script as argv by default, making it trivial to access this with your language of choosing.

To show a list of items in Alfred once you’re done you have to do nothing more than output some JSON (or XML) to STDOUT.
Alfred has pretty good documentation on how your outputted data has to be formatted for Alfred to pick it up.

The basic idea is having a list of items with their respective fields. Most of them are pretty self-explanatory or well explained in the docs linked above.

{"items": [
    {
        "title": "An item",
        "subtitle": "Some description ",
        "arg": "an argument",
        "icon": {
            "path": "link to an image"
        }
    },
    //...
]}

Setting an argument is especially helpful for other actions, as this is what is passed on to them. You can also specify different arguments for modifier keys, so a different actions will be passed on if the user holds ⌘ for example.

Alfred also does a lot for you out-of-the-box if you want to list files from your harddrive.

Using a Helper Library

You’ll make your life a lot easier using one of the plentiful alfred-workflow helper libraries out there, surely also for your language of choice.

Two I’d like to highlight are Alfy by Sindre Sorhus (Javascript) and goalfred by Benjamin Herzog (golang).
Both have a fantastic API making your life a lot easier by just passing along the items and setting appropriate attributes.

Something specific to goalfred are the so called complex arguments. It turns out to be rather tricky if you want to pass along specific variables to further actions. Ben and I figured that out together as I was trying to build a workflow showing departures in our local public transport network (DVB in Dresden, Germany).

When hitting enter on an item I wanted to schedule a notification to be displayed several minutes before the departure. My first implementation included a small Swift app using system APIs to schedule that as it turns out you can’t schedule future notifications via applescript 😕
We later figured out how to implement the same functionality directly within the workflow getting rid of the rather cumbersome and awkward first implementation. Ben went ahead and built that directly into goalfred 🙂 A big recommendation goes out to that library.

Using that we can easily throw together a small (albeit useless) workflow script in go greeting the name the user enters or no one if no input is given.

package main

import (
    "fmt"

    "github.com/BenchR267/goalfred"
)

func main() {
    // Deals with the normalizing issue below.
    query, _ := goalfred.NormalizedArguments()

    defer goalfred.Print()

    if query[0] == "" {
        goalfred.Add(goalfred.Item{
            Title: "Hello world!",
        })
    } else {
        goalfred.Add(goalfred.Item{
            Title: fmt.Sprintf("Hello, %s 👋", query[0]),
        })
    }
}

I would usually compile this running go build <file>.go and setting Alfred to run the binary as an external script, but you can also use a bash script filter to have Alfred run go run <file>.go or the binary, whatever you prefer.

Problems

A pain point specific to non-ascii-compatible languages is Alfred’s handling of special characters. It uses NSTask internally, which results in umlauts for example being split up into their parts before being passed on, meaning ü becomes ¨u. Here’s some more info on that if you’re interested and some help on how to re-normalize the user’s input.

Something essential I haven’t found a good solution for are workflow updates. Some people publish their workflows using Packal, which provides some help with that. There’s also a python lib with some magic.
The best solution I’ve seen this far is how Alfy recommends publishing workflows on npm and linking them to the correct directory on a post-install step. Still not perfect, but definitely interesting.

If you want to check out the source to some workflows, I’ve published three of mine on GitHub: alfred dvb, alfred mensa and alfred n26.

Got any additional input or cool workflow ideas? Hit me up on Twitter 🙃


text:
copyright:
  years: 2015, 2017

lastupdated: "2017-02-01"

---

{:shortdesc: .shortdesc}
{:new_window: target="_blank"}
{:codeblock: .codeblock}
{:screen: .screen}

# Ejemplo: Envío de secuencia de registros de aplicaciones de Cloud Foundry a Splunk
{: #splunk}

En este ejemplo, Jane, una desarrolladora, creará un servidor virtual utilizando IBM Virtual Servers Beta y una imagen Ubuntu.  Jane intenta enviar una secuencia de registros de app de Cloud Foundry desde {{site.data.keyword.Bluemix_notm}} a Splunk.
{:shortdesc}

  1. Lo primero que hace Jane es configurar Splunk.

     a. Jane descarga Splunk Light desde el [sitio de descarga de Splunk Light ![Icono de enlace externo](../icons/launch-glyph.svg "Icono de enlace externo")](https://www.splunk.com/en_us/download/splunk-light.html){:new_window} y, a continuación, lo instala con el siguiente mandato. El software se instala en */opt/splunk*.

	    ```
        dpkg -i  ~/splunklight-6.3.0-aa7d4b1ccb80-linux-2.6-amd64.deb
        ```

     b. Jane instala y aplica los parches al complemento de tecnología syslog de RFC5424 para realizar la integración con {{site.data.keyword.Bluemix_notm}}. Para obtener más información sobre cómo instalar el complemento, consulte [las directrices de Cloud Foundry ![Icono de enlace externo](../icons/launch-glyph.svg "Icono de enlace externo")](https://docs.cloudfoundry.org/devguide/services/integrate-splunk.html){:new_window}.

	    Jane instala el complemento con los mandatos siguientes:

	    ```
        cd /opt/splunk/etc/apps
        tar xvfz ~/rfc5424-syslog_11.tgz
        ```

        A continuación, aplica los parches al complemento, sustituyendo */opt/splunk/etc/apps/rfc5424/default/transforms.conf* con el nuevo archivo *transforms.conf* que contiene el siguiente texto:

	    ```
        [rfc5424_host]
        DEST_KEY = MetaData:Host
        REGEX = <\d+>\d{1}\s{1}\S+\s{1}(\S+)
        FORMAT = host::$1

        [rfc5424_header]
        REGEX = <(\d+)>\d{1}\s{1}\S+\s{1}\S+\s{1}(\S+)\s{1}(\S+)\s{1}(\S+)
        FORMAT = prival::$1 appname::$2 procid::$3 msgid::$4
        MV_ADD = true
        ```
        {:screen}

     Una vez que Splunk está configurado, Jane debe abrir algunos puertos en la máquina Ubuntu para que acepte la obtención de los syslog entrantes (puerto 5140) y la interfaz de usuario web de Splunk (puerto 8000) porque de forma predeterminada el cortafuegos del servidor virtual de {{site.data.keyword.Bluemix_notm}} está activado.

	    **Nota:** La configuración de iptable se realiza aquí a efectos de la evaluación que Jane está realizando y es temporal. Para configurar los parámetros del cortafuegos en el servidor virtual Bluemix en producción, consulte la documentación de [Grupos de seguridad de red ![Icono de enlace externo](../icons/launch-glyph.svg "Icono de enlace externo")](https://new-console.ng.bluemix.net/docs/services/networksecuritygroups/index.html){:new_window} para obtener información más detallada.

	   ```
	   iptables -A INPUT -p tcp --dport 5140 -j ACCEPT
       iptables -A INPUT -p tcp --sport 5140 -j ACCEPT
       iptables -A INPUT -p tcp --dport 8000 -j ACCEPT
       iptables -A INPUT -p tcp --sport 8000 -j ACCEPT
	   ```
	   {:screen}

	   A continuación, Jane ejecuta Splunk utilizando el siguiente mandato:

       ```
	   /opt/splunk/bin/splunk start --accept-license
       ```

  2. Jane configura los valores de Splunk para aceptar la obtención de syslog desde {{site.data.keyword.Bluemix_notm}}. Debe crear una entrada de datos para la obtención de syslog.

     a. Desde la interfaz web de Splunk, Jane pulsa **Datos > Entrada de datos**. Se visualizará una lista de tipos de entrada a los que Splunk da soporte.

     b. Selecciona **TCP**, porque la obtención de syslog utiliza el protocolo TCP.

     c. En el panel de **TCP**, Jane especifica **5140** en el campo **Puerto**, deja los campos restantes en blanco y, a continuación, pulsa **Siguiente**.

     d. Desde la lista de **Tipo de origen**, selecciona **No categorizado > rfc5424_syslog**.

     e. Para el tipo de **Método**, selecciona **IP**.

     f. En el campo **Índice**, pulsa **Crear un nuevo índice**. Le otorga el nombre "bluemix" al nuevo índice y, a continuación, pulsa **Guardar**.

     g. Por último, en la ventana **Revisar**, confirma que los valores son correctos y pulsa **Enviar** para habilitar esta entrada de datos.

  3. En {{site.data.keyword.Bluemix_notm}}, Jane crea un servicio de obtención de syslog y vincula el servicio a una app.

     a. Jane crea un servicio de obtención de syslog utilizando el siguiente mandato desde la interfaz de línea de mandatos de cf:

     ```
     cf cups splunk -l syslog://dummyhost:5140
     ```

     **Nota:** *dummyhost* no es el nombre real. Se utiliza para ocultar el nombre de host real.

     b. Jane vincula el servicio de obtención de syslog a una app en su espacio y, a continuación, reconstruye la app.

	 ```
     cf bind-service myapp splunk
     cf restage myapp
     ```

Jane prueba su app y, a continuación, escribe la siguiente serie de consulta en la interfaz web de Splunk:

```
source="tcp:5140" index="bluemix" sourcetype="rfc5424_syslog"
```

Jane verá una secuencia de registros en su interfaz web de Splunk. A pesar de que la versión de Splunk que Jane instala es Splunk Light, todavía podrá retener hasta 500MB de registros al día.

redpajama_set_name: RedPajamaGithub


text:
using Microsoft.Xna.Framework.Input;
using System.ComponentModel;
using Gem.Infrastructure.Attributes;
using Microsoft.Xna.Framework;

namespace Gem.Gui.Input
{
    public class GamePadInputButtons
    {
        public GamePadInputButtons()
        {
            this.AssignDefaultValues();
        }

        [DefaultValue(Buttons.DPadRight)]
        public Buttons Right { get; set; }

        [DefaultValue(Buttons.DPadLeft)]
        public Buttons Left { get; set; }

        [DefaultValue(Buttons.DPadDown)]
        public Buttons Next { get; set; }

        [DefaultValue(Buttons.DPadUp)]
        public Buttons Previous { get; set; }

        [DefaultValue(Buttons.A)]
        public Buttons Trigger { get; set; }

        [DefaultValue(PlayerIndex.One)]
        public PlayerIndex PlayerIndex { get; set; }
    }

}


text:
package spet.sbwo.data.table;

import spet.sbwo.data.base.BaseEntity;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Table;

@Entity
@Table(name = "T_COURT")
public class Court extends BaseEntity {
    @Column(name = "C_NAME")
    private String name;

    @Column(name = "C_CODE")
    private String code;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    @Override
    public String toString() {
        return "Court [id=" + id + ", name=" + name + ", code=" + code + "]";
    }

}


text:
using Microsoft.Internal;

namespace System.Composition
{
    internal static class ExceptionBuilder
    {
        public static ArgumentException Argument_ExpressionMustBeNew(string parameterName)
        {
            return CreateArgumentException(SR.Argument_ExpressionMustBeNew, parameterName);
        }

        public static ArgumentException Argument_ExpressionMustBePropertyMember(string parameterName)
        {
            return CreateArgumentException(SR.Argument_ExpressionMustBePropertyMember, parameterName);
        }

        public static ArgumentException Argument_ExpressionMustBeVoidMethodWithNoArguments(string methodName)
        {
            return CreateArgumentException(SR.Argument_ExpressionMustBeVoidMethodWithNoArguments, methodName);
        }

        private static ArgumentException CreateArgumentException(string message, string parameterName)
        {
            Assumes.NotNull(parameterName);

            return new ArgumentException(SR.Format(message, parameterName), parameterName);
        }
    }
}


text:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.kevinsprong</groupId>
  <artifactId>gamesolver</artifactId>
  <packaging>pom</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>gamesolver</name>
  <url>kevinsprong.com</url>
  <modules>
    <module>TwoPlayerGame</module>
    <module>AlphaBetaSolver</module>
    <module>TwoZeroFourEight</module>
    <module>Driver2048</module>
    <module>Threes</module>
    <module>DriverThrees</module>
  </modules>
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.1</version>
        <configuration>
          <source>1.7</source>
          <target>1.7</target>
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>


text:
#pragma once

#include <sys/types.h>

/*
 * A set of routines to assist with walking a Flattened Device Tree in memory
 * for interesting nodes. Uses libfdt internally.
 */

struct fdt_walk_callbacks {
    void (*mem)(uint64_t base, uint64_t len, void *cookie);
    void *memcookie;
    void (*cpu)(uint64_t id, void *cookie);
    void *cpucookie;
};

status_t fdt_walk(const void *fdt, const struct fdt_walk_callbacks *);


text:
#ifndef OPENTISSUE_DYNAMICS_MBD_COLLISION_DETECTION_MBD_EXHAUSTIVE_SEARCH_H
#define OPENTISSUE_DYNAMICS_MBD_COLLISION_DETECTION_MBD_EXHAUSTIVE_SEARCH_H
//
// OpenTissue Template Library
// - A generic toolbox for physics-based modeling and simulation.
// Copyright (C) 2008 Department of Computer Science, University of Copenhagen.
//
// OTTL is licensed under zlib: http://opensource.org/licenses/zlib-license.php
//
#include <OpenTissue/configuration.h>

#include <list>

namespace OpenTissue
{
  namespace mbd
  {

    /**
    * The Exhaustive Search Broad Phase Collision Detection Algorithm.
    *
    * The algorithm is intended to be used as a policy in the CollisionDetection class.
    */
    template<typename types>
    class ExhaustiveSearch
    {
    protected:

      //--- Convience Stuff for better readability
      typedef typename types::configuration_type configuration_type;
      typedef typename types::body_type body_type;
      typedef typename types::edge_type edge_type;
      typedef typename types::edge_ptr_container edge_ptr_container;
      typedef typename types::math_policy::real_type      real_type;
      typedef typename types::math_policy::vector3_type    vector3_type;
      typedef typename types::math_policy::matrix3x3_type  matrix3x3_type;

    protected:

      configuration_type * m_configuration;         ///< A pointer to the configuration that holds the configuration
      ///< that the broad phase collision detection algorithm is
      ///< intended to work on.
    public:

      class node_traits
      {
      public:
        vector3_type m_es_pmin;  ///< Minimum corner of enclosing AABB
        vector3_type m_es_pmax;  ///< Maximum corner of enclosing AABB
      };
      class edge_traits  {   };
      class constraint_traits { };

    public:

      ExhaustiveSearch()
        : m_configuration(0)
      {}

    public:

      void clear()
      {
        this->m_configuration = 0;
      }

      void init(configuration_type & configuration) {  m_configuration = &configuration;  };
      void add(body_type * /*body*/)  {  };
      void remove(body_type * /*body*/)  {    };

      /**
      * Run Exhaustive Search.
      *
      * @param edges   Upon return this argument holds all the reported overlaps.
      */
      void run(edge_ptr_container & edges)
      {
        edges.clear();
        assert(m_configuration);
        typename configuration_type::body_iterator body1,body2,tmp;
        typename configuration_type::body_iterator begin = m_configuration->body_begin();
        typename configuration_type::body_iterator end = m_configuration->body_end();
        real_type envelope = m_configuration->get_collision_envelope();
        //--- Update AABB's of all bodies
        for(body1 = begin; body1!=end; ++body1)
        {
          vector3_type r;
          matrix3x3_type R;
          body1->get_position(r);
          body1->get_orientation(R);
          body1->compute_collision_aabb(r,R,body1->m_es_pmin,body1->m_es_pmax,envelope);
        }
        //--- Test AABB's of each body pair against each other for collision
        for(body1 = begin; body1!=end; ++body1)
        {
          tmp = body1; ++tmp;
          for(body2 = tmp; body2!=end; ++body2)
          {
            if(!body1->has_joint_to(  &(*body2) ))
            {
              if(body1->m_es_pmin(0)> body2->m_es_pmax(0) || body2->m_es_pmin(0)>body1->m_es_pmax(0))
                continue;
              if(body1->m_es_pmin(1)> body2->m_es_pmax(1) || body2->m_es_pmin(1)>body1->m_es_pmax(1))
                continue;
              if(body1->m_es_pmin(2)> body2->m_es_pmax(2) || body2->m_es_pmin(2)>body1->m_es_pmax(2))
                continue;
            }
            //--- Colliding AABB's were detected, report edge as ovelapping
            edge_type * edge = m_configuration->get_edge(&(*body1),&(*body2));
            if(!edge)
              edge = m_configuration->add(&(*body1),&(*body2));
            edges.push_back( edge );
          }
        }
      };
    };/* End class ExhaustiveSearch */

  } // namespace mbd
} // namespace OpenTissue

// OPENTISSUE_DYNAMICS_MBD_COLLISION_DETECTION_MBD_EXHAUSTIVE_SEARCH_H
#endif


text:
require 'spec_helper'

describe DeliveriesController do
  before(:each) do
    activate_authlogic
    UserSession.create Factory(:admin_user)
  end

  it "should list deliveries only for soul food farm" do
    get :index, :farm_id => Factory(:farm)

    response.should be_success

    assigns(:deliveries).each do |p|
      p.farm.should == Factory(:farm)
    end

  end

  it "should redirect index if no farm id is given" do
    get :index

    response.should be_redirect

  end

  it "should create a delivery and pickups" do
    farm = Factory(:farm)

    location1 = Factory(:location, :farm => farm, :name => "Potrero", :location_tag => Factory(:location_tag, :name => "SF-Potrero"))
    location2 = Factory(:location, :farm => farm, :name => "Elsewhere", :location_tag => Factory(:location_tag, :name => "Elsewehere"))

    get :create, :location_ids => [location1.id,location2.id],
          :farm_id => farm.id,
          :delivery => {:farm_id => farm.id, :date => '2010-03-01'}

    assigns[:delivery].locations.first.should_not be_nil
    assigns[:delivery].locations.size.should == 2
  end

  it "should update delivery statuses on show" do
    farm = Factory(:farm)
    delivery = Factory(:delivery, :status => 'notyetopen',
                       :opening_at => Time.current - 10.minutes, :farm => farm,
                       :status_override => false)

    get :show, :id => delivery.id

    response.should be_success
    delivery.reload
    delivery.status.should == 'open'
  end

  it "should set status_override if status is manually changed" do
    farm = Factory(:farm)
    delivery = Factory(:delivery, :status => 'inprogress', :farm => farm, :status_override => false)

    get :update,  :id => delivery.id,
                  :farm_id => farm.id,
                  :delivery => {}

    response.should be_redirect
    delivery.reload
    delivery.status_override.should == false

    get :update,  :id => delivery.id,
                  :farm_id => farm.id,
                  :delivery => {:status => 'open'}

    delivery.reload
    delivery.status_override.should == true
  end

  it "should update finalized totals and set a flag on the delivery" do
    farm = Factory(:farm)
    delivery = Factory(:delivery, :status => 'inprogress', :farm => farm)
    delivery.orders << Factory.create(:order, :delivery => delivery)

    get :update_finalized_totals, :id => delivery.id,
                                  :farm_id => farm.id,
                                  :totals => "true",
                                  :delivery => {"orders_attributes"=>{"0"=>{"finalized_total"=>"86", "id"=>delivery.orders.first.id}}}

    delivery.reload
    delivery.finalized_totals.should == true
    delivery.orders.first.finalized_total.should == 86

  end

  it "should delete reminders when deleting a delivery" do

    farm = Factory(:farm, :reminders_enabled => true)
    delivery = Factory(:delivery, :status => 'open', :farm => farm)

    Factory.create(:email_template, :identifier => "order_reminder", :farm => farm)
    Factory.create(:email_template, :identifier => "order_reminder_last_call", :farm => farm)

    reminder_manager = ReminderManager.new
    reminder_manager.schedule_reminders_for_delivery(delivery)

    reminders = DeliveryOrderReminder.find_all_by_delivery_id(delivery.id)
    reminders.size.should == 2

    get :destroy, :id => delivery.id, :farm_id => farm.id

    reminders = DeliveryOrderReminder.find_all_by_delivery_id(delivery.id)
    reminders.size.should == 0

  end

end


text:
Sorry for the slow reports lately.  Last week was Dockercon and many people inside Docker and external contributors where in Austin for the week.  It was a long week and we didn't get much work done on the project but it was good meeting everyone IRL and putting a face to the github handle.  Also, thank you to everyone that stayed a day late to attend the summit on Thursday.  You can see the summit notes at the bottom of this report.

## New Projects to the Org.

We are looking to move some of our dependencies used by containerd into the org.  We want to have a simple maintainer model for containerd and any other repository that is added to the org.  Bascially, if you are a maintainer of containerd, you are a maintainer on all of the repos.  We don't want to have separate maintainers for the various parts as we should all share the responsibility for quality and stability for the project as a whole.

We have an issue on github discussing the various projects that we want to add.  If you have any feedback please let us know on the issue below.

[projects!](https://github.com/containerd/containerd/issues/772)
[process](https://github.com/containerd/containerd/pull/779)

## Darwin/BSD Port

Justin has begun work on porting over containerd to Darwin and BSD.  `ctr` compiles and there were a few changes in terminal handling that had to be made but overall its going fairly smooth.  You can ping @justincormack for more information or if you are interested in working on something like a BSD jails port of `runc`.

## Introspection

@AkihiroSuda has been working on introspection RPCs to make sure consumers know the services and features that they are interacting with.  There is still a lot to consider when exposing service versions, containerd versions and functionality; if you have any input you can take a look at the current PR [here](https://github.com/containerd/containerd/pull/776).

## Expanded Registry Support

@dmcgowan has been working on expanding registry support with authentication in [783](https://github.com/containerd/containerd/pull/783).  This expands registry support for gcr.io, Dockerhub, and local registries.

## Task List for week of May 1

So, now that we are all back from Dockercon and not rested at all, whats on the agenda for next week?

* Docker Integration Pass
	- Replace the current v0.2.x branch of containerd in Docker for execution with the 1.0 execution service
* Converge Event Handling
* Move new projects into containerd organization
* New Layer creation for supporting build
* Continue work on metadata service
	- container
	- layer
	- image
	- namespace support

If are you looking for areas to contribute to containerd just take a pass through the issue tracker.  There are issues such as [770](https://github.com/containerd/containerd/issues/770) that could use some help in solving as well as other.  Also feel free to stop by the slack channel for containerd to chat and find ideas on what needs to be developed next.

## containerd Summit Notes

Here are the notes from the containerd summit that was held after Dockercon.  If there are important to you and you would like to start working on a feature, fix, request, please go ahead and open an issue on github.  Just remember, we shouldn't have to have a summit to get things into containerd.  Open issues, disscuss with other members of the community and write the code ;)

* "Since containerd is one of the bottom bricks in the stack, how can we setup automated integration tests for consumers of containerd?"
	- Looking for others to provide compute (testing within Docker, K8s, Microsoft)
	- Would we publish results of integration tests, not likely per PR
	- K8s had a similar problem, solved by pushing builds to buckets and creating dashboards from results pushed back to buckets
	- Need tests for projects containerd is integrated with (Windows, runv), testing containerd connection to shims
* "We'd like to propose an Authorization plugin to containerd that would allow an external component to police events like container start & stop (and have a discussion about the best way to go about it)"
	- Need to look into how it could be implemented with containerd
	- Possible to be done by MITM the GRPC socket
	- Currently seen as out of scope for server, can be done via client (or proxy), we could build a client package to support this so it does not have to be implemented by each integrator.
	- Currently only unix socket allowed which prevents unauthorized access
* "Should containerd provide image filesystem metrics? If yes, what metrics should be included? How to implement that?"
	- Previously discussed, yes, PR to provide this information through the snapshot interface.
	- Figuring out what is being shared, could figure out it from mapping layers to images
* "Support for disk quotas: How? What is the role of containerd? How is it going to be integrated with volume managers that want to be in the same quota group?"
	- Expanding question, "will each snapshot driver have a quota system? What is the granularity, per container, global?"
	- Stephen's hope is that quota management can be done based on the returned mounts, otherwise need to figure out quota abstraction
	- Could we rely on work being done for volumes with CSI
	- Need to open up issue to discuss project quotas and general snapshot quotas
* "Checkpoint/Restore: how can we support more use cases? One of the big issues here is the large number of options that can be passed to CRIU."
	- Not currently in Containerd, requires runc update as well
	- Need to figure out a way to pass in options opaquely
	- Needs to be discuss with Michael for what best solution for runc will be
	- Today caller must know runtime since runtime spec is passed opaquely on create to runtime
* "How to support multi-OS docker images, for example, Linux Vs Windows using one graph driver plugin properly?"
	- From looking into implementing linux containers on HyperV
	- Missing options when creating rootfs to specify the snapshot driver
	- Containerd will support running multiple snapshotter
	- Timeline, Docker will first use update runtime after stabilizing
* "Containerd is acting as init system in LinuxKit, is there a plan to support what init systems support"
-	 Containerd was not implemented as an init system, we are not trying to compete with it. A higher level init system could be implemented with it.
* "Will containerd be able to leverage runtime plugins specified within Docker?"
	- Docker would have to orchestrate re-configuring containerd with the new runtime
	- Currently cannot hotswap plugins, runtime and shim are built in
	- Would require defining plugin interface or getting go 1.8 plugins working
	- We could have a plugin which connects to a grpc address
	- Resolved in rocket by first allowing downloading a runtime and running it as privileged
	- Need to open up an issue to discuss this
* "What do we want from orchestrator who are looking at integration?"
	- Feedback is biggest
	- Currently targeting K8s and SwarmKit to keep API grounded
	- Starting PoCs now, we have already made changes based on early feedback


text:
using Glav.CognitiveServices.FluentApi.Core.Contracts;

namespace Glav.CognitiveServices.FluentApi.TextAnalytic.Domain.ApiResponses
{
    public sealed class LanguagesResultResponseRoot : BaseResponse<LanguagesResultResponseItem>, IActionResponseRoot
    {

    }
}


text:
 Hello, {{displayname}}!

        $<input type="text" class="dollar" ng-model='cost' required></input>

          {{user.name.first}}
          {{user.name.last}}

              <i class="fa fa-beer fa-lg" ng-class="{'red': (user.tab<0), 'green': (user.tab>0)}">

            <button class="pay-btn" ng-hide="user.tab <= 0" ng-click="sendBeer(user.username, getSelectedDrink(), cost)">Got {{ getSelectedDrink() }}</button>
            <button class="pay-btn" ng-hide="user.tab > 0" ng-click="sendBeer(user.username, getSelectedDrink(), cost)">Send {{ getSelectedDrink() }}</button>

  <dropdown placeholder="Colour..." list="colours" selected="colour" property="name"></dropdown>
  <button class="add-friend-btn" ng-hide="clicked" ng-click="clicked = true; toUser = '';">Add New Friend</button>
    <form ng-submit="sendBeer(toUser)" name="send-beer" novalidate>

           <ui-select ng-model='result.selected' on-select='addUser(result.selected); toggle()'  theme="bootstrap" ng-disabled="false" reset-search-input="false" uiSelectConfig.appendToBody = true; style="width: 300px;">
              <ui-select-match id='ui-select-container' placeholder="I owe a beer to...">{{$select.selected.name}}</ui-select-match>
              <ui-select-choices repeat='user in results|limitTo:10' refresh='findUser($select.search)' refresh-delay='0'>

              </ui-select-choices>
            </ui=select>

<input type="submit" value="SEND {{ getSelectedDrink().toUpperCase() }}" class="btn btn2" ng-disabled="login.$invalid" disabled="disabled" ng-click="clicked = false;">

    </form>


text:
package net.geocentral.geometria.action;

import net.geocentral.geometria.model.GDocument;
import net.geocentral.geometria.model.GProblem;
import net.geocentral.geometria.util.GDictionary;

import org.apache.log4j.Logger;

public class GNewProblemAction implements GAction {

    private static Logger logger = Logger.getLogger("net.geocentral.geometria");

    public boolean execute(GDocumentHandler documentHandler,
            boolean quietMode) {
        logger.info(quietMode);
        if (!documentHandler.onCloseDocument())
            return false;
        documentHandler.clearUndoableActions();
        GDocument document = new GProblem();
        document.setPrime(true);
        documentHandler.setActiveDocument(document);
        documentHandler.setMasterSolution(null);
        documentHandler.documentChanged();
        documentHandler.setDocumentModified(false);
        documentHandler.setTitle(GDictionary.get("UntitledProblem"));
        logger.info("");
        return true;
    }
}


text:
package api

import (
	"errors"
	"github.com/mailrack/src/config"
	"github.com/mailrack/src/db"
	"log"
	"strings"
)

// Filter model
type Filter struct {
	Id      int    `json:"id,omitempty"`
	Name    string `json:"name"`
	Pattern string `json:"mask"`
	Color   string `json:"color"`
	Field   string `json:"field"`
	Unread  int    `json:"unread"`
}

const defaultName = "Inbox"

var fieldsMap = map[string]string{"0": "sender", "1": "receiver", "2": "subject"}

func (f *Filter) prepare() error {
	if len(f.Name) == 0 || len(f.Pattern) == 0 {
		return errors.New("Name and Pattern is required")
	}

	if f.Name == defaultName {
		return errors.New("Name `" + defaultName + "` is not allowed")
	}

	q := `SELECT EXISTS(SELECT 1 FROM filters WHERE name = ? COLLATE NOCASE LIMIT 1)`
	var recordExsist bool

	db.Client.QueryRow(q, f.Name).Scan(&recordExsist)

	if recordExsist {
		return errors.New("Name should be unique")
	}

	// map int index to .field string value
	field := fieldsMap[f.Field]

	if field == "" {
		f.Field = "sender"
	} else {
		f.Field = field
	}

	f.convertPattern()

	return nil
}

// All filters
func (f Filter) All() ([]interface{}, error) {
	// default - all messages
	defaultF := Filter{Name: defaultName, Pattern: "*"}
	q1 := `SELECT COUNT(*) AS count FROM messages WHERE viewed = 0`

	db.Client.QueryRow(q1).Scan(&defaultF.Unread)

	res := []interface{}{defaultF}
	rows, err := db.Client.Query("SELECT * FROM filters")

	if err != nil {
		return nil, err
	}

	defer rows.Close()

	ch := make(chan Filter)
	chSize := 0

	for rows.Next() {
		chSize++
		filter := Filter{}
		rows.Scan(&filter.Id, &filter.Name, &filter.Pattern, &filter.Color, &filter.Field)

		go func(filter Filter, ch chan Filter) {
			filter.Unread = MessagesCount(filter, true)
			ch <- filter
		}(filter, ch)
	}

	if chSize == 0 {
		close(ch)
		return res, nil
	}

	for tag := range ch {
		res = append(res, tag)
		chSize--

		if chSize == 0 {
			close(ch)
		}
	}

	return res, nil
}

// Save filter
func (f *Filter) Save() error {
	err := f.prepare()

	if err != nil {
		return err
	}

	q := `INSERT INTO filters (name, pattern, color, field) VALUES (?, ?, ?, ?)`
	_, err = db.Client.Exec(q, f.Name, f.Pattern, f.Color, f.Field)

	if err != nil {
		return err
	}

	return nil
}

// Test if any messages match search pattern
func (f *Filter) Test() (map[string]interface{}, error) {
	err := f.prepare()

	if err != nil {
		return nil, err
	}

	filter := *f

	return map[string]interface{}{
		"field":   f.Field,
		"pattern": f.Pattern,
		"count":   MessagesCount(filter, false),
	}, nil
}

// Find filter
func (f *Filter) Find() Filter {
	filter := Filter{}
	q := `SELECT name, pattern, color, field FROM filters WHERE id = ?`

	err := db.Client.QueryRow(q, f.Id).Scan(&filter.Name, &filter.Pattern, &filter.Color, &filter.Field)

	if err != nil {
		log.Fatalf("[ERROR][Filter.Find()] %s", err)
	}

	return filter
}

// Delete filter
// @param messages delete related messages
// @param self     actually delete Filter
func (f *Filter) Delete(messages, self bool) error {
	var err error

	if messages {
		var q1 string
		filter := f.Find()

		switch filter.Field {
		case "receiver":
			q1 = `SELECT message_id FROM receives WHERE to_addr LIKE ?`
		case "subject":
			q1 = `SELECT id FROM messages WHERE subject LIKE ?`
		default: // sender
			q1 = `SELECT id FROM messages WHERE from_addr LIKE ?`
		}

		rows, err := db.Client.Query(q1, filter.Pattern)

		if err != nil {
			log.Fatalf("%s", err)
		}

		defer rows.Close()

		var messageIds []string

		for rows.Next() {
			var messageId string
			rows.Scan(&messageId)
			messageIds = append(messageIds, messageId)
		}

		if rows.Err() != nil {
			log.Fatalf("%s", rows.Err())
		}

		inCondition := "(" + strings.Join(messageIds, ",") + ")"

		_, err = db.Client.Exec("DELETE FROM receives WHERE message_id IN " + inCondition)

		if err != nil {
			log.Fatalf("%s", err)
		}

		_, err = db.Client.Exec("DELETE FROM messages WHERE id IN " + inCondition)

		if err != nil {
			log.Fatalf("%s", err)
		}
	}

	if self {
		q2 := `DELETE FROM filters WHERE id = ?`
		_, err = db.Client.Exec(q2, f.Id)

		if err != nil {
			return err
		}
	}

	return nil
}

// FilterBy find which field use to search
func (f *Filter) FilterBy() string {
	switch f.Field {
	case "receiver":
		return "messages.id IN(SELECT message_id FROM receives WHERE to_addr LIKE ?)"
	case "subject":
		return "messages.subject LIKE ?"
	default: // sender
		return "messages.from_addr LIKE ?"
	}
}

// convertPattern remove spaces and replace * => %, ? => _ for LIKE condition
func (f *Filter) convertPattern() {
	p := strings.Replace(f.Pattern, " ", "", -1)
	p = strings.Replace(p, "*", "%", -1)
	p = strings.Replace(p, "?", "_", -1)
	f.Pattern = p
}

// MessagesCount count messages which match pattern
func MessagesCount(Filter Filter, onlyNew bool) int {
	var count int
	var q string

	q1 := "SELECT COUNT(*) AS count FROM messages WHERE"
	q2 := Filter.FilterBy()

	if onlyNew {
		q = q1 + " viewed = 0 AND " + q2
	} else {
		q = q1 + " " + q2
	}

	if config.GetBool("debug") {
		log.Printf("[SQLite]\n %s\n %q", q, Filter.Pattern)
	}

	err := db.Client.QueryRow(q, Filter.Pattern).Scan(&count)

	if err != nil {
		log.Fatalf("[ERROR][Filter.messagesCount()] %s", err)
		return 0
	}

	return count
}


text:
package io.quarkus.spring.web.test;

import static io.restassured.RestAssured.given;
import static io.restassured.RestAssured.when;
import static org.hamcrest.Matchers.is;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

import io.quarkus.test.QuarkusUnitTest;

public class BasicMappingTest {

    @RegisterExtension
    static QuarkusUnitTest runner = new QuarkusUnitTest()
            .withApplicationRoot((jar) -> jar
                    .addClasses(SomeClass.class, Greeting.class, TestController.class, ResponseEntityController.class,
                            ResponseStatusController.class, GreetingControllerWithNoRequestMapping.class));

    @Test
    public void verifyGetWithQueryParam() {
        when().get(TestController.CONTROLLER_PATH + "/hello?name=people")
                .then()
                .statusCode(200)
                .contentType("text/plain")
                .body(is("hello people"));
    }

    @Test
    public void verifyRequestMappingWithNoMethod() {
        when().get(TestController.CONTROLLER_PATH + "/hello4?name=people")
                .then()
                .statusCode(200)
                .contentType("text/plain")
                .body(is("hello people"));
    }

    @Test
    public void verifyGetToMethodWithoutForwardSlash() {
        when().get(TestController.CONTROLLER_PATH + "/yolo")
                .then()
                .statusCode(200)
                .body(is("yolo"));
    }

    @Test
    public void verifyGetUsingDefaultValue() {
        when().get(TestController.CONTROLLER_PATH + "/hello2")
                .then()
                .statusCode(200)
                .body(is("hello world"));
    }

    @Test
    public void verifyGetUsingNonLatinChars() {
        when().get(TestController.CONTROLLER_PATH + "/hello3?name=Γιώργος")
                .then()
                .statusCode(200)
                .body(is("hello Γιώργος"));
    }

    @Test
    public void verifyPathWithWildcard() {
        when().get(TestController.CONTROLLER_PATH + "/wildcard/whatever/world")
                .then()
                .statusCode(200)
                .body(is("world"));
    }

    @Test
    public void verifyPathWithMultipleWildcards() {
        when().get(TestController.CONTROLLER_PATH + "/wildcard2/something/folks/somethingelse")
                .then()
                .statusCode(200)
                .body(is("folks"));
    }

    @Test
    public void verifyPathWithAntStyleWildCard() {
        when().get(TestController.CONTROLLER_PATH + "/antwildcard/whatever/we/want")
                .then()
                .statusCode(200)
                .body(is("ant"));
    }

    @Test
    public void verifyPathWithCharacterWildCard() {
        for (char c : new char[] { 't', 'r' }) {
            when().get(TestController.CONTROLLER_PATH + String.format("/ca%cs", c))
                    .then()
                    .statusCode(200)
                    .body(is("single"));
        }
    }

    @Test
    public void verifyPathWithMultipleCharacterWildCards() {
        for (String path : new String[] { "/cars/shop/info", "/cart/show/info" }) {
            when().get(TestController.CONTROLLER_PATH + path)
                    .then()
                    .statusCode(200)
                    .body(is("multiple"));
        }
    }

    @Test
    public void verifyPathVariableTypeConversion() {
        when().get(TestController.CONTROLLER_PATH + "/int/9")
                .then()
                .statusCode(200)
                .body(is("10"));
    }

    @Test
    public void verifyJsonGetWithPathParamAndGettingMapping() {
        when().get(TestController.CONTROLLER_PATH + "/json/dummy")
                .then()
                .statusCode(200)
                .contentType("application/json")
                .body("message", is("dummy"));
    }

    @Test
    public void verifyJsonOnRequestMappingGetWithPathParamAndRequestMapping() {
        when().get(TestController.CONTROLLER_PATH + "/json2/dummy")
                .then()
                .statusCode(200)
                .contentType("application/json")
                .body("message", is("dummy"));
    }

    @Test
    public void verifyJsonPostWithPostMapping() {
        given().body("{\"message\": \"hi\"}")
                .contentType("application/json")
                .when().post(TestController.CONTROLLER_PATH + "/json")
                .then()
                .statusCode(200)
                .contentType("text/plain")
                .body(is("hi"));
    }

    @Test
    public void verifyJsonPostWithRequestMapping() {
        given().body("{\"message\": \"hi\"}")
                .contentType("application/json")
                .when().post(TestController.CONTROLLER_PATH + "/json2")
                .then()
                .statusCode(200)
                .contentType("text/plain")
                .body(is("hi"));
    }

    @Test
    public void verifyMultipleInputAndJsonResponse() {
        given().body("{\"message\": \"hi\"}")
                .contentType("application/json")
                .when().put(TestController.CONTROLLER_PATH + "/json3?suffix=!")
                .then()
                .statusCode(200)
                .contentType("application/json")
                .body("message", is("hi!"));
    }

    @Test
    public void verifyEmptyContentResponseEntity() {
        when().get(ResponseEntityController.CONTROLLER_PATH + "/noContent")
                .then()
                .statusCode(204);
    }

    @Test
    public void verifyStringContentResponseEntity() {
        when().get(ResponseEntityController.CONTROLLER_PATH + "/string")
                .then()
                .statusCode(200)
                .contentType("text/plain")
                .body(is("hello world"));
    }

    @Test
    public void verifyJsonContentResponseEntity() {
        when().get(ResponseEntityController.CONTROLLER_PATH + "/json")
                .then()
                .statusCode(200)
                .contentType("application/json")
                .body("message", is("dummy"))
                .header("custom-header", "somevalue");
    }

    @Test
    public void verifyJsonContentResponseEntityWithoutType() {
        when().get(ResponseEntityController.CONTROLLER_PATH + "/json2")
                .then()
                .statusCode(200)
                .contentType("application/json")
                .body("message", is("dummy"));
    }

    @Test
    public void verifyJsonContentResponseEntityWithCustomJsonHeader() {
        when().get(ResponseEntityController.CONTROLLER_PATH + "/custom-json")
                .then()
                .statusCode(200)
                .contentType("application/jsontest")
                .header("custom-header", "somevalue");
    }

    @Test
    public void verifyJsonContentResponseEntityWithContentType() {
        when().get(ResponseEntityController.CONTROLLER_PATH + "/content-type")
                .then()
                .statusCode(200)
                .contentType("application/jsontest")
                .header("custom-header", "somevalue");
    }

    @Test
    public void verifyEmptyContentResponseStatus() {
        when().get(ResponseStatusController.CONTROLLER_PATH + "/noContent")
                .then()
                .statusCode(200);
    }

    @Test
    public void verifyStringResponseStatus() {
        when().get(ResponseStatusController.CONTROLLER_PATH + "/string")
                .then()
                .statusCode(202)
                .contentType("text/plain")
                .body(is("accepted"));
    }

    @Test
    public void verifyControllerWithoutRequestMapping() {
        when().get("/hello")
                .then()
                .statusCode(200)
                .contentType("text/plain")
                .body(is("hello world"));
    }
}


text:
#ifndef PREGEL_OL_DEV_H
#define PREGEL_OL_DEV_H

#include "Task.h"
#include "VertexOL.h"
#include "WorkerOL.h"
#include "WorkerOL_auto.h"
using namespace std;

#endif /* PREGEL_DEV_H_ */


text:
package com.java.laiy.view;

import com.java.laiy.controller.GameController;

public class AdvConsoleView extends  ConsoleView {

    private static final String CHARACTER_HYPHEN = "__";

    private static final byte LINE_SIZE = 3;

    public AdvConsoleView(final GameController game) {
        super(game);
    }

    @Override
    public void showGameName() {
        printLine(CHARACTER_HYPHEN, LINE_SIZE);
        System.out.println("\n" + game.getGameName());
    }
}


text:
/* GLOBAL STYLES
-------------------------------------------------- */
/* Padding below the footer and lighter body text */

body {
  padding-bottom: 40px;
  color: #5a5a5a;
}

/* CUSTOMIZE THE NAVBAR
-------------------------------------------------- */

/* Special class on .container surrounding .navbar, used for positioning it into place. */
.navbar-text img {
  max-height:30px;
  width:auto;
  vertical-align:middle;
}

.navbar-wrapper {
  position: absolute;
  top: 0;
  right: 0;
  left: 0;
  z-index: 20;
}

/* Flip around the padding for proper display in narrow viewports */
.navbar-wrapper .container {
  padding-right: 0;
  padding-left: 0;
}
.navbar-wrapper .navbar {
 padding-right: 15px;
  padding-left: 15px;
}

.navbar-fixed-top {
  top: 0px;
  padding-right: 0px;
  padding-left: 0px;
}

/* CUSTOMIZE THE CAROUSEL
-------------------------------------------------- */

/* Carousel base class */
.carousel {
  height: 650px;
  margin-bottom: 0px;
}
/* Since positioning the image, we need to help out the caption */
.carousel-caption {
  z-index: 50;
}

/* Declare heights because of positioning of img element */
.carousel .item {
  height: 650px;
  background-color: #777;
}
.carousel-inner > .item > img {
  position: absolute;
  top: 0;
  left: 0;
  min-width: 100%;
  height: 650px;
}

/* MARKETING CONTENT
-------------------------------------------------- */

/* Pad the edges of the mobile views a bit */
.marketing {
  padding-right: 15px;
  padding-left: 15px;
}

/* Center align the text within the three columns below the carousel */
.marketing .col-lg-4 {
  margin-bottom: 20px;
  text-align: center;
}
.marketing h2 {
  font-weight: normal;
}
.marketing .col-lg-4 p {
  margin-right: 10px;
  margin-left: 10px;
}

/* Featurettes
------------------------- */

.featurette-divider {
  margin: 80px; /* Space out the Bootstrap <hr> more */
}

/* Thin out the marketing headings */
.featurette-heading {
  font-weight: 300;
  line-height: 1;
  letter-spacing: -1px;
}

/* RESPONSIVE CSS
-------------------------------------------------- */

@media (min-width: 768px) {

  /* Remove the edge padding needed for mobile */
  .marketing {
    padding-right: 0;
    padding-left: 0;
  }

  /* Navbar positioning foo */
  .navbar-wrapper {
    margin-top: 20px;
  }
  .navbar-wrapper .container {
    padding-right: 15px;
    padding-left:  15px;
  }
  .navbar-wrapper .navbar {
    padding-right: 0;
    padding-left:  0;
  }

  /* The navbar becomes detached from the top, so we round the corners */
  .navbar-wrapper .navbar {
    border-radius: 4px;
  }

  /* Bump up size of carousel content */
  .carousel-caption p {
/*    margin-top: 320px;
    max-height: 200px;
    max-width: 500px; */
    font-size: 21px;
    line-height: 1.4;
  }

  .featurette-heading {
    font-size: 50px;
  }
}

@media (min-width: 992px) {
  .featurette-heading {
    margin-top: 120px;
  }
}


text:
"""Python packaging."""
import os
import sys

from setuptools import setup
from setuptools.command.test import test as TestCommand

class Tox(TestCommand):
    """Test command that runs tox."""
    def finalize_options(self):
        TestCommand.finalize_options(self)
        self.test_args = []
        self.test_suite = True

    def run_tests(self):
        import tox  # import here, cause outside the eggs aren't loaded.
        errno = tox.cmdline(self.test_args)
        sys.exit(errno)

#: Absolute path to directory containing setup.py file.
here = os.path.abspath(os.path.dirname(__file__))
#: Boolean, ``True`` if environment is running Python version 2.
IS_PYTHON2 = sys.version_info[0] == 2

# Data for use in setup.
NAME = 'piecutter'
DESCRIPTION = 'Templating framework.'
README = open(os.path.join(here, 'README.rst')).read()
VERSION = open(os.path.join(here, 'VERSION')).read().strip()
AUTHOR = u'Rémy HUBSCHER'
EMAIL = 'hubscher.remy@gmail.com'
LICENSE = 'BSD'
URL = 'https://{name}.readthedocs.io/'.format(name=NAME)
CLASSIFIERS = [
    'Development Status :: 3 - Alpha',
    'Intended Audience :: Developers',
    'License :: OSI Approved :: BSD License',
    'Natural Language :: English',
    'Programming Language :: Python :: 2.7',
    'Programming Language :: Python :: 3.3',
]
KEYWORDS = [
    'template',
    'templates',
    'template engine',
    'jinja2',
    'django',
    'generator',
    'file generation',
    'scaffold',
]
PACKAGES = [NAME.replace('-', '_')]
REQUIREMENTS = [
    'Django',
    'jinja2',
    'requests',
    'setuptools',
    'six',
]
if IS_PYTHON2:
    REQUIREMENTS.extend(['mock'])
ENTRY_POINTS = {}
TEST_REQUIREMENTS = ['tox']
CMDCLASS = {'test': Tox}

if __name__ == '__main__':  # Do not run setup() when we import this module.
    setup(
        name=NAME,
        version=VERSION,
        description=DESCRIPTION,
        long_description=README,
        classifiers=CLASSIFIERS,
        keywords=' '.join(KEYWORDS),
        author=AUTHOR,
        author_email=EMAIL,
        url=URL,
        license=LICENSE,
        packages=PACKAGES,
        include_package_data=True,
        zip_safe=False,
        install_requires=REQUIREMENTS,
        entry_points=ENTRY_POINTS,
        tests_require=TEST_REQUIREMENTS,
        cmdclass=CMDCLASS,
    )


text:
import Ember from 'ember';
import isTrackingHeaderField from 'wherehows-web/utils/validators/tracking-headers';
import {
  classifiers,
  datasetClassifiers,
  fieldIdentifierTypes,
  idLogicalTypes,
  nonIdFieldLogicalTypes,
  defaultFieldDataTypeClassification,
  compliancePolicyStrings
} from 'wherehows-web/constants';
import { isPolicyExpectedShape } from 'wherehows-web/utils/datasets/functions';
import scrollMonitor from 'scrollmonitor';

const {
  assert,
  Component,
  computed,
  set,
  get,
  setProperties,
  getProperties,
  getWithDefault,
  String: { htmlSafe },
  inject: { service }
} = Ember;

const {
  complianceDataException,
  missingTypes,
  successUpdating,
  failedUpdating,
  helpText,
  successUploading,
  invalidPolicyData
} = compliancePolicyStrings;

const hiddenTrackingFieldsMsg = htmlSafe(
  '
Some fields in this dataset have been hidden from the table(s) below. ' +
    "These are tracking fields for which we've been able to predetermine the compliance classification.
" +
    '
For example: header.memberId, requestHeader. ' +
    'Hopefully, this saves you some scrolling!
'
);

/**
 * Takes a string, returns a formatted string. Niche , single use case
 * for now, so no need to make into a helper
 * @param {String} string
 */
const formatAsCapitalizedStringWithSpaces = string => string.replace(/[A-Z]/g, match => ` ${match}`).capitalize();

/**
 * List of non Id field data type classifications
 * @type {Array}
 */
const genericLogicalTypes = Object.keys(nonIdFieldLogicalTypes).sort();

/**
 * Merged object of logicalTypes
 * @type {Object}
 */
const logicalTypes = Object.assign({}, nonIdFieldLogicalTypes);
/**
 * String constant referencing the datasetClassification on the privacy policy
 * @type {String}
 */
const datasetClassificationKey = 'complianceInfo.datasetClassification';
/**
 * A list of available keys for the datasetClassification map on the security specification
 * @type {Array}
 */
const datasetClassifiersKeys = Object.keys(datasetClassifiers);

/**
 * A reference to the compliance policy entities on the complianceInfo map
 * @type {string}
 */
const policyComplianceEntitiesKey = 'complianceInfo.complianceEntities';
/**
 * Duplicate check using every to short-circuit iteration
 * @param {Array} list = [] the list to check for dupes
 * @return {Boolean} true is unique, false otherwise
 */
const listIsUnique = (list = []) => new Set(list).size === list.length;

assert('`fieldIdentifierTypes` contains an object with a key `none`', typeof fieldIdentifierTypes.none === 'object');
const fieldIdentifierTypeKeysBarNone = Object.keys(fieldIdentifierTypes).filter(k => k !== 'none');
const fieldDisplayKeys = ['none', '_', ...fieldIdentifierTypeKeysBarNone];

/**
 * A list of field identifier types mapped to label, value options for select display
 * @type {any[]|Array.<{value: String, label: String}>}
 */
const fieldIdentifierOptions = fieldDisplayKeys.map(fieldIdentifierType => {
  const divider = '──────────';
  const { value = fieldIdentifierType, displayAs: label = divider } = fieldIdentifierTypes[fieldIdentifierType] || {};

  // Adds a divider for a value of _
  // Visually this separates ID from none fieldIdentifierTypes
  return {
    value,
    label,
    isDisabled: fieldIdentifierType === '_'
  };
});

/**
 * A list of field identifier types that are Ids i.e member ID, org ID, group ID
 * @type {any[]|Array.<String>}
 */
export const fieldIdentifierTypeIds = Object.keys(fieldIdentifierTypes)
  .map(fieldIdentifierType => fieldIdentifierTypes[fieldIdentifierType])
  .filter(({ isId }) => isId)
  .mapBy('value');

/**
 * Caches a list of logicalType mappings for displaying its value and a label by logicalType
 * @param {String} logicalType
 */
const cachedLogicalTypes = logicalType =>
  computed(function() {
    return {
      id: idLogicalTypes,
      generic: genericLogicalTypes
    }[logicalType].map(value => ({
      value,
      label: logicalTypes[value]
        ? logicalTypes[value].displayAs
        : value.replace(/_/g, ' ').replace(/([A-Z]{3,})/g, f => f.toLowerCase().capitalize())
    }));
  });

// Map logicalTypes to options consumable by DOM
export const logicalTypesForIds = cachedLogicalTypes('id');

// Map generic logical type to options consumable in DOM
export const logicalTypesForGeneric = cachedLogicalTypes('generic');

export default Component.extend({
  sortColumnWithName: 'identifierField',
  filterBy: 'identifierField',
  sortDirection: 'asc',
  searchTerm: '',
  helpText,
  fieldIdentifierOptions,
  hiddenTrackingFields: hiddenTrackingFieldsMsg,
  classNames: ['compliance-container'],
  classNameBindings: ['isEditing:compliance-container--edit-mode'],
  /**
   * Flag indicating that the component is in edit mode
   * @type {String}
   */
  isEditing: computed('isNewComplianceInfo', 'isEditingDatasetClassification', 'isEditingCompliancePolicy', function() {
    const { isNewComplianceInfo, isEditingDatasetClassification, isEditingCompliancePolicy } = getProperties(
      this,
      'isNewComplianceInfo',
      'isEditingDatasetClassification',
      'isEditingCompliancePolicy'
    );
    return isNewComplianceInfo || isEditingDatasetClassification || isEditingCompliancePolicy;
  }),

  /**
   * Convenience flag indicating the policy is not currently being edited
   * @type {Ember.computed}
   * @return {boolean}
   */
  isReadOnly: computed.not('isEditing'),
  /**
   * Flag indicating that the component is currently saving / attempting to save the privacy policy
   * @type {String}
   */
  isSaving: false,

  /**
   * Determines if the the compliance policy update form should be shown
   * @type {Ember.computed}
   * @return {boolean}
   */
  isShowingComplianceEditMode: computed('isNewComplianceInfo', 'isEditingCompliancePolicy', function() {
    const { isNewComplianceInfo, isEditingCompliancePolicy, isEditingDatasetClassification } = getProperties(
      this,
      'isNewComplianceInfo',
      'isEditingCompliancePolicy',
      'isEditingDatasetClassification'
    );

    return (isNewComplianceInfo || isEditingCompliancePolicy) && !isEditingDatasetClassification;
  }),

  /**
   * Proxy to the check if the dataset classification form is being edited and should be shown
   * @type {Ember.computed}
   * @return {boolean}
   */
  isShowingDatasetClassificationEditMode: computed.bool('isEditingDatasetClassification'),

  datasetComplianceSteps: computed('isEditingCompliancePolicy', 'isEditingDatasetClassification', function() {
    const { isEditingCompliancePolicy, isEditingDatasetClassification } = getProperties(
      this,
      'isEditingCompliancePolicy',
      'isEditingDatasetClassification'
    );

    return [isEditingCompliancePolicy, isEditingDatasetClassification].map((_step, index) => ({
      done: !index ? !!isEditingDatasetClassification : false
    }));
  }),

  /**
   * Reference to the application notifications Service
   * @type {Ember.Service}
   */
  notifications: service(),

  didReceiveAttrs() {
    this._super(...Array.from(arguments));
    // Perform validation step on the received component attributes
    this.validateAttrs();
  },

  /**
   * @override
   */
  didRender() {
    this._super(...arguments);
    // Hides DOM elements that are not currently visible in the UI and unhides them once the user scrolls the
    // elements into view
    this.enableDomCloaking();
  },

  /**
   * A `lite` / intermediary step to occlusion culling, this helps to improve the rendering of
   * elements that are currently rendered in the viewport by hiding that aren't.
   * Setting them to visibility hidden doesn't remove them from the document flow, but the browser
   * doesn't have to deal with layout for the affected elements since they are off-screen
   */
  enableDomCloaking() {
    const [dom] = this.$('.dataset-compliance-fields');
    const triggerCount = 100;
    if (dom) {
      const rows = dom.querySelectorAll('tbody tr');

      // if we already have watchers for elements, or if the elements previously cached are no longer valid,
      // e.g. those elements were destroyed when new data was received, pagination etc
      if (rows.length > triggerCount && (!this.complianceWatchers || !this.complianceWatchers.has(rows[0]))) {
        /**
         * If an item is not in the viewport add a class to occlude it
         */
        const cloaker = function() {
          if (!this.isInViewport) {
            return this.watchItem.classList.add('compliance-row--off-screen');
          }
          this.watchItem.classList.remove('compliance-row--off-screen');
        };
        this.watchers = [];

        // Retain a weak reference to DOM nodes
        this.complianceWatchers = new WeakMap(
          [...rows].map(row => {
            const watcher = scrollMonitor.create(row);
            watcher['stateChange'](cloaker);
            cloaker.call(watcher);
            this.watchers = [...this.watchers, watcher];

            return [watcher.watchItem, watcher];
          })
        );
      }
    }
  },

  /**
   * Cleans up the artifacts from the dom cloaking operation, drops references held by scroll monitor
   */
  disableDomCloaking() {
    if (!this.watchers || !Array.isArray(this.watchers)) {
      return;
    }

    this.watchers.forEach(watcher => watcher.destroy());
  },

  /**
   * @override
   */
  willDestroyElement() {
    this.disableDomCloaking();
  },

  /**
   * Ensure that props received from on this component
   * are valid, otherwise flag
   */
  validateAttrs() {
    const fieldNames = getWithDefault(this, 'schemaFieldNamesMappedToDataTypes', []).mapBy('fieldName');

    // identifier field names from the column api should be unique
    if (listIsUnique(fieldNames.sort())) {
      return set(this, '_hasBadData', false);
    }

    // Flag this component's data as problematic
    set(this, '_hasBadData', true);
  },

  // Map logicalTypes to options consumable by DOM
  idLogicalTypes: logicalTypesForIds,

  // Map generic logical type to options consumable in DOM
  genericLogicalTypes: logicalTypesForGeneric,

  // Map classifiers to options better consumed in DOM
  classifiers: ['', ...classifiers.sort()].map(value => ({
    value,
    label: value ? formatAsCapitalizedStringWithSpaces(value) : '...'
  })),

  /**
   * Caches the policy's modification time in milliseconds
   */
  policyModificationTimeInEpoch: computed('complianceInfo', function() {
    return getWithDefault(this, 'complianceInfo.modifiedTime', 0);
  }),

  /**
   * Checks that suggested values postdate the last save date or that suggestions exist
   * @type {boolean}
   */
  hasRecentSuggestions: computed('policyModificationTimeInEpoch', 'complianceSuggestion', function() {
    const { policyModificationTimeInEpoch, complianceSuggestion = {} } = getProperties(this, [
      'policyModificationTimeInEpoch',
      'complianceSuggestion'
    ]);
    const { lastModified: suggestionsLastModified, complianceSuggestions = [] } = complianceSuggestion;

    // If modification dates exist, check that the suggestions are newer than the last time the policy was saved
    // and we have at least 1 suggestion, otherwise check that the count of suggestions is at least 1
    if (policyModificationTimeInEpoch && suggestionsLastModified) {
      return complianceSuggestions.length && suggestionsLastModified > policyModificationTimeInEpoch;
    }

    return !!complianceSuggestions.length;
  }),

  /**
   * @type {Boolean} cached boolean flag indicating that fields do contain a `kafka type`
   *    tracking header.
   *    Used to indicate to viewer that these fields are hidden.
   */
  containsHiddenTrackingFields: computed('truncatedColumnFields.length', function() {
    // If their is a diff in schemaFieldNamesMappedToDataTypes and truncatedColumnFields,
    //   then we have hidden tracking fields
    return get(this, 'truncatedColumnFields.length') !== get(this, 'schemaFieldNamesMappedToDataTypes.length');
  }),

  /**
   * @type {Array.<Object>} Filters the mapped compliance data fields without `kafka type`
   *   tracking headers
   */
  truncatedColumnFields: computed('schemaFieldNamesMappedToDataTypes', function() {
    return getWithDefault(this, 'schemaFieldNamesMappedToDataTypes', []).filter(
      ({ fieldName }) => !isTrackingHeaderField(fieldName)
    );
  }),

  /**
   * Checks that all tags/ dataset content types have a boolean value
   * @type {Ember.computed}
   */
  isDatasetFullyClassified: computed('datasetClassification', function() {
    const datasetClassification = get(this, 'datasetClassification');

    return Object.keys(datasetClassification)
      .map(key => ({ value: datasetClassification[key].value }))
      .every(({ value }) => [true, false].includes(value));
  }),

  /**
   * Determines if all member data fields should be shown in the member data table i.e. show only fields contained in
   * this dataset or otherwise
   */
  isShowingAllMemberData: computed.or('showAllDatasetMemberData', 'isEditing'),

  /**
   * Determines if the save feature is allowed for the current dataset, otherwise e.g. interface should be disabled
   * @type {Ember.computed}
   */
  isSavingDisabled: computed('isDatasetFullyClassified', 'isSaving', function() {
    const { isDatasetFullyClassified, isSaving } = getProperties(this, ['isDatasetFullyClassified', 'isSaving']);

    return !isDatasetFullyClassified || isSaving;
  }),

  /**
   * Checks to ensure the the number of fields added to compliance entities is less than or equal
   * to what is available on the dataset schema
   * @return {boolean}
   */
  isSchemaFieldLengthGreaterThanComplianceEntities() {
    const { length: columnFieldsLength } = getWithDefault(this, 'schemaFieldNamesMappedToDataTypes', []);
    const { length: complianceListLength } = get(this, policyComplianceEntitiesKey);

    return columnFieldsLength >= complianceListLength;
  },

  /**
   * Computed property that is dependent on all the keys in the datasetClassification map
   *   Returns a new map of datasetClassificationKey: String-> Object.<Boolean|undefined,String>
   * @type {Ember.computed}
   */
  datasetClassification: computed(`${datasetClassificationKey}.{${datasetClassifiersKeys.join(',')}}`, function() {
    const sourceDatasetClassification = get(this, datasetClassificationKey) || {};

    return datasetClassifiersKeys.sort().reduce((classifiers, classifier) => {
      return [
        ...classifiers,
        {
          classifier,
          value: sourceDatasetClassification[classifier],
          label: datasetClassifiers[classifier]
        }
      ];
    }, []);
  }),

  /**
   * Lists all dataset fields found in the `columns` performs an intersection
   * of fields with the currently persisted and/or updated
   * privacyCompliancePolicy.complianceEntities.
   * The returned list is a map of fields with current or default privacy properties
   */
  mergeComplianceEntitiesAndColumnFields(
    columnIdFieldsToCurrentPrivacyPolicy = {},
    truncatedColumnFields = [],
    identifierFieldMappedToSuggestions = {}
  ) {
    return truncatedColumnFields.map(({ fieldName: identifierField, dataType }) => {
      const {
        [identifierField]: { identifierType, logicalType, securityClassification }
      } = columnIdFieldsToCurrentPrivacyPolicy;

      //Cache the mapped suggestion into a local
      const suggestion = identifierFieldMappedToSuggestions[identifierField];
      let field = {
        identifierField,
        dataType,
        identifierType,
        logicalType,
        classification: securityClassification
      };

      // If a suggestion exists for this field add the suggestion attribute to the field properties
      if (suggestion) {
        field = { ...field, suggestion };
      }

      return field;
    });
  },

  /**
   *
   * @param {Array} columnFieldNames
   * @return {*|{}|any}
   */
  mapColumnIdFieldsToCurrentPrivacyPolicy(columnFieldNames) {
    const complianceEntities = get(this, policyComplianceEntitiesKey) || [];
    const getKeysOnField = (keys = [], fieldName, source = []) => {
      const sourceField = source.find(({ identifierField }) => identifierField === fieldName) || {};
      let ret = {};

      for (const [key, value] of Object.entries(sourceField)) {
        if (keys.includes(key)) {
          ret = { ...ret, [key]: value };
        }
      }
      return ret;
    };

    return columnFieldNames.reduce((acc, identifierField) => {
      const currentPrivacyAttrs = getKeysOnField(
        ['identifierType', 'logicalType', 'securityClassification'],
        identifierField,
        complianceEntities
      );

      return { ...acc, ...{ [identifierField]: currentPrivacyAttrs } };
    }, {});
  },

  /**
   * Computed prop over the current Id fields in the Privacy Policy
   * @type {Ember.computed}
   */
  columnIdFieldsToCurrentPrivacyPolicy: computed(
    'truncatedColumnFields',
    `${policyComplianceEntitiesKey}.[]`,
    function() {
      const columnFieldNames = get(this, 'truncatedColumnFields').map(({ fieldName }) => fieldName);
      return this.mapColumnIdFieldsToCurrentPrivacyPolicy(columnFieldNames);
    }
  ),

  /**
   * Caches a reference to the generated list of merged data between the column api and the current compliance entities list
   * @type {Ember.computed}
   */
  mergedComplianceEntitiesAndColumnFields: computed('columnIdFieldsToCurrentPrivacyPolicy', function() {
    // truncatedColumnFields is a dependency for cp columnIdFieldsToCurrentPrivacyPolicy, so no need to dep on that directly
    return this.mergeComplianceEntitiesAndColumnFields(
      get(this, 'columnIdFieldsToCurrentPrivacyPolicy'),
      get(this, 'truncatedColumnFields'),
      get(this, 'identifierFieldToSuggestion')
    );
  }),

  /**
   * Creates a mapping of compliance suggestions to identifierField
   * This improves performance in a subsequent merge op since this loop
   * happens only once and is cached
   * @type {Ember.computed}
   */
  identifierFieldToSuggestion: computed('complianceSuggestion', function() {
    const identifierFieldToSuggestion = {};
    const complianceSuggestions = getWithDefault(this, 'complianceSuggestion.complianceSuggestions', []);
    // If the compliance suggestions array contains suggestions the create reduced map,
    // otherwise, ignore
    if (complianceSuggestions.length) {
      return complianceSuggestions.reduce(
        (identifierFieldToSuggestion, { fieldName, identifierTypePrediction, logicalTypePrediction }) => ({
          ...identifierFieldToSuggestion,
          [fieldName]: {
            identifierTypePrediction,
            logicalTypePrediction
          }
        }),
        identifierFieldToSuggestion
      );
    }

    return identifierFieldToSuggestion;
  }),

  /**
   * Checks that each entity in sourceEntities has a generic
   * @param {Array} sourceEntities = [] the source entities to be matched against
   * @param {Array} logicalTypes = [] list of logicalTypes to check against
   */
  checkEachEntityByLogicalType: (sourceEntities = [], logicalTypes = []) =>
    sourceEntities.every(
      ({ logicalType }) =>
        typeof logicalType === 'object' ? logicalTypes.includes(logicalType.value) : logicalTypes.includes(logicalType)
    ),

  /**
   * TODO:DSS-6719 refactor into mixin
   * Clears recently shown user messages
   */
  clearMessages() {
    return setProperties(this, {
      _message: '',
      _alertType: ''
    });
  },

  /**
   * Helper method to update user when an async server update to the
   * security specification is handled.
   * @param {Promise|*} request the server request
   * @param {String} [successMessage] optional message for successful response
   * @param { Boolean} [isSaving = false] optional flag indicating when the user intends to persist / save
   */
  whenRequestCompletes(request, { successMessage, isSaving = false } = {}) {
    const notify = get(this, 'notifications.notify');

    return Promise.resolve(request)
      .then(({ status = 'error' }) => {
        return status === 'ok'
          ? notify('success', { content: successMessage || successUpdating })
          : Promise.reject(new Error(`Reason code for this is ${status}`));
      })
      .catch(err => {
        let message = `${failedUpdating} \n ${err}`;

        if (get(this, 'isNewComplianceInfo') && !isSaving) {
          return notify('info', {
            content: 'This dataset does not have any previously saved fields with a identifying information.'
          });
        }

        notify('error', { content: message });
      });
  },

  /**
   * Sets the default classification for the given identifier field
   * Using the provided logicalType, or in some cases the identifierType, determines the fields
   * default security classification based on a lookup
   * @param {String} identifierField the field for which the default classification should apply
   * @param {String} [identifierType] the current identifier type for the field
   * @param {String} [logicalType] the logicalType / (field format) for the identifierField
   */
  setDefaultClassification({ identifierField, identifierType }, { value: logicalType = '' } = {}) {
    let defaultTypeClassification = defaultFieldDataTypeClassification[logicalType] || null;
    // If the identifierType is of custom, set the default classification to the of a CUSTOM_ID, otherwise use value
    // based on logicalType
    defaultTypeClassification =
      identifierType === fieldIdentifierTypes.custom.value
        ? defaultFieldDataTypeClassification['CUSTOM_ID']
        : defaultTypeClassification;

    defaultTypeClassification =
      identifierType === fieldIdentifierTypes.enterpriseAccount.value
        ? defaultFieldDataTypeClassification['ID']
        : defaultTypeClassification;
    this.actions.onFieldClassificationChange.call(this, { identifierField }, { value: defaultTypeClassification });
  },

  /**
   * Requires that the user confirm that any non-id fields are ok to be saved without a field format specified
   * @return {Boolean}
   */
  async confirmUnformattedFields() {
    // Current list of compliance entities on policy
    const complianceEntities = get(this, policyComplianceEntitiesKey);
    // All candidate fields that can be on policy, excluding tracking type fields
    const datasetFields = get(
      this,
      'mergedComplianceEntitiesAndColumnFields'
    ).map(({ identifierField, identifierType, logicalType, classification }) => ({
      identifierField,
      identifierType,
      logicalType,
      securityClassification: classification
    }));
    // Fields that do not have a logicalType, and no identifierType or identifierType is `fieldIdentifierTypes.none`
    const { formatted, unformatted } = datasetFields.reduce(
      ({ formatted, unformatted }, field) => {
        const { identifierType, logicalType } = getProperties(field, ['identifierType', 'logicalType']);
        if (!logicalType && (fieldIdentifierTypes.none.value === identifierType || !identifierType)) {
          unformatted = [...unformatted, field];
        } else {
          formatted = [...formatted, field];
        }

        return { formatted, unformatted };
      },
      { formatted: [], unformatted: [] }
    );

    const dialogActions = {};
    let isConfirmed = true;
    let unformattedComplianceEntities = [];

    // If there are unformatted fields, require confirmation from user
    if (unformatted.length) {
      unformattedComplianceEntities = unformatted.map(({ identifierField }) => ({
        identifierField,
        identifierType: fieldIdentifierTypes.none.value,
        logicalType: null,
        securityClassification: null
      }));

      const confirmHandler = (function() {
        return new Promise((resolve, reject) => {
          dialogActions['didConfirm'] = () => resolve();
          dialogActions['didDismiss'] = () => reject();
        });
      })();

      // Create confirmation dialog
      get(this, 'notifications').notify('confirm', {
        header: 'Some field formats are unspecified',
        content:
          `There are ${unformatted.length} non-ID fields that have no field format specified. ` +
          `Are you sure they don't contain any of the following PII?\n\n` +
          `Name, Email, Phone, Address, Location, IP Address, Payment Info, Password, National ID, Device ID etc.`,
        dialogActions: dialogActions
      });

      try {
        await confirmHandler;
      } catch (e) {
        isConfirmed = false;
      }
    }

    isConfirmed && complianceEntities.setObjects([...formatted, ...unformattedComplianceEntities]);

    return isConfirmed;
  },

  /**
   * Ensures the fields in the updated list of compliance entities meet the criteria
   * checked in the function. If criteria is not met, an the returned promise is settled
   * in a rejected state, otherwise fulfilled
   * @method
   * @return {any | Promise<any>}
   */
  validateFields() {
    const notify = get(this, 'notifications.notify');
    const complianceEntities = get(this, policyComplianceEntitiesKey);
    const idFieldsHaveValidLogicalType = this.checkEachEntityByLogicalType(
      complianceEntities.filter(({ identifierType }) => fieldIdentifierTypeIds.includes(identifierType)),
      [...genericLogicalTypes, ...idLogicalTypes]
    );
    const fieldIdentifiersAreUnique = listIsUnique(complianceEntities.mapBy('identifierField'));
    const schemaFieldLengthGreaterThanComplianceEntities = this.isSchemaFieldLengthGreaterThanComplianceEntities();

    if (!fieldIdentifiersAreUnique || !schemaFieldLengthGreaterThanComplianceEntities) {
      notify('error', { content: complianceDataException });
      return Promise.reject(new Error(complianceDataException));
    }

    if (!idFieldsHaveValidLogicalType) {
      return Promise.reject(notify('error', { content: missingTypes }));
    }
  },

  /**
   * Gets a reference to the current dataset classification object
   */
  getDatasetClassificationRef() {
    let sourceDatasetClassification = getWithDefault(this, datasetClassificationKey, {});

    // For datasets initially without a datasetClassification, the default value is null
    if (sourceDatasetClassification === null) {
      sourceDatasetClassification = set(this, datasetClassificationKey, {});
    }

    return sourceDatasetClassification;
  },

  actions: {
    /**
     * Sets each datasetClassification value as false
     */
    async markDatasetAsNotContainingMemberData() {
      const dialogActions = {};
      const confirmMarkAllHandler = new Promise((resolve, reject) => {
        dialogActions.didDismiss = () => reject();
        dialogActions.didConfirm = () => resolve();
      });
      let willMarkAllAsNo = true;

      get(this, 'notifications').notify('confirm', {
        content: 'Are you sure that any this dataset does not contain any of the listed types of member data?',
        header: 'Dataset contains no member data',
        dialogActions
      });

      try {
        await confirmMarkAllHandler;
      } catch (e) {
        willMarkAllAsNo = false;
      }

      return (
        willMarkAllAsNo &&
        setProperties(
          this.getDatasetClassificationRef(),
          datasetClassifiersKeys.reduce(
            (classification, classifier) => ({ ...classification, ...{ [classifier]: false } }),
            {}
          )
        )
      );
    },

    /**
     * Sets the flag to show all member potential member data fields that may be contained in this dataset
     */
    onShowAllDatasetMemberData() {
      return set(this, 'showAllDatasetMemberData', true);
    },

    /**
     * Handler for setting the compliance policy into edit mode and rendering
     */
    onEditCompliancePolicy() {
      setProperties(this, { isEditingCompliancePolicy: true, isEditingDatasetClassification: false });
    },

    /**
     * Handler for setting the dataset classification into edit mode and rendering into DOM
     */
    async onEditDatasetClassification() {
      const isConfirmed = await this.confirmUnformattedFields();

      if (isConfirmed) {
        // Ensure that the fields on the policy meet the validation criteria before proceeding
        // Otherwise exit early
        try {
          await this.validateFields();
        } catch (e) {
          // Flag this dataset's data as problematic
          if (e instanceof Error && e.message === complianceDataException) {
            set(this, '_hasBadData', true);
            window.scrollTo(0, 0);
          }

          return;
        }

        // If user provides confirmation for unformatted fields or there are none,
        // then validate fields against expectations
        // otherwise inform user of validation exception
        setProperties(this, { isEditingCompliancePolicy: false, isEditingDatasetClassification: true });
      }
    },

    /**
     * Augments the field props with w a suggestionAuthority indicating that the field
     * suggestion has either been accepted or ignored, and assigns the value of that change to the prop
     * @param {object} field field for which this suggestion intent should apply
     * @param {string | void} [intent] user's intended action for suggestion, Defaults to `ignore`
     */
    onFieldSuggestionIntentChange(field, intent = 'ignore') {
      set(field, 'suggestionAuthority', intent);
    },

    /**
     * Receives the json representation for compliance and applies each key to the policy
     * @param {string} textString string representation for the JSON file
     */
    onComplianceJsonUpload(textString) {
      let policy;
      try {
        policy = JSON.parse(textString);
      } catch (e) {
        get(this, 'notifications').notify('error', {
          content: invalidPolicyData
        });
      }

      if (isPolicyExpectedShape(policy)) {
        setProperties(this, {
          'complianceInfo.complianceEntities': policy.complianceEntities,
          'complianceInfo.datasetClassification': policy.datasetClassification
        });

        get(this, 'notifications').notify('info', {
          content: successUploading
        });
      }

      get(this, 'notifications').notify('error', {
        content: invalidPolicyData
      });
    },

    /**
     * Handles the compliance policy download action
     */
    onComplianceDownloadJson() {
      const currentPolicy = get(this, 'complianceInfo');
      const policyProps = [datasetClassificationKey, policyComplianceEntitiesKey].map(name => name.split('.').pop());
      const policy = Object.assign({}, getProperties(currentPolicy, policyProps));
      const href = `data:text/json;charset=utf-8,${encodeURIComponent(JSON.stringify(policy))}`;
      const download = `${get(this, 'datasetName')}_policy.json`;
      const anchor = document.createElement('a');
      const anchorParent = document.body;

      /**
       *  Post download housekeeping
       */
      const cleanupPostDownload = () => {
        anchor.removeEventListener('click', cleanupPostDownload);
        anchorParent.removeChild(anchor);
      };

      Object.assign(anchor, { download, href });
      anchor.addEventListener('click', cleanupPostDownload);

      // Element needs to be in DOM to receive event in firefox
      anchorParent.appendChild(anchor);

      anchor.click();
    },

    /**
     * When a user updates the identifierFieldType in the DOM, update the backing store
     * @param {String} identifierField
     * @param {String} logicalType
     * @param {String} identifierType
     */
    onFieldIdentifierTypeChange({ identifierField }, { value: identifierType }) {
      const currentComplianceEntities = get(this, 'mergedComplianceEntitiesAndColumnFields');
      // A reference to the current field in the compliance list, it should exist even for empty complianceEntities
      // since this is a reference created in the working copy: mergedComplianceEntitiesAndColumnFields
      const currentFieldInComplianceList = currentComplianceEntities.findBy('identifierField', identifierField);
      setProperties(currentFieldInComplianceList, {
        identifierType,
        logicalType: void 0
      });
      // Set the defaultClassification for the identifierField,
      // although the classification is based on the logicalType,
      // an identifierField may only have one valid logicalType for it's given identifierType
      this.setDefaultClassification({ identifierField, identifierType });
    },

    /**
     * Updates the logical type for the given identifierField
     * @param {Object} field
     * @prop {String} field.identifierField
     * @param {Event} e the DOM change event
     * @return {*}
     */
    onFieldLogicalTypeChange(field, { value: logicalType } = {}) {
      const { identifierField } = field;

      // If the identifierField does not current exist, invoke onFieldIdentifierChange to add it on the compliance list
      if (!field) {
        this.actions.onFieldIdentifierTypeChange.call(
          this,
          { identifierField, logicalType },
          { value: fieldIdentifierTypes.none.value }
        );
      } else {
        set(field, 'logicalType', logicalType);
      }

      return this.setDefaultClassification({ identifierField }, { value: logicalType });
    },

    /**
     * Updates the filed classification
     * @param {String} identifierField the identifier field to update the classification for
     * @param {String} classification
     * @return {*}
     */
    onFieldClassificationChange({ identifierField }, { value: classification = null }) {
      const currentFieldInComplianceList = get(this, 'mergedComplianceEntitiesAndColumnFields').findBy(
        'identifierField',
        identifierField
      );
      // TODO:DSS-6719 refactor into mixin
      this.clearMessages();

      // Apply the updated classification value to the current instance of the field in working copy
      set(currentFieldInComplianceList, 'classification', classification);
    },

    /**
     * Updates the source object representing the current datasetClassification map
     * @param {String} classifier the property on the datasetClassification to update
     * @param {Boolean} value flag indicating if this dataset contains member data for the specified classifier
     * @return {*}
     */
    onChangeDatasetClassification(classifier, value) {
      return set(this.getDatasetClassificationRef(), classifier, value);
    },

    /**
     * If all validity checks are passed, invoke onSave action on controller
     */
    async saveCompliance() {
      const setSaveFlag = (flag = false) => set(this, 'isSaving', flag);

      try {
        const isSaving = true;
        const onSave = get(this, 'onSave');
        setSaveFlag(isSaving);

        return await this.whenRequestCompletes(onSave(), { isSaving });
      } finally {
        setSaveFlag();
      }
    },

    // Rolls back changes made to the compliance spec to current
    // server state
    resetCompliance() {
      const options = {
        successMessage: 'Field classification has been reset to the previously saved state.'
      };
      this.whenRequestCompletes(get(this, 'onReset')(), options);
    }
  }
});


text:
What We Do

OUR SERVICES

                            <img src="<?php echo get_template_directory_uri(); ?>/assets/images/gss_our_services_01.svg" alt="">

Business & Investment Consultancy

It won't be a bigger problem to find one video game lover in your neibor

                            <img src="<?php echo get_template_directory_uri(); ?>/assets/images/gss_our_services_03_not_hover.svg" alt="">

Offshore IT Development

It won't be a bigger problem to find one video game lover in your neibor

                            <img src="<?php echo get_template_directory_uri(); ?>/assets/images/gss_our_services_05.svg" alt="">

Mobile & Web Applications

It won't be a bigger problem to find one video game lover in your neibor

                            <img src="<?php echo get_template_directory_uri(); ?>/assets/images/gss_our_services_02.svg" alt="">

HR, Payroll & Accounting Services

It won't be a bigger problem to find one video game lover in your neibor

                            <img src="<?php echo get_template_directory_uri(); ?>/assets/images/gss_our_services_04.svg" alt="">

Data Processing and General Administration

It won't be a bigger problem to find one video game lover in your neibor

                            <img src="<?php echo get_template_directory_uri(); ?>/assets/images/gss_our_services_06.svg" alt="">

Research and Marketing

It won't be a bigger problem to find one video game lover in your neibor


text:
package com.lucidchart.open.nark.views.models

import com.lucidchart.open.nark.models.records.Alert

import play.api.libs.json.Json

object alert {
	def apply(obj: Alert) = Json.obj(
		"id" -> obj.id.toString,
		"name" -> obj.name,
		"userId" -> obj.userId.toString,
		"target" -> obj.target,
		"comparison" -> obj.comparison.toString,
		"dynamicAlertId" -> obj.dynamicAlertId.map(_.toString),
		"active" -> obj.active,
		"deleted" -> obj.deleted,
		"created" -> obj.created.getTime,
		"updated" -> obj.updated.getTime,
		"lastChecked" -> obj.lastChecked.getTime,
		"nextCheck" -> obj.nextCheck.getTime,
		"frequency" -> obj.frequency,
		"warnThreshold" -> obj.warnThreshold,
		"errorThreshold" -> obj.errorThreshold,
		"worstState" -> obj.worstState.toString,
		"consecutiveFailures" -> obj.consecutiveFailures
	)
}


text:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<title>RakNet: D:/temp/RakNet_PC/DependentExtensions/Lobby2/Steam Directory Reference</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>

<link href="doxygen.css" rel="stylesheet" type="text/css" />

RakNet
    4.0

Main Page

Related Pages

Modules

Namespaces

Classes

Files

D:

temp

RakNet_PC

DependentExtensions

Lobby2

Steam

Steam Directory Reference

Files

file  	Lobby2Client_Steam.h

file  	Lobby2Client_Steam_Impl.h

file  	Lobby2Message_Steam.h

<address class="footer">
Generated on Mon Jun 2 2014 20:10:30 for RakNet by

 1.8.2
</address>


text:
class MyObject {
 public:
  static void Init(napi_env env, napi_value exports);
  static void Destructor(napi_env env, void* nativeObject, void* finalize_hint);

 private:
  explicit MyObject(double value_ = 0);
  ~MyObject();

  static napi_value New(napi_env env, napi_callback_info info);
  static napi_value GetValue(napi_env env, napi_callback_info info);
  static napi_value SetValue(napi_env env, napi_callback_info info);
  static napi_value PlusOne(napi_env env, napi_callback_info info);
  static napi_value Multiply(napi_env env, napi_callback_info info);
  static napi_ref constructor;
  double value_;
  napi_env env_;
  napi_ref wrapper_;
};

#endif  // TEST_JS_NATIVE_API_6_OBJECT_WRAP_MYOBJECT_H_


text:
package com.jakduk.api.restcontroller.vo.admin;

import javax.validation.constraints.Min;

/**
 * @author Jang,Pyohwan
 * @company  : http://jakduk.com
 * @date     : 2015. 3. 2.
 * @desc     :
 */

public class ThumbnailSizeWrite {

	@Min(1)
	private int width = 1;

	@Min(1)
	private int height = 1;

	private String galleryId;

	public int getWidth() {
		return width;
	}

	public void setWidth(int width) {
		this.width = width;
	}

	public int getHeight() {
		return height;
	}

	public void setHeight(int height) {
		this.height = height;
	}

	public String getGalleryId() {
		return galleryId;
	}

	public void setGalleryId(String galleryId) {
		this.galleryId = galleryId;
	}

	@Override
	public String toString() {
		return "ThumbnailSizeWrite [width=" + width + ", height=" + height
				+ ", galleryId=" + galleryId + "]";
	}

}


text:
package net.kemitix.kxssh;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStream;

public class SshIOFactory {

    public FileOutputStream createFileOutputStream(File output) throws FileNotFoundException {
        return new FileOutputStream(output);
    }

    public InputStream createFileInputStream(File input) throws FileNotFoundException {
        return new FileInputStream(input);
    }

}


text:
import logging
from os.path import expanduser, isfile

import subprocess32

LOG = logging.getLogger("simdeplower")

class VmrunHelper(object):
    """
    Helper class to make running vmrun commands a bit easier..
    No that they are hard.. but what ever.
    """

    def __init__(self, vmrun_path=None, nogui=None, target=None):
        """
        Constructor

        :param vmrun_path: str path to vmrun binary
        :param nogui: bool
        :return:
        """
        if vmrun_path is None:
            LOG.debug("vmrun path not set. Attempting OSX settings")
            osx_path = "/Applications/VMware Fusion.app/Contents/Library/vmrun"
            osx_path = expanduser(osx_path)
            if isfile(osx_path):
                vmrun_path = osx_path
                target = "fusion"
                LOG.debug("OSX settings successful.")
            else:
                raise ValueError(
                    "vmrun_path not supplied. vmrun not found on file system."
                    " Please supply full path to vmrun binary.")
        elif not isfile(expanduser(vmrun_path)):
            raise ValueError("vmrun not found at path provided. Please provide"
                             " full path to vmrun binary.")

        if target != "fusion" and target != "ws":
            msg = "Only supported target is 'fusion' or 'ws' for workstation."
            raise ValueError(msg)

        self.target = target
        self.vmrun = expanduser(vmrun_path)
        if nogui is None:
            self.gui_setting = "nogui"
        if nogui:
            self.gui_setting = "nogui"
        else:
            self.gui_setting = "gui"
        LOG.debug("Using gui: {0}".format(self.gui_setting))
        LOG.debug("Using target: {0}".format(self.target))
        LOG.debug("Using vmrun: {0}".format(self.vmrun))

    def start_vmx(self, vmx_path=None):
        """
        If no exception is thrown it started the vm.

        :param vmx_path:
        :return:
        """
        vmx_path = expanduser(vmx_path)
        self._verify_vmx_path(vmx_path)
        cli_msg = subprocess32.check_call(
            [
                self.vmrun,
                "-T",
                self.target,
                "start",
                vmx_path,
                self.gui_setting
            ]
        )

    def stop_vmx(self, vmx_path=None):
        vmx_path = expanduser(vmx_path)
        self._verify_vmx_path(vmx_path)
        cli_msg = subprocess32.check_call(
            [
                self.vmrun,
                "-T",
                self.target,
                "stop",
                vmx_path
            ]
        )
        LOG.debug(cli_msg)

    def get_vmx_ip(self, vmx_path=None):
        vmx_path = expanduser(vmx_path)
        self._verify_vmx_path(vmx_path)
        output = subprocess32.check_output(
            [
                self.vmrun,
                "-T",
                self.target,
                "getGuestIPAddress",
                vmx_path,
                "-wait"
            ]
        )
        return output.rstrip('\n')

    @staticmethod
    def _verify_vmx_path(vmx_path=None):
        if vmx_path is None:
            raise ValueError("vmx_path was None. "
                             "Im sorry Dave, Im afraid I cant do that.")
        if not isfile(vmx_path):
            raise ValueError("File not found using vmx_path {0}".format(vmx_path))
        if not vmx_path.endswith(".vmx"):
            raise ValueError("vmx_path does not end with .vmx fix the file.")


text:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="org.rosedu.dandroid.dateandtime" >

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".view.DateAndTimeActivity"
            android:label="@string/app_name"
            android:theme="@style/AppTheme.NoActionBar" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>

            <!-- exercise 4a: intent filter (intent) -->

            <!-- exercise 4c: intent filter (URI) -->

        </activity>

        <!-- exercise 4b: receiver -->

    </application>

</manifest>