diff --git a/Makefile b/Makefile index 56b8431..84e0d79 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ build: - pelican -s pelican.conf.py . + pelican -s pelican.conf.py content upload: build rsync -e "ssh -p 22" -P -rvz --delete output/* alexis@172.19.2.119:/home/www/notmyidea.org/blog diff --git a/content/dev/carto-forms-first-steps.rst b/content/dev/carto-forms-first-steps.rst new file mode 100644 index 0000000..c819540 --- /dev/null +++ b/content/dev/carto-forms-first-steps.rst @@ -0,0 +1,190 @@ +Carto Forms - First steps +######################### + +:status: draft + +For an introduction on carto forms, please see this blog post: +http://blog.notmyidea.org/carto-forms.html (and its variant in french if you +prefer: http://blog.notmyidea.org/carto-forms-fr.html) + +So, let's not talk too much about what we want to do, and rather explain how we +will do it instead ;) + +Writing this article turned out to dump my thinking while bootstraping the +project, so I'm really explaining how I'm getting from here to there ;) + +First step: defining a way to describe forms +============================================ + +What we want is a generic way to describe forms. I'm not sure if such a thing +exist. And, because I'm on a train atm, let's suppose there isn't anything like +this already (which is probably a wrong assumption, but, let's stick with that +for now). + +What do we want? A way to associate titles, descriptions to a field. We also +want to be able to describe what's *in* the field (the type of content), and if +it is a repeatable field or not. In the case of a selection, we might also want +to have a list of possibilities somewhere. Let's take a simple example: + +Title: Ads spots +Description: Describe all the ads spots in Paris +Fields: + +- location (geoloc/address/lat-long) +- size *the size of the ad* (choice list: small/medium/big/huge) +- light *is there light on it?* (boolean) + +Okay, so what we have here is in the form: name *description* (type of field). +In some way, we need to separate the widget that will be displayed to the user +from the type of data. What we need here is the type of data, the widget thing +should be decided at a different layer. So, let's refine the "location" field +to "location (SIG point)". + +Okay, we now know what we want to save. Yet, we need to define the format. +At this point, I'm wondering if I should use XML, YAML or JSON to describe this +data. To be able to choose, listing the potential consumers / providers of data +can help. The first consumer of this data will be a REST API, and the first +producer will be, probably javascript (or whatever techno is used on the +client). Of course, we can provide lots of format on the REST API and depend +on the "Content-Types" header to know how to talk to it, but well, do we really +want or need to do that? Let's assume no for now and stick with JSON, because +it's now easily validable and I can't think of a language without a lib for it +(apart COBOL, of course). + +Hey-hi, JSON. How does our data look with you? Let's dump a python structure +and dump it with `json.dumps`:: + + data = { + 'title': 'Ads spots', + 'description': 'All the ads spots in paris', + 'fields': ( + {'name': 'location', 'type': 'SIG point'}, + {'name': 'size', 'type': 'choice', 'description': 'the size of the ad', + 'choices': ('small', 'medium', 'big', 'huge')}, + {'name': 'light', 'desciption': 'is there light on it?', 'type': 'bool'}, + )} + import json + json.dumps(data) + +… and the result is (ran with `python data.py | python -m json.tool`) …:: + + { + "title": "Ads spots" + "description": "All the ads spots in paris", + "fields": [ + { + "name": "location", + "type": "SIG point" + }, + { + "choices": [ + "small", + "medium", + "big", + "huge" + ], + "description": "the size of the ad", + "name": "size", + "type": "choice" + }, + { + "desciption": "is there light on it?", + "name": "light", + "type": "bool" + } + ], + } + +Validating the form definition +============================== + +JSON is nice to us, JSON schema now exists and there are tools to work with it. +Quickly, it's the same kind of things than what's provided by XML Schema: you +create a schema, pass it some data and it's able to tell you if the data +complies with the schema. If not, it gives you a nice list of wrong fields. + +The second option, in python, is a tool named colander, which approximately +does the same thing, but with its own syntax. + +FIXME need to dig on json schema here and do an approx schema for this. + +Creating the forms +================== + +The next step is to actually create a form from this. Python, and django in +particular, have nice APIs to do that in python. However, I don't know how +they internally work, but you can pass to it some data provided by an HTTP POST +request and it will tell you if it validate or no. + +The problem with django is that you're tied to it, and it's not possible (well, +as far as I know) to get only the validation bits out of it. On the other hand, +the form framework already comes with nice geolocation facilities. It could be +nice to have a tool able to parse the format we defined and to generate django +models out of it. + +We need to be careful here: what I'm talking about is to generate code… Well, +there are two approches to do that: either we generate a python file and parse +it, or either we can read the json data and programatically create a form out +of it, at runtime. We might want to cache this at some point to avoid doing it +each time, but let's consider it's another problem we will tackle later. + +So, django internals! + +Let's loop on the fields provided by our format and generate the form. We will +care about how to store this / retrieve it later :) + +Oh, but wait. I'm talking about forms but I should be talking about models! +Validation is one thing, but what we want to do is to describe the data we will +be handling. Forms will just be the user facing thing and what will to the +validation! + +Django, no django? Let's think about this one more time. There is another +competitor on this field, because we are talking about storing information that +are changing all the time and to base validation on them: CouchDB! And there +also is GeoCouch, which brings interesting SIG features to Couch. And it's +talking JSON! + +Creating a new form should be as easy as this:: + + $ curl -X POST localhost:5984/cartoforms/ -d "`python test.py`" -H "Content-Type: application/json" + {"ok":true,"id":"2d58ef2b02eae639b3f94e357a000d26","rev":"1-0462d0827e7cdad20b5703a923249220"} + +Hmm, wait, this is cool but we got this hideous hash. Let's change this to a +PUT instead:: + + $ curl -X PUT localhost:5984/cartoforms/paris-ads -d "`python test.py`" -H "Content-Type: application/json" + {"ok":true,"id":"paris-ads","rev":"1-0462d0827e7cdad20b5703a923249220"} + +Of course, we can already retrieve this with a GET:: + + curl -X GET localhost:5984/cartoforms/paris-ads -d "`python test.py`" + {"_id":"paris-ads","_rev":"1-0462d0827e7cdad20b5703a923249220","fields":[{"type":"SIG + point","name":"location"},{"choices":["small","medium","big","huge"],"type":"choice","name":"size","description":"the + size of the ad"},{"type":"bool","desciption":"is there light on + it?","name":"light"}],"description":"All the ads spots in + paris","title":"Ads spots"} + +Validation? Yes, you're completely right: we need validation for this. Because +in this current state, anyone can just insert whatever data they want into this +system, which could become a problem at some point. + +Let's say we don't care who is able to publish to the DB, until we know that +what's being posted complies with a certain format. And, guess what's cool? +CouchDB provides validators. Yeah, I agree, it's somewhat exhausting to realize +that we have all this for free, but, heh, that's open source, dude! + +Adding validation! +================== + +So, we described our format already, what we need to do is to create a couchdb +validator which is able to filter this. + +Hmm, I don't remember how they are named (will find out in the couch +documentation), but if I remember correctly, you can hook up some javascript +functions to each POST / PUT, to check that the data inserted is correct, and +output appropriate error messages when it's not what you expected. + +Yeah, this means writing javascript, which is cool because I wanted to re-learn +how to do javascript! + +… train arrives to station, see you next :) diff --git a/content/dev/python-functools-aliases.rst b/content/dev/python-functools-aliases.rst new file mode 100644 index 0000000..c86fc2e --- /dev/null +++ b/content/dev/python-functools-aliases.rst @@ -0,0 +1,14 @@ +Python, functools and aliases +############################# + +:status: draft + +I have been playing lately with python and functools to make method aliases. I +wanted to have something like this. + +.. code-block:: python + + class Baby(object): + + def eat(self, thing): + self.intestine.digest(thing) diff --git a/images/concassage.jpg b/content/images/concassage.jpg similarity index 100% rename from images/concassage.jpg rename to content/images/concassage.jpg diff --git a/images/concasse.jpg b/content/images/concasse.jpg similarity index 100% rename from images/concasse.jpg rename to content/images/concasse.jpg diff --git a/content/images/daybed.jpg b/content/images/daybed.jpg new file mode 100644 index 0000000..b815e6c Binary files /dev/null and b/content/images/daybed.jpg differ diff --git a/images/filtrage.jpg b/content/images/filtrage.jpg similarity index 100% rename from images/filtrage.jpg rename to content/images/filtrage.jpg diff --git a/images/ihatemoney-fr.png b/content/images/ihatemoney-fr.png similarity index 100% rename from images/ihatemoney-fr.png rename to content/images/ihatemoney-fr.png diff --git a/images/ihatemoney.png b/content/images/ihatemoney.png similarity index 100% rename from images/ihatemoney.png rename to content/images/ihatemoney.png diff --git a/images/marmite.jpg b/content/images/marmite.jpg similarity index 100% rename from images/marmite.jpg rename to content/images/marmite.jpg diff --git a/images/refroidissement.jpg b/content/images/refroidissement.jpg similarity index 100% rename from images/refroidissement.jpg rename to content/images/refroidissement.jpg diff --git a/images/refroidisseur.jpg b/content/images/refroidisseur.jpg similarity index 100% rename from images/refroidisseur.jpg rename to content/images/refroidisseur.jpg diff --git a/images/supercuve.jpg b/content/images/supercuve.jpg similarity index 100% rename from images/supercuve.jpg rename to content/images/supercuve.jpg diff --git a/images/unison.png b/content/images/unison.png similarity index 100% rename from images/unison.png rename to content/images/unison.png diff --git a/content/mozilla/service-description.rst b/content/mozilla/service-description.rst new file mode 100644 index 0000000..2a20df3 --- /dev/null +++ b/content/mozilla/service-description.rst @@ -0,0 +1,58 @@ +API description using cornice and colander +########################################## + +:status: draft + +One of the goals we want to accomplish with Cornice is to describe the web +services in a nice and easy way, for the developer. This for different reasons. + +Having web services described in some ways allows you do do interesting things, +such as automatically generating a documentation, or a client, for instance. +REST services are supposed to be discoverable, but in a lot of situations, +that's not the case, and it can be a pain to implement a client for them, even +if most of what is being done there is shared between a lot of web services. + +In cornice, we alreadygenerate some documentation, but this one is incomplete in +different ways. For instance, it is currently not possible to get information +about the inputs you are waiting for, in the different locations (body, +headers and query string). + +For instance, if you want to describe that a *POST* on `/foobar` needs the +*foo* and *bar* parameters, and that you eventually could add a *baz* +parameter, you can't, or you have to describe it manually in the documentation +of the web service. + +Cornice, while not tied to `Colander`_, tries to make a good use of it when +possible. So it is possible to do validation of the incoming data (in different +locations) and, at the same time, documentation of the web service. + +To do so, you have to use a particular `schema` keyword in the decorator. Here +is an example of definition + +.. code-block:: python + + from cornice import Service + from colander import MappingSchema, SchemaNode, String + + foobar = Service(name="foobar", path="/foobar") + + + class Foobar(MappingSchema): + foo = SchemaNode(String(), location="body") + bar = SchemaNode(String(), location="headers") + baz = SchemaNode(String(), default=None) + + + @foobar.get(scheme=Foobar) + def foobar_get(request): + # do something here + +.. _Colander: http://docs.pylonsproject.org/projects/colander/en/latest/ + +The output documentation currently looks like this: + +.. image:: images/cornice-exampledoc-validation.png + +The plans for the future are to be able to put direct curl calls in the +documentation to demonstrate how the service behaves for instance, and why not +creating a tiny python client able to consume the cornice APIs. diff --git a/content/mozilla/token-server.rst b/content/mozilla/token-server.rst new file mode 100644 index 0000000..64df11b --- /dev/null +++ b/content/mozilla/token-server.rst @@ -0,0 +1,87 @@ +Mozilla - The sagrada token server +################################## + +:date: 19-03-2012 +:tags: sagrada, python, browserid +:status: draft + +Since I started, back in december, we started a new project on the services +team, which aims to bring a central authentication point on our server side. +This had been motivated by the fact that we are switching our services +authentication mechanism from basic HTTP auth to browserid (this was basically +for sync in the first place, and now for AITC, a.k.a Market Place APIs). + +- A Token Server ? +- Services architecture (server / nodes) +- MAC auth +- Crypto / Signing + - HKDF + - Signing the tokens + - Parsing browserid assertions +- Resources + +A token server ? +================ + +So, we don't want to be tied to any authentication mean on our platform. The +best way to accomplish this is to chose one and to provide a way to map all the +potential authentication means to the chosen one. + +In addition to trade a browserid assertion for another authentication token, +the mission of the token server is to retrieve the node allocation of a +particular user, and eventually assign it to a node. + +To resume, we take any authentication scheme (browserid for now) and +trade it for another one we can use for all of our services. This has several +advantages: + +* We don't need to check the browserid assertion at each request. This avoids + doing crypto at each request. +* As said, we are able to deal with different authentication schemes. If we + want to use openid, we just need to add support for it on one location +* The node allocation is done anyways (the user need to know wich node it is + assigned to) so it doesn't add an extra call for this. + +Our architecture +================ + +I'm talking about nodes, users and services. Let's clarifiy a bit all this. +Because at the services team, we mostly care about being able to scale our +infrastructures without (too much) pain, we try to avoid SPOFs (Single Point Of +Failure) of any sort. For this purpose we expose at the authentication layer +information about the node that need to be retrieved by the clients. + +What? clients? Okay, here is what the authentication looks like:: + + User-Agent Token Server Node + | | | + | | | + |----------------------->| | + | | | + | | | + |<-----------------------| | + | | | + | | + |----------------------------------------------->| + +In HTTP terms, looks like this, the user agent (client) gives a browserid +assertion and receives back information about the service it should deal with + +:: + + > HTTP POST http://token.services.mozilla.org/1.0// + > Data: # some authentication information (browserid assertion in our case) + < Header: 200 OK + < Data: "{'id': token, 'key': secret, 'uid': uid, 'api_endpoint': api_endpoint}" + +(This is an hand crafted request/response flow) + +We don't bother about the signing and crypto details in here as it is explained +in a later section, but basically, we asked for a node, with a specific +browserid assertions and now we have an *api_endpoint* to send our requests +against, along with the token. + +Crypto details +============== + +All the flow is explained in our documentation, for the token server diff --git a/content/mozilla/walint.rst b/content/mozilla/walint.rst new file mode 100644 index 0000000..19e973e --- /dev/null +++ b/content/mozilla/walint.rst @@ -0,0 +1,83 @@ +walint - tilt +############# + +:status: draft + +Things start to fold together. I still need some time to be up to +speed (new job / new city / new people), but the projects I'm working on are +pretty exciting and I like what I'm doing. We've been working with Tarek on a +tool about web services testing. + +At Mozilla, we produce and consume web services. As an organisation defending +web standards, providing services that match these specifications is the least +we can do. + +Web App Lint (WALint) is a simple tool to help you to test your web services +against the HTTP specification. The goal is to detect potential problems a +service could be subject to, and to provide a simple-to-configure tool to test +your WS against HTTP as speced. The long term goal is to be exhaustive on the +controllers we provide, but if you have special needs, you should be able to +define tests in a simple way. + +As everything we do at Mozilla, the tool is an opensource project. Our goal is +to have something useful for web service consumers and providers. If you think +you can be of any help, don't hesitate to drop me an email or fork on github. + +Testing the HTTP specification +============================== + +A lot of web services are written on top of HTTP. The protocol is fully +described in a specification and introduce some really interesting stuff we +should care about when implementing our services. This tool wants to check this +up and provide a ways to ensure that you are defining your web services the +right way. It's not a replacement for manual service testing, thus: you still +have to test that your web service is doing what you think it does. WALint is +checking the stuff we almost forgot all of the time. + +For instance, the HTTP specification specifies that if the client sends a +request with a Content-Type not handled by the server, it should answer with a +"406 Not Acceptable" and should return the list of accepted headers (so the +client is able to send again the request with the right accept header). We also +check that sending weird data (broken json objects or authentication headers) +does not break the tested service. + +Obviously, we don't have all the scenarios in mind, and they aren't all +implemented. That's where being an open source project makes sense. You, as +service providers and consumers, know what are the kind of mistake you are used +to do / to deal with. It should make "tilt": fork the project and write some +lines checking the particular behavior that's disturbing you, everyone will +enjoy it. If you prefer, just open a ticket and we'll care about the +implementation. + +The documentation defines a list of all the implemented controllers: +http://packages.python.org/walint/controllers.html + +What does it looks like? +======================== + +Here is an example of a configuration file: you describe the paths and +signatures of your web services, the controllers you want to use and the test +scenarios you want to run, that's it, just run "walint config.cfg" and you're +good. + +Here's a capture of the output of the command line invocation: you get all the +paths tested with the different listed methods, and if needed what's not +working. In the future, why not putting some documentation online with +information about how to fix common mistakes? + +We also provide a wizard so it's possible to describe your web service in a +simple and easy way. Just invoke it with "walint --create config.cfg". + +What's next ? +============= + +We plan to do some fun stuff with WALint. Here are some thoughts: + +* service discovery: just provide an API root URI and we'll try to discover + what's in there and how to generate configuration files + +* unittest integration, so it's possible to have an unified way to describe web + services with existing tools. (heh, we can do Web Services CI the easy way!) +* integration with cornice description language and other web services description + languages (still to be defined) +* your ideas, so please fill issues and provide us feedback, it's useful! diff --git a/content/mozilla/weekly-update.rst b/content/mozilla/weekly-update.rst new file mode 100644 index 0000000..b1f91ae --- /dev/null +++ b/content/mozilla/weekly-update.rst @@ -0,0 +1,84 @@ +Mozilla's weekly update #1 +########################## + +:date: 20-09-2012 +:status: draft + +My day-to-day work is changing a lot these days, as I'm working on different +tools and working across different teams. I thought it could be useful to have +a place to put updates weekly about what's going-on. This can be extra useful +for folks that are not on the same timezone I am (I'm looking at you, +California), so let's try this. + +I'm not used to post regularly, but I will try to update the blog with an entry +each week, if there is something interesting to say. + +Circus +====== + +As you may know, last week we had a sprint about Circus at PyconFR, we now have +a bunch of folks interested by the project now, and some activity on our irc +channel (#mozilla-circus on freenode). + +I've written `a more comprehensive wrap-up about this sprint +`_, so have a look at +it if you're interested! + +Vaurien +======= + +Vaurien is a TCP proxy which can be useful for our load-testing. its goal is to +sometimes let the traffic go trough, sometimes play a bit with it (add delays, +timeouts, close the socket etc) to check how the stack is behaving when under +pressure. + +The code isn't used to test our services yet but we have something interesting +to show: http://github.com/mozilla-services/vaurien/ + +I will not explain the specifics here, I've tried to make `the README +`_ explicit enough. + +Marteau +======= + +`Marteau `_ is the tool we're +using to throw load-test to our services, to check that they're able to handle +it. It's basically a frontend to Funkload. Tarek worked on adding real-time +feedback from the nodes (when in distributed mode, Funkload clients are +deployed on some nodes and send traffic to the service from there), and I am +working on making this available on the web interface. This means playing a bit +with web-sockets and javascript, yay. + +Marketplace packaging +===================== + +Currently, the application behind market place, `Zamboni +`_ uses a non-standard mechanism to deal +with its dependencies. A `vendor` folder contains the packages themselves, in +the form of git submodules. This comes with some drawbacks such as the fact +that it's not easy to upgrade dependencies etc, and very long updates of the +repository, into other things. + +We were also dependant on github to deploy Marketplace, which isn't reliable at +all, especially when you know that github was down last week, for instance. We +now have a local PyPI mirror at Mozilla, and we use it to avoid reaching the +internet for something else than our code. + +This also means that we need to pull all the dependencies out of this `vendor` +folder, and rely on PyPI packages when they are up to date. Then we will be +able to directly use `pip` to deal with dependency management and packaging. + +Splitting up the Marketplace +============================ + +Zamboni is currently one big django project. This led to something quite hard +to understand and hard to deal with., especially for newcomers. Also, it means +that all the aspects of the site are inter-connected and that you need to be +comfortable with the whole infrastructure of the project to add new features +/ fix bugs. + +Splitting this big project into smaller chunks can allow to have something +easier to work on. We're trying to do that these days. More on this later :) + +That's all for now, I'll try to keep you posted on all this, see you next week +:-) diff --git a/content/python/cheese-and-code-result.rst b/content/python/cheese-and-code-result.rst index 60c04e2..347697c 100644 --- a/content/python/cheese-and-code-result.rst +++ b/content/python/cheese-and-code-result.rst @@ -1,7 +1,6 @@ Cheese & code - Wrap-up ####################### -:status: draft :date: 2012-10-22 This week-end I hosted a *cheese & code* session in the country-side of Angers, diff --git a/content/thoughts/focus.rst b/content/thoughts/focus.rst new file mode 100644 index 0000000..8f25e19 --- /dev/null +++ b/content/thoughts/focus.rst @@ -0,0 +1,46 @@ +Focusing on what's important +############################ + +:date: 16-03-2012 +:tags: focus, time-management +:status: draft + +I do have a problem with information. + +Information overload. + +This thing that makes me check my emails, irc, twitter, my feed reader etc. +This thing that makes me feel uncomfortable at the end of the day, because I +feel that I missed something. That I missed some good time, away from news and +agitation. + +What do I need? I tried to change my tools, it helped a bit, Still, I'm not +focused like I would like to be. I've tried the pomodoro technique but… I'm not +yet convinced, mostly because this means me being interrupted every 20 minutes. + +Maybe that's just me who needs some more persuasion over myself, but the best +way I found to work is to unplug the cable. Literally. At work, I'm using a +RJ45 cable to connect to the internet. When I want to work on something, +I just unplug this cable. + +And that's amazing how you find yourself in the process to "check" +something on the web. Mails, irc… well, you got the idea. + +Of course, that web isn't filled only with lolcats and twitter messages +(even if I would **love** to see a pie chart with the repartition of lolcats +VS the rest of the web's content), so sometimes you need some precious bit of +information that's there. Fair enough. plug the cable, do what you **need** to +do, and unplug. Alexis, unplug! + +I'm feeling adventurous, so I'll try something new starting tomorrow, and I'll +report back in here my findings. Here's the challenge: + +* **Check emails only twice a day**. Do not do it in the morning, before + working, to keep my mind clear. I would say at 2pm (after lunch) and at 8pm. + (This doesn't mean I will not send mails tho) +* Stay away from the internet during the morning. I'll not connect if I don't + need to. + +I still need to find a way to be reachable during these off-line periods, +because that could be very painful for the folks on my team otherwise. (the +good thing is that my morning is their nights). diff --git a/light/static/css/main.css b/light/static/css/main.css deleted file mode 100644 index f7cadb9..0000000 --- a/light/static/css/main.css +++ /dev/null @@ -1,87 +0,0 @@ -@import url(http://fonts.googleapis.com/css?family=Rosario); -@import url("pygment.css"); -@import url("typogrify.css"); - -body { - width: 800px; - margin: auto; - font-size: 1.3em; - background-color: #fffff0; - font-family: "Georgia", serif; -} - -a{ - color: #000; -} - -nav ul { - list-style-type: none; -} - -nav ul li { - float: right; - margin-left: 10px; -} - -.content { - clear: both; -} - - .content h1, h2, h3, h4, h5, h6{ - font-family: 'Rosario', arial, serif; - margin-left: -20px; - } - - .content h1{ - font-size: 2.5em; - } - - .content p{ - font-size: 1.1em; - text-align: justify; - text-justify: newspaper; - } - - .content .date{ - font-style: italic; - font-size: 0.7em; - } - - .content h2{ - font-size: 1.5em; - } - - .content a{ - padding: 2px; - color: #0F0F0F; - } - - .content a:hover{ - background-color: #0F0F0F; - color: #eaeaea; - } - - .content .highlight pre{ - padding: 15px; - background-color: black; - color: white; - overflow: scroll; - - } - - .content blockquote { - margin: 0px; - margin-right: 40px; - margin-left: 20px; - padding-left: 20px; - text-align: left; - border-left: 3px black solid; - letter-spacing: 2px; - font-style: italic; - text-align: justify; - } - -.description { - margin-top: -15px; - font-style: italic; -} diff --git a/light/static/css/pygment.css b/light/static/css/pygment.css deleted file mode 100644 index 594b0fa..0000000 --- a/light/static/css/pygment.css +++ /dev/null @@ -1,205 +0,0 @@ -.hll { -background-color:#FFFFCC; -} -.c { -color:#408090; -font-style:italic; -} -.err { -border:1px solid #FF0000; -} -.k { -color:#007020; -font-weight:bold; -} -.o { -color:#666666; -} -.cm { -color:#408090; -font-style:italic; -} -.cp { -color:#007020; -} -.c1 { -color:#408090; -font-style:italic; -} -.cs { -background-color:#FFF0F0; -color:#408090; -} -.gd { -color:#A00000; -} -.ge { -font-style:italic; -} -.gr { -color:#FF0000; -} -.gh { -color:#000080; -font-weight:bold; -} -.gi { -color:#00A000; -} -.go { -color:#303030; -} -.gp { -color:#C65D09; -font-weight:bold; -} -.gs { -font-weight:bold; -} -.gu { -color:#800080; -font-weight:bold; -} -.gt { -color:#0040D0; -} -.kc { -color:#007020; -font-weight:bold; -} -.kd { -color:#007020; -font-weight:bold; -} -.kn { -color:#007020; -font-weight:bold; -} -.kp { -color:#007020; -} -.kr { -color:#007020; -font-weight:bold; -} -.kt { -color:#902000; -} -.m { -color:#208050; -} -.s { -color:#4070A0; -} -.na { -color:#4070A0; -} -.nb { -color:#007020; -} -.nc { -color:#0E84B5; -font-weight:bold; -} -.no { -color:#60ADD5; -} -.nd { -color:#555555; -font-weight:bold; -} -.ni { -color:#D55537; -font-weight:bold; -} -.ne { -color:#007020; -} -.nf { -color:#06287E; -} -.nl { -color:#002070; -font-weight:bold; -} -.nn { -color:#0E84B5; -font-weight:bold; -} -.nt { -color:#062873; -font-weight:bold; -} -.nv { -color:#BB60D5; -} -.ow { -color:#007020; -font-weight:bold; -} -.w { -color:#BBBBBB; -} -.mf { -color:#208050; -} -.mh { -color:#208050; -} -.mi { -color:#208050; -} -.mo { -color:#208050; -} -.sb { -color:#4070A0; -} -.sc { -color:#4070A0; -} -.sd { -color:#4070A0; -font-style:italic; -} -.s2 { -color:#4070A0; -} -.se { -color:#4070A0; -font-weight:bold; -} -.sh { -color:#4070A0; -} -.si { -color:#70A0D0; -font-style:italic; -} -.sx { -color:#C65D09; -} -.sr { -color:#235388; -} -.s1 { -color:#4070A0; -} -.ss { -color:#517918; -} -.bp { -color:#007020; -} -.vc { -color:#BB60D5; -} -.vg { -color:#BB60D5; -} -.vi { -color:#BB60D5; -} -.il { -color:#208050; -} diff --git a/light/static/css/typogrify.css b/light/static/css/typogrify.css deleted file mode 100644 index c9b34dc..0000000 --- a/light/static/css/typogrify.css +++ /dev/null @@ -1,3 +0,0 @@ -.caps {font-size:.92em;} -.amp {color:#666; font-size:1.05em;font-family:"Warnock Pro", "Goudy Old Style","Palatino","Book Antiqua",serif; font-style:italic;} -.dquo {margin-left:-.38em;} diff --git a/light/templates/article.html b/light/templates/article.html deleted file mode 100644 index 687a369..0000000 --- a/light/templates/article.html +++ /dev/null @@ -1,30 +0,0 @@ -{% extends "base.html" %} -{% block title %}{{ article.title }}{% endblock title %} -{% block content %} -

{{ article.title }}

-

{% if article.lang == "fr" %}Publié le{% else %}Published - on{% endif%} {{ article.locale_date }}. - {% if article.translations %} - {% if article.lang == "fr" %}Vous pouvez aussi lire cet article en {% else %}You can also read this article in {% endif %} - {% for tr in article.translations %} - {{ tr.lang }} - {% endfor %} - {% endif %} -

- {{ article.content }} - - {% if DISQUS_SITENAME %} -
-

Comments

-
- -
- {% endif %} -{% endblock %} diff --git a/light/templates/base.html b/light/templates/base.html deleted file mode 100644 index 1440ff0..0000000 --- a/light/templates/base.html +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - Alexis Métaireau - - -
{% block content %}{% endblock %}
- - diff --git a/light/templates/index.html b/light/templates/index.html deleted file mode 100644 index 574abd6..0000000 --- a/light/templates/index.html +++ /dev/null @@ -1,23 +0,0 @@ -{% extends "base.html" %} -{% block content %} - -

Hi and welcome in this web logs. I try here to talk about freedom, free - software, activism and education. And about anything I think would be - valuable to share.

- -

Bienvenue sur ces carnets. J'essaye de parler ici de liberté, - de logiciel libre d'activisme et d'éducation. Et finalement d'un peu tout - ce qui me passe par la tête et que j'ai envie de partager.

- - {% for article in articles %} -

{{ article.title }} ({{article.lang}}) - {% if article.translations %} - (also in {% for article in article.translations %}{{ article.lang }}{% endfor %}) - {% endif %} - {{ article.date.strftime('%B %Y')}} -

- {% if article.description %} -

{{ article.description }}

- {% endif %} - {% endfor %} -{% endblock %} diff --git a/theme/static/css/categories.css b/theme/static/css/categories.css index 2356f67..b2d0239 100644 --- a/theme/static/css/categories.css +++ b/theme/static/css/categories.css @@ -13,8 +13,8 @@ h1 { .hentry { border-left: 10px solid; - border-color: rgba(200, 200, 200, .2); - color: rgba(200, 200, 200, .1); + border-color: rgba(200, 200, 200, .4); + color: rgba(200, 200, 200, .3); padding: 40px; } @@ -32,15 +32,15 @@ article .category { } .dev, .python { - border-color: rgba(150, 200, 150, .2); - color: rgba(150, 200, 150, .1); + border-color: rgba(150, 200, 150, .4); + color: rgba(150, 200, 150, .3); } .asso { - border-color: rgba(200, 0, 0, .2); - color: rgba(200, 0, 0, .1); + border-color: rgba(200, 0, 0, .4); + color: rgba(200, 0, 0, .3); } .thoughts { - border-color: rgba(100, 0, 100, .2); - color: rgba(100, 0, 100, .1); + border-color: rgba(100, 0, 100, .4); + color: rgba(100, 0, 100, .3); } diff --git a/theme/static/css/main.css b/theme/static/css/main.css index 60b8c8b..3a31559 100644 --- a/theme/static/css/main.css +++ b/theme/static/css/main.css @@ -17,7 +17,7 @@ /***** Global *****/ /* Body */ body { - background: #F5F4EF; + background: url('../images/background.jpg') fixed; color: #000305; font-size: 87.5%; /* Base font size: 14px */ font-family: 'Trebuchet MS', Trebuchet, 'Lucida Sans Unicode', 'Lucida Grande', 'Lucida Sans', Arial, sans-serif; @@ -165,7 +165,6 @@ img.left, figure.left {float: right; margin: 0 0 2em 2em;} } #banner h1 a:hover, #banner h1 a:active { background: none; - color: #C74350; text-shadow: none; } diff --git a/theme/static/images/background.jpg b/theme/static/images/background.jpg new file mode 100644 index 0000000..c12723d Binary files /dev/null and b/theme/static/images/background.jpg differ