Android SWORD deposit mobile app

As part of the Open Repositories 2011 Developers Challenge, our team submitted a few different prototypes that formed our vision of ‘The Future of Repositories’.  Our whole entry centered around the theme of ‘Raas’, or ‘Repository as a Service’.  The notion of RaaS included the ability for the Repository become a commodity which could be switched in and out of our infrastructure.  In order for this to happen we required interoperability at multiple levels – we demonstrated two: ingest (using SWORD) and discovery (using Solr).

One of the prototypes was a new deposit application using SWORD.  It was written for the Android mobile operating system, and was designed to deposit photographs into repositories.  The use case for this is for social scientists who want to capture photographs straight into trusted storage – a repository.  One of the benefits of taking photographs with mobile phones is that they are usually now geo-tagged using the in-built GPS functionality to stamp the photo with the location where it was taken.  Of course the modern smartphone is a great data collection device, and could be used to capture many different kids of data, ready for deposit.  The notion of ‘citizen science‘ could come in to play here with a large set of distributed data collection devices in the pockets of millions of cell phone users.

Android has a nice ‘Share’ system, where applications are able to share files with one another.  If you take a photo or look at one in the photo gallery application, you should be able to find the ‘Share’ option.  From here you can share the photo with applications that know how to consume photos, such as posting to Facebook, sending as email attachements, or adding to tweets on Twitter.  Using our new application called ‘SWORD Share’, you can now deposit the photos into a repository!

If you have an Android phone, launch the marketplace application, and search for ‘sword share’.  Alternatively visit https://market.android.com/details?id=org.skylightui.swordshare&feature=search_result or scan the QR code.

When you launch the application you’ll be prompted to enter your SWORD server details: Author name, username, password, and the deposit URL.  If you don’t have easy access to a repository, you could try depositing to the DSpace Demo Server.  Use the following details: Name: Your name, Username: dspacedemo+admin@gmail.com, Password: dspace, Deposit URL: http://demo.dspace.org/sword/deposit/10673/39403

You will then be able to ‘share’ a photo you have taken, and a username and password, and deposit it to the repository.  Once the deposit has finished, you’ll be given the URL of the deposited item.  Just one thing to note if you use the demo.dspace.org system: It looks like the handle server isn’t currently running on that server, therefore if you receive a URL back such as http://hdl.handle.net/10673/{12345}, to see your item, instead visit http://demo.dspace.org/jspui/handle/10673/{12345}.

I’d be interested to hear about your ideas for the application, and if it worked OK for you!

Of course the code is open source, and housed in github.авито москва объявления

SWORD PHP Library – version 1.0 finally released!

After over 2.5 years of development and refinement, I have finally released version 1.0 of the SWORD PHP library! The library has been relatively stable for quite some time now, and is firmly embedded in tools such as EasyDeposit and OJS.

The other reason that I wanted to get it released (after many earlier 0.x version releases) is that the SWORD v2 development work is now starting, and therefore my attention needs to focus on that for a while.  There is now a github repository to host that:

I owe a big thank you to all the people who have contributed or used the library over the years, because of the feedback and patches, the code is now stable and works well.объявление в интернете

EasyDeposit now supports Shibboleth

Just a quick note to say that the latest release of EasyDeposit now supports Shibboleth authentication. Or to be precise, it supports any form of authentication where the user’s details are passed via HTTP headers / environment variables. This includes other SSO (Single Sign-On) systems such as CoSign.

To use, select the ‘ssologin’ step as the first step.  Edit the settings to state which headers to look at, and it should all work.  Of course you’ll need to configure your web server and single sign-on system to protect your EasyDeposit installation directory.

odno-lom

Display a stack trace in the android debugger

I’ve found that when developing an application for android, it is not obvious how to display a stack trace in the debugger in order to assist with finding the cause of a problem. If you don’t catch the exception, the stack trace will display OK. However often you want to catch the exception, but when debugging you want to find out what caused it by logging it to the debugger.

