mirror of
https://github.com/Tautulli/Tautulli.git
synced 2025-03-12 04:35:40 -07:00
Rename Tautulli android app to remote app
This commit is contained in:
parent
bde2372d90
commit
741f3d836a
data/interfaces/default
plexpy
@ -3888,16 +3888,15 @@ a:hover .overlay-refresh-image:hover {
|
||||
#changelog-modal ul {
|
||||
padding-left: 20px;
|
||||
}
|
||||
.google-play-badge {
|
||||
display:inline-block;
|
||||
height:45px;
|
||||
margin-top: 10px;
|
||||
.app-badge {
|
||||
float: left;
|
||||
display: inline-block;
|
||||
height: 46px;
|
||||
margin-right: 10px;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
.google-play-badge img {
|
||||
border: 1px solid #3B3B3B;
|
||||
border-radius: 6px;
|
||||
box-sizing: border-box;
|
||||
height: 45px;
|
||||
.app-badge img {
|
||||
height: 46px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
|
Binary file not shown.
Before ![]() (image error) Size: 20 KiB |
113
data/interfaces/default/images/google-play-badge.svg
Normal file
113
data/interfaces/default/images/google-play-badge.svg
Normal file
@ -0,0 +1,113 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 23.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [
|
||||
<!ENTITY ns_extend "http://ns.adobe.com/Extensibility/1.0/">
|
||||
<!ENTITY ns_ai "http://ns.adobe.com/AdobeIllustrator/10.0/">
|
||||
<!ENTITY ns_graphs "http://ns.adobe.com/Graphs/1.0/">
|
||||
<!ENTITY ns_vars "http://ns.adobe.com/Variables/1.0/">
|
||||
<!ENTITY ns_imrep "http://ns.adobe.com/ImageReplacement/1.0/">
|
||||
<!ENTITY ns_sfw "http://ns.adobe.com/SaveForWeb/1.0/">
|
||||
<!ENTITY ns_custom "http://ns.adobe.com/GenericCustomNamespace/1.0/">
|
||||
<!ENTITY ns_adobe_xpath "http://ns.adobe.com/XPath/1.0/">
|
||||
]>
|
||||
<svg version="1.1" id="Livello_1" xmlns:x="&ns_extend;" xmlns:i="&ns_ai;" xmlns:graph="&ns_graphs;"
|
||||
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 5435.8 1604"
|
||||
style="enable-background:new 0 0 5435.8 1604;" xml:space="preserve">
|
||||
<style type="text/css">
|
||||
.st0{fill-rule:evenodd;clip-rule:evenodd;}
|
||||
.st1{fill-rule:evenodd;clip-rule:evenodd;fill:#A6A6A6;}
|
||||
.st2{fill:#FFFFFF;}
|
||||
.st3{fill-rule:evenodd;clip-rule:evenodd;fill:#FFFFFF;}
|
||||
.st4{fill-rule:evenodd;clip-rule:evenodd;fill:url(#SVGID_1_);}
|
||||
.st5{fill-rule:evenodd;clip-rule:evenodd;fill:url(#SVGID_2_);}
|
||||
.st6{fill-rule:evenodd;clip-rule:evenodd;fill:url(#SVGID_3_);}
|
||||
.st7{fill-rule:evenodd;clip-rule:evenodd;fill:url(#SVGID_4_);}
|
||||
.st8{opacity:0.2;fill-rule:evenodd;clip-rule:evenodd;enable-background:new ;}
|
||||
.st9{opacity:0.12;fill-rule:evenodd;clip-rule:evenodd;enable-background:new ;}
|
||||
.st10{opacity:0.25;fill-rule:evenodd;clip-rule:evenodd;fill:#FFFFFF;enable-background:new ;}
|
||||
</style>
|
||||
<metadata>
|
||||
<sfw xmlns="&ns_sfw;">
|
||||
<slices></slices>
|
||||
<sliceSourceBounds bottomLeftOrigin="true" height="1604" width="5435.8" x="-2656.9" y="-784"></sliceSourceBounds>
|
||||
</sfw>
|
||||
</metadata>
|
||||
<path class="st0" d="M5234.4,1604h-5033C90.4,1604,0,1513.6,0,1403.5v-1203C0,90,90.4,0,201.4,0h5033c110.9,0,201.4,90,201.4,200.5
|
||||
v1203C5435.8,1513.6,5345.3,1604,5234.4,1604z"/>
|
||||
<path class="st1" d="M5234.4,32.1c93.1,0,169.3,75.7,169.3,168.4v1203c0,92.7-75.7,168.4-169.3,168.4h-5033
|
||||
c-93.1,0-169.3-75.7-169.3-168.4v-1203c0-92.7,75.7-168.4,169.3-168.4C201.4,32.1,5234.4,32.1,5234.4,32.1z M5234.4,0h-5033
|
||||
C90.4,0,0,90.4,0,200.5v1203C0,1514,90.4,1604,201.4,1604h5033c110.9,0,201.4-90,201.4-200.5v-1203C5435.8,90.4,5345.3,0,5234.4,0z"
|
||||
/>
|
||||
<path class="st2" d="M2863.6,530.6c-36.3,0-66.9-12.7-91.1-37.7c-24-24.3-37.4-57.8-36.8-92c0-36.5,12.4-67.4,36.8-91.9
|
||||
c24.1-25,54.7-37.7,91-37.7c35.9,0,66.5,12.7,91.1,37.7c24.4,25.3,36.8,56.2,36.8,91.9c-0.4,36.6-12.8,67.5-36.8,91.9
|
||||
C2930.5,518,2899.9,530.6,2863.6,530.6z M1783.5,530.6c-35.5,0-66.3-12.5-91.5-37.2c-25-24.6-37.7-55.7-37.7-92.4
|
||||
s12.7-67.8,37.7-92.4c24.7-24.7,55.5-37.2,91.5-37.2c17.6,0,34.7,3.5,51.1,10.6c16.1,6.9,29.2,16.3,38.9,27.8l2.4,2.9l-27.1,26.6
|
||||
l-2.8-3.3c-15.3-18.2-35.8-27.1-62.9-27.1c-24.2,0-45.3,8.6-62.7,25.6c-17.5,17.1-26.4,39.5-26.4,66.6s8.9,49.5,26.4,66.6
|
||||
c17.4,17,38.5,25.6,62.7,25.6c25.8,0,47.5-8.6,64.4-25.6c10-10,16.2-24,18.4-41.7h-86.9v-37.4h124.2l0.5,3.4
|
||||
c0.9,6.3,1.8,12.8,1.8,18.8c0,34.5-10.4,62.4-31,83C1851.1,518.2,1820.5,530.6,1783.5,530.6z M3219.6,525.3h-38.3L3064,337.6l1,33.8
|
||||
v153.8h-38.3V276.7h43.7l1.2,1.9l110.3,176.8l-1-33.7V276.7h38.7V525.3z M2575.8,525.3H2537V314.1h-67.3v-37.4H2643v37.4h-67.3
|
||||
V525.3z M2438.1,525.3h-38.7V276.7h38.7V525.3z M2220.6,525.3h-38.7V314.1h-67.3v-37.4h173.3v37.4h-67.3V525.3z M2090.1,524.9
|
||||
h-148.4V276.7h148.4v37.4h-109.6v68.2h98.9v37h-98.9v68.2h109.6V524.9z M2800.9,467.2c17.3,17.3,38.3,26,62.7,26
|
||||
c25.1,0,45.6-8.5,62.7-26c17-17,25.6-39.3,25.6-66.2s-8.6-49.3-25.5-66.2c-17.3-17.3-38.4-26-62.7-26c-25.1,0-45.6,8.5-62.6,26
|
||||
c-17,17-25.6,39.3-25.6,66.2S2784,450.3,2800.9,467.2L2800.9,467.2z"/>
|
||||
<path class="st3" d="M2732.1,872.4c-94.5,0-171.1,71.7-171.1,170.6c0,98,77.1,170.6,171.1,170.6c94.5,0,171.1-72.2,171.1-170.6
|
||||
C2903.2,944.1,2826.6,872.4,2732.1,872.4z M2732.1,1146c-51.7,0-96.2-42.8-96.2-103.4c0-61.5,44.6-103.4,96.2-103.4
|
||||
c51.7,0,96.2,41.9,96.2,103.4C2828.4,1103.6,2783.8,1146,2732.1,1146z M2358.8,872.4c-94.5,0-171.1,71.7-171.1,170.6
|
||||
c0,98,77.1,170.6,171.1,170.6c94.5,0,171.1-72.2,171.1-170.6C2529.9,944.1,2453.2,872.4,2358.8,872.4z M2358.8,1146
|
||||
c-51.7,0-96.2-42.8-96.2-103.4c0-61.5,44.6-103.4,96.2-103.4c51.7,0,96.2,41.9,96.2,103.4C2455,1103.6,2410.5,1146,2358.8,1146z
|
||||
M1914.6,924.5v72.2h173.3c-5.3,40.5-18.7,70.4-39.2,90.9c-25.4,25.4-64.6,53-133.7,53c-106.5,0-189.8-86-189.8-192.5
|
||||
s83.3-192.5,189.8-192.5c57.5,0,99.4,22.7,130.5,51.7l51.2-51.2c-43.2-41.4-100.7-73.1-181.3-73.1c-146.1,0-268.7,119-268.7,264.7
|
||||
c0,146.1,122.5,264.7,268.7,264.7c78.9,0,138.1-25.8,184.9-74.4c47.7-47.7,62.8-115,62.8-169.3c0-16.9-1.3-32.1-4-45h-244.6
|
||||
C1914.6,923.6,1914.6,924.5,1914.6,924.5z M3731.5,980.7c-14.3-38.3-57.5-108.7-146.1-108.7c-87.8,0-160.8,69.1-160.8,170.6
|
||||
c0,95.8,72.2,170.6,169.3,170.6c78,0,123.4-47.7,142.1-75.7l-57.9-38.8c-19.2,28.5-45.9,47.2-83.8,47.2c-38.3,0-65.1-17.4-82.9-51.7
|
||||
l228.1-94.5C3739.5,999.8,3731.5,980.7,3731.5,980.7z M3498.9,1037.7c-1.8-65.9,51.2-99.4,89.1-99.4c29.9,0,54.8,14.7,63.3,36.1
|
||||
L3498.9,1037.7z M3313.6,1203h74.9V701.8h-74.9V1203z M3190.6,910.3h-2.7c-16.9-20.1-49-38.3-90-38.3
|
||||
c-85.1,0-163.5,74.9-163.5,171.1c0,95.8,78,169.8,163.5,169.8c40.5,0,73.1-18.3,90-38.8h2.7v24.5c0,65.1-34.8,100.2-90.9,100.2
|
||||
c-45.9,0-74.4-33-86-60.6l-65.1,27.2c18.7,45,68.6,100.7,151,100.7c87.8,0,162.2-51.7,162.2-177.8V882.2h-70.8v28.1
|
||||
C3191.1,910.3,3190.6,910.3,3190.6,910.3z M3104.6,1146c-51.7,0-94.9-43.2-94.9-102.9c0-60.2,43.2-103.8,94.9-103.8
|
||||
c51.2,0,90.9,44.1,90.9,103.8C3196,1102.8,3155.9,1146,3104.6,1146z M4082.2,701.8h-179.1V1203h74.9v-189.8h104.3
|
||||
c82.9,0,164.4-60.1,164.4-155.5S4165.5,701.8,4082.2,701.8z M4084.4,943.2h-106.5v-172h106.5c56.1,0,87.8,46.3,87.8,86
|
||||
C4172.2,896.5,4140.1,943.2,4084.4,943.2z M4546.9,871.5c-54.4,0-110.5,24.1-133.7,76.6l66.4,27.6c14.3-27.6,40.5-37,68.2-37
|
||||
c38.8,0,78,23.2,78.9,64.6v5.3c-13.4-7.6-42.8-19.2-78-19.2c-71.7,0-144.4,39.2-144.4,112.7c0,67.3,58.8,110.5,124.3,110.5
|
||||
c50.3,0,78-22.7,95.3-49h2.7v38.8h72.2v-192C4698.8,921,4632.4,871.5,4546.9,871.5z M4537.5,1146c-24.5,0-58.8-12-58.8-42.8
|
||||
c0-38.8,42.8-53.5,79.3-53.5c33,0,48.6,7.1,68.2,16.9C4620.8,1111.6,4582.8,1145.6,4537.5,1146z M4962.2,882.2l-86,217.4h-2.7
|
||||
l-89.1-217.4h-80.6l133.7,303.9l-76.2,168.9h78L5045,882.2C5045,882.2,4962.2,882.2,4962.2,882.2z M4288,1203h74.9V701.8H4288V1203z
|
||||
"/>
|
||||
<linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="1682.1077" y1="1339.4783" x2="1624.2924" y2="1309.6345" gradientTransform="matrix(11.64 0 0 -22.55 -18705.5957 30554.3691)">
|
||||
<stop offset="0" style="stop-color:#00A0FF"/>
|
||||
<stop offset="6.569999e-03" style="stop-color:#00A1FF"/>
|
||||
<stop offset="0.2601" style="stop-color:#00BEFF"/>
|
||||
<stop offset="0.5122" style="stop-color:#00D2FF"/>
|
||||
<stop offset="0.7604" style="stop-color:#00DFFF"/>
|
||||
<stop offset="1" style="stop-color:#00E3FF"/>
|
||||
</linearGradient>
|
||||
<path class="st4" d="M418.4,302.1c-11.6,12.5-18.3,31.6-18.3,56.6v886.7c0,25,6.7,44.1,18.7,56.1l3.1,2.7l496.8-496.8v-11.1
|
||||
L421.5,299.4C421.5,299.4,418.4,302.1,418.4,302.1z"/>
|
||||
<linearGradient id="SVGID_2_" gradientUnits="userSpaceOnUse" x1="1712.6624" y1="1274.8376" x2="1606.5613" y2="1274.8376" gradientTransform="matrix(9.145 0 0 -7.7 -14305.5381 10618.251)">
|
||||
<stop offset="0" style="stop-color:#FFE000"/>
|
||||
<stop offset="0.4087" style="stop-color:#FFBD00"/>
|
||||
<stop offset="0.7754" style="stop-color:#FFA500"/>
|
||||
<stop offset="1" style="stop-color:#FF9C00"/>
|
||||
</linearGradient>
|
||||
<path class="st5" d="M1084,973.5L918.3,807.8v-11.6L1084,630.5l3.6,2.2l196,111.4c56.1,31.6,56.1,83.8,0,115.8l-196,111.4
|
||||
C1087.6,971.3,1084,973.5,1084,973.5z"/>
|
||||
<linearGradient id="SVGID_3_" gradientUnits="userSpaceOnUse" x1="1707.4414" y1="1290.0475" x2="1646.682" y2="1211.2225" gradientTransform="matrix(15.02 0 0 -11.5775 -24650.2285 15829.6484)">
|
||||
<stop offset="0" style="stop-color:#FF3A44"/>
|
||||
<stop offset="1" style="stop-color:#C31162"/>
|
||||
</linearGradient>
|
||||
<path class="st6" d="M1087.6,971.3L918.3,802l-499.9,499.9c18.3,19.6,49,21.8,83.3,2.7L1087.6,971.3"/>
|
||||
<linearGradient id="SVGID_4_" gradientUnits="userSpaceOnUse" x1="1660.6357" y1="1365.6676" x2="1687.767" y2="1330.4501" gradientTransform="matrix(15.02 0 0 -11.5715 -24650.2285 15809.9922)">
|
||||
<stop offset="0" style="stop-color:#32A071"/>
|
||||
<stop offset="6.850000e-02" style="stop-color:#2DA771"/>
|
||||
<stop offset="0.4762" style="stop-color:#15CF74"/>
|
||||
<stop offset="0.8009" style="stop-color:#06E775"/>
|
||||
<stop offset="1" style="stop-color:#00F076"/>
|
||||
</linearGradient>
|
||||
<path class="st7" d="M1087.6,632.7L501.7,299.9c-34.3-19.6-65.1-16.9-83.3,2.7L918.3,802L1087.6,632.7z"/>
|
||||
<path class="st8" d="M1084,967.7l-581.9,330.6c-32.5,18.7-61.5,17.4-80.2,0.4l-3.1,3.1l3.1,2.7c18.7,16.9,47.7,18.3,80.2-0.4
|
||||
L1088,971.3C1088,971.3,1084,967.7,1084,967.7z"/>
|
||||
<path class="st9" d="M1283.6,854.1l-200.1,113.6l3.6,3.6l196-111.4c28.1-16,41.9-37,41.9-57.9C1323.3,821.2,1309,839.4,1283.6,854.1
|
||||
z"/>
|
||||
<path class="st10" d="M501.7,305.7l781.9,444.2c25.4,14.3,39.7,33,41.9,52.1c0-20.9-13.8-41.9-41.9-57.9L501.7,299.9
|
||||
c-56.1-32.1-101.6-5.3-101.6,58.8v5.8C400.1,300.3,445.6,274,501.7,305.7z"/>
|
||||
</svg>
|
After (image error) Size: 9.0 KiB |
@ -46,7 +46,7 @@
|
||||
<div class="form-group">
|
||||
<label for="friendly_name">OneSignal Device ID</label>
|
||||
<div class="row">
|
||||
<div class="col-md-8">
|
||||
<div class="col-md-12">
|
||||
<div class="input-group">
|
||||
<span class="input-group-btn">
|
||||
<button class="btn btn-form reveal-token" type="button"><i class="fa fa-eye-slash"></i></button>
|
||||
|
@ -56,7 +56,7 @@
|
||||
<li role="presentation"><a id="nav-tabs-newsletter_agents" href="#tabs-newsletter_agents" aria-controls="tabs-newsletter_agents" role="tab" data-toggle="tab">Newsletter Agents</a></li>
|
||||
<li role="presentation"><a id="nav-tabs-3rd_party_apis" href="#tabs-3rd_party_apis" aria-controls="tabs-3rd_party_apis" role="tab" data-toggle="tab">3rd Party APIs</a></li>
|
||||
<li role="presentation"><a id="nav-tabs-import_backups" href="#tabs-import_backups" aria-controls="tabs-import_backups" role="tab" data-toggle="tab">Import & Backups</a></li>
|
||||
<li role="presentation"><a id="nav-tabs-android_app" href="#tabs-android_app" aria-controls="tabs-android_app" role="tab" data-toggle="tab">Tautulli Remote Android App <sup><small>beta</small></sup></a></li>
|
||||
<li role="presentation"><a id="nav-tabs-remote_app" href="#tabs-remote_app" aria-controls="tabs-remote_app" role="tab" data-toggle="tab">Tautulli Remote App <sup><small>beta</small></sup></a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="col-md-9">
|
||||
@ -696,7 +696,7 @@
|
||||
<label>
|
||||
<input type="checkbox" id="api_enabled" name="api_enabled" value="1" ${config['api_enabled']}> Enable API
|
||||
</label>
|
||||
<p class="help-block">Allow remote applications to interface with Tautulli.</p>
|
||||
<p class="help-block">Allow external applications to interface with Tautulli.</p>
|
||||
</div>
|
||||
<div id="apioptions">
|
||||
<div class="form-group">
|
||||
@ -1559,20 +1559,28 @@
|
||||
|
||||
</div>
|
||||
|
||||
<div role="tabpanel" class="tab-pane" id="tabs-android_app">
|
||||
<div role="tabpanel" class="tab-pane" id="tabs-remote_app">
|
||||
|
||||
<div class="padded-header">
|
||||
<h3>Tautulli Remote Android App</h3>
|
||||
<h3>Tautulli Remote App</h3>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Get the App</label>
|
||||
<p class="help-block">
|
||||
Get the <a href="${anon_url('https://play.google.com/store/apps/details?id=com.tautulli.tautulli_remote')}" target="_blank" rel="noreferrer">Tautulli Remote</a> app on Google Play<sup><small>TM</small></sup> to access Tautulli from your Android device!<br />
|
||||
<span class="google-play-badge">
|
||||
<a href="${anon_url('https://play.google.com/store/apps/details?id=com.tautulli.tautulli_remote')}" target="_blank" rel="noreferrer"><img alt="Get it on Google Play" src="images/en-play-badge.png" /></a>
|
||||
Get the Tautulli Remote app on
|
||||
<a href="${anon_url('https://play.google.com/store/apps/details?id=com.tautulli.tautulli_remote')}" target="_blank" rel="noreferrer">Google Play</a>
|
||||
to access Tautulli from your mobile device!<br />
|
||||
</p>
|
||||
<p class="help-block">
|
||||
<span class="app-badge">
|
||||
<a href="${anon_url('https://play.google.com/store/apps/details?id=com.tautulli.tautulli_remote')}" target="_blank" rel="noreferrer"><img alt="Get it on Google Play" src="images/google-play-badge.svg" /></a>
|
||||
</span>
|
||||
<span class="app-badge">
|
||||
<small>Google Play and the Google Play logo are trademarks of Google LLC.</small>
|
||||
</span>
|
||||
</p>
|
||||
<br style="clear: both">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Registered Devices</label>
|
||||
@ -2040,12 +2048,12 @@ Rating: {rating}/10 --> Rating: /10
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true"><i class="fa fa-remove"></i></button>
|
||||
<h4 class="modal-title">Register Tautulli Android App</h4>
|
||||
<h4 class="modal-title">Register Tautulli Remote App</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<label>Instructions</label>
|
||||
<p class="help-block">
|
||||
Scan the QR code below with the Tautulli Android app to automatically register it with the server (make sure the Tautulli Address below is correct)
|
||||
Scan the QR code below with the Tautulli Remote app to automatically register it with the server (make sure the Tautulli Address below is correct)
|
||||
or manually enter the connection info and device token into the app settings. This window will automatically close once device registration is successful.
|
||||
</p>
|
||||
<p class="help-block">
|
||||
|
@ -1,4 +1,4 @@
|
||||
# This file is part of Tautulli.
|
||||
# This file is part of Tautulli.
|
||||
#
|
||||
# Tautulli is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
@ -2342,7 +2342,9 @@ def dbcheck():
|
||||
|
||||
# Rename notifiers in the database
|
||||
result = c_db.execute('SELECT agent_label FROM notifiers '
|
||||
'WHERE agent_label = "XBMC" OR agent_label = "OSX Notify"').fetchone()
|
||||
'WHERE agent_label = "XBMC" '
|
||||
'OR agent_label = "OSX Notify" '
|
||||
'OR agent_name = "androidapp"').fetchone()
|
||||
if result:
|
||||
logger.debug("Altering database. Renaming notifiers.")
|
||||
c_db.execute(
|
||||
@ -2351,6 +2353,10 @@ def dbcheck():
|
||||
c_db.execute(
|
||||
'UPDATE notifiers SET agent_label = "macOS Notification Center" WHERE agent_label = "OSX Notify"'
|
||||
)
|
||||
c_db.execute(
|
||||
'UPDATE notifiers SET agent_name = "remoteapp", agent_label = "Tautulli Remote App" '
|
||||
'WHERE agent_name = "androidapp"'
|
||||
)
|
||||
|
||||
# Upgrade exports table from earlier versions
|
||||
try:
|
||||
|
@ -98,7 +98,7 @@ AGENT_IDS = {'growl': 0,
|
||||
'browser': 17,
|
||||
'join': 18,
|
||||
'discord': 20,
|
||||
'androidapp': 21,
|
||||
'remoteapp': 21,
|
||||
'groupme': 22,
|
||||
'mqtt': 23,
|
||||
'zapier': 24,
|
||||
@ -110,10 +110,10 @@ DEFAULT_CUSTOM_CONDITIONS = [{'parameter': '', 'operator': '', 'value': ''}]
|
||||
|
||||
|
||||
def available_notification_agents():
|
||||
agents = [{'label': 'Tautulli Remote Android App',
|
||||
'name': 'androidapp',
|
||||
'id': AGENT_IDS['androidapp'],
|
||||
'class': ANDROIDAPP,
|
||||
agents = [{'label': 'Tautulli Remote App',
|
||||
'name': 'remoteapp',
|
||||
'id': AGENT_IDS['remoteapp'],
|
||||
'class': TAUTULLIREMOTEAPP,
|
||||
'action_types': ('all',)
|
||||
},
|
||||
{'label': 'Boxcar',
|
||||
@ -882,188 +882,6 @@ class Notifier(object):
|
||||
return config_options
|
||||
|
||||
|
||||
class ANDROIDAPP(Notifier):
|
||||
"""
|
||||
Tautulli Remote Android app notifications
|
||||
"""
|
||||
NAME = 'Tautulli Remote Android App'
|
||||
_DEFAULT_CONFIG = {'device_id': '',
|
||||
'priority': 3,
|
||||
'notification_type': 0
|
||||
}
|
||||
|
||||
def agent_notify(self, subject='', body='', action='', notification_id=None, **kwargs):
|
||||
# Check mobile device is still registered
|
||||
device = mobile_app.get_mobile_devices(device_id=self.config['device_id'])
|
||||
if not device:
|
||||
logger.warn("Tautulli Notifiers :: Unable to send Android app notification: device not registered.")
|
||||
return
|
||||
else:
|
||||
device = device[0]
|
||||
|
||||
pretty_metadata = PrettyMetadata(kwargs.get('parameters'))
|
||||
|
||||
plaintext_data = {'notification_id': notification_id,
|
||||
'subject': subject,
|
||||
'body': body,
|
||||
'action': action,
|
||||
'priority': self.config['priority'],
|
||||
'notification_type': self.config['notification_type'],
|
||||
'session_key': pretty_metadata.parameters.get('session_key', ''),
|
||||
'session_id': pretty_metadata.parameters.get('session_id', ''),
|
||||
'user_id': pretty_metadata.parameters.get('user_id', ''),
|
||||
'rating_key': pretty_metadata.parameters.get('rating_key', ''),
|
||||
'poster_thumb': pretty_metadata.parameters.get('poster_thumb', '')}
|
||||
|
||||
#logger.debug("Plaintext data: {}".format(plaintext_data))
|
||||
|
||||
if CRYPTODOME:
|
||||
# Key generation
|
||||
salt = get_random_bytes(16)
|
||||
passphrase = device['device_token']
|
||||
key_length = 32 # AES256
|
||||
iterations = 1000
|
||||
key = PBKDF2(passphrase, salt, dkLen=key_length, count=iterations,
|
||||
prf=lambda p, s: HMAC.new(p, s, SHA1).digest())
|
||||
|
||||
#logger.debug("Encryption key (base64): {}".format(base64.b64encode(key)))
|
||||
|
||||
# Encrypt using AES GCM
|
||||
nonce = get_random_bytes(16)
|
||||
cipher = AES.new(key, AES.MODE_GCM, nonce)
|
||||
encrypted_data, gcm_tag = cipher.encrypt_and_digest(json.dumps(plaintext_data).encode('utf-8'))
|
||||
encrypted_data += gcm_tag
|
||||
|
||||
#logger.debug("Encrypted data (base64): {}".format(base64.b64encode(encrypted_data)))
|
||||
#logger.debug("GCM tag (base64): {}".format(base64.b64encode(gcm_tag)))
|
||||
#logger.debug("Nonce (base64): {}".format(base64.b64encode(nonce)))
|
||||
#logger.debug("Salt (base64): {}".format(base64.b64encode(salt)))
|
||||
|
||||
payload = {'app_id': mobile_app._ONESIGNAL_APP_ID,
|
||||
'include_player_ids': [device['onesignal_id']],
|
||||
'contents': {'en': 'Tautulli Notification'},
|
||||
'data': {'encrypted': True,
|
||||
'cipher_text': base64.b64encode(encrypted_data),
|
||||
'nonce': base64.b64encode(nonce),
|
||||
'salt': base64.b64encode(salt),
|
||||
'server_id': plexpy.CONFIG.PMS_UUID}
|
||||
}
|
||||
else:
|
||||
logger.warn("Tautulli Notifiers :: PyCryptodome library is missing. "
|
||||
"Android app notifications will be sent unecrypted. "
|
||||
"Install the library to encrypt the notifications.")
|
||||
|
||||
payload = {'app_id': mobile_app._ONESIGNAL_APP_ID,
|
||||
'include_player_ids': [device['onesignal_id']],
|
||||
'contents': {'en': 'Tautulli Notification'},
|
||||
'data': {'encrypted': False,
|
||||
'plain_text': plaintext_data,
|
||||
'server_id': plexpy.CONFIG.PMS_UUID}
|
||||
}
|
||||
|
||||
#logger.debug("OneSignal payload: {}".format(payload))
|
||||
|
||||
headers = {'Content-Type': 'application/json'}
|
||||
|
||||
return self.make_request("https://onesignal.com/api/v1/notifications", headers=headers, json=payload)
|
||||
|
||||
def get_devices(self):
|
||||
db = database.MonitorDatabase()
|
||||
|
||||
try:
|
||||
query = 'SELECT * FROM mobile_devices WHERE official = 1 ' \
|
||||
'AND onesignal_id IS NOT NULL AND onesignal_id != ""'
|
||||
result = db.select(query=query)
|
||||
except Exception as e:
|
||||
logger.warn("Tautulli Notifiers :: Unable to retrieve Android app devices list: %s." % e)
|
||||
return {'': ''}
|
||||
|
||||
devices = {}
|
||||
for device in result:
|
||||
if device['friendly_name']:
|
||||
devices[device['device_id']] = device['friendly_name']
|
||||
else:
|
||||
devices[device['device_id']] = device['device_name']
|
||||
|
||||
return devices
|
||||
|
||||
def _return_config_options(self):
|
||||
config_option = []
|
||||
|
||||
if not CRYPTODOME:
|
||||
config_option.append({
|
||||
'label': 'Warning',
|
||||
'description': '<strong>The PyCryptodome library is missing. '
|
||||
'The content of your notifications will be sent unencrypted!</strong><br>'
|
||||
'Please install the library to encrypt the notification contents. '
|
||||
'Instructions can be found in the '
|
||||
'<a href="' + helpers.anon_url(
|
||||
'https://github.com/%s/%s/wiki/Frequently-Asked-Questions#notifications-pycryptodome'
|
||||
% (plexpy.CONFIG.GIT_USER, plexpy.CONFIG.GIT_REPO)) + '" target="_blank">FAQ</a>.' ,
|
||||
'input_type': 'help'
|
||||
})
|
||||
else:
|
||||
config_option.append({
|
||||
'label': 'Note',
|
||||
'description': 'The PyCryptodome library was found. '
|
||||
'The content of your notifications will be sent encrypted!',
|
||||
'input_type': 'help'
|
||||
})
|
||||
|
||||
config_option[-1]['description'] += '<br><br>Notifications are sent using the ' \
|
||||
'<a href="' + helpers.anon_url('https://onesignal.com') + '" target="_blank">' \
|
||||
'OneSignal</a>. Some user data is collected and cannot be encrypted. ' \
|
||||
'Please read the <a href="' + helpers.anon_url(
|
||||
'https://onesignal.com/privacy_policy') + '" target="_blank">' \
|
||||
'OneSignal Privacy Policy</a> for more details.'
|
||||
|
||||
devices = self.get_devices()
|
||||
|
||||
if not devices:
|
||||
config_option.append({
|
||||
'label': 'Device',
|
||||
'description': 'No mobile devices registered with OneSignal. '
|
||||
'<a data-tab-destination="android_app" data-toggle="tab" data-dismiss="modal">'
|
||||
'Get the Android App</a> and register a device.<br>'
|
||||
'Note: Only devices registered with a valid OneSignal ID will appear in the list.',
|
||||
'input_type': 'help'
|
||||
})
|
||||
else:
|
||||
config_option.append({
|
||||
'label': 'Device',
|
||||
'value': self.config['device_id'],
|
||||
'name': 'androidapp_device_id',
|
||||
'description': 'Select your mobile device or '
|
||||
'<a data-tab-destination="android_app" data-toggle="tab" data-dismiss="modal">'
|
||||
'register a new device</a> with Tautulli.<br>'
|
||||
'Note: Only devices registered with a valid OneSignal ID will appear in the list.',
|
||||
'input_type': 'select',
|
||||
'select_options': devices
|
||||
})
|
||||
|
||||
config_option.append({
|
||||
'label': 'Priority',
|
||||
'value': self.config['priority'],
|
||||
'name': 'androidapp_priority',
|
||||
'description': 'Set the notification priority.',
|
||||
'input_type': 'select',
|
||||
'select_options': {1: 'Minimum', 2: 'Low', 3: 'Normal', 4: 'High'}
|
||||
})
|
||||
config_option.append({
|
||||
'label': 'Notification Image Type',
|
||||
'value': self.config['notification_type'],
|
||||
'name': 'androidapp_notification_type',
|
||||
'description': 'Set the notification image type.',
|
||||
'input_type': 'select',
|
||||
'select_options': {0: 'No notification image',
|
||||
1: 'Small image (Expandable text)',
|
||||
2: 'Large image (Non-expandable text)'
|
||||
}
|
||||
})
|
||||
|
||||
return config_option
|
||||
|
||||
|
||||
class BOXCAR(Notifier):
|
||||
"""
|
||||
Boxcar notifications
|
||||
@ -3399,6 +3217,188 @@ class SLACK(Notifier):
|
||||
return config_option
|
||||
|
||||
|
||||
class TAUTULLIREMOTEAPP(Notifier):
|
||||
"""
|
||||
Tautulli Remote app notifications
|
||||
"""
|
||||
NAME = 'Tautulli Remote App'
|
||||
_DEFAULT_CONFIG = {'device_id': '',
|
||||
'priority': 3,
|
||||
'notification_type': 0
|
||||
}
|
||||
|
||||
def agent_notify(self, subject='', body='', action='', notification_id=None, **kwargs):
|
||||
# Check mobile device is still registered
|
||||
device = mobile_app.get_mobile_devices(device_id=self.config['device_id'])
|
||||
if not device:
|
||||
logger.warn("Tautulli Notifiers :: Unable to send Tautulli Remote app notification: device not registered.")
|
||||
return
|
||||
else:
|
||||
device = device[0]
|
||||
|
||||
pretty_metadata = PrettyMetadata(kwargs.get('parameters'))
|
||||
|
||||
plaintext_data = {'notification_id': notification_id,
|
||||
'subject': subject,
|
||||
'body': body,
|
||||
'action': action,
|
||||
'priority': self.config['priority'],
|
||||
'notification_type': self.config['notification_type'],
|
||||
'session_key': pretty_metadata.parameters.get('session_key', ''),
|
||||
'session_id': pretty_metadata.parameters.get('session_id', ''),
|
||||
'user_id': pretty_metadata.parameters.get('user_id', ''),
|
||||
'rating_key': pretty_metadata.parameters.get('rating_key', ''),
|
||||
'poster_thumb': pretty_metadata.parameters.get('poster_thumb', '')}
|
||||
|
||||
#logger.debug("Plaintext data: {}".format(plaintext_data))
|
||||
|
||||
if CRYPTODOME:
|
||||
# Key generation
|
||||
salt = get_random_bytes(16)
|
||||
passphrase = device['device_token']
|
||||
key_length = 32 # AES256
|
||||
iterations = 1000
|
||||
key = PBKDF2(passphrase, salt, dkLen=key_length, count=iterations,
|
||||
prf=lambda p, s: HMAC.new(p, s, SHA1).digest())
|
||||
|
||||
#logger.debug("Encryption key (base64): {}".format(base64.b64encode(key)))
|
||||
|
||||
# Encrypt using AES GCM
|
||||
nonce = get_random_bytes(16)
|
||||
cipher = AES.new(key, AES.MODE_GCM, nonce)
|
||||
encrypted_data, gcm_tag = cipher.encrypt_and_digest(json.dumps(plaintext_data).encode('utf-8'))
|
||||
encrypted_data += gcm_tag
|
||||
|
||||
#logger.debug("Encrypted data (base64): {}".format(base64.b64encode(encrypted_data)))
|
||||
#logger.debug("GCM tag (base64): {}".format(base64.b64encode(gcm_tag)))
|
||||
#logger.debug("Nonce (base64): {}".format(base64.b64encode(nonce)))
|
||||
#logger.debug("Salt (base64): {}".format(base64.b64encode(salt)))
|
||||
|
||||
payload = {'app_id': mobile_app._ONESIGNAL_APP_ID,
|
||||
'include_player_ids': [device['onesignal_id']],
|
||||
'contents': {'en': 'Tautulli Notification'},
|
||||
'data': {'encrypted': True,
|
||||
'cipher_text': base64.b64encode(encrypted_data),
|
||||
'nonce': base64.b64encode(nonce),
|
||||
'salt': base64.b64encode(salt),
|
||||
'server_id': plexpy.CONFIG.PMS_UUID}
|
||||
}
|
||||
else:
|
||||
logger.warn("Tautulli Notifiers :: PyCryptodome library is missing. "
|
||||
"Tautulli Remote app notifications will be sent unecrypted. "
|
||||
"Install the library to encrypt the notifications.")
|
||||
|
||||
payload = {'app_id': mobile_app._ONESIGNAL_APP_ID,
|
||||
'include_player_ids': [device['onesignal_id']],
|
||||
'contents': {'en': 'Tautulli Notification'},
|
||||
'data': {'encrypted': False,
|
||||
'plain_text': plaintext_data,
|
||||
'server_id': plexpy.CONFIG.PMS_UUID}
|
||||
}
|
||||
|
||||
#logger.debug("OneSignal payload: {}".format(payload))
|
||||
|
||||
headers = {'Content-Type': 'application/json'}
|
||||
|
||||
return self.make_request("https://onesignal.com/api/v1/notifications", headers=headers, json=payload)
|
||||
|
||||
def get_devices(self):
|
||||
db = database.MonitorDatabase()
|
||||
|
||||
try:
|
||||
query = 'SELECT * FROM mobile_devices WHERE official = 1 ' \
|
||||
'AND onesignal_id IS NOT NULL AND onesignal_id != ""'
|
||||
result = db.select(query=query)
|
||||
except Exception as e:
|
||||
logger.warn("Tautulli Notifiers :: Unable to retrieve Tautulli Remote app devices list: %s." % e)
|
||||
return {'': ''}
|
||||
|
||||
devices = {}
|
||||
for device in result:
|
||||
if device['friendly_name']:
|
||||
devices[device['device_id']] = device['friendly_name']
|
||||
else:
|
||||
devices[device['device_id']] = device['device_name']
|
||||
|
||||
return devices
|
||||
|
||||
def _return_config_options(self):
|
||||
config_option = []
|
||||
|
||||
if not CRYPTODOME:
|
||||
config_option.append({
|
||||
'label': 'Warning',
|
||||
'description': '<strong>The PyCryptodome library is missing. '
|
||||
'The content of your notifications will be sent unencrypted!</strong><br>'
|
||||
'Please install the library to encrypt the notification contents. '
|
||||
'Instructions can be found in the '
|
||||
'<a href="' + helpers.anon_url(
|
||||
'https://github.com/%s/%s/wiki/Frequently-Asked-Questions#notifications-pycryptodome'
|
||||
% (plexpy.CONFIG.GIT_USER, plexpy.CONFIG.GIT_REPO)) + '" target="_blank">FAQ</a>.' ,
|
||||
'input_type': 'help'
|
||||
})
|
||||
else:
|
||||
config_option.append({
|
||||
'label': 'Note',
|
||||
'description': 'The PyCryptodome library was found. '
|
||||
'The content of your notifications will be sent encrypted!',
|
||||
'input_type': 'help'
|
||||
})
|
||||
|
||||
config_option[-1]['description'] += '<br><br>Notifications are sent using the ' \
|
||||
'<a href="' + helpers.anon_url('https://onesignal.com') + '" target="_blank">' \
|
||||
'OneSignal</a>. Some user data is collected and cannot be encrypted. ' \
|
||||
'Please read the <a href="' + helpers.anon_url(
|
||||
'https://onesignal.com/privacy_policy') + '" target="_blank">' \
|
||||
'OneSignal Privacy Policy</a> for more details.'
|
||||
|
||||
devices = self.get_devices()
|
||||
|
||||
if not devices:
|
||||
config_option.append({
|
||||
'label': 'Device',
|
||||
'description': 'No mobile devices registered with OneSignal. '
|
||||
'<a data-tab-destination="remote_app" data-toggle="tab" data-dismiss="modal">'
|
||||
'Get the Tautulli Remote App</a> and register a device.<br>'
|
||||
'Note: Only devices registered with a valid OneSignal ID will appear in the list.',
|
||||
'input_type': 'help'
|
||||
})
|
||||
else:
|
||||
config_option.append({
|
||||
'label': 'Device',
|
||||
'value': self.config['device_id'],
|
||||
'name': 'remoteapp_device_id',
|
||||
'description': 'Select your mobile device or '
|
||||
'<a data-tab-destination="remote_app" data-toggle="tab" data-dismiss="modal">'
|
||||
'register a new device</a> with Tautulli.<br>'
|
||||
'Note: Only devices registered with a valid OneSignal ID will appear in the list.',
|
||||
'input_type': 'select',
|
||||
'select_options': devices
|
||||
})
|
||||
|
||||
config_option.append({
|
||||
'label': 'Priority',
|
||||
'value': self.config['priority'],
|
||||
'name': 'remoteapp_priority',
|
||||
'description': 'Set the notification priority.',
|
||||
'input_type': 'select',
|
||||
'select_options': {1: 'Minimum', 2: 'Low', 3: 'Normal', 4: 'High'}
|
||||
})
|
||||
config_option.append({
|
||||
'label': 'Notification Image Type',
|
||||
'value': self.config['notification_type'],
|
||||
'name': 'remoteapp_notification_type',
|
||||
'description': 'Set the notification image type.',
|
||||
'input_type': 'select',
|
||||
'select_options': {0: 'No notification image',
|
||||
1: 'Small image (Expandable text)',
|
||||
2: 'Large image (Non-expandable text)'
|
||||
}
|
||||
})
|
||||
|
||||
return config_option
|
||||
|
||||
|
||||
class TELEGRAM(Notifier):
|
||||
"""
|
||||
Telegram notifications
|
||||
|
Loading…
x
Reference in New Issue
Block a user