| 1 | # -*- coding: utf-8 -*- |
|---|
| 2 | ## |
|---|
| 3 | ## |
|---|
| 4 | ## This file is part of CDS Indico. |
|---|
| 5 | ## Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 CERN. |
|---|
| 6 | ## |
|---|
| 7 | ## CDS Indico is free software; you can redistribute it and/or |
|---|
| 8 | ## modify it under the terms of the GNU General Public License as |
|---|
| 9 | ## published by the Free Software Foundation; either version 2 of the |
|---|
| 10 | ## License, or (at your option) any later version. |
|---|
| 11 | ## |
|---|
| 12 | ## CDS Indico is distributed in the hope that it will be useful, but |
|---|
| 13 | ## WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 14 | ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|---|
| 15 | ## General Public License for more details. |
|---|
| 16 | ## |
|---|
| 17 | ## You should have received a copy of the GNU General Public License |
|---|
| 18 | ## along with CDS Indico; if not, write to the Free Software Foundation, Inc., |
|---|
| 19 | ## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. |
|---|
| 20 | import os, sys, csv, tempfile, stat |
|---|
| 21 | from datetime import datetime, timedelta |
|---|
| 22 | from mod_python import apache |
|---|
| 23 | from MaKaC.common import DBMgr |
|---|
| 24 | from MaKaC.rb_factory import Factory |
|---|
| 25 | from MaKaC.common.Configuration import Config |
|---|
| 26 | from MaKaC.common.datetimeParser import parse_date |
|---|
| 27 | from MaKaC.domain import DomainHolder |
|---|
| 28 | from MaKaC.common.info import HelperMaKaCInfo |
|---|
| 29 | from MaKaC.errors import HostnameResolveError |
|---|
| 30 | from MaKaC.webinterface.urlHandlers import UHRoomBookingBookingDetails |
|---|
| 31 | from MaKaC.common.utils import parseDate |
|---|
| 32 | |
|---|
| 33 | """ |
|---|
| 34 | TODO: This must be refactor to be done with RH??? |
|---|
| 35 | """ |
|---|
| 36 | |
|---|
| 37 | def index(req, **params): |
|---|
| 38 | |
|---|
| 39 | DBMgr.getInstance().startRequest() |
|---|
| 40 | Factory.getDALManager().connect() |
|---|
| 41 | |
|---|
| 42 | ################### checking protection ################### |
|---|
| 43 | |
|---|
| 44 | def getHostIP(req): |
|---|
| 45 | import socket |
|---|
| 46 | |
|---|
| 47 | host = str(req.get_remote_host(apache.REMOTE_NOLOOKUP)) |
|---|
| 48 | |
|---|
| 49 | try: |
|---|
| 50 | hostIP = socket.gethostbyname(host) |
|---|
| 51 | minfo = HelperMaKaCInfo.getMaKaCInfoInstance() |
|---|
| 52 | if minfo.useProxy(): |
|---|
| 53 | # if we're behind a proxy, use X-Forwarded-For |
|---|
| 54 | xff = req.headers_in.get("X-Forwarded-For",hostIP).split(", ")[-1] |
|---|
| 55 | return socket.gethostbyname(xff) |
|---|
| 56 | else: |
|---|
| 57 | return hostIP |
|---|
| 58 | except socket.gaierror, e: |
|---|
| 59 | # in case host resolution fails |
|---|
| 60 | raise HostnameResolveError("Error resolving host '%s' : %s" % (host, e)) |
|---|
| 61 | |
|---|
| 62 | |
|---|
| 63 | # check if it is a machine that belongs to the CERN domain |
|---|
| 64 | cernDomain = DomainHolder().getById(0) # id 0 means CERN |
|---|
| 65 | if not cernDomain.belongsTo(getHostIP(req)): |
|---|
| 66 | return "Only CERN users can access to this export resource" |
|---|
| 67 | |
|---|
| 68 | ################### checking params ################### |
|---|
| 69 | if not (params.has_key("sd") and params.has_key("ed") and params.has_key("r")): |
|---|
| 70 | return """Missing parameters. The request should be like this: http://indico.cern.ch/exportReservations.py?sd=24-09-2010&ed=25-09-2010&r=1,18,114,42""" |
|---|
| 71 | |
|---|
| 72 | try: |
|---|
| 73 | sd = parseDate(params.get("sd"), "%Y-%m-%d") |
|---|
| 74 | ed = parseDate(params.get("ed"), "%Y-%m-%d") |
|---|
| 75 | except ValueError, e: |
|---|
| 76 | return """The format for the dates (sd and ed) must be like this: YYYY-MM-DD""" |
|---|
| 77 | if sd > ed: |
|---|
| 78 | return """'sd' must be <= than 'ed'""" |
|---|
| 79 | if ed - sd > timedelta(35): |
|---|
| 80 | return """One can only export 3 days at most""" |
|---|
| 81 | |
|---|
| 82 | |
|---|
| 83 | roomIDs = params.get("r").strip().split(",") |
|---|
| 84 | if roomIDs == "": |
|---|
| 85 | return """At least one roomID must be specified (http://....?r=1,42,14,...)""" |
|---|
| 86 | try: |
|---|
| 87 | roomIDs = map(lambda x: int(x), roomIDs) |
|---|
| 88 | except ValueError: |
|---|
| 89 | return """Room IDs must be integers separated by commas (http://....?r=1,42,14,...)""" |
|---|
| 90 | if len(roomIDs) > 10: |
|---|
| 91 | return "One can only export 10 rooms at most" |
|---|
| 92 | |
|---|
| 93 | #################### process ################### |
|---|
| 94 | |
|---|
| 95 | results=[['URL', |
|---|
| 96 | 'id', |
|---|
| 97 | 'start date', |
|---|
| 98 | 'end date', |
|---|
| 99 | 'name', |
|---|
| 100 | 'site', |
|---|
| 101 | 'building', |
|---|
| 102 | 'floor', |
|---|
| 103 | 'roomNr', |
|---|
| 104 | 'IP', |
|---|
| 105 | 'H323 IP', |
|---|
| 106 | 'uses VC equipment' |
|---|
| 107 | ]] |
|---|
| 108 | |
|---|
| 109 | rooms = [] |
|---|
| 110 | for roomID in roomIDs: |
|---|
| 111 | roomEx = Factory.newRoom() |
|---|
| 112 | roomEx.id = roomID |
|---|
| 113 | rooms.append(roomEx) |
|---|
| 114 | |
|---|
| 115 | resvEx = Factory.newReservation() |
|---|
| 116 | resvEx.startDT = datetime(sd.year, sd.month, sd.day, 0, 0) |
|---|
| 117 | resvEx.endDT = datetime(ed.year, ed.month, ed.day, 23, 59) |
|---|
| 118 | resvs = resvEx.getCollisions(rooms = rooms ) |
|---|
| 119 | |
|---|
| 120 | for collision in resvs: |
|---|
| 121 | resv = collision.withReservation |
|---|
| 122 | if resv.usesAVC: |
|---|
| 123 | usesAVC = 1 |
|---|
| 124 | else: |
|---|
| 125 | usesAVC = 0 |
|---|
| 126 | results.append([str(UHRoomBookingBookingDetails.getURL(resv)), |
|---|
| 127 | str(resv.id), |
|---|
| 128 | collision.startDT.strftime("%Y-%m-%d %H:%M:%S"), |
|---|
| 129 | collision.endDT.strftime("%Y-%m-%d %H:%M:%S"), |
|---|
| 130 | resv.room.name or "", |
|---|
| 131 | resv.room.site, |
|---|
| 132 | str(resv.room.building), |
|---|
| 133 | resv.room.floor, |
|---|
| 134 | str(resv.room.roomNr), |
|---|
| 135 | resv.room.customAtts.get('IP') or "", |
|---|
| 136 | resv.room.customAtts.get('H323 IP') or "", |
|---|
| 137 | usesAVC |
|---|
| 138 | ]) |
|---|
| 139 | |
|---|
| 140 | Factory.getDALManager().disconnect() |
|---|
| 141 | DBMgr.getInstance().endRequest() |
|---|
| 142 | |
|---|
| 143 | #################### create temp file ################### |
|---|
| 144 | cfg = Config.getInstance() |
|---|
| 145 | tempPath = cfg.getUploadedFilesTempDir() |
|---|
| 146 | tempFileName = tempfile.mkstemp( prefix="Bookings", suffix=".csv", dir = tempPath )[1] |
|---|
| 147 | |
|---|
| 148 | #################### write the results in the temp file ################### |
|---|
| 149 | fd=open(tempFileName, 'w') |
|---|
| 150 | writer = csv.writer(fd, delimiter=',', quotechar='"', quoting=csv.QUOTE_MINIMAL) |
|---|
| 151 | for i in results: |
|---|
| 152 | writer.writerow(i) |
|---|
| 153 | fd.close() |
|---|
| 154 | |
|---|
| 155 | #################### return the CSV file ################### |
|---|
| 156 | req.headers_out["Content-Length"] = "%s"%int(os.stat(tempFileName)[stat.ST_SIZE]) |
|---|
| 157 | mimetype = cfg.getFileTypeMimeType( cfg.getFileType("CSV") ) |
|---|
| 158 | req.content_type = """%s"""%(mimetype) |
|---|
| 159 | req.headers_out["Content-Disposition"] = """inline; filename="%s\""""%os.path.basename(tempFileName) |
|---|
| 160 | |
|---|
| 161 | fr = open(tempFileName, "rb") |
|---|
| 162 | data = fr.read() |
|---|
| 163 | fr.close() |
|---|
| 164 | return data |
|---|
| 165 | |
|---|