<commit_before>from django.contrib import admin

import datetime

from mptt.admin import MPTTModelAdmin
from fsm_admin.mixins import FSMTransitionMixin

from .inlines import (
    ArrangerInline,
    AwardInline,
    CertificationInline,
    ContestantInline,
    SessionInline,
    PerformerInline,
    PerformerStackedInline,
    DirectorInline,
    GroupInline,
    JudgeInline,
    PerformanceInline,
    ScoreInline,
    RoundInline,
    RankingInline,
    SingerInline,
    SongStackedInline,
    OrganizationInline,
)

from .models import (
    Arranger,
    Award,
    Catalog,
    Chapter,
    Contestant,
    Session,
    Performer,
    Convention,
    Group,
    Judge,
    Organization,
    Performance,
    Person,
    Score,
    Round,
    Song,
    Tune,
    User,
)

import arrow

# from grappelli.forms import GrappelliSortableHiddenMixin
from super_inlines.admin import SuperModelAdmin

@admin.register(Arranger)
class ArrangerAdmin(admin.ModelAdmin):
    list_display = [
        'name',
        'catalog',
        'person',
    ]

@admin.register(Award)
class AwardAdmin(admin.ModelAdmin):
    change_list_template = "admin/change_list_filter_sidebar.html"
    list_display = [
        'name',
        'organization',
        'get_long_name',
        'get_level',
        'kind',
        'long_name',
        'stix_name',
    ]

    list_filter = [
        'status',
        'kind',
        'organization',
    ]

    def get_long_name(self, obj):
        return obj.organization.long_name
    get_long_name.short_description = 'Org Name'
    get_long_name.admin_order_field = 'organization__long_name'

    def get_level(self, obj):
        return obj.organization.get_kind_display()
    get_level.short_description = 'Org Level'
    get_level.admin_order_field = 'organization__level'

@admin.register(Catalog)
class CatalogAdmin(admin.ModelAdmin):
    list_display = [
        'song_name',
        'tune',
        'bhs_id',
        'bhs_songname',
        'bhs_arranger',
    ]

@admin.register(Chapter)
class ChapterAdmin(admin.ModelAdmin):
    search_fields = (
        'name',
    )

    list_display = (
        'name',
        'organization',
        'code',
        # 'status',
        # 'status_monitor',
        # 'location',
        # 'website',
        # 'facebook',
        # 'twitter',
        # 'email',
        # 'phone',
        # 'picture',
    )

    list_filter = (
        'organization',
        'status',
    )

    fields = (
        'name',
        # ('status', 'status_monitor',),
        'organization',
        'location',
        'website',
        'facebook',
        'twitter',
        'email',
        'phone',
        'picture',
        'description',
        'code',
        'notes',
    )

    inlines = [
        GroupInline,
    ]

    readonly_fields = (
        # 'status_monitor',
    )
    save_on_top = True

@admin.register(Contestant)
class ContestantAdmin(admin.ModelAdmin):
    change_list_template = "admin/change_list_filter_sidebar.html"
    search_fields = [
        'name',
    ]
    fields = [
        'name',
        ('status', 'status_monitor',),
        'performer',
        'place',
        'total_score',
    ]
    list_filter = (
        'status',
    )

    autocomplete_lookup_fields = {
        'fk': [
            'performer',
        ]
    }
    readonly_fields = [
        'name',
        'status_monitor',
        'place',
        'total_score',
    ]

    raw_id_fields = [
        'performer',
    ]

@admin.register(Convention)
class ConventionAdmin(FSMTransitionMixin, admin.ModelAdmin):

    def human_range(self, obj):
        if obj.date:
            if obj.date.upper - obj.date.lower == datetime.timedelta(1):
                dates = "{0}".format(
                    arrow.get(obj.date.lower).format('MMMM D, YYYY'),
                )
            else:
                dates = "{0} - {1}".format(
                    arrow.get(obj.date.lower).format('MMMM D'),
                    arrow.get(obj.date.upper).format('MMMM D, YYYY'),
                )
        else:
            dates = obj.date
        return dates
    human_range.short_description = "Dates22"

    fsm_field = [
        'status',
    ]

    change_list_template = "admin/change_list_filter_sidebar.html"
    search_fields = (
        'name',
    )

    list_display = (
        'name',
        'status',
        'organization',
        'kind',
        'division',
        # 'date',
        'human_range',
        # 'location',
    )

    fields = (
        'name',
        ('status', 'status_monitor',),
        # 'stix_name',
        # 'stix_div',
        ('location', 'timezone',),
        # 'dates',
        'date',
        'organization',
        'drcj',
        'kind',
        # 'stix_file',
        'division',
    )

    list_filter = (
        'status',
        'kind',
        'year',
        'organization__level',
        'division',
        'organization',
    )

    inlines = [
        SessionInline,
        # OrganizationInline,
    ]

    readonly_fields = (
        'name',
        'status_monitor',
        'year',
    )

    raw_id_fields = [
        'drcj',
    ]

    save_on_top = True

@admin.register(Group)
class GroupAdmin(admin.ModelAdmin):
    search_fields = (
        'name',
        'chapter__name',
    )

    list_display = (
        'name',
        'chapter',
        'status',
        'status_monitor',
        'location',
        'website',
        'facebook',
        'twitter',
        'email',
        'phone',
        'picture',
    )

    fields = (
        'name',
        ('status', 'status_monitor',),
        'kind',
        'organization',
        'chapter',
        'location',
        'website',
        'facebook',
        'twitter',
        'email',
        'phone',
        'picture',
        'description',
        'notes',
    )

    list_filter = (
        'kind',
    )

    inlines = [
        PerformerInline,
    ]

    readonly_fields = (
        'status_monitor',
    )

    raw_id_fields = [
        'chapter',
    ]

    autocomplete_lookup_fields = {
        'fk': [
            'chapter',
        ]
    }

    save_on_top = True

@admin.register(Judge)
class JudgeAdmin(admin.ModelAdmin):
    change_list_template = "admin/change_list_filter_sidebar.html"
    save_on_top = True
    fields = [
        'name',
        ('status', 'status_monitor',),
        'session',
        'person',
        'organization',
        ('category', 'slot',),
    ]

    list_display = [
        'name',
        'status',
        'person',
        'organization',
    ]

    list_filter = (
        'status',
    )

    list_select_related = [
        'organization',
        'session',
        'person',
    ]

    raw_id_fields = (
        'session',
        'person',
    )

    autocomplete_lookup_fields = {
        'fk': [
            'session',
            'person',
        ]
    }

    readonly_fields = [
        'name',
    ]

    inlines = [
        ScoreInline,
    ]

@admin.register(Organization)
class OrganizationAdmin(MPTTModelAdmin):
    fields = [
        'name',
        ('status', 'status_monitor',),
        'parent',
        'kind',
        'code',
        'short_name',
        'long_name',
        'location',
        'website',
        'facebook',
        'twitter',
        'email',
        'phone',
        'picture',
        'description',
        'notes',
    ]

    list_filter = [
        'status',
        'level',
        'kind',
    ]

    readonly_fields = [
        'status_monitor',
    ]

    list_display = [
        'name',
        'short_name',
        'long_name',
        'status',
        'kind',
    ]

    inlines = [
        AwardInline,
    ]

    # ordering = [
    #     'tree_id',
    # ]

@admin.register(Performance)
class PerformanceAdmin(FSMTransitionMixin, SuperModelAdmin):
    fsm_field = [
        'status',
    ]

    save_on_top = True
    change_list_template = "admin/change_list_filter_sidebar.html"

    inlines = [
        SongStackedInline,
        # RoundInline,
    ]
    list_display = [
        'name',
        'status',
        'draw',
        'total_score',
    ]
    list_filter = [
        'status',
        'round',
    ]

    fields = [
        'name',
        ('status', 'status_monitor',),
        'performer',
        ('draw', 'scheduled'),
        ('mus_points', 'prs_points', 'sng_points', 'total_points',),
        ('mus_score', 'prs_score', 'sng_score', 'total_score',),
    ]

    readonly_fields = [
        'name',
        'status_monitor',
        'mus_points',
        'prs_points',
        'sng_points',
        'total_points',
        'mus_score',
        'prs_score',
        'sng_score',
        'total_score',
        'draw',
    ]

    raw_id_fields = (
        'performer',
    )
    autocomplete_lookup_fields = {
        'fk': [
            'performer',
        ]
    }

    search_fields = (
        'name',
    )

@admin.register(Performer)
class PerformerAdmin(FSMTransitionMixin, admin.ModelAdmin):
    fsm_field = [
        'status',
    ]

    change_list_template = "admin/change_list_filter_sidebar.html"

    inlines = [
        SingerInline,
        DirectorInline,
        PerformanceInline,
        ContestantInline,
    ]

    list_display = (
        'name',
        'status',
        'seed',
        'prelim',
        # 'mus_score',
        # 'prs_score',
        # 'sng_score',
        # 'total_score',
        'men',
    )

    search_fields = (
        'name',
    )

    list_filter = (
        'status',
    )

    raw_id_fields = (
        'session',
        'group',
    )

    autocomplete_lookup_fields = {
        'fk': [
            'session',
            'group',
        ]
    }
    fields = (
        'name',
        ('status', 'status_monitor',),
        'session',
        ('group', 'organization',),
        ('seed', 'prelim',),
        ('men',),
        # ('mus_points', 'prs_points', 'sng_points', 'total_points',),
        # ('mus_score', 'prs_score', 'sng_score', 'total_score',),
    )

    readonly_fields = (
        'organization',
        'name',
        'status_monitor',
        'mus_points',
        'prs_points',
        'sng_points',
        'total_points',
        'mus_score',
        'prs_score',
        'sng_score',
        'total_score',
    )

    save_on_top = True

@admin.register(Person)
class PersonAdmin(admin.ModelAdmin):
    search_fields = (
        'name',
    )

    save_on_top = True
    list_display = (
        'name',
        'status',
        'status_monitor',
        'member',
        'location',
        'website',
        'facebook',
        'twitter',
        'email',
        'phone',
        'picture',
        'bhs_member_id',
        'bhs_name',
        'bhs_city',
        'bhs_state',
        'bhs_phone',
        'bhs_email',
    )

    fields = (
        'name',
        ('status', 'status_monitor',),
        'organization',
        'location',
        'website',
        'facebook',
        'twitter',
        'email',
        'phone',
        'member',
        'picture',
        'description',
        'bhs_city',
        'notes',
    )

    list_filter = [
        'status',
    ]

    readonly_fields = (
        'status_monitor',
    )
    inlines = [
        DirectorInline,
        SingerInline,
        ArrangerInline,
        CertificationInline,
    ]

@admin.register(Round)
class RoundAdmin(FSMTransitionMixin, admin.ModelAdmin):
    fsm_field = [
        'status',
    ]

    save_on_top = True
    change_list_template = "admin/change_list_filter_sidebar.html"
    list_display = [
        'name',
        'status',
        'slots',
    ]
    fields = [
        'name',
        ('status', 'status_monitor',),
        ('session', 'kind',),
        ('slots',),
    ]

    readonly_fields = [
        'name',
        'status_monitor',
        'session',
        'kind',
    ]

    list_filter = (
        'status',
    )

    raw_id_fields = (
        'session',
    )

    autocomplete_lookup_fields = {
        'fk': [
            'session',
        ]
    }

    inlines = [
        PerformanceInline,
    ]

    search_fields = [
        'name',
    ]

@admin.register(Score)
class ScoreAdmin(admin.ModelAdmin):
    change_list_template = "admin/change_list_filter_sidebar.html"
    save_on_top = True
    fields = [
        'name',
        # ('status', 'status_monitor',),
        'song',
        'judge',
        'points',
    ]

    readonly_fields = [
        'name',
        # 'status_monitor',
        'song',
        'judge',
    ]

    list_display = [
        'name',
        # 'status',
        'points',
    ]

    # list_filter = [
    #     'status',
    # ]

    raw_id_fields = [
        'song',
        'judge',
    ]

    autocomplete_lookup_fields = {
        'fk': [
            'song',
            'judge',
        ]
    }

    ordering = [
        'song',
        'judge',
    ]

