Esempio n. 1
0
def test_app():
    """Instantiate the app for each test with its own temporary data directory

    Each test using this fixture will use its own db.json and its own data
    directory, and then delete them.
    """
    # create a temporary file to isolate the database for each test
    app_dir = tempfile.mkdtemp()
    app.config['APP_PATH'] = app_dir
    data_dir = os.path.join(app_dir, "data")
    os.mkdir(data_dir)

    app.config['TESTING'] = True
    app.config["WTF_CSRF_ENABLED"] = False
    # This setups a TinyDB instance, using the `app_dir` temporary
    # directory defined above
    # Required so that `flask.current_app` can be called in data.py and
    # models.py
    # See https://flask.palletsprojects.com/en/1.1.x/appcontext/ for more
    # information.
    with app.app_context():
        _ = get_db()
        yield app

    # close and remove the temporary database
    shutil.rmtree(app_dir)
Esempio n. 2
0
def parse_pocket():
    db = get_db()
    pocket = db.search(Query().type == "pocket_key")[0]
    if request.args.get("new") == "1":
        auth_data = {
            "consumer_key": pocket["consumer_key"],
            "code": pocket["code"]}
        resp = requests.post(
            "https://getpocket.com/v3/oauth/authorize",
            json=auth_data,
            headers={
                "X-Accept": "application/json",
                "Content-Type": "application/json"})
        db.update(
            operations.set(
                "access_token",
                resp.json()["access_token"]),
            Query().type == "pocket_key")
        flash(f"{resp.json()['username']} Signed in!")

    # update pocket dictionary
    pocket = db.search(Query().type == "pocket_key")[0]

    pocket_data = {
        "consumer_key": pocket["consumer_key"],
        "access_token": pocket["access_token"],
        "sort": "newest"}

    # get date of latest call to pocket api
    since = datetime(1970, 1, 1)
    for post in data.get_items(
            collections=["pocket_bookmark"],
            structured=False):
        date = datetime.strptime(post["date"].replace("-", "/"), "%x")
        since = max(date, since)

    since = datetime.timestamp(since)
    if since:
        pocket_data["since"] = since
    bookmarks = requests.post(
        "https://getpocket.com/v3/get",
        json=pocket_data).json()

    # api spec: https://getpocket.com/developer/docs/v3/retrieve
    for pocket_bookmark in bookmarks["list"].values():
        if int(pocket_bookmark["status"]) != 2:
            desc = pocket_bookmark["excerpt"] if int(
                pocket_bookmark["is_article"]) else None
            bookmark = DataObj(
                desc=desc,
                url=pocket_bookmark["resolved_url"],
                date=datetime.now(),
                type="pocket_bookmarks")
            bookmark.process_bookmark_url()

            print(bookmark.insert())
    return redirect("/")
Esempio n. 3
0
def edit_user():
    form = forms.UserForm()
    if form.validate_on_submit():
        db = get_db()
        db.update(
            {
                "username": form.username.data,
                "hashed_password": generate_password_hash(form.password.data)
            },
            doc_ids=[current_user.id])
        flash("Information saved!")
        return redirect("/")
    form.username.data = current_user.username
    return render_template("users/form.html", title="Edit Profile", form=form)
Esempio n. 4
0
    def insert(self):

        if not self.password:
            return False

        hashed_password = generate_password_hash(self.password)
        db = extensions.get_db()

        if db.search((Query().type == "user")
                     & (Query().username == self.username)):
            return False
        db_user = {
            "username": self.username,
            "hashed_password": hashed_password,
            "is_admin": self.is_admin,
            "type": "user"
        }

        return db.insert(db_user)
Esempio n. 5
0
def login():
    form = forms.UserForm()
    if form.validate_on_submit():
        db = get_db()
        user = db.search((Query().username == form.username.data)
                         & (Query().type == "user"))

        if user and check_password_hash(user[0]["hashed_password"],
                                        form.password.data):
            user = User.from_db(user[0])
            login_user(user, remember=True)
            flash("Login successful!")

            next_url = request.args.get("next")
            return redirect(next_url or "/")

        flash("Invalid credentials")
        return redirect("/login")
    return render_template("users/form.html", form=form, title="Login")
