def init(config={}):
    global cfg, printer, fd, num_axes, num_buttons, dead
    if cfg is not None:
        return
    configdata = {
        'tick_time': .05,
        'js': '/dev/input/js0',
        'printer': '8000',
        'dead': .1
    }
    configdata.update(config)
    cfg = fhs.init(configdata)
    dead = float(cfg['dead'])
    printer = websocketd.RPC(cfg['printer'], tls=False)
    fd = os.open(cfg['js'], os.O_RDWR)

    version = ioctl(js.gversion, ctypes.c_uint32)
    if version != js.version:
        sys.stderr.write('version mismatch (%x != %x)' % (version, js.version))

    num_axes = ioctl(js.gaxes, ctypes.c_uint8)
    num_buttons = ioctl(js.gbuttons, ctypes.c_uint8)

    axis_state[:] = [0.] * num_axes
    button_state[:] = [None] * num_buttons
Example #2
0
		def _tls_init(self):
			# Set up members for using tls, if requested.
			if self.tls in (False, '-'):
				self.tls = False
				return
			if self.tls in (None, True, ''):
				self.tls = fhs.init(packagename = 'network', config = {'tls': ''}, argv = os.getenv('NETWORK_OPTS', '').split())['tls']
			if self.tls == '':
				self.tls = socket.getfqdn()
			elif self.tls == '-':
				self.tls = False
				return
			# Use tls.
			fc = fhs.read_data(os.path.join('certs', self.tls + os.extsep + 'pem'), opened = False, packagename = 'network')
			fk = fhs.read_data(os.path.join('private', self.tls + os.extsep + 'key'), opened = False, packagename = 'network')
			if fc is None or fk is None:
				# Create new self-signed certificate.
				certfile = fhs.write_data(os.path.join('certs', self.tls + os.extsep + 'pem'), opened = False, packagename = 'network')
				csrfile = fhs.write_data(os.path.join('csr', self.tls + os.extsep + 'csr'), opened = False, packagename = 'network')
				for p in (certfile, csrfile):
					path = os.path.dirname(p)
					if not os.path.exists(path):
						os.makedirs(path)
				keyfile = fhs.write_data(os.path.join('private', self.tls + os.extsep + 'key'), opened = False, packagename = 'network')
				path = os.path.dirname(keyfile)
				if not os.path.exists(path):
					os.makedirs(path, 0o700)
				os.system('openssl req -x509 -nodes -days 3650 -newkey rsa:4096 -subj "/CN=%s" -keyout "%s" -out "%s"' % (self.tls, keyfile, certfile))
				os.system('openssl req -subj "/CN=%s" -new -key "%s" -out "%s"' % (self.tls, keyfile, csrfile))
				fc = fhs.read_data(os.path.join('certs', self.tls + os.extsep + 'pem'), opened = False, packagename = 'network')
				fk = fhs.read_data(os.path.join('private', self.tls + os.extsep + 'key'), opened = False, packagename = 'network')
			self.tls_cert = fc
			self.tls_key = fk
Example #3
0
def init(config = {}):
	global cfg, printer, fd, num_axes, num_buttons, dead
	if cfg is not None:
		return
	configdata = {'tick_time': .05, 'js': '/dev/input/js0', 'printer': '8000', 'dead': .1}
	configdata.update(config)
	cfg = fhs.init(configdata)
	dead = float(cfg['dead'])
	printer = websocketd.RPC(cfg['printer'], tls = False)
	fd = os.open(cfg['js'], os.O_RDWR)

	version = ioctl(js.gversion, ctypes.c_uint32)
	if version != js.version:
		sys.stderr.write('version mismatch (%x != %x)' % (version, js.version))

	num_axes = ioctl(js.gaxes, ctypes.c_uint8)
	num_buttons = ioctl(js.gbuttons, ctypes.c_uint8)

	axis_state[:] = [0.] * num_axes
	button_state[:] = [None] * num_buttons
Example #4
0
#!/usr/bin/python3

from PIL import Image
import fhs
import binascii

config = fhs.init({'src': None, 'dpmm': 10, 'speed': 5, 'margin': 10})
im = Image.open(config['src']).convert(mode='1', dither=Image.FLOYDSTEINBERG)
data = im.getdata()

