Reorganizing structure of project

Deleted /fs because it is the old version of the project and no longer used
Moved various notes and todos to /doc
Moved non-essential shell scripts from / to /shell_utils
Deleted /gpio_tests because they aren't used in the project
pull/45/head
Dan Puttick 6 years ago
parent d9b54ce295
commit dbf35536be
  1. 4
      README.md
  2. 0
      doc/MountNOOBS.md
  3. 0
      doc/NOTES
  4. 0
      doc/NOTES-RPI2
  5. 0
      doc/TODO
  6. 0
      doc/resize_img.md
  7. 0
      doc/tests_TODO.md
  8. 6
      fs/etc/fstab
  9. 54
      fs/etc/group
  10. 5
      fs/etc/pmount.allow
  11. 19
      fs/etc/profile.d/raspi-config.sh
  12. 36
      fs/etc/rc.local
  13. 1
      fs/etc/security/limits.conf
  14. 28
      fs/etc/sudoers
  15. 1
      fs/etc/udev/rules.d/50-blockhid.rules
  16. 2
      fs/etc/udev/rules.d/90-qemu.rules
  17. 23
      fs/opt/groomer/constraint.sh
  18. 4
      fs/opt/groomer/constraint_conv.sh
  19. 332
      fs/opt/groomer/functions.py
  20. 221
      fs/opt/groomer/functions.sh
  21. 68
      fs/opt/groomer/functions_pier9.py
  22. 122
      fs/opt/groomer/groomer.sh
  23. 149
      fs/opt/groomer/helpers.py
  24. 43
      fs/opt/groomer/init.sh
  25. 21
      fs/opt/groomer/music.sh
  26. 0
      fs_get_shell/etc/fstab
  27. 0
      fs_get_shell/etc/rc.local
  28. 47
      gpio_tests/test.py
  29. 0
      shell_utils/copy_force_shell.sh
  30. 0
      shell_utils/create_user.sh
  31. 0
      shell_utils/get_shell.exp
  32. 0
      shell_utils/get_shell.sh
  33. 0
      shell_utils/prepare_rPI.sh
  34. 0
      shell_utils/prepare_rPI_builder.sh
  35. 0
      shell_utils/update_PyCIRCLean.sh
  36. 0
      shell_utils/update_builder.sh

