def index():
    """List all listings tags.

    @return: HTML with the listing tags index.
    @rtype: str
    """
    config = tiny_classified.get_config()

    tags = services.listing_service.index_tags()
    categories = services.listing_service.collect_index_dict(tags, home_only=True)

    url_base = tiny_classified.get_config()["LISTING_URL_BASE"]

    html_categories = [render_html_category(url_base, cat, subcats) for cat, subcats in categories.iteritems()]

    temp_vals = tiny_classified.render_common_template_vals()
    temp_vals.update(temp_vals_extra)

    parent_template = config.get("PARENT_TEMPLATE", "tinyclassified_base.html")

    return flask.render_template(
        "public/public_index_chrome.html",
        base_url=config["BASE_URL"],
        parent_template=parent_template,
        html_categories=html_categories,
        **temp_vals
    )
    def test_send_only_plain(self):
        test_service = TestEmailService()
        self.mox.StubOutWithMock(email_service, 'get_service_client')
        email_service.get_service_client(
            tiny_classified.get_config()['EMAIL_USERNAME'],
            tiny_classified.get_config()['EMAIL_PASSWORD'],
            tiny_classified.get_config()['EMAIL_USE_SECURE'],
        ).AndReturn(test_service)
        self.mox.ReplayAll()

        email_service.send(
            ['*****@*****.**'],
            'subject',
            '**plain_body**'
        )

        message = test_service.web.message
        mesg_dict = message.__dict__
        self.assertEqual(
            mesg_dict['from_email'],
            tiny_classified.get_config()['EMAIL_FROM_ADDR']
        )
        self.assertEqual(mesg_dict['to'], ['*****@*****.**'])
        self.assertEqual(mesg_dict['subject'], 'subject')
        self.assertEqual(mesg_dict['text'], '**plain_body**')
        self.assertEqual(mesg_dict['html'], '<p><strong>plain_body</strong></p>')
def index_listings_by_slug_programmatic(slug, parent_template, temp_vals, home):
    listings = services.listing_service.list_by_slug(slug)

    slug_split = slug.split("/")
    category = slug_split[0]

    config = tiny_classified.get_config()

    if listings.count() == 0:
        return None

    listing = listings[0]
    is_qualified = services.listing_service.check_is_qualified(listing, slug)

    about = listing.get("about", None)
    if about:
        about = markdown.markdown(about)

    if listings.count() == 1 and is_qualified:
        return flask.render_template(
            "public/listing_chrome.html",
            base_url=config["BASE_URL"],
            parent_template=parent_template,
            listing=listing,
            category=category,
            about=about,
            listing_url_base=tiny_classified.get_config()["LISTING_URL_BASE"],
            admin=util.check_admin_requirement(True),
            **temp_vals
        )
    else:
        tags = listings.distinct("tags")
        tags = services.listing_service.collect_index_dict(tags, home_only=home)

        if len(slug_split) > 1:
            subcategories = []
            selected_subcategory = {"name": slug_split[1]}
        else:
            subcategories = tags[category]
            selected_subcategory = None

        url_base = config["LISTING_URL_BASE"]

        listings = list(listings)
        featured_listings = sorted(filter(lambda x: x.get("featured", False), listings), key=lambda x: x["name"])

        prep = util.prepare_subcategory
        return flask.render_template(
            "public/category_chrome.html",
            base_url=config["BASE_URL"],
            parent_template=parent_template,
            category=category,
            listings=listings,
            featured_listings=featured_listings,
            subcategories=[prep(url_base, category, x) for x in subcategories],
            selected_subcategory=selected_subcategory,
            listing_url_base=url_base,
            **temp_vals
        )
示例#4
0
    def get_database(self):
        """Get the database for the application.

        @return: Database point provided by the native pymongo.MongoClient
        @rtype: pymongo.database
        """
        app_config = tiny_classified.get_config()
        return self.client[app_config["MONGO_DATABASE_NAME"]]
示例#5
0
    def __init__(self):
        """Create a new database adapater around the database engine.

        @param client: The native database wrapper to adapt.
        @type client: flask.ext.pymongo.PyMongo
        """
        app_config = tiny_classified.get_config()
        self.client = pymongo.mongo_client.MongoClient(app_config["MONGO_URI"])
def confirm_delete():
    config = tiny_classified.get_config()
    temp_vals = tiny_classified.render_common_template_vals()
    temp_vals.update(temp_vals_extra)

    parent_template = config.get("PARENT_TEMPLATE", "tinyclassified_base.html")

    return flask.render_template(
        "public/deleted_confirmation.html", base_url=config["BASE_URL"], parent_template=parent_template, **temp_vals
    )
示例#7
0
def forgot_password():
    """Render the forgot password view with forgot password form.

    @return: The HTML forgot password view.
    @rtype: str
    """
    config = tiny_classified.get_config()
    parent_template = config.get(
        'PARENT_TEMPLATE',
        'tinyclassified_base.html'
    )
    return flask.render_template(
        'login/forgot_password.html',
        base_url=config['BASE_URL'],
        parent_template=parent_template
    )
示例#8
0
def index_tags_as_html():
    """List all unique listings tags formatted as an HTML document.

    @return: List all unique listings tags formatted as an HTML document.
    @rtype: str
    """
    tags = index_tags()
    categories = collect_index_dict(tags)

    template = None
    with open(INDEX_TEMPLATE_PATH) as f:
        template = jinja2.Template(f.read())

    return template.render({
        'categories': categories,
        'listing_url_base': tiny_classified.get_config()['LISTING_URL_BASE']
    })
示例#9
0
def collect_index_dict(taglists, home_only=True):
    """Collect the unique categories and subcategories into a dict.

    Compresses lists of listing tags into an intersection in the form of a dict.
    Unique categories are the keys of the resultant dict, which have values of
    lists of listing tag subcategories.

    Example input:
    taglists = [
        {'altcat': ['altsubcat1', 'altsubcat2']}],
        {'altcat': ['altsubcat2', 'altsubcat3']},
        {'cat': ['subcat2', 'subcat3']}
    ]

    example output:
    {
        'altcat': ['altsubcat1', 'altsubcat2', 'altsubcat3'],
        'cat': ['subcat2', 'subcat3']
    }

    @param taglists: The lists of listings tags to collect.
    @type taglists: iterable over dict
    @return: Dict which has unique categories as the keys and lists of listing
    tag subcategories as values.
    @rtype: dict
    """
    categories = {}
    for tags in taglists:
        for category, subcategories in tags.iteritems():
            if categories.get(category, None) == None:
                categories[category] = []
            for subcat in subcategories:
                if not subcat in categories[category]:
                    categories[category].append(subcat)

    if home_only:
        to_ignore =  tiny_classified.get_config()['NO_FRONT_PAGE_CATEGORIES']
        categories = dict(filter(
            lambda (key, val): key not in to_ignore,
            categories.iteritems()
        ))

    return categories
示例#10
0
def index_listings_by_slug(slug):
    """List all listings of a given slug.

    @param slug: The slug for which to list listings.
    @type slug: str
    @return: HTML with the listings belonging the the given slug.
    @rtype: str
    """
    config = tiny_classified.get_config()
    temp_vals = tiny_classified.render_common_template_vals("resources/" + slug)
    temp_vals.update(temp_vals_extra)

    parent_template = config.get("PARENT_TEMPLATE", "tinyclassified_base.html")

    result = index_listings_by_slug_programmatic(slug, parent_template, temp_vals, True)

    if not result:
        flask.abort(404)

    return result
示例#11
0
def show_user_ui():
    """Render the chrome (UI constructs) for user / author controls.

    @return: Rendered HTML template with the author control interface.
    @rtype: str
    """
    config = tiny_classified.get_config()
    temp_vals = tiny_classified.render_common_template_vals()
    parent_template = config.get(
        'PARENT_TEMPLATE',
        'tinyclassified_base.html'
    )

    listing_view_templates = flask.render_template(
        'author/listing_view.html',
        parent_template=parent_template,
        base_url=config['BASE_URL']
    )
    contacts_view_templates = flask.render_template(
        'author/contacts_view.html',
        parent_template=parent_template,
        base_url=config['BASE_URL']
    )
    listing_about_templates = flask.render_template(
        'author/listing_about.html',
        parent_template=parent_template,
        base_url=config['BASE_URL']
    )

    return flask.render_template(
        'author/author_chrome.html',
        parent_template=parent_template,
        listing_view_templates=listing_view_templates,
        contacts_view_templates=contacts_view_templates,
        listing_about_templates=listing_about_templates,
        email=flask.session[util.SESS_EMAIL],
        base_url=config['BASE_URL'],
        **temp_vals
    )
示例#12
0
def send(recipients, subject, plain_body, html_body=None):
    """Sends email message through the system-specified email service.

    @param recipients: The email addresses to send to.
    @type recipients: Iterable over str
    @param subject: The email subject line.
    @type subject: str
    @param plain_body: The plain text email body.
    @type plain_body: str
    @keyword html_body: The HTML email body.
    @type html_body: str
    """
    app_config = tiny_classified.get_config()

    if html_body == None:
        html_body = markdown.markdown(plain_body)

    if app_config['FAKE_EMAIL']:
        print '-------'
        print html_body
        print '-------'
        return

    client = get_service_client(
        app_config['EMAIL_USERNAME'],
        app_config['EMAIL_PASSWORD'],
        app_config['EMAIL_USE_SECURE']
    )

    message = sendgrid.Mail()
    message.set_from(app_config['EMAIL_FROM_ADDR'])
    message.set_subject(subject)
    message.set_html(html_body)
    message.set_text(plain_body)

    for recipient in recipients:
        message.add_to(recipient)

    client.web.send(message)
示例#13
0
def login():
    """Render the login view with login form.

    @return: The HTML login view.
    @rtype: str
    """
    flask.session[util.SESS_EMAIL] = None
    flask.session[util.SESS_IS_ADMIN] = None

    error = flask.session.get(util.SESS_VALIDATION_ERROR, None)
    if error:
        del flask.session[util.SESS_VALIDATION_ERROR]

    show_reset_password = flask.session.get(
        util.SESS_VALIDATION_SHOW_RESET, None)
    if show_reset_password:
        del flask.session[util.SESS_VALIDATION_SHOW_RESET]

    confirm = flask.session.get(util.SESS_CONFIRMATION_MSG, None)
    if confirm:
        del flask.session[util.SESS_CONFIRMATION_MSG]

    config = tiny_classified.get_config()

    temp_vals = tiny_classified.render_common_template_vals()
    parent_template = config.get(
        'PARENT_TEMPLATE',
        'tinyclassified_base.html'
    )

    return flask.render_template(
        'login/login.html',
        error=error,
        confirm=confirm,
        show_reset_password=show_reset_password,
        base_url=config['BASE_URL'],
        parent_template=parent_template,
        **temp_vals
    )
示例#14
0
 def setUp(self):
     mox.MoxTestBase.setUp(self)
     tiny_classified.get_config()['FAKE_EMAIL'] = False