Archives 2005 - 2019    Search

How to use the forward.py script in paramiko

published Oct 16, 2012 11:22   by admin ( last modified Oct 16, 2012 11:22 )

Paramiko is an ssh library for python.

The forward.py script expects one non-keyword argument, and a number of keyword arguments.

 

python forward.py example.com:22 -r 80 -p 8080 -r example.com:80 --user username --key secret_key_file_name

The above example takes the remote port 80 and makes it available locally as 8080.

The non-keyword argument above is example.com:22 . It connects to the ssh server at example.com running at port 22. 22 is not the port the forward goes to. It is simply the port where the ssh server is, and can be changed from 22 if you run an ssh server on a non-standard port.

The -p indicates the local port for the tunnel, i.e. the port your applications are going to connect to, i.e. your end of the tunnel.

The -r indicates the host and port that the remote server is going to forward to. The server indicated by -r may be different than the server you are connecting to, e.g.:

python forward.py example.com:22 -r 80 -p 8080 -r anotherhost.example.com:80 --user username --key secret_key_file_name

...in which case you are using example.com to reach anotherhost.example.com .

In normal ssh, an equivalent tunnel to the first example above could be written as:

ssh -L 8080:localhost:80 username@example.com

How to find out what's stuck in your queues in Redis

published Oct 15, 2012 01:34   by admin ( last modified Oct 15, 2012 01:34 )

Start redis-cli that should have come with your redis distribution. Start redis-cli and type "keys *" (without the quotes) and hit return. That will show you what keys (queues) have data in them. See this stackoverflow discussion:

you can explore the Redis dataset using the 'redis-cli' tool included in the Redis distribution. Just start the tool without arguments, then type commands to explore the dataset. For instance KEYS will list all the keys matching a glob-style pattern, for instance with: keys * you'll see all the keys available.



Read more: ruby - Dumping all key/value pairs in a Redis db - Stack Overflow


Länk - Interesting list on pitfalls in javascript

published Oct 12, 2012 01:37   by admin ( last modified Oct 12, 2012 01:37 )

 jcampbelly:

  1. Try to forget the existence of "==" and use "===" instead. There are use cases for double-equals, but those are exceptions to the rule (usually cute hacks for brevity).
  2. Truthy and falsy values can be difficult to grasp. Falsy: "", 0, undefined, null, NaN (0/0). Truthy: "0", 1/0, {}.
  3. Type coercion is weird: (new Date() + 0) is ""Sat Oct 06 2012 12:56:45 GMT-0400 (Eastern Daylight Time)0"", (new Date() - 0) is 1349542608499. Incidentally, with implicit type coercion, the string form is local time and the numeric form is UTC.
  4. Always parse integers with a base: parseInt('07') is 7, parseInt('08') is 0, parseInt('08',10) is 8.
  5. Use console.log() instead of alert().
  6. Primitives are passed by value, objects are passed by reference.
  7. Declaring a variable without "var" makes it a global variable.
  8. object['property'] is identical to object.property except that "dot notation" cannot be used with language keywords (depends on browser) or numbers and bracket notation can be used with arbitrary strings (including spaces, for example).
  9. There is no scope inside of loops. Declaring a variable within a loop scope is the same as declaring it in the containing block. This can be hard to demonstrate, but take this very contrived example. The number "10" will be printed 10 times, because at the end of the loop execution there exists only one variable "i" whose value is 10, which is what the callback is referring to.

    for (var i = 0; i < 10; i++) {   setTimeout(function(){ console.log(i); }, 1000); } 



Read more: jcampbelly comments on In my first week of a JavaScript course -- Is there anything in particular I should watch out for that consistently trips up newcomers?


Länk - A client-side shopping cart system written in javascript

published Oct 08, 2012 09:14   by admin ( last modified Oct 08, 2012 09:14 )

 

A free and open-source javascript shopping cart that easily integrates with your current website.



Read more: Javascript Shopping Cart - simpleCart(js)


Some javascript libraries

