initial commit
parent
6a974d996e
commit
3f5fa6c390
@ -1,11 +1,14 @@
|
||||
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
||||
|
||||
Version 2, December 2004
|
||||
|
||||
Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
|
||||
|
||||
Everyone is permitted to copy and distribute verbatim or modified copies of this license document, and changing it is allowed as long as the name is changed.
|
||||
Everyone is permitted to copy and distribute verbatim or modified copies of
|
||||
this license document, and changing it is allowed as long as the name is changed.
|
||||
|
||||
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
||||
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. You just DO WHAT THE FUCK YOU WANT TO.
|
||||
0. You just DO WHAT THE FUCK YOU WANT TO.
|
@ -1,2 +1,10 @@
|
||||
# libcurses
|
||||
# Libcurses
|
||||
|
||||
Regroupe des fonctions faites maison pour l'utilisation personnelle simplifiée de la bibliothèque curses.
|
||||
|
||||
## Contributions
|
||||
|
||||
Toute contribution est la bienvenue, et peut m'être adressée à l'adresse <math@denoncin.fr>
|
||||
|
||||
## Licence
|
||||
[WTFPL](http://www.wtfpl.net/)
|
||||
|
@ -0,0 +1,20 @@
|
||||
# Minimal makefile for Sphinx documentation
|
||||
#
|
||||
|
||||
# You can set these variables from the command line, and also
|
||||
# from the environment for the first two.
|
||||
SPHINXOPTS ?=
|
||||
SPHINXBUILD ?= sphinx-build
|
||||
SOURCEDIR = .
|
||||
BUILDDIR = _build
|
||||
|
||||
# Put it first so that "make" without argument is like "make help".
|
||||
help:
|
||||
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
|
||||
|
||||
.PHONY: help Makefile
|
||||
|
||||
# Catch-all target: route all unknown targets to Sphinx using the new
|
||||
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
|
||||
%: Makefile
|
||||
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
|
@ -0,0 +1,70 @@
|
||||
# Configuration file for the Sphinx documentation builder.
|
||||
#
|
||||
# This file only contains a selection of the most common options. For a full
|
||||
# list see the documentation:
|
||||
# https://www.sphinx-doc.org/en/master/usage/configuration.html
|
||||
|
||||
# -- Path setup --------------------------------------------------------------
|
||||
|
||||
# If extensions (or modules to document with autodoc) are in another directory,
|
||||
# add these directories to sys.path here. If the directory is relative to the
|
||||
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
||||
#
|
||||
# import os
|
||||
# import sys
|
||||
# sys.path.insert(0, '/home/david/dev_python_packaging/libcurses/libcurses')
|
||||
|
||||
|
||||
# -- Project information -----------------------------------------------------
|
||||
|
||||
project = 'libcurses'
|
||||
copyright = '2020, Author'
|
||||
author = 'Author'
|
||||
|
||||
|
||||
# -- General configuration ---------------------------------------------------
|
||||
|
||||
# Add any Sphinx extension module names here, as strings. They can be
|
||||
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
|
||||
# ones.
|
||||
extensions = [
|
||||
'sphinx.ext.autodoc',
|
||||
'sphinx.ext.viewcode',
|
||||
'sphinx.ext.todo',
|
||||
]
|
||||
|
||||
# Add any paths that contain templates here, relative to this directory.
|
||||
templates_path = ['_templates']
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
#
|
||||
# This is also used if you do content translation via gettext catalogs.
|
||||
# Usually you set "language" from the command line for these cases.
|
||||
language = 'en'
|
||||
|
||||
# List of patterns, relative to source directory, that match files and
|
||||
# directories to ignore when looking for source files.
|
||||
# This pattern also affects html_static_path and html_extra_path.
|
||||
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
|
||||
|
||||
|
||||
# -- Options for HTML output -------------------------------------------------
|
||||
|
||||
# The theme to use for HTML and HTML Help pages. See the documentation for
|
||||
# a list of builtin themes.
|
||||
#
|
||||
html_theme = 'alabaster'
|
||||
|
||||
# Add any paths that contain custom static files (such as style sheets) here,
|
||||
# relative to this directory. They are copied after the builtin static files,
|
||||
# so a file named "default.css" will overwrite the builtin "default.css".
|
||||
html_static_path = ['_static']
|
||||
|
||||
|
||||
# -- Extension configuration -------------------------------------------------
|
||||
|
||||
# -- Options for todo extension ----------------------------------------------
|
||||
|
||||
# If true, `todo` and `todoList` produce output, else they produce nothing.
|
||||
todo_include_todos = True
|
@ -0,0 +1,21 @@
|
||||
.. libcurses documentation master file, created by
|
||||
sphinx-quickstart on Sat May 9 17:50:38 2020.
|
||||
You can adapt this file completely to your liking, but it should at least
|
||||
contain the root `toctree` directive.
|
||||
|
||||
Welcome to libcurses's documentation!
|
||||
=====================================
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 4
|
||||
:caption: Contents:
|
||||
|
||||
libcurses
|
||||
|
||||
|
||||
Indices and tables
|
||||
==================
|
||||
|
||||
* :ref:`genindex`
|
||||
* :ref:`modindex`
|
||||
* :ref:`search`
|
@ -0,0 +1,30 @@
|
||||
libcurses package
|
||||
=================
|
||||
|
||||
Submodules
|
||||
----------
|
||||
|
||||
libcurses.constantes\_curses module
|
||||
-----------------------------------
|
||||
|
||||
.. automodule:: libcurses.constantes_curses
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
libcurses.libcurses module
|
||||
--------------------------
|
||||
|
||||
.. automodule:: libcurses.libcurses
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
|
||||
Module contents
|
||||
---------------
|
||||
|
||||
.. automodule:: libcurses
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
@ -0,0 +1,35 @@
|
||||
@ECHO OFF
|
||||
|
||||
pushd %~dp0
|
||||
|
||||
REM Command file for Sphinx documentation
|
||||
|
||||
if "%SPHINXBUILD%" == "" (
|
||||
set SPHINXBUILD=sphinx-build
|
||||
)
|
||||
set SOURCEDIR=.
|
||||
set BUILDDIR=_build
|
||||
|
||||
if "%1" == "" goto help
|
||||
|
||||
%SPHINXBUILD% >NUL 2>NUL
|
||||
if errorlevel 9009 (
|
||||
echo.
|
||||
echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
|
||||
echo.installed, then set the SPHINXBUILD environment variable to point
|
||||
echo.to the full path of the 'sphinx-build' executable. Alternatively you
|
||||
echo.may add the Sphinx directory to PATH.
|
||||
echo.
|
||||
echo.If you don't have Sphinx installed, grab it from
|
||||
echo.http://sphinx-doc.org/
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
|
||||
goto end
|
||||
|
||||
:help
|
||||
%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
|
||||
|
||||
:end
|
||||
popd
|
@ -0,0 +1 @@
|
||||
from libcurses.libcurses import *
|
@ -0,0 +1,32 @@
|
||||
"""Constantes de la bibliothèque libcurses
|
||||
|
||||
version
|
||||
encoding
|
||||
|
||||
touche_haut : chaîne de caractère du clavier
|
||||
touche_bas : chaîne de caractère du clavier
|
||||
touche_entree : entier désignant la touche entrée (10)
|
||||
|
||||
quitter : chaîne de caractère pour quitter une fenêtre curses à tout moment
|
||||
terminer : chaîne de caractère alternative pour quitter une boucle infinie
|
||||
suivant : chaîne de caractère pour passer à l'écran suivant
|
||||
|
||||
"""
|
||||
version = "1.0"
|
||||
|
||||
## Encodage
|
||||
encoding = 'utf8'
|
||||
|
||||
## Configuration du clavier
|
||||
touche_haut = 'n'
|
||||
touche_bas = 't' # pour se déplacer dans un menu
|
||||
touche_entree = 10
|
||||
|
||||
## Chaîne de caractères pour quitter un programme
|
||||
quitter = 'quitter'
|
||||
|
||||
## Chaîne de caractères pour sortir d'une saisie dont le type est contraint
|
||||
terminer = 'terminer'
|
||||
|
||||
## Chaîne de caractères pour saisir la question suivantes d'un barème
|
||||
suivant = 'suivant'
|
@ -0,0 +1,204 @@
|
||||
import curses
|
||||
import sys
|
||||
from . import constantes_curses as constantes
|
||||
#import constantes_curses as constantes
|
||||
|
||||
def create_newwin():
|
||||
"""Initialise une fenêtre
|
||||
"""
|
||||
window = curses.newwin(0,0)
|
||||
window.border(0)
|
||||
return window
|
||||
|
||||
def init_curses():
|
||||
"""Initialise la biliothèque curses
|
||||
"""
|
||||
stdscr = curses.initscr()
|
||||
curses.noecho()
|
||||
curses.cbreak()
|
||||
stdscr.keypad(True)
|
||||
return stdscr
|
||||
|
||||
def close_curses(stdscr):
|
||||
"""Ferme la fenêtre
|
||||
"""
|
||||
stdscr.keypad(0)
|
||||
curses.nocbreak()
|
||||
curses.echo()
|
||||
curses.endwin()
|
||||
|
||||
def init_colors():
|
||||
"""Initialisation des couleurs de la fenêtre
|
||||
"""
|
||||
curses.start_color()
|
||||
curses.init_pair(1,curses.COLOR_RED,curses.COLOR_BLACK)
|
||||
curses.init_pair(2,curses.COLOR_BLACK,curses.COLOR_RED)
|
||||
|
||||
class Echo():
|
||||
"""Décorateur permettant de garantir que ce qui est écrit au clavier sera vu à l'écran
|
||||
"""
|
||||
|
||||
|
||||
def __init__(self,f):
|
||||
self.f = f
|
||||
|
||||
def __call__(self,*args,**kwargs):
|
||||
curses.echo()
|
||||
return self.f(*args,**kwargs)
|
||||
curses.noecho()
|
||||
|
||||
def add_line(window,pos,nombre_lignes):
|
||||
"""Permet de passer à la ligne suivante lors d'une saisie utilisateur : on ré-initialise la fenêtre si on est descendu trop bas.
|
||||
"""
|
||||
if pos == nombre_lignes-2:
|
||||
pos = 1
|
||||
window = curses.newwin(0,0)
|
||||
window.border(0)
|
||||
window.refresh()
|
||||
return pos
|
||||
else:
|
||||
pos +=1
|
||||
return pos
|
||||
|
||||
@Echo
|
||||
def get_user_entry(window,encoding=constantes.encoding):
|
||||
"""Récupère la saisie d'un message à l'écran
|
||||
"""
|
||||
userentry = window.getstr()
|
||||
return userentry.decode(encoding)
|
||||
|
||||
def get_entry(window,message,pos,nombre_lignes,encoding=constantes.encoding):
|
||||
"""
|
||||
Récupère la saisie utilisateur, en affichant un message d'erreur et demandant la re-saisie si la fonction decode plante (effacement d'un seul caractère au lieu de deux lors d'une saisie erronée d'un caractère accentué).
|
||||
"""
|
||||
while True:
|
||||
try:
|
||||
window.addstr(pos,1,message,curses.color_pair(1))
|
||||
return [get_user_entry(window,encoding),add_line(window,pos,nombre_lignes)]
|
||||
except:
|
||||
pos = add_line(window,pos,nombre_lignes)
|
||||
window.addstr(pos,1,"Erreur de saisie, merci de recommencer",curses.color_pair(1))
|
||||
pos = add_line(window,pos,nombre_lignes)
|
||||
|
||||
def display_menu(title,menu,window,active=1):
|
||||
"""Affiche un menu, qui ne doit pas avoir plus de lignes que la taille de l'écran (non vérifié).
|
||||
"""
|
||||
window.addstr(1,1,title,curses.color_pair(1))
|
||||
item_pos = 6 ## WTF ??
|
||||
pos = 1
|
||||
for item in menu:
|
||||
if pos == active:
|
||||
color = curses.color_pair(2)
|
||||
else:
|
||||
color = curses.A_NORMAL
|
||||
if item == 'Quitter':
|
||||
item_pos +=1
|
||||
window.addstr(item_pos,1," %d. %s" %(pos,item),color)
|
||||
pos +=1
|
||||
else:
|
||||
window.addstr(item_pos,1," %d. %s" %(pos,item),color)
|
||||
item_pos +=1
|
||||
pos +=1
|
||||
window.refresh()
|
||||
|
||||
def getkey(final,title,menu,window,active_pos=1):
|
||||
"""Permet de se balader dans un menu
|
||||
"""
|
||||
c = None
|
||||
while c != constantes.touche_entree:
|
||||
c = window.getch()
|
||||
if c == ord(constantes.touche_bas):
|
||||
if active_pos != final:
|
||||
active_pos +=1
|
||||
else:
|
||||
active_pos = 1
|
||||
elif c == ord(constantes.touche_haut):
|
||||
if active_pos != 1:
|
||||
active_pos -=1
|
||||
else:
|
||||
active_pos = final
|
||||
display_menu(title,menu,window,active_pos)
|
||||
return active_pos
|
||||
|
||||
|
||||
class Stdscr():
|
||||
"""Décorateur permettant d'initialiser une fenêtre curses
|
||||
"""
|
||||
|
||||
|
||||
def __init__(self,f):
|
||||
self.f = f
|
||||
|
||||
def __call__(self,*args):
|
||||
window = init_curses()
|
||||
nombre_lignes = curses.LINES
|
||||
init_colors()
|
||||
window = create_newwin()
|
||||
window.refresh()
|
||||
try:
|
||||
return self.f(*args,window,nombre_lignes)
|
||||
finally:
|
||||
close_curses(window)
|
||||
|
||||
@Stdscr
|
||||
def saisie_message_std(message,window,nombre_lignes):
|
||||
"""Retourne la saisie de l'utilisateur, et quitte le programme si cette saisie est constantes.quitter
|
||||
"""
|
||||
pos = 1
|
||||
user_entry = get_entry(window,message,pos,nombre_lignes,encoding=constantes.encoding)[0]
|
||||
if user_entry.lower() == constantes.quitter:
|
||||
quit() # pourquoi pas sys.exit() ?
|
||||
else:
|
||||
return user_entry
|
||||
|
||||
@Stdscr
|
||||
def afficher_message_std(message,window,nombre_lignes):
|
||||
"""Permet d'afficher un unique message à l'écran
|
||||
"""
|
||||
pos = 1
|
||||
fin_message = " (appuyer sur une touche pour continuer) "
|
||||
c = None
|
||||
window.addstr(pos,1,message+fin_message,curses.color_pair(1))
|
||||
while c == None:
|
||||
c = window.getch()
|
||||
return None
|
||||
|
||||
def saisie_message(pos,message,window,nombre_lignes):
|
||||
"""Retourne la saisie de l'utilisateur, et quitte le programme si cette saisie est constantes.quitter
|
||||
"""
|
||||
user_entry,pos = get_entry(window,message,pos,nombre_lignes,encoding=constantes.encoding)
|
||||
if user_entry.lower() == constantes.quitter:
|
||||
sys.exit()
|
||||
else:
|
||||
return [user_entry, pos]
|
||||
|
||||
def afficher_message(pos,message,window,nombre_lignes):
|
||||
"""Permet d'afficher un message à l'écran dans une fenêtre déjà initialisée
|
||||
"""
|
||||
fin_message = " (appuyer sur une touche pour continuer) "
|
||||
c = None
|
||||
window.addstr(pos,1,message+fin_message,curses.color_pair(1))
|
||||
while c == None:
|
||||
c = window.getch()
|
||||
return add_line(window,pos,nombre_lignes)
|
||||
|
||||
def is_forceable(info,type_info):
|
||||
"""Détermine si l'info peut être considérée comme un 'type_info'
|
||||
"""
|
||||
try:
|
||||
return type_info(info)
|
||||
except:
|
||||
return False
|
||||
|
||||
def get_clean_info(type_info,message,pos,window,nombre_lignes):
|
||||
"""Permet de s'assurer que l'information récupérée est bien du type voulue.
|
||||
"""
|
||||
var = False
|
||||
while not var:
|
||||
var,pos = saisie_message(pos,message,window,nombre_lignes)
|
||||
if var == constantes.terminer: #cas particulier de nécessité de sortie de boucle
|
||||
return [var,pos]
|
||||
var = is_forceable(var,type_info)
|
||||
if (var is 0) and type_info == int: #cas particulier du zéro interprété comme False
|
||||
return [var, pos]
|
||||
return [var, pos]
|
@ -0,0 +1,18 @@
|
||||
from setuptools import setup, find_packages
|
||||
from libcurses.constantes_curses import version
|
||||
|
||||
setup(
|
||||
name="libcurses",
|
||||
version=version,
|
||||
packages=find_packages(),
|
||||
|
||||
author="David Denoncin",
|
||||
author_email="math@denoncin.fr",
|
||||
url="math.denoncin.fr",
|
||||
description="Mes fonctions perso pour faciliter l'utilisation de la bibliothèque curses",
|
||||
classifiers=[
|
||||
"Licence :: WTFPL"
|
||||
]
|
||||
)
|
||||
|
||||
|
Loading…
Reference in New Issue