<commit_before>from os import path

from django.core.paginator import Paginator, InvalidPage, EmptyPage
from django.core.urlresolvers import reverse
from django.shortcuts import render_to_response, render

from django.template import RequestContext
from django.views.decorators.csrf import ensure_csrf_cookie

import thumbnailer.thumbnailer as thumbnailer

from filemanager.models import fileobject, thumbobject, zippedobject

from post.models import Post
from post.forms import PostForm, createForm, defaulttag
from django import forms
##obviously ignoring csrf is a bad thing. Get this fixed.
from django.views.decorators.csrf import csrf_exempt, csrf_protect,requires_csrf_token
from django.core.context_processors import csrf

from django.http import HttpResponseRedirect, HttpResponse

def thumbnail_get(post, fileobject, *args, **kwargs):

    if not post.thumbnail:
        print("I cant find the thumbnail for " + str(post))
        # so we just get a new thumbnail for their post. #
        Post.select_thumbnail(post)
    thumbnail = thumbobject.objects.get_or_create(fileobject=post.thumbnail, filex = 128, filey = 128)[0]
    return thumbnail

def post(request, pk):
    print("pk is "+str(pk))
    post = Post.objects.filter(pk=pk).exclude(draft=True)[0:1].get()
    print("post is "+str(post))
    postfiles = fileobject.objects.filter(post=post)
    mainthumb = thumbobject.objects.get_or_create(fileobject=post.thumbnail, filex = 250, filey = 250)[0]
    images=[]
    for i in postfiles:
        fullpath=i.filename.url
        renderer=i.filetype
        thumbmodel=thumbobject.objects.get_or_create( fileobject = i, filex=64, filey=64 )[0]
        thumbnail=thumbmodel.filename.url
        images.append([thumbnail,fullpath,renderer])

    download=zippedobject.objects.get_or_create(post=post)[0]
    print("^^ download url is "+str(download.filename.url))
    c = RequestContext(request, dict(post=post,
				user=request.user,images=images,
				galleryname="base",
				mainthumb=mainthumb.filename.url,
                                downloadurl=download.filename.url))

    return render(request, "article.html", c)

def front(request):

    return render_to_response('list.html', dict(post=post, user=request.user,))

def list(request):
    """Main listing."""

###   get all the posts!   ###
    posts = Post.objects.exclude(draft=True).order_by("-created")

    listdata = []
    for post in posts:
        # if a post has no thumbnail. This happens when ignorant users delete thier pictures and navigate away without saving and seeing the form error. #
########if not post.thumbnail:
########    print("I cant find the thumbnail for " + str(post))
########    # so we just get a new thumbnail for their post. #
########    Post.select_thumbnail(post)
        thumbnail = thumbnail_get(post=post, fileobject=post.thumbnail, filex = 128, filey = 128)
        listdata += [[post, thumbnail]]
    print("listdata is "+str(listdata))

    paginator = Paginator(listdata, 8)

    try: page = int(request.GET.get("page", '1'))
    except ValueError: page = 1

    try:
        listdata = paginator.page(page)
    except (InvalidPage, EmptyPage):
        listdata = paginator.page(paginator.num_pages)
    print("listdata.object_list[?][0].title is "+str(listdata[0][0].title))
    print("listdata.object_list[?][1].filename is "+str(listdata[0][1].filename.url))
    return render_to_response("front.html", dict(listdata=listdata, user=request.user, active="home"))

from django.utils import simplejson

@csrf_exempt
@requires_csrf_token
def edit(request, pk):

##The form-----------------------------
    try:
        post=Post.objects.filter(pk=pk)[0:1].get()
    except:
        return HttpResponse(status=404)
    if request.method == 'POST':
        form = PostForm(request.POST, post)
        print("view's post.pk = "+str(post.pk))
        #Check to make sure the form is valid and the user matches the post author
        if form.is_valid() and str(post.author) == str(request.user):
            #save thr form
            post.body = form.cleaned_data["body"]
           #post.thumbnail = form.cleaned_data["thumbnail"]
            list_to_tags(form.cleaned_data["tags"], post.tags)
            post.save()
            return HttpResponseRedirect('/post/'+str(post.pk))
        else:
            if str(post.author) == str(request.user):
                return render_to_response('edit.html', dict(post=post, user=request.user, form=form, ))
            else:
                return HttpResponse(status=403)

#--------------------------
#Set up the actual view.

    elif str(post.author) == str(request.user):
        taglist = []
        for i in post.tags.names():
           taglist.append(i)
        taglist = ",".join(taglist)
        print ("tags= "+str(taglist))
        thumbnailstring = "/"+path.split(post.thumbnail.filename.url)[1]
        form = PostForm({'body': post.body, 'thumbnail': thumbnailstring, 'tags' : str(taglist)}, post)
        return render_to_response('edit.html', dict(post=post, user=request.user, form=form,))
        #return HttpResponse(response_data, mimetype="application/json")
    else:
        return HttpResponse(status=403)

@csrf_exempt
def create(request):
    try:
        post=Post.objects.filter(author=request.user).filter(draft=True)[0]
    except:
        post = Post()
        post.title = None
        post.draft=True
        post.author = request.user
        post.save()
##The form-----------------------------
    if request.method == 'POST':
        form = createForm(request.POST, post)
        form2 = defaulttag(request.POST)
        #Check to make sure the form is valid and the user matches the post author
        if form.is_valid() and form2.is_valid() and request.user.is_authenticated():
            #save thr form
            post.author = request.user
            post.title = form.cleaned_data["title"]
            post.body = form.cleaned_data["body"]
            post.author = request.user
           #post.thumbnail = form.cleaned_data["thumbnail"]
            post.draft=False
            post.save()
            list_to_tags(form.cleaned_data["tags"], post.tags)
            list_to_tags(form2.cleaned_data["categories"], post.tags, False)
            post.save()
            #add error if thumbnail is invalid
            return HttpResponseRedirect('/post/'+str(post.pk))
        else:
            return render_to_response('create.html', dict(user=request.user,  form=form, form2=form2,post=post))
#--------------------------
#Set up the actual view.
    elif request.user.is_authenticated():
        form = createForm("",post)
        form2 = defaulttag()

        return render_to_response('create.html', dict(user=request.user, form=form, form2=form2, post=post))
    else:
        return HttpResponse(status=403)

def tag(request,tag):
    posts = Post.objects.filter(tags__name__in=[tag]).order_by("-created")
    print("post.views.tag says posts are "+str(posts))
    paginator = Paginator(posts, 15)

    try: page = int(request.GET.get("page", '1'))
    except ValueError: page = 1

    try:
        posts = paginator.page(page)
    except (InvalidPage, EmptyPage):
        posts = paginator.page(paginator.num_pages)

    return render_to_response("list.html", dict(posts=posts, user=request.user))

def tagcloud(request):
    return render(request, "tagcloud.html")

def list_to_tags(list, tags, clear=True):
            if clear:
                tags.clear()
            for tag in list:
                tags.add(tag)
<commit_msg>Removed some useless debug output<commit_after>from os import path

from django.core.paginator import Paginator, InvalidPage, EmptyPage
from django.core.urlresolvers import reverse
from django.shortcuts import render_to_response, render

from django.template import RequestContext
from django.views.decorators.csrf import ensure_csrf_cookie

import thumbnailer.thumbnailer as thumbnailer

from filemanager.models import fileobject, thumbobject, zippedobject

from post.models import Post
from post.forms import PostForm, createForm, defaulttag
from django import forms
##obviously ignoring csrf is a bad thing. Get this fixed.
from django.views.decorators.csrf import csrf_exempt, csrf_protect,requires_csrf_token
from django.core.context_processors import csrf

from django.http import HttpResponseRedirect, HttpResponse

def thumbnail_get(post, fileobject, *args, **kwargs):

    if not post.thumbnail:
        print("I cant find the thumbnail for " + str(post))
        # so we just get a new thumbnail for their post. #
        Post.select_thumbnail(post)
    thumbnail = thumbobject.objects.get_or_create(fileobject=post.thumbnail, filex = 128, filey = 128)[0]
    return thumbnail

def post(request, pk):
    post = Post.objects.filter(pk=pk).exclude(draft=True)[0:1].get()
    postfiles = fileobject.objects.filter(post=post)
    mainthumb = thumbobject.objects.get_or_create(fileobject=post.thumbnail, filex = 250, filey = 250)[0]
    images=[]
    for i in postfiles:
        fullpath=i.filename.url
        renderer=i.filetype
        thumbmodel=thumbobject.objects.get_or_create( fileobject = i, filex=64, filey=64 )[0]
        thumbnail=thumbmodel.filename.url
        images.append([thumbnail,fullpath,renderer])

    download=zippedobject.objects.get_or_create(post=post)[0]
    print("^^ download url is "+str(download.filename.url))
    c = RequestContext(request, dict(post=post,
				user=request.user,images=images,
				galleryname="base",
				mainthumb=mainthumb.filename.url,
                                downloadurl=download.filename.url))

    return render(request, "article.html", c)

def front(request):

    return render_to_response('list.html', dict(post=post, user=request.user,))

def list(request):
    """Main listing."""

###   get all the posts!   ###
    posts = Post.objects.exclude(draft=True).order_by("-created")

    listdata = []
    for post in posts:
        # if a post has no thumbnail. This happens when ignorant users delete thier pictures and navigate away without saving and seeing the form error. #
########if not post.thumbnail:
########    print("I cant find the thumbnail for " + str(post))
########    # so we just get a new thumbnail for their post. #
########    Post.select_thumbnail(post)
        thumbnail = thumbnail_get(post=post, fileobject=post.thumbnail, filex = 128, filey = 128)
        listdata += [[post, thumbnail]]
    print("listdata is "+str(listdata))

    paginator = Paginator(listdata, 8)

    try: page = int(request.GET.get("page", '1'))
    except ValueError: page = 1

    try:
        listdata = paginator.page(page)
    except (InvalidPage, EmptyPage):
        listdata = paginator.page(paginator.num_pages)
    print("listdata.object_list[?][0].title is "+str(listdata[0][0].title))
    print("listdata.object_list[?][1].filename is "+str(listdata[0][1].filename.url))
    return render_to_response("front.html", dict(listdata=listdata, user=request.user, active="home"))

