Compare commits

...

590 Commits

Author SHA1 Message Date
Michael Teeuw
6db61b4357 Merge pull request #1418 from MichMich/develop
Develop
2018-10-01 08:16:04 +02:00
Michael Teeuw
f245cbf7f2 Merge pull request #1419 from rudibarani/master
Details to install the latest version of Node.js
2018-10-01 08:05:22 +02:00
rudibarani
6f2b04669f Details to install the latest version of Node.js
Added the direct code to always install the latest version of Node.js for the manual installation.
Maybe you could also include this in the automatic setup script, which does not seem to install the latest version of Node.js.
2018-09-30 23:39:22 +02:00
Michael Teeuw
9a46081d0b Prepare for release 2.5.0 2018-09-30 21:36:04 +02:00
Michael Teeuw
7117725e69 Merge pull request #1405 from ubertao/multi-line-compliments
Multi-line compliments
2018-09-25 11:36:27 +02:00
ubertao
ba428c6cfe Use 'white-space: pre-line' for multi-line compliment. 2018-09-24 23:01:17 +08:00
ubertao
d76c924ad1 Update compliments README.md for multi-line support. 2018-09-20 09:09:06 +08:00
ubertao
cad7debc5b Replace innerHTML() with createElement() and appendChild() for security. 2018-09-20 08:49:17 +08:00
ubertao
40725aa2a2 Update CHANGELOG.md with multi-line compliments support. 2018-09-17 00:54:01 +08:00
ubertao
6034891fed Support multi-line compliments. 2018-09-17 00:51:37 +08:00
Michael Teeuw
9dd9862d33 Merge pull request #1402 from ubertao/pr-zh-cn-2.5.0
Update zh-cn translation for 2.5.0
2018-09-13 08:59:57 +02:00
Michael Teeuw
48c72e319b Merge pull request #1401 from ubertao/pr-calender-gzip
Pr calender gzip
2018-09-13 08:58:13 +02:00
ubertao
4b6208fd9c Update CHANGELOG.md for zh-cn translation updates. 2018-09-12 09:35:58 +08:00
ubertao
168904a159 Update zh-cn translation to 2.5.0 2018-09-12 09:31:46 +08:00
ubertao
28f1498ec3 update CHANGELOG.md adding gzip fix for calendar module 2018-09-12 08:17:10 +08:00
ubertao
d3028e10d3 Merge branch 'develop' of https://github.com/MichMich/MagicMirror into pr-calender-gzip 2018-09-12 08:15:52 +08:00
ubertao
4aace5b95a update changelog with gzip calendar fix 2018-09-08 23:44:12 +08:00
ubertao
044dbd4a65 Add gzip support to calendar fetcher. 2018-09-08 23:05:19 +08:00
Michael Teeuw
5dbae7c9d7 Merge pull request #1383 from balassy/bugfix/updatenotification-localization
Making the word "commit" localizable in the UpdateNotification module message
2018-09-05 09:12:04 +02:00
György Balássy
ec44cb2761 CHANGED: The wording in CHANGELOG is modified to be more descriptive. 2018-09-05 04:41:09 +02:00
György Balássy
b06cf55c0b FIXED: Character encoding issue in pl.json occurred during rebase. 2018-09-05 04:33:42 +02:00
György Balássy
b601f6a138 CHANGED: The UPDATE_INFO key in the localization file is changed to UPDATE_INFO_SINGLE and UPDATE_INFO_MULTIPLE to allow different localization for single and multiple commits. 2018-09-05 04:30:57 +02:00
György Balássy
ddebc63488 ADDED: CHANGELOG entry. 2018-09-05 04:30:23 +02:00
György Balássy
35440822be CHANGED: The COMMIT_COUNT placeholder in the UPDATE_INFO message of the UpdateNotification module does not contain the word "commit" or "commits" any more, so language files can independently localize them. 2018-09-05 04:30:22 +02:00
György Balássy
f4c6bcfb8e Merge pull request #4 from MichMich/develop
Update Develop from the original repo
2018-09-05 04:26:13 +02:00
Michael Teeuw
6365c5c9ef Merge pull request #1396 from matt08/patch-4
Updated Polish translation
2018-09-04 11:42:16 +02:00
matt08
dd0334d30d Update pl.json 2018-08-31 09:24:18 +02:00
matt08
c462a44973 Polish translate for "Feels" 2018-08-31 09:17:04 +02:00
Michael Teeuw
6f88f5db83 Merge pull request #1385 from el97/patch-4
Update sv.json
2018-08-31 09:14:33 +02:00
matt08
93617f62a2 Updating "feels" translation 2018-08-31 09:14:16 +02:00
György Balássy
61d5f39408 Merge pull request #3 from MichMich/develop
Update the develop branch from the original repository
2018-08-30 00:00:56 +02:00
Michael Teeuw
c1fddaa7dd Merge pull request #1392 from vlebourl/develop
support for showing the end time of non full day events and the end date of several day long
2018-08-29 09:12:02 +02:00
vlb
188aa14d82 added support for showing end of events in calendar 2018-08-28 18:11:38 +02:00
Vincent Le Bourlot
5c25dd5b6d Update CHANGELOG.md 2018-08-28 18:00:13 +02:00
vlb
7c579cf7b7 added support for showing end of events through config parameters showEnd and dateEndFormat 2018-08-28 17:35:53 +02:00
vlb
c755c823fa added support for events having a duration instead of an end 2018-08-28 17:29:42 +02:00
Michael Teeuw
116588c237 Merge pull request #1390 from ccrlawrence/patch-1
ClientOnly: Global variable name used in callback function
2018-08-28 15:37:55 +02:00
Michael Teeuw
f02c1e4dc7 Merge branch 'develop' into patch-1 2018-08-28 15:36:58 +02:00
Michael Teeuw
c4e8cc1641 Correct changelog entry. 2018-08-28 15:33:53 +02:00
Michael Teeuw
93e68ad147 Merge branch 'develop' into patch-1 2018-08-28 15:32:47 +02:00
vlb
7ba88a83f0 consider events lasting several full days as full day events 2018-08-28 13:05:06 +02:00
ccrlawrence
c9293327ce Update CHANGELOG.md 2018-08-26 16:01:41 +01:00
ccrlawrence
fa1f35a89e ClientOnly: Global variable name used in callback function.
The global 'config' variable is used in the callback function, changed to local one. Unwanted behaviour when accessing server on docker or if using 0.0.0.0 or blank address in config file as it just passes this to electron to display.
2018-08-26 15:53:01 +01:00
Michael Teeuw
845ce7a711 Merge pull request #1384 from YangVincent/develop
Update OpenWeather city list instructions
2018-08-21 16:31:08 +02:00
el97
2b40007563 Update sv.json
Small changes. Added "FEELS": "Känns som".
2018-08-21 15:29:20 +02:00
Vincent Yang
217034c4a7 Update Changelog for weather city link 2018-08-21 01:06:12 -07:00
Vincent Yang
0b9d4f17ab Fix link for finding cities in OpenWeather 2018-08-21 01:04:58 -07:00
Michael Teeuw
7fb0ec12dd Merge pull request #1381 from Elaniobro/rp-zero-w-es6-fix
RaspBerry Pi Zero W default calendar module fix
2018-08-17 12:18:31 +02:00
György Balássy
3581158a7b Merge pull request #2 from MichMich/develop
Update Develop from original repo
2018-08-17 06:40:54 +02:00
Elan Trybuch
facfa73214 Merge branch 'develop' into rp-zero-w-es6-fix 2018-08-16 12:07:38 -04:00
Elan Trybuch
0ef4a86d42 Add patch note to CHANGELOG.md 2018-08-16 11:51:10 -04:00
Elan Trybuch
d4ec4795c3 Fix ES6 syntax bug on RaspberryPi Zero W
Following this issue https://github.com/MichMich/MagicMirror/issues/694 it seems that the Midori Browser does not recoginize ES6 syntax. Further, the use of 'var' is seen throughout the calendar module excpet on line 439, where the error is reported
2018-08-16 11:45:34 -04:00
Michael Teeuw
b13d0aa283 Merge pull request #1373 from jannekalliola/develop
Calendar: Absolute dates do not show absolute even if getRelative and urgency are set to zero
2018-08-16 12:05:22 +02:00
Michael Teeuw
a6965342e7 Update CHANGELOG.md 2018-08-16 12:00:06 +02:00
Michael Teeuw
752dfa5b7f Merge pull request #1369 from heskja/patch-2
Patch 2
2018-08-16 11:56:03 +02:00
Michael Teeuw
87aa283f22 Merge pull request #1376 from vincep5/develop
weatherforecast rainfall rounding
2018-08-16 11:55:25 +02:00
vincep5
6598ae080f weatherforecast rainfall rounding 2018-08-07 11:48:10 -05:00
Janne Kalliola
7c5e8a66e4 Added also description of the change to changelog 2018-08-05 19:49:26 +03:00
Janne Kalliola
c9577bcdc5 Added an if to use absolute dates with all events 2018-08-05 19:47:27 +03:00
heskja
8254c2e83c Merge pull request #1 from heskja/patch-1
Update nb.json
2018-08-03 20:24:46 +02:00
heskja
20a9ac841d Update nn.json
Added translation for "FEELS"
2018-08-03 20:23:19 +02:00
heskja
ae86b75d89 Update nb.json
Added translation for "FEELS"
2018-08-03 20:22:44 +02:00
György Balássy
93a0afe612 Merge pull request #1 from MichMich/develop
Sync Develop from original repo
2018-08-02 06:26:23 +02:00
Michael Teeuw
439027220b Merge pull request #1366 from Ybbet/alert_css
Alert css #1353
2018-08-01 10:19:52 +02:00
Teddy Payet
4a07272d7a Changelog.md updated 2018-08-01 09:42:23 +02:00
Teddy Payet
81432b54a3 Classes for alert module
Use of classes instead of inline style. With those modifications, it will be easier to personnalize the alert with custom.css
2018-08-01 09:37:27 +02:00
Michael Teeuw
b84a6e0c02 Merge pull request #1358 from jagobagascon/develop
Added missing spanish text
2018-07-15 19:47:04 +02:00
jagoba
37dc5a00e8 Merge branch 'bugfix/spanish-missing-localization' into develop 2018-07-15 19:21:59 +02:00
jagoba
e6edf85fbe Added Spanish translation for "FEELS" 2018-07-15 19:13:04 +02:00
Michael Teeuw
cb533a26f2 Merge pull request #1356 from balassy/bugfix/hungarian-localization
Updating the Hungarian localization
2018-07-13 22:01:56 +02:00
György Balássy
a7278f76a8 UPDATED: The CHANGELOG.md file with description of the changes in the Hungarian localization. 2018-07-13 16:42:47 +02:00
György Balássy
80bd32382f CHANGED: The Hungarian localization of the updatenotification module is changed to be more natural, because the existing messages felt like they were created with machine translation, and they were not only unnatural, but also misleading. 2018-07-13 16:32:32 +02:00
György Balássy
db21ced104 ADDED: Missing Hungarian localization for the "FEELS" resource key. 2018-07-13 16:26:15 +02:00
György Balássy
717c6555cb ADDED: Missing Hungarian localization for the "WEEK" resource key. 2018-07-13 16:23:34 +02:00
Michael Teeuw
a412e4af5c Merge pull request #1354 from Ybbet/develop
Wrong mixup… (cf german and spanish)
2018-07-11 02:21:14 +02:00
Teddy Payet
3350bf1ac6 CHANGELOG 2018-07-11 01:52:29 +02:00
Teddy Payet
4aa3353a1d Wrong mixup… (cf german and spanish)
Thanks fewieden.
2018-07-11 01:45:16 +02:00
Michael Teeuw
ff48a58537 Merge pull request #1352 from Ybbet/develop
Add some translations (mostly french).
2018-07-10 16:15:13 +02:00
Teddy Payet
08fa511d17 Add some translations (mostly french). 2018-07-10 15:03:54 +02:00
Michael Teeuw
c295115ffc Merge pull request #1347 from cederstrom/toggle-news-article-fullscreen
Abillity to toggle news article in fullscreen
2018-07-10 12:41:20 +02:00
Michael Teeuw
5fb14610ec Merge pull request #1348 from cederstrom/swedish-translations
Swedish translations
2018-07-10 12:40:04 +02:00
Andreas Cederström
e87c2350b7 Update CHANGELOG.md 2018-07-07 17:36:51 +02:00
Andreas Cederström
44e691e840 Update CHANGELOG.md 2018-07-07 17:35:04 +02:00
Andreas Cederström
b5a7234cf3 Swedish translation for "FEELS" 2018-07-07 17:26:17 +02:00
Andreas Cederström
d12509957f Abillity to toggle article in fullscreen 2018-07-07 16:50:10 +02:00
Michael Teeuw
f01e7b7e20 Prepare for 2.5.0 2018-07-04 11:32:04 +02:00
Michael Teeuw
6aa156d956 Merge pull request #1343 from MichMich/develop
Release 2.4.1
2018-07-04 11:27:05 +02:00
Michael Teeuw
ef5ea93de1 Prepare for release 2.4.1 2018-07-04 11:20:37 +02:00
Michael Teeuw
b4913f51f2 Merge pull request #1341 from jannekalliola/master
Fixed parsing date
2018-07-03 17:08:07 +02:00
Janne Kalliola
dc3e960e79 Fixed parsing date, as dt_txt is missing from certain weather API results 2018-07-02 23:22:09 +03:00
Michael Teeuw
1f76bd1942 Setup the next release (2.5.0). 2018-07-01 21:01:41 +02:00
Michael Teeuw
3545f80920 Merge pull request #1338 from MichMich/develop
Release 2.4.0
2018-07-01 20:50:46 +02:00
Michael Teeuw
0b2d1564ef Prepare to release 2.4.0 2018-07-01 20:43:04 +02:00
Michael Teeuw
fdacf824b3 Merge pull request #1337 from ShameerAshraf/develop
Fixed Wind Chill and Heat Index for Kelvin
2018-06-30 21:03:19 +02:00
Shameer Ashraf
5c01a44644 Updated changelog 2018-06-29 13:27:55 -04:00
Shameer Ashraf
4eb49d872b Updated changelog 2018-06-29 13:24:28 -04:00
Shameer Ashraf
34e5f29419 Fixed Wind Chill in Kelvin 2018-06-29 01:00:20 -04:00
Shameer Ashraf
f4910f0a8e Fixed Heat Index for Kelvin 2018-06-29 00:23:04 -04:00
Michael Teeuw
c8c14611dc Merge pull request #1334 from mdrayer/quick-fix-readme-raspberry-pi
Correct the "Raspberry Pi" link in the ToC.
2018-06-27 20:22:30 +02:00
Michael Drayer
491201991e Correct the "Raspberry Pi" link in the ToC. 2018-06-27 14:18:25 -04:00
Michael Teeuw
401f3574fd Update CHANGELOG.md 2018-06-27 10:29:49 +02:00
Michael Teeuw
173a86172c Add update translations. 2018-06-27 10:29:08 +02:00
Michael Teeuw
9ecbff024a Update CHANGELOG.md 2018-06-27 10:26:30 +02:00
Michael Teeuw
1b5be34be4 Merge pull request #1333 from ubertao/fixlocale
Fix locale id zh_cn -> zh-cn, zh_tw -> zh-tw, pt_br -> pt-br
2018-06-27 10:25:34 +02:00
Michael Teeuw
ceb3a997b6 Merge pull request #1330 from pintman/patch-1
minor typo in position fixed.
2018-06-27 10:23:15 +02:00
Ubertao
b1ead7fec8 Fix locale id zh_cn -> zh-cn, zh_tw -> zh-tw, pt_br -> pt-br 2018-06-27 14:09:02 +08:00
Michael Teeuw
d534dbb006 Merge pull request #1331 from flyingchipmunk/dev_newsfeed_logging
Add option to newsfeed for logging errors
2018-06-27 02:39:14 +02:00
Matthew Veno
e56377117b Add option to newsfeed for logging errors
- 'logFeedWarnings' added to newsfeed config, defaulted to false
- Only log parse feed errors when logFeedWarnings is true
- Updated README and CHANGELOG
- Fixes #1329
2018-06-26 20:01:28 -04:00
Marco Bakera
63483dc6c3 minor typo in position fixed. 2018-06-24 14:29:55 +02:00
Michael Teeuw
dd793650c3 Merge pull request #1314 from Ybbet/develop
Customize classes for table.
2018-06-12 09:19:16 +02:00
Teddy Payet
afd829307d Tabs and spaces from the original files
With a diff, here the orginal tabulations.
2018-06-11 23:09:00 +02:00
Teddy Payet
09abdc0f12 ESLint format
Resolve format ith eslint
2018-06-11 19:59:21 +02:00
Teddy Payet
ed4d17f578 README updated
Update of README for the new option.
2018-06-11 16:41:08 +02:00
Teddy Payet
aeeeb5a37b Add changelog 2018-06-11 14:04:06 +02:00
Teddy
dcb2e51587 Update .gitignore 2018-06-11 14:00:16 +02:00
Teddy Payet
cbc2eaf908 Customize classes for table
MagicMirror offers helper classes in the main.css. Therefore, we give
the possibility to indicate the class that we want.
2018-06-11 12:54:27 +02:00
Michael Teeuw
8808031e7c Merge pull request #1309 from sdetweil/fix_suspend
invoke callback for suspend notification, even if no dom content
2018-06-08 13:21:40 +02:00
Sam Detweiler
23ac7213d3 remove trailing spaces from reformatted else 2018-06-08 06:11:36 -05:00
Michael Teeuw
add7b44d0b Style change. 2018-06-07 16:31:49 +02:00
Michael Teeuw
1e4b7599a7 Merge branch 'develop' into fix_suspend 2018-06-07 16:29:16 +02:00
Sam Detweiler
54443b038a Revert "fix changelog"
This reverts commit c3f03e3f95.
2018-06-07 08:09:39 -05:00
Sam Detweiler
c3f03e3f95 fix changelog 2018-06-07 08:04:49 -05:00
Sam Detweiler
18135624f6 update changelog 2018-06-07 08:02:16 -05:00
Sam Detweiler
11238d6b71 fix tabs 2018-06-07 07:59:07 -05:00
Sam Detweiler
848f94b1e0 invoke callback for suspend notification, even if no dom content 2018-06-07 07:50:42 -05:00
Michael Teeuw
d47cfe9504 Merge pull request #1304 from kjb085/kb/calendar-regex
Add regex filtering to calendar module
2018-06-05 21:02:56 +02:00
Kenn Breece
70dccff293 Add regex filtering to calendar module 2018-06-03 21:12:31 -04:00
Michael Teeuw
e40873710b Merge pull request #1302 from idoodler/develop
Ability to fetch compliments from a remote server
2018-06-03 19:46:01 +02:00
idoodler
b140ef3b7a Ability to fetch compliments from a remote server 2018-06-03 15:47:56 +02:00
Michael Teeuw
3b7b74aa67 Merge pull request #1297 from OiYouYeahYou/linting-fix
Add and lint clientonly/index.js
2018-05-29 11:56:18 +02:00
Jason
de8e5b2d69 Merge branch 'develop' into linting-fix 2018-05-26 19:44:06 +01:00
Jason
afea33b0e3 Changelog 2018-05-26 19:42:58 +01:00
Jason
b44fbc1e4f add and lint clientonly 2018-05-26 19:36:46 +01:00
Michael Teeuw
c4dee3dd8d Merge pull request #1293 from derRAV3N/patch-1
Add note to README.md
2018-05-22 15:27:03 +02:00
derRAV3N
091e024032 Add note to README.md
Add note to README.md to not add calendars that have entries before 1st January 1970.
2018-05-22 15:14:05 +02:00
Michael Teeuw
0e030f7f48 Add information about the Electron update. 2018-05-21 14:06:50 +02:00
Michael Teeuw
3049ba0b24 Merge pull request #1290 from edward-shen/develop
newsfeed now remembers user configuration settings for descriptions after fullscreen view. Fixes #1282.
2018-05-16 07:27:38 +02:00
Edward Shen
55a161fafe Fixes #1282.
Added a runtime var isShowingDescription that gets reset to user config.
this.config.showDescription no longer mutates during runtime.
Changelog has been updated to include this fix.
2018-05-15 20:37:45 -04:00
Michael Teeuw
349af24c81 Merge pull request #1287 from ringzer/patch-1
Update README.md
2018-05-12 12:33:25 +02:00
ringzer
788f1c4b3e Update README.md
Included /home/pi/MagicMirror/ path when copying config.js.sample and running npm run config:check
2018-05-11 16:47:03 +01:00
Michael Teeuw
889af461c6 Upgrade to Electron 2.0.0. 2018-05-11 16:23:43 +02:00
Michael Teeuw
df86e59089 Merge pull request #1284 from jrlambs/develop
New calendar display format
2018-05-11 15:36:36 +02:00
=
c6bf69cce4 fix linting errors. add line to changelog 2018-05-10 19:54:01 -04:00
=
e492012004 fix missing s on timeFormat 2018-05-09 22:36:53 -04:00
=
94c46f9881 New calendar display format with date headers for days and times listed next to events for that date
IE:

Sunday, May 1st
  2:00 pm       Soccer
  4:00 pm       Basketball
2018-05-09 22:32:15 -04:00
Michael Teeuw
1eaa9d32ea Merge pull request #1283 from jannekalliola/develop
Changed weatherforecast to use dt_txt field
2018-05-09 09:35:49 +02:00
Janne Kalliola
0e2e8d2e2a Changed weatherforecast to use dt_txt field 2018-05-08 18:45:38 +03:00
Michael Teeuw
cfb39c6364 Merge pull request #1279 from parnic/develop
Fixed coloredSymbolOnly
2018-05-05 18:38:54 +02:00
Parnic
173499f496 Fixed coloredSymbolOnly 2018-05-05 08:31:58 -05:00
Michael Teeuw
1081049074 Merge pull request #1264 from parnic/develop
Fixed heat index
2018-05-01 09:55:42 +02:00
Michael Teeuw
961dc85514 Merge pull request #1275 from john3300/colored-symbol-only
Added option to calendar module that colors only the symbol
2018-05-01 09:55:13 +02:00
Michael Teeuw
6434acd492 Merge branch 'develop' into colored-symbol-only 2018-05-01 09:55:05 +02:00
Michael Teeuw
ccb27c89d8 Merge pull request #1262 from ndom91/patch-1
Updated newsfeed.js - improved fullscreen iframe
2018-05-01 09:53:56 +02:00
Brian Johnson
8053256203 Added option to calendar module that colors only the symbol instead of the whole line 2018-04-27 11:06:45 -05:00
Parnic
4abd7301fd Updated changelog 2018-04-17 19:45:12 -05:00
Parnic
d6fe5ab417 Fixed heat index
Celsius and Fahrenheit were flipped. The index was computed in Fahrenheit but used as if it were Celsius.
2018-04-17 19:43:09 -05:00
Nico Domino
a739fbdf1d Update CHANGELOG.md 2018-04-17 00:39:05 +02:00
Nico Domino
c90a1ab6dc Updated newsfeed.js - improved fullscreen iframe
Had much better performance using 100vw (viewport width) than 100% (why - idk), but with 100% about 5% of my screen (1080x1920) to the right of the scroll bar was left black/blank, with 100vw I legitimately takes up the whole screen/viewport width. 

With the 10000 height the articles would always load about half way scrolled down. So I reduced the height and style.height to 3000. At my resolution at least, which I assume is fairly common, I had much better results. Unfortunately 3000 also isn't perfect - this still requires some tweaking. The article loads perfectly at the top of the iframe at 2500, but 2500 is much too small for most articles. 3000 seemed a good compromise, I could scroll far enoguh to read most articles on Reuters, and also load far enoguh up to read the beginning of the article.

