First commit

This commit is contained in:
LubuWest 2015-11-27 21:24:25 +01:00
parent 0781b382c1
commit 1986e59b58
7 changed files with 858 additions and 0 deletions

9
README.md Normal file
View file

@ -0,0 +1,9 @@
## Friendica#
## Screenshot ##
![screenshot]()
## Details ##
Friendica Client with Javascript and QML in an early stage

BIN
Source/Update.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 810 B

256
Source/service.js Normal file
View file

@ -0,0 +1,256 @@
function friendicaRequest(url,user,password,api,callback) {
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (xhr.readyState === XMLHttpRequest.HEADERS_RECEIVED) {
} else if(xhr.readyState === XMLHttpRequest.DONE) {
try{ callback(xhr.responseText);
}
catch (e){
print("friendicaRequest: Data retrieval failure! "+ e);
}
}
}
xhr.open("GET", url+api,false,user,password);
xhr.send();
}
function requestFriends(url,user,password,database,callback){
friendicaRequest(url,user,password,"/api/statuses/friends", function (obj){
var friends=JSON.parse(obj);
for (var i=0;i<friends.length;i++){
var db=LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]);
print('store friends data for ' + friends[i].name);
db.transaction( function(tx) {
var result = tx.executeSql('SELECT * from contacts where id = "'+obj[i].id+'"'); // check for user id
if(result.rows.length === 1) {// use update
print(list[i].id +' exists, update it')
result = tx.executeSql('UPDATE contacts SET id="'+friends[i].id+'", name="'+friends[i].name+'", screen_name="'+friends[i].screen_name+'", location="'+friends[i].location+'", description="'+friends[i].description+'", profile_image="'+getBase64Image(friends[i].profile_image_url)+'", url="'+friends[i].url+'", protected="'+friends[i].protected+'", followers_count="'+friends[i].followers_count+'", friends_count="'+friends[i].friends_count+'", created_at="'+friends[i].created_at+'", favourites_count="'+friends[i].favourites_count+'", utc_offset="'+ friends[i].utc_offset+'", time_zone="'+friends[i].time_zone+'",statuses_count="' +friends[i].statuses_count+'", following="'+friends[i].following+'", verified="'+friends[i].verified+'", statusnet_blocking="'+friends[i].statusnet_blocking+'", notifications="'+friends[i].notifications+'", statusnet_profile_url="'+friends[i].statusnet_profile_url+'", cid="'+friends[i].cid+'", network="'+friends[i].network+'" WHERE cid="'+friends[i].cid+'"');
} else {// use insert
result = tx.executeSql('INSERT INTO contacts VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)', [friends[i].id,friends[i].name,friends[i].screen_name,friends[i].location,friends[i].description,getBase64Image(friends[i].profile_image_url),friends[i].url,friends[i].protected,friends[i].followers_count,friends[i].friends_count,friends[i].created_at,friends[i].favourites_count,friends[i].utc_offset,friends[i].time_zone,friends[i].statuses_count,friends[i].following,friends[i].verified,friends[i].statusnet_blocking,friends[i].notifications,friends[i].statusnet_profile_url,friends[i].cid,friends[i].network]);}
print("Result: " + result)
});
}
callback();});}
function requestNews(url,user,password,database,callback){
friendicaRequest(url,user,password,"/api/statuses/friends_timeline", function (obj){
var news=JSON.parse(obj);
for (var i=0;i<news.length;i++){
var db=LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]);
print('store news data for ' + news[i].status_id);
db.transaction( function(tx) {
var result = tx.executeSql('SELECT * from news where id = "'+news[i].status_id+'"'); // check for news id
if(result.rows.length === 1) {// use update
print(news[i].id +' exists, update it')
result = tx.executeSql('UPDATE news SET text="'+news[i].text+'", truncated="'+news[i].truncated+'", created_at="'+news[i].created_at+'", in_reply_to_status_id="'+news[i].in_reply_to_status_id+'", source="'+news[i].source+'", status_id="'+news[i].status_id+'", in_reply_to_user_id="'+news[i].in_reply_to_user_id+'", geo="'+news[i].geo+'", favorited="'+news[i].favorited+'", uid="'+news[i].uid+'", status_html="'+news[i].status_html+'", statusnet_conversation_id="'+news[i].statusnet_conversation_id+'", attachments="'+news[i].attachments+'" where status_id="'+news[i].status_id+'"');
} else {// use insert
result = tx.executeSql('INSERT INTO news VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)', [news[i].text,news[i].truncated,news[i].created_at, news[i].in_reply_to_status_id, news[i].source, news[i].status_id,news[i].in_reply_to_user_id,news[i].geo,news[i].favorited, news[i].uid,news[i].status_html,news[i].statusnet_conversation_id, news[i].attachments]);
print("Inserted");}
});}
callback();}
);}
function requestFriendsAlbumPictures(url,user,password,db){
readField("screen_name",db,"contacts",function(obj){
for (i=0; i<obj.length;i++){
friendicaRequest(url,user,password,"/photos/"+screen_name,function(photohtml){
print(photohtml);
var photoarray=[];
var arr = photohtml.split("photo-top-image-wrapper lframe");
for (j=1;j<arr.length;i++){
var photo = arr[i].substring(arr[i].indexOf('<img src=')+11,arr[i].indexOf('alt=')-3);
photoarray.push(photo);
}})}},"network","FRIENDICA")
}
function newsfromdb(database,user,callback,stop_id){
var db=LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]);
db.transaction( function(tx) {
if (!stop_id){var rs = tx.executeSql('select status_id from news ORDER BY status_id DESC LIMIT 1');
var stop_id=rs.rows.item;}
var newsrs=tx.executeSql('select * from news WHERE (status_id<'+stop_id+') DESC LIMIT 20');
var newsArray;
for(var i = 0; i < newsrs.rows.length; i++) {
newsArray.push(newsrs.rows.item(i))
}
callback(newsArray);
});}
function requestList(url,user,password,database,callback) {
friendicaRequest(url,user,password,"/api/friendica/photos/list", function (obj){
var obj=JSON.parse(obj);
readField("resourceID",database,"imageData",function(AllStoredImages){
for(var i=0;i< AllStoredImages.length;i++){
obj.splice(obj.indexOf(AllStoredImages[i]),1);
}
});
callback(obj);
})}
function uploadData(url,user,password,api,data,callback) {
var xhr = new XMLHttpRequest();
print(url+api+data);
xhr.onreadystatechange = function() {
if (xhr.readyState === XMLHttpRequest.HEADERS_RECEIVED) {
print('HEADERS_RECEIVED')
} else if(xhr.readyState === XMLHttpRequest.DONE) {
print('DONE');
var obj=xhr.responseText.toString();
print("Upload message: "+obj);
callback(obj);
}
}
xhr.open("POST", url+api+data,false,user,password);
xhr.send();
}
function uploadMedia(url,user,password,picture,callback) {
uploadData(url,user,password,"/api/media/upload?media=", getBase64Image(picture),callback)
}
function statusUpdate(url,user,password,title,status,in_reply_to_status_id,media,group_allow,contact_allow,group_deny,contact_deny,callback) {
if(title){titleString="&title="+title}
if(status){statusString="&status="+status}
if(in_reply_to_status_id){replyString="&in_reply_to_status_id="+in_reply_to_status_id}
if(media){mediaString="&media="+base64Image(media)}
if(group_allow){groupallowString="&group_allow="+group_allow}
if(group_deny){groupdenyString="&group_deny="+group_deny}
if(contact_allow){contactallowString="&contact_allow="+contact_allow}
if(contact_deny){contactdenyString="&contact_deny="+contact_deny}
if(in_reply_to_status_id){replyString="&in_reply_to_status_id="+in_reply_to_status_id}
upload_data(url,user,password,"statuses/update?"+titleString+statusString+replyString+mediaString+groupallowString+groupdenyString+contactallowString+contactdenyString, function (obj){
var obj=JSON.parse(obj);
})}
function getBase64Image(img) {
var ctx = getContext("2d");
ctx.width = img.width;
ctx.height = img.height;
ctx.drawImage(img, 0, 0);
var dataURL = canvas.toDataURL("image/png");
// escape data:image prefix
return dataURL.replace(/^data:image\/(png|jpg);base64,/, "");
// or just return dataURL
// return dataURL
}
function dataRequest(url,user,password,photoID,database) {
friendicaRequest(url,user,password,"/api/friendica/photo?photo_id="+photoID, function (obj){
try{ var image = JSON.parse(obj);
print(" Data retrieval success!");
storeData(image,database)
}
catch (e){
infobox.text="Data retrieval failure! "+ e;
}
});
}
function initDatabase(database) { // initialize the database object
var db =LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]);
print('initDatabase()'+database[0]+database[1]+database[2]+database[3])
db.transaction( function(tx) {
print('... create table')
tx.executeSql('CREATE TABLE IF NOT EXISTS imageData(id INT, uid INT, contact_id INT, guid TEXT, resourceID TEXT, created TEXT,edited TEXT, title TEXT, desc TEXT, album TEXT,filename TEXT, type TEXT, height INT, width INT, datasize INT, data BLOB, scale INT, profile INT, allow_cid TEXT, allow_gid TEXT, deny_cid TEXT, deny_gid TEXT)');
tx.executeSql('CREATE TABLE IF NOT EXISTS config(server TEXT, username TEXT, password TEXT,isActive BOOL)');
tx.executeSql('CREATE TABLE IF NOT EXISTS news(text TEXT, truncated BOOL, created_at TEXT, in_reply_to_status_id INT, source TEXT, status_id INT, in_reply_to_user_id INT, geo TEXT,favorited BOOL, uid INT, statusnet_html TEXT, statusnet_conversation_id TEXT,attachments TEXT)');
tx.executeSql('CREATE TABLE IF NOT EXISTS contacts(id INT, name TEXT, screen_name TEXT, location TEXT,description TEXT, profile_image BLOB, url TEXT, protected BOOL, followers_count INT, friends_count INT, created_at TEXT, favourites_count INT, utc_offset TEXT, time_zone TEXT, statuses_count INT, following BOOL, verified BOOL, statusnet_blocking BOOL, notifications BOOL, statusnet_profile_url TEXT, cid INT, network TEXT)');
})}
function storeConfig(database,obj) { // stores config to DB
var db=LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]);
print('storeConfig() for ' + obj.username)
print('database: ' + database[0]);
db.transaction( function(tx) {
print('... check if a object exists: '+obj.username)
var result = tx.executeSql('SELECT * from config WHERE username="'+obj.username+'"');
if(result.rows.length === 1) {// use update
print(obj.username +' exists, update it');
var result2 = tx.executeSql('UPDATE config SET server="'+obj.server+'",password="'+obj.password+'", isActive="TRUE" WHERE username="'+obj.username +'"');
var result3 = tx.executeSql('UPDATE config SET isActive="FALSE" WHERE username !="'+obj.username +'"');
} else {// use insert print('... does not exists, create it')
var result2 = tx.executeSql('INSERT INTO config VALUES (?,?,?,?)', [obj.server, obj.username, obj.password, "TRUE"]);
var result3 = tx.executeSql('UPDATE config SET isActive="FALSE" WHERE username !="'+obj.username +'"');
print("Inserted");}
});}
function getServerConfig(url,user,password,callback){
try {friendicaRequest(url,user,password,"/api/statusnet/config", function (obj){
var serverconfig = JSON.parse(obj);
var serverconfigString="import QtQuick 2.0; Text{x: 20; y: 150; color:'white'; text: 'Name: "+serverconfig.site.name+"\nLanguage: "+serverconfig.site.language+
"\nEmail: "+serverconfig.site.email+"\nTimezone: "+serverconfig.site.timezone+"\nClosed: "+serverconfig.site.closed+
"\nText limit: "+serverconfig.site.textlimit+"\nShort Url length: "+serverconfig.site.shorturllength+
"\nFriendica version: "+serverconfig.site.friendica.FRIENDICA_VERSION+"\nDFRN version: "+serverconfig.site.friendica.DFRN_PROTOCOL_VERSION +
"\nDB Update version: "+serverconfig.site.friendica.DB_UPDATE_VERSION+"'}";
callback(serverconfigString);
})}
catch (e){callback (e);
}}
function readConfig(database,callback,filter,filtervalue) { // reads and applies data from DB
print('readConfig()')
if (filter){var where = " WHERE "+ filter +" = '" + filtervalue+"'";} else { var where="";}
var db=LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]);
if(!db) { return; }
db.transaction( function(tx) {
print('... read from database '+where)
var rs = tx.executeSql('select * from config'+where);
var rsArray=[];
for(var i = 0; i < rs.rows.length; i++) {
rsArray.push(rs.rows.item(i))
}
print(rs.toString);
var rsObject={server:rsArray[0].server,username:rsArray[0].username, password:rsArray[0].password};
callback(rsObject);
});
}
function storeData(obj,database) { // stores data to DB
var db=LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]);
print('storeData() for ' + obj["resource-id"])
print('database: ' + database[0]);
db.transaction( function(tx) {
print('... check if a object exists: '+obj["resource-id"])
var result = tx.executeSql('SELECT * from imageData where resourceID = "'+obj["resource-id"]+'"'); // prepare object to be stored as JSON
if(result.rows.length === 1) {// use update
print(obj["resource-id"] +' exists, update it')
result = tx.executeSql('UPDATE imageData SET id="'+obj.id+'", uid="'+obj.uid+'", contact_id="'+obj.contact_id+'", guid="'+obj.guid+'", created="'+obj.created+'", edited="'+obj.edited+'", datasize="'+obj.datasize+'", scale="'+obj.scale+'", profile="'+obj.profile+'", allow_cid="'+obj.allow_cid+'", allow_gid="'+obj.allow_gid+'", deny_cid="'+obj.deny_cid+'", deny_gid="'+obj.deny_gid+'", filename="'+obj.filename+'",title="'+obj.title+'", desc="'+obj.desc+'", type="'+obj.type+'", width="'+obj.width+'", height="'+obj.height+'", album="'+obj.album+'", data="'+obj.data+'", where resourceID="'+obj["resource-id"]+'"');
} else {// use insert print('... does not exists, create it')
result = tx.executeSql('INSERT INTO imageData VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)', [obj.id,obj.uid,obj.contact_id,obj.guid, obj["resource-id"], obj.created,obj.edited, obj.title, obj.desc, obj.album, obj.filename, obj.type, obj.height, obj.width, obj.datasize, obj.data,obj.scale, obj.profile,obj.allow_cid,obj.allow_gid,obj.deny_cid,obj.deny_gid]);
print("Inserted");}
});}
function readData(resourceID) { // reads and applies data from DB
print('readData()')
if(!db) { return; }
db.transaction( function(tx) {
print('... read object')
var result = tx.executeSql('select * from imageData where resourceID="'+resourceID+'"');
return result;
});
}
function readField(field,database,table, callback,filter,filtervalue) { // reads and applies data from DB
print('readData()')
if (filter){
var where = " WHERE "+ filter +" = '" + filtervalue+"'";
} else { var where="";}
var db=LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]);
if(!db) { return; }
db.transaction( function(tx) {
print('... read from database ' + field)
var rsArray=[];
print('select DISTINCT '+field+' from '+table+where);
var rs = tx.executeSql('select DISTINCT '+field+' from '+table+where);
for(var i = 0; i < rs.rows.length; i++) {
rsArray.push(rs.rows.item(i)[field])
}
callback(rsArray);
});
}

