PK ! l1e e pdf_shuffle/__init__.pyfrom flask import Flask import os import json app = Flask(__name__) from .views import index, send_pdf from .util import open_browser_tab def init(filename, start=1, end=None, step=1, random=True, host='localhost', port=5000): """ :param filename: :param start: :param end: :param step: :param bool|list|tuple random: :param host: :param port: :return: """ os.environ.update({ 'FILENAME': filename, 'PAGE_START': str(start), 'PAGE_END': json.dumps(end), 'PAGE_STEP': str(step), 'PAGE_RANDOM': json.dumps(random), 'HOST': host, 'PORT': str(port) }) open_browser_tab('http://{}:{}/'.format(os.getenv('HOST'), os.getenv('PORT'))) app.run(host=os.getenv('HOST'), port=os.getenv('PORT')) def init_quiz(filename, start=2, end=None, step=2, random=True, host='localhost', port=5000): """ :param filename: :param start: :param end: :param step: :param bool|list|tuple random: :param host: :param port: :return: """ init(filename, start, end, step, random, host, port) PK ! ۿ pdf_shuffle/__main__.pyimport click import os from . import init @click.command() @click.argument('filename') @click.option('--start', default=1, envvar='PAGE_START') @click.option('--end', default=None, envvar='PAGE_END') @click.option('--step', default=1, envvar='PAGE_STEP') @click.option('--random/--no-random', default=True, envvar='PAGE_RANDOM') @click.option('--host', default='localhost', envvar='HOST') @click.option('--port', default=5000, envvar='PORT') def pdf_shuffle(filename, start, end, step, random, host, port): init(filename, start, end, step, random, host, port) def pdf_quiz(): os.environ.update({ 'PAGE_START': '2', 'PAGE_STEP': '2' }) pdf_shuffle() PK ! s" pdf_shuffle/static/index.css* { margin: 0px; } body { width: 100%; min-width: 100%; } #nav-area { border: 1px solid #ccc; background-color: #f1f1f1; display: inline-table; width: 100%; } /* Style the buttons that are used to open the tab content */ #new-record, .page-button { background-color: inherit; border: none; outline: none; padding: 14px 16px; margin: 0px; transition: 0.3s; font-size: 17px; } .page-button:disabled { color: white; } #nav-page-button, #nav-page-button > *, #page-label > * { display: inherit; } #page-label > * { margin-left: 0.5em; margin-right: 0.5em; } #pdf-container { position: relative; overflow: scroll; } #pdf-area { position: absolute; height: auto; width: 100%; } PK ! p4>9 pdf_shuffle/static/index.jslet pdfCache; const SCALING = 2; config.stepped = 1; if(Array.isArray(config.random) && config.random.length > 0){ config.current = config.random[0] } else { config.current = config.start; } document.getElementById('title').innerHTML = config.filename; Object.assign(document.getElementById('pdf-container').style, getTrueWindowDimension()); pdfjsLib.getDocument('/file?filename=' + encodeURIComponent(config.filename)) .then(pdf=>{ pdfCache = pdf; config.end = config.end || pdfCache.numPages; document.getElementById('page-label-total').innerHTML = pdfCache.numPages; randomizePages(); }); document.getElementById('previous-all').onclick = ()=>{ config.current = config.start; renderPage(); } document.getElementById('previous').onclick = ()=>{ config.current -= config.step; renderPage(); } document.getElementById('next-all').onclick = ()=>{ config.current = config.end; renderPage(); } document.getElementById('next').onclick = ()=>{ config.current += config.step; renderPage(); } document.getElementById('pdf-area').onclick = ()=>{ if(config.end && config.stepped < config.step && config.current < config.end){ config.current++; config.stepped++; renderPage(false); } else { config.stepped = 1; randomizePages(); } } document.body.addEventListener('keydown', (e)=>{ e = e || window.event; const key = e.which || e.keyCode; }); window.addEventListener('resize', ()=>{ Object.assign(document.getElementById('pdf-container').style, getTrueWindowDimension()); }); function getTrueWindowDimension(){ return { height: (window.innerHeight - document.getElementById('nav-area').offsetHeight) + 'px', width: window.innerWidth + 'px' }; } function setPageNav(){ if(config.current >= config.step + config.start){ document.getElementById('previous-all').disabled = false; document.getElementById('previous').disabled = false; } else { document.getElementById('previous-all').disabled = true; document.getElementById('previous').disabled = true; } if((!config.end) || config.current <= config.end - config.step){ document.getElementById('next-all').disabled = false; document.getElementById('next').disabled = false; } else { document.getElementById('next-all').disabled = true; document.getElementById('next').disabled = true; } } function randomizePages(){ const oldCurrent = config.current; if(config.random){ if(Array.isArray(config.random)){ config.current = config.random[Math.floor(Math.random() * config.random.length)]; } else { if(pdfCache){ config.current = (Math.floor(Math.random() * (config.end - config.start + 1)/config.step) * config.step) + config.start; } } } else { if((!config.end) || config.current <= config.end - config.step){ config.current++; } } if(config.current !== oldCurrent){ renderPage(); } } function renderPage(resetStep){ if(resetStep !== false){ config.stepped = 1; } if(pdfCache === undefined){ return; } pdfCache.getPage(config.current) .then(page=>{ const canvas = document.getElementById('pdf-area'); const context = canvas.getContext('2d'); const viewport = page.getViewport(SCALING); const trueHeight = parseInt(getTrueWindowDimension().height); canvas.width = viewport.width; canvas.height = viewport.height; if(canvas.offsetHeight > trueHeight){ Object.assign(canvas.style, { top: '0', left: '50%', transform: 'translateX(-50%)' }); } else if (canvas.offsetHeight < trueHeight){ Object.assign(canvas.style, { top: '50%', left: '0', transform: 'translateY(-50%)' }); } if(viewport.height > viewport.width){ Object.assign(canvas.style, { height: 'auto', width: '100%' }); } else { Object.assign(canvas.style, { height: '100%', width: 'auto' }); } page.render({canvasContext: context, viewport: viewport}); document.getElementById('page-label-current').innerHTML = config.current; Object.assign(document.getElementById('pdf-container'), { scrollTop: 0, scrollLeft: 0 }); setPageNav(); }); } PK ! :H1 1 pdf_shuffle/templates/index.html