0
0
mirror of https://github.com/cucumber-sp/yandex-music-linux.git synced 2024-12-23 22:22:59 +03:00

Merge branch 'master' into dev

This commit is contained in:
Andrey Onishchenko 2024-09-24 02:00:36 +03:00
commit 325e133f84
24 changed files with 441 additions and 218 deletions

View File

@ -19,7 +19,7 @@ jobs:
image: archlinux:latest image: archlinux:latest
steps: steps:
- name: Install packages - name: Install packages
run: pacman -Syy -q --noconfirm && pacman -S -q --noconfirm git sudo base-devel p7zip nodejs jq asar electron29 libpulse dpkg unzip xdg-utils python rpm-tools run: pacman -Syy -q --noconfirm && pacman -S -q --noconfirm git sudo base-devel p7zip nodejs jq asar dpkg unzip python rpm-tools glibc icu
- name: Checkout - name: Checkout
uses: actions/checkout@v4 uses: actions/checkout@v4
with: with:
@ -29,10 +29,10 @@ jobs:
run: mkdir -p dist run: mkdir -p dist
- name: Fix permissions for build - name: Fix permissions for build
run: mkdir /home/build && chgrp nobody /home/build && chmod g+ws /home/build && setfacl -m u::rwx,g::rwx /home/build && setfacl -d --set u::rwx,g::rwx,o::- /home/build && chown nobody . run: mkdir /home/build && chgrp nobody /home/build && chmod g+ws /home/build && setfacl -m u::rwx,g::rwx /home/build && setfacl -d --set u::rwx,g::rwx,o::- /home/build && chown nobody . && mkdir -p arch && chown nobody arch
- name: Make Arch package - name: Make Arch package
run: sudo -u nobody makepkg --log && mv *.pkg.tar.zst dist/ run: cp PKGBUILD arch && cd arch && sudo -u nobody makepkg -d --log && mv *.pkg.tar.zst ../dist/ && mv ./src/app/yandex-music.asar ../dist/ && mv ./src/app/release_notes.json ../dist/ && cd .. && rm -rf arch
- name: Build tarball packages - name: Build tarball packages
run: bash ./build_tarball.sh -a all && cp tar/* dist/ run: bash ./build_tarball.sh -a all && cp tar/* dist/
@ -43,9 +43,6 @@ jobs:
- name: Build RPM packages - name: Build RPM packages
run: bash ./build_rpm.sh && mv rpm/*.rpm dist run: bash ./build_rpm.sh && mv rpm/*.rpm dist
- name: Retrieve Asar and release notes
run: mv ./src/app/yandex-music.asar dist/yandex-music.asar && mv ./src/app/release_notes.json dist/release_notes.json
- name: Upload Arch artifacts - name: Upload Arch artifacts
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
with: with:

View File

@ -18,7 +18,7 @@ jobs:
steps: steps:
- name: Install dependencies - name: Install dependencies
run: pacman -Syy -q --noconfirm && pacman -S -q --noconfirm git jq nix python python-requests run: pacman -Syy -q --noconfirm && pacman -S -q --noconfirm git jq nix python python-requests openssl gcc-libs glibc
- name: Checkout - name: Checkout
uses: actions/checkout@v4 uses: actions/checkout@v4
@ -49,6 +49,13 @@ jobs:
echo "VERSION=$VERSION" >> $GITHUB_OUTPUT echo "VERSION=$VERSION" >> $GITHUB_OUTPUT
echo "release_name=$release_name" >> $GITHUB_OUTPUT echo "release_name=$release_name" >> $GITHUB_OUTPUT
echo "tag_name=$tag_name" >> $GITHUB_OUTPUT echo "tag_name=$tag_name" >> $GITHUB_OUTPUT
- name: Tag Repo
uses: rickstaa/action-create-tag@v1
with:
tag: ${{ steps.version.outputs.tag_name }}
force_push_tag: true
commit_sha: ${{ steps.commit.outputs.commit_long_sha || github.event.head_commit.id}}
- name: Outputs - name: Outputs
id: outputs id: outputs
@ -63,12 +70,12 @@ jobs:
outputs: outputs:
commited: ${{ steps.outputs.commited != '' }} commited: ${{ steps.outputs.outputs.commited != '' }}
commit_long_sha: ${{ steps.outputs.commit_long_sha }} commit_long_sha: ${{ steps.outputs.outputs.commit_long_sha }}
commit_name: ${{ steps.outputs.commit_name }} commit_name: ${{ steps.outputs.outputs.commit_name }}
tag_name: ${{ steps.outputs.tag_name }} tag_name: ${{ steps.outputs.outputs.tag_name }}
release_name: ${{ steps.outputs.release_name }} release_name: ${{ steps.outputs.outputs.release_name }}
version: ${{ steps.outputs.VERSION }} version: ${{ steps.outputs.outputs.VERSION }}
build: build:
@ -81,7 +88,7 @@ jobs:
upload-release: upload-release:
needs: [build, update_packages] needs: [build, update_packages]
if: ${{ needs.update_packages.outputs.commited && github.ref_name == 'main' }} if: ${{ needs.update_packages.outputs.commited && github.ref_name == 'master' }}
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout - name: Checkout
@ -90,7 +97,7 @@ jobs:
ref: ${{ needs.update_packages.outputs.commit_long_sha }} ref: ${{ needs.update_packages.outputs.commit_long_sha }}
- name: Publish package changes to AUR - name: Publish package changes to AUR
uses: KSXGitHub/github-actions-deploy-aur@v2.7.0 uses: KSXGitHub/github-actions-deploy-aur@v2.7.2
with: with:
pkgname: "yandex-music" pkgname: "yandex-music"
pkgbuild: "PKGBUILD" pkgbuild: "PKGBUILD"
@ -100,7 +107,7 @@ jobs:
commit_email: "loraner123@gmail.com" commit_email: "loraner123@gmail.com"
ssh_private_key: "${{ secrets.AUR_SSH_PRIVATE_KEY }}" ssh_private_key: "${{ secrets.AUR_SSH_PRIVATE_KEY }}"
commit_message: "${{ needs.update_packages.outputs.commit_name }}" commit_message: "${{ needs.update_packages.outputs.commit_name }}"
ssh_keyscan_types: "rsa,dsa,ecdsa,ed25519" ssh_keyscan_types: "rsa,ecdsa,ed25519"
- name: Download artifact - name: Download artifact
uses: actions/download-artifact@v4 uses: actions/download-artifact@v4
@ -118,14 +125,7 @@ jobs:
run: echo "release_html=$(jq -r --arg version "${{ needs.update_packages.outputs.version }}" '.["desktop-release-notes." + $version]' ./dist/release_notes.json)" >> $GITHUB_OUTPUT run: echo "release_html=$(jq -r --arg version "${{ needs.update_packages.outputs.version }}" '.["desktop-release-notes." + $version]' ./dist/release_notes.json)" >> $GITHUB_OUTPUT
- run: rm -rf dist/release_notes.json - run: rm -rf dist/release_notes.json
- name: Tag Repo
uses: richardsimko/update-tag@v1
with:
tag_name: ${{ needs.update_packages.outputs.tag_name}}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Upload files to a GitHub release - name: Upload files to a GitHub release
uses: ncipollo/release-action@v1.13.0 uses: ncipollo/release-action@v1.13.0
with: with:

View File

@ -1,20 +1,20 @@
# Maintainer: Andrey Onischenko loraner123@gmail.com # Maintainer: Andrey Onischenko loraner123@gmail.com
pkgname=yandex-music pkgname=yandex-music
pkgver="5.0.14" pkgver=5.18.2
pkgrel="1" pkgrel=1
pkgdesc="Yandex Music - Personal recommendations, selections for any occasion and new music" pkgdesc="Yandex Music - Personal recommendations, selections for any occasion and new music"
arch=("any") arch=("any")
url="https://github.com/cucumber-sp/yandex-music-linux" url="https://github.com/cucumber-sp/yandex-music-linux"
license=("custom") license=("Unlicense")
depends=("electron29" "libpulse" "xdg-utils") depends=("electron29" "libpulse" "xdg-utils" "bash" "hicolor-icon-theme")
makedepends=("p7zip" "nodejs" "asar" "jq" "python") makedepends=("p7zip" "nodejs" "asar" "jq" "python" "git")
source=("https://music-desktop-application.s3.yandex.net/stable/Yandex_Music_x64_5.0.14.exe" "git+https://github.com/cucumber-sp/yandex-music-linux") source=("https://music-desktop-application.s3.yandex.net/stable/Yandex_Music_x64_5.18.2.exe" "git+${url}#tag=v${pkgver}")
sha256sums=("c10c6c4b5d596f9bf490a231d7c13bbd2627109f71c9c57aa4e2b034e31252f4" "SKIP") sha256sums=("a513eb6aa4bd05bae8503f5578a8e91d778794ffe4eb3a450040903570106941" "SKIP")
build() { build() {
bash "$srcdir/yandex-music-linux/repack.sh" "$srcdir/Yandex_Music_x64_5.0.14.exe" bash "$srcdir/yandex-music-linux/repack.sh" "$srcdir/Yandex_Music_x64_5.18.2.exe"
} }
package() { package() {
@ -31,9 +31,10 @@ package() {
install -Dm644 "$srcdir/yandex-music-linux/templates/desktop" "$pkgdir/usr/share/applications/yandex-music.desktop" install -Dm644 "$srcdir/yandex-music-linux/templates/desktop" "$pkgdir/usr/share/applications/yandex-music.desktop"
install -Dm644 "$srcdir/yandex-music-linux/templates/default.conf" "$pkgdir/usr/lib/yandex-music/default.conf" install -Dm644 "$srcdir/yandex-music-linux/templates/default.conf" "$pkgdir/usr/lib/yandex-music/default.conf"
sed -i "s|%electron_path%|/usr/bin/electron29|g" "$pkgdir/usr/lib/yandex-music/default.conf"
install -Dm644 "$srcdir/yandex-music-linux/LICENSE.md" "$pkgdir/usr/share/licenses/$pkgname/LICENSE" install -Dm644 "$srcdir/yandex-music-linux/LICENSE.md" "$pkgdir/usr/share/licenses/$pkgname/LICENSE"
install -Dm755 "$srcdir/yandex-music-linux/templates/yandex-music.sh" "$pkgdir/usr/bin/yandex-music" install -Dm755 "$srcdir/yandex-music-linux/templates/yandex-music.sh" "$pkgdir/usr/bin/yandex-music"
sed -i "s|%electron_path%|/usr/bin/electron29|g" "$pkgdir/usr/bin/yandex-music"
sed -i "s|%asar_path%|/usr/lib/yandex-music/yandex-music.asar|g" "$pkgdir/usr/bin/yandex-music"
} }

170
README.md
View File

@ -8,16 +8,28 @@ Native YandexMusic client for Linux. Built using repacking of Windows client (El
- [Installation](#installation) - [Installation](#installation)
- [Arch Linux](#arch-linux) - [Arch Linux](#arch-linux)
- [Debian/Ubuntu](#debianubuntu) - [Debian/Ubuntu](#debianubuntu)
- [RPM-based](#rpm-based)
- [Configuration](#configuration)
- [Configuration file](#configuration-file)
- [Custom Electron binary](#custom-electron-binary)
- [Electron arguments](#electron-arguments)
- [Tray mode](#tray-mode)
- [Manual Build](#manual-build) - [Manual Build](#manual-build)
- [Prerequisites](#prerequisites) - [Prerequisites](#prerequisites)
- [Extract app only](#extract-app-only) - [Extract app only](#extract-app-only)
- [ASAR archive](#asar-archive) - [ASAR archive](#asar-archive)
- [Arch Linux](#arch-linux-1) - [Arch Linux](#arch-linux-1)
- [Debian/Ubuntu](#debianubuntu-1) - [Debian/Ubuntu](#debianubuntu-1)
- [RPM-based](#rpm-based-1)
- [Run with nix](#run-with-nix) - [Run with nix](#run-with-nix)
- [Run with flakes](#run-with-flakes) - [NixOS unstable](#nixos-unstable)
- [Run old style](#run-old-style) - [Run from unstable channel with flakes](#run-from-unstable-channel-with-flakes)
- [Install to NixOS](#install-to-nixos) - [Install from unstable channel](#install-from-unstable-channel)
- [Overriding](#overriding)
- [Built-in module](#built-in-module)
- [Run with flakes](#run-with-flakes)
- [Run old style](#run-old-style)
- [Install to NixOS](#install-to-nixos)
## Screenshots ## Screenshots
![image](https://github.com/cucumber-sp/yandex-music-linux/assets/100789522/ab2f69ee-efc4-4a33-8110-131b4c4ff4de) ![image](https://github.com/cucumber-sp/yandex-music-linux/assets/100789522/ab2f69ee-efc4-4a33-8110-131b4c4ff4de)
@ -28,8 +40,6 @@ Native YandexMusic client for Linux. Built using repacking of Windows client (El
### Arch Linux ### Arch Linux
***
#### AUR #### AUR
You can obtain the latest version of package from `AUR` using one of the [AUR Helpers](https://wiki.archlinux.org/title/AUR_helpers). Then install it with `yandex-music` as package name. You can obtain the latest version of package from `AUR` using one of the [AUR Helpers](https://wiki.archlinux.org/title/AUR_helpers). Then install it with `yandex-music` as package name.
@ -54,11 +64,18 @@ pacman -U yandex-music-<version>-any.pkg.tar.zst
### Debian/Ubuntu ### Debian/Ubuntu
***
#### APT #### APT
Package is currently unavailable at APT. We're still working on it Download key and add repository to mirror list
```bash
curl -fsSL https://apt.cucumber-space.online/key.gpg | sudo gpg --dearmor -o /etc/apt/keyrings/cucumber-space.key.gpg
echo 'deb [signed-by=/etc/apt/keyrings/cucumber-space.key.gpg] https://apt.cucumber-space.online ./' | sudo tee /etc/apt/sources.list.d/cucumber-space.list > /dev/null
sudo apt update
```
Then you can install app with
```bash
sudo apt install yandex-music
```
#### Binary package file #### Binary package file
@ -72,6 +89,67 @@ dpkg -i yandex-music_<version>_<arch>.deb
*** ***
### RPM-based
#### DNF
Package is currently unavailable at DNF. If you'd like to help us with publishing, feel free to open new issue.
#### Binary package file
Download prebuilt binary package from [Releases](https://github.com/cucumber-sp/yandex-music-linux/releases) section.
Unfortunatelly, we only provide packages for x64 architecture. If you need package for different architecture, you can build it manually.
Then you can install it with the following command
```bash
rpm -i yandex-music-<version>-1.x86_64.rpm
```
***
## Configuration
### Configuration file
You can find configuration file at `HOME/.config/yandex-music.conf`. It's a simple `key=value` file that's sourced before launching the app. This means you can set environment variables and other options there.
***
### Custom Electron binary
You can set path to custom Electron binary with `ELECTRON_CUSTOM_BIN` option. For example:
```bash
ELECTRON_CUSTOM_BIN=/usr/bin/electron
```
***
### Electron arguments
You can set custom Electron flags with `ELECTRON_ARGS` option. By default it's set to `--no-sandbox`. For example:
```bash
ELECTRON_ARGS="--no-sandbox --trace-warnings"
```
***
### Tray mode
Tray mode is disabled by default. It allows program to be minimized to tray instead of closing. To enable it set `TRAY_ENABLED` option to `1`.
![image](https://github.com/cucumber-sp/yandex-music-linux/assets/100789522/5998ba7f-9ee7-4725-9d51-fbe5510a799d)
***
### Dev tools
Chromium developer/debug tools can be enabled by setting `DEV_TOOLS` option to `1`.
***
## Manual Build ## Manual Build
### Prerequisites ### Prerequisites
@ -137,12 +215,55 @@ bash build_deb.sh [-a <x64|armv7l|arm64|all> default=x64]
*** ***
### RPM-based
You can build `.rpm` binary package using the following command:
```bash
bash build_rpm.sh [-a <x64|armv7l|arm64|all> default=x64]
```
## Run with nix ## Run with nix
The `yandex-music` package has unlicensed license, so you need to have The `yandex-music` package has unlicensed license, so you need to have
`allowUnfree` option enabled. `allowUnfree` option enabled.
### Run with flakes ### NixOS unstable
The `yandex-music` package is
[available](https://github.com/NixOS/nixpkgs/pull/337425) at nixos-unstable
channel.
#### Run from unstable channel with flakes
```bash
nix run github:NixOS/nixpkgs/nixos-unstable#yandex-music
```
#### Install from unstable channel
Add next to your configuration:
```nix
environment.systemPackages = with pkgs; [ yandex-music ];
```
#### Overriding
There is several option of package available to override:
```nix
yandex-music.override {
trayEnabled = true; # Whenether to enable tray support
electronArguments = ""; # Extra arguments to electron executable
}
```
### Built-in module
This repository contains its own nix-related receipts.
#### Run with flakes
Execute next to build and run yandex music directly from github Execute next to build and run yandex music directly from github
@ -150,7 +271,7 @@ Execute next to build and run yandex music directly from github
nix run github:cucumber-sp/yandex-music-linux nix run github:cucumber-sp/yandex-music-linux
``` ```
### Run old style #### Run old style
Execute next in this repository to build yandex-music package without using Execute next in this repository to build yandex-music package without using
flakes. flakes.
@ -159,7 +280,7 @@ flakes.
nix-build --expr '(import <nixpkgs> {}).callPackage ./nix {}' nix-build --expr '(import <nixpkgs> {}).callPackage ./nix {}'
``` ```
### Install to NixOS #### Install to NixOS
1. Add input in your flake.nix 1. Add input in your flake.nix
@ -169,27 +290,24 @@ nix-build --expr '(import <nixpkgs> {}).callPackage ./nix {}'
}; };
``` ```
2. Import module in your `configuration.nix` or `home-manager.nix` 2. Import module in your `configuration.nix`:
```nix ```nix
imports = [ imports = [
yandex-music.nixosModule yandex-music.nixosModules.default
]; ];
``` ```
3. Add package `yandex-music` or in `home-manager.nix`:
```nix
imports = [
yandex-music.homeManagerModules.default
];
```
For `configuration.nix`:
3. Enable `yandex-music`
```nix ```nix
environment.systemPackages = with pkgs; [ programs.yandex-music.enable = true;
yandex-music programs.yandex-music.tray.enable = true; # to enable tray support
];
```
For Home Manager:
```nix
home.packages = with pkgs; [
yandex-music
];
``` ```

View File

@ -34,14 +34,15 @@ build_tarball(){
install -Dm644 "${TEMPDIR}/app/favicon.png" "${app_dir}/usr/share/pixmaps/yandex-music.png" install -Dm644 "${TEMPDIR}/app/favicon.png" "${app_dir}/usr/share/pixmaps/yandex-music.png"
install -Dm644 "${TEMPDIR}/app/favicon.png" "${app_dir}/usr/share/icons/hicolor/48x48/apps/yandex-music.png" install -Dm644 "${TEMPDIR}/app/favicon.png" "${app_dir}/usr/share/icons/hicolor/48x48/apps/yandex-music.png"
install -Dm644 "${TEMPDIR}/app/favicon.svg" "${app_dir}/usr/share/icons/hicolor/scalable/apps/yandex-music.svg" install -Dm644 "${TEMPDIR}/app/favicon.svg" "${app_dir}/usr/share/icons/hicolor/scalable/apps/yandex-music.svg"
install -Dm644 "./templates/desktop" "${app_dir}/usr/share/applications/yandex-music.desktop" install -Dm644 "./templates/desktop" "${app_dir}/usr/share/applications/yandex-music.desktop"
install -Dm644 "./templates/default.conf" "${app_dir}/usr/lib/yandex-music/default.conf" install -Dm644 "./templates/default.conf" "${app_dir}/usr/lib/yandex-music/default.conf"
sed -i "s|%electron_path%|/usr/lib/yandex-music/electron/electron|g" "${app_dir}/usr/lib/yandex-music/default.conf"
install -Dm644 "./LICENSE.md" "${app_dir}/usr/share/licenses/yandex-music/LICENSE" install -Dm644 "./LICENSE.md" "${app_dir}/usr/share/licenses/yandex-music/LICENSE"
mv "${TEMPDIR}/electron-${arch}/" "${app_dir}/usr/lib/yandex-music/electron" mv "${TEMPDIR}/electron-${arch}/" "${app_dir}/usr/lib/yandex-music/electron"
install -Dm755 "./templates/yandex-music.sh" "${app_dir}/usr/bin/yandex-music" install -Dm755 "./templates/yandex-music.sh" "${app_dir}/usr/bin/yandex-music"
sed -i "s|%electron_path%|/usr/lib/yandex-music/electron/electron|g" "${app_dir}/usr/bin/yandex-music"
sed -i "s|%asar_path%|/usr/lib/yandex-music/yandex-music.asar|g" "${app_dir}/usr/bin/yandex-music"
cd "${app_dir}" cd "${app_dir}"
tar -czf "${OUTPUT_DIR}/yandex-music_${version}_${arch}.tar.gz" * tar -czf "${OUTPUT_DIR}/yandex-music_${version}_${arch}.tar.gz" *
@ -128,4 +129,4 @@ fi
if [ ${arm64} -eq 1 ]; then if [ ${arm64} -eq 1 ]; then
download_electron_binary "arm64" download_electron_binary "arm64"
build_tarball "arm64" build_tarball "arm64"
fi fi

View File

@ -56,13 +56,13 @@
"ymExe": { "ymExe": {
"flake": false, "flake": false,
"locked": { "locked": {
"narHash": "sha256-6YOx1r40nBcexbeqmQn5/FkuUaHxRrg4Qn1mEwPVnTs=", "narHash": "sha256-DtSXyYlViRVFWka3SLVaJjB/r6lgaQEPbCM7uXvmtHI=",
"type": "file", "type": "file",
"url": "https://music-desktop-application.s3.yandex.net/stable/Yandex_Music_x64_5.0.14.exe" "url": "https://music-desktop-application.s3.yandex.net/stable/Yandex_Music_x64_5.18.2.exe"
}, },
"original": { "original": {
"type": "file", "type": "file",
"url": "https://music-desktop-application.s3.yandex.net/stable/Yandex_Music_x64_5.0.14.exe" "url": "https://music-desktop-application.s3.yandex.net/stable/Yandex_Music_x64_5.18.2.exe"
} }
} }
}, },

View File

@ -2,40 +2,38 @@
description = "Native Yandex Music desktop client"; description = "Native Yandex Music desktop client";
inputs = { inputs = {
ymExe.url = https://music-desktop-application.s3.yandex.net/stable/Yandex_Music_x64_5.0.14.exe; ymExe.url = "https://music-desktop-application.s3.yandex.net/stable/Yandex_Music_x64_5.18.2.exe";
ymExe.flake = false; ymExe.flake = false;
}; };
outputs = { self, ymExe, nixpkgs, flake-utils }: outputs = { self, ymExe, nixpkgs, flake-utils }:
let let
yandex-music-with = pkgs: pkgs.callPackage ./nix { yandex-music-with = pkgs: pkgs.callPackage ./nix {
inherit ymExe; inherit ymExe;
};
in
flake-utils.lib.eachDefaultSystem
(system:
let
pkgs = import nixpkgs { inherit system; };
in
{
packages = rec {
yandex-music = yandex-music-with pkgs;
yandex-music-noflakes = pkgs.callPackage ./nix {};
default = yandex-music;
};
}
) // {
nixosModules = rec {
yandex-music = {
nixpkgs.overlays = [
(final: prev: {
yandex-music = yandex-music-with prev;
})
];
}; };
default = yandex-music; modules = isHm: rec {
}; yandex-music = {
imports = [ (import ./nix/module.nix { inherit isHm yandex-music-with; }) ];
};
default = yandex-music;
};
in
flake-utils.lib.eachDefaultSystem
(system:
let
pkgs = import nixpkgs { inherit system; };
in
{
packages = rec {
yandex-music = yandex-music-with pkgs;
yandex-music-noflakes = pkgs.callPackage ./nix { };
default = yandex-music;
};
}
) // {
nixosModules = modules false;
homeManagerModules = modules true;
nixosModule = self.nixosModules.default; nixosModule = self.nixosModules.default;
}; };
} }

View File

@ -10,6 +10,8 @@
, electron , electron
, ymExe ? null , ymExe ? null
, electronArguments ? ""
, trayEnabled ? false
}: }:
let let
version_info = with builtins; fromJSON (readFile ../utility/version_info.json); version_info = with builtins; fromJSON (readFile ../utility/version_info.json);
@ -32,6 +34,7 @@ stdenvNoCC.mkDerivation
utility = ./../utility; utility = ./../utility;
icons = ./../icons; icons = ./../icons;
desktopItem = ../templates/desktop; desktopItem = ../templates/desktop;
ymScript = ../templates/yandex-music.sh;
src = src =
if ymExe != null if ymExe != null
then ymExe then ymExe
@ -54,9 +57,17 @@ stdenvNoCC.mkDerivation
mkdir -p "$out/share/nodejs" mkdir -p "$out/share/nodejs"
mv app/yandex-music.asar "$out/share/nodejs" mv app/yandex-music.asar "$out/share/nodejs"
# use makeWrapper on electron binary to make it call our asar package CONFIG_FILE="$out/share/yandex-music.conf"
makeWrapper "${electron}/bin/electron" "$out/bin/yandex-music" \ echo "TRAY_ENABLED=${if trayEnabled then "1" else "0"}" >> "$CONFIG_FILE"
--add-flags "$out/share/nodejs/yandex-music.asar" echo "ELECTRON_ARGS=\"${electronArguments}\"" >> "$CONFIG_FILE"
install -Dm755 "$ymScript" "$out/bin/yandex-music"
sed -i "s|%electron_path%|${electron}/bin/electron|g" "$out/bin/yandex-music"
sed -i "s|%asar_path%|$out/share/nodejs/yandex-music.asar|g" "$out/bin/yandex-music"
wrapProgram "$out/bin/yandex-music" \
--set-default YANDEX_MUSIC_CONFIG "$CONFIG_FILE"
install -Dm644 "./app/favicon.png" "$out/share/pixmaps/yandex-music.png" install -Dm644 "./app/favicon.png" "$out/share/pixmaps/yandex-music.png"
install -Dm644 "./app/favicon.png" "$out/share/icons/hicolor/48x48/apps/yandex-music.png" install -Dm644 "./app/favicon.png" "$out/share/icons/hicolor/48x48/apps/yandex-music.png"

53
nix/module.nix Normal file
View File

@ -0,0 +1,53 @@
{ yandex-music-with
, isHm ? false
}:
{ lib, pkgs, config, ... }:
let
cfg = config.programs.yandex-music;
in
{
imports = [{
nixpkgs.overlays = [
(final: prev: {
yandex-music = yandex-music-with prev;
})
];
}];
options = {
programs.yandex-music = {
enable = lib.mkEnableOption "yandex music application";
tray.enable = lib.mkEnableOption "tray icon for yandex music application";
electronArguments = lib.mkOption {
description = "Extra electron arguments";
example = "--no-sandbox --trace-warnings";
type = lib.types.str;
default = "";
};
package = lib.mkOption {
description = "Finalized package of yandex music application";
type = lib.types.package;
default = pkgs.yandex-music.override {
trayEnabled = cfg.tray.enable;
electronArguments = cfg.electronArguments;
};
};
};
};
config = lib.mkIf cfg.enable (
if isHm then
{
home.packages = [
cfg.package
];
}
else
{
environment.systemPackages = [
cfg.package
];
}
);
}

View File

@ -1,10 +1,10 @@
diff --git a/package.json b/package.json diff --git a/package.json b/package.json
--- a/package.json --- a/package.json
+++ b/package.json +++ b/package.json
@@ -39,5 +39,6 @@ @@ -50,5 +50,6 @@
"COPYRIGHT": "Яндекс Музыка", "kk",
"TRADEMARK": "Яндекс Музыка", "az"
"DEEPLINK_PROTOCOL": "yandexmusic" ]
- } - }
+ }, + },
+ "license": "UNLICENSED" + "license": "UNLICENSED"

View File

@ -1,14 +0,0 @@
diff --git a/package.json b/package.json
--- a/package.json
+++ b/package.json
@@ -40,5 +40,9 @@
"TRADEMARK": "Яндекс Музыка",
"DEEPLINK_PROTOCOL": "yandexmusic"
},
- "license": "UNLICENSED"
+ "license": "UNLICENSED",
+ "icon": {
+ "48x48": "build/next-desktop/favicon.png",
+ "scalable": "build/next-desktop/favicon.svg"
+ }
}

View File

@ -0,0 +1,84 @@
diff --git a/main/lib/createTray.js b/main/lib/createTray.js
--- a/main/lib/createTray.js
+++ b/main/lib/createTray.js
@@ -0,0 +1,21 @@
+const { app, Menu, Tray, nativeImage } = require('electron');
+const path = require('path');
+
+function createTray(window) {
+ const iconPath = path.join(__dirname, '../../app/favicon.png');
+ const tray = new Tray(iconPath);
+ const contextMenu = Menu.buildFromTemplate([
+ {label: 'Открыть', click: () => window.show()},
+ {label: 'Закрыть Яндекс Музыку', click: () => app.quit()}
+ ]);
+ tray.setToolTip('Яндекс Музыка');
+ tray.setContextMenu(contextMenu);
+
+ tray.on('click', () => {
+ window.show();
+ });
+ tray.setIgnoreDoubleClickEvents(true);
+}
+
+exports.createTray = createTray;
+
diff --git a/main/index.js b/main/index.js
--- a/main/index.js
+++ b/main/index.js
@@ -46,6 +46,9 @@ Logger_js_1.Logger.setupLogger();
(0, handleDeeplink_js_1.handleDeeplink)(window);
(0, handleMetrikaRequests_js_1.handleMetrikaRequests)(window);
(0, handleCrash_js_1.handleCrash)();
+ const {createTray} = require('./lib/createTray.js');
+ const trayEnabled = process.env.TRAY_ENABLED && process.env.TRAY_ENABLED > 0;
+ if (trayEnabled){createTray(window);}
await (0, loadURL_js_1.loadURL)(window);
if (node_os_1.default.platform() === platform_js_1.Platform.WINDOWS) {
(0, customTitleBar_js_1.createCustomTitleBar)(window);
diff --git a/main/lib/handlers/handleWindowLifecycleEvents.js b/main/lib/handlers/handleWindowLifecycleEvents.js
--- a/main/lib/handlers/handleWindowLifecycleEvents.js
+++ b/main/lib/handlers/handleWindowLifecycleEvents.js
@@ -31,9 +31,8 @@ const handleWindowLifecycleEvents = (window) => {
state_js_1.state.willQuit = true;
});
electron_1.app.on('window-all-closed', () => {
- if (node_os_1.default.platform() === platform_js_1.Platform.WINDOWS) {
- electron_1.app.quit();
- }
+ const trayEnabled = process.env.TRAY_ENABLED && process.env.TRAY_ENABLED > 0;
+ if (!trayEnabled) {electron_1.app.quit();}
});
electron_1.app.on('browser-window-blur', () => {
setBlurredTime();
@@ -54,22 +53,11 @@ const handleWindowLifecycleEvents = (window) => {
checkAndUpdateApplicationData(window);
});
window.on('close', (event) => {
- if (node_os_1.default.platform() !== platform_js_1.Platform.MACOS) {
- return;
- }
- if (state_js_1.state.willQuit) {
- return;
- }
+ const trayEnabled = process.env.TRAY_ENABLED && process.env.TRAY_ENABLED > 0;
+ if (!trayEnabled) {electron_1.app.quit();}
+ if (state_js_1.state.willQuit) {return;}
event.preventDefault();
- if (window.isFullScreen()) {
- window.once('leave-full-screen', () => {
- (0, createWindow_js_1.toggleWindowVisibility)(window, false);
- });
- window.setFullScreen(false);
- }
- else {
- (0, createWindow_js_1.toggleWindowVisibility)(window, false);
- }
+ (0, createWindow_js_1.toggleWindowVisibility)(window, false);
});
const webContents = window.webContents;
webContents.on('did-fail-load', (event, errorCode, errorDescription, validatedUrl) => {

View File

@ -1,44 +0,0 @@
diff --git a/main/lib/createTray.js b/main/lib/createTray.js
--- a/main/lib/createTray.js
+++ b/main/lib/createTray.js
@@ -0,0 +1,20 @@
+const { app, Menu, Tray, nativeImage } = require('electron');
+const path = require('path');
+
+function createTray(window) {
+ const iconPath = path.join(__dirname, '../../build/next-desktop/favicon.png');
+ const tray = new Tray(iconPath);
+ const contextMenu = Menu.buildFromTemplate([
+ {label: 'Открыть', click: () => window.show()},
+ {label: 'Закрыть Яндекс Музыку', click: () => app.quit()}
+ ]);
+ tray.setToolTip('Яндекс Музыка');
+ tray.setContextMenu(contextMenu);
+
+ tray.on('click', () => {
+ window.show();
+ });
+ tray.setIgnoreDoubleClickEvents(true);
+}
+
+exports.createTray = createTray;
diff --git a/main/index.js b/main/index.js
--- a/main/index.js
+++ b/main/index.js
@@ -23,6 +23,7 @@ const handleMetrikaRequests_js_1 = require("./lib/handlers/handleMetrikaRequests
const loadURL_js_1 = require("./lib/loadURL.js");
const safeRedirects_js_1 = require("./lib/safeRedirects.js");
const handleWindowSessionEvents_js_1 = require("./lib/handlers/handleWindowSessionEvents.js");
+const {createTray} = require('./lib/createTray.js');
(0, handleError_js_1.handleUncaughtException)();
(0, singleInstance_js_1.checkForSingleInstance)();
(0, handleDeeplink_js_1.handleDeeplinkOnApplicationStartup)();
@@ -30,6 +31,7 @@ const handleWindowSessionEvents_js_1 = require("./lib/handlers/handleWindowSessi
await electron_1.app.whenReady();
(0, menu_js_1.setupMenu)();
const window = await (0, createWindow_js_1.createWindow)();
+ createTray(window);
(0, safeRedirects_js_1.safeRedirects)(window);
(0, handleWindowLifecycleEvents_js_1.handleWindowLifecycleEvents)(window);
(0, handleWindowSessionEvents_js_1.handleWindowSessionEvents)(window);

View File

@ -1,7 +1,7 @@
diff --git a/main/lib/createWindow.js b/main/lib/createWindow.js diff --git a/main/lib/createWindow.js b/main/lib/createWindow.js
--- a/main/lib/createWindow.js --- a/main/lib/createWindow.js
+++ b/main/lib/createWindow.js +++ b/main/lib/createWindow.js
@@ -16,8 +16,6 @@ const createWindow = async () => { @@ -45,8 +45,6 @@ const createWindow = async () => {
x: 16, x: 16,
y: 10 y: 10
}, },

View File

@ -0,0 +1,14 @@
diff --git a/main/config.js b/main/config.js
--- a/main/config.js
+++ b/main/config.js
@@ -5,8 +5,9 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
Object.defineProperty(exports, "__esModule", { value: true });
exports.applyCommonConfig = exports.config = void 0;
const package_json_1 = __importDefault(require("../package.json"));
+const devTools = process.env.DEV_TOOLS && process.env.DEV_TOOLS > 0;
exports.config = {
- enableDevTools: false,
+ enableDevTools: devTools,
enableWebSecurity: true,
enableAutoUpdate: true,
bypassCSP: false,

View File

@ -67,13 +67,14 @@ curdir="$PWD"
cd "$TEMPDIR/app" cd "$TEMPDIR/app"
# fixing secretKey issue
echo "Fixing SecretKey" echo "Fixing SecretKey"
echo "Spoofing OS"
find "./" -type f \( -name "*.js" -o -name "*.js.map" \) -print0 | while IFS= read -r -d $'\0' file; do find "./" -type f \( -name "*.js" -o -name "*.js.map" \) -print0 | while IFS= read -r -d $'\0' file; do
# Use 'sed' to perform the replacement in-place # Use 'sed' to perform the replacement in-place
sed -i "s/secretKey:this.secretKey/secretKey:'superSecretKey'/g" "$file" sed -i "s/a.t.WINDOWS/a.t.LINUX/g" "$file"
sed -i "s/B.LINUX/B.WINDOWS/g" "$file"
done done
echo "SecretKey replaced" echo "OS spoofed"
# fixing titile # fixing titile
echo "Fixing Title" echo "Fixing Title"
@ -84,7 +85,7 @@ done
echo "Title Fixed" echo "Title Fixed"
echo "Replacing Icons" echo "Replacing Icons"
cp -drf "$SCRIPT_DIR/icons/." "./build/next-desktop/" cp -drf "$SCRIPT_DIR/icons/." "./app/"
echo "Replaced Icons" echo "Replaced Icons"
# applying patches # applying patches
@ -131,8 +132,8 @@ echo "Packing"
cd "$curdir" cd "$curdir"
asar pack "$TEMPDIR/app" "$dst/yandex-music.asar" asar pack "$TEMPDIR/app" "$dst/yandex-music.asar"
for ext in png svg; do for ext in png svg; do
mv "$TEMPDIR/app/build/next-desktop/favicon.$ext" "$dst" mv "$TEMPDIR/app/app/favicon.$ext" "$dst"
done done
python "$SCRIPT_DIR/utility/extract_release_notes.py" "$TEMPDIR/app/build/next-desktop/album.txt" "$dst/release_notes.json" python "$SCRIPT_DIR/utility/extract_release_notes.py" "$TEMPDIR/app/main/translations/compiled/ru.json" "$dst/release_notes.json"
echo "Done" echo "Done"

View File

@ -1,16 +1,16 @@
# Maintainer: Andrey Onischenko loraner123@gmail.com # Maintainer: Andrey Onischenko loraner123@gmail.com
pkgname=yandex-music pkgname=yandex-music
pkgver="%version%" pkgver=%version%
pkgrel="%release%" pkgrel=%release%
pkgdesc="Yandex Music - Personal recommendations, selections for any occasion and new music" pkgdesc="Yandex Music - Personal recommendations, selections for any occasion and new music"
arch=("any") arch=("any")
url="https://github.com/cucumber-sp/yandex-music-linux" url="https://github.com/cucumber-sp/yandex-music-linux"
license=("custom") license=("Unlicense")
depends=("electron29" "libpulse" "xdg-utils") depends=("electron29" "libpulse" "xdg-utils" "bash" "hicolor-icon-theme")
makedepends=("p7zip" "nodejs" "asar" "jq" "python") makedepends=("p7zip" "nodejs" "asar" "jq" "python" "git")
source=("%exe_link%" "git+https://github.com/cucumber-sp/yandex-music-linux") source=("%exe_link%" "git+${url}#tag=v${pkgver}")
sha256sums=("%exe_sha256%" "SKIP") sha256sums=("%exe_sha256%" "SKIP")
build() { build() {
@ -31,9 +31,10 @@ package() {
install -Dm644 "$srcdir/yandex-music-linux/templates/desktop" "$pkgdir/usr/share/applications/yandex-music.desktop" install -Dm644 "$srcdir/yandex-music-linux/templates/desktop" "$pkgdir/usr/share/applications/yandex-music.desktop"
install -Dm644 "$srcdir/yandex-music-linux/templates/default.conf" "$pkgdir/usr/lib/yandex-music/default.conf" install -Dm644 "$srcdir/yandex-music-linux/templates/default.conf" "$pkgdir/usr/lib/yandex-music/default.conf"
sed -i "s|%electron_path%|/usr/bin/electron29|g" "$pkgdir/usr/lib/yandex-music/default.conf"
install -Dm644 "$srcdir/yandex-music-linux/LICENSE.md" "$pkgdir/usr/share/licenses/$pkgname/LICENSE" install -Dm644 "$srcdir/yandex-music-linux/LICENSE.md" "$pkgdir/usr/share/licenses/$pkgname/LICENSE"
install -Dm755 "$srcdir/yandex-music-linux/templates/yandex-music.sh" "$pkgdir/usr/bin/yandex-music" install -Dm755 "$srcdir/yandex-music-linux/templates/yandex-music.sh" "$pkgdir/usr/bin/yandex-music"
sed -i "s|%electron_path%|/usr/bin/electron29|g" "$pkgdir/usr/bin/yandex-music"
sed -i "s|%asar_path%|/usr/lib/yandex-music/yandex-music.asar|g" "$pkgdir/usr/bin/yandex-music"
} }

View File

@ -1,2 +1,4 @@
ELECTRON_BIN=%electron_path% ELECTRON_CUSTOM_BIN=
ELECTRON_ARGS="--no-sandbox" ELECTRON_ARGS="--no-sandbox"
TRAY_ENABLED=0
DEV_TOOLS=0

View File

@ -9,4 +9,5 @@ Icon=yandex-music
Type=Application Type=Application
StartupNotify=true StartupNotify=true
StartupWMClass=YandexMusic StartupWMClass=YandexMusic
MimeType=x-scheme-handler/yandexmusic
Categories=Audio;Music;Player;AudioVideo Categories=Audio;Music;Player;AudioVideo

View File

@ -17,12 +17,12 @@ source "$CONFIG_FILE"
WAYLAND_FLAGS="" WAYLAND_FLAGS=""
if [ "$XDG_SESSION_TYPE" == "wayland" ]; then if [ "$XDG_SESSION_TYPE" == "wayland" ]; then
WAYLAND_FLAGS="--enable-features=UseOzonePlatform --ozone-platform=wayland" WAYLAND_FLAGS="--ozone-platform-hint=auto --enable-features=WaylandWindowDecorations --ozone-platform=wayland"
fi fi
if [ -z "$ELECTRON_BIN" ]; then ELECTRON_BIN=${ELECTRON_CUSTOM_BIN:-%electron_path%}
echo "ELECTRON_BIN is not set"
exit 1
fi
exec "${ELECTRON_BIN}" /usr/lib/yandex-music/yandex-music.asar "${ELECTRON_ARGS}" "${WAYLAND_FLAGS}" export TRAY_ENABLED=${TRAY_ENABLED:-0}
export DEV_TOOLS=${DEV_TOOLS:-0}
exec "${ELECTRON_BIN}" "%asar_path%" $ELECTRON_ARGS $WAYLAND_FLAGS

View File

@ -1,5 +1,5 @@
import sys
import json import json
import sys
if len(sys.argv) < 3: if len(sys.argv) < 3:
print("Usage: python extract_release_notes.py <file_name>") print("Usage: python extract_release_notes.py <file_name>")
@ -7,7 +7,8 @@ if len(sys.argv) < 3:
file_name = sys.argv[1] file_name = sys.argv[1]
save_file_name = sys.argv[2] save_file_name = sys.argv[2]
def build_html(data, first_launch=False): def build_html(data, first_launch=False):
html = "" html = ""
for i, element in enumerate(data): for i, element in enumerate(data):
@ -16,35 +17,23 @@ def build_html(data, first_launch=False):
html += f"<h3>{element['value']}</h3>".replace('\n', '<br/>') html += f"<h3>{element['value']}</h3>".replace('\n', '<br/>')
continue continue
if element['value'] == '\n': if element['value'] == '\n':
html += "<br/>" continue
else: else:
html += f"<span>{element['value']}</span>".replace('\n', '<br/>') html += f"<span>{element['value']}</span>".replace('\n', '<br/>')
elif element['type'] == 8: elif element['type'] == 8:
html += f"<{element['value']}>{build_html(element['children'])}</{element['value']}>" html += f"<{element['value']}>{build_html(element['children'])}</{element['value']}>"
return html return html
with open(file_name, "r", encoding='utf-8') as file: with open(file_name, "r", encoding='utf-8') as file:
full_text = file.read() translation = json.load(file)
notes = {} notes = {}
position = full_text.find("desktop-release-notes.") element_key: str
while position != -1: for element_key in translation.keys():
start_position = position if not element_key.startswith("desktop-release-notes."):
while full_text[position] != '"': continue
position += 1 notes[element_key] = build_html(translation[element_key], True)
name = full_text[start_position:position]
position += 2
start_position = position
braces_count = 1
while braces_count > 0:
position += 1
if full_text[position] == '{' or full_text[position] == '[':
braces_count += 1
elif full_text[position] == '}' or full_text[position] == ']':
braces_count -= 1
data = full_text[start_position:position + 1]
notes[name] = build_html(json.loads(data), True)
position = full_text.find("desktop-release-notes.", position)
with open(save_file_name, "w", encoding='utf-8') as file: with open(save_file_name, "w", encoding='utf-8') as file:
file.write(json.dumps(notes, ensure_ascii=False, indent=4)) file.write(json.dumps(notes, ensure_ascii=False, indent=4))

View File

@ -3,12 +3,14 @@ import os
import shutil import shutil
import subprocess import subprocess
def check_dependency(dependency): def check_dependency(dependency):
if shutil.which(dependency): if shutil.which(dependency):
return True return True
print(f"{dependency} not installed.") print(f"{dependency} not installed.")
return False return False
script_dir = os.path.dirname(os.path.realpath(__file__)) script_dir = os.path.dirname(os.path.realpath(__file__))
# loading versions information from json # loading versions information from json
@ -16,6 +18,7 @@ version_info_path = os.path.join(script_dir, "version_info.json")
with open(version_info_path, "r") as f: with open(version_info_path, "r") as f:
version_info = json.load(f) version_info = json.load(f)
# Arch # Arch
def generate_arch(): def generate_arch():
pkgbuild_template = os.path.join(script_dir, "../templates/PKGBUILD") pkgbuild_template = os.path.join(script_dir, "../templates/PKGBUILD")
@ -35,14 +38,16 @@ def generate_arch():
# Nix # Nix
def is_nix_version_2_19(): def is_nix_version_2_19():
version = subprocess.run(["nix", "--version"], capture_output=True, text=True).stdout.split()[2] version = subprocess.run(["nix", "--version"], capture_output=True, text=True).stdout.split()[2]
print(f"Nix version: {version}")
major, minor, _ = map(int, version.split(".")) major, minor, _ = map(int, version.split("."))
if major > 2 or (minor >= 19 and major == 2): if major > 2 or (minor >= 19 and major == 2):
return True return True
return False return False
def generate_nix(): def generate_nix():
nixcmd = "nix --extra-experimental-features nix-command --extra-experimental-features flakes" nixcmd = "nix --extra-experimental-features nix-command --extra-experimental-features flakes"
flake_path = os.path.join(script_dir, "../flake.nix") flake_path = os.path.join(script_dir, "../flake.nix")
@ -52,14 +57,14 @@ def generate_nix():
flake = f.read() flake = f.read()
_start_index = flake.find("ymExe.url = ") _start_index = flake.find("ymExe.url = ")
_end_index = flake.find(";", _start_index) _end_index = flake.find(";", _start_index)
flake = flake.replace(flake[_start_index:_end_index+1], f'ymExe.url = {version_info["ym"]["exe_link"]};') flake = flake.replace(flake[_start_index:_end_index + 1], f'ymExe.url = "{version_info["ym"]["exe_link"]}";')
with open(flake_path, "w") as f: with open(flake_path, "w") as f:
f.write(flake) f.write(flake)
if not check_dependency("nix"): if not check_dependency("nix"):
print("flake.nix was updated, but nix is not installed to update flake.lock") print("flake.nix was updated, but nix is not installed to update flake.lock")
return return
if is_nix_version_2_19(): if is_nix_version_2_19():
subprocess.run(f"{nixcmd} flake update ymExe", shell=True) subprocess.run(f"{nixcmd} flake update ymExe", shell=True)
else: else:
@ -70,4 +75,4 @@ def generate_nix():
generate_arch() generate_arch()
generate_nix() generate_nix()

View File

@ -4,6 +4,7 @@ import json
import os import os
import shutil import shutil
import tempfile import tempfile
import requests import requests
YM_VERSIONS_URL = "https://music-desktop-application.s3.yandex.net/stable/download.json" YM_VERSIONS_URL = "https://music-desktop-application.s3.yandex.net/stable/download.json"
@ -13,17 +14,21 @@ ELECTRON_DOWNLOAD_URL = "https://github.com/electron/electron/releases/download/
script_dir = os.path.dirname(os.path.realpath(__file__)) script_dir = os.path.dirname(os.path.realpath(__file__))
tempdir = tempfile.mkdtemp() tempdir = tempfile.mkdtemp()
def clear(): def clear():
shutil.rmtree(tempdir) shutil.rmtree(tempdir)
atexit.register(clear) atexit.register(clear)
def assert_dependency(dependency): def assert_dependency(dependency):
if shutil.which(dependency): if shutil.which(dependency):
return return
print(f"{dependency} not installed.") print(f"{dependency} not installed.")
exit(1) exit(1)
# loading versions json # loading versions json
versions_obj = requests.get(YM_VERSIONS_URL).json() versions_obj = requests.get(YM_VERSIONS_URL).json()
exe_link = versions_obj["windows"] exe_link = versions_obj["windows"]
@ -74,4 +79,4 @@ version_file = os.path.join(script_dir, "version_info.json")
with open(version_file, "w") as f: with open(version_file, "w") as f:
f.write(json.dumps(version_info, indent=4)) f.write(json.dumps(version_info, indent=4))
print(f"Version info written to {version_file}") print(f"Version info written to {version_file}")

View File

@ -1,14 +1,14 @@
{ {
"ym": { "ym": {
"version": "5.0.14", "version": "5.18.2",
"exe_name": "Yandex_Music_x64_5.0.14.exe", "exe_name": "Yandex_Music_x64_5.18.2.exe",
"exe_link": "https://music-desktop-application.s3.yandex.net/stable/Yandex_Music_x64_5.0.14.exe", "exe_link": "https://music-desktop-application.s3.yandex.net/stable/Yandex_Music_x64_5.18.2.exe",
"exe_sha256": "c10c6c4b5d596f9bf490a231d7c13bbd2627109f71c9c57aa4e2b034e31252f4" "exe_sha256": "a513eb6aa4bd05bae8503f5578a8e91d778794ffe4eb3a450040903570106941"
}, },
"electron": { "electron": {
"version": "29.1.1", "version": "29.4.6",
"x64": "https://github.com/electron/electron/releases/download/v29.1.1/electron-v29.1.1-linux-x64.zip", "x64": "https://github.com/electron/electron/releases/download/v29.4.6/electron-v29.4.6-linux-x64.zip",
"armv7l": "https://github.com/electron/electron/releases/download/v29.1.1/electron-v29.1.1-linux-armv7l.zip", "armv7l": "https://github.com/electron/electron/releases/download/v29.4.6/electron-v29.4.6-linux-armv7l.zip",
"arm64": "https://github.com/electron/electron/releases/download/v29.1.1/electron-v29.1.1-linux-arm64.zip" "arm64": "https://github.com/electron/electron/releases/download/v29.4.6/electron-v29.4.6-linux-arm64.zip"
} }
} }