-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdefault.py
235 lines (195 loc) · 9.19 KB
/
default.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
import xbmcplugin,xbmcgui,xbmcaddon
import os,urllib2,re,urlparse
from cgi import parse_qs
from BeautifulSoup import BeautifulSoup, BeautifulStoneSoup
__addonName__ = "Penny Arcade TV"
__addonID__ = "plugin.video.pennyarcadetv"
__addon__ = xbmcaddon.Addon(__addonID__)
__strings__ = __addon__.getLocalizedString
__version__ = __addon__.getAddonInfo("version")
__dbg__ = __addon__.getSetting("debug") == "true"
__latestInSub__ = __addon__.getSetting("latestInSub") == "true"
__baseURL__ = "http://www.penny-arcade.com"
def log(msg):
if(__dbg__):
print "[PLUGIN] '%s (%s)' " % (__addonName__, __version__) + str(msg)
log("Parameters: " + str(sys.argv))
pluginPath = sys.argv[0]
pluginHandle = int(sys.argv[1])
pluginQuery = sys.argv[2]
def getHeaders(referrer):
headers = {}
headers["User-Agent"] = "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3"
if referrer:
headers["Referrer"] = referrer
return headers
def getHTML(forURL, withPOSTData=None, withReferrer=__baseURL__):
log("Get HTML for URL: " + forURL)
req = urllib2.Request(forURL, withPOSTData, getHeaders(withReferrer))
response = urllib2.urlopen(req)
data = response.read()
response.close()
return data
def getRedirectURL(forURL, withReferrer=None):
log("Get redirect for URL: " + forURL)
req = urllib2.Request(forURL, None, getHeaders(withReferrer))
return urllib2.urlopen(req).url
def listShowsAndLatest(showOnlyLatest):
#Note: not sure if using set content is worth the effort since there isn"t much
#metadata available for these episodes other than title and image
#xbmcplugin.setContent(pluginHandle, "tvshows")
showsPage = BeautifulSoup(getHTML(forURL=__baseURL__ + "/patv"), convertEntities=BeautifulSoup.HTML_ENTITIES)
titleRegex = re.compile("Season (?P<s>[0-9]): Episode (?P<ep>[0-9]+) - (?P<title>.+)")
onlyNumberRegex = re.compile("Season (?P<s>[0-9]): Episode (?P<ep>[0-9]+)")
#Parse the current ep and show links from the root page
infoDivs = showsPage.findAll("div",attrs={"class":"info"})
foundShows = []
foundEps = []
#Get a list of found shows and current episodes
for div in infoDivs:
try:
links = div.findAll("a")
if links[0]["title"] == "Watch Now":
ep = {}
#Show title
ep["title"] = links[1]["title"]
#Episode title
titleParts = titleRegex.match(links[2]["title"]) or onlyNumberRegex.match(links[2]["title"])
if(titleParts is not None):
titleParts = titleParts.groupdict()
ep["title"] += " - %sx%s" % (titleParts["s"], titleParts["ep"])
if "title" in titleParts:
ep["title"] += " - " + titleParts["title"]
else:
#Fallback if title isn't an expected format...
ep["title"] = links[2]["title"]
#Image and url
ep["imgurl"] = __baseURL__ + div.parent.img["src"]
ep["url"] = __baseURL__ + links[0]["href"]
foundEps.append(ep)
else:
#Todo - Get show infos to add as some info label? Doesn"t seem to be a good view
#that shows the info without having other fields left empty..
show = {}
show["title"] = links[0]["title"]
show["imgurl"] = __baseURL__ + div.parent.a.img["src"]
show["url"] = __baseURL__ + links[0]["href"]
foundShows.append(show)
except:
log("Issue with parsing show or ep div.")
log(div)
continue
#Add the found shows
if not __latestInSub__ or (__latestInSub__ and not showOnlyLatest) :
for show in foundShows:
li = xbmcgui.ListItem(show["title"], iconImage=show["imgurl"], thumbnailImage=show["imgurl"])
li.setInfo(type="video", infoLabels={"Title": show["title"]})
xbmcplugin.addDirectoryItem(
handle=pluginHandle,
isFolder=True,
url=pluginPath + "?action=listshowepisodes&url=" + show["url"],
listitem=li)
#Add latest directory if necessary
if __latestInSub__ and not showOnlyLatest :
xbmcplugin.addDirectoryItem(
handle=pluginHandle,
isFolder=True,
url=pluginPath + "?action=listlatestepisodes",
listitem=xbmcgui.ListItem(__strings__(30051)))
#Add latest episodes if necessary
if not __latestInSub__ or showOnlyLatest :
for ep in foundEps:
li = xbmcgui.ListItem(ep["title"], thumbnailImage=ep["imgurl"])
li.setProperty("IsPlayable", "true")
xbmcplugin.addDirectoryItem(
handle=pluginHandle,
url=pluginPath + "?action=playvideo&url=" + ep["url"],
listitem=li)
xbmcplugin.endOfDirectory(pluginHandle)
def addEpisodeItem(name, url, img):
li = xbmcgui.ListItem(name, iconImage=img, thumbnailImage=img)
li.setInfo(type="video", infoLabels={"Title": name})
li.setProperty("IsPlayable","true")
xbmcplugin.addDirectoryItem(
handle=pluginHandle,
url=pluginPath + "?action=playvideo&url=" + url,
listitem=li)
def listShowEpisodes(url):
#TODO - not sure if using set content is worth the effort since there isn"t much
#metadata available for these episodes other than title and image
#xbmcplugin.setContent(pluginHandle, "episodes")
urlRegex = re.compile("/.*/.*/(.*?)/")
episodesPage = BeautifulSoup(getHTML(forURL=url), convertEntities=BeautifulSoup.HTML_ENTITIES)
epLists = episodesPage.findAll(attrs={"class" : "episodes"})
if not epLists:
epLists = episodesPage.findAll(attrs={"id" : "episodes"})
#passing counter into format ep name for non number episodes
seasonCounter = len(epLists)
for epList in epLists:
for ep in epList.findAll("li"):
aTags = ep.findAll("a")
img = __baseURL__ + ep.img["src"]
url = __baseURL__ + aTags[0]["href"]
name = formatEpName(aTags[0]["href"], aTags[1].contents[2], urlRegex, seasonCounter)
addEpisodeItem(name, url, img)
seasonCounter -= 1
xbmcplugin.endOfDirectory(pluginHandle)
def formatEpName(url, epName, urlRegex, seasonCt):
#for urls that don"t have trailing / so they will work with regex
if url[-1] != "/":
url += "/"
#some eps in penny arcade series have non-number episodes
epPart = urlRegex.match(url).groups()[0]
try:
test = int(epPart)
finalName = epPart[0] + "x" + epPart[1:] + " - "
except:
finalName = "%sx00 - " % (seasonCt)
idx = epName.find(":")
if idx != -1:
finalName += epName[idx+2:]
else:
finalName += epName
return finalName
def playVideo(url):
#Start at video page http://www.penny-arcade.com/patv/[show]/[episode]
#Get the embed tag on the video page as the first step to get the final url
videoPage = BeautifulSoup(getHTML(forURL=url))
#Assuming a single embed tag works for now
embedUrl = videoPage("embed")[0]["src"]
#embedUrl redirects to another Url that has a QS param for a Url to the rss file for this specific video
#4 is to get the query portion of the final url, not sure why the named attribute doesn"t work..
redirectUrl = urlparse.urlparse(getRedirectURL(forURL=embedUrl))
redirectQS = parse_qs(redirectUrl[4])
rssFileUrl = redirectQS["file"][0]
rssFile = BeautifulStoneSoup(getHTML(forURL=rssFileUrl))
#assuming first is default, if not true for all will need to alter this.
mediaTags = rssFile("media:content")
#todo - should probably add a default choice, need to be sure what's all available first
choices = []
for mTag in mediaTags:
size = float(mTag["filesize"]) / (1024*1024)
choices.append("%s (%sx%s) (%.2f MB)" % (mTag["blip:role"],mTag["width"],mTag["height"], size))
selected = xbmcgui.Dialog().select(__strings__(30052), choices)
#todo - should figure out how to gracefully not play something if they back out of
#selection
if selected == -1:
selected = 0
finalVideoUrl = mediaTags[selected]["url"]
#set the final url as the resolved url
resolvedItem = xbmcgui.ListItem(path=finalVideoUrl)
xbmcplugin.setResolvedUrl(pluginHandle, True, resolvedItem)
#Set default action
action="listshowsandlatest"
#Parse parameters, slicing to remove leading ?
params = parse_qs(pluginQuery[1:])
if len(params) > 0:
action = params["action"][0]
if action == "listshowsandlatest":
listShowsAndLatest(showOnlyLatest=False)
elif action == "listlatestepisodes":
listShowsAndLatest(showOnlyLatest=True)
elif action == "listshowepisodes":
listShowEpisodes(params["url"][0])
elif action == "playvideo":
playVideo(params["url"][0])