text:
<?php

namespace Blog\UserBundle\Util;

use FOS\UserBundle\Model\UserManagerInterface;

/**
 * Executes some manipulations on the users
 *
 * @author Christophe Coevoet <stof@notk.org>
 * @author Luis Cordova <cordoval@gmail.com>
 */
class UserManipulator
{
    /**
     * User manager
     *
     * @var UserManagerInterface
     */
    private $userManager;

    public function __construct(UserManagerInterface $userManager)
    {
        $this->userManager = $userManager;
    }

    /**
     * Creates a user and returns it.
     *
     * @param string  $username
     * @param string  $password
     * @param string  $email
     * @param Boolean $active
     * @param Boolean $superadmin
     *
     * @return \FOS\UserBundle\Model\UserInterface
     */
    public function create($firstname, $lastname, $username, $password, $email, $active, $superadmin)
    {
        $user = $this->userManager->createUser();
        $user->setFirstName($firstname);
        $user->setLastName($lastname);
        $user->setUsername($username);
        $user->setEmail($email);
        $user->setPlainPassword($password);
        $user->setEnabled((Boolean) $active);
        $user->setSuperAdmin((Boolean) $superadmin);
        $this->userManager->updateUser($user);

        return $user;
    }

    /**
     * Activates the given user.
     *
     * @param string $username
     */
    public function activate($username)
    {
        $user = $this->findUserByUsernameOrThrowException($username);
        $user->setEnabled(true);
        $this->userManager->updateUser($user);
    }

    /**
     * Deactivates the given user.
     *
     * @param string $username
     */
    public function deactivate($username)
    {
        $user = $this->findUserByUsernameOrThrowException($username);
        $user->setEnabled(false);
        $this->userManager->updateUser($user);
    }

    /**
     * Changes the password for the given user.
     *
     * @param string $username
     * @param string $password
     */
    public function changePassword($username, $password)
    {
        $user = $this->findUserByUsernameOrThrowException($username);
        $user->setPlainPassword($password);
        $this->userManager->updateUser($user);
    }

    /**
     * Promotes the given user.
     *
     * @param string $username
     */
    public function promote($username)
    {
        $user = $this->findUserByUsernameOrThrowException($username);
        $user->setSuperAdmin(true);
        $this->userManager->updateUser($user);
    }

    /**
     * Demotes the given user.
     *
     * @param string $username
     */
    public function demote($username)
    {
        $user = $this->findUserByUsernameOrThrowException($username);
        $user->setSuperAdmin(false);
        $this->userManager->updateUser($user);
    }

    /**
     * Adds role to the given user.
     *
     * @param string $username
     * @param string $role
     *
     * @return Boolean true if role was added, false if user already had the role
     */
    public function addRole($username, $role)
    {
        $user = $this->findUserByUsernameOrThrowException($username);
        if ($user->hasRole($role)) {
            return false;
        }
        $user->addRole($role);
        $this->userManager->updateUser($user);

        return true;
    }

    /**
     * Removes role from the given user.
     *
     * @param string $username
     * @param string $role
     *
     * @return Boolean true if role was removed, false if user didn't have the role
     */
    public function removeRole($username, $role)
    {
        $user = $this->findUserByUsernameOrThrowException($username);
        if (!$user->hasRole($role)) {
            return false;
        }
        $user->removeRole($role);
        $this->userManager->updateUser($user);

        return true;
    }

    /**
     * Finds a user by his username and throws an exception if we can't find it.
     *
     * @param string $username
     *
     * @return UserInterface
     */
    private function findUserByUsernameOrThrowException($username)
    {
        $user = $this->userManager->findUserByUsername($username);

        if (!$user) {
            throw new \InvalidArgumentException(sprintf('User identified by "%s" username does not exist.', $username));
        }

        return $user;
    }
}


text:
package org.traccar.model;

import java.text.ParseException;

import org.traccar.Context;
import org.traccar.database.QueryIgnore;
import org.traccar.geofence.GeofenceCircle;
import org.traccar.geofence.GeofenceGeometry;
import org.traccar.geofence.GeofencePolygon;
import org.traccar.geofence.GeofencePolyline;

import com.fasterxml.jackson.annotation.JsonIgnore;

public class Geofence extends ScheduledModel {

    public static final String TYPE_GEOFENCE_CILCLE = "geofenceCircle";
    public static final String TYPE_GEOFENCE_POLYGON = "geofencePolygon";
    public static final String TYPE_GEOFENCE_POLYLINE = "geofencePolyline";

    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    private String description;

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    private String area;

    public String getArea() {
        return area;
    }

    public void setArea(String area) throws ParseException {

        if (area.startsWith("CIRCLE")) {
            geometry = new GeofenceCircle(area);
        } else if (area.startsWith("POLYGON")) {
            geometry = new GeofencePolygon(area);
        } else if (area.startsWith("LINESTRING")) {
            final double distance = getDouble("polylineDistance");
            geometry = new GeofencePolyline(area, distance > 0 ? distance
                    : Context.getConfig().getDouble("geofence.polylineDistance", 25));
        } else {
            throw new ParseException("Unknown geometry type", 0);
        }

        this.area = area;
    }

    private GeofenceGeometry geometry;

    @QueryIgnore
    @JsonIgnore
    public GeofenceGeometry getGeometry() {
        return geometry;
    }

    @QueryIgnore
    @JsonIgnore
    public void setGeometry(GeofenceGeometry geometry) {
        area = geometry.toWkt();
        this.geometry = geometry;
    }
}

redpajama_set_name: RedPajamaGithub


text:
<!doctype html>

	<meta charset="utf-8">

	<title>Angular 2 and Material Design</title>

	<meta name="author" content="Gaétan Collaud">

	<meta name="apple-mobile-web-app-capable" content="yes"/>
	<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent"/>

	<meta name="viewport"
		  content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, minimal-ui">

	<link rel="stylesheet" href="../reveal.js-3.3.0/css/reveal.css">
	<link rel="stylesheet" href="../reveal.js-3.3.0/lib/css/zenburn.css">
	<link rel="stylesheet" href="../reveal.js-3.3.0/css/theme/night.css" id="theme">
	<link rel="stylesheet"
		  href="http://slidifylibraries2.googlecode.com/git/inst/libraries/widgets/bootstrap/css/bootstrap.css">

Angular 2 and MaterialDesign

In VideoProtector

				Gaétan Collaud / Morphean SA

Summary

Angular2

Material Design

Solutions tested

Angular2 material design

Polymer

Bootstrap material design

Final solution

Demo

Angular 2

Developed in Typescript

Components, no more directives
 and controllers

no more $scope

New dependency injection

New router

RxJs (Observable & cie)

Material design

Specifications and guide lines

Developed by google (2014)

Mobile oriented

Rapidly used in Android and new
Google application (Maps, Inbox, ...)

material.google.com

Examples

Solutions tested

Angular2 material design
 - library

Polymer
 - framework

Bootstrap material design
 - extension of bootstrap

Angular 2 material

Pros

Library by google

Very good integration
with Angular 2

Cons

In Alpha

Too few components

material.angular.io

Polymer

Pros

Lots of components

Developed by Google

Work with Angular 2

Cons

Half suported by Firefox

Don't even ask about IE...

www.polymer-project.org

Bootstrap Material design

Pros

Use Boostrap elements

Nothing new to learn

Cons

Conflict with liferay CSS

We must trigger JS
functions from angular

github.com/FezVrasta/bootstrap-material-design

Final solution (1/2)

Angular 2 (with typescript)

Boostratp Material design

Iframe in liferay

Final solution (2/2)

Gulp as build system

Standalone development

Override LocationStrategy

						/web/guest/customers

Override PlatformLocation

						iframe location

Questions ?

Demo

localhost:3000 (standalone)

integration.videoprotector.com/customers (in liferay)


text:
@class NSMutableArray;

@interface IMAPDownload : NSObject
{
    unsigned int _uid;
    NSMutableArray *_pendingFetchResults;
}

- (void)dealloc;
- (id)initWithUid:(unsigned int)arg1;
- (id)init;
- (id)createCopy;
- (unsigned int)uid;
- (unsigned int)expectedLength;
- (BOOL)isComplete;
- (unsigned int)bytesFetched;
- (id)data;
- (id)error;
- (void)setError:(id)arg1;
- (void)handleFetchResult:(id)arg1;
- (void)processResults;
- (void)addCommandsToPipeline:(id)arg1 withCache:(id)arg2;
- (id)description;

@end


text:
from __future__ import unicode_literals
from future import standard_library
standard_library.install_aliases()
from builtins import object

import threading

class TaskManager(object):
    """ Multi threading manager """

    def __init__(self):
        """ Initializes a TaskManager

        """
        self.threads = list()

    def wait_until_exit(self):
        """ Wait until all the threads are finished.

        """
        [t.join() for t in self.threads]

        self.threads = list()

    def start_task(self, method, *args, **kwargs):
        """ Start a task in a separate thread

            Args:
                method: the method to start in a separate thread
                args: Accept args/kwargs arguments
        """
        thread = threading.Thread(target=method, args=args, kwargs=kwargs)
        thread.is_daemon = False
        thread.start()
        self.threads.append(thread)


text:
var currentBugNumber;
var markerClass = 'lphelper-marked';

