# Blog - Niteo > Read the Niteo blog to learn about our work process, conferences we visited, and other things happening with the company. --- ## Posts - [Sprint season is open](https://niteo.co/blog/sprint-season-is-open/): I used to go to a ton of sprints. Then I got kids. So I made sprints come to me... - [Niteo IRL#15 - Kranjska Gora](https://niteo.co/blog/niteo-irl15-kranjska-gora/): Our 15th In-Real-Life meetup is in the books! Hard to believe our first IRL was back in 2016 in Croatia.... - [NixCon 2024 Berlin](https://niteo.co/blog/nixcon-2024-berlin/): Ever since the day NixCon 2024 dates were published, I was sad I was not going to be able to... - [PyCon JP 2024](https://niteo.co/blog/pycon-jp-2024/): Another Year, Another PyCon Japan Another year, another fantastic PyCon Japan! This year’s conference in Tokyo was filled with insightful... - [Niteo IRL#13 - Lanzarote](https://niteo.co/blog/niteo-irl13-lanzarote/): For the 13th IRL edition, we gathered at our Niteo house in Lanzarote. Nejc had already hosted a few Ocean... - [EuroPython 2023](https://niteo.co/blog/europython-2023/): EuroPython in 2018 was my first international conference. After five years, I eagerly joined another EuroPython. I hopped on a... - [Niteo Summer IRL meetup in Ljubljana](https://niteo.co/blog/niteo-summer-irl-meetup-in-ljubljana/): Our summer In-Real-Life meetup was held in Ljubljana, in the heart of Slovenia. The first things you see as you... - [Niteo IRL#11 - Manila](https://niteo.co/blog/niteo-irl11-manila/): Mabuhay! It’s winter 2023 and time for our in-real-life meetup. It’s our 11th IRL, but this will be my first... - [Fast development on NixOS](https://niteo.co/blog/fast-development-on-nixos/): We’ve been using NixOS for a few years, and it has proven to be a stable and reliable OS. More... - [PyCon JP 2022](https://niteo.co/blog/pycon-jp-2022/): It’s good to be back! The past two PyCons in Japan have been online, so it was nice to be... - [NixCon Paris 2022](https://niteo.co/blog/nixcon-paris-2022/): After three years, we finally got a proper IRL NixCon. Since the Nix community is not the biggest one, it... - [Indispensable pytest plugins](https://niteo.co/blog/indispensable-pytest-plugins/): I’ve been babbling on about testing for a decade now. Here’s a quick list of pytest plugins I use in... - [Niteo IRL#10](https://niteo.co/blog/niteo-irl10/): Man... I can’t believe it has been two and a half years since I was abroad. The last time was... - [PyCon.IT 2022](https://niteo.co/blog/pycon-it-2022/): At the beginning of the month, I made a quick road trip down to Florence for this year’s edition of... - [OceanSprint 2022](https://niteo.co/blog/oceansprint-2022/): The mind has not yet completely recovered from all the brain explosions that happened during OceanSprint 2021, and I was... - [How we spent $980,000 on a failed SaaS project](https://niteo.co/blog/failed-saas-project/): Three months after we closed the sale of WooCart, our project that was gonna “make it big”, I am ready... - [Standing on the shoulders of giants](https://niteo.co/blog/standing-on-the-shoulders-of-giants/): Whether we know it or not, we build things based on the work done before us. This is true in... - [Nix build on a diet](https://niteo.co/blog/nix-build-on-a-diet/): At Niteo, we are using nix-shell to build isolated development and production environments. We deploy production as a Docker image... - [Niteo IRL#FML](https://niteo.co/blog/niteo-irlfml/): We were really, really hoping we’d be able to meet up in January for a proper all-company IRL meetup after... - [Sprints are back!](https://niteo.co/blog/sprints-are-back/): Back in early 2010’s, “sprints” were how I lived. Week-long events, in random places around the World, hacking on open... - [Founder Summit in Mexico City](https://niteo.co/blog/founder-summit-in-mexico-city/): I knew I missed conferences. But I did not fully understand how much. Being an introvert (that can act as... - [Attending MicroConf Europe '21 in Dubrovnik](https://niteo.co/blog/attending-microconf-europe-21-in-dubrovnik/): MicroConf Europe in 2019 was the second to last conference I attended before COVID-19 struck. This year MicroConf returned to... - [Deploying +100 servers with GitHub Actions](https://niteo.co/blog/deploying-100-servers-with-github-actions/): Last year we decided to replace our Ubuntu servers with NixOS. We were still on Ubuntu 14. 04, so we... - [Concurrency in Go](https://niteo.co/blog/concurrency-in-go/): Concurrency in Go is an extensive topic, and we won’t cover all the things in this post. There are tons... - [Why we're building a house in the middle of the ocean](https://niteo.co/blog/why-were-building-a-house-in-the-middle-of-the-ocean/): Let’s get the clickbaiting out of the way first: we’re not technically building a house, we’re renovating an existing villa.... - [Niteo IRL#9](https://niteo.co/blog/niteo-irl9/): After a year and a half, Niteo finally organized our bi-annual In-Real-Life meetup. The third time is the charm! Unfortunately,... - [Postmortems](https://niteo.co/blog/postmortems/): Earlier this year, on one of our half-yearly IRL's, we had a discussion about whether or not we should proceed... - [Niteo IRL: YA'RLY](https://niteo.co/blog/niteo-irl-yarly/): After our first virtual IRL in July-2020, it’s time for our first remote-first IRL. Which means Niteans were given options... - [Lowering H12 errors on Heroku](https://niteo.co/blog/lowering-h12-errors-on-heroku/): This post will briefly discuss H12 errors on Heroku, more commonly known as request timeouts, how we tackled them, and... - [Staging like it's 2020](https://niteo.co/blog/staging-like-its-2020/): Last year, we wrote a blog post on how we use Heroku’s Review Apps to create staging apps for every... - [Niteo IRL: O'RLY](https://niteo.co/blog/niteo-irl-orly/): As a remote-first company, Niteo invests in doing bi-annual IRLs (In Real Life) meetups to get everyone in the same... - [Project isolation beyond requirements.txt](https://niteo.co/blog/project-isolation-beyond-requirements-txt/): I’ve been a Python dev for almost 15 years now and I’ve recently completely overhauled how I keep my development... - [Niteo COVID-19 response](https://niteo.co/blog/niteo-covid-19-response/): This was supposed to be an internal memo sent to my fellow coworkers, but I decided to publish it here... - [Astronomer, psychologist, and MIT professor went to a design conference](https://niteo.co/blog/astronomer-psychologist-and-mit-professor-went-to-a-design-conference/): The title could sound like the beginning of some joke, but the modern design field attracts more and more professionals... - [Keeping your head above water by managing your tasks and time](https://niteo.co/blog/keeping-your-head-above-water-by-managing-your-tasks-and-time/): In this blog post, I’ll write a little bit about the tools and methods I used to manage the chaos... - [IRL #8: Bangkok](https://niteo.co/blog/irl-8-bangkok/): Wohooo! It’s 2020 and time for our first IRL of the year Decade. We decided on Bangkok (known as Krung... - [Reading Nix expressions](https://niteo.co/blog/reading-nix-expressions/): These are my notes from the Reading Nix expressions talk in NixCon 2019. Nix package language has a similar syntax... - [NixCon 2019](https://niteo.co/blog/nixcon-2019/): It’s been a few years since I’ve been to a smaller conference and I made the right choice to visit... - [Frontend week in Budapest](https://niteo.co/blog/frontend-week-in-budapest/): Last week I attended my first two frontend conferences – CSSConf & JSConf Budapest 2019. My week in Budapest started... - [PyCon JP 2019](https://niteo.co/blog/pycon-jp-2019/): I’ve been to many conferences in my life, but this was my first time attending a PyCon. To me, what... - [IRL#7: Ljubljana](https://niteo.co/blog/irl7-ljubljana/): It’s mid-year and it was time for In-Real-Life meetup in the hometown of Niteo, Ljubljana. Mid-year IRL is usually a... - [Elm: A frontend story that a backend dev can love](https://niteo.co/blog/elm-a-frontend-story-that-a-backend-dev-can-love/): I’ve been doing Web development for about 15 years now. The first few years were mostly tinkering with PHP and... - [PyCon Thailand 2019](https://niteo.co/blog/pycon-thailand-2019/): Website: https://th. pycon. org/en Talks: http://yt. vu/c/UCtHekbmBXtp5AYSVARFQQiw (to be uploaded) It is the first conference I ever attended, my first... - [KubeCon 2019](https://niteo.co/blog/kubecon-2019/): This was my first time at a KubeCon conference. This year it was held in Barcelona with over 7. 5k... - [Robust REST APIs with Pyramid](https://niteo.co/blog/robust-rest-apis-with-pyramid/): It’s almost a year since we started working on a new project: WooCart. Up until that point, all our projects... - [The Many Faces of AI Powered Marketing](https://niteo.co/blog/the-many-faces-of-ai-powered-marketing/): This month I went to DigiMarCon in New York. I expected it to be a much bigger conference with more... - [We got banned from PayPal after 12 years of business (updated)](https://niteo.co/blog/paypal-ban-after-12-years/): Update: PayPal restored our account, and they were as descriptive as when banning us. This was after a call and... - [Why everyone at Niteo loves checklists](https://niteo.co/blog/why-everyone-at-niteo-loves-checklists/): At Niteo we love using checklists. We think they’re great because they: are easy to follow, remind you about the... - [Why we are backing Earnest Capital](https://niteo.co/blog/why-we-invested-in-earnest-capital/): I always had a vision for Niteo to grow into a factory of sane startups. A combination of internal spin-offs,... - [Staging like it's 2019](https://niteo.co/blog/staging-like-its-2019/): The What Here at Niteo we’ve been delivering continuously since about 2011. We started with home-grown fabric scrips that used... - [Design. Technology. Cool shit.](https://niteo.co/blog/design-technology-cool-shit/): Last week I traveled to Amsterdam to attend FITC conference 2019. I got inspired both by the city and the... - [IRL#6: Marrakesh](https://niteo.co/blog/irl6-marrakesh/): It was that time of the year again, to spend a full week of in-person time with fellow Niteans in... - [Export Plone to PDFs](https://niteo.co/blog/export-plone-to-pdfs/): Since many years ago, we’ve had a private installation of Plone in Niteo that we call Intra. Short for “intranet”.... - [Four meetups in three days](https://niteo.co/blog/four-meetups-in-three-days/): This past week has been quite eventful for me! On Monday, I was still in Lanzarote, enjoying the summer-like weather... - [A month of travel](https://niteo.co/blog/a-month-of-travel/): The last couple of weeks I’ve had another bout of traveling to conferences. I’ve been lucky this time: all three... - [World Usability Congress 2018](https://niteo.co/blog/world-usability-congress-2018/): In the middle of October, I went to Graz to attend World Usability Congress. This conference first started 10 years... - [The Niteo Handbook update - less bloat, more information](https://niteo.co/blog/the-niteo-handbook-update-less-bloat-more-information/): Documentation naturally grows with the company. But if you’re not careful it can quickly become bloated and unnecessary detailed. This... - [IRL#5: Ljubljana](https://niteo.co/blog/irl5-ljubljana/): Summer is a great time to be in central Europe because of long days and good weather (when it’s not... - [GopherConUK](https://niteo.co/blog/gopherconuk/): While part of the dev team was still on EuroPython, Janez and I were packing to go to this year’s... - [PyConWeb 2018](https://niteo.co/blog/pyconweb-2018/): PyConWeb is an international Python Web conference held in Munich. Its main purpose is to talk about Web tools and... - [How to get to the job interview at Niteo as a developer](https://niteo.co/blog/how-to-get-to-the-job-interview-at-niteo-as-a-developer/): In June we’ve opened up three job positions and received A TON of applications. Python job posting alone received more... - [My Experience at iCEE.fest 2018](https://niteo.co/blog/my-experience-at-icee-fest-2018/): Two weeks ago I was at the iCEE. fest conference. I decided to go because it takes place in Bucharest... - [Niteo is hiring!](https://niteo.co/blog/niteo-is-hiring/): Currently, Niteo has three open positions: An enthusiastic Python developer, WordPress & WooCommerce Developer, DevOps with a love for Python... - [LTV Conf, May 2018, London](https://niteo.co/blog/ltv-conf-may-2018-london/): I love going to conferences in London because it is one of the rare cities I have a direct connection... - [Resuming uploads to Amazon S3](https://niteo.co/blog/resuming-uploads-to-amazon-s3/): I am escaping continental winter at the moment which means my internet connection is not perfect. I was uploading a... - [IRL#4: Istanbul](https://niteo.co/blog/irl4-istanbul/): Last month we again held our biannual in-person gathering of all Niteans, the IRL. As is customary, we meet somewhere... - [AWS EC2 gotchas](https://niteo.co/blog/aws-ec2-gotchas/): Lately, AWS has been giving us a lot of headaches on the Easy Blog Networks project. It turns out only... - [Recording Talks](https://niteo.co/blog/recording-talks/): Last year on IRL#2, our biannual in-person get-together, we decided to start recording talks, so that those that could not... - [Nitean Recognition](https://niteo.co/blog/nitean-recognition/): “Bang a gong, get it on. ” While the lyric is pulled from a modestly talented rocker in the 70s,... - [Conference hiatus is over](https://niteo.co/blog/conference-hiatus-is-over/): Back in the day when Niteo was still a consulting company I had to do a lot of traveling to... - [SaaStock, September 2017, Dublin](https://niteo.co/blog/saastock-september-2017-dublin/): This was one of my first conferences outside the Internet Marketing industry and I mostly went to it to expand... - [Upgrading our Intranet to Plone 5](https://niteo.co/blog/upgrading-our-intranet-to-plone-5/): While we haven’t done any Plone consulting (well, *any* consulting to be exact) in over 3 years, we still use... - [Thailand was a blast!](https://niteo.co/blog/thailand-was-a-blast/): It’s January — time for the “IRL”, our biannual in-person get-together. Summer IRLs happen in (around) Slovenia since that means... - [How we work in NiteoWeb](https://niteo.co/blog/how-we-work-in-niteoweb/): Update: see the latest version of this document on our Handbook. NiteoWeb is a distributed team of Web experts spread... - [Strings in Python 2 and Python 3](https://niteo.co/blog/strings-in-python-2-and-python-3/): The goal of this post is to show you how to properly use encode and decode in python 2 and... - [IRLs](https://niteo.co/blog/irls/): NiteoWeb is a remote-first team. While we do have a physical office in Ljubljana, few people go there regularly. Most... - [Lessons Learned from PyMunich 2016](https://niteo.co/blog/pymunich-2016/): At the end of October there was a Python conference in Munich (PyMunich). For a regional conference it was quite... - [A dev’s MacBook from scratch](https://niteo.co/blog/a-devs-macbook-from-scratch/): I’ve been a long time Apple user. I hate a lot about the company’s policy and how they treat their... - [Writing The Docs - Prague 2016](https://niteo.co/blog/writing-the-docs-prague-2016/): On September 19th and 20th Write the Docs Meeting took place in Prague. This year I had the pleasure to... - [WP Meetups](https://niteo.co/blog/wp-meetups/): A few months back I noticed we actually have regular WordPress Meetups in Ljubljana, our base town. We attended one... - [Lessons learned from EuroPython 2016](https://niteo.co/blog/lessons-learned-from-europython-2016/): This was my first EuroPython conference and I had high expectations because I heard a lot of good things about... - [Y U NO USE CLIPBOARD MANAGER??!??!11?!oneone](https://niteo.co/blog/y-u-no-use-clipboard-manager11oneone/): Every time when I am in a pair-programming session and the other person does not use a clipboard manager I... - [New NiteoWeb.com website!](https://niteo.co/blog/new-niteoweb-com-website/): Well, we haven’t worked in the consulting business for almost two years now, so it was about time we changed... - [Dear Plone, welcome to year 2014](https://niteo.co/blog/dear-plone-welcome-to-year-2014/): TL;DR: Production-level Plone on free-tier Heroku: https://github. com/niteoweb/heroku-buildpack-plone First, a bit of history: it was year 2006 and I was... - [NiteoWeb attended a Pyramid sprint in Halle, Germany](https://niteo.co/blog/niteoweb-attended-a-pyramid-sprint-in-halle-germany/): Gocept, a company based in Halle (Saale), Germany, organized a Pyramid sprint, which lasted from 15th to 17th August 2013.... - [Setuptools - run custom code in setup.py](https://niteo.co/blog/setuptools-run-custom-code-in-setup-py/): A week or so ago I started developing an experimental Python package for one of our projects. At some point... - [Write a Plone CLI maintenance script](https://niteo.co/blog/write-a-plone-cli-maintenance-script/): This is a quick tip on how to write your own command line maintenance scripts for your Plone application. Recently... - [Load overrides.zcml in plone.app.testing](https://niteo.co/blog/load-overrides-zcml-in-plone-app-testing/): Today I was working on a project where we use overrides. zcml to easily override some default Plone behavior. All... - [Dexterity vs. Archetypes](https://niteo.co/blog/dexterity-vs-archetypes/): TL;DR: migrating your Archetypes content to Dexterity shrinks your Data. fs considerably! I’ve started looking into migrating Archetypes content in... - [Raspberry PI boot to browser](https://niteo.co/blog/raspberry-pi-boot-to-browser/): Here at NiteoWeb, we use various SaaS monitoring and logging providers such as Librato Metrics and Papertrail to keep on... - [Convert z3c.form field desc. to tooltip](https://niteo.co/blog/convert-z3c-form-field-desc-to-tooltip/): Let’s say you have a typical form with some input fields. By default z3c. form displays a description (if provided... - [How to change element's ID with Diazo?](https://niteo.co/blog/how-to-change-elements-id-with-diazo/): A common scenario: on your website all subpages share a common header, but you want a different header on the... - [Robot on Travis - uploading results to S3](https://niteo.co/blog/robot-on-travis-uploading-results-to-s3/): This is a walkthrough of how one could upload to Amazon S3 screenshots and other output files produced by Robot... - [10 days to sprint in Antwerp!](https://niteo.co/blog/10-days-to-sprint-in-antwerp/): The Belgian Beer Sprint is nearing ever so closer! Only a bit over a week is left until we start... - [Testing log output](https://niteo.co/blog/testing-log-output/): ATTRIBUTION: This post was inspired by Domen’s Mocking logging module for unittests post back from 2009. Most of the code... - [Fixing unresolved dependencies error](https://niteo.co/blog/fixing-unresolved-dependencies-error/): For a while now we’ve been getting the following errors on one of our sites: WARNING GenericSetup There are unresolved... - [OpenVPN over SSH](https://niteo.co/blog/openvpn-over-ssh/): Prelude I’ve recently moved to Barcelona to continue my Computer Science studies on UB. First thing I noticed walking into... - [Professional Plone 4 development review](https://niteo.co/blog/professional-plone-4-development-review/): Short summary If you are doing Plone 4 development, go buy this book. Now. Some background I started working with... - [Plone 4 dev on Lion](https://niteo.co/blog/plone-4-dev-on-lion/): Introduction Recently I upgraded to OS X Lion and here are my notes on how I got my working environment... - [Help me get to PloneConf!](https://niteo.co/blog/help-me-get-to-ploneconf/): Intro Hi, I’m Nejc, a Plone user since 2005. I’m trying to get to the Plone Conference in San Francisco... - [collective.table, report #3](https://niteo.co/blog/collective-table-report-3/): Work report A week ago, myself and my mentor both participated in the Plone Sauna Sprint. It was an epic... - [collective.table alpha release](https://niteo.co/blog/collective-table-alpha-release/): Introduction It’s now past the mid-term evaluation deadline for my Google Summer of Code project and it’s time to release... - [collective.table GSoC report](https://niteo.co/blog/collective-table-gsoc-report/): Introduction It’s now been over a month since I started my Google Summer of Code project. It’s been a fun... - [Collective SVN project -> GitHub](https://niteo.co/blog/collective-svn-project-github/): More and more Plone projects are being migrated over to GitHub for various reasons. Here’s a quick guide on how... - [Assertion `t_size >= b_size' failed](https://niteo.co/blog/assertion-t_size-b_size-failed/): Recently, when migrating a Plone 4 site from one VPS server instance to another, we had the following problem: We... - [Multiple configurations for Tunnelblick](https://niteo.co/blog/multiple-configurations-for-tunnelblick/): A while ago I wrote about configuring Tunnelblick OpenVPN client for OS X. Here is how you can have multiple... - [Finding bad blocks on USB flash drives](https://niteo.co/blog/finding-bad-blocks-on-usb-flash-drives/): After a recent thorough cleaning of my office desk I found a handful of USB sticks. I knew some of... - [Deploying Cyn.in 3.1.3 on CentOS 5.4](https://niteo.co/blog/deploying-cyn-in-3-1-3-on-centos-5-4/): Last week we were upgrading Cyn. in to the latest version. After a few days of testing on a local... - [Testing memoized methods](https://niteo.co/blog/testing-memoized-methods/): For a recent Plone project we needed to write unit tests for methods that were using plone. memoize for caching... - [Order of 'parts' when compiling lxml](https://niteo.co/blog/order-of-parts-when-compiling-lxml/): CentOS’s repos don’t have a working version of libxslt (you need 1. 1. 20, repos have 1. 1. 17) so... - [Upgrade Cyn.in 2.1 to 3.1.3](https://niteo.co/blog/upgrade-cyn-in-2-1-to-3-1-3/): We started using Cyn. in for internal documentation repository about 2 years ago. We are a small team of developers... - [Secure IM for internal communication](https://niteo.co/blog/secure-im-for-internal-communication/): During this summer we finally got some time to review our internal working processes. One thing clearly missing was a... - [Click2Sell integration for Plone](https://niteo.co/blog/click2sell-integration-for-plone/): After integrating Clickbank with Plone last month we decided we also need integration with Click2Sell affiliate marketing network. A new... - [Compiling lxml on 64bit CentOS](https://niteo.co/blog/compiling-lxml-on-64bit-centos/): A few days ago I encountered a problem while deploying Plone 4 with collective. xdv to a CentOS cloud instance.... - [DD-WRT + Tunnelblick = OpenVPN](https://niteo.co/blog/dd-wrt-tunnelblick-openvpn/): Debating about VPNs on the Sauna Sprint, sprinters convinced me that we should use VPN for remote access to our... - [Back from Helsinki](https://niteo.co/blog/back-from-helsinki/): I’m back from another legendary sprint: Plone Sauna Sprint in Helsinki. No need to say anything more, here are the... - [Clickbank integration for Plone](https://niteo.co/blog/clickbank-integration-for-plone/): So you want paid membership on your Plone site? Look no further, we present to you niteoweb. clickbank. It’s a... - [MladiPodjetnik.si performance tweaks](https://niteo.co/blog/mladipodjetnik-si-performance-tweaks/): MladiPodjetnik. si is a portal we’ve been actively developing since 2006 and has since seen 3 revisions. The latest one,... - [New Plone website - Vodja.si](https://niteo.co/blog/new-plone-website-vodja-si/): It’s time for a new website release. This time it’s Vodja. si. Vodja. si is a presentation website for a... - [IMW, Athens and Cathedral sprints](https://niteo.co/blog/imw-athens-and-cathedral-sprints/): I’ve attended 3 sprints in the past month. Sprints are a great way to learn new Plone techniques and of... - [New project - BigContentSearch.com](https://niteo.co/blog/new-project-bigcontentsearch-com/): Last week we introduced a new project – BigContentSearch. com. It will be the first PLR membership website on the... - [OS X specific .cfg for collective.xdv](https://niteo.co/blog/os-x-specific-cfg-for-collective-xdv/): The collective. xdv manual on plone. org tells you how to customize your buildout. cfg in order to be able... - [New Wordpress sites](https://niteo.co/blog/new-wordpress-sites/): In the past few months we’ve deployed 3 new WordPress sites. They are all basic presentation sites with low running... - [New Plone website - LifeInLjubljana.si](https://niteo.co/blog/new-plone-website-lifeinljubljana-si/): During the first month of 2010 we’ve been busy developing a new site for Erasmus students in Ljubljana – LifeInLjubljana.... - [Testing session in Plone 3.3](https://niteo.co/blog/testing-session-in-plone-3-3/): Yesterday, while I was working on LifeInLjubljana. si, I had to test if some data was correctly written to Plone’s... - [unrestrictedGetObject()](https://niteo.co/blog/unrestrictedgetobject/): Argh! Sometimes I am truly amazed by how much I can complicate things. For the past year or so, every... - [CWPortlets, Scrawl and DISQUS](https://niteo.co/blog/cwportlets-scrawl-and-disqus/): Following previous post, here are instructions to get above mentioned products running on Plone 4 Alpha 2. Products. ContentWellPortlets ContentWellPortlets... - [Plone4 + collective.xdv + deco.gs](https://niteo.co/blog/plone4-collective-xdv-deco-gs/): Here at NiteoWeb Ltd. we decided a few days ago that we should start trying out Plone 4 in order... --- # # Detailed Content ## Posts ### Sprint season is open - Published: 2025-02-21 - Modified: 2025-02-21 - URL: https://niteo.co/blog/sprint-season-is-open/ - Categories: Tech I used to go to a ton of sprints. Then I got kids. So I made sprints come to me by organizing four OceanSprints. Now that kids are a bit older, it was time to attend a sprint again. What better choice than ThaigerSprint, an offspring of OceanSprint? It was such a relief not being the main organizer! I could actually focus on getting shit done instead of running around to refill TP or something. Here's just the highlight of achievements: pgweb now has a NixOS test. elm-review has been rewritten from node2nix to buildNpmPackage, and a simple version test added. elm-land 0. 20. 1, after more than half a year of trying, is now finally working on NixOS. I wrote a guide on how to be a Happy Nixer on a Mac, with lots of help from Jacek and Michael. Besides hacking, I really enjoyed Chiang Mai. I started every day with a Muay Thai training with Domen, ate a bunch of unordinary food, tried smoothies in all sizes, colors and condiments, finished the day off with a Thai massage and fun activities with fellow Nixies. The week flew by in an instant! Big thanks to clan. lol for sponsoring the event! See y'all next month at OceanSprint! --- ### Niteo IRL#15 - Kranjska Gora - Published: 2025-01-29 - Modified: 2025-01-29 - URL: https://niteo.co/blog/niteo-irl15-kranjska-gora/ - Categories: General Our 15th In-Real-Life meetup is in the books! Hard to believe our first IRL was back in 2016 in Croatia. Eight years and countless memories later, we gathered in Kranjska Gora, Slovenia. Normally, we chase the sun at this time of year, but thanks to someone's less-than-ideal planning, we stayed closer to home. That didn’t stop us from making the most of it! Bjørnar gets a special shoutout - he made it all the way from Japan, just a day after traveling from Norway and we’re incredibly grateful he managed to join us. The weather was cold but absolutely stunning. Every noon, the sun peeked over Lake Jasna, treating us to breathtaking views. As always, we balanced work and play. We had productive planning sessions, but also made time for some adrenaline—sledding and ski running kept us active and entertained. To cap it all off, we ended the IRL in Ljubljana’s grubbiest bar. But hey, it had karaoke, and that’s all that mattered (for some). For the full experience, check out our 1-minute summary video. https://www. youtube. com/watch? v=rbj9z4rxt7o --- ### NixCon 2024 Berlin - Published: 2024-11-11 - Modified: 2024-11-26 - URL: https://niteo.co/blog/nixcon-2024-berlin/ - Categories: Tech Ever since the day NixCon 2024 dates were published, I was sad I was not going to be able to make it due to some personal stuff taking place that week. But then about 10 days before the event, the personal stuff got moved, and I was free to go! Yay, Berlin! It was so nice to meet in person a bunch of Nix people I have met over the years, either online or in-real-life, and talk all things nix, and beyond. As often, of all the talks, I enjoyed lightning talks the most. I attended a few workshops and the stand-outs had to be the introduction to devenv. sh by Domen, and a deep dive into NixOS Tests by Jacek. My most recent open source repo is already using devenv. And I'm planning to add NixOS Tests for some Elm libraries that I use and help to maintain in nixpkgs. Speaking of Elm and nixpkgs, the last day of the conference was a "hackday" or what some of us old kooks would call a "sprint". I started working on refactoring Elm packages from node2nix to buildNpmPackage. Apart from conferencing, we had many a good beer, a private tour of one of the oldest hackspaces in the World and even a proper wood-stove sauna! Could be worse! Catch y'all at ThaigerSprint, OceanSprint or the next NixCon! --- ### PyCon JP 2024 - Published: 2024-10-02 - Modified: 2024-10-02 - URL: https://niteo.co/blog/pycon-jp-2024/ - Categories: Tech Another Year, Another PyCon Japan Another year, another fantastic PyCon Japan! This year’s conference in Tokyo was filled with insightful talks, interesting conversations, and a welcoming community that made every attendee feel right at home. As always, PyCon Japan proved to be more than just a tech conference; it was a celebration of everything that makes the Python community so special. The theme for this year was summed up perfectly by the tagline, "from everyone import PyConJP. " This simple yet powerful phrase encapsulates the spirit of the conference: that we all have something to "import" (read: learn) from one another. Whether you’re a seasoned developer or just starting your Python journey, there’s always something new to discover, and PyCon JP is the perfect place to do just that. One of the best parts of PyCon Japan is the chance to catch up with old friends and make new ones. It’s incredible to see familiar faces year after year and to share the latest updates, projects, and experiences. Even more rewarding is the opportunity to meet new people who are just as passionate about Python and technology as you are. These connections are what make PyCon JP feel like a reunion of sorts—a gathering of like-minded individuals who are eager to share knowledge and experiences. The talks and booths this year were great. From deep dives into advanced Python topics to beginner-friendly sessions, there was something for everyone. The speakers brought a wealth of knowledge and enthusiasm, and it was... --- ### Niteo IRL#13 - Lanzarote - Published: 2024-01-24 - Modified: 2024-01-24 - URL: https://niteo.co/blog/niteo-irl13-lanzarote/ - Categories: General For the 13th IRL edition, we gathered at our Niteo house in Lanzarote. Nejc had already hosted a few Ocean sprints at the house, so everything ran seamlessly, like a finely-tuned machine. We went through the usual agenda - reviewing the state of the company and projects, planning for the upcoming year, and optimizing internal processes. One of the biggest changes was the decision to transition from Scrum to Kanban. Given the smaller size of our team and the self-sufficiency of each Nitean, we had already minimized meetings by cutting down on stand-ups. With the adoption of Kanban, we now look forward to a single weekly meeting. Everyone is excited about fewer meetings, but it's too early to draw any conclusions. See handbook for more details about our new Kanban process. Besides productive work, we had plenty of fun. This was the most sports-intensive IRL for sure! Nejc guided us through his favorite MTB trails on the island. On the way up, we enjoyed the beautiful landscape, and on the way down, we tried to stay in one piece. We took surfing lessons at the famous Famara beach. With the perfect conditions for beginners, we managed to stand up on the board (for a few seconds). Glub glub glu glu glub glu glub glub glub. Not sure what is more entertaining - playing VR game or watching someone else playing it. With all the work and activities, we were too busy to take a group photo that includes everyone. Two... --- ### EuroPython 2023 - Published: 2023-08-08 - Modified: 2023-08-08 - URL: https://niteo.co/blog/europython-2023/ - Categories: Tech - Tags: Python EuroPython in 2018 was my first international conference. After five years, I eagerly joined another EuroPython. I hopped on a night train and woke up with a view of beautiful sunflower fields near Prague. With the conference starting the next day, I had some spare time to explore the charming city. In the evening I joined a dinner with fellow conference attendees for some tasty Czech food and tech discussions. As engineers, we are often too focused on writing beautiful, optimized, and scalable code using the latest frameworks, libraries, and tools and overlook the true impact of our work. A talk from Merve Noyan was a good reminder about that. After the devastating earthquake in Turkey a group of volunteers built a map to help coordinate rescue missions and distribution of essential supplies. They built different models that were classifying what kind of help people need and their location. The data was sourced from tweets and Instagram posts containing requests for help. Initially, people posted their locations to be rescued from collapsed buildings, but later, the focus shifted to requests for water, shelter, and medicine. It was heartwarming to witness how technology can play a big role in times of crisis. On the technical front, I liked the tips from Sebastian Buczyński about BDD tests. The key takeaway from the talk was the importance of making Gherkin scripts readable for non-technical individuals, rather than writing technical step-by-step instruction script. F-Strings in Python are getting an improvement. Pablo Galindo Salgado and Marta... --- ### Niteo Summer IRL meetup in Ljubljana - Published: 2023-07-31 - Modified: 2023-08-04 - URL: https://niteo.co/blog/niteo-summer-irl-meetup-in-ljubljana/ - Categories: General Our summer In-Real-Life meetup was held in Ljubljana, in the heart of Slovenia. The first things you see as you approach it are castles, numerous parks, and dragons. :) The dragon is the symbol of the city. You will see dragons everywhere... on bridges, at the castle, and decorating railings and buildings. Moreover, Ljubljana is a charming old town with beautiful architecture and rich history. Walking around this green city is a real pleasure. Niteans gathered to have some fun and work in the Computer museum space. This is not the first time Niteans have met there. But have enough words been said about this great space before? This venue offers an exciting journey into the history of computers with great exhibits, which you can try. The atmosphere there is amazing, and all the computers on display are fully functional. Every visitor can interact with many devices and get an experience of how computers and technology used to be and how they've evolved. Our team is not an exception, and we also plunged into this nostalgia and played some retro games: Liero, Mortal Kombat, Doom, etc. On IRL, we’ve done a lot of work, discussed some future plans, and did planning for new projects. In the evening we usually had a nice time together in different bars, pubs and restaurants.  There are a lot of tasty craft beers from Slovenian breweries and it is a real paradise for beer lovers :) You will definitely want to bring some souvenirs from... --- ### Niteo IRL#11 - Manila - Published: 2023-02-03 - Modified: 2023-02-19 - URL: https://niteo.co/blog/niteo-irl11-manila/ - Categories: General Mabuhay! It’s winter 2023 and time for our in-real-life meetup. It's our 11th IRL, but this will be my first time joining one. Because of the COVID lockdowns and the war in Ukraine, I was only able to attend these meetups virtually. We do these IRLs not only for work but also to bond and create memories that are not limited to only the black screen. This blog post will immerse you in the memories of this adventure. Mabuhay! IRL#11 Niteans decided to organize this face-to-face meetup in Manila, Philippines, and our team gathered on this island. Manila, Philippines Manila itself is a beautiful and nicely planned city. The only thing more beautiful than the landscape there is the people themselves. To me, the Filipino people are what truly make the Philippines what it is: nice, easygoing, and happy. Evening in Manila My flight to Manila was a bit long (18 hours). Nonetheless, I've safely arrived in the Philippines. Wooh! It was the first time I met everyone in real life, and I would be lying if I said that I was not worried at all. Moreover, this was my first trip after a long break. Seeing my coworkers in real life was amazing and a bit exciting. How to prepare for the first IRL abroad and not forget anything? I started preparing for it by gathering documents for receiving my visa. This is very important to do in advance and responsibly. Next, every Nitean should think about packing. When... --- ### Fast development on NixOS - Published: 2022-11-10 - Modified: 2022-11-10 - URL: https://niteo.co/blog/fast-development-on-nixos/ - Categories: Tech - Tags: nix, nixos We've been using NixOS for a few years, and it has proven to be a stable and reliable OS. More importantly, it's declarative and reproducible, which is one of the main reasons we decided to migrate ~700 of our Ubuntu servers to NixOS. However, it has a few downsides, and one of the biggest ones is the slow iteration of service configuration when you're still in the development phase. For example: let's say you want to create a new NixOS server where you'll have your WooCommerce shop, your blog and some Python API service you need for managing WooCommerce. You decide to use HAProxy in front, to act as a reverse proxy. Configuring this in NixOS is very easy because, for the most part, all the configuration is already set up, and in most cases, you only need to enable a service. In our case, if we want to install and start the HAProxy service, we put this in our . nix configuration: services. haproxy. enable = true; After rebuilding NixOS, we'll have HAProxy running with the default settings. Great, but now we need to add our own custom HAProxy configuration: services. haproxy. config = '' global maxconn 5000 log /dev/log local0 ... ''; After saving the configuration. nix file, you will quickly realize that the HAProxy configuration hasn't changed. It's still the same as before you made your changes to the services. haproxy. config even if you restart the service (i. e. systemctl restart haproxy). This is because of... --- ### PyCon JP 2022 - Published: 2022-11-01 - Modified: 2022-11-07 - URL: https://niteo.co/blog/pycon-jp-2022/ - Categories: Tech It’s good to be back! The past two PyCons in Japan have been online, so it was nice to be back in person where you could actually enjoy the little things in between talks like meeting and talking to other attendees and exhibitors. This year, the event took place in Ariake, Tokyo, which is home to several unique buildings like Tokyo Big Sight and Tokyo Baycourt Club. Ready for day 2 at PyCon JP 2022 in Ariake, Tokyo At the time of the conference, Japan had just opened up its borders to tourists so a few people from overseas had made their way to the conference which was very nice to see. Unfortunately, some of the English-speaking speakers were prohibited from coming because of visa issues so the track for people who couldn’t speak Japanese was a bit limited on day 1. Day 2, however, had plenty of talks in English to choose from. Still being careful to avoid the spread of Covid, this PyCon was a silent conference so all attendees wore audio receivers and any questions to the speakers had to be submitted online. This actually worked quite well in practice and submitted questions could be upvoted by other attendees as well. Oh, and there was an official PyCon JP party after the second day ended where party-goers had to have tested negative on a Covid antigen test earlier that day to attend. The party had a nice atmosphere, good food and drinks, and included a few lightning... --- ### NixCon Paris 2022 - Published: 2022-10-24 - Modified: 2022-11-06 - URL: https://niteo.co/blog/nixcon-paris-2022/ - Categories: Tech - Tags: nix, nixos After three years, we finally got a proper IRL NixCon. Since the Nix community is not the biggest one, it was nice to talk about Nix for three days (two at the conference and one at the sprint). We heard many interesting talks and answered a few important questions. So let's start with the most exciting things first. If I had to give this conference a tagline, I would give it "What's up with Flakes? ". This was probably the most asked question, and I think the organisers were aware of this beforehand, so Eelco gave a talk about them (I recommend you watch it). The short version is: Flakes are the de facto standard, but they have a major problem (primarily) with large packages. The second biggest news was the new Nix Board. The board should help the community overcome obstacles and allocate resources for, e. g. meetups, conferences etc. Officially, they are not there to decide on any technical decisions (that is still in the hands of the community), but only time will tell if that will be the case. Nix community grows rapidly, and several talks addressed this by pointing at the documentation and how to be more beginner friendly as a community. We all need to be aware that at this moment, at least half of Nix users are beginners, and with this growth rate, it will stay like this for a long time. And this is one complaint I have about the conference: it wasn't... --- ### Indispensable pytest plugins - Published: 2022-10-07 - Modified: 2022-10-09 - URL: https://niteo.co/blog/indispensable-pytest-plugins/ - Categories: Tech - Tags: Python, Testing I’ve been babbling on about testing for a decade now. Here’s a quick list of pytest plugins I use in most of my Python projects: pytest-cov - pytest integration for the wonderful coverage tool by Ned Batchelder. pytest-mock - pytest integration for the unittest. mock library. pytest-instafail - Print out the test failure as it happens, instead of waiting for all tests to finish. I've only recently discovered this one, and I'm breaking into cold sweat thinking how much time I've wasted in the past decade waiting for the test suite to finish just to see the output of that one failing test. pytest-randomly - Catch flaky tests by running your tests in a random order. Additionally, you can pass in the —randomly-seed value to repeat a randomness-induced failure. Hate flaky tests? Check out BuildPulse. io to get help finding and fixing them. pytest-socket - I like my tests fast. A surefire way to make tests slow is to have them connect to the Internet. This plugin prevents any test from doing (unmocked) network calls and as such ensures a faster test suite. pytest-csv - A dependency of BlueRacer. io, so that I can keep an eye on the speed of my test suite. pytest-splinter - Real-browser testing of web apps with splinter. Unit tests are not enough. I always have a few real-browser tests to verify that all parts of my stack are correctly glued together. That's it, short and sweet. Happy testing! --- ### Niteo IRL#10 - Published: 2022-08-01 - Modified: 2023-02-06 - URL: https://niteo.co/blog/niteo-irl10/ - Categories: General Man... I can’t believe it has been two and a half years since I was abroad. The last time was actually IRL#8 in Bangkok, Thailand. A global pandemic and Japan’s strict border control sure made it difficult for an expat to go traveling. This time, though, the stars had aligned and I was once again sitting fairly comfortably in a chair 30. 000 feet in the air, traveling close to the speed of sound! After two flights and a 13-hour (! ) layover, my feet finally touched Slovenian ground. A few minutes later when I stepped out into the arrivals hall, Nejc was waiting for me with a poster of a bear in his hands (my name means bears in Norwegian) and we were off to Ljubljana. It was truly amazing to see most of my coworkers again after so long, even though the circumstances definitely could have been better. We started each workday with all of us taking COVID-19 rapid tests, and all restaurant visits were made solely to venues with outside seating. On the first day of IRL, Dejan and Nejc presented the current state of the company and its finances. We then proceeded to make a list of all the discussions we needed to have in the next few days in order to be prepared for the next quarter. The discussions went smoothly and we soon found ourselves working on some exciting new projects before those of us who were physically in Ljubljana went out for activities... --- ### PyCon.IT 2022 - Published: 2022-06-26 - Modified: 2022-06-27 - URL: https://niteo.co/blog/pycon-it-2022/ - Categories: Tech At the beginning of the month, I made a quick road trip down to Florence for this year's edition of PyCon Italia. I try to never miss a chance for a conference I can *drive* to, and Tuscany is just such an awesome place to visit, it really was a no-brainer. The organizers have been throwing conference for a number of years so everything was smooth and organized. Everyone was asked to wear a mask when inside in the hallways and lecture rooms, which was perfectly fine as there were lots of tables outside to sit and chat. The food was obviously fantastic, as one would expect. I gave a re-vamped version of my Don't Rely On Discipline talk, evangelized the use of nix-shell, had long discussions about tech and business with Justin about Fortressa and Pareto Security, and found two nice little utilities that I have already added to my toolkit: flake8-ensure-ascii -> ensure your codebase only includes ASCII characters and as such prevent supply-chain side-channel attacks,pyupgrade -> auto-format your Python files according to the latest style recommendations. --- ### OceanSprint 2022 - Published: 2022-06-09 - Modified: 2022-06-09 - URL: https://niteo.co/blog/oceansprint-2022/ - Categories: Tech - Tags: nix, Sprint The mind has not yet completely recovered from all the brain explosions that happened during OceanSprint 2021, and I was already planning the next one. I've never organized two sprints so close to each other, but it worked out great! Domen and I knew exactly what we were getting into, most of the vendors we used were the same, the logistics were mostly smooth sailing -- as much as they could be with the pandemic still in effect. 14 Nix hackers gathered at Niteo House back in April for a week of squashing bugs and pushing the Nix ecosystem further. Some flew in as far away as Australia to get in on the fun! Like the previous sprint, this was a productive one: nix. dev tutorial's code samples are now tested in CI. This helps us prevent broken examples in the future. We are booting into M1 NixOS! Not everything works, but getting there. Lots of fixes pushed upstream. dream2nix automatically parses your existing projects and automatically creates flakes using the lower level tooling for each language. We prototyped a solution to incrementally build VirtualBox source using Nix. It's a generic function that overrides an existing derivation by feeding in the previous output. If a NixOS test runs for a long time, there could for example be a typo in the script. With typechecking that's detected before running the script, whereas before full test has to run. We replaced our current script logic with systemd as an opt-in. The motivation... --- ### How we spent $980,000 on a failed SaaS project - Published: 2022-05-23 - Modified: 2022-06-08 - URL: https://niteo.co/blog/failed-saas-project/ - Categories: Tech Three months after we closed the sale of WooCart, our project that was gonna “make it big”, I am ready to review the full financial consequences of our failure: $700k loss. Three months after we closed the sale of WooCart (hosting for WooCommerce stores), our project that was gonna “make it big”, I am ready to review the full financial consequences of our failure: Revenue: $280k (incl project sale)Expenses: $980kLoss: $700k It’s also been four years of company focus and four years of my life that went into the project. We more or less gave it everything, but it still failed. This is a cautionary tale, and I hope you’re smarter than we were - because we read stories like this, and we still made the same mistakes. And yes, some mistakes are really, really obvious and really, really stupid. It’s funny how it never feels that way when you’re doing them. How we got into this mess The path to our first 7-figures was not easy. It took many failed ideas, a few solid projects, and about eight years of being in business. After we got a taste of success, we soon started looking at projects in more competitive markets for an even larger one. We probably learned something in these past few years, right? We kinda know what we’re doing now (red flag). Actually, no, I think we’re going to crush it (red flag). We got this! We might have been a bit arrogant. It didn’t help that my cofounder Nejc and I decided on the whole project in an afternoon (red flag), in a conversation that still haunts me to this day. Someone mentioned to me that the first product... --- ### Standing on the shoulders of giants - Published: 2022-02-25 - Modified: 2022-02-25 - URL: https://niteo.co/blog/standing-on-the-shoulders-of-giants/ - Categories: Tech - Tags: heroku, nix Whether we know it or not, we build things based on the work done before us. This is true in every aspect of life, and programming is no different. Every few weeks, we (at Niteo) have a developer session where we (developers at Niteo) talk about new things we learned, cool libraries/tools we discovered, etc. Last week Nejc talked about optimising Nix build for Pareto Security. If you use Nix to build your environment, I strongly suggest reading his post. On EBN, we also have a long deployment time, and his talk got me thinking about Nix build on EBN. Usually, it takes around 30-40min for the EBN app to be deployed. Unfortunately, we didn't measure Heroku deployments until this point, so I don't have an exact number on this. What I do know is the size of the Docker image. It's a whopping 1. 95GB. I know the EBN stack is big, but I had a feeling (based on Nejc's blog post) that we also have something in our build that is causing such a large image. So I started digging, exactly like Nejc wrote in his blog post. First, by producing a local build that I use to feed into nix-store to analyse what was produced (again, see Nejc's blog post for step-by-step instructions). nix-store produced ~1. 7k lines of dependencies. I was overwhelmed at first. I tried to represent the data visually, but it was even worse. I couldn't wrap my head around it. After looking at... --- ### Nix build on a diet - Published: 2022-02-13 - Modified: 2022-05-09 - URL: https://niteo.co/blog/nix-build-on-a-diet/ - Categories: Tech - Tags: heroku, nix At Niteo, we are using nix-shell to build isolated development and production environments. We deploy production as a Docker image on Heroku. Recently, I've noticed that Pareto Security dashboard app deployments have been very slow. Almost 10 minutes, even more on a busy afternoon. Most of the time was spent in copying files around, as Heroku seems to have terrible disk i/o dedicated to building Docker images. I like my CI/CD pipelines in the range of 3 to 7 minutes, so I took some time to take our production env on a diet. This post is a story of how I did just that, and reduced the resulting image size by 60%. And consequently halved the time it takes to deploy the latest commit to production. The journey Our Dockerfile is quite simple: Pull a minimal base image with preinstalled Nix and Cachix, along with a pre-fetched commit of nixpkgs, to speed things up. Run nix-build --attr herokuEnv to build the production runtime enviornment. Create the second stage image from scratch and copy over the result of herokuEnv. The first step was to run nix-build -A herokuEnv locally to get the derivation path: $ nix-build -attr herokuEnv these derivations will be built: ... created 431 symlinks in user environment /nix/store/rpy6why69q13snjv2byzm90qpcbqnffy-pareto Then I fed this path to nix-store to give me a list of runtime dependencies: $ nix-store --query --graph /nix/store/4ld5jzxrgibzkvcq3kqv5cffs5mlim38-pareto "/nix/store/nqz4h9cqfcvcn08nq80bzddkd9h6wq05-pareto"; "/nix/store/1cxrpmfwwvncncsp1hnmkapijsx927zj-bash-interactive-5. 1-p8" -> "/nix/store/nqz4h9cqfcvcn08nq80bzddkd9h6wq05-pareto"; "/nix/store/5wch96kji9zlffxjqpjdrszjzp4i7m3a-coreutils-9. 0" -> "/nix/store/nqz4h9cqfcvcn08nq80bzddkd9h6wq05-pareto"; ... I kept scrolling until I found this line: "/nix/store/vq7r6jvhn3mffzvi0x7w478llls7h2jv-gcc-10. 3.... --- ### Niteo IRL#FML - Published: 2022-01-31 - Modified: 2022-05-09 - URL: https://niteo.co/blog/niteo-irlfml/ - Categories: General We were really, really hoping we’d be able to meet up in January for a proper all-company IRL meetup after two years. Unfortunately, it was (again) not meant to be. Omicron surged in late 2021, and we had to cancel the meetup. That’s where the name of this virtual one comes. So it was back to Zoom. We’re pretty used to meetings online and can be very efficient, and this time it was no different. We flew through our agenda, had discussions, and made decisions for which we created Stories for future implementation. There were no issues left at the end to discuss, which made the 3-day meetup a success. In the evenings, we gathered on Mibo virtual space for meetings. We tried it a year ago, and it progressed a lot. While I absolutely love the idea of virtual spaces and thoroughly enjoyed the first 20minutes, there’s still some clunkiness to it that prevents it from being used for work. I’m expecting that it’ll be a lot better in another year, and maybe, just maybe, it can become a better way to meet online than Zoom. On evening socials, we did some gaming, one of them being Keep Talking, which was a ton of fun. Even though we can classify the meetup as successful, I, and everyone else, really hope this was the last time. --- ### Sprints are back! - Published: 2021-12-17 - Modified: 2021-12-17 - URL: https://niteo.co/blog/sprints-are-back/ - Categories: PeopleOps, Tech - Tags: community, nix, nixos, Sprint, travel Back in early 2010's, "sprints" were how I lived. Week-long events, in random places around the World, hacking on open source. From offices in European cities, to lake sides, castles and saunas. It's where I met some of my best friends, where I got business for Niteo's agency side. It's where I learned more than any university could teach me. And finally, it's where I had unimaginable amounts of fun. Hacking on Nix(OS) at OceanSprint 2021 But as the years flew by, I started feeling the downsides of constant traveling & hotel food. My health started declining. Every sprint came with a nagging feel that, yes, it was fun, but it was taking it's toll. Then I became a father. And that nagging feeling increased by a ten-fold. Every time I went away, I felt bad for not being around. I stopped organizing sprints. I almost stopped attending them. One in a year, maybe. "... and then you have to shove the swab into your brain. You know, like Nix. "Tests & coding in the cold -- the price to pay to attend a sprint during covid times I missed them, though, dearly. I felt like I wasn't learning as much as I did in the past, that I was falling behind. I remembered the early days, when I was daydreaming that one day, I'm gonna have a villa by the beach, and throw sprints there. It was gonna be so awesome! One day, I'll get there ... The real... --- ### Founder Summit in Mexico City - Published: 2021-11-08 - Modified: 2021-12-17 - URL: https://niteo.co/blog/founder-summit-in-mexico-city/ - Categories: General, PeopleOps I knew I missed conferences. But I did not fully understand how much. Being an introvert (that can act as an extrovert when needed) I rather enjoyed the lack of social interactions in the last year and a half. But I was getting more and more groggy as months went by. Nothing major, but I could definitely detect that my energy was kinda lower than usual and getting through the less interesting tasks at work was more of a chore. Biking 'round town before the opening party Then Founder Summit happened. A 4-day trip to Mexico City to spend time with like-minded founders of calm companies. Founders that value people over ubergrowth, their family over 100-hour-weeks and long-term sustainability over the next VC round. My kinda folks! Morning runs Coming back and decompressing from the event was such an eye-opener of how much I need these in-person interactions every now and then. How easy it was to build profound friendships with strangers over the course of just a few days -- something I forgot was doable for someone like myself. That even introverts need their tribe. Open rooftop boutique restaurant instead of a corpo-style conference room. Me likey! I'm writing this exploding with productive energy, getting up early every day eager to start working on helping fellow founders adopt better security practices with Pareto Security, even if it means answering support questions instead of coding. It's been a while since I felt this way, and boy did I miss it!... --- ### Attending MicroConf Europe '21 in Dubrovnik - Published: 2021-10-25 - Modified: 2021-12-17 - URL: https://niteo.co/blog/attending-microconf-europe-21-in-dubrovnik/ - Categories: General, Marketing MicroConf Europe in 2019 was the second to last conference I attended before COVID-19 struck. This year MicroConf returned to Dubrovnik. And it's an absolutely amazing location, plus the weather was great all three days. The conference was not large in 2019 but it was even smaller now - and that’s a good thing. I really dislike big conferences so this was great. It was about 100 people which made it very “intimate”. It also made it a lot easier to talk to the same people a few times so that it wasn’t just a 5-minute conversation and then you never see that person again. Having speakers mingle and chat with the attendees is also a great benefit of conferences like this. You get to ask some follow-up questions and have in-depth conversations. I had some really good conversations and built relationships with a few people whom I hope to see again at the next conference. Which, for me, will be the London local in May 2022. Hope to see you there! --- ### Deploying +100 servers with GitHub Actions - Published: 2021-09-24 - Modified: 2021-09-24 - URL: https://niteo.co/blog/deploying-100-servers-with-github-actions/ - Categories: Tech Last year we decided to replace our Ubuntu servers with NixOS. We were still on Ubuntu 14. 04, so we also had to upgrade all the services and tools, including PHP, MySQL, HAProxy, etc. As you can imagine, this was a lot of work, and you might be asking yourself, "why didn't you just upgrade Ubuntu? " and it's a good question. One that we asked ourselves several times, but we kept coming to the same answer: NixOS is declarative, reproducible, and it's hard to break it (as opposed to Ubuntu, where you often break something without even noticing). To learn more about NixOS, I highly encourage you to visit their site. But the story doesn't end there (or this would be a very short and dull blog post). Because of how our infrastructure is built, we have a lot of servers with minimal resources. We are talking about 1GB - 2GB of RAM and 1 CPU (e. g. , AWS t2 small). And, of course, we want to utilize our servers fully and not leave money on the table. On average, they would run ~15 services (e. g. , Telegraf, MySQL, HAProxy, Apache, Varnish, PHP-FPM, Redis, and many of our internal tools), so they would have very little memory free. In NixOS, whenever you change something (e. g. , HAProxy configuration, add/remove a user, etc. ), you need to rebuild it. But this takes a lot of memory (and CPU, but that is generally not an issue) which is... --- ### Concurrency in Go - Published: 2021-09-20 - Modified: 2021-09-20 - URL: https://niteo.co/blog/concurrency-in-go/ - Categories: Tech Concurrency in Go is an extensive topic, and we won't cover all the things in this post. There are tons of articles and several books that cover concurrency in depth. The goal of this post is to cover topics between basic and advance. We'll cover the usage of sync. WaitGroup and channels. Those two things combined can be powerful tools. Let's start first with sync. WaitGroup. The idea is to count how many goroutines we have scheduled and wait for them to finish. There is a simple example on Go by Example that shows this in action: const WORKERS = 5 func main { var wg sync. WaitGroup // initialise the goroutine "counter" for i := 1; i --- ### Why we're building a house in the middle of the ocean - Published: 2021-08-07 - Modified: 2021-11-08 - URL: https://niteo.co/blog/why-were-building-a-house-in-the-middle-of-the-ocean/ - Categories: General, PeopleOps Let's get the clickbaiting out of the way first: we're not technically building a house, we're renovating an existing villa. To make it more suitable for remote teams. The rest is true, though. It's on a unique subtropical island in the Atlantic Ocean! OK, but why on Earth would a software company build a vacation villa? The answer is about a decade old. When Niteo was just starting out, I stumbled upon Plone, a Web CMS with a fantastic community. I regularly attended conferences and "sprints", week-long coding marathons with fellow Plonistas at various locations around the World. These sprints were great to learn from the best developers, to meet different cultures and to have a heck of a good time! My first sprint, the Plone Cathedral Sprint 2010 in Köln. Many of the people in this photo are my close friends to this day. One time at Sauna Sprint, somewhere deep in the Finish forest, with my laptop in my lap, lounging by the lake after a long sauna session, my bucket list grew for a new item: someday, I want to have a beach house where I can throw sprints by the sea. How can one NOT have a great idea in a location like this! ? That day has come. Niteo House is a 3-bedroom villa on Lanzarote, an EU island of eternal spring. It can sleep up to 6 people, enough for small sprints, or enough for the organizing team of a bigger event. There are... --- ### Niteo IRL#9 - Published: 2021-07-15 - Modified: 2022-01-31 - URL: https://niteo.co/blog/niteo-irl9/ - Categories: General After a year and a half, Niteo finally organized our bi-annual In-Real-Life meetup. The third time is the charm! Unfortunately, we only managed to do it for half of the team. People in and around Slovenia, all vaccinated, met up in Ljubljana in a great space rented from the Computer museum. The other half of the team connected through Zoom and watched the presentations live, then connected virtually for work in small teams. We've done lots of exciting work, especially planning for new projects, which we hope we'll be able to reveal very shortly! Since this was partially a virtual meetup, we kept the duration to three days, instead of the regular five. Even with just those three days, we managed to hike the local hill (twice! ), did lots of work, caught up with colleagues, had three great lunches together, and two dinners, the final one being a real treat. Beef Wellington and baked octopus. It was *fantastic* seeing Niteans in person after so long, and we hope that the next IRL, the tenth one, is a full house event with no one missing. Fingers crossed that by January 2022, most of the World gets back to normal and everyone will be able to fly-in. See you in the Philippines! --- ### Postmortems - Published: 2021-04-01 - Modified: 2021-04-04 - URL: https://niteo.co/blog/postmortems/ - Categories: General, PeopleOps, Tech - Tags: Postmortem, tech Earlier this year, on one of our half-yearly IRL's, we had a discussion about whether or not we should proceed with a massive upgrade... an analysis or discussion of an event after it is over. Merriam-Webster The backstory Earlier this year, on one of our half-yearly IRL's, we had a discussion about whether or not we should proceed with a massive upgrade process that had been going on for the past year or so. The team that was working on it, myself included, had been facing numerous problems on a daily basis where it felt like if we plugged one leak it started leaking from a different hole so we were starting to get demotivated and it felt like no solution was in sight. The discussion went on for a few hours with a lot of strong opinions on both sides, for and against proceeding, but in the end, we decided that it was time to stop beating on the dead horse and start fresh with a new one. Nejc didn't feel like the right decision had been made, however, and decided to reinforce the team, and even join himself, to give it one last attempt with everything we had. After just two-three weeks with the reinforced team working on it we finally saw a light at the end of the tunnel, and most of our issues were either already solved or had been identified. Now, a full quarter later, we're certain we made the right choice to continue with and finish what we had started on. The postmortem Smallbones, CC BY-SA 3. 0, via Wikimedia Commons Realizing that we had almost made a... --- ### Niteo IRL: YA'RLY - Published: 2021-01-27 - Modified: 2021-11-08 - URL: https://niteo.co/blog/niteo-irl-yarly/ - Categories: General, PeopleOps After our first virtual IRL in July-2020, it's time for our first remote-first IRL. Which means Niteans were given options to plan and decide a location where they could meet other nearby Niteans and connect with the rest virtually. So, the plan was to divide and organise Mini-IRLs - one in Lanzarote and one in Asia. However, as the scars from the pandemic were yet to heal globally, most of the Niteans decided it would be best to stay put and wait for things to improve. As a consequence, team Lanzarote had to cancel and team Asia was on the verge of cancellation too. But two Niteans found a way to travel and meet in a place while ignoring public transport and crowded places as much as possible. It was me (Surya) and Arijit, two of the adventures loving coding partners in Niteo. We decided on Darjeeling(Queen of hills), West Bengal as the place since visiting it has been on our wishlist for a long time. No, actually riding on a bike to Darjeeling and Gangtok was the original wish. On motorbike towards Darjeeling We made sure to lower the risk factors as much as possible. We neither compromised investing on good protective riding gears, nor on medical kits, sanitizers and face masks. Although, we couldn't avoid getting sore butts due to the almost 15 hours long ride each way (excluding the night stay in a hotel). But when we reached our destination, needless to say, all of it was... --- ### Lowering H12 errors on Heroku - Published: 2020-11-25 - Modified: 2020-11-25 - URL: https://niteo.co/blog/lowering-h12-errors-on-heroku/ - Categories: Tech This post will briefly discuss H12 errors on Heroku, more commonly known as request timeouts, how we tackled them, and how we fixed them. Before we start, let's establish some context. We have an app that's a hub for ~600 servers. A few times per day, each server creates a request to the app, ensuring everything is in sync. As we started to add more and more servers, we saw more H12 errors on Heroku. We quickly realized that the problem is that, basically, our servers are DDoSing the app every time they make those requests. Because those requests come from a scheduled cronjob, they all come at approximately the same time. The quick fix would be to look into those requests and optimize them. But we wanted our app to handle that kind of a load, so we decided to look into HTTP server options. We were confident that we didn't optimize gunicorn (our HTTP server) enough, so we should start there. Gunicorn async option sounded very attractive because usually async works well with network IO. Before we started playing around with gunicorn settings, we had to create a simulation that would be our base point. We deployed the app locally and simulated the requests with hey. To be exact, we first spent a day or two deciding which tool to use and learning about different kinds of tests, but I'll skip this part. We started hitting our testing app with hey -n 100 -c 3 and slowly brought... --- ### Staging like it's 2020 - Published: 2020-09-14 - Modified: 2020-09-14 - URL: https://niteo.co/blog/staging-like-its-2020/ - Categories: Tech - Tags: staging Last year, we wrote a blog post on how we use Heroku's Review Apps to create staging apps for every Pull Request submitted to a project's repository. These apps are created and deployed automatically, completely isolated from the production environment, and contain the changes from the Pull Request. This allows every stakeholder to see how the changes proposed in the Pull Request will actually look when deployed. But there's a weak link in the chain: we are relying on developers and stakeholders to be disciplined enough to always click around the Review App linked in the Pull Request before clicking Merge. It has happened more than once that we assumed "surely it's fine to merge this PR, the Review App built fine and the fix is trivial" only to regret it later when production was down. To avoid human errors like these we're now taking things to next level. We have a process in place that spins up a browser and clicks around the Review App to confirm that the Review App wasn't just built correctly, but that it's actually possible to log in and do stuff. If there is an error in this test, the Pull Request is marked as failed and merging is prevented. How do we do it The entire process is split into two jobs:  Verify if the Review App is successfully deployed (i. e. both build and release Heroku stages are successful). Confirm that the new code didn't break anything by actually clicking around the... --- ### Niteo IRL: O'RLY - Published: 2020-07-31 - Modified: 2020-07-31 - URL: https://niteo.co/blog/niteo-irl-orly/ - Categories: General, PeopleOps As a remote-first company, Niteo invests in doing bi-annual IRLs (In Real Life) meetups to get everyone in the same time and space. Spending time with Niteans face-to-face is invaluable. The bonds we create during IRLs are strong — but our meaningful connections do not come from the onsites alone. We consciously work to develop these relationships throughout the year. But, with the onslaught of the pandemic, all travels are grounded. We've started preparations for our summer IRL which would have happened in Sri Lanka this month. While the trip was cancelled, we had our first remote "IRL" - there's a quotation in there since the two words create a paradox. So, how to run a successful virtual "IRL"? Get yourselves some awesome people. A virtual party is only as good as the attendants so if everyone does not engage, all you'll see are dead eyes staring back at you on your screen with some crickets in the background. We followed our usual IRL template - there's work, there's fun; there are beers and some good stories. We are all over the world so the crucial part of the preparation was finding the viable time - where it's not too late for those in Asia, and not too early for those in the Western hemisphere, specifically the United States. And we did manage to find the block of time that works for everyone, so off to a good start! We played online games - and there are a plethora that... --- ### Project isolation beyond requirements.txt - Published: 2020-04-16 - Modified: 2020-04-17 - URL: https://niteo.co/blog/project-isolation-beyond-requirements-txt/ - Categories: Tech I've been a Python dev for almost 15 years now and I've recently completely overhauled how I keep my development tools and dependencies in check. I'm so happy with my new setup that I couldn't wait to share it with fellow geeks! Some background I used to use Homebrew to install tools such as pyenv that I then used to install the exact Python version I needed that I then used to install the correct pipenv or poetry version that I needed that I then used to install all project Python dependencies. It's a long chain but "if you know what you are doing" it works. Most of the time. Until there was a new version of MacOS and I had to nuke my Homebrew environment and install everything again. Or when my system-installed black did not match the one that the project was using causing formatting failures in CI. Or when some other project implicitly depended on a non-Python library, such as chromedriver, to drive browser tests. I found myself frustrated more often than I would like. And often reaching for the "nuke from orbit" approach to fix broken system-level tooling. Surely there's a better way? Maybe stop being lazy and finally, after a decade of duct-tape fixes, learn how to correctly maintain complex dependency trees? To put it in other words: pinning down Python project dependencies is easy enough, with requirements. txt and similar files. The problem is pinning down tooling on a level above that. Executables that... --- ### Niteo COVID-19 response - Published: 2020-03-12 - Modified: 2020-03-23 - URL: https://niteo.co/blog/niteo-covid-19-response/ - Categories: PeopleOps This was supposed to be an internal memo sent to my fellow coworkers, but I decided to publish it here on our blog, to encourage other businesses to take similar actions. So here it goes. The situation with COVID-19 is deteriorating incredibly fast, on a global scale. WHO just declared it a pandemic. Additionally, there's an alarming amount of horrible cases in --- ### Astronomer, psychologist, and MIT professor went to a design conference - Published: 2020-03-06 - Modified: 2020-03-06 - URL: https://niteo.co/blog/astronomer-psychologist-and-mit-professor-went-to-a-design-conference/ - Categories: Tech The title could sound like the beginning of some joke, but the modern design field attracts more and more professionals that don’t do that much drawing but build new systems and experiences. This year FITC Amsterdam again gathered a lot of great professionals to share their most interesting projects and thoughts. Now I’d like to mention the top 3 talks that I liked. Visualizing Connections Nadieh Bremer is an astronomer that turned out to become a freelancing data visualization designer and artist. With her background in data science, it’s not an issue for her to collect 12,000 lines of data and make a beautiful and meaningful graph from it. Have you ever wondered how many constellations were there in the sky according to different cultures? Or have you wondered about “Royal constellations” i. e. connections between people in royal families? Figures in the Sky and Royal Constellations Do you know what people search in google about cats and dogs? Or where do homeless people in the US travel the most (spoiler: it’s not only LA)? Why Do Cats and Dogs ... ? and Bussed out Please your inner perfectionist with beautifully visualized data and learn something new in Nadieh’s projects. You want me to measure what? /Design Science David M. Hogue is a sociologist and physiologist working as a UX design lead at Google. His team researches through different devices to improve UX quality, cohesiveness, and consistency. I started my conference experience with a workshop by David. There we were... --- ### Keeping your head above water by managing your tasks and time - Published: 2020-02-28 - Modified: 2020-02-28 - URL: https://niteo.co/blog/keeping-your-head-above-water-by-managing-your-tasks-and-time/ - Categories: General - Tags: productivity In this blog post, I'll write a little bit about the tools and methods I used to manage the chaos that used to be my workday. In my previous job, I was managing the IT departments in four different high schools. Every day at work I would get at least 50 emails and a lot of PM's in the organizations' chat platform. In addition to this, I attended many meetings which led to even more tasks that needed my attention. For a long time after starting in that position, I had trouble keeping up with the flow of incoming emails and finding time to complete my tasks within a reasonable time. This would make me feel guilty toward the people waiting for me to finish my tasks and would increase the level of stress I was walking around with. I would always look for different note-taking and task management apps to help me stay organized, but in the end, it only led to yet another place where I had tasks needed to be done. The inspiration to change Then one day at a seminar a speaker talked about the use of Microsoft OneNote along with the GTD method to be able to stay organized. His name is Ståle Hansen and here's a link to a talk that is similar to what I heard that day. The main takeaway for me from that talk wasn't necessarily Microsoft OneNote's functionality, but the idea of using one, and only one app for all... --- ### IRL #8: Bangkok - Published: 2020-01-27 - Modified: 2020-01-27 - URL: https://niteo.co/blog/irl-8-bangkok/ - Categories: General Wohooo! It's 2020 and time for our first IRL of the year Decade. We decided on Bangkok (known as Krung Thep in Thai) as the IRL location since it has relaxed visa norms and for its undisputed reputation as a fun city. IRL location: Amazing Airbnb property just a few miles away from the city center. By late Sunday evening and after the hustle-and-bustle for the few Niteans, the entire team reached the IRL location all set for the week-long fun (oh! and work too). We started the IRL by writing down Workgroups (amusingly called WAR-groups) on our tasks board. Workgroups are usually decided a sprint or two before the event and we execute them on the IRL where we divide into groups for discussion. This time, we had around 40ish workgroups that were covered during the week. Looks like Dejan is posing for the camera After deciding with the Workgroups, Dejan and Nejc explained the State the Niteo which is a summary of how 2019 was as a year for the company, what did we achieve/lose, what went right/wrong, and so much more. This is extremely helpful to get the panoramic view of the company operations and it serves as a metric when we define our yearly goals. Fast forward two days of work, and here we are at a German Brewery, on a Wednesday evening with a sole purpose - to have fun (and get drunk too). I started counting the number of beer towers that were coming... --- ### Reading Nix expressions - Published: 2019-11-20 - Modified: 2021-01-28 - URL: https://niteo.co/blog/reading-nix-expressions/ - Categories: Tech These are my notes from the Reading Nix expressions talk in NixCon 2019. Nix package language has a similar syntax to the "JSON meets functional language concepts". E. g. you have Let-expressions which I would say is a functional concept (ref: https://en. wikipedia. org/wiki/Let_expression) - I first saw it in Elm and Haskell. An important thing to keep in mind is that Nix is a lazy language so some code might not get evaluated if it is not called. This means you can actually read the code from the "middle". For example, you can start reading this config https://github. com/jwiegley/nix-config/blob/master/default. nix in line 12 and then continue to the next one. Once you see a variable like e. g. ${version} you can "evaluate" it in your head (in this case version is defined in line 1). The point is that some variables/functions can be defined but might not get called so Nix won't evaluate them. This is completely different from how e. g. Python works. Functions Nix functions are just lambda expressions. Example: a: b: a + b Another representation is keyword arguments or a set pattern: { a, b }: a + b This one is the most popular. You can call this function with a and b attributes. If you need additional arguments you can use an ellipsis (... ): { a, b, c, ... }: a + b + c This will work on any set that contains at least the three named attributes. Ref: https://nixos. org/nix/manual/#ss-functions... --- ### NixCon 2019 - Published: 2019-11-20 - Modified: 2021-01-28 - URL: https://niteo.co/blog/nixcon-2019/ - Categories: Tech It's been a few years since I've been to a smaller conference and I made the right choice to visit NixCon 2019. It was held in a really nice coworking space called Impact Hub in Brno. There were 2 tracks and about 180 people attending. Generally speaking, smaller conferences like this one will give you more information because people are more connected with each other. For example, the second day we had one track which wasn't planned at all where people were just asking questions regarding Nix. So it was like a free consulting which is insane in terms of the value you get. Before I attended NixCon my knowledge of Nix was very limited. I spent about 5 hours reading the docs and checking out the config files. So I just had an idea of how it works and how to use it. Attending Reading Nix expressions a real game-changer for me (Youtube: link). I finally understand those nix config files. It basically covers Nix Manual but just the "important" parts. The parts you to need to know before you start playing with nix config files. I would highly recommend this talk for anyone new to Nix. The second talk How and Why it Works (Youtube: link) just builds on top of what we learned with the previous talk (Reading Nix expressions). Graham Christensen explained what Derivations are and a few other important semi-advanced concepts like filesystem isolation. I don't know how complicated derivations are for a newcomer but... --- ### Frontend week in Budapest - Published: 2019-09-30 - Modified: 2019-10-01 - URL: https://niteo.co/blog/frontend-week-in-budapest/ - Categories: Tech Last week I attended my first two frontend conferences - CSSConf & JSConf Budapest 2019. My week in Budapest started with Rust meetup. Sadly the organizers didn't expect that any foreigners will attend the meetup. Half an hour long talk wasn't enough for me to learn any Hungarian, but I still had a great time talking to everyone afterward. On Tuesday I attended the JAMstack workshop organized by SuperCharge. We worked on a simple webshop written with Gatsby. We configured deployment to Netlify, integrated Netlify admin to manage the content and implemented a few basic features to get familiar with the framework. After the workshop, I went to Reactive meetup. The most interesting talk was from Tibor Szasz about his side project - a web app where you can design and buy customized shirts using generative art. He talked about challenges on frontend and backend to get a smooth experience from designing to making an order. CSSConf Budapest 2019 Wednesday was time for CSSConf with 9 talks. I wasn't expecting much from the CSS conference and was pleasantly surprised with inspiring and technical talks. Yu Ling Cheng and France Wang presented DevUX culture that aims to improve collaboration between designers and developers in their talk Building Better Products Faster: DevUx is the new DevOps. They walked us through four levels of collaboration between designers and developers with examples of collaborations when things went wrong and suggestions to improve. Alan Stearns encouraged us to report browser bugs in his talk Getting... --- ### PyCon JP 2019 - Published: 2019-09-20 - Modified: 2019-09-20 - URL: https://niteo.co/blog/pycon-jp-2019/ - Categories: Tech - Tags: PyCon, Python I’ve been to many conferences in my life, but this was my first time attending a PyCon. To me, what separates this conference from the others I’ve been to is the sense that people are there not so much to sell their products, but are just genuinely interested to hear how other people are using Python in many different industries. I also felt that nobody judged other people based on their proficiency or experience with Python. A beginner programmer like myself was as welcome in a discussion as a more veteran programmer. People were just generally nice and including! The fact that this conference was in Japan naturally meant that most talks were in Japanese. Since my Japanese still isn't that good, it helped simplify the selection process for which talk I’d like to listen to. There were a lot of interesting talks so it was hard to decide which ones to write about, but here is a little bit about a few of them. Keynote day 1 - Why Python is eating the world By: Cory Althoff - YouTube Cory Althoff, the author of a best-selling book called The self-taught programmer, talked about why Python is as popular as it is these days. Here are a few of the reasons he pointed out: Easy to get started withGood readability, easy to write syntaxFor example, let's compare how to output a simple "Hello world" in Java and Python. Java:class HelloWorld { public static void main(String args) { System. out. println("Hello... --- ### IRL#7: Ljubljana - Published: 2019-08-01 - Modified: 2019-08-01 - URL: https://niteo.co/blog/irl7-ljubljana/ - Categories: General It's mid-year and it was time for In-Real-Life meetup in the hometown of Niteo, Ljubljana. Mid-year IRL is usually a bit more relaxed since there is no major reviewing or planning that needs to take place. Therefore we had a quick overview of the last half a year and then worked on a few important tasks in workgroups in the first two days. Wednesday came quickly and in the afternoon it was time for, now traditional, picnic and barbecue with partners, friends, and family. Thursday we took a full day off and we went to the mountains (Bohinj). It was a fun day where one group went eBiking, and the other rafting, and we finished the day with some great food. The great thing in Slovenia is that you're never more than an hour away from anything. So, Friday was a day off at the seaside where we've hired a sailboat! Luckily, after 5 hours on the sun and a ton of sunscreen, no one got burned. :) It was an amazing IRL where we've had a ton of fun. Unfortunately, a few Niteans were missing because of visa issues. Since we want to have the whole group together at least once a year, we've decided we'll be going to Bangkok in January! --- ### Elm: A frontend story that a backend dev can love - Published: 2019-07-29 - Modified: 2021-01-28 - URL: https://niteo.co/blog/elm-a-frontend-story-that-a-backend-dev-can-love/ - Categories: Tech I’ve been doing Web development for about 15 years now. The first few years were mostly tinkering with PHP and doing basic changes via the browser using Plone.   Very early into my career I co-founded Niteo. And got the first few clients. We were n00bs, so we decided to use Plone to build client websites -- it had a nice default UI for those years. I mostly worked on business logic customizations and add-ons. The UI part usually consisted of using correct classes and relying on Plone to make sure the frontend looked OK-ish. We weren’t winning any design competitions, but that was not our goal. We were going for pragmatic, usable interfaces. This mantra stayed with us for many years. We started using Twitter Bootstrap soon after it was released. We were freed from the constraints of the Plone styling, now we could build UIs that looked kinda modern! Sweet! But we still kept very close to default Bootstrap look. It was “good enough” and I really wanted to avoid writing JavaScript. I tried to learn to like JavaScript several times. But compared to Python it always seemed such a stress-inducing experience. There’s no great way to debug my scripts, let alone have a good testing story. I like to stay in my terminal where I can use the keyboard to move around, not my mouse. Clicking around in the browser to develop & debug code feels like using my left hand for writing. It's not impossible, but... --- ### PyCon Thailand 2019 - Published: 2019-06-19 - Modified: 2020-01-08 - URL: https://niteo.co/blog/pycon-thailand-2019/ - Categories: Tech Website: https://th. pycon. org/en Talks: http://yt. vu/c/UCtHekbmBXtp5AYSVARFQQiw (to be uploaded) It is the first conference I ever attended, my first foreign trip, and the first opportunity to give a talk. In short, it was an incredible and unforgettable experience for me. Positives Friendly, energetic and very helpful people. Perfect venue: easy to reach technology park with dedicated rooms for conferences and similar programs. A crowd of about 300 people. Insightful keynote talks worth taking note of. Most parts of the execution was flawless and strictly on schedule. Party and food were great. I won two gifts for answering a question in the quiz session. Being a beginner friendly event, it encouraged me to do a lightning talk and introduce one of my libraries without any preparation. View from True Digital Park - 7th floor, Bangkok, Thailand Negatives Projector display connectivity issues were there to trouble some speakers. Wi-Fi visitor credentials were not working on my laptop and the staffs were only able to temporarily fix it by using credentials that they can't share (i. e. if it disconnects, I have to ask for it again). Most of the non-keynote talks were related to Machine Learning. Most of the talks not related to Machine Learning were for beginners. One of the talks I attended was fully in Thai, we had to read the English subtitles on the slides. Weather was too humid. Talks I attended Day 1 9:05 How to meaningfully contribute to Python without being very good at programming: It... --- ### KubeCon 2019 - Published: 2019-06-12 - Modified: 2019-06-13 - URL: https://niteo.co/blog/kubecon-2019/ - Categories: Tech This was my first time at a KubeCon conference. This year it was held in Barcelona with over 7. 5k attendees! The conference was held at Gran Via which is a huge place. It consists of 8 huge halls and 3 of them were used for KubeCon. It could take you up to 15 minutes of walking from one talk to another. Personally, I don’t like conferences this big, but I went anyway because I wanted to learn more about Kubernetes. When the conference started I couldn't get to the first or even the second talk because the lecture rooms were full. This was quite a shocker because this has never happened to me before, and this isn't my first conference. The talks were a mixed bag (as always) but the main complaint from me is that the topic was too wide. It wasn't only about Kuernetes. It was basically a DevOps conference. If you are a programmer imagine that you go to a programming conference where every talk is about a different language. If you are an expert that is probably fine, maybe even interesting, but if you want to learn a specific language you won't get much out of the conference. AWS chilling terrace. The second problem, related to the size of the conference, was how many tracks there were. There were from 12 up to 22 tracks which is insane. Maybe it's just me but I don't like that many choices, so even picking talks was a... --- ### Robust REST APIs with Pyramid - Published: 2019-06-03 - Modified: 2019-06-04 - URL: https://niteo.co/blog/robust-rest-apis-with-pyramid/ - Categories: Tech - Tags: pyramid, Python It's almost a year since we started working on a new project: WooCart. Up until that point, all our projects were "backend-monoliths", i. e. the backend rendered all necessary HTML and served it to the user. Some templates had some jQuery or Vue. js sprinkled on top, but that was about as far as we were willing to go with interactive interfaces. With WooCart it was time for us to adopt the concept of the Single Page Application (SPA). I. e. have the backend only serve data, and frontend do all the rendering. We settled on React for the frontend, but that's a story for another time. This post is about the decisions for the backend. Backend stack Since we've never done SPAs before, we wanted to minimize changes to our stack on the backend, to keep things controllable. It was an obvious choice to go with Pyramid, a mature Python Web framework. Pyramid is behind the new PyPI. org, serving mind-boggling amount of traffic and if it is good for that, then it's good for us too. API specification At first, I wanted to use cornice, a REST framework for Pyramid. I've used it before and it worked fine. Cornice generates API documentation straight from your Pyramid views. Super convenient and fast to write! But then Domen convinced me to take the "API-first" approach: First, describe the API using a standard format, such as Swagger, only then write code. At first, I was fighting it, because this meant writing... --- ### The Many Faces of AI Powered Marketing - Published: 2019-05-27 - Modified: 2019-05-27 - URL: https://niteo.co/blog/the-many-faces-of-ai-powered-marketing/ - Categories: Marketing, Tech This month I went to DigiMarCon in New York. I expected it to be a much bigger conference with more people, more talks to choose from and actual workshops. It was far from that but is a good conference to attend if it’s near you. I want to share here and expand on some AI marketing examples that I took from Pam Didner, one of the speakers. Whether we like it or not, AI is the future, and we need to be prepared for it. Even better, we should take advantage of the huge opportunities that it creates all around us. Nutella 7 million jars of Nutella, each with a unique design! It sure sounds like a cool marketing stunt but how is it possible? Well, it seems you only need one algorithm. And if you check the results you see they look great, fresh and vibrant designs that are unique but at the same time keep a consistent line. There isn’t much data on how this influenced sales, but we do know it’s 7 million sold jars, not just designed. https://www. youtube. com/watch? v=sHYakhyvJps Conversica This Conversica AI assistant is mind-blowing, it handles perfectly the text interactions with your leads, from start to finish. It’s persistent, does follow up after follow up without being out of place. It never forgets about a lead and most important, at the right moment, it connects the lead with a sales representative. See some conversation examples. Drift Drift is not really AI but,... --- ### We got banned from PayPal after 12 years of business (updated) - Published: 2019-05-09 - Modified: 2019-05-17 - URL: https://niteo.co/blog/paypal-ban-after-12-years/ - Categories: General Update: PayPal restored our account, and they were as descriptive as when banning us. This was after a call and tweet confirming the "final decision". We're appreciative nonetheless. :) PayPal unban Original post continues below You'd think that being a legitimate online business, having 12 years of history with PayPal, and hundreds of thousands of dollars processed, you'd gain some credibility with them. Not so. Our company was banned with a generic "breaking terms of use" email. After calling their support twice, explaining the situation and asking for a reason, we have received nothing but "the decision is final, and we will not provide more information". Our account has not been limited or flagged once in these 12 years. We have processed hundreds of thousands of dollars in online subscriptions for our software services. The most interesting thing is that we've moved away from PayPal in the last two years and have only been receiving some minor payments and paying for a few online services. We never thought this would happen and have absolutely no clue what they're referring. We have reviewed the user agreement multiple times and there is absolutely nothing there that we've engaged in. Do not kid yourself - your business is never, never safe with PayPal. Move away or at least have a plan B in place so that you don't lose your business over their arbitrary actions. We were lucky that we have moved away from PayPal for actual business revenue, otherwise the consequences could've... --- ### Why everyone at Niteo loves checklists - Published: 2019-03-22 - Modified: 2019-03-22 - URL: https://niteo.co/blog/why-everyone-at-niteo-loves-checklists/ - Categories: Tech At Niteo we love using checklists. We think they're great because they: are easy to follow,remind you about the critical things that need doing,anyone can lead a meeting if they have a checklist. We use checklists for Sprint Planning and Sprint Retrospectives: We use checklists for User Story Expectations (aka Acceptance Criteria): We use checklists for onboarding: ... and offboarding: We also use checklists for monthly administration tasks, for quarterly administration tasks, for organizing our IRLs, one on ones, and so much more. In short: if we can make it a checklist, we will. Simplify Documentation by Using Checklists I would categorize documentation into two: static and active. The Niteo Handbook is static documentation. We use it to explain how we work from a bird's perspective. It still changes but changes are rare and usually only when there's a significant change in our processes. Our templates with checklists for User Stories, administration tasks and everything else are active documentation. They are used daily and as such change whenever we see a better way to do something. They give us the flexibility to change our workflows simply by changing our templates. When you create a template with a checklist, there is a lot less static documentation required. Instead of explaining or listing all of the required tasks in static documentation, all you need to do is create a template and adapt it whenever the need arises. A few weeks ago we decided we wanted to move a section of our alignment... --- ### Why we are backing Earnest Capital - Published: 2019-03-11 - Modified: 2019-03-29 - URL: https://niteo.co/blog/why-we-invested-in-earnest-capital/ - Categories: Tech I always had a vision for Niteo to grow into a factory of sane startups. A combination of internal spin-offs, an accelerator, and a VC fund. But with the emphasis on longevity rather than growth rate and unicorns. A little over a year ago in Lisbon, I had a very long evening conversation about the same topic with Tyler, a founder who recently sold his SaaS business, and Kevin, a CEO of a successful fund. How to do an early stage fund that is not only looking for an exit but values long-term profitably of the project? A fund that supports a good work-life balance for people in the company? A fund that does not push the founder(s) to scale for the sake of scaling, but instead to focus on profitability? Our debate ended as the wine ran out and the sun started to rise. We each went our own ways, back to our daily worklives. But then I recently noticed that Tyler is trying to make the idea real: to start a “sane” VC fund, called Earnest Capital. We exchanged a few emails and I liked the idea more and more. We soon had a call about applying WooCart, our upcoming project, to the fund. Not only because of the capital, but because of the fantastic mentors/investors Tyler managed to get on board. About an hour into the meeting I realized that instead of applying with WooCart, we should apply with Niteo. As investors. Earnest is so well aligned... --- ### Staging like it's 2019 - Published: 2019-03-05 - Modified: 2021-01-28 - URL: https://niteo.co/blog/staging-like-its-2019/ - Categories: Tech The What Here at Niteo we’ve been delivering continuously since about 2011. We started with home-grown fabric scrips that used cron to run svn update && bin/supervisorctl restart every 15 minutes. A lot has changed since then, namely, we’re now running our projects on Pyramid instead of Plone (Plone is great if your problem-space is CMS, but as a more general purpose framework, Pyramid kicks some serious ass). And we now use Heroku to host our code instead of having a manually maintained dedicated server at Hetzner. Heroku has been great to us. Especially their integration with GitHub and Travis CI is really handy if you want to do Continuous Delivery. Basically, you tell Heroku to deploy your app every time a new commit is pushed to master on GitHub, but only if all tests on Travis CI pass. This workflow allows us to do several low-friction deploys to production every day, which brings fixes and features to our customers at lightning speed. The other upside is that, from the developer’s perspective, it’s motivating to see your code being used hours instead of weeks after you finish writing it. The main pain-point, however, has been a proper staging setup. For any non-trivial change, the one reviewing a Pull Request would have to pull the code locally and run it against a local database version to see if the Pull Request is OK to merge. This becomes a mundane task quite fast. Or is an impossible one for people outside of... --- ### Design. Technology. Cool shit. - Published: 2019-03-01 - Modified: 2019-03-01 - URL: https://niteo.co/blog/design-technology-cool-shit/ - Categories: General Last week I traveled to Amsterdam to attend FITC conference 2019. I got inspired both by the city and the conference, and want to share some themes I encountered there. As a note, I’d like to mention this was the 12th year of FITC in Amsterdam, a smaller version of the original conference from Toronto, and many participants came for their 11th or even 12th time. Which was quite surprising and appeared as a good sign to me! The speakers were talking about redesigning your thinking and finding extraordinary experience in your ordinary life, how to design for your digital health and for the good of other people, how not to burn out, take your work to the new levels and keep working after the personal failures. We were reminded of a human-centered core of designer’s work, how it consists of a complex web of professional relationships and furthermore sometimes of the battles to negotiate design with your team. In his speech David Hogue (UX designer from Google), was untwisting a tendency of the teams to mess up and complicate their products. He found 12 reasons leading to complexity: Sometimes we’re designing just for ourselves instead of the users. We’re just driven by some new technology ("Woah that looks cool! Let’s add it! "). The product structure could be mapped to organization structure or technology structure, which gives the incorrect flows and irrelevant needs. There’s a consensus when the whole team says YES to everything. Don’t confuse it with being... --- ### IRL#6: Marrakesh - Published: 2019-02-06 - Modified: 2021-01-28 - URL: https://niteo.co/blog/irl6-marrakesh/ - Categories: Tech It was that time of the year again, to spend a full week of in-person time with fellow Niteans in an amazing city! This time, we chose Marrakesh, the cultural & cuisine capital of Morocco, one of my favorite travel destinations. We stayed in a private guest house in the medina, the ancient walled city-center of winding narrow streets full of merchants, repair shops, food stalls and more. As is usual, we had a few talks lined up at the beginning of the week, followed by more loosely organized workgroups later on. One of the most demanding one was coming up with a fair and inclusive Salary System. Personally, I had doubts it can even be done, but I was proven wrong. To break up days of sitting around and talking, we booked a private yoga class every day before lunch, which was absolutely critical in keeping us sane. And we took a stressful at first, but fun once we got used to it, bike tour through the medina. We finished the week off with a proper downhill tour in the Atlas mountains! Looking forward to seeing everyone in Ljubljana this July, at our summer IRL and the traditional barbecue party! --- ### Export Plone to PDFs - Published: 2019-01-19 - Modified: 2019-01-19 - URL: https://niteo.co/blog/export-plone-to-pdfs/ - Categories: Tech Since many years ago, we've had a private installation of Plone in Niteo that we call Intra. Short for “intranet”. It is meant to hold our company-wide, non-project-specific documents. I. e. financial reports, internal newsletters, various guides, and internal policies. But as of 2017, we moved most of these documents to our public Handbook, so the wider community can benefit from them and to make the decision of applying for one of our open positions a more informed one. Last week we were on our bi-annual In-Real-Life meet, where we discuss any and all aspects of our work. It turns out, everyone (including marketing! ) got so used to writing Markdown that they no longer want to use an in-browser editor. And they like the detailed history of changes that git provides. We decided to sunset our Intra. To move the remaining couple of documents to GitHub and then make searchable PDFs of entire Intra, for future reference. Wanna know how we did it? Read on! Exporting entire Plone site into a directory tree of PDFs The way to do it is to open all Plone objects with a headless Chromium browser and use the Print-to-PDF feature: Spin up a local copy of your production Plone site. Go to portal_workflows, go through all workflows and give all permissions to Anonymous Still in portal_workflows, click Update portal security for your changes to apply. This will take some time, especially on bigger sites. Start bin/instance debug and run the following: >>> for... --- ### Four meetups in three days - Published: 2018-12-11 - Modified: 2018-12-11 - URL: https://niteo.co/blog/four-meetups-in-three-days/ - Categories: Tech This past week has been quite eventful for me! On Monday, I was still in Lanzarote, enjoying the summer-like weather and beautifully glassy swell from the West. After a sunrise surf on Tuesday, we boarded the plane and headed back to Ljubljana for the real fun to start. FIRE meetup Last year I founded a small, somewhat private, community of peers in Ljubljana who are interested in FIRE. We took turns to talk about what went on in 2018 and what our plans (and potential roadblocks) are for 2019. We had people who are just starting out with their career and also some who have practically retired already, which made the talks super interesting and diverse. Big thanks to Hekovnik! HRM in the new World: Remote Work I was invited along with Miha Rekar to speak at the local HRM meetup about remote work. Miha is a developer who works remotely and I was invited as an employer who hires remotely. It was funny how much our values around work were aligned, we both said “well, what he said, I have nothing to add” quite a number of times. The main takeaway for participants was that everything builds on top of trust. You have to have complete trust in the people you work with for remote work to really show its benefits. And there are plenty! Photo by Tamara Valencic Python & Lambdas meetup I helped organize another joint meetup between the local Pythonistas and Lambdas. Domen first gave a... --- ### A month of travel - Published: 2018-11-15 - Modified: 2018-11-15 - URL: https://niteo.co/blog/a-month-of-travel/ - Categories: Tech The last couple of weeks I've had another bout of traveling to conferences. I've been lucky this time: all three events were absolutely amazing! First I went to the Google Summer of Code Mentors' Summit in California, followed by Wordcamp Bucharest and finally to Tokyo for the annual Plone Conf. GSoC Mentor's Summit GSoC is a decade old programme by Google where they sponsor hundreds of students around the World to work on Open Source software during the summer instead of waiting tables. Each student gets assigned a mentor (or more) from the organization that owns the codebase the student is working on. For many years, I've been mentoring students working on Plone; this year included. So I got to go to the Mentors' Summit! The Mentor's Summit is possibly the best conference you can go to. Imagine it: all the attendees are leaders and/or core contributors of their organizations. And there are over 200 attendees. The level of talks and discussions I had is just crazy, I really was learning a ton every day. Massive kudos to Google running the GSoC programme for 14 years already and for hosting us in Mountain View for two amazing days. PloneConf 2018 Tokyo The other contender for possibly the best conference is definitely the PloneConf. It's an annual gathering of people using and developing Plone, the enterprise Python CMS. But there's a catch: a good chunk of attendees don't actually do Plone any more, for years. Including me. But a lot of... --- ### World Usability Congress 2018 - Published: 2018-11-09 - Modified: 2018-11-09 - URL: https://niteo.co/blog/world-usability-congress-2018/ - Categories: General In the middle of October, I went to Graz to attend World Usability Congress. This conference first started 10 years ago and even though it’s not a huge one (around 450 attendees), it attracts designers, managers and product owners from all over the world. It was my first time there and I’m pleased to say that it’s organized with love, has a nice and friendly community and lets you learn not only from the speakers but through the networking with other attendees. During the two days of this conference, there were almost 40 talks in 5 streams. It was quite of a challenge to choose and visit all the interesting talks, so here I’d like to leave my highlights on the ones that I really liked. Change is constant: How to scale the impact of design (Kevin Lee, Visa) Show first, tell later. Prototyping wherever possible. Don’t waste too much time before showing your idea to the colleagues or the world. The tools are means, not ends. Remember, that any tool is made not for the sake of the tool, but to resolve an issue. Do partnerships. It’s difficult to do everything alone. If a greater success tempts you, it might come out of a collaboration with a bigger company. Example: Visa + Apple Pay. Invest in creating a Design System. What will it give you? Interaction and unifying the network as a part of the global community, creating greater value for the partnerships, better experience through the lens of... --- ### The Niteo Handbook update - less bloat, more information - Published: 2018-09-24 - Modified: 2018-09-24 - URL: https://niteo.co/blog/the-niteo-handbook-update-less-bloat-more-information/ - Categories: General Documentation naturally grows with the company. But if you’re not careful it can quickly become bloated and unnecessary detailed. This happened to us this year. We’ve noticed that a large part of The Niteo Handbook was too complicated, too detailed and the writing style too strict. It was time to refresh it. We’ve removed a lot of unnecessary docs, especially a lot of detailed installation guides. We’ve moved a lot of documentation into short lines on our checklists. If there is an action to be done as part of a process, it should be in that process’ checklist, not explained in detail in the docs. We now link to the issue with a checklist and the assigned Nitean follows it. There’s a great book about the importance of checklists that I recommend reading, the Checklist Manifesto. Besides that, we've moved everything about the company history and other information onto our website. Before it was split but now it's just linked from the Handbook. I think there is a good quote that represents the “less is more” philosophy: Perfection is achieved not when there is nothing more to add, but when there is nothing left to take away. I think this is especially important for documentation. When you remove everything but the most essential documentation, then you have documentation that serves its purpose. In our case, we can safely assume that you’re comfortable around technology and don’t need detailed instructions on how to sign up for services, install software or learn... --- ### IRL#5: Ljubljana - Published: 2018-08-06 - Modified: 2018-08-06 - URL: https://niteo.co/blog/irl5-ljubljana/ - Categories: General Summer is a great time to be in central Europe because of long days and good weather (when it's not scorching hot). It is one of the reasons why we hold our mid-year IRL in Ljubljana, the other being that it is close to many Niteans which makes it easier and less expensive to organize. We've had a big tornado of changes happening just before the IRL#5 and the main focus was on implementing these changes and setting the stage for the next six months. The goal: launching WooCart by the end of the quarter and spinning off EBN with its own team. With our prelaunch advertising and competition research, we've seen that hosted WooCommerce, or WooCommerce as a Service, is a natural progression for the platform and it's only a matter of time before someone else launches it. We've had experience with launching late in the past and we knew this time we need to be in the front. In between work, there was also time for a shooting session, some great local food, friends and family picnic, and a late night out. Looking forward to the IRL#6 in January! --- ### GopherConUK - Published: 2018-08-05 - Modified: 2018-08-05 - URL: https://niteo.co/blog/gopherconuk/ - Categories: Tech While part of the dev team was still on EuroPython, Janez and I were packing to go to this year's Go conference in London. This was a first Go conference for me, so naturally, I enjoyed it a lot. The vibe was similar to those old Plone/Python conferences back around 2010. Lots of very smart people, everyone super friendly, great talks. And small size, only a couple hundred participants. I much prefer when conferences are small, makes them feel more ... intimate? One actually has a chance to chat with the majority of the fellow participants, which is not something even remotely possible on a conference the size of EuroPython. In any case, I learned *a ton*. The day before the conference we attended a Kubernetes training, which was super helpful in answering a few corner cases we bumped into while working on WooCart's deployment story. Of the talks, the following two were the most memorable: From monolith to serverless, by Michael Hausenblas, a showcase of developing & deploying an app in a monolith approach, in a containerization approach, and in a serverless approach. With working examples! GraphQL, by Christopher Biscardi who gave a really nice intro to GraphQL and explained its use cases. Also, I got confirmation that schema-first approach to writing APIs is better compared to generating the schema from code. Black Box Monitoring in Go, by Grant Griffiths who talked about yes and nos about monitoring, how to write probes and infrastructure to support monitoring. Finally, we... --- ### PyConWeb 2018 - Published: 2018-08-05 - Modified: 2018-08-05 - URL: https://niteo.co/blog/pyconweb-2018/ - Categories: Tech - Tags: Python PyConWeb is an international Python Web conference held in Munich. Its main purpose is to talk about Web tools and techniques to make the Web even more awesome. Attending this conference really feels different from the other non-German conferences. The conference is organised and prepared with German precision. Everything was taken care of and the only thing you need to think about is to learn as much as you can and have a good time. And that we did ... The keynote was held by Nicola Iarocci. He talked about his journey in the open source community. I have yet to hear such an inspiring talk regarding open source. He used to be an introvert and he couldn't speak in public but after his first Python conference (where he also gave his first talk) his world changed. He highlighted the benefits of open source and encouraged listeners to work more with open source. Next talk I want to mention was by Doug Sillars. He talked about compressing and resizing images on the Web ("Stop Stalling! Delivering Fast Video without the Buffering"). This is what I like so much about these conferences. I must admit I didn't expect much from this talk because the topic didn't seem too difficult to me. Boy, was I wrong. Let's say we have a single site that contains a single image. For every client, we should check what is the size of the screen and also on what connection they are on and then we... --- ### How to get to the job interview at Niteo as a developer - Published: 2018-07-06 - Modified: 2018-07-03 - URL: https://niteo.co/blog/how-to-get-to-the-job-interview-at-niteo-as-a-developer/ - Categories: PeopleOps In June we've opened up three job positions and received A TON of applications. Python job posting alone received more than 70 applicants in a matter of days. To simplify our selection process there are two sets of written questions for filtering before the interview. For future developers applying for a job (hopefully many of them will read this post), here are a few things that will put you in the top few percent of the candidates and a good chance at an interview. You accurately answer the questions When we ask "what are your preferred working hours in UTC time", we like to read something in the lines of "between 11AM to 8PM UTC". Answers like "I'm adaptable", "I'm in EST timezone", or "I can start at 5AM" don't help us since they're not specific enough for us to plan where we'd put you in the work process. Avoid writing "refer to my cover letter/CV for the answer" because that means we need to scroll through the job application, PDFs, and CV, to find that one sentence that answers the question. You have open source contributions We give back to the Open Source community and we give priority to those who do the same. It's also easy for our development team to review your code. Excellent written English We are a remote team. The large majority of communication happens in written English. If you take time to write proper sentences with periods and commas and run a basic grammar... --- ### My Experience at iCEE.fest 2018 - Published: 2018-06-28 - Modified: 2018-06-28 - URL: https://niteo.co/blog/my-experience-at-icee-fest-2018/ - Categories: Marketing Two weeks ago I was at the iCEE. fest conference. I decided to go because it takes place in Bucharest where I'm based. Then the event mostly focuses on marketing and advertising although it's promoted as a general tech conference. That's perfect in my case, plus I know the owner and his great results over the years. This is by far one of the biggest conferences in the CEE region, we are talking about 7 stages that have different speakers at the same time, and around 4000 attendees. In the halls you can interact with the latest technologies, outside there is a venue for networking and relaxing, and at the end of each day, there is a standup comedy show and afterward a party with live artists. All these things are great but at the same time can be pretty exhausting, lots of choices, the schedule doesn't always stay on track on all the stages (many factors can disturb the agreed flow). By leaving a good speaker to see a better speaker you can eventually find out that they almost finished the talk, plus when you come back to the previous speaker there's no free chair. You start each day at 9 AM and finish at 10 PM, not to mention the traffic in Bucharest that, depending on where you stay, can add up to 2 hours in the morning and another 2 in the evening, or even more. That's why having Jeff Leach as a host is a smart... --- ### Niteo is hiring! - Published: 2018-06-15 - Modified: 2018-06-15 - URL: https://niteo.co/blog/niteo-is-hiring/ - Categories: PeopleOps Currently, Niteo has three open positions: An enthusiastic Python developer, WordPress & WooCommerce Developer, DevOps with a love for Python and Go. We are looking for help on our current flagship project, Easy Blog Networks, and our new project WooCart. We look forward to your application! --- ### LTV Conf, May 2018, London - Published: 2018-05-16 - Modified: 2018-05-17 - URL: https://niteo.co/blog/ltv-conf-may-2018-london/ - Categories: Marketing I love going to conferences in London because it is one of the rare cities I have a direct connection to. We were invited to this one and being a small SaaS conference with great speakers lined up it was a no-brainer. I only wrote notes for the two talks that impact our business the most, no offense to other speakers. :) Day 1 I really looked forward to the first talk of the conference. It was by Patrick Campbell from Price Intelligently and Profit Well who had a great booth presentation on SaaStock last year. And he did not disappoint with this one either. Here are my notes from the talk: There is massive competition in the SaaS market. CAC is increasing. The relative value of features is decreasing. NPS is down overall. In short - there is massive competition with tools that do more and more but customers are less happy with every year. Monetization and retention optimization are now more effective than acquisition optimization. Based on their research, European software is underpriced. We could be charging way more than we are. Product development should be more methodical ("you are building trash features"). Do more customer research conversations and experiments. If you're sending out non-compensated surveys, they should be shorter than 60 seconds. Rank features for each persona. Day 2 The first talk on the next day was also great. Brennan Dunn from RightMessage talked about website personalization. The idea was not new, I first encountered it in... --- ### Resuming uploads to Amazon S3 - Published: 2018-02-24 - Modified: 2018-03-27 - URL: https://niteo.co/blog/resuming-uploads-to-amazon-s3/ - Categories: Tech I am escaping continental winter at the moment which means my internet connection is not perfect. I was uploading a 1GB file to Amazon S3 via the console. aws. amazon. com and the upload failed at 93%. Just my luck! I didn’t want this to happen again. So I tried using Cyberduck to upload and intentionally turned off WiFi after a few seconds to see if I can resume the upload. Nope. Does not work. OK, what about the official AWS command-line tool? Also nope. Oh, come on! Finally, I found this StackOverflow entry. Apparently `s3cmd` does support resuming uploads. Let’s give it a try: ~$ s3cmd put --multipart-chunk-size-mb=5 IRL_talk_recording. mp4 s3://videos. niteo. co/IRL4/ upload: 'IRL_talk_recording. mp4' -> 's3://videos. niteo. co/IRL4/IRL_talk_recording. mp4' 5242880 of 5242880 100% in 45s 111. 64 kB/s done upload: 'IRL_talk_recording. mp4' -> 's3://videos. niteo. co/IRL4/IRL_talk_recording. mp4' 5242880 of 5242880 100% in 37s 136. 04 kB/s done upload: 'IRL_talk_recording. mp4' -> 's3://videos. niteo. co/IRL4/IRL_talk_recording. mp4' 5242880 of 5242880 100% in 25s 204. 51 kB/s done upload: 'IRL_talk_recording. mp4' -> 's3://videos. niteo. co/IRL4/IRL_talk_recording. mp4' 524288 of 5242880 10% in 3s 155. 49 kB/s^CERROR: Upload of 'IRL_talk_recording. mp4' part 4 failed. Use bin/s3cmd abortmp s3://videos. niteo. co/IRL4/IRL_talk_recording. mp4 zOidfC... 5RHKek_DS to abort the upload, or bin/s3cmd --upload-id zOidfC... 5RHKek_DS put ... to continue the upload. See ya! ~$ s3cmd --upload-id zOidfC... 5RHKek_DS put --multipart-chunk-size-mb=5 IRL_talk_recording. mp4 s3://videos. niteo. co/multi/ WARNING: MultiPart: size and md5sum match for s3://videos. niteo. co/IRL4/IRL_talk_recording. mp4 part 1, skipping. WARNING: MultiPart: size and md5sum match... --- ### IRL#4: Istanbul - Published: 2018-02-16 - Modified: 2018-08-06 - URL: https://niteo.co/blog/irl4-istanbul/ - Categories: Tech Last month we again held our biannual in-person gathering of all Niteans, the IRL. As is customary, we meet somewhere warm for the winter edition of the event. This year we chose Istanbul, Turkey. A stunning city with millennia of heritage. We’ve gotten good at running IRLs so this one was by far the most productive. We’ve done several improvements to our policy and process (published in our Handbook), set good goals for the year and planned out the coming months. We had technical discussions, we had marketing brainstorms. We had coding sessions in the sun, we listened to lightning talks while sipping Mango Rum (thanks, Marbe! ) and we took turns trying to beat Dejan at “foosball”. With a ton of fantastic food in between. One of the outcomes I personally am most proud of is that we are charging ahead with our purpose, to help improve lives, using information and software as the main driving force. We are doing so by moving into a more mainstream market with our upcoming project so that we will be able to help "regular Johns and Janes" and not just hard-core internet marketers. There's more: in the past, we have donated to great organizations such as LibreOffice, Wikipedia and Let’s Encrypt. Now, we’ve set it as a company goal for this year to make our impact on such causes an order of magnitude greater. In order to do that, we are 10X-ing our donations in 2018! Since Niteo has grown a lot... --- ### AWS EC2 gotchas - Published: 2018-02-14 - Modified: 2018-03-27 - URL: https://niteo.co/blog/aws-ec2-gotchas/ - Categories: Tech Lately, AWS has been giving us a lot of headaches on the Easy Blog Networks project. It turns out only because resources (we pay per how many things we can do per second) are fiercely measured on AWS, but the underlying problems are happening on all EBN providers. So when we go over operations per second limit which is 100, the EC2 hypervisor will limit entire server by lowering CPU resources. We see that as CPU steal. Now in order to figure out what exactly is using more than 100 operations per second, I installed netdata on a few servers. Which gave me the following picture: In above picture we can see enormous spike in CPU usage by group of apache2 servers. We had ~1. 8k I/O operations(read,open,mmap syscalls), the limit is 100. And we still had a lot of credits to spare. But AWS has this thing called burstable limit: you can have 100OP per second but you can also spike over that limit (3000 in our case). The burst is limited to 5-seconds moving average window if instance does not lower usage in that timespan, entire instance is punished by taking away CPU resources. One can disable this behavior on all x2 instances (Enable T2 unlimited), but this will incur additional costs, if you have constant usage above limits and not just spikes. Now what that means is that some scripts are doing more things than anything else (backups don't even come close to this). Tracking it down... --- ### Recording Talks - Published: 2018-02-12 - Modified: 2018-03-27 - URL: https://niteo.co/blog/recording-talks/ - Categories: Tech - Tags: Talks Last year on IRL#2, our biannual in-person get-together, we decided to start recording talks, so that those that could not attend in person would be able to watch them at some later point in time. Turns out, there is another great use case for these recordings: onboarding. Whenever a new person joins our team, these talks help to get them up to speed. The recordings have been a huge success and we’ve started doing them regularly when we give a talk, at local meetups, at conferences without dedicated video teams, etc. Our setup is opinionated based on what we need and what devices we already have. It tries to be as simple & portable as possible while keeping good audio quality: An iPhone for video: video is not very important when recording talks and iPhone’s camera is good enough. A fantastic external shotgun microphone for audio: we often have more than one speaker (at once or alternating), we have questions from the audience, we have remote attendees pitching in, etc. We wanted our setup to be invisible, without attaching microphones to speakers’ shirts, without passing microphones around for questions and without complicated channels mixing in post-production. It turns out, the Rode VideoMic Pro “shutgun” microphone does the job perfectly. We set it up 7 to 10 meters from the speaker, among the audience, pointed at the speaker. Since the microphone is directional, it picks up the speaker’s voice very well while also allowing the comments from the audience to get... --- ### Nitean Recognition - Published: 2018-02-01 - Modified: 2021-01-28 - URL: https://niteo.co/blog/nitean-recognition/ - Categories: PeopleOps "Bang a gong, get it on. " While the lyric is pulled from a modestly talented rocker in the 70s, it does hit a key entrepreneurial principle. Some companies and businesses ring a bell when something good happens or an achievement reached. At Niteo, we give kudos and +1s. The wall of happy Laszlo Bock, head of Google’s People Operations, has a Wall of Happy outside his office where kudos are printed and put on a physical wall. We took the idea and the bell tolling, and spin them into something that would work for our case. Instead of a bell, we have a Wall of Happy where celebrations and peer recognition are documented. And since we're a remote-first team, the wall-of-happy is a Slack channel. The modality used to implement the Nitean recognition was based on the fact that Slack is our main and effective communication tool. See our Handbook policy on this. For what the bell tolls The Nitean recognition aspires to keep the team motivated by creating a work culture where the simplest achievement is celebrated. Moreover, it also promotes higher peer engagement and better work communication. Both of which are key activities that underpin all aspects of business and life in one-way or another. Whether it's closing a sale, removing a blocker or helping out a fellow Nitean, the bell tolls. There is no discrimination between achievements. From a modest to a momentous victory, the team recognizes and heralds it. Creating a positive workplace culture Having... --- ### Conference hiatus is over - Published: 2017-12-29 - Modified: 2018-03-27 - URL: https://niteo.co/blog/conference-hiatus-is-over/ - Categories: General - Tags: Plone Back in the day when Niteo was still a consulting company I had to do a lot of traveling to find and do work. And to attend conferences. I loved to go to conferences. But being away so much, in boring hotel rooms and eating out every day took a toll on my (mental) health so I decided I needed a break. The hiatus is now over! I’ve been to three conferences this autumn and I gladly found out they are as enjoyable as I remember them. I’ve been to Open Data Science Conference in London, the annual Plone Conference in Barcelona and finally MicroConf EU in Lisbon. They are vastly different conferences: ODSC is huge and very corporate and academical, MicroConf is tiny, lifestyle-oriented and friendly. And then there is PloneConf: consistently the best fun you can have at a conference. :) Here are a few random thoughts: The data science community is very much where the Python community was a decade ago in terms of Open Sourcing their work. The questions “But how do you make money? ” and “How did you convince your boss? ” came up a lot during the conference. Maybe I need to do a talk to address these next year. We’ve been open sourcing our code for a decade now and recently also published our internal policies and work processes for others to learn from. Conferences absolutely *suck* if you don’t do a talk. As soon as you are a speaker, at least... --- ### SaaStock, September 2017, Dublin - Published: 2017-10-18 - Modified: 2018-03-27 - URL: https://niteo.co/blog/saastock-september-2017-dublin/ - Categories: Marketing This was one of my first conferences outside the Internet Marketing industry and I mostly went to it to expand my horizons and see what successful SaaS companies are doing. Coming from a bootstrapped and ROI-focused background, what struck me as strange was the definition of success (or at least a path to success) for these SaaS companies. A lot of the speakers came from companies that made $10M+ ARR which sounds quite impressive, however, soon after you learn how many employees they have and, for me one of the most important metrics, how much revenue per employee they make. My friends and I calculated the numbers for a few of the more advertised companies and they shocked us. One company, and mind you these are companies based and operated in the west, not outsourcing 90% of their business to low-cost countries, had a total of 50,000 EUR revenue per employee. That number is closer to old labor-intensive industries and not what you'd expect from a SaaS company. There is absolutely no chance they can make any serious profit on those numbers. The only explanation for that is that since these companies are also mostly VC-backed, the whole philosophy is "go big or go home". Investing literally everything into people to grow the business as much as possible, as fast as possible. Very far from where I come from where one of the metrics we follow is revenue per employee (keep it above 100k/year) and even actual profit at the... --- ### Upgrading our Intranet to Plone 5 - Published: 2017-03-16 - Modified: 2017-03-16 - URL: https://niteo.co/blog/upgrading-our-intranet-to-plone-5/ - Categories: Tech While we haven’t done any Plone consulting (well, *any* consulting to be exact) in over 3 years, we still use Plone internally, every single day. It was about time our Intranet got some love, so I put on my disco pants, poured some of Belgium’s finest and got to work. Our installation was an old Plone 4. 1 one. It was about 3 years since we last touched it (apart from applying security hotfixes, obviously). The first task was to clean up and update our buildout environment. Mostly throwing things away. I like my Plone vanilla flavored. What followed was making sure our tests still pass and enabling Travis CI for the project. Then came the upgrade to a new major version of Plone. The Plone 5. And let me tell you how the upgrade went: Bump version to 5. 0. 6, make sure buildout uses version pins that come with Plone 5. 0. 6. Run buildout & restart server. Click a big honking “Upgrade” button. Crack open another beer. I mean seriously, people! Why can’t all software have such smooth upgrade paths! ? Plonistas, you have my utmost respect. Back in the Plone 4. 1 days we still had Archetypes, an ancient framework for defining types of content, but Plone 5 is all about Dexterity, so I migrated that too. With a click of a button. Zero hassle once again. What followed was some throwing content around, updating workflows and permissions to match our company structure and that was... --- ### Thailand was a blast! - Published: 2017-01-28 - Modified: 2018-02-14 - URL: https://niteo.co/blog/thailand-was-a-blast/ - Categories: General It’s January — time for the “IRL”, our biannual in-person get-together. Summer IRLs happen in (around) Slovenia since that means short travel for the majority of the team plus it’s hard to find a more beautiful place in those early summer months. That said, come winter, Europe gets, well, uncomfortably cold. And most of us want to escape somewhere warm. This year we’ve chosen Thailand! Why Thailand? Good climate (read: flip-flops) in January and it’s about half-way between Europe and the Philippines making travel times relatively equal for everyone. After the initial clusterf*ck of almost getting scammed into booking a non-existing venue, we got lucky in the end and got an absolutely perfect place for our event: two houses with rooms, with a covered patio in between and a pool. The covered patio meant we could be outside for the majority of our sessions. And the 15 minute breaks in-between meant we got to use the pool a lot. To top it off, billiards in the evenings! We are a remote company and IRLs such as this one give us an opportunity to finally meet some of our coworkers in person. Due to EU visa requirements some of us finally, after years of working together, got to meet the people behind the Slack handles in real life. It’s so good to paint a face over all those interactions we had. The week ended in a flash, we came up with great ideas for the future and set ambitious goals for... --- ### How we work in NiteoWeb - Published: 2016-12-30 - Modified: 2017-07-25 - URL: https://niteo.co/blog/how-we-work-in-niteoweb/ - Categories: General Update: see the latest version of this document on our Handbook. NiteoWeb is a distributed team of Web experts spread around the World. While we do rent office space in Ljubljana, Slovenia, most of us work remotely. Here's a quick overview of how we go by our days. Communication Instant messaging is done through Slack on different channels (operations, support, development etc. ). We have daily standups at 9AM UTC on Google Hangouts when everyone has a minute or two to say what they're working on and if they need any help. Once a week, Dejan has "catch ups" (better known as 1-on-1) with everyone on the team to keep himself in the loop. About once or twice a year we fly the whole team somewhere nice and we'll have an "IRL" (in-real-life) meetup. Here we discuss company status, projects and the future in a group setting. Then there are ad-hoc in-person meetups that happen about once or twice a month, as needed. Some of us might get together to watch a talk at a local conference or we go to lunch together to discuss project work. Project and Company Management Project and task management is currently done with either Plan. io (being slowly discontinued) or GitHub. Support handles tickets through GrooveHQ. We also have an internal document system (intranet) we call "intra", running on Plone, where all our company processes and documents are stored. We track cash flow with Xero. Finance reports are published to intranet on a monthly... --- ### Strings in Python 2 and Python 3 - Published: 2016-12-14 - Modified: 2016-12-14 - URL: https://niteo.co/blog/strings-in-python-2-and-python-3/ - Categories: Tech - Tags: Python, Python3 The goal of this post is to show you how to properly use encode and decode in python 2 and in python 3. This post will be based on small examples that will (hopefully) make you better understand how strings work in python 2 and python 3. A bit of background on unicode and UTF-8: Unicode has a different way of thinking about characters. In Unicode, the letter ``A`` is a platonic ideal. It’s just floating in "heaven". Every platonic letter in every alphabet is assigned a magic number by the Unicode consortium which is written like this: U+0639 (in python ``\u0639``). UTF-8 is a system of storing your string of unicode code points (those magic ``U+number``) in memory using 8 bit bytes. One of the common questions for python 3 is when to use bytestring and when to use strings as an object? When you are manipulating string (e. g. ``reversed(my_string)``) you always use string object and newer bytestring. Why? Here is an example: my_string = "I owe you £100" my_bytestring = my_string. encode >>> print(''. join) 001£ uoy ewo I >>> print(''. join) 001£Â uoy ewo I The first print is what we expect but the second is not. And why is that? Well the ``reversed`` function iterates over a sequence which in second case is bytestring which is b'I owe you \xc2\xa3100'. We can also verify this by checking the length of ``my_bytestring`` and ``my_string``: >>> print(len(my_string)) 14 >>> print(len(my_bytestring)) 15 If I always just add ``.... --- ### IRLs - Published: 2016-11-26 - Modified: 2017-03-15 - URL: https://niteo.co/blog/irls/ - Categories: General NiteoWeb is a remote-first team. While we do have a physical office in Ljubljana, few people go there regularly. Most of us prefer to work from home, from coffee shops or from the beach. Wherever and whenever we feel we are the most productive. While remote work certainly has its benefits, it does indeed have its challenges. Building rapport with coworkers is harder over digital channels than it is in person. While we do have a daily stand-up meeting on Google Hangouts where we all gather around a digital campfire for a few minutes every morning, it isn't enough. About once a month those of us living in Slovenia try to get together for lunch, a picnic or a local tech meetup. These in-person gatherings are fantastic, but they are geographically limited. It does not make sense for people outside of Slovenia to travel for hours just to attend a lunch. So we started doing semiannual gatherings where the entire team converges on a single physical location to talk, socialize and rant. We call these gatherings IRLs ("In Real Life"). In the summer we do it in Slovenia (or close by) and during the winter we do it in some warm place around the world. This summer we booked an AirBNB villa in Vodnjan, just across the border with Croatia. What a fantastic place we got! The summer IRL was two days filled to the brink with insightful talks from the team, mindblowing idea pitches and great discussion about anything... --- ### Lessons Learned from PyMunich 2016 - Published: 2016-11-14 - Modified: 2016-11-14 - URL: https://niteo.co/blog/pymunich-2016/ - Categories: Tech - Tags: PyMunich, Python At the end of October there was a Python conference in Munich (PyMunich). For a regional conference it was quite big in my opinion. There were 3 tracks and more then 40 speakers. As always I won't cover all the talks just the ones that I found the most interesting and educational. After all this is the biggest reason why I go to these conferences. The first talk I attended was by Dmitry Trofimov. He talked about profiling ("Profiling the unprofilable"). There are 2 approaches you can profile your code and it is important to know them both so you know which one to choose. The first one is statistical or sampler profiling (e. g. vmprof) and the second one is deterministic profiling (e. g. cprofile). For more details about the differences I strongly suggest to do some research on your own. When you need to optimize your code you should be aware of the optimization levels. Often developers want to be smart and they go straight into optimizing their algorithms. But this doesn't have the biggest impact. The biggest impact on the performance has the design (architecture). So this should be your biggest focus. After that you can start looking at algorithms and data structures and at the end line profiling. See "Effective Python" section in lessons learned from europython 2016 blog post for more details on this. You can also use Cython for even better optimization (i. e. when you would need to write C code) but in... --- ### A dev’s MacBook from scratch - Published: 2016-10-06 - Modified: 2016-10-06 - URL: https://niteo.co/blog/a-devs-macbook-from-scratch/ - Categories: Tech - Tags: productivity, Python, Raspberry PI I’ve been a long time Apple user. I hate a lot about the company’s policy and how they treat their power users, but I love the tight integration between their software and hardware. Another thing to love is their migration tools. You buy new hardware, you click Restore from backup and you are done. Safari even opens up the tabs you had open on the old device. However recently, I’ve splurged on a new MacBook 12” and decided to set it up from scratch. For the fun of it. Here are some notes of how I’ve set it up for myself, for future reference and if someone is in a similar position. Tips: Don’t sign into iCloud during installation as that starts syncing everything to iCloud and you might not want that. I moved over some files manually from a Time Machine external disk and they got "locked" i. e. I had to enter the admin password for any change to them. This is how I "unlocked" them: xattr -c -r FOLDER_WITH_LOCKED_ITEMS/ && chmod -RN FOLDER_WITH_LOCKED_ITEMS/ System configuration: First off, update to the latest version of OS X, since every major update overwrites some system configuration and you don't want to duplicate your work. Turn on auto updates. Doh. Go through all System preferences panes and see what works for you. Take your time to see what's there, it pays off. I disabled Location services, because I use VPNs a lot and then Location Services get totally confused. Enable sending/receiving... --- ### Writing The Docs - Prague 2016 - Published: 2016-09-29 - Modified: 2016-09-29 - URL: https://niteo.co/blog/writing-the-docs-prague-2016/ - Categories: Tech On September 19th and 20th Write the Docs Meeting took place in Prague. This year I had the pleasure to attend. More than 250 people came which is about 40% more compared to last year. On my surprise the majority of the people were actual tech writers or 'documentarians' as they called themselves (well there were several talks were they pointed out that they actually don't have a good, recognisable name). All of the speakers were tech writers so there wasn't much correlation with the actual coding or development from the software point of view. Nonetheless there were quite a few tips that I have picked up. One of the first talks that I found interesting was about writing as a non-native speaker (by Szabó István Zoltán aka Steve). Although his main focus was on language differences and how they affect non-native speaker when he needs to write something (e. g. documentation) he also gave a few tips on how to write in generally. He said you should "Write drunk; edit sober" which I think is a very interesting idea (unfortunately I'm not drunk while writing this). The more technical suggestions were: First do the writing part and then the editing part. In the writing part you should: Create the structure, estimate the word number focus on the flow, don't mind the grammar. And in the editing part you should: Self-edit, grammar checkers, read out loud, send to the editor. He also suggested in order to improve your language skills... --- ### WP Meetups - Published: 2016-09-11 - Modified: 2016-09-11 - URL: https://niteo.co/blog/wp-meetups/ - Categories: General, Tech - Tags: Wordpress A few months back I noticed we actually have regular WordPress Meetups in Ljubljana, our base town. We attended one in April, where David talked about theming and Emanuel about bringing Wordpress into the Public Sector. On the second one, in June, we were active participants: Janez and myself delivered a talk titled Lessons learned running 25k WordPress blogs describing how we scaled Easy Blog Networks to 25k blogs running on several hundred servers. Both events also had a Lightning Talks section, which is what I normally enjoy the most. So many great ideas packed into such a short timeframe. Looking forward to the next meetup that should happen sometime in Autumn! --- ### Lessons learned from EuroPython 2016 - Published: 2016-07-27 - Modified: 2016-09-11 - URL: https://niteo.co/blog/lessons-learned-from-europython-2016/ - Categories: Tech - Tags: Parrallel Computing, Performance, Python This was my first EuroPython conference and I had high expectations because I heard a lot of good things about it. I must say that overall it didn’t let me down. I learned several new things and met a lot of new people. So lets dive straight into the most important lessons. On Tuesday I attended “Effective Python for High-Performance Parallel Computing” training session by Michael McKerns. This was by far my favorite training session and I have learned a lot from it. Before Michael started with code examples and code analysis he emphasized two things: Do not assume what you hear/read/think. Time it and measure it. Stupid code is fast! Intelligent code is slow! At this point I knew that the session is going to be amazing. He gave us a github link (https://github. com/mmckerns/tuthpc) where all examples with profiler results were located. He stressed out that we shouldn’t believe him and that we should test them ourselves (lesson #1). I strongly suggest to clone his github repo (https://github. com/mmckerns/tuthpc) and test those examples yourself. Here are my quick notes (TL; DR): always compile regular expressions use local variables (true = True, local = GLOBAL) if you know how many elements it will be in your list, create it with None elements and then fill it (L = * N) when inserting item on 0 index in a list use append then reverse (O(n) vs O(1)) use built-in functions, use built-in functions, use built-in functions! ! ! (they are... --- ### Y U NO USE CLIPBOARD MANAGER??!??!11?!oneone - Published: 2016-06-22 - Modified: 2016-06-22 - URL: https://niteo.co/blog/y-u-no-use-clipboard-manager11oneone/ - Categories: General - Tags: productivity Every time when I am in a pair-programming session and the other person does not use a clipboard manager I am taken aback at how such a thing is even possible. To me, a clipboard manager is such an essential piece of toolkit that I forget it’s there. What is a clipboard manager? In its simplest form it’s a history of the things you copied. For example, you select text “Foo”, press Ctrl+C (Cmd+C on a Mac), then repeat the same on text “Bar”. The clipboard manager will keep both “Foo” and “Bar” values handy for use when needed. My entire clipboard history, searchable, just one keypress away. Priceless. Simple as that. And so, so effective! Every time you need to copy many things from one window to another, select and copy them one by one, go to the other window, paste them one by one. You save a ton of window switching and clicking around! Good clipboard managers support searching through the history of things you copied and they are smart about the type of content you copied, such as plain text, URLs, images, etc. There are many more reasons why using a clipboard manager makes your day easier. Personally, I use the clipboard manager that comes with Alfred, the OS X productivity app. But there are literally hundreds of clipboard managers out there, for all major OSes and most of them do their job just fine. Choosing one is mostly about personal preference on keyboard for keyboard shortcuts... --- ### New NiteoWeb.com website! - Published: 2015-10-13 - Modified: 2015-10-13 - URL: https://niteo.co/blog/new-niteoweb-com-website/ - Categories: General Well, we haven't worked in the consulting business for almost two years now, so it was about time we changed the website. Old Website New Website We now build cool stuff for the web. :) --- ### Dear Plone, welcome to year 2014 - Published: 2014-07-30 - Modified: 2015-10-13 - URL: https://niteo.co/blog/dear-plone-welcome-to-year-2014/ - Categories: Tech - Tags: Plone TL;DR: Production-level Plone on free-tier Heroku: https://github. com/niteoweb/heroku-buildpack-plone First, a bit of history: it was year 2006 and I was realizing that I was not made to be an academic. I made my first strides into entrepreneurship and being in IT, the first logical step was to create a few websites and try to get paid for my work. I did have some programming experience but haven't done any web development yet. I heard PHP was not the ideal solution so I started looking elsewhere. In my student association I heard about this Plone thingy and gave it a go: I purchased a 20€ per month shared Plone hosting account at Nidelven IT and started hacking. It was the Plone 2. x era and boy was I productive! I threw in content, installed a ready-made theme and did some TTW tweaks. Done! First customer happy! Rinse & repeat, upgrade to a beefier server, rinse & repeat. NiteoWeb Ltd. was born. Fast forward to a couple of months ago: we used GeckoBoard to drive a wall-mounted dashboard display. GeckoBoard works fine, but they want almost $60 per month if you want to drive more than one display. Sounds quite expensive for a bit of HTML and JavaScript, doesn't it? So I looked around for alternatives and one of them was the Dashing dashboard from Spotify. I was reluctant to even give it a try as it was a self-hosted Ruby app. And I didn't know *any* Ruby. But there, in their... --- ### NiteoWeb attended a Pyramid sprint in Halle, Germany - Published: 2013-08-21 - Modified: 2015-10-13 - URL: https://niteo.co/blog/niteoweb-attended-a-pyramid-sprint-in-halle-germany/ - Categories: Tech - Tags: Plone, Sprint Gocept, a company based in Halle (Saale), Germany, organized a Pyramid sprint, which lasted from 15th to 17th August 2013. The sprint took place at their headquarters which, by the way, has a lovely garden perfectly suited for relaxation, eating, drinking and development (not necessarily in that order! ). A bunch of NiteoWeb former and present employees took part, too. Despite the fact that Halle is about 10 hours away from Ljubljana if you go by car (quite a long ride indeed! ), but it was well worth coming there. Gocept did an excellent job of feeding and entertaining all the sprint participiants and it was a great pleasure to meet Chris McDonough, author of the Pyramid web framework, in person. An interesting and amusing dude I must say. Happy sprint participants were quite productive and a whole bunch of bug fixes and enhancements have been made - see the wrap up for more details. The only real downside was that the sprint ended so early, three days really passed in the blink of an eye. But hey, isn't that always the case when you're having fun? So Gocept, thanks again for everything and hope to see you in 2014! --- ### Setuptools - run custom code in setup.py - Published: 2013-08-15 - Modified: 2015-10-13 - URL: https://niteo.co/blog/setuptools-run-custom-code-in-setup-py/ - Categories: Tech - Tags: Python, Setuptools A week or so ago I started developing an experimental Python package for one of our projects. At some point I realized that it would be convenient to automatically execute some additional initialization code during the package installation process (i. e. when "python setup. py install" is run). This can be achived by subclassing the setuptools. command. install class and overriding its run method, like this (in setup. py): from setuptools import setup from setuptools. command. install import install class CustomInstallCommand(install): """Customized setuptools install command - prints a friendly greeting. """ def run(self): print "Hello, developer, how are you? :)" install. run(self) setup( ... NOTE: We reference the parent class' run method directly - we can't use super(... ). run(self), because setuptools commands are old-style Python classes and super does not support them. Now that we have a customized install class, we must tell the setuptools machinery to actually use it instead of the built-in version. We do this through the cmdclass parameter of the setup function: ... setup( ... cmdclass={ 'install': CustomInstallCommand, }, ... ) The value of the cmdclass parameter should be a dictionary whose keys are the names of the setuptools commands we're customizing ('install' in our case), while the corresponding values are our custom command classes we have defined eariler (CustomInstallCommand in this example). BONUS Sometimes you will want to apply the the same modification to more than a single command class. For instance your package could also be installed in development mode (by running python... --- ### Write a Plone CLI maintenance script - Published: 2013-07-31 - Modified: 2015-10-13 - URL: https://niteo.co/blog/write-a-plone-cli-maintenance-script/ - Categories: Tech - Tags: Plone, Python This is a quick tip on how to write your own command line maintenance scripts for your Plone application. Recently one of our clients expressed a need for a maintenance script which would walk the database of a Plone application and, for every object, print out all the roles users have assigned on that object. Since we were dealing with a large database, processing it would take a considerable amount of time, rendering a solution with a browser view (or similar) not particularly useful. We needed some kind of a command line utility which would occasionally be run in the background (e. g. as a cron job) and would output results to a file. The question which arised next was how to write such a Python script so that it would hook up to the Plone application, its database and would at the same time already have access to all the Plone utilities it might need (i. e. Products. CMFCore). I searched around the internet quite a bit before I finally stumbled upon the missing part. It turned out to be pretty easy actually. The key is to define a zopectl. command entry point in your package's setup. py (i. e. in a package containing your maintenance script): setup( ... entry_points=""" dump_roles = your. package. module:some_callable """, ... ) You can then add this package as a dependency of the bigger Plone project, run the buildout and there it is - your maintenance script (named dump_roles in our example) can... --- ### Load overrides.zcml in plone.app.testing - Published: 2013-03-08 - Modified: 2015-10-13 - URL: https://niteo.co/blog/load-overrides-zcml-in-plone-app-testing/ - Categories: Tech - Tags: Plone, plone.app.testing, Testing Today I was working on a project where we use overrides. zcml to easily override some default Plone behavior. All was working fine (in the browser, that is) until I started writing tests for our custom behavior. First thing I noticed was that the overrides. zcml was not loaded in our test layer. "Doh, I need to load it manually with the loadZCML method! " I thought to myself. Boy was I wrong :). The problem with using loadZCML is that it loads whatever ZCML you tell it to load in a "normal" way. So, obviously, you get conflict errors, since declarations in your overrides. zcml directly map declarations that they override. Hence I needed to find a way to tell plone. app. testing to load my overrides. zcml in an "override" manner and not throw conflict errors. After quite some research and asking around, I got a tip from JC Brand on the #plone IRC channel: use xmlconfig. includeOverrides. This indeed got me the exact result I wanted. Here's a snippet for my future self and any other plonista struggling with the same problem that happen to stumble upon this blog: from plone. app. testing import PLONE_FIXTURE from plone. app. testing import PloneSandboxLayer from plone. testing import z2 from zope. configuration import xmlconfig class MyProductLayer(PloneSandboxLayer): defaultBases = (PLONE_FIXTURE,) def setUpZope(self, app, configurationContext): import my. product self. loadZCML(package=my. product) xmlconfig. includeOverrides(configurationContext, 'overrides. zcml', package=my. product) z2. installProduct(app, 'my. product') --- ### Dexterity vs. Archetypes - Published: 2013-02-16 - Modified: 2015-10-13 - URL: https://niteo.co/blog/dexterity-vs-archetypes/ - Categories: Tech - Tags: Performance, Plone TL;DR: migrating your Archetypes content to Dexterity shrinks your Data. fs considerably! I've started looking into migrating Archetypes content in one of the sites we're running to Dexterity. But before I started coding I wanted to make sure that the juice is worth the squeeze. The site contains roughly 130k content objects. Most of them are default Plone File type, with a few additional string fields (added with archetypes. schemaextender) and a custom workflow. Nothing fancy, just your standard integration project. New content is imported into the site in batches of ~10k items every now and then with the help of the awesome collective. transmogrifier. To test how Dexterity compares to Archetypes for our use-case I first created a new Dexterity type that matched the feature-set of the Archetypes type. Then I created a fresh instance, used Transmogrifier to import 13k items (10% of our production data) and ran some numbers. Results are pretty amazing. With Archetypes, an import of 13k items into a fresh Plone 4. 2 site took 61 minutes and the resulting Data. fs had 144 MB (details). With Dexterity, the same import took only 18 minutes and the resulting Data. fs had 64 MB (details). That's a whopping 70% decrease in import time and a 55% decrease in Data. fs size! More than enough to be a valid reason to invest in rewriting our types and write that migration script. --- ### Raspberry PI boot to browser - Published: 2013-01-22 - Modified: 2015-10-13 - URL: https://niteo.co/blog/raspberry-pi-boot-to-browser/ - Categories: Tech - Tags: Plone, Raspberry PI Here at NiteoWeb, we use various SaaS monitoring and logging providers such as Librato Metrics and Papertrail to keep on top of our Plone and Pyramid projects. Hence the need to have a wall-mounted screen to display various graphs and outputs these services. What better way to drive the screen than a Raspberry Pi! Getting the Raspberry Pi to boot into X and connect to the net was fairly trivial, just follow the official docs. However, getting the Pi to boot directly into a browser (also called "kiosk" mode) required some research. This is how I've done it in the end: Disable screen sleep -- so the screen stays on $ sudo nano /etc/lightdm/lightdm. conf # add the following lines to the section # don't sleep the screen xserver-command=X -s 0 dpms Hide cursor on inactivity $ sudo apt-get install unclutter Configure LXDE to start the Midori browser on login $ sudo nano /etc/xdg/lxsession/LXDE/autostart # comment everything and add the following lines @xset s off @xset -dpms @xset s noblank @midori -e Fullscreen -a http://plone. org That's it! Reboot and you are done! --- ### Convert z3c.form field desc. to tooltip - Published: 2012-12-14 - Modified: 2015-10-13 - URL: https://niteo.co/blog/convert-z3c-form-field-desc-to-tooltip/ - Categories: Tech - Tags: Plone, z3c.form Let's say you have a typical form with some input fields. By default z3c. form displays a description (if provided in form definition) above each form field, like in the screenshot below for example: Sometimes however, you might want to make things a little bit different. Perhaps you want to save some screen space by hiding field descriptions, but still want to provide helpful additional information on form fields to your users. One way of achieving this is to display field descriptions as tooltip text: Not bad. And it's easy too. Simply set the title attribute of a corresponding form field and you're done. I'll show you how we did it for one of our clients. The form was called List Events, because, well, it lists upcoming events based on search criteria. # file eventlist. py in browser directory ... from z3c. form import form ... class ListEventsForm(form. Form): ... def updateWidgets(self): """Move fields' descriptions to title attributes of HTML form elements. """ super(ListEventsForm, self). updateWidgets for name, widget in self. widgets. items: widget. title = widget. field. description In the ListEventsForm class we override the updateWidgets method in order to iterate through all form fields and set their title attribute. Note that this makes tooltips to show, but field descriptions themselves are still visible. We hide them with the following CSS rule (``eventlist-form`` being our form's ID): #eventlist-form div. formHelp { display: none; } And that's all, folks! --- ### How to change element's ID with Diazo? - Published: 2012-12-13 - Modified: 2015-10-13 - URL: https://niteo.co/blog/how-to-change-elements-id-with-diazo/ - Categories: Tech - Tags: Plone, Theming A common scenario: on your website all subpages share a common header, but you want a different header on the front page. Let's say you differentiate between both header versions by their ID attribute and define two different sets of CSS rules for each version. When applying Diazo rules to a theme file, you therefore need to change header element's ID, depending on whether the first page or one of the subpages was requested. Here's a snippet from rules. xml, which does exactly that: header-subpage ID of the header as defined in theme file (header-index) is changed to header-subpage after the rule above is applied. The rule basically says "Match #header-index element in theme file and use some inline XSL on it". The "xsl:attribute" tag matches current element's attribute whose name is "id" (with "current element" being the #header-index element as matched by the outer tag). The content of the "xsl:attribute" tag is a new value for the ID attribute. Nothing spectacular here indeed, but I lost quite some time trying to figure out how to do it in a simple yet efffective way. Very frustrating for such a small task. Various suggestions found on Google simply didn't work or were a bit too complicated (there must be an easier way to do it, right? ). So to help you avoid all the trouble, I decided to wrote this blog post. Too bad it didn't exist before. ;) --- ### Robot on Travis - uploading results to S3 - Published: 2012-11-15 - Modified: 2015-10-13 - URL: https://niteo.co/blog/robot-on-travis-uploading-results-to-s3/ - Categories: Tech - Tags: Plone, Robot framework, Selenium, Testing, Travis CI This is a walkthrough of how one could upload to Amazon S3 screenshots and other output files produced by Robot framework ran in a Travis CI build. The reason why we want to do this is to be able to inspect what Robot sees and have more information when a test fails. It's written with some things specific to Plone development, nevertheless it should still be useful for any other framework/language supported by Travis. Preparing Amazon S3 Go to http://aws. amazon. com/ and sign-up & login. Go to http://aws. amazon. com/s3/ and click "Sign Up Now" to enable Amazon S3 for your account. Go to https://console. aws. amazon. com/s3/home and click "Create Bucket" named "my-travis-builds" or something similar. Travis will upload screenshots inside this bucket. Go to https://console. aws. amazon. com/iam/home, click "Users" in the left navigation sidebar and then click "Create New Users" button. Enter "travis" as a username and keep the "Generate an access key for each User" checked. This is the user that Travis CI will use to upload files to your Amazon S3 account. When your user is created click the "Download credentials" -- we'll need them later. Now click on the "travis" user, select the "Permissions" tab and click "Attach User Policy". Select "Custom Policy" and click "Select". Enter "travis-upload-only" or similar as the Policy Name and paste the following into the Policy Document field: { "Statement": , "Effect": "Allow", "Resource": }, { "Action": , "Effect": "Allow", "Resource": }, { "Action": , "Effect": "Allow", "Resource":... --- ### 10 days to sprint in Antwerp! - Published: 2012-06-28 - Modified: 2015-10-13 - URL: https://niteo.co/blog/10-days-to-sprint-in-antwerp/ - Categories: Tech - Tags: Plone, Sprint The Belgian Beer Sprint is nearing ever so closer! Only a bit over a week is left until we start this year's EESTEC Plone sprint. Like last years we invited Electrical Engineering students from around Europe for a week-long introduction to Plone. In the meantime we will have members of the Plone community sprinting on various sprint topics, mostly oriented into entry-level Plone documentation and tools. Sprints like this offer unique opportunity for the Plone community to observe how newcomers consume our documentation and where they get stuck. However, due to the Plone Conference being in Europe this year and EuroPython being just a week before the sprint, we are facing financial problems. We have a budget of 5. 000 EUR with which we are covering accommodation, three meals per day, t-shirts and other niceties for all participants (around 25 in total). We are still missing ~1000 EUR of our goal and would like to ask again everyone in the Plone community to help us reach it. In any case, whatever we will be missing at the end, we'll just split among the ~10 Plone participants (obviously we cannot ask students for additional 100 EUR). Ways to help: Donation: any amount, on the 'info@eestec. be' PayPal account -- and your name will be mentioned under supporters on the sprint page Sponsorship: any amount above 100 EUR, either through PayPal or bank transfer -- you can get a VAT invoice for the sponsorship, your company logo goes on the sprint page... --- ### Testing log output - Published: 2012-06-03 - Modified: 2015-10-13 - URL: https://niteo.co/blog/testing-log-output/ - Categories: Tech - Tags: Plone, Testing ATTRIBUTION: This post was inspired by Domen's Mocking logging module for unittests post back from 2009. Most of the code below is from him, with some added Plone specific bits and pieces. I was recently debugging an installation of our niteoweb. click2sell and had the need for more verbose error handling. After adding support for it in the code I wondered if and how I should test what was written to the log under different scenarios. The final result of my research looks like this: Create a logger handler that stores all records in a list. Add this handler to the logger on layer setup. Use it in tests to assert log output. Reset its list on test teardown. First, let's look at the code for the logger handler, that you would likely put in the same module as where you define your test cases and such (base. py in my case): class MockedLoggingHandler(logging. Handler): debug = warning = info = error = def emit(self, record): getattr(self. __class__, record. levelname. lower). append(record. getMessage) @classmethod def reset(cls): for attr in dir(cls): if isinstance(getattr(cls, attr), list): setattr(cls, attr, ) Now, assuming you use plone. app. testing, add the following lines somewhere in your layer setup (setUpPloneSite in my case): logger = logging. getLogger('your. package') logger. addHandler(MockedLoggingHandler) You are ready to assert log output in your tests: def test_log_output(self): some_method_that_prints_to_log from your. package. tests. base import MockedLoggingHandler as logger self. assertEqual(logger. error, "Error occured! ") Finally, remember to clear the list of log... --- ### Fixing unresolved dependencies error - Published: 2012-03-23 - Modified: 2015-10-13 - URL: https://niteo.co/blog/fixing-unresolved-dependencies-error/ - Categories: Tech - Tags: Plone For a while now we've been getting the following errors on one of our sites: WARNING GenericSetup There are unresolved or circular dependencies. Graphviz diagram:: digraph dependencies {"typeinfo" -> "toolset"; "tinymce_settings" -> "componentregistry"; "transmogrifier" -> "toolset"; "kss_mimetype" -> "mimetypes-registry-various"; "pleonformgen" -> "toolset"; "pleonformgen" -> "propertiestool"; "pleonformgen" -> "typeinfo"; "atcttool" -> "catalog"; "atcttool" -> "componentregistry"; "actions" -> "componentregistry"; Apparently they are not harmful so I let them be for a while. But yesterday, while upgrading to Plone 4. 2b2, it was time to track down the source of these errors and hopefully fix them. I started by downloading GraphViz to vizualize the dependency diagram reported by GenericSetup. After I had it installed it was time to create a . dot file that I could feed into GraphViz. I did that by creating an empty file, adding strict digraph G to the first line, followed by whatever GS outputted in curly braces: strict digraph G {"typeinfo" -> "toolset"; "tinymce_settings" -> "componentregistry"; "transmogrifier" -> "toolset"; "kss_mimetype" -> "mimetypes-registry-various"; "pleonformgen" -> "toolset"; "pleonformgen" -> "propertiestool"; "pleonformgen" -> "typeinfo"; "atcttool" -> "catalog"; "atcttool" -> "componentregistry"; "actions" -> "componentregistry"; Opening my graph. dot in GraphViz I was presented with the following diagram, showing two unresolved dependencies: plonepas and collective. prettyphoto. I started with collective. prettyphoto as it's an add-on and probably easier to fix than Plone Core. After some research I found out that this issue was already fixed by Ross Patterson. Pinning collective. prettyphoto to the latest release, 0. 4. 4, indeed fixed the problem:... --- ### OpenVPN over SSH - Published: 2012-02-09 - Modified: 2015-10-13 - URL: https://niteo.co/blog/openvpn-over-ssh/ - Categories: Tech - Tags: Plone, ssh Prelude I've recently moved to Barcelona to continue my Computer Science studies on UB. First thing I noticed walking into the University building was my mobile happily notifying me that it has found a known network. Ah, of course: eduroam. My Slovenian eduroam account from University of Ljubljana should be valid throughout Europe for accessing the eduroam wireless network. And indeed it is. Nice. Troubles on the horizon Alas ... there is a downside. Apparently the IT dept at UB is filtering OpenVPN and IPsec traffic. I'm soo used to having these that I feel "naked" using a public network without encrypting all my communications. Now wait a minute, what do I see here, SSH traffic goes through without problems? If SSH goes through, then it should possible to tunnel basically anything through it. Even an OpenVPN tunnel. Yep, tunneling a tunnel over a tunnel, that's the idea :). The solution After some fiddling around, this is how I did it (referencing my original setup): Find a server somewhere on the net you can SSH to, so you can setup a SOCKS proxy: $ ssh -D 6666 Change protocol in OpenVPN's server. conf to use TCP rather than UDP. Normally, using UDP is better, but if you want tunneling over SOCKS, you need TCP: proto tcp Change protocol in OpenVPN's iptables config: iptables -I INPUT 1 -p tcp --dport 1194 -j ACCEPT Now modify the client. conf to use TCP and to use SOCKS proxy: proto tcp socks-proxy 127. 0.... --- ### Professional Plone 4 development review - Published: 2011-11-20 - Modified: 2015-10-13 - URL: https://niteo.co/blog/professional-plone-4-development-review/ - Categories: Tech - Tags: Plone Short summary If you are doing Plone 4 development, go buy this book. Now. Some background I started working with Plone in 2006. Back then I was really just beggining with development in general and did not know how to do things properly. I only knew how to tweak some templates and to use ArchGenXML to generate some content types. No version control, no tests, no nothing. Then Professional Plone 3 Development came. "Wow, I'm doing things seriously wrong" was my first reaction. That booked steered me in the direction of using Subversion to control my source code, writing tests to prove my code doesn't break in various places, using pdb - the Python debugger, deploying Plone sites myself, etc. Plone 3 vs. Plone 4 However, Plone 3 was complicated. There were all these new technologies and concepts that you now had to use. That's not bad in itself, but those technologies only delivered part of the story. You still had to use old ways to do certain tasks. Plone's learning wall was higher than ever. With Plone 4, these technologies are not new anymore. They are polished and widely used. You only need to learn one way to do something, not three. As a consequence of this, Plone is now easier to learn. Plone's development process is cleaner, more defined, with better tools. The new book from Martin is the same: less history overhead, more confidence in newer, better tools and concepts. PP4D Having in mind how much Martin's... --- ### Plone 4 dev on Lion - Published: 2011-09-15 - Modified: 2015-10-13 - URL: https://niteo.co/blog/plone-4-dev-on-lion/ - Categories: Tech - Tags: Plone Introduction Recently I upgraded to OS X Lion and here are my notes on how I got my working environment working. XCode First things first, you need to setup build tools (gcc, make and the like). On OS X these come as a part of XCode. Even if you had XCode installed on Snow Leaopard before upgrading to Lion, do take time and reinstall it completely. Stuff changed since the white cat and it's safer to have your build tools up-to-date. collective. buildout. python Same story as with XCode. Remove your collective. buildout. python directory entirely and recreate it from scrach. It takes a while, go make yourself some nice tea. UPDATE: In OSX 10. 7. 1 readline does not get built because it's configuration script does not correctly recognizes the OS. You can fix this by appending the following two lines to the bottom of src/readline. cfg in your local checkout of collective. buildout. python and re-running buildout. make-options = SHOBJ_LDFLAGS="-dynamiclib" egg cache If you are using a local egg cache it might get tricky. Some people report everything works fine, but several people also report that things were randomly breaking until they had removed all eggs from their egg cache and re-ran buildout. My suggestion? Clear the cache! It takes a while to download all those eggs again, but it beats losing a day chasing readline related SEGFAULTS causing Zope crashes on seemingly random requests: Program received signal EXC_BAD_ACCESS, Could not access memory. Reason: KERN_INVALID_ADDRESS at address: 0x0000000000000000... --- ### Help me get to PloneConf! - Published: 2011-08-27 - Modified: 2015-10-13 - URL: https://niteo.co/blog/help-me-get-to-ploneconf/ - Categories: Tech - Tags: Plone Intro Hi, I'm Nejc, a Plone user since 2005. I'm trying to get to the Plone Conference in San Francisco this year to do a talk on Raptus Article and I need a few dollars worth of help. At first I did not plan to go due to being expensive to get from Slovenia to the States. But then my talk Plone Article -> Raptus Article got accepted! Now I have strong motivation to go! I also plan to attend the post-conference sprint and will work on things that anyone donating would like me to. Read more about me below or help me out immediately. Why I need $800? Well, I did a quick back-of-the-envelope calculation of what expenses I'll have: plane ticket from Slovenia ~$900, accommodation ~$250, food ~$250 and a student rate conference ticket $225; the total sum being ~1600. I can afford to cover half of these expenses, but not much more. And man would I like to attend this conference :). About me I started using Plone in 2005 and liked the hell out of it immediately. Shortly after that I started my own Plone consultancy firm for small projects in Slovenia, my home country. Meanwhile I am still a student at University of Ljubljana, currently in my (hopefully) last year. In these 6 years of me being a Plonista I've taught Plone to numerous students on international student workshops we organized throughout Europe (google for "Plone My Web"). Some of them became active members of... --- ### collective.table, report #3 - Published: 2011-08-08 - Modified: 2015-10-13 - URL: https://niteo.co/blog/collective-table-report-3/ - Categories: Tech - Tags: Plone, Sprint Work report A week ago, myself and my mentor both participated in the Plone Sauna Sprint. It was an epic event, thanks to all sprinters for being that great throughout the week. During the event my mentor and I discussed in great length how to approach challenges that collective. table presents. We want the table to be pluggable and reusable. We want to support having several tables on one page. We want to support having multiple backend data sources for our tables, with a dedicated configuration view for each data source. Current status Table works, we have one data source. Multiple sources are being supported, prototype for configuration view is ready. Also, my brand new MacBook Pro died. Apparently RAM problems, or so they say at the repair shop. So now I am stuck using an old laptop, which hinders my ability to be productive. Plans First, I need to get my MacBook back from the repair shop to restore my normal working environment. Hopefully they can get it fixed in a couple of days. Next thing on the menu is to polish and document configuration views for storages. Followed with tests for them. After that, we'll see how much more time we have until the GSoC deadline and decide priorities based on that. --- ### collective.table alpha release - Published: 2011-07-21 - Modified: 2015-10-13 - URL: https://niteo.co/blog/collective-table-alpha-release/ - Categories: Tech - Tags: Plone, Sprint Introduction It's now past the mid-term evaluation deadline for my Google Summer of Code project and it's time to release my work out to the wider community to receive feedback and ideas on how to improve it. Status During the last days I was focusing on polishing the first release: writing documentation, adding more comments, increasing test coverage and such. My plan was to have a public release just days before Sauna Sprint so I can start getting valuable feedback from the community on the progress and roadmap for the project. But why did I chose Sauna Sprint as a deadline? Well, myself and my GSoC mentor Martijn Pieters will both be there for the entire sprint next week. Productivity will be through the roof if I can judge based on the number of Plone sprints I attended in the past. We'll mainly be focusing on improving the UI and making our storage more scalable. Give it a spin! So: buckle-up, add collective. table to your eggs and give it a spin! Any and all feedback is greatly appreciated. The release is available on PyPI and code is available on GitHub. --- ### collective.table GSoC report - Published: 2011-07-04 - Modified: 2015-10-13 - URL: https://niteo.co/blog/collective-table-gsoc-report/ - Categories: Tech - Tags: Plone, Sprint Introduction It's now been over a month since I started my Google Summer of Code project. It's been a fun month, full of newly learned tricks, mostly courtesy of my mentor Martijn Pieters, Jarn AS. Our goal is to have an ability in Plone to store arbitrary pieces of tabular data, in the same way that PHP CMSes often have their databases abused for other things. A simple intranet solution for everything that is now uploaded as Excel files: equipment lists, book loans, etc. It's a list of items where members can add/edit columns and rows, and of course data. Status Currently we are nearing the first alpha release, which should be out in about 10 days, when we have the GSoC mid-term report deadline. I already have the basic CRUD interface with data being stored in a dictionary as a simple zope annotation. Here's a screenshot of how it looks in action: Anyhow, I need to do some polishing first and to increase test coverage, then we're ready for the first release! Roadmap By default collective. table comes with a simple zope annotation storage, called local storage that does not support advanced features, such as sorting and filtering. For use-cases where sorting and filtering are needed, plus the dataset could be much bigger I plan to create another storage. I'm currently leaning towards using cornerstone. soup as a backend for this additional storage. In any case, collective. table is designed to support many pluggable data storages, so later on... --- ### Collective SVN project -> GitHub - Published: 2011-06-09 - Modified: 2015-10-13 - URL: https://niteo.co/blog/collective-svn-project-github/ - Categories: Tech - Tags: Plone, svn More and more Plone projects are being migrated over to GitHub for various reasons. Here's a quick guide on how to import your Collective SVN project into GitHub. GitHub can directly import SVN projects only by specifying a URL to the repository. However, for some reason this does not work for Collective SVN repositories. The import screen keeps processing but nothing happens. You are left with the manual approach of migrating a Collective SVN repository to GitHub. GitHub account Naturally, you first need an account at GitHub. Go register if you don't already have one! Git repository Next you need to create a git repository. Login to GitHub and go to your Dashboard. Follow the New Repository button in the right-hand portlet and fill in the required fields. Click Create Repository. Great, your git repository is now ready! Instead of creating a new git repository in your own account, you can also consider creating one in the unofficial "Collective" GitHub account - an experiment by a few fellow Plonistas to recreate the Collective spirit on GitHub. Authors Before proceeding you need to compile a list of people that committed code to your project. Do that by inspecting output of svn log http://svn. plone. org/svn/collective/. Create a file called authors. txt where you map all SVN committers to GitHub users: zupo = Nejc Zupan The format of the mapping is svn_username = git_username . You can also generate this list automatically. Using plone. org's author page usually gives good enough results... --- ### Assertion `t_size >= b_size' failed - Published: 2011-03-22 - Modified: 2015-10-13 - URL: https://niteo.co/blog/assertion-t_size-b_size-failed/ - Categories: Tech - Tags: Plone Recently, when migrating a Plone 4 site from one VPS server instance to another, we had the following problem: We were not able to start Zope with Supervisord because it crashed every time we tried to start it. Running Zope in foreground (bin/instance fg) produced the following error: Python: Objects/typeobject. c:1736: extra_ivars: Assertion `t_size >= b_size' failed. Aborted Luckily, after some Googling around I discovered that Hanno had already commited a patch to fix this. Pinning eggs to patched versions by adding the lines below to versions. cfg fixed the problem entirely. # Handle tp_basicsize correctly ExtensionClass = 2. 13. 2 Persistence = 2. 13. 2 --- ### Multiple configurations for Tunnelblick - Published: 2011-02-26 - Modified: 2015-10-13 - URL: https://niteo.co/blog/multiple-configurations-for-tunnelblick/ - Categories: Tech A while ago I wrote about configuring Tunnelblick OpenVPN client for OS X. Here is how you can have multiple OpenVPN configurations with TunnelBlick: 1. Open ~/Library/Application\ Support/Tunnelblick/Configurations/ with Finder. 2. Rename openvpn. conf to openvpn-location-a. conf. 3. Duplicate openvpn-location-a. conf and rename the duplicate to openvpn-location-b. conf. 4. Open both of these configurations and change values such as server IP, etc. 5. Restart Tunnelblick. This should be it. Now you should be able to choose between configurations when clicking Tunnelblick's tray icon. --- ### Finding bad blocks on USB flash drives - Published: 2011-02-01 - Modified: 2015-10-13 - URL: https://niteo.co/blog/finding-bad-blocks-on-usb-flash-drives/ - Categories: Tech After a recent thorough cleaning of my office desk I found a handful of USB sticks. I knew some of them were more or less broken and some should be OK. But which are whic The solution that first came to mind was to scan USB drives for corrupted sectors / bad blocks. After some Googling around and reading through comments I came up with a process using 'badblocks' from 'ext2fs' package to scan for bad blocks: 1. Install ext2fsx. 2. Insert USB drive. 3. Backup data from the USB drive because 'badblocks' removes all data from the stick. 4. Identify USB drive in console. $ mount ... snip ... /dev/disk1 on /Volumes/NO NAME (msdos, local, nodev, nosuid, noowners) 5. Unmount USB drive so we can run 'badblocks' on it. $ sudo umount -f /Volumes/NO\ NAME/ 6. Run badblocks to identify and mark bad block WARNING: badblocks removes all data on drive. Make sure you have a backup and that you don't mistype the drive's i $ badblocks -vw /dev/disk1 7. Use 'Disk Utility' to format the drive so you can actually use it. --- ### Deploying Cyn.in 3.1.3 on CentOS 5.4 - Published: 2011-01-10 - Modified: 2015-10-13 - URL: https://niteo.co/blog/deploying-cyn-in-3-1-3-on-centos-5-4/ - Categories: Tech - Tags: Plone Last week we were upgrading Cyn. in to the latest version. After a few days of testing on a local server it was time to deploy it to the server. Since Cyn. in needs quite some RAM to operate normally, we chose Virpus VPS instance with 2 gigs of RAM, running CentOS 5. 4. Running buildout on the server produced this error: ... Modules/constants. c: In function ‘LDAPinit_constants’: Modules/constants. c:184: error: ‘LDAP_OPT_X_TLS_NEWCTX’ undeclared (first use in this function) Modules/constants. c:184: error: (Each undeclared identifier is reported only once Modules/constants. c:184: error: for each function it appears in. ) After a bit of googling around it seemed that the problem was caused by a bug in python-ldap. A quick look at CHANGES revealed that 2. 3. 10 version of python-ldap mentions work being done around LDAP_OPT_X_TLS_NEWCTX. Maybe it was fixed in the next version, 2. 3. 11? I tried pinning the version of python-ldap to 2. 3. 11 and buildout finished without errors. Great! Adding the following lines to buildout. cfg makes buildout more repeatable and future-proof: versions = versions python-ldap = 2. 3. 11 --- ### Testing memoized methods - Published: 2011-01-06 - Modified: 2015-10-13 - URL: https://niteo.co/blog/testing-memoized-methods/ - Categories: Tech - Tags: Plone, plone.memoize, Testing For a recent Plone project we needed to write unit tests for methods that were using plone. memoize for caching return values. With a standard Plone's PloneTestCase I got the following error: Error in test test_main_image (niteoweb. elcond. tests. test_stol. TestContent) Traceback (most recent call last): File "/Users/zupo/work/python/parts/opt/lib/python2. 6/unittest. py", line 279, in run testMethod File "/Users/zupo/work/niteoweb. elcond/src/niteoweb/elcond/tests/test_stol. py", line 75, in test_main_image image = self. portal. stol. main_image File "/Users/zupo/work/niteoweb. elcond/src/niteoweb/elcond/content/stol. py", line 91, in main_image images = self. images(sort_limit=1) File "/Users/zupo/. buildout/eggs/plone. memoize-1. 1-py2. 6. egg/plone/memoize/view. py", line 21, in memogetter annotations = IAnnotations(request) TypeError: ('Could not adapt', None, ) The cause of the problem is that TestRequest (used by PloneTestCase) does not allow IAnnotations adapter to store data in an attribute named __annotations__. The solution is to add the lines below to afterSetUp method of your TestCase. from zope. annotation. interfaces import IAttributeAnnotatable from zope. interface import directlyProvides from zope. publisher. browser import TestRequest request = TestRequest directlyProvides(request, IAttributeAnnotatable) --- ### Order of 'parts' when compiling lxml - Published: 2011-01-05 - Modified: 2015-10-13 - URL: https://niteo.co/blog/order-of-parts-when-compiling-lxml/ - Categories: Tech - Tags: Plone CentOS's repos don't have a working version of libxslt (you need 1. 1. 20, repos have 1. 1. 17) so we need to statically compile it for collective. xdv to work. But, there is a catch! You need to be careful about how you order your parts in your buildout. cfg. For examle, the following buildout. cfg works perfectly fine, it downloads libxml and libxslt and compiles them in your buildout environment for your use: extends = http://dist. plone. org/release/4. 0/versions. cfg parts = lxml zopepy recipe = zc. recipe. egg interpreter = zopepy eggs = lxml recipe = z3c. recipe. staticlxml egg = lxml static-build = true Problems start when you change the order of 'parts' section to be like this: parts = zopepy lxml ... In this case, zopepy wants to fetch the lxml egg and compile lxml immediately. Since the 'lxml' part has not been run yet, there is no libxml2 and libxslt available in your buildout and the whole thing crashes. The point being: always put the lxml part at the top of your parts list. The fix is a one-liner and I just spent 2 days figuring it out. I wish I knew this earlier. UPDATE: Florian Schulze pointed out that "an even better fix is to reference the lxml part from zopepy. extends = http://dist. plone. org/release/4. 0/versions. cfg parts = lxml zopepy recipe = zc. recipe. egg interpreter = zopepy eggs = ${lxml:egg} recipe = z3c. recipe. staticlxml egg = lxml static-build =... --- ### Upgrade Cyn.in 2.1 to 3.1.3 - Published: 2011-01-03 - Modified: 2015-10-13 - URL: https://niteo.co/blog/upgrade-cyn-in-2-1-to-3-1-3/ - Categories: Tech - Tags: Plone We started using Cyn. in for internal documentation repository about 2 years ago. We are a small team of developers and we don't use all of it's features, but we still do use it daily and have grown to love it. It's just great to have a place to store all little bits and pieces of information and have it searchable quickly. Now it was time to upgrade it so we keep up with the community around it in case anything goes wrong. Here's how we did it. Prepare a new version of Cyn. in Obviously you first need to get the newest version of Cyn. in up and running locally. Following Cynapse's guide on buildout helps you do it without much pain. When you have the environment ready, start up Zope and try if your Cyn. in installation works on a plain Plone instance. Upgrade Data. fs When you have confirmed that Cyn. in works it's time to upgrade the actual data. Shutdown Zope and remove everything in var/filestorage/ folder. Copy Data. fs from your old Cyn. in installation into var/filestorage/ folder. Start Zope. Go to http://localhost:8080//portal_migration and migrate Plone content to the latest Plone version Go to http://localhost:8080//portal_quickinstaller and reinstall ubify. site_policy. The reinstall will fail at this point. We had to perform the following (ugly) patches for reinstall to work: In file src/ubify. policy/ubify/policy/migration/onetimeinstall. py comment out line 114: - logger. info("Unable to assign collection portlet for smartview : %s" % (item,)) + # logger. info("Unable to... --- ### Secure IM for internal communication - Published: 2010-10-18 - Modified: 2015-10-13 - URL: https://niteo.co/blog/secure-im-for-internal-communication/ - Categories: Tech During this summer we finally got some time to review our internal working processes. One thing clearly missing was a solid IM solution for quick communication when working remotely. After trying out several different approaches we decided to use the old and well-proven one: IRC. Very important feature we were looking for was secure communication. Domen mentioned something about FISH, a blowfish implementation for IRC chats. One google search away we had exactly what we needed. Kubuntu users get Konversation installed on their system by default and Konversation has built-in support for FISH. Nice. Those of us using Colloquy on OS X, however, needed to install a plugin - FISHy. Download, copy to Plugins folder and we were set. Simple and effective. I like it when things just work. --- ### Click2Sell integration for Plone - Published: 2010-10-15 - Modified: 2015-10-13 - URL: https://niteo.co/blog/click2sell-integration-for-plone/ - Categories: Tech - Tags: Plone After integrating Clickbank with Plone last month we decided we also need integration with Click2Sell affiliate marketing network. A new Plone add-on was born: niteoweb. click2sell. The add-on has the same feature-set as it's sister add-on niteoweb. clickbank, enabling you to have paid membership on your Plone site. It's very simple to install and use. Project page: http://pypi. python. org/pypi/niteoweb. click2sell Documentation: http://packages. python. org/niteoweb. click2sell Code: http://svn. plone. org/svn/collective/niteoweb. click2sell --- ### Compiling lxml on 64bit CentOS - Published: 2010-08-24 - Modified: 2015-10-13 - URL: https://niteo.co/blog/compiling-lxml-on-64bit-centos/ - Categories: Tech - Tags: Plone A few days ago I encountered a problem while deploying Plone 4 with collective. xdv to a CentOS cloud instance. Since CentOS' repos were a bit out of date I needed to statically compile lxml and it's dependencies with z3c. recipe. staticlxml. Here's what you need to add to your buildout. cfg to do so: parts += lxml eggs += lxml # =================================================================== # For collective. xdv to work properly, we need a static build of lxml # and it's dependencies on OS X and x86_64 Linux # =================================================================== recipe = z3c. recipe. staticlxml egg = lxml force = false static-build = true And here's the kicker: on some 64-bit Linux systems compiling lxml produces an error like this at compile-time: lxml: Building lxml ... Building lxml version 2. 2. 6. NOTE: Trying to build without Cython, pre-generated 'src/lxml/lxml. etree. c' needs to be available. Using build configuration of libxslt 1. 1. 24 Building against libxml2/libxslt in one of the following directories: /home/production/1. 1/parts/lxml/libxslt/lib /home/production/1. 1/parts/lxml/libxml2/lib /usr/bin/ld: /home/production/1. 1/parts/lxml/libxslt/lib/libxslt. a(xslt. o): relocation R_X86_64_32 against `a local symbol' can not be used when making a shared object; recompile with -fPIC /home/production/1. 1/parts/lxml/libxslt/lib/libxslt. a: could not read symbols: Bad value collect2: ld returned 1 exit status error: Setup script exited with error: command 'gcc' failed with exit status 1 An error occured when trying to install lxml 2. 2. 6. Look above this message for any errors that were output by easy_install. While: Updating lxml. Error: Couldn't install: lxml 2. 2. 6... --- ### DD-WRT + Tunnelblick = OpenVPN - Published: 2010-08-12 - Modified: 2015-10-13 - URL: https://niteo.co/blog/dd-wrt-tunnelblick-openvpn/ - Categories: Tech Debating about VPNs on the Sauna Sprint, sprinters convinced me that we should use VPN for remote access to our internal services in our office. And for an extra layer of security when using public networks. So here it goes. Certificates I didn't want to install openssl and openvpn on my Macbook just so I could generate access certificates. Luckily, Rackspace Cloud instance with Ubuntu was only 2 minutes away. From there on I just followed the tutorial on creating certificates. OpenVPN server Since we already have a Linksys WRT54G router running DD-WRT firmware it was an obvious decision to just use this piece of hardware to act as an OpenVPN server. Off to the DD-WRT download page and grab the package that also has OpenVPN support (dd-wrt. v24_vpn_generic. bin). Quick flash of the router's firmware and we are set. Enable OpenVPN server in Services and set it's Start type to WAN Up. Paste in certificates created in advance on a Ubuntu cloud instance. Paste in OpenVPN server config (find it below). Configure iptables by going to Administration -> Commands, pasting in iptables config (find it below) and clicking save firewall. Reboot router. Tunnelblick OpenVPN client For OS X users the recommended application for using OpenVPN is Tunnelblick. 1. Go to Tunnelblick's website, download Tunnelblick 3. 0 application and install it. 2. Run Tunnelblick. Click install and edit sample configuration file and paste into it client configuration (find it below). 3. In this configuration, find SSL/TLS parms. and replace text... --- ### Back from Helsinki - Published: 2010-08-10 - Modified: 2015-10-13 - URL: https://niteo.co/blog/back-from-helsinki/ - Categories: Tech - Tags: Plone, Sprint I'm back from another legendary sprint: Plone Sauna Sprint in Helsinki. No need to say anything more, here are the reports: Plone Sauna Sprint mid-term report Plone Sauna Sprint final report Next on schedule: Plone Conference in Bristol. --- ### Clickbank integration for Plone - Published: 2010-07-13 - Modified: 2015-10-13 - URL: https://niteo.co/blog/clickbank-integration-for-plone/ - Categories: Tech - Tags: Plone So you want paid membership on your Plone site? Look no further, we present to you niteoweb. clickbank. It's a Plone 4 add-on that integrates ClickBank digital products retailer system with Plone to enable paid memberships on your Plone site. It's very simple to install and use. Project page: http://pypi. python. org/pypi/niteoweb. clickbank Documentation: http://packages. python. org/niteoweb. clickbank Code: http://svn. plone. org/svn/collective/niteoweb. clickbank --- ### MladiPodjetnik.si performance tweaks - Published: 2010-05-19 - Modified: 2015-10-13 - URL: https://niteo.co/blog/mladipodjetnik-si-performance-tweaks/ - Categories: Tech - Tags: Plone MladiPodjetnik. si is a portal we've been actively developing since 2006 and has since seen 3 revisions. The latest one, running on Plone 3. 1, was running out of juice due to enormous increase in traffic in the last year. It was time to do some performance optimization. 1. We started out by upgrading Plone to the latest 3. x realease - 3. 3. 5. A fairly straightforward procedure. 2. Then we focused on optimizing Zope settings: setting python-check-interval to 1000 lowering ZServer threads (we could do this because we were adding ZEO clustering with several Zopes) tweaking ZODB cache size disabling Z2. log specifying only one language (Slovenian) for the Placeless Translation Service # add these lines to section of your buildout. cfg z2-log = off zodb-cache-size = 13500 zserver-threads = 1 zope-conf-additional = python-check-interval 1000 environment-vars = PTS_LANGUAGES sl 3. Binding to a newer version of zope. i18nmessageid fixes severe memory leaks in Zope. zope. i18nmessageid = 3. 5. 1 4. Finally we built and configured HAProxy load-balancer so we can have several Zopes serving those requests. Result: Tweaking proved to be successful as we no longer get time-outs on traffic peaks and the site feels much more snappier than before. Munin graphs confirm this. --- ### New Plone website - Vodja.si - Published: 2010-04-30 - Modified: 2015-10-13 - URL: https://niteo.co/blog/new-plone-website-vodja-si/ - Categories: Tech - Tags: Plone It's time for a new website release. This time it's Vodja. si. Vodja. si is a presentation website for a NLP and leadership trainer Marjan Račnik. The base for the project is default Plone CMS with a unique theme developed from a Photoshop mockup and some Plone add-ons such as ContentWellPortlets. The site also has an intranet section where training participants can download materials and do some basic collaboration. More about the project on our portfolio page. --- ### IMW, Athens and Cathedral sprints - Published: 2010-03-28 - Modified: 2023-09-15 - URL: https://niteo.co/blog/imw-athens-and-cathedral-sprints/ - Categories: Tech - Tags: Plone, plone.app.search, Sprint I've attended 3 sprints in the past month. Sprints are a great way to learn new Plone techniques and of course to meet fellow plonistas. I love the fact that I was able to attend 3 in just one month. Next one on the schedule: Plone Sauna Sprint in Helsinki in the end of July. IMW mini sprint During the second International Motivational Weekend organized by LC Munich near Salzburg, Austria, the EESTEC IT Team got together and fixed some issues on eestec. net. In a short period of time we managed to squash several bugs and updated content on the site. A full report at eestec. net/news-and-offers/itt-mini-sprint-report. Cathedral sprint Then came the Plone Cathedral Sprint 2010 which is a first 'proper' Plone sprint I attended. From day 1 I loved being there, working with Plone rock stars on the future releases of Plone 4. x. I helped Denys Mishunov on search results page improvements (plone. app. search package) which will hopefully ship with Plone 4. 1. Signing the Contributor Agreement I was accepted into the Plone core developers family and I immediately committed some code. Yaay! Read the whole report on Jarn's blog. Athens sprint Finally, another sprint during an EESTEC event, this time an annual Congress, the IT Team got together to do some hacking. Florian, Joni and me spent the whole week in the lobby of Hotel Titania. We started where we left in Skopje in November 2009. Commiting everything that was done on the server in... --- ### New project - BigContentSearch.com - Published: 2010-03-01 - Modified: 2015-10-13 - URL: https://niteo.co/blog/new-project-bigcontentsearch-com/ - Categories: Tech - Tags: Plone Last week we introduced a new project - BigContentSearch. com. It will be the first PLR membership website on the internet with over 100,000 articles in a searchable database. Since we are dealing with a huge amount of data, we want to use Plone 4 with it's out-of-the-box blob storage capabilities. Since Plone 4 is still in it's alpha release, the site is still a bit buggy but it works in general. We'll be starting with closed beta release in the following days and give away some free memberships to get the first feedback. Later on we'll be integrating ClickBank to enable affiliate marketers to sale our product. More information about our affiliate program on bigaffiliateprogram. com. The site is currently in pre-public stage, running on plr. niteoweb. com and not on it's soon-to-be public domain bigcontentsearch. com. Follow us on the project's blog. --- ### OS X specific .cfg for collective.xdv - Published: 2010-02-23 - Modified: 2015-10-08 - URL: https://niteo.co/blog/os-x-specific-cfg-for-collective-xdv/ - Categories: Tech - Tags: Plone The collective. xdv manual on plone. org tells you how to customize your buildout. cfg in order to be able to run collective. xdv on OS X. However if you are working in a team of developers where not everyone is using OS X, it's nice to have your specific buildout hacks in a separate osx. cfg file. Below is an OS X specific osx. cfg file that extends the original buildout. cfg with OS X specific hacks for collective. xdv. extends = buildout. cfg parts += lxml versions = versions lxml = 2. 2. 2 recipe = z3c. recipe. staticlxml egg = lxml force = false Now all you need to do is run buildout with config file set as osx. cfg. $ bin/buildout -c osx. cfg --- ### New Wordpress sites - Published: 2010-02-14 - Modified: 2015-10-13 - URL: https://niteo.co/blog/new-wordpress-sites/ - Categories: Tech - Tags: Wordpress In the past few months we've deployed 3 new Wordpress sites. They are all basic presentation sites with low running costs. Presentation Website for Moj fit - www. mojfit. com Presentation Website for MIROR d. o. o. - www. miror. rs Sales Website for Zavod mladi podjetnik - mp-racunovodstvo. si You can find more info about these project on our portfolio page. --- ### New Plone website - LifeInLjubljana.si - Published: 2010-02-01 - Modified: 2015-10-13 - URL: https://niteo.co/blog/new-plone-website-lifeinljubljana-si/ - Categories: Tech - Tags: Plone During the first month of 2010 we've been busy developing a new site for Erasmus students in Ljubljana - LifeInLjubljana. si. It helps Erasmus students coming to Ljubljana to easily find a room and connect with other Erasmus students already in Ljubljana. We use custom developed content types to provide a the list of available flats/beds with an advanced search. Visitors can do a sorted search on several characteristics of a flat/bed. There is also integration with Google Maps so the system can automatically calculate distances from a selected flat to nearest faculties. More about the project on our portfolio page. --- ### Testing session in Plone 3.3 - Published: 2010-01-07 - Modified: 2015-10-08 - URL: https://niteo.co/blog/testing-session-in-plone-3-3/ - Categories: Tech - Tags: Plone, Testing Yesterday, while I was working on LifeInLjubljana. si, I had to test if some data was correctly written to Plone's session. I couldn't use the standard ptc. FunctionalTestCase test case as it does not have a session and I would get errors like this: (Pdb) self. context. session_data_manager *** AttributeError: session_data_manager (Pdb) self. context. REQUEST. SESSION *** AttributeError: SESSION Following a tip on the Plone-Users mailing list and some trail-and-error I have come up with a solution. Below is my test case with which I can build functional tests for sessions: class SessionFunctionalTestCase(ptc. FunctionalTestCase): """ We use this base class for all the session-related tests in this package. """ def afterSetUp(self): # Set up sessioning objects ztc. utils. setupCoreSessions(self. app) class Session(dict): def set(self, key, value): self = value def _setup(self): ptc. FunctionalTestCase. _setup(self) self. app. REQUEST = self. Session --- ### unrestrictedGetObject() - Published: 2009-12-15 - Modified: 2015-10-08 - URL: https://niteo.co/blog/unrestrictedgetobject/ - Categories: Tech - Tags: Plone, portal_catalog Argh! Sometimes I am truly amazed by how much I can complicate things. For the past year or so, every time I had to access an object with brain. getObject that I otherwise did not have permission to, I went to great lengths hacking Zope's SecurityManager to let me do it. Today, I was introducted to unrestrictedGetObject. I have kind of expected that it should exist, but I've always looked in the wrong place. It's dead-easy to use: brain. _unrestrictedGetObject Hopefully this spares someone some frustration. --- ### CWPortlets, Scrawl and DISQUS - Published: 2009-12-12 - Modified: 2015-10-08 - URL: https://niteo.co/blog/cwportlets-scrawl-and-disqus/ - Categories: Tech - Tags: Plone, Scrawl Following previous post, here are instructions to get above mentioned products running on Plone 4 Alpha 2. Products. ContentWellPortlets ContentWellPortlets is a great product that enables you to add portlets before and after content as well as in the footer. There is no official release for Plone 4 yet (as expected) so you need to use the latest code directly from the collective subversion repository. Fairly simple, with a little help from a buildout recipe called infrae. subversion. parts += eggcheckouts recipe = infrae. subversion location = src as_eggs = true urls = TODO Products. Scrawl Scrawl is a simple blogging tool for Plone. Exactly what we need for this site. The procedure for installing it on Plone 4 Alpha 2 is the same as above. Only change the url to TODO. collective. disqus This product replaces default Plone commenting engine with DISQUS commenting system. Perfect for simple sites like this one. Installation is fairly simple, just add collective. disqus to eggs section of your buildout. cfg, re-run buildout and restart Zope. Now just enter your DISQUS id in the plone control panel and you are done. --- ### Plone4 + collective.xdv + deco.gs - Published: 2009-12-06 - Modified: 2015-10-08 - URL: https://niteo.co/blog/plone4-collective-xdv-deco-gs/ - Categories: Tech - Tags: Plone Here at NiteoWeb Ltd. we decided a few days ago that we should start trying out Plone 4 in order to be ready for the stable release. There are quite some new features that I can't wait to start using on production sites. Being in adventurous mood I volunteered for the job. I also wanted to give collective. xdv a go. So the first step was to grab the Plone 4 development buildout and marry it with collective. xdv buildout for Plone 3. After some trial-and-error it started working. You basically just add collective. xdv to eggs section in buildout. cfg and that's it: eggs = Plone plone. reload collective. xdv Then I was off to code HTML template that I would use with xdv. After a few lines of CSS I remembered Limi's talk about deco. gs on the Plone Conference and still feeling adventurous I couldn't refuse the temptation to position elements in the HTML template with the Deco grid system. It didn't go as smoothly as with installing collective. xdv as there's some lack of documentation, but the general idea is simple enough that you can grasp it rather quickly. Having a proof-of-concept for all three components I also needed a real site to try it out. So I decided to update our old corporate website. After a rainy weekend it was ready to go live. As a beta :). Hence the warning: This site is using a bleeding-edge Plone version. Please bare with us if something... --- ---