<commit_before>load("//private/rules:javadoc.bzl", "javadoc")
load("//private/rules:maven_project_jar.bzl", "maven_project_jar")
load("//private/rules:maven_publish.bzl", "maven_publish")
load("//private/rules:pom_file.bzl", "pom_file")

def java_export(
        name,
        maven_coordinates,
        deploy_env = [],
        pom_template = None,
        visibility = None,
        tags = [],
        **kwargs):
    """Extends `java_library` to allow maven artifacts to be uploaded.

    This macro can be used as a drop-in replacement for `java_library`, but
    also generates an implicit `name.publish` target that can be run to publish
    maven artifacts derived from this macro to a maven repository. The publish
    rule understands the following variables (declared using `--define` when
    using `bazel run`):

      * `maven_repo`: A URL for the repo to use. May be "https" or "file".
      * `maven_user`: The user name to use when uploading to the maven repository.
      * `maven_password`: The password to use when uploading to the maven repository.

    This macro also generates a `name-pom` target that creates the `pom.xml` file
    associated with the artifacts. The template used is derived from the (optional)
    `pom_template` argument, and the following substitutions are performed on
    the template file:

      * `{groupId}`: Replaced with the maven coordinates group ID.
      * `{artifactId}`: Replaced with the maven coordinates artifact ID.
      * `{version}`: Replaced by the maven coordinates version.
      * `{type}`: Replaced by the maven coordintes type, if present (defaults to "jar")
      * `{dependencies}`: Replaced by a list of maven dependencies directly relied upon
        by java_library targets within the artifact.

    The "edges" of the artifact are found by scanning targets that contribute to
    runtime dependencies for the following tags:

      * `maven_coordinates=group:artifact:type:version`: Specifies a dependency of
        this artifact.
      * `maven:compile_only`: Specifies that this dependency should not be listed
        as a dependency of the artifact being generated.

    To skip generation of the javadoc jar, add the `no-javadocs` tag to the target.

    Generated rules:
      * `name`: A `java_library` that other rules can depend upon.
      * `name-docs`: A javadoc jar file.
      * `name-pom`: The pom.xml file.
      * `name.publish`: To be executed by `bazel run` to publish to a maven repo.

    Args:
      name: A unique name for this target
      maven_coordinates: The maven coordinates for this target.
      pom_template: The template to be used for the pom.xml file.
      deploy_env: A list of labels of java targets to exclude from the generated jar
      visibility: The visibility of the target
      kwargs: These are passed to [`java_library`](https://docs.bazel.build/versions/master/be/java.html#java_library),
        and so may contain any valid parameter for that rule.
    """

    tags = tags + ["maven_coordinates=%s" % maven_coordinates]
    lib_name = "%s-lib" % name

    javadocopts = kwargs.pop("javadocopts", [])

    # Construct the java_library we'll export from here.
    native.java_library(
        name = lib_name,
        tags = tags,
        **kwargs
    )

    # Merge the jars to create the maven project jar
    maven_project_jar(
        name = "%s-project" % name,
        target = ":%s" % lib_name,
        deploy_env = deploy_env,
        tags = tags,
    )

    native.filegroup(
        name = "%s-maven-artifact" % name,
        srcs = [
            ":%s-project" % name,
        ],
        output_group = "maven_artifact",
    )

    native.filegroup(
        name = "%s-maven-source" % name,
        srcs = [
            ":%s-project" % name,
        ],
        output_group = "maven_source",
    )

    docs_jar = None
    if not "no-javadocs" in tags:
        docs_jar = "%s-docs" % name
        javadoc(
            name = docs_jar,
            deps = [
                ":%s-project" % name,
            ],
            javadocopts = javadocopts
        )

    pom_file(
        name = "%s-pom" % name,
        target = ":%s" % lib_name,
        pom_template = pom_template,
    )

    maven_publish(
        name = "%s.publish" % name,
        coordinates = maven_coordinates,
        pom = "%s-pom" % name,
        javadocs = docs_jar,
        artifact_jar = ":%s-maven-artifact" % name,
        source_jar = ":%s-maven-source" % name,
        visibility = visibility,
    )

    # Finally, alias the primary output
    native.alias(
        name = name,
        actual = ":%s-project" % name,
        visibility = visibility,
    )