@admin.register(Session)
class SessionAdmin(FSMTransitionMixin, SuperModelAdmin):
    fsm_field = [
        'status',
    ]

    change_list_template = "admin/change_list_filter_sidebar.html"
    save_on_top = True
    fields = [
        'name',
        ('status', 'status_monitor',),
        ('history', 'history_monitor',),
        'convention',
        'kind',
        'administrator',
        # 'organization',
        # 'year',
        # # 'size',
        # 'num_rounds',
    ]

    list_display = [
        'name',
        'status',
        'convention',
        'kind',
        'administrator',
        # 'size',
        # 'num_rounds',
    ]

    list_filter = (
        'status',
        'history',
        'kind',
        'convention__year',
        'organization',
        'administrator',
    )

    raw_id_fields = (
        'convention',
    )

    autocomplete_lookup_fields = {
        'fk': [
            'convention',
        ]
    }

    readonly_fields = [
        'name',
        'status_monitor',
        'history_monitor',
        'organization',
    ]

    inlines = [
        RoundInline,
        PerformerInline,
        JudgeInline,
    ]

@admin.register(Song)
class SongAdmin(admin.ModelAdmin):
    change_list_template = "admin/change_list_filter_sidebar.html"
    save_on_top = True
    list_display = (
        'name',
        # 'status',
        'title',
        # 'tune',
        'mus_points',
        'prs_points',
        'sng_points',
        'total_points'
    )

    search_fields = (
        'name',
        'title',
    )

    fields = [
        'name',
        # ('status', 'status_monitor',),
        'order',
        ('mus_points', 'prs_points', 'sng_points', 'total_points',),
        ('mus_score', 'prs_score', 'sng_score', 'total_score',),
        'title',
        # 'tune',
        # 'catalog',
    ]

    inlines = [
        # ArrangersInline,
        ScoreInline,
    ]

    # list_filter = (
    #     'status',
    # )

    readonly_fields = (
        'name',
        'order',
        'mus_points',
        'prs_points',
        'sng_points',
        'total_points',
        'mus_score',
        'prs_score',
        'sng_score',
        'total_score',
        # 'status_monitor',
    )
    raw_id_fields = (
        'performance',
        # 'tune',
        # 'catalog',
    )
    autocomplete_lookup_fields = {
        'fk': [
            'performance',
            # 'tune',
        ]
    }

    ordering = (
        'name',
        'order',
    )

@admin.register(Tune)
class TuneAdmin(admin.ModelAdmin):
    save_on_top = True
    fields = (
        'name',
    )

    search_fields = (
        'name',
    )

@admin.register(User)
class UserAdmin(admin.ModelAdmin):
    model = User
    save_on_top = True
<commit_msg>Add code to search<commit_after>from django.contrib import admin

import datetime

from mptt.admin import MPTTModelAdmin
from fsm_admin.mixins import FSMTransitionMixin

from .inlines import (
    ArrangerInline,
    AwardInline,
    CertificationInline,
    ContestantInline,
    SessionInline,
    PerformerInline,
    PerformerStackedInline,
    DirectorInline,
    GroupInline,
    JudgeInline,
    PerformanceInline,
    ScoreInline,
    RoundInline,
    RankingInline,
    SingerInline,
    SongStackedInline,
    OrganizationInline,
)

from .models import (
    Arranger,
    Award,
    Catalog,
    Chapter,
    Contestant,
    Session,
    Performer,
    Convention,
    Group,
    Judge,
    Organization,
    Performance,
    Person,
    Score,
    Round,
    Song,
    Tune,
    User,
)

import arrow

# from grappelli.forms import GrappelliSortableHiddenMixin
from super_inlines.admin import SuperModelAdmin

@admin.register(Arranger)
class ArrangerAdmin(admin.ModelAdmin):
    list_display = [
        'name',
        'catalog',
        'person',
    ]

@admin.register(Award)
class AwardAdmin(admin.ModelAdmin):
    change_list_template = "admin/change_list_filter_sidebar.html"
    list_display = [
        'name',
        'organization',
        'get_long_name',
        'get_level',
        'kind',
        'long_name',
        'stix_name',
    ]

    list_filter = [
        'status',
        'kind',
        'organization',
    ]

    def get_long_name(self, obj):
        return obj.organization.long_name
    get_long_name.short_description = 'Org Name'
    get_long_name.admin_order_field = 'organization__long_name'

    def get_level(self, obj):
        return obj.organization.get_kind_display()
    get_level.short_description = 'Org Level'
    get_level.admin_order_field = 'organization__level'

@admin.register(Catalog)
class CatalogAdmin(admin.ModelAdmin):
    list_display = [
        'song_name',
        'tune',
        'bhs_id',
        'bhs_songname',
        'bhs_arranger',
    ]

@admin.register(Chapter)
class ChapterAdmin(admin.ModelAdmin):
    search_fields = (
        'name',
        'code',
    )

    list_display = (
        'name',
        'organization',
        'code',
        # 'status',
        # 'status_monitor',
        # 'location',
        # 'website',
        # 'facebook',
        # 'twitter',
        # 'email',
        # 'phone',
        # 'picture',
    )

    list_filter = (
        'organization',
        'status',
    )

    fields = (
        'name',
        # ('status', 'status_monitor',),
        'organization',
        'location',
        'website',
        'facebook',
        'twitter',
        'email',
        'phone',
        'picture',
        'description',
        'code',
        'notes',
    )

    inlines = [
        GroupInline,
    ]

    readonly_fields = (
        # 'status_monitor',
    )
    save_on_top = True

@admin.register(Contestant)
class ContestantAdmin(admin.ModelAdmin):
    change_list_template = "admin/change_list_filter_sidebar.html"
    search_fields = [
        'name',
    ]
    fields = [
        'name',
        ('status', 'status_monitor',),
        'performer',
        'place',
        'total_score',
    ]
    list_filter = (
        'status',
    )

    autocomplete_lookup_fields = {
        'fk': [
            'performer',
        ]
    }
    readonly_fields = [
        'name',
        'status_monitor',
        'place',
        'total_score',
    ]

    raw_id_fields = [
        'performer',
    ]

@admin.register(Convention)
class ConventionAdmin(FSMTransitionMixin, admin.ModelAdmin):

    def human_range(self, obj):
        if obj.date:
            if obj.date.upper - obj.date.lower == datetime.timedelta(1):
                dates = "{0}".format(
                    arrow.get(obj.date.lower).format('MMMM D, YYYY'),
                )
            else:
                dates = "{0} - {1}".format(
                    arrow.get(obj.date.lower).format('MMMM D'),
                    arrow.get(obj.date.upper).format('MMMM D, YYYY'),
                )
        else:
            dates = obj.date
        return dates
    human_range.short_description = "Dates22"

    fsm_field = [
        'status',
    ]

    change_list_template = "admin/change_list_filter_sidebar.html"
    search_fields = (
        'name',
    )

    list_display = (
        'name',
        'status',
        'organization',
        'kind',
        'division',
        # 'date',
        'human_range',
        # 'location',
    )

    fields = (
        'name',
        ('status', 'status_monitor',),
        # 'stix_name',
        # 'stix_div',
        ('location', 'timezone',),
        # 'dates',
        'date',
        'organization',
        'drcj',
        'kind',
        # 'stix_file',
        'division',
    )

    list_filter = (
        'status',
        'kind',
        'year',
        'organization__level',
        'division',
        'organization',
    )

    inlines = [
        SessionInline,
        # OrganizationInline,
    ]

    readonly_fields = (
        'name',
        'status_monitor',
        'year',
    )

    raw_id_fields = [
        'drcj',
    ]

    save_on_top = True

@admin.register(Group)
class GroupAdmin(admin.ModelAdmin):
    search_fields = (
        'name',
        'chapter__name',
    )

    list_display = (
        'name',
        'chapter',
        'status',
        'status_monitor',
        'location',
        'website',
        'facebook',
        'twitter',
        'email',
        'phone',
        'picture',
    )

    fields = (
        'name',
        ('status', 'status_monitor',),
        'kind',
        'organization',
        'chapter',
        'location',
        'website',
        'facebook',
        'twitter',
        'email',
        'phone',
        'picture',
        'description',
        'notes',
    )

    list_filter = (
        'kind',
    )

    inlines = [
        PerformerInline,
    ]

    readonly_fields = (
        'status_monitor',
    )

    raw_id_fields = [
        'chapter',
    ]

    autocomplete_lookup_fields = {
        'fk': [
            'chapter',
        ]
    }

    save_on_top = True

@admin.register(Judge)
class JudgeAdmin(admin.ModelAdmin):
    change_list_template = "admin/change_list_filter_sidebar.html"
    save_on_top = True
    fields = [
        'name',
        ('status', 'status_monitor',),
        'session',
        'person',
        'organization',
        ('category', 'slot',),
    ]

    list_display = [
        'name',
        'status',
        'person',
        'organization',
    ]

    list_filter = (
        'status',
    )

    list_select_related = [
        'organization',
        'session',
        'person',
    ]

    raw_id_fields = (
        'session',
        'person',
    )

    autocomplete_lookup_fields = {
        'fk': [
            'session',
            'person',
        ]
    }

    readonly_fields = [
        'name',
    ]

    inlines = [
        ScoreInline,
    ]

@admin.register(Organization)
class OrganizationAdmin(MPTTModelAdmin):
    fields = [
        'name',
        ('status', 'status_monitor',),
        'parent',
        'kind',
        'code',
        'short_name',
        'long_name',
        'location',
        'website',
        'facebook',
        'twitter',
        'email',
        'phone',
        'picture',
        'description',
        'notes',
    ]

    list_filter = [
        'status',
        'level',
        'kind',
    ]

    readonly_fields = [
        'status_monitor',
    ]

    list_display = [
        'name',
        'short_name',
        'long_name',
        'status',
        'kind',
    ]

    inlines = [
        AwardInline,
    ]

    # ordering = [
    #     'tree_id',
    # ]

@admin.register(Performance)
class PerformanceAdmin(FSMTransitionMixin, SuperModelAdmin):
    fsm_field = [
        'status',
    ]

    save_on_top = True
    change_list_template = "admin/change_list_filter_sidebar.html"

    inlines = [
        SongStackedInline,
        # RoundInline,
    ]
    list_display = [
        'name',
        'status',
        'draw',
        'total_score',
    ]
    list_filter = [
        'status',
        'round',
    ]

    fields = [
        'name',
        ('status', 'status_monitor',),
        'performer',
        ('draw', 'scheduled'),
        ('mus_points', 'prs_points', 'sng_points', 'total_points',),
        ('mus_score', 'prs_score', 'sng_score', 'total_score',),
    ]

    readonly_fields = [
        'name',
        'status_monitor',
        'mus_points',
        'prs_points',
        'sng_points',
        'total_points',
        'mus_score',
        'prs_score',
        'sng_score',
        'total_score',
        'draw',
    ]

    raw_id_fields = (
        'performer',
    )
    autocomplete_lookup_fields = {
        'fk': [
            'performer',
        ]
    }

    search_fields = (
        'name',
    )

@admin.register(Performer)
class PerformerAdmin(FSMTransitionMixin, admin.ModelAdmin):
    fsm_field = [
        'status',
    ]

    change_list_template = "admin/change_list_filter_sidebar.html"

    inlines = [
        SingerInline,
        DirectorInline,
        PerformanceInline,
        ContestantInline,
    ]

    list_display = (
        'name',
        'status',
        'seed',
        'prelim',
        # 'mus_score',
        # 'prs_score',
        # 'sng_score',
        # 'total_score',
        'men',
    )

    search_fields = (
        'name',
    )

    list_filter = (
        'status',
    )

    raw_id_fields = (
        'session',
        'group',
    )

    autocomplete_lookup_fields = {
        'fk': [
            'session',
            'group',
        ]
    }
    fields = (
        'name',
        ('status', 'status_monitor',),
        'session',
        ('group', 'organization',),
        ('seed', 'prelim',),
        ('men',),
        # ('mus_points', 'prs_points', 'sng_points', 'total_points',),
        # ('mus_score', 'prs_score', 'sng_score', 'total_score',),
    )

    readonly_fields = (
        'organization',
        'name',
        'status_monitor',
        'mus_points',
        'prs_points',
        'sng_points',
        'total_points',
        'mus_score',
        'prs_score',
        'sng_score',
        'total_score',
    )

    save_on_top = True