published Oct 05, 2012 12:45   by admin ( last modified Feb 29, 2016 01:27 )

Updated 2016-02-29

javascript - At underscore js, Can I get multiple columns with pluck method after input where method as linq select projection - Stack Overflow
ESLint - Pluggable JavaScript linter
JavaScript’s Apply, Call, and Bind Methods are Essential for JavaScript Professionals | JavaScript is Sexy
JavaScript Nested function - Stack Overflow
How can I pretty-print JSON using JavaScript? - Stack Overflow
lodash documentation

 

DOM libraries

Libraries that solve things that "everybody needs", by making constructs that make commonly done things simpler, and things more compatible between browsers over different platforms and versions. Usually you only use one of these, but there are ways of making them not be in conflict with one another. One of these basic libraries is often required by the frameworks.

jquery

An ubiquitous library that makes stuff easier and more cross browser compatible. Concentrates on the DOM (Document Object Model). Has a plugin ecosystem

Other basic libraries are Prototype, MooTools, Dojo and YUI.

 

Utility libraries

Libraries that make specific tasks easier.

atomizejs

A library that implements STM (Software transactional memory), a fairly novel way of doing concurrency

underscore.js

Functional idioms, required by Backbone

Amino

Animation and interactive graphics on the HTML5 Canvas

Google closure library

The foundation for GMail, Google documents, among other projects. Strong on widgets. Could arguably be called a framework, but according to the documentation emphasizes modularity and being usable in small parts in other code

D3.js - Data-Driven Documents

Data visualization and interaction, with some amazing examples

Functional programming libraries

Ramda Documentation

fn.js | A JavaScript library built to encourage a functional programming style & strategy.

The functional JavaScript library | functional.js

Form validation

Livevalidation

Validation library with immediate feedback

jquery.validate

Validation library that might be one step better for me, in initial tests

 

Frameworks

Put some overall structure onto the code and how to get things done. You choose one over the others. Tend to deal with data modelling and how to bind together an application with views, control, routes, and data persistence. Goal is to make larger scale applications doable and manageable.

backbone

powers many of the big sites. Has models, views routes and can serialize data into JSON and talk RESTfully with the server back end.

canjs

A framework in the same vein as backbone and ember

ember

A framework in the same vein as backbone, methinks

spine

backbone written in coffeescript, methinks

Angularjs

Like backbone but operating purely(?) with markup, it looks like.

Obviel

zope.interface and adapter stuff on the client side, in javascript

 

Live bindings

Helps make things update immediately in the UI when data changes, like in a normal GUI on the desktop. Some of the frameworks already contain live bindings, such a Ember, Angularjs.

knockout

makes data and presentation update immediately, like in a normal GUI on the desktop

knockback

compatibility layer between knockout and backbone

Backbone.ModelBinder

I believe it makes data and presentation update immediately, like in a normal GUI on the desktop

 

Slideshows

jquery cycle

 

Build/test/deploy frameworks

Grunt

Can apply different transformations to your code before deployment with the aid of modules, such as unit tests, minification and conformance to coding standards

Twitter Bootstrap

Responsive web design with eminently usable page layouts and css. Also contains javascript targetting the look and feel.

PhantomJS

Let's you control a headless webkit engine. The webkit engine underlies Google Chrome, Apple's Safari, the Android's standard web brwoser and many more. Webkit originally comes from KDE, a popular desktop environment on e.g. Linux. PhantomJS ought to make it possible todo very realistic testing and simulation.

 

Languages

Languages that are translated into javascript before being run in the browser. Debugging is going to get better when these languages start using the new source map functionality of the recent versions of Chrome/Chromium, where a breakpoint in the executed javascript code is associated with a line in the non-javascript source code. The other main browsers will hopefully follow suit implementing source maps.

coffeescript

Makes javascript look more like python. The kickstarter founded fork  CoffeeScriptRedux supports source maps, according to this blog post.

clojurescript

