Ejemplo n.º 1
0
def news_config(request):
    users = Person.objects.filter(userid=request.user.username)
    if users.count() == 1:
        user = users[0]
    else:
        return NotFoundResponse(
            request,
            errormsg=
            "Your account is not known to this system.  There is nothing to configure."
        )

    # get appropriate UserConfig object
    configs = UserConfig.objects.filter(user=user, key='newsitems')
    if configs:
        config = configs[0]
    else:
        config = UserConfig(user=user, key='newsitems', value={})

    if request.method == 'POST':
        form = NewsConfigForm(request.POST)
        if form.is_valid():
            config.value['email'] = form.cleaned_data['want_email']
            config.save()
            messages.add_message(request, messages.SUCCESS,
                                 'News settings updated.')
            return HttpResponseRedirect(reverse('config:config'))
    else:
        initial = {
            'want_email': 'email' not in config.value or config.value['email']
        }
        form = NewsConfigForm(initial)

    context = {'form': form}
    return render(request, "dashboard/news_config.html", context)
Ejemplo n.º 2
0
def create_news_url(request):
    user = get_object_or_404(Person, userid=request.user.username)
    configs = UserConfig.objects.filter(user=user, key="feed-token")
    if request.method == 'POST':
        form = FeedSetupForm(request.POST)
        if form.is_valid():
            token = new_feed_token()
            if configs:
                c = configs[0]
                c.value = {'token': token}
            else:
                c = UserConfig(user=user,
                               key="feed-token",
                               value={'token': token})
            c.save()
            messages.add_message(request, messages.SUCCESS,
                                 'Feed URL configured.')
            return HttpResponseRedirect(reverse('config:config'))
    else:
        if configs:
            # pre-check if we're changing the token
            form = FeedSetupForm({'agree': True})
        else:
            form = FeedSetupForm()

    context = {'form': form}
    return render(request, "dashboard/news_url.html", context)
Ejemplo n.º 3
0
def photo_agreement(request):
    user = get_object_or_404(Person, userid=request.user.username)
    configs = UserConfig.objects.filter(user=user, key='photo-agreement')
    if configs:
        config = configs[0]
    else:
        config = UserConfig(user=user, key='photo-agreement', value={'agree': False})

    if request.method == 'POST':
        form = PhotoAgreementForm(request.POST)
        if form.is_valid():
            config.value['agree'] = form.cleaned_data['agree']
            if config.value['agree']:
                config.value['version'] = 1
                config.value['at'] = datetime.datetime.now().isoformat()
                config.value['from'] = ip.get_ip(request)
            config.save()
            messages.add_message(request, messages.SUCCESS, 'Updated your photo agreement status.')
            if 'return' in request.GET:
                url = request.GET['return']
            else:
                url = reverse('config:config')
            return HttpResponseRedirect(url)
    else:
        form = PhotoAgreementForm({'agree': config.value['agree']})
        
    context = {"form": form}
    return render(request, "dashboard/photo_agreement.html", context)
Ejemplo n.º 4
0
def create_calendar_url(request):
    user = get_object_or_404(Person, userid=request.user.username)
    config = _get_calendar_config(user)
    if request.method == 'POST':
        form = FeedSetupForm(request.POST)
        if form.is_valid():
            token = new_feed_token()
            config['token'] = token
            uc = UserConfig.objects.filter(user=user, key="calendar-config")
            if uc:
                uc = uc[0]
                uc.value = config
            else:
                uc = UserConfig(user=user, key="calendar-config", value=config)
            uc.save()
            messages.add_message(request, messages.SUCCESS,
                                 'Calendar URL configured.')
            return HttpResponseRedirect(reverse('config:config'))
    else:
        if 'token' in config:
            # pre-check if we're changing the token
            form = FeedSetupForm({'agree': True})
        else:
            form = FeedSetupForm()

    context = {'form': form}
    return render(request, "dashboard/calendar_url.html", context)
