Librarian on Android

Librarian is platform independent and runs in python. Python compillers exist for Android. Huzzah.

Qpython likes projects with a ‘main.py’. Therfore it wouldnt see the librarian folder as valid. I attempted to use the console to manually call setup.py, but it wanted flags and i didnt know them. Any assistance from python savvy people is welcome, as i am throwing in the towel for the time being.

1 Like

We’re currently working on getting Librarian up and running on Android. However, since there are no Android experts on the team, it would be a great contribution if you got it up and running and shared the findings with us. :smile:

If you look at the source code, you’ll see that there’s run.py in the root. It sets up a temporary directory where content is stored and runs Librarian. This script is meant to be used on your PC to start Librarian using a modified configuration file local.ini found in the root of the source directory. Now the location of the temporary directory is right within the source tree by default. If you could modify that (or tell me where you want it), and renamed the run.py to main.py, I imagine it might satisfy qpython.

1 Like

I found the file, renamed it, and qpython recognizes it as a project. From there it is quite simple, if you are awake enough to enter commands properly.

Epic success! Its nice that this is basic terminal stuff. Everything works except cherrypy. I can get it using pip but byte_compiling fails during easy_install.py. I will investigate a bit later.

Alright, with all the dependencies it gives a segmentation fault. I’m not sure what to do with it from here. This bit of code is from running from the source code.

app_24@android:/ $ python
Python 3.2.2 (default, Jun 23 2014, 00:13:13)
[GCC 4.8] on linux-armv7l
Type "help", "copyright", "credits" or "license" for more information.
>>>
app_24@android:/ $ cd data/data/
app_24@android:/data/data $ ls
opendir failed, Permission denied
255|app_24@android:/data/data $ cd../../
/system/bin/sh: cd../../: not found
127|app_24@android:/data/data $ cd ../../
app_24@android:/ $ cd sdcard/com.hipipal.qpyplus/
cache/     lib/       projects3/ scripts3/  snippets/
d sdcard/com.hipipal.qpyplus/projects3/                                                           <
WeatherNotify/      WeatherReport/      WebAppSample/       librarian-0.1b1/    public3.version
d sdcard/com.hipipal.qpyplus/projects3/                                                           <
WeatherNotify/      WeatherReport/      WebAppSample/       librarian-0.1b1/    public3.version
rd/com.hipipal.qpyplus/projects3/librarian-0.1b1/                                                 <
CHANGES             Vagrantfile         icons/              scripts/            tests/
COPYING             build/              librarian.egg-info/ scss/
MANIFEST.in         conf/               librarian/          setup.cmd
README.rst          dist/               main.py             setup.py
rd/com.hipipal.qpyplus/projects3/librarian-0.1b1/                                                 <
app_24@android:/sdcard/com.hipipal.qpyplus/projects3/librarian-0.1b1 $ python ./setup.py install
running install
running bdist_egg
running egg_info
writing requirements to librarian.egg-info/requires.txt
writing librarian.egg-info/PKG-INFO
writing top-level names to librarian.egg-info/top_level.txt
writing dependency_links to librarian.egg-info/dependency_links.txt
reading manifest file 'librarian.egg-info/SOURCES.txt'
reading manifest template 'MANIFEST.in'
writing manifest file 'librarian.egg-info/SOURCES.txt'
installing library code to build/bdist.linux-armv7l/egg
running install_lib
running build_py
warning: build_py: byte-compiling is disabled, skipping.