Lisp-like language that also exists on the server side running on the JVM. Fairly big in the JVM world, so does not live or die by the browser. Source map tweet indicates that source maps may be on the way.

typescript

Light-handed enhancement of standard javascript to aid with development in larger projects. Tries to anticipate new versions of javascript (a.k.a. ECMAScript).  Prevents a lot of late binding in order to make things more predictable and bugs easier to spot automatically. Gives more ambitious editing help than what is possible with javascript.

pyjs

 

Templating

Handlebars

Templating

Dust

Javascript date handling
Moment.js | Docs
datejs
Moment Timezone | Home
Moment Timezone | Docs
Time · mbostock/d3 Wiki
dosx/timezone-picker
Node.js Express
Using template engines with Express
Git
How do you merge selective files with git-merge? - Stack Overflow
Git Tip: How to "Merge" Specific Files from Another Branch [jasonrudolph.com]
Javascript testing
Intern: Software testing for humans
Buster.JS overview — Buster.JS 0.7 documentation
List of unit testing frameworks - Wikipedia, the free encyclopedia
coderwall.com : establishing geek cred since 1305712800
Jasmine: Behavior-Driven JavaScript
Cookbook | QUnit
QUnit
Sinon.JS - Documentation
Javascript testing frameworks — jorgenmodin.net
node.js
Mocha - the fun, simple, flexible JavaScript test framework
The Node Way - Testing Essentials
jhnns/rewire
mfncooper/mockery
Node.js Handbook - Testing Essentials | FredKSchott
Nightwatch.js | Node.js powered End-to-End testing framework
Vows « Asynchronous BDD for Node
testing framework node.js promise chains - Google Search
dareid/chakram
Eradicating Non-Determinism in Tests
StrongLoop | Testing and Documenting Node.js APIs with Mocha and Acquit
acquit
Home - Chai
Using Tests to Document a Node.js Module
How To Use Mocha With Node.js For Test-Driven Development to Avoid Pain and Ship Products Faster
cloudhead/hijs
Asynchronous programming
Implementing Actors in JavaScript
benlau/nactor · GitHub
mental/webactors · GitHub
AndrewBelt/hack.chat
events - How is Node.js evented system different than the actor pattern of Akka? - Stack Overflow
Embracing Async With Deferreds and Promises - Sebastian's Blog
Reactive programming - Wikipedia, the free encyclopedia
JavaScript Promises: There and back again - HTML5 Rocks
Does async/await solve a real problem?
chopachom/syncio
We have a problem with promises
Promise anti patterns · petkaantonov/bluebird Wiki
Taming the asynchronous beast with ES7
JSX in Depth | React
petkaantonov/bluebird
javascript asynchronous styles - Google Search
Testing Asynchronous JavaScript
Javascript Promises - Being Agile
You're Missing the Point of Promises
domenic/chai-as-promised
javascript - How do you properly promisify request? - Stack Overflow
node request promise - Google Search
Passing multiple arguments in promises | Better world by better software
JavaScript with Promises - Daniel Parker - Google Books
Resolving JavaScript Objects Containing Promises - Will Anderson
javascript - asynchronous or promised condition for array filter - Stack Overflow
Patterns for Asynchronous Programming with Promises | Joe Zim's JavaScript Blog
monet.js - For when you have no choice but to use JavaScript
prequest
promise-useful-utils/API.md at master · fanatid/promise-useful-utils
JavaScript with Promises - Daniel Parker - Google Books
Resolving JavaScript Objects Containing Promises - Will Anderson
javascript - asynchronous or promised condition for array filter - Stack Overflow
Ecmascript 6 & higher and typescript
 
Sign in or Register | edX
TagClass - jsdoc-toolkit - @class - A documentation generator for JavaScript. - Google Project Hosting
Language Safety Score Mark 2 - Deliberate Software
Programming Language Safety Score - Deliberate Software
ECMAScript 6: New Features: Overview and Comparison
ES6 | Node.js
ECMAScript - Wikipedia, the free encyclopedia
ES7 async functions - JakeArchibald.com
Use ECMAScript 6 Today - Tuts+ Code Article
Which TypeScript IDE - Steve Fenton
Using TypeScript in Visual Studio Code - TypeScript - Site Home - MSDN Blogs
ES6 | Node.js
lukehoban/es6features

 