Ejemplo n.º 5
0
def news_config(request):
    users = Person.objects.filter(userid=request.user.username)
    if users.count() == 1:
        user = users[0]
    else:
        return NotFoundResponse(request, errormsg="Your account is not known to this system.  There is nothing to configure.")

    # get appropriate UserConfig object
    configs = UserConfig.objects.filter(user=user, key='newsitems')
    if configs:
        config = configs[0]
    else:
        config = UserConfig(user=user, key='newsitems', value={})

    if request.method == 'POST':
        form = NewsConfigForm(request.POST)
        if form.is_valid():
            config.value['email'] = form.cleaned_data['want_email']
            config.save()
            messages.add_message(request, messages.SUCCESS, 'News settings updated.')
            return HttpResponseRedirect(reverse('config:config'))
    else:
        initial = {'want_email': 'email' not in config.value or config.value['email']}
        form = NewsConfigForm(initial)

    context = {'form': form}
    return render(request, "dashboard/news_config.html", context)
Ejemplo n.º 6
0
def create_calendar_url(request):
    user = get_object_or_404(Person, userid=request.user.username)
    config = _get_calendar_config(user)
    if request.method == 'POST':
        form = FeedSetupForm(request.POST)
        if form.is_valid():
            token = new_feed_token()
            config['token'] = token
            uc = UserConfig.objects.filter(user=user, key="calendar-config")
            if uc:
                uc = uc[0]
                uc.value = config
            else:
                uc = UserConfig(user=user, key="calendar-config", value=config)
            uc.save()
            messages.add_message(request, messages.SUCCESS, 'Calendar URL configured.')
            return HttpResponseRedirect(reverse('config:config'))
    else:
        if 'token' in config:
            # pre-check if we're changing the token
            form = FeedSetupForm({'agree': True})
        else:
            form = FeedSetupForm()

    context = {'form': form}
    return render(request, "dashboard/calendar_url.html", context)
Ejemplo n.º 7
0
def photo_agreement(request):
    user = get_object_or_404(Person, userid=request.user.username)
    configs = UserConfig.objects.filter(user=user, key='photo-agreement')
    if configs:
        config = configs[0]
    else:
        config = UserConfig(user=user,
                            key='photo-agreement',
                            value={'agree': False})

    if request.method == 'POST':
        form = PhotoAgreementForm(request.POST)
        if form.is_valid():
            config.value['agree'] = form.cleaned_data['agree']
            if config.value['agree']:
                config.value['version'] = 1
                config.value['at'] = datetime.datetime.now().isoformat()
                config.value['from'] = ip.get_ip(request)
            config.save()
            messages.add_message(request, messages.SUCCESS,
                                 'Updated your photo agreement status.')
            if 'return' in request.GET:
                url = request.GET['return']
            else:
                url = reverse('config:config')
            return HttpResponseRedirect(url)
    else:
        form = PhotoAgreementForm({'agree': config.value['agree']})

    context = {"form": form}
    return render(request, "dashboard/photo_agreement.html", context)
Ejemplo n.º 8
0
def enable_advisor_token(request):
    user = get_object_or_404(Person, userid=request.user.username)
    configs = UserConfig.objects.filter(user=user, key="advisor-token")
    if not len(configs) is 0:
        raise Http404
    if request.method == 'POST':
        form = FeedSetupForm(request.POST)
        if form.is_valid():
            config = {'token': new_feed_token()}
            uc = UserConfig(user=user, key="advisor-token", value=config)
            uc.save()
            messages.add_message(request, messages.SUCCESS, 'Advisor notes API enabled')
            return HttpResponseRedirect(reverse('config:config'))
    else:
        form = FeedSetupForm()
    return render(request, "dashboard/enable_advisor_token.html", {"form": form})
Ejemplo n.º 9
0
def enable_advisor_token(request):
    user = get_object_or_404(Person, userid=request.user.username)
    configs = UserConfig.objects.filter(user=user, key="advisor-token")
    if not len(configs) is 0:
        raise Http404
    if request.method == 'POST':
        form = FeedSetupForm(request.POST)
        if form.is_valid():
            config = {'token': new_feed_token()}
            uc = UserConfig(user=user, key="advisor-token", value=config)
            uc.save()
            messages.add_message(request, messages.SUCCESS, 'Advisor notes API enabled')
            return HttpResponseRedirect(reverse('dashboard.views.config'))
    else:
        form = FeedSetupForm()
    return render(request, "dashboard/enable_advisor_token.html", {"form": form})