h, w = im.size
print(';size: %d,%d' % (w, h))
print('G1 F%f' % (config['speed'] * 60))
for y in range(h):
    line = b''
    # The full range is w/16, rounded up. That is (w+15)//16. Add one bit to make sure the laser is turned off at the end of the line. That makes it (w+16)//16 == w//16+1.
    for x in range(w // 16 + 1):
        for x2 in (0, 8):
            d = 0
            for bit in range(8):
                b = data[y * w + x + x2 + bit] and 1 if x + x2 + bit < w else 0
                d |= b << bit
            line += bytes((d, ))
    code = binascii.b2a_base64(line).strip().decode('utf-8', 'replace')
    print('G1 X%f Y%f' % (-config['margin'], y / config['dpmm']))
    print('G1 X0')
    print('G1 X%f ;PATTERN:%s' % (w / config['dpmm'], code))
    print('G1 X%f' % (w / config['dpmm'] + config['margin']))
    print('G1 X0 Y0')
Example #5
0
import json
import traceback
import fcntl
import protocol

config = fhs.init(
    packagename='franklin',
    config={
        'port': '8000',
        'address': '',
        'printer': '',
        'blacklist': '/dev/(input/.*|ptmx|console|tty(printk|(S|GS)?\\d*))$',
        'add-blacklist': '$',
        'autodetect': 'True',
        'predetect':
        'stty -F #PORT# raw 115200 -echo -echoe -echok -echoke -echonl -echoprt',
        'atexit': '',
        'allow-system': '^$',
        'admin': '',
        'expert': '',
        'user': '',
        'done': '',
        'local': '',
        'log': '',
        'tls': 'True',
    })
# }}}

# Global variables. {{{
httpd = None
default_printer = (None, None)
Example #6
0
	it switches a lot) which turns the motor on when active.

	The sewing machine should be set up with very low pressure on the foot,
	so the fabric can move underneath it without lifting the foot.  If
	possible, there should be no transport from below.  The stitch width
	and length should be set to 0.