Generate reasonably unique ids in javascript

published Oct 05, 2012 10:50   by admin ( last modified Oct 05, 2012 10:50 )

 

Returns a random v4 UUID of the form xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx, where each x is replaced with a random hexadecimal digit from 0 to f, and y is replaced with a random hexadecimal digit from 8 to b.



Read more: generate random UUIDs — Gist


Front-orphaned reverse numbered batching to mitigate cache invalidation

published Oct 04, 2012 11:25   by admin ( last modified Oct 04, 2012 11:25 )

With a standard Plone setup that this site used to have (and for many other systems), one new blog post on this blog would invalidate 250 pages or so, by pushing one blog post off the front page and on to the next "older blog posts >>" page. That in its turn would push one blog post on the the next older page etcetera all the way back to changing 250 pages for the total of 2500 or so blog posts on this blog.

Numbering batches in reverse with the high numbers first, and having the orphans in the beginning rather than the end saves you a lot of cache invalidation.

If you look at the "older blog posts >>" at the front page of this blog you will notice that the numbers in the url for the first page of slightly older posts are very high. That is because the blog posts are numbered backwards.

This saves a lot of cache invalidation when a new blog post is posted. Furthermore, even though the batch size of the site is 10, the front page expands to 19 items before "giving birth" to a new batched page. this means that when a new blog post is made, one page . the front page - is invalidated in the Varnish cache, and not like before, 250 pages.

This blog has about 2500 blog entries as I type this, and you can go back in time, browsing through them with the "older blog posts >>" link. You will get 10 blog posts per page. The url for each batch contains info on what sequence numbers of blog posts you want to see.

However, for some reason it is customary to number these batches starting with newest first. This means that whenever a new item is added to the sequence, every single item gets a new sequence number. Furthermore for aesthetic reasons one does not want to have a small number of posts on the last page (this is called to have "orphans"). So instead the last page is expanded to accommodate for these "orphaned" posts. If you let the first page take care of the orphans, suddenly all your batched pages will be stable forever, barring edits.


Javascript learned during the week

published Sep 27, 2012 09:11   by admin ( last modified Sep 27, 2012 09:11 )

I am doing a lot of javascript programming this week so here some things I have picked up.

 

Javascript debuggers in Firefox and Chrome

Chrome's built in seems the better one compared to Firebug on Firefox, but some things are hidden behind miniscule non-descript widgets in Chrome. i still cannot see how to select an element with the mouse on the page and get the source code to jump there though. Other way works fine.

 

jquery

When you select for an element in jquery, even if it is for an element with a specific and hopefully unique id, it will return an array, so you will have to extract the one you want. The slice method works well for that: result.slice(0) for first (and possibly only) element, and result.slice(-1) for last.

The clone() method is very nice.

 

If you miss python's "for .. in" syntax for iterating over things, there is an ".each()" method in jquery that accomplishes the same more or less.

 

javascript and prices

When handlig currencies with decimals, it seems to be ok to use parseFloat() to convert it into something numerical, but that can introduce rounding errors when doing arithmetic on the numbers. That seems to be handled by using var.toFixed(2) in the end. A bit of a patchwork.

Another way would be to multiply the prices by 100 and then use parseInt and just work with integers I suppose.

 

Submitting two forms at once

Can be done in at least two ways in javascript. You can submit one with XML-RPC or similar but the method I used was to have the first one submit to an invisible iframe with an appropriate target atribute in the form.  In that way you are still on the original page when the second form submits. Otherwise you would be somewhere else and the second submit would not work. I found this iframe technique in a discussion forum but I have closed that page alas.

 

 

 

 

 


Initial thoughts on form validation with Livevalidation

