diff --git a/modules/bibrank/lib/bibrank_grapher.py b/modules/bibrank/lib/bibrank_grapher.py index 0bab0f3f9..e1304a531 100644 --- a/modules/bibrank/lib/bibrank_grapher.py +++ b/modules/bibrank/lib/bibrank_grapher.py @@ -1,204 +1,204 @@ # -*- coding: utf-8 -*- ## ## $Id$ ## ## This file is part of CDS Invenio. ## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN. ## ## CDS Invenio is free software; you can redistribute it and/or ## modify it under the terms of the GNU General Public License as ## published by the Free Software Foundation; either version 2 of the ## License, or (at your option) any later version. ## ## CDS Invenio is distributed in the hope that it will be useful, but ## WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ## General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with CDS Invenio; if not, write to the Free Software Foundation, Inc., ## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. __revision__ = "$Id$" import os import sys import time import tempfile -from invenio.config import webdir +from invenio.config import * from invenio.websubmit_config import * ## test gnuplot presence: cfg_gnuplot_available = 1 try: import Gnuplot except ImportError, e: cfg_gnuplot_available = 0 def write_coordinates_in_tmp_file(lists_coordinates): """write the graph coordinates in a temporary file for reading it later by the create_temporary_image method lists_coordinates is a list of list of this form: [[(1,3),(2,4),(3,5)],[(1,5),(2,5),(3,6)] This file is organized into one or more sets of 2 columns. Each set is separated from the others by two blank lines. Each intern list represents a set and each tuple a line in the file where fist element of the tuple is the element of the first column, and second element of the tuple is the element of the second column. With gnuplot, first column is used as x coordinates, and second column as y coordinates. One set represents a curve in the graph. """ max_y_datas = 0 tempfile.tempdir = webdir + "img" fname = tempfile.mktemp() file_dest = open(fname, 'a') for list_elem in lists_coordinates: y_axe = [] #prepare data and store them in a file for key_value in list_elem: file_dest.write("%s %s\n"%(key_value[0], key_value[1])) y_axe.append(key_value[1]) max_tmp = 0 if y_axe: max_tmp = max(y_axe) if max_tmp > max_y_datas: max_y_datas = max_tmp file_dest.write("\n\n") file_dest.close() return [fname, max_y_datas] def create_temporary_image(recid, kind_of_graphe, data_file, x_label, y_label, origin_tuple, y_max, docid_list, graphe_titles, intervals): """From a temporary file, draw a gnuplot graph The arguments are as follows: recid - reccord ID kind_of_graph - takes one of these values : "citation" ,"download_history", "download_users" All the commons gnuplot commands for these cases, are written at the beginning After the particular commands dependaing of each case are written. data_file - Name of the temporary file which contains the gnuplot datas used to plot the graph. This file is organized into one or more sets of 2 columns. First column contains x coordinates, and second column contains y coordinates. Each set is separated from the others by two blank lines. x_label - Name of the x axe. y_label - Name of the y axe. origin_tuple - Reference coordinates for positionning the graph. y_max - Max value of y. Used to set y range. docid_list - In download_history case, docid_list is used to plot multiple curves. graphe_titles - List of graph titles. It's used to name the curve in the legend. intervals - x tics location and xrange specification""" if cfg_gnuplot_available == 0: return (None, None) #For different curves color_line_list = ['4', '3', '2', '9', '6'] #Gnuplot graphe object g = Gnuplot.Gnuplot() #Graphe name: file to store graph graphe_name = "tmp_%s_%s_stats.png" % (kind_of_graphe, recid) g('set terminal png small') g('set output "%s/img/%s"' % (webdir, graphe_name)) len_intervals = len(intervals) len_docid_list = len(docid_list) # Standard options g('set size 0.5,0.5') g('set origin %s,%s'% (origin_tuple[0], origin_tuple[1])) if x_label == '': g('unset xlabel') else: g.xlabel(s = x_label) if x_label == '': g('unset ylabel') else: g.ylabel(s = y_label) g('set bmargin 5') #let a place at the top of the graph g('set tmargin 1') #Will be passed to g at the end to plot the graphe plot_text = "" if kind_of_graphe == 'download_history': g('set xdata time') #Set x scale as date g('set timefmt "%m/%Y"') #Inform about format in file .dat g('set format x "%b %y"') #Format displaying if len(intervals) > 1 : g('set xrange ["%s":"%s"]' % (intervals[0], intervals[len_intervals-1])) y_offset = max(3, float(y_max)/60) g('set yrange [0:%s]' %str(y_max + y_offset)) if len_intervals > 1 and len_intervals <= 12: g('set xtics rotate %s' % str(tuple(intervals)))#to prevent duplicate tics elif len_intervals > 12 and len_intervals <= 24: g('set xtics rotate "%s", 7776000, "%s"' % (intervals[0], intervals[len_intervals-1])) #3 months intervalls else : g('set xtics rotate "%s",15552000, "%s"' % (intervals[0], intervals[len_intervals-1])) #6 months intervalls if len_docid_list <= 1: #Only one curve #g('set style fill solid 0.25') if len(intervals)<=4: plot_text = plot_command(1, data_file, (0, 0), "", "imp", color_line_list[0], 20) else: plot_text = plot_command(1, data_file, (0, 0), "", "linespoint", color_line_list[0], 1, "pt 26", "ps 0.5") elif len_docid_list > 1: #Multiple curves if len(intervals)<=4: plot_text = plot_command(1, data_file, (0, 0), graphe_titles[0], "imp", color_line_list[0], 20) else: plot_text = plot_command(1, data_file, (0, 0), graphe_titles[0], "linespoint", color_line_list[0], 1, "pt 26", "ps 0.5") for d in range(1, len_docid_list): if len(intervals)<=4: plot_text += plot_command(0, data_file, (d, d) , graphe_titles[d], "imp", color_line_list[d], 20) else : plot_text += plot_command(0, data_file, (d, d) , graphe_titles[d], "linespoint", color_line_list[d], 1, "pt 26", "ps 0.5") if len(intervals)>2: plot_text += plot_command(0, data_file, (len_docid_list, len_docid_list), "", "impulses", 0, 2 ) plot_text += plot_command(0, data_file, (len_docid_list, len_docid_list), "TOTAL", "lines", 0, 5) elif kind_of_graphe == 'download_users': g('set size 0.25,0.5') g('set xrange [0:4]') g('set yrange [0:100]') g('set format y "%g %%"') g("""set xtics ("" 0, "CERN\\n Users" 1, "Other\\n Users" 3, "" 4)""") g('set ytics 0,10,100') g('set boxwidth 0.7 relative') g('set style fill solid 0.25') plot_text = 'plot "%s" using 1:2 title "" with boxes lt 7 lw 2' % data_file else: #citation g('set boxwidth 0.6 relative') g('set style fill solid 0.250000 border -1') g('set xtics rotate %s'% str(tuple(intervals))) g('set xrange [%s:%s]' % (str(intervals[0]), str(intervals[len_intervals-1]))) g('set yrange [0:%s]' %str(y_max+2)) plot_text = """plot "% s" index 0:0 using 1:2 title "" w steps lt %s lw 3""" % (data_file, color_line_list[1]) g('%s' % plot_text) return (graphe_name, data_file) def remove_old_img(prefix_file_name): """Detele all the images older than 10 minutes to prevent to much storage Takes 0.0 seconds for 50 files to delete""" command = "find %s/img/ -name tmp_%s*.png -amin +10 -exec rm -f {} \;" % (webdir, prefix_file_name) return os.system(command) def plot_command(first_line, file_source, indexes, title, style, line_type, line_width, point_type="", point_size=""): """Return a string of a gnuplot plot command.Particularly useful when multiple curves From a temporary file, draw a gnuplot graph Return a plot command string as follows: plot datafile , datafile ,... The arguments are as follows: first_line - only the drawing command of the first curve contains the word plot file_source - data file source which containes coordinates indexes - points out set number in data file source title - title of the curve in the legend box style - respresentation of the curve ex: linespoints, lines ... line_type - color of the line line_width - width of the line point_type - optionnal parameter: if not mentionned it's a wide string. Using in the case of style = linespoints to set point style""" if first_line: plot_text = """plot "%s" index %s:%s using 1:2 title "%s" with %s lt %s lw %s %s %s""" % (file_source, indexes[0], indexes[1], title, style, line_type, line_width, point_type, point_size) else: plot_text = """, "%s" index %s:%s using 1:2 title "%s" with %s lt %s lw %s %s %s""" % (file_source, indexes[0], indexes[1], title, style, line_type, line_width, point_type, point_size) return plot_text diff --git a/modules/websubmit/lib/file.py b/modules/websubmit/lib/file.py index 2aaa52e0a..172450fe4 100644 --- a/modules/websubmit/lib/file.py +++ b/modules/websubmit/lib/file.py @@ -1,577 +1,577 @@ ## $Id$ ## This file is part of CDS Invenio. ## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN. ## ## CDS Invenio is free software; you can redistribute it and/or ## modify it under the terms of the GNU General Public License as ## published by the Free Software Foundation; either version 2 of the ## License, or (at your option) any later version. ## ## CDS Invenio is distributed in the hope that it will be useful, but ## WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ## General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with CDS Invenio; if not, write to the Free Software Foundation, Inc., ## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. ## import interesting modules: import string import os import sys import time import types import re import mimetypes import shutil import md5 import urllib from xml.sax.saxutils import quoteattr from mod_python import apache from invenio.config import * from invenio.access_control_engine import acc_authorize_action from invenio.access_control_admin import acc_isRole from invenio.webpage import page, create_error_box from invenio.webuser import getUid, get_email from invenio.dbquery import run_sql from invenio.websubmit_config import * from invenio.messages import gettext_set_language import invenio.template websubmit_templates = invenio.template.load('websubmit') archivepath = filedir archivesize = filedirsize # sort compressed file extensions list to get lengthy ones first: -cfg_compressed_file_extensions_sorted = cfg_compressed_file_extensions -cfg_compressed_file_extensions_sorted.sort() +CFG_COMPRESSED_FILE_EXTENSIONS_SORTED = CFG_COMPRESSED_FILE_EXTENSIONS +CFG_COMPRESSED_FILE_EXTENSIONS_SORTED.sort() def file_strip_ext(file): - for c_ext in cfg_known_file_extensions: + for c_ext in CFG_KNOWN_FILE_EXTENSIONS: if file[-len(c_ext):len(file)]==c_ext and file[-len(c_ext)-1]==".": file = file[0:-len(c_ext)-1] return file class BibRecDocs: """this class represents all the files attached to one record""" def __init__(self,recid): self.id = recid self.bibdocs = [] self.buildBibDocList() def buildBibDocList(self): self.bibdocs = [] res = run_sql("select id_bibdoc,type,status from bibrec_bibdoc,bibdoc where id=id_bibdoc and id_bibrec=%s", (self.id,)) for row in res: if row[2] == "": status = 0 else: status = int(row[2]) if status & 1 == 0: self.bibdocs.append(BibDoc(bibdocid=row[0],recid=self.id)) def listBibDocs(self,type=""): tmp=[] for bibdoc in self.bibdocs: if type=="" or type == bibdoc.getType(): tmp.append(bibdoc) return tmp def getBibDocNames(self,type="Main"): names = [] for bibdoc in self.listBibDocs(type): names.append(bibdoc.getDocName()) return names def getBibDoc(self,bibdocid): for bibdoc in self.bibdocs: if bibdoc.getId() == bibdocid: return bibdoc return None def deleteBibDoc(self,bibdocid): for bibdoc in self.bibdocs: if bibdoc.getId() == bibdocid: bibdoc.delete() self.buildBibDocList() def addBibDoc(self,type="Main",docname="file"): while docname in self.getBibDocNames(type): match = re.match("(.*_)([^_]*)",docname) if match: try: docname = match.group(1)+str(int(match.group(2)) + 1) except: docname = docname + "_2" else: docname = docname + "_2" bibdoc = BibDoc(recid=self.id,type=type,docname=docname) if bibdoc != None: self.bibdocs.append(bibdoc) return bibdoc def addNewFile(self,fullpath,type="Main"): filename = re.sub("\..*","",re.sub(r".*[\\/:]", "", fullpath)) bibdoc = self.addBibDoc(type,filename) if bibdoc != None: bibdoc.addFilesNewVersion(files=[fullpath]) return bibdoc return None def addNewVersion(self,fullpath,bibdocid): bibdoc = self.getBibDoc(bibdocid) if bibdoc != None: bibdoc.addFilesNewVersion(files=[fullpath]) docname = re.sub("\..*","",re.sub(r".*[\\/:]", "", fullpath)) if docname != bibdoc.getDocName(): while docname in self.getBibDocNames(bibdoc.getType()): match = re.match("(.*_)([^_]*)",docname) if match: try: docname = match.group(1)+str(int(match.group(2)) + 1) except: docname = docname + "_2" else: docname = docname + "_2" bibdoc.changeName(docname) return bibdoc return None def addNewFormat(self,fullpath,bibdocid): bibdoc = self.getBibDoc(bibdocid) if bibdoc != None: bibdoc.addFilesNewFormat(files=[fullpath]) return bibdoc return None def listLatestFiles(self,type=""): docfiles = [] for bibdoc in self.listBibDocs(type): for docfile in bibdoc.listLatestFiles(): docfiles.append(docfile) return docfiles def checkFileExists(self,fullpath,type=""): if os.path.exists(fullpath): docfiles = self.listLatestFiles(type) for docfile in docfiles: if md5.new(readfile(fullpath)).digest() == md5.new(readfile(docfile.getPath())).digest(): return docfile.getBibDocId() else: return 0 def display(self,bibdocid="",version="",type="", ln = cdslang): t="" bibdocs = [] if bibdocid!="": for bibdoc in self.bibdocs: if bibdoc.getId() == bibdocid: bibdocs.append(bibdoc) else: bibdocs = self.listBibDocs(type) if len(bibdocs) > 0: types = listTypesFromArray(bibdocs) fulltypes = [] for mytype in types: fulltype = { 'name' : mytype, 'content' : [], } for bibdoc in bibdocs: if mytype == bibdoc.getType(): fulltype['content'].append(bibdoc.display(version, ln = ln)) fulltypes.append(fulltype) t = websubmit_templates.tmpl_bibrecdoc_filelist( ln = ln, types = fulltypes, ) return t class BibDoc: """this class represents one file attached to a record there is a one to one mapping between an instance of this class and an entry in the bibdoc db table""" def __init__ (self,bibdocid="",recid="",docname="file",type="Main"): # bibdocid is known, the document already exists if bibdocid != "": if recid == "": res = run_sql("select id_bibrec,type from bibrec_bibdoc where id_bibdoc=%s",(bibdocid,)) if len(res) > 0: recid = res[0][0] self.type = res[0][1] else: recid = None self.type = "" else: res = run_sql("select type from bibrec_bibdoc where id_bibrec=%s and id_bibdoc=%s",(recid,bibdocid,)) self.type = res[0][0] # gather the other information res = run_sql("select * from bibdoc where id=%s", (bibdocid,)) self.cd = res[0][3] self.md = res[0][4] self.recid = recid self.docname = res[0][2] self.id = bibdocid self.status = res[0][1] group = "g"+str(int(int(self.id)/archivesize)) self.basedir = "%s/%s/%s" % (archivepath,group,self.id) # else it is a new document else: if docname == "" or type == "": return None else: self.recid = recid self.type = type self.docname = docname self.status = 0 self.id = run_sql("insert into bibdoc (status,docname,creation_date,modification_date) values(%s,%s,NOW(),NOW())", (str(self.status), docname,)) if self.id != None: #we link the document to the record if a recid was specified if self.recid != "": run_sql("insert into bibrec_bibdoc values(%s,%s,%s)", (recid,self.id,self.type,)) else: return None group = "g"+str(int(int(self.id)/archivesize)) self.basedir = "%s/%s/%s" % (archivepath,group,self.id) # we create the corresponding storage directory if not os.path.exists(self.basedir): os.makedirs(self.basedir) # and save the father record id if it exists if self.recid!="": fp = open("%s/.recid" % self.basedir,"w") fp.write(str(self.recid)) fp.close() # build list of attached files self.docfiles = {} self.BuildFileList() # link with relatedFiles self.relatedFiles = {} self.BuildRelatedFileList() def addFilesNewVersion(self,files=[]): """add a new version of a file to an archive""" latestVersion = self.getLatestVersion() if latestVersion == "0": myversion = "1" else: myversion = str(int(latestVersion)+1) for file in files: if os.path.exists(file): filename = re.sub(r".*[\\/:]", "", file) shutil.copy(file,"%s/%s;%s" % (self.basedir,filename,myversion)) self.BuildFileList() def addFilesNewFormat(self,files=[],version=""): """add a new format of a file to an archive""" if version == "": version = self.getLatestVersion() for file in files: if os.path.exists(file): filename = re.sub(r".*[\\/:]", "", file) shutil.copy(file,"%s/%s;%s" % (self.basedir,filename,version)) self.BuildFileList() def getIcon(self): if self.relatedFiles.has_key('Icon'): return self.relatedFiles['Icon'][0] else: return None def addIcon(self,file): """link an icon with the bibdoc object""" #first check if an icon already exists existingIcon = self.getIcon() if existingIcon != None: existingIcon.delete() #then add the new one filename = re.sub("\..*","",re.sub(r".*[\\/:]", "", file)) newicon = BibDoc(type='Icon',docname=filename) if newicon != None: newicon.addFilesNewVersion(files=[file]) run_sql("insert into bibdoc_bibdoc values(%s,%s,'Icon')", (self.id,newicon.getId(),)) if os.path.exists(newicon.getBaseDir()): fp = open("%s/.docid" % newicon.getBaseDir(),"w") fp.write(str(self.id)) fp.close() self.BuildRelatedFileList() def deleteIcon(self): existingIcon = self.getIcon() if existingIcon != None: existingIcon.delete() self.BuildRelatedFileList() def display(self,version="", ln = cdslang): t="" if version == "all": docfiles = self.listAllFiles() elif version != "": docfiles = self.listVersionFiles(version) else: docfiles = self.listLatestFiles() existingIcon = self.getIcon() if existingIcon != None: imagepath = "%s/getfile.py?docid=%s&name=%s&format=gif" % (weburl,existingIcon.getId(),urllib.quote(existingIcon.getDocName())) else: imagepath = "%s/smallfiles.gif" % images versions = [] for version in listVersionsFromArray(docfiles): currversion = { 'version' : version, 'previous' : 0, 'content' : [] } if version == self.getLatestVersion() and version != "1": currversion['previous'] = 1 for docfile in docfiles: if docfile.getVersion() == version: currversion['content'].append(docfile.display(ln = ln)) versions.append(currversion) t = websubmit_templates.tmpl_bibdoc_filelist( ln = ln, weburl = weburl, versions = versions, imagepath = imagepath, docname = self.docname, id = self.id, ) return t def changeName(self,newname): run_sql("update bibdoc set docname=%s where id=%s",(newname,self.id,)) self.docname = newname def getDocName(self): """retrieve bibdoc name""" return self.docname def getBaseDir(self): """retrieve bibdoc base directory""" return self.basedir def getType(self): """retrieve bibdoc type""" return self.type def getRecid(self): """retrieve bibdoc recid""" return self.recid def getId(self): """retrieve bibdoc id""" return self.id def getFile(self,name,format,version): if version == "": docfiles = self.listLatestFiles() else: docfiles = self.listVersionFiles(version) for docfile in docfiles: if docfile.getName()==name and docfile.getFormat()==format: return docfile return None def listVersions(self): versions = [] for docfile in self.docfiles: if not docfile.getVersion() in versions: versions.append(docfile.getVersion()) return versions def delete(self): """delete the current bibdoc instance""" self.status = self.status | 1 run_sql("update bibdoc set status='" + self.status + "' where id=%s",(self.id,)) def BuildFileList(self): """lists all files attached to the bibdoc""" self.docfiles = [] if os.path.exists(self.basedir): for fil in os.listdir(self.basedir): if fil != ".recid" and fil != ".docid" and fil != "." and fil != "..": filepath = "%s/%s" % (self.basedir,fil) fileversion = re.sub(".*;","",fil) fullname = fil.replace(";%s" % fileversion,"") # detect fullname's basename and extension: fullname_lowercase = fullname.lower() fullname_extension_postition = -1 # first try to detect compressed file extensions: - for compressed_file_extension in cfg_compressed_file_extensions_sorted: + for compressed_file_extension in CFG_COMPRESSED_FILE_EXTENSIONS_SORTED: if fullname_lowercase.endswith("." + compressed_file_extension): fullname_extension_postition = fullname[:-len(compressed_file_extension)-1].rfind(".") break if fullname_extension_postition == -1: # okay, no compressed extension found, so try to find last dot: fullname_extension_postition = len(file_strip_ext(fullname)) # okay, fullname_extension_postition should now indicate where extension starts (incl. compressed ones) if fullname_extension_postition == -1: fullname_basename = fullname fullname_extension = "" else: fullname_basename = fullname[:fullname_extension_postition] fullname_extension = fullname[fullname_extension_postition+1:] # we can append file: self.docfiles.append(BibDocFile(filepath,self.type,fileversion,fullname_basename,fullname_extension,self.id,self.status)) def BuildRelatedFileList(self): res = run_sql("select ln.id_bibdoc2,ln.type,bibdoc.status from bibdoc_bibdoc as ln,bibdoc where id=ln.id_bibdoc2 and ln.id_bibdoc1=%s",(self.id,)) for row in res: bibdocid = row[0] type = row[1] if row[2] == "": status = 0 else: status = int(row[2]) if status & 1 == 0: if not self.relatedFiles.has_key(type): self.relatedFiles[type] = [] self.relatedFiles[type].append(BibDoc(bibdocid=bibdocid)) def listAllFiles(self): return self.docfiles def listLatestFiles(self): return self.listVersionFiles(self.getLatestVersion()) def listVersionFiles(self,version): tmp = [] for docfile in self.docfiles: if docfile.getVersion() == version: tmp.append(docfile) return tmp def getLatestVersion(self): if len(self.docfiles) > 0: self.docfiles.sort(orderFilesWithVersion) return self.docfiles[0].getVersion() else: return 0 def getFileNumber(self): return len(self.files) def registerDownload(self,addressIp,version,format,userid=0): return run_sql("INSERT INTO rnkDOWNLOADS (id_bibrec,id_bibdoc,file_version,file_format,id_user,client_host,download_time) VALUES (%s,%s,%s,%s,%s,INET_ATON(%s),NOW())", (self.recid,self.id,version,string.upper(format),userid,addressIp,)) class BibDocFile: """this class represents a physical file in the CDS Invenio filesystem""" def __init__(self,fullpath,type,version,name,format,bibdocid,status): self.fullpath = fullpath self.type = type self.bibdocid = bibdocid self.version = version self.status = status self.size = os.path.getsize(fullpath) self.md = os.path.getmtime(fullpath) try: self.cd = os.path.getctime(fullpath) except: self.cd = self.md self.name = name self.format = format self.dir = os.path.dirname(fullpath) if format == "": self.mime = "text/plain" self.encoding = "" self.fullname = name else: self.fullname = "%s.%s" % (name,format) (self.mime,self.encoding) = mimetypes.guess_type(self.fullname) if self.mime == None: self.mime = "text/plain" def display(self, ln = cdslang): if self.format != "": format = ".%s" % self.format else: format = "" return websubmit_templates.tmpl_bibdocfile_filelist( ln = ln, weburl = weburl, id = self.bibdocid, selfformat = self.format, version = self.version, name = self.name, format = format, size = self.size, ) def isRestricted(self): """return restriction state""" if int(self.status) & 10 == 10: return 1 return 0 def getType(self): return self.type def getPath(self): return self.fullpath def getBibDocId(self): return self.bibdocid def getName(self): return self.name def getFormat(self): return self.format def getSize(self): return self.size def getVersion(self): return self.version def getRecid(self): return run_sql("select id_bibrec from bibrec_bibdoc where id_bibdoc=%s",(self.bibdocid,))[0][0] def stream(self,req): if os.path.exists(self.fullpath): req.content_type = self.mime req.encoding = self.encoding req.filename = self.fullname req.headers_out["Content-Disposition"] = "attachment; filename=%s" % quoteattr(self.fullname) req.send_http_header() fp = file(self.fullpath,"r") content = fp.read() fp.close() return content def readfile(path): if os.path.exists(path): fp = open(path,"r") content = fp.read() fp.close() return content def listTypesFromArray(bibdocs): types = [] for bibdoc in bibdocs: if not bibdoc.getType() in types: types.append(bibdoc.getType()) return types def listVersionsFromArray(docfiles): versions = [] for docfile in docfiles: if not docfile.getVersion() in versions: versions.append(docfile.getVersion()) return versions def orderFilesWithVersion(docfile1,docfile2): """order docfile objects according to their version""" version1 = int(docfile1.getVersion()) version2 = int(docfile2.getVersion()) return cmp(version2,version1) diff --git a/modules/websubmit/lib/functions/Allocate_ALEPH_SYS.py b/modules/websubmit/lib/functions/Allocate_ALEPH_SYS.py index d3bb48ee3..4e346741e 100644 --- a/modules/websubmit/lib/functions/Allocate_ALEPH_SYS.py +++ b/modules/websubmit/lib/functions/Allocate_ALEPH_SYS.py @@ -1,383 +1,382 @@ ## $Id$ ## This file is part of CDS Invenio. ## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN. ## ## CDS Invenio is free software; you can redistribute it and/or ## modify it under the terms of the GNU General Public License as ## published by the Free Software Foundation; either version 2 of the ## License, or (at your option) any later version. ## ## CDS Invenio is distributed in the hope that it will be useful, but ## WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ## General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with CDS Invenio; if not, write to the Free Software Foundation, Inc., ## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. import os.path from random import randint, seed from os import getpid, unlink, access, rename, R_OK, W_OK from os.path import getmtime from shutil import copyfile from time import strftime, localtime, time, mktime, sleep -from invenio.config import cdsname, supportemail, adminemail -from invenio.websubmit_config import counters +from invenio.config import cdsname, supportemail, adminemail, counters max_sys_approaching_warning_point = 2000 max_age_lockfile = 300 # (seconds) legal_aleph_dbs = ["CER", "IEX", "MAN", "MMD"] execfile("%s/invenio/websubmit_functions/mail.py" % pylibdir) def Allocate_ALEPH_SYS(parameters, curdir, form): """Get the next available ALEPH SYS from the counter file, and allocate it as the SYS for this record. Increment the counterby one. ALEPH SYS allocation works in "slots" of free numbers. For example, 000425201 -> 000634452 for a given database may be available. This means that it is necessary to care about not over-stepping the maximum boundary. To this end, two counters (for each ALEPH Database) must be present: - last_SYS_ (this contains the last SYS allocated for a database) - maximum_SYS_ (this contains the MAXIMUM SYS allowed for a database) So, for example, for the CER database, there would be: - last_SYS_CER - maximum_SYS_CER When the maximum SYS has been reached, all further attempts to obtain ALEPH SYSs will fail, as this function will fail with an error. To prevent this from coming as a surprise, however, when "last_SYS_" gets somewhere near to the value stored in "maximum_SYS_", a mail will be sent to the Admin with every SYS allocated, warning them that only N numbers remain free for the XY database. The number until MAX SYS which determines this period of warning emails is determined by a variable "warn_admin_at_N_sys_remaining". It is set to 2000 by default, but can be changed. When the system allocates a new sys and there are 2000 or less free SYS remaining, the warning mails to ADMIN will be sent. @param database: (string) the name of the ALEPH database for which a SYS is to be allocated. E.g. "CER". The he absence of this will cause the function to fail. Also, the absence of either of the 2 counter files "last_SYS_${database}" and "maximum_SYS_${database}" will cause the function to fail. """ mailfrom_addr = '%s Submission Engine <%s>' % (cdsname, supportemail) database = parameters['database'].strip() counter_lastsys = "last_SYS_%s" % (database,) counter_maxsys = "maximum_SYS_%s" % (database,) ## ensure that "database" param is not empty, and exists in the list of legal DBs if database == "" or database not in legal_aleph_dbs: ## error with supplied database msg = """ERROR: When trying to allocate an ALEPH SYS for a record, an invalid database name was"""\ """ supplied: [%s]. It was therefore not possible to allocate the SYS.""" % (database,) raise functionError(msg) ## before trying to make a lockfile, test if one exists and whether it is older than "max_age_lockfile" seconds ## if so, raise an error and warn the admin: counter_lockfile = "last_SYS_%s.lock" % (database,) try: lockfile_modtime = getmtime("%s/%s" % (counters, counter_lockfile)) time_now = mktime(localtime()) time_since_last_lockfile_mod = time_now - lockfile_modtime if time_since_last_lockfile_mod > max_age_lockfile: ## lockfile is old - warn admin and stop admin_msg = """ERROR: When trying to allocate an ALEPH SYS for a record in the [%s] DB, it was not possible """\ """to create a lockfile. An attempt was made at [%s], but a lockfile already existed with a """\ """last modification time of [%s]. It was therefore not possible to allocate the SYS.""" \ % (database, strftime("%d/%m/%Y %H:%M:%S", localtime(time_now)), strftime("%d/%m/%Y %H:%M:%S", localtime(lockfile_modtime))) mailbody = forge_email(fromaddr=mailfrom_addr, toaddr=adminemail, bcc="", subject="WebSubmit ERROR - OLD ALEPH SYS LOCKFILE ENCOUNTERED!", content="\n\n"+admin_msg) send_email(fromaddr=mailfrom_addr, toaddr=adminemail, body=mailbody) user_msg = """ERROR: When trying to allocate an ALEPH SYS for a record in the [%s] DB, it was not possible""" \ """ to create a lockfile. It was therefore not possible to allocate the SYS.""" \ % (database,) raise functionError(user_msg) except OSError: ## no lockfile pass ## before any counter operations, create a lockfile: got_lock = _create_SYS_counter_lockfile(database) if got_lock == 0: ## unable to create lockfile! msg = """ERROR: When trying to allocate an ALEPH SYS for a record in the [%s] DB, it was not possible"""\ """ to create a lockfile within 60 seconds. It was therefore not possible to allocate the SYS.""" % (database,) mailbody = forge_email(fromaddr=mailfrom_addr, toaddr=adminemail, bcc="", subject="WebSubmit ERROR - CANNOT CREATE LOCKFILE!", content="\n\n"+msg) send_email(fromaddr=mailfrom_addr, toaddr=adminemail, body=mailbody) raise functionError(msg) ## test that counter files exist for "database": rw_count_lastsys_ok = access("%s/%s" % (counters, counter_lastsys), R_OK|W_OK) rw_count_maxsys_ok = access("%s/%s" % (counters, counter_maxsys), R_OK|W_OK) if not rw_count_lastsys_ok or not rw_count_maxsys_ok: ## cannot access the ALEPH counter files - critical error msg = """ERROR: When trying to allocate an ALEPH SYS for a record, either [%s] or [%s] (or both) was not"""\ """ accessable. It was therefore not possible to allocate the SYS.""" % (counter_lastsys, counter_maxsys) lockfile_removed = _unlink_SYS_counter_lockfile(database) if lockfile_removed == 0: ## couldn't remove lockfile - mail ADMIN _mail_admin_because_lockfile_not_removeable(lockfilename="last_SYS_%s" % (database,), extramsg="\n\n"+msg) mailbody = forge_email(fromaddr=mailfrom_addr, toaddr=adminemail, bcc="", subject="WebSubmit ERROR - CANNOT ACCESS ALEPH SYS COUNTER(S)!", content="\n\n"+msg) send_email(fromaddr=mailfrom_addr, toaddr=adminemail, body=mailbody) raise functionError(msg) ## read last-sys and max-sys: try: fp = open("%s/%s" % (counters, counter_lastsys), "r") fileval_lastsys = fp.read() fp.close() fp = open("%s/%s" % (counters, counter_maxsys), "r") fileval_maxsys = fp.read() fp.close() except IOError: ## could not read one or both of the files msg = """ERROR: When trying to allocate an ALEPH SYS for a record, either [%s] or [%s] (or both) could not"""\ """ be read. It was therefore not possible to allocate the SYS.""" % (counter_lastsys, counter_maxsys) lockfile_removed = _unlink_SYS_counter_lockfile(database) if lockfile_removed == 0: ## couldn't remove lockfile - mail ADMIN _mail_admin_because_lockfile_not_removeable(lockfilename="last_SYS_%s" % (database,), extramsg="\n\n"+msg) mailbody = forge_email(fromaddr=mailfrom_addr, toaddr=adminemail, bcc="", subject="WebSubmit ERROR - CANNOT ACCESS ALEPH SYS COUNTER(S)!", content="\n\n"+msg) send_email(fromaddr=mailfrom_addr, toaddr=adminemail, body=mailbody) raise functionError(msg) ## for the values from both files, clean any whitespace from beginning or end of file text and cast the result to an integer: try: lastsys = int(fileval_lastsys.strip()) maxsys = int(fileval_maxsys.strip()) except ValueError: ## the value in one or both of the files did not cast to an int! msg = """ERROR: When trying to allocate an ALEPH SYS for a record, either [%s] or [%s] (or both) contained invalid"""\ """ (non-integer) values. It was therefore not possible to allocate the SYS.""" % (counter_lastsys, counter_maxsys) lockfile_removed = _unlink_SYS_counter_lockfile(database) if lockfile_removed == 0: ## couldn't remove lockfile - mail ADMIN _mail_admin_because_lockfile_not_removeable(lockfilename="last_SYS_%s" % (database,), extramsg="\n\n"+msg) mailbody = forge_email(fromaddr=mailfrom_addr, toaddr=adminemail, bcc="", subject="WebSubmit ERROR - ALEPH SYS COUNTER(S) CONTAINS INVALID DATA!", content="\n\n"+msg) send_email(fromaddr=mailfrom_addr, toaddr=adminemail, body=mailbody) raise functionError(msg) ## check that "fileval_lastsys" is less than "fileval_maxsys". If yes, proceed - else fail and mail ADMIN if not (lastsys < maxsys): ## MAX SYS EXCEEDED msg = """ERROR: When trying to allocate an ALEPH SYS for a record, the value of [%s -> %d] is not less than the """\ """value of [%s -> %d]. It was therefore not possible to allocate the SYS. A new SYS range must be allocated!"""\ % (counter_lastsys, lastsys, counter_maxsys, maxsys) ## mail admin: mailbody = forge_email(fromaddr=mailfrom_addr, toaddr=adminemail, bcc="", subject="WebSubmit ERROR - MAXIMUM ALEPH SYS COUNTER VALUE EXCEEDED!", content="\n\n"+msg) send_email(fromaddr=mailfrom_addr, toaddr=adminemail, body=mailbody) lockfile_removed = _unlink_SYS_counter_lockfile(database) if lockfile_removed == 0: ## couldn't remove lockfile - mail ADMIN _mail_admin_because_lockfile_not_removeable(lockfilename="last_SYS_%s" % (database,), extramsg="\n\n"+msg) raise functionError(msg) if maxsys - lastsys < max_sys_approaching_warning_point: ## WARN admin that MAX ALEPH SYS for this DB is approaching: _warn_admin_counterlimit_approaching(db=database, lastsys=lastsys, maxsys=maxsys) ## increment the value of the last SYS lastsys += 1 ## cast sys to a string and pad the value on the left with leading zeros to 9 characters: cursys = "%09d%s" % (lastsys, database[0:3].upper().strip()) ## now write out the new value of lastsys to the relevant counter file: ## make temporary file then move it later tmpfname = "%s_%s_%s" % (counter_lastsys, strftime("%Y%m%d%H%M%S", localtime()), getpid()) ## open temp counter file for writing: try: fp = open("%s/%s" % (counters, tmpfname), "w") fp.write("%d" % (lastsys,)) fp.flush() fp.close() except IOError: ## could not write to temp file msg = """ERROR: When trying to allocate an ALEPH SYS for a record, could not write out new value for last SYS used """\ """to a temporary file [%s]. It was therefore not possible to allocate a SYS for the record ([%s] was not """\ """incremented.)""" % ("%s/%s" % (counters, tmpfname), counter_lastsys) ## remove the "lock file" lockfile_removed = _unlink_SYS_counter_lockfile(database) if lockfile_removed == 0: ## couldn't remove lockfile - mail ADMIN _mail_admin_because_lockfile_not_removeable(lockfilename="last_SYS_%s" % (database,), extramsg="\n\n"+msg) mailbody = forge_email(fromaddr=mailfrom_addr, toaddr=adminemail, bcc="", subject="WebSubmit ERROR - CANNOT CREATE TEMPORARY ALEPH SYS COUNTER FILE!", content="\n\n"+msg) send_email(fromaddr=mailfrom_addr, toaddr=adminemail, body=mailbody) raise functionError(msg) ## copy old counter file to backup version: try: copyfile("%s/%s" % (counters, counter_lastsys), "%s/%s.bk" % (counters, counter_lastsys)) except IOError: ## unable to make backup of counter file: msg = """ERROR: When trying to allocate an ALEPH SYS for a record, could not write out new value for last SYS used."""\ """ Couldn't make a back-up copy of the SYS counter file [%s].""" % ("%s/%s" % (counters, counter_lastsys),) ## remove the "lock file" lockfile_removed = _unlink_SYS_counter_lockfile(database) if lockfile_removed == 0: ## couldn't remove lockfile - mail ADMIN _mail_admin_because_lockfile_not_removeable(lockfilename="last_SYS_%s" % (database,), extramsg="\n\n"+msg) mailbody = forge_email(fromaddr=mailfrom_addr, toaddr=adminemail, bcc="", subject="WebSubmit ERROR - CANNOT WRITE BACK-UP ALEPH SYS COUNTER!", content="\n\n"+msg) send_email(fromaddr=mailfrom_addr, toaddr=adminemail, body=mailbody) raise functionError(msg) ## rename temp counter file to final counter file: try: rename("%s/%s" % (counters, tmpfname), "%s/%s" % (counters, counter_lastsys)) except OSError: ## couldnt rename the tmp file to final file name msg = """ERROR: When trying to allocate an ALEPH SYS for a record, could not write out new value for last SYS used."""\ """ Created the temporary last SYS counter file [%s], but couldn't then rename it to the final counter file [%s]."""\ """ It was therefore not possible to allocate a SYS for the record ([%s] was not incremented.)"""\ % ("%s/%s" % (counters, tmpfname), "%s/%s" % (counters, counter_lastsys), counter_lastsys) lockfile_removed = _unlink_SYS_counter_lockfile(database) if lockfile_removed == 0: ## couldn't remove lockfile - mail ADMIN _mail_admin_because_lockfile_not_removeable(lockfilename="last_SYS_%s" % (database,), extramsg="\n\n"+msg) mailbody = forge_email(fromaddr=mailfrom_addr, toaddr=adminemail, bcc="", subject="WebSubmit ERROR - CANNOT WRITE ALEPH SYS COUNTER FILE!", content="\n\n"+msg) send_email(fromaddr=mailfrom_addr, toaddr=adminemail, body=mailbody) raise functionError(msg) ## now that counter has been successfully incremented, write cursys out to the file "SNa500": try: fp = open("%s/SNa500" % (curdir,), "w") fp.write("%s" % (cursys,)) fp.flush() fp.close() except IOError: ## unable to write out the SYS! msg = """ERROR: When trying to allocate an ALEPH SYS for a record, could not write out new SYS to file [%s/SNa500]."""\ """ It was therefore not possible to allocate the SYS ([%s] was not incremented.)"""\ % (curdir, counter_lastsys) lockfile_removed = _unlink_SYS_counter_lockfile(database) if lockfile_removed == 0: ## couldn't remove lockfile - mail ADMIN _mail_admin_because_lockfile_not_removeable(lockfilename="last_SYS_%s" % (database,), extramsg="\n\n"+msg) raise functionError(msg) ## finally, unlink the lock file: lockfile_removed = _unlink_SYS_counter_lockfile(database) if lockfile_removed == 0: ## couldn't remove lockfile - mail ADMIN msg = """ERROR: After allocating an ALEPH SYS for a record, it was not possible to remove the lock file [last_SYS_%s.lock] after the """\ """SYS was allocated.""" % ("%s/%s" % (counters, database),) _mail_admin_because_lockfile_not_removeable(lockfilename="last_SYS_%s" % (database,), extramsg="\n\n"+msg) raise functionError(msg) return "" def _warn_admin_counterlimit_approaching(db, lastsys, maxsys): mailfrom_addr = '%s Submission Engine <%s>' % (cdsname, supportemail) mailtxt = """WARNING: The maxmimum ALEPH SYS value for the [%s] database is approaching!\n"""\ """The last SYS allocated was [%d]; The maximum SYS allowed is [%d].\n\n"""\ """You should be thinking about allocating a new range of SYS now!\n"""\ % (db, lastsys, maxsys) mailbody = forge_email(fromaddr=mailfrom_addr, toaddr=adminemail, bcc="", subject="WebSubmit WARNING - MAXIMUM SYS IN [%s] APPROACHING!" % (db,), content=mailtxt) send_email(fromaddr=mailfrom_addr, toaddr=adminemail, body=mailbody) def _mail_admin_because_lockfile_not_removeable(lockfilename, extramsg=""): mailfrom_addr = '%s Submission Engine <%s>' % (cdsname, supportemail) mailtxt = """ERROR: When trying to allocate an ALEPH SYS for a record, it was not possible to remove the lockfile [%s]!"""\ """ This means that all attempted new submissions to that database will be blocked and fail, as it is not"""\ """ possible to allocate them a SYS in ALEPH. Please investigate and remove the lockfile ASAP.\n\n"""\ % (lockfilename,) mailtxt += extramsg mailbody = forge_email(fromaddr=mailfrom_addr, toaddr=adminemail, bcc="", subject="WebSubmit ERROR - CANNOT REMOVE ALEPH SYS LOCKFILE!", content=mailtxt) send_email(fromaddr=mailfrom_addr, toaddr=adminemail, body=mailbody) def _create_SYS_counter_lockfile(database): """Write a lock-file for "last_SYS_%(database)s" to the "counters" directory, thus ensuring that only one process will access the counter at any one time. If the lockfile doesn't already exist, it will be created in the counters directory with the name "last_SYS_%(database)s.lock" (e.g. "last_SYS_CER.lock".) If the lockfile does exist, the process will sleep for 1 second and then try again. In all, it will try 60 times to create a lockfile before giving up. When a lockfile is created, it will contain a string of the format "processPID->YYYYMMDDhhmmss->random int, between 1-1000000" (E.g. something like this: "856->20060705120533->324".) When the lockfile has been written, it will be re-read and the string inside of it compared with the string that was written. If they match, then it shall be assumed that this is the lockfile owned by this process. If they do not match, then it shall be assumed that at the time of lockfile creation, another process also created its own lockfile, and this one belongs to the other process. In such a case, this process will sleep for one second and then try again. @param database: (string) the name of the database whose counter file has been locked. This is used to determine the name of the lockfile. @return: (integer) an error flag - 0 (ZERO) or 1 (ONE). 0 means lockfile could not be created; 1 means that it was successfully created. """ seed() counter_lockfile = "last_SYS_%s.lock" % (database,) lockfile_text = """%s->%.7f->%d""" % (getpid(), time(), randint(0,1000000)) got_lock = 0 ## get lock on counter: for i in range(0, 60): if os.path.exists("%s/%s" % (counters, counter_lockfile)): ## lock file exists - sleep 1 second and try again sleep(1) continue else: ## lock file doesn't exist - make it try: fp = open("%s/%s" % (counters, counter_lockfile), "w") fp.write("%s" % (lockfile_text,)) fp.flush() fp.close() ## open and read the contents of the lock file back to ensure that it *really* belongs to this process: fp = open("%s/%s" % (counters, counter_lockfile), "r") read_lockfile_contents = fp.readline() fp.close() if read_lockfile_contents.strip() != lockfile_text: ## this is not our lockfile, or it has been corrupted ## probably another process has written its own lockfile in the mean time sleep(1) continue else: got_lock = 1 break except IOError: ## could not create - pass and go on to next iteration got_lock = 0 sleep(1) return got_lock def _unlink_SYS_counter_lockfile(database): """Remove the lockfile that was created for this session of SYS allocation. @param database: (string) the name of the database whose counter file has been locked. This is used to determine the name of the lockfile. @return: (integer) an error flag - 0 (ZERO) or 1 (ONE). 0 means lockfile could not be removed; 1 means that it was successfully removed. """ counter_lockfile = "last_SYS_%s.lock" % (database,) unlinked_lockfile = 0 try: unlink("%s/%s" % (counters, counter_lockfile)) unlinked_lockfile = 1 except OSError: ## unable to remove lockfile: pass return unlinked_lockfile diff --git a/modules/websubmit/lib/functions/Mail_Submitter.py b/modules/websubmit/lib/functions/Mail_Submitter.py index 60de3aa3e..b901b5b06 100644 --- a/modules/websubmit/lib/functions/Mail_Submitter.py +++ b/modules/websubmit/lib/functions/Mail_Submitter.py @@ -1,104 +1,104 @@ ## $Id$ ## This file is part of CDS Invenio. ## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN. ## ## CDS Invenio is free software; you can redistribute it and/or ## modify it under the terms of the GNU General Public License as ## published by the Free Software Foundation; either version 2 of the ## License, or (at your option) any later version. ## ## CDS Invenio is distributed in the hope that it will be useful, but ## WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ## General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with CDS Invenio; if not, write to the Free Software Foundation, Inc., ## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. ## ## Name: Mail_Submitter.py ## Description: function Mail_Submitter ## This function sends a confirmation email to the submitter ## of the document ## Author: T.Baron ## ## PARAMETERS: authorfile: name of the file containing the author ## titleFile: name of the file containing the title ## emailFile: name of the file containing the email ## status: one of "ADDED" (the document has been integrated ## into the database) or "APPROVAL" (an email has ## been sent to a referee - simple approval) ## edsrn: name of the file containing the reference ## newrnin: name of the file containing the 2nd reference ## (if any) ## OUTPUT: HTML ## -from invenio.websubmit_config import cfg_websubmit_copy_mails_to_admin +from invenio.websubmit_config import CFG_WEBSUBMIT_COPY_MAILS_TO_ADMIN execfile("%s/invenio/websubmit_functions/mail.py" % pylibdir) def Mail_Submitter (parameters,curdir,form): FROMADDR = '%s Submission Engine <%s>' % (cdsname,supportemail) # retrieve report number edsrn = parameters['edsrn'] newrnin = parameters['newrnin'] fp = open("%s/%s" % (curdir,edsrn),"r") rn = fp.read() fp.close() rn = re.sub("[\n\r]+","",rn) if newrnin != "" and os.path.exists("%s/%s" % (curdir,newrnin)): fp = open("%s/%s" % (curdir,newrnin),"r") additional_rn = read() fp.close() additional_rn = re.sub("[\n\r]+","",additional_rn) fullrn = "%s and %s" % (additional_rn,rn) else: fullrn = rn fullrn = fullrn.replace("\n"," ") # The title is read from the file specified by 'titlefile' try: fp = open("%s/%s" % (curdir,parameters['titleFile']),"r") m_title = fp.read().replace("\n"," ") fp.close() except: m_title = "-" # The name of the author is read from the file specified by 'authorfile' try: fp = open("%s/%s" % (curdir,parameters['authorfile']),"r") m_author = fp.read().replace("\n"," ") fp.close() except: m_author = "-" # The submitters email address is read from the file specified by 'emailFile' try: fp = open("%s/%s" % (curdir,parameters['emailFile']),"r") m_recipient = fp.read().replace ("\n"," ") fp.close() except: m_recipient = "" # create email body email_txt = "The document %s\nTitle: %s\nAuthor(s): %s\n\nhas been correctly received\n\n" % (fullrn,m_title,m_author) # The user is either informed that the document has been added to the database, or sent for approval if parameters['status'] == "APPROVAL": email_txt = email_txt + "An email has been sent to the referee. You will be warned by email as soon as the referee takes his/her decision regarding your document.\n\n" elif parameters['status'] == "ADDED": email_txt = email_txt + "It will be soon added to our Document Server.\n\nOnce inserted, you will be able to check the bibliographic information and the quality of the electronic documents at this URL:\n<%s/record/%s>\nIf you detect an error please let us know by sending an email to %s. \n\n" % (htdocsurl,sysno,supportemail) email_txt = email_txt + "Thank you for using %s Submission Interface.\n" % cdsname # send the mail tostring = m_recipient.strip() - if cfg_websubmit_copy_mails_to_admin: + if CFG_WEBSUBMIT_COPY_MAILS_TO_ADMIN: # Copy mail to admins: if len(tostring) > 0: tostring += ",%s" % (adminemail,) else: tostring = adminemail body = forge_email(FROMADDR,m_recipient,"","%s: Document Received" % fullrn,email_txt) tolist = tostring.split(",") if len(tolist[0]) > 0: send_email(FROMADDR,tolist,body,0) return "" diff --git a/modules/websubmit/lib/functions/Send_APP_Mail.py b/modules/websubmit/lib/functions/Send_APP_Mail.py index a0e081dda..d8aa35d23 100644 --- a/modules/websubmit/lib/functions/Send_APP_Mail.py +++ b/modules/websubmit/lib/functions/Send_APP_Mail.py @@ -1,121 +1,121 @@ ## $Id$ ## This file is part of CDS Invenio. ## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN. ## ## CDS Invenio is free software; you can redistribute it and/or ## modify it under the terms of the GNU General Public License as ## published by the Free Software Foundation; either version 2 of the ## License, or (at your option) any later version. ## ## CDS Invenio is distributed in the hope that it will be useful, but ## WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ## General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with CDS Invenio; if not, write to the Free Software Foundation, Inc., ## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. ## Description: function Send_APP_Mail ## This function send an email informing the original ## submitter of a document that the referee has approved/ ## rejected the document. The email is also sent to the ## referee for checking. ## Author: T.Baron ## PARAMETERS: ## newrnin: name of the file containing the 2nd reference ## addressesAPP: email addresses to which the email will ## be sent (additionally to the author) ## categformatAPP: variable needed to derive the addresses ## mentioned above from invenio.access_control_admin import acc_getRoleUsers,acc_getRoleId -from invenio.websubmit_config import cfg_websubmit_copy_mails_to_admin +from invenio.websubmit_config import CFG_WEBSUBMIT_COPY_MAILS_TO_ADMIN execfile("%s/invenio/websubmit_functions/mail.py" % pylibdir) def Send_APP_Mail (parameters,curdir,form): global emailvalue,titlevalue,authorvalue,sysno,rn FROMADDR = '%s Submission Engine <%s>' % (cdsname,supportemail) doctype = form['doctype'] emailvalue = emailvalue.replace("\n","") titlevalue = titlevalue.replace("\n","") authorvalue = authorvalue.replace("\n","") # variables declaration categformat = parameters['categformatAPP'] otheraddresses = parameters['addressesAPP'] newrnpath = parameters['newrnin'] # retrieve values stored into files if os.path.exists("%s/COM" % curdir): fp = open("%s/COM" % curdir, "r") comment = fp.read() fp.close() else: comment = "" if os.path.exists("%s/decision" % curdir): fp = open("%s/decision" % curdir,"r") decision = fp.read() fp.close() else: decision = "" if os.path.exists("%s/%s" % (curdir,newrnpath)): fp = open("%s/%s" % (curdir,newrnpath) , "r") newrn = fp.read() fp.close() else: newrn = "" # Document name res = run_sql("SELECT ldocname FROM sbmDOCTYPE WHERE sdocname=%s", (doctype,)) docname = res[0][0] # retrieve category categformat = categformat.replace("","([^-]*)") categs = re.match(categformat,rn) if categs != None: category = categs.group(1) else: category = "unknown" # Build referee's email address refereeaddress = "" # Try to retrieve the referee's email from the referee's database for user in acc_getRoleUsers(acc_getRoleId("referee_%s_%s" % (doctype,category))): refereeaddress += user[1] + "," # And if there is a general referee for user in acc_getRoleUsers(acc_getRoleId("referee_%s_*" % doctype)): refereeaddress += user[1] + "," refereeaddress = re.sub(",$","",refereeaddress) # Creation of the mail for the referee otheraddresses = otheraddresses.replace("",category) addresses = "" if refereeaddress != "": addresses = refereeaddress + "," if otheraddresses != "": addresses += otheraddresses else: addresses = re.sub(",$","",addresses) if decision == "approve": mailtitle = "%s has been approved" % rn mailbody = "The %s %s has been approved." % (docname,rn) mailbody += "\nIt will soon be accessible here:\n<%s/record/%s>" % (htdocsurl,sysno) else: mailtitle = "%s has been rejected" % rn mailbody = "The %s %s has been rejected." % (docname,rn) if rn != newrn and decision == "approve" and newrn != "": mailbody += "Its new reference number is: %s" % newrn mailbody += "\n\nTitle: %s\n\nAuthor(s): %s\n\n" % (titlevalue,authorvalue) if comment != "": mailbody += "Comments from the referee:\n%s\n" % comment mailbody += "---------------------------------------------\nBest regards.\nThe submission team.\n" #Send mail to referee tostring = addresses.strip() - if cfg_websubmit_copy_mails_to_admin: + if CFG_WEBSUBMIT_COPY_MAILS_TO_ADMIN: # Copy mail to admins: if len(tostring) > 0: tostring += ",%s" % (adminemail,) else: tostring = adminemail body = forge_email(FROMADDR,addresses,"",mailtitle,mailbody) tolist = re.split(",",tostring) if len(tolist[0]) > 0: send_email(FROMADDR,tolist,body,0) return "" diff --git a/modules/websubmit/lib/functions/Send_Approval_Request.py b/modules/websubmit/lib/functions/Send_Approval_Request.py index dca10c701..dc91d75a6 100644 --- a/modules/websubmit/lib/functions/Send_Approval_Request.py +++ b/modules/websubmit/lib/functions/Send_Approval_Request.py @@ -1,112 +1,112 @@ ## $Id$ ## This file is part of CDS Invenio. ## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN. ## ## CDS Invenio is free software; you can redistribute it and/or ## modify it under the terms of the GNU General Public License as ## published by the Free Software Foundation; either version 2 of the ## License, or (at your option) any later version. ## ## CDS Invenio is distributed in the hope that it will be useful, but ## WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ## General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with CDS Invenio; if not, write to the Free Software Foundation, Inc., ## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. ## Description: function Send_Approval_Request ## This function sends an email to the referee asking him/her ## to approve/reject a document ## Author: T.Baron ## PARAMETERS: directory: parameter to the link manager program ## addressesDAM: address of the referee(s) ## categformatDAM: variable needed to extract the category ## of the document and use it to derive the ## address. ## authorfile: name of the file containing the author list ## titleFile: name of the file containing the title from invenio.access_control_admin import acc_getRoleUsers,acc_getRoleId -from invenio.websubmit_config import cfg_websubmit_copy_mails_to_admin +from invenio.websubmit_config import CFG_WEBSUBMIT_COPY_MAILS_TO_ADMIN execfile("%s/invenio/websubmit_functions/mail.py" % pylibdir) def Send_Approval_Request (parameters,curdir,form): global rn,sysno # variables declaration doctype = re.search(".*/([^/]*)/([^/]*)/[^/]*$",curdir).group(2) FROMADDR = '%s Submission Engine <%s>' % (cdsname,supportemail) otheraddresses = parameters['addressesDAM'] categformat = parameters['categformatDAM'] # retrieve category categformat = categformat.replace("","([^-]*)") categs = re.match(categformat,rn) if categs != None: category = categs.group(1) else: category = "unknown" # create TI if os.path.exists("%s/date" % curdir): fp = open("%s/date" % curdir, "r") date = fp.read() fp.close() else: date = "" if os.path.exists("%s/%s" % (curdir,parameters['titleFile'])): fp = open("%s/%s" % (curdir,parameters['titleFile']),"r") title = fp.read() fp.close() title = title.replace("\n","") else: title = "" title += " - %s" % date # create AU if os.path.exists("%s/%s" % (curdir,parameters['authorfile'])): fp = open("%s/%s" % (curdir,parameters['authorfile']), "r") author = fp.read() fp.close() else: author = "" # we get the referee password sth = run_sql("SELECT access FROM sbmAPPROVAL WHERE rn=%s", (rn,)) if len(sth) >0: access = sth[0][0] # Build referee's email address refereeaddress = "" # Try to retrieve the referee's email from the referee's database for user in acc_getRoleUsers(acc_getRoleId("referee_%s_%s" % (doctype,category))): refereeaddress += user[1] + "," # And if there are general referees for user in acc_getRoleUsers(acc_getRoleId("referee_%s_*" % doctype)): refereeaddress += user[1] + "," refereeaddress = re.sub(",$","",refereeaddress) # Creation of the mail for the referee addresses = "" if refereeaddress != "": addresses = refereeaddress + "," if otheraddresses != "": addresses += otheraddresses else: addresses = re.sub(",$","",addresses) title_referee = "Request for approval of %s" % rn mail_referee = "The document %s has been submitted to the %s Server..\nYour approval is requested on it.\n\n" % (rn,cdsname) mail_referee +="Title: %s\n\nAuthor(s): %s\n\n" % (title,author) mail_referee +="To access the document(s), select the file(s) from the location:<%s/getfile.py?recid=%s>\n\n" % (htdocsurl,sysno) mail_referee +="To approve/reject the document, you should go to this URL:\n<%s/approve.py?%s>\n" % (urlpath,access) mail_referee +="---------------------------------------------\nBest regards.\nThe submission team.\n" #Send mail to referee tostring = addresses.strip() - if cfg_websubmit_copy_mails_to_admin: + if CFG_WEBSUBMIT_COPY_MAILS_TO_ADMIN: # Copy mail to admins: if len(tostring) > 0: tostring += ",%s" % (adminemail,) else: tostring = adminemail body = forge_email(FROMADDR,addresses,"",title_referee,mail_referee) tolist = re.split(",",tostring) if len(tolist[0]) > 0: send_email(FROMADDR,tolist,body,0) return "" diff --git a/modules/websubmit/lib/functions/Send_Modify_Mail.py b/modules/websubmit/lib/functions/Send_Modify_Mail.py index 7b2f547a3..1afd1da01 100644 --- a/modules/websubmit/lib/functions/Send_Modify_Mail.py +++ b/modules/websubmit/lib/functions/Send_Modify_Mail.py @@ -1,83 +1,83 @@ ## $Id$ ## This file is part of CDS Invenio. ## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN. ## ## CDS Invenio is free software; you can redistribute it and/or ## modify it under the terms of the GNU General Public License as ## published by the Free Software Foundation; either version 2 of the ## License, or (at your option) any later version. ## ## CDS Invenio is distributed in the hope that it will be useful, but ## WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ## General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with CDS Invenio; if not, write to the Free Software Foundation, Inc., ## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. ## Description: function Send_Modify_Mail ## This function sends an email saying the document has been ## correctly updated ## Author: T.Baron ## PARAMETERS: addressesMBI: email addresses to which the mail is sent ## fieldnameMBI: name of the file containing the modified ## fields ## sourceDoc: name of the type of document ## emailFile: name of the file containing the email of the ## user -from invenio.websubmit_config import cfg_websubmit_copy_mails_to_admin +from invenio.websubmit_config import CFG_WEBSUBMIT_COPY_MAILS_TO_ADMIN execfile("%s/invenio/websubmit_functions/mail.py" % pylibdir) def Send_Modify_Mail (parameters,curdir,form): FROMADDR = '%s Submission Engine <%s>' % (cdsname,supportemail) global sysno,rn if parameters['emailFile']!= None and parameters['emailFile']!= "" and os.path.exists("%s/%s" % (curdir,parameters['emailFile'])): fp = open("%s/%s" % (curdir,parameters['emailFile']),"r") sub = fp.read() fp.close() sub = sub.replace ("\n","") else: sub = "" # Copy mail to: addresses = parameters['addressesMBI'] addresses = addresses.strip() m_fields = parameters['fieldnameMBI'] type = parameters['sourceDoc'] rn = re.sub("[\n\r ]+","",rn) if os.path.exists("%s/%s" % (curdir,m_fields)): fp = open("%s/%s" % (curdir,m_fields),"r") fields = fp.read() fp.close() fields = fields.replace ("\n"," | ") fields = re.sub("[| \n\r]+$","",fields) else: fields = "" email_txt = "Dear Sir or Madam, \n%s %s has just been modified.\nModified fields: %s\n\n" % (type,rn,fields) if accessurl != "" and sysno != "": email_txt += "You can check the modified document here:\n" email_txt += "<%s?id=%s>\n\n" % (accessurl,sysno) email_txt += "Please note that the modifications will be taken into account in a couple of minutes.\n\nBest regards,\nThe %s Server support Team" % cdsname # send the mail tostring = sub.strip() if len(addresses) > 0: if len(tostring) > 0: tostring += ",%s" % (addresses,) else: tostring = addresses - if cfg_websubmit_copy_mails_to_admin: + if CFG_WEBSUBMIT_COPY_MAILS_TO_ADMIN: # Copy mail to admins: if len(tostring) > 0: tostring += ",%s" % (adminemail,) else: tostring = adminemail body = forge_email(FROMADDR,sub,"","%s modified" % rn,email_txt) tolist = tostring.split(",") if len(tolist[0]) > 0: send_email(FROMADDR,tolist,body,0) return "" diff --git a/modules/websubmit/lib/functions/Send_SRV_Mail.py b/modules/websubmit/lib/functions/Send_SRV_Mail.py index 76f5e956f..50074d640 100644 --- a/modules/websubmit/lib/functions/Send_SRV_Mail.py +++ b/modules/websubmit/lib/functions/Send_SRV_Mail.py @@ -1,80 +1,80 @@ ## $Id$ ## This file is part of CDS Invenio. ## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN. ## ## CDS Invenio is free software; you can redistribute it and/or ## modify it under the terms of the GNU General Public License as ## published by the Free Software Foundation; either version 2 of the ## License, or (at your option) any later version. ## ## CDS Invenio is distributed in the hope that it will be useful, but ## WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ## General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with CDS Invenio; if not, write to the Free Software Foundation, Inc., ## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. ## Description: function Send_SRV_Mail ## This function sends an email confirming the revision ## has been carried on with success ## Author: T.Baron ## PARAMETERS: addressesSRV: list of addresses to send this email to. ## categformatDAM: variable used to derive the category of ## the document from its reference. This value might then ## be used to derive the list of addresses ## emailFile: name of the file in which the user's email is ## noteFile: name of the file containing a note from the user -from invenio.websubmit_config import cfg_websubmit_copy_mails_to_admin +from invenio.websubmit_config import CFG_WEBSUBMIT_COPY_MAILS_TO_ADMIN execfile("%s/invenio/websubmit_functions/mail.py" % pylibdir) execfile("%s/invenio/websubmit_functions/Retrieve_Data.py" % pylibdir) def Send_SRV_Mail(parameters,curdir,form): global rn,doctype,sysno # variables declaration FROMADDR = '%s Submission Engine <%s>' % (cdsname,supportemail) addresses = parameters['addressesSRV'] addresses = addresses.strip() if parameters['emailFile']!=None and parameters['emailFile']!="" and os.path.exists("%s/%s" % (curdir,parameters['emailFile'])): fp = open("%s/%s" % (curdir,parameters['emailFile']), "r") SuE = fp.read() fp.close() else: SuE = "" SuE = SuE.replace("\n",",") if parameters['noteFile']!=None and parameters['noteFile']!= "" and os.path.exists("%s/%s" % (curdir,parameters['noteFile'])): fp = open("%s/%s" % (curdir,parameters['noteFile']), "r") note = fp.read() fp.close() else: note = "" title = Get_Field("245__a",sysno) author = Get_Field('100__a',sysno) author += Get_Field('700__a',sysno) # create message message = "A revised version of document %s has been submitted.\n\nTitle: %s\nAuthor(s): %s\nURL: <%s?id=%s>%s" % (rn,title,author,accessurl,sysno,note) # send the email tostring = SuE.strip() if len(addresses) > 0: if len(tostring) > 0: tostring += ",%s" % (addresses,) else: tostring = addresses - if cfg_websubmit_copy_mails_to_admin: + if CFG_WEBSUBMIT_COPY_MAILS_TO_ADMIN: # Copy mail to admins: if len(tostring) > 0: tostring += ",%s" % (adminemail,) else: tostring = adminemail body = forge_email(FROMADDR,SuE,"","%s revised" % rn,message) tolist = re.split(",",tostring) if len(tolist[0]) > 0: send_email(FROMADDR,tolist,body,0) return "" diff --git a/modules/websubmit/lib/websubmit_config.py b/modules/websubmit/lib/websubmit_config.py index 53682afc6..8d09eedd2 100644 --- a/modules/websubmit/lib/websubmit_config.py +++ b/modules/websubmit/lib/websubmit_config.py @@ -1,123 +1,98 @@ ## $Id$ ## ## This file is part of CDS Invenio. ## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN. ## ## CDS Invenio is free software; you can redistribute it and/or ## modify it under the terms of the GNU General Public License as ## published by the Free Software Foundation; either version 2 of the ## License, or (at your option) any later version. ## ## CDS Invenio is distributed in the hope that it will be useful, but ## WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ## General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with CDS Invenio; if not, write to the Free Software Foundation, Inc., ## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. """CDS Invenio Submission Web Interface config file.""" __revision__ = "$Id$" -## import config variables defined from config.wml: -from invenio.config import adminemail, \ - supportemail, \ - images, \ - urlpath, \ - accessurl, \ - counters, \ - storage, \ - filedir, \ - filedirsize, \ - gfile, \ - gzip, \ - tar, \ - gunzip, \ - acroread, \ - distiller, \ - convert, \ - tmpdir, \ - bibupload, \ - bibformat, \ - bibwords, \ - bibconvert, \ - bibconvertconf, \ - htdocsurl - ## test: test = "FALSE" ## CC all action confirmation mails to administrator? (0 == NO; 1 == YES) -cfg_websubmit_copy_mails_to_admin = 0 +CFG_WEBSUBMIT_COPY_MAILS_TO_ADMIN = 0 ## known compressed file extensions: -cfg_compressed_file_extensions = ["z", "gz", "tar", "tgz", "tar", +CFG_COMPRESSED_FILE_EXTENSIONS = ["z", "gz", "tar", "tgz", "tar", "tar.gz", "zip", "rar", "arj", "arc", "pak", "lha", "lhz", "sit", "sea", "sitx", "cpt", "hqx", "uu", "uue", "bz", "bz2", "bzip", "tbz", "tbz2", "tar.bz", "tar.bz2"] -cfg_known_file_extensions = ["lis", +CFG_KNOWN_FILE_EXTENSIONS = ["lis", "sxi", "zip", "kpr", "xls", "mov", "avi", "ppt", "prn", "pdf", "tif", "doc", "dot", "ps.gz", "ps.Z", "ps", "eps", "pps", "gif", "jpeg", "jpg", "JPG", "html", "htm", "Download.link", "link", "tex", "txt", "ef.tif", "e.tif", "f.tif", "ef.pdf", "e.pdf", "f.pdf", "ef.ps.gz", "e.ps.gz", "f.ps.gz", "ef.ps", "e.ps", "f.ps", "e.xls", "f.xls", "ef.doc", "e.doc", "f.doc", "ef.html", "e.html", "f.html", "hpg", "mpp", "h", "rtf", "tar", "tar.gz", "tgz", "msg", "llb", "ogg", "mp3", "wav", "mpg"] diff --git a/modules/websubmit/lib/websubmit_webinterface.py b/modules/websubmit/lib/websubmit_webinterface.py index f828569dc..da5eb3c1c 100644 --- a/modules/websubmit/lib/websubmit_webinterface.py +++ b/modules/websubmit/lib/websubmit_webinterface.py @@ -1,400 +1,400 @@ ## $Id$ ## ## This file is part of CDS Invenio. ## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN. ## ## CDS Invenio is free software; you can redistribute it and/or ## modify it under the terms of the GNU General Public License as ## published by the Free Software Foundation; either version 2 of the ## License, or (at your option) any later version. ## ## CDS Invenio is distributed in the hope that it will be useful, but ## WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ## General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with CDS Invenio; if not, write to the Free Software Foundation, Inc., ## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. import string import os import time import types import re from mod_python import apache import sys from urllib import quote from invenio.dbquery import run_sql, Error -from invenio.config import cdsname,cdslang,weburl +from invenio.config import * from invenio.access_control_engine import acc_authorize_action from invenio.access_control_admin import acc_isRole from invenio.webpage import page, create_error_box from invenio.webuser import getUid, get_email, page_not_authorized from invenio.websubmit_config import * from invenio.file import * from invenio.access_control_config import CFG_ACCESS_CONTROL_LEVEL_SITE from invenio.webinterface_handler import wash_urlargd, WebInterfaceDirectory from invenio.urlutils import make_canonical_urlargd, redirect_to_url from invenio.messages import gettext_set_language import invenio.template websubmit_templates = invenio.template.load('websubmit') class WebInterfaceFilesPages(WebInterfaceDirectory): def __init__(self,recid): self.recid = recid return def _lookup(self, component, path): # after /record//files/ every part is used as the file # name (with possible path in the case of archives to be # uncompressed) filename = component def getfile(req, form): args = wash_urlargd(form, websubmit_templates.files_default_urlargd) ln = args['ln'] _ = gettext_set_language(ln) uid = getUid(req) if uid == -1 or CFG_ACCESS_CONTROL_LEVEL_SITE > 1: return page_not_authorized(req, "../getfile.py/index") uid_email = get_email(uid) readonly = CFG_ACCESS_CONTROL_LEVEL_SITE == 1 # From now on: either the user provided a specific file # name (and a possible version), or we return a list of # all the available files. In no case are the docids # visible. bibarchive = BibRecDocs(self.recid) if filename: # We know the complete file name, guess which docid it # refers to ## TODO: Change the extension system according to ext.py from setlink ## and have a uniform extension mechanism... name = file_strip_ext(filename) format = filename[len(name):] if format and format[0] == '.': format = format[1:] # search this filename in the complete list of files for doc in bibarchive.listBibDocs(): if filename in [f.fullname for f in doc.listAllFiles()]: docfile=doc.getFile(name,format,args['version']) if docfile is None: return warningMsg(_("Unable to find file."), req, cdsname, ln) if docfile.isRestricted(): return warningMsg(_("This file is restricted!"), req, cdsname, ln) if not readonly: ip = str(req.get_remote_host(apache.REMOTE_NOLOOKUP)) res = doc.registerDownload(ip, version, format, uid) return docfile.stream(req) else: return warningMsg(_("Unable to find file."), req, cdsname, ln) filelist = bibarchive.display("", args['version'], ln=ln) t = websubmit_templates.tmpl_filelist( ln=ln, recid=self.recid, docid="", version=args['version'], filelist=filelist) return page(title="", body=t, navtrail=_("Access to Fulltext"), description="", keywords="keywords", uid=uid, language=ln, req=req) return getfile, [] def __call__(self, req, form): """Called in case of URLs like /record/123/files without trailing slash. """ return redirect_to_url(req, '%s/record/%s/files/' % (weburl, self.recid)) def websubmit_legacy_getfile(req, form): """ Handle legacy /getfile.py URLs """ # FIXME: this should _redirect_ to the proper # /record/.../files/... URL. args = wash_urlargd(form, { 'c': (str, cdsname), 'recid': (str, ''), 'docid': (str, ''), 'version': (str, ''), 'name': (str, ''), 'format': (str, '') }) def _getfile_py(req,c=cdsname,ln=cdslang,recid="",docid="",version="",name="",format=""): _ = gettext_set_language(ln) # get user ID: try: uid = getUid(req) if uid == -1 or CFG_ACCESS_CONTROL_LEVEL_SITE >= 1: return page_not_authorized(req, "../getfile.py/index") uid_email = get_email(uid) except Error, e: return errorMsg(e.value,req) filelist="" # redirect to a canonical URL as far as it is possible (what # if we only have a docid, and no file supplied?) if name!="": if docid=="": return errorMsg(_("Parameter docid missing"), req, c, ln) doc = BibDoc(bibdocid=docid) docfile=doc.getFile(name,format,version) if docfile == None: return warningMsg(_("Unable to find file."),req, c, ln) # redirect to this specific file, possibly dropping # the version if we are referring to the latest one. target = '%s/record/%d/files/%s.%s' % ( weburl, doc.recid, docfile.name, docfile.format) if version and int(version) == int(doc.getLatestVersion()): version = '' target += make_canonical_urlargd({ 'version': version}, websubmit_templates.files_default_urlargd) return redirect_to_url(req, target) # all files attached to a record elif recid!="": return redirect_to_url(req, '%s/record/%s/files/' % (weburl, recid)) # a precise filename elif docid!="": bibdoc = BibDoc(bibdocid=docid) recid = bibdoc.getRecid() filelist = bibdoc.display(version, ln=ln) t = websubmit_templates.tmpl_filelist( ln = ln, recid = recid, docid = docid, version = version, filelist = filelist, ) p_navtrail = _("Access to Fulltext") return page(title="", body=t, navtrail = p_navtrail, description="", keywords="keywords", uid=uid, language=ln, req=req) return _getfile_py(req, **args) # -------------------------------------------------- from invenio.websubmit_engine import home, action, interface, endaction class WebInterfaceSubmitPages(WebInterfaceDirectory): _exports = ['summary', 'sub', 'direct', ''] def direct(self, req, form): args = wash_urlargd(form, {'sub': (str, '')}) sub = args['sub'] uid = getUid(req) if uid == -1 or CFG_ACCESS_CONTROL_LEVEL_SITE >= 1: return page_not_authorized(req, "../direct.py/index") myQuery = req.args if sub == "": return errorMsg("Sorry parameter missing...",req) res = run_sql("select docname,actname from sbmIMPLEMENT where subname=%s", (sub,)) if len(res)==0: return errorMsg("Sorry. Cannot analyse parameter",req) else: # get document type doctype = res[0][0] # get action name action = res[0][1] # retrieve other parameter values params = re.sub("sub=[^&]*","",myQuery) # find existing access number result = re.search("access=([^&]*)",params) if result != None: access = result.group(1) params = re.sub("access=[^&]*","",params) else: # create 'unique' access number pid = os.getpid() now = time.time() access = "%i_%s" % (now,pid) # retrieve 'dir' value res = run_sql ("select dir from sbmACTION where sactname=%s",(action,)) dir = res[0][0] try: mainmenu = req.headers_in['Referer'] except: mainmenu = "" url = "/submit?doctype=%s&dir=%s&access=%s&act=%s&startPg=1%s&mainmenu=%s" % ( doctype,dir,access,action,params,quote(mainmenu)) req.err_headers_out.add("Location", url) raise apache.SERVER_RETURN, apache.HTTP_MOVED_PERMANENTLY return "" def sub(self, req, form): uid = getUid(req) if uid == -1 or CFG_ACCESS_CONTROL_LEVEL_SITE >= 1: return page_not_authorized(req, "../sub/") myQuery = req.args if myQuery: if re.search("@",myQuery): param = re.sub("@.*","",myQuery) IN = re.sub(".*@","",myQuery) else: IN = myQuery url = "%s/submit/direct?sub=%s&%s" % (urlpath,IN,param) req.err_headers_out.add("Location", url) raise apache.SERVER_RETURN, apache.HTTP_MOVED_PERMANENTLY return "" else: return "Illegal page access" def summary(self, req, form): args = wash_urlargd(form, { 'doctype': (str, ''), 'act': (str, ''), 'access': (str, ''), 'indir': (str, '')}) uid = getUid(req) if uid == -1 or CFG_ACCESS_CONTROL_LEVEL_SITE >= 1: return page_not_authorized(req, "../summary.py/index") t="" curdir = "%s/%s/%s/%s" % (storage,args['indir'],args['doctype'],args['access']) subname = "%s%s" % (args['act'], args['doctype']) res = run_sql("select sdesc,fidesc,pagenb,level from sbmFIELD where subname=%s " "order by pagenb,fieldnb", (subname,)) nbFields = 0 values = [] for arr in res: if arr[0] != "": val = { 'mandatory' : (arr[3] == 'M'), 'value' : '', 'page' : arr[2], 'name' : arr[0], } if os.path.exists("%s/%s" % (curdir,arr[1])): fd = open("%s/%s" % (curdir,arr[1]),"r") value = fd.read() fd.close() value = value.replace("\n"," ") value = value.replace("Select:","") else: value = "" val['value'] = value values.append(val) return websubmit_templates.tmpl_submit_summary( ln = args['ln'], values = values, images = images, ) def index(self, req, form): args = wash_urlargd(form, { 'c': (str, cdsname), 'doctype': (str, ''), 'act': (str, ''), 'startPg': (str, "1"), 'indir': (str, ''), 'access': (str, ''), 'mainmenu': (str, ''), 'fromdir': (str, ''), 'file': (str, ''), 'nextPg': (str, ''), 'nbPg': (str, ''), 'curpage': (str, '1'), 'step': (str, '0'), 'mode': (str, 'U'), }) req.form = form def _index(req, c, ln, doctype, act, startPg, indir, access, mainmenu, fromdir, file, nextPg, nbPg, curpage, step, mode): uid = getUid(req) if uid == -1 or CFG_ACCESS_CONTROL_LEVEL_SITE >= 1: return page_not_authorized(req, "../submit") if doctype=="": return home(req,c,ln) elif act=="": return action(req,c,ln,doctype) elif int(step)==0: return interface(req,c,ln, doctype, act, startPg, indir, access, mainmenu, fromdir, file, nextPg, nbPg, curpage) else: return endaction(req,c,ln, doctype, act, startPg, indir, access,mainmenu, fromdir, file, nextPg, nbPg, curpage, step, mode) return _index(req, **args) # Answer to both /submit/ and /submit __call__ = index def errorMsg(title,req,c=cdsname,ln=cdslang): _ = gettext_set_language(ln) return page(title=_("Error"), body = create_error_box(req, title=title,verbose=0, ln=ln), description=_("Internal Error"), keywords="CDS Invenio, Internal Error", language=ln, req=req) def warningMsg(title,req,c=cdsname,ln=cdslang): _ = gettext_set_language(ln) return page(title=_("Warning"), body = title, description=_("Internal Error"), keywords="CDS Invenio, Internal Error", language=ln, req=req) diff --git a/modules/websubmit/web/admin/referees.py b/modules/websubmit/web/admin/referees.py index 227965f7e..9d0695da0 100644 --- a/modules/websubmit/web/admin/referees.py +++ b/modules/websubmit/web/admin/referees.py @@ -1,219 +1,219 @@ ## $Id$ ## ## This file is part of CDS Invenio. ## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN. ## ## CDS Invenio is free software; you can redistribute it and/or ## modify it under the terms of the GNU General Public License as ## published by the Free Software Foundation; either version 2 of the ## License, or (at your option) any later version. ## ## CDS Invenio is distributed in the hope that it will be useful, but ## WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ## General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with CDS Invenio; if not, write to the Free Software Foundation, Inc., ## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. ## import interesting modules: import string import os import sys import time import types import re import shutil -from invenio.config import cdsname,cdslang,weburl +from invenio.config import * from invenio.dbquery import run_sql, Error from invenio.access_control_engine import acc_authorize_action from invenio.access_control_admin import * from invenio.webpage import page, create_error_box from invenio.webuser import getUid, get_email, list_registered_users from invenio.messages import wash_language from invenio.websubmit_config import * def index(req,c=cdsname,ln=cdslang,todo="",id="",doctype="",categ="",addusers="",warningText="",role=""): ln = wash_language(ln) # get user ID: try: uid = getUid(req) uid_email = get_email(uid) except Error, e: return errorMsg(e.value,req) (auth_code, auth_message) = acc_authorize_action(uid, "cfgwebsubmit",verbose=0) if auth_code != 0: return errorMsg(auth_message, req, uid) # request for deleting a user if todo == "deleteuser": acc_deleteUserRole(id,name_role=role) # request for adding user(s) if todo == "adduser": role = "referee_%s_%s" % (doctype,categ[1]) roleId = acc_getRoleId(role) # if the role does not exists, we create it if roleId == 0: if acc_addRole(role,"referees for document type %s category %s" % (doctype,categ[1])) == 0: return errorMsg("Cannot create referee role",req) else: roleId = acc_getRoleId(role) # if the action does not exist, we create it actionId = acc_getActionId("referee") if actionId == 0: if acc_addAction("referee","","no",("doctype","categ")) == 0: return errorMsg("Cannot create action 'referee'",req) else: actionId = acc_getActionId("referee") #create arguments arg1Id = acc_addArgument("doctype",doctype) arg2Id = acc_addArgument("categ",categ[1]) # then link the role with the action if acc_addRoleActionArguments(roleId,actionId,-1,0,0,[arg1Id,arg2Id]) == 0: return errorMsg("Cannot link role with action",req) roleId = acc_getRoleId(role) # For each id in the array if isinstance(addusers,types.ListType): for adduser in addusers: # First check whether this id is not already associated with this rule myRoles = acc_getUserRoles(adduser) if not roleId in myRoles: # Actually add the role to the user acc_addUserRole(adduser,roleId) else: warningText = "Sorry... This user is already a referee for this category." else: # First check whether this id is not already associated with this rule myRoles = acc_getUserRoles(addusers) if not roleId in myRoles: # Actually add the role to the user acc_addUserRole(addusers,roleId) else: warningText = "Sorry... This user is already a referee for this category." return page(title="websubmit admin - referee selection", body=displayRefereesPage(doctype,warningText), description="", keywords="", uid=uid, language=ln, req=req) def displayRefereesPage(doctype,warningText): t="" if doctype == "*": docname = "all catalogues" else: res = run_sql("SELECT * FROM sbmDOCTYPE WHERE sdocname=%s", (doctype,)) docname = res[0][0] t+=warningText t+="""
""" %doctype # call the function to display the table containing the list of associated emails t+=displayUserTable(doctype) t+=""" """ # call the function to display the form allowing the manager to add new users t+=displayAddUser(doctype) t+= """
Finished
""" % (weburl, doctype) return t def displayUserTable(doctype): t="" # start displaying the table which will contain the list of email addresses. t+= """ """ roles = acc_getAllRoles() referees = {} for role in roles: role_name = role[1] role_id = role[0] if re.match("^referee_%s_" % doctype,role_name): # Try to retrieve the referee's email from the referee's database if acc_getRoleUsers(role_id) != None: referees[role_name] = acc_getRoleUsers(role_id) if len(referees) == 0: t+= "" % images i=0 for role in referees.keys(): categ = re.match("referee_%s_(.*)" % doctype,role).group(1) res = run_sql("SELECT lname FROM sbmCATEGORIES WHERE sname=%s and doctype=%s", (categ,doctype,)) if len(res) > 0: categname = "Referee(s) for category: %s" % res[0][0] else: categname = "General Referee(s)" t+= "" % categname for referee in referees[role]: if int(i/2) == i/2: bgcolor="#eeeeee" else: bgcolor="#dddddd" t+= "" % bgcolor t+= "" t+= ""; t+= ""; i+=1 # close table t+="" return t def displayAddUser(doctype): t="" # start displaying the table which will contain the add form t+= """ " return t def errorMsg(title,req,uid,c=cdsname,ln=cdslang): return page(title="error", body = create_error_box(req, title=title,verbose=0, ln=ln), description="%s - Internal Error" % c, keywords="%s, CDS Invenio, Internal Error" % c, language=ln, uid=uid, req=req) diff --git a/modules/websubmit/web/approve.py b/modules/websubmit/web/approve.py index c7412e391..a678bbbd0 100644 --- a/modules/websubmit/web/approve.py +++ b/modules/websubmit/web/approve.py @@ -1,73 +1,73 @@ ## $Id$ ## ## This file is part of CDS Invenio. ## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN. ## ## CDS Invenio is free software; you can redistribute it and/or ## modify it under the terms of the GNU General Public License as ## published by the Free Software Foundation; either version 2 of the ## License, or (at your option) any later version. ## ## CDS Invenio is distributed in the hope that it will be useful, but ## WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ## General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with CDS Invenio; if not, write to the Free Software Foundation, Inc., ## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. ## import interesting modules: import string import os import sys import time import types import re from mod_python import apache -from invenio.config import cdsname,cdslang +from invenio.config import * from invenio.dbquery import run_sql from invenio.access_control_engine import acc_authorize_action from invenio.access_control_admin import acc_isRole from invenio.websubmit_config import * from invenio.webpage import page, create_error_box from invenio.webuser import getUid, get_email, page_not_authorized from invenio.messages import wash_language from invenio.access_control_config import CFG_ACCESS_CONTROL_LEVEL_SITE def index(req,c=cdsname,ln=cdslang): uid = getUid(req) if uid == -1 or CFG_ACCESS_CONTROL_LEVEL_SITE >= 1: return page_not_authorized(req, "../approve.py/index") ln = wash_language(ln) form = req.form if form.keys(): access = form.keys()[0] if access == "": return errorMsg("approve.py: cannot determine document reference",req) res = run_sql("select doctype,rn from sbmAPPROVAL where access=%s",(access,)) if len(res) == 0: return errorMsg("approve.py: cannot find document in database",req) else: doctype = res[0][0] rn = res[0][1] res = run_sql("select value from sbmPARAMETERS where name='edsrn' and doctype=%s",(doctype,)) edsrn = res[0][0] url = "%s/submit/sub?%s=%s&password=%s@APP%s" % (urlpath,edsrn,rn,access,doctype) req.err_headers_out.add("Location", url) raise apache.SERVER_RETURN, apache.HTTP_MOVED_PERMANENTLY return "" else: return errorMsg("Sorry parameter missing...", req, c, ln) def errorMsg(title,req,c=cdsname,ln=cdslang): return page(title="error", body = create_error_box(req, title=title,verbose=0, ln=ln), description="%s - Internal Error" % c, keywords="%s, CDS Invenio, Internal Error" % c, language=ln, req=req) diff --git a/modules/websubmit/web/publiline.py b/modules/websubmit/web/publiline.py index 06fc66073..194d582cb 100644 --- a/modules/websubmit/web/publiline.py +++ b/modules/websubmit/web/publiline.py @@ -1,364 +1,364 @@ ## $Id$ ## This file is part of CDS Invenio. ## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN. ## ## CDS Invenio is free software; you can redistribute it and/or ## modify it under the terms of the GNU General Public License as ## published by the Free Software Foundation; either version 2 of the ## License, or (at your option) any later version. ## ## CDS Invenio is distributed in the hope that it will be useful, but ## WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ## General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with CDS Invenio; if not, write to the Free Software Foundation, Inc., ## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. ## import interesting modules: import string import os import sys import time import types import re import shutil -from invenio.config import cdsname,cdslang,supportemail,pylibdir, sweburl +from invenio.config import * from invenio.dbquery import run_sql, Error from invenio.access_control_engine import acc_authorize_action from invenio.access_control_admin import * from invenio.webpage import page, create_error_box from invenio.webuser import getUid, get_email, list_registered_users, page_not_authorized from invenio.messages import gettext_set_language, wash_language from invenio.websubmit_config import * from invenio.search_engine import search_pattern from invenio.access_control_config import CFG_ACCESS_CONTROL_LEVEL_SITE execfile("%s/invenio/websubmit_functions/Retrieve_Data.py" % pylibdir) execfile("%s/invenio/websubmit_functions/mail.py" % pylibdir) import invenio.template websubmit_templates = invenio.template.load('websubmit') def index(req,c=cdsname,ln=cdslang,doctype="",categ="",RN="",send=""): global uid ln = wash_language(ln) # load the right message language _ = gettext_set_language(ln) t="" # get user ID: try: uid = getUid(req) if uid == -1 or CFG_ACCESS_CONTROL_LEVEL_SITE >= 1: return page_not_authorized(req, "../publiline.py/index") uid_email = get_email(uid) except Error, e: return errorMsg(e.value,req, ln = ln) if doctype == "": t = selectDoctype(ln) elif categ == "": t = selectCateg(doctype, ln) elif RN == "": t = selectDocument(doctype,categ, ln) else: t = displayDocument(doctype,categ,RN,send, ln) return page(title="publication line", navtrail= """%(account)s""" % { 'sweburl' : sweburl, 'account' : _("Your Account"), }, body=t, description="", keywords="", uid=uid, language=ln, req=req) def selectDoctype(ln = cdslang): res = run_sql("select DISTINCT doctype from sbmAPPROVAL") docs = [] for row in res: res2 = run_sql("select ldocname from sbmDOCTYPE where sdocname=%s", (row[0],)) docs.append({ 'doctype' : row[0], 'docname' : res2[0][0], }) t = websubmit_templates.tmpl_publiline_selectdoctype( ln = ln, docs = docs, ) return t def selectCateg(doctype, ln = cdslang): t="" res = run_sql("select ldocname from sbmDOCTYPE where sdocname=%s",(doctype,)) title = res[0][0] sth = run_sql("select * from sbmCATEGORIES where doctype=%s order by lname",(doctype,)) if len(sth) == 0: categ = "unknown" return selectDocument(doctype,categ, ln = ln) categories = [] for arr in sth: waiting = 0 rejected = 0 approved = 0 sth2 = run_sql("select COUNT(*) from sbmAPPROVAL where doctype=%s and categ=%s and status='waiting'", (doctype,arr[1],)) waiting = sth2[0][0] sth2 = run_sql("select COUNT(*) from sbmAPPROVAL where doctype=%s and categ=%s and status='approved'",(doctype,arr[1],)) approved = sth2[0][0] sth2 = run_sql("select COUNT(*) from sbmAPPROVAL where doctype=%s and categ=%s and status='rejected'",(doctype,arr[1],)) rejected = sth2[0][0] categories.append({ 'waiting' : waiting, 'approved' : approved, 'rejected' : rejected, 'id' : arr[1], }) t = websubmit_templates.tmpl_publiline_selectcateg( ln = ln, categories = categories, doctype = doctype, title = title, images = images, ) return t def selectDocument(doctype,categ, ln = cdslang): t="" res = run_sql("select ldocname from sbmDOCTYPE where sdocname=%s", (doctype,)) title = res[0][0] if categ == "": categ == "unknown" docs = [] sth = run_sql("select rn,status from sbmAPPROVAL where doctype=%s and categ=%s order by status DESC,rn DESC",(doctype,categ)) for arr in sth: docs.append({ 'RN' : arr[0], 'status' : arr[1], }) t = websubmit_templates.tmpl_publiline_selectdocument( ln = ln, doctype = doctype, title = title, categ = categ, images = images, docs = docs, ) return t def displayDocument(doctype,categ,RN,send, ln = cdslang): # load the right message language _ = gettext_set_language(ln) t="" res = run_sql("select ldocname from sbmDOCTYPE where sdocname=%s", (doctype,)) docname = res[0][0] if categ == "": categ = "unknown" sth = run_sql("select rn,status,dFirstReq,dLastReq,dAction,access from sbmAPPROVAL where rn=%s",(RN,)) if len(sth) > 0: arr = sth[0] rn = arr[0] status = arr[1] dFirstReq = arr[2] dLastReq = arr[3] dAction = arr[4] access = arr[5] else: return _("Approval has never been requested for this document.") + "
 " try: (authors,title,sysno,newrn) = getInfo(doctype,categ,RN) except TypeError: return _("Unable to display document.") confirm_send = 0 if send == _("Send Again"): if authors == "unknown" or title == "unknown": SendWarning(doctype,categ,RN,title,authors,access, ln = ln) else: # @todo - send in different languages SendEnglish(doctype,categ,RN,title,authors,access,sysno) run_sql("update sbmAPPROVAL set dLastReq=NOW() where rn=%s",(RN,)) confirm_send = 1 if status == "waiting": (auth_code, auth_message) = acc_authorize_action(uid, "referee",verbose=0,doctype=doctype, categ=categ) else: (auth_code, auth_message) = (None, None) t = websubmit_templates.tmpl_publiline_displaydoc( ln = ln, docname = docname, doctype = doctype, categ = categ, rn = rn, status = status, dFirstReq = dFirstReq, dLastReq = dLastReq, dAction = dAction, access = access, images = images, accessurl = accessurl, confirm_send = confirm_send, auth_code = auth_code, auth_message = auth_message, authors = authors, title = title, sysno = sysno, newrn = newrn, ) return t # Retrieve info about document def getInfo(doctype,categ,RN): result = getInPending(doctype,categ,RN) if not result: result = getInAlice(doctype,categ,RN) return result #seek info in pending directory def getInPending(doctype,categ,RN): PENDIR="%s/pending" % storage if os.path.exists("%s/%s/%s/AU" % (PENDIR,doctype,RN)): fp = open("%s/%s/%s/AU" % (PENDIR,doctype,RN),"r") authors=fp.read() fp.close() else: authors = "" if os.path.exists("%s/%s/%s/TI" % (PENDIR,doctype,RN)): fp = open("%s/%s/%s/TI" % (PENDIR,doctype,RN),"r") title=fp.read() fp.close() else: title = "" if os.path.exists("%s/%s/%s/SN" % (PENDIR,doctype,RN)): fp = open("%s/%s/%s/SN" % (PENDIR,doctype,RN),"r") sysno=fp.read() fp.close() else: sysno = "" if title == "" and os.path.exists("%s/%s/%s/TIF" % (PENDIR,doctype,RN)): fp = open("%s/%s/%s/TIF" % (PENDIR,doctype,RN),"r") title=fp.read() fp.close() if title == "": return 0 else: return (authors,title,sysno,"") #seek info in Alice database def getInAlice(doctype,categ,RN): # initialize sysno variable sysno = "" searchresults = search_pattern(req=None, p=RN, f="reportnumber").items().tolist() if len(searchresults) == 0: return 0 sysno = searchresults[0] if sysno != "": title = Get_Field('245__a',sysno) emailvalue = Get_Field('8560_f',sysno) authors = Get_Field('100__a',sysno) authors += "\n%s" % Get_Field('700__a',sysno) newrn = Get_Field('037__a',sysno) return (authors,title,sysno,newrn) else: return 0 def SendEnglish(doctype,categ,RN,title,authors,access,sysno): FROMADDR = '%s Submission Engine <%s>' % (cdsname,supportemail) # retrieve useful information from webSubmit configuration res = run_sql("select value from sbmPARAMETERS where name='categformatDAM' and doctype=%s", (doctype,)) categformat = res[0][0] categformat = re.sub("","([^-]*)",categformat) categs = re.match(categformat,RN) if categs != None: categ = categs.group(1) else: categ = "unknown" res = run_sql("select value from sbmPARAMETERS where name='addressesDAM' and doctype=%s",(doctype,)) if len(res) > 0: otheraddresses = res[0][0] otheraddresses = otheraddresses.replace("",categ) else: otheraddresses = "" # Build referee's email address refereeaddress = "" # Try to retrieve the referee's email from the referee's database for user in acc_getRoleUsers(acc_getRoleId("referee_%s_%s" % (doctype,categ))): refereeaddress += user[1] + "," # And if there are general referees for user in acc_getRoleUsers(acc_getRoleId("referee_%s_*" % doctype)): refereeaddress += user[1] + "," refereeaddress = re.sub(",$","",refereeaddress) # Creation of the mail for the referee addresses = "" if refereeaddress != "": addresses = refereeaddress + "," if otheraddresses != "": addresses += otheraddresses else: addresses = re.sub(",$","",addresses) if addresses=="": SendWarning(doctype,categ,RN,title,authors,access) return 0 if authors == "": authors = "-" res = run_sql("select value from sbmPARAMETERS where name='directory' and doctype=%s", (doctype,)) directory = res[0][0] message = """ The document %s has been published as a Communication. Your approval is requested for it to become an official Note. Title: %s Author(s): %s To access the document(s), select the file(s) from the location: <%s/getfile.py?recid=%s> To approve/reject the document, you should go to this URL: <%s/approve.py?%s> --------------------------------------------- Best regards. The submission team.""" % (RN,title,authors,urlpath,sysno,urlpath,access) # send the mail body = forge_email(FROMADDR,addresses,adminemail,"Request for Approval of %s" % RN,message) send_email(FROMADDR,addresses,body,0) return "" def SendWarning(doctype,categ,RN,title,authors,access): FROMADDR = '%s Submission Engine <%s>' % (cdsname,supportemail) message = "Failed sending approval email request for %s" % RN # send the mail body = forge_email(FROMADDR,adminemail,"","Failed sending approval email request",message) send_email(FROMADDR,adminemail,body,0) return "" def errorMsg(title,req,c=cdsname,ln=cdslang): return page(title="error", body = create_error_box(req, title=title,verbose=0, ln=ln), description="%s - Internal Error" % c, keywords="%s, CDS Invenio, Internal Error" % c, language=ln, req=req) def warningMsg(title,req,c=cdsname,ln=cdslang): return page(title="warning", body = title, description="%s - Internal Error" % c, keywords="%s, CDS Invenio, Internal Error" % c, language=ln, req=req) diff --git a/modules/websubmit/web/yourapprovals.py b/modules/websubmit/web/yourapprovals.py index f05428415..24c587c73 100644 --- a/modules/websubmit/web/yourapprovals.py +++ b/modules/websubmit/web/yourapprovals.py @@ -1,113 +1,113 @@ ## $Id$ ## This file is part of CDS Invenio. ## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN. ## ## CDS Invenio is free software; you can redistribute it and/or ## modify it under the terms of the GNU General Public License as ## published by the Free Software Foundation; either version 2 of the ## License, or (at your option) any later version. ## ## CDS Invenio is distributed in the hope that it will be useful, but ## WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ## General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with CDS Invenio; if not, write to the Free Software Foundation, Inc., ## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. ## import interesting modules: import os import sys -from invenio.config import weburl, sweburl, cdsname, cdslang +from invenio.config import * from invenio.dbquery import run_sql, Error from invenio.access_control_engine import acc_authorize_action from invenio.access_control_admin import * from invenio.webpage import page, create_error_box from invenio.webuser import getUid, get_email, list_registered_users, page_not_authorized from invenio.messages import gettext_set_language, wash_language from invenio.websubmit_config import * from invenio.search_engine import search_pattern from invenio.access_control_config import CFG_ACCESS_CONTROL_LEVEL_SITE import invenio.template websubmit_templates = invenio.template.load('websubmit') def index(req,c=cdsname,ln=cdslang,order="",doctype="",deletedId="",deletedAction="",deletedDoctype=""): global uid ln = wash_language(ln) # load the right message language _ = gettext_set_language(ln) t="" # get user ID: try: uid = getUid(req) if uid == -1 or CFG_ACCESS_CONTROL_LEVEL_SITE >= 1: return page_not_authorized(req, "../yourapprovals.py/index") u_email = get_email(uid) except Error, e: return errorMsg(e.value,req, ln = ln) res = run_sql("select sdocname,ldocname from sbmDOCTYPE") referees = [] for row in res: doctype = row[0] docname = row[1] reftext = "" if isReferee(uid,doctype,"*"): referees.append ({'doctype': doctype, 'docname': docname, 'categories': None}) else: res2 = run_sql("select sname,lname from sbmCATEGORIES where doctype=%s",(doctype,)) categories = [] for row2 in res2: category = row2[0] categname = row2[1] if isReferee(uid,doctype,category): categories.append({ 'id' : category, 'name' : categname, }) referees.append({ 'doctype' : doctype, 'docname' : docname, 'categories' : categories }) t = websubmit_templates.tmpl_yourapprovals( ln = ln, referees = referees ) return page(title=_("Your Approvals"), navtrail= """%(account)s""" % { 'sweburl' : sweburl, 'account' : _("Your Account"), }, body=t, description="", keywords="", uid=uid, language=ln, req=req) def isReferee(uid,doctype="",categ=""): (auth_code, auth_message) = acc_authorize_action(uid, "referee",verbose=0,doctype=doctype, categ=categ) if auth_code == 0: return 1 else: return 0 def errorMsg(title,req,c=cdsname,ln=cdslang): return page(title="error", body = create_error_box(req, title=title,verbose=0, ln=ln), description="%s - Internal Error" % c, keywords="%s, CDS Invenio, Internal Error" % c, language=ln, req=req) diff --git a/modules/websubmit/web/yoursubmissions.py b/modules/websubmit/web/yoursubmissions.py index 6411f16c3..491804c19 100644 --- a/modules/websubmit/web/yoursubmissions.py +++ b/modules/websubmit/web/yoursubmissions.py @@ -1,203 +1,203 @@ ## $Id$ ## This file is part of CDS Invenio. ## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN. ## ## CDS Invenio is free software; you can redistribute it and/or ## modify it under the terms of the GNU General Public License as ## published by the Free Software Foundation; either version 2 of the ## License, or (at your option) any later version. ## ## CDS Invenio is distributed in the hope that it will be useful, but ## WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ## General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with CDS Invenio; if not, write to the Free Software Foundation, Inc., ## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. ## import interesting modules: import string import os import sys import time import types import re import shutil import operator -from invenio.config import weburl, sweburl, cdsname, cdslang +from invenio.config import * from invenio.dbquery import run_sql, Error from invenio.access_control_engine import acc_authorize_action from invenio.access_control_admin import * from invenio.webpage import page, create_error_box from invenio.webuser import getUid, get_email, list_registered_users, page_not_authorized from invenio.messages import gettext_set_language, wash_language from invenio.websubmit_config import * from invenio.search_engine import search_pattern from invenio.access_control_config import CFG_ACCESS_CONTROL_LEVEL_SITE import invenio.template websubmit_templates = invenio.template.load('websubmit') def index(req,c=cdsname,ln=cdslang,order="",doctype="",deletedId="",deletedAction="",deletedDoctype=""): global uid ln = wash_language(ln) # load the right message language _ = gettext_set_language(ln) t="" # get user ID: try: uid = getUid(req) if uid == -1 or CFG_ACCESS_CONTROL_LEVEL_SITE >= 1: return page_not_authorized(req, "../yoursubmissions.py/index") u_email = get_email(uid) except Error, e: return errorMsg(e.value, req, ln) if u_email == "guest" or u_email == "": return warningMsg(websubmit_templates.tmpl_warning_message( ln = ln, msg = _("Sorry, you must log in to perform this action."), ),req, ln = ln) if deletedId != "": t += deleteSubmission(deletedId,deletedAction,deletedDoctype,u_email) # doctypes res = run_sql("select ldocname,sdocname from sbmDOCTYPE order by ldocname") doctypes = [] for row in res: doctypes.append({ 'id' : row[1], 'name' : row[0], 'selected' : (doctype == row[1]), }) # submissions # request order default value reqorder = "sbmSUBMISSIONS.md DESC, lactname" # requested value if order == "actiondown": reqorder = "lactname ASC, sbmSUBMISSIONS.md DESC" elif order == "actionup": reqorder = "lactname DESC, sbmSUBMISSIONS.md DESC" elif order == "refdown": reqorder = "reference ASC, sbmSUBMISSIONS.md DESC, lactname DESC" elif order == "refup": reqorder = "reference DESC, sbmSUBMISSIONS.md DESC, lactname DESC" elif order == "cddown": reqorder = "sbmSUBMISSIONS.cd DESC, lactname" elif order == "cdup": reqorder = "sbmSUBMISSIONS.cd ASC, lactname" elif order == "mddown": reqorder = "sbmSUBMISSIONS.md DESC, lactname" elif order == "mdup": reqorder = "sbmSUBMISSIONS.md ASC, lactname" elif order == "statusdown": reqorder = "sbmSUBMISSIONS.status DESC, lactname" elif order == "statusup": reqorder = "sbmSUBMISSIONS.status ASC, lactname" if doctype != "": docselect = " and doctype='%s' " % doctype else: docselect = "" res = run_sql("SELECT sbmSUBMISSIONS.* FROM sbmSUBMISSIONS,sbmACTION WHERE sactname=action and email=%s and id!='' "+docselect+" ORDER BY doctype,"+reqorder,(u_email,)) currentdoctype = "" currentaction = "" currentstatus = "" submissions = [] for row in res: if currentdoctype != row[1]: currentdoctype = row[1] currentaction = "" currentstatus = "" res2 = run_sql("SELECT ldocname FROM sbmDOCTYPE WHERE sdocname=%s",(currentdoctype,)) if res2: ldocname = res2[0][0] else: ldocname = """***Unknown Document Type - (%s)""" % (currentdoctype,) if currentaction != row[2]: currentaction = row[2] res2 = run_sql("SELECT lactname FROM sbmACTION WHERE sactname=%s",(currentaction,)) if res2: lactname = res2[0][0] else: lactname = "\"" else: lactname = "\"" if currentstatus != row[3]: currentstatus = row[3] status=row[3] else: status = "\"" submissions.append({ 'docname' : ldocname, 'actname' : lactname, 'status' : status, 'cdate' : row[6], 'mdate' : row[7], 'reference' : row[5], 'id' : row[4], 'act' : currentaction, 'doctype' : currentdoctype, 'pending' : (row[3] == "pending") }) # display t += websubmit_templates.tmpl_yoursubmissions( ln = ln, weburl = weburl, images = images, order = order, doctypes = doctypes, submissions = submissions, ) return page(title=_("Your Submissions"), navtrail= """%(account)s""" % { 'sweburl' : sweburl, 'account' : _("Your Account"), }, body=t, description="", keywords="", uid=uid, language=ln, req=req) def deleteSubmission(id, action, doctype, u_email): global storage run_sql("delete from sbmSUBMISSIONS WHERE doctype=%s and action=%s and email=%s and status='pending' and id=%s",(doctype,action,u_email,id,)) res = run_sql("select dir from sbmACTION where sactname=%s",(action,)) dir = res[0][0] if not ('..' in doctype or '..' in id) and id != "": full = os.path.join(storage, dir, doctype, id) if os.path.isdir(full): shutil.rmtree(full) return "" def warningMsg(title,req,c=cdsname,ln=cdslang): return page(title="warning", body = title, description="%s - Internal Error" % c, keywords="%s, CDS Invenio, Internal Error" % c, language=ln, req=req) def errorMsg(title,req,c=cdsname,ln=cdslang): return page(title="error", body = create_error_box(req, title=title,verbose=0, ln=ln), description="%s - Internal Error" % c, keywords="%s, CDS Invenio, Internal Error" % c, language=ln, req=req)