In normal java, you might use e.printStackTrace, but this won’t work without the use of log redirecting in the adb as it is normally sent to /dev/null

I’ve written a small utility class to do this:

[code lang=”java”]
package com.example;

import android.util.Log;

/**
* A class to display a traditional Java stack trace in the android debugger
*
* @author Stuart Lewis (stuart@stuartlewis.com)
*/
public class StackTraceLogger {

/**
* Display a stack trace
*
* @param e The Exception
* @param tag The tag to use in the debugger
*/
public static void getStackTraceString(Exception e, String tag) {
Log.e(tag, e.toString());
for (StackTraceElement ste : e.getStackTrace()) {
Log.e(tag, ste.toString());
}
}
}
[/code]

To make use of this, in your catch use:

StackTraceLogger.getStackTraceString(e, TAG);

(where ‘e’ is the Exception, and TAG is your logging TAG). I hope this is useful.mobile java games

Scrolling Text with an Arduino and Nokia 5110 screen

A while ago I purchased a nice little Nokia 5110 screen from MindKits.co.nz (or Sparkfun). It comes complete with a little PCB and a built-in PCD8544 controller.  It took  me a while looking at some different demos on the web to get it working – but once you’ve got it worked out, it is very easy.

It has 8 pins, connect these as follows (or adjust the code below for the correct arduino pins):

  1. VCC (3v arduino output)
  2. GND – Not needed, but if you do some sites say to connect via a small capacitor
  3. SCE – Pin 7
  4. RST – Pin 6
  5. D/C – Pin 5
  6. DN – Pin 4
  7. SCLK – Pin 3
  8. LED (backlight) – No needed, but if you do, remember to use a current limiting resistor!

I took one of the example pieces of code, and improved it with a scroll routine.  Call the ‘scroll(“Message”)’ function in the main loop, and each time the loop repeats, it will scroll the message on one more character, and when needed, it starts looping again.

Here is a video of it working, and below that is the code:

[code]
/*
Scrolling text example code
Modified from: http://www.arduino.cc/playground/Code/PCD8544
*/

// The pins to use on the arduino
#define PIN_SCE 7
#define PIN_RESET 6
#define PIN_DC 5
#define PIN_SDIN 4
#define PIN_SCLK 3

// COnfiguration for the LCD
#define LCD_C LOW
#define LCD_D HIGH
#define LCD_CMD 0

// Size of the LCD
#define LCD_X 84
#define LCD_Y 48

int scrollPosition = -10;