from django.utils import simplejson

@csrf_exempt
@requires_csrf_token
def edit(request, pk):

##The form-----------------------------
    try:
        post=Post.objects.filter(pk=pk)[0:1].get()
    except:
        return HttpResponse(status=404)
    if request.method == 'POST':
        form = PostForm(request.POST, post)
        print("view's post.pk = "+str(post.pk))
        #Check to make sure the form is valid and the user matches the post author
        if form.is_valid() and str(post.author) == str(request.user):
            #save thr form
            post.body = form.cleaned_data["body"]
           #post.thumbnail = form.cleaned_data["thumbnail"]
            list_to_tags(form.cleaned_data["tags"], post.tags)
            post.save()
            return HttpResponseRedirect('/post/'+str(post.pk))
        else:
            if str(post.author) == str(request.user):
                return render_to_response('edit.html', dict(post=post, user=request.user, form=form, ))
            else:
                return HttpResponse(status=403)

#--------------------------
#Set up the actual view.

    elif str(post.author) == str(request.user):
        taglist = []
        for i in post.tags.names():
           taglist.append(i)
        taglist = ",".join(taglist)
        print ("tags= "+str(taglist))
        thumbnailstring = "/"+path.split(post.thumbnail.filename.url)[1]
        form = PostForm({'body': post.body, 'thumbnail': thumbnailstring, 'tags' : str(taglist)}, post)
        return render_to_response('edit.html', dict(post=post, user=request.user, form=form,))
        #return HttpResponse(response_data, mimetype="application/json")
    else:
        return HttpResponse(status=403)

@csrf_exempt
def create(request):
    try:
        post=Post.objects.filter(author=request.user).filter(draft=True)[0]
    except:
        post = Post()
        post.title = None
        post.draft=True
        post.author = request.user
        post.save()
##The form-----------------------------
    if request.method == 'POST':
        form = createForm(request.POST, post)
        form2 = defaulttag(request.POST)
        #Check to make sure the form is valid and the user matches the post author
        if form.is_valid() and form2.is_valid() and request.user.is_authenticated():
            #save thr form
            post.author = request.user
            post.title = form.cleaned_data["title"]
            post.body = form.cleaned_data["body"]
            post.author = request.user
           #post.thumbnail = form.cleaned_data["thumbnail"]
            post.draft=False
            post.save()
            list_to_tags(form.cleaned_data["tags"], post.tags)
            list_to_tags(form2.cleaned_data["categories"], post.tags, False)
            post.save()
            #add error if thumbnail is invalid
            return HttpResponseRedirect('/post/'+str(post.pk))
        else:
            return render_to_response('create.html', dict(user=request.user,  form=form, form2=form2,post=post))
#--------------------------
#Set up the actual view.
    elif request.user.is_authenticated():
        form = createForm("",post)
        form2 = defaulttag()

        return render_to_response('create.html', dict(user=request.user, form=form, form2=form2, post=post))
    else:
        return HttpResponse(status=403)

def tag(request,tag):
    posts = Post.objects.filter(tags__name__in=[tag]).order_by("-created")
    print("post.views.tag says posts are "+str(posts))
    paginator = Paginator(posts, 15)

    try: page = int(request.GET.get("page", '1'))
    except ValueError: page = 1

    try:
        posts = paginator.page(page)
    except (InvalidPage, EmptyPage):
        posts = paginator.page(paginator.num_pages)

    return render_to_response("list.html", dict(posts=posts, user=request.user))

def tagcloud(request):
    return render(request, "tagcloud.html")

def list_to_tags(list, tags, clear=True):
            if clear:
                tags.clear()
            for tag in list:
                tags.add(tag)
<|endoftext|>


<commit_before>GLOBAL_NAMESPACE = 'global'

def parse_partial_toml(raw_text):
    items = {}
    current_section = GLOBAL_NAMESPACE

    for line in raw_text.splitlines():
        # Check (naively) what the line contains
        if len(line) > 0 and line.lstrip()[0] == '[':
            # Open a new section
            name = line.strip().strip("[]")
            current_section = name
            if current_section not in items:
                items[current_section] = {}

        elif line.find('=') >= 0:
            # We have an assignment line
            parts = line.split('=')
            assign = parts[0].strip()
            value = parts[1]

            parse_type = check_parse_type(value)
            if parse_type == 'array':
                value = parse_as_array(value)
            elif parse_type == 'string':
                value = parse_as_string(value)

            # If it's a global assignment, try to put it there, unless the space is already taken
            if current_section == GLOBAL_NAMESPACE and assign not in items:
                items[assign] = value
            elif current_section == GLOBAL_NAMESPACE:
                items[GLOBAL_NAMESPACE][assign] = value
            else:
                items[current_section][assign] = value

        else:
            # Something else, possibly a comment
            pass

    return items

def check_parse_type(raw):
    if raw.strip()[0] == '[':
        return 'array'
    else:
        return 'string'

def parse_as_string(raw):
    return raw.strip("\t\n\r \"'")

def parse_as_array(raw):
    items = []
    for item in raw.strip("[]\r\n\t ").split(','):
        items.append(parse_as_string(item))
    return items

# Now, do the thing
with open("sessions/0/session.toml") as conffile:
    config = parse_partial_toml(conffile.read())
    print(config)
    for chapterFilename in config["book"]["chapters"]:
        with open("sessions/0/" + chapterFilename) as chapterFile:
            pass
<commit_msg>Implemented basic static replacement of params in a given string.<commit_after>import re

GLOBAL_NAMESPACE = 'global'

def parse_partial_toml(raw_text):
    items = {}
    current_section = GLOBAL_NAMESPACE

    for line in raw_text.splitlines():
        # Check (naively) what the line contains
        if len(line) > 0 and line.lstrip()[0] == '[':
            # Open a new section
            name = line.strip().strip("[]")
            current_section = name
            if current_section not in items:
                items[current_section] = {}

        elif line.find('=') >= 0:
            # We have an assignment line
            parts = line.split('=')
            assign = parts[0].strip()
            value = parts[1]

            parse_type = check_parse_type(value)
            if parse_type == 'array':
                value = parse_as_array(value)
            elif parse_type == 'string':
                value = parse_as_string(value)

            # If it's a global assignment, try to put it there, unless the space is already taken
            if current_section == GLOBAL_NAMESPACE and assign not in items:
                items[assign] = value
            elif current_section == GLOBAL_NAMESPACE:
                items[GLOBAL_NAMESPACE][assign] = value
            else:
                items[current_section][assign] = value

        else:
            # Something else, possibly a comment
            pass

    return items

def check_parse_type(raw):
    if raw.strip()[0] == '[':
        return 'array'
    else:
        return 'string'

def parse_as_string(raw):
    return raw.strip("\t\n\r \"'")

def parse_as_array(raw):
    items = []
    for item in raw.strip("[]\r\n\t ").split(','):
        items.append(parse_as_string(item))
    return items

def apply_params(raw_text, params):
    text = raw_text

    # First, replace the static params
    replacements = {}
    pattern = re.compile('<%[^-+~].*%>')
    matches = pattern.findall(text)

    for match in matches:
        parts = match.strip().strip('<>%').split('.')
        if len(parts) == 1:
            key = parts[0]
            if key in config:
                replacements[match] = config[key]
            elif GLOBAL_NAMESPACE in config and key in config[GLOBAL_NAMESPACE]:
                replacements[match] = config[GLOBAL_NAMESPACE][key]
        elif len(parts) == 2:
            ns = parts[0]
            key = parts[1]
            if ns in config and key in config[ns]:
                replacements[match] = config[ns][key]
        else:
            # Nested namespaces not supported yet
            pass

    for old in replacements:
        text = text.replace(old, replacements[old])

    # Second, replace iterated params

    return text

# Now, do the thing
with open("sessions/0/session.toml") as conffile:
    config = parse_partial_toml(conffile.read())
    print(config)
    for chapterFilename in config["book"]["chapters"]:
        with open("sessions/0/" + chapterFilename) as chapterFile:
            output = apply_params(chapterFile.read(), config)
            print output
<|endoftext|>


<commit_before># Copyright 2014 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import logging
import os

from telemetry.core import util
from telemetry.testing import run_tests

def RunChromeOSTests(browser_type, tests_to_run):
  """ Run ChromeOS tests.
  Args:
    |browser_type|: string specifies which browser type to use.
    |tests_to_run|: a list of tuples (top_level_dir, unit_tests), whereas
      |top_level_dir| specifies the top level directory for running tests, and
      |unit_tests| is a list of string test names to run.
  """
  stream = _LoggingOutputStream()
  error_string = ''

  for (top_level_dir, unit_tests) in tests_to_run:
    logging.info('Running unit tests in %s with browser_type "%s".' %
                 (top_level_dir, browser_type))

    ret = _RunOneSetOfTests(browser_type, top_level_dir, unit_tests, stream)
    if ret:
      error_string += 'The unit tests of %s failed.\n' % top_level_dir
  return error_string

# TODO(nednguyen): Remove this API after cros team has migrated to use
# RunChromeOSTests.
def RunTestsForChromeOS(browser_type, unit_tests, perf_tests):
  tests_to_run = []
  chromium_src_dir = util.GetChromiumSrcDir()
  if unit_tests:
    tests_to_run.append(
      (os.path.join(chromium_src_dir, 'tools', 'telemetry'), unit_tests))
  if perf_tests:
    tests_to_run.append(
      (os.path.join(chromium_src_dir, 'tools', 'perf'), perf_tests))
  return RunChromeOSTests(browser_type, tests_to_run)

def _RunOneSetOfTests(browser_type, top_level_dir, tests, stream):
  args = ['--browser', browser_type,
          '--top-level-dir', top_level_dir,
          '--jobs', '1',
          '--disable-logging-config'] + tests
  return run_tests.RunTestsCommand.main(args, stream=stream)