Esempio n. 6
0
def pocket_fixture(test_app, mocked_responses):
    """Sets up pocket key and mocked responses for testing pocket sync

    When using this fixture, all calls to https://getpocket.com/v3/get will
    succeed and return a single article whose url is https://example.com.
    """
    with test_app.app_context():
        db = get_db()

    mocked_responses.add(responses.POST,
                         "https://getpocket.com/v3/oauth/authorize",
                         json={
                             "access_token": "5678defg-5678-defg-5678-defg56",
                             "username": "******"
                         })

    # fake /get response from pocket API
    mocked_responses.add(responses.POST,
                         "https://getpocket.com/v3/get",
                         json={
                             'status': 1,
                             'complete': 1,
                             'list': {
                                 '3088163616': {
                                     'given_url': 'https://example.com',
                                     'status': '0',
                                     'resolved_url': 'https://example.com',
                                     'excerpt': 'Lorem ipsum',
                                     'is_article': '1',
                                 },
                             },
                         })

    pocket_key = {
        "type": "pocket_key",
        "consumer_key": "1234-abcd1234abcd1234abcd1234",
        "code": "dcba4321-dcba-4321-dcba-4321dc",
    }
    db.insert(pocket_key)
    return pocket_key
Esempio n. 7
0
def pocket_settings():
    db = get_db()
    form = PocketForm()
    pocket = Query()
    if form.validate_on_submit():
        request_data = {
            "consumer_key": form.api_key.data,
            "redirect_uri": "http://localhost:5000/parse_pocket?new=1",
        }
        resp = requests.post("https://getpocket.com/v3/oauth/request",
                             json=request_data,
                             headers={
                                 "X-Accept": "application/json",
                                 "Content-Type": "application/json"
                             })
        new_data = {
            "type": "pocket_key",
            "consumer_key": form.api_key.data,
            "code": resp.json()["code"]
        }
        if db.search(pocket.type == "pocket_key"):
            db.update(new_data, pocket.type == "pocket_key")
        else:
            db.insert(new_data)
        flash("Settings Saved")
        return redirect(
            # FIXME: the redirect is forced to localhost:5000
            # but the server is started on 0.0.0.0
            # port 5000 might be on use by another resource
            # so add a check here
            f"https://getpocket.com/auth/authorize?"
            f"request_token={resp.json()['code']}"
            f"&redirect_uri=http://localhost:5000/"
            f"parse_pocket?new=1")

    return render_template("pocket/new.html",
                           title="Pocket Settings",
                           form=form)
Esempio n. 8
0
def load_user(user_id):
    db = extensions.get_db()
    res = db.get(doc_id=int(user_id))
    if res and res["type"] == "user":
        return User.from_db(res)
    return None
Esempio n. 9
0
@login_manager.user_loader
def load_user(user_id):
    db = extensions.get_db()
    res = db.get(doc_id=int(user_id))
    if res and res["type"] == "user":
        return User.from_db(res)
    return None


# prevent pytest from hanging because of running thread
if 'pytest' not in sys.argv[0]:
    Thread(target=run_watcher, args=[app]).start()

app.jinja_options["extensions"].append("jinja2.ext.do")

# create admin user if it does not exist
with app.app_context():
    db = extensions.get_db()
    user_query = Query()
    # noqa here because tinydb requires us to explicitly specify is_admin == True
    if not db.search((user_query.type == "user") & (user_query.is_admin == True)): # noqa:
        password = token_urlsafe(32)
        user = User(username="******", password=password, is_admin=True)
        if user.insert():
            app.logger.info(f"""Archivy has created an admin user as it did not exist.
                            Username: '******', password: '******'
                        """)

from archivy import routes  # noqa: