<commit_before># Mixpanel Magic Lamp

[![Gem Version](https://badge.fury.io/rb/mixpanel_magic_lamp.svg)](http://badge.fury.io/rb/mixpanel_magic_lamp)

Rub the magic lamp and your desired Mixpanel ORM will appear!

If you're using [Mixpanel](https://mixpanel.com/) for your web site analytics you probably thought
in make reports exporting your data through any **Mixpanel API** client. This gem is your answer 
for not overwarming your head with so many doc, and it will remind you to ```ActiveRecord```.

## Install
You can install this *gem* by

```
$ gem install mixpanel_magic_lamp
```

Or bundle it on your app by adding this line at your *Gemfile*

```ruby
gem 'mixpanel_magic_lamp'
```

## Configuration
To setup this gem you should add API keys and other config:
```ruby
MixpanelMagicLamp.configure do |config|
  # Set your API Key/Secret
  config.api_key     = "YOUR MIXPANEL API KEY"
  config.api_secret  = "YOUR MIXPANEL API SECRET"

  # Run query in parallel (recomended for better performance)
  config.parallel = true

  # Default interval on from/to dates when dates are not provided
  config.interval = 30
end
```

### Rails config generator
Copy base config file on your **Rails app** by
```bash
rails generator mixpanel_magic_lamp:config
```


## Build your query
The most interesting feature from this library is probably the query builder, that
let you to build an 'ActiveRecord' like query to run API queries, it will remind you to
the Mixpanel UI:

### where
Start any query with this keyword, and extend is as long as you need.
This method accept a hash as first parameter where each pair of key/value are traslated
to "key == value" (*equals_to*), a second parameter may change union word:

```ruby
Mixpanel.where(country: 'Spain', gender: 'Female').to_s
=> "(properties[\"country\"] == \"Spain\" and properties[\"gender\"] == \"Female\")"

Mixpanel.where({country: 'Spain', gender: 'Female'}, 'or').to_s
=> "(properties[\"country\"] == \"Spain\" or properties[\"gender\"] == \"Female\")"
```


Then you may append any existent query build to complete your API query:

```ruby
Mixpanel.where(country: 'Spain').or.is_set('source').to_s
=> "(properties[\"country\"] == \"Spain\") or (defined (properties[\"source\"]))"
```

### and/or
Concat as many query builders as you need with ```and``` and ```or``` operators:

```ruby
Mixpanel.where(country: "Spain", browser: "Chrome")
        .and.is_set('device_type')
        .and.does_not_equal(user_type: 'bot')
        .and.contains(url: '/sales')
=> "(properties[\"country\"] == \"Spain\" and properties[\"browser\"] == \"Chrome\") and (defined (properties[\"device_type\"])) and (properties[\"user_type\"] != \"bot\") and (\"/sales\" in (properties[\"url\"]))">
```


### on
Use it as **by** statement on your UI, in order to group segmentation:

```ruby
Mixpanel.on('country')
=> "properties[\"country\"]"
```

### Builders
* ```equals```:
  ```ruby
  Mixpanel.where.and.equals(country: 'Spain', user_type: 'human').to_s
  => "(properties[\"country\"] == \"Spain\" and properties[\"user_type\"] == \"human\")"
  ```
* ```does_not_equal```
  ```ruby
  Mixpanel.where.and.does_not_equal(country: 'Spain', user_type: 'human')
  => "(properties[\"country\"] != \"Spain\" and properties[\"user_type\"] != \"human\")"
  ```
* ```contains```
  ```ruby
  Mixpanel.where.and.contains(country: 'Spain', user_type: 'human').to_s
  => "(\"Spain\" in (properties[\"country\"]) and \"human\" in (properties[\"user_type\"]))"
  ```
* ```does_not_contain```
  ```ruby
  Mixpanel.where.and.does_not_contain(country: 'Spain', user_type: 'human').to_s
  => "(not \"Spain\" in (properties[\"country\"]) and not \"human\" in (properties[\"user_type\"]))"
  ```
* ```is_set```
  ```ruby
  Mixpanel.where.and.is_set(['country', 'user_type']).to_s
  => "(defined (properties[\"country\"]) and defined (properties[\"user_type\"]))"
  ```
* ```is_not_set```
  ```ruby
  Mixpanel.where.and.is_not_set(['country', 'user_type']).to_s
  => "(not defined (properties[\"country\"]) and not defined (properties[\"user_type\"]))"
  ```


## Actions
Mixpanel API client has a lot of possible actions, so far these are the supported actions:

### Segementation
Classic **Mixpanel** segmentation action, where you can specify *event name*, *from/to dates* and *any conditions* you want. Prepare and run as many request in parallel you need

```ruby
interface = Mixpanel::Interface.new

page_visits_query = Mixpanel.where("product" => 'Finances')
                            .and.is_set("subproduct")
page_visits  = interface.segmentation('Page visit', { from: Data.parse('2015-01-31'),
                                                      to: Date.today },
                                                    { where: page_visits_query })


login_clicks_query = Mixpanel.where("device_type" => 'mobile')
login_clicks = interface.segmentation('Login', { from: Data.parse('2015-04-01'),
                                                 to: Date.today },
                                               { where: login_clicks_query })

# Run all the queued queries
interface.run!

# Present your data...
p page_visits[:data]
p login_clicks[:data]
```
 
### Segmentation by
Same as **segmentation** but grouping the output by any property you want to.

```ruby
interface = Mixpanel::Interface.new

page_visits_query = Mixpanel.where("product" => 'Finances')
                            .and.is_set("subproduct")
page_visits  = interface.segmentation('Page visit', { from: Data.parse('2015-01-31'),
                                                      to: Date.today },
                                                    { where: page_visits_query,
                                                      on: Mixpanel.on('device_type') })

# Run all the queued queries
interface.run!

# Present your data...
p page_visits[:data]
```


## Your own interface
Now you master all the above concepts, the best thing you can do is to build you own interface model to extracting you reports:
<commit_msg>Fix typos on README<commit_after># Mixpanel Magic Lamp

[![Gem Version](https://badge.fury.io/rb/mixpanel_magic_lamp.svg)](http://badge.fury.io/rb/mixpanel_magic_lamp)

Rub the magic lamp and your desired Mixpanel ORM will appear!

If you're using [Mixpanel](https://mixpanel.com/) for your web site analytics you probably thought
in make reports exporting your data through any **Mixpanel API** client. This gem is your answer 
for not overwarming your head with so many doc, and it will remind you to ```ActiveRecord```.

## Install
You can install this *gem* by

```
$ gem install mixpanel_magic_lamp
```

Or bundle it on your app by adding this line at your *Gemfile*

```ruby
gem 'mixpanel_magic_lamp'
```

## Configuration
To setup this gem you should add API keys and other config:
```ruby
MixpanelMagicLamp.configure do |config|
  # Set your API Key/Secret
  config.api_key     = "YOUR MIXPANEL API KEY"
  config.api_secret  = "YOUR MIXPANEL API SECRET"

  # Run query in parallel (recomended for better performance)
  config.parallel = true

  # Default interval on from/to dates when dates are not provided
  config.interval = 30
end
```

### Rails config generator
Copy base config file on your **Rails app** by
```bash
rails generator mixpanel_magic_lamp:config
```


## Build your query
The most interesting feature from this library is probably the query builder, that
let you to build an 'ActiveRecord' like query to run API queries, it will remind you to
the Mixpanel UI:

### where
Start any query with this keyword, and extend is as long as you need.
This method accept a hash as first parameter where each pair of key/value are traslated
to "key == value" (*equals_to*), a second parameter may change union word:

```ruby
Mixpanel.where(country: 'Spain', gender: 'Female').to_s
=> "(properties[\"country\"] == \"Spain\" and properties[\"gender\"] == \"Female\")"

Mixpanel.where({country: 'Spain', gender: 'Female'}, 'or').to_s
=> "(properties[\"country\"] == \"Spain\" or properties[\"gender\"] == \"Female\")"
```


Then you may append any existent query build to complete your API query:

```ruby
Mixpanel.where(country: 'Spain').or.is_set('source').to_s
=> "(properties[\"country\"] == \"Spain\") or (defined (properties[\"source\"]))"
```

### and/or
Concat as many query builders as you need with ```and``` and ```or``` operators:

```ruby
Mixpanel.where(country: "Spain", browser: "Chrome")
        .and.is_set('device_type')
        .and.does_not_equal(user_type: 'bot')
        .and.contains(url: '/sales')
=> "(properties[\"country\"] == \"Spain\" and properties[\"browser\"] == \"Chrome\") and (defined (properties[\"device_type\"])) and (properties[\"user_type\"] != \"bot\") and (\"/sales\" in (properties[\"url\"]))">
```


### on
Use it as **by** statement on your UI, in order to group segmentation:

```ruby
Mixpanel.on('country')
=> "properties[\"country\"]"
```

### Builders
* ```equals```:

  ```ruby
  Mixpanel.where.and.equals(country: 'Spain', user_type: 'human').to_s
  => "(properties[\"country\"] == \"Spain\" and properties[\"user_type\"] == \"human\")"
  ```

* ```does_not_equal```

  ```ruby
  Mixpanel.where.and.does_not_equal(country: 'Spain', user_type: 'human')
  => "(properties[\"country\"] != \"Spain\" and properties[\"user_type\"] != \"human\")"
  ```

* ```contains```

  ```ruby
  Mixpanel.where.and.contains(country: 'Spain', user_type: 'human').to_s
  => "(\"Spain\" in (properties[\"country\"]) and \"human\" in (properties[\"user_type\"]))"
  ```

* ```does_not_contain```

  ```ruby
  Mixpanel.where.and.does_not_contain(country: 'Spain', user_type: 'human').to_s
  => "(not \"Spain\" in (properties[\"country\"]) and not \"human\" in (properties[\"user_type\"]))"
  ```

* ```is_set```

  ```ruby
  Mixpanel.where.and.is_set(['country', 'user_type']).to_s
  => "(defined (properties[\"country\"]) and defined (properties[\"user_type\"]))"
  ```

* ```is_not_set```

  ```ruby
  Mixpanel.where.and.is_not_set(['country', 'user_type']).to_s
  => "(not defined (properties[\"country\"]) and not defined (properties[\"user_type\"]))"
  ```


## Actions
Mixpanel API client has a lot of possible actions, so far these are the supported actions:

### Segementation
Classic **Mixpanel** segmentation action, where you can specify *event name*, *from/to dates* and *any conditions* you want. Prepare and run as many request in parallel you need

```ruby
interface = Mixpanel::Interface.new

page_visits_query = Mixpanel.where("product" => 'Finances')
                            .and.is_set("subproduct")
page_visits  = interface.segmentation('Page visit', { from: Data.parse('2015-01-31'),
                                                      to: Date.today },
                                                    { where: page_visits_query })


login_clicks_query = Mixpanel.where("device_type" => 'mobile')
login_clicks = interface.segmentation('Login', { from: Data.parse('2015-04-01'),
                                                 to: Date.today },
                                               { where: login_clicks_query })

# Run all the queued queries
interface.run!

# Present your data...
p page_visits[:data]
p login_clicks[:data]
```
 
### Segmentation by
Same as **segmentation** but grouping the output by any property you want to.

```ruby
interface = Mixpanel::Interface.new

page_visits_query = Mixpanel.where("product" => 'Finances')
                            .and.is_set("subproduct")
page_visits  = interface.segmentation('Page visit', { from: Data.parse('2015-01-31'),
                                                      to: Date.today },
                                                    { where: page_visits_query,
                                                      on: Mixpanel.on('device_type') })

# Run all the queued queries
interface.run!

# Present your data...
p page_visits[:data]
```


## Your own interface
Now you master all the above concepts, the best thing you can do is to build your own interface model for extracting your reports:

{'fraction_non_alphanumeric': 0.15838303512259774, 'fraction_numerical': 0.004307488402915839, 'mean_word_length': 3.307170888333928, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 33, 'https://': 4, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 28, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3413185', 'n_tokens_mistral': 3799, 'n_tokens_neox': 3566, 'n_words': 1119}