@admin.register(Person)
class PersonAdmin(admin.ModelAdmin):
    search_fields = (
        'name',
    )

    save_on_top = True
    list_display = (
        'name',
        'status',
        'status_monitor',
        'member',
        'location',
        'website',
        'facebook',
        'twitter',
        'email',
        'phone',
        'picture',
        'bhs_member_id',
        'bhs_name',
        'bhs_city',
        'bhs_state',
        'bhs_phone',
        'bhs_email',
    )

    fields = (
        'name',
        ('status', 'status_monitor',),
        'organization',
        'location',
        'website',
        'facebook',
        'twitter',
        'email',
        'phone',
        'member',
        'picture',
        'description',
        'bhs_city',
        'notes',
    )

    list_filter = [
        'status',
    ]

    readonly_fields = (
        'status_monitor',
    )
    inlines = [
        DirectorInline,
        SingerInline,
        ArrangerInline,
        CertificationInline,
    ]

@admin.register(Round)
class RoundAdmin(FSMTransitionMixin, admin.ModelAdmin):
    fsm_field = [
        'status',
    ]

    save_on_top = True
    change_list_template = "admin/change_list_filter_sidebar.html"
    list_display = [
        'name',
        'status',
        'slots',
    ]
    fields = [
        'name',
        ('status', 'status_monitor',),
        ('session', 'kind',),
        ('slots',),
    ]

    readonly_fields = [
        'name',
        'status_monitor',
        'session',
        'kind',
    ]

    list_filter = (
        'status',
    )

    raw_id_fields = (
        'session',
    )

    autocomplete_lookup_fields = {
        'fk': [
            'session',
        ]
    }

    inlines = [
        PerformanceInline,
    ]

    search_fields = [
        'name',
    ]

@admin.register(Score)
class ScoreAdmin(admin.ModelAdmin):
    change_list_template = "admin/change_list_filter_sidebar.html"
    save_on_top = True
    fields = [
        'name',
        # ('status', 'status_monitor',),
        'song',
        'judge',
        'points',
    ]

    readonly_fields = [
        'name',
        # 'status_monitor',
        'song',
        'judge',
    ]

    list_display = [
        'name',
        # 'status',
        'points',
    ]

    # list_filter = [
    #     'status',
    # ]

    raw_id_fields = [
        'song',
        'judge',
    ]

    autocomplete_lookup_fields = {
        'fk': [
            'song',
            'judge',
        ]
    }

    ordering = [
        'song',
        'judge',
    ]

@admin.register(Session)
class SessionAdmin(FSMTransitionMixin, SuperModelAdmin):
    fsm_field = [
        'status',
    ]

    change_list_template = "admin/change_list_filter_sidebar.html"
    save_on_top = True
    fields = [
        'name',
        ('status', 'status_monitor',),
        ('history', 'history_monitor',),
        'convention',
        'kind',
        'administrator',
        # 'organization',
        # 'year',
        # # 'size',
        # 'num_rounds',
    ]

    list_display = [
        'name',
        'status',
        'convention',
        'kind',
        'administrator',
        # 'size',
        # 'num_rounds',
    ]

    list_filter = (
        'status',
        'history',
        'kind',
        'convention__year',
        'organization',
        'administrator',
    )

    raw_id_fields = (
        'convention',
    )

    autocomplete_lookup_fields = {
        'fk': [
            'convention',
        ]
    }

    readonly_fields = [
        'name',
        'status_monitor',
        'history_monitor',
        'organization',
    ]

    inlines = [
        RoundInline,
        PerformerInline,
        JudgeInline,
    ]

@admin.register(Song)
class SongAdmin(admin.ModelAdmin):
    change_list_template = "admin/change_list_filter_sidebar.html"
    save_on_top = True
    list_display = (
        'name',
        # 'status',
        'title',
        # 'tune',
        'mus_points',
        'prs_points',
        'sng_points',
        'total_points'
    )

    search_fields = (
        'name',
        'title',
    )

    fields = [
        'name',
        # ('status', 'status_monitor',),
        'order',
        ('mus_points', 'prs_points', 'sng_points', 'total_points',),
        ('mus_score', 'prs_score', 'sng_score', 'total_score',),
        'title',
        # 'tune',
        # 'catalog',
    ]

    inlines = [
        # ArrangersInline,
        ScoreInline,
    ]

    # list_filter = (
    #     'status',
    # )

    readonly_fields = (
        'name',
        'order',
        'mus_points',
        'prs_points',
        'sng_points',
        'total_points',
        'mus_score',
        'prs_score',
        'sng_score',
        'total_score',
        # 'status_monitor',
    )
    raw_id_fields = (
        'performance',
        # 'tune',
        # 'catalog',
    )
    autocomplete_lookup_fields = {
        'fk': [
            'performance',
            # 'tune',
        ]
    }

    ordering = (
        'name',
        'order',
    )

@admin.register(Tune)
class TuneAdmin(admin.ModelAdmin):
    save_on_top = True
    fields = (
        'name',
    )

    search_fields = (
        'name',
    )

@admin.register(User)
class UserAdmin(admin.ModelAdmin):
    model = User
    save_on_top = True
<|endoftext|>


<commit_before>from django.contrib import admin
from main.models import Persons, Users, Groups, GroupLists, Images, Views

class SubjectDashboardAdmin(admin.ModelAdmin):
    pass

class PersonsAdmin(admin.ModelAdmin):
    pass

class UsersAdmin(admin.ModelAdmin):
    pass

class GroupsAdmin(admin.ModelAdmin):
    pass

class GroupListsAdmin(admin.ModelAdmin):
    def formfield_for_foreignkey(self, db_field, request, **kwargs):
        if db_field.name == 'group_name':
            kwargs['queryset'] = Groups.objects.exclude(group_name='public')

    list_display = ("group_name", "friend_id")

class ImagesAdmin(admin.ModelAdmin):
    pass

# Register your models here.
admin.site.register(Users)
admin.site.register(Groups)
admin.site.register(GroupLists)
admin.site.register(Views)
<commit_msg>remove reference to SubjectDashboard<commit_after>from django.contrib import admin
from main.models import Persons, Users, Groups, GroupLists, Images, Views

class PersonsAdmin(admin.ModelAdmin):
    pass

class UsersAdmin(admin.ModelAdmin):
    pass

class GroupsAdmin(admin.ModelAdmin):
    pass

class GroupListsAdmin(admin.ModelAdmin):
    def formfield_for_foreignkey(self, db_field, request, **kwargs):
        if db_field.name == 'group_name':
            kwargs['queryset'] = Groups.objects.exclude(group_name='public')

    list_display = ("group_name", "friend_id")

class ImagesAdmin(admin.ModelAdmin):
    pass

# Register your models here.
admin.site.register(Users)
admin.site.register(Groups)
admin.site.register(GroupLists)
admin.site.register(Views)
<|endoftext|>


<commit_before>from __future__ import print_function
import os, sys, command_class
import argcomplete, argparse

def cli_interface(projectkey_class):
    """CLI interpreter for the ProjectKey class itself."""
    cc = command_class.CommandClass(projectkey_class)
    parser = argparse.ArgumentParser(add_help=False, prefix_chars=[None,])
    parser.add_argument("commands", nargs='*', default=None).completer = cc.command_completer
    argcomplete.autocomplete(parser)
    commands = parser.parse_args().commands
    returnval = 0

    if len(commands) == 0 or len(commands) == 1 and commands[0] in ['-h', '--help', 'help']:
        print("Usage: k command [args]\n")
        if cc.doc() is not None:
            print("%s\n" % cc.doc())
        print(cc.commands_help())
        print("Run 'd help [command]' to get more help on a particular command.")
    elif len(commands) > 1 and commands[0] in ['-h', '--help', 'help']:
        command = commands[1]
        if command in cc.command_list():
            print("Usage: d %s %s" % (command, cc.arg_help(command)))
            print()
            print(cc.commands[command]['helptext'])
        else:
            print("Command '%s' not found in %s. Type 'd help' to see a full list of commands." % (command, cc.projectkey_file))
    else:
        returnval = cc.run_command(commands[0], commands[1:])

    sys.exit(returnval)
<commit_msg>Changed stray reference from d to k<commit_after>from __future__ import print_function
import os, sys, command_class
import argcomplete, argparse

def cli_interface(projectkey_class):
    """CLI interpreter for the ProjectKey class itself."""
    cc = command_class.CommandClass(projectkey_class)
    parser = argparse.ArgumentParser(add_help=False, prefix_chars=[None,])
    parser.add_argument("commands", nargs='*', default=None).completer = cc.command_completer
    argcomplete.autocomplete(parser)
    commands = parser.parse_args().commands
    returnval = 0

    if len(commands) == 0 or len(commands) == 1 and commands[0] in ['-h', '--help', 'help']:
        print("Usage: k command [args]\n")
        if cc.doc() is not None:
            print("%s\n" % cc.doc())
        print(cc.commands_help())
        print("Run 'd help [command]' to get more help on a particular command.")
    elif len(commands) > 1 and commands[0] in ['-h', '--help', 'help']:
        command = commands[1]
        if command in cc.command_list():
            print("Usage: k %s %s" % (command, cc.arg_help(command)))
            print()
            print(cc.commands[command]['helptext'])
        else:
            print("Command '%s' not found in %s. Type 'd help' to see a full list of commands." % (command, cc.projectkey_file))
    else:
        returnval = cc.run_command(commands[0], commands[1:])

    sys.exit(returnval)
<|endoftext|>


<commit_before>
import platform
import os
import sys
import shutil
import subprocess
import shlex

try:
    from SCons.Script import *
except ImportError:
    pass

def run_test(target, source, env):
# Runs a single unit test and checks that the return code is 0
    try:
        subprocess.check_call(source[0].abspath)
    except subprocess.CalledProcessError, e:
        return 1

def build_pch(target, source, env):
    try:
        args = (
            str(env['CXX']),
            str(env['CXXFLAGS']),
            '-x'
            'c++-header',
            str(source[0]),
            '-o',
            str(target[0]),
        )
        print(' '.join(args))
        subprocess.check_call(shlex.split(' '.join(args)))
    except subprocess.CalledProcessError, e:
        return 1

