File:  [Repository] / VSyncer / BaseSyncer.py
Revision 1.1: download - view: text, annotated - select for diffs - revision graph
Wed Jan 2 19:01:35 2008 UTC (16 years, 6 months ago) by casties
Branches: MAIN
CVS tags: HEAD
first checking of modified SourceSyncer

    1: from OFS import SimpleItem
    2: from Globals import Persistent, data_dir, MessageDialog
    3: from AccessControl import getSecurityManager, Role
    4: import Acquisition, base64, time
    5: from Config import *
    6: from SysConfig import *
    7: from DocumentTemplate.DT_Var import url_quote_plus
    8: from StringIO import StringIO
    9: import string, os
   10: from os.path import exists
   11: from Products.PageTemplates.PageTemplateFile import PageTemplateFile
   12: 
   13: # do xml
   14: import xmlrpclibBasicAuth
   15: 
   16: 
   17: class BaseSyncer(SimpleItem.Item, Persistent, Acquisition.Implicit, Role.RoleManager):
   18:     """This class contains Basic methods, even These methods will be common if we implements Module Syncer"""
   19:     manage_options = (
   20:         {'label': 'Sync', 'action': 'manage_vsync' },
   21:         {'label': 'Edit Server', 'action': 'manage_edit' },
   22:         {'label': 'View Log', 'action': 'manage_viewlog' },
   23:     )
   24:     
   25:     __ac_permissions__= (
   26:         ('View management screens', (
   27:         'manage_tabs','manage_main','manage_edit','is_diffable', 'manage_approvedAction', 'manage_addXMLRPC',
   28:         'manage_listObjects', 'manage_exportXMLRPC', 'manage_deleteXMLRPC', 'manage_diffObject',
   29:         'manage_compare', 'manage_srcXMLRPC', 'status_colour', 'manage_folders', 'manage_vsync') ),
   30:         ('Change permissions', ('manage_access',) ),
   31:     )
   32: 
   33:     targetServer=dest_syncer
   34:     allowed_objs_sync = allowed_objs_sync
   35:     manage_viewlog = PageTemplateFile('zpt/VViewLog', globals())
   36:     
   37: 
   38:     def __init__(self, id, title=''):
   39:         """initialize a new instance of Server"""
   40:         self.id = id
   41:         self.title = title
   42:         self.source_server = [ None, ] # source is this Syncer
   43:         self.dest_server = ''
   44:         self.log = 0
   45:         self.approval = 1
   46:         self.syncable = syncable
   47:         self.filtered_objects = []
   48:         self.logfile = os.path.join(data_dir, 'VSourceSyncer.log')
   49: 
   50:     def manage_editServer(self, title='', dest=None, log=0, approval=0, logfile='', REQUEST=None, syncable=syncable, filterObjects=0, allowed_objs=[] ):
   51:         "edit server"
   52:         auth_user = getSecurityManager().getUser().getId()
   53:         if auth_user not in managers_list:
   54:             return MessageDialog(title='Addess Denied', message='You are not allowed to edit SourceSyncer', action='manage_vsync')
   55:         
   56:         self.title = title
   57:         self.log = log
   58:         self.logfile = logfile
   59:         self.approval = approval
   60:         self.syncable = syncable
   61:         self.dest_server = string.strip(dest)
   62:         self.filterObjects = filterObjects
   63:         self.filtered_objects = allowed_objs
   64:         if REQUEST is not None:
   65:             return MessageDialog(title = 'Edited', message = "Properties changed.", action = 'manage_edit')
   66:             
   67:     #################### for displaying the log info ##########################
   68:     def manage_getLog(self, filter=None):
   69:         """Return the log file details as a list """
   70:         log_list=[]
   71:         if not exists(self.logfile):
   72:                 return 'file not found. Please enable log option from edit server tab'
   73: 
   74:         # Cool. File found. Open. if we have permission.
   75:         try:
   76:             fp = open(self.logfile, 'r')
   77:             data_list = fp.readlines()
   78:             fp.close()
   79:         except :
   80:             return "problem with opening/reading file" 
   81:         dummy_list = []    
   82:         for line in data_list:
   83:             if string.find(line, 'Syncing finished') > -1:
   84:                 dummy_list.reverse()
   85:                 log_list = log_list + dummy_list
   86:                 dummy_list = []
   87:                 continue
   88:             elif string.find(line, 'Syncing started') > -1:
   89:                 dummy_list.append({'head':1,'text':line[:25]})
   90:             elif (string.find(line, 'Syncer:') > -1 or
   91:                     string.find(line, 'Approver:') > -1):
   92:                 dummy_list.append({'spec':1,'text':line[25:]})
   93:             else:
   94:                 dummy_list.append({'normal':1,'text':line[25:]})
   95: 
   96:         log_list.reverse()
   97:         return log_list
   98:     ############################################################    
   99:     def manage_approvedAction(self, REQUEST=None, action='', object=None, syncer=None, approver=None, comments=None):
  100:         """ If this action is to be approved, throw that data in into the message list """
  101:         if not syncer : syncer = getSecurityManager().getUser().getId()
  102:         msgs = ['Syncer: %s' % syncer,]
  103:         msgs.append('Approver: %s' % approver)
  104:         
  105:         # string out any newlines in comments
  106:         msgs.append('Comments: %s' % string.replace(comments, '\n', ''))
  107:         # call the relevant thing
  108:         if action == 'manage_updateXMLRPC':
  109:             return self.manage_updateXMLRPC(object, msgs=msgs, REQUEST=REQUEST)
  110:         else:
  111:             return self._error(msg='Unknown action')
  112: 
  113: 
  114:     def manage_addXMLRPC(self, data, obj_path, add_in=1):
  115:         """ Adds an object into the server """
  116:         # make sure we always get a string or a list
  117:         if type(obj_path) == type('string'): obj_path = string.split(obj_path, '/')
  118: 
  119:         # object lets try finding the parent
  120:         try: parent = self.restrictedTraverse(obj_path[:-1])
  121:         except KeyError: return 404
  122: 
  123:         # lets check they are allowed to do this
  124:         c = getSecurityManager().checkPermission
  125:         allowed = 1
  126:         for perm in ['Delete objects', 'Import/Export objects']:
  127:             if not c(perm, parent): allowed = 0
  128:         if not allowed: return 403
  129: 
  130:         # if there is one there already, delete it
  131:         if obj_path[-1] in parent.objectIds():
  132:             parent.manage_delObjects([obj_path[-1],])
  133:         else:
  134:             if not add_in: # ok so if we are deleting
  135:                 return 404
  136: 
  137:         # lets do it
  138:         if add_in:
  139:             # fake a file using StringIO
  140:             file = StringIO()
  141:             file.write(self._decode(data))
  142:             file.seek(0)
  143: 
  144:             # now import
  145:             new = parent._p_jar.importFile(file)
  146:             parent._setObject(new.getId(), new)
  147: 
  148:         # wow!..
  149:         return 200
  150: 
  151:     def manage_takeBackup(self, obj=None):
  152:         #take a back of the syncable file in the backup_sync folder if not exists just create one.
  153:         if obj is None : return None
  154:         obj_id = obj.getId()
  155:         parent = obj.aq_parent
  156:         parent_contents = parent.objectIds()
  157:         bak_id = 'backup_sync' #  backup folder name.
  158:         if bak_id not in parent_contents:parent.manage_addFolder(id=bak_id)
  159:         bak_folder = getattr(parent,bak_id)
  160:         if obj_id in bak_folder.objectIds(): bak_folder.manage_delObjects([obj_id])
  161:         bak_folder.manage_pasteObjects(parent.manage_copyObjects([obj_id]))
  162: 
  163:     #############################################################################
  164:     #Private Methods
  165:     #############################################################################
  166:     
  167:     def _log(self, msgs):
  168:         # log to ZSyncer
  169:         # this will become more configurable
  170:         file = open(self.logfile, 'a')
  171: 
  172:         # write out the log
  173:         file.write('%s\tSyncing started\n' % self._get_time())
  174:         for m in msgs: file.write('%s\t%s\n' % (self._get_time(), m))
  175:         file.write('%s\tSyncing finished\n' % self._get_time())
  176: 
  177:         file.close()
  178: 
  179:     def _get_time(self):
  180:         # get time for logging
  181:         # could be done using DateTime, but i think I want to fiddle this
  182:         return time.asctime(time.localtime(time.time()))    
  183: 
  184:     def _encode(self, s):
  185:         # do any other encoding here
  186:         # eg twofish, zlib etc
  187:         # this will do me for now
  188:         return base64.encodestring(s)
  189:     
  190:     def _decode(self, s):
  191:         # do any other encoding here
  192:         return base64.decodestring(s)
  193: 
  194:     def _serverUser(self, url):
  195:         # extract user from server url, returns server, user, pw
  196:         if url.find('@'):
  197:             # user:password in URL
  198:             (us,ur) = url.split('@')
  199:             (prot,upw) = us.split('//')
  200:             (user,pw) = upw.split(':')
  201:             url = prot + '//' + ur
  202:         else: 
  203:             u = getSecurityManager().getUser()
  204:             user = u.getId()
  205:             pw = u._getPassword()
  206:         return (url,user,pw)
  207: 
  208:     def _serverConn(self, url):
  209:         # connect using xmlrpc lib
  210:         (server,user,pw) = self._serverUser(url)
  211:         return xmlrpclibBasicAuth.Server(server, user, pw)
  212: 
  213:     def _check_http(self, v):
  214:         # so people can get away with leaving http:// off :)
  215:         if v[:7] != 'http://' and v[:8] != 'https://': v = 'http://%s' % v
  216:         if v[:5] != 'http:' and v[:6] != 'https:': v = 'http:%s' % v
  217:         return v
  218: 
  219:     def _msg(self, msgs, REQUEST=None):
  220:         # what to do with these messages
  221:         ms = []
  222:         for m in msgs:
  223:             # hack-o-rama, if i have a number, its a status code, so lets look it up and get a nicer message
  224:             if type(m) == type(1): ms.append(' - %s' % (error_messages.get(str(m), '<font color=red>Unknown error occured</font>')))
  225:             elif m[:6] == 'Object': ms.append('<li><font color=blue size=3>%s</font>' % m)
  226:             else: ms.append(m)
  227: 
  228:         if self.log or self.approval: self._log(ms)
  229:         if REQUEST is not None:
  230:             return REQUEST.RESPONSE.redirect(
  231:                     'manage_vsync?folder=%s&msg=%s' %
  232:                     (
  233:                         self.REQUEST.get('folder', '/'),
  234:                         url_quote_plus(string.join(ms, '<br>'))
  235:                     )    
  236:                 )

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>