1006
правок
Kekaloav (обсуждение | вклад) (Новая страница: «Вот уже год мы говорим учителям, что скачивать "разговоры о важном" надо заранее. А воз и ныне там. Появилась идея скачать материалы автоматом в общую папку досок и запускать оттуда. Непонятно выдержит ли инфраструктура такую нагрузку. Будем пробовать....») |
Kekaloav (обсуждение | вклад) |
||
Строка 1: | Строка 1: | ||
Вот уже год мы говорим учителям, что скачивать "разговоры о важном" надо заранее. А воз и ныне там. | Вот уже год мы говорим учителям, что скачивать "разговоры о важном" надо заранее. А воз и ныне там. | ||
Появилась идея скачать материалы автоматом в общую папку досок и запускать оттуда. | Появилась идея скачать материалы автоматом в общую папку досок и запускать оттуда. | ||
Непонятно выдержит ли инфраструктура такую нагрузку. Будем пробовать. | Непонятно выдержит ли инфраструктура такую нагрузку. Будем пробовать. | ||
Кому интересно публикую скрипт для скачивания. | Кому интересно публикую скрипт для скачивания. | ||
talks.sh<syntaxhighlight lang="bash"> | |||
#!/bin/bash | |||
#файл кладется в /root/ на Линукс (в моем случае Ubuntu, но это не существенно) сервере | |||
#набираем crintab -e и добавляем строку "0 0 * * * /root/talks.sh" | |||
#а еще надо сначала установить (или проверить наличие) утилиту mount.glusterfs | |||
sudo mount.glusterfs 10.xxx.xxx.20:/share /mnt | |||
sudo /root/talks.py | |||
sudo umount /mnt | |||
</syntaxhighlight>talks.py<syntaxhighlight lang="python3"> | |||
#!/usr/bin/env python3 | |||
# -*- coding: utf-8 -*- | |||
#утилита скачивание ВСЕХ имеющихся в наличии файлов "разговоров о важном" в /mnt/public | |||
#перед запуском проверьте наличие всех библиотек описанных в import, особенно logzero и bs4 | |||
#все библиотеки ставятся через pip (pip3) | |||
import shutil | |||
import pathlib | |||
import os | |||
import argparse | |||
import hashlib | |||
import requests | |||
from logzero import logger as log | |||
from pprint import pformat | |||
from time import sleep | |||
from bs4 import BeautifulSoup as bs | |||
url="https://razgovor.edsoo.ru/" | |||
class Yadiredo: | |||
API_ENDPOINT = 'https://cloud-api.yandex.net/v1/disk/public/resources/?public_key={}&path=/{}&offset={}' | |||
def md5sum(self, file_path): | |||
md5 = hashlib.md5() | |||
with open(file_path, 'rb') as f: | |||
for chunk in iter(lambda: f.read(128 * md5.block_size), b''): | |||
md5.update(chunk) | |||
return md5.hexdigest() | |||
def download_file(self, target_path, url): | |||
log.info('downloading') | |||
r = requests.get(url, stream=True) | |||
with open(target_path, 'wb') as f: | |||
shutil.copyfileobj(r.raw, f) | |||
def check_local_file(self, target_path, size, checksum): | |||
if os.path.isfile(target_path): | |||
if size == os.path.getsize(target_path): | |||
if checksum == self.md5sum(target_path): | |||
return True | |||
else: | |||
log.warning('checksum mismatch') | |||
else: | |||
log.warning('size mismatch') | |||
else: | |||
log.warning('missing') | |||
return False | |||
def try_as_file(self, j, current_path): | |||
if 'file' in j: | |||
file_save_path = os.path.join(current_path, j['name']) | |||
log.info(f'processing {file_save_path}') | |||
if not self.check_local_file(file_save_path, j['size'], j['md5']): | |||
self.download_file(file_save_path, j['file']) | |||
else: | |||
log.info('correct') | |||
return True | |||
return False | |||
def download_path(self, target_path, public_key, source_path, offset=0): | |||
log.info('getting "{}" at offset {}'.format(source_path, offset)) | |||
current_path = os.path.join(target_path, source_path) | |||
pathlib.Path(current_path).mkdir(parents=True, exist_ok=True) | |||
jsn = requests.get(self.API_ENDPOINT.format(public_key, source_path, offset)).json() | |||
if self.try_as_file(jsn, current_path): | |||
return | |||
try: | |||
emb = jsn['_embedded'] | |||
except KeyError: | |||
log.error(pformat(jsn)) | |||
return | |||
items = emb['items'] | |||
for i in items: | |||
if self.try_as_file(i, current_path): | |||
continue | |||
else: | |||
subdir_path = os.path.join(source_path, i['name']) | |||
self.download_path(target_path, public_key, subdir_path) | |||
last = offset + emb['limit'] | |||
if last < emb['total']: | |||
self.download_path(target_path, public_key, source_path, last) | |||
def scanall(url): | |||
r = requests.get(url) | |||
if (r.status_code==200): | |||
# soup=bs(r.text,features="lxml") | |||
soup=bs(r.text) | |||
e = soup.find_all('a') | |||
for a in e: | |||
if "topic" in a['href']: | |||
if a.find("div",class_="card-date"): | |||
d=a.div.find_all("div",class_="card-date") | |||
date=d[0].span.get_text() | |||
rr = requests.get(url+a['href'][1:]) | |||
if (rr.status_code==200): | |||
# ssoup=bs(rr.text,features="lxml") | |||
ssoup=bs(rr.text) | |||
groups=ssoup.find_all('div',class_='topic-resource-group') | |||
for group in groups: | |||
cls=group.find("span").get_text() | |||
public_key=group.find('div',class_='topic-resource-download').a['href'] | |||
d = Yadiredo() | |||
d.download_path("/mnt/public/Разговоры о важном/"+date+"/"+cls,public_key, '') | |||
scanall(url) | |||
</syntaxhighlight> | |||
[[Категория:МОС]] | |||
[[Категория:МОС12]] |