class Package:
    """
    Defines a workspace for a package.  Automatically sets up all the usual SCons
    stuff, including a precompiled header file.
    """
    defines = {}
    includes = []
    libs = []
    frameworks = []
    path = []
    lib_path = []
    major_version = '0'
    minor_version = '0'
    patch = '0'
    kind = 'lib'
    frameworks = []

    def __init__(self):

        (system, _, release, version, machine, proc) = platform.uname()
        self.name = self.__class__.__name__.lower()
        self.pch = '%s/Common.hpp' % self.name
        self.build_mode = ARGUMENTS.get('mode', 'debug')
        self.version = '.'.join((self.major_version, self.minor_version, self.patch))
        self.branch = os.popen('git rev-parse --abbrev-ref HEAD').read().strip()
        self.revision = os.popen('git rev-parse HEAD').read().strip()
        self.defines.update({
            'VERSION': self.version,
            'REVISION': self.revision,
            'BRANCH': self.branch,
        })
        self.includes.extend([
            'include',
            'src',
            'C:\\WinBrew\\include',
        ])
        self.lib_path.extend([
            'C:\\WinBrew\\lib',
        ])
        self.path.extend([
            os.environ['PATH'],
            'C:\\WinBrew\\lib',
            'C:\\WinBrew\\bin',
        ])

        self.env = Environment(CPPPATH=['build/src'])
        self.env.Append(ENV=os.environ)
        self.env.VariantDir('build/src', 'src', duplicate=0)
        self.env.VariantDir('build/test', 'test', duplicate=0)

        self.env.Append(CPPDEFINES=self.defines)
        self.env.Append(CPPPATH=self.includes)
        self.env.Append(LIBPATH=self.lib_path)
        self.env.Append(LIBS=self.libs)

        src = []

        if self.env['PLATFORM'] == 'win32':
            self.env.Append(CXXFLAGS='/MT /EHsc /Zi /Gm /FS')
            self.env.Append(CXXFLAGS='/Fpbuild/Common.pch')
            self.env.Append(CXXFLAGS='/Yu%s' % self.pch)
            self.env.Append(LINKFLAGS='/DEBUG')
            src += self.env.Glob('build/src/**.asm')

            pchenv = self.env.Clone()
            pchenv.Append(CXXFLAGS='/Yc%s' % self.pch)
            pch = pchenv.StaticObject('build/src/Common', 'build/src/Common.cpp')
        else:
            self.env['CXX'] = 'clang++'
            self.env.Append(CXXFLAGS='-std=c++11 -stdlib=libc++ -g -Wall -Werror -fPIC')
            for framework in self.frameworks:
                self.env.Append(LINKFLAGS='-framework %s' % framework)
            self.env.Append(LINKFLAGS='-stdlib=libc++')
            self.env.Append(BUILDERS={'Pch': Builder(action=build_pch)})
            src += self.env.Glob('build/src/**.s')

            pchenv = self.env.Clone()
            pch = pchenv.Pch('include/%s/Common.hpp.pch' % self.name, 'include/%s' % self.pch)
            self.env.Append(CXXFLAGS='-include include/%s/Common.hpp' % self.name)

        src += self.env.Glob('build/src/**.cpp')
        src += self.env.Glob('build/src/**.c')
        src = filter(lambda x: 'Common.cpp' not in x.name, src)
        self.env.Depends(src, pch) # Wait for pch to build

        self.lib = self.env.SharedLibrary('lib/%s' % self.name, src)
        if self.kind == 'bin':
            main = self.env.Glob('Main.cpp')
            self.program = self.env.Program('bin/%s' % self.name, (self.lib, main))

        self.env.Append(BUILDERS={'Test': Builder(action=run_test)})
        self.tests = []
        testenv = self.env.Clone()
        testenv.Append(LIBS=self.lib)
        for test in self.env.Glob('build/test/**.cpp'):
            self.env.Depends(test, pch)
            name = test.name.replace('.cpp', '')
            prog = testenv.Program('bin/test/%s' % name, test)
            if 'check' in COMMAND_LINE_TARGETS:
                self.tests.append(testenv.Test(name, prog))
        if 'check' in COMMAND_LINE_TARGETS:
            self.env.Alias('check', self.tests)

        self.build()

    def build(self):
        pass

<commit_msg>Cleaned up package.py<commit_after>
import platform
import os
import sys
import shutil
import subprocess
import shlex

try:
    from SCons.Script import *
except ImportError:
    pass

def run_test(target, source, env):
# Runs a single unit test and checks that the return code is 0
    try:
        subprocess.check_call(source[0].abspath)
    except subprocess.CalledProcessError, e:
        return 1

def build_pch(target, source, env):
    try:
        args = (
            str(env['CXX']),
            str(env['CXXFLAGS']),
            '-x'
            'c++-header',
            str(source[0]),
            '-o',
            str(target[0]),
        )
        print(' '.join(args))
        subprocess.check_call(shlex.split(' '.join(args)))
    except subprocess.CalledProcessError, e:
        return 1

class Lib:
    """
    Defines a library that the build depends upon.
    """
    def __init__(self, name, platforms):
        self.name = name
        self.platforms = platforms

    def __str__(self):
        return self.name

    def __repr__(self):
        return self.name

class Package:
    """
    Defines a workspace for a package.  Automatically sets up all the usual SCons
    stuff, including a precompiled header file.
    """
    defines = {}
    includes = []
    libs = []
    frameworks = []
    path = []
    lib_path = []
    major_version = '0'
    minor_version = '0'
    patch = '0'
    kind = 'lib'
    frameworks = []

    def __init__(self):
        # Initializes a package, and sets up an SCons build environment given
        # the instructions found in the subclass definition.
        self._setup_vars()
        self._setup_env()
        if self.env['PLATFORM'] == 'win32':
            self._setup_win()
        else:
            self._setup_unix()
        self._setup_tests()
        self.build() # Run custom code for building the package

    def _lib_is_valid_for_platform(self, lib):
        if type(lib) == str:
            return True
        elif type(lib.platforms) == list:
            return self.env['PLATFORM'] in lib.platforms
        elif type(lib.platforms) == str:
            return self.env['PLATFORM'] == lib.platforms

    def _setup_vars(self):
        # Set up the basic configuration options
        (system, _, release, version, machine, proc) = platform.uname()
        self.name = self.__class__.__name__.lower()
        self.pch = '%s/Common.hpp' % self.name
        self.build_mode = ARGUMENTS.get('mode', 'debug')
        self.version = '.'.join((self.major_version, self.minor_version, self.patch))
        self.branch = os.popen('git rev-parse --abbrev-ref HEAD').read().strip()
        self.revision = os.popen('git rev-parse HEAD').read().strip()
        self.defines.update({
            'VERSION': self.version,
            'REVISION': self.revision,
            'BRANCH': self.branch,
        })
        self.includes.extend([
            'include',
            'src',
        ])
        self.src = []

    def _setup_env(self):
        # Create the SCons build environment, and fill it with default parameters.
        self.env = Environment(CPPPATH=['build/src'])
        self.env.Append(ENV=os.environ)
        self.env.VariantDir('build/src', 'src', duplicate=0)
        self.env.VariantDir('build/test', 'test', duplicate=0)

    def _setup_win(self):
        # Set up Windows-specific options
        self.env.Append(CXXFLAGS='/MT /EHsc /Zi /Gm /FS')
        self.env.Append(CXXFLAGS='/Fpbuild/Common.pch')
        self.env.Append(CXXFLAGS='/Yu%s' % self.pch)
        self.env.Append(LINKFLAGS='/DEBUG')
        self.src += self.env.Glob('build/src/**.asm')
        # Add MASM assembly files

        self.includes.extend([
            'C:\\WinBrew\\include',
        ])
        self.lib_path.extend([
            'C:\\WinBrew\\lib',
        ])
        self.path.extend([
            os.environ['PATH'],
            'C:\\WinBrew\\lib',
            'C:\\WinBrew\\bin',
        ])
        # Extra Windows includes

        self._setup_build()

        pchenv = self.env.Clone()
        pchenv.Append(CXXFLAGS='/Yc%s' % self.pch)
        self.pch = pchenv.StaticObject('build/src/Common', 'build/src/Common.cpp')

    def _setup_unix(self):
        # Set up OS X/Linux-specific options
        self.env['CXX'] = 'clang++'
        self.env.Append(CXXFLAGS='-std=c++11 -stdlib=libc++ -g -Wall -Werror -fPIC')
        for framework in self.frameworks:
            self.env.Append(LINKFLAGS='-framework %s' % framework)
        self.env.Append(LINKFLAGS='-stdlib=libc++')
        self.env.Append(BUILDERS={'Pch': Builder(action=build_pch)})
        self.src += self.env.Glob('build/src/**.s')
        # Add gas assembly files

        self._setup_build()

        pchenv = self.env.Clone()
        self.pch = pchenv.Pch('include/%s/Common.hpp.pch' % self.name, 'include/%s' % self.pch)
        self.env.Append(CXXFLAGS='-include include/%s/Common.hpp' % self.name)

    def _setup_build(self):
        # Set up the basic build options
        self.libs = filter(self._lib_is_valid_for_platform, self.libs)
        self.libs = map(str, self.libs)

        self.env.Append(CPPDEFINES=self.defines)
        self.env.Append(CPPPATH=self.includes)
        self.env.Append(LIBPATH=self.lib_path)
        self.env.Append(LIBS=self.libs)

        self.src += self.env.Glob('build/src/**.cpp')
        self.src += self.env.Glob('build/src/**.c')
        self.src = filter(lambda x: 'Common.cpp' not in x.name, self.src)
        self.env.Depends(self.src, self.pch) # Wait for pch to build

        if self.env['PLATFORM'] == 'win32':
            self.lib = self.env.StaticLibrary('lib/%s' % self.name, self.src)
        else:
            self.lib = self.env.SharedLibrary('lib/%s' % self.name, self.src)
        if self.kind == 'bin':
            main = self.env.Glob('Main.cpp')
            self.program = self.env.Program('bin/%s' % self.name, (self.lib, main))

    def _setup_tests(self):
        # Configure the test environment
        self.env.Append(BUILDERS={'Test': Builder(action=run_test)})
        self.tests = []
        testenv = self.env.Clone()
        testenv.Append(LIBS=self.lib)
        for test in self.env.Glob('build/test/**.cpp'):
            self.env.Depends(test, self.pch)
            name = test.name.replace('.cpp', '')
            if self.env['PLATFORM'] == 'win32':
                prog = testenv.Program('bin/test/%s' % name, (test, self.pch))
            else:
                prog = testenv.Program('bin/test/%s' % name, test)
            if 'check' in COMMAND_LINE_TARGETS:
                self.tests.append(testenv.Test(name, prog))
        if 'check' in COMMAND_LINE_TARGETS:
            self.env.Alias('check', self.tests)

    def build(self):
        pass

<|endoftext|>


<commit_before>import hashlib
import os
import re
import shlex
import stat
import sys
import subprocess
import tempfile
import uuid
from base64 import b64encode
from itertools import dropwhile

from .eval import ArgError, action, eval, get_actions
from .utils import hashstr

IMAGE_HINT_TEMPL = '### image hint: {}'

@action(escape=False)
def layer(command=None, *args):
    'start a new layer'
    if not command:
        return eval([['original-layer']])  # fall back to buildin layer action
    else:
        lst = [['layer']]
        for arg in args:
            lst.append([command, arg])
            lst.append(['layer'])
        return eval(lst)

@action(escape=False, keep_comments=True)
def run(*cmds):
    'run shell script'
    return '\n'.join(cmds)

@action()
def align_cwd():
    'cd tho the pwd at the host'
    yield 'cd {}'.format(shlex.quote(os.getcwd()))

@action()
def import_envs(*envs):
    'import environment variables from host'
    for env in envs:
        parts = env.split(':', 1)
        if len(parts) == 1:
            export_as = env
        else:
            env, export_as = parts
        yield '{}={}'.format(export_as, shlex.quote(os.environ[env]))

@action()
def bust_cache():
    'Invalidate cache'
    return ': bust cache with {}'.format(uuid.uuid4())

@action(keep_comments=True)
def write_script(fname, *lines):
    'write an executable file'
    yield 'touch {}'.format(fname)
    for line in lines:
        yield "echo {} >> {}".format(line, fname)
    yield 'chmod 755 {}'.format(fname)

@action(escape=False)
def include(*files):
    'include parameters from file'
    for file in files:
        fname = os.path.realpath(os.path.expanduser(file))
        with open(fname) as f:
            lsp = []
            tokens = dropwhile(
	        lambda l: l.startswith('#'),
	        (i[:-1] for i in f.readlines()))
            for line0, token in enumerate(tokens):
                if line0 == 0 and token.startswith('#!'):
                    continue
                if token.startswith('--'):
                    lsp.append([token[2:]])
                elif token:
                    lsp[-1].append(token)
        yield eval(lsp)

def hash_paths(paths):
    collect_files = []
    for path in paths:
        if os.path.isdir(path):
            collect_files.extend(all_files(path))
        else:
            collect_files.append(path)

    hasher = hashlib.sha1()
    for fname in sorted(collect_files):
        perm = str(oct(stat.S_IMODE(os.lstat(fname).st_mode))).encode()
        with open(fname, 'rb') as f:
            fread = f.read()  # well, no buffering?
        hasher.update(fname.encode())
        hasher.update(perm)

        hasher.update(hashstr(fread).encode())

    hash = hasher.hexdigest()
    return hash

def all_files(dir):
    for (dirpath, dirnames, filenames) in os.walk(dir):
        for filename in filenames:
            fname = os.sep.join([dirpath, filename])
            yield fname

@action(escape=False)
def watch(*paths):
    'only rebuild if anything in a path has changed'
    hash = hash_paths(paths)
    return ": watch hash: {}".format(hash)

@action(escape=False)
def defpm(name, *lines):
    'define a new package manager'
    @action(name, group='package managers')
    def package_manager(*packages):
        if not packages:
            return
        sh_packages = ' '.join(pkg for pkg in packages)
        expanded_lines = [line.format(sh_packages) for line in lines]
        return eval([['run'] + expanded_lines])
    package_manager.__doc__ = "install packages with {}".format(name)

@action()
def pkg(*packages):
    'call the default package manager'
    raise ArgError('you need to "--set-pkg <package-manager>" to use pkg')

@action(escape=False)
def set_pkg(pm):
    'set the default package manager'
    @action('pkg')
    def pkg(*packages):
        return eval([[pm] + list(packages)])

@action(escape=False)
def all(command, *args):
    'use first argument as action, map it to other arguments'
    return eval([[command, arg] for arg in args])

@action()
def comment(*args):
    'do nothing'
    pass

@action('image', escape=False)
def image(os):
    'set the base image'
    return IMAGE_HINT_TEMPL.format(os)

@action(escape=False)
def chdir(path):
    'change directory at host'
    os.chdir(path)

@action()
def namespace(ns):
    'start a new build namespace'
    return eval([
         ['layer'],
         ['run', ': new namespace {}'.format(ns)],
         ['layer']])

@action()
def devinit():
    'ensure a minimal /dev setup'
    # using this: from http://www.tldp.org/LDP/lfs/LFS-BOOK-6.1.1-HTML/chapter06/devices.html
    return '''
    test -e /dev/console || mknod -m 622 /dev/console c 5 1
    test -e /dev/null || mknod -m 666 /dev/null c 1 3
    test -e /dev/zero || mknod -m 666 /dev/zero c 1 5
    test -e /dev/ptmx || mknod -m 666 /dev/ptmx c 5 2
    test -e /dev/tty || mknod -m 666 /dev/tty c 5 0
    test -e /dev/random || mknod -m 444 /dev/random c 1 8
    test -e /dev/urandom || mknod -m 444 /dev/urandom c 1 9
    chown -v root:tty /dev/console
    chown -v root:tty /dev/ptmx
    chown -v root:tty /dev/tty'''

@action()
def list():
    'list all actions'
    actions = get_actions()
    prev_group = None
    for name, func in sorted(actions.items(),
            key=lambda i: (i[1]._plash_group or '', i[0])):
        group = func._plash_group or 'main'
        if group != prev_group:
            prev_group is None or print()
            print('    ## {} ##'.format(group), file=sys.stderr)
        print('{: <16} {}'.format(name, func.__doc__), file=sys.stderr)
        prev_group = group
    sys.exit(1)

ALIASES = dict(
    x=[['run']],
    l=[['layer']],
    I=[['include']],
    i=[['image']],
    alpine=[['image', 'alpine'], ['apk']],
    A=[['alpine']],
    ubuntu=[['image', 'ubuntu'], ['apt']],
    U=[['ubuntu']],
    fedora=[['image', 'fedora'], ['dnf']],
    F=[['fedora']],
    debian=[['image', 'debian'], ['apt']],
    D=[['debian']],
    centos=[['image', 'centos'], ['yum']],
    C=[['centos']],
    arch=[['image', 'arch'], ['pacman']],
    R=[['arch']],
    gentoo=[['image', 'gentoo'], ['emerge']],
    G=[['gentoo']],
)

for name, macro in ALIASES.items():
    def bounder(macro=macro):
        def func(*args):
            # list(args) throws exception some really funny reason
            # therefore the list comprehension
            args = [i for i in args]
            return eval(macro[:-1] + [macro[-1] + args])
        func.__doc__ = 'macro for: {}[ARG1 [ARG2 [...]]]'.format(' '.join('--'+i[0]+' '+' '.join(i[1:]) for i in macro))
        return func
    func = bounder()
    action(name=name, group='macros', escape=False)(func)

eval([[
    'defpm',
    'apt',
    'apt-get update',
    'apt-get install -y {}',
], [
    'defpm',
    'add-apt-repository',
    'apt-get install software-properties-common',
    'run add-apt-repository -y {}',
], [
    'defpm',
    'apk',
    'apk update',
    'apk add {}',
], [
    'defpm',
    'yum',
    'yum install -y {}',
], [
    'defpm',
    'dnf',
    'dnf install -y {}',
], [
    'defpm',
    'pip',
    'pip install {}',
], [
    'defpm',
    'npm',
    'npm install -g {}',
], [
    'defpm',
    'pacman',
    'pacman -Sy --noconfirm {}',
], [
    'defpm',
    'emerge',
    'emerge {}',
]])
<commit_msg>indentation fix<commit_after>import hashlib
import os
import re
import shlex
import stat
import sys
import subprocess
import tempfile
import uuid
from base64 import b64encode
from itertools import dropwhile

from .eval import ArgError, action, eval, get_actions
from .utils import hashstr

IMAGE_HINT_TEMPL = '### image hint: {}'

@action(escape=False)
def layer(command=None, *args):
    'start a new layer'
    if not command:
        return eval([['original-layer']])  # fall back to buildin layer action
    else:
        lst = [['layer']]
        for arg in args:
            lst.append([command, arg])
            lst.append(['layer'])
        return eval(lst)

@action(escape=False, keep_comments=True)
def run(*cmds):
    'run shell script'
    return '\n'.join(cmds)

@action()
def align_cwd():
    'cd tho the pwd at the host'
    yield 'cd {}'.format(shlex.quote(os.getcwd()))

@action()
def import_envs(*envs):
    'import environment variables from host'
    for env in envs:
        parts = env.split(':', 1)
        if len(parts) == 1:
            export_as = env
        else:
            env, export_as = parts
        yield '{}={}'.format(export_as, shlex.quote(os.environ[env]))

@action()
def bust_cache():
    'Invalidate cache'
    return ': bust cache with {}'.format(uuid.uuid4())

@action(keep_comments=True)
def write_script(fname, *lines):
    'write an executable file'
    yield 'touch {}'.format(fname)
    for line in lines:
        yield "echo {} >> {}".format(line, fname)
    yield 'chmod 755 {}'.format(fname)

@action(escape=False)
def include(*files):
    'include parameters from file'
    for file in files:
        fname = os.path.realpath(os.path.expanduser(file))
        with open(fname) as f:
            lsp = []
            tokens = dropwhile(
	        lambda l: l.startswith('#'),
	        (i[:-1] for i in f.readlines()))
            for line0, token in enumerate(tokens):
                if line0 == 0 and token.startswith('#!'):
                    continue
                if token.startswith('--'):
                    lsp.append([token[2:]])
                elif token:
                    lsp[-1].append(token)
        yield eval(lsp)

def hash_paths(paths):
    collect_files = []
    for path in paths:
        if os.path.isdir(path):
            collect_files.extend(all_files(path))
        else:
            collect_files.append(path)

    hasher = hashlib.sha1()
    for fname in sorted(collect_files):
        perm = str(oct(stat.S_IMODE(os.lstat(fname).st_mode))).encode()
        with open(fname, 'rb') as f:
            fread = f.read()  # well, no buffering?
        hasher.update(fname.encode())
        hasher.update(perm)

        hasher.update(hashstr(fread).encode())

    hash = hasher.hexdigest()
    return hash

def all_files(dir):
    for (dirpath, dirnames, filenames) in os.walk(dir):
        for filename in filenames:
            fname = os.sep.join([dirpath, filename])
            yield fname

@action(escape=False)
def watch(*paths):
    'only rebuild if anything in a path has changed'
    hash = hash_paths(paths)
    return ": watch hash: {}".format(hash)

@action(escape=False)
def defpm(name, *lines):
    'define a new package manager'
    @action(name, group='package managers')
    def package_manager(*packages):
        if not packages:
            return
        sh_packages = ' '.join(pkg for pkg in packages)
        expanded_lines = [line.format(sh_packages) for line in lines]
        return eval([['run'] + expanded_lines])
    package_manager.__doc__ = "install packages with {}".format(name)

@action()
def pkg(*packages):
    'call the default package manager'
    raise ArgError('you need to "--set-pkg <package-manager>" to use pkg')

@action(escape=False)
def set_pkg(pm):
    'set the default package manager'
    @action('pkg')
    def pkg(*packages):
        return eval([[pm] + list(packages)])

@action(escape=False)
def all(command, *args):
    'use first argument as action, map it to other arguments'
    return eval([[command, arg] for arg in args])

@action()
def comment(*args):
    'do nothing'
    pass

@action('image', escape=False)
def image(os):
    'set the base image'
    return IMAGE_HINT_TEMPL.format(os)

@action(escape=False)
def chdir(path):
    'change directory at host'
    os.chdir(path)

@action()
def namespace(ns):
    'start a new build namespace'
    return eval([
         ['layer'],
         ['run', ': new namespace {}'.format(ns)],
         ['layer']])

@action()
def devinit():
    'ensure a minimal /dev setup'
    # using this: from http://www.tldp.org/LDP/lfs/LFS-BOOK-6.1.1-HTML/chapter06/devices.html
    return '''
    test -e /dev/console || mknod -m 622 /dev/console c 5 1
    test -e /dev/null || mknod -m 666 /dev/null c 1 3
    test -e /dev/zero || mknod -m 666 /dev/zero c 1 5
    test -e /dev/ptmx || mknod -m 666 /dev/ptmx c 5 2
    test -e /dev/tty || mknod -m 666 /dev/tty c 5 0
    test -e /dev/random || mknod -m 444 /dev/random c 1 8
    test -e /dev/urandom || mknod -m 444 /dev/urandom c 1 9
    chown -v root:tty /dev/console
    chown -v root:tty /dev/ptmx
    chown -v root:tty /dev/tty'''

@action()
def list():
    'list all actions'
    actions = get_actions()
    prev_group = None
    for name, func in sorted(actions.items(),
            key=lambda i: (i[1]._plash_group or '', i[0])):
        group = func._plash_group or 'main'
        if group != prev_group:
            prev_group is None or print()
            print('    ## {} ##'.format(group), file=sys.stderr)
        print('{: <16} {}'.format(name, func.__doc__), file=sys.stderr)
        prev_group = group
    sys.exit(1)

ALIASES = dict(
    x=[['run']],
    l=[['layer']],
    I=[['include']],
    i=[['image']],
    alpine=[['image', 'alpine'], ['apk']],
    A=[['alpine']],
    ubuntu=[['image', 'ubuntu'], ['apt']],
    U=[['ubuntu']],
    fedora=[['image', 'fedora'], ['dnf']],
    F=[['fedora']],
    debian=[['image', 'debian'], ['apt']],
    D=[['debian']],
    centos=[['image', 'centos'], ['yum']],
    C=[['centos']],
    arch=[['image', 'arch'], ['pacman']],
    R=[['arch']],
    gentoo=[['image', 'gentoo'], ['emerge']],
    G=[['gentoo']],
)

for name, macro in ALIASES.items():
    def bounder(macro=macro):
        def func(*args):
            # list(args) throws exception some really funny reason
            # therefore the list comprehension
            args = [i for i in args]
            return eval(macro[:-1] + [macro[-1] + args])
        func.__doc__ = 'macro for: {}[ARG1 [ARG2 [...]]]'.format(
                ' '.join('--'+i[0]+' '+' '.join(i[1:]) for i in macro))
        return func
    func = bounder()
    action(name=name, group='macros', escape=False)(func)

eval([[
    'defpm',
    'apt',
    'apt-get update',
    'apt-get install -y {}',
], [
    'defpm',
    'add-apt-repository',
    'apt-get install software-properties-common',
    'run add-apt-repository -y {}',
], [
    'defpm',
    'apk',
    'apk update',
    'apk add {}',
], [
    'defpm',
    'yum',
    'yum install -y {}',
], [
    'defpm',
    'dnf',
    'dnf install -y {}',
], [
    'defpm',
    'pip',
    'pip install {}',
], [
    'defpm',
    'npm',
    'npm install -g {}',
], [
    'defpm',
    'pacman',
    'pacman -Sy --noconfirm {}',
], [
    'defpm',
    'emerge',
    'emerge {}',
]])
<|endoftext|>


