mirror of
https://github.com/TeamNewPipe/NewPipe
synced 2025-10-03 02:40:52 +02:00
Compare commits
469 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
72d90374a0 | ||
![]() |
fc8160acda | ||
![]() |
751ffb9de9 | ||
![]() |
60d636940d | ||
![]() |
7a5cca519a | ||
![]() |
1e93d06a25 | ||
![]() |
4341f8aaec | ||
![]() |
46022d60f3 | ||
![]() |
80ddc76926 | ||
![]() |
bd999b4b0a | ||
![]() |
4cdc387338 | ||
![]() |
df258a0003 | ||
![]() |
7cc1c0fbdd | ||
![]() |
42644c956b | ||
![]() |
00eaedcbfa | ||
![]() |
1ff5a97c85 | ||
![]() |
241414f81b | ||
![]() |
1bf046a8ba | ||
![]() |
61471fdd3c | ||
![]() |
a0524fb136 | ||
![]() |
fa39389a64 | ||
![]() |
697a24e699 | ||
![]() |
cf3bb87a54 | ||
![]() |
14fb7d8a7a | ||
![]() |
d097363b24 | ||
![]() |
bad576c23d | ||
![]() |
8d9e4e7442 | ||
![]() |
431d03c63f | ||
![]() |
24321731d9 | ||
![]() |
fddcade1fb | ||
![]() |
a0aa7dcdc1 | ||
![]() |
d3e9f354b3 | ||
![]() |
e958334406 | ||
![]() |
a42029970d | ||
![]() |
2108e09e13 | ||
![]() |
8c010093e8 | ||
![]() |
adc98be441 | ||
![]() |
fb942912db | ||
![]() |
7f12b58722 | ||
![]() |
05d58f8f98 | ||
![]() |
46c2db310a | ||
![]() |
607408b9b9 | ||
![]() |
b81e8cb81a | ||
![]() |
44ef04d90a | ||
![]() |
3e9d84b109 | ||
![]() |
aa2d8d4833 | ||
![]() |
55f63b948b | ||
![]() |
cece543d6b | ||
![]() |
9204a89319 | ||
![]() |
f8ed96bb25 | ||
![]() |
54d318bf04 | ||
![]() |
f152d66cd8 | ||
![]() |
576786c751 | ||
![]() |
a6b7cd3202 | ||
![]() |
ea9caaaaf0 | ||
![]() |
22d8f434be | ||
![]() |
8360c10141 | ||
![]() |
750dc6f2cc | ||
![]() |
47b556544d | ||
![]() |
f6cee739a6 | ||
![]() |
d1afe0028c | ||
![]() |
a4cace1ef7 | ||
![]() |
707ac8be27 | ||
![]() |
2f2254966a | ||
![]() |
eb57675f55 | ||
![]() |
dde93c5ccf | ||
![]() |
886b5959f7 | ||
![]() |
dc44546ac7 | ||
![]() |
42c6698732 | ||
![]() |
bd014a107f | ||
![]() |
3a7298bb99 | ||
![]() |
aa06e3490d | ||
![]() |
ece889b36b | ||
![]() |
9848f19ce6 | ||
![]() |
e59b087057 | ||
![]() |
5b451d1ac7 | ||
![]() |
f050c05b3c | ||
![]() |
06b8edefbf | ||
![]() |
f3a2a28398 | ||
![]() |
9b0a1fc2ec | ||
![]() |
c87ab234eb | ||
![]() |
68468756a8 | ||
![]() |
9016df0195 | ||
![]() |
7acece9705 | ||
![]() |
d1896c23c0 | ||
![]() |
dae19f03e0 | ||
![]() |
9dafccf0f7 | ||
![]() |
5f270c41ae | ||
![]() |
f9f80e9003 | ||
![]() |
c5063d4269 | ||
![]() |
ccbe18ec1c | ||
![]() |
321a8a8b25 | ||
![]() |
77a9560376 | ||
![]() |
058a039a82 | ||
![]() |
7c744703e4 | ||
![]() |
a934cbb085 | ||
![]() |
cf4158c0d0 | ||
![]() |
dc56eab9b6 | ||
![]() |
37d1f59132 | ||
![]() |
ab0ce55411 | ||
![]() |
c1d66596d1 | ||
![]() |
cbfccdf0d3 | ||
![]() |
9362037177 | ||
![]() |
e25c93bae2 | ||
![]() |
367c434010 | ||
![]() |
02d8463e15 | ||
![]() |
9d5a1d5c43 | ||
![]() |
c8d94f541f | ||
![]() |
27d06eaa6b | ||
![]() |
7f32857e00 | ||
![]() |
2f060f0f52 | ||
![]() |
f89d405226 | ||
![]() |
fd4459e570 | ||
![]() |
eb0df2b101 | ||
![]() |
6c178cfb7e | ||
![]() |
8ced68430d | ||
![]() |
0aade598ff | ||
![]() |
95949fd1ab | ||
![]() |
1a56382112 | ||
![]() |
d610e4b19b | ||
![]() |
fc44d9e36e | ||
![]() |
c07686576a | ||
![]() |
c2400aea4d | ||
![]() |
fb4bf0dde4 | ||
![]() |
e4f638d1ce | ||
![]() |
5c492c01a1 | ||
![]() |
f451e11f82 | ||
![]() |
95b73f35f7 | ||
![]() |
58147e9e12 | ||
![]() |
a8830e2ede | ||
![]() |
9804bb95cc | ||
![]() |
0da1aef763 | ||
![]() |
0a334804a3 | ||
![]() |
94d2f03e9b | ||
![]() |
9127f7f0c2 | ||
![]() |
0bb0226bc2 | ||
![]() |
b3a1a5dcc2 | ||
![]() |
984dd1cc25 | ||
![]() |
5663e543a4 | ||
![]() |
d3879a0398 | ||
![]() |
6bd2468d44 | ||
![]() |
e63d43151b | ||
![]() |
0265da4ae6 | ||
![]() |
ef255d12ae | ||
![]() |
eeb612f9a2 | ||
![]() |
dfcb4edb81 | ||
![]() |
d3500e9036 | ||
![]() |
adcb8c6469 | ||
![]() |
592eee7d3d | ||
![]() |
7dadb2b26c | ||
![]() |
7cbb135f28 | ||
![]() |
966ac0673c | ||
![]() |
d715eae0d1 | ||
![]() |
ccdd13d136 | ||
![]() |
efe5de4c75 | ||
![]() |
2a93e9bd2e | ||
![]() |
28dd53ae50 | ||
![]() |
3c1e64d8dc | ||
![]() |
4fe3cb2bca | ||
![]() |
b31490c4e3 | ||
![]() |
5533f6ba86 | ||
![]() |
8aa5f87a1c | ||
![]() |
6deb674377 | ||
![]() |
12d1d998a3 | ||
![]() |
d90162d06f | ||
![]() |
97c924341c | ||
![]() |
e91fc225e1 | ||
![]() |
43149fd832 | ||
![]() |
78df579703 | ||
![]() |
f61b915894 | ||
![]() |
cd3f405bff | ||
![]() |
7cfdca7a81 | ||
![]() |
216063dba8 | ||
![]() |
b647bacd72 | ||
![]() |
4f77937e3e | ||
![]() |
48e299b2ac | ||
![]() |
40f00af196 | ||
![]() |
bd6cc22e63 | ||
![]() |
8760792426 | ||
![]() |
870b0bf7aa | ||
![]() |
afd0bd4318 | ||
![]() |
f829ac1d34 | ||
![]() |
86a0177855 | ||
![]() |
718d4fd0bd | ||
![]() |
365137c32b | ||
![]() |
e83ca0dfda | ||
![]() |
6a9f6ef651 | ||
![]() |
99122ccc03 | ||
![]() |
97923697e1 | ||
![]() |
68888b15e0 | ||
![]() |
f48b26067b | ||
![]() |
4bf2d5837d | ||
![]() |
4eb2d09c75 | ||
![]() |
a146c1c4b6 | ||
![]() |
2f1ea9aa5d | ||
![]() |
a90da62deb | ||
![]() |
c1c3fbdf26 | ||
![]() |
e07a824d82 | ||
![]() |
2aff660a5b | ||
![]() |
abfcbe6f0e | ||
![]() |
28bf72ed75 | ||
![]() |
21b054d4ca | ||
![]() |
34f115b322 | ||
![]() |
8b67354076 | ||
![]() |
b62e0a8b40 | ||
![]() |
f46d5376fe | ||
![]() |
dc3640578f | ||
![]() |
0a43494de5 | ||
![]() |
2544e45d2d | ||
![]() |
4a53e9e018 | ||
![]() |
9d7dc99416 | ||
![]() |
c89dc4ba5b | ||
![]() |
72289ced39 | ||
![]() |
3554ccde05 | ||
![]() |
73e2c42931 | ||
![]() |
b11778ec55 | ||
![]() |
18bc937958 | ||
![]() |
9f618f6678 | ||
![]() |
0c3c7493de | ||
![]() |
8f3f02e9f7 | ||
![]() |
69903ba889 | ||
![]() |
25c5f95ad9 | ||
![]() |
2546d1107e | ||
![]() |
fdbeaf8692 | ||
![]() |
63c0316af2 | ||
![]() |
f2e761c07c | ||
![]() |
6a741de7d1 | ||
![]() |
3e94d18fe1 | ||
![]() |
95d3651e29 | ||
![]() |
cd2d88781a | ||
![]() |
2178e86d09 | ||
![]() |
f9ad0f12d0 | ||
![]() |
63b16d925d | ||
![]() |
53b9ffcbc8 | ||
![]() |
df01f41980 | ||
![]() |
b0c40d3b09 | ||
![]() |
5880dcbcfd | ||
![]() |
489bbc45f5 | ||
![]() |
5e67502729 | ||
![]() |
842079c928 | ||
![]() |
b0bab07a15 | ||
![]() |
4dbb12c65d | ||
![]() |
db500e9791 | ||
![]() |
fd8f600fec | ||
![]() |
2e2d7d02fb | ||
![]() |
d068cd7f75 | ||
![]() |
5a05ffcbdd | ||
![]() |
d8c7f50b39 | ||
![]() |
988e6e1c82 | ||
![]() |
f6af19444c | ||
![]() |
0581e50e0c | ||
![]() |
a95da9a42d | ||
![]() |
be10b9750f | ||
![]() |
29a3cbc688 | ||
![]() |
4f57d3a201 | ||
![]() |
c9be1398b0 | ||
![]() |
30eef4db12 | ||
![]() |
b932dbf514 | ||
![]() |
320ac82dea | ||
![]() |
af1b21db23 | ||
![]() |
0e892ff60e | ||
![]() |
074963aee0 | ||
![]() |
37d9be9095 | ||
![]() |
26e36454ef | ||
![]() |
78b95f67eb | ||
![]() |
6c63841d0c | ||
![]() |
6ec2d91d91 | ||
![]() |
3299b90c20 | ||
![]() |
7b6d6da9a6 | ||
![]() |
7c7c61fc35 | ||
![]() |
c5408fb6b8 | ||
![]() |
1c49102f67 | ||
![]() |
f9dd88c1cb | ||
![]() |
9ed4a65fd2 | ||
![]() |
10bebf8a89 | ||
![]() |
36260dac18 | ||
![]() |
2e4e993967 | ||
![]() |
ef1bfe98f7 | ||
![]() |
2e123aa617 | ||
![]() |
cf2ef0f2a8 | ||
![]() |
520f40d862 | ||
![]() |
856bdac84b | ||
![]() |
deb7e38fcf | ||
![]() |
e5f47a4563 | ||
![]() |
d1b465d8be | ||
![]() |
5c73b2f324 | ||
![]() |
7d3e992b3f | ||
![]() |
296640930e | ||
![]() |
1c42735e3a | ||
![]() |
0800bc1790 | ||
![]() |
bd76a12b90 | ||
![]() |
d3daea6383 | ||
![]() |
df1acd5413 | ||
![]() |
0d65cc09f6 | ||
![]() |
892b082b9e | ||
![]() |
9069ef1325 | ||
![]() |
47cc493ab5 | ||
![]() |
f43d7837f8 | ||
![]() |
91921ae672 | ||
![]() |
eba6afc12b | ||
![]() |
ff826a9eeb | ||
![]() |
6c01a30af5 | ||
![]() |
53f8d09d31 | ||
![]() |
ae191aaafe | ||
![]() |
d1694d563b | ||
![]() |
75fadf79da | ||
![]() |
23ce5a6b1e | ||
![]() |
bb65e2b84d | ||
![]() |
aa42b1d95a | ||
![]() |
32d5a18198 | ||
![]() |
63faefe9c3 | ||
![]() |
a90c49d030 | ||
![]() |
b1ef3fa4df | ||
![]() |
b8cf67cba9 | ||
![]() |
4780e10ade | ||
![]() |
401e606fbc | ||
![]() |
6b4ef8f397 | ||
![]() |
7c66d07779 | ||
![]() |
92aed0cc3a | ||
![]() |
457b08d3cc | ||
![]() |
1e5f6fd2b8 | ||
![]() |
aebfeb98aa | ||
![]() |
f6974e8315 | ||
![]() |
2ce6313ac1 | ||
![]() |
e98a113a59 | ||
![]() |
ba7bed9c2c | ||
![]() |
c9ea451c53 | ||
![]() |
4261ff32c7 | ||
![]() |
cb4b20af45 | ||
![]() |
b8a27adb93 | ||
![]() |
15b58128f4 | ||
![]() |
237282db28 | ||
![]() |
71bb59dbb8 | ||
![]() |
e41c46c075 | ||
![]() |
6ca9e52f2f | ||
![]() |
2afee89de3 | ||
![]() |
189bee3e44 | ||
![]() |
6b9a4d5e0a | ||
![]() |
451e2b2182 | ||
![]() |
f6ff41cfb4 | ||
![]() |
d6d144c927 | ||
![]() |
7f86872139 | ||
![]() |
dc0fc05a9e | ||
![]() |
6b2c3217ab | ||
![]() |
0f93a45b9d | ||
![]() |
943027ffdd | ||
![]() |
5d28b2400f | ||
![]() |
67324bfc80 | ||
![]() |
3c340e7144 | ||
![]() |
c834405a92 | ||
![]() |
4ee9e26847 | ||
![]() |
94293ca9d9 | ||
![]() |
b9cd9f8d35 | ||
![]() |
812dd9282d | ||
![]() |
fa1d386fcc | ||
![]() |
0392bf6a02 | ||
![]() |
97f771ff50 | ||
![]() |
6adcc72a8a | ||
![]() |
2c11bd1889 | ||
![]() |
23e0196fcc | ||
![]() |
91f98c125e | ||
![]() |
7f01e9a4d9 | ||
![]() |
320a4e2351 | ||
![]() |
0829ce51fc | ||
![]() |
97ec50c202 | ||
![]() |
975a3e8103 | ||
![]() |
658ef2ef26 | ||
![]() |
bd1e531d7b | ||
![]() |
e440d1d1bd | ||
![]() |
2110020165 | ||
![]() |
dac74dc30d | ||
![]() |
fa4b971254 | ||
![]() |
2d31ae0baa | ||
![]() |
5eebfa132f | ||
![]() |
522febef93 | ||
![]() |
a421645ea5 | ||
![]() |
0aac4b1347 | ||
![]() |
36697825cf | ||
![]() |
b0182ed604 | ||
![]() |
c4ea73ca7a | ||
![]() |
2aa28d6453 | ||
![]() |
2d51085ccf | ||
![]() |
4eae02e47e | ||
![]() |
f3bf9f9e5d | ||
![]() |
75d0b84bdb | ||
![]() |
3643ddcf5c | ||
![]() |
35500e8ef7 | ||
![]() |
6badcf5391 | ||
![]() |
d4898043f6 | ||
![]() |
2322ba833a | ||
![]() |
5aabb2917f | ||
![]() |
eacbf6ce50 | ||
![]() |
031300a132 | ||
![]() |
f905611e69 | ||
![]() |
e475f9f876 | ||
![]() |
b65263349e | ||
![]() |
5cb8026f6d | ||
![]() |
cc7ce5cf93 | ||
![]() |
af506639a9 | ||
![]() |
d377d67174 | ||
![]() |
cf926353d1 | ||
![]() |
d686c744d0 | ||
![]() |
501c60b180 | ||
![]() |
da36687e25 | ||
![]() |
f13f9a066a | ||
![]() |
8eaa4f7654 | ||
![]() |
145a7f8e0d | ||
![]() |
67ba126602 | ||
![]() |
c5084901b5 | ||
![]() |
3bfc82f7c0 | ||
![]() |
3411b53450 | ||
![]() |
873564f2aa | ||
![]() |
353ed90d12 | ||
![]() |
799faecc5b | ||
![]() |
731321b1f9 | ||
![]() |
7ff43caf96 | ||
![]() |
d0877c3132 | ||
![]() |
c589b03dcb | ||
![]() |
862b5aaef6 | ||
![]() |
596443bf5e | ||
![]() |
27b450f1e3 | ||
![]() |
61a09e97ca | ||
![]() |
224e7a8969 | ||
![]() |
9e7d9ee973 | ||
![]() |
586bad345c | ||
![]() |
abdd7dc7d3 | ||
![]() |
aee32f7a3e | ||
![]() |
696760e65a | ||
![]() |
200db15d4b | ||
![]() |
33e332f105 | ||
![]() |
bb2955e442 | ||
![]() |
2fc2fa56c3 | ||
![]() |
c87458590c | ||
![]() |
8aff134c56 | ||
![]() |
4a938b81df | ||
![]() |
4def715b25 | ||
![]() |
821acf12d8 | ||
![]() |
fc707b6c7e | ||
![]() |
85ac000479 | ||
![]() |
68a0eefa20 | ||
![]() |
fc32377ce7 | ||
![]() |
59e512a64d | ||
![]() |
c51a5a51f1 | ||
![]() |
9546a276dc | ||
![]() |
a18353df5f | ||
![]() |
3c72113f4c | ||
![]() |
7e193751c4 | ||
![]() |
56c96eb712 | ||
![]() |
4106a984ca | ||
![]() |
10f1ab0598 | ||
![]() |
bca9603440 | ||
![]() |
c32c267889 | ||
![]() |
627e987bda | ||
![]() |
7c18e147f3 | ||
![]() |
6a8fb5910d | ||
![]() |
b865326d51 | ||
![]() |
a2d5b0893d | ||
![]() |
db0508b9ab | ||
![]() |
1850dee93a | ||
![]() |
7b1eb8a6dc | ||
![]() |
95a9f2f5e3 | ||
![]() |
ae7ed2d226 | ||
![]() |
20cf82bab1 | ||
![]() |
5dcb1e26b5 | ||
![]() |
8076589180 | ||
![]() |
edbd4003be | ||
![]() |
122b089bf0 | ||
![]() |
a28d917990 | ||
![]() |
5b605a1100 |
7
.gitignore
vendored
7
.gitignore
vendored
@@ -1,7 +1,10 @@
|
|||||||
|
.gitignore
|
||||||
.gradle
|
.gradle
|
||||||
/local.properties
|
/local.properties
|
||||||
/.idea/workspace.xml
|
|
||||||
/.idea/libraries
|
|
||||||
.DS_Store
|
.DS_Store
|
||||||
/build
|
/build
|
||||||
/captures
|
/captures
|
||||||
|
/app/app.iml
|
||||||
|
/.idea
|
||||||
|
/*.iml
|
||||||
|
gradle.properties
|
||||||
|
1
.idea/.name
generated
1
.idea/.name
generated
@@ -1 +0,0 @@
|
|||||||
NewPipe
|
|
22
.idea/compiler.xml
generated
22
.idea/compiler.xml
generated
@@ -1,22 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="CompilerConfiguration">
|
|
||||||
<resourceExtensions />
|
|
||||||
<wildcardResourcePatterns>
|
|
||||||
<entry name="!?*.java" />
|
|
||||||
<entry name="!?*.form" />
|
|
||||||
<entry name="!?*.class" />
|
|
||||||
<entry name="!?*.groovy" />
|
|
||||||
<entry name="!?*.scala" />
|
|
||||||
<entry name="!?*.flex" />
|
|
||||||
<entry name="!?*.kt" />
|
|
||||||
<entry name="!?*.clj" />
|
|
||||||
<entry name="!?*.aj" />
|
|
||||||
</wildcardResourcePatterns>
|
|
||||||
<annotationProcessing>
|
|
||||||
<profile default="true" name="Default" enabled="false">
|
|
||||||
<processorPath useClasspath="true" />
|
|
||||||
</profile>
|
|
||||||
</annotationProcessing>
|
|
||||||
</component>
|
|
||||||
</project>
|
|
3
.idea/copyright/profiles_settings.xml
generated
3
.idea/copyright/profiles_settings.xml
generated
@@ -1,3 +0,0 @@
|
|||||||
<component name="CopyrightManager">
|
|
||||||
<settings default="" />
|
|
||||||
</component>
|
|
3
.idea/dictionaries/the_scrabi.xml
generated
3
.idea/dictionaries/the_scrabi.xml
generated
@@ -1,3 +0,0 @@
|
|||||||
<component name="ProjectDictionaryState">
|
|
||||||
<dictionary name="the-scrabi" />
|
|
||||||
</component>
|
|
19
.idea/gradle.xml
generated
19
.idea/gradle.xml
generated
@@ -1,19 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="GradleSettings">
|
|
||||||
<option name="linkedExternalProjectsSettings">
|
|
||||||
<GradleProjectSettings>
|
|
||||||
<option name="distributionType" value="LOCAL" />
|
|
||||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
|
||||||
<option name="gradleHome" value="$APPLICATION_HOME_DIR$/gradle/gradle-2.4" />
|
|
||||||
<option name="gradleJvm" value="1.8" />
|
|
||||||
<option name="modules">
|
|
||||||
<set>
|
|
||||||
<option value="$PROJECT_DIR$" />
|
|
||||||
<option value="$PROJECT_DIR$/app" />
|
|
||||||
</set>
|
|
||||||
</option>
|
|
||||||
</GradleProjectSettings>
|
|
||||||
</option>
|
|
||||||
</component>
|
|
||||||
</project>
|
|
46
.idea/misc.xml
generated
46
.idea/misc.xml
generated
@@ -1,46 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="EntryPointsManager">
|
|
||||||
<entry_points version="2.0" />
|
|
||||||
</component>
|
|
||||||
<component name="NullableNotNullManager">
|
|
||||||
<option name="myDefaultNullable" value="android.support.annotation.Nullable" />
|
|
||||||
<option name="myDefaultNotNull" value="android.support.annotation.NonNull" />
|
|
||||||
<option name="myNullables">
|
|
||||||
<value>
|
|
||||||
<list size="4">
|
|
||||||
<item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.Nullable" />
|
|
||||||
<item index="1" class="java.lang.String" itemvalue="javax.annotation.Nullable" />
|
|
||||||
<item index="2" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.Nullable" />
|
|
||||||
<item index="3" class="java.lang.String" itemvalue="android.support.annotation.Nullable" />
|
|
||||||
</list>
|
|
||||||
</value>
|
|
||||||
</option>
|
|
||||||
<option name="myNotNulls">
|
|
||||||
<value>
|
|
||||||
<list size="4">
|
|
||||||
<item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.NotNull" />
|
|
||||||
<item index="1" class="java.lang.String" itemvalue="javax.annotation.Nonnull" />
|
|
||||||
<item index="2" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.NonNull" />
|
|
||||||
<item index="3" class="java.lang.String" itemvalue="android.support.annotation.NonNull" />
|
|
||||||
</list>
|
|
||||||
</value>
|
|
||||||
</option>
|
|
||||||
</component>
|
|
||||||
<component name="ProjectLevelVcsManager" settingsEditedManually="false">
|
|
||||||
<OptionsSetting value="true" id="Add" />
|
|
||||||
<OptionsSetting value="true" id="Remove" />
|
|
||||||
<OptionsSetting value="true" id="Checkout" />
|
|
||||||
<OptionsSetting value="true" id="Update" />
|
|
||||||
<OptionsSetting value="true" id="Status" />
|
|
||||||
<OptionsSetting value="true" id="Edit" />
|
|
||||||
<ConfirmationsSetting value="0" id="Add" />
|
|
||||||
<ConfirmationsSetting value="0" id="Remove" />
|
|
||||||
</component>
|
|
||||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" default="true" assert-keyword="true" jdk-15="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
|
|
||||||
<output url="file://$PROJECT_DIR$/build/classes" />
|
|
||||||
</component>
|
|
||||||
<component name="ProjectType">
|
|
||||||
<option name="id" value="Android" />
|
|
||||||
</component>
|
|
||||||
</project>
|
|
9
.idea/modules.xml
generated
9
.idea/modules.xml
generated
@@ -1,9 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="ProjectModuleManager">
|
|
||||||
<modules>
|
|
||||||
<module fileurl="file://$PROJECT_DIR$/NewPipe.iml" filepath="$PROJECT_DIR$/NewPipe.iml" />
|
|
||||||
<module fileurl="file://$PROJECT_DIR$/app/app.iml" filepath="$PROJECT_DIR$/app/app.iml" />
|
|
||||||
</modules>
|
|
||||||
</component>
|
|
||||||
</project>
|
|
12
.idea/runConfigurations.xml
generated
12
.idea/runConfigurations.xml
generated
@@ -1,12 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="RunConfigurationProducerService">
|
|
||||||
<option name="ignoredProducers">
|
|
||||||
<set>
|
|
||||||
<option value="org.jetbrains.plugins.gradle.execution.test.runner.AllInPackageGradleConfigurationProducer" />
|
|
||||||
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestClassGradleConfigurationProducer" />
|
|
||||||
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestMethodGradleConfigurationProducer" />
|
|
||||||
</set>
|
|
||||||
</option>
|
|
||||||
</component>
|
|
||||||
</project>
|
|
6
.idea/vcs.xml
generated
6
.idea/vcs.xml
generated
@@ -1,6 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="VcsDirectoryMappings">
|
|
||||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
|
||||||
</component>
|
|
||||||
</project>
|
|
30
.travis.yml
Normal file
30
.travis.yml
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
language: android
|
||||||
|
android:
|
||||||
|
components:
|
||||||
|
# The BuildTools version used by NewPipe
|
||||||
|
- tools
|
||||||
|
- build-tools-23.0.2
|
||||||
|
|
||||||
|
# The SDK version used to compile NewPipe
|
||||||
|
- android-23
|
||||||
|
|
||||||
|
# Additional components
|
||||||
|
- extra-android-support
|
||||||
|
- extra-android-m2repository
|
||||||
|
|
||||||
|
# Emulators
|
||||||
|
- sys-img-armeabi-v7a-android-21
|
||||||
|
- sys-img-armeabi-v7a-android-19
|
||||||
|
- sys-img-armeabi-v7a-android-15
|
||||||
|
|
||||||
|
env:
|
||||||
|
global:
|
||||||
|
- ADB_INSTALL_TIMEOUT=8 # minutes (2 by default)
|
||||||
|
matrix:
|
||||||
|
- ANDROID_TARGET=android-19 ANDROID_ABI=armeabi-v7a
|
||||||
|
|
||||||
|
before_script:
|
||||||
|
- echo no | android create avd --force -n test -t $ANDROID_TARGET --abi $ANDROID_ABI
|
||||||
|
- emulator -avd test -no-skin -no-audio -no-window &
|
||||||
|
- android-wait-for-emulator
|
||||||
|
- adb shell input keyevent 82 &
|
33
CONTRIBUTING.md
Normal file
33
CONTRIBUTING.md
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
#Contribution
|
||||||
|
|
||||||
|
This document contains guidelines on making contributions to NewPipe.
|
||||||
|
|
||||||
|
## Programming
|
||||||
|
|
||||||
|
* Follow the [Google Style Guidelines](https://google.github.io/styleguide/javaguide.html)
|
||||||
|
* Make a new feature on a separate branch, not on the master branch
|
||||||
|
* Make a [pull request](https://github.com/theScrabi/NewPipe/pulls) if you're done with your changes
|
||||||
|
* When submitting changes, you agree that your code will be GPLv3 licensed
|
||||||
|
|
||||||
|
## Commit messages
|
||||||
|
|
||||||
|
* The subject line of your commit message shouldn't be longer than 72 characters
|
||||||
|
* Try to keep each line of your commit message 72 characters to ensure proper
|
||||||
|
compatibility with all git tools
|
||||||
|
* [This guide](http://chris.beams.io/posts/git-commit/) goes more in depth on what makes a good commit message
|
||||||
|
|
||||||
|
## Translation
|
||||||
|
|
||||||
|
* NewPipe can be translated on [weblate](https://hosted.weblate.org/projects/newpipe/strings/)
|
||||||
|
|
||||||
|
## Issue reporting
|
||||||
|
|
||||||
|
* Search the [existing issues](https://github.com/theScrabi/NewPipe/issues) first to make sure your issue hasn't been reported before
|
||||||
|
* Check if this issue is already fixed in the repository
|
||||||
|
* When making bug reports, be sure to tell which version of NewPipe you are using and the steps to reproduce the problem
|
||||||
|
* Please include a log if you can
|
||||||
|
|
||||||
|
## Communication
|
||||||
|
|
||||||
|
* For the time being, [Slack](http://invite.chschtsch.ml/) is being used for project communication
|
||||||
|
* Feel free to post suggestions, changes, ideas etc!
|
19
NewPipe.iml
19
NewPipe.iml
@@ -1,19 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<module external.linked.project.id="NewPipe" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$" external.system.id="GRADLE" external.system.module.group="" external.system.module.version="unspecified" type="JAVA_MODULE" version="4">
|
|
||||||
<component name="FacetManager">
|
|
||||||
<facet type="java-gradle" name="Java-Gradle">
|
|
||||||
<configuration>
|
|
||||||
<option name="BUILD_FOLDER_PATH" value="$MODULE_DIR$/build" />
|
|
||||||
<option name="BUILDABLE" value="false" />
|
|
||||||
</configuration>
|
|
||||||
</facet>
|
|
||||||
</component>
|
|
||||||
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_7" inherit-compiler-output="true">
|
|
||||||
<exclude-output />
|
|
||||||
<content url="file://$MODULE_DIR$">
|
|
||||||
<excludeFolder url="file://$MODULE_DIR$/.gradle" />
|
|
||||||
</content>
|
|
||||||
<orderEntry type="inheritedJdk" />
|
|
||||||
<orderEntry type="sourceFolder" forTests="false" />
|
|
||||||
</component>
|
|
||||||
</module>
|
|
54
README.md
54
README.md
@@ -1,30 +1,44 @@
|
|||||||
# NewPipe
|
# NewPipe
|
||||||
|
NewPipe: A free lightweight Youtube frontend for Android.
|
||||||
|
|
||||||
|
[](http://dasochan.nl/newpipe/)
|
||||||
|
|
||||||
|
Project status:
|
||||||
[](https://hosted.weblate.org/engage/NewPipe/)
|
[](https://hosted.weblate.org/engage/NewPipe/)
|
||||||
|
[](https://travis-ci.org/theScrabi/NewPipe)
|
||||||
|
|
||||||
[](http://dasochan.nl/newpipe/)
|
## Get NewPipe
|
||||||
NewPipe: A free lightweight Youtube fronted for Android.
|
|
||||||
|
|
||||||
[](https://f-droid.org/repository/browse/?fdfilter=newpipe&fdid=org.schabi.newpipe)
|
[](https://f-droid.org/repository/browse/?fdfilter=newpipe&fdid=org.schabi.newpipe)
|
||||||
|
|
||||||
|
## Screenshots
|
||||||
|
|
||||||
|
[<img src="screenshots/screenshot_1.png" width=150>](screenshots/screenshot_1.png)
|
||||||
|
[<img src="screenshots/screenshot_2.png" width=150>](screenshots/screenshot_2.png)
|
||||||
|
[<img src="screenshots/screenshot_3.png" width=150>](screenshots/screenshot_3.png)
|
||||||
|
[<img src="screenshots/screenshot_4.png" width=150>](screenshots/screenshot_4.png)
|
||||||
|
[<img src="screenshots/screenshot_5.png" width=150>](screenshots/screenshot_5.png)
|
||||||
|
|
||||||
## Description
|
## Description
|
||||||
|
|
||||||
NewPipe does not use any Google framework libraries, or the Youtube api. It only parses the website in order to gain the information it needs. Therefore this app can be used on devices without g-services installed. Also NewPipe does not store data on the Youtube website (no login), and it's free software.
|
NewPipe does not use any Google framework libraries, or the YouTube API. It only parses the website in order to gain the information it needs. Therefore this app can be used on devices without Google Services installed. Also, you don't need a YouTube account to use NewPipe, and it's FLOSS.
|
||||||
|
|
||||||
## Features
|
### Features
|
||||||
|
|
||||||
* Search videos
|
* Search videos
|
||||||
* Display general information about a video
|
* Display general information about a video
|
||||||
* Watch Youtube videos
|
* Watch YouTube videos
|
||||||
* Listen to Youtube videos (audio only streaming)
|
* Listen to YouTube videos (experimental)
|
||||||
* Select the streaming player to watch the video with
|
* Select the streaming player to watch the video with
|
||||||
* Download videos (working, but it could be better)
|
* Download videos (experimental)
|
||||||
* Download audio only (working but, but it could be better)
|
* Download audio only (experimental)
|
||||||
* Open a video in Kodi
|
* Open a video in Kodi
|
||||||
|
* Show Next/Related videos
|
||||||
|
* Search YouTube in a specific language
|
||||||
|
* Orbot/Tor support (no streaming yet, experimental)
|
||||||
|
|
||||||
## Coming Features
|
### Coming Features
|
||||||
|
|
||||||
* Shows Next/Related videos
|
|
||||||
* Improved Downloading
|
* Improved Downloading
|
||||||
* Bookmarks
|
* Bookmarks
|
||||||
* View history
|
* View history
|
||||||
@@ -36,10 +50,20 @@ NewPipe does not use any Google framework libraries, or the Youtube api. It only
|
|||||||
* Search/Watch Playlists
|
* Search/Watch Playlists
|
||||||
* ... and many more
|
* ... and many more
|
||||||
|
|
||||||
### Multi service support
|
### Multiservice support
|
||||||
Generally NewPipe is designed to not only support YouTube, but many more streaming services. How ever, right now NewPipe is not stable enough to support more than only youtube. But if all works as plant, NewPipe will get such support by the version 2.0.
|
Although NewPipe only supports YouTube at the moment, it's designed to support many more streaming services. The plan is, that NewPipe will get such support by the version 2.0.
|
||||||
|
|
||||||
# Help is always welcome !!!
|
|
||||||
Whether its about ideas, translation, design changes, code cleaning, or real heavy code changes. Help is always welcome.
|
|
||||||
|
|
||||||
|
## Contribution
|
||||||
|
Whether you have ideas, translation, design changes, code cleaning, or real heavy code changes, help is always welcome.
|
||||||
The more is done the better it gets!
|
The more is done the better it gets!
|
||||||
|
|
||||||
|
If you'd like to get involved, check our [contribution notes](CONTRIBUTING.md).
|
||||||
|
|
||||||
|
## License
|
||||||
|
[](http://www.gnu.org/licenses/gpl-3.0.en.html)
|
||||||
|
|
||||||
|
NewPipe is Free Software: You can use, study share and improve it at your
|
||||||
|
will. Specifically you can redistribute and/or modify it under the terms of the
|
||||||
|
[GNU General Public License](https://www.gnu.org/licenses/gpl.html) as
|
||||||
|
published by the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
2
app/.gitignore
vendored
2
app/.gitignore
vendored
@@ -1 +1,3 @@
|
|||||||
|
.gitignore
|
||||||
/build
|
/build
|
||||||
|
app.iml
|
||||||
|
103
app/app.iml
103
app/app.iml
@@ -1,103 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<module external.linked.project.id=":app" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$/.." external.system.id="GRADLE" external.system.module.group="NewPipe" external.system.module.version="unspecified" type="JAVA_MODULE" version="4">
|
|
||||||
<component name="FacetManager">
|
|
||||||
<facet type="android-gradle" name="Android-Gradle">
|
|
||||||
<configuration>
|
|
||||||
<option name="GRADLE_PROJECT_PATH" value=":app" />
|
|
||||||
</configuration>
|
|
||||||
</facet>
|
|
||||||
<facet type="android" name="Android">
|
|
||||||
<configuration>
|
|
||||||
<option name="SELECTED_BUILD_VARIANT" value="debug" />
|
|
||||||
<option name="SELECTED_TEST_ARTIFACT" value="_android_test_" />
|
|
||||||
<option name="ASSEMBLE_TASK_NAME" value="assembleDebug" />
|
|
||||||
<option name="COMPILE_JAVA_TASK_NAME" value="compileDebugSources" />
|
|
||||||
<option name="ASSEMBLE_TEST_TASK_NAME" value="assembleDebugAndroidTest" />
|
|
||||||
<option name="COMPILE_JAVA_TEST_TASK_NAME" value="compileDebugAndroidTestSources" />
|
|
||||||
<afterSyncTasks>
|
|
||||||
<task>generateDebugAndroidTestSources</task>
|
|
||||||
<task>generateDebugSources</task>
|
|
||||||
</afterSyncTasks>
|
|
||||||
<option name="ALLOW_USER_CONFIGURATION" value="false" />
|
|
||||||
<option name="MANIFEST_FILE_RELATIVE_PATH" value="/src/main/AndroidManifest.xml" />
|
|
||||||
<option name="RES_FOLDER_RELATIVE_PATH" value="/src/main/res" />
|
|
||||||
<option name="RES_FOLDERS_RELATIVE_PATH" value="file://$MODULE_DIR$/src/main/res" />
|
|
||||||
<option name="ASSETS_FOLDER_RELATIVE_PATH" value="/src/main/assets" />
|
|
||||||
</configuration>
|
|
||||||
</facet>
|
|
||||||
</component>
|
|
||||||
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_7" inherit-compiler-output="false">
|
|
||||||
<output url="file://$MODULE_DIR$/build/intermediates/classes/debug" />
|
|
||||||
<output-test url="file://$MODULE_DIR$/build/intermediates/classes/androidTest/debug" />
|
|
||||||
<exclude-output />
|
|
||||||
<content url="file://$MODULE_DIR$">
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/r/debug" isTestSource="false" generated="true" />
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/aidl/debug" isTestSource="false" generated="true" />
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/debug" isTestSource="false" generated="true" />
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/debug" isTestSource="false" generated="true" />
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/debug" type="java-resource" />
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/resValues/debug" type="java-resource" />
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/r/androidTest/debug" isTestSource="true" generated="true" />
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/aidl/androidTest/debug" isTestSource="true" generated="true" />
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/androidTest/debug" isTestSource="true" generated="true" />
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/androidTest/debug" isTestSource="true" generated="true" />
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/androidTest/debug" type="java-test-resource" />
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/resValues/androidTest/debug" type="java-test-resource" />
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src/debug/res" type="java-resource" />
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src/debug/resources" type="java-resource" />
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src/debug/assets" type="java-resource" />
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src/debug/aidl" isTestSource="false" />
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src/debug/java" isTestSource="false" />
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src/debug/jni" isTestSource="false" />
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src/debug/rs" isTestSource="false" />
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src/main/res" type="java-resource" />
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src/main/assets" type="java-resource" />
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src/main/aidl" isTestSource="false" />
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src/main/jni" isTestSource="false" />
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src/main/rs" isTestSource="false" />
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/res" type="java-test-resource" />
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/resources" type="java-test-resource" />
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/assets" type="java-test-resource" />
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/aidl" isTestSource="true" />
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/java" isTestSource="true" />
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/jni" isTestSource="true" />
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/rs" isTestSource="true" />
|
|
||||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/assets" />
|
|
||||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/bundles" />
|
|
||||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/classes" />
|
|
||||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/coverage-instrumented-classes" />
|
|
||||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/dependency-cache" />
|
|
||||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/dex" />
|
|
||||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/dex-cache" />
|
|
||||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/appcompat-v7/23.1.0/jars" />
|
|
||||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/design/23.1.0/jars" />
|
|
||||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/recyclerview-v7/23.1.0/jars" />
|
|
||||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/support-v4/23.1.0/jars" />
|
|
||||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental" />
|
|
||||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/jacoco" />
|
|
||||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/javaResources" />
|
|
||||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/libs" />
|
|
||||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/lint" />
|
|
||||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/manifests" />
|
|
||||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/ndk" />
|
|
||||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/pre-dexed" />
|
|
||||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/proguard" />
|
|
||||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/res" />
|
|
||||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/rs" />
|
|
||||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/symbols" />
|
|
||||||
<excludeFolder url="file://$MODULE_DIR$/build/outputs" />
|
|
||||||
<excludeFolder url="file://$MODULE_DIR$/build/tmp" />
|
|
||||||
</content>
|
|
||||||
<orderEntry type="jdk" jdkName="Android API 23 Platform" jdkType="Android SDK" />
|
|
||||||
<orderEntry type="sourceFolder" forTests="false" />
|
|
||||||
<orderEntry type="library" exported="" name="recyclerview-v7-23.1.0" level="project" />
|
|
||||||
<orderEntry type="library" exported="" name="jsoup-1.8.3" level="project" />
|
|
||||||
<orderEntry type="library" exported="" name="support-v4-23.1.0" level="project" />
|
|
||||||
<orderEntry type="library" exported="" name="rhino-1.7.7" level="project" />
|
|
||||||
<orderEntry type="library" exported="" name="design-23.1.0" level="project" />
|
|
||||||
<orderEntry type="library" exported="" name="appcompat-v7-23.1.0" level="project" />
|
|
||||||
<orderEntry type="library" exported="" name="support-annotations-23.1.0" level="project" />
|
|
||||||
</component>
|
|
||||||
</module>
|
|
@@ -2,14 +2,14 @@ apply plugin: 'com.android.application'
|
|||||||
|
|
||||||
android {
|
android {
|
||||||
compileSdkVersion 23
|
compileSdkVersion 23
|
||||||
buildToolsVersion "23.0.1"
|
buildToolsVersion '23.0.2'
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
applicationId "org.schabi.newpipe"
|
applicationId "org.schabi.newpipe"
|
||||||
minSdkVersion 15
|
minSdkVersion 15
|
||||||
targetSdkVersion 23
|
targetSdkVersion 23
|
||||||
versionCode 5
|
versionCode 13
|
||||||
versionName "0.5.0"
|
versionName "0.7.4"
|
||||||
}
|
}
|
||||||
buildTypes {
|
buildTypes {
|
||||||
release {
|
release {
|
||||||
@@ -17,13 +17,29 @@ android {
|
|||||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lintOptions {
|
||||||
|
checkReleaseBuilds false
|
||||||
|
// Or, if you prefer, you can continue to check for errors in release builds,
|
||||||
|
// but continue the build even when errors are found:
|
||||||
|
abortOnError false
|
||||||
|
}
|
||||||
|
compileOptions {
|
||||||
|
sourceCompatibility JavaVersion.VERSION_1_7
|
||||||
|
targetCompatibility JavaVersion.VERSION_1_7
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
compile fileTree(include: ['*.jar'], dir: 'libs')
|
compile fileTree(include: ['*.jar'], dir: 'libs')
|
||||||
compile 'com.android.support:appcompat-v7:23.1.0'
|
compile 'com.android.support:appcompat-v7:23.1.1'
|
||||||
compile 'com.android.support:support-v4:23.1.0'
|
compile 'com.android.support:support-v4:23.1.1'
|
||||||
|
compile 'com.android.support:design:23.1.1'
|
||||||
|
compile 'com.android.support:recyclerview-v7:23.1.1'
|
||||||
compile 'org.jsoup:jsoup:1.8.3'
|
compile 'org.jsoup:jsoup:1.8.3'
|
||||||
compile 'org.mozilla:rhino:1.7.7'
|
compile 'org.mozilla:rhino:1.7.7'
|
||||||
compile 'com.android.support:design:23.1.0'
|
compile 'info.guardianproject.netcipher:netcipher:1.2'
|
||||||
|
compile 'de.hdodenhof:circleimageview:2.0.0'
|
||||||
|
compile 'com.nostra13.universalimageloader:universal-image-loader:1.9.5'
|
||||||
|
compile 'com.github.nirhart:parallaxscroll:1.0'
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,93 @@
|
|||||||
|
package org.schabi.newpipe.services.youtube;
|
||||||
|
|
||||||
|
import android.test.AndroidTestCase;
|
||||||
|
|
||||||
|
import org.schabi.newpipe.crawler.VideoPreviewInfo;
|
||||||
|
import org.schabi.newpipe.crawler.SearchEngine;
|
||||||
|
import org.schabi.newpipe.crawler.services.youtube.YoutubeSearchEngine;
|
||||||
|
import org.schabi.newpipe.Downloader;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by the-scrabi on 29.12.15.
|
||||||
|
*
|
||||||
|
* Copyright (C) Christian Schabesberger 2015 <chris.schabesberger@mailbox.org>
|
||||||
|
* YoutubeSearchEngineTest.java is part of NewPipe.
|
||||||
|
*
|
||||||
|
* NewPipe is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* NewPipe is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with NewPipe. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class YoutubeSearchEngineTest extends AndroidTestCase {
|
||||||
|
private SearchEngine.Result result;
|
||||||
|
private ArrayList<String> suggestionReply;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setUp() throws Exception{
|
||||||
|
super.setUp();
|
||||||
|
SearchEngine engine = new YoutubeSearchEngine();
|
||||||
|
|
||||||
|
result = engine.search("https://www.youtube.com/results?search_query=bla",
|
||||||
|
0, "de", new Downloader());
|
||||||
|
suggestionReply = engine.suggestionList("hello", new Downloader());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testIfNoErrorOccur() {
|
||||||
|
assertEquals(result.errorMessage, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testIfListIsNotEmpty() {
|
||||||
|
assertEquals(result.resultList.size() > 0, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testItemsHaveTitle() {
|
||||||
|
for(VideoPreviewInfo i : result.resultList) {
|
||||||
|
assertEquals(i.title.isEmpty(), false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testItemsHaveUploader() {
|
||||||
|
for(VideoPreviewInfo i : result.resultList) {
|
||||||
|
assertEquals(i.uploader.isEmpty(), false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testItemsHaveRightDuration() {
|
||||||
|
for(VideoPreviewInfo i : result.resultList) {
|
||||||
|
assertTrue(i.duration, i.duration.contains(":"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testItemsHaveRightThumbnail() {
|
||||||
|
for (VideoPreviewInfo i : result.resultList) {
|
||||||
|
assertTrue(i.thumbnail_url, i.thumbnail_url.contains("https://"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testItemsHaveRightVideoUrl() {
|
||||||
|
for (VideoPreviewInfo i : result.resultList) {
|
||||||
|
assertTrue(i.webpage_url, i.webpage_url.contains("https://"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testIfSuggestionsAreReplied() {
|
||||||
|
assertEquals(suggestionReply.size() > 0, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testIfSuggestionsAreValid() {
|
||||||
|
for(String s : suggestionReply) {
|
||||||
|
assertTrue(s, !s.isEmpty());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,109 @@
|
|||||||
|
package org.schabi.newpipe.services.youtube;
|
||||||
|
|
||||||
|
import android.test.AndroidTestCase;
|
||||||
|
|
||||||
|
import org.schabi.newpipe.Downloader;
|
||||||
|
import org.schabi.newpipe.crawler.CrawlingException;
|
||||||
|
import org.schabi.newpipe.crawler.ParsingException;
|
||||||
|
import org.schabi.newpipe.crawler.services.youtube.YoutubeStreamExtractor;
|
||||||
|
import org.schabi.newpipe.crawler.VideoInfo;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by the-scrabi on 30.12.15.
|
||||||
|
*
|
||||||
|
* Copyright (C) Christian Schabesberger 2015 <chris.schabesberger@mailbox.org>
|
||||||
|
* YoutubeVideoExtractorDefault.java is part of NewPipe.
|
||||||
|
*
|
||||||
|
* NewPipe is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* NewPipe is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with NewPipe. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class YoutubeStreamExtractorDefaultTest extends AndroidTestCase {
|
||||||
|
private YoutubeStreamExtractor extractor;
|
||||||
|
|
||||||
|
public void setUp() throws IOException, CrawlingException {
|
||||||
|
/* some anonymus video test
|
||||||
|
extractor = new YoutubeStreamExtractor("https://www.youtube.com/watch?v=FmG385_uUys",
|
||||||
|
new Downloader()); */
|
||||||
|
/* some vevo video (suggested to test against) */
|
||||||
|
extractor = new YoutubeStreamExtractor("https://www.youtube.com/watch?v=YQHsXMglC9A",
|
||||||
|
new Downloader());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testGetInvalidTimeStamp() throws ParsingException {
|
||||||
|
assertTrue(Integer.toString(extractor.getTimeStamp()),
|
||||||
|
extractor.getTimeStamp() <= 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testGetValidTimeStamp() throws CrawlingException, IOException {
|
||||||
|
YoutubeStreamExtractor extractor =
|
||||||
|
new YoutubeStreamExtractor("https://youtu.be/FmG385_uUys?t=174", new Downloader());
|
||||||
|
assertTrue(Integer.toString(extractor.getTimeStamp()),
|
||||||
|
extractor.getTimeStamp() == 174);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testGetTitle() throws ParsingException {
|
||||||
|
assertTrue(!extractor.getTitle().isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testGetDescription() throws ParsingException {
|
||||||
|
assertTrue(extractor.getDescription() != null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testGetUploader() throws ParsingException {
|
||||||
|
assertTrue(!extractor.getUploader().isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testGetLength() throws ParsingException {
|
||||||
|
assertTrue(extractor.getLength() > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testGetViews() throws ParsingException {
|
||||||
|
assertTrue(extractor.getLength() > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testGetUploadDate() throws ParsingException {
|
||||||
|
assertTrue(extractor.getUploadDate().length() > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testGetThumbnailUrl() throws ParsingException {
|
||||||
|
assertTrue(extractor.getThumbnailUrl(),
|
||||||
|
extractor.getThumbnailUrl().contains("https://"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testGetUploaderThumbnailUrl() throws ParsingException {
|
||||||
|
assertTrue(extractor.getUploaderThumbnailUrl(),
|
||||||
|
extractor.getUploaderThumbnailUrl().contains("https://"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testGetAudioStreams() throws ParsingException {
|
||||||
|
assertTrue(!extractor.getAudioStreams().isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testGetVideoStreams() throws ParsingException {
|
||||||
|
for(VideoInfo.VideoStream s : extractor.getVideoStreams()) {
|
||||||
|
assertTrue(s.url,
|
||||||
|
s.url.contains("https://"));
|
||||||
|
assertTrue(s.resolution.length() > 0);
|
||||||
|
assertTrue(Integer.toString(s.format),
|
||||||
|
0 <= s.format && s.format <= 4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testGetDashMpd() throws ParsingException {
|
||||||
|
assertTrue(extractor.getDashMpdUrl(),
|
||||||
|
!extractor.getDashMpdUrl().isEmpty());
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,49 @@
|
|||||||
|
package org.schabi.newpipe.services.youtube;
|
||||||
|
|
||||||
|
import android.test.AndroidTestCase;
|
||||||
|
|
||||||
|
import org.schabi.newpipe.Downloader;
|
||||||
|
import org.schabi.newpipe.crawler.CrawlingException;
|
||||||
|
import org.schabi.newpipe.crawler.services.youtube.YoutubeStreamExtractor;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by the-scrabi on 30.12.15.
|
||||||
|
*
|
||||||
|
* Copyright (C) Christian Schabesberger 2015 <chris.schabesberger@mailbox.org>
|
||||||
|
* YoutubeVideoExtractorGema.java is part of NewPipe.
|
||||||
|
*
|
||||||
|
* NewPipe is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* NewPipe is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with NewPipe. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
// This class only works in Germany.
|
||||||
|
public class YoutubeStreamExtractorGemaTest extends AndroidTestCase {
|
||||||
|
|
||||||
|
// Deaktivate this Test Case bevore uploading it githup, otherwise CI will fail.
|
||||||
|
private static final boolean testActive = false;
|
||||||
|
|
||||||
|
public void testGemaError() throws IOException, CrawlingException {
|
||||||
|
if(testActive) {
|
||||||
|
try {
|
||||||
|
new YoutubeStreamExtractor("https://www.youtube.com/watch?v=3O1_3zBUKM8",
|
||||||
|
new Downloader());
|
||||||
|
assertTrue("Gema exception not thrown", false);
|
||||||
|
} catch(YoutubeStreamExtractor.GemaException ge) {
|
||||||
|
assertTrue(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -1,19 +1,23 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
package="org.schabi.newpipe" >
|
package="org.schabi.newpipe" >
|
||||||
|
|
||||||
<uses-permission android:name= "android.permission.INTERNET" />
|
<uses-permission android:name= "android.permission.INTERNET" />
|
||||||
|
<uses-permission android:name= "android.permission.WAKE_LOCK" />
|
||||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
|
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
|
||||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
|
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
|
||||||
<application
|
<application
|
||||||
|
android:name=".App"
|
||||||
android:allowBackup="true"
|
android:allowBackup="true"
|
||||||
android:icon="@mipmap/ic_launcher"
|
android:icon="@mipmap/ic_launcher"
|
||||||
android:logo="@mipmap/ic_launcher"
|
android:logo="@mipmap/ic_launcher"
|
||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
android:theme="@style/AppTheme" >
|
android:theme="@style/AppTheme"
|
||||||
|
tools:ignore="AllowBackup">
|
||||||
<activity
|
<activity
|
||||||
android:name=".VideoItemListActivity"
|
android:name=".VideoItemListActivity"
|
||||||
android:label="@string/app_name" >
|
android:label="@string/app_name"
|
||||||
|
android:configChanges="orientation|screenSize">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.MAIN" />
|
<action android:name="android.intent.action.MAIN" />
|
||||||
|
|
||||||
@@ -22,57 +26,81 @@
|
|||||||
</activity>
|
</activity>
|
||||||
<activity
|
<activity
|
||||||
android:name=".VideoItemDetailActivity"
|
android:name=".VideoItemDetailActivity"
|
||||||
android:label="@string/title_videoitem_detail" >
|
android:label="@string/title_videoitem_detail"
|
||||||
|
android:theme="@style/AppTheme"
|
||||||
|
android:configChanges="orientation|screenSize"
|
||||||
|
android:screenOrientation="portrait">
|
||||||
<meta-data
|
<meta-data
|
||||||
android:name="android.support.PARENT_ACTIVITY"
|
android:name="android.support.PARENT_ACTIVITY"
|
||||||
android:value=".VideoItemListActivity" />
|
android:value=".VideoItemListActivity" />
|
||||||
|
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.VIEW"/>
|
<action android:name="android.intent.action.VIEW" />
|
||||||
|
<action android:name="android.media.action.MEDIA_PLAY_FROM_SEARCH" />
|
||||||
|
<action android:name="android.nfc.action.NDEF_DISCOVERED" />
|
||||||
|
|
||||||
<category android:name="android.intent.category.DEFAULT" />
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
<category android:name="android.intent.category.BROWSABLE" />
|
<category android:name="android.intent.category.BROWSABLE" />
|
||||||
|
|
||||||
<data
|
<data android:scheme="http" />
|
||||||
android:host="youtube.com"
|
<data android:scheme="https" />
|
||||||
android:scheme="http"
|
<data android:host="youtube.com" />
|
||||||
android:pathPattern="/?*#*/*watch"/>
|
<data android:host="m.youtube.com" />
|
||||||
<data
|
<data android:host="www.youtube.com" />
|
||||||
android:host="youtube.com"
|
<data android:pathPrefix="/v/" />
|
||||||
android:scheme="https"
|
<data android:pathPrefix="/watch" />
|
||||||
android:pathPattern="/?*#*/*watch"/>
|
</intent-filter>
|
||||||
<data
|
<intent-filter>
|
||||||
android:host="www.youtube.com"
|
<action android:name="android.intent.action.VIEW" />
|
||||||
android:scheme="http"
|
<action android:name="android.media.action.MEDIA_PLAY_FROM_SEARCH" />
|
||||||
android:pathPattern="/?*#*/*watch"/>
|
<action android:name="android.nfc.action.NDEF_DISCOVERED" />
|
||||||
<data
|
|
||||||
android:host="www.youtube.com"
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
android:scheme="https"
|
<category android:name="android.intent.category.BROWSABLE" />
|
||||||
android:pathPattern="/?*#*/*watch"/>
|
|
||||||
<data
|
<data android:scheme="http" />
|
||||||
android:host="m.youtube.com"
|
<data android:scheme="https" />
|
||||||
android:scheme="http"
|
<data android:host="youtu.be" />
|
||||||
android:pathPattern="/?*#*/*watch"/>
|
<data android:pathPrefix="/" />
|
||||||
<data
|
</intent-filter>
|
||||||
android:host="m.youtube.com"
|
<intent-filter>
|
||||||
android:scheme="https"
|
<action android:name="android.intent.action.VIEW" />
|
||||||
android:pathPattern="/?*#*/*watch"/>
|
<action android:name="android.media.action.MEDIA_PLAY_FROM_SEARCH" />
|
||||||
<data
|
<action android:name="android.nfc.action.NDEF_DISCOVERED" />
|
||||||
android:host="youtu.be"
|
|
||||||
android:scheme="https"
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
android:pathPrefix="/"/>
|
<category android:name="android.intent.category.BROWSABLE" />
|
||||||
<data
|
|
||||||
android:host="youtu.be"
|
<data android:scheme="vnd.youtube" />
|
||||||
android:scheme="http"
|
<data android:scheme="vnd.youtube.launch" />
|
||||||
android:pathPrefix="/"/>
|
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
<activity android:name=".PlayVideoActivity"
|
<activity android:name=".PlayVideoActivity"
|
||||||
android:configChanges="orientation|keyboardHidden|screenSize"
|
android:configChanges="orientation|keyboardHidden|screenSize"
|
||||||
android:theme="@style/FullscreenTheme"
|
android:theme="@style/VideoPlayerTheme"
|
||||||
>
|
android:parentActivityName=".VideoItemDetailActivity"
|
||||||
|
tools:ignore="UnusedAttribute">
|
||||||
</activity>
|
</activity>
|
||||||
|
<service
|
||||||
|
android:name=".BackgroundPlayer"
|
||||||
|
android:label="@string/background_player_name"
|
||||||
|
android:exported="false" />
|
||||||
<activity
|
<activity
|
||||||
android:name=".SettingsActivity"
|
android:name=".SettingsActivity"
|
||||||
android:label="@string/title_activity_settings" >
|
android:label="@string/settings_activity_title" >
|
||||||
</activity>
|
</activity>
|
||||||
|
<activity
|
||||||
|
android:name=".PanicResponderActivity"
|
||||||
|
android:launchMode="singleInstance"
|
||||||
|
android:noHistory="true"
|
||||||
|
android:theme="@android:style/Theme.NoDisplay">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="info.guardianproject.panic.action.TRIGGER" />
|
||||||
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
|
</intent-filter>
|
||||||
|
</activity>
|
||||||
|
<activity
|
||||||
|
android:name=".ExitActivity"
|
||||||
|
android:theme="@android:style/Theme.NoDisplay" />
|
||||||
</application>
|
</application>
|
||||||
</manifest>
|
</manifest>
|
||||||
|
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,42 @@
|
|||||||
|
package org.schabi.newpipe;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Christian Schabesberger on 24.12.15.
|
||||||
|
*
|
||||||
|
* Copyright (C) Christian Schabesberger 2015 <chris.schabesberger@mailbox.org>
|
||||||
|
* ActivityCommunicator.java is part of NewPipe.
|
||||||
|
*
|
||||||
|
* NewPipe is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* NewPipe is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with NewPipe. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Singleton:
|
||||||
|
* Used to send data between certain Activity/Services within the same process.
|
||||||
|
* This can be considered as hack inside the Android universe. **/
|
||||||
|
public class ActivityCommunicator {
|
||||||
|
|
||||||
|
private static ActivityCommunicator activityCommunicator = null;
|
||||||
|
|
||||||
|
public static ActivityCommunicator getCommunicator() {
|
||||||
|
if(activityCommunicator == null) {
|
||||||
|
activityCommunicator = new ActivityCommunicator();
|
||||||
|
}
|
||||||
|
return activityCommunicator;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Thumbnail send from VideoItemDetailFragment to BackgroundPlayer
|
||||||
|
public volatile Bitmap backgroundPlayerThumbnail;
|
||||||
|
}
|
78
app/src/main/java/org/schabi/newpipe/App.java
Normal file
78
app/src/main/java/org/schabi/newpipe/App.java
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
package org.schabi.newpipe;
|
||||||
|
|
||||||
|
import android.app.Application;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.SharedPreferences;
|
||||||
|
import android.preference.PreferenceManager;
|
||||||
|
|
||||||
|
import com.nostra13.universalimageloader.core.ImageLoader;
|
||||||
|
import com.nostra13.universalimageloader.core.ImageLoaderConfiguration;
|
||||||
|
|
||||||
|
import info.guardianproject.netcipher.NetCipher;
|
||||||
|
import info.guardianproject.netcipher.proxy.OrbotHelper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copyright (C) Hans-Christoph Steiner 2016 <hans@eds.org>
|
||||||
|
* App.java is part of NewPipe.
|
||||||
|
*
|
||||||
|
* NewPipe is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* NewPipe is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with NewPipe. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class App extends Application {
|
||||||
|
|
||||||
|
private static boolean useTor;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate() {
|
||||||
|
super.onCreate();
|
||||||
|
|
||||||
|
// Initialize image loader
|
||||||
|
ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(this).build();
|
||||||
|
ImageLoader.getInstance().init(config);
|
||||||
|
|
||||||
|
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
|
||||||
|
if(prefs.getBoolean(getString(R.string.use_tor_key), false)) {
|
||||||
|
OrbotHelper.requestStartTor(this);
|
||||||
|
configureTor(true);
|
||||||
|
} else {
|
||||||
|
configureTor(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// DO NOT REMOVE THIS FUNCTION!!!
|
||||||
|
// Otherwise downloadPathPreference has invalid value.
|
||||||
|
SettingsActivity.initSettings(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the proxy settings based on whether Tor should be enabled or not.
|
||||||
|
*/
|
||||||
|
static void configureTor(boolean enabled) {
|
||||||
|
useTor = enabled;
|
||||||
|
if (useTor) {
|
||||||
|
NetCipher.useTor();
|
||||||
|
} else {
|
||||||
|
NetCipher.setProxy(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void checkStartTor(Context context) {
|
||||||
|
if (useTor) {
|
||||||
|
OrbotHelper.requestStartTor(context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static boolean isUsingTor() {
|
||||||
|
return useTor;
|
||||||
|
}
|
||||||
|
}
|
368
app/src/main/java/org/schabi/newpipe/BackgroundPlayer.java
Normal file
368
app/src/main/java/org/schabi/newpipe/BackgroundPlayer.java
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,18 +1,29 @@
|
|||||||
package org.schabi.newpipe;
|
package org.schabi.newpipe;
|
||||||
|
|
||||||
|
import android.Manifest;
|
||||||
|
import android.app.Activity;
|
||||||
import android.app.Dialog;
|
import android.app.Dialog;
|
||||||
import android.app.DownloadManager;
|
import android.app.DownloadManager;
|
||||||
|
import android.app.Notification;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.os.Environment;
|
||||||
import android.preference.PreferenceManager;
|
import android.preference.PreferenceManager;
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
|
import android.support.v4.app.ActivityCompat;
|
||||||
import android.support.v4.app.DialogFragment;
|
import android.support.v4.app.DialogFragment;
|
||||||
|
import android.support.v4.content.ContextCompat;
|
||||||
import android.support.v7.app.AlertDialog;
|
import android.support.v7.app.AlertDialog;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by Christian Schabesberger on 21.09.15.
|
* Created by Christian Schabesberger on 21.09.15.
|
||||||
@@ -42,48 +53,102 @@ public class DownloadDialog extends DialogFragment {
|
|||||||
public static final String FILE_SUFFIX_VIDEO = "file_suffix_video";
|
public static final String FILE_SUFFIX_VIDEO = "file_suffix_video";
|
||||||
public static final String AUDIO_URL = "audio_url";
|
public static final String AUDIO_URL = "audio_url";
|
||||||
public static final String VIDEO_URL = "video_url";
|
public static final String VIDEO_URL = "video_url";
|
||||||
Bundle arguments;
|
private Bundle arguments;
|
||||||
|
|
||||||
|
@NonNull
|
||||||
@Override
|
@Override
|
||||||
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||||
arguments = getArguments();
|
arguments = getArguments();
|
||||||
super.onCreateDialog(savedInstanceState);
|
super.onCreateDialog(savedInstanceState);
|
||||||
|
if(ContextCompat.checkSelfPermission(this.getContext(),Manifest.permission.WRITE_EXTERNAL_STORAGE)!= PackageManager.PERMISSION_GRANTED)
|
||||||
|
ActivityCompat.requestPermissions(getActivity(),new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},0);
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
|
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
|
||||||
builder.setTitle(R.string.downloadDialogTitle)
|
builder.setTitle(R.string.download_dialog_title)
|
||||||
.setItems(R.array.downloadOptions, new DialogInterface.OnClickListener() {
|
.setItems(R.array.download_options, new DialogInterface.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(DialogInterface dialog, int which) {
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
Context context = getActivity();
|
Context context = getActivity();
|
||||||
SharedPreferences defaultPreferences = PreferenceManager.getDefaultSharedPreferences(context);
|
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
|
||||||
String suffix = "";
|
String suffix = "";
|
||||||
String title = arguments.getString(TITLE);
|
String title = arguments.getString(TITLE);
|
||||||
String url = "";
|
String url = "";
|
||||||
|
File downloadDir = NewPipeSettings.getDownloadFolder();
|
||||||
switch(which) {
|
switch(which) {
|
||||||
case 0: // Video
|
case 0: // Video
|
||||||
suffix = arguments.getString(FILE_SUFFIX_VIDEO);
|
suffix = arguments.getString(FILE_SUFFIX_VIDEO);
|
||||||
url = arguments.getString(VIDEO_URL);
|
url = arguments.getString(VIDEO_URL);
|
||||||
|
downloadDir = NewPipeSettings.getVideoDownloadFolder(context);
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
suffix = arguments.getString(FILE_SUFFIX_AUDIO);
|
suffix = arguments.getString(FILE_SUFFIX_AUDIO);
|
||||||
url = arguments.getString(AUDIO_URL);
|
url = arguments.getString(AUDIO_URL);
|
||||||
|
downloadDir = NewPipeSettings.getAudioDownloadFolder(context);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
Log.d(TAG, "lolz");
|
Log.d(TAG, "lolz");
|
||||||
}
|
}
|
||||||
DownloadManager dm = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
|
if(!downloadDir.exists()) {
|
||||||
DownloadManager.Request request = new DownloadManager.Request(
|
//attempt to create directory
|
||||||
Uri.parse(url));
|
boolean mkdir = downloadDir.mkdirs();
|
||||||
request.setDestinationUri(Uri.fromFile(new File(
|
if(!mkdir && !downloadDir.isDirectory()) {
|
||||||
defaultPreferences.getString("download_path_preference", "/storage/emulated/0/NewPipe")
|
String message = context.getString(R.string.err_dir_create,downloadDir.toString());
|
||||||
+ "/" + title + suffix)));
|
Log.e(TAG, message);
|
||||||
try {
|
Toast.makeText(context,message , Toast.LENGTH_LONG).show();
|
||||||
dm.enqueue(request);
|
|
||||||
} catch (Exception e) {
|
return;
|
||||||
e.printStackTrace();
|
}
|
||||||
|
String message = context.getString(R.string.info_dir_created,downloadDir.toString());
|
||||||
|
Log.e(TAG, message);
|
||||||
|
Toast.makeText(context,message , Toast.LENGTH_LONG).show();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
File saveFilePath = new File(downloadDir,createFileName(title) + suffix);
|
||||||
|
|
||||||
|
long id = 0;
|
||||||
|
if (App.isUsingTor()) {
|
||||||
|
// if using Tor, do not use DownloadManager because the proxy cannot be set
|
||||||
|
FileDownloader.downloadFile(getContext(), url, saveFilePath, title);
|
||||||
|
} else {
|
||||||
|
DownloadManager dm = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
|
||||||
|
DownloadManager.Request request = new DownloadManager.Request(
|
||||||
|
Uri.parse(url));
|
||||||
|
request.setDestinationUri(Uri.fromFile(saveFilePath));
|
||||||
|
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
|
||||||
|
|
||||||
|
request.setTitle(title);
|
||||||
|
request.setDescription("'" + url +
|
||||||
|
"' => '" + saveFilePath + "'");
|
||||||
|
request.allowScanningByMediaScanner();
|
||||||
|
|
||||||
|
try {
|
||||||
|
id = dm.enqueue(request);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.i(TAG,"Started downloading '" + url +
|
||||||
|
"' => '" + saveFilePath + "' #" + id);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return builder.create();
|
return builder.create();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* #143 #44 #42 #22: make shure that the filename does not contain illegal chars.
|
||||||
|
* This should fix some of the "cannot download" problems.
|
||||||
|
* */
|
||||||
|
private String createFileName(String fName) {
|
||||||
|
// from http://eng-przemelek.blogspot.de/2009/07/how-to-create-valid-file-name.html
|
||||||
|
|
||||||
|
List<String> forbiddenCharsPatterns = new ArrayList<String> ();
|
||||||
|
forbiddenCharsPatterns.add("[:]+"); // Mac OS, but it looks that also Windows XP
|
||||||
|
forbiddenCharsPatterns.add("[\\*\"/\\\\\\[\\]\\:\\;\\|\\=\\,]+"); // Windows
|
||||||
|
forbiddenCharsPatterns.add("[^\\w\\d\\.]+"); // last chance... only latin letters and digits
|
||||||
|
String nameToTest = fName;
|
||||||
|
for (String pattern : forbiddenCharsPatterns) {
|
||||||
|
nameToTest = nameToTest.replaceAll(pattern, "_");
|
||||||
|
}
|
||||||
|
return nameToTest;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,14 +1,19 @@
|
|||||||
package org.schabi.newpipe;
|
package org.schabi.newpipe;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
|
import java.io.IOException;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
import java.net.HttpURLConnection;
|
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
import java.net.UnknownHostException;
|
||||||
|
|
||||||
|
import javax.net.ssl.HttpsURLConnection;
|
||||||
|
|
||||||
|
import info.guardianproject.netcipher.NetCipher;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by Christian Schabesberger on 14.08.15.
|
* Created by Christian Schabesberger on 28.01.16.
|
||||||
*
|
*
|
||||||
* Copyright (C) Christian Schabesberger 2015 <chris.schabesberger@mailbox.org>
|
* Copyright (C) Christian Schabesberger 2016 <chris.schabesberger@mailbox.org>
|
||||||
* Downloader.java is part of NewPipe.
|
* Downloader.java is part of NewPipe.
|
||||||
*
|
*
|
||||||
* NewPipe is free software: you can redistribute it and/or modify
|
* NewPipe is free software: you can redistribute it and/or modify
|
||||||
@@ -25,29 +30,61 @@ import java.net.URL;
|
|||||||
* along with NewPipe. If not, see <http://www.gnu.org/licenses/>.
|
* along with NewPipe. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public class Downloader {
|
public class Downloader implements org.schabi.newpipe.crawler.Downloader {
|
||||||
|
|
||||||
|
private static final String USER_AGENT = "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:43.0) Gecko/20100101 Firefox/43.0";
|
||||||
|
|
||||||
private static final String USER_AGENT = "Mozilla/5.0";
|
/**Download the text file at the supplied URL as in download(String),
|
||||||
public static String download(String siteUrl) {
|
* but set the HTTP header field "Accept-Language" to the supplied string.
|
||||||
|
* @param siteUrl the URL of the text file to return the contents of
|
||||||
|
* @param language the language (usually a 2-character code) to set as the preferred language
|
||||||
|
* @return the contents of the specified text file*/
|
||||||
|
public String download(String siteUrl, String language) throws IOException {
|
||||||
|
URL url = new URL(siteUrl);
|
||||||
|
//HttpsURLConnection con = (HttpsURLConnection) url.openConnection();
|
||||||
|
HttpsURLConnection con = NetCipher.getHttpsURLConnection(url);
|
||||||
|
con.setRequestProperty("Accept-Language", language);
|
||||||
|
return dl(con);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**Common functionality between download(String url) and download(String url, String language)*/
|
||||||
|
private static String dl(HttpsURLConnection con) throws IOException {
|
||||||
|
StringBuilder response = new StringBuilder();
|
||||||
|
BufferedReader in = null;
|
||||||
|
|
||||||
StringBuffer response = new StringBuffer();
|
|
||||||
try {
|
try {
|
||||||
URL url = new URL(siteUrl);
|
|
||||||
HttpURLConnection con = (HttpURLConnection) url.openConnection();
|
|
||||||
con.setRequestMethod("GET");
|
con.setRequestMethod("GET");
|
||||||
con.setRequestProperty("User-Agent", USER_AGENT);
|
con.setRequestProperty("User-Agent", USER_AGENT);
|
||||||
|
|
||||||
BufferedReader in = new BufferedReader(
|
in = new BufferedReader(
|
||||||
new InputStreamReader(con.getInputStream()));
|
new InputStreamReader(con.getInputStream()));
|
||||||
String inputLine;
|
String inputLine;
|
||||||
|
|
||||||
while((inputLine = in.readLine()) != null) {
|
while((inputLine = in.readLine()) != null) {
|
||||||
response.append(inputLine);
|
response.append(inputLine);
|
||||||
}
|
}
|
||||||
in.close();
|
} catch(UnknownHostException uhe) {//thrown when there's no internet connection
|
||||||
} catch (Exception e) {
|
throw new IOException("unknown host or no network", uhe);
|
||||||
e.printStackTrace();
|
//Toast.makeText(getActivity(), uhe.getMessage(), Toast.LENGTH_LONG).show();
|
||||||
|
} catch(Exception e) {
|
||||||
|
throw new IOException(e);
|
||||||
|
} finally {
|
||||||
|
if(in != null) {
|
||||||
|
in.close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return response.toString();
|
return response.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**Download (via HTTP) the text file located at the supplied URL, and return its contents.
|
||||||
|
* Primarily intended for downloading web pages.
|
||||||
|
* @param siteUrl the URL of the text file to download
|
||||||
|
* @return the contents of the specified text file*/
|
||||||
|
public String download(String siteUrl) throws IOException {
|
||||||
|
URL url = new URL(siteUrl);
|
||||||
|
HttpsURLConnection con = (HttpsURLConnection) url.openConnection();
|
||||||
|
//HttpsURLConnection con = NetCipher.getHttpsURLConnection(url);
|
||||||
|
return dl(con);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
54
app/src/main/java/org/schabi/newpipe/ExitActivity.java
Normal file
54
app/src/main/java/org/schabi/newpipe/ExitActivity.java
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
|
||||||
|
package org.schabi.newpipe;
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint;
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.os.Build;
|
||||||
|
import android.os.Bundle;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copyright (C) Hans-Christoph Steiner 2016 <hans@eds.org>
|
||||||
|
* ExitActivity.java is part of NewPipe.
|
||||||
|
*
|
||||||
|
* NewPipe is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* NewPipe is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with NewPipe. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class ExitActivity extends Activity {
|
||||||
|
|
||||||
|
@SuppressLint("NewApi")
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
|
if (Build.VERSION.SDK_INT >= 21) {
|
||||||
|
finishAndRemoveTask();
|
||||||
|
} else {
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
System.exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void exitAndRemoveFromRecentApps(Activity activity) {
|
||||||
|
Intent intent = new Intent(activity, ExitActivity.class);
|
||||||
|
|
||||||
|
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
|
||||||
|
| Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
|
||||||
|
| Intent.FLAG_ACTIVITY_CLEAR_TASK
|
||||||
|
| Intent.FLAG_ACTIVITY_NO_ANIMATION);
|
||||||
|
|
||||||
|
activity.startActivity(intent);
|
||||||
|
}
|
||||||
|
}
|
169
app/src/main/java/org/schabi/newpipe/FileDownloader.java
Normal file
169
app/src/main/java/org/schabi/newpipe/FileDownloader.java
Normal file
@@ -0,0 +1,169 @@
|
|||||||
|
package org.schabi.newpipe;
|
||||||
|
|
||||||
|
|
||||||
|
import android.app.NotificationManager;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.SharedPreferences;
|
||||||
|
import android.graphics.drawable.BitmapDrawable;
|
||||||
|
import android.graphics.drawable.Drawable;
|
||||||
|
import android.os.AsyncTask;
|
||||||
|
import android.preference.PreferenceManager;
|
||||||
|
import android.support.v4.app.NotificationCompat;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.net.HttpURLConnection;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.net.UnknownHostException;
|
||||||
|
|
||||||
|
import javax.net.ssl.HttpsURLConnection;
|
||||||
|
|
||||||
|
import info.guardianproject.netcipher.NetCipher;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Christian Schabesberger on 14.08.15.
|
||||||
|
*
|
||||||
|
* Copyright (C) Christian Schabesberger 2015 <chris.schabesberger@mailbox.org>
|
||||||
|
* FileDownloader.java is part of NewPipe.
|
||||||
|
*
|
||||||
|
* NewPipe is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* NewPipe is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with NewPipe. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class FileDownloader extends AsyncTask<Void, Integer, Void> {
|
||||||
|
public static final String TAG = "FileDownloader";
|
||||||
|
|
||||||
|
|
||||||
|
private NotificationManager nm;
|
||||||
|
private NotificationCompat.Builder builder;
|
||||||
|
private int notifyId = 0x1234;
|
||||||
|
private int fileSize = 0xffffffff;
|
||||||
|
|
||||||
|
private final Context context;
|
||||||
|
private final String fileURL;
|
||||||
|
private final File saveFilePath;
|
||||||
|
private final String title;
|
||||||
|
|
||||||
|
private final String debugContext;
|
||||||
|
|
||||||
|
public FileDownloader(Context context, String fileURL, File saveFilePath, String title) {
|
||||||
|
this.context = context;
|
||||||
|
this.fileURL = fileURL;
|
||||||
|
this.saveFilePath = saveFilePath;
|
||||||
|
this.title = title;
|
||||||
|
|
||||||
|
this.debugContext = "'" + fileURL +
|
||||||
|
"' => '" + saveFilePath + "'";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Downloads a file from a URL in the background using an {@link AsyncTask}.
|
||||||
|
*
|
||||||
|
* @param fileURL HTTP URL of the file to be downloaded
|
||||||
|
* @param saveFilePath path of the directory to save the file
|
||||||
|
* @param title
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public static void downloadFile(final Context context, final String fileURL, final File saveFilePath, String title) {
|
||||||
|
new FileDownloader(context, fileURL, saveFilePath, title).execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** AsyncTask impl: executed in gui thread */
|
||||||
|
@Override
|
||||||
|
protected void onPreExecute() {
|
||||||
|
super.onPreExecute();
|
||||||
|
nm = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
|
||||||
|
Drawable icon = context.getResources().getDrawable(R.mipmap.ic_launcher);
|
||||||
|
builder = new NotificationCompat.Builder(context)
|
||||||
|
.setSmallIcon(android.R.drawable.stat_sys_download)
|
||||||
|
.setLargeIcon(((BitmapDrawable) icon).getBitmap())
|
||||||
|
.setContentTitle(saveFilePath.getName())
|
||||||
|
.setContentText(saveFilePath.getAbsolutePath())
|
||||||
|
.setProgress(fileSize, 0, false);
|
||||||
|
nm.notify(notifyId, builder.build());
|
||||||
|
}
|
||||||
|
|
||||||
|
/** AsyncTask impl: executed in background thread does the download */
|
||||||
|
@Override
|
||||||
|
protected Void doInBackground(Void... voids) {
|
||||||
|
HttpsURLConnection con = null;
|
||||||
|
InputStream inputStream = null;
|
||||||
|
FileOutputStream outputStream = null;
|
||||||
|
try {
|
||||||
|
con = NetCipher.getHttpsURLConnection(fileURL);
|
||||||
|
int responseCode = con.getResponseCode();
|
||||||
|
|
||||||
|
// always check HTTP response code first
|
||||||
|
if (responseCode == HttpURLConnection.HTTP_OK) {
|
||||||
|
fileSize = con.getContentLength();
|
||||||
|
inputStream = new BufferedInputStream(con.getInputStream());
|
||||||
|
outputStream = new FileOutputStream(saveFilePath);
|
||||||
|
|
||||||
|
int bufferSize = 8192;
|
||||||
|
int downloaded = 0;
|
||||||
|
|
||||||
|
int bytesRead = -1;
|
||||||
|
byte[] buffer = new byte[bufferSize];
|
||||||
|
while ((bytesRead = inputStream.read(buffer)) != -1) {
|
||||||
|
outputStream.write(buffer, 0, bytesRead);
|
||||||
|
downloaded += bytesRead;
|
||||||
|
if (downloaded % 50000 < bufferSize) {
|
||||||
|
publishProgress(downloaded);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
publishProgress(bufferSize);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
Log.i(TAG, "No file to download. Server replied HTTP code: " + responseCode);
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
Log.e(TAG, "No file to download. Server replied HTTP code: ", e);
|
||||||
|
e.printStackTrace();
|
||||||
|
} finally {
|
||||||
|
try {
|
||||||
|
if (outputStream != null) {
|
||||||
|
outputStream.close();
|
||||||
|
}
|
||||||
|
if (inputStream != null) {
|
||||||
|
inputStream.close();
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
if (con != null) {
|
||||||
|
con.disconnect();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onProgressUpdate(Integer... progress) {
|
||||||
|
builder.setProgress(fileSize, progress[0], false);
|
||||||
|
nm.notify(notifyId, builder.build());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onPostExecute(Void aVoid) {
|
||||||
|
super.onPostExecute(aVoid);
|
||||||
|
nm.cancel(notifyId);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
93
app/src/main/java/org/schabi/newpipe/Localization.java
Normal file
93
app/src/main/java/org/schabi/newpipe/Localization.java
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
package org.schabi.newpipe;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.SharedPreferences;
|
||||||
|
import android.content.res.Resources;
|
||||||
|
import android.preference.PreferenceManager;
|
||||||
|
|
||||||
|
import java.text.DateFormat;
|
||||||
|
import java.text.NumberFormat;
|
||||||
|
import java.text.ParseException;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by chschtsch on 12/29/15.
|
||||||
|
*
|
||||||
|
* Copyright (C) Gregory Arkhipov 2015
|
||||||
|
* Localization.java is part of NewPipe.
|
||||||
|
*
|
||||||
|
* NewPipe is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* NewPipe is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with NewPipe. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class Localization {
|
||||||
|
|
||||||
|
public static Locale getPreferredLocale(Context context) {
|
||||||
|
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
|
||||||
|
|
||||||
|
String languageCode = sp.getString(String.valueOf(R.string.search_language_key),
|
||||||
|
context.getString(R.string.default_language_value));
|
||||||
|
|
||||||
|
if(languageCode.length() == 2) {
|
||||||
|
return new Locale(languageCode);
|
||||||
|
}
|
||||||
|
else if(languageCode.contains("_")) {
|
||||||
|
String country = languageCode
|
||||||
|
.substring(languageCode.indexOf("_"), languageCode.length());
|
||||||
|
return new Locale(languageCode.substring(0, 2), country);
|
||||||
|
}
|
||||||
|
return Locale.getDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String localizeViewCount(long viewCount, Context context) {
|
||||||
|
Locale locale = getPreferredLocale(context);
|
||||||
|
|
||||||
|
Resources res = context.getResources();
|
||||||
|
String viewsString = res.getString(R.string.view_count_text);
|
||||||
|
|
||||||
|
NumberFormat nf = NumberFormat.getInstance(locale);
|
||||||
|
String formattedViewCount = nf.format(viewCount);
|
||||||
|
return String.format(viewsString, formattedViewCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String localizeNumber(long number, Context context) {
|
||||||
|
Locale locale = getPreferredLocale(context);
|
||||||
|
NumberFormat nf = NumberFormat.getInstance(locale);
|
||||||
|
return nf.format(number);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String formatDate(String date, Context context) {
|
||||||
|
Locale locale = getPreferredLocale(context);
|
||||||
|
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
|
||||||
|
Date datum = null;
|
||||||
|
try {
|
||||||
|
datum = formatter.parse(date);
|
||||||
|
} catch (ParseException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
DateFormat df = DateFormat.getDateInstance(DateFormat.MEDIUM, locale);
|
||||||
|
|
||||||
|
return df.format(datum);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String localizeDate(String date, Context context) {
|
||||||
|
Resources res = context.getResources();
|
||||||
|
String dateString = res.getString(R.string.upload_date_text);
|
||||||
|
|
||||||
|
String formattedDate = formatDate(date, context);
|
||||||
|
return String.format(dateString, formattedDate);
|
||||||
|
}
|
||||||
|
}
|
72
app/src/main/java/org/schabi/newpipe/NewPipeSettings.java
Normal file
72
app/src/main/java/org/schabi/newpipe/NewPipeSettings.java
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
/**
|
||||||
|
* Created by k3b on 07.01.2016.
|
||||||
|
*
|
||||||
|
* Copyright (C) Christian Schabesberger 2015 <chris.schabesberger@mailbox.org>
|
||||||
|
* NewPipeSettings.java is part of NewPipe.
|
||||||
|
*
|
||||||
|
* NewPipe is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* NewPipe is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with NewPipe. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.schabi.newpipe;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.SharedPreferences;
|
||||||
|
import android.os.Environment;
|
||||||
|
import android.preference.PreferenceManager;
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper for global settings
|
||||||
|
*/
|
||||||
|
public class NewPipeSettings {
|
||||||
|
public static void initSettings(Context context) {
|
||||||
|
PreferenceManager.setDefaultValues(context, R.xml.settings, false);
|
||||||
|
getVideoDownloadFolder(context);
|
||||||
|
getAudioDownloadFolder(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static File getDownloadFolder() {
|
||||||
|
return getFolder(Environment.DIRECTORY_DOWNLOADS);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static File getVideoDownloadFolder(Context context) {
|
||||||
|
return getFolder(context, R.string.download_path_key, Environment.DIRECTORY_MOVIES);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static File getAudioDownloadFolder(Context context) {
|
||||||
|
return getFolder(context, R.string.download_path_audio_key, Environment.DIRECTORY_MUSIC);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static File getFolder(Context context, int keyID, String defaultDirectoryName) {
|
||||||
|
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
|
||||||
|
final String key = context.getString(keyID);
|
||||||
|
String downloadPath = prefs.getString(key, null);
|
||||||
|
if ((downloadPath != null) && (!downloadPath.isEmpty())) return new File(downloadPath.trim());
|
||||||
|
|
||||||
|
final File folder = getFolder(defaultDirectoryName);
|
||||||
|
SharedPreferences.Editor spEditor = prefs.edit();
|
||||||
|
spEditor.putString(key
|
||||||
|
, new File(folder,"NewPipe").getAbsolutePath());
|
||||||
|
spEditor.apply();
|
||||||
|
return folder;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
private static File getFolder(String defaultDirectoryName) {
|
||||||
|
return new File(Environment.getExternalStorageDirectory(),defaultDirectoryName);
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,50 @@
|
|||||||
|
|
||||||
|
package org.schabi.newpipe;
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint;
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.os.Build;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.media.AudioManager;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copyright (C) Hans-Christoph Steiner 2016 <hans@eds.org>
|
||||||
|
* PanicResponderActivity.java is part of NewPipe.
|
||||||
|
*
|
||||||
|
* NewPipe is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* NewPipe is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with NewPipe. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class PanicResponderActivity extends Activity {
|
||||||
|
|
||||||
|
public static final String PANIC_TRIGGER_ACTION = "info.guardianproject.panic.action.TRIGGER";
|
||||||
|
|
||||||
|
@SuppressLint("NewApi")
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
Intent intent = getIntent();
|
||||||
|
if (intent != null && PANIC_TRIGGER_ACTION.equals(intent.getAction())) {
|
||||||
|
// TODO explicitly clear the search results once they are restored when the app restarts
|
||||||
|
// or if the app reloads the current video after being killed, that should be cleared also
|
||||||
|
ExitActivity.exitAndRemoveFromRecentApps(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Build.VERSION.SDK_INT >= 21) {
|
||||||
|
finishAndRemoveTask();
|
||||||
|
} else {
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user