<commit_msg>Propagate bazel tags= in java_export sub-targets (#647)<commit_after>load("//private/rules:javadoc.bzl", "javadoc")
load("//private/rules:maven_project_jar.bzl", "maven_project_jar")
load("//private/rules:maven_publish.bzl", "maven_publish")
load("//private/rules:pom_file.bzl", "pom_file")

def java_export(
        name,
        maven_coordinates,
        deploy_env = [],
        pom_template = None,
        visibility = None,
        tags = [],
        **kwargs):
    """Extends `java_library` to allow maven artifacts to be uploaded.

    This macro can be used as a drop-in replacement for `java_library`, but
    also generates an implicit `name.publish` target that can be run to publish
    maven artifacts derived from this macro to a maven repository. The publish
    rule understands the following variables (declared using `--define` when
    using `bazel run`):

      * `maven_repo`: A URL for the repo to use. May be "https" or "file".
      * `maven_user`: The user name to use when uploading to the maven repository.
      * `maven_password`: The password to use when uploading to the maven repository.

    This macro also generates a `name-pom` target that creates the `pom.xml` file
    associated with the artifacts. The template used is derived from the (optional)
    `pom_template` argument, and the following substitutions are performed on
    the template file:

      * `{groupId}`: Replaced with the maven coordinates group ID.
      * `{artifactId}`: Replaced with the maven coordinates artifact ID.
      * `{version}`: Replaced by the maven coordinates version.
      * `{type}`: Replaced by the maven coordintes type, if present (defaults to "jar")
      * `{dependencies}`: Replaced by a list of maven dependencies directly relied upon
        by java_library targets within the artifact.

    The "edges" of the artifact are found by scanning targets that contribute to
    runtime dependencies for the following tags:

      * `maven_coordinates=group:artifact:type:version`: Specifies a dependency of
        this artifact.
      * `maven:compile_only`: Specifies that this dependency should not be listed
        as a dependency of the artifact being generated.

    To skip generation of the javadoc jar, add the `no-javadocs` tag to the target.

    Generated rules:
      * `name`: A `java_library` that other rules can depend upon.
      * `name-docs`: A javadoc jar file.
      * `name-pom`: The pom.xml file.
      * `name.publish`: To be executed by `bazel run` to publish to a maven repo.

    Args:
      name: A unique name for this target
      maven_coordinates: The maven coordinates for this target.
      pom_template: The template to be used for the pom.xml file.
      deploy_env: A list of labels of java targets to exclude from the generated jar
      visibility: The visibility of the target
      kwargs: These are passed to [`java_library`](https://docs.bazel.build/versions/master/be/java.html#java_library),
        and so may contain any valid parameter for that rule.
    """

    maven_coordinates_tags = ["maven_coordinates=%s" % maven_coordinates]
    lib_name = "%s-lib" % name

    javadocopts = kwargs.pop("javadocopts", [])

    # Construct the java_library we'll export from here.
    native.java_library(
        name = lib_name,
        tags = tags + maven_coordinates_tags,
        **kwargs
    )

    # Merge the jars to create the maven project jar
    maven_project_jar(
        name = "%s-project" % name,
        target = ":%s" % lib_name,
        deploy_env = deploy_env,
        tags = tags + maven_coordinates_tags,
    )

    native.filegroup(
        name = "%s-maven-artifact" % name,
        srcs = [
            ":%s-project" % name,
        ],
        output_group = "maven_artifact",
        tags = tags,
    )

    native.filegroup(
        name = "%s-maven-source" % name,
        srcs = [
            ":%s-project" % name,
        ],
        output_group = "maven_source",
        tags = tags,
    )

    docs_jar = None
    if not "no-javadocs" in tags:
        docs_jar = "%s-docs" % name
        javadoc(
            name = docs_jar,
            deps = [
                ":%s-project" % name,
            ],
            javadocopts = javadocopts,
            tags = tags,
        )

    pom_file(
        name = "%s-pom" % name,
        target = ":%s" % lib_name,
        pom_template = pom_template,
        tags = tags,
    )

    maven_publish(
        name = "%s.publish" % name,
        coordinates = maven_coordinates,
        pom = "%s-pom" % name,
        javadocs = docs_jar,
        artifact_jar = ":%s-maven-artifact" % name,
        source_jar = ":%s-maven-source" % name,
        visibility = visibility,
        tags = tags,
    )

    # Finally, alias the primary output
    native.alias(
        name = name,
        actual = ":%s-project" % name,
        visibility = visibility,
        tags = tags,
    )
<|endoftext|>


<commit_before>from rest_framework.response import Response
from rest_framework.views import APIView

from crawler.models import App
from crawler.serializers import AppSerializer

class AppList(APIView):
    def get(self, request, format=None):
        users = App.objects.all()[:25]
        serializer = AppSerializer(users, many=True)
        return Response(serializer.data)
<commit_msg>Fixing returning to get all apps. The django rest handles the paging for me<commit_after>from rest_framework.response import Response
from rest_framework.views import APIView

from crawler.models import App
from crawler.serializers import AppSerializer

class AppList(APIView):
    def get(self, request, format=None):
        users = App.objects.all()
        serializer = AppSerializer(users, many=True)
        return Response(serializer.data)
<|endoftext|>


<commit_before># -*- coding: UTF-8 -*-
# Copyright 2016-2018 Rumma & Ko Ltd
# License: BSD (see file COPYING for details)

"""Database models specific for the Team variant of Lino Noi.

Defines a customized :class:`TicketDetail`.

"""
from __future__ import print_function

from lino_xl.lib.tickets.models import *
from lino.modlib.users.mixins import Assignable
from lino.api import _

from lino_xl.lib.working.choicelists import ReportingTypes, ZERO_DURATION
from lino.modlib.summaries.mixins import Summarized

def get_summary_fields():
    for t in ReportingTypes.get_list_items():
        yield t.name + '_hours'

class Site(Site):

    class Meta(Site.Meta):
        app_label = 'tickets'
        abstract = dd.is_abstract_model(__name__, 'Site')

    def get_change_observers(self, ar=None):
        action = ar.bound_action.action if ar.bound_action else None
        if ar is not None and isinstance(action, CreateRow) and issubclass(ar.actor.model,Ticket):
            subs = rt.models.tickets.Subscription.objects.filter(site=ar.selected_rows[-1].site)
            for (u, um) in [(u, u.mail_mode) for u in [sub.user for sub in subs]
                            if (u.user_type and u.user_type.has_required_roles([Triager])
                                and u != ar.get_user())]:
                yield (u, um)
        else:
            for s in rt.models.tickets.Subscription.objects.filter(site=self):
                yield (s.user, s.user.mail_mode)

    def after_ui_create(self, ar):
        super(Site, self).after_ui_create(ar)
        rt.models.tickets.Subscription.objects.create(user=ar.get_user(), site=self)

class Ticket(Ticket, Assignable, Summarized):

    class Meta(Ticket.Meta):
        # app_label = 'tickets'
        abstract = dd.is_abstract_model(__name__, 'Ticket')

    def assigned_to_changed(self, ar):
        """Add a star and send notification of Assignment"""
        # self.add_change_watcher(self.assigned_to)

        if (self.assigned_to is not None and
                self.assigned_to != ar.user and
                dd.is_installed('notify')):
            ctx = dict(user=ar.user, what=ar.obj2memo(self))
            def msg(user, mm):
                subject = _("{user} has assigned you to ticket: {what}").format(**ctx)
                return (subject , tostring(E.span(subject)))

            mt = rt.models.notify.MessageTypes.tickets

            rt.models.notify.Message.emit_notification(
                ar, self, mt, msg,
                [(self.assigned_to, self.assigned_to.mail_mode)]
            )
    # def end_user_changed(self, ar):
    #     """Add a star"""
    #     self.add_change_watcher(self.end_user)

    # def user_changed(self, ar):
    #     """Add a star"""
    #     self.add_change_watcher(self.user)

    def after_ui_create(self, ar):
        # print("Create")
        # self.site_changed(ar)
        # self.assigned_to_changed(ar)
        # self.end_user_changed(ar)
        # self.user_changed(ar)
        super(Ticket, self).after_ui_create(ar)

    show_commits = dd.ShowSlaveTable('github.CommitsByTicket')
    show_changes = dd.ShowSlaveTable('changes.ChangesByMaster')
    # show_wishes = dd.ShowSlaveTable('deploy.DeploymentsByTicket')
    # show_stars = dd.ShowSlaveTable('stars.AllStarsByController')

    def get_change_subject(self, ar, cw):
        ctx = dict(user=ar.user, what=str(self))
        if cw is None:
            return _("{user} submitted ticket {what}").format(**ctx)
        if len(list(cw.get_updates())) == 0:
            return
        return _("{user} modified {what}").format(**ctx)

    def get_change_body(self, ar, cw):
        ctx = dict(user=ar.user, what=ar.obj2memo(self))
        if cw is None:
            elems = [E.p(
                _("{user} submitted ticket {what}").format(**ctx), ".")]
            elems += list(self.get_change_info(ar, cw))
        else:
            items = list(cw.get_updates_html(["_user_cache"]))
            if len(items) == 0:
                return
            elems = []
            elems += list(self.get_change_info(ar, cw))
            elems.append(E.p(
                _("{user} modified {what}").format(**ctx), ":"))
            elems.append(E.ul(*items))
        # print("20170210 {}".format(tostring(E.div(*elems))))
        return tostring(E.div(*elems))

    @classmethod
    def get_layout_aliases(cls):
        yield ("SUMMARY_FIELDS", ' '.join(get_summary_fields()))

    # @classmethod
    # def get_summary_master_model(cls):
    #     return cls

    def reset_summary_data(self):
        for k in get_summary_fields():
            setattr(self, k, ZERO_DURATION)
        self.last_commenter = None

    def get_summary_collectors(self):
        qs = rt.models.working.Session.objects.filter(ticket=self)
        yield (self.add_from_session, qs)
        qs = rt.models.comments.Comment.objects.filter(**gfk2lookup(rt.models.comments.Comment._meta.get_field("owner"),
                                                                    self)
                                                       ).order_by("-created")[0:1]
        yield (self.add_from_comment, qs)

    def add_from_comment(self, obj):
        self.last_commenter = obj.user

    def add_from_session(self, obj):
        d = obj.get_duration()
        if d:
            rt = obj.get_reporting_type()
            k = rt.name + '_hours'
            value = getattr(self, k) + d
            setattr(self, k, value)\

    @dd.chooser()
    def site_choices(cls, end_user, user, ar):
        user = user if user is not None else ar.get_user()
        sub_user = [user.pk]
        if end_user: sub_user.append(end_user.pk)
        pks = rt.models.tickets.Subscription.objects.filter(user__pk__in=sub_user).values_list("site__pk", flat=True)
        print(pks)
        return Site.objects.filter(id__in=pks)

class TicketDetail(TicketDetail):
    """Customized detail_layout for Tickets in Noi

    """
    main = "general more comments.CommentsByMentioned #history_tab #more2 #github.CommitsByTicket"

    general = dd.Panel("""
    general1:60 comments.CommentsByRFC:30
    """, label=_("General"))

    general1 = """
    general1a:30 general1b:30
    """

    # 50+6=56
    # in XL: label span is 4, so we have 8 units for the fields
    # 56.0/8 = 7
    # summary:  50/56*8 = 7.14 --> 7
    # id:  6/56*8 = 0.85 -> 1
    general1a = """
    summary id:6
    site ticket_type
    workflow_buttons
    description
    """
    general1b = """
    user end_user
    assigned_to private:10
    priority:10 planned_time
    SUMMARY_FIELDS
    working.SessionsByTicket
    """

    more = dd.Panel("""
    more1 DuplicatesByTicket:20 #WishesByTicket
    upgrade_notes LinksByTicket uploads.UploadsByController
    """, label=_("More"))

    # history_tab = dd.Panel("""
    # changes.ChangesByMaster #stars.StarsByController:20
    # github.CommitsByTicket
    # """, label=_("History"), required_roles=dd.login_required(Triager))

    more1 = """
    created modified fixed_since #reported_for #fixed_date #fixed_time
    state ref duplicate_of deadline
    # standby feedback closed
    """

    # more2 = dd.Panel("""
    # # deploy.DeploymentsByTicket
    # # skills.DemandsByDemander
    # stars.AllStarsByController
    # uploads.UploadsByController
    # """, label=_("Even more"))

class TicketInsertLayout(dd.InsertLayout):
    main = """
    summary #private:20
    right:30 left:50
    """

    right = """
    ticket_type
    priority
    end_user
    #assigned_to
    site
    """

    left = """
    description
    """

    window_size = (80, 20)

class SiteDetail(SiteDetail):

    main = """general config"""

    general = dd.Panel("""
    gen_left:20 TicketsBySite:60
    """, label=_("General"))

    gen_left = """
    overview
    group
    SubscriptionsBySite
    """

    general2 = """
    ref name
    company contact_person
    reporting_type #start_date end_date hours_paid
    remark:20 private
    workflow_buttons:20 id
    working.SummariesBySite
    """

    config = dd.Panel("""
    general2:50 description:30
    """, label=_("Configure"), required_roles = dd.login_required(TicketsStaff))

    # history = dd.Panel("""
    # # meetings.MeetingsBySite
    # working.SummariesBySite
    # """, label=_("History"))

# Note in the following lines we don't subclass Tickets because then
# we would need to also override these attributes for all subclasses

Tickets.insert_layout = 'tickets.TicketInsertLayout'
Tickets.params_layout = """user end_user assigned_to not_assigned_to interesting_for site has_site state priority
    #deployed_to show_assigned show_active #show_deployed show_todo show_private
    start_date end_date observed_event #topic #feasable_by has_ref
    last_commenter not_last_commenter subscriber"""
Tickets.column_names = 'id summary:50 #user:10 #topic #faculty priority ' \
                       'workflow_buttons:30 site:10 #project:10'
Tickets.tablet_columns = "id summary workflow_buttons"
#Tickets.tablet_columns_popin = "site project"

Tickets.mobile_columns = "workflow_buttons"
#Tickets.mobile_columns_pop = "summary workflow_buttons"
Tickets.popin_columns = "summary"

Tickets.order_by = ["-id"]

TicketsBySite.column_names = "priority detail_link planned_time SUMMARY_FIELDS workflow_buttons *"
AllSites.column_names = "ref name company group remark workflow_buttons id *"
# Sites.detail_layout = """
# id name partner #responsible_user
# remark
# #InterestsBySite TicketsBySite deploy.MilestonesBySite
# """

# Not needed, have it be inffered by mobile_columns or tablet_columns if both None, use normal grid.
#AllTickets.display_mode = "responsive_grid"
<commit_msg>Ticket.site_choices() was obsolete and untested<commit_after># -*- coding: UTF-8 -*-
# Copyright 2016-2018 Rumma & Ko Ltd
# License: BSD (see file COPYING for details)

"""Database models specific for the Team variant of Lino Noi.

Defines a customized :class:`TicketDetail`.

"""
from __future__ import print_function

from lino_xl.lib.tickets.models import *
from lino.modlib.users.mixins import Assignable
from lino.api import _

from lino_xl.lib.working.choicelists import ReportingTypes, ZERO_DURATION
from lino.modlib.summaries.mixins import Summarized

def get_summary_fields():
    for t in ReportingTypes.get_list_items():
        yield t.name + '_hours'

class Site(Site):

    class Meta(Site.Meta):
        app_label = 'tickets'
        abstract = dd.is_abstract_model(__name__, 'Site')

    def get_change_observers(self, ar=None):
        action = ar.bound_action.action if ar.bound_action else None
        if ar is not None and isinstance(action, CreateRow) and issubclass(ar.actor.model,Ticket):
            subs = rt.models.tickets.Subscription.objects.filter(site=ar.selected_rows[-1].site)
            for (u, um) in [(u, u.mail_mode) for u in [sub.user for sub in subs]
                            if (u.user_type and u.user_type.has_required_roles([Triager])
                                and u != ar.get_user())]:
                yield (u, um)
        else:
            for s in rt.models.tickets.Subscription.objects.filter(site=self):
                yield (s.user, s.user.mail_mode)

    def after_ui_create(self, ar):
        super(Site, self).after_ui_create(ar)
        rt.models.tickets.Subscription.objects.create(user=ar.get_user(), site=self)

class Ticket(Ticket, Assignable, Summarized):

    class Meta(Ticket.Meta):
        # app_label = 'tickets'
        abstract = dd.is_abstract_model(__name__, 'Ticket')

    def assigned_to_changed(self, ar):
        """Add a star and send notification of Assignment"""
        # self.add_change_watcher(self.assigned_to)

        if (self.assigned_to is not None and
                self.assigned_to != ar.user and
                dd.is_installed('notify')):
            ctx = dict(user=ar.user, what=ar.obj2memo(self))
            def msg(user, mm):
                subject = _("{user} has assigned you to ticket: {what}").format(**ctx)
                return (subject , tostring(E.span(subject)))

            mt = rt.models.notify.MessageTypes.tickets

            rt.models.notify.Message.emit_notification(
                ar, self, mt, msg,
                [(self.assigned_to, self.assigned_to.mail_mode)]
            )
    # def end_user_changed(self, ar):
    #     """Add a star"""
    #     self.add_change_watcher(self.end_user)

    # def user_changed(self, ar):
    #     """Add a star"""
    #     self.add_change_watcher(self.user)

    def after_ui_create(self, ar):
        # print("Create")
        # self.site_changed(ar)
        # self.assigned_to_changed(ar)
        # self.end_user_changed(ar)
        # self.user_changed(ar)
        super(Ticket, self).after_ui_create(ar)

    show_commits = dd.ShowSlaveTable('github.CommitsByTicket')
    show_changes = dd.ShowSlaveTable('changes.ChangesByMaster')
    # show_wishes = dd.ShowSlaveTable('deploy.DeploymentsByTicket')
    # show_stars = dd.ShowSlaveTable('stars.AllStarsByController')

    def get_change_subject(self, ar, cw):
        ctx = dict(user=ar.user, what=str(self))
        if cw is None:
            return _("{user} submitted ticket {what}").format(**ctx)
        if len(list(cw.get_updates())) == 0:
            return
        return _("{user} modified {what}").format(**ctx)

    def get_change_body(self, ar, cw):
        ctx = dict(user=ar.user, what=ar.obj2memo(self))
        if cw is None:
            elems = [E.p(
                _("{user} submitted ticket {what}").format(**ctx), ".")]
            elems += list(self.get_change_info(ar, cw))
        else:
            items = list(cw.get_updates_html(["_user_cache"]))
            if len(items) == 0:
                return
            elems = []
            elems += list(self.get_change_info(ar, cw))
            elems.append(E.p(
                _("{user} modified {what}").format(**ctx), ":"))
            elems.append(E.ul(*items))
        # print("20170210 {}".format(tostring(E.div(*elems))))
        return tostring(E.div(*elems))

    @classmethod
    def get_layout_aliases(cls):
        yield ("SUMMARY_FIELDS", ' '.join(get_summary_fields()))

    # @classmethod
    # def get_summary_master_model(cls):
    #     return cls

    def reset_summary_data(self):
        for k in get_summary_fields():
            setattr(self, k, ZERO_DURATION)
        self.last_commenter = None

    def get_summary_collectors(self):
        qs = rt.models.working.Session.objects.filter(ticket=self)
        yield (self.add_from_session, qs)
        qs = rt.models.comments.Comment.objects.filter(**gfk2lookup(rt.models.comments.Comment._meta.get_field("owner"),
                                                                    self)
                                                       ).order_by("-created")[0:1]
        yield (self.add_from_comment, qs)

    def add_from_comment(self, obj):
        self.last_commenter = obj.user

    def add_from_session(self, obj):
        d = obj.get_duration()
        if d:
            rt = obj.get_reporting_type()
            k = rt.name + '_hours'
            value = getattr(self, k) + d
            setattr(self, k, value)\

    @dd.chooser()
    def site_choices(cls, ar):
        # if user is None:
        #     user = ar.get_user()
        user = ar.get_user()
        # user = user if user is not None else ar.get_user()
        group_ids = rt.models.groups.Membership.objects.filter(user=user).values_list("group__pk", flat=True)
        # user_ids = [user.pk]
        # if end_user: user_ids.append(end_user.pk)
        # pks = rt.models.tickets.Subscription.objects.filter(user__pk__in=user_ids).values_list("site__pk", flat=True)
        # # print(pks)
        # return Site.objects.filter(id__in=pks)
        return Site.objects.filter(group__in=group_ids)

class TicketDetail(TicketDetail):
    """Customized detail_layout for Tickets in Noi

    """
    main = "general more comments.CommentsByMentioned #history_tab #more2 #github.CommitsByTicket"

    general = dd.Panel("""
    general1:60 comments.CommentsByRFC:30
    """, label=_("General"))

    general1 = """
    general1a:30 general1b:30
    """

    # 50+6=56
    # in XL: label span is 4, so we have 8 units for the fields
    # 56.0/8 = 7
    # summary:  50/56*8 = 7.14 --> 7
    # id:  6/56*8 = 0.85 -> 1
    general1a = """
    summary id:6
    site ticket_type
    workflow_buttons
    description
    """
    general1b = """
    user end_user
    assigned_to private:10
    priority:10 planned_time
    SUMMARY_FIELDS
    working.SessionsByTicket
    """

    more = dd.Panel("""
    more1 DuplicatesByTicket:20 #WishesByTicket
    upgrade_notes LinksByTicket uploads.UploadsByController
    """, label=_("More"))

    # history_tab = dd.Panel("""
    # changes.ChangesByMaster #stars.StarsByController:20
    # github.CommitsByTicket
    # """, label=_("History"), required_roles=dd.login_required(Triager))

    more1 = """
    created modified fixed_since #reported_for #fixed_date #fixed_time
    state ref duplicate_of deadline
    # standby feedback closed
    """

    # more2 = dd.Panel("""
    # # deploy.DeploymentsByTicket
    # # skills.DemandsByDemander
    # stars.AllStarsByController
    # uploads.UploadsByController
    # """, label=_("Even more"))

class TicketInsertLayout(dd.InsertLayout):
    main = """
    summary #private:20
    right:30 left:50
    """

    right = """
    ticket_type
    priority
    end_user
    #assigned_to
    site
    """

    left = """
    description
    """

    window_size = (80, 20)

class SiteDetail(SiteDetail):

    main = """general config"""

    general = dd.Panel("""
    gen_left:20 TicketsBySite:60
    """, label=_("General"))

    gen_left = """
    overview
    group
    SubscriptionsBySite
    """

    general2 = """
    ref name
    company contact_person
    reporting_type #start_date end_date hours_paid
    remark:20 private
    workflow_buttons:20 id
    working.SummariesBySite
    """

    config = dd.Panel("""
    general2:50 description:30
    """, label=_("Configure"), required_roles = dd.login_required(TicketsStaff))

    # history = dd.Panel("""
    # # meetings.MeetingsBySite
    # working.SummariesBySite
    # """, label=_("History"))

# Note in the following lines we don't subclass Tickets because then
# we would need to also override these attributes for all subclasses

Tickets.insert_layout = 'tickets.TicketInsertLayout'
Tickets.params_layout = """user end_user assigned_to not_assigned_to interesting_for site has_site state priority
    #deployed_to show_assigned show_active #show_deployed show_todo show_private
    start_date end_date observed_event #topic #feasable_by has_ref
    last_commenter not_last_commenter subscriber"""
Tickets.column_names = 'id summary:50 #user:10 #topic #faculty priority ' \
                       'workflow_buttons:30 site:10 #project:10'
Tickets.tablet_columns = "id summary workflow_buttons"
#Tickets.tablet_columns_popin = "site project"

Tickets.mobile_columns = "workflow_buttons"
#Tickets.mobile_columns_pop = "summary workflow_buttons"
Tickets.popin_columns = "summary"

Tickets.order_by = ["-id"]

TicketsBySite.column_names = "priority detail_link planned_time SUMMARY_FIELDS workflow_buttons *"
AllSites.column_names = "ref name company group remark workflow_buttons id *"
# Sites.detail_layout = """
# id name partner #responsible_user
# remark
# #InterestsBySite TicketsBySite deploy.MilestonesBySite
# """

# Not needed, have it be inffered by mobile_columns or tablet_columns if both None, use normal grid.
#AllTickets.display_mode = "responsive_grid"
<|endoftext|>


<commit_before>#!/usr/bin/env python
DESC = """EPP script for Quant-iT mesurements to verify standards, calculate
concentrations and load input artifact-udfs and output file-udfs of the process
with concentation values and fluorescence intensity

Reads from:
    --Lims fields--
    "Assay type"                process udf
    "Standard volume"           process udf
    "Standard dilution"         process udf
    "Linearity of standards"    process udf
    "Sample volume"             process udf

    --files--
    "Standards File (.txt)"     "shared result file" uploaded by user.
    "Quant-iT Result File 1"    "shared result file" uploaded by user.
    "Quant-iT Result File 2"    "shared result file" uploaded by user. (optional)

Writes to:
    --Lims fields--
    "Fluorescence intensity 1"  udf of input analytes to the process
    "Fluorescence intensity 2"  udf of input analytes to the  process
    "Concentration"             udf of process artifacts (result file)
    "Conc. Units"               udf of process artifacts (result file)

Logging:
The script outputs a regular log file with regular execution information.

Performance:
1)  Makes a linear regression analysis on the End RFU standards read from
"Standards File (.txt)" --> slope, intersect and R2 (Pearson correlation coefficient)

2)  If R2 is less than "Linearity of standards", standards are not ok and the
user is warned "Problem with standards! Redo measurement!".

3)  If R2 is greater than "Linearity of standards", concentration values are
calculated based on the linear regression parameters, copied to the "Concentration"-udf
on the output artifacts (one result file per sample). The "Conc. Units"-udf on the same
artifacts are set to "ng/ul".

4)  "End RFU" values from "Quant-iT Result File 1" are copied to the udf
"Fluorescence intentisy 1" of the input analyte to the process, and "End RFU" values from
"Quant-iT Result File 2" are copied to the udf "Fluorescence intensity 2".

Written by Maya Brandi
"""

import os
import sys
import logging
import numpy as np

from argparse import ArgumentParser
from requests import HTTPError
from genologics.lims import Lims
from genologics.config import BASEURI,USERNAME,PASSWORD
from genologics.entities import Process
from genologics.epp import EppLogger
from genologics.epp import set_field
from genologics.epp import ReadResultFiles
lims = Lims(BASEURI,USERNAME,PASSWORD)

class QunatiT():
    def __init__(self, process):
        self.file_handler = ReadResultFiles(process)
        self.udfs = dict(process.udf.items())
        self.abstract = []
        self.missing_udfs = []
        self.missing_samps =[]
        self.no_samps = 0
        self.standards = self._make_standards_dict()
        self.model = self._verify_standards()
        self.result_files = self._formated_result_files_dict()

    def _formated_result_files_dict(self):
        """"Quant-iT Result File 1" and "Quant-iT Result File 2" (the second is optional)
        uploaded by user, are formated and stored in a dict"""
        result_files_dict = {}
        file_names = {'Quant-iT Result File 1':'Fluorescence intensity 1',
                    'Quant-iT Result File 2':'Fluorescence intensity 2'}
        for f_name, udf_name in file_names.items():
            if self.file_handler.shared_files.has_key(f_name):
                result_file = self.file_handler.shared_files[f_name]
                result_files_dict[udf_name] = self.file_handler.format_file(result_file,
                                            name = f_name, root_key_col = 1, header_row = 19)
        return result_files_dict

    def _make_standards_dict(self):
        """End RFU standards are read from 'Standards File (.txt)' and stored in a dict"""
        standards_file = self.file_handler.shared_files['Standards File (.txt)']
        standards_file_formated = self.file_handler.format_file(standards_file,
                        name = 'Standards File (.txt)', root_key_col = 1, header_row = 19)
        standards_dict = {}
        for k,v in standards_file_formated.items():
            if set(['Sample','End RFU']).issubset(v) and v['Sample'].split()[0]=='Standard':
                standard = int(v['Sample'].split()[1])
                standards_dict[standard] = float(v['End RFU'])
        return standards_dict

    def _nuclear_acid_amount_in_standards(self):
        """Nuclear acid amount in standards is calculated as
        "Supposed concentrations of standards" * "Standard volume" / "Standard dilution"
        Supposed concentrations of standards are different between Quant-iT BR
        assays and Quant-iT HS assays."""
        requiered_udfs = set(['Standard volume','Assay type','Standard dilution'])
        supp_conc_stds = {'RNA BR':[0,5,10,20,40,60,80,100],
                          'DNA BR':[0,5,10,20,40,60,80,100],
                          'RNA':[0,0.5,1,2,4,6,8,10],
                          'DNA HS':[0,0.5,1,2,4,6,8,10]}
        if requiered_udfs.issubset(self.udfs.keys()):
            nuclear_acid_amount = np.ones(8)
            for standard in range(8):
                supp_conc_standard = supp_conc_stds[self.udfs['Assay type']][standard]
                nuclear_acid_amount[standard] = np.true_divide(supp_conc_standard *
                                    self.udfs['Standard volume'], self.udfs['Standard dilution'])
            return nuclear_acid_amount
        elif not requiered_udfs.issubset(self.missing_udfs):
            self.missing_udfs += requiered_udfs
        return None

    def _linear_regression(self, X,Y):
        """Perform linear regression with intersect forced to origin. And calculates
        Pearson correlation coefficient R2. """
        X = np.array(X)
        X_force_zero = X[:,np.newaxis]
        slope = np.linalg.lstsq(X_force_zero, Y)[0]

        A = np.array([ X, np.ones(len(X))])
        resid = np.linalg.lstsq(A.T,Y)[1]
        R2 = 1 - resid / (Y.size * Y.var())
        return float(R2), float(slope)

    def _verify_standards(self):
        """Performing linear regresion on standards.
        X = Relative fluorescence intensities of 8 standards
        Y = Nuclear acid amount in standards
        Y = slope*X + intersect; R2=Pearson correlation coefficient."""
        amount_in_standards = self._nuclear_acid_amount_in_standards()
        if amount_in_standards is not None:
            relative_standards = np.ones(8)
            for k,v in self.standards.items():
                relative_standards[k-1] = v - self.standards[1]
            R2, slope = self._linear_regression(relative_standards, amount_in_standards)
            return [R2, slope]
        else:
            return None

    def get_and_set_fluor_int(self, target_file):
        """Copies "End RFU" values from "Quant-iT Result File 1" and "Quant-iT Result File 2"
        (if provided) to udfs "Fluorescence intentisy 1" and "Fluorescence intensity 2.
        Calculates and returns Relative fluorescence intensitiy standards:
        rel_fluor_int = The End RFU of standards - Background fluorescence intensity"""
        sample = target_file.samples[0].name
        fluor_int = []
        target_udfs = target_file.udf.items()
        if dict(target_udfs).has_key("Fluorescence intentisy 1"):
            del target_udfs["Fluorescence intentisy 1"]
        if dict(target_udfs).has_key("Fluorescence intentisy 2"):
            del target_udfs["Fluorescence intentisy 2"]
        target_file.udf = target_udfs
        for udf_name ,formated_file in self.result_files.items():
            if sample in formated_file.keys():
                fluor_int.append(int(formated_file[sample]['End RFU']))
                target_file.udf[udf_name] = int(formated_file[sample]['End RFU'])
            else:
                self.missing_samps.append(sample)
        set_field(target_file)
        rel_fluor_int = np.mean(fluor_int) - self.standards[1]
        return rel_fluor_int

    def calc_and_set_conc(self, target_file, rel_fluor_int):
        """Concentrations are calculated based on the linear regression parametersand copied to
        the "Concentration"-udf of the target_file. The "Conc. Units"-udf is set to "ng/ul"""
        requiered_udfs = set(['Sample volume','Standard dilution','WS volume'])
        if requiered_udfs.issubset(self.udfs.keys()) and self.model:
            conc = np.true_divide((self.model[1] * rel_fluor_int * (self.udfs['WS volume'] +
            self.udfs['Sample volume'])),self.udfs['Sample volume']*(self.udfs['WS volume'] +
                                                                self.udfs['Standard volume']))
            target_file.udf['Concentration'] = conc
            target_file.udf['Conc. Units'] = 'ng/ul'
            set_field(target_file)
            self.no_samps +=1
        elif not requiered_udfs.issubset(self.missing_udfs):
            self.missing_udfs += requiered_udfs

def main(lims, pid, epp_logger):
    process = Process(lims,id = pid)
    QiT = QunatiT(process)
    target_files = dict((r.samples[0].name, r) for r in process.result_files())
    if QiT.model and 'Linearity of standards' in QiT.udfs.keys():
        R2 = QiT.model[0]
        if R2 >= QiT.udfs['Linearity of standards']:
            QiT.abstract.insert(0,"R2 = {0}. Standards OK.".format(R2))
            if QiT.result_files:
                for sample, target_file in target_files.items():
                    rel_fluor_int = QiT.get_and_set_fluor_int(target_file)
                    QiT.calc_and_set_conc(target_file, rel_fluor_int)
                QiT.abstract.append("Concentrations uploaded for {0} samples.".format(QiT.no_samps))
            else:
                QiT.abstract.append("Upload input file(s) for samples.")
        else:
            QiT.abstract.insert(0, "R2 = {0}. Problem with standards! Redo measurement!".format(R2))
    else:
        QiT.missing_udfs.append('Linearity of standards')
    if QiT.missing_samps:
        QiT.abstract.append("The folowing samples are missing in Quant-iT result File 1 or 2: {0}.".format(
                                                                            ', '.join(QiT.missing_samps)))

    if QiT.missing_udfs:
        QiT.abstract.append("Are all of the folowing udfs set? : {0}".format(', '.join(QiT.missing_udfs)))

    print >> sys.stderr, ' '.join(QiT.abstract)

if __name__ == "__main__":
    parser = ArgumentParser(description=DESC)
    parser.add_argument('--pid', default = None , dest = 'pid',
                        help='Lims id for current Process')
    parser.add_argument('--log', dest = 'log',
                        help=('File name for standard log file, '
                              'for runtime information and problems.'))

    args = parser.parse_args()
    lims = Lims(BASEURI,USERNAME,PASSWORD)
    lims.check_version()

    with EppLogger(log_file=args.log, lims=lims, prepend=True) as epp_logger:
        main(lims, args.pid, epp_logger)

<commit_msg>rm old flourecence intencity from udf if not given as input<commit_after>#!/usr/bin/env python
DESC = """EPP script for Quant-iT mesurements to verify standards, calculate
concentrations and load input artifact-udfs and output file-udfs of the process
with concentation values and fluorescence intensity

Reads from:
    --Lims fields--
    "Assay type"                process udf
    "Standard volume"           process udf
    "Standard dilution"         process udf
    "Linearity of standards"    process udf
    "Sample volume"             process udf

    --files--
    "Standards File (.txt)"     "shared result file" uploaded by user.
    "Quant-iT Result File 1"    "shared result file" uploaded by user.
    "Quant-iT Result File 2"    "shared result file" uploaded by user. (optional)

Writes to:
    --Lims fields--
    "Fluorescence intensity 1"  udf of input analytes to the process
    "Fluorescence intensity 2"  udf of input analytes to the  process
    "Concentration"             udf of process artifacts (result file)
    "Conc. Units"               udf of process artifacts (result file)

Logging:
The script outputs a regular log file with regular execution information.

Performance:
1)  Makes a linear regression analysis on the End RFU standards read from
"Standards File (.txt)" --> slope, intersect and R2 (Pearson correlation coefficient)

2)  If R2 is less than "Linearity of standards", standards are not ok and the
user is warned "Problem with standards! Redo measurement!".

3)  If R2 is greater than "Linearity of standards", concentration values are
calculated based on the linear regression parameters, copied to the "Concentration"-udf
on the output artifacts (one result file per sample). The "Conc. Units"-udf on the same
artifacts are set to "ng/ul".

4)  "End RFU" values from "Quant-iT Result File 1" are copied to the udf
"Fluorescence intentisy 1" of the input analyte to the process, and "End RFU" values from
"Quant-iT Result File 2" are copied to the udf "Fluorescence intensity 2".

Written by Maya Brandi
"""

import os
import sys
import logging
import numpy as np

from argparse import ArgumentParser
from requests import HTTPError
from genologics.lims import Lims
from genologics.config import BASEURI,USERNAME,PASSWORD
from genologics.entities import Process
from genologics.epp import EppLogger
from genologics.epp import set_field
from genologics.epp import ReadResultFiles
lims = Lims(BASEURI,USERNAME,PASSWORD)

class QunatiT():
    def __init__(self, process):
        self.file_handler = ReadResultFiles(process)
        self.udfs = dict(process.udf.items())
        self.abstract = []
        self.missing_udfs = []
        self.missing_samps =[]
        self.no_samps = 0
        self.standards = self._make_standards_dict()
        self.model = self._verify_standards()
        self.result_files = self._formated_result_files_dict()

    def _formated_result_files_dict(self):
        """"Quant-iT Result File 1" and "Quant-iT Result File 2" (the second is optional)
        uploaded by user, are formated and stored in a dict"""
        result_files_dict = {}
        file_names = {'Quant-iT Result File 1':'Fluorescence intensity 1',
                    'Quant-iT Result File 2':'Fluorescence intensity 2'}
        for f_name, udf_name in file_names.items():
            if self.file_handler.shared_files.has_key(f_name):
                result_file = self.file_handler.shared_files[f_name]
                result_files_dict[udf_name] = self.file_handler.format_file(result_file,
                                            name = f_name, root_key_col = 1, header_row = 19)
        return result_files_dict

    def _make_standards_dict(self):
        """End RFU standards are read from 'Standards File (.txt)' and stored in a dict"""
        standards_file = self.file_handler.shared_files['Standards File (.txt)']
        standards_file_formated = self.file_handler.format_file(standards_file,
                        name = 'Standards File (.txt)', root_key_col = 1, header_row = 19)
        standards_dict = {}
        for k,v in standards_file_formated.items():
            if set(['Sample','End RFU']).issubset(v) and v['Sample'].split()[0]=='Standard':
                standard = int(v['Sample'].split()[1])
                standards_dict[standard] = float(v['End RFU'])
        return standards_dict

    def _nuclear_acid_amount_in_standards(self):
        """Nuclear acid amount in standards is calculated as
        "Supposed concentrations of standards" * "Standard volume" / "Standard dilution"
        Supposed concentrations of standards are different between Quant-iT BR
        assays and Quant-iT HS assays."""
        requiered_udfs = set(['Standard volume','Assay type','Standard dilution'])
        supp_conc_stds = {'RNA BR':[0,5,10,20,40,60,80,100],
                          'DNA BR':[0,5,10,20,40,60,80,100],
                          'RNA':[0,0.5,1,2,4,6,8,10],
                          'DNA HS':[0,0.5,1,2,4,6,8,10]}
        if requiered_udfs.issubset(self.udfs.keys()):
            nuclear_acid_amount = np.ones(8)
            for standard in range(8):
                supp_conc_standard = supp_conc_stds[self.udfs['Assay type']][standard]
                nuclear_acid_amount[standard] = np.true_divide(supp_conc_standard *
                                    self.udfs['Standard volume'], self.udfs['Standard dilution'])
            return nuclear_acid_amount
        elif not requiered_udfs.issubset(self.missing_udfs):
            self.missing_udfs += requiered_udfs
        return None

    def _linear_regression(self, X,Y):
        """Perform linear regression with intersect forced to origin. And calculates
        Pearson correlation coefficient R2. """
        X = np.array(X)
        X_force_zero = X[:,np.newaxis]
        slope = np.linalg.lstsq(X_force_zero, Y)[0]

        A = np.array([ X, np.ones(len(X))])
        resid = np.linalg.lstsq(A.T,Y)[1]
        R2 = 1 - resid / (Y.size * Y.var())
        return float(R2), float(slope)

    def _verify_standards(self):
        """Performing linear regresion on standards.
        X = Relative fluorescence intensities of 8 standards
        Y = Nuclear acid amount in standards
        Y = slope*X + intersect; R2=Pearson correlation coefficient."""
        amount_in_standards = self._nuclear_acid_amount_in_standards()
        if amount_in_standards is not None:
            relative_standards = np.ones(8)
            for k,v in self.standards.items():
                relative_standards[k-1] = v - self.standards[1]
            R2, slope = self._linear_regression(relative_standards, amount_in_standards)
            return [R2, slope]
        else:
            return None

    def get_and_set_fluor_int(self, target_file):
        """Copies "End RFU" values from "Quant-iT Result File 1" and "Quant-iT Result File 2"
        (if provided) to udfs "Fluorescence intentisy 1" and "Fluorescence intensity 2.
        Calculates and returns Relative fluorescence intensitiy standards:
        rel_fluor_int = The End RFU of standards - Background fluorescence intensity"""
        sample = target_file.samples[0].name
        fluor_int = []
        target_udfs = target_file.udf
        if dict(target_udfs.items()).has_key("Fluorescence intentisy 1"):
            del target_udfs["Fluorescence intentisy 1"]
        if dict(target_udfs.items()).has_key("Fluorescence intentisy 2"):
            del target_udfs["Fluorescence intentisy 2"]
        target_file.udf = target_udfs
        for udf_name ,formated_file in self.result_files.items():
            if sample in formated_file.keys():
                fluor_int.append(int(formated_file[sample]['End RFU']))
                target_file.udf[udf_name] = int(formated_file[sample]['End RFU'])
            else:
                self.missing_samps.append(sample)
        set_field(target_file)
        rel_fluor_int = np.mean(fluor_int) - self.standards[1]
        return rel_fluor_int

    def calc_and_set_conc(self, target_file, rel_fluor_int):
        """Concentrations are calculated based on the linear regression parametersand copied to
        the "Concentration"-udf of the target_file. The "Conc. Units"-udf is set to "ng/ul"""
        requiered_udfs = set(['Sample volume','Standard dilution','WS volume'])
        if requiered_udfs.issubset(self.udfs.keys()) and self.model:
            conc = np.true_divide((self.model[1] * rel_fluor_int * (self.udfs['WS volume'] +
            self.udfs['Sample volume'])),self.udfs['Sample volume']*(self.udfs['WS volume'] +
                                                                self.udfs['Standard volume']))
            target_file.udf['Concentration'] = conc
            target_file.udf['Conc. Units'] = 'ng/ul'
            set_field(target_file)
            self.no_samps +=1
        elif not requiered_udfs.issubset(self.missing_udfs):
            self.missing_udfs += requiered_udfs

def main(lims, pid, epp_logger):
    process = Process(lims,id = pid)
    QiT = QunatiT(process)
    target_files = dict((r.samples[0].name, r) for r in process.result_files())
    if QiT.model and 'Linearity of standards' in QiT.udfs.keys():
        R2 = QiT.model[0]
        if R2 >= QiT.udfs['Linearity of standards']:
            QiT.abstract.insert(0,"R2 = {0}. Standards OK.".format(R2))
            if QiT.result_files:
                for sample, target_file in target_files.items():
                    rel_fluor_int = QiT.get_and_set_fluor_int(target_file)
                    QiT.calc_and_set_conc(target_file, rel_fluor_int)
                QiT.abstract.append("Concentrations uploaded for {0} samples.".format(QiT.no_samps))
            else:
                QiT.abstract.append("Upload input file(s) for samples.")
        else:
            QiT.abstract.insert(0, "R2 = {0}. Problem with standards! Redo measurement!".format(R2))
    else:
        QiT.missing_udfs.append('Linearity of standards')
    if QiT.missing_samps:
        QiT.abstract.append("The folowing samples are missing in Quant-iT result File 1 or 2: {0}.".format(
                                                                            ', '.join(QiT.missing_samps)))

    if QiT.missing_udfs:
        QiT.abstract.append("Are all of the folowing udfs set? : {0}".format(', '.join(QiT.missing_udfs)))

    print >> sys.stderr, ' '.join(QiT.abstract)

if __name__ == "__main__":
    parser = ArgumentParser(description=DESC)
    parser.add_argument('--pid', default = None , dest = 'pid',
                        help='Lims id for current Process')
    parser.add_argument('--log', dest = 'log',
                        help=('File name for standard log file, '
                              'for runtime information and problems.'))

    args = parser.parse_args()
    lims = Lims(BASEURI,USERNAME,PASSWORD)
    lims.check_version()

    with EppLogger(log_file=args.log, lims=lims, prepend=True) as epp_logger:
        main(lims, args.pid, epp_logger)

<|endoftext|>


<commit_before># Copyright 2009 10gen, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""Tools for dealing with Mongo's BSON data representation.

Generally not needed to be used by application developers."""

import types
import struct
import random
import re
import datetime
import calendar
import logging

from binary import Binary, is_binary
from objectid import ObjectId
from dbref import DBRef
from son import SON
from errors import InvalidBSON, InvalidDocument, UnsupportedTag

_logger = logging.getLogger("pymongo.bson")
# _logger.setLevel(logging.DEBUG)
# _logger.addHandler(logging.StreamHandler())

def _get_int(data):
    try:
        value = struct.unpack("<i", data[:4])[0]
    except struct.error:
        raise InvalidBSON()

    return (value, data[4:])

def _get_c_string(data):
    try:
        end = data.index("\x00")
    except ValueError:
        raise InvalidBSON()

    return (unicode(data[:end], "utf-8"), data[end + 1:])

def _make_c_string(string):
    string = string.encode("utf-8")
    try:
        string.index("\x00")
        raise InvalidDocument("cannot encode string %r: contains '\\x00'" % string)
    except InvalidDocument:
        raise
    except ValueError:
        pass
    return string + "\x00"

def _validate_number(data):
    assert len(data) >= 8
    return data[8:]

def _validate_string(data):
    (length, data) = _get_int(data)
    assert len(data) >= length
    assert data[length - 1] == "\x00"
    return data[length:]

def _validate_object(data):
    return _validate_document(data, None)

_valid_array_name = re.compile("^\d+$")
def _validate_array(data):
    return _validate_document(data, _valid_array_name)

def _validate_binary(data):
    (length, data) = _get_int(data)
    # + 1 for the subtype byte
    assert len(data) >= length + 1
    return data[length + 1:]

def _validate_undefined(data):
    return data

_OID_SIZE = 12
def _validate_oid(data):
    assert len(data) >= _OID_SIZE
    return data[_OID_SIZE:]

def _validate_boolean(data):
    assert len(data) >= 1
    return data[1:]

_DATE_SIZE = 8
def _validate_date(data):
    assert len(data) >= _DATE_SIZE
    return data[_DATE_SIZE:]

_validate_null = _validate_undefined

def _validate_regex(data):
    (regex, data) = _get_c_string(data)
    (options, data) = _get_c_string(data)
    return data

def _validate_ref(data):
    data = _validate_string(data)
    return _validate_oid(data)

_validate_code = _validate_string

# still not sure what is actually stored here, but i know how big it is...
def _validate_code_w_scope(data):
    (length, data) = _get_int(data)
    assert len(data) >= length + 1
    return data[length + 1:]

_validate_symbol = _validate_string

def _validate_number_int(data):
    assert len(data) >= 4
    return data[4:]

_element_validator = {
    "\x01": _validate_number,
    "\x02": _validate_string,
    "\x03": _validate_object,
    "\x04": _validate_array,
    "\x05": _validate_binary,
    "\x06": _validate_undefined,
    "\x07": _validate_oid,
    "\x08": _validate_boolean,
    "\x09": _validate_date,
    "\x0A": _validate_null,
    "\x0B": _validate_regex,
    "\x0C": _validate_ref,
    "\x0D": _validate_code,
    "\x0E": _validate_symbol,
    "\x0F": _validate_code_w_scope,
    "\x10": _validate_number_int,
}

def _validate_element_data(type, data):
    try:
        return _element_validator[type](data)
    except KeyError:
        raise InvalidBSON("unrecognized type: %s" % type)

def _validate_element(data, valid_name):
    element_type = data[0]
    (element_name, data) = _get_c_string(data[1:])
    if valid_name:
        assert valid_name.match(element_name), "%r doesn't match %s" % (element_name, valid_name.pattern)
    return _validate_element_data(element_type, data)

def _validate_elements(data, valid_name):
    while data:
        data = _validate_element(data, valid_name)

def _validate_document(data, valid_name=None):
    try:
        obj_size = struct.unpack("<i", data[:4])[0]
    except struct.error:
        raise InvalidBSON()

    assert obj_size <= len(data)
    obj = data[4:obj_size]
    assert len(obj)

    eoo = obj[-1]
    assert eoo == "\x00"

    elements = obj[:-1]
    _validate_elements(elements, valid_name)

    return data[obj_size:]

def _get_number(data):
    return (struct.unpack("<d", data[:8])[0], data[8:])

def _get_string(data):
    return _get_c_string(data[4:])

def _get_object(data):
    return _document_to_dict(data)

def _get_array(data):
    (obj, data) = _get_object(data)
    result = []
    i = 0
    while True:
        try:
            result.append(obj[str(i)])
            i += 1
        except KeyError:
            break
    return (result, data)

def _get_binary(data):
    (length, data) = _get_int(data)
    subtype = data[0]
    data = data[1:]
    if subtype != "\x02":
        raise InvalidBSON("binary subtype %r is unsupported" % subtype)
    (length2, data) = _get_int(data)
    if length2 != length - 4:
        raise InvalidBSON("invalid binary - lengths don't match!")
    return (Binary(data[:length2]), data[length2:])

def _get_oid(data):
    oid = _shuffle_oid(data[:12])
    return (ObjectId(oid), data[12:])

def _get_boolean(data):
    return (data[0] == "\x01", data[1:])

def _get_date(data):
    seconds = float(struct.unpack("<q", data[:8])[0]) / 1000.0
    return (datetime.datetime.utcfromtimestamp(seconds), data[8:])

def _get_null(data):
    return (None, data)

def _get_regex(data):
    (pattern, data) = _get_c_string(data)
    (bson_flags, data) = _get_c_string(data)
    flags = 0
    if "i" in bson_flags:
        flags |= re.IGNORECASE
    if "l" in bson_flags:
        flags |= re.LOCALE
    if "m" in bson_flags:
        flags |= re.MULTILINE
    if "s" in bson_flags:
        flags |= re.DOTALL
    if "u" in bson_flags:
        flags |= re.UNICODE
    if "x" in bson_flags:
        flags |= re.VERBOSE
    return (re.compile(pattern, flags), data)

def _get_ref(data):
    (collection, data) = _get_c_string(data[4:])
    (oid, data) = _get_oid(data)
    return (DBRef(collection, oid), data)

_element_getter = {
    "\x01": _get_number,
    "\x02": _get_string,
    "\x03": _get_object,
    "\x04": _get_array,
    "\x05": _get_binary,
    "\x06": _get_null, # undefined
    "\x07": _get_oid,
    "\x08": _get_boolean,
    "\x09": _get_date,
    "\x0A": _get_null,
    "\x0B": _get_regex,
    "\x0C": _get_ref,
    "\x0D": _get_string, # code
    "\x0E": _get_string, # symbol
#    "\x0F": _get_code_w_scope
    "\x10": _get_int, # number_int
}

def _element_to_dict(data):
    element_type = data[0]
    (element_name, data) = _get_c_string(data[1:])
    (value, data) = _element_getter[element_type](data)
    return (element_name, value, data)

def _elements_to_dict(data):
    result = SON()
    while data:
        (key, value, data) = _element_to_dict(data)
        result[key] = value
    return result

def _document_to_dict(data):
    obj_size = struct.unpack("<i", data[:4])[0]
    elements = data[4:obj_size - 1]
    return (_elements_to_dict(elements), data[obj_size:])

def _int_to_bson(int):
    return struct.pack("<i", int)

def _int_64_to_bson(int):
    return struct.pack("<q", int)

def _shuffle_oid(data):
    return data[7::-1] + data[:7:-1]

_RE_TYPE = type(_valid_array_name)
def _value_to_bson(value):
    if isinstance(value, types.FloatType):
        return ("\x01", struct.pack("<d", value))
    if is_binary(value):
        length = len(value)
        return ("\x05",
                _int_to_bson(length + 4) + "\x02" + _int_to_bson(length) + value)
    if isinstance(value, types.StringTypes):
        cstring = _make_c_string(unicode(value))
        length = _int_to_bson(len(cstring))
        return ("\x02", length + cstring)
    if isinstance(value, (types.DictType, SON)):
        return ("\x03", BSON.from_dict(value))
    if isinstance(value, types.ListType):
        as_dict = SON(zip([str(i) for i in range(len(value))], value))
        return ("\x04", BSON.from_dict(as_dict))
    if isinstance(value, ObjectId):
        return ("\x07", _shuffle_oid(str(value)))
    if isinstance(value, types.BooleanType):
        if value:
            return ("\x08", "\x01")
        return ("\x08", "\x00")
    if isinstance(value, datetime.datetime):
        millis = int(calendar.timegm(value.timetuple()) * 1000 + value.microsecond / 1000)
        return ("\x09", _int_64_to_bson(millis))
    if isinstance(value, types.NoneType):
        return ("\x0A", "")
    if isinstance(value, _RE_TYPE):
        pattern = value.pattern
        flags = ""
        if value.flags & re.IGNORECASE:
            flags += "i"
        if value.flags & re.LOCALE:
            flags += "l"
        if value.flags & re.MULTILINE:
            flags += "m"
        if value.flags & re.DOTALL:
            flags += "s"
        if value.flags & re.UNICODE:
            flags += "u"
        if value.flags & re.VERBOSE:
            flags += "x"
        return ("\x0B", _make_c_string(pattern) + _make_c_string(flags))
    if isinstance(value, DBRef):
        ns = _make_c_string(value.collection())
        return ("\x0C", _int_to_bson(len(ns)) + ns + _shuffle_oid(str(value.id())))
    if isinstance(value, types.IntType):
        return ("\x10", _int_to_bson(value))
    raise InvalidDocument("cannot convert value of type %s to bson" % type(value))

def _where_value_to_bson(value):
    if not isinstance(value, types.StringTypes):
        raise TypeError("$where value must be an instance of (str, unicode)")
    cstring = _make_c_string(value)
    length = _int_to_bson(len(cstring))
    return ("\x0D", length + cstring)

def _element_to_bson(key, value):
    if not isinstance(key, types.StringTypes):
        raise TypeError("all keys must be instances of (str, unicode)")

    element_name = _make_c_string(key)
    if key == "$where":
        (element_type, element_data) = _where_value_to_bson(value)
    else:
        (element_type, element_data) = _value_to_bson(value)

    return element_type + element_name + element_data

def is_valid(bson):
    """Validate that the given string represents valid BSON data.

    Raises TypeError if the data is not an instance of a subclass of str.
    Returns True if the data represents a valid BSON object, False otherwise.

    :Parameters:
      - `bson`: the data to be validated
    """
    if not isinstance(bson, types.StringType):
        raise TypeError("BSON data must be an instance of a subclass of str")

    try:
        remainder = _validate_document(bson)
        return remainder == ""
    except (AssertionError, InvalidBSON):
        return False

def to_dicts(data):
    """Convert binary data to sequence of SON objects.

    Data must be concatenated strings of valid BSON data.
    """
    dicts = []
    while len(data):
        (son, data) = _document_to_dict(data)
        dicts.append(son)
    return dicts

class BSON(str):
    """BSON data.

    Represents binary data storable in and retrievable from Mongo.
    """
    def __new__(cls, bson):
        """Initialize a new BSON object with some data.

        Raises TypeError if `bson` is not an instance of str.

        :Parameters:
          - `bson`: the initial data
        """
        return str.__new__(cls, bson)

    @classmethod
    def from_dict(cls, dict):
        """Create a new BSON object from a python mapping type (like dict).

        Raises TypeError if the argument is not a mapping type, or contains keys
        that are not instance of (str, unicode). Raises InvalidDocument if the
        dictionary cannot be converted to BSON.

        :Parameters:
          - `dict`: mapping type representing a Mongo document
        """
        try:
            elements = "".join([_element_to_bson(key, value) for (key, value) in dict.iteritems()])
        except AttributeError:
            raise TypeError("argument to from_dict must be a mapping type")

        length = len(elements) + 5
        bson = _int_to_bson(length) + elements + "\x00"
        return cls(bson)

    def to_dict(self):
        """Get the dictionary representation of this data."""
        (son, _) = _document_to_dict(self)
        return son
<commit_msg>optimizations<commit_after># Copyright 2009 10gen, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""Tools for dealing with Mongo's BSON data representation.

Generally not needed to be used by application developers."""

import types
import struct
import random
import re
import datetime
import calendar
import logging

from binary import Binary
from objectid import ObjectId
from dbref import DBRef
from son import SON
from errors import InvalidBSON, InvalidDocument, UnsupportedTag

_logger = logging.getLogger("pymongo.bson")
# _logger.setLevel(logging.DEBUG)
# _logger.addHandler(logging.StreamHandler())

def _get_int(data):
    try:
        value = struct.unpack("<i", data[:4])[0]
    except struct.error:
        raise InvalidBSON()

    return (value, data[4:])

def _get_c_string(data):
    try:
        end = data.index("\x00")
    except ValueError:
        raise InvalidBSON()

    return (unicode(data[:end], "utf-8"), data[end + 1:])

def _make_c_string(string):
    return string.encode("utf-8") + "\x00"

def _validate_number(data):
    assert len(data) >= 8
    return data[8:]

def _validate_string(data):
    (length, data) = _get_int(data)
    assert len(data) >= length
    assert data[length - 1] == "\x00"
    return data[length:]

def _validate_object(data):
    return _validate_document(data, None)

_valid_array_name = re.compile("^\d+$")
def _validate_array(data):
    return _validate_document(data, _valid_array_name)

def _validate_binary(data):
    (length, data) = _get_int(data)
    # + 1 for the subtype byte
    assert len(data) >= length + 1
    return data[length + 1:]

def _validate_undefined(data):
    return data

_OID_SIZE = 12
def _validate_oid(data):
    assert len(data) >= _OID_SIZE
    return data[_OID_SIZE:]

def _validate_boolean(data):
    assert len(data) >= 1
    return data[1:]

_DATE_SIZE = 8
def _validate_date(data):
    assert len(data) >= _DATE_SIZE
    return data[_DATE_SIZE:]

_validate_null = _validate_undefined

def _validate_regex(data):
    (regex, data) = _get_c_string(data)
    (options, data) = _get_c_string(data)
    return data

def _validate_ref(data):
    data = _validate_string(data)
    return _validate_oid(data)

_validate_code = _validate_string

# still not sure what is actually stored here, but i know how big it is...
def _validate_code_w_scope(data):
    (length, data) = _get_int(data)
    assert len(data) >= length + 1
    return data[length + 1:]

_validate_symbol = _validate_string

def _validate_number_int(data):
    assert len(data) >= 4
    return data[4:]

_element_validator = {
    "\x01": _validate_number,
    "\x02": _validate_string,
    "\x03": _validate_object,
    "\x04": _validate_array,
    "\x05": _validate_binary,
    "\x06": _validate_undefined,
    "\x07": _validate_oid,
    "\x08": _validate_boolean,
    "\x09": _validate_date,
    "\x0A": _validate_null,
    "\x0B": _validate_regex,
    "\x0C": _validate_ref,
    "\x0D": _validate_code,
    "\x0E": _validate_symbol,
    "\x0F": _validate_code_w_scope,
    "\x10": _validate_number_int,
}

def _validate_element_data(type, data):
    try:
        return _element_validator[type](data)
    except KeyError:
        raise InvalidBSON("unrecognized type: %s" % type)

def _validate_element(data, valid_name):
    element_type = data[0]
    (element_name, data) = _get_c_string(data[1:])
    if valid_name:
        assert valid_name.match(element_name), "%r doesn't match %s" % (element_name, valid_name.pattern)
    return _validate_element_data(element_type, data)

def _validate_elements(data, valid_name):
    while data:
        data = _validate_element(data, valid_name)

def _validate_document(data, valid_name=None):
    try:
        obj_size = struct.unpack("<i", data[:4])[0]
    except struct.error:
        raise InvalidBSON()

    assert obj_size <= len(data)
    obj = data[4:obj_size]
    assert len(obj)

    eoo = obj[-1]
    assert eoo == "\x00"

    elements = obj[:-1]
    _validate_elements(elements, valid_name)

    return data[obj_size:]

def _get_number(data):
    return (struct.unpack("<d", data[:8])[0], data[8:])

def _get_string(data):
    return _get_c_string(data[4:])

def _get_object(data):
    return _document_to_dict(data)

def _get_array(data):
    (obj, data) = _get_object(data)
    result = []
    i = 0
    while True:
        try:
            result.append(obj[str(i)])
            i += 1
        except KeyError:
            break
    return (result, data)

def _get_binary(data):
    (length, data) = _get_int(data)
    subtype = data[0]
    data = data[1:]
    if subtype != "\x02":
        raise InvalidBSON("binary subtype %r is unsupported" % subtype)
    (length2, data) = _get_int(data)
    if length2 != length - 4:
        raise InvalidBSON("invalid binary - lengths don't match!")
    return (Binary(data[:length2]), data[length2:])

def _get_oid(data):
    oid = _shuffle_oid(data[:12])
    return (ObjectId(oid), data[12:])

def _get_boolean(data):
    return (data[0] == "\x01", data[1:])

def _get_date(data):
    seconds = float(struct.unpack("<q", data[:8])[0]) / 1000.0
    return (datetime.datetime.utcfromtimestamp(seconds), data[8:])

def _get_null(data):
    return (None, data)

def _get_regex(data):
    (pattern, data) = _get_c_string(data)
    (bson_flags, data) = _get_c_string(data)
    flags = 0
    if "i" in bson_flags:
        flags |= re.IGNORECASE
    if "l" in bson_flags:
        flags |= re.LOCALE
    if "m" in bson_flags:
        flags |= re.MULTILINE
    if "s" in bson_flags:
        flags |= re.DOTALL
    if "u" in bson_flags:
        flags |= re.UNICODE
    if "x" in bson_flags:
        flags |= re.VERBOSE
    return (re.compile(pattern, flags), data)

def _get_ref(data):
    (collection, data) = _get_c_string(data[4:])
    (oid, data) = _get_oid(data)
    return (DBRef(collection, oid), data)

_element_getter = {
    "\x01": _get_number,
    "\x02": _get_string,
    "\x03": _get_object,
    "\x04": _get_array,
    "\x05": _get_binary,
    "\x06": _get_null, # undefined
    "\x07": _get_oid,
    "\x08": _get_boolean,
    "\x09": _get_date,
    "\x0A": _get_null,
    "\x0B": _get_regex,
    "\x0C": _get_ref,
    "\x0D": _get_string, # code
    "\x0E": _get_string, # symbol
#    "\x0F": _get_code_w_scope
    "\x10": _get_int, # number_int
}

def _element_to_dict(data):
    element_type = data[0]
    (element_name, data) = _get_c_string(data[1:])
    (value, data) = _element_getter[element_type](data)
    return (element_name, value, data)

def _elements_to_dict(data):
    result = SON()
    while data:
        (key, value, data) = _element_to_dict(data)
        result[key] = value
    return result

def _document_to_dict(data):
    obj_size = struct.unpack("<i", data[:4])[0]
    elements = data[4:obj_size - 1]
    return (_elements_to_dict(elements), data[obj_size:])

def _shuffle_oid(data):
    return data[7::-1] + data[:7:-1]

_RE_TYPE = type(_valid_array_name)
def _value_to_bson(value):
    if isinstance(value, float):
        return ("\x01", struct.pack("<d", value))
    if isinstance(value, Binary):
        length = len(value)
        return ("\x05",
                struct.pack("<i", length + 4) + "\x02" + struct.pack("<i", length) + value)
    if isinstance(value, basestring):
        cstring = _make_c_string(value)
        length = struct.pack("<i", len(cstring))
        return ("\x02", length + cstring)
    if isinstance(value, (dict, SON)):
        return ("\x03", BSON.from_dict(value))
    if isinstance(value, list):
        as_dict = SON(zip([str(i) for i in range(len(value))], value))
        return ("\x04", BSON.from_dict(as_dict))
    if isinstance(value, ObjectId):
        return ("\x07", _shuffle_oid(str(value)))
    if isinstance(value, bool):
        if value:
            return ("\x08", "\x01")
        return ("\x08", "\x00")
    if isinstance(value, int):
        return ("\x10", struct.pack("<i", value))
    if isinstance(value, datetime.datetime):
        millis = int(calendar.timegm(value.timetuple()) * 1000 + value.microsecond / 1000)
        return ("\x09", struct.pack("<q", millis))
    if value is None:
        return ("\x0A", "")
    if isinstance(value, _RE_TYPE):
        pattern = value.pattern
        flags = ""
        if value.flags & re.IGNORECASE:
            flags += "i"
        if value.flags & re.LOCALE:
            flags += "l"
        if value.flags & re.MULTILINE:
            flags += "m"
        if value.flags & re.DOTALL:
            flags += "s"
        if value.flags & re.UNICODE:
            flags += "u"
        if value.flags & re.VERBOSE:
            flags += "x"
        return ("\x0B", _make_c_string(pattern) + _make_c_string(flags))
    if isinstance(value, DBRef):
        ns = _make_c_string(value.collection())
        return ("\x0C", struct.pack("<i", len(ns)) + ns + _shuffle_oid(str(value.id())))
    raise InvalidDocument("cannot convert value of type %s to bson" % type(value))

def _where_value_to_bson(value):
    if not isinstance(value, types.StringTypes):
        raise TypeError("$where value must be an instance of (str, unicode)")
    cstring = _make_c_string(value)
    length = struct.pack("<i", len(cstring))
    return ("\x0D", length + cstring)

def _element_to_bson(key, value):
    if not isinstance(key, types.StringTypes):
        raise TypeError("all keys must be instances of (str, unicode)")

    element_name = _make_c_string(key)
    if key == "$where":
        (element_type, element_data) = _where_value_to_bson(value)
    else:
        (element_type, element_data) = _value_to_bson(value)

    return element_type + element_name + element_data

def is_valid(bson):
    """Validate that the given string represents valid BSON data.

    Raises TypeError if the data is not an instance of a subclass of str.
    Returns True if the data represents a valid BSON object, False otherwise.

    :Parameters:
      - `bson`: the data to be validated
    """
    if not isinstance(bson, types.StringType):
        raise TypeError("BSON data must be an instance of a subclass of str")

    try:
        remainder = _validate_document(bson)
        return remainder == ""
    except (AssertionError, InvalidBSON):
        return False

def to_dicts(data):
    """Convert binary data to sequence of SON objects.

    Data must be concatenated strings of valid BSON data.
    """
    dicts = []
    while len(data):
        (son, data) = _document_to_dict(data)
        dicts.append(son)
    return dicts

class BSON(str):
    """BSON data.

    Represents binary data storable in and retrievable from Mongo.
    """
    def __new__(cls, bson):
        """Initialize a new BSON object with some data.

        Raises TypeError if `bson` is not an instance of str.

        :Parameters:
          - `bson`: the initial data
        """
        return str.__new__(cls, bson)

    @classmethod
    def from_dict(cls, dict):
        """Create a new BSON object from a python mapping type (like dict).

        Raises TypeError if the argument is not a mapping type, or contains keys
        that are not instance of (str, unicode). Raises InvalidDocument if the
        dictionary cannot be converted to BSON.

        :Parameters:
          - `dict`: mapping type representing a Mongo document
        """
        try:
            elements = "".join([_element_to_bson(key, value) for (key, value) in dict.iteritems()])
        except AttributeError:
            raise TypeError("argument to from_dict must be a mapping type")

        length = len(elements) + 5
        bson = struct.pack("<i", length) + elements + "\x00"
        return cls(bson)

    def to_dict(self):
        """Get the dictionary representation of this data."""
        (son, _) = _document_to_dict(self)
        return son
<|endoftext|>


<commit_before>from .base import Base, Property

class Distribution(Base):
    api_endpoint = '/distributions'
    properties = {
        'id': Property(identifier=True),
        'label': Property(filterable=True),
        'minimum_image_size': Property(filterable=True),
        'recommended': Property(filterable=True),
        'vendor': Property(filterable=True),
        'experimental': Property(filterable=True),
        'created': Property(is_datetime=True),
        'x64': Property(),
    }
<commit_msg>Fixes Distribution objects not self-populating<commit_after>from .base import Base, Property

class Distribution(Base):
    api_endpoint = '/distributions/{id}'
    properties = {
        'id': Property(identifier=True),
        'label': Property(filterable=True),
        'minimum_image_size': Property(filterable=True),
        'recommended': Property(filterable=True),
        'vendor': Property(filterable=True),
        'experimental': Property(filterable=True),
        'created': Property(is_datetime=True),
        'x64': Property(),
    }
<|endoftext|>


<commit_before>#!/usr/bin/env python
DESC="""EPP used to create csv files for the nanoprep robot"""
import logging
import os

from argparse import ArgumentParser
from genologics.lims import Lims
from genologics.config import BASEURI,USERNAME,PASSWORD
from genologics.entities import *
from genologics.epp import attach_file

def read_log(lims, pid, logfile):
    logger=setupLog(logfile)
    pro=Process(lims, id=pid)
    f=None
    for out in pro.all_outputs():
        if out.type == "ResultFile" and out.name == "NeoPrep Output Log File":
            fid=out.files[0].id
            f=lims.get_file_contents(id=fid)
            logger.info("Found the machine log file")

    if f:
        data={}
        read=False
        #default values
        sample_idx=2
        conc_idx=6
        norm_idx=7
        stat_idx=8
        logger.info("Reading the file")
        for line in f.split('\n') :
            if not line.rstrip():
                read=False
            if read:
                if "Start Well" in line:
                    #Header row
                    elements=line.split('\t')
                    for idx, el in enumerate(elements):
                        if el == "Name":
                            sample_idx=idx
                        elif el == "Quant":
                            conc_idx=idx
                        elif el == "Norm":
                            norm_idx=idx
                        elif el == "Status":
                            stat_idx=idx
                else:
                    elements=line.split('\t')
                    #data rows
                    data[elements[sample_idx]]={}
                    data[elements[sample_idx]]['conc']=elements[conc_idx]
                    data[elements[sample_idx]]['norm']=elements[norm_idx]
                    data[elements[sample_idx]]['stat']=elements[stat_idx]

            if "[Sample Information]" in line:
                read=True
        logger.info("obtained data for samples {0}".format(data.keys()))

    for inp in pro.all_inputs():
        if inp.name in data:
            inp.udf['Molar Conc. (nM)']=data[inp.name]['conc']
            inp.udf['Normalized conc. (nM)']=data[inp.name]['norm']
            inp.udf['NeoPrep Machine QC']=data[inp.name]['stat']
            inp.put()
            logger.info("updated sample {0}".format(inp.name))

    for out in pro.all_outputs():
        if out.name=="EPP Log":
            attach_file(os.path.join(os.getcwd(), logfile), out)

def setupLog(logfile):
        mainlog = logging.getLogger(__name__)
        mainlog.setLevel(level=logging.INFO)
        mfh = logging.FileHandler(logfile)
        mft = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
        mfh.setFormatter(mft)
        mainlog.addHandler(mfh)
        return mainlog

if __name__ == "__main__":
    parser = ArgumentParser(description=DESC)
    parser.add_argument('--pid',
                        help='Lims id for current Process')
    parser.add_argument('--log', default="read_neoprep_log.log",
                        help='logfile for this epp')
    args = parser.parse_args()

    lims = Lims(BASEURI, USERNAME, PASSWORD)
    lims.check_version()
    read_log(lims, args.pid, args.log)
<commit_msg>changed the typing<commit_after>#!/usr/bin/env python
DESC="""EPP used to create csv files for the nanoprep robot"""
import logging
import os

from argparse import ArgumentParser
from genologics.lims import Lims
from genologics.config import BASEURI,USERNAME,PASSWORD
from genologics.entities import *
from genologics.epp import attach_file

def read_log(lims, pid, logfile):
    logger=setupLog(logfile)
    pro=Process(lims, id=pid)
    f=None
    for out in pro.all_outputs():
        if out.type == "ResultFile" and out.name == "NeoPrep Output Log File":
            fid=out.files[0].id
            f=lims.get_file_contents(id=fid)
            logger.info("Found the machine log file")

    if f:
        data={}
        read=False
        #default values
        sample_idx=2
        conc_idx=6
        norm_idx=7
        stat_idx=8
        logger.info("Reading the file")
        for line in f.split('\n') :
            if not line.rstrip():
                read=False
            if read:
                if "Start Well" in line:
                    #Header row
                    elements=line.split('\t')
                    for idx, el in enumerate(elements):
                        if el == "Name":
                            sample_idx=idx
                        elif el == "Quant":
                            conc_idx=idx
                        elif el == "Norm":
                            norm_idx=idx
                        elif el == "Status":
                            stat_idx=idx
                else:
                    elements=line.split('\t')
                    #data rows
                    data[elements[sample_idx]]={}
                    data[elements[sample_idx]]['conc']=elements[conc_idx]
                    data[elements[sample_idx]]['norm']=elements[norm_idx]
                    data[elements[sample_idx]]['stat']=elements[stat_idx]

            if "[Sample Information]" in line:
                read=True
        logger.info("obtained data for samples {0}".format(data.keys()))

    for inp in pro.all_inputs():
        if inp.name in data:
            inp.udf['Molar Conc. (nM)']=float(data[inp.name]['conc'])
            inp.udf['Normalized conc. (nM)']=float(data[inp.name]['norm'])
            inp.udf['NeoPrep Machine QC']=data[inp.name]['stat']
            inp.put()
            logger.info("updated sample {0}".format(inp.name))

    for out in pro.all_outputs():
        if out.name=="EPP Log":
            attach_file(os.path.join(os.getcwd(), logfile), out)

def setupLog(logfile):
        mainlog = logging.getLogger(__name__)
        mainlog.setLevel(level=logging.INFO)
        mfh = logging.FileHandler(logfile)
        mft = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
        mfh.setFormatter(mft)
        mainlog.addHandler(mfh)
        return mainlog

if __name__ == "__main__":
    parser = ArgumentParser(description=DESC)
    parser.add_argument('--pid',
                        help='Lims id for current Process')
    parser.add_argument('--log', default="read_neoprep_log.log",
                        help='logfile for this epp')
    args = parser.parse_args()

    lims = Lims(BASEURI, USERNAME, PASSWORD)
    lims.check_version()
    read_log(lims, args.pid, args.log)
<|endoftext|>