<commit_before>from os import environ, path, makedirs, sep
from platform import system
from shutil import move
import sqlite3
from hashlib import sha1
from sys import argv, exit
import getopt

root = path.abspath(sep)
if system() == 'Windows':
    LOCALAPPDATA = environ['LOCALAPPDATA']
elif system() == 'Linux':
    LOCALAPPDATA = environ['PLEX_HOME']
elif system() == 'Darwin':
    LOCALAPPDATA = '~/Library/Application Support'
else:
    print('Unsupported System; Exiting')
    exit()
DBDIR = path.join(LOCALAPPDATA, "Plex Media Server", "Plug-in Support", "Databases")
MDDIR = path.join(LOCALAPPDATA, "Plex Media Server", "Metadata")

def main(argv):
    """
    Search Plex database for a specific item and remove its metadata.
    Args:
        :param searchstring: Name of item to be searched, should be a close to the actual name as possible
        :type searchstring: str

    Returns:
        :return: None

    References:
        [1] https://nikansell.wordpress.com/2012/03/14/fixing-corrupt-plex-thumbnails/
        [2] http://axisdata.com/FixPlexPosters
    """

    opts, args = getopt.getopt(argv, "ht:d", ["help", "type="])

    mediatype = None

    for opt, arg in opts:
        if opt in ("-h", "--help"):
            print('''Usage: plexfix [options] Media Title
Options:
    -t, --type:
        s, series = deletes metadata for a an entire series.
        e, episode = deletes metadata for an episode
        m, movie = deletes metadata for a movie
        se, series_episodes = deletes metadata for an entire series including all episodes
    -h, --help:
        Prints this help file
    -d:
        debug NOT IMPLEMENTED''')
            exit()
        elif opt == "-d":
            raise NotImplementedError
            # global _debug
            # _debug = 1
        elif opt in ("-t", "--type"):
            mediatype = arg

    searchstring = " ".join(args)

    conn = sqlite3.connect(path.join(DBDIR, "com.plexapp.plugins.library.db"))

    if mediatype is None:
        sql_string = "SELECT title, guid FROM metadata_items WHERE title LIKE '{}'".format(searchstring)
    elif mediatype.lower() in ["s", "series"]:
        # do the series search
        sql_string = "SELECT title, guid FROM metadata_items WHERE title LIKE '{}' AND metadata_type LIKE 2".format(
            searchstring)
    elif mediatype.lower() in ["e", "episode"]:
        # do the epispode thing
        sql_string = "SELECT title, guid FROM metadata_items WHERE title LIKE '{}' AND metadata_type LIKE 4".format(
            searchstring)
    elif mediatype.lower() in ["m", "movie"]:
        # do the movie thing
        sql_string = "SELECT title, guid FROM metadata_items WHERE title LIKE '{}' AND metadata_type LIKE 1".format(
            searchstring)
    elif mediatype.lower() in ["se", "series_episodes"]:
        # do the entire series thing
        raise NotImplementedError('Still clarifying how to get thr right address of each episode in a series, if it is needed at all?')
        sql_string = "SELECT title, guid, id FROM metadata_items WHERE title LIKE '{}' AND metadata_type LIKE 2".format(
            searchstring)
    else:
        raise Exception

    def result_execute(result):
        title = result[0]
        guid = result[1]
        showsum = sha1(guid.encode('utf-8')).hexdigest()
        showchar = showsum[0]
        showdir = showsum[1:]
        print("Title: {}, GUID:{}".format(title, guid))
        moviepath = path.join(MDDIR, "Movies", showchar, showdir) + '.bundle'
        tvpath = path.join(MDDIR, "TV Shows", showchar, showdir) + '.bundle'
        plexposterbundles = path.join(root, 'tmp', 'plexposterbundles')
        if path.isdir(moviepath):
            bundlefile = moviepath
            bundledest = path.join(plexposterbundles, 'Movies')
        elif path.isdir(tvpath):
            bundlefile = tvpath
            bundledest = path.join(plexposterbundles, 'TV')
        else:
            print('No bundle file')
            return

        if path.isdir(bundlefile):
            if not path.isdir(bundledest):
                if not path.isdir(path.join('tmp', 'plexposterbundles')):
                    makedirs(path.join('tmp', 'plexposterbundles'))
                makedirs(bundledest)
            move(bundlefile, bundledest)
            print("""Bundle found and moved to "{}"
        Now go to Plex Media Manager and choose "Fix Incorrect Match"
        and then "Update Selection" for this title.""".format(bundledest))

    # sql_string = "SELECT title, guid FROM metadata_items WHERE title LIKE '{}'".format(searchstring)
    result = list(conn.execute(sql_string))
    print('Searching for: {}'.format(searchstring))
    if len(result) == 1:
        if mediatype.lower() in ["se", "series_episodes"]:
            parent_id = result[0][2]
            # Get the series ID
            sql_string = "SELECT title, guid, id FROM metadata_items WHERE parent_id LIKE '{}' AND metadata_type LIKE 3".format(
                parent_id)
            results = list(conn.execute(sql_string))
            sub_parent_ids = list(zip(*results))[-1]
            # Get the seasons ID
            sql_string = "SELECT title, guid, id FROM metadata_items WHERE parent_id IN {} AND metadata_type LIKE 4".format(
                sub_parent_ids)
            results = list(conn.execute(sql_string))
            for result in results:
                result_execute(result)
        else:
            result_execute(result[0])

    elif len(result) > 1:
        print('Multiple Entries Found')
        for i in result:
            print(i[0])
            print('Try a more specific search')

    else:
        print('No entries found -- please try a different search string.')

if __name__ == '__main__':
    main(['-t', 'se', 'Fawlty Towers'])
    # # for arg in :
    main(argv[1:])
    # print(argv)
    # opts, args = getopt.getopt(argv[1:], "ht:d", ["help", "type="])
    # print(opts)
    # print(args)
<commit_msg>Figured out that only effective to delete a whole series, removed the abilty to search for episodes.<commit_after>from os import environ, path, makedirs, sep
from platform import system
from shutil import move
import sqlite3
from hashlib import sha1
from sys import argv, exit
import getopt

root = path.abspath(sep)
if system() == 'Windows':
    LOCALAPPDATA = environ['LOCALAPPDATA']
elif system() == 'Linux':
    LOCALAPPDATA = environ['PLEX_HOME']
elif system() == 'Darwin':
    LOCALAPPDATA = '~/Library/Application Support'
else:
    print('Unsupported System; Exiting')
    exit()
DBDIR = path.join(LOCALAPPDATA, "Plex Media Server", "Plug-in Support", "Databases")
MDDIR = path.join(LOCALAPPDATA, "Plex Media Server", "Metadata")

def main(argv):
    """
    Search Plex database for a specific item and remove its metadata.
    Args:
        :param searchstring: Name of item to be searched, should be a close to the actual name as possible
        :type searchstring: str

    Returns:
        :return: None

    References:
        [1] https://nikansell.wordpress.com/2012/03/14/fixing-corrupt-plex-thumbnails/
        [2] http://axisdata.com/FixPlexPosters
    """

    opts, args = getopt.getopt(argv, "ht:d", ["help", "type="])

    mediatype = None

    for opt, arg in opts:
        if opt in ("-h", "--help"):
            print('''Usage: plexfix [options] Media Title
Options:
    -t, --type:
        s, series = deletes metadata for a an entire series.
        m, movie = deletes metadata for a movie
    -h, --help:
        Prints this help file
    -d:
        debug NOT IMPLEMENTED''')
            exit()
        elif opt == "-d":
            raise NotImplementedError
            # global _debug
            # _debug = 1
        elif opt in ("-t", "--type"):
            mediatype = arg

    searchstring = " ".join(args)

    conn = sqlite3.connect(path.join(DBDIR, "com.plexapp.plugins.library.db"))

    if mediatype is None:
        sql_string = "SELECT title, guid FROM metadata_items WHERE title LIKE '{}'".format(searchstring)
    elif mediatype.lower() in ["s", "series"]:
        # do the series search
        sql_string = "SELECT title, guid FROM metadata_items WHERE title LIKE '{}' AND metadata_type LIKE 2".format(
            searchstring)
    elif mediatype.lower() in ["m", "movie"]:
        # do the movie thing
        sql_string = "SELECT title, guid FROM metadata_items WHERE title LIKE '{}' AND metadata_type LIKE 1".format(
            searchstring)
    else:
        raise Exception

    def result_execute(result):
        title = result[0]
        guid = result[1]
        showsum = sha1(guid.encode('utf-8')).hexdigest()
        showchar = showsum[0]
        showdir = showsum[1:]
        print("Title: {}, GUID:{}".format(title, guid))
        moviepath = path.join(MDDIR, "Movies", showchar, showdir) + '.bundle'
        tvpath = path.join(MDDIR, "TV Shows", showchar, showdir) + '.bundle'
        plexposterbundles = path.join(root, 'tmp', 'plexposterbundles')
        if path.isdir(moviepath):
            bundlefile = moviepath
            bundledest = path.join(plexposterbundles, 'Movies')
        elif path.isdir(tvpath):
            bundlefile = tvpath
            bundledest = path.join(plexposterbundles, 'TV')
        else:
            print('No bundle file')
            return

        if path.isdir(bundlefile):
            if not path.isdir(bundledest):
                if not path.isdir(path.join('tmp', 'plexposterbundles')):
                    makedirs(path.join('tmp', 'plexposterbundles'))
                makedirs(bundledest)
            move(bundlefile, bundledest)
            print("""Bundle found and moved to "{}"
        Now go to Plex Media Manager and choose "Fix Incorrect Match"
        and then "Update Selection" for this title.""".format(bundledest))

    # sql_string = "SELECT title, guid FROM metadata_items WHERE title LIKE '{}'".format(searchstring)
    result = list(conn.execute(sql_string))
    print('Searching for: {}'.format(searchstring))
    if len(result) == 1:
        result_execute(result[0])

    elif len(result) > 1:
        print('Multiple Entries Found')
        for i in result:
            print(i[0])
            print('Try a more specific search')

    else:
        print('No entries found -- please try a different search string.')

if __name__ == '__main__':
    main(argv[1:])
<|endoftext|>


<commit_before>'''
	Server Density
	www.serverdensity.com
	----
	A web based server resource monitoring application

	Licensed under Simplified BSD License (see LICENSE)
	(C) Boxed Ice 2009 all rights reserved
'''

# Core modules
import httplib # Used only for handling httplib.HTTPException (case #26701)
import logging
import logging.handlers
import md5
import platform
import re
import subprocess
import sys
import urllib
import urllib2

# We need to return the data using JSON. As of Python 2.6+, there is a core JSON
# module. We have a 2.4/2.5 compatible lib included with the agent but if we're
# on 2.6 or above, we should use the core module which will be faster
pythonVersion = platform.python_version_tuple()

if int(pythonVersion[1]) >= 6: # Don't bother checking major version since we only support v2 anyway
	import json
else:
	import minjson

