Browse Source

start with db and core structure

Olivier Massot 4 năm trước cách đây
mục cha
commit
cce7636e97
22 tập tin đã thay đổi với 60 bổ sung383 xóa
  1. 2 4
      .gitignore
  2. 1 1
      .idea/mew.iml
  3. 1 1
      .idea/misc.xml
  4. 6 0
      .idea/vcs.xml
  5. 6 3
      README.md
  6. 0 1
      VERSION
  7. 0 0
      core/backup.py
  8. 15 0
      core/constants.py
  9. BIN
      core/db.sqlite.dist
  10. 6 0
      core/discography.py
  11. 0 0
      core/download.py
  12. 0 0
      core/player.py
  13. 17 0
      core/scanner.py
  14. 0 0
      data/.gitkeep
  15. 1 0
      fixtures/.gitignore
  16. 2 14
      main.py
  17. 0 4
      requirements.txt
  18. 0 141
      setup.iss
  19. 0 86
      setup.py
  20. 2 55
      ui/qt/main.ui
  21. 1 1
      ui/window.py
  22. 0 72
      updater.py

+ 2 - 4
.gitignore

@@ -1,9 +1,7 @@
 *.pyc
 
-# Eclipse pydev project
-.project
-.pydevproject
-.settings/
+# Pycharm project
+.idea
 
 # tests
 htmlcov/

+ 1 - 1
.idea/mew.iml

@@ -2,7 +2,7 @@
 <module type="PYTHON_MODULE" version="4">
   <component name="NewModuleRootManager">
     <content url="file://$MODULE_DIR$" />
-    <orderEntry type="inheritedJdk" />
+    <orderEntry type="jdk" jdkName="Python 3.8 (clonedb)" jdkType="Python SDK" />
     <orderEntry type="sourceFolder" forTests="false" />
   </component>
 </module>

+ 1 - 1
.idea/misc.xml

@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <project version="4">
-  <component name="ProjectRootManager" version="2" project-jdk-name="Python 3.6" project-jdk-type="Python SDK" />
+  <component name="ProjectRootManager" version="2" project-jdk-name="Python 3.8 (clonedb)" project-jdk-type="Python SDK" />
 </project>

+ 6 - 0
.idea/vcs.xml

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="VcsDirectoryMappings">
+    <mapping directory="$PROJECT_DIR$" vcs="Git" />
+  </component>
+</project>

+ 6 - 3
README.md

@@ -1,6 +1,9 @@
-# Hello World
+# Mewx
 
-A model for a basic python app 
+An intuitive playlist manager for Mathilde
+
+> Python 3.8, PyQt5
+
+    sudo apt install qtcreator
 
-> Python 3.6, PyQt5
 

+ 0 - 1
VERSION

@@ -1 +0,0 @@
-1.0

+ 0 - 0
core/backup.py


+ 15 - 0
core/constants.py

@@ -0,0 +1,15 @@
+from path import Path
+
+APP_ROOT = Path(__file__).parent.parent
+
+MUSIC_FOLDERS = [
+    APP_ROOT / 'fixtures'
+]
+
+SUPPORTED_EXTENSIONS = ('mp3', 'wma', 'flac')
+
+
+
+# Db
+
+DB_PATH = APP_ROOT / 'data' / 'db.sqlite'

BIN
core/db.sqlite.dist


+ 6 - 0
core/discography.py

@@ -0,0 +1,6 @@
+from core import constants
+
+
+class Discography:
+    def __init__(self):
+        pass

+ 0 - 0
core/download.py


+ 0 - 0
core/player.py


+ 17 - 0
core/scanner.py

@@ -0,0 +1,17 @@
+from core import constants
+
+
+class Scanner:
+    def __init__(self):
+        pass
+
+    def scan(self):
+        disco = {}
+        for dir_ in constants.MUSIC_FOLDERS:
+            disco[dir_] = []
+
+            for f in dir_.files():
+                if f.ext not in constants.SUPPORTED_EXTENSIONS:
+                    continue
+
+                disco[dir_].append(f)

+ 0 - 0
data/.gitkeep


+ 1 - 0
fixtures/.gitignore

@@ -0,0 +1 @@
+*

+ 2 - 14
main.py

@@ -14,9 +14,6 @@ from PyQt5.QtWidgets import QMessageBox
 
 from core import logging_
 from ui.window import MainWindow
-from updater import UpdateNeeded
-import updater
-
 
 try:
     # Necessary to ensure that stacktraces are printed when using PyQt5
@@ -28,23 +25,14 @@ except:
 logger = logging.getLogger("hello")
 logging_.start("hello", level=10)
 