class _LoggingOutputStream(object):

  def __init__(self):
    self._buffer = []

  def write(self, s):
    """Buffer a string write. Log it when we encounter a newline."""
    if '\n' in s:
      segments = s.split('\n')
      segments[0] = ''.join(self._buffer + [segments[0]])
      log_level = logging.getLogger().getEffectiveLevel()
      try:  # TODO(dtu): We need this because of crbug.com/394571
        logging.getLogger().setLevel(logging.INFO)
        for line in segments[:-1]:
          logging.info(line)
      finally:
        logging.getLogger().setLevel(log_level)
      self._buffer = [segments[-1]]
    else:
      self._buffer.append(s)

  def flush(self):  # pylint: disable=W0612
    pass
<commit_msg>Remove RunTestsForChromeOS.<commit_after># Copyright 2014 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import logging

from telemetry.testing import run_tests

def RunChromeOSTests(browser_type, tests_to_run):
  """ Run ChromeOS tests.
  Args:
    |browser_type|: string specifies which browser type to use.
    |tests_to_run|: a list of tuples (top_level_dir, unit_tests), whereas
      |top_level_dir| specifies the top level directory for running tests, and
      |unit_tests| is a list of string test names to run.
  """
  stream = _LoggingOutputStream()
  error_string = ''

  for (top_level_dir, unit_tests) in tests_to_run:
    logging.info('Running unit tests in %s with browser_type "%s".' %
                 (top_level_dir, browser_type))

    ret = _RunOneSetOfTests(browser_type, top_level_dir, unit_tests, stream)
    if ret:
      error_string += 'The unit tests of %s failed.\n' % top_level_dir
  return error_string

def _RunOneSetOfTests(browser_type, top_level_dir, tests, stream):
  args = ['--browser', browser_type,
          '--top-level-dir', top_level_dir,
          '--jobs', '1',
          '--disable-logging-config'] + tests
  return run_tests.RunTestsCommand.main(args, stream=stream)

class _LoggingOutputStream(object):

  def __init__(self):
    self._buffer = []

  def write(self, s):
    """Buffer a string write. Log it when we encounter a newline."""
    if '\n' in s:
      segments = s.split('\n')
      segments[0] = ''.join(self._buffer + [segments[0]])
      log_level = logging.getLogger().getEffectiveLevel()
      try:  # TODO(dtu): We need this because of crbug.com/394571
        logging.getLogger().setLevel(logging.INFO)
        for line in segments[:-1]:
          logging.info(line)
      finally:
        logging.getLogger().setLevel(log_level)
      self._buffer = [segments[-1]]
    else:
      self._buffer.append(s)

  def flush(self):  # pylint: disable=W0612
    pass
<|endoftext|>


<commit_before>from urllib.parse import urlparse

import scrapy

from feeds.loaders import FeedEntryItemLoader
from feeds.spiders import FeedsSpider
from feeds.utils import generate_feed_header

class RisKommunalSpider(FeedsSpider):
    name = "riskommunal"
    custom_settings = {"COOKIES_ENABLED": True}
    allowed_domains = []
    cookies = {"ris-cookie": "g7750"}

    _sites = []
    _titles = {}
    _subtitles = {}
    _links = {}
    _icons = {}

    def feed_headers(self):
        for site in self._sites:
            yield generate_feed_header(
                title=self._titles.get(site),
                subtitle=self._subtitles.get(site),
                link=self._links.get(site),
                icon=self._icons.get(site),
                path=site,
            )

    def start_requests(self):
        urls = self.settings.get("FEEDS_SPIDER_RISKOMMUNAL_URLS")
        if not urls:
            self.logger.error("Please specify url(s) in the config file!")
            return

        for url in urls.split():
            parsed = urlparse(url)
            site = parsed.netloc

            self._sites.append(site)
            self._allow_domain(site)
            self._links[site] = f"{parsed.scheme}://{parsed.netloc}"

            yield scrapy.Request(
                url, cookies=self.cookies, meta={"dont_cache": True, "site": site},
            )

    def parse(self, response):
        site = response.meta["site"]

        title = response.css("meta[property='og:title']::attr('content')").get()
        self._titles[site] = title
        self._subtitles[site] = f"Neuigkeiten aus {title}"

        icon = response.css("link[rel='icon']::attr('href')").get()
        if icon and icon.startswith("/"):
            icon = f"{self._links[site]}{icon}"
        self._icons[site] = icon

        for selector in response.css("div.newslist div[class*='float_left']"):
            updated = selector.css("p.float_right::text").get()
            if not updated:
                # Do not care about "archived news"
                continue

            url = selector.css("a::attr('href')").get()
            if not url:
                # Ignore articles without a link
                continue

            if url.startswith("/"):
                url = f"{self._links[site]}{url}"

            yield scrapy.Request(
                url,
                self.parse_article,
                cookies=self.cookies,
                meta={"site": site, "updated": updated},
            )

    def parse_article(self, response):
        site = response.meta["site"]
        il = FeedEntryItemLoader(
            response=response,
            timezone="Europe/Vienna",
            base_url=self._links[site],
            dayfirst=True,
            yearfirst=False,
            remove_elems=[
                "div.main-content h1:first-of-type",
                "p#ctl00_ctl00_ctl00_cph_col_a_cph_content_cph_content_detail_p_date",
                "div#main-content-header",
            ],
        )
        il.add_value("path", site)
        il.add_value("link", response.url)
        il.add_value("updated", response.meta["updated"])
        il.add_css("title", "div.main-content h1:first-of-type::text")
        il.add_css("content_html", "div.main-content")

        yield il.load_item()

    def _allow_domain(self, domain):
        self.allowed_domains.append(domain)
        for mw in self.crawler.engine.scraper.spidermw.middlewares:
            if isinstance(mw, scrapy.spidermiddlewares.offsite.OffsiteMiddleware):
                mw.spider_opened(self)
<commit_msg>riskommunal: add another cookie<commit_after>from urllib.parse import urlparse

import scrapy

from feeds.loaders import FeedEntryItemLoader
from feeds.spiders import FeedsSpider
from feeds.utils import generate_feed_header

class RisKommunalSpider(FeedsSpider):
    name = "riskommunal"
    custom_settings = {"COOKIES_ENABLED": True}
    allowed_domains = []
    cookies = {"ris-cookie": "g7750", "ris_cookie_setting": "g7750"}

    _sites = []
    _titles = {}
    _subtitles = {}
    _links = {}
    _icons = {}

    def feed_headers(self):
        for site in self._sites:
            yield generate_feed_header(
                title=self._titles.get(site),
                subtitle=self._subtitles.get(site),
                link=self._links.get(site),
                icon=self._icons.get(site),
                path=site,
            )

    def start_requests(self):
        urls = self.settings.get("FEEDS_SPIDER_RISKOMMUNAL_URLS")
        if not urls:
            self.logger.error("Please specify url(s) in the config file!")
            return

        for url in urls.split():
            parsed = urlparse(url)
            site = parsed.netloc

            self._sites.append(site)
            self._allow_domain(site)
            self._links[site] = f"{parsed.scheme}://{parsed.netloc}"

            yield scrapy.Request(
                url, cookies=self.cookies, meta={"dont_cache": True, "site": site},
            )

    def parse(self, response):
        site = response.meta["site"]

        title = response.css("meta[property='og:title']::attr('content')").get()
        self._titles[site] = title
        self._subtitles[site] = f"Neuigkeiten aus {title}"

        icon = response.css("link[rel='icon']::attr('href')").get()
        if icon and icon.startswith("/"):
            icon = f"{self._links[site]}{icon}"
        self._icons[site] = icon

        for selector in response.css("div.newslist div[class*='float_left']"):
            updated = selector.css("p.float_right::text").get()
            if not updated:
                # Do not care about "archived news"
                continue

            url = selector.css("a::attr('href')").get()
            if not url:
                # Ignore articles without a link
                continue

            if url.startswith("/"):
                url = f"{self._links[site]}{url}"

            yield scrapy.Request(
                url,
                self.parse_article,
                cookies=self.cookies,
                meta={"site": site, "updated": updated},
            )

    def parse_article(self, response):
        site = response.meta["site"]
        il = FeedEntryItemLoader(
            response=response,
            timezone="Europe/Vienna",
            base_url=self._links[site],
            dayfirst=True,
            yearfirst=False,
            remove_elems=[
                "div.main-content h1:first-of-type",
                "p#ctl00_ctl00_ctl00_cph_col_a_cph_content_cph_content_detail_p_date",
                "div#main-content-header",
            ],
        )
        il.add_value("path", site)
        il.add_value("link", response.url)
        il.add_value("updated", response.meta["updated"])
        il.add_css("title", "div.main-content h1:first-of-type::text")
        il.add_css("content_html", "div.main-content")

        yield il.load_item()

    def _allow_domain(self, domain):
        self.allowed_domains.append(domain)
        for mw in self.crawler.engine.scraper.spidermw.middlewares:
            if isinstance(mw, scrapy.spidermiddlewares.offsite.OffsiteMiddleware):
                mw.spider_opened(self)
<|endoftext|>


<commit_before>#
# -*- coding: utf-8 -*-
# Copyright 2019 Red Hat
# GNU General Public License v3.0+
# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
"""
The facts base class
this contains methods common to all facts subsets
"""
from ansible.module_utils.network.common.network import get_resource_connection
from ansible.module_utils.six import iteritems