392
Source/test.qml Normal file
View file

@ -0,0 +1,392 @@
import QtQuick 2.0
import QtQuick.LocalStorage 2.0
import QtQuick.Window 2.0
import "service.js" as Service
import QtQuick.Dialogs 1.2
import QtQuick.Controls 1.4
import QtMultimedia 5.0
TabView{
tabPosition: Qt.BottomEdge
width: 600
height: 600
property var db: ["Photos", "1.0", "Stores Friendica data", 100000000]
Tab{
title: "Fotos"
Rectangle {
property var db;
width: 600
height: 600
color: '#fff'
property var imageList
Image {
id: updatePhoto
x: 10; y: 10
source: "Update.png"
MouseArea {
anchors.fill: parent
onClicked: {
updatePhoto.rotation += 25;
print("clicked");
var url="http://cubie.fritz.box";
var user="marco";
var password="rx3715";
var db = ["Photos", "1.0", "Stores photo data", 100000000];
Service.initDatabase(db);
print("Database:" +db[0]);
Service.requestList(url,user,password,db, function(obj){
for (var i=0; i<obj.length; i++){
infoboxGallery.text="Loading "+i+" of "+ obj.length+" pictures...";
print ("Requesting and storing data for "+obj[i]);
Service.dataRequest(url,user,password,obj[i],db);
}
});
}}
}
ComboBox{
width: 150
model: ["album", "type","filename"]
onCurrentIndexChanged:{
var db = ["Photos", "1.0", "Stores photo data", 100000000];
photoModel.clear();
Service.readField(currentText,db, "imageData",function(filter){
for (var j=0;j<filter.length;j++){
Service.readField("data",db,"imageData",function(obj){
// obj.sort(function(obj1,obj2){return obj1.data-obj2.data});
if (obj[j]) {photoModel.append({"imageString": "data:image/jpeg;base64," + obj[j], "selectionName": filter[j]});
};
},currentText,filter[j]);
}})
}
}
Text {
id:infoboxGallery
width: parent.width - 60;height: 30
anchors.left:parent.left
text: ""
color: "black"
font.family: "Monospace"
font.pixelSize: 10
}
Image {
id: liste
x: 300; y: 10
sourceSize.height: 150
source: "Update.png"
MouseArea {
anchors.fill: parent
onClicked: {
var db = ["Photos", "1.0", "Stores photo data", 100000000];
Service.readField("album",db, "imageData",function(albums){
for (var j=0;j<albums.length;j++){
Service.readField("data",db,"imageData",function(obj){
// obj.sort(function(obj1,obj2){return obj1.data-obj2.data});
if (obj[i]) {photoModel.append({"imageString": "data:image/jpeg;base64," + obj[j]})};
},"album",albums[j]);
}
})
}
}}
ListModel{
id: photoModel
dynamicRoles: false
}
GridView {
id: view
cellWidth: 80
cellHeight: 80
x: 10;y:50
anchors.fill: parent
anchors.margins: 50
clip: true
add: Transition {
NumberAnimation { properties: "x,y"; from: 0; duration: 1000 }
}
model: photoModel
delegate: photoDelegate
}
Component {
id: photoDelegate
Rectangle {
id: wrapper
width: 80
height: 80
border.color: "red"
Text {
text: selectionName
color: "#303030"
font.family: "Monospace"
font.pixelSize: 14
}
Image {
id: photoImage
anchors.fill: parent
fillMode: Image.PreserveAspectFit
source: imageString
MouseArea {
anchors.fill: parent
onClicked: {
}}
}
}
}
ListModel{
id:photoslideshow
}
}
}
Tab{
title: "Upload"
Rectangle{
property string photofile:"Update.png"
color: "grey"
FileDialog {
id: fileDialog
title: "Please choose a file"
folder: shortcuts.pictures
selectMultiple: true
onAccepted: {
photofile=fileDialog.fileUrls[0];
console.log("You chose: " + fileDialog.fileUrls)
Service.readConfig(db,function(login){
var url=login.url; var user=login.user; var password=login.password;
Service.friendlist(url,user,password,function(obj){
for (var i=0; i<obj.length; i++){
print(obj[i]);
if (obj[i]) {friendsModel.append({"friendName": obj[i]});
};
};
});
});
}
onRejected: {
console.log("Canceled")
}
}
Component.onCompleted: {fileDialog.open()}
Image {
id: photoFromFilesystem
x: 20;y:50
height: 200
fillMode: Image.PreserveAspectFit
source: photofile
}
Button {
text: "Upload"
onClicked:{
Service.readConfig(db,function(obj){
var url=obj.url;
var user=obj.user;
var password=obj.password;
// img.src=file;
Service.uploadMedia(url,user,password,photofile, function(returnvalue){print("Upload return"+returnvalue)})
},"isActive","TRUE");}
}
ListModel{
id: friendsModel
dynamicRoles: false
}
GridView {
id: view
cellWidth: 50
cellHeight: 50
x: 300;y:50
// anchors.fill: parent
// anchors.margins: 50
clip: true
add: Transition {
NumberAnimation { properties: "x,y"; from: 300; duration: 1000 }
}
model: friendsModel
delegate: friendsDelegate
}
Component {
id: friendsDelegate
Rectangle {
id: wrapper
width: 50
height: 50
border.color: "grey"
Text {
text: friendName
color: "#303030"
font.family: "Monospace"
font.pixelSize: 10
}
// Image {
// id: photoImage
// anchors.fill: parent
// fillMode: Image.PreserveAspectFit
// source: imageString
// }
state: "neutral"
states: [
State {
name: "neutral"
PropertyChanges { target: wrapper; color: "grey" }
},
State {
name: "positive"
PropertyChanges { target: wrapper; color: "green" }
},
State {
name: "negative"
PropertyChanges { target: wrapper; color: "red" }
}
]
MouseArea {
anchors.fill: parent
onClicked: {
if (parent.state == "neutral"){ parent.state="positive"};
if (parent.state=="positive") {parent.state="negative"};
if (parent.state=="positive") {parent.state="neutral"};
}
}
}}
}}
Tab {
title: "Camera"
property string photofile;
VideoOutput {
anchors.fill: parent
source: localCamera
}
Camera {
id: localCamera
}
Button {
id: shotButton
width: 200; height: 75
text: "Take Photo"
onClicked: {
localCamera.imageCapture.capture();
} }
Connections {
target: localCamera.imageCapture
onImageSaved: {
photofile= imagePaths.append({"path": path})
listView.positionViewAtEnd(); }
}
Image {
id: photoFromCamera
anchors.fill: parent
fillMode: Image.PreserveAspectFit
source: photo
}
Button {
text: "Upload"
onClicked:{
var url="http://cubie.fritz.box";
var user="marco";
var password="rx3715";
img.src=file;
Service.Upload(url,user,password,file)
}
}
}
Tab{
title: "Config"
Rectangle{
id:configBackground
color: "grey"
Text {
text: "Server"
x: 10; y: 10
}
Text {
text: "User"
x: 10; y: 40
}
Text {
text: "Password"
x: 10; y: 70
}
Rectangle{
color: "white"
x: 100; y: 10; width: 150; height: 20;
TextInput {
anchors.fill: parent
id: servername
selectByMouse: true
focus: true
text: "http://"
}
}
Rectangle{
color: "white"
x: 100; y: 40; width: 150; height: 20;
TextInput {
id: username
anchors.fill: parent
selectByMouse: true
}
}
Rectangle{
color: "white"
x: 100; y: 70; width: 150; height: 20;
TextInput {
id: password
anchors.fill: parent
selectByMouse: true
echoMode: TextInput.PasswordEchoOnEdit
// text: "password"
}
}
Button {
x: 100; y: 100; width: 96; height: 20;
text: "Update"
onClicked:{
var serverString="";
var userconfig={server: servername.text, username: username.text, password:password.text};
Service.storeConfig(db,userconfig);
Service.readConfig(db,function(userconfig){print(userconfig.server);Service.getServerConfig(userconfig.server,userconfig.username,userconfig.password, function(obj){
serverString=obj})},"isActive","TRUE");
var serverconfigObject=Qt.createQmlObject(serverString,configBackground,"serverconfigOutput")
}}
Component.onCompleted: {
Service.initDatabase(db);
try {Service.readConfig(db,function(obj){
servername.text=obj.server;
username.text= obj.username;
password.text=obj.password;},"isActive","TRUE")}
catch (e){print(e)}
}
}
}
}

