def save_form_in_session(context, request): sdm = getToolByName(context, "session_data_manager") session = sdm.getSessionData(create=True) path = "/".join(context.getPhysicalPath()) pdict = PersistentDict() pdict.update(request.form) session.set(path, pdict)
def remember_identity(self, userid, userdata): """stores poisaml2 result data """ # first create an identity for this time of login portal = api.portal.get() manager = get_saml2rightsManager() identity = PersistentDict( userid=userid, secret=str(uuid.uuid4()), ) identity.update(userdata) logger.info(userdata) identity[_GROUP_ATTRIBUTE] = set() logger.info('add groups to user:'******'Person.Roles']: # if samlrole in SAMLROLE_TO_GROUP: for samlrole in _samlroles(userdata): groups = manager.samlrole2groups(samlrole, portal, userdata) if groups: identity[_GROUP_ATTRIBUTE].update(groups) logger.info("{} -> {}".format(samlrole, groups)) self._userdata_by_userid[userid] = identity return identity
def copy_meta(self): # XXX disable working copy support return json.dumps({ 'newId': self.request.get('metaId'), 'success': True, 'locked': False }) _id = self.request.get('metaId') copy_id = self.get_working_copy_meta_id() annotations = IAnnotations(self.context) data = annotations.get(TILE_ANNOTATIONS_KEY_PREFIX + '.' + _id) if not data: data = PersistentDict() if ('locked' in data and self.request.get( 'override', '').lower() not in ('y', 'yes', '1', 'true', 't') and api.user.get_current().getId() != data['locked']['user']): return json.dumps({ 'locked': True, 'success': False, 'lock_data': data['locked'] }) if TILE_ANNOTATIONS_KEY_PREFIX + '.' + copy_id in annotations: # cut out, we're good, resume existing return json.dumps({ 'newId': copy_id, 'success': True, 'locked': False }) version_key = self.get_working_copy_key() tile_mapping = {} new_tiles = [] for tile in data.get('tiles', []): # make copies of all the tiles tile_id = tile['id'] copy_tile_id = '{}-{}'.format(tile_id, version_key) tile_data = annotations.get(TILE_ANNOTATIONS_KEY_PREFIX + '.' + tile_id) if tile_data: annotations[TILE_ANNOTATIONS_KEY_PREFIX + '.' + copy_tile_id] = deepcopy(tile_data) new_tile_info = deepcopy(tile) new_tile_info['id'] = copy_tile_id new_tiles.append(new_tile_info) tile_mapping[tile_id] = copy_tile_id new_data = PersistentDict(dict(data)) new_data.update({'tiles': new_tiles, 'mapping': tile_mapping}) data.update({ 'locked': { 'when': DateTime().ISO8601(), 'user': api.user.get_current().getId() } }) annotations[TILE_ANNOTATIONS_KEY_PREFIX + '.' + copy_id] = new_data return json.dumps({'newId': copy_id, 'success': True, 'locked': False})
def add(self, data, index=-1): """Add data to the storage. Data must the a dict-like structure""" row = PersistentDict() row.update(data) if index>-1: self._ann.insert(index, row) else: self._ann.append(row)
def add(self, data, index=-1): """Add data to the storage. Data must the a dict-like structure""" row = PersistentDict() row.update(data) if index > -1: self._ann.insert(index, row) else: self._ann.append(row)
class NyBFile(NyContentData, NyAttributes, NyItem, NyCheckControl, NyValidation, NyContentType): """ """ implements(INyBFile) meta_type = config['meta_type'] meta_label = config['label'] icon = 'misc_/NaayaContent/NyBFile.gif' icon_marked = 'misc_/NaayaContent/NyBFile_marked.gif' manage_options = ( {'label': 'Properties', 'action': 'manage_edit_html'}, {'label': 'Edit', 'action': 'manage_main'}, {'label': 'View', 'action': 'index_html'}, ) + NyItem.manage_options security = ClassSecurityInfo() def __init__(self, id, contributor): """ """ self.id = id NyContentData.__init__(self) NyValidation.__dict__['__init__'](self) NyCheckControl.__dict__['__init__'](self) NyItem.__dict__['__init__'](self) self.contributor = contributor self._versions_i18n = PersistentDict() @property def versions_store(self): if not hasattr(self, '_versions_i18n'): self._versions_i18n = PersistentDict() return self._versions_i18n def all_versions(self, language=None): """ Returns all versions of objects. It only returns them for current language, and also all the non-i18n versions """ for ver in getattr(self, '_versions', []): yield ver if language is None: language = self.get_selected_language() if language in self.versions_store: for ver in self.versions_store[language]: yield ver def isVersionable(self): """ BFile objects are not versionable # TODO: Should remove NyCheckControl inheritance and refactor code to not use NyCheckControl methods. """ return False security.declarePublic('upload_date') @property def upload_date(self): return self.current_version.timestamp.strftime('%d %b %Y') security.declarePrivate('current_version') @property def current_version(self, language=None): versions = list(self.all_versions(language)) cur = None for ver in versions: # we want last item of this iter if not ver.removed: cur = ver continue return cur security.declareProtected(view, 'current_version_download_url') def current_version_download_url(self): language = self.get_selected_language() versions = self._versions_for_tmpl(language) if versions: return versions[-1]['url'] else: return None def _save_file(self, the_file, language=None, contributor=""): """ """ bf = make_blobfile(the_file, removed=False, timestamp=datetime.now(), contributor=contributor) if language is None: try: language = self.get_selected_language() except TypeError: # this may happens in migrations language = self.getSite().gl_get_default_language() _versions = self.versions_store.pop(language, None) if _versions is None: self._versions_i18n.update({language: [bf]}) else: _versions.append(bf) self._versions_i18n.update({language: _versions}) security.declarePrivate('remove_version') def remove_version(self, number, language=None, removed_by=None): """ Number is 0-based index of version """ _versions = list(self.all_versions(language)) ver = _versions[number] # this can raise errors. Very good if ver.removed: return ver.removed = True ver.removed_by = removed_by ver.removed_at = datetime.now() ver.size = None f = ver.open_write() f.write('') f.close() security.declareProtected(PERMISSION_EDIT_OBJECTS, 'saveProperties') def saveProperties(self, REQUEST=None, **kwargs): """ """ if not self.checkPermissionEditObject(): raise EXCEPTION_NOTAUTHORIZED(EXCEPTION_NOTAUTHORIZED_MSG) if REQUEST is not None: schema_raw_data = dict(REQUEST.form) else: schema_raw_data = kwargs _lang = schema_raw_data.pop('_lang', schema_raw_data.pop('lang', None)) _releasedate = self.process_releasedate( schema_raw_data.pop('releasedate', ''), self.releasedate) _uploaded_file = schema_raw_data.pop('uploaded_file', None) versions_to_remove = schema_raw_data.pop('versions_to_remove', []) form_errors = self.process_submitted_form( schema_raw_data, _lang, _override_releasedate=_releasedate) if form_errors: if REQUEST is not None: self._prepare_error_response( REQUEST, form_errors, schema_raw_data) REQUEST.RESPONSE.redirect( '%s/edit_html?lang=%s' % (self.absolute_url(), _lang)) return else: raise ValueError(form_errors.popitem()[1]) contributor = self.REQUEST.AUTHENTICATED_USER.getUserName() for ver_id in reversed(versions_to_remove): self.remove_version(int(ver_id) - 1, _lang, contributor) self._p_changed = 1 self.recatalogNyObject(self) # log date auth_tool = self.getAuthenticationTool() auth_tool.changeLastPost(contributor) if file_has_content(_uploaded_file): self._save_file(_uploaded_file, _lang, contributor) notify(NyContentObjectEditEvent(self, contributor)) if REQUEST: self.setSessionInfoTrans(MESSAGE_SAVEDCHANGES, date=self.utGetTodayDate()) REQUEST.RESPONSE.redirect('%s/edit_html?lang=%s' % (self.absolute_url(), _lang)) security.declareProtected(view_management_screens, 'manageProperties') def manageProperties(self, REQUEST=None, **kwargs): """ """ if not self.checkPermissionEditObject(): raise EXCEPTION_NOTAUTHORIZED(EXCEPTION_NOTAUTHORIZED_MSG) if self.wl_isLocked(): raise ResourceLockedError("File is locked via WebDAV") if REQUEST is not None: schema_raw_data = dict(REQUEST.form) else: schema_raw_data = kwargs _lang = schema_raw_data.pop('_lang', schema_raw_data.pop('lang', None)) _releasedate = self.process_releasedate( schema_raw_data.pop('releasedate', ''), self.releasedate) schema_raw_data.pop('uploaded_file', None) versions_to_remove = schema_raw_data.pop('versions_to_remove', []) form_errors = self.process_submitted_form( schema_raw_data, _lang, _override_releasedate=_releasedate) if form_errors: raise ValueError(form_errors.popitem()[1]) # pick a random error user = self.REQUEST.AUTHENTICATED_USER.getUserName() # TODO: check this for ver_id in versions_to_remove: self.remove_version(int(ver_id) - 1, user) self._p_changed = 1 self.recatalogNyObject(self) if REQUEST: REQUEST.RESPONSE.redirect('manage_main?save=ok') def _versions_for_tmpl(self, language=None): """ generate a dictionary with info about all versions, suitable for use in a page template """ versions = [tmpl_version(self, ver, str(n+1), language) for n, ver in enumerate(self.all_versions(language))] versions = filter(lambda x: not x['removed'], versions) if versions: versions[-1]['is_current'] = True return versions security.declareProtected(view, 'index_html') def index_html(self, REQUEST=None, RESPONSE=None): """ """ language = self.get_selected_language() versions = {} for lang in self.gl_get_languages_map(): versions[lang['id']] = self._versions_for_tmpl(lang['id']) options = {'versions': versions} if versions[language]: options['current_version'] = ( self.gl_get_language_name(language), versions.get(language)[-1]) else: for lang in versions: if versions[lang]: options['current_version'] = ( self.gl_get_language_name(lang), versions.get(lang)[-1]) break template_vars = {'here': self, 'options': options} to_return = self.getFormsTool().getContent(template_vars, 'bfile_index') return to_return security.declareProtected(PERMISSION_EDIT_OBJECTS, 'edit_html') def edit_html(self, REQUEST=None, RESPONSE=None): """ """ hasKey = 'lang' in REQUEST.form if hasKey is False: language = self.get_selected_language() else: language = REQUEST.form['lang'] options = {'versions': self._versions_for_tmpl(language)} template_vars = {'here': self, 'options': options} to_return = self.getFormsTool().getContent(template_vars, 'bfile_edit') return to_return # TODO: fix this security.declareProtected(view, 'version_at_date') def version_at_date(self, date): """ return the file version that was online at the given date """ for version in self._versions_for_tmpl(): if version['timestamp'] < date: candidate = version return candidate security.declareProtected(view, 'download') download = CaptureTraverse(localizedbfile_download)
class Igrac(Persistent): def __init__(self, nadimak, jeLiRacunalo, igra): self.nadimak = nadimak self.karte = PersistentList() self.igra = igra self.jeLiRacunalo = jeLiRacunalo self.zastavice = PersistentDict() self.zastavice.update({ 'uzmiKarte': 0, 'provjeriZvanja': 0, 'hocuLiZvati': 0, 'baciKartu': 0 }) self.igra.onSudjeluj(self) transaction.commit() def uzmiKarte(self): global vidljiveKarteSprites global karteSpritesList self.karte.extend(self.igra.onDajKarte()) self.karte = self.sortirajKarte(self.karte) for i in range(len(self.karte)): kartaSprite = next((x for x in karteSpritesList if x.karta.slika == self.karte[i].slika), None) kartaSprite.pozicioniraj( (1000 - (100 * len(self.karte))) / 2 + 100 * i, 566) kartaSprite.layer = i kartaSprite.prikazi() vidljiveKarteSprites.add(kartaSprite) def sortirajKarte(self, karte): return sorted(karte, key=lambda karta: (karta.boja, karta.poredak), reverse=False) def provjeriZvanja(self): self.igra.onPrijaviZvanje(self, self.karte) def hocuLiZvati(self, moramLiZvati): if self.jeLiRacunalo == True: jacinaAduta = {'Herc': 0, 'Bundeva': 0, 'Zelena': 0, 'Zir': 0} for karta in self.karte: if karta.boja == 'Herc': jacinaAduta['Herc'] += karta.vrijednostAduta elif karta.boja == 'Bundeva': jacinaAduta['Bundeva'] += karta.vrijednostAduta elif karta.boja == 'Zelena': jacinaAduta['Zelena'] += karta.vrijednostAduta elif karta.boja == 'Zir': jacinaAduta['Zir'] += karta.vrijednostAduta najjacaBoja = max(jacinaAduta, key=jacinaAduta.get) if jacinaAduta[najjacaBoja] > 30 or moramLiZvati: print self.nadimak + ": zovem " + najjacaBoja self.igra.onOdaberiAdut(najjacaBoja) else: print self.nadimak + ": dalje!" self.igra.onOdaberiAdut(False) return False def baciKartu(self, odabranaKarta=None): if (self.jeLiRacunalo == True): for karta in self.karte: if self.igra.onJeLiPoPravilima(self.karte, karta) == True: time.sleep(.01) print self.nadimak + ": ", karta self.karte.remove(karta) self.igra.onBaciKartu(karta) else: continue else: if self.igra.onJeLiPoPravilima(self.karte, odabranaKarta) == True: self.zastavice["baciKartu"] = 0 self.igra.onBaciKartu( self.karte.pop(self.karte.index(odabranaKarta))) return True else: return False
class MultiPlugin(BasePlugin): security = ClassSecurityInfo() meta_type = 'WebServerAuth Plugin' ## PAS interface implementations: ############################ security.declarePublic('loginUrl') def loginUrl(self, currentUrl): """Given the URL of the page where the user presently is, return the URL which will prompt him for authentication and land him at the same place. If something goes wrong, return ''. """ usingCustomRedirection = self.config[useCustomRedirectionKey] pattern, replacement = usingCustomRedirection and ( self.config[challengePatternKey], self.config[challengeReplacementKey]) or ( defaultChallengePattern, defaultChallengeReplacement) match = pattern.match(currentUrl) # Let the web server's auth have a swing at it: if match: # will usually start with http:// but may start with https:// (and thus not match) if you're already logged in and try to access something you're not privileged to try: destination = match.expand(replacement) except re.error: # Don't screw up your replacement string, please. If you do, we at least try not to punish the user with a traceback. if usingCustomRedirection: logger.error( "Your custom WebServerAuth Replacement Pattern could not be applied to a URL which needs authentication: %s. Please correct it." % currentUrl) else: return destination # Our regex didn't match, or something went wrong. return '' protocol = 'http' security.declarePrivate('challenge') def challenge(self, request, response): config = self.config if config[challengeHeaderEnabledKey]: if request.get_header(config[challengeHeaderNameKey]) is None: return False url = self.loginUrl(request.ACTUAL_URL) if url: response.redirect(url, lock=True) return True else: # Pass off control to the next challenge plugin. return False security.declarePrivate('enumerateUsers') # Inspired by the OpenID plugin def enumerateUsers(self, id=None, login=None, exact_match=False, sort_by=None, max_results=None, **kw): """Evil, layer-violating enumerator to get the logged in user, though unenumerable, to be validatable. PAS doesn't seem to make an allowance for authorizing (IIRC) an existing user if that user cannot be enumerated, so we try to guess who's calling and make that happen. """ # Unless we're admitting non-Plone-dwelling users, don't pretend the user is there. Also, don't enumerate unless we seem to have been called by getUserById(). We're very conservative, even checking the types of things like exact_match. Also also, don't enumerate unless we're searching for the currently logged in user. Heck, we even look at the stack now, because searchUsers() (as called by searchPrincipals()) calls us the same way getUserById() does. if self.config[authenticateEverybodyKey] and ( id is not None and login is None and exact_match is True and sort_by is None and max_results is None and not kw ) and ( self.REQUEST and self._normalizedLoginName( self.REQUEST.environ.get( self.config[usernameHeaderKey])) == id ): # may be redundant with the stack inspection below, but it makes me feel warm and fuzzy for now stack = inspect.stack() try: calledByGetUserById = stack[2][ 3] == 'getUserById' # getUserById calls _verifyUser, which calls us finally: del stack # Dispose of frames, as recommended by http://docs.python.org/lib/inspect-stack.html if calledByGetUserById: return [{"id": id, "login": id, "pluginid": self.getId()}] return [] security.declarePrivate('authenticateCredentials') def authenticateCredentials(self, credentials): """Expects a login name in the form returned by extractCredentials() below. Example: >>> authenticateCredentials({usernameKey: 'foobar'}) ('foobar', 'foobar') """ defaultDate = '2000/01/01' def setLoginTimes(member): """Do what the logged_in script usually does, with regard to login times, to users after they log in.""" # Ripped off and simplified from CMFPlone.MembershipTool.MembershipTool.setLoginTimes(): now = self.ZopeTime() # Duplicate mysterious logic from MembershipTool.py: lastLoginTime = member.getProperty( 'login_time', defaultDate ) # In Plone 2.5, 'login_time' property is DateTime('2000/01/01') when a user has never logged in, so this default never kicks in. However, I'll assume it was in the MembershipTool code for a reason. if str(lastLoginTime) == defaultDate: lastLoginTime = now member.setMemberProperties({ 'login_time': now, 'last_login_time': lastLoginTime }) login = credentials.get(usernameKey) if login is None: return None else: user = self._getPAS().getUser( login) # Our enumerator doesn't respond to getUser() calls. userId = user and user.getId() or login membershipTool = getToolByName(self, 'portal_membership', default=None) if membershipTool is not None: # Tolerate running in plain Zope, sans Plone. member = membershipTool.getMemberById( userId ) # works thanks to our UserEnumerationPlugin # implicitly creates the record in portal_memberdata, at least when authenticate_everybody is on: see memberdata.py:67 if member is None: # happens only when authenticate_everybody is off return None if IDisableCSRFProtection is not None: alsoProvides(self.REQUEST, IDisableCSRFProtection) if str( member.getProperty('login_time') ) == defaultDate: # This member has never had his login time set; he's never logged in before. setLoginTimes( member ) # lets the user show up in member searches. We do this only when the member record is first created. This means the login times are less accurate than in a stock Plone with form-based login, in which the times are set at each login. However, if we were to set login times at each request, that's an expensive DB write at each, and lots of ConflictErrors happen. The real answer is for somebody (Plone or PAS) to fire an event when somebody logs in. membershipTool.createMemberArea(member_id=userId) return userId, login security.declarePrivate('extractCredentials') def extractCredentials(self, request): """Get login name from a request header passed into Zope. Example: >>> class MockRequest: ... def __init__(self, environ={}): ... self.environ = environ >>> request = MockRequest({'HTTP_X_REMOTE_USER': '******'}) >>> handler = MultiPlugin('someId') >>> handler.extractCredentials(request) {'apache_username': '******'} """ # Do not extract credentials if we are configured to expect a cookie # but it is not found. if self.config[cookieCheckEnabledKey]: cookieName = self.config[cookieNameKey] if cookieName and cookieName not in request.cookies: return None # Do not extract credentials if a secret matching is enabled, but not matched. if self.config[secretEnabledKey]: secret = request.environ.get(self.config[secretHeaderKey]) if secret != self.config[secretValueKey]: return None login = request.environ.get(self.config[usernameHeaderKey]) if not login: return None return {usernameKey: self._normalizedLoginName(login)} ## Helper methods: ############################ security.declarePrivate('_normalizedLoginName') def _normalizedLoginName(self, login): """Given a raw login name, return it modified according to the "Strip domain names from usernames" preference.""" if login is not None: if self.config[stripDomainNamesKey] and '@' in login: # With some setups, the login name is returned as '*****@*****.**'. login = login.split('@', 1)[0] elif self.config[stripWindowsDomainKey] and '\\' in login: # Active Directory user expressions have exactly 1 backslash. login = login.split('\\', 1)[1] if self.config[forceLowercaseUsernamesKey]: login = login.lower() return login @property def config(self): """Return the configuration mapping, in the latest format.""" # Upgrade config to version 1.1 format: if not hasattr(self, '_config'): self._config = self.__dict__['config'] # sidestep descriptor del self.__dict__['config'] self._config.update(configDefaults1_1) # Upgrade to 1.4 format: if stripWindowsDomainKey not in self._config: self._config[stripWindowsDomainKey] = configDefaults[ stripWindowsDomainKey] # Upgrade to 1.5 format: if not isinstance(self._config, PersistentDict): self._config = PersistentDict(self._config) self._config.update(configDefaults1_5) # Upgrade to 1.6 format: if secretEnabledKey not in self._config: self._config.update(configDefaults1_6) # Upgrade to 1.7 format: if forceLowercaseUsernamesKey not in self._config: self._config.update(configDefaults1_7) return self._config ## ZMI crap: ############################ def __init__(self, id, title=None): BasePlugin.__init__(self) self._setId(id) self.title = title self._config = PersistentDict(configDefaults) # A method to return the configuration page: security.declareProtected(ManageUsers, 'manage_config') manage_config = PageTemplateFile('config.pt', wwwDirectory) # Add a tab that calls that method: manage_options = ({ 'label': 'Options', 'action': 'manage_config' }, ) + BasePlugin.manage_options security.declareProtected(ManageUsers, 'configForView') def configForView(self): """Return a mapping of my configuration values, for use in a page template.""" ret = dict(self.config) ret['challenge_pattern_uncompiled'] = ret['challenge_pattern'].pattern return ret security.declareProtected(ManageUsers, 'manage_changeConfig') def manage_changeConfig(self, REQUEST=None): """Update my configuration based on form data.""" for key in [ stripDomainNamesKey, stripWindowsDomainKey, authenticateEverybodyKey, useCustomRedirectionKey, cookieCheckEnabledKey, challengeHeaderEnabledKey, secretEnabledKey, forceLowercaseUsernamesKey ]: self.config[key] = REQUEST.form.get( key ) == '1' # Don't raise an exception; unchecked checkboxes don't get submitted. for key in [ usernameHeaderKey, challengeReplacementKey, cookieNameKey, challengeHeaderNameKey, secretHeaderKey, secretValueKey ]: self.config[key] = REQUEST.form[key] self.config[challengePatternKey] = re.compile( REQUEST.form[challengePatternKey]) return REQUEST.RESPONSE.redirect('%s/manage_config' % self.absolute_url())
class NyLocalizedBFile(NyContentData, NyAttributes, NyItem, NyCheckControl, NyValidation, NyContentType): """ """ implements(INyBFile) meta_type = config['meta_type'] meta_label = config['label'] manage_options = ( {'label': 'Properties', 'action': 'manage_edit_html'}, {'label': 'Edit', 'action': 'manage_main'}, {'label': 'View', 'action': 'index_html'}, ) + NyItem.manage_options security = ClassSecurityInfo() def __init__(self, id, contributor): self.id = id NyContentData.__init__(self) NyValidation.__dict__['__init__'](self) NyCheckControl.__dict__['__init__'](self) NyItem.__dict__['__init__'](self) self.contributor = contributor self._versions = PersistentDict() security.declarePrivate('current_version') @property def current_version(self): language = self.get_selected_language() hasKey = self._versions.has_key(language) if hasKey == True: _versions = self._versions[language] for ver in reversed(_versions): if not ver.removed: return ver else: return None security.declareProtected(view, 'current_version_download_url') def current_version_download_url(self): language = self.get_selected_language() versions = self._versions_for_tmpl(language) if versions: return versions[-1]['url'] else: return None security.declarePrivate('remove_version') def remove_version(self, number, language, removed_by=None): if (not self._versions[language]) or (not self._versions[language][number]): raise ValueError # pick a random error ver = self._versions[language][number] if ver.removed: return ver.removed = True ver.removed_by = removed_by ver.removed_at = datetime.utcnow() ver.size = None f = ver.open_write() f.write('') f.close() def _save_file(self, the_file, language, contributor): """ """ bf = make_blobfile(the_file, removed=False, timestamp=datetime.utcnow(), contributor=contributor) _versions = self._versions.pop(language, None) if _versions == None: toAdd = [bf] newD = {language:toAdd} self._versions.update(newD) else: _versions.append(bf) newD = {language:_versions} self._versions.update(newD) def _versions_for_tmpl(self, language): """ """ hasKey = self._versions.has_key(language) if hasKey == True: _versions = self._versions[language] versions = [tmpl_version(self, ver, str(n+1)) for n, ver in enumerate(_versions) if not ver.removed] if versions: versions[-1]['is_current'] = True return versions else: return None security.declareProtected(view, 'index_html') def index_html(self, REQUEST=None, RESPONSE=None): """ """ language = self.get_selected_language() versions = self._versions_for_tmpl(language) options = {'versions': versions} if versions: options['current_version'] = versions[-1] template_vars = {'here': self, 'options': options} to_return = self.getFormsTool().getContent(template_vars, 'localizedbfile_index') return to_return def isVersionable(self): """ Localized BFiles are not versionable""" return False security.declareProtected(PERMISSION_EDIT_OBJECTS, 'saveProperties') def saveProperties(self, REQUEST=None, **kwargs): """ """ if not self.checkPermissionEditObject(): raise EXCEPTION_NOTAUTHORIZED, EXCEPTION_NOTAUTHORIZED_MSG if REQUEST is not None: schema_raw_data = dict(REQUEST.form) else: schema_raw_data = kwargs _lang = schema_raw_data.pop('_lang', schema_raw_data.pop('lang', None)) _releasedate = self.process_releasedate(schema_raw_data.pop('releasedate', ''), self.releasedate) _uploaded_file = schema_raw_data.pop('uploaded_file', None) versions_to_remove = schema_raw_data.pop('versions_to_remove', []) form_errors = self.process_submitted_form(schema_raw_data, _lang, _override_releasedate=_releasedate) if form_errors: if REQUEST is not None: self._prepare_error_response(REQUEST, form_errors, schema_raw_data) REQUEST.RESPONSE.redirect('%s/edit_html?lang=%s' % (self.absolute_url(), _lang)) return else: raise ValueError(form_errors.popitem()[1]) # pick a random error contributor = self.REQUEST.AUTHENTICATED_USER.getUserName() for ver_id in reversed(versions_to_remove): self.remove_version(int(ver_id) - 1, _lang, contributor) self._p_changed = 1 self.recatalogNyObject(self) #log date auth_tool = self.getAuthenticationTool() auth_tool.changeLastPost(contributor) if file_has_content(_uploaded_file): self._save_file(_uploaded_file, _lang, contributor) notify(NyContentObjectEditEvent(self, contributor)) if REQUEST: self.setSessionInfoTrans(MESSAGE_SAVEDCHANGES, date=self.utGetTodayDate()) REQUEST.RESPONSE.redirect('%s/edit_html?lang=%s' % (self.absolute_url(), _lang)) security.declareProtected(PERMISSION_EDIT_OBJECTS, 'edit_html') def edit_html(self, REQUEST=None, RESPONSE=None): """ """ hasKey = REQUEST.form.has_key('lang') if hasKey == False: language = self.get_selected_language() else: language = REQUEST.form['lang'] options = {'versions': self._versions_for_tmpl(language)} template_vars = {'here': self, 'options': options} to_return = self.getFormsTool().getContent(template_vars, 'localizedbfile_edit') return to_return security.declareProtected(view, 'download') download = CaptureTraverse(localizedbfile_download)
class NyBFile(NyContentData, NyAttributes, NyItem, NyCheckControl, NyValidation, NyContentType): """ """ implements(INyBFile) meta_type = config['meta_type'] meta_label = config['label'] icon = 'misc_/NaayaContent/NyBFile.gif' icon_marked = 'misc_/NaayaContent/NyBFile_marked.gif' manage_options = ( {'label': 'Properties', 'action': 'manage_edit_html'}, {'label': 'Edit', 'action': 'manage_main'}, {'label': 'View', 'action': 'index_html'}, ) + NyItem.manage_options security = ClassSecurityInfo() def __init__(self, id, contributor): """ """ self.id = id NyContentData.__init__(self) NyValidation.__dict__['__init__'](self) NyCheckControl.__dict__['__init__'](self) NyItem.__dict__['__init__'](self) self.contributor = contributor self._versions_i18n = PersistentDict() @property def versions_store(self): if not hasattr(self, '_versions_i18n'): self._versions_i18n = PersistentDict() return self._versions_i18n def all_versions(self, language=None): """ Returns all versions of objects. It only returns them for current language, and also all the non-i18n versions """ for ver in getattr(self, '_versions', []): yield ver if language is None: language = self.get_selected_language() if language in self.versions_store: for ver in self.versions_store[language]: yield ver def isVersionable(self): """ BFile objects are not versionable # TODO: Should remove NyCheckControl inheritance and refactor code to not use NyCheckControl methods. """ return False security.declarePublic('upload_date') @property def upload_date(self): return self.current_version.timestamp.strftime('%d %b %Y') security.declarePrivate('current_version') @property def current_version(self, language=None): versions = list(self.all_versions(language)) cur = None for ver in versions: # we want last item of this iter if not ver.removed: cur = ver continue return cur security.declareProtected(view, 'current_version_download_url') def current_version_download_url(self): language = self.get_selected_language() versions = self._versions_for_tmpl(language) if versions: return versions[-1]['url'] else: return None def _save_file(self, the_file, language=None, contributor=""): """ """ bf = make_blobfile(the_file, removed=False, timestamp=datetime.utcnow(), contributor=contributor) if language is None: try: language = self.get_selected_language() except TypeError: # this may happens in migrations language = self.getSite().gl_get_default_language() _versions = self.versions_store.pop(language, None) if _versions is None: self._versions_i18n.update({language: [bf]}) else: _versions.append(bf) self._versions_i18n.update({language: _versions}) security.declarePrivate('remove_version') def remove_version(self, number, language=None, removed_by=None): """ Number is 0-based index of version """ _versions = list(self.all_versions(language)) ver = _versions[number] # this can raise errors. Very good if ver.removed: return ver.removed = True ver.removed_by = removed_by ver.removed_at = datetime.utcnow() ver.size = None f = ver.open_write() f.write('') f.close() security.declareProtected(PERMISSION_EDIT_OBJECTS, 'saveProperties') def saveProperties(self, REQUEST=None, **kwargs): """ """ if not self.checkPermissionEditObject(): raise EXCEPTION_NOTAUTHORIZED(EXCEPTION_NOTAUTHORIZED_MSG) if REQUEST is not None: schema_raw_data = dict(REQUEST.form) else: schema_raw_data = kwargs _lang = schema_raw_data.pop('_lang', schema_raw_data.pop('lang', None)) _releasedate = self.process_releasedate( schema_raw_data.pop('releasedate', ''), self.releasedate) _uploaded_file = schema_raw_data.pop('uploaded_file', None) versions_to_remove = schema_raw_data.pop('versions_to_remove', []) form_errors = self.process_submitted_form( schema_raw_data, _lang, _override_releasedate=_releasedate) if form_errors: if REQUEST is not None: self._prepare_error_response( REQUEST, form_errors, schema_raw_data) REQUEST.RESPONSE.redirect( '%s/edit_html?lang=%s' % (self.absolute_url(), _lang)) return else: raise ValueError(form_errors.popitem()[1]) contributor = self.REQUEST.AUTHENTICATED_USER.getUserName() for ver_id in reversed(versions_to_remove): self.remove_version(int(ver_id) - 1, _lang, contributor) self._p_changed = 1 self.recatalogNyObject(self) # log date auth_tool = self.getAuthenticationTool() auth_tool.changeLastPost(contributor) if file_has_content(_uploaded_file): self._save_file(_uploaded_file, _lang, contributor) notify(NyContentObjectEditEvent(self, contributor)) if REQUEST: self.setSessionInfoTrans(MESSAGE_SAVEDCHANGES, date=self.utGetTodayDate()) REQUEST.RESPONSE.redirect('%s/edit_html?lang=%s' % (self.absolute_url(), _lang)) security.declareProtected(view_management_screens, 'manageProperties') def manageProperties(self, REQUEST=None, **kwargs): """ """ if not self.checkPermissionEditObject(): raise EXCEPTION_NOTAUTHORIZED(EXCEPTION_NOTAUTHORIZED_MSG) if self.wl_isLocked(): raise ResourceLockedError("File is locked via WebDAV") if REQUEST is not None: schema_raw_data = dict(REQUEST.form) else: schema_raw_data = kwargs _lang = schema_raw_data.pop('_lang', schema_raw_data.pop('lang', None)) _releasedate = self.process_releasedate( schema_raw_data.pop('releasedate', ''), self.releasedate) schema_raw_data.pop('uploaded_file', None) versions_to_remove = schema_raw_data.pop('versions_to_remove', []) form_errors = self.process_submitted_form( schema_raw_data, _lang, _override_releasedate=_releasedate) if form_errors: raise ValueError(form_errors.popitem()[1]) # pick a random error user = self.REQUEST.AUTHENTICATED_USER.getUserName() # TODO: check this for ver_id in versions_to_remove: self.remove_version(int(ver_id) - 1, user) self._p_changed = 1 self.recatalogNyObject(self) if REQUEST: REQUEST.RESPONSE.redirect('manage_main?save=ok') def _versions_for_tmpl(self, language=None): """ generate a dictionary with info about all versions, suitable for use in a page template """ versions = [tmpl_version(self, ver, str(n+1)) for n, ver in enumerate(self.all_versions(language))] versions = filter(lambda x: not x['removed'], versions) if versions: versions[-1]['is_current'] = True return versions security.declareProtected(view, 'index_html') def index_html(self, REQUEST=None, RESPONSE=None): """ """ language = self.get_selected_language() versions = self._versions_for_tmpl(language) options = {'versions': versions} if versions: options['current_version'] = versions[-1] template_vars = {'here': self, 'options': options} to_return = self.getFormsTool().getContent(template_vars, 'bfile_index') return to_return security.declareProtected(PERMISSION_EDIT_OBJECTS, 'edit_html') def edit_html(self, REQUEST=None, RESPONSE=None): """ """ hasKey = 'lang' in REQUEST.form if hasKey is False: language = self.get_selected_language() else: language = REQUEST.form['lang'] options = {'versions': self._versions_for_tmpl(language)} template_vars = {'here': self, 'options': options} to_return = self.getFormsTool().getContent(template_vars, 'bfile_edit') return to_return # TODO: fix this security.declareProtected(view, 'version_at_date') def version_at_date(self, date): """ return the file version that was online at the given date """ for version in self._versions_for_tmpl(): if version['timestamp'] < date: candidate = version return candidate security.declareProtected(view, 'download') download = CaptureTraverse(localizedbfile_download)
class NyLocalizedBFile(NyContentData, NyAttributes, NyItem, NyCheckControl, NyValidation, NyContentType): """ """ implements(INyBFile) meta_type = config['meta_type'] meta_label = config['label'] manage_options = ( { 'label': 'Properties', 'action': 'manage_edit_html' }, { 'label': 'Edit', 'action': 'manage_main' }, { 'label': 'View', 'action': 'index_html' }, ) + NyItem.manage_options security = ClassSecurityInfo() def __init__(self, id, contributor): self.id = id NyContentData.__init__(self) NyValidation.__dict__['__init__'](self) NyCheckControl.__dict__['__init__'](self) NyItem.__dict__['__init__'](self) self.contributor = contributor self._versions = PersistentDict() security.declarePrivate('current_version') @property def current_version(self): language = self.get_selected_language() hasKey = self._versions.has_key(language) if hasKey == True: _versions = self._versions[language] for ver in reversed(_versions): if not ver.removed: return ver else: return None security.declareProtected(view, 'current_version_download_url') def current_version_download_url(self): language = self.get_selected_language() versions = self._versions_for_tmpl(language) if versions: return versions[-1]['url'] else: return None security.declarePrivate('remove_version') def remove_version(self, number, language, removed_by=None): if (not self._versions[language]) or ( not self._versions[language][number]): raise ValueError # pick a random error ver = self._versions[language][number] if ver.removed: return ver.removed = True ver.removed_by = removed_by ver.removed_at = datetime.utcnow() ver.size = None f = ver.open_write() f.write('') f.close() def _save_file(self, the_file, language, contributor): """ """ bf = make_blobfile(the_file, removed=False, timestamp=datetime.utcnow(), contributor=contributor) _versions = self._versions.pop(language, None) if _versions == None: toAdd = [bf] newD = {language: toAdd} self._versions.update(newD) else: _versions.append(bf) newD = {language: _versions} self._versions.update(newD) def _versions_for_tmpl(self, language): """ """ hasKey = self._versions.has_key(language) if hasKey == True: _versions = self._versions[language] versions = [ tmpl_version(self, ver, str(n + 1)) for n, ver in enumerate(_versions) if not ver.removed ] if versions: versions[-1]['is_current'] = True return versions else: return None security.declareProtected(view, 'index_html') def index_html(self, REQUEST=None, RESPONSE=None): """ """ language = self.get_selected_language() versions = self._versions_for_tmpl(language) options = {'versions': versions} if versions: options['current_version'] = versions[-1] template_vars = {'here': self, 'options': options} to_return = self.getFormsTool().getContent(template_vars, 'localizedbfile_index') return to_return def isVersionable(self): """ Localized BFiles are not versionable""" return False security.declareProtected(PERMISSION_EDIT_OBJECTS, 'saveProperties') def saveProperties(self, REQUEST=None, **kwargs): """ """ if not self.checkPermissionEditObject(): raise EXCEPTION_NOTAUTHORIZED, EXCEPTION_NOTAUTHORIZED_MSG if REQUEST is not None: schema_raw_data = dict(REQUEST.form) else: schema_raw_data = kwargs _lang = schema_raw_data.pop('_lang', schema_raw_data.pop('lang', None)) _releasedate = self.process_releasedate( schema_raw_data.pop('releasedate', ''), self.releasedate) _uploaded_file = schema_raw_data.pop('uploaded_file', None) versions_to_remove = schema_raw_data.pop('versions_to_remove', []) form_errors = self.process_submitted_form( schema_raw_data, _lang, _override_releasedate=_releasedate) if form_errors: if REQUEST is not None: self._prepare_error_response(REQUEST, form_errors, schema_raw_data) REQUEST.RESPONSE.redirect('%s/edit_html?lang=%s' % (self.absolute_url(), _lang)) return else: raise ValueError( form_errors.popitem()[1]) # pick a random error contributor = self.REQUEST.AUTHENTICATED_USER.getUserName() for ver_id in reversed(versions_to_remove): self.remove_version(int(ver_id) - 1, _lang, contributor) self._p_changed = 1 self.recatalogNyObject(self) #log date auth_tool = self.getAuthenticationTool() auth_tool.changeLastPost(contributor) if file_has_content(_uploaded_file): self._save_file(_uploaded_file, _lang, contributor) notify(NyContentObjectEditEvent(self, contributor)) if REQUEST: self.setSessionInfoTrans(MESSAGE_SAVEDCHANGES, date=self.utGetTodayDate()) REQUEST.RESPONSE.redirect('%s/edit_html?lang=%s' % (self.absolute_url(), _lang)) security.declareProtected(PERMISSION_EDIT_OBJECTS, 'edit_html') def edit_html(self, REQUEST=None, RESPONSE=None): """ """ hasKey = REQUEST.form.has_key('lang') if hasKey == False: language = self.get_selected_language() else: language = REQUEST.form['lang'] options = {'versions': self._versions_for_tmpl(language)} template_vars = {'here': self, 'options': options} to_return = self.getFormsTool().getContent(template_vars, 'localizedbfile_edit') return to_return security.declareProtected(view, 'download') download = CaptureTraverse(localizedbfile_download)