published Sep 27, 2012 08:56   by admin ( last modified Sep 27, 2012 08:56 )

I have been doing a lot of javascript programming this week, so here are what I have learned so far about live validation.

Form validation with Livevalidation

I am using a library called Live Validation, which I so far like.

Conflict with jquery when submitting

However if you are using it in conjunction with jquery, which I do, there is one conflict. When livevalidation is turned on for a field, livevalidation also takes care of the submit handler of that form, inserting itself in a chain with the original handler placed after it. In this way livevalidation can stop the submitting of a form. However in my use case I had a jquery form submit event handler set up on loading the page, and this one fired even when validation failed since it somehow managed to sneak in before livevalidation. Since my code submits another form as part of that code, that did not work out well.

 

Solution was to assign my code to the onsubmit handler of the form, instead of using fancy jquery event interception. Then livevalidation can then sneak in and stop the shenanigans.

An empty field with an email validator still validates

Secondly a thing that is logical on scrutiny when it comes to livevalidation, is that even if you have marked a field that it must contain a valid e-mail address, an empty field also validates.

Why? I believe it is because there is the use case that you would like to validate optional fields too. The solution is to stick two validators on the field, one for e-mail and one for at least something (Validate.Presence in livevalidation speak).

 

Liveavalidation tries to validate non-existing removed  fields

If you remove input fields from your form with jquery's remove(), while these inputs still have Livevalidation validators on them, Livevalidation will still remember them and refuse to submit the form if they have any validators on them that checks for empty. Solution is to go through the inputs before you remove them and do something like this:

var fieldid = $(v).attr('id');
var aField = new LiveValidation(fieldid);
aField.disable();

Calling the Livevalidation destroy() methid is not enough unless you manage to get hold of the original Livevalidation object(s) for that field, so use disable().


Using a real log file to load test a server

published Sep 23, 2012 11:10   by admin ( last modified Apr 15, 2014 10:55 )

 

Summary: These python scripts take a log file in the standard Apache combined format and load test a server of your choice (like a development server). You can speed up or slow down the simulation. It prints out a report on how long each request took, which you can use to do comparisons between different server configurations with regards to performance. It is tested on Ubuntu 12.04 with pycurl installed.

Note: Read the comments below this post for bugs in this code, I have unfortunately not had the time to test the fixes.

Update: There are at least two other tools that can use a log file to simulate the traffic, httperf  and siege . However they do not follow the timing of the log file as far as I can see, which playlogfiletoserver does.

Check the playlogfiletoserver github repository for newest versions of the files and installation and usage instructions. And do give me a pull request if you fix any oustanding bugs!

 

Last week I had to look into a problem with a Plone production server that had performed unsatisfactory a couple of times during the week under heavy load, with lagging response times. Now, how to trouble shoot what was the problem? I had a copy of the server that looked fine when clicking around in it, or when using the Apache benchmarking tool. The solution is of course to hit the testing server with lots of requests and see what actually happens.

However since the slowness only happened under certain load patterns, wouldn't it make sense to just use the log files from the times when the problems manifested themselves? I googled a bit and found repache, that is supposed to replay Apache log files to a server. It is written in C++ and does not compile on newer Ubuntus unless you add a couple of includes. Once that was done it promptly crashed on my access_log log file.

So, time to whip something together (note that the playlogfiletoserver github repository may have newer versions of the scipts than posted below). First a pre processor that takes a log file in the Apache combined log file format and outputs a python module containing a tuple of tuples with info on when to fire each request and what request that would be:

 

import datetime
import re

def get_timestamp(date):
    timestamp = datetime.datetime.strptime(date, '%d/%b/%Y:%H:%M:%S')
    return timestamp
    
