def unarchive_content( self, context, request: TracimRequest, hapic_data=None, ) -> None: """ unarchive a content """ app_config = request.registry.settings['CFG'] path_data = hapic_data.path api = ContentApi( current_user=request.current_user, session=request.dbsession, config=app_config, show_archived=True, ) content = api.get_one( path_data.content_id, content_type=ContentType.Any ) with new_revision( session=request.dbsession, tm=transaction.manager, content=content ): api.unarchive(content) return
def _get_current_content(self, user: User, workspace: Workspace, request: 'TracimRequest') -> Content: """ Get current content from request :param user: User who want to check the workspace :param workspace: Workspace of the content :param request: pyramid request :return: current content """ content_id = '' try: if 'content_id' in request.matchdict: content_id_str = request.matchdict['content_id'] if not isinstance( content_id_str, str) or not content_id_str.isdecimal(): # nopep8 raise InvalidContentId( 'content_id is not a correct integer') # nopep8 content_id = int(request.matchdict['content_id']) if not content_id: raise ContentNotFoundInTracimRequest( 'No content_id property found in request') # nopep8 api = ContentApi(current_user=user, session=request.dbsession, config=request.registry.settings['CFG']) content = api.get_one(content_id=content_id, workspace=workspace, content_type=ContentType.Any) # nopep8 except NoResultFound as exc: raise ContentNotFound( 'Content {} does not exist ' 'or is not visible for this user'.format(content_id)) from exc return content
def workspace_content( self, context, request: TracimRequest, hapic_data=None, ) -> typing.List[ContentInContext]: """ return list of contents found in the workspace """ app_config = request.registry.settings['CFG'] content_filter = hapic_data.query api = ContentApi( current_user=request.current_user, session=request.dbsession, config=app_config, show_archived=content_filter.show_archived, show_deleted=content_filter.show_deleted, show_active=content_filter.show_active, ) contents = api.get_all( parent_id=content_filter.parent_id, workspace=request.current_workspace, content_type=content_filter.content_type or ContentType.Any, ) contents = [ api.get_content_in_context(content) for content in contents ] return contents
def contents_read_status(self, context, request: TracimRequest, hapic_data=None): # nopep8 """ get user_read status of contents """ app_config = request.registry.settings['CFG'] content_filter = hapic_data.query api = ContentApi( current_user=request.candidate_user, # User session=request.dbsession, config=app_config, ) wapi = WorkspaceApi( current_user=request.candidate_user, # User session=request.dbsession, config=app_config, ) workspace = None if hapic_data.path.workspace_id: workspace = wapi.get_one(hapic_data.path.workspace_id) last_actives = api.get_last_active( workspace=workspace, limit=None, before_datetime=None, content_ids=hapic_data.query.contents_ids or None) return [ api.get_content_in_context(content) for content in last_actives ]
def __init__(self, path, environ, workspace: Workspace, user: User, session: Session, content: Content=None, type: str=HistoryType.Standard ) -> None: super(HistoryFolderResource, self).__init__( path=path, environ=environ, workspace=workspace, content=content, user=user, session=session, ) self._is_archived = type == HistoryType.Archived self._is_deleted = type == HistoryType.Deleted self.content_api = ContentApi( current_user=self.user, show_archived=self._is_archived, show_deleted=self._is_deleted, session=self.session, config=self.provider.app_config, )
def sized_preview_jpg_revision(self, context, request: TracimRequest, hapic_data=None): # nopep8 """ Obtain resized jpg preview of a specific revision of content. """ app_config = request.registry.settings['CFG'] api = ContentApi( current_user=request.current_user, session=request.dbsession, config=app_config, ) content = api.get_one(hapic_data.path.content_id, content_type=ContentType.Any) revision = api.get_one_revision( revision_id=hapic_data.path.revision_id, content=content) jpg_preview_path = api.get_jpg_preview_path( content_id=content.content_id, revision_id=revision.revision_id, page=hapic_data.query.page, height=hapic_data.path.height, width=hapic_data.path.width, ) return FileResponse(jpg_preview_path)
def upload_file(self, context, request: TracimRequest, hapic_data=None): """ Upload a new version of raw file of content. This will create a new revision. """ app_config = request.registry.settings['CFG'] api = ContentApi( current_user=request.current_user, session=request.dbsession, config=app_config, ) content = api.get_one(hapic_data.path.content_id, content_type=ContentType.Any) file = request.POST['files'] with new_revision(session=request.dbsession, tm=transaction.manager, content=content): api.update_file_data( content, new_filename=file.filename, new_mimetype=file.type, new_content=file.file, ) return
def test_func__create_new_content_with_notification__ok__nominal_case(self): uapi = UserApi( current_user=None, session=self.session, config=self.app_config, ) current_user = uapi.get_one_by_email('*****@*****.**') # Create new user with notification enabled on w1 workspace wapi = WorkspaceApi( current_user=current_user, session=self.session, config=self.app_config, ) workspace = wapi.get_one_by_label('Recipes') user = uapi.get_one_by_email('*****@*****.**') wapi.enable_notifications(user, workspace) api = ContentApi( current_user=user, session=self.session, config=self.app_config, ) item = api.create( ContentType.Folder, workspace, None, 'parent', do_save=True, do_notify=False, ) item2 = api.create( ContentType.File, workspace, item, 'file1', do_save=True, do_notify=True, ) # Send mail async from redis queue redis = get_redis_connection( self.app_config ) queue = get_rq_queue( redis, 'mail_sender', ) worker = SimpleWorker([queue], connection=queue.connection) worker.work(burst=True) # check mail received response = requests.get('http://127.0.0.1:8025/api/v1/messages') response = response.json() headers = response[0]['Content']['Headers'] assert headers['From'][0] == '"Bob i. via Tracim" <test_user_from+3@localhost>' # nopep8 assert headers['To'][0] == 'Global manager <*****@*****.**>' assert headers['Subject'][0] == '[TRACIM] [Recipes] file1 (Open)' assert headers['References'][0] == 'test_user_refs+22@localhost' assert headers['Reply-to'][0] == '"Bob i. & all members of Recipes" <test_user_reply+22@localhost>' # nopep8
def exists(self, path, environ) -> bool: """ Called by wsgidav to check if a certain path is linked to a _DAVResource """ path = normpath(path) working_path = self.reduce_path(path) root_path = environ['http_authenticator.realm'] parent_path = dirname(working_path) user = environ['tracim_user'] session = environ['tracim_dbsession'] if path == root_path: return True workspace = self.get_workspace_from_path( path, WorkspaceApi( current_user=user, session=session, config=self.app_config, ) ) if parent_path == root_path or workspace is None: return workspace is not None # TODO bastien: Arnaud avait mis a True, verif le comportement # lorsque l'on explore les dossiers archive et deleted content_api = ContentApi( current_user=user, session=session, config=self.app_config, show_archived=False, show_deleted=False ) revision_id = re.search(r'/\.history/[^/]+/\((\d+) - [a-zA-Z]+\) ([^/].+)$', path) is_archived = self.is_path_archive(path) is_deleted = self.is_path_delete(path) if revision_id: revision_id = revision_id.group(1) content = content_api.get_one_revision(revision_id) else: content = self.get_content_from_path(working_path, content_api, workspace) return content is not None \ and content.is_deleted == is_deleted \ and content.is_archived == is_archived
def update_file_info(self, context, request: TracimRequest, hapic_data=None) -> ContentInContext: # nopep8 """ update thread """ app_config = request.registry.settings['CFG'] api = ContentApi( current_user=request.current_user, session=request.dbsession, config=app_config, ) content = api.get_one(hapic_data.path.content_id, content_type=ContentType.Any) with new_revision(session=request.dbsession, tm=transaction.manager, content=content): api.update_content( item=content, new_label=hapic_data.body.label, new_content=hapic_data.body.raw_content, ) api.save(content) return api.get_content_in_context(content)
def set_content_as_unread(self, context, request: TracimRequest, hapic_data=None): # nopep8 """ set user_read status of content to unread """ app_config = request.registry.settings['CFG'] api = ContentApi( current_user=request.candidate_user, session=request.dbsession, config=app_config, ) api.mark_unread(request.current_content, do_flush=True) return
def get_html_document(self, context, request: TracimRequest, hapic_data=None) -> ContentInContext: # nopep8 """ Get html document content """ app_config = request.registry.settings['CFG'] api = ContentApi( current_user=request.current_user, session=request.dbsession, config=app_config, ) content = api.get_one( hapic_data.path.content_id, content_type=ContentType.Any ) return api.get_content_in_context(content)
def set_workspace_as_read(self, context, request: TracimRequest, hapic_data=None): # nopep8 """ set user_read status of all content of workspace to read """ app_config = request.registry.settings['CFG'] api = ContentApi( current_user=request.candidate_user, session=request.dbsession, config=app_config, ) api.mark_read__workspace(request.current_workspace) return
def allowed_dim_preview_jpg(self, context, request: TracimRequest, hapic_data=None): # nopep8 """ Get allowed dimensions of jpg preview. If restricted is true, only those dimensions are strictly accepted. """ app_config = request.registry.settings['CFG'] api = ContentApi( current_user=request.current_user, session=request.dbsession, config=app_config, ) return api.get_jpg_preview_allowed_dim()
def preview_pdf(self, context, request: TracimRequest, hapic_data=None): """ Obtain a specific page pdf preview of last revision of content. """ app_config = request.registry.settings['CFG'] api = ContentApi( current_user=request.current_user, session=request.dbsession, config=app_config, ) content = api.get_one(hapic_data.path.content_id, content_type=ContentType.Any) pdf_preview_path = api.get_pdf_preview_path(content.content_id, content.revision_id, page=hapic_data.query.page) return FileResponse(pdf_preview_path)
def download_file(self, context, request: TracimRequest, hapic_data=None): """ Download raw file of last revision of content. """ app_config = request.registry.settings['CFG'] api = ContentApi( current_user=request.current_user, session=request.dbsession, config=app_config, ) content = api.get_one(hapic_data.path.content_id, content_type=ContentType.Any) file = DepotManager.get().get(content.depot_file) response = request.response response.content_type = file.content_type response.app_iter = FileIter(file) return response
def preview_pdf_full(self, context, request: TracimRequest, hapic_data=None): # nopep8 """ Obtain a full pdf preview (all page) of last revision of content. """ app_config = request.registry.settings['CFG'] api = ContentApi( current_user=request.current_user, session=request.dbsession, config=app_config, ) content = api.get_one(hapic_data.path.content_id, content_type=ContentType.Any) pdf_preview_path = api.get_full_pdf_preview_path(content.revision_id) return FileResponse(pdf_preview_path)
def set_html_document_status( self, context, request: TracimRequest, hapic_data=None ) -> None: """ set html_document status """ app_config = request.registry.settings['CFG'] api = ContentApi( current_user=request.current_user, session=request.dbsession, config=app_config, ) content = api.get_one( hapic_data.path.content_id, content_type=ContentType.Any ) with new_revision( session=request.dbsession, tm=transaction.manager, content=content ): api.set_status( content, hapic_data.body.status, ) api.save(content) return
def create_generic_empty_content( self, context, request: TracimRequest, hapic_data=None, ) -> ContentInContext: """ create a generic empty content """ app_config = request.registry.settings['CFG'] creation_data = hapic_data.body api = ContentApi( current_user=request.current_user, session=request.dbsession, config=app_config ) parent = None if creation_data.parent_id: try: parent = api.get_one(content_id=creation_data.parent_id, content_type=ContentType.Any) # nopep8 except ContentNotFound as exc: raise ParentNotFound( 'Parent with content_id {} not found'.format(creation_data.parent_id) ) from exc content = api.create( label=creation_data.label, content_type=creation_data.content_type, workspace=request.current_workspace, parent=parent, ) api.save(content, ActionDescription.CREATION) content = api.get_content_in_context(content) return content
def __init__( self, path: str, environ: dict, content: Content, user: User, session: Session, ) -> None: super(FileResource, self).__init__(path, environ) self.content = content self.user = user self.session = session self.content_api = ContentApi( current_user=self.user, config=self.provider.app_config, session=self.session, )
def test_children(self): admin = self.session.query(User).filter( User.email == '*****@*****.**').one() self._create_thread_and_test(workspace_name='workspace_1', folder_name='folder_1', thread_name='thread_1', user=admin) workspace = self.session.query(Workspace).filter( Workspace.label == 'workspace_1').one() content_api = ContentApi( session=self.session, current_user=admin, config=self.app_config, ) folder = content_api.get_canonical_query().filter( Content.label == 'folder_1').one() eq_([ folder, ], list(workspace.get_valid_children()))
def get_file_revisions(self, context, request: TracimRequest, hapic_data=None) -> typing.List[RevisionInContext]: """ get file revisions """ app_config = request.registry.settings['CFG'] api = ContentApi( current_user=request.current_user, session=request.dbsession, config=app_config, ) content = api.get_one(hapic_data.path.content_id, content_type=ContentType.Any) revisions = content.revisions return [ api.get_revision_in_context(revision) for revision in revisions ]
def add_comment(self, context, request: TracimRequest, hapic_data=None): """ Add new comment """ # login = hapic_data.body app_config = request.registry.settings['CFG'] api = ContentApi( current_user=request.current_user, session=request.dbsession, config=app_config, ) content = api.get_one(hapic_data.path.content_id, content_type=ContentType.Any) comment = api.create_comment( content.workspace, content, hapic_data.body.raw_content, do_save=True, ) return api.get_content_in_context(comment)
def content_comments(self, context, request: TracimRequest, hapic_data=None): """ Get all comments related to a content in asc order (first is the oldest) """ # login = hapic_data.body app_config = request.registry.settings['CFG'] api = ContentApi( current_user=request.current_user, session=request.dbsession, config=app_config, ) content = api.get_one(hapic_data.path.content_id, content_type=ContentType.Any) comments = content.get_comments() comments.sort(key=lambda comment: comment.created) return [api.get_content_in_context(comment) for comment in comments]
def __init__(self, path: str, environ: dict, workspace: Workspace, user: User, session: Session ) -> None: super(WorkspaceResource, self).__init__(path, environ) self.workspace = workspace self.content = None self.user = user self.session = session self.content_api = ContentApi( current_user=self.user, session=session, config=self.provider.app_config, show_temporary=True ) self._file_count = 0
def preview_jpg(self, context, request: TracimRequest, hapic_data=None): """ Obtain normally sied jpg preview of last revision of content. """ app_config = request.registry.settings['CFG'] api = ContentApi( current_user=request.current_user, session=request.dbsession, config=app_config, ) content = api.get_one(hapic_data.path.content_id, content_type=ContentType.Any) allowed_dim = api.get_jpg_preview_allowed_dim() jpg_preview_path = api.get_jpg_preview_path( content_id=content.content_id, revision_id=content.revision_id, page=hapic_data.query.page, width=allowed_dim.dimensions[0].width, height=allowed_dim.dimensions[0].height, ) return FileResponse(jpg_preview_path)
def delete_comment(self, context, request: TracimRequest, hapic_data=None): """ Delete comment """ app_config = request.registry.settings['CFG'] api = ContentApi( current_user=request.current_user, session=request.dbsession, config=app_config, ) wapi = WorkspaceApi( current_user=request.current_user, session=request.dbsession, config=app_config, ) workspace = wapi.get_one(hapic_data.path.workspace_id) parent = api.get_one(hapic_data.path.content_id, content_type=ContentType.Any, workspace=workspace) comment = api.get_one( hapic_data.path.comment_id, content_type=ContentType.Comment, workspace=workspace, parent=parent, ) with new_revision(session=request.dbsession, tm=transaction.manager, content=comment): api.delete(comment) return
def _create_content_and_test(self, name, workspace, *args, **kwargs) -> Content: """ All extra parameters (*args, **kwargs) are for Content init :return: Created Content instance """ content = Content(*args, **kwargs) content.label = name content.workspace = workspace self.session.add(content) self.session.flush() content_api = ContentApi( current_user=None, session=self.session, config=self.app_config, ) eq_( 1, content_api.get_canonical_query().filter( Content.label == name).count()) return content_api.get_canonical_query().filter( Content.label == name).one()
def copyMoveSingle(self, destpath, isMove): if isMove: # INFO - G.M - 12-03-2018 - This case should not happen # As far as moveRecursive method exist, all move should not go # through this method. If such case appear, try replace this to : #### # self.move_file(destpath) # return #### raise NotImplemented new_file_name = None new_file_extension = None # Inspect destpath if basename(destpath) != self.getDisplayName(): new_given_file_name = transform_to_bdd(basename(destpath)) new_file_name, new_file_extension = \ os.path.splitext(new_given_file_name) workspace_api = WorkspaceApi( current_user=self.user, session=self.session, config=self.provider.app_config, ) content_api = ContentApi( current_user=self.user, session=self.session, config=self.provider.app_config ) destination_workspace = self.provider.get_workspace_from_path( destpath, workspace_api, ) destination_parent = self.provider.get_parent_from_path( destpath, content_api, destination_workspace, ) workspace = self.content.workspace parent = self.content.parent new_content = self.content_api.copy( item=self.content, new_label=new_file_name, new_parent=destination_parent, ) self.content_api.copy_children(self.content, new_content) transaction.commit()
def move_content( self, context, request: TracimRequest, hapic_data=None, ) -> ContentInContext: """ move a content """ app_config = request.registry.settings['CFG'] path_data = hapic_data.path move_data = hapic_data.body api = ContentApi( current_user=request.current_user, session=request.dbsession, config=app_config, ) content = api.get_one( path_data.content_id, content_type=ContentType.Any ) new_parent = api.get_one( move_data.new_parent_id, content_type=ContentType.Any ) new_workspace = request.candidate_workspace with new_revision( session=request.dbsession, tm=transaction.manager, content=content ): api.move( content, new_parent=new_parent, new_workspace=new_workspace, must_stay_in_same_workspace=False, ) updated_content = api.get_one( path_data.content_id, content_type=ContentType.Any ) return api.get_content_in_context(updated_content)