admin.py 8.19 KB
Newer Older
Marc Duez's avatar
Marc Duez committed
1
# coding: utf8
Marc Duez's avatar
Marc Duez committed
2
import gluon.contrib.simplejson, re
3
import os.path, subprocess
4
import vidjil_utils
5

6
MAX_LOG_LINES = 500
7

Marc Duez's avatar
Marc Duez committed
8 9 10 11 12 13 14 15
if request.env.http_origin:
    response.headers['Access-Control-Allow-Origin'] = request.env.http_origin  
    response.headers['Access-Control-Allow-Credentials'] = 'true'
    response.headers['Access-Control-Max-Age'] = 86400
    

## return admin_panel
def index():
16
    if auth.is_admin():
17 18 19 20 21
        p = subprocess.Popen(["uptime"], stdout=subprocess.PIPE)
        uptime, err = p.communicate()
        
        p = subprocess.Popen(["df", "-h"], stdout=subprocess.PIPE)
        disk_use, err = p.communicate()
22 23 24 25 26 27
        revision = 'not versioned'
        try:
            p = subprocess.Popen(["git", "rev-parse", "HEAD"], stdout=subprocess.PIPE)
            revision,  err = p.communicate()
        except:
            pass
28
        
29 30
        d = monitor()
        return dict(d,
31
                    uptime=uptime,
32 33
                    disk_use=disk_use,
                    revision=revision,
34
                    )
35 36 37


def monitor():
Marc Duez's avatar
Marc Duez committed
38 39 40 41 42
    """
    >>> monitor().has_key('worker')
    True
    
    """
43
    # External monitor
44 45 46 47 48 49 50

    last_results = ''
    for res in db(db.scheduler_task.id == db.results_file.scheduler_task_id).select(orderby=~db.results_file.id,
                                                                                    limitby=(0,10)):
        last_results += res.scheduler_task.status[0]


51
    return dict (worker = len(db().select(db.scheduler_worker.ALL)),
52 53
                 queued = len(db(db.scheduler_task.status=='QUEUED').select()),
                 assigned = len(db(db.scheduler_task.status=='ASSIGNED').select()),
54 55
                 running = len(db(db.scheduler_task.status=='RUNNING').select()),
                 last_results = last_results)
Marc Duez's avatar
Marc Duez committed
56
    
Marc Duez's avatar
Marc Duez committed
57
    
58
def showlog():
59
    if auth.is_admin():
Marc Duez's avatar
Marc Duez committed
60
        
61
        
Marc Duez's avatar
Marc Duez committed
62
        lines = []
63
        file = open(defs.DIR_LOG+request.vars["file"])
64 65
        log_format = request.vars['format'] if 'format' in request.vars else ''

66 67 68
        if log_format == 'raw':
            return {'raw': ''.join(file.readlines()), 'format': log_format}

69 70
        if "filter" not in request.vars :
            request.vars["filter"] = ""
Marc Duez's avatar
Marc Duez committed
71
            
72
        for row in reversed(file.readlines()) :
73
            parsed = False
74

75
            if not vidjil_utils.advanced_filter([row], request.vars["filter"]) :
76 77
                continue

78
            if log_format: # == 'vidjil'
79 80 81 82
                # Parses lines such as
                # [11889] 2015-02-01 12:01:28,367     INFO - default.py:312 1.23.45.67/user/Toto <Toto> xxxxx log message
                # [11889] 2015-02-01 12:01:28,367     INFO - default.py:312 1.23.45.67 log message
                # [11889] 2015-02-01 12:01:28,367     INFO - default.py:312 log message
Marc Duez's avatar
Marc Duez committed
83 84 85 86
                line = {}

                tmp = re.split('\t+| +', row) 

87 88 89 90 91
                if len(tmp) >= 7:
                    parsed = True
                    line["date"] = tmp[1]
                    line["date2"] = tmp[2].split(',')[0]
                    line["type"] = tmp[3]
92
                    line["file"] = vidjil_utils.log_links(tmp[5])
93 94 95 96 97 98 99 100 101 102 103 104

                    if tmp[6] != "Creating":
                        if len(tmp) < 9:
                            j = 0
                            parsed = False
                        elif '<' in tmp[8]:
                            line["user"] = tmp[8] + ' ' + tmp[7]
                            j = 9
                        else:
                            line["user"] = tmp[7]
                            j = 8
                        line["mes"] = " ".join(tmp[j:])
105
                    else:
106 107 108
                        line["user"] = ""
                        line["mes"] = " ".join(tmp[6:])

HERBERT Ryan's avatar
HERBERT Ryan committed
109
                    line["mes"] = line["mes"].replace(" at ", "\nat ")
110 111 112 113
                    line["mes"] = vidjil_utils.log_links(line["mes"])

            if not parsed:
                line = { 'mes': row, 'date': '', 'date2': '', 'user': '', 'type':'', 'file':''}
114