def parseline(line):  
    linedict = {}
    line = line.replace('\\"', '%22')
    quoteprep = line.split('"')
    try:
        (linedict['ipnumber'], tmp, tmp, linedict['date'], tmp, tmp) = quoteprep[0].split(" ")
        (linedict['method'], linedict['path'], linedict['protocol']) = quoteprep[1].split(" ")
        (tmp, linedict['returncode'], linedict['bytestransferred'], tmp) = quoteprep[2].split(" ")
        linedict['url'] = quoteprep[3]
        linedict['date'] = linedict['date'][1:]
        
    except ValueError:
        print line
        raise
    return linedict
    
fi = open('access_log', 'r')
fo = open('generatedrequests.py', 'w')
fo.write('requests = (')

first_timestamp = 0
for line in fi:
    linedict = parseline(line)
    if not first_timestamp:
        first_timestamp = get_timestamp(linedict['date'])
        time_offset = 0
    else:
        time_offset = (get_timestamp(linedict['date']) - first_timestamp).seconds
    lineout = '''(%s,"%s"\n),''' % (str(time_offset), linedict['path'])
    fo.write(lineout)
    
fo.write(')')

Secondly, some kind of user agent is needed to do the actual requesting, and it needs to be able to run requests in parallel, lest we would not be load testing the server much if we just kindly wait for it to duly process each request in sequence. I found Pete Warden's pyparallelcurl that uses pycurl/libcurl to do its magic (pyparallelcurl is also included in the playlogfiletoserver github repository for convenience).

Thirdly and lastly the script to do the actual load testing:

import datetime
import time
from generatedrequests import requests as therequests
import pyparallelcurl
import pycurl

server = 'http://www.example.com'
speedup = 4
maxparallelrequests = 100

sleepduration = 0.5/speedup
t = datetime.datetime.now()
starttime = time.mktime(t.timetuple())


curloptions = {
    pycurl.SSL_VERIFYPEER: False,
    pycurl.SSL_VERIFYHOST: False,
    pycurl.USERAGENT: 'Play log file to server user agent',
    pycurl.FOLLOWLOCATION: True
}

#c.setopt(c.MAX_RECV_SPEED_LARGE, 10000)

parallel_curl = pyparallelcurl.ParallelCurl(maxparallelrequests, curloptions)

def go(request):
    parallel_curl.startrequest(server + request[1], on_request_done)
    return

   
def on_request_done(content, url, ch, search):
    
    if content is None:
        print "Fetch error for "+url
        return
    
    httpcode = ch.getinfo(pycurl.HTTP_CODE)   
    transfertime = ch.getinfo(pycurl.TOTAL_TIME)
    if httpcode != 200:
        print "%0.3f seconds fetch error %s for %s" % (transfertime, str(httpcode),url)
        return
    else:
        print "%0.3f seconds fetch worked %s for %s" % (transfertime, str(httpcode),url)
    print "********"


def timetogo(request):
    reqtime = request[0]
    t = datetime.datetime.now()
    now = time.mktime(t.timetuple())
    return reqtime  <= (now - starttime) * speedup


for request in therequests:
    while True:
        if timetogo(request):
            go(request)
            break
        else:
            time.sleep(sleepduration)
    
    

There are probably some faulty assumptions hiding in these few lines of code, feel free to point them out in the comments below in the issue tracker or fork the code on github.

 


Länk - Info on diagnosing slow Plone sites

published Sep 22, 2012 01:23   by admin ( last modified Sep 22, 2012 01:23 )

 

Always rely on monitor tools! Some example?



Read more: Slow Plone site? Let's use haufe.requestmonitoring — RedTurtle's Blog


Link - Limiting bandwidth (throttling) with trickle

published Sep 19, 2012 06:02   by admin ( last modified Sep 19, 2012 06:02 )

Untested by me, but seems like something that could be used for testing different connection speeds, i.e. to throttle connections a.k.a. bandwidth shaping (just putting in synonyms so I can find this blog post again if and when I need it).

Although this is an old question, I came across this when looking for an answer to the same question. The OS and interface limits are already addressed in an earlier answer, so here is a way to set up application specific limits. Use an application called trickle. So do sudo apt-get install trickle. You can limit upload/download for a specific app by running trickle -u (upload limit in KB/s) -d (download limit in KB/s) application



