Browse Source

Add should_run condition

Sacha Bron 6 months ago
parent
commit
cf7be8decb
2 changed files with 155 additions and 8 deletions
  1. 114 0
      .vscode/.ropeproject/config.py
  2. 41 8
      cotisations.py

+ 114 - 0
.vscode/.ropeproject/config.py

@@ -0,0 +1,114 @@
+# The default ``config.py``
+# flake8: noqa
+
+
+def set_prefs(prefs):
+    """This function is called before opening the project"""
+
+    # Specify which files and folders to ignore in the project.
+    # Changes to ignored resources are not added to the history and
+    # VCSs.  Also they are not returned in `Project.get_files()`.
+    # Note that ``?`` and ``*`` match all characters but slashes.
+    # '*.pyc': matches 'test.pyc' and 'pkg/test.pyc'
+    # 'mod*.pyc': matches 'test/mod1.pyc' but not 'mod/1.pyc'
+    # '.svn': matches 'pkg/.svn' and all of its children
+    # 'build/*.o': matches 'build/lib.o' but not 'build/sub/lib.o'
+    # 'build//*.o': matches 'build/lib.o' and 'build/sub/lib.o'
+    prefs['ignored_resources'] = ['*.pyc', '*~', '.ropeproject',
+                                  '.hg', '.svn', '_svn', '.git', '.tox']
+
+    # Specifies which files should be considered python files.  It is
+    # useful when you have scripts inside your project.  Only files
+    # ending with ``.py`` are considered to be python files by
+    # default.
+    # prefs['python_files'] = ['*.py']
+
+    # Custom source folders:  By default rope searches the project
+    # for finding source folders (folders that should be searched
+    # for finding modules).  You can add paths to that list.  Note
+    # that rope guesses project source folders correctly most of the
+    # time; use this if you have any problems.
+    # The folders should be relative to project root and use '/' for
+    # separating folders regardless of the platform rope is running on.
+    # 'src/my_source_folder' for instance.
+    # prefs.add('source_folders', 'src')
+
+    # You can extend python path for looking up modules
+    # prefs.add('python_path', '~/python/')
+
+    # Should rope save object information or not.
+    prefs['save_objectdb'] = True
+    prefs['compress_objectdb'] = False
+
+    # If `True`, rope analyzes each module when it is being saved.
+    prefs['automatic_soa'] = True
+    # The depth of calls to follow in static object analysis
+    prefs['soa_followed_calls'] = 0
+
+    # If `False` when running modules or unit tests "dynamic object
+    # analysis" is turned off.  This makes them much faster.
+    prefs['perform_doa'] = True
+
+    # Rope can check the validity of its object DB when running.
+    prefs['validate_objectdb'] = True
+
+    # How many undos to hold?
+    prefs['max_history_items'] = 32
+
+    # Shows whether to save history across sessions.
+    prefs['save_history'] = True
+    prefs['compress_history'] = False
+
+    # Set the number spaces used for indenting.  According to
+    # :PEP:`8`, it is best to use 4 spaces.  Since most of rope's
+    # unit-tests use 4 spaces it is more reliable, too.
+    prefs['indent_size'] = 4
+
+    # Builtin and c-extension modules that are allowed to be imported
+    # and inspected by rope.
+    prefs['extension_modules'] = []
+
+    # Add all standard c-extensions to extension_modules list.
+    prefs['import_dynload_stdmods'] = True
+
+    # If `True` modules with syntax errors are considered to be empty.
+    # The default value is `False`; When `False` syntax errors raise
+    # `rope.base.exceptions.ModuleSyntaxError` exception.
+    prefs['ignore_syntax_errors'] = False
+
+    # If `True`, rope ignores unresolvable imports.  Otherwise, they
+    # appear in the importing namespace.
+    prefs['ignore_bad_imports'] = False
+
+    # If `True`, rope will insert new module imports as
+    # `from <package> import <module>` by default.
+    prefs['prefer_module_from_imports'] = False
+
+    # If `True`, rope will transform a comma list of imports into
+    # multiple separate import statements when organizing
+    # imports.
+    prefs['split_imports'] = False
+
+    # If `True`, rope will remove all top-level import statements and
+    # reinsert them at the top of the module when making changes.
+    prefs['pull_imports_to_top'] = True
+
+    # If `True`, rope will sort imports alphabetically by module name instead
+    # of alphabetically by import statement, with from imports after normal
+    # imports.
+    prefs['sort_imports_alphabetically'] = False
+
+    # Location of implementation of
+    # rope.base.oi.type_hinting.interfaces.ITypeHintingFactory In general
+    # case, you don't have to change this value, unless you're an rope expert.
+    # Change this value to inject you own implementations of interfaces
+    # listed in module rope.base.oi.type_hinting.providers.interfaces
+    # For example, you can add you own providers for Django Models, or disable
+    # the search type-hinting in a class hierarchy, etc.
+    prefs['type_hinting_factory'] = (
+        'rope.base.oi.type_hinting.factory.default_type_hinting_factory')
+
+
+def project_opened(project):
+    """This function is called after opening the project"""
+    # Do whatever you like here!

