Search page OK
This commit is contained in:
parent
682aa72031
commit
fbf42ece8e
10
.env.dist
Normal file
10
.env.dist
Normal 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
1
.gitignore
vendored
@ -1,5 +1,6 @@
|
|||||||
.idea/
|
.idea/
|
||||||
.venv/
|
.venv/
|
||||||
.db/
|
.db/
|
||||||
|
.env
|
||||||
__pycache__/
|
__pycache__/
|
||||||
test.py
|
test.py
|
||||||
|
@ -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()
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
13
models.py
13
models.py
@ -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()
|
||||||
|
@ -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>
|
||||||
|
Reference in New Issue
Block a user