Read more: networking - How I can limit Download/Upload bandwidth? - Ask Ubuntu


Länk - Histograms in python

published Sep 16, 2012 02:43   by admin ( last modified Sep 16, 2012 02:43 )

 

Generate histograms from the command line. Dependencies Python 2.7 & numpy required, gnuplot for easy plotting.



Read more: SamChill/hist · GitHub


A Plone System Owners' Association?

published Aug 17, 2012 06:26   by admin ( last modified Aug 17, 2012 06:26 )

Quite some time ago (okay, all the way back in 2009!), at a very well arranged world Plone day at Fry-IT in London we sat in groups brainstorming about what a Plone user group in the UK could be about.

I came up with the idea of a Plone System Owners' Association , but the idea did not get traction, at least not during the limited time we had at the meeting.

Mikko Ohtamaa has now (in 2012) posted about the state of Plone, "Making the world to love Plone again", which triggered me to finally publish this:

I still think a Plone System Owners' Association is a good idea, and here is why:

Over the years of teaching Plone I have got in touch with many organisations that have a vested interest in Plone, since they are running Plone installations, from small ones to massive. A couple of things they say are these:

  1. We do not want to upgrade!
  2. We like Product X, but needs it to be updated/changed, how do we go about that?
  3. We tried to contact the maintainer of product X, but got no reply

There may also be in house development of things, that might be quicker, better and cheaper to do if the development effort was shared between several parties.

 

My take on this is that these Plone system owners need to:

  • Know about each other and have a forum to communicate
  • Find a way to:
  • Contact and interact with the developer community
  • Pool funding of development of software and other services for Plone

 

Better formulate what demands system owners have on Plone with regards to

  • Features
  • Usability
  • Upgrade path
  • Legacy support

Make change easier

  • Direct resources to the developer community while delivering value to the system owners
  • Being an open source citizen
  • Getting funding
  • Funding what you want to have done

Now, I am not foremost a Plone system owner, but one example of a cool thing to do, would be to have a script that automatically upgraded a Plone 2.5 site to Plone 4, similar to how 2to3 can upgrade from python 2 to python 3.

I actually think that this could work, parsing python, ZPT and using Diazo. But I am not going to embark on it, but it would not surprise me if a good number of system owner's wouldn't mind chipping in for such a script to come about.

 

 


HTML Canvas Javascript animation toolkit

published Aug 06, 2012 04:41   by admin ( last modified Aug 06, 2012 04:41 )

 

Amino is 2D scene graph library, 100% open source (BSD), for HTML Canvas using JavaScript.



Read more: Amino Java/JavaScript Scene Graph


Design patterns in python

published Aug 06, 2012 04:40   by admin ( last modified Aug 06, 2012 04:40 )




Do you think out of the many patterns some are unnecessary in a dynamic language like Python (e.g. because they are substituted by a dynamic feature)?


Read more: Are there any design patterns that are unnecessary in dynamic languages like Python? - Programmers

 


Although it usually requires some adaptation, Python makes implementing most of the GoF design patterns trivial.



Read more: The GITS Blog » Six GoF design patterns, Python style

 


Generate decent looking PDF docs and charts from JSON

published Aug 04, 2012 10:33   by admin ( last modified Aug 04, 2012 10:33 )


Source code is free, in Clojure. You can call it over http.

This service accepts POST requests with JSON markup at http://yogthos.net/instant-pdf/ and returns PDFs.



Read more: Instant PDF


Att få det mörkt med bibehållen ventilation

published Jul 21, 2012 07:59   by admin ( last modified Jul 21, 2012 07:59 )

Mörkläggande gardiner är ganska trevligt i dessa ljusa sommartider. Problemet är dock att de ofta är täta inte bara mot ljus utan även mot luftväxling. Ett par bastanta mörkläggande gardiner kan ganska effektivt strypa luftväxlingen mellan luften utanför fönstren och rummet.