class FactsBase(object):
    """
    The facts base class
    """
    def __init__(self, module):
        self._module = module
        self._warnings = []
        self._gather_subset = module.params.get('gather_subset')
        self._gather_network_resources = module.params.get('gather_network_resources')
        self._connection = get_resource_connection(module)

        self.ansible_facts = {'ansible_network_resources': {}}
        self.ansible_facts['ansible_net_gather_network_resources'] = list()
        self.ansible_facts['ansible_net_gather_subset'] = list()

        if not self._gather_subset:
            self._gather_subset = ['!config']
        if not self._gather_network_resources:
            self._gather_network_resources = ['all']

    def gen_runable(self, subsets, valid_subsets):
        """ Generate the runable subset

        :param module: The module instance
        :param subsets: The provided subsets
        :param valid_subsets: The valid subsets
        :rtype: list
        :returns: The runable subsets
        """
        runable_subsets = set()
        exclude_subsets = set()
        minimal_gather_subset = frozenset(['default'])

        for subset in subsets:
            if subset == 'all':
                runable_subsets.update(valid_subsets)
                continue
            if subset == 'min' and minimal_gather_subset:
                runable_subsets.update(minimal_gather_subset)
                continue
            if subset.startswith('!'):
                subset = subset[1:]
                if subset == 'min':
                    exclude_subsets.update(minimal_gather_subset)
                    continue
                if subset == 'all':
                    exclude_subsets.update(
                        valid_subsets - minimal_gather_subset)
                    continue
                exclude = True
            else:
                exclude = False

            if subset not in valid_subsets:
                self._module.fail_json(msg='Subset must be one of [%s], got %s' %
                                           (', '.join(sorted([item for item in valid_subsets])), subset))

            if exclude:
                exclude_subsets.add(subset)
            else:
                runable_subsets.add(subset)

        if not runable_subsets:
            runable_subsets.update(valid_subsets)
        runable_subsets.difference_update(exclude_subsets)
        return runable_subsets

    def get_network_resources_facts(self, net_res_choices, facts_resource_obj_map, resource_facts_type=None, data=None):
        """
        :param net_res_choices:
        :param fact_resource_subsets:
        :param data: previously collected configuration
        :return:
        """
        if net_res_choices:
            if 'all' in net_res_choices:
                net_res_choices.remove('all')

        if net_res_choices:
            if not resource_facts_type:
                resource_facts_type = self._gather_network_resources

            restorun_subsets = self.gen_runable(resource_facts_type, frozenset(net_res_choices))
            if restorun_subsets:
                self.ansible_facts['ansible_net_gather_network_resources'] = list(restorun_subsets)
                instances = list()
                for key in restorun_subsets:
                    fact_cls_obj = facts_resource_obj_map.get(key)
                    if fact_cls_obj:
                        instances.append(fact_cls_obj(self._module))
                    else:
                        self._warnings.extend(["network resource fact gathering for '%s' is not supported" % key])

                for inst in instances:
                    inst.populate_facts(self._connection, self.ansible_facts, data)

    def get_network_legacy_facts(self, fact_legacy_obj_map, legacy_facts_type=None):
        if not legacy_facts_type:
            legacy_facts_type = self._gather_subset

        runable_subsets = self.gen_runable(legacy_facts_type, frozenset(fact_legacy_obj_map.keys()))
        runable_subsets.add('default')
        if runable_subsets:
            facts = dict()
            self.ansible_facts['ansible_net_gather_subset'] = list(runable_subsets)

            instances = list()
            for key in runable_subsets:
                instances.append(fact_legacy_obj_map[key](self._module))

            for inst in instances:
                inst.populate()
                facts.update(inst.facts)
                self._warnings.extend(inst.warnings)

            for key, value in iteritems(facts):
                key = 'ansible_net_%s' % key
                self.ansible_facts[key] = value
