<commit_before>from typing import ClassVar, Dict, List, Optional, Tuple, Union
from typing import cast as typecast

import datetime
import json
import logging
import re
import os

import semantic_version

from scout import Scout

# Import version stuff directly from ambassador.VERSION to avoid a circular import.
from .VERSION import Version, Build, BuildInfo

ScoutNotice = Dict[str, str]

class LocalScout:
    def __init__(self, logger, app: str, version: str, install_id: str) -> None:
        self.logger = logger
        self.app = app
        self.version = version
        self.install_id = install_id

        self.events = []

        self.logger.info(f'LocalScout: initialized for {app} {version}: ID {install_id}')

    def report(self, **kwargs) -> dict:
        self.events.append(kwargs)

        mode = kwargs['mode']
        action = kwargs['action']

        now = datetime.datetime.now().timestamp()

        kwargs['local_scout_timestamp'] = now

        if 'timestamp' not in kwargs:
            kwargs['timestamp'] = now

        self.logger.info(f"LocalScout: mode {mode}, action {action} ({kwargs})")

        return {
            "latest_version": self.version,
            "application": self.app,
            "cached": False,
            "notices": [ { "level": "WARNING", "message": "Using LocalScout, result is faked!" } ],
            "timestamp": now
        }

    def reset_events(self) -> None:
        self.events = []

class AmbScout:
    reTaggedBranch: ClassVar = re.compile(r'^(\d+\.\d+\.\d+)(-[a-zA-Z][a-zA-Z]\d+)?$')
    reGitDescription: ClassVar = re.compile(r'-(\d+)-g([0-9a-f]+)$')

    install_id: str
    runtime: str
    namespace: str

    version: str
    semver: Optional[semantic_version.Version]

    _scout: Optional[Scout]
    _scout_error: Optional[str]

    _notices: Optional[List[ScoutNotice]]
    _last_result: Optional[dict]
    _last_update: Optional[datetime.datetime]
    _update_frequency: datetime.timedelta

    _latest_version: Optional[str] = None
    _latest_semver: Optional[semantic_version.Version] = None

    def __init__(self, install_id=None, update_frequency=datetime.timedelta(hours=12), local_only=False) -> None:
        if not install_id:
            install_id = os.environ.get('AMBASSADOR_CLUSTER_ID',
                                        os.environ.get('AMBASSADOR_SCOUT_ID', "00000000-0000-0000-0000-000000000000"))

        self.install_id = install_id
        self.runtime = "kubernetes" if os.environ.get('KUBERNETES_SERVICE_HOST', None) else "docker"
        self.namespace = os.environ.get('AMBASSADOR_NAMESPACE', 'default')

        self.version = self.parse_git_description(Version, Build)
        self.semver = self.get_semver(self.version)

        self.logger = logging.getLogger("ambassador.scout")
        # self.logger.setLevel(logging.DEBUG)

        self.logger.debug("Ambassador version %s built from %s on %s" % (Version, Build.git.commit, Build.git.branch))
        self.logger.debug("Scout version      %s%s" % (self.version, " - BAD SEMVER" if not self.semver else ""))
        self.logger.debug("Runtime            %s" % self.runtime)
        self.logger.debug("Namespace          %s" % self.namespace)

        self._scout = None
        self._scout_error = None

        self._local_only = local_only

        self._notices = None
        self._last_result = None
        self._update_frequency = update_frequency
        self._latest_version = None
        self._latest_semver = None

        self.reset_cache_time()

    def reset_cache_time(self) -> None:
        self._last_update = datetime.datetime.now() - datetime.timedelta(hours=24)

    def reset_events(self) -> None:
        if self._local_only:
            self._scout.reset_events()

    def __str__(self) -> str:
        return ("%s: %s" % ("OK" if self._scout else "??",
                            self._scout_error if self._scout_error else "OK"))

    @property
    def scout(self) -> Optional[Scout]:
        if not self._scout:
            if self._local_only:
                self._scout = LocalScout(logger=self.logger,
                                         app="ambassador", version=self.version, install_id=self.install_id)
                self.logger.debug("LocalScout initialized")
            else:
                try:
                    self._scout = Scout(app="ambassador", version=self.version, install_id=self.install_id)
                    self._scout_error = None
                    self.logger.debug("Scout connection established")
                except OSError as e:
                    self._scout = None
                    self._scout_error = str(e)
                    self.logger.debug("Scout connection failed, will retry later: %s" % self._scout_error)

        return self._scout

    def report(self, force_result: Optional[dict]=None, no_cache=False, **kwargs) -> dict:
        _notices: List[ScoutNotice] = []

        # Silly, right?
        use_cache = not no_cache

        env_result = None

        if use_cache:
            env_result = os.environ.get("AMBASSADOR_SCOUT_RESULT", None)

            if env_result:
                force_result = json.loads(env_result)

        result: Optional[dict] = force_result
        result_was_cached: bool = False

        if not result:
            if 'runtime' not in kwargs:
                kwargs['runtime'] = self.runtime

            if 'commit' not in kwargs:
                kwargs['commit'] = Build.git.commit

            if 'branch' not in kwargs:
                kwargs['branch'] = Build.git.branch

            # How long since the last Scout update? If it's been more than an hour,
            # check Scout again.

            now = datetime.datetime.now()

            needs_update = True

            if use_cache:
                if self._last_update:
                    since_last_update = now - typecast(datetime.datetime, self._last_update)
                    needs_update = (since_last_update > self._update_frequency)

            if needs_update:
                if self.scout:
                    result = self.scout.report(**kwargs)

                    self._last_update = now
                    self._last_result = dict(**typecast(dict, result)) if result else None
                else:
                    result = { "scout": "unavailable: %s" % self._scout_error }
                    _notices.append({ "level": "DEBUG",
                                      "message": "scout temporarily unavailable: %s" % self._scout_error })

                # Whether we could talk to Scout or not, update the timestamp so we don't
                # try again too soon.
                result_timestamp = datetime.datetime.now()
            else:
                _notices.append({ "level": "DEBUG", "message": "Returning cached result" })
                result = dict(**typecast(dict, self._last_result)) if self._last_result else None
                result_was_cached = True

                # We can't get here unless self._last_update is set.
                result_timestamp = typecast(datetime.datetime, self._last_update)
        else:
            _notices.append({ "level": "INFO", "message": "Returning forced Scout result" })
            result_timestamp = datetime.datetime.now()

        if not self.semver:
            _notices.append({
                "level": "WARNING",
                "message": "Ambassador has invalid version '%s'??!" % self.version
            })

        if result:
            result['cached'] = result_was_cached
        else:
            result = { 'cached': False }

        result['timestamp'] = result_timestamp.timestamp()

        # Do version & notices stuff.
        if 'latest_version' in result:
            latest_version = result['latest_version']
            latest_semver = self.get_semver(latest_version)

            if latest_semver:
                self._latest_version = latest_version
                self._latest_semver = latest_semver
            else:
                _notices.append({
                    "level": "WARNING",
                    "message": "Scout returned invalid version '%s'??!" % latest_version
                })

        if (self._latest_semver and ((not self.semver) or
                                     (self._latest_semver > self.semver))):
            _notices.append({
                "level": "INFO",
                "message": "Upgrade available! to Ambassador version %s" % self._latest_semver
            })

        if 'notices' in result:
            rnotices = typecast(List[Union[str, ScoutNotice]], result['notices'])

            for notice in rnotices:
                if isinstance(notice, str):
                    _notices.append({ "level": "WARNING", "message": notice })
                elif isinstance(notice, dict):
                    lvl = notice.get('level', 'WARNING').upper()
                    msg = notice.get('message', None)

                    if msg:
                        _notices.append({ "level": lvl, "message": msg })
                else:
                    _notices.append({ "level": "WARNING", "message": json.dumps(notice) })

        self._notices = _notices

        if self._notices:
            result['notices'] = self._notices
        else:
            result.pop('notices', None)

        return result

    @staticmethod
    def get_semver(version_string: str) -> Optional[semantic_version.Version]:
        semver = None

        try:
            semver = semantic_version.Version(version_string)
        except ValueError:
            pass

        return semver

    @staticmethod
    def parse_git_description(version: str, build: BuildInfo) -> str:
        # Here's what we get for various kinds of builds:
        #
        # Random (clean):
        # Version:               shared-dev-tgr606-f60229d
        # build.git.branch:      shared/dev/tgr606
        # build.git.commit:      f60229d
        # build.git.dirty:       False
        # build.git.description: 0.50.0-tt2-1-gf60229d
        # --> 0.50.0-local+gf60229d
        #
        # Random (dirty):
        # Version:               shared-dev-tgr606-f60229d-dirty
        # build.git.branch:      shared/dev/tgr606
        # build.git.commit:      f60229d
        # build.git.dirty:       True
        # build.git.description: 0.50.0-tt2-1-gf60229d
        # --> 0.50.0-local+gf60229d.dirty
        #
        # EA:
        # Version:               0.50.0
        # build.git.branch:      0.50.0-ea2
        # build.git.commit:      05aefd5
        # build.git.dirty:       False
        # build.git.description: 0.50.0-ea2
        # --> 0.50.0-ea2
        #
        # RC
        # Version:               0.40.0
        # build.git.branch:      0.40.0-rc1
        # build.git.commit:      d450dca
        # build.git.dirty:       False
        # build.git.description: 0.40.0-rc1
        # --> 0.40.0-rc1
        #
        # GA
        # Version:               0.40.0
        # build.git.branch:      0.40.0
        # build.git.commit:      e301a90
        # build.git.dirty:       False
        # build.git.description: 0.40.0
        # --> 0.40.0

        # Start by assuming that the version is sane and we needn't
        # tack any build metadata onto it.

        build_elements: List[str] = []

        m = AmbScout.reTaggedBranch.search(build.git.branch)

        if not m:
            # This isn't a proper sane version. It must be a local build. Per
            # Scout's rules, anything with semver build metadata is treated as a
            # dev version, so we need to make sure our returned version has some.
            #
            # Start by assuming that we won't find a useable version in the
            # description, and must fall back to 0.0.0.
            build_version = "0.0.0"
            desc_delta = None

            # OK. Can we find a version from what the git description starts
            # with? If so, the upgrade logic in the diagnostics will work more
            # sanely.

            m = AmbScout.reGitDescription.search(build.git.description)

            if m:
                # OK, the description ends with -$delta-g$commit at least, so
                # it may start with a version. Strip off the matching text and
                # remember the delta and commit.

                desc_delta = m.group(1)
                desc = build.git.description[0:m.start()]

                # Does the remaining description match a sane version?
                m = AmbScout.reTaggedBranch.search(desc)

                if m:
                    # Yes. Use it as the base version.
                    build_version = m.group(1)

            # We'll use prerelease "local", and include the branch and such
            # in the build metadata.
            version = '%s-local' % build_version

            # Does the commit not appear in a build element?
            build_elements = []

            if desc_delta:
                build_elements.append(desc_delta)

            build_elements.append("g%s" % build.git.commit)

            # If this branch is dirty, append a build element of "dirty".
            if build.git.dirty:
                build_elements.append('dirty')
        else:
            # The build branch is a sane version. Does it match our base version?
            (base_version, prerelease) = m.groups()

            if base_version != version:
                build_elements.append("q%s" % version.replace('.', '-'))

            # Overwrite the version with the branch only if it's important to show the
            # branch (e.g. 0.50.0-rc7 instead of 0.50.0) at all times. We should probably
            # not do this again -- or we should revamp this stuff to rebuild the Docker
            # image for a GA build.
            # version = build.git.branch

        # Finally, put it all together.
        if build_elements:
            version += "+%s" % ('.'.join(build_elements))

        return version
<commit_msg>Whoops. Tweak the Scout versioning checks for the leading 'v'. Thanks to the all the folks who reported this!<commit_after>from typing import ClassVar, Dict, List, Optional, Tuple, Union
from typing import cast as typecast

import datetime
import json
import logging
import re
import os

import semantic_version

from scout import Scout

# Import version stuff directly from ambassador.VERSION to avoid a circular import.
from .VERSION import Version, Build, BuildInfo

ScoutNotice = Dict[str, str]

class LocalScout:
    def __init__(self, logger, app: str, version: str, install_id: str) -> None:
        self.logger = logger
        self.app = app
        self.version = version
        self.install_id = install_id

        self.events = []

        self.logger.info(f'LocalScout: initialized for {app} {version}: ID {install_id}')

    def report(self, **kwargs) -> dict:
        self.events.append(kwargs)

        mode = kwargs['mode']
        action = kwargs['action']

        now = datetime.datetime.now().timestamp()

        kwargs['local_scout_timestamp'] = now

        if 'timestamp' not in kwargs:
            kwargs['timestamp'] = now

        self.logger.info(f"LocalScout: mode {mode}, action {action} ({kwargs})")

        return {
            "latest_version": self.version,
            "application": self.app,
            "cached": False,
            "notices": [ { "level": "WARNING", "message": "Using LocalScout, result is faked!" } ],
            "timestamp": now
        }

    def reset_events(self) -> None:
        self.events = []

