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>