Compare commits

...

16 Commits
dev ... master

Author SHA1 Message Date
vincent
545bb6d783 CI: switch to vault secret
Some checks reported errors
continuous-integration/drone/push Build was killed
2022-12-04 09:56:14 +01:00
vincent
72d3de7707 dwitch gunicorn worker to 2
All checks were successful
continuous-integration/drone/push Build is passing
2022-05-19 19:55:50 +02:00
vincent
22f5d0f350 enable drone arm build
All checks were successful
continuous-integration/drone Build is passing
2022-05-15 21:15:25 +02:00
vincent
ec898f7a27 fix chown
All checks were successful
continuous-integration/drone/push Build is passing
2022-05-15 20:56:01 +02:00
vincent
fe35beb47f add parsechaine to start
Some checks failed
continuous-integration/drone/push Build is failing
2022-05-15 20:53:30 +02:00
vincent
b22a4dae41 change right in dockerfile 2022-05-15 20:49:57 +02:00
vincent
69f5539910 switch build on python 3.9
All checks were successful
continuous-integration/drone Build is passing
2022-05-10 13:41:33 +02:00
vincent
bb148ce6f7 fix CI docker manifest
All checks were successful
continuous-integration/drone Build is passing
2022-05-10 11:20:00 +02:00
vincent
c7d89b1c11 comment arm build
All checks were successful
continuous-integration/drone Build is passing
2022-05-10 11:09:52 +02:00
vincent
a449dc0ab0 add drone file
Some checks reported errors
continuous-integration/drone Build was killed
2022-05-10 10:38:59 +02:00
vincent
fe66948742 add docker file 2022-05-10 10:11:02 +02:00
vincent
d62b16df39 switch to requests API for emission 2022-01-30 21:46:21 +01:00
vincent
db7890ff4b update requirement 2022-01-30 15:52:08 +01:00
vincent
4787a36d0e fix parsing issue 2021-05-13 13:30:23 +02:00
vincent
f18dd28614 update requirement 2021-02-16 19:18:57 +01:00
vincent
e58639bbc8 recrap programmeTV 2021-02-16 18:54:06 +01:00
8 changed files with 169 additions and 53 deletions

71
.drone.yml Normal file
View File

@ -0,0 +1,71 @@
---
kind: pipeline
name: build_amd64
platform:
os: linux
arch: amd64
steps:
- name: docker
image: plugins/docker
settings:
repo: ducampsv/chainetv
auto_tag: "true"
auto_tag_suffix: amd64
username:
from_secret: docker_username
password:
from_secret: docker_password
---
kind: pipeline
name: build_arm
platform:
os: linux
arch: arm
steps:
- name: docker
image: plugins/docker
settings:
repo: ducampsv/chainetv
auto_tag: "true"
auto_tag_suffix: arm
username:
from_secret: docker_username
password:
from_secret: docker_password
---
kind: pipeline
type: docker
name: manifest
steps:
- name: manifest
image: plugins/manifest
settings:
auto_tag: "true"
target: ducampsv/chainetv:latest
template: ducampsv/chainetv:ARCH
username:
from_secret: docker_username
password:
from_secret: docker_password
platforms:
- linux/amd64
- linux/arm
depends_on:
- build_amd64
- build_arm
---
kind: secret
name: docker_username
get:
path: secrets/data/droneci/dockerHub
name: username
---
kind: secret
name: docker_password
get:
path: secrets/data/droneci/dockerHub
name: password

23
Dockerfile Normal file
View File

@ -0,0 +1,23 @@
FROM python:3.9-alpine as Build
COPY backend/ /pkg/backend
RUN apk -U --no-progress upgrade && \
apk --no-progress add gcc musl-dev && \
pip install -r /pkg/backend/requirements.txt && \
mv "/usr/local" "/pkg/usr" && \
adduser -S -D -H -h /var/lib/chaineTV -s /sbin/nologin -G users -g chaineTV chaineTV && \
chown chaineTV /pkg/backend -R && \
install -d -m755 "/pkg/etc" && \
install -m644 "/etc/passwd" "/pkg/etc/passwd" &&\
install -m644 "/etc/group" "/pkg/etc/group" &&\
install -m640 -gshadow "/etc/shadow" "/pkg/etc/shadow"
FROM alpine
COPY --from=Build /pkg /
RUN apk -U --no-progress upgrade && \
apk --no-progress add py3-gunicorn
USER chaineTV
EXPOSE 5000
WORKDIR /backend
CMD /usr/bin/gunicorn --workers=2 -b :5000 run:app

6
Makefile Normal file
View File

@ -0,0 +1,6 @@
DOCKER_ORGANIZATION := ducampsv
DOCKER_IMAGE := chainetv
DOCKER_TAG ?= base
docker-build:
docker buildx build -t $(DOCKER_ORGANIZATION)/$(DOCKER_IMAGE):$(DOCKER_TAG) .

View File

@ -7,6 +7,7 @@ from datetime import datetime, timedelta
from .user import User from .user import User
data= JSONfile("chaine.json") data= JSONfile("chaine.json")
data.parsechaine()
emmission= Emmission() emmission= Emmission()
def token_required(f): def token_required(f):

View File

@ -1,73 +1,84 @@
from bs4 import BeautifulSoup from bs4 import BeautifulSoup
import urllib.request import requests
import re import re
from datetime import datetime, timedelta from datetime import datetime, timedelta
from time import sleep from time import sleep
#debug # debug
#import pprint # import pprint
class Emmission(object): class Emmission(object):
loading = False loading = False
def __init__(self): def __init__(self):
self._LoadreferencePage() self._LoadreferencePage()
def _LoadreferencePage(self): def _LoadreferencePage(self):
URL="https://www.programme-tv.net/programme/canal-5/" URL = "https://www.programme-tv.net/programme/canal-5/"
try: response = requests.get(URL)
response = urllib.request.urlopen(URL)
except urllib.error.URLError:
return None
print("load") print("load")
self.html = BeautifulSoup(response.read(),"html.parser") self.html = BeautifulSoup(response.content, "html.parser")
self.timeexp=datetime.utcnow() +timedelta(seconds=30) self.timeexp = datetime.utcnow() + timedelta(seconds=30)
def parse_emmission(self,strsearch): def parse_emmission(self, strsearch):
if ((datetime.utcnow() > self.timeexp) and (self.loading == False)): if (datetime.utcnow() > self.timeexp) and (self.loading is False):
self.loading = True self.loading = True
self._LoadreferencePage() self._LoadreferencePage()
self.loading = False self.loading = False
else: else:
while(self.loading): while self.loading:
sleep(0.1) sleep(0.1)
pass pass
strsearch=strsearch.replace('É','E') strsearch = strsearch.replace("É", "E")
linkchaine=self.html.find(text=re.compile(re.escape(strsearch))) strsearch = strsearch.strip()
if linkchaine == None: print(strsearch)
strsearch=strsearch.replace(" ","") chaineElement = self.html.find(string=re.compile(re.escape(strsearch)))
linkchaine=self.html.find(text=re.compile(re.escape(strsearch))) if chaineElement == None:
if linkchaine == None: strsearch = strsearch.replace(" ", "")
chaineElement = self.html.find(string=re.compile(re.escape(strsearch)))
if chaineElement == None:
return "can't find channel" return "can't find channel"
link = linkchaine.parent.parent.find_next_sibling().find_next_sibling().find("a") emissionElement = chaineElement.parent.parent.parent.find_next_sibling()
href = link['href'] print(emissionElement)
response = urllib.request.urlopen(href) link = emissionElement.find("a")
parse=BeautifulSoup(response.read(),"html.parser") href = link["href"]
divcasting=parse.select_one(".descriptif") try:
if (divcasting): img = emissionElement.find_next("img")["data-src"]
casting=divcasting.find_all(href=re.compile("biographie")) except KeyError:
count=0 img = emissionElement.find_next("img")["src"]
response = requests.get(href)
parse = BeautifulSoup(response.content, "html.parser")
divcasting = parse.select_one(".peopleList")
if divcasting:
casting = divcasting.find_all(href=re.compile("\/biographie.*"))
count = 0
for actor in casting: for actor in casting:
casting[count]=actor.text casting[count] = actor["title"]
count+=1 count += 1
else: else:
casting= None casting = None
divsynopsis=parse.select_one(".episode-synopsis") divsynopsis = parse.select_one(".synopsis")
if (divsynopsis): if divsynopsis:
img=divsynopsis.find_next('img')['data-src'] synopsis = divsynopsis.text
synopsis=divsynopsis.select_one(".d-b").text
else: else:
img=None img = None
synopsis="" synopsis = ""
return {'title':link['title'],'href':href,'casting':casting,'synopsis':remove_first_space(synopsis),'img':img} return {
"title": link["title"],
"href": href,
"casting": casting,
"synopsis": remove_first_space(synopsis),
"img": img,
}
def remove_first_space (string): def remove_first_space(string):
space_number=0 space_number = 0
for char in string: for char in string:
if char.isspace(): if char.isspace():
space_number+=1 space_number += 1
else: else:
break break
return string[space_number:] return string[space_number:]