class AmbScout:
    reTaggedBranch: ClassVar = re.compile(r'^v?(\d+\.\d+\.\d+)(-[a-zA-Z][a-zA-Z]\d+)?$')
    reGitDescription: ClassVar = re.compile(r'-(\d+)-g([0-9a-f]+)$')

    install_id: str
    runtime: str
    namespace: str

    version: str
    semver: Optional[semantic_version.Version]

    _scout: Optional[Scout]
    _scout_error: Optional[str]

    _notices: Optional[List[ScoutNotice]]
    _last_result: Optional[dict]
    _last_update: Optional[datetime.datetime]
    _update_frequency: datetime.timedelta

    _latest_version: Optional[str] = None
    _latest_semver: Optional[semantic_version.Version] = None

    def __init__(self, install_id=None, update_frequency=datetime.timedelta(hours=12), local_only=False) -> None:
        if not install_id:
            install_id = os.environ.get('AMBASSADOR_CLUSTER_ID',
                                        os.environ.get('AMBASSADOR_SCOUT_ID', "00000000-0000-0000-0000-000000000000"))

        self.install_id = install_id
        self.runtime = "kubernetes" if os.environ.get('KUBERNETES_SERVICE_HOST', None) else "docker"
        self.namespace = os.environ.get('AMBASSADOR_NAMESPACE', 'default')

        self.version = self.parse_git_description(Version, Build)
        self.semver = self.get_semver(self.version)

        self.logger = logging.getLogger("ambassador.scout")
        # self.logger.setLevel(logging.DEBUG)

        self.logger.debug("Ambassador version %s built from %s on %s" % (Version, Build.git.commit, Build.git.branch))
        self.logger.debug("Scout version      %s%s" % (self.version, " - BAD SEMVER" if not self.semver else ""))
        self.logger.debug("Runtime            %s" % self.runtime)
        self.logger.debug("Namespace          %s" % self.namespace)

        self._scout = None
        self._scout_error = None

        self._local_only = local_only

        self._notices = None
        self._last_result = None
        self._update_frequency = update_frequency
        self._latest_version = None
        self._latest_semver = None

        self.reset_cache_time()

    def reset_cache_time(self) -> None:
        self._last_update = datetime.datetime.now() - datetime.timedelta(hours=24)

    def reset_events(self) -> None:
        if self._local_only:
            self._scout.reset_events()

    def __str__(self) -> str:
        return ("%s: %s" % ("OK" if self._scout else "??",
                            self._scout_error if self._scout_error else "OK"))

    @property
    def scout(self) -> Optional[Scout]:
        if not self._scout:
            if self._local_only:
                self._scout = LocalScout(logger=self.logger,
                                         app="ambassador", version=self.version, install_id=self.install_id)
                self.logger.debug("LocalScout initialized")
            else:
                try:
                    self._scout = Scout(app="ambassador", version=self.version, install_id=self.install_id)
                    self._scout_error = None
                    self.logger.debug("Scout connection established")
                except OSError as e:
                    self._scout = None
                    self._scout_error = str(e)
                    self.logger.debug("Scout connection failed, will retry later: %s" % self._scout_error)

        return self._scout

    def report(self, force_result: Optional[dict]=None, no_cache=False, **kwargs) -> dict:
        _notices: List[ScoutNotice] = []

        # Silly, right?
        use_cache = not no_cache

        env_result = None

        if use_cache:
            env_result = os.environ.get("AMBASSADOR_SCOUT_RESULT", None)

            if env_result:
                force_result = json.loads(env_result)

        result: Optional[dict] = force_result
        result_was_cached: bool = False

        if not result:
            if 'runtime' not in kwargs:
                kwargs['runtime'] = self.runtime

            if 'commit' not in kwargs:
                kwargs['commit'] = Build.git.commit

            if 'branch' not in kwargs:
                kwargs['branch'] = Build.git.branch

            # How long since the last Scout update? If it's been more than an hour,
            # check Scout again.

            now = datetime.datetime.now()

            needs_update = True

            if use_cache:
                if self._last_update:
                    since_last_update = now - typecast(datetime.datetime, self._last_update)
                    needs_update = (since_last_update > self._update_frequency)

            if needs_update:
                if self.scout:
                    result = self.scout.report(**kwargs)

                    self._last_update = now
                    self._last_result = dict(**typecast(dict, result)) if result else None
                else:
                    result = { "scout": "unavailable: %s" % self._scout_error }
                    _notices.append({ "level": "DEBUG",
                                      "message": "scout temporarily unavailable: %s" % self._scout_error })

                # Whether we could talk to Scout or not, update the timestamp so we don't
                # try again too soon.
                result_timestamp = datetime.datetime.now()
            else:
                _notices.append({ "level": "DEBUG", "message": "Returning cached result" })
                result = dict(**typecast(dict, self._last_result)) if self._last_result else None
                result_was_cached = True

                # We can't get here unless self._last_update is set.
                result_timestamp = typecast(datetime.datetime, self._last_update)
        else:
            _notices.append({ "level": "INFO", "message": "Returning forced Scout result" })
            result_timestamp = datetime.datetime.now()

        if not self.semver:
            _notices.append({
                "level": "WARNING",
                "message": "Ambassador has invalid version '%s'??!" % self.version
            })

        if result:
            result['cached'] = result_was_cached
        else:
            result = { 'cached': False }

        result['timestamp'] = result_timestamp.timestamp()

        # Do version & notices stuff.
        if 'latest_version' in result:
            latest_version = result['latest_version']
            latest_semver = self.get_semver(latest_version)

            if latest_semver:
                self._latest_version = latest_version
                self._latest_semver = latest_semver
            else:
                _notices.append({
                    "level": "WARNING",
                    "message": "Scout returned invalid version '%s'??!" % latest_version
                })

        if (self._latest_semver and ((not self.semver) or
                                     (self._latest_semver > self.semver))):
            _notices.append({
                "level": "INFO",
                "message": "Upgrade available! to Ambassador version %s" % self._latest_semver
            })

        if 'notices' in result:
            rnotices = typecast(List[Union[str, ScoutNotice]], result['notices'])

            for notice in rnotices:
                if isinstance(notice, str):
                    _notices.append({ "level": "WARNING", "message": notice })
                elif isinstance(notice, dict):
                    lvl = notice.get('level', 'WARNING').upper()
                    msg = notice.get('message', None)

                    if msg:
                        _notices.append({ "level": lvl, "message": msg })
                else:
                    _notices.append({ "level": "WARNING", "message": json.dumps(notice) })

        self._notices = _notices

        if self._notices:
            result['notices'] = self._notices
        else:
            result.pop('notices', None)

        return result

    @staticmethod
    def get_semver(version_string: str) -> Optional[semantic_version.Version]:
        semver = None

        try:
            semver = semantic_version.Version(version_string)
        except ValueError:
            pass

        return semver

    @staticmethod
    def parse_git_description(version: str, build: BuildInfo) -> str:
        # Here's what we get for various kinds of builds:
        #
        # Random (clean):
        # Version:               shared-dev-tgr606-f60229d
        # build.git.branch:      shared/dev/tgr606
        # build.git.commit:      f60229d
        # build.git.dirty:       False
        # build.git.description: 0.50.0-tt2-1-gf60229d
        # --> 0.50.0-local+gf60229d
        #
        # Random (dirty):
        # Version:               shared-dev-tgr606-f60229d-dirty
        # build.git.branch:      shared/dev/tgr606
        # build.git.commit:      f60229d
        # build.git.dirty:       True
        # build.git.description: 0.50.0-tt2-1-gf60229d
        # --> 0.50.0-local+gf60229d.dirty
        #
        # EA:
        # Version:               0.50.0
        # build.git.branch:      0.50.0-ea2
        # build.git.commit:      05aefd5
        # build.git.dirty:       False
        # build.git.description: 0.50.0-ea2
        # --> 0.50.0-ea2
        #
        # RC
        # Version:               0.40.0
        # build.git.branch:      0.40.0-rc1
        # build.git.commit:      d450dca
        # build.git.dirty:       False
        # build.git.description: 0.40.0-rc1
        # --> 0.40.0-rc1
        #
        # GA
        # Version:               0.40.0
        # build.git.branch:      0.40.0
        # build.git.commit:      e301a90
        # build.git.dirty:       False
        # build.git.description: 0.40.0
        # --> 0.40.0

        # Start by assuming that the version is sane and we needn't
        # tack any build metadata onto it.

        build_elements: List[str] = []

        m = AmbScout.reTaggedBranch.search(build.git.branch)

        if not m:
            # This isn't a proper sane version. It must be a local build. Per
            # Scout's rules, anything with semver build metadata is treated as a
            # dev version, so we need to make sure our returned version has some.
            #
            # Start by assuming that we won't find a useable version in the
            # description, and must fall back to 0.0.0.
            build_version = "0.0.0"
            desc_delta = None

            # OK. Can we find a version from what the git description starts
            # with? If so, the upgrade logic in the diagnostics will work more
            # sanely.

            m = AmbScout.reGitDescription.search(build.git.description)

            if m:
                # OK, the description ends with -$delta-g$commit at least, so
                # it may start with a version. Strip off the matching text and
                # remember the delta and commit.

                desc_delta = m.group(1)
                desc = build.git.description[0:m.start()]

                # Does the remaining description match a sane version?
                m = AmbScout.reTaggedBranch.search(desc)

                if m:
                    # Yes. Use it as the base version.
                    build_version = m.group(1)

            # We'll use prerelease "local", and include the branch and such
            # in the build metadata.
            version = '%s-local' % build_version

            # Does the commit not appear in a build element?
            build_elements = []

            if desc_delta:
                build_elements.append(desc_delta)

            build_elements.append("g%s" % build.git.commit)

            # If this branch is dirty, append a build element of "dirty".
            if build.git.dirty:
                build_elements.append('dirty')
        else:
            # The build branch is a sane version. Does it match our base version?
            (base_version, prerelease) = m.groups()

            if base_version != version:
                build_elements.append("q%s" % version.replace('.', '-'))

            # Overwrite the version with the branch only if it's important to show the
            # branch (e.g. 0.50.0-rc7 instead of 0.50.0) at all times. We should probably
            # not do this again -- or we should revamp this stuff to rebuild the Docker
            # image for a GA build.
            # version = build.git.branch

        # Finally, put it all together.
        if build_elements:
            version += "+%s" % ('.'.join(build_elements))

        return version
<|endoftext|>


<commit_before>from django.contrib import admin

from .models import Person, Publication, Position, Talk, Project, Poster, Keyword, News, Banner, Video, Project_header, Photo, Project_umbrella, Project_Role, Sponsor
from website.admin_list_filters import CurrentMemberListFilter, PositionListFilter

from django.http import HttpResponse
from datetime import datetime
from django.template import loader
from django.template import RequestContext