class checks:

	def __init__(self, agentConfig):
		self.agentConfig = agentConfig

	def getApacheStatus(self):
		self.checksLogger.debug('Getting apacheStatus')

		if self.agentConfig['apacheStatusUrl'] != 'http://www.example.com/server-status/?auto':	# Don't do it if the status URL hasn't been provided
			self.checksLogger.debug('Apache config value set')

			try:
				request = urllib2.urlopen(self.agentConfig['apacheStatusUrl'])
				response = request.read()

			except urllib2.HTTPError, e:
				self.checksLogger.error('Unable to get Apache status - HTTPError = ' + str(e))
				return False

			except urllib2.URLError, e:
				self.checksLogger.error('Unable to get Apache status - URLError = ' + str(e))
				return False

			except httplib.HTTPException, e:
				self.checksLogger.error('Unable to get Apache status - HTTPException = ' + str(e))
				return False

			except Exception, e:
				import traceback
				self.checksLogger.error('Unable to get Apache status - Exception = ' + traceback.format_exc())
				return False

			self.checksLogger.debug('Got server response')

			# Split out each line
			lines = response.split('\n')

			# Loop over each line and get the values
			apacheStatus = {}

			self.checksLogger.debug('Looping over lines')

			# Loop through and extract the numerical values
			for line in lines:
				values = line.split(': ')

				try:
					apacheStatus[str(values[0])] = values[1]

				except IndexError:
					break

			self.checksLogger.debug('Done looping')

			try:
				if apacheStatus['ReqPerSec'] != False and apacheStatus['BusyWorkers'] != False and apacheStatus['IdleWorkers'] != False:
					self.checksLogger.debug('Returning statuses')

					return {'reqPerSec': apacheStatus['ReqPerSec'], 'busyWorkers': apacheStatus['BusyWorkers'], 'idleWorkers': apacheStatus['IdleWorkers']}

				else:
					self.checksLogger.debug('One of the statuses was empty')

					return False

			except IndexError: # Stops the agent crashing if one of the apacheStatus elements isn't set (e.g. ExtendedStatus Off)
				self.checksLogger.debug('Apache status failed - ReqPerSec, BusyWorkers or IdleWorkers not present')

			except KeyError: # Stops the agent crashing if one of the apacheStatus elements isn't set (e.g. ExtendedStatus Off)
				self.checksLogger.debug('Apache status failed - ReqPerSec, BusyWorkers or IdleWorkers not present')

				return False

		else:
			self.checksLogger.debug('Apache config not set')

			return False

	def getDf(self):
		# CURRENTLY UNUSED

		# Get output from df
		try:
			df = subprocess.Popen(['df'], stdout=subprocess.PIPE).communicate()[0]

		except Exception, e:
			import traceback
			self.checksLogger.error('getDf - Exception = ' + traceback.format_exc())
			return False

		# Split out each volume
		volumes = df.split('\n')

		# Remove first (headings) and last (blank)
		volumes.pop()
		volumes.pop(0)

		# Loop through each volue and split out parts
		for volume in volumes:
			parts = re.findall(r'[a-zA-Z0-9_/]+', volume)

	def getLoadAvrgs(self):
		self.checksLogger.debug('Getting loadAvrgs')

		# Get output from uptime
		try:
			uptime = subprocess.Popen(['uptime'], stdout=subprocess.PIPE).communicate()[0]

		except Exception, e:
			import traceback
			self.checksLogger.error('getLoadAvrgs - Exception = ' + traceback.format_exc())
			return False

		# Split out the 3 load average values (we actually only use the 5 min average)
		loadAvrgs = re.findall(r'([0-9]+\.\d+)', uptime)

		self.checksLogger.debug('Got loadAvrgs - ' + uptime)

		return loadAvrgs # We only use loadAvrgs[0] but may use more in the future, so return all

	def getMemoryUsage(self):
		self.checksLogger.debug('Getting memoryUsage')

		# See http://stackoverflow.com/questions/446209/possible-values-from-sys-platform/446210#446210 for possible
		# sys.platform values
		if sys.platform == 'linux2':
			self.checksLogger.debug('memoryUsage - linux2 - /proc/meminfo')

			try:
				meminfoProc = open('/proc/meminfo', 'r')
				lines = meminfoProc.readlines()

			except IOError, e:
				self.checksLogger.error('getMemoryUsage (linux2) - Exception = ' + str(e))
				return False

			meminfoProc.close()

			self.checksLogger.debug('Looping over lines')

			regexp = re.compile(r'([0-9]+)') # We run this several times so one-time compile now

			meminfo = {}

			# Loop through and extract the numerical values
			for line in lines:
				values = line.split(':')

				try:
					# Picks out the key (values[0]) and makes a list with the value as the meminfo value (values[1])
					# We are only interested in the KB data so regexp that out
					meminfo[str(values[0])] = re.search(regexp, values[1]).group(0)

				except IndexError:
					break

			self.checksLogger.debug('Done looping')

			memData = {}

			# Phys
			try:
				self.checksLogger.debug('phys')

				physTotal = int(meminfo['MemTotal'])
				physFree = int(meminfo['MemFree'])
				physUsed = physTotal - physFree

				# Convert to MB
				memData['physFree'] = physFree / 1024
				memData['physUsed'] = physUsed / 1024

				self.checksLogger.debug('Phys Used: ' + str(memData['physFree']) + ' / Free: ' + str(memData['physUsed']))

			except IndexError: # Stops the agent crashing if one of the meminfo elements isn't set
				self.checksLogger.debug('/proc/meminfo failed (IndexError) - MemTotal or MemFree not present')

			except KeyError: # Stops the agent crashing if one of the meminfo elements isn't set
				self.checksLogger.debug('/proc/meminfo failed (KeyError) - MemTotal or MemFree not present')

			# Swap
			try:
				self.checksLogger.debug('swap')

				swapTotal = int(meminfo['SwapTotal'])
				swapFree = int(meminfo['SwapFree'])
				swapUsed = swapTotal - swapFree

				# Convert to MB
				memData['swapFree'] = swapFree / 1024
				memData['swapUsed'] = swapUsed / 1024

				self.checksLogger.debug('Swap Used: ' + str(memData['swapFree']) + ' / Free: ' + str(memData['swapUsed']))

			except IndexError: # Stops the agent crashing if one of the meminfo elements isn't set
				self.checksLogger.debug('/proc/meminfo failed (IndexError) - SwapTotal or SwapFree not present')

			except KeyError: # Stops the agent crashing if one of the meminfo elements isn't set
				self.checksLogger.debug('/proc/meminfo failed (KeyError) - SwapTotal or SwapFree not present')

			return memData

		elif sys.platform == 'darwin':
			self.checksLogger.debug('memoryUsage - darwin - top/sysctl')

			try:
				top = subprocess.Popen(['top', '-l 1'], stdout=subprocess.PIPE).communicate()[0]
				sysctl = subprocess.Popen(['sysctl', 'vm.swapusage'], stdout=subprocess.PIPE).communicate()[0]

			except Exception, e:
				import traceback
				self.checksLogger.error('getMemoryUsage (darwin) - Exception = ' + traceback.format_exc())
				return False

			# Deal with top
			lines = top.split('\n')
			physParts = re.findall(r'([0-9]\d+)', lines[5])

			# Deal with sysctl
			swapParts = re.findall(r'([0-9]+\.\d+)', sysctl)

			self.checksLogger.debug('Got memoryUsage - Phys ' + physParts[3] + ' / ' + physParts[4] + ' Swap ' + swapParts[1] + ' / ' + swapParts[2])

			return {'physUsed' : physParts[3], 'physFree' : physParts[4], 'swapUsed' : swapParts[1], 'swapFree' : swapParts[2]}

		else:
			return False

	def getProcesses(self):
		self.checksLogger.debug('Getting processes')

		# Get output from ps
		try:
			ps = subprocess.Popen(['ps', 'aux'], stdout=subprocess.PIPE).communicate()[0]

		except Exception, e:
			import traceback
			self.checksLogger.error('getProcessCount - Exception = ' + traceback.format_exc())
			return False

		self.checksLogger.debug('Got processes, now to split')

		# Split out each process
		processLines = ps.split('\n')

		del processLines[0] # Removes the headers
		processLines.pop() # Removes a trailing empty line

		processes = []

		# http://stackoverflow.com/questions/682446/splitting-out-the-output-of-ps-using-python/682464#682464
		for line in processLines:
			line = line.split(None, 10)
			processes.append(line)

		return processes

	def doPostBack(self, postBackData):
		self.checksLogger.debug('Doing postback to ' + self.agentConfig['sdUrl'])

		try:
			# Build the request handler
			request = urllib2.Request(self.agentConfig['sdUrl'] + '/postback/', postBackData, { 'User-Agent' : 'Server Density Agent' })

			# Do the request, log any errors
			response = urllib2.urlopen(request)

			if self.agentConfig['debugMode']:
				print response.read()

		except urllib2.HTTPError, e:
			self.checksLogger.error('Unable to postback - HTTPError = ' + str(e))
			return False

		except urllib2.URLError, e:
			self.checksLogger.error('Unable to postback - URLError = ' + str(e))
			return False

		except httplib.HTTPException, e: # Added for case #26701
			self.checksLogger.error('Unable to postback - HTTPException')
			return False

		except Exception, e:
			import traceback
			self.checksLogger.error('Unable to postback - Exception = ' + traceback.format_exc())
			return False

		self.checksLogger.debug('Posted back')

	def doChecks(self, sc):
		self.checksLogger = logging.getLogger('checks')

		self.checksLogger.debug('doChecks')

		# Do the checks
		loadAvrgs = self.getLoadAvrgs()
		processes = self.getProcesses()
		memory = self.getMemoryUsage()
		apacheStatus = self.getApacheStatus()

		self.checksLogger.debug('All checks done, now to post back')

		checksData = {'agentKey' : self.agentConfig['agentKey'], 'agentVersion' : self.agentConfig['version'], 'loadAvrg' : loadAvrgs[0], 'processes' : processes, 'memPhysUsed' : memory['physUsed'], 'memPhysFree' : memory['physFree'], 'memSwapUsed' : memory['swapUsed'], 'memSwapFree' : memory['swapFree']}

		# Apache Status
		if apacheStatus != False:
			checksData['apacheReqPerSec'] = apacheStatus['reqPerSec']
			checksData['apacheBusyWorkers'] = apacheStatus['busyWorkers']
			checksData['apacheIdleWorkers'] = apacheStatus['idleWorkers']

		# Post back the data
		if int(pythonVersion[1]) >= 6:
			payload = json.dumps(checksData)

		else:
			payload = minjson.write(checksData)

		payloadHash = md5.new(payload).hexdigest()
		postBackData = urllib.urlencode({'payload' : payload, 'hash' : payloadHash})

		self.doPostBack(postBackData)

		self.checksLogger.debug('Rescheduling checks')
		sc.enter(self.agentConfig['checkFreq'], 1, self.doChecks, (sc,))	<commit_msg>Fixed mixed up debug output for new memory parser<commit_after>'''
	Server Density
	www.serverdensity.com
	----
	A web based server resource monitoring application

	Licensed under Simplified BSD License (see LICENSE)
	(C) Boxed Ice 2009 all rights reserved
'''

# SO references
# http://stackoverflow.com/questions/446209/possible-values-from-sys-platform/446210#446210
# http://stackoverflow.com/questions/682446/splitting-out-the-output-of-ps-using-python/682464#682464

# Core modules
import httplib # Used only for handling httplib.HTTPException (case #26701)
import logging
import logging.handlers
import md5
import platform
import re
import subprocess
import sys
import urllib
import urllib2

# We need to return the data using JSON. As of Python 2.6+, there is a core JSON
# module. We have a 2.4/2.5 compatible lib included with the agent but if we're
# on 2.6 or above, we should use the core module which will be faster
pythonVersion = platform.python_version_tuple()

if int(pythonVersion[1]) >= 6: # Don't bother checking major version since we only support v2 anyway
	import json
else:
	import minjson

