Commit 531f8e82 authored by Ferry Jérémie's avatar Ferry Jérémie
Browse files

first commit

parents
build
*.egg-info
*.pyc
debian/*
debian/debhelper-build-stamp
debian/*.debhelper.log
debian/*.substvars
apt install python-flask
export FLASK_APP=primtuxmenu.py
flask run
CREATE TABLE IF NOT EXISTS results (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name varchar(255) NOT NULL,
app_name varchar(255) NOT NULL,
icon_path varchar(2048) NOT NULL,
path varchar(2048) NOT NULL,
generic varchar(255) NOT NULL,
cat_name varchar(255) NULL,
sub_cat_name varchar(255) NULL,
sub_sub_cat_name varchar(255) NULL,
in_mini BOOLEAN NOT NULL CHECK (in_mini IN (0, 1)),
in_super BOOLEAN NOT NULL CHECK (in_super IN (0, 1)),
in_maxi BOOLEAN NOT NULL CHECK (in_maxi IN (0, 1)),
in_prof BOOLEAN NOT NULL CHECK (in_prof IN (0, 1))
);
CREATE TABLE IF NOT EXISTS keywords (
id INTEGER PRIMARY KEY AUTOINCREMENT,
text varchar(255) NOT NULL
);
CREATE TABLE IF NOT EXISTS contains (
id INTEGER PRIMARY KEY AUTOINCREMENT,
id_results INTEGER,
id_keywords INTEGER,
FOREIGN KEY(id_results) REFERENCES results(id)
FOREIGN KEY(id_keywords) REFERENCES keywords(id)
);
DROP TABLE IF EXISTS results;
DROP TABLE IF EXISTS keywords;
DROP TABLE IF EXISTS contains;
digraph models_diagram {
graph[rankdir=LR, overlap=false, splines=true]
link2 [label="Contains",shape=ellipse,color=green]
table1 [shape=none, label=<
<table border="0" cellborder="1" cellspacing="0">
<tr>
<td bgcolor="lightblue"><b>Results</b></td>
</tr>
<tr>
<td align="left" port="c0"><b>id : </b> int</td>
</tr>
<tr>
<td align="left"><b>title: </b> varchar 255</td>
</tr>
<tr>
<td align="left"><b>path: </b> varchar 1024</td>
</tr>
<tr>
<td align="left"><b>icon_path: </b> varchar 1024</td>
</tr>
<tr>
<td align="left"><b>cat_name: </b> varchar 255</td>
</tr>
<tr>
<td align="left"><b>sub_cat_name: </b> varchar 255</td>
</tr>
<tr>
<td align="left"><b>sub_sub_cat_name: </b> varchar 255</td>
</tr>
<tr>
<td align="left"><b>in_mini: </b> bool</td>
</tr>
<tr>
<td align="left"><b>in_super: </b> bool</td>
</tr>
<tr>
<td align="left"><b>in_maxi: </b> bool</td>
</tr>
<tr>
<td align="left"><b>in_prof: </b> bool</td>
</tr>
</table>>
]
table2 [shape=none, label=<
<table border="0" cellborder="1" cellspacing="0">
<tr>
<td bgcolor="lightblue"><b>Keywords</b></td>
</tr>
<tr>
<td align="left" port="c0"><b>id : </b> int</td>
</tr>
<tr>
<td align="left"><b>name : </b> varchar 255</td>
</tr>
</table>>
]
table3 [shape=none, label=<
<table border="0" cellborder="1" cellspacing="0">
<tr>
<td bgcolor="lightblue"><b>Categories</b></td>
</tr>
<tr>
<td align="left" port="c0"><b>id : </b> int</td>
</tr>
<tr>
<td align="left"><b>name : </b> varchar 255</td>
</tr>
<tr>
<td align="left"><b>parent_id: </b> int</td>
</tr>
<tr>
<td align="left"><b>deep: </b> int</td>
</tr>
<tr>
<td align="left"><b>in_mini: </b> bool</td>
</tr>
<tr>
<td align="left"><b>in_super: </b> bool</td>
</tr>
<tr>
<td align="left"><b>in_maxi: </b> bool</td>
</tr>
<tr>
<td align="left"><b>in_prof: </b> bool</td>
</tr>
</table>>
]
table1:c0 -> link2 [label="3,n"];
link2 -> table2:c0 [label="1,n"];
}
diagram.png

48.4 KB

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!-- Generated by graphviz version 2.38.0 (20140413.2041)
-->
<!-- Title: models_diagram Pages: 1 -->
<svg width="546pt" height="462pt"
viewBox="0.00 0.00 546.49 462.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 458)">
<title>models_diagram</title>
<polygon fill="white" stroke="none" points="-4,4 -4,-458 542.493,-458 542.493,4 -4,4"/>
<!-- link2 -->
<g id="node1" class="node"><title>link2</title>
<ellipse fill="none" stroke="green" cx="306.246" cy="-203.5" rx="42.4939" ry="18"/>
<text text-anchor="middle" x="306.246" y="-199.8" font-family="Times,serif" font-size="14.00">Contains</text>
</g>
<!-- table2 -->
<g id="node3" class="node"><title>table2</title>
<polygon fill="lightblue" stroke="none" points="410.493,-214.5 410.493,-235.5 530.493,-235.5 530.493,-214.5 410.493,-214.5"/>
<polygon fill="none" stroke="black" points="410.493,-214.5 410.493,-235.5 530.493,-235.5 530.493,-214.5 410.493,-214.5"/>
<text text-anchor="start" x="440.493" y="-222.3" font-family="Times,serif" font-weight="bold" font-size="14.00">Keywords</text>
<polygon fill="none" stroke="black" points="410.493,-193.5 410.493,-214.5 530.493,-214.5 530.493,-193.5 410.493,-193.5"/>
<text text-anchor="start" x="413.493" y="-201.3" font-family="Times,serif" font-weight="bold" font-size="14.00">id : </text>
<text text-anchor="start" x="437.493" y="-201.3" font-family="Times,serif" font-size="14.00"> int</text>
<polygon fill="none" stroke="black" points="410.493,-172.5 410.493,-193.5 530.493,-193.5 530.493,-172.5 410.493,-172.5"/>
<text text-anchor="start" x="413.493" y="-180.3" font-family="Times,serif" font-weight="bold" font-size="14.00">name : </text>
<text text-anchor="start" x="458.493" y="-180.3" font-family="Times,serif" font-size="14.00"> varchar 255</text>
</g>
<!-- link2&#45;&gt;table2 -->
<g id="edge2" class="edge"><title>link2&#45;&gt;table2:c0</title>
<path fill="none" stroke="black" d="M348.538,-203.5C364.106,-203.5 382.224,-203.5 399.467,-203.5"/>
<polygon fill="black" stroke="black" points="399.493,-207 409.493,-203.5 399.492,-200 399.493,-207"/>
<text text-anchor="middle" x="375.493" y="-207.3" font-family="Times,serif" font-size="14.00">1,n</text>
</g>
<!-- table1 -->
<g id="node2" class="node"><title>table1</title>
<polygon fill="lightblue" stroke="none" points="8,-213.5 8,-234.5 202,-234.5 202,-213.5 8,-213.5"/>
<polygon fill="none" stroke="black" points="8,-213.5 8,-234.5 202,-234.5 202,-213.5 8,-213.5"/>
<text text-anchor="start" x="83.5" y="-221.3" font-family="Times,serif" font-weight="bold" font-size="14.00">Results</text>
<polygon fill="none" stroke="black" points="8,-192.5 8,-213.5 202,-213.5 202,-192.5 8,-192.5"/>
<text text-anchor="start" x="11" y="-200.3" font-family="Times,serif" font-weight="bold" font-size="14.00">id : </text>
<text text-anchor="start" x="35" y="-200.3" font-family="Times,serif" font-size="14.00"> int</text>
<polygon fill="none" stroke="black" points="8,-171.5 8,-192.5 202,-192.5 202,-171.5 8,-171.5"/>
<text text-anchor="start" x="11" y="-179.3" font-family="Times,serif" font-weight="bold" font-size="14.00">title: </text>
<text text-anchor="start" x="42" y="-179.3" font-family="Times,serif" font-size="14.00"> varchar 255</text>
<polygon fill="none" stroke="black" points="8,-150.5 8,-171.5 202,-171.5 202,-150.5 8,-150.5"/>
<text text-anchor="start" x="11" y="-158.3" font-family="Times,serif" font-weight="bold" font-size="14.00">path: </text>
<text text-anchor="start" x="46" y="-158.3" font-family="Times,serif" font-size="14.00"> varchar 1024</text>
<polygon fill="none" stroke="black" points="8,-129.5 8,-150.5 202,-150.5 202,-129.5 8,-129.5"/>
<text text-anchor="start" x="11" y="-137.3" font-family="Times,serif" font-weight="bold" font-size="14.00">cat_name: </text>
<text text-anchor="start" x="76" y="-137.3" font-family="Times,serif" font-size="14.00"> varchar 255</text>
<polygon fill="none" stroke="black" points="8,-108.5 8,-129.5 202,-129.5 202,-108.5 8,-108.5"/>
<text text-anchor="start" x="11" y="-116.3" font-family="Times,serif" font-weight="bold" font-size="14.00">sub_cat_name: </text>
<text text-anchor="start" x="103" y="-116.3" font-family="Times,serif" font-size="14.00"> varchar 255</text>
<polygon fill="none" stroke="black" points="8,-87.5 8,-108.5 202,-108.5 202,-87.5 8,-87.5"/>
<text text-anchor="start" x="11" y="-95.3" font-family="Times,serif" font-weight="bold" font-size="14.00">sub_sub_cat_name: </text>
<text text-anchor="start" x="130" y="-95.3" font-family="Times,serif" font-size="14.00"> varchar 255</text>
<polygon fill="none" stroke="black" points="8,-66.5 8,-87.5 202,-87.5 202,-66.5 8,-66.5"/>
<text text-anchor="start" x="11" y="-74.3" font-family="Times,serif" font-weight="bold" font-size="14.00">in_mini: </text>
<text text-anchor="start" x="65" y="-74.3" font-family="Times,serif" font-size="14.00"> bool</text>
<polygon fill="none" stroke="black" points="8,-45.5 8,-66.5 202,-66.5 202,-45.5 8,-45.5"/>
<text text-anchor="start" x="11" y="-53.3" font-family="Times,serif" font-weight="bold" font-size="14.00">in_super: </text>
<text text-anchor="start" x="70" y="-53.3" font-family="Times,serif" font-size="14.00"> bool</text>
<polygon fill="none" stroke="black" points="8,-24.5 8,-45.5 202,-45.5 202,-24.5 8,-24.5"/>
<text text-anchor="start" x="11" y="-32.3" font-family="Times,serif" font-weight="bold" font-size="14.00">in_maxi: </text>
<text text-anchor="start" x="67" y="-32.3" font-family="Times,serif" font-size="14.00"> bool</text>
<polygon fill="none" stroke="black" points="8,-3.5 8,-24.5 202,-24.5 202,-3.5 8,-3.5"/>
<text text-anchor="start" x="11" y="-11.3" font-family="Times,serif" font-weight="bold" font-size="14.00">in_prof: </text>
<text text-anchor="start" x="63" y="-11.3" font-family="Times,serif" font-size="14.00"> bool</text>
</g>
<!-- table1&#45;&gt;link2 -->
<g id="edge1" class="edge"><title>table1:c0&#45;&gt;link2</title>
<path fill="none" stroke="black" d="M203,-203.5C219.454,-203.5 237.398,-203.5 253.596,-203.5"/>
<polygon fill="black" stroke="black" points="253.954,-207 263.954,-203.5 253.954,-200 253.954,-207"/>
<text text-anchor="middle" x="237" y="-207.3" font-family="Times,serif" font-size="14.00">3,n</text>
</g>
<!-- table3 -->
<g id="node4" class="node"><title>table3</title>
<polygon fill="lightblue" stroke="none" points="45,-428.5 45,-449.5 165,-449.5 165,-428.5 45,-428.5"/>
<polygon fill="none" stroke="black" points="45,-428.5 45,-449.5 165,-449.5 165,-428.5 45,-428.5"/>
<text text-anchor="start" x="74" y="-436.3" font-family="Times,serif" font-weight="bold" font-size="14.00">Categories</text>
<polygon fill="none" stroke="black" points="45,-407.5 45,-428.5 165,-428.5 165,-407.5 45,-407.5"/>
<text text-anchor="start" x="48" y="-415.3" font-family="Times,serif" font-weight="bold" font-size="14.00">id : </text>
<text text-anchor="start" x="72" y="-415.3" font-family="Times,serif" font-size="14.00"> int</text>
<polygon fill="none" stroke="black" points="45,-386.5 45,-407.5 165,-407.5 165,-386.5 45,-386.5"/>
<text text-anchor="start" x="48" y="-394.3" font-family="Times,serif" font-weight="bold" font-size="14.00">name : </text>
<text text-anchor="start" x="93" y="-394.3" font-family="Times,serif" font-size="14.00"> varchar 255</text>
<polygon fill="none" stroke="black" points="45,-365.5 45,-386.5 165,-386.5 165,-365.5 45,-365.5"/>
<text text-anchor="start" x="48" y="-373.3" font-family="Times,serif" font-weight="bold" font-size="14.00">parent_id: </text>
<text text-anchor="start" x="113" y="-373.3" font-family="Times,serif" font-size="14.00"> int</text>
<polygon fill="none" stroke="black" points="45,-344.5 45,-365.5 165,-365.5 165,-344.5 45,-344.5"/>
<text text-anchor="start" x="48" y="-352.3" font-family="Times,serif" font-weight="bold" font-size="14.00">deep: </text>
<text text-anchor="start" x="84" y="-352.3" font-family="Times,serif" font-size="14.00"> int</text>
<polygon fill="none" stroke="black" points="45,-323.5 45,-344.5 165,-344.5 165,-323.5 45,-323.5"/>
<text text-anchor="start" x="48" y="-331.3" font-family="Times,serif" font-weight="bold" font-size="14.00">in_mini: </text>
<text text-anchor="start" x="102" y="-331.3" font-family="Times,serif" font-size="14.00"> bool</text>
<polygon fill="none" stroke="black" points="45,-302.5 45,-323.5 165,-323.5 165,-302.5 45,-302.5"/>
<text text-anchor="start" x="48" y="-310.3" font-family="Times,serif" font-weight="bold" font-size="14.00">in_super: </text>
<text text-anchor="start" x="107" y="-310.3" font-family="Times,serif" font-size="14.00"> bool</text>
<polygon fill="none" stroke="black" points="45,-281.5 45,-302.5 165,-302.5 165,-281.5 45,-281.5"/>
<text text-anchor="start" x="48" y="-289.3" font-family="Times,serif" font-weight="bold" font-size="14.00">in_maxi: </text>
<text text-anchor="start" x="104" y="-289.3" font-family="Times,serif" font-size="14.00"> bool</text>
<polygon fill="none" stroke="black" points="45,-260.5 45,-281.5 165,-281.5 165,-260.5 45,-260.5"/>
<text text-anchor="start" x="48" y="-268.3" font-family="Times,serif" font-weight="bold" font-size="14.00">in_prof: </text>
<text text-anchor="start" x="100" y="-268.3" font-family="Times,serif" font-size="14.00"> bool</text>
</g>
</g>
</svg>
.PHONY: unittest flake8 run test diagram clean
unittest:
python3 -m unittest
flake8:
flake8 --filename="*.py./primtuxmenu"
run:
flask run --reload
test:
make unittest
make flake8
diagram:
dot -Tpng diagram.dot -o diagram.png
dot -Tsvg diagram.dot -o diagram.svg
clean:
rm -f MANIFEST
rm -rf build dist
from os.path import join
from .debug import is_debug_mode
class DbConf:
path = 'primtuxstore.db'
drop_path = join('SQL', 'DROP.sql')
create_path = join('SQL', 'CREATE.sql')
def __init__(self, debug=False):
if debug:
return
self.path = ''
class Conf:
sessions = ['super', 'mini', 'maxi', 'prof']
results_by_page = 10
def __init__(self, verbose=False):
"""Init Primtux store config"""
self.verbose = verbose
self.DEBUG = False
if is_debug_mode():
self.DEBUG = True
self.assets = ''
self.db = DbConf(self.DEBUG)
from os.path import join
from .debug import is_debug_mode
class DbConf:
path = 'primtuxstore.db'
drop_path = join('SQL', 'DROP.sql')
create_path = join('SQL', 'CREATE.sql')
def __init__(self, debug=False):
if debug:
return
self.path = ''
class Conf:
sessions = ['super', 'mini', 'maxi', 'prof']
results_by_page = 10
def __init__(self, verbose=False):
"""Init Primtux store config"""
self.verbose = verbose
self.DEBUG = False
if is_debug_mode():
self.DEBUG = True
self.assets = ''
self.db = DbConf(self.DEBUG)
import os
from os.path import dirname, join, isdir
import sys
def is_debug_mode():
return True
#d = dirname(sys.modules["pstore"].__file__)
#if isdir(join(d, '..', '.git')):
# return True
#return False
DELTA = 2
def pagination(current, last):
if last <= 1:
return
_range = []
range_with_dots = []
l = None
for i in range(1, last + 1):
if (
i == 1 or i == last
or i >= (current - DELTA)
and i < (current + DELTA + 1)
):
_range.append(i)
for i in _range:
if l:
if (i - l) == 2:
range_with_dots.append(l + 1)
elif i - l != 1:
range_with_dots.append('...')
range_with_dots.append(i)
l = i
return range_with_dots
import re
import inspect
import sqlite3
class DataBase:
def __init__(self, conf):
self.debug = conf.DEBUG
self.db = sqlite3.connect(conf.db.path)
self.db.row_factory = sqlite3.Row
def _where_like(self, value):
if value:
return "WHERE k.text LIKE '" + value + "%'"
return ''
def _exec(self, request, commit=False):
if self.debug:
request = re.sub('\s+', ' ', request).strip()
previous_frame = inspect.currentframe().f_back
frame = inspect.getframeinfo(previous_frame)
print('sql (%s) : %s' % (frame[2], request))
result = self.db.execute(request)
if commit:
self.db.commit()
return result
def count_results(self, value=None):
if value:
where = " WHERE k.text LIKE '" + value + "%'"
return self._exec(
'''
SELECT count(r.id)
FROM results AS r
INNER JOIN contains AS c ON c.id_results = r.id
INNER JOIN keywords AS k ON k.id = c.id_keywords
%s;
''' % self._where_like(value)
).fetchone()[0]
return self._exec(
'''
SELECT count(id) FROM results;
'''
).fetchone()[0]
def get(self, _id):
return self._exec(
'''
SELECT name, app_name, generic, icon_path, path, in_mini, in_maxi, in_super, in_prof
FROM results WHERE id = "%s";
''' % _id
)
def get_page(self, offset, nb, value=None):
if value:
return self._exec(
'''
SELECT id, name, app_name, generic, icon_path, path, in_mini, in_maxi, in_super, in_prof
FROM results AS r
INNER JOIN contains AS c ON c.id_results = r.id
INNER JOIN keywords AS k ON k.id = c.id_keywords
%s
LIMIT %s, %s;
''' % (self._where_like(value), offset, nb)
)
return self._exec(
'''
SELECT id, name, app_name, generic, icon_path, path, in_mini, in_maxi, in_super, in_prof
FROM results LIMIT %s, %s;
''' % (offset, nb)
)
def app_exist(self, name, sessions, session):
result = self._exec(
'''
SELECT %s, %s, %s, %s
FROM results WHERE name = "%s";
''' % (
'in_%s' % sessions[0],
'in_%s' % sessions[1],
'in_%s' % sessions[2],
session,
name
)
).fetchone()
if not result:
return None
return {
sessions[0]: result[0],
sessions[1]: result[1],
sessions[2]: result[2],
session: result[3]
}
def add_app(
self,
sessions,
app_name,
name,
icon_path,
cmd,
generic,
session
):
return self._exec(
'''
INSERT INTO results
(name, app_name, generic, icon_path, path, %s, %s, %s, %s)
VALUES ("%s", "%s", "%s", "%s", '%s', 0, 0, 0, 1);
''' % (
'in_%s' % sessions[0],
'in_%s' % sessions[1],
'in_%s' % sessions[2],
session,
name,
app_name,
generic,
icon_path,
cmd
),
True
).lastrowid
def update_app(self, name, session):
return self._exec(
'''
UPDATE results
set %s = 1
WHERE name ="%s";
''' % (
session,
name
)
)
def add_keyword(self, keyword, id_results):
keywords_cursor = self._exec(
'''
SELECT k.id FROM keywords AS k
WHERE k.text = "%s";
''' % keyword
).fetchone()
if keywords_cursor:
keywords_id = keywords_cursor[0]
else:
keywords_id = self._exec(
'''
INSERT INTO keywords(text) VALUES("%s");
''' % keyword
).lastrowid
self._exec(
'''
INSERT INTO contains(id_results, id_keywords)
VALUES (%s, %s);
''' % (id_results, keywords_id)
)
def get_keywords(self, value=None):
return self._exec(
'''
SELECT k.text, count(k.id) FROM keywords AS k
INNER JOIN contains AS c ON k.id = c.id_keywords
%s
GROUP BY k.id
ORDER BY count(k.id) DESC
LIMIT 20;
''' % self._where_like(value)
)
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, Gdk, GdkPixbuf
from ..lib.pagination import pagination
def pages_widget(
pages,
hbox,
db,
vox,
app_box,
cache,
page,
results_by_page,
update_softs,
value=None
):
if not pages:
return
for p in pages:
page_b = Gtk.Button.new_with_label(str(p))
if str(p) == '...' or page == p:
page_b.set_sensitive(False)
else:
page_b.connect(
'clicked',
update_softs,
db,
vox,
app_box,
cache,
results_by_page,
p,
pagination_widget,
value
)
hbox.pack_start(page_b, False, False, True)
def pagination_widget(
db,
vbox,
app_box,
cache,
page,
results_by_page,
nb_pages,
update_softs,
value=None
):
hbox = Gtk.HBox(homogeneous=False)
first_b = Gtk.Button.new_with_label("Premier")
if page == 1:
first_b.set_sensitive(False)
else:
first_b.connect(
'clicked',
update_softs,
db,
vbox,
app_box,
cache,
results_by_page,
1,
pagination_widget,
value
)
hbox.pack_start(first_b, False, False, False)