20
Source/test.qmlproject Normal file
View file

@ -0,0 +1,20 @@
/* File generated by Qt Creator */
import QmlProject 1.1
Project {
mainFile: "test.qml"
/* Include .qml, .js, and image files from current directory and subdirectories */
QmlFiles {
directory: "."
}
JavaScriptFiles {
directory: "."
}
ImageFiles {
directory: "."
}
/* List of plugin directories passed to QML runtime */
// importPaths: [ "../exampleplugin" ]
}

146
Source/test.qmlproject.user Normal file
View file

@ -0,0 +1,146 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE QtCreatorProject>
<!-- Written by QtCreator 3.5.1, 2015-11-27T21:09:55. -->
<qtcreator>
<data>
<variable>EnvironmentId</variable>
<value type="QByteArray">{4e26e1df-26fd-4b76-8028-2f213523c328}</value>
</data>
<data>
<variable>ProjectExplorer.Project.ActiveTarget</variable>
<value type="int">0</value>
</data>
<data>
<variable>ProjectExplorer.Project.EditorSettings</variable>
<valuemap type="QVariantMap">
<value type="bool" key="EditorConfiguration.AutoIndent">true</value>
<value type="bool" key="EditorConfiguration.AutoSpacesForTabs">false</value>
<value type="bool" key="EditorConfiguration.CamelCaseNavigation">true</value>
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.0">
<value type="QString" key="language">Cpp</value>
<valuemap type="QVariantMap" key="value">
<value type="QByteArray" key="CurrentPreferences">CppGlobal</value>
</valuemap>
</valuemap>
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.1">
<value type="QString" key="language">QmlJS</value>
<valuemap type="QVariantMap" key="value">
<value type="QByteArray" key="CurrentPreferences">QmlJSGlobal</value>
</valuemap>
</valuemap>
<value type="int" key="EditorConfiguration.CodeStyle.Count">2</value>
<value type="QByteArray" key="EditorConfiguration.Codec">UTF-8</value>
<value type="bool" key="EditorConfiguration.ConstrainTooltips">false</value>
<value type="int" key="EditorConfiguration.IndentSize">4</value>
<value type="bool" key="EditorConfiguration.KeyboardTooltips">false</value>
<value type="int" key="EditorConfiguration.MarginColumn">80</value>
<value type="bool" key="EditorConfiguration.MouseHiding">true</value>
<value type="bool" key="EditorConfiguration.MouseNavigation">true</value>
<value type="int" key="EditorConfiguration.PaddingMode">1</value>
<value type="bool" key="EditorConfiguration.ScrollWheelZooming">true</value>
<value type="bool" key="EditorConfiguration.ShowMargin">false</value>
<value type="int" key="EditorConfiguration.SmartBackspaceBehavior">0</value>
<value type="bool" key="EditorConfiguration.SpacesForTabs">true</value>
<value type="int" key="EditorConfiguration.TabKeyBehavior">0</value>
<value type="int" key="EditorConfiguration.TabSize">8</value>
<value type="bool" key="EditorConfiguration.UseGlobal">true</value>
<value type="int" key="EditorConfiguration.Utf8BomBehavior">1</value>
<value type="bool" key="EditorConfiguration.addFinalNewLine">true</value>
<value type="bool" key="EditorConfiguration.cleanIndentation">true</value>
<value type="bool" key="EditorConfiguration.cleanWhitespace">true</value>
<value type="bool" key="EditorConfiguration.inEntireDocument">false</value>
</valuemap>
</data>
<data>
<variable>ProjectExplorer.Project.PluginSettings</variable>
<valuemap type="QVariantMap"/>
</data>
<data>
<variable>ProjectExplorer.Project.Target.0</variable>
<valuemap type="QVariantMap">
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Desktop</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Desktop</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">{e9e69f48-1ef9-4389-91ea-9cc2982eefff}</value>
<value type="int" key="ProjectExplorer.Target.ActiveBuildConfiguration">-1</value>
<value type="int" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
<value type="int" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
<value type="int" key="ProjectExplorer.Target.BuildConfigurationCount">0</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">0</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deployment</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Lokales Deployment</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.DefaultDeployConfiguration</value>
</valuemap>
<value type="int" key="ProjectExplorer.Target.DeployConfigurationCount">1</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.PluginSettings"/>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0">
<valuelist type="QVariantList" key="Analyzer.Valgrind.AddedSuppressionFiles"/>
<value type="bool" key="Analyzer.Valgrind.Callgrind.CollectBusEvents">false</value>
<value type="bool" key="Analyzer.Valgrind.Callgrind.CollectSystime">false</value>
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableBranchSim">false</value>
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableCacheSim">false</value>
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableEventToolTips">true</value>
<value type="double" key="Analyzer.Valgrind.Callgrind.MinimumCostRatio">0.01</value>
<value type="double" key="Analyzer.Valgrind.Callgrind.VisualisationMinimumCostRatio">10</value>
<value type="bool" key="Analyzer.Valgrind.FilterExternalIssues">true</value>
<value type="int" key="Analyzer.Valgrind.LeakCheckOnFinish">1</value>
<value type="int" key="Analyzer.Valgrind.NumCallers">25</value>
<valuelist type="QVariantList" key="Analyzer.Valgrind.RemovedSuppressionFiles"/>
<value type="int" key="Analyzer.Valgrind.SelfModifyingCodeDetection">1</value>
<value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
<value type="bool" key="Analyzer.Valgrind.ShowReachable">false</value>
<value type="bool" key="Analyzer.Valgrind.TrackOrigins">true</value>
<value type="QString" key="Analyzer.Valgrind.ValgrindExecutable">valgrind</value>
<valuelist type="QVariantList" key="Analyzer.Valgrind.VisibleErrorKinds">
<value type="int">0</value>
<value type="int">1</value>
<value type="int">2</value>
<value type="int">3</value>
<value type="int">4</value>
<value type="int">5</value>
<value type="int">6</value>
<value type="int">7</value>
<value type="int">8</value>
<value type="int">9</value>
<value type="int">10</value>
<value type="int">11</value>
<value type="int">12</value>
<value type="int">13</value>
<value type="int">14</value>
</valuelist>
<value type="int" key="PE.EnvironmentAspect.Base">0</value>
<valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">QML Scene</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QmlProjectManager.QmlRunConfiguration.QmlScene</value>
<value type="QString" key="QmlProjectManager.QmlRunConfiguration.MainScript">CurrentFile</value>
<value type="QString" key="QmlProjectManager.QmlRunConfiguration.QDeclarativeViewerArguments"></value>
<value type="uint" key="RunConfiguration.QmlDebugServerPort">3768</value>
<value type="bool" key="RunConfiguration.UseCppDebugger">false</value>
<value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
<value type="bool" key="RunConfiguration.UseMultiProcess">false</value>
<value type="bool" key="RunConfiguration.UseQmlDebugger">false</value>
<value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
</valuemap>
<value type="int" key="ProjectExplorer.Target.RunConfigurationCount">1</value>
</valuemap>
</data>
<data>
<variable>ProjectExplorer.Project.TargetCount</variable>
<value type="int">1</value>
</data>
<data>
<variable>ProjectExplorer.Project.Updater.FileVersion</variable>
<value type="int">18</value>
</data>
<data>
<variable>Version</variable>
<value type="int">18</value>
</data>
</qtcreator>

35
TODO.txt Normal file
View file

@ -0,0 +1,35 @@
TODO
======
Layout
____________
Config
____________
- Server Domain
- SSL Check
- OAuth?
Fotos erhalten
_______________
- Liste der Fotos mit api/friendica/photos/list
- Daten der Fotos als JSON über api/friendica/photo.xml?photo_id=[ID], "album" als Feld vorhanden
- Raw data in File?
- Download/Sortieren der Fotos?
Fotos senden
____________
- Upload über api/media/upload.xml?media= (raw data)?
- Berechtigungen? Album?
- Album erstellen/bearbeiten