diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..277afac --- /dev/null +++ b/.gitignore @@ -0,0 +1,179 @@ +# Created by https://www.gitignore.io/api/git,emacs,python,coffeescript +# Edit at https://www.gitignore.io/?templates=git,emacs,python,coffeescript + +### CoffeeScript ### +*.js + +### Emacs ### +# -*- mode: gitignore; -*- +*~ +\#*\# +/.emacs.desktop +/.emacs.desktop.lock +*.elc +auto-save-list +tramp +.\#* + +# Org-mode +.org-id-locations +*_archive + +# flymake-mode +*_flymake.* + +# eshell files +/eshell/history +/eshell/lastdir + +# elpa packages +/elpa/ + +# reftex files +*.rel + +# AUCTeX auto folder +/auto/ + +# cask packages +.cask/ +dist/ + +# Flycheck +flycheck_*.el + +# server auth directory +/server/ + +# projectiles files +.projectile + +# directory configuration +.dir-locals.el + +# network security +/network-security.data + + +### Git ### +# Created by git for backups. To disable backups in Git: +# $ git config --global mergetool.keepBackup false +*.orig + +# Created by git when using merge tools for conflicts +*.BACKUP.* +*.BASE.* +*.LOCAL.* +*.REMOTE.* +*_BACKUP_*.txt +*_BASE_*.txt +*_LOCAL_*.txt +*_REMOTE_*.txt + +### Python ### +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +pip-wheel-metadata/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +.hypothesis/ +.pytest_cache/ + +# Translations +*.mo +*.pot + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +# pyenv +.python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# celery beat schedule file +celerybeat-schedule + +# SageMath parsed files +*.sage.py + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# Mr Developer +.mr.developer.cfg +.project +.pydevproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +#project settings +sahli-venv/* +*.wp* diff --git a/README.md b/README.md index 3b64e94..c171394 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ l__________/__________|___|______l__________j_____j Ansi/Ansi Viewer in Ecmascript - Coded by Sir Garbagetruck / Accession 2013 + Coded by Sir Garbagetruck / Accession 2013+ Uses fonts by DMG, http:trueschool.se Uses SixteenColors textmode js library for rendering (well, my optimized version...) @@ -48,6 +48,8 @@ idea... * Android tablets ARE considered modern; Ipad/Iphone too. * I haven't tested on MorphOS yet. +For Chrome/Chromium: + To use with _local_ files you need to run your browser in "developer" mode, that means: @@ -63,6 +65,30 @@ This works just fine if you use remote urls for the files. EVERY PERSON ALIVE, DEAD, OR IMAGINARY, INCLUDING THE NONEXISTENT. *** +Mr Doob (who I want to call Trace (: ) has a good page +explaining how to do this and alternatives here: + +https://github.com/mrdoob/three.js/wiki/How-to-run-things-locally + +Firefox (and Icecat, possibly other Firefox codebased browsers) +seem to work today (Sept 2016) _without_ making any changes, so +you can use it 'out of the box.' M0qui was able to, and I tested, +and so the big 72-point "not supported on Windows+Firefox" warning +goes away. + +Again, DON'T FREAKING TURN OFF JAVASCRIPT SECURITY AND FORGET TO +TURN IT BACK ON. DON'T. NOT JUST ON WINDOWS. BUT ESPECIALLY ON +WINDOWS. + +I may be able to turn this into a chrome app at some point, which +will eliminate that issue. Possibly also a Firefox solution, but: +As of today: I do not support this on Windows + Firefox. That is +100% at your own risk, because of the possibility you will forget +to set the setting back. + +It's just plain safer to install this on your webserver at the +party place in a directory and use _that._ + This product is licensed under the WTFPL. See: http://www.wtfpl.net for details, or just get the license: @@ -98,3 +124,8 @@ Azzarro/Madwizards. - More examples came from 16colors archive. When the final Sahli ver. B comes out, I'll select some test files and put those credits in here too. + +- Thanks to M0qui for submitting a patch for 'backwards' +(in case you accidentally hit space. Which we c64 sceners +never do, because that would be the NEXT demopart, and +you'd have to reload (: ) diff --git a/editor/jquery-2.1.0.min.js b/editor-old-js/jquery-2.1.0.min.js similarity index 100% rename from editor/jquery-2.1.0.min.js rename to editor-old-js/jquery-2.1.0.min.js diff --git a/editor/jquery-ui-dot-luv.css b/editor-old-js/jquery-ui-dot-luv.css similarity index 100% rename from editor/jquery-ui-dot-luv.css rename to editor-old-js/jquery-ui-dot-luv.css diff --git a/editor/jquery-ui.min.js b/editor-old-js/jquery-ui.min.js similarity index 100% rename from editor/jquery-ui.min.js rename to editor-old-js/jquery-ui.min.js diff --git a/editor/sahliedit.css b/editor-old-js/sahliedit.css similarity index 100% rename from editor/sahliedit.css rename to editor-old-js/sahliedit.css diff --git a/editor/sahliedit.js b/editor-old-js/sahliedit.js similarity index 93% rename from editor/sahliedit.js rename to editor-old-js/sahliedit.js index 678a60e..45237d7 100644 --- a/editor/sahliedit.js +++ b/editor-old-js/sahliedit.js @@ -1,4 +1,4 @@ -// Generated by CoffeeScript 1.7.1 +// Generated by CoffeeScript 1.11.0 (function() { var Sahli, ansiorascii, arraytocolor, booltoint, colorindex, colortoarray, colortoname, dec2hex, dumpjson, emptyfiledef, getfilelist, hex2dec, inttobool, loadsahli, newsahli, resolvefiletype, sahlicolor, statustobool; @@ -163,19 +163,19 @@ }; Sahli.prototype.buildlist = function(data) { - var i, item, x, _i, _j, _len, _len1, _ref, _ref1; + var i, item, j, k, len, len1, ref, ref1, x; $('#list').show(100); $('#list ol li').remove(); - _ref = this.data.filedata; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - i = _ref[_i]; + ref = this.data.filedata; + for (j = 0, len = ref.length; j < len; j++) { + i = ref[j]; console.log(i.author); } x = 0; $('#dirlocation').val(this.data.location); - _ref1 = this.data.filedata; - for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) { - item = _ref1[_j]; + ref1 = this.data.filedata; + for (k = 0, len1 = ref1.length; k < len1; k++) { + item = ref1[k]; $('#sortlist').append(this.additem(item, x++)); } return $('#sortlist').sortable({ @@ -186,13 +186,13 @@ }, stop: (function(_this) { return function(event, ui) { - var e, name, s, _k, _len2, _ref2; + var e, l, len2, name, ref2, s; s = ui.item.data().startpos; e = ui.item.index(); _this.data.filedata = _this.rearrangearray(s, e, _this.data.filedata); - _ref2 = _this.data.filedata; - for (_k = 0, _len2 = _ref2.length; _k < _len2; _k++) { - name = _ref2[_k]; + ref2 = _this.data.filedata; + for (l = 0, len2 = ref2.length; l < len2; l++) { + name = ref2[l]; console.log(name.author, name.name, name.file); } console.log('---'); @@ -367,13 +367,13 @@ arraytocolor = function(array) { var c, x; c = ((function() { - var _i, _len, _results; - _results = []; - for (_i = 0, _len = array.length; _i < _len; _i++) { - x = array[_i]; - _results.push(dec2hex(x)); + var j, len, results; + results = []; + for (j = 0, len = array.length; j < len; j++) { + x = array[j]; + results.push(dec2hex(x)); } - return _results; + return results; })()).slice(0, 3).join(''); return "#" + c; }; @@ -383,13 +383,13 @@ color = color.slice(1); c1 = [color.slice(0, 2), color.slice(2, 4), color.slice(4, 6)]; x = (function() { - var _i, _len, _results; - _results = []; - for (_i = 0, _len = c1.length; _i < _len; _i++) { - i = c1[_i]; - _results.push(hex2dec(i)); + var j, len, results; + results = []; + for (j = 0, len = c1.length; j < len; j++) { + i = c1[j]; + results.push(hex2dec(i)); } - return _results; + return results; })(); x.push(255); return x; diff --git a/editor/sahliedit.litcoffee b/editor-old-js/sahliedit.litcoffee similarity index 100% rename from editor/sahliedit.litcoffee rename to editor-old-js/sahliedit.litcoffee diff --git a/editor/sahlieditor.html b/editor-old-js/sahlieditor.html similarity index 100% rename from editor/sahlieditor.html rename to editor-old-js/sahlieditor.html diff --git a/editor.py b/editor.py new file mode 100644 index 0000000..bf96391 --- /dev/null +++ b/editor.py @@ -0,0 +1,160 @@ +#!/usr/bin/env python +# coding:utf-8 +""" + Author: Sir Garbagetruck -- + Purpose: make editing the list.sahli file easier + Created: 2020/04/09 +""" + +import json +import argparse +import os +from sauce import SAUCE +from PIL import Image +from sahliEditorPython import sahlifile as SF + + +def getfilesindir(directory): + """return the files in a directory as an array""" + for root, dirs, files, rootfd in os.fwalk(directory): + return files + + +def getfilenames(filedata): + """return the file names from a sahli filedata array""" + f = [] + for i in filedata: + f.append(i['file']) + return f + + +def getdata(filedata, name): + """get the filedata entry where file = name""" + for i in filedata: + if i['file'] == name: + return i + return [] + + +def getpicdata(filename): + """extract picture data from filename""" + imagedata = Image.open(filename) + picdata = { + 'width': imagedata.width, + 'height': imagedata.height + } + return picdata + + +def getansidata(filename): + """extract SAUCE data from filename""" + saucedata = SAUCE(filename) + ansidata = { + 'author': saucedata.author, + 'group': saucedata.group, + 'title': saucedata.title, + 'filesize': saucedata.filesize, + 'comments': saucedata.comments, + 'width': None, + 'height': None + } + tinfonames = [saucedata.tinfo1_name, + saucedata.tinfo2_name, + saucedata.tinfo3_name, + saucedata.tinfo4_name] + tinfo = [saucedata.tinfo1, + saucedata.tinfo2, + saucedata.tinfo3, + saucedata.tinfo4] + for i in range(0, 3): + if tinfonames[i] == 'width': + ansidata['width'] = tinfo[i] + if tinfonames[i] == 'height': + ansidata['height'] = tinfo[i] +# print(tinfonames[i]) + return ansidata + + +def getamigadata(filename): + """try to get some form of info from file (:""" + with open(filename, encoding='latin1') as f: + ascii = f.readlines() + width = 0 + for i in ascii: + if len(i) > width: + width = len(i) + return {'height': len(ascii), + 'width': width} + + +def main(args): + """maintain a list.sahli file""" + if args.new: + mysahli = SF.sahlifile(None) + else: + mysahli = SF.sahlifile(args.filename) + mysahli.sahli['location'] = args.directory + files = getfilesindir(args.directory) + filedata = mysahli.sahli['filedata'] + filedatanames = getfilenames(filedata) + newdata = [] + for i in files: + dirfile = '{}/{}'.format(args.directory, i) + if i in filedatanames: + print('found! {}'.format(i)) + # todo: _if_ I ever make this a non-preparser, then... futz with + a = getansidata(dirfile) + newdata.append(getdata(filedata, i)) + else: + print('not found! {}'.format(i)) + suf = i.split('.')[-1] + if suf in ['png', 'jpg', 'jpeg', 'gif', + 'PNG', 'JPG', 'JPEG', 'GIF']: + stuff = getpicdata(dirfile) + entry = mysahli.blank_picture() + entry['width'] = stuff['width'] + entry['height'] = stuff['height'] + entry['file'] = i + entry['name'] = i + newdata.append(entry) + elif suf in ['ans', 'ANS', 'BIN', 'bin', 'XB', 'xb']: + stuff = getansidata(dirfile) + entry = mysahli.blank_ansi() + entry['file'] = i + entry['name'] = stuff['title'] + entry['author'] = '{}/{}'.format( + stuff['author'], stuff['group']) + entry['text'] = stuff['comments'] + if stuff['height'] is not None: + entry['height'] = stuff['height'] + if stuff['width'] is not None: + entry['width'] = stuff['width'] + newdata.append(entry) + elif suf in ['TXT', 'ASC', 'txt', 'asc', + 'NFO', 'nfo', 'diz', 'DIZ']: + stuff = getamigadata(dirfile) + entry = mysahli.blank_amiga_ascii() + entry['name'] = i +# entry['title'] = i +# entry['height'] = stuff['height'] + entry['file'] = i + newdata.append(entry) + else: + print("dunno what type of file this is... {}".format(dirfile)) + mysahli.sahli['filedata'] = newdata + out = json.dumps(mysahli.sahli, sort_keys=False, indent=4) + if args.outfile == '>stdout': + print(out) + else: + with open(args.outfile, 'w') as f: + json.dump(mysahli.sahli, f, sort_keys=False, indent=4) + + +if __name__ == '__main__': + ap = argparse.ArgumentParser() + ap.add_argument('-f', '--filename', default='list.sahli') + ap.add_argument('-n', '--new', action='store_true') + ap.add_argument('-o', '--outfile', type=str, default='>stdout') + ap.add_argument('-d', '--directory', type=str, required=True, + help='directory where compo files are') + main(ap.parse_args()) diff --git a/index.html b/index.html index 0c9660b..e070433 100644 --- a/index.html +++ b/index.html @@ -41,6 +41,8 @@
  • W Begin scrolling upward
  • A Stop scrolling
  • +
  • P Previous Picture
  • +
  • T Jump to Top of picture (resets zoom)
  • B Jump to Bottom
  • 12345 Alter scrollspeed (fast -> slow)
  • diff --git a/list.sahli b/list.sahli index e394280..0a19dfc 100644 --- a/list.sahli +++ b/list.sahli @@ -14,100 +14,104 @@ "filedata": [ + { + "file": "AD - Green Beam.scaled.png", + "name": "Green Beam", + "amiga": false, + "filetype": "image", + "width": "1600", + "author": "AD", + "font": "Propaz", + "color": [ + 0, + 0, + 0, + 255 + ], + "bg": [ + 255, + 255, + 255, + 255 + ], + "line1": "", + "line2": "", + "text": "" + }, + + { + "file": "om-boss.png", + "name": "Green Beam", + "amiga": false, + "filetype": "image", + "width": "640", + "author": "AD", + "font": "Propaz", + "color": [ + 0, + 0, + 0, + 255 + ], + "bg": [ + 255, + 255, + 255, + 255 + ], + "line1": "", + "line2": "", + "text": "" + }, + { "file": "spaceflight.asc", - "name": "Spaceflight", - "amiga": true, - "filetype": "plain", - "width": "80", - "author": "Urs", - "font": "pot-noodle", - "color": [ - 255, - 128, - 0, - 255 - ], - "bg": [ - 0, - 0, - 0, - 255 - ], - "line1": "Orange on Dark Grey", - "line2": "Test for plain files", - "text": "" - }, - { - "file": "az0!-revi510n.txt", - "name": "Revision", - "amiga": true, - "filetype": "plain", - "width": "80", - "author": "Azzarro/Madwizards", - - "font": "Propaz", - - "color": [ - + "font": "mosoul", + "color": [ 0, - 240, - 0, - 255 - ], - "bg": [ - 255, - 0, - 0, - 255 - ], - "line1": "Azzaro Returns", - "line2": "Revision ansi/ascii compo 2013", - - "text": "Color test as well as Microknight test." - + "text": "Color test as well as mOsOul test." }, { "file": "dS!-JUFV.txt", diff --git a/sahli.coffee b/sahli.coffee index a4cf8a0..34af56e 100644 --- a/sahli.coffee +++ b/sahli.coffee @@ -14,6 +14,7 @@ l__________/__________|___|______l__________j_____j class @Sahli constructor: () -> + $('body').css('cursor', 'none'); # I don't think we actually are going to have one, as we don't # need instance variables (things used outside the function) @@ -39,6 +40,8 @@ class @Sahli @loadhugeansi picdata, inserthere when 'tundra' @loadhugeansi picdata, inserthere + when 'image' + @loadpicture picdata, inserthere else @loadplain picdata, inserthere @@ -49,6 +52,7 @@ class @Sahli buf = $('') buf.css {'margin':'0 auto'} ptxt = $('
    ')
    +    ptxt.addClass 'plaintext'
         color = @calccolor(picdata.color)
         bgcolor = @calccolor(picdata.bg)
         pdiv.addClass 'scrolly'
    @@ -58,9 +62,9 @@ class @Sahli
           'background-color': bgcolor
           'margin': 'auto'
           'display': 'inline-block'
    -    ptxt.width picdata.width * 8
    -    @origwidth = ptxt.width
    -    pdiv.width ptxt.width
    +    #ptxt.width picdata.width * 8
    +    #@origwidth = ptxt.width
    +    #pdiv.width ptxt.width
         pdiv.prepend buf.clone()
         pdiv.append ptxt
         pdiv.append buf
    @@ -78,6 +82,72 @@ class @Sahli
         req.open 'GET', fname, true
         req.send null
     
    +  @increaseFont = (node, increaseBy=5) ->
    +    current_size = parseInt($(node).css("font-size"));
    +    $(node).css("font-size", current_size + increaseBy);
    +
    +  @loadpicture = (picdata, inserthere) ->
    +    fname = @location + '/' + picdata.file
    +    pdiv = $('
    ') + pdiv.addClass 'scrolly' + pdiv.addClass 'image' + pdiv.width window.innerWidth + pdiv.css 'display', 'inline-block' + pimg = $('') + pimg.addClass 'fullwidth' + pdiv.append pimg + inserthere.after pdiv + $('h6').hide() + $('body').scrollTop 0 + @origwidth = picdata.width + @origheight = picdata.height + @bestfit() + + @fullwidthplain = => + if ($('pre').css("font-size") == "16px") + $('pre').css("font-size", "2.5vw"); + else + $('pre').css("font-size", "16px"); + + @togglefullwidthmode = => + if ($('pre').hasClass('plaintext')) + @fullwidthplain() + else + if $('div.scrolly').hasClass('image') + @bestfit() + else + @zoom() + + @zoomin = => + if ($('pre').hasClass('plaintext')) + @increaseFont($('pre'), 2) + else + @zoom(100); + + @zoomout = => + if ($('pre').hasClass('plaintext')) + @increaseFont($('pre'), -2) + else + @zoom(-100); + + @bestfit = => + if $('div.scrolly').hasClass('image') + if $('div.scrolly').hasClass('bestfitMode') + $('div.scrolly').removeClass 'bestfitMode' + $('div.scrolly').addClass 'fullwidthMode' + $('div.scrolly').width window.innerWidth + $('div.scrolly').height("") + $('img.bestfit').addClass 'fullwidth' + $('img.bestfit').removeClass 'bestfit' + else + $('h6').hide() + $('div.scrolly').addClass 'bestfitMode' + $('div.scrolly').removeClass 'fullwidthMode' + $('div.scrolly').width window.innerWidth + $('div.scrolly').height window.innerHeight + $('img.fullwidth').addClass 'bestfit' + $('img.fullwidth').removeClass 'fullwidth' + @loadhugeansi = (picdata, inserthere) -> fname = @location + '/' + picdata.file pdiv = $('
    ') @@ -97,7 +167,7 @@ class @Sahli @origwidth = canvwidth @origheight = calcheight pdiv.width canvwidth - ), 30, 'bits': '8' + ), 30, {'bits': '8', "font": picdata.font} @loadavatar = (picdata, inserthere) -> console.log 'avatar', picdata, inserthere @@ -137,6 +207,7 @@ class @Sahli filedata = @filedata filedata[i].pic = $('
    ' + filedata[i].file + '
    ') viewbox.append filedata[i].pic + $('h6').show() @loadpic filedata[i], filedata[i].pic @currentpic += 1 if @currentpic > filedata.length - 1 @@ -146,6 +217,13 @@ class @Sahli $('body').stop() @loadinfopanel i + @prevpic = => + i = @currentpic-2 + if i < 0 + i = i + @filedata.length + @currentpic = i + @nextpic() + @togglefullscreen = -> docElm = document.documentElement if @fullscreen @@ -230,7 +308,7 @@ class @Sahli zoomee.width newwidth $('canvas').width newwidth else - if zoomee.width() != @origwidth + if parseInt( zoomee.width(), 10 ) != parseInt( @origwidth, 10) zoomee.width @origwidth $('canvas').width '100%' else @@ -315,24 +393,26 @@ class @Sahli switch ev.which when @keycode ' ' @nextpic() + when @keycode 'p' + @prevpic() when @keycode 'f' @togglefullscreen() when @keycode 's' @setscroll() when @keycode 't' $('body').scrollTop 0 - @zoom 0 + @togglefullwidthmode() when @keycode 'b' $('body').scrollTop $('body').height() when @keycode 'a' $('body').stop() @scroll_direction = - @scroll_direction when @keycode 'z' - @zoom() + @togglefullwidthmode() when @keycode 'e' - @zoom 100 + @zoomin() when @keycode 'r' - @zoom -100 + @zoomout() when @keycode 'w' @changescrolldirection -1 when @keycode 'x' @@ -342,6 +422,7 @@ class @Sahli when @keycode 'i' $('div.infobox').toggle() when @keycode 'v' + $('h6').show() $('h6').height( (window.innerHeight - $('.scrolly').height()) / 2 ) when @keycode '1' @changespeed 1 @@ -356,6 +437,10 @@ class @Sahli @scroll_speed = 4 when @keycode '5' @changespeed 5 + when @keycode '8' + @increaseFont($('pre'), -2) + when @keycode '9' + @increaseFont($('pre'), 2) when 40 # down @moveline 1 when 38 # up diff --git a/sahli.css b/sahli.css index b0a213a..a47845b 100644 --- a/sahli.css +++ b/sahli.css @@ -10,6 +10,10 @@ body { border: none; } +pre { + line-height: 100%; +} + #top { border: 1px solid green; color: green; @@ -40,7 +44,7 @@ h6 { .help { position: fixed; top: 1em; - left: 33%; + left: 25%; text-align: left; background-color: lightgrey; border: outset darkgray; @@ -49,7 +53,19 @@ h6 { border-radius: 8px; font-family: topaz1200,mOsOul, Consolas, monospace; opacity: .85; - width: 33%; + width: 50%; +} + +.fullwidth { + width: 100%; +} + +.bestfit { + padding: 0; + display: block; + margin: 0 auto; + max-width: 100%; + max-height: 100%; } .keylist { diff --git a/sahli.js b/sahli.js index 4dd5734..8168d21 100644 --- a/sahli.js +++ b/sahli.js @@ -1,4 +1,4 @@ -// Generated by CoffeeScript 1.9.0 +// Generated by CoffeeScript 1.9.3 /* .___________________________________, ___ @@ -16,7 +16,9 @@ l__________/__________|___|______l__________j_____j (function() { this.Sahli = (function() { - function Sahli() {} + function Sahli() { + $('body').css('cursor', 'none'); + } Sahli.loadpic = function(picdata, inserthere) { switch (picdata.filetype) { @@ -40,6 +42,8 @@ l__________/__________|___|______l__________j_____j return this.loadhugeansi(picdata, inserthere); case 'tundra': return this.loadhugeansi(picdata, inserthere); + case 'image': + return this.loadpicture(picdata, inserthere); default: return this.loadplain(picdata, inserthere); } @@ -55,6 +59,7 @@ l__________/__________|___|______l__________j_____j 'margin': '0 auto' }); ptxt = $('
    ');
    +      ptxt.addClass('plaintext');
           color = this.calccolor(picdata.color);
           bgcolor = this.calccolor(picdata.bg);
           pdiv.addClass('scrolly');
    @@ -65,9 +70,6 @@ l__________/__________|___|______l__________j_____j
             'margin': 'auto',
             'display': 'inline-block'
           });
    -      ptxt.width(picdata.width * 8);
    -      this.origwidth = ptxt.width;
    -      pdiv.width(ptxt.width);
           pdiv.prepend(buf.clone());
           pdiv.append(ptxt);
           pdiv.append(buf);
    @@ -87,6 +89,91 @@ l__________/__________|___|______l__________j_____j
           return req.send(null);
         };
     
    +    Sahli.increaseFont = function(node, increaseBy) {
    +      var current_size;
    +      if (increaseBy == null) {
    +        increaseBy = 5;
    +      }
    +      current_size = parseInt($(node).css("font-size"));
    +      return $(node).css("font-size", current_size + increaseBy);
    +    };
    +
    +    Sahli.loadpicture = function(picdata, inserthere) {
    +      var fname, pdiv, pimg;
    +      fname = this.location + '/' + picdata.file;
    +      pdiv = $('
    '); + pdiv.addClass('scrolly'); + pdiv.addClass('image'); + pdiv.width(window.innerWidth); + pdiv.css('display', 'inline-block'); + pimg = $(''); + pimg.addClass('fullwidth'); + pdiv.append(pimg); + inserthere.after(pdiv); + $('h6').hide(); + $('body').scrollTop(0); + this.origwidth = picdata.width; + this.origheight = picdata.height; + return this.bestfit(); + }; + + Sahli.fullwidthplain = function() { + if ($('pre').css("font-size") === "16px") { + return $('pre').css("font-size", "2.5vw"); + } else { + return $('pre').css("font-size", "16px"); + } + }; + + Sahli.togglefullwidthmode = function() { + if ($('pre').hasClass('plaintext')) { + return Sahli.fullwidthplain(); + } else { + if ($('div.scrolly').hasClass('image')) { + return Sahli.bestfit(); + } else { + return Sahli.zoom(); + } + } + }; + + Sahli.zoomin = function() { + if ($('pre').hasClass('plaintext')) { + return Sahli.increaseFont($('pre'), 2); + } else { + return Sahli.zoom(100); + } + }; + + Sahli.zoomout = function() { + if ($('pre').hasClass('plaintext')) { + return Sahli.increaseFont($('pre'), -2); + } else { + return Sahli.zoom(-100); + } + }; + + Sahli.bestfit = function() { + if ($('div.scrolly').hasClass('image')) { + if ($('div.scrolly').hasClass('bestfitMode')) { + $('div.scrolly').removeClass('bestfitMode'); + $('div.scrolly').addClass('fullwidthMode'); + $('div.scrolly').width(window.innerWidth); + $('div.scrolly').height(""); + $('img.bestfit').addClass('fullwidth'); + return $('img.bestfit').removeClass('bestfit'); + } else { + $('h6').hide(); + $('div.scrolly').addClass('bestfitMode'); + $('div.scrolly').removeClass('fullwidthMode'); + $('div.scrolly').width(window.innerWidth); + $('div.scrolly').height(window.innerHeight); + $('img.fullwidth').addClass('bestfit'); + return $('img.fullwidth').removeClass('fullwidth'); + } + } + }; + Sahli.loadhugeansi = function(picdata, inserthere) { var calcheight, canvwidth, fname, pdiv; fname = this.location + '/' + picdata.file; @@ -111,7 +198,8 @@ l__________/__________|___|______l__________j_____j return pdiv.width(canvwidth); }; })(this)), 30, { - 'bits': '8' + 'bits': '8', + "font": picdata.font }); }; @@ -161,6 +249,7 @@ l__________/__________|___|______l__________j_____j filedata = Sahli.filedata; filedata[i].pic = $('
    ' + filedata[i].file + '
    '); viewbox.append(filedata[i].pic); + $('h6').show(); Sahli.loadpic(filedata[i], filedata[i].pic); Sahli.currentpic += 1; if (Sahli.currentpic > filedata.length - 1) { @@ -172,6 +261,16 @@ l__________/__________|___|______l__________j_____j return Sahli.loadinfopanel(i); }; + Sahli.prevpic = function() { + var i; + i = Sahli.currentpic - 2; + if (i < 0) { + i = i + Sahli.filedata.length; + } + Sahli.currentpic = i; + return Sahli.nextpic(); + }; + Sahli.togglefullscreen = function() { var docElm; docElm = document.documentElement; @@ -270,7 +369,7 @@ l__________/__________|___|______l__________j_____j zoomee.width(newwidth); return $('canvas').width(newwidth); } else { - if (zoomee.width() !== this.origwidth) { + if (parseInt(zoomee.width(), 10) !== parseInt(this.origwidth, 10)) { zoomee.width(this.origwidth); return $('canvas').width('100%'); } else { @@ -281,7 +380,7 @@ l__________/__________|___|______l__________j_____j }; Sahli.panelmode = function() { - var canvs, ct, drawcol, level, newheight, newwidth, numcols, numpanels, outer, panelratio, panelslotheight, panelsperslot, pic, picdpercol, screenratio, wh, ww, x, _i, _j, _len, _len1, _results; + var canvs, ct, drawcol, j, k, len, len1, level, newheight, newwidth, numcols, numpanels, outer, panelratio, panelslotheight, panelsperslot, pic, picdpercol, results, screenratio, wh, ww, x; $('#panel').toggle(); canvs = $('canvas'); $('.scrolly').width(this.origwidth); @@ -309,9 +408,9 @@ l__________/__________|___|______l__________j_____j drawcol = 1; ct = 0; outer.append(this.createpanel(1, newwidth - 6)); - _results = []; - for (_i = 0, _len = canvs.length; _i < _len; _i++) { - pic = canvs[_i]; + results = []; + for (j = 0, len = canvs.length; j < len; j++) { + pic = canvs[j]; $("#column" + drawcol).append(pic); level += 1; ct += 1; @@ -319,19 +418,19 @@ l__________/__________|___|______l__________j_____j level = 0; drawcol = drawcol + 1; if (ct < numpanels) { - _results.push(outer.append(this.createpanel(drawcol, newwidth - 6))); + results.push(outer.append(this.createpanel(drawcol, newwidth - 6))); } else { - _results.push(void 0); + results.push(void 0); } } else { - _results.push(void 0); + results.push(void 0); } } - return _results; + return results; } else { $('#outbox').show(); - for (_j = 0, _len1 = canvs.length; _j < _len1; _j++) { - pic = canvs[_j]; + for (k = 0, len1 = canvs.length; k < len1; k++) { + pic = canvs[k]; $('.scrolly').append(pic); } canvs.width(this.origwidth); @@ -374,24 +473,26 @@ l__________/__________|___|______l__________j_____j switch (ev.which) { case _this.keycode(' '): return _this.nextpic(); + case _this.keycode('p'): + return _this.prevpic(); case _this.keycode('f'): return _this.togglefullscreen(); case _this.keycode('s'): return _this.setscroll(); case _this.keycode('t'): $('body').scrollTop(0); - return _this.zoom(0); + return _this.togglefullwidthmode(); case _this.keycode('b'): return $('body').scrollTop($('body').height()); case _this.keycode('a'): $('body').stop(); return _this.scroll_direction = -_this.scroll_direction; case _this.keycode('z'): - return _this.zoom(); + return _this.togglefullwidthmode(); case _this.keycode('e'): - return _this.zoom(100); + return _this.zoomin(); case _this.keycode('r'): - return _this.zoom(-100); + return _this.zoomout(); case _this.keycode('w'): return _this.changescrolldirection(-1); case _this.keycode('x'): @@ -401,6 +502,7 @@ l__________/__________|___|______l__________j_____j case _this.keycode('i'): return $('div.infobox').toggle(); case _this.keycode('v'): + $('h6').show(); return $('h6').height((window.innerHeight - $('.scrolly').height()) / 2); case _this.keycode('1'): return _this.changespeed(1); @@ -415,6 +517,10 @@ l__________/__________|___|______l__________j_____j return _this.scroll_speed = 4; case _this.keycode('5'): return _this.changespeed(5); + case _this.keycode('8'): + return _this.increaseFont($('pre'), -2); + case _this.keycode('9'): + return _this.increaseFont($('pre'), 2); case 40: return _this.moveline(1); case 38: diff --git a/sahliEditorPython/__init__.py b/sahliEditorPython/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/sahliEditorPython/sahlifile.py b/sahliEditorPython/sahlifile.py new file mode 100644 index 0000000..598614e --- /dev/null +++ b/sahliEditorPython/sahlifile.py @@ -0,0 +1,130 @@ +#!/usr/bin/env python +# coding:utf-8 +""" + Author: Sir Garbagetruck -- + Purpose: base class for Sahli file + Created: 2020/04/09 +""" + +import json +######################################################################## + + +class sahlifile: + """the Sahli file structure and classes to futz with""" + + # ---------------------------------------------------------------------- + def __init__(self, filename): + """Constructor""" + self.valid_filetypes = [ + "plain", + "ansi", + "xbin", + "ice", + "adf", + "avatar", + "bin", + "idf", + "pcboard", + "tundra" + ] + self.valid_fonts = [ + 'Propaz', 'ansifont', 'mOsOul', 'Microknight', 'p0t-nOodle' + ] + if filename is not None: + with open(filename) as f: + self.sahli = json.load(f) + else: + location = self.blank_location() + slides = self.blank_slides() + filedata = [] + self.sahli = { + 'location': location, + 'slides': slides, + 'filedata': filedata + } + + def blank_slides(self): + """blank slide structure""" + slides = { + 'background': '', + 'template': '', + 'css': '' + } + return slides + + def blank_location(self): + """blank location structure""" + return '' + + def blank_picture(self): + """Blank picture structure""" + return { + 'file': '', + 'name': '', + 'amiga': False, + 'filetype': 'image', + 'width': '1600', + 'author': '', + 'font': 'Propaz', + 'color': [0, 0, 0, 255], + 'bg': [255, 255, 255, 255], + 'line1': '', + 'line2': '', + 'text': '' + } + # ---------------------------------------------------------------------- + + def blank_amiga_ascii(self): + """blank amiga ascii""" + return { + 'file': '', + 'name': '', + 'amiga': True, + 'filetype': 'plain', + 'width': '80', + 'author': '', + 'font': 'Propaz', + 'color': [250, 250, 250, 255], + 'bg': [0, 0, 0, 255], + 'line1': '', + 'line2': '', + 'text': '' + } + # ---------------------------------------------------------------------- + + def blank_ansi(self): + """blank PC Ansi""" + return { + 'file': '', + 'name': '', + 'amiga': False, + 'filetype': 'ansi', + 'width': '80', + 'author': '', + 'font': 'Propaz', + 'color': [255, 255, 255, 255], + 'bg': [0, 0, 0, 255], + 'line1': '', + 'line2': '', + 'text': '' + } + + def blank_filedata(self): + """Blank filedata structure""" + + filedata = { + 'file': '', + 'name': '', + 'amiga': False, + 'filetype': 'image', + 'width': '', + 'author': '', + 'font': 'Propaz', + 'color': [0, 0, 0, 255], + 'bg': [255, 255, 255, 255], + 'line1': '', + 'line2': '', + 'text': '' + } + return filedata diff --git a/sauce.py b/sauce.py new file mode 100644 index 0000000..00a6408 --- /dev/null +++ b/sauce.py @@ -0,0 +1,510 @@ +#! /usr/bin/env python +# +# _______ +# ____________ _______ _\__ /_________ ___ _____ +# | _ _ \ _ | ____\ _ / | |/ _ \ +# | / / / / | | | /___/ _ | | / / +# |___/___/ /___/____|________|___ | |_| |___|_____/ +# \__/ |___| +# +# (c) 2006-2012 Wijnand Modderman-Lenstra - https://maze.io/ +# + +''' +Parser for SAUCE or Standard Architecture for Universal Comment Extensions. +''' + +__author__ = 'Wijnand Modderman-Lenstra ' +__copyright__ = '(C) 2006-2012 Wijnand Modderman-Lenstra' +__license__ = 'LGPL' +__version__ = '1.2' +__url__ = 'https://github.com/tehmaze/sauce' + +import datetime +import os +import struct +try: + from io import StringIO +except ImportError: + from io import StringIO + + +class SAUCE(object): + ''' + Parser for SAUCE or Standard Architecture for Universal Comment Extensions, + as defined in http://www.acid.org/info/sauce/s_spec.htm. + + :param filename: file name or file handle + :property author: Name or 'handle' of the creator of the file + :property datatype: Type of data + :property date: Date the file was created + :property filesize: Original filesize NOT including any information of + SAUCE + :property group: Name of the group/company the creator is employed by + :property title: Title of the file + + Example:: + + >>> art = open('31337.ANS', 'rb') + >>> nfo = sauce.SAUCE(art) + >>> nfo.author + 'maze' + ... + >>> nfo.group + '' + >>> nfo.group = 'mononoke' + >>> raw = str(nfo) + + Saving the new file:: + + >>> sav = open('31337.NEW', 'wb') + >>> nfo.write(sav) + >>> # OR you can do: + >>> sav = nfo.write('31337.NEW') + + ''' + + # template + template = ( + # name default size type + ('SAUCE', 'SAUCE', 5, '5s'), + ('SAUCEVersion', '00', 2, '2s'), + ('Title', '\x00' * 35, 35, '35s'), + ('Author', '\x00' * 20, 20, '20s'), + ('Group', '\x00' * 20, 20, '20s'), + ('Date', '\x00' * 8, 8, '8s'), + ('FileSize', [0], 4, 'I'), + ('DataType', [0], 1, 'B'), + ('FileType', [0], 1, 'B'), + ('TInfo1', [0], 2, 'H'), + ('TInfo2', [0], 2, 'H'), + ('TInfo3', [0], 2, 'H'), + ('TInfo4', [0], 2, 'H'), + ('Comments', [0], 1, 'B'), + ('Flags', [0], 1, 'B'), + ('Filler', ['\x00'] * 22, 22, '22c'), + ) + templates = [t[0] for t in template] + datatypes = ['None', 'Character', 'Graphics', 'Vector', 'Sound', + 'BinaryText', 'XBin', 'Archive', 'Executable'] + filetypes = { + 'None': { + 'filetype': ['Undefined'], + }, + 'Character': { + 'filetype': ['ASCII', 'ANSi', 'ANSiMation', 'RIP', 'PCBoard', + 'Avatar', 'HTML', 'Source'], + 'flags': {0: 'None', 1: 'iCE Color'}, + 'tinfo': ( + ('width', 'height', None, None), + ('width', 'height', None, None), + ('width', 'height', None, None), + ('width', 'height', 'colors', None), + ('width', 'height', None, None), + ('width', 'height', None, None), + (None, None, None, None), + ), + }, + 'Graphics': { + 'filetype': ['GIF', 'PCX', 'LBM/IFF', 'TGA', 'FLI', 'FLC', + 'BMP', 'GL', 'DL', 'WPG', 'PNG', 'JPG', 'MPG', + 'AVI'], + 'tinfo': (('width', 'height', 'bpp')) * 14, + }, + 'Vector': { + 'filetype': ['DX', 'DWG', 'WPG', '3DS'], + }, + 'Sound': { + 'filetype': ['MOD', '669', 'STM', 'S3M', 'MTM', 'FAR', 'ULT', + 'AMF', 'DMF', 'OKT', 'ROL', 'CMF', 'MIDI', 'SADT', + 'VOC', 'WAV', 'SMP8', 'SMP8S', 'SMP16', 'SMP16S', + 'PATCH8', 'PATCH16', 'XM', 'HSC', 'IT'], + 'tinfo': ((None,)) * 16 + (('Sampling Rate',)) * 4, + }, + 'BinaryText': { + 'flags': {0: 'None', 1: 'iCE Color'}, + }, + 'XBin': { + 'tinfo': (('width', 'height'),), + }, + 'Archive': { + 'filetype': ['ZIP', 'ARJ', 'LZH', 'ARC', 'TAR', 'ZOO', 'RAR', + 'UC2', 'PAK', 'SQZ'], + }, + } + + def __init__(self, filename='', data=''): + assert (filename or data), 'Need either filename or record' + + if filename: + # if type(filename) == file: + # self.filehand = filename + # else: + self.filehand = open(filename, 'rb') + self._size = os.path.getsize(self.filehand.name) + else: + self._size = len(data) + self.filehand = StringIO(data) + + self.record, self.data = self._read() + + def __str__(self): + return ''.join(list(self._read_file())) + + def _read_file(self): + # Buffered reader (generator), reads the original file without SAUCE + # record. + self.filehand.seek(0) + # Check if we have SAUCE data + if self.record: + reads, rest = divmod(self._size - 128, 1024) + else: + reads, rest = divmod(self._size, 1024) + for x in range(0, reads): + yield self.filehand.read(1024) + if rest: + yield self.filehand.read(rest) + + def _read(self): + if self._size >= 128: + self.filehand.seek(self._size - 128) + record = self.filehand.read(128) + if record.startswith(b'SAUCE'): + self.filehand.seek(0) + return record, self.filehand.read(self._size - 128) + + self.filehand.seek(0) + return None, self.filehand.read() + + def _gets(self, key): + if self.record is None: + return None + + name, default, offset, size, stype = self._template(key) + data = self.record[offset:offset + size] + data = struct.unpack(stype, data) + if stype[-1] in 'cs': + # return ''.join(data) + return data[0].decode() + elif stype[-1] in 'BI' and len(stype) == 1: + return data[0] + else: + return data + + def _puts(self, key, data): + name, default, offset, size, stype = self._template(key) + #print offset, size, data, repr(struct.pack(stype, data)) + if self.record is None: + self.record = self.sauce() + self.record = ''.join([ + self.record[:offset], + struct.pack(stype, data), + self.record[offset + size:] + ]) + return self.record + + def _template(self, key): + index = self.templates.index(key) + name, default, size, stype = self.template[index] + offset = sum([self.template[x][2] for x in range(0, index)]) + return name, default, offset, size, stype + + def sauce(self): + ''' + Get the raw SAUCE record. + ''' + if self.record: + return self.record + else: + data = 'SAUCE' + for name, default, size, stype in self.template[1:]: + #print stype, default + if stype[-1] in 's': + data += struct.pack(stype, default) + else: + data += struct.pack(stype, *default) + return data + + def write(self, filename): + ''' + Save the file including SAUCE data to the given file(handle). + ''' + filename = type(filename) == file and filename or open( + filename, 'wb') + for part in self._read_file(): + filename.write(part) + filename.write(self.sauce()) + return filename + + # SAUCE meta data + + def get_author(self): + astr = self._gets('Author') + if astr is not None: + return astr.strip() + else: + return '' + + def set_author(self, author): + self._puts('Author', author) + return self + + def get_comments(self): + return self._gets('Comments') + + def set_comments(self, comments): + self._puts('Comments', comments) + return self + + def get_datatype(self): + return self._gets('DataType') + + def get_datatype_str(self): + datatype = self.datatype + if datatype is None: + return None + if datatype < len(self.datatypes): + return self.datatypes[datatype] + else: + return None + + def set_datatype(self, datatype): + if type(datatype) == str: + datatype = datatype.lower().title() # fOoBAR -> Foobar + datatype = self.datatypes.index(datatype) + self._puts('DataType', datatype) + return self + + def get_date(self): + return self._gets('Date') + + def get_date_str(self, format='%Y%m%d'): + return datetime.datetime.strptime(self.date, format) + + def set_date(self, date=None, format='%Y%m%d'): + if date is None: + date = datetime.datetime.now().strftime(format) + elif type(date) in [datetime.date, datetime.datetime]: + date = date.strftime(format) + elif type(date) in [int, int, float]: + date = datetime.datetime.fromtimestamp(date).strftime(format) + self._puts('Date', date) + return self + + def get_filesize(self): + return self._gets('FileSize') + + def set_filesize(self, size): + self._puts('FileSize', size) + + def get_filler(self): + return self._gets('Filler') + + def get_filler_str(self): + filler = self._gets('Filler') + if filler is None: + return '' + else: + return filler.rstrip('\x00') + + def get_filetype(self): + return self._gets('FileType') + + def get_filetype_str(self): + datatype = self.datatype_str + filetype = self.filetype + + if datatype is None or filetype is None: + return None + + if datatype in self.filetypes and \ + 'filetype' in self.filetypes[datatype] and \ + filetype < len(self.filetypes[datatype]['filetype']): + return self.filetypes[datatype]['filetype'][filetype] + else: + return None + + def set_filetype(self, filetype): + datatype = self.datatype_str + if type(filetype) == str: + filetype = filetype.lower().title() # fOoBAR -> Foobar + filetype = [name.lower().title() + for name in self.filetypes[datatype]['filetype']].index(filetype) + self._puts('FileType', filetype) + return self + + def get_flags(self): + return self._gets('Flags') + + def set_flags(self, flags): + self._puts('Flags', flags) + return self + + def get_flags_str(self): + datatype = self.datatype_str + filetype = self.filetype + + if datatype is None or filetype is None: + return None + + if datatype in self.filetypes and \ + 'flags' in self.filetypes[datatype] and \ + filetype < len(self.filetypes[datatype]['filetype']): + return self.filetypes[datatype]['filetype'][filetype] + else: + return None + + def get_group(self): + gstr = self._gets('Group') + if gstr is not None: + return gstr.strip() + else: + return '' +# return self._gets('Group').strip() + + def set_group(self, group): + self._puts('Group', group) + return self + + def _get_tinfo_name(self, i): + datatype = self.datatype_str + filetype = self.filetype + + if datatype is None or filetype is None: + return None + + try: + return self.filetypes[datatype]['tinfo'][filetype][i - 1] + except (KeyError, IndexError): + return '' + + def get_tinfo1(self): + tinfo = self._gets('TInfo1') + if tinfo is not None: + return tinfo[0] + else: + return '' + + def get_tinfo1_name(self): + return self._get_tinfo_name(1) + + def set_tinfo1(self, tinfo): + self._puts('TInfo1', tinfo) + return self + + def get_tinfo2(self): + tinfo = self._gets('TInfo2') + if tinfo is not None: + return tinfo[0] + else: + return '' + + def get_tinfo2_name(self): + return self._get_tinfo_name(2) + + def set_tinfo2(self, tinfo): + self._puts('TInfo2', tinfo) + return self + + def get_tinfo3(self): + tinfo = self._gets('TInfo3') + if tinfo is not None: + return tinfo[0] + return '' + + def get_tinfo3_name(self): + return self._get_tinfo_name(3) + + def set_tinfo3(self, tinfo): + self._puts('TInfo3', tinfo) + return self + + def get_tinfo4(self): + tinfo = self._gets('TInfo4') + if tinfo is not None: + return tinfo[0] + return '' + + def get_tinfo4_name(self): + return self._get_tinfo_name(4) + + def set_tinfo4(self, tinfo): + self._puts('TInfo4', tinfo) + return self + + def get_title(self): + tstr = self._gets('Title') + if tstr is not None: + return tstr.strip() + else: + return '' +# return self._gets('Title').strip() + + def set_title(self, title): + self._puts('Title', title) + return self + + def get_version(self): + return self._gets('SAUCEVersion') + + def set_version(self, version): + self._puts('SAUCEVersion', version) + return self + + # properties + author = property(get_author, set_author) + comments = property(get_comments, set_comments) + datatype = property(get_datatype, set_datatype) + datatype_str = property(get_datatype_str) + date = property(get_date, set_date) + filesize = property(get_filesize, set_filesize) + filetype = property(get_filetype, set_filetype) + filetype_str = property(get_filetype_str) + filler = property(get_filler) + filler_str = property(get_filler_str) + flags = property(get_flags, set_flags) + flags_str = property(get_flags_str) + group = property(get_group, set_group) + tinfo1 = property(get_tinfo1, set_tinfo1) + tinfo1_name = property(get_tinfo1_name) + tinfo2 = property(get_tinfo2, set_tinfo2) + tinfo2_name = property(get_tinfo2_name) + tinfo3 = property(get_tinfo3, set_tinfo3) + tinfo3_name = property(get_tinfo3_name) + tinfo4 = property(get_tinfo4, set_tinfo4) + tinfo4_name = property(get_tinfo4_name) + title = property(get_title, set_title) + version = property(get_version) + + +if __name__ == '__main__': + import sys + if len(sys.argv) != 2: + print('%s ' % (sys.argv[0],), file=sys.stderr) + sys.exit(1) + else: + test = SAUCE(sys.argv[1]) + + def show(sauce): + print('Version.:', sauce.version) + print('Title...:', sauce.title) + print('Author..:', sauce.author) + print('Group...:', sauce.group) + print('Date....:', sauce.date) + print('FileSize:', sauce.filesize) + print('DataType:', sauce.datatype, sauce.datatype_str) + print('FileType:', sauce.filetype, sauce.filetype_str) + print('TInfo1..:', sauce.tinfo1) + print('TInfo2..:', sauce.tinfo2) + print('TInfo3..:', sauce.tinfo3) + print('TInfo4..:', sauce.tinfo4) + print('Flags...:', sauce.flags, sauce.flags_str) + print('Record..:', len(sauce.record), repr(sauce.record)) + print('Filler..:', sauce.filler_str) + + if test.record: + show(test) + else: + print('No SAUCE record found') + test = SAUCE(data=test.sauce()) + show(test) diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..fe18ef9 --- /dev/null +++ b/setup.py @@ -0,0 +1,15 @@ +#!/usr/bin/env python +# coding:utf-8 +""" + Author: Sir Garbagetruck -- + Purpose: setup script for Sahli editor tools + Created: 2020/04/09 +""" + +from setuptools import setup, find_packages + +setup( + name="SahliEditor", + version="0.1", + packages=find_packages() +) diff --git a/testshow/AD - Green Beam.scaled.png b/testshow/AD - Green Beam.scaled.png new file mode 100644 index 0000000..fbecb25 Binary files /dev/null and b/testshow/AD - Green Beam.scaled.png differ diff --git a/testshow/om-boss.png b/testshow/om-boss.png new file mode 100644 index 0000000..e3abd45 Binary files /dev/null and b/testshow/om-boss.png differ diff --git a/todo.txt b/todo.txt index f26a2e7..f29534b 100644 --- a/todo.txt +++ b/todo.txt @@ -7,3 +7,4 @@ (C) SAHLI ansi & ascii for load page (C) redo load page (not popup, info) (B) Preload +(C) Chrome app