View File

@ -1 +1 @@
{"version":3,"sources":["webpack:///webpack/bootstrap 1dcf71904b3481064b5a"],"names":["parentJsonpFunction","window","chunkIds","moreModules","executeModules","moduleId","chunkId","result","i","resolves","length","installedChunks","push","Object","prototype","hasOwnProperty","call","modules","shift","__webpack_require__","s","installedModules","2","exports","module","l","m","c","d","name","getter","o","defineProperty","configurable","enumerable","get","n","__esModule","object","property","p","oe","err","console","error"],"mappings":"aACA,IAAAA,EAAAC,OAAA,aACAA,OAAA,sBAAAC,EAAAC,EAAAC,GAIA,IADA,IAAAC,EAAAC,EAAAC,EAAAC,EAAA,EAAAC,KACQD,EAAAN,EAAAQ,OAAoBF,IAC5BF,EAAAJ,EAAAM,GACAG,EAAAL,IACAG,EAAAG,KAAAD,EAAAL,GAAA,IAEAK,EAAAL,GAAA,EAEA,IAAAD,KAAAF,EACAU,OAAAC,UAAAC,eAAAC,KAAAb,EAAAE,KACAY,EAAAZ,GAAAF,EAAAE,IAIA,IADAL,KAAAE,EAAAC,EAAAC,GACAK,EAAAC,QACAD,EAAAS,OAAAT,GAEA,GAAAL,EACA,IAAAI,EAAA,EAAYA,EAAAJ,EAAAM,OAA2BF,IACvCD,EAAAY,IAAAC,EAAAhB,EAAAI,IAGA,OAAAD,GAIA,IAAAc,KAGAV,GACAW,EAAA,GAIA,SAAAH,EAAAd,GAGA,GAAAgB,EAAAhB,GACA,OAAAgB,EAAAhB,GAAAkB,QAGA,IAAAC,EAAAH,EAAAhB,IACAG,EAAAH,EACAoB,GAAA,EACAF,YAUA,OANAN,EAAAZ,GAAAW,KAAAQ,EAAAD,QAAAC,IAAAD,QAAAJ,GAGAK,EAAAC,GAAA,EAGAD,EAAAD,QAKAJ,EAAAO,EAAAT,EAGAE,EAAAQ,EAAAN,EAGAF,EAAAS,EAAA,SAAAL,EAAAM,EAAAC,GACAX,EAAAY,EAAAR,EAAAM,IACAhB,OAAAmB,eAAAT,EAAAM,GACAI,cAAA,EACAC,YAAA,EACAC,IAAAL,KAMAX,EAAAiB,EAAA,SAAAZ,GACA,IAAAM,EAAAN,KAAAa,WACA,WAA2B,OAAAb,EAAA,SAC3B,WAAiC,OAAAA,GAEjC,OADAL,EAAAS,EAAAE,EAAA,IAAAA,GACAA,GAIAX,EAAAY,EAAA,SAAAO,EAAAC,GAAsD,OAAA1B,OAAAC,UAAAC,eAAAC,KAAAsB,EAAAC,IAGtDpB,EAAAqB,EAAA,aAGArB,EAAAsB,GAAA,SAAAC,GAA8D,MAApBC,QAAAC,MAAAF,GAAoBA","file":"static/js/manifest.d2b81368489a04c68bca.js","sourcesContent":[" \t// install a JSONP callback for chunk loading\n \tvar parentJsonpFunction = window[\"webpackJsonp\"];\n \twindow[\"webpackJsonp\"] = function webpackJsonpCallback(chunkIds, moreModules, executeModules) {\n \t\t// add \"moreModules\" to the modules object,\n \t\t// then flag all \"chunkIds\" as loaded and fire callback\n \t\tvar moduleId, chunkId, i = 0, resolves = [], result;\n \t\tfor(;i < chunkIds.length; i++) {\n \t\t\tchunkId = chunkIds[i];\n \t\t\tif(installedChunks[chunkId]) {\n \t\t\t\tresolves.push(installedChunks[chunkId][0]);\n \t\t\t}\n \t\t\tinstalledChunks[chunkId] = 0;\n \t\t}\n \t\tfor(moduleId in moreModules) {\n \t\t\tif(Object.prototype.hasOwnProperty.call(moreModules, moduleId)) {\n \t\t\t\tmodules[moduleId] = moreModules[moduleId];\n \t\t\t}\n \t\t}\n \t\tif(parentJsonpFunction) parentJsonpFunction(chunkIds, moreModules, executeModules);\n \t\twhile(resolves.length) {\n \t\t\tresolves.shift()();\n \t\t}\n \t\tif(executeModules) {\n \t\t\tfor(i=0; i < executeModules.length; i++) {\n \t\t\t\tresult = __webpack_require__(__webpack_require__.s = executeModules[i]);\n \t\t\t}\n \t\t}\n \t\treturn result;\n \t};\n\n \t// The module cache\n \tvar installedModules = {};\n\n \t// objects to store loaded and loading chunks\n \tvar installedChunks = {\n \t\t2: 0\n \t};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, {\n \t\t\t\tconfigurable: false,\n \t\t\t\tenumerable: true,\n \t\t\t\tget: getter\n \t\t\t});\n \t\t}\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"/chainetv/\";\n\n \t// on error function for async loading\n \t__webpack_require__.oe = function(err) { console.error(err); throw err; };\n\n\n\n// WEBPACK FOOTER //\n// webpack/bootstrap 1dcf71904b3481064b5a"],"sourceRoot":""} {"version":3,"sources":["webpack:///webpack/bootstrap 7f4d8c76659779b6d89f"],"names":["parentJsonpFunction","window","chunkIds","moreModules","executeModules","moduleId","chunkId","result","i","resolves","length","installedChunks","push","Object","prototype","hasOwnProperty","call","modules","shift","__webpack_require__","s","installedModules","2","exports","module","l","m","c","d","name","getter","o","defineProperty","configurable","enumerable","get","n","__esModule","object","property","p","oe","err","console","error"],"mappings":"aACA,IAAAA,EAAAC,OAAA,aACAA,OAAA,sBAAAC,EAAAC,EAAAC,GAIA,IADA,IAAAC,EAAAC,EAAAC,EAAAC,EAAA,EAAAC,KACQD,EAAAN,EAAAQ,OAAoBF,IAC5BF,EAAAJ,EAAAM,GACAG,EAAAL,IACAG,EAAAG,KAAAD,EAAAL,GAAA,IAEAK,EAAAL,GAAA,EAEA,IAAAD,KAAAF,EACAU,OAAAC,UAAAC,eAAAC,KAAAb,EAAAE,KACAY,EAAAZ,GAAAF,EAAAE,IAIA,IADAL,KAAAE,EAAAC,EAAAC,GACAK,EAAAC,QACAD,EAAAS,OAAAT,GAEA,GAAAL,EACA,IAAAI,EAAA,EAAYA,EAAAJ,EAAAM,OAA2BF,IACvCD,EAAAY,IAAAC,EAAAhB,EAAAI,IAGA,OAAAD,GAIA,IAAAc,KAGAV,GACAW,EAAA,GAIA,SAAAH,EAAAd,GAGA,GAAAgB,EAAAhB,GACA,OAAAgB,EAAAhB,GAAAkB,QAGA,IAAAC,EAAAH,EAAAhB,IACAG,EAAAH,EACAoB,GAAA,EACAF,YAUA,OANAN,EAAAZ,GAAAW,KAAAQ,EAAAD,QAAAC,IAAAD,QAAAJ,GAGAK,EAAAC,GAAA,EAGAD,EAAAD,QAKAJ,EAAAO,EAAAT,EAGAE,EAAAQ,EAAAN,EAGAF,EAAAS,EAAA,SAAAL,EAAAM,EAAAC,GACAX,EAAAY,EAAAR,EAAAM,IACAhB,OAAAmB,eAAAT,EAAAM,GACAI,cAAA,EACAC,YAAA,EACAC,IAAAL,KAMAX,EAAAiB,EAAA,SAAAZ,GACA,IAAAM,EAAAN,KAAAa,WACA,WAA2B,OAAAb,EAAA,SAC3B,WAAiC,OAAAA,GAEjC,OADAL,EAAAS,EAAAE,EAAA,IAAAA,GACAA,GAIAX,EAAAY,EAAA,SAAAO,EAAAC,GAAsD,OAAA1B,OAAAC,UAAAC,eAAAC,KAAAsB,EAAAC,IAGtDpB,EAAAqB,EAAA,aAGArB,EAAAsB,GAAA,SAAAC,GAA8D,MAApBC,QAAAC,MAAAF,GAAoBA","file":"static/js/manifest.d2b81368489a04c68bca.js","sourcesContent":[" \t// install a JSONP callback for chunk loading\n \tvar parentJsonpFunction = window[\"webpackJsonp\"];\n \twindow[\"webpackJsonp\"] = function webpackJsonpCallback(chunkIds, moreModules, executeModules) {\n \t\t// add \"moreModules\" to the modules object,\n \t\t// then flag all \"chunkIds\" as loaded and fire callback\n \t\tvar moduleId, chunkId, i = 0, resolves = [], result;\n \t\tfor(;i < chunkIds.length; i++) {\n \t\t\tchunkId = chunkIds[i];\n \t\t\tif(installedChunks[chunkId]) {\n \t\t\t\tresolves.push(installedChunks[chunkId][0]);\n \t\t\t}\n \t\t\tinstalledChunks[chunkId] = 0;\n \t\t}\n \t\tfor(moduleId in moreModules) {\n \t\t\tif(Object.prototype.hasOwnProperty.call(moreModules, moduleId)) {\n \t\t\t\tmodules[moduleId] = moreModules[moduleId];\n \t\t\t}\n \t\t}\n \t\tif(parentJsonpFunction) parentJsonpFunction(chunkIds, moreModules, executeModules);\n \t\twhile(resolves.length) {\n \t\t\tresolves.shift()();\n \t\t}\n \t\tif(executeModules) {\n \t\t\tfor(i=0; i < executeModules.length; i++) {\n \t\t\t\tresult = __webpack_require__(__webpack_require__.s = executeModules[i]);\n \t\t\t}\n \t\t}\n \t\treturn result;\n \t};\n\n \t// The module cache\n \tvar installedModules = {};\n\n \t// objects to store loaded and loading chunks\n \tvar installedChunks = {\n \t\t2: 0\n \t};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, {\n \t\t\t\tconfigurable: false,\n \t\t\t\tenumerable: true,\n \t\t\t\tget: getter\n \t\t\t});\n \t\t}\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"/chainetv/\";\n\n \t// on error function for async loading\n \t__webpack_require__.oe = function(err) { console.error(err); throw err; };\n\n\n\n// WEBPACK FOOTER //\n// webpack/bootstrap 7f4d8c76659779b6d89f"],"sourceRoot":""}