+ 41 - 8
cotisations.py

@@ -1,6 +1,7 @@
 #!/usr/bin/env python3
 # coding=utf-8
 
+import sys
 import os
 import time
 import odoorpc
@@ -25,8 +26,8 @@ grand merci aux généreux membres qui choisissent de verser un montant supérie
 pour soutenir FIXME !
 
 
-Montant de ta cotisation: CHF {p[x_amount]}
-Montant reçu dans les 12 derniers mois: CHF {cotisations_encaissees}
+Montant de ta cotisation : CHF {p[x_amount]}
+Montant reçu dans les 12 derniers mois : CHF {cotisations_encaissees}
 
 
 Ton comité
@@ -87,19 +88,50 @@ def send_mail(p, cotisations_encaissees, cotisations_dues, odoo):
     mail_mail.send([msg_id], raise_exception=True)
     logging.debug("Message ID {} sent".format(msg_id))
 
-
-def check_bank_statements(odoo):
+# Check if the last cotisations update is not too old
+def is_bank_statements_up_to_date(odoo):
   statement = odoo.env['account.bank.statement']
-
   one_year_ago = arrow.utcnow().shift(years=-1).format('YYYY-MM-DD')
 
   statements = statement.search_read([('state', '=', 'confirm'), ('date', '>', one_year_ago)])
 
-  if len(statements):
+  # If it is up to date on the last 11 months
+  if len(statements) >= 11:
     logging.error('Please ensure that bank statements for the last 12 months are up to date, found only {}'.format(len(statements)))
 
     if not args.dryrun:
-      sys.exit(1)
+      return True
+
+    return False
+  else:
+    return True
+
+def should_run(odoo):
+  # Check if the last cotisations update is not too old
+
+  # If it is too old, we should send an email to the comité
+  if not is_bank_statements_up_to_date(odoo):
+    # TODO email
+    return False
+
+  # Check if the last time this script ran is old enough
+  # if(args.dryrun == True):
+
+  now = arrow.utcnow()
+  with open('last_run_timestamp.txt', 'r') as f:
+    last_run_timestamp = f.read()
+    last_run = arrow.utcfromtimestamp(last_run_timestamp)
+
+  # If the emails where send less than 4 months ago, we quit
+  if now.shift(months=-4) < last_run:
+    return False
+
+  # We finally run the script, we save the timestamp in a file
+  timestamp = now.timestamp
+  with open('last_run_timestamp.txt', 'w') as f:
+    f.write(timestamp)
+
+  return True
 
 def run(args):
   logging.basicConfig(level=logging.DEBUG)
@@ -107,7 +139,8 @@ def run(args):
   odoo = odoorpc.ODOO('odoo.fixme.ch', protocol='jsonrpc+ssl', port=443)
   odoo.login(os.environ['DATABASE'], os.environ['USERNAME'], os.environ['PASSWORD'])
 
-  check_bank_statements(odoo)
+  if not should_run(odoo):
+    sys.exit(0)
 
   count = 0
   total_amount = 0