creating build/bdist.linux-armv7l/egg
creating build/bdist.linux-armv7l/egg/librarian
copying build/lib/librarian/app.py -> build/bdist.linux-armv7l/egg/librarian
copying build/lib/librarian/__init__.py -> build/bdist.linux-armv7l/egg/librarian
copying build/lib/librarian/exceptions.py -> build/bdist.linux-armv7l/egg/librarian
creating build/bdist.linux-armv7l/egg/librarian/lib
copying build/lib/librarian/lib/html.py -> build/bdist.linux-armv7l/egg/librarian/lib
copying build/lib/librarian/lib/__init__.py -> build/bdist.linux-armv7l/egg/librarian/lib
copying build/lib/librarian/lib/favorites.py -> build/bdist.linux-armv7l/egg/librarian/lib
copying build/lib/librarian/lib/flash.py -> build/bdist.linux-armv7l/egg/librarian/lib
copying build/lib/librarian/lib/pager.py -> build/bdist.linux-armv7l/egg/librarian/lib
copying build/lib/librarian/lib/csrf.py -> build/bdist.linux-armv7l/egg/librarian/lib
copying build/lib/librarian/lib/ajax.py -> build/bdist.linux-armv7l/egg/librarian/lib
copying build/lib/librarian/lib/archive.py -> build/bdist.linux-armv7l/egg/librarian/lib
copying build/lib/librarian/lib/http.py -> build/bdist.linux-armv7l/egg/librarian/lib
copying build/lib/librarian/lib/common.py -> build/bdist.linux-armv7l/egg/librarian/lib
copying build/lib/librarian/lib/meta.py -> build/bdist.linux-armv7l/egg/librarian/lib
copying build/lib/librarian/lib/lazy.py -> build/bdist.linux-armv7l/egg/librarian/lib
copying build/lib/librarian/lib/content_crypto.py -> build/bdist.linux-armv7l/egg/librarian/lib
copying build/lib/librarian/lib/apps.py -> build/bdist.linux-armv7l/egg/librarian/lib
copying build/lib/librarian/lib/downloads.py -> build/bdist.linux-armv7l/egg/librarian/lib
copying build/lib/librarian/lib/files.py -> build/bdist.linux-armv7l/egg/librarian/lib
copying build/lib/librarian/lib/send_file.py -> build/bdist.linux-armv7l/egg/librarian/lib
copying build/lib/librarian/lib/i18n.py -> build/bdist.linux-armv7l/egg/librarian/lib
copying build/lib/librarian/lib/squery.py -> build/bdist.linux-armv7l/egg/librarian/lib
creating build/bdist.linux-armv7l/egg/librarian/utils
copying build/lib/librarian/utils/helpers.py -> build/bdist.linux-armv7l/egg/librarian/utils
copying build/lib/librarian/utils/migrations.py -> build/bdist.linux-armv7l/egg/librarian/utils
copying build/lib/librarian/utils/__init__.py -> build/bdist.linux-armv7l/egg/librarian/utils
creating build/bdist.linux-armv7l/egg/librarian/routes
copying build/lib/librarian/routes/downloads.py -> build/bdist.linux-armv7l/egg/librarian/routes
copying build/lib/librarian/routes/dashboard.py -> build/bdist.linux-armv7l/egg/librarian/routes
copying build/lib/librarian/routes/__init__.py -> build/bdist.linux-armv7l/egg/librarian/routes
copying build/lib/librarian/routes/favorites.py -> build/bdist.linux-armv7l/egg/librarian/routes
copying build/lib/librarian/routes/content.py -> build/bdist.linux-armv7l/egg/librarian/routes
copying build/lib/librarian/routes/apps.py -> build/bdist.linux-armv7l/egg/librarian/routes
creating build/bdist.linux-armv7l/egg/librarian/static
creating build/bdist.linux-armv7l/egg/librarian/static/css
copying build/lib/librarian/static/css/content.css -> build/bdist.linux-armv7l/egg/librarian/static/css
copying build/lib/librarian/static/css/screen.css -> build/bdist.linux-armv7l/egg/librarian/static/css
copying build/lib/librarian/static/css/base.css -> build/bdist.linux-armv7l/egg/librarian/static/css
creating build/bdist.linux-armv7l/egg/librarian/static/img
copying build/lib/librarian/static/img/folder.png -> build/bdist.linux-armv7l/egg/librarian/static/img
copying build/lib/librarian/static/img/document.png -> build/bdist.linux-armv7l/egg/librarian/static/img
copying build/lib/librarian/static/img/apps.png -> build/bdist.linux-armv7l/egg/librarian/static/img
copying build/lib/librarian/static/img/camera.png -> build/bdist.linux-armv7l/egg/librarian/static/img
copying build/lib/librarian/static/img/antenna.png -> build/bdist.linux-armv7l/egg/librarian/static/img
copying build/lib/librarian/static/img/background.png -> build/bdist.linux-armv7l/egg/librarian/static/img
copying build/lib/librarian/static/img/folder_up.png -> build/bdist.linux-armv7l/egg/librarian/static/img
copying build/lib/librarian/static/img/fav.png -> build/bdist.linux-armv7l/egg/librarian/static/img
copying build/lib/librarian/static/img/antenna_yellow.png -> build/bdist.linux-armv7l/egg/librarian/static/img
copying build/lib/librarian/static/img/forward.png -> build/bdist.linux-armv7l/egg/librarian/static/img
copying build/lib/librarian/static/img/file.png -> build/bdist.linux-armv7l/egg/librarian/static/img
copying build/lib/librarian/static/img/files.png -> build/bdist.linux-armv7l/egg/librarian/static/img
copying build/lib/librarian/static/img/outernet_logo.png -> build/bdist.linux-armv7l/egg/librarian/static/img
copying build/lib/librarian/static/img/home.png -> build/bdist.linux-armv7l/egg/librarian/static/img
copying build/lib/librarian/static/img/back.png -> build/bdist.linux-armv7l/egg/librarian/static/img
copying build/lib/librarian/static/img/camera_small.png -> build/bdist.linux-armv7l/egg/librarian/static/img
creating build/bdist.linux-armv7l/egg/librarian/static/js
copying build/lib/librarian/static/js/content.js -> build/bdist.linux-armv7l/egg/librarian/static/js
copying build/lib/librarian/static/js/downloads.js -> build/bdist.linux-armv7l/egg/librarian/static/js
copying build/lib/librarian/static/js/jquery.js -> build/bdist.linux-armv7l/egg/librarian/static/js
copying build/lib/librarian/static/js/librarian.js -> build/bdist.linux-armv7l/egg/librarian/static/js
creating build/bdist.linux-armv7l/egg/librarian/migrations
copying build/lib/librarian/migrations/05_rename_is_core_to_archive.sql -> build/bdist.linux-armv7l/egg/librarian/migrations
copying build/lib/librarian/migrations/04_add_content_license_and_source_columns.sql -> build/bdist.linux-armv7l/egg/librarian/migrations
copying build/lib/librarian/migrations/03_make_md5_unique.sql -> build/bdist.linux-armv7l/egg/librarian/migrations
copying build/lib/librarian/migrations/02_add_favorites_and_viewcounts.sql -> build/bdist.linux-armv7l/egg/librarian/migrations
copying build/lib/librarian/migrations/01_add_zipballs_table.sql -> build/bdist.linux-armv7l/egg/librarian/migrations
copying build/lib/librarian/migrations/00_initial.sql -> build/bdist.linux-armv7l/egg/librarian/migrations
creating build/bdist.linux-armv7l/egg/librarian/keys
copying build/lib/librarian/keys/artexin.gpg -> build/bdist.linux-armv7l/egg/librarian/keys
copying build/lib/librarian/keys/artexin.gpg.txt -> build/bdist.linux-armv7l/egg/librarian/keys
creating build/bdist.linux-armv7l/egg/librarian/views
copying build/lib/librarian/views/downloads.tpl -> build/bdist.linux-armv7l/egg/librarian/views
copying build/lib/librarian/views/dashboard.tpl -> build/bdist.linux-armv7l/egg/librarian/views
copying build/lib/librarian/views/_badges.tpl -> build/bdist.linux-armv7l/egg/librarian/views
copying build/lib/librarian/views/exec_result.tpl -> build/bdist.linux-armv7l/egg/librarian/views
copying build/lib/librarian/views/cleanup.tpl -> build/bdist.linux-armv7l/egg/librarian/views
copying build/lib/librarian/views/_space_info.tpl -> build/bdist.linux-armv7l/egg/librarian/views
copying build/lib/librarian/views/favorites.tpl -> build/bdist.linux-armv7l/egg/librarian/views
copying build/lib/librarian/views/content_list.tpl -> build/bdist.linux-armv7l/egg/librarian/views
copying build/lib/librarian/views/base.tpl -> build/bdist.linux-armv7l/egg/librarian/views
copying build/lib/librarian/views/_simple_pager.tpl -> build/bdist.linux-armv7l/egg/librarian/views
copying build/lib/librarian/views/app_list.tpl -> build/bdist.linux-armv7l/egg/librarian/views
copying build/lib/librarian/views/file_list.tpl -> build/bdist.linux-armv7l/egg/librarian/views
creating build/bdist.linux-armv7l/egg/librarian/locales
creating build/bdist.linux-armv7l/egg/librarian/locales/zh
creating build/bdist.linux-armv7l/egg/librarian/locales/zh/LC_MESSAGES
copying build/lib/librarian/locales/zh/LC_MESSAGES/librarian.po -> build/bdist.linux-armv7l/egg/librarian/locales/zh/LC_MESSAGES
creating build/bdist.linux-armv7l/egg/librarian/locales/da
creating build/bdist.linux-armv7l/egg/librarian/locales/da/LC_MESSAGES
copying build/lib/librarian/locales/da/LC_MESSAGES/librarian.po -> build/bdist.linux-armv7l/egg/librarian/locales/da/LC_MESSAGES
creating build/bdist.linux-armv7l/egg/librarian/locales/tr
creating build/bdist.linux-armv7l/egg/librarian/locales/tr/LC_MESSAGES
copying build/lib/librarian/locales/tr/LC_MESSAGES/librarian.po -> build/bdist.linux-armv7l/egg/librarian/locales/tr/LC_MESSAGES
creating build/bdist.linux-armv7l/egg/librarian/locales/sr
creating build/bdist.linux-armv7l/egg/librarian/locales/sr/LC_MESSAGES
copying build/lib/librarian/locales/sr/LC_MESSAGES/librarian.po -> build/bdist.linux-armv7l/egg/librarian/locales/sr/LC_MESSAGES
creating build/bdist.linux-armv7l/egg/librarian/locales/jp
creating build/bdist.linux-armv7l/egg/librarian/locales/jp/LC_MESSAGES
copying build/lib/librarian/locales/jp/LC_MESSAGES/librarian.po -> build/bdist.linux-armv7l/egg/librarian/locales/jp/LC_MESSAGES
creating build/bdist.linux-armv7l/egg/librarian/locales/ar
creating build/bdist.linux-armv7l/egg/librarian/locales/ar/LC_MESSAGES
copying build/lib/librarian/locales/ar/LC_MESSAGES/librarian.po -> build/bdist.linux-armv7l/egg/librarian/locales/ar/LC_MESSAGES
creating build/bdist.linux-armv7l/egg/librarian/locales/de
creating build/bdist.linux-armv7l/egg/librarian/locales/de/LC_MESSAGES
copying build/lib/librarian/locales/de/LC_MESSAGES/librarian.po -> build/bdist.linux-armv7l/egg/librarian/locales/de/LC_MESSAGES
creating build/bdist.linux-armv7l/egg/librarian/locales/nb
creating build/bdist.linux-armv7l/egg/librarian/locales/nb/LC_MESSAGES
copying build/lib/librarian/locales/nb/LC_MESSAGES/librarian.po -> build/bdist.linux-armv7l/egg/librarian/locales/nb/LC_MESSAGES
creating build/bdist.linux-armv7l/egg/librarian/locales/ta
creating build/bdist.linux-armv7l/egg/librarian/locales/ta/LC_MESSAGES
copying build/lib/librarian/locales/ta/LC_MESSAGES/librarian.po -> build/bdist.linux-armv7l/egg/librarian/locales/ta/LC_MESSAGES
creating build/bdist.linux-armv7l/egg/librarian/locales/pt
creating build/bdist.linux-armv7l/egg/librarian/locales/pt/LC_MESSAGES
copying build/lib/librarian/locales/pt/LC_MESSAGES/librarian.po -> build/bdist.linux-armv7l/egg/librarian/locales/pt/LC_MESSAGES
creating build/bdist.linux-armv7l/egg/librarian/locales/sv
creating build/bdist.linux-armv7l/egg/librarian/locales/sv/LC_MESSAGES
copying build/lib/librarian/locales/sv/LC_MESSAGES/librarian.po -> build/bdist.linux-armv7l/egg/librarian/locales/sv/LC_MESSAGES
creating build/bdist.linux-armv7l/egg/librarian/locales/fr
creating build/bdist.linux-armv7l/egg/librarian/locales/fr/LC_MESSAGES
copying build/lib/librarian/locales/fr/LC_MESSAGES/librarian.po -> build/bdist.linux-armv7l/egg/librarian/locales/fr/LC_MESSAGES
creating build/bdist.linux-armv7l/egg/librarian/locales/en
creating build/bdist.linux-armv7l/egg/librarian/locales/en/LC_MESSAGES
copying build/lib/librarian/locales/en/LC_MESSAGES/librarian.po -> build/bdist.linux-armv7l/egg/librarian/locales/en/LC_MESSAGES
creating build/bdist.linux-armv7l/egg/librarian/locales/ru
creating build/bdist.linux-armv7l/egg/librarian/locales/ru/LC_MESSAGES
copying build/lib/librarian/locales/ru/LC_MESSAGES/librarian.po -> build/bdist.linux-armv7l/egg/librarian/locales/ru/LC_MESSAGES
creating build/bdist.linux-armv7l/egg/librarian/locales/es
creating build/bdist.linux-armv7l/egg/librarian/locales/es/LC_MESSAGES
copying build/lib/librarian/locales/es/LC_MESSAGES/librarian.po -> build/bdist.linux-armv7l/egg/librarian/locales/es/LC_MESSAGES
copying build/lib/librarian/librarian.ini -> build/bdist.linux-armv7l/egg/librarian
warning: install_lib: byte-compiling is disabled, skipping.