from django.shortcuts import redirect

from django import forms

import urllib

import bibtexparser

from image_cropping import ImageCroppingMixin

class BannerAdmin(ImageCroppingMixin, admin.ModelAdmin):
    fieldsets = [
        (None, {'fields': ["page", "title", "caption", "alt_text", "link", "favorite", "project"]}),
        # ('Image', {'fields': ["image", "image_preview"]})
        ('Image', {'fields': ["image", "cropping"]})
    ]
    list_display = ('__str__', 'admin_thumbnail')
    # readonly_fields = ["image_preview"]

class PositionInline(admin.StackedInline):
    model = Position

    # This specifies that the Inline is linked to the main owner of the position rather than any of the advisor roles.
    fk_name = "person"

    # This specifies that the field appears only once (by default)
    extra = 0

    def formfield_for_foreignkey(self, db_field, request, **kwargs):
        print("PositionInline.formfield_for_foreignkey: db_field: {} db_field.name {} request: {}".format(db_field, db_field.name, request))

        if db_field.name == "advisor" or db_field.name == "co_advisor":
            # Filters advisors to professors and sorts by first name
            # Based on: http://stackoverflow.com/a/30627555
            professor_ids = [person.id for person in Person.objects.all() if person.is_professor()]
            filtered_persons = Person.objects.filter(id__in=professor_ids).order_by('first_name')
            print(filtered_persons)
            kwargs["queryset"] = filtered_persons
        elif db_field.name == "grad_mentor":
            # Filters grad mentor list to current grad students (either member or collaborator)
            grad_ids = [person.id for person in Person.objects.all() if person.is_grad_student() and (person.is_current_member() or person.is_current_collaborator())]
            filtered_persons = Person.objects.filter(id__in=grad_ids).order_by('first_name')
            print(filtered_persons)
            kwargs["queryset"] = filtered_persons

        return super(PositionInline, self).formfield_for_foreignkey(db_field, request, **kwargs)

class ProjectRoleInline(admin.StackedInline):
    model = Project_Role
    extra = 0

class ProjectHeaderInline(ImageCroppingMixin, admin.StackedInline):
    model = Project_header
    extra = 0

# Uses format as per https://github.com/jonasundderwolf/django-image-cropping to add cropping to the admin page
class NewsAdmin(ImageCroppingMixin, admin.ModelAdmin):
    # Filters authors only to current members and sorts by firstname
    # Based on: http://stackoverflow.com/a/30627555
    def formfield_for_foreignkey(self, db_field, request, **kwargs):
        # print("NewsAdmin.formfield_for_foreignkey: db_field: {} db_field.name {} request: {}".format(db_field, db_field.name, request))
        if db_field.name == "author":
            current_member_ids = [person.id for person in Person.objects.all() if person.is_current_member()]
            filtered_persons = Person.objects.filter(id__in=current_member_ids).order_by('first_name')
            print(filtered_persons)
            kwargs["queryset"] = filtered_persons
        return super(NewsAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)

class PhotoAdmin(ImageCroppingMixin, admin.ModelAdmin):
    list_display = ('__str__', 'admin_thumbnail')

class ProjectAdmin(ImageCroppingMixin, admin.ModelAdmin):
    inlines = [ProjectHeaderInline]

class PersonAdmin(ImageCroppingMixin, admin.ModelAdmin):

    # inlines allow us to edit models on the same page as a parent model
    # see: https://docs.djangoproject.com/en/1.11/ref/contrib/admin/#inlinemodeladmin-objects
    inlines = [PositionInline, ProjectRoleInline]

    # The list display lets us control what is shown in the default persons table at Home > Website > People
    # info on displaying multiple entries comes from http://stackoverflow.com/questions/9164610/custom-columns-using-django-admin
    list_display = ('get_full_name', 'get_current_title', 'get_current_role', 'is_active', 'get_start_date', 'get_end_date', 'get_time_in_current_position', 'get_total_time_as_member')

    #TODO setup filter here that has diff categories (like active members, past, etc.):
    #https://www.elements.nl/2015/03/16/getting-the-most-out-of-django-admin-filters/
    #related to: https://github.com/jonfroehlich/makeabilitylabwebsite/issues/238
    list_filter = (CurrentMemberListFilter, PositionListFilter)

class VideoAdmin(admin.ModelAdmin):
    # The list display lets us control what is shown in the default persons table at Home > Website > Videos
    # info on displaying multiple entries comes from http://stackoverflow.com/questions/9164610/custom-columns-using-django-admin
    list_display = ('title', 'caption', 'project')

class TalkAdmin(admin.ModelAdmin):
    # Filters speakers only to current members and collaborators and sorts by first name
    # Based on: https://stackoverflow.com/a/17457828
    def formfield_for_manytomany(self, db_field, request, **kwargs):
        print("TalkAdmin.formfield_for_manytomany: db_field: {} db_field.name {} request: {}".format(db_field, db_field.name, request))
        if db_field.name == "speakers":
            current_member_and_collab_ids = [person.id for person in Person.objects.all() if person.is_current_member()]
            filtered_persons = Person.objects.filter(id__in=current_member_and_collab_ids).order_by('first_name')
            print(filtered_persons)
            kwargs["queryset"] = filtered_persons
        return super(TalkAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)

class PublicationAdmin(admin.ModelAdmin):
    fieldsets = [
        (None,                      {'fields': ['title', 'authors', 'date']}),
        ('Files',                   {'fields': ['pdf_file']}),
        ('Pub Venue information',   {'fields': ['pub_venue_type', 'book_title', 'book_title_short', 'geo_location', 'total_papers_submitted', 'total_papers_accepted']}),
        ('Archival Info',           {'fields': ['official_url', 'extended_abstract', 'peer_reviewed', 'award' ]}),
        ('Video Info',              {'fields': ['video']}),
        ('Page Info',               {'fields': ['num_pages', 'page_num_start', 'page_num_end']}),
        ('Talk Info',               {'fields': ['talk']}),
        ('Project Info',            {'fields': ['projects', 'project_umbrellas']}),
        ('Keyword Info',            {'fields': ['keywords']}),
    ]
    list_display = ('title', 'book_title_short')

    # Uncomment this function to enable auto-entry from bibtex
    # The following code is based in part on a hint by this Stackoverflow post: http://stackoverflow.com/a/4952370
    # See: http://stackoverflow.com/a/10041463 for overiding admin forms
    # def add_view(self, request, **kwargs):

    #     if request.method == 'POST':
    #         # Stage 1 form submitted, parse data and redirect to with data in url to get Django to auto-fill in form
    #         extra_context = {}

    #         extra_context['test_var'] = 'In stage 2!'

    #         bibtex_str = request.POST['bibtex_textarea']
    #         if 'submitbibtex_button' in request.POST and len(bibtex_str) > 0:

    #             bib_database = bibtexparser.loads(bibtex_str)
    #             bib_entry = bib_database.entries[0]
    #             # str_items = ""
    #             # for key in bib_entry:
    #             #     str_items = str_items + "{}={}&".format(key, bib_entry[key])
    #             #
    #             # raw_url = '/admin/website/publication/add/?{}'.format(str_items)
    #             # prepared_url = urllib.parse.urlencode(raw_url)
    #             #return redirect()

    #             # TODO: The problem is that passing values in the url only works if those values are already existing
    #             # django entries. So, for example, if you pass in a bibtex that has a new, never-before-seen author
    #             # then we need to create that Author database entry first. I also cannot actually get one-to-many fields
    #             # like authors to actually pass correctly by value in the url.
    #             params = urllib.parse.urlencode(bib_entry)
    #             redirect_url = '/admin/website/publication/add/?{}'.format(params)
    #             return redirect(redirect_url)
    #             #return redirect('/admin/website/publication/add/?title="test"')
    #         else:
    #             return redirect('/admin/website/publication/add/?title=')

    #     elif not request.GET:

    #         opts = self.model._meta
    #         app_label = opts.app_label

    #         template = loader.get_template('admin/website/publication/bibtex_form.html')
    #         context = RequestContext(request)

    #         # because bibtex_form.thml extends the 'admin/change_form.html' template, we need to add in some variables
    #         # that change_form.html requires. See: http://stackoverflow.com/questions/28777376/problems-extend-change-form-html-in-django-admin
    #         # and specifically the answer: http://stackoverflow.com/a/28777461
    #         context.push(
    #                 {"test_var": "in stage 1",
    #                  'opts': opts,
    #                  'app_label': app_label,
    #                  'change': False,
    #                  'is_popup': False,
    #                  'save_as': False,
    #                  'has_delete_permission': False,
    #                  'has_add_permission': False,
    #                  'has_change_permission': False}
    #         )
    #         return HttpResponse(template.render(context))
    #     elif request.GET:
    #         extra_context = {}
    #         extra_context['test_var'] = 'In stage 1'
    #         return super(PublicationAdmin, self).add_view(request, extra_context=extra_context, **kwargs)

admin.site.register(Person, PersonAdmin)
admin.site.register(Publication, PublicationAdmin)
admin.site.register(Talk, TalkAdmin)
admin.site.register(Project, ProjectAdmin)
admin.site.register(Poster)
admin.site.register(Keyword)
admin.site.register(News, NewsAdmin)
admin.site.register(Banner, BannerAdmin)
admin.site.register(Video, VideoAdmin)
admin.site.register(Photo, PhotoAdmin)
admin.site.register(Project_umbrella)
admin.site.register(Sponsor)
<commit_msg>Video admin table default sort by date<commit_after>from django.contrib import admin

from .models import Person, Publication, Position, Talk, Project, Poster, Keyword, News, Banner, Video, Project_header, Photo, Project_umbrella, Project_Role, Sponsor
from website.admin_list_filters import CurrentMemberListFilter, PositionListFilter

from django.http import HttpResponse
from datetime import datetime
from django.template import loader
from django.template import RequestContext

from django.shortcuts import redirect

from django import forms

import urllib

import bibtexparser

from image_cropping import ImageCroppingMixin

class BannerAdmin(ImageCroppingMixin, admin.ModelAdmin):
    fieldsets = [
        (None, {'fields': ["page", "title", "caption", "alt_text", "link", "favorite", "project"]}),
        # ('Image', {'fields': ["image", "image_preview"]})
        ('Image', {'fields': ["image", "cropping"]})
    ]
    list_display = ('__str__', 'admin_thumbnail')
    # readonly_fields = ["image_preview"]

class PositionInline(admin.StackedInline):
    model = Position

    # This specifies that the Inline is linked to the main owner of the position rather than any of the advisor roles.
    fk_name = "person"

    # This specifies that the field appears only once (by default)
    extra = 0

    def formfield_for_foreignkey(self, db_field, request, **kwargs):
        print("PositionInline.formfield_for_foreignkey: db_field: {} db_field.name {} request: {}".format(db_field, db_field.name, request))

        if db_field.name == "advisor" or db_field.name == "co_advisor":
            # Filters advisors to professors and sorts by first name
            # Based on: http://stackoverflow.com/a/30627555
            professor_ids = [person.id for person in Person.objects.all() if person.is_professor()]
            filtered_persons = Person.objects.filter(id__in=professor_ids).order_by('first_name')
            print(filtered_persons)
            kwargs["queryset"] = filtered_persons
        elif db_field.name == "grad_mentor":
            # Filters grad mentor list to current grad students (either member or collaborator)
            grad_ids = [person.id for person in Person.objects.all() if person.is_grad_student() and (person.is_current_member() or person.is_current_collaborator())]
            filtered_persons = Person.objects.filter(id__in=grad_ids).order_by('first_name')
            print(filtered_persons)
            kwargs["queryset"] = filtered_persons

        return super(PositionInline, self).formfield_for_foreignkey(db_field, request, **kwargs)

class ProjectRoleInline(admin.StackedInline):
    model = Project_Role
    extra = 0

class ProjectHeaderInline(ImageCroppingMixin, admin.StackedInline):
    model = Project_header
    extra = 0

# Uses format as per https://github.com/jonasundderwolf/django-image-cropping to add cropping to the admin page
class NewsAdmin(ImageCroppingMixin, admin.ModelAdmin):
    # Filters authors only to current members and sorts by firstname
    # Based on: http://stackoverflow.com/a/30627555
    def formfield_for_foreignkey(self, db_field, request, **kwargs):
        # print("NewsAdmin.formfield_for_foreignkey: db_field: {} db_field.name {} request: {}".format(db_field, db_field.name, request))
        if db_field.name == "author":
            current_member_ids = [person.id for person in Person.objects.all() if person.is_current_member()]
            filtered_persons = Person.objects.filter(id__in=current_member_ids).order_by('first_name')
            print(filtered_persons)
            kwargs["queryset"] = filtered_persons
        return super(NewsAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)

class PhotoAdmin(ImageCroppingMixin, admin.ModelAdmin):
    list_display = ('__str__', 'admin_thumbnail')

class ProjectAdmin(ImageCroppingMixin, admin.ModelAdmin):
    inlines = [ProjectHeaderInline]

class PersonAdmin(ImageCroppingMixin, admin.ModelAdmin):

    # inlines allow us to edit models on the same page as a parent model
    # see: https://docs.djangoproject.com/en/1.11/ref/contrib/admin/#inlinemodeladmin-objects
    inlines = [PositionInline, ProjectRoleInline]

    # The list display lets us control what is shown in the default persons table at Home > Website > People
    # info on displaying multiple entries comes from http://stackoverflow.com/questions/9164610/custom-columns-using-django-admin
    list_display = ('get_full_name', 'get_current_title', 'get_current_role', 'is_active', 'get_start_date', 'get_end_date', 'get_time_in_current_position', 'get_total_time_as_member')

    #TODO setup filter here that has diff categories (like active members, past, etc.):
    #https://www.elements.nl/2015/03/16/getting-the-most-out-of-django-admin-filters/
    #related to: https://github.com/jonfroehlich/makeabilitylabwebsite/issues/238
    list_filter = (CurrentMemberListFilter, PositionListFilter)

class VideoAdmin(admin.ModelAdmin):
    # The list display lets us control what is shown in the default persons table at Home > Website > Videos
    # info on displaying multiple entries comes from http://stackoverflow.com/questions/9164610/custom-columns-using-django-admin
    list_display = ('title', 'date', 'caption', 'project')

    # default lay out in descending order by date
    ordering = ('-date',)

class TalkAdmin(admin.ModelAdmin):
    # Filters speakers only to current members and collaborators and sorts by first name
    # Based on: https://stackoverflow.com/a/17457828
    def formfield_for_manytomany(self, db_field, request, **kwargs):
        print("TalkAdmin.formfield_for_manytomany: db_field: {} db_field.name {} request: {}".format(db_field, db_field.name, request))
        if db_field.name == "speakers":
            current_member_and_collab_ids = [person.id for person in Person.objects.all() if person.is_current_member()]
            filtered_persons = Person.objects.filter(id__in=current_member_and_collab_ids).order_by('first_name')
            print(filtered_persons)
            kwargs["queryset"] = filtered_persons
        return super(TalkAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)

