mirror of
https://github.com/akaessens/NoFbEventScraper
synced 2025-06-05 23:29:13 +02:00
Compare commits
18 Commits
Author | SHA1 | Date | |
---|---|---|---|
c43911fc77 | |||
3cbfc9b9c1 | |||
71169dae76 | |||
5b412733b4 | |||
a3f2990c61 | |||
1c112f3e4e | |||
2faf8aa003 | |||
643ac62788 | |||
d5e12c4d88 | |||
320d1787aa | |||
c7a4d9b027 | |||
bb1e7579d8 | |||
ba2ec36666 | |||
81fd1f3ebb | |||
8b5263db63 | |||
76f56434e8 | |||
9540b252a5 | |||
7a44e467f0 |
40
CHANGELOG.md
Normal file
40
CHANGELOG.md
Normal file
@ -0,0 +1,40 @@
|
||||
# Changelog
|
||||
## v0.3.3 (9)
|
||||
- Update about section with download and changelog information.
|
||||
- Improve high-res preview scraping.
|
||||
- Fix potential crash on calendar intent.
|
||||
## v0.3.2 (8)
|
||||
- Add german translation.
|
||||
- Decrease MinSDK to 23 (Android 6.0).
|
||||
- Replace Date implementation.
|
||||
- Enable Dark Mode for WebViews.
|
||||
- Add high-res preview for www prefix.
|
||||
## v0.3.1 (7)
|
||||
- Fix invalid default uri.
|
||||
- Update about section.
|
||||
## v0.3.0 (6)
|
||||
- Rework help and about.
|
||||
- Add settings with URL prefix selector.
|
||||
- Add Maps button for location.
|
||||
- Disable text field inputs - all fields can be edited in the calendar app.
|
||||
- Change date/time format to RFC standard.
|
||||
- Minor interface changes.
|
||||
- Code cleanup and refactoring.
|
||||
- Add code documentation.
|
||||
## v0.2.2 (5)
|
||||
- Fix for event links with querystrings.
|
||||
- New icon and banner as default toolbar image.
|
||||
## v0.2.1 (4)
|
||||
- Fixes for new design.
|
||||
- New button layout.
|
||||
- Improve input error display.
|
||||
## v0.2.0 (3)
|
||||
- Fix for timezone calculation.
|
||||
- Material design Interface, will be improved further.
|
||||
- Display the event picture in the toolbar.
|
||||
## v0.1.1 (2)
|
||||
- Added help and reports section.
|
||||
- Fix for some locations not scraped correctly.
|
||||
- Resolve fb-internal links.
|
||||
## v0.1.0 (1)
|
||||
- Initial release.
|
31
README.md
31
README.md
@ -1,20 +1,37 @@
|
||||