And finally I added a "scroll back up" button notification. This seems to work flawlessly.
2018-04-17 00:25:58 +02:00
Michael Teeuw
05ef68e079 Merge pull request #1258 from jannekalliola/develop
Support for hiding on-going events
2018-04-08 18:14:39 +02:00
Michael Teeuw
dee4a7f3c7 Merge pull request #1257 from parnic/develop
Fixed to work in Midori browser
2018-04-08 18:11:00 +02:00
Janne Kalliola
75753df0d8 Added description of on-going event hiding changes to the changelog 2018-04-08 15:07:20 +03:00
Janne Kalliola
30c5d78647 Support for hiding on-going events 2018-04-08 14:57:28 +03:00
Chris Pickett
6bb4db3842 Midori 0.4.3 support 2018-04-07 20:01:53 -05:00
Chris Pickett
cc0907fcd7 Updated changelog 2018-04-07 20:00:51 -05:00
Michael Teeuw
20b018bcc7 Merge pull request #1250 from bastilimbach/master
Remove yarn-or-npm as it breaks production builds
2018-04-06 14:40:26 +02:00
Michael Teeuw
aafe2fa8d0 Update CHANGELOG.md 2018-04-06 14:39:41 +02:00
Michael Teeuw
ee7bd73b3f Merge branch 'develop' into master 2018-04-06 14:39:04 +02:00
Michael Teeuw
b67f3bd629 Move change to 2.4.0 changelog. 2018-04-06 14:37:26 +02:00
Michael Teeuw
38b81e79f8 Merge pull request #1255 from wonjerry/develop
Error in default/currentWeather
2018-04-06 14:35:19 +02:00
wonjerry
b73c549131 Error in MagicMirror/modules/default/currentWeather/currentWeather.js line 296, 300
Notice that self.config.animationSpeed can not be found because the notificationReceived function does not have "self" variable.
2018-04-06 21:25:10 +09:00
Michael Teeuw
d21d9f0141 Use Electron 2 Beta. 2018-04-06 13:21:53 +02:00
Michael Teeuw
7bb85032a1 Merge pull request #1252 from BerndKohl/feelslike-localisation
enabling translation for "feelsLike" in current weather
2018-04-06 13:11:51 +02:00
Michael Teeuw
d90446ad28 Update CHANGELOG.md 2018-04-06 13:10:41 +02:00
Michael Teeuw
8b5e2f5528 Add dutch 'Feels' temperature. 2018-04-06 13:04:55 +02:00
Michael Teeuw
1bcc3ab7f1 Add default translation. 2018-04-06 13:04:04 +02:00
Michael Teeuw
3359c3cd45 Update currentweather.js 2018-04-06 13:03:06 +02:00
Michael Teeuw
af812f3c90 Fix translation file. 2018-04-06 13:02:27 +02:00
Michael Teeuw
1e6201093b restore windChillInF variable. 2018-04-06 13:01:23 +02:00
BerndKohl
959ea69427 enabling translation for "feelsLike" in current weather
enabled translation
fixed typos in comments
added German translation
2018-04-06 12:28:47 +02:00
Sebastian Limbach
cea744a914 Remove yarn-or-npm 2018-04-03 19:38:00 +02:00
Michael Teeuw
e8baf48764 Update CHANGELOG.md 2018-04-02 14:18:28 +02:00
Michael Teeuw
41242a2ae1 Merge pull request #1248 from E3V3A/patch-5
null check for notification removal
2018-04-02 14:17:25 +02:00
Michael Teeuw
f1dee488a7 Fix indent. 2018-04-02 14:11:21 +02:00
Michael Teeuw
3b4ff1818e Update CHANGELOG.md 2018-04-02 14:03:16 +02:00
E:V:A
497145b1b5 null check for notification removal
Make sure there is something to remove, before we attempt to remove the notifications. 
- This fixes #1240
2018-04-02 14:07:25 +03:00
Michael Teeuw
10eb41d319 FIx wind chill in Fahrenheit. 2018-04-02 12:58:19 +02:00
Michael Teeuw
4daf2e4a3d Merge pull request #1246 from secuflag/develop
Update italian translation
2018-04-01 19:44:24 +02:00
secuflag
f3266a5111 Update italian translation 2018-04-01 19:38:03 +02:00
Michael Teeuw
27cac4e8b8 Merge v2.3.1 2018-04-01 19:17:08 +02:00
Michael Teeuw
60b9a5b9da Merge pull request #1245 from MichMich/electron-downgrade
v2.3.1
2018-04-01 19:12:25 +02:00
Michael Teeuw
eaaa62a7f3 Downgrade Electron. 2018-04-01 19:05:38 +02:00
Michael Teeuw
6ce732ec3d Preparation for v2.4.0. 2018-04-01 14:23:28 +02:00
Michael Teeuw
fb0cc61e09 Merge pull request #1241 from MichMich/develop
Release 2.3.0
2018-04-01 14:16:36 +02:00
Michael Teeuw
be29b5daf8 Prepare for release 2.3.0 2018-04-01 14:08:38 +02:00
Michael Teeuw
f010adabd0 Merge pull request #1232 from Kiina/develop
Update electron to 1.7.13
2018-03-28 12:27:05 +02:00
Dominic Dey-Marckmann
c93b263b1f Update electron to 1.7.13 2018-03-27 21:09:08 +02:00
Michael Teeuw
15f34d6b54 Update CHANGELOG.md 2018-03-25 14:56:20 +02:00
Michael Teeuw
d0eeb55999 Merge pull request #1186 from BonySimon/patch-1
Fix exception on translation of objects
2018-03-25 14:55:52 +02:00
Michael Teeuw
08c0d39b23 Update translator.js 2018-03-25 14:55:42 +02:00
Michael Teeuw
d0ecde3277 Merge pull request #1176 from relm923/forecast_max_days
Forecast - Max Days
2018-03-25 14:53:30 +02:00
Michael Teeuw
45ec57afd7 Merge branch 'develop' into forecast_max_days 2018-03-25 14:52:42 +02:00
Michael Teeuw
b0cd053083 Merge pull request #1202 from iampranavsethi/currentweather-module-updates
Currentweather module updates
2018-03-25 14:52:05 +02:00
Michael Teeuw
698a11be58 Merge branch 'develop' into currentweather-module-updates 2018-03-25 14:51:47 +02:00
Michael Teeuw
efb08fb1e1 Update CHANGELOG.md 2018-03-25 14:51:18 +02:00
Michael Teeuw
f89bc8422e Merge pull request #1224 from bacongobbler/clearer-install-question
capitalize "y/n" for clearer intent
2018-03-25 14:47:35 +02:00
Michael Teeuw
4bf4889a08 Merge pull request #1225 from moham96/patch-1
use shallow clone
2018-03-25 14:47:09 +02:00
Michael Teeuw
01ab8ba38e Merge pull request #1227 from E3V3A/patch-4
removed known issues as they are closed
2018-03-25 14:46:44 +02:00
E:V:A
ae6d15e812 removed known issues as they are closed 2018-03-25 12:07:29 +03:00
MOHAMMAD RASIM
1abfbe1d34 use shallow clone
not need to download the whole repo history
2018-03-24 16:11:57 +03:00
Matthew Fisher
d3095297c2 capitalize "y/n" for clearer intent
If you press enter, `choice` is an empty string and will default to "no". The convention is to capitalize the default answer so users know what happens when they auto-accept prompts.
2018-03-23 16:29:37 -07:00
Michael Teeuw
79d40d5644 Merge pull request #1199 from ThomasMirlacher/develop
Add dc:date to parsing in newsfeed module, which allows parsing of mo…
2018-03-21 12:17:23 +01:00
Thomas Mirlacher
008e305a84 use doublequotes. 2018-03-21 11:58:09 +01:00
Michael Teeuw
0379611edd Merge pull request #1218 from kjb085/kb/calendar-adv-filter
Add advanced filtering to excludedEvents
2018-03-21 11:34:41 +01:00
Kenn Breece
96d883c1c7 Merge branch 'develop' into kb/calendar-adv-filter 2018-03-20 15:38:16 -04:00
Kenn Breece
be0f262e37 Add advanced filtering to excludedEvents 2018-03-18 23:54:23 -04:00
Michael Teeuw
1676adf071 Merge pull request #1209 from E3V3A/patch-3
update node stable to 9.x
2018-03-14 10:26:25 +01:00
E:V:A
a5d5630067 update node stable to 9.x 2018-03-14 11:24:41 +02:00
Pranav Sethi
275956caba Fixed typos in README.md for currentweather. 2018-03-12 22:22:45 -04:00
Michael Teeuw
bf8ed87fc9 Merge pull request #1197 from ptz0n/patch-1
Update README.md
2018-03-12 18:34:21 +01:00
Michael Teeuw
fb3afac097 Merge pull request #1200 from djgalloway/wip-apt-y
Assume yes when installing deps on Raspberry Pi via apt-get
2018-03-12 18:33:36 +01:00
Michael Teeuw
eda8b037a9 Merge pull request #1205 from Tajnymag/develop
Added yarn support
2018-03-12 18:32:31 +01:00
Marek Lukáš
8ef14f7a54 Added changes from [9974e35] to CHANGELOG 2018-03-12 15:33:30 +01:00
Marek Lukáš
9974e35656 Added yarn support 2018-03-12 15:28:43 +01:00
Pranav Sethi
15bc5431b6 Fixed Trailling Spaces 2018-03-12 05:25:33 -04:00
Pranav Sethi
f767531d89 Fixed Trailling Spaces 2018-03-12 05:25:01 -04:00
Pranav Sethi
7285ada9dd Added feels like and kmph wind for currentweather module 2018-03-12 05:06:16 -04:00
Pranav Sethi
b9b9773df9 Merge branch 'develop' into currentweather-module-updates 2018-03-12 03:56:44 -04:00
David Galloway
c29a83b259 Assume yes when installing deps on Raspberry Pi via apt-get
Signed-off-by: David Galloway <dgallowa@redhat.com>
2018-03-11 13:17:33 -04:00
Thomas Mirlacher
fa45e66da6 Add dc:date to parsing in newsfeed module, which allows parsing of more rss feeds. 2018-03-10 00:30:45 +01:00
Erik Eng
7cbcdddac9 Merge branch 'develop' into patch-1 2018-03-07 09:18:07 +01:00
Erik Eng
a2f17900da Update README.md
Correct manual installation step.
2018-03-07 09:13:33 +01:00
Michael Teeuw
fb7e97b8ad Merge pull request #1190 from E3V3A/patch-1
made the module "this" instances into a table
2018-03-06 09:36:04 +01:00
Michael Teeuw
0c92a8a8e9 Merge pull request #1191 from E3V3A/patch-2
fix md header
2018-03-06 09:35:34 +01:00
Michael Teeuw
dcc59380e5 Merge pull request #1194 from bastilimbach/develop
Remove old docker config and link to docker repository
2018-03-06 09:33:50 +01:00
Sebastian Limbach
f9bf25f96d Add changes 2018-03-04 14:07:44 +01:00
Sebastian Limbach
cbcbea8b08 Remove old docker config 2018-03-04 13:59:45 +01:00
Pranav Sethi
62eb4f20da Fixed Trailling Spaces to Pass checks 2018-03-03 05:08:12 -05:00
Pranav Sethi
43d5311e5e Fixed Trailling Spaces 2018-03-03 05:00:26 -05:00
Pranav Sethi
a6f08a09d5 Added Feels Like and Windspeed in KMPH 2018-03-03 04:52:22 -05:00
Pranav Sethi
d93f5d7785 Added Feels Like and Windspeed in KMPH 2018-03-03 04:21:24 -05:00
E:V:A
c7170e6dc2 fix md header 2018-03-01 11:53:10 +02:00
E:V:A
bcf3ca7339 made the module "this" instances into a table 2018-03-01 09:44:57 +02:00
Steelskin3
0388f5787a Fix exception on translation of objects
Sometimes, the content of translations[module.name][key] is not a string but an entire object. It cause a crash on template.replace(...) of createStringFromTemplate(...). It is currently the case of MMM-Voice-Control and the previous commit have broked this module (10 month ago... I am surprised to be the first founded it)
2018-02-23 11:51:59 +01:00
Michael Teeuw
6514df9d96 Merge pull request #1184 from patoberli/patch-1
Update README.md
2018-02-20 11:29:27 +01:00
Michael Teeuw
8f5b9869dc Merge branch 'develop' into patch-1 2018-02-20 11:28:58 +01:00
patoberli
580c5fe23f Update README.md
Added a hint to use the full and not lite version of Raspbian, as the GUI is missing and thus ndm (electron) can't start after the installation.
2018-02-17 21:54:31 +01:00
Michael Teeuw
b0af5b26ba Merge pull request #1183 from fewieden/feature/translations-update
translations update
2018-02-17 10:30:30 +01:00
Michael Teeuw
9e898932f6 Merge pull request #1182 from fewieden/feature/automated-tests
Automated tests
2018-02-17 10:29:23 +01:00
fewieden
1f873b93f6 changelog, linting 2018-02-17 10:17:59 +01:00
fewieden
f414707f11 update translations for updatenotifications 2018-02-17 10:14:37 +01:00
fewieden
505825056c use translation template for updatenotifications 2018-02-17 10:10:57 +01:00
fewieden
38f7716738 linting 2018-02-17 09:20:34 +01:00
fewieden
a69d08b554 changelog 2018-02-17 09:18:12 +01:00
fewieden
3ccdb64833 deprecated unit tests 2018-02-16 22:09:15 +01:00
fewieden
78d8bff599 clone array, clone nested object, add safe checks for objects (memory address) 2018-02-16 19:58:28 +01:00
fewieden
a756fed70b fixed and reenabled lockstring test 2018-02-16 08:43:27 +01:00
fewieden
3e2a1e3548 linting 2018-02-16 00:08:11 +01:00
fewieden
96b2f2b3a4 clone object unit test 2018-02-16 00:01:02 +01:00
fewieden
d81d7d4f68 compare version unit test 2018-02-15 23:53:57 +01:00
fewieden
20244c4fb5 translations integration test 2018-02-15 23:22:52 +01:00
Michael Teeuw
b50d31ffe2 Merge pull request #1178 from E3V3A/develop
Added ToC
2018-02-13 09:24:36 +01:00
fewieden
d709a44960 strip comments unit test 2018-02-13 07:17:46 +01:00
E:V:A
4e4d07ced6 Added ToC
ToDo: Fix ToC links to headers
2018-02-11 18:24:31 +02:00
fewieden
d775bc9d7e loadCoreTranslationsFallback unit test 2018-02-11 09:08:09 +01:00
fewieden
85528761eb only load core callback if there is one available 2018-02-11 09:07:41 +01:00
fewieden
ad3eac9ddb loadcoretransations unit test 2018-02-11 08:58:02 +01:00
Reagan Elm
613f9fccd2 Update changelog 2018-02-10 20:56:10 -05:00
Reagan Elm
3d1741c904 Respect maxNumberOfDays regardless of endpoint 2018-02-10 20:53:38 -05:00
fewieden
26be14ba67 load unit test 2018-02-10 20:33:22 +01:00
fewieden
daa0755920 add missing parameter in documentation 2018-02-10 12:38:55 +01:00
fewieden
305d60e09b translator unit tests 2018-02-10 12:32:43 +01:00
fewieden
d0029efd02 utils unit tests 2018-02-10 12:30:33 +01:00
fewieden
fb4d42bf5b moved test 2018-02-10 12:28:30 +01:00
Michael Teeuw
20eec53b14 Add Manifesto. 2018-02-07 13:04:10 +01:00
Michael Teeuw
8343db44db Merge pull request #1173 from vvzvlad/vvzvlad_local
add variable morning afternoon times
2018-02-07 12:32:42 +01:00
vvzvlad
649652e373 Merge branch 'develop' into vvzvlad_local 2018-02-07 14:10:43 +03:00
vvzvlad
e37ed7c32d add variable morning afternoon times 2018-02-07 14:06:26 +03:00
vvzvlad
f9a525068b add variable morning afternoon times 2018-02-05 18:15:02 +03:00
Michael Teeuw
aa11e6d62e Merge pull request #1166 from henrysun18/develop
Show remote compliments on boot
2018-02-01 08:20:22 +01:00
henrysun18
6802d152da Show remote compliments at boot instead of after one updateInterval 2018-01-31 23:19:47 -05:00
Michael Teeuw
3b40f393d8 Merge pull request #1163 from pinsdorf/patch-1
corrected link to 3rd party modules wiki page
2018-01-30 13:49:37 +01:00
pinsdorf
020443ae8a corrected link to 3rd party modules wiki page
The link to the 3rd Party Modules still directs to the old wiki page, where use has to follow another link to the right page. Updated the link in README.md to navigate to the right wiki page instantly.
2018-01-30 10:59:18 +01:00
Michael Teeuw
1d0baccffc Merge pull request #1161 from thobach/master
Allow to scroll in full page article view of default newsfeed module
2018-01-30 09:47:33 +01:00
Thomas Bachmann
5426f0f329 Updated documentation for scroll mode in newsfeed module 2018-01-29 21:41:43 +01:00
Thomas Bachmann
790249dd1a Merge branch 'MichMich/develop' 2018-01-29 21:37:25 +01:00
Thomas Bachmann
446a201d25 Allow to scroll articles with gesture events 2018-01-29 21:26:34 +01:00
Thomas Bachmann
b6538d5e18 Merge remote-tracking branch 'MichMich/master' 2018-01-29 18:54:32 +01:00
Michael Teeuw
edd6043059 Fail PRs that are sent to the master branch. 2018-01-26 12:12:44 +01:00
Michael Teeuw
fe4ffeb7f1 Text cleanup. 2018-01-25 20:45:25 +01:00
Michael Teeuw
27b3875bfb Changed missing Changlog text. 2018-01-25 20:38:42 +01:00
Michael Teeuw
e2dbe8a0a2 Minor fixes. 2018-01-25 20:07:51 +01:00
Michael Teeuw
29fc7910b7 Remove Jest. Update dangerfile.js. 2018-01-25 19:51:23 +01:00
Michael Teeuw
22e2fdc707 Jest implementation to get danger.js to work. 2018-01-25 19:43:09 +01:00
Michael Teeuw
584786eb9f Temp disable danger. 2018-01-25 17:00:51 +01:00
Michael Teeuw
d803d9eaf9 Import 'includes' from lodash. 2018-01-25 16:39:49 +01:00
Michael Teeuw
bad6575d83 Add Danger.js 2018-01-25 16:24:05 +01:00
Michael Teeuw
fbcb7ae836 Update README.md 2018-01-23 19:10:37 +01:00
Michael Teeuw
2c1a1b10c8 Merge pull request #1147 from E3V3A/patch-2
Update README.md
2018-01-23 09:51:15 +01:00
E:V:A
155fb16a8a Update README.md
Updated README by reformatting and restructuring.
- Added, Clarified and corrected grammatics and wrong info 
- Moved/Removed some redundant parts
2018-01-23 10:44:55 +02:00
Michael Teeuw
b1ab2ce96a Merge pull request #1146 from cederstrom/put-article-in-front-of-modules
Put article iframe in front of modules
2018-01-21 11:33:22 +01:00
Andreas Cederström
f299ba6218 Put article ifram in front of modules
Before this change the article was brought up in its ifram in fullscreen and you could still see the other modules in front of it
2018-01-20 23:46:58 +01:00
Michael Teeuw
d167ad1923 Merge pull request #1136 from E3V3A/patch-2
Update README
2018-01-19 09:15:54 +01:00
E:V:A
93626e8154 Fixed bullet points markup for lint 2018-01-19 09:13:59 +02:00
Michael Teeuw
d5040c091a Merge pull request #1143 from shbatm/bug-fix
Fix for #1140 - sendNotification module errors after #1116
2018-01-18 13:35:47 +01:00
shbatm
868daef0f0 Fix for #1140 - sendNotification module errors after #1116 2018-01-17 09:49:17 -06:00
Michael Teeuw
dc8e85e7f2 Merge pull request #1139 from amcolash/patch-1
Change English translation to "In 2 days"
2018-01-16 09:20:57 +01:00
Michael Teeuw
22d32d7ca3 Merge pull request #1141 from ConnorChristie/old-dom-event-fix
Fix to emit DOM_OBJECTS_CREATED event after module DOMs have actually loaded
2018-01-16 09:20:39 +01:00
Connor Christie
2d500f8074 Fix to emit DOM_OBJECTS_CREATED event after module DOMs have actually loaded 2018-01-14 22:03:09 -06:00
Andrew McOlash
452cdc17c6 Change English translation to "In 2 days" 2018-01-14 15:52:15 -06:00
E:V:A
bcbfee0321 Update README
Updated README to warn about long installation time as discussed in #1124.
2018-01-12 10:00:35 +02:00
Michael Teeuw
dab2e7ede3 Merge pull request #1127 from roramirez/set-version-test-7-node
Set only 7 version of node to run tests in Travis CI
2018-01-08 11:26:25 +01:00
Michael Teeuw
d91acb8352 Merge pull request #1126 from d-Rickyy-b/patch-1
Fix typo in newsfeed documentation
2018-01-08 11:23:49 +01:00
Rodrigo Ramírez Norambuena
373dd8058e Set only 7 version of node to run tests in Travis CI 2018-01-07 01:03:00 -03:00
Rico
de6310e52a Fix typo
A little typo which lead to poor formatting
2018-01-07 03:30:01 +01:00
Michael Teeuw
8c297a4a4c Merge pull request #1123 from E3V3A/patch-1
Added general advice
2018-01-06 19:49:44 +01:00
E:V:A
4eb5c817bc fixed typos 2018-01-06 20:19:43 +02:00
E:V:A
07e4b26b9e Added general advice 2018-01-06 19:57:46 +02:00
Michael Teeuw
b63aa62985 Merge pull request #1121 from henrikra/master
Add basic typescript types for module
2018-01-06 14:29:52 +01:00
Henrik Raitasola
ca701c0580 Merge branch 'master' of github.com:henrikra/MagicMirror 2018-01-06 15:26:51 +02:00
Henrik Raitasola
e37043a6a8 Solve conflict 2018-01-06 15:26:38 +02:00
Michael Teeuw
7c26975d14 Merge branch 'develop' into master 2018-01-06 14:16:21 +01:00
Henrik Raitasola
47f8a43637 Add changelog 2018-01-06 15:10:10 +02:00
Henrik Raitasola
1238c0cefe Rename file to be more explicit 2018-01-06 15:06:58 +02:00
Henrik Raitasola
4c35fda045 Add most used module properties 2018-01-06 15:04:54 +02:00
Henrik Raitasola
780124c2f5 Add basic types to get started 2018-01-06 14:51:32 +02:00
Michael Teeuw
38e0af41ce Merge pull request #1116 from ConnorChristie/async-dom
DOM creation notifications in cases of async template rendering
2018-01-04 21:51:13 +01:00
Connor Christie
601e99eec0 Merge branch 'develop' into async-dom 2018-01-02 18:10:07 -06:00
Connor Christie
745a2adee7 Merge branch 'develop' into async-dom 2018-01-02 18:08:55 -06:00
Connor Christie
9e83234df1 Update changelog 2018-01-02 18:06:21 -06:00
Connor Christie
e45eeadf7d Merge remote-tracking branch 'origin/master' into async-dom 2018-01-02 18:04:03 -06:00
Michael Teeuw
9a778cea6b Merge v2.2.2 changes. 2018-01-02 18:46:41 +01:00
Michael Teeuw
20823bfc87 Add missing package-lock.json. 2018-01-02 18:41:33 +01:00
Connor Christie
be3d703692 Fix linter errors 2018-01-01 10:55:39 -06:00
Connor Christie
e2df5739f0 Update module docs 2018-01-01 10:40:52 -06:00
Connor Christie
7bb11d6436 Add documentation regarding updates 2018-01-01 10:38:00 -06:00
Connor Christie
80b84212cc Add notification for module dom creation with async support 2018-01-01 10:23:15 -06:00
Connor Christie
4a1bee769b Add true module dom creation events 2018-01-01 09:42:34 -06:00
Michael Teeuw
de99a7aeaf Merge 2.2.1 changes. 2018-01-01 14:23:38 +01:00
Michael Teeuw
a0a02701b0 Update version number. 2018-01-01 13:42:39 +01:00
Michael Teeuw
1314ae1555 Add info about v2.2.1 2018-01-01 13:40:39 +01:00
Michael Teeuw
67cf0e745c Fix linting errors. 2018-01-01 13:39:05 +01:00
Michael Teeuw
538a2acbf5 Fix linting errors. 2018-01-01 13:38:07 +01:00
Michael Teeuw
8d0e453666 Preparation for v2.3.0 release. 2018-01-01 12:59:28 +01:00
Michael Teeuw
ace04f0b30 Merge pull request #1115 from MichMich/develop
Cleanup.
2018-01-01 12:48:22 +01:00
Michael Teeuw
f8e25d6c4a Cleanup. 2018-01-01 12:47:54 +01:00
Michael Teeuw
b2bc43da4f Merge pull request #1113 from MichMich/develop
Release v2.2.0.
2018-01-01 12:44:24 +01:00
Michael Teeuw
cb12e540d2 Add package lock. 2018-01-01 12:40:37 +01:00
Michael Teeuw
39955af2fa Upgrade packages. 2018-01-01 12:36:53 +01:00
Michael Teeuw
86e1f0615d Prepare for release v2.2.0 2018-01-01 12:33:00 +01:00
Michael Teeuw
dc81ab6dee Merge pull request #1111 from TTigges/weather_decimal_marks
added option of decimal comma for temp values for default weather modules
2017-12-31 12:25:24 +01:00
Michael Teeuw
f8cf6a65ae Merge branch 'develop' into weather_decimal_marks 2017-12-31 12:25:06 +01:00
Michael Teeuw
ba909c696d Merge branch 'develop' into weather_decimal_marks 2017-12-31 12:24:25 +01:00
Torben Tigges
df0515cebf currentweather, weatherforecast, changed option of decimal comma to any decimal symbol 2017-12-31 01:15:59 +01:00
Torben Tigges
46c0e14d67 currentweather, weatherforecast, added option of decimal comma for temperature values to config 2017-12-30 22:03:26 +01:00
Michael Teeuw
97d7733464 Remove trailing spaces. 2017-12-30 21:46:34 +01:00
Michael Teeuw
afda84ef09 Electron reverted. 2017-12-30 21:39:56 +01:00
Michael Teeuw
61d6e74102 Use an old electron version ...
Hopefully Electron will be fixed soon.
2017-12-30 21:33:56 +01:00
Michael Teeuw
8d74258ce2 Merge pull request #1102 from EricWarnke/patch-1
Spelling/grammar fix
2017-12-13 09:22:38 +01:00
Eric Warnke
5dfba0b834 Spelling/gramar fix 2017-12-12 15:54:33 -07:00
Michael Teeuw
056370ec08 Merge pull request #1092 from sebcaps/develop
Fix #1091 : handle empty description
2017-11-26 20:54:13 +01:00
unknown
4e2c254558 Fix #1091 : handle empty description 2017-11-26 11:52:01 +01:00
Michael Teeuw
38c2bdb447 Merge pull request #1090 from rejas/patch-1
Fix typo
2017-11-26 10:42:20 +01:00
Veeck
0cee4717e2 Fix typo 2017-11-26 10:02:31 +01:00
Michael Teeuw
221b04c466 Merge pull request #1089 from MichMich/patch-1
Update CHANGELOG.md
2017-11-25 12:15:54 +01:00
Michael Teeuw
237e9b7191 Merge pull request #1088 from reeno/patch-2
fixed width Font Awesome symbols
2017-11-25 12:15:27 +01:00
Michael Teeuw
9457e44a88 Update CHANGELOG.md 2017-11-25 12:14:54 +01:00
reeno
80a9d40a44 fixed width Font Awesome symbols
See http://fontawesome.io/examples/#fixed-width
2017-11-25 12:08:40 +01:00
Michael Teeuw
0715325a63 Merge pull request #1081 from ChytilTomas/develop
Develop
2017-11-17 09:06:06 +01:00
Michael Teeuw
0a026fef0f Update CHANGELOG.md 2017-11-17 09:05:33 +01:00
Tomáš Chytil
5fbf650d2d Czech translation 2017-11-16 23:06:52 +01:00
Tomáš Chytil
dabdde0c3f Czech translation 2017-11-16 23:01:00 +01:00
Michael Teeuw
b6ca92a7ef Merge pull request #1080 from slametps/develop
some new features (resubmission)
2017-11-15 08:26:25 +01:00
slametps
62f7339170 add some new options
add some new options
2017-11-15 12:21:45 +07:00
slametps
eaec682ea7 per feed reloadInterval support
per feed reloadInterval support
2017-11-15 12:21:22 +07:00
slametps
12110a4442 new options
* truncated description support
* specific reloadInterval for particular feed
2017-11-15 12:21:02 +07:00
slametps
df597f53b2 add no-cache entries in HTTP header
add no-cache entries in HTTP header
2017-11-15 12:19:53 +07:00
slametps
d7d40254d4 updated
updated
2017-11-15 12:19:19 +07:00
Michael Teeuw
e7c4a2cce6 Merge pull request #1072 from morozgrafix/newsfeed_filter
Added ability to set a list of prohibited words that will be filtered…
2017-11-01 11:53:00 +01:00
Sergey Morozov
0eb1c0cea6 Added ability to set a list of prohibited words that will be filtered out of newsfeed
Resolves #1071

`prohibitedWords` config parameter is an array of words. If set and case insensitive greedy match is found anywhere in the title then that newsfeed item will not be displayed. Readme updated with instructions.

Users should be careful on the words selection as careless setting may remove many or all items from the newsfeed. Some obvious mistakes like `space, comma, dot` etc. can be prevented programatically, but I left it out of this PR

Example:

with `prohibitedWords: ['dodgers']`

Original `newsItems`:
```
0:{title: "New York City, Russia, Los Angeles Dodgers: Your Wednesday Briefing", description: "Here’s what you need to know to start your day.", pubdate: "Wed, 01 Nov 2017 09:37:36 GMT", url: "https://www.nytimes.com/2017/11/01/briefing/new-yo…ssia-los-angeles-dodgers.html?partner=rss&emc=rss", sourceTitle: "New York Times"}
1:{title: "A Mangled School Bus, Bodies Everywhere; ‘It Was Surreal’", description: "A truck ramming bicyclists. The driver emerging wi…e attack, it was as confusing as it was gruesome.", pubdate: "Wed, 01 Nov 2017 09:27:41 GMT", url: "https://www.nytimes.com/2017/10/31/nyregion/nyc-sc…r-attack-truck-witnesses.html?partner=rss&emc=rss", sourceTitle: "New York Times"}
2:{title: "Dodgers 3, Astros 1 | Series tied, 3-3: With a Rally and a Romp, Dodgers Top Astros and Force Game 7", description: "Down by a run with just four innings left in Game …nst a dominating Justin Verlander. Game 7 awaits.", pubdate: "Wed, 01 Nov 2017 07:21:07 GMT", url: "https://www.nytimes.com/2017/11/01/sports/dodgers-win-game-6.html?partner=rss&emc=rss", sourceTitle: "New York Times"}
3:{title: "José Andrés Fed Puerto Rico, and May Change How Aid Is Given", description: "The chef’s huge effort is just the latest led by c…ocally based way to feed people after a disaster.", pubdate: "Wed, 01 Nov 2017 06:40:09 GMT", url: "https://www.nytimes.com/2017/10/30/dining/jose-andres-puerto-rico.html?partner=rss&emc=rss", sourceTitle: "New York Times"}
```

