iobroker.foobar2000 2.0.3 → 2.1.0-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/.eslintignore ADDED
@@ -0,0 +1,2 @@
1
+ **/.eslintrc.js
2
+ admin/words.js
@@ -0,0 +1,32 @@
1
+ ---
2
+ name: Bug report
3
+ about: Something is not working as it should
4
+ title: ''
5
+ labels: ''
6
+ assignees: ''
7
+ ---
8
+
9
+ **Describe the bug**
10
+ A clear and concise description of what the bug is.
11
+
12
+ **To Reproduce**
13
+ Steps to reproduce the behavior:
14
+ 1. Go to '...'
15
+ 2. Click on '...'
16
+ 3. Scroll down to '....'
17
+ 4. See error
18
+
19
+ **Expected behavior**
20
+ A clear and concise description of what you expected to happen.
21
+
22
+ **Screenshots & Logfiles**
23
+ If applicable, add screenshots and logfiles to help explain your problem.
24
+
25
+ **Versions:**
26
+ - Adapter version: <adapter-version>
27
+ - JS-Controller version: <js-controller-version> <!-- determine this with `iobroker -v` on the console -->
28
+ - Node version: <node-version> <!-- determine this with `node -v` on the console -->
29
+ - Operating system: <os-name>
30
+
31
+ **Additional context**
32
+ Add any other context about the problem here.
@@ -0,0 +1,17 @@
1
+ # Configure here which dependency updates should be merged automatically.
2
+ # The recommended configuration is the following:
3
+ - match:
4
+ # Only merge patches for production dependencies
5
+ dependency_type: production
6
+ update_type: "semver:patch"
7
+ - match:
8
+ # Except for security fixes, here we allow minor patches
9
+ dependency_type: production
10
+ update_type: "security:minor"
11
+ - match:
12
+ # and development dependencies can have a minor update, too
13
+ dependency_type: development
14
+ update_type: "semver:minor"
15
+
16
+ # The syntax is based on the legacy dependabot v1 automerged_updates syntax, see:
17
+ # https://dependabot.com/docs/config-file/#automerged_updates
@@ -0,0 +1,18 @@
1
+ version: 2
2
+ updates:
3
+ - package-ecosystem: npm
4
+ directory: "/"
5
+ schedule:
6
+ interval: weekly
7
+ time: "04:00"
8
+ timezone: Europe/Berlin
9
+ open-pull-requests-limit: 15
10
+ versioning-strategy: increase
11
+
12
+ - package-ecosystem: github-actions
13
+ directory: "/"
14
+ schedule:
15
+ interval: weekly
16
+ time: "04:00"
17
+ timezone: Europe/Berlin
18
+ open-pull-requests-limit: 15
@@ -0,0 +1,27 @@
1
+ # Automatically merge Dependabot PRs when version comparison is within the range
2
+ # that is configured in .github/auto-merge.yml
3
+
4
+ name: Auto-Merge Dependabot PRs
5
+
6
+ on:
7
+ # WARNING: This needs to be run in the PR base, DO NOT build untrusted code in this action
8
+ # details under https://github.blog/changelog/2021-02-19-github-actions-workflows-triggered-by-dependabot-prs-will-run-with-read-only-permissions/
9
+ pull_request_target:
10
+
11
+ jobs:
12
+ auto-merge:
13
+ if: github.actor == 'dependabot[bot]'
14
+ runs-on: ubuntu-latest
15
+ steps:
16
+ - name: Checkout code
17
+ uses: actions/checkout@v4
18
+
19
+ - name: Check if PR should be auto-merged
20
+ uses: ahmadnassri/action-dependabot-auto-merge@v2
21
+ with:
22
+ # In order to use this, you need to go to https://github.com/settings/tokens and
23
+ # create a Personal Access Token with the permission "public_repo".
24
+ # Enter this token in your repository settings under "Secrets" and name it AUTO_MERGE_TOKEN
25
+ github-token: ${{ secrets.AUTO_MERGE_TOKEN }}
26
+ # By default, squash and merge, so Github chooses nice commit messages
27
+ command: squash and merge
@@ -0,0 +1,92 @@
1
+ name: Test and Release
2
+
3
+ # Run this job on all pushes and pull requests
4
+ # as well as tags with a semantic version
5
+ on:
6
+ push:
7
+ branches:
8
+ - 'master'
9
+ tags:
10
+ # normal versions
11
+ - 'v[0-9]+.[0-9]+.[0-9]+'
12
+ # pre-releases
13
+ - 'v[0-9]+.[0-9]+.[0-9]+-**'
14
+ pull_request: {}
15
+
16
+ # Cancel previous PR/branch runs when a new commit is pushed
17
+ concurrency:
18
+ group: ${{ github.ref }}
19
+ cancel-in-progress: true
20
+
21
+ jobs:
22
+ # Performs quick checks before the expensive test runs
23
+ check-and-lint:
24
+ if: contains(github.event.head_commit.message, '[skip ci]') == false
25
+
26
+ runs-on: ubuntu-latest
27
+
28
+ steps:
29
+ - uses: ioBroker/testing-action-check@v1
30
+ with:
31
+ node-version: '18.x'
32
+ # Uncomment the following line if your adapter cannot be installed using 'npm ci'
33
+ # install-command: 'npm install'
34
+ lint: true
35
+
36
+ # Runs adapter tests on all supported node versions and OSes
37
+ adapter-tests:
38
+ if: contains(github.event.head_commit.message, '[skip ci]') == false
39
+
40
+ runs-on: ${{ matrix.os }}
41
+ strategy:
42
+ matrix:
43
+ node-version: [16.x, 18.x, 20.x]
44
+ os: [ubuntu-latest, windows-latest, macos-latest]
45
+
46
+ steps:
47
+ - uses: ioBroker/testing-action-adapter@v1
48
+ with:
49
+ node-version: ${{ matrix.node-version }}
50
+ os: ${{ matrix.os }}
51
+ # Uncomment the following line if your adapter cannot be installed using 'npm ci'
52
+ # install-command: 'npm install'
53
+
54
+ # TODO: To enable automatic npm releases, create a token on npmjs.org
55
+ # Enter this token as a GitHub secret (with name NPM_TOKEN) in the repository options
56
+ # Then uncomment the following block:
57
+
58
+ # Deploys the final package to NPM
59
+ deploy:
60
+ needs: [check-and-lint, adapter-tests]
61
+
62
+ # Trigger this step only when a commit on any branch is tagged with a version number
63
+ if: |
64
+ contains(github.event.head_commit.message, '[skip ci]') == false &&
65
+ github.event_name == 'push' &&
66
+ startsWith(github.ref, 'refs/tags/v')
67
+
68
+ runs-on: ubuntu-latest
69
+
70
+ # Write permissions are required to create Github releases
71
+ permissions:
72
+ contents: write
73
+
74
+ steps:
75
+ - uses: ioBroker/testing-action-deploy@v1
76
+ with:
77
+ node-version: '18.x'
78
+ # Uncomment the following line if your adapter cannot be installed using 'npm ci'
79
+ # install-command: 'npm install'
80
+ npm-token: ${{ secrets.NPM_TOKEN }}
81
+ github-token: ${{ secrets.GITHUB_TOKEN }}
82
+
83
+ # When using Sentry for error reporting, Sentry can be informed about new releases
84
+ # To enable create a API-Token in Sentry (User settings, API keys)
85
+ # Enter this token as a GitHub secret (with name SENTRY_AUTH_TOKEN) in the repository options
86
+ # Then uncomment and customize the following block:
87
+ # sentry: true
88
+ # sentry-token: ${{ secrets.SENTRY_AUTH_TOKEN }}
89
+ # sentry-project: "iobroker-pid"
90
+ # sentry-version-prefix: "iobroker.pid"
91
+ # # If your sentry project is linked to a GitHub repository, you can enable the following option
92
+ # # sentry-github-integration: true
@@ -0,0 +1,2 @@
1
+ package.json
2
+ package-lock.json
package/.prettierrc.js ADDED
@@ -0,0 +1,9 @@
1
+ module.exports = {
2
+ semi: true,
3
+ trailingComma: 'all',
4
+ singleQuote: true,
5
+ printWidth: 120,
6
+ useTabs: false,
7
+ tabWidth: 4,
8
+ endOfLine: 'lf',
9
+ };
@@ -0,0 +1,3 @@
1
+ {
2
+ "plugins": ["iobroker", "license", "manual-review"]
3
+ }
package/LICENSE CHANGED
@@ -1,6 +1,7 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2020 instalator <vvvalt@mail.ru>
3
+ Copyright (c) 2023 iobroker-community-adapters <mcm57@gmx.at>
4
+ Copyright (c) 2021 instalator <vvvalt@mail.ru>
4
5
 
