Skip to content

Instantly share code, notes, and snippets.

@imayhaveborkedit
Last active September 11, 2015 05:40
Show Gist options
  • Save imayhaveborkedit/55ff40ff06018236a108 to your computer and use it in GitHub Desktop.
Save imayhaveborkedit/55ff40ff06018236a108 to your computer and use it in GitHub Desktop.
Silly anime watching assistant
import sys, inspect, re
import requests, webbrowser
from BeautifulSoup import BeautifulSoup
USER_AGENT_HEADER = {'User-agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:34.0) Gecko/20100101 Firefox/34.0.1'}
class Anime(object):
baseurl = ''
_total_episodes = -1
_video_cache = {}
def __init__(self, url):
raise NotImplementedError
self.anime_name = ''
self.info_page = ''
self.start_ep = 1
self.current_ep = 1
def get_total_episodes(self):
raise NotImplementedError
if self._total_episodes < 0:
pass
return self._total_episodes
def get_episode(self, episode):
return
def get_video_link(self, episode):
if episode in self._video_cache:
return self._video_cache[episode]
def pop_episode(self):
if self.reached_end(): return
elif self.current_ep == self.get_total_episodes():
self.current_ep = -1
return self.get_episode(self.get_total_episodes())
else:
self.current_ep += 1
return self.get_episode(self.current_ep-1)
def cache_video_link(self, episode):
self._video_cache[episode] = self.get_video_link(episode)
def reached_end(self):
return self.current_ep == -1
def goto(self, ep):
self.current_ep = int(ep)
class GogoAnime(Anime):
baseurl = 'http://gogoanime.tv/'
def __init__(self, url):
if not url.startswith(self.baseurl):
raise NameError("Wrong class idiot")
print url
if '.tv/category/' in url:
self.anime_name = url.split('/')[-1]
self.start_ep = 1
self.info_page = url
elif '-episode-' in url:
self.anime_name = '-'.join(url.split('/')[-1].split('-')[:-2])
self.start_ep = int(url.split('/')[-1].split('-')[-1])
self.info_page = self.baseurl + 'category/' + self.anime_name
else:
raise AttributeError("What the fuck is up with this: " + url)
self.current_ep = self.start_ep
def get_total_episodes(self):
if self._total_episodes < 0:
data = BeautifulSoup(requests.get(self.info_page).text)
eps = data.body.find('ul', attrs={'id':'episode_page'})
self._total_episodes = int(eps()[-1].string.split('-')[-1])
return self._total_episodes
def get_episode(self, episode):
if episode > self.get_total_episodes(): raise IndexError
return self.baseurl + self.anime_name + '-episode-%s' % int(episode)
def get_video_link(self, episode):
super(self.__class__, self).get_video_link(episode)
data = BeautifulSoup(requests.get(self.get_episode(episode)).text)
udata = data.body.find('select', attrs={'id':'selectQuality'})
odata = udata.findChildren()[-1]
print 'Using quality ' + odata.string
return str(odata.get('value'))
class AnimeJoy(Anime):
baseurl = 'http://animejoy.tv/watch/'
def __init__(self, url):
if not url.startswith(self.baseurl):
raise NameError("Wrong class idiot")
surl = url.split('/')
self.anime_name = surl[4]
self.info_page = '/'.join(surl[:5])
self.current_ep = self.start_ep = int(surl[5]) if len(surl) == 6 else 1
def get_total_episodes(self):
if self._total_episodes < 0:
data = BeautifulSoup(requests.get(self.info_page).text)
eps = data.body.find('div', attrs={'class':'episodes'})
self._total_episodes = int(eps('a')[0]['href'].split('/')[-1])
return self._total_episodes
def get_episode(self, episode):
if episode > self.get_total_episodes(): raise IndexError
return self.baseurl + self.anime_name + '/%s' % int(episode)
def get_video_link(self, episode):
super(self.__class__, self).get_video_link(episode)
data = BeautifulSoup(requests.get(self.get_episode(episode)).text)
odata = data.body.find('source')['src']
return str(odata)
class AnimeShowTv(Anime):
baseurl = 'http://animeshow.tv/'
_mirror_prioritys = ['MP4UPLOAD HD', 'MP4UPLOAD', 'MP4VIDS', 'AUENGINE', 'RAW']
_mirror_video_reg = {
'auengine':
"file: \s*'(.*?\.mp4)',\s*?label:\s*'720p'",
'mp4upload':
"url:\s*'(.*\.mp4)\?",
'mp4vids':
"file:\s*'(.*?\.mp4)'",
}
def __init__(self, url):
if not url.startswith(self.baseurl):
raise NameError("Wrong class idiot")
surl = url.split('/')
durl = surl[3]
if '-episode-' in url:
self.anime_name = durl.split('-episode-')[0]
self.info_page = url.split('-episode-')[0] + '/'
else:
self.anime_name = url.split('/')[3]
self.info_page = url if url.endswith('/') else url + '/'
if '-mirror-' in durl:
self.current_ep = self.start_ep = int(durl.split('-mirror-')[1].strip('/'))
elif '-episode-' in durl:
self.current_ep = self.start_ep = int(durl.split('-episode-')[1].strip('/'))
else:
self.current_ep = self.start_ep = 1
if '-mirror-' in durl:
self._mirror = int(durl.split('-mirror-')[1])
else:
self._mirror = 0
data = BeautifulSoup(requests.get(self.get_episode(self.current_ep, self._mirror)).text)
self._mirrortype = str(data.body.find('a', attrs={'class':'mirror-active'}).string)
def get_total_episodes(self):
if self._total_episodes < 0:
data = BeautifulSoup(requests.get(self.info_page).text)
eps = data.body.find('table', attrs={'id':'episode-list-entry-tbl'})
self._total_episodes = int(eps('tr')[0].td.a['href'].split('-')[-1].strip('/'))
return self._total_episodes
def get_episode(self, episode, urlmirror=0):
if episode > self.get_total_episodes(): raise IndexError
aurl = self.baseurl + self.anime_name + '-episode-%s' % int(episode)
if urlmirror:
res = requests.head(aurl+'-mirror-'+str(urlmirror)+'/')
res.raise_for_status()
aurl += '-mirror-' + str(urlmirror)
else: # This is where I pick the best mirror right?
pass
return aurl + '/'
def get_video_link(self, episode, mirror=-1):
super(self.__class__, self).get_video_link(episode)
if mirror == -1:
mirror = self._mirror
data = BeautifulSoup(requests.get(self.get_episode(episode, mirror)).text)
odata = data.body.find('div', attrs={'id':'embbed-video'}).iframe['src']
data2 = BeautifulSoup(requests.get(str(odata), headers=USER_AGENT_HEADER).text)
mirrortype = str(odata).strip('http://').strip('www.').split('.')[0]
try:
return re.search(self._mirror_video_reg[mirrortype], str(data2.text)).groups()[0]
except:
if not hasattr(self, '_other_mirrors'):
self._other_mirrors = self._get_other_mirrors(mirror)
else:
if mirror in self._other_mirrors: self._other_mirrors.pop(mirror)
if not self._other_mirrors:
raise RuntimeError("No available mirrors")
while self._other_mirrors:
for m in self._other_mirrors:
next_mirror = self._other_mirrors.get(m)
if next_mirror is not None:
break
print 'Mirror %s (%s) failed, trying mirror %s (%s)' % (mirror, mirrortype, m, next_mirror[0].lower())
d = self.get_video_link(episode, m)
del self._other_mirrors
return d
def _get_other_mirrors(self, mirror):
data = BeautifulSoup(requests.get(self.get_episode(self.current_ep, mirror)).text)
mirs = data.body.findAll('a', attrs={'class':'mirror'})
return {mirs.index(t)+1:(t.string, str(t['href'])) for t in mirs}
def get_class_dict():
classes = inspect.getmembers(sys.modules[__name__],
lambda m: inspect.isclass(m) and issubclass(m, Anime) and m != Anime)
return {y.baseurl:y for x,y in classes}
def lazy(url):
cd = get_class_dict()
url = url.replace('http://www.', 'http://')
for path in cd:
if url.startswith(path):
return cd[path]
import time, itertools, webbrowser
import pyperclip
import anime
if __name__ == '__main__':
print 'Supported anime websites:'
for a in anime.get_class_dict():
print ' ' + a
print
print 'Copy a valid video url to the clipboard and press enter.\n'
s = itertools.cycle('|/-\\|\\-/')
waited = False
while True:
cbtext = pyperclip.paste()
if cbtext and anime.lazy(cbtext):
print 'Valid url: %s\n' % cbtext
if waited: raw_input('Press enter to begin\n')
break
else:
print '\rWaiting for valid url %s\r' % s.next(),
waited = True
time.sleep(0.5)
CorrectAnime = anime.lazy(cbtext)
a = CorrectAnime(cbtext)
print 'Starting at episode %s/%s' % (a.current_ep, a.get_total_episodes())
for ae in range(a.current_ep, a.get_total_episodes()+1):
webbrowser.open_new_tab(a.get_video_link(ae))
a.pop_episode()
print 'Caching next video link...',
a.cache_video_link(a.current_ep)
print 'Done.\n'
if a.reached_end():
print 'You have reached the end of the available episodes.'
break
raw_input('Press enter to open episode %s/%s' % (ae + 1, a.get_total_episodes()))
print
@akumasenpai
Copy link

Rad thnx for this! I just wrote an animejoy py script that allows search and episode selection check it out you might like it

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment