text:
from __future__ import absolute_import, division, print_function, unicode_literals

import time
import unittest
import logging
import functools

from nose.tools import *  # flake8: noqa (PEP8 asserts)
import mock

from framework.auth.core import Auth

from website import settings
import website.search.search as search
from website.search import elastic_search
from website.search.util import build_query
from website.search_migration.migrate import migrate
from osf.models import Retraction, NodeLicense, Tag, QuickFilesNode
from addons.osfstorage.models import OsfStorageFile

from scripts.populate_institutions import main as populate_institutions

from osf_tests import factories
from tests.base import OsfTestCase
from tests.test_features import requires_search
from tests.utils import mock_archive, run_celery_tasks

TEST_INDEX = 'test'

def query(term):
    results = search.search(build_query(term), index=elastic_search.INDEX)
    return results

def query_user(name):
    term = 'category:user AND "{}"'.format(name)
    return query(term)

def query_file(name):
    term = 'category:file AND "{}"'.format(name)
    return query(term)

def query_tag_file(name):
    term = 'category:file AND (tags:u"{}")'.format(name)
    return query(term)

def retry_assertion(interval=0.3, retries=3):
    def test_wrapper(func):
        t_interval = interval
        t_retries = retries
        @functools.wraps(func)
        def wrapped(*args, **kwargs):
            try:
                func(*args, **kwargs)
            except AssertionError as e:
                if retries:
                    time.sleep(t_interval)
                    retry_assertion(interval=t_interval, retries=t_retries - 1)(func)(*args, **kwargs)
                else:
                    raise e
        return wrapped
    return test_wrapper

class TestUserUpdate(OsfTestCase):

    def setUp(self):
        super(TestUserUpdate, self).setUp()
        search.delete_index(elastic_search.INDEX)
        search.create_index(elastic_search.INDEX)
        self.user = factories.UserFactory(fullname='David Bowie')

    def test_new_user(self):
        # Verify that user has been added to Elastic Search
        docs = query_user(self.user.fullname)['results']
        assert_equal(len(docs), 1)

    def test_new_user_unconfirmed(self):
        user = factories.UnconfirmedUserFactory()
        docs = query_user(user.fullname)['results']
        assert_equal(len(docs), 0)
        token = user.get_confirmation_token(user.username)
        user.confirm_email(token)
        user.save()
        docs = query_user(user.fullname)['results']
        assert_equal(len(docs), 1)

    def test_change_name(self):
        # Add a user, change her name, and verify that only the new name is
        # found in search.
        user = factories.UserFactory(fullname='Barry Mitchell')
        fullname_original = user.fullname
        user.fullname = user.fullname[::-1]
        user.save()

        docs_original = query_user(fullname_original)['results']
        assert_equal(len(docs_original), 0)

        docs_current = query_user(user.fullname)['results']
        assert_equal(len(docs_current), 1)

    def test_disabled_user(self):
        # Test that disabled users are not in search index

        user = factories.UserFactory(fullname='Bettie Page')
        user.save()

        # Ensure user is in search index
        assert_equal(len(query_user(user.fullname)['results']), 1)

        # Disable the user
        user.is_disabled = True
        user.save()

        # Ensure user is not in search index
        assert_equal(len(query_user(user.fullname)['results']), 0)

    def test_merged_user(self):
        user = factories.UserFactory(fullname='Annie Lennox')
        merged_user = factories.UserFactory(fullname='Lisa Stansfield')
        user.save()
        merged_user.save()
        assert_equal(len(query_user(user.fullname)['results']), 1)
        assert_equal(len(query_user(merged_user.fullname)['results']), 1)

        user.merge_user(merged_user)

        assert_equal(len(query_user(user.fullname)['results']), 1)
        assert_equal(len(query_user(merged_user.fullname)['results']), 0)

    def test_employment(self):
        user = factories.UserFactory(fullname='Helga Finn')
        user.save()
        institution = 'Finn\'s Fine Filers'

        docs = query_user(institution)['results']
        assert_equal(len(docs), 0)
        user.jobs.append({
            'institution': institution,
            'title': 'The Big Finn',
        })
        user.save()

        docs = query_user(institution)['results']
        assert_equal(len(docs), 1)

    def test_education(self):
        user = factories.UserFactory(fullname='Henry Johnson')
        user.save()
        institution = 'Henry\'s Amazing School!!!'

        docs = query_user(institution)['results']
        assert_equal(len(docs), 0)
        user.schools.append({
            'institution': institution,
            'degree': 'failed all classes',
        })
        user.save()

        docs = query_user(institution)['results']
        assert_equal(len(docs), 1)

    def test_name_fields(self):
        names = ['Bill Nye', 'William', 'the science guy', 'Sanford', 'the Great']
        user = factories.UserFactory(fullname=names[0])
        user.given_name = names[1]
        user.middle_names = names[2]
        user.family_name = names[3]
        user.suffix = names[4]
        user.save()
        docs = [query_user(name)['results'] for name in names]
        assert_equal(sum(map(len, docs)), len(docs))  # 1 result each
        assert_true(all([user._id == doc[0]['id'] for doc in docs]))

class TestProject(OsfTestCase):

    def setUp(self):
        super(TestProject, self).setUp()
        search.delete_index(elastic_search.INDEX)
        search.create_index(elastic_search.INDEX)
        self.user = factories.UserFactory(fullname='John Deacon')
        self.project = factories.ProjectFactory(title='Red Special', creator=self.user)

    def test_new_project_private(self):
        # Verify that a private project is not present in Elastic Search.
        docs = query(self.project.title)['results']
        assert_equal(len(docs), 0)

    def test_make_public(self):
        # Make project public, and verify that it is present in Elastic
        # Search.
        with run_celery_tasks():
            self.project.set_privacy('public')
        docs = query(self.project.title)['results']
        assert_equal(len(docs), 1)

class TestNodeSearch(OsfTestCase):

    def setUp(self):
        super(TestNodeSearch, self).setUp()
        with run_celery_tasks():
            self.node = factories.ProjectFactory(is_public=True, title='node')
            self.public_child = factories.ProjectFactory(parent=self.node, is_public=True, title='public_child')
            self.private_child = factories.ProjectFactory(parent=self.node, title='private_child')
            self.public_subchild = factories.ProjectFactory(parent=self.private_child, is_public=True)
            self.node.node_license = factories.NodeLicenseRecordFactory()
            self.node.save()

        self.query = 'category:project & category:component'

    @retry_assertion()
    def test_node_license_added_to_search(self):
        docs = query(self.query)['results']
        node = [d for d in docs if d['title'] == self.node.title][0]
        assert_in('license', node)
        assert_equal(node['license']['id'], self.node.node_license.license_id)

    @unittest.skip("Elasticsearch latency seems to be causing theses tests to fail randomly.")
    @retry_assertion(retries=10)
    def test_node_license_propogates_to_children(self):
        docs = query(self.query)['results']
        child = [d for d in docs if d['title'] == self.public_child.title][0]
        assert_in('license', child)
        assert_equal(child['license'].get('id'), self.node.node_license.license_id)
        child = [d for d in docs if d['title'] == self.public_subchild.title][0]
        assert_in('license', child)
        assert_equal(child['license'].get('id'), self.node.node_license.license_id)

    @unittest.skip("Elasticsearch latency seems to be causing theses tests to fail randomly.")
    @retry_assertion(retries=10)
    def test_node_license_updates_correctly(self):
        other_license = NodeLicense.objects.get(name='MIT License')
        new_license = factories.NodeLicenseRecordFactory(node_license=other_license)
        self.node.node_license = new_license
        self.node.save()
        docs = query(self.query)['results']
        for doc in docs:
            assert_equal(doc['license'].get('id'), new_license.license_id)

class TestRegistrationRetractions(OsfTestCase):

    def setUp(self):
        super(TestRegistrationRetractions, self).setUp()
        self.user = factories.UserFactory(fullname='Doug Bogie')
        self.title = 'Red Special'
        self.consolidate_auth = Auth(user=self.user)
        self.project = factories.ProjectFactory(
            title=self.title,
            creator=self.user,
            is_public=True,
        )
        self.registration = factories.RegistrationFactory(project=self.project, is_public=True)

    @mock.patch('website.project.tasks.update_node_share')
    @mock.patch('osf.models.registrations.Registration.archiving', mock.PropertyMock(return_value=False))
    def test_retraction_is_searchable(self, mock_registration_updated):
        self.registration.retract_registration(self.user)
        self.registration.retraction.state = Retraction.APPROVED
        self.registration.retraction.save()
        self.registration.save()
        self.registration.retraction._on_complete(self.user)
        docs = query('category:registration AND ' + self.title)['results']
        assert_equal(len(docs), 1)

    @mock.patch('osf.models.registrations.Registration.archiving', mock.PropertyMock(return_value=False))
    def test_pending_retraction_wiki_content_is_searchable(self):
        # Add unique string to wiki
        wiki_content = {'home': 'public retraction test'}
        for key, value in wiki_content.items():
            docs = query(value)['results']
            assert_equal(len(docs), 0)
            with run_celery_tasks():
                self.registration.create_or_update_node_wiki(name=key, content=value, auth=self.consolidate_auth)
            # Query and ensure unique string shows up
            docs = query(value)['results']
            assert_equal(len(docs), 1)

        # Query and ensure registration does show up
        docs = query('category:registration AND ' + self.title)['results']
        assert_equal(len(docs), 1)

        # Retract registration
        self.registration.retract_registration(self.user, '')
        with run_celery_tasks():
            self.registration.save()
            self.registration.reload()

        # Query and ensure unique string in wiki doesn't show up
        docs = query('category:registration AND "{}"'.format(wiki_content['home']))['results']
        assert_equal(len(docs), 1)

        # Query and ensure registration does show up
        docs = query('category:registration AND ' + self.title)['results']
        assert_equal(len(docs), 1)

    @mock.patch('osf.models.registrations.Registration.archiving', mock.PropertyMock(return_value=False))
    def test_retraction_wiki_content_is_not_searchable(self):
        # Add unique string to wiki
        wiki_content = {'home': 'public retraction test'}
        for key, value in wiki_content.items():
            docs = query(value)['results']
            assert_equal(len(docs), 0)
            with run_celery_tasks():
                self.registration.create_or_update_node_wiki(name=key, content=value, auth=self.consolidate_auth)
            # Query and ensure unique string shows up
            docs = query(value)['results']
            assert_equal(len(docs), 1)

        # Query and ensure registration does show up
        docs = query('category:registration AND ' + self.title)['results']
        assert_equal(len(docs), 1)

        # Retract registration
        self.registration.retract_registration(self.user, '')
        self.registration.retraction.state = Retraction.APPROVED
        with run_celery_tasks():
            self.registration.retraction.save()
            self.registration.save()
            self.registration.update_search()

        # Query and ensure unique string in wiki doesn't show up
        docs = query('category:registration AND "{}"'.format(wiki_content['home']))['results']
        assert_equal(len(docs), 0)

        # Query and ensure registration does show up
        docs = query('category:registration AND ' + self.title)['results']
        assert_equal(len(docs), 1)

class TestPublicNodes(OsfTestCase):

    def setUp(self):
        with run_celery_tasks():
            super(TestPublicNodes, self).setUp()
            self.user = factories.UserFactory(fullname='Doug Bogie')
            self.title = 'Red Special'
            self.consolidate_auth = Auth(user=self.user)
            self.project = factories.ProjectFactory(
                title=self.title,
                creator=self.user,
                is_public=True,
            )
            self.component = factories.NodeFactory(
                parent=self.project,
                title=self.title,
                creator=self.user,
                is_public=True
            )
            self.registration = factories.RegistrationFactory(
                title=self.title,
                creator=self.user,
                is_public=True,
            )
            self.registration.archive_job.target_addons = []
            self.registration.archive_job.status = 'SUCCESS'
            self.registration.archive_job.save()

    def test_make_private(self):
        # Make project public, then private, and verify that it is not present
        # in search.
        with run_celery_tasks():
            self.project.set_privacy('private')
        docs = query('category:project AND ' + self.title)['results']
        assert_equal(len(docs), 0)

        with run_celery_tasks():
            self.component.set_privacy('private')
        docs = query('category:component AND ' + self.title)['results']
        assert_equal(len(docs), 0)

    def test_search_node_partial(self):
        self.project.set_title('Blue Rider-Express', self.consolidate_auth)
        with run_celery_tasks():
            self.project.save()
        find = query('Blue')['results']
        assert_equal(len(find), 1)

    def test_search_node_partial_with_sep(self):
        self.project.set_title('Blue Rider-Express', self.consolidate_auth)
        with run_celery_tasks():
            self.project.save()
        find = query('Express')['results']
        assert_equal(len(find), 1)

    def test_search_node_not_name(self):
        self.project.set_title('Blue Rider-Express', self.consolidate_auth)
        with run_celery_tasks():
            self.project.save()
        find = query('Green Flyer-Slow')['results']
        assert_equal(len(find), 0)

    def test_public_parent_title(self):
        self.project.set_title('hello & world', self.consolidate_auth)
        with run_celery_tasks():
            self.project.save()
        docs = query('category:component AND ' + self.title)['results']
        assert_equal(len(docs), 1)
        assert_equal(docs[0]['parent_title'], 'hello & world')
        assert_true(docs[0]['parent_url'])

    def test_make_parent_private(self):
        # Make parent of component, public, then private, and verify that the
        # component still appears but doesn't link to the parent in search.
        with run_celery_tasks():
            self.project.set_privacy('private')
        docs = query('category:component AND ' + self.title)['results']
        assert_equal(len(docs), 1)
        assert_false(docs[0]['parent_title'])
        assert_false(docs[0]['parent_url'])

    def test_delete_project(self):
        with run_celery_tasks():
            self.component.remove_node(self.consolidate_auth)
        docs = query('category:component AND ' + self.title)['results']
        assert_equal(len(docs), 0)

        with run_celery_tasks():
            self.project.remove_node(self.consolidate_auth)
        docs = query('category:project AND ' + self.title)['results']
        assert_equal(len(docs), 0)

    def test_change_title(self):
        title_original = self.project.title
        with run_celery_tasks():
            self.project.set_title(
                'Blue Ordinary', self.consolidate_auth, save=True
            )

        docs = query('category:project AND ' + title_original)['results']
        assert_equal(len(docs), 0)

        docs = query('category:project AND ' + self.project.title)['results']
        assert_equal(len(docs), 1)

    def test_add_tags(self):

        tags = ['stonecoldcrazy', 'just a poor boy', 'from-a-poor-family']

        with run_celery_tasks():
            for tag in tags:
                docs = query('tags:"{}"'.format(tag))['results']
                assert_equal(len(docs), 0)
                self.project.add_tag(tag, self.consolidate_auth, save=True)

        for tag in tags:
            docs = query('tags:"{}"'.format(tag))['results']
            assert_equal(len(docs), 1)

    def test_remove_tag(self):

        tags = ['stonecoldcrazy', 'just a poor boy', 'from-a-poor-family']

        for tag in tags:
            self.project.add_tag(tag, self.consolidate_auth, save=True)
            self.project.remove_tag(tag, self.consolidate_auth, save=True)
            docs = query('tags:"{}"'.format(tag))['results']
            assert_equal(len(docs), 0)

    def test_update_wiki(self):
        """Add text to a wiki page, then verify that project is found when
        searching for wiki text.

        """
        wiki_content = {
            'home': 'Hammer to fall',
            'swag': '#YOLO'
        }
        for key, value in wiki_content.items():
            docs = query(value)['results']
            assert_equal(len(docs), 0)
            with run_celery_tasks():
                self.project.update_node_wiki(
                    key, value, self.consolidate_auth,
                )
            docs = query(value)['results']
            assert_equal(len(docs), 1)

    def test_clear_wiki(self):
        # Add wiki text to page, then delete, then verify that project is not
        # found when searching for wiki text.
        wiki_content = 'Hammer to fall'
        self.project.update_node_wiki(
            'home', wiki_content, self.consolidate_auth,
        )
        with run_celery_tasks():
            self.project.update_node_wiki('home', '', self.consolidate_auth)

        docs = query(wiki_content)['results']
        assert_equal(len(docs), 0)

    def test_add_contributor(self):
        # Add a contributor, then verify that project is found when searching
        # for contributor.
        user2 = factories.UserFactory(fullname='Adam Lambert')

        docs = query('category:project AND "{}"'.format(user2.fullname))['results']
        assert_equal(len(docs), 0)
        with run_celery_tasks():
            self.project.add_contributor(user2, save=True)

        docs = query('category:project AND "{}"'.format(user2.fullname))['results']
        assert_equal(len(docs), 1)

    def test_remove_contributor(self):
        # Add and remove a contributor, then verify that project is not found
        # when searching for contributor.
        user2 = factories.UserFactory(fullname='Brian May')

        self.project.add_contributor(user2, save=True)
        self.project.remove_contributor(user2, self.consolidate_auth)

        docs = query('category:project AND "{}"'.format(user2.fullname))['results']
        assert_equal(len(docs), 0)

    def test_hide_contributor(self):
        user2 = factories.UserFactory(fullname='Brian May')
        self.project.add_contributor(user2)
        with run_celery_tasks():
            self.project.set_visible(user2, False, save=True)
        docs = query('category:project AND "{}"'.format(user2.fullname))['results']
        assert_equal(len(docs), 0)
        with run_celery_tasks():
            self.project.set_visible(user2, True, save=True)
        docs = query('category:project AND "{}"'.format(user2.fullname))['results']
        assert_equal(len(docs), 1)

    def test_wrong_order_search(self):
        title_parts = self.title.split(' ')
        title_parts.reverse()
        title_search = ' '.join(title_parts)

        docs = query(title_search)['results']
        assert_equal(len(docs), 3)

    def test_tag_aggregation(self):
        tags = ['stonecoldcrazy', 'just a poor boy', 'from-a-poor-family']

        with run_celery_tasks():
            for tag in tags:
                self.project.add_tag(tag, self.consolidate_auth, save=True)

        docs = query(self.title)['tags']
        assert len(docs) == 3
        for doc in docs:
            assert doc['key'] in tags