115 116
            ### Stores log line
            lines.append(line)
Marc Duez's avatar
Marc Duez committed
117

118
            if len(lines) >= MAX_LOG_LINES :
119
                break
Marc Duez's avatar
Marc Duez committed
120
            
121
        return {'lines': lines, 'format': log_format}
Marc Duez's avatar
Marc Duez committed
122 123 124

## to use after change in the upload folder
def repair_missing_files():
125
    if auth.is_admin():
Marc Duez's avatar
Marc Duez committed
126 127 128 129 130 131 132
        
        flist = ""
        for row in db(db.sequence_file.id>0 and db.sequence_file.data_file != None).select() : 
            seq_file = defs.DIR_SEQUENCES+row.data_file
            
            if not os.path.exists(seq_file) :
                db.sequence_file[row.id] = dict(data_file = None)
133
                flist += " : " + str(row.filename)
Marc Duez's avatar
Marc Duez committed
134
            else :
135
                size = os.path.getsize(seq_file)
Marc Duez's avatar
Marc Duez committed
136 137
                db.sequence_file[row.id] = dict(size_file = size)
                
138
        res = {"success" : "true", "message" : "DB: references to missing files have been removed: "+flist}
139
        log.admin(res)
Marc Duez's avatar
Marc Duez committed
140
        return gluon.contrib.simplejson.dumps(res, separators=(',',':'))
141 142

    
143 144 145
def backup_database(stream):
    db.export_to_csv_file(stream)

146
def make_backup():
147
    if auth.is_admin():
148
        
149
        backup_database(open(defs.DB_BACKUP_FILE, 'wb'))
150
                
Vidjil Team's avatar
Vidjil Team committed
151
        res = {"success" : "true", "message" : "DB backup -> %s" % defs.DB_BACKUP_FILE}
152
        log.admin(res)
153
        return gluon.contrib.simplejson.dumps(res, separators=(',',':'))
marc's avatar
marc committed
154 155 156 157 158
    
    
def load_backup():
    if auth.is_admin():
        db.import_from_csv_file(defs.DB_BACKUP_FILE,'rb')
159 160 161 162

## delete all sample_set
## create a new sample_set for every patient/ every sequence_file
## add sequence_file from a patient to the patient sample set
163
## Add sample_set_id to fused_file and analysis_file entries
164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182
def sample_set_fixer():
    if auth.is_admin():
        
        db(db.sample_set.id>0).update(sample_type="old")
        db(db.sample_set_membership.id>0).delete()
        
        for row in db(db.sequence_file.id>0).select() :
            sample_set_id = db.sample_set.insert(sample_type="sequence_file")

            db.sample_set_membership.insert(sample_set_id=sample_set_id,
                                           sequence_file_id=row.id)
        
        for row in db(db.patient.id>0).select() :
            sample_set_id = db.sample_set.insert(sample_type="patient")
            db.patient[row.id] = dict(sample_set_id=sample_set_id)
            
            for row2 in db(db.sequence_file.patient_id==row.id).select() :
                db.sample_set_membership.insert(sample_set_id=sample_set_id,
                                               sequence_file_id=row2.id)
183 184 185

            db(db.fused_file.patient_id==row.id).update(sample_set_id=sample_set_id)
            db(db.analysis_file.patient_id==row.id).update(sample_set_id=sample_set_id)
186 187 188
                
        db(db.sample_set.sample_type=="old").delete()
                
189 190
    
def repair():
191
    if auth.is_admin():
192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211
        
        flist = "fix creator "
        for row in db(db.patient.creator == None).select() : 
            flist += " : " + str(row.id)
            db.patient[row.id] = dict(creator = auth.user_id)
            
        flist += "fix event "
        for row in db(db.auth_event.user_id == None).select() : 
            flist += " : " + str(row.id)
            db.auth_event[row.id] = dict(user_id = auth.user_id)
            
        flist += "fix permission "
        db(db.auth_permission.group_id == None).delete();
        
        flist += "fix sequence_file provider "
        for row in db(db.sequence_file.provider == None).select() :
            flist += " : " + str(row.id)
            db.sequence_file[row.id] = dict(provider = auth.user_id)
      
        flist += "fix sequence_file patient "
212 213
        db((db.sequence_file.id == db.sample_set_membership.sequence_file_id)
           & (db.sample_set_membership.sample_set_id == None)).delete();
214 215 216 217 218 219 220 221 222
        
        flist += "fix results_file "
        db(db.results_file.sequence_file_id == None).delete()
    
        flist += "fix fused file "
        for row in db(db.fused_file.fuse_date == None).select() :
            flist += " : " + str(row.id)
            db.fused_file[row.id] = dict(fuse_date = "1970-01-01 00:00:00")
        
223
        res = {"success" : "true", "message" : "DB repaired: " + flist}
224
        log.admin(res)
225
        return gluon.contrib.simplejson.dumps(res, separators=(',',':'))
226 227