class PublicationAdmin(admin.ModelAdmin):
    fieldsets = [
        (None,                      {'fields': ['title', 'authors', 'date']}),
        ('Files',                   {'fields': ['pdf_file']}),
        ('Pub Venue information',   {'fields': ['pub_venue_type', 'book_title', 'book_title_short', 'geo_location', 'total_papers_submitted', 'total_papers_accepted']}),
        ('Archival Info',           {'fields': ['official_url', 'extended_abstract', 'peer_reviewed', 'award' ]}),
        ('Video Info',              {'fields': ['video']}),
        ('Page Info',               {'fields': ['num_pages', 'page_num_start', 'page_num_end']}),
        ('Talk Info',               {'fields': ['talk']}),
        ('Project Info',            {'fields': ['projects', 'project_umbrellas']}),
        ('Keyword Info',            {'fields': ['keywords']}),
    ]
    list_display = ('title', 'book_title_short')

    # Uncomment this function to enable auto-entry from bibtex
    # The following code is based in part on a hint by this Stackoverflow post: http://stackoverflow.com/a/4952370
    # See: http://stackoverflow.com/a/10041463 for overiding admin forms
    # def add_view(self, request, **kwargs):

    #     if request.method == 'POST':
    #         # Stage 1 form submitted, parse data and redirect to with data in url to get Django to auto-fill in form
    #         extra_context = {}

    #         extra_context['test_var'] = 'In stage 2!'

    #         bibtex_str = request.POST['bibtex_textarea']
    #         if 'submitbibtex_button' in request.POST and len(bibtex_str) > 0:

    #             bib_database = bibtexparser.loads(bibtex_str)
    #             bib_entry = bib_database.entries[0]
    #             # str_items = ""
    #             # for key in bib_entry:
    #             #     str_items = str_items + "{}={}&".format(key, bib_entry[key])
    #             #
    #             # raw_url = '/admin/website/publication/add/?{}'.format(str_items)
    #             # prepared_url = urllib.parse.urlencode(raw_url)
    #             #return redirect()

    #             # TODO: The problem is that passing values in the url only works if those values are already existing
    #             # django entries. So, for example, if you pass in a bibtex that has a new, never-before-seen author
    #             # then we need to create that Author database entry first. I also cannot actually get one-to-many fields
    #             # like authors to actually pass correctly by value in the url.
    #             params = urllib.parse.urlencode(bib_entry)
    #             redirect_url = '/admin/website/publication/add/?{}'.format(params)
    #             return redirect(redirect_url)
    #             #return redirect('/admin/website/publication/add/?title="test"')
    #         else:
    #             return redirect('/admin/website/publication/add/?title=')

    #     elif not request.GET:

    #         opts = self.model._meta
    #         app_label = opts.app_label

    #         template = loader.get_template('admin/website/publication/bibtex_form.html')
    #         context = RequestContext(request)

    #         # because bibtex_form.thml extends the 'admin/change_form.html' template, we need to add in some variables
    #         # that change_form.html requires. See: http://stackoverflow.com/questions/28777376/problems-extend-change-form-html-in-django-admin
    #         # and specifically the answer: http://stackoverflow.com/a/28777461
    #         context.push(
    #                 {"test_var": "in stage 1",
    #                  'opts': opts,
    #                  'app_label': app_label,
    #                  'change': False,
    #                  'is_popup': False,
    #                  'save_as': False,
    #                  'has_delete_permission': False,
    #                  'has_add_permission': False,
    #                  'has_change_permission': False}
    #         )
    #         return HttpResponse(template.render(context))
    #     elif request.GET:
    #         extra_context = {}
    #         extra_context['test_var'] = 'In stage 1'
    #         return super(PublicationAdmin, self).add_view(request, extra_context=extra_context, **kwargs)

admin.site.register(Person, PersonAdmin)
admin.site.register(Publication, PublicationAdmin)
admin.site.register(Talk, TalkAdmin)
admin.site.register(Project, ProjectAdmin)
admin.site.register(Poster)
admin.site.register(Keyword)
admin.site.register(News, NewsAdmin)
admin.site.register(Banner, BannerAdmin)
admin.site.register(Video, VideoAdmin)
admin.site.register(Photo, PhotoAdmin)
admin.site.register(Project_umbrella)
admin.site.register(Sponsor)
<|endoftext|>


<commit_before>#
# __init__.py -- Basic version and package information
#
# Copyright (c) 2007-2009  Christian Hammond
# Copyright (c) 2007-2009  David Trowbridge
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#

# The version of RBTools
#
# This is in the format of:
#
#   (Major, Minor, Micro, alpha/beta/rc/final, Release Number, Released)
#
VERSION = (0, 3, 1, 'alpha', 0, False)

def get_version_string():
    version = '%s.%s' % (VERSION[0], VERSION[1])

    if VERSION[2]:
        version += ".%s" % VERSION[2]

    if VERSION[3] != 'final':
        if VERSION[3] == 'rc':
            version += ' RC%s' % VERSION[4]
        else:
            version += ' %s %s' % (VERSION[3], VERSION[4])

    if not is_release():
        version += " (dev)"

    return version

def get_package_version():
    version = '%s.%s' % (VERSION[0], VERSION[1])

    if VERSION[2]:
        version += ".%s" % VERSION[2]

    if VERSION[3] != 'final':
        version += '%s%s' % (VERSION[3], VERSION[4])

    return version

def is_release():
    return VERSION[5]

__version_info__ = VERSION[:-1]
__version__ = get_package_version()
<commit_msg>Release RBTools v0.3.1.<commit_after>#
# __init__.py -- Basic version and package information
#
# Copyright (c) 2007-2009  Christian Hammond
# Copyright (c) 2007-2009  David Trowbridge
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#

# The version of RBTools
#
# This is in the format of:
#
#   (Major, Minor, Micro, alpha/beta/rc/final, Release Number, Released)
#
VERSION = (0, 3, 1, 'final', 0, True)

def get_version_string():
    version = '%s.%s' % (VERSION[0], VERSION[1])

    if VERSION[2]:
        version += ".%s" % VERSION[2]

    if VERSION[3] != 'final':
        if VERSION[3] == 'rc':
            version += ' RC%s' % VERSION[4]
        else:
            version += ' %s %s' % (VERSION[3], VERSION[4])

    if not is_release():
        version += " (dev)"

    return version

def get_package_version():
    version = '%s.%s' % (VERSION[0], VERSION[1])

    if VERSION[2]:
        version += ".%s" % VERSION[2]

    if VERSION[3] != 'final':
        version += '%s%s' % (VERSION[3], VERSION[4])

    return version

def is_release():
    return VERSION[5]

__version_info__ = VERSION[:-1]
__version__ = get_package_version()
<|endoftext|>


<commit_before>#!/usr/bin/env python

import wx
import requests