var bugLastUpdatedImportanceClasses = [
    {olderThan: moment.duration(1, 'month'), importance: 'critical'},
    {olderThan: moment.duration(2, 'weeks'), importance: 'high'},
    {olderThan: moment.duration(1, 'week'), importance: 'medium'}
];

var calculateImportanceFromLastUpdated = function (last_updated) {
    var now = moment(),
        diff = now.diff(moment(last_updated)) / 1000;

    for (var i = 0; i < bugLastUpdatedImportanceClasses.length; i++) {
        var obj = bugLastUpdatedImportanceClasses[i];
        if (diff >= obj.olderThan.asSeconds()) {
            return obj.importance;
        }
    }
};

var tooltipsterOptions = function() {
    return {
        contentAsHTML: true,
        interactive: true,
        interactiveTolerance: 1000,
        maxWidth: 600,
        onlyOne: true,
        position: 'right',
        theme: 'tooltipster-light',
        updateAnimation: false
    }
};

var TooltipFunctions = {
    bugTitle: function(bugnumber, owner, assignees) {
        return 'Bug: ' + bugnumber +
            '
Owner: ' + HTMLHelpers.makeUserLink(owner) +
            '
Assignees: ' + assignees.join(', ');
    },
    formatAssignee: function(entry) {
        var assignee = URLHelpers.usernameFromURL(entry.assignee_link);
        if (assignee) {
            assignee = HTMLHelpers.makeUserLink(assignee);
        } else {
            assignee = 'None';
        }

        return assignee + ' ' + HTMLHelpers.importanceSpan('[' + entry.bug_target_name + ']', entry.importance);
    },
    bug: function () {
        var $el = $(this),
            $ela = $el.attr('href') ? $el : $el.find('a'),
            bugnumber = URLHelpers.bugNumberFromURL($ela.attr('href')),
            url = URLHelpers.launchpadApi.bug(bugnumber);

        if ((bugnumber === null) || (bugnumber == currentBugNumber) || ($el.hasClass(markerClass))) {
            return;
        }

        $el.addClass(markerClass);

        $.ajax({
            method: 'GET',
            url: url,
            headers: {'Content-Type': 'application/json'},
            cache: true
        }).done(function (response) {
            HTMLHelpers.clearLastUpdatedSpan($ela);
            var $lastUpdatedSpan = HTMLHelpers.lastUpdatedSpan(response);
            $ela.prepend($lastUpdatedSpan);

            // Save on requests, fetch tasks lazily
            $ela.one('mouseenter', function () {
                $.ajax({
                    method: 'GET',
                    url: response.bug_tasks_collection_link,
                    headers: {'Content-Type': 'application/json'},
                    cache: true
                }).done(function (responseBugTasks) {
                    var opts = tooltipsterOptions();

                    var assignees = $.map(responseBugTasks.entries, TooltipFunctions.formatAssignee);
                    var owner = URLHelpers.usernameFromURL(response.owner_link);
                    var title = TooltipFunctions.bugTitle(bugnumber, owner, assignees);
                    var description = response.description.replace(/\n/g, '
');
                    description = HTMLHelpers.urlify(description);

                    $ela.tooltipster(opts);
                    $ela.tooltipster('content', HTMLHelpers.formatTooltip(title, description));
                    $ela.tooltipster('show');
                });
            });
        });
    },

    person: function () {
        var $el = $(this),
            href = $el.attr('href'),
            username = URLHelpers.usernameFromURL(href),
            url = URLHelpers.launchpadApi.userSuperTeams(username);

        if($el.hasClass(markerClass)) {
            return;
        }

        $el.addClass(markerClass);

        $.ajax({
            method: "GET",
            url: url,
            headers: {'Content-Type': 'application/json'},
            cache: true
        }).done(function (response) {
            var teams, html;

            response.entries.sort(function (e1, e2) {
                return e1.display_name.localeCompare(e2.name);
            });
            teams = $.map(response.entries, function (entry) {
                return '
' + HTMLHelpers.link(entry.web_link, entry.display_name) + '
';
            });
            html = '
Teams
';
            html += teams.join('');

            $.ajax({
                method: "GET",
                url: URLHelpers.launchpadApi.userBugTasks(username),
                headers: {'Content-Type': 'application/json'},
                cache: true
            }).done(function(personBugTasks) {
                var bugs = $.map(personBugTasks.entries, TooltipFunctions.personBugTask);
                $el.tooltipster(tooltipsterOptions());
                html += '
Bugs [' + bugs.length + '] (' + HTMLHelpers.link(URLHelpers.launchpad.user(username), 'More details') + ')
';
                html += bugs.join('');
                $el.tooltipster('content', HTMLHelpers.formatTooltip(username, html));
                $el.tooltipster('show');
            });
        }).fail(function (r) {
            console.log('error', r.status, r.statusText);
        });
    },
    personBugTask: function(bugTask) {
        return '
' + HTMLHelpers.link(bugTask.bug_link, LaunchpadHelpers.formatBugTaskTitle(bugTask)) + '
';
    }
};

var PageHelpers = {
    person: function() {
        var username = URLHelpers.usernameFromURL(window.location.href);
        var $footer = $('#footer');

        return $.ajax({
            method: 'GET',
            url: URLHelpers.launchpadApi.userBugTasks(username),
            headers: {'Content-Type': 'application/json'},
            cache: true
        }).done(function(personBugTasks) {
            var $bugsHtml = $('

');
            var $clientBugs = $('

');
            var $listingClientBugs = $('

');
            $.each(personBugTasks.entries, function(idx, bugEntry) {
                $listingClientBugs.append(
                    HTMLHelpers.formatBugRow({
                        bug_target_display_name: bugEntry.bug_target_display_name,
                        importance: bugEntry.importance,
                        link: bugEntry.web_link,
                        status: bugEntry.status,
                        title: LaunchpadHelpers.formatBugTaskTitle(bugEntry)
                    })
                );
            });
            $clientBugs.append($listingClientBugs);
            $bugsHtml.append($clientBugs);
            $footer.before('
Bugs [' + personBugTasks.entries.length + ']
 ' + $bugsHtml.html());
        });
    }
};

currentBugNumber = URLHelpers.bugNumberFromURL(window.location.href);

var noMarkerClassSelector = function() {
    return ':not(.' + markerClass + ')';
};

var generateTooltips = function() {
    // Person info
    $(document).find('a.sprite.person').filter(noMarkerClassSelector()).one('mouseenter', TooltipFunctions.person);
    $(document).find('a:has(.sprite.person)').filter(noMarkerClassSelector()).one('mouseenter', TooltipFunctions.person);

    // Bug info
    $('#bugs-table-listing').find('.buglisting-row .buginfo').filter(noMarkerClassSelector()).each(TooltipFunctions.bug);
    $(document).find('a[href*="bugs.launchpad.net"]').filter(noMarkerClassSelector()).each(TooltipFunctions.bug);

    setTimeout(generateTooltips, 1000);
};

$(document).ready(function() {
    if(URLHelpers.isPersonPage()) {
        PageHelpers.person().done(generateTooltips);
    } else {
        generateTooltips();
    }
});


text:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>
  Module: InvoicePrinter

    — Documentation by YARD 0.8.2.1

</title>

  <link rel="stylesheet" href="css/style.css" type="text/css" media="screen" charset="utf-8" />

  <link rel="stylesheet" href="css/common.css" type="text/css" media="screen" charset="utf-8" />

    Index (I) »

    InvoicePrinter

(no frames)

      Class List

      Method List

      File List

Module: InvoicePrinter

Includes:

ActionView::Helpers::NumberHelper, MainPrinter

Included in:

Admin::Document::InvoicesController

Defined in:

lib/printing/invoice_printer.rb

      Instance Method Summary
      (collapse)

      - (Object) new_page(pdf, invoice, start_new_page = true)

      - (Object) order_specific_details(pdf, invoice)

      - (Object) print_bounding_box(pdf, invoice, pdf_info)

      - (Object) print_form(order_invoice)

      - (Object) print_invoice_background(pdf, png_background = "#{Rails.root}/public/images/invoice_template.png")

end of print_form method.

      - (Object) print_order_invoice_form(pdf, invoice, file_to_load = "#{Rails.root}/lib/printing/x_y_locations/invoice.yml")

Methods included from MainPrinter

#check_box, #checker_background, #checker_form, #print_line, #print_lines

Instance Method Details

    - (<tt>Object</tt>) new_page(pdf, invoice, start_new_page = true)

53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75

# File 'lib/printing/invoice_printer.rb', line 53

def new_page(pdf, invoice, start_new_page = true)
  pdf.start_new_page() if start_new_page
  pdf.font "#{Rails.root}/lib/printing/fonts/DejaVuSans.ttf"
  print_invoice_background(pdf)

  pdf.bounding_box([0,400], :width => 612) do
    @invoice_yml.each do |info|
      if info.last['multiple_lines']
        pdf.bounding_box(   [  info.last['arguements']['bounded_at'][0].to_i,
                              info.last['arguements']['bounded_at'][1].to_i
                            ],
                              :width => info.last['arguements']['bounded_by'][0].to_i,
                              :height => info.last['arguements']['bounded_by'][1].to_i
                            ) do

          print_lines(pdf, invoice.send(info.last['method'].to_sym) )
        end
      else
        print_line(pdf, invoice.send(info.last['method'].to_sym), info.last )
      end
    end
  end
end

    - (<tt>Object</tt>) order_specific_details(pdf, invoice)

38
39
40
41
42
43
44
45
46
47
48
49
50
51

# File 'lib/printing/invoice_printer.rb', line 38

def order_specific_details(pdf, invoice)
  invoice.order.order_items.each_with_index do |item, i|
    new_page(pdf, invoice) if ((i) % 3) == 0 && i > 1
    pdf.draw_text item.variant.product_name,      {:at => [130, 420 - (i * 50) ]}
    pdf.draw_text number_to_currency(item.price), {:at => [470, 420 - (i * 50) ]}
  end
  invoice.order.shipping_rates.each_with_index do |shipping_rate, i|
    pdf.draw_text 'Shipping',      {:at => [130, 270 - (i * 15) ]}
    pdf.draw_text shipping_rate.rate,      {:at => [470, 270 - (i * 15) ]}
  end
  pdf.draw_text invoice.order.total_tax_charges,      {:at => [480, 175], :size => 10 }

end

    - (<tt>Object</tt>) print_bounding_box(pdf, invoice, pdf_info)

77
78
79
80
81
82
83
84
85
86

# File 'lib/printing/invoice_printer.rb', line 77

def print_bounding_box(pdf, invoice, pdf_info)
  pdf.bounding_box( [ pdf_info['arguements']['bounded_at'][0].to_i,
                      pdf_info['arguements']['bounded_at'][1].to_i
                    ],
                    :width  => pdf_info['arguements']['bounded_by'][0].to_i,
                    :height => pdf_info['arguements']['bounded_by'][1].to_i
                  ) do
      pdf.text invoice.send( pdf_info['arguements']['method'].to_sym )
  end
end

    - (<tt>Object</tt>) print_form(order_invoice)

6
7
8
9
10
11
12

# File 'lib/printing/invoice_printer.rb', line 6

def print_form(order_invoice)
  document = Prawn::Document.new do |pdf|
    print_order_invoice_form(pdf, order_invoice)
    pdf#.render#_file card_name
  end # end of Prawn::Document.generate
  return document
end

    - (<tt>Object</tt>) print_invoice_background(pdf, png_background = "#{Rails.root}/public/images/invoice_template.png")

end of print_form method

14
15
16
17
18
19
20
21
22
23
24
25
26
27

# File 'lib/printing/invoice_printer.rb', line 14

def print_invoice_background(pdf, png_background = "#{Rails.root}/public/images/invoice_template.png")
  pdf.bounding_box([10,730], :width => 530) do
    pdf.image png_background, :width => 519 if png_background
  end
  begin
    pdf.bounding_box([20,720], :width => 120) do
      pdf.image "#{Rails.root}/public/images/logos/#{Image::MAIN_LOGO}"
    end
  rescue
    pdf.bounding_box([20,720], :width => 120) do
      pdf.draw_text "LOGO", {:size => 32, :at => [100, 100]}
    end
  end
end

    - (<tt>Object</tt>) print_order_invoice_form(pdf, invoice, file_to_load = "#{Rails.root}/lib/printing/x_y_locations/invoice.yml")

29
30
31
32
33
34
35
36

# File 'lib/printing/invoice_printer.rb', line 29

def print_order_invoice_form( pdf,
                            invoice,
                            file_to_load = "#{Rails.root}/lib/printing/x_y_locations/invoice.yml" )

  @invoice_yml    = YAML::load( File.open( file_to_load ) )
  new_page(pdf, invoice, false)
  order_specific_details(pdf, invoice)
end

  Generated on Sun Jul 15 15:24:22 2012 by
  yard
  0.8.2.1 (ruby-1.9.3).


text:
import re, os
from jpy.util import expand, match_groups
from jpy.asrt import *

# Regex for values (e.g. "mykey = myval")
VALUE_REGEX = re.compile('\s*([^\s]+)\s*=\s*(.*)\s*')

# Comment regex (e.g. "# some comment")
COMMENT_REGEX = re.compile('^\s*#')

# Import regex (e.g. "import somefile")
IMPORT_REGEX = re.compile('^import (.+)$')

# Used to match trailing slashes (for line-continuation)
NEWLINE = re.compile('.*(\\\\[\\r\\n]+)$')

def convert_to_bool(s):
    """Intelligently converts a string to a bool.
    All of 'yes', 'true', 'on', '1' convert to True.
    All of 'no', 'false', 'off', '0' convert to False.
    """
    # values for booleans
    TRUE = [ 'yes', 'true', 'on', '1' ]
    FALSE = [ 'no', 'false', 'off', '0' ]

    t = type(s)

    # deliberately don't handle None as we want to preserve
    # the distinction between a bool being set and not being set

    if t is bool:
        return s

    elif t in [list, tuple]:
        if len(s) == 0: return False
        s = s[0].lower()

    # if we get here it must be a string, otherwise die
    asrt(t in [str, str])
    if s in TRUE: return True
    elif s in FALSE: return False

    else: raise ValueError('invalid boolean value: ' + str(s))

def convert_value(value, val_type):
    """Convert the given value to the correct type as determined
    by config_value. Assumes that value is a string."""
    # deliberately public so that other modules can call this

    # always preserve None-ness
    if value == None: return None

    # handle bools especially
    if val_type == bool:
        return convert_to_bool(value)
    else:
        return val_type(value)

class ConfigFile(object):
    def __init__(self, config_file, defaults = {},
                 must_exist = True, config_values = None):
        """Initialise the ConfigFile.

        config_file is the path to a file that we can parse.
        defaults is an optional dict of default key->value
            pairs to use (added into the config file after the
            file is loaded for unset keys)
        must_exist, if false, allows you to create a blank
            ConfigFile, in which case config_file doesn't need
            to exist.
        config_values, if specified, should be a list of
          ConfigValue instances, which provide configuration
          for settings which will be stored in this ConfigFile.

        If config_values is specified:
        - all settings in files loaded into the ConfigFile
          must have a corresponding ConfigValue with the same
          name
        - all return values of get() will be converted according
          to the corresponding ConfigValue's val_type
        - default values will be returned by get() if the
          setting requested is not present and the corresponding
          ConfigValue has a default_value set
        """
        self.items_dict = {}
        self.must_exist = must_exist

        self.config_values = None
        if config_values:
            self.config_values = { x.name.lower(): x for x in config_values }

        # store values in a list too so that we get ordering?
        self.items = []

        self.config_file = config_file
        self.defaults = defaults

        # store the lines in the config file (just the ones
        # directly in this file, not imported files) so that
        # we can save the file back as it was when set() is called
        self.lines = []

        # dict of key -> line number (mapping to items in self.lines)
        # so that set() is able to modify values in specified lines.
        # this dict will not contain mappings for blank lines or comments
        self.line_numbers = {}

        self._read_file()

    def _read_file(self):
        if not self.config_file: return

        exists = os.path.exists(self.config_file)
        if not exists and self.must_exist:
            raise ValueError('file does not exist: ' + \
                             self.config_file)

        if exists:
            previous_line = None

            line_number = -1
            for line in open(self.config_file, 'r'):
                line_number += 1
                self.lines.append(line.rstrip('\n\r'))
                asrt_eq(len(self.lines)-1, line_number)

                if previous_line != None:
                    line = previous_line + line.lstrip()
                    previous_line = None

                newline_match = match_groups(NEWLINE, line)
                if newline_match:
                    previous_line = line[:-len(newline_match[0])]
                    continue

                if line.strip() == '':
                    continue

                comment_match = COMMENT_REGEX.match(line)
                value_match = VALUE_REGEX.match(line)
                import_match = IMPORT_REGEX.match(line)

                if comment_match != None:
                    # Ignore as this line is a comment line
                    pass

                elif value_match != None:
                    groups = value_match.groups()
                    self._set_attr(groups[0], groups[1])

                    self.line_numbers[groups[0]] = line_number

                elif import_match != None:
                    groups = import_match.groups()

                    c = ConfigFile(expand(groups[0]))
                    self.import_configfile(c)

                else:
                    raise ValueError('Line "' + line + \
                                     '" in file "' + self.config_file + \
                                     '" is not in the right format')

        for (k, v) in list(self.defaults.items()):
            if not self.has(k):
                self._set_attr(k, v)

    def import_configfile(self, configfile, overwrite = False):
        """Import the items in another configfile into this configfile

        If overwrite is True, any values that exist in this
        instance and also in configfile are overwritten by the ones in
        configfile. if overwrite is False, the values in this instance
        are preserved.
        """
        asrt(type(configfile) is ConfigFile, 'configfile must be a ConfigFile instance (was ' + str(type(configfile)) + ', ' + str(configfile) + ')')

        for name, value in list(configfile.get_all().items()):
            if self.has(name) and not overwrite: continue

            self._set_attr(name, value)

    def _set_attr(self, name, value):
        if name.startswith('_'):
            raise ValueError('Bad property name "' + name + '", cannot set attributes starting with _')

        cv = self.get_configvalue(name)
        if cv:
            value = convert_value(value, cv.val_type)

        self.items_dict[name] = value

    def get_configvalue(self, name):
        """look up a ConfigValue

        returns None if ConfigValues have not been set for this ConfigFile
        """
        if not self.config_values: return None

        n = name.lower()
        if not n in list(self.config_values.keys()):
            raise ValueError('Error in ' + self.config_file + ', property "' + name + '" invalid; no corresponding ConfigValue')

        return self.config_values[n]

    def get(self, name, val_type = None):
        """Retrieve a setting from the ConfigFile.

        If this ConfigFile has been configured with ConfigValues,
        and the corresponding ConfigValue for `name` has a default_value
        set, that value is returned if it does not exist in the ConfigFile.

        val_type can be specified, in which case the type of the value
        returned can be specified. This is most useful in cases where
        ConfigValues are being used to specify different datatypes; val_type
        can be specified to make the code more readable and to give you
        assurance that you'll get a certain type back.
        NB In practice setting val_type does not cause conversions to be
        performed. If set, the val_type is compared with the actual return
        type and an exception is thrown if they do not match.
        """
        result = None

        if name in self.items_dict:
            result = self.items_dict[name]
        else:
            cv = self.get_configvalue(name)
            if cv: result = cv.default_value

        # validate type against val_type
        if val_type and (val_type != type(result)):
            raise ValueError('Value for "' + name + '" is wrong type.' + \
                             'Expected: ' + str(val_type) + ', actual: ' + str(type(result)))

        return result

    def get_bool(self, name):
        """get as a boolean."""
        if not self.has(name): return False

        s = self.get(name)
        return convert_to_bool(s)

    def has(self, name):
        return name in self.items_dict

    def get_single(self, name):
        """Get a single property by name. An exception is thrown
        if more than one property by this name exists"""
        result = self.get_list(name)
        if len(result) > 1:
            raise ValueError('More than one value has been assigned for setting ' + name)

        # values are already unpacked by get_list()
        return result[0]

    def get_all(self, prefix=None):
        """Get all properties. (Meaning only those defined; for example, those
        where defaults have been set are *not* included in the return value
        for this method.)

        If prefix is specified, only return those with that prefix"""
        if prefix is None:
            return dict(self.items_dict)

        else:
            result = {}
            prefixl = prefix.lower()

            for (k, v) in list(self.items_dict.items()):
                if k.lower().startswith(prefixl):
                    result[k] = v

            return result

    def set(self, key, value, write = True):
        """set a value in the config file and write the config file to disk

        if write is False, do not write to disk, just keep the new value in
        memory"""
        cv = self.get_configvalue(key)
        self._set_attr(key, value)

        line_number = self.line_numbers.get(key)

        new_line = '%s = %s' % (key, value)

        if line_number is not None:
            self.lines[line_number] = new_line
        else:
            self.lines.append('')
            self.lines.append(new_line)
            self.line_numbers[key] = len(self.lines)-1

        if write:
            with open(self.config_file, 'w') as f:
                for line in self.lines:
                    f.write(line)
                    f.write('\n')

    def set_with_dict(self, values, write = True):
        """set several values in the config file and write the config file to disk

        if write is False, do not write to disk, just keep the new value in
        memory
        values should be a dict consisting of keys->values to write
        """
        for key, value in list(values.items()):
            cv = self.get_configvalue(key)
            self._set_attr(key, value)

            line_number = self.line_numbers.get(key)

            new_line = '%s = %s' % (key, value)

            if line_number is not None:
                self.lines[line_number] = new_line
            else:
                self.lines.append('')
                self.lines.append(new_line)
                self.line_numbers[key] = len(self.lines)-1

        if write:
            with open(self.config_file, 'w') as f:
                for line in self.lines:
                    f.write(line)
                    f.write('\n')

class ConfigValue(object):
    """Represents a configuration value (or rather, the configuration
    of that configuration value)."""
    def __init__(self, name, default_value = None, val_type = str):
        self.name = name
        self.default_value = default_value
        self.val_type = val_type

        # ensure the ConfigValue's default_value is the right type
        if type(self.default_value) != self.val_type:
            self.default_value = convert_value(self.default_value, self.val_type)


text:
"""
JSONSchema to Unimodel model_schema (basically Unimodel AST) converter.
This class will create a ModelSchema object from a jsonschema definition.
ModelSchema object can then be used to compile python code or thift IDL.

There's actually a fundamental mismatch here between encoding-oriented
IDLs like thrift or Unimodel and validation languages like jsonschema.
The latter is perfectly happy saying "there may be additional fields here
which I know nothing about", while the former isn't.

So something like this has no Thrift equivalent:
    {
        "type": "object",
        "properties": {},
        "additionalProperties": true
    }

Unimodel has the JSONData field for these cases.

Other mismatches:

anyOf, allOf, oneOf
---
These keywords combine several types. They are represented in Unimodel
as a struct where each field has one of these values. The JSON metadata
for the struct indicates that it should be "unpacked", so allOf or oneOf
results in the fields of the referenced types being present in the JSON
directly (without the parent type).
anyOf is also represented as a struct (a union), but the json reader has
to try to match all the fields in the struct individually and move on
to the next candidate if the current field does not match. Only of the
fields should match the incoming data.

tuples
---
Thrift and Unimodel considers a list a collection of elements each
with one type. Jsonschema offer tuples:
{
    "type": "array",
    "items": [
        {
            "type": "boolean"
        },
        {
            "type": "integer"
        },
        {
            "type": "string"
        }
    ],
}

Unimodel also has tuples (a struct is generated with a field names
derived from the tuple element types). It is also possible to have
additional elements in the tuple with the "additionalItems" keyword:

    "additionalItems": {
        "type": "boolean",
        "default": false
    }

In Unimodel, this becomes an unboxed struct where the first field is the tuple,
and the second field is a list of elements of the type declared in the
"additionalItems" definition.

Reserved field names
---
Field names which are reserved words, or simply invalid fieldnames in python
(eg: $ref, /path/, public) are renamed to something that python can deal with,
but the field's metadata contains the original field name so read-writing
JSON still works.

Root struct
---
Jsonschema describes a DAG, Unimodel describes a set of structs. In order
to reproduce the json structure, a Root struct is created (typically named
Root unless that collides with something).
"""

import json
import jsonschema
from unimodel.schema import *
from unimodel import types
from jsonschema.validators import RefResolver
from unimodel.util import is_str

# Thanks to Randy Abernethy for the list of reserved keywords
RESERVED_NAMES = """BEGIN END __CLASS__ __DIR__ __FILE__ __FUNCTION__ __LINE__
__METHOD__ __NAMESPACE__ abstract alias and args as assert begin break case
catch class clone continue declare def default del delete do dynamic elif else
elseif elsif end enddeclare endfor endforeach endif endswitch endwhile ensure
except exec finally float for foreach function global goto if implements import
in inline instanceof interface is lambda module native new next nil not or pass
public print private protected public raise redo rescue retry register return
self sizeof static super switch synchronized then this throw transient try
undef union unless unsigned until use var virtual volatile when while with xor
yield""".split()
REF_TEMPLATE = "%(base_uri)s/definitions/%(name)s"  # base_uri ends in '#'
DEFAULT_ARRAY_ITEMS = {'type': 'string'}

def walk_json(json_obj, key=""):
    def append_key(prefix, postfix):
        return "%s.%s" % (prefix, postfix)
    if isinstance(json_obj, dict):
        for k, v in json_obj.items():
            for pair in walk_json(v, append_key(key, str(k))):
                yield pair
    elif isinstance(json_obj, list):
        for i in xrange(0, len(json_obj)):
            for pair in walk_json(json_obj[i], append_key(key, str(i))):
                yield pair
    yield (key, json_obj)

class Reference(object):
    REF_ATTR = '$ref'

    def __init__(self, obj):
        self.ref = obj[Reference.REF_ATTR]

    @classmethod
    def is_ref(cls, obj):
        return isinstance(obj, dict) and Reference.REF_ATTR in obj

    @classmethod
    def make_absolute(cls, base_uri, ref):
        if is_str(ref) and ref.startswith('#'):
            real_base_uri = base_uri
            if real_base_uri.endswith('#'):
                real_base_uri = base_uri[:-1]
            return "%s%s" % (real_base_uri, ref)
        return ref

    @classmethod
    def replace_relative_references(cls, base_uri, json_value):
        # TODO
        for _path, value in walk_json(json_value):
            if isinstance(value, dict) and Reference.REF_ATTR in value:
                value[Reference.REF_ATTR] = cls.make_absolute(
                    base_uri, value[Reference.REF_ATTR])
        return json_value

    def resolve(self, refresolver):
        with refresolver.resolving(self.ref) as res:
            if self.is_ref(res):
                ref = Reference(res)
                return ref.resolve(refresolver)
            # It's not enough to call replace_relative_references when
            # the schema is loaded, because resolve() may be pulling in
            # fragments from other JSON documents, thus it may contain
            # relative references.
            return self.replace_relative_references(refresolver.base_uri, res)

class JSONSchemaModelGenerator(object):
    # From:
    # github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md#data-types
    # Name     type    format    Comments
    # --       --      --        --
    # integer  integer int32     signed 32 bits
    # long     integer int64     signed 64 bits
    # float    number  float
    # double   number  double
    # string   string
    # byte     string  byte
    # boolean  boolean
    # date     string  date      As defined by full-date - RFC3339
    # dateTime string  date-time As defined by date-time - RFC3339

    # Maps (type, format) -> (unimodel type name, type constructor class)
    # based on the table above. Unimodel names take from
    # unimodel.schema.type_id_enum
    JSON_TO_UNIMODEL_TYPE = {
    #   type        format       unimodel type
        ('integer', None):       'int64',
        ('integer', 'int32'):    'int32',
        ('integer', 'int64'):    'int64',
        ('number', None):        'double',
        ('number', 'float'):     'double',
        ('number', 'double'):    'double',
        ('string', None):        'utf8',
        ('string', 'byte'):      'binary',
        ('string', 'date'):      'utf8', # TODO: make this a date UTF8 subclass
        ('string', 'date-time'): 'utf8', # TODO: make this a date-time UTF8 subclass
        ('string', 'uri'):       'utf8', # TODO: make this a URI UTF8 subclass
        ('string', 'email'):     'utf8', # TODO: make this an email UTF8 subclass
        ('string', 'regex'):     'utf8', # TODO: make this an email UTF8 subclass
        ('boolean', None):       'bool',
        ('array', None):         'list',
        # 'object' can mean map or struct, but structs are
        # listed directly under 'definitions', everywhere else,
        # they are $ref'd.
        ('object', None):        'map'
        # Enums have the 'string' type in jsonschema. An additional
        # 'enum' property identifies them as such.
    }

    def __init__(self, name, schema):
        self.name = name
        self.base_uri = schema.get('id', '')
        # replace all relative references with absolute refs to avoid
        # clashes in self.definitions
        self.schema = Reference.replace_relative_references(self.base_uri, schema)
        # maps full jsonschema fragment path to internal structure,
        # for example a StructDef or a TypeDef.
        self.definitions = {}
        self.refresolver = RefResolver.from_schema(schema)

    def is_defined(self, name):
        return name in self.definitions

    def generate_enum(self, definition):
        enum = definition['enum']
        return TypeDef(type_class=TypeClass(
            enum=dict(zip(
                xrange(0, len(enum)),
                enum))))

    def generate_type_def(self, definition):
        """ Generates a TypeDef object based on a
            JSONSchema definition. """
        # we should always be getting a dict
        assert isinstance(definition, dict)
        if 'enum' in definition:
            return self.generate_enum(definition)
        if 'type' not in definition:
            raise Exception(
                "Cannot process type definition %s" %
                json.dumps(definition))
        json_type = definition['type']
        json_format = definition.get('format', None)
        type_name = self.JSON_TO_UNIMODEL_TYPE[(json_type, json_format)]
        type_id = type_id_enum.name_to_key(type_name)
        # note: type_name will never be "struct" because
        # struct objects are already defined by this point in the code.
        assert not type_name == "struct"
        # note: maps are generated by generate_map
        assert not type_name == "map"
        if type_name == "list":
            # eg: {u'uniqueItems': True, u'items': {u'$ref':
            # u'#/definitions/mimeType'}, u'type': u'array'}
            if definition.get('uniqueItems', False):
                type_id = type_id_enum.name_to_key("set")
            return TypeDef(
                type_class=TypeClass(
                    parametric_type=ParametricType(
                        type_id=type_id,
                        type_parameters=[
                            self.get_field_type(
                                definition.get(
                                    'items',
                                    DEFAULT_ARRAY_ITEMS))])))
        # primitive type
        return TypeDef(type_class=TypeClass(primitive_type_id=type_id))

    def generate_map(self, name, definition):
        # There are 4 different thing we could return:
        # 1: A Map. This is what we return if
        #    additionalProperties or patternProperties
        #    gives a type, and there is no 'properties' field
        # 2: A Struct (unbox) composed of a Map and a Struct.
        #    additionalProperties or patternProperties
        #    gives a type, and there is a 'properties' field.

        return TypeDef(
            type_class=TypeClass(
                parametric_type=ParametricType(
                    type_id=type_id_enum.name_to_key("map"),
                    type_parameters=[
                        self.generate_type_def({"type": "string"}),
                        self.generate_type_def({"type": "string"})])))

    def get_field_type(self, definition):
        field_type_obj = self.process_definition(None, definition)
        # if field_type_obj is a StructDef, we need to convert it
        # to a TypeDef object.
        if isinstance(field_type_obj, StructDef):
            # for StructDefs, we need to create the proper TypeDef object.
            field_type_obj = TypeDef(
                type_class=TypeClass(
                    struct_name=field_type_obj.common.name))
        if isinstance(field_type_obj, Literal):
            # default values result in Literals being returned by
            # process_definition. In such cases we just return None
            return None
        assert isinstance(field_type_obj, TypeDef)
        return field_type_obj

    def generate_field(self, name, definition, required=False):
        field_def = FieldDef(
            field_type=self.get_field_type(definition),
            common=SchemaObject(name=self.relative_name(name)),
            required=required)
        return field_def

    def generate_struct(self, name, definition, struct_def):
        struct_def.common = SchemaObject(name=self.relative_name(name))
        struct_def.fields = []
        required_fields = definition.get('required', [])
        for field_name, field_definition in definition.get(
                'properties', {}).items():
            field_def = self.generate_field(
                field_name,
                field_definition,
                field_name in required_fields)
            struct_def.fields.append(field_def)
        return struct_def

    @classmethod
    def ensure_nonexisting(cls, original_name, existing_names=None):
        existing_names = [] if existing_names is None else existing_names
        name = original_name
        counter = 0
        while name in existing_names or name in RESERVED_NAMES:
            name = "%s%s" % (original_name, counter)
            counter += 1
        existing_names.append(name)
        return name

    @classmethod
    def relative_name(cls, full_name):
        """ turns #/definitions/X into X """
        if full_name is None:
            import pdb;pdb.set_trace()
        return full_name.split("/")[-1]

    def field_name_from_type(self, field_type, existing_names=None):
        # primitive types
        if field_type.type_class.primitive_type_id is not None:
            return self.ensure_nonexisting(type_id_enum.key_to_name(
                field_type.type_class.primitive_type_id), existing_names)
        if field_type.type_class.enum is not None:
            return self.ensure_nonexisting('enum', existing_names)
        if field_type.type_class.struct_name is not None:
            return self.ensure_nonexisting(field_type.type_class.struct_name, existing_names)
        # parametric types
        name_parts = [type_id_enum.key_to_name(
            field_type.type_class.parametric_type.type_id)]
        for t in field_type.type_class.parametric_type.type_parameters:
            name_parts.append(self.field_name_from_type(t))
        return self.ensure_nonexisting("_".join(name_parts), existing_names)

    def get_composite_struct_name(self, composite_struct):
        # TODO: we may have to populate 'existing_names' with short names
        # of currently defined structs.
        return  self.ensure_nonexisting("_".join(["struct"] +
            [self.field_name_from_type(f.field_type) for f in composite_struct.fields]), [])

    def generate_composite_struct(self, definition, composition_type):
        """ generates StructDefs for anyOf, allOf and oneOf """
        # TODO: differentiate based on composition_type:
        # oneOf: type union (formerly called unboxed union)
        # allOf, anyOf: unboxed struct
        field_types_all = [self.get_field_type(d)
                       for d in definition[composition_type]]
        # default value definitions like {'default': 0}
        # result in extra Literal types. get_field_type
        # returns None for them. We can ignore them
        # as long as we don't claim to do jsonschema validation.
        field_types = [f for f in field_types_all if f is not None]
        # if there is only a single field type, there is no need
        # to create a composite struct
        if len(field_types) == 1:
            return field_types[0]
        # generate a name for each field based on its type
        composite_struct = StructDef(fields=[])
        existing_field_names = []
        for field_type in field_types:
            field_name = self.field_name_from_type(
                field_type,
                existing_field_names)
            composite_struct.fields.append(
                FieldDef(
                    common=SchemaObject(name=field_name),
                    required=False,
                    field_type=field_type))
        # name the newly created composite field type
        composite_struct.common=SchemaObject(name=self.relative_name(
            self.get_composite_struct_name(composite_struct)))
        return composite_struct

    def generate_tuple(self, name, definition):
        """ generates StructDefs for anyOf, allOf and oneOf """
        # TODO TypeParams!!!
        return TypeDef(type_class=TypeClass(parametric_type=ParametricType(
            type_id=type_id_enum.name_to_key("tuple"),
            type_parameters=[])))

    def save_type_def(self, name, value):
        if name is not None:
            self.definitions[name] = value
        return value

    def process_definition(self, name, definition):
        """ reads a json definition of some sort, and creates
            the associated object from unimodel.struct. """
        # check if the value is already cached
        if self.is_defined(name):
            return self.definitions[name]
        # default values:
        if definition.keys() == ['default']:
            # TODO: make the 'real' kind of literal
            return Literal(literal_value=LiteralValue(integer=0))
        # empty objects
        if definition == {}:
            return self.save_type_def(
                name,
                StructDef(
                    common=SchemaObject(
                        name=self.relative_name(name)),
                    fields=[]))
        # recursively process references
        if Reference.is_ref(definition):
            ref = Reference(definition)
            if self.is_defined(ref.ref):
                return self.definitions[ref.ref]
            else:
                resolved_definition = ref.resolve(self.refresolver)
                result = self.process_definition(ref.ref, resolved_definition)
                return self.save_type_def(ref.ref, result)
        # Maps and Structs are pretty similar in jsonschema (they're both 'object'
        # values in JSON).
        # Both definitions with additionalProperties and patternProperties
        # could be either a map or the unboxed union of a struct and a map
        if 'patternProperties' in definition or 'additionalProperties' in definition:
            return self.save_type_def(
                name,
                self.generate_map(
                    name,
                    definition))
        # composite structs / unions
        for composition_type in ['allOf', 'oneOf', 'anyOf']:
            if composition_type in definition:
                composite_struct_def = self.generate_composite_struct(
                    definition,
                    composition_type)
                # generate_composite_struct will give a regular TypeDef
                # if only a single field is defined in the composite
                # struct. So despite the name, composite_struct_def
                # isn't always a StructDef.
                if isinstance(composite_struct_def, StructDef):
                    self.save_type_def(
                        self.full_name(composite_struct_def.common.name),
                        composite_struct_def)
                return composite_struct_def
        # tuples
        if 'additionalItems' in definition:
            return self.save_type_def(
                name,
                self.generate_tuple(
                    name,
                    definition))
        # unhandled case (we didn't think of something)
        if 'type' not in definition:
            raise Exception(
                "Unexpected jsonschema element in field %s: %s" %
                (name, json.dumps(definition)))
        # structs
        if definition['type'] == 'object':
            # generate_struct save the type definition itself to handle
            # recursive types
            struct_name = self.relative_name(name)
            self.definitions[name] = StructDef()
            return self.generate_struct(
                struct_name,
                definition,
                self.definitions[name])
        # all other types, which can be handled in a fairly uniform
        # matter: enums, lists, sets, primitive types
        return self.save_type_def(name, self.generate_type_def(definition))

    def full_name(self, name):
        return REF_TEMPLATE % {'base_uri': self.base_uri, 'name': name}

    def generate_model_schema(self):
        # generate models for structs in definitions
        model_schema = ModelSchema(
            common=SchemaObject(name=self.name),
            description=self.schema.get('description', ''))
        # process schema definitions
        for name, definition in self.schema.get('definitions', {}).items():
            self.process_definition(self.full_name(name), definition)
        # process schema root object
        root_name = self.ensure_nonexisting(self.full_name("Root"), self.schema.get('definitions', {}).keys())
        self.process_definition(root_name, self.schema)
        model_schema.root_struct_name = root_name
        model_schema.structs = [
            s for s in self.definitions.values() if isinstance(
                s,
                StructDef)]
        return model_schema


text:
#simpledb-comments

User comments are a drag - so is maintaining a database to hold them. Simpledb-comments allows you to integrate a comments engine that stores data on [AWS SimpleDB](http://aws.amazon.com/simpledb/). It's also not picky about what you use to authenticate users and can be implemented through [Express](http://expressjs.com/) middlewares.

##Simple Example - Submitting a Comment
```
var
  aws                = require('aws-sdk'),
  simpleDbComments   = require('simpledb-comments'),
  comments,
  simpledb;

//setup aws
aws.config.apiVersions = {
  simpledb: '2009-04-15'
};
aws.config.loadFromPath(/* load your credentials */);
simpledb = new aws.SimpleDB({
  region     : 'US-East',
  endpoint   : 'https://sdb.amazonaws.com'
});

//define your configuration
comments = simpleDbComments({
  //pass in your simpledb aws object
  simpledb     : simpledb,
  //tell it what table domain to look in
  tableDomain  : 'comments-sample'
});

//submit a comment
comments.submit({
  username    : 'john-doe',
  commentBody : 'lorem ipsum',
  slug        : 'testItem' , //the slug that identifies your thread
},function(err,results){
  if (err) { throw(err); } else {
    console.log(results);
  }
});
```

##Simple Example - Getting Comments

Do the above configuration and replace `comments.submit` with this:

```
comments.thread({
  slug   : 'testItem',
},function(err,results){
  if (err) { throw(err); } else {
    console.log(results);
  }
});
```

##Example Express server with comments

This is an example implementation of simpledb-comments in an express server. _Note:_ This has no authentication and is thus not something you should throw on a production server, you'll want to tie in whatever type of authentication you're using in your project and pass the username through to simpledb-comments.

```
var
  aws                = require('aws-sdk'),
  simpleDbComments   = require('simpledb-comments'),
  express            = require('express'),
  bodyParser        = require('body-parser'),
  app               = express(),
  threadPath,
  comments,
  simpledb;

aws.config.apiVersions = {
  simpledb: '2009-04-15'
};
aws.config.loadFromPath(/* load your credentials */);
simpledb = new aws.SimpleDB({
  region     : 'US-East',
  endpoint   : 'https://sdb.amazonaws.com'
});

comments = simpleDbComments({
  //this is your configuration object
  simpledb     : simpledb,
  tableDomain  : 'comments-sample'
});

//you need some sort of body parser to get the POST data
app.use(
  bodyParser.urlencoded({
    extended  : true
  })
);

threadPath = 'params.thread'; //the module will look for your thread slug at req.params.thread in this case
app.get(
  '/thread/:thread(\\w+)/:next?', //regexp on the thread param for extra security since this is quoted into the query string.
  //`next` represents the next token if you placed a limit on the number displayed in your original configuration
  comments.middleware.thread(threadPath),
  function(req,res) {
    res.send(req.sdbComments); //by default, the results are placed in req.sdbComments, but you can change this by defining 'commentPath' in your configuration object
  }
);

app.post(
  '/thread/:thread(\\w+)/:username', //your username should come from your authentication/session management system, not from the path. This is just for demonstration.
  comments.middleware.submit(
    threadPath,
    {
        username    : 'params.username', //you can point these object paths to anywhere in the express req
        commentBody  : 'body.commentBody'
    }
  ),
  function(req,res) {
    res.send(req.sdbComments);
  }
)

app.listen(3000);
```

In this example, you can point your browser to http://localhost:3000/thread/your-thread to view the thread as JSON. To post a comment POST to http://localhost:3000/thread/your-thread/your-username to submit a comment. In CURL it would look like: `curl --data "commentBody=test1234567" http://localhost:3000/thread/testItem/john`

To implement a JSON/AJAX based comment system, just expand on the above code and integrate it with the rest of your app. You can also use it as a middleware and then pass it along to a template engine. Be warned, SimpleDB is a slow link and it could make your pages rather slow.


text:
OBJS=font.o vgft.o graphics.o
LIB=libvgfont.a

INCLUDES+=-I$(SDKSTAGE)/usr/include/freetype2 -I$(SDKSTAGE)/usr/include -I$(SDKSTAGE)/usr/include/arm-linux-gnueabi

include ../../Makefile.include


text:
create or replace function get_supplied_item_count( p_bpar_id in number ) return number is
  v_return number;
begin
  select count(1)
    into v_return
    from items_suppliers
   where bpar_id = p_bpar_id;

  return v_return;
end;
/


text:
package org.ttnmapper.ttnmapperv2;

import android.location.Location;

import java.util.ArrayList;

/**
 * Created by jpmeijers on 7-2-17.
 */

public class Packet {
    /*
          "app_id":"jpm_testing",
          "dev_id":"arduino_uno_rn2483",
          "hardware_serial":"00999B8A917DBB71",
          "port":1,
          "counter":123,
          "payload_raw":"IQ==",
          "metadata":{
            "time":"2017-02-07T11:03:29.086549185Z",
            "frequency":868.1,
            "modulation":"LORA",
            "data_rate":"SF7BW125",
            "coding_rate":"4/5",
     */
    String appID;
    String deviceID;

    String time;
    double frequency;
    String modulation;
    String dataRate;
    String codingRate;

    ArrayList<Gateway> gateways = new ArrayList<>();
    double maxRssi = 0;
    double maxSnr = 100;
    double maxDistance = 0;

    double latitude;
    double longitude;
    double altitude;
    double accuracy;
    String provider;
    String mqttTopic;

    public String getModulation() {
        return modulation;
    }

    public void setModulation(String modulation) {
        this.modulation = modulation;
    }

    public String getCodingRate() {
        return codingRate;
    }

    public void setCodingRate(String codingRate) {
        this.codingRate = codingRate;
    }

    public double getMaxRssi() {
        //we assume here that the max rssi only needs to be calculated once
        //as no more gateways will be added than was added at the start
        if (maxRssi == 0) {
            for (Gateway gateway : gateways) {
                if (maxRssi == 0 || gateway.getRssi() > maxRssi) {
                    maxRssi = gateway.getRssi();
                }
            }
        }
        return maxRssi;
    }

    public double getMaxSnr() {
        if (maxSnr == 100) {
            for (Gateway gateway : gateways) {
                if (maxSnr == 100 || gateway.getSnr() > maxSnr) {
                    maxSnr = gateway.getSnr();
                }
            }
        }
        return maxSnr;
    }

    public double getMaxDistance() {
        if (maxDistance == 0) {
            for (Gateway gateway : gateways) {
                double distance = 0;
                if (gateway.getLatitude() == 0 || gateway.getLongitude() == 0 || latitude == 0 || longitude == 0) {
                    distance = 0;
                } else {
                    Location locationA = new Location("");
                    locationA.setLatitude(gateway.getLatitude());
                    locationA.setLongitude(gateway.getLongitude());

                    Location locationB = new Location("");
                    locationB.setLatitude(latitude);
                    locationB.setLongitude(longitude);

                    distance = locationA.distanceTo(locationB);
                }
                if (distance > maxDistance) {
                    maxDistance = distance;
                }
            }
        }
        return maxDistance;
    }

    public ArrayList<Gateway> getGateways() {
        return gateways;
    }

    public void setGateways(ArrayList<Gateway> gateways) {
        this.gateways = gateways;
    }

    public void addGateway(Gateway gateway) {
        if (gateways == null) {
            gateways = new ArrayList<>();
        }
        gateways.add(gateway);
    }

    public String getProvider() {
        return provider;
    }

    public void setProvider(String provider) {
        this.provider = provider;
    }

    public String getTime() {
        return time;
    }

    public void setTime(String time) {
        this.time = time;
    }

    public String getDeviceID() {
        return deviceID;
    }

    public void setDeviceID(String deviceID) {
        this.deviceID = deviceID;
    }

    public double getFrequency() {
        return frequency;
    }

    public void setFrequency(double frequency) {
        this.frequency = frequency;
    }

    public double getLatitude() {
        return latitude;
    }

    public void setLatitude(double latitude) {
        this.latitude = latitude;
    }

    public double getLongitude() {
        return longitude;
    }

    public void setLongitude(double longitude) {
        this.longitude = longitude;
    }

    public String getDataRate() {
        return dataRate;
    }

    public void setDataRate(String dataRate) {
        this.dataRate = dataRate;
    }

    public String getAppID() {
        return appID;
    }

    public void setAppID(String appID) {
        this.appID = appID;
    }

    public double getAltitude() {
        return altitude;
    }

    public void setAltitude(double altitude) {
        this.altitude = altitude;
    }

    public double getAccuracy() {
        return accuracy;
    }

    public void setAccuracy(double accuracy) {
        this.accuracy = accuracy;
    }

    public String getMqttTopic() {
        return mqttTopic;
    }

    public void setMqttTopic(String mqttTopic) {
        this.mqttTopic = mqttTopic;
    }

}


text:
import {Job, JobStatus, Range} from '@common/types';

const INGRESS_EPOCH: number = Date.UTC(2012, 10, 15, 0, 0, 0, 0);

export const getRawRanges = (lastReportTime?: number, rangeToTime?: number): Range[] => {

  let fromTime: number = lastReportTime ? lastReportTime+1 : INGRESS_EPOCH;
  const toTime: number = rangeToTime ? rangeToTime : Date.now();
  const ranges: Range[] = [];
  // const now: number = Date.now();
  // const oneRange = 1000*3600*24*30; // 30 days

  do {
    const oneRange = toTime - fromTime > 1000*3600*24*30 ?
      1000*3600*24*30 : toTime - fromTime;
    ranges.push({
      "fromTime": fromTime,
      "toTime": fromTime + oneRange,
      "done": false
    });
    fromTime += oneRange;
  }while(fromTime < toTime && ranges.length < 100);
  // }while(fromTime < now && ranges.length < 100);

  return ranges;
};

// FIXME
export const done = (ranges: Range[], current: Range) => {
  for(let i=0; i<ranges.length; i++) {
    if(ranges[i].fromTime === current.fromTime &&
        ranges[i].toTime === current.toTime) {
      ranges[i].done = true;
      console.log('done:', ranges[i]);
      return;
    }
  }
}

export const nextRange = (ranges: Range[]): Range => {

  for(let i=0; i<ranges.length; i++) {
    if(ranges[i].done) {
      continue;
    }else{
      // ranges[i].done = true;
      console.log('nextRange:', ranges[i]);
      return ranges[i];
    }
  }
  return null; // unreachable
};

export const hasMoreRange = (ranges: Range[]): boolean => {
  for(let aRange of ranges) {
    if(!aRange.done) {
      console.log('hasMoreRange:', aRange);
      return true;
    }
  }
  return false;
}


text:
// Copyright (c) Martin Costello, 2015. All rights reserved.
// Licensed under the Apache 2.0 license. See the LICENSE file in the project root for full license information.

using System.Collections.Concurrent;
using System.Numerics;

namespace MartinCostello.ProjectEuler;

/// <summary>
/// A class containing mathematics-related methods. This class cannot be inherited.
/// </summary>
internal static class Maths
{
    /// <summary>
    /// An array containing the digits for base10. This field is read-only.
    /// </summary>
    private static readonly int[] Base10Digits = Enumerable.Range(0, 10).ToArray();

    /// <summary>
    /// A cache of values for which being prime has been computed. This field is read-only.
    /// </summary>
    private static readonly ConcurrentDictionary<long, bool> _primes = new();

    /// <summary>
    /// Returns the binomial coefficient for the specified values.
    /// </summary>
    /// <param name="n">The number of values.</param>
    /// <param name="k">The number of values to select.</param>
    /// <returns>
    /// The value of the binomial coefficient for <paramref name="n"/> and <paramref name="k"/>.
    /// </returns>
    internal static long Binomial(int n, int k)
    {
        double result = 1;

        for (int i = 1; i <= k; i++)
        {
            result *= n - (k - i);
            result /= i;
        }

        return (long)result;
    }

    /// <summary>
    /// Returns the cumulative sum for the specified values.
    /// </summary>
    /// <param name="collection">The values to compute the cumulative sum for.</param>
    /// <returns>
    /// An <see cref="IEnumerable{T}"/> containing the cumulative sum for <paramref name="collection"/>.
    /// </returns>
    internal static IEnumerable<int> CumulativeSum(IEnumerable<int> collection)
    {
        int sum = 0;

        foreach (int value in collection)
        {
            sum += value;
            yield return sum;
        }
    }

    /// <summary>
    /// Returns the digits of the specified value in base 10.
    /// </summary>
    /// <param name="value">The value to get the digits for.</param>
    /// <returns>
    /// The digits of <paramref name="value"/> in base 10.
    /// </returns>
    internal static IList<int> Digits(BigInteger value)
    {
        if (value == BigInteger.Zero)
        {
            return new[] { 0 };
        }

        if (value < BigInteger.Zero)
        {
            value = BigInteger.Negate(value);
        }

        var digits = new List<int>();

        while (value > 0)
        {
            var div = BigInteger.DivRem(value, 10, out var rem);

            digits.Add((int)rem);
            value = div;
        }

        digits.Reverse();

        return digits;
    }

    /// <summary>
    /// Returns the digits of the specified value in base 10.
    /// </summary>
    /// <param name="value">The value to get the digits for.</param>
    /// <returns>
    /// The digits of <paramref name="value"/> in base 10.
    /// </returns>
    internal static IReadOnlyList<int> Digits(long value)
    {
        if (value == 0)
        {
            return new[] { 0 };
        }

        value = Math.Abs(value);

        var digits = new List<int>();

        while (value > 0)
        {
            (long div, long rem) = Math.DivRem(value, 10);

            digits.Add((int)rem);
            value = div;
        }

        digits.Reverse();

        return digits;
    }

    /// <summary>
    /// Returns the factorial (<c>value!</c>) of the specified value.
    /// </summary>
    /// <param name="value">The value to get the factorial for.</param>
    /// <returns>
    /// The factorial of <paramref name="value"/>.
    /// </returns>
    internal static int Factorial(int value)
    {
        if (value == 0)
        {
            return 1;
        }

        int result = value;

        for (int i = value - 1; i > 1; i--)
        {
            result *= i;
        }

        return result;
    }

    /// <summary>
    /// Returns the 64-bit integer represented by the specified digits.
    /// </summary>
    /// <param name="collection">The digits of the number.</param>
    /// <returns>
    /// The <see cref="long"/> represented by the digits in <paramref name="collection"/>.
    /// </returns>
    internal static long FromDigits(IList<int> collection)
    {
        double result = 0;

        for (int j = 0; j < collection.Count - 1; j++)
        {
            result += collection[j] * Math.Pow(10, collection.Count - j - 1);
        }

        result += collection[collection.Count - 1];

        return (long)result;
    }

    /// <summary>
    /// Returns the factors of the specified number.
    /// </summary>
    /// <param name="value">The value to get the factors for.</param>
    /// <returns>
    /// An <see cref="IEnumerable{T}"/> which enumerates the factors of <paramref name="value"/>.
    /// </returns>
    internal static IEnumerable<long> GetFactors(long value) => GetFactorsUnordered(value).Order();

    /// <summary>
    /// Returns the proper divisors of the specified number.
    /// </summary>
    /// <param name="value">The value to get the proper divisors for.</param>
    /// <returns>
    /// An <see cref="IEnumerable{T}"/> which enumerates the proper divisors of <paramref name="value"/>.
    /// </returns>
    internal static IEnumerable<long> GetProperDivisors(long value) => GetFactors(value).TakeWhile((p) => p != value);

    /// <summary>
    /// Returns the hexagonal number for the specified value.
    /// </summary>
    /// <param name="n">The value to calculate the hexagonal number for.</param>
    /// <returns>
    /// The hexagonal number of <paramref name="n"/>.
    /// </returns>
    internal static long Hexagonal(long n) => n * ((2 * n) - 1);

    /// <summary>
    /// Returns whether the specified number is an abundant number.
    /// </summary>
    /// <param name="value">The number to test for being an abundant number.</param>
    /// <returns>
    /// <see langword="true"/> if <paramref name="value"/> is an abundant number; otherwise <see langword="false"/>.
    /// </returns>
    internal static bool IsAbundantNumber(long value)
    {
        long sum = 0;

        using var enumerator = GetProperDivisors(value).GetEnumerator();

        while (enumerator.MoveNext() && sum <= value)
        {
            sum += enumerator.Current;
        }

        return sum > value;
    }

    /// <summary>
    /// Returns whether the specified number is an hexagonal number.
    /// </summary>
    /// <param name="x">The value to test for being hexagonal.</param>
    /// <returns>
    /// <see langword="true"/> if <paramref name="x"/> is an hexagonal number; otherwise <see langword="false"/>.
    /// </returns>
    internal static bool IsHexagonal(long x) => Math.IEEERemainder(1 + Math.Sqrt(1 + (8 * x)), 4) == 0;

    /// <summary>
    /// Returns whether the specified value is pandigital.
    /// </summary>
    /// <param name="value">The value to test for being pandigital.</param>
    /// <param name="allowZero">Whether zero is allowed.</param>
    /// <returns>
    /// <see langword="true"/> if <paramref name="value"/> is pandigital; otherwise <see langword="false"/>.
    /// </returns>
    internal static bool IsPandigital(long value, bool allowZero = false)
    {
        IReadOnlyList<int> digits = Digits(value);
        IReadOnlyList<int> distinctDigits = digits.Distinct().ToArray();

        if (digits.Count != distinctDigits.Count)
        {
            return false;
        }

        IEnumerable<int> expectedDigits = Base10Digits
            .Skip(allowZero ? 0 : 1)
            .Take(digits.Count);

        return !distinctDigits.Except(expectedDigits).Any();
    }

    /// <summary>
    /// Returns whether the specified number is a pentagonal number.
    /// </summary>
    /// <param name="x">The value to test for being pentagonal.</param>
    /// <returns>
    /// <see langword="true"/> if <paramref name="x"/> is a pentagonal number; otherwise <see langword="false"/>.
    /// </returns>
    internal static bool IsPentagonal(long x) => Math.IEEERemainder(Math.Sqrt((24 * x) + 1) + 1, 6) == 0;

    /// <summary>
    /// Returns whether the specified number is a triangular number.
    /// </summary>
    /// <param name="x">The value to test for being triangular.</param>
    /// <returns>
    /// <see langword="true"/> if <paramref name="x"/> is a triangular number; otherwise <see langword="false"/>.
    /// </returns>
    internal static bool IsTriangular(long x) => IsPerfectSquare((8 * x) + 1);

    /// <summary>
    /// Returns whether the specified number is a perfect number.
    /// </summary>
    /// <param name="value">The number to test for being a perfect number.</param>
    /// <returns>
    /// <see langword="true"/> if <paramref name="value"/> is a perfect number; otherwise <see langword="false"/>.
    /// </returns>
    internal static bool IsPerfectNumber(long value) => GetProperDivisors(value).Sum() == value;

    /// <summary>
    /// Returns whether the specified number is a perfect square.
    /// </summary>
    /// <param name="value">The number to test for being a perfect square.</param>
    /// <returns>
    /// <see langword="true"/> if <paramref name="value"/> is a perfect square; otherwise <see langword="false"/>.
    /// </returns>
    internal static bool IsPerfectSquare(long value) => GetProperDivisors(value).Any((p) => p * p == value);

    /// <summary>
    /// Returns whether the specified value is a prime number.
    /// </summary>
    /// <param name="value">The value to test for being prime.</param>
    /// <returns>
    /// <see langword="true"/> if <paramref name="value"/> is a prime number; otherwise <see langword="false"/>.
    /// </returns>
    internal static bool IsPrime(long value)
    {
        if (value < 2)
        {
            return false;
        }

        if (value < 4)
        {
            return true;
        }

        if (value % 2 == 0 || value % 3 == 0)
        {
            return false;
        }

        if (_primes.TryGetValue(value, out bool result))
        {
            return result;
        }

        result = true;

        long i = 5;

        while (i * i <= value)
        {
            if (value % i == 0 || value % (i + 2) == 0)
            {
                result = false;
                break;
            }

            i += 6;
        }

        return _primes[value] = result;
    }

    /// <summary>
    /// Returns the pentagonal number for the specified value.
    /// </summary>
    /// <param name="n">The value to calculate the pentagonal number for.</param>
    /// <returns>
    /// The pentagonal number of <paramref name="n"/>.
    /// </returns>
    internal static long Pentagonal(long n) => n * ((3 * n) - 1) / 2;

    /// <summary>
    /// Returns all the permutations of the specified collection of values.
    /// </summary>
    /// <typeparam name="T">The type of the values.</typeparam>
    /// <param name="collection">The collection to get the permutations of.</param>
    /// <returns>
    /// An <see cref="IEnumerable{T}"/> that returns the permutations of <paramref name="collection"/>.
    /// </returns>
    internal static IEnumerable<IEnumerable<T>> Permutations<T>(ICollection<T> collection) => Permutations(collection, collection.Count);

    /// <summary>
    /// Returns all the permutations of the specified collection of values.
    /// </summary>
    /// <typeparam name="T">The type of the values.</typeparam>
    /// <param name="collection">The collection to get the permutations of.</param>
    /// <param name="count">The number of items to calculate the permutations from.</param>
    /// <returns>
    /// An <see cref="IEnumerable{T}"/> that returns the permutations of <paramref name="collection"/>.
    /// </returns>
    internal static IEnumerable<IEnumerable<T>> Permutations<T>(IEnumerable<T> collection, int count)
    {
        if (count == 1)
        {
            return collection.Select((p) => new[] { p });
        }

        return Permutations(collection, count - 1)
            .SelectMany((p) => collection.Where((r) => !p.Contains(r)), (set, value) => set.Append(value));
    }

    /// <summary>
    /// Enumerates the prime numbers below the specified value.
    /// </summary>
    /// <param name="maximum">The maximum prime number.</param>
    /// <returns>
    /// An <see cref="IEnumerable{T}"/> that returns all the prime numbers below <paramref name="maximum"/>.
    /// </returns>
    internal static IEnumerable<int> Primes(int maximum)
    {
        // Based on https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes#Algorithm_and_variants
        if (maximum < 3)
        {
            yield break;
        }

        // Array of prime candidates. A value of false at an
        // index means that the value of the index is prime.
        bool[] primeCandidates = new bool[maximum];

        // 0 and 1 are not prime
        primeCandidates[0] = true;
        primeCandidates[1] = true;

        int root = (int)Math.Sqrt(maximum);

        for (int i = 2; i <= root; i++)
        {
            if (!primeCandidates[i])
            {
                // Mark all values i^2 * ij up to the maximum as not prime
                for (int j = 0; ; j++)
                {
                    int k = (i * i) + (i * j);

                    if (k >= maximum)
                    {
                        break;
                    }

                    primeCandidates[k] = true;
                }
            }
        }

        for (int i = 2; i < primeCandidates.Length; i++)
        {
            if (!primeCandidates[i])
            {
                yield return i;
            }
        }

        // Only odd values are prime (except 2)
        for (int i = 3; i < primeCandidates.Length; i += 2)
        {
            if (!primeCandidates[i])
            {
                _primes[i] = true;
            }
        }
    }

    /// <summary>
    /// Returns the factors of the specified number.
    /// </summary>
    /// <param name="value">The value to get the factors for.</param>
    /// <returns>
    /// An <see cref="IEnumerable{T}"/> containing the factors of the specified number.
    /// </returns>
    /// <remarks>
    /// The values returned are unsorted.
    /// </remarks>
    internal static IEnumerable<long> GetFactorsUnordered(long value)
    {
        for (int i = 1; i * i <= value; i++)
        {
            (long div, long rem) = Math.DivRem(value, i);

            if (rem == 0)
            {
                yield return i;

                if (i * i != value)
                {
                    yield return div;
                }
            }
        }
    }

    /// <summary>
    /// Returns the triangular number for the specified value.
    /// </summary>
    /// <param name="n">The value to calculate the triangular number for.</param>
    /// <returns>
    /// The triangular number of <paramref name="n"/>.
    /// </returns>
    internal static long Triangular(long n) => n * (n + 1) / 2;
}


text:
package org.apache.druid.common.guava;

import com.google.common.base.Supplier;

/**
 * A settable Supplier. Not thread safe.
 */
public class SettableSupplier<T> implements Supplier<T>
{
  private T obj;

  public SettableSupplier()
  {
  }

  public SettableSupplier(T obj)
  {
    this.obj = obj;
  }

  public void set(T obj)
  {
    this.obj = obj;
  }

  @Override
  public T get()
  {
    return obj;
  }
}


text:
package org.apache.hadoop.fs.contract.s3n;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.contract.AbstractContractRootDirectoryTest;
import org.apache.hadoop.fs.contract.AbstractFSContract;

/**
 * Root dir operations against an S3 bucket.
 */
public class ITestS3NContractRootDir extends
    AbstractContractRootDirectoryTest {

  @Override
  protected AbstractFSContract createContract(Configuration conf) {
    return new NativeS3Contract(conf);
  }
}