// IPTV extension for App Inventor by Marco Perrone
package Iptv;
import com.google.appinventor.components.runtime.*;
import android.app.Activity;
import android.content.Intent;
import com.google.appinventor.components.annotations.DesignerComponent;
import com.google.appinventor.components.annotations.DesignerProperty;
import com.google.appinventor.components.annotations.PropertyCategory;
import com.google.appinventor.components.annotations.SimpleFunction;
import com.google.appinventor.components.annotations.SimpleEvent;
import com.google.appinventor.components.annotations.SimpleObject;
import com.google.appinventor.components.annotations.SimpleProperty;
import com.google.appinventor.components.annotations.UsesPermissions;
import com.google.appinventor.components.annotations.UsesActivities;
import com.google.appinventor.components.annotations.UsesLibraries;
import com.google.appinventor.components.annotations.UsesActivityMetadata;
import com.google.appinventor.components.annotations.androidmanifest.*;
import com.google.appinventor.components.common.ComponentCategory;
import com.google.appinventor.components.common.PropertyTypeConstants;
import com.google.appinventor.components.common.YaVersion;
import com.google.appinventor.components.runtime.util.GingerbreadUtil;
import com.google.appinventor.components.runtime.util.SdkLevel;
import com.google.appinventor.components.runtime.util.AsynchUtil;
import com.google.appinventor.components.runtime.util.YailList;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.CookieHandler;
import java.util.Scanner;
import java.util.Iterator;
import java.util.Map;
import java.util.List;
import java.util.ArrayList;
import java.io.FileWriter;
import java.io.BufferedWriter;
import java.io.StringWriter;
import java.io.PrintWriter;
import java.io.IOException;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.DataOutputStream;
import java.io.BufferedReader;
import java.io.OutputStream;
@SimpleObject(external=true)
@UsesPermissions(permissionNames = "android.permission.INTERNET")
@DesignerComponent(version = YaVersion.WEB_COMPONENT_VERSION,
description = "
Non-visible component to search IPTV from all over the world.",
category = ComponentCategory.EXTENSION,
nonVisible = true,
iconName = "images/nearfield.png")
public class Iptv extends AndroidNonvisibleComponent implements Component {
private final Activity activity;
private final CookieHandler cookieHandler;
private String twoHyphens = "--";
private String boundary = "*****"+Long.toString(System.currentTimeMillis())+"*****";
private String LINE = "\r\n";
private URL url;
private HttpURLConnection httpConn = null;
private OutputStream outputStream;
private PrintWriter writer;
private String charset = "utf-8";
@SimpleEvent(description = "Got Countries")
public void GotCountries(int responseCode, String response, YailList country, YailList countryCode, YailList language, String message) {
EventDispatcher.dispatchEvent(this, "GotCountries", responseCode, response, country, countryCode, language, message);
}
@SimpleEvent(description = "Got Categories")
public void GotCategories(int responseCode, String response, YailList categories, String message) {
EventDispatcher.dispatchEvent(this, "GotCategories", responseCode, response, categories, message);
}
@SimpleEvent(description = "Got Channels")
public void GotChannels(int responseCode, YailList name, YailList website ,YailList logo, YailList urlStream, YailList category, String message) {
EventDispatcher.dispatchEvent(this, "GotChannels", responseCode, name, website, logo, urlStream, category, message);
}
@SimpleFunction(description = "Get Countries")
public void GetCountries() {
AsynchUtil.runAsynchronously(new Runnable() {
@Override
public void run() {
GetCountries_Exec();
}
});
}
@SimpleFunction(description = "Get Categories")
public void GetCategories() {
AsynchUtil.runAsynchronously(new Runnable() {
@Override
public void run() {
GetCategories_Exec();
}
});
}
@SimpleFunction(description = "Get Channels")
public void GetChannels(final String country, final String limit, final String name ) {
AsynchUtil.runAsynchronously(new Runnable() {
@Override
public void run() {
int limitInt;
try
{
limitInt = Integer.parseInt(limit);
}
catch
(Exception e)
{
limitInt = 1000;
}
GetChannels_Exec(country, limitInt, name);
}
});
}
public Iptv(ComponentContainer container) {
super(container.$form());
activity = container.$context();
cookieHandler = (SdkLevel.getLevel() >= SdkLevel.LEVEL_GINGERBREAD)
? GingerbreadUtil.newCookieManager()
: null;
}
void GetCountries_Exec() {
try
{
InputStream inputStream = null;
String URLStr = "https://iptv-org.github.io/api/countries.json";
URL url = new URL(URLStr);
httpConn = (HttpURLConnection) url.openConnection();
httpConn.setRequestMethod("GET");
httpConn.setRequestProperty("Connection", "Keep-Alive");
httpConn.setRequestProperty("User-Agent", "Android Multipart HTTP Client 1.0");
final int status = httpConn.getResponseCode();
List country = new ArrayList();
List countryCode = new ArrayList();
List language = new ArrayList();
String Msg = "";
if (status == HttpURLConnection.HTTP_OK)
{
inputStream = httpConn.getInputStream();
BufferedReader in = new BufferedReader(new InputStreamReader(httpConn.getInputStream()));
String inputLine;
final StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
final String responseStr = response.toString();
String ImportantValues = "";
String countryStr = "";
String countryCodeStr = "";
String languageStr = "";
if (responseStr.indexOf("name") != -1)
{
ImportantValues = responseStr;
while (ImportantValues.indexOf("name") != -1)
{
ImportantValues = ImportantValues.substring(ImportantValues.indexOf("name")+7);
countryStr = ImportantValues.substring(0,ImportantValues.indexOf("\""));
country.add(countryStr);
countryCodeStr = ImportantValues.substring(ImportantValues.indexOf("code")+7);
countryCodeStr = countryCodeStr.substring(0,countryCodeStr.indexOf("\""));
countryCode.add(countryCodeStr);
languageStr = ImportantValues.substring(ImportantValues.indexOf("lang")+7);
languageStr = languageStr.substring(0,languageStr.indexOf("\""));
language.add(languageStr);
}
}
else
{
if (responseStr.indexOf("message") != -1)
{
Msg = responseStr.substring(responseStr.indexOf("message")+10);
Msg = Msg.substring(0,Msg.indexOf("\""));
}
else
{
Msg = "No results found";
}
}
httpConn.disconnect();
final List countryFin = country;
final List countryCodeFin = countryCode;
final List languageFin = language;
final String Message = Msg;
// Dispatch the event.
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
GotCountries(status, responseStr , YailList.makeList(countryFin), YailList.makeList(countryCodeFin), YailList.makeList(languageFin), Message);
}
});
}
else
{
InputStream inputStreamErr = httpConn.getErrorStream();
BufferedReader in = new BufferedReader(new InputStreamReader(httpConn.getErrorStream()));
String inputLine;
final StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
final String responseStr = response.toString();
httpConn.disconnect();
// Dispatch the event.
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
GotCountries(status, responseStr , null, null, null, "");
}
});
}
}
catch (Exception e) {
e.printStackTrace();
StringWriter errors = new StringWriter();
e.printStackTrace(new PrintWriter(errors));
appendLog(errors.toString());
}
}
void GetCategories_Exec() {
try
{
InputStream inputStream = null;
String URLStr = "https://iptv-org.github.io/api/categories.json";
URL url = new URL(URLStr);
httpConn = (HttpURLConnection) url.openConnection();
httpConn.setRequestMethod("GET");
httpConn.setRequestProperty("Connection", "Keep-Alive");
httpConn.setRequestProperty("User-Agent", "Android Multipart HTTP Client 1.0");
final int status = httpConn.getResponseCode();
List categories = new ArrayList();
String Msg = "";
if (status == HttpURLConnection.HTTP_OK)
{
inputStream = httpConn.getInputStream();
BufferedReader in = new BufferedReader(new InputStreamReader(httpConn.getInputStream()));
String inputLine;
final StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
final String responseStr = response.toString();
String ImportantValues = "";
String categoriesStr = "";
if (responseStr.indexOf("name") != -1)
{
ImportantValues = responseStr;
while (ImportantValues.indexOf("name") != -1)
{
ImportantValues = ImportantValues.substring(ImportantValues.indexOf("name")+7);
categoriesStr = ImportantValues.substring(0,ImportantValues.indexOf("\""));
if (categoriesStr.indexOf("XXX") == -1)
{
categories.add(categoriesStr);
}
}
}
else
{
if (responseStr.indexOf("message") != -1)
{
Msg = responseStr.substring(responseStr.indexOf("message")+10);
Msg = Msg.substring(0,Msg.indexOf("\""));
}
else
{
Msg = "No results found";
}
}
httpConn.disconnect();
final List categoriesFin = categories;
final String Message = Msg;
// Dispatch the event.
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
GotCategories(status, responseStr , YailList.makeList(categoriesFin) , Message);
}
});
}
else
{
InputStream inputStreamErr = httpConn.getErrorStream();
BufferedReader in = new BufferedReader(new InputStreamReader(httpConn.getErrorStream()));
String inputLine;
final StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
final String responseStr = response.toString();
httpConn.disconnect();
// Dispatch the event.
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
GotCategories(status, responseStr , null, "");
}
});
}
}
catch (Exception e) {
e.printStackTrace();
StringWriter errors = new StringWriter();
e.printStackTrace(new PrintWriter(errors));
appendLog(errors.toString());
}
}
void GetChannels_Exec(String COUNTRY, int LIMIT, String NAME) {
String Channels = "";
try
{
InputStream inputStream = null;
String URLStr = "https://iptv-org.github.io/api/channels.json";
URL url = new URL(URLStr);
httpConn = (HttpURLConnection) url.openConnection();
httpConn.setRequestMethod("GET");
httpConn.setRequestProperty("Connection", "Keep-Alive");
httpConn.setRequestProperty("User-Agent", "Android Multipart HTTP Client 1.0");
final int status = httpConn.getResponseCode();
String Msg = "";
if (status == HttpURLConnection.HTTP_OK)
{
inputStream = httpConn.getInputStream();
BufferedReader in = new BufferedReader(new InputStreamReader(httpConn.getInputStream()));
String inputLine;
final StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
Channels = response.toString();
httpConn.disconnect();
}
}
catch (Exception e) {
e.printStackTrace();
StringWriter errors = new StringWriter();
e.printStackTrace(new PrintWriter(errors));
appendLog(errors.toString());
}
try
{
InputStream inputStream = null;
String URLStr = "https://iptv-org.github.io/api/streams.json";
URL url = new URL(URLStr);
httpConn = (HttpURLConnection) url.openConnection();
httpConn.setRequestMethod("GET");
httpConn.setRequestProperty("Connection", "Keep-Alive");
httpConn.setRequestProperty("User-Agent", "Android Multipart HTTP Client 1.0");
final int status = httpConn.getResponseCode();
List channelName = new ArrayList();
List website = new ArrayList();
List logo = new ArrayList();
List urlStream = new ArrayList();
List category = new ArrayList();
String Msg = "";
String ImportantValues = "";
String channelIdStr = "";
String urlStreamStr = "";
String statusStr = "";
String ChannelValues = "";
String CountryCode = "";
String CategoryChannel = "";
String ChannelNameStr = "";
String websiteStr = "";
String logoStr = "";
if (status == HttpURLConnection.HTTP_OK)
{
inputStream = httpConn.getInputStream();
BufferedReader in = new BufferedReader(new InputStreamReader(httpConn.getInputStream()));
String inputLine;
final StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
final String responseStr = response.toString();
if (responseStr.indexOf("channel") != -1)
{
ImportantValues = responseStr;
boolean ChannelLimit = true;
int ChannelFound = 0;
while ((ImportantValues.indexOf("channel") != -1) && (ChannelLimit == true))
{
ImportantValues = ImportantValues.substring(ImportantValues.indexOf("channel\"")+10);
channelIdStr = ImportantValues.substring(0,ImportantValues.indexOf("\""));
urlStreamStr = ImportantValues.substring(ImportantValues.indexOf("url")+6);
urlStreamStr = urlStreamStr.substring(0,urlStreamStr.indexOf("\""));
statusStr = ImportantValues.substring(ImportantValues.indexOf("status")+9);
statusStr = statusStr.substring(0,statusStr.indexOf("\""));
if (statusStr.equals("online") == true) // select only the channels online
{
if (Channels.indexOf(channelIdStr) != -1)
{
ChannelValues = Channels.substring(Channels.indexOf(channelIdStr));
CountryCode = ChannelValues.substring(ChannelValues.indexOf("country")+10);
CountryCode = CountryCode.substring(0,CountryCode.indexOf("\""));
if (CountryCode.equals(COUNTRY) == true)
{
CategoryChannel = ChannelValues.substring(ChannelValues.indexOf("categories")+12);
CategoryChannel = CategoryChannel.substring(0,CategoryChannel.indexOf("]")+1);
if (CategoryChannel.indexOf("xxx") == -1) // filter to remove the adult channels
{
if (CategoryChannel.indexOf("[]") != -1)
{
CategoryChannel = "Other";
}
else
{
CategoryChannel = CategoryChannel.substring(CategoryChannel.indexOf("[\"")+2);
CategoryChannel = CategoryChannel.substring(0, CategoryChannel.indexOf("\"]"));
}
ChannelNameStr = ChannelValues.substring(ChannelValues.indexOf("name")+7);
ChannelNameStr = ChannelNameStr.substring(0,ChannelNameStr.indexOf("\""));
if (NAME.length() > 0)
{
if (ChannelNameStr.indexOf(NAME) != -1)
{
channelName.add(ChannelNameStr);
category.add(CategoryChannel);
websiteStr = ChannelValues.substring(ChannelValues.indexOf("website")+10);
websiteStr = websiteStr.substring(0,websiteStr.indexOf("\""));
if (websiteStr.compareTo("ull,") == 0)
{
websiteStr = "unavailable";
}
website.add(websiteStr);
logoStr = ChannelValues.substring(ChannelValues.indexOf("logo")+7);
logoStr = logoStr.substring(0,logoStr.indexOf("\""));
if (logoStr.compareTo("ull,") == 0)
{
logoStr = "unavailable";
}
logo.add(logoStr);
urlStream.add(urlStreamStr);
if (LIMIT > 0)
{
ChannelFound = ChannelFound + 1;
if (ChannelFound == LIMIT)
{
ChannelLimit = false;
}
}
}
}
else
{
channelName.add(ChannelNameStr);
category.add(CategoryChannel);
websiteStr = ChannelValues.substring(ChannelValues.indexOf("website")+10);
websiteStr = websiteStr.substring(0,websiteStr.indexOf("\""));
if (websiteStr.compareTo("ull,") == 0)
{
websiteStr = "unavailable";
}
website.add(websiteStr);
logoStr = ChannelValues.substring(ChannelValues.indexOf("logo")+7);
logoStr = logoStr.substring(0,logoStr.indexOf("\""));
if (logoStr.compareTo("ull,") == 0)
{
logoStr = "unavailable";
}
logo.add(logoStr);
urlStream.add(urlStreamStr);
if (LIMIT > 0)
{
ChannelFound = ChannelFound + 1;
if (ChannelFound == LIMIT)
{
ChannelLimit = false;
}
}
}
}
}
}
}
}
}
else
{
if (responseStr.indexOf("message") != -1)
{
Msg = responseStr.substring(responseStr.indexOf("message")+10);
Msg = Msg.substring(0,Msg.indexOf("\""));
}
else
{
Msg = "No results found";
}
}
httpConn.disconnect();
final List channelNameFin = channelName;
final List websiteFin = website;
final List logoFin = logo;
final List urlStreamFin = urlStream;
final List categoryFin = category;
final String Message = Msg;
// Dispatch the event.
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
GotChannels(status, YailList.makeList(channelNameFin) , YailList.makeList(websiteFin), YailList.makeList(logoFin), YailList.makeList(urlStreamFin), YailList.makeList(categoryFin), Message);
}
});
}
else
{
InputStream inputStreamErr = httpConn.getErrorStream();
BufferedReader in = new BufferedReader(new InputStreamReader(httpConn.getErrorStream()));
String inputLine;
final StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
final String responseStr = response.toString();
httpConn.disconnect();
// Dispatch the event.
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
GotChannels(status, null, null, null, null, null, "");
}
});
}
}
catch (Exception e) {
e.printStackTrace();
StringWriter errors = new StringWriter();
e.printStackTrace(new PrintWriter(errors));
appendLog(errors.toString());
}
}
public void appendLog(String text)
{
File logFile = new File("sdcard/IptvLog.txt");
if (!logFile.exists())
{
try
{
logFile.createNewFile();
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
try
{
//BufferedWriter for performance, true to set append to file flag
BufferedWriter buf = new BufferedWriter(new FileWriter(logFile, true));
buf.append(text);
buf.newLine();
buf.flush();
buf.close();
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}