Projet

Général

Profil

0001-WIP-add-federation_utils-module-19396.patch

Paul Marillonnet, 17 novembre 2017 16:36

Télécharger (3,64 ko)

Voir les différences:

Subject: [PATCH] WIP add federation_utils module (#19396)

 mellon/federation_utils.py | 83 ++++++++++++++++++++++++++++++++++++++++++++++
 setup.py                   |  1 +
 2 files changed, 84 insertions(+)
 create mode 100644 mellon/federation_utils.py
mellon/federation_utils.py
1
import fcntl
2
import logging
3
import tempfile
4
import threading
5
from datetime import timedelta
6

  
7
from django.utils.text import slugify
8
from datetime import datetime
9

  
10
import requests
11
from pytz import utc
12
from time import mktime, sleep
13
import os
14
import hashlib
15
import os.path
16

  
17
from django.core.files.storage import default_storage
18

  
19

  
20
def truncate_unique(s, length):
21
    if len(s) < length:
22
        return s
23
    md5 = hashlib.md5(s.encode('ascii')).hexdigest()
24
    # we should be the first and last characters from the URL
25
    l = (length - len(md5)) / 2 - 2  # four additional characters
26
    assert l > 20
27
    return s[:l] + '...' + s[-l:] + '_' + md5
28

  
29

  
30
def dt_to_timestamp(input_dt):
31
    return mktime(utc.localize(input_dt).utctimetuple())
32

  
33

  
34
def load_federation_cache(url):
35
    logger = logging.getLogger(__name__)
36
    try:
37
        filename = truncate_unique(slugify(url), 250)
38
        path = os.path.join('metadata-cache', filename)
39

  
40
        unix_path = default_storage.path(path)
41
        if not os.path.exists('metadata-cache'):
42
            os.makedirs('metadata-cache')
43
        f = open(unix_path, 'w')
44
        try:
45
            fcntl.lockf(f, fcntl.LOCK_EX | fcntl.LOCK_NB)
46
        except IOError:
47
            return
48
        else:
49
            with tempfile.NamedTemporaryFile(dir=os.path.dirname(unix_path), delete=False) as temp:
50
                try:
51
                    # increase modified time by one hour to prevent too many updates
52
                    st = os.stat(unix_path)
53
                    os.utime(unix_path, (st.st_atime, st.st_mtime + 3600))
54
                    response = requests.get(url)
55
                    response.raise_for_status()
56
                    temp.write(response.content)
57
                    temp.flush()
58
                    os.rename(temp.name, unix_path)
59
                except:
60
                    os.unlink(temp.name)
61
                finally:
62
                    fcntl.lockf(f, fcntl.LOCK_UN)
63
        finally:
64
            f.close()
65
    except OSError:
66
        logger.exception(u"could create the intermediary 'metadata-cache' "
67
                         "folder")
68
        return
69
    except:
70
        logger.exception(u'failed to load federation from %s', url)
71

  
72

  
73
def get_federation_from_url(url, update_cache=False):
74
    logger = logging.getLogger(__name__)
75
    filename = truncate_unique(slugify(url), 250)
76
    path = os.path.join('metadata-cache', filename)
77
    if not default_storage.exists(path) or update_cache or \
78
            default_storage.created_time(path) < datetime.now() - timedelta(days=1):
79
        threading.Thread(target=load_federation_cache, args=(url,)).start()
80
        sleep(2)
81
    return default_storage.open(path).read()
82
    logger.warning('federation %s has not been loaded', url)
83
    return None
setup.py
94 94
          'django>=1.5',
95 95
          'requests',
96 96
          'isodate',
97
          'pytz',
97 98
      ],
98 99
      setup_requires=[
99 100
          'django',
100
-