Search page OK

This commit is contained in:
Michel Roux 2019-11-30 23:42:35 +01:00
parent 682aa72031
commit fbf42ece8e
7 changed files with 116 additions and 33 deletions

10
.env.dist Normal file
View File

@ -0,0 +1,10 @@
FLASK_APP=app.py
FLASK_ENV=development
FLASK_PORT=5000
MYSQL_USER=root
MYSQL_PASSWORD=root
MYSQL_DATABASE=www
MYSQL_SERVER=db
ADMIN_USERNAME=admin
ADMIN_PASSWORD=secret
MYSQL_ROOT_PASSWORD=root

1
.gitignore vendored
View File

@ -1,5 +1,6 @@
.idea/ .idea/
.venv/ .venv/
.db/ .db/
.env
__pycache__/ __pycache__/
test.py test.py

View File

@ -12,7 +12,7 @@ modules["MySQLdb"] = pymysql
db_user = environ.get('MYSQL_USER') db_user = environ.get('MYSQL_USER')
db_password = environ.get('MYSQL_PASSWORD') db_password = environ.get('MYSQL_PASSWORD')
db_name = environ.get('MYSQL_DATABASE') db_name = environ.get('MYSQL_DATABASE')
db_host = environ.get('MYSQL_HOST') db_host = environ.get('MYSQL_SERVER')
if not db_host or not db_user or not db_password or not db_name: if not db_host or not db_user or not db_password or not db_name:
print('Missing connection environment variables') print('Missing connection environment variables')
exit() exit()

View File