class TestAddContributor(OsfTestCase):
    # Tests of the search.search_contributor method

    def setUp(self):
        self.name1 = 'Roger1 Taylor1'
        self.name2 = 'John2 Deacon2'
        self.name3 = u'j\xc3\xb3ebert3 Smith3'
        self.name4 = u'B\xc3\xb3bbert4 Jones4'

        with run_celery_tasks():
            super(TestAddContributor, self).setUp()
            self.user = factories.UserFactory(fullname=self.name1)
            self.user3 = factories.UserFactory(fullname=self.name3)

    def test_unreg_users_dont_show_in_search(self):
        unreg = factories.UnregUserFactory()
        contribs = search.search_contributor(unreg.fullname)
        assert_equal(len(contribs['users']), 0)

    def test_unreg_users_do_show_on_projects(self):
        with run_celery_tasks():
            unreg = factories.UnregUserFactory(fullname='Robert Paulson')
            self.project = factories.ProjectFactory(
                title='Glamour Rock',
                creator=unreg,
                is_public=True,
            )
        results = query(unreg.fullname)['results']
        assert_equal(len(results), 1)

    def test_search_fullname(self):
        # Searching for full name yields exactly one result.
        contribs = search.search_contributor(self.name1)
        assert_equal(len(contribs['users']), 1)

        contribs = search.search_contributor(self.name2)
        assert_equal(len(contribs['users']), 0)

    def test_search_firstname(self):
        # Searching for first name yields exactly one result.
        contribs = search.search_contributor(self.name1.split(' ')[0])
        assert_equal(len(contribs['users']), 1)

        contribs = search.search_contributor(self.name2.split(' ')[0])
        assert_equal(len(contribs['users']), 0)

    def test_search_partial(self):
        # Searching for part of first name yields exactly one
        # result.
        contribs = search.search_contributor(self.name1.split(' ')[0][:-1])
        assert_equal(len(contribs['users']), 1)

        contribs = search.search_contributor(self.name2.split(' ')[0][:-1])
        assert_equal(len(contribs['users']), 0)

    def test_search_fullname_special_character(self):
        # Searching for a fullname with a special character yields
        # exactly one result.
        contribs = search.search_contributor(self.name3)
        assert_equal(len(contribs['users']), 1)

        contribs = search.search_contributor(self.name4)
        assert_equal(len(contribs['users']), 0)

    def test_search_firstname_special_charcter(self):
        # Searching for a first name with a special character yields
        # exactly one result.
        contribs = search.search_contributor(self.name3.split(' ')[0])
        assert_equal(len(contribs['users']), 1)

        contribs = search.search_contributor(self.name4.split(' ')[0])
        assert_equal(len(contribs['users']), 0)

    def test_search_partial_special_character(self):
        # Searching for a partial name with a special character yields
        # exctly one result.
        contribs = search.search_contributor(self.name3.split(' ')[0][:-1])
        assert_equal(len(contribs['users']), 1)

        contribs = search.search_contributor(self.name4.split(' ')[0][:-1])
        assert_equal(len(contribs['users']), 0)

    def test_search_profile(self):
        orcid = '123456'
        user = factories.UserFactory()
        user.social['orcid'] = orcid
        user.save()
        contribs = search.search_contributor(orcid)
        assert_equal(len(contribs['users']), 1)
        assert_equal(len(contribs['users'][0]['social']), 1)
        assert_equal(contribs['users'][0]['social']['orcid'], user.social_links['orcid'])

class TestProjectSearchResults(OsfTestCase):
    def setUp(self):
        self.singular = 'Spanish Inquisition'
        self.plural = 'Spanish Inquisitions'
        self.possessive = 'Spanish\'s Inquisition'

        with run_celery_tasks():
            super(TestProjectSearchResults, self).setUp()
            self.user = factories.UserFactory(fullname='Doug Bogie')

            self.project_singular = factories.ProjectFactory(
                title=self.singular,
                creator=self.user,
                is_public=True,
            )

            self.project_plural = factories.ProjectFactory(
                title=self.plural,
                creator=self.user,
                is_public=True,
            )

            self.project_possessive = factories.ProjectFactory(
                title=self.possessive,
                creator=self.user,
                is_public=True,
            )

            self.project_unrelated = factories.ProjectFactory(
                title='Cardinal Richelieu',
                creator=self.user,
                is_public=True,
            )

    def test_singular_query(self):
        # Verify searching for singular term includes singular,
        # possessive and plural versions in results.
        time.sleep(1)
        results = query(self.singular)['results']
        assert_equal(len(results), 3)

    def test_plural_query(self):
        # Verify searching for singular term includes singular,
        # possessive and plural versions in results.
        results = query(self.plural)['results']
        assert_equal(len(results), 3)

    def test_possessive_query(self):
        # Verify searching for possessive term includes singular,
        # possessive and plural versions in results.
        results = query(self.possessive)['results']
        assert_equal(len(results), 3)

def job(**kwargs):
    keys = [
        'title',
        'institution',
        'department',
        'location',
        'startMonth',
        'startYear',
        'endMonth',
        'endYear',
        'ongoing',
    ]
    job = {}
    for key in keys:
        if key[-5:] == 'Month':
            job[key] = kwargs.get(key, 'December')
        elif key[-4:] == 'Year':
            job[key] = kwargs.get(key, '2000')
        else:
            job[key] = kwargs.get(key, 'test_{}'.format(key))
    return job

class TestUserSearchResults(OsfTestCase):
    def setUp(self):
        with run_celery_tasks():
            super(TestUserSearchResults, self).setUp()
            self.user_one = factories.UserFactory(jobs=[job(institution='Oxford'),
                                                        job(institution='Star Fleet')],
                                                  fullname='Date Soong')

            self.user_two = factories.UserFactory(jobs=[job(institution='Grapes la Picard'),
                                                        job(institution='Star Fleet')],
                                                  fullname='Jean-Luc Picard')

            self.user_three = factories.UserFactory(jobs=[job(institution='Star Fleet'),
                                                      job(institution='Federation Medical')],
                                                    fullname='Beverly Crusher')

            self.user_four = factories.UserFactory(jobs=[job(institution='Star Fleet')],
                                                   fullname='William Riker')

            self.user_five = factories.UserFactory(jobs=[job(institution='Traveler intern'),
                                                         job(institution='Star Fleet Academy'),
                                                         job(institution='Star Fleet Intern')],
                                                   fullname='Wesley Crusher')

            for i in range(25):
                factories.UserFactory(jobs=[job()])

        self.current_starfleet = [
            self.user_three,
            self.user_four,
        ]

        self.were_starfleet = [
            self.user_one,
            self.user_two,
            self.user_three,
            self.user_four,
            self.user_five
        ]

    @unittest.skip('Cannot guarentee always passes')
    def test_current_job_first_in_results(self):
        results = query_user('Star Fleet')['results']
        result_names = [r['names']['fullname'] for r in results]
        current_starfleet_names = [u.fullname for u in self.current_starfleet]
        for name in result_names[:2]:
            assert_in(name, current_starfleet_names)

    def test_had_job_in_results(self):
        results = query_user('Star Fleet')['results']
        result_names = [r['names']['fullname'] for r in results]
        were_starfleet_names = [u.fullname for u in self.were_starfleet]
        for name in result_names:
            assert_in(name, were_starfleet_names)

class TestSearchExceptions(OsfTestCase):
    # Verify that the correct exception is thrown when the connection is lost

    @classmethod
    def setUpClass(cls):
        logging.getLogger('website.project.model').setLevel(logging.CRITICAL)
        super(TestSearchExceptions, cls).setUpClass()
        if settings.SEARCH_ENGINE == 'elastic':
            cls._client = search.search_engine.CLIENT
            search.search_engine.CLIENT = None

    @classmethod
    def tearDownClass(cls):
        super(TestSearchExceptions, cls).tearDownClass()
        if settings.SEARCH_ENGINE == 'elastic':
            search.search_engine.CLIENT = cls._client

    @requires_search
    def test_connection_error(self):
        # Ensures that saving projects/users doesn't break as a result of connection errors
        self.user = factories.UserFactory(fullname='Doug Bogie')
        self.project = factories.ProjectFactory(
            title="Tom Sawyer",
            creator=self.user,
            is_public=True,
        )
        self.user.save()
        self.project.save()