<commit_msg>Change default behaviour for network resource facts (#58750)<commit_after>#
# -*- coding: utf-8 -*-
# Copyright 2019 Red Hat
# GNU General Public License v3.0+
# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
"""
The facts base class
this contains methods common to all facts subsets
"""
from ansible.module_utils.network.common.network import get_resource_connection
from ansible.module_utils.six import iteritems

class FactsBase(object):
    """
    The facts base class
    """
    def __init__(self, module):
        self._module = module
        self._warnings = []
        self._gather_subset = module.params.get('gather_subset')
        self._gather_network_resources = module.params.get('gather_network_resources')
        self._connection = get_resource_connection(module)

        self.ansible_facts = {'ansible_network_resources': {}}
        self.ansible_facts['ansible_net_gather_network_resources'] = list()
        self.ansible_facts['ansible_net_gather_subset'] = list()

        if not self._gather_subset:
            self._gather_subset = ['!config']
        if not self._gather_network_resources:
            self._gather_network_resources = ['!all']

    def gen_runable(self, subsets, valid_subsets):
        """ Generate the runable subset

        :param module: The module instance
        :param subsets: The provided subsets
        :param valid_subsets: The valid subsets
        :rtype: list
        :returns: The runable subsets
        """
        runable_subsets = set()
        exclude_subsets = set()
        minimal_gather_subset = frozenset(['default'])

        for subset in subsets:
            if subset == 'all':
                runable_subsets.update(valid_subsets)
                continue
            if subset == 'min' and minimal_gather_subset:
                runable_subsets.update(minimal_gather_subset)
                continue
            if subset.startswith('!'):
                subset = subset[1:]
                if subset == 'min':
                    exclude_subsets.update(minimal_gather_subset)
                    continue
                if subset == 'all':
                    exclude_subsets.update(
                        valid_subsets - minimal_gather_subset)
                    continue
                exclude = True
            else:
                exclude = False

            if subset not in valid_subsets:
                self._module.fail_json(msg='Subset must be one of [%s], got %s' %
                                           (', '.join(sorted([item for item in valid_subsets])), subset))

            if exclude:
                exclude_subsets.add(subset)
            else:
                runable_subsets.add(subset)

        if not runable_subsets:
            runable_subsets.update(valid_subsets)
        runable_subsets.difference_update(exclude_subsets)
        return runable_subsets

    def get_network_resources_facts(self, net_res_choices, facts_resource_obj_map, resource_facts_type=None, data=None):
        """
        :param net_res_choices:
        :param fact_resource_subsets:
        :param data: previously collected configuration
        :return:
        """
        if net_res_choices:
            if 'all' in net_res_choices:
                net_res_choices.remove('all')

        if net_res_choices:
            if not resource_facts_type:
                resource_facts_type = self._gather_network_resources

            restorun_subsets = self.gen_runable(resource_facts_type, frozenset(net_res_choices))
            if restorun_subsets:
                self.ansible_facts['ansible_net_gather_network_resources'] = list(restorun_subsets)
                instances = list()
                for key in restorun_subsets:
                    fact_cls_obj = facts_resource_obj_map.get(key)
                    if fact_cls_obj:
                        instances.append(fact_cls_obj(self._module))
                    else:
                        self._warnings.extend(["network resource fact gathering for '%s' is not supported" % key])

                for inst in instances:
                    inst.populate_facts(self._connection, self.ansible_facts, data)

    def get_network_legacy_facts(self, fact_legacy_obj_map, legacy_facts_type=None):
        if not legacy_facts_type:
            legacy_facts_type = self._gather_subset

        runable_subsets = self.gen_runable(legacy_facts_type, frozenset(fact_legacy_obj_map.keys()))
        runable_subsets.add('default')
        if runable_subsets:
            facts = dict()
            self.ansible_facts['ansible_net_gather_subset'] = list(runable_subsets)

            instances = list()
            for key in runable_subsets:
                instances.append(fact_legacy_obj_map[key](self._module))

            for inst in instances:
                inst.populate()
                facts.update(inst.facts)
                self._warnings.extend(inst.warnings)

            for key, value in iteritems(facts):
                key = 'ansible_net_%s' % key
                self.ansible_facts[key] = value
<|endoftext|>


<commit_before>"""Unit tests for contextlib.py, and other context managers."""

import sys
import os
import decimal
import tempfile
import unittest
import threading
from contextlib import *  # Tests __all__
from test import support

class ContextManagerTestCase(unittest.TestCase):

    def test_contextmanager_plain(self):
        state = []
        @contextmanager
        def woohoo():
            state.append(1)
            yield 42
            state.append(999)
        with woohoo() as x:
            self.assertEqual(state, [1])
            self.assertEqual(x, 42)
            state.append(x)
        self.assertEqual(state, [1, 42, 999])

    def test_contextmanager_finally(self):
        state = []
        @contextmanager
        def woohoo():
            state.append(1)
            try:
                yield 42
            finally:
                state.append(999)
        try:
            with woohoo() as x:
                self.assertEqual(state, [1])
                self.assertEqual(x, 42)
                state.append(x)
                raise ZeroDivisionError()
        except ZeroDivisionError:
            pass
        else:
            self.fail("Expected ZeroDivisionError")
        self.assertEqual(state, [1, 42, 999])

    def test_contextmanager_no_reraise(self):
        @contextmanager
        def whee():
            yield
        ctx = whee()
        ctx.__enter__()
        # Calling __exit__ should not result in an exception
        self.failIf(ctx.__exit__(TypeError, TypeError("foo"), None))

    def test_contextmanager_trap_yield_after_throw(self):
        @contextmanager
        def whoo():
            try:
                yield
            except:
                yield
        ctx = whoo()
        ctx.__enter__()
        self.assertRaises(
            RuntimeError, ctx.__exit__, TypeError, TypeError("foo"), None
        )

    def test_contextmanager_except(self):
        state = []
        @contextmanager
        def woohoo():
            state.append(1)
            try:
                yield 42
            except ZeroDivisionError as e:
                state.append(e.args[0])
                self.assertEqual(state, [1, 42, 999])
        with woohoo() as x:
            self.assertEqual(state, [1])
            self.assertEqual(x, 42)
            state.append(x)
            raise ZeroDivisionError(999)
        self.assertEqual(state, [1, 42, 999])

    def test_contextmanager_attribs(self):
        def attribs(**kw):
            def decorate(func):
                for k,v in kw.items():
                    setattr(func,k,v)
                return func
            return decorate
        @contextmanager
        @attribs(foo='bar')
        def baz(spam):
            """Whee!"""
        self.assertEqual(baz.__name__,'baz')
        self.assertEqual(baz.foo, 'bar')
        self.assertEqual(baz.__doc__, "Whee!")

class NestedTestCase(unittest.TestCase):

    # XXX This needs more work

    def test_nested(self):
        @contextmanager
        def a():
            yield 1
        @contextmanager
        def b():
            yield 2
        @contextmanager
        def c():
            yield 3
        with nested(a(), b(), c()) as (x, y, z):
            self.assertEqual(x, 1)
            self.assertEqual(y, 2)
            self.assertEqual(z, 3)

    def test_nested_cleanup(self):
        state = []
        @contextmanager
        def a():
            state.append(1)
            try:
                yield 2
            finally:
                state.append(3)
        @contextmanager
        def b():
            state.append(4)
            try:
                yield 5
            finally:
                state.append(6)
        try:
            with nested(a(), b()) as (x, y):
                state.append(x)
                state.append(y)
                1/0
        except ZeroDivisionError:
            self.assertEqual(state, [1, 4, 2, 5, 6, 3])
        else:
            self.fail("Didn't raise ZeroDivisionError")

    def test_nested_right_exception(self):
        state = []
        @contextmanager
        def a():
            yield 1
        class b(object):
            def __enter__(self):
                return 2
            def __exit__(self, *exc_info):
                try:
                    raise Exception()
                except:
                    pass
        try:
            with nested(a(), b()) as (x, y):
                1/0
        except ZeroDivisionError:
            self.assertEqual((x, y), (1, 2))
        except Exception:
            self.fail("Reraised wrong exception")
        else:
            self.fail("Didn't raise ZeroDivisionError")

    def test_nested_b_swallows(self):
        @contextmanager
        def a():
            yield
        @contextmanager
        def b():
            try:
                yield
            except:
                # Swallow the exception
                pass
        try:
            with nested(a(), b()):
                1/0
        except ZeroDivisionError:
            self.fail("Didn't swallow ZeroDivisionError")

    def test_nested_break(self):
        @contextmanager
        def a():
            yield
        state = 0
        while True:
            state += 1
            with nested(a(), a()):
                break
            state += 10
        self.assertEqual(state, 1)

    def test_nested_continue(self):
        @contextmanager
        def a():
            yield
        state = 0
        while state < 3:
            state += 1
            with nested(a(), a()):
                continue
            state += 10
        self.assertEqual(state, 3)

    def test_nested_return(self):
        @contextmanager
        def a():
            try:
                yield
            except:
                pass
        def foo():
            with nested(a(), a()):
                return 1
            return 10
        self.assertEqual(foo(), 1)

class ClosingTestCase(unittest.TestCase):

    # XXX This needs more work

    def test_closing(self):
        state = []
        class C:
            def close(self):
                state.append(1)
        x = C()
        self.assertEqual(state, [])
        with closing(x) as y:
            self.assertEqual(x, y)
        self.assertEqual(state, [1])

    def test_closing_error(self):
        state = []
        class C:
            def close(self):
                state.append(1)
        x = C()
        self.assertEqual(state, [])
        try:
            with closing(x) as y:
                self.assertEqual(x, y)
                1/0
        except ZeroDivisionError:
            self.assertEqual(state, [1])
        else:
            self.fail("Didn't raise ZeroDivisionError")

class FileContextTestCase(unittest.TestCase):

    def testWithOpen(self):
        tfn = tempfile.mktemp()
        try:
            f = None
            with open(tfn, "w") as f:
                self.failIf(f.closed)
                f.write("Booh\n")
            self.failUnless(f.closed)
            f = None
            try:
                with open(tfn, "r") as f:
                    self.failIf(f.closed)
                    self.assertEqual(f.read(), "Booh\n")
                    1/0
            except ZeroDivisionError:
                self.failUnless(f.closed)
            else:
                self.fail("Didn't raise ZeroDivisionError")
        finally:
            try:
                os.remove(tfn)
            except os.error:
                pass

class LockContextTestCase(unittest.TestCase):

    def boilerPlate(self, lock, locked):
        self.failIf(locked())
        with lock:
            self.failUnless(locked())
        self.failIf(locked())
        try:
            with lock:
                self.failUnless(locked())
                1/0
        except ZeroDivisionError:
            self.failIf(locked())
        else:
            self.fail("Didn't raise ZeroDivisionError")

    def testWithLock(self):
        lock = threading.Lock()
        self.boilerPlate(lock, lock.locked)

    def testWithRLock(self):
        lock = threading.RLock()
        self.boilerPlate(lock, lock._is_owned)

    def testWithCondition(self):
        lock = threading.Condition()
        def locked():
            return lock._is_owned()
        self.boilerPlate(lock, locked)

    def testWithSemaphore(self):
        lock = threading.Semaphore()
        def locked():
            if lock.acquire(False):
                lock.release()
                return False
            else:
                return True
        self.boilerPlate(lock, locked)

    def testWithBoundedSemaphore(self):
        lock = threading.BoundedSemaphore()
        def locked():
            if lock.acquire(False):
                lock.release()
                return False
            else:
                return True
        self.boilerPlate(lock, locked)

# This is needed to make the test actually run under regrtest.py!
def test_main():
    support.run_unittest(__name__)

if __name__ == "__main__":
    test_main()
<commit_msg>Suppress deprecation warnings.<commit_after>"""Unit tests for contextlib.py, and other context managers."""

import sys
import os
import decimal
import tempfile
import unittest
import threading
from contextlib import *  # Tests __all__
from test import support
import warnings

class ContextManagerTestCase(unittest.TestCase):

    def test_contextmanager_plain(self):
        state = []
        @contextmanager
        def woohoo():
            state.append(1)
            yield 42
            state.append(999)
        with woohoo() as x:
            self.assertEqual(state, [1])
            self.assertEqual(x, 42)
            state.append(x)
        self.assertEqual(state, [1, 42, 999])

    def test_contextmanager_finally(self):
        state = []
        @contextmanager
        def woohoo():
            state.append(1)
            try:
                yield 42
            finally:
                state.append(999)
        try:
            with woohoo() as x:
                self.assertEqual(state, [1])
                self.assertEqual(x, 42)
                state.append(x)
                raise ZeroDivisionError()
        except ZeroDivisionError:
            pass
        else:
            self.fail("Expected ZeroDivisionError")
        self.assertEqual(state, [1, 42, 999])

    def test_contextmanager_no_reraise(self):
        @contextmanager
        def whee():
            yield
        ctx = whee()
        ctx.__enter__()
        # Calling __exit__ should not result in an exception
        self.failIf(ctx.__exit__(TypeError, TypeError("foo"), None))

    def test_contextmanager_trap_yield_after_throw(self):
        @contextmanager
        def whoo():
            try:
                yield
            except:
                yield
        ctx = whoo()
        ctx.__enter__()
        self.assertRaises(
            RuntimeError, ctx.__exit__, TypeError, TypeError("foo"), None
        )

    def test_contextmanager_except(self):
        state = []
        @contextmanager
        def woohoo():
            state.append(1)
            try:
                yield 42
            except ZeroDivisionError as e:
                state.append(e.args[0])
                self.assertEqual(state, [1, 42, 999])
        with woohoo() as x:
            self.assertEqual(state, [1])
            self.assertEqual(x, 42)
            state.append(x)
            raise ZeroDivisionError(999)
        self.assertEqual(state, [1, 42, 999])

    def test_contextmanager_attribs(self):
        def attribs(**kw):
            def decorate(func):
                for k,v in kw.items():
                    setattr(func,k,v)
                return func
            return decorate
        @contextmanager
        @attribs(foo='bar')
        def baz(spam):
            """Whee!"""
        self.assertEqual(baz.__name__,'baz')
        self.assertEqual(baz.foo, 'bar')
        self.assertEqual(baz.__doc__, "Whee!")

class NestedTestCase(unittest.TestCase):

    # XXX This needs more work

    def test_nested(self):
        @contextmanager
        def a():
            yield 1
        @contextmanager
        def b():
            yield 2
        @contextmanager
        def c():
            yield 3
        with nested(a(), b(), c()) as (x, y, z):
            self.assertEqual(x, 1)
            self.assertEqual(y, 2)
            self.assertEqual(z, 3)

    def test_nested_cleanup(self):
        state = []
        @contextmanager
        def a():
            state.append(1)
            try:
                yield 2
            finally:
                state.append(3)
        @contextmanager
        def b():
            state.append(4)
            try:
                yield 5
            finally:
                state.append(6)
        try:
            with nested(a(), b()) as (x, y):
                state.append(x)
                state.append(y)
                1/0
        except ZeroDivisionError:
            self.assertEqual(state, [1, 4, 2, 5, 6, 3])
        else:
            self.fail("Didn't raise ZeroDivisionError")

    def test_nested_right_exception(self):
        state = []
        @contextmanager
        def a():
            yield 1
        class b(object):
            def __enter__(self):
                return 2
            def __exit__(self, *exc_info):
                try:
                    raise Exception()
                except:
                    pass
        try:
            with nested(a(), b()) as (x, y):
                1/0
        except ZeroDivisionError:
            self.assertEqual((x, y), (1, 2))
        except Exception:
            self.fail("Reraised wrong exception")
        else:
            self.fail("Didn't raise ZeroDivisionError")

    def test_nested_b_swallows(self):
        @contextmanager
        def a():
            yield
        @contextmanager
        def b():
            try:
                yield
            except:
                # Swallow the exception
                pass
        try:
            with nested(a(), b()):
                1/0
        except ZeroDivisionError:
            self.fail("Didn't swallow ZeroDivisionError")

    def test_nested_break(self):
        @contextmanager
        def a():
            yield
        state = 0
        while True:
            state += 1
            with nested(a(), a()):
                break
            state += 10
        self.assertEqual(state, 1)

    def test_nested_continue(self):
        @contextmanager
        def a():
            yield
        state = 0
        while state < 3:
            state += 1
            with nested(a(), a()):
                continue
            state += 10
        self.assertEqual(state, 3)

    def test_nested_return(self):
        @contextmanager
        def a():
            try:
                yield
            except:
                pass
        def foo():
            with nested(a(), a()):
                return 1
            return 10
        self.assertEqual(foo(), 1)

class ClosingTestCase(unittest.TestCase):

    # XXX This needs more work

    def test_closing(self):
        state = []
        class C:
            def close(self):
                state.append(1)
        x = C()
        self.assertEqual(state, [])
        with closing(x) as y:
            self.assertEqual(x, y)
        self.assertEqual(state, [1])

    def test_closing_error(self):
        state = []
        class C:
            def close(self):
                state.append(1)
        x = C()
        self.assertEqual(state, [])
        try:
            with closing(x) as y:
                self.assertEqual(x, y)
                1/0
        except ZeroDivisionError:
            self.assertEqual(state, [1])
        else:
            self.fail("Didn't raise ZeroDivisionError")

class FileContextTestCase(unittest.TestCase):

    def testWithOpen(self):
        tfn = tempfile.mktemp()
        try:
            f = None
            with open(tfn, "w") as f:
                self.failIf(f.closed)
                f.write("Booh\n")
            self.failUnless(f.closed)
            f = None
            try:
                with open(tfn, "r") as f:
                    self.failIf(f.closed)
                    self.assertEqual(f.read(), "Booh\n")
                    1/0
            except ZeroDivisionError:
                self.failUnless(f.closed)
            else:
                self.fail("Didn't raise ZeroDivisionError")
        finally:
            try:
                os.remove(tfn)
            except os.error:
                pass

class LockContextTestCase(unittest.TestCase):

    def boilerPlate(self, lock, locked):
        self.failIf(locked())
        with lock:
            self.failUnless(locked())
        self.failIf(locked())
        try:
            with lock:
                self.failUnless(locked())
                1/0
        except ZeroDivisionError:
            self.failIf(locked())
        else:
            self.fail("Didn't raise ZeroDivisionError")

    def testWithLock(self):
        lock = threading.Lock()
        self.boilerPlate(lock, lock.locked)

    def testWithRLock(self):
        lock = threading.RLock()
        self.boilerPlate(lock, lock._is_owned)

    def testWithCondition(self):
        lock = threading.Condition()
        def locked():
            return lock._is_owned()
        self.boilerPlate(lock, locked)

    def testWithSemaphore(self):
        lock = threading.Semaphore()
        def locked():
            if lock.acquire(False):
                lock.release()
                return False
            else:
                return True
        self.boilerPlate(lock, locked)

    def testWithBoundedSemaphore(self):
        lock = threading.BoundedSemaphore()
        def locked():
            if lock.acquire(False):
                lock.release()
                return False
            else:
                return True
        self.boilerPlate(lock, locked)

# This is needed to make the test actually run under regrtest.py!
def test_main():
    with warnings.catch_warnings():
        warnings.simplefilter('ignore')
        support.run_unittest(__name__)

if __name__ == "__main__":
    test_main()
<|endoftext|>


<commit_before>from django.conf import settings

from allauth.account.adapter import DefaultAccountAdapter
from allauth.socialaccount.adapter import DefaultSocialAccountAdapter

from feedthefox.users.mozillians import MozilliansClient

class FeedTheFoxAdapter(DefaultAccountAdapter):
    """Customize the default allauth account adapter."""

    def is_open_for_signup(self, request):
        """Disable signup since everything will go through Persona."""

        return False

class FeedTheFoxSocialAdapter(DefaultSocialAccountAdapter):

    def __init__(self, *args, **kwargs):
        """Initialize mozillians.org api client."""

        super(FeedTheFoxSocialAdapter, self).__init__(*args, **kwargs)
        self.mozillians_client = MozilliansClient(settings.MOZILLIANS_API_URL,
                                                  settings.MOZILLIANS_API_KEY)

    def is_open_for_signup(self, request, sociallogin):
        """ Enable signup only through social accounts."""

        return True

    def populate_user(self, request, sociallogin, data):
        """Populate user with data from mozillians.org."""

        mozillian_attrs = ['country', 'photo', 'ircname', 'city']
        user = super(FeedTheFoxSocialAdapter, self).populate_user(request,
                                                                  sociallogin,
                                                                  data)
        emails = []

        if sociallogin.account.provider == 'github':
            for email_address in sociallogin.email_addresses:
                email_address.user = sociallogin.user
                if email_address.primary:
                    sociallogin.user.email = email_address.email
                emails.append(email_address.email)
        else:
            emails.append(user.email)

        for email in emails:
            try:
                mozillian = self.mozillians_client.lookup_user({'email': email})
                break
            except:
                mozillian = None

        if mozillian:
            user.username = mozillian['username']
            for attr in mozillian_attrs:
                if mozillian[attr].get('privacy') == 'Public':
                    setattr(user, attr, mozillian[attr].get('value'))
            if mozillian['full_name']['privacy'] == 'Public':
                first_name, last_name = mozillian['full_name']['value'].split(' ', 1)
            else:
                first_name = 'Anonymous'
                last_name = 'Mozillian'
            user.first_name = first_name
            user.last_name = last_name
        else:
            user.is_active = False
        return user
<commit_msg>Automatically connect users with verified emails.<commit_after>from django.conf import settings

from allauth.account.adapter import DefaultAccountAdapter
from allauth.socialaccount.adapter import DefaultSocialAccountAdapter
from allauth.socialaccount.models import EmailAddress

from feedthefox.users.models import User
from feedthefox.users.mozillians import MozilliansClient

class FeedTheFoxAdapter(DefaultAccountAdapter):
    """Customize the default allauth account adapter."""

    def is_open_for_signup(self, request):
        """Disable signup since everything will go through Persona."""

        return False

class FeedTheFoxSocialAdapter(DefaultSocialAccountAdapter):

    def __init__(self, *args, **kwargs):
        """Initialize mozillians.org api client."""

        super(FeedTheFoxSocialAdapter, self).__init__(*args, **kwargs)
        self.mozillians_client = MozilliansClient(settings.MOZILLIANS_API_URL,
                                                  settings.MOZILLIANS_API_KEY)

    def is_open_for_signup(self, request, sociallogin):
        """ Enable signup only through social accounts."""

        return True

    def populate_user(self, request, sociallogin, data):
        """Populate user with data from mozillians.org."""

        mozillian_attrs = ['country', 'photo', 'ircname', 'city']
        user = super(FeedTheFoxSocialAdapter, self).populate_user(request,
                                                                  sociallogin,
                                                                  data)
        emails = []

        if sociallogin.account.provider == 'github':
            for email_address in sociallogin.email_addresses:
                email_address.user = sociallogin.user
                if email_address.primary:
                    sociallogin.user.email = email_address.email
                emails.append(email_address.email)
        else:
            emails.append(user.email)

        for email in emails:
            try:
                mozillian = self.mozillians_client.lookup_user({'email': email})
                break
            except:
                mozillian = None

        if mozillian:
            user.username = mozillian['username']
            for attr in mozillian_attrs:
                if mozillian[attr].get('privacy') == 'Public':
                    setattr(user, attr, mozillian[attr].get('value'))
            if mozillian['full_name']['privacy'] == 'Public':
                first_name, last_name = mozillian['full_name']['value'].split(' ', 1)
            else:
                first_name = 'Anonymous'
                last_name = 'Mozillian'
            user.first_name = first_name
            user.last_name = last_name
        else:
            user.is_active = False
        return user

    def pre_social_login(self, request, sociallogin):
        email = sociallogin.user.email
        try:
            user = User.objects.get(email=email)
            sociallogin.connect(request, user)
        except User.DoesNotExist:
            query = EmailAddress.objects.filter(email=email)
            if query.exists():
                sociallogin.connect(request, query[0].user)
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
##############################################################################
#
#    Copyright (c) 2014 Acsone SA/NV (http://www.acsone.eu)
#    All Rights Reserved
#
#    WARNING: This program as such is intended to be used by professional
#    programmers who take the whole responsibility of assessing all potential
#    consequences resulting from its eventual inadequacies and bugs.
#    End users who are looking for a ready-to-use solution with commercial
#    guarantees and support are strongly advised to contact a Free Software
#    Service Company.
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU Affero General Public License as
#    published by the Free Software Foundation, either version 3 of the
#    License, or (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU Affero General Public License for more details.
#
#    You should have received a copy of the GNU Affero General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
import logging

from openerp.osv import orm, fields
from openerp.tools.translate import _
from openerp.tools import SUPERUSER_ID

_logger = logging.getLogger(__name__)

INVALIDATE_ERROR = _('Invalidation impossible, at least one dependency is still active')

class abstract_ficep_model (orm.AbstractModel):

    _name = 'abstract.ficep.model'
    _inherit = ['mail.thread', 'ir.needaction_mixin']
    _description = 'Abstract Ficep Model'

    _allowed_inactive_link_models = []
    _inactive_cascade = False

    def action_invalidate(self, cr, uid, ids, context=None, vals=None):
        """
        =================
        action_invalidate
        =================
        Invalidates an object
        :rparam: True
        :rtype: boolean
        Note: Argument vals must be the last in the signature
        """
        vals = vals or {}
        vals.update(self.get_fields_to_update(cr, uid, 'deactivate', context=context))
        return self.write(cr, uid, ids, vals, context=context)

    def action_revalidate(self, cr, uid, ids, context=None, vals=None):
        """
        ===============
        action_revalidate
        ===============
        Reactivates an object by setting
        :rparam: True
        :rtype: boolean
        """
        vals = vals or {}
        vals.update(self.get_fields_to_update(cr, uid, 'activate', context=context))
        return self.write(cr, uid, ids, vals, context=context)

    def get_fields_to_update(self, cr, uid, mode, context=None):
        """
        ====================
        get_fields_to_update
        ====================
        Depending on a mode, builds a dictionary allowing to update validity fields
        :rparam: fields to update
        :rtype: dictionary
        """
        res = {}
        if mode == 'deactivate':
            res.update({
                'active': False,
                'expire_date': fields.datetime.now(),
            })
        if mode == 'activate':
            res.update({
                'active': True,
                'expire_date': False,
            })
        return res

    _columns = {
        'id': fields.integer('ID', readonly=True),
        'create_date': fields.datetime('Creation Date', readonly=True),
        'expire_date': fields.datetime('Expiration Date', readonly=True, track_visibility='onchange'),
        'active': fields.boolean('Active'),
    }

    _defaults = {
        'active': True,
        'expire_date': False,
    }

# constraints

    def _check_invalidate(self, cr, uid, ids, context=None):
        """
        =================
        _check_invalidate
        =================
        Check if object can be desactivated, dependencies must be desactivated before
        :rparam: True if it is the case
                 False otherwise
        :rtype: boolean
        """
        invalidate_ids = list(ids)
        ficep_models = self.browse(cr, uid, invalidate_ids, context=context)
        for ficep_model in ficep_models:
            if not ficep_model.expire_date:
                invalidate_ids.remove(ficep_model.id)

        if invalidate_ids:
            rels_dict = self.pool.get('ir.model')._get_active_relations(cr, uid, invalidate_ids, self._name, context=context)

            if len(rels_dict) > 0:
                for k in rels_dict.keys():
                    _logger.info('Remaining active m2o for %s(%s): %s', self._name, k, rels_dict[k])
                return False

        return True

    def _invalidate_active_relations(self, cr, uid, ids, context=None):
        """
        =============================
        _invalidate_actives_relations
        =============================
        Invalidate all dependencies of ids object
        :rparam: True if no error
                 False otherwise
        :rtype: boolean
        """
        invalidate_ids = isinstance(ids, (long, int)) and [ids] or ids
        if invalidate_ids:
            rels_dict = self.pool.get('ir.model')._get_active_relations(cr, uid, invalidate_ids, self._name, context=context, with_ids=True)
            for relation_models in rels_dict.values():
                for relation, relation_ids in relation_models.iteritems():
                    relation_object = self.pool.get(relation)
                    if hasattr(relation_object, 'action_invalidate'):
                        relation_object.action_invalidate(cr, uid, relation_ids, context=context)
                    else:
                        if relation == 'mail.followers':
                            relation_object.unlink(cr, uid, relation_ids, context=context)
                        elif hasattr(relation_object, 'active'):
                            relation_object.write(cr, uid, relation_ids, {'active': False}, context=context)

    _constraints = [
        (_check_invalidate, INVALIDATE_ERROR, ['expire_date'])
    ]

    _unicity_keys = None

    def init(self, cr):
        if not self._auto:
            return

        if not self._unicity_keys:
            _logger.warn('No _unicity_keys specified for model %s', self._name)
            return

        if self._unicity_keys == 'N/A':
            return

        createit = True
        index_def = "CREATE UNIQUE INDEX %s_unique_idx ON %s USING btree (%s) WHERE (active IS TRUE)" % \
                    (self._table, self._table, self._unicity_keys)
        cr.execute("""SELECT indexdef
                      FROM pg_indexes
                      WHERE tablename = '%s' and indexname = '%s_unique_idx'""" % \
                   (self._table, self._table))
        sql_res = cr.dictfetchone()
        if sql_res:
            if sql_res['indexdef'] != index_def:
                cr.execute("DROP INDEX %s_unique_idx" % (self._table,))
            else:
                createit = False

        if createit:
            cr.execute(index_def)

# orm methods

    def create(self, cr, uid, vals, context=None):
        """
        Do not add creator to followers, nor track message on create
        """
        ctx = dict(context or {})
        ctx.update({
            'mail_create_nosubscribe': True,
            'mail_notrack': True,
        })
        if ctx.get('install_mode'):
            # optimize for tests escaping useless treatments in mail.thread
            ctx.update({
                'tracking_disable': True,
                'mail_create_nolog': True,
                'mail_no_autosubscribe': True,
                'lang': 'en_US',
            })
        new_id = super(abstract_ficep_model, self).create(cr, uid, vals, context=ctx)
        return new_id

    def write(self, cr, uid, ids, vals, context=None):
        ctx = dict(context or {})
        if ctx.get('install_mode'):
            # optimize for tests escaping useless treatments in mail.thread
            ctx.update({
                'tracking_disable': True,
                'mail_notrack': True,
                'mail_no_autosubscribe': True,
                'lang': 'en_US',
            })
        mode = False
        if 'active' in vals:
            mode = 'activate' if vals['active'] else 'deactivate'
            vals.update(self.get_fields_to_update(cr, uid, mode, context=ctx))
        if mode == 'deactivate' and self._inactive_cascade:
            mail_follower_object = self.pool['mail.followers']
            follower_ids = mail_follower_object.search(cr, uid, [('res_model', '=', self._name), ('res_id', 'in', ids)], context=context)
            mail_follower_object.unlink(cr, uid, follower_ids, context=context)
            self._invalidate_active_relations(cr, uid, ids, context=ctx)
        res = super(abstract_ficep_model, self).write(cr, uid, ids, vals, context=ctx)
        return res

    def message_auto_subscribe(self, cr, uid, ids, updated_fields, context=None, values=None):
        ctx = context or {}
        if ctx.get('mail_no_autosubscribe'):
            return True
        res = super(abstract_ficep_model, self).message_auto_subscribe(cr, uid, ids, updated_fields, context=ctx, values=values)
        return res

    def copy_data(self, cr, uid, ids, default=None, context=None):
        """
        Reset some fields to their initial values
        """
        default = default or {}
        default.update(self.get_fields_to_update(cr, uid, 'activate', context=context))
        res = super(abstract_ficep_model, self).copy_data(cr, uid, ids, default=default, context=context)
        return res

    def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, toolbar=False, submenu=False):
        """
        * Add the "popup" item into the context if the form will be shown as a popup
        * Generate a domain on all fields to make the form readonly when document is inactive
        * Work around the automatic form generation when it is inherited from an other model
        """
        context = context or {}

        if view_type == 'form':
            if not toolbar:
                context.update(popup=True)
            if uid != SUPERUSER_ID and not context.get('is_developper'):
                context.update(add_readonly_condition=True)

        if not view_id and not context.get('%s_view_ref' % view_type):
            cr.execute("""SELECT id
                          FROM ir_ui_view
                          WHERE model=%s AND type=%s AND inherit_id IS NULL
                          ORDER BY priority LIMIT 1""", (self._name, view_type))
            sql_res = cr.dictfetchone()
            if not sql_res:
                cr.execute("""SELECT id
                              FROM ir_ui_view
                              WHERE model=%s AND type=%s
                              ORDER BY priority LIMIT 1""", (self._name, view_type))
                sql_res = cr.dictfetchone()
                if sql_res:
                    # force this existing view
                    view_id = sql_res['id']
                elif view_type in ['tree', 'search']:
                    # Heuristic at this point: maybe an abstract search or tree view is declared on an ir.act.window
                    col = view_type == 'search' and 'search_view_id' or 'view_id'
                    cr.execute("""SELECT %s as v
                                  FROM ir_act_window, ir_ui_view i
                                  WHERE res_model=%%s AND i.id = %s
                                  ORDER BY priority LIMIT 1""" % (col, col), (self._name, ))
                    sql_res = cr.dictfetchone()
                    if sql_res:
                        # force this existing view
                        view_id = sql_res['v']

        res = super(abstract_ficep_model, self).fields_view_get(cr, uid, view_id=view_id, view_type=view_type, context=context, toolbar=toolbar, submenu=submenu)
        return res

    def display_object_in_form_view(self, cr, uid, object_id, context=None):
        """
        Return the object (with given id) in the default form view
        """
        view_ids = self.pool.get('ir.ui.view').search(cr, uid, [('model', '=', self._name),
                                                                ('type', '=', 'form')], limit=1, context=context)

        res = {
            'type': 'ir.actions.act_window',
            'name': self._description,
            'res_model': self._name,
            'res_id': object_id,
            'view_type': 'form',
            'view_mode': 'form',
            'view_id': view_ids[0] if len(view_ids) > 0 else False,
            'target': 'current',
            'nodestroy': True,
        } if len(view_ids) else False

        return res