class checks:

	def __init__(self, agentConfig):
		self.agentConfig = agentConfig

	def getApacheStatus(self):
		self.checksLogger.debug('Getting apacheStatus')

		if self.agentConfig['apacheStatusUrl'] != 'http://www.example.com/server-status/?auto':	# Don't do it if the status URL hasn't been provided
			self.checksLogger.debug('Apache config value set')

			try:
				request = urllib2.urlopen(self.agentConfig['apacheStatusUrl'])
				response = request.read()

			except urllib2.HTTPError, e:
				self.checksLogger.error('Unable to get Apache status - HTTPError = ' + str(e))
				return False

			except urllib2.URLError, e:
				self.checksLogger.error('Unable to get Apache status - URLError = ' + str(e))
				return False

			except httplib.HTTPException, e:
				self.checksLogger.error('Unable to get Apache status - HTTPException = ' + str(e))
				return False

			except Exception, e:
				import traceback
				self.checksLogger.error('Unable to get Apache status - Exception = ' + traceback.format_exc())
				return False

			self.checksLogger.debug('Got server response')

			# Split out each line
			lines = response.split('\n')

			# Loop over each line and get the values
			apacheStatus = {}

			self.checksLogger.debug('Looping over lines')

			# Loop through and extract the numerical values
			for line in lines:
				values = line.split(': ')

				try:
					apacheStatus[str(values[0])] = values[1]

				except IndexError:
					break

			self.checksLogger.debug('Done looping')

			try:
				if apacheStatus['ReqPerSec'] != False and apacheStatus['BusyWorkers'] != False and apacheStatus['IdleWorkers'] != False:
					self.checksLogger.debug('Returning statuses')

					return {'reqPerSec': apacheStatus['ReqPerSec'], 'busyWorkers': apacheStatus['BusyWorkers'], 'idleWorkers': apacheStatus['IdleWorkers']}

				else:
					self.checksLogger.debug('One of the statuses was empty')

					return False

			# Stops the agent crashing if one of the apacheStatus elements isn't set (e.g. ExtendedStatus Off)
			except IndexError:
				self.checksLogger.debug('Apache status failed - ReqPerSec, BusyWorkers or IdleWorkers not present')

			except KeyError:
				self.checksLogger.debug('Apache status failed - ReqPerSec, BusyWorkers or IdleWorkers not present')

				return False

		else:
			self.checksLogger.debug('Apache config not set')

			return False

	def getDf(self):
		# CURRENTLY UNUSED

		# Get output from df
		try:
			df = subprocess.Popen(['df'], stdout=subprocess.PIPE).communicate()[0]

		except Exception, e:
			import traceback
			self.checksLogger.error('getDf - Exception = ' + traceback.format_exc())
			return False

		# Split out each volume
		volumes = df.split('\n')

		# Remove first (headings) and last (blank)
		volumes.pop()
		volumes.pop(0)

		# Loop through each volue and split out parts
		for volume in volumes:
			parts = re.findall(r'[a-zA-Z0-9_/]+', volume)

	def getLoadAvrgs(self):
		self.checksLogger.debug('Getting loadAvrgs')

		# Get output from uptime
		try:
			uptime = subprocess.Popen(['uptime'], stdout=subprocess.PIPE).communicate()[0]

		except Exception, e:
			import traceback
			self.checksLogger.error('getLoadAvrgs - Exception = ' + traceback.format_exc())
			return False

		# Split out the 3 load average values (we actually only use the 5 min average)
		loadAvrgs = re.findall(r'([0-9]+\.\d+)', uptime)

		self.checksLogger.debug('Got loadAvrgs - ' + uptime)

		return loadAvrgs # We only use loadAvrgs[0] but may use more in the future, so return all

	def getMemoryUsage(self):
		self.checksLogger.debug('Getting memoryUsage')

		if sys.platform == 'linux2':
			self.checksLogger.debug('memoryUsage - linux2 - /proc/meminfo')

			try:
				meminfoProc = open('/proc/meminfo', 'r')
				lines = meminfoProc.readlines()

			except IOError, e:
				self.checksLogger.error('getMemoryUsage (linux2) - Exception = ' + str(e))
				return False

			meminfoProc.close()

			self.checksLogger.debug('Looping over lines')

			regexp = re.compile(r'([0-9]+)') # We run this several times so one-time compile now

			meminfo = {}

			# Loop through and extract the numerical values
			for line in lines:
				values = line.split(':')

				try:
					# Picks out the key (values[0]) and makes a list with the value as the meminfo value (values[1])
					# We are only interested in the KB data so regexp that out
					meminfo[str(values[0])] = re.search(regexp, values[1]).group(0)

				except IndexError:
					break

			self.checksLogger.debug('Done looping')

			memData = {}

			# Phys
			try:
				self.checksLogger.debug('phys')

				physTotal = int(meminfo['MemTotal'])
				physFree = int(meminfo['MemFree'])
				physUsed = physTotal - physFree

				# Convert to MB
				memData['physFree'] = physFree / 1024
				memData['physUsed'] = physUsed / 1024

				self.checksLogger.debug('Phys Used: ' + str(memData['physUsed']) + ' / Free: ' + str(memData['physFree']))

			# Stops the agent crashing if one of the meminfo elements isn't set
			except IndexError:
				self.checksLogger.debug('/proc/meminfo failed (IndexError) - MemTotal or MemFree not present')

			except KeyError:
				self.checksLogger.debug('/proc/meminfo failed (KeyError) - MemTotal or MemFree not present')

			# Swap
			try:
				self.checksLogger.debug('swap')

				swapTotal = int(meminfo['SwapTotal'])
				swapFree = int(meminfo['SwapFree'])
				swapUsed = swapTotal - swapFree

				# Convert to MB
				memData['swapFree'] = swapFree / 1024
				memData['swapUsed'] = swapUsed / 1024

				self.checksLogger.debug('Swap Used: ' + str(memData['swapUsed']) + ' / Free: ' + str(memData['swapFree']))

			# Stops the agent crashing if one of the meminfo elements isn't set
			except IndexError:
				self.checksLogger.debug('/proc/meminfo failed (IndexError) - SwapTotal or SwapFree not present')

			except KeyError:
				self.checksLogger.debug('/proc/meminfo failed (KeyError) - SwapTotal or SwapFree not present')

			return memData

		elif sys.platform == 'darwin':
			self.checksLogger.debug('memoryUsage - darwin - top/sysctl')

			try:
				top = subprocess.Popen(['top', '-l 1'], stdout=subprocess.PIPE).communicate()[0]
				sysctl = subprocess.Popen(['sysctl', 'vm.swapusage'], stdout=subprocess.PIPE).communicate()[0]

			except Exception, e:
				import traceback
				self.checksLogger.error('getMemoryUsage (darwin) - Exception = ' + traceback.format_exc())
				return False

			# Deal with top
			lines = top.split('\n')
			physParts = re.findall(r'([0-9]\d+)', lines[5])

			# Deal with sysctl
			swapParts = re.findall(r'([0-9]+\.\d+)', sysctl)

			self.checksLogger.debug('Got memoryUsage - Phys ' + physParts[3] + ' / ' + physParts[4] + ' Swap ' + swapParts[1] + ' / ' + swapParts[2])

			return {'physUsed' : physParts[3], 'physFree' : physParts[4], 'swapUsed' : swapParts[1], 'swapFree' : swapParts[2]}

		else:
			return False

	def getProcesses(self):
		self.checksLogger.debug('Getting processes')

		# Get output from ps
		try:
			ps = subprocess.Popen(['ps', 'aux'], stdout=subprocess.PIPE).communicate()[0]

		except Exception, e:
			import traceback
			self.checksLogger.error('getProcessCount - Exception = ' + traceback.format_exc())
			return False

		self.checksLogger.debug('Got processes, now to split')

		# Split out each process
		processLines = ps.split('\n')

		del processLines[0] # Removes the headers
		processLines.pop() # Removes a trailing empty line

		processes = []

		for line in processLines:
			line = line.split(None, 10)
			processes.append(line)

		return processes

	def doPostBack(self, postBackData):
		self.checksLogger.debug('Doing postback to ' + self.agentConfig['sdUrl'])

		try:
			# Build the request handler
			request = urllib2.Request(self.agentConfig['sdUrl'] + '/postback/', postBackData, { 'User-Agent' : 'Server Density Agent' })

			# Do the request, log any errors
			response = urllib2.urlopen(request)

			if self.agentConfig['debugMode']:
				print response.read()

		except urllib2.HTTPError, e:
			self.checksLogger.error('Unable to postback - HTTPError = ' + str(e))
			return False

		except urllib2.URLError, e:
			self.checksLogger.error('Unable to postback - URLError = ' + str(e))
			return False

		except httplib.HTTPException, e: # Added for case #26701
			self.checksLogger.error('Unable to postback - HTTPException')
			return False

		except Exception, e:
			import traceback
			self.checksLogger.error('Unable to postback - Exception = ' + traceback.format_exc())
			return False

		self.checksLogger.debug('Posted back')

	def doChecks(self, sc):
		self.checksLogger = logging.getLogger('checks')

		self.checksLogger.debug('doChecks')

		# Do the checks
		loadAvrgs = self.getLoadAvrgs()
		processes = self.getProcesses()
		memory = self.getMemoryUsage()
		apacheStatus = self.getApacheStatus()

		self.checksLogger.debug('All checks done, now to post back')

		checksData = {'agentKey' : self.agentConfig['agentKey'], 'agentVersion' : self.agentConfig['version'], 'loadAvrg' : loadAvrgs[0], 'processes' : processes, 'memPhysUsed' : memory['physUsed'], 'memPhysFree' : memory['physFree'], 'memSwapUsed' : memory['swapUsed'], 'memSwapFree' : memory['swapFree']}

		# Apache Status
		if apacheStatus != False:
			checksData['apacheReqPerSec'] = apacheStatus['reqPerSec']
			checksData['apacheBusyWorkers'] = apacheStatus['busyWorkers']
			checksData['apacheIdleWorkers'] = apacheStatus['idleWorkers']

		# Post back the data
		if int(pythonVersion[1]) >= 6:
			payload = json.dumps(checksData)

		else:
			payload = minjson.write(checksData)

		payloadHash = md5.new(payload).hexdigest()
		postBackData = urllib.urlencode({'payload' : payload, 'hash' : payloadHash})

		self.doPostBack(postBackData)

		self.checksLogger.debug('Rescheduling checks')
		sc.enter(self.agentConfig['checkFreq'], 1, self.doChecks, (sc,))	<|endoftext|>


<commit_before>"""
Platform independent module
for controlling the mouse and keyboard
"""
import sys

class Mouse:

    LEFT_BUTTON = 0
    MIDDLE_BUTTON = 1
    RIGHT_BUTTON = 2

    def move(self, x, y):
        """Move mouse pointer to specified location"""
        raise NotImplementedError

    def press(self, button):
        """Trigger mouse press of the specified button"""
        raise NotImplementedError

    def release(self, button):
        """Trigger mouse release of the specified button"""
        raise NotImplementedError

class X11Mouse(Mouse):

    def __init__(self):
        self.display = display.Display()
        self.screen = self.display.screen()

    def move(self, x, y):
        self.screen.root.warp_pointer(x, y)
        self.display.sync()

    def press(self, button):
        # TODO: implement
        return

    def release(self, button):
        # TODO: implement
         return

class Win32Mouse(Mouse):

    def move(self, x, y):
        # TODO: implement
        return

    def press(self, button):
        # TODO: implement
        return

    def release(self, button):
        # TODO: implement
        return

if sys.platform == 'linux2':
    from Xlib import display
    mouse = X11Mouse()
elif sys.platform == 'win32':
    import win32api
    mouse = Win32Mouse()
else:
    raise ImportError("Unsupported platform")

<commit_msg>X11Mouse in cheese module fully implemented.<commit_after>"""
Platform independent module
for controlling the mouse and keyboard
"""
import sys

class Mouse:

    LEFT_BUTTON = 1
    MIDDLE_BUTTON = 2
    RIGHT_BUTTON = 3

    def move(self, x, y):
        """Move mouse pointer to specified location"""
        raise NotImplementedError

    def press(self, button):
        """Trigger mouse press of the specified button"""
        raise NotImplementedError

    def release(self, button):
        """Trigger mouse release of the specified button"""
        raise NotImplementedError

class X11Mouse(Mouse):

    def __init__(self):
        self.display = Xlib.display.Display()
        self.screen = self.display.screen()

    def move(self, x, y):
        self.screen.root.warp_pointer(x, y)
        self.display.sync()

    def press(self, button):
        Xlib.ext.xtest.fake_input(self.display, Xlib.X.ButtonPress, button)
        self.display.sync()

    def release(self, button):
        Xlib.ext.xtest.fake_input(self.display, Xlib.X.ButtonRelease, button)
        self.display.sync()

class Win32Mouse(Mouse):

    def move(self, x, y):
        # TODO: implement
        return

    def press(self, button):
        # TODO: implement
        return

    def release(self, button):
        # TODO: implement
        return

if sys.platform == 'linux2':
    import Xlib.display
    import Xlib.X
    import Xlib.ext.xtest
    mouse = X11Mouse()
elif sys.platform == 'win32':
    import win32api
    mouse = Win32Mouse()
else:
    raise ImportError("Unsupported platform")

<|endoftext|>