Ejemplo n.º 10
0
def create_news_url(request):
    user = get_object_or_404(Person, userid=request.user.username)
    configs = UserConfig.objects.filter(user=user, key="feed-token")
    if request.method == 'POST':
        form = FeedSetupForm(request.POST)
        if form.is_valid():
            token = new_feed_token()
            if configs:
                c = configs[0]
                c.value = {'token':token}
            else:
                c = UserConfig(user=user, key="feed-token", value={'token':token})
            c.save()
            messages.add_message(request, messages.SUCCESS, 'Feed URL configured.')
            return HttpResponseRedirect(reverse('config:config'))
    else:
        if configs:
            # pre-check if we're changing the token
            form = FeedSetupForm({'agree': True})
        else:
            form = FeedSetupForm()

    context = {'form': form}
    return render(request, "dashboard/news_url.html", context)
Ejemplo n.º 11
0
def create_more_data():
    """
    More data for the unit tests and general usabilty of a test system
    """
    templates = [
        {
            "field":
            "contact_email_text",
            "label":
            "generic",
            "text":
            "DESCRIPTION OF INCIDENT. This does not usually occur unless there is a violation of SFU's Code of Academic Integrity and Good Conduct, Policy S10.01. I take academic honesty very seriously and intend to pursue this apparent violation of SFU's standards for academic honesty.\r\n\r\nAs required by SFU Policy S10.02, Principles and Procedures for Academic Discipline, I am offering you the opportunity to meet with me to discuss this incident. You are not required to accept this offer. If you would like to meet, please contact me to make an appointment outside of my regular office hours.\r\n\r\nYou may wish to refer to SFU's policies and procedures on academic integrity,\r\n  http://www.sfu.ca/policies/Students/index.html .\r\nYou can also contact the Office of the Ombudsperson for assistance in navigating University procedures.\r\n"
        },
        {
            "field":
            "contact_email_text",
            "label":
            "not your work",
            "text":
            "Your submission for {{ACTIVITIES}} contains work that does not appear to be your own. This indicates that there is a violation of SFU's Code of Academic Integrity and Good Conduct, Policy S10.01. I take academic honesty very seriously and intend to pursue this apparent violation of SFU's standards for academic honesty.\r\n\r\nAs required by SFU Policy S10.02, Principles and Procedures for Academic Discipline, I am offering you the opportunity to meet with me to discuss this incident. You are not required to accept this offer. If you would like to meet, please contact me to make an appointment outside of my regular office hours.\r\n\r\nYou may wish to refer to SFU's policies and procedures on academic integrity,\r\n  http://www.sfu.ca/policies/Students/index.html .\r\nYou can also contact the Office of the Ombudsperson for assistance in navigating University procedures.\r\n"
        },
        {
            "field": "facts",
            "label": "attachment",
            "text": "See details in attached file facts.pdf."
        },
        {
            "field":
            "contact_email_text",
            "label":
            "simiar work (group)",
            "text":
            "You and other students submitted very similar work on {{ACTIVITIES}}. This level of similarity does not usually occur unless collaboration exceeds the limits allowed by SFU's Code of Academic Integrity and Good Conduct, Policy S10.01. I take academic honesty very seriously and intend to pursue this apparent violation of SFU's standards for academic honesty.\r\n\r\nAs required by SFU Policy S10.02, Principles and Procedures for Academic Discipline, I am offering you the opportunity to meet with me to discuss this incident. You are not required to accept this offer. If you would like to meet, please contact me to make an appointment outside of my regular office hours.\r\n\r\nYou may wish to refer to SFU's policies and procedures on academic integrity,\r\n  http://www.sfu.ca/policies/Students/index.html .\r\nYou can also contact the Office of the Ombudsperson for assistance in navigating University procedures.\r\n"
        },
        {
            "field":
            "facts",
            "label":
            "copied (other knew)",
            "text":
            "{{FNAME}} was given a solution to {{ACTIVITIES}} by another student. The other student seems to have completed the work independently. Both students submitted the work as their own."
        },
        {
            "field":
            "facts",
            "label":
            "copied (without knowledge)",
            "text":
            "{{FNAME}} copied the work of another student on {{ACTIVITIES}} without his/her knowledge.  Both students submitted the work as their own."
        },
        {
            "field":
            "meeting_summary",
            "label":
            "admitted",
            "text":
            u"The student admitted academic dishonesty as described below in \u201cfacts of the case\u201d."
        },
        {
            "field":
            "meeting_summary",
            "label":
            "quote email",
            "text":
            "The student explained the situation in his/her email:\r\n\r\nbq. PASTE QUOTE HERE"
        },
        {
            "field": "meeting_summary",
            "label": "explained",
            "text": "{{FNAME}} explained that..."
        },
    ]
    for data in templates:
        t = DisciplineTemplate(**data)
        t.save()

    cmpt = Unit.objects.get(slug='cmpt')
    a = Account(account_number=12345,
                position_number=12345,
                title='MSc TA',
                unit=cmpt)
    a.save()
    a = Account(account_number=12346,
                position_number=12346,
                title='PhD TA',
                unit=cmpt)
    a.save()
    a = Account(account_number=12347,
                position_number=12347,
                title='External TA',
                unit=cmpt)
    a.save()
    a = Account(account_number=12348,
                position_number=12348,
                title='Undergrad TA',
                unit=cmpt)
    a.save()

    uc = UserConfig(user=Person.objects.get(userid='dzhao'),
                    key='advisor-token',
                    value={'token': '30378700c0091f34412ec9a082dca267'})
    uc.save()
    uc = UserConfig(user=Person.objects.get(userid='ggbaker'),
                    key='advisor-token',
                    value={'token': '082dca26730378700c0091f34412ec9a'})
    uc.save()
    p = Person(userid='probadmn',
               emplid='200002387',
               first_name='Problem',
               last_name='Admin')
    p.save()
    uc = UserConfig(user=p,
                    key='problems-token',
                    value={'token': '30378700c0091f34412ec9a082dca268'})
    uc.save()

    p = Person(userid='teachadm',
               emplid='200002388',
               first_name='Teaching',
               last_name='Admin')
    p.save()
    r = Role(person=p, role="TADM", unit=Unit.objects.get(slug='cmpt'))
    r.save()
    #sp = SemesterPlan(semester=Semester.objects.get(name=TEST_SEMESTER), name='Test Plan', unit=Unit.objects.get(slug='cmpt'), slug='test-plan')
    #sp.save()
    #o = PlannedOffering(plan=sp, course=Course.objects.get(slug='cmpt-102'), section='D100', campus='BRNBY', enrl_cap=100)
    #o.save()
    #PlanningCourse.create_for_unit(Unit.objects.get(slug='cmpt'))
    #te = TeachingEquivalent(pk=1, instructor=Person.objects.get(userid='ggbaker'), semester=Semester.objects.get(name=TEST_SEMESTER), credits_numerator=1, credits_denominator=1, summary="Foo", status='UNCO')
    #te.save()
    #ti = TeachingIntention(instructor=Person.objects.get(userid='ggbaker'), semester=Semester.objects.get(name=TEST_SEMESTER), count=2)
    #ti.save()
    #tc = TeachingCapability(instructor=Person.objects.get(userid='ggbaker'), course=Course.objects.get(slug='cmpt-102'), note='foo')
    #tc.save()

    p = Person(userid='classam',
               emplid='200002389',
               first_name='Curtis',
               last_name='Lassam')
    p.save()
    r = Role(person=p, role="TECH", unit=Unit.objects.get(slug='cmpt'))
    r.save()
    r = Role(person=p, role="SYSA", unit=Unit.objects.get(slug='cmpt'))
    r.save()

    # create some faculty roles
    members = Member.objects.filter(role='INST', offering__owner__slug='cmpt')
    instr = set(m.person for m in members)
    faculty = random.sample(instr, 10)
    for p in faculty:
        Role.objects.get_or_create(person=p, role='FAC', unit=cmpt)
