mirror of
https://github.com/TeamNewPipe/NewPipe
synced 2025-09-20 11:20:52 +02:00
Compare commits
106 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
d0d41c6b16 | ||
![]() |
f7a531e71b | ||
![]() |
c28fddc4dd | ||
![]() |
b6ea10fc73 | ||
![]() |
320eb44061 | ||
![]() |
7a6b5dd5b7 | ||
![]() |
460653ed16 | ||
![]() |
b6fda788c5 | ||
![]() |
da4b9306fa | ||
![]() |
d76c02cbf4 | ||
![]() |
4d5466b5cd | ||
![]() |
e9c20ac8b0 | ||
![]() |
961820a250 | ||
![]() |
4cc2976061 | ||
![]() |
477f182b43 | ||
![]() |
a5252bb765 | ||
![]() |
3f0078f38a | ||
![]() |
91434dd2ac | ||
![]() |
f29bd0a6e7 | ||
![]() |
7186f58374 | ||
![]() |
5c8bcf15ba | ||
![]() |
130757ee99 | ||
![]() |
5020a4f9dc | ||
![]() |
ef15902ec4 | ||
![]() |
ed8d13f837 | ||
![]() |
27f2c65e6d | ||
![]() |
0b3428ede9 | ||
![]() |
3e0102ad2a | ||
![]() |
c42002ccc5 | ||
![]() |
e8101d5d91 | ||
![]() |
ecdf4ad502 | ||
![]() |
af760f9cdc | ||
![]() |
b3491da49f | ||
![]() |
c322feeaff | ||
![]() |
b26f46a063 | ||
![]() |
9f0944dc5a | ||
![]() |
e869098434 | ||
![]() |
4baa23af5f | ||
![]() |
78fc5bbbd5 | ||
![]() |
a69784d168 | ||
![]() |
d48a7f1a18 | ||
![]() |
082c6128ad | ||
![]() |
7c9771873b | ||
![]() |
7257cdacc8 | ||
![]() |
140b480f82 | ||
![]() |
77db2f8a48 | ||
![]() |
22bc81b0eb | ||
![]() |
b52b3d4be0 | ||
![]() |
f845098b42 | ||
![]() |
0f7397e3b8 | ||
![]() |
0b9d99fdc9 | ||
![]() |
9a1da5cc75 | ||
![]() |
9e76f94cf6 | ||
![]() |
7d6b92e064 | ||
![]() |
849a45a3ca | ||
![]() |
7ddea5a71b | ||
![]() |
5d81358c15 | ||
![]() |
492aad9d70 | ||
![]() |
647cfcd401 | ||
![]() |
c60d98e52d | ||
![]() |
d3cfac6b15 | ||
![]() |
7fb4e5a143 | ||
![]() |
8e451b2a83 | ||
![]() |
8083f06fe7 | ||
![]() |
44521a2e56 | ||
![]() |
dfeed3d0eb | ||
![]() |
081a45b70d | ||
![]() |
616a721bba | ||
![]() |
c9aa553b32 | ||
![]() |
e3d59c3cff | ||
![]() |
df51635674 | ||
![]() |
1e81f61760 | ||
![]() |
a4043eab83 | ||
![]() |
60dc19d2bc | ||
![]() |
a2e4585fe8 | ||
![]() |
b5df281447 | ||
![]() |
650917f9f9 | ||
![]() |
3a9c95a9ae | ||
![]() |
5458acfcad | ||
![]() |
68e80e6054 | ||
![]() |
e4aa69b8d3 | ||
![]() |
dfd40e43da | ||
![]() |
7efd111d9c | ||
![]() |
6809172203 | ||
![]() |
40a4343f06 | ||
![]() |
cd9333b39e | ||
![]() |
82d426c781 | ||
![]() |
c7e773de25 | ||
![]() |
2ded33110f | ||
![]() |
b26c0aa9da | ||
![]() |
2fc8fb6f17 | ||
![]() |
ea76f1d6e2 | ||
![]() |
7cda1d116b | ||
![]() |
8bf7a1a9db | ||
![]() |
0aa0ad65c0 | ||
![]() |
53ff58daa3 | ||
![]() |
b3225bebe6 | ||
![]() |
4beafad71f | ||
![]() |
c96f933626 | ||
![]() |
bea6359d5f | ||
![]() |
1b9a6e53ce | ||
![]() |
c7abf377eb | ||
![]() |
175d8ce572 | ||
![]() |
1708a401cf | ||
![]() |
141278e668 | ||
![]() |
754bd82699 |
5
.github/CONTRIBUTING.md
vendored
5
.github/CONTRIBUTING.md
vendored
@@ -13,6 +13,9 @@ Do not report crashes in the GitHub issue tracker. NewPipe has an automated cras
|
||||
* Check if this issue/feature is already fixed/implemented in the repository
|
||||
* If you are an android/java developer you are always welcome to fix/implement an issue/a feature yourself
|
||||
|
||||
## Bugfixing
|
||||
* If you want to help NewPipe getting bug free, you can send me a mail to tnp@newpipe.schabi.org to let me know that you intent to help, and than register at our [sentry](https://support.schabi.org) setup.
|
||||
|
||||
## Translation
|
||||
|
||||
* NewPipe can be translated on [weblate](https://hosted.weblate.org/projects/newpipe/strings/)
|
||||
@@ -31,6 +34,6 @@ Do not report crashes in the GitHub issue tracker. NewPipe has an automated cras
|
||||
|
||||
## Communication
|
||||
|
||||
* I hereby declare our Slack channel as dead!!! There are no plans on building a new chat, but if there is interest on creating one and keeping it alive, I'd be pleased to create one again.
|
||||
* WE DO NOW HAVE A MAILING LIST: [newpipe@list.schabi.org](https://list.schabi.org/cgi-bin/mailman/listinfo/newpipe).
|
||||
* If you want to get in contact with me or one of our other contributors you can send me an email at tnp(at)schabi.org
|
||||
* Feel free to post suggestions, changes, ideas etc!
|
||||
|
@@ -37,12 +37,12 @@ NewPipe does not use any Google framework libraries, or the YouTube API. It only
|
||||
* Listen to YouTube videos (experimental)
|
||||
* Select the streaming player to watch the video with
|
||||
* Download videos
|
||||
* Download audio only
|
||||
* Open a video in Kodi
|
||||
* Download audio only * Open a video in Kodi
|
||||
* Show Next/Related videos
|
||||
* Search YouTube in a specific language
|
||||
* Watch age restricted material
|
||||
* Display general information about channels
|
||||
* Search channels
|
||||
|
||||
### Coming Features
|
||||
|
||||
@@ -50,7 +50,6 @@ NewPipe does not use any Google framework libraries, or the YouTube API. It only
|
||||
* Bookmarks
|
||||
* View history
|
||||
* Search history
|
||||
* Search channels
|
||||
* Subscribe to channels
|
||||
* Watch videos from a channel
|
||||
* Search/Watch Playlists
|
||||
|
@@ -8,8 +8,8 @@ android {
|
||||
applicationId "org.schabi.newpipe"
|
||||
minSdkVersion 15
|
||||
targetSdkVersion 25
|
||||
versionCode 21
|
||||
versionName "0.8.7"
|
||||
versionCode 24
|
||||
versionName "0.8.10"
|
||||
}
|
||||
buildTypes {
|
||||
release {
|
||||
@@ -32,10 +32,10 @@ android {
|
||||
|
||||
dependencies {
|
||||
testCompile 'junit:junit:4.12'
|
||||
compile 'com.android.support:appcompat-v7:25.1.0'
|
||||
compile 'com.android.support:support-v4:25.1.0'
|
||||
compile 'com.android.support:design:25.1.0'
|
||||
compile 'com.android.support:recyclerview-v7:25.1.0'
|
||||
compile 'com.android.support:appcompat-v7:25.1.1'
|
||||
compile 'com.android.support:support-v4:25.1.1'
|
||||
compile 'com.android.support:design:25.1.1'
|
||||
compile 'com.android.support:recyclerview-v7:25.1.1'
|
||||
compile 'org.jsoup:jsoup:1.8.3'
|
||||
compile 'org.mozilla:rhino:1.7.7'
|
||||
compile 'info.guardianproject.netcipher:netcipher:1.2'
|
||||
@@ -45,6 +45,8 @@ dependencies {
|
||||
compile 'com.google.android.exoplayer:exoplayer:r1.5.5'
|
||||
compile 'com.google.code.gson:gson:2.4'
|
||||
compile 'com.nononsenseapps:filepicker:3.0.0'
|
||||
testCompile 'junit:junit:4.12'
|
||||
compile 'ch.acra:acra:4.9.0'
|
||||
testCompile 'junit:junit:4.12'
|
||||
testCompile 'org.mockito:mockito-core:1.10.19'
|
||||
testCompile 'org.json:json:20160810'
|
||||
}
|
||||
|
@@ -1,52 +0,0 @@
|
||||
package org.schabi.newpipe.extractor.youtube;
|
||||
|
||||
import android.test.AndroidTestCase;
|
||||
|
||||
|
||||
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
|
||||
import org.schabi.newpipe.extractor.exceptions.ParsingException;
|
||||
import org.schabi.newpipe.extractor.stream_info.StreamExtractor;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Created by Christian Schabesberger on 11.03.16.
|
||||
*
|
||||
* Copyright (C) Christian Schabesberger 2016 <chris.schabesberger@mailbox.org>
|
||||
* YoutubeStreamExtractorLiveStreamTest.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 YoutubeStreamExtractorLiveStreamTest extends AndroidTestCase {
|
||||
|
||||
private StreamExtractor extractor;
|
||||
|
||||
public void setUp() throws IOException, ExtractionException {
|
||||
//todo: make the extractor not throw over a livestream
|
||||
/*
|
||||
|
||||
NewPipe.init(Downloader.getInstance());
|
||||
extractor = NewPipe.getService("Youtube")
|
||||
.getExtractorInstance("https://www.youtube.com/watch?v=J0s6NjqdjLE", Downloader.getInstance());
|
||||
*/
|
||||
}
|
||||
|
||||
public void testStreamType() throws ParsingException {
|
||||
assertTrue(true);
|
||||
// assertTrue(extractor.getStreamType() == AbstractVideoInfo.StreamType.LIVE_STREAM);
|
||||
}
|
||||
}
|
||||
|
@@ -156,11 +156,22 @@
|
||||
<activity
|
||||
android:name=".ChannelActivity"
|
||||
android:label="@string/title_activity_channel"
|
||||
android:launchMode="singleTask"
|
||||
android:theme="@style/AppTheme.NoActionBar" />
|
||||
|
||||
<activity
|
||||
android:name=".ReCaptchaActivity"
|
||||
android:label="@string/reCaptchaActivity" />
|
||||
|
||||
<provider
|
||||
android:name="android.support.v4.content.FileProvider"
|
||||
android:authorities="${applicationId}.provider"
|
||||
android:exported="false"
|
||||
android:grantUriPermissions="true">
|
||||
<meta-data
|
||||
android:name="android.support.FILE_PROVIDER_PATHS"
|
||||
android:resource="@xml/provider_paths"/>
|
||||
</provider>
|
||||
</application>
|
||||
|
||||
</manifest>
|
@@ -48,6 +48,7 @@ public class App extends Application {
|
||||
@Override
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
|
||||
// init crashreport
|
||||
try {
|
||||
final ACRAConfiguration acraConfig = new ConfigurationBuilder(this)
|
||||
|
@@ -1,17 +1,24 @@
|
||||
package org.schabi.newpipe;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.support.design.widget.CollapsingToolbarLayout;
|
||||
import android.support.design.widget.FloatingActionButton;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.support.v7.widget.LinearLayoutManager;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.view.Window;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.Toast;
|
||||
@@ -29,8 +36,13 @@ import org.schabi.newpipe.extractor.exceptions.ParsingException;
|
||||
import org.schabi.newpipe.info_list.InfoItemBuilder;
|
||||
import org.schabi.newpipe.info_list.InfoListAdapter;
|
||||
import org.schabi.newpipe.report.ErrorActivity;
|
||||
import org.schabi.newpipe.util.NavStack;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Objects;
|
||||
|
||||
import static android.os.Build.VERSION.SDK;
|
||||
import static android.os.Build.VERSION.SDK_INT;
|
||||
|
||||
/**
|
||||
* Copyright (C) Christian Schabesberger 2016 <chris.schabesberger@mailbox.org>
|
||||
@@ -51,15 +63,9 @@ import java.io.IOException;
|
||||
*/
|
||||
|
||||
public class ChannelActivity extends AppCompatActivity {
|
||||
|
||||
|
||||
private static final String TAG = ChannelActivity.class.toString();
|
||||
private View rootView = null;
|
||||
|
||||
// intent const
|
||||
public static final String CHANNEL_URL = "channel_url";
|
||||
public static final String SERVICE_ID = "service_id";
|
||||
|
||||
private int serviceId = -1;
|
||||
private String channelUrl = "";
|
||||
private int pageNumber = 0;
|
||||
@@ -72,27 +78,42 @@ public class ChannelActivity extends AppCompatActivity {
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
//since we set themeing we have to set translucent statusBar by hand
|
||||
if (PreferenceManager.getDefaultSharedPreferences(this)
|
||||
.getString("theme", getResources().getString(R.string.light_theme_title)).
|
||||
equals(getResources().getString(R.string.dark_theme_title))) {
|
||||
setTheme(R.style.DarkTheme_NoActionBar);
|
||||
}
|
||||
setTranslucentStatusBar(getWindow());
|
||||
|
||||
setContentView(R.layout.activity_channel);
|
||||
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
|
||||
rootView = findViewById(R.id.rootView);
|
||||
setSupportActionBar(toolbar);
|
||||
Intent i = getIntent();
|
||||
channelUrl = i.getStringExtra(CHANNEL_URL);
|
||||
serviceId = i.getIntExtra(SERVICE_ID, -1);
|
||||
if(savedInstanceState == null) {
|
||||
Intent i = getIntent();
|
||||
channelUrl = i.getStringExtra(NavStack.URL);
|
||||
serviceId = i.getIntExtra(NavStack.SERVICE_ID, -1);
|
||||
} else {
|
||||
channelUrl = savedInstanceState.getString(NavStack.URL);
|
||||
serviceId = savedInstanceState.getInt(NavStack.SERVICE_ID);
|
||||
NavStack.getInstance()
|
||||
.restoreSavedInstanceState(savedInstanceState);
|
||||
}
|
||||
|
||||
|
||||
infoListAdapter = new InfoListAdapter(this, rootView);
|
||||
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.channel_streams_view);
|
||||
final LinearLayoutManager layoutManager = new LinearLayoutManager(this);
|
||||
recyclerView.setLayoutManager(layoutManager);
|
||||
recyclerView.setAdapter(infoListAdapter);
|
||||
infoListAdapter.setOnItemSelectedListener(new InfoItemBuilder.OnItemSelectedListener() {
|
||||
infoListAdapter.setOnStreamInfoItemSelectedListener(
|
||||
new InfoItemBuilder.OnInfoItemSelectedListener() {
|
||||
@Override
|
||||
public void selected(String url) {
|
||||
Intent detailIntent = new Intent(ChannelActivity.this, VideoItemDetailActivity.class);
|
||||
detailIntent.putExtra(VideoItemDetailFragment.VIDEO_URL, url);
|
||||
detailIntent.putExtra(
|
||||
VideoItemDetailFragment.STREAMING_SERVICE, serviceId);
|
||||
startActivity(detailIntent);
|
||||
public void selected(String url, int serviceId) {
|
||||
NavStack.getInstance()
|
||||
.openDetailActivity(ChannelActivity.this, url, serviceId);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -122,13 +143,20 @@ public class ChannelActivity extends AppCompatActivity {
|
||||
requestData(false);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onSaveInstanceState(Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
outState.putString(NavStack.URL, channelUrl);
|
||||
outState.putInt(NavStack.SERVICE_ID, serviceId);
|
||||
NavStack.getInstance()
|
||||
.onSaveInstanceState(outState);
|
||||
}
|
||||
|
||||
private void updateUi(final ChannelInfo info) {
|
||||
CollapsingToolbarLayout ctl = (CollapsingToolbarLayout) findViewById(R.id.channel_toolbar_layout);
|
||||
ProgressBar progressBar = (ProgressBar) findViewById(R.id.progressBar);
|
||||
ImageView channelBanner = (ImageView) findViewById(R.id.channel_banner_image);
|
||||
FloatingActionButton feedButton = (FloatingActionButton) findViewById(R.id.channel_rss_fab);
|
||||
final FloatingActionButton feedButton = (FloatingActionButton) findViewById(R.id.channel_rss_fab);
|
||||
ImageView avatarView = (ImageView) findViewById(R.id.channel_avatar_view);
|
||||
ImageView haloView = (ImageView) findViewById(R.id.channel_avatar_halo);
|
||||
|
||||
@@ -165,7 +193,7 @@ public class ChannelActivity extends AppCompatActivity {
|
||||
}
|
||||
|
||||
private void addVideos(final ChannelInfo info) {
|
||||
infoListAdapter.addStreamItemList(info.related_streams);
|
||||
infoListAdapter.addInfoItemList(info.related_streams);
|
||||
}
|
||||
|
||||
private void postNewErrorToast(Handler h, final int stringResource) {
|
||||
@@ -237,9 +265,13 @@ public class ChannelActivity extends AppCompatActivity {
|
||||
});
|
||||
pe.printStackTrace();
|
||||
} catch(ExtractionException ex) {
|
||||
String name = "none";
|
||||
if(service != null) {
|
||||
name = service.getServiceInfo().name;
|
||||
}
|
||||
ErrorActivity.reportError(h, ChannelActivity.this, ex, VideoItemDetailFragment.class, null,
|
||||
ErrorActivity.ErrorInfo.make(ErrorActivity.REQUESTED_CHANNEL,
|
||||
service.getServiceInfo().name, channelUrl, R.string.parsing_error));
|
||||
name, channelUrl, R.string.parsing_error));
|
||||
h.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
@@ -265,4 +297,38 @@ public class ChannelActivity extends AppCompatActivity {
|
||||
channelExtractorThread.start();
|
||||
}
|
||||
|
||||
|
||||
// fix transparent statusbar fuckup (fuck google why can't they just leave something that worked
|
||||
// as it is, and everyone gets happy)
|
||||
public static void setTranslucentStatusBar(Window window) {
|
||||
if (window == null) return;
|
||||
int sdkInt = Build.VERSION.SDK_INT;
|
||||
if (sdkInt >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
setTranslucentStatusBarLollipop(window);
|
||||
} else if (sdkInt >= Build.VERSION_CODES.KITKAT) {
|
||||
setTranslucentStatusBarKiKat(window);
|
||||
}
|
||||
}
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
|
||||
private static void setTranslucentStatusBarLollipop(Window window) {
|
||||
window.setStatusBarColor(
|
||||
ContextCompat.getColor(window.getContext(), android.R.color.transparent));
|
||||
}
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.KITKAT)
|
||||
private static void setTranslucentStatusBarKiKat(Window window) {
|
||||
window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
try {
|
||||
NavStack.getInstance()
|
||||
.navBack(this);
|
||||
} catch (Exception e) {
|
||||
ErrorActivity.reportUiError(this, e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -4,13 +4,17 @@ import android.content.Intent;
|
||||
import android.media.AudioManager;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.app.NavUtils;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.widget.AdapterView;
|
||||
|
||||
import org.schabi.newpipe.download.DownloadActivity;
|
||||
import org.schabi.newpipe.settings.SettingsActivity;
|
||||
import org.schabi.newpipe.util.PermissionHelper;
|
||||
|
||||
/**
|
||||
* Created by Christian Schabesberger on 02.08.16.
|
||||
@@ -32,15 +36,14 @@ import org.schabi.newpipe.settings.SettingsActivity;
|
||||
* along with NewPipe. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
public class MainActivity extends AppCompatActivity {
|
||||
|
||||
public class MainActivity extends ThemableActivity {
|
||||
private Fragment mainFragment = null;
|
||||
private static final String TAG = MainActivity.class.toString();
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_main);
|
||||
|
||||
setVolumeControlStream(AudioManager.STREAM_MUSIC);
|
||||
mainFragment = getSupportFragmentManager()
|
||||
.findFragmentById(R.id.search_fragment);
|
||||
@@ -52,8 +55,6 @@ public class MainActivity extends AppCompatActivity {
|
||||
MenuInflater inflater = getMenuInflater();
|
||||
|
||||
inflater.inflate(R.menu.main_menu, menu);
|
||||
|
||||
mainFragment.onCreateOptionsMenu(menu, inflater);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -61,7 +62,7 @@ public class MainActivity extends AppCompatActivity {
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
int id = item.getItemId();
|
||||
|
||||
switch(id) {
|
||||
switch (id) {
|
||||
case android.R.id.home: {
|
||||
Intent intent = new Intent(this, MainActivity.class);
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
|
||||
@@ -74,13 +75,20 @@ public class MainActivity extends AppCompatActivity {
|
||||
return true;
|
||||
}
|
||||
case R.id.action_show_downloads: {
|
||||
Intent intent = new Intent(this, org.schabi.newpipe.download.DownloadActivity.class);
|
||||
if (!PermissionHelper.checkStoragePermissions(this)) {
|
||||
return false;
|
||||
}
|
||||
Intent intent = new Intent(this, DownloadActivity.class);
|
||||
startActivity(intent);
|
||||
return true;
|
||||
}
|
||||
default:
|
||||
return mainFragment.onOptionsItemSelected(item) ||
|
||||
super.onOptionsItemSelected(item);
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
//ignore back
|
||||
}
|
||||
}
|
||||
|
28
app/src/main/java/org/schabi/newpipe/ThemableActivity.java
Normal file
28
app/src/main/java/org/schabi/newpipe/ThemableActivity.java
Normal file
@@ -0,0 +1,28 @@
|
||||
package org.schabi.newpipe;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
|
||||
public class ThemableActivity extends AppCompatActivity {
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
if (PreferenceManager.getDefaultSharedPreferences(this)
|
||||
.getString("theme", getResources().getString(R.string.light_theme_title)).
|
||||
equals(getResources().getString(R.string.dark_theme_title))) {
|
||||
setTheme(R.style.DarkTheme);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
if (PreferenceManager.getDefaultSharedPreferences(this)
|
||||
.getString("theme", getResources().getString(R.string.light_theme_title)).
|
||||
equals(getResources().getString(R.string.dark_theme_title))) {
|
||||
setTheme(R.style.DarkTheme);
|
||||
}
|
||||
}
|
||||
}
|
@@ -125,10 +125,13 @@ public class StreamInfoWorker {
|
||||
e.printStackTrace();
|
||||
} catch (YoutubeStreamExtractor.DecryptException de) {
|
||||
// custom service related exceptions
|
||||
ErrorActivity.reportError(h, a, de, VideoItemDetailFragment.class, null,
|
||||
ErrorActivity.ErrorInfo.make(ErrorActivity.REQUESTED_STREAM,
|
||||
service.getServiceInfo().name, videoUrl, R.string.youtube_signature_decryption_error));
|
||||
h.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
onStreamInfoReceivedListener.onError(R.string.youtube_signature_decryption_error);
|
||||
a.finish();
|
||||
}
|
||||
});
|
||||
de.printStackTrace();
|
||||
|
@@ -1,11 +1,11 @@
|
||||
package org.schabi.newpipe.detail;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.media.AudioManager;
|
||||
import android.os.Bundle;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.support.v4.app.NavUtils;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.util.Log;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
@@ -14,12 +14,17 @@ import android.widget.Toast;
|
||||
import org.schabi.newpipe.App;
|
||||
import org.schabi.newpipe.MainActivity;
|
||||
import org.schabi.newpipe.R;
|
||||
import org.schabi.newpipe.ThemableActivity;
|
||||
import org.schabi.newpipe.extractor.NewPipe;
|
||||
import org.schabi.newpipe.extractor.StreamingService;
|
||||
import org.schabi.newpipe.report.ErrorActivity;
|
||||
import org.schabi.newpipe.util.NavStack;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
|
||||
import static android.os.Build.VERSION.SDK_INT;
|
||||
|
||||
|
||||
/**
|
||||
* Copyright (C) Christian Schabesberger 2015 <chris.schabesberger@mailbox.org>
|
||||
@@ -39,7 +44,7 @@ import java.util.HashSet;
|
||||
* along with NewPipe. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
public class VideoItemDetailActivity extends AppCompatActivity {
|
||||
public class VideoItemDetailActivity extends ThemableActivity {
|
||||
|
||||
/**
|
||||
* Removes invisible separators (\p{Z}) and punctuation characters including
|
||||
@@ -81,8 +86,10 @@ public class VideoItemDetailActivity extends AppCompatActivity {
|
||||
if (savedInstanceState == null) {
|
||||
handleIntent(getIntent());
|
||||
} else {
|
||||
videoUrl = savedInstanceState.getString(VideoItemDetailFragment.VIDEO_URL);
|
||||
currentStreamingService = savedInstanceState.getInt(VideoItemDetailFragment.STREAMING_SERVICE);
|
||||
videoUrl = savedInstanceState.getString(NavStack.URL);
|
||||
currentStreamingService = savedInstanceState.getInt(NavStack.SERVICE_ID);
|
||||
NavStack.getInstance()
|
||||
.restoreSavedInstanceState(savedInstanceState);
|
||||
addFragment(savedInstanceState);
|
||||
}
|
||||
}
|
||||
@@ -114,12 +121,12 @@ public class VideoItemDetailActivity extends AppCompatActivity {
|
||||
currentStreamingService = getServiceIdByUrl(videoUrl);
|
||||
} else {
|
||||
//this is if the video was called through another NewPipe activity
|
||||
videoUrl = intent.getStringExtra(VideoItemDetailFragment.VIDEO_URL);
|
||||
currentStreamingService = intent.getIntExtra(VideoItemDetailFragment.STREAMING_SERVICE, -1);
|
||||
videoUrl = intent.getStringExtra(NavStack.URL);
|
||||
currentStreamingService = intent.getIntExtra(NavStack.SERVICE_ID, -1);
|
||||
}
|
||||
arguments.putBoolean(VideoItemDetailFragment.AUTO_PLAY, autoplay);
|
||||
arguments.putString(VideoItemDetailFragment.VIDEO_URL, videoUrl);
|
||||
arguments.putInt(VideoItemDetailFragment.STREAMING_SERVICE, currentStreamingService);
|
||||
arguments.putString(NavStack.URL, videoUrl);
|
||||
arguments.putInt(NavStack.SERVICE_ID, currentStreamingService);
|
||||
addFragment(arguments);
|
||||
}
|
||||
|
||||
@@ -141,13 +148,17 @@ public class VideoItemDetailActivity extends AppCompatActivity {
|
||||
|
||||
@Override
|
||||
public void onSaveInstanceState(Bundle outState) {
|
||||
outState.putString(VideoItemDetailFragment.VIDEO_URL, videoUrl);
|
||||
outState.putInt(VideoItemDetailFragment.STREAMING_SERVICE, currentStreamingService);
|
||||
super.onSaveInstanceState(outState);
|
||||
outState.putString(NavStack.URL, videoUrl);
|
||||
outState.putInt(NavStack.SERVICE_ID, currentStreamingService);
|
||||
outState.putBoolean(VideoItemDetailFragment.AUTO_PLAY, false);
|
||||
NavStack.getInstance()
|
||||
.onSaveInstanceState(outState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
super.onOptionsItemSelected(item);
|
||||
int id = item.getItemId();
|
||||
if (id == android.R.id.home) {
|
||||
// This ID represents the Home or Up button. In the case of this
|
||||
@@ -157,24 +168,24 @@ public class VideoItemDetailActivity extends AppCompatActivity {
|
||||
|
||||
// http://developer.android.com/design/patterns/navigation.html#up-vs-back
|
||||
|
||||
Intent intent = new Intent(this, MainActivity.class);
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
|
||||
NavUtils.navigateUpTo(this, intent);
|
||||
NavStack.getInstance()
|
||||
.openMainActivity(this);
|
||||
return true;
|
||||
} else {
|
||||
return fragment.onOptionsItemSelected(item) ||
|
||||
super.onOptionsItemSelected(item);
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
super.onCreateOptionsMenu(menu);
|
||||
fragment.onCreateOptionsMenu(menu, getMenuInflater());
|
||||
return true;
|
||||
public void onBackPressed() {
|
||||
try {
|
||||
NavStack.getInstance()
|
||||
.navBack(this);
|
||||
} catch (Exception e) {
|
||||
ErrorActivity.reportUiError(this, e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves all Strings which look remotely like URLs from a text.
|
||||
* Used if NewPipe was called through share menu.
|
||||
@@ -231,7 +242,7 @@ public class VideoItemDetailActivity extends AppCompatActivity {
|
||||
StreamingService[] serviceList = NewPipe.getServices();
|
||||
int service = -1;
|
||||
for (int i = 0; i < serviceList.length; i++) {
|
||||
if (serviceList[i].getUrlIdHandlerInstance().acceptUrl(videoUrl)) {
|
||||
if (serviceList[i].getStreamUrlIdHandlerInstance().acceptUrl(videoUrl)) {
|
||||
service = i;
|
||||
//videoExtractor = ServiceList.getService(i).getExtractorInstance();
|
||||
break;
|
||||
|
@@ -21,6 +21,7 @@ import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
@@ -30,7 +31,6 @@ import android.widget.LinearLayout;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.TextView;
|
||||
import android.view.MenuItem;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.google.android.exoplayer.util.Util;
|
||||
@@ -39,26 +39,27 @@ import com.nostra13.universalimageloader.core.ImageLoader;
|
||||
import com.nostra13.universalimageloader.core.assist.FailReason;
|
||||
import com.nostra13.universalimageloader.core.listener.ImageLoadingListener;
|
||||
|
||||
import java.util.Vector;
|
||||
|
||||
import org.schabi.newpipe.ActivityCommunicator;
|
||||
import org.schabi.newpipe.ChannelActivity;
|
||||
import org.schabi.newpipe.ReCaptchaActivity;
|
||||
import org.schabi.newpipe.extractor.stream_info.StreamInfo;
|
||||
import org.schabi.newpipe.extractor.stream_info.StreamPreviewInfo;
|
||||
import org.schabi.newpipe.info_list.InfoItemBuilder;
|
||||
import org.schabi.newpipe.report.ErrorActivity;
|
||||
import org.schabi.newpipe.ImageErrorLoadingListener;
|
||||
import org.schabi.newpipe.Localization;
|
||||
import org.schabi.newpipe.R;
|
||||
import org.schabi.newpipe.ReCaptchaActivity;
|
||||
import org.schabi.newpipe.download.DownloadDialog;
|
||||
import org.schabi.newpipe.extractor.stream_info.AudioStream;
|
||||
import org.schabi.newpipe.extractor.InfoItem;
|
||||
import org.schabi.newpipe.extractor.MediaFormat;
|
||||
import org.schabi.newpipe.extractor.NewPipe;
|
||||
import org.schabi.newpipe.extractor.stream_info.AudioStream;
|
||||
import org.schabi.newpipe.extractor.stream_info.StreamInfo;
|
||||
import org.schabi.newpipe.extractor.stream_info.VideoStream;
|
||||
import org.schabi.newpipe.info_list.InfoItemBuilder;
|
||||
import org.schabi.newpipe.player.BackgroundPlayer;
|
||||
import org.schabi.newpipe.player.PlayVideoActivity;
|
||||
import org.schabi.newpipe.player.ExoPlayerActivity;
|
||||
import org.schabi.newpipe.player.PlayVideoActivity;
|
||||
import org.schabi.newpipe.report.ErrorActivity;
|
||||
import java.util.Vector;
|
||||
|
||||
import org.schabi.newpipe.util.NavStack;
|
||||
import org.schabi.newpipe.util.PermissionHelper;
|
||||
|
||||
import static android.app.Activity.RESULT_OK;
|
||||
import static org.schabi.newpipe.ReCaptchaActivity.RECAPTCHA_REQUEST;
|
||||
@@ -91,8 +92,6 @@ public class VideoItemDetailFragment extends Fragment {
|
||||
* The fragment argument representing the item ID that this fragment
|
||||
* represents.
|
||||
*/
|
||||
public static final String VIDEO_URL = "video_url";
|
||||
public static final String STREAMING_SERVICE = "streaming_service";
|
||||
public static final String AUTO_PLAY = "auto_play";
|
||||
|
||||
private AppCompatActivity activity;
|
||||
@@ -144,6 +143,7 @@ public class VideoItemDetailFragment extends Fragment {
|
||||
TextView similarTitle = (TextView) activity.findViewById(R.id.detail_similar_title);
|
||||
Button backgroundButton = (Button)
|
||||
activity.findViewById(R.id.detail_stream_thumbnail_window_background_button);
|
||||
View thumbnailView = activity.findViewById(R.id.detail_thumbnail_view);
|
||||
View topView = activity.findViewById(R.id.detailTopView);
|
||||
Button channelButton = (Button) activity.findViewById(R.id.channel_button);
|
||||
|
||||
@@ -275,14 +275,20 @@ public class VideoItemDetailFragment extends Fragment {
|
||||
}
|
||||
});
|
||||
|
||||
//todo: make backgroundButton handle this
|
||||
thumbnailView.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
playVideo(info);
|
||||
}
|
||||
});
|
||||
|
||||
if (info.channel_url != null && info.channel_url != "") {
|
||||
channelButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
Intent i = new Intent(activity, ChannelActivity.class);
|
||||
i.putExtra(ChannelActivity.CHANNEL_URL, info.channel_url);
|
||||
i.putExtra(ChannelActivity.SERVICE_ID, info.service_id);
|
||||
startActivity(i);
|
||||
NavStack.getInstance()
|
||||
.openChannelActivity(getActivity(), info.channel_url, info.service_id);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
@@ -393,6 +399,10 @@ public class VideoItemDetailFragment extends Fragment {
|
||||
actionBarHandler.setOnDownloadListener(new ActionBarHandler.OnActionListener() {
|
||||
@Override
|
||||
public void onActionSelected(int selectedStreamId) {
|
||||
if(!PermissionHelper.checkStoragePermissions(getActivity())) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
Bundle args = new Bundle();
|
||||
|
||||
@@ -523,13 +533,15 @@ public class VideoItemDetailFragment extends Fragment {
|
||||
|
||||
private void initSimilarVideos(final StreamInfo info) {
|
||||
LinearLayout similarLayout = (LinearLayout) activity.findViewById(R.id.similar_streams_view);
|
||||
for (final StreamPreviewInfo item : info.related_streams) {
|
||||
for (final InfoItem item : info.related_streams) {
|
||||
similarLayout.addView(infoItemBuilder.buildView(similarLayout, item));
|
||||
}
|
||||
infoItemBuilder.setOnItemSelectedListener(new InfoItemBuilder.OnItemSelectedListener() {
|
||||
infoItemBuilder.setOnStreamInfoItemSelectedListener(
|
||||
new InfoItemBuilder.OnInfoItemSelectedListener() {
|
||||
@Override
|
||||
public void selected(String url) {
|
||||
openStreamUrl(url);
|
||||
public void selected(String url, int serviceId) {
|
||||
NavStack.getInstance()
|
||||
.openDetailActivity(getContext(), url, serviceId);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -629,6 +641,7 @@ public class VideoItemDetailFragment extends Fragment {
|
||||
onNotSpecifiedContentError();
|
||||
}
|
||||
});
|
||||
setHasOptionsMenu(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -647,10 +660,9 @@ public class VideoItemDetailFragment extends Fragment {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityCreated(Bundle savedInstanceBundle) {
|
||||
super.onActivityCreated(savedInstanceBundle);
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
Activity a = getActivity();
|
||||
|
||||
infoItemBuilder = new InfoItemBuilder(a, a.findViewById(android.R.id.content));
|
||||
|
||||
if (android.os.Build.VERSION.SDK_INT < 18) {
|
||||
@@ -664,8 +676,8 @@ public class VideoItemDetailFragment extends Fragment {
|
||||
// then we must not try to access objects of this fragment.
|
||||
// Otherwise the applications would crash.
|
||||
if(backgroundButton != null) {
|
||||
streamingServiceId = getArguments().getInt(STREAMING_SERVICE);
|
||||
String videoUrl = getArguments().getString(VIDEO_URL);
|
||||
streamingServiceId = getArguments().getInt(NavStack.SERVICE_ID);
|
||||
String videoUrl = getArguments().getString(NavStack.URL);
|
||||
StreamInfoWorker siw = StreamInfoWorker.getInstance();
|
||||
siw.search(streamingServiceId, videoUrl, getActivity());
|
||||
|
||||
@@ -779,11 +791,13 @@ public class VideoItemDetailFragment extends Fragment {
|
||||
|
||||
@Override
|
||||
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
|
||||
super.onCreateOptionsMenu(menu, inflater);
|
||||
actionBarHandler.setupMenu(menu, inflater);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
super.onOptionsItemSelected(item);
|
||||
return actionBarHandler.onItemSelected(item);
|
||||
}
|
||||
|
||||
@@ -796,20 +810,13 @@ public class VideoItemDetailFragment extends Fragment {
|
||||
stringResource, Toast.LENGTH_LONG).show();
|
||||
}
|
||||
|
||||
private void openStreamUrl(String url) {
|
||||
Intent detailIntent = new Intent(activity, VideoItemDetailActivity.class);
|
||||
detailIntent.putExtra(VideoItemDetailFragment.VIDEO_URL, url);
|
||||
detailIntent.putExtra(
|
||||
VideoItemDetailFragment.STREAMING_SERVICE, streamingServiceId);
|
||||
activity.startActivity(detailIntent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
switch (requestCode) {
|
||||
case RECAPTCHA_REQUEST:
|
||||
if (resultCode == RESULT_OK) {
|
||||
String videoUrl = getArguments().getString(VIDEO_URL);
|
||||
String videoUrl = getArguments().getString(NavStack.URL);
|
||||
StreamInfoWorker siw = StreamInfoWorker.getInstance();
|
||||
siw.search(streamingServiceId, videoUrl, getActivity());
|
||||
} else {
|
||||
|
@@ -13,8 +13,8 @@ import android.os.IBinder;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.support.v4.app.NavUtils;
|
||||
import android.support.v7.app.ActionBar;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
@@ -28,8 +28,10 @@ import android.widget.SeekBar;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import org.schabi.newpipe.ThemableActivity;
|
||||
import org.schabi.newpipe.report.ErrorActivity;
|
||||
import org.schabi.newpipe.R;
|
||||
import org.schabi.newpipe.settings.NewPipeSettings;
|
||||
import org.schabi.newpipe.settings.SettingsActivity;
|
||||
|
||||
import java.io.File;
|
||||
@@ -42,7 +44,7 @@ import us.shandian.giga.ui.fragment.MissionsFragment;
|
||||
import us.shandian.giga.util.CrashHandler;
|
||||
import us.shandian.giga.util.Utility;
|
||||
|
||||
public class DownloadActivity extends AppCompatActivity implements AdapterView.OnItemClickListener{
|
||||
public class DownloadActivity extends ThemableActivity implements AdapterView.OnItemClickListener{
|
||||
|
||||
public static final String INTENT_DOWNLOAD = "us.shandian.giga.intent.DOWNLOAD";
|
||||
|
||||
@@ -53,26 +55,11 @@ public class DownloadActivity extends AppCompatActivity implements AdapterView.O
|
||||
|
||||
|
||||
private MissionsFragment mFragment;
|
||||
private DownloadManager mManager;
|
||||
private DownloadManagerService.DMBinder mBinder;
|
||||
|
||||
|
||||
private String mPendingUrl;
|
||||
private SharedPreferences mPrefs;
|
||||
|
||||
private ServiceConnection mConnection = new ServiceConnection() {
|
||||
|
||||
@Override
|
||||
public void onServiceConnected(ComponentName p1, IBinder binder) {
|
||||
mBinder = (DownloadManagerService.DMBinder) binder;
|
||||
mManager = mBinder.getDownloadManager();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServiceDisconnected(ComponentName p1) {
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
@TargetApi(21)
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
@@ -83,7 +70,6 @@ public class DownloadActivity extends AppCompatActivity implements AdapterView.O
|
||||
Intent i = new Intent();
|
||||
i.setClass(this, DownloadManagerService.class);
|
||||
startService(i);
|
||||
bindService(i, mConnection, Context.BIND_AUTO_CREATE);
|
||||
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_downloader);
|
||||
@@ -91,7 +77,7 @@ public class DownloadActivity extends AppCompatActivity implements AdapterView.O
|
||||
|
||||
//noinspection ConstantConditions
|
||||
|
||||
// its ok if this failes, we will catch that error later, and send it as report
|
||||
// its ok if this fails, we will catch that error later, and send it as report
|
||||
ActionBar actionBar = getSupportActionBar();
|
||||
actionBar.setDisplayHomeAsUpEnabled(true);
|
||||
actionBar.setTitle(R.string.downloads_title);
|
||||
@@ -202,22 +188,24 @@ public class DownloadActivity extends AppCompatActivity implements AdapterView.O
|
||||
@Override
|
||||
public boolean onMenuItemClick(MenuItem item) {
|
||||
if (item.getItemId() == R.id.okay) {
|
||||
|
||||
String location;
|
||||
if(audioButton.isChecked()) {
|
||||
location = NewPipeSettings.getAudioDownloadPath(DownloadActivity.this);
|
||||
} else {
|
||||
location = NewPipeSettings.getVideoDownloadPath(DownloadActivity.this);
|
||||
}
|
||||
|
||||
String fName = name.getText().toString().trim();
|
||||
|
||||
File f = new File(mManager.getLocation() + "/" + fName);
|
||||
|
||||
File f = new File(location, fName);
|
||||
if (f.exists()) {
|
||||
Toast.makeText(DownloadActivity.this, R.string.msg_exists, Toast.LENGTH_SHORT).show();
|
||||
} else {
|
||||
|
||||
while (mBinder == null);
|
||||
|
||||
int res = mManager.startMission(
|
||||
getIntent().getData().toString(),
|
||||
fName,
|
||||
audioButton.isChecked(),
|
||||
threads.getProgress() + 1);
|
||||
mBinder.onMissionAdded(mManager.getMission(res));
|
||||
DownloadManagerService.startMission(
|
||||
DownloadActivity.this,
|
||||
getIntent().getData().toString(), location, fName,
|
||||
audioButton.isChecked(), threads.getProgress() + 1);
|
||||
mFragment.notifyChange();
|
||||
|
||||
mPrefs.edit().putInt(THREADS, threads.getProgress() + 1).commit();
|
||||
@@ -254,9 +242,7 @@ public class DownloadActivity extends AppCompatActivity implements AdapterView.O
|
||||
|
||||
switch (id) {
|
||||
case android.R.id.home: {
|
||||
Intent intent = new Intent(this, org.schabi.newpipe.MainActivity.class);
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
|
||||
NavUtils.navigateUpTo(this, intent);
|
||||
onBackPressed();
|
||||
return true;
|
||||
}
|
||||
case R.id.action_settings: {
|
||||
@@ -264,17 +250,9 @@ public class DownloadActivity extends AppCompatActivity implements AdapterView.O
|
||||
startActivity(intent);
|
||||
return true;
|
||||
}
|
||||
case R.id.action_report_error: {
|
||||
ErrorActivity.reportError(DownloadActivity.this, new Vector<Throwable>(),
|
||||
null, null,
|
||||
ErrorActivity.ErrorInfo.make(ErrorActivity.USER_REPORT,
|
||||
null,
|
||||
"user_report", R.string.user_report));
|
||||
return true;
|
||||
}
|
||||
default:
|
||||
return mFragment.onOptionsItemSelected(item) ||
|
||||
super.onOptionsItemSelected(item);
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -26,6 +26,8 @@ import android.widget.TextView;
|
||||
|
||||
import org.schabi.newpipe.App;
|
||||
import org.schabi.newpipe.R;
|
||||
import org.schabi.newpipe.extractor.NewPipe;
|
||||
import org.schabi.newpipe.settings.NewPipeSettings;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
@@ -65,24 +67,6 @@ public class DownloadDialog extends DialogFragment {
|
||||
public static final String AUDIO_URL = "audio_url";
|
||||
public static final String VIDEO_URL = "video_url";
|
||||
|
||||
private DownloadManager mManager;
|
||||
private DownloadManagerService.DMBinder mBinder;
|
||||
|
||||
private ServiceConnection mConnection = new ServiceConnection() {
|
||||
|
||||
@Override
|
||||
public void onServiceConnected(ComponentName p1, IBinder binder) {
|
||||
mBinder = (DownloadManagerService.DMBinder) binder;
|
||||
mManager = mBinder.getDownloadManager();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServiceDisconnected(ComponentName p1) {
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
public DownloadDialog() {
|
||||
|
||||
}
|
||||
@@ -102,12 +86,6 @@ public class DownloadDialog extends DialogFragment {
|
||||
if(ContextCompat.checkSelfPermission(this.getContext(),Manifest.permission.WRITE_EXTERNAL_STORAGE)!= PackageManager.PERMISSION_GRANTED)
|
||||
ActivityCompat.requestPermissions(getActivity(),new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},0);
|
||||
|
||||
Intent i = new Intent();
|
||||
i.setClass(getContext(), DownloadManagerService.class);
|
||||
getContext().startService(i);
|
||||
getContext().bindService(i, mConnection, Context.BIND_AUTO_CREATE);
|
||||
|
||||
|
||||
return inflater.inflate(R.layout.dialog_url, container);
|
||||
}
|
||||
|
||||
@@ -219,36 +197,22 @@ public class DownloadDialog extends DialogFragment {
|
||||
|
||||
String fName = name.getText().toString().trim();
|
||||
|
||||
// todo: add timeout? would be bad if the thread gets locked dueto this.
|
||||
while (mBinder == null);
|
||||
|
||||
if(audioButton.isChecked()){
|
||||
int res = mManager.startMission(
|
||||
arguments.getString(AUDIO_URL),
|
||||
fName + arguments.getString(FILE_SUFFIX_AUDIO),
|
||||
audioButton.isChecked(),
|
||||
threads.getProgress() + 1);
|
||||
DownloadMission mission = mManager.getMission(res);
|
||||
mBinder.onMissionAdded(mission);
|
||||
// add download listener to allow media scan notification
|
||||
DownloadListener listener = new DownloadListener(getContext(), mission);
|
||||
mission.addListener(listener);
|
||||
boolean isAudio = audioButton.isChecked();
|
||||
String url, location, filename;
|
||||
if(isAudio) {
|
||||
url = arguments.getString(AUDIO_URL);
|
||||
location = NewPipeSettings.getAudioDownloadPath(getContext());
|
||||
filename = fName + arguments.getString(FILE_SUFFIX_AUDIO);
|
||||
} else {
|
||||
url = arguments.getString(VIDEO_URL);
|
||||
location = NewPipeSettings.getVideoDownloadPath(getContext());
|
||||
filename = fName + arguments.getString(FILE_SUFFIX_VIDEO);
|
||||
}
|
||||
|
||||
if(videoButton.isChecked()){
|
||||
int res = mManager.startMission(
|
||||
arguments.getString(VIDEO_URL),
|
||||
fName + arguments.getString(FILE_SUFFIX_VIDEO),
|
||||
audioButton.isChecked(),
|
||||
threads.getProgress() + 1);
|
||||
DownloadMission mission = mManager.getMission(res);
|
||||
mBinder.onMissionAdded(mission);
|
||||
// add download listener to allow media scan notification
|
||||
DownloadListener listener = new DownloadListener(getContext(), mission);
|
||||
mission.addListener(listener);
|
||||
}
|
||||
DownloadManagerService.startMission(getContext(), url, location, filename, isAudio,
|
||||
threads.getProgress() + 1);
|
||||
|
||||
getDialog().dismiss();
|
||||
|
||||
}
|
||||
|
||||
private void download(String url, String title,
|
||||
|
@@ -1,62 +0,0 @@
|
||||
package org.schabi.newpipe.download;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
|
||||
import us.shandian.giga.get.DownloadMission;
|
||||
import us.shandian.giga.get.DownloadMission.MissionListener;
|
||||
|
||||
/**
|
||||
* Created by erwin on 06.11.16.
|
||||
*
|
||||
* Copyright (C) Christian Schabesberger 2016 <chris.schabesberger@mailbox.org>
|
||||
* DownloadListener.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/>.
|
||||
*/
|
||||
|
||||
class DownloadListener implements MissionListener
|
||||
{
|
||||
DownloadMission mMission;
|
||||
Context mContext;
|
||||
|
||||
public DownloadListener(Context context, DownloadMission mission)
|
||||
{
|
||||
super();
|
||||
mMission = mission;
|
||||
mContext = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onProgressUpdate(long done, long total)
|
||||
{
|
||||
// do nothing special ...
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFinish()
|
||||
{
|
||||
// notify media scanner on downloaded media file ...
|
||||
mContext.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE,
|
||||
Uri.parse( "file://" + mMission.location
|
||||
+ "/" + mMission.name)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(int errCode)
|
||||
{
|
||||
// do nothing special ...
|
||||
}
|
||||
}
|
@@ -42,7 +42,7 @@ import info.guardianproject.netcipher.NetCipher;
|
||||
*/
|
||||
|
||||
|
||||
// TODO: FOR HEVEN SAKE !!! DO NOT SIMPLY USE ASYNCTASK. MAKE THIS A PROPER SERVICE !!!
|
||||
// TODO: FOR HEAVEN SAKE !!! DO NOT SIMPLY USE ASYNCTASK. MAKE THIS A PROPER SERVICE !!!
|
||||
public class FileDownloader extends AsyncTask<Void, Integer, Void> {
|
||||
public static final String TAG = "FileDownloader";
|
||||
|
||||
|
@@ -18,9 +18,9 @@ package org.schabi.newpipe.extractor;
|
||||
* along with NewPipe. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**Common properties between StreamInfo and StreamPreviewInfo.*/
|
||||
/**Common properties between StreamInfo and StreamInfoItem.*/
|
||||
public abstract class AbstractStreamInfo {
|
||||
public static enum StreamType {
|
||||
public enum StreamType {
|
||||
NONE, // placeholder to check if stream type was checked or not
|
||||
VIDEO_STREAM,
|
||||
AUDIO_STREAM,
|
||||
|
33
app/src/main/java/org/schabi/newpipe/extractor/InfoItem.java
Normal file
33
app/src/main/java/org/schabi/newpipe/extractor/InfoItem.java
Normal file
@@ -0,0 +1,33 @@
|
||||
package org.schabi.newpipe.extractor;
|
||||
|
||||
/**
|
||||
* Created by the-scrabi on 11.02.17.
|
||||
*
|
||||
* Copyright (C) Christian Schabesberger 2017 <chris.schabesberger@mailbox.org>
|
||||
* InfoItem.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 interface InfoItem {
|
||||
public enum InfoType {
|
||||
STREAM,
|
||||
PLAYLIST,
|
||||
CHANNEL
|
||||
}
|
||||
|
||||
InfoType infoType();
|
||||
String getTitle();
|
||||
String getLink();
|
||||
}
|
@@ -0,0 +1,61 @@
|
||||
package org.schabi.newpipe.extractor;
|
||||
|
||||
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Vector;
|
||||
|
||||
/**
|
||||
* Created by Christian Schabesberger on 12.02.17.
|
||||
*
|
||||
* Copyright (C) Christian Schabesberger 2017 <chris.schabesberger@mailbox.org>
|
||||
* InfoItemCollector.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 InfoItemCollector {
|
||||
private List<InfoItem> itemList = new Vector<>();
|
||||
private List<Throwable> errors = new Vector<>();
|
||||
private int serviceId = -1;
|
||||
|
||||
public InfoItemCollector(int serviceId) {
|
||||
this.serviceId = serviceId;
|
||||
}
|
||||
|
||||
public List<InfoItem> getItemList() {
|
||||
return itemList;
|
||||
}
|
||||
public List<Throwable> getErrors() {
|
||||
return errors;
|
||||
}
|
||||
protected void addFromCollector(InfoItemCollector otherC) throws ExtractionException {
|
||||
if(serviceId != otherC.serviceId) {
|
||||
throw new ExtractionException("Service Id does not equal: "
|
||||
+ NewPipe.getNameOfService(serviceId)
|
||||
+ " and " + NewPipe.getNameOfService(otherC.serviceId));
|
||||
}
|
||||
errors.addAll(otherC.errors);
|
||||
itemList.addAll(otherC.itemList);
|
||||
}
|
||||
protected void addError(Exception e) {
|
||||
errors.add(e);
|
||||
}
|
||||
protected void addItem(InfoItem item) {
|
||||
itemList.add(item);
|
||||
}
|
||||
protected int getServiceId() {
|
||||
return serviceId;
|
||||
}
|
||||
}
|
@@ -34,25 +34,22 @@ public class NewPipe {
|
||||
|
||||
private static final String TAG = NewPipe.class.toString();
|
||||
|
||||
private static final StreamingService[] serviceList = {
|
||||
new YoutubeService(0)
|
||||
};
|
||||
|
||||
private static Downloader downloader = null;
|
||||
|
||||
public static StreamingService[] getServices() {
|
||||
return serviceList;
|
||||
return ServiceList.serviceList;
|
||||
}
|
||||
public static StreamingService getService(int serviceId)throws ExtractionException {
|
||||
for(StreamingService s : serviceList) {
|
||||
for(StreamingService s : ServiceList.serviceList) {
|
||||
if(s.getServiceId() == serviceId) {
|
||||
return s;
|
||||
}
|
||||
}
|
||||
throw new ExtractionException("Service not known: " + Integer.toString(serviceId));
|
||||
return null;
|
||||
}
|
||||
public static StreamingService getService(String serviceName) throws ExtractionException {
|
||||
return serviceList[getIdOfService(serviceName)];
|
||||
return ServiceList.serviceList[getIdOfService(serviceName)];
|
||||
}
|
||||
public static String getNameOfService(int id) {
|
||||
try {
|
||||
@@ -63,13 +60,13 @@ public class NewPipe {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
public static int getIdOfService(String serviceName) throws ExtractionException {
|
||||
for(int i = 0; i < serviceList.length; i++) {
|
||||
if(serviceList[i].getServiceInfo().name.equals(serviceName)) {
|
||||
public static int getIdOfService(String serviceName) {
|
||||
for(int i = 0; i < ServiceList.serviceList.length; i++) {
|
||||
if(ServiceList.serviceList[i].getServiceInfo().name.equals(serviceName)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
throw new ExtractionException("Error: Service " + serviceName + " not known.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
public static void init(Downloader d) {
|
||||
@@ -79,4 +76,13 @@ public class NewPipe {
|
||||
public static Downloader getDownloader() {
|
||||
return downloader;
|
||||
}
|
||||
|
||||
public static StreamingService getServiceByUrl(String url) {
|
||||
for(StreamingService s : ServiceList.serviceList) {
|
||||
if(s.getLinkTypeByUrl(url) != StreamingService.LinkType.NONE) {
|
||||
return s;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@@ -42,15 +42,23 @@ public class Parser {
|
||||
}
|
||||
|
||||
public static String matchGroup1(String pattern, String input) throws RegexException {
|
||||
return matchGroup(pattern, input, 1);
|
||||
}
|
||||
|
||||
public static String matchGroup(String pattern, String input, int group) throws RegexException {
|
||||
Pattern pat = Pattern.compile(pattern);
|
||||
Matcher mat = pat.matcher(input);
|
||||
boolean foundMatch = mat.find();
|
||||
if (foundMatch) {
|
||||
return mat.group(1);
|
||||
return mat.group(group);
|
||||
}
|
||||
else {
|
||||
//Log.e(TAG, "failed to find pattern \""+pattern+"\" inside of \""+input+"\"");
|
||||
throw new RegexException("failed to find pattern \""+pattern+" inside of "+input+"\"");
|
||||
if(input.length() > 1024) {
|
||||
throw new RegexException("failed to find pattern \""+pattern);
|
||||
} else {
|
||||
throw new RegexException("failed to find pattern \"" + pattern + " inside of " + input + "\"");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -0,0 +1,13 @@
|
||||
package org.schabi.newpipe.extractor;
|
||||
|
||||
import org.schabi.newpipe.extractor.services.youtube.YoutubeService;
|
||||
|
||||
/**
|
||||
* Created by the-scrabi on 18.02.17.
|
||||
*/
|
||||
|
||||
class ServiceList {
|
||||
public static final StreamingService[] serviceList = {
|
||||
new YoutubeService(0)
|
||||
};
|
||||
}
|
@@ -3,7 +3,6 @@ package org.schabi.newpipe.extractor;
|
||||
import org.schabi.newpipe.extractor.channel.ChannelExtractor;
|
||||
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
|
||||
import org.schabi.newpipe.extractor.search.SearchEngine;
|
||||
import org.schabi.newpipe.extractor.search.SuggestionExtractor;
|
||||
import org.schabi.newpipe.extractor.stream_info.StreamExtractor;
|
||||
|
||||
import java.io.IOException;
|
||||
@@ -33,6 +32,13 @@ public abstract class StreamingService {
|
||||
public String name = "";
|
||||
}
|
||||
|
||||
public enum LinkType {
|
||||
NONE,
|
||||
STREAM,
|
||||
CHANNEL,
|
||||
PLAYLIST
|
||||
}
|
||||
|
||||
private int serviceId;
|
||||
|
||||
public StreamingService(int id) {
|
||||
@@ -44,7 +50,7 @@ public abstract class StreamingService {
|
||||
public abstract StreamExtractor getExtractorInstance(String url)
|
||||
throws IOException, ExtractionException;
|
||||
public abstract SearchEngine getSearchEngineInstance();
|
||||
public abstract UrlIdHandler getUrlIdHandlerInstance();
|
||||
public abstract UrlIdHandler getStreamUrlIdHandlerInstance();
|
||||
public abstract UrlIdHandler getChannelUrlIdHandlerInstance();
|
||||
public abstract ChannelExtractor getChannelExtractorInstance(String url, int page)
|
||||
throws ExtractionException, IOException;
|
||||
@@ -53,4 +59,20 @@ public abstract class StreamingService {
|
||||
public final int getServiceId() {
|
||||
return serviceId;
|
||||
}
|
||||
|
||||
/**
|
||||
* figure out where the link is pointing to (a channel, video, playlist, etc.)
|
||||
*/
|
||||
public final LinkType getLinkTypeByUrl(String url) {
|
||||
UrlIdHandler sH = getStreamUrlIdHandlerInstance();
|
||||
UrlIdHandler cH = getChannelUrlIdHandlerInstance();
|
||||
|
||||
if(sH.acceptUrl(url)) {
|
||||
return LinkType.STREAM;
|
||||
} else if(cH.acceptUrl(url)) {
|
||||
return LinkType.CHANNEL;
|
||||
} else {
|
||||
return LinkType.NONE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,4 +1,4 @@
|
||||
package org.schabi.newpipe.extractor.search;
|
||||
package org.schabi.newpipe.extractor;
|
||||
|
||||
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
|
||||
|
@@ -23,6 +23,7 @@ import org.schabi.newpipe.extractor.exceptions.ParsingException;
|
||||
*/
|
||||
|
||||
public interface UrlIdHandler {
|
||||
|
||||
String getUrl(String videoId);
|
||||
String getId(String siteUrl) throws ParsingException;
|
||||
String cleanUrl(String siteUrl) throws ParsingException;
|
||||
|
@@ -3,7 +3,7 @@ package org.schabi.newpipe.extractor.channel;
|
||||
import org.schabi.newpipe.extractor.UrlIdHandler;
|
||||
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
|
||||
import org.schabi.newpipe.extractor.exceptions.ParsingException;
|
||||
import org.schabi.newpipe.extractor.stream_info.StreamPreviewInfoCollector;
|
||||
import org.schabi.newpipe.extractor.stream_info.StreamInfoItemCollector;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
@@ -31,7 +31,7 @@ public abstract class ChannelExtractor {
|
||||
private int serviceId;
|
||||
private String url;
|
||||
private UrlIdHandler urlIdHandler;
|
||||
private StreamPreviewInfoCollector previewInfoCollector;
|
||||
private StreamInfoItemCollector previewInfoCollector;
|
||||
private int page = -1;
|
||||
|
||||
public ChannelExtractor(UrlIdHandler urlIdHandler, String url, int page, int serviceId)
|
||||
@@ -40,12 +40,12 @@ public abstract class ChannelExtractor {
|
||||
this.page = page;
|
||||
this.serviceId = serviceId;
|
||||
this.urlIdHandler = urlIdHandler;
|
||||
previewInfoCollector = new StreamPreviewInfoCollector(urlIdHandler, serviceId);
|
||||
previewInfoCollector = new StreamInfoItemCollector(urlIdHandler, serviceId);
|
||||
}
|
||||
|
||||
public String getUrl() { return url; }
|
||||
public UrlIdHandler getUrlIdHandler() { return urlIdHandler; }
|
||||
public StreamPreviewInfoCollector getStreamPreviewInfoCollector() {
|
||||
public StreamInfoItemCollector getStreamPreviewInfoCollector() {
|
||||
return previewInfoCollector;
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ public abstract class ChannelExtractor {
|
||||
public abstract String getAvatarUrl() throws ParsingException;
|
||||
public abstract String getBannerUrl() throws ParsingException;
|
||||
public abstract String getFeedUrl() throws ParsingException;
|
||||
public abstract StreamPreviewInfoCollector getStreams() throws ParsingException;
|
||||
public abstract StreamInfoItemCollector getStreams() throws ParsingException;
|
||||
public abstract boolean hasNextPage() throws ParsingException;
|
||||
public int getServiceId() {
|
||||
return serviceId;
|
||||
|
@@ -1,8 +1,9 @@
|
||||
package org.schabi.newpipe.extractor.channel;
|
||||
|
||||
import org.schabi.newpipe.extractor.InfoItem;
|
||||
import org.schabi.newpipe.extractor.exceptions.ParsingException;
|
||||
import org.schabi.newpipe.extractor.stream_info.StreamPreviewInfo;
|
||||
import org.schabi.newpipe.extractor.stream_info.StreamPreviewInfoCollector;
|
||||
import org.schabi.newpipe.extractor.stream_info.StreamInfoItem;
|
||||
import org.schabi.newpipe.extractor.stream_info.StreamInfoItemCollector;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Vector;
|
||||
@@ -59,7 +60,7 @@ public class ChannelInfo {
|
||||
info.errors.add(e);
|
||||
}
|
||||
try {
|
||||
StreamPreviewInfoCollector c = extractor.getStreams();
|
||||
StreamInfoItemCollector c = extractor.getStreams();
|
||||
info.related_streams = c.getItemList();
|
||||
info.errors.addAll(c.getErrors());
|
||||
} catch(Exception e) {
|
||||
@@ -74,7 +75,7 @@ public class ChannelInfo {
|
||||
public String avatar_url = "";
|
||||
public String banner_url = "";
|
||||
public String feed_url = "";
|
||||
public List<StreamPreviewInfo> related_streams = null;
|
||||
public List<InfoItem> related_streams = null;
|
||||
public boolean hasNextPage = false;
|
||||
|
||||
public List<Throwable> errors = new Vector<>();
|
||||
|
@@ -0,0 +1,44 @@
|
||||
package org.schabi.newpipe.extractor.channel;
|
||||
|
||||
import org.schabi.newpipe.extractor.InfoItem;
|
||||
|
||||
/**
|
||||
* Created by Christian Schabesberger on 11.02.17.
|
||||
*
|
||||
* Copyright (C) Christian Schabesberger 2017 <chris.schabesberger@mailbox.org>
|
||||
* ChannelInfoItem.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 ChannelInfoItem implements InfoItem {
|
||||
|
||||
public int serviceId = -1;
|
||||
public String channelName = "";
|
||||
public String thumbnailUrl = "";
|
||||
public String webPageUrl = "";
|
||||
public String description = "";
|
||||
public long subscriberCount = -1;
|
||||
public int videoAmount = -1;
|
||||
|
||||
public InfoType infoType() {
|
||||
return InfoType.CHANNEL;
|
||||
}
|
||||
public String getTitle() {
|
||||
return channelName;
|
||||
}
|
||||
public String getLink() {
|
||||
return webPageUrl;
|
||||
}
|
||||
}
|
@@ -0,0 +1,74 @@
|
||||
package org.schabi.newpipe.extractor.channel;
|
||||
|
||||
import org.schabi.newpipe.extractor.InfoItemCollector;
|
||||
import org.schabi.newpipe.extractor.NewPipe;
|
||||
import org.schabi.newpipe.extractor.exceptions.FoundAdException;
|
||||
import org.schabi.newpipe.extractor.exceptions.ParsingException;
|
||||
import org.schabi.newpipe.extractor.stream_info.StreamInfoItem;
|
||||
import org.schabi.newpipe.extractor.stream_info.StreamInfoItemExtractor;
|
||||
|
||||
/**
|
||||
* Created by Christian Schabesberger on 12.02.17.
|
||||
*
|
||||
* Copyright (C) Christian Schabesberger 2017 <chris.schabesberger@mailbox.org>
|
||||
* ChannelInfoItemCollector.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 ChannelInfoItemCollector extends InfoItemCollector {
|
||||
public ChannelInfoItemCollector(int serviceId) {
|
||||
super(serviceId);
|
||||
}
|
||||
|
||||
public ChannelInfoItem extract(ChannelInfoItemExtractor extractor) throws ParsingException {
|
||||
ChannelInfoItem resultItem = new ChannelInfoItem();
|
||||
// importand information
|
||||
resultItem.channelName = extractor.getChannelName();
|
||||
|
||||
resultItem.serviceId = getServiceId();
|
||||
resultItem.webPageUrl = extractor.getWebPageUrl();
|
||||
|
||||
// optional information
|
||||
try {
|
||||
resultItem.subscriberCount = extractor.getSubscriberCount();
|
||||
} catch (Exception e) {
|
||||
addError(e);
|
||||
}
|
||||
try {
|
||||
resultItem.videoAmount = extractor.getVideoAmount();
|
||||
} catch (Exception e) {
|
||||
addError(e);
|
||||
}
|
||||
try {
|
||||
resultItem.thumbnailUrl = extractor.getThumbnailUrl();
|
||||
} catch (Exception e) {
|
||||
addError(e);
|
||||
}
|
||||
try {
|
||||
resultItem.description = extractor.getDescription();
|
||||
} catch (Exception e) {
|
||||
addError(e);
|
||||
}
|
||||
return resultItem;
|
||||
}
|
||||
|
||||
public void commit(ChannelInfoItemExtractor extractor) throws ParsingException {
|
||||
try {
|
||||
addItem(extract(extractor));
|
||||
} catch (Exception e) {
|
||||
addError(e);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,32 @@
|
||||
package org.schabi.newpipe.extractor.channel;
|
||||
|
||||
import org.schabi.newpipe.extractor.exceptions.ParsingException;
|
||||
|
||||
/**
|
||||
* Created by Christian Schabesberger on 12.02.17.
|
||||
*
|
||||
* Copyright (C) Christian Schabesberger 2017 <chris.schabesberger@mailbox.org>
|
||||
* ChannelInfoItemExtractor.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 interface ChannelInfoItemExtractor {
|
||||
String getThumbnailUrl() throws ParsingException;
|
||||
String getChannelName() throws ParsingException;
|
||||
String getWebPageUrl() throws ParsingException;
|
||||
String getDescription() throws ParsingException;
|
||||
long getSubscriberCount() throws ParsingException;
|
||||
int getVideoAmount() throws ParsingException;
|
||||
}
|
@@ -0,0 +1,79 @@
|
||||
package org.schabi.newpipe.extractor.search;
|
||||
|
||||
import org.schabi.newpipe.extractor.InfoItemCollector;
|
||||
import org.schabi.newpipe.extractor.UrlIdHandler;
|
||||
import org.schabi.newpipe.extractor.channel.ChannelInfoItemCollector;
|
||||
import org.schabi.newpipe.extractor.channel.ChannelInfoItemExtractor;
|
||||
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
|
||||
import org.schabi.newpipe.extractor.exceptions.FoundAdException;
|
||||
import org.schabi.newpipe.extractor.exceptions.ParsingException;
|
||||
import org.schabi.newpipe.extractor.stream_info.StreamInfoItemCollector;
|
||||
import org.schabi.newpipe.extractor.stream_info.StreamInfoItemExtractor;
|
||||
|
||||
/**
|
||||
* Created by Christian Schabesberger on 12.02.17.
|
||||
*
|
||||
* Copyright (C) Christian Schabesberger 2017 <chris.schabesberger@mailbox.org>
|
||||
* InfoItemSearchCollector.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 InfoItemSearchCollector extends InfoItemCollector {
|
||||
private String suggestion = "";
|
||||
private StreamInfoItemCollector streamCollector;
|
||||
private ChannelInfoItemCollector channelCollector;
|
||||
|
||||
SearchResult result = new SearchResult();
|
||||
|
||||
InfoItemSearchCollector(UrlIdHandler handler, int serviceId) {
|
||||
super(serviceId);
|
||||
streamCollector = new StreamInfoItemCollector(handler, serviceId);
|
||||
channelCollector = new ChannelInfoItemCollector(serviceId);
|
||||
}
|
||||
|
||||
public void setSuggestion(String suggestion) {
|
||||
this.suggestion = suggestion;
|
||||
}
|
||||
|
||||
public SearchResult getSearchResult() throws ExtractionException {
|
||||
|
||||
addFromCollector(channelCollector);
|
||||
addFromCollector(streamCollector);
|
||||
|
||||
result.suggestion = suggestion;
|
||||
result.errors = getErrors();
|
||||
return result;
|
||||
}
|
||||
|
||||
public void commit(StreamInfoItemExtractor extractor) {
|
||||
try {
|
||||
result.resultList.add(streamCollector.extract(extractor));
|
||||
} catch(FoundAdException ae) {
|
||||
System.err.println("Found add");
|
||||
} catch (Exception e) {
|
||||
addError(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void commit(ChannelInfoItemExtractor extractor) {
|
||||
try {
|
||||
result.resultList.add(channelCollector.extract(extractor));
|
||||
} catch(FoundAdException ae) {
|
||||
System.err.println("Found add");
|
||||
} catch (Exception e) {
|
||||
addError(e);
|
||||
}
|
||||
}
|
||||
}
|
@@ -2,9 +2,10 @@ package org.schabi.newpipe.extractor.search;
|
||||
|
||||
import org.schabi.newpipe.extractor.UrlIdHandler;
|
||||
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
|
||||
import org.schabi.newpipe.extractor.stream_info.StreamInfoItemCollector;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.EnumSet;
|
||||
|
||||
/**
|
||||
* Created by Christian Schabesberger on 10.08.15.
|
||||
@@ -26,26 +27,27 @@ import java.util.List;
|
||||
* along with NewPipe. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
@SuppressWarnings("ALL")
|
||||
public abstract class SearchEngine {
|
||||
public enum Filter {
|
||||
STREAM, CHANNEL, PLAY_LIST
|
||||
}
|
||||
|
||||
public static class NothingFoundException extends ExtractionException {
|
||||
public NothingFoundException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
|
||||
private StreamPreviewInfoSearchCollector collector;
|
||||
private InfoItemSearchCollector collector;
|
||||
|
||||
public SearchEngine(UrlIdHandler urlIdHandler, int serviceId) {
|
||||
collector = new StreamPreviewInfoSearchCollector(urlIdHandler, serviceId);
|
||||
collector = new InfoItemSearchCollector(urlIdHandler, serviceId);
|
||||
}
|
||||
|
||||
protected StreamPreviewInfoSearchCollector getStreamPreviewInfoSearchCollector() {
|
||||
protected InfoItemSearchCollector getInfoItemSearchCollector() {
|
||||
return collector;
|
||||
}
|
||||
|
||||
//Result search(String query, int page);
|
||||
public abstract StreamPreviewInfoSearchCollector search(
|
||||
String query, int page, String contentCountry)
|
||||
public abstract InfoItemSearchCollector search(
|
||||
String query, int page, String contentCountry, EnumSet<Filter> filter)
|
||||
throws ExtractionException, IOException;
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user