@ -9,12 +9,19 @@ from sys import platform
import requests import requests
from bs4 import BeautifulSoup from bs4 import BeautifulSoup
from models import AnimeLink
class ConnectorReturn(Enum): class ConnectorReturn(Enum):
SEARCH = 1 SEARCH = 1
HISTORY = 2 HISTORY = 2
class ConnectorLang(Enum):
FR = '🇫🇷'
JP = '🇯🇵'
class Connector(ABC): class Connector(ABC):
blacklist_words = ['Chris44', 'Vol.'] blacklist_words = ['Chris44', 'Vol.']
@ -90,9 +97,9 @@ class Connector(ABC):
@staticmethod @staticmethod
def get_lang(str_to_test): def get_lang(str_to_test):
if re.search('(vf|multi|french)', str_to_test, re.IGNORECASE): if re.search('(vf|multi|french)', str_to_test, re.IGNORECASE):
return 'fr' return ConnectorLang.FR
else: else:
return 'jp' return ConnectorLang.JP
def boldify(self, str_to_replace): def boldify(self, str_to_replace):
if self.query: if self.query:
@ -106,6 +113,7 @@ class Nyaa(Connector):
title = 'Nyaa' title = 'Nyaa'
favicon = 'nyaa.png' favicon = 'nyaa.png'
base_url = 'https://nyaa.si' base_url = 'https://nyaa.si'
is_light = False
def get_full_search_url(self): def get_full_search_url(self):
sort_type = 'size' sort_type = 'size'
@ -149,10 +157,11 @@ class Nyaa(Connector):
continue continue
valid_trs = valid_trs + 1 valid_trs = valid_trs + 1
href = '%s%s' % (self.base_url, url['href'])
self.data.append({ self.data.append({
'lang': self.get_lang(url.string), 'lang': self.get_lang(url.string),
'href': '%s%s' % (self.base_url, url['href']), 'href': href,
'name': self.boldify(url.string), 'name': self.boldify(url.string),
'comment': str(urls[0]).replace('/view/', 'comment': str(urls[0]).replace('/view/',
'%s%s' % (self.base_url, '/view/')) if has_comment else '', '%s%s' % (self.base_url, '/view/')) if has_comment else '',
@ -163,7 +172,8 @@ class Nyaa(Connector):
'seeds': check_seeds, 'seeds': check_seeds,
'leechs': tds[6].string, 'leechs': tds[6].string,
'downloads': check_downloads, 'downloads': check_downloads,
'class': 'is-%s' % tr['class'][0] 'class': self.color if AnimeLink.query.filter_by(link=href).first() else 'is-%s' %
tr['class'][0]
}) })
self.on_error = False self.on_error = False
@ -175,6 +185,7 @@ class Pantsu(Connector):
title = 'Pantsu' title = 'Pantsu'
favicon = 'pantsu.png' favicon = 'pantsu.png'
base_url = 'https://nyaa.net' base_url = 'https://nyaa.net'
is_light = False
def get_full_search_url(self): def get_full_search_url(self):
sort_type = 4 sort_type = 4
@ -211,10 +222,11 @@ class Pantsu(Connector):
continue continue
valid_trs = valid_trs + 1 valid_trs = valid_trs + 1
href = '%s%s' % (self.base_url, url['href'])
self.data.append({ self.data.append({
'lang': self.get_lang(url.string), 'lang': self.get_lang(url.string),
'href': '%s%s' % (self.base_url, url['href']), 'href': href,
'name': self.boldify(url.string), 'name': self.boldify(url.string),
'comment': '', 'comment': '',
'link': tds[2].decode_contents() 'link': tds[2].decode_contents()
@ -227,7 +239,8 @@ class Pantsu(Connector):
'seeds': check_seeds, 'seeds': check_seeds,
'leechs': tds[5].string, 'leechs': tds[5].string,
'downloads': check_downloads, 'downloads': check_downloads,
'class': 'is-%s' % tr['class'][0] 'class': self.color if AnimeLink.query.filter_by(link=href).first() else 'is-%s' %
tr['class'][0]
}) })
self.on_error = False self.on_error = False
@ -239,6 +252,7 @@ class YggTorrent(Connector):
title = 'YggTorrent' title = 'YggTorrent'
favicon = 'yggtorrent.png' favicon = 'yggtorrent.png'
base_url = 'https://www2.yggtorrent.pe' base_url = 'https://www2.yggtorrent.pe'
is_light = False
def get_full_search_url(self): def get_full_search_url(self):
sort_type = 'size' sort_type = 'size'
@ -291,7 +305,7 @@ class YggTorrent(Connector):
'seeds': check_seeds, 'seeds': check_seeds,
'leechs': tds[8].string, 'leechs': tds[8].string,
'downloads': check_downloads, 'downloads': check_downloads,
'class': '' 'class': self.color if AnimeLink.query.filter_by(link=url['href']).first() else ''
}) })
self.on_error = False self.on_error = False
@ -303,6 +317,7 @@ class AnimeUltime(Connector):
title = 'Anime-Ultime' title = 'Anime-Ultime'
favicon = 'animeultime.png' favicon = 'animeultime.png'
base_url = 'http://www.anime-ultime.net' base_url = 'http://www.anime-ultime.net'
is_light = True
def get_full_search_url(self): def get_full_search_url(self):
from_date = '' from_date = ''
@ -336,23 +351,27 @@ class AnimeUltime(Connector):
continue continue
url = tds[0].a url = tds[0].a
href = '%s/%s' % (self.base_url, url['href'])
self.data.append({ self.data.append({
'lang': 'jp', 'lang': ConnectorLang.JP,
'href': '%s/%s' % (self.base_url, url['href']), 'href': '%s/%s' % (self.base_url, url['href']),
'name': url.decode_contents(), 'name': url.decode_contents(),
'type': tds[1].string 'type': tds[1].string,
'class': self.color if AnimeLink.query.filter_by(link=href).first() else ''
}) })
else: else:
player = html.select('div.AUVideoPlayer') player = html.select('div.AUVideoPlayer')
name = html.select('h1') name = html.select('h1')
ani_type = html.select('div.titre') ani_type = html.select('div.titre')
href = '%s/file-0-1/%s' % (self.base_url, player[0]['data-serie'])
self.data.append({ self.data.append({
'lang': 'jp', 'lang': ConnectorLang.JP,
'href': '%s/file-0-1/%s' % (self.base_url, player[0]['data-serie']), 'href': '%s/file-0-1/%s' % (self.base_url, player[0]['data-serie']),
'name': self.boldify(name[0].string), 'name': self.boldify(name[0].string),
'type': ani_type[0].string.replace(':', '') 'type': ani_type[0].string.replace(':', ''),
'class': self.color if AnimeLink.query.filter_by(link=href).first() else ''
}) })
self.on_error = False self.on_error = False
@ -378,13 +397,15 @@ class AnimeUltime(Connector):
locale.setlocale(locale.LC_ALL, ('fr_FR', 'UTF-8')) locale.setlocale(locale.LC_ALL, ('fr_FR', 'UTF-8'))
release_date = datetime.strptime(h3s[i].string, '%A %d %B %Y : ').strftime('%Y-%m-%d %H:%M:%S') release_date = datetime.strptime(h3s[i].string, '%A %d %B %Y : ').strftime('%Y-%m-%d %H:%M:%S')
locale.setlocale(locale.LC_ALL, current_locale) locale.setlocale(locale.LC_ALL, current_locale)
href = '%s/%s' % (self.base_url, link['href'])
self.data.append({ self.data.append({
'lang': 'jp', 'lang': ConnectorLang.JP,
'href': '%s/%s' % (self.base_url, link['href']), 'href': '%s/%s' % (self.base_url, link['href']),
'name': link.string, 'name': link.string,
'type': tds[4].string, 'type': tds[4].string,
'date': release_date 'date': release_date,
'class': self.color if AnimeLink.query.filter_by(link=href).first() else ''
}) })
self.on_error = False self.on_error = False
@ -394,6 +415,7 @@ class Other(Connector):
color = 'is-danger' color = 'is-danger'
title = 'Other' title = 'Other'
favicon = 'blank.png' favicon = 'blank.png'
is_light = True
def get_full_search_url(self): def get_full_search_url(self):
pass pass

