Skip to content

Instantly share code, notes, and snippets.

@oxpa
Created April 27, 2015 16:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save oxpa/1afb40770cafc0af0c38 to your computer and use it in GitHub Desktop.
Save oxpa/1afb40770cafc0af0c38 to your computer and use it in GitHub Desktop.
range getting files from server
def generate(taskname, ext='html'):
#jobs=get_results_from_redis()
#job = [i for i in jobs if i.name == taskname][0]
try:
logfile = open('/opt/deploy/var/log/tasks/%s.%s'%(taskname, ext), 'r')
except:
raise StopIteration
yield ''.join(logfile.readlines())
#while job.status != 'SUCCESS' and job.status != 'FAIL' and job.status != 'STOP' and logfile:
try:
line = logfile.readline()
if line != '':
if '\n' not in line:
line = line + '\n'
yield line
else:
#jobs=get_results_from_redis()
#job = [i for i in jobs if i.name == taskname][0]
#log.debug('no data while reading file for %s, state is %s, sleeping', taskname, job.status)
raise StopIteration
time.sleep(2)
except:
app.logger.debug('exception occured!', exc_info=True)
time.sleep(3)
raise StopIteration
def send_file_partial(logname):
path = '/opt/deploy/var/log/tasks/' + logname
range_header = request.headers.get('Range', None)
if not range_header: return send_file(path)
size = os.path.getsize(path)
byte1, byte2 = 0, None
m = re.search('(\d+)-(\d*)', range_header)
g = m.groups()
if g[0]: byte1 = int(g[0])
if g[1]: byte2 = int(g[1])
length = size - byte1
if byte2 is not None:
length = byte2 - byte1
data = None
with open(path, 'rb') as f:
f.seek(byte1)
data = f.read(length)
rv = Response(data,
206,
mimetype=mimetypes.guess_type(path)[0],
direct_passthrough=True)
rv.headers.add('Content-Range', 'bytes {0}-{1}/{2}'.format(byte1, byte1 + length - 1, size))
return rv
@app.route('/log/')
@app.route('/log/<taskname>')
def stream_log(taskname=None):
range_header = request.headers.get('Range')
if taskname == None:
return redirect(url_for('select'))
if range_header is None:
#log.debug('returning log without Range')
return Response(stream_with_context(generate(taskname)), content_type='text/plain; charset=utf-8')
else:
#log.debug('returning Ranged log part')
return send_file_partial(taskname + '.html')
<script type="text/javascript">
var xhr = new window.XMLHttpRequest();
var gotBytes = 0;
xhr.onreadystatechange = function () {
if (xhr.readyState==4 && xhr.status>200 && xhr.status <400 && xhr.responseText !=''){
var ins = document.getElementById('log');
ins.innerHTML += xhr.responseText;
gotBytes += xhr.responseText.length;
if (xhr.responseText !="")
console.log('response text length is ', xhr.responseText.length, '. Overall length is now', ins.innerHTML.length, 'while requesting bytes starting from ', gotBytes);
window.scrollTo(0,document.body.scrollHeight);
}
};
function update () {
xhr.open("GET", "/log/{{taskname}}", true);
xhr.setRequestHeader('Content-Type', 'text/plain');
xhr.setRequestHeader('Tranfer-Encoding','chunked ');
xhr.setRequestHeader('Range', 'bytes='+gotBytes+'-');
xhr.send(null);
setTimeout(update, 3000);
}
update();
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment