mirror of
https://github.com/zxing/zxing.git
synced 2024-11-09 20:44:03 -08:00
Add basic Google Glass Mirror API app. Not likely to be functional.
git-svn-id: https://zxing.googlecode.com/svn/trunk@2926 59b500cc-1b3d-0410-9834-0bbf25fbcc57
This commit is contained in:
parent
4c642283bf
commit
d1ef2a902e
3
CHANGES
3
CHANGES
|
@ -319,10 +319,11 @@
|
|||
- Many ports of Java updates to C++ and C# ports
|
||||
- Standardize test system image processing and image format for reproducibility
|
||||
|
||||
2.3 (XX Dec 2013)
|
||||
2.3.0 (1 Dec 2013)
|
||||
|
||||
- Added clone of Google Chart Server QR code encoder API to zxingorg/, at endpoint /chart
|
||||
- Updated zxing.appspot.com generator to remove deprecated API usage, use latest GWT / App Engine
|
||||
- Added skeleton Google Glass Mirror API app
|
||||
- Improve and standardize Maven build, standardize directories and version naming
|
||||
- Barcode Scanner Android up requires Android 4 and is updated to use Android 4+ APIs
|
||||
- javase/ and zxingorg/ modules now use Java 7
|
||||
|
|
|
@ -43,6 +43,7 @@
|
|||
<exclude name="core/src/test/resources/**"/> <!-- included separately below -->
|
||||
<include name="cpp/**"/>
|
||||
<include name="csharp/**"/>
|
||||
<include name="glass-mirror/**"/>
|
||||
<include name="iphone/**"/>
|
||||
<include name="javase/**"/>
|
||||
<include name="jruby/**"/>
|
||||
|
|
145
glass-mirror/pom.xml
Executable file
145
glass-mirror/pom.xml
Executable file
|
@ -0,0 +1,145 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Copyright 2013 ZXing authors
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<!-- Author: Sean Owen -->
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>glass-mirror</artifactId>
|
||||
<version>2.3.0-SNAPSHOT</version>
|
||||
<packaging>war</packaging>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.google.apis</groupId>
|
||||
<artifactId>google-api-services-mirror</artifactId>
|
||||
<version>v1-rev28-1.17.0-rc</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>commons-logging</groupId>
|
||||
<artifactId>commons-logging</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.http-client</groupId>
|
||||
<artifactId>google-http-client-jackson2</artifactId>
|
||||
<version>1.17.0-rc</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.apis</groupId>
|
||||
<artifactId>google-api-services-oauth2</artifactId>
|
||||
<version>v2-rev51-1.17.0-rc</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.google.zxing</groupId>
|
||||
<artifactId>core</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.zxing</groupId>
|
||||
<artifactId>javase</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Update dependencies -->
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-core</artifactId>
|
||||
<version>2.2.3</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-codec</groupId>
|
||||
<artifactId>commons-codec</artifactId>
|
||||
<version>1.8</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpclient</artifactId>
|
||||
<version>4.3.1</version>
|
||||
<scope>runtime</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>commons-logging</groupId>
|
||||
<artifactId>commons-logging</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpcore</artifactId>
|
||||
<version>4.3</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
<version>15.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
<version>1.7.5</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-jdk14</artifactId>
|
||||
<version>1.7.5</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>jcl-over-slf4j</artifactId>
|
||||
<version>1.7.5</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax</groupId>
|
||||
<artifactId>javaee-web-api</artifactId>
|
||||
<version>6.0</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<parent>
|
||||
<groupId>com.google.zxing</groupId>
|
||||
<artifactId>zxing-parent</artifactId>
|
||||
<version>2.3.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<source>7</source>
|
||||
<target>7</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<name>ZXing Google Glass Mirror API app</name>
|
||||
<description>Experimental Barcode Scanner app for Google Glass Mirror API</description>
|
||||
|
||||
</project>
|
86
glass-mirror/src/main/java/com/google/zxing/client/glass/AuthUtil.java
Executable file
86
glass-mirror/src/main/java/com/google/zxing/client/glass/AuthUtil.java
Executable file
|
@ -0,0 +1,86 @@
|
|||
/*
|
||||
* Copyright (C) 2013 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright 2013 ZXing authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.google.zxing.client.glass;
|
||||
|
||||
import com.google.api.client.auth.oauth2.AuthorizationCodeFlow;
|
||||
import com.google.api.client.auth.oauth2.Credential;
|
||||
import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeFlow;
|
||||
import com.google.api.client.http.javanet.NetHttpTransport;
|
||||
import com.google.api.client.json.jackson2.JacksonFactory;
|
||||
import com.google.api.client.util.store.DataStoreFactory;
|
||||
import com.google.api.client.util.store.MemoryDataStoreFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* A collection of utility functions that simplify common authentication and
|
||||
* user identity tasks
|
||||
*
|
||||
* @author Sean Owen
|
||||
* @author Google
|
||||
*/
|
||||
final class AuthUtil {
|
||||
|
||||
private static final Collection<String> SCOPES =
|
||||
Arrays.asList("https://www.googleapis.com/auth/glass.timeline",
|
||||
"https://www.googleapis.com/auth/userinfo.profile");
|
||||
|
||||
private final DataStoreFactory dataStoreFactory;
|
||||
private final String clientID;
|
||||
private final String clientSecret;
|
||||
|
||||
AuthUtil(String clientID, String clientSecret) {
|
||||
dataStoreFactory = new MemoryDataStoreFactory();
|
||||
this.clientID = clientID;
|
||||
this.clientSecret = clientSecret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates and returns a new {@link AuthorizationCodeFlow} for this app.
|
||||
*/
|
||||
public AuthorizationCodeFlow newAuthorizationCodeFlow() throws IOException {
|
||||
return new GoogleAuthorizationCodeFlow.Builder(new NetHttpTransport(),
|
||||
new JacksonFactory(),
|
||||
clientID,
|
||||
clientSecret,
|
||||
SCOPES)
|
||||
.setAccessType("offline").setDataStoreFactory(dataStoreFactory).build();
|
||||
}
|
||||
|
||||
public Credential getCredential(String userId) throws IOException {
|
||||
return userId == null ? null : newAuthorizationCodeFlow().loadCredential(userId);
|
||||
}
|
||||
|
||||
}
|
114
glass-mirror/src/main/java/com/google/zxing/client/glass/DecodeHelper.java
Executable file
114
glass-mirror/src/main/java/com/google/zxing/client/glass/DecodeHelper.java
Executable file
|
@ -0,0 +1,114 @@
|
|||
/*
|
||||
* Copyright 2013 ZXing authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.google.zxing.client.glass;
|
||||
|
||||
import com.google.zxing.BarcodeFormat;
|
||||
import com.google.zxing.BinaryBitmap;
|
||||
import com.google.zxing.DecodeHintType;
|
||||
import com.google.zxing.LuminanceSource;
|
||||
import com.google.zxing.MultiFormatReader;
|
||||
import com.google.zxing.Reader;
|
||||
import com.google.zxing.ReaderException;
|
||||
import com.google.zxing.Result;
|
||||
import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
|
||||
import com.google.zxing.common.GlobalHistogramBinarizer;
|
||||
import com.google.zxing.common.HybridBinarizer;
|
||||
|
||||
import java.awt.color.CMMException;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.EnumMap;
|
||||
import java.util.EnumSet;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
|
||||
/**
|
||||
* @author Sean Owen
|
||||
*/
|
||||
final class DecodeHelper {
|
||||
|
||||
// No real reason to deal with more than maybe 8.3 megapixels
|
||||
private static final int MAX_PIXELS = 1 << 23;
|
||||
private static final Map<DecodeHintType,Object> HINTS;
|
||||
|
||||
static {
|
||||
HINTS = new EnumMap<>(DecodeHintType.class);
|
||||
HINTS.put(DecodeHintType.TRY_HARDER, Boolean.TRUE);
|
||||
HINTS.put(DecodeHintType.POSSIBLE_FORMATS, EnumSet.allOf(BarcodeFormat.class));
|
||||
}
|
||||
|
||||
private DecodeHelper() {
|
||||
}
|
||||
|
||||
static Collection<Result> processStream(InputStream is) throws IOException {
|
||||
BufferedImage image;
|
||||
try {
|
||||
image = ImageIO.read(is);
|
||||
} catch (CMMException | IllegalArgumentException e) {
|
||||
throw new IOException(e);
|
||||
}
|
||||
if (image == null) {
|
||||
throw new IOException("No image");
|
||||
}
|
||||
if (image.getHeight() <= 1 || image.getWidth() <= 1 ||
|
||||
image.getHeight() * image.getWidth() > MAX_PIXELS) {
|
||||
throw new IOException("Dimensions out of bounds: " + image.getWidth() + 'x' + image.getHeight());
|
||||
}
|
||||
|
||||
return processImage(image);
|
||||
}
|
||||
|
||||
private static Collection<Result> processImage(BufferedImage image) {
|
||||
|
||||
Reader reader = new MultiFormatReader();
|
||||
LuminanceSource source = new BufferedImageLuminanceSource(image);
|
||||
BinaryBitmap bitmap = new BinaryBitmap(new GlobalHistogramBinarizer(source));
|
||||
Collection<Result> results = new ArrayList<>(1);
|
||||
|
||||
if (results.isEmpty()) {
|
||||
try {
|
||||
// Look for normal barcode in photo
|
||||
Result theResult = reader.decode(bitmap, HINTS);
|
||||
if (theResult != null) {
|
||||
results.add(theResult);
|
||||
}
|
||||
} catch (ReaderException re) {
|
||||
// continue
|
||||
}
|
||||
}
|
||||
|
||||
if (results.isEmpty()) {
|
||||
try {
|
||||
// Try again with other binarizer
|
||||
BinaryBitmap hybridBitmap = new BinaryBitmap(new HybridBinarizer(source));
|
||||
Result theResult = reader.decode(hybridBitmap, HINTS);
|
||||
if (theResult != null) {
|
||||
results.add(theResult);
|
||||
}
|
||||
} catch (ReaderException re) {
|
||||
// continue
|
||||
}
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,184 @@
|
|||
/*
|
||||
* Copyright (C) 2013 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright 2013 ZXing authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.google.zxing.client.glass;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.ResourceBundle;
|
||||
import javax.servlet.ServletConfig;
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import com.google.api.client.auth.oauth2.AuthorizationCodeFlow;
|
||||
import com.google.api.client.auth.oauth2.Credential;
|
||||
import com.google.api.client.auth.oauth2.TokenResponse;
|
||||
import com.google.api.client.googleapis.auth.oauth2.GoogleTokenResponse;
|
||||
import com.google.api.client.http.GenericUrl;
|
||||
import com.google.api.services.mirror.model.Contact;
|
||||
import com.google.api.services.mirror.model.Subscription;
|
||||
import com.google.api.services.mirror.model.TimelineItem;
|
||||
import com.google.zxing.client.glass.mirror.MirrorClient;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* This servlet manages the OAuth 2.0 dance.
|
||||
*
|
||||
* @author Jenny Murphy - http://google.com/+JennyMurphy
|
||||
* @author Sean Owen
|
||||
* @link https://developers.google.com/glass/develop/mirror/authorization
|
||||
*/
|
||||
public final class NewUserSetupServlet extends HttpServlet {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(NewUserSetupServlet.class);
|
||||
|
||||
private static final String BS_ID = "barcode-scanner";
|
||||
|
||||
private AuthUtil authUtil;
|
||||
private String baseURL;
|
||||
private String notificationCallbackURL;
|
||||
private String subscriptionVerifyToken;
|
||||
|
||||
@Override
|
||||
public void init(ServletConfig servletConfig) {
|
||||
ServletContext context = servletConfig.getServletContext();
|
||||
authUtil = new AuthUtil(context.getInitParameter("CLIENT_ID"), context.getInitParameter("CLIENT_SECRET"));
|
||||
baseURL = context.getInitParameter("BASE_URL");
|
||||
notificationCallbackURL = baseURL + "/notification";
|
||||
subscriptionVerifyToken = context.getInitParameter("SUBSCRIPTION_VERIFY_TOKEN");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
|
||||
|
||||
String redirect;
|
||||
|
||||
if (request.getParameter("error") != null) {
|
||||
|
||||
log.warn("OAuth error: {}", Arrays.toString(request.getParameterValues("error")));
|
||||
redirect = baseURL;
|
||||
|
||||
} else {
|
||||
|
||||
GenericUrl url1 = new GenericUrl(request.getRequestURL().toString());
|
||||
url1.setRawPath("/oauth2callback");
|
||||
String callbackURL = url1.build();
|
||||
String code = request.getParameter("code");
|
||||
|
||||
if (code == null) {
|
||||
|
||||
log.info("New OAuth flow");
|
||||
|
||||
AuthorizationCodeFlow flow = authUtil.newAuthorizationCodeFlow();
|
||||
GenericUrl url = flow.newAuthorizationUrl().setRedirectUri(callbackURL);
|
||||
url.set("approval_prompt", "force");
|
||||
redirect = url.build();
|
||||
|
||||
} else {
|
||||
// If we have a code, finish the OAuth 2.0 dance
|
||||
|
||||
log.info("OAuth response, code: {}", code);
|
||||
|
||||
AuthorizationCodeFlow flow = authUtil.newAuthorizationCodeFlow();
|
||||
TokenResponse tokenResponse = flow.newTokenRequest(code).setRedirectUri(callbackURL).execute();
|
||||
|
||||
// Extract the Google User ID from the ID token in the auth response
|
||||
String userId = ((GoogleTokenResponse) tokenResponse).parseIdToken().getPayload().getSubject();
|
||||
|
||||
// Set it into the session
|
||||
//AuthUtil.setUserId(request, userId);
|
||||
flow.createAndStoreCredential(tokenResponse, userId);
|
||||
|
||||
ResourceBundle resources = ResourceBundle.getBundle("Strings", request.getLocale());
|
||||
|
||||
bootstrapNewUser(userId, resources);
|
||||
|
||||
redirect = "glass/index.jspx";
|
||||
}
|
||||
}
|
||||
|
||||
response.sendRedirect(redirect);
|
||||
}
|
||||
|
||||
private void bootstrapNewUser(String userId, ResourceBundle resources) throws IOException {
|
||||
Credential credential = authUtil.newAuthorizationCodeFlow().loadCredential(userId);
|
||||
|
||||
String appName = resources.getString("app.title");
|
||||
|
||||
MirrorClient mirrorClient = MirrorClient.get();
|
||||
|
||||
boolean contactExists = false;
|
||||
for (Contact contact : mirrorClient.listContacts(credential)) {
|
||||
if (BS_ID.equals(contact.getId())) {
|
||||
contactExists = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!contactExists) {
|
||||
Contact contact = new Contact();
|
||||
contact.setId(BS_ID);
|
||||
contact.setDisplayName(appName);
|
||||
contact.setAcceptTypes(Arrays.asList("image/png", "image/jpeg", "image/gif", "image/bmp"));
|
||||
mirrorClient.insertContact(credential, contact);
|
||||
}
|
||||
|
||||
boolean subscriptionExists = false;
|
||||
for (Subscription subscription : mirrorClient.listSubscriptions(credential)) {
|
||||
if (notificationCallbackURL.equals(subscription.getCallbackUrl())) {
|
||||
subscriptionExists = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!subscriptionExists) {
|
||||
Subscription subscription = new Subscription();
|
||||
subscription.setCollection("timeline");
|
||||
subscription.setOperation(Collections.singletonList("INSERT"));
|
||||
subscription.setCallbackUrl(notificationCallbackURL);
|
||||
subscription.setVerifyToken(subscriptionVerifyToken);
|
||||
subscription.setUserToken(userId);
|
||||
mirrorClient.insertSubscription(credential, subscription);
|
||||
}
|
||||
|
||||
TimelineItem timelineItem = new TimelineItem();
|
||||
timelineItem.setTitle(MessageFormat.format(resources.getString("setup.welcome.title"), appName));
|
||||
timelineItem.setText(MessageFormat.format(resources.getString("setup.welcome.text"), appName));
|
||||
mirrorClient.insertTimelineItem(credential, timelineItem);
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,117 @@
|
|||
/*
|
||||
* Copyright 2013 ZXing authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.google.zxing.client.glass;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.ResourceBundle;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
import com.google.api.client.auth.oauth2.Credential;
|
||||
import com.google.api.services.mirror.model.Attachment;
|
||||
import com.google.api.services.mirror.model.TimelineItem;
|
||||
import com.google.zxing.Result;
|
||||
import com.google.zxing.client.result.ParsedResult;
|
||||
import com.google.zxing.client.result.ResultParser;
|
||||
import com.google.zxing.client.result.URIParsedResult;
|
||||
import com.google.zxing.client.glass.mirror.MirrorClient;
|
||||
|
||||
/**
|
||||
* @author Sean Owen
|
||||
*/
|
||||
final class NotificationCallable implements Callable<Void> {
|
||||
|
||||
private final Credential credential;
|
||||
private final String timelineItemID;
|
||||
private final ResourceBundle resources;
|
||||
|
||||
NotificationCallable(Credential credential, String timelineItemID, ResourceBundle resources) {
|
||||
this.credential = credential;
|
||||
this.timelineItemID = timelineItemID;
|
||||
this.resources = resources;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void call() throws Exception {
|
||||
MirrorClient mirrorClient = MirrorClient.get();
|
||||
TimelineItem timelineItem = mirrorClient.getTimelineItem(credential, timelineItemID);
|
||||
if (timelineItem == null) {
|
||||
return null;
|
||||
}
|
||||
List<Attachment> attachments = timelineItem.getAttachments();
|
||||
if (attachments == null || attachments.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
Attachment attachment = attachments.get(0);
|
||||
String attachmentId = attachment.getId();
|
||||
|
||||
String errorMessage = null;
|
||||
Collection<Result> results = null;
|
||||
try (InputStream in = mirrorClient.getAttachmentInputStream(credential, timelineItemID, attachmentId)) {
|
||||
results = DecodeHelper.processStream(in);
|
||||
} catch (IOException | RuntimeException e) {
|
||||
errorMessage = e.toString();
|
||||
}
|
||||
|
||||
if (results == null || results.isEmpty()) {
|
||||
|
||||
TimelineItem resultTimelineItem = new TimelineItem();
|
||||
if (errorMessage == null) {
|
||||
resultTimelineItem.setTitle(resources.getString("scan.result.notfound.title"));
|
||||
resultTimelineItem.setText(resources.getString("scan.result.notfound.text"));
|
||||
} else {
|
||||
resultTimelineItem.setTitle(resources.getString("scan.result.error.title"));
|
||||
resultTimelineItem.setText(MessageFormat.format(resources.getString("scan.result.error.text"), errorMessage));
|
||||
}
|
||||
mirrorClient.insertTimelineItem(credential, resultTimelineItem);
|
||||
|
||||
} else {
|
||||
|
||||
for (Result result : results) {
|
||||
ParsedResult parsedResult = ResultParser.parseResult(result);
|
||||
|
||||
TimelineItem resultTimelineItem = new TimelineItem();
|
||||
resultTimelineItem.setText(parsedResult.getDisplayResult());
|
||||
resultTimelineItem.setTitle(
|
||||
MessageFormat.format(resources.getString("scan.result.success.title"), parsedResult.getType()));
|
||||
|
||||
addResultDetailToTimelineItem(parsedResult, resultTimelineItem);
|
||||
|
||||
mirrorClient.insertTimelineItem(credential, resultTimelineItem);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static void addResultDetailToTimelineItem(ParsedResult parsedResult, TimelineItem item) {
|
||||
if (parsedResult instanceof URIParsedResult) {
|
||||
addURIResultDetailToTimelineItem((URIParsedResult) parsedResult, item);
|
||||
}
|
||||
}
|
||||
|
||||
private static void addURIResultDetailToTimelineItem(URIParsedResult parsedResult, TimelineItem item) {
|
||||
String uri = parsedResult.getURI();
|
||||
item.setHtml("<a href=\"" + uri + "\">" + parsedResult.getDisplayResult() + "</a>");
|
||||
item.setCanonicalUrl(uri);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
* Copyright 2013 ZXing authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.google.zxing.client.glass;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ResourceBundle;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import javax.servlet.ServletConfig;
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import com.google.api.client.auth.oauth2.Credential;
|
||||
import com.google.api.client.json.JsonObjectParser;
|
||||
import com.google.api.client.json.jackson2.JacksonFactory;
|
||||
import com.google.api.services.mirror.model.Notification;
|
||||
|
||||
/**
|
||||
* @author Sean Owen
|
||||
* @link https://developers.google.com/glass/develop/mirror/timeline
|
||||
*/
|
||||
public final class NotificationServlet extends HttpServlet {
|
||||
|
||||
private ExecutorService executor;
|
||||
private final JsonObjectParser jsonParser = new JsonObjectParser(new JacksonFactory());
|
||||
private AuthUtil authUtil;
|
||||
private String subscriptionVerifyToken;
|
||||
|
||||
@Override
|
||||
public void init(ServletConfig servletConfig) {
|
||||
ServletContext context = servletConfig.getServletContext();
|
||||
authUtil = new AuthUtil(context.getInitParameter("CLIENT_ID"), context.getInitParameter("CLIENT_SECRET"));
|
||||
executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
|
||||
subscriptionVerifyToken = context.getInitParameter("SUBSCRIPTION_VERIFY_TOKEN");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {
|
||||
|
||||
Notification notification = jsonParser.parseAndClose(request.getReader(), Notification.class);
|
||||
|
||||
if (!subscriptionVerifyToken.equals(notification.getVerifyToken())) {
|
||||
response.sendError(HttpServletResponse.SC_BAD_REQUEST);
|
||||
return;
|
||||
}
|
||||
|
||||
String userId = notification.getUserToken();
|
||||
Credential credential = authUtil.newAuthorizationCodeFlow().loadCredential(userId);
|
||||
String timelineItemID = notification.getItemId();
|
||||
|
||||
ResourceBundle resources = ResourceBundle.getBundle("Strings", request.getLocale());
|
||||
|
||||
executor.submit(new NotificationCallable(credential, timelineItemID, resources));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
executor.shutdownNow();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
* Copyright (C) 2013 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright 2013 ZXing authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.google.zxing.client.glass.mirror;
|
||||
|
||||
import com.google.api.client.auth.oauth2.Credential;
|
||||
import com.google.api.client.http.GenericUrl;
|
||||
import com.google.api.client.http.HttpResponse;
|
||||
import com.google.api.client.http.javanet.NetHttpTransport;
|
||||
import com.google.api.client.json.jackson2.JacksonFactory;
|
||||
import com.google.api.services.mirror.Mirror;
|
||||
import com.google.api.services.mirror.model.Attachment;
|
||||
import com.google.api.services.mirror.model.Contact;
|
||||
import com.google.api.services.mirror.model.Subscription;
|
||||
import com.google.api.services.mirror.model.TimelineItem;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Collection;
|
||||
|
||||
final class GoogleAPIMirrorClient extends MirrorClient {
|
||||
|
||||
@Override
|
||||
public void insertContact(Credential credential, Contact contact) throws IOException {
|
||||
getMirror(credential).contacts().insert(contact).execute();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Contact> listContacts(Credential credential) throws IOException {
|
||||
return getMirror(credential).contacts().list().execute().getItems();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void insertTimelineItem(Credential credential, TimelineItem item) throws IOException {
|
||||
getMirror(credential).timeline().insert(item).execute();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void insertSubscription(Credential credential, Subscription subscription) throws IOException {
|
||||
getMirror(credential).subscriptions().insert(subscription).execute();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Subscription> listSubscriptions(Credential credential) throws IOException {
|
||||
return getMirror(credential).subscriptions().list().execute().getItems();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TimelineItem getTimelineItem(Credential credential, String id) throws IOException {
|
||||
return getMirror(credential).timeline().get(id).execute();
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream getAttachmentInputStream(Credential credential, String timelineItemId, String attachmentId)
|
||||
throws IOException {
|
||||
Mirror mirrorService = getMirror(credential);
|
||||
Mirror.Timeline.Attachments attachments = mirrorService.timeline().attachments();
|
||||
Attachment attachmentMetadata = attachments.get(timelineItemId, attachmentId).execute();
|
||||
HttpResponse resp =
|
||||
mirrorService.getRequestFactory()
|
||||
.buildGetRequest(new GenericUrl(attachmentMetadata.getContentUrl())).execute();
|
||||
return resp.getContent();
|
||||
}
|
||||
|
||||
private static Mirror getMirror(Credential credential) {
|
||||
return new Mirror.Builder(new NetHttpTransport(), new JacksonFactory(), credential).build();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,92 @@
|
|||
/*
|
||||
* Copyright 2013 ZXing authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.google.zxing.client.glass.mirror;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
|
||||
import com.google.api.client.auth.oauth2.Credential;
|
||||
import com.google.api.services.mirror.model.Attachment;
|
||||
import com.google.api.services.mirror.model.Contact;
|
||||
import com.google.api.services.mirror.model.Subscription;
|
||||
import com.google.api.services.mirror.model.TimelineItem;
|
||||
import com.google.common.collect.Sets;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
final class MemoryMirrorClient extends MirrorClient {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(MemoryMirrorClient.class);
|
||||
|
||||
private static final String FAKE_ATTACHMENT_ID = "0123";
|
||||
|
||||
private final Collection<Contact> contacts =
|
||||
Collections.synchronizedCollection(Sets.<Contact>newHashSet());
|
||||
private final Collection<Subscription> subscriptions =
|
||||
Collections.synchronizedCollection(Sets.<Subscription>newHashSet());
|
||||
|
||||
@Override
|
||||
public void insertContact(Credential credential, Contact contact) {
|
||||
log.info("Insert Contact: {}", contact);
|
||||
contacts.add(contact);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Contact> listContacts(Credential credential) {
|
||||
log.info("Contacts: {}", contacts);
|
||||
return contacts;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void insertTimelineItem(Credential credential, TimelineItem item) {
|
||||
log.info("Insert Timeline: {}", item);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void insertSubscription(Credential credential, Subscription subscription) {
|
||||
log.info("Insert Subscription: {}", subscription);
|
||||
subscriptions.add(subscription);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Subscription> listSubscriptions(Credential credential) {
|
||||
log.info("Subscriptions: {}", subscriptions);
|
||||
return subscriptions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TimelineItem getTimelineItem(Credential credential, String id) {
|
||||
log.info("Get Timeline {}", id);
|
||||
TimelineItem timelineItem = new TimelineItem();
|
||||
timelineItem.setId(id);
|
||||
Attachment fakeAttachment = new Attachment();
|
||||
fakeAttachment.setId(FAKE_ATTACHMENT_ID);
|
||||
timelineItem.setAttachments(Collections.singletonList(fakeAttachment));
|
||||
return timelineItem;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream getAttachmentInputStream(Credential credential, String timelineItemId, String attachmentId) {
|
||||
log.info("Get Attachment {} {}", timelineItemId, attachmentId);
|
||||
if (!FAKE_ATTACHMENT_ID.equals(attachmentId)) {
|
||||
return null;
|
||||
}
|
||||
return MemoryMirrorClient.class.getResourceAsStream("/test.jpg");
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* Copyright 2013 ZXing authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.google.zxing.client.glass.mirror;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Collection;
|
||||
|
||||
import com.google.api.client.auth.oauth2.Credential;
|
||||
import com.google.api.services.mirror.model.Contact;
|
||||
import com.google.api.services.mirror.model.Subscription;
|
||||
import com.google.api.services.mirror.model.TimelineItem;
|
||||
|
||||
public abstract class MirrorClient {
|
||||
|
||||
private static MirrorClient instance = null;
|
||||
|
||||
public static synchronized MirrorClient get() {
|
||||
if (instance == null) {
|
||||
instance = new GoogleAPIMirrorClient();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
public abstract void insertContact(Credential credential, Contact contact) throws IOException;
|
||||
|
||||
public abstract Collection<Contact> listContacts(Credential credential) throws IOException;
|
||||
|
||||
public abstract void insertTimelineItem(Credential credential, TimelineItem item) throws IOException;
|
||||
|
||||
public abstract void insertSubscription(Credential credential, Subscription subscription) throws IOException;
|
||||
|
||||
public abstract Collection<Subscription> listSubscriptions(Credential credential) throws IOException;
|
||||
|
||||
public abstract TimelineItem getTimelineItem(Credential credential, String id) throws IOException;
|
||||
|
||||
public abstract InputStream getAttachmentInputStream(Credential credential,
|
||||
String timelineItemId,
|
||||
String attachmentId) throws IOException;
|
||||
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
* Copyright 2013 ZXing authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.google.zxing.client.glass.store;
|
||||
|
||||
import com.google.api.client.auth.oauth2.StoredCredential;
|
||||
import com.google.api.client.util.store.AbstractDataStore;
|
||||
import com.google.api.client.util.store.DataStore;
|
||||
import com.google.api.client.util.store.DataStoreFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Serializable;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
|
||||
final class MySQLDataStore<V extends Serializable> extends AbstractDataStore<V> {
|
||||
|
||||
MySQLDataStore(DataStoreFactory dataStoreFactory, String id) {
|
||||
super(dataStoreFactory, id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> keySet() {
|
||||
return Collections.singleton(StoredCredential.DEFAULT_DATA_STORE_ID);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<V> values() throws IOException {
|
||||
return null; // TODO
|
||||
}
|
||||
|
||||
@Override
|
||||
public V get(String key) throws IOException {
|
||||
return null; // TODO
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataStore<V> set(String key, V value) throws IOException {
|
||||
return null; // TODO
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataStore<V> clear() throws IOException {
|
||||
return null; // TODO
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataStore<V> delete(String key) throws IOException {
|
||||
return null; // TODO
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* Copyright 2013 ZXing authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.google.zxing.client.glass.store;
|
||||
|
||||
import com.google.api.client.util.store.AbstractDataStoreFactory;
|
||||
import com.google.api.client.util.store.DataStore;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
final class MySQLDataStoreFactory extends AbstractDataStoreFactory {
|
||||
|
||||
@Override
|
||||
protected <V extends Serializable> DataStore<V> createDataStore(String id) {
|
||||
return new MySQLDataStore<>(this, id);
|
||||
}
|
||||
|
||||
}
|
8
glass-mirror/src/main/resources/Strings.properties
Executable file
8
glass-mirror/src/main/resources/Strings.properties
Executable file
|
@ -0,0 +1,8 @@
|
|||
app.title=Barcode Scanner for Google Glass
|
||||
setup.welcome.title=Welcome to {0}
|
||||
setup.welcome.text=To read a barcode, share a photo of it with the contact called '{0}'
|
||||
scan.result.notfound.title=No Barcode Found
|
||||
scan.result.notfound.text=Sorry, no barcode could be found it that image. Try sharing another image.
|
||||
scan.result.error.title=Error
|
||||
scan.result.error.text=An error occurred while looking for a barcode: {0}
|
||||
scan.result.success.title={0} Barcode
|
BIN
glass-mirror/src/main/resources/test.jpg
Executable file
BIN
glass-mirror/src/main/resources/test.jpg
Executable file
Binary file not shown.
After Width: | Height: | Size: 50 KiB |
104
glass-mirror/src/main/webapp/WEB-INF/web.xml
Executable file
104
glass-mirror/src/main/webapp/WEB-INF/web.xml
Executable file
|
@ -0,0 +1,104 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Copyright 2013 ZXing authors
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<!-- Author: Sean Owen -->
|
||||
<web-app version="3.0"
|
||||
xmlns="http://java.sun.com/xml/ns/javaee"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
|
||||
|
||||
<distributable/>
|
||||
|
||||
<!--
|
||||
Change these two to client ID / secret you generated when you set up your Glass API
|
||||
https://developers.google.com/glass/develop/mirror/authorization#create_a_client_id_and_client_secret
|
||||
-->
|
||||
<context-param>
|
||||
<param-name>CLIENT_ID</param-name>
|
||||
<param-value>TODO</param-value>
|
||||
</context-param>
|
||||
<context-param>
|
||||
<param-name>CLIENT_SECRET</param-name>
|
||||
<param-value>TODO</param-value>
|
||||
</context-param>
|
||||
<!--
|
||||
The URL base for your Mirror app
|
||||
-->
|
||||
<context-param>
|
||||
<param-name>BASE_URL</param-name>
|
||||
<param-value>http://example.org/todo</param-value>
|
||||
</context-param>
|
||||
<!--
|
||||
See https://developers.google.com/glass/v1/reference/subscriptions/insert
|
||||
-->
|
||||
<context-param>
|
||||
<param-name>SUBSCRIPTION_VERIFY_TOKEN</param-name>
|
||||
<param-value>TODO</param-value>
|
||||
</context-param>
|
||||
|
||||
<servlet>
|
||||
<servlet-name>OAuth2CallbackServlet</servlet-name>
|
||||
<servlet-class>com.google.zxing.client.glass.NewUserSetupServlet</servlet-class>
|
||||
</servlet>
|
||||
<servlet>
|
||||
<servlet-name>NotificationServlet</servlet-name>
|
||||
<servlet-class>com.google.zxing.client.glass.NotificationServlet</servlet-class>
|
||||
</servlet>
|
||||
|
||||
<servlet-mapping>
|
||||
<servlet-name>OAuth2CallbackServlet</servlet-name>
|
||||
<url-pattern>/oauth2callback</url-pattern>
|
||||
<url-pattern>/start</url-pattern>
|
||||
</servlet-mapping>
|
||||
<servlet-mapping>
|
||||
<servlet-name>NotificationServlet</servlet-name>
|
||||
<url-pattern>/notification</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<error-page>
|
||||
<exception-type>java.lang.Throwable</exception-type>
|
||||
<location>/error.jspx</location>
|
||||
</error-page>
|
||||
<error-page>
|
||||
<error-code>400</error-code>
|
||||
<location>/error.jspx</location>
|
||||
</error-page>
|
||||
<error-page>
|
||||
<error-code>401</error-code>
|
||||
<location>/error.jspx</location>
|
||||
</error-page>
|
||||
<error-page>
|
||||
<error-code>404</error-code>
|
||||
<location>/error.jspx</location>
|
||||
</error-page>
|
||||
<error-page>
|
||||
<error-code>405</error-code>
|
||||
<location>/error.jspx</location>
|
||||
</error-page>
|
||||
<error-page>
|
||||
<error-code>500</error-code>
|
||||
<location>/error.jspx</location>
|
||||
</error-page>
|
||||
<error-page>
|
||||
<error-code>501</error-code>
|
||||
<location>/error.jspx</location>
|
||||
</error-page>
|
||||
<error-page>
|
||||
<error-code>503</error-code>
|
||||
<location>/error.jspx</location>
|
||||
</error-page>
|
||||
|
||||
</web-app>
|
41
glass-mirror/src/main/webapp/error.jspx
Executable file
41
glass-mirror/src/main/webapp/error.jspx
Executable file
|
@ -0,0 +1,41 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Copyright 2013 ZXing authors
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<!-- Author: Sean Owen -->
|
||||
<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page" version="2.1">
|
||||
<jsp:directive.page contentType="text/html"/>
|
||||
<jsp:directive.page isErrorPage="true"/>
|
||||
<jsp:directive.page session="false"/>
|
||||
<jsp:directive.page import="java.io.PrintWriter"/>
|
||||
<jsp:text><![CDATA[<!DOCTYPE html>]]></jsp:text>
|
||||
<html>
|
||||
<head>
|
||||
<title>Error</title>
|
||||
<style type="text/css">body{background-color:black} body,p{font-family:monospace;color:white}</style>
|
||||
</head>
|
||||
<body>
|
||||
<p><strong>Error ${pageContext.errorData.statusCode}</strong> : ${pageContext.errorData.requestURI}</p>
|
||||
<p><pre>
|
||||
<jsp:scriptlet>
|
||||
Throwable t = pageContext.getErrorData().getThrowable();
|
||||
if (t != null) {
|
||||
t.printStackTrace(new PrintWriter(out));
|
||||
}
|
||||
</jsp:scriptlet>
|
||||
</pre></p>
|
||||
</body>
|
||||
</html>
|
||||
</jsp:root>
|
31
glass-mirror/src/main/webapp/glass/index.jspx
Executable file
31
glass-mirror/src/main/webapp/glass/index.jspx
Executable file
|
@ -0,0 +1,31 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Copyright 2013 ZXing authors
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<!-- Author: Sean Owen -->
|
||||
<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page" version="2.1">
|
||||
<jsp:directive.page contentType="text/html" session="false"/>
|
||||
<jsp:text><![CDATA[<!DOCTYPE html>]]></jsp:text>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8"/>
|
||||
<title>Barcode Scanner for Google Glass</title>
|
||||
<link rel="stylesheet" href="style.css" type="text/css"/>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Success</h1>
|
||||
</body>
|
||||
</html>
|
||||
</jsp:root>
|
3
glass-mirror/src/main/webapp/glass/style.css
Executable file
3
glass-mirror/src/main/webapp/glass/style.css
Executable file
|
@ -0,0 +1,3 @@
|
|||
body {background-color:black;margin:0;padding:0}
|
||||
body,th,td,p {font-family:Helvetica,Arial,sans-serif;color:white}
|
||||
td {vertical-align:top}
|
Loading…
Reference in a new issue