Ejemplo n.º 12
0
def create_more_data():
    """
    More data for the unit tests and general usabilty of a test system
    """
    templates = [
                 {"field": "contact_email_text",
                  "label": "generic",
                  "text": "DESCRIPTION OF INCIDENT. This does not usually occur unless there is a violation of SFU's Code of Academic Integrity and Good Conduct, Policy S10.01. I take academic honesty very seriously and intend to pursue this apparent violation of SFU's standards for academic honesty.\r\n\r\nAs required by SFU Policy S10.02, Principles and Procedures for Academic Discipline, I am offering you the opportunity to meet with me to discuss this incident. You are not required to accept this offer. If you would like to meet, please contact me to make an appointment outside of my regular office hours.\r\n\r\nYou may wish to refer to SFU's policies and procedures on academic integrity,\r\n  http://www.sfu.ca/policies/Students/index.html .\r\nYou can also contact the Office of the Ombudsperson for assistance in navigating University procedures.\r\n"},
                 {"field": "contact_email_text",
                  "label": "not your work",
                  "text": "Your submission for {{ACTIVITIES}} contains work that does not appear to be your own. This indicates that there is a violation of SFU's Code of Academic Integrity and Good Conduct, Policy S10.01. I take academic honesty very seriously and intend to pursue this apparent violation of SFU's standards for academic honesty.\r\n\r\nAs required by SFU Policy S10.02, Principles and Procedures for Academic Discipline, I am offering you the opportunity to meet with me to discuss this incident. You are not required to accept this offer. If you would like to meet, please contact me to make an appointment outside of my regular office hours.\r\n\r\nYou may wish to refer to SFU's policies and procedures on academic integrity,\r\n  http://www.sfu.ca/policies/Students/index.html .\r\nYou can also contact the Office of the Ombudsperson for assistance in navigating University procedures.\r\n"},
                 {"field": "facts",
                  "label": "attachment",
                  "text": "See details in attached file facts.pdf."},
                 {"field": "contact_email_text",
                  "label": "simiar work (group)",
                  "text": "You and other students submitted very similar work on {{ACTIVITIES}}. This level of similarity does not usually occur unless collaboration exceeds the limits allowed by SFU's Code of Academic Integrity and Good Conduct, Policy S10.01. I take academic honesty very seriously and intend to pursue this apparent violation of SFU's standards for academic honesty.\r\n\r\nAs required by SFU Policy S10.02, Principles and Procedures for Academic Discipline, I am offering you the opportunity to meet with me to discuss this incident. You are not required to accept this offer. If you would like to meet, please contact me to make an appointment outside of my regular office hours.\r\n\r\nYou may wish to refer to SFU's policies and procedures on academic integrity,\r\n  http://www.sfu.ca/policies/Students/index.html .\r\nYou can also contact the Office of the Ombudsperson for assistance in navigating University procedures.\r\n"},
                 {"field": "facts",
                  "label": "copied (other knew)",
                  "text": "{{FNAME}} was given a solution to {{ACTIVITIES}} by another student. The other student seems to have completed the work independently. Both students submitted the work as their own."},
                 {"field": "facts",
                  "label": "copied (without knowledge)",
                  "text": "{{FNAME}} copied the work of another student on {{ACTIVITIES}} without his/her knowledge.  Both students submitted the work as their own."},
                 {"field": "meeting_summary",
                  "label": "admitted",
                  "text": "The student admitted academic dishonesty as described below in \u201cfacts of the case\u201d."},
                 {"field": "meeting_summary",
                  "label": "quote email",
                  "text": "The student explained the situation in his/her email:\r\n\r\nbq. PASTE QUOTE HERE"},
                 {"field": "meeting_summary",
                  "label": "explained",
                  "text": "{{FNAME}} explained that..."},
                 ]
    for data in templates:
        t = DisciplineTemplate(**data)
        t.save()

    cmpt = Unit.objects.get(slug='cmpt')
    a = Account(account_number=12345, position_number=12345, title='MSc TA', unit=cmpt)
    a.save()
    a = Account(account_number=12346, position_number=12346, title='PhD TA', unit=cmpt)
    a.save()
    a = Account(account_number=12347, position_number=12347, title='External TA', unit=cmpt)
    a.save()
    a = Account(account_number=12348, position_number=12348, title='Undergrad TA', unit=cmpt)
    a.save()

    uc = UserConfig(user=Person.objects.get(userid='dzhao'), key='advisor-token', value={'token': '30378700c0091f34412ec9a082dca267'})
    uc.save()
    uc = UserConfig(user=Person.objects.get(userid='ggbaker'), key='advisor-token', value={'token': '082dca26730378700c0091f34412ec9a'})
    uc.save()
    p = Person(userid='probadmn', emplid='200002387', first_name='Problem', last_name='Admin')
    p.save()
    uc = UserConfig(user=p, key='problems-token', value={'token': '30378700c0091f34412ec9a082dca268'})
    uc.save()

    p = Person(userid='teachadm', emplid='200002388', first_name='Teaching', last_name='Admin')
    p.save()
    r = Role(person=p, role="TADM", unit=Unit.objects.get(slug='cmpt'))
    r.save()
    #sp = SemesterPlan(semester=Semester.objects.get(name=TEST_SEMESTER), name='Test Plan', unit=Unit.objects.get(slug='cmpt'), slug='test-plan')
    #sp.save()
    #o = PlannedOffering(plan=sp, course=Course.objects.get(slug='cmpt-102'), section='D100', campus='BRNBY', enrl_cap=100)
    #o.save()
    #PlanningCourse.create_for_unit(Unit.objects.get(slug='cmpt'))
    #te = TeachingEquivalent(pk=1, instructor=Person.objects.get(userid='ggbaker'), semester=Semester.objects.get(name=TEST_SEMESTER), credits_numerator=1, credits_denominator=1, summary="Foo", status='UNCO')
    #te.save()
    #ti = TeachingIntention(instructor=Person.objects.get(userid='ggbaker'), semester=Semester.objects.get(name=TEST_SEMESTER), count=2)
    #ti.save()
    #tc = TeachingCapability(instructor=Person.objects.get(userid='ggbaker'), course=Course.objects.get(slug='cmpt-102'), note='foo')
    #tc.save()

    p = Person(userid='classam', emplid='200002389', first_name='Curtis', last_name='Lassam')
    p.save()
    r = Role(person=p, role="TECH", unit=Unit.objects.get(slug='cmpt'))
    r.save()
    r = Role(person=p, role="SYSA", unit=Unit.objects.get(slug='cmpt'))
    r.save()

    # create some faculty roles
    members = Member.objects.filter(role='INST', offering__owner__slug='cmpt')
    instr = set(m.person for m in members)
    faculty = random.sample(instr, 10)
    for p in faculty:
        Role.objects.get_or_create(person=p, role='FAC', unit=cmpt)