|
||||
[](https://github.com/akaessens/NoFbEventScraper/actions)
|
||||
[](https://github.com/akaessens/NoFbEventScraper/blob/master/LICENSE)
|
||||
[](https://github.com/akaessens/NoFbEventScraper/releases/latest)
|
||||
[](https://f-droid.org/en/packages/com.akdev.nofbeventscraper)
|
||||
|
||||
|
||||
<img src="https://github.com/akaessens/NoFbEventScraper/raw/master/fastlane/metadata/android/en-US/images/featureGraphic.png" alt="Feature Graphic" width="max-width">
|
||||
|
||||
# NoFb Event Scraper
|
||||
# Description
|
||||
|
||||
This application was developed to be used without a facebook account.
|
||||
This application was developed to be used without a Facebook account.
|
||||
|
||||
Therefore it does not use the facebook API.
|
||||
Instead it opens the facebook event URI and downloads the website source code.
|
||||
Therefore it does not use the Facebook API.
|
||||
Instead it opens the Facebook event URI and downloads the website source code.
|
||||
This source contains the information which is used to create a calendar entry.
|
||||
|
||||
# Download
|
||||
Currently this application is in the submitting process to FDroid. see also [#2](/../../issues/2).
|
||||
|
||||
Until it is published at FDroid, use [release v0.3.1](https://github.com/akaessens/NoFbEventScraper/releases/download/v0.3.1/app-release.apk).
|
||||
<a href="https://f-droid.org/en/packages/com.akdev.nofbeventscraper">
|
||||
<img src="https://fdroid.gitlab.io/artwork/badge/get-it-on.png" height="75">
|
||||
</a>
|
||||
|
||||
# Building
|
||||
|
||||
This Android app is written in Java and is using the Gradle build system. To compile it, i recommend using Android Studio.
|
||||
```
|
||||
./gradlew build
|
||||
```
|
||||
|
||||
# Screenshots
|
||||
|
||||
<img src="https://github.com/akaessens/NoFbEventScraper/raw/master/fastlane/metadata/android/en-US/images/phoneScreenshots/1.png" alt="Screenshot 1" width="200"> <img src="https://github.com/akaessens/NoFbEventScraper/raw/master/fastlane/metadata/android/en-US/images/phoneScreenshots/2.png" alt="Screenshot 2" width="200"> <img src="https://github.com/akaessens/NoFbEventScraper/raw/master/fastlane/metadata/android/en-US/images/phoneScreenshots/3.png" alt="Screenshot 3" width="200"> <img src="https://github.com/akaessens/NoFbEventScraper/raw/master/fastlane/metadata/android/en-US/images/phoneScreenshots/4.png" alt="Screenshot 4" width="200">
|
||||
|
||||
# Donations
|
||||
I develop this application in my free time. If you like it, you can donate at <a href="https://www.paypal.me/andreaskaessens">PayPal</a>.
|
||||
|
||||
<a title="PayPal" href="https://www.paypal.me/andreaskaessens"><img src="https://raw.githubusercontent.com/stefan-niedermann/paypal-donate-button/master/paypal-donate-button.png" height="75" /></a>
|
@ -6,10 +6,10 @@ android {
|
||||
|
||||
defaultConfig {
|
||||
applicationId "com.akdev.nofbeventscraper"
|
||||
minSdkVersion 26
|
||||
minSdkVersion 23
|
||||
targetSdkVersion 29
|
||||
versionCode 7
|
||||
versionName "0.3.1"
|
||||
versionCode 9
|
||||
versionName "0.3.3"
|
||||
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
}
|
||||
@ -30,7 +30,6 @@ dependencies {
|
||||
|
||||
implementation 'androidx.appcompat:appcompat:1.2.0'
|
||||
implementation 'com.google.android.material:material:1.2.0'
|
||||
implementation 'androidx.constraintlayout:constraintlayout:2.0.1'
|
||||
implementation 'androidx.navigation:navigation-fragment:2.3.0'
|
||||
implementation 'androidx.navigation:navigation-ui:2.3.0'
|
||||
|
||||
@ -40,6 +39,8 @@ dependencies {
|
||||
implementation 'com.squareup.picasso:picasso:2.71828'
|
||||
implementation 'androidx.preference:preference:1.1.1'
|
||||
|
||||
implementation "androidx.webkit:webkit:1.3.0"
|
||||
|
||||
testImplementation 'junit:junit:4.12'
|
||||
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
|
||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
|
||||
|
@ -42,15 +42,16 @@ public class ScraperUnitTest {
|
||||
|
||||
FbScraper scraper = new FbScraper(null, "");
|
||||
|
||||
String exp = "2020-10-23T05:00+02:00";
|
||||
String in = "2020-10-23T05:00:00+0200";
|
||||
String act = scraper.toZonedDateTime(in).toString();
|
||||
String in = "2020-01-01T12:00:00+0100";
|
||||
String exp = "Mi., 01 Jan. 2020 12:00 MEZ";
|
||||
|
||||
String act = FbEvent.dateTimeToString(scraper.parseToDate(in));
|
||||
assertEquals(exp, act);
|
||||
|
||||
|
||||
exp = null;
|
||||
exp = "";
|
||||
in = "";
|
||||
ZonedDateTime act2 = scraper.toZonedDateTime(in);
|
||||
String act2 = FbEvent.dateTimeToString(scraper.parseToDate(in));
|
||||
assertEquals(exp, act2);
|
||||
}
|
||||
|
||||
|
@ -32,8 +32,10 @@
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".MainActivity"
|
||||
android:launchMode="singleTop"
|
||||
android:label="@string/app_name"
|
||||
android:theme="@style/AppTheme.NoActionBar">
|
||||
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
|
@ -1,15 +1,13 @@
|
||||
package com.akdev.nofbeventscraper;
|
||||
|
||||
import android.content.res.Configuration;
|
||||
import android.os.Bundle;
|
||||
import android.webkit.WebView;
|
||||
|
||||
import androidx.appcompat.app.ActionBar;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.webkit.WebView;
|
||||
import android.widget.ImageView;
|
||||
import androidx.webkit.WebSettingsCompat;
|
||||
import androidx.webkit.WebViewFeature;
|
||||
|
||||
public class AboutActivity extends AppCompatActivity {
|
||||
|
||||
@ -24,7 +22,14 @@ public class AboutActivity extends AppCompatActivity {
|
||||
|
||||
WebView webview_about = findViewById(R.id.webview_about);
|
||||
|
||||
webview_about.loadUrl("file:////android_asset/about.html");
|
||||
int night_mode_flags = getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK;
|
||||
if (night_mode_flags == Configuration.UI_MODE_NIGHT_YES) {
|
||||
if (WebViewFeature.isFeatureSupported(WebViewFeature.FORCE_DARK)) {
|
||||
WebSettingsCompat.setForceDark(webview_about.getSettings(),
|
||||
WebSettingsCompat.FORCE_DARK_ON);
|
||||
}
|
||||
}
|
||||
webview_about.loadUrl("file:///android_res/raw/about.html");
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
package com.akdev.nofbeventscraper;
|
||||
|
||||
import java.time.ZonedDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.time.format.FormatStyle;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* Objects of this class store immutable information about
|
||||
@ -12,14 +12,14 @@ public class FbEvent {
|
||||
|
||||
public final String url;
|
||||
public final String name;
|
||||
public final ZonedDateTime start_date;
|
||||
public final ZonedDateTime end_date;
|
||||
public final Date start_date;
|
||||
public final Date end_date;
|
||||
public final String description;
|
||||
public final String location;
|
||||
public final String image_url;
|
||||
|
||||
|
||||
public FbEvent(String url, String name, ZonedDateTime start_date, ZonedDateTime end_date,
|
||||
public FbEvent(String url, String name, Date start_date, Date end_date,
|
||||
String description, String location, String image_url) {
|
||||
this.url = url;
|
||||
this.name = name;
|
||||
@ -33,28 +33,28 @@ public class FbEvent {
|
||||
/**
|
||||
* Converts datetime to epoch.
|
||||
*
|
||||
* @param zoned_date_time ZonedDateTime object
|
||||
* @param date Date object
|
||||
* @return Event begin time in milliseconds from the epoch for calendar intent or null
|
||||
*/
|
||||
static Long dateTimeToEpoch(ZonedDateTime zoned_date_time) {
|
||||
static Long dateTimeToEpoch(Date date) {
|
||||
try {
|
||||
return zoned_date_time.toEpochSecond() * 1000;
|
||||
return date.getTime();
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a RFC formatted String representation of a ZonedDateTime
|
||||
* Returns a locally formatted String representation of a Date
|
||||
*
|
||||
* @param zoned_date_time
|
||||
* @return RFC-1123 formatted String of zoned_date_time or empty String
|
||||
* @param date
|
||||
* @return locally formatted String of date or empty String
|
||||
*/
|
||||
static String dateTimeToString(ZonedDateTime zoned_date_time) {
|
||||
static String dateTimeToString(Date date) {
|
||||
try {
|
||||
return DateTimeFormatter
|
||||
.RFC_1123_DATE_TIME
|
||||
.format(zoned_date_time);
|
||||
SimpleDateFormat formatter = new SimpleDateFormat("E, dd MMM yyyy HH:mm z",
|
||||
Locale.getDefault());
|
||||
return formatter.format(date);
|
||||
} catch (Exception e) {
|
||||
return "";
|
||||
}
|
||||
|
@ -2,8 +2,6 @@ package com.akdev.nofbeventscraper;
|
||||
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.AsyncTask;
|
||||
import android.text.Editable;
|
||||
import android.text.SpannableStringBuilder;
|
||||
|
||||
import androidx.preference.PreferenceManager;
|
||||
|
||||
@ -17,8 +15,9 @@ import java.lang.ref.WeakReference;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.Locale;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
@ -28,7 +27,7 @@ import java.util.regex.Pattern;
|
||||
*/
|
||||
public class FbScraper extends AsyncTask<Void, Void, Void> {
|
||||
|
||||
private String error;
|
||||
private int error;
|
||||
private String input_url;
|
||||
private WeakReference<MainActivity> main; // no context leak with WeakReference
|
||||
private FbEvent event;
|
||||
@ -36,7 +35,7 @@ public class FbScraper extends AsyncTask<Void, Void, Void> {
|
||||
/**
|
||||
* Constructor with WeakReference to the main activity, to update it's text fields.
|
||||
*
|
||||
* @param main WeakReference of main activity to prevent context leak
|
||||
* @param main WeakReference of main activity to prevent context leak
|
||||
* @param input_url Input url to scrape from
|
||||
*/
|
||||
FbScraper(WeakReference<MainActivity> main, String input_url) {
|
||||
@ -49,7 +48,7 @@ public class FbScraper extends AsyncTask<Void, Void, Void> {
|
||||
*
|
||||
* @param url input url
|
||||
* @return facebook event url String if one was found
|
||||
* @throws URISyntaxException if event not found
|
||||
* @throws URISyntaxException if event not found
|
||||
* @throws MalformedURLException
|
||||
*/
|
||||
protected String fixURI(String url) throws URISyntaxException, MalformedURLException {
|
||||
@ -65,7 +64,7 @@ public class FbScraper extends AsyncTask<Void, Void, Void> {
|
||||
if (matcher.find()) {
|
||||
|
||||
String url_prefix = "https://m.";
|
||||
if (main != null){
|
||||
if (main != null) {
|
||||
SharedPreferences shared_prefs = PreferenceManager.getDefaultSharedPreferences(main.get());
|
||||
url_prefix = shared_prefs.getString("url_preference", url_prefix);
|
||||
}
|
||||
@ -75,7 +74,7 @@ public class FbScraper extends AsyncTask<Void, Void, Void> {
|
||||
if (matcher.group(2) != null) {
|
||||
ret += matcher.group(2);
|
||||
}
|
||||
return ret;
|
||||
return ret;
|
||||
} else {
|
||||
throw new URISyntaxException(url, "Does not contain event.");
|
||||
}
|
||||
@ -85,6 +84,7 @@ public class FbScraper extends AsyncTask<Void, Void, Void> {
|
||||
/**
|
||||
* Strips the event location from the json string.
|
||||
* This can be a name only or a complete postal address.
|
||||
*
|
||||
* @param location_json JSON formatted string
|
||||
* @return String representation of the location.
|
||||
*/
|
||||
@ -122,21 +122,18 @@ public class FbScraper extends AsyncTask<Void, Void, Void> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a time string from the facebook event.
|
||||
* Corrects format to ISO date time and parse into ZonedDateTime
|
||||
* Parses a time string from the facebook event into a Date
|
||||
*
|
||||
* @param time_in time string from the event
|
||||
* @return ZonedDateTime parsed from input or null
|
||||
* @return Date parsed from input or null
|
||||
*/
|
||||
protected ZonedDateTime toZonedDateTime(String time_in) {
|
||||
protected Date parseToDate(String time_in) {
|
||||
|
||||
try {
|
||||
// time in is missing a : in the timezone offset
|
||||
Editable editable = new SpannableStringBuilder(time_in);
|
||||
String time_str = editable.insert(22, ":").toString();
|
||||
// parse e.g. 2011-12-03T10:15:30+0100
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ", Locale.getDefault());
|
||||
|
||||
// parse e.g. 2011-12-03T10:15:30+01:00
|
||||
return ZonedDateTime.parse(time_str, DateTimeFormatter.ISO_OFFSET_DATE_TIME);
|
||||
return sdf.parse(time_in);
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
@ -168,8 +165,9 @@ public class FbScraper extends AsyncTask<Void, Void, Void> {
|
||||
|
||||
/**
|
||||
* Read a single field from a JSONObject
|
||||
*
|
||||
* @param reader JSONObject to read from
|
||||
* @param field Which field to read
|
||||
* @param field Which field to read
|
||||
* @return String of the value of the field or empty string
|
||||
*/
|
||||
private String readFromJson(JSONObject reader, String field) {
|
||||
@ -184,6 +182,7 @@ public class FbScraper extends AsyncTask<Void, Void, Void> {
|
||||
/**
|
||||
* Started by scraper.execute().
|
||||
* Gets the HTML doc from the input string and scrapes the event information from it.
|
||||
*
|
||||
* @param voids
|
||||
* @return
|
||||
*/
|
||||
@ -192,8 +191,8 @@ public class FbScraper extends AsyncTask<Void, Void, Void> {
|
||||
|
||||
try {
|
||||
String url = fixURI(input_url);
|
||||
// use correct system user agent because of facebook ToS
|
||||
String user_agent = System.getProperty("http.agent");
|
||||
// use default android user agent
|
||||
String user_agent = "Mozilla/5.0 (X11; Linux x86_64)";
|
||||
Document document = Jsoup.connect(url).userAgent(user_agent).get();
|
||||
|
||||
if (document == null) {
|
||||
@ -205,28 +204,39 @@ public class FbScraper extends AsyncTask<Void, Void, Void> {
|
||||
|
||||
JSONObject reader = new JSONObject(json);
|
||||
|
||||
event = new FbEvent(
|
||||
url,
|
||||
readFromJson(reader, "name"),
|
||||
toZonedDateTime(readFromJson(reader, "startDate")),
|
||||
toZonedDateTime(readFromJson(reader, "endDate")),
|
||||
fixDescriptionLinks(readFromJson(reader, "description")),
|
||||
fixLocation(readFromJson(reader, "location")),
|
||||
readFromJson(reader, "image")
|
||||
);
|
||||
|
||||
String name = readFromJson(reader, "name");
|
||||
Date start_date = parseToDate(readFromJson(reader, "startDate"));
|
||||
Date end_date = parseToDate(readFromJson(reader, "endDate"));
|
||||
String description = fixDescriptionLinks(readFromJson(reader, "description"));
|
||||
String location = fixLocation(readFromJson(reader, "location"));
|
||||
|
||||
String image_url = readFromJson(reader, "image"); // get from json
|
||||
|
||||
try {
|
||||
// possibly get higher res image from event header
|
||||
image_url = document.select("div[id=event_header_primary]")
|
||||
.select("img").first().attr("src");
|
||||
|
||||
} catch (Exception e) {
|
||||
// ignore
|
||||
}
|
||||
|
||||
event = new FbEvent(url, name, start_date, end_date, description, location, image_url);
|
||||
|
||||
|
||||
} catch (URISyntaxException | MalformedURLException e) {
|
||||
e.printStackTrace();
|
||||
this.error = "Error: URL invalid.";
|
||||
this.error = R.string.error_url;
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
this.error = "Error: Scraping event data failed";
|
||||
this.error = R.string.error_scraping;
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
this.error = "Error: Unable to connect.";
|
||||
this.error = R.string.error_connection;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
this.error = "Error: Unknown Error.";
|
||||
this.error = R.string.error_unknown;
|
||||
}
|
||||
|
||||
return null;
|
||||
@ -240,6 +250,7 @@ public class FbScraper extends AsyncTask<Void, Void, Void> {
|
||||
/**
|
||||
* When scraping is finished, main activity will be updated.
|
||||
* If an error occurred, main activity is given an error string.
|
||||
*
|
||||
* @param aVoid
|
||||
*/
|
||||
protected void onPostExecute(Void aVoid) {
|
||||
|
@ -1,10 +1,13 @@
|
||||
package com.akdev.nofbeventscraper;
|
||||
|
||||
import android.content.res.Configuration;
|
||||
import android.os.Bundle;
|
||||
import android.webkit.WebView;
|
||||
|
||||
import androidx.appcompat.app.ActionBar;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.webkit.WebSettingsCompat;
|
||||
import androidx.webkit.WebViewFeature;
|
||||
|
||||
public class HelpActivity extends AppCompatActivity {
|
||||
|
||||
@ -19,7 +22,17 @@ public class HelpActivity extends AppCompatActivity {
|
||||
|
||||
WebView webview_help = findViewById(R.id.webview_help);
|
||||
|
||||
webview_help.loadUrl("file:////android_asset/help.html");
|
||||
int night_mode_flags = getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK;
|
||||
if (night_mode_flags == Configuration.UI_MODE_NIGHT_YES) {
|
||||
if (WebViewFeature.isFeatureSupported(WebViewFeature.FORCE_DARK)) {
|
||||
WebSettingsCompat.setForceDark(webview_help.getSettings(),
|
||||
WebSettingsCompat.FORCE_DARK_ON);
|
||||
}
|
||||
}
|
||||
|
||||
webview_help.loadUrl("file:////android_res/raw/help.html");
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
package com.akdev.nofbeventscraper;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.ClipboardManager;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
@ -111,15 +112,17 @@ public class MainActivity extends AppCompatActivity {
|
||||
|
||||
try {
|
||||
ClipboardManager clipboard = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
|
||||
String str = clipboard.getPrimaryClip().getItemAt(0).getText().toString();
|
||||
String str = Objects.requireNonNull(clipboard.getPrimaryClip())
|
||||
.getItemAt(0).getText().toString();
|
||||
|
||||
clear(true);
|
||||
edit_text_uri_input.setText(str);
|
||||
} catch (NullPointerException e) {
|
||||
|
||||
startScraping();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
error("Error: Clipboard empty");
|
||||
error(R.string.error_clipboard_empty);
|
||||
}
|
||||
startScraping();
|
||||
}
|
||||
});
|
||||
|
||||
@ -171,7 +174,10 @@ public class MainActivity extends AppCompatActivity {
|
||||
// prepend url in description
|
||||
String desc = event.url + "\n\n" + event.description;
|
||||
intent.putExtra(CalendarContract.Events.DESCRIPTION, desc);
|
||||
startActivity(intent);
|
||||
|
||||
if (intent.resolveActivity(getPackageManager()) != null) {
|
||||
startActivity(intent);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@ -222,8 +228,13 @@ public class MainActivity extends AppCompatActivity {
|
||||
scraper.execute();
|
||||
}
|
||||
|
||||
public void error(String str) {
|
||||
layout_uri_input.setError(str);
|
||||
public void error(Integer resId) {
|
||||
if (resId != null) {
|
||||
layout_uri_input.setError(getString(resId));
|
||||
} else {
|
||||
layout_uri_input.setError(null);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -276,34 +287,34 @@ public class MainActivity extends AppCompatActivity {
|
||||
edit_text_uri_input.setText(event.url);
|
||||
|
||||
if (event.name.equals("")) {
|
||||
edit_text_event_name.setError("no event name detected");
|
||||
edit_text_event_name.setError(getString(R.string.error_no_name));
|
||||
} else {
|
||||
edit_text_event_name.setText(event.name);
|
||||
}
|
||||
|
||||
if (event.start_date == null) {
|
||||
edit_text_event_start.setError("no event start date detected");
|
||||
edit_text_event_start.setError(getString(R.string.error_no_start_date));
|
||||
} else {
|
||||
String str = FbEvent.dateTimeToString(event.start_date);
|
||||
edit_text_event_start.setText(str);
|
||||
}
|
||||
|
||||
if (event.end_date == null) {
|
||||
edit_text_event_end.setError("no event end date detected");
|
||||
edit_text_event_end.setError(getString(R.string.error_no_end_date));
|
||||
} else {
|
||||
String str = FbEvent.dateTimeToString(event.end_date);
|
||||
edit_text_event_end.setText(str);
|
||||
}
|
||||
|
||||
if (event.location.equals("")) {
|
||||
edit_text_event_location.setError("no event location detected");
|
||||
edit_text_event_location.setError(getString(R.string.error_no_location));
|
||||
} else {
|
||||
edit_text_event_location.setText(event.location);
|
||||
layout_event_location.setEndIconVisible(true);
|
||||
}
|
||||
|
||||
if (event.description.equals("")) {
|
||||
edit_text_event_description.setError("no event description detected");
|
||||
edit_text_event_description.setError(getString(R.string.error_no_description));
|
||||
} else {
|
||||
edit_text_event_description.setText(event.description);
|
||||
}
|
||||
@ -317,12 +328,13 @@ public class MainActivity extends AppCompatActivity {
|
||||
}
|
||||
|
||||
|
||||
@SuppressLint("RestrictedApi")
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
// Inflate the menu; this adds items to the action bar if it is present.
|
||||
getMenuInflater().inflate(R.menu.menu_main, menu);
|
||||
|
||||
if(menu instanceof MenuBuilder){
|
||||
if (menu instanceof MenuBuilder) {
|
||||
MenuBuilder m = (MenuBuilder) menu;
|
||||
//noinspection RestrictedApi
|
||||
m.setOptionalIconsVisible(true);
|
||||
|
@ -1,15 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:context=".AboutActivity">
|
||||
|
||||
|
||||
<WebView
|
||||
android:id="@+id/webview_about"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</RelativeLayout>
|
@ -1,15 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:context=".HelpActivity">
|
||||
|
||||
|
||||
<WebView
|
||||
android:id="@+id/webview_help"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</RelativeLayout>
|
@ -59,7 +59,9 @@
|
||||
app:layout_anchor="@id/app_bar"
|
||||
app:layout_anchorGravity="bottom|end"
|
||||
app:icon="@drawable/ic_content_paste"
|
||||
android:text="@string/paste_button"/>
|
||||
android:text="@android:string/paste"
|
||||
android:tooltipText="@string/tooltip_paste"
|
||||
tools:ignore="UnusedAttribute" />
|
||||
|
||||
<include layout="@layout/content_main" />
|
||||
|
||||
@ -80,7 +82,7 @@
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_weight="1"
|
||||
android:padding="12dp"
|
||||
android:text="@string/add_to_calendar"
|
||||
android:text="@string/button_add"
|
||||
android:textColor="#FFFFFF"
|
||||
app:cornerRadius="24dp"
|
||||
app:icon="@drawable/ic_event_available"
|
||||
|
@ -37,7 +37,7 @@
|
||||
app:errorIconDrawable="@drawable/ic_backspace_black"
|
||||
app:endIconMode="custom"
|
||||
|
||||
app:helperText="@string/add_link_helper"
|
||||
app:helperText="@string/helper_add_link"
|
||||
app:helperTextEnabled="true">
|
||||
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
@ -46,7 +46,7 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:autoLink="web"
|
||||
android:cursorVisible="true"
|
||||
android:hint="@string/add_link_hint"
|
||||
android:hint="@string/hint_add_link"
|
||||
android:inputType="textNoSuggestions"
|
||||
android:singleLine="true"
|
||||
android:textColorLink="@color/material_on_background_emphasis_high_type" />
|
||||
@ -63,7 +63,7 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:focusable="false"
|
||||
android:cursorVisible="false"
|
||||
android:hint="Event name"
|
||||
android:hint="@string/hint_event_name"
|
||||
android:inputType="textNoSuggestions"
|
||||
android:singleLine="true"
|
||||
android:textColorLink="@color/material_on_background_emphasis_high_type" />
|
||||
@ -80,7 +80,7 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:focusable="false"
|
||||
android:cursorVisible="false"
|
||||
android:hint="Event start"
|
||||
android:hint="@string/hint_event_start"
|
||||
android:inputType="textNoSuggestions"
|
||||
android:singleLine="true" />
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
@ -96,7 +96,7 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:focusable="false"
|
||||
android:cursorVisible="false"
|
||||
android:hint="Event end"
|
||||
android:hint="@string/hint_event_end"
|
||||
android:inputType="textNoSuggestions"
|
||||
android:singleLine="true" />
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
@ -114,10 +114,9 @@
|
||||
android:id="@+id/edit_text_event_location"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:autoLink="map"
|
||||
android:focusable="false"
|
||||
android:cursorVisible="false"
|
||||
android:hint="Event location"
|
||||
android:hint="@string/hint_event_location"
|
||||
android:inputType="textNoSuggestions"
|
||||
android:singleLine="true" />
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
@ -134,7 +133,7 @@
|
||||
android:autoLink="web"
|
||||
android:focusable="false"
|
||||
android:cursorVisible="false"
|
||||
android:hint="Event description"
|
||||
android:hint="@string/hint_event_description"
|
||||
android:inputType="textNoSuggestions|textMultiLine"
|
||||
android:singleLine="false"
|
||||
android:textColorLink="@color/material_on_background_emphasis_high_type" />
|
||||
|
14
app/src/main/res/raw-de/about.html
Normal file
14
app/src/main/res/raw-de/about.html
Normal file
@ -0,0 +1,14 @@
|
||||
<!doctype html>
|
||||
<h3>Beschreibung</h3>
|
||||
<p>Diese Anwendung wurde entwickelt, um ohne ein Facebook-Konto verwendet werden zu können. Daher verwendet sie nicht die Facebook-API. Stattdessen öffnet sie die URI der Facebook-Veranstaltung und lädt den Quellcode der Website herunter. Dieser Quellcode enthält die Informationen, die zum Erstellen eines Kalendereintrags verwendet werden.</p>
|
||||
<h3>Open Source</h3>
|
||||
<p>Der Quellcode für diese Anwendung ist bei <a href=" https://github.com/akaessens/NoFbEventScraper">GitHub</a> verfügbar.<strong><br /></strong></p>
|
||||
<p>Wenn Sie auf ein Problem stoßen, melden Sie es mir bitte anonym über den <a href="https://gitreports.com/issue/akaessens/NoFbEventScraper">Bugtracker</a> oder direkt bei <a href="https://github.com/akaessens/NoFbEventScraper/issues">GitHub</a>.</p>
|
||||
<h3>Updates</h3>
|
||||
<p>Diese App ist bei <a href="https://f-droid.org/de/packages/com.akdev.nofbeventscraper">F-Droid</a> zum Download verfügbar. Das Änderungsprotokoll ist auf <a href="https://github.com/akaessens/NoFbEventScraper/blob/master/CHANGELOG.md">GitHub</a> verfügbar.</p>
|
||||
<p><a href="https://f-droid.org/en/packages/com.akdev.nofbeventscraper"> <img src="https://fdroid.gitlab.io/artwork/badge/get-it-on.png" height="75" /> </a></p>
|
||||
<h3>Rechtliches</h3>
|
||||
<p>Diese Anwendung ist für das Speichern einzelner, öffentlich zugänglicher Veranstaltungen in einem persönlichen Kalender vorgesehen. Verwenden Sie sie nicht zur automatischen Datenerfassung und halten Sie sich an die <a href="http://www.facebook.com/apps/site_scraping_tos_terms.php">Bedingungen für die automatische Datenerfassung</a> von Facebook.</p>
|
||||
<h3>Spenden</h3>
|
||||
<p>Ich entwickle diese Anwendung in meiner Freizeit. Wenn sie Ihnen gefällt, können Sie bei <a href="https://www.paypal.me/andreaskaessens">PayPal</a> spenden.</p>
|
||||
<p><a title="PayPal" href="https://www.paypal.me/andreaskaessens"><img src="https://raw.githubusercontent.com/stefan-niedermann/paypal-donate-button/master/paypal-donate-button.png" height="75" /></a></p>
|
14
app/src/main/res/raw-de/help.html
Normal file
14
app/src/main/res/raw-de/help.html
Normal file
@ -0,0 +1,14 @@
|
||||
<!doctype html>
|
||||
<h3>Welche Links können mit dieser App verwendet werden?</h3>
|
||||
<p>Alle Facebook-Subdomains werden unterstützt, ob mobil (m.facebook.com) oder sprachspezifisch (de-de.facebook.com). Der Link muss eine Ereignis-ID enthalten.<br />Wie kann diese Anwendung verwendet werden?</p>
|
||||
<h3>Wie kann diese Anwendung verwendet werden?</h3>
|
||||
<ul>
|
||||
<li><strong>Einfügen-Knopf</strong>: Fügen Sie einen kopierten Link aus der Zwischenablage in die URL-Leiste ein.</li>
|
||||
<li><strong>Teilen mit</strong>: Eingebaute Android-Freigabefunktion, z.B. von einem Browser aus.</li>
|
||||
<li><strong>Öffnen mit</strong>: Die in Android eingebaute öffnen-mit-Funktion, z.B. beim Klicken auf einen Link in einem Messenger.</li>
|
||||
</ul>
|
||||
<h3>Warum funktioniert die Veranstaltung X nicht?</h3>
|
||||
<p>Diese Anwendung greift auf öffentlich zugängliche Ereignisinformationen zu. Wenn die Veranstaltung z.B. den Ort ohne Login nicht anbietet, ist dies in dieser Anwendung nicht verfügbar. Auch bieten einige Veranstaltungen die Informationen einfach nicht in einem maschinenlesbaren Format an. Veranstaltungen mit mehreren Instanzen sind problematisch, da sie beim Scraping von m.facebook.com nicht das korrekte Start- und Enddatum angeben.</p>
|
||||
<p>Wenn Sie Probleme mit einem bestimmten Ereignis haben, lassen Sie es mich bitte über den <a href="https://gitreports.com/issue/akaessens/NoFbEventScraper">anonymen Bugtracker</a> oder auf der <a href="https://github.com/akaessens/NoFbEventScraper/issues/">GitHub Problemseite</a>.</p>
|
||||
<h3>Ist diese App kompatibel mit meinem Kalender?</h3>
|
||||
<p>Ja. Diese Anwendung verwendet anwendungsunabhängige Kalenderfunktionen, wodurch sie mit jeder Kalenderanwendung kompatibel ist. Ich empfehle jedoch den <a href="https://play.google.com/store/apps/details?id=ws.xsoh.etar">Etar Kalender</a>, da er Open Source ist. </p>
|
@ -1,11 +1,14 @@
|
||||
<!doctype html>
|
||||
<h3>Description</h3>
|
||||
<p>This application was developed to be used without a facebook account. Therefore it does not use the facebook API. Instead it opens the facebook event URI and downloads the website source code. This source contains the information which is used to create a calendar entry.</p>
|
||||
<p>This application was developed to be used without a Facebook account. Therefore it does not use the Facebook API. Instead it opens the Facebook event URI and downloads the website source code. This source contains the information which is used to create a calendar entry.</p>
|
||||
<h3>Open Source</h3>
|
||||
<p>The source code for this application is available at <a href=" https://github.com/akaessens/NoFbEventScraper">GitHub</a>.<strong><br /></strong></p>
|
||||
<p>If you encounter an issue, please report it to me anonymously at the <a href="https://gitreports.com/issue/akaessens/NoFbEventScraper">Bugtracker</a> or directly at <a href="https://github.com/akaessens/NoFbEventScraper/issues">GitHub</a>.</p>
|
||||
<h3>Updates</h3>
|
||||
<p>This application is available for download at <a href="https://f-droid.org/de/packages/com.akdev.nofbeventscraper">F-Droid</a>. The changelog is at <a href="https://github.com/akaessens/NoFbEventScraper/blob/master/CHANGELOG.md">GitHub</a>.</p>
|
||||
<p><a href="https://f-droid.org/en/packages/com.akdev.nofbeventscraper"> <img src="https://fdroid.gitlab.io/artwork/badge/get-it-on.png" height="75" /> </a></p>
|
||||
<h3>Legal</h3>
|
||||
<p>This application is intended for saving single, publicly available events into a personal calendar. Do not use it to automatically collect data and comply with facebook's <a href="http://www.facebook.com/apps/site_scraping_tos_terms.php">Automated Data Collection Terms</a>.</p>
|
||||
<p>This application is intended for saving single, publicly available events into a personal calendar. Do not use it to automatically collect data and comply with Facebook's <a href="http://www.facebook.com/apps/site_scraping_tos_terms.php">Automated Data Collection Terms</a>.</p>
|
||||
<h3>Donations</h3>
|
||||
<p>I develop this application in my free time. If you like it, you can donate at <a href="https://www.paypal.me/andreaskaessens">PayPal</a>.</p>
|
||||
<p><a title="PayPal" href="https://www.paypal.me/andreaskaessens"><img src="https://www.paypalobjects.com/webstatic/de_DE/i/de-pp-logo-100px.png" /></a></p>
|
||||
<p><a title="PayPal" href="https://www.paypal.me/andreaskaessens"><img src="https://raw.githubusercontent.com/stefan-niedermann/paypal-donate-button/master/paypal-donate-button.png" height="75" /></a></p>
|
@ -8,7 +8,7 @@
|
||||
<li><strong>Open with</strong>: Android's built-in open-with-function, e.g. when clicking on a link in a messenger.</li>
|
||||
</ul>
|
||||
<h3>Why does event X not work?</h3>
|
||||
<p>This app relies on event information that is publicy available. If the event does not offer for example the location without a login, it will not be available in this application. Events with multiple instances are problematic because they do not provide the correct start and end date when scraping from m.facebook.com.</p>
|
||||
<p>This app relies on event information that is publicly available. If the event does not offer for example the location without a login, it will not be available in this application. Also, some events just do not provide the information in a machine readable format. Events with multiple instances are problematic because they do not provide the correct start and end date when scraping from m.facebook.com.</p>
|
||||
<p>If you encounter issues with a specific event, please let me know via the <a href="https://gitreports.com/issue/akaessens/NoFbEventScraper">anonymous bugtracker</a> or at the <a href="https://github.com/akaessens/NoFbEventScraper/issues/">GitHub issue page</a>.</p>
|
||||
<h3>Is this compatible with my calendar app?</h3>
|
||||
<p>Yes. This application makes use of application independent calendar functions, which makes it compatible to every calendar app. However, i recommend <a href="https://play.google.com/store/apps/details?id=ws.xsoh.etar&hl=de">Etar Calendar</a> because it is Open Source.</p>
|
||||
<p>Yes. This application makes use of application independent calendar functions, which makes it compatible to every calendar app. However, i recommend <a href="https://play.google.com/store/apps/details?id=ws.xsoh.etar">Etar Calendar</a> because it is Open Source.</p>
|
28
app/src/main/res/values-de/strings.xml
Normal file
28
app/src/main/res/values-de/strings.xml
Normal file
@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="app_name">NoFb Event Scraper</string>
|
||||
<string name="action_about">Über</string>
|
||||
<string name="action_help">Hilfe</string>
|
||||
<string name="action_settings">Einstellungen</string>
|
||||
<string name="hint_add_link">Veranstaltungslink</string>
|
||||
<string name="hint_event_name">Veranstaltungsname</string>
|
||||
<string name="hint_event_start">Veranstaltungsbeginn</string>
|
||||
<string name="hint_event_end">Veranstantungsende</string>
|
||||
<string name="hint_event_location">Veranstaltungsort</string>
|
||||
<string name="hint_event_description">Veranstaltungsbeschreibung</string>
|
||||
<string name="helper_add_link">Facebook-Link zur Veranstaltung einfügen</string>
|
||||
<string name="button_add">Zum Kalender hinzufügen</string>
|
||||
<string name="tooltip_paste">Einfügen von Inhalten aus der Zwischenablage in das URL-Eingabefeld</string>
|
||||
<string name="preferences_url_setting">Welcher URL-Präfix ist zu verwenden?</string>
|
||||
<string name="preferences_url_setting_summary">Die Nutzung von m.facebook.com ist stabiler und schneller. Die Verwendung von www.facebook.com funktioniert besser bei Ereignissen mit mehreren Instanzen und zeigt eine hochauflösende Vorschau an, geht aber irgendwann kaputt, wenn Facebook das klassische Design deaktiviert.</string>
|
||||
<string name="error_clipboard_empty">Fehler: Zwischenablage leer</string>
|
||||
<string name="error_no_name">Fehler: Veranstaltungsname nicht verfügbar</string>
|
||||
<string name="error_no_start_date">Fehler: Veranstaltungsbeginn nicht verfügbar</string>
|
||||
<string name="error_no_end_date">Fehler: Veranstaltungsende nicht verfügbar</string>
|
||||
<string name="error_no_location">Fehler: Veranstaltungsort nicht verfügbar</string>
|
||||
<string name="error_no_description">Fehler: Veranstaltungsbeschreibung nicht verfügbar</string>
|
||||
<string name="error_scraping">Fehler: Veranstaltungsdaten nicht gefunden</string>
|
||||
<string name="error_url">Fehler: URL ungültig</string>
|
||||
<string name="error_connection">Fehler: Keine Verbindung möglich</string>
|
||||
<string name="error_unknown">Fehler: Unbekannter Fehler</string>
|
||||
</resources>
|
@ -1,19 +1,42 @@
|
||||
<resources>
|
||||
<string name="app_name">NoFb Event Scraper</string>
|
||||
|
||||
<!-- Action names -->
|
||||
<string name="action_about">About</string>
|
||||
<string name="action_help">Help</string>
|
||||
<string name="action_settings">Settings</string>
|
||||
<string name="add_link_hint">Event link</string>
|
||||
<string name="add_link_helper">Paste facebook link to the event.</string>
|
||||
<string name="add_to_calendar">Add to calendar</string>
|
||||
<string name="paste_button">Paste from clipboard</string>
|
||||
|
||||
<!-- Preference Titles -->
|
||||
<string name="scraper_header">Scraper</string>
|
||||
<!-- Input hints -->
|
||||
<string name="hint_add_link">Event link</string>
|
||||
<string name="hint_event_name">Event name</string>
|
||||
<string name="hint_event_start">Event start</string>
|
||||
<string name="hint_event_end">Event end</string>
|
||||
<string name="hint_event_location">Event location</string>
|
||||
<string name="hint_event_description">Event description</string>
|
||||
|
||||
|
||||
<string name="helper_add_link">Paste Facebook link to the event</string>
|
||||
<string name="button_add">Add to calendar</string>
|
||||
<string name="tooltip_paste">Paste content from clipboard into the URL input box</string>
|
||||
|
||||
<!-- Errors -->
|
||||
<string name="error_clipboard_empty">Error: clipboard empty</string>
|
||||
<string name="error_no_name">Error: Event name unavailable</string>
|
||||
<string name="error_no_start_date">Error: Event start date unavailable</string>
|
||||
<string name="error_no_end_date">Error: Event end date unavailable</string>
|
||||
<string name="error_no_location">Error: Event location unavailable</string>
|
||||
<string name="error_no_description">Error: Event description unavailable</string>
|
||||
<string name="error_scraping">Error: Scraping event data failed</string>
|
||||
<string name="error_url">Error: URL invalid</string>
|
||||
<string name="error_connection">Error: Unable to connect</string>
|
||||
<string name="error_unknown">Error: Unknown Error</string>
|
||||
|
||||
<!-- Preferences -->
|
||||
<string name="preferences_scraper_header" translatable="false">Scraper</string>
|
||||
|
||||
<string name="preferences_url_setting">Which URL prefix to use</string>
|
||||
<string name="preferences_url_setting_summary">"Using m.facebook.com is more stable and faster. Using www.facebook.com works better with multiple instance events and will display a high resolution preview but will eventually break when Facebook disables the classic design. "</string>
|
||||
|
||||
|
||||
<string name="url_setting">Which URL to scrape</string>
|
||||
<string name="url_setting_summary">
|
||||
Using m.facebook.com is more stable and faster. Using www.facebook.com works better with multiple instance events but will eventually break when facebook disables the classic design.
|
||||
</string>
|
||||
|
||||
</resources>
|
||||
|
@ -1,7 +1,7 @@
|
||||
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<PreferenceCategory app:title="@string/scraper_header">
|
||||
<PreferenceCategory app:title="@string/preferences_scraper_header">
|
||||
|
||||
|
||||
<ListPreference
|
||||
@ -9,8 +9,8 @@
|
||||
app:entries="@array/url_to_scrape"
|
||||
app:entryValues="@array/url_prefix"
|
||||
app:key="url_preference"
|
||||
app:title="@string/url_setting"
|
||||
android:summary="@string/url_setting_summary"/>
|
||||
app:title="@string/preferences_url_setting"
|
||||
android:summary="@string/preferences_url_setting_summary"/>
|
||||
|
||||
|
||||
|
||||
|
21
create_changelog.sh
Executable file
21
create_changelog.sh
Executable file
@ -0,0 +1,21 @@
|
||||
#!/bin/bash
|
||||
|
||||
changelog_location="fastlane/metadata/android/en-US/changelogs"
|
||||
count_txt=$(ls -r $changelog_location/*.txt | wc -l)
|
||||
count_tag=$(git tag | wc -l)
|
||||
|
||||
if (( count_txt != count_tag )); then
|
||||
echo "Tag count and txt-file count not matching."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "# Changelog" > CHANGELOG.md
|
||||
|
||||
for i in $(seq "$count_txt" -1 1)
|
||||
do
|
||||
tag=$(git tag | sed "$i!d")
|
||||
|
||||
echo "## $tag ($i)" >> CHANGELOG.md
|
||||
cat $changelog_location/"$i".txt >> CHANGELOG.md
|
||||
|
||||
done
|
4
fastlane/metadata/android/de/full_description.txt
Normal file
4
fastlane/metadata/android/de/full_description.txt
Normal file
@ -0,0 +1,4 @@
|
||||
Diese Anwendung wurde entwickelt, um ohne ein Facebook-Konto verwendet werden zu können.
|
||||
Daher verwendet sie nicht die Facebook-API.
|
||||
Stattdessen öffnet sie die URI der Facebook-Veranstaltung und lädt den Quellcode der Website herunter.
|
||||
Dieser Quellcode enthält die Informationen, die zum Erstellen eines Kalendereintrags verwendet werden.
|
1
fastlane/metadata/android/de/short_description.txt
Normal file
1
fastlane/metadata/android/de/short_description.txt
Normal file
@ -0,0 +1 @@
|
||||
Diese App durchsucht Facebook-Veranstaltungslinks und fügt sie zu deinem Kalender hinzu.
|
@ -1 +1 @@
|
||||
Initial release.
|
||||
- Initial release.
|
||||
|
@ -1,3 +1,3 @@
|
||||
Added help and reports section.
|
||||
Fix for some locations not scraped correctly.
|
||||
Resolve fb-internal links.
|
||||
- Added help and reports section.
|
||||
- Fix for some locations not scraped correctly.
|
||||
- Resolve fb-internal links.
|
||||
|
@ -1,3 +1,3 @@
|
||||
Fix for timezone calculation.
|
||||
Material design Interface, will be improved further.
|
||||
Display the event picture in the toolbar.
|
||||
- Fix for timezone calculation.
|
||||
- Material design Interface, will be improved further.
|
||||
- Display the event picture in the toolbar.
|
||||
|
@ -1,3 +1,3 @@
|
||||
Fixes for new design.
|
||||
New button layout.
|
||||
Improve input error display.
|
||||
- Fixes for new design.
|
||||
- New button layout.
|
||||
- Improve input error display.
|
||||
|
@ -1,2 +1,2 @@
|
||||
Fix for event links with querystrings.
|
||||
New icon and banner as default toolbar image.
|
||||
- Fix for event links with querystrings.
|
||||
- New icon and banner as default toolbar image.
|
||||
|
@ -1,8 +1,8 @@
|
||||
Rework help and about.
|
||||
Add settings with URL prefix selector.
|
||||
Add Maps button for location.
|
||||
Disable text field inputs - all fields can be edited in the calendar app.
|
||||
Change date/time format to RFC standard.
|
||||
Minor interface changes.
|
||||
Code cleanup and refactoring.
|
||||
Add code documentation.
|
||||
- Rework help and about.
|
||||
- Add settings with URL prefix selector.
|
||||
- Add Maps button for location.
|
||||
- Disable text field inputs - all fields can be edited in the calendar app.
|
||||
- Change date/time format to RFC standard.
|
||||
- Minor interface changes.
|
||||
- Code cleanup and refactoring.
|
||||
- Add code documentation.
|
||||
|
@ -1,2 +1,2 @@
|
||||
Fix invalid default uri.
|
||||
Update about section.
|
||||
- Fix invalid default uri.
|
||||
- Update about section.
|
||||
|
5
fastlane/metadata/android/en-US/changelogs/8.txt
Normal file
5
fastlane/metadata/android/en-US/changelogs/8.txt
Normal file
@ -0,0 +1,5 @@
|
||||
- Add german translation.
|
||||
- Decrease MinSDK to 23 (Android 6.0).
|
||||
- Replace Date implementation.
|
||||
- Enable Dark Mode for WebViews.
|
||||
- Add high-res preview for www prefix.
|
3
fastlane/metadata/android/en-US/changelogs/9.txt
Normal file
3
fastlane/metadata/android/en-US/changelogs/9.txt
Normal file
@ -0,0 +1,3 @@
|
||||
- Update about section with download and changelog information.
|
||||
- Improve high-res preview scraping.
|
||||
- Fix potential crash on calendar intent.
|
@ -1,4 +1,4 @@
|
||||
This application was developed to be used without a facebook account.
|
||||
Therefore it does not use the facebook API.
|
||||
Instead it opens the facebook event URI and downloads the website source code.
|
||||
This source contains the information which is used to create a calendar entry.
|
||||
This application was developed to be used without a Facebook account.
|
||||
Therefore it does not use the Facebook API.
|
||||
Instead it opens the Facebook event URI and downloads the website source code.
|
||||
This source contains the information which is used to create a calendar entry.
|
Binary file not shown.
Before Width: | Height: | Size: 82 KiB After Width: | Height: | Size: 82 KiB |
Binary file not shown.
Before Width: | Height: | Size: 92 KiB After Width: | Height: | Size: 629 KiB |
Binary file not shown.
Before Width: | Height: | Size: 484 KiB After Width: | Height: | Size: 84 KiB |
@ -1 +1 @@
|
||||
This app scrapes facebook event links and adds the event to your calendar.
|
||||
This app scrapes Facebook event links and adds the event to your calendar.
|
||||
|
Reference in New Issue
Block a user