static const byte ASCII[][5] =
{
{0x00, 0x00, 0x00, 0x00, 0x00} // 20
,{0x00, 0x00, 0x5f, 0x00, 0x00} // 21 !
,{0x00, 0x07, 0x00, 0x07, 0x00} // 22 "
,{0x14, 0x7f, 0x14, 0x7f, 0x14} // 23 #
,{0x24, 0x2a, 0x7f, 0x2a, 0x12} // 24 $
,{0x23, 0x13, 0x08, 0x64, 0x62} // 25 %
,{0x36, 0x49, 0x55, 0x22, 0x50} // 26 &
,{0x00, 0x05, 0x03, 0x00, 0x00} // 27 ‘
,{0x00, 0x1c, 0x22, 0x41, 0x00} // 28 (
,{0x00, 0x41, 0x22, 0x1c, 0x00} // 29 )
,{0x14, 0x08, 0x3e, 0x08, 0x14} // 2a *
,{0x08, 0x08, 0x3e, 0x08, 0x08} // 2b +
,{0x00, 0x50, 0x30, 0x00, 0x00} // 2c ,
,{0x08, 0x08, 0x08, 0x08, 0x08} // 2d –
,{0x00, 0x60, 0x60, 0x00, 0x00} // 2e .
,{0x20, 0x10, 0x08, 0x04, 0x02} // 2f /
,{0x3e, 0x51, 0x49, 0x45, 0x3e} // 30 0
,{0x00, 0x42, 0x7f, 0x40, 0x00} // 31 1
,{0x42, 0x61, 0x51, 0x49, 0x46} // 32 2
,{0x21, 0x41, 0x45, 0x4b, 0x31} // 33 3
,{0x18, 0x14, 0x12, 0x7f, 0x10} // 34 4
,{0x27, 0x45, 0x45, 0x45, 0x39} // 35 5
,{0x3c, 0x4a, 0x49, 0x49, 0x30} // 36 6
,{0x01, 0x71, 0x09, 0x05, 0x03} // 37 7
,{0x36, 0x49, 0x49, 0x49, 0x36} // 38 8
,{0x06, 0x49, 0x49, 0x29, 0x1e} // 39 9
,{0x00, 0x36, 0x36, 0x00, 0x00} // 3a :
,{0x00, 0x56, 0x36, 0x00, 0x00} // 3b ;
,{0x08, 0x14, 0x22, 0x41, 0x00} // 3c <
,{0x14, 0x14, 0x14, 0x14, 0x14} // 3d =
,{0x00, 0x41, 0x22, 0x14, 0x08} // 3e >
,{0x02, 0x01, 0x51, 0x09, 0x06} // 3f ?
,{0x32, 0x49, 0x79, 0x41, 0x3e} // 40 @
,{0x7e, 0x11, 0x11, 0x11, 0x7e} // 41 A
,{0x7f, 0x49, 0x49, 0x49, 0x36} // 42 B
,{0x3e, 0x41, 0x41, 0x41, 0x22} // 43 C
,{0x7f, 0x41, 0x41, 0x22, 0x1c} // 44 D
,{0x7f, 0x49, 0x49, 0x49, 0x41} // 45 E
,{0x7f, 0x09, 0x09, 0x09, 0x01} // 46 F
,{0x3e, 0x41, 0x49, 0x49, 0x7a} // 47 G
,{0x7f, 0x08, 0x08, 0x08, 0x7f} // 48 H
,{0x00, 0x41, 0x7f, 0x41, 0x00} // 49 I
,{0x20, 0x40, 0x41, 0x3f, 0x01} // 4a J
,{0x7f, 0x08, 0x14, 0x22, 0x41} // 4b K
,{0x7f, 0x40, 0x40, 0x40, 0x40} // 4c L
,{0x7f, 0x02, 0x0c, 0x02, 0x7f} // 4d M
,{0x7f, 0x04, 0x08, 0x10, 0x7f} // 4e N
,{0x3e, 0x41, 0x41, 0x41, 0x3e} // 4f O
,{0x7f, 0x09, 0x09, 0x09, 0x06} // 50 P
,{0x3e, 0x41, 0x51, 0x21, 0x5e} // 51 Q
,{0x7f, 0x09, 0x19, 0x29, 0x46} // 52 R
,{0x46, 0x49, 0x49, 0x49, 0x31} // 53 S
,{0x01, 0x01, 0x7f, 0x01, 0x01} // 54 T
,{0x3f, 0x40, 0x40, 0x40, 0x3f} // 55 U
,{0x1f, 0x20, 0x40, 0x20, 0x1f} // 56 V
,{0x3f, 0x40, 0x38, 0x40, 0x3f} // 57 W
,{0x63, 0x14, 0x08, 0x14, 0x63} // 58 X
,{0x07, 0x08, 0x70, 0x08, 0x07} // 59 Y
,{0x61, 0x51, 0x49, 0x45, 0x43} // 5a Z
,{0x00, 0x7f, 0x41, 0x41, 0x00} // 5b [
,{0x02, 0x04, 0x08, 0x10, 0x20} // 5c ¥
,{0x00, 0x41, 0x41, 0x7f, 0x00} // 5d ]
,{0x04, 0x02, 0x01, 0x02, 0x04} // 5e ^
,{0x40, 0x40, 0x40, 0x40, 0x40} // 5f _
,{0x00, 0x01, 0x02, 0x04, 0x00} // 60 `
,{0x20, 0x54, 0x54, 0x54, 0x78} // 61 a
,{0x7f, 0x48, 0x44, 0x44, 0x38} // 62 b
,{0x38, 0x44, 0x44, 0x44, 0x20} // 63 c
,{0x38, 0x44, 0x44, 0x48, 0x7f} // 64 d
,{0x38, 0x54, 0x54, 0x54, 0x18} // 65 e
,{0x08, 0x7e, 0x09, 0x01, 0x02} // 66 f
,{0x0c, 0x52, 0x52, 0x52, 0x3e} // 67 g
,{0x7f, 0x08, 0x04, 0x04, 0x78} // 68 h
,{0x00, 0x44, 0x7d, 0x40, 0x00} // 69 i
,{0x20, 0x40, 0x44, 0x3d, 0x00} // 6a j
,{0x7f, 0x10, 0x28, 0x44, 0x00} // 6b k
,{0x00, 0x41, 0x7f, 0x40, 0x00} // 6c l
,{0x7c, 0x04, 0x18, 0x04, 0x78} // 6d m
,{0x7c, 0x08, 0x04, 0x04, 0x78} // 6e n
,{0x38, 0x44, 0x44, 0x44, 0x38} // 6f o
,{0x7c, 0x14, 0x14, 0x14, 0x08} // 70 p
,{0x08, 0x14, 0x14, 0x18, 0x7c} // 71 q
,{0x7c, 0x08, 0x04, 0x04, 0x08} // 72 r
,{0x48, 0x54, 0x54, 0x54, 0x20} // 73 s
,{0x04, 0x3f, 0x44, 0x40, 0x20} // 74 t
,{0x3c, 0x40, 0x40, 0x20, 0x7c} // 75 u
,{0x1c, 0x20, 0x40, 0x20, 0x1c} // 76 v
,{0x3c, 0x40, 0x30, 0x40, 0x3c} // 77 w
,{0x44, 0x28, 0x10, 0x28, 0x44} // 78 x
,{0x0c, 0x50, 0x50, 0x50, 0x3c} // 79 y
,{0x44, 0x64, 0x54, 0x4c, 0x44} // 7a z
,{0x00, 0x08, 0x36, 0x41, 0x00} // 7b {
,{0x00, 0x00, 0x7f, 0x00, 0x00} // 7c |
,{0x00, 0x41, 0x36, 0x08, 0x00} // 7d }
,{0x10, 0x08, 0x08, 0x10, 0x08} // 7e ←
,{0x00, 0x06, 0x09, 0x09, 0x06} // 7f →
};