# Replace the orm.transfer_node_to_modifiers functions.

original_transfer_node_to_modifiers = orm.transfer_node_to_modifiers

def transfer_node_to_modifiers(node, modifiers, context=None, in_tree_view=False):
    '''
    Add conditions on usefull fields (but chatting fields) to make readonly the form if the document is inactive
    '''
    fct_src = original_transfer_node_to_modifiers
    trace = False

    if context and context.get('add_readonly_condition'):
        context.pop('add_readonly_condition')

        if trace:
            # etree.tostring(node)
            pass
        if node.xpath("//field[@name='active'][not(ancestor::field)]"):
            for nd in node.xpath("//field[not(ancestor::div[(@name='dev') or (@name='chat')])][not(ancestor::field)]"):
                attrs_str = nd.get('attrs') or '{}'
                after = eval(attrs_str)
                if after.get('readonly'):
                    dom = str(after.get('readonly'))[1:-1]
                    if len(dom.split("'active'")) > 1:
                        continue
                    else:
                        dom = "['|', ('active', '=', False), %s]" % dom
                        after['readonly'] = eval(dom)
                else:
                    after['readonly'] = [('active', '=', False)]
                after = str(after)
                nd.set('attrs', after)
                if trace:
                    _logger.info('Field %s - attrs before: %s - after: %s', nd.get('name'), attrs_str, after)

    return fct_src(node, modifiers, context=context, in_tree_view=in_tree_view)