class SkM_UI(wx.Frame):

    def __init__(self, parent, title):
        wx.Frame.__init__(self, parent, title=title, size=(530,250))

        vbox = wx.BoxSizer(wx.VERTICAL)

        font = wx.SystemSettings_GetFont(wx.SYS_SYSTEM_FONT)
        font.SetPointSize(14)

        self.Centre()

        hbox = wx.BoxSizer(wx.HORIZONTAL)
        panel = wx.Panel(self)
        st = wx.StaticText(panel, label='Movie Title')
        st.SetFont(font)

        hbox.Add(st, flag=wx.RIGHT, border=8)
        self.tc = wx.TextCtrl(parent=panel)
        hbox.Add(self.tc, proportion=1)
        vbox.Add(hbox, flag=wx.EXPAND|wx.LEFT|wx.RIGHT|wx.TOP, border=10)
        vbox.Add((-1, 10))

        self.genre = wx.CheckBox(panel, -1, pos=(5, 180), label='Genre')
        self.rated = wx.CheckBox(panel, -1, pos=(135, 180), label='Rated')
        self.lang = wx.CheckBox(panel, -1, pos=(265, 180), label='Languages')
        self.poster = wx.CheckBox(panel, -1, pos=(395, 180), label='IMDb Poster')

        self.url = wx.CheckBox(panel, -1, pos=(5, 90), label='IMDb URL')
        self.ID = wx.CheckBox(panel, -1, pos=(135, 90), label='IMDb ID')
        self.cntry = wx.CheckBox(panel, -1, pos=(265, 90), label='Country')
        self.location = wx.CheckBox(panel, -1, pos=(395, 90), label='Filming Location')

        self.writer = wx.CheckBox(panel, -1, pos=(5, 120), label='Writers')
        self.plot = wx.CheckBox(panel, -1, pos=(135, 120), label='Plot Synopsis')
        self.year = wx.CheckBox(panel, -1, pos=(265, 120), label='Year')
        self.runtme = wx.CheckBox(panel, -1, pos=(395, 120), label='Runtime')

        self.release = wx.CheckBox(panel, -1, pos=(5, 150), label='Release')
        self.director = wx.CheckBox(panel, -1, pos=(135, 150), label='Directors')
        self.actor = wx.CheckBox(panel, -1, pos=(265, 150), label='Actors')
        self.rating = wx.CheckBox(panel, -1, pos=(395, 150), label='Rating')

        hbox2 = wx.BoxSizer(wx.HORIZONTAL)
        self.OkBtn = wx.Button(parent=panel, label='Ok', size=(70, 30))
        self.ClsBtn = wx.Button(parent=panel, label='Close', size=(70, 30))
        hbox2.Add(self.OkBtn, flag=wx.RIGHT, border=15)
        hbox2.Add(self.ClsBtn, flag=wx.RIGHT, border=15)

        self.Bind(wx.EVT_BUTTON, self.results, self.OkBtn)
        self.Bind(wx.EVT_BUTTON, self.stpexit, self.ClsBtn)

        vbox.Add(hbox2, flag=wx.ALIGN_RIGHT|wx.BOTTOM, border=10)
        panel.SetSizer(vbox)
        self.Show()

    def stpexit(self, event):
        self.Destroy()

    def results(self, event):
        m = ''
        data = self.tc.GetValue()
        data = [str(i) for i in data.split(' ')]
        req = requests.get('http://www.imdbapi.org/?title=%s' % data)
        try:
            data = req.json()[0]
            m = m + '\n------------------------------------------------------------------------'
            m = m + '\n'
            m = 'Search Results For : %s' % data['title']
            m = m + '\n'
            m = m + '\n************************************************************************'
            m = m + '\n'

            if self.director.GetValue():
                d = ''
                for director in data['directors']:
                    d = d + director + ', '
                d = d.rstrip(', ')
                m = m + '\n'
                m = m + '\nDirectors: %s' % d

            if self.writer.GetValue():
                w = ''
                for writer in data['writers']:
                    w = w + writer + ', '
                w = w.rstrip(', ')
                m = m + '\n'
                m = m + '\nWriters: %s' % w

            if self.actor.GetValue():
                a = ''
                for actor in data['actors']:
                    a = a + actor + ', '
                a = a.rstrip(', ')
                m = m + '\n'
                m = '\nActors/Actresses: %s' % a

            if self.rating.GetValue():
                m = m + '\n'
                m = m + '\nMovie Rating: %s' % data['rating']

            if self.rated.GetValue():
                m = m + '\n'
                m = m + '\nRated: %s' % data['rated']

            if self.lang.GetValue():
                l = ''
                for lang in data['language']:
                    l = l + lang + ', '
                l = l.rstrip(', ')
                m = m + '\n'
                m = m + '\nLanguage: %s' % l

            if self.poster.GetValue():
                m = m + '\n'
                m = m + '\nPoster Url: %s' % data['poster']

            if self.url.GetValue():
                m = m + '\n'
                m = m + '\nIMDB address: %s' % data['imdb_url']

            if self.ID.GetValue():
                m = m + '\n'
                m = m + '\nIMDB id: %s' % data['imdb_id']

            if self.plot.GetValue():
                m = m + '\n'
                m = m + '\nPlot: %s' % data['plot_simple']

            if self.release.GetValue():
                rel = str(data['release_date'])
                m = m + '\n'
                m = m + '\nRelease Date: %s' % rel[4:6] + ' ' + rel[6:8] + ' ' + rel[:4]

            if self.year.GetValue():
                m = m + '\n'
                m = m + '\nYear: %s' % data['year']

            if self.location.GetValue():
                m = m + '\n'
                m = m + '\nFilming Locations: %s' % data['filming_locations']

            if self.runtme.GetValue():
                r = ''
                for runtime in data['runtime']:
                    r = r + runtime + ', '
                r = r.rstrip(', ')
                m = m + '\n'
                m = m + '\nTotal Runtime: %s' % r

            if self.cntry.GetValue():
                c = ''
                for cntry in data['country']:
                    c = c + cntry + ', '
                c = c.rstrip(', ')
                m = m + '\n'
                m = m + '\nCountry: %s' % c

            if self.genre.GetValue():
                g = ''
                for genre in data['genres']:
                    g = g + genre + ', '
                g = g.rstrip(', ')
                m = m + '\n'
                m = m + '\nGenre: %s' % g
            m = m + '\n________________________________________________________________________'

            dialog = wx.MessageDialog(self, m, style=wx.OK)
            dialog.ShowModal()
            dialog.Destroy()
        except KeyError:
            dialog = wx.MessageDialog(self, 'Make sure you have the correct title!', style=wx.OK)
            dialog.ShowModal()
            dialog.Destroy()
        return

if __name__ == '__main__':
    app = wx.App(False)
    frame = SkM_UI(None, 'IMDb Shortcut')
    app.MainLoop()

<commit_msg>added select all options<commit_after>#!/usr/bin/env python

import wx
import requests