creating build/bdist.linux-armv7l/egg/EGG-INFO
copying librarian.egg-info/PKG-INFO -> build/bdist.linux-armv7l/egg/EGG-INFO
copying librarian.egg-info/SOURCES.txt -> build/bdist.linux-armv7l/egg/EGG-INFO
copying librarian.egg-info/dependency_links.txt -> build/bdist.linux-armv7l/egg/EGG-INFO
copying librarian.egg-info/requires.txt -> build/bdist.linux-armv7l/egg/EGG-INFO
copying librarian.egg-info/top_level.txt -> build/bdist.linux-armv7l/egg/EGG-INFO
zip_safe flag not set; analyzing archive contents...
creating 'dist/librarian-0.1b1-py3.2.egg' and adding 'build/bdist.linux-armv7l/egg' to it
removing 'build/bdist.linux-armv7l/egg' (and everything under it)
Creating /data/data/com.hipipal.qpy3/files/lib/python3.2/site-packages/site.py
warning: easy_install: byte-compiling is disabled, skipping.

Processing librarian-0.1b1-py3.2.egg
Removing /data/data/com.hipipal.qpy3/files/lib/python3.2/site-packages/librarian-0.1b1-py3.2.egg
Copying librarian-0.1b1-py3.2.egg to /data/data/com.hipipal.qpy3/files/lib/python3.2/site-packages
librarian 0.1b1 is already the active version in easy-install.pth

Installed /data/data/com.hipipal.qpy3/files/lib/python3.2/site-packages/librarian-0.1b1-py3.2.egg
Processing dependencies for librarian==0.1b1
Searching for python-dateutil==2.2
Best match: python-dateutil 2.2
Processing python_dateutil-2.2-py3.2.egg
python-dateutil 2.2 is already the active version in easy-install.pth

Using /data/data/com.hipipal.qpy3/files/lib/python3.2/site-packages/python_dateutil-2.2-py3.2.egg
Searching for python-gnupg==0.3.6
Best match: python-gnupg 0.3.6
Processing python_gnupg-0.3.6-py3.2.egg
python-gnupg 0.3.6 is already the active version in easy-install.pth

Using /data/data/com.hipipal.qpy3/files/lib/python3.2/site-packages/python_gnupg-0.3.6-py3.2.egg
Searching for CherryPy==3.3.0
Best match: CherryPy 3.3.0
Processing CherryPy-3.3.0-py3.2.egg
CherryPy 3.3.0 is already the active version in easy-install.pth
Installing cherryd script to /data/data/com.hipipal.qpy3/files/bin

Using /data/data/com.hipipal.qpy3/files/lib/python3.2/site-packages/CherryPy-3.3.0-py3.2.egg
Searching for Werkzeug==0.9.6
Best match: Werkzeug 0.9.6
Processing Werkzeug-0.9.6-py3.2.egg
Werkzeug 0.9.6 is already the active version in easy-install.pth

Using /data/data/com.hipipal.qpy3/files/lib/python3.2/site-packages/Werkzeug-0.9.6-py3.2.egg
Searching for bottle==0.12.7
Best match: bottle 0.12.7
Processing bottle-0.12.7-py3.2.egg
bottle 0.12.7 is already the active version in easy-install.pth
Installing bottle.py script to /data/data/com.hipipal.qpy3/files/bin

Using /data/data/com.hipipal.qpy3/files/lib/python3.2/site-packages/bottle-0.12.7-py3.2.egg
Searching for six==1.8.0
Best match: six 1.8.0
Processing six-1.8.0-py3.2.egg
six 1.8.0 is already the active version in easy-install.pth

Using /data/data/com.hipipal.qpy3/files/lib/python3.2/site-packages/six-1.8.0-py3.2.egg
Finished processing dependencies for librarian==0.1b1
Segmentation fault
139|app_24@android:/sdcard/com.hipipal.qpyplus/projects3/librarian-0.1b1 $

Since I currently do android app development, I can help with a few things. What specific troubles are there at the moment?

Well, what ive done is installed cherrypy 3.3 from source in qpython3, then installed librarian, except it segmentation faults after the dependency check. Not sure if it managed to install somewhere or something, but I doubt it.

Ben, maybe you should create a fork of the main repo and host it on GitHub?

