MasterPuppeteer

Updates to the new API.

......@@ -23,86 +23,112 @@ package tv.puppetmaster.usa
import org.json.JSONArray
import org.json.JSONObject
import org.jsoup.Jsoup
import org.jsoup.nodes.Document
import tv.puppetmaster.data.BasePuppetIterator
import tv.puppetmaster.data.i.*
import tv.puppetmaster.data.i.Puppet.PuppetIterator
import tv.puppetmaster.data.i.SourcesPuppet.SourceDescription
import java.util.concurrent.TimeUnit
import java.util.regex.Matcher
public class PopcornFlixPuppet implements InstallablePuppet {
class PopcornFlixPuppet implements InstallablePuppet {
static final int VERSION_CODE = 5
def ParentPuppet mParent
def String mUrl
def String mName
def String mDescription
def boolean mIsTopLevel
def String mImageUrl
static final DISPLAY_MAX_VIDEOS = 20
public PopcornFlixPuppet() {
ParentPuppet mParent
String mUrl
String mName
String mDescription
boolean mIsTopLevel
String mImageUrl
String mBackgroundImageUrl
PopcornFlixPuppet() {
this(
null,
"http://www.popcornflix.com",
"https://www.popcornflix.com",
"Popcorn Flix",
"Offers a broad collection of great movies you can watch right now.",
true,
"http://compass.xboxlive.com/assets/88/f9/88f9f3a7-51bf-4ad1-84aa-a4bf213abb45.jpg"
"http://compass.xboxlive.com/assets/88/f9/88f9f3a7-51bf-4ad1-84aa-a4bf213abb45.jpg",
"http://icdn2.digitaltrends.com/image/popcornflix-screen-1200x630-c.jpg"
)
}
public PopcornFlixPuppet(ParentPuppet parent, String url, String name, String description, boolean isTopLevel, String imageUrl) {
PopcornFlixPuppet(ParentPuppet parent, String url, String name, String description, boolean isTopLevel, String imageUrl, String backgroundImageUrl) {
mParent = parent
mUrl = url
mName = name
mDescription = description
mIsTopLevel = isTopLevel
mImageUrl = imageUrl
mBackgroundImageUrl = backgroundImageUrl
}
@Override
PuppetIterator getChildren() {
PuppetIterator children = new PopcornFlixPuppetIterator()
Document document = Jsoup.connect(mUrl).ignoreContentType(true).get()
document.select(".item-block ul li").each { node ->
String url = node.select("figure a").first().absUrl("href")
String name = node.select("figure figcaption").first().text()
String description = node.select(".film-data .film-data-desc").first().text()
long duration = -1
try {
duration = convertDuration(node.select(".film-data .duration").first().text() + ":00")
} catch (ignore) {
}
String imageUrl = node.select("figure a img").first().absUrl("src")
String backgroundImageUrl = "http://icdn2.digitaltrends.com/image/popcornflix-screen-1200x630-c.jpg"
if (url.contains("/tv-shows/")) {
children.add(new PopcornFlixPuppet(this, url, name, description, false, imageUrl))
} else {
String id = url.substring(url.lastIndexOf('/') + 1, url.length())
children.add(new PopcornFlixSourcesPuppet(this, id, name, description, duration, imageUrl, backgroundImageUrl))
}
}
PuppetIterator children = new BasePuppetIterator()
if (mParent == null) {
document.select(".item-block h2:first-child a").each { node ->
String url = node.absUrl("href")
String name = node.text().trim()
if (url.endsWith("/Pop%20Picks-movies")) {
url = url.replace("/Pop%20Picks-movies", "/most-popular-movies")
String html = new URL(mUrl).getText(requestProperties: [
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36',
]).replaceAll("\n", "")
Matcher matcher = html =~ /,\s*\{(.+?)\}\)\s*<\/script>/
if (!matcher.find()) {
return children
}
JSONObject json = new JSONObject("{${matcher.group(1)}}")
JSONArray items = json.getJSONObject('layout').getJSONArray('leftMenu')
for (int i = 0; i < items.length(); i++) {
JSONObject it = items.getJSONObject(i)
if (it.has('channels')) {
JSONArray channels = it.getJSONArray('channels')
for (int j = 0; j < channels.length(); j++) {
children.add(new PopcornFlixPuppet(
this,
"https://api.unreel.me/v1/videos/channel/${channels.getString(j).toLowerCase()}/0?__site=popcornflix&__source=web&max=${DISPLAY_MAX_VIDEOS}&videoSourceCombo=4",
channels.getString(j),
null,
true,
mImageUrl,
mBackgroundImageUrl
))
}
}
boolean isBrokenLink = name in ["Rock Stars", "Comedy", "Horror", "Urban", "Film School Originals"]
if (!isBrokenLink) {
children.add(new PopcornFlixPuppet(this, url, name, null, true, imageUrl))
}
} else {
JSONArray videos = new JSONObject(new URL(mUrl).getText()).getJSONArray('videos')
for (int i = 0; i < videos.length(); i++) {
JSONObject video = videos.getJSONObject(i)
JSONObject thumbnails = video.getJSONObject('metadata').getJSONObject('providerThumbnails')
children.add(
new PopcornFlixSourcesPuppet(
this,
video.getString('uid'),
video.getString('title'),
video.getString('description'),
video.getJSONObject('contentDetails').getLong('duration'),
thumbnails.has('default') ? thumbnails.getString('default') : mImageUrl,
thumbnails.has('standard') ? thumbnails.getString('standard') : mBackgroundImageUrl
)
)
}
if (videos.length() == DISPLAY_MAX_VIDEOS) {
Matcher matcher = mUrl =~ /.*\/(\d+)\\?.*/
if (matcher.find()) {
String index = matcher.group(1)
int nextIndex = index.toInteger() + DISPLAY_MAX_VIDEOS
children.add(new PopcornFlixPuppet(
this,
mUrl.replace("/${index}?", "/${nextIndex}?"),
'Next',
null,
false,
mImageUrl,
mBackgroundImageUrl
))
}
}
}
......@@ -136,7 +162,7 @@ public class PopcornFlixPuppet implements InstallablePuppet {
@Override
String getBackgroundImageUrl() {
return "http://icdn2.digitaltrends.com/image/popcornflix-screen-1200x630-c.jpg"
return mBackgroundImageUrl
}
@Override
......@@ -161,7 +187,7 @@ public class PopcornFlixPuppet implements InstallablePuppet {
@Override
SearchesPuppet getSearchProvider() {
return new PopcornFlixSearchesPuppet(this)
return null
}
@Override
......@@ -204,7 +230,7 @@ public class PopcornFlixPuppet implements InstallablePuppet {
}
@Override
public String toString() {
String toString() {
return mParent == null ? getName() : mParent.toString() + " < " + getName()
}
......@@ -213,94 +239,22 @@ public class PopcornFlixPuppet implements InstallablePuppet {
return VERSION_CODE
}
private static long convertDuration(String str) { // HH:MM[:SS] to milliseconds
if (str.equals("")) {
return -1
}
String[] data = str.split(":")
int time
if (data.length > 2) {
int hours = Integer.parseInt(data[0])
int minutes = Integer.parseInt(data[1])
int seconds = Integer.parseInt(data[2])
time = seconds + 60 * minutes + 3600 * hours
} else if (data.length > 1) {
int minutes = Integer.parseInt(data[0])
int seconds = Integer.parseInt(data[1])
time = seconds + 60 * minutes
} else {
int seconds = Integer.parseInt(data[0])
time = seconds
}
return TimeUnit.MILLISECONDS.convert(time, TimeUnit.SECONDS)
}
def static class PopcornFlixSearchesPuppet extends PopcornFlixPuppet implements SearchesPuppet {
def static final String SEARCH_URL = "http://www.popcornflix.com/search?query="
public PopcornFlixSearchesPuppet(ParentPuppet parent) {
super(
parent,
SEARCH_URL,
"Search",
"Search Popcorn Flix",
false,
"http://compass.xboxlive.com/assets/88/f9/88f9f3a7-51bf-4ad1-84aa-a4bf213abb45.jpg"
)
}
@Override
public void setSearchQuery(String searchQuery) {
setUrl(SEARCH_URL + searchQuery.replace(" ", "+"))
}
}
def class PopcornFlixPuppetIterator extends PuppetIterator {
def ArrayList<Puppet> mPuppets = new ArrayList<>()
def int currentIndex = 0
@Override
boolean hasNext() {
return currentIndex < mPuppets.size()
}
@Override
void add(Puppet puppet) {
mPuppets.add(puppet)
}
@Override
Puppet next() {
return mPuppets.get(currentIndex++)
}
@Override
void remove() {
}
}
def static class PopcornFlixSourcesPuppet implements SourcesPuppet {
def ParentPuppet mParent
def String mId
def String mName
def String mShortDescription
def long mDuration
def String mImageUrl
def String mBackgroundImageUrl
ParentPuppet mParent
String mId
String mName
String mShortDescription
long mDuration
String mImageUrl
String mBackgroundImageUrl
public PopcornFlixSourcesPuppet(parent, id, name, shortDescription, duration, imageUrl, backgroundImageUrl) {
PopcornFlixSourcesPuppet(parent, id, name, shortDescription, duration, imageUrl, backgroundImageUrl) {
mParent = parent
mId = id
mName = name
mShortDescription = shortDescription
mDuration = duration
mDuration = duration * 1000l
mImageUrl = imageUrl
mBackgroundImageUrl = backgroundImageUrl
}
......@@ -381,24 +335,27 @@ public class PopcornFlixPuppet implements InstallablePuppet {
}
@Override
public String toString() {
String toString() {
return mParent == null ? getName() : mParent.toString() + " < " + getName()
}
def class PopcornFlixSourceIterator implements SourcesPuppet.SourceIterator {
def List<SourceDescription> mSources
def int currentIndex = 0
List<SourceDescription> mSources
int currentIndex = 0
@Override
boolean hasNext() {
if (mSources == null) {
mSources = new ArrayList<SourceDescription>()
String json = new URL("http://popcornflixv2.device.screenmedia.net/api/videos/" + PopcornFlixSourcesPuppet.this.mId).getText(requestProperties: ['User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.95 Safari/537.11'])
JSONObject data = (JSONObject) ((JSONArray) new JSONObject(json).get("movies")).get(0)
JSONObject json = new JSONObject(new URL("https://api.unreel.me/v2/sites/popcornflix/videos/${mId}/play-url?__site=popcornflix&__source=web&protocol=https").getText(
requestProperties: [
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.95 Safari/537.11'
]
))
SourceDescription source = new SourceDescription()
source.url = ((JSONObject) data.get("urls")).get("Web v2 Player")
source.url = json.getString('url')
mSources.add(source)
}
return currentIndex < mSources.size()
......