void LcdCharacter(char character)
{
LcdWrite(LCD_D, 0x00);
for (int index = 0; index < 5; index++)
{
LcdWrite(LCD_D, ASCII[character – 0x20][index]);
}
LcdWrite(LCD_D, 0x00);
}

void LcdClear(void)
{
for (int index = 0; index < LCD_X * LCD_Y / 8; index++)
{
LcdWrite(LCD_D, 0x00);
}
}

void LcdInitialise(void)
{
pinMode(PIN_SCE, OUTPUT);
pinMode(PIN_RESET, OUTPUT);
pinMode(PIN_DC, OUTPUT);
pinMode(PIN_SDIN, OUTPUT);
pinMode(PIN_SCLK, OUTPUT);

digitalWrite(PIN_RESET, LOW);
digitalWrite(PIN_RESET, HIGH);

LcdWrite(LCD_CMD, 0x21); // LCD Extended Commands.
LcdWrite(LCD_CMD, 0xBf); // Set LCD Vop (Contrast). //B1
LcdWrite(LCD_CMD, 0x04); // Set Temp coefficent. //0x04
LcdWrite(LCD_CMD, 0x14); // LCD bias mode 1:48. //0x13
LcdWrite(LCD_CMD, 0x0C); // LCD in normal mode. 0x0d for inverse
LcdWrite(LCD_C, 0x20);
LcdWrite(LCD_C, 0x0C);
}

void LcdString(char *characters)
{
while (*characters)
{
LcdCharacter(*characters++);
}
}

