Skip to content

Commit

Permalink
Merge pull request #1 from COMPFEST/main
Browse files Browse the repository at this point in the history
Main
  • Loading branch information
mhmdhaekal authored Jun 24, 2024
2 parents f31d496 + 1b4c266 commit 6912a8d
Show file tree
Hide file tree
Showing 433 changed files with 27,444 additions and 7,179 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ node_modules
# misc
.DS_Store
.idea
.yarn
*.iml
*.log
.vscode
Expand Down
114 changes: 85 additions & 29 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,69 +1,93 @@
# umami
<p align="center">
<img src="https://umami.is/images/umami-logo.png" alt="Umami Logo" width="100">
</p>

Umami is a simple, fast, privacy-focused alternative to Google Analytics.
<h1 align="center">Umami</h1>

## Getting started
<p align="center">
<i>Umami is a simple, fast, privacy-focused alternative to Google Analytics.</i>
</p>

A detailed getting started guide can be found at [https://umami.is/docs/](https://umami.is/docs/)
<p align="center">
<a href="https://github.com/umami-software/umami/releases">
<img src="https://img.shields.io/github/release/umami-software/umami.svg" alt="GitHub Release" />
</a>
<a href="https://github.com/umami-software/umami/blob/master/LICENSE">
<img src="https://img.shields.io/github/license/umami-software/umami.svg" alt="MIT License" />
</a>
<a href="https://github.com/umami-software/umami/actions">
<img src="https://img.shields.io/github/actions/workflow/status/umami-software/umami/ci.yml" alt="Build Status" />
</a>
<a href="https://analytics.umami.is/share/LGazGOecbDtaIwDr/umami.is" style="text-decoration: none;">
<img src="https://img.shields.io/badge/Try%20Demo%20Now-Click%20Here-brightgreen" alt="Umami Demo" />
</a>
</p>

## Installing from source
---

## 🚀 Getting Started

A detailed getting started guide can be found at [umami.is/docs](https://umami.is/docs/).

---

## 🛠 Installing from Source

### Requirements

- A server with Node.js version 16.13 or newer
- A database. Umami supports [MySQL](https://www.mysql.com/) and [Postgresql](https://www.postgresql.org/) databases.
- A database. Umami supports [MySQL](https://www.mysql.com/) (minimum v8.0) and [PostgreSQL](https://www.postgresql.org/) (minimum v12.14) databases.

### Install Yarn

```
```bash
npm install -g yarn
```

### Get the source code and install packages
### Get the Source Code and Install Packages

```
```bash
git clone https://github.com/umami-software/umami.git
cd umami
yarn install
```

### Configure umami
### Configure Umami

Create an `.env` file with the following
Create an `.env` file with the following:

```
```bash
DATABASE_URL=connection-url
```

The connection url is in the following format:
The connection URL format:

```
```bash
postgresql://username:mypassword@localhost:5432/mydb
mysql://username:mypassword@localhost:3306/mydb
```

### Build the application
### Build the Application

```bash
yarn build
```

The build step will also create tables in your database if you are installing for the first time. It will also create a login user with username **admin** and password **umami**.
*The build step will create tables in your database if you are installing for the first time. It will also create a login user with username **admin** and password **umami**.*

### Start the application
### Start the Application

```bash
yarn start
```

By default this will launch the application on `http://localhost:3000`. You will need to either
[proxy](https://docs.nginx.com/nginx/admin-guide/web-server/reverse-proxy/) requests from your web server
or change the [port](https://nextjs.org/docs/api-reference/cli#production) to serve the application directly.
*By default, this will launch the application on `http://localhost:3000`. You will need to either [proxy](https://docs.nginx.com/nginx/admin-guide/web-server/reverse-proxy/) requests from your web server or change the [port](https://nextjs.org/docs/api-reference/cli#production) to serve the application directly.*

---

## Installing with Docker
## 🐳 Installing with Docker

To build the umami container and start up a Postgres database, run:
To build the Umami container and start up a Postgres database, run:

```bash
docker compose up -d
Expand All @@ -72,16 +96,18 @@ docker compose up -d
Alternatively, to pull just the Umami Docker image with PostgreSQL support:

```bash
docker pull ghcr.io/umami-software/umami:postgresql-latest
docker pull docker.umami.is/umami-software/umami:postgresql-latest
```

Or with MySQL support:

```bash
docker pull ghcr.io/umami-software/umami:mysql-latest
docker pull docker.umami.is/umami-software/umami:mysql-latest
```

## Getting updates
---

## 🔄 Getting Updates

To get the latest features, simply do a pull, install any new dependencies, and rebuild:

Expand All @@ -98,6 +124,36 @@ docker compose pull
docker compose up --force-recreate
```

## License

MIT
---

## 🛟 Support

<p align="center">
<a href="https://github.com/umami-software/umami">
<img src="https://img.shields.io/badge/GitHub--blue?style=social&logo=github" alt="GitHub" />
</a>
<a href="https://twitter.com/umami_software">
<img src="https://img.shields.io/badge/Twitter--blue?style=social&logo=twitter" alt="Twitter" />
</a>
<a href="https://linkedin.com/company/umami-software">
<img src="https://img.shields.io/badge/LinkedIn--blue?style=social&logo=linkedin" alt="LinkedIn" />
</a>
<a href="https://umami.is/discord">
<img src="https://img.shields.io/badge/Discord--blue?style=social&logo=discord" alt="Discord" />
</a>
</p>

[release-shield]: https://img.shields.io/github/release/umami-software/umami.svg
[releases-url]: https://github.com/umami-software/umami/releases
[license-shield]: https://img.shields.io/github/license/umami-software/umami.svg
[license-url]: https://github.com/umami-software/umami/blob/master/LICENSE
[build-shield]: https://img.shields.io/github/actions/workflow/status/umami-software/umami/ci.yml
[build-url]: https://github.com/umami-software/umami/actions
[github-shield]: https://img.shields.io/badge/GitHub--blue?style=social&logo=github
[github-url]: https://github.com/umami-software/umami
[twitter-shield]: https://img.shields.io/badge/Twitter--blue?style=social&logo=twitter
[twitter-url]: https://twitter.com/umami_software
[linkedin-shield]: https://img.shields.io/badge/LinkedIn--blue?style=social&logo=linkedin
[linkedin-url]: https://linkedin.com/company/umami-software
[discord-shield]: https://img.shields.io/badge/Discord--blue?style=social&logo=discord
[discord-url]: https://discord.com/invite/4dz4zcXYrQ
5 changes: 5 additions & 0 deletions cypress.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,9 @@ export default defineConfig({
e2e: {
baseUrl: 'http://localhost:3000',
},
// default username / password on init
env: {
umami_user: 'admin',
umami_password: 'umami',
},
});
3 changes: 2 additions & 1 deletion cypress/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,10 @@ services:
- CYPRESS_umami_user=admin
- CYPRESS_umami_password=umami
volumes:
- ../tsconfig.json:/tsconfig.json
- ./tsconfig.json:/tsconfig.json
- ../cypress.config.ts:/cypress.config.ts
- ./:/cypress
- ../node_modules/:/node_modules
- ../src/lib/crypto.ts:/src/lib/crypto.ts
volumes:
umami-db-data:
8 changes: 6 additions & 2 deletions cypress/e2e/login.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,12 @@ describe('Login tests', () => {
},
() => {
cy.visit('/login');
cy.getDataTest('input-username').find('input').type(Cypress.env('umami_user'));
cy.getDataTest('input-password').find('input').type(Cypress.env('umami_password'));
cy.getDataTest('input-username').find('input').click();
cy.getDataTest('input-username').find('input').type(Cypress.env('umami_user'), { delay: 50 });
cy.getDataTest('input-password').find('input').click();
cy.getDataTest('input-password')
.find('input')
.type(Cypress.env('umami_password'), { delay: 50 });
cy.getDataTest('button-submit').click();
cy.url().should('eq', Cypress.config().baseUrl + '/dashboard');
cy.getDataTest('button-profile').click();
Expand Down
30 changes: 14 additions & 16 deletions cypress/e2e/website.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,10 @@ describe('Website tests', () => {
cy.visit('/settings/websites');
cy.getDataTest('button-website-add').click();
cy.contains(/Add website/i).should('be.visible');
cy.getDataTest('input-name').find('input').wait(500).type('Add test', { delay: 50 });
cy.getDataTest('input-domain').find('input').wait(500).type('addtest.com', { delay: 50 });
cy.getDataTest('input-name').find('input').click();
cy.getDataTest('input-name').find('input').type('Add test', { delay: 50 });
cy.getDataTest('input-domain').find('input').click();
cy.getDataTest('input-domain').find('input').type('addtest.com', { delay: 50 });
cy.getDataTest('button-submit').click();
cy.get('td[label="Name"]').should('contain.text', 'Add test');
cy.get('td[label="Domain"]').should('contain.text', 'addtest.com');
Expand All @@ -26,27 +28,23 @@ describe('Website tests', () => {
cy.deleteWebsite(websiteId);
});
cy.visit('/settings/websites');
cy.contains('Add test').should('not.exist');
cy.contains(/Add test/i).should('not.exist');
});

it.only('Edit a website', () => {
it('Edit a website', () => {
// prep data
cy.addWebsite('Update test', 'updatetest.com');
cy.visit('/settings/websites');

// edit website
cy.getDataTest('link-button-edit').first().click();
cy.contains(/Details/i).should('be.visible');
cy.getDataTest('input-name')
.find('input')
.wait(500)
.clear()
.type('Updated website', { delay: 50 });
cy.getDataTest('input-domain')
.find('input')
.wait(500)
.clear()
.type('updatedwebsite.com', { delay: 50 });
cy.getDataTest('input-name').find('input').click();
cy.getDataTest('input-name').find('input').clear();
cy.getDataTest('input-name').find('input').type('Updated website', { delay: 50 });
cy.getDataTest('input-domain').find('input').click();
cy.getDataTest('input-domain').find('input').clear();
cy.getDataTest('input-domain').find('input').type('updatedwebsite.com', { delay: 50 });
cy.getDataTest('button-submit').click({ force: true });
cy.getDataTest('input-name').find('input').should('have.value', 'Updated website');
cy.getDataTest('input-domain').find('input').should('have.value', 'updatedwebsite.com');
Expand All @@ -69,7 +67,7 @@ describe('Website tests', () => {
cy.deleteWebsite(websiteId);
});
cy.visit('/settings/websites');
cy.contains('Add test').should('not.exist');
cy.contains(/Add test/i).should('not.exist');
});

it('Delete a website', () => {
Expand All @@ -86,6 +84,6 @@ describe('Website tests', () => {
cy.contains(/Type DELETE in the box below to confirm./i).should('be.visible');
cy.get('input[name="confirm"').type('DELETE');
cy.get('button[type="submit"]').click();
cy.contains('Delete test').should('not.exist');
cy.contains(/Delete test/i).should('not.exist');
});
});
90 changes: 90 additions & 0 deletions db/clickhouse/migrations/02_add_visit_id.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
CREATE TABLE umami.website_event_join
(
session_id UUID,
visit_id UUID,
created_at DateTime('UTC')
)
engine = MergeTree
ORDER BY (session_id, created_at)
SETTINGS index_granularity = 8192;

INSERT INTO umami.website_event_join
SELECT DISTINCT
s.session_id,
generateUUIDv4() visit_id,
s.created_at
FROM (SELECT DISTINCT session_id,
date_trunc('hour', created_at) created_at
FROM website_event) s;

-- create new table
CREATE TABLE umami.website_event_new
(
website_id UUID,
session_id UUID,
visit_id UUID,
event_id UUID,
hostname LowCardinality(String),
browser LowCardinality(String),
os LowCardinality(String),
device LowCardinality(String),
screen LowCardinality(String),
language LowCardinality(String),
country LowCardinality(String),
subdivision1 LowCardinality(String),
subdivision2 LowCardinality(String),
city String,
url_path String,
url_query String,
referrer_path String,
referrer_query String,
referrer_domain String,
page_title String,
event_type UInt32,
event_name String,
created_at DateTime('UTC'),
job_id UUID
)
engine = MergeTree
ORDER BY (website_id, session_id, created_at)
SETTINGS index_granularity = 8192;

INSERT INTO umami.website_event_new
SELECT we.website_id,
we.session_id,
j.visit_id,
we.event_id,
we.hostname,
we.browser,
we.os,
we.device,
we.screen,
we.language,
we.country,
we.subdivision1,
we.subdivision2,
we.city,
we.url_path,
we.url_query,
we.referrer_path,
we.referrer_query,
we.referrer_domain,
we.page_title,
we.event_type,
we.event_name,
we.created_at,
we.job_id
FROM umami.website_event we
JOIN umami.website_event_join j
ON we.session_id = j.session_id
and date_trunc('hour', we.created_at) = j.created_at

RENAME TABLE umami.website_event TO umami.website_event_old;
RENAME TABLE umami.website_event_new TO umami.website_event;

/*
DROP TABLE umami.website_event_old
DROP TABLE umami.website_event_join
*/
Loading

0 comments on commit 6912a8d

Please sign in to comment.