Skip to content

Commit

Permalink
Update readme, also various fixes and improvements.
Browse files Browse the repository at this point in the history
  • Loading branch information
JonasCz committed Feb 15, 2015
1 parent 785bffb commit 579a938
Show file tree
Hide file tree
Showing 9 changed files with 71 additions and 57 deletions.
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
Save for offline is an Android app for saving webpages for offline reading.

In you web browser select 'share' , and then 'Save For Offline'
```
This is an experimental beta version, and while it mostly works, it may have some problems. Please do report any bugs you find!
```

## Screenshots
#### Grid layout for the list of all saved pages.
Expand All @@ -13,7 +16,7 @@ In you web browser select 'share' , and then 'Save For Offline'
![List layout](https://raw.githubusercontent.com/JonasCz/save-for-offline/master/screenshots/listlayout.png)
***

#### Built in viewer. (Future versions may support opening saved files in web browser)
#### Built in viewer. (Saved HTML files can also be opened in other apps or copied to computer)
![Viewer](https://raw.githubusercontent.com/JonasCz/save-for-offline/master/screenshots/viewer.png)
***

Expand Down
5 changes: 3 additions & 2 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ android {
applicationId "jonas.tool.saveForOffline"
minSdkVersion 14
targetSdkVersion 19
versionCode 10
versionName "2.0.1 Beta"
versionCode 11
versionName "2.0.2 Beta"
}
buildTypes {
release {
Expand All @@ -21,4 +21,5 @@ android {

dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])

}
47 changes: 26 additions & 21 deletions app/src/main/java/jonas/tool/saveForOffline/MainActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public class MainActivity extends Activity implements SearchView.OnQueryTextList
private TextView helpText;

private int sortOrder = 0;


private GridView mainGrid;
private SearchView mSearchView;
Expand All @@ -52,7 +52,6 @@ public class MainActivity extends Activity implements SearchView.OnQueryTextList

private int scrollPosition;


@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Expand All @@ -63,6 +62,7 @@ public void onCreate(Bundle savedInstanceState) {
mainGrid = (GridView) findViewById(R.id.List);

mainGrid.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);

mainGrid.setMultiChoiceModeListener(new ModeCallback());


Expand Down Expand Up @@ -91,13 +91,6 @@ public void onCreate(Bundle savedInstanceState) {
mainGrid.setAdapter(gridAdapter);


}

private void deleteItems() {




}

@Override
Expand All @@ -117,6 +110,7 @@ public boolean onCreateOptionsMenu(Menu menu) {
mSearchView.setIconifiedByDefault(true);
mSearchView.setOnQueryTextListener(this);
return super.onCreateOptionsMenu(menu);

}


Expand Down Expand Up @@ -195,7 +189,7 @@ public void onClick(DialogInterface dialog, int which) {
return true;

case R.id.ic_action_settings:
Intent settings = new Intent(getApplicationContext(), Preferences.class);
Intent settings = new Intent(this, Preferences.class);
startActivityForResult(settings, 1);

return true;
Expand All @@ -205,6 +199,7 @@ public void onClick(DialogInterface dialog, int which) {
startActivity(intent);
return true;


default:
return super.onOptionsItemSelected(item);
}
Expand Down Expand Up @@ -271,8 +266,9 @@ private void displayData(String searchQuery) {

class ModeCallback implements ListView.MultiChoiceModeListener {


@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {

MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main_activity_multi_choice, menu);
mode.setTitle("Select Items");
Expand All @@ -281,10 +277,15 @@ public boolean onCreateActionMode(ActionMode mode, Menu menu) {
return true;
}



@Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
gridAdapter.selectedViewsPositions.clear();
return true;
}

@Override
public boolean onActionItemClicked(final ActionMode mode, MenuItem item) {

switch (item.getItemId()) {
Expand Down Expand Up @@ -347,10 +348,10 @@ public void onClick(DialogInterface dialog, int which) {
displayData("");
pd.hide();
pd.cancel();

Toast.makeText(MainActivity.this, "Deleted " + gridAdapter.selectedViewsPositions.size() + " saved pages",Toast.LENGTH_LONG).show();


Toast.makeText(MainActivity.this, "Deleted " + gridAdapter.selectedViewsPositions.size() + " saved pages", Toast.LENGTH_LONG).show();


mode.finish();
}
});
Expand All @@ -370,18 +371,20 @@ public void onClick(DialogInterface dialog,

break;
default:

break;
}
return true;
}

@Override
public void onDestroyActionMode(ActionMode mode) {
gridAdapter.selectedViewsPositions.clear();

gridAdapter.selectedViewsPositions.clear();

}

@Override
public void onItemCheckedStateChanged(ActionMode mode,
int position, long itemId, boolean checked) {
Integer pos = position;
Expand Down Expand Up @@ -409,14 +412,16 @@ public void onItemCheckedStateChanged(ActionMode mode,

switch (checkedCount) {
case 0:
mode.setSubtitle("Select items");
Log.w("MainActivity / Gridview", "Should never happen: nothing selected");
mode.setSubtitle("Tap to select items");
findViewById(R.id.action_delete).setEnabled(false);
break;
case 1:
mode.setSubtitle("One item selected");
findViewById(R.id.action_delete).setEnabled(true);
break;
default:
mode.setSubtitle("" + checkedCount + " items selected");
mode.setSubtitle(checkedCount + " items selected");
findViewById(R.id.action_delete).setEnabled(true);
break;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public void onClick(DialogInterface dialog, int which) {
} else {
Preference advancedSavingOptions = getPreferenceScreen().findPreference("saving_advanced_opts");
advancedSavingOptions.setEnabled(true);
advancedSavingOptions.setSummary("Choose how errors should be handled and what parts of a webpage to save (images, scripts...) ");
advancedSavingOptions.setSummary("Choose how errors should be handled and what parts of a webpage to save (images, scripts...). Use with care");
}
//disabled for now
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,11 +66,10 @@ public void onCreate(Bundle savedInstanceState)

if (ua.equals("desktop")) {
webview.getSettings().setUserAgentString("Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.517 Safari/537.36");
Log.d("saveActivity", "using desktop ua");
}
if (ua.equals("ipad")) {
webview.getSettings().setUserAgentString("todo:iPad ua");
Log.w("saveActivity", "iPad ua not implemented yet");

}


Expand Down
56 changes: 31 additions & 25 deletions app/src/main/java/jonas/tool/saveForOffline/SaveService.java
Original file line number Diff line number Diff line change
Expand Up @@ -269,18 +269,6 @@ private void grabPage(String url, String outputDirPath) throws Exception {

}

for (String f: GrabUtility.framesToGrab) {
lt.d(f);
}
for (String f: GrabUtility.cssToGrab) {
lt.d(f);
}
for (String f: GrabUtility.extraCssToGrab) {
lt.d(f);
}
for (String f: GrabUtility.filesToGrab) {
lt.d(f);
}
//download extra files, such as images / scripts
for (String urlToDownload: GrabUtility.filesToGrab) {

Expand Down Expand Up @@ -729,8 +717,8 @@ private void getExtraFile(String urlToDownload, File outputDir) {
}

/**
* @author Pramod Khare & improved by Jonas Czec
* Contains all the utility methods used in above GrabWebPage class
* @author Pramod Khare & improved by Jonas Czech
* Contains all the utility methods used in above class
*/
class GrabUtility{
// filesToGrab - maintains all the links to files which we are going to grab/download
Expand Down Expand Up @@ -762,7 +750,7 @@ public static String parseHtmlForLinks(String htmlToParse, String baseUrl) {
try {
fromHTMLPageUrl = new URL(baseUrl);
noBaseUrl = false;
} catch (java.net.MalformedURLException e) {
} catch (MalformedURLException e) {
fromHTMLPageUrl = null;
noBaseUrl = true;
}
Expand Down Expand Up @@ -872,14 +860,24 @@ public static String parseHtmlForLinks(String htmlToParse, String baseUrl) {
}

if (saveVideo) {
links = parsedHtml.select("video");
//video src is sometimes in a child element
links = parsedHtml.select("video:not([src])");
for (Element link: links.select("[src]")){
urlToGrab = link.attr("abs:src");
addLinkToList(urlToGrab);

String replacedURL = urlToGrab.substring(urlToGrab.lastIndexOf("/") + 1).replaceAll("[^a-zA-Z0-9-_\\.]", "_");
link.attr("src", replacedURL);
}

links = parsedHtml.select("video[src]");
for (Element link: links){
urlToGrab = link.attr("abs:src");
addLinkToList(urlToGrab);

String replacedURL = urlToGrab.substring(urlToGrab.lastIndexOf("/") + 1).replaceAll("[^a-zA-Z0-9-_\\.]", "_");
link.attr("src", replacedURL);
}
}

if (makeLinksAbsolute) {
Expand All @@ -896,8 +894,6 @@ public static String parseHtmlForLinks(String htmlToParse, String baseUrl) {

public static String parseCssForLinks(String cssToParse, String baseUrl) {


String importString = "@(import\\s*['\"])()([^ '\"]*)";
String patternString = "url(\\s*\\(\\s*['\"]*\\s*)(.*?)\\s*['\"]*\\s*\\)"; //I hate regexes...

Pattern pattern = Pattern.compile(patternString);
Expand All @@ -915,9 +911,11 @@ public static String parseCssForLinks(String cssToParse, String baseUrl) {

}

addLinkToList(makeLinkRelative(matcher.group().replaceAll(patternString, "$2").trim(), baseUrl));
addLinkToList(makeLinkAbsolute(matcher.group().replaceAll(patternString, "$2").trim(), baseUrl));
}

// find css linked with @import - needs testing
String importString = "@(import\\s*['\"])()([^ '\"]*)";
pattern = Pattern.compile(importString);
matcher = pattern.matcher(cssToParse);
matcher.reset();
Expand All @@ -930,30 +928,38 @@ public static String parseCssForLinks(String cssToParse, String baseUrl) {

}

extraCssToGrab.add(makeLinkRelative(matcher.group().replaceAll(patternString, "$2").trim(), baseUrl));
extraCssToGrab.add(makeLinkAbsolute(matcher.group().replaceAll(patternString, "$2").trim(), baseUrl));
}

return cssToParse;
}

public static void addLinkToList(String link) {
//no multithreading for now
synchronized (filesToGrab) {
if (!filesToGrab.contains(link)) {
filesToGrab.add(link);
}
}
}

public static String makeLinkRelative(String link, String baseurl) {
//jsoup figures out the absolute url for me...
Document d = Document.createShell(baseurl);
d.body().appendElement("img").attr("src", link);
return d.body().child(0).attr("abs:src");
public static String makeLinkAbsolute(String link, String baseurl) {

try {
URL u = new URL(new URL(baseurl), link);
return u.toString();
} catch (MalformedURLException e) {
lt.e("MalformedURLException while making url absolute");
lt.e("Link: " + link);
lt.e("BaseURL: " + baseurl);
return null;
}

}
}

class lt {
//log messages are sent here
public static void e (String message) {
Log.e("SaveService", message);
}
Expand Down
4 changes: 2 additions & 2 deletions app/src/main/res/menu/main_activity_actions.xml
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@

<item android:id="@+id/action_sort_by"
android:icon="@drawable/ic_action_sort"
android:title="Sort by"
android:showAsAction="ifRoom"/>
android:title="Sort items by"
android:showAsAction="never"/>

<item android:id="@+id/ic_action_settings"
android:title="Settings"
Expand Down
4 changes: 2 additions & 2 deletions app/src/main/res/values/styles_theme_main_yellow.xml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
<item name="android:actionBarTabStyle">@style/ActionBarTabStyle.Theme_main_yellow</item>
<item name="android:actionDropDownStyle">@style/DropDownNav.Theme_main_yellow</item>
<item name="android:actionBarStyle">@style/ActionBar.Solid.Theme_main_yellow</item>
<item name="android:actionModeBackground">@drawable/cab_background_top_theme_main_yellow</item>
<item name="android:actionModeStyle">@style/ActionBar.Solid.Theme_main_yellow</item>
<item name="android:actionModeSplitBackground">@drawable/cab_background_bottom_theme_main_yellow</item>
<item name="android:actionModeCloseButtonStyle">@style/ActionButton.CloseMode.Theme_main_yellow</item>

Expand Down Expand Up @@ -77,4 +77,4 @@
<item name="android:dropDownListViewStyle">@style/DropDownListView.Theme_main_yellow</item>
</style>

</resources>
</resources>
2 changes: 1 addition & 1 deletion app/src/main/res/xml/preferences.xml
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
android:title="Advanced options for saving"
android:summary="DONT play with these unless you are doing! Changimg these options may result in the app not working as expected"
android:summary="Choose how errors should be handled and what parts of a webpage to save (images, scripts...). Use with care"
android:key="saving_advanced_opts">
<PreferenceCategory
android:title="Saving options">
Expand Down

0 comments on commit 579a938

Please sign in to comment.