Compare commits

..

3 Commits

Author SHA1 Message Date
Jean-Jacques Brucker 17ebb60b2f WIP packaging... I think it's better to improve and evolve silkaj, if possible. 2021-07-01 11:32:08 +02:00
Jean-Jacques Brucker 001d17dd06 Merge branch 'master' into debian 2021-07-01 11:28:43 +02:00
Jean-Jacques Brucker f4de57a47b dh_make --python -c gpl3 -p jaklis_0.0.4 --createorig 2021-06-30 11:12:18 +02:00
37 changed files with 1132 additions and 968 deletions

View File

@ -1,16 +1,10 @@
# Chemin de la clé privé Ḡ1 de l'émetteur, au format PubSec
# ex. DUNIKEY="/path/myprivateG1key.dunikey"
DUNIKEY=""
DUNIKEY=
# Noeud Duniter
DUNITER="https://g1.asycn.io"
#DUNITER="https://duniter.pini.fr"
#DUNITER="https://g1v1.p2p.legal"
NODE=https://g1.librelois.fr/gva
# Adresse du pod Cesium ou Gchange à utiliser
ESNODE="https://g1.data.e-is.pro"
#ESNODE="https://g1.data.presles.fr"
#ESNODE="https://g1.data.adn.life"
#ESNODE=https://g1.data.le-sou.org
#ESNODE=https://g1.data.duniter.fr
#ESNODE=https://data.gchange.fr
POD=https://g1.data.le-sou.org
#POD=https://g1.data.duniter.fr
#POD=https://data.gchange.fr

4
.gitignore vendored
View File

@ -1,5 +1,5 @@
.env
__pycache__
*.dunikey
not4U
.vscode/settings.json
__pycache__

6
.vscode/settings.json vendored Executable file → Normal file
View File

@ -1,7 +1,3 @@
{
"python.pythonPath": "/usr/bin/python3.9",
"[python]": {
"editor.defaultFormatter": "ms-python.black-formatter"
},
"python.formatting.provider": "none"
"python.pythonPath": "/usr/bin/python3.9"
}

6
debian/README.Debian vendored Normal file
View File

@ -0,0 +1,6 @@
jaklis for Debian
----------------
<possible notes regarding this package - if none, delete this file>
-- Jean-Jacques Brucker <jjbrucker@free.fr> Wed, 30 Jun 2021 11:11:54 +0200

10
debian/README.source vendored Normal file
View File

@ -0,0 +1,10 @@
jaklis for Debian
----------------
<this file describes information about the source package, see Debian policy
manual section 4.14. You WILL either need to modify or delete this file>
-- Jean-Jacques Brucker <jjbrucker@free.fr> Wed, 30 Jun 2021 11:11:54 +0200

5
debian/changelog vendored Normal file
View File