Tricket är ju såklart att ha en mörk barriär mot ljus, som ju alltid färdas i raka linjer, men samtidigt låta luftväxlingen kunna sick-sacka genom barriären.

Hur ser då en sådan barriär ut? Ja den kan ju såklart se ut på många sätt, men fågeluppfödare använder sig av M-formade kolsvarta profiler ovanpå varandra:


Optimizing breeder performance requires being able to fully block out light, while allowing adequate ventilation for the birds. Dandy corporation has engineered superior light reduction solutions since 1982. Through independant laboratory testing and actual in- field performance, our light traps are recognized around the world for their effectiveness and durability.


Read more: LIGHT TRAPS 1


Ett sätt att få bort fästingproblemet med Borrelia?

published Jul 03, 2012 01:48   by admin ( last modified Jul 03, 2012 01:48 )


På engelska Wikipedia står det uppgifter om att om man reducerar antalet hjortdjur (hjort, rådjur, älg osv) till 8-10 st per engelsk kvadratmil, vilket  motsvarar 3-4 hjortdjur per kvadratkilometer, så upphör spridningen av Borrelia och andra fästingburna sjukdomar.

For example, in the US, reducing the deer population to levels of 8 to 10 per square mile (from the current levels of 60 or more deer per square mile in the areas of the country with the highest Lyme disease rates), the tick numbers can be brought down to levels too low to spread Lyme and other tick-borne diseases.[106] However, such a drastic reduction may be impractical in many areas.

(min fetstil)

Read more: Lyme disease - Wikipedia, the free encyclopedia


Getting comments to work in a Plone 3 to 4.1.5 upgrade

published Jul 02, 2012 01:55   by admin ( last modified Nov 09, 2012 11:56 )

 

Summary

The upgrade machinery from Plone 3 to Plone 4.1.5 does not upgrade the comments, you need to do that manually.

Furthermore, folderish content types may find their commenting disabled. Read on for how to fix this.

 

I upgraded a customer's web site from Plone 3 to Plone 4, and even though commenting seemed to work fine, while commenting it did not show the same context as on Plone 3. Starting up two stock Plone sites, one with Plone 3 and one with Plone 4 showed that you should indeed see context.

What had happened was that the commenting part of the site had not been upgraded, and this left the commenting system in a usable but limited state. The Plone upgrade machinery, which for the most part in my experience does a good job, had missed out on upgrading the commenting part. See this bug report:

https://dev.plone.org/ticket/12184

It also lists the remedy:

In portal_setup / Import select Plone Discussions from profile-dropdown. Click "Import all steps" at the bottom

Once you've done that, you need to visit the Discussions configlet, enable commenting on the site and update all comments to the new system:

 

If you have folderish content types, that may not be enough. The new commenting system will not allow comments on folderish content, from conversation.py in plone.app.discussion.browser:

# Always return False if object is a folder
        if (IFolderish.providedBy(context) and
            not INonStructuralFolder.providedBy(context)):
            return False

Hmmm... There are two ways around this, either make sure that your content types have the interface INonStructuralFolder, or make a copy of conversation.py and simply delete the above if clause in the copy. I wasn't sure what knock-on effects the INonStructuralFolder interface might start in relationship to how the types are being used, so I made a copy of conversation.py, and stuck it in my custom skin product:

<!-- Conversation view -->
    <browser:page
        name="conversation_view"
        for="Products.CMFCore.interfaces.IContentish"
        layer="..interfaces.IThemeSpecific"
        class=".conversation.ConversationView"
        permission="zope2.View"
        />

The layer declaration there seems to overpower the layer declaration of the original conversation_view stanza:

<!-- Conversation view -->
    <browser:page
        name="conversation_view"
        for="Products.CMFCore.interfaces.IContentish"
        layer="..interfaces.IDiscussionLayer"
        class=".conversation.ConversationView"
        permission="zope2.View"
        />

One could also have used an overrides.zcml instead of using a layer to override.