text:
[![license](http://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/udhos/goben/blob/master/LICENSE)
[![Go Report Card](https://goreportcard.com/badge/github.com/udhos/goben)](https://goreportcard.com/report/github.com/udhos/goben)
[![Go Reference](https://pkg.go.dev/badge/github.com/udhos/goben.svg)](https://pkg.go.dev/github.com/udhos/goben)
[![GolangCI](https://golangci.com/badges/github.com/udhos/goben.svg)](https://golangci.com/r/github.com/udhos/goben)

# goben

goben is a golang tool to measure TCP/UDP transport layer throughput between hosts.

- Can limit maximum bandwidth.
- Written in [Go](https://golang.org/). Single executable file. No runtime dependency.
- Simple usage: start the server then launch the client pointing to server's address.
- Spawns multiple concurrent lightweight goroutines to handle multiple parallel traffic streams.
- Can save test results as PNG chart.
- Can export test results as YAML or CSV.

# History

- Years ago out of frustration with [iperf2](https://sourceforge.net/projects/iperf2/) limitations, I wrote the [nepim](http://www.nongnu.org/nepim/) tool. One can find some known iperf problems here: [iperf caveats](https://support.cumulusnetworks.com/hc/en-us/articles/216509388-Throughput-Testing-and-Troubleshooting#network_testing_with_open_source_tools). Nepim was more customizable, easier to use, reported simpler to understand results, was lighter on CPU.
- Later I found another amazing tool called [nuttcp](https://www.nuttcp.net/). One can read about nepim and nuttcp here: [nepim and nuttcp](https://www.linux.com/news/benchmarking-network-performance-network-pipemeter-lmbench-and-nuttcp).
- [goben](https://github.com/udhos/goben) is intended to fix shortcomings of nepim: (1) Take advantage of multiple CPUs while not wasting processing power. Nepim was single-threaded. (2) Be easily portable to multiple platforms. Nepim was heavily tied to UNIX-like world. (3) Use a simpler synchronous code flow. Nepim used hard-to-follow asynchronous architecture.

# Requirements

- You need a [system with the Go language](https://golang.org/dl/) in order to build the application. There is no special requirement for running it.

Start server:

    server$ goben

Start client:

    client$ goben -hosts <IP_ADDRESS> ;# <IP_ADDRESS> is server's address

# Command-line Options

Find several supported command-line switches by running 'goben -h':

```
$ goben -h
2021/02/28 00:43:28 goben version 0.6 runtime go1.16 GOMAXPROCS=12 OS=linux arch=amd64
Usage of goben:
  -ascii
        plot ascii chart (default true)
  -cert string
        TLS cert file (default "cert.pem")
  -chart string
        output filename for rendering chart on client
        '%d' is parallel connection index to host
        '%s' is hostname:port
        example: -chart chart-%d-%s.png
  -connections int
        number of parallel connections (default 1)
  -csv string
        output filename for CSV exporting test results on client
        '%d' is parallel connection index to host
        '%s' is hostname:port
        example: -csv export-%d-%s.csv
  -defaultPort string
        default port (default ":8080")
  -export string
        output filename for YAML exporting test results on client
        '%d' is parallel connection index to host
        '%s' is hostname:port
        example: -export export-%d-%s.yaml
  -hosts value
        comma-separated list of hosts
        you may append an optional port to every host: host[:port]
  -key string
        TLS key file (default "key.pem")
  -listeners value
        comma-separated list of listen addresses
        you may prepend an optional host to every port: [host]:port
  -localAddr string
        bind specific local address:port
        example: -localAddr <IP_ADDRESS>:2000
  -maxSpeed float
        bandwidth limit in mbps (0 means unlimited)
  -passiveClient
        suppress client writes
  -passiveServer
        suppress server writes
  -reportInterval string
        periodic report interval
        unspecified time unit defaults to second (default "2s")
  -tcpReadSize int
        TCP read buffer size in bytes (default 1000000)
  -tcpWriteSize int
        TCP write buffer size in bytes (default 1000000)
  -tls
        set to false to disable TLS (default true)
  -totalDuration string
        test total duration
        unspecified time unit defaults to second (default "10s")
  -udp
        run client in UDP mode
  -udpReadSize int
        UDP read buffer size in bytes (default 64000)
  -udpWriteSize int
        UDP write buffer size in bytes (default 64000)
```

# Example

Server side:

    $ goben
    2018/06/28 15:04:26 goben version 0.3 runtime go1.11beta1 GOMAXPROCS=1
    2018/06/28 15:04:26 connections=1 defaultPort=:8080 listeners=[":8080"] hosts=[]
    2018/06/28 15:04:26 reportInterval=2s totalDuration=10s
    2018/06/28 15:04:26 server mode (use -hosts to switch to client mode)
    2018/06/28 15:04:26 serve: spawning TCP listener: :8080
    2018/06/28 15:04:26 serve: spawning UDP listener: :8080

Client side:

    $ goben -hosts localhost
    2018/06/28 15:04:28 goben version 0.3 runtime go1.11beta1 GOMAXPROCS=1
    2018/06/28 15:04:28 connections=1 defaultPort=:8080 listeners=[":8080"] hosts=["localhost"]
    2018/06/28 15:04:28 reportInterval=2s totalDuration=10s
    2018/06/28 15:04:28 client mode, tcp protocol
    2018/06/28 15:04:28 open: opening tcp 0/1: localhost:8080
    2018/06/28 15:04:28 handleConnectionClient: starting 0/1 [::1]:8080
    2018/06/28 15:04:28 handleConnectionClient: options sent: {2s 10s 50000 50000 false 0}
    2018/06/28 15:04:28 clientReader: starting: 0/1 [::1]:8080
    2018/06/28 15:04:28 clientWriter: starting: 0/1 [::1]:8080
    2018/06/28 15:04:30 0/1  report   clientReader rate:  13917 Mbps  34793 rcv/s
    2018/06/28 15:04:30 0/1  report   clientWriter rate:  13468 Mbps  33670 snd/s
    2018/06/28 15:04:32 0/1  report   clientReader rate:  14044 Mbps  35111 rcv/s
    2018/06/28 15:04:32 0/1  report   clientWriter rate:  13591 Mbps  33978 snd/s
    2018/06/28 15:04:34 0/1  report   clientReader rate:  12934 Mbps  32337 rcv/s
    2018/06/28 15:04:34 0/1  report   clientWriter rate:  12517 Mbps  31294 snd/s
    2018/06/28 15:04:36 0/1  report   clientReader rate:  13307 Mbps  33269 rcv/s
    2018/06/28 15:04:36 0/1  report   clientWriter rate:  12878 Mbps  32196 snd/s
    2018/06/28 15:04:38 0/1  report   clientWriter rate:  13330 Mbps  33325 snd/s
    2018/06/28 15:04:38 0/1  report   clientReader rate:  13774 Mbps  34436 rcv/s
    2018/06/28 15:04:38 handleConnectionClient: 10s timer
    2018/06/28 15:04:38 workLoop: 0/1 clientWriter: write tcp [::1]:42130->[::1]:8080: use of closed network connection
    2018/06/28 15:04:38 0/1 average   clientWriter rate:  13157 Mbps  32892 snd/s
    2018/06/28 15:04:38 clientWriter: exiting: 0/1 [::1]:8080
    2018/06/28 15:04:38 workLoop: 0/1 clientReader: read tcp [::1]:42130->[::1]:8080: use of closed network connection
    2018/06/28 15:04:38 0/1 average   clientReader rate:  13595 Mbps  33989 rcv/s
    2018/06/28 15:04:38 clientReader: exiting: 0/1 [::1]:8080
    2018/06/28 15:04:38 input:
     14038 ┤          ╭────╮
     13939 ┤──────────╯    ╰╮
     13840 ┼                ╰─╮
     13741 ┤                  ╰╮                                    ╭──
     13641 ┤                   ╰╮                               ╭───╯
     13542 ┤                    ╰─╮                          ╭──╯
     13443 ┤                      ╰╮                     ╭───╯
     13344 ┤                       ╰─╮               ╭───╯
     13245 ┤                         ╰╮          ╭───╯
     13146 ┤                          ╰─╮    ╭───╯
     13047 ┤                            ╰────╯
     12948 ┤
    2018/06/28 15:04:38 output:
     13585 ┤          ╭────╮
     13489 ┤──────────╯    ╰╮
     13393 ┼                ╰─╮
     13297 ┤                  ╰╮                                    ╭──
     13201 ┤                   ╰╮                               ╭───╯
     13105 ┤                    ╰─╮                          ╭──╯
     13009 ┤                      ╰╮                     ╭───╯
     12914 ┤                       ╰─╮               ╭───╯
     12818 ┤                         ╰╮          ╭───╯
     12722 ┤                          ╰─╮    ╭───╯
     12626 ┤                            ╰────╯
     12530 ┤
    2018/06/28 15:04:38 handleConnectionClient: closing: 0/1 [::1]:8080

# TLS

For TLS, a server-side certificate is required:

    $ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout key.pem -out cert.pem

If the certificate is available, goben server listens on TLS socket. Otherwise, it falls back to plain TCP.

--x--

repository: udhos/goben

repo_name: udhos/goben


text:
---
published: true
title: Configure Dell BIOS from WinPE
layout: post
---
To start off, I should clarify that I typically use SCCM Task Sequences with MDT integration.  The following scenario utilizes SCCM 2012 R2 with MDT 2013 integration.

1. Download and install the Dell Client Configuration Toolkit (CCTK) from Dell’s website: http://www.dell.com/support/home/us/en/04/Drivers/DriversDetails?driverId=6HCTN
2. From the installation directory, typically C:\Program Files (x86)\Dell\CCTK, grab X86 and X86_64 folders and create an empty package (no programs).

3. Additionally, add CCTK-default.cmd and show-cctkerrors.vbs to the root of your package folder, we’ll be utilizing this in a task sequence step.  These files were originally authored by windowsmasher: http://windowsmasher.wordpress.com/2013/01/21/sccm-2012-generic-multi-platform-dell-cctk-bios-settings/.  Thank you!  I’ve made my own customization to the cmd file to better suite my needs.  Created a config subfolder in the CCTK package and drop Multi-Platform_Generic.ini there.  You can find the files you need here.  The final folder structure should look like this:
root\X86\
root\X86_64\
root\config\Multi-Platform_Generic.ini
4. Edit your OSD Task Sequence and insert a new folder Configure Dell BIOS.  I prefer to insert this at the Preinstall phase of the task sequence, although it technically can be applied anytime before the Apply Operating System image step in the task sequence.  This is because we reconfigure the SATA operating mode to the highest level that the BIOS is capable of, RAID On, AHCI, ATA, respectively.

5. You must also remember to create evaluations in the options of this new folder to ensure that the PC is actually running in WinPE and that the Manufacturer is Dell.

6. The next step is optional, but recommended for easily troubleshooting BIOS configuration issues.  Create a step called Connect to Network Drive.  This drive will be used for dumping log files in a subsequent step.

7. After optionally mapping a network drive, it’s time to perform the actual configuration.  It’s recommended that you read through the cmd file and make appropriate modifications to best suite your environment.

8. We must restart the computer to have the BIOS settings take effect.  This is particularly important for the SATA operation to ensure that the appropriate storage drivers are installed.  Make sure you reboot to WinPE, there is no operating system installed yet.

9. After rebooting, we need to re-load the toolkit package and run the gather step again.

license: MIT

branch_name: refs/heads/master

extension: markdown

license_type: permissive


text:
# Stockholm-ticket-art
Stockholm ticket art competition

This is a personal art-project for Stockholm Ticket Art. It is an inofficial, rolling contest by some interested in ticket-art in the Stockholm area.

The purpose is art, and nothing else. This entry is a submission of one individuals (with the unknowing help of others and their skill) artistic intepretation of the Stockholm SL tickets.
Remember that it is a serious crime in Sweden to use fake-tickets.

# In order to view on mobile, Android device:

Get the .zip file on to your Android phone, and extract it.

Get the app Local HTML Viewer, and open index.html

You may now enjoy your ticket-art.

# Do not use as fake-ticket in Sweden as it is very illegal and would constitute forgery!

![Screenshot](screenshot.png)

license: Unlicense

extension: md


text:
## Reference models

### Content
This folder provides the reference models to be used for SAS testing.

This includes:

  - `geo/`: the geo data drivers and distance calculation routines.
  - `propagation_models/`: the Winnforum ITM and Hybrid propagation models.
  - `antenna/`: the antenna gain calculation.
  - `ppa/`: the PPA zones creation.
  - `interference/`: interference calculation on protected entities (except dpa).
  - `move_list_calc/`: the DPA move list calculation.
  - `iap/`: The IAP (Iterative Allocation Process) algorithm.
  - `pre_iap_filtering/`: Pre IAP filtering, including purge algorithms.

The `examples/` folder provides an example of using the models for FSS protection,
which exercise the ITM model, antenna gain calculation and geo routines.

### Setup
In order to use the reference models, you should:
 - have your PYTHONPATH pointing to the top level harness/ directory
 - configure the geo/CONFIG.py paths towards the geo databases.
 - compile the propagation model extension modules

See the specific README.md for more details.

### Setup Validation
You can validate your setup by using the script:

```
    python test_config.py
```

If everything properly installed, the script will end with a SUCCESS message,
otherwise follow the provided instruction to complete your setup.

You can also validate that the scripts are performing as expected by launching
the unit tests:

In Linux:
```
    ./run_all_tests_py2.sh
    ./run_all_tests_py3.sh
```

In Windows:

```
    python -m unittest discover -p '*_test.py'
    python3 -m unittest discover -p '*_test.py'
```

gha_language: Python


text:
# Local Vitess cluster using docker-compose

This directory has a docker-compose sample application.
To understand it better, you can run it.

First you will need to [install docker-compose](https://docs.docker.com/compose/install/).

### Start the cluster
To start Consul(which saves the topology config), vtctld, vtgate and a few vttablets with MySQL running on them.
```
vitess/examples/compose$ docker-compose up -d
```

### Check the status of the containers
You can check the logs of the containers (vtgate, vttablet1, vttablet2, vttablet3) at any time.
For example to check vtgate logs, run the following;
```
vitess/examples/compose$ docker-compose logs -f vtgate
```

### Load the schema
We need to create a few tables into our new cluster. To do that, we can run the `ApplySchema` command.
```
vitess/examples/compose$ ./lvtctl.sh ApplySchema -sql "$(cat create_test_table.sql)" test_keyspace
```

### Create Vschema
Create Vschema
```
vitess/examples/compose$ ./lvtctl.sh ApplyVschema -vschema '{"tables": {"messages": {} } }' test_keyspace
```

### Run the client to insert and read some data
This will build and run the `client.go` file. It will insert and read data from the master and from the replica.
[See Possible Errors.](#common-errors "Go to common errors")
```
vitess/examples/compose$ ./client.sh
```

### Connect to vgate and run queries
vtgate responds to the MySQL protocol, so we can connect to it using the default MySQL client command line.
```
vitess/examples/compose$ ./lmysql.sh --port=15306 --host=<IP_ADDRESS>
```

### Play around with vtctl commands

```
vitess/examples/compose$ ./lvtctl.sh Help
```

## Exploring

- vtctld web ui:
  http://localhost:15000

- vttablets web ui:
  http://localhost:15001/debug/status
  http://localhost:15002/debug/status
  http://localhost:15003/debug/status

- vtgate web ui:
  http://localhost:15099/debug/status

## Troubleshooting
If the cluster gets in a bad state, you most likely will have to stop and kill the containers. Note: you will lose all the data.
```
vitess/examples/compose$ docker-compose kill
vitess/examples/compose$ docker-compose rm
```

## Advanced Usage

### External mysql instance
The compose example has the capability to run against an external mysql instance. Kindly take care to secure your connection to the database.
To start vitess against unsharded external mysql, change the following variables in your .env file to match your external database;
```
KEYSPACE=external_db_name
DB=external_db_name
EXTERNAL_DB=1
DB_HOST=external_db_host
DB_PORT=external_db_port
DB_USER=external_db_user
DB_PASS=external_db_password
DB_CHARSET=CHARACTER SET utf8 COLLATE utf8_general_ci
```

Ensure you have log bin enabled on your external database.
You may add the following configs to your conf.d directory and reload mysqld on your server
```
vitess/config/mycnf/master_mysql56.cnf
vitess/config/mycnf/rbr.cnf
```

### Start the cluster
```
vitess/examples/compose$ docker-compose up -d
```

### Check replication status
Once vitess starts, check if replication is working
```
vitess/examples/compose$ ./lfixrepl.sh status
```

### Fix replication
To fix replication, place a mysqldump of the database in vitess/examples/compose/script with filename 'database.sql'
You may then run the following command
```
vitess/examples/compose$ ./lfixrepl.sh
```

### Apply Vschema
Apply Vschema for the unsharded keyspace
```
vitess/examples/compose$ ./lvtctl.sh ApplyVschema -vschema '{"sharded":false, "tables": {"*": {} } }' external_db_name
```

### Connect to vgate and run queries
vtgate responds to the MySQL protocol, so we can connect to it using the default MySQL client command line.
```sh
vitess/examples/compose$ ./lmysql.sh --port=15306 --host=<host of machine containers are running in e.g. <IP_ADDRESS>, docker-machine ip e.t.c>

mysql> show databases;
+--------------------+
| Databases          |
+--------------------+
| external_db_name   |
+--------------------+
1 row in set (0.00 sec)
mysql> use external_db_name@master or use external_db_name@replica or use external_db_name@rdonly;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> use external_db_name@replica;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> show tables;
+--------------------------------------------+
| Tables_in_external_db_name                 |
+--------------------------------------------+
| DATABASECHANGELOG                          |
| ......................                     |
| table_name_1                               |
| table_name_2                               |
| ......................                     |
|                                            |
+--------------------------------------------+
29 rows in set (0.00 sec)
```

## Helper Scripts
The following helper scripts are included to help you perform various actions easily
* vitess/examples/compose/lvtctl.sh
* vitess/examples/compose/lmysql.sh
* vitess/examples/compose/lfixrepl.sh

You may run them as below
```
vitess/examples/compose$ ./lvtctl.sh <args>
```

To run against a specific compose service/container, use the environment variable **$CS**

```
vitess/examples/compose$ (export CS=vttablet2; ./lvtctl.sh <args> )
```

## Common Errors

1. Running ./client.sh may generate the following error
```sh
vitess/examples/compose$ ./client.sh
Inserting into master...
exec failed: Code: FAILED_PRECONDITION
vtgate: ...vttablet: The MySQL server is running with the --read-only option so it cannot execute this statement (errno 1290) ...
exit status 1
```
To resolve use the [SetReadWrite](../../doc/Troubleshooting.md#master-starts-up-read-only) command on master.
```sh
vitess/examples/compose$ ./lvtctl.sh SetReadWrite test-1

```

2. Running ./lvtctl.sh ApplyVschema -vschema '{"sharded":false }' may result in an error referenced by this [issue](https://github.com/vitessio/vitess/issues/4013 )

A quick fix for unsharded db is;
```
vitess/examples/compose$ ./lvtctl.sh ApplyVschema -vschema '{"sharded":false, "tables": {"*": {} } }' external_db_name
```

repository: yjicfdx/vitess

repo_name: yjicfdx/vitess


text:
# Purifit

Purifit Product Page

## Packages/Plugins used

- styled-components

- @fortawesome/react-fontawesome

- @fortawesome/fontawesome-svg-core

- @fortawesome/free-solid-svg-icons

- gatsby-transformer-remark

## File Structure

-  **components** - all the individual components like header, footer

-  **images** - all the images used in the site

-  **pages** - all the route pages foreg for route /blog page is blog.js

-  **posts** - folder to organize all the markdown files

-  **templates** - template for the individual blog page

Clone the repo and run the app

```sh
gatsby develop
```

Your site is now running at `http://localhost:8000`!

*Note: You'll also see a second link: `http://localhost:8000/___graphql`. This is a tool you can use to experiment with querying your data.

repository: PurifitDevTeam/Purifit

gha_language: JavaScript

gha_license_id: MIT

repo_name: PurifitDevTeam/Purifit


text:
# parse-commit-args-action

Parses the last commit and parses user input arguments (eg. --my-arg [val]). Adds helpful default arguments for
release detection and docker. (versio, is_release, is_pull_request ...)

Allows for:
1. Overriding default args (see overrideable column). (i.e. override version, or is_release for example)
1. Select which events allow args reading.
1. Select argument format via regex. (e.g !!my-arg)

#### If you like it, star it, so other people would also use it.

# TL;DR

```yaml
name: 'Test action'
on:
  pull_request:
    branches:
      - 'master'
  release:
    branches:
      - 'master'
    types:
      - created
  push:
    branches:
      - master
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: 'parse_commit_args'
        id: args
        uses: LamaAni/parse-commit-args-action@master
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

      - name: 'show args'
        run: echo "$THE_ARGS"
        env:
          THE_ARGS: '${{ toJSON(steps.args.outputs) }}'

      - name: 'run on release only'
        if: ${{steps.args.outputs.is_release=="true"}}
        run: echo "$THE_ARGS"
        env:
          THE_ARGS: '${{ toJSON(steps.args.outputs) }}'

      - name: 'run on use falg only'
        if: ${{steps.args.outputs.my_flag=="120"}}
        run: echo "$THE_ARGS"
        env:
          THE_ARGS: '${{ toJSON(steps.args.outputs) }}'

```

To activate the user flag,

```shell
git add . && git commit -m"Some commit text --my_flag 120" && git push
```

To override `is_release`,

```shell
git add . && git commit -m"Some commit text --my_flag 120 --is_release true" && git push
```

# Default output arguments

Name | Description | Overrideable
---|---|---
ref | The name of the branch/tag or the pull request number | true
ref_type | The reference type (tags, heads, ...) | true
ref_group | The reference group type (refs ..) | true
is_release | If true, this is a release event | true
is_pull_request | If true, this is a pull request | true
event_name | The name of the github event | true
action | The executing action type (opened, closed ...) | true
default_branch | The repo default branch (defaults to master) | true

user_name | The name of the user/actor that triggered the action | true
user_type | The type of the user/actor that triggered the action | true

pull_request_merged | If true, this action is a result of a merged pull request | true
pull_request_state | "closed" "open" | true
pull_request_base_ref | The base ref for the pull request (merge to) | true
pull_request_head_ref | The head ref for the pull request (merge from) | true
pull_request_merged | If true the pull request has been merged | true
pull_request_is_open | If true the pull request is now open | true
pull_request_active | If true the pull request is active (open and !merged) | true
pull_request_url | The url for the PR | true

version | The detected version (defaults to branch, head or tag). Will match the release name, or the pull request head name | true
 | |
versions | Spaced out value. Decomposition of the version using a split char (for use in docker releases). eg. fancy.0.1.12 -> fancy fancy.0, fancy.0.1 fancy.0.1.12 | false
last_commit | The last commit | false
commits | A collection of associated commits | false
commit_message | The last commit message | false

args_as_json | All the arguments as json output. For easy pass between jobs | false

# Environment variables

Name | Description | Default value
---|---|---
LOAD_MESSAGE_ARGUMENTS_ON_EVENTS | Controls which github events( release, push...) are allowed to load user commit message args. Otherwise these are ignored. null or empty means all, none never load args | ''
VERSION_MARKER_SPLIT_SYMBOL| A symbol to split the cascading versions | .
ARG_MATCH_REGEX | A regex pattern to detect an input argument word (eg. --my-arg). Will join all match groups to create the full argument. |  /[-]{2}([a-zA-Z0-9][\w-]+)/g
ARG_REGEX_GROUP_JOIN_SYMBOL | Join symbol for between match groups | _
RUN_SCRIPT | A javascript script to run after the parameters have been evaluated. Run in method `async (args)=>{}` | empty
RUN_SCRIPT_FILE | A javascript file to run after the parameters have been evaluated. expects, `module.exports=async (args)=>{}` | empty

# Licence

Copyright ©
`Zav Shotan` and other [contributors](../../graphs/contributors).
It is free software, released under the MIT licence, and may be redistributed under the terms specified in [LICENSE](LICENSE).

repository: cbsi-cmg/parse-commit-args-action

repo_name: cbsi-cmg/parse-commit-args-action


text:
# Udemy Downloader with DRM support
[![forthebadge](https://forthebadge.com/images/badges/built-with-love.svg)](https://forthebadge.com)
[![forthebadge](https://forthebadge.com/images/badges/designed-in-ms-paint.svg)](https://forthebadge.com)
[![forthebadge](https://forthebadge.com/images/badges/made-with-python.svg)](https://forthebadge.com)
[![forthebadge](https://forthebadge.com/images/badges/approved-by-george-costanza.svg)](https://forthebadge.com)
![GitHub forks](https://img.shields.io/github/forks/Puyodead1/udemy-downloader?style=for-the-badge)
![GitHub Repo stars](https://img.shields.io/github/stars/Puyodead1/udemy-downloader?style=for-the-badge)
![GitHub](https://img.shields.io/github/license/Puyodead1/udemy-downloader?style=for-the-badge)
# NOTE

This program is WIP, the code is provided as-is and I am not held resposible for any legal issues resulting from the use of this program.

# Support

if you want help using the program, join [my discord server](https://discord.gg/5B3XVb4RRX) or use [github issues](https://github.com/Puyodead1/udemy-downloader/issues)

# License

All code is licensed under the MIT license

# Description

Simple program to download a Udemy course, has support for DRM videos but requires the user to aquire the decryption key (for legal reasons).<br>
Current only Windows is supported but with some small modifications it should work on linux also (and maybe mac)

# Requirements

1. You would need to download `ffmpeg` and `mp4decrypter`from Bento4 SDK and ensure they are in path (typing their name in cmd invokes them).

# Usage

_quick and dirty how-to_

You will need to get a few things before you can use this program:

- Decryption Key ID
- Decryption Key
- Udemy Course ID
- Udemy Bearer Token

### Setting up

- rename `.env.sample` to `.env`
- rename `keyfile.example.json` to `keyfile.json`

### Aquire bearer token

- open dev tools
- go to network tab
- in the search field, enter `api-2.0/courses`
- ![Valid udemy api requests](https://i.imgur.com/Or371l7.png)
- click a random request
- locate the `Request Headers` section
- copy the the text after `Authorization`, it should look like `Bearer xxxxxxxxxxx`
- ![bearer token example](https://i.imgur.com/FhQdwgD.png)
- enter this in the `.env` file after `UDEMY_BEARER=` (you can also pass this as an argument, see advanced usage for more information)

### Aquire Course ID

- Follow above before following this
- locate the request url field
- ![request url](https://i.imgur.com/EUIV3bk.png)
- copy the number after `/api-2.0/courses/` as seen highlighed in the above picture
- enter this in the `.env` file after `UDEMY_COURSE_ID=` (you can also pass this as an argument, see advanced usage for more information)

### Key ID and Key

It is up to you to aquire the key and key id.

- Enter the key and key id in the `keyfile.json`
- ![keyfile example](https://i.imgur.com/wLPsqOR.png)
- ![example key and kid from console](https://i.imgur.com/awgndZA.png)

### Start Downloading

You can now run `python main.py` to start downloading. The course will download to `out_dir`, chapters are seperated into folders.

# Advanced Usage

```
usage: main.py [-h] [-d] [-b BEARER_TOKEN] [-c COURSE_ID] [-q QUALITY] [-l LANG] [--skip-lectures] [--download-assets] [--download-captions]

Udemy Downloader

optional arguments:
  -h, --help            show this help message and exit
  -d, --debug           Use test_data.json rather than fetch from the udemy api.
  -b BEARER_TOKEN, --bearer BEARER_TOKEN
                        The Bearer token to use
  -c COURSE_ID, --course-id COURSE_ID
                        The ID of the course to download
  -q QUALITY, --quality QUALITY
                        Download specific video quality. (144, 360, 480, 720, 1080)
  -l LANG, --lang LANG  The language to download for captions (Default is en)
  --skip-lectures       If specified, lectures won't be downloaded.
  --download-assets     If specified, lecture assets will be downloaded.
  --download-captions   If specified, captions will be downloaded.
```

- Passing a Bearer Token and Course ID as an argument
  - `python main.py -b <Bearer Token> -c <Course ID>`
- Download a specific quality
  - `python main.py -q 720`
- Download assets along with lectures
  - `python main.py --download-assets`
- Download assets and specify a quality
  - `python main.py -q 360 --download-assets`
- Download captions (Defaults to English)
  - `python main.py --download-captions`
- Download captions with specific language
  - `python main.py --download-captions -l en` - English subtitles
  - `python main.py --download-captions -l es` - Spanish subtitles
  - `python main.py --download-captions -l it` - Italian subtitles
  - `python main.py --download-captions -l pl` - Polish Subtitles
  - `python main.py --download-captions -l all` - Downloads all subtitles
  - etc
- Skip downloading lecture videos
  - `python main.py --skip-lectures --download-captions` - Downloads only captions
  - `python main.py --skip-lectures --download-assets` - Downloads only assets

# Getting an error about "Accepting the latest terms of service"?

- If you are using Udemy business, you must edit `main.py` and change `udemy.com` to `<portal name>.udemy.com`

# Credits

- https://github.com/Jayapraveen/Drm-Dash-stream-downloader - For the original code which this is based on
- https://github.com/alastairmccormack/pywvpssh - For code related to PSSH extraction
- https://github.com/alastairmccormack/pymp4parse/ - For code related to mp4 box parsing (used by pywvpssh)
- https://github.com/lbrayner/vtt-to-srt - For code related to converting subtitles from vtt to srt format


text:
# List of work items

## Bug fix

- [ ] invisible headers/footers though settings exist in styles.css and headers-footer.css;
- [x] possible word bleeding in tables/simpletables;
- [x] sequence of toc: move the list of figures and list of tables to the end of toc;
- [x] abnormal hyphenation in tables

## features

- [ ] customized icons for:
  - [x] note and its variants by attribute value;
  - [x] hazardstatement and its variants by attribute value;
  - [x] relevant local paths in root folder:
   - C:\Program Files\Oxygen XML Editor 23\frameworks\dita\lw\css\img for LwDITA
   - C:\Program Files\Oxygen XML Editor 23\frameworks\dita\css\img for DITA, transformation scenario = HTML5 & CSS
   - p4v path: //Solutions/Documentation/Library/Templates/Art/Rebrand

- [ ] NI-styled side bar for left and right pages
- [x] Customized Font. Relevant local path:
  - C:\Program Files\Oxygen XML Editor 23\frameworks\dita\css\fonts for DITA, transformation scenario = HTML5 & CSS
- [ ] Customized cc_config for LwDITA, relevant local path:
  - C:\Program Files\Oxygen XML Editor 23\frameworks\dita\lw\resources for LwDITA
  - C:\Program Files\Oxygen XML Editor 23\frameworks\dita\resources for DITA 1.3
- [x] ditaval settings for templates:
    + project
    + product
    + customer
    + year
    + module

## Sample Project

- A sample project created in oxygen;
- It should contain at least 2 conditional texts in current STS templates;
- The conditional texts should be converted to ditavals;
- Fill the metadata for maps, topics.
- Keydef and keyref should be used for certain frequently used phrases;
- Conref should be used for content including copyright, legal notice, compliance chapter;

Structure:

Bookmap
  - Frontmatter
  - Chapters
  - Glossary
  - Relation tables

repository: iesdocs/styles

branch_name: refs/heads/main

repo_name: iesdocs/styles


text:
Classic service example: URL shortener
===

Average reading time: 10-15 minutes.

<!-- markdown-toc start - Don't edit this section. Run M-x markdown-toc-refresh-toc -->
**Table of Contents**

- [Classic service example: URL shortener](#classic-service-example-url-shortener)
    - [Abstract](#abstract)
    - [Database choice](#database-choice)
    - [URL shortener algorithm choice](#url-shortener-algorithm-choice)
    - [Data partitioning](#data-partitioning)
    - [Other possible improvements](#other-possible-improvements)
    - [Additional services](#additional-services)
    - [Actual deployment configuration with Kubernetes on Azure](#actual-deployment-configuration-with-kubernetes-on-azure)
    - [Load testing on Azure](#load-testing-on-azure)

<!-- markdown-toc end -->

``` sh
go test -cover
PASS
coverage: 70.1% of statements
ok      github.com/hqhs/url-shortener/service   0.019s
```

## Abstract

This is a thought experiment about engineering url-shortener service with high
load capabilities. Any corrections are welcome!

## Database choice

  Let's say average long URL size is 2kb. Additionally I want to record
statistics, such as Unix timestamp and IP request address for each click. Keep
in mind that I may add more statistics in future. 10 bytes for timestamp and 16
bytes for IP (with IPv6 support) sounds reasonable. Statistics is not
implemented at all (yet), but in the world of data driven advertising losing
opportunity to collect useful info is not very realistic.

bit.ly statistics from ([source]( http://highscalability.com/blog/2014/7/14/bitly-lessons-learned-building-a-distributed-system-that-han.html )):
  - 6 * 10^9 clicks/month
  - 6 * 10^8 shortens/month,
  - average click/link is 10, but maximum click per link could be anything.

 6 * 10^9 * 26 bytes + 6 * 10^8 * 2 kb = 1.35 terabytes/month

 I need to choose database wisely. Take into account that data has high
read/write ratio, never changes, is not structured (even with users structure would
be slightly structured), and the record size is small (around 2kb).

 I don't need relational database -- data is too simple, not column stored, thus
there's no need for searching/sorting, not a graph db -- there's no graph, not
document stored -- this is not the fastest available option. What I need is
key/value store, which is reliable out of the box, easy to scale, and easy to
get up and running.

 So, for bit.ly comparable traffic I can use AerospikeDB, Apache
Cassandra, Riak, or DynamoDB (those are the most popular, there are other choices).

 Remember, that statistics above were taken from startup which has URL
shortening and analytics service as its **primary** product. Just copy-pasting
their architecture (and choosing hadoop) solutions doesn't fit because I can't
**expect** such traffic. And I'm not competent enough for building
infrastructure capable to withstand **real** high load traffic (though someday I
will be), so for purpose of making a working demo I'm going with redis cluster
and implement database connection as golang interface, which allows us to
quickly change database when needed.

## URL shortener algorithm choice

- **Option 0: Simple counter stored in database**:
Store counter in database. To enforce shortening of URLs being longer then N chars,
counter should start with 64^N, since service uses base64 url-safe encoding.
For new URL get current counter value, encode it, and use as a key. Increment
after usage.

Issue: It's easy to iterate over all URLs.
- **Option 1: Hash based algorithm with counter**:
Hash requested URL, base64 encode hash result, take first N chars, check that
received key is unique in database. To enforce different keys for the same URLs
hash use counter technique from previous variant.

Issue: It's slows down over time. Let's calculate degradation speed.
Given N=6 there are ~6^64 or ~10^50 possible keys. With 6 * 10^8 request/month
(bit.ly load rate from above), that's 7.2 * 10^9 per year and ~10^11 per 15
years. After 15 years 10^11 / 10^50 = 1/10^39 of all possible keys will be used.
Practically speaking, every new key is random and has 1/10^39 probability to be
already used. So, on average, every 1/10^39 request makes additional database
request after 15 years of bit.ly load rate.

- **Option 2: Zookeper**:
Use separate (let's call it zookeper) service which pre-generates keys for
service nodes. When node bootstraps or runs out of keys it requests a new set of
unique keys from zookeper and uses it.

Issue: Zookeper is a single point of failure and adds unnecessary entities.

First option has good price/performance ratio. I'm going with it.

## Data partitioning

  Data partitioning is heavily based on database of your choice, but with
"practically speaking" random URL shortening algorithm service could
split urls between master nodes (if any) based on their shortened versions.

## Other possible improvements

- Caching. We can start with 20% caching of daily traffic and adjust that value when
needed. Least Recently Used (LRU) is reasonable policy for our system.
- Load balancing. Initially simple Round Robin approach would suffice. After
noticeable traffic growth more complex algorithm with back pressure support is
needed.
- Throttling and graceful degradation.
- Telemetry.
- Health checking.

## Additional services

  It's a good idea to move data gathering to a separate service with column based
database (such as ClickHouse). For this particular feature we need to add a
method to distinguish users from each other. For example, generate unique
cookie (or allow users to register themselves) for each user, build profile with
their interests based on their requested URLs, and show advertising based on
this profile (or just sell data). The simplest way to find correlation between a URL
and interests is to parse destination page's SEO metatags. Other way to monetize
(bit.ly uses it) is analytics selling to registered users (such as click rate etc.)

repository: hqhs/url-shortener

repo_name: hqhs/url-shortener


text:
---
title: Use with Inertia
weight: 6
---

> Inertia.js lets you quickly build modern single-page React, Vue, and Svelte apps using classic server-side routing and controllers.

Laravel Data works excellent with [Inertia](https://inertiajs.com).

You can pass a complete data object to an Inertia response:

```php
return Inertia::render('Song', SongsData::from($song));
```

## Lazy properties

This package supports [lazy](https://spatie.be/docs/laravel-data/v3/as-a-resource/lazy-properties) properties, which can be manually included or excluded.

Inertia has a similar concept called [lazy data evaluation](https://inertiajs.com/partial-reloads#lazy-data-evaluation), where some properties wrapped in a closure only get evaluated and included in the response when explicitly asked.

This package can output specific properties as Inertia lazy props as such:

```php
class SongData extends Data
{
    public function __construct(
        public Lazy|string $title,
        public Lazy|string $artist,
    ) {
    }

    public static function fromModel(Song $song): self
    {
        return new self(
            Lazy::inertia(fn() => $song->title),
            Lazy::inertia(fn() => $song->artist)
        );
    }
}
```

Now within your JavaScript code, you can include the properties as such:

```js
Inertia.reload((url, {
    only: ['title'],
});
```

repository: izisoft/laravel-data

repo_name: izisoft/laravel-data


text:
# lexbelt
A tool to provision Amazon Lex using YAML or JSON

Amazon Lex is amazing, except it has very low automation.  There's no CloudFormation (CFN) for it for it.

Also, when trying to create or update anything, the CLI wants you to pass in a checksum so it can figure out if it needs to update or create, this can be annoying.

`lexbelt` fixes all this.

```
usage: lexbelt [<flags>] <command> [<args> ...]

AWS Lex CLI utilities

Flags:
  -h, --help             Show context-sensitive help (also try --help-long and --help-man).
      --profile=PROFILE  AWS credentials/config file profile to use
      --region=REGION    AWS region
  -v, --version          Show application version.

Commands:
  help [<command>...]
    Show help.

  put-slot-type --name=NAME <file>
    Adds or updates a slot type

  put-intent --name=NAME <file>
    Adds or updates an intent

  put-bot --name=NAME [<flags>] <file>
    Adds or updates a bot

  export [<flags>]
    Export existing AWS Lex configs and write to workspace
```
## Getting lexbelt
Easiest way to install if you're on a Mac or Linux (amd64 or arm64)  is to use [Homebrew](https://brew.sh/)

Type:

```
brew tap sethkor/tap
brew install lexbelt
```

For other platforms take a look at the releases in Github.  I build binaries for:

|OS            | Architecture                           |
|:------------ |:-------------------------------------- |
|Mac (Darwin)  | amd64 (aka x86_64)                     |
|Linux         | amd64, arm64, 386 (32 bit) |
|Windows       | amd64, 386 (32 bit)                   |

Let me know if you would like a particular os/arch binary regularly built.

Lexbelt expects your workspace to look like this:
```
your-lex-workspace
   ├──slots
   ├──intents
   └──bots

```
The reason why is that it intelligently looks for dependecies when deploying bots or intents and will automatically
deploy any dependecies needed.

Lexbelt supports publishing, that is promoting the `$LATEST` version to the next incremental version number.  This is
done by passing the `--publish` flag with the command.

If you deploy a bot at it or intents has a dependecy on something who's version is `$LATEST` in hte spec you provide,
lexbelt will publish the dependencies and provision new elements with the correct version id's you have just published.

The yaml/json syntax for slots, intents and bots are all based directly of the AWS API Put API calls, so any attribute
supported by the AWS API will be supported in the API now or in the future can be included in a yaml file

The tool won't handle mixing json and yaml within a bot (e.g. yaml bot, json intent or slot, etc), pick one and stick with it.

## Lex Bot Odd Behaviour
AWS Lex does do some weird stuff.

### Bot versioning
For instance if your attempt to create a new version of a slot or an intent and
nothing has actually changed, you'll get the last version number returned.  Smart.  However, if you try to create a new
version of abot and nothing has actualy changed, you'll get a new version number.  This inconsistency is a bit annoying.

### 409 ConflictException
Once a new bot is published, there seems to be some asynchronous AWS magik still going on in the background.  Any
subsequent request to publish the bot again can trigger a HTTP response 409 ConflictException.  Wait a minute and try it
again, it will work. I'm guessing this is related to the build process.

### AWS UI doesn't refresh or is slow
This happens quite often.  Some times it requires waiting for the page to load or in the case of an alias, clicking on
other settings before clicking on Aliases again.

### TODO
* Any other feature requested.
* Windows Testing

repository: sethkor/lexbelt

gha_language: Go

repo_name: sethkor/lexbelt


text:
hxPixels
========

An _hxperimental_ (cross-target/cross-lib) Pixels abstract, in Haxe 3.1+

Simple interface to access/manipulate pixel values among different targets and libs, having a way to get/set individual pixels (or bytes), and be able to apply them back to the original source (taking care of framework-specific details under the hood).

### API

For the supported libs the following methods are implemented (**note** that all color values are in ARGB format):

 - `get`/`setPixel32()`: get/set pixel value (with alpha) at `x`,`y`
 - `get`/`setPixel()`: get/set pixel value (without alpha) at `x`,`y`
 - `get`/`setByte()`: get/set byte value at `i`
 - `clone()`: make a duplicate of the `Pixels` instance
 - `fillRect()`: fill a rect area with pixel value (with alpha)
 - `bytes`: access to the _raw_ underlying bytes (in source-specific format)
 - `format`: change internal color mapping

### Supported classes/libs

 - `BitmapData`: flash, openfl and nme (and `applyToBitmapData()` for flambe+flash)
 - `Texture`: for flambe (`applyToFlambeTexture()` only for html, due to limitations imposed by Stage3d)
 - `BufferedImage`: for java
 - `ImageData`: for plain js
 - `Texture` and `AssetImage`: for snow/luxe

### Implementation

`Pixels` is an abstract over `haxe.io.Bytes`. It stores the raw bytes in the underlying `bytes` var (in source-specific color format), auto-converting to ARGB when using get/set methods (see other branches for the inverse approach).

### Usage
See the [src folder](https://github.com/azrafe7/hxPixels/tree/master/src) for examples on how to use it, and file issues if you have problems or spot a bug.


text:
---
layout: post
section-type: post
title: March 1st, 2017 Meeting Record
category: hours
---

![UniGDC Logo](/img/logo_2016-2017.png)

## UniGDC Official Meetings Record

### Board Members Present
 - All board members are present.

### Content

#### Club Related
 1. No special club events were discussed.

#### Game Related
 1. Reviewed the final design of the game.
 2. Confirmed the tutorial script has been done.
 3. Concept arts were made.
     - Player will be choosing either a male protagonist or a female protagonist.
     - The protagonist character will grow as players progress to the next level.
 4. For more specific discussion, please refer to the #meetings text channel of UniGDC Discord server.
     - [Visit the main page](/) for a link to the server.

gha_language: HTML


text:
python-blueback
===============

**This project is abandoned and incomplete, though it does work. Use [Ruby gem backup](https://github.com/meskyanichi/backup) instead.**

python-blueback is a cloud backup utility, it backs up files on your server to cloud storage. Configurations are done in ini-style files. There is a `blueback` executable, it is designed to run from cron.

I had big plans for this, like backing up databases directly, backing up over SSH (rsync/sftp), and other stuff. Then I found the [Ruby gem backup](https://github.com/meskyanichi/backup) by Michael van Rooijen, which does everything I wanted blueback to do, except is doesn't use a nice machine writable config format. I may re-write all the config parsing in Ruby to make the backup gem use YAML or ini-style configs. That's why this is called 'python-blueback' and not 'blueback'.

## Configuration ##
By default python-blueback reads config files from /etc/blueback.conf and any .conf file in /etc/blueback.d/. You can pass `-c file.conf` on command line. Or pass arguments on command line, use `-h` or `--help` for a list of args.

python-blueback runs 'jobs', which are named in the ini section heads. The [main] section is inherited by all jobs.

```
[main]
destination_type=s3
destination_container=s3bucket.exmaple.com
destination_key=YOUR_S3_KEY
destination_secret=YOUR_S3_SECRET

# This job is named 'test'
[test]
# Path on the bucket (subfolder)
destination_path=/testbackup
# Prefix for the backup file
destination_prefix=backtests
# Path to source to backup
source_name=./backuptests
```

## Testing ##
```
git clone https://github.com/antoncohen/python-blueback.git
cd python-blueback
vim test.conf  # Enter your S3 bucket and creds
. pythonpath.sh  # Adds current dir to python path
bin/blueback -c test.conf test  # Runs the test job
```

* Anton Cohen<EMAIL_ADDRESS>* [Source](https://github.com/antoncohen/python-blueback)
* [Homepage](http://www.antoncohen.com/)
* [@antoncohen](http://twitter.com/antoncohen)

repository: antoncohen/python-blueback

repo_name: antoncohen/python-blueback


text:
# Matlab JSON

tbxmanager-compatible redistribution of the [matlab-json](https://github.com/kyamagu/matlab-json) package by Kota Yamaguchi.

## Installation
```
tbxmanager install matlabjson
```

## Building (for package maintainer only)

1. bump the version number in `tbxmake.m`
2. run `tbxmake`

repository: kvasnica/matlabjson

repo_name: kvasnica/matlabjson


text:
## About winforms

WinForms is the informal term given to Windows Forms, one of the graphical application programming interface (API) included as a part of Microsoft .NET Framework. WinForms provides access to the native Microsoft Windows interface elements by wrapping the existing Windows API in managed code.

WinForms is the informal name given to Windows Forms, the graphical application programming interface (API) included as a part of Microsoft's [.net](http://stackoverflow.com/questions/tagged/.net "show questions tagged '.net'") framework, which provides access to the native Microsoft Windows interface elements by wrapping the existing [windows-api](http://stackoverflow.com/questions/tagged/windows-api "show questions tagged 'windows-api'") in managed code.[Wikipedia](http://en.wikipedia.org/wiki/Windows_Forms)

A Windows Forms application is an event-driven application supported by Microsoft's .NET Framework. Unlike a batch program, it spends most of its time simply waiting for the user to do something, such as fill in a text box or click a button.[Wikipedia](http://en.wikipedia.org/wiki/Windows_Forms#Architecture)

Windows Forms is still supported by Microsoft. In addition to the Microsoft .NET Framework, Windows Forms is available in [Mono](http://www.mono-project.com/WinForms).

**MSDN Library**

*   [Windows Forms Documentation](https://msdn.microsoft.com/en-us/library/dd30h2yb(v=vs.110).aspx)

**Comparisons with [wpf](http://stackoverflow.com/questions/tagged/wpf "show questions tagged 'wpf'")**

*   [When creating a new GUI, is WPF the preferred choice over Windows Forms?](http://stackoverflow.com/questions/57909/when-creating-a-new-gui-is-wpf-the-preferred-choice-over-windows-forms)

**Visual Studio Extensions for WinForms Controls**

*   [Telerik UI for WinForms](http://www.telerik.com/products/winforms.aspx)
*   [DevExpress WinForms Controls](https://www.devexpress.com/Products/NET/Controls/WinForms/)
*   [Infragistics WinForms](http://www.infragistics.com/products/windows-forms/)

**Tutorials**

*   [WinForms User Controls 101](http://blogs.msmvps.com/deborahk/winforms-user-controls-101/)
*   [WinForms For Beginners](http://homeandlearn.co.uk/csharp/csharp.html)

Code Language (used for [syntax highlighting](http://google-code-prettify.googlecode.com/svn/trunk/README.html)): default

  default


text:
The deployment for Kubernetes 1.13 uses CSI 1.0 and thus is
incompatible with older Kubernetes releases.

The sidecar images rely on the CRDs for CSIDriverInfo and CSINodeInfo,
which were replaced with builtin APIs in Kubernetes 1.14. They can be
deployed on Kubernetes 1.14 if the CRDs are installed, but features
relying on these CRDs (like topology) are unlikely to work.

repository: bshouse/csi-driver-host-path

repo_name: bshouse/csi-driver-host-path


text:
# Mission lib

This package includes utils to manage UAVs in the PX4 mission flight mode via mavros for fixed wing, VTOL and multicopters.

### Dependencies ###

* [ROS Kinetic](http://wiki.ros.org/kinetic/Installation/Ubuntu)
* [geodesy (from geographic_info)](http://wiki.ros.org/geodesy): `sudo apt install -y ros-${ROS_VERSION}-geodesy`

repository: joselusl/grvc-utils

repo_name: joselusl/grvc-utils


text:
---
title: 'July 29th Friday'
date: '1994-7-29'
---

Go to the first level in the world and go to the old faucet. This is a famous place in history. When it comes to it, it feels like this. There are too many people to write the words "the first pass in the world". The whole building has its own characteristics in ancient Chinese architecture. From a historical perspective, there is a lot of history here.

The old faucet is at the end of the Great Wall and has entered the sea. Shanhaiguan’s place name also makes sense, probably the place where the mountain and the sea meet. Unfortunately, ancient nature is not complete, with a lot of commercial colors. A large number of rented emperors and empress clothing photos on the stalls above, there are electronic computer fortune telling, playing games, lifting the sedan chair, etc., made a fancy, township. Coupled with these stalls, the crowds are screaming for the sound of buying, which makes people suddenly lose their nostalgic mood.

Why can't these stalls be put outside?  This has cultural problems and is also a cultural issue of a nation. It seems that most of the people who come here also have a sense of play, not a sense of history. In this way, these stalls have a market. When these places are clean, we have history, and the people know history. The biggest problem for Chinese people is that there is too much history and too heavy, so no one wants to take on too much history.

In the "first pass in the world", our party also took pictures of the emperor, which is completely a kind of adventure. But why is the emperor attractive to people? Not the other? This is another mystery.

Get a poem:

First step in the world

The millennium ramp has been walked,

Wall inscriptions, poems and wines.

Qin Diwei has a new building,

Ginger female tears in the old stone.

One Guan Guomen faucet vertical,

Miles chest rock stay.

Canglang Gulai lost the flag,

The Great Wall breaks the current.


text:
# Invoking Rake Tasks Multiple Times

I have a rake task, `build`, that builds a single record for development
purposes.  To keep things dry, `build:all` should just invoke
`build` a number of times.

```ruby
namespace :build do
  task :all do
    predefined_list.each do |data|
      Rake::Task["build"].invoke(data)
    end
  end
end
```

This doesn't work though. No matter how many items are in the list, the
`build` task only seems to get run once. This is because by default tasks
can only be invoked once in a given context. To get around this, the task
needs to be _reenabled_ after each invocation.

```ruby
namespace :build do
  task :all do
    predefined_list.each do |data|
      Rake::Task["build"].invoke(data)
      Rake::Task["build"].reenable
    end
  end
end
```

repository: jbranchaud/til

gha_language: Vim Script

repo_name: jbranchaud/til


text:
Midisurf
================

Midisurf is an Audiosurf/GuitarHero-like game based on Midi files. It is created in 2019 for the 1985 Atari ST computer, and is written in C. At the start of the game, a Midi file from disk has to be selected. This Midi file is being played on the Atari ST YT sound-chip, while the player(s) of the game have to press keys on the keyboard at the right time to 'play along' the Midi track.

Playing Midisurf
-------------

The game features two dragons from the Earthsea lore by Ursula K. Le Guin: 'Kalessin' and 'Orm Embar'. These dragons can score points by picking up notes from the Midi track as they are played, and can move left and right to do so:

    * Press '<' to move Kalessin left
    * Press '>' to move Kalessin right
    * Press 'x' to move Orm Embar left
    * Press 'c' to move Orm Embar right

The two dragons can be controlled by a single player or by two players on a single Atari ST, as scores are counted separately for them. The game can be stopped by pressing the escape key.

The Atari ST's sound-chip has three channels, and as such Midisurf was implemented to work with at most three Midi tracks. If a Midi file has more tracks, the player is asked to select the tracks he or she wants to use for the game.

Example Midi tracks that work well with the game are provided in the `testmidi` subfolder, see [here](testmidi/README.md) for more information.

An example of what the game looks like:

![Midisurf gameplay example](docs/gameplay.png)

Or watch the [Midisurf gameplay video](docs/gameplay.mp4). You can also try out Midisurf in the browser, but it is without audio unfortunately.

Limitations
-------------

The game is currently limited in the following ways:

* It is designed mainly for an Atari ST with a high-resolution (640x400 black & white) screen, although it can also be played with some limitations on a 320x200 low-resolution colour screen

* Tunes are most recognizable with just the main Midi track and notes playing, so it is recommended to remove any background Midi tracks and supporting keys upfront, e.g. using a tool like [MidiEditor](https://www.midieditor.org/)

* Certain features of Midi tracks are not supported yet and parsing those tracks will result in an error

Compilation
-------------

Midisurf can be cross-compiled on a modern UNIX/Windows system with the [freemint Atari-ST GCC compiler](https://github.com/freemint/m68k-atari-mint-gcc) as follows:

    m68k-atari-mint-gcc src/*.c -DHIGH_RES -o midisurf.prg -lgem

That however results in a relatively large binary (~160KB), so alternatively with [mfro0's libcmini](https://github.com/mfro0/libcmini) (v0.491 has bugs so use the master branch or a newer version when released) you can obtain a binary of around 35KB:

    m68k-atari-mint-gcc -nostdlib $LIBCMINI/startup.o src/*.c -DHIGH_RES -o midisurf.prg -s -L$LIBCMINI -lcmini -lgcc -lgem

When running with a low-resolution colour screen, replace the above `-DHIGH_RES` with `-DLOW_RES`.

When running it on the Atari ST or an emulator, make sure you run it as a GEM application rather than TOS (otherwise the mouse won't show).

Alternatively, for development and debugging purpose (to some extent), it can be compiled and run (but without graphics, audio or gameplay) on a UNIX system by setting the `UNIX` define. For convenience, this can be done with CMake, e.g.:

    mkdir build && cd build
    cmake ..
    make
    ./midisurf

For debugging purpose, Clang's address sanitizer can be used on a UNIX system to check for overflows and memory leaks by compiling and running as follows:

    clang -g -fsanitize=address -fno-omit-frame-pointer -DUNIX src/*.c -DHIGH_RES -o midisurf.unix && ./midisurf.unix && rm midisurf.unix

Running Midisurf on an emulator
-------------

If you don't own an Atari ST or just want to test the game first before you write it to a floppy disk, you can run Midisurf on an Atari ST emulator such as [Hatari](https://hatari.tuxfamily.org/). After setting up the emulator, select the high resolution screen (640x400), and then either:

* Mount one of the Atari ST image releases (`mdsrf_X.Yh.st`) as floppy A or B

* Mount the contents of one of the release archives (`mdsrf_X.Yh.zip`) as a hard disk

* Compile your own `midisurf.prg` from the repository and mount the folder as a hard disk along with the other files in this repository (at least *.bpm and *.rsc).

repository: CNugteren/midisurf

repo_name: CNugteren/midisurf


text:
# Stargate

[![Build Status](https://travis-ci.org/sapcc/stargate.svg?branch=master)](https://travis-ci.org/sapcc/stargate)
[![Docker Repository](https://img.shields.io/docker/pulls/sapcc/stargate.svg?maxAge=604800)](https://hub.docker.com/r/sapcc/stargate/)

The Stargate opens a gate from [Slack](https://slack.com) to the several systems to enable interaction with these :)
The primary gate opens to the [Prometheus Alertmanager](https://prometheus.io/docs/alerting/alertmanager) so one can respond to alerts from Slack.

## Features

- Respond to Prometheus alerts from the Slack messenger.
- Silence alerts in the Prometheus Alertmanager using interactive Slack messages.
- Acknowledge alerts in the Alertmanager and incidents in Pagerduty using interactive Slack messages.
- Visualize acknowledged and silenced alerts in [Grafana](https://grafana.com/) using the Stargate and the [Prometheus Alertmanager datasource](https://github.com/sapcc/grafana-prometheus-alertmanager-datasource).

Currently, the stargate only supports **Slack** as a messenger and the **Prometheus Alertmanager**, **Pagerduty** as receiver.

## Installation, Configuration, API

See the [installation guide](./docs/install.md) as well as the [API documentation](./docs/api.md).

Minimal configuration of the Stargate:
```yaml

slack:
  # provide signing_secret or verification token to verify messages sent by slack
  verification_token:   <string>

  # stargate oauth token. required
  access_token:         <string>

  # members of these slack user groups are authorized to interact with slack messages
  authorized_groups:
    - admin
    - ...

alertmanager:
  # URL of the Prometheus Alertmanager
  url: <string>
```

See the [full Stargate configuration example](./etc/stargate.yaml).
Also see the [Prometheus Alertmanager configuration](./etc/alertmanager.yaml) and the corresponding [Slack template](./etc/slack.tmpl).
Full example via helm chart is available [here](https://github.com/sapcc/helm-charts/tree/master/global/prometheus-alertmanager).

repository: sapcc/stargate

repo_name: sapcc/stargate


text:
# HGAP

this means SMRT Suite

Assembly with PacBio data

PacBio is a company that uses a technology called single molecule real time (SMRT) sequencing. This produces very long sequencing reads (up to xx?). These raw sequencing reads can be assembled into genomes by using the software from PacBio, called the SMRT Portal.

link: http://www.pacb.com/smrt-science/
link: http://www.pacb.com/products-and-services/analytical-software/smrt-analysis/

info:
https://github.com/PacificBiosciences/Bioinformatics-Training/wiki/Large-Genome-Assembly-with-PacBio-Long-Reads

Background:
assembly
galaxy
cmdline?

Start
Open your GVL dashboard.

Go to Admin. There is a list of packages. Find SMRT Analysis. On the right, click on "Install".  (Note: you will need 16 cores in your GVL).

open up the link and log on (create a username and password I think)
FIXME

Sepsis Data
e.g. https://downloads-qcif.bioplatforms.com/bpa/sepsis/pacbio/

e.g. one sample
it will be split into three files ?
for each sample: need the bas file? and the xml

but not the subreads

bas.h5 Reference Guide (PDF):
Describes the main output files produced by the primary analysis pipeline: bas.h5,.1.bax.h5, .2.bax.h5, and .3.bax.h5. The bax.h5 files contain base call information from the sequencing run. The bas.h5 file is essentially a pointer to the three bax.h5 files.
Metadata Output Guide (PDF): Describes the file metadata.xml, which contains top-level information about the data, including what sequencing enzyme and chemistry were used, sample name, and other metadata.

which files to put over into sepsis gvl

Input data
from here [link]

Import and Manage
Import SMRT cells: SMRT Cells
shows file paths that are searched
add
(so should have made folder, put smrt cells data in there, and then tell it this path using "add")

How it works
The PacBio SMRT analysis software: de novo assembly.

link: http://www.pacb.com/products-and-services/analytical-software/smrt-analysis/analysis-applications/de-novo-assembly/
Several options, but for example HGAP + BridgeMapper:
RS_HGAP Assembly.3
pre-assembly
de novo assembly with AssembleUnitig
finalise assembly with Quiver

RS_Bridgemapper
assesses assembly quality by comparing to a reference genome.

Run

give job name and comments
choose a protocol
click on the data you want (how to get in) and then arrow to transfer it to right pane
run
click on the monitor tab
as it runs, new items will appear on the left hand side under reports, e.g. starting with filtering
graphs will appear for some items, e.g. mapped subread length, what does it mean
new data sets will appear under on the left hand side under data eg polished assembly fastq.
click on top right corner - log (to check for anything?)

Output
when finished, go to view data tab; click on job name, open (what is SMRT view? another option)

shows all reports and data files
e.g. assembled genome

download any or leave in here?
main assembly parameters /reports - what to check
how do you know assembly is good

https://github.com/PacificBiosciences/Bioinformatics-Training/wiki/Finishing-Bacterial-Genomes

-- good detail in here

Next

Links to more information

gha_language: Makefile


text:
This section describes how it's possible to deploy a Prometheus server for scraping metrics from the Kafka cluster and showing them using a Grafana dashboard. The provided resources for deploying can't be considered production grade; they are used just as an example to show how it's possible to use the metrics feature provided in this project.

If you are going to use `minikube` or `minishift` for your Apache Kafka deployment adding Prometheus and Grafana servers, it would be better to increase the default amount of memory available to the virtual machine (i.e. not using the default 2 GB of RAM but 4 GB instead).
For doing that, you can start the OpenShift cluster by running

```
minishift start --memory 4GB
```

In case you want to use Kubernetes instead, you can run

```
minikube start --memory 4096
```

# Deploying on OpenShift

## Prometheus

The Prometheus server configuration uses a service discovery feature in order to discover the pods in the cluster from which it gets metrics.
In order to have this feature working, it's necessary to provide access to the API server to get the pod list to the service account used for running the Prometheus service pod (the service account `prometheus-server` is used).

```
export NAMESPACE=[namespace]
oc login -u system:admin
oc create sa prometheus-server
oc adm policy add-cluster-role-to-user cluster-reader system:serviceaccount:${NAMESPACE}:prometheus-server
oc login -u developer
```

where `[namespace]` is the namespace/project where the Apache Kafka cluster was deployed.

After that, it's possible to deploy the Prometheus server in the cluster :

1. Create the [provided "prometheus" template](prometheus/openshift-template.yaml) by running

        oc create -f metrics/prometheus/openshift-template.yaml

2. Create a new app using the "prometheus" template:

        oc new-app prometheus

## Grafana

A Grafana server is necessary only to get a UI for the Prometheus metrics. You can use the following [project](https://github.com/OpenShiftDemos/grafana-openshift) which you need to clone locally.

From the `grafana-openshift` directory, run

```
chmod +x root/usr/bin/fix-permissions
chmod +x run.sh
```

to set "execute" permissions on the above scripts and then run

```
oc new-build --binary --name=grafana
oc start-build grafana --from-dir=. --follow
```

to start the image building process inside the OpenShift cluster.
After a while, the grafana image will be available in the internal Docker registry of the OpenShift cluster and the last step is just creating a new application with the provided image.

```
oc new-app grafana
```

# Deploying on Kubernetes

## Prometheus

The Prometheus server configuration uses a service discovery feature in order to discover the pods in the cluster from which it gets metrics.
In order to have this feature working, it's necessary to provide access to the API server to get the pod list to the service account used for running the Prometheus service pod (the service account `prometheus-server` is used) if the RBAC is enabled in your Kubernetes deployment.

```
export NAMESPACE=[namespace]
kubectl create sa prometheus-server
kubectl create -f metrics/prometheus/cluster-reader.yaml
kubectl create clusterrolebinding read-pods-binding --clusterrole=cluster-reader --serviceaccount=${NAMESPACE}:prometheus-server
```

where `[namespace]` is the namespace/project where the Apache Kafka cluster was deployed.

Finally, create the Prometheus service by running

        kubectl apply -f metrics/prometheus/kubernetes.yaml

## Grafana

A Grafana server is necessary only to get a UI for the Prometheus metrics. You can use the following [project](https://github.com/OpenShiftDemos/grafana-openshift) which you need to clone locally.

From the `grafana-openshift` directory, run

```
chmod +x root/usr/bin/fix-permissions
chmod +x run.sh
```

to set "execute" permissions on the above needed scripts.
If you are using `minikube` for running the Kubernetes cluster then you have to build the Grafana image inside the cluster itself in order to have it available in the internal Docker registry. To use the Docker environment in `minikube` run

```
eval $(minikube docker-env)
```

After that it's possible to build the image by running

```
docker build -t strimzi/grafana:latest .
```

Finally you can execute the actual deployment by running

```
kubectl apply -f metrics/grafana/kubernetes.yaml
```

# Grafana dashboard

As an example and in order to visualize the exported metrics in Grafana, the simple dashboard `kafka-dashboard.json` JSON file is provided.
Following these steps you'll be able to set up the Prometheus data source in Grafana and adding the above dashboard.

> If your cluster is running using `minikube` or `minishift`, you can use the `port-forward` command for forwarding traffic from the Grafana pod to the host. For example, running `oc port-forward grafana-1-fbl7s 3000:3000` (or using `kubectl` instead of `oc`) you can access the Grafana UI opening your browser and pointing to the `http://localhost:3000`.

1. Access to the Grafana UI using `admin/admin` credentials.

![Grafana login](grafana/images/grafana_login.png)

2. Click on the "Add data source" button from the Grafana home in order to add Prometheus as data source.

![Grafana home](grafana/images/grafana_home.png)

3. Fill in the information about the Prometheus data source, specifying a name and "Prometheus" as type. In the URL field you have to specify the connection string to the Prometheus server (i.e. `http://prometheus:9090`). Click on "Add" and after that, Grafana will test the connection with the data source.

![Add Prometheus data source](grafana/images/grafana_prometheus_data_source.png)

4. From the top left menu, click on "Dashboards" and then "Import" for opening the "Import Dashboard" window where you can import the provided dashboard uploading the JSON file or copying/pastying its content.

![Add Grafana dashboard](grafana/images/grafana_import_dashboard.png)

5. After importing the dashboard you should see it in your Grafan home with first metrics about CPU and JVM memory usage. You can start to use the Kafka cluster, creating topics and exchanging messages in order to see the other metrics like messages in, bytes in/out per topic.

![Kafka dashboard](grafana/images/grafana_kafka_dashboard.png)


text:
# StructuredLogger

A structured logger with Ruby's Logger interface.

[![License X11](https://img.shields.io/badge/license-X11-brightgreen.svg)](https://raw.githubusercontent.com/nishidayuya/structured_logger/master/LICENSE.txt)
[![Gem Version](https://badge.fury.io/rb/structured_logger.svg)](http://badge.fury.io/rb/structured_logger)
[![Dependency Status](https://img.shields.io/gemnasium/nishidayuya/structured_logger.svg)](https://gemnasium.com/nishidayuya/structured_logger)
[![Build Status](https://img.shields.io/travis/nishidayuya/structured_logger.svg)](https://travis-ci.org/nishidayuya/structured_logger)
[![Coverage Status](https://img.shields.io/codeclimate/coverage/github/nishidayuya/structured_logger.svg)](https://codeclimate.com/github/nishidayuya/structured_logger/coverage)
[![Code Climate](https://img.shields.io/codeclimate/github/nishidayuya/structured_logger.svg)](https://codeclimate.com/github/nishidayuya/structured_logger)

## Installation

### General Ruby application

Add this line to your application's Gemfile:

    gem 'structured_logger'

And then execute:

    $ bundle

Or install it yourself as:

    $ gem install structured_logger

### Rails application

Add to `Gemfile` (see previous section) and run `bundle`.

Write `config/initializers/structured_logger.rb`.

```ruby
# Use StructuredLogger instead of Logger.
l = StructuredLogger.new("log/#{Rails.env}.log")

# If you want timestamp and PID with ActiveSupport::TaggedLogging, enable next line.
#l.formatter = ::Logger::Formatter.new

# If you want tagging support, enable next line.
#l = ActiveSupport::TaggedLogging.new(l)

Rails.logger = l
```

Play it!

## Usage

We can write log with parameters.

```ruby
t = Time.now; sleep(0.1)
l = StructuredLogger.new(STDOUT)

l.debug("processed request", started_at: t, elapsed_sec: Time.now - t, status: "ok")
#=> D, [2015-08-21T05:14:37.022621 #8310] DEBUG -- : processed request: started_at=2015-08-21 05:14:36 +0900 elapsed_sec=0.100156444 status="ok"

l.debug { ["processed request", started_at: t, elapsed_sec: Time.now - t, status: "ok"] }
#=> D, [2015-08-21T05:15:00.214480 #8416] DEBUG -- : processed request: started_at=2015-08-21 05:15:00 +0900 elapsed_sec=0.100193648 status="ok"
```

`StructuredLogger` instance methods have Ruby's `Logger` interface. So, we can replace Ruby's `Logger` to `StructuredLogger`.

```ruby
l = Logger.new(STDOUT)
l.error("Something happend")
#=> E, [2015-08-25T06:43:18.244950 #23623] ERROR -- : Something happend

l = StructuredLogger.new(STDOUT)
l.error("Something happend")
#=> E, [2015-08-25T06:43:47.798889 #23623] ERROR -- : Something happend
```

Also we can use it with `ActiveSupport::TaggedLogging`.

```ruby
l = ActiveSupport::TaggedLogging.new(StructuredLogger.new(STDOUT))
l.tagged(:crawler) do
  l.tagged(:downloading) do
    l.warn("malformed file format", path: downloaded_path.to_s)
  end
end
#=> [crawler] [downloading] malformed file format: path="/opt/app/tmp/1234.bin"
```

## Development

After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake false` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.

To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`.

## Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/nishidayuya/structured_logger.

gha_language: Ruby


text:
Tango
=====

All right, I've done it.  In a classic example of NIH syndrome, I've invested a disproportionate amount of time in completely
reimplementing [Anki](http://ankisrs.net/) to create a stripped-down, buggy, inflexible version that slightly better fits my
workflow, stomping on the very philosophy that makes Anki so great in the process.  This is Tango, a flash-card study system
designed to help memorize vocabulary.  The name comes from the Japanese word for "vocabulary" (creative, I know), and the program is
strongly slanted toward studying Japanese, but I hope to make it more general in the near future.

Tango is very much in its early stages of development.  It is functional enough to meet most of my needs, but far too much is still
hardcoded into the program or done manually by me.  Expect this to change as the program matures.

Usage
-----

To build, just `cd` into the cloned source directory and run `cmake src && make`.  You will need the wxWidgets libraries (`wx-config
--version` should return 3 or greater) and SQLite 3 installed.

Tango uses a SQLite3 database at the user's `XDG_CONFIG_HOME/tango/decks.db` for storing configuration and practice data.  If this
file does not exist, it is created at startup, which should allow a user to start using Tango immediately, except for the "bank"
functionality.  The only ramification of this is that no cards will ever be placed in the "Kanji" set.

Decks, Cards, Sets
------------------

Each item for study in Tango is a *card*.  Unlike a real flashcard, a Tango card can have more than two "sides", or fields.
Currently, the fields are *temporarily* hardcoded into the program as "Expression", "Reading", and "Meaning".  Which fields to
display are selected according to "sets", explained momentarily.

Card are organized into *decks* based on the user's wishes; generally, cards in the same deck should be cards that are thematically
related to each other or cards that should be studied together.  Decks can be either *explicit* or *implicit*.  Explicit decks are
created explicitly by the user using the "Add" button in the decks panel and can have settings associated with them.  These settings
are stored in the database and persist between sessions.  Implicit decks are not stored in the database, but exist simply by virtue
of the fact that there is a card that thinks it is in that deck.  If all cards in an implicit deck are deleted or moved elsewhere,
the deck ceases to exist.  Implicit decks inherit their settings from their parent decks.  There is a special deck, the root deck,
that is explicit and undeletable and uses settings that are *temporarily* hardcoded into the project but will eventually be settable
through the preferences window.

How does a card "think" that it is in a deck?  In Tango, cards and decks are only loosely coupled.  A list of explicit decks is
stored in the database, and a "path" is stored for each card.  This path is a slash-delimited string describing where the card is.
For example, I may have two explicit decks in my database, called "1" and "1/2", as well as cards with paths "1", "1/2", "1/3", and
"4".  In this case, "1" is a top-level explicit deck, and "1/2" is an explicit subdeck of "1".  "1" also has an implicit subdeck,
"1/3", that exists because there is a card in it.  There is also an implicit top-level deck called "4".  If the card in "4" is
deleted, the deck will automatically disappear.  "1" and "1/2" have their own settings, but "1/3" inherits its settings from "1" and
"4" inherits its settings from the root deck.

Each deck has several *sets*.  A set is a collection of cards to be practiced together in a certain way.  Each set is associated
with a subset of the cards in the deck, as well as which fields of those cards to show as the "question" and "answer" of the card.
An example should clarify this.  When studying Japanese, I know the kanji (Chinese characters) for some of the words, but not for
others.  Therefore, for the cards whose kanji I know, I want to be shown the English meaning of the word and write down the kanji,
then be shown the kanji so I can check whether I was correct.  For other cards, I want to be shown either the Japanese reading or
the English meaning, guess the other, and then be shown the other so I can check myself.  Therefore, I will have a set called
"Kanji", which only contains cards whose kanji I know, whose "front" is the meaning and whose "back" is the kanji; and a set called
"Kana", which contains all the other cards, whose front is either the meaning or reading and whose back is the other.  At the
moment, the set setup is *temporarily* hardcoded in the sort of configuration I have just described, only a little more complicated;
all decks have four sets ("Normal", "All", "Kanji", and "Kana"), and each one  has rules for which fields to display for the
"front", the "back", and a "hint".  At the moment, this is pretty easy to use since it is completely unconfigurable; eventually I'll
make it configurable and the whole thing will get more complicated to use.

Sets also do not exist in the database; they are generated by the program when it starts up based on which cards are "due" for
studying.  A card can be in multiple sets -- indeed, the "All" set contains all cards in the deck, in case you want a thorough
go-over.  Cards are determined to be "due" based on how long it's been since you've studied them, but unlike Anki, Tango does not
work in real-time.  When you are ready to study more cards, click the right arrow button at the bottom of the decks pane to advance
every card in the system, and the next set of "due" cards will be presented.  You can also go back in time by clicking the left
arrow.  I plan to have an option eventually to automatically advance the cards every 24 hours, which will emulate Anki and restore
some of the time pressure that pushes you to study every day.

I mentioned earlier that I only want words with kanji I know to appear in the "Kanji" set.  To allow the program to know which kanji
I know, each explicit deck is associated with a "bank" of kanji.  This is one of the rather Japanese-specific aspects of Tango, and
I'm not sure yet how I'll generalize it to other languages and concepts.  The bank interface is still rather primitive and
incomplete, but more should be coming after I get some of the more major issues out of the way.

Studying
--------

Okay, how do you actually use Tango to study?  Assuming you have a populated database with some decks and cards (which, as I said,
will come soon), select the set you want to study within the deck you want to study (or select the deck name, in which case the
"Normal" set will be selected), and switch to the study pane.  The bottom status bar will display, from left to right, the current
set, the number of cards to be studied in that set, and the current study interval on the current card.  Use the following keys to
interact with the program:

  - `Enter`: Toggle displaying the "front" and "back" of the current card

  - `1`: Update the card with half of the current study interval.  That means that the current study interval displayed in the
    status bar will be halved and the card's due date will be updated to be that many steps in the future.  If the current study
    interval is 1 or 0, it will be updated to 0 and placed at the back of the set to be studied again this session.  Do this if you
    got the answer wrong or felt uncertain about your answer.

  - `2`: Update the card with the current study interval.  Do this if you got the answer right and feel moderately confident about
    it.

  - `3`: Update the card with twice the current study interval.  Do this if you got the answer right and feel very confident.  If
    the new study interval exceeds 365 days (this will eventually be configurable), the card will be marked "done" and you will not
    need to study it again.

  - `4`: Reset the card.  This sets its study interval to 0, marking it for immediate re-studying, and places it at the back of the
    current set.  Do this if you think the card needs to be studied again right away.

  - `5`: Suspend the card.  It will not be presented for study and the time until its next study will not be decremented until you
    un-suspend it through the cards pane.

  - `6`: Immediately mark the card "done".  It will not be presented for study any more.  There is currently no practical difference
    between marking a card "suspended" and "done"; it's merely for book-keeping.

  - `9`: Bury the card.  Move the card to the back of the set without updating it at all.  This allows you to "put off" studying a
    card.  This and all of the numpad number keys above "advance" the deck to the next card.

  - `H`: Toggle displaying the card hint.  Which field the hint is depends on the display settings.

  - `E`: Jump to the current card in the cards pane, allowing you to edit its fields or other properties.

  - `D`: Delete the current card from its deck and from the database.

  - `S`: Shuffle the set.

Thus, the standard study session consists of selecting a set to study, and then repeatedly looking at a card, thinking of the
correct answer, pressing `Enter` to check your answer, and pressing a number key based on how good your answer was.  The new status
of each card is saved immediately in the database after it is studied or edited, so there is no need to manually save.

More documentation will come as I have time to flesh out the program itself.

repository: showermat/tango

repo_name: showermat/tango


text:
# Vibration of a Rotating Cantilever Beam
This study demonstrates the natural frequency analysis of a cantilever beam subjected to centrifugal loading. This is analogous to the vibrations of compressor and turbine blades. The free and open-source finite element analysis software [CalculiX](http://www.calculix.de/) is used.

File| Contents|
:-------------| :-------------|
[rotating_cantilever_beam_pre.fbd](rotating_cantilever_beam_pre.fbd)| Pre-processing script for CalculiX GraphiX|
[rotating_cantilever_beam.inp](rotating_cantilever_beam.inp) | CalculiX input|
[rotating_cantilever_beam_post.fbd](rotating_cantilever_beam_post.fbd)| CalculiX GraphiX post-processing script|
[rotating_cantilever_beam_py.py](rotating_cantilever_beam_py.py)| Python script to run the example|
[rotating_cantilever_beam_tex.tex](rotating_cantilever_beam_tex.tex)| LaTeX file for the study report|
[rotating_cantilever_beam_tex.pdf](rotating_cantilever_beam_tex.pdf)| LaTeX output pdf for the study report|

## Parameters

| Parameter         | Value     | Unit      | Description                            |
| :-------------    |  :----    | :----     | :-------------                         |
| `r`               | 150       | mm        | Radius of the rigid disk               |
| `Omega`           | 4500      | rpm       | Rotational speed of the rigid disk     |
| `l`               | 328       | mm        | Lenght of the beam                     |
| `w`               | 28        | mm        | Width of the beam                      |
| `t`               | 3         | mm        | Thickness of the beam                  |
| `alpha`           | 0         | degrees   | Orientation of the beam                |
| `E`               | 2.1e5     | MPa       | Young's modulus of the beam materal    |
| `nu`              | 0.3       |           | Poisson's ration of the beam material  |
| `Etyp`            | he20r     |           | Element type of the beam (C3D20R)      |

## Description

The beam is built into a rigid disk of **_r mm_** radius, rotating about its axis at a speed of **_Omega rpm_**. It is **_l mm_** long, **_w mm_** wide, **_t mm_** thick, and makes an angle of **_alpha degrees_** with the rotation axis, as shown in the following [Figure](images/rotating_cantilever_beam.png).

    Figure Rotating cantilever beam.

## Pre-processing

The beam is made of steel, with a Young's modulus **_2.17e5 MPa_**, Poisson's ratio of **_0.3_** and a density of **_7.85e-9 tonne/mm^3_**.

The general purpose quadratic brick element with reduced integration (C3D20R) is used. The the beam is cantilevered at **_r = 150 mm_**. A rotational speed of **_Omega = 4500 rpm_** about the axis of the rigid disk is applied to the whole model. See the following [Figure](images/pre.png) for the finite element model of the rotating cantilever beam.

    Figure Finite element model of the rotating cantilever beam.

## Results

The first vibration mode is obtained as **_71.81 Hz_** from CalculiX. This result is can be compared with the results reported for Abaqus 6.6 in this [Reference](https://classes.engineering.wustl.edu/2009/spring/mase5513/abaqus/docs/v6.6/books/bmk/default.htm?startat=ch01s04ach43.html). Followign table shows the first three modes obtained with CalculiX.

| Mode         | Frequency [Hz]     |
| :-------------    |  :----        |
| 1                 | 71.807009     |
| 2                 | 243.222157    |
| 3                 | 273.155573    |

Following [Figure](images/post.png) shows the displacements of the first mode.

    Figure Mode 1 displacements in z-axis.

repository: QiangF/CalculiX-Examples

repo_name: QiangF/CalculiX-Examples


text:
---
title: Multi-Account Aws Environments
slug:
author: Carl Cassar
description: AWS recommends that you set up multiple accounts when your environment becomes more complex. This article outlines the benefits of multi-account environments and shows you how to get started.
tags:
  - aws
image:
link: https://www.carlcassar.com/articles/multi-account-AWS-environments
published_at: 2020-10-05 19:35:00
created_at: 2020-10-05 19:35:00
updated_at: 2020-10-05 19:35:00
deleted_at:
---
I first heard about the full potential of AWS Organisations in
[this excellent talk](https://www.youtube.com/watch?v=aISWoPf_XNE) on IAM Policies. I had seen this option in the
console before, but I thought it would be overkill to create an organisation with multiple accounts when I only had a
few small projects running on AWS at the time. Nowadays I make a new account for every new project I host on AWS. I love
the organisation and separation of concerns that this brings to my setup. It's given me a lot of confidence to
experiment with new AWS features and configurations.

## What is a multi-account environment?

 This might sound like it adds a lot of complexity to your setup, but it's actually very
simple to implement and brings a number of benefits in exchange.

AWS offers an easy way to manage multiple accounts under an AWS organisation in your root account. These new
"sub-accounts" can be grouped into organisational units (OUs), and arranged into a hierarchy that matches your
real-world needs.

[This article on best practices](https://aws.amazon.com/organizations/getting-started/best-practices/)
outlines a number of useful organisational units based on best practices from existing AWS customers.

## When should you set up a multi-account environment?

AWS [recommends](https://aws.amazon.com/organizations/getting-started/best-practices/) this as best practice as
soon as your workload grows in size and complexity.

In my opinion, the benefits are such that you should consider using this technique as soon as possible.

## Benefits of a multi-account AWS environment

1. **Experiment with confidence**

If you're anything like me, you felt pretty overwhelmed the first time you logged into the AWS console. As I'm writing
this, there are now [more than 175](https://en.wikipedia.org/wiki/Amazon_Web_Services) products and services on AWS,
ranging from storage to satellite communications and everything in between. What's more, the learning curve is pretty
steep, and the repercussions of making a mistake can be costly.

One of the best things you can do when learning to use Amazon Web Services is to set up a sandbox
account in which you can experiment freely, knowing you can tear down your resources when you are done. Of course,
its possible to set up a new root account with the same purpose, but then you wouldn't gain any of the other benefits
of a multi-account environment.

2. **Simpler, more accurate billing**

As soon as you're working on multiple projects, it becomes useful to know the total cost for the project
across all resources. If you're using a single AWS account you can track the cost of a project by using tags, but
there are several issues with this approach. First, there are some services that don't allow custom tags. Second,
tags have to be managed, updated and maintained, which could lead to some project costs being missed.

By using a separate account for projects, teams or departments, you can track costs accurately across all resources
created in that account. You can then see an overview of all costs across the organisation or drill down into the
charges for each account in the billing dashboard.

3. **Better organisation**

When you use a multi-account environment, you can enforce tag and backup policies for each account. What's
more, you'll be able to find resources quicker, making it much easier to build solutions that require several
resources to communicate with each other. Multiple accounts will enable you to adapt each account to the specific
needs of your project or team.

4. **Increased Security**

With each new account, you get a fresh set of IAM users, roles and policies. You can create completely different
security configurations for each account, giving you fine-grained control over access to your resources. This is
especially useful when projects need to meet strict compliance requirements or operate in a different region.

5. **Scale easier**

You never know when that side project might become your main stay. If you keep all your projects in one account, it can
be extremely tricky and time-consuming to retrospectively extract one of them to another account. If, on the other
hand, you create a new account for your project on day one, you can easily:
- give new users permission to access specific resources
- promote the account to a root account for accounting or other purposes
- hand over the account in the event that you sell the project
- take action quickly and efficiently in case something goes wrong.

## How to set up an AWS organisation

Follow these steps to create your AWS organisation:

1. Click on your name on the AWS Management Console.
2. Choose "My Organisation"
3. Choose "Create Organisation"
4. Choose "Enable all features or Enable only consolidated billing."
5. Choose "Create"

[See this article](https://aws.amazon.com/premiumsupport/knowledge-center/get-started-organizations/) to watch a short
video on how to set up your AWS organisation.

## How to add a new account to your organisation

Once you've created your organisation, you're ready to add another account. You can either create a new account or
invite an existing account to join your organisation.

Follow these steps to add a new account to your organisation:

1. Click on your name on the AWS Management Console.
2. Choose "My Organisation"
3. Chose "Add account"
4. Choose "Create account"
5. Fill in the "Account Name", "Email Address" and "IAM role name".
6. Add any tags that you want to add to the account.
7. Choose "Create"

The **IAM role name** specifies the name of a role that will be created by AWS in the new account and allow you to
gain access to it. The default value is `OrganizationAccountAccessRole`, which will grant the organisation full
administrative control over the new account.

## Conclusion

This setup may not be for everyone, but it can be a powerful option in your AWS toolbox when you outgrow your root
account. Personally, I wish I had known about this option sooner and haven't regretted the decision to use this
architecture for my own projects.

repository: carlcassar/carlcassar

filename: Multi-Account Aws Environments.md

repo_name: carlcassar/carlcassar


text:
---
title: "My thoughts on remote working"
date: "2022-05-25"
draft: true
---

Now that the worst of covid is hopefully behind us, many companies are "encouraging"
their staff to come back to the office and this is a problem for many.

Why are people so strongly against this? After all, we all used to work in an office before
COVID and many people complained about the downsides of working from home when it all started
two years ago.

The thing is - this is not a question of whether it's advantageous or not to come together and
collaborate IRL. It's a question of who decides when and how often it's advantageous.

Most of us have not only grew accustomed to working from home and arranged our lives around
the flexibility of it, but we've also realised we can be flexible and be more productive working
this way. It's a win-win for everyone.

So why are companies wanting to get people back into the office when home working is more productive and
makes their staff happier?

That's the question to ask your manager when they gently enourage you to go into the office more. Just ask
why. What problem have you noticed that you think this will fix?

If manager's are concerned about people slacking off, you can refer to the fact you've been perforing extremely
well (if not better) during 2 years of remote working.


text:
# tsusu protocol

**TODO. nothing in here makes sense, should rewrite it**

the protocol is:
 - used to communicate between the executable `tsusu` and the daemon
 - works via a single unix socket
 - very short-lived

## protocol outline

 - connect to `$XDG_RUNTIME_DIR/tsusu/sock`
 - receive `HELO`
 - send a request
 - get a reply
 - close socket

### why only a single request/response pair

it is a cli app, there isn't much of a need to allow continuous
request/response pairs for means other than automation.

**TODO** check if this is actually needed, we may need to change
the daemon architecture to allow long-lived clients for purposes
like attaching to existing processes (don't know how to do that yet)

## requests and their responses

**TODO**

### LIST

**TODO**