View File

@ -7,16 +7,9 @@ services:
- "5000:5000" - "5000:5000"
entrypoint: python3 app.py entrypoint: python3 app.py
working_dir: /app working_dir: /app
environment: env_file:
FLASK_APP: app.py - .env.dist
FLASK_ENV: development - .env
FLASK_PORT: 5000
MYSQL_USER: root
MYSQL_PASSWORD: root
MYSQL_DATABASE: www
MYSQL_HOST: db
ADMIN_USERNAME: admin
ADMIN_PASSWORD: secret
volumes: volumes:
- .:/app - .:/app
@ -24,8 +17,8 @@ services:
image: mariadb image: mariadb
ports: ports:
- "3306:3306" - "3306:3306"
environment: env_file:
MYSQL_ROOT_PASSWORD: root - .env.dist
MYSQL_DATABASE: www - .env
volumes: volumes:
- ./.db:/var/lib/mysql - ./.db:/var/lib/mysql

View File

@ -8,16 +8,15 @@ from config import db
class AnimeFolder(db.Model): class AnimeFolder(db.Model):
id = db.Column(db.Integer, primary_key=True) id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.Text, unique=True, nullable=False) name = db.Column(db.Text, unique=True, nullable=False)
titles = db.relationship("AnimeTitle", back_populates="folder") titles = db.relationship("AnimeTitle", backref="folder")
class AnimeTitle(db.Model): class AnimeTitle(db.Model):
id = db.Column(db.Integer, primary_key=True) id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.Text, unique=True, nullable=False) name = db.Column(db.Text, unique=True, nullable=False)
keyword = db.Column(db.Text, nullable=False) keyword = db.Column(db.Text, nullable=False)
folder_id = db.Column(db.Integer, db.ForeignKey('folder.id')) folder_id = db.Column(db.Integer, db.ForeignKey('anime_folder.id'))
folder = db.relationship('AnimeFolder', back_populates="titles") links = db.relationship('AnimeLink', backref="title")
links = db.relationship('AnimeLink', back_populates="title")
class AnimeLink(db.Model): class AnimeLink(db.Model):
@ -26,9 +25,11 @@ class AnimeLink(db.Model):
season = db.Column(db.Text, nullable=False) season = db.Column(db.Text, nullable=False)
comment = db.Column(db.Text) comment = db.Column(db.Text)
vf = db.Column(db.Boolean, nullable=False) vf = db.Column(db.Boolean, nullable=False)
title_id = db.Column(db.Integer, db.ForeignKey('title.id')) title_id = db.Column(db.Integer, db.ForeignKey('anime_title.id'))
title = db.relationship('AnimeTitle', back_populates="links")
class SearchForm(FlaskForm): class SearchForm(FlaskForm):
q = SearchField('search', validators=[DataRequired]) q = SearchField('search', validators=[DataRequired])
db.create_all()

View File

@ -26,8 +26,64 @@
{% for connector in connectors %} {% for connector in connectors %}
{% for torrent in connector.data %} {% for torrent in connector.data %}
{% if not loop.index0 %}
<th colspan="8">{{ connector.title }}</th>
{% endif %}
<tr class="{{ torrent.class }}">
<td>
{{ torrent.lang.value }}
<a href="{{ torrent.href }}" target="_blank">
{{ torrent.name|safe }}
</a>
</td>
{% if connector.is_light %}
<td colspan="7">
{{ torrent.type }}
</td>
{% else %}
<td>
{{ torrent.comment|safe }}
</td>
<td>
{{ torrent.link|safe }}
</td>
<td>
{{ torrent.size }}
</td>
<td>
{{ torrent.date }}
</td>
<td>
{{ torrent.seeds }}
</td>
<td>
{{ torrent.leechs }}
</td>
<td>
{{ torrent.downloads }}
</td>
{% endif %}
</tr>
{% endfor %} {% endfor %}
{% if connector.is_more %}
<tr>
<th colspan="8">
<a href="{{ connector.get_full_search_url() }}" target="_blank">More ...</a>
</th>
</tr>
{% endif %}
{% if connector.on_error %}
<tr class="is-danger">
<th colspan="8" class="error">
Error, can't grab data from {{ connector.title }}
<a href="{{ connector.get_full_search_url() }}" target="_blank">Go to the website -></a>
</th>
</tr>
{% endif %}
{% endfor %} {% endfor %}
</tbody> </tbody>