Ticket #5: 10-track-chunks.patch
| File 10-track-chunks.patch, 10.2 kB (added by Chris Tilden, 3 years ago) |
|---|
-
a/src/org/lastpod/Scrobbler.java
old new 18 18 */ 19 19 package org.lastpod; 20 20 21 import org.lastpod.chunk.Chunk; 22 import org.lastpod.chunk.ChunkUtil; 23 21 24 import java.io.BufferedReader; 22 25 import java.io.IOException; 23 26 import java.io.InputStream; … … 54 57 */ 55 58 public class Scrobbler { 56 59 /** 60 * AudioScrobbler suggests a maximum number of tracks per chunk. 61 */ 62 private static final int MAX_TRACKS_PER_CHUNK = 10; 63 64 /** 57 65 * The minimum length (in seconds) of a track that meets Last.fm guidelines. 58 66 */ 59 67 private static final int MIN_TRACK_SECONDS = 30; … … 177 185 String urlEncodedUsername = URLEncoder.encode(username, "UTF-8"); 178 186 String urlEncodedChallange = URLEncoder.encode(md5chal, "UTF-8"); 179 187 180 pauseIfRequired(); 188 /* Converts the recentPlayed List into a List of Chunk objects. Each 189 * chunk stores at most 10 tracks. Each chunk will be submitted to 190 * Last.fm individually, per their guidelines. 191 */ 192 List chunks = ChunkUtil.createChunks(recentPlayed, MAX_TRACKS_PER_CHUNK); 181 193 182 String queryString = "u=" + urlEncodedUsername + "&" + "s=" + urlEncodedChallange;194 Chunk chunk = null; 183 195 184 int tracknum = 0; 196 for (int i = 0; i < chunks.size(); i++) { 197 pauseIfRequired(); 185 198 186 for (int i = 0; i < recentPlayed.size(); i++) { 187 TrackItem track = (TrackItem) recentPlayed.get(i); 199 chunk = (Chunk) chunks.get(i); 188 200 189 /* Per Last.fm guidelines; do not submit tracks that are less 190 * than 30 characters in length. 191 */ 192 if (track.getLength() < MIN_TRACK_SECONDS) { 193 continue; 201 String queryString = "u=" + urlEncodedUsername + "&" + "s=" + urlEncodedChallange; 202 203 int tracknum = 0; 204 205 for (int j = 0; j < chunk.getChunkSize(); j++) { 206 TrackItem track = (TrackItem) chunk.getContent().get(j); 207 208 /* Per Last.fm guidelines; do not submit tracks that are less 209 * than 30 characters in length. 210 */ 211 if (track.getLength() < MIN_TRACK_SECONDS) { 212 continue; 213 } 214 215 queryString += buildTrackQueryString(track, tracknum); 216 217 tracknum++; 194 218 } 195 219 196 queryString += buildTrackQueryString(track, tracknum);220 String content = null; 197 221 198 tracknum++; 199 } 222 /* If a backup URL is specified then two submits will take place. A 223 * backup URL can be used to send your information to another server. 224 */ 225 if ((backupUrl != null) && !backupUrl.equals("")) { 226 content = fetchContent(backupUrl, queryString); 227 logger.log(Level.FINE, "Received from server:\n" + content); 228 } 200 229 201 String content = null; 230 String urlString = "http://" + submitHost + ":" + submitPort + submitUrl; 231 content = fetchContent(urlString, queryString); 202 232 203 /* If a backup URL is specified then two submits will take place. A 204 * backup URL can be used to send your information to another server. 205 */ 206 if ((backupUrl != null) && !backupUrl.equals("")) { 207 content = fetchContent(backupUrl, queryString); 208 logger.log(Level.FINE, "Received from server:\n" + content); 209 } 233 String[] lines = content.split("\n"); 210 234 211 String urlString = "http://" + submitHost + ":" + submitPort + submitUrl; 212 content = fetchContent(urlString, queryString); 235 /* Sets the interval, if it is present in the response. */ 236 if ((lines.length >= 2) && (lines[1].length() >= 10)) { 237 String wait = lines[3].substring(10); 238 interval = Integer.parseInt(wait); 239 } 213 240 214 String[] lines = content.split("\n"); 241 if ((lines[0].length() >= 6) && lines[0].substring(0, 6).equals("FAILED")) { 242 throw new RuntimeException(lines[0].substring(7)); 243 } 215 244 216 if ((lines[0].length() >= 6) && lines[0].substring(0, 6).equals("FAILED")) {217 throw new RuntimeException(lines[0].substring(7));218 }245 if ((lines[0].length() >= 7) && lines[0].substring(0, 7).equals("BADAUTH")) { 246 throw new FailedLoginException("Invalid username/password"); 247 } 219 248 220 if ((lines[0].length() >= 7) && lines[0].substring(0, 7).equals("BADAUTH")) { 221 throw new FailedLoginException("Invalid username/password"); 249 if ((lines[0].length() >= 2) && !lines[0].substring(0, 2).equals("OK")) { 250 throw new RuntimeException("Unknown error submitting tracks"); 251 } 222 252 } 223 253 224 if ((lines[0].length() >= 2) && !lines[0].substring(0, 2).equals("OK")) {225 throw new RuntimeException("Unknown error submitting tracks");226 }227 228 254 logger.log(Level.INFO, "Tracks submitted"); 229 255 logger.log(Level.INFO, 230 256 "You must now sync your iPod with your music management software " -
a/src/org/lastpod/chunk/ChunkUtil.java
old new 1 /* 2 * LastPod is an application used to publish one's iPod play counts to Last.fm. 3 * Copyright (C) 2007 muti, Chris Tilden 4 * 5 * This program is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU General Public License 7 * as published by the Free Software Foundation; either version 2 8 * of the License, or (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program; if not, write to the Free Software 17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 */ 19 package org.lastpod.chunk; 20 21 import java.util.ArrayList; 22 import java.util.Collections; 23 import java.util.List; 24 25 public class ChunkUtil { 26 private List originalList; 27 private int chunkSize; 28 29 private ChunkUtil(final List originalList, final int chunkSize) { 30 this.originalList = originalList; 31 this.chunkSize = chunkSize; 32 } 33 34 public static List createChunks(final List orignalList, final int chunkSize) { 35 if ((orignalList == null) || (orignalList.size() == 0)) { 36 return Collections.EMPTY_LIST; 37 } 38 39 ChunkUtil pagination = new ChunkUtil(orignalList, chunkSize); 40 41 Chunk page = null; 42 int totalPages = pagination.getTotalChunks(); 43 44 List paginationList = new ArrayList(); 45 46 for (int i = 0; i < totalPages; i++) { 47 page = pagination.getNextChunk(page); 48 paginationList.add(page); 49 } 50 51 return paginationList; 52 } 53 54 private Chunk getFirstChunk() { 55 Chunk result = null; 56 57 if ((originalList != null) && (originalList.size() > 0)) { 58 result = new Chunk(1, getTotalChunks(), chunkSize, iterateFrom(0)); 59 } 60 61 return result; 62 } 63 64 private Chunk getNextChunk(final Chunk currentChunk) { 65 if (currentChunk == null) { 66 return getFirstChunk(); 67 } 68 69 if (currentChunk.isLastChunk()) { 70 return currentChunk; 71 } 72 73 Chunk result = null; 74 75 if (originalList != null) { 76 result = new Chunk(currentChunk.getChunkNumber() + 1, currentChunk.getTotalChunks(), 77 chunkSize, iterateFrom(currentChunk.getChunkNumber() * chunkSize)); 78 } 79 80 return result; 81 } 82 83 private List iterateFrom(final int startIndex) { 84 final int totalSize = originalList.size(); 85 86 int endIndex = startIndex + chunkSize; 87 88 if (endIndex > totalSize) { 89 endIndex = totalSize; 90 } 91 92 return originalList.subList(startIndex, endIndex); 93 } 94 95 private int getTotalChunks() { 96 if ((originalList == null) || (originalList.size() <= 0)) { 97 return 0; 98 } 99 100 final int totalSize = originalList.size(); 101 102 return ((totalSize - 1) / chunkSize) + 1; 103 } 104 }