Filtered `newsItems`:
```
0:{title: "A Mangled School Bus, Bodies Everywhere; ‘It Was Surreal’", description: "A truck ramming bicyclists. The driver emerging wi…e attack, it was as confusing as it was gruesome.", pubdate: "Wed, 01 Nov 2017 09:27:41 GMT", url: "https://www.nytimes.com/2017/10/31/nyregion/nyc-sc…r-attack-truck-witnesses.html?partner=rss&emc=rss", sourceTitle: "New York Times"}
1:{title: "José Andrés Fed Puerto Rico, and May Change How Aid Is Given", description: "The chef’s huge effort is just the latest led by c…ocally based way to feed people after a disaster.", pubdate: "Wed, 01 Nov 2017 06:40:09 GMT", url: "https://www.nytimes.com/2017/10/30/dining/jose
```
2017-11-01 03:50:34 -07:00
Michael Teeuw
f4d5996a88 Allow use of .njk extension for template files. 2017-10-18 13:49:03 +02:00
Michael Teeuw
c75662e720 Remove trailing spaces. 2017-10-18 12:01:06 +02:00
Michael Teeuw
79a662fb93 Log nunjucks parsing errors for debugging. 2017-10-18 11:55:02 +02:00
Michael Teeuw
8b009b7ee9 Add Catalan translation. 2017-10-18 10:15:47 +02:00
Michael Teeuw
c4face30cc Update CHANGELOG.md 2017-10-18 10:14:54 +02:00
sergibarca
d4dbb5cb51 Translation to Catalan. 2017-10-17 22:24:13 +02:00
Michael Teeuw
1e27187652 Merge pull request #1060 from nhubbard/revert-1053-remove-package-lock.json
Revert "Delete large package-lock.json files"
2017-10-16 14:46:39 +02:00
Michael Teeuw
3ff278291f Merge pull request #1061 from qistoph/difflink
Add Github diff link to update info
2017-10-16 14:43:55 +02:00
Chris van Marle
4e8bf216df Update CHANGELOG 2017-10-16 14:26:15 +02:00
Chris van Marle
e7b9100f1c Add Github link to update info 2017-10-16 14:24:29 +02:00
Michael Teeuw
08aa9790f3 Fix lint issues. 2017-10-16 14:17:12 +02:00
Michael Teeuw
5f13fd2dca Merge pull request #1058 from shbatm/develop_1056
Gracefully Shutdown Module node_helpers on exit/SIGINT (Fixes #1056)
2017-10-16 13:59:40 +02:00
shbatm
f4c6f42c38 Added default implementation of stop() function. 2017-10-15 18:44:11 -05:00
Nicholas Hubbard
6a10d08189 Revert "Delete large package-lock.json files" 2017-10-13 19:59:39 -04:00
shbatm
f646360af6 Gracefully shutdown node_helpers (Fixes #1056)
Updated documentation


Corrected Typo in Documentation


Style correction
2017-10-13 16:43:11 -05:00
Michael Teeuw
95f265ebbf Merge pull request #1057 from Stromwerk/develop
Add Bulgarian translations for MagicMirror² and Alert module
2017-10-13 21:05:16 +02:00
Kalin Koychev
39d0142993 - Add Bulgarian translations for MagicMirror² and Alert module 2017-10-13 21:51:21 +03:00
Michael Teeuw
da16172244 Merge pull request #1055 from qistoph/commentscheck
Check trailing white space in comments too
2017-10-13 20:39:44 +02:00
Michael Teeuw
71aded0fae Merge pull request #1054 from qistoph/gruntfix
Fix some white space grunt errors
2017-10-13 20:39:04 +02:00
Michael Teeuw
e173b3ea41 Merge pull request #1053 from roramirez/remove-package-lock.json
Delete large package-lock.json files
2017-10-13 20:38:18 +02:00
Chris van Marle
6c4f9466b9 Don't ignore comments in trailing whitespace check 2017-10-12 11:06:57 +02:00
Chris van Marle
664196c5ef Fix some trailing whitespace grunt errors 2017-10-12 10:23:40 +02:00
Michael Teeuw
c8d5044e7a Merge pull request #1051 from egin10/patch-1
correcting translation for indonesian language
2017-10-10 17:20:28 +02:00
Michael Teeuw
d8c31fe560 Merge pull request #1049 from egin10/patch-2
Updating and Correcting Translation
2017-10-10 17:19:50 +02:00
Rodrigo Ramírez Norambuena
516db855f5 Delete large package-lock.json files 2017-10-08 23:41:51 -03:00
Ginanjar S.B
9cdcf08ab1 correcting translation for indonesian language 2017-10-09 08:05:11 +07:00
Ginanjar
326fa73b22 Updating and Correcting Translation 2017-10-08 03:03:29 +07:00
Michael Teeuw
79cacefd07 Merge pull request #1047 from jannickfahlbusch/useHTTPSOpenWeatherMap
Weather (Current/Forecast): Use HTTPS instead of HTTP
2017-10-06 21:32:49 +02:00
Jannick Fahlbusch
07e28bfee6 Use HTTPS instead of HTTP
Chrome blocks insecure requests (HTTP) when MagicMirror is loaded
via HTTPS. This commit changes the protocol used for OpenWeatherMap.
2017-10-06 21:31:06 +02:00
Michael Teeuw
980b017fbe Merge pull request #1046 from wbleek/master
moved weekNumber into field and adjusted language handling accordingly [issue #910]
2017-10-03 22:13:21 +02:00
Wolf-Gideon Bleek
4567fd1eb0 Merge branch 'develop' into master 2017-10-03 21:29:10 +02:00
Wolf-Gideon Bleek
8c150c23f3 moved weekNumber into field and adjusted language handling accordingly [issue #910] 2017-10-03 21:25:30 +02:00
Wolf-Gideon Bleek
b4fd570269 moved weekNumber into field and adjusted language handling accordingly [issue #910] 2017-10-03 21:18:25 +02:00
Michael Teeuw
6e051d73c1 Merge pull request #1044 from cederstrom/honor-calendar-maximum-entries
Slice the list of all calendar events to honor config.maximumEntries
2017-10-01 21:51:33 +02:00
Michael Teeuw
e381e1a313 Merge pull request #1042 from roramirez/readme-localhost-bind
Updated readme about default value for `address` configuration
2017-10-01 21:49:47 +02:00
Andreas Cederström
2d03ff63cf Slice the list of all events to honor config.maximumEntries
Scenario:
* Specify more than one calendar in `config.calendars`
* Specify a maximum number of entries in `config.maximumEntries`

Result:
The module will show as many as maximumEntries for EACH calendar

Expected:
The module shall not show more than a total of maximumEntries, regardless of how many calendars I specify

Fixes #1043
2017-10-01 21:47:10 +02:00
Rodrigo Ramírez Norambuena
309de631ed Updated readme about default value for address configuration changed it
in https://github.com/MichMich/MagicMirror/commit/2f05228d
2017-10-01 15:01:34 -03:00
Michael Teeuw
bad7316b80 Allow html tags in text string. 2017-10-01 13:22:29 +02:00
Michael Teeuw
4757c36233 Updated changelog and minor fix example 2017-10-01 13:16:07 +02:00
Michael Teeuw
9ca6180207 Merge branch 'templates' into develop 2017-10-01 13:10:25 +02:00
Michael Teeuw
30179ad977 Setup of new dev release. 2017-10-01 12:39:48 +02:00
Michael Teeuw
b799609749 Merge pull request #1039 from MichMich/develop
Release 2.1.3
2017-10-01 12:36:53 +02:00
Michael Teeuw
efb6994ae7 Changes in preparation of 2.1.3 2017-10-01 12:34:54 +02:00
Michael Teeuw
880a977dd6 Merge pull request #1038 from roramirez/templates-fixes
This fix the follow things:
2017-09-30 13:39:00 +02:00
Michael Teeuw
6eceffb403 Merge pull request #1037 from roramirez/lint-fix
Little lint fix
2017-09-30 13:36:38 +02:00
Rodrigo Ramírez Norambuena
795e33881c This fix the follow things:
* The default screen on missing configuration file and syntax error.
    * Tests
2017-09-29 19:10:03 -03:00
Rodrigo Ramírez Norambuena
d310c3857f Little lint fix 2017-09-29 18:33:17 -03:00
Michael Teeuw
8c53908cc4 Update CHANGELOG.md 2017-09-29 13:37:24 +02:00
Michael Teeuw
589b54984a Add slack badge. 2017-09-29 13:36:44 +02:00
Michael Teeuw
3f30ed5251 Add info about weather forecast. 2017-09-29 13:01:08 +02:00
Michael Teeuw
3f9181905a Fix typo's. 2017-09-29 11:05:59 +02:00
Michael Teeuw
29f3a81666 Fix weather forecast. 2017-09-29 10:04:42 +02:00
Michael Teeuw
5efc43260e Switch to async rendering. 2017-09-28 16:43:38 +02:00
Michael Teeuw
e01794a07f First Nunchucks Implementation. 2017-09-28 16:11:25 +02:00
Michael Teeuw
5fde095a6f Merge pull request #1024 from roramirez/openweathermap-forescast
Hack fix issue #1017
2017-09-28 14:44:13 +02:00
Michael Teeuw
3237af2d85 Add translation: Welsh (Cymraeg) 2017-09-28 14:42:21 +02:00
Michael Teeuw
953b666ebd Update translations.js 2017-09-28 14:41:30 +02:00
Michael Teeuw
417bb4bf37 Merge pull request #1022 from meigwilym/meigwilym-welsh-lang
Welsh (Cymraeg) language file
2017-09-28 14:39:26 +02:00
Michael Teeuw
a55213d88a Merge pull request #1019 from EdgardosReis/develop
Updated pt.json translation
2017-09-28 14:38:55 +02:00
Michael Teeuw
ec84d190f4 Remove newline. 2017-09-28 14:38:39 +02:00
Michael Teeuw
1b0bad72de Remove newline. 2017-09-28 14:38:08 +02:00
Michael Teeuw
931055708d Merge pull request #1033 from roramirez/one-instance-all-module-position-spec
Refactor modules_position_spec use one instance for all it statements
2017-09-26 08:56:06 +02:00
Rodrigo Ramírez Norambuena
15fd570b49 Refactor modules_position_spec use one instance for all it statements 2017-09-25 20:52:27 -03:00
Michael Teeuw
5e51a438a7 Merge pull request #1025 from ryck/feature/indoorHumidity
Feature/indoor humidity
2017-09-20 15:19:53 +02:00
Ricardo Gonzalez
7f768059e6 Update README 2017-09-17 16:33:23 +01:00
Ricardo Gonzalez
ea70175a17 Merge branch 'develop' into feature/indoorHumidity
* develop: (71 commits)
  Update sample address
  set version of express-ipfilter:
  Describe default in comment of sample config
  More secure defaults.
  Fix grunt errors
  Weather forecast settings match current weather
  Fix JavaScript error in weatherforecast
  Update fr.json
  TestSuite: Show the missing strings for translations files.
  Update fr.json with added translations
  Added e2e test for font files
  Fix issue #986
  Fix extra tab file translations/zh_cn.json
  Add Changelog entry for new e2e test for helloworld module
  Small change for re-running Travis CI
  Change Two Conditionals to UpperCase-If
  Fix linting?
  Show Scale of Temperature if config flag is set
  Change to install Roboto fonts by npm
  Update stylelint package
  ...

# Conflicts:
#	CHANGELOG.md
2017-09-17 16:32:37 +01:00
Ricardo Gonzalez
74a736691a Merge remote-tracking branch 'upstream/develop' into develop
* upstream/develop: (71 commits)
  Update sample address
  set version of express-ipfilter:
  Describe default in comment of sample config
  More secure defaults.
  Fix grunt errors
  Weather forecast settings match current weather
  Fix JavaScript error in weatherforecast
  Update fr.json
  TestSuite: Show the missing strings for translations files.
  Update fr.json with added translations
  Added e2e test for font files
  Fix issue #986
  Fix extra tab file translations/zh_cn.json
  Add Changelog entry for new e2e test for helloworld module
  Small change for re-running Travis CI
  Change Two Conditionals to UpperCase-If
  Fix linting?
  Show Scale of Temperature if config flag is set
  Change to install Roboto fonts by npm
  Update stylelint package
  ...
2017-09-17 16:31:27 +01:00
Mei Gwilym
86ff44adfc Welsh (Cymraeg) language file 2017-09-13 22:17:07 +01:00
Rodrigo Ramírez Norambuena
58b763e935 Hack fix issue #1017 2017-09-12 10:31:49 -03:00
EdgardosReis
5c90cc59aa Updated pt.json translation 2017-09-10 21:42:01 +01:00
Michael Teeuw
710ab44073 Merge pull request #1014 from roramirez/tests/unit/weatherforecast
Add roundValue unit test function weatherforecast module:
2017-09-07 10:07:28 +02:00
Michael Teeuw
b28c5e6807 Merge pull request #1015 from roramirez/show-missing-string-test-translations
TestSuite: Show the missing strings for translations files.
2017-09-07 10:07:09 +02:00
Michael Teeuw
e5ead9ed44 Merge pull request #1004 from qistoph/issue950
More secure defaults.
2017-09-06 15:25:04 +02:00
Chris van Marle
d99897cf9d Update sample address
As proposed in review
2017-09-06 15:22:17 +02:00
Michael Teeuw
701a7cae02 Merge pull request #1011 from qistoph/fix_on_991
Fix on 991
2017-09-06 14:40:32 +02:00
Michael Teeuw
068b6a5470 Merge pull request #1012 from roramirez/set-version-express-ipfilter
set version of express-ipfilter:
2017-09-06 14:19:30 +02:00
Rodrigo Ramírez Norambuena
45d597ac49 set version of express-ipfilter:
Prevent problems with ipWhitelist using []

Information in https://forum.magicmirror.builders/topic/4716/issue-with-white-list-ip-s-not-working/14
4adc5dc33e
2017-09-05 23:56:32 -03:00
Chris van Marle
a518d3f33f Describe default in comment of sample config 2017-09-01 14:46:25 +02:00
Chris van Marle
2f05228d91 More secure defaults.
Without config, listen only on looback interface. In sample config
listen on any interface, but use an IP whitelist.

Related to #950
2017-09-01 14:46:25 +02:00
Chris van Marle
335ae0105f Fix grunt errors 2017-09-01 11:17:01 +02:00
Chris van Marle
62ce7a0e37 Weather forecast settings match current weather
This change makes the config of weather forecast more in line with
current weather. It uses the configured units (metric, imperial,
default) to determine the sign.
2017-09-01 10:58:21 +02:00
Chris van Marle
afa0fb8da1 Fix JavaScript error in weatherforecast
Change 5568e0c2ad introduces JavaScript
errors, because it's calling toUpperCase() on a boolean value.
2017-09-01 10:38:25 +02:00
Michael Teeuw
763d835f4e Merge pull request #1006 from gcarret/patch-1
Added translations for french language
2017-08-29 14:17:43 +02:00
Michael Teeuw
0289872dcd Merge pull request #1000 from QNimbus/fix-issue-986
Fix for issue 986 (font file paths)
2017-08-29 14:15:27 +02:00
Michael Teeuw
2810141bd6 Merge pull request #997 from roramirez/extra-tab-translations/zh_cn.json
Fix extra tab file translations/zh_cn.json
2017-08-29 14:14:32 +02:00
Michael Teeuw
93ea22c69d Merge pull request #996 from roramirez/default-hello-world
Default hello world
2017-08-29 14:14:12 +02:00
Michael Teeuw
daf76a311c Merge pull request #991 from DanielWeeber/temperature-scale-show
Temperature scale show
2017-08-29 14:13:43 +02:00
gcarret
b94271a725 Update fr.json 2017-08-29 07:21:10 +02:00
Rodrigo Ramírez Norambuena
1456aeedf2 TestSuite: Show the missing strings for translations files.
In the translations test now when are missing some translations for
determinated language will be show the missing string.

This can help to identified and improved the translations files.

/me listening STP: Silvergun superman
2017-08-28 21:31:01 -03:00
gcarret
4c6589a57e Update fr.json with added translations 2017-08-27 14:30:58 +02:00
Bas van Wetten
5b9a61b7db Added e2e test for font files 2017-08-21 15:33:17 +02:00
Bas van Wetten
96e71695c5 Fix issue #986
Fixed some font file paths
2017-08-21 11:51:57 +02:00
Rodrigo Ramírez Norambuena
2e7dd1bde3 Fix extra tab file translations/zh_cn.json 2017-08-20 22:50:29 -03:00
Rodrigo Ramírez Norambuena
2de543f5f9 Add Changelog entry for new e2e test for helloworld module 2017-08-20 22:49:23 -03:00
Rodrigo Ramírez Norambuena
a6ee20fca4 Merge remote-tracking branch 'roramirez_github/develop' into default-hello-world 2017-08-20 22:49:13 -03:00
DanielWeeber
2d2f159e04 Small change for re-running Travis CI 2017-08-16 12:11:57 +02:00
DanielWeeber
5568e0c2ad Change Two Conditionals to UpperCase-If 2017-08-16 10:00:38 +02:00
DanielWeeber
cb2cc0cb9e Fix linting? 2017-08-15 20:57:18 +02:00
DanielWeeber
5e573ca980 Show Scale of Temperature if config flag is set 2017-08-15 19:54:35 +02:00
Michael Teeuw
dcb4a315a6 Merge pull request #990 from roramirez/deprecation-warning
Added deprecation warning for authentication of the calendar module.
2017-08-13 19:21:17 +02:00
Rodrigo Ramírez Norambuena
4bd36fc29e Merge branch 'develop' into deprecation-warning 2017-08-13 04:28:06 -03:00
Michael Teeuw
1a7971ec82 Merge pull request #987 from roramirez/update-stylelint
Update stylelint package
2017-08-12 16:52:13 +02:00
Michael Teeuw
c1eda034b3 Merge pull request #989 from roramirez/add-log-deprecated-function
Add log deprecated function in test
2017-08-12 13:50:52 +02:00
Michael Teeuw
2294d722c7 Merge pull request #986 from roramirez/roboto-fonts-as-vendor
Change to install Roboto fonts by npm
2017-08-12 13:50:23 +02:00
Michael Teeuw
7d053be6d1 Merge pull request #975 from QNimbus/unittests/calendar
Add unittest for calendar module
2017-08-12 13:50:07 +02:00
Michael Teeuw
7a508661eb Merge branch 'develop' into update-stylelint 2017-08-10 16:29:30 +02:00
Michael Teeuw
c976242ce5 Merge branch 'develop' into unittests/calendar 2017-08-10 16:27:00 +02:00
Michael Teeuw
2b77c372a3 Merge pull request #979 from CatoAntonsen/fix_filepath
Fix this.file path
2017-08-10 16:26:03 +02:00
Michael Teeuw
b61cc67997 Merge pull request #983 from roramirez/test-unit-js-class
Test unit js class
2017-08-10 12:15:31 +02:00
Michael Teeuw
de8db1a86d Merge branch 'develop' into test-unit-js-class 2017-08-10 12:15:23 +02:00
Michael Teeuw
abfdf0e1c2 Merge pull request #982 from roramirez/doc-roundValue
Fix Documentation in  roundValue function
2017-08-10 12:14:58 +02:00
Michael Teeuw
1d662e354b Merge branch 'develop' into doc-roundValue 2017-08-10 12:14:16 +02:00
Michael Teeuw
663e9a9b5e Merge pull request #973 from roramirez/add-code-error-cliente-failstart
Add log when clientonly failed on starting.
2017-08-10 12:12:24 +02:00
Michael Teeuw
8535409962 Merge branch 'develop' into add-code-error-cliente-failstart 2017-08-10 12:12:17 +02:00
Michael Teeuw
cd5623b348 Merge pull request #972 from roramirez/add-warning-color-full-ip
Add warning color when are using full ip whitelist
2017-08-10 12:11:51 +02:00
Michael Teeuw
673e051bd5 Merge pull request #969 from roramirez/showWeek-test-es-language
Show week test es language
2017-08-10 12:11:25 +02:00
Michael Teeuw
66c949057e Merge pull request #968 from roramirez/set-version-test-dependencies
Set version spectron for 3.6.x
2017-08-10 12:11:12 +02:00
Rodrigo Ramírez Norambuena
aed09f0c64 Change to install Roboto fonts by npm 2017-08-07 20:45:42 -04:00
Rodrigo Ramírez Norambuena
c05f306b0d Update stylelint package 2017-08-06 07:59:31 -04:00
Rodrigo Ramírez Norambuena
739fb99ced Resolved conflict unit tests between currentweather and newsfeed. 2017-08-06 07:53:03 -04:00
Rodrigo Ramírez Norambuena
7fc82ccead Update Changelog for unit tests for currentweather module 2017-08-07 20:42:32 -04:00
Rodrigo Ramírez Norambuena
8ae947f59c Merge remote-tracking branch 'origin/round-temp-unit' into doc-roundValue 2017-08-07 20:40:27 -04:00
Rodrigo Ramírez Norambuena
d34b493b7d Fix clock_es_spec running before the clock_spec 2017-08-05 22:30:38 -04:00
Rodrigo Ramírez Norambuena
4df6e0ee7d Merge remote-tracking branch 'upstream/develop' into showWeek-test-es-language 2017-08-05 21:12:39 -04:00
Rodrigo Ramírez Norambuena
aac4ef05e4 Merge remote-tracking branch 'upstream/develop' into test-unit-js-class 2017-08-05 19:50:34 -04:00
Rodrigo Ramírez Norambuena
ea2f53e166 Merge remote-tracking branch 'upstream/develop' into doc-roundValue 2017-08-05 18:20:22 -04:00
Rodrigo Ramírez Norambuena
f144ec67ab Add changelog entry for log in failed of clientonly 2017-08-05 17:48:20 -04:00
Rodrigo Ramírez Norambuena
7e42dcf0b5 Merge branch 'develop' into add-code-error-cliente-failstart 2017-08-05 17:47:36 -04:00
Rodrigo Ramírez Norambuena
87c4dc313a Merge branch 'develop' into set-version-test-dependencies 2017-08-05 17:44:51 -04:00
Rodrigo Ramírez Norambuena
0d29339898 Merge branch 'develop' into add-warning-color-full-ip 2017-08-05 17:44:05 -04:00
Michael Teeuw
6d83f18490 Merge pull request #981 from roramirez/disable-vendor_spec
Disabled tests of vendor_spec:
2017-08-05 21:30:44 +02:00
Rodrigo Ramírez Norambuena
0ba125c2d7 Disabled tests of vendor_spec:
Sometimes these getting failed in Travis.
2017-08-05 02:40:03 -04:00
Rodrigo Ramírez Norambuena
6abd120a5c Add CHANGELOG entry for color in warning if full ip whitelist 2017-08-04 22:39:52 -04:00
Rodrigo Ramírez Norambuena
5cf7e89ce6 Merge remote-tracking branch 'roramirez_github/develop' into add-warning-color-full-ip 2017-08-04 22:38:31 -04:00
Cato Antonsen
353786cb61 Fix this.file path 2017-08-03 21:34:23 +02:00
Michael Teeuw
586beea21e Merge pull request #977 from roramirez/use-before-after-vendors
Use before after vendors
2017-08-02 12:07:40 +02:00
Rodrigo Ramírez Norambuena
b80454a1f4 Added log text DEPRECATED for old method of authentication 2017-07-31 17:18:34 -04:00
Rodrigo Ramírez Norambuena
19f80cf506 Add entry in Changelog for change hooks in vendors_spec 2017-07-31 16:58:33 -04:00
Rodrigo Ramírez Norambuena
d01100bb15 Merge remote-tracking branch 'roramirez_github/develop' into use-before-after-vendors 2017-07-31 16:57:24 -04:00
Bas van Wetten
e0414e4eb9 Add unittest for calendar module
Add unittest for 'getLocalSpecification' function.
2017-07-31 22:36:14 +02:00
Michael Teeuw
1eb10e3c22 Merge pull request #971 from roramirez/set-title-magicmirror-2
Set title on MagicMirror² for index.html
2017-07-31 15:04:54 +02:00
Michael Teeuw
4772fbcd4a Merge pull request #970 from QNimbus/unittest-calendar
Add new unit tests
2017-07-31 15:04:25 +02:00
Michael Teeuw
18b61e35be Merge branch 'develop' into unittest-calendar 2017-07-31 15:04:16 +02:00
Michael Teeuw
bb7faf0fb3 Merge pull request #967 from roramirez/show-test-build-npm-dependencies
Debug npm list in CI
2017-07-31 15:03:25 +02:00
Michael Teeuw
1603742adc Merge branch 'develop' into show-test-build-npm-dependencies 2017-07-31 15:03:20 +02:00
Michael Teeuw
8a830e40bb Merge pull request #966 from roramirez/format-changelog
Fix litles changes of format in the Changelog
2017-07-31 15:02:43 +02:00
Michael Teeuw
d8adcf5a84 Merge branch 'develop' into format-changelog 2017-07-31 15:02:36 +02:00
Michael Teeuw
1d9a404f77 Merge pull request #965 from roramirez/newfeed-unit
Newfeed unit
2017-07-31 15:00:37 +02:00
Michael Teeuw
26dcaf6078 Merge pull request #962 from QNimbus/fix-issue-961
Fix calendar.js bug
2017-07-31 15:00:15 +02:00
Michael Teeuw
a91e4014bf Merge pull request #959 from roramirez/include-node-8
Include node 8 testsuite and CI
2017-07-31 14:59:34 +02:00
Rodrigo Ramírez Norambuena
06af327e5e Added deprecation warning for authentication of the calendar module.
Discussed in Review
9848f80630 (r105531731)
2017-07-30 22:56:27 -04:00
Bas van Wetten
35e3b889c3 Add new unit tests
Add new unit tests for 'shorten' function in calendar module
2017-07-29 16:02:53 +02:00
Bas van Wetten
5ef6ba0258 Small edit of CHANGELOG
Added a period at the end of the CHANGELOG entries
2017-07-29 11:44:43 +02:00
Bas van Wetten
12754ff135 Updated changelog for calendar fix
Updated changelog for calendar fix
2017-07-28 22:19:25 +02:00
Bas van Wetten
d09a1e254f Merge branch 'fix-issue-963' into fix-issue-961 2017-07-28 21:34:58 +02:00
Bas van Wetten
b89ee67daf Merge branch 'fix-issue-961' into fix-issue-963 2017-07-28 21:33:10 +02:00
Bas van Wetten
7bd256c311 Fix calendar.js bug issue #963
Fixed calendar specific configuration settings maximumEntries and maximumNumberOfDays not overriding global setting
2017-07-28 21:07:38 +02:00
Bas van Wetten
4add7cd0b3 Fix calendar.js bug
Fix bug where excludedEvents count towards maximumEntries displayed
2017-07-28 17:47:22 +02:00
Rodrigo Ramírez Norambuena
5ac20cc4cf SuiteTest: Added unit tests for js/class.js 2017-07-25 21:42:51 -04:00
Rodrigo Ramírez Norambuena
9d7b0487d5 Change hooks for vendor_spec:
Use the hooks before and after in the vendor_spec instead of use beforeAll and
afterAll in the e2e test to prevent failure in CI.
2017-07-25 20:24:04 -04:00
Rodrigo Ramírez Norambuena
59aa84f6c8 Add log when clientonly failed on starting. 2017-07-25 17:52:44 -04:00
Rodrigo Ramírez Norambuena
765b03c868 Add warning color when are using full ip whitelist 2017-07-25 11:26:01 -04:00
Rodrigo Ramírez Norambuena
41ce3db8f9 Set title on MagicMirror² for index.html 2017-07-25 11:00:38 -04:00
Rodrigo Ramírez Norambuena
00e3ef757c Merge remote-tracking branch 'roramirez_github/develop' into showWeek-test-es-language 2017-07-25 10:53:50 -04:00
Rodrigo Ramírez Norambuena
84dc0b2959 Set version spectron for 3.6.x 2017-07-25 10:28:45 -04:00
Rodrigo Ramírez Norambuena
2e48099070 Debug npm list in CI
Execute npm list after the tests in Travis
2017-07-25 10:07:32 -04:00
Rodrigo Ramírez Norambuena
77779bbcd9 Fix litles changes of format in the Changelog 2017-07-25 09:50:51 -04:00
Rodrigo Ramírez Norambuena
e08bc01c33 Fix conflict with test function newsfeed 2017-07-25 09:32:32 -04:00
Michael Teeuw
bf24ee369f Merge pull request #957 from QNimbus/develop
Addition to .gitignore to ignore VS Code folder
2017-07-25 14:50:00 +02:00
Michael Teeuw
876f12db89 Merge pull request #955 from roramirez/close-code-tag-README-modules
Close code tag and fix format for Modules Readme
2017-07-25 14:49:42 +02:00
Michael Teeuw
8b84459e13 Merge pull request #953 from roramirez/activate-test-e2e
Activate e2e test in Travis and desactivate failed test in CI:
2017-07-25 14:49:25 +02:00
Rodrigo Ramírez Norambuena
dccfcc9663 Merge pull request #2 from QNimbus/activate-test-e2e
Change suggestion for e2e testing
2017-07-24 22:38:32 -04:00
Bas van Wetten
203e1cc9b9 Implemented requested change PR #2
Moved tests/e2e_new to tests/e2e folder
2017-07-24 22:08:12 +02:00
Bas van Wetten
b612f0cdec PR for issue #956
Changed .gitignore to ignore Visual Studio Code project folder with custom launch configuration. (See issue #956)
2017-07-24 21:56:53 +02:00
Rodrigo Ramírez Norambuena
961301fbec Merge remote-tracking branch 'roramirez_github/develop' into newfeed-unit 2017-07-24 11:36:16 -04:00
Rodrigo Ramírez Norambuena
2a38d99cf1 Merge remote-tracking branch 'roramirez_github/develop' into include-node-8 2017-07-24 11:34:47 -04:00
Rodrigo Ramírez Norambuena
7903328c2d Add Node 8 for testing 2017-07-23 20:49:52 -04:00
Rodrigo Ramírez Norambuena
56d2b4a80c Close code tag and fix format for Modules Readme 2017-07-23 20:31:26 -04:00
Ricardo Gonzalez
2c6ecaab5b Add ability for currentweather module to display indoor humidity via INDOOR_HUMIDITY notification 2017-07-23 23:55:32 +01:00
Ricardo Gonzalez
45d289a65e Merge branch 'develop' of github.com:ryck/MagicMirror into develop
* 'develop' of github.com:ryck/MagicMirror:
  Add template for v2.1.3
  Set dev version.
2017-07-23 23:52:10 +01:00
Bas van Wetten
318c8c68b0 Change suggestion for e2e testing
- Changed global-setup.js to allow for easier test creation
- Changed each e2e test suite to work with new global-setup.js
- All tests (except for dev_console.js) now work with Travis CI
2017-07-23 23:06:27 +02:00
Michael Teeuw
fbd47a7f3b Merge pull request #951 from QNimbus/fix-issue-950
Fix for issue #950
2017-07-20 10:12:45 +02:00
Rodrigo Ramírez Norambuena
07533f5658 Activate e2e test in Travis and desactivate failed test in CI:
- dev_console
 - vendor_spec
2017-07-20 00:34:20 -04:00
Rodrigo Ramírez Norambuena
66b7e3e1f5 Fix lint newsfeed_spec 2017-07-20 00:27:57 -04:00
Rodrigo Ramírez Norambuena
4fee4d1903 Add Changelog Unit test for capitalizeFirstLetter newfeed module 2017-07-20 00:10:01 -04:00
Rodrigo Ramírez Norambuena
90d70beea2 Merge remote-tracking branch 'roramirez_github/develop' into newfeed-unit 2017-07-20 00:09:05 -04:00
Unknown
a7297d2685 Fix for issue #950
Changed 'server.js' to allow an empty ipwhitelist to allow any and all hosts instead of none as mentioned in the documentation
2017-07-18 14:07:18 +02:00
Michael Teeuw
86ae704e86 Merge pull request #924 from QNimbus/client-only-pr
Added clientonly script
2017-07-12 11:08:04 +02:00
Michael Teeuw
2d1e993fe1 Merge branch 'develop' into client-only-pr 2017-07-12 11:07:49 +02:00
Michael Teeuw
04b550e435 Update correct version. 2017-07-12 10:58:28 +02:00
Michael Teeuw
c492ea77f1 Merge pull request #943 from QNimbus/fix-issue-940
Fix issue #940
2017-07-12 10:55:43 +02:00
Michael Teeuw
61d9112ba7 Merge pull request #941 from QNimbus/fix-issue-933
Fix issue #933
2017-07-12 10:55:23 +02:00
Michael Teeuw
d7fe36de71 Merge pull request #934 from eouia/develop
add symbol and color on broadcasted events
2017-07-12 10:54:59 +02:00
Unknown
db0bd3fa2d Fix issue #940
Fix for issue 940 - time was incorrectly displayed in a 12-hour fashion regardless of the 24 hour clock preference in config.js
2017-07-09 11:46:59 +02:00
Unknown
551619e772 Fix issue #933
This is a fix for issue 933 which restores the original alligment of the analog clock; the analog clock still does not properly align to the left of the left sidebar when content of other left sidebar modules is too wide.
2017-07-08 21:31:05 +02:00
eouia
29bae230a4 Update CHANGELOG.md 2017-07-06 16:09:49 +02:00
eouia
83be49156f symbol and color for broadcasted events (calendar)
- Add symbol and color properties of event when `CALENDAR_EVENTS` notification is broadcasted from `defaultcalendar` module.
2017-07-06 16:09:16 +02:00
eouia
561ae102fb add symbol and color on broadcasted events 2017-07-06 11:57:16 +02:00
Unknown
a05e69b855 Removed cookie dependencies
Removed module import and dependency on the 'cookie' library; it's not used anymore
2017-07-02 12:10:16 +02:00
Unknown
8eb772d80b Allow use of env variables
Made some changes that allows the use of environment variables when starting the standalone client.
2017-07-02 12:10:16 +02:00
Unknown
1590693547 New server route to fetch config
Added a new route to the Express server to supply client with config. Removed the original 'cookie' hack
2017-07-02 12:10:16 +02:00
Unknown
66f93ee541 Added clientonly script
Added clientonly script to have server and client run at different locations
2017-07-02 12:10:16 +02:00
Michael Teeuw
8893df118e Add template for v2.1.3 2017-07-01 20:36:17 +02:00
Michael Teeuw
2c77cb5ca5 Set dev version. 2017-07-01 20:35:11 +02:00
Rodrigo Ramírez Norambuena
947c2e556d Add test e2e showWeek feature in spanish language. 2017-04-09 15:32:15 -03:00
Rodrigo Ramírez Norambuena
f974fd0660 Add roundValue unit test function weatherforecast module:
- tests for this.config.roundTemp is false
    - tests for this.config.roundTemp is true
2017-03-29 00:29:47 -03:00
Rodrigo Ramírez Norambuena
af9fdfa224 Add roundValue unit test function currentweather module:
- tests for this.config.roundTemp is false
2017-03-28 22:15:48 -03:00
Rodrigo Ramírez Norambuena
181cb235df Unit test currentweather module:
Add roundValue unit test function currentweather module
	tests for this.config.roundTemp is true
2017-03-28 10:05:08 -03:00
Rodrigo Ramírez Norambuena
60c5d96037 fix documentation currentweather and weatherforecast function
roundValue:

This function toFixed return a string type not a number value.
2017-03-27 12:18:36 -03:00
Rodrigo Ramírez Norambuena
daad8bca69 Add test e2e helloworld module with default config text. 2017-03-26 17:36:45 -03:00
Rodrigo Ramírez Norambuena
0117cd478b Unit test for capitalizeFirstLetter newfeed module 2017-03-26 16:19:45 -03:00
181 changed files with 13660 additions and 1369 deletions

View File

@@ -5,12 +5,18 @@
"max-len": ["error", 250],
"curly": "error",
"camelcase": ["error", {"properties": "never"}],
"no-trailing-spaces": ["error"],
"no-trailing-spaces": ["error", {"ignoreComments": false }],
"no-irregular-whitespace": ["error"]
},
"env": {
"browser": true,
"node": true,
"es6": true
}
},
"parserOptions": {
"sourceType": "module",
"ecmaFeatures": {
"globalReturn": true
}
}
}

6
.gitignore vendored
View File

@@ -16,6 +16,12 @@ jspm_modules
.npm
.node_repl_history
# Visual Studio Code ignoramuses.
.vscode/
# IDE Code ignoramuses.
.idea/
# Various Windows ignoramuses.
Thumbs.db
ehthumbs.db

View File

@@ -1,9 +1,8 @@
language: node_js
node_js:
- "7"
- "6"
- "5.1"
before_script:
- yarn danger ci
- npm install grunt-cli -g
- "export DISPLAY=:99.0"
- "sh -e /etc/init.d/xvfb start"
@@ -11,6 +10,9 @@ before_script:
script:
- grunt
- npm run test:unit
- npm run test:e2e
after_script:
- npm list
cache:
directories:
- node_modules

View File

@@ -1,7 +1,206 @@
# MagicMirror² Change Log
All notable changes to this project will be documented in this file.
This project adheres to [Semantic Versioning](http://semver.org/).
---
## [2.5.0] - 2018-10-01
### Added
- Support multi-line compliments
- Simplified Chinese translation for "Feels"
- Polish translate for "Feels"
- French translate for "Feels"
- Translations for newsfeed module
- Support for toggling news article in fullscreen
- Hungarian translation for "Feels" and "Week"
- Spanish translation for "Feels"
- Add classes instead of inline style to the message from the module Alert
- Support for events having a duration instead of an end
- Support for showing end of events through config parameters showEnd and dateEndFormat
### Fixed
- Fixed gzip encoded calendar loading issue #1400.
- Mixup between german and spanish translation for newsfeed.
- Fixed close dates to be absolute, if no configured in the config.js - module Calendar
- Fixed the UpdateNotification module message about new commits in the repository, so they can be correctly localized in singular and plural form.
- Fix for weatherforecast rainfall rounding [#1374](https://github.com/MichMich/MagicMirror/issues/1374)
- Fix calendar parsing issue for Midori on RasperryPi Zero w, related to issue #694.
- Fix weather city ID link in sample config
- Fixed issue with clientonly not updating with IP address and port provided on command line.
### Updated
- Updated Simplified Chinese translation
- Swedish translations
- Hungarian translations for the updatenotification module
- Updated Norsk bokmål translation
- Updated Norsk nynorsk translation
- Consider multi days event as full day events
## [2.4.1] - 2018-07-04
### Fixed
- Fix weather parsing issue #1332.
## [2.4.0] - 2018-07-01
⚠️ **Warning:** This release includes an updated version of Electron. This requires a Raspberry Pi configuration change to allow the best performance and prevent the CPU from overheating. Please read the information on the [MagicMirror Wiki](https://github.com/michmich/magicmirror/wiki/configuring-the-raspberry-pi#enable-the-open-gl-driver-to-decrease-electrons-cpu-usage).
**Note:** This update uses new dependencies. Please update using the following command: `git pull && npm install`
### Added
- Enabled translation of feelsLike for module currentweather
- Added support for on-going calendar events
- Added scroll up in fullscreen newsfeed article view
- Changed fullscreen newsfeed width from 100% to 100vw (better results)
- Added option to calendar module that colors only the symbol instead of the whole line
- Added option for new display format in the calendar module with date headers with times/events below.
- Ability to fetch compliments from a remote server
- Add regex filtering to calendar module
- Customize classes for table
- Added option to newsfeed module to only log error parsing a news article if enabled
- Add update translations for Português Brasileiro
### Changed
- Upgrade to Electron 2.0.0.
- Remove yarn-or-npm which breaks production builds.
- Invoke module suspend even if no dom content. [#1308](https://github.com/MichMich/MagicMirror/issues/1308)
### Fixed
- Fixed issue where wind chill could not be displayed in Fahrenheit. [#1247](https://github.com/MichMich/MagicMirror/issues/1247)
- Fixed issues where a module crashes when it tries to dismiss a non existing alert. [#1240](https://github.com/MichMich/MagicMirror/issues/1240)
- In default module currentWeather/currentWeather.js line 296, 300, self.config.animationSpeed can not be found because the notificationReceived function does not have "self" variable.
- Fixed browser-side code to work on the Midori browser.
- Fixed issue where heat index was reporting incorrect values in Celsius and Fahrenheit. [#1263](https://github.com/MichMich/MagicMirror/issues/1263)
- Fixed weatherforecast to use dt_txt field instead of dt to handle timezones better
- Newsfeed now remembers to show the description when `"ARTICLE_LESS_DETAILS"` is called if the user wants to always show the description. [#1282](https://github.com/MichMich/MagicMirror/issues/1282)
- `clientonly/*.js` is now linted, and one linting error is fixed
- Fix issue #1196 by changing underscore to hyphen in locale id, in align with momentjs.
- Fixed issue where heat index and wind chill were reporting incorrect values in Kelvin. [#1263](https://github.com/MichMich/MagicMirror/issues/1263)
### Updated
- Updated Italian translation
- Updated German translation
- Updated Dutch translation
## [2.3.1] - 2018-04-01
### Fixed
- Downgrade electron to 1.4.15 to solve the black screen issue.[#1243](https://github.com/MichMich/MagicMirror/issues/1243)
## [2.3.0] - 2018-04-01
### Added
- Add new settings in compliments module: setting time intervals for morning and afternoon
- Add system notification `MODULE_DOM_CREATED` for notifying each module when their Dom has been fully loaded.
- Add types for module.
- Implement Danger.js to notify contributors when CHANGELOG.md is missing in PR.
- Allow to scroll in full page article view of default newsfeed module with gesture events from [MMM-Gestures](https://github.com/thobach/MMM-Gestures)
- Changed 'compliments.js' - update DOM if remote compliments are loaded instead of waiting one updateInterval to show custom compliments
- Automated unit tests utils, deprecated, translator, cloneObject(lockstrings)
- Automated integration tests translations
- Add advanced filtering to the excludedEvents configuration of the default calendar module
- New currentweather module config option: `showFeelsLike`: Shows how it actually feels like. (wind chill or heat index)
- New currentweather module config option: `useKMPHwind`: adds an option to see wind speed in Kmph instead of just m/s or Beaufort.
- Add dc:date to parsing in newsfeed module, which allows parsing of more rss feeds.
### Changed
- Add link to GitHub repository which contains the respective Dockerfile.
- Optimized automated unit tests cloneObject, cmpVersions
- Update notifications use now translation templates instead of normal strings.
- Yarn can be used now as an installation tool
- Changed Electron dependency to v1.7.13.
### Fixed
- News article in fullscreen (iframe) is now shown in front of modules.
- Forecast respects maxNumberOfDays regardless of endpoint.
- Fix exception on translation of objects.
## [2.2.2] - 2018-01-02
### Added
- Add missing `package-lock.json`.
### Changed
- Changed Electron dependency to v1.7.10.
## [2.2.1] - 2018-01-01
### Fixed
- Fixed linting errors.
## [2.2.0] - 2018-01-01
**Note:** This update uses new dependencies. Please update using the following command: `git pull && npm install`
### Changed
- Calender week is now handled with a variable translation in order to move number language specific.
- Reverted the Electron dependency back to 1.4.15 since newer version don't seem to work on the Raspberry Pi very well.
### Added
- Add option to use [Nunjucks](https://mozilla.github.io/nunjucks/) templates in modules. (See `helloworld` module as an example.)
- Add Bulgarian translations for MagicMirror² and Alert module.
- Add graceful shutdown of modules by calling `stop` function of each `node_helper` on SIGINT before exiting.
- Link update subtext to Github diff of current version versus tracking branch.
- Add Catalan translation.
- Add ability to filter out newsfeed items based on prohibited words found in title (resolves #1071)
- Add options to truncate description support of a feed in newsfeed module
- Add reloadInterval option for particular feed in newsfeed module
- Add no-cache entries of HTTP headers in newsfeed module (fetcher)
- Add Czech translation.
- Add option for decimal symbols other than the decimal point for temperature values in both default weather modules: WeatherForecast and CurrentWeather.
### Fixed
- Fixed issue with calendar module showing more than `maximumEntries` allows
- WeatherForecast and CurrentWeather are now using HTTPS instead of HTTP
- Correcting translation for Indonesian language
- Fix issue where calendar icons wouldn't align correctly
## [2.1.3] - 2017-10-01
**Note:** This update uses new dependencies. Please update using the following command: `git pull && npm install`
### Changed
- Remove Roboto fonts files inside `fonts` and these are installed by npm install command.
### Added
- Add `clientonly` script to start only the electron client for a remote server.
- Add symbol and color properties of event when `CALENDAR_EVENTS` notification is broadcasted from `default/calendar` module.
- Add `.vscode/` folder to `.gitignore` to keep custom Visual Studio Code config out of git.
- Add unit test the capitalizeFirstLetter function of newfeed module.
- Add new unit tests for function `shorten` in calendar module.
- Add new unit tests for function `getLocaleSpecification` in calendar module.
- Add unit test for js/class.js.
- Add unit tests for function `roundValue` in currentweather module.
- Add test e2e showWeek feature in spanish language.
- Add warning Log when is used old authentication method in the calendar module.
- Add test e2e for helloworld module with default config text.
- Add ability for `currentweather` module to display indoor humidity via INDOOR_HUMIDITY notification.
- Add Welsh (Cymraeg) translation.
- Add Slack badge to Readme.
### Updated
- Changed 'default.js' - listen on all attached interfaces by default.
- Add execution of `npm list` after the test are ran in Travis CI.
- Change hooks for the vendors e2e tests.
- Add log when clientonly failed on starting.
- Add warning color when are using full ip whitelist.
- Set version of the `express-ipfilter` on 0.3.1.
### Fixed
- Fixed issue with incorrect allignment of analog clock when displayed in the center column of the MM.
- Fixed ipWhitelist behaviour to make empty whitelist ([]) allow any and all hosts access to the MM.
- Fixed issue with calendar module where 'excludedEvents' count towards 'maximumEntries'.
- Fixed issue with calendar module where global configuration of maximumEntries was not overridden by calendar specific config (see module doc).
- Fixed issue where `this.file(filename)` returns a path with two hashes.
- Workaround for the WeatherForecast API limitation.
## [2.1.2] - 2017-07-01
### Changed
@@ -30,7 +229,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
### Updated
- Added missing keys to Polish translation.
- Added missing key to German translation.
- Added better translation with flexible word order to Finnish translation
- Added better translation with flexible word order to Finnish translation.
### Fixed
- Fix instruction in README for using automatically installer script.
@@ -38,8 +237,8 @@ This project adheres to [Semantic Versioning](http://semver.org/).
- Fix double message about port when server is starting
- Corrected Swedish translations for TODAY/TOMORROW/DAYAFTERTOMORROW.
- Removed unused import from js/electron.js
- Made calendar.js respect config.timeFormat irrespecive of locale setting
- Fixed alignment of analog clock when a large calendar is displayed in the same side bar
- Made calendar.js respect config.timeFormat irrespecive of locale setting.
- Fixed alignment of analog clock when a large calendar is displayed in the same side bar.
## [2.1.1] - 2017-04-01
@@ -47,18 +246,18 @@ This project adheres to [Semantic Versioning](http://semver.org/).
### Changed
- Add `anytime` group for Compliments module.
- Compliments module can use remoteFile without default daytime arrays defined
- Compliments module can use remoteFile without default daytime arrays defined.
- Installer: Use init config.js from config.js.sample.
- Switched out `rrule` package for `rrule-alt` and fixes in `ical.js` in order to fix calendar issues. ([#565](https://github.com/MichMich/MagicMirror/issues/565))
- Make mouse events pass through the region fullscreen_above to modules below.
- Scaled the splash screen down to make it a bit more subtle.
- Replace HTML tables with markdown tables in README files.
- Added `DAYAFTERTOMORROW`, `UPDATE_NOTIFICATION` and `UPDATE_NOTIFICATION_MODULE` to Finnish translations.
- Run `npm test` on Travis automatically
- Run `npm test` on Travis automatically.
- Show the splash screen image even when is reboot or halted.
- Added some missing translaton strings in the sv.json file.
- Run task jsonlint to check translation files.
- Restructured Test Suite
- Restructured Test Suite.
### Added
- Added Docker support (Pull Request [#673](https://github.com/MichMich/MagicMirror/pull/673)).

View File

@@ -11,6 +11,7 @@ module.exports = function(grunt) {
"modules/default/*.js",
"modules/default/*/*.js",
"serveronly/*.js",
"clientonly/*.js",
"*.js",
"tests/**/*.js",
"!modules/default/alert/notificationFx.js",

183
README.md
View File

@@ -7,6 +7,7 @@
<a href="http://choosealicense.com/licenses/mit"><img src="https://img.shields.io/badge/license-MIT-blue.svg" alt="License"></a>
<a href="https://travis-ci.org/MichMich/MagicMirror"><img src="https://travis-ci.org/MichMich/MagicMirror.svg" alt="Travis"></a>
<a href="https://snyk.io/test/github/MichMich/MagicMirror"><img src="https://snyk.io/test/github/MichMich/MagicMirror/badge.svg" alt="Known Vulnerabilities" data-canonical-src="https://snyk.io/test/github/MichMich/MagicMirror" style="max-width:100%;"></a>
<a href="http://slack.magicmirror.builders"><img src="http://slack.magicmirror.builders:3000/badge.svg" alt="Slack Status"></a>
</p>
**MagicMirror²** is an open source modular smart mirror platform. With a growing list of installable modules, the **MagicMirror²** allows you to convert your hallway or bathroom mirror into your personal assistant. **MagicMirror²** is built by the creator of [the original MagicMirror](http://michaelteeuw.nl/tagged/magicmirror) with the incredible help of a [growing community of contributors](https://github.com/MichMich/MagicMirror/graphs/contributors).
@@ -15,109 +16,125 @@ MagicMirror² focuses on a modular plugin system and uses [Electron](http://elec
## Table Of Contents
- [Usage](#usage)
- [Installation](#installation)
- [Raspberry Pi](#raspberry-pi)
- [General](#general)
- [Server Only](#server-only)
- [Client Only](#client-only)
- [Docker](#docker)
- [Configuration](#configuration)
- [Modules](#modules)
- [Updating](#updating)
- [Known Issues](#known-issues)
- [Community](#community)
- [Contributing Guidelines](#contributing-guidelines)
- [Manifesto](#manifesto)
## Usage
## Installation
### Raspberry Pi Support
Electron, the app wrapper around MagicMirror², only supports the Raspberry Pi 2 & 3. The Raspberry Pi 1 is currently **not** supported. If you want to run this on a Raspberry Pi 1, use the [server only](#server-only) feature and setup a fullscreen browser yourself.
### Raspberry Pi
### Automatic Installer (Raspberry Pi Only!)
#### Automatic Installation (Raspberry Pi only!)
*Electron*, the app wrapper around MagicMirror², only supports the Raspberry Pi 2/3. The Raspberry Pi 0/1 is currently **not** supported. If you want to run this on a Raspberry Pi 1, use the [server only](#server-only) feature and setup a fullscreen browser yourself. (Yes, people have managed to run MM² also on a Pi0, so if you insist, search in the forums.)
Note that you will need to install the lastest full version of Raspbian, **don't use the Lite version**.
Execute the following command on your Raspberry Pi to install MagicMirror²:
````
```bash
bash -c "$(curl -sL https://raw.githubusercontent.com/MichMich/MagicMirror/master/installers/raspberry.sh)"
````
```
### Manual Installation
#### Manual Installation
1. Download and install the latest Node.js version.
1. Download and install the latest *Node.js* version:
- `curl -sL https://deb.nodesource.com/setup_10.x | sudo -E bash -`
- `sudo apt install -y nodejs`
2. Clone the repository and check out the master branch: `git clone https://github.com/MichMich/MagicMirror`
3. Enter the repository: `cd ~/MagicMirror`
4. Install and run the app: `npm install && npm start`
3. Enter the repository: `cd MagicMirror/`
4. Install and run the app with: `npm install && npm start` \
For **Server Only** use: `npm install && node serveronly` .
**Important:** `npm start` does **not** work via SSH, use `DISPLAY=:0 nohup npm start &` instead. This starts the mirror on the remote display.
**Note:** if you want to debug on Raspberry Pi you can use `npm start dev` which will start the MagicMirror app with Dev Tools enabled.
**:warning: Important!**
- **The installation step for `npm install` will take a very long time**, often with little or no terminal response! \
For the RPi3 this is **~10** minutes and for the Rpi2 **~25** minutes. \
Do not interrupt or you risk getting a :broken_heart: by Raspberry Jam.
Also note that:
- `npm start` does **not** work via SSH. But you can use `DISPLAY=:0 nohup npm start &` instead. \
This starts the mirror on the remote display.
- If you want to debug on Raspberry Pi you can use `npm start dev` which will start MM with *Dev Tools* enabled.
- To access toolbar menu when in mirror mode, hit `ALT` key.
- To toggle the (web) `Developer Tools` from mirror mode, use `CTRL-SHIFT-I` or `ALT` and select `View`.
### Server Only
In some cases, you want to start the application without an actual app window. In this case, you can start MagicMirror² in server only mode by manually running `node serveronly` or using Docker. This will start the server, after which you can open the application in your browser of choice. Detailed description below.
#### Docker
**Important:** Make sure that you whitelist the interface/ip (`ipWhitelist`) in the server config where you want the client to connect to, otherwise it will not be allowed to connect to the server. You also need to set the local host `address` field to `0.0.0.0` in order for the RPi to listen on all interfaces and not only `localhost` (default).
```javascript
var config = {
address: "0.0.0.0", // default is "localhost"
port: 8080, // default
ipWhitelist: ["127.0.0.1", "::ffff:127.0.0.1", "::1", "::ffff:172.17.0.1"], // default -- need to add your IP here
...
};
```
### Client Only
This is when you already have a server running remotely and want your RPi to connect as a standalone client to this instance, to show the MM from the server. Then from your RPi, you run it with: `node clientonly --address 192.168.1.5 --port 8080`. (Specify the ip address and port number of the server)
### Docker
MagicMirror² in server only mode can be deployed using [Docker](https://docker.com). After a successful [Docker installation](https://docs.docker.com/engine/installation/) you just need to execute the following command in the shell:
```bash
docker run -d \
--publish 80:8080 \
--restart always \
--volume ~/magic_mirror/config:/opt/magic_mirror/config \
--volume ~/magic_mirror/modules:/opt/magic_mirror/modules \
--name magic_mirror \
bastilimbach/docker-magicmirror
--publish 80:8080 \
--restart always \
--volume ~/magic_mirror/config:/opt/magic_mirror/config \
--volume ~/magic_mirror/modules:/opt/magic_mirror/modules \
--name magic_mirror \
bastilimbach/docker-magicmirror
```
To get more information about the available Dockerfile versions and configurations head over to the respective [GitHub repository](https://github.com/bastilimbach/docker-MagicMirror).
| **Volumes** | **Description** |
| --- | --- |
| `/opt/magic_mirror/config` | Mount this volume to insert your own config into the docker container. |
| `/opt/magic_mirror/modules` | Mount this volume to add your own custom modules into the docker container. |
You may need to add your Docker Host IP to your `ipWhitelist` option. If you have some issues setting up this configuration, check [this forum post](https://forum.magicmirror.builders/topic/1326/ipwhitelist-howto).
```javascript
var config = {
ipWhitelist: ["127.0.0.1", "::ffff:127.0.0.1", "::1", "::ffff:172.17.0.1"]
};
```
If you want to run the server on a raspberry pi, use the `raspberry` tag. (bastilimbach/docker-magicmirror:raspberry)
#### Manual
1. Download and install the latest Node.js version.
2. Clone the repository and check out the master branch: `git clone https://github.com/MichMich/MagicMirror`
3. Enter the repository: `cd ~/MagicMirror`
4. Install and run the app: `npm install && node serveronly`
### Raspberry Configuration & Auto Start.
The following wiki links are helpful in the configuration of your MagicMirror² operating system:
- [Configuring the Raspberry Pi](https://github.com/MichMich/MagicMirror/wiki/Configuring-the-Raspberry-Pi)
- [Auto Starting MagicMirror](https://github.com/MichMich/MagicMirror/wiki/Auto-Starting-MagicMirror)
### Updating your MagicMirror²
If you want to update your MagicMirror² to the latest version, use your terminal to go to your Magic Mirror folder and type the following command:
```bash
git pull && npm install
```
If you changed nothing more than the config or the modules, this should work without any problems.
Type `git status` to see your changes, if there are any, you can reset them with `git reset --hard`. After that, git pull should be possible.
## Configuration
1. Duplicate `config/config.js.sample` to `config/config.js`. **Note:** If you used the installer script. This step is already done for you.
2. Modify your required settings.
### Raspberry Specific
The following wiki links are helpful for the initial configuration of your MagicMirror² operating system:
- [Configuring the Raspberry Pi](https://github.com/MichMich/MagicMirror/wiki/Configuring-the-Raspberry-Pi)
- [Auto Starting MagicMirror](https://github.com/MichMich/MagicMirror/wiki/Auto-Starting-MagicMirror)
### General
1. Copy `/home/pi/MagicMirror/config/config.js.sample` to `/home/pi/MagicMirror/config/config.js`. \
**Note:** If you used the installer script. This step is already done for you.
2. Modify your required settings. \
Note: You'll can check your configuration running `npm run config:check` in `/home/pi/MagicMirror`.
Note: You'll can check your configuration running the follow command:
```bash
npm run config:check
```
The following properties can be configured:
| **Option** | **Description** |
| --- | --- |
| `port` | The port on which the MagicMirror² server will run on. The default value is `8080`. |
| `address` | The ip address the accept connections. The default open bind `::` is IPv6 is available or `0.0.0.0` IPv4 run on. Example config: `192.168.10.100`. |
| `ipWhitelist` | The list of IPs from which you are allowed to access the MagicMirror². The default value is `["127.0.0.1", "::ffff:127.0.0.1", "::1"]`. It is possible to specify IPs with subnet masks (`["127.0.0.1", "127.0.0.1/24"]`) or define ip ranges (`["127.0.0.1", ["192.168.0.1", "192.168.0.100"]]`). Set `[]` to allow all IP addresses. For more information about how configure this directive see the [follow post ipWhitelist HowTo](https://forum.magicmirror.builders/topic/1326/ipwhitelist-howto) |
| `address` | The *interface* ip address on which to accept connections. The default is `localhost`, which would prevent exposing the built-in webserver to machines on the local network. To expose it to other machines, use: `0.0.0.0`. |
| `ipWhitelist` | The list of IPs from which you are allowed to access the MagicMirror². The default value is `["127.0.0.1", "::ffff:127.0.0.1", "::1"]`, which is from `localhost` only. Add your IP when needed. You can also specify IP ranges with subnet masks (`["127.0.0.1", "127.0.0.1/24"]`) or directly with (`["127.0.0.1", ["192.168.0.1", "192.168.0.100"]]`). Set `[]` to allow all IP addresses. For more information see: [follow post ipWhitelist HowTo](https://forum.magicmirror.builders/topic/1326/ipwhitelist-howto) |
| `zoom` | This allows to scale the mirror contents with a given zoom factor. The default value is `1.0`|
| `language` | The language of the interface. (Note: Not all elements will be localized.) Possible values are `en`, `nl`, `ru`, `fr`, etc., but the default value is `en`. |
| `timeFormat` | The form of time notation that will be used. Possible values are `12` or `24`. The default is `24`. |
@@ -131,7 +148,7 @@ Module configuration:
| **Option** | **Description** |
| --- | --- |
| `module` | The name of the module. This can also contain the subfolder. Valid examples include `clock`, `default/calendar` and `custommodules/mymodule`. |
| `position` | The location of the module in which the module will be loaded. Possible values are `top_ bar`, `top_left`, `top_center`, `top_right`, `upper_third`, `middle_center`, `lower_third`, `bottom_left`, `bottom_center`, `bottom_right`, `bottom_bar`, `fullscreen_above`, and `fullscreen_below`. This field is optional but most modules require this field to set. Check the documentation of the module for more information. Multiple modules with the same position will be ordered based on the order in the configuration file. |
| `position` | The location of the module in which the module will be loaded. Possible values are `top_bar`, `top_left`, `top_center`, `top_right`, `upper_third`, `middle_center`, `lower_third`, `bottom_left`, `bottom_center`, `bottom_right`, `bottom_bar`, `fullscreen_above`, and `fullscreen_below`. This field is optional but most modules require this field to set. Check the documentation of the module for more information. Multiple modules with the same position will be ordered based on the order in the configuration file. |
| `classes` | Additional classes which are passed to the module. The field is optional. |
| `header` | To display a header text above the module, add the header property. This field is optional. |
| `disabled` | Set disabled to `true` to skip creating the module. This field is optional. |
@@ -150,12 +167,20 @@ The following modules are installed by default.
- [**Hello World**](modules/default/helloworld)
- [**Alert**](modules/default/alert)
For more available modules, check out out the wiki page: [MagicMirror² Modules](https://github.com/MichMich/MagicMirror/wiki/MagicMirror²-Modules). If you want to build your own modules, check out the [MagicMirror² Module Development Documentation](modules) and don't forget to add it to the wiki and the [forum](https://forum.magicmirror.builders/category/7/showcase)!
For more available modules, check out out the wiki page [MagicMirror² 3rd Party Modules](https://github.com/MichMich/MagicMirror/wiki/3rd-party-modules). If you want to build your own modules, check out the [MagicMirror² Module Development Documentation](modules) and don't forget to add it to the wiki and the [forum](https://forum.magicmirror.builders/category/7/showcase)!
## Known issues
- Electron seems to have some issues on certain Raspberry Pi 2's. See [#145](https://github.com/MichMich/MagicMirror/issues/145).
- MagicMirror² (Electron) sometimes quits without an error after an extended period of use. See [#150](https://github.com/MichMich/MagicMirror/issues/150).
## Updating
If you want to update your MagicMirror² to the latest version, use your terminal to go to your Magic Mirror folder and type the following command:
```bash
git pull && npm install
```
If you changed nothing more than the config or the modules, this should work without any problems.
Type `git status` to see your changes, if there are any, you can reset them with `git reset --hard`. After that, git pull should be possible.
## Community
@@ -174,6 +199,22 @@ Please keep the following in mind:
Thanks for your help in making MagicMirror² better!
## Manifesto
A real Manifesto is still to be written. Till then, Michael's response on [one of the repository issues](https://github.com/MichMich/MagicMirror/issues/1174) gives a great summary:
> "... I started this project as an ultimate starter project for Raspberry Pi enthusiasts. As a matter of fact, for most of the contributors, the MagicMirror project is the first open source project they ever contributed to. This is one of the reasons why the MagicMirror project is featured in several RasPi magazines.
>
>The project has a lot of opportunities for improvement. We could use a powerful framework like Vue to ramp up the development speed. We could use SASS for better/easier css implementations. We could make it an NPM installable package. And as you say, we could bundle it up. The big downside of of of these changes is that it over complicates things: a user no longer will be able to open just one file and make a small modification and see how it works out.
>
>Of course, a bundled version can be complimentary to the regular un-bundled version. And I'm sure a lot of (new) users will opt for the bundled version. But this means those users won't be motivated to take a peek under the hood. They will just remain 'users'. They won't become contributors, and worse: they won't be motivated to take their first steps in software development.
>
>And to be honest: motivating curious users to step out of their comfort zone and take those first steps is what drives me in this project. Therefor my ultimate goal is this project is to keep it as accessible as possible."
>
> ~ Michael Teeuw
<p align="center">
<br>
<a href="https://forum.magicmirror.builders/topic/728/magicmirror-is-voted-number-1-in-the-magpi-top-50"><img src="https://magicmirror.builders/img/magpi-best-watermark-custom.png" width="150" alt="MagPi Top 50"></a>

104
clientonly/index.js Normal file
View File

@@ -0,0 +1,104 @@
/* jshint esversion: 6 */
"use strict";
// Use seperate scope to prevent global scope pollution
(function () {
var config = {};
// Helper function to get server address/hostname from either the commandline or env
function getServerAddress() {
// Helper function to get command line parameters
// Assumes that a cmdline parameter is defined with `--key [value]`
function getCommandLineParameter(key, defaultValue = undefined) {
var index = process.argv.indexOf(`--${key}`);
var value = index > -1 ? process.argv[index + 1] : undefined;
return value !== undefined ? String(value) : defaultValue;
}
// Prefer command line arguments over environment variables
["address", "port"].forEach((key) => {
config[key] = getCommandLineParameter(key, process.env[key.toUpperCase()]);
})
}
function getServerConfig(url) {
// Return new pending promise
return new Promise((resolve, reject) => {
// Select http or https module, depending on reqested url
const lib = url.startsWith("https") ? require("https") : require("http");
const request = lib.get(url, (response) => {
var configData = "";
// Gather incomming data
response.on("data", function(chunk) {
configData += chunk;
});
// Resolve promise at the end of the HTTP/HTTPS stream
response.on("end", function() {
resolve(JSON.parse(configData));
});
});
request.on("error", function(error) {
reject(new Error(`Unable to read config from server (${url} (${error.message}`));
});
})
};
function fail(message, code = 1) {
if (message !== undefined && typeof message === "string") {
console.log(message);
} else {
console.log("Usage: 'node clientonly --address 192.168.1.10 --port 8080'");
}
process.exit(code);
}
getServerAddress();
(config.address && config.port) || fail();
// Only start the client if a non-local server was provided
if (["localhost", "127.0.0.1", "::1", "::ffff:127.0.0.1", undefined].indexOf(config.address) === -1) {
getServerConfig(`http://${config.address}:${config.port}/config/`)
.then(function (configReturn) {
// Pass along the server config via an environment variable
var env = Object.create(process.env);
var options = { env: env };
configReturn.address = config.address;
configReturn.port = config.port;
env.config = JSON.stringify(configReturn);
// Spawn electron application
const electron = require("electron");
const child = require("child_process").spawn(electron, ["js/electron.js"], options);
// Pipe all child process output to current stdout
child.stdout.on("data", function (buf) {
process.stdout.write(`Client: ${buf}`);
});
// Pipe all child process errors to current stderr
child.stderr.on("data", function (buf) {
process.stderr.write(`Client: ${buf}`);
});
child.on("error", function (err) {
process.stdout.write(`Client: ${err}`);
});
child.on("close", (code) => {
if (code != 0) {
console.log(`There something wrong. The clientonly is not running code ${code}`);
}
});
})
.catch(function (reason) {
fail(`Unable to connect to server: (${reason})`);
});
} else {
fail();
}
}());

View File

@@ -9,6 +9,11 @@
*/
var config = {
address: "localhost", // Address to listen on, can be:
// - "localhost", "127.0.0.1", "::1" to listen on loopback interface
// - another specific IPv4/6 to listen on a specific interface
// - "", "0.0.0.0", "::" to listen on any interface
// Default, when address config is left out, is "localhost"
port: 8080,
ipWhitelist: ["127.0.0.1", "::ffff:127.0.0.1", "::1"], // Set [] to allow all IP addresses
// or add a specific IPv4 of 192.168.1.5 :
@@ -54,7 +59,7 @@ var config = {
position: "top_right",
config: {
location: "New York",
locationID: "", //ID from http://www.openweathermap.org/help/city_list.txt
locationID: "", //ID from http://bulk.openweathermap.org/sample/; unzip the gz file and find your city
appid: "YOUR_OPENWEATHER_API_KEY"
}
},

View File

@@ -95,7 +95,7 @@ body {
header {
text-transform: uppercase;
font-size: 15px;
font-family: "Roboto Condensed";
font-family: "Roboto Condensed", Arial, Helvetica, sans-serif;
font-weight: 400;
border-bottom: 1px solid #666;
line-height: 15px;
@@ -128,6 +128,10 @@ sup {
text-overflow: ellipsis;
}
.pre-line {
white-space: pre-line;
}
/**
* Region Definitions.
*/
@@ -151,6 +155,7 @@ sup {
.region.right {
right: 0;
text-align: right;
}
.region.top {
@@ -161,6 +166,10 @@ sup {
margin-bottom: 25px;
}
.region.bottom .container {
margin-top: 25px;
}
.region.top .container:empty {
margin-bottom: 0;
}
@@ -185,10 +194,6 @@ sup {
bottom: 0;
}
.region.bottom .container {
margin-top: 25px;
}
.region.bottom .container:empty {
margin-top: 0;
}
@@ -231,10 +236,6 @@ sup {
text-align: left;
}
.region.right {
text-align: right;
}
.region table {
width: 100%;
border-spacing: 0;

17
dangerfile.js Normal file
View File

@@ -0,0 +1,17 @@
import { danger, fail, warn } from "danger"
// Check if the CHANGELOG.md file has been edited
// Fail the build and post a comment reminding submitters to do so if it wasn't changed
if (!danger.git.modified_files.includes("CHANGELOG.md")) {
warn("Please include an updated `CHANGELOG.md` file.<br>This way we can keep track of all the contributions.")
}
// Check if the PR request is send to the master branch.
// This should only be done by MichMich.
if (danger.github.pr.base.ref === "master" && danger.github.pr.user.login !== "MichMich") {
// Check if the PR body or title includes the text: #accepted.
// If not, the PR will fail.
if ((danger.github.pr.body + danger.github.pr.title).includes("#accepted")) {
fail("Please send all your pull requests to the `develop` branch.<br>Pull requests on the `master` branch will not be accepted.")
}
}

View File

@@ -1,202 +0,0 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

12
fonts/package-lock.json generated Normal file
View File

@@ -0,0 +1,12 @@
{
"name": "magicmirror-fonts",
"requires": true,
"lockfileVersion": 1,
"dependencies": {
"roboto-fontface": {
"version": "0.8.0",
"resolved": "https://registry.npmjs.org/roboto-fontface/-/roboto-fontface-0.8.0.tgz",
"integrity": "sha512-ZYzRkETgBrdEGzL5JSKimvjI2CX7ioyZCkX2BpcfyjqI+079W0wHAyj5W4rIZMcDSOHgLZtgz1IdDi/vU77KEQ=="
}
}
}

15
fonts/package.json Normal file
View File

@@ -0,0 +1,15 @@
{
"name": "magicmirror-fonts",
"description": "Package for fonts use by MagicMirror Core.",
"repository": {
"type": "git",
"url": "git+https://github.com/MichMich/MagicMirror.git"
},
"license": "MIT",
"bugs": {
"url": "https://github.com/MichMich/MagicMirror/issues"
},
"dependencies": {
"roboto-fontface": "^0.8.0"
}
}

View File

@@ -5,9 +5,9 @@
src:
local("Roboto Thin"),
local("Roboto-Thin"),
url("Roboto-Thin/Roboto-Thin.woff2") format("woff2"),
url("Roboto-Thin/Roboto-Thin.woff") format("woff"),
url("Roboto-Thin/Roboto-Thin.ttf") format("truetype");
url("node_modules/roboto-fontface/fonts/roboto/Roboto-Thin.woff2") format("woff2"),
url("node_modules/roboto-fontface/fonts/roboto/Roboto-Thin.woff") format("woff"),
url("node_modules/roboto-fontface/fonts/roboto/Roboto-Thin.ttf") format("truetype");
}
@font-face {
@@ -17,9 +17,9 @@
src:
local("Roboto Condensed Light"),
local("RobotoCondensed-Light"),
url("RobotoCondensed-Light/RobotoCondensed-Light.woff2") format("woff2"),
url("RobotoCondensed-Light/RobotoCondensed-Light.woff") format("woff"),
url("RobotoCondensed-Light/RobotoCondensed-Light.ttf") format("truetype");
url("node_modules/roboto-fontface/fonts/roboto-condensed/Roboto-Condensed-Light.woff2") format("woff2"),
url("node_modules/roboto-fontface/fonts/roboto-condensed/Roboto-Condensed-Light.woff") format("woff"),
url("node_modules/roboto-fontface/fonts/roboto-condensed/Roboto-Condensed-Light.ttf") format("truetype");
}
@font-face {
@@ -29,9 +29,9 @@
src:
local("Roboto Condensed"),
local("RobotoCondensed-Regular"),
url("RobotoCondensed-Regular/RobotoCondensed-Regular.woff2") format("woff2"),
url("RobotoCondensed-Regular/RobotoCondensed-Regular.woff") format("woff"),
url("RobotoCondensed-Regular/RobotoCondensed-Regular.ttf") format("truetype");
url("node_modules/roboto-fontface/fonts/roboto-condensed/Roboto-Condensed-Regular.woff2") format("woff2"),
url("node_modules/roboto-fontface/fonts/roboto-condensed/Roboto-Condensed-Regular.woff") format("woff"),
url("node_modules/roboto-fontface/fonts/roboto-condensed/Roboto-Condensed-Regular.ttf") format("truetype");
}
@font-face {
@@ -41,9 +41,9 @@
src:
local("Roboto Condensed Bold"),
local("RobotoCondensed-Bold"),
url("RobotoCondensed-Bold/RobotoCondensed-Bold.woff2") format("woff2"),
url("RobotoCondensed-Bold/RobotoCondensed-Bold.woff") format("woff"),
url("RobotoCondensed-Bold/RobotoCondensed-Bold.ttf") format("truetype");
url("node_modules/roboto-fontface/fonts/roboto-condensed/Roboto-Condensed-Bold.woff2") format("woff2"),
url("node_modules/roboto-fontface/fonts/roboto-condensed/Roboto-Condensed-Bold.woff") format("woff"),
url("node_modules/roboto-fontface/fonts/roboto-condensed/Roboto-Condensed-Bold.ttf") format("truetype");
}
@font-face {
@@ -53,9 +53,9 @@
src:
local("Roboto"),
local("Roboto-Regular"),
url("Roboto-Regular/Roboto-Regular.woff2") format("woff2"),
url("Roboto-Regular/Roboto-Regular.woff") format("woff"),
url("Roboto-Regular/Roboto-Regular.ttf") format("truetype");
url("node_modules/roboto-fontface/fonts/roboto/Roboto-Regular.woff2") format("woff2"),
url("node_modules/roboto-fontface/fonts/roboto/Roboto-Regular.woff") format("woff"),
url("node_modules/roboto-fontface/fonts/roboto/Roboto-Regular.ttf") format("truetype");
}
@font-face {
@@ -65,9 +65,9 @@
src:
local("Roboto Medium"),
local("Roboto-Medium"),
url("Roboto-Medium/Roboto-Medium.woff2") format("woff2"),
url("Roboto-Medium/Roboto-Medium.woff") format("woff"),
url("Roboto-Medium/Roboto-Medium.ttf") format("truetype");
url("node_modules/roboto-fontface/fonts/roboto/Roboto-Medium.woff2") format("woff2"),
url("node_modules/roboto-fontface/fonts/roboto/Roboto-Medium.woff") format("woff"),
url("node_modules/roboto-fontface/fonts/roboto/Roboto-Medium.ttf") format("truetype");
}
@font-face {
@@ -77,9 +77,9 @@
src:
local("Roboto Bold"),
local("Roboto-Bold"),
url("Roboto-Bold/Roboto-Bold.woff2") format("woff2"),
url("Roboto-Bold/Roboto-Bold.woff") format("woff"),
url("Roboto-Bold/Roboto-Bold.ttf") format("truetype");
url("node_modules/roboto-fontface/fonts/roboto/Roboto-Bold.woff2") format("woff2"),
url("node_modules/roboto-fontface/fonts/roboto/Roboto-Bold.woff") format("woff"),
url("node_modules/roboto-fontface/fonts/roboto/Roboto-Bold.ttf") format("truetype");
}
@font-face {
@@ -89,7 +89,7 @@
src:
local("Roboto Light"),
local("Roboto-Light"),
url("Roboto-Light/Roboto-Light.woff2") format("woff2"),
url("Roboto-Light/Roboto-Light.woff") format("woff"),
url("Roboto-Light/Roboto-Light.ttf") format("truetype");
url("node_modules/roboto-fontface/fonts/roboto/Roboto-Light.woff2") format("woff2"),
url("node_modules/roboto-fontface/fonts/roboto/Roboto-Light.woff") format("woff"),
url("node_modules/roboto-fontface/fonts/roboto/Roboto-Light.ttf") format("truetype");
}

7
fonts/yarn.lock Normal file
View File

@@ -0,0 +1,7 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1
roboto-fontface@^0.8.0:
version "0.8.0"
resolved "https://registry.yarnpkg.com/roboto-fontface/-/roboto-fontface-0.8.0.tgz#031a83c8f79932801a57d83bf743f37250163499"

View File

@@ -1,7 +1,7 @@
<!DOCTYPE html>
<html>
<head>
<title>Magic Mirror</title>
<title>MagicMirror²</title>
<meta name="google" content="notranslate" />
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
@@ -38,6 +38,7 @@
</div>
<div class="region fullscreen above"><div class="container"></div></div>
<script type="text/javascript" src="/socket.io/socket.io.js"></script>
<script type="text/javascript" src="vendor/node_modules/nunjucks/browser/nunjucks.min.js"></script>
<script type="text/javascript" src="js/defaults.js"></script>
<script type="text/javascript" src="#CONFIG_FILE#"></script>
<script type="text/javascript" src="vendor/vendor.js"></script>

View File

@@ -42,7 +42,7 @@ sudo apt-get update || echo -e "\e[91mUpdate failed, carrying on installation ..
# Installing helper tools
echo -e "\e[96mInstalling helper tools ...\e[90m"
sudo apt-get install curl wget git build-essential unzip || exit
sudo apt-get --assume-yes install curl wget git build-essential unzip || exit
# Check if we need to install or upgrade Node.js.
echo -e "\e[96mCheck current Node installation ...\e[0m"
@@ -82,7 +82,7 @@ if $NODE_INSTALL; then
# The NODE_STABLE_BRANCH variable will need to be manually adjusted when a new branch is released. (e.g. 7.x)
# Only tested (stable) versions are recommended as newer versions could break MagicMirror.
NODE_STABLE_BRANCH="6.x"
NODE_STABLE_BRANCH="9.x"
curl -sL https://deb.nodesource.com/setup_$NODE_STABLE_BRANCH | sudo -E bash -
sudo apt-get install -y nodejs
echo -e "\e[92mNode.js installation Done!\e[0m"
@@ -101,7 +101,7 @@ if [ -d "$HOME/MagicMirror" ] ; then
fi
echo -e "\e[96mCloning MagicMirror ...\e[90m"
if git clone https://github.com/MichMich/MagicMirror.git; then
if git clone --depth=1 https://github.com/MichMich/MagicMirror.git; then
echo -e "\e[92mCloning MagicMirror Done!\e[0m"
else
echo -e "\e[91mUnable to clone MagicMirror."
@@ -149,7 +149,7 @@ else
fi
# Use pm2 control like a service MagicMirror
read -p "Do you want use pm2 for auto starting of your MagicMirror (y/n)?" choice
read -p "Do you want use pm2 for auto starting of your MagicMirror (y/N)?" choice
if [[ $choice =~ ^[Yy]$ ]]; then
sudo npm install -g pm2
sudo su -c "env PATH=$PATH:/usr/bin pm2 startup linux -u pi --hp /home/pi"

View File

@@ -236,6 +236,33 @@ var App = function() {
});
});
};
/* stop()
* This methods stops the core app.
* This calls each node_helper's STOP() function, if it exists.
* Added to fix #1056
*/
this.stop = function() {
for (var h in nodeHelpers) {
var nodeHelper = nodeHelpers[h];
if (typeof nodeHelper.stop === "function") {
nodeHelper.stop();
}
}
};
/* Listen for SIGINT signal and call stop() function.
*
* Added to fix #1056
* Note: this is only used if running `server-only`. Otherwise
* this.stop() is called by app.on("before-quit"... in `electron.js`
*/
process.on("SIGINT", () => {
console.log("[SIGINT] Received. Shutting down server...");
setTimeout(() => { process.exit(0); }, 3000); // Force quit after 3 seconds
this.stop();
process.exit(0);
});
};
module.exports = new App();

View File

@@ -4,15 +4,15 @@
*/
// Inspired by base2 and Prototype
(function() {
(function () {
var initializing = false;
var fnTest = /xyz/.test(function() {xyz;}) ? /\b_super\b/ : /.*/;
var fnTest = /xyz/.test(function () { xyz; }) ? /\b_super\b/ : /.*/;
// The base Class implementation (does nothing)
this.Class = function() {};
this.Class = function () { };
// Create a new Class that inherits from this class
Class.extend = function(prop) {
Class.extend = function (prop) {
var _super = this.prototype;
// Instantiate a base class (but only create the instance,
@@ -30,23 +30,23 @@
for (var name in prop) {
// Check if we're overwriting an existing function
prototype[name] = typeof prop[name] == "function" &&
typeof _super[name] == "function" && fnTest.test(prop[name]) ? (function(name, fn) {
return function() {
var tmp = this._super;
typeof _super[name] == "function" && fnTest.test(prop[name]) ? (function (name, fn) {
return function () {
var tmp = this._super;
// Add a new ._super() method that is the same method
// but on the super-class
this._super = _super[name];
// Add a new ._super() method that is the same method
// but on the super-class
this._super = _super[name];
// The method only need to be bound temporarily, so we
// remove it when we're done executing
var ret = fn.apply(this, arguments);
this._super = tmp;
// The method only need to be bound temporarily, so we
// remove it when we're done executing
var ret = fn.apply(this, arguments);
this._super = tmp;
return ret;
};
})(name, prop[name]) : prop[name];
return ret;
};
})(name, prop[name]) : prop[name];
}
// The dummy class constructor
@@ -90,4 +90,6 @@ function cloneObject(obj) {
}
/*************** DO NOT EDIT THE LINE BELOW ***************/
if (typeof module !== "undefined") {module.exports = Class;}
if (typeof module !== "undefined") {
module.exports = Class;
}

View File

@@ -8,10 +8,12 @@
*/
var port = 8080;
var address = "localhost";
if (typeof(mmPort) !== "undefined") {
port = mmPort;
}
var defaults = {
address: address,
port: port,
kioskmode: false,
electronOptions: {},

View File

@@ -6,7 +6,7 @@ const electron = require("electron");
const core = require(__dirname + "/app.js");
// Config
var config = {};
var config = process.env.config ? JSON.parse(process.env.config) : {};
// Module to control application life.
const app = electron.app;
// Module to create native browser window.
@@ -17,7 +17,6 @@ const BrowserWindow = electron.BrowserWindow;
let mainWindow;
function createWindow() {
var electronOptionsDefaults = {
width: 800,
height: 600,
@@ -46,8 +45,9 @@ function createWindow() {
mainWindow = new BrowserWindow(electronOptions);
// and load the index.html of the app.
//mainWindow.loadURL('file://' + __dirname + '../../index.html');
mainWindow.loadURL("http://localhost:" + config.port);
// If config.address is not defined or is an empty string (listening on all interfaces), connect to localhost
var address = (config.address === void 0) | (config.address === "") ? (config.address = "localhost") : config.address;
mainWindow.loadURL(`http://${address}:${config.port}`);
// Open the DevTools if run with "npm start dev"
if (process.argv.includes("dev")) {
@@ -96,8 +96,24 @@ app.on("activate", function() {
}
});
// Start the core application.
// This starts all node helpers and starts the webserver.
core.start(function(c) {
config = c;
/* This method will be called when SIGINT is received and will call
* each node_helper's stop function if it exists. Added to fix #1056
*
* Note: this is only used if running Electron. Otherwise
* core.stop() is called by process.on("SIGINT"... in `app.js`
*/
app.on("before-quit", (event) => {
console.log("Shutting down server...");
event.preventDefault();
setTimeout(() => { process.exit(0); }, 3000); // Force-quit after 3 seconds.
core.stop();
process.exit(0);
});
// Start the core application if server is run on localhost
// This starts all node helpers and starts the webserver.
if (["localhost", "127.0.0.1", "::1", "::ffff:127.0.0.1", undefined].indexOf(config.address) > -1) {
core.start(function(c) {
config = c;
});
}

View File

@@ -1,5 +1,5 @@
/* global Log, Loader, Module, config, defaults */
/* jshint -W020 */
/* jshint -W020, esversion: 6 */
/* Magic Mirror
* Main System
@@ -19,42 +19,49 @@ var MM = (function() {
* are configured for a specific position.
*/
var createDomObjects = function() {
for (var m in modules) {
var module = modules[m];
var domCreationPromises = [];
if (typeof module.data.position === "string") {
var wrapper = selectWrapper(module.data.position);
var dom = document.createElement("div");
dom.id = module.identifier;
dom.className = module.name;
if (typeof module.data.classes === "string") {
dom.className = "module " + dom.className + " " + module.data.classes;
}
dom.opacity = 0;
wrapper.appendChild(dom);
if (typeof module.data.header !== "undefined" && module.data.header !== "") {
var moduleHeader = document.createElement("header");
moduleHeader.innerHTML = module.data.header;
moduleHeader.className = "module-header";
dom.appendChild(moduleHeader);
}
var moduleContent = document.createElement("div");
moduleContent.className = "module-content";
dom.appendChild(moduleContent);
updateDom(module, 0);
modules.forEach(function(module) {
if (typeof module.data.position !== "string") {
return;
}
}
var wrapper = selectWrapper(module.data.position);
var dom = document.createElement("div");
dom.id = module.identifier;
dom.className = module.name;
if (typeof module.data.classes === "string") {
dom.className = "module " + dom.className + " " + module.data.classes;
}
dom.opacity = 0;
wrapper.appendChild(dom);
if (typeof module.data.header !== "undefined" && module.data.header !== "") {
var moduleHeader = document.createElement("header");
moduleHeader.innerHTML = module.data.header;
moduleHeader.className = "module-header";
dom.appendChild(moduleHeader);
}
var moduleContent = document.createElement("div");
moduleContent.className = "module-content";
dom.appendChild(moduleContent);
var domCreationPromise = updateDom(module, 0);
domCreationPromises.push(domCreationPromise);
domCreationPromise.then(function() {
sendNotification("MODULE_DOM_CREATED", null, null, module);
}).catch(Log.error);
});
updateWrapperStates();
sendNotification("DOM_OBJECTS_CREATED");
Promise.all(domCreationPromises).then(function() {
sendNotification("DOM_OBJECTS_CREATED");
});
};
/* selectWrapper(position)
@@ -79,11 +86,12 @@ var MM = (function() {
* argument notification string - The identifier of the notification.
* argument payload mixed - The payload of the notification.
* argument sender Module - The module that sent the notification.
* argument sendTo Module - The module to send the notification to. (optional)
*/
var sendNotification = function(notification, payload, sender) {
var sendNotification = function(notification, payload, sender, sendTo) {
for (var m in modules) {
var module = modules[m];
if (module !== sender) {
if (module !== sender && (!sendTo || module === sendTo)) {
module.notificationReceived(notification, payload, sender);
}
}
@@ -94,19 +102,53 @@ var MM = (function() {
*
* argument module Module - The module that needs an update.
* argument speed Number - The number of microseconds for the animation. (optional)
*
* return Promise - Resolved when the dom is fully updated.
*/
var updateDom = function(module, speed) {
var newContent = module.getDom();
var newHeader = module.getHeader();
return new Promise(function(resolve) {
var newContentPromise = module.getDom();
var newHeader = module.getHeader();
if (!module.hidden) {
if (!(newContentPromise instanceof Promise)) {
// convert to a promise if not already one to avoid if/else's everywhere
newContentPromise = Promise.resolve(newContentPromise);
}
newContentPromise.then(function(newContent) {
var updatePromise = updateDomWithContent(module, speed, newHeader, newContent);
updatePromise.then(resolve).catch(Log.error);
}).catch(Log.error);
});
};
/* updateDomWithContent(module, speed, newHeader, newContent)
* Update the dom with the specified content
*
* argument module Module - The module that needs an update.
* argument speed Number - The number of microseconds for the animation. (optional)
* argument newHeader String - The new header that is generated.
* argument newContent Domobject - The new content that is generated.
*
* return Promise - Resolved when the module dom has been updated.
*/
var updateDomWithContent = function(module, speed, newHeader, newContent) {
return new Promise(function(resolve) {
if (module.hidden || !speed) {
updateModuleContent(module, newHeader, newContent);
resolve();
return;
}
if (!moduleNeedsUpdate(module, newHeader, newContent)) {
resolve();
return;
}
if (!speed) {
updateModuleContent(module, newHeader, newContent);
resolve();
return;
}
@@ -115,16 +157,16 @@ var MM = (function() {
if (!module.hidden) {
showModule(module, speed / 2);
}
resolve();
});
} else {
updateModuleContent(module, newHeader, newContent);
}
});
};
/* moduleNeedsUpdate(module, newContent)
* Check if the content has changed.
*
* argument module Module - The module to check.
* argument newHeader String - The new header that is generated.
* argument newContent Domobject - The new content that is generated.
*
* return bool - Does the module need an update?
@@ -152,6 +194,7 @@ var MM = (function() {
* Update the content of a module on screen.
*
* argument module Module - The module to check.
* argument newHeader String - The new header that is generated.
* argument newContent Domobject - The new content that is generated.
*/
var updateModuleContent = function(module, newHeader, newContent) {
@@ -202,6 +245,9 @@ var MM = (function() {
if (typeof callback === "function") { callback(); }
}, speed);
} else {
// invoke callback even if no content, issue 1308
if (typeof callback === "function") { callback(); }
}
};

View File

@@ -27,6 +27,11 @@ var Module = Class.extend({
// visibility when hiding and showing module.
lockStrings: [],
// Storage of the nunjuck Environment,
// This should not be referenced directly.
// Use the nunjucksEnvironment() to get it.
_nunjucksEnvironment: null,
/* init()
* Is called when the module is instantiated.
*/
@@ -70,25 +75,37 @@ var Module = Class.extend({
/* getDom()
* This method generates the dom which needs to be displayed. This method is called by the Magic Mirror core.
* This method needs to be subclassed if the module wants to display info on the mirror.
* This method can to be subclassed if the module wants to display info on the mirror.
* Alternatively, the getTemplete method could be subclassed.
*
* return domobject - The dom to display.
* return DomObject | Promise - The dom or a promise with the dom to display.
*/
getDom: function () {
var nameWrapper = document.createElement("div");
var name = document.createTextNode(this.name);
nameWrapper.appendChild(name);
var self = this;
return new Promise(function(resolve) {
var div = document.createElement("div");
var template = self.getTemplate();
var templateData = self.getTemplateData();
var identifierWrapper = document.createElement("div");
var identifier = document.createTextNode(this.identifier);
identifierWrapper.appendChild(identifier);
identifierWrapper.className = "small dimmed";
// Check to see if we need to render a template string or a file.
if (/^.*((\.html)|(\.njk))$/.test(template)) {
// the template is a filename
self.nunjucksEnvironment().render(template, templateData, function (err, res) {
if (err) {
Log.error(err)
}
var div = document.createElement("div");
div.appendChild(nameWrapper);
div.appendChild(identifierWrapper);
div.innerHTML = res;
return div;
resolve(div);
});
} else {
// the template is a template string.
div.innerHTML = self.nunjucksEnvironment().renderString(template, templateData);
resolve(div);
}
});
},
/* getHeader()
@@ -102,6 +119,28 @@ var Module = Class.extend({
return this.data.header;
},
/* getTemplate()
* This method returns the template for the module which is used by the default getDom implementation.
* This method needs to be subclassed if the module wants to use a tempate.
* It can either return a template sting, or a template filename.
* If the string ends with '.html' it's considered a file from within the module's folder.
*
* return string - The template string of filename.
*/
getTemplate: function () {
return "<div class=\"normal\">" + this.name + "</div><div class=\"small dimmed\">" + this.identifier + "</div>";
},
/* getTemplateData()
* This method returns the data to be used in the template.
* This method needs to be subclassed if the module wants to use a custom data.
*
* return Object
*/
getTemplateData: function () {
return {}
},
/* notificationReceived(notification, payload, sender)
* This method is called when a notification arrives.
* This method is called by the Magic Mirror core.
@@ -118,6 +157,30 @@ var Module = Class.extend({
}
},
/** nunjucksEnvironment()
* Returns the nunjucks environment for the current module.
* The environment is checked in the _nunjucksEnvironment instance variable.
* @returns Nunjucks Environment
*/
nunjucksEnvironment: function() {
if (this._nunjucksEnvironment != null) {
return this._nunjucksEnvironment;
}
var self = this;
this._nunjucksEnvironment = new nunjucks.Environment(new nunjucks.WebLoader(this.file(""), {async: true}), {
trimBlocks: true,
lstripBlocks: true
});
this._nunjucksEnvironment.addFilter("translate", function(str) {
return self.translate(str)
});
return this._nunjucksEnvironment;
},
/* socketNotificationReceived(notification, payload)
* This method is called when a socket notification arrives.
*
@@ -194,7 +257,7 @@ var Module = Class.extend({
* return string - File path.
*/
file: function (file) {
return this.data.path + "/" + file;
return (this.data.path + "/" + file).replace("//", "/");
},
/* loadStyles()
@@ -276,8 +339,8 @@ var Module = Class.extend({
* Request the translation for a given key with optional variables and default value.
*
* argument key string - The key of the string to translate
* argument defaultValueOrVariables string/object - The default value or variables for translating. (Optional)
* argument defaultValue string - The default value with variables. (Optional)
* argument defaultValueOrVariables string/object - The default value or variables for translating. (Optional)
* argument defaultValue string - The default value with variables. (Optional)
*/
translate: function (key, defaultValueOrVariables, defaultValue) {
if(typeof defaultValueOrVariables === "object") {
@@ -414,11 +477,3 @@ Module.register = function (name, moduleDefinition) {
Log.log("Module registered: " + name);
Module.definitions[name] = moduleDefinition;
};
if (typeof exports != "undefined") { // For testing purpose only
// A good a idea move the function cmpversions a helper file.
// It's used into other side.
exports._test = {
cmpVersions: cmpVersions
}
}

View File

@@ -13,6 +13,7 @@ var path = require("path");
var ipfilter = require("express-ipfilter").IpFilter;
var fs = require("fs");
var helmet = require("helmet");
var Utils = require(__dirname + "/utils.js");
var Server = function(config, callback) {
@@ -26,11 +27,11 @@ var Server = function(config, callback) {
server.listen(port, config.address ? config.address : null);
if (config.ipWhitelist instanceof Array && config.ipWhitelist.length == 0) {
console.info("You're using a full whitelist configuration to allow for all IPs")
console.info(Utils.colors.warn("You're using a full whitelist configuration to allow for all IPs"))
}
app.use(function(req, res, next) {
var result = ipfilter(config.ipWhitelist, {mode: "allow", log: false})(req, res, function(err) {
var result = ipfilter(config.ipWhitelist, {mode: config.ipWhitelist.length === 0 ? "deny" : "allow", log: false})(req, res, function(err) {
if (err === undefined) {
return next();
}
@@ -52,6 +53,10 @@ var Server = function(config, callback) {
res.send(global.version);
});
app.get("/config", function(req,res) {
res.send(config);
});
app.get("/", function(req, res) {
var html = fs.readFileSync(path.resolve(global.root_path + "/index.html"), {encoding: "utf8"});
html = html.replace("#VERSION#", global.version);

View File

@@ -126,6 +126,9 @@ var Translator = (function() {
// variables: {timeToWait: "2 hours", work: "painting"}
// to: "Please wait for 2 hours before continuing with painting."
function createStringFromTemplate(template, variables) {
if(Object.prototype.toString.call(template) !== "[object String]") {
return template;
}
if(variables.fallback && !template.match(new RegExp("\{.+\}"))) {
template = variables.fallback;
}
@@ -156,11 +159,12 @@ var Translator = (function() {
return key;
},
/* load(module, file, callback)
/* load(module, file, isFallback, callback)
* Load a translation file (json) and remember the data.
*
* argument module Module - The module to load the translation file for.
* argument file string - Path of the file we want to load.
* argument isFallback boolean - Flag to indicate fallback translations.
* argument callback function - Function called when done.
*/
load: function(module, file, isFallback, callback) {
@@ -216,10 +220,12 @@ var Translator = (function() {
// defined translation after the following line.
for (var first in translations) {break;}
Log.log("Loading core translation fallback file: " + translations[first]);
loadJSON(translations[first], function(translations) {
self.coreTranslationsFallback = translations;
});
if (first) {
Log.log("Loading core translation fallback file: " + translations[first]);
loadJSON(translations[first], function(translations) {
self.coreTranslationsFallback = translations;
});
}
},
};
})();

31
module-types.ts Normal file
View File

@@ -0,0 +1,31 @@
type ModuleProperties = {
defaults?: object,
start?(): void,
getHeader?(): string,
getTemplate?(): string,
getTemplateData?(): object,
notificationReceived?(notification: string, payload: any, sender: object): void,
socketNotificationReceived?(notification: string, payload: any): void,
suspend?(): void,
resume?(): void,
getDom?(): HTMLElement,
getStyles?(): string[],
[key: string]: any,
};
export declare const Module: {
register(moduleName: string, moduleProperties: ModuleProperties): void;
};
export declare const Log: {
info(message?: any, ...optionalParams: any[]): void,
log(message?: any, ...optionalParams: any[]): void,
error(message?: any, ...optionalParams: any[]): void,
warn(message?: any, ...optionalParams: any[]): void,
group(groupTitle?: string, ...optionalParams: any[]): void,
groupCollapsed(groupTitle?: string, ...optionalParams: any[]): void,
groupEnd(): void,
time(timerName?: string): void,
timeEnd(timerName?: string): void,
timeStamp(timerName?: string): void,
};

View File

@@ -2,6 +2,42 @@
This document describes the way to develop your own MagicMirror² modules.
Table of Contents:
- Module structure
- Files
- The Core module file: modulename.js
- Available module instance properties
- Subclassable module methods
- Module instance methods
- Visibility locking
- The Node Helper: node_helper.js
- Available module instance properties
- Subclassable module methods
- Module instance methods
- MagicMirror Helper Methods
- Module Selection
- MagicMirror Logger
---
## General Advice
As MagicMirror has gained huge popularity, so has the number of available modules. For new users and developers alike, it is very time consuming to navigate around the various repositories in order to find out what exactly a certain modules does, how it looks and what it depends on. Unfortunately, this information is rarely available, nor easily obtained without having to install it first.
Therefore **we highly recommend you to include the following information in your README file.**
- A high quality screenshot of your working module
- A short, one sentence, clear description what it does (duh!)
- What external API's it depend on, including web links to those
- Wheteher the API/request require a key and the user limitations of those. (Is it free?)
Surely this also help you get better recognition and feedback for your work.
## Module structure
All modules are loaded in the `modules` folder. The default modules are grouped together in the `modules/default` folder. Your module should be placed in a subfolder of `modules`. Note that any file or folder your create in the `modules` folder will be ignored by git, allowing you to upgrade the MagicMirror² without the loss of your files.
@@ -14,7 +50,7 @@ A module can be placed in one single folder. Or multiple modules can be grouped
- **modulename/public** - Any files in this folder can be accesed via the browser on `/modulename/filename.ext`.
- **modulename/anyfileorfolder** Any other file or folder in the module folder can be used by the core module script. For example: *modulename/css/modulename.css* would be a good path for your additional module styles.
## Core module file: modulename.js
## The Core module file: modulename.js
This is the script in which the module will be defined. This script is required in order for the module to be used. In it's most simple form, the core module file must contain:
````javascript
Module.register("modulename",{});
@@ -44,30 +80,16 @@ As you can see, the `Module.register()` method takes two arguments: the name of
### Available module instance properties
After the module is initialized, the module instance has a few available module properties:
#### `this.name`
**String**
| Instance Property | Type | Description |
|:----------------- |:---- |:----------- |
| `this.name` | String | The name of the module. |
| `this.identifier` | String | This is a unique identifier for the module instance. |
| `this.hidden` | Boolean | This represents if the module is currently hidden (faded away). |
| `this.config` | Boolean | The configuration of the module instance as set in the user's `config.js` file. This config will also contain the module's defaults if these properties are not over-written by the user config. |
| `this.data` | Object | The data object contain additional metadata about the module instance. (See below) |
The name of the module.
#### `this.identifier`
**String**
This is a unique identifier for the module instance.
#### `this.hidden`
**Boolean**
This represents if the module is currently hidden (faded away).
#### `this.config`
**Boolean**
The configuration of the module instance as set in the user's config.js file. This config will also contain the module's defaults if these properties are not over written by the user config.
#### `this.data`
**Object**
The data object contains additional metadata about the module instance:
The `this.data` data object contain the follwoing metadata:
- `data.classes` - The classes which are added to the module dom wrapper.
- `data.file` - The filename of the core module file.
- `data.path` - The path of the module folder.
@@ -230,11 +252,12 @@ notificationReceived: function(notification, payload, sender) {
}
````
**Note:** the system sends two notifications when starting up. These notifications could come in handy!
**Note:** the system sends three notifications when starting up. These notifications could come in handy!
- `ALL_MODULES_STARTED` - All modules are started. You can now send notifications to other modules.
- `DOM_OBJECTS_CREATED` - All dom objects are created. The system is now ready to perform visual changes.
- `MODULE_DOM_CREATED` - This module's dom has been fully loaded. You can now access your module's dom objects.
#### `socketNotificationReceived: function(notification, payload)`
@@ -472,7 +495,7 @@ this.translate("RUNNING", {
{
"RUNNING": "Slutar",
}
````
In this case the `translate`-function will not find any variables in the translation, will look for `fallback` variable and use that if possible to create the translation.
## The Node Helper: node_helper.js
@@ -555,6 +578,17 @@ start: function() {
}
````
#### `stop()`
This method is called when the MagicMirror server receives a `SIGINT` command and is shutting down. This method should include any commands needed to close any open connections, stop any sub-processes and gracefully exit the module.
**Example:**
````javascript
stop: function() {
console.log("Shutting down MyModule");
this.connection.close();
}
````
#### `socketNotificationReceived: function(notification, payload)`
With this method, your node helper can receive notifications from your modules. When this method is called, it has 2 arguments:

View File

@@ -60,5 +60,5 @@ self.sendNotification("SHOW_ALERT", {});
| `timer` (optional) | How long the alert should stay visible in ms. <br> **Important:** If you do not use the `timer`, it is your duty to hide the alert by using `self.sendNotification("HIDE_ALERT");`! <br><br>**Possible values:** `int` `float` <br> **Default value:** `none`
## Open Source Licenses
###[NotificationStyles](https://github.com/codrops/NotificationStyles)
### [NotificationStyles](https://github.com/codrops/NotificationStyles)
See [ympanus.net](http://tympanus.net/codrops/licensing/) for license.

View File

@@ -38,13 +38,13 @@ Module.register("alert",{
if (this.config.effect == "slide") {this.config.effect = this.config.effect + "-" + this.config.position;}
msg = "";
if (message.title) {
msg += "<span class='thin' style='line-height: 35px; font-size:24px' color='#4A4A4A'>" + message.title + "</span>";
msg += "<span class='thin dimmed medium'>" + message.title + "</span>";
}
if (message.message){
if (msg != ""){
msg+= "<br />";
}
msg += "<span class='light' style='font-size:28px;line-height: 30px;'>" + message.message + "</span>";
msg += "<span class='light bright small'>" + message.message + "</span>";
}
new NotificationFx({
@@ -63,9 +63,9 @@ Module.register("alert",{
params.imageUrl = null;
image = "";
} else if (typeof params.imageFA === "undefined"){
image = "<img src='" + (params.imageUrl).toString() + "' height=" + (params.imageHeight).toString() + " style='margin-bottom: 10px;'/><br />";
image = "<img src='" + (params.imageUrl).toString() + "' height='" + (params.imageHeight).toString() + "' style='margin-bottom: 10px;'/><br />";
} else if (typeof params.imageUrl === "undefined"){
image = "<span class='" + "fa fa-" + params.imageFA + "' style='margin-bottom: 10px;color: #fff;font-size:" + (params.imageHeight).toString() + ";'/></span><br />";
image = "<span class='bright " + "fa fa-" + params.imageFA + "' style='margin-bottom: 10px;font-size:" + (params.imageHeight).toString() + ";'/></span><br />";
}
//Create overlay
var overlay = document.createElement("div");
@@ -79,16 +79,16 @@ Module.register("alert",{
}
//Display title and message only if they are provided in notification parameters
message ="";
var message = "";
if (params.title) {
message += "<span class='light' style='line-height: 35px; font-size:30px' color='#4A4A4A'>" + params.title + "</span>"
message += "<span class='light dimmed medium'>" + params.title + "</span>";
}
if (params.message) {
if (message != ""){
if (message !== ""){
message += "<br />";
}
message += "<span class='thin' style='font-size:22px;line-height: 30px;'>" + params.message + "</span>";
message += "<span class='thin bright small'>" + params.message + "</span>";
}
//Store alert in this.alerts
@@ -110,25 +110,27 @@ Module.register("alert",{
},
hide_alert: function(sender) {
//Dismiss alert and remove from this.alerts
this.alerts[sender.name].dismiss();
this.alerts[sender.name] = null;
//Remove overlay
var overlay = document.getElementById("overlay");
overlay.parentNode.removeChild(overlay);
if (this.alerts[sender.name]) {
this.alerts[sender.name].dismiss();
this.alerts[sender.name] = null;
//Remove overlay
var overlay = document.getElementById("overlay");
overlay.parentNode.removeChild(overlay);
}
},
setPosition: function(pos) {
//Add css to body depending on the set position for notifications
var sheet = document.createElement("style");
if (pos == "center") {sheet.innerHTML = ".ns-box {margin-left: auto; margin-right: auto;text-align: center;}";}
if (pos == "right") {sheet.innerHTML = ".ns-box {margin-left: auto;text-align: right;}";}
if (pos == "left") {sheet.innerHTML = ".ns-box {margin-right: auto;text-align: left;}";}
if (pos === "center") {sheet.innerHTML = ".ns-box {margin-left: auto; margin-right: auto;text-align: center;}";}
if (pos === "right") {sheet.innerHTML = ".ns-box {margin-left: auto;text-align: right;}";}
if (pos === "left") {sheet.innerHTML = ".ns-box {margin-right: auto;text-align: left;}";}
document.body.appendChild(sheet);
},
notificationReceived: function(notification, payload, sender) {
if (notification === "SHOW_ALERT") {
if (typeof payload.type === "undefined") { payload.type = "alert"; }
if (payload.type == "alert") {
if (payload.type === "alert") {
this.show_alert(payload, sender);
} else if (payload.type = "notification") {
this.show_notification(payload);
@@ -141,7 +143,7 @@ Module.register("alert",{
this.alerts = {};
this.setPosition(this.config.position);
if (this.config.welcome_message) {
if (this.config.welcome_message == true){
if (this.config.welcome_message === true){
this.show_notification({title: this.translate("sysTitle"), message: this.translate("welcome")});
}
else{

View File

@@ -0,0 +1,4 @@
{
"sysTitle": "MagicMirror нотификация",
"welcome": "Добре дошли, стартирането беше успешно"
}

View File

@@ -0,0 +1,4 @@
{
"sysTitle": "MagicMirror Notification",
"welcome": "Bienvenue, le démarrage a été un succès!"
}

11
modules/default/calendar/README.md Normal file → Executable file
View File

@@ -1,6 +1,7 @@
# Module: Calendar
The `calendar` module is one of the default modules of the MagicMirror.
This module displays events from a public .ical calendar. It can combine multiple calendars.
Note that calendars may not contain any entry before 1st January 1970, otherwise the calendar won't be displayed and the module will crash.
## Using the module
@@ -33,30 +34,34 @@ The following properties can be configured:
| `maxTitleLength` | The maximum title length. <br><br> **Possible values:** `10` - `50` <br> **Default value:** `25`
| `wrapEvents` | Wrap event titles to multiple lines. Breaks lines at the length defined by `maxTitleLength`. <br><br> **Possible values:** `true` or `false` <br> **Default value:** `false`
| `fetchInterval` | How often does the content needs to be fetched? (Milliseconds) <br><br> **Possible values:** `1000` - `86400000` <br> **Default value:** `300000` (5 minutes)
| `animationSpeed` | Speed of the update animation. (Milliseconds) <br><br> **Possible values:**`0` - `5000` <br> **Default value:** `2000` (2 seconds)
| `animationSpeed` | Speed of the update animation. (Milliseconds) <br><br> **Possible values:** `0` - `5000` <br> **Default value:** `2000` (2 seconds)
| `fade` | Fade the future events to black. (Gradient) <br><br> **Possible values:** `true` or `false` <br> **Default value:** `true`
| `fadePoint` | Where to start fade? <br><br> **Possible values:** `0` (top of the list) - `1` (bottom of list) <br> **Default value:** `0.25`
| `tableClass` | Name of the classes issued from `main.css`. <br><br> **Possible values:** xsmall, small, medium, large, xlarge. <br> **Default value:** _small._
| `calendars` | The list of calendars. <br><br> **Possible values:** An array, see _calendar configuration_ below. <br> **Default value:** _An example calendar._
| `titleReplace` | An object of textual replacements applied to the tile of the event. This allow to remove or replace certains words in the title. <br><br> **Example:** `{'Birthday of ' : '', 'foo':'bar'}` <br> **Default value:** `{ "De verjaardag van ": "", "'s birthday": "" }`
| `displayRepeatingCountTitle` | Show count title for yearly repeating events (e.g. "X. Birthday", "X. Anniversary") <br><br> **Possible values:** `true` or `false` <br> **Default value:** `false`
| `dateFormat` | Format to use for the date of events (when using absolute dates) <br><br> **Possible values:** See [Moment.js formats](http://momentjs.com/docs/#/parsing/string-format/) <br> **Default value:** `MMM Do` (e.g. Jan 18th)
| `fullDayEventDateFormat` | Format to use for the date of full day events (when using absolute dates) <br><br> **Possible values:** See [Moment.js formats](http://momentjs.com/docs/#/parsing/string-format/) <br> **Default value:** `MMM Do` (e.g. Jan 18th)
| `timeFormat` | Display event times as absolute dates, or relative time <br><br> **Possible values:** `absolute` or `relative` <br> **Default value:** `relative`
| `timeFormat` | Display event times as absolute dates, or relative time, or using absolute date headers with times for each event next to it <br><br> **Possible values:** `absolute` or `relative` or `dateheaders` <br> **Default value:** `relative`
| `getRelative` | How much time (in hours) should be left until calendar events start getting relative? <br><br> **Possible values:** `0` (events stay absolute) - `48` (48 hours before the event starts) <br> **Default value:** `6`
| `urgency` | When using a timeFormat of `absolute`, the `urgency` setting allows you to display events within a specific time frame as `relative`. This allows events within a certain time frame to be displayed as relative (in xx days) while others are displayed as absolute dates <br><br> **Possible values:** a positive integer representing the number of days for which you want a relative date, for example `7` (for 7 days) <br><br> **Default value:** `7`
| `broadcastEvents` | If this property is set to true, the calendar will broadcast all the events to all other modules with the notification message: `CALENDAR_EVENTS`. The event objects are stored in an array and contain the following fields: `title`, `startDate`, `endDate`, `fullDayEvent`, `location` and `geo`. <br><br> **Possible values:** `true`, `false` <br><br> **Default value:** `true`
| `hidePrivate` | Hides private calendar events. <br><br> **Possible values:** `true` or `false` <br> **Default value:** `false`
| `excludedEvents` | An array of words / phrases from event titles that will be excluded from being shown. <br><br> **Example:** `['Birthday', 'Hide This Event']` <br> **Default value:** `[]`
| `hideOngoing` | Hides calendar events that have already started. <br><br> **Possible values:** `true` or `false` <br> **Default value:** `false`
| `excludedEvents` | An array of words / phrases from event titles that will be excluded from being shown. <br><br>Additionally advanced filter objects can be passed in. Below is the configuration for the advance filtering object.<br>**Required**<br>`filterBy` - string used to determine if filter is applied.<br>**Optional**<br>`until` - Time before an event to display it Ex: [`'3 days'`, `'2 months'`, `'1 week'`]<br>`caseSensitive` - By default, excludedEvents are case insensitive, set this to true to enforce case sensitivity<br>`regex` - set to `true` if filterBy is a regex. For those not familiar with regex it is used for pattern matching, please see [here](https://regexr.com/) for more info.<br><br> **Example:** `['Birthday', 'Hide This Event', {filterBy: 'Payment', until: '6 days', caseSensitive: true}, {filterBy: '^[0-9]{1,}.*', regex: true}]` <br> **Default value:** `[]`
### Calendar configuration
The `calendars` property contains an array of the configured calendars.
The `colored` property gives the option for an individual color for each calendar.
The `coloredSymbolOnly` property will apply color to the symbol only, not the whole line. This is only applicable when `colored` is also enabled.
#### Default value:
````javascript
config: {
colored: false,
coloredSymbolOnly: false,
calendars: [
{
url: 'http://www.calendarlabs.com/templates/ical/US-Holidays.ics',

324
modules/default/calendar/calendar.js Normal file → Executable file
View File

@@ -25,11 +25,16 @@ Module.register("calendar", {
urgency: 7,
timeFormat: "relative",
dateFormat: "MMM Do",
dateEndFormat: "HH:mm",
fullDayEventDateFormat: "MMM Do",
showEnd: true,
getRelative: 6,
fadePoint: 0.25, // Start on 1/4th of the list.
hidePrivate: false,
hideOngoing: false,
colored: false,
coloredSymbolOnly: false,
tableClass: "small",
calendars: [
{
symbol: "calendar",
@@ -67,30 +72,7 @@ Module.register("calendar", {
Log.log("Starting module: " + this.name);
// Set locale.
moment.locale(config.language);
switch (config.timeFormat) {
case 12: {
moment.updateLocale(config.language, {
longDateFormat: {
LT: "h:mm A"
}
});
break;
}
case 24: {
moment.updateLocale(config.language, {
longDateFormat: {
LT: "hh:mm"
}
});
break;
}
// If config.timeFormat was not given (or has invalid format) default to locale default
default: {
break;
}
}
moment.updateLocale(config.language, this.getLocaleSpecification(config.timeFormat));
for (var c in this.config.calendars) {
var calendar = this.config.calendars[c];
@@ -102,7 +84,9 @@ Module.register("calendar", {
};
// we check user and password here for backwards compatibility with old configs
if(calendar.user && calendar.pass){
if(calendar.user && calendar.pass) {
Log.warn("Deprecation warning: Please update your calendar authentication configuration.");
Log.warn("https://github.com/MichMich/MagicMirror/tree/v2.1.2/modules/default/calendar#calendar-authentication-options");
calendar.auth = {
user: calendar.user,
pass: calendar.pass
@@ -143,33 +127,39 @@ Module.register("calendar", {
var events = this.createEventList();
var wrapper = document.createElement("table");
wrapper.className = "small";
wrapper.className = this.config.tableClass;
if (events.length === 0) {
wrapper.innerHTML = (this.loaded) ? this.translate("EMPTY") : this.translate("LOADING");
wrapper.className = "small dimmed";
wrapper.className = this.config.tableClass + " dimmed";
return wrapper;
}
var lastSeenDate = "";
for (var e in events) {
var event = events[e];
var dateAsString = moment(event.startDate, "x").format(this.config.dateFormat);
if(this.config.timeFormat === "dateheaders"){
if(lastSeenDate !== dateAsString){
var dateRow = document.createElement("tr");
dateRow.className = "normal"
var dateCell = document.createElement("td");
var excluded = false;
for (var f in this.config.excludedEvents) {
var filter = this.config.excludedEvents[f];
if (event.title.toLowerCase().includes(filter.toLowerCase())) {
excluded = true;
break;
dateCell.colSpan = "3";
dateCell.innerHTML = dateAsString;
dateRow.appendChild(dateCell);
wrapper.appendChild(dateRow);
lastSeenDate = dateAsString;
}
}
if (excluded) {
continue;
}
var eventWrapper = document.createElement("tr");
if (this.config.colored) {
if (this.config.colored && !this.config.coloredSymbolOnly) {
eventWrapper.style.cssText = "color:" + this.colorForUrl(event.url);
}
@@ -177,6 +167,11 @@ Module.register("calendar", {
if (this.config.displaySymbol) {
var symbolWrapper = document.createElement("td");
if (this.config.colored && this.config.coloredSymbolOnly) {
symbolWrapper.style.cssText = "color:" + this.colorForUrl(event.url);
}
symbolWrapper.className = "symbol align-right";
var symbols = this.symbolsForUrl(event.url);
if(typeof symbols === "string") {
@@ -185,13 +180,17 @@ Module.register("calendar", {
for(var i = 0; i < symbols.length; i++) {
var symbol = document.createElement("span");
symbol.className = "fa fa-" + symbols[i];
symbol.className = "fa fa-fw fa-" + symbols[i];
if(i > 0){
symbol.style.paddingLeft = "5px";
}
symbolWrapper.appendChild(symbol);
}
eventWrapper.appendChild(symbolWrapper);
}else if(this.config.timeFormat === "dateheaders"){
var blankCell = document.createElement("td");
blankCell.innerHTML = "&nbsp;&nbsp;&nbsp;"
eventWrapper.appendChild(blankCell);
}
var titleWrapper = document.createElement("td"),
@@ -217,89 +216,136 @@ Module.register("calendar", {
titleWrapper.className = "title";
}
eventWrapper.appendChild(titleWrapper);
if(this.config.timeFormat === "dateheaders"){
var timeWrapper = document.createElement("td");
//console.log(event.today);
var now = new Date();
// Define second, minute, hour, and day variables
var oneSecond = 1000; // 1,000 milliseconds
var oneMinute = oneSecond * 60;
var oneHour = oneMinute * 60;
var oneDay = oneHour * 24;
if (event.fullDayEvent) {
if (event.today) {
timeWrapper.innerHTML = this.capFirst(this.translate("TODAY"));
} else if (event.startDate - now < oneDay && event.startDate - now > 0) {
timeWrapper.innerHTML = this.capFirst(this.translate("TOMORROW"));
} else if (event.startDate - now < 2 * oneDay && event.startDate - now > 0) {
if (this.translate("DAYAFTERTOMORROW") !== "DAYAFTERTOMORROW") {
timeWrapper.innerHTML = this.capFirst(this.translate("DAYAFTERTOMORROW"));
} else {
timeWrapper.innerHTML = this.capFirst(moment(event.startDate, "x").fromNow());
if (event.fullDayEvent) {
titleWrapper.colSpan = "2";
titleWrapper.align = "left";
}else{
var timeWrapper = document.createElement("td");
timeWrapper.className = "time light";
timeWrapper.align = "left";
timeWrapper.style.paddingLeft = "2px";
var timeFormatString = "";
switch (config.timeFormat) {
case 12: {
timeFormatString = "h:mm A";
break;
}
} else {
/* Check to see if the user displays absolute or relative dates with their events
* Also check to see if an event is happening within an 'urgency' time frameElement
* For example, if the user set an .urgency of 7 days, those events that fall within that
* time frame will be displayed with 'in xxx' time format or moment.fromNow()
*
* Note: this needs to be put in its own function, as the whole thing repeats again verbatim
*/
if (this.config.timeFormat === "absolute") {
if ((this.config.urgency > 1) && (event.startDate - now < (this.config.urgency * oneDay))) {
// This event falls within the config.urgency period that the user has set
timeWrapper.innerHTML = this.capFirst(moment(event.startDate, "x").fromNow());
} else {
timeWrapper.innerHTML = this.capFirst(moment(event.startDate, "x").format(this.config.fullDayEventDateFormat));
}
} else {
timeWrapper.innerHTML = this.capFirst(moment(event.startDate, "x").fromNow());
case 24: {
timeFormatString = "HH:mm";
break;
}
default: {
timeFormatString = "HH:mm";
break;
}
}
timeWrapper.innerHTML = moment(event.startDate, "x").format(timeFormatString);
eventWrapper.appendChild(timeWrapper);
titleWrapper.align = "right";
}
} else {
if (event.startDate >= new Date()) {
if (event.startDate - now < 2 * oneDay) {
// This event is within the next 48 hours (2 days)
if (event.startDate - now < this.config.getRelative * oneHour) {
// If event is within 6 hour, display 'in xxx' time format or moment.fromNow()
timeWrapper.innerHTML = this.capFirst(moment(event.startDate, "x").fromNow());
eventWrapper.appendChild(titleWrapper);
}else{
var timeWrapper = document.createElement("td");
eventWrapper.appendChild(titleWrapper);
//console.log(event.today);
var now = new Date();
// Define second, minute, hour, and day variables
var oneSecond = 1000; // 1,000 milliseconds
var oneMinute = oneSecond * 60;
var oneHour = oneMinute * 60;
var oneDay = oneHour * 24;
if (event.fullDayEvent) {
if (event.today) {
timeWrapper.innerHTML = this.capFirst(this.translate("TODAY"));
} else if (event.startDate - now < oneDay && event.startDate - now > 0) {
timeWrapper.innerHTML = this.capFirst(this.translate("TOMORROW"));
} else if (event.startDate - now < 2 * oneDay && event.startDate - now > 0) {
if (this.translate("DAYAFTERTOMORROW") !== "DAYAFTERTOMORROW") {
timeWrapper.innerHTML = this.capFirst(this.translate("DAYAFTERTOMORROW"));
} else {
// Otherwise just say 'Today/Tomorrow at such-n-such time'
timeWrapper.innerHTML = this.capFirst(moment(event.startDate, "x").calendar());
timeWrapper.innerHTML = this.capFirst(moment(event.startDate, "x").fromNow());
}
} else {
/* Check to see if the user displays absolute or relative dates with their events
* Also check to see if an event is happening within an 'urgency' time frameElement
* For example, if the user set an .urgency of 7 days, those events that fall within that
* time frame will be displayed with 'in xxx' time format or moment.fromNow()
*
* Note: this needs to be put in its own function, as the whole thing repeats again verbatim
*/
* Also check to see if an event is happening within an 'urgency' time frameElement
* For example, if the user set an .urgency of 7 days, those events that fall within that
* time frame will be displayed with 'in xxx' time format or moment.fromNow()
*
* Note: this needs to be put in its own function, as the whole thing repeats again verbatim
*/
if (this.config.timeFormat === "absolute") {
if ((this.config.urgency > 1) && (event.startDate - now < (this.config.urgency * oneDay))) {
// This event falls within the config.urgency period that the user has set
timeWrapper.innerHTML = this.capFirst(moment(event.startDate, "x").fromNow());
} else {
timeWrapper.innerHTML = this.capFirst(moment(event.startDate, "x").format(this.config.dateFormat));
timeWrapper.innerHTML = this.capFirst(moment(event.startDate, "x").format(this.config.fullDayEventDateFormat));
}
} else {
timeWrapper.innerHTML = this.capFirst(moment(event.startDate, "x").fromNow());
}
}
if(this.config.showEnd){
timeWrapper.innerHTML += "-" ;
timeWrapper.innerHTML += this.capFirst(moment(event.endDate , "x").format(this.config.fullDayEventDateFormat));
}
} else {
timeWrapper.innerHTML = this.capFirst(
this.translate("RUNNING", {
fallback: this.translate("RUNNING") + " {timeUntilEnd}",
timeUntilEnd: moment(event.endDate, "x").fromNow(true)
})
);
if (event.startDate >= new Date()) {
if (event.startDate - now < 2 * oneDay) {
// This event is within the next 48 hours (2 days)
if (event.startDate - now < this.config.getRelative * oneHour) {
// If event is within 6 hour, display 'in xxx' time format or moment.fromNow()
timeWrapper.innerHTML = this.capFirst(moment(event.startDate, "x").fromNow());
} else {
if(this.config.timeFormat === "absolute") {
timeWrapper.innerHTML = this.capFirst(moment(event.startDate, "x").format(this.config.dateFormat));
} else {
// Otherwise just say 'Today/Tomorrow at such-n-such time'
timeWrapper.innerHTML = this.capFirst(moment(event.startDate, "x").calendar());
}
}
} else {
/* Check to see if the user displays absolute or relative dates with their events
* Also check to see if an event is happening within an 'urgency' time frameElement
* For example, if the user set an .urgency of 7 days, those events that fall within that
* time frame will be displayed with 'in xxx' time format or moment.fromNow()
*
* Note: this needs to be put in its own function, as the whole thing repeats again verbatim
*/
if (this.config.timeFormat === "absolute") {
if ((this.config.urgency > 1) && (event.startDate - now < (this.config.urgency * oneDay))) {
// This event falls within the config.urgency period that the user has set
timeWrapper.innerHTML = this.capFirst(moment(event.startDate, "x").fromNow());
} else {
timeWrapper.innerHTML = this.capFirst(moment(event.startDate, "x").format(this.config.dateFormat));
}
} else {
timeWrapper.innerHTML = this.capFirst(moment(event.startDate, "x").fromNow());
}
}
} else {
timeWrapper.innerHTML = this.capFirst(
this.translate("RUNNING", {
fallback: this.translate("RUNNING") + " {timeUntilEnd}",
timeUntilEnd: moment(event.endDate, "x").fromNow(true)
})
);
}
if (this.config.showEnd) {
timeWrapper.innerHTML += "-";
timeWrapper.innerHTML += this.capFirst(moment(event.endDate, "x").format(this.config.dateEndFormat));
}
}
//timeWrapper.innerHTML += ' - '+ moment(event.startDate,'x').format('lll');
//console.log(event);
timeWrapper.className = "time light";
eventWrapper.appendChild(timeWrapper);
}
//timeWrapper.innerHTML += ' - '+ moment(event.startDate,'x').format('lll');
//console.log(event);
timeWrapper.className = "time light";
eventWrapper.appendChild(timeWrapper);
wrapper.appendChild(eventWrapper);
@@ -320,6 +366,31 @@ Module.register("calendar", {
return wrapper;
},
/**
* This function accepts a number (either 12 or 24) and returns a moment.js LocaleSpecification with the
* corresponding timeformat to be used in the calendar display. If no number is given (or otherwise invalid input)
* it will a localeSpecification object with the system locale time format.
*
* @param {number} timeFormat Specifies either 12 or 24 hour time format
* @returns {moment.LocaleSpecification}
*/
getLocaleSpecification: function(timeFormat) {
switch (timeFormat) {
case 12: {
return { longDateFormat: {LT: "h:mm A"} };
break;
}
case 24: {
return { longDateFormat: {LT: "HH:mm"} };
break;
}
default: {
return { longDateFormat: {LT: moment.localeData().longDateFormat("LT")} };
break;
}
}
},
/* hasCalendarURL(url)
* Check if this config contains the calendar url.
*
@@ -346,6 +417,7 @@ Module.register("calendar", {
createEventList: function () {
var events = [];
var today = moment().startOf("day");
var now = new Date();
for (var c in this.calendarData) {
var calendar = this.calendarData[c];
for (var e in calendar) {
@@ -356,6 +428,14 @@ Module.register("calendar", {
continue;
}
}
if(this.config.hideOngoing) {
if(event.startDate < now) {
continue;
}
}
if(this.listContainsEvent(events,event)){
continue;
}
event.url = c;
event.today = event.startDate >= today && event.startDate < (today + 24 * 60 * 60 * 1000);
events.push(event);
@@ -369,6 +449,17 @@ Module.register("calendar", {
return events.slice(0, this.config.maximumEntries);
},
listContainsEvent: function(eventList, event){
for(var evt of eventList){
if(evt.title === event.title && parseInt(evt.startDate) === parseInt(event.startDate)){
return true;
}
}
return false;
},
/* createEventList(url)
* Requests node helper to add calendar url.
*
@@ -377,6 +468,7 @@ Module.register("calendar", {
addCalendar: function (url, auth, calendarConfig) {
this.sendSocketNotification("ADD_CALENDAR", {
url: url,
excludedEvents: calendarConfig.excludedEvents || this.config.excludedEvents,
maximumEntries: calendarConfig.maximumEntries || this.config.maximumEntries,
maximumNumberOfDays: calendarConfig.maximumNumberOfDays || this.config.maximumNumberOfDays,
fetchInterval: this.config.fetchInterval,
@@ -437,25 +529,27 @@ Module.register("calendar", {
return defaultValue;
},
/* shorten(string, maxLength)
* Shortens a string if it's longer than maxLength.
* Adds an ellipsis to the end.
/**
* Shortens a string if it's longer than maxLength and add a ellipsis to the end
*
* argument string string - The string to shorten.
* argument maxLength number - The max length of the string.
* argument wrapEvents - Wrap the text after the line has reached maxLength
*
* return string - The shortened string.
* @param {string} string Text string to shorten
* @param {number} maxLength The max length of the string
* @param {boolean} wrapEvents Wrap the text after the line has reached maxLength
* @returns {string} The shortened string
*/
shorten: function (string, maxLength, wrapEvents) {
if (wrapEvents) {
if (typeof string !== "string") {
return "";
}
if (wrapEvents === true) {
var temp = "";
var currentLine = "";
var words = string.split(" ");
for (var i = 0; i < words.length; i++) {
var word = words[i];
if (currentLine.length + word.length < 25 - 1) { // max - 1 to account for a space
if (currentLine.length + word.length < (typeof maxLength === "number" ? maxLength : 25) - 1) { // max - 1 to account for a space
currentLine += (word + " ");
} else {
if (currentLine.length > 0) {
@@ -467,12 +561,12 @@ Module.register("calendar", {
}
}
return temp + currentLine;
return (temp + currentLine).trim();
} else {
if (string.length > maxLength) {
return string.slice(0, maxLength) + "&hellip;";
if (maxLength && typeof maxLength === "number" && string.length > maxLength) {
return string.trim().slice(0, maxLength) + "&hellip;";
} else {
return string;
return string.trim();
}
}
},
@@ -522,6 +616,8 @@ Module.register("calendar", {
var calendar = this.calendarData[url];
for (var e in calendar) {
var event = cloneObject(calendar[e]);
event.symbol = this.symbolsForUrl(url);
event.color = this.colorForUrl(url);
delete event.url;
eventList.push(event);
}

View File

@@ -8,7 +8,7 @@
var ical = require("./vendor/ical.js");
var moment = require("moment");
var CalendarFetcher = function(url, reloadInterval, maximumEntries, maximumNumberOfDays, auth) {
var CalendarFetcher = function(url, reloadInterval, excludedEvents, maximumEntries, maximumNumberOfDays, auth) {
var self = this;
var reloadTimer = null;
@@ -29,7 +29,8 @@ var CalendarFetcher = function(url, reloadInterval, maximumEntries, maximumNumbe
var opts = {
headers: {
"User-Agent": "Mozilla/5.0 (Node.js "+ nodeVersion + ") MagicMirror/" + global.version + " (https://github.com/MichMich/MagicMirror/)"
}
},
gzip: true
};
if (auth) {
@@ -90,6 +91,9 @@ var CalendarFetcher = function(url, reloadInterval, maximumEntries, maximumNumbe
var endDate;
if (typeof event.end !== "undefined") {
endDate = eventDate(event, "end");
} else if(typeof event.duration !== "undefined") {
dur=moment.duration(event.duration);
endDate = startDate.clone().add(dur);
} else {
if (!isFacebookBirthday) {
endDate = startDate;
@@ -113,6 +117,56 @@ var CalendarFetcher = function(url, reloadInterval, maximumEntries, maximumNumbe
title = event.description;
}
var excluded = false,
dateFilter = null;
for (var f in excludedEvents) {
var filter = excludedEvents[f],
testTitle = title.toLowerCase(),
until = null,
useRegex = false,
regexFlags = "g";
if (filter instanceof Object) {
if (typeof filter.until !== "undefined") {
until = filter.until;
}
if (typeof filter.regex !== "undefined") {
useRegex = filter.regex;
}
// If additional advanced filtering is added in, this section
// must remain last as we overwrite the filter object with the
// filterBy string
if (filter.caseSensitive) {
filter = filter.filterBy;
testTitle = title;
} else if (useRegex) {
filter = filter.filterBy;
testTitle = title;
regexFlags += "i";
} else {
filter = filter.filterBy.toLowerCase();
}
} else {
filter = filter.toLowerCase();
}
if (testTitleByFilter(testTitle, filter, useRegex, regexFlags)) {
if (until) {
dateFilter = until;
} else {
excluded = true;
}
break;
}
}
if (excluded) {
continue;
}
var location = event.location || false;
var geo = event.geo || false;
var description = event.description || false;
@@ -124,6 +178,11 @@ var CalendarFetcher = function(url, reloadInterval, maximumEntries, maximumNumbe
for (var d in dates) {
startDate = moment(new Date(dates[d]));
endDate = moment(parseInt(startDate.format("x")) + duration, "x");
if (timeFilterApplies(now, endDate, dateFilter)) {
continue;
}
if (endDate.format("x") > now) {
newEvents.push({
title: title,
@@ -158,6 +217,10 @@ var CalendarFetcher = function(url, reloadInterval, maximumEntries, maximumNumbe
continue;
}
if (timeFilterApplies(now, endDate, dateFilter)) {
continue;
}
// Every thing is good. Add it to the list.
newEvents.push({
@@ -214,8 +277,7 @@ var CalendarFetcher = function(url, reloadInterval, maximumEntries, maximumNumbe
var start = event.start || 0;
var startDate = new Date(start);
var end = event.end || 0;
if (end - start === 24 * 60 * 60 * 1000 && startDate.getHours() === 0 && startDate.getMinutes() === 0) {
if (((end - start) % (24 * 60 * 60 * 1000)) === 0 && startDate.getHours() === 0 && startDate.getMinutes() === 0) {
// Is 24 hours, and starts on the middle of the night.
return true;
}
@@ -223,6 +285,44 @@ var CalendarFetcher = function(url, reloadInterval, maximumEntries, maximumNumbe
return false;
};
/* timeFilterApplies()
* Determines if the user defined time filter should apply
*
* argument now Date - Date object using previously created object for consistency
* argument endDate Moment - Moment object representing the event end date
* argument filter string - The time to subtract from the end date to determine if an event should be shown
*
* return bool - The event should be filtered out
*/
var timeFilterApplies = function(now, endDate, filter) {
if (filter) {
var until = filter.split(" "),
value = parseInt(until[0]),
increment = until[1].slice("-1") === "s" ? until[1] : until[1] + "s", // Massage the data for moment js
filterUntil = moment(endDate.format()).subtract(value, increment);
return now < filterUntil.format("x");
}
return false;
};
var testTitleByFilter = function (title, filter, useRegex, regexFlags) {
if (useRegex) {
// Assume if leading slash, there is also trailing slash
if (filter[0] === "/") {
// Strip leading and trailing slashes
filter = filter.substr(1).slice(0, -1);
}
filter = new RegExp(filter, regexFlags);
return filter.test(title);
} else {
return title.includes(filter);
}
}
/* public methods */
/* startFetch()

View File

@@ -24,7 +24,7 @@ module.exports = NodeHelper.create({
socketNotificationReceived: function(notification, payload) {
if (notification === "ADD_CALENDAR") {
//console.log('ADD_CALENDAR: ');
this.createFetcher(payload.url, payload.fetchInterval, payload.maximumEntries, payload.maximumNumberOfDays, payload.auth);
this.createFetcher(payload.url, payload.fetchInterval, payload.excludedEvents, payload.maximumEntries, payload.maximumNumberOfDays, payload.auth);
}
},
@@ -36,7 +36,7 @@ module.exports = NodeHelper.create({
* attribute reloadInterval number - Reload interval in milliseconds.
*/
createFetcher: function(url, fetchInterval, maximumEntries, maximumNumberOfDays, auth) {
createFetcher: function(url, fetchInterval, excludedEvents, maximumEntries, maximumNumberOfDays, auth) {
var self = this;
if (!validUrl.isUri(url)) {
@@ -47,7 +47,7 @@ module.exports = NodeHelper.create({
var fetcher;
if (typeof self.fetchers[url] === "undefined") {
console.log("Create new calendar fetcher for url: " + url + " - Interval: " + fetchInterval);
fetcher = new CalendarFetcher(url, fetchInterval, maximumEntries, maximumNumberOfDays, auth);
fetcher = new CalendarFetcher(url, fetchInterval, excludedEvents, maximumEntries, maximumNumberOfDays, auth);
fetcher.onReceive(function(fetcher) {
//console.log('Broadcast events.');

View File

@@ -108,7 +108,7 @@ vows.describe('node-ical').addBatch({
assert.equal(topic.end.getFullYear(), 1998);
assert.equal(topic.end.getUTCMonth(), 2);
assert.equal(topic.end.getUTCDate(), 15);
assert.equal(topic.end.getUTCHours(), 00);
assert.equal(topic.end.getUTCHours(), 0);
assert.equal(topic.end.getUTCMinutes(), 30);
}
}
@@ -146,7 +146,7 @@ vows.describe('node-ical').addBatch({
}
, 'has a start datetime' : function(topic) {
assert.equal(topic.start.getFullYear(), 2011);
assert.equal(topic.start.getMonth(), 09);
assert.equal(topic.start.getMonth(), 9);
assert.equal(topic.start.getDate(), 11);
}
@@ -192,7 +192,7 @@ vows.describe('node-ical').addBatch({
}
, 'has a start' : function(topic){
assert.equal(topic.start.tz, 'America/Phoenix')
assert.equal(topic.start.toISOString(), new Date(2011, 10, 09, 19, 0,0).toISOString())
assert.equal(topic.start.toISOString(), new Date(2011, 10, 9, 19, 0,0).toISOString())
}
}
}
@@ -208,7 +208,7 @@ vows.describe('node-ical').addBatch({
})[0];
}
, 'has a start' : function(topic){
assert.equal(topic.start.toISOString(), new Date(2011, 07, 04, 12, 0,0).toISOString())
assert.equal(topic.start.toISOString(), new Date(2011, 7, 4, 12, 0,0).toISOString())
}
}
, 'event with rrule' :{
@@ -249,7 +249,7 @@ vows.describe('node-ical').addBatch({
},
'task completed': function(task){
assert.equal(task.completion, 100);
assert.equal(task.completed.toISOString(), new Date(2013, 06, 16, 10, 57, 45).toISOString());
assert.equal(task.completed.toISOString(), new Date(2013, 6, 16, 10, 57, 45).toISOString());
}
}
}
@@ -367,7 +367,7 @@ vows.describe('node-ical').addBatch({
assert.equal(topic.end.getFullYear(), 2014);
assert.equal(topic.end.getMonth(), 3);
assert.equal(topic.end.getUTCHours(), 19);
assert.equal(topic.end.getUTCMinutes(), 00);
assert.equal(topic.end.getUTCMinutes(), 0);
}
}
},

View File

@@ -94,7 +94,7 @@ Module.register("clock",{
dateWrapper.innerHTML = now.format(this.config.dateFormat);
}
if (this.config.showWeek) {
weekWrapper.innerHTML = this.translate("WEEK") + " " + now.week();
weekWrapper.innerHTML = this.translate("WEEK", { weekNumber: now.week() });
}
timeWrapper.innerHTML = timeString;
secondsWrapper.innerHTML = now.format("ss");

View File

@@ -1,5 +1,5 @@
.clockCircle {
margin: 0;
margin: 0 auto;
position: relative;
border-radius: 50%;
background-size: 100%;

View File

@@ -30,8 +30,14 @@ The following properties can be configured:
| `updateInterval` | How often does the compliment have to change? (Milliseconds) <br><br> **Possible values:** `1000` - `86400000` <br> **Default value:** `30000` (30 seconds)
| `fadeSpeed` | Speed of the update animation. (Milliseconds) <br><br> **Possible values:**`0` - `5000` <br> **Default value:** `4000` (4 seconds)
| `compliments` | The list of compliments. <br><br> **Possible values:** An object with four arrays: `morning`, `afternoon`, `evening` and `anytime`. See _compliment configuration_ below. <br> **Default value:** See _compliment configuration_ below.
| `remoteFile` | External file from which to load the compliments <br><br> **Possible values:** Path to a JSON file containing compliments, configured as per the value of the _compliments configuration_ (see below). An object with four arrays: `morning`, `afternoon`, `evening` and `anytime`. - `compliments.json` <br> **Default value:** `null` (Do not load from file)
| `remoteFile` | External file from which to load the compliments <br><br> **Possible values:** Path or URL (starting with `http://` or `https://`) to a JSON file containing compliments, configured as per the value of the _compliments configuration_ (see below). An object with four arrays: `morning`, `afternoon`, `evening` and `anytime`. - `compliments.json` <br> **Default value:** `null` (Do not load from file)
| `classes` | Override the CSS classes of the div showing the compliments <br><br> **Default value:** `thin xlarge bright`
| `morningStartTime` | Time in hours (in 24 format), after which the mode of "morning" will begin <br> **Possible values:** `0` - `24` <br><br> **Default value:** `3`
| `morningEndTime` | Time in hours (in 24 format), after which the mode of "morning" will end <br> **Possible values:** `0` - `24` <br><br> **Default value:** `12`
| `afternoonStartTime` | Time in hours (in 24 format), after which the mode "afternoon" will begin <br> **Possible values:** `0` - `24` <br><br> **Default value:** `12`
| `afternoonEndTime` | Time in hours (in 24 format), after which the mode "afternoon" will end <br> **Possible values:** `0` - `24` <br><br> **Default value:** `17`
All the rest of the time that does not fall into the morningStartTime-morningEndTime and afternoonStartTime-afternoonEndTime ranges is considered "evening".
### Compliment configuration
@@ -101,6 +107,13 @@ config: {
}
````
#### Multi-line compliments:
Use `\n` to split compliment text into multiple lines, e.g. `First line.\nSecond line.` will be shown as:
```
First line.
Second line.
```
### External Compliment File
You may specify an external file that contains the three compliment arrays. This is particularly useful if you have a
large number of compliments and do not wish to crowd your `config.js` file with a large array of compliments.

View File

@@ -32,7 +32,11 @@ Module.register("compliments", {
},
updateInterval: 30000,
remoteFile: null,
fadeSpeed: 4000
fadeSpeed: 4000,
morningStartTime: 3,
morningEndTime: 12,
afternoonStartTime: 12,
afternoonEndTime: 17
},
// Set currentweather from module
@@ -49,14 +53,15 @@ Module.register("compliments", {
this.lastComplimentIndex = -1;
var self = this;
if (this.config.remoteFile != null) {
this.complimentFile((response) => {
this.config.compliments = JSON.parse(response);
this.complimentFile(function(response) {
self.config.compliments = JSON.parse(response);
self.updateDom();
});
}
// Schedule update timer.
var self = this;
setInterval(function() {
self.updateDom(self.config.fadeSpeed);
}, this.config.updateInterval);
@@ -98,9 +103,9 @@ Module.register("compliments", {
var hour = moment().hour();
var compliments;
if (hour >= 3 && hour < 12 && this.config.compliments.hasOwnProperty("morning")) {
if (hour >= this.config.morningStartTime && hour < this.config.morningEndTime && this.config.compliments.hasOwnProperty("morning")) {
compliments = this.config.compliments.morning.slice(0);
} else if (hour >= 12 && hour < 17 && this.config.compliments.hasOwnProperty("afternoon")) {
} else if (hour >= this.config.afternoonStartTime && hour < this.config.afternoonEndTime && this.config.compliments.hasOwnProperty("afternoon")) {
compliments = this.config.compliments.afternoon.slice(0);
} else if(this.config.compliments.hasOwnProperty("evening")) {
compliments = this.config.compliments.evening.slice(0);
@@ -123,9 +128,11 @@ Module.register("compliments", {
* Retrieve a file from the local filesystem
*/
complimentFile: function(callback) {
var xobj = new XMLHttpRequest();
var xobj = new XMLHttpRequest(),
isRemote = this.config.remoteFile.indexOf("http://") === 0 || this.config.remoteFile.indexOf("https://") === 0,
path = isRemote ? this.config.remoteFile : this.file(this.config.remoteFile);
xobj.overrideMimeType("application/json");
xobj.open("GET", this.file(this.config.remoteFile), true);
xobj.open("GET", path, true);
xobj.onreadystatechange = function() {
if (xobj.readyState == 4 && xobj.status == "200") {
callback(xobj.responseText);
@@ -152,7 +159,7 @@ Module.register("compliments", {
var compliment = document.createTextNode(complimentText);
var wrapper = document.createElement("div");
wrapper.className = this.config.classes ? this.config.classes : "thin xlarge bright";
wrapper.className = this.config.classes ? this.config.classes : "thin xlarge bright pre-line";
wrapper.appendChild(compliment);
return wrapper;
@@ -192,4 +199,4 @@ Module.register("compliments", {
}
},
});
});

View File

@@ -43,9 +43,12 @@ The following properties can be configured:
| `showWindDirectionAsArrow` | Show the wind direction as an arrow instead of abbreviation <br><br> **Possible values:** `true` or `false` <br> **Default value:** `false`
| `showHumidity` | Show the current humidity <br><br> **Possible values:** `true` or `false` <br> **Default value:** `false`
| `showIndoorTemperature` | If you have another module that emits the INDOOR_TEMPERATURE notification, the indoor temperature will be displayed <br> **Default value:** `false`
| `onlyTemp` | Show only current Temperature and weather icon. <br><br> **Possible values:** `true` or `false` <br> **Default value:** `false`
| `onlyTemp` | Show only current Temperature and weather icon without windspeed, sunset, sunrise time and feels like. <br><br> **Possible values:** `true` or `false` <br> **Default value:** `false`
| `showFeelsLike` | Shows the Feels like temperature weather. <br><br> **Possible values:**`true` or `false`<br>**Default value:** `true`
| `useKMPHWind` | Uses KMPH as units for windspeed. <br><br> **Possible values:**`true` or `false`<br>**Default value:** `false`
| `useBeaufort` | Pick between using the Beaufort scale for wind speed or using the default units. <br><br> **Possible values:** `true` or `false` <br> **Default value:** `true`
| `lang` | The language of the days. <br><br> **Possible values:** `en`, `nl`, `ru`, etc ... <br> **Default value:** uses value of _config.language_
| `decimalSymbol` | The decimal symbol to use.<br><br> **Possible values:** `.`, `,` or any other symbol.<br> **Default value:** `.`
| `initialLoadDelay` | The initial delay before loading. If you have multiple modules that use the same API key, you might want to delay one of the requests. (Milliseconds) <br><br> **Possible values:** `1000` - `5000` <br> **Default value:** `0`
| `retryDelay` | The delay before retrying after a request failure. (Milliseconds) <br><br> **Possible values:** `1000` - `60000` <br> **Default value:** `2500`
| `apiVersion` | The OpenWeatherMap API version to use. <br><br> **Default value:** `2.5`

View File

@@ -23,16 +23,20 @@ Module.register("currentweather",{
showWindDirection: true,
showWindDirectionAsArrow: false,
useBeaufort: true,
useKMPHwind: false,
lang: config.language,
decimalSymbol: ".",
showHumidity: false,
degreeLabel: false,
showIndoorTemperature: false,
showIndoorHumidity: false,
showFeelsLike: true,
initialLoadDelay: 0, // 0 seconds delay
retryDelay: 2500,
apiVersion: "2.5",
apiBase: "http://api.openweathermap.org/data/",
apiBase: "https://api.openweathermap.org/data/",
weatherEndpoint: "weather",
appendLocationNameToHeader: true,
@@ -63,7 +67,7 @@ Module.register("currentweather",{
},
},
// create a variable for the first upcoming calendaar event. Used if no location is specified.
// create a variable for the first upcoming calendar event. Used if no location is specified.
firstEvent: false,
// create a variable to hold the location name based on the API result.
@@ -83,7 +87,7 @@ Module.register("currentweather",{
getTranslations: function() {
// The translations for the default modules are defined in the core translation files.
// Therefor we can just return false. Otherwise we should have returned a dictionary.
// If you're trying to build yiur own module including translations, check out the documentation.
// If you're trying to build your own module including translations, check out the documentation.
return false;
},
@@ -101,8 +105,9 @@ Module.register("currentweather",{
this.sunriseSunsetIcon = null;
this.temperature = null;
this.indoorTemperature = null;
this.indoorHumidity = null;
this.weatherType = null;
this.feelsLike = null;
this.loaded = false;
this.scheduleUpdate(this.config.initialLoadDelay);
@@ -207,9 +212,13 @@ Module.register("currentweather",{
}
}
if (this.config.decimalSymbol === "") {
this.config.decimalSymbol = ".";
}
var temperature = document.createElement("span");
temperature.className = "bright";
temperature.innerHTML = " " + this.temperature + "&deg;" + degreeLabel;
temperature.innerHTML = " " + this.temperature.replace(".", this.config.decimalSymbol) + "&deg;" + degreeLabel;
large.appendChild(temperature);
if (this.config.showIndoorTemperature && this.indoorTemperature) {
@@ -219,11 +228,35 @@ Module.register("currentweather",{
var indoorTemperatureElem = document.createElement("span");
indoorTemperatureElem.className = "bright";
indoorTemperatureElem.innerHTML = " " + this.indoorTemperature + "&deg;" + degreeLabel;
indoorTemperatureElem.innerHTML = " " + this.indoorTemperature.replace(".", this.config.decimalSymbol) + "&deg;" + degreeLabel;
large.appendChild(indoorTemperatureElem);
}
if (this.config.showIndoorHumidity && this.indoorHumidity) {
var indoorHumidityIcon = document.createElement("span");
indoorHumidityIcon.className = "fa fa-tint";
large.appendChild(indoorHumidityIcon);
var indoorHumidityElem = document.createElement("span");
indoorHumidityElem.className = "bright";
indoorHumidityElem.innerHTML = " " + this.indoorHumidity + "%";
large.appendChild(indoorHumidityElem);
}
wrapper.appendChild(large);
if (this.config.showFeelsLike && this.config.onlyTemp === false){
var small = document.createElement("div");
small.className = "normal medium";
var feelsLike = document.createElement("span");
feelsLike.className = "dimmed";
feelsLike.innerHTML = this.translate("FEELS") + " " + this.feelsLike + "&deg;" + degreeLabel;
small.appendChild(feelsLike);
wrapper.appendChild(small);
}
return wrapper;
},
@@ -260,7 +293,11 @@ Module.register("currentweather",{
}
if (notification === "INDOOR_TEMPERATURE") {
this.indoorTemperature = this.roundValue(payload);
this.updateDom(self.config.animationSpeed);
this.updateDom(this.config.animationSpeed);
}
if (notification === "INDOOR_HUMIDITY") {
this.indoorHumidity = this.roundValue(payload);
this.updateDom(this.config.animationSpeed);
}
},
@@ -343,13 +380,71 @@ Module.register("currentweather",{
this.humidity = parseFloat(data.main.humidity);
this.temperature = this.roundValue(data.main.temp);
this.feelsLike = 0;
if (this.config.useBeaufort){
this.windSpeed = this.ms2Beaufort(this.roundValue(data.wind.speed));
} else if (this.config.useKMPHwind) {
this.windSpeed = parseFloat((data.wind.speed * 60 * 60) / 1000).toFixed(0);
} else {
this.windSpeed = parseFloat(data.wind.speed).toFixed(0);
}
// ONLY WORKS IF TEMP IN C //
var windInMph = parseFloat(data.wind.speed * 2.23694);
var tempInF = 0;
switch (this.config.units){
case "metric": tempInF = 1.8 * this.temperature + 32;
break;
case "imperial": tempInF = this.temperature;
break;
case "default":
var tc = this.temperature - 273.15;
tempInF = 1.8 * tc + 32;
break;
}
if (windInMph > 3 && tempInF < 50){
// windchill
var windChillInF = Math.round(35.74+0.6215*tempInF-35.75*Math.pow(windInMph,0.16)+0.4275*tempInF*Math.pow(windInMph,0.16));
var windChillInC = (windChillInF - 32) * (5/9);
// this.feelsLike = windChillInC.toFixed(0);
switch (this.config.units){
case "metric": this.feelsLike = windChillInC.toFixed(0);
break;
case "imperial": this.feelsLike = windChillInF.toFixed(0);
break;
case "default":
var tc = windChillInC + 273.15;
this.feelsLike = tc.toFixed(0);
break;
}
} else if (tempInF > 80 && this.humidity > 40){
// heat index
var Hindex = -42.379 + 2.04901523*tempInF + 10.14333127*this.humidity
- 0.22475541*tempInF*this.humidity - 6.83783*Math.pow(10,-3)*tempInF*tempInF
- 5.481717*Math.pow(10,-2)*this.humidity*this.humidity
+ 1.22874*Math.pow(10,-3)*tempInF*tempInF*this.humidity
+ 8.5282*Math.pow(10,-4)*tempInF*this.humidity*this.humidity
- 1.99*Math.pow(10,-6)*tempInF*tempInF*this.humidity*this.humidity;
switch (this.config.units){
case "metric": this.feelsLike = parseFloat((Hindex - 32) / 1.8).toFixed(0);
break;
case "imperial": this.feelsLike = Hindex.toFixed(0);
break;
case "default":
var tc = parseFloat((Hindex - 32) / 1.8) + 273.15;
this.feelsLike = tc.toFixed(0);
break;
}
} else {
this.feelsLike = parseFloat(this.temperature).toFixed(0);
}
this.windDirection = this.deg2Cardinal(data.wind.deg);
this.windDeg = data.wind.deg;
this.weatherType = this.config.iconTable[data.weather[0].icon];
@@ -469,10 +564,11 @@ Module.register("currentweather",{
*
* argument temperature number - Temperature.
*
* return number - Rounded Temperature.
* return string - Rounded Temperature.
*/
roundValue: function(temperature) {
var decimals = this.config.roundTemp ? 0 : 1;
return parseFloat(temperature).toFixed(decimals);
}
});

View File

@@ -14,10 +14,11 @@ Module.register("helloworld",{
text: "Hello World!"
},
// Override dom generator.
getDom: function() {
var wrapper = document.createElement("div");
wrapper.innerHTML = this.config.text;
return wrapper;
getTemplate: function () {
return "helloworld.njk"
},
getTemplateData: function () {
return this.config
}
});

View File

@@ -0,0 +1,5 @@
<!--
Use ` | safe` to allow html tages within the text string.
https://mozilla.github.io/nunjucks/templating.html#autoescaping
-->
<div>{{text | safe}}</div>

View File

@@ -39,8 +39,9 @@ MagicMirror's [notification mechanism](https://github.com/MichMich/MagicMirror/t
| ----------------------- | -----------
| `ARTICLE_NEXT` | Shows the next news title (hiding the summary or previously fully displayed article)
| `ARTICLE_PREVIOUS` | Shows the previous news title (hiding the summary or previously fully displayed article)
| `ARTICLE_MORE_DETAILS` | When received the _first time_, shows the corresponding description of the currently displayed news title. <br> The module expects that the module's configuration option `showDescription` is set to `false` (default value). <br><br> When received a _second consecutive time_, shows the full news article in an IFRAME. <br> This requires that the news page can be embedded in an IFRAME, e.g. doesn't have the HTTP response header [X-Frame-Options](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options) set to e.g. `DENY`.
| `ARTICLE_MORE_DETAILS` | When received the _first time_, shows the corresponding description of the currently displayed news title. <br> The module expects that the module's configuration option `showDescription` is set to `false` (default value). <br><br> When received a _second consecutive time_, shows the full news article in an IFRAME. <br> This requires that the news page can be embedded in an IFRAME, e.g. doesn't have the HTTP response header [X-Frame-Options](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options) set to e.g. `DENY`.<br><br>When received the _next consecutive times_, reloads the page and scrolls down by `scrollLength` pixels to paginate through the article.
| `ARTICLE_LESS_DETAILS` | Hides the summary or full news article and only displays the news title of the currently viewed news item.
| `ARTICLE_TOGGLE_FULL` | Toogles article in fullscreen.
Note the payload of the sent notification event is ignored.
@@ -57,25 +58,30 @@ The third party [MMM-Gestures](https://github.com/thobach/MMM-Gestures) module s
The following properties can be configured:
| Option | Description
| ----------------- | -----------
| `feeds` | An array of feed urls that will be used as source. <br> More info about this object can be found below. <br> **Default value:** `[{ title: "New York Times", url: "http://www.nytimes.com/services/xml/rss/nyt/HomePage.xml", encoding: "UTF-8" }]`
| `showSourceTitle` | Display the title of the source. <br><br> **Possible values:** `true` or `false` <br> **Default value:** `true`
| `showPublishDate` | Display the publish date of an headline. <br><br> **Possible values:** `true` or `false` <br> **Default value:** `true`
| `showDescription` | Display the description of an item. <br><br> **Possible values:** `true` or `false` <br> **Default value:** `false`
| `wrapTitle` | Wrap the title of the item to multiple lines. <br><br> **Possible values:** `true` or `false` <br> **Default value:** `true`
| `wrapDescription` | Wrap the description of the item to multiple lines. <br><br> **Possible values:** `true` or `false` <br> **Default value:** `true`
| `hideLoading` | Hide module instead of showing LOADING status. <br><br> **Possible values:** `true` or `false` <br> **Default value:** `false`
| `reloadInterval` | How often does the content needs to be fetched? (Milliseconds) <br><br> **Possible values:** `1000` - `86400000` <br> **Default value:** `300000` (5 minutes)
| `updateInterval` | How often do you want to display a new headline? (Milliseconds) <br><br> **Possible values:**`1000` - `60000` <br> **Default value:** `10000` (10 seconds)
| `animationSpeed` | Speed of the update animation. (Milliseconds) <br><br> **Possible values:**`0` - `5000` <br> **Default value:** `2500` (2.5 seconds)
| `maxNewsItems` | Total amount of news items to cycle through. (0 for unlimited) <br><br> **Possible values:**`0` - `...` <br> **Default value:** `0`
| `ignoreOldItems` | Ignore news items that are outdated. <br><br> **Possible values:**`true` or `false <br> **Default value:** `false`
| `ignoreOlderThan` | How old should news items be before they are considered outdated? (Milliseconds) <br><br> **Possible values:**`1` - `...` <br> **Default value:** `86400000` (1 day)
| `removeStartTags` | Some newsfeeds feature tags at the **beginning** of their titles or descriptions, such as _[VIDEO]_. This setting allows for the removal of specified tags from the beginning of an item's description and/or title. <br><br> **Possible values:**`'title'`, `'description'`, `'both'`
| `startTags` | List the tags you would like to have removed at the beginning of the feed item <br><br> **Possible values:** `['TAG']` or `['TAG1','TAG2',...]`
| `removeEndTags` | Remove specified tags from the **end** of an item's description and/or title. <br><br> **Possible values:**`'title'`, `'description'`, `'both'`
| `endTags` | List the tags you would like to have removed at the end of the feed item <br><br> **Possible values:** `['TAG']` or `['TAG1','TAG2',...]`
| Option | Description
| ------------------ | -----------
| `feeds` | An array of feed urls that will be used as source. <br> More info about this object can be found below. <br> **Default value:** `[{ title: "New York Times", url: "http://www.nytimes.com/services/xml/rss/nyt/HomePage.xml", encoding: "UTF-8" }]`<br>You can add `reloadInterval` option to set particular reloadInterval to a feed.
| `showSourceTitle` | Display the title of the source. <br><br> **Possible values:** `true` or `false` <br> **Default value:** `true`
| `showPublishDate` | Display the publish date of an headline. <br><br> **Possible values:** `true` or `false` <br> **Default value:** `true`
| `showDescription` | Display the description of an item. <br><br> **Possible values:** `true` or `false` <br> **Default value:** `false`
| `wrapTitle` | Wrap the title of the item to multiple lines. <br><br> **Possible values:** `true` or `false` <br> **Default value:** `true`
| `wrapDescription` | Wrap the description of the item to multiple lines. <br><br> **Possible values:** `true` or `false` <br> **Default value:** `true`
| `truncDescription` | Truncate description? <br><br> **Possible values:** `true` or `false` <br> **Default value:** `true`
| `lengthDescription`| How many characters to be displayed for a truncated description? <br><br> **Possible values:** `1` - `500` <br> **Default value:** `400`
| `hideLoading` | Hide module instead of showing LOADING status. <br><br> **Possible values:** `true` or `false` <br> **Default value:** `false`
| `reloadInterval` | How often does the content needs to be fetched? (Milliseconds) <br><br> **Possible values:** `1000` - `86400000` <br> **Default value:** `300000` (5 minutes)
| `updateInterval` | How often do you want to display a new headline? (Milliseconds) <br><br> **Possible values:**`1000` - `60000` <br> **Default value:** `10000` (10 seconds)
| `animationSpeed` | Speed of the update animation. (Milliseconds) <br><br> **Possible values:**`0` - `5000` <br> **Default value:** `2500` (2.5 seconds)
| `maxNewsItems` | Total amount of news items to cycle through. (0 for unlimited) <br><br> **Possible values:**`0` - `...` <br> **Default value:** `0`
| `ignoreOldItems` | Ignore news items that are outdated. <br><br> **Possible values:**`true` or `false` <br> **Default value:** `false`
| `ignoreOlderThan` | How old should news items be before they are considered outdated? (Milliseconds) <br><br> **Possible values:**`1` - `...` <br> **Default value:** `86400000` (1 day)
| `removeStartTags` | Some newsfeeds feature tags at the **beginning** of their titles or descriptions, such as _[VIDEO]_. This setting allows for the removal of specified tags from the beginning of an item's description and/or title. <br><br> **Possible values:**`'title'`, `'description'`, `'both'`
| `startTags` | List the tags you would like to have removed at the beginning of the feed item <br><br> **Possible values:** `['TAG']` or `['TAG1','TAG2',...]`
| `removeEndTags` | Remove specified tags from the **end** of an item's description and/or title. <br><br> **Possible values:**`'title'`, `'description'`, `'both'`
| `endTags` | List the tags you would like to have removed at the end of the feed item <br><br> **Possible values:** `['TAG']` or `['TAG1','TAG2',...]`
| `prohibitedWords` | Remove news feed item if one of these words is found anywhere in the title (case insensitive and greedy matching) <br><br> **Possible values:** `['word']` or `['word1','word2',...]`
| `scrollLength` | Scrolls the full news article page by a given number of pixels when a `ARTICLE_MORE_DETAILS` notification is received and the full news article is already displayed.<br><br> **Possible values:** `1` or `10000` <br> **Default value:** `500`
| `logFeedWarnings` | Log warnings when there is an error parsing a news article. <br><br> **Possible values:** `true` or `false` <br> **Default value:** `false`
The `feeds` property contains an array with multiple objects. These objects have the following properties:

View File

@@ -14,9 +14,10 @@ var iconv = require("iconv-lite");
*
* attribute url string - URL of the news feed.
* attribute reloadInterval number - Reload interval in milliseconds.
* attribute logFeedWarnings boolean - Log warnings when there is an error parsing a news article.
*/
var Fetcher = function(url, reloadInterval, encoding) {
var Fetcher = function(url, reloadInterval, encoding, logFeedWarnings) {
var self = this;
if (reloadInterval < 1000) {
reloadInterval = 1000;
@@ -45,13 +46,13 @@ var Fetcher = function(url, reloadInterval, encoding) {
var title = item.title;
var description = item.description || item.summary || item.content || "";
var pubdate = item.pubdate || item.published || item.updated;
var pubdate = item.pubdate || item.published || item.updated || item["dc:date"];
var url = item.url || item.link || "";
if (title && pubdate) {
var regex = /(<([^>]+)>)/ig;
description = description.replace(regex, "");
description = description.toString().replace(regex, "");
items.push({
title: title,
@@ -60,18 +61,17 @@ var Fetcher = function(url, reloadInterval, encoding) {
url: url,
});
} else {
// console.log("Can't parse feed item:");
// console.log(item);
// console.log('Title: ' + title);
// console.log('Description: ' + description);
// console.log('Pubdate: ' + pubdate);
} else if (logFeedWarnings) {
console.log("Can't parse feed item:");
console.log(item);
console.log("Title: " + title);
console.log("Description: " + description);
console.log("Pubdate: " + pubdate);
}
});
parser.on("end", function() {
parser.on("end", function() {
//console.log("end parsing - " + url);
self.broadcastItems();
scheduleTimer();
});
@@ -83,7 +83,9 @@ var Fetcher = function(url, reloadInterval, encoding) {
nodeVersion = Number(process.version.match(/^v(\d+\.\d+)/)[1]);
headers = {"User-Agent": "Mozilla/5.0 (Node.js "+ nodeVersion + ") MagicMirror/" + global.version + " (https://github.com/MichMich/MagicMirror/)"}
headers = {"User-Agent": "Mozilla/5.0 (Node.js "+ nodeVersion + ") MagicMirror/" + global.version + " (https://github.com/MichMich/MagicMirror/)",
"Cache-Control": "max-age=0, no-cache, no-store, must-revalidate",
"Pragma": "no-cache"}
request({uri: url, encoding: null, headers: headers})
.on("error", function(error) {

Some files were not shown because too many files have changed in this diff Show More