void LcdWrite(byte dc, byte data)
{
digitalWrite(PIN_DC, dc);
digitalWrite(PIN_SCE, LOW);
shiftOut(PIN_SDIN, PIN_SCLK, MSBFIRST, data);
digitalWrite(PIN_SCE, HIGH);
}

/**
* gotoXY routine to position cursor
* x – range: 0 to 84
* y – range: 0 to 5
*/
void gotoXY(int x, int y)
{
LcdWrite( 0, 0x80 | x); // Column.
LcdWrite( 0, 0x40 | y); // Row.
}

void drawBox(void)
{
int j;
for(j = 0; j < 84; j++) // top
{
gotoXY(j, 0);
LcdWrite(1, 0x01);
}

for(j = 0; j < 84; j++) //Bottom
{
gotoXY(j, 5);
LcdWrite(1, 0x80);
}

for(j = 0; j < 6; j++) // Right
{
gotoXY(83, j);
LcdWrite(1, 0xff);
}

for(j = 0; j < 6; j++) // Left
{
gotoXY(0, j);
LcdWrite(1, 0xff);
}
}

void Scroll(String message)
{
for (int i = scrollPosition; i < scrollPosition + 11; i++)
{
if ((i >= message.length()) || (i < 0))
{
LcdCharacter(‘ ‘);
}
else
{
LcdCharacter(message.charAt(i));
}
}
scrollPosition++;
if ((scrollPosition >= message.length()) && (scrollPosition > 0))
{
scrollPosition = -10;
}
}

void setup(void)
{
LcdInitialise();
LcdClear();
drawBox();

gotoXY(7,1);
LcdString("Nokia 5110");
gotoXY(4,2);
LcdString("Scroll Demo");
}

void loop(void)
{
gotoXY(4,4);
Scroll("Scrolling Message from MindKits.co.nz / blog.stuartlewis.com");
delay(200);
}
[/code]автореклама

Life used to be so simple / unconfigurable

I had a spare hour this afternoon, so I thought I’d take a quick look at how dspace.cfg has changed over time. Anyone who has had the pleasure of looking after a DSpace server will know about dspace.cfg. It is the main configuration file for DSpace where many of the configurable options reside. These vary from core settings such as the name of your database server or mail server, to minor tweaks that make differences to your repository that nobody would ever notice!

DSpace 1.7 has just been released, and as it stands, dspace.cfg is a whopping 2268 lines long, containing over 200 required or preset configuration options, and a further 250+ optional parameters.  That’s quite a configuration file!

(It’s not so bad though – to get a new system up and running requires less than 5 settings to be edited to match your local environment.  The rest are there for a rainy day.)

But… how has it grown over time?

  • Version 1.0: 31 required / preset, 2 optional
  • Version 1.1: 30 required / preset, 5 optional (-1, +3)
  • Version 1.2: 34 required / preset, 9 optional (+4, +4)
  • Version 1.3: 55 required / preset, 32 optional (+21, +23)
  • Version 1.4: 101 required / preset, 58 optional (+46, +26)
  • Version 1.5 : 157 required / preset, 104 optional (+56, +46)
  • Version 1.6: 195 required / preset, 227 optional (+38, +123)
  • Version 1.7: 215 required / preset, 257 optional (+20, +30)

Or if you want to see it as a chart:

(N.B.: The gaps in between each release do not always reflect the amount of time or code changes in that version, but as a subversion repository as a whole.  The darker area are the number of required / preset configuration options, and the lighter shaded area the optional settings.  The number of optional settings is a rough calculation, looking in the configuration file for any line that starts with a ‘#’ (a comment) and contains and equals sign.)

That’s obviously quite a change – from humble beginnings.  I think everyone agrees that something needs to be done to help the system administrator / repository manager navigate and understand the plethora of configuration options.  However there are many different options / preferences / views about how this is best tackled: multiple configuration files, configuration stored in the database, configuration managed via spring services, DSpace installers, etc. One will have to win…сайт