Make sure that the embroidery loop moves properly over the surface of the
sewing machine.
"""

import websocketd
import time
import fhs

config = fhs.init({'port': 8000, 'tls': 'False', 'motor': 3, 'sensor': 4})
motor = int(config['motor'])
sensor = int(config['sensor'])
tls = config['tls'].lower() != 'false'

p = websocketd.RPC(config['port'], tls=tls)
'''
Procedure:
	-> wait for confirm
	motor on
	needle down -> wait for gpio off
	needle up -> wait for gpio on
	motor off
	-> confirm
	Franklin moves
	repeat
Example #7
0
import protocol

config = fhs.init(
    packagename='franklin',
    config={
        'port': '8000',  # Port to listen on.
        'address':
        '',  # Address to listen on.  Mainly intended for RPi, which cannot handle IPv6 and needs 0.0.0.0 here to force IPv4.
        'blacklist':
        '/dev/(input/.*|ptmx|console|tty(printk|(GS)?\\d*))$',  # Which serial ports to refuse detecting on.
        'add-blacklist':
        '$',  # Which serial ports to additionally refuse detecting on.  Used to add ports to the list without losing the defaults.
        'autodetect':
        True,  # Whether new machines are autodetected on new ports, and after flashing.
        'predetect':
        'stty -F $PORT raw 115200 -echo -echoe -echok -echoke -echonl -echoprt',  # What to do to a port before detecting a machine.
        'controller':
        '/usr/lib/franklin/controller.py --dev "$PORT"',  # How to start a controller subprocess
        'allow-system':
        '^$',  # Which commands are allowed through system comments in G-Code.
        'admin': '',  # Admin password; defaults to expert password.
        'expert': '',  # Expert password; defaults to user password.
        'user': '',  # User password; defaults to no password.
        'done': '',  # Program to run when a job is done.
        'log': '',  # Enable logging to a given logfile.
        'tls':
        'False',  # Whether TLS is used on the network connection.  If using Apache's virtual proxy method, this must be False, because Apache handles the encryption.
        'arc':
        False,  # Whether arc detection in G-Code is enabled.  This is False by default, because it is broken.
    })
# }}}
Example #8
0
#!/usr/bin/python3

from PIL import Image
import fhs
import binascii

config = fhs.init({'src': None, 'dpmm': 10, 'speed': 5, 'margin': 10})
im = Image.open(config['src']).convert(mode = '1', dither = Image.FLOYDSTEINBERG)
data = im.getdata()

h, w = im.size
print(';size: %d,%d' % (w, h))
print('G1 F%f' % (config['speed'] * 60))
for y in range(h):
	line = b''
	# The full range is w/16, rounded up. That is (w+15)//16. Add one bit to make sure the laser is turned off at the end of the line. That makes it (w+16)//16 == w//16+1.
	for x in range(w // 16 + 1):
		for x2 in (0, 8):
			d = 0
			for bit in range(8):
				b = data[y * w + x  + x2 + bit] and 1 if x + x2 + bit < w else 0
				d |= b << bit
			line += bytes((d,))
	code = binascii.b2a_base64(line).strip().decode('utf-8', 'replace')
	print('G1 X%f Y%f' % (-config['margin'], y / config['dpmm']))
	print('G1 X0')
	print('G1 X%f ;PATTERN:%s' % (w / config['dpmm'], code))
	print('G1 X%f' % (w / config['dpmm'] + config['margin']))
	print('G1 X0 Y0')
Example #9
0
fhs.option('controller',
           'Run this command to handle a controller on a serial port',
           default='/usr/lib/franklin/controller.py --dev "$PORT"')
fhs.option('allow-system',
           'Only allow system commands that match this regular expression',
           default='^$')
fhs.option('admin', 'Admin password', default='')
fhs.option('expert', 'Expert user password', default='')
fhs.option('user', 'Local user password', default='')
fhs.option('remote', 'Remote user password', default='')
fhs.option('done', 'Run this command when a job is done', default='')
fhs.option('log', 'Enable logging to a given logfile')
fhs.option('tls',
           'Enable TLS. It is recommended to let Apache handle this',
           argtype=bool)
config = fhs.init(packagename='franklin')
# }}}

# Global variables. {{{
httpd = None
ports = {}
autodetect = not config['noautodetect']
tls = config['tls']
machines = {}
log('whitelist: %s' % config['whitelist'])
# }}}


class Server(websocketd.RPChttpd):  # {{{
    def auth_message(self, connection, is_websocket):
        path = connection.address.path
Example #10
0
        data[spot] = item
        objects.remove(item)
        accessible.add(item)

    for item_addr, check_addr in drop_addrs:
        item = data[item_addr + itemoffset]
        data[check_addr +
             codeoffset] = 0x20 + item - 1 if item < 8 else 0xa0 + item - 8 - 1
    return data


try:
    import fhs
    import websocketd

    config = fhs.init({'port': 9999})

    server = websocketd.Httpd(config['port'],
                              None,
                              httpdirs=['html'],
                              tls=False)

    def new_page(connection, path=None):
        if connection.address.path != '/random.rom':
            return default_page(connection, path)
        args = {}
        for arg in ('initial', 'silencer', 'card7', 'card8', 'drops', 'bag'):
            args[arg] = arg not in connection.query or connection.query[arg][
                0].lower() not in ('0', 'false')
        if 'rom' in connection.query:
            args['rom'] = connection.query['rom'][0]
Example #11
0
import serial
import json
import traceback
import fcntl
import protocol

config = fhs.init(packagename = 'franklin', config = {
		'port': '8000',	# Port to listen on.
		'address': '',	# Address to listen on.  Mainly intended for RPi, which cannot handle IPv6 and needs 0.0.0.0 here to force IPv4.
		'whitelist': r'', # Which serial ports to attempt detecting on. Ports that are both whitelisted and blacklisted are not included.
		'blacklist': r'/dev/(input/.*|ptmx|console|tty(printk|(GS)?\d*))$', # Which serial ports to refuse detecting on.
		'add-blacklist': r'$',	# Which serial ports to additionally refuse detecting on.  Used to add ports to the list without losing the defaults.
		'autodetect': True,	# Whether new machines are autodetected on new ports, and after flashing.
		'predetect': 'stty -F $PORT raw 115200 -echo -echoe -echok -echoke -echonl -echoprt',	# What to do to a port before detecting a machine.
		'controller': '/usr/lib/franklin/controller.py --dev "$PORT"',	# How to start a controller subprocess
		'allow-system': '^$',	# Which commands are allowed through system comments in G-Code.
		'admin': '',	# Admin password.
		'expert': '',	# Expert password.
		'user': '',	# User password.
		'remote': '',	# Remote password.
		'done': '',	# Program to run when a job is done.
		'log': '',	# Enable logging to a given logfile.
		'tls': 'False',	# Whether TLS is used on the network connection.  If using Apache's virtual proxy method, this must be False, because Apache handles the encryption.
		'arc': False,	# Whether arc detection in G-Code is enabled.  This is False by default, because it is broken.
	})
# }}}

# Global variables. {{{
httpd = None
ports = {}
autodetect = config['autodetect']
Example #12
0
		add_item(data, 0 if extreme else item, spots, item_offset, code_offset, items[spot])
		found.add(item)
	for i in all_items:
		add_item(data, 0 if extreme else i, spots, item_offset, code_offset)
		found.add(i)
	while len(spots) > 0:
		add_item(data, 0 if extreme else default_item(), spots, item_offset, code_offset)
	return bytes(data)
# }}}

try:
	import fhs
	import websocketd

	fhs.option('port', 'port to listen on', default = '9999')
	config = fhs.init()

	server = websocketd.Httpd(config['port'], None, httpdirs = ['html'], tls = False)

	def new_page(connection, path = None):
		if connection.address.path != '/random.rom':
			return default_page(connection, path)
		close_doors = None if 'doors' not in connection.query or connection.query['doors'][-1] == 'keep' else True if connection.query['doors'][-1] == 'close' else False
		show_doors = 'showdoor' in connection.query and connection.query['showdoor'][-1].lower() == 'true'
		extreme = 'extreme' in connection.query and connection.query['extreme'][-1].lower() == 'true'
		print(connection.query, close_doors, show_doors, extreme)
		data = randomize(connection.query['rom'][0] if 'rom' in connection.query else None, close_doors, show_doors, extreme)
		return server.reply(connection, 200, bytes(data), 'application/octet-stream')

	default_page = server.page
	server.page = new_page
Example #13
0
import time
import serial
import json
import traceback
import fcntl
import protocol

config = fhs.init(packagename = 'franklin', config = {
		'port': '8000',
		'address': '',
		'printer': '',
		'blacklist': '/dev/(input/.*|ptmx|console|tty(printk|(S|GS)?\\d*))$',
		'add-blacklist': '$',
		'autodetect': 'True',
		'predetect': 'stty -F #PORT# raw 115200 -echo -echoe -echok -echoke -echonl -echoprt',
		'atexit': '',
		'allow-system': '^$',
		'admin': '',
		'expert': '',
		'user': '',
		'done': '',
		'local': '',
		'log': '',
		'tls': 'True',
	})
# }}}

# Global variables. {{{
httpd = None
default_printer = (None, None)
ports = {}
autodetect = config['autodetect'].lower() == 'true'
Example #14
0
def Game(): # Main function to start a game. {{{
	global server, title_game, have_2d, have_3d, _num_players
	# Set up the game name.
	if not hasattr(__main__, 'name') or __main__.name is None:
		__main__.name = os.path.basename(sys.argv[0]).capitalize()
	# Initialize fhs module.
	if not fhs.initialized:
		fhs.init({}, packagename = __main__.name.lower(), game = True)
	# Set up other constants.
	if not hasattr(__main__, 'autokill'):
		__main__.autokill = True
	have_2d = fhs.read_data(os.path.join('html', '2d'), dir = True, opened = False) is not None
	have_3d = fhs.read_data(os.path.join('html', '3d'), dir = True, opened = False) is not None or not have_2d
	# Fill in min and max if not specified.
	assert hasattr(__main__, 'num_players')
	if isinstance(__main__.num_players, int):
		_num_players = (__main__.num_players, __main__.num_players)
	else:
		_num_players = __main__.num_players
	assert 1 <= _num_players[0] and (_num_players[1] is None or _num_players[0] <= _num_players[1])
	# Build asset string for inserting in js.
	for subdir, use_3d in (('2d', False), ('3d', True)):
		targets = []
		for base in ('img', 'jta', 'gani', 'audio', 'text'):
			for d in (os.path.join('html', base), os.path.join('html', subdir, base)):
				for p in fhs.read_data(d, dir = True, multiple = True, opened = False):
					targets.extend(f.encode('utf-8') for f in os.listdir(p) if not f.startswith('.') and not os.path.isdir(os.path.join(p, f)))
		if len(targets) > 0:
			loader_js[use_3d] = b'\n'.join(b"\tplease.load('" + f + b"');" for f in targets)
		else:
			# Nothing to load, but force the "finished loading" event to fire anyway.
			loader_js[use_3d] = b'\twindow.dispatchEvent(new CustomEvent("mgrl_media_ready"));'
	# Set up commands.
	cmds['leave'] = {None: leave}
	if hasattr(__main__, 'commands'):
		for c in __main__.commands:
			cmds[c] = {None: __main__.commands[c]}
	# Start up websockets server.
	config = fhs.module_get_config('webgame')
	httpdirs = [fhs.read_data(x, opened = False, multiple = True, dir = True) for x in ('html', os.path.join('html', '2d'), os.path.join('html', '3d'))]
	server = websocketd.RPChttpd(config['port'], Connection, tls = config['tls'], httpdirs = httpdirs[0] + httpdirs[1] + httpdirs[2])
	server.handle_ext('png', 'image/png')
	server.handle_ext('jpg', 'image/jpeg')
	server.handle_ext('jpeg', 'image/jpeg')
	server.handle_ext('gif', 'image/gif')
	server.handle_ext('gani', 'text/plain')
	server.handle_ext('wav', 'audio/wav')
	server.handle_ext('ogg', 'audio/ogg')
	server.handle_ext('mp3', 'audio/mp3')
	server.handle_ext('jta', 'application/octet-stream')
	server.handle_ext('txt', 'text/plain')
	server.handle_ext('frag', 'text/plain')
	server.handle_ext('vert', 'text/plain')
	server.handle_ext('glsl', 'text/plain')
	# Set up title page.
	if hasattr(__main__, 'Title'):
		title_game = Instance(__main__.Title, '')
	else:
		title_game = Instance(Title, '')
	log('Game "%s" started' % __main__.name)
	# Main loop.
	websocketd.fgloop()
Example #15
0
import traceback
import fcntl
import protocol

config = fhs.init(packagename = 'franklin', config = {
		'port': '8000',
		'address': '',
		'printer': '',
		'audiodir': '',
		'blacklist': '/dev/(input/.*|ptmx|console|tty(printk|(S|GS)?\\d*))$',
		'add-blacklist': '$',
		'autodetect': 'True',
		'predetect': 'stty -F #PORT# raw 115200',
		'atexit': '',
		'avrdude': '/usr/bin/avrdude',
		'allow-system': '^$',
		'admin': '',
		'expert': '',
		'user': '',
		'done': '',
		'local': '',
		'driver': '',
		'cdriver': '',
		'log': '',
		'tls': 'True',
		'avrdudeconfig': '/usr/lib/franklin/avrdude.conf'
	})
if config['audiodir'] == '':
	config['audiodir'] = fhs.write_cache(name = 'audio', dir = True),
if config['driver'] == '':
	config['driver'] = fhs.read_data('driver.py', opened = False)
Example #16
0
	it switches a lot) which turns the motor on when active.

	The sewing machine should be set up with very low pressure on the foot,
	so the fabric can move underneath it without lifting the foot.  If
	possible, there should be no transport from below.  The stitch width
	and length should be set to 0.

Make sure that the embroidery loop moves properly over the surface of the
sewing machine.
"""

