text:
---
title: React Component Composition with Dot Notation Exports
date: '2021-05-18'
description: Co-locating React components and using them together with dot notation
---

## Intended Audience

Beginner and intermediate React developers looking to learn more about the dot notation export pattern with React components.

## Example

We'll take a look at what a modal component might look like with the dot notation export pattern. The demo uses React with Styled Components.

Let's jump right into the code.

```jsx
// Modal.js
import styled from 'styled-components'

export const Button = styled.button.attrs(() => ({ type: 'button' }))`
  // button styles
`

export const Heading = styled.h2`
  // heading styles
`

export const Body = styled.p`
  // body styles
`

export const Wrap = styled.div`
  // outer modal styles
`

Modal.Heading = Heading;
Modal.Body = Body;
Modal.Button = Button;

export function Modal({ isVisible, children }) {
  return (
    <Wrap isVisible={isVisible}>
      {children}
    </Wrap>
  )
}

---

// ParentComponent.js
import { useState } from 'react'
import { Modal } from '../components/Modal'

export function ParentComponent() {
  const [isModalVisible, setModalVisible] = useState(false)

  return (
    <>
      <Modal isVisible={isModalVisible}>
        <Modal.Header>Hello, I am a Modal</Modal.Header>
        <Modal.Body>I can show helpful information</Modal.Body>
        <Modal.Button onClick={() => setModalVisible(false)}>
          Hide Modal
        </Modal.Button>
      </Modal>
      <button
        onClick={() => setModalVisible(true)}
        type="button"
      >
        Show Modal
      </button>
    </>
  )
}
```

Let's now go over what's happening in this example.

## Breakdown

The `Modal` component and some styled components are co-located and exported from `Modal.js`. We then use `Modal.Heading = Heading` pattern, for example, to allow for `Heading` to be used with the `Modal` export.

The parent component imports only `Modal`. The styled components may be used inside the `Modal`, depending on what's needed in the implementation, and they can be called with the dot notation pattern.

There are a few benefits to using this kind of pattern.

## Benefits

This pattern is useful when multiple components are often composed and used together. This can be useful because:

- Inversion of control: the user, and not the `Modal`, is not responsible for use cases

Let's say we were to build a version of the modal component that accepts props in place of children. Imagine it looks something like this.

```jsx
// Modal.js

export function Modal({ isVisible, header, body, buttonText, buttonOnClick }) {
  return (
    <Wrap isVisible={isVisible}>
      {header && <Header>{header}</Header>}
      {body && <Body>{body}</Body>}
      {button && <Button onClick={buttonOnClick}>{buttonText}</Button>}
    </Wrap>
  )
}

// ParentComponent.js
import { useState } from 'react'
import { Modal } from './Modal'

export function ParentComponent() {
  const [isModalVisible, setModalVisible] = useState(false)

  return (
    <>
      <Modal
        isVisible={isModalVisible}
        header="Hello, I am a Modal"
        body="I am receiving this data as props"
        buttonText="Ok"
        buttonOnClick={() => console.log('button clicked')}
      />
    </>
  )
```

This version of the modal is resposible for handling all the use cases from the props it gets, as well as the conditional rendering of components in cases where props are missing.

Let's say that the Modal's use cases get extended: a new implementation calls for an `<a>` tag instead of a button and an icon above the header text. The prop-based modal would need to accept these new props and add logic to handle all the use cases.

The composed version of the modal can simply expose a `<Modal.Icon>` and `<Modal.Link>` and let the user of the modal build out the use case, and the `Modal` component will render its children. The `Modal` inverts the control by letting the the user handle the use case, instead of handling it internally.

- Fewer import statements are needed to implement `Modal` and its children

`import { Modal } from '../components/Modal` instead of `import { Modal, Heading, Button, Body } from '../components/Modal'`

- Co-locating `Modal` with the components it's commonly used with

Keeping the `Modal` and all of its potential children in the same file for each on maintenance.

- The JSX communicates that `Modal` and its children are related

For example, we can more easily infer that these components are related

```jsx
<Modal>
  <Modal.Heading>Heading</Modal.Heading>
  <Modal.Body>Body</Modal.Body>
  <Modal.Button>Button</Modal.Button>
</Modal>
```

than these components

```jsx
<Modal>
  <Heading>Heading</Heading>
  <Body>Body</Body>
  <Button>Button</Button>
</Modal>
```

- TypeScript can help autocomplete the components

If you start typing `<Modal.`, TypeScript will show a list of the components you've assigned to `Modal`. The autocomplete helps with productivity (typing components faster) and discovery (showing which components are available).

React's `children` prop makes for component composition and dot notation is something you may be familiar with, especially from using open source libraries. React Navigation's [Stack.Screen](https://reactnavigation.org/docs/screen) comes to mind as well as React's own API [import pattern](https://reactjs.org/blog/2020/09/22/introducing-the-new-jsx-transform.html) of

```jsx
import * as React from 'react'

// React.useState, React.createContext, React.lazy etc.
```

## Alternatives

Without changing any of the code, we can just as easily import and use the components in `Modal.js` separately, without dot notation.

```jsx{3,11,12,13}
// ParentComponent.js
import { useState } from 'react'
import { Modal, Heading, Button, Body } from '../components/Modal'

export function ParentComponent() {
  const [isModalVisible, setModalVisible] = useState(false)

  return (
    <>
      <Modal isVisible={isModalVisible}>
        <Header>Hello, I am a Modal</Header>
        <Body>I can show helpful information</Body>
        <Button onClick={() => setModalVisible(false)}>Hide Modal</Button>
      </Modal>
      <button onClick={() => setModalVisible(true)} type="button">
        Show Modal
      </button>
    </>
  )
}
```

We can also choose not to co-locate the rest of the components with `Modal` and import them from elsewhere. This might be a good option if the `Button` needs to be used somewhere other than in the `Modal`. This option isn't mutually exclusive with the dot notation export, as `Modal.js` can still import the component it needs and re-export it to use with dot notation.

```jsx
// Modal.js
import { Button } from './Button'

Modal.Button = Button

export function Modal({ children }) {
  return (
    <div>
      Modal
      {children}
    </div>
  )
}
```

The component that imports `Modal` could then call `Modal.Button` just like in the above example.

repository: avedetvedea/blog

repo_name: avedetvedea/blog


text:
# README

Nested Yarn 2 install.

This directory and package.json contains only the dependencies needed to run the action.
It does not include any development dependencies. This is an explicit design choice.
Yarn 2 Zero Install is being used as a way to package `cspell` while avoiding the pitfalls of
WebPack breaking `cosmiconfig`.

But, Yarn 2 does not seem to have a "production" cache mode. This resulted in an action that
was more then 50 MB. Much too big, since the Webpack version was around 2 MB.

license: MIT

repository: streetsidesoftware/cspell-action

branch_name: refs/heads/main

extension: md

gha_language: JavaScript

gha_license_id: MIT

license_type: permissive

repo_name: streetsidesoftware/cspell-action


text:
# Dash Core for Fedora Linux
_...wallet, node, and masternode_

The most current source packages can be found in this directory:
<https://github.com/taw00/dashcore-rpm/tree/master/SRPMS>

From these source packages, Dash Core has been successfully built and
maintained for Fedora and RHEL/CentOS for years (starting with Fedora 23 or 24
and CentOS7). Build on the latest versions of Fedora please.

The original components used to build these packages come from:

* Tagged release builds / source archives:
  - Dash <https://github.com/dashpay/dash/releases>
  - Sentinel <https://github.com/dashpay/sentinel/releases>
  - Dash Masternode Tool  <https://github.com/Bertrand256/dash-masternode-tool/releases>

* Directly from the build system and non-tagged repositories:
  - Dash <https://bamboo.dash.org/browse/DASHL-DEV/latestSuccessful>
  - Sentinel <https://github.com/dashpay/sentinel>
  - Dash Masternode Tool  <https://github.com/Bertrand256/dash-masternode-tool>

Each RPM contains my own contributed imagery and configuration. If you wish to
browse my contributions, browse to this link and explore the directories ending
in `-contrib`:

<https://github.com/taw00/dashcore-rpm/tree/master/SOURCES/>

----

With these SRPMs one should be able to build binary RPMs for your
specific linux variety and architecture.

A source RPM (SRPM or .src.rpm) nicely packages up the source code of a
program/project and contains all the instruction needed to build (compile and
package) corresponding binary RPM packages. To include build requirements. In
the case of Dash, one source RPM will compile the code and generate all the
binary runnable RPM packages associated to the Dash project.

Important notes:

- All source is organized in directories named just like `rpmbuild` organizes
  things: `SOURCES/`, `SRPMS/`, `SPECS/`. The finalized RPMS are housed in the
  COPR repositories (Fedora Project) and not here (see repo configuration in the
  installation section).
- In this github repo, everything directly in the `source/` directory is
  **stable** and, of course, everything found in the `source/testing/` is
  experimental.
- Source archives with filenames ending in `-contrib.tar.gz` are my
  contributions and contain desktop icons and configuration; firewalld,
  systemd, and logrotation configuration; and more.

```bash
dashcore-rpm
 ├── SOURCES   ← stable code and contrib archive files
 ├── SRPMS     ← stable src.rpm packages
 │   └── archive
 └── SPECS     ← stable rpm spec files
    └── archive
```

- Only use **stable** versions on the mainnet (`testnet=0`).

  **Testing** versions are test versions and great to play with on the testnet
  (`testnet=1`). Please don't use them on the mainnet.

----

# Building from source RPM packages

#### [1]  Set up your Build environment

RPM? How? What?:
* <https://fedoraproject.org/wiki/How_to_create_an_RPM_package>
  (read especially "Preparing your system")
* <https://github.com/rpm-software-management/mock/wiki>
* <https://fedoraproject.org/wiki/Packaging:Versioning>

In order to build from a source RPM, you first need to set up your environment.
If you have not already, _**do this as your normal user (not root)**_ from the
commandline:

```bash
# Install needed packages
sudo dnf dnf-utils install @development-tools rpmdevtools rpm-sign fedora-packager
# create your working folder ~/rpmbuild/{SOURCES,SRPMS,SPECS,RPMS}
rpmdev-setuptree

# Add yourself to the mock group
# mock group membership allows you to build in mock build # environments
sudo usermod -a -G mock $USER
# refresh your login so that the new group shows up for this user
# (not as reliable as logging out and logging back in again)
newgrp -
```

***If that fails,*** you need to read more about setting up your development
environment at the link that was provided earlier.

Note, it suggests using a separate user on your system to build RPMs… you can
do that, but for our examples, I am assuming you are doing it with whatever
user you want. I execute these commands from my personal normal user account
usually.

**Configure mock**

Copy `/etc/mock/site-defaults.cfg` to `~/.config/mock.cfg`
```sh
mkdir -p ~/.config
cp -i /etc/mock/site-defaults.cfg ~/.config/mock.cfg
```
and then edit `~/.config/mock.cfg` and configure it similarly to this (this is
what I have uncommented and configured in mine.

```sh
# ~/.config/mock.cfg
config_opts['basedir'] = '/var/lib/mock/'
config_opts['cache_topdir'] = '/var/cache/mock'
config_opts['rpmbuild_networking'] = True
config_opts['bootstrap_module_enable'] = []
config_opts['bootstrap_module_install'] = []
config_opts['environment']['LANG'] = os.environ.setdefault('LANG', 'en_US.UTF-8')
# This is something I do. I use 'tree', 'vim', 'less' in my testing
config_opts['chroot_additional_packages'] = ['tree', 'vim-enhanced', 'less']
# I turn off "cleanup" when doing a lot of testing.
#config_opts['cleanup_on_success'] = 0
#config_opts['cleanup_on_failure'] = 0
```

#### [2] Download a source RPM of your choosing

For example, at the time of this writing the latest Dash Core (dashcore) src.rpm of version
`0.14`, is considered "stable". For the purposes of this document, we are
going use version-release `<IP_ADDRESS>-1.taw` as our example. Download the lastest
version that is specific to your linux distribution Fedora, CentOS, or RHEL. If
you are attempting to build in a different environment, download the source RPM
that as closely matches your platform and experiment away.

#### [3] Verify the RPM has not been tampered with

This is done with a GPG signature check.

**Verification of the source RPM's digital signature**

(1) Import my GPG key into your RPM keyring if you have not already done so.
You have to do this as the root user.

```bash
# As a normal user (not root)
sudo rpm --import https://keybase.io/toddwarner/key.asc
```

(2) Check the signature

`$ rpm --checksig -v dashcore-0.14.0.*.src.rpm` ...or...
`$ rpm -Kv dashcore-0.14.0.*.src.rpm`

You should see something like: `dashcore-<IP_ADDRESS>-1.taw.fc30.src.rpm: rsa sha1 (md5) pgp md5 OK`

*Notice the "pgp" and the "OK"*

And if you used the verbose flag, `-v`, then you should see my key ID: `694673ed`

If the output says something like
`(MISSING KEYS: RSA#694673ed (MD5) PGP#694673ed)`,
you did not successfully import my key in step 1.

Another way to look at this information is via...

`$ rpm -qpi dashcore-<IP_ADDRESS>-1.taw.*.src.rpm | grep 'Name\|\|Version\|Release\|Signature'`

#### [4] Install the source RPM

Again, from the command line as a normal user... First, move that source RPM into the source RPMs location in the rpmbuild build tree:

```bash
# As a normal user (not root)
mv dashcore-*.src.rpm ~/rpmbuild/SRPMS/
# Install the sucker (do not use sudo here!):
rpm -ivh ~/rpmbuild/SRPMS/dashcore-<IP_ADDRESS>-1.taw.fc30.src.rpm #Or whatever version you are installing.
```

That should explode source code and patch instruction into
~/rpmbuild/SOURCES/ and the build instructions into ~/rpmbuild/SPECS/.
Something like this...

```bash
~/rpmbuild/SPECS/dashcore.spec
~/rpmbuild/SOURCES/dash-<IP_ADDRESS>.tar.gz
~/rpmbuild/SOURCES/dashcore-0.14.0-contrib.tar.gz
```

#### [5] Build the binaries

One source RPM will often build multiple binary RPMs. In this case, six RPMs
are built (if you also build the optional debuginfo RPM). See them listed later
in this document.

_**mock and rpmbuild:**_ There are two ways to build RPMs, (1) by using `mock`
which is a wrapper around `rpmbuild` that creates an isolated build environment
(chroot) using a special use system user (mockbuild of the mock group) and
installs any needed BuildRequires into that environment without effecting your
workstation, or (2) directly with `rpmbuild` which requires you to install all
build requirements unisolated from your workstation environment.  _**We
recommend you use mock.** Mock is cool. Mock is awesome. Mock will change your
life._

**⸻ Method 1: mock (recommended)**

Reconstruct the source rpm.

```bash
# As a normal user (not root)
mock --buildsrpm --spec ~/rpmbuild/SPECS/dashcore.spec --sources ~/rpmbuild/SOURCES/ --resultdir ~/rpmbuild/SRPMS/
```

This will create a source package and place it in `~/rpmbuild/SRPMS/`. For
example `~/rpmbuild/SRPMS/dashcore-<IP_ADDRESS>-1.taw.fc30.src.rpm`

Now build it...

```bash
# As a normal user (not root)
# Hint hint: With mock you can build for targets that are not your OS version
#            and architecture!
mock -r fedora-31-x86_64 ~/rpmbuild/SRPMS/dashcore-<IP_ADDRESS>-1.taw.fc30.src.rpm --resultdir ~/rpmbuild/RPMS/
```

This will build packages in `~/rpmbuild/RPMS/` Note, if you did not add
`--resultdir`, mock would build the packages in the mock chroot tree, like
perhaps `/var/lib/mock/fedora-31-x86_64/root/builddir/build/RPMS/`. That chroot
tree gets blown away by default nearly every time you use mock (a good thing),
so... just fair warning.

If you want to noodle around the mock chroot, (a) add `--no-clean` to your mock commands above and (b) use the built in mock shell to look around...
```bash
mock --shell
# you will be "fakeroot" in that chroot, login as the mockbuild user...
su -l mockbuild
ll
pwd
```

When you are satisfied with the build, cleanup the mock environment and set it
back to it's original state...
```bash
# As a normal user (not root)
mock --scrub all
```

**⸻ Method 2: rpmbuild (works but not recommended)**

With this method, you use `rpmbuild` to execute the process. For example:

```bash
# As a normal user (not root)
cd ~/rpmbuild/SPECS
rpmbuild -ba dashcore.spec
```

Note, you may run into a failed build. Look at the BuildRequires in the .spec
file. For example, you may have to install a few RPMs first, like gcc-c++ and
and others. Or just note the output of the failed build and add the packages.
For example, I had to do something like this for a RHEL7 build...

**For Fedora:**
```bash
# As a normal user (not root) -- Note, this may not be comprehensive.
sudo dnf install gcc-c++ qt5-qtbase-devel qt5-linguist qrencode-devel miniupnpc-devel protobuf-devel openssl-devel desktop-file-utils autoconf automake boost-devel libdb4-cxx-devel libevent-devel libtool java python3-zmq zeromq-devel
```
**For CentOS7 and RHEL7:**
```bash
# As a normal user (not root) -- Note, this may not be comprehensive.
sudo yum install gcc-c++ qt5-qtbase-devel qt5-linguist qrencode-devel miniupnpc-devel protobuf-devel openssl-devel desktop-file-utils autoconf automake boost-devel libdb4-cxx-devel libevent-devel libtool java openssl-compat-bitcoin-libs python34
```

Manually adding those BuildRequires is a PITA and pollutes your sytem. This is
why I highly recommend you use `mock` instead of `rpmbuild`.

If all goes well, the build process may take 30+ minutes and nicely bog down
your computer. If the build succeeded, the build process will list the RPMS
that were created at the end of the terminal window output. The binary RPMs
will be saved in the _~/rpmbuild/RPMS/_ directory and a newly minted source RPM
will land in the _~/rpmbuild/SRPMS/_ directory. The binary RPMs will be
these...

* **dashcore-client** -- The dash-qt wallet and full node _(note, some older
  sources merely named this package "dash" and not "dashcore-client")_
* **dashcore-utils** -- dash-cli, a utility to communicate with and control a
  Dash server via its RPC protocol, and dash-tx, a utility to create custom
  Dash transactions.
* **dashcore-server** -- dashd, a peer-to-peer node and wallet server. It is
  the command line installation without a GUI.  It can be used as a commandline
  wallet and is typically used to run a Dash Masternode. Requires
  dashcore-utils to be installed as well.
* **dashcore-libs** -- provides libbitcoinconsensus, which is used by third
  party applications to verify scripts (and other functionality in the future).
* **dashcore-devel** -- provides the libraries and header files necessary to
  compile programs which use libbitcoinconsensus. Requires dashcore-libs to be
  installed as well.
* **dashcore-[version info].src.rpm** -- The source code -- the source RPM, or
  SRPM You want to build binaries for your RPM-based linux distribution? Use
  this source RPM to do so easily.
* **dashcore-debuginfo** -- debug information for package dash. Debug
  information is useful when developing applications that use this package or
  when debugging this package.  (99.999% of you do not need to install this)

***Are you impatient?*** Binaries for Dash Core have already been built for
these linux distributions. Again, reference the link provided at the beginning
of this document.

----

### Advanced: Creating your own monogrammed builds

If you are feeling a bit froggy, build and compile the binary RPM packages
specifically tagged with your name/initials.

Let's say your name is Barney Miller (initials "bm0").

```bash
# As a normal user (not root)
cp dashcore.spec dashcore.bm0.spec
```

* Edit `dashcore.bm0.spec`
* Change the _minorbump_ value in that file from 'taw' to 'bm0'
* Add a stanza in the changelog at the bottom reflective of what you did (copy
  the format)...

...and build your RPMs from that...

```bash
# versions are just examples...
# As a normal user (not root) -- rpmbuild method
#rpmbuild -ba dashcore.bm0.spec
# As a normal user (not root) -- mock method (recommended)
rpmbuild -bs dashcore.bm0.spec
mock -r fedora-31-x86_64 ~/rpmbuild/SRPMS/dashcore-<IP_ADDRESS>-1.bm0.fc30.src.rpm
```

If all goes to plan, in 30 or 40 minutes you should have a set of binary
packages, specifically built to your system with a release of '1.bm0'.

If there is a significant problem where you have to, for example, fix the
`configure.ac` file in the `dash-<IP_ADDRESS>.tar.gz` archive (common issue)... you
will have to do something like this:

* Copy the archive to some working director and then extract it...

      tar xvzf dash-<IP_ADDRESS>.tar.gz

* Copy the resultant (the original pristine) folder…

      cp -a dash-<IP_ADDRESS> dash-<IP_ADDRESS>.orig --

* Work on the `dash-<IP_ADDRESS>/configure.ac` file, build a new patch, and try to
  rebuild things (iterate iterate iterate). All that is a bit beyond this
  document, but this is a good place to start to understand RPMs:
  <https://fedoraproject.org/wiki/How_to_create_an_RPM_package>

Finally, once built and you are happy, instead of relying on sha256sum hash
verification, you can GPG sign your packages. For instruction, read these nice
summaries (hint, you will have to install the `rpm-sign` RPM first):

* http://fedoranews.org/tchung/gpg/
* http://blog.packagecloud.io/eng/2014/11/24/howto-gpg-sign-verify-rpm-packages-yum-repositories/

And if you are feeling really ambitious, you can set up a publicly facing dnf
(once called yum) repository and making your packages available through
super-automated means to the world (keep reading the Fedora documentation for
more information about yum and dnf).

---

### That should get you started! Good luck!

Got a dash of feedback? Send it my way: <https://keybase.io/toddwarner>

branch_name: refs/heads/master


text:
---
title: “What Are the Drums Saying, Booker?”
author: Adolph L. Reed, Jr.
lang: en
---

## _The Curious Role of the Black Public Intellectual_ {.subtitle-etc}

## Adolph L. Reed, Jr. {.subtitle-etc}

### 11 Apr. 1995 • _The Village Voice_ {.dateline}

_This essay was originally published with the subtitle, "The Current Crisis of
the Black Intellectual." The version provided here is drawn from Reed's
collected volume,_ [Class Notes](https://thenewpress.com/books/class-notes)
_(New York, 2000). You can read it
[in PDF](https://libcom.org/files/ReedWhatAreTheDrumsSayingBooker.pdf), if you
prefer._

＊ ＊ ＊

::: {#body-text .section}

In a typical episode of _Ramar of the Jungle_, an early television adventure
series, the two heroes of the show spend most of their time on safari, attended
to by a coterie of native bearers. Whenever they hear drums in the distance, the
whites summon their head bearer. "Willie, what are the drums saying?" Willie, a
Sancho Panza-like servant, steps forward. "Bwana, drums say simba come soon,
much danger." On noticing a furtive sullenness among the bearers, the hero again
inquires: "Willie, what's going on with the men?" Willie answers dutifully. "Men
afraid. Say they don't want to go into Leopard Men territory, afraid of evil
spirits."

In these vignettes, Willie was enacting the definitive role of the black public
intellectual---interpreting the opaquely black heart of darkness for whites. Of
course, this connection couldn't be observed at the time because the category
"black public intellectual" didn't yet exist. It wasn't invented until nearly
four decades later, when several youngish black professors with ties to and
visibility within the cultural studies/cultural politics precincts of the
academic left began using it to refer to themselves and one another. This group
includes most prominently Cornel West, Henry Louis Gates, Jr., Gloria Watkins
(bell hooks), Michael Dyson, and Robin Kelley, though others in that world no
doubt feel comfortable wearing the label. And people with varying professional
and political affiliations---like Stanley Crouch, Stephen Carter, and Shelby
Steele---increasingly turn up under the black public intellectual rubric, as the
Warholian imperatives of fame send it rippling through the culture. But this
identity is most clearly the product of the cultural wing of the left academy
and its extramural offshoots.

In the last months of 1994 and early 1995, the notion gained greater currency.
It has been addressed in successive articles by Michael Alan Bérubé in the _New
Yorker_ and Robert Boynton in the _Atlantic_, while Leon Wieseltier's
right-for-the-wrong-reasons attack on Cornel West in the _New Republic_ spawned
commentary by James Ledbetter and Ellen Willis in the _Voice_. Although these
white writers obviously didn't invent the black public intellectual identity,
they certainly anointed it as a specific, notable status in upper-middle-brow
American culture. Despite gestures in the direction of serious critical
analysis, the Bérubé and Boynton essays are really press releases. Their
explorations of their subjects' substantive output are thin and breezy. And I'm
certain that not all of the individuals on Boynton's rather ecumenical
list---the criterion for which seems to be "black people who write social
commentary and are known to white elite institutions"---would embrace the black
public intellectual label. But now that the concept has been formalized as a
social type, it is useful to consider exactly what this phenomenon is, where it
came from, and what it means.

The "public intellectual" notion emerged in 1987, when Russell Jacoby published
_The Last Intellectuals_, which was in part a nostalgic exaltation of a previous
cohort of politically engaged writers and critics. Jacoby contended that public
intellectuals such as Dwight MacDonald, Irving Howe, Philip Rahv, and others
were only marginally tied to the academy, and that their freedom from
institutional constraint enabled them to fashion an autonomous, macroscopic view
of American society and culture. The cohort of black people who call themselves
black public intellectuals seem to suggest that they constitute a new social and
political identity. But on closer examination, the role is all too familiar.

＊ ＊ ＊

We might see today's black public intellectuals as lineal descendants of the
authors of nineteenth-century slave narratives, if we understand those
narratives as attempts to articulate a collective racial voice. The major
difference is that slave narrators---with the partial exception of Frederick
Douglass---did not attain celebrity as individuals. Rather, their public
significance lay in embodying black people's collective capabilities.

The role of cellular representative reflected the prevailing view that a race's
ideals are carried by its exceptional members. Personal attainment was less
meaningful as a statement about the worth or prowess of the narrator than as a
vindication of black humanity. Even the most accomplished authors or those whose
odysseys had been most arduous or led to the greatest triumphs did not develop
intensely _personal_ followings. They remained primarily data points attesting
to black possibility, and cogs in a larger abolitionist conversation.

The black public intellectual's more direct progenitor is Booker T. Washington,
who turned the slave narrative into a saga of personal triumph befitting his
era. In _Up from Slavery_ (1901) Washington constructed a program and a rhetoric
that promised group progress through acquiescence to white supremacy. He crafted
it in the idiom of the gospel of personal enrichment then popular in both
religious and secular (and often overlapping) forms. In presenting his tale of
individual and group success through strength of character and perseverance, he
simultaneously presented himself as a Horatio Alger figure and an Andrew
Carnegie dipped in chocolate.

Washington's stature derived from skill at soothing white liberals' _retreat_
from the Reconstruction era's relatively progressive racial politics. He became
the first purely freelance race spokesman; his status depended on designation by
white elites rather than by any black electorate or social movement. To that
extent he originated a new model of the generic Black Leader---the Racial Voice
accountable to no clearly identifiable constituency among the spoken-for.

What made this possible, and credible, was black Americans' expulsion from civic
life. The role was unthinkable, even for a figure as prominent and respected as
Douglass, during the first three decades after the Civil War because a culture
of broad, democratic political participation flourished among black citizens.
The obvious multiplicity of articulate black voices, from the local Union
Leagues and Loyal Leagues to the United States Congress, would have immediately
exposed as absurd the suggestion that any individual carried---or should
carry---a blanket racial proxy. The idea of the free-floating race spokesman was
a pathological effect of the disfranchisement specific to the segregation era,
the condition to which Washington contributed.

Washington's paramountcy as bearer of the race's interests was always contested
by other blacks, and no one claimed the mantle after him. In fact the fifty
years between his death in 1915 and the final defeat of the Jim Crow regime were
punctuated by periods of intense, politically engaged debate among black
intellectuals. In addition to the famously vibrant discursive community of the
1920s, a lively current of engaged scholarship and commentary ran through the
1930s and 1940s, centered institutionally in the _Journal of Negro History_, the
_Journal of Negro Education_, and Du Bois's _Phylon_. Participants in this
community---which included humanists such as Sterling Brown, Jessie Fauset, Zora
Neale Hurston, James Weldon Johnson, and John S. Lash, as well as such social
scientists as Abram Harris, Charles S. Johnson, and Joseph Sandy Himes (novelist
Chester's brother)---converged on such questions as the definition, status, and
functions of black literature, the foundation of black identity, topical
critiques of ideological programs and tendencies in social affairs, and the
character and obligations of Afro-Americanist intellectual activity itself.
Many, such as Ralph Bunche, E. Franklin Frazier, Doxey Wilkerson, and Oliver
Cox, operated simultaneously in academic and activist domains. Others, like
James Ford, A. Philip Randolph, and George Schuyler, functioned entirely outside
the academy.

Cold War anti-radicalism and the apparent successes of an atheoretical,
desegregationist politics narrowed the scope and blunted the critical edge of
black intellectual discourse in the 1950s, although Baldwin and Ellison pushed
against the boundaries of convention. And civil rights activism soon created its
own eddies of debate and commentary. From the mid-1960s to the late 1970s
another wave of engaged political and cultural critique defined black
intellectual life; this movement was sustained most visibly in the _Negro
Digest_ (later _Black World_) and the _Black Scholar_, but it was propelled as
much through ephemeral, _samizdat_-like writing (for example, Amiri Baraka's
paper, "Why I Changed My Ideology"). More directly tied to activist politics,
this pattern of debate was more sharply contentious and aggressively
oppositional (and perhaps less sophisticated) than that of the interwar years.

Each of these discursive moments, however, was haunted by the problem of
speaking for the race---how to delineate the characteristics and warrants of
black leadership, how to authenticate it, the difficulties associated with
assuming the racial voice, the conundrum of undertaking social or cultural
criticism without accepting the role of race spokesperson. Bunche and Cox tried
to generate a rigorous critique of prevailing styles of political leadership.
Baldwin and Ellison strained mightily to comment on topical issues in a racially
conscious way while rejecting designation as black spokesmen. All these concerns
are responses to the conventional presumption---Washington's unacknowledged
legacy in the modern era---that any black individual's participation in public
life always strives to express the will of the racial collectivity.

This presumption in turn reflects an important complication facing black
intellectuals; they need to address both black and white audiences, and those
different acts of communication proceed from objectives that are distinct and
often incompatible. James Weldon Johnson identified this peculiar burden in a
1928 essay, "The Dilemma of the Negro Author," noting that black writers face
"more than a double audience; it is a divided audience made up of two elements
with differing and often quite opposite and antagonistic points of view."
Although Johnson focused primarily on creative writing, his observation that the
white audience's biases dispose black authors toward a "defensive and
exculpatory literature" applies more generally. The historian Lawrence D.
Reddick and the philosopher William T. Fontaine in the '30s and '40s similarly
complained of the "defense psychology" of black scholars, maintaining that it
undermines examination of the black experience by grounding Afro-Americanist
inquiry in the narrow, other-directed objective of demonstrating black people's
equal humanity.

＊ ＊ ＊

Those who now describe themselves as black public intellectuals diverge
significantly from the rich history of black commentary. Their differences speak
to the character of our time and the changes in black intellectual life ensuing
from the passage of the segregation era. The contemporary public intellectuals
are unique in that they exhibit little sense of debate or controversy among
themselves as a cohort. To the contrary, they seem rather to come together as a
publicist's delight, a hyperbolically log-rolling lovefest. Watkins and West
gush over each other's nonpareil brilliance; Gates proclaims West "the
preeminent African-American intellectual of our generation"; and Gates, West,
and Kelley lavish world-historical superlatives on Dyson, who, naturally enough,
expresses comparable judgments about them. Their anthologies and conferences
feature no sharp disagreements. Instead, they function as a kind of Tuskegee
Machine by committee. Their political utterances exude _pro forma_ moralism, not
passion. Their critiques are only easy pronouncements against racism, sexism,
homophobia, anti-Semitism or equally easy dissent from a lame Afrocentricity
that has no adherents among their audience anyway.

The point is not that controversy by itself makes for purity or legitimacy, but
that in this instance at least, the absence of controversy betrays a lack of
critical content and purpose. The stance of these black public intellectuals is
by and large just that---not a stand but a posture. Can the reader familiar with
their work recall without hesitation a specific critique, a concrete
formulation---an extended argument that is neither airily abstract nor cozily
compatible with what passes for common sense at the moment? I'd bet not, because
in this arena prominence of author counts more than weight of utterance.

The posture of the black public intellectual is a claim to speak from the edges
of convention, to infuse mainstream discourse with a particular
"counterhegemonic" perspective at least implicitly linked to one's connectedness
to identifiably black sensibilities or interests. It is also therefore, again at
least implicitly, a claim to immersion in a strategic conversation among black
Americans about politics, culture, and social affairs. The posture is flimflam
that elides the dual audience problem.

To expand on Johnson's initial formulation, for the black audience the focus of
critical intellectual activity is---or should be---on careful, tough-minded
examination of the multifarious dynamics shaping black social life. To that
extent, the black intellectual positions herself metaphorically at the boundary
of the black experience and faces in, establishing enough distance to get a
broad perspective but intent on contributing to a conversation that presumes not
only intricate knowledge but also an interpretive orientation filtered through
shared, racially inflected assumptions that inform strategic thinking. The
racially and politically attentive black intellectual is in this sense engaged
in a discourse of group self-examination.

In addressing the white audience, the task remains all too much explaining the
mysteries of black America. For that project one still positions oneself on the
metaphorical boundary of the Bantustan, but facing outward. This is why there
isn't much attention to flux, differentiation, contingency, or even analysis of
social process in our public intellectuals' accounts of black life; you don't
see nuances with your back turned, and besides that sort of messy texture
doesn't count for much because the white audience mainly just wants the
executive summary anyway. Why do they act that way? How can I keep from
gratuitously offending my coworkers or housekeeper? What do the drums say,
Cornel?

The different objectives involved in addressing the two audiences become more
important in the post-Jim Crow world. The demise of _Black World_ and atrophy of
the _Black Scholar_ both fuel and reflect the shriveling of an autonomous domain
for black debate. At the same time, the opening-up of employment opportunities
at elite academic institutions has increased the likelihood that black
intellectuals operate in multiracial discursive networks and has greatly
enhanced the visibility of a lucky few. Therefore, white forums, particularly
those associated with the left, have become the primary arenas for elaboration
of black commentary and critical public discourse, which makes a principled
self-consciousness in negotiating the two audiences all the more essential. But
the discursive space constructed by the black public intellectuals either
conflates the audiences into an unhelpful least common denominator or undertakes
a misdirection in combining an insider's "it's a black thang" posture with a
superficial, other-directed analysis explaining or defending the Negro. The
result is an all-purpose message, equally suitable for corporate boards,
rarefied academic conferences, White House dinners, and common folk. And,
unsurprisingly, the white audience overwhelms and sets the terms for the black,
repeating an ironic pattern begun with Washington.

Traditionally, engaged black intellectuals have also addressed a third
audience---a transracial community of progressive activists. This is a pattern
that can be seen from the abolitionist Douglass through the middle-aged and
elderly Du Bois, the young Bunche and others in his cohort, down to Lani
Guinier, Julian Bond, and hosts of others less well known. They haven't
functioned as interpreters of an esoteric black experience or bearers of a
"black position" or as itinerant Moral Voices, but as participants in a common
debate aimed at stimulating, directing, and taking political action.

Where Baldwin and Ellison bristled at the Black Voice designation, today's
public intellectuals accept it gladly. And they have to, because maintaining
credibility with their real, white audience requires that they be authentically
black, that their reports on the heart of darkness ring with verisimilitude.
("Drums say nihilism, moral breakdown. Need politics of conversion, love
ethic.") This underscores the extent to which---beneath all the overheated
academic trendiness---the black public intellectual stance merely updates Booker
T. Washington's role, but without the institutional trappings and, for the
moment at least, without the power.

As with Washington, the public intellectual's authenticity is conferred by white
opinion-makers. The typical trajectory of stardom is instructive. First, one
becomes recognized as a Black Voice in the intellectual apparatus of the left,
which---out of a combination of good intentions and bad faith---stands ever
ready to confer prominence on any reasonable, articulate black person willing to
associate with it. To qualify, one need not even put forward a critique that
seems leftist by usual standards: secular, rooted in political economy, focused
on stimulating political mobilization. After all, the "black community" is
different, has different needs, _etc_. Reputation spreads, and eventually
opportunities present themselves to cross over from the left intellectual ghetto
to the status of Black Voice for the mainstream. All it takes is the courage to
square off in the white public sphere against black anti-Semitism on the
Anti-Defamation League's terms, or to join the chorus lamenting the putative
social pathology of the inner city. Not to mention a knack for packaging the
center-right wisdom of the moment as a well-considered, yet bold and personally
risky challenge to convention. This is the path blazed so far by Gates and West,
and Dyson, as usual, is bringing his best Pigmeat-Markham-Meets-Baudrillard act
along behind.

＊ ＊ ＊

The consummate irony of the puffery is that it is misdirected all the way
through. Jacoby's archetype is only weakly connected to the bureaucratized
intellectual life of the academy. His public intellectual figures in a critique
of the politically corrosive effects of the left's having settled into the
university after the collapse of extramural radicalism. But those now wearing
the black public intellectual tag as a red, black, and green badge of courage
are not only deeply embedded in the higher reaches of the academic celebrity
system, they are also its unalloyed products. This brute fact is obscured by
another flimflam---what we might call the Proudhon Scam. Marx quipped that the
anarchist Pierre-Joseph Proudhon represented himself in Germany, where they
didn't know much political economy, as a political economist; and in France,
where they didn't know much philosophy, as a philosopher. West, Dyson _et al_.
use the public intellectual pose to claim authority both as certified,
world-class elite academics and as links to an extra-academic blackness, thus
splitting the difference between being insiders and outsiders. In the process,
they are able to skirt the practical requirements of either role---to avoid both
rigorous, careful intellectual work _and_ protracted, committed political
action.

Gates is the most complicated, most intellectually probing, and most consistent
of the group. Unlike the others, he makes no pretense of being a conduit to some
sort of grassroots black authenticity. He has publicly criticized the notion
that there are leaders who are singular representatives of the race. His
position is perhaps most like that of Bayard Rustin, as a freelance advocate for
black political centrism. Like Rustin, Gates has without equivocation chosen as
the forum for his advocacy the largely white circles of elite opinion, most
conspicuously as a staff writer for the _New Yorker_. A significant difference
is that Rustin in his last years was primarily an arbiter of the boundaries of
"responsible" black spokesmanship for the right wing of the Democratic Party
coalition. Gates also sometimes functions as an arbiter of black political
etiquette, but he is more actively concerned with articulating the voice of an
autonomously black, self-consciously _petit-bourgeois_ centrism.

West's program is less coherent and less concrete than Gates's. He has postured
as a link to black activist authenticity, holding an honorary leadership
position in the Democratic Socialists of America and referring frequently to
associations with supposed grassroots leaders and organizations. At the same
time, he has no particular history of concrete political practice or affiliation
and has shown no reticence about operating as a freelance race relations
consultant and Moral Voice for white elites. Most of all, the substance of his
public commentary---when it descends from sonorous platitudes and well-hedged
abstractions---is, to resuscitate an old slogan, "left in form, right in
essence." As Stephen Steinberg has demonstrated in a thorough and powerful
critique in the summer 1994 issue of _New Politics_, West's interpretation of
contemporary social and political life derives directly and definitively from
Daniel Patrick Moynihan's scurrilous arguments about black pathology.

 But too often with Kelley, politics reduces to
the academic pose, the combined stance of acting out flamboyantly crafted
rituals of "blackness" in conventional settings and spinning narratives that
ultimately demean concerted political action by claiming to find it everywhere.
Dyson and Watkins/hooks are little more than hustlers, blending bombast,
clichés, psychobabble, and lame guilt-tripping in service to the "pay me"
principle. Dyson, for instance, has managed to say absolutely nothing in a
string of _New York Times_ op-ed pieces.

"Public intellectual" is by and large an excuse, the marker of a sterile, hybrid
variant of "bearing witness" that, when all is said and done, is a justification
for an aversion to intellectual or political heavy lifting---a pretentious name
for highfalutin babble about the movie you just saw or the rhyme you just heard
on the radio. In its intimations of always being from and on the way to the
other place, the label is an admission and exaltation of *dis*connectedness, a
notion of the critical intellectual as Galahad or High Plains Drifter that is
the opposite of rootedness in a discourse community. That is why this cohort's
discussions of themselves and others seem so much like attempts to create
all-star lineups---the greatest this, the most brilliant that, the preeminent
other. They're more like the Super Friends than the Frankfurt School or the
Howard University social scientists of the 1930s.

There's a lot about this charade that is distasteful, but one feature makes it
especially hard to take. The dialectics of authentication trades on elaborate
displays of what sociolinguists call code-switching---in this case, going back
and forth from rarefied theoreticism to slivers of one or another version of
black vernacular expression. In academic lectures and scholarly writing, Kelley
can "send a shout out" in the _Journal of American History_ while dragging
Gramsci to the root doctor and holy roller church. Dyson finds Michael Jackson's
"postmodern spirituality" and in lectures lacks only for cork; West loads up on
Continental theory to explain why the music he listened to in his undergraduate
dorm is the apotheosis of black culture and why poor people need moral
rearmament. When we consider that these performances are directed to white
audiences, their minstrel quality stands out as especially distasteful because
it masquerades as being in touch with the latest wrinkles of refined black
hipness. This, admittedly, puts off those affronted by coon shows.

 In rejecting all considerations of
standards of evidence and argument as expressions of naïve positivism, the
cultural politicians get to make the story up as they go along. Graduate
students can figure out that this gambit has two very attractive features: it
drastically reduces the quantity of digging and thinking one has to do, and it
clears the path to public visibility and academic recognition. Of course, it's
not as if black public intellectuals were the only hustlers in an academic world
largely defined by the politics of reputation; and all in all it's good that
black people are getting paid, too. So why should anyone be concerned? The
answer is that the public intellectuals cohere around a more or less deceptively
conservative politics that is particularly dangerous at this moment in our
history.

Political conservatism is fundamental to the Black Voice business now no less
than in 1895, and Stanley Crouch and Shelby Steele have shown that it is
sometimes the sole requirement. One can qualify for the job only by giving white
opinion-makers a heavy dose of what they want to hear. Gates didn't get to be a
world-class Black Voice until he denounced the bogey of "black anti-Semitism"
all over the op-ed page of the _New York Times_ and went on to reassure
_Forbes_'s readership that, "yes, there is a culture of poverty," calling up the
image of a "sixteen-year-old mother, a thirty-two-year-old grandmother and a
forty-eight-year-old great-grandmother," noting for good measure, "It's also
true that not everyone in any society wants to work, that not all people are
equally motivated. There! Was that so hard to say?" He has since secured his
public intellectuality in a series of essays in the _New Republic_ and elsewhere
whose main point is to endorse the "vital center," and he extols the lost Jim
Crow world in _Colored People_, a memoir that could have been titled _Up from
Slavery on Lake Wobegon_. West's conservative moralism and victim-blaming have
made him Bill Bradley's favorite conduit to the Mind of the Negro and a hit on
the business school lecture circuit.

Most insidious, though, is the retrograde sham that masquerades as a leftist
"cultural politics." Rather than an alternative, deep structural "infra"
politics, as Kelley and others contend, the cultural politics focus is a
quietistic alternative to real political analysis. It boils down to nothing more
than an insistence that authentic, meaningful political engagement for black
Americans is expressed not in relation to the institutions of public
authority---the state---or the workplace---but in the clandestine significance
assigned to apparently apolitical rituals. Black people, according to this
logic, don't mobilize through overt collective action. They do it
surreptitiously when they look like they're just dancing, or as a colleague of
mine ironically described it, "dressing for resistance." In a _Journal of
American History_ article, supposedly about black working-class opposition,
Kelley asks rhetorically: "If a worker turns to a root doctor or prayer rather
than to a labor union to make an employer less evil, is that 'false
consciousness'?" He compares a conjuror's power favorably to that of the CIO,
the Populists, and the NAACP.

This is don't-worry, be-happy politics. Resistance flows from life by
definition. There is no need to try to create it because it's all around us; all
we have to do is change the way we define things. Then we can just celebrate the
people's spontaneous infrapolitics and show white people how to find it and
point out to them that Gramscianism is an African survival. We can make radical
politics by climbing the tenure ladder and feeling good about our collective
black selves through the pride of vicarious identification with the embedded
theoretical sophistication of the folk.

 And for good reason. The
posture of the Racial Voice requires---and, as the centennial of Washington's
perfidy should remind us, helps to produce---a black population that is
disfranchised and incapable of articulating its own agendas as a citizenry. Thus
the black intellectuals' insistence on defining politics centered in the
exercise of state power as inauthentic, which in turn underwrites all the
Aesopian interpretive twaddle in black cultural studies. (Interestingly, in
chastising proponents of codes prohibiting hate speech, Gates has complained
self-righteously about an identity politics that pays no attention to public
policy. His point would go down better if it came with a little self-criticism
from one whose scholarly reputation---supposedly the source of his
prominence---is based on precisely the view that he disparages.)

Before disfranchisement in the South, black people didn't have to express their
politics surreptitiously; they crafted and fought to realize their agendas
through public policy, and after disfranchisement they fought for sixty years to
be reenfranchised so they could do it again. And the record of overt black
political action outside the South is unbroken. What the current environment
demands from black intellectuals who would comment on public affairs is not more
whining about disparagement of the "black body" in Western culture (as if that
were news) or examination of representations of representations or noodling
about how, if we apply the right spin, everything black people do is resistance
to oppression. And most of all there is no need for interpretations that presume
an uncomplicated, conveniently mute black reality; there's already a surfeit of
analysis propelled by the collective black subject---"black people want, feel,
_etc_." As is true on the left generally, what is desperately called for is
stimulation of informed discussion among black Americans, and between blacks and
others, that presumes proprietorship of the institutions of governance and
policy processes on an identical basis with other citizens and aims at crafting
agendas that define and realize black interests accordingly. We should be in the
forefront of the fight against ratification of the balanced budget amendment,
crafting responses to so-called tort reform, fighting corporate globalization,
and finding ways to counter the assault on the Bill of Rights.

The cultural politicians' fixation on youth definitively illustrates their
bankruptcy. Not only are young people the least connected, the most alienated,
and the least politically attentive cohort of the black population, they're also
the ones whites are most interested in. "Willie, why do they have those welfare
babies? What must we do so that they won't take my car stereo?" What a
felicitous coincidence.

:::

repository: theodore-s-beers/reed-archive

gha_language: HTML

repo_name: theodore-s-beers/reed-archive


text:
# wekan-cleanup
Tools to clean up Mongodb database and delete archived cards / list / boards (after few months)

Need to have below Python module : pymongo

    pip install pymongo

You need to have authentification setup on Mongo database and port opened (if docker)

WekanCleanUp will delete as well Board with no cards

You need to update parameters before executing it

    # Parameters
    day_to_keep_board_arch = 30
    day_to_keep_list_arch = 30
    day_to_keep_card_arch = 60
    day_to_keep_board_nocard = 15
    mongo_user = 'admin'
    mongo_password = 'admin123'
    mongo_server = 'localhost'
    mongo_port = '27017'

repository: maulal/wekan-cleanup

repo_name: maulal/wekan-cleanup


text:
---
title: "Ubidots"
description: ""
weight:
aliases: ["/integrations/cloud-integrations/ubidots/ubidots-setup", "/integrations/cloud-integrations/ubidots/tts-setup"]
---

[Ubidots](https://ubidots.com/) provides a secure and easy way to build IoT solutions for students, makers and researchers. It is used for sending data from any Internet-enabled device to the cloud, triggering actions and alerts based on that data, and visualizing it.

<!--more-->

{{< warning >}} In this guide, we use the [UbiFunctions](https://help.ubidots.com/en/articles/2132086-analytics-ubifunctions-user-guide) module, which is currently not available for the STEM plan. {{</ warning >}}

## Prerequisites

1. A Ubidots user account with an upgraded plan.

## Setup Ubidots

Log in to your Ubidots account and find the **Devices** tab in the upper part of your dashboard. In its drop-down list, choose **Functions**.

When redirected to the **UbiFunctions** page, create a new function with the **Create Function** button.

On the left, give a **Name** to your function, select the **POST** method and choose **Python 3.6** for **Runtime**.

In this example, we will use the following Python function, which receives a JSON payload from {{% tts %}}, extracts the `decoded_payload`, and posts received data to Ubidots.

{{< note >}} To find your **Token**, click on your avatar in the upper right corner and select **API Credentials**. Be sure to use your **Token** and not your **API Key**. {{</ note >}}

```
import requests
import json
import time

BASE_URL = "https://industrial.api.ubidots.com"
TOKEN = "····" # Enter a token here

def main(args):
    # Prining args from TTI
    print(f'[INFO] Args from TTI:\n {args}')

    # Parsing data
    payload = parse_tti_data(args)
    dev_label = tti_dev_eui(args)
    print(f'[INFO] Parsed data:\n {payload}')
    print(f'[INFO] TTI Dev_EUI data:\n {dev_label}')

    # Posting to Ubidots
    req = update_device(dev_label, payload, TOKEN)
    print(f'[INFO] Request to Ubidots Status code: {req.status_code}')
    print(f'[INFO] Request ti Ubidots JSON:\n {req.json()}')

    return {
        'status_code': req.status_code,
        'response_json': req.json()
    }

def parse_tti_data(data):
    return data['uplink_message']['decoded_payload']

def tti_dev_eui(data):
    return data['end_device_ids']['device_id']

def update_device(device, payload, token):
    """
    Updates device with payload
    """
    url = "{}/api/v1.6/devices/{}".format(BASE_URL, device)
    headers = {"X-Auth-Token": token, "Content-Type": "application/json"}
    req = create_request(url, headers, attempts=5, request_type="post", data=payload)
    return req

def create_request(url, headers, attempts, request_type, data=None):
    """
    Function to make a request to the server
    """
    request_func = getattr(requests, request_type)
    kwargs = {"url": url, "headers": headers}
    if request_type == "post" or request_type == "patch":
        kwargs["json"] = data
    try:
        req = request_func(**kwargs)
        status_code = req.status_code
        time.sleep(1)
        while status_code >= 400 and attempts < 5:
            req = request_func(**kwargs)
            status_code = req.status_code
            attempts += 1
            time.sleep(1)
        return req
    except Exception as e:
        print("[ERROR] There was an error with the request, details:")
        print(e)
        return None
```

After modifying the function code with your token, click the **Make it live** button.

Your function will be assigned an **HTTPS Endpoint URL**. Copy this URL in order to use it later as a part of setup on {{% tts %}}.

{{< figure src="creating-function.png" alt="Creating a UbiFunction" >}}

Your function is now ready to handle the conversion of the incoming messages from {{% tts %}}, from JSON format to the one that is compatible with Ubidots.

## Configure {{% tts %}}

Next step is to create a Webhook integration on {{% tts %}} by using the **Ubidots** [Webhook template]({{< ref "/integrations/webhooks/webhook-templates" >}}).

{{< note >}} Besides implementing the Webhook integration, you also need to create an uplink payload formatter in order to decode the uplink payload and set fields in the `decoded_payload` object of the uplink message. This is necessary to allow the Ubidots function to interpret the payload coming from {{% tts %}}. See [Payload Formatters]({{< ref "/integrations/payload-formatters" >}}) for a detailed info. {{</ note >}}

First, fill in the **Webhook ID** field.

Then enter your **Ubidots username** and provide your UbiFunction's name.

{{< note >}} The name of the UbiFunction needs to be modified to use lowercase and dashes only. For example, if the UbiFunction is named **Example Function**, enter `example-function` in the **UbiFunction name** field as shown in the image below. {{</ note >}}

{{< figure src="ubidots-webhook-creation.png" alt="Ubidots webhook" >}}

{{< note >}} To see the values of all parameters of the Ubidots integration, click on the integration after you created it with the Webhook template. {{</ note >}}

Once you have created the integration, navigate to **Devices** tab in Ubidots dashboard and select **Devices**.

You should see your device listed, as it is automatically added when an uplink is received. Click the device to see variables and their latest values.


text:
# Unraid Console

[source](https://docs.unraid.net/legacy/FAQ/console)

## Basics of Console Usage

- If you are new to Linux, start by reading the [Terminal
  Access](https://docs.unraid.net/legacy/FAQ/terminal-access) page.
- The commands below usually list a usage note, which is a link to a
  'man page'. In Linux, man pages describe the syntax of command
  usage, including all options for the command. Linux splits all of
  these command line commands into numbered groups, and often lists
  the group number with the command, eg. `cat(1)`. Ignore the
  numbers! I think they are just there to confuse those of us who did
  not grow up speaking Linux.
- In some commands, you have to press the Ctrl-C keystroke combination
  to break out. In `less`, use the `q` key to quit.
- When a command produces output that is more than can fit on the
  physical console, you can use the Shift-PgUp and Shift-PgDn key
  combinations to page up and down through the console display,
  including what may appear to have scrolled off the top.
- The commands below are often compared with DOS or Windows console
  commands, but even when they appear essentially equivalent, there
  can be very subtle differences, not necessarily mentioned below.
- `cat` - [usage](http://linux.die.net/man/1/cat) and a [how to
  use](http://www.cyberciti.biz/faq/howto-use-cat-command-in-unix-linux-shell-script/)
  - `cat` is like the DOS/Windows `type`, displays a file on
    screen. The file is assumed to be all text, and if not, will
    usually display garbage.
  - `cat` is used often below, but could easily be replaced by
    `more` or `less` (eg. `cat /proc/cpuinfo` could be `less /proc/cpuinfo`)
- `more` - [usage](http://linux.die.net/man/1/more)
  - `more` displays text files like `cat`, but pages them to the
    screen. It waits for a keystroke between each page.
- `less` - [usage](http://linux.die.net/man/1/less)
  - `less` pages text files like `more`, but also lets you page
    up and down through them (press `q` to quit).
- `ls` - [usage](http://linux.die.net/man/1/ls)
  - `ls` is a little like the DOS/Windows `dir` command, for
    displaying directories in different ways, but the syntax is very
    different.
  - `ls -l` is a common way to list complete directory entries
  - see the [Command Macros](#command-macros)
    section for more complex examples
  - _Note: in the default setup of Unraid, `v` is an alias for
    `ls -l`, so you can replace the `ls -l` above with just
    `v`. It is OK to use the alias, but it is far better to learn
    the actual `ls -l` command in case you are ever in a situation
    where the alias does not exist. (nearly every other Linux based
    device will NOT have `v` as an alias for `ls -l`, and it may
    even be aliased to something completely different!)_
- `cp` - [usage](http://linux.die.net/man/1/cp)
  - `cp` is like the DOS/Windows `copy` command.
- `rm` - [usage](http://linux.die.net/man/1/rm)
  - `rm` is like the DOS/Windows `del` command.
- `cd` - [usage](http://ss64.com/bash/cd.html) and a [how to
  use](http://www.linfo.org/cd.html)
  - `cd` is like the DOS/Windows `cd` command.
  - `cd` with no parameters changes to the users home directory
- `pwd` - [usage](http://linux.die.net/man/1/pwd)
  - `pwd` displays the users current directory
- `mkdir` - [usage](http://linux.die.net/man/1/mkdir)
  - `mkdir` is like the DOS/Windows `md` command.
- `rmdir` - [usage](http://linux.die.net/man/1/rmdir)
  - `rmdir` is like the DOS/Windows `rd` command.
- `chmod` - [usage](http://linux.die.net/man/1/chmod)
  - `chmod` is a little like the DOS/Windows `attrib` command,
    but the syntax is very different.
  - The Linux system of security and access attributes is very
    different to the Windows system. For more help, see
    [this](https://wiki.archlinux.org/index.php/File_permissions_and_attributes)
    and
    [this](http://www.yourownlinux.com/2013/09/chmod-basics-of-filesdirectories.html).
- `find` - [usage](http://linux.die.net/man/1/find)
  - `find` is used to search for files
  - Example: the command `find . -iname "file*"` will search
    the current folder and all sub-folders for files matching
    `file*`, using a case-insensitive search.

## Console Commands for Hard Drives

The following commands require the Device ID, which you can get from
the "Main" tab of your webgui. Locate your drive, then look for the Device ID in parentheses. It
is always 3 lowercase letters, beginning with either **hd** or **sd**,
eg. _sda_, _sdk_, _hdc_, _hdg_. For simplicity, _sdx_ will be used
below, and you will substitute the appropriate Device ID for your drive.
(Extra spaces are added for clarity only, only one space is needed.)

### hdparm

- Instruction manual (a Linux MAN page) =\>
  <http://linux.die.net/man/8/hdparm>

To view the identity and configuration information for a drive (at the
console or terminal prompt)

`hdparm  -I  /dev/sdx`

To determine the read speed of a hard drive, the following command can
be used. The very last number in MB/sec is the one you want, ignore the
rest. Although one run will give you a decent result, for better
accuracy, take the average of at least 5 runs. See also [Check Harddrive
Speed](https://docs.unraid.net/legacy/FAQ/check-harddrive-speed).

`hdparm  -tT  /dev/sdx`

### smartctl

- Instruction manual (a Linux MAN page) =\>
  <http://smartmontools.sourceforge.net/man/smartctl.8.html>

To obtain the SMART info for a drive, including some identity and
configuration information, and physical statistics and error history.
For more information about SMART and `smartctl`, see
[here](https://forums.unraid.net/forum/index.php?topic=1521) and
[here](https://docs.unraid.net/unraid-os/manual/troubleshooting#data-recovery) and
[here](https://forums.unraid.net/forum/index.php?topic=1845.msg13042#msg13042)
and [here](https://forums.unraid.net/forum/index.php?topic=2097) and
[here](https://forums.unraid.net/forum/index.php?topic=2074.0).

`smartctl  -a  -d  ata  /dev/sdx`

Some newer drives and disk controllers will not issue a report if you
use the "-d ata" option, as they are not "ata" drives. (in fact,
they will respond with an error message instead) Most older disk
controllers did require the "-d ata" option, even if SATA drives. If
the smartctl report works without "-d ata" it is OK to leave it off.
If you get an error with "-d ata", try without it. The basic command
would then be

`smartctl -a /dev/sdx`

To copy the SMART report to a file called **smart.txt** on your Unraid
flash drive, that you can copy elsewhere and post to the forums, use the
following command. Of course, you can change the file name to what ever
you like, for example, **smart_Seagate320_2008-12-15.txt**.

`smartctl  -a  -d  ata  /dev/sdx  >/boot/smart.txt`

or

`smartctl  -a  -d  ata  /dev/sdx  |  todos  >/boot/smart.txt`

This second form makes it easier to look at the **smart.txt** file from
a Windows workstation, because it adds the standard end-of-lines that
are used in Windows.

To run a short or long SMART test on a drive, select one of the
following commands (short test takes minutes, long test can take several
hours depending on size of drive)

`smartctl  -d  ata  -tshort  /dev/sdx`
`smartctl  -d  ata  -tlong  /dev/sdx`

As of Unraid v4.3 final, **smartctl** is included with Unraid. Prior to
this, it needed to be copied to the flash drive, see
[this](http://lime-technology.com/wiki/index.php?title=Best_of_the_Forums#unRAID_Addons_and_Tools)
for links to obtaining it. If you had to copy it to your flash drive,
then the command to execute would be **/boot/smartctl** instead of just
**smartctl**. For example, the command to get a SMART report would be

`/boot/smartctl  -a  -d  ata  /dev/sdx`

### other hard drive commands

To view the partitioning of a drive, the drive geometry, and the total
number of sectors

`fdisk  -l  -u  /dev/sdx`

To obtain the total number of sectors on a drive

`blockdev  --getsz  /dev/sdx`

To verify how the drive is labeled (note the "1" at the end of the
command, indicating the first partition on device /dev/sdx)

`vol_id  /dev/sdx1`

Shows you the drives by their model and serial number and the drive
device ID (sda, hdc, etc) linked to each

`ls  -l  /dev/disk/by-id`
`-or-`
`ls  -l  /dev/disk/by-id/[au]*  |  grep  -v  part1`

Lists the drive devices that have "volume labels", and device ID
linked to each. Typically, only the flash drive will have an entry here
and it MUST have a volume label of "UNRAID" for Unraid to start up
properly

`ls  -l  /dev/disk/by-label`

_Note: in the default setup of Unraid, `v` is an alias for `ls -l`,
so you can replace the `ls -l` above with just `v`._

## Console Commands for Networking

Here are a few networking commands that will provide more info about the
driver, about the card, about its configured parameters and speed, and
about its connection statistics.

Note: The ethtool utility is included in some but not all Unraid
distributions. See
[here](https://forums.unraid.net/forum/index.php?topic=2109.msg15568#msg15568)
for more information about ethtool, and a download link.

- `lsmod` - [usage](http://linux.die.net/man/8/lsmod)
  - lists the installed kernel modules, including your network
    driver
- `ethtool -i eth0` - [usage](http://linux.die.net/man/8/ethtool)
  - displays the network driver being used by your network chipset
    (for eth0), and its version
- `ethtool eth0`
  - displays a number of the settings for your network chipset
  - displays the speed setting, typically "Speed: 1000 Mb/s" for a
    gigabit connection
  - displays the Wake-on-LAN setting, typically "Wake-on: g" if
    enabled for 'magic' packet
- `ifconfig` - [usage](http://linux.die.net/man/8/ifconfig)
  - displays various numeric parameters and statistics for your
    networking
  - displays your MAC address, as `HWaddr`
  - displays your local IP, as `inet addr`
  - displays your MTU setting
  - displays assorted transmit and receive statistics, including
    errors and collisions
- `ethtool -S eth0`
  - displays more detailed network statistics
- `net lookup google.com` - [usage](http://linux.die.net/man/8/net)
  - check for correct nameserver and DNS configuration, should
    provide the IP for Google if setup right
- `ping -c5 google.com` - [usage](http://linux.die.net/man/8/ping)
  - another way to check for correct nameserver configuration (if it
    times out, or produces errors, you need to set a nameserver)
- `egrep -i "eth0|rc.inet1|((forcedeth|r8169|e1000|e1000e|sky2|skge|tg3|bcm5700|sk98lin)[ :])|dhcp" /var/log/syslog` -
  [usage](http://linux.die.net/man/1/egrep)
  - displays lines in the system log (/var/log/syslog) affiliated
    with networking

## Console Commands for System Management

**`section needs more work`**

- `tail -f --lines=99 /var/log/syslog` -
  [usage](http://linux.die.net/man/1/tail)

  - Display current end of syslog
  - If you leave the `--lines` parameter off, it will display the
    last 10 lines, which is often all you need. There are many
    situations though where at least a page full is useful, perhaps
    even 200 (eg. `\--lines=200`).
  - It is essentially real time, use Ctrl-C to quit.
- `free -l` - [usage](http://linux.die.net/man/1/free)

  - Show current memory usage
- `top` - [usage](http://linux.die.net/man/1/top)

  - List processes, with some memory and CPU stats
- `ps -eF` - [usage](http://linux.die.net/man/1/ps)

  - List processes (similar to top but ...)
- `ps -eo size,pid,time,args --sort -size` _(those are commas not
  periods, double hyphen before sort)_

  - List the processes on the server and their memory size (first
    column) sorted by memory size
- `testparm -sv` - [usage](http://linux.die.net/man/1/testparm)

  - Show system configuration parameters, including security and
    permissions
- `w` - [usage](http://linux.die.net/man/1/w)

  - Show who is logged on and what they are doing

For excellent descriptions and examples of the use of `screen`
([usage](http://linux.die.net/man/1/screen)), see
[here](https://forums.unraid.net/forum/index.php?topic=72.msg27984#msg27984)
and
[here](https://forums.unraid.net/forum/index.php?topic=2817.msg32232#msg32232).
The `screen` tool allows you to 'detach' a terminal session, to keep
it running even if you log out of the terminal session. An interesting
example using `screen` is in the
[rtorrent](https://forums.unraid.net/forum/index.php?topic=4029)
thread.

### To cleanly Stop the array from the command line

The following section is from 2011, and does NOT take into consideration
any of the extra services etc that Unraid has had incorporated since
then.

To shutdown the server properly from the command prompt, simply type in

powerdown

To cleanly stop the array from the linux command line prior to a reboot
requires the use of several commands in turn. They will stop SAMBA,
unmount the disks, and then stop the Unraid server. These commands can
be performed on the linux command line as follows:

`/root/samba stop`

Then, for each of your data disks type (note, the command is umount, not
unmount. data disk1=/dev/md1, disk2=/dev/md2, etc...):

`umount /dev/md1`
`umount /dev/md2`
`umount /dev/md3`
`umount /dev/md4`
`umount /dev/md5`
`etc...`

`/root/mdcmd stop`

Note, a disk will not be able to be unmounted if it is busy. It will be
busy if it has an open file, or a process whose current directory is
located on the disk. If a disk is unable to be unmounted you'll first
need to terminate the processes holding it busy before it can be
unmounted.

To identify processes holding a disk busy you can type:

`fuser -mv /mnt/disk* /mnt/user/*`

To terminate processes holding a disk busy you can type (example is for
disk1):

`fuser -mvk /mnt/disk1`

or you can individually terminate individual process IDs by typing

`kill PID`

(where PID = the numeric process ID as printed by the prior `fuser -mv` command)
\--[Joe L.](https://forums.unraid.net/profile/6-joe-l/) 16:54, 3 January 2011 (UTC)

## Console Commands for Files and Folders

Many more file and folder commands can be found in the [Basics of
Console Usage](#basics-of-bonsole-usage) section
above.

- `df` - [usage](http://linux.die.net/man/1/df)
  - reports file system disk space usage
  - example: `df /var/log` reports space usage of the log folder,
    in RAM
- `mount` - [usage](http://linux.die.net/man/8/mount)
  - mounts file systems; makes your files available!
- `umount` - [usage](http://linux.die.net/man/8/umount)
  - unmounts mounted file systems
- `which` - [usage](http://linux.die.net/man/1/which)
  - checks for shell commands that are executable from the system
    path

## Console Commands for System Information

In the commands below, `cat` is often used to display info, but
`more` and `less` can be used instead (see [Basics of Console
Usage](#basics-of-bonsole-usage) section above).

### CPU Info

- `lscpu` - [usage](http://linux.die.net/man/1/lscpu)
  - short summary of CPU info
- `cat /proc/cpuinfo`
  - much longer report of all CPU's
- `grep --color lm /proc/cpuinfo`
  - tests for 64 bit compatibility; if your CPU supports 64bit mode,
    then 'lm' will be highlighted in the cpuinfo report
- `grep --color vmx /proc/cpuinfo`
  - tests for Intel VT CPU Virtualization Extensions; if your CPU
    supports them, then 'vmx' will be highlighted in the cpuinfo
    report
- `grep --color svm /proc/cpuinfo`
  - tests for AMD V CPU Virtualization Extensions; if your CPU
    supports them, then 'svm' will be highlighted in the cpuinfo
    report
- `egrep --color 'lm\|vmx\|svm' /proc/cpuinfo`
  - quick way to test all 3 above _(thanks WeeboTech!)_

### Memory Info

- `free` - [usage](http://linux.die.net/man/1/free)
  - abbreviated summary of general memory info
  - Note: be careful putting much importance on low free memory
    numbers, as Linux uses memory very differently than Windows
- `free -t`
  - summary of general memory info with totals
- `free -mt`
  - summary of general memory info with totals, all in megabytes
- `cat /proc/meminfo`
  - more complete report of memory usage
- `slabtop` - [usage](http://linux.die.net/man/1/slabtop)
  - displays kernel slab cache information in real time
- `slabtop -s c`
  - slabtop display, but sorted by cache size usage
- `vmstat` - [usage](http://linux.die.net/man/8/vmstat)
  - displays virtual memory statistics
- `vmstat -m`
  - detailed memory usage

### Sensor Info

- `sensors` - [usage](http://linux.die.net/man/1/sensors)
  - displays some of available sensor info, may include system, CPU,
    and drive temperatures, system voltages, fan speeds and
    settings, etc
- `sensors-detect` -
  [usage](http://linux.die.net/man/8/sensors-detect)
  - analyses system and displays all available sensors and needed
    modules, helps configure
    [`sensors.conf`](http://linux.die.net/man/5/sensors.conf),
    requires Perl installed first

### Network Info

- Please see the [Network
  section](#console-commands-for-networking) above

### Other Hardware Info

_Note: the following commands may or may not be installed in your release_

- `lspci` - [usage](http://linux.die.net/man/8/lspci)
  - displays information about PCI buses and devices
- `lspci -vnn`
  - displays more verbose information about PCI buses and devices
    (add another `v` (`-vvnn`) for even more verbose)
- `lspci -knn`
  - displays more information about PCI buses and devices, including
    device numbers and assigned kernel modules
- `lsscsi` - [usage](http://linux.die.net/man/8/lsscsi)
  - displays information about SCSI devices
- `lsscsi -vgl` _(that's a lower case L)_
  - displays more verbose information about SCSI devices, including
    ATA numbers!
- `lsusb` - [usage](http://linux.die.net/man/8/lsusb)
  - displays information about USB buses and the devices connected
    to them
- `dmidecode` - [usage](http://linux.die.net/man/8/dmidecode)
  - displays the raw information from DMI/SMBIOS tables; may contain
    info on system manufacturer, motherboard, BIOS, memory,
    chipsets, etc
  - some of it is not human readable, and it is very often
    unreliable or wrong
  - if you see _Invalid entry length (0). DMI table is broken!
    Stop._, then the DMI tables are bad. Sometimes a BIOS update
    will improve them, but not guaranteed.

### Version Info

- `uname -a` - [usage](http://linux.die.net/man/1/uname)
  - displays the Linux kernel version
- `grep "emhttp: unRAID System Management Utility" /var/log/syslog` - [usage](http://linux.die.net/man/1/grep)
  - displays the UnRAID version
- `ethtool -i eth0` - [usage](http://linux.die.net/man/8/ethtool)
  - displays the version of the network driver being used by your
    network chipset (for eth0)
- `openssl version` - [usage](http://linux.die.net/man/1/openssl)
  - displays the version of OpenSSL, if installed

## Command Macros

Typing commands at the console command prompt can get tiresome,
especially when repetitive. You can use the up and down keys to repeat
previous commands, or at least reduce the typing, but Linux provides for
command macros, otherwise called a command alias. Below is a sample
macro file (with the file name of `macros`) that you can use and
modify. It requires being executed from your `go` file, so insert a
line into `/boot/config/go` similar to `/boot/macros`.

```bash
#!/bin/bash

# set dn like Windows dir/o-d, newest files first
echo "alias dn='ls -Aogt --group-directories-first --time-style=long-iso'">>/etc/profile

# set ds like dn plus Windows dir/s, newest files first, include all subdirs
echo "alias ds='ls -AogtR --group-directories-first --time-style=long-iso'">>/etc/profile

# start tail of syslog with plenty of lines
echo "alias tale='tail -f --lines=200 /var/log/syslog'">>/etc/profile

# an attempt to emulate the old Norton FF (FileFind)
echo "alias ff='find . -wholename '/proc' -prune -o -name '">>/etc/profile

# set screen blanking (if idle for 10 minutes) and monitor to standby (if idle for 30 minutes)
/bin/setterm -blank 10 -powersave powerdown -powerdown 30
```

When these macros are added to `/etc/profile`, they are available in
any console you open, whether by SSH or Telnet or at the physical
console on the UnRAID machine.

UnRAID already includes one macro - `v` is aliased to `ls -l`.

repository: ikrima/gamedevguide

gha_language: PowerShell

repo_name: ikrima/gamedevguide


text:
---
hrs_structure:
  division: '2'
  volume: '10'
  title: '25'
  chapter: 468L
  section: 468L-5.5
type: hrs_section
tags:
  - Business
menu:
  hrs:
    identifier: HRS_0468L-0005_0005
    parent: HRS0468L
    name: 468L-5.5 Recordkeeping requirements for client trust accounts
weight: 93040
title: Recordkeeping requirements for client trust accounts
full_title: 468L-5.5 Recordkeeping requirements for client trust accounts
---
**[§468L-5.5] Recordkeeping requirements for client trust accounts.** (a) A travel agency or charter tour operator shall maintain all books and records necessary to comply with this chapter and its rules.

(b) A travel agency or charter tour operator shall keep and maintain for a period of at least two years copies of all bank statements, deposit slips, canceled checks, drafts, and wire or electronic transaction documents relating to client trust accounts. The travel agency, charter tour operator, or any branch offices shall make such records available for inspection and audit within three business days of a written request by the director. Nothing herein shall prevent the director from inspecting and auditing the books and records of the travel agency, charter tour operator, or any branch offices, as otherwise provided under this chapter or its rules. [L 2001, c 62, pt of §2]

repository: SamMade/BlueAndKrabby

repo_name: SamMade/BlueAndKrabby


text:
![](http://sheep.fish/wp-content/themes/sheepfish/images/logo2.png)
# Sheep.Fish base front v0.2.0

> The initial layout from [Sheep.Fish](http://sheep.fish) team

## Features

Please see our [gulpfile](gulpfile.js) for up to date information on what we support.

* enable [ES2015 features](https://babeljs.io/docs/learn-es2015/) using [Babel](https://babeljs.io)
* CSS Autoprefixing
* Built-in preview server with BrowserSync
* Automagically compile Sass with [libsass](http://libsass.org)
* Map compiled CSS to source stylesheets with source maps (optional)
* Image optimization

## Getting Started

- Install: `npm install`
- Run `gulp` to preview and watch for changes (develop version)
- Run `gulp build` to build your site for production
- Run `gulp build-test` to preview the production build
- Run `build-minify` to build and minify for production

## License

[BSD license](http://opensource.org/licenses/bsd-license.php)

repository: PsihStevens/Slider-Site

repo_name: PsihStevens/Slider-Site


text:
# Live Localizer

Live Localizer widget for Polymer [i18n-behavior](https://github.com/t2ym/i18n-behavior) (work in progress)

[API Docs](https://t2ym.github.io/live-localizer/components/live-localizer/#live-localizer-main) and [Live Demo](https://t2ym.github.io/live-localizer/components/live-localizer/demo/) on GitHub Pages (Chrome recommended for now)

## Live Localizer applied to [the Shop App](https://www.polymer-project.org/1.0/toolbox/case-study)

<img src="https://raw.githubusercontent.com/wiki/t2ym/live-localizer/live-localizer.gif" width="768px">

Sequential description of the animated screenshot above:

- Browse the Shop App with Live Localizer widget at the bottom left corner as a fab icon
- Open the Live Localizer widget
- Switch to the Japanese locale with pseudo-L10N
- Save the working strings of the Shop App as a local XLIFF file `bundle.ja.xlf`
- Open the local XLIFF with XLIFF editor [Virtaal](https://github.com/translate/virtaal)
- Translate the local XLIFF (Actually, open the translated XLIFF `shop-bundle.ja.xlf`)
- Drag and drop the translated XLIFF from Windows Explorer to Live Localizer widget
- Load the dropped XLIFF to the running Shop App
- Browse the localized Shop App
- Switch to the English locale

## Use Cases

- Dispatch translation tasks via the running Web app itself
- Dispatch incremental translation tasks via the running Web app itself
- Check screenshots on the running Web app
- Check translation progress in statistics view
- Submit translations to Cloud (Firebase)
- Watch Cloud to update translations in real-time

## Features

- Export XLIFF from the running app to a local file
- Import XLIFF from a local file to the running app
- Save XLIFF to Browser Storage (IndexedDB)
- Load XLIFF from Browser Storage (IndexedDB)
- Upload XLIFF to Cloud Storate (Firebase)
- Download XLIFF from Cloud Storage (Firebase)
- Show translation statistics in list view
- Detect changes on Cloud Storage (Firebase) to trigger a new build
- Detect changes and load Local XLIFF

## Install

```sh
  bower install --save live-localizer
```

## Import

### Static Loading
```html
  <link rel="import" href="path/to/bower_components/live-localizer.html">
```

### Lazy Loading
```html
  <link rel="import" href="path/to/bower_components/live-localizer-lazy.html">
```

## Apply

Attach at the end of the main body element.

### With Firebase Cloud Storage:

```html
<body>
  ...
  <live-localizer>
    <!--
      Firebase Cloud Storage configuration with the example parameters for Live Localizer demo app:
      For each target app, a dedicated Firebase project has to be configured.
    -->
    <live-localizer-firebase-storage id="firebase-storage" class="storage cloud"
      auth-provider="google"
      auth-domain="live-localizer-demo.firebaseapp.com"
      database-url="https://live-localizer-demo.firebaseio.com"
      api-key="AIzaSyCjrlPhl0cLSZVRsDvuajq16vkerhcu_UM">
    </live-localizer-firebase-storage>
  </live-localizer>
</body>
```

### Without Firebase Cloud Storage:

```html
<body>
  ...
  <live-localizer></live-localizer>
</body>
```

## Firebase Setup

Firebase project has to be set up for storing XLIFF.

### Supported Authentication Methods

- Anonymous
- Google (OAuth)
- GitHub (OAuth)
- Twitter (OAuth)

### Firebase Security Rules

```javascript
{
  "rules": {
    "users": {
      ".read": "auth.uid === 'xliff-watcher'",
      "$uid": {
        ".read": "$uid === auth.uid",
        ".write": "$uid === auth.uid"
      }
    }
  }
}
```

### XLIFF Watcher (Optional)

See `gulp fetch-xliff` and `gulp watch-xliff` tasks in `demo/gulpfile.js`

#### Notes on XLIFF Watcher:

- `firebase login:ci` token from `firebase-tools` is required for `gulp fetch-xliff` task
- Service account credentials' JSON is required for `gulp watch-xliff` task

## Local XLIFF Watcher (Optional)

Local XLIFF changes can be watched via local HTTP server at http://localhost:8887/UPLOADED_XLIFF_FILE

Check "Watch and Load XLIFF" in the local file storage control panel to start watching the local XLIFF file

### HTTP Server for Local XLIFF Watcher Setup

- Install [NodeJS](https://nodejs.org/) on the local host of the translator
- Install [the local HTTP server npm package](https://www.npmjs.com/package/http-server)
```
npm install -g http-server
```
- For HTTP sites, start local HTTP server at http://localhost:8887 with the root folder containing the XLIFF file
```
http-server FOLDER_TO_CONTAIN_XLIFF -d false -c-1 -r -a localhost -p 8887 --cors=If-Modified-Since
```
- For HTTPS sites, start local HTTPS server at https://localhost:8887 with the root folder containing the XLIFF file

Batch File to Launch local HTTPS server on Windows: [`https-local-server.bat`](https://github.com/t2ym/live-localizer/blob/master/http-local-server.zip?raw=true) FOLDER_TO_CONTAIN_XLIFF
```
@echo off
if "%1"=="" echo Please specify the path to the root folder containing the target XLIFF file
if "%1"=="" echo %0 C:\Path\To\XLIFF\Folder
if "%1"=="" goto :end
if exist C:\OpenSSL-Win64 set OPENSSL_CONF=C:\OpenSSL-Win64\bin\openssl.cfg
if exist C:\OpenSSL-Win64 set PATH=%PATH%;C:\OpenSSL-Win64\bin
if exist C:\OpenSSL-Win32 set OPENSSL_CONF=C:\OpenSSL-Win32\bin\openssl.cfg
if exist C:\OpenSSL-Win32 set PATH=%PATH%;C:\OpenSSL-Win32\bin
if "%OPENSSL_CONF%"=="" echo Please install OpenSSL package for Windows from https://slproweb.com/products/Win32OpenSSL.html linked from https://wiki.openssl.org/index.php/Binaries
if "%OPENSSL_CONF%"=="" goto :end
if not exist demoCA mkdir demoCA
cd demoCA
if not exist newcerts mkdir newcerts
type nul >index.txt
echo 01 >serial
echo y >yy
echo y >>yy
if not exist localhostCA.key openssl genrsa 2048 >localhostCA.key
if not exist localhostCA.csr openssl req -new -key localhostCA.key -subj "/C=JP/ST=Tokyo/O=i18n-behavior/OU=Live Localizer/CN=Live Localizer Localhost CA" -out localhostCA.csr
del /Q CAcreation
if not exist localhostCA.crt type nul >CAcreation
if not exist localhostCA.crt openssl x509 -days 3650 -sha256 -req -signkey localhostCA.key -in localhostCA.csr -out localhostCA.crt
if not exist localhost.key openssl genrsa 2048 >localhost.key
if not exist localhost.csr openssl req -new -key localhost.key -subj "/C=JP/ST=Tokyo/O=i18n-behavior/OU=Live Localizer/CN=localhost" -out localhost.csr
cd ..
if not exist demoCA\localhost.crt openssl ca -md sha256 -days 3650 -cert demoCA\localhostCA.crt -keyfile demoCA\localhostCA.key -in demoCA\localhost.csr -out demoCA\localhost.crt <demoCA\yy
if exist demoCA\CAcreation echo Please install the generated Localhost CA certificate as "Trusted Root Certification Authorities"
if exist demoCA\CAcreation demoCA\localhostCA.crt
http-server "%1" -d false -c-1 -r -a localhost -p 8887 --cors=If-Modified-Since --ssl --cert demoCA\localhost.crt --key demoCA\localhost.key
:end
```

Script to Launch local HTTPS server on Mac: [`https-local-server.sh`](https://gist.githubusercontent.com/t2ym/b633f6a92e72e64e03ab8ad53e14e912/raw/1071a8b24a9cb6adcda69c61af46e74d77dcdfa8/https-local-server.sh) FOLDER_TO_CONTAIN_XLIFF
```
#!/bin/sh

if [ "$1" = "" ]; then
  echo Please specify the path to the root folder containing the target XLIFF file
  echo $0 /Path/To/XLIFF/Folder
  exit 1
fi
which openssl
if [ "$?" = "1" ]; then
  echo Please install openssl command
  exit 1
fi
mkdir -p demoCA
cd demoCA
mkdir -p newcerts
rm -f index.txt
touch index.txt
echo 01 >serial
echo y >yy
echo y >>yy
if [ ! -e localhostCA.key ]; then
  openssl genrsa 2048 >localhostCA.key
fi
if [ ! -e localhostCA.csr ]; then
  openssl req -new -key localhostCA.key -subj "/C=JP/ST=Tokyo/O=i18n-behavior/OU=Live Localizer/CN=Live Localizer Localhost CA" -out localhostCA.csr
fi
rm -f CAcreation
if [ ! -e localhostCA.crt ]; then
  touch CAcreation
  openssl x509 -days 3650 -sha256 -req -signkey localhostCA.key -in localhostCA.csr -out localhostCA.crt
fi
if [ ! -e localhost.key ]; then
  openssl genrsa 2048 >localhost.key
fi
if [ ! -e localhost.csr ]; then
  openssl req -new -key localhost.key -subj "/C=JP/ST=Tokyo/O=i18n-behavior/OU=Live Localizer/CN=localhost" -out localhost.csr
fi
cd ..
if [ ! -e demoCA/localhost.crt ]; then
  openssl ca -md sha256 -days 3650 -cert demoCA/localhostCA.crt -keyfile demoCA/localhostCA.key -in demoCA/localhost.csr -out demoCA/localhost.crt <demoCA/yy
fi
if [ -e demoCA/CAcreation ]; then
  echo Please install the generated Localhost CA certificate demoCA/localhostCA.crt as Trusted Certificate for SSL
  if [ "`uname`" = "Darwin" ]; then
    open demoCA/localhostCA.crt
  fi
fi
http-server "$1" -d false -c-1 -r -a localhost -p 8887 --cors=If-Modified-Since --ssl --cert demoCA/localhost.crt --key demoCA/localhost.key
```

#### Notes:
- The XLIFF folder should contain only the target XLIFF file(s) for the project for security.
- The HTTP server is accessible only from the localhost and disallows directory listing.
- If the XLIFF file name is prefixed with an unpredictable string, it can serve as a kind of "password" to block malicious access from other local HTTP clients.

## Build

### Bundle dependent components with `polymer-build` bundler

With lazy loader `live-localizer-lazy.html`, `live-localizer-main.html` and its dependencies are lazily loaded.
The dependent components except for region flag images can be bundled with `polymer-build` bundler as follows.

#### `polymer.json` with bundled `live-localizer` dependencies: applied to [`polymer init i18n-starter-kit`](https://github.com/t2ym/generator-polymer-init-i18n-starter-kit)
```javascript
{
  "entrypoint": "index.html",
  "shell": "src/my-app.html",
  "fragments": [
    "src/my-view1.html",
    "src/my-view2.html",
    "src/my-view3.html",
    "src/my-view404.html",
    "bower_components/live-localizer/live-localizer-main.html"
  ],
  "sourceGlobs": [
    "src/**/*",
    "images/**/*",
    "locales/*",
    "xliff/*",
    "bundle.json",
    "bower.json"
  ],
  "includeDependencies": [
    "manifest.json",
    "bower_components/webcomponentsjs/webcomponents-lite.min.js",
    "bower_components/intl/**/*",
    "bower_components/region-flags/**/*"
  ]
}
```

## TODOs

- Code cleanup/optimization/refactoring
- Automated tests
- Documentation
- Fix issues

## Plans

TBD

## License

[BSD-2-Clause](https://github.com/t2ym/live-localizer/blob/master/LICENSE.md)


text:
# README #

File-Translator helps you translate your Android app using Google Translate.

### Getting started ###

* [Download the library](https://github.com/mathieudebrito/file-translator#download)
* Add a dedicated module into your project
* Add the library to the newly created module
* Create the runnable

### Dedicate a specific module to translation ? ###

* Right-click on the main project
* Click on *add a new module*
* Select *Java module*

### Download ###

##### Using gradle #####

Add this line to your module dependencies
```gradle
    compile 'com.github.mathieudebrito:file-translator:2.0.+'
```

##### Using the .jar #####

* [Download the latest version](https://github.com/mathieudebrito/file-translator/releases)
* Put the jar into the */libs* folder
* Add this line to your module dependencies

```gradle
    compile fileTree(dir: 'libs', include: ['*.jar'])
```

### Create a runnable ###

```java
public class TranslateValues {

    public static final String GOOGLE_API_KEY = "YOUR-API-KEY";

    public static void main(String[] args) {

        Translator.Config config = new Translator.Config();
        config.key = GOOGLE_API_KEY;
        config.languageFrom = Language.ENGLISH;
        config.languageTo = Language.toList(Language.FRENCH, Language.ESTONIAN);
        config.excludes = Language.toList(Language.ESTONIAN);
        config.files.add(new FileToTranslate.Builder()
                .path(root).from("strings.xml").to("strings.xml")
                .fileNameOfEntriesToExclude("strings_translated.xml")
                .parser(new ResourcesStringsFileParser())
                .generator(new ResourcesStringsFileGenerator())
                .build());
        Translator translator = new TranslatorGoogle();
        translator.init(config);

        translator.translate();
    }
}
```

### Run the translator ###

* Right-click on the runnable java file
* Click on Run

## License

	 The MIT License (MIT)

	 Copyright (c) 2015 Mathieu de Brito

	 Permission is hereby granted, free of charge, to any person obtaining a copy
	 of this software and associated documentation files (the "Software"), to deal
	 in the Software without restriction, including without limitation the rights
	 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
	 copies of the Software, and to permit persons to whom the Software is
	 furnished to do so, subject to the following conditions:

	 The above copyright notice and this permission notice shall be included in all
	 copies or substantial portions of the Software.

	  IN NO EVENT SHALL THE
 	 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
	 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
	 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
	 SOFTWARE.

repository: mathieudebrito/file-translator

repo_name: mathieudebrito/file-translator


text:
![License](https://img.shields.io/static/v1?label=License&message=MIT&color=BLUE)
# react-portfolio

## Description

This weeks challenge was to rebuild our portfolio using React.JS. React is a popular Single-Page Application, or SPA, language that a lot of big companies like to use. Apps are popularly built in React because of their effciency when loading. Users will see quick load times beteen pages and also functional responsiveness across media devices. In my personal portfolio users can navigate between four pages, the "About", "Portfolio", "Contact" and "Resumé" pages. All of these pages load quickly and effciently thanks to React.

## Table of Contents

* [Installation](#installation)
* [Usage](#usage)
* [License](#license)
* [Contributing](#contributing)
* [Links](#links)
* [Questions](#questions)

## Installation

Run 'npm install' in the command line to install all the necessary dependencies if trying to run the app locally.

## Usage

To access this application simply navigate to https://aaroncenteno.github.io/react-portfolio/  and begin browsing my projects.

## Licenses

* MIT

## Contributing

* Aaron Centeno

## Technologies Used
* Node Modules
* GitHub
* JavaScript
* React.js
* Terminal
* CSS
* Font Awesome Library

## Screenshots

<img src="./public/react-portfolio.jpg">

## Links

Live App: https://aaroncenteno.github.io/react-portfolio/

GitHub Repo: https://github.com/aaroncenteno/react-portfolio

## Questions

Contact Information for questions:

GitHub: [aaroncenteno](https://www.github.com/aaroncenteno)

E-mail: asamcent@gmail.com

repository: aaroncenteno/react-portfolio

repo_name: aaroncenteno/react-portfolio