Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
olb
hreports
Commits
cad182e8
Commit
cad182e8
authored
Aug 25, 2019
by
olb
Browse files
python packaging
parent
815ba9f1
Changes
18
Hide whitespace changes
Inline
Side-by-side
.gitignore
View file @
cad182e8
/settings.py
*.pyc
/python-env
/build/
/dist/
/hreports.egg-info/
/.vim/
*.pyc
.*.swp
README.md
View file @
cad182e8
Hreport build html reports on top of h
e
lger.
Hreport build html reports on top of hl
ed
ger.
There are several kinds of report :
...
...
bin/hreport
View file @
cad182e8
#!/usr/bin/env python
""" Annual report
"""
import
locale
import
logging
import
os
import
shutil
import
sys
from
jinja2
import
Environment
,
FileSystemLoader
from
hreports
import
settings
from
hreports.hledger
import
AccountingYears
,
Hledger
from
hreports.scripts
import
main
assert
sys
.
version_info
>=
(
3
,
5
)
logging
.
basicConfig
(
level
=
logging
.
INFO
)
LOGGER
=
logging
.
getLogger
(
'hreport'
)
TPL_ENV
=
Environment
(
loader
=
FileSystemLoader
(
settings
.
get
(
'TEMPLATES_DIRS'
)),
extensions
=
[
'jinja2.ext.with_'
],
)
def
incomes_statement
(
accounting_years
,
report
,
context
=
None
):
expenses
=
accounting_years
.
extract
(
match
=
'|'
.
join
(
report
[
'expenses'
][
'accounts'
]
))
incomes
=
accounting_years
.
extract
(
match
=
'|'
.
join
(
report
[
'incomes'
][
'accounts'
]
))
context
=
context
or
dict
()
context
.
update
({
'incomes'
:
incomes
,
'expenses'
:
expenses
,
'conf'
:
report
,
})
template
=
TPL_ENV
.
get_template
(
'income-statement.html'
)
return
template
.
render
(
**
context
)
def
balance_sheet
(
accounting_years
,
report
,
context
=
None
):
liabilities
=
accounting_years
.
extract
(
match
=
'|'
.
join
(
report
[
'liabilities'
][
'accounts'
]
))
assets
=
accounting_years
.
extract
(
match
=
'|'
.
join
(
report
[
'assets'
][
'accounts'
]
))
context
=
context
or
dict
()
context
.
update
({
'liabilities'
:
liabilities
,
'assets'
:
assets
,
'conf'
:
report
,
})
template
=
TPL_ENV
.
get_template
(
'balance-sheet.html'
)
return
template
.
render
(
**
context
)
def
cash
(
accounting_years
,
report
,
context
=
None
):
accounting_year
=
accounting_years
.
get_year
(
accounting_years
.
last_year
())
context
=
context
or
dict
()
context
.
update
({
'accounting_year'
:
accounting_year
,
'conf'
:
report
,
})
template
=
TPL_ENV
.
get_template
(
'cash.html'
)
return
template
.
render
(
**
context
)
def
chart_of_accounts
(
accounting_years
,
report
,
context
=
None
):
accounting_year
=
accounting_years
.
get_year
(
accounting_years
.
last_year
())
context
=
context
or
dict
()
context
.
update
({
'chart_of_accounts'
:
accounting_year
.
chart_of_accounts
,
'conf'
:
report
,
})
template
=
TPL_ENV
.
get_template
(
'chart-of-accounts.html'
)
return
template
.
render
(
**
context
)
def
process_args
(
argv
):
"""
No more options. Maybe in the futur.
"""
options
=
{}
return
options
def
load
(
options
):
accounting_years
=
AccountingYears
()
accounting_years_closed
=
AccountingYears
()
for
year
in
settings
.
get
(
'ACCOUNTING_YEARS'
):
LOGGER
.
info
(
'loading year %s with hledger'
,
year
)
hledger
=
Hledger
(
settings
.
get
(
'ACCOUNTING_YEARS_OPTIONS'
)[
year
][
'incomes_statement'
],
settings
.
get
(
'ACCOUNTING_YEARS_OPTIONS'
)[
year
][
'chart_of_accounts'
],
inverted
=
settings
.
get
(
'INVERTED'
),
)
accounting_years
.
add_year
(
hledger
.
accounting_year
(
year
)
)
LOGGER
.
info
(
'loading closed year %s with hledger'
,
year
)
hledger
=
Hledger
(
settings
.
get
(
'ACCOUNTING_YEARS_OPTIONS'
)[
year
][
'balance_sheet'
],
settings
.
get
(
'ACCOUNTING_YEARS_OPTIONS'
)[
year
][
'chart_of_accounts'
],
inverted
=
settings
.
get
(
'INVERTED'
),
)
accounting_years_closed
.
add_year
(
hledger
.
accounting_year
(
year
)
)
return
(
accounting_years
,
accounting_years_closed
)
def
doreport
(
accounting_years
,
accounting_years_closed
,
report
,
context
=
None
):
accounting_years
=
accounting_years
.
clone_until
(
report
[
'year'
])
accounting_years_closed
=
accounting_years_closed
.
clone_until
(
report
[
'year'
])
directory
=
os
.
path
.
dirname
(
report
[
'output'
])
css_path
=
os
.
path
.
join
(
settings
.
get
(
'OUTPUT_DIR'
),
'style.css'
)
css_url
=
os
.
path
.
relpath
(
css_path
,
directory
)
context
=
context
or
dict
()
context
.
update
({
'css_url'
:
css_url
,
})
if
report
[
'type'
]
in
[
'incomes_statement'
,
'is'
]:
output
=
incomes_statement
(
accounting_years
,
report
,
context
)
elif
report
[
'type'
]
in
[
'balance_sheet'
,
'bs'
]:
output
=
balance_sheet
(
accounting_years_closed
,
report
,
context
)
elif
report
[
'type'
]
in
[
'cash'
,
]:
output
=
cash
(
accounting_years
,
report
,
context
)
elif
report
[
'type'
]
in
[
'chart_of_accounts'
,
'coa'
]:
output
=
chart_of_accounts
(
accounting_years
,
report
,
context
)
if
not
os
.
path
.
exists
(
directory
):
os
.
makedirs
(
directory
)
elif
not
os
.
path
.
isdir
(
directory
):
raise
Exception
(
'%s must be a directory'
%
directory
)
LOGGER
.
info
(
'write report %s to file %s'
,
report
[
'output'
],
report
[
'type'
])
ofile
=
open
(
report
[
'output'
],
'w+'
)
print
(
output
,
file
=
ofile
)
ofile
.
close
()
def
doreports
(
options
):
(
accounting_years
,
accounting_years_closed
)
=
load
(
options
)
for
report
in
settings
.
get
(
'REPORTS'
):
doreport
(
accounting_years
,
accounting_years_closed
,
report
)
def
doindex
(
options
,
context
=
None
):
template
=
TPL_ENV
.
get_template
(
'index.html'
)
output
=
os
.
path
.
join
(
settings
.
get
(
'OUTPUT_DIR'
),
'index.html'
)
ofile
=
open
(
output
,
'w+'
)
reports
=
settings
.
get
(
'REPORTS'
)
reports_by_year
=
{}
for
report
in
reports
:
if
not
report
[
'year'
]
in
reports_by_year
:
reports_by_year
[
report
[
'year'
]]
=
[]
reports_by_year
[
report
[
'year'
]].
append
(
report
)
context
=
context
or
dict
()
context
.
update
({
'css_url'
:
'style.css'
,
'accounting_years'
:
settings
.
get
(
'ACCOUNTING_YEARS'
),
'reports'
:
reports_by_year
,
})
LOGGER
.
info
(
'write index to file %s'
,
output
)
print
(
template
.
render
(
**
context
),
file
=
ofile
)
def
doassets
(
options
):
source
=
os
.
path
.
join
(
settings
.
get
(
'STATIC_DIR'
),
'style.css'
)
output
=
os
.
path
.
join
(
settings
.
get
(
'OUTPUT_DIR'
),
'style.css'
)
LOGGER
.
info
(
'copy %s to %s'
,
source
,
output
)
shutil
.
copyfile
(
source
,
output
)
def
main
(
argv
):
locale
.
setlocale
(
locale
.
LC_ALL
,
'fr_FR.utf-8'
)
options
=
process_args
(
argv
)
doreports
(
options
)
doindex
(
options
)
doassets
(
options
)
if
__name__
==
"__main__"
:
main
(
sys
.
argv
[
1
:])
main
()
hreports/scripts.py
0 → 100755
View file @
cad182e8
#!/usr/bin/env python
""" Annual report
"""
import
locale
import
logging
import
os
import
shutil
import
sys
assert
sys
.
version_info
>=
(
3
,
5
)
from
jinja2
import
Environment
,
FileSystemLoader
from
hreports
import
settings
from
hreports.hledger
import
AccountingYears
,
Hledger
logging
.
basicConfig
(
level
=
logging
.
INFO
)
LOGGER
=
logging
.
getLogger
(
'hreport'
)
TPL_ENV
=
Environment
(
loader
=
FileSystemLoader
(
settings
.
get
(
'TEMPLATES_DIR'
)),
extensions
=
[
'jinja2.ext.with_'
],
)
def
incomes_statement
(
accounting_years
,
report
,
context
=
None
):
expenses
=
accounting_years
.
extract
(
match
=
'|'
.
join
(
report
[
'expenses'
][
'accounts'
]
))
incomes
=
accounting_years
.
extract
(
match
=
'|'
.
join
(
report
[
'incomes'
][
'accounts'
]
))
context
=
context
or
dict
()
context
.
update
({
'incomes'
:
incomes
,
'expenses'
:
expenses
,
'conf'
:
report
,
})
template
=
TPL_ENV
.
get_template
(
'income-statement.html'
)
return
template
.
render
(
**
context
)
def
balance_sheet
(
accounting_years
,
report
,
context
=
None
):
liabilities
=
accounting_years
.
extract
(
match
=
'|'
.
join
(
report
[
'liabilities'
][
'accounts'
]
))
assets
=
accounting_years
.
extract
(
match
=
'|'
.
join
(
report
[
'assets'
][
'accounts'
]
))
context
=
context
or
dict
()
context
.
update
({
'liabilities'
:
liabilities
,
'assets'
:
assets
,
'conf'
:
report
,
})
template
=
TPL_ENV
.
get_template
(
'balance-sheet.html'
)
return
template
.
render
(
**
context
)
def
cash
(
accounting_years
,
report
,
context
=
None
):
accounting_year
=
accounting_years
.
get_year
(
accounting_years
.
last_year
())
context
=
context
or
dict
()
context
.
update
({
'accounting_year'
:
accounting_year
,
'conf'
:
report
,
})
template
=
TPL_ENV
.
get_template
(
'cash.html'
)
return
template
.
render
(
**
context
)
def
chart_of_accounts
(
accounting_years
,
report
,
context
=
None
):
accounting_year
=
accounting_years
.
get_year
(
accounting_years
.
last_year
())
context
=
context
or
dict
()
context
.
update
({
'chart_of_accounts'
:
accounting_year
.
chart_of_accounts
,
'conf'
:
report
,
})
template
=
TPL_ENV
.
get_template
(
'chart-of-accounts.html'
)
return
template
.
render
(
**
context
)
def
process_args
(
argv
):
"""
No more options. Maybe in the futur.
"""
options
=
{}
return
options
def
load
(
options
):
accounting_years
=
AccountingYears
()
accounting_years_closed
=
AccountingYears
()
for
year
in
settings
.
get
(
'ACCOUNTING_YEARS'
):
LOGGER
.
info
(
'loading year %s with hledger'
,
year
)
hledger
=
Hledger
(
settings
.
get
(
'ACCOUNTING_YEARS_OPTIONS'
)[
year
][
'incomes_statement'
],
settings
.
get
(
'ACCOUNTING_YEARS_OPTIONS'
)[
year
][
'chart_of_accounts'
],
inverted
=
settings
.
get
(
'INVERTED'
),
)
accounting_years
.
add_year
(
hledger
.
accounting_year
(
year
)
)
LOGGER
.
info
(
'loading closed year %s with hledger'
,
year
)
hledger
=
Hledger
(
settings
.
get
(
'ACCOUNTING_YEARS_OPTIONS'
)[
year
][
'balance_sheet'
],
settings
.
get
(
'ACCOUNTING_YEARS_OPTIONS'
)[
year
][
'chart_of_accounts'
],
inverted
=
settings
.
get
(
'INVERTED'
),
)
accounting_years_closed
.
add_year
(
hledger
.
accounting_year
(
year
)
)
return
(
accounting_years
,
accounting_years_closed
)
def
doreport
(
accounting_years
,
accounting_years_closed
,
report
,
context
=
None
):
accounting_years
=
accounting_years
.
clone_until
(
report
[
'year'
])
accounting_years_closed
=
accounting_years_closed
.
clone_until
(
report
[
'year'
])
directory
=
os
.
path
.
dirname
(
report
[
'output'
])
css_path
=
os
.
path
.
join
(
settings
.
get
(
'OUTPUT_DIR'
),
'style.css'
)
css_url
=
os
.
path
.
relpath
(
css_path
,
directory
)
context
=
context
or
dict
()
context
.
update
({
'css_url'
:
css_url
,
})
if
report
[
'type'
]
in
[
'incomes_statement'
,
'is'
]:
output
=
incomes_statement
(
accounting_years
,
report
,
context
)
elif
report
[
'type'
]
in
[
'balance_sheet'
,
'bs'
]:
output
=
balance_sheet
(
accounting_years_closed
,
report
,
context
)
elif
report
[
'type'
]
in
[
'cash'
,
]:
output
=
cash
(
accounting_years
,
report
,
context
)
elif
report
[
'type'
]
in
[
'chart_of_accounts'
,
'coa'
]:
output
=
chart_of_accounts
(
accounting_years
,
report
,
context
)
if
not
os
.
path
.
exists
(
directory
):
os
.
makedirs
(
directory
)
elif
not
os
.
path
.
isdir
(
directory
):
raise
Exception
(
'%s must be a directory'
%
directory
)
LOGGER
.
info
(
'write report %s to file %s'
,
report
[
'output'
],
report
[
'type'
])
ofile
=
open
(
report
[
'output'
],
'w+'
)
print
(
output
,
file
=
ofile
)
ofile
.
close
()
def
doreports
(
options
):
(
accounting_years
,
accounting_years_closed
)
=
load
(
options
)
for
report
in
settings
.
get
(
'REPORTS'
):
doreport
(
accounting_years
,
accounting_years_closed
,
report
)
def
doindex
(
options
,
context
=
None
):
template
=
TPL_ENV
.
get_template
(
'index.html'
)
output
=
os
.
path
.
join
(
settings
.
get
(
'OUTPUT_DIR'
),
'index.html'
)
ofile
=
open
(
output
,
'w+'
)
reports
=
settings
.
get
(
'REPORTS'
)
reports_by_year
=
{}
for
report
in
reports
:
if
not
report
[
'year'
]
in
reports_by_year
:
reports_by_year
[
report
[
'year'
]]
=
[]
reports_by_year
[
report
[
'year'
]].
append
(
report
)
context
=
context
or
dict
()
context
.
update
({
'css_url'
:
'style.css'
,
'accounting_years'
:
settings
.
get
(
'ACCOUNTING_YEARS'
),
'reports'
:
reports_by_year
,
})
LOGGER
.
info
(
'write index to file %s'
,
output
)
print
(
template
.
render
(
**
context
),
file
=
ofile
)
def
doassets
(
options
):
source
=
os
.
path
.
join
(
settings
.
get
(
'STATIC_DIR'
),
'style.css'
)
output
=
os
.
path
.
join
(
settings
.
get
(
'OUTPUT_DIR'
),
'style.css'
)
LOGGER
.
info
(
'copy %s to %s'
,
source
,
output
)
shutil
.
copyfile
(
source
,
output
)
def
main
():
locale
.
setlocale
(
locale
.
LC_ALL
,
'fr_FR.utf-8'
)
argv
=
sys
.
argv
[
1
:]
options
=
process_args
(
argv
)
doreports
(
options
)
doindex
(
options
)
doassets
(
options
)
if
__name__
==
"__main__"
:
main
()
hreports/settings.py
View file @
cad182e8
...
...
@@ -28,13 +28,13 @@ if __SETTINGS is None:
if
'OUTPUT_DIR'
not
in
__SETTINGS
:
raise
Exception
(
'need OUTPUT_DIR settings'
)
if
'TEMPLATES_DIR
S
'
not
in
__SETTINGS
:
__SETTINGS
[
'TEMPLATES_DIR
S
'
]
=
os
.
path
.
join
(
os
.
path
.
dirname
(
__file__
),
'..'
,
'templates'
)
if
'TEMPLATES_DIR'
not
in
__SETTINGS
:
__SETTINGS
[
'TEMPLATES_DIR'
]
=
os
.
path
.
join
(
os
.
path
.
dirname
(
__file__
),
'templates'
)
if
'STATIC_DIR'
not
in
__SETTINGS
:
__SETTINGS
[
'STATIC_DIR'
]
=
os
.
path
.
join
(
os
.
path
.
dirname
(
__file__
),
'..'
,
'static'
)
os
.
path
.
dirname
(
__file__
),
'static'
)
if
'INVERTED'
not
in
__SETTINGS
:
__SETTINGS
[
'INVERTED'
]
=
False
...
...
static/style.css
→
hreports/
static/style.css
View file @
cad182e8
File moved
templates/balance-sheet.html
→
hreports/
templates/balance-sheet.html
View file @
cad182e8
File moved
templates/base.html
→
hreports/
templates/base.html
View file @
cad182e8
File moved
templates/cash.html
→
hreports/
templates/cash.html
View file @
cad182e8
File moved
templates/chart-of-accounts.html
→
hreports/
templates/chart-of-accounts.html
View file @
cad182e8
File moved
templates/inc/account.html
→
hreports/
templates/inc/account.html
View file @
cad182e8
File moved
templates/inc/balance-sheet-part.html
→
hreports/
templates/inc/balance-sheet-part.html
View file @
cad182e8
File moved
templates/inc/income-statement-part.html
→
hreports/
templates/inc/income-statement-part.html
View file @
cad182e8
File moved
templates/inc/value-percent.html
→
hreports/
templates/inc/value-percent.html
View file @
cad182e8
File moved
templates/income-statement.html
→
hreports/
templates/income-statement.html
View file @
cad182e8
File moved
templates/index.html
→
hreports/
templates/index.html
View file @
cad182e8
File moved
requirements.
pip
→
requirements.
txt
View file @
cad182e8
File moved
setup.py
0 → 100644
View file @
cad182e8
import
setuptools
with
open
(
"README.md"
,
"r"
)
as
fh
:
long_description
=
fh
.
read
()
setuptools
.
setup
(
name
=
"hreports"
,
version
=
"0.0.1"
,
author
=
"olb"
,
author_email
=
"olb@nebkha.net"
,
description
=
"build html reports on top of hledger"
,
long_description
=
long_description
,
long_description_content_type
=
"text/markdown"
,
url
=
"https://forge.gresille.org/olb/hreports"
,
packages
=
setuptools
.
find_packages
(),
package_data
=
{
'hreports'
:
[
'templates/*'
,
'templates/inc/*'
,
'static/*'
,
]
},
classifiers
=
[
"Programming Language :: Python :: 3"
,
"Operating System :: OS Independent"
,
],
install_requires
=
[
'jinja2'
,
],
python_requires
=
'>=3'
,
entry_points
=
{
'console_scripts'
:
[
'hreport=hreports.scripts:main'
,
],
},
)
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment