]> pere.pagekite.me Git - homepage.git/blobdiff - blog/index.rss
Generated.
[homepage.git] / blog / index.rss
index d870555ae34fa263384ffd00f67704ad8ab65f22..a327511f035618252aab46936a946329775f163f 100644 (file)
@@ -6,6 +6,162 @@
                 <link>http://people.skolelinux.org/pere/blog/</link>
                 <atom:link href="http://people.skolelinux.org/pere/blog/index.rss" rel="self" type="application/rss+xml" />
        
+       <item>
+               <title>Valutakrambod - A python and bitcoin love story</title>
+               <link>http://people.skolelinux.org/pere/blog/Valutakrambod___A_python_and_bitcoin_love_story.html</link>
+               <guid isPermaLink="true">http://people.skolelinux.org/pere/blog/Valutakrambod___A_python_and_bitcoin_love_story.html</guid>
+                <pubDate>Sat, 29 Sep 2018 22:20:00 +0200</pubDate>
+               <description>&lt;p&gt;It would come as no surprise to anyone that I am interested in
+bitcoins and virtual currencies.  I&#39;ve been keeping an eye on virtual
+currencies for many years, and it is part of the reason a few months
+ago, I started writing a python library for collecting currency
+exchange rates and trade on virtual currency exchanges.  I decided to
+name the end result valutakrambod, which perhaps can be translated to
+small currency shop.&lt;/p&gt;
+
+&lt;p&gt;The library uses the tornado python library to handle HTTP and
+websocket connections, and provide a asynchronous system for
+connecting to and tracking several services.  The code is available
+from
+&lt;a href=&quot;http://github.com/petterreinholdtsen/valutakrambod&quot;&gt;github&lt;/a&gt;.&lt;/p&gt;
+
+&lt;/p&gt;There are two example clients of the library.  One is very simple and
+list every updated buy/sell price received from the various services.
+This code is started by running bin/btc-rates and call the client code
+in valutakrambod/client.py.  The simple client look like this:&lt;/p&gt;
+
+&lt;p&gt;&lt;blockquote&gt;&lt;pre&gt;
+import functools
+import tornado.ioloop
+import valutakrambod
+class SimpleClient(object):
+    def __init__(self):
+        self.services = []
+        self.streams = []
+        pass
+    def newdata(self, service, pair, changed):
+        print(&quot;%-15s %s-%s: %8.3f %8.3f&quot; % (
+            service.servicename(),
+            pair[0],
+            pair[1],
+            service.rates[pair][&#39;ask&#39;],
+            service.rates[pair][&#39;bid&#39;])
+        )
+    async def refresh(self, service):
+        await service.fetchRates(service.wantedpairs)
+    def run(self):
+        self.ioloop = tornado.ioloop.IOLoop.current()
+        self.services = valutakrambod.service.knownServices()
+        for e in self.services:
+            service = e()
+            service.subscribe(self.newdata)
+            stream = service.websocket()
+            if stream:
+                self.streams.append(stream)
+            else:
+                # Fetch information from non-streaming services immediately
+                self.ioloop.call_later(len(self.services),
+                                       functools.partial(self.refresh, service))
+                # as well as regularly
+                service.periodicUpdate(60)
+        for stream in self.streams:
+            stream.connect()
+        try:
+            self.ioloop.start()
+        except KeyboardInterrupt:
+            print(&quot;Interrupted by keyboard, closing all connections.&quot;)
+            pass
+        for stream in self.streams:
+            stream.close()
+&lt;/pre&gt;&lt;/blockquote&gt;&lt;/p&gt;
+
+&lt;p&gt;The library client loop over all known &quot;public&quot; services,
+initialises it, subscribe to any updates from the service, check and
+activate websocket streaming if the service provide it, and if no
+streaming is supported, fetch information from the service and set up
+a periodic update every 60 seconds.  The output from this client can
+look like this:&lt;/p&gt;
+
+&lt;p&gt;&lt;blockquote&gt;&lt;pre&gt;
+Bl3p            BTC-EUR: 5687.110 5653.690
+Bl3p            BTC-EUR: 5687.110 5653.690
+Bl3p            BTC-EUR: 5687.110 5653.690
+Hitbtc          BTC-USD: 6594.560 6593.690
+Hitbtc          BTC-USD: 6594.560 6593.690
+Bl3p            BTC-EUR: 5687.110 5653.690
+Hitbtc          BTC-USD: 6594.570 6593.690
+Bitstamp        EUR-USD:    1.159    1.154
+Hitbtc          BTC-USD: 6594.570 6593.690
+Hitbtc          BTC-USD: 6594.580 6593.690
+Hitbtc          BTC-USD: 6594.580 6593.690
+Hitbtc          BTC-USD: 6594.580 6593.690
+Bl3p            BTC-EUR: 5687.110 5653.690
+Paymium         BTC-EUR: 5680.000 5620.240
+&lt;/pre&gt;&lt;/blockquote&gt;&lt;/p&gt;
+
+&lt;p&gt;The exchange order book is tracked in addition to the best buy/sell
+price, for those that need to know the details.&lt;/p&gt;
+
+&lt;p&gt;The other example client is focusing on providing a curses view
+with updated buy/sell prices as soon as they are received from the
+services.  This code is located in bin/btc-rates-curses and activated
+by using the &#39;-c&#39; argument.  Without the argument the &quot;curses&quot; output
+is printed without using curses, which is useful for debugging.  The
+curses view look like this:&lt;/p&gt;
+
+&lt;p&gt;&lt;blockquote&gt;&lt;pre&gt;
+           Name Pair   Bid         Ask         Spr    Ftcd    Age
+ BitcoinsNorway BTCEUR   5591.8400   5711.0800   2.1%   16    nan     60
+       Bitfinex BTCEUR   5671.0000   5671.2000   0.0%   16     22     59
+        Bitmynt BTCEUR   5580.8000   5807.5200   3.9%   16     41     60
+         Bitpay BTCEUR   5663.2700         nan   nan%   15    nan     60
+       Bitstamp BTCEUR   5664.8400   5676.5300   0.2%    0      1      1
+           Bl3p BTCEUR   5653.6900   5684.9400   0.5%    0    nan     19
+       Coinbase BTCEUR   5600.8200   5714.9000   2.0%   15    nan    nan
+         Kraken BTCEUR   5670.1000   5670.2000   0.0%   14     17     60
+        Paymium BTCEUR   5620.0600   5680.0000   1.1%    1   7515    nan
+ BitcoinsNorway BTCNOK  52898.9700  54034.6100   2.1%   16    nan     60
+        Bitmynt BTCNOK  52960.3200  54031.1900   2.0%   16     41     60
+         Bitpay BTCNOK  53477.7833         nan   nan%   16    nan     60
+       Coinbase BTCNOK  52990.3500  54063.0600   2.0%   15    nan    nan
+        MiraiEx BTCNOK  52856.5300  54100.6000   2.3%   16    nan    nan
+ BitcoinsNorway BTCUSD   6495.5300   6631.5400   2.1%   16    nan     60
+       Bitfinex BTCUSD   6590.6000   6590.7000   0.0%   16     23     57
+         Bitpay BTCUSD   6564.1300         nan   nan%   15    nan     60
+       Bitstamp BTCUSD   6561.1400   6565.6200   0.1%    0      2      1
+       Coinbase BTCUSD   6504.0600   6635.9700   2.0%   14    nan    117
+         Gemini BTCUSD   6567.1300   6573.0700   0.1%   16     89    nan
+         Hitbtc+BTCUSD   6592.6200   6594.2100   0.0%    0      0      0
+         Kraken BTCUSD   6565.2000   6570.9000   0.1%   15     17     58
+  Exchangerates EURNOK      9.4665      9.4665   0.0%   16 107789    nan
+     Norgesbank EURNOK      9.4665      9.4665   0.0%   16 107789    nan
+       Bitstamp EURUSD      1.1537      1.1593   0.5%    4      5      1
+  Exchangerates EURUSD      1.1576      1.1576   0.0%   16 107789    nan
+ BitcoinsNorway LTCEUR      1.0000     49.0000  98.0%   16    nan    nan
+ BitcoinsNorway LTCNOK    492.4800    503.7500   2.2%   16    nan     60
+ BitcoinsNorway LTCUSD      1.0221     49.0000  97.9%   15    nan    nan
+     Norgesbank USDNOK      8.1777      8.1777   0.0%   16 107789    nan
+&lt;/pre&gt;&lt;/blockquote&gt;&lt;/p&gt;
+
+&lt;p&gt;The code for this client is too complex for a simple blog post, so
+you will have to check out the git repository to figure out how it
+work.  What I can tell is how the three last numbers on each line
+should be interpreted.  The first is how many seconds ago information
+was received from the service.  The second is how long ago, according
+to the service, the provided information was updated.  The last is an
+estimate on how often the buy/sell values change.&lt;/p&gt;
+
+&lt;p&gt;If you find this library useful, or would like to improve it, I
+would love to hear from you.  Note that for some of the services I&#39;ve
+implemented a trading API.  It might be the topic of a future blog
+post.&lt;/p&gt;
+
+&lt;p&gt;As usual, if you use Bitcoin and want to show your support of my
+activities, please send Bitcoin donations to my address
+&lt;b&gt;&lt;a href=&quot;bitcoin:15oWEoG9dUPovwmUL9KWAnYRtNJEkP1u1b&quot;&gt;15oWEoG9dUPovwmUL9KWAnYRtNJEkP1u1b&lt;/a&gt;&lt;/b&gt;.&lt;/p&gt;
+</description>
+       </item>
+       
        <item>
                <title>VLC in Debian now can do bittorrent streaming</title>
                <link>http://people.skolelinux.org/pere/blog/VLC_in_Debian_now_can_do_bittorrent_streaming.html</link>
@@ -616,84 +772,6 @@ Package: printrun
 
 &lt;p&gt;PS: A new version of Cura was uploaded to Debian yesterday.&lt;/p&gt;
 
-&lt;p&gt;As usual, if you use Bitcoin and want to show your support of my
-activities, please send Bitcoin donations to my address
-&lt;b&gt;&lt;a href=&quot;bitcoin:15oWEoG9dUPovwmUL9KWAnYRtNJEkP1u1b&quot;&gt;15oWEoG9dUPovwmUL9KWAnYRtNJEkP1u1b&lt;/a&gt;&lt;/b&gt;.&lt;/p&gt;
-</description>
-       </item>
-       
-       <item>
-               <title>Debian APT upgrade without enough free space on the disk...</title>
-               <link>http://people.skolelinux.org/pere/blog/Debian_APT_upgrade_without_enough_free_space_on_the_disk___.html</link>
-               <guid isPermaLink="true">http://people.skolelinux.org/pere/blog/Debian_APT_upgrade_without_enough_free_space_on_the_disk___.html</guid>
-                <pubDate>Sun, 8 Jul 2018 12:10:00 +0200</pubDate>
-               <description>&lt;p&gt;Quite regularly, I let my Debian Sid/Unstable chroot stay untouch
-for a while, and when I need to update it there is not enough free
-space on the disk for apt to do a normal &#39;apt upgrade&#39;.  I normally
-would resolve the issue by doing &#39;apt install &amp;lt;somepackages&amp;gt;&#39; to
-upgrade only some of the packages in one batch, until the amount of
-packages to download fall below the amount of free space available.
-Today, I had about 500 packages to upgrade, and after a while I got
-tired of trying to install chunks of packages manually.  I concluded
-that I did not have the spare hours required to complete the task, and
-decided to see if I could automate it.  I came up with this small
-script which I call &#39;apt-in-chunks&#39;:&lt;/p&gt;
-
-&lt;p&gt;&lt;blockquote&gt;&lt;pre&gt;
-#!/bin/sh
-#
-# Upgrade packages when the disk is too full to upgrade every
-# upgradable package in one lump.  Fetching packages to upgrade using
-# apt, and then installing using dpkg, to avoid changing the package
-# flag for manual/automatic.
-
-set -e
-
-ignore() {
-    if [ &quot;$1&quot; ]; then
-       grep -v &quot;$1&quot;
-    else
-       cat
-    fi
-}
-
-for p in $(apt list --upgradable | ignore &quot;$@&quot; |cut -d/ -f1 | grep -v &#39;^Listing...&#39;); do
-    echo &quot;Upgrading $p&quot;
-    apt clean
-    apt install --download-only -y $p
-    for f in /var/cache/apt/archives/*.deb; do
-       if [ -e &quot;$f&quot; ]; then
-           dpkg -i /var/cache/apt/archives/*.deb
-           break
-       fi
-    done
-done
-&lt;/pre&gt;&lt;/blockquote&gt;&lt;/p&gt;
-
-&lt;p&gt;The script will extract the list of packages to upgrade, try to
-download the packages needed to upgrade one package, install the
-downloaded packages using dpkg.  The idea is to upgrade packages
-without changing the APT mark for the package (ie the one recording of
-the package was manually requested or pulled in as a dependency).  To
-use it, simply run it as root from the command line.  If it fail, try
-&#39;apt install -f&#39; to clean up the mess and run the script again.  This
-might happen if the new packages conflict with one of the old
-packages.  dpkg is unable to remove, while apt can do this.&lt;/p&gt;
-
-&lt;p&gt;It take one option, a package to ignore in the list of packages to
-upgrade.  The option to ignore a package is there to be able to skip
-the packages that are simply too large to unpack.  Today this was
-&#39;ghc&#39;, but I have run into other large packages causing similar
-problems earlier (like TeX).&lt;/p&gt;
-
-&lt;p&gt;Update 2018-07-08: Thanks to Paul Wise, I am aware of two
-alternative ways to handle this.  The &quot;unattended-upgrades
---minimal-upgrade-steps&quot; option will try to calculate upgrade sets for
-each package to upgrade, and then upgrade them in order, smallest set
-first.  It might be a better option than my above mentioned script.
-Also, &quot;aptutude upgrade&quot; can upgrade single packages, thus avoiding
-the need for using &quot;dpkg -i&quot; in the script above.&lt;/p&gt;
-
 &lt;p&gt;As usual, if you use Bitcoin and want to show your support of my
 activities, please send Bitcoin donations to my address
 &lt;b&gt;&lt;a href=&quot;bitcoin:15oWEoG9dUPovwmUL9KWAnYRtNJEkP1u1b&quot;&gt;15oWEoG9dUPovwmUL9KWAnYRtNJEkP1u1b&lt;/a&gt;&lt;/b&gt;.&lt;/p&gt;