-with open("VERSION") as f:
-    __VERSION__ = f.read()
-
-try:
-    updater.autoupdate()
-except UpdateNeeded:
-    print("Veuillez patienter pendant la mise à jour automatique")
-    sys.exit(0)
-
 # Configure how errors are processed
 sys_err = sys.excepthook
-def gestionnaire_erreurs(typ, value, trace):
+def err_handler(typ, value, trace):
     QApplication.restoreOverrideCursor()
     logger.error("{}\n{}\n{}".format(typ.__name__, value, ''.join(traceback.format_tb(trace))))
     QMessageBox.critical(mainw, "Erreur: {}".format(typ.__name__), """{}""".format(value))
     sys_err(typ, value, trace)
-sys.excepthook = gestionnaire_erreurs
+sys.excepthook = err_handler
 
 # Start UI
 app = QApplication(sys.argv)

+ 0 - 4
requirements.txt

@@ -1,6 +1,2 @@
-# PyQt5: only if it app needs a graphical interface
 PyQt5
 
-# requests is used by the auto-updater
-requests
-

+ 0 - 141
setup.iss

@@ -1,141 +0,0 @@
-; Installation program script for Hello world
-
-; WARNING: do not forget to regenerate the AppId (Inno Setup > Tools > Generate GUI) ; Double the bracklaces
-#define AppGuid "{3ABFE415-C8DA-43E8-91BD-0DFD8231A58F}"
-
-; Version of the installer
-#define FileVersion "1.0.0"
-
-; Application short name (also the name of the install directory)
-#define AppName "hello_world"
-
-; Application verbose name
-#define AppVerboseName "Python Hello World"
-
-; Application current version
-#define AppVersion "0.1"
-
-; Publisher's name
-#define AppPublisher "Conseil Départemental du Bas-Rhin"
-
-; Website
-#define AppURL "http://codebox/lab/Python_3-6-1"
-
-; Install diretory
-#define AppLocation "{%temp}"
-
-; Python version required
-#define PythonVersion "3.6-32"
-
-[Setup]
-AppId={{#AppGuid}}
-VersionInfoVersion={#FileVersion}
-AppName={#AppVerboseName}
-AppVersion={#AppVersion}
-AppPublisher={#AppPublisher}
-AppPublisherURL={#AppURL}
-AppSupportURL={#AppURL}
-AppUpdatesURL={#AppURL}
-DefaultDirName={#AppLocation}\\{#AppName}
-DefaultGroupName={#AppName}
-Compression=lzma
-PrivilegesRequired=lowest
-SolidCompression=yes
-VersionInfoCompany={#AppPublisher}
-DisableDirPage=yes
-DisableProgramGroupPage=yes
-DisableFinishedPage=yes
-OutputDir=.
-OutputBaseFilename=setup-{#AppName}
-ChangesEnvironment=yes
-UninstallFilesDir={app}\uninstall\
-
-[Languages]
-Name: "french"; MessagesFile: "compiler:Languages\French.isl"
-
-[Files]
-; Files to be installed
-Source: "core\*"; DestDir: "{app}\core"; Flags: recursesubdirs
-Source: "ui\*"; DestDir: "{app}\ui"; Flags: recursesubdirs
-Source: "main.py"; DestDir: "{app}"
-Source: "updater.py"; DestDir: "{app}"
-Source: "icon.ico"; DestDir: "{app}"    
-Source: "requirements.txt"; DestDir: "{app}"
-Source: "VERSION"; DestDir: "{app}"
-
-[Icons]
-; Shortcuts to be created in the menu bar and on the desktop
-; WARNING: Because it's an UI app, pythonw.exe is used. Replace with 'python.exe' for a console app.
-Name: "{group}\{#AppName}"; Filename: "{code:fPythonDir}\pythonw.exe"; Parameters: """{app}\main.py"""; WorkingDir: "{app}"; IconFilename: "{app}\icon.ico"
-Name: "{group}\{cm:UninstallProgram,{#AppName}}"; Filename: "{uninstallexe}"
-Name: "{commondesktop}\{#AppName}"; Filename: "{code:fPythonDir}\pythonw.exe"; Parameters: """{app}\main.py"""; WorkingDir: "{app}"; IconFilename: "{app}\icon.ico"
-
-[Code]
-var
-  sPythonDir: String;
-  sPythonExecPath: String;
-  sPythonWExecPath: String;
-
-// Return the directory containing the python executable
-procedure UpdatePythonDir();
-var
-  Dirname: String;
-begin
-  sPythonDir := '';
-
-  if RegQueryStringValue(HKLM, 'SOFTWARE\Wow6432Node\Python\PythonCore\{#PythonVersion}\InstallPath', '', Dirname) OR 
-  RegQueryStringValue(HKLM, 'SOFTWARE\Python\PythonCore\{#PythonVersion}\InstallPath', '', Dirname) then
-  begin
-    sPythonDir := Dirname;
-    sPythonExecPath := Dirname + 'python.exe'
-    sPythonWExecPath := Dirname + 'pythonw.exe'
-  end
-end;
-
-// Initial checkup
-function InitializeSetup(): Boolean;
-begin
-  UpdatePythonDir();
-
-  // check that python is installed
-  if not FileExists(sPythonExecPath) then
-  begin
-     MsgBox('Python {#PythonVersion} doit être installé.' + #13#10 + 'Installation annulée.', mbError, MB_OK);
-     Result := False;
-     Exit; 
-  end
-
-  Result := True;
-end;
-
-procedure CurStepChanged(CurStep: TSetupStep);
-var
-  ShowCmd: Integer;
-  ExitCode: Integer;
-begin
-  if CurStep = ssPostInstall then
-  begin      
-
-    // Search for a requirements.txt file,and process it if exists
-    if FileExists(ExpandConstant('{app}\requirements.txt')) then
-    begin
-      
-      if WizardSilent then begin ShowCmd := SW_HIDE end else begin ShowCmd := SW_SHOWNORMAL end
-      Exec(sPythonDir + 'Scripts\pip67.exe', 'install -r ' + ExpandConstant('"{app}\requirements.txt"'), '', ShowCmd, ewWaitUntilTerminated, ExitCode);
-
-      if ExitCode <> 0 then
-      begin
-        MsgBox('Python 3.6 - Une erreur s''est produite lors de l''installation des librairies' + #13#10 + '[' + SysErrorMessage(ExitCode) + ']', mbError, MB_OK);
-        Exit;     
-      end
-    Log('Installed in ' + ExpandConstant('{app}'))
-    end
-  end       
-end;
-
-// Scripted Constants for use in the other sections
-function fPythonDir(Param: String): String;
-begin
-  Result := sPythonDir;
-end;
-

+ 0 - 86
setup.py

@@ -1,86 +0,0 @@
-# fichier et explications issues de: http://sametmax.com/creer-un-setup-py-et-mettre-sa-bibliotheque-python-en-ligne-sur-pypi/
-
-from setuptools import setup, find_packages
-
-import hello_world
-
-setup(
-
-    # le nom de votre bibliothèque, tel qu'il apparaitre sur pypi
-    name='hello_world',
-
-    # la version du code
-    version=hello_world.__version__,
-
-    # Liste les packages à insérer dans la distribution
-    # plutôt que de le faire à la main, on utilise la foncton
-    # find_packages() de setuptools qui va cherche tous les packages
-    # python recursivement dans le dossier courant.
-    # C'est pour cette raison que l'on a tout mis dans un seul dossier:
-    # on peut ainsi utiliser cette fonction facilement
-    packages=find_packages(),
-
-    # votre pti nom
-    author="olivier.massot",
-
-    # Votre email, sachant qu'il sera publique visible, avec tous les risques
-    # que ça implique.
-    author_email="olivier.massot@gmail.com",
-
-    # Une description courte
-    description="Hello world",
-
-    # Une description longue, sera affichée pour présenter la lib
-    # Généralement on dump le README ici
-    long_description=open('README.md').read(),
-
-    # Vous pouvez rajouter une liste de dépendances pour votre lib
-    # et même préciser une version. A l'installation, Python essayera de
-    # les télécharger et les installer.
-    #
-    # Ex: ["docopt", "docutils >= 0.3", "lxml==0.5a7"]
-    #
-    # install_requires= ,
-
-    # Active la prise en compte du fichier MANIFEST.in
-    include_package_data=True,
-
-    # Une url qui pointe vers la page officielle de votre lib
-    url='http://codebox/lab/Integration-continue',
-
-    # Il est d'usage de mettre quelques metadata à propos de sa lib
-    # Pour que les robots puissent facilement la classer.
-    # La liste des marqueurs autorisées est longue:
-    # https://pypi.python.org/pypi?%3Aaction=list_classifiers.
-    #
-    # Il n'y a pas vraiment de règle pour le contenu. Chacun fait un peu
-    # comme il le sent. Il y en a qui ne mettent rien.
-    classifiers=[
-        "Programming Language :: Python",
-        "Development Status :: 1 - Planning",
-        "License :: OSI Approved",
-        "Natural Language :: French",
-        "Operating System :: OS Independent",
-        "Programming Language :: Python :: 2.7",
-        "Topic :: Communications",
-    ],
-
-    # C'est un système de plugin, mais on s'en sert presque exclusivement
-    # Pour créer des commandes, comme "django-admin".
-    # Par exemple, si on veut créer la fabuleuse commande "hello-command", on
-    # va faire pointer ce nom vers la fonction proclamer(). La commande sera
-    # créé automatiquement.
-    # La syntaxe est "nom-de-commande-a-creer = package.module:fonction".
-    entry_points={
-        'console_scripts': [
-            'hello-command = hello_world.core:hello_message',
-        ],
-    },
-
-    # A fournir uniquement si votre licence n'est pas listée dans "classifiers"
-    # ce qui est notre cas
-    license="WTFPL",
-
-    # Et encore d'autres paramètes...
-
-)

+ 2 - 55
ui/qt/main.ui

@@ -6,22 +6,10 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>521</width>
-    <height>196</height>
+    <width>838</width>
+    <height>601</height>
    </rect>
   </property>
-  <property name="minimumSize">
-   <size>
-    <width>521</width>
-    <height>196</height>
-   </size>
-  </property>
-  <property name="maximumSize">
-   <size>
-    <width>521</width>
-    <height>196</height>
-   </size>
-  </property>
   <property name="font">
    <font>
     <family>Verdana</family>
@@ -52,47 +40,6 @@
     <property name="bottomMargin">
      <number>3</number>
     </property>
-    <item>
-     <widget class="QPushButton" name="btnGet">
-      <property name="minimumSize">
-       <size>
-        <width>0</width>
-        <height>36</height>
-       </size>
-      </property>
-      <property name="maximumSize">
-       <size>
-        <width>16777215</width>
-        <height>36</height>
-       </size>
-      </property>
-      <property name="text">
-       <string>Get message</string>
-      </property>
-     </widget>
-    </item>
-    <item>
-     <widget class="QLabel" name="lblResult">
-      <property name="minimumSize">
-       <size>
-        <width>0</width>
-        <height>36</height>
-       </size>
-      </property>
-      <property name="maximumSize">
-       <size>
-        <width>16777215</width>
-        <height>36</height>
-       </size>
-      </property>
-      <property name="text">
-       <string>[message here]</string>
-      </property>
-      <property name="alignment">
-       <set>Qt::AlignCenter</set>
-      </property>
-     </widget>
-    </item>
    </layout>
   </widget>
   <widget class="QStatusBar" name="statusbar"/>

+ 1 - 1
ui/window.py

@@ -7,7 +7,7 @@
 
 from PyQt5.QtWidgets import QMainWindow
 
-from core import hello_world
+from core import discography
 from ui.qt.main_ui import Ui_mainWindow
 
 

+ 0 - 72
updater.py

@@ -1,72 +0,0 @@
-'''
-    Auto-updater
-'''
-from distutils.version import StrictVersion
-import os
-from subprocess import Popen
-import sys
-import tempfile
-
-import requests
-
-VERSIONFILE_URL = "http://codebox/lab/ModelePython/raw/master/VERSION"
-SETUPFILE_URL = "http://codebox/lab/ModelePython/raw/master/setup-hello_world.exe"
-
-CURDIR = os.path.dirname(__file__)
-
-TMPDIR = os.path.join(tempfile.gettempdir(), os.path.basename(CURDIR), "update")
-TMP_SETUPFILE = os.path.join(TMPDIR, "setup.exe")
-
-class UpdateNeeded(Exception):
-    pass
-
-class Unavailable(requests.exceptions.RequestException):
-    pass
-
-def autoupdate():
-    clean_old()
-    try:
-        if update_needed():
-            update()
-    except Unavailable:
-        pass
-
-def clean_old():
-    try:
-        os.rmdir(TMPDIR)
-    except:
-        pass
-
-def update_needed():
-    # Available version
-    try:
-        raw = requests.get(VERSIONFILE_URL).text
-        available_version = StrictVersion(raw)
-    except (ValueError, requests.exceptions.RequestException):
-        raise Unavailable()
-
-    # Installed version
-    with open(os.path.join(CURDIR, "VERSION")) as f:
-        installed_version = f.read()
-
-    return available_version > installed_version
-
-def update():
-
-    # Download the setup.exe
-    response = requests.get(SETUPFILE_URL, stream=True)
-
-    os.mkdir(TMPDIR)
-    with open(TMP_SETUPFILE, "wb") as handle:
-        for chunk in response.iter_content(chunk_size=1024):
-            if chunk:
-                handle.write(chunk)
-
-    # Run the installer and restart the start command
-    args = "/c {} /SILENT & {} {}".format(TMP_SETUPFILE, sys.executable, " ".join(sys.argv[:]))
-
-    Popen(["cmd.exe", args], shell=True)
-
-    # An UpdateNeeded exception is raised so the script exit before being restarted by subprocess
-    raise UpdateNeeded()
-