import websocketd
import time
import fhs

config = fhs.init({'port': 8000, 'tls': 'False', 'motor': 3, 'sensor': 4})
motor = int(config['motor'])
sensor = int(config['sensor'])
tls = config['tls'].lower() != 'false'

p = websocketd.RPC(config['port'], tls = tls)

'''
Procedure:
	-> wait for confirm
	motor on
	needle down -> wait for gpio off
	needle up -> wait for gpio on
	motor off
	-> confirm
	Franklin moves
Example #17
0
# GNU Affero General Public License for more details.
# 
# You should have received a copy of the GNU Affero General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
# }}}

# Imports
import sys
import os
import Image
import pickle
import readini
import fhs

# Config.
config = fhs.init({'dinkdir': '/usr/share/games/dink/dink', 'dmoddir': os.path.join(fhs.HOME, 'dmods'), 'editdir': None, 'freedink': '/usr/bin/freedink'}, packagename = 'pydink')
dinkdir = os.path.realpath(config['dinkdir'])
dmoddir = os.path.realpath(config['dmoddir'])
editdir = os.path.realpath(config['editdir'])
freedink = os.path.realpath(config['freedink'])

fhs.save_config(config)
readini.setup(dinkdir)
savedir = fhs.write_cache(dir = True)

# Create data to be cached.
err = ''
try:
	harddata, harddefaults, tilefiles = readini.read_hard()
	tilefiles = [t[0] for t in tilefiles]
	collections, sequences, codes = readini.read_ini()