class TestSearchMigration(OsfTestCase):
    # Verify that the correct indices are created/deleted during migration

    @classmethod
    def tearDownClass(cls):
        super(TestSearchMigration, cls).tearDownClass()
        search.create_index(settings.ELASTIC_INDEX)

    def setUp(self):
        super(TestSearchMigration, self).setUp()
        populate_institutions('test')
        self.es = search.search_engine.CLIENT
        search.delete_index(settings.ELASTIC_INDEX)
        search.create_index(settings.ELASTIC_INDEX)
        self.user = factories.UserFactory(fullname='David Bowie')
        self.project = factories.ProjectFactory(
            title=settings.ELASTIC_INDEX,
            creator=self.user,
            is_public=True
        )

    def test_first_migration_no_remove(self):
        migrate(delete=False, remove=False, index=settings.ELASTIC_INDEX, app=self.app.app)
        var = self.es.indices.get_aliases()
        assert_equal(var[settings.ELASTIC_INDEX + '_v1']['aliases'].keys()[0], settings.ELASTIC_INDEX)

    def test_multiple_migrations_no_remove(self):
        for n in xrange(1, 21):
            migrate(delete=False, remove=False, index=settings.ELASTIC_INDEX, app=self.app.app)
            var = self.es.indices.get_aliases()
            assert_equal(var[settings.ELASTIC_INDEX + '_v{}'.format(n)]['aliases'].keys()[0], settings.ELASTIC_INDEX)

    def test_first_migration_with_remove(self):
        migrate(delete=False, remove=True, index=settings.ELASTIC_INDEX, app=self.app.app)
        var = self.es.indices.get_aliases()
        assert_equal(var[settings.ELASTIC_INDEX + '_v1']['aliases'].keys()[0], settings.ELASTIC_INDEX)

    def test_multiple_migrations_with_remove(self):
        for n in xrange(1, 21, 2):
            migrate(delete=False, remove=True, index=settings.ELASTIC_INDEX, app=self.app.app)
            var = self.es.indices.get_aliases()
            assert_equal(var[settings.ELASTIC_INDEX + '_v{}'.format(n)]['aliases'].keys()[0], settings.ELASTIC_INDEX)

            migrate(delete=False, remove=True, index=settings.ELASTIC_INDEX, app=self.app.app)
            var = self.es.indices.get_aliases()
            assert_equal(var[settings.ELASTIC_INDEX + '_v{}'.format(n + 1)]['aliases'].keys()[0], settings.ELASTIC_INDEX)
            assert not var.get(settings.ELASTIC_INDEX + '_v{}'.format(n))

    def test_migration_institutions(self):
        migrate(delete=True, index=settings.ELASTIC_INDEX, app=self.app.app)
        count_query = {}
        count_query['aggregations'] = {
            'counts': {
                'terms': {
                    'field': '_type',
                }
            }
        }
        institution_bucket_found = False
        res = self.es.search(index=settings.ELASTIC_INDEX, doc_type=None, search_type='count', body=count_query)
        for bucket in res['aggregations']['counts']['buckets']:
            if bucket['key'] == u'institution':
                institution_bucket_found = True

        assert_equal(institution_bucket_found, True)

class TestSearchFiles(OsfTestCase):

    def setUp(self):
        super(TestSearchFiles, self).setUp()
        self.node = factories.ProjectFactory(is_public=True, title='Otis')
        self.osf_storage = self.node.get_addon('osfstorage')
        self.root = self.osf_storage.get_root()

    def test_search_file(self):
        self.root.append_file('Shake.wav')
        find = query_file('Shake.wav')['results']
        assert_equal(len(find), 1)

    def test_search_file_name_without_separator(self):
        self.root.append_file('Shake.wav')
        find = query_file('Shake')['results']
        assert_equal(len(find), 1)

    def test_delete_file(self):
        file_ = self.root.append_file('I\'ve Got Dreams To Remember.wav')
        find = query_file('I\'ve Got Dreams To Remember.wav')['results']
        assert_equal(len(find), 1)
        file_.delete()
        find = query_file('I\'ve Got Dreams To Remember.wav')['results']
        assert_equal(len(find), 0)

    def test_add_tag(self):
        file_ = self.root.append_file('That\'s How Strong My Love Is.mp3')
        tag = Tag(name='Redding')
        tag.save()
        file_.tags.add(tag)
        file_.save()
        find = query_tag_file('Redding')['results']
        assert_equal(len(find), 1)

    def test_remove_tag(self):
        file_ = self.root.append_file('I\'ve Been Loving You Too Long.mp3')
        tag = Tag(name='Blue')
        tag.save()
        file_.tags.add(tag)
        file_.save()
        find = query_tag_file('Blue')['results']
        assert_equal(len(find), 1)
        file_.tags.remove(tag)
        file_.save()
        find = query_tag_file('Blue')['results']
        assert_equal(len(find), 0)

    def test_make_node_private(self):
        file_ = self.root.append_file('Change_Gonna_Come.wav')
        find = query_file('Change_Gonna_Come.wav')['results']
        assert_equal(len(find), 1)
        self.node.is_public = False
        with run_celery_tasks():
            self.node.save()
        find = query_file('Change_Gonna_Come.wav')['results']
        assert_equal(len(find), 0)

    def test_make_private_node_public(self):
        self.node.is_public = False
        self.node.save()
        file_ = self.root.append_file('Try a Little Tenderness.flac')
        find = query_file('Try a Little Tenderness.flac')['results']
        assert_equal(len(find), 0)
        self.node.is_public = True
        with run_celery_tasks():
            self.node.save()
        find = query_file('Try a Little Tenderness.flac')['results']
        assert_equal(len(find), 1)

    def test_delete_node(self):
        node = factories.ProjectFactory(is_public=True, title='The Soul Album')
        osf_storage = node.get_addon('osfstorage')
        root = osf_storage.get_root()
        root.append_file('The Dock of the Bay.mp3')
        find = query_file('The Dock of the Bay.mp3')['results']
        assert_equal(len(find), 1)
        node.is_deleted = True
        with run_celery_tasks():
            node.save()
        find = query_file('The Dock of the Bay.mp3')['results']
        assert_equal(len(find), 0)

    def test_file_download_url_guid(self):
        file_ = self.root.append_file('Timber.mp3')
        file_guid = file_.get_guid(create=True)
        file_.save()
        find = query_file('Timber.mp3')['results']
        assert_equal(find[0]['guid_url'], '/' + file_guid._id + '/')

    def test_file_download_url_no_guid(self):
        file_ = self.root.append_file('Timber.mp3')
        path = OsfStorageFile.objects.get(node=file_.node).path
        deep_url = '/' + file_.node._id + '/files/osfstorage' + path + '/'
        find = query_file('Timber.mp3')['results']
        assert_not_equal(file_.path, '')
        assert_equal(file_.path, path)
        assert_equal(find[0]['guid_url'], None)
        assert_equal(find[0]['deep_url'], deep_url)

    def test_quickfiles_files_appear_in_search(self):
        quickfiles = QuickFilesNode.objects.get(creator=self.node.creator)
        quickfiles_osf_storage = quickfiles.get_addon('osfstorage')
        quickfiles_root = quickfiles_osf_storage.get_root()

        quickfiles_root.append_file('GreenLight.mp3')
        find = query_file('GreenLight.mp3')['results']
        assert_equal(len(find), 1)

    def test_qatest_quickfiles_files_not_appear_in_search(self):
        quickfiles = QuickFilesNode.objects.get(creator=self.node.creator)
        quickfiles_osf_storage = quickfiles.get_addon('osfstorage')
        quickfiles_root = quickfiles_osf_storage.get_root()

        file = quickfiles_root.append_file('GreenLight.mp3')
        tag = Tag(name='qatest')
        tag.save()
        file.tags.add(tag)
        file.save()

        find = query_file('GreenLight.mp3')['results']
        assert_equal(len(find), 0)

    def test_quickfiles_spam_user_files_do_not_appear_in_search(self):
        quickfiles = QuickFilesNode.objects.get(creator=self.node.creator)
        quickfiles_osf_storage = quickfiles.get_addon('osfstorage')
        quickfiles_root = quickfiles_osf_storage.get_root()
        quickfiles_root.append_file('GreenLight.mp3')

        self.node.creator.disable_account()
        self.node.creator.add_system_tag('spam_confirmed')
        self.node.creator.save()

        find = query_file('GreenLight.mp3')['results']
        assert_equal(len(find), 0)


text:
var ngApp = require('ngApp');
var _ = require('lodash');