orm.transfer_node_to_modifiers = transfer_node_to_modifiers

# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
<commit_msg>[CHG] if context is empty, a test is running => disable tracking<commit_after># -*- coding: utf-8 -*-
##############################################################################
#
#    Copyright (c) 2014 Acsone SA/NV (http://www.acsone.eu)
#    All Rights Reserved
#
#    WARNING: This program as such is intended to be used by professional
#    programmers who take the whole responsibility of assessing all potential
#    consequences resulting from its eventual inadequacies and bugs.
#    End users who are looking for a ready-to-use solution with commercial
#    guarantees and support are strongly advised to contact a Free Software
#    Service Company.
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU Affero General Public License as
#    published by the Free Software Foundation, either version 3 of the
#    License, or (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU Affero General Public License for more details.
#
#    You should have received a copy of the GNU Affero General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
import logging

from openerp.osv import orm, fields
from openerp.tools.translate import _
from openerp.tools import SUPERUSER_ID

_logger = logging.getLogger(__name__)

INVALIDATE_ERROR = _('Invalidation impossible, at least one dependency is still active')

class abstract_ficep_model (orm.AbstractModel):

    _name = 'abstract.ficep.model'
    _inherit = ['mail.thread', 'ir.needaction_mixin']
    _description = 'Abstract Ficep Model'

    _allowed_inactive_link_models = []
    _inactive_cascade = False

    def action_invalidate(self, cr, uid, ids, context=None, vals=None):
        """
        =================
        action_invalidate
        =================
        Invalidates an object
        :rparam: True
        :rtype: boolean
        Note: Argument vals must be the last in the signature
        """
        vals = vals or {}
        vals.update(self.get_fields_to_update(cr, uid, 'deactivate', context=context))
        return self.write(cr, uid, ids, vals, context=context)

    def action_revalidate(self, cr, uid, ids, context=None, vals=None):
        """
        ===============
        action_revalidate
        ===============
        Reactivates an object by setting
        :rparam: True
        :rtype: boolean
        """
        vals = vals or {}
        vals.update(self.get_fields_to_update(cr, uid, 'activate', context=context))
        return self.write(cr, uid, ids, vals, context=context)

    def get_fields_to_update(self, cr, uid, mode, context=None):
        """
        ====================
        get_fields_to_update
        ====================
        Depending on a mode, builds a dictionary allowing to update validity fields
        :rparam: fields to update
        :rtype: dictionary
        """
        res = {}
        if mode == 'deactivate':
            res.update({
                'active': False,
                'expire_date': fields.datetime.now(),
            })
        if mode == 'activate':
            res.update({
                'active': True,
                'expire_date': False,
            })
        return res

    _columns = {
        'id': fields.integer('ID', readonly=True),
        'create_date': fields.datetime('Creation Date', readonly=True),
        'expire_date': fields.datetime('Expiration Date', readonly=True, track_visibility='onchange'),
        'active': fields.boolean('Active'),
    }

    _defaults = {
        'active': True,
        'expire_date': False,
    }