I can do that. What do you think should go in there? I haven’t modified the source of anything.

This is a link to cherrypy 3.3

And this goes to qpython3

Quick question, does this web site essentially say to run this run.py I would need to be calling some functions from kivy? This would theoretically be done by simply making another file that loads kivy then runs run.py.

I have just started learning python as of yesterday.

I’ve already tried Kivy. My advice is to first try building their example app and deploying on Android. If that fails, it would be very difficult to get it running with Librarian (that’s where I got stuck anyway).

As for the repo, my suggestion is to never bundle dependencies in the repo. I usually put dependencies (if they need to be in the source tree) in a separate folder and use .gitignore to prevent that folder from being committed along with other code. Then I create a requirements.txt file which lists necessary dependencies and (optionally) write a build script that collects dependencies and performs the build in a way that other developers can replicate, or at least document it somewhere. You’ll find the requirements.txt file in conf directory.

Most developers prefer to keep requirements.txt in the root of the source tree, but I keep my configuration files in the conf directory except when I do something stupid like keeping local.ini outside it. :stuck_out_tongue:

The end result of the forked repo should be all the code, configuration files, and scripts necessary to perform Android build, I guess.

Btw, requirements file is a Python standard for listing deps. You can read more about the format here. It’s used with Python’s official-unofficial package manager called pip. I also recommend you take a look at virtualenvwrapper which will handle creation of virtual development environments (basically isolated version of python interpreter and libraries specific to your project).

1 Like

Understood. I will file that under ‘todo’ after I get librarian to load up a bit. Currently it gets mad at my locale I believe. Pardon the screencapture but copy and paste is surprisingly annoying.

Librarian will look for translations in librarian/lcoales/$lang/LC_MESSAGES (it’ll look for librarian.mo at that location). The message you see is usually the result of locale files not being there.

EDIT:

Ah, ok. I see now why it does that. The compiled message were not committed to the repository. I should have mentioned that in the docs. You’d ned to install GNU gettext, and then you need to run:

python scripts/cmpmsgs.py librarian

in the source directory.

Alright! Here Here is my Official Guide for installing Librarian on Android.
First, download and install [QPython3][1]

Then [download][2] and install Pips 3.3, the version is relevant.
Extract it to a directory and run

python pip/setup.py install

Install the dependencies via pips:

pip install bottle werkzeug python-gnupg python-dateutil

Then [download][3] and install cherrypy from source/.
Extract it to a directory and run

python cherrypy/setup.py install

Download librarian-android from somewhere tbd (In the meantime pm me for it) and extract it into

sdcard/com.hipipal.qpyplus

Librarian files can be downloaded from [here.][4]

The next step is building a script to check for updates to the repo and download them.
[1]: https://play.google.com/store/apps/details?id=com.hipipal.qpy3
[2]: GitHub - pypa/pip at 1.4.1
[3]: CherryPy · PyPI
[4]: http://archive.outernet.is/

2 Likes

This is really exciting stuff. A lot of progress being made here. Outernet on Android will be huge.

Thanks! Im really excited and have been pushing hard. I have one error left which should be taken care of today. In case of the ability to help, here is the issue:

When running

import urllib
prefix = 'http://archive.outernet.is/'
with open("!file_list.txt", 'r') as f:
    stock = f.read().splitlines()
    for l in stock:
        content = ("%s%s") % (prefix, l)
        print(content)
        print(urllib.urlretrieve(content, l))

I get

I think it’s just a matter of stripping the trailing newline. I’ve added a few more changes but it’s mostly a matter of taste.

from urllib.request import urlretrieve
prefix = 'http://archive.outernet.is/'
with open("!file_list.txt", 'r') as f:
    for l in f:  # <-- you can iterate the file handle line by line
        content_url = ("%s%s") % (prefix, l.strip())  # <-- remove trailing \n
        print(content_url)
        urlretrieve(content_url, l)  # <-- The content is now in memory

I have recieved this advice a few times (maybe should have mentiomed that) and i cant get it to run on qpython. It essentially ignores the strip, or an attempt at replacing it. I copied your code and still get the error.

I’ll install QPython later and try it. Meanwhile, could you try just doing the strip? Like 'abc '.strip() should result in 'abc'.

Currently it works! You can download all the zips and run the server, but the server doesn’t seem to work once youve gotten all the files… Uploading a copy shortly.

Edit: Its here!

Server running on my phone. Error when loading the dashboard. Other pages work. Not sure how to add content.

Error: 500 Internal Server Error

Sorry, the requested URL 'http://127.0.0.1:8080/dashboard/' caused an error:

Internal Server Error
Exception:

AttributeError("'module' object has no attribute 'statvfs'",)
Traceback:

Traceback (most recent call last):
  File "/data/data/com.hipipal.qpy3/files/lib/python3.2/site-packages/bottle.py", line 862, in _handle
    return route.call(**args)
  File "/data/data/com.hipipal.qpy3/files/lib/python3.2/site-packages/bottle.py", line 1729, in wrapper
    rv = callback(*a, **ka)
  File "/storage/sdcard0/com.hipipal.qpyplus/projects3/librarian-android/librarian/lib/squery.py", line 107, in plugin
    body = callback(*args, **kwargs)
  File "/storage/sdcard0/com.hipipal.qpyplus/projects3/librarian-android/librarian/lib/i18n.py", line 401, in wrapper
    return callback(*args, **kwargs)
  File "/data/data/com.hipipal.qpy3/files/lib/python3.2/site-packages/bottle.py", line 3612, in wrapper
    result = func(*args, **kwargs)
  File "/storage/sdcard0/com.hipipal.qpyplus/projects3/librarian-android/librarian/routes/dashboard.py", line 35, in dashboard
    spool, content, total = archive.free_space()
  File "/storage/sdcard0/com.hipipal.qpyplus/projects3/librarian-android/librarian/lib/archive.py", line 336, in free_space
    sdev, sfree, stot = path_space(sdir)
  File "/storage/sdcard0/com.hipipal.qpyplus/projects3/librarian-android/librarian/lib/archive.py", line 318, in path_space
    stat = os.statvfs(path)
AttributeError: 'module' object has no attribute 'statvfs'