File diff suppressed because one or more lines are too long

View File

@ -1,21 +1,25 @@
astroid==2.2.5 astroid==2.2.5
beautifulsoup4==4.7.1 beautifulsoup4==4.9.3
bs4==0.0.1 bs4==0.0.1
Click==7.0 certifi==2021.10.8
Flask==1.0.2 charset-normalizer==2.0.11
Flask-Cors==3.0.7 click==8.0.3
Flask==2.0.2
Flask-Cors==3.0.10
gunicorn==20.0.4 gunicorn==20.0.4
idna==3.3
isort==4.3.17 isort==4.3.17
itsdangerous==1.1.0 itsdangerous==2.0.1
Jinja2==2.10.1 Jinja2==3.0.3
lazy-object-proxy==1.3.1 lazy-object-proxy==1.3.1
MarkupSafe==1.1.1 MarkupSafe==2.0.1
mccabe==0.6.1 mccabe==0.6.1
PyJWT==1.7.1 PyJWT==1.7.1
pylint==2.3.1 pylint==2.3.1
requests==2.27.1
six==1.12.0 six==1.12.0
soupsieve==1.9.1 soupsieve==1.9.1
typed-ast==1.4.1 typed-ast==1.5.2
Werkzeug==0.16.0 urllib3==1.26.8
Werkzeug==2.0.2
wrapt==1.11.1 wrapt==1.11.1