def get_number_comments(self, status=None): if not status: return Session.query(sa.func.count(Comment.id)).filter_by(change_id=self.id).first()[0] date = Session.query(func.max(CommentStatus.created_date).label('date'), Comment.id) date = date.filter(CommentStatus.comment_id==Comment.id).filter(Comment.change_id==self.id) date = date.group_by(CommentStatus.comment_id, Comment.id) subq = date.subquery() q = Session.query(func.count(Comment.id)).outerjoin((subq, subq.c.id==Comment.id)) q = q.outerjoin((CommentStatus, CommentStatus.comment_id==Comment.id)) q = q.filter(Comment.change_id==self.id).filter(Comment.status!=STATUS_REMOVED) q = q.filter(Comment.in_reply_to_id==None) if status == STATUS_OPEN: q = q.filter(sa.or_( CommentStatus.id==None, sa.and_(CommentStatus.created_date==subq.columns.date, CommentStatus.status==status) )) return q.scalar() else: q = q.filter( sa.and_(CommentStatus.created_date==subq.columns.date, CommentStatus.status==status) ) return q.scalar()
def _create_parent_directories(self): """ Check if the parent directory exists and if it doesn't create it. self.path is the path part of the full filepath already so name here is actually the name of the directory. """ path = self.path.lstrip("/") if not path: # if path is '' then there's no parent to create because # we are at root. return segments = path.split(u"/") current_path = u"/" for segment in segments: q = Session.query(Directory) q = q.filter_by(path=current_path) q = q.filter_by(name=segment) directory = q.first() if not directory: directory = Directory(path=current_path, name=segment, project=self.project) Session.add(directory) current_path = directory.full_path
def get(cls, sid=None, email=None): if sid and email: return Session.query(BetaEmail).filter( sa.or_(BetaEmail.email==(email and email.lower() or ''), BetaEmail.sid==sid) ).first() if sid: return Session.query(BetaEmail).filter( BetaEmail.sid==sid ).first() if email: return Session.query(BetaEmail).filter( BetaEmail.email==(email and email.lower() or '') ).first() return None
def remove_user(self, user): q = Session.query(self.connection_class).filter(getattr(self.connection_class, self.object_id_name)==self.id) q = q.filter(self.connection_class.user_id==user.id) cu = q.first() if cu: Session.delete(cu) return True return False
def remove_user(self, user): q = Session.query(self.connection_class).filter( getattr(self.connection_class, self.object_id_name) == self.id) q = q.filter(self.connection_class.user_id == user.id) cu = q.first() if cu: Session.delete(cu) return True return False
def __call__(self, environ, start_response): """Invoke the Controller""" # WSGIController.__call__ dispatches to the Controller method # the request is routed to. This routing information is # available in environ['pylons.routes_dict'] try: self._session = Session auth.authenticate_basic_auth() if '_debug_frontend' in request.params: #now we can force this no matter the environment. c.debug_frontend = request.params['_debug_frontend'] == 'True' else: c.debug_frontend = not h.is_production() #this is used by timer proxy and the templates c.show_debug = bool(session.get('show_debug')) request.environ['USER'] = session.get('username', '') request.environ['REAL_USER'] = session.get('real_username', '') # set the start of the rendering c.render_start = time.time() c.requested_url = request.environ.get('PATH_INFO') if request.environ.get('QUERY_STRING'): c.requested_url += '?' + request.environ['QUERY_STRING'] logger.info(c.requested_url) # Capture IP address in non-ssl mode, so we can use it in SSL mode see ticket #2275 ip = auth.get_user_ip() if not session.get('IP_ADDRESS') and ip: session['IP_ADDRESS'] = ip elif not session.get('IP_ADDRESS') and request.environ.get( 'HTTP_RLNCLIENTIPADDR'): session['IP_ADDRESS'] = request.environ.get( 'HTTP_RLNCLIENTIPADDR') elif not session.get('IP_ADDRESS') and request.environ.get( 'REMOTE_ADDR'): session['IP_ADDRESS'] = request.environ.get('REMOTE_ADDR') # Save the first referer we see to store in user record when/if we create one. if not session.get('referer'): session['referer'] = environ.get('HTTP_REFERER', '').decode('utf-8', 'ignore') session.save() if session.get('notify'): c._notify = session['notify'] del session['notify'] session.save() return WSGIController.__call__(self, environ, start_response) finally: if 'paste.testing_variables' not in request.environ: Session.remove()
def __init__(self, **kwargs): super(Project, self).__init__(**kwargs) if not self.slug: self.slug = get_unique_slug(self.organization, kwargs['name']) creator = kwargs.get('creator') if creator: self.attach_user(creator, APP_ROLE_ADMIN) Session.add(activity.NewProject(creator, self))
def deactivate(self, user): """ Deactivate this project. Since there is a unique contraint in the organization_id/name tuple we also rename the project using the unique eid. """ self.status = STATUS_INACTIVE self.name = "%s-%s" % (self.eid, self.name) self.update_activity() Session.add(activity.DeleteProject(user, self))
def interested_users(self): # people invited to this file... # people with changes on this file, # people with comments on this file. from desio.model.users import User cus = self.get_user_connections(status=STATUS_APPROVED) users = [cu.user for cu in cus if cu.user] contributors = Session.query(User).join(Change).filter(Change.entity_id==self.id).all() commenters = Session.query(User).join(Comment).join((Change, Comment.change_id==Change.id)).filter(Change.entity_id==self.id).all() return list(set(users + contributors + commenters))
def __call__(self, environ, start_response): """Invoke the Controller""" # WSGIController.__call__ dispatches to the Controller method # the request is routed to. This routing information is # available in environ['pylons.routes_dict'] try: self._session = Session auth.authenticate_basic_auth() if '_debug_frontend' in request.params: #now we can force this no matter the environment. c.debug_frontend = request.params['_debug_frontend'] == 'True' else: c.debug_frontend = not h.is_production() #this is used by timer proxy and the templates c.show_debug = bool(session.get('show_debug')) request.environ['USER'] = session.get('username', '') request.environ['REAL_USER'] = session.get('real_username', '') # set the start of the rendering c.render_start = time.time() c.requested_url = request.environ.get('PATH_INFO') if request.environ.get('QUERY_STRING'): c.requested_url += '?' + request.environ['QUERY_STRING'] logger.info(c.requested_url) # Capture IP address in non-ssl mode, so we can use it in SSL mode see ticket #2275 ip = auth.get_user_ip() if not session.get('IP_ADDRESS') and ip: session['IP_ADDRESS'] = ip elif not session.get('IP_ADDRESS') and request.environ.get('HTTP_RLNCLIENTIPADDR'): session['IP_ADDRESS'] = request.environ.get('HTTP_RLNCLIENTIPADDR') elif not session.get('IP_ADDRESS') and request.environ.get('REMOTE_ADDR'): session['IP_ADDRESS'] = request.environ.get('REMOTE_ADDR') # Save the first referer we see to store in user record when/if we create one. if not session.get('referer'): session['referer'] = environ.get('HTTP_REFERER','').decode('utf-8','ignore') session.save() if session.get('notify'): c._notify = session['notify'] del session['notify'] session.save() return WSGIController.__call__(self, environ, start_response) finally: if 'paste.testing_variables' not in request.environ: Session.remove()
def attach_user(self, user, role=APP_ROLE_READ, status=STATUS_APPROVED): cu = Session.query(self.connection_class) \ .filter(getattr(self.connection_class, self.object_name)==self) \ .filter(self.connection_class.user==user).first() if cu: cu.role = role cu.status = status return cu cu = self.connection_class(user=user, role=role, status=status) setattr(cu, self.object_name, self) Session.add(cu) return cu
def set_preference(self, key, val): """ Sets a user's preference """ self._load_prefs() if key in self.preferences_dict: self.preferences_dict[key].value = val pref = self.preferences_dict[key] else: pref = UserPreference(key=key, value=val, user=self) Session.add(pref) self.preferences_dict[key] = pref return pref
def attach_user(self, user, role=APP_ROLE_READ, status=STATUS_APPROVED): cu = Session.query(self.connection_class) \ .filter(getattr(self.connection_class, self.object_name)==self) \ .filter(self.connection_class.user==user).first() if cu: cu.role = role cu.status = status return cu cu = self.connection_class(user=user, role=role, status=status) setattr(cu, self.object_name, self) Session.add(cu) return cu
def create(cls, sid, email, creator=None, send_email=True): from desio.utils import email as email_mod be = cls.get(sid, email) if be: return be be = BetaEmail(sid=sid, email=email.lower(), creator=creator) Session.add(be) if send_email: email_mod.send(email, 'beta_email.txt', reply_to='*****@*****.**') return be
def completion_status(self): """ Users can 'complete' comments. This will get the most recent row from CommentStatus. Should be either 'open' or 'completed' """ cs = Session.query(CommentStatus).filter_by(comment_id=self.id).order_by(sa.desc(CommentStatus.created_date)).first() if not cs: #create a default cs = CommentStatus(user=self.creator, created_date=self.created_date, status=STATUS_OPEN, comment=self) Session.add(cs) Session.flush() return cs
def __init__(self, *args, **kwargs): version = kwargs.get('version', None) super(Change, self).__init__(*args, **kwargs) if version is None: version = self._get_next_version() self.version = version creator = kwargs.get('creator', None) if version == 1: Session.add(activity.NewFile(creator, self.entity)) else: Session.add(activity.NewVersion(creator, self))
def add_change(self, user, filepath, temp_contents_filepath, description): """ Check that file exists, if it does add a Change directly. If it doesn't exist, create the File and then add the change. """ file_object = self.get_file(filepath) if file_object is None: path, name = os.path.split(filepath) file_object = File(path=path, name=name, project=self) Session.add(file_object) return file_object.add_change(user, temp_contents_filepath, description)
def add_directory(self, user, path): """ Check if dir exists, if so return it. If not create dir. """ dir_object = self.get_entities(path, only_type=Directory.TYPE) if dir_object: return dir_object path, name = os.path.split(path) dir_object = Directory(path=path, name=name, project=self) Session.add(dir_object) return dir_object
def interested_users(self): from desio.model.users import User cus = self.get_user_connections(status=STATUS_APPROVED) users = [cu.user for cu in cus if cu.user] contributors = Session.query(User).join(Change).filter(Change.project_id==self.id).all() return list(set(users + contributors))
def get_comments(self): """ Get the comments associated with this change(_extract). """ q = Session.query(Comment) q = q.filter_by(status=STATUS_EXISTS) q = q.filter_by(**{self._comment_attribute: self}) q = q.order_by(sa.asc(Comment.created_date)) return q.all()
def get_changes(self): """ Fetch change for this file. """ q = Session.query(Change) q = q.filter_by(entity=self) q = q.filter_by(project=self.project) q = q.order_by(sa.desc(Change.version)) return q.all()
def interested_users(self): # people invited to this file... # people with changes on this file, # people with comments on this file. from desio.model.users import User commenters = Session.query(User).join(Comment).filter(Comment.in_reply_to_id==self.id).all() return list(set([self.creator] + commenters))
def get_user_connection(self, user, status=STATUS_APPROVED): """ Find a single user's membership within this org """ if not user: return None q = Session.query(self.connection_class).filter(self.connection_class.user_id==user.id) if status: q = q.filter(self.connection_class.status==status) return q.filter(getattr(self.connection_class, self.object_id_name)==self.id).first()
def get_user_connections(self, status=None): """ Get all memberships in this org. """ q = Session.query(self.connection_class).filter(getattr(self.connection_class, self.object_id_name)==self.id) if status and isinstance(status, basestring): q = q.filter(self.connection_class.status==status) if status and isinstance(status, (list, tuple)): q = q.filter(self.connection_class.status.in_(status)) return q.all()
def get_comments(self): """ Get the comments associated with this change(_extract). """ q = Session.query(Comment) q = q.filter_by(status=STATUS_EXISTS) q = q.join(Change) q = q.filter(Change.entity_id==self.id) q = q.order_by(sa.asc(Comment.created_date)) return q.all()
def authenticate(username, password, redirect_after=True, from_http_auth=False): q = Session.query(users.User) q = q.filter(sa.or_(users.User.username==username, users.User.email==username)) u = q.first() if u and u.is_active and u.does_password_match(password): return login(u, redirect_after=redirect_after, from_http_auth=from_http_auth) else: raise exceptions.ClientException('Email and password do not match.', code=exceptions.MISMATCH, field='password') return None
def get_user_connections(self, status=None): """ Get all memberships in this org. """ q = Session.query(self.connection_class).filter( getattr(self.connection_class, self.object_id_name) == self.id) if status and isinstance(status, basestring): q = q.filter(self.connection_class.status == status) if status and isinstance(status, (list, tuple)): q = q.filter(self.connection_class.status.in_(status)) return q.all()
def get_invites(self, status=STATUS_PENDING, has_user=None): q = Session.query(Invite).filter_by(object_id=self.id, type=INVITE_TYPE_ORGANIZATION) if has_user == False: q = q.filter(Invite.invited_user_id==None) if has_user == True: q = q.filter(Invite.invited_user_id!=None) q = q.filter(Invite.status.in_([status])) q = q.order_by(sa.desc(Invite.created_date)) return q.all()
def last_modified(self): """ Return the most recent last_modified date, wether it is the project metadata change or one of the entities in it. """ last_changed_file = Session.query(sa.func.max(Entity.last_modified_date)).filter_by(project=self).first()[0] if last_changed_file: return max(self.last_modified_date, last_changed_file) return self.last_modified_date
def add_change(self, user, temp_contents_filepath, description): """ Introduce a new change in the given changeset using the file stored at temp_contents_filepath with the given description for the change. """ size = 0 if temp_contents_filepath: size = os.stat(temp_contents_filepath).st_size change = Change(description=description, size=size, entity=self, project=self.project, creator=user) change.digest = digests.md5_file(temp_contents_filepath) Session.add(change) Session.flush() change.set_contents(temp_contents_filepath) self.update_activity() return change
def get_invites(self, status=STATUS_PENDING, has_user=None): from desio.model.users import Invite, INVITE_TYPE_ENTITY q = Session.query(Invite).filter_by(object_id=self.id, type=INVITE_TYPE_ENTITY) if has_user == False: q = q.filter(Invite.invited_user_id==None) if has_user == True: q = q.filter(Invite.invited_user_id!=None) q = q.filter(Invite.status.in_([status])) q = q.order_by(sa.desc(Invite.created_date)) return q.all()
def create(cls, user, email, obj, role=APP_ROLE_READ): """ Invites a user to an object. Params are supposed to be: user invites email to obj with role This will find the user if he already exists. """ cls._setup_lookups() if role not in APP_ROLES: raise ex.AppException('Check your role(%s) param' % (type, role), ex.INVALID) if not obj or not user or type(obj).__name__ not in cls.put_types: raise ex.AppException('Check your user and org params. They must not be None.' % (type, role), ex.INVALID) type_ = cls.put_types[type(obj).__name__].strip() invited = Session.query(User).filter_by(email=email).first() invites = Session.query(Invite).filter_by(invited_email=email, object_id=obj.id, type=type_) invites = invites.filter(Invite.status.in_([STATUS_APPROVED, STATUS_PENDING])).first() if (invited and obj.get_role(invited)) or invites: raise ex.AppException('User has already been added to this %s' % type(obj).__name__, ex.DUPLICATE) inv = Invite(role=role, type=type_, invited_email=email, user=user, invited_user=invited, object_id=obj.id, status=STATUS_PENDING) Session.flush() Session.add(activity.InviteEvent(user, inv)) return inv
def get_user_connection(self, user, status=STATUS_APPROVED): """ Find a single user's membership within this org """ if not user: return None q = Session.query(self.connection_class).filter( self.connection_class.user_id == user.id) if status: q = q.filter(self.connection_class.status == status) return q.filter( getattr(self.connection_class, self.object_id_name) == self.id).first()
def set_completion_status(self, user, status): cs = CommentStatus(user=user, status=status, comment=self) Session.add(cs) Session.flush() Session.add(activity.CommentComplete(cs)) return cs
def get_projects(self, user): from desio.model import projects q = Session.query(projects.Project).filter_by(organization=self, status=STATUS_APPROVED) # this is kind of hairy. If org.is_read_open, the user can see all projects, otherwise, # we get based on connections #if not self.is_read_open and self.get_role(user) != APP_ROLE_ADMIN: # q = q.join(projects.ProjectUser).filter(sa.and_(projects.ProjectUser.user==user, projects.ProjectUser.status==STATUS_APPROVED)) projects = q.order_by(sa.desc(projects.Project.last_modified_date)).all() #this will return all the projects the user can see return [p for p in projects if p.get_role(user)]
def fset(self, value): if self.path and self.name: old_path = self.full_path q = Session.query(Entity).filter(Entity.path.like(old_path + '%')) entities = q.all() self._name = value new_path = self.full_path for e in entities: e.path = new_path + e.path[len(old_path):] else: self._name = value