# constraints

    def _check_invalidate(self, cr, uid, ids, context=None):
        """
        =================
        _check_invalidate
        =================
        Check if object can be desactivated, dependencies must be desactivated before
        :rparam: True if it is the case
                 False otherwise
        :rtype: boolean
        """
        invalidate_ids = list(ids)
        ficep_models = self.browse(cr, uid, invalidate_ids, context=context)
        for ficep_model in ficep_models:
            if not ficep_model.expire_date:
                invalidate_ids.remove(ficep_model.id)

        if invalidate_ids:
            rels_dict = self.pool.get('ir.model')._get_active_relations(cr, uid, invalidate_ids, self._name, context=context)

            if len(rels_dict) > 0:
                for k in rels_dict.keys():
                    _logger.info('Remaining active m2o for %s(%s): %s', self._name, k, rels_dict[k])
                return False

        return True

    def _invalidate_active_relations(self, cr, uid, ids, context=None):
        """
        =============================
        _invalidate_actives_relations
        =============================
        Invalidate all dependencies of ids object
        :rparam: True if no error
                 False otherwise
        :rtype: boolean
        """
        invalidate_ids = isinstance(ids, (long, int)) and [ids] or ids
        if invalidate_ids:
            rels_dict = self.pool.get('ir.model')._get_active_relations(cr, uid, invalidate_ids, self._name, context=context, with_ids=True)
            for relation_models in rels_dict.values():
                for relation, relation_ids in relation_models.iteritems():
                    relation_object = self.pool.get(relation)
                    if hasattr(relation_object, 'action_invalidate'):
                        relation_object.action_invalidate(cr, uid, relation_ids, context=context)
                    else:
                        if relation == 'mail.followers':
                            relation_object.unlink(cr, uid, relation_ids, context=context)
                        elif hasattr(relation_object, 'active'):
                            relation_object.write(cr, uid, relation_ids, {'active': False}, context=context)

    _constraints = [
        (_check_invalidate, INVALIDATE_ERROR, ['expire_date'])
    ]

    _unicity_keys = None

    def init(self, cr):
        if not self._auto:
            return

        if not self._unicity_keys:
            _logger.warn('No _unicity_keys specified for model %s', self._name)
            return

        if self._unicity_keys == 'N/A':
            return

        createit = True
        index_def = "CREATE UNIQUE INDEX %s_unique_idx ON %s USING btree (%s) WHERE (active IS TRUE)" % \
                    (self._table, self._table, self._unicity_keys)
        cr.execute("""SELECT indexdef
                      FROM pg_indexes
                      WHERE tablename = '%s' and indexname = '%s_unique_idx'""" % \
                   (self._table, self._table))
        sql_res = cr.dictfetchone()
        if sql_res:
            if sql_res['indexdef'] != index_def:
                cr.execute("DROP INDEX %s_unique_idx" % (self._table,))
            else:
                createit = False

        if createit:
            cr.execute(index_def)

# orm methods

    def create(self, cr, uid, vals, context=None):
        """
        Do not add creator to followers, nor track message on create
        """
        ctx = dict(context or {'tracking_disable': True})
        ctx.update({
            'mail_create_nosubscribe': True,
            'mail_notrack': True,
        })
        if ctx.get('install_mode'):
            # optimize for tests escaping useless treatments in mail.thread
            ctx.update({
                'tracking_disable': True,
                'mail_create_nolog': True,
                'mail_no_autosubscribe': True,
                'lang': 'en_US',
            })
        new_id = super(abstract_ficep_model, self).create(cr, uid, vals, context=ctx)
        return new_id

    def write(self, cr, uid, ids, vals, context=None):
        ctx = dict(context or {'tracking_disable': True})
        if ctx.get('install_mode'):
            # optimize for tests escaping useless treatments in mail.thread
            ctx.update({
                'tracking_disable': True,
                'mail_notrack': True,
                'mail_no_autosubscribe': True,
                'lang': 'en_US',
            })
        mode = False
        if 'active' in vals:
            mode = 'activate' if vals['active'] else 'deactivate'
            vals.update(self.get_fields_to_update(cr, uid, mode, context=ctx))
        if mode == 'deactivate' and self._inactive_cascade:
            mail_follower_object = self.pool['mail.followers']
            follower_ids = mail_follower_object.search(cr, uid, [('res_model', '=', self._name), ('res_id', 'in', ids)], context=context)
            mail_follower_object.unlink(cr, uid, follower_ids, context=context)
            self._invalidate_active_relations(cr, uid, ids, context=ctx)
        res = super(abstract_ficep_model, self).write(cr, uid, ids, vals, context=ctx)
        return res

    def message_auto_subscribe(self, cr, uid, ids, updated_fields, context=None, values=None):
        ctx = context or {}
        if ctx.get('mail_no_autosubscribe'):
            return True
        res = super(abstract_ficep_model, self).message_auto_subscribe(cr, uid, ids, updated_fields, context=ctx, values=values)
        return res

    def copy_data(self, cr, uid, ids, default=None, context=None):
        """
        Reset some fields to their initial values
        """
        default = default or {}
        default.update(self.get_fields_to_update(cr, uid, 'activate', context=context))
        res = super(abstract_ficep_model, self).copy_data(cr, uid, ids, default=default, context=context)
        return res

    def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, toolbar=False, submenu=False):
        """
        * Add the "popup" item into the context if the form will be shown as a popup
        * Generate a domain on all fields to make the form readonly when document is inactive
        * Work around the automatic form generation when it is inherited from an other model
        """
        context = context or {}

        if view_type == 'form':
            if not toolbar:
                context.update(popup=True)
            if uid != SUPERUSER_ID and not context.get('is_developper'):
                context.update(add_readonly_condition=True)

        if not view_id and not context.get('%s_view_ref' % view_type):
            cr.execute("""SELECT id
                          FROM ir_ui_view
                          WHERE model=%s AND type=%s AND inherit_id IS NULL
                          ORDER BY priority LIMIT 1""", (self._name, view_type))
            sql_res = cr.dictfetchone()
            if not sql_res:
                cr.execute("""SELECT id
                              FROM ir_ui_view
                              WHERE model=%s AND type=%s
                              ORDER BY priority LIMIT 1""", (self._name, view_type))
                sql_res = cr.dictfetchone()
                if sql_res:
                    # force this existing view
                    view_id = sql_res['id']
                elif view_type in ['tree', 'search']:
                    # Heuristic at this point: maybe an abstract search or tree view is declared on an ir.act.window
                    col = view_type == 'search' and 'search_view_id' or 'view_id'
                    cr.execute("""SELECT %s as v
                                  FROM ir_act_window, ir_ui_view i
                                  WHERE res_model=%%s AND i.id = %s
                                  ORDER BY priority LIMIT 1""" % (col, col), (self._name, ))
                    sql_res = cr.dictfetchone()
                    if sql_res:
                        # force this existing view
                        view_id = sql_res['v']

        res = super(abstract_ficep_model, self).fields_view_get(cr, uid, view_id=view_id, view_type=view_type, context=context, toolbar=toolbar, submenu=submenu)
        return res

    def display_object_in_form_view(self, cr, uid, object_id, context=None):
        """
        Return the object (with given id) in the default form view
        """
        view_ids = self.pool.get('ir.ui.view').search(cr, uid, [('model', '=', self._name),
                                                                ('type', '=', 'form')], limit=1, context=context)

        res = {
            'type': 'ir.actions.act_window',
            'name': self._description,
            'res_model': self._name,
            'res_id': object_id,
            'view_type': 'form',
            'view_mode': 'form',
            'view_id': view_ids[0] if len(view_ids) > 0 else False,
            'target': 'current',
            'nodestroy': True,
        } if len(view_ids) else False

        return res

# Replace the orm.transfer_node_to_modifiers functions.

original_transfer_node_to_modifiers = orm.transfer_node_to_modifiers

def transfer_node_to_modifiers(node, modifiers, context=None, in_tree_view=False):
    '''
    Add conditions on usefull fields (but chatting fields) to make readonly the form if the document is inactive
    '''
    fct_src = original_transfer_node_to_modifiers
    trace = False

    if context and context.get('add_readonly_condition'):
        context.pop('add_readonly_condition')

        if trace:
            # etree.tostring(node)
            pass
        if node.xpath("//field[@name='active'][not(ancestor::field)]"):
            for nd in node.xpath("//field[not(ancestor::div[(@name='dev') or (@name='chat')])][not(ancestor::field)]"):
                attrs_str = nd.get('attrs') or '{}'
                after = eval(attrs_str)
                if after.get('readonly'):
                    dom = str(after.get('readonly'))[1:-1]
                    if len(dom.split("'active'")) > 1:
                        continue
                    else:
                        dom = "['|', ('active', '=', False), %s]" % dom
                        after['readonly'] = eval(dom)
                else:
                    after['readonly'] = [('active', '=', False)]
                after = str(after)
                nd.set('attrs', after)
                if trace:
                    _logger.info('Field %s - attrs before: %s - after: %s', nd.get('name'), attrs_str, after)

    return fct_src(node, modifiers, context=context, in_tree_view=in_tree_view)

orm.transfer_node_to_modifiers = transfer_node_to_modifiers

# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
<|endoftext|>