5
6
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
7
  of this software and associated documentation files (the "Software"), to deal
package/README.md CHANGED
@@ -1,58 +1,88 @@
1
1
  ![Logo](admin/foobar2000.png)
2
- # Foobar2000 adapter for iobroker
3
- ![Number of Installations](http://iobroker.live/badges/foobar2000-installed.svg) ![Number of Installations](http://iobroker.live/badges/foobar2000-stable.svg) [![NPM version](https://img.shields.io/npm/v/iobroker.foobar2000.svg)](https://www.npmjs.com/package/iobroker.foobar2000)
4
- [![Downloads](https://img.shields.io/npm/dm/iobroker.foobar2000.svg)](https://www.npmjs.com/package/iobroker.foobar2000)
5
- [![Tests](http://img.shields.io/travis/instalator/ioBroker.foobar2000/master.svg)](https://travis-ci.org/instalator/ioBroker.foobar2000)
6
2
 
7
- [![NPM](https://nodei.co/npm/iobroker.foobar2000.png?downloads=true)](https://nodei.co/npm/iobroker.foobar2000/)
3
+ # iobroker.foobar2000
8
4
 
9
- [![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=PFUALWTR2CTPY)
5
+ [![GitHub license](https://img.shields.io/github/license/iobroker-community-adapters/ioBroker.foobar2000)](https://github.com/iobroker-community-adapters/ioBroker.foobar2000/blob/master/LICENSE)
6
+ [![Downloads](https://img.shields.io/npm/dm/iobroker.foobar2000.svg)](https://www.npmjs.com/package/iobroker.foobar2000)
7
+ ![GitHub repo size](https://img.shields.io/github/repo-size/iobroker-community-adapters/ioBroker.foobar2000)
8
+ [![Translation status](https://weblate.iobroker.net/widgets/adapters/-/foobar2000/svg-badge.svg)](https://weblate.iobroker.net/engage/adapters/?utm_source=widget)</br>
9
+ ![GitHub commit activity](https://img.shields.io/github/commit-activity/m/iobroker-community-adapters/ioBroker.foobar2000)
10
+ ![GitHub commits since latest release (by date)](https://img.shields.io/github/commits-since/iobroker-community-adapters/ioBroker.foobar2000/latest)
11
+ ![GitHub last commit](https://img.shields.io/github/last-commit/iobroker-community-adapters/ioBroker.foobar2000)
12
+ ![GitHub issues](https://img.shields.io/github/issues/iobroker-community-adapters/ioBroker.foobar2000)
13
+ </br>
14
+ **Version:** </br>
15
+ [![NPM version](http://img.shields.io/npm/v/iobroker.foobar2000.svg)](https://www.npmjs.com/package/iobroker.foobar2000)
16
+ ![Current version in stable repository](https://iobroker.live/badges/foobar2000-stable.svg)
17
+ ![Number of Installations](https://iobroker.live/badges/foobar2000-installed.svg)
18
+ </br>
19
+ **Tests:** </br>
20
+ [![Test and Release](https://github.com/iobroker-community-adapters/ioBroker.foobar2000/actions/workflows/test-and-release.yml/badge.svg)](https://github.com/iobroker-community-adapters/ioBroker.foobar2000/actions/workflows/test-and-release.yml)
21
+ [![CodeQL](https://github.com/iobroker-community-adapters/ioBroker.foobar2000/actions/workflows/codeql.yml/badge.svg)](https://github.com/iobroker-community-adapters/ioBroker.foobar2000/actions/workflows/codeql.yml)
22
+
23
+ <!--
24
+ ## Sentry
25
+ **This adapter uses Sentry libraries to automatically report exceptions and code errors to the developers.**
26
+ For more details and for information how to disable the error reporting see [Sentry-Plugin Documentation](https://github.com/ioBroker/plugin-sentry#plugin-sentry)! Sentry reporting is used starting with js-controller 3.0.
27
+ -->
28
+
29
+ ## Foobar2000 adapter for iobroker
10
30
 
11
31
  ![admin settings.](admin/admin.png)
12
32
 
13
33
  ## Using
14
- Описание [тут](http://blog.instalator.ru/archives/541).
15
- Для управления проигрывателем необходимо установить плагин [foo_httpcontrol](https://bitbucket.org/oblikoamorale/foo_httpcontrol/downloads/).
16
- Для отображения обложки как ссылка на файл, необходимо в файле ```c:\Users\{USER}\AppData\Roaming\foobar2000\foo_httpcontrol_data\foobar2000controller\config``` изменить параметр ```albumart_prefer_embedded=0```
17
34
 
18
35
  To control the player, you must install the plugin [foo_httpcontrol](https://bitbucket.org/oblikoamorale/foo_httpcontrol/downloads/).
19
36
  To display the cover as a link to a file, in the file ```c:\Users\{USER}\AppData\Roaming\foobar2000\foo_httpcontrol_data\foobar2000controller\config``` change the parameter ```albumart_prefer_embedded = 0```
20
37
 
21
38
  ## Changelog
22
39
 
23
- #### 2.0.3
40
+ <!--
41
+ Placeholder for the next version (at the beginning of the line):
42
+ ### **WORK IN PROGRESS**
43
+ -->
44
+ ### 2.1.0-alpha.0 (2023-11-07)
45
+ * (mcm1957) Adapter requires nodejs16 or newer now.
46
+ * (mcm1957) Adapter has been moved to iobroker-community-adapters organization.
47
+ * (mcm1957) Dependencies have been updated.
48
+
49
+ ### 2.0.4
50
+ * (instalator) fixed error
51
+
52
+ ### 2.0.3
24
53
  * (instalator) fixed admin error
25
54
 
26
- #### 2.0.2
55
+ ### 2.0.2
27
56
  * (instalator) fixed error
28
57
 
29
- #### 2.0.0
58
+ ### 2.0.0
30
59
  * (instalator) Completely rewritten
31
60
 
32
- #### 1.0.0
61
+ ### 1.0.0
33
62
  * (instalator) Up to stable
34
63
 
35
- #### 0.2.0
64
+ ### 0.2.0
36
65
  * (instalator) Change for widgets vis-players
37
66
 
38
- #### 0.1.2
67
+ ### 0.1.2
39
68
  * (instalator) del widgets folders
40
69
  * (instalator) change log level
41
70
  * (instalator) add news object
42
71
 
43
- #### 0.1.1
72
+ ### 0.1.1
44
73
  * (instalator) fix start, exit for local
45
74
 
46
- #### 0.1.0
75
+ ### 0.1.0
47
76
  * (instalator) beta (20.10.2016)
48
77
 
49
- #### 0.0.1
78
+ ### 0.0.1
50
79
  * (instalator) initial (12.10.2016)
51
80
 
52
81
  ## License
53
82
  The MIT License (MIT)
54
83
 
55
- Copyright (c) 2020 instalator <vvvalt@mail.ru>
84
+ Copyright (c) 2023 iobroker-community-adapters <mcm57@gmx.at>
85
+ Copyright (c) 2021 instalator <vvvalt@mail.ru>
56
86
 
57
87
  Permission is hereby granted, free of charge, to any person obtaining a copy
58
88
  of this software and associated documentation files (the "Software"), to deal
Binary file
@@ -72,7 +72,41 @@
72
72
  }
73
73
  }
74
74
  </script>
75
+ <script>
76
+ $(function (){
77
+ $(".adapter-body").append("" +
78
+ "<div class=\"m row\" style='display:block;position:absolute;bottom:130px;right:0;'>" +
79
+ "<div class=\"col right\">" +
80
+ "<div class=\"col\" style=\"margin-top:10px;float:right;margin-right:20px;\">" +
81
+ "<a target=\"_blank\" href=\"https://sobe.ru/na/instalator\"><img style=\"float:right;\" src=\"https://img.shields.io/badge/Donate-YooMoney-green\" alt=\"\"></a>" +
82
+ "<a target=\"_blank\" href=\"https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=PFUALWTR2CTPY\"><img style=\"float:right;padding-right:10px;\" src=\"https://img.shields.io/badge/Donate-PayPal-green.svg\" alt=\"\"></a>" +
83
+ "</div></div></div>");
84
+ });
85
+ </script>
86
+ <style>
87
+ .adapter-body {
88
+ display: block;
89
+ }
75
90
 
91
+ .m .input-field > label {
92
+ color: #5a5a5a;
93
+ }
94
+
95
+ .adapter-body::after {
96
+ top: 0;
97
+ left: 0;
98
+ bottom: 0;
99
+ right: 0;
100
+ content: "";
101
+ background: url(background.png);
102
+ background-position: top;
103
+ background-repeat: no-repeat;
104
+ background-size: cover;
105
+ opacity: 0.2;
106
+ position: absolute;
107
+ z-index: -1;
108
+ }
109
+ </style>
76
110
  </head>
77
111
  <body>
78
112
  <div class="m adapter-container">
package/foobar2000.js CHANGED
@@ -1,14 +1,19 @@
1
- "use strict";
1
+ 'use strict';
2
2
  const utils = require('@iobroker/adapter-core');
3
- let http = require('http');
4
- let exec = require('child_process').exec;
5
- let adapter, foobarPath = null, timerPoll, timeout, muteVol = 100, request, old_states,
6
- states = {
7
- playlist: []
8
- };
9
-
3
+ const http = require('http');
4
+ const exec = require('child_process').exec;
5
+ let adapter;
6
+ let foobarPath = null;
7
+ let timerPoll;
8
+ let timeout;
9
+ let muteVol = 100;
10
+ let request;
11
+ let old_states;
12
+ const states = {
13
+ playlist: []
14
+ };
10
15
 
11
- let Commands = {
16
+ const Commands = {
12
17
  'play': 'Start',
13
18
  'stop': 'Stop',
14
19
  'next': 'StartNext',
@@ -41,7 +46,7 @@ function startAdapter(options){
41
46
  timerPoll && clearInterval(timerPoll);
42
47
  timeout && clearTimeout(timeout);
43
48
  try {
44
- debug('cleaned everything up...');
49
+ adapter.log.debug('cleaned everything up...');
45
50
  callback();
46
51
  } catch (e) {
47
52
  callback();
@@ -51,7 +56,7 @@ function startAdapter(options){
51
56
  if (id && state && !state.ack){
52
57
  adapter.log.debug(`state ${id} changed: ${state.val} (ack = ${state.ack})`);
53
58
  let param;
54
- id = id.split(".")[2].toString().toLowerCase();
59
+ id = id.split('.')[2].toString().toLowerCase();
55
60
  if (id === 'start' || id === 'exit'){
56
61
  launch(id);
57
62
  return;
@@ -138,14 +143,14 @@ function startAdapter(options){
138
143
  path: '/foobar2000controller/?cmd=Browse&param1=' + param + '&param2=EnqueueDirSubdirs' //&param3=browser.json
139
144
  };*/
140
145
  timeout && clearTimeout(timeout);
141
- httpGet('Browse', [param, 'EnqueueDirSubdirs'], (data) => {
146
+ httpGet('Browse', [param, 'EnqueueDirSubdirs'], (_data) => {
142
147
  timeout = setTimeout(() => {
143
148
  getPlaylist();
144
149
  }, 1000);
145
150
  });
146
151
  }
147
152
  } else {
148
- let cmd = Commands[id];
153
+ const cmd = Commands[id];
149
154
  if (cmd){
150
155
  if (param !== undefined){
151
156
  httpGet(cmd, [param]);
@@ -166,7 +171,7 @@ function httpGet(cmd, param, cb){
166
171
  params += '&param' + (i + 1) + '=' + key;
167
172
  });
168
173
  }
169
- let options = {
174
+ const options = {
170
175
  host: adapter.config.ip || '127.0.0.1',
171
176
  port: adapter.config.port || 8888,
172
177
  path: '/foobar2000controller/?cmd=' + cmd + params
@@ -218,8 +223,8 @@ function getCurrentTrackInfo(cb){
218
223
  if (res){
219
224
  states.volume = res.volume;
220
225
  states.state = statePlaying(res.isPlaying, res.playingItem);
221
- states.album = res.playlist[0].album === '?' ? '': res.playlist[0].album;
222
- states.artist = res.playlist[0].artist === '?' ? res.playlist[0].track: res.playlist[0].artist;
226
+ states.album = res.playlist[0].album === '?' ? '' :res.playlist[0].album;
227
+ states.artist = res.playlist[0].artist === '?' ? res.playlist[0].track :res.playlist[0].artist;
223
228
  states.title = res.playlist[0].track;
224
229
  states.current_duration = res.playlist[0].len;
225
230
  states.rating = res.playlist[0].rating !== '?' ? res.playlist[0].rating :'';
@@ -236,7 +241,7 @@ function getCurrentTrackInfo(cb){
236
241
  states.volumeDB = parseInt(res.volumeDB, 10);
237
242
  states.trackLength = parseInt(res.trackLength, 10);
238
243
  states.elapsedTime = parseInt(res.trackPosition, 10);
239
- states.seek = isNaN(parseFloat((res.trackPosition / res.trackLength) * 100).toFixed(4)) ? 0:parseFloat((res.trackPosition / res.trackLength) * 100).toFixed(4);
244
+ states.seek = isNaN(parseFloat((res.trackPosition / res.trackLength) * 100).toFixed(4)) ? 0 :parseFloat((res.trackPosition / res.trackLength) * 100).toFixed(4);
240
245
  states.mute = res.volume === 0;
241
246
  cb && cb();
242
247
  }
@@ -356,41 +361,41 @@ function setInfoConnection(val){
356
361
  function secToText(sec){
357
362
  let res;
358
363
  let m = Math.floor(sec / 60);
359
- let s = sec % 60;
360
- let h = Math.floor(m / 60);
364
+ const s = sec % 60;
365
+ const h = Math.floor(m / 60);
361
366
  m = m % 60;
362
367
  if (h > 0){
363
- res = pad2(h) + ":" + pad2(m) + ":" + pad2(s);
368
+ res = pad2(h) + ':' + pad2(m) + ':' + pad2(s);
364
369
  } else {
365
- res = pad2(m) + ":" + pad2(s);
370
+ res = pad2(m) + ':' + pad2(s);
366
371
  }
367
372
  return res;
368
373
  }
369
374
 
370
375
  function pad2(num){
371
- let s = num.toString();
372
- return (s.length < 2) ? "0" + s :s;
376
+ const s = num.toString();
377
+ return (s.length < 2) ? '0' + s :s;
373
378
  }
374
379
 
375
380
  function getPlaylist(){
376
381
  httpGet('PlaylistItemsPerPage', [16384], (res) => {
377
382
  if (res && res.playlist){
378
- let playlist = [];
379
- let arr = res.songs;
383
+ const playlist = [];
384
+ //const arr = res.songs;
380
385
  res.playlist.forEach((key, i) => {
381
386
  playlist[i] = {
382
- "id": i + 1,
383
- "artist": key.artist,
384
- "album": key.album,
385
- "bitrate": 0,
386
- "title": key.track,
387
- "file": "",
388
- "genre": "",
389
- "year": 0,
390
- "len": key.len,
391
- "rating": key.rating,
392
- "cover": ""
393
- }
387
+ 'id': i + 1,
388
+ 'artist': key.artist,
389
+ 'album': key.album,
390
+ 'bitrate': 0,
391
+ 'title': key.track,
392
+ 'file': '',
393
+ 'genre': '',
394
+ 'year': 0,
395
+ 'len': key.len,
396
+ 'rating': key.rating,
397
+ 'cover': ''
398
+ };
394
399
  });
395
400
  states.playlist = JSON.stringify(playlist);
396
401
  states.playlists = JSON.stringify(res.playlists);
@@ -407,8 +412,8 @@ function launch(cmd){
407
412
  sendShellCommand('exit');
408
413
  }
409
414
  } else if (adapter.config.cmdstart){
410
- let parts = adapter.config.path.split(':');
411
- let options = {
415
+ const parts = adapter.config.path.split(':');
416
+ const options = {
412
417
  host: parts[0],
413
418
  port: parts[1],
414
419
  path: ''
@@ -456,18 +461,18 @@ function browser(cmd, param){
456
461
  }
457
462
 
458
463
  function filemanager(val, arr){
459
- let browser = {}, files = [];
464
+ const browser = {}, files = [];
460
465
  arr.forEach((item, i, arr) => {
461
- let obj = {};
462
- let size = parseFloat(arr[i].fs) * 1024;
466
+ const obj = {};
467
+ const size = parseFloat(arr[i].fs) * 1024;
463
468
  if (!isNaN(size)){
464
469
  obj.size = (parseFloat(arr[i].fs.replace(',', '.')) * 1024).toFixed(0);
465
470
  } else {
466
471
  obj.size = '';
467
472
  }
468
473
  if (arr[i].ft && ~arr[i].ft.indexOf(':')){
469
- let mod = arr[i].ft.split(' '); //"27.05.2004 01:50" 2016-02-27 16:05:46
470
- let d = mod[0].split('.').reverse().join('-');
474
+ const mod = arr[i].ft.split(' '); //"27.05.2004 01:50" 2016-02-27 16:05:46
475
+ const d = mod[0].split('.').reverse().join('-');
471
476
  arr[i].ft = d + ' ' + mod[1];
472
477
  }
473
478
  if (arr[i].fs){
package/io-package.json CHANGED
@@ -1,8 +1,33 @@
1
1
  {
2
2
  "common": {
3
3
  "name": "foobar2000",
4
- "version": "2.0.3",
4
+ "version": "2.1.0-alpha.0",
5
5
  "news": {
6
+ "2.1.0-alpha.0": {
7
+ "en": "Adapter requires nodejs16 or newer now.\nAdapter has been moved to iobroker-community-adapters organization.\nDependencies have been updated.",
8
+ "de": "Adapter benötigt jetzt nodejs16 oder neuer.\nAdapter wurde auf iobroker-community-Adapter Organisation verschoben.\nAbhängigkeiten wurden aktualisiert.",
9
+ "ru": "Адаптер требует nodejs16 или новее теперь.\nАдаптер переехал в организацию iobroker-community-adapters.\nОбновлены зависимости.",
10
+ "pt": "Adaptador requer nodejs16 ou mais recente agora.\nAdapter foi movido para iobroker-community-adapters organização.\nAs dependências foram atualizadas.",
11
+ "nl": "Adapter vereist nodejs16 of Newer nu.\nAdapter is verplaatst naar iobroker-community-papters organisatie.\nAfhankelijkheid is geüpdateerd.",
12
+ "fr": "Adaptateur nécessite nodejs16 ou plus récent maintenant.\nL'adaptateur a été déplacé à l'organisation iobroker-community-adapters.\nLes dépendances ont été mises à jour.",
13
+ "it": "Adattatore richiede nodejs16 o più nuovo ora.\nL'adattatore è stato trasferito all'organizzazione iobroker-community-adapters.\nLe dipendenze sono state aggiornate.",
14
+ "es": "Adaptador requiere nodejs16 o nuevo ahora.\nEl adaptador ha sido trasladado a la organización de ibroker-community-adapters.\nSe han actualizado las dependencias.",
15
+ "pl": "Adapter wymaga węzłów 16 lub nowszych.\nAdapter przeniesiono do organizacji iobroker-community-adapter.\nW zależności zostały zaktualizowane.",
16
+ "uk": "Адаптер вимагає nodejs16 або новіший зараз.\nПереміщено перехід на організацію iobroker-community-adapters.\nОновлено залежність.",
17
+ "zh-cn": "道歉要求现在不再出现。.\n现已移到加勒比妓院。.\n情况已经更新。."
18
+ },
19
+ "2.0.4": {
20
+ "en": "fixed error",
21
+ "de": "fixed error",
22
+ "ru": "fixed error",
23
+ "pt": "fixed error",
24
+ "nl": "fixed error",
25
+ "fr": "fixed error",
26
+ "it": "fixed error",
27
+ "es": "fixed error",
28
+ "pl": "fixed error",
29
+ "zh-cn": "fixed error"
30
+ },
6
31
  "2.0.3": {
7
32
  "en": "fixed admin error",
8
33
  "de": "fixed admin error",
@@ -28,37 +53,64 @@
28
53
  "zh-cn": "Completely rewritten"
29
54
  }
30
55
  },
31
- "title": "Control foobar2000 player",
56
+ "titleLang": {
57
+ "en": "Control foobar2000 player",
58
+ "de": "Steuerung foobar2000 Player",
59
+ "ru": "Управление foobar2000 игроком",
60
+ "pt": "Control foobar2000 jogador",
61
+ "nl": "Controle:",
62
+ "fr": "Contrôle du joueur de foobar2000",
63
+ "it": "Controllo del lettore foobar2000",
64
+ "es": "Control foobar2000 jugador",
65
+ "pl": "Foobar2000 player",
66
+ "uk": "Контроль фобар2000",
67
+ "zh-cn": "控制软禁2000年"
68
+ },
32
69
  "desc": {
33
70
  "en": "Control your foobar2000 player",
34
- "de": "Steuern Sie Ihren foobar2000-Player",
35
- "ru": "Управляйте своим игроком foobar2000",
36
- "pt": "Controle o seu foobar2000 player",
37
- "nl": "Bedien uw foobar2000-speler",
71
+ "de": "Steuern Sie Ihren foobar2000 Player",
72
+ "ru": "Контролируйте своего игрока foobar2000",
73
+ "pt": "Controle o seu jogador foobar2000",
74
+ "nl": "Controleer je foobar2000 speler",
38
75
  "fr": "Contrôlez votre lecteur foobar2000",
39
- "it": "Controlla il tuo giocatore foobar2000",
40
- "es": "Controla tu reproductor foobar2000",
41
- "pl": "Kontroluj swój odtwarzacz foobar2000",
42
- "zh-cn": "控制您的foobar2000播放器"
76
+ "it": "Controlla il tuo lettore foobar2000",
77
+ "es": "Controle su jugador foobar2000",
78
+ "pl": "Kontrola nad foobar2000",
79
+ "uk": "Керуйте фобар2000",
80
+ "zh-cn": "控制你的野蛮2000年事件"
43
81
  },
44
- "license": "MIT",
45
82
  "authors": [
46
- "instalator"
83
+ "instalator",
84
+ "iobroker-community-adapters <mcm57@gmx.at>"
85
+ ],
86
+ "keywords": [
87
+ "foobar2000",
88
+ "player"
47
89
  ],
90
+ "license": "MIT",
48
91
  "platform": "Javascript/Node.js",
49
- "mode": "daemon",
92
+ "main": "foobar2000.js",
50
93
  "icon": "foobar2000.png",
51
94
  "enabled": false,
52
- "compact": true,
53
- "materialize": true,
95
+ "extIcon": "https://raw.githubusercontent.com/iobroker-community-adapters/iobroker.foobar2000/master/admin/foobar2000.png",
96
+ "readme": "https://github.com/iobroker-community-adapters/iobroker.foobar2000/blob/master/README.md",
54
97
  "loglevel": "info",
98
+ "mode": "daemon",
55
99
  "type": "multimedia",
56
- "extIcon": "https://raw.githubusercontent.com/instalator/iobroker.foobar2000/master/admin/foobar2000.png",
57
- "keywords": [
58
- "foobar2000",
59
- "player"
100
+ "compact": true,
101
+ "connectionType": "local",
102
+ "dataSource": "pull",
103
+ "materialize": true,
104
+ "dependencies": [
105
+ {
106
+ "js-controller": ">=4.0.24"
107
+ }
60
108
  ],
61
- "readme": "https://github.com/instalator/iobroker.foobar2000/blob/master/README.md"
109
+ "globalDependencies": [
110
+ {
111
+ "admin": ">=5.1.13"
112
+ }
113
+ ]
62
114
  },
63
115
  "native": {
64
116
  "ip": "127.0.0.1",
@@ -392,7 +444,11 @@
392
444
  "read": true,
393
445
  "write": true,
394
446
  "def": false,
395
- "states": {"0": "Off", "1": "All", "2": "One"}
447
+ "states": {
448
+ "0": "Off",
449
+ "1": "All",
450
+ "2": "One"
451
+ }
396
452
  },
397
453
  "native": {}
398
454
  },
@@ -0,0 +1,16 @@
1
+ // This file extends the AdapterConfig type from "@types/iobroker"
2
+ // using the actual properties present in io-package.json
3
+ // in order to provide typings for adapter.config properties
4
+
5
+ import { native } from '../io-package.json';
6
+
7
+ type _AdapterConfig = typeof native;
8
+
9
+ // Augment the globally declared type ioBroker.AdapterConfig
10
+ declare global {
11
+ namespace ioBroker {
12
+ interface AdapterConfig extends _AdapterConfig {
13
+ // Do not enter anything here!
14
+ }
15
+ }
16
+ }
package/lib/tools.js ADDED
@@ -0,0 +1,99 @@
1
+ const axios = require('axios');
2
+
3
+ /**
4
+ * Tests whether the given variable is a real object and not an Array
5
+ * @param {any} it The variable to test
6
+ * @returns {it is Record<string, any>}
7
+ */
8
+ function isObject(it) {
9
+ // This is necessary because:
10
+ // typeof null === 'object'
11
+ // typeof [] === 'object'
12
+ // [] instanceof Object === true
13
+ return Object.prototype.toString.call(it) === '[object Object]';
14
+ }
15
+
16
+ /**
17
+ * Tests whether the given variable is really an Array
18
+ * @param {any} it The variable to test
19
+ * @returns {it is any[]}
20
+ */
21
+ function isArray(it) {
22
+ if (typeof Array.isArray === 'function') return Array.isArray(it);
23
+ return Object.prototype.toString.call(it) === '[object Array]';
24
+ }
25
+
26
+ /**
27
+ * Translates text to the target language. Automatically chooses the right translation API.
28
+ * @param {string} text The text to translate
29
+ * @param {string} targetLang The target languate
30
+ * @param {string} [yandexApiKey] The yandex API key. You can create one for free at https://translate.yandex.com/developers
31
+ * @returns {Promise<string>}
32
+ */
33
+ async function translateText(text, targetLang, yandexApiKey) {
34
+ if (targetLang === 'en') {
35
+ return text;
36
+ } else if (!text) {
37
+ return '';
38
+ }
39
+ if (yandexApiKey) {
40
+ return translateYandex(text, targetLang, yandexApiKey);
41
+ } else {
42
+ return translateGoogle(text, targetLang);
43
+ }
44
+ }
45
+
46
+ /**
47
+ * Translates text with Yandex API
48
+ * @param {string} text The text to translate
49
+ * @param {string} targetLang The target languate
50
+ * @param {string} apiKey The yandex API key. You can create one for free at https://translate.yandex.com/developers
51
+ * @returns {Promise<string>}
52
+ */
53
+ async function translateYandex(text, targetLang, apiKey) {
54
+ if (targetLang === 'zh-cn') {
55
+ targetLang = 'zh';
56
+ }
57
+ try {
58
+ const url = `https://translate.yandex.net/api/v1.5/tr.json/translate?key=${apiKey}&text=${encodeURIComponent(text)}&lang=en-${targetLang}`;
59
+ const response = await axios({url, timeout: 15000});
60
+ if (response.data && response.data.text && isArray(response.data.text)) {
61
+ return response.data.text[0];
62
+ }
63
+ throw new Error('Invalid response for translate request');
64
+ } catch (e) {
65
+ throw new Error(`Could not translate to "${targetLang}": ${e}`);
66
+ }
67
+ }
68
+
69
+ /**
70
+ * Translates text with Google API
71
+ * @param {string} text The text to translate
72
+ * @param {string} targetLang The target languate
73
+ * @returns {Promise<string>}
74
+ */
75
+ async function translateGoogle(text, targetLang) {
76
+ try {
77
+ const url = `http://translate.googleapis.com/translate_a/single?client=gtx&sl=en&tl=${targetLang}&dt=t&q=${encodeURIComponent(text)}&ie=UTF-8&oe=UTF-8`;
78
+ const response = await axios({url, timeout: 15000});
79
+ if (isArray(response.data)) {
80
+ // we got a valid response
81
+ return response.data[0][0][0];
82
+ }
83
+ throw new Error('Invalid response for translate request');
84
+ } catch (e) {
85
+ if (e.response && e.response.status === 429) {
86
+ throw new Error(
87
+ `Could not translate to "${targetLang}": Rate-limited by Google Translate`
88
+ );
89
+ } else {
90
+ throw new Error(`Could not translate to "${targetLang}": ${e}`);
91
+ }
92
+ }
93
+ }
94
+
95
+ module.exports = {
96
+ isArray,
97
+ isObject,
98
+ translateText
99
+ };
package/main.test.js ADDED
@@ -0,0 +1,30 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * This is a dummy TypeScript test file using chai and mocha
5
+ *
6
+ * It's automatically excluded from npm and its build output is excluded from both git and npm.
7
+ * It is advised to test all your modules with accompanying *.test.js-files
8
+ */
9
+
10
+ // tslint:disable:no-unused-expression
11
+
12
+ const { expect } = require('chai');
13
+ // import { functionToTest } from "./moduleToTest";
14
+
15
+ describe('module to test => function to test', () => {
16
+ // initializing logic
17
+ const expected = 5;
18
+
19
+ it(`should return ${expected}`, () => {
20
+ const result = 5;
21
+ // assign result a value from functionToTest
22
+ expect(result).to.equal(expected);
23
+ // or using the should() syntax
24
+ result.should.equal(expected);
25
+ });
26
+ // ... more tests => it
27
+
28
+ });
29
+
30
+ // ... more test suites => describe
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "iobroker.foobar2000",
3
- "version": "2.0.3",
3
+ "version": "2.1.0-alpha.0",
4
4
  "description": "ioBroker Foobar2000 player adapter",
5
5
  "author": {
6
6
  "name": "instalator",
@@ -10,9 +10,13 @@
10
10
  {
11
11
  "name": "instalator",
12
12
  "email": "vvvalt@mail.ru"
13
+ },
14
+ {
15
+ "name": "iobroker-community-adapters",
16
+ "email": "mcm57@gmx.at"
13
17
  }
14
18
  ],
15
- "homepage": "https://github.com/instalator/iobroker.foobar2000",
19
+ "homepage": "https://github.com/iobroker-community-adapters/iobroker.foobar2000",
16
20
  "license": "MIT",
17
21
  "keywords": [
18
22
  "ioBroker",
@@ -22,42 +26,54 @@
22
26
  ],
23
27
  "repository": {
24
28
  "type": "git",
25
- "url": "https://github.com/instalator/ioBroker.foobar2000.git"
29
+ "url": "https://github.com/iobroker-community-adapters/ioBroker.foobar2000.git"
30
+ },
31
+ "engines": {
32
+ "node": ">=16"
26
33
  },
27
34
  "dependencies": {
28
- "@iobroker/adapter-core": "^2.2.1"
35
+ "@iobroker/adapter-core": "^3.0.4"
29
36
  },
30
37
  "devDependencies": {
31
- "@iobroker/testing": "^2.1.0",
32
- "@types/chai": "^4.2.11",
33
- "@types/chai-as-promised": "^7.1.2",
34
- "@types/gulp": "^4.0.6",
35
- "@types/mocha": "^7.0.2",
36
- "@types/node": "^13.11.1",
37
- "@types/proxyquire": "^1.3.28",
38
- "@types/sinon": "^9.0.0",
39
- "@types/sinon-chai": "^3.2.4",
40
- "axios": "^0.19.2",
41
- "chai": "^4.2.0",
38
+ "@alcalzone/release-script": "^3.6.0",
39
+ "@alcalzone/release-script-plugin-iobroker": "^3.6.0",
40
+ "@alcalzone/release-script-plugin-license": "^3.5.9",
41
+ "@alcalzone/release-script-plugin-manual-review": "^3.5.9",
42
+ "@iobroker/adapter-dev": "^1.2.0",
43
+ "@iobroker/testing": "^4.1.0",
44
+ "@tsconfig/node14": "^14.1.0",
45
+ "@types/chai": "^4.3.8",
46
+ "@types/chai-as-promised": "^7.1.6",
47
+ "@types/mocha": "^10.0.2",
48
+ "@types/node": "^20.8.6",
49
+ "@types/proxyquire": "^1.3.29",
50
+ "@types/sinon": "^17.0.0",
51
+ "@types/sinon-chai": "^3.2.10",
52
+ "chai": "^4.3.10",
42
53
  "chai-as-promised": "^7.1.1",
43
- "eslint": "^6.8.0",
44
- "gulp": "^4.0.2",
45
- "mocha": "^7.1.1",
54
+ "eslint": "^8.51.0",
55
+ "eslint-config-prettier": "^8.9.0",
56
+ "eslint-plugin-prettier": "^4.2.1",
57
+ "mocha": "^10.2.0",
58
+ "prettier": "^3.0.3",
46
59
  "proxyquire": "^2.1.3",
47
- "sinon": "^9.0.2",
48
- "sinon-chai": "^3.5.0"
60
+ "sinon": "^17.0.1",
61
+ "sinon-chai": "^3.7.0",
62
+ "typescript": "~5.2.2"
49
63
  },
50
64
  "main": "foobar2000.js",
51
65
  "scripts": {
52
- "test:js": "mocha --opts test/mocha.custom.opts",
66
+ "test:js": "mocha --config test/mocharc.custom.json \"{!(node_modules|test)/**/*.test.js,*.test.js,test/**/test!(PackageFiles|Startup).js}\"",
53
67
  "test:package": "mocha test/package --exit",
54
- "test:unit": "mocha test/unit --exit",
55
68
  "test:integration": "mocha test/integration --exit",
56
69
  "test": "npm run test:js && npm run test:package",
57
- "lint": "eslint"
70
+ "check": "tsc --noEmit -p tsconfig.check.json",
71
+ "lint": "eslint .",
72
+ "translate": "translate-adapter",
73
+ "release": "release-script"
58
74
  },
59
75
  "bugs": {
60
- "url": "https://github.com/instalator/iobroker.foobar2000/issues"
76
+ "url": "https://github.com/iobroker-community-adapters/iobroker.foobar2000/issues"
61
77
  },
62
78
  "readmeFilename": "README.md"
63
79
  }
@@ -1,7 +0,0 @@
1
- {
2
- "extends": "../tsconfig.json",
3
- "include": [
4
- "./**/*.d.ts",
5
- "./**/*.js"
6
- ]
7
- }