Ejemplo n.º 13
0
def create_coredata():
    """
    Create enough of the coredata.models stuff to run basic tests
    """
    create_units()

    # restore ggbaker's real emplid so import_offerings will match
    p = find_person('ggbaker')
    p.emplid = find_emplid('ggbaker')
    p.first_name = 'Gregorʏ'
    p.pref_first_name = 'Greg'
    p.save()

    # import a few more people we definitely need later
    find_person('popowich')
    find_person('dixon')
    find_person('diana')
    find_person('dzhao')
    find_person('pba7')

    # import a limited set of course offerings
    offerings = import_offerings(
        import_semesters=import_strms,
        extra_where="(subject='CMPT' AND (catalog_nbr LIKE '%% 12%%')) "
        "OR (subject='CMPT' AND (catalog_nbr LIKE '%% 16%%')) "
        "OR (subject='ENSC' AND (catalog_nbr LIKE '%% 10%%')) ")
    offerings = list(offerings)
    offerings.sort()

    if not CourseOffering.objects.filter(slug=TEST_COURSE_SLUG):
        o = CourseOffering.objects.filter(subject='CMPT', semester__name=import_strms()[0]) \
            .order_by('number', 'section').first()
        raise ValueError(
            "courselib.testing.TEST_COURSE_SLUG isn't an offering we have. Maybe use '%s'."
            % (o.slug))

    # import instructors
    for o in offerings:
        import_offering_members(o, students=False)

    # try to guess instructors' userids
    for p in Person.objects.filter(userid__isnull=True):
        p.userid = guess_userid(p.emplid)
        p.save()

    fake_emplids()
    p = find_person('ggbaker')
    p.first_name = 'Gregorʏ'
    p.pref_first_name = 'Greg'
    p.save()

    # use/import no real emplids after this

    # create some fake undergrad/grad students
    for i in range(20):
        userid = "0aaa%i" % (i)
        fname = randname(8)
        p = random.randint(1, 2)
        if p == 1:
            pref = fname[:4]
        else:
            pref = fname
        p = Person(emplid=300000300 + i,
                   userid=userid,
                   last_name='Student',
                   first_name=fname,
                   middle_name=randname(6),
                   pref_first_name=pref)
        p.save()

        userid = "0ggg%i" % (i)
        fname = randname(8)
        p = random.randint(1, 2)
        if p == 1:
            pref = fname[:4]
        else:
            pref = fname
        p = Person(emplid=300000500 + i,
                   userid=userid,
                   last_name='Grad',
                   first_name=fname,
                   middle_name=randname(6),
                   pref_first_name=pref)
        p.config['gender'] = random.choice(('M', 'F', 'U'))
        p.config['gpa'] = round(random.triangular(0.0, 4.33, 2.33), 2)
        p.config['visa'] = random.choice([x for x, _ in VISA_STATUSES])
        p.config['citizen'] = random.choice(('Canadian', 'OtherCountrian'))
        p.save()

    # some memberships/roles/etc assumed by tests
    o = CourseOffering.objects.get(slug=TEST_COURSE_SLUG)
    ensure_member(Person.objects.get(userid='ggbaker'), o, "INST", 0, "AUTO",
                  "NONS")
    ensure_member(Person.objects.get(userid='0ggg0'), o, "TA", 0, "AUTO",
                  "NONS")
    ensure_member(Person.objects.get(userid='0aaa0'), o, "STUD", 3, "AUTO",
                  "UGRD")
    ensure_member(Person.objects.get(userid='0aaa1'), o, "STUD", 3, "AUTO",
                  "UGRD")

    d = Person.objects.get(userid='dzhao')
    set_privacy_signed(d)
    set_privacy_da_signed(d)
    config = UserConfig(user=d, key='photo-agreement', value={'agree': True})
    config.save()
    u = Unit.objects.get(slug='cmpt')
    r1 = Role(person=d, role='ADVS', unit=u, expiry=role_expiry)
    r1.save()
    r2 = Role(person=d, role='ADMN', unit=u, expiry=role_expiry)
    r2.save()
    r3 = Role(person=Person.objects.get(userid='pba7'),
              role='SYSA',
              unit=Unit.objects.get(slug='univ'),
              expiry=role_expiry)
    r3.save()
    r4 = Role(person=d, role='INV', unit=u, expiry=role_expiry)
    r4.save()
    r5 = Role(person=d, role='OUTR', unit=u, expiry=role_expiry)
    r5.save()
    r6 = Role(person=d, role='SPAC', unit=u, expiry=role_expiry)
    r6.save()

    # ensures course appears in menu for students
    a = NumericActivity(offering=o,
                        name='Assignmenț 1',
                        short_name='A1',
                        status='URLS',
                        position=1,
                        percent=10,
                        max_grade=10,
                        due_date=(o.semester.start +
                                  datetime.timedelta(days=60)))
    a.save()

    return itertools.chain(
        SemesterWeek.objects.filter(semester__name__gt=SEMESTER_CUTOFF),
        Unit.objects.all(),
        Course.objects.all(),
        CourseOffering.objects.all(),
        Person.objects.order_by('emplid'),
        Member.objects.all(),
        UserConfig.objects.all(),
        [r1, r2, r3, r4, r5, r6, a.activity_ptr, a],
    )