@ -0,0 +1,5 @@
jaklis (0.0.4-1) unstable; urgency=medium
* Initial release (Closes: #nnnn) <nnnn is the bug number of your ITP>
-- Jean-Jacques Brucker <jjbrucker@free.fr> Wed, 30 Jun 2021 11:11:54 +0200

29
debian/control vendored Normal file
View File

@ -0,0 +1,29 @@
Source: jaklis
Section: unknown
Priority: optional
Maintainer: Jean-Jacques Brucker <jjbrucker@free.fr>
Build-Depends: debhelper-compat (= 13), dh-python, python3-setuptools, python3-all
Standards-Version: 4.5.1
Homepage: <insert the upstream URL, if relevant>
#Vcs-Browser: https://salsa.debian.org/debian/jaklis
#Vcs-Git: https://salsa.debian.org/debian/jaklis.git
#Testsuite: autopkgtest-pkg-python
Rules-Requires-Root: no
Package: python3-jaklis
Architecture: all
Depends: ${python3:Depends}, ${misc:Depends}
Suggests: python-jaklis-doc
Description: <insert up to 60 chars description> (Python 3)
<insert long description, indented with spaces>
.
This package installs the library for Python 3.
Package: python-jaklis-doc
Architecture: all
Section: doc
Depends: ${sphinxdoc:Depends}, ${misc:Depends}
Description: <insert up to 60 chars description> (common documentation)
<insert long description, indented with spaces>
.
This is the common documentation package.

38
debian/copyright vendored Normal file
View File

@ -0,0 +1,38 @@
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: jaklis
Upstream-Contact: Etienne Bouché <poka@p2p.legal>
Source: https://git.p2p.legal/axiom-team/jaklis
Files: *
Copyright: 2021 Etienne Bouché <poka@p2p.legal>
License: GPL-3.0+
Files: debian/*
Copyright: 2021 Jean-Jacques Brucker <jjbrucker@free.fr>
License: GPL-3.0+
License: GPL-3.0+
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
.
This package is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
.
On Debian systems, the complete text of the GNU General
Public License version 3 can be found in "/usr/share/common-licenses/GPL-3".
# Please also look if there are files or directories which have a
# different copyright/license attached and list them here.
# Please avoid picking licenses with terms that are more restrictive than the
# packaged work, as it may make Debian's contributions unacceptable upstream.
#
# If you need, there are some extra license texts available in two places:
# /usr/share/debhelper/dh_make/licenses/
# /usr/share/common-licenses/

4
debian/jaklis.cron.d.ex vendored Normal file
View File

@ -0,0 +1,4 @@
#
# Regular cron jobs for the jaklis package
#
0 4 * * * root [ -x /usr/bin/jaklis_maintenance ] && /usr/bin/jaklis_maintenance

20
debian/jaklis.doc-base.EX vendored Normal file
View File

@ -0,0 +1,20 @@
Document: jaklis
Title: Debian jaklis Manual
Author: <insert document author here>
Abstract: This manual describes what jaklis is
and how it can be used to
manage online manuals on Debian systems.
Section: unknown
Format: debiandoc-sgml
Files: /usr/share/doc/jaklis/jaklis.sgml.gz
Format: postscript
Files: /usr/share/doc/jaklis/jaklis.ps.gz
Format: text
Files: /usr/share/doc/jaklis/jaklis.text.gz
Format: HTML
Index: /usr/share/doc/jaklis/html/index.html
Files: /usr/share/doc/jaklis/html/*.html

56
debian/manpage.1.ex vendored Normal file
View File

@ -0,0 +1,56 @@
.\" Hey, EMACS: -*- nroff -*-
.\" (C) Copyright 2021 Jean-Jacques Brucker <jjbrucker@free.fr>,
.\"
.\" First parameter, NAME, should be all caps
.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection
.\" other parameters are allowed: see man(7), man(1)
.TH Jaklis SECTION "June 30 2021"
.\" Please adjust this date whenever revising the manpage.
.\"
.\" Some roff macros, for reference:
.\" .nh disable hyphenation
.\" .hy enable hyphenation
.\" .ad l left justify
.\" .ad b justify to both left and right margins
.\" .nf disable filling
.\" .fi enable filling
.\" .br insert line break
.\" .sp <n> insert n+1 empty lines
.\" for manpage-specific macros, see man(7)
.SH NAME
jaklis \- program to do something
.SH SYNOPSIS
.B jaklis
.RI [ options ] " files" ...
.br
.B bar
.RI [ options ] " files" ...
.SH DESCRIPTION
This manual page documents briefly the
.B jaklis
and
.B bar
commands.
.PP
.\" TeX users may be more comfortable with the \fB<whatever>\fP and
.\" \fI<whatever>\fP escape sequences to invode bold face and italics,
.\" respectively.
\fBjaklis\fP is a program that...
.SH OPTIONS
These programs follow the usual GNU command line syntax, with long
options starting with two dashes (`-').
A summary of options is included below.
For a complete description, see the Info files.
.TP
.B \-h, \-\-help
Show summary of options.
.TP
.B \-v, \-\-version
Show version of program.
.SH SEE ALSO
.BR bar (1),
.BR baz (1).
.br
The programs are documented fully by
.IR "The Rise and Fall of a Fooish Bar" ,
available via the Info system.

154
debian/manpage.sgml.ex vendored Normal file
View File

@ -0,0 +1,154 @@
<!doctype refentry PUBLIC "-//OASIS//DTD DocBook V4.1//EN" [
<!-- Process this file with docbook-to-man to generate an nroff manual
page: `docbook-to-man manpage.sgml > manpage.1'. You may view
the manual page with: `docbook-to-man manpage.sgml | nroff -man |
less'. A typical entry in a Makefile or Makefile.am is:
manpage.1: manpage.sgml
docbook-to-man $< > $@
The docbook-to-man binary is found in the docbook-to-man package.
Please remember that if you create the nroff version in one of the
debian/rules file targets (such as build), you will need to include
docbook-to-man in your Build-Depends control field.
-->
<!-- Fill in your name for FIRSTNAME and SURNAME. -->
<!ENTITY dhfirstname "<firstname>FIRSTNAME</firstname>">
<!ENTITY dhsurname "<surname>SURNAME</surname>">
<!-- Please adjust the date whenever revising the manpage. -->
<!ENTITY dhdate "<date>June 30 2021</date>">
<!-- SECTION should be 1-8, maybe w/ subsection other parameters are
allowed: see man(7), man(1). -->
<!ENTITY dhsection "<manvolnum>SECTION</manvolnum>">
<!ENTITY dhemail "<email>jjbrucker@free.fr</email>">
<!ENTITY dhusername "Jean-Jacques Brucker">
<!ENTITY dhucpackage "<refentrytitle>Jaklis</refentrytitle>">
<!ENTITY dhpackage "jaklis">
<!ENTITY debian "<productname>Debian</productname>">
<!ENTITY gnu "<acronym>GNU</acronym>">
<!ENTITY gpl "&gnu; <acronym>GPL</acronym>">
]>
<refentry>
<refentryinfo>
<address>
&dhemail;
</address>
<author>
&dhfirstname;
&dhsurname;
</author>
<copyright>
<year>2003</year>
<holder>&dhusername;</holder>
</copyright>
&dhdate;
</refentryinfo>
<refmeta>
&dhucpackage;
&dhsection;
</refmeta>
<refnamediv>
<refname>&dhpackage;</refname>
<refpurpose>program to do something</refpurpose>
</refnamediv>
<refsynopsisdiv>
<cmdsynopsis>
<command>&dhpackage;</command>
<arg><option>-e <replaceable>this</replaceable></option></arg>
<arg><option>--example <replaceable>that</replaceable></option></arg>
</cmdsynopsis>
</refsynopsisdiv>
<refsect1>
<title>DESCRIPTION</title>
<para>This manual page documents briefly the
<command>&dhpackage;</command> and <command>bar</command>
commands.</para>
<para>This manual page was written for the &debian; distribution
because the original program does not have a manual page.
Instead, it has documentation in the &gnu;
<application>Info</application> format; see below.</para>
<para><command>&dhpackage;</command> is a program that...</para>
</refsect1>
<refsect1>
<title>OPTIONS</title>
<para>These programs follow the usual &gnu; command line syntax,
with long options starting with two dashes (`-'). A summary of
options is included below. For a complete description, see the
<application>Info</application> files.</para>
<variablelist>
<varlistentry>
<term><option>-h</option>
<option>--help</option>
</term>
<listitem>
<para>Show summary of options.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>-v</option>
<option>--version</option>
</term>
<listitem>
<para>Show version of program.</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1>
<title>SEE ALSO</title>
<para>bar (1), baz (1).</para>
<para>The programs are documented fully by <citetitle>The Rise and
Fall of a Fooish Bar</citetitle> available via the
<application>Info</application> system.</para>
</refsect1>
<refsect1>
<title>AUTHOR</title>
<para>This manual page was written by &dhusername; &dhemail; for
the &debian; system (and may be used by others). Permission is
granted to copy, distribute and/or modify this document under
the terms of the &gnu; General Public License, Version 2 any
later version published by the Free Software Foundation.
</para>
<para>
On Debian systems, the complete text of the GNU General Public
License can be found in /usr/share/common-licenses/GPL.
</para>
</refsect1>
</refentry>
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-omittag:t
sgml-shorttag:t
sgml-minimize-attributes:nil
sgml-always-quote-attributes:t
sgml-indent-step:2
sgml-indent-data:t
sgml-parent-document:nil
sgml-default-dtd-file:nil
sgml-exposed-tags:nil
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
End:
-->

291
debian/manpage.xml.ex vendored Normal file
View File

@ -0,0 +1,291 @@
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
<!--
`xsltproc -''-nonet \
-''-param man.charmap.use.subset "0" \
-''-param make.year.ranges "1" \
-''-param make.single.year.ranges "1" \
/usr/share/xml/docbook/stylesheet/docbook-xsl/manpages/docbook.xsl \
manpage.xml'
A manual page <package>.<section> will be generated. You may view the
manual page with: nroff -man <package>.<section> | less'. A typical entry
in a Makefile or Makefile.am is:
DB2MAN = /usr/share/sgml/docbook/stylesheet/xsl/docbook-xsl/manpages/docbook.xsl
XP = xsltproc -''-nonet -''-param man.charmap.use.subset "0"
manpage.1: manpage.xml
$(XP) $(DB2MAN) $<
The xsltproc binary is found in the xsltproc package. The XSL files are in
docbook-xsl. A description of the parameters you can use can be found in the
docbook-xsl-doc-* packages. Please remember that if you create the nroff
version in one of the debian/rules file targets (such as build), you will need
to include xsltproc and docbook-xsl in your Build-Depends control field.
Alternatively use the xmlto command/package. That will also automatically
pull in xsltproc and docbook-xsl.
Notes for using docbook2x: docbook2x-man does not automatically create the
AUTHOR(S) and COPYRIGHT sections. In this case, please add them manually as
<refsect1> ... </refsect1>.
To disable the automatic creation of the AUTHOR(S) and COPYRIGHT sections
read /usr/share/doc/docbook-xsl/doc/manpages/authors.html. This file can be
found in the docbook-xsl-doc-html package.
Validation can be done using: `xmllint -''-noout -''-valid manpage.xml`
General documentation about man-pages and man-page-formatting:
man(1), man(7), http://www.tldp.org/HOWTO/Man-Page/
-->
<!-- Fill in your name for FIRSTNAME and SURNAME. -->
<!ENTITY dhfirstname "FIRSTNAME">
<!ENTITY dhsurname "SURNAME">
<!-- dhusername could also be set to "&dhfirstname; &dhsurname;". -->
<!ENTITY dhusername "Jean-Jacques Brucker">
<!ENTITY dhemail "jjbrucker@free.fr">
<!-- SECTION should be 1-8, maybe w/ subsection other parameters are
allowed: see man(7), man(1) and
http://www.tldp.org/HOWTO/Man-Page/q2.html. -->
<!ENTITY dhsection "SECTION">
<!-- TITLE should be something like "User commands" or similar (see
http://www.tldp.org/HOWTO/Man-Page/q2.html). -->
<!ENTITY dhtitle "jaklis User Manual">
<!ENTITY dhucpackage "Jaklis">
<!ENTITY dhpackage "jaklis">
]>
<refentry>
<refentryinfo>
<title>&dhtitle;</title>
<productname>&dhpackage;</productname>
<authorgroup>
<author>
<firstname>&dhfirstname;</firstname>
<surname>&dhsurname;</surname>
<contrib>Wrote this manpage for the Debian system.</contrib>
<address>
<email>&dhemail;</email>
</address>
</author>
</authorgroup>
<copyright>
<year>2007</year>
<holder>&dhusername;</holder>
</copyright>
<legalnotice>
<para>This manual page was written for the Debian system
(and may be used by others).</para>
<para>Permission is granted to copy, distribute and/or modify this
document under the terms of the GNU General Public License,
Version 2 or (at your option) any later version published by
the Free Software Foundation.</para>
<para>On Debian systems, the complete text of the GNU General Public
License can be found in
<filename>/usr/share/common-licenses/GPL</filename>.</para>
</legalnotice>
</refentryinfo>
<refmeta>
<refentrytitle>&dhucpackage;</refentrytitle>
<manvolnum>&dhsection;</manvolnum>
</refmeta>
<refnamediv>
<refname>&dhpackage;</refname>
<refpurpose>program to do something</refpurpose>
</refnamediv>
<refsynopsisdiv>
<cmdsynopsis>
<command>&dhpackage;</command>
<!-- These are several examples, how syntaxes could look -->
<arg choice="plain"><option>-e <replaceable>this</replaceable></option></arg>
<arg choice="opt"><option>--example=<parameter>that</parameter></option></arg>
<arg choice="opt">
<group choice="req">
<arg choice="plain"><option>-e</option></arg>
<arg choice="plain"><option>--example</option></arg>
</group>
<replaceable class="option">this</replaceable>
</arg>
<arg choice="opt">
<group choice="req">
<arg choice="plain"><option>-e</option></arg>
<arg choice="plain"><option>--example</option></arg>
</group>
<group choice="req">
<arg choice="plain"><replaceable>this</replaceable></arg>
<arg choice="plain"><replaceable>that</replaceable></arg>
</group>
</arg>
</cmdsynopsis>
<cmdsynopsis>
<command>&dhpackage;</command>
<!-- Normally the help and version options make the programs stop
right after outputting the requested information. -->
<group choice="opt">
<arg choice="plain">
<group choice="req">
<arg choice="plain"><option>-h</option></arg>
<arg choice="plain"><option>--help</option></arg>
</group>
</arg>
<arg choice="plain">
<group choice="req">
<arg choice="plain"><option>-v</option></arg>
<arg choice="plain"><option>--version</option></arg>
</group>
</arg>
</group>
</cmdsynopsis>
</refsynopsisdiv>
<refsect1 id="description">
<title>DESCRIPTION</title>
<para>This manual page documents briefly the
<command>&dhpackage;</command> and <command>bar</command>
commands.</para>
<para>This manual page was written for the Debian distribution
because the original program does not have a manual page.
Instead, it has documentation in the GNU <citerefentry>
<refentrytitle>info</refentrytitle>
<manvolnum>1</manvolnum>
</citerefentry> format; see below.</para>
<para><command>&dhpackage;</command> is a program that...</para>
</refsect1>
<refsect1 id="options">
<title>OPTIONS</title>
<para>The program follows the usual GNU command line syntax,
with long options starting with two dashes (`-'). A summary of
options is included below. For a complete description, see the
<citerefentry>
<refentrytitle>info</refentrytitle>
<manvolnum>1</manvolnum>
</citerefentry> files.</para>
<variablelist>
<!-- Use the variablelist.term.separator and the
variablelist.term.break.after parameters to
control the term elements. -->
<varlistentry>
<term><option>-e <replaceable>this</replaceable></option></term>
<term><option>--example=<replaceable>that</replaceable></option></term>
<listitem>
<para>Does this and that.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>-h</option></term>
<term><option>--help</option></term>
<listitem>
<para>Show summary of options.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>-v</option></term>
<term><option>--version</option></term>
<listitem>
<para>Show version of program.</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1 id="files">
<title>FILES</title>
<variablelist>
<varlistentry>
<term><filename>/etc/foo.conf</filename></term>
<listitem>
<para>The system-wide configuration file to control the
behaviour of <application>&dhpackage;</application>. See
<citerefentry>
<refentrytitle>foo.conf</refentrytitle>
<manvolnum>5</manvolnum>
</citerefentry> for further details.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><filename>${HOME}/.foo.conf</filename></term>
<listitem>
<para>The per-user configuration file to control the
behaviour of <application>&dhpackage;</application>. See
<citerefentry>
<refentrytitle>foo.conf</refentrytitle>
<manvolnum>5</manvolnum>
</citerefentry> for further details.</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1 id="environment">
<title>ENVIRONMENT</title>
<variablelist>
<varlistentry>
<term><envar>FOO_CONF</envar></term>
<listitem>
<para>If used, the defined file is used as configuration
file (see also <xref linkend="files"/>).</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1 id="diagnostics">
<title>DIAGNOSTICS</title>
<para>The following diagnostics may be issued
on <filename class="devicefile">stderr</filename>:</para>
<variablelist>
<varlistentry>
<term><errortext>Bad configuration file. Exiting.</errortext></term>
<listitem>
<para>The configuration file seems to contain a broken configuration
line. Use the <option>--verbose</option> option, to get more info.
</para>
</listitem>
</varlistentry>
</variablelist>
<para><command>&dhpackage;</command> provides some return codes, that can
be used in scripts:</para>
<segmentedlist>
<segtitle>Code</segtitle>
<segtitle>Diagnostic</segtitle>
<seglistitem>
<seg><errorcode>0</errorcode></seg>
<seg>Program exited successfully.</seg>
</seglistitem>
<seglistitem>
<seg><errorcode>1</errorcode></seg>
<seg>The configuration file seems to be broken.</seg>
</seglistitem>
</segmentedlist>
</refsect1>
<refsect1 id="bugs">
<!-- Or use this section to tell about upstream BTS. -->
<title>BUGS</title>
<para>The program is currently limited to only work
with the <package>foobar</package> library.</para>
<para>The upstreams <acronym>BTS</acronym> can be found
at <ulink url="http://bugzilla.foo.tld"/>.</para>
</refsect1>
<refsect1 id="see_also">
<title>SEE ALSO</title>
<!-- In alpabetical order. -->
<para><citerefentry>
<refentrytitle>bar</refentrytitle>
<manvolnum>1</manvolnum>
</citerefentry>, <citerefentry>
<refentrytitle>baz</refentrytitle>
<manvolnum>1</manvolnum>
</citerefentry>, <citerefentry>
<refentrytitle>foo.conf</refentrytitle>
<manvolnum>5</manvolnum>
</citerefentry></para>
<para>The programs are documented fully by <citetitle>The Rise and
Fall of a Fooish Bar</citetitle> available via the <citerefentry>
<refentrytitle>info</refentrytitle>
<manvolnum>1</manvolnum>
</citerefentry> system.</para>
</refsect1>
</refentry>

39
debian/postinst.ex vendored Normal file
View File

@ -0,0 +1,39 @@
#!/bin/sh
# postinst script for jaklis
#
# see: dh_installdeb(1)
set -e
# summary of how this script can be called:
# * <postinst> `configure' <most-recently-configured-version>
# * <old-postinst> `abort-upgrade' <new version>
# * <conflictor's-postinst> `abort-remove' `in-favour' <package>
# <new-version>
# * <postinst> `abort-remove'
# * <deconfigured's-postinst> `abort-deconfigure' `in-favour'
# <failed-install-package> <version> `removing'
# <conflicting-package> <version>
# for details, see https://www.debian.org/doc/debian-policy/ or
# the debian-policy package
case "$1" in
configure)
;;
abort-upgrade|abort-remove|abort-deconfigure)
;;
*)
echo "postinst called with unknown argument \`$1'" >&2
exit 1
;;
esac
# dh_installdeb will replace this with shell code automatically
# generated by other debhelper scripts.
#DEBHELPER#
exit 0

37
debian/postrm.ex vendored Normal file
View File

@ -0,0 +1,37 @@
#!/bin/sh
# postrm script for jaklis
#
# see: dh_installdeb(1)
set -e
# summary of how this script can be called:
# * <postrm> `remove'
# * <postrm> `purge'
# * <old-postrm> `upgrade' <new-version>
# * <new-postrm> `failed-upgrade' <old-version>
# * <new-postrm> `abort-install'
# * <new-postrm> `abort-install' <old-version>
# * <new-postrm> `abort-upgrade' <old-version>
# * <disappearer's-postrm> `disappear' <overwriter>
# <overwriter-version>
# for details, see https://www.debian.org/doc/debian-policy/ or
# the debian-policy package
case "$1" in
purge|remove|upgrade|failed-upgrade|abort-install|abort-upgrade|disappear)
;;
*)
echo "postrm called with unknown argument \`$1'" >&2
exit 1
;;
esac
# dh_installdeb will replace this with shell code automatically
# generated by other debhelper scripts.
#DEBHELPER#
exit 0

35
debian/preinst.ex vendored Normal file
View File

@ -0,0 +1,35 @@
#!/bin/sh
# preinst script for jaklis
#
# see: dh_installdeb(1)
set -e
# summary of how this script can be called:
# * <new-preinst> `install'
# * <new-preinst> `install' <old-version>
# * <new-preinst> `upgrade' <old-version>
# * <old-preinst> `abort-upgrade' <new-version>
# for details, see https://www.debian.org/doc/debian-policy/ or
# the debian-policy package
case "$1" in
install|upgrade)
;;
abort-upgrade)
;;
*)
echo "preinst called with unknown argument \`$1'" >&2
exit 1
;;
esac
# dh_installdeb will replace this with shell code automatically
# generated by other debhelper scripts.
#DEBHELPER#
exit 0

38
debian/prerm.ex vendored Normal file
View File

@ -0,0 +1,38 @@
#!/bin/sh
# prerm script for jaklis
#
# see: dh_installdeb(1)
set -e
# summary of how this script can be called:
# * <prerm> `remove'
# * <old-prerm> `upgrade' <new-version>
# * <new-prerm> `failed-upgrade' <old-version>
# * <conflictor's-prerm> `remove' `in-favour' <package> <new-version>
# * <deconfigured's-prerm> `deconfigure' `in-favour'
# <package-being-installed> <version> `removing'
# <conflicting-package> <version>
# for details, see https://www.debian.org/doc/debian-policy/ or
# the debian-policy package
case "$1" in
remove|upgrade|deconfigure)
;;
failed-upgrade)
;;
*)
echo "prerm called with unknown argument \`$1'" >&2
exit 1
;;
esac
# dh_installdeb will replace this with shell code automatically
# generated by other debhelper scripts.
#DEBHELPER#
exit 0

2
debian/python-jaklis-doc.docs vendored Normal file
View File

@ -0,0 +1,2 @@
README.source
README.Debian

23
debian/rules vendored Executable file
View File

@ -0,0 +1,23 @@
#!/usr/bin/make -f
# See debhelper(7) (uncomment to enable)
# output every command that modifies files on the build system.
#export DH_VERBOSE = 1
export PYBUILD_NAME=jaklis
%:
dh $@ --with python3 --buildsystem=pybuild
# If you need to rebuild the Sphinx documentation
# Add sphinxdoc to the dh --with line
#
# And uncomment the following lines
#override_dh_auto_build: export http_proxy=127.0.0.1:9
#override_dh_auto_build: export https_proxy=127.0.0.1:9
#override_dh_auto_build:
# dh_auto_build
# PYTHONPATH=. python3 -m sphinx -N -bhtml \
# docs/ build/html # HTML generator
# PYTHONPATH=. python3 -m sphinx -N -bman \
# docs/ build/man # Manpage generator

11
debian/salsa-ci.yml.ex vendored Normal file
View File

@ -0,0 +1,11 @@
# For more information on what jobs are run see:
# https://salsa.debian.org/salsa-ci-team/pipeline
#
# To enable the jobs, go to your repository (at salsa.debian.org)
# and click over Settings > CI/CD > Expand (in General pipelines).
# In "Custom CI config path" write debian/salsa-ci.yml and click
# in "Save Changes". The CI tests will run after the next commit.
---
include:
- https://salsa.debian.org/salsa-ci-team/pipeline/raw/master/salsa-ci.yml
- https://salsa.debian.org/salsa-ci-team/pipeline/raw/master/pipeline-jobs.yml

1
debian/source/format vendored Normal file
View File

@ -0,0 +1 @@
3.0 (quilt)

1
debian/source/options vendored Normal file
View File

@ -0,0 +1 @@
extend-diff-ignore = "^[^/]*[.]egg-info/"

38
debian/watch.ex vendored Normal file
View File

@ -0,0 +1,38 @@
# Example watch control file for uscan
# Rename this file to "watch" and then you can run the "uscan" command
# to check for upstream updates and more.
# See uscan(1) for format
# Compulsory line, this is a version 4 file
version=4
# PGP signature mangle, so foo.tar.gz has foo.tar.gz.sig
#opts="pgpsigurlmangle=s%$%.sig%"
# HTTP site (basic)
#http://example.com/downloads.html \
# files/jaklis-([\d\.]+)\.tar\.gz debian uupdate
# Uncomment to examine an FTP server
#ftp://ftp.example.com/pub/jaklis-(.*)\.tar\.gz debian uupdate
# SourceForge hosted projects
# http://sf.net/jaklis/ jaklis-(.*)\.tar\.gz debian uupdate
# GitHub hosted projects
#opts="filenamemangle=s%(?:.*?)?v?(\d[\d.]*)\.tar\.gz%<project>-$1.tar.gz%" \
# https://github.com/<user>/jaklis/tags \
# (?:.*?/)?v?(\d[\d.]*)\.tar\.gz debian uupdate
# PyPI
# https://pypi.debian.net/jaklis/jaklis-(.+)\.(?:zip|tgz|tbz|txz|(?:tar\.(?:gz|bz2|xz)))
# Direct Git
# opts="mode=git" http://git.example.com/jaklis.git \
# refs/tags/v([\d\.]+) debian uupdate
# Uncomment to find new files on GooglePages
# http://example.googlepages.com/foo.html jaklis-(.*)\.tar\.gz

557
jaklis.py
View File

@ -1,395 +1,198 @@
#!/usr/bin/env python3
import argparse
import sys
import os
import string
import random
import argparse, sys, os, getpass, string, random
from os.path import join, dirname
from shutil import copyfile
from dotenv import load_dotenv
from duniterpy.key import SigningKey
from pathlib import Path
from lib.gva import GvaApi
from lib.cesium import CesiumPlus
__version__ = "0.1.1"
__version__ = "0.0.4"
MY_PATH = Path(__file__).resolve().parent
MY_PATH = os.path.realpath(os.path.dirname(sys.argv[0])) + '/'
# Set file paths
dotenv_file = MY_PATH / ".env"
dotenv_template = MY_PATH / ".env.template"
# Get variables environment
if not os.path.isfile(MY_PATH + '.env'):
copyfile(MY_PATH + ".env.template",MY_PATH + ".env")
dotenv_path = join(dirname(__file__),MY_PATH + '.env')
load_dotenv(dotenv_path)
# Check and create dotenv file
if not dotenv_file.is_file():
dotenv_file.write_text(dotenv_template.read_text())
# Set global values (default parameters) , regarding variables environments
node = os.getenv('NODE')
if not node:
node="https://g1.librelois.fr/gva"
# Load environment variables
load_dotenv(dotenv_file)
pod = os.getenv('POD')
if not pod:
pod="https://g1.data.le-sou.org"
# Set global values (default parameters) regarding environment variables
node = os.getenv("DUNITER") + "/gva" or "https://g1v1.p2p.legal/gva"
pod = os.getenv("ESNODE") or "https://g1.data.e-is.pro"
destPubkey = False
# define parser
parser = argparse.ArgumentParser(
description="CLI Client for Cesium+ and Ḡchange",
epilog="current node: '" + node + "', current pod: '" + pod + "'.",
)
# Parse arguments
parser = argparse.ArgumentParser(description="Client CLI pour Cesium+ et Ḡchange", epilog="current node: '" + node + "', current pod: '" + pod + "'.")
parser.add_argument('-v', '--version', action='store_true', help="Affiche la version actuelle du programme")
parser.add_argument('-k', '--key', help="Chemin vers mon trousseau de clé (PubSec)")
parser.add_argument('-n', '--node', help="Adresse du noeud Cesium+, Gchange ou Duniter à utiliser")
# load global arguments
parser.add_argument(
"-v",
"--version",
action="store_true",
help="Display the current program version",
)
parser.add_argument("-k", "--key", help="Path to the keyfile (PubSec)")
parser.add_argument(
"-n", "--node", help="Address of the Cesium+, Gchange, or Duniter node to use"
)
subparsers = parser.add_subparsers(title="Commandes de jaklis", dest="cmd")
read_cmd = subparsers.add_parser('read', help="Lecture des messages")
send_cmd = subparsers.add_parser('send', help="Envoi d'un message")
delete_cmd = subparsers.add_parser('delete', help="Supression d'un message")
getProfile_cmd = subparsers.add_parser('get', help="Voir un profile Cesium+")
setProfile_cmd = subparsers.add_parser('set', help="Configurer son profile Cesium+")
eraseProfile_cmd = subparsers.add_parser('erase', help="Effacer son profile Cesium+")
stars_cmd = subparsers.add_parser('stars', help="Voir les étoiles d'un profile / Noter un profile (option -s NOTE)")
unstars_cmd = subparsers.add_parser('unstars', help="Supprimer un star")
getoffer_cmd = subparsers.add_parser('getoffer', help="Obtenir les informations d'une annonce gchange")
setoffer_cmd = subparsers.add_parser('setoffer', help="Créer une annonce gchange")
deleteoffer_cmd = subparsers.add_parser('deleteoffer', help="Supprimer une annonce gchange")
pay_cmd = subparsers.add_parser('pay', help="Payer en Ḡ1")
history_cmd = subparsers.add_parser('history', help="Voir l'historique des transactions d'un compte Ḡ1")
balance_cmd = subparsers.add_parser('balance', help="Voir le solde d'un compte Ḡ1")
id_cmd = subparsers.add_parser('id', help="Voir l'identité d'une clé publique/username")
id_balance_cmd = subparsers.add_parser('idBalance', help="Voir l'identité d'une clé publique/username et son solde")
currentUd = subparsers.add_parser('currentUd', help="Affiche la montant actuel du dividende Universel")
# Define commands with arguments
commands = {
"read": {
"help": "Read messages",
"arguments": {
("n", "number"): {
"type": int,
"default": 3,
"help": "Display the last NUMBER messages",
},
("j", "json"): {"action": "store_true", "help": "Output in JSON format"},
("o", "outbox"): {"action": "store_true", "help": "Read sent messages"},
},
"type": "cesium",
},
"send": {
"help": "Send a message",
"arguments": {
("d", "destinataire"): {
"required": True,
"help": "Recipient of the message",
},
("t", "titre"): {"help": "Title of the message to send"},
("m", "message"): {"help": "Message to send"},
("f", "fichier"): {"help": "Send the message from the 'FILE'"},
("o", "outbox"): {
"action": "store_true",
"help": "Send the message to the outbox",
},
},
"type": "cesium",
},
"delete": {
"help": "Delete a message",
"arguments": {
("i", "id"): {
"action": "append",
"nargs": "+",
"required": True,
"help": "ID(s) of the message(s) to delete",
},
("o", "outbox"): {
"action": "store_true",
"help": "Delete a sent message",
},
},
"type": "cesium",
},
"get": {
"help": "View a Cesium+ profile",
"arguments": {
("p", "profile"): {"help": "Profile name"},
("a", "avatar"): {
"action": "store_true",
"help": "Also retrieve the avatar in raw base64 format",
},
},
"type": "cesium",
},
"page": {
"help": "View a Cesium+ page",
"arguments": {
("p", "page"): {"help": "Page name"},
("a", "avatar"): {
"action": "store_true",
"help": "Also retrieve the page's avatar in raw base64 format",
},
},
"type": "cesium",
},
"set": {
"help": "Configure your Cesium+ profile",
"arguments": {
("n", "name"): {"help": "Profile name"},
("d", "description"): {"help": "Profile description"},
("v", "ville"): {"help": "Profile city"},
("a", "adresse"): {"help": "Profile address"},
("pos", "position"): {
"nargs": 2,
"help": "Geographical coordinates (lat + lon)",
},
("s", "site"): {"help": "Profile website"},
("A", "avatar"): {"help": "Path to profile avatar in PNG"},
},
"type": "cesium",
},
"erase": {
"help": "Erase your Cesium+ profile",
"arguments": {},
"type": "cesium",
},
"stars": {
"help": "View a profile's stars / Rate a profile (option -s RATING)",
"arguments": {
("p", "profile"): {"help": "Target profile"},
("n", "number"): {"type": int, "help": "Number of stars"},
},
"type": "cesium",
},
"unstars": {
"help": "Remove a star",
"arguments": {
("p", "profile"): {"help": "Profile to unstar"},
},
"type": "cesium",
},
"getoffer": {
"help": "Get information about a Ḡchange listing",
"arguments": {
("i", "id"): {"help": "Target listing to retrieve"},
},
"type": "cesium",
},
"setoffer": {
"help": "Create a Ḡchange listing",
"arguments": {
("t", "title"): {"help": "Title of the listing to create"},
("d", "description"): {"help": "Description of the listing to create"},
("c", "category"): {"help": "Category of the listing to create"},
("l", "location"): {
"nargs": 2,
"help": "Location of the listing to create (lat + lon)",
},
("p", "picture"): {"help": "Image of the listing to create"},
("ci", "city"): {"help": "City of the listing to create"},
("pr", "price"): {"help": "Price of the listing to create"},
},
"type": "cesium",
},
"deleteoffer": {
"help": "Delete a Ḡchange listing",
"arguments": {
("i", "id"): {"help": "Target listing to delete"},
},
"type": "cesium",
},
"geolocProfiles": {
"help": "Get JSON of all geolocated accounts",
"arguments": {},
"type": "cesium",
},
"pay": {
"help": "Pay in Ḡ1",
"arguments": {
("p", "pubkey"): {"help": "Payment recipient"},
("a", "amount"): {"type": float, "help": "Transaction amount"},
("c", "comment"): {
"default": "",
"help": "Transaction comment",
"nargs": "*",
},
("m", "mempool"): {
"action": "store_true",
"help": "Use mempool sources",
},
("v", "verbose"): {
"action": "store_true",
"help": "Display the JSON result of the transaction",
},
},
"type": "gva",
},
"history": {
"help": "View Ḡ1 account transaction history",
"arguments": {
("p", "pubkey"): {"help": "Public key of the target account"},
("n", "number"): {
"type": int,
"default": 10,
"help": "Display the last NUMBER transactions",
},
("j", "json"): {
"action": "store_true",
"help": "Display the result in JSON format",
},
("nocolors"): {
"action": "store_true",
"help": "Display the result in black and white",
},
},
"type": "gva",
},
"balance": {
"help": "View Ḡ1 account balance",
"arguments": {
("p", "pubkey"): {"help": "Public key of the target account"},
("m", "mempool"): {
"action": "store_true",
"help": "Use mempool sources",
},
},
"type": "gva",
},
"id": {
"help": "View public key/username identity",
"arguments": {
("p", "pubkey"): {"help": "Public key of the target account"},
("u", "username"): {"help": "Username of the target account"},
},
"type": "gva",
},
"idBalance": {
"help": "View public key/username identity and balance",
"arguments": {
("p", "pubkey"): {"help": "Public key of the target account"},
},
"type": "gva",
},
"currentUd": {
"help": "Display the current Universal Dividend amount",
"arguments": {
("p", "pubkey"): {"help": "Public key of the target account"},
},
"type": "gva",
},
"listWallets": {
"help": "List all G1 wallets",
"arguments": {
("m", "mbr"): {
"action": "store_true",
"help": "Display raw list of member pubkeys",
},
("nm", "non_mbr"): {
"action": "store_true",
"help": "Display raw list of nonmember identity pubkeys",
},
("l", "larf"): {
"action": "store_true",
"help": "Display raw list of nonmember pubkeys",
},
("b", "brut"): {
"action": "store_true",
"help": "Display raw list of all pubkeys",
},
},
"type": "gva",
},
}
# Messages management
read_cmd.add_argument('-n', '--number',type=int, default=3, help="Affiche les NUMBER derniers messages")
read_cmd.add_argument('-j', '--json', action='store_true', help="Sort au format JSON")
read_cmd.add_argument('-o', '--outbox', action='store_true', help="Lit les messages envoyés")
send_cmd.add_argument('-d', '--destinataire', required=True, help="Destinataire du message")
send_cmd.add_argument('-t', '--titre', help="Titre du message à envoyer")
send_cmd.add_argument('-m', '--message', help="Message à envoyer")
send_cmd.add_argument('-f', '--fichier', help="Envoyer le message contenu dans le fichier 'FICHIER'")
send_cmd.add_argument('-o', '--outbox', action='store_true', help="Envoi le message sur la boite d'envoi")
delete_cmd.add_argument('-i', '--id', action='append', nargs='+', required=True, help="ID(s) du/des message(s) à supprimer")
delete_cmd.add_argument('-o', '--outbox', action='store_true', help="Suppression d'un message envoyé")
# Profiles management
setProfile_cmd.add_argument('-n', '--name', help="Nom du profile")
setProfile_cmd.add_argument('-d', '--description', help="Description du profile")
setProfile_cmd.add_argument('-v', '--ville', help="Ville du profile")
setProfile_cmd.add_argument('-a', '--adresse', help="Adresse du profile")
setProfile_cmd.add_argument('-pos', '--position', nargs=2, help="Points géographiques (lat + lon)")
setProfile_cmd.add_argument('-s', '--site', help="Site web du profile")
setProfile_cmd.add_argument('-A', '--avatar', help="Chemin vers mon avatar en PNG")
getProfile_cmd.add_argument('-p', '--profile', help="Nom du profile")
getProfile_cmd.add_argument('-a', '--avatar', action='store_true', help="Récupérer également l'avatar au format raw base64")
# Likes management
stars_cmd.add_argument('-p', '--profile', help="Profile cible")
stars_cmd.add_argument('-n', '--number', type=int, help="Nombre d'étoile")
unstars_cmd.add_argument('-p', '--profile', help="Profile à dénoter")
# Offers management
getoffer_cmd.add_argument('-i', '--id', help="Annonce cible à récupérer")
setoffer_cmd.add_argument('-t', '--title', help="Titre de l'annonce à créer")
setoffer_cmd.add_argument('-d', '--description', help="Description de l'annonce à créer")
setoffer_cmd.add_argument('-c', '--category', help="Categorie de l'annonce à créer")
setoffer_cmd.add_argument('-l', '--localisation', nargs=2, help="Localisation de l'annonce à créer (lat + lon)")
setoffer_cmd.add_argument('-p', '--picture', help="Image de l'annonce à créer")
setoffer_cmd.add_argument('-ci', '--city', help="Ville de l'annonce à créer")
setoffer_cmd.add_argument('-pr', '--price', help="Prix de l'annonce à créer")
deleteoffer_cmd.add_argument('-i', '--id', help="Annonce cible à supprimer")
# GVA usage
pay_cmd.add_argument('-p', '--pubkey', help="Destinataire du paiement")
pay_cmd.add_argument('-a', '--amount', type=float, help="Montant de la transaction")
pay_cmd.add_argument('-c', '--comment', default="", help="Commentaire de la transaction")
pay_cmd.add_argument('-m', '--mempool', action='store_true', help="Utilise les sources en Mempool")
pay_cmd.add_argument('-v', '--verbose', action='store_true', help="Affiche le résultat JSON de la transaction")
history_cmd.add_argument('-p', '--pubkey', help="Clé publique du compte visé")
history_cmd.add_argument('-n', '--number',type=int, default=10, help="Affiche les NUMBER dernières transactions")
history_cmd.add_argument('-j', '--json', action='store_true', help="Affiche le résultat en format JSON")
history_cmd.add_argument('--nocolors', action='store_true', help="Affiche le résultat en noir et blanc")
balance_cmd.add_argument('-p', '--pubkey', help="Clé publique du compte visé")
balance_cmd.add_argument('-m', '--mempool', action='store_true', help="Utilise les sources en Mempool")
id_cmd.add_argument('-p', '--pubkey', help="Clé publique du compte visé")
id_cmd.add_argument('-u', '--username', help="Username du compte visé")
id_balance_cmd.add_argument('-p', '--pubkey', help="Pubkey du compte visé")
currentUd.add_argument('-p', '--pubkey', help="Pubkey du compte visé")
# Process commands and arguments
subparsers = parser.add_subparsers(title="jaklis Commands", dest="cmd")
for cmd, cmd_info in commands.items():
cmd_parser = subparsers.add_parser(cmd, help=cmd_info["help"])
for args, kwargs in cmd_info["arguments"].items():
if isinstance(args, str):
cmd_parser.add_argument("--" + args, **kwargs)
else:
short_arg, long_arg = args
cmd_parser.add_argument("-" + short_arg, "--" + long_arg, **kwargs)
args = parser.parse_args()
args_dict = vars(args)
cmd = args.cmd
if args.version:
print(__version__)
sys.exit(0)
print(__version__)
sys.exit(0)
if not cmd:
parser.print_help()
sys.exit(0)
sys.exit(1)
def createTmpDunikey():
# Generate a pseudo-random nonce
nonce = "".join(
random.choice(string.ascii_letters + string.digits) for _ in range(32)
)
# Generate pseudo-random nonce
nonce=[]
for _ in range(32):
nonce.append(random.choice(string.ascii_letters + string.digits))
nonce = ''.join(nonce)
keyPath = "/tmp/secret.dunikey-" + nonce
# Create a dummy key (replace with actual key creation logic)
key = SigningKey.from_credentials(
"sgse547yhd54xv6541srdh", "sfdgwdrhpkxdawsbszqpof1sdg65xc", None
)
key = SigningKey.from_credentials(getpass.getpass("Identifiant: "), getpass.getpass("Mot de passe: "), None)
key.save_pubsec_file(keyPath)
return keyPath
# Check if we need dunikey
try:
pubkey = args.pubkey
except:
pubkey = False
try:
profile = args.profile
except:
profile = False
def get_arg_value(args, arg):
if cmd in ('history','balance','get','id','idBalance') and (pubkey or profile):
noNeedDunikey = True
keyPath = False
try:
return getattr(args, arg)
except AttributeError:
return False
def get_dunikey(args):
dunikey = args.pubkey
except:
dunikey = args.profile
else:
noNeedDunikey = False
if args.key:
return args.key
dunikey = os.getenv("DUNIKEY")
if not dunikey:
keyPath = createTmpDunikey()
dunikey = keyPath
dunikey = args.key
keyPath = False
else:
dunikey = os.getenv('DUNIKEY')
if not dunikey:
keyPath = createTmpDunikey()
dunikey = keyPath
else:
keyPath = False
if not os.path.isfile(dunikey):
HOME = os.getenv("HOME")
dunikey = HOME + dunikey
if not os.path.isfile(dunikey):
sys.stderr.write("The keyfile {0} is not found.\n".format(dunikey))
sys.stderr.write('Le fichier de trousseau {0} est introuvable.\n'.format(dunikey))
sys.exit(1)
return dunikey
pubkey = get_arg_value(args, "pubkey")
profile = get_arg_value(args, "profile")
# Construct CesiumPlus object
if cmd in ("read","send","delete","set","get","erase","stars","unstars","getoffer","setoffer","deleteoffer"):
from lib.cesium import CesiumPlus
noNeedDunikey = cmd in (
"history",
"balance",
"page",
"id",
"idBalance",
"listWallets",
"geolocProfiles",
) and (pubkey or profile)
if args.node:
pod = args.node
if noNeedDunikey:
dunikey = pubkey if pubkey else profile
else:
dunikey = get_dunikey(args)
keyPath = False if dunikey else createTmpDunikey()
def handle_cesium_commands(args, cmd, cesium):
# Get args of the command
cmd_args = (
list(zip(*list(commands[cmd]["arguments"].keys())))[1]
if len(commands[cmd]["arguments"].keys()) > 0
else []
)
cmd_args_dict = {arg: args_dict[arg] for arg in cmd_args if arg in args_dict}
cmd_args_values = list(cmd_args_dict.values())
cesium = CesiumPlus(dunikey, pod, noNeedDunikey)
# Messaging
if cmd == "read":
cesium.read(*cmd_args_values)
cesium.read(args.number, args.outbox, args.json)
elif cmd == "send":
if args.fichier:
with open(args.fichier, "r") as f:
with open(args.fichier, 'r') as f:
msgT = f.read()
titre = msgT.splitlines(True)[0].replace("\n", "")
msg = "".join(msgT.splitlines(True)[1:])
titre = msgT.splitlines(True)[0].replace('\n', '')
msg = ''.join(msgT.splitlines(True)[1:])
if args.titre:
titre = args.titre
msg = msgT
@ -397,8 +200,8 @@ def handle_cesium_commands(args, cmd, cesium):
titre = args.titre
msg = args.message
else:
titre = input("Enter the message title: ")
msg = input("Enter the message content: ")
titre = input("Indiquez le titre du message: ")
msg = input("Indiquez le contenu du message: ")
cesium.send(titre, msg, args.destinataire, args.outbox)
@ -407,15 +210,11 @@ def handle_cesium_commands(args, cmd, cesium):
# Profiles
elif cmd == "set":
cesium.set(**cmd_args_dict)
cesium.set(args.name, args.description, args.ville, args.adresse, args.position, args.site, args.avatar)
elif cmd == "get":
cesium.get(**cmd_args_dict)
elif cmd == "page":
cesium.getPage(**cmd_args_dict)
cesium.get(args.profile, args.avatar)
elif cmd == "erase":
cesium.erase()
elif cmd == "geolocProfiles":
cesium.geolocProfiles(node)
# Stars
elif cmd == "stars":
@ -430,22 +229,21 @@ def handle_cesium_commands(args, cmd, cesium):
elif cmd == "getoffer":
cesium.getOffer(args.id)
elif cmd == "setoffer":
cesium.setOffer(**cmd_args_dict)
cesium.setOffer(args.title, args.description, args.city, args.localisation, args.category, args.price, args.picture)
elif cmd == "deleteoffer":
cesium.deleteOffer(**cmd_args_dict)
else:
raise ValueError(f"Unknown command: {cmd}")
cesium.deleteOffer(args.id)
# Construct GVA object
elif cmd in ("pay","history","balance","id","idBalance","currentUd"):
from lib.gva import GvaApi
def handle_gva_commands(args, cmd, gva):
# Get args of the command
cmd_args = (
list(zip(*list(commands[cmd]["arguments"].keys())))[1]
if len(commands[cmd]["arguments"].keys()) > 0
else []
)
cmd_args_dict = {arg: args_dict[arg] for arg in cmd_args if arg in args_dict}
# cmd_args_values = list(cmd_args_dict.values())
if args.node:
node = args.node
if args.pubkey:
destPubkey = args.pubkey
gva = GvaApi(dunikey, node, destPubkey, noNeedDunikey)
if cmd == "pay":
gva.pay(args.amount, args.comment, args.mempool, args.verbose)
@ -454,37 +252,12 @@ def handle_gva_commands(args, cmd, gva):
elif cmd == "balance":
gva.balance(args.mempool)
elif cmd == "id":
gva.id(**cmd_args_dict)
gva.id(args.pubkey, args.username)
elif cmd == "idBalance":
gva.idBalance(**cmd_args_dict)
gva.idBalance(args.pubkey)
elif cmd == "currentUd":
gva.currentUd()
elif cmd == "listWallets":
gva.listWallets(args.brut, args.mbr, args.non_mbr, args.larf)
else:
raise ValueError(f"Unknown command: {cmd}")
# Construct the CesiumPlus object
if commands[cmd]["type"] == "cesium":
if args.node:
pod = args.node
cesium = CesiumPlus(dunikey, pod, noNeedDunikey)
handle_cesium_commands(args, cmd, cesium)
# Construct the GvaApi object
elif commands[cmd]["type"] == "gva":
if args.node:
node = args.node
if hasattr(args, "pubkey"):
destPubkey = args.pubkey
gva = GvaApi(dunikey, node, destPubkey, noNeedDunikey)
handle_gva_commands(args, cmd, gva)
else:
raise ValueError(f"Unknown command: {cmd}")
if keyPath:
os.remove(keyPath)

View File

@ -1,19 +1,16 @@
import json
import re, string, random, base64
from lib.cesiumCommon import CesiumCommon, PUBKEY_REGEX
from lib.geolocProfiles import GeolocProfiles
from lib.getPages import Pages
from lib.messaging import ReadFromCesium, SendToCesium, DeleteFromCesium
from lib.profiles import Profiles
from lib.stars import ReadLikes, SendLikes, UnLikes
from lib.offers import Offers
class CesiumPlus(CesiumCommon):
#################### Messaging ####################
def read(self, nbrMsg, isJSON, outbox):
readCesium = ReadFromCesium(self.dunikey, self.pod)
def read(self, nbrMsg, outbox, isJSON):
readCesium = ReadFromCesium(self.dunikey, self.pod)
jsonMsg = readCesium.sendDocument(nbrMsg, outbox)
if isJSON:
jsonFormat = readCesium.jsonMessages(jsonMsg, nbrMsg, outbox)
@ -26,18 +23,16 @@ class CesiumPlus(CesiumCommon):
sendCesium.recipient = recipient
# Generate pseudo-random nonce
nonce = []
nonce=[]
for _ in range(32):
nonce.append(random.choice(string.ascii_letters + string.digits))
sendCesium.nonce = base64.b64decode("".join(nonce))
sendCesium.nonce = base64.b64decode(''.join(nonce))
finalDoc = sendCesium.configDoc(
sendCesium.encryptMsg(title), sendCesium.encryptMsg(msg)
) # Configure JSON document to send
sendCesium.sendDocument(finalDoc, outbox) # Send final signed document
finalDoc = sendCesium.configDoc(sendCesium.encryptMsg(title), sendCesium.encryptMsg(msg)) # Configure JSON document to send
sendCesium.sendDocument(finalDoc, outbox) # Send final signed document
def delete(self, idsMsgList, outbox):
deleteCesium = DeleteFromCesium(self.dunikey, self.pod)
deleteCesium = DeleteFromCesium(self.dunikey, self.pod)
# deleteCesium.issuer = recipient
for idMsg in idsMsgList:
finalDoc = deleteCesium.configDoc(idMsg, outbox)
@ -45,74 +40,40 @@ class CesiumPlus(CesiumCommon):
#################### Profiles ####################
def set(
self,
name=None,
description=None,
ville=None,
adresse=None,
position=None,
site=None,
avatar=None,
):
setProfile = Profiles(self.dunikey, self.pod)
document = setProfile.configDocSet(
name, description, ville, adresse, position, site, avatar
)
result = setProfile.sendDocument(document, "set")
def set(self, name=None, description=None, ville=None, adresse=None, position=None, site=None, avatar=None):
setProfile = Profiles(self.dunikey, self.pod)
document = setProfile.configDocSet(name, description, ville, adresse, position, site, avatar)
result = setProfile.sendDocument(document,'set')
print(result)
return result
def get(self, profile=None, avatar=None):
getProfile = Profiles(self.dunikey, self.pod, self.noNeedDunikey)
getProfile = Profiles(self.dunikey, self.pod, self.noNeedDunikey)
if not profile:
profile = self.pubkey
if not re.match(PUBKEY_REGEX, profile) or len(profile) > 45:
scope = "title"
scope = 'title'
else:
scope = "_id"
scope = '_id'
document = getProfile.configDocGet(profile, scope, avatar)
resultJSON = getProfile.sendDocument(document, "get")
resultJSON = getProfile.sendDocument(document, 'get')
result = getProfile.parseJSON(resultJSON)
print(result)
def getPage(self, page=None, avatar=None):
getPage = Pages(self.dunikey, self.pod, self.noNeedDunikey)
if not page:
page = self.pubkey
if not re.match(PUBKEY_REGEX, page) or len(page) > 45:
scope = "title"
else:
scope = "_id"
document = getPage.configDocGet(page, scope, avatar)
resultJSON = getPage.sendDocument(document, "get")
result = getPage.parseJSON(resultJSON)
print(result)
def erase(self):
eraseProfile = Profiles(self.dunikey, self.pod)
eraseProfile = Profiles(self.dunikey, self.pod)
document = eraseProfile.configDocErase()
result = eraseProfile.sendDocument(document, "erase")
result = eraseProfile.sendDocument(document,'erase')
print(result)
def geolocProfiles(self, node):
geolocProfiles = GeolocProfiles(self.dunikey, self.pod)
cesiumProfiles = geolocProfiles.getCesiumProfiles()
gvaProfiles = geolocProfiles.getGVAProfiles(node)
result = geolocProfiles.formatProfiles(cesiumProfiles, json.loads(gvaProfiles))
print(json.dumps(result))
#################### Likes ####################
def readLikes(self, profile=False):
likes = ReadLikes(self.dunikey, self.pod, self.noNeedDunikey)
likes = ReadLikes(self.dunikey, self.pod, self.noNeedDunikey)
document = likes.configDoc(profile)
result = likes.sendDocument(document)
result = likes.parseResult(result)
@ -120,13 +81,13 @@ class CesiumPlus(CesiumCommon):
print(result)
def like(self, stars, profile=False):
likes = SendLikes(self.dunikey, self.pod)
likes = SendLikes(self.dunikey, self.pod)
document = likes.configDoc(profile, stars)
if document:
likes.sendDocument(document, profile)
def unLike(self, pubkey, silent=False):
likes = UnLikes(self.dunikey, self.pod)
likes = UnLikes(self.dunikey, self.pod)
idLike = likes.checkLike(pubkey)
if idLike:
document = likes.configDoc(idLike)
@ -134,37 +95,26 @@ class CesiumPlus(CesiumCommon):
#################### Offer ####################
def setOffer(
self,
title=None,
description=None,
city=None,
location=None,
category=None,
price=None,
picture=None,
):
setOffer = Offers(self.dunikey, self.pod)
document = setOffer.configDocSet(
title, description, city, location, category, price, picture
)
result = setOffer.sendDocumentSet(document, "set")
def setOffer(self, title=None, description=None, city=None, localisation=None, category=None, price=None, picture=None):
setOffer = Offers(self.dunikey, self.pod)
document = setOffer.configDocSet(title, description, city, localisation, category, price, picture)
result = setOffer.sendDocumentSet(document,'set')
# print(result)
return result
def getOffer(self, id, avatar=None):
getOffer = Offers(self.dunikey, self.pod, self.noNeedDunikey)
resultJSON = getOffer.sendDocumentGet(id, "get")
getOffer = Offers(self.dunikey, self.pod, self.noNeedDunikey)
resultJSON = getOffer.sendDocumentGet(id, 'get')
# print(resultJSON)
result = getOffer.parseJSON(resultJSON)
print(result)
def deleteOffer(self, id):
eraseOffer = Offers(self.dunikey, self.pod)
eraseOffer = Offers(self.dunikey, self.pod)
document = eraseOffer.configDocErase(id)
result = eraseOffer.sendDocumentSet(document, "delete", id)
result = eraseOffer.sendDocumentSet(document,'delete', id)
print(result)

0
lib/currentUd.py Executable file → Normal file
View File

View File

@ -1,112 +0,0 @@
import requests
from time import time
from lib.cesiumCommon import CesiumCommon
from lib.gvaWallets import ListWallets
class GeolocProfiles(CesiumCommon):
def getCesiumProfiles(self):
# Send a POST request to the Cesium profiles API
response = requests.post(
"https://g1.data.e-is.pro/user/profile/_search?scroll=2m",
json={
"query": {
"constant_score": {
"filter": [
{"exists": {"field": "geoPoint"}},
{
"geo_bounding_box": {
"geoPoint": {
"top_left": {"lat": 90, "lon": -180},
"bottom_right": {"lat": -90, "lon": 180},
}
}
},
]
}
},
"_source": [
"title",
"avatar._content_type",
"description",
"city",
"address",
"socials.url",
"creationTime",
"membersCount",
"type",
"geoPoint",
],
"size": 20000,
},
)
scroll_id = response.json()["_scroll_id"]
finalResult: dict | None = response.json()["hits"]["hits"]
while True:
# Send a scroll request to get the next page
response_scroll = requests.post(
"https://g1.data.e-is.pro/_search/scroll",
json={"scroll_id": scroll_id, "scroll": "2m"},
)
# Check if the response is empty (no results) or if there's an error
if (
not response_scroll.json()["hits"]["hits"]
or "error" in response_scroll.json()
):
break
else:
finalResult.extend(response_scroll.json()["hits"]["hits"])
# Process the results here
# Delete the scroll context when done
requests.delete(
"https://g1.data.e-is.pro/_search/scroll", json={"scroll_id": [scroll_id]}
)
return finalResult
def getGVAProfiles(self, node):
# Retrieve GVA profiles using the ListWallets class
gva = ListWallets(node, map=True)
return gva.sendDoc()
def formatProfiles(self, cesiumProfiles, gvaProfiles):
walletsResult = []
for profile in cesiumProfiles:
source: dict = profile["_source"]
pubkey: dict = profile["_id"]
if pubkey not in gvaProfiles:
continue
# Extract necessary information from the profiles
id_info: dict = gvaProfiles[pubkey].get("id") or {}
isMember = id_info.get("isMember", False)
userId = id_info.get("username")
title = source.get("title")
city = source.get("city")
avatar = source.get("avatar")
socials = source.get("socials")
description = source.get("description")
address = source.get("address")
walletsResult.append(
{
"pubkey": pubkey,
**({"address": address} if address else {}),
**({"city": city} if city else {}),
**({"description": description} if description else {}),
**({"avatar": avatar} if avatar else {}),
**({"userId": userId} if userId else {}),
"isMember": isMember,
"geoPoint": source["geoPoint"],
**({"socials": socials} if socials else {}),
**({"title": title} if title else {}),
}
)
return {"wallets": walletsResult, "time": int(time())}

View File

@ -1,125 +0,0 @@
import sys, re, json, requests, base64
from time import time
from lib.cesiumCommon import CesiumCommon, PUBKEY_REGEX
class Pages(CesiumCommon):
# Configure JSON document SET to send
def configDocSet(self, name, description, city, address, pos, socials, avatar):
timeSent = int(time())
data = {}
if name: data['title'] = name
if description: data['description'] = description
if address: data['address'] = address
if city: data['city'] = city
if pos:
geoPoint = {}
geoPoint['lat'] = pos[0]
geoPoint['lon'] = pos[1]
data['geoPoint'] = geoPoint
if socials:
data['socials'] = []
data['socials'].append({})
data['socials'][0]['type'] = "web"
data['socials'][0]['url'] = socials
if avatar:
avatar = open(avatar, 'rb').read()
avatar = base64.b64encode(avatar).decode()
data['avatar'] = {}
data['avatar']['_content'] = avatar
data['avatar']['_content_type'] = "image/png"
data['time'] = timeSent
data['issuer'] = self.pubkey
data['version'] = 2
data['tags'] = []
document = json.dumps(data)
return self.signDoc(document)
# Configure JSON document GET to send
def configDocGet(self, profile, scope='title', getAvatar=None):
if getAvatar:
avatar = "avatar"
else:
avatar = "avatar._content_type"
data = {
"query": {
"bool": {
"should":[
{
"match":{
scope:{
"query": profile,"boost":2
}
}
},{
"prefix": {scope: profile}
}
]
}
},"highlight": {
"fields": {
"title":{},
"tags":{}
}
},"from":0,
"size":100,
"_source":["title", avatar,"description","city","address","socials.url","creationTime","membersCount","type","geoPoint"],
"indices_boost":{"user":100,"page":1,"group":0.01
}
}
document = json.dumps(data)
return document
# Configure JSON document SET to send
def configDocErase(self):
timeSent = int(time())
data = {}
data['time'] = timeSent
data['id'] = self.pubkey
data['issuer'] = self.pubkey
data['version'] = 2
data['index'] = "user"
data['type'] = "profile"
document = json.dumps(data)
return self.signDoc(document)
def sendDocument(self, document, type):
headers = {
'Content-type': 'application/json',
}
# Send JSON document and get JSON result
if type == 'set':
reqQuery = '{0}/user/profile?pubkey={1}/_update?pubkey={1}'.format(self.pod, self.pubkey)
elif type == 'get':
reqQuery = '{0}/user,page,group/profile,record/_search'.format(self.pod)
elif type == 'erase':
reqQuery = '{0}/history/delete'.format(self.pod)
result = requests.post(reqQuery, headers=headers, data=document)
if result.status_code == 200:
# print(result.text)
return result.text
else:
sys.stderr.write("Echec de l'envoi du document...\n" + result.text + '\n')
def parseJSON(self, doc):
doc = json.loads(doc)['hits']['hits']
if doc:
pubkey = { "pubkey": doc[0]['_id'] }
rest = doc[0]['_source']
final = {**pubkey, **rest}
return json.dumps(final, indent=2)
else:
return 'Profile vide'

View File

@ -1,5 +1,4 @@
from lib.currentUd import currentUd
from lib.gvaWallets import ListWallets
import sys, re
from lib.natools import get_privkey
from lib.gvaPay import Transaction, PUBKEY_REGEX
@ -39,7 +38,6 @@ class GvaApi():
#################### Payments ####################
def pay(self, amount, comment, mempool, verbose):
comment = " ".join(comment)
gva = Transaction(self.dunikey, self.node, self.destPubkey, amount, comment, mempool, verbose)
gva.genDoc()
gva.checkTXDoc()
@ -75,10 +73,4 @@ class GvaApi():
def currentUd(self):
gva = currentUd(self.node)
result = gva.sendDoc()
print(result)
def listWallets(self, brut, brutMbr, brutNonMbr, brutLarf):
gva = ListWallets(self.node, brut, brutMbr, brutNonMbr, brutLarf)
result = gva.sendDoc()
print(result)

View File

@ -43,11 +43,9 @@ class History:
node {
currency
issuers
blockstamp
outputs
comment
writtenTime
hash
}
}
}
@ -59,17 +57,13 @@ class History:
comment
outputs
receivedTime
blockstamp
hash
}
sending {
receiving {
currency
issuers
comment
outputs
receivedTime
blockstamp
hash
}
}
balance(script: $script) {
@ -125,7 +119,6 @@ class History:
trans[i] = []
trans[i].append(direction)
trans[i].append(transaction['writtenTime'])
if direction == 'SENT':
trans[i].append(outPubkey)
amount = int('-' + output.split(':')[0])
@ -140,12 +133,12 @@ class History:
trans[i].append(round(amount/self.UD, 2))
trans[i].append(transaction['comment'])
trans[i].append(base)
trans[i].append(transaction['blockstamp'])
trans[i].append(transaction['hash'])
i += 1
# Parse transactions in mempool
for direction, resBc in self.historyDoc['txsHistoryMp'].items():
for direction in self.historyDoc['txsHistoryMp']:
resBc = []
resBc = self.historyDoc['txsHistoryMp'][direction]
for j, transaction in enumerate(resBc):
# print(transaction)
transaction = resBc[j]
@ -154,11 +147,9 @@ class History:
# if direction == 'RECEIVING' or self.pubkey != outPubkey:
trans.append(i)
trans[i] = []
trans[i].append(direction.upper())
trans[i].append(transaction['receivedTime'])
# trans[i].append(int(time.time()))
if direction.upper() == 'SENDING':
trans[i].append(direction)
trans[i].append(int(time.time()))
if direction == 'SENDING':
trans[i].append(outPubkey)
amount = int('-' + output.split(':')[0])
else:
@ -172,8 +163,6 @@ class History:
trans[i].append(round(amount/self.UD, 2))
trans[i].append(transaction['comment'])
trans[i].append(base)
trans[i].append(transaction['blockstamp'])
trans[i].append(transaction['hash'])
i += 1
# Order transactions by date
@ -268,14 +257,11 @@ class History:
for i, trans in enumerate(transList):
dailyJSON.append(i)
dailyJSON[i] = {}
dailyJSON[i]['status'] = trans[0].upper()
dailyJSON[i]['date'] = trans[1]
dailyJSON[i]['pubkey'] = trans[2]
dailyJSON[i]['amount'] = trans[3]
dailyJSON[i]['amountUD'] = trans[4]
dailyJSON[i]['comment'] = trans[5]
dailyJSON[i]['blockstamp'] = trans[7]
dailyJSON[i]['hash'] = trans[8]
dailyJSON = json.dumps(dailyJSON, indent=2)
# If we want to write JSON to a file

0
lib/gvaID.py Executable file → Normal file
View File

View File

@ -1,100 +0,0 @@
#!/usr/bin/env python3
import sys
import json
from gql import gql, Client
from gql.transport.aiohttp import AIOHTTPTransport
from lib.natools import fmt, sign, get_privkey
class ListWallets:
def __init__(
self, node=False, brut=False, mbr=False, nonMbr=False, larf=False, map=False
):
# Initialize the ListWallets class with optional filters
self.mbr = mbr # Filter for members
self.larf = larf # Filter for non-empty identities
self.nonMbr = nonMbr # Filter for non-members
self.brut = brut # Output format flag (brut or JSON)
self.map = map # Output format flag (map or list)
# Define Duniter GVA node
transport = AIOHTTPTransport(url=node)
self.client = Client(transport=transport, fetch_schema_from_transport=True)
def sendDoc(self):
# Define the GraphQL query to retrieve wallet information
queryBuild = gql(
"""
{
wallets(pagination: { cursor: null, ord: ASC, pageSize: 0 }) {
pageInfo {
hasNextPage
endCursor
}
edges {
node {
script
balance {
amount
base
}
idty {
isMember
username
}
}
}
}
}
"""
)
try:
# Execute the GraphQL query
queryResult = self.client.execute(queryBuild)
except Exception as e:
# Handle any exceptions that occur during the query
sys.stderr.write("Failed to retrieve the list:\n" + str(e) + "\n")
sys.exit(1)
jsonBrut = queryResult["wallets"]["edges"]
walletList = []
walletMap = {}
for i, trans in enumerate(jsonBrut):
dataWork = trans["node"]
identity = dataWork["idty"]
is_member = identity and identity["isMember"]
# Apply filters based on member status and larf flag
member_filter = self.mbr and not is_member
non_member_filter = self.nonMbr and is_member
larf_filter = self.larf and identity
if member_filter or non_member_filter or larf_filter:
continue
wallet_data = {
"pubkey": dataWork["script"],
"balance": dataWork["balance"]["amount"] / 100,
"id": identity,
}
if self.map:
walletMap[dataWork["script"]] = wallet_data
else:
walletList.append(wallet_data)
if self.brut:
# Generate a list of formatted wallet names using list comprehension
names = [
wallet["pubkey"]
if not (self.mbr or self.nonMbr) or wallet["id"] is None
else f'{wallet["pubkey"]} {wallet["id"]["username"]}'
for wallet in walletList
]
return "\n".join(names)
else:
# Return JSON data in either map or list format
return json.dumps(walletMap if self.map else walletList, indent=2)

View File

@ -46,7 +46,6 @@ class ReadFromCesium(CesiumCommon):
# Parse JSON result and display messages
def readMessages(self, msgJSON, nbrMsg, outbox):
def decrypt(msg):
if msg is None: return ''
msg64 = base64.b64decode(msg)
return box_decrypt(msg64, get_privkey(self.dunikey, "pubsec"), self.issuer, nonce).decode()
@ -68,10 +67,7 @@ class ReadFromCesium(CesiumCommon):
msgSrc = hits["_source"]
self.issuer = msgSrc["issuer"]
nonce = msgSrc["nonce"]
try:
nonce = base58.b58decode(nonce)
except:
nonce = base58.b58decode('5aZdSqKGHBqm2uMPwN6XnfiiJKRieb1Hh')
nonce = base58.b58decode(nonce)
self.dateS = msgSrc["time"]
date = datetime.fromtimestamp(self.dateS).strftime(", le %d/%m/%Y à %H:%M ")
if outbox:
@ -98,7 +94,6 @@ class ReadFromCesium(CesiumCommon):
# Parse JSON result and display messages
def jsonMessages(self, msgJSON, nbrMsg, outbox):
def decrypt(msg):
if msg is None: return ''
msg64 = base64.b64decode(msg)
return box_decrypt(msg64, get_privkey(self.dunikey, "pubsec"), self.issuer, nonce).decode()
@ -118,10 +113,7 @@ class ReadFromCesium(CesiumCommon):
msgSrc = hits["_source"]
self.issuer = msgSrc["issuer"]
nonce = msgSrc["nonce"]
try:
nonce = base58.b58decode(nonce)
except:
nonce = base58.b58decode('5aZdSqKGHBqm2uMPwN6XnfiiJKRieb1Hh')
nonce = base58.b58decode(nonce)
self.date = msgSrc["time"]
if outbox:
@ -131,18 +123,11 @@ class ReadFromCesium(CesiumCommon):
try:
self.title = decrypt(msgSrc["title"])
except Exception as e:
self.title = "jaklis can't read that mother fucker"
# sys.stderr.write(colored(str('Error decrypt message title: ' + str(e)), 'red') + '\n')
# pp_json(hits)
try:
self.content = decrypt(msgSrc["content"])
except Exception as e:
self.content = "jaklis can't read that mother fucker"
# sys.stderr.write(colored(str('Error decrypt message content: ' + str(e)), 'red') + '\n')
# pp_json(hits)
sys.stderr.write(colored(str(e), 'red') + '\n')
pp_json(hits)
continue
data.append(i)
data[i] = {}
@ -151,7 +136,6 @@ class ReadFromCesium(CesiumCommon):
data[i]['pubkey'] = pubkey
data[i]['title'] = self.title
data[i]['content'] = self.content
# print('toto')
data = json.dumps(data, indent=2)
return data

10
lib/offers.py Executable file → Normal file
View File

@ -4,7 +4,7 @@ from lib.cesiumCommon import CesiumCommon, PUBKEY_REGEX
class Offers(CesiumCommon):
# Configure JSON document SET to send
def configDocSet(self, title, description, city, location, category, price: float, picture):
def configDocSet(self, title, description, city, localisation, category, price: float, picture):
timeSent = int(time())
# {"parent":"cat90","localizedNames":{"en":"Fruits &amp; Vegetables","es-ES":"Frutas y Vegetales","fr-FR":"Fruits &amp; Légumes"},"name":"Fruits &amp; Légumes","id":"cat92"}
@ -13,10 +13,10 @@ class Offers(CesiumCommon):
if title: data['title'] = title
if description: data['description'] = description
if city: data['city'] = city
if location:
if localisation:
geoPoint = {}
geoPoint['lat'] = location[0]
geoPoint['lon'] = location[1]
geoPoint['lat'] = localisation[0]
geoPoint['lon'] = localisation[1]
data['geoPoint'] = geoPoint
if picture:
picture = open(picture, 'rb').read()
@ -26,7 +26,7 @@ class Offers(CesiumCommon):
data['thumbnail']['_content_type'] = "image/png"
# if category: data['category'] = category
# else:
data['category'] = {"parent":"cat24","localizedNames":{"en":"DVD / Films","es-ES":"DVDs / Cine","fr-FR":"DVD / Films"},"name":"DVD / Films","id":"cat25"}
data['category'] = {"parent":"cat90","localizedNames":{"en":"Fruits &amp; Vegetables","es-ES":"Frutas y Vegetales","fr-FR":"Fruits &amp; Légumes"},"name":"Fruits &amp; Légumes","id":"cat92"}
if price: data['price'] = float(price) * 100
data['type'] = 'offer'
data['time'] = timeSent

View File

@ -1,4 +1,4 @@
import sys, json, requests, base64
import sys, re, json, requests, base64
from time import time
from lib.cesiumCommon import CesiumCommon, PUBKEY_REGEX
@ -9,74 +9,71 @@ class Profiles(CesiumCommon):
timeSent = int(time())
data = {}
if name:
data["title"] = name
if description:
data["description"] = description
if address:
data["address"] = address
if city:
data["city"] = city
if pos:
if name: data['title'] = name
if description: data['description'] = description
if address: data['address'] = address
if city: data['city'] = city
if pos:
geoPoint = {}
geoPoint["lat"] = pos[0]
geoPoint["lon"] = pos[1]
data["geoPoint"] = geoPoint
geoPoint['lat'] = pos[0]
geoPoint['lon'] = pos[1]
data['geoPoint'] = geoPoint
if socials:
data["socials"] = []
data["socials"].append({})
data["socials"][0]["type"] = "web"
data["socials"][0]["url"] = socials
data['socials'] = []
data['socials'].append({})
data['socials'][0]['type'] = "web"
data['socials'][0]['url'] = socials
if avatar:
avatar = open(avatar, "rb").read()
avatar = open(avatar, 'rb').read()
avatar = base64.b64encode(avatar).decode()
data["avatar"] = {}
data["avatar"]["_content"] = avatar
data["avatar"]["_content_type"] = "image/png"
data["time"] = timeSent
data["issuer"] = self.pubkey
data["version"] = 2
data["tags"] = []
data['avatar'] = {}
data['avatar']['_content'] = avatar
data['avatar']['_content_type'] = "image/png"
data['time'] = timeSent
data['issuer'] = self.pubkey
data['version'] = 2
data['tags'] = []
document = json.dumps(data)
document = json.dumps(data)
return self.signDoc(document)
# Configure JSON document GET to send
def configDocGet(self, profile, scope="title", getAvatar=None):
# Configure JSON document GET to send
def configDocGet(self, profile, scope='title', getAvatar=None):
if getAvatar:
avatar = "avatar"
else:
avatar = "avatar._content_type"
data = {
"query": {
"query": {
"bool": {
"should": [
{"match": {scope: {"query": profile, "boost": 2}}},
{"prefix": {scope: profile}},
"should":[
{
"match":{
scope:{
"query": profile,"boost":2
}
}
},{
"prefix": {scope: profile}
}
]
}
},
"highlight": {"fields": {"title": {}, "tags": {}}},
"from": 0,
"size": 100,
"_source": [
"title",
avatar,
"description",
"city",
"address",
"socials.url",
"creationTime",
"membersCount",
"type",
"geoPoint",
],
"indices_boost": {"user": 100, "page": 1, "group": 0.01},
},"highlight": {
"fields": {
"title":{},
"tags":{}
}
},"from":0,
"size":100,
"_source":["title", avatar,"description","city","address","socials.url","creationTime","membersCount","type","geoPoint"],
"indices_boost":{"user":100,"page":1,"group":0.01
}
}
document = json.dumps(data)
document = json.dumps(data)
return document
@ -85,45 +82,44 @@ class Profiles(CesiumCommon):
timeSent = int(time())
data = {}
data["time"] = timeSent
data["id"] = self.pubkey
data["issuer"] = self.pubkey
data["version"] = 2
data["index"] = "user"
data["type"] = "profile"
data['time'] = timeSent
data['id'] = self.pubkey
data['issuer'] = self.pubkey
data['version'] = 2
data['index'] = "user"
data['type'] = "profile"
document = json.dumps(data)
document = json.dumps(data)
return self.signDoc(document)
def sendDocument(self, document, type):
headers = {
"Content-type": "application/json",
'Content-type': 'application/json',
}
# Send JSON document and get JSON result
if type == "set":
reqQuery = "{0}/user/profile?pubkey={1}/_update?pubkey={1}".format(
self.pod, self.pubkey
)
elif type == "get":
reqQuery = "{0}/user,page,group/profile,record/_search".format(self.pod)
elif type == "erase":
reqQuery = "{0}/history/delete".format(self.pod)
if type == 'set':
reqQuery = '{0}/user/profile?pubkey={1}/_update?pubkey={1}'.format(self.pod, self.pubkey)
elif type == 'get':
reqQuery = '{0}/user,page,group/profile,record/_search'.format(self.pod)
elif type == 'erase':
reqQuery = '{0}/history/delete'.format(self.pod)
result = requests.post(reqQuery, headers=headers, data=document)
if result.status_code == 200:
# print(result.text)
return result.text
else:
sys.stderr.write("Echec de l'envoi du document...\n" + result.text + "\n")
sys.stderr.write("Echec de l'envoi du document...\n" + result.text + '\n')
def parseJSON(self, doc):
doc = json.loads(doc)["hits"]["hits"]
doc = json.loads(doc)['hits']['hits']
if doc:
pubkey = {"pubkey": doc[0]["_id"]}
rest = doc[0]["_source"]
pubkey = { "pubkey": doc[0]['_id'] }
rest = doc[0]['_source']
final = {**pubkey, **rest}
return json.dumps(final, indent=2)
else:
return "Profile vide"
return 'Profile vide'

View File

@ -1,8 +1,9 @@
wheel
base58
pybase64
duniterpy
duniterpy==0.62.0
termcolor
python-dotenv
gql
gql==3.0.0a5
#gql==2.0
requests

View File

@ -1,7 +1,5 @@
#!/bin/bash
hasError=0
for i in gcc python3-pip python3-setuptools libpq-dev python3-dev python3-wheel; do
if [ $(dpkg-query -W -f='${Status}' $i 2>/dev/null | grep -c "ok installed") -eq 0 ]; then
[[ ! $j ]] && sudo apt update
@ -10,12 +8,5 @@ for i in gcc python3-pip python3-setuptools libpq-dev python3-dev python3-wheel;
fi
done
pip3 install -r requirements.txt || hasError=1
pip3 install -r requirements.txt
chmod u+x jaklis.py
sudo ln -sf $(realpath jaklis.py) /usr/local/bin/jaklis || hasError=1
if [[ hasError -eq 0 ]]; then
echo "Setup done. You can use 'jaklis' command, try it."
else
echo "An error has occurred"
fi