def seen() -> Tuple[flask.Response, int]: """ Lists or marks the source conversation items that the journalist has seen. """ user = _authenticate_user_from_auth_header(request) if request.method == "POST": if request.json is None or not isinstance(request.json, collections.abc.Mapping): abort(400, "Please send requests in valid JSON.") if not any(map(request.json.get, ["files", "messages", "replies"])): abort(400, "Please specify the resources to mark seen.") # gather everything to be marked seen. if any don't exist, # reject the request. targets = set() # type: Set[Union[Submission, Reply]] for file_uuid in request.json.get("files", []): f = Submission.query.filter( Submission.uuid == file_uuid).one_or_none() if f is None or not f.is_file: abort(404, "file not found: {}".format(file_uuid)) targets.add(f) for message_uuid in request.json.get("messages", []): m = Submission.query.filter( Submission.uuid == message_uuid).one_or_none() if m is None or not m.is_message: abort(404, "message not found: {}".format(message_uuid)) targets.add(m) for reply_uuid in request.json.get("replies", []): r = Reply.query.filter(Reply.uuid == reply_uuid).one_or_none() if r is None: abort(404, "reply not found: {}".format(reply_uuid)) targets.add(r) # now mark everything seen. utils.mark_seen(list(targets), user) return jsonify({"message": "resources marked seen"}), 200 abort(405)
def download_single_file(filesystem_id, fn): """ Marks the file being download (the file being downloaded is either a submission message, submission file attachement, or journalist reply) as seen by the current logged-in user and send the file to a client to be saved or opened. """ if '..' in fn or fn.startswith('/'): abort(404) # mark as seen by the current user try: journalist = g.get("user") if fn.endswith("reply.gpg"): reply = Reply.query.filter(Reply.filename == fn).one() mark_seen([reply], journalist) elif fn.endswith("-doc.gz.gpg") or fn.endswith("doc.zip.gpg"): file = Submission.query.filter(Submission.filename == fn).one() mark_seen([file], journalist) else: message = Submission.query.filter( Submission.filename == fn).one() mark_seen([message], journalist) except NoResultFound as e: current_app.logger.error("Could not mark {} as seen: {}".format( fn, e)) return send_file(current_app.storage.path(filesystem_id, fn), mimetype="application/pgp-encrypted")
def bulk_setup_for_seen_only(journo: Journalist, storage: Storage) -> List[Dict]: """ Create some sources with some seen submissions that are not marked as 'downloaded' in the database and some seen replies from journo. """ setup_collection = [] for i in range(random.randint(2, 4)): collection = {} source, _ = init_source(storage) submissions = submit(storage, source, random.randint(2, 4)) half = math.ceil(len(submissions) / 2) messages = submissions[half:] files = submissions[:half] replies = reply(storage, journo, source, random.randint(1, 3)) seen_files = random.sample(files, math.ceil(len(files) / 2)) seen_messages = random.sample(messages, math.ceil(len(messages) / 2)) seen_replies = random.sample(replies, math.ceil(len(replies) / 2)) mark_seen(seen_files, journo) mark_seen(seen_messages, journo) mark_seen(seen_replies, journo) unseen_files = list(set(files).difference(set(seen_files))) unseen_messages = list(set(messages).difference(set(seen_messages))) unseen_replies = list(set(replies).difference(set(seen_replies))) not_downloaded = list( set(files + messages).difference(set(seen_files + seen_messages))) collection["source"] = source collection["seen_files"] = seen_files collection["seen_messages"] = seen_messages collection["seen_replies"] = seen_replies collection["unseen_files"] = unseen_files collection["unseen_messages"] = unseen_messages collection["unseen_replies"] = unseen_replies collection["not_downloaded"] = not_downloaded setup_collection.append(collection) return setup_collection
def download_single_file(filesystem_id: str, fn: str) -> werkzeug.Response: """ Marks the file being download (the file being downloaded is either a submission message, submission file attachement, or journalist reply) as seen by the current logged-in user and send the file to a client to be saved or opened. """ if ".." in fn or fn.startswith("/"): abort(404) file = Storage.get_default().path(filesystem_id, fn) if not Path(file).is_file(): flash( gettext( "Your download failed because the file could not be found. An admin can find " + "more information in the system and monitoring logs."), "error", ) current_app.logger.error("File {} not found".format(file)) return redirect(url_for("col.col", filesystem_id=filesystem_id)) # mark as seen by the current user try: journalist = g.get("user") if fn.endswith("reply.gpg"): reply = Reply.query.filter(Reply.filename == fn).one() mark_seen([reply], journalist) elif fn.endswith("-doc.gz.gpg") or fn.endswith("doc.zip.gpg"): submitted_file = Submission.query.filter( Submission.filename == fn).one() mark_seen([submitted_file], journalist) else: message = Submission.query.filter( Submission.filename == fn).one() mark_seen([message], journalist) except NoResultFound as e: current_app.logger.error("Could not mark {} as seen: {}".format( fn, e)) return send_file(Storage.get_default().path(filesystem_id, fn), mimetype="application/pgp-encrypted")