module.exports = ngApp.directive('petList', function () {
    return {
        restrict: 'C',
        replace: true,
        template: require('raw-loader!./templates/pet-list.html'),
        controller: function ($scope, $mdDialog, animalDataService, speciesDataService) {
            $scope.currentSpeciesIndex = 0;
            $scope.animals = {};
            $scope.selectedPets = {};
            $scope.selectedSpecies = null;
            $scope.batchSpeciesProp = null;

            $scope.getActiveSpecies = function () {
                var defaultSpecies = 'dog';
                var speciesName = false;

                _.forEach($scope.selectedPets, function (animal) {
                    speciesName = animal.getSpeciesName();
                    if (speciesName) {
                        // if we have a species, exit early
                        return false;
                    }
                });

                // use selected tab species in pet list as fallback
                if (!speciesName && $scope.selectedSpecies) {
                    speciesName = $scope.selectedSpecies;
                }

                return (speciesName || defaultSpecies).toLowerCase();
            };

            $scope.isBatchEditActive = function () {
                return (_.keys($scope.selectedPets).length > 0);
            };

            /**
             *
             * @param {Animal} animal
             */
            $scope.selectPet = function (animal) {
                $scope.selectedPets[animal.getId()] = animal;
            };

            /**
             *
             * @param {Animal} animal
             */
            $scope.deselectPet = function (animal) {
                delete $scope.selectedPets[animal.getId()];
            };

            /**
             *
             * @param {Animal} animal
             */
            $scope.togglePetSelection = function (animal) {
                var animalId = animal.getId();

                $scope.selectedPets[animalId] ? $scope.deselectPet(animal) : $scope.selectPet(animal);
            };

            $scope.clearSelectedPets = function () {
                _.forEach($scope.selectedPets, function (animal) {
                    $scope.deselectPet(animal);
                });
            };

            $scope.isEditableByBatch = function (propData) {
                switch (propData.key) {
                    case 'petName':
                        return false;
                    default:
                        break;
                }
                switch (propData.valType) {
                    case 'String':
                    case 'Number':
                    case 'Boolean':
                    case 'Date':
                        return true;
                    default:
                        return false;
                }
            };

            $scope.setBatchSpecies = function (speciesName) {
                $scope.showLoading();
                return speciesDataService.getSpecies(speciesName, {useCache: true})
                    .then(function (species) {
                        $scope.batchProperties = species.getProps().filter($scope.isEditableByBatch);
                        $scope.batchSpeciesProp = _.chain($scope.batchProperties)
                            .find({key: 'species'})
                            .extend({
                                val: speciesName,
                                options: $scope.speciesList
                            })
                            .value();
                    })
                    .catch(function (err) {
                        $scope.showError('Could not get model for ' + speciesName);

                        console.error(err);
                    })
                    .then(function () {
                        $scope.hideLoading();
                    })
            };

            $scope.batchEdit = function (ev) {
                var speciesWatchHandler = $scope.$watch('batchSpeciesProp.val', function (activeSpeciesName) {
                    if (!activeSpeciesName) {
                        // ignore invalid speciesName value
                        return;
                    }
                    $scope.setBatchSpecies(activeSpeciesName);
                });

                $scope.setBatchSpecies($scope.getActiveSpecies());

                $mdDialog.show({
                        controller: function ($mdDialog) {
                            $scope.close = function () {
                                console.log('petList: mdDialog: closing dialog');
                                $mdDialog.hide();
                            }
                        },
                        template: require('raw-loader!modules/views/dialogs/batch-edit.html'),
                        parent: angular.element(document.body),
                        targetEvent: ev,
                        scope: $scope,
                        preserveScope: true,
                        clickOutsideToClose: true
                    })
                    .catch(function (err) {
                        console.error(err);
                    })
                    .then(function () {
                        speciesWatchHandler();
                    })
            };

            $scope.isEditableProp = function (propData) {
                switch (propData.key) {
                    case 'petName':
                        return false;
                    default:
                        break;
                }
                switch (propData.valType) {
                    case 'String':
                    case 'Number':
                    case 'Boolean':
                    case 'Date':
                        return true;
                    default:
                        return false;
                }
            };

            function loadPets() {
                return speciesDataService.getSpeciesList()
                    .then(function (speciesList) {
                        $scope.speciesList = speciesList;
                        return Promise.all(speciesList.map(function (speciesName) {
                            return animalDataService.getAnimalsBySpecies(speciesName)
                                .then(function (animals) {
                                    $scope.animals[speciesName] = animals;
                                })
                        }))
                    })
            }

            /**
             *
             * @param {Object} [options]
             * @param {String} [options.visibleNotification=true]
             */
            $scope.save = function (options) {
                var opts = _.defaults(options, {
                    visibleNotification: true
                });

                $scope.showLoading();
                return Promise.all(Object.keys($scope.selectedPets).map(function (animalId, idx) {
                        var animal = $scope.selectedPets[animalId];

                        if (!animal) {
                            console.error('Could not save pet[%s]: %o', idx, animal);
                            return Promise.resolve();
                        }

                        return animalDataService.fetchAnimal(animal)
                            .then(function (fetchedAnimal) {

                                fetchedAnimal.setProps($scope.batchProperties);

                                return animalDataService.saveAnimal(fetchedAnimal)
                                    .then(function (result) {
                                        console.log('petList: saved pet (%s/%s)', idx, Object.keys($scope.selectedPets).length);
                                        return result;
                                    })
                            })
                            .catch(function (err) {
                                if (opts.visibleNotification) $scope.showError('Could not save pet');
                                console.error(err);
                            })
                    }))
                    .then(function () {
                        if (opts.visibleNotification) $scope.showMessage('All pets saved');
                    })
                    .catch(function (err) {
                        console.error(err);
                        if (opts.visibleNotification) $scope.showError('Failed to save all pets');
                    })
                    .then(function () {
                        $scope.hideLoading();
                        loadPets();
                    })
            };

            $scope.delete = function (options) {
                $scope.showLoading();
                return Promise.all(Object.keys($scope.selectedPets).map(function (selectedPetId) {
                        return animalDataService.deleteAnimal($scope.selectedPets[selectedPetId])
                    }))
                    .then(function () {
                        if ($scope.visibleNotification) $scope.showMessage('All pets deleted');
                    })
                    .catch(function (err) {
                        console.error(err);
                        if ($scope.visibleNotification) $scope.showError('Could not delete all pets');
                    })
                    .then(function () {
                        $scope.hideLoading();
                        loadPets()
                    })
            };

            (function init() {
                loadPets();
            })();
        }
    }
});

module.exports = ngApp;

redpajama_set_name: RedPajamaGithub


text:
@implementation NMVerticalRangeSlider

//Returns the lower value based on the X potion
//The return value is automatically adjust to fit inside the valid range
-(float) lowerValueForCenterX:(float)x
{
    float _padding = self.lowerHandle.frame.size.height/2.0f;
    float value = self.minimumValue + (x-_padding) / (self.frame.size.height-(_padding*2)) * (self.maximumValue - self.minimumValue);

    value = MAX(value, self.minimumValue);
    value = MIN(value, self.upperValue - self.minimumRange);

    return value;
}

//Returns the upper value based on the X potion
//The return value is automatically adjust to fit inside the valid range
-(float) upperValueForCenterX:(float)x
{
    float _padding = self.upperHandle.frame.size.height/2.0;

    float value = self.minimumValue + (x-_padding) / (self.frame.size.height-(_padding*2)) * (self.maximumValue - self.minimumValue);

    value = MIN(value, self.maximumValue);
    value = MAX(value, self.lowerValue+self.minimumRange);

    return value;
}

@end