class SkM_UI(wx.Frame):

    def __init__(self, parent, title):
        wx.Frame.__init__(self, parent, title=title, size=(530, 250))

        vbox = wx.BoxSizer(wx.VERTICAL)

        font = wx.SystemSettings_GetFont(wx.SYS_SYSTEM_FONT)
        font.SetPointSize(14)

        self.Centre()

        hbox = wx.BoxSizer(wx.HORIZONTAL)
        panel = wx.Panel(self)
        st = wx.StaticText(panel, label='Movie Title')
        st.SetFont(font)

        hbox.Add(st, flag=wx.RIGHT, border=8)
        self.tc = wx.TextCtrl(parent=panel)
        hbox.Add(self.tc, proportion=1)
        vbox.Add(hbox, flag=wx.EXPAND|wx.LEFT|wx.RIGHT|wx.TOP, border=10)
        vbox.Add((-1, 10))

        self.genre = wx.CheckBox(panel, -1, pos=(5, 180), label='Genre')
        self.rated = wx.CheckBox(panel, -1, pos=(135, 180), label='Rated')
        self.lang = wx.CheckBox(panel, -1, pos=(265, 180), label='Languages')
        self.poster = wx.CheckBox(panel, -1, pos=(395, 180), label='IMDb Poster')

        self.url = wx.CheckBox(panel, -1, pos=(5, 90), label='IMDb URL')
        self.ID = wx.CheckBox(panel, -1, pos=(135, 90), label='IMDb ID')
        self.cntry = wx.CheckBox(panel, -1, pos=(265, 90), label='Country')
        self.location = wx.CheckBox(panel, -1, pos=(395, 90), label='Filming Location')

        self.writer = wx.CheckBox(panel, -1, pos=(5, 120), label='Writers')
        self.plot = wx.CheckBox(panel, -1, pos=(135, 120), label='Plot Synopsis')
        self.year = wx.CheckBox(panel, -1, pos=(265, 120), label='Year')
        self.runtme = wx.CheckBox(panel, -1, pos=(395, 120), label='Runtime')

        self.release = wx.CheckBox(panel, -1, pos=(5, 150), label='Release')
        self.director = wx.CheckBox(panel, -1, pos=(135, 150), label='Directors')
        self.actor = wx.CheckBox(panel, -1, pos=(265, 150), label='Actors')
        self.rating = wx.CheckBox(panel, -1, pos=(395, 150), label='Rating')

        self.select_all = wx.CheckBox(panel, -1, pos=(25, 220), label='Select All')

        hbox2 = wx.BoxSizer(wx.HORIZONTAL)
        self.OkBtn = wx.Button(parent=panel, label='Ok', size=(70, 30))
        self.ClsBtn = wx.Button(parent=panel, label='Close', size=(70, 30))
        hbox2.Add(self.OkBtn, flag=wx.RIGHT, border=15)
        hbox2.Add(self.ClsBtn, flag=wx.RIGHT, border=15)

        self.Bind(wx.EVT_BUTTON, self.results, self.OkBtn)
        self.Bind(wx.EVT_BUTTON, self.stpexit, self.ClsBtn)
        self.Bind(wx.EVT_CHECKBOX, self.chkall, self.select_all)

        vbox.Add(hbox2, flag=wx.ALIGN_RIGHT|wx.BOTTOM, border=10)
        panel.SetSizer(vbox)
        self.Show()

    def stpexit(self, event):
        self.Destroy()

    def chkall(self, event):
        self.genre.SetValue(event.IsChecked())
        self.rated.SetValue(event.IsChecked())
        self.lang.SetValue(event.IsChecked())
        self.poster.SetValue(event.IsChecked())

        self.url.SetValue(event.IsChecked())
        self.ID.SetValue(event.IsChecked())
        self.cntry.SetValue(event.IsChecked())
        self.location.SetValue(event.IsChecked())

        self.writer.SetValue(event.IsChecked())
        self.plot.SetValue(event.IsChecked())
        self.year.SetValue(event.IsChecked())
        self.runtme.SetValue(event.IsChecked())

        self.release.SetValue(event.IsChecked())
        self.director.SetValue(event.IsChecked())
        self.actor.SetValue(event.IsChecked())
        self.rating.SetValue(event.IsChecked())

    def results(self, event):
        m = ''
        data = self.tc.GetValue()
        data = [str(i) for i in data.split(' ')]
        req = requests.get('http://www.imdbapi.org/?title=%s' % data)
        try:
            data = req.json()[0]
            m = m + '\n------------------------------------------------------------------------'
            m = m + '\n'
            m = 'Search Results For : %s' % data['title']
            m = m + '\n'
            m = m + '\n************************************************************************'
            m = m + '\n'

            if self.director.GetValue():
                d = ''
                for director in data['directors']:
                    d = d + director + ', '
                d = d.rstrip(', ')
                m = m + '\n'
                m = m + '\nDirectors: %s' % d

            if self.writer.GetValue():
                w = ''
                for writer in data['writers']:
                    w = w + writer + ', '
                w = w.rstrip(', ')
                m = m + '\n'
                m = m + '\nWriters: %s' % w

            if self.actor.GetValue():
                a = ''
                for actor in data['actors']:
                    a = a + actor + ', '
                a = a.rstrip(', ')
                m = m + '\n'
                m = '\nActors/Actresses: %s' % a

            if self.rating.GetValue():
                m = m + '\n'
                m = m + '\nMovie Rating: %s' % data['rating']

            if self.rated.GetValue():
                m = m + '\n'
                m = m + '\nRated: %s' % data['rated']

            if self.lang.GetValue():
                l = ''
                for lang in data['language']:
                    l = l + lang + ', '
                l = l.rstrip(', ')
                m = m + '\n'
                m = m + '\nLanguage: %s' % l

            if self.poster.GetValue():
                m = m + '\n'
                m = m + '\nPoster Url: %s' % data['poster']

            if self.url.GetValue():
                m = m + '\n'
                m = m + '\nIMDB address: %s' % data['imdb_url']

            if self.ID.GetValue():
                m = m + '\n'
                m = m + '\nIMDB id: %s' % data['imdb_id']

            if self.plot.GetValue():
                m = m + '\n'
                m = m + '\nPlot: %s' % data['plot_simple']

            if self.release.GetValue():
                rel = str(data['release_date'])
                m = m + '\n'
                m = m + '\nRelease Date: %s' % rel[4:6] + ' ' + rel[6:8] + ' ' + rel[:4]

            if self.year.GetValue():
                m = m + '\n'
                m = m + '\nYear: %s' % data['year']

            if self.location.GetValue():
                m = m + '\n'
                m = m + '\nFilming Locations: %s' % data['filming_locations']

            if self.runtme.GetValue():
                r = ''
                for runtime in data['runtime']:
                    r = r + runtime + ', '
                r = r.rstrip(', ')
                m = m + '\n'
                m = m + '\nTotal Runtime: %s' % r

            if self.cntry.GetValue():
                c = ''
                for cntry in data['country']:
                    c = c + cntry + ', '
                c = c.rstrip(', ')
                m = m + '\n'
                m = m + '\nCountry: %s' % c

            if self.genre.GetValue():
                g = ''
                for genre in data['genres']:
                    g = g + genre + ', '
                g = g.rstrip(', ')
                m = m + '\n'
                m = m + '\nGenre: %s' % g
            m = m + '\n________________________________________________________________________'

            dialog = wx.MessageDialog(self, m, style=wx.OK)
            dialog.ShowModal()
            dialog.Destroy()
        except KeyError:
            dialog = wx.MessageDialog(self, 'Make sure you have the correct title!', style=wx.OK)
            dialog.ShowModal()
            dialog.Destroy()
        return

if __name__ == '__main__':
    app = wx.App(False)
    frame = SkM_UI(None, 'IMDb Shortcut')
    app.MainLoop()

<|endoftext|>


<commit_before>from motif_analyzer import celery
from .models import Result

from bson import ObjectId
import re

@celery.task(name='tasks.analyze_sequence')
def analyze_sequence(query_id, sequence_description, sequence, motif_list, motif_frequency, motif_frame_size, user):
    """
    Analyzes single sequence and inserts
    results of analysis into MongoDB
    :param query_id:
    :param sequence_description:
    :param sequence:
    :param motif_list:
    :param motif_frequency:
    :param motif_frame_size:
    :param user:
    :return:
    """
    sequence_regex_matches = []
    has_motif = False

    for motif_str in motif_list:
        motif_regex = re.compile(motif_str)
        regex_match_list = []

        for match in motif_regex.finditer(sequence):
            substr_start = int(match.start())
            substr_end = substr_start + motif_frame_size
            substr_analysis = [match for match in motif_regex.finditer(sequence[substr_start:substr_end])]
            substr_match_list = []

            if len(substr_analysis) >= motif_frequency:
                for substr_match in substr_analysis:
                    substr = {
                        'match': substr_match.group(),
                        'span': [(substr_start + substr_match.span()[0]), (substr_start + substr_match.span()[1])]
                    }
                    substr_match_list.append(substr)
                has_motif = True
                regex_match_list.append(substr_match_list)
        regex_data = {
            motif_str: regex_match_list
        }
        sequence_regex_matches.append(regex_data)

    Result.insert_one(
        query_id=ObjectId(query_id),
        sequence_description=sequence_description,
        sequence=sequence,
        analysis=sequence_regex_matches,
        has_motif=has_motif,
        user=user
    )
<commit_msg>DONE MUST TEST CELERY TASK  QUEUE<commit_after>from motif_analyzer import celery
from .models import Result

from bson import ObjectId
import re

@celery.task(name='app.celery.analyze_sequence')
def analyze_sequence(query_id, sequence_description, sequence, motif_list, motif_frequency, motif_frame_size, user):
    """
    Analyzes single sequence and inserts
    results of analysis into MongoDB
    :param query_id:
    :param sequence_description:
    :param sequence:
    :param motif_list:
    :param motif_frequency:
    :param motif_frame_size:
    :param user:
    :return:
    """
    sequence_regex_matches = []
    has_motif = False

    for motif_str in motif_list:
        motif_regex = re.compile(motif_str)
        regex_match_list = []

        for match in motif_regex.finditer(sequence):
            substr_start = int(match.start())
            substr_end = substr_start + motif_frame_size
            substr_analysis = [match for match in motif_regex.finditer(sequence[substr_start:substr_end])]
            substr_match_list = []

            if len(substr_analysis) >= motif_frequency:
                for substr_match in substr_analysis:
                    substr = {
                        'match': substr_match.group(),
                        'span': [(substr_start + substr_match.span()[0]), (substr_start + substr_match.span()[1])]
                    }
                    substr_match_list.append(substr)
                has_motif = True
                regex_match_list.append(substr_match_list)
        regex_data = {
            motif_str: regex_match_list
        }
        sequence_regex_matches.append(regex_data)

    Result.insert_one(
        query_id=ObjectId(query_id),
        sequence_description=sequence_description,
        sequence=sequence,
        analysis=sequence_regex_matches,
        has_motif=has_motif,
        user=user
    )
<|endoftext|>