Skip to content

Commit

Permalink
Merge pull request #225 from openzim/ui-revamp-homepage
Browse files Browse the repository at this point in the history
Create homepage UI for channels in `zimui`
  • Loading branch information
benoit74 authored Jun 17, 2024
2 parents dff542d + 46d3b9e commit 690d22f
Show file tree
Hide file tree
Showing 47 changed files with 2,223 additions and 44 deletions.
17 changes: 16 additions & 1 deletion .github/workflows/Tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ jobs:
pip install -U pip build
python3 -m build --sdist --wheel
build-zimui:
build-and-test-zimui:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v3
Expand All @@ -65,11 +65,26 @@ jobs:
working-directory: zimui
run: |
yarn install
- name: Build
working-directory: zimui
run: |
yarn build
- name: Start web server
working-directory: zimui
run: |
yarn preview &
- name: Wait for web server to be ready
run: |
npx wait-on http://localhost:5173
- name: Run frontend tests
run: |
cd zimui
$(yarn bin)/cypress run
build-docker:
runs-on: ubuntu-22.04
steps:
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Update scraper to generate JSON files for `zimui` (#212)
- Remove old UI files and methods: template files (home.html, article.html) and `make_html_files` method in scraper.py
- Remove broken locale folder and files used for translation; translation will be restored with #222
- Create "Videos" and "Playlists" tabs for homepage in new Vue.js UI (#213, #214)

## [2.3.0] - 2024-05-22

Expand Down
54 changes: 54 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,57 @@ To add a new locale (`fr` in this example, use only ISO-639-1):
* Upload to PyPI `twine upload dist/youtube2zim-2.0.0*`.
* Commit your CHANGELOG + version bump changes
* Tag version on git `git tag -a v2.0.0`

## developing the ZIM UI in Vue.JS

Sometimes you need to alter something in the ZIM UI in Vue.JS but for this to work, you need assets which are generated by the scraper (e.g. channel.json, ...).

To simplify this, it is possible to:
- run the scraper (with original code base or your modified one)
- extract assets from generated files and place them in a directory where ZIM UI will find them
- iterate on ZIM UI code

To achieve this, first build the Docker image based on current code base.

```
docker build -t local-youtube2zim .
```

Scrape a channel (here we use the [openZIM_testing](https://www.youtube.com/channel/UC8elThf5TGMpQfQc_VE917Q) channel, but you could use any other one of interest for your UI developments).

```
docker run --rm -it -v "$PWD/output":/output local-youtube2zim youtube2zim --api-key <YOUR-API-KEY> --type channel --id "UC8elThf5TGMpQfQc_VE917Q" --name "openZIM_testing" --zim-file "openZIM_testing"
```

Extract interesting ZIM content and move it to `public` folder.

```
find zimui/public/ -mindepth 1 ! -name ".gitignore" -delete
docker run -it --rm -v $(pwd)/output:/data ghcr.io/openzim/zim-tools:latest zimdump dump --dir=/data/openZIM_testing /data/openZIM_testing.zim
sudo chown -R $(id -u -n):$(id -g -n) output/openZIM_testing
mv output/openZIM_testing/* zimui/public/
rm -rf output/openZIM_testing
```

Start ZIM UI locally.

```
cd zimui
yarn dev
```

Do not forget to cleanup `public` folder before building the docker image again, otherwise all assets will be pushed to the ZIM.

## testing with cypress

Cypress is used for end-to-end testing of the ZIM UI. It allows you to write tests that simulate user interactions with the application to ensure everything works as expected.

To run the tests, you need to start the ZIM UI locally and then run the tests.

```
cd zimui
yarn dev
yarn test:e2e
```

On Linux, you might need to install additional dependencies, see [Linux Prerequisites](https://docs.cypress.io/guides/getting-started/installing-cypress#Linux-Prerequisites) in the Cypress documentation.
15 changes: 0 additions & 15 deletions scraper/src/youtube2zim/scraper.py
Original file line number Diff line number Diff line change
Expand Up @@ -844,15 +844,6 @@ def download_authors_branding(self):
)
for channel_id in uniq_channel_ids:
save_channel_branding(self.channels_dir, channel_id, save_banner=False)
self.copy_default_banner(channel_id)

def copy_default_banner(self, channel_id):
banner_path = self.channels_dir / channel_id / "banner.jpg"
if not banner_path.exists():
shutil.copy(
self.templates_dir / "assets" / "banner.jpg",
self.channels_dir / channel_id / "banner.jpg",
)

def update_metadata(self):
# we use title, description, profile and banner of channel/user
Expand All @@ -867,7 +858,6 @@ def update_metadata(self):
save_channel_branding(
self.channels_dir, self.main_channel_id, save_banner=True
)
self.copy_default_banner(self.main_channel_id)

# if a single playlist was requested, use if for names;
# otherwise, use main_channel's details.
Expand Down Expand Up @@ -906,11 +896,6 @@ def update_metadata(self):
self.channels_dir.joinpath(self.main_channel_id, "profile.jpg"),
self.profile_path,
)
if not self.banner_path.exists():
shutil.copy(
self.channels_dir.joinpath(self.main_channel_id, "banner.jpg"),
self.banner_path,
)

# set colors from images if not supplied
if self.main_color is None or self.secondary_color is None:
Expand Down
Binary file removed scraper/src/youtube2zim/templates/assets/banner.jpg
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
10 changes: 10 additions & 0 deletions zimui/cypress.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { defineConfig } from 'cypress'

export default defineConfig({
e2e: {
setupNodeEvents() {
// implement node event listeners here
},
baseUrl: 'http://localhost:5173'
}
})
35 changes: 35 additions & 0 deletions zimui/cypress/e2e/channel_home_page.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
describe('home page for a channel', () => {
beforeEach(() => {
cy.intercept('GET', '/channel.json', { fixture: 'channel/channel.json' }).as('getChannel')
cy.intercept('GET', '/playlists/uploads_from_openzim_testing-917Q.json', {
fixture: 'channel/playlists/uploads_from_openzim_testing-917Q.json'
}).as('getUploads')
cy.visit('/')
cy.wait('@getChannel')
cy.wait('@getUploads')
})

it('loads the videos tab', () => {
cy.contains('2 videos').should('be.visible')
cy.contains('Coffee Machine').should('be.visible')
cy.contains('Timelapse').should('be.visible')
})

it('loads the playlist tab', () => {
cy.intercept('GET', '/playlists.json', { fixture: 'channel/playlists.json' }).as('getPlaylists')
cy.contains('.v-btn__content', 'Playlists').click()
cy.url().should('include', '/playlists')
cy.wait('@getPlaylists')

cy.contains('3 playlists').should('be.visible')
cy.contains('Timelapses').should('be.visible')
cy.contains('Trailers').should('be.visible')
cy.contains('Coffee').should('be.visible')
})

it('opens and loads "About Channel" dialog', () => {
cy.contains('.v-btn__content', 'About Channel').click()
cy.contains('Description for openZIM_testing').should('be.visible')
cy.contains('Jun 4, 2024').should('be.visible')
})
})
12 changes: 12 additions & 0 deletions zimui/cypress/fixtures/channel/channel.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"id": "UC8elThf5TGMpQfQc_VE917Q",
"title": "openZIM_testing",
"description": "-",
"channelName": "openZIM_testing",
"channelDescription": "Description for openZIM_testing",
"profilePath": "profile.jpg",
"bannerPath": "banner.jpg",
"joinedDate": "2024-06-04T13:30:16.232286Z",
"collectionType": "channel",
"mainPlaylist": "uploads_from_openzim_testing-917Q"
}
28 changes: 28 additions & 0 deletions zimui/cypress/fixtures/channel/playlists.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"playlists": [
{
"slug": "timelapses-QgGI",
"id": "PLMK6hZr9PcsjcF5mnaQk8Fi-xnb0AQgGI",
"title": "Timelapses",
"thumbnailPath": "videos/9TgosbGRsTk/video.webp",
"videosCount": 2,
"mainVideoSlug": "timelapse-9Tgo"
},
{
"slug": "trailers-5Gph",
"id": "PLMK6hZr9PcshJpNSRVaKReGlwhVlh5Gph",
"title": "Trailers",
"thumbnailPath": "videos/TcMBFSGVi1c/video.webp",
"videosCount": 1,
"mainVideoSlug": "marvel_studios_avengers_endgame_official_trailer-TcMB"
},
{
"slug": "coffee-O2wS",
"id": "PLMK6hZr9PcsjTJ5u2z-khzvDNXlqdO2wS",
"title": "Coffee",
"thumbnailPath": "videos/DYvYGQHYScc/video.webp",
"videosCount": 1,
"mainVideoSlug": "coffee_machine-DYvY"
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"id": "UU8elThf5TGMpQfQc_VE917Q",
"author": {
"channelId": "UC8elThf5TGMpQfQc_VE917Q",
"channelTitle": "openZIM_testing",
"profilePath": "channels/UC8elThf5TGMpQfQc_VE917Q/profile.jpg",
"bannerPath": "channels/UC8elThf5TGMpQfQc_VE917Q/banner.jpg"
},
"title": "Uploads from openZIM_testing",
"description": "",
"publicationDate": "2024-06-04T14:57:45Z",
"thumbnailPath": "videos/DYvYGQHYScc/video.webp",
"videos": [
{
"slug": "coffee_machine-DYvY",
"id": "DYvYGQHYScc",
"title": "Coffee Machine",
"thumbnailPath": "videos/DYvYGQHYScc/video.webp",
"duration": "PT9S"
},
{
"slug": "timelapse-9Tgo",
"id": "9TgosbGRsTk",
"title": "Timelapse",
"thumbnailPath": "videos/9TgosbGRsTk/video.webp",
"duration": "PT11S"
}
],
"videosCount": 2
}
37 changes: 37 additions & 0 deletions zimui/cypress/support/commands.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/// <reference types="cypress" />
// ***********************************************
// This example commands.ts shows you how to
// create various custom commands and overwrite
// existing commands.
//
// For more comprehensive examples of custom
// commands please read more here:
// https://on.cypress.io/custom-commands
// ***********************************************
//
//
// -- This is a parent command --
// Cypress.Commands.add('login', (email, password) => { ... })
//
//
// -- This is a child command --
// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... })
//
//
// -- This is a dual command --
// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... })
//
//
// -- This will overwrite an existing command --
// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... })
//
// declare global {
// namespace Cypress {
// interface Chainable {
// login(email: string, password: string): Chainable<void>
// drag(subject: string, options?: Partial<TypeOptions>): Chainable<Element>
// dismiss(subject: string, options?: Partial<TypeOptions>): Chainable<Element>
// visit(originalFn: CommandOriginalFn, url: string, options: Partial<VisitOptions>): Chainable<Element>
// }
// }
// }
20 changes: 20 additions & 0 deletions zimui/cypress/support/e2e.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// ***********************************************************
// This example support/e2e.ts is processed and
// loaded automatically before your test files.
//
// This is a great place to put global configuration and
// behavior that modifies Cypress.
//
// You can change the location of this file or turn off
// automatically serving support files with the
// 'supportFile' configuration option.
//
// You can read more here:
// https://on.cypress.io/configuration
// ***********************************************************

// Import commands.js using ES2015 syntax:
import './commands'

// Alternatively you can use CommonJS syntax:
// require('./commands')
10 changes: 10 additions & 0 deletions zimui/cypress/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"extends": "../tsconfig.json",
"compilerOptions": {
"noEmit": true,
// be explicit about types included
// to avoid clashing with Jest types
"types": ["cypress"]
},
"include": ["../node_modules/cypress", "./**/*.ts"]
}
6 changes: 5 additions & 1 deletion zimui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,21 @@
"name": "zimui",
"version": "0.0.0",
"private": true,
"type": "module",
"scripts": {
"dev": "vite",
"build": "run-p type-check \"build-only {@}\" --",
"preview": "vite preview",
"test:unit": "vitest",
"test:e2e": "cypress run",
"build-only": "vite build",
"type-check": "vue-tsc --build --force",
"lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore",
"format": "prettier --write src/"
},
"dependencies": {
"@fontsource/roboto": "^5.0.13",
"axios": "^1.7.2",
"dayjs": "^1.11.11",
"pinia": "^2.1.7",
"vite-plugin-vuetify": "^2.0.3",
"vue": "^3.4.21",
Expand All @@ -31,6 +34,7 @@
"@vue/eslint-config-typescript": "^13.0.0",
"@vue/test-utils": "^2.4.5",
"@vue/tsconfig": "^0.5.1",
"cypress": "^13.11.0",
"eslint": "^8.57.0",
"eslint-plugin-vue": "^9.23.0",
"jsdom": "^24.0.0",
Expand Down
1 change: 1 addition & 0 deletions zimui/public/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
*
12 changes: 11 additions & 1 deletion zimui/src/App.vue
Original file line number Diff line number Diff line change
@@ -1,11 +1,21 @@
<script setup lang="ts">
import { RouterView } from 'vue-router'
import { useMainStore } from '@/stores/main'
import ErrorDisplay from '@/components/common/ErrorDisplay.vue'
const main = useMainStore()
</script>

<template>
<v-app>
<v-main>
<router-view />
<div v-if="main.errorMessage">
<error-display />
</div>
<div v-else>
<router-view />
</div>
</v-main>
</v-app>
</template>
Expand Down
Binary file added zimui/src/assets/images/banner-placeholder.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added zimui/src/assets/images/dead-kiwix.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added zimui/src/assets/images/profile-placeholder.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added zimui/src/assets/images/thumbnail-placeholder.webp
Binary file not shown.
Loading

0 comments on commit 690d22f

Please sign in to comment.