text:
;(function($) {

	$.fn.fixPNG = function() {
		return this.each(function () {
			var image = $(this).css('backgroundImage');

			if (image.match(/^url\(["']?(.*\.png)["']?\)$/i)) {
				image = RegExp.$1;
				$(this).css({
					'backgroundImage': 'none',
					'filter': "progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true, sizingMethod=" + ($(this).css('backgroundRepeat') == 'no-repeat' ? 'crop' : 'scale') + ", src='" + image + "')"
				}).each(function () {
					var position = $(this).css('position');
					if (position != 'absolute' && position != 'relative')
						$(this).css('position', 'relative');
				});
			}
		});
	};

  //TODO refactor using data.content_klass
  $.facybox = function(data, klass) {
    $.facybox.loading();
    $.facybox.content_klass = klass;
    if (data.ajax) revealAjax(data.ajax);
    else if(data.image) revealImage(data.image);
    else if(data.images) revealGallery(data.images,data.initial);
    else if(data.div) revealHref(data.div);
    else if($.isFunction(data)) data.call($);
    else $.facybox.reveal(data);
  }

  /*
   * Public, $.facybox methods
   */

  $.extend($.facybox, {
    //possible option: noAutoload --- will build facybox only when it is needed
    settings: {
		opacity      : 0.3,
		overlay      : true,
		modal        : false,
		imageTypes   : [ 'png', 'jpg', 'jpeg', 'gif' ],
		imageMimeTypes  : [ 'image/jpeg', 'image/png', 'image/gif' ]
    },

    html : function(){
      return '\

 \

 \

 \

 \

 \
							 \

 \

 \
							 \
							 \

 \
							\

 \

 \
							 \
							 \

 \

 \
							 \

 \

 \

 \

 \

 \

 \
	'
    },

    loading: function(){
      init();
      if($('.loading',$('#facybox'))[0]) return;//already in loading state...
      showOverlay();
      $.facybox.wait();
      if (!$.facybox.settings.modal) {
        $(document).bind('keydown.facybox', function(e) {
          if(e.keyCode == 27) $.facybox.close();//ESC
        });
      }
      $(document).trigger('loading.facybox');
    },

    wait: function(){
      var $f = $('#facybox');
      $('.content',$f).empty();//clear out old content
      $('.body',$f).children().hide().end().append('

');
      $f.fadeIn('fast');
	  $.facybox.centralize();
      $(document).trigger('reveal.facybox').trigger('afterReveal.facybox');
    },

    centralize: function(){

		var $f = $('#facybox');
		var pos = $.facybox.getViewport();
		var wl = parseInt(pos[0]/2) - parseInt($f.find("table").width() / 2);
		var fh = parseInt($f.height());

		if(pos[1] > fh){
			var t = (pos[3] + (pos[1] - fh)/2);
			$f.css({ 'left': wl, 'top': t });
			// console.log('height smaller then window: '+fh, pos[1], pos[3])
		} else {
			var t = (pos[3] + (pos[1] /10));
			$f.css({ 'left': wl, 'top': t });
			// console.log('height bigger then window')
		}
    },

	getViewport: function() {
		//  [1009, 426, 0, 704]
		return [$(window).width(), $(window).height(), $(window).scrollLeft(), $(window).scrollTop()];
	},

    reveal: function(content){
	$(document).trigger('beforeReveal.facybox');
	var $f = $('#facybox');
	$('.content',$f)
		.attr('class',($.facybox.content_klass||'')+' content') //do not simply add the new class, since on the next call the old classes would remain
		.html(content);
	$('.loading',$f).remove();

	var $body 	= $('.body',$f);

	$body.children().fadeIn('fast');

	$.facybox.centralize();

	$(document).trigger('reveal.facybox').trigger('afterReveal.facybox');
    },

    close: function(){
      $(document).trigger('close.facybox');
      return false;
    }
  })

  /*
   * Bind to links, on click they open a facybox which
   * contains what their href points to
   */
  $.fn.facybox = function(settings) {
    var $this = $(this);
    if(!$this[0]) return $this;//called on empty elements, just stop and continue chain
    if(settings)$.extend($.facybox.settings, settings);
    if(!$.facybox.settings.noAutoload) init();

    $this.bind('click.facybox',function(){
      $.facybox.loading();
      // support for rel="facybox.inline_popup" syntax, to add a class
      // also supports deprecated "facybox[.inline_popup]" syntax
      var klass = this.rel.match(/facybox\[?\.(\w+)\]?/);
      $.facybox.content_klass = klass ? klass[1] : '';
      revealHref(this.href);
      return false;
    });
    return $this;//continue chain
  }

  /*
   * Private methods
   */
  // called one time to setup facybox on this page
  function init() {
    if($.facybox.settings.inited) return;
    else $.facybox.settings.inited = true;

    $(document).trigger('init.facybox');
    makeBackwardsCompatible();

    var imageTypes = $.facybox.settings.imageTypes.join('|');
    $.facybox.settings.imageTypesRegexp = new RegExp('\.(' + imageTypes + ')', 'i');

    $('body').append($.facybox.html());//insert facybox to dom

	// ie hacks
	var $f = $("#facybox");

	// it amazes me that this is still better than native png32 support in ie8...
	if($.browser.msie){
		$(".n, .s, .w, .e, .nw, .ne, .sw, .se", $f).fixPNG();
		// ie6
		if(parseInt($.browser.version) <= 6){
			var css = ""
			$('head').append(css);
			$(".close", $f).fixPNG();
			$(".close",$f).css({
				'right': '15px'
			});
		}
		$(".w, .e",$f).css({
			width: '13px',
			'font-size': '0'
		}).text(" ");
	}

    //if we did not autoload, so the user has just clicked the facybox and pre-loading is useless
    if(! $.facybox.settings.noAutoload){
		preloadImages();
	}
        $('#facybox .close').click($.facybox.close);
  }

  //preloads all the static facybox images
  function preloadImages(){
    //TODO preload prev/next ?
    $('#facybox').find('.n, .close , .s, .w, .e, .nw, ne, sw, se').each(function() {
        backgroundImage = $(this).css('background-image');
        if (backgroundImage === 'none') return;
        var img = new Image();
        img.src = backgroundImage.replace(/url\("?(.*?)"?\)/, '$1');
    });
    // var img = new Image();
    // img.src = 'images/loading.gif';
    /*
      TODO: remove and load preloader from filament group
    */
  }

  function makeBackwardsCompatible() {
    var $s = $.facybox.settings;
    $s.imageTypes = $s.image_types || $s.imageTypes;
    $s.facyboxHtml = $s.facybox_html || $s.facyboxHtml;
  }

  // Figures out what you want to display and displays it
  // formats are:
  //     div: #id
  //   image: blah.extension
  //    ajax: anything else
  function revealHref(href) {
    // div
    if(href.match(/#/)) {
      var url    = window.location.href.split('#')[0];
      var target = href.replace(url,'');
      if (target == '#') return
      $.facybox.reveal($(target).html(), $.facybox.content_klass);
    // image
    } else if(href.match($.facybox.settings.imageTypesRegexp)) {
      revealImage(href);
    // ajax
    } else { revealAjax(href)}
  }

  function revealGallery(hrefs, initial) {
    //initial position
    var position = $.inArray(initial||0,hrefs);
    if(position ==-1){
		position = 0;
	}

    //build navigation and ensure it will be removed
	var $footer  = $('#facybox div.footer');

    $footer.append($('

'));
    var $nav = $('#facybox .navigation');

    $(document).bind('afterClose.facybox',function(){$nav.remove()});

    function change_image(diff){
      position = (position + diff + hrefs.length) % hrefs.length;
      revealImage(hrefs[position]);
      $nav.find('.counter').html(position +1+" / "+hrefs.length);
    }
    change_image(0);

    //bind events
    $('.prev',$nav).click(function(){change_image(-1)});
    $('.next',$nav).click(function(){change_image(1)});
    $(document).bind('keydown.facybox', function(e) {
      if(e.keyCode == 39)change_image(1);  // right
      if(e.keyCode == 37)change_image(-1); // left
    });
  }

  function revealImage(href){

	var $f = $("#facybox");

    $('#facybox .content').empty();
    $.facybox.loading();//TODO loading must be shown until image is loaded -> stopLoading() on onload
    var image = new Image();
    image.onload = function() {
		$.facybox.reveal('

', $.facybox.content_klass);

		var $footer  	= $("div.footer",$f);
		var $content 	= $("div.content",$f);
		var $navigation	= $("div.navigation",$f);
		var $next		= $("a.next",$f);
		var $prev		= $("a.prev",$f);
		var $counter	= $("div.counter",$f);

		var size = [$content.width(), $content.height()];

		$footer.width(size[0]).height(size[1]);
		$navigation.width(size[0]).height(size[1]);
		$next.width(parseInt(size[0]/2)).height(size[1]).css({ left: (size[0]/2) });
		$prev.width(size[0]/2).height(size[1]);
		$counter.width(parseInt($f.width() -26)).css({'opacity' : 0.5, '-moz-border-radius' : '8px', '-webkit-border-radius' : '8px'})

    }
    image.src = href;
  }

  function revealAjax(href) {
    // $.get(href, function(data) { $.facybox.reveal(data) });
	$.ajax({
	  type: "GET",
	  url: href,
	  complete: function(XMLHttpRequest, textStatus) {
	    content_type = XMLHttpRequest.getResponseHeader("Content-Type");
	    if ( jQuery.inArray(content_type, $.facybox.settings.imageMimeTypes) >= 0 ) {
	      revealImage(href)
	  $.facybox.centralize();
	    } else {
	      $.facybox.reveal( XMLHttpRequest.responseText );
	    }
	  }
	});
  }

  function skipOverlay() {
    return $.facybox.settings.overlay == false || $.facybox.settings.opacity === null
  }

  function showOverlay() {
    if(skipOverlay()) return;

    if($('#facybox_overlay').length == 0){
      $("body").append('

');
    }

    $('#facybox_overlay').hide().addClass("facybox_overlayBG")
      .css('opacity', $.facybox.settings.opacity)
      .fadeIn(200);
    if(!$.facybox.settings.modal){
      $('#facybox_overlay').click(function(){ $(document).trigger('close.facybox')})
    }
  }

  function hideOverlay() {
    if(skipOverlay()) return;

    $('#facybox_overlay').fadeOut(200, function(){
      $("#facybox_overlay").removeClass("facybox_overlayBG").
        addClass("facybox_hide").
        remove();
    })
  }

  /*
   * Bindings
   */

  $(document).bind('close.facybox', function() {
    $(document).unbind('keydown.facybox');

	// ie hacks
	var $f = $("#facybox");
	if($.browser.msie){
		$('#facybox').hide();
		hideOverlay();
		$('#facybox .loading').remove();
	} else {
		$('#facybox').fadeOut('fast',function() {
	      $('#facybox .content').removeClass().addClass('content');//revert changing class
	      hideOverlay();
	      $('#facybox .loading').remove();
	    })
	}

    $(document).trigger('afterClose.facybox');
  });

})(jQuery);


text:
class CreateNewsletterSubscribers < ActiveRecord::Migration
  def change
    create_table :newsletter_subscribers do |t|
      t.string :email, :null => false

      t.timestamps
    end
    add_index :newsletter_subscribers,:email, :unique => true
  end
end


text:
package com.xplus.commons.pattern.behavioral.state;

public class Client {

	public static void main(String[] args) {
		Context context = new Context();
		context.setState(new ConcreteStateA());
		context.request();
		context.setState(new ConcreteStateB());
		context.request();
	}

}


text:
package org.fastcatsearch.http.action.management.dictionary;

import java.io.Writer;
import java.sql.SQLIntegrityConstraintViolationException;
import java.util.List;

import org.fastcatsearch.db.dao.DictionaryDAO;
import org.fastcatsearch.http.ActionAuthority;
import org.fastcatsearch.http.ActionAuthorityLevel;
import org.fastcatsearch.http.ActionMapping;
import org.fastcatsearch.http.action.ActionRequest;
import org.fastcatsearch.http.action.ActionResponse;
import org.fastcatsearch.http.action.AuthAction;
import org.fastcatsearch.plugin.Plugin;
import org.fastcatsearch.plugin.PluginService;
import org.fastcatsearch.plugin.analysis.AnalysisPlugin;
import org.fastcatsearch.plugin.analysis.AnalysisPluginSetting.ColumnSetting;
import org.fastcatsearch.service.ServiceManager;
import org.fastcatsearch.util.ResponseWriter;

@ActionMapping(value="/management/dictionary/put", authority=ActionAuthority.Dictionary, authorityLevel=ActionAuthorityLevel.WRITABLE)
public class PutDictionaryWordAction extends AuthAction {

	@Override
	public void doAuthAction(ActionRequest request, ActionResponse response) throws Exception {

		String pluginId = request.getParameter("pluginId");
		String dictionaryId = request.getParameter("dictionaryId");

		PluginService pluginService = ServiceManager.getInstance().getService(PluginService.class);
		Plugin plugin = pluginService.getPlugin(pluginId);
		AnalysisPlugin analysisPlugin = (AnalysisPlugin) plugin;

		DictionaryDAO dictionaryDAO = analysisPlugin.getDictionaryDAO(dictionaryId);

		List<ColumnSetting> columnSettingList = dictionaryDAO.columnSettingList();

		int count = 0;
		String errorMessage = null;
		if (columnSettingList != null && columnSettingList.size() > 0) {
			String[] columns = new String[columnSettingList.size()];
			Object[] values = new Object[columnSettingList.size()];
			for (int i = 0; i < columnSettingList.size(); i++) {
				ColumnSetting columnSetting = columnSettingList.get(i);
				String name = columnSetting.getName().toUpperCase();
				String type = columnSetting.getType();
				columns[i] = name;
				String value = request.getParameter(name);

				if (type.startsWith("int") || type.startsWith("INT")) {
					int intValue = 0;
					try {
						intValue = Integer.parseInt(value);
					} catch (Exception ignore) {
					}
					values[i] = intValue;
				} else if (type.contains("char") || type.contains("CHAR")) {
					values[i] = value;
				} else {
					values[i] = value;
				}
			}
			try{
				count = dictionaryDAO.putEntry(columns, values);
			}catch(Exception e){
				if(e.getCause() instanceof SQLIntegrityConstraintViolationException){
					errorMessage = "Duplicate word exist.";
				}else{
					errorMessage = e.getCause().toString();
				}
			}
		}

		if(count > 0){
			analysisPlugin.dictionaryStatusDAO().updateUpdateTime(dictionaryId);
		}

		Writer writer = response.getWriter();
		ResponseWriter resultWriter = getDefaultResponseWriter(writer);
		resultWriter.object().key("success").value(count > 0);
		if(errorMessage != null){
			resultWriter.key("errorMessage").value(errorMessage);
		}
		resultWriter.endObject();
		resultWriter.done();

	}

}


text:
using Fan.Exceptions;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks;

namespace Fan.Data
{
    /// <summary>
    /// EF implementation of a base repository for commonly used data access methods.
    /// </summary>
    /// <typeparam name="T">It is a sub type of <see cref="Entity"/> which provides an int based PK.</typeparam>
    /// <remarks>
    /// The sub class will have its specific methods, for example SqlCategoryRepository and SqlTagRepository
    /// has a GetListAsync() which does their specific join.
    /// </remarks>
    public class EntityRepository<T> : IRepository<T> where T : Entity
    {
        /// <summary>
        /// The set initialized by sub class.
        /// </summary>
        protected readonly DbSet<T> _entities;
        protected readonly bool isSqlite;

        /// <summary>
        /// The specific context initialized by sub class.
        /// </summary>
        private readonly DbContext _db;

        public EntityRepository(DbContext context)
        {
            _entities = context.Set<T>();
            _db = context;
            isSqlite = _db.Database.ProviderName == "Microsoft.EntityFrameworkCore.Sqlite";
        }

        /// <summary>
        /// Creates an entity and returns a tracked object with id.
        /// </summary>
        /// <param name="entity"></param>
        /// <returns>The <paramref name="entity"/> with id.</returns>
        /// <exception cref="FanException">
        /// Throws if insert violates unique key constraint. See <see cref="https://stackoverflow.com/a/47465944/32240"/>
        /// </exception>
        public virtual async Task<T> CreateAsync(T entity)
        {
            try
            {
                await _entities.AddAsync(entity);
                await _db.SaveChangesAsync();
                return entity;
            }
            catch (DbUpdateException dbUpdEx)
            {
                throw GetExceptionForUniqueConstraint(dbUpdEx);
            }
        }

        /// <summary>
        /// Creates a list of entities.
        /// </summary>
        /// <param name="entities"></param>
        /// <returns></returns>
        public virtual async Task<IEnumerable<T>> CreateRangeAsync(IEnumerable<T> entities)
        {
            _entities.AddRange(entities);
            await _db.SaveChangesAsync();
            return entities;
        }

        /// <summary>
        /// Deletes an entity.
        /// </summary>
        /// <param name="id">The integer id of the entity.</param>
        public virtual async Task DeleteAsync(int id)
        {
            var entity = await _entities.SingleAsync(e => e.Id == id);
            _entities.Remove(entity);
            await _db.SaveChangesAsync();
        }

        /// <summary>
        /// Returns a list of objects of T based on search predicate.
        /// </summary>
        /// <param name="predicate"></param>
        /// <returns></returns>
        /// <remarks>
        /// Suitable when predicate is very simple and short.  If you take a look at
        /// SqlTagRepository GetListAsync() that is not suitable for this.
        /// </remarks>
        public virtual async Task<IEnumerable<T>> FindAsync(Expression<Func<T, bool>> predicate) =>
            isSqlite ?
                _entities.ToList().Where(predicate.Compile()).ToList() :
                await _entities.Where(predicate).ToListAsync();

        /// <summary>
        /// Returns an object by id, returns null if not found.
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public virtual async Task<T> GetAsync(int id) => await _entities.SingleOrDefaultAsync(e => e.Id == id);

        /// <summary>
        /// Updates an entity.
        /// </summary>
        /// <param name="entity">
        /// The entity to be updated, the EF implementation does not use this parameter.
        /// </param>
        /// <exception cref="FanException">
        /// Throws if update violates unique key constraint.
        /// </exception>
        public virtual async Task UpdateAsync(T entity)
        {
            try
            {
                await _db.SaveChangesAsync();
            }
            catch (DbUpdateException dbUpdEx)
            {
                throw GetExceptionForUniqueConstraint(dbUpdEx);
            }
        }

        /// <summary>
        /// Updates a list of entities.
        /// </summary>
        /// <param name="entities">
        /// The entities to be updated, the EF implementation does not use this parameter.
        /// </param>
        /// <returns></returns>
        public virtual async Task UpdateAsync(IEnumerable<T> entities)
        {
            await _db.SaveChangesAsync();
        }

        private Exception GetExceptionForUniqueConstraint(DbUpdateException dbUpdEx)
        {
            if (dbUpdEx.InnerException != null)
            {
                var message = dbUpdEx.InnerException.Message;
                if (message.Contains("UniqueConstraint", StringComparison.OrdinalIgnoreCase)
                    || message.Contains("Unique Constraint", StringComparison.OrdinalIgnoreCase))
                    return new FanException(EExceptionType.DuplicateRecord, dbUpdEx);

                if (dbUpdEx.InnerException.InnerException != null)
                {
                    message = dbUpdEx.InnerException.InnerException.Message;
                    if (message.Contains("UniqueConstraint", StringComparison.OrdinalIgnoreCase)
                        || message.Contains("Unique Constraint", StringComparison.OrdinalIgnoreCase))
                        return new FanException(EExceptionType.DuplicateRecord, dbUpdEx);
                }
            }

            return dbUpdEx;
        }
    }
}


text:
<!DOCTYPE html>

  <meta charset="utf-8">
  <title>

      What Programmers Can Learn From Pathological Gamblers –

    Devang Sampat
  </title>

  <meta name="author" content="Devang Sampat" />
  <meta name="description" content="On not getting fired on Day 1" />

  <link rel="alternate" type="application/rss+xml" href="/atom.xml" />

  <link rel="stylesheet" href="/css/base.css" type="text/css" media="screen, projection" />
  <link rel="stylesheet" href="/css/pygments.css" type="text/css" />
  <link media="only screen and (max-device-width: 480px)" href="/css/iphone.css" type="text/css" rel="stylesheet" />
  <link media="only screen and (device-width: 768px)" href="/css/iphone.css" type="text/css" rel="stylesheet" />
  <link href='http://fonts.googleapis.com/css?family=Yanone+Kaffeesatz' rel='stylesheet' type='text/css'>
  <link rel="apple-touch-icon" href="/apple-touch-icon.png" />

        Devang
        Sampat

about

posts

    What Programmers Can Learn From Pathological Gamblers

    May 12, 2013

Think about how many times you've thought you were so close to something, that if you just kept at it for a little longer, then you'd finally succeed.

Others take the opposite approach. They belive that by continuing at the task, they could make things worse.

How do we know when to keep working, and when to call it a day?

The Near Miss Effect

Two years ago, researchers at the Southern Illnois University published a paper in which they ran an experiment on two groups of people: those who were pathlogical gamblers, and those who gambled, but not compulsively). The experiment simulated a slot machine which had three outcomes - win, near miss, and loss. A near miss is when the slots mostly matched, except for one column. They found that:

Pathological gamblers were more excited about winning than nonpathological gamblers even when there was no actual monetary reward for a win

Neurologically, pathlogical gamblers saw near misses as wins, while nonpathological gamblers saw near misses as losses

Now in gambling, a near miss is in reality a loss. However, if we translate these results into a different field, then near misses might actually be very useful!

The Pathological Programmer

Let's say you are now Joe Code Monkey. Instead of having an addiction to gambling, Joe  has somehow trained himself to have an addiction to writing software. His boss wants him to write The Next Big Thing for the company. So he starts by figuring out what features are needed, then he writes all your tests(woohoo TDD!), and now he needs to write the actual software. For the purposes of this example, we can simulate a slot machine here by saying that for every feature he writes and runs against the test bench, he will get one of three results:

All the tests pass

Almost all tests pass

All tests fail

Having become a pathological programmer, Joe get ones of those rushes that makes the hair on the back of his neck stand up not only when he finally has a 100% working feature, but he also when he ran a 80% working feature. This means that instead of calling it a day because he felt that he achieved nothing today, he keeps going and gets the entire feature done. What would previously have been an quite familiar 2am existental crisis, is now a source of inspiration to push forward!

The Downside

However, just like with being a pathological gambler, there can be harmful consequences to one's personal life. Is spending all your time and money on your work really much better than spending all your time and money on gambling? Success may mean that your boss likes you and gives you a big raise, and of course there's the dopamine hit, but winning also means you get a lot of money and a dopamine hit.  There is a risk of becoming a workaholic, of health concerns, of losing friends and family, all for nothing. Instead of giving you a raise, your boss might do the worst thing possible by NOT firing you - meaning that you have yet another day to come back, to play the slot machine.


text:
using namespace ENGINE::UTIL;
template<typename T>
class EMinusX : public Curve<T> {
	T GetValue(T xValue) {
		return (T)glm::exp(-xValue);
	};
};


text:
const jwt = require('jsonwebtoken');
const bcrypt = require('bcryptjs');
const Player = require('../models/player');

let secret;
if(process.env.NODE_ENV === 'production' && process.env.THE_SECRET) {
  secret = { theSecret: process.env.THE_SECRET }
} else {
  secret = require('../creds/secret');
}

module.exports = {
  getToken(req, res, next) {
    Player.findOne({ username: req.body.username})
      .then((player) => {
        if(!player) {
          res.json({ success: false, message: "Username or Password incorrect"});
        } else if(player){
          bcrypt.compare(req.body.password, player.password, (err, response) => {
            if(!response) {
              res.json({ success: false, message: 'Username or Password incorrect'});
            } else {
              const thePlayer = {
                _id: player._id,
                username: player.username,
                avatar: player.avatar,
                email: player.email,
                gamesDrawn: player.gamesDrawn,
                gamesLost: player.gamesLost,
                gamesWon: player.gamesWon,
                gamesPlayed: player.gamesPlayed
              }
              const token = jwt.sign({ _id: player._id, username: player.username}, secret.theSecret, { expiresIn: 60 * 60 });
              res.json({ success: true, message: "YAY TOKEN", token: token, player: thePlayer})
            }
          })
        }
      })
      .catch(next)
  },
  reauthToken(req,res,next) {
    const { token } = req.body;
    jwt.verify(token, secret.theSecret, (err,user) => {

      if(err) {
        res.json({success: false, message: 'Token Expired'})
      }

      Player.findById(user._id)
        .then((player) => {
          if(player) {

          } else {
            res.json({success: false, message: 'Could not find player'})
          }
        })

    })
  }
}


text:
<?php

namespace Magento\Sales\Ui\Component\Listing\Column\Status;

use Magento\Framework\Data\OptionSourceInterface;
use Magento\Sales\Model\ResourceModel\Order\Status\CollectionFactory;

/**
 * Class Options
 */
class Options implements OptionSourceInterface
{
    /**
     * @var array
     */
    protected $options;

    /**
     * @var CollectionFactory
     */
    protected $collectionFactory;

    /**
     * Constructor
     *
     * @param CollectionFactory $collectionFactory
     */
    public function __construct(CollectionFactory $collectionFactory)
    {
        $this->collectionFactory = $collectionFactory;
    }

    /**
     * Get options
     *
     * @return array
     */
    public function toOptionArray()
    {
        if ($this->options === null) {
            $this->options = $this->collectionFactory->create()->toOptionArray();
        }
        return $this->options;
    }
}


text:
import * as Prism from 'prismjs';
import * as components from 'prismjs/components';
import loadLanguages = require('prismjs/components/');

const element = document.createElement("code");
const container = document.querySelector("div");
const callback = (element: Element) => console.log(element);

Prism.highlightElement(element, false, callback);
Prism.highlightElement(element, false);
Prism.highlightElement(element);
Prism.highlightAll(true, callback);
Prism.highlightAll(true);
Prism.highlightAll();
if (container) {
    Prism.highlightAllUnder(container);
}
Prism.highlightAllUnder(document);

// $ExpectType "Null"
Prism.util.type(null);

// $ExpectType "Undefined"
Prism.util.type(undefined);

// $ExpectType "Boolean"
Prism.util.type(true);

// $ExpectType "Boolean"
Prism.util.type(false);

// $ExpectType "Number"
Prism.util.type(NaN);

// $ExpectType "String"
Prism.util.type("PrismJS");

// $ExpectType "Function"
Prism.util.type(callback);

// $ExpectType "RegExp"
Prism.util.type(/prism/giu);

// $ExpectType "Array"
Prism.util.type([1, 2, 3]);

const hookCallback: Prism.hooks.HookCallback = env => null;
Prism.hooks.add("before-highlightall", hookCallback);
Prism.hooks.add("future-hook", hookCallback);

Prism.hooks.add("before-highlightall", env => {
    env.selector.trim();
});

Prism.hooks.add("complete", env => {
    env.code.trim();
    env.highlightedCode.trim();
});

const language = "js";
// $ExpectType "String"
Prism.util.type(language);

const tokens = Prism.tokenize("var n = 1;", Prism.languages[language]);
(function visit(token: Prism.TokenStream): Prism.TokenStream {
    if (typeof token === "string") {
        return token;
    } else if (Array.isArray(token)) {
        return token.map(visit) as Prism.TokenStream;
    } else {
        token.alias += "visited";
        return token;
    }
})(tokens);

// $ExpectError
if (Prism.util.type(language) === "Null") {
    // `language` is a non-null string constant
}

Prism.languages.insertBefore('javascript', 'function-variable', {
    'method-variable': {
        pattern: RegExp('(\\.\\s*)'),
        lookbehind: true,
        alias: ['function-variable', 'method', 'function', 'property-access']
    }
});

// $ExpectType Record<string, any>
components.core;
// $ExpectType Record<string, any>
components.languages;
// $ExpectType Record<string, any>
components.plugins;
// $ExpectType Record<string, any>
components.themes;

loadLanguages();
loadLanguages('typescript');
loadLanguages(['javascript', 'typescript']);
loadLanguages.silent = true;


text:
package com.microsoft.windowsazure.services.media.implementation.templates.playreadylicense;

import java.security.InvalidParameterException;
import java.util.UUID;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlType;

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "ContentEncryptionKeyFromKeyIdentifier")
public class ContentEncryptionKeyFromKeyIdentifier extends PlayReadyContentKey {

    @XmlElement(name = "KeyIdentifier")
    private UUID keyIdentifier;

    public ContentEncryptionKeyFromKeyIdentifier() {

    }

    public ContentEncryptionKeyFromKeyIdentifier(UUID keyIdentifier) {
        if (keyIdentifier.equals(new UUID(0L, 0L))) {
            throw new InvalidParameterException("keyIdentifier");
        }

        this.keyIdentifier = keyIdentifier;
    }

    /**
     * @return the keyIdentifier
     */
    public UUID getKeyIdentifier() {
        return keyIdentifier;
    }

    /**
     * @param keyIdentifier
     *            the keyIdentifier to set
     */
    public void setKeyIdentifier(UUID keyIdentifier) {
        this.keyIdentifier = keyIdentifier;
    }

}