@ -6,9 +6,9 @@ CIRCLean
How To
======
[Graphical how-to and pre-build image](http://circl.lu/projects/CIRCLean/).
[Graphical how-to and pre-built image](http://circl.lu/projects/CIRCLean/).
To prepare the SD card on Windows, you can use [Win32DiskImager] (http://sourceforge.net/projects/win32diskimager/).
To prepare the SD card on Windows, you can use [Win32DiskImager](http://sourceforge.net/projects/win32diskimager/).
And the linux way is in the command line, via dd (see in copy_to_final.sh)

@ -1,6 +0,0 @@
proc /proc proc defaults 0 0
/dev/mmcblk0p1 /boot vfat ro,defaults 0 0
/dev/mmcblk0p2 / ext4 ro,defaults,noatime 0 0
tmpfs /tmp tmpfs rw,size=64M,noexec,nodev,nosuid,mode=1777 0 0
tmpfs /media tmpfs rw,size=64M,noexec,nodev,nosuid,mode=1777 0 0
# a swapfile is not a swap partition, so no using swapon|off from here on, use dphys-swapfile swap[on|off] for that

@ -1,54 +0,0 @@
root:x:0:
daemon:x:1:
bin:x:2:
sys:x:3:
adm:x:4:pi
tty:x:5:
disk:x:6:
lp:x:7:
mail:x:8:
news:x:9:
uucp:x:10:
man:x:12:
proxy:x:13:
kmem:x:15:
dialout:x:20:pi
fax:x:21:
voice:x:22:
cdrom:x:24:pi
floppy:x:25:
tape:x:26:
sudo:x:27:pi
audio:x:29:pi
dip:x:30:
www-data:x:33:
backup:x:34:
operator:x:37:
list:x:38:
irc:x:39:
src:x:40:
gnats:x:41:
shadow:x:42:
utmp:x:43:
video:x:44:pi
sasl:x:45:
plugdev:x:46:pi,kitten
staff:x:50:
games:x:60:pi
users:x:100:pi
nogroup:x:65534:
libuuid:x:101:
crontab:x:102:
pi:x:1000:
ssh:x:103:
ntp:x:104:
netdev:x:105:pi
input:x:999:pi
messagebus:x:106:
lpadmin:x:107:
fuse:x:108:
lightdm:x:109:
indiecity:x:1001:root
spi:x:1002:pi
gpio:x:1003:pi
kitten:x:1004:

@ -1,5 +0,0 @@
# /etc/pmount.allow
# pmount will allow users to additionally mount all devices that are
# listed here.
/dev/sdb1
/dev/sda*

@ -1,19 +0,0 @@
#!/bin/sh
# Part of raspi-config http://github.com/asb/raspi-config
#
# See LICENSE file for copyright and license details
# Should be installed to /etc/profile.d/raspi-config.sh to force raspi-config
# to run at initial login
# You may also want to set automatic login in /etc/inittab on tty1 by adding a
# line such as:
# 1:2345:respawn:/bin/login -f root tty1 </dev/tty1 >/dev/tty1 2>&1 # RPICFG_TO_DISABLE
if [ $(id -u) -ne 0 ]; then
printf "\nNOTICE: the software on this Raspberry Pi has not been fully configured. Please run 'sudo raspi-config'\n\n"
else
# Disable raspi-config at the first run.
# raspi-config
exec login -f pi
fi

@ -1,36 +0,0 @@
#!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.
clean(){
echo 'Rc Local done, quit.'
/sbin/shutdown -P -h now
}
# Print the IP address
_IP=$(hostname -I) || true
if [ "$_IP" ]; then
printf "My IP address is %s\n" "$_IP"
fi
if [ -e /dev/sda ]; then
if [ -e /dev/sdb ]; then
# avoid possible misuse
/sbin/ifconfig eth0 down
trap clean EXIT TERM INT
cd /opt/groomer
/usr/sbin/led &
./init.sh
fi
fi
exit 0

@ -1 +0,0 @@
kitten hard priority -20

@ -1,28 +0,0 @@
#
# This file MUST be edited with the 'visudo' command as root.
#
# Please consider adding local content in /etc/sudoers.d/ instead of
# directly modifying this file.
#
# See the man page for details on how to write a sudoers file.
#
Defaults env_reset
Defaults mail_badpass
Defaults secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
# Host alias specification
# User alias specification
# Cmnd alias specification
# User privilege specification
#root ALL=(ALL:ALL) ALL
# Allow members of group sudo to execute any command
#%sudo ALL=(ALL:ALL) ALL
# See sudoers(5) for more information on "#include" directives:
#includedir /etc/sudoers.d
#pi ALL=(ALL) NOPASSWD: ALL

@ -1 +0,0 @@
SUBSYSTEM=="hidraw", DRIVERS=="usbhid", RUN+="/bin/bash -c 'cd /sys/devices/platform/bcm2708_usb/usb1/1-1 ; for d in $(ls -d 1-1.[2-5]); do if [ $(ls -lR $d | grep -c usbhid) -gt 0 ] ; then echo 0 > $d/authorized ; fi ; done'"

@ -1,2 +0,0 @@
KERNEL=="sdc", SYMLINK+="mmcblk0"
KERNEL=="sdc?", SYMLINK+="mmcblk0p%n",

@ -1,23 +0,0 @@
DEV_SRC='/dev/sda'
DEV_DST='sdb1'
# User allowed to do the following commands without password
USERNAME='kitten'
MUSIC="/opt/midi/"
ID=`/usr/bin/id -u`
# Paths used in multiple scripts
SRC="src"
DST="dst"
TEMP="/media/${DST}/temp"
ZIPTEMP="/media/${DST}/ziptemp"
LOGS="/media/${DST}/logs"
# commands
SYNC='/bin/sync'
TIMIDITY='/usr/bin/timidity'
MOUNT='/bin/mount'
PMOUNT='/usr/bin/pmount -A -s'
PUMOUNT='/usr/bin/pumount'

@ -1,4 +0,0 @@
# Paths to the commands used to convert the files
PDF="/usr/bin/pdf2htmlEX"
LO="/usr/bin/libreoffice"
UNPACKER="/usr/bin/7z"

@ -1,332 +0,0 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import magic
import os
import mimetypes
import shlex
import subprocess
import time
from helpers import FileBase, KittenGroomerBase, main
UNOCONV = '/usr/bin/unoconv'
LIBREOFFICE = '/usr/bin/libreoffice'
GS = '/usr/bin/gs'
PDF2HTMLEX = '/usr/bin/pdf2htmlEX'
SEVENZ = '/usr/bin/7z'
# Prepare application/<subtype>
mimes_office = ['msword', 'vnd.openxmlformats-officedocument.', 'vnd.ms-',
'vnd.oasis.opendocument']
mimes_pdf = ['pdf']
mimes_xml = ['xml']
mimes_ms = ['x-dosexec']
mimes_compressed = ['zip', 'x-rar', 'x-bzip2', 'x-lzip', 'x-lzma', 'x-lzop',
'x-xz', 'x-compress', 'x-gzip', 'x-tar', 'compressed']
mimes_data = ['octet-stream']
class File(FileBase):
def __init__(self, src_path, dst_path):
''' Init file object, set the mimetype '''
super(File, self).__init__(src_path, dst_path)
mimetype = magic.from_file(src_path, mime=True)
self.main_type, self.sub_type = mimetype.split('/')
self.log_details.update({'maintype': self.main_type, 'subtype': self.sub_type})
self.expected_mimetype, self.expected_extensions = self.crosscheck_mime()
self.is_recursive = False
def crosscheck_mime(self):
'''
Set the expected mime and extension variables based on mime type.
'''
# /usr/share/mime has interesting stuff
# guess_type uses the extension to get a mime type
expected_mimetype, encoding = mimetypes.guess_type(self.src_path, strict=False)
if expected_mimetype is not None:
expected_extensions = mimetypes.guess_all_extensions(expected_mimetype,
strict=False)
else:
# the extension is unknown...
expected_extensions = None
return expected_mimetype, expected_extensions
def verify_extension(self):
'''Check if the extension is the one we expect'''
if self.expected_extensions is None:
return None
path, actual_extension = os.path.splitext(self.src_path)
return actual_extension in self.expected_extensions
def verify_mime(self):
'''Check if the mime is the one we expect'''
if self.expected_mimetype is None:
return None
actual_mimetype = '{}/{}'.format(self.main_type, self.sub_type)
return actual_mimetype == self.expected_mimetype
class KittenGroomer(KittenGroomerBase):
def __init__(self, root_src=None, root_dst=None, max_recursive=5):
'''
Initialize the basics of the conversion process
'''
if root_src is None:
root_src = os.path.join(os.sep, 'media', 'src')
if root_dst is None:
root_dst = os.path.join(os.sep, 'media', 'dst')
super(KittenGroomer, self).__init__(root_src, root_dst)
self.recursive = 0
self.max_recursive = max_recursive
subtypes_apps = [
(mimes_office, self._office_related),
(mimes_pdf, self._pdf),
(mimes_xml, self._office_related),
(mimes_ms, self._executables),
(mimes_compressed, self._archive),
(mimes_data, self._binary_app),
]
self.subtypes_application = self._init_subtypes_application(subtypes_apps)
self.mime_processing_options = {
'text': self.text,
'audio': self.audio,
'image': self.image,
'video': self.video,
'application': self.application,
'example': self.example,
'message': self.message,
'model': self.model,
'multipart': self.multipart,
'inode': self.inode,
}
# Dirty trick to run libreoffice at least once and avoid unoconv to crash...
self._run_process(LIBREOFFICE, 5)
# ##### Helpers #####
def _init_subtypes_application(self, subtypes_application):
'''
Create the Dict to pick the right function based on the sub mime type
'''
to_return = {}
for list_subtypes, fct in subtypes_application:
for st in list_subtypes:
to_return[st] = fct
return to_return
def _print_log(self):
'''
Print the logs related to the current file being processed
'''
tmp_log = self.log_name.fields(**self.cur_file.log_details)
if self.cur_file.log_details.get('dangerous'):
tmp_log.warning(self.cur_file.log_string)
elif self.cur_file.log_details.get('unknown') or self.cur_file.log_details.get('binary'):
tmp_log.info(self.cur_file.log_string)
else:
tmp_log.debug(self.cur_file.log_string)
def _run_process(self, command_line, timeout=0):
'''Run subprocess, wait until it finishes'''
if timeout != 0:
deadline = time.time() + timeout
else:
deadline = None
args = shlex.split(command_line)
p = subprocess.Popen(args)
while True:
code = p.poll()
if code is not None:
break
if deadline is not None and time.time() > deadline:
p.kill()
break
time.sleep(1)
return True
#######################
# ##### Discarded mime types, reason in the comments ######
def inode(self):
''' Usually empty file. No reason (?) to copy it on the dest key'''
self.cur_file.log_string += 'Inode file'
def unknown(self):
''' This main type is unknown, that should not happen '''
self.cur_file.log_string += 'Unknown file'
# ##### Threated as malicious, no reason to have it on a USB key ######
def example(self):
'''Way to process example file'''
self.cur_file.log_string += 'Example file'
self.cur_file.make_dangerous()
self._safe_copy()
def message(self):
'''Way to process message file'''
self.cur_file.log_string += 'Message file'
self.cur_file.make_dangerous()
self._safe_copy()
def model(self):
'''Way to process model file'''
self.cur_file.log_string += 'Model file'
self.cur_file.make_dangerous()
self._safe_copy()
def multipart(self):
'''Way to process multipart file'''
self.cur_file.log_string += 'Multipart file'
self.cur_file.make_dangerous()
self._safe_copy()
#######################
# ##### Converted ######
def text(self):
''' LibreOffice should be able to open all the files '''
self.cur_file.log_string += 'Text file'
self._office_related()
def application(self):
''' Everything can be there, using the subtype to decide '''
for subtype, fct in list(self.subtypes_application.items()):
if subtype in self.cur_file.sub_type:
fct()
self.cur_file.log_string += 'Application file'
return
self.cur_file.log_string += 'Unknown Application file'
self._unknown_app()
def _executables(self):
'''Way to process executable file'''
self.cur_file.add_log_details('processing_type', 'executable')
self.cur_file.make_dangerous()
self._safe_copy()
def _office_related(self):
'''Way to process all the files LibreOffice can handle'''
self.cur_file.add_log_details('processing_type', 'office')
dst_dir, filename = os.path.split(self.cur_file.dst_path)
tmpdir = os.path.join(dst_dir, 'temp')
name, ext = os.path.splitext(filename)
tmppath = os.path.join(tmpdir, name + '.pdf')
self._safe_mkdir(tmpdir)
lo_command = '{} --format pdf -eSelectPdfVersion=1 --output {} {}'.format(
UNOCONV, tmppath, self.cur_file.src_path)
self._run_process(lo_command)
self._pdfa(tmppath)
self._safe_rmtree(tmpdir)
def _pdfa(self, tmpsrcpath):
'''Way to process PDF/A file'''
pdf_command = '{} --dest-dir / {} {}'.format(PDF2HTMLEX, tmpsrcpath,
self.cur_file.dst_path + '.html')
self._run_process(pdf_command)
def _pdf(self):
'''Way to process PDF file'''
self.cur_file.add_log_details('processing_type', 'pdf')
dst_dir, filename = os.path.split(self.cur_file.dst_path)
tmpdir = os.path.join(dst_dir, 'temp')
tmppath = os.path.join(tmpdir, filename)
self._safe_mkdir(tmpdir)
gs_command = '{} -dPDFA -dBATCH -dNOPAUSE -sDEVICE=pdfwrite -sOutputFile={} {}'.format(
GS, tmppath, self.cur_file.src_path)
self._run_process(gs_command)
self._pdfa(tmppath)
self._safe_rmtree(tmpdir)
def _archive(self):
'''Way to process Archive'''
self.cur_file.add_log_details('processing_type', 'archive')
self.cur_file.is_recursive = True
self.cur_file.log_string += 'Archive extracted, processing content.'
tmpdir = self.cur_file.dst_path + '_temp'
self._safe_mkdir(tmpdir)
extract_command = '{} -p1 x {} -o{} -bd'.format(SEVENZ, self.cur_file.src_path, tmpdir)
self._run_process(extract_command)
self.recursive += 1
self.processdir(tmpdir, self.cur_file.dst_path)
self.recursive -= 1
self._safe_rmtree(tmpdir)
def _unknown_app(self):
'''Way to process an unknown file'''
self.cur_file.make_unknown()
self._safe_copy()
def _binary_app(self):
'''Way to process an unknown binary file'''
self.cur_file.make_binary()
self._safe_copy()
#######################
# ##### Not converted, checking the mime type ######
def audio(self):
'''Way to process an audio file'''
self.cur_file.log_string += 'Audio file'
self._media_processing()
def image(self):
'''Way to process an image'''
self.cur_file.log_string += 'Image file'
self._media_processing()
def video(self):
'''Way to process a video'''
self.cur_file.log_string += 'Video file'
self._media_processing()
def _media_processing(self):
'''Generic way to process all the media files'''
self.cur_log.fields(processing_type='media')
if not self.cur_file.verify_mime() or not self.cur_file.verify_extension():
# The extension is unknown or doesn't match the mime type => suspicious
# TODO: write details in the logfile
self.cur_file.make_dangerous()
self._safe_copy()
#######################
def processdir(self, src_dir=None, dst_dir=None):
'''
Main function doing the processing
'''
if src_dir is None:
src_dir = self.src_root_dir
if dst_dir is None:
dst_dir = self.dst_root_dir
if self.recursive > 0:
self._print_log()
if self.recursive >= self.max_recursive:
self.cur_log.warning('ARCHIVE BOMB.')
self.cur_log.warning('The content of the archive contains recursively other archives.')
self.cur_log.warning('This is a bad sign so the archive is not extracted to the destination key.')
self._safe_rmtree(src_dir)
if src_dir.endswith('_temp'):
archbomb_path = src_dir[:-len('_temp')]
self._safe_remove(archbomb_path)
for srcpath in self._list_all_files(src_dir):
self.cur_file = File(srcpath, srcpath.replace(src_dir, dst_dir))
self.log_name.info('Processing {} ({}/{})', srcpath.replace(src_dir + '/', ''),
self.cur_file.main_type, self.cur_file.sub_type)
self.mime_processing_options.get(self.cur_file.main_type, self.unknown)()
if not self.cur_file.is_recursive:
self._print_log()
if __name__ == '__main__':
main(KittenGroomer)

@ -1,221 +0,0 @@
#!/bin/bash
source ./constraint.sh
source ./constraint_conv.sh
RECURSIVE_ARCHIVE_MAX=3
RECURSIVE_ARCHIVE_CURRENT=0
ARCHIVE_BOMB=0
LOGFILE="${LOGS}/processing.txt"
# Something went wrong.
error_handler(){
echo "FAILED." >> ${LOGFILE}
echo -e "\tSomething went wrong during the duplication of the last file." >> ${LOGFILE}
echo -e "\tPlease open a bug on https://www.github.com/Rafiot/KittenGroomer" >> ${LOGFILE}
continue
}
trap error_handler ERR TERM INT
office_n_txt(){
src_file=${1}
dst_file=${2}${1##$CURRENT_SRC}.html
temp=${2}/temp
${LO} --headless --convert-to pdf --outdir "${temp}" "${src_file}"
${PDF} --dest-dir=/ ${temp}/*.pdf ${dst_file}
rm -rf "${temp}"
}
copy(){
src_file=${1}
dst_file=${2}
mkdir -p `dirname "${dst_file}"`
cp "${src_file}" "${dst_file}"
}
# Plain text
text(){
echo Text file ${1}
office_n_txt ${1} ${2}
}
# Multimedia
## WARNING: They are assumed safe.
audio(){
echo Audio file ${1}
copy ${1} ${2}${1##$CURRENT_SRC}
}
image(){
echo Image file ${1}
copy ${1} ${2}${1##$CURRENT_SRC}
}
video(){
echo Video file ${1}
copy ${1} ${2}${1##$CURRENT_SRC}
}
# Random - Used
archive(){
echo Archive file ${1}
if [ ${ARCHIVE_BOMB} -eq 0 ]; then
temp_extract_dir=${2}_temp
mkdir -p "${temp_extract_dir}"
${UNPACKER} -p1 x "${1}" -o"${temp_extract_dir}" -bd
main ${2} ${RECURSIVE_ARCHIVE_CURRENT} ${temp_extract_dir} || true
rm -rf "${temp_extract_dir}"
fi
if [ ${ARCHIVE_BOMB} -eq 1 ]; then
rm -rf "${2}"
rm -rf "${2}_temp"
fi
CURRENT_SRC="/media/${SRC}"
}
application(){
echo App file ${1}
src_file=${1}
dst_file=${2}${1##$CURRENT_SRC}
mime_details=${3}
case ${mime_details} in
pdf)
echo "Got a pdf"
${PDF} --dest-dir "${2}" "${src_file}"
;;
msword|vnd.openxmlformats-officedocument.*|vnd.ms-*|vnd.oasis.opendocument*)
# https://blogs.msdn.com/b/vsofficedeveloper/archive/2008/05/08/office-2007-open-xml-mime-types.aspx
# http://plan-b-for-openoffice.org/glossary/term/mime-type
echo "MS Office or ODF document"
office_n_txt ${src_file} ${2}
;;
*xml*)
echo "Got an XML"
office_n_txt ${src_file} ${2}
;;
x-dosexec)
echo "Win executable"
copy ${src_file} ${2}/DANGEROUS_${1##$CURRENT_SRC/}_DANGEROUS
;;
zip|x-rar|x-bzip2|x-lzip|x-lzma|x-lzop|x-xz|x-compress|x-gzip|x-tar|*compressed)
echo "Compressed file"
archive ${src_file} ${dst_file}
;;
octet-stream)
echo "Unknown type."
copy ${src_file} ${dst_file}.bin
;;
*)
echo "Unhandled type"
copy ${src_file} ${dst_file}
;;
esac
}
# Random - Unused?
## WARNING: They are assumed safe.
example(){
echo Example file ${1}
copy ${1} ${2}${1##$CURRENT_SRC}
}
message(){
echo Message file ${1}
copy ${1} ${2}${1##$CURRENT_SRC}
}
model(){
echo Model file ${1}
copy ${1} ${2}${1##$CURRENT_SRC}
}
multipart(){
echo Multipart file ${1}
copy ${1} ${2}${1##$CURRENT_SRC}
}
main(){
if [ -z ${1} ]; then
echo "Please specify the destination directory."
exit
fi
set -e
set -x
if [ -z ${2} ]; then
CURRENT_SRC="/media/${SRC}"
RECURSIVE_ARCHIVE_CURRENT=0
ARCHIVE_BOMB=0
else
RECURSIVE_ARCHIVE_CURRENT=${2}
CURRENT_SRC=${3}
if [ ${RECURSIVE_ARCHIVE_CURRENT} -gt ${RECURSIVE_ARCHIVE_MAX} ]; then
echo Archive bomb.
ARCHIVE_BOMB=1
echo "ARCHIVE BOMB." >> ${LOGFILE}
echo "The content of the archive contains recursively other archives." >> ${LOGFILE}
echo "This is a bad sign so the archive is not extracted to the destination key." >> ${LOGFILE}
return
else
RECURSIVE_ARCHIVE_CURRENT=`expr ${RECURSIVE_ARCHIVE_CURRENT} + 1`
fi
fi
FILE_LIST=`find ${CURRENT_SRC} -type f`
SAVEIFS=$IFS
IFS=$(echo -en "\n\b")
for file in ${FILE_LIST}; do
# first param is the destination dir
dest=${1}
mime=`file -b --mime-type "${file}"`
echo ${mime}
main_mime=`echo ${mime} | cut -f1 -d/`
details=`echo ${mime} | cut -f2 -d/`
echo -n "Processing ${file} (${mime})... " >> ${LOGFILE}
case "${main_mime}" in
"text")
text ${file} ${dest} || error_handler
;;
"audio")
audio ${file} ${dest} || error_handler
;;
"image")
image ${file} ${dest} || error_handler
;;
"video")
video ${file} ${dest} || error_handler
;;
"application")
application ${file} ${dest} ${details} || error_handler
;;
"example")
example ${file} ${dest} || error_handler
;;
"message")
message ${file} ${dest} || error_handler
;;
"model")
model ${file} ${dest} || error_handler
;;
"multipart")
multipart ${file} ${dest} || error_handler
;;
*)
echo "This should never happen... :]"
echo $mime $main_mime $details
;;
esac
echo "done." >> ${LOGFILE}
done
IFS=$SAVEIFS
return 0
}

@ -1,68 +0,0 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import os
from helpers import FileBase, KittenGroomerBase, main
printers = ['.STL', '.obj']
cnc = ['.nc', '.tap', '.gcode', '.dxf', '.stl', '.obj', '.iges', '.igs',
'.vrml', '.vrl', '.thing', '.step', '.stp', '.x3d']
shopbot = ['.ai', '.svg', '.dxf', '.dwg', '.eps']
omax = ['.ai', '.svg', '.dxf', '.dwg', '.eps', '.omx', '.obj']
epilog_laser = ['.ai', '.svg', '.dxf', '.dwg', '.eps']
metabeam = ['.dxf']
up = ['.upp', '.up3', '.stl', '.obj']
class FilePier9(FileBase):
def __init__(self, src_path, dst_path):
''' Init file object, set the extension '''
super(FilePier9, self).__init__(src_path, dst_path)
a, self.extension = os.path.splitext(self.src_path)
class KittenGroomerPier9(KittenGroomerBase):
def __init__(self, root_src=None, root_dst=None):
'''
Initialize the basics of the copy
'''
if root_src is None:
root_src = os.path.join(os.sep, 'media', 'src')
if root_dst is None:
root_dst = os.path.join(os.sep, 'media', 'dst')
super(KittenGroomerPier9, self).__init__(root_src, root_dst)
# The initial version will accept all the file extension for all the machines.
self.authorized_extensions = printers + cnc + shopbot + omax + epilog_laser + metabeam + up
def _print_log(self):
'''
Print the logs related to the current file being processed
'''
tmp_log = self.log_name.fields(**self.cur_file.log_details)
if not self.cur_file.log_details.get('valid'):
tmp_log.warning(self.cur_file.log_string)
else:
tmp_log.debug(self.cur_file.log_string)
def processdir(self):
'''
Main function doing the processing
'''
for srcpath in self._list_all_files(self.src_root_dir):
self.log_name.info('Processing {}', srcpath.replace(self.src_root_dir + '/', ''))
self.cur_file = FilePier9(srcpath, srcpath.replace(self.src_root_dir, self.dst_root_dir))
if self.cur_file.extension in self.authorized_extensions:
self.cur_file.add_log_details('valid', True)
self.cur_file.log_string = 'Expected extension: ' + self.cur_file.extension
self._safe_copy()
else:
self.cur_file.log_string = 'Bad extension: ' + self.cur_file.extension
self._print_log()
if __name__ == '__main__':
main(KittenGroomerPier9)

@ -1,122 +0,0 @@
#!/bin/bash
set -e
set -x
# To make debugging easier
echo "KittenGroomer: in groomer.sh" 1>&2
source ./constraint.sh
if ! [ "${ID}" -ge "1000" ]; then
echo "This script cannot run as root."
exit
fi
source ./functions.sh
clean(){
echo Cleaning.
${SYNC}
# Cleanup source
pumount ${SRC}
# Cleanup destination
rm -rf ${TEMP}
rm -rf ${ZIPTEMP}
pumount ${DST}
exit
}
trap clean EXIT TERM INT
# De we have a source device
if [ ! -b ${DEV_SRC} ]; then
echo "Source device (${DEV_SRC}) does not exists."
exit
fi
# Find the partition names on the source device
DEV_PARTITIONS=`ls "${DEV_SRC}"* | grep "${DEV_SRC}[1-9][0-6]*" || true`
if [ -z "${DEV_PARTITIONS}" ]; then
echo "${DEV_SRC} does not have any partitions."
exit
fi
# Do we have a destination device
if [ ! -b "/dev/${DEV_DST}" ]; then
echo "Destination device (/dev/${DEV_DST}) does not exists."
exit
fi
# mount and prepare destination device
if ${MOUNT}|grep ${DST}; then
${PUMOUNT} ${DST} || true
fi
# uid= only works on a vfat FS. What should wedo if we get an ext* FS ?
${PMOUNT} -w ${DEV_DST} ${DST}
if [ ${?} -ne 0 ]; then
echo "Unable to mount /dev/${DEV_DST} on /media/${DST}"
exit
else
echo "Target USB device (/dev/${DEV_DST}) mounted at /media/${DST}"
rm -rf "/media/${DST}/FROM_PARTITION_"*
# prepare temp dirs and make sure it's empty
mkdir -p "${TEMP}"
mkdir -p "${ZIPTEMP}"
mkdir -p "${LOGS}"
rm -rf "${TEMP}/"*
rm -rf "${ZIPTEMP}/"*
rm -rf "${LOGS}/"*
fi
# Groom da kitteh!
# Find the FS types
# lsblk -n -o name,fstype,mountpoint,label,uuid -r
PARTCOUNT=1
for partition in ${DEV_PARTITIONS}
do
# Processing a partition
echo "Processing partition: ${partition}"
if [ `${MOUNT} | grep -c ${SRC}` -ne 0 ]; then
${PUMOUNT} ${SRC}
fi
${PMOUNT} -w ${partition} ${SRC}
ls "/media/${SRC}" | grep -i autorun.inf | xargs -I {} mv "/media/${SRC}"/{} "/media/${SRC}"/DANGEROUS_{}_DANGEROUS || true
${PUMOUNT} ${SRC}
${PMOUNT} -r ${partition} ${SRC}
if [ ${?} -ne 0 ]; then
echo "Unable to mount ${partition} on /media/${SRC}"
else
echo "${partition} mounted at /media/${SRC}"
# Print the filenames on the current partition in a logfile
find "/media/${SRC}" -fls "${LOGS}/Content_partition_${PARTCOUNT}.txt"
# create a directory on ${DST} named PARTION_$PARTCOUNT
target_dir="/media/${DST}/FROM_PARTITION_${PARTCOUNT}"
echo "copying to: ${target_dir}"
mkdir -p "${target_dir}"
LOGFILE="${LOGS}/processing.txt"
echo "==== Starting processing of /media/${SRC} to ${target_dir}. ====" 1>&2
echo "==== Starting processing of /media/${SRC} to ${target_dir}. ====" >> ${LOGFILE}
generic.py --source /media/${SRC} --destination ${target_dir} || true
echo "==== Done with /media/${SRC} to ${target_dir}. ====" 1>&2
echo "==== Done with /media/${SRC} to ${target_dir}. ====" >> ${LOGFILE}
ls -lR "${target_dir}"
fi
let PARTCOUNT=`expr $PARTCOUNT + 1`
done
# To make debugging easier
echo "KittenGroomer: done with groomer.sh" 1>&2
# The cleanup is automatically done in the function clean called when
# the program quits

@ -1,149 +0,0 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import os
import shutil
from twiggy import quickSetup, log
import argparse
class KittenGroomerError(Exception):
def __init__(self, message):
'''
Base KittenGroomer exception handler.
'''
super(KittenGroomerError, self).__init__(message)
self.message = message
class ImplementationRequired(KittenGroomerError):
'''
Implementation required error
'''
pass
class FileBase(object):
def __init__(self, src_path, dst_path):
'''
Contains base information for a file on the source USB key,
initialised with expected src and dest path
'''
self.src_path = src_path
self.dst_path = dst_path
self.log_details = {'filepath': self.src_path}
self.log_string = ''
def add_log_details(self, key, value):
'''
Add an entry in the log dictionary
'''
self.log_details[key] = value
def make_dangerous(self):
'''
This file should be considered as dangerous and never run.
Prepending and appending DANGEROUS to the destination
file name avoid double-click of death
'''
self.log_details['dangerous'] = True
path, filename = os.path.split(self.dst_path)
self.dst_path = os.path.join(path, 'DANGEROUS_{}_DANGEROUS'.format(filename))
def make_unknown(self):
'''
This file has an unknown type and it was not possible to take
a decision. Theuser will have to decide what to do.
Prepending UNKNOWN
'''
self.log_details['unknown'] = True
path, filename = os.path.split(self.dst_path)
self.dst_path = os.path.join(path, 'UNKNOWN_{}'.format(filename))
def make_binary(self):
'''
This file is a binary, and should probably not be run.
Appending .bin avoir double click of death but the user
will have to decide by itself.
'''
self.log_details['binary'] = True
path, filename = os.path.split(self.dst_path)
self.dst_path = os.path.join(path, '{}.bin'.format(filename))
class KittenGroomerBase(object):
def __init__(self, root_src, root_dst):
'''
Setup the base options of the copy/convert setup
'''
self.src_root_dir = root_src
self.dst_root_dir = root_dst
self.log_root_dir = os.path.join(self.dst_root_dir, 'logs')
self.log_processing = os.path.join(self.log_root_dir, 'processing.log')
# quickSetup(file=self.log_processing)
quickSetup()
self.log_name = log.name('files')
self.cur_file = None
# ##### Helpers #####
def _safe_rmtree(self, directory):
'''Remove a directory tree if it exists'''
if os.path.exists(directory):
shutil.rmtree(directory)
def _safe_remove(self, filepath):
'''Remove a file if it exists'''
if os.path.exists(filepath):
os.remove(filepath)
def _safe_mkdir(self, directory):
'''Remove a directory if it exists'''
if not os.path.exists(directory):
os.makedirs(directory)
def _safe_copy(self):
''' Copy a file and create directory if needed '''
try:
dst_path, filename = os.path.split(self.cur_file.dst_path)
self._safe_mkdir(dst_path)
shutil.copy(self.cur_file.src_path, self.cur_file.dst_path)
return True
except Exception as e:
# TODO: Logfile
print(e)
return False
def _list_all_files(self, directory):
''' Generate an iterator over all the files in a directory tree '''
for root, dirs, files in os.walk(directory):
for filename in files:
filepath = os.path.join(root, filename)
yield filepath
def _print_log(self):
'''
Print log, should be called after each file.
You probably want to reimplement it in the subclass
'''
tmp_log = self.log_name.fields(**self.cur_file.log_details)
tmp_log.info('It did a thing.')
#######################
def processdir(self, src_dir=None, dst_dir=None):
'''
Main function doing the work, you have to implement it yourself.
'''
raise ImplementationRequired('You have to implement the result processdir.')
def main(kg_implementation):
parser = argparse.ArgumentParser(prog='KittenGroomer', description='Call the KittenGroomer implementation to do things on files present in the source directory to the destination directory')
parser.add_argument('-s', '--source', type=str, help='Source directory')
parser.add_argument('-d', '--destination', type=str, help='Destination directory')
args = parser.parse_args()
kg = kg_implementation(args.source, args.destination)
kg.processdir()

@ -1,43 +0,0 @@
#!/bin/bash
set -e
set -x
source ./constraint.sh
if [ ${ID} -ne 0 ]; then
echo "This script has to be run as root."
exit
fi
clean(){
echo Done, cleaning.
${SYNC}
kill -9 $(cat /tmp/music.pid)
rm -f /tmp/music.pid
}
trap clean EXIT TERM INT
./music.sh &
echo $! > /tmp/music.pid
# Dumb libreoffice wants to write into ~/libreoffice or crash with
# com::sun::star::uno::RuntimeException
mkdir /tmp/libreoffice
chown -R kitten:kitten /tmp/libreoffice
# Avoid:
# Failed to connect to /usr/lib/libreoffice/program/soffice.bin (pid=2455) in 6 seconds.
# Connector : couldn't connect to socket (Success)
# Error: Unable to connect or start own listener. Aborting.
mkdir /tmp/libreoffice_config
chown -R kitten:kitten /tmp/libreoffice_config
# Reject all network connexions.
iptables -F
iptables -A INPUT -j REJECT
iptables -A OUTPUT -j REJECT
iptables -A FORWARD -j REJECT
su ${USERNAME} -c ./groomer.sh

@ -1,21 +0,0 @@
#!/bin/bash
set -e
#set -x
source ./constraint.sh
killed(){
echo 'Music stopped.'
}
trap killed EXIT TERM INT
# Force output on analog
amixer cset numid=3 1
files=(${MUSIC}*)
while true; do
$TIMIDITY ${files[RANDOM % ${#files[@]}]}
done

@ -1,47 +0,0 @@
#!/usr/bin/env python3
from RPi import GPIO
import time
# blinking function
def blink(pin):
GPIO.output(pin, GPIO.HIGH)
time.sleep(.1)
GPIO.output(pin, GPIO.LOW)
time.sleep(.1)
return
def test_leds():
# to use Raspberry Pi board pin numbers
GPIO.setmode(GPIO.BOARD)
pins = [11, 12, 15]
# set up GPIO output channel
for pin in pins:
GPIO.setup(pin, GPIO.OUT)
# blink GPIO17 50 times
for i in range(0, 50):
for pin in pins:
blink(pin)
def test_button():
GPIO.setmode(GPIO.BCM)
button = 23
GPIO.setup(button, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
while True:
GPIO.wait_for_edge(button, GPIO.RISING)
print("Button Pressed")
GPIO.wait_for_edge(button, GPIO.FALLING)
print("Button Released")
test_button()
GPIO.cleanup()
Loading…
Cancel
Save