From 32f8354649dff138dc2b8ec3484ceed42de4e4fe Mon Sep 17 00:00:00 2001 From: antoine Date: Sat, 23 Jul 2016 21:19:06 +0200 Subject: [PATCH] fit widget position on screen --- VDMAPI/Display/kivyDisplay.py | 18 +++++- VDM_API.egg-info/PKG-INFO | 60 +++++++++++++++++ VDM_API.egg-info/SOURCES.txt | 22 +++++++ VDM_API.egg-info/dependency_links.txt | 1 + VDM_API.egg-info/entry_points.txt | 3 + VDM_API.egg-info/top_level.txt | 1 + build/lib/VDMAPI/Display/__init__.py | 7 ++ build/lib/VDMAPI/Display/console.py | 12 ++++ build/lib/VDMAPI/Display/i3.py | 20 ++++++ build/lib/VDMAPI/Display/kivy.kv | 23 +++++++ build/lib/VDMAPI/Display/kivyDisplay.py | 82 ++++++++++++++++++++++++ build/lib/VDMAPI/Display/pyside.py | 13 ++++ build/lib/VDMAPI/Display/tkinter.py | 51 +++++++++++++++ build/lib/VDMAPI/Display/windows.py | 12 ++++ build/lib/VDMAPI/Display/wxpython.py | 18 ++++++ build/lib/VDMAPI/HtmlParser.py | 26 ++++++++ build/lib/VDMAPI/VDM.py | 36 +++++++++++ build/lib/VDMAPI/__init__.py | 0 build/lib/VDMAPI/version.py | 1 + dist/VDM API-1.0.tar.gz | Bin 5483 -> 5623 bytes dist/VDM_API-1.0-py2.py3-none-any.whl | Bin 8753 -> 8909 bytes 21 files changed, 404 insertions(+), 2 deletions(-) create mode 100644 VDM_API.egg-info/PKG-INFO create mode 100644 VDM_API.egg-info/SOURCES.txt create mode 100644 VDM_API.egg-info/dependency_links.txt create mode 100644 VDM_API.egg-info/entry_points.txt create mode 100644 VDM_API.egg-info/top_level.txt create mode 100644 build/lib/VDMAPI/Display/__init__.py create mode 100644 build/lib/VDMAPI/Display/console.py create mode 100644 build/lib/VDMAPI/Display/i3.py create mode 100644 build/lib/VDMAPI/Display/kivy.kv create mode 100644 build/lib/VDMAPI/Display/kivyDisplay.py create mode 100644 build/lib/VDMAPI/Display/pyside.py create mode 100644 build/lib/VDMAPI/Display/tkinter.py create mode 100644 build/lib/VDMAPI/Display/windows.py create mode 100644 build/lib/VDMAPI/Display/wxpython.py create mode 100644 build/lib/VDMAPI/HtmlParser.py create mode 100644 build/lib/VDMAPI/VDM.py create mode 100644 build/lib/VDMAPI/__init__.py create mode 100644 build/lib/VDMAPI/version.py diff --git a/VDMAPI/Display/kivyDisplay.py b/VDMAPI/Display/kivyDisplay.py index d05682d..61d80bf 100755 --- a/VDMAPI/Display/kivyDisplay.py +++ b/VDMAPI/Display/kivyDisplay.py @@ -4,10 +4,24 @@ from ..VDM import VDM import os import i3 +# get screen resolution +import tkinter +root = tkinter.Tk() +width = root.winfo_screenwidth() +height = root.winfo_screenheight() + from kivy.config import Config +Config.set('graphics','fullscreen', 0) Config.set('graphics','resizable',0) +Config.set('graphics','position', 'custom') +Config.set('graphics','width', 600) +Config.set('graphics','height', 150) + +# align bottom and 50 px from right +Config.set('graphics','left', width-Config.getint('graphics', 'width')-45) +Config.set('graphics','top', height-Config.getint('graphics', 'height')-17) + from kivy.core.window import Window -Window.size = (600, 150) import kivy from kivy.app import App @@ -65,4 +79,4 @@ class guiApp(GridLayout): class kivyApp(App): def build(self): - return guiApp(cols=3) + return guiApp(cols=3, pos=(0,0)) diff --git a/VDM_API.egg-info/PKG-INFO b/VDM_API.egg-info/PKG-INFO new file mode 100644 index 0000000..65098c8 --- /dev/null +++ b/VDM_API.egg-info/PKG-INFO @@ -0,0 +1,60 @@ +Metadata-Version: 1.1 +Name: VDM-API +Version: 1.0 +Summary: VDM API: an API for recover random VDM from vdm.fr website +Home-page: git://176.189.130.29/python/vdmAPI.git +Author: Antoine Roux +Author-email: antoinroux@hotmail.fr +License: Beerware +Download-URL: git://176.189.130.29/python/vdmAPI.git/tags +Description: ******* + VDM API + ******* + V1.0 + + **VDM API** is a python api for pull random api. + + Use case + ======== + You can use this API in python langage by instanciate a VDM() object : + :: + + from VDMAPI.VDM import VDM + + if __name__ == "__main__": + vdm = VDM() + lstAllVDM = vdm.get() + for i, vdm in enumerate(lstAllVDM): + print(str(i)+" : "+vdm) + + + Available GUI + ============= + + **VDM API** include four display mode : + + - **i3** : this GUI use dmenu for display the list of VDM + - **tkinter** : this use tkinter native interface + - **kivy** : use kivy library + - **console** : this last mode display the list of VDM in plain text mode + + Installing + ========== + + For **setup** you could do with this : + :: + + pip install --no-index --find-links= VDM_API + +Platform: any +Classifier: License :: FSF approved :: Beerware License +Classifier: Operating System :: POSIX :: Linux +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 2.6 +Classifier: Programming Language :: Python :: 2.7 +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.2 +Classifier: Programming Language :: Python :: 3.3 +Classifier: Programming Language :: Python :: 3.4 +Classifier: Programming Language :: Python :: 3.5 +Classifier: Topic :: Software Development :: Libraries :: Python Modules diff --git a/VDM_API.egg-info/SOURCES.txt b/VDM_API.egg-info/SOURCES.txt new file mode 100644 index 0000000..946b9c3 --- /dev/null +++ b/VDM_API.egg-info/SOURCES.txt @@ -0,0 +1,22 @@ +MANIFEST.in +README.html +README.rst +setup.py +VDMAPI/HtmlParser.py +VDMAPI/VDM.py +VDMAPI/__init__.py +VDMAPI/version.py +VDMAPI/Display/__init__.py +VDMAPI/Display/console.py +VDMAPI/Display/i3.py +VDMAPI/Display/kivy.kv +VDMAPI/Display/kivyDisplay.py +VDMAPI/Display/pyside.py +VDMAPI/Display/tkinter.py +VDMAPI/Display/windows.py +VDMAPI/Display/wxpython.py +VDM_API.egg-info/PKG-INFO +VDM_API.egg-info/SOURCES.txt +VDM_API.egg-info/dependency_links.txt +VDM_API.egg-info/entry_points.txt +VDM_API.egg-info/top_level.txt \ No newline at end of file diff --git a/VDM_API.egg-info/dependency_links.txt b/VDM_API.egg-info/dependency_links.txt new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/VDM_API.egg-info/dependency_links.txt @@ -0,0 +1 @@ + diff --git a/VDM_API.egg-info/entry_points.txt b/VDM_API.egg-info/entry_points.txt new file mode 100644 index 0000000..6b89213 --- /dev/null +++ b/VDM_API.egg-info/entry_points.txt @@ -0,0 +1,3 @@ +[console_scripts] +vdm = VDMAPI:main + diff --git a/VDM_API.egg-info/top_level.txt b/VDM_API.egg-info/top_level.txt new file mode 100644 index 0000000..b60ebbe --- /dev/null +++ b/VDM_API.egg-info/top_level.txt @@ -0,0 +1 @@ +VDMAPI diff --git a/build/lib/VDMAPI/Display/__init__.py b/build/lib/VDMAPI/Display/__init__.py new file mode 100644 index 0000000..7bcea61 --- /dev/null +++ b/build/lib/VDMAPI/Display/__init__.py @@ -0,0 +1,7 @@ +# import all module include into current package +__name__ = "VDMAPI" +__version__ = 1.0 +__author__ = "antoine roux" +__author_email__= "antoinroux@hotmail.fr" +__url__ = "antoine-roux.tk" +__description__ = "an api for recover a list of random vdm from vdm.fr and display it on different GUI (i3, tkinter, windows or commande line" diff --git a/build/lib/VDMAPI/Display/console.py b/build/lib/VDMAPI/Display/console.py new file mode 100644 index 0000000..7317811 --- /dev/null +++ b/build/lib/VDMAPI/Display/console.py @@ -0,0 +1,12 @@ +from ..VDM import VDM + +class console(object): + """display all vdm into console""" + def __init__(self): + super(console, self).__init__() + self.v = VDM() + + def render(self): + lstAllVDM = self.v.get() + for i, vdm in enumerate(lstAllVDM): + print(str(i)+" : "+vdm) diff --git a/build/lib/VDMAPI/Display/i3.py b/build/lib/VDMAPI/Display/i3.py new file mode 100644 index 0000000..9fb48b3 --- /dev/null +++ b/build/lib/VDMAPI/Display/i3.py @@ -0,0 +1,20 @@ +from ..VDM import VDM +import subprocess +import i3 + +class i3(object): + """display all vdm into i3 menu""" + def __init__(self): + super(i3, self).__init__() + self.v = VDM() + + def render(self): + lstAllVDM = self.v.get() + + dmenu = subprocess.Popen(['/usr/bin/dmenu', '-i','-l', str(len(lstAllVDM))], + stdin=subprocess.PIPE, + stdout=subprocess.PIPE) + + menu_str = '\n'.join(lstAllVDM) + win_str = dmenu.communicate(menu_str.encode('utf-8'))[0].decode('utf-8').rstrip() + print(win_str) \ No newline at end of file diff --git a/build/lib/VDMAPI/Display/kivy.kv b/build/lib/VDMAPI/Display/kivy.kv new file mode 100644 index 0000000..90b13c4 --- /dev/null +++ b/build/lib/VDMAPI/Display/kivy.kv @@ -0,0 +1,23 @@ +#:kivy 1.0 + +: + Button: + id: prev + + size_hint_x: None + width: 100 + + text: '<<' + on_press: root._prevAction() + Label: + text_size: 300, None + id: Message + text: 'no VDM load for the moment' + Button: + id: next + + size_hint_x: None + + width: 100 + text: '>>' + on_press: root._nextAction() \ No newline at end of file diff --git a/build/lib/VDMAPI/Display/kivyDisplay.py b/build/lib/VDMAPI/Display/kivyDisplay.py new file mode 100644 index 0000000..61d80bf --- /dev/null +++ b/build/lib/VDMAPI/Display/kivyDisplay.py @@ -0,0 +1,82 @@ +#!/usr/bin/env python + +from ..VDM import VDM +import os +import i3 + +# get screen resolution +import tkinter +root = tkinter.Tk() +width = root.winfo_screenwidth() +height = root.winfo_screenheight() + +from kivy.config import Config +Config.set('graphics','fullscreen', 0) +Config.set('graphics','resizable',0) +Config.set('graphics','position', 'custom') +Config.set('graphics','width', 600) +Config.set('graphics','height', 150) + +# align bottom and 50 px from right +Config.set('graphics','left', width-Config.getint('graphics', 'width')-45) +Config.set('graphics','top', height-Config.getint('graphics', 'height')-17) + +from kivy.core.window import Window + +import kivy +from kivy.app import App +from kivy.properties import * +from kivy.uix.gridlayout import GridLayout + +class guiApp(GridLayout): + """ display all vdm into kivy interface """ + + # https://kivy.org/docs/api-kivy.properties.html#kivy.properties.ListProperty + # NumericProperty, StringProperty, ListProperty, ObjectProperty, + # BooleanProperty, BoundedNumericProperty, OptionProperty, ReferenceListProperty, AliasProperty, DictProperty + + indice = NumericProperty(0) + vdm = ListProperty([]) + + def __init__(self, **kwargs): + super(guiApp, self).__init__(**kwargs) + + self._keyboard = Window.request_keyboard(self._keyboard_closed, self) + self._keyboard.bind(on_key_down = self._on_keyboard_down) + + self.v = VDM() + self.vdm = self.v.get() + self.render() + i3.msg("command", "floating enable") + + def _nextAction(self): + if self.indice == len(self.vdm)-1: + self.vdm = self.v.get() + self.indice = 0 + else: + self.indice += 1 + self.render() + + def _prevAction(self): + if self.indice > 0: + self.indice -= 1 + self.render() + + def _keyboard_closed(self): + self._keyboard.unbind(on_key_down = self._on_keyboard_down) + self._keyboard = None + + def _on_keyboard_down(self, *args): + if args[1][1] == 'right': + self._nextAction() + + elif args[1][1] == 'left': + self._prevAction() + + def render(self): + print(self.indice) + self.ids["Message"].text = self.vdm[self.indice] + +class kivyApp(App): + def build(self): + return guiApp(cols=3, pos=(0,0)) diff --git a/build/lib/VDMAPI/Display/pyside.py b/build/lib/VDMAPI/Display/pyside.py new file mode 100644 index 0000000..760e267 --- /dev/null +++ b/build/lib/VDMAPI/Display/pyside.py @@ -0,0 +1,13 @@ +#!/usr/bin/env python + +import sys +import PySide + +app = QtGui.QApplication(sys.argv) + +hello = QtGui.QLabel("hello Qt") +hello.show() +x, y, w, h = 100, 100, 100, 100 +hello.setGeometry(x, y, w, h) + +sys.exit(app.exec_()) \ No newline at end of file diff --git a/build/lib/VDMAPI/Display/tkinter.py b/build/lib/VDMAPI/Display/tkinter.py new file mode 100644 index 0000000..0f8d2fe --- /dev/null +++ b/build/lib/VDMAPI/Display/tkinter.py @@ -0,0 +1,51 @@ +from ..VDM import VDM +import tkinter as tk +import i3 +from tkinter import ttk +import os + +class tkinter: + def __init__(self): + """ init vdm object and create GUI """ + self.v = VDM() + self.indice = 0 + self.vdm = self.v.get() + + self.root = tk.Tk() + self.gui(self.root) + + def nextAction(self, event=None): + if self.indice == len(self.vdm)-1: + self.vdm = self.v.get() + self.indice = 0 + else: + self.indice+=1 + self.render() + + def prevAction(self, event=None): + if self.indice > 0: + self.indice-=1 + self.render() + + def gui(self, master): + self.mainwindow = ttk.Frame(master) + self.message = tk.Message(master, text="No VDM load for the moment", width="400") + + self.next = ttk.Button(master, text=">>", command=self.nextAction) + self.prev = ttk.Button(master, text="<<", command=self.prevAction) + self.root.bind('', self.prevAction) + self.root.bind('', self.nextAction) + + self.message.pack(fill="y", side="left", padx="5", pady="5") + self.prev.pack(fill="y", side="left", pady="1") + self.next.pack(fill="y", side="right", pady="1") + + def _floatingDisabler(self): + i3.msg("command", "floating enable") + + def render(self): + print("indice {}".format(self.indice)) + + self.message.configure(text=self.vdm[self.indice]) + self.root.after(1, self._floatingDisabler) + self.root.mainloop() diff --git a/build/lib/VDMAPI/Display/windows.py b/build/lib/VDMAPI/Display/windows.py new file mode 100644 index 0000000..8974669 --- /dev/null +++ b/build/lib/VDMAPI/Display/windows.py @@ -0,0 +1,12 @@ +from ..VDM import VDM + +class windows(object): + """display all vdm into windows os""" + def __init__(self): + super(windows, self).__init__() + v = VDM() + + def render(self): + lstAllVDM = self.v.get() + for i, vdm in enumerate(lstAllVDM): + print(str(i)+" : "+vdm) \ No newline at end of file diff --git a/build/lib/VDMAPI/Display/wxpython.py b/build/lib/VDMAPI/Display/wxpython.py new file mode 100644 index 0000000..684c194 --- /dev/null +++ b/build/lib/VDMAPI/Display/wxpython.py @@ -0,0 +1,18 @@ +#!/usr/bin/python + +import wx + +def onButton(event): + print "Button pressed." + +app = wx.App() +frame = wx.Frame(None, -1, 'win.py') +frame.SetDimensions(0,0,200,50) + +panel = wx.Panel(frame, wx.ID_ANY) +button = wx.Button(panel, wx.ID_ANY, 'Test', (10, 10)) +button.Bind(wx.EVT_BUTTON, onButton) + +frame.Show() +frame.Centre() +app.MainLoop() \ No newline at end of file diff --git a/build/lib/VDMAPI/HtmlParser.py b/build/lib/VDMAPI/HtmlParser.py new file mode 100644 index 0000000..c03a52d --- /dev/null +++ b/build/lib/VDMAPI/HtmlParser.py @@ -0,0 +1,26 @@ +from html.parser import HTMLParser +from html.entities import name2codepoint + +class MyHTMLParser(HTMLParser): + def __init__(self): + super(MyHTMLParser, self).__init__() + self.vdm = [] + self.save = False + + def _searchClass(self, listTuple, className="post article"): + for v in listTuple: + if v[0] == 'class' and v[1] == className: + return True + return False + + def handle_starttag(self, tag, attrs): + if tag == "p" and self._searchClass(attrs, className="content"): + self.save = True + + def handle_data(self, data): + if self.save: + self.vdm.append(data) + self.save = False + + def getText(self): + return self.vdm \ No newline at end of file diff --git a/build/lib/VDMAPI/VDM.py b/build/lib/VDMAPI/VDM.py new file mode 100644 index 0000000..9717016 --- /dev/null +++ b/build/lib/VDMAPI/VDM.py @@ -0,0 +1,36 @@ +from .HtmlParser import MyHTMLParser +import requests + +class VDM(object): + """VDM module for recover random VDM""" + + def __init__(self): + self.url = "http://www.viedemerde.fr/aleatoire" + self.vdm = {} + + def get(self): + try: + r = requests.get(self.url) + r.encoding = 'utf-8' # ISO-8859-1 + + if(r.status_code == requests.codes.ok): + parser = MyHTMLParser() + parser.feed(r.text) + self.vdm = parser.getText() + + print("Sucess {}".format(r.status_code)) + + return self.vdm + else: + print("Error {}".format(r.status_code)) + + except requests.exceptions.ConnectionError as e: + raise errorVDM("network error") + + except HTTPError as e: + raise errorVDM("HTTP Error") + +class errorVDM(Exception): + def __init__(self, message): + super(errorVDM, self).__init__(message) + \ No newline at end of file diff --git a/build/lib/VDMAPI/__init__.py b/build/lib/VDMAPI/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/build/lib/VDMAPI/version.py b/build/lib/VDMAPI/version.py new file mode 100644 index 0000000..050eddb --- /dev/null +++ b/build/lib/VDMAPI/version.py @@ -0,0 +1 @@ +version = '1.0' \ No newline at end of file diff --git a/dist/VDM API-1.0.tar.gz b/dist/VDM API-1.0.tar.gz index 8527153d639610d2cf5701ca86fa0e57d911abc1..8f868913286b40ba3fa31ea8bfd25d7c55b58821 100644 GIT binary patch literal 5623 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 RGX3YL{|5|iARGXo004KaW6J;l literal 5483 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 O9_N=t!30Eq-uw&UH``4B delta 2042 zcmY*ac{tQ<7oG);WyZct_92GEP$cV%Y$MTEyk(b^8B0TDE5;Tw8S*PjWnV&LdnehG z5RnXqWS>&DMwVBaFnv?+)gPVfI?uVzx$paV{&}wZ3|Q73uf4!6Y?HWclSN93uY!O; z!8{<4EZ~8V07%^Y#53-fCop1BC!=p>nFuu>iJ^UUyk*N&XO_y3s00ea6h&vbYRJrY zh(kMDEh_q4=?3p{$cLoo`Px9>w0UKtu{wO1nhxAD|bbVrQFoPJO099`~dSnHybj5S(atF=IN zSB+1awLU<`pIqP@iD`0HM5@{hdvwG3@1CoXQ4byotia?YjQGrotk@j4x1Csxc`+mmt`D4+F}dKEttGE#DR>U01=OA zdm^KLa*O&vQfpGcEEOqCYmQc;jp9P|N^zIE&N zAi8Fz!06QS^Xo-tlz!MfrfzPODmY_bXIbcDrcK=%z<6s+GuA+YnS> z8#fI$;2Rg=?_&IK3kdoaCgj>Dt$R{uVdeY4iPU7FA7F4IkSv1dG@BxZ5Kf~dZp%3% z#IrafVF@%8#`*U1+jvR{1=lO%_n0z-z2uNIwv4U5^#+I$$1 z2d-?BRfDXZY!7%=QNFKqt$aSkK9K4ZA+V#kbd<>lKbL%mPBhf+rC_bxY|Y~RET{i^ zmu1qFpMnX6RDdKY6aI$jRR+gTceVd`$o3liXxVZ6WJP9#@AW9K!mH z-pM}gJF50=*s}Y)OQ3*)Ob2nEJ=>n}xx0w6uEq~ZB)pZazd zed+yrEC_9hxg5}fh}fNAC}p;ttGrI4Iq^SHC^<+vk;d(;Q7HcRSBhHX0Q_5=vEeSG zum@Gs)BdbW!9ATwZn_km`Aumu;cOplKu&EtJoI%X6Hr`Y9Pj^{>*yX%(3cbT?QGx^h4ELvAf6LnI)7mW zTH@q?Jf|19G*JI`-h4dF=U8s83rlr;al7$NiyI~ zMjH7BMsE)jy(DA2V7**+3xT3WC)neh6&q!t=P!)9_BodJ<8?@WDlvYE-%D2FIyWet z(RG7Y$(sGGYRc{g)9B0jc*GaWqS!OqEi0(k0X@c_oBF6ODKpU_hhh!S8gWG#Y%815 zo@oZwLiC6hTjQtbTi{1yN!b^)VzSv_#GlIxXqIz@n8Sb_m^7dx zuMR=;0t{XmAW~i(YygzXTZ7#Iro0uT3=ViAqyT#bbx0}#h)_`C7(=dt3}jXiP?V4Y zYJ~(5j&@*(7*q@d0>MDeiNM-VRQNwsMCjn3=(bJQCll%p7z7I80)dn`n%_|piv_$D z56g3`rhl^O5-(@IkCT5=62*Sq+poC)C-3oOoTw*<6U0erPX3OPSlWL)8I;IRH$%xl q{KPpz1t1Uw